From: Kameron Carr <kameroncarr@linux.microsoft.com>
To: 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,
mhklinux@outlook.com
Subject: [RFC PATCH 3/6] arm64: hyperv: Add per-CPU RSI host call infrastructure for CCA Realms
Date: Tue, 9 Jun 2026 11:10:27 -0700 [thread overview]
Message-ID: <20260609181030.2378391-4-kameroncarr@linux.microsoft.com> (raw)
In-Reply-To: <20260609181030.2378391-1-kameroncarr@linux.microsoft.com>
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.
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
next prev parent reply other threads:[~2026-06-09 18:10 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-09 18:10 [RFC PATCH 0/6] arm64: hyperv: Add Realm support for Hyper-V Kameron Carr
2026-06-09 18:10 ` [RFC PATCH 1/6] arm64: rsi: Add RSI host call structure and helper function Kameron Carr
2026-06-09 18:20 ` sashiko-bot
2026-06-09 18:10 ` [RFC PATCH 2/6] firmware: smccc: Detect hypervisor via RSI host call in CCA Realms Kameron Carr
2026-06-09 18:24 ` sashiko-bot
2026-06-09 18:10 ` Kameron Carr [this message]
2026-06-09 18:51 ` [RFC PATCH 3/6] arm64: hyperv: Add per-CPU RSI host call infrastructure for " sashiko-bot
2026-06-09 18:10 ` [RFC PATCH 4/6] Drivers: hv: Mark shared memory as decrypted " Kameron Carr
2026-06-09 18:27 ` sashiko-bot
2026-06-09 18:10 ` [RFC PATCH 5/6] arm64: hyperv: Route hypercalls through RSI host call in " Kameron Carr
2026-06-09 18:50 ` sashiko-bot
2026-06-09 18:10 ` [RFC PATCH 6/6] arm64: hyperv: Implement hv_is_isolation_supported() for " Kameron Carr
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260609181030.2378391-4-kameroncarr@linux.microsoft.com \
--to=kameroncarr@linux.microsoft.com \
--cc=arnd@arndb.de \
--cc=catalin.marinas@arm.com \
--cc=decui@microsoft.com \
--cc=haiyangz@microsoft.com \
--cc=kys@microsoft.com \
--cc=linux-arch@vger.kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-hyperv@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=longli@microsoft.com \
--cc=lpieralisi@kernel.org \
--cc=mark.rutland@arm.com \
--cc=mhklinux@outlook.com \
--cc=sudeep.holla@kernel.org \
--cc=thuth@redhat.com \
--cc=wei.liu@kernel.org \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.