From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from esa4.hc1455-7.c3s2.iphmx.com (esa4.hc1455-7.c3s2.iphmx.com [68.232.139.117]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7808F349CC5 for ; Fri, 12 Jun 2026 11:11:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=68.232.139.117 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781262685; cv=none; b=FAOkyScHJ5/9Dg+KAzhvrVvNxKNu5mmkQd7VYWhOcb+WQgm/m/z8z0dxZ0sLDlsi+ZpfoHkZifx4VhvEUPXc/GZpQVUedDXxyRA3Res5lm5mPMKNWZYGKfJfW4c6HcLNTBLoa/5orPudOHwjkxy03WJVXB7Q3DiLNhTOX4bhmKM= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781262685; c=relaxed/simple; bh=9qubmuU7CLkrQdKYRxmeV83E7ctcbp//g8biYkjQtpM=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=m14wdOR798YCk2NQJmav3RbqHOfR8lutJWmXPN96b+GR3yJleEs55j28eAvcIyHtzHhvbg2cVKPHP/6TiznUV2wtkUyezbxQQJkNXB5MwVvH+Q+5c6oS32wLAm78x5bE30LSNExJXGn7vpnU5GsmG2GO8sob2IjYi5BxtXgv7+4= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=fujitsu.com; spf=pass smtp.mailfrom=fujitsu.com; dkim=pass (2048-bit key) header.d=fujitsu.com header.i=@fujitsu.com header.b=YiTU8Tnl; arc=none smtp.client-ip=68.232.139.117 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=fujitsu.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=fujitsu.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=fujitsu.com header.i=@fujitsu.com header.b="YiTU8Tnl" DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=fujitsu.com; i=@fujitsu.com; q=dns/txt; s=fj2; t=1781262683; x=1812798683; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=9qubmuU7CLkrQdKYRxmeV83E7ctcbp//g8biYkjQtpM=; b=YiTU8Tnl6tPOYugJHmnQjb2MSvsBdy6Fi9bWQYEXgJlff9yrtdYG7pqt VqrGr0wYTFsX3crKY9X2xPrZv/vROHOeaP1NKxF2893dcNnpLP7rM9BJ3 xJ0rc2Huq/E1lFKIGyQPYsJV+01XOCWszNdmWUqEANIyJ132TEupYbHrF Hbo1UfgO0jNXTtfnyWbIaO4aPWW4KmhjIgk6fBGQRtiSe/BMMJQedOSAQ xt+mjFJ5O/GUgxBAYInwFkIPa7xpmv/DCZ5nkotzxlFUoMD5ET6fdyxHv SJTdmITd+Q82LTfQM1Ejv7y/I4Oydmf6mCwuv5PL/G4T/eeD/84lOcbXM g==; X-CSE-ConnectionGUID: 4p/XjWfKRiCPla2MKB2E/g== X-CSE-MsgGUID: 4nwpCM8LT+GvGrWWXjWNhQ== X-IronPort-AV: E=McAfee;i="6800,10657,11813"; a="243338306" X-IronPort-AV: E=Sophos;i="6.24,200,1774278000"; d="scan'208";a="243338306" Received: from gmgwuk01.global.fujitsu.com ([172.187.114.235]) by esa4.hc1455-7.c3s2.iphmx.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Jun 2026 20:10:13 +0900 Received: from az2uksmgm3.o.css.fujitsu.com (unknown [10.151.22.200]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by gmgwuk01.global.fujitsu.com (Postfix) with ESMTPS id 4CB3C820C1B for ; Fri, 12 Jun 2026 11:10:13 +0000 (UTC) Received: from az2uksmom3.o.css.fujitsu.com (unknown [10.151.22.205]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by az2uksmgm3.o.css.fujitsu.com (Postfix) with ESMTPS id 0492CCAB81D for ; Fri, 12 Jun 2026 11:10:13 +0000 (UTC) Received: from FCCLS0092175.flets-east.jp (unknown [10.9.54.178]) by az2uksmom3.o.css.fujitsu.com (Postfix) with ESMTP id 817851000A62; Fri, 12 Jun 2026 11:10:09 +0000 (UTC) From: Kohei Enju To: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Cc: Catalin Marinas , Will Deacon , Suzuki K Poulose , Sami Mujawar , Steven Price , Gavin Shan , Kohei Enju Subject: [PATCH v3] virt: arm-cca-guest: use migrate_disable() for attestation token requests Date: Fri, 12 Jun 2026 20:09:21 +0900 Message-ID: <20260612111007.49434-1-enju.kohei@fujitsu.com> X-Mailer: git-send-email 2.54.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit The RSI attestation token init and continue calls must be issued from the same CPU. arm_cca_report_new() currently snapshots the CPU number and uses smp_call_function_single() to issue those calls on that CPU. With CONFIG_DEBUG_PREEMPT=y, the smp_processor_id() call used for the snapshot triggers a debug splat [0] because it runs in preemptible context. The snapshot does not pin the task to that CPU; it is only used to choose the target CPU for smp_call_function_single(), which can fail if that CPU is no longer available. Use migrate_disable() and issue the token init and continue operations directly, without the smp_call_function_single() callbacks. This keeps the token request sequence on the same CPU while preserving a sleepable context for the GFP_KERNEL allocations needed after the init call. [0] BUG: using smp_processor_id() in preemptible [00000000] code: cca-workload-at/264 caller is debug_smp_processor_id+0x20/0x30 CPU: 0 UID: 0 PID: 264 Comm: cca-workload-at Not tainted 7.1.0-rc1-00044-g55542ab273f2 #80 PREEMPT(lazy) Hardware name: linux,dummy-virt (DT) Call trace: [...] check_preemption_disabled+0xd8/0xf8 debug_smp_processor_id+0x20/0x30 arm_cca_report_new+0x48/0x278 tsm_report_read+0x154/0x1f8 tsm_report_outblob_read+0x20/0x38 configfs_bin_read_iter+0x118/0x208 vfs_read+0x220/0x318 [...] Fixes: 7999edc484ca ("virt: arm-cca-guest: TSM_REPORT support for realms") Signed-off-by: Kohei Enju --- Changes: v3: - Switch to migrate_disable() and call RSI directly, removing smp_call_function_single() (Will, Suzuki) - Remove arm_cca_attestation_init() helper and unused fields from arm_cca_token_info - Drop Reviewed-by tags since the approach changed from v2 v2: https://lore.kernel.org/linux-arm-kernel/20260519101217.155740-1-enju.kohei@fujitsu.com/ - Add comment about why this path doesn't use migrate_disable() v1: https://lore.kernel.org/linux-arm-kernel/20260518033157.1865498-1-enju.kohei@fujitsu.com/ --- .../virt/coco/arm-cca-guest/arm-cca-guest.c | 97 +++++++------------ 1 file changed, 36 insertions(+), 61 deletions(-) diff --git a/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c b/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c index 66d00b6ceb78..a38df08da6fa 100644 --- a/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c +++ b/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c @@ -16,54 +16,38 @@ /** * struct arm_cca_token_info - a descriptor for the token buffer. - * @challenge: Pointer to the challenge data - * @challenge_size: Size of the challenge data * @granule: PA of the granule to which the token will be written * @offset: Offset within granule to start of buffer in bytes - * @result: result of rsi_attestation_token_continue operation */ struct arm_cca_token_info { - void *challenge; - unsigned long challenge_size; phys_addr_t granule; unsigned long offset; - unsigned long result; }; -static void arm_cca_attestation_init(void *param) -{ - struct arm_cca_token_info *info; - - info = (struct arm_cca_token_info *)param; - - info->result = rsi_attestation_token_init(info->challenge, - info->challenge_size); -} - /** * arm_cca_attestation_continue - Retrieve the attestation token data. * - * @param: pointer to the arm_cca_token_info + * @info: pointer to the arm_cca_token_info * * Attestation token generation is a long running operation and therefore * the token data may not be retrieved in a single call. Moreover, the * token retrieval operation must be requested on the same CPU on which the * attestation token generation was initialised. - * This helper function is therefore scheduled on the same CPU multiple + * This helper function must therefore be executed on the same CPU multiple * times until the entire token data is retrieved. */ -static void arm_cca_attestation_continue(void *param) +static unsigned long +arm_cca_attestation_continue(struct arm_cca_token_info *info) { + unsigned long ret; unsigned long len; unsigned long size; - struct arm_cca_token_info *info; - - info = (struct arm_cca_token_info *)param; size = RSI_GRANULE_SIZE - info->offset; - info->result = rsi_attestation_token_continue(info->granule, - info->offset, size, &len); + ret = rsi_attestation_token_continue(info->granule, info->offset, size, + &len); info->offset += len; + return ret; } /** @@ -74,8 +58,8 @@ static void arm_cca_attestation_continue(void *param) * * Initialise the attestation token generation using the challenge data * passed in the TSM descriptor. Allocate memory for the attestation token - * and schedule calls to retrieve the attestation token on the same CPU - * on which the attestation token generation was initialised. + * and retrieve the attestation token on the same CPU on which the + * attestation token generation was initialised. * * The challenge data must be at least 32 bytes and no more than 64 bytes. If * less than 64 bytes are provided it will be zero padded to 64 bytes. @@ -85,12 +69,11 @@ static void arm_cca_attestation_continue(void *param) * * %-EINVAL - A parameter was not valid. * * %-ENOMEM - Out of memory. * * %-EFAULT - Failed to get IPA for memory page(s). - * * A negative status code as returned by smp_call_function_single(). */ static int arm_cca_report_new(struct tsm_report *report, void *data) { - int ret; - int cpu; + int ret = 0; + unsigned long rsi_result; long max_size; unsigned long token_size = 0; struct arm_cca_token_info info; @@ -103,37 +86,33 @@ static int arm_cca_report_new(struct tsm_report *report, void *data) /* * The attestation token 'init' and 'continue' calls must be - * performed on the same CPU. smp_call_function_single() is used - * instead of simply calling get_cpu() because of the need to - * allocate outblob based on the returned value from the 'init' - * call and that cannot be done in an atomic context. + * performed on the same CPU, so disable CPU migration around + * those operations. */ - cpu = smp_processor_id(); + migrate_disable(); - info.challenge = desc->inblob; - info.challenge_size = desc->inblob_len; - - ret = smp_call_function_single(cpu, arm_cca_attestation_init, - &info, true); - if (ret) - return ret; - max_size = info.result; - - if (max_size <= 0) - return -EINVAL; + max_size = rsi_attestation_token_init(desc->inblob, desc->inblob_len); + if (max_size <= 0) { + ret = -EINVAL; + goto exit_migrate_enable; + } /* Allocate outblob */ token = kvzalloc(max_size, GFP_KERNEL); - if (!token) - return -ENOMEM; + if (!token) { + ret = -ENOMEM; + goto exit_migrate_enable; + } /* * Since the outblob may not be physically contiguous, use a page * to bounce the buffer from RMM. */ buf = alloc_pages_exact(RSI_GRANULE_SIZE, GFP_KERNEL); - if (!buf) - return -ENOMEM; + if (!buf) { + ret = -ENOMEM; + goto exit_migrate_enable; + } /* Get the PA of the memory page(s) that were allocated */ info.granule = (unsigned long)virt_to_phys(buf); @@ -144,21 +123,15 @@ static int arm_cca_report_new(struct tsm_report *report, void *data) info.offset = 0; do { /* - * Schedule a call to retrieve a sub-granule chunk - * of data per loop iteration. + * Retrieve a sub-granule chunk of data per loop + * iteration. */ - ret = smp_call_function_single(cpu, - arm_cca_attestation_continue, - (void *)&info, true); - if (ret != 0) { - token_size = 0; - goto exit_free_granule_page; - } - } while (info.result == RSI_INCOMPLETE && + rsi_result = arm_cca_attestation_continue(&info); + } while (rsi_result == RSI_INCOMPLETE && info.offset < RSI_GRANULE_SIZE); /* Break out in case of failure */ - if (info.result != RSI_SUCCESS && info.result != RSI_INCOMPLETE) { + if (rsi_result != RSI_SUCCESS && rsi_result != RSI_INCOMPLETE) { ret = -ENXIO; token_size = 0; goto exit_free_granule_page; @@ -173,12 +146,14 @@ static int arm_cca_report_new(struct tsm_report *report, void *data) break; memcpy(&token[token_size], buf, info.offset); token_size += info.offset; - } while (info.result == RSI_INCOMPLETE); + } while (rsi_result == RSI_INCOMPLETE); report->outblob = no_free_ptr(token); exit_free_granule_page: report->outblob_len = token_size; free_pages_exact(buf, RSI_GRANULE_SIZE); +exit_migrate_enable: + migrate_enable(); return ret; } -- 2.43.0