From patchwork Wed Nov 30 20:02:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Jason A. Donenfeld" X-Patchwork-Id: 27962 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f944:0:0:0:0:0 with SMTP id q4csp1127667wrr; Wed, 30 Nov 2022 12:09:59 -0800 (PST) X-Google-Smtp-Source: AA0mqf7aVp5H/E05/qgkRdSC+qsAM4HGS8fyeolaPhdYvYGa/CiG0HGDOTS54RuZu9mAlNN2Ixzd X-Received: by 2002:a63:ec11:0:b0:470:5b0d:b50e with SMTP id j17-20020a63ec11000000b004705b0db50emr41356222pgh.488.1669838998674; Wed, 30 Nov 2022 12:09:58 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1669838998; cv=none; d=google.com; s=arc-20160816; b=w766mQ56rcaxV6VpN1uqzUiWBUb8PZVNgfEgCQxb35zWYinabUatI6DhPuBOyjDdZN ixkebX3pVFbjqoRWdwBD5TAWSSj+x9ntmaw8wIbmXfYDidv+47qX1zKsIw9C/bUKkMYN gKZG5ONxNSrcGT+SrvDN+Ph+qMn1HQ/adXXxxMlgS71rCnnpp8ekhYOBGrHa1jP87Pax Cd8ahnEbI8afIYryYmhCtj3QtWshIHe5sEKm3/XF4nYCaj3JnhOWOcpBjm7aCg+O35pz X4l8l0OdfB4cB1W1pLcXhqm959TE0oW5Y+S5o3jB5mVzEwhfNuemtG74g8VBYYKWMovo WOzg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=1vH/NcoP2zEaCp8SEXsclpeZY780y8IHRUsr5heJWX8=; b=d330NH2Sb3dLk/s8mrdFKDp0E1iUAb0cO3iH0UYwu/M5JtyIZ3WhyGjfRAB35aSwHF HUHvLZXYx/mSXNnS7vLP0V+Nc9BcfV57EL9pmine9fn8iJafFW80ikJaIaiZOAmkNnAT 9KnURlPwkI223/tN2ZtrMo2d3VGHShPj/SEJTYes6oF9OJI4f0DaVYETvdE4LzuDtoN3 4vAZbwz+l0qCJeGle47MsvxIcvRUtLgPelH780iTqFO1lmPRievlq3neg10CXlBLiomV jGYsdBJPwhNqFp6O4NiwPx8Jcl47U072JsluLFAlyru9Xav1LfesQ8Ljlb2KH1gHjWbT 5rUw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@zx2c4.com header.s=20210105 header.b=ddpmDtlY; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=zx2c4.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id r71-20020a632b4a000000b00452baa58e5dsi2209894pgr.275.2022.11.30.12.09.45; Wed, 30 Nov 2022 12:09:58 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@zx2c4.com header.s=20210105 header.b=ddpmDtlY; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=zx2c4.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229675AbiK3UDI (ORCPT + 99 others); Wed, 30 Nov 2022 15:03:08 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38094 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229472AbiK3UDH (ORCPT ); Wed, 30 Nov 2022 15:03:07 -0500 Received: from sin.source.kernel.org (sin.source.kernel.org [145.40.73.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 59F2A23BFA for ; Wed, 30 Nov 2022 12:03:06 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sin.source.kernel.org (Postfix) with ESMTPS id 84398CE1B0A for ; Wed, 30 Nov 2022 20:03:04 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 05C5AC433C1; Wed, 30 Nov 2022 20:03:01 +0000 (UTC) Authentication-Results: smtp.kernel.org; dkim=pass (1024-bit key) header.d=zx2c4.com header.i=@zx2c4.com header.b="ddpmDtlY" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zx2c4.com; s=20210105; t=1669838580; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=1vH/NcoP2zEaCp8SEXsclpeZY780y8IHRUsr5heJWX8=; b=ddpmDtlYq+odsPu2QUDUygcoSXrMGP7Ot8jHYu9zRWQ7eoYjl7RNrwfXvlQvn1x73rQ7MG 752Dg0fz3wnQqDVH7C7Oum214dOKVkJxUdPm/zWbCmGduUSzYDzXm8BzbIcHoLcH9k5caG FQWwjAwpue1bClbkErdNk0hj3Xmls0Q= Received: by mail.zx2c4.com (ZX2C4 Mail Server) with ESMTPSA id dd68b3be (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Wed, 30 Nov 2022 20:03:00 +0000 (UTC) From: "Jason A. Donenfeld" To: linux-kernel@vger.kernel.org Cc: "Jason A. Donenfeld" , Eric Biggers Subject: [PATCH v2] random: align entropy_timer_state to cache line Date: Wed, 30 Nov 2022 21:02:53 +0100 Message-Id: <20221130200253.511606-1-Jason@zx2c4.com> In-Reply-To: References: MIME-Version: 1.0 X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, RCVD_IN_DNSWL_HI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1750885281752994514?= X-GMAIL-MSGID: =?utf-8?q?1750953097925763869?= The theory behind the jitter dance is that multiple things are poking at the same cache line. This only works, however, if what's being poked at is actually all in the same cache line. Ensure this is the case by aligning the struct on the stack to the cache line size. We can't use ____cacheline_aligned on a stack variable, because gcc assumes 16 byte alignment when only 8 byte alignment is provided by the kernel, which means gcc could technically do something pathological like `(rsp & ~48) - 64`. It doesn't, but rather than risk it, just do the stack alignment manually with PTR_ALIGN and an oversized buffer. Fixes: 50ee7529ec45 ("random: try to actively add entropy rather than passively wait for it") Cc: Eric Biggers Signed-off-by: Jason A. Donenfeld --- drivers/char/random.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/drivers/char/random.c b/drivers/char/random.c index acb9548a870e..46bb81c2da6e 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -1265,29 +1265,30 @@ static void __cold entropy_timer(struct timer_list *timer) static void __cold try_to_generate_entropy(void) { enum { NUM_TRIAL_SAMPLES = 8192, MAX_SAMPLES_PER_BIT = HZ / 15 }; - struct entropy_timer_state stack; + u8 stack_bytes[sizeof(struct entropy_timer_state) + SMP_CACHE_BYTES - 1]; + struct entropy_timer_state *stack = PTR_ALIGN((void *)stack_bytes, SMP_CACHE_BYTES); unsigned int i, num_different = 0; unsigned long last = random_get_entropy(); int cpu = -1; for (i = 0; i < NUM_TRIAL_SAMPLES - 1; ++i) { - stack.entropy = random_get_entropy(); - if (stack.entropy != last) + stack->entropy = random_get_entropy(); + if (stack->entropy != last) ++num_different; - last = stack.entropy; + last = stack->entropy; } - stack.samples_per_bit = DIV_ROUND_UP(NUM_TRIAL_SAMPLES, num_different + 1); - if (stack.samples_per_bit > MAX_SAMPLES_PER_BIT) + stack->samples_per_bit = DIV_ROUND_UP(NUM_TRIAL_SAMPLES, num_different + 1); + if (stack->samples_per_bit > MAX_SAMPLES_PER_BIT) return; - atomic_set(&stack.samples, 0); - timer_setup_on_stack(&stack.timer, entropy_timer, 0); + atomic_set(&stack->samples, 0); + timer_setup_on_stack(&stack->timer, entropy_timer, 0); while (!crng_ready() && !signal_pending(current)) { /* * Check !timer_pending() and then ensure that any previous callback has finished * executing by checking try_to_del_timer_sync(), before queueing the next one. */ - if (!timer_pending(&stack.timer) && try_to_del_timer_sync(&stack.timer) >= 0) { + if (!timer_pending(&stack->timer) && try_to_del_timer_sync(&stack->timer) >= 0) { struct cpumask timer_cpus; unsigned int num_cpus; @@ -1312,20 +1313,20 @@ static void __cold try_to_generate_entropy(void) } while (cpu == smp_processor_id() && num_cpus > 1); /* Expiring the timer at `jiffies` means it's the next tick. */ - stack.timer.expires = jiffies; + stack->timer.expires = jiffies; - add_timer_on(&stack.timer, cpu); + add_timer_on(&stack->timer, cpu); preempt_enable(); } - mix_pool_bytes(&stack.entropy, sizeof(stack.entropy)); + mix_pool_bytes(&stack->entropy, sizeof(stack->entropy)); schedule(); - stack.entropy = random_get_entropy(); + stack->entropy = random_get_entropy(); } - mix_pool_bytes(&stack.entropy, sizeof(stack.entropy)); + mix_pool_bytes(&stack->entropy, sizeof(stack->entropy)); - del_timer_sync(&stack.timer); - destroy_timer_on_stack(&stack.timer); + del_timer_sync(&stack->timer); + destroy_timer_on_stack(&stack->timer); }