* RE: [RFC PATCH 3/6] arm64: hyperv: Add per-CPU RSI host call infrastructure for CCA Realms
From: Michael Kelley @ 2026-06-18 17:46 UTC (permalink / raw)
To: Kameron Carr, kys@microsoft.com, haiyangz@microsoft.com,
wei.liu@kernel.org, decui@microsoft.com, longli@microsoft.com
Cc: catalin.marinas@arm.com, will@kernel.org, mark.rutland@arm.com,
lpieralisi@kernel.org, sudeep.holla@kernel.org, arnd@arndb.de,
thuth@redhat.com, linux-hyperv@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org,
Michael Kelley
In-Reply-To: <20260609181030.2378391-4-kameroncarr@linux.microsoft.com>
From: Kameron Carr <kameroncarr@linux.microsoft.com> Sent: Tuesday, June 9, 2026 11:10 AM
>
> Arm CCA Realms cannot issue Hyper-V hypercalls via HVC; the guest must
> route them through the RSI_HOST_CALL interface, which takes the IPA of a
> per-CPU rsi_host_call structure as its argument.
>
> Add hyperv_pcpu_hostcall_struct as a per-CPU pointer to that buffer and
> allocate it for the boot CPU during hyperv_init() and for each secondary
> CPU in hv_cpu_init(). The allocation is gated on is_realm_world() so
> non-Realm arm64 Hyper-V guests pay no memory cost.
I wonder if there's a simpler approach here. What about calculating the
total size of struct rsi_host_call needed for all CPUs, then doing a single
dynamic allocation to effectively create an array of entries? Each CPU
would just index into the array with its processor ID. You could still have
a per-cpu pointer that points to the correct array entry to avoid the need
to get the processor ID, but I wonder if even that is worth the trouble. Since
struct rsi_host_call size is a power of 2, the indexing is just a simple shift.
The hyperv_pcpu_input_page is allocated the way it is because it's much
bigger. But 16 struct rsi_host_call fit into a single 4 KiB, so there's no
danger of hitting a memory allocation limit at boot time. Even with 8192
CPUs the allocation is only 2 MiB.
Michael
>
> Signed-off-by: Kameron Carr <kameroncarr@linux.microsoft.com>
> ---
> arch/arm64/hyperv/mshyperv.c | 78 ++++++++++++++++++++++++++++++-
> arch/arm64/include/asm/mshyperv.h | 3 ++
> 2 files changed, 79 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
> index 4fdc26ade1d74..08fec82691683 100644
> --- a/arch/arm64/hyperv/mshyperv.c
> +++ b/arch/arm64/hyperv/mshyperv.c
> @@ -15,10 +15,16 @@
> #include <linux/errno.h>
> #include <linux/version.h>
> #include <linux/cpuhotplug.h>
> +#include <linux/slab.h>
> +#include <linux/percpu.h>
> #include <asm/mshyperv.h>
> +#include <asm/rsi.h>
>
> static bool hyperv_initialized;
>
> +void * __percpu *hyperv_pcpu_hostcall_struct;
> +EXPORT_SYMBOL_GPL(hyperv_pcpu_hostcall_struct);
> +
> int hv_get_hypervisor_version(union hv_hypervisor_version_info *info)
> {
> hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION,
> @@ -60,6 +66,46 @@ static bool __init hyperv_detect_via_acpi(void)
>
> #endif
>
> +static void hv_hostcall_free(void)
> +{
> + int cpu;
> +
> + if (!hyperv_pcpu_hostcall_struct)
> + return;
> +
> + for_each_possible_cpu(cpu)
> + kfree(*per_cpu_ptr(hyperv_pcpu_hostcall_struct, cpu));
> + free_percpu(hyperv_pcpu_hostcall_struct);
> + hyperv_pcpu_hostcall_struct = NULL;
> +}
> +
> +static int hv_cpu_init(unsigned int cpu)
> +{
> + void **hostcall_struct;
> + gfp_t flags;
> + void *mem;
> +
> + if (hyperv_pcpu_hostcall_struct) {
> + /* hv_cpu_init() can be called with IRQs disabled from hv_resume() */
> + flags = irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL;
> +
> + hostcall_struct = (void **)this_cpu_ptr(hyperv_pcpu_hostcall_struct);
> + /*
> + * The hostcall_struct memory is not freed when the CPU
> + * goes offline. If a previously offlined CPU is brought
> + * back online, the memory is reused here.
> + */
> + if (!*hostcall_struct) {
> + mem = kzalloc_obj(struct rsi_host_call, flags);
> + if (!mem)
> + return -ENOMEM;
> + *hostcall_struct = mem;
> + }
> + }
> +
> + return hv_common_cpu_init(cpu);
> +}
> +
> static bool __init hyperv_detect_via_smccc(void)
> {
> uuid_t hyperv_uuid = UUID_INIT(
> @@ -73,6 +119,8 @@ static bool __init hyperv_detect_via_smccc(void)
> static int __init hyperv_init(void)
> {
> struct hv_get_vp_registers_output result;
> + void **hostcall_struct;
> + void *mem;
> u64 guest_id;
> int ret;
>
> @@ -85,6 +133,27 @@ static int __init hyperv_init(void)
> if (!hyperv_detect_via_acpi() && !hyperv_detect_via_smccc())
> return 0;
>
> + /*
> + * The RSI host-call buffer is only ever used when
> + * is_realm_world() is true. Skip the per-CPU allocation on
> + * non-Realm guests.
> + */
> + if (is_realm_world()) {
> + hyperv_pcpu_hostcall_struct = alloc_percpu(void *);
> + if (!hyperv_pcpu_hostcall_struct)
> + return -ENOMEM;
> +
> + hostcall_struct = (void **)this_cpu_ptr(hyperv_pcpu_hostcall_struct);
> + if (!*hostcall_struct) {
> + mem = kzalloc_obj(struct rsi_host_call);
> + if (!mem) {
> + ret = -ENOMEM;
> + goto free_hostcall_mem;
> + }
> + *hostcall_struct = mem;
> + }
> + }
> +
> /* Setup the guest ID */
> guest_id = hv_generate_guest_id(LINUX_VERSION_CODE);
> hv_set_vpreg(HV_REGISTER_GUEST_OS_ID, guest_id);
> @@ -106,12 +175,13 @@ static int __init hyperv_init(void)
>
> ret = hv_common_init();
> if (ret)
> - return ret;
> + goto free_hostcall_mem;
>
> ret = cpuhp_setup_state(CPUHP_AP_HYPERV_ONLINE,
> "arm64/hyperv_init:online",
> - hv_common_cpu_init, hv_common_cpu_die);
> + hv_cpu_init, hv_common_cpu_die);
> if (ret < 0) {
> hv_common_free();
> + hv_hostcall_free();
> return ret;
> }
>
> @@ -125,6 +195,10 @@ static int __init hyperv_init(void)
>
> hyperv_initialized = true;
> return 0;
> +
> +free_hostcall_mem:
> + hv_hostcall_free();
> + return ret;
> }
>
> early_initcall(hyperv_init);
> diff --git a/arch/arm64/include/asm/mshyperv.h b/arch/arm64/include/asm/mshyperv.h
> index b721d3134ab66..65a00bd14c6cb 100644
> --- a/arch/arm64/include/asm/mshyperv.h
> +++ b/arch/arm64/include/asm/mshyperv.h
> @@ -63,4 +63,7 @@ static inline u64 hv_get_non_nested_msr(unsigned int reg)
>
> #include <asm-generic/mshyperv.h>
>
> +/* Per-CPU RSI host call structure for CCA Realms */
> +extern void *__percpu *hyperv_pcpu_hostcall_struct;
> +
> #endif
> --
> 2.45.4
>
^ permalink raw reply
* RE: [RFC PATCH 2/6] firmware: smccc: Detect hypervisor via RSI host call in CCA Realms
From: Michael Kelley @ 2026-06-18 17:45 UTC (permalink / raw)
To: Kameron Carr, kys@microsoft.com, haiyangz@microsoft.com,
wei.liu@kernel.org, decui@microsoft.com, longli@microsoft.com
Cc: catalin.marinas@arm.com, will@kernel.org, mark.rutland@arm.com,
lpieralisi@kernel.org, sudeep.holla@kernel.org, arnd@arndb.de,
thuth@redhat.com, linux-hyperv@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org,
Michael Kelley
In-Reply-To: <20260609181030.2378391-3-kameroncarr@linux.microsoft.com>
From: Kameron Carr <kameroncarr@linux.microsoft.com> Sent: Tuesday, June 9, 2026 11:10 AM
>
> Modify arm_smccc_hypervisor_has_uuid() to check is_realm_world() and
> use rsi_host_call() to query the hypervisor vendor UUID when inside a
> Realm. The realm path is factored into a helper,
> arm_smccc_realm_get_hypervisor_uuid(), that owns a file-static
> rsi_host_call buffer (uuid_hc) serialized by a spinlock.
>
> The RSI-specific includes, file-static state and helper are guarded
> with CONFIG_ARM64 because <asm/rsi.h> does not exist on 32-bit ARM.
>
> For non-Realm environments, the existing arm_smccc_1_1_invoke() path
> is unchanged.
>
> Signed-off-by: Kameron Carr <kameroncarr@linux.microsoft.com>
> ---
> drivers/firmware/smccc/smccc.c | 41 +++++++++++++++++++++++++++++++++-
> 1 file changed, 40 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/firmware/smccc/smccc.c b/drivers/firmware/smccc/smccc.c
> index bdee057db2fd3..6b465e65472b0 100644
> --- a/drivers/firmware/smccc/smccc.c
> +++ b/drivers/firmware/smccc/smccc.c
> @@ -12,6 +12,12 @@
> #include <linux/platform_device.h>
> #include <asm/archrandom.h>
>
> +#ifdef CONFIG_ARM64
> +#include <linux/cleanup.h>
> +#include <linux/spinlock.h>
> +#include <asm/rsi.h>
> +#endif
> +
> static u32 smccc_version = ARM_SMCCC_VERSION_1_0;
> static enum arm_smccc_conduit smccc_conduit = SMCCC_CONDUIT_NONE;
>
> @@ -67,12 +73,45 @@ s32 arm_smccc_get_soc_id_revision(void)
> }
> EXPORT_SYMBOL_GPL(arm_smccc_get_soc_id_revision);
>
> +#ifdef CONFIG_ARM64
> +static struct rsi_host_call uuid_hc;
> +static DEFINE_SPINLOCK(uuid_hc_lock);
So evidently Sashiko is wrong in saying that struct rsi_host_call must be
in decrypted memory?
>
> +/*
> + * Helper function to get the hypervisor UUID via an RsiHostCall.
> + */
> +static bool arm_smccc_realm_get_hypervisor_uuid(struct arm_smccc_res *res)
> +{
> + guard(spinlock_irqsave)(&uuid_hc_lock);
> +
> + memset(&uuid_hc, 0, sizeof(uuid_hc));
> + uuid_hc.gprs[0] = ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID;
> +
> + if (rsi_host_call(__pa_symbol(&uuid_hc)) != RSI_SUCCESS)
> + return false;
Rather than having this function return a boolean upon failure,
couldn't it just set res->a0 to SMCCC_RET_NOT_SUPPORTED like
arm_smcc_1_1_invoke()? Then arm_smccc_hypervisor_has_uuid()
could process both paths exactly the same way.
> +
> + res->a0 = uuid_hc.gprs[0];
> + res->a1 = uuid_hc.gprs[1];
> + res->a2 = uuid_hc.gprs[2];
> + res->a3 = uuid_hc.gprs[3];
> + return true;
> +}
> +#endif
> +
> bool arm_smccc_hypervisor_has_uuid(const uuid_t *hyp_uuid)
> {
> struct arm_smccc_res res = {};
> uuid_t uuid;
>
> - arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID, &res);
> +#ifdef CONFIG_ARM64
> + if (is_realm_world()) {
> + if (!arm_smccc_realm_get_hypervisor_uuid(&res))
> + return false;
> + } else
> +#endif
> +
> arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID,
> + &res);
> +
> if (res.a0 == SMCCC_RET_NOT_SUPPORTED)
> return false;
>
> --
> 2.45.4
>
^ permalink raw reply
* RE: [RFC PATCH 1/6] arm64: rsi: Add RSI host call structure and helper function
From: Michael Kelley @ 2026-06-18 17:45 UTC (permalink / raw)
To: Kameron Carr, kys@microsoft.com, haiyangz@microsoft.com,
wei.liu@kernel.org, decui@microsoft.com, longli@microsoft.com
Cc: catalin.marinas@arm.com, will@kernel.org, mark.rutland@arm.com,
lpieralisi@kernel.org, sudeep.holla@kernel.org, arnd@arndb.de,
thuth@redhat.com, linux-hyperv@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org,
Michael Kelley
In-Reply-To: <20260609181030.2378391-2-kameroncarr@linux.microsoft.com>
From: Kameron Carr <kameroncarr@linux.microsoft.com> Sent: Tuesday, June 9, 2026 11:10 AM
>
> Add struct rsi_host_call to rsi_smc.h, which represents the host call
> data structure used by the Realm Management Monitor (RMM) for the
> RSI_HOST_CALL interface. The structure contains a 16-bit immediate field
> and 31 general-purpose register values, aligned to 256 bytes as required
> by the CCA RMM specification.
>
> Add rsi_host_call() static inline wrapper in rsi_cmds.h that invokes
> SMC_RSI_HOST_CALL with the physical address of the host call structure.
> This will be used by Hyper-V guest code to route hypercalls through the
> RSI interface when running inside an Arm CCA Realm.
>
> Signed-off-by: Kameron Carr <kameroncarr@linux.microsoft.com>
> ---
> arch/arm64/include/asm/rsi_cmds.h | 9 +++++++++
> arch/arm64/include/asm/rsi_smc.h | 6 ++++++
> 2 files changed, 15 insertions(+)
>
> diff --git a/arch/arm64/include/asm/rsi_cmds.h b/arch/arm64/include/asm/rsi_cmds.h
> index 2c8763876dfb7..83b4b1f598454 100644
> --- a/arch/arm64/include/asm/rsi_cmds.h
> +++ b/arch/arm64/include/asm/rsi_cmds.h
> @@ -159,4 +159,13 @@ static inline unsigned long
> rsi_attestation_token_continue(phys_addr_t granule,
> return res.a0;
> }
>
> +static inline long rsi_host_call(phys_addr_t host_call_struct)
> +{
> + struct arm_smccc_res res;
> +
> + arm_smccc_smc(SMC_RSI_HOST_CALL, host_call_struct, 0, 0, 0, 0, 0, 0,
> + &res);
> + return res.a0;
> +}
For consistent grouping, it seems like this inline function should
be placed after rsi_set_addr_range_state() since it follows the
same pattern. It's a bit different from the token functions.
> +
> #endif /* __ASM_RSI_CMDS_H */
> diff --git a/arch/arm64/include/asm/rsi_smc.h b/arch/arm64/include/asm/rsi_smc.h
> index e19253f96c940..ffea93340ed7f 100644
> --- a/arch/arm64/include/asm/rsi_smc.h
> +++ b/arch/arm64/include/asm/rsi_smc.h
> @@ -142,6 +142,12 @@ struct realm_config {
> */
> } __aligned(0x1000);
>
> +struct rsi_host_call {
> + u16 immediate;
I don't see the "immediate" used anywhere in this patch set.
Is it always zero for the Hyper-V use cases? Just curious ...
> + u64 gprs[31];
> +} __aligned(256);
> +static_assert(sizeof(struct rsi_host_call) == 256);
This struct defines an ABI with the RMM layer, so I'd suggest
adding explicit padding of 6 bytes after the immediate so there's
no implicit dependency on the compiler adding the padding.
Sashiko had the same comment ....
Michael
> +
> #endif /* __ASSEMBLER__ */
>
> /*
> --
> 2.45.4
>
^ permalink raw reply
* Re: [PATCH v4 00/31] Introduce SCMI Telemetry FS support
From: David Hildenbrand (Arm) @ 2026-06-18 17:27 UTC (permalink / raw)
To: Cristian Marussi, Christian Brauner
Cc: linux-kernel, linux-arm-kernel, arm-scmi, linux-fsdevel,
linux-doc, sudeep.holla, james.quinlan, f.fainelli,
vincent.guittot, etienne.carriere, peng.fan, michal.simek, d-gole,
jic23, elif.topuz, lukasz.luba, philip.radford,
souvik.chakravarty, leitao, kas, puranjay, usama.arif,
kernel-team
In-Reply-To: <29a304f0-1e62-418a-b84f-aabdc4c0de8d@kernel.org>
> Maybe you have it in some of the patches here, but what does the typical
> directory + file structure look like in the current implementation?
>
> Do you have an example?
Found it in patch #20! :)
--
Cheers,
David
^ permalink raw reply
* Re: [PATCH v4 00/31] Introduce SCMI Telemetry FS support
From: David Hildenbrand (Arm) @ 2026-06-18 17:22 UTC (permalink / raw)
To: Cristian Marussi, Christian Brauner
Cc: linux-kernel, linux-arm-kernel, arm-scmi, linux-fsdevel,
linux-doc, sudeep.holla, james.quinlan, f.fainelli,
vincent.guittot, etienne.carriere, peng.fan, michal.simek, d-gole,
jic23, elif.topuz, lukasz.luba, philip.radford,
souvik.chakravarty, leitao, kas, puranjay, usama.arif,
kernel-team
In-Reply-To: <ajLVW1eHzbGDm4yn@pluto>
Hi,
asking some clarifying questions that I assume also Christian might want to know.
>>> In a nutshell, the SCMI Telemetry protocol allows an agent to discover at
>>> runtime the set of Telemetry Data Events (DEs) available on a specific
>>> platform and provides the means to configure the set of DEs that a user is
Is the configuration aspect limited to enabling selected events, or is there
more that can be configured?
>>> interested into, while reading them back using the collection method that
>>> is deeemed more suitable for the usecase at hand. (...amongst the various
>>> possible collection methods allowed by SCMI specification)
>>>
>>> Without delving into the gory details of the whole SCMI Telemetry protocol
>>> let's just say that the SCMI platform/server firmware advertises a number
>>> of Telemetry Data Events, each one identified by a 32bit unique ID, and an
>>> SCMI agent/client, like Linux, can discover them and read back at will the
>>> associated data value in a number of ways.
>>> Data collection is mainly intended to happen on demand via shared memory
>>> areas exposed by the platform firmware, discovered dynamically via SCMI
>>> Telemetry and accessed by Linux on-demand, but some DE can also be reported
>>> via SCMI Notifications asynchronous messages or via direct dedicated
>>> FastChannels (another kind of SCMI memory based access): all of this
>>> underlying mechanism is anyway hidden to the user since it is mediated by
>>> the kernel driver which will return the proper data value when queried.
>>>
>>> Anyway, the set of well-known architected DE IDs defined by the spec is
>>> limited to a dozen IDs, which means that the vast majority of DE IDs are
>>> customizable per-platform: as a consequence, though, the same ID, say
>>> '0x1234', could represent completely different things on different systems.
>>>
>>> Precise definitions and semantic of such custom Data Event IDs are out of
>>> the scope of the SCMI Telemetry specification and of this implementation:
>>> they are supposed to be provided using some kind of JSON-like description
>>> file that will have to be consumed by a userspace tool which would be
>>> finally in charge of making sense of the set of available DEs.
You mention json here ... but I assume the data we are getting fed by the
protocol is not in some default format? (e.g., json)
>>>
>>> IOW, in turn, this means that even though the DEs enumerated via SCMI come
>>> with some sort of topological and qualitative description provided by the
>>> protocol (like unit of measurements, name, topology info etc), kernel-wise
>>> we CANNOT be completely sure of "what is what" without being fed-back some
>>> sort of information about the DEs by the afore mentioned userspace tool.
Maybe you have it in some of the patches here, but what does the typical
directory + file structure look like in the current implementation?
Do you have an example?
Also, is everything in that filesystem read-only, or are there some writable
file (IOW, how is stuff configured?).
>>>
>>> For these reasons, currently this series does NOT attempt to register any
>>> of these DEs with any of the usual in-kernel subsystems (like HWMON, IIO,
>>> PERF etc), simply because we cannot be sure which DE is suitable, or even
>>> desirable, for a given subsystem. This also means there are NO in-kernel
>>> users of these Telemetry data events as of now.
Okay, so you really only feed this data to user space, exposing all the data you
have easily available as part of the protocol.
>>>
>>> So, while we do not exclude, for the future, to feed/register some of the
>>> discovered DEs to/with some of the above mentioned Kernel subsystems, as
>>> of now we have ONLY modeled a custom userspace API to make SCMI Telemetry
>>> available to userspace tools.
It's a good question how that could be done, if you need more information about
these events from user space.
>>>
>>> In deciding which kind of interface to expose SCMI Telemetry data to a
>>> user, this new SCMI Telemetry driver aims at satisfying 2 main reqs:
>>>
>>> - exposing an FS-based human-readable interface that can be used to
>>> discover, configure and access our Telemetry data directly also from
>>> the shell without special tools
>>>
>>> - exposing alternative machine-friendly, more-performant, binary
>>> interfaces that can be used to avoid the overhead of multiple accesses
>>> to the VFS and that can be more suitable to access with custom tools
[...]
>>>
>>> Due to the above reasoning, since V1 we opted for a new approach with the
>>> proposed interfaces now based on a full fledged, unified, virtual pseudo
>>> filesystem implemented from scratch, so that we can:
>>>
>>> - expose all the DEs property we like as before with SysFS, but without
>>> any of the constraint imposed by the usage of SysFs or kernfs.
>>>
>>> - easily expose additional alternative views of the same set of DEs
>>> using symlinking capabilities (e.g. alternative topological view)
That sounds reasonable.
[...]
> ...I would not say that this was the kind of feedback I was hoping for,
> but I am NOT gonna argue, given that you shot down already what I thought
> were all my best selling points :P
>
> At this point my understanding is that the way forward must be to use
> a custom tool to configure/extract/translate the raw Telemetry data and
> move up into userspace the whole human readable FS layer via FUSE, if
> really needed.
>
> I suppose that the new kernel/user interface has to be some dedicated char
> device implementing proper fops. (like I did previously in early versions
> of this series and then abandoned...)
>
> Is this you have in mind ? Dedicated character device(s) with enough fops
> to be able to configure/extract Telemetry data with a custom tool ?
I cannot speak for Christian, but I guess you could have some kind of libscmi in
user space that can obtain the information (as you say, probably char device,
not sure which alternatives we have), to expose the data through a nice ABI, to
then either make tools build upon that directly, or have a fuse server in user
space that mimics what you currently do with the file system.
One thing that is not clear to me yet is how stuff would be configured, and how
possibly multiple users of libscmi would possibly interact.
>
> Should/could such a tool live in the kernel tree (tools/) at least for
> ease of development/deployment ?
I think OOT.
--
Cheers,
David
^ permalink raw reply
* Re: [PATCH v7 7/7] KVM: arm64: Zero out the stack initialized data in the FFA handler
From: Vincent Donnefort @ 2026-06-18 17:14 UTC (permalink / raw)
To: Sebastian Ene
Cc: catalin.marinas, oupton, sudeep.holla, will, jens.wiklander,
joey.gouly, kvmarm, linux-arm-kernel, linux-kernel, android-kvm,
maz, mrigendra.chaubey, op-tee, perlarsen, seiden, smostafa,
sumit.garg, suzuki.poulose, yuzenghui, Sashiko AI
In-Reply-To: <20260617145130.3729015-8-sebastianene@google.com>
On Wed, Jun 17, 2026 at 02:51:30PM +0000, Sebastian Ene wrote:
> Don't leak hypervisor stack data when using the FFA_VERSION call.
> When the compiler doesn't support -ftrivial-auto-var-init=zero option
Even when it does, I believe this is an optional kernel option.
> we need to zero out the stack initialized variable before returning data
> to the host caller.
>
> Reported-by: Sashiko AI <sashiko-bot@kernel.org>
It seems most people are using "Reported-by: Sashiko <sashiko-bot@kernel.org>"
> Closes:
> https://lore.kernel.org/all/20260616160016.C62C81F000E9@smtp.kernel.org/
> Fixes: c9c012625e12 ("KVM: arm64: Trap FFA_VERSION host call in pKVM")
> Signed-off-by: Sebastian Ene <sebastianene@google.com>
Reviewed-by: Vincent Donnefort <vdonnefort@google.com>
> ---
> arch/arm64/kvm/hyp/nvhe/ffa.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
> index d7c5701d0584..b321682ead04 100644
> --- a/arch/arm64/kvm/hyp/nvhe/ffa.c
> +++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
> @@ -883,7 +883,7 @@ static void do_ffa_part_get(struct arm_smccc_1_2_regs *res,
>
> bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
> {
> - struct arm_smccc_1_2_regs res;
> + struct arm_smccc_1_2_regs res = {0};
>
> /*
> * There's no way we can tell what a non-standard SMC call might
> --
> 2.54.0.1136.gdb2ca164c4-goog
>
^ permalink raw reply
* Re: [PATCH v7 6/7] KVM: arm64: Ensure FFA ranges are page aligned
From: Vincent Donnefort @ 2026-06-18 17:09 UTC (permalink / raw)
To: Sebastian Ene
Cc: catalin.marinas, oupton, sudeep.holla, will, jens.wiklander,
joey.gouly, kvmarm, linux-arm-kernel, linux-kernel, android-kvm,
maz, mrigendra.chaubey, op-tee, perlarsen, seiden, smostafa,
sumit.garg, suzuki.poulose, yuzenghui
In-Reply-To: <20260617145130.3729015-7-sebastianene@google.com>
On Wed, Jun 17, 2026 at 02:51:29PM +0000, Sebastian Ene wrote:
> From: Mostafa Saleh <smostafa@google.com>
>
> At the moment we only check that the size of the range is page
> aligned, and truncate the address to the page boundary.
> This make an assumption that TZ will do the same.
>
> However, it might decide to use the extra offset of the neighbour
> page at the end, which is valid under FFA if NS is using larger
> page size.
I failed to parse this
But I see
/* The base IPA of the constituent memory region, aligned to 4 kiB */
So it sounds fair to prevent oversharing when PAGE_SIZE > 4KiB
>
> Harden this check by also checking that the base address is aligned
> and reject it otherwise.
>
> Fixes: 436090001776 ("KVM: arm64: Handle FFA_MEM_SHARE calls from the host")
> Signed-off-by: Mostafa Saleh <smostafa@google.com>
> Signed-off-by: Sebastian Ene <sebastianene@google.com>
Perhaps the commit description needs some improvement.
The rest looks good.
Reviewed-by: Vincent Donnefort <vdonnefort@google.com>
> ---
> arch/arm64/kvm/hyp/nvhe/ffa.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
> index 1a2abd0154c6..d7c5701d0584 100644
> --- a/arch/arm64/kvm/hyp/nvhe/ffa.c
> +++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
> @@ -352,7 +352,7 @@ static u32 __ffa_host_share_ranges(struct ffa_mem_region_addr_range *ranges,
> u64 sz = (u64)range->pg_cnt * FFA_PAGE_SIZE;
> u64 pfn = hyp_phys_to_pfn(range->address);
>
> - if (!PAGE_ALIGNED(sz))
> + if (!PAGE_ALIGNED(sz | range->address))
> break;
>
> if (__pkvm_host_share_ffa(pfn, sz / PAGE_SIZE))
> @@ -372,7 +372,7 @@ static u32 __ffa_host_unshare_ranges(struct ffa_mem_region_addr_range *ranges,
> u64 sz = (u64)range->pg_cnt * FFA_PAGE_SIZE;
> u64 pfn = hyp_phys_to_pfn(range->address);
>
> - if (!PAGE_ALIGNED(sz))
> + if (!PAGE_ALIGNED(sz | range->address))
> break;
>
> if (__pkvm_host_unshare_ffa(pfn, sz / PAGE_SIZE))
> --
> 2.54.0.1136.gdb2ca164c4-goog
>
^ permalink raw reply
* Re: [PATCH v7 5/7] KVM: arm64: Validate the offset to the mem access descriptor
From: Vincent Donnefort @ 2026-06-18 16:56 UTC (permalink / raw)
To: Sebastian Ene
Cc: catalin.marinas, oupton, sudeep.holla, will, jens.wiklander,
joey.gouly, kvmarm, linux-arm-kernel, linux-kernel, android-kvm,
maz, mrigendra.chaubey, op-tee, perlarsen, seiden, smostafa,
sumit.garg, suzuki.poulose, yuzenghui
In-Reply-To: <20260617145130.3729015-6-sebastianene@google.com>
On Wed, Jun 17, 2026 at 02:51:28PM +0000, Sebastian Ene wrote:
> Prevent the pKVM hypervisor from making assumptions that the
> endpoint memory access descriptor (EMAD) comes right after the
> FF-A memory region header.
> Prior to FF-A version 1.1 the header of the memory region
> didn't contain an offset to the endpoint memory access descriptor.
> The layout of a memory transaction looks like this from 1.1 onward:
> Type | Field name | Offset
> [ Header | ffa_mem_region | 0
> EMAD 1 | ffa_mem_region_attributes) | ffa_mem_region.ep_mem_offset
> ]
> Verify that the offset to the first endpoint memory access descriptor
> is within the mailbox buffer bounds.
>
> Also, fix one hardcoded sizeof(struct ffa_mem_region_attributes) that
> should be replaced ffa_emad_size_get() for compatibility with FFA v1.0.
>
> Fixes: 42fb33dde42b ("KVM: arm64: Use FF-A 1.1 with pKVM")
> Signed-off-by: Sebastian Ene <sebastianene@google.com>
> Signed-off-by: Mostafa Saleh <smostafa@google.com>
> ---
> arch/arm64/kvm/hyp/nvhe/ffa.c | 29 +++++++++++++++++++++--------
> 1 file changed, 21 insertions(+), 8 deletions(-)
>
> diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
> index 2d211661952e..1a2abd0154c6 100644
> --- a/arch/arm64/kvm/hyp/nvhe/ffa.c
> +++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
> @@ -476,11 +476,14 @@ static void __do_ffa_mem_xfer(const u64 func_id,
> DECLARE_REG(u32, fraglen, ctxt, 2);
> DECLARE_REG(u64, addr_mbz, ctxt, 3);
> DECLARE_REG(u32, npages_mbz, ctxt, 4);
> + u32 offset, nr_ranges, checked_offset, em_mem_access_off;
> struct ffa_mem_region_attributes *ep_mem_access;
> struct ffa_composite_mem_region *reg;
> struct ffa_mem_region *buf;
> - u32 offset, nr_ranges, checked_offset;
> int ret = 0;
> + size_t mem_region_len = !FFA_MEM_REGION_HAS_EP_MEM_OFFSET(hyp_ffa_version) ?
> + offsetof(struct ffa_mem_region, ep_mem_offset) :
> + sizeof(struct ffa_mem_region);
>
> if (addr_mbz || npages_mbz || fraglen > len ||
> fraglen > KVM_FFA_MBOX_NR_PAGES * PAGE_SIZE) {
> @@ -488,8 +491,7 @@ static void __do_ffa_mem_xfer(const u64 func_id,
> goto out;
> }
>
> - if (fraglen < sizeof(struct ffa_mem_region) +
> - sizeof(struct ffa_mem_region_attributes)) {
> + if (fraglen < mem_region_len + ffa_emad_size_get(hyp_ffa_version)) {
Can't we replace mem_region_len with ffa_mem_desc_offset()? that pretty much
looks like the same thing.
> ret = FFA_RET_INVALID_PARAMETERS;
> goto out;
> }
> @@ -508,8 +510,13 @@ static void __do_ffa_mem_xfer(const u64 func_id,
> buf = hyp_buffers.tx;
> memcpy(buf, host_buffers.tx, fraglen);
>
> - ep_mem_access = (void *)buf +
> - ffa_mem_desc_offset(buf, 0, hyp_ffa_version);
> + em_mem_access_off = ffa_mem_desc_offset(buf, 0, hyp_ffa_version);
> + if ((u64)em_mem_access_off + ffa_emad_size_get(hyp_ffa_version) > fraglen) {
This check looks like ffa_mem_desc_offset() with count to 1.
> + ret = FFA_RET_INVALID_PARAMETERS;
> + goto out_unlock;
> + }
> +
> + ep_mem_access = (void *)buf + em_mem_access_off;
> offset = ep_mem_access->composite_off;
> if (!offset || buf->ep_count != 1 || buf->sender_id != HOST_FFA_ID) {
> ret = FFA_RET_INVALID_PARAMETERS;
> @@ -574,9 +581,9 @@ static void do_ffa_mem_reclaim(struct arm_smccc_1_2_regs *res,
> DECLARE_REG(u32, handle_lo, ctxt, 1);
> DECLARE_REG(u32, handle_hi, ctxt, 2);
> DECLARE_REG(u32, flags, ctxt, 3);
> + u32 offset, len, fraglen, fragoff, em_mem_access_off;
> struct ffa_mem_region_attributes *ep_mem_access;
> struct ffa_composite_mem_region *reg;
> - u32 offset, len, fraglen, fragoff;
> struct ffa_mem_region *buf;
> int ret = 0;
> u64 handle;
> @@ -599,8 +606,14 @@ static void do_ffa_mem_reclaim(struct arm_smccc_1_2_regs *res,
> len = res->a1;
> fraglen = res->a2;
>
> - ep_mem_access = (void *)buf +
> - ffa_mem_desc_offset(buf, 0, hyp_ffa_version);
> + em_mem_access_off = ffa_mem_desc_offset(buf, 0, hyp_ffa_version);
> + if ((u64)em_mem_access_off + ffa_emad_size_get(hyp_ffa_version) > fraglen) {
ditto. ffa_mem_desc_offset()
> + ret = FFA_RET_INVALID_PARAMETERS;
> + ffa_rx_release(res);
> + goto out_unlock;
> + }
> +
> + ep_mem_access = (void *)buf + em_mem_access_off;
> offset = ep_mem_access->composite_off;
> /*
> * We can trust the SPMD to get this right, but let's at least
> --
> 2.54.0.1136.gdb2ca164c4-goog
>
^ permalink raw reply
* Re: [PATCH] arm64: Avoid eager DVMSync reclaim batches with C1-Pro SME erratum
From: Will Deacon @ 2026-06-18 16:54 UTC (permalink / raw)
To: Catalin Marinas; +Cc: linux-arm-kernel
In-Reply-To: <20260610104829.1157497-1-catalin.marinas@arm.com>
On Wed, Jun 10, 2026 at 11:37:16AM +0100, Catalin Marinas wrote:
> The C1-Pro SME DVMSync workaround currently samples mm_cpumask() from
> arch_tlbbatch_add_pending(). It requires a DSB after every batched TLBI
> so that the mask read is ordered after the hardware DVMSync, defeating
> much of the reclaim batching benefit.
>
> Introduce the sme_active_cpus mask tracking which CPUs run in user-space
> with SME enabled and use it for batch flushing instead of accumulating
> the mm_cpumask() of the unmapped pages.
>
> Fixes: 0baba94a9779 ("arm64: errata: Work around early CME DVMSync acknowledgement")
> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will@kernel.org>
> ---
>
> The dsb() in arch_tlbbatch_add_pending() -> sme_dvmsync_add_pending()
> did introduce a performance regression for kswapd. This patch restores
> the original behaviour with the barrier only issued when the TLB batch
> is flushed. The trade-off is that the IPIs are now sent to all CPUs
> running with SME enabled at EL0 even if the reclaimed pages do not
> belong to SME tasks. This is acceptable for current SME deployments.
>
> arch/arm64/include/asm/tlbbatch.h | 10 ++-----
> arch/arm64/include/asm/tlbflush.h | 49 +++++--------------------------
> arch/arm64/kernel/fpsimd.c | 10 +++++--
> arch/arm64/kernel/process.c | 35 ----------------------
> 4 files changed, 17 insertions(+), 87 deletions(-)
Ok, so this partially undoes the work to mitigate the IPI-based DoS
reported by Sashiko, but only for the TLB batching case. The mm_cpumask()
is still used for the unbatched case.
It looks functionally correct to me, but it would be great to see some
Tested-by lines from people who are concerned about the performance...
Will
^ permalink raw reply
* Re: [PATCH 01/11] dt-bindings: power: Convert Ux500 PM domains to schema
From: Rob Herring (Arm) @ 2026-06-18 16:51 UTC (permalink / raw)
To: Linus Walleij
Cc: Lee Jones, dri-devel, linux-pm, Maarten Lankhorst, David Airlie,
linux-arm-kernel, Ulf Hansson, Frank Li, devicetree,
Maxime Ripard, dmaengine, Thomas Zimmermann, Mark Brown,
Simona Vetter, Vinod Koul, Conor Dooley, Krzysztof Kozlowski
In-Reply-To: <20260618-ux500-power-domains-v7-1-v1-1-eb5e50b1a588@kernel.org>
On Thu, 18 Jun 2026 07:00:47 +0200, Linus Walleij wrote:
> Convert the legacy Ux500 power domain text binding to YAML.
>
> Move it under bindings/power.
>
> Reference the generic power-domain schema.
>
> Update MAINTAINERS for the new path.
>
> Assisted-by: Codex:gpt-5-5
> Signed-off-by: Linus Walleij <linusw@kernel.org>
> ---
> .../devicetree/bindings/arm/ux500/power_domain.txt | 35 ----------------
> .../power/stericsson,ux500-pm-domains.yaml | 46 ++++++++++++++++++++++
> MAINTAINERS | 1 +
> 3 files changed, 47 insertions(+), 35 deletions(-)
>
My bot found errors running 'make dt_binding_check' on your patch:
yamllint warnings/errors:
dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/power/stericsson,ux500-pm-domains.example.dts:25.28-28.11: Warning (unit_address_vs_reg): /example-0/sdi0_per1@80126000: node has a unit name, but no reg or ranges property
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/power/stericsson,ux500-pm-domains.example.dtb: sdi0_per1@80126000 (arm,pl18x): $nodename:0: 'sdi0_per1@80126000' does not match '^mmc(@.*)?$'
from schema $id: http://devicetree.org/schemas/mmc/arm,pl18x.yaml
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/power/stericsson,ux500-pm-domains.example.dtb: sdi0_per1@80126000 (arm,pl18x): 'oneOf' conditional failed, one must be fixed:
'interrupts' is a required property
'interrupts-extended' is a required property
from schema $id: http://devicetree.org/schemas/mmc/arm,pl18x.yaml
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/power/stericsson,ux500-pm-domains.example.dtb: sdi0_per1@80126000 (arm,pl18x): 'reg' is a required property
from schema $id: http://devicetree.org/schemas/mmc/arm,pl18x.yaml
doc reference errors (make refcheckdocs):
See https://patchwork.kernel.org/project/devicetree/patch/20260618-ux500-power-domains-v7-1-v1-1-eb5e50b1a588@kernel.org
The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.
^ permalink raw reply
* Re: [PATCH RFC 3/3] arm64: Add HOTPLUG_PARALLEL support for secondary CPUs
From: Thomas Gleixner @ 2026-06-18 15:53 UTC (permalink / raw)
To: Jinjie Ruan, Michael Kelley, catalin.marinas@arm.com,
will@kernel.org, tsbogend@alpha.franken.de, pjw@kernel.org,
palmer@dabbelt.com, aou@eecs.berkeley.edu, alex@ghiti.fr,
mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com,
hpa@zytor.com, peterz@infradead.org, kees@kernel.org,
nathan@kernel.org, linusw@kernel.org, ojeda@kernel.org,
david.kaplan@amd.com, lukas.bulwahn@redhat.com,
ryan.roberts@arm.com, maz@kernel.org, timothy.hayes@arm.com,
lpieralisi@kernel.org, thuth@redhat.com, oupton@kernel.org,
yeoreum.yun@arm.com, miko.lenczewski@arm.com, broonie@kernel.org,
kevin.brodsky@arm.com, james.clark@linaro.org, tabba@google.com,
mrigendra.chaubey@gmail.com, arnd@arndb.de,
anshuman.khandual@arm.com, x86@kernel.org,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, linux-mips@vger.kernel.org,
linux-riscv@lists.infradead.org
In-Reply-To: <4588efb4-e757-4ca7-9197-025b67ca9ef6@huawei.com>
On Mon, Jun 15 2026 at 17:57, Jinjie Ruan wrote:
> On 6/12/2026 11:45 PM, Michael Kelley wrote:
>
> - Default (no patch): Slowest HVC64 handling (126 μs), highest WFx count
> (85k), and most total VM‑exits.
>
> - cpuhp.parallel=1: HVC64 latency improved to 78 μs (close to
> cpuhp.parallel=0), but IRQ exits increased dramatically (12.9k, 2.7×
> that of `cpuhp.parallel=0`), accounting for 95% of event time and
> becoming the new bottleneck.
>
> - cpuhp.parallel=0: Fastest HVC64 (69 μs), lowest IRQ exits (4.8k), and
> lowest total samples, delivering the best overall boot performance.
>
> Therefor, `cpuhp.parallel=1` reduces HVC cost but suffers from a massive
> increase in IRQ exits, while `cpuhp.parallel=0` avoids this interrupt
> storm and therefore performs best in a KVM guest.
What's the cause for having this massive interrupt exit rate in parallel
mode? Just because parallel does not give a useful explanation.
Thanks,
tglx
^ permalink raw reply
* Re: [PATCH v7 4/7] KVM: arm64: Fix bounds checking in do_ffa_mem_reclaim()
From: Vincent Donnefort @ 2026-06-18 16:19 UTC (permalink / raw)
To: Sebastian Ene
Cc: catalin.marinas, oupton, sudeep.holla, will, jens.wiklander,
joey.gouly, kvmarm, linux-arm-kernel, linux-kernel, android-kvm,
maz, mrigendra.chaubey, op-tee, perlarsen, seiden, smostafa,
sumit.garg, suzuki.poulose, yuzenghui
In-Reply-To: <20260617145130.3729015-5-sebastianene@google.com>
On Wed, Jun 17, 2026 at 02:51:27PM +0000, Sebastian Ene wrote:
> From: Mostafa Saleh <smostafa@google.com>
>
> Sashiko (locally) reports out of bound write possiblity if SPMD
> returns an invalid data.
>
> While SPMD is considered trusted, pKVM does some basic checks,
> for offset to be less than or equal len.
>
> However, that is incorrect as even if the offset is smaller than
> len pKVM can still access out of bound memory in the next
> ffa_host_unshare_ranges().
>
> Split this check into 2:
> 1- Check that the fixed portion of the descriptor fits.
> 2- After getting reg, check the variable array size addr_range_cnt
> fits.
>
> Also, drop the WARN_ONs as that will panic the kernel and in the
> next checks there are no WARNs, so that makes it consistent.
>
> Fixes: 0a9f15fd5674 ("KVM: arm64: pkvm: Add support for fragmented FF-A descriptors")
> Signed-off-by: Mostafa Saleh <smostafa@google.com>
> Signed-off-by: Sebastian Ene <sebastianene@google.com>
FTR, I believe the comment about composite_off in include/linux/arm_ffa.h is
incorrect. It is an offset to a ffa_composite_mem_region (not a
ffa_mem_region_addr_range)
Reviewed-by: Vincent Donnefort <vdonnefort@google.com>
> ---
> arch/arm64/kvm/hyp/nvhe/ffa.c | 12 +++++++++---
> 1 file changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
> index 1af722771178..2d211661952e 100644
> --- a/arch/arm64/kvm/hyp/nvhe/ffa.c
> +++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
> @@ -607,8 +607,8 @@ static void do_ffa_mem_reclaim(struct arm_smccc_1_2_regs *res,
> * check that we end up with something that doesn't look _completely_
> * bogus.
> */
> - if (WARN_ON(offset > len ||
> - fraglen > KVM_FFA_MBOX_NR_PAGES * PAGE_SIZE)) {
> + if (offset + CONSTITUENTS_OFFSET(0) > len ||
> + fraglen > KVM_FFA_MBOX_NR_PAGES * PAGE_SIZE) {
> ret = FFA_RET_ABORTED;
> ffa_rx_release(res);
> goto out_unlock;
> @@ -636,11 +636,17 @@ static void do_ffa_mem_reclaim(struct arm_smccc_1_2_regs *res,
> ffa_rx_release(res);
> }
>
> + reg = (void *)buf + offset;
> + if (offset + CONSTITUENTS_OFFSET(reg->addr_range_cnt) > len) {
> + ret = FFA_RET_ABORTED;
> + ffa_rx_release(res);
> + goto out_unlock;
> + }
> +
> ffa_mem_reclaim(res, handle_lo, handle_hi, flags);
> if (res->a0 != FFA_SUCCESS)
> goto out_unlock;
>
> - reg = (void *)buf + offset;
> /* If the SPMD was happy, then we should be too. */
> WARN_ON(ffa_host_unshare_ranges(reg->constituents,
> reg->addr_range_cnt));
> --
> 2.54.0.1136.gdb2ca164c4-goog
>
^ permalink raw reply
* [PATCH v2 1/2] module: add SCMI device table alias support
From: Bjorn Andersson @ 2026-06-18 15:56 UTC (permalink / raw)
To: Sudeep Holla, Cristian Marussi, Nathan Chancellor, Nicolas Schier,
Michael Turquette
Cc: arm-scmi, linux-arm-kernel, linux-kernel, linux-kbuild,
Hans de Goede, Bjorn Andersson, Stephen Boyd, Brian Masney,
Rafael J. Wysocki, Viresh Kumar, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, Guenter Roeck,
Jyoti Bhayana, Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko, Dmitry Torokhov, Ulf Hansson, Liam Girdwood,
Mark Brown, Philipp Zabel, Alexandre Belloni, linux-clk, linux-pm,
imx, linux-hwmon, linux-iio, linux-input, linux-rtc
In-Reply-To: <20260618-scmi-modalias-v2-0-8c7547c1be21@oss.qualcomm.com>
SCMI client drivers already describe their bus match data with
MODULE_DEVICE_TABLE(scmi, ...), but modpost does not know how to consume
SCMI device tables. As a result, SCMI modules do not get generated module
aliases from their id tables.
Move struct scmi_device_id to mod_devicetable.h so it has a fixed layout
visible to modpost, add the corresponding generated offsets and teach
file2alias to emit scmi:<protocol>:<name> aliases.
Use the same stable alias format for SCMI device uevents and sysfs
modaliases. The previous string included the instance-specific device
name, which is not useful for matching modules.
Assisted-by: Codex:GPT-5.5
Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
---
drivers/clk/clk-scmi.c | 1 +
drivers/cpufreq/scmi-cpufreq.c | 1 +
drivers/firmware/arm_scmi/bus.c | 20 ++++++++++----------
drivers/firmware/arm_scmi/driver.c | 1 +
drivers/firmware/arm_scmi/scmi_power_control.c | 1 +
drivers/firmware/imx/sm-cpu.c | 1 +
drivers/firmware/imx/sm-lmm.c | 1 +
drivers/firmware/imx/sm-misc.c | 1 +
drivers/hwmon/scmi-hwmon.c | 1 +
drivers/iio/common/scmi_sensors/scmi_iio.c | 1 +
drivers/input/keyboard/imx-sm-bbm-key.c | 1 +
drivers/pmdomain/arm/scmi_perf_domain.c | 1 +
drivers/pmdomain/arm/scmi_pm_domain.c | 1 +
drivers/powercap/arm_scmi_powercap.c | 1 +
drivers/regulator/scmi-regulator.c | 1 +
drivers/reset/reset-scmi.c | 1 +
drivers/rtc/rtc-imx-sm-bbm.c | 1 +
include/linux/mod_devicetable.h | 11 +++++++++++
include/linux/scmi_protocol.h | 5 +----
scripts/mod/devicetable-offsets.c | 4 ++++
scripts/mod/file2alias.c | 11 +++++++++++
21 files changed, 53 insertions(+), 14 deletions(-)
diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c
index 7c562559ad8b..b9e29e124302 100644
--- a/drivers/clk/clk-scmi.c
+++ b/drivers/clk/clk-scmi.c
@@ -11,6 +11,7 @@
#include <linux/err.h>
#include <linux/of.h>
#include <linux/module.h>
+#include <linux/mod_devicetable.h>
#include <linux/scmi_protocol.h>
#define NOT_ATOMIC false
diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c
index 4edb4f7a8aa9..affa005bf8b1 100644
--- a/drivers/cpufreq/scmi-cpufreq.c
+++ b/drivers/cpufreq/scmi-cpufreq.c
@@ -15,6 +15,7 @@
#include <linux/energy_model.h>
#include <linux/export.h>
#include <linux/module.h>
+#include <linux/mod_devicetable.h>
#include <linux/of.h>
#include <linux/pm_opp.h>
#include <linux/pm_qos.h>
diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
index 793be9eabaed..70781146fa61 100644
--- a/drivers/firmware/arm_scmi/bus.c
+++ b/drivers/firmware/arm_scmi/bus.c
@@ -10,14 +10,16 @@
#include <linux/atomic.h>
#include <linux/types.h>
#include <linux/module.h>
+#include <linux/mod_devicetable.h>
#include <linux/of.h>
#include <linux/kernel.h>
#include <linux/slab.h>
+#include <linux/string.h>
#include <linux/device.h>
#include "common.h"
-#define SCMI_UEVENT_MODALIAS_FMT "%s:%02x:%s"
+#define SCMI_UEVENT_MODALIAS_FMT SCMI_MODULE_PREFIX "%02x:%s"
BLOCKING_NOTIFIER_HEAD(scmi_requested_devices_nh);
EXPORT_SYMBOL_GPL(scmi_requested_devices_nh);
@@ -141,7 +143,7 @@ static int scmi_protocol_table_register(const struct scmi_device_id *id_table)
int ret = 0;
const struct scmi_device_id *entry;
- for (entry = id_table; entry->name && ret == 0; entry++)
+ for (entry = id_table; entry->name[0] && ret == 0; entry++)
ret = scmi_protocol_device_request(entry);
return ret;
@@ -197,18 +199,18 @@ scmi_protocol_table_unregister(const struct scmi_device_id *id_table)
{
const struct scmi_device_id *entry;
- for (entry = id_table; entry->name; entry++)
+ for (entry = id_table; entry->name[0]; entry++)
scmi_protocol_device_unrequest(entry);
}
static int scmi_dev_match_by_id_table(struct scmi_device *scmi_dev,
const struct scmi_device_id *id_table)
{
- if (!id_table || !id_table->name)
+ if (!id_table || !id_table->name[0])
return 0;
/* Always skip transport devices from matching */
- for (; id_table->protocol_id && id_table->name; id_table++)
+ for (; id_table->protocol_id && id_table->name[0]; id_table++)
if (id_table->protocol_id == scmi_dev->protocol_id &&
strncmp(scmi_dev->name, "__scmi_transport_device", 23) &&
!strcmp(id_table->name, scmi_dev->name))
@@ -245,7 +247,7 @@ static struct scmi_device *scmi_child_dev_find(struct device *parent,
struct device *dev;
id_table[0].protocol_id = prot_id;
- id_table[0].name = name;
+ strscpy(id_table[0].name, name, sizeof(id_table[0].name));
dev = device_find_child(parent, &id_table, scmi_match_by_id_table);
if (!dev)
@@ -282,8 +284,7 @@ static int scmi_device_uevent(const struct device *dev, struct kobj_uevent_env *
const struct scmi_device *scmi_dev = to_scmi_dev(dev);
return add_uevent_var(env, "MODALIAS=" SCMI_UEVENT_MODALIAS_FMT,
- dev_name(&scmi_dev->dev), scmi_dev->protocol_id,
- scmi_dev->name);
+ scmi_dev->protocol_id, scmi_dev->name);
}
static ssize_t modalias_show(struct device *dev,
@@ -292,8 +293,7 @@ static ssize_t modalias_show(struct device *dev,
struct scmi_device *scmi_dev = to_scmi_dev(dev);
return sysfs_emit(buf, SCMI_UEVENT_MODALIAS_FMT,
- dev_name(&scmi_dev->dev), scmi_dev->protocol_id,
- scmi_dev->name);
+ scmi_dev->protocol_id, scmi_dev->name);
}
static DEVICE_ATTR_RO(modalias);
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 3e0d975ec94c..0fd6a947499e 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -30,6 +30,7 @@
#include <linux/hashtable.h>
#include <linux/list.h>
#include <linux/module.h>
+#include <linux/mod_devicetable.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/processor.h>
diff --git a/drivers/firmware/arm_scmi/scmi_power_control.c b/drivers/firmware/arm_scmi/scmi_power_control.c
index 955736336061..1900bb77383e 100644
--- a/drivers/firmware/arm_scmi/scmi_power_control.c
+++ b/drivers/firmware/arm_scmi/scmi_power_control.c
@@ -45,6 +45,7 @@
#include <linux/math.h>
#include <linux/module.h>
+#include <linux/mod_devicetable.h>
#include <linux/mutex.h>
#include <linux/pm.h>
#include <linux/printk.h>
diff --git a/drivers/firmware/imx/sm-cpu.c b/drivers/firmware/imx/sm-cpu.c
index 091b014f739f..53a8d1cee5ea 100644
--- a/drivers/firmware/imx/sm-cpu.c
+++ b/drivers/firmware/imx/sm-cpu.c
@@ -5,6 +5,7 @@
#include <linux/firmware/imx/sm.h>
#include <linux/module.h>
+#include <linux/mod_devicetable.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/scmi_protocol.h>
diff --git a/drivers/firmware/imx/sm-lmm.c b/drivers/firmware/imx/sm-lmm.c
index 6807bf563c03..f4dc198187a8 100644
--- a/drivers/firmware/imx/sm-lmm.c
+++ b/drivers/firmware/imx/sm-lmm.c
@@ -5,6 +5,7 @@
#include <linux/firmware/imx/sm.h>
#include <linux/module.h>
+#include <linux/mod_devicetable.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/scmi_protocol.h>
diff --git a/drivers/firmware/imx/sm-misc.c b/drivers/firmware/imx/sm-misc.c
index ac9af824c2d4..5e39e79a9d8a 100644
--- a/drivers/firmware/imx/sm-misc.c
+++ b/drivers/firmware/imx/sm-misc.c
@@ -7,6 +7,7 @@
#include <linux/device/devres.h>
#include <linux/firmware/imx/sm.h>
#include <linux/module.h>
+#include <linux/mod_devicetable.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/scmi_protocol.h>
diff --git a/drivers/hwmon/scmi-hwmon.c b/drivers/hwmon/scmi-hwmon.c
index eec223d174c0..57b91e931c5d 100644
--- a/drivers/hwmon/scmi-hwmon.c
+++ b/drivers/hwmon/scmi-hwmon.c
@@ -8,6 +8,7 @@
#include <linux/hwmon.h>
#include <linux/module.h>
+#include <linux/mod_devicetable.h>
#include <linux/scmi_protocol.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
diff --git a/drivers/iio/common/scmi_sensors/scmi_iio.c b/drivers/iio/common/scmi_sensors/scmi_iio.c
index 442b40ef27cf..3babc4261965 100644
--- a/drivers/iio/common/scmi_sensors/scmi_iio.c
+++ b/drivers/iio/common/scmi_sensors/scmi_iio.c
@@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/module.h>
+#include <linux/mod_devicetable.h>
#include <linux/mutex.h>
#include <linux/scmi_protocol.h>
#include <linux/time.h>
diff --git a/drivers/input/keyboard/imx-sm-bbm-key.c b/drivers/input/keyboard/imx-sm-bbm-key.c
index 96486bd23d60..36e349136ee7 100644
--- a/drivers/input/keyboard/imx-sm-bbm-key.c
+++ b/drivers/input/keyboard/imx-sm-bbm-key.c
@@ -6,6 +6,7 @@
#include <linux/input.h>
#include <linux/jiffies.h>
#include <linux/module.h>
+#include <linux/mod_devicetable.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/rtc.h>
diff --git a/drivers/pmdomain/arm/scmi_perf_domain.c b/drivers/pmdomain/arm/scmi_perf_domain.c
index 3693423459c9..741375ad325b 100644
--- a/drivers/pmdomain/arm/scmi_perf_domain.c
+++ b/drivers/pmdomain/arm/scmi_perf_domain.c
@@ -8,6 +8,7 @@
#include <linux/err.h>
#include <linux/device.h>
#include <linux/module.h>
+#include <linux/mod_devicetable.h>
#include <linux/pm_domain.h>
#include <linux/pm_opp.h>
#include <linux/scmi_protocol.h>
diff --git a/drivers/pmdomain/arm/scmi_pm_domain.c b/drivers/pmdomain/arm/scmi_pm_domain.c
index 3d73aef21d2f..0948d05c9e3c 100644
--- a/drivers/pmdomain/arm/scmi_pm_domain.c
+++ b/drivers/pmdomain/arm/scmi_pm_domain.c
@@ -8,6 +8,7 @@
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
+#include <linux/mod_devicetable.h>
#include <linux/pm_domain.h>
#include <linux/scmi_protocol.h>
diff --git a/drivers/powercap/arm_scmi_powercap.c b/drivers/powercap/arm_scmi_powercap.c
index ab66e9a3b1e2..332e4e26f1e5 100644
--- a/drivers/powercap/arm_scmi_powercap.c
+++ b/drivers/powercap/arm_scmi_powercap.c
@@ -10,6 +10,7 @@
#include <linux/limits.h>
#include <linux/list.h>
#include <linux/module.h>
+#include <linux/mod_devicetable.h>
#include <linux/powercap.h>
#include <linux/scmi_protocol.h>
#include <linux/slab.h>
diff --git a/drivers/regulator/scmi-regulator.c b/drivers/regulator/scmi-regulator.c
index c005e65ba0ec..f55f228cb133 100644
--- a/drivers/regulator/scmi-regulator.c
+++ b/drivers/regulator/scmi-regulator.c
@@ -25,6 +25,7 @@
#include <linux/linear_range.h>
#include <linux/module.h>
+#include <linux/mod_devicetable.h>
#include <linux/of.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
diff --git a/drivers/reset/reset-scmi.c b/drivers/reset/reset-scmi.c
index 4335811e0cfa..a6739df1d3c2 100644
--- a/drivers/reset/reset-scmi.c
+++ b/drivers/reset/reset-scmi.c
@@ -6,6 +6,7 @@
*/
#include <linux/module.h>
+#include <linux/mod_devicetable.h>
#include <linux/of.h>
#include <linux/device.h>
#include <linux/reset-controller.h>
diff --git a/drivers/rtc/rtc-imx-sm-bbm.c b/drivers/rtc/rtc-imx-sm-bbm.c
index daa472be7c80..c8643718cef1 100644
--- a/drivers/rtc/rtc-imx-sm-bbm.c
+++ b/drivers/rtc/rtc-imx-sm-bbm.c
@@ -5,6 +5,7 @@
#include <linux/jiffies.h>
#include <linux/module.h>
+#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
#include <linux/rtc.h>
#include <linux/scmi_protocol.h>
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 3b0c9a251a2e..769382f2eadd 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -473,6 +473,17 @@ struct rpmsg_device_id {
kernel_ulong_t driver_data;
};
+/* scmi */
+
+#define SCMI_NAME_SIZE 32
+#define SCMI_MODULE_PREFIX "scmi:"
+
+struct scmi_device_id {
+ __u8 protocol_id;
+ char name[SCMI_NAME_SIZE];
+ kernel_ulong_t driver_data;
+};
+
/* i2c */
#define I2C_NAME_SIZE 20
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index 5ab73b1ab9aa..61f5ecfe0133 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -951,10 +951,7 @@ struct scmi_device {
#define to_scmi_dev(d) container_of_const(d, struct scmi_device, dev)
-struct scmi_device_id {
- u8 protocol_id;
- const char *name;
-};
+struct scmi_device_id;
struct scmi_driver {
const char *name;
diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c
index b4178c42d08f..da5bd712c8da 100644
--- a/scripts/mod/devicetable-offsets.c
+++ b/scripts/mod/devicetable-offsets.c
@@ -144,6 +144,10 @@ int main(void)
DEVID(rpmsg_device_id);
DEVID_FIELD(rpmsg_device_id, name);
+ DEVID(scmi_device_id);
+ DEVID_FIELD(scmi_device_id, protocol_id);
+ DEVID_FIELD(scmi_device_id, name);
+
DEVID(i2c_device_id);
DEVID_FIELD(i2c_device_id, name);
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 8d36c74dec2d..a5283f4c8e6f 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -852,6 +852,16 @@ static void do_rpmsg_entry(struct module *mod, void *symval)
module_alias_printf(mod, false, RPMSG_DEVICE_MODALIAS_FMT, *name);
}
+/* Looks like: scmi:NN:S */
+static void do_scmi_entry(struct module *mod, void *symval)
+{
+ DEF_FIELD(symval, scmi_device_id, protocol_id);
+ DEF_FIELD_ADDR(symval, scmi_device_id, name);
+
+ module_alias_printf(mod, false, SCMI_MODULE_PREFIX "%02x:%s",
+ protocol_id, *name);
+}
+
/* Looks like: i2c:S */
static void do_i2c_entry(struct module *mod, void *symval)
{
@@ -1491,6 +1501,7 @@ static const struct devtable devtable[] = {
{"virtio", SIZE_virtio_device_id, do_virtio_entry},
{"vmbus", SIZE_hv_vmbus_device_id, do_vmbus_entry},
{"rpmsg", SIZE_rpmsg_device_id, do_rpmsg_entry},
+ {"scmi", SIZE_scmi_device_id, do_scmi_entry},
{"i2c", SIZE_i2c_device_id, do_i2c_entry},
{"i3c", SIZE_i3c_device_id, do_i3c_entry},
{"slim", SIZE_slim_device_id, do_slim_entry},
--
2.53.0
^ permalink raw reply related
* [PATCH v2 2/2] firmware: arm_scmi: request modules for discovered protocols
From: Bjorn Andersson @ 2026-06-18 15:56 UTC (permalink / raw)
To: Sudeep Holla, Cristian Marussi, Nathan Chancellor, Nicolas Schier,
Michael Turquette
Cc: arm-scmi, linux-arm-kernel, linux-kernel, linux-kbuild,
Hans de Goede, Bjorn Andersson, Stephen Boyd, Brian Masney,
Rafael J. Wysocki, Viresh Kumar, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, Guenter Roeck,
Jyoti Bhayana, Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko, Dmitry Torokhov, Ulf Hansson, Liam Girdwood,
Mark Brown, Philipp Zabel, Alexandre Belloni, linux-clk, linux-pm,
imx, linux-hwmon, linux-iio, linux-input, linux-rtc
In-Reply-To: <20260618-scmi-modalias-v2-0-8c7547c1be21@oss.qualcomm.com>
SCMI client devices are created from SCMI driver id tables. If such a
driver is modular, the core does not know the driver's client name until
the module has already loaded, so normal device uevent based autoloading
cannot break the dependency cycle.
Emit a protocol-level alias for each SCMI device id table entry and
request that alias when the SCMI core discovers an implemented protocol.
This loads modules that have registered interest in the protocol; their
normal SCMI driver registration then requests the concrete client device
and the SCMI bus matches it by protocol and name.
This allows e.g. ARM_SCMI_CPUFREQ=m to autoload on systems that expose
only the SCMI Performance protocol node, where the cpufreq client name
is Linux-internal and not available from firmware before loading the
module.
Assisted-by: Codex:GPT-5.5
Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
---
drivers/firmware/arm_scmi/driver.c | 2 ++
include/linux/mod_devicetable.h | 1 +
scripts/mod/file2alias.c | 4 +++-
3 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 0fd6a947499e..7d33fab94e28 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -48,6 +48,7 @@
#include <trace/events/scmi.h>
#define SCMI_VENDOR_MODULE_ALIAS_FMT "scmi-protocol-0x%02x-%s"
+#define SCMI_MODULE_ALIAS_FMT SCMI_PROTOCOL_MODULE_PREFIX "0x%02x"
static DEFINE_IDA(scmi_id);
@@ -3363,6 +3364,7 @@ static int scmi_probe(struct platform_device *pdev)
}
of_node_get(child);
+ request_module_nowait(SCMI_MODULE_ALIAS_FMT, prot_id);
scmi_create_protocol_devices(child, info, prot_id, NULL);
}
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 769382f2eadd..2cc7e78e35a3 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -477,6 +477,7 @@ struct rpmsg_device_id {
#define SCMI_NAME_SIZE 32
#define SCMI_MODULE_PREFIX "scmi:"
+#define SCMI_PROTOCOL_MODULE_PREFIX "scmi-protocol-"
struct scmi_device_id {
__u8 protocol_id;
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index a5283f4c8e6f..40a37b6bf1ad 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -852,7 +852,7 @@ static void do_rpmsg_entry(struct module *mod, void *symval)
module_alias_printf(mod, false, RPMSG_DEVICE_MODALIAS_FMT, *name);
}
-/* Looks like: scmi:NN:S */
+/* Looks like: scmi:NN:S and scmi-protocol-0xNN */
static void do_scmi_entry(struct module *mod, void *symval)
{
DEF_FIELD(symval, scmi_device_id, protocol_id);
@@ -860,6 +860,8 @@ static void do_scmi_entry(struct module *mod, void *symval)
module_alias_printf(mod, false, SCMI_MODULE_PREFIX "%02x:%s",
protocol_id, *name);
+ module_alias_printf(mod, false, SCMI_PROTOCOL_MODULE_PREFIX "0x%02x",
+ protocol_id);
}
/* Looks like: i2c:S */
--
2.53.0
^ permalink raw reply related
* [PATCH v2 0/2] firmware: arm_scmi: Ensure automatic module loading
From: Bjorn Andersson @ 2026-06-18 15:56 UTC (permalink / raw)
To: Sudeep Holla, Cristian Marussi, Nathan Chancellor, Nicolas Schier,
Michael Turquette
Cc: arm-scmi, linux-arm-kernel, linux-kernel, linux-kbuild,
Hans de Goede, Bjorn Andersson, Stephen Boyd, Brian Masney,
Rafael J. Wysocki, Viresh Kumar, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, Guenter Roeck,
Jyoti Bhayana, Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko, Dmitry Torokhov, Ulf Hansson, Liam Girdwood,
Mark Brown, Philipp Zabel, Alexandre Belloni, linux-clk, linux-pm,
imx, linux-hwmon, linux-iio, linux-input, linux-rtc
SCMI drivers such as the Arm SCMI CPUfreq driver are allowed to built as
modules, but they are then not automatically loaded. Rework the SCMI
device table alias support to make modpost consume the information from
MODULE_DEVICE_TABLE(scmi, ...) and allow drivers to be loaded based on
this information, if known. Also add a protocol-based alias to also
trigger driver loading when only the SCMI protocol id is known.
Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
---
Changes in v2:
- Use request_module_nowait()
- Drop #include <linux/mod_devicetable.h> from scmi_protocol.h
- Link to v1: https://patch.msgid.link/20260616-scmi-modalias-v1-0-662b8dd52ab2@oss.qualcomm.com
To: Sudeep Holla <sudeep.holla@kernel.org>
To: Cristian Marussi <cristian.marussi@arm.com>
To: Michael Turquette <mturquette@baylibre.com>
To: Nicolas Schier <nsc@kernel.org>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: Brian Masney <bmasney@redhat.com>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Viresh Kumar <viresh.kumar@linaro.org>
Cc: Frank Li <Frank.Li@nxp.com>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Guenter Roeck <linux@roeck-us.net>
Cc: Jyoti Bhayana <jbhayana@google.com>
Cc: Jonathan Cameron <jic23@kernel.org>
Cc: David Lechner <dlechner@baylibre.com>
Cc: Nuno Sá <nuno.sa@analog.com>
Cc: Andy Shevchenko <andy@kernel.org>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Ulf Hansson <ulfh@kernel.org>
Cc: Liam Girdwood <lgirdwood@gmail.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Philipp Zabel <p.zabel@pengutronix.de>
Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: arm-scmi@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-pm@vger.kernel.org
Cc: imx@lists.linux.dev
Cc: linux-hwmon@vger.kernel.org
Cc: linux-iio@vger.kernel.org
Cc: linux-input@vger.kernel.org
Cc: linux-rtc@vger.kernel.org
Cc: linux-kbuild@vger.kernel.org
---
Bjorn Andersson (2):
module: add SCMI device table alias support
firmware: arm_scmi: request modules for discovered protocols
drivers/clk/clk-scmi.c | 1 +
drivers/cpufreq/scmi-cpufreq.c | 1 +
drivers/firmware/arm_scmi/bus.c | 20 ++++++++++----------
drivers/firmware/arm_scmi/driver.c | 3 +++
drivers/firmware/arm_scmi/scmi_power_control.c | 1 +
drivers/firmware/imx/sm-cpu.c | 1 +
drivers/firmware/imx/sm-lmm.c | 1 +
drivers/firmware/imx/sm-misc.c | 1 +
drivers/hwmon/scmi-hwmon.c | 1 +
drivers/iio/common/scmi_sensors/scmi_iio.c | 1 +
drivers/input/keyboard/imx-sm-bbm-key.c | 1 +
drivers/pmdomain/arm/scmi_perf_domain.c | 1 +
drivers/pmdomain/arm/scmi_pm_domain.c | 1 +
drivers/powercap/arm_scmi_powercap.c | 1 +
drivers/regulator/scmi-regulator.c | 1 +
drivers/reset/reset-scmi.c | 1 +
drivers/rtc/rtc-imx-sm-bbm.c | 1 +
include/linux/mod_devicetable.h | 12 ++++++++++++
include/linux/scmi_protocol.h | 5 +----
scripts/mod/devicetable-offsets.c | 4 ++++
scripts/mod/file2alias.c | 13 +++++++++++++
21 files changed, 58 insertions(+), 14 deletions(-)
---
base-commit: 8d6dbbbe3ba62de0a63e962ee004afb848c8e3ac
change-id: 20260616-scmi-modalias-0f32421bd452
Best regards,
--
Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
^ permalink raw reply
* Re: [PATCH 3/3] dt-bindings: spi: nxp,imx94-xspi: add DMA properties
From: Mark Brown @ 2026-06-18 15:54 UTC (permalink / raw)
To: han.xu
Cc: Han Xu, Haibo Chen, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam, linux-spi, imx, devicetree, linux-arm-kernel,
linux-kernel
In-Reply-To: <20260617215520.3327836-3-han.xu@oss.nxp.com>
[-- Attachment #1: Type: text/plain, Size: 539 bytes --]
On Wed, Jun 17, 2026 at 04:55:19PM -0500, han.xu@oss.nxp.com wrote:
> From: Han Xu <han.xu@nxp.com>
>
> Add dmas and dma-names to describe TX and RX DMA channels for the i.MX94
> XSPI controller.
Please submit patches using subject lines reflecting the style for the
subsystem, this makes it easier for people to identify relevant patches.
Look at what existing commits in the area you're changing are doing and
make sure your subject lines visually resemble what they're doing.
There's no need to resubmit to fix this alone.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* [PATCH kvmtool v2 7/7] arm64: Improve KVM_ARM_VCPU_PMU_V3_CTRL diagnostics
From: Alexandru Elisei @ 2026-06-18 15:50 UTC (permalink / raw)
To: will, julien.thierry.kdev, maz, oupton, jean-philippe.brucker,
andre.przywara, suzuki.poulose, kvm, linux-arm-kernel, kvmarm
In-Reply-To: <20260618155001.226266-1-alexandru.elisei@arm.com>
kvmtool issues several ioctls when configuring the PMU, and each of them
can fail for different reasons. Be more specific about the ioctl that
failed when that happens.
Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
arm64/pmu.c | 31 ++++++++++++++++++++++++-------
1 file changed, 24 insertions(+), 7 deletions(-)
diff --git a/arm64/pmu.c b/arm64/pmu.c
index 92cacd62479e..78c15f153fad 100644
--- a/arm64/pmu.c
+++ b/arm64/pmu.c
@@ -12,6 +12,24 @@
#include "asm/pmu.h"
+static const char *pmu_attr_names[] = {
+ [KVM_ARM_VCPU_PMU_V3_IRQ] = "KVM_ARM_VCPU_PMU_V3_IRQ",
+ [KVM_ARM_VCPU_PMU_V3_INIT] = "KVM_ARM_VCPU_PMU_V3_INIT",
+ [KVM_ARM_VCPU_PMU_V3_FILTER] = "KVM_ARM_VCPU_PMU_V3_FILTER",
+ [KVM_ARM_VCPU_PMU_V3_SET_PMU] = "KVM_ARM_VCPU_PMU_V3_SET_PMU",
+ [KVM_ARM_VCPU_PMU_V3_SET_NR_COUNTERS] = "KVM_ARM_VCPU_PMU_V3_SET_NR_COUNTER",
+};
+
+static const char *pmu_get_attr_name(u64 attr)
+{
+ switch (attr) {
+ case KVM_ARM_VCPU_PMU_V3_IRQ ... KVM_ARM_VCPU_PMU_V3_SET_NR_COUNTERS:
+ return pmu_attr_names[attr];
+ default:
+ return "UNKNOWN";
+ }
+}
+
static bool pmu_has_attr(struct kvm_cpu *vcpu, u64 attr)
{
struct kvm_device_attr pmu_attr = {
@@ -32,13 +50,12 @@ static void set_pmu_attr(struct kvm_cpu *vcpu, void *addr, u64 attr)
};
int ret;
- if (pmu_has_attr(vcpu, attr)) {
- ret = ioctl(vcpu->vcpu_fd, KVM_SET_DEVICE_ATTR, &pmu_attr);
- if (ret)
- die_perror("PMU KVM_SET_DEVICE_ATTR");
- } else {
- die_perror("PMU KVM_HAS_DEVICE_ATTR");
- }
+ if (!pmu_has_attr(vcpu, attr))
+ die_perror("KVM_HAS_DEVICE_ATTR(%s)", pmu_get_attr_name(attr));
+
+ ret = ioctl(vcpu->vcpu_fd, KVM_SET_DEVICE_ATTR, &pmu_attr);
+ if (ret)
+ die_perror("KVM_SET_DEVICE_ATTR(%s)", pmu_get_attr_name(attr));
}
#define SYS_EVENT_SOURCE "/sys/bus/event_source/devices/"
--
2.54.0
^ permalink raw reply related
* [PATCH kvmtool v2 6/7] util: Allow die_perror() to take a variable list of argument
From: Alexandru Elisei @ 2026-06-18 15:50 UTC (permalink / raw)
To: will, julien.thierry.kdev, maz, oupton, jean-philippe.brucker,
andre.przywara, suzuki.poulose, kvm, linux-arm-kernel, kvmarm
In-Reply-To: <20260618155001.226266-1-alexandru.elisei@arm.com>
Make die_perror() more similar to die() by allowing the user to specify
a format string and arguments.
Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
include/kvm/util.h | 2 +-
util/util.c | 17 +++++++++++++++--
2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/include/kvm/util.h b/include/kvm/util.h
index ac8515f8c46b..a6dba1147d68 100644
--- a/include/kvm/util.h
+++ b/include/kvm/util.h
@@ -41,7 +41,7 @@
#define MAP_ANON_NORESERVE (MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE)
extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
-extern void die_perror(const char *s) NORETURN;
+extern void die_perror(const char *fmt, ...) NORETURN __attribute__((format (printf, 1, 2)));
extern void pr_err(const char *err, ...) __attribute__((format (printf, 1, 2)));
extern void pr_warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
extern void pr_info(const char *err, ...) __attribute__((format (printf, 1, 2)));
diff --git a/util/util.c b/util/util.c
index fc732200f2dc..6f41e2c1b008 100644
--- a/util/util.c
+++ b/util/util.c
@@ -1,6 +1,7 @@
/*
* Taken from perf which in turn take it from GIT
*/
+#include <stdio.h>
#include "kvm/util.h"
@@ -98,11 +99,23 @@ void __pr_debug(const char *debug, ...)
va_end(params);
}
-void die_perror(const char *s)
+void die_perror(const char *fmt, ...)
{
+ char buf[1024];
+ va_list params;
int e = errno;
+ int ret;
+
+ va_start(params, fmt);
+ ret = vsnprintf(buf, sizeof(buf), fmt, params);
+ if (ret < 0) {
+ perror("vsnprintf");
+ buf[0] = '\0';
+ }
+ va_end(params);
- perror(s);
+ errno = e;
+ perror(buf);
exit(e);
}
--
2.54.0
^ permalink raw reply related
* [PATCH kvmtool v2 5/7] util: Set exit status to errno in die_perror()
From: Alexandru Elisei @ 2026-06-18 15:49 UTC (permalink / raw)
To: will, julien.thierry.kdev, maz, oupton, jean-philippe.brucker,
andre.przywara, suzuki.poulose, kvm, linux-arm-kernel, kvmarm
In-Reply-To: <20260618155001.226266-1-alexandru.elisei@arm.com>
Exit with a return code equal to errno in die_perror() to make it easier
for the user to get the error code directly.
As per man 3 perror, errno is undefined after a successful library call, so
save it when entering die_perror().
Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
util/util.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/util/util.c b/util/util.c
index bab4bb394111..fc732200f2dc 100644
--- a/util/util.c
+++ b/util/util.c
@@ -100,8 +100,10 @@ void __pr_debug(const char *debug, ...)
void die_perror(const char *s)
{
+ int e = errno;
+
perror(s);
- exit(1);
+ exit(e);
}
void *mmap_hugetlbfs(struct kvm *kvm, const char *htlbfs_path, u64 size)
--
2.54.0
^ permalink raw reply related
* [PATCH kvmtool v2 1/7] x86: Define bioscall only in 32-bit mode
From: Alexandru Elisei @ 2026-06-18 15:49 UTC (permalink / raw)
To: will, julien.thierry.kdev, maz, oupton, jean-philippe.brucker,
andre.przywara, suzuki.poulose, kvm, linux-arm-kernel, kvmarm
In-Reply-To: <20260618155001.226266-1-alexandru.elisei@arm.com>
The gcc online docs define the behaviour of the regparm attribute for
x86-32 targets [1], and there's no mention of the behaviour for the 64-bit
version of the architecure.
gcc version 16.1 throws this error when compiling for x86-64:
x86/include/kvm/bios.h:91:43: error: ‘regparm’ attribute ignored [-Werror=attributes]
91 | extern bioscall void int10_handler(struct biosregs *regs);
| ^~~~~~~~
but there's no such error with gcc version 14.2.
This patch author assumes that somewhere between gcc 14.2 and 16.1 the
compiler behaviour was modified to treat the regparm attribute on x86_64
as unused. Fix the compilation error by using it only for the 32-bit
version of the x86 architecture.
[1] https://gcc.gnu.org/onlinedocs/gcc-16.1.0/gcc/x86-Attributes.html#index-regparm_002c-x86
Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
x86/include/kvm/bios.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/x86/include/kvm/bios.h b/x86/include/kvm/bios.h
index 6f4338d50717..76beb2e0a46b 100644
--- a/x86/include/kvm/bios.h
+++ b/x86/include/kvm/bios.h
@@ -62,11 +62,15 @@
#define MB_BIOS_SS 0xfff7
#define MB_BIOS_SP 0x40
+#ifdef CONFIG_X86_32
/*
* When interfere with assembler code we need to be sure how
* arguments are passed in real mode.
*/
#define bioscall __attribute__((regparm(3)))
+#else
+#define bioscall
+#endif
#ifndef __ASSEMBLER__
--
2.54.0
^ permalink raw reply related
* [PATCH kvmtool v2 3/7] disk/core: Do not modify const strings in disk_img_name_parser()
From: Alexandru Elisei @ 2026-06-18 15:49 UTC (permalink / raw)
To: will, julien.thierry.kdev, maz, oupton, jean-philippe.brucker,
andre.przywara, suzuki.poulose, kvm, linux-arm-kernel, kvmarm
In-Reply-To: <20260618155001.226266-1-alexandru.elisei@arm.com>
@arg is const char *, but disk_img_name_parser() modifies it, which leads
to a compilation error on x86 with gcc 15.2.1:
disk/core.c:27:21: error: assignment discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers]
27 | sep = strstr(arg, ":");
Make a copy of @arg and modify it instead, and be very careful to free it
when no longer needed.
Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
disk/core.c | 44 +++++++++++++++++++++++++++-------------
include/kvm/disk-image.h | 6 +++---
2 files changed, 33 insertions(+), 17 deletions(-)
diff --git a/disk/core.c b/disk/core.c
index 91db277f7846..b232eece9e73 100644
--- a/disk/core.c
+++ b/disk/core.c
@@ -13,35 +13,42 @@ static int disk_image__close(struct disk_image *disk);
int disk_img_name_parser(const struct option *opt, const char *arg, int unset)
{
- const char *cur;
- char *sep;
+ struct disk_image_params *params;
struct kvm *kvm = opt->ptr;
+ char *cur, *sep;
if (kvm->nr_disks >= MAX_DISK_IMAGES)
die("Currently only 4 images are supported");
- kvm->cfg.disk_image[kvm->nr_disks].filename = arg;
- cur = arg;
+ params = &kvm->cfg.disk_image[kvm->nr_disks];
if (strncmp(arg, "scsi:", 5) == 0) {
- sep = strstr(arg, ":");
- kvm->cfg.disk_image[kvm->nr_disks].wwpn = sep + 1;
+ params->wwpn = strdup(strstr(arg, ":") + 1);
+ if (!params->wwpn)
+ die_perror("strdup");
/* Old invocation had two parameters. Ignore the second one. */
- sep = strstr(sep + 1, ":");
+ sep = strstr(params->wwpn, ":");
if (sep) {
*sep = 0;
cur = sep + 1;
+ } else {
+ cur = params->wwpn;
}
+ } else {
+ params->filename = strdup(arg);
+ if (!params->filename)
+ die_perror("strdup");
+ cur = params->filename;
}
do {
sep = strstr(cur, ",");
if (sep) {
if (strncmp(sep + 1, "ro", 2) == 0)
- kvm->cfg.disk_image[kvm->nr_disks].readonly = true;
+ params->readonly = true;
else if (strncmp(sep + 1, "direct", 6) == 0)
- kvm->cfg.disk_image[kvm->nr_disks].direct = true;
+ params->direct = true;
*sep = 0;
cur = sep + 1;
}
@@ -145,8 +152,7 @@ static struct disk_image *disk_image__open(const char *filename, bool readonly,
static struct disk_image **disk_image__open_all(struct kvm *kvm)
{
struct disk_image **disks;
- const char *filename;
- const char *wwpn;
+ char *filename, *wwpn;
bool readonly;
bool direct;
void *err;
@@ -189,18 +195,27 @@ static struct disk_image **disk_image__open_all(struct kvm *kvm)
goto error;
}
disks[i]->debug_iodelay = kvm->cfg.debug_iodelay;
+
+ free(params[i].filename);
+ params[i].filename = NULL;
}
return disks;
error:
for (i = 0; i < count; i++) {
- if (IS_ERR_OR_NULL(disks[i]))
+ free(params[i].filename);
+
+ if (IS_ERR_OR_NULL(disks[i])) {
+ free(params[i].wwpn);
continue;
+ }
- if (disks[i]->wwpn)
+ if (disks[i]->wwpn) {
+ free(disks[i]->wwpn);
free(disks[i]);
- else
+ } else {
disk_image__close(disks[i]);
+ }
}
free(disks);
return err;
@@ -236,6 +251,7 @@ static int disk_image__close(struct disk_image *disk)
if (disk->fd && close(disk->fd) < 0)
pr_warning("close() failed");
+ free(disk->wwpn);
free(disk);
return 0;
diff --git a/include/kvm/disk-image.h b/include/kvm/disk-image.h
index bf602b582a3b..cbe91b07af0b 100644
--- a/include/kvm/disk-image.h
+++ b/include/kvm/disk-image.h
@@ -47,9 +47,9 @@ struct disk_image_operations {
};
struct disk_image_params {
- const char *filename;
+ char *filename;
/* wwpn == World Wide Port Number */
- const char *wwpn;
+ char *wwpn;
bool readonly;
bool direct;
};
@@ -69,7 +69,7 @@ struct disk_image {
pthread_t thread;
u64 aio_inflight;
#endif /* CONFIG_HAS_AIO */
- const char *wwpn;
+ char *wwpn;
int debug_iodelay;
};
--
2.54.0
^ permalink raw reply related
* [PATCH kvmtool v2 4/7] arm64: Initialise the PMU after the GIC
From: Alexandru Elisei @ 2026-06-18 15:49 UTC (permalink / raw)
To: will, julien.thierry.kdev, maz, oupton, jean-philippe.brucker,
andre.przywara, suzuki.poulose, kvm, linux-arm-kernel, kvmarm
In-Reply-To: <20260618155001.226266-1-alexandru.elisei@arm.com>
PMU initialisation is done in:
setup_fdt()
vcpu->generate_fdt_nodes()
pmu__generate_fdt_nodes()
The PMU ioctl KVM_ARM_VCPU_PMU_V3_INIT requires that the GIC has been
initialised, which is done in gic__init_gic().
gic__init_gic() and setup_fdt() are part of the same initialisation list.
The relative order on the list depends on the order of compilation: gic.c
is compiled after fdt.c and this places gic__init_gic() first on the
initialisation list.
If the compilation order changes and gic.c is compiled *before* fdt.c,
gic__init_gic() will be executed *after* setup_fdt() and PMU initialisation
will fail with an error message:
PMU KVM_SET_DEVICE_ATTR: No such device
This is fragile and hard to debug. Improve the situation by having
gic__init_gic() explicitely initialize the PMU.
Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
arm64/gic.c | 9 ++++++++-
arm64/include/asm/pmu.h | 3 +++
arm64/pmu.c | 28 ++++++++++++++++++----------
3 files changed, 29 insertions(+), 11 deletions(-)
diff --git a/arm64/gic.c b/arm64/gic.c
index b0be9e5766df..1e4009625595 100644
--- a/arm64/gic.c
+++ b/arm64/gic.c
@@ -9,6 +9,8 @@
#include <linux/kvm.h>
#include <linux/sizes.h>
+#include <asm/pmu.h>
+
#define IRQCHIP_GIC 0
#define GIC_MAINT_IRQ 9
@@ -355,7 +357,12 @@ static int gic__init_gic(struct kvm *kvm)
vgic_is_init = true;
- return irq__setup_irqfd_lines(kvm);
+ ret = irq__setup_irqfd_lines(kvm);
+ if (ret)
+ return ret;
+
+ /* The PMU requires that the GIC has been initialized. */
+ return pmu__init(kvm);
}
late_init(gic__init_gic)
diff --git a/arm64/include/asm/pmu.h b/arm64/include/asm/pmu.h
index 38e3154b11b7..74566943f355 100644
--- a/arm64/include/asm/pmu.h
+++ b/arm64/include/asm/pmu.h
@@ -3,6 +3,9 @@
#define KVM_ARM_PMUv3_PPI 23
+struct kvm;
+
void pmu__generate_fdt_nodes(void *fdt, struct kvm *kvm);
+int pmu__init(struct kvm *kvm);
#endif /* __ARM_PMU_H__ */
diff --git a/arm64/pmu.c b/arm64/pmu.c
index 5f31d6b6f346..92cacd62479e 100644
--- a/arm64/pmu.c
+++ b/arm64/pmu.c
@@ -193,21 +193,32 @@ static int find_pmu(struct kvm *kvm)
void pmu__generate_fdt_nodes(void *fdt, struct kvm *kvm)
{
const char compatible[] = "arm,armv8-pmuv3";
- int irq = KVM_ARM_PMUv3_PPI;
- struct kvm_cpu *vcpu;
- int pmu_id = -ENXIO;
- int i;
-
u32 cpu_mask = gic__get_fdt_irq_cpumask(kvm);
u32 irq_prop[] = {
cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI),
- cpu_to_fdt32(irq - 16),
+ cpu_to_fdt32(KVM_ARM_PMUv3_PPI - 16),
cpu_to_fdt32(cpu_mask | IRQ_TYPE_LEVEL_HIGH),
};
if (!kvm->cfg.arch.has_pmuv3)
return;
+ _FDT(fdt_begin_node(fdt, "pmu"));
+ _FDT(fdt_property(fdt, "compatible", compatible, sizeof(compatible)));
+ _FDT(fdt_property(fdt, "interrupts", irq_prop, sizeof(irq_prop)));
+ _FDT(fdt_end_node(fdt));
+}
+
+int pmu__init(struct kvm *kvm)
+{
+ int irq = KVM_ARM_PMUv3_PPI;
+ struct kvm_cpu *vcpu;
+ int pmu_id = -ENXIO;
+ int i;
+
+ if (!kvm->cfg.arch.has_pmuv3)
+ return 0;
+
if (pmu_has_attr(kvm->cpus[0], KVM_ARM_VCPU_PMU_V3_SET_PMU)) {
pmu_id = find_pmu(kvm);
if (pmu_id < 0) {
@@ -228,8 +239,5 @@ void pmu__generate_fdt_nodes(void *fdt, struct kvm *kvm)
set_pmu_attr(vcpu, NULL, KVM_ARM_VCPU_PMU_V3_INIT);
}
- _FDT(fdt_begin_node(fdt, "pmu"));
- _FDT(fdt_property(fdt, "compatible", compatible, sizeof(compatible)));
- _FDT(fdt_property(fdt, "interrupts", irq_prop, sizeof(irq_prop)));
- _FDT(fdt_end_node(fdt));
+ return 0;
}
--
2.54.0
^ permalink raw reply related
* [PATCH kvmtool v2 2/7] virtio: Do not modify const strings in virtio_9p_rootdir_parser()
From: Alexandru Elisei @ 2026-06-18 15:49 UTC (permalink / raw)
To: will, julien.thierry.kdev, maz, oupton, jean-philippe.brucker,
andre.przywara, suzuki.poulose, kvm, linux-arm-kernel, kvmarm
In-Reply-To: <20260618155001.226266-1-alexandru.elisei@arm.com>
Even though @arg is of type const char *, virtio_9p_rootdir_parser()
modifies it it if a tag name is specified, leading to the following
compilation error on an x86_64 machine with gcc 15.2.1:
virtio/9p.c:1503:18: error: assignment discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers]
1503 | tag_name = strstr(arg, ",");
Fix it by copying @arg to a local string, which can then be modified
in-place.
Also use die_perror() if realpath() fails, to provide more information to
the user.
Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
virtio/9p.c | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/virtio/9p.c b/virtio/9p.c
index e6f669c49895..cf3e547d3173 100644
--- a/virtio/9p.c
+++ b/virtio/9p.c
@@ -1491,25 +1491,32 @@ struct virtio_ops p9_dev_virtio_ops = {
int virtio_9p_rootdir_parser(const struct option *opt, const char *arg, int unset)
{
- char *tag_name;
- char tmp[PATH_MAX];
struct kvm *kvm = opt->ptr;
+ char *tag_name, *copy;
+ char path[PATH_MAX];
+ copy = strdup(arg);
+ if (!copy)
+ die_perror("strdup");
/*
* 9p dir can be of the form dirname,tag_name or
* just dirname. In the later case we use the
* default tag name
*/
- tag_name = strstr(arg, ",");
+ tag_name = strstr(copy, ",");
if (tag_name) {
*tag_name = '\0';
tag_name++;
}
- if (realpath(arg, tmp)) {
- if (virtio_9p__register(kvm, tmp, tag_name) < 0)
+ if (realpath(copy, path)) {
+ if (virtio_9p__register(kvm, path, tag_name) < 0)
die("Unable to initialize virtio 9p");
- } else
- die("Failed resolving 9p path");
+ } else {
+ die_perror("Failed resolving 9p path");
+ }
+
+ free(copy);
+
return 0;
}
--
2.54.0
^ permalink raw reply related
* [PATCH kvmtool v2 0/7] x86 compilation fixes and arm64 PMU improvements
From: Alexandru Elisei @ 2026-06-18 15:49 UTC (permalink / raw)
To: will, julien.thierry.kdev, maz, oupton, jean-philippe.brucker,
andre.przywara, suzuki.poulose, kvm, linux-arm-kernel, kvmarm
v1 here [1].
v1 was sent to fix this compilation error:
disk/core.c: In function ‘disk_img_name_parser’:
disk/core.c:27:21: error: assignment discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers]
27 | sep = strstr(arg, ":");
| ^
fixed in patches #2 and #3.
Working on v2 found another one:
x86/include/kvm/bios.h:91:43: error: ‘regparm’ attribute ignored [-Werror=attributes]
91 | extern bioscall void int10_handler(struct biosregs *regs);
| ^~~~~~~~
which is fixed in patch #1.
The remaining of the patches are there to improve PMU initialisation and
error reporting.
Tested on arm64, with and without hugetlbfs, with and without a PMU. Also
tested on arm64 using scsi-virtio (got it working in v2, I couldn't get
scsi-virtio working for v1, most likely user error).
Tested on x86_64 by booting a VM. Don't have an x86_32 machine to do the
same, but I did cross-compile for x86_32.
Changes in v2:
- Patch #1 ("x86: Define bioscall only in 32-bit mode") is new. The bug
that it fixes was probably triggered when I updated the gcc compiler.
- pmu__init() is now called from gic__init_gic() (Will).
- die_perror() prints the original errno is vsnprintf() fails (Will).
[1] https://lore.kernel.org/kvm/20260323150221.49256-1-alexandru.elisei@arm.com/
Alexandru Elisei (7):
x86: Define bioscall only in 32-bit mode
virtio: Do not modify const strings in virtio_9p_rootdir_parser()
disk/core: Do not modify const strings in disk_img_name_parser()
arm64: Initialise the PMU after the GIC
util: Set exit status to errno in die_perror()
util: Allow die_perror() to take a variable list of argument
arm64: Improve KVM_ARM_VCPU_PMU_V3_CTRL diagnostics
arm64/gic.c | 9 +++++-
arm64/include/asm/pmu.h | 3 ++
arm64/pmu.c | 59 ++++++++++++++++++++++++++++------------
disk/core.c | 44 ++++++++++++++++++++----------
include/kvm/disk-image.h | 6 ++--
include/kvm/util.h | 2 +-
util/util.c | 21 ++++++++++++--
virtio/9p.c | 21 +++++++++-----
x86/include/kvm/bios.h | 4 +++
9 files changed, 123 insertions(+), 46 deletions(-)
base-commit: 6c2de8d9531c7e9aad7ac6701e848bedb3f1d3a4
--
2.54.0
^ permalink raw reply
* Re: [PATCH RFC 3/3] arm64: Add HOTPLUG_PARALLEL support for secondary CPUs
From: Thomas Gleixner @ 2026-06-18 15:49 UTC (permalink / raw)
To: Jinjie Ruan, catalin.marinas, will, tsbogend, pjw, palmer, aou,
alex, mingo, bp, dave.hansen, hpa, peterz, kees, nathan, linusw,
ojeda, ruanjinjie, david.kaplan, lukas.bulwahn, ryan.roberts, maz,
timothy.hayes, lpieralisi, thuth, oupton, yeoreum.yun,
miko.lenczewski, broonie, kevin.brodsky, james.clark, tabba,
mrigendra.chaubey, arnd, anshuman.khandual, x86, linux-kernel,
linux-arm-kernel, linux-mips, linux-riscv
In-Reply-To: <20260611133809.3854977-4-ruanjinjie@huawei.com>
On Thu, Jun 11 2026 at 21:38, Jinjie Ruan wrote:
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -113,6 +113,7 @@ config ARM64
> select CPUMASK_OFFSTACK if NR_CPUS > 256
> select DCACHE_WORD_ACCESS
> select HAVE_EXTRA_IPI_TRACEPOINTS
> + select HOTPLUG_PARALLEL if SMP && HOTPLUG_CPU
Why do you tie that to HOTPLUG_CPU? HOTPLUG_CPU lets you unplug/plug
CPUs at runtime, but if its disabled then a SMP system still has to
bring up the APs. So why should that fall back to the existing variant?
> +#ifdef CONFIG_HOTPLUG_PARALLEL
> +extern struct secondary_data cpu_boot_data[NR_CPUS];
> +#endif
> +
> extern struct secondary_data secondary_data;
> extern long __early_cpu_boot_status;
> extern void secondary_entry(void);
> @@ -124,7 +128,11 @@ static inline void __noreturn cpu_park_loop(void)
>
> static inline void update_cpu_boot_status(unsigned int cpu, int val)
> {
> +#ifdef CONFIG_HOTPLUG_PARALLEL
> + WRITE_ONCE(cpu_boot_data[cpu].status, val);
> +#else
> WRITE_ONCE(secondary_data.status, val);
> +#endif
You're really a great fan of #ifdefs, right?
Just convert it over to the parallel mode unconditionally and get rid of
the existing cruft.
> /*
> * TTBR0 is only used for the identity mapping at this stage. Make it
> * point to zero page to avoid speculatively fetching new entries.
> @@ -254,7 +276,9 @@ asmlinkage notrace void secondary_start_kernel(void)
> read_cpuid_id());
> update_cpu_boot_status(cpu, CPU_BOOT_SUCCESS);
> set_cpu_online(cpu, true);
> +#ifndef CONFIG_HOTPLUG_PARALLEL
> complete(&cpu_running);
> +#endif
Just for the record. You can get rid of this completion w/o PARALLEL
hotplug by selecting HOTPLUG_SPLIT_STARTUP and implementing the
kick/sync parts.
Thanks,
tglx
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox