RE: [PATCH v2 3/6] arm64: hyperv: Add per-CPU RSI host call infrastructure for CCA Realms
Michael Kelley <[email protected]>
| Newsgroups | org.kernel.vger.linux-hyperv,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-arch,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <SN6PR02MB4157D9A0C6527A896780EC63D4EC2@SN6PR02MB4157.namprd02.prod.outlook.com> |
From: Kameron Carr <[email protected]> Sent: Thursday, June 25, 2026 10:35 AM > To: [email protected]; [email protected]; [email protected]; > [email protected]; [email protected] > Cc: [email protected]; [email protected]; [email protected]; > [email protected]; [email protected]; [email protected]; [email protected]; linux- > [email protected]; [email protected]; linux- > [email protected]; [email protected]; [email protected] > Subject: [PATCH v2 3/6] arm64: hyperv: Add per-CPU RSI host call infrastructure for CCA > Realms > > 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 hv_hostcall_array as a per-CPU struct array and allocate it during > hyperv_init(). The allocation is gated on is_realm_world() so non-Realm > arm64 Hyper-V guests pay no memory cost. > > Signed-off-by: Kameron Carr <[email protected]> > --- > arch/arm64/hyperv/mshyperv.c | 32 ++++++++++++++++++++++++++++++- > arch/arm64/include/asm/mshyperv.h | 4 ++++ > 2 files changed, 35 insertions(+), 1 deletion(-) > > diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c > index 4fdc26ade1d74..7d536d7fb557e 100644 > --- a/arch/arm64/hyperv/mshyperv.c > +++ b/arch/arm64/hyperv/mshyperv.c > @@ -15,10 +15,15 @@ > #include <linux/errno.h> > #include <linux/version.h> > #include <linux/cpuhotplug.h> > +#include <linux/slab.h> > #include <asm/mshyperv.h> > +#include <asm/rsi.h> > > static bool hyperv_initialized; > > +struct rsi_host_call *hv_hostcall_array; > +EXPORT_SYMBOL_GPL(hv_hostcall_array); > + > int hv_get_hypervisor_version(union hv_hypervisor_version_info *info) > { > hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION, > @@ -60,6 +65,12 @@ static bool __init hyperv_detect_via_acpi(void) > > #endif > > +static void hv_hostcall_free(void) > +{ > + kfree(hv_hostcall_array); > + hv_hostcall_array = NULL; > +} > + > static bool __init hyperv_detect_via_smccc(void) > { > uuid_t hyperv_uuid = UUID_INIT( > @@ -85,6 +96,20 @@ static int __init hyperv_init(void) > if (!hyperv_detect_via_acpi() && !hyperv_detect_via_smccc()) > return 0; > > + /* > + * The RSI host-call buffers are only ever used when > + * is_realm_world() is true. Skip the allocation on non-Realm > + * guests. A single contiguous array of nr_cpu_ids entries is > + * allocated; each CPU indexes into it by its processor ID. > + */ > + if (is_realm_world()) { > + hv_hostcall_array = kcalloc(nr_cpu_ids, > + sizeof(struct rsi_host_call), > + GFP_KERNEL); > + if (!hv_hostcall_array) > + return -ENOMEM; > + } > + > /* 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 +131,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); > if (ret < 0) { > hv_common_free(); > + hv_hostcall_free(); > return ret; Let me suggest a small additional simplification. For this error path, call hv_common_free() as you have now, but then do "goto free_hostcall_mem". At the free_hostcall_mem label, do kfree(hv_hostcall_array); hv_hostcall_array = NULL; directly inline, and eliminate the hv_hostcall_free() helper function. Saves about 5 lines of code overall and I think is a bit simpler. > } > > @@ -125,6 +151,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..c207a3f79b99b 100644 > --- a/arch/arm64/include/asm/mshyperv.h > +++ b/arch/arm64/include/asm/mshyperv.h > @@ -63,4 +63,8 @@ static inline u64 hv_get_non_nested_msr(unsigned int reg) > > #include <asm-generic/mshyperv.h> > > +/* Per-CPU-indexed RSI host call structures for CCA Realms */ > +struct rsi_host_call; > +extern struct rsi_host_call *hv_hostcall_array; > + The intent is that the #include of asm-generic/mshyperv.h should be last in the arch-specific version of mshyperv.h. If there's a need to go after the #include, that's a red flag to check if some restructuring of the definitions would be appropriate. Unless I'm missing something, I think these new definitions can go above the #include. Michael > #endif > -- > 2.45.4 >