* [PATCH v6 1/6] arm64: rsi: Add RSI host call structure and helper function
2026-10-31 0:14 [PATCH v6 0/6] arm64: hyperv: Add Realm support for Hyper-V Kameron Carr
@ 2026-10-31 0:14 ` Kameron Carr
2026-10-31 4:51 ` Dexuan Cui
2026-10-31 0:14 ` [PATCH v6 2/6] arm64: hyperv: Detect Hyper-V via RSI host call in CCA Realms Kameron Carr
` (4 subsequent siblings)
5 siblings, 1 reply; 18+ messages in thread
From: Kameron Carr @ 2026-10-31 0:14 UTC (permalink / raw)
To: decui, haiyangz, mhklinux, wei.liu
Cc: arnd, catalin.marinas, linux-arch, linux-arm-kernel,
linux-hyperv, linux-kernel, lpieralisi, mark.rutland,
sudeep.holla, thuth, will
Add struct rsi_host_call to arm-smccc-rsi.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 arm-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.
Reviewed-by: Michael Kelley <mhklinux@outlook.com>
Signed-off-by: Kameron Carr <kameroncarr@linux.microsoft.com>
---
include/linux/arm-rsi-cmds.h | 22 ++++++++++++++++++++++
include/linux/arm-smccc-rsi.h | 7 +++++++
2 files changed, 29 insertions(+)
diff --git a/include/linux/arm-rsi-cmds.h b/include/linux/arm-rsi-cmds.h
index 3f7a6a8..01d292e 100644
--- a/include/linux/arm-rsi-cmds.h
+++ b/include/linux/arm-rsi-cmds.h
@@ -236,4 +236,26 @@ static inline unsigned long rsi_attestation_token_continue(phys_addr_t granule,
return res.a0;
}
+/**
+ * rsi_host_call - Make a Host call.
+ * @host_call_struct: IPA of host call structure
+ *
+ * This call will fail if the IPA of the host call structure:
+ * * is not aligned to 256 bytes,
+ * * is not protected / encrypted,
+ * * is RIPAS_EMPTY
+ *
+ * Returns:
+ * On success, returns RSI_SUCCESS.
+ * Otherwise, returns an error code.
+ */
+static inline unsigned 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;
+}
+
#endif /* __LINUX_ARM_RSI_CMDS_H_ */
diff --git a/include/linux/arm-smccc-rsi.h b/include/linux/arm-smccc-rsi.h
index fddb779..4c8530b 100644
--- a/include/linux/arm-smccc-rsi.h
+++ b/include/linux/arm-smccc-rsi.h
@@ -142,6 +142,13 @@ struct realm_config {
*/
} __aligned(0x1000);
+struct rsi_host_call {
+ u16 immediate;
+ u8 _padding[6];
+ u64 gprs[31];
+} __aligned(256);
+static_assert(sizeof(struct rsi_host_call) == 256);
+
#endif /* __ASSEMBLER__ */
/*
--
2.45.4
^ permalink raw reply [flat|nested] 18+ messages in thread* RE: [PATCH v6 1/6] arm64: rsi: Add RSI host call structure and helper function
2026-10-31 0:14 ` [PATCH v6 1/6] arm64: rsi: Add RSI host call structure and helper function Kameron Carr
@ 2026-10-31 4:51 ` Dexuan Cui
2026-11-02 12:10 ` Catalin Marinas
0 siblings, 1 reply; 18+ messages in thread
From: Dexuan Cui @ 2026-10-31 4:51 UTC (permalink / raw)
To: Kameron Carr, Haiyang Zhang, mhklinux, wei.liu
Cc: arnd, catalin.marinas, linux-arch, linux-arm-kernel,
linux-hyperv, linux-kernel, lpieralisi, Mark.Rutland,
sudeep.holla, thuth, will
> From: Kameron Carr <kameroncarr@linux.microsoft.com>
> Sent: Friday, October 30, 2026 5:14 PM
> To: Dexuan Cui <DECUI@microsoft.com>; Haiyang Zhang
> <haiyangz@microsoft.com>; mhklinux@outlook.com; wei.liu@kernel.org
> Cc: arnd@arndb.de; catalin.marinas@arm.com; linux-arch@vger.kernel.org;
> linux-arm-kernel@lists.infradead.org; linux-hyperv@vger.kernel.org; linux-
> kernel@vger.kernel.org; lpieralisi@kernel.org; Mark.Rutland
> <Mark.Rutland@arm.com>; sudeep.holla@kernel.org; thuth@redhat.com;
> will@kernel.org
> Subject: [PATCH v6 1/6] arm64: rsi: Add RSI host call structure and helper
> function
>
> Add struct rsi_host_call to arm-smccc-rsi.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 arm-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.
>
> Reviewed-by: Michael Kelley <mhklinux@outlook.com>
> Signed-off-by: Kameron Carr <kameroncarr@linux.microsoft.com>
> ---
Catalin provided Reviewed-by to v5's patch #1, which is the same
as v6's patch #1:
https://lore.kernel.org/all/auPOxoaRbdOEHnv_@arm.com/
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v6 1/6] arm64: rsi: Add RSI host call structure and helper function
2026-10-31 4:51 ` Dexuan Cui
@ 2026-11-02 12:10 ` Catalin Marinas
0 siblings, 0 replies; 18+ messages in thread
From: Catalin Marinas @ 2026-11-02 12:10 UTC (permalink / raw)
To: Dexuan Cui
Cc: Kameron Carr, Haiyang Zhang, mhklinux, wei.liu, arnd, linux-arch,
linux-arm-kernel, linux-hyperv, linux-kernel, lpieralisi,
Mark.Rutland, sudeep.holla, thuth, will
On Sat, Oct 31, 2026 at 04:51:21AM +0000, Dexuan Cui wrote:
> > From: Kameron Carr <kameroncarr@linux.microsoft.com>
> > Sent: Friday, October 30, 2026 5:14 PM
> > To: Dexuan Cui <DECUI@microsoft.com>; Haiyang Zhang
> > <haiyangz@microsoft.com>; mhklinux@outlook.com; wei.liu@kernel.org
> > Cc: arnd@arndb.de; catalin.marinas@arm.com; linux-arch@vger.kernel.org;
> > linux-arm-kernel@lists.infradead.org; linux-hyperv@vger.kernel.org; linux-
> > kernel@vger.kernel.org; lpieralisi@kernel.org; Mark.Rutland
> > <Mark.Rutland@arm.com>; sudeep.holla@kernel.org; thuth@redhat.com;
> > will@kernel.org
> > Subject: [PATCH v6 1/6] arm64: rsi: Add RSI host call structure and helper
> > function
> >
> > Add struct rsi_host_call to arm-smccc-rsi.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 arm-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.
> >
> > Reviewed-by: Michael Kelley <mhklinux@outlook.com>
> > Signed-off-by: Kameron Carr <kameroncarr@linux.microsoft.com>
> > ---
>
> Catalin provided Reviewed-by to v5's patch #1, which is the same
> as v6's patch #1:
> https://lore.kernel.org/all/auPOxoaRbdOEHnv_@arm.com/
Yes, my review still stands.
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v6 2/6] arm64: hyperv: Detect Hyper-V via RSI host call in CCA Realms
2026-10-31 0:14 [PATCH v6 0/6] arm64: hyperv: Add Realm support for Hyper-V Kameron Carr
2026-10-31 0:14 ` [PATCH v6 1/6] arm64: rsi: Add RSI host call structure and helper function Kameron Carr
@ 2026-10-31 0:14 ` Kameron Carr
2026-11-02 12:12 ` Catalin Marinas
2026-10-31 0:14 ` [PATCH v6 3/6] arm64: hyperv: Add per-CPU RSI host call infrastructure for " Kameron Carr
` (3 subsequent siblings)
5 siblings, 1 reply; 18+ messages in thread
From: Kameron Carr @ 2026-10-31 0:14 UTC (permalink / raw)
To: decui, haiyangz, mhklinux, wei.liu
Cc: arnd, catalin.marinas, linux-arch, linux-arm-kernel,
linux-hyperv, linux-kernel, lpieralisi, mark.rutland,
sudeep.holla, thuth, will
When booting without ACPI, hyperv_detect_via_smccc() detects Hyper-V by
querying the SMCCC vendor hypervisor UID. In an Arm CCA Realm the SMCCC
call is handled by the RMM rather than by the hypervisor, so the
query never reaches Hyper-V and detection fails.
When running in a Realm, forward ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID
to the host with RSI_HOST_CALL instead, which is how Hyper-V hypercalls
are issued from a Realm.
This is done in the Hyper-V code rather than in the generic
arm_smccc_hypervisor_has_uuid() because the other users expect different
behavior.
hyperv_init() is an early_initcall and runs before the secondary CPUs
are brought up, so a single __initdata host call structure is used
without locking.
ACPI-based detection and non-Realm guests are unaffected.
Signed-off-by: Kameron Carr <kameroncarr@linux.microsoft.com>
---
arch/arm64/hyperv/mshyperv.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
index 4fdc26a..82572c5 100644
--- a/arch/arm64/hyperv/mshyperv.c
+++ b/arch/arm64/hyperv/mshyperv.c
@@ -11,6 +11,7 @@
#include <linux/types.h>
#include <linux/acpi.h>
+#include <linux/arm-rsi-cmds.h>
#include <linux/export.h>
#include <linux/errno.h>
#include <linux/version.h>
@@ -60,6 +61,27 @@ static bool __init hyperv_detect_via_acpi(void)
#endif
+/*
+ * In a Realm, the SMCCC call is handled by the RMM rather than by
+ * Hyper-V, so the vendor hypervisor UID query must be forwarded to the
+ * host with RSI_HOST_CALL, in the same way as hypercalls.
+ */
+static bool __init hyperv_realm_has_uuid(const uuid_t *hyperv_uuid)
+{
+ static struct rsi_host_call hc __initdata;
+ uuid_t uuid;
+
+ hc.gprs[0] = ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID;
+
+ if (rsi_host_call(__pa_symbol(&hc)) != RSI_SUCCESS ||
+ hc.gprs[0] == SMCCC_RET_NOT_SUPPORTED)
+ return false;
+
+ uuid = smccc_res_to_uuid(hc.gprs[0], hc.gprs[1], hc.gprs[2],
+ hc.gprs[3]);
+ return uuid_equal(&uuid, hyperv_uuid);
+}
+
static bool __init hyperv_detect_via_smccc(void)
{
uuid_t hyperv_uuid = UUID_INIT(
@@ -67,6 +89,9 @@ static bool __init hyperv_detect_via_smccc(void)
0x75, 0x6c, 0xef, 0x8e,
0x24, 0x70, 0x59, 0x16);
+ if (is_realm_world())
+ return hyperv_realm_has_uuid(&hyperv_uuid);
+
return arm_smccc_hypervisor_has_uuid(&hyperv_uuid);
}
--
2.45.4
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v6 2/6] arm64: hyperv: Detect Hyper-V via RSI host call in CCA Realms
2026-10-31 0:14 ` [PATCH v6 2/6] arm64: hyperv: Detect Hyper-V via RSI host call in CCA Realms Kameron Carr
@ 2026-11-02 12:12 ` Catalin Marinas
2026-11-02 19:27 ` Kameron Carr
0 siblings, 1 reply; 18+ messages in thread
From: Catalin Marinas @ 2026-11-02 12:12 UTC (permalink / raw)
To: Kameron Carr
Cc: decui, haiyangz, mhklinux, wei.liu, arnd, linux-arch,
linux-arm-kernel, linux-hyperv, linux-kernel, lpieralisi,
mark.rutland, sudeep.holla, thuth, will
On Fri, Oct 30, 2026 at 05:14:08PM -0700, Kameron Carr wrote:
> When booting without ACPI, hyperv_detect_via_smccc() detects Hyper-V by
> querying the SMCCC vendor hypervisor UID. In an Arm CCA Realm the SMCCC
> call is handled by the RMM rather than by the hypervisor, so the
> query never reaches Hyper-V and detection fails.
>
> When running in a Realm, forward ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID
> to the host with RSI_HOST_CALL instead, which is how Hyper-V hypercalls
> are issued from a Realm.
>
> This is done in the Hyper-V code rather than in the generic
> arm_smccc_hypervisor_has_uuid() because the other users expect different
> behavior.
>
> hyperv_init() is an early_initcall and runs before the secondary CPUs
> are brought up, so a single __initdata host call structure is used
> without locking.
>
> ACPI-based detection and non-Realm guests are unaffected.
>
> Signed-off-by: Kameron Carr <kameroncarr@linux.microsoft.com>
This works for me, thanks. I replied to Dexuan clarifying my objection
to v5 do the UUID check generically.
--
Catalin
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v6 2/6] arm64: hyperv: Detect Hyper-V via RSI host call in CCA Realms
2026-11-02 12:12 ` Catalin Marinas
@ 2026-11-02 19:27 ` Kameron Carr
2026-11-03 14:01 ` Catalin Marinas
0 siblings, 1 reply; 18+ messages in thread
From: Kameron Carr @ 2026-11-02 19:27 UTC (permalink / raw)
To: Catalin Marinas
Cc: decui, haiyangz, mhklinux, wei.liu, arnd, linux-arch,
linux-arm-kernel, linux-hyperv, linux-kernel, lpieralisi,
mark.rutland, sudeep.holla, thuth, will
On 11/2/2026 4:12 AM, Catalin Marinas wrote:
> On Fri, Oct 30, 2026 at 05:14:08PM -0700, Kameron Carr wrote:
>> When booting without ACPI, hyperv_detect_via_smccc() detects Hyper-V by
>> querying the SMCCC vendor hypervisor UID. In an Arm CCA Realm the SMCCC
>> call is handled by the RMM rather than by the hypervisor, so the
>> query never reaches Hyper-V and detection fails.
>>
>> When running in a Realm, forward ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID
>> to the host with RSI_HOST_CALL instead, which is how Hyper-V hypercalls
>> are issued from a Realm.
>>
>> This is done in the Hyper-V code rather than in the generic
>> arm_smccc_hypervisor_has_uuid() because the other users expect different
>> behavior.
>>
>> hyperv_init() is an early_initcall and runs before the secondary CPUs
>> are brought up, so a single __initdata host call structure is used
>> without locking.
>>
>> ACPI-based detection and non-Realm guests are unaffected.
>>
>> Signed-off-by: Kameron Carr <kameroncarr@linux.microsoft.com>
>
> This works for me, thanks. I replied to Dexuan clarifying my objection
> to v5 do the UUID check generically.
Thank you for your review and suggestions.
Your clarification makes sense.
Is this a "Reviewed-by" or an "Acked-by"?
--
Regards,
Kameron
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v6 2/6] arm64: hyperv: Detect Hyper-V via RSI host call in CCA Realms
2026-11-02 19:27 ` Kameron Carr
@ 2026-11-03 14:01 ` Catalin Marinas
0 siblings, 0 replies; 18+ messages in thread
From: Catalin Marinas @ 2026-11-03 14:01 UTC (permalink / raw)
To: Kameron Carr
Cc: decui, haiyangz, mhklinux, wei.liu, arnd, linux-arch,
linux-arm-kernel, linux-hyperv, linux-kernel, lpieralisi,
mark.rutland, sudeep.holla, thuth, will
On Mon, Nov 02, 2026 at 11:27:37AM -0800, Kameron Carr wrote:
> On 11/2/2026 4:12 AM, Catalin Marinas wrote:
> > On Fri, Oct 30, 2026 at 05:14:08PM -0700, Kameron Carr wrote:
> >> When booting without ACPI, hyperv_detect_via_smccc() detects Hyper-V by
> >> querying the SMCCC vendor hypervisor UID. In an Arm CCA Realm the SMCCC
> >> call is handled by the RMM rather than by the hypervisor, so the
> >> query never reaches Hyper-V and detection fails.
> >>
> >> When running in a Realm, forward ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID
> >> to the host with RSI_HOST_CALL instead, which is how Hyper-V hypercalls
> >> are issued from a Realm.
> >>
> >> This is done in the Hyper-V code rather than in the generic
> >> arm_smccc_hypervisor_has_uuid() because the other users expect different
> >> behavior.
> >>
> >> hyperv_init() is an early_initcall and runs before the secondary CPUs
> >> are brought up, so a single __initdata host call structure is used
> >> without locking.
> >>
> >> ACPI-based detection and non-Realm guests are unaffected.
> >>
> >> Signed-off-by: Kameron Carr <kameroncarr@linux.microsoft.com>
> >
> > This works for me, thanks. I replied to Dexuan clarifying my objection
> > to v5 do the UUID check generically.
>
> Thank you for your review and suggestions.
> Your clarification makes sense.
>
> Is this a "Reviewed-by" or an "Acked-by"?
I don't usually ack the hyperv patches as I don't know enough about it
but given that I commented on this particular patch in v5:
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
--
Catalin
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v6 3/6] arm64: hyperv: Add per-CPU RSI host call infrastructure for CCA Realms
2026-10-31 0:14 [PATCH v6 0/6] arm64: hyperv: Add Realm support for Hyper-V Kameron Carr
2026-10-31 0:14 ` [PATCH v6 1/6] arm64: rsi: Add RSI host call structure and helper function Kameron Carr
2026-10-31 0:14 ` [PATCH v6 2/6] arm64: hyperv: Detect Hyper-V via RSI host call in CCA Realms Kameron Carr
@ 2026-10-31 0:14 ` Kameron Carr
2026-11-11 18:00 ` Michael Kelley
2026-10-31 0:14 ` [PATCH v6 4/6] Drivers: hv: Mark shared memory as decrypted " Kameron Carr
` (2 subsequent siblings)
5 siblings, 1 reply; 18+ messages in thread
From: Kameron Carr @ 2026-10-31 0:14 UTC (permalink / raw)
To: decui, haiyangz, mhklinux, wei.liu
Cc: arnd, catalin.marinas, linux-arch, linux-arm-kernel,
linux-hyperv, linux-kernel, lpieralisi, mark.rutland,
sudeep.holla, thuth, will
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.
Reviewed-by: Michael Kelley <mhklinux@outlook.com>
Signed-off-by: Kameron Carr <kameroncarr@linux.microsoft.com>
---
arch/arm64/hyperv/mshyperv.c | 27 +++++++++++++++++++++++++--
arch/arm64/include/asm/mshyperv.h | 4 ++++
2 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
index 82572c5..46ab2da 100644
--- a/arch/arm64/hyperv/mshyperv.c
+++ b/arch/arm64/hyperv/mshyperv.c
@@ -14,12 +14,16 @@
#include <linux/arm-rsi-cmds.h>
#include <linux/export.h>
#include <linux/errno.h>
+#include <linux/slab.h>
#include <linux/version.h>
#include <linux/cpuhotplug.h>
#include <asm/mshyperv.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,
@@ -110,6 +114,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);
@@ -131,13 +149,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();
- return ret;
+ goto free_hostcall_mem;
}
if (ms_hyperv.priv_high & HV_ACCESS_PARTITION_ID)
@@ -150,6 +168,11 @@ static int __init hyperv_init(void)
hyperv_initialized = true;
return 0;
+
+free_hostcall_mem:
+ kfree(hv_hostcall_array);
+ hv_hostcall_array = NULL;
+ return ret;
}
early_initcall(hyperv_init);
diff --git a/arch/arm64/include/asm/mshyperv.h b/arch/arm64/include/asm/mshyperv.h
index b721d31..aed0aa5 100644
--- a/arch/arm64/include/asm/mshyperv.h
+++ b/arch/arm64/include/asm/mshyperv.h
@@ -61,6 +61,10 @@ static inline u64 hv_get_non_nested_msr(unsigned int reg)
ARM_SMCCC_OWNER_VENDOR_HYP, \
HV_SMCCC_FUNC_NUMBER)
+/* Per-CPU-indexed RSI host call structures for CCA Realms */
+struct rsi_host_call;
+extern struct rsi_host_call *hv_hostcall_array;
+
#include <asm-generic/mshyperv.h>
#endif
--
2.45.4
^ permalink raw reply [flat|nested] 18+ messages in thread* RE: [PATCH v6 3/6] arm64: hyperv: Add per-CPU RSI host call infrastructure for CCA Realms
2026-10-31 0:14 ` [PATCH v6 3/6] arm64: hyperv: Add per-CPU RSI host call infrastructure for " Kameron Carr
@ 2026-11-11 18:00 ` Michael Kelley
2026-11-11 19:40 ` Kameron Carr
0 siblings, 1 reply; 18+ messages in thread
From: Michael Kelley @ 2026-11-11 18:00 UTC (permalink / raw)
To: Kameron Carr, decui, haiyangz, wei.liu
Cc: arnd, catalin.marinas, linux-arch, linux-arm-kernel,
linux-hyperv, linux-kernel, lpieralisi, mark.rutland,
sudeep.holla, thuth, will
From: Kameron Carr <kameroncarr@linux.microsoft.com> Sent: Friday, October 30, 2026 5:14 PM
>
> 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().
A quibble: This statement is a bit misleading. I think you mean it is a
global array with an entry for each CPU. The term "per-CPU" typically
means something allocated out of the per-CPU area.
Michael
> The allocation is gated on is_realm_world() so non-Realm
> arm64 Hyper-V guests pay no memory cost.
>
> Reviewed-by: Michael Kelley <mhklinux@outlook.com>
> Signed-off-by: Kameron Carr <kameroncarr@linux.microsoft.com>
> ---
> arch/arm64/hyperv/mshyperv.c | 27 +++++++++++++++++++++++++--
> arch/arm64/include/asm/mshyperv.h | 4 ++++
> 2 files changed, 29 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
> index 82572c5..46ab2da 100644
> --- a/arch/arm64/hyperv/mshyperv.c
> +++ b/arch/arm64/hyperv/mshyperv.c
> @@ -14,12 +14,16 @@
> #include <linux/arm-rsi-cmds.h>
> #include <linux/export.h>
> #include <linux/errno.h>
> +#include <linux/slab.h>
> #include <linux/version.h>
> #include <linux/cpuhotplug.h>
> #include <asm/mshyperv.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,
> @@ -110,6 +114,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);
> @@ -131,13 +149,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();
> - return ret;
> + goto free_hostcall_mem;
> }
>
> if (ms_hyperv.priv_high & HV_ACCESS_PARTITION_ID)
> @@ -150,6 +168,11 @@ static int __init hyperv_init(void)
>
> hyperv_initialized = true;
> return 0;
> +
> +free_hostcall_mem:
> + kfree(hv_hostcall_array);
> + hv_hostcall_array = NULL;
> + return ret;
> }
>
> early_initcall(hyperv_init);
> diff --git a/arch/arm64/include/asm/mshyperv.h
> b/arch/arm64/include/asm/mshyperv.h
> index b721d31..aed0aa5 100644
> --- a/arch/arm64/include/asm/mshyperv.h
> +++ b/arch/arm64/include/asm/mshyperv.h
> @@ -61,6 +61,10 @@ static inline u64 hv_get_non_nested_msr(unsigned int reg)
> ARM_SMCCC_OWNER_VENDOR_HYP, \
> HV_SMCCC_FUNC_NUMBER)
>
> +/* Per-CPU-indexed RSI host call structures for CCA Realms */
> +struct rsi_host_call;
> +extern struct rsi_host_call *hv_hostcall_array;
> +
> #include <asm-generic/mshyperv.h>
>
> #endif
> --
> 2.45.4
>
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v6 3/6] arm64: hyperv: Add per-CPU RSI host call infrastructure for CCA Realms
2026-11-11 18:00 ` Michael Kelley
@ 2026-11-11 19:40 ` Kameron Carr
0 siblings, 0 replies; 18+ messages in thread
From: Kameron Carr @ 2026-11-11 19:40 UTC (permalink / raw)
To: Michael Kelley, decui, haiyangz, wei.liu
Cc: arnd, catalin.marinas, linux-arch, linux-arm-kernel,
linux-hyperv, linux-kernel, lpieralisi, mark.rutland,
sudeep.holla, thuth, will
On 11/11/2026 10:00 AM, Michael Kelley wrote:
> From: Kameron Carr <kameroncarr@linux.microsoft.com> Sent: Friday, October 30, 2026 5:14 PM
>>
>> 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().
>
> A quibble: This statement is a bit misleading. I think you mean it is a
> global array with an entry for each CPU. The term "per-CPU" typically
> means something allocated out of the per-CPU area.
I agree. Earlier versions of the patch did use a per-CPU struct but it
was changed to a global array because the structure was small enough.
This series has already been applied to hyperv-next, but I can reach out
to Wei about editing the commit messages.
--
Regards,
Kameron
> Michael
>
>> The allocation is gated on is_realm_world() so non-Realm
>> arm64 Hyper-V guests pay no memory cost.
>>
>> Reviewed-by: Michael Kelley <mhklinux@outlook.com>
>> Signed-off-by: Kameron Carr <kameroncarr@linux.microsoft.com>
>> ---
>> arch/arm64/hyperv/mshyperv.c | 27 +++++++++++++++++++++++++--
>> arch/arm64/include/asm/mshyperv.h | 4 ++++
>> 2 files changed, 29 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
>> index 82572c5..46ab2da 100644
>> --- a/arch/arm64/hyperv/mshyperv.c
>> +++ b/arch/arm64/hyperv/mshyperv.c
>> @@ -14,12 +14,16 @@
>> #include <linux/arm-rsi-cmds.h>
>> #include <linux/export.h>
>> #include <linux/errno.h>
>> +#include <linux/slab.h>
>> #include <linux/version.h>
>> #include <linux/cpuhotplug.h>
>> #include <asm/mshyperv.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,
>> @@ -110,6 +114,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);
>> @@ -131,13 +149,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();
>> - return ret;
>> + goto free_hostcall_mem;
>> }
>>
>> if (ms_hyperv.priv_high & HV_ACCESS_PARTITION_ID)
>> @@ -150,6 +168,11 @@ static int __init hyperv_init(void)
>>
>> hyperv_initialized = true;
>> return 0;
>> +
>> +free_hostcall_mem:
>> + kfree(hv_hostcall_array);
>> + hv_hostcall_array = NULL;
>> + return ret;
>> }
>>
>> early_initcall(hyperv_init);
>> diff --git a/arch/arm64/include/asm/mshyperv.h
>> b/arch/arm64/include/asm/mshyperv.h
>> index b721d31..aed0aa5 100644
>> --- a/arch/arm64/include/asm/mshyperv.h
>> +++ b/arch/arm64/include/asm/mshyperv.h
>> @@ -61,6 +61,10 @@ static inline u64 hv_get_non_nested_msr(unsigned int reg)
>> ARM_SMCCC_OWNER_VENDOR_HYP, \
>> HV_SMCCC_FUNC_NUMBER)
>>
>> +/* Per-CPU-indexed RSI host call structures for CCA Realms */
>> +struct rsi_host_call;
>> +extern struct rsi_host_call *hv_hostcall_array;
>> +
>> #include <asm-generic/mshyperv.h>
>>
>> #endif
>> --
>> 2.45.4
>>
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v6 4/6] Drivers: hv: Mark shared memory as decrypted for CCA Realms
2026-10-31 0:14 [PATCH v6 0/6] arm64: hyperv: Add Realm support for Hyper-V Kameron Carr
` (2 preceding siblings ...)
2026-10-31 0:14 ` [PATCH v6 3/6] arm64: hyperv: Add per-CPU RSI host call infrastructure for " Kameron Carr
@ 2026-10-31 0:14 ` Kameron Carr
2026-11-11 18:01 ` Michael Kelley
2026-10-31 0:14 ` [PATCH v6 5/6] arm64: hyperv: Route hypercalls through RSI host call in " Kameron Carr
2026-10-31 0:14 ` [PATCH v6 6/6] arm64: hyperv: Implement hv_is_isolation_supported() for " Kameron Carr
5 siblings, 1 reply; 18+ messages in thread
From: Kameron Carr @ 2026-10-31 0:14 UTC (permalink / raw)
To: decui, haiyangz, mhklinux, wei.liu
Cc: arnd, catalin.marinas, linux-arch, linux-arm-kernel,
linux-hyperv, linux-kernel, lpieralisi, mark.rutland,
sudeep.holla, thuth, will
In hv_common_cpu_init(), the per-CPU hypercall input/output pages need
to be marked as decrypted (shared) for confidential VM isolation types.
This is already done for SNP and TDX isolation; extend the same handling
to Arm CCA Realm guests so that the host hypervisor can access the
shared hypercall buffers.
is_realm_world() is declared in include/linux/arm-rsi-cmds.h which only
builds on arm64 (it includes <asm/memory.h>), so using it directly in
the arch-neutral drivers/hv/hv_common.c would break the x86 build.
Introduce a Hyper-V-specific helper following the established
hv_isolation_type_snp() / hv_isolation_type_tdx() pattern.
On architectures other than arm64 the weak default keeps the existing
behaviour.
Reviewed-by: Michael Kelley <mhklinux@outlook.com>
Signed-off-by: Kameron Carr <kameroncarr@linux.microsoft.com>
---
arch/arm64/hyperv/mshyperv.c | 5 +++++
drivers/hv/hv_common.c | 17 +++++++++++++----
include/asm-generic/mshyperv.h | 1 +
3 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
index 46ab2da..da6c3aa0 100644
--- a/arch/arm64/hyperv/mshyperv.c
+++ b/arch/arm64/hyperv/mshyperv.c
@@ -182,3 +182,8 @@ bool hv_is_hyperv_initialized(void)
return hyperv_initialized;
}
EXPORT_SYMBOL_GPL(hv_is_hyperv_initialized);
+
+bool hv_isolation_type_cca(void)
+{
+ return is_realm_world();
+}
diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index 31256cb..a60c92c 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -476,6 +476,7 @@ int hv_common_cpu_init(unsigned int cpu)
u64 msr_vp_index;
gfp_t flags;
const int pgcount = hv_output_page_exists() ? 2 : 1;
+ const size_t alloc_size = ALIGN((size_t)pgcount * HV_HYP_PAGE_SIZE, PAGE_SIZE);
void *mem;
int ret = 0;
@@ -489,7 +490,7 @@ int hv_common_cpu_init(unsigned int cpu)
* online and then taken offline
*/
if (!*inputarg) {
- mem = kmalloc_array(pgcount, HV_HYP_PAGE_SIZE, flags);
+ mem = kmalloc(alloc_size, flags);
if (!mem)
return -ENOMEM;
@@ -499,14 +500,16 @@ int hv_common_cpu_init(unsigned int cpu)
}
if (!ms_hyperv.paravisor_present &&
- (hv_isolation_type_snp() || hv_isolation_type_tdx())) {
- ret = set_memory_decrypted((unsigned long)mem, pgcount);
+ (hv_isolation_type_snp() || hv_isolation_type_tdx() ||
+ hv_isolation_type_cca())) {
+ ret = set_memory_decrypted((unsigned long)mem,
+ alloc_size >> PAGE_SHIFT);
if (ret) {
/* It may be unsafe to free 'mem' */
return ret;
}
- memset(mem, 0x00, pgcount * HV_HYP_PAGE_SIZE);
+ memset(mem, 0x00, alloc_size);
}
/*
@@ -666,6 +669,12 @@ bool __weak hv_isolation_type_tdx(void)
}
EXPORT_SYMBOL_GPL(hv_isolation_type_tdx);
+bool __weak hv_isolation_type_cca(void)
+{
+ return false;
+}
+EXPORT_SYMBOL_GPL(hv_isolation_type_cca);
+
void __weak hv_setup_vmbus_handler(void (*handler)(void))
{
}
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index bf601d6..1fa79ab 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -79,6 +79,7 @@ u64 hv_do_fast_hypercall16(u16 control, u64 input1, u64 input2);
bool hv_isolation_type_snp(void);
bool hv_isolation_type_tdx(void);
+bool hv_isolation_type_cca(void);
/*
* On architectures where Hyper-V doesn't support AEOI (e.g., ARM64),
--
2.45.4
^ permalink raw reply [flat|nested] 18+ messages in thread* RE: [PATCH v6 4/6] Drivers: hv: Mark shared memory as decrypted for CCA Realms
2026-10-31 0:14 ` [PATCH v6 4/6] Drivers: hv: Mark shared memory as decrypted " Kameron Carr
@ 2026-11-11 18:01 ` Michael Kelley
2026-11-11 22:36 ` Kameron Carr
0 siblings, 1 reply; 18+ messages in thread
From: Michael Kelley @ 2026-11-11 18:01 UTC (permalink / raw)
To: Kameron Carr, decui, haiyangz, wei.liu, Mukesh R
Cc: arnd, catalin.marinas, linux-arch, linux-arm-kernel,
linux-hyperv, linux-kernel, lpieralisi, mark.rutland,
sudeep.holla, thuth, will
From: Kameron Carr <kameroncarr@linux.microsoft.com> Sent: Friday, October 30, 2026 5:14 PM
>
> In hv_common_cpu_init(), the per-CPU hypercall input/output pages need
> to be marked as decrypted (shared) for confidential VM isolation types.
> This is already done for SNP and TDX isolation; extend the same handling
> to Arm CCA Realm guests so that the host hypervisor can access the
> shared hypercall buffers.
>
> is_realm_world() is declared in include/linux/arm-rsi-cmds.h which only
> builds on arm64 (it includes <asm/memory.h>), so using it directly in
> the arch-neutral drivers/hv/hv_common.c would break the x86 build.
> Introduce a Hyper-V-specific helper following the established
> hv_isolation_type_snp() / hv_isolation_type_tdx() pattern.
>
> On architectures other than arm64 the weak default keeps the existing
> behaviour.
>
> Reviewed-by: Michael Kelley <mhklinux@outlook.com>
> Signed-off-by: Kameron Carr <kameroncarr@linux.microsoft.com>
> ---
> arch/arm64/hyperv/mshyperv.c | 5 +++++
> drivers/hv/hv_common.c | 17 +++++++++++++----
> include/asm-generic/mshyperv.h | 1 +
> 3 files changed, 19 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
> index 46ab2da..da6c3aa0 100644
> --- a/arch/arm64/hyperv/mshyperv.c
> +++ b/arch/arm64/hyperv/mshyperv.c
> @@ -182,3 +182,8 @@ bool hv_is_hyperv_initialized(void)
> return hyperv_initialized;
> }
> EXPORT_SYMBOL_GPL(hv_is_hyperv_initialized);
> +
> +bool hv_isolation_type_cca(void)
> +{
> + return is_realm_world();
> +}
> diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
> index 31256cb..a60c92c 100644
> --- a/drivers/hv/hv_common.c
> +++ b/drivers/hv/hv_common.c
> @@ -476,6 +476,7 @@ int hv_common_cpu_init(unsigned int cpu)
> u64 msr_vp_index;
> gfp_t flags;
> const int pgcount = hv_output_page_exists() ? 2 : 1;
> + const size_t alloc_size = ALIGN((size_t)pgcount * HV_HYP_PAGE_SIZE, PAGE_SIZE);
> void *mem;
> int ret = 0;
>
> @@ -489,7 +490,7 @@ int hv_common_cpu_init(unsigned int cpu)
> * online and then taken offline
> */
> if (!*inputarg) {
> - mem = kmalloc_array(pgcount, HV_HYP_PAGE_SIZE, flags);
> + mem = kmalloc(alloc_size, flags);
> if (!mem)
> return -ENOMEM;
>
> @@ -499,14 +500,16 @@ int hv_common_cpu_init(unsigned int cpu)
> }
>
> if (!ms_hyperv.paravisor_present &&
> - (hv_isolation_type_snp() || hv_isolation_type_tdx())) {
> - ret = set_memory_decrypted((unsigned long)mem, pgcount);
> + (hv_isolation_type_snp() || hv_isolation_type_tdx() ||
> + hv_isolation_type_cca())) {
Could this big "if" statement use "hv_is_isolation_supported()" instead
of explicitly testing for each CoCo VM type? I ask partly because
Mukesh Rathor has just submitted a patch [1] that introduces a new
function that does something almost exactly the same as
hv_is_isolation_supported() and uses it here.
You don't provide the non-stub hv_is_isolation_supported() until
Patch 6 of this series, but the weak stub should allow everything to
build if a bisection splits this patch series.
Michael
[1] https://lore.kernel.org/linux-hyperv/20261111022036.351231-2-mrathor@linux.microsoft.com/
> + ret = set_memory_decrypted((unsigned long)mem,
> + alloc_size >> PAGE_SHIFT);
> if (ret) {
> /* It may be unsafe to free 'mem' */
> return ret;
> }
>
> - memset(mem, 0x00, pgcount * HV_HYP_PAGE_SIZE);
> + memset(mem, 0x00, alloc_size);
> }
>
> /*
> @@ -666,6 +669,12 @@ bool __weak hv_isolation_type_tdx(void)
> }
> EXPORT_SYMBOL_GPL(hv_isolation_type_tdx);
>
> +bool __weak hv_isolation_type_cca(void)
> +{
> + return false;
> +}
> +EXPORT_SYMBOL_GPL(hv_isolation_type_cca);
> +
> void __weak hv_setup_vmbus_handler(void (*handler)(void))
> {
> }
> diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
> index bf601d6..1fa79ab 100644
> --- a/include/asm-generic/mshyperv.h
> +++ b/include/asm-generic/mshyperv.h
> @@ -79,6 +79,7 @@ u64 hv_do_fast_hypercall16(u16 control, u64 input1, u64
> input2);
>
> bool hv_isolation_type_snp(void);
> bool hv_isolation_type_tdx(void);
> +bool hv_isolation_type_cca(void);
>
> /*
> * On architectures where Hyper-V doesn't support AEOI (e.g., ARM64),
> --
> 2.45.4
>
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v6 4/6] Drivers: hv: Mark shared memory as decrypted for CCA Realms
2026-11-11 18:01 ` Michael Kelley
@ 2026-11-11 22:36 ` Kameron Carr
0 siblings, 0 replies; 18+ messages in thread
From: Kameron Carr @ 2026-11-11 22:36 UTC (permalink / raw)
To: Michael Kelley, decui, haiyangz, wei.liu, Mukesh R
Cc: arnd, catalin.marinas, linux-arch, linux-arm-kernel,
linux-hyperv, linux-kernel, lpieralisi, mark.rutland,
sudeep.holla, thuth, will
On 11/11/2026 10:01 AM, Michael Kelley wrote:
> From: Kameron Carr <kameroncarr@linux.microsoft.com> Sent: Friday, October 30, 2026 5:14 PM
>>
>> In hv_common_cpu_init(), the per-CPU hypercall input/output pages need
>> to be marked as decrypted (shared) for confidential VM isolation types.
>> This is already done for SNP and TDX isolation; extend the same handling
>> to Arm CCA Realm guests so that the host hypervisor can access the
>> shared hypercall buffers.
>>
>> is_realm_world() is declared in include/linux/arm-rsi-cmds.h which only
>> builds on arm64 (it includes <asm/memory.h>), so using it directly in
>> the arch-neutral drivers/hv/hv_common.c would break the x86 build.
>> Introduce a Hyper-V-specific helper following the established
>> hv_isolation_type_snp() / hv_isolation_type_tdx() pattern.
>>
>> On architectures other than arm64 the weak default keeps the existing
>> behaviour.
>>
>> Reviewed-by: Michael Kelley <mhklinux@outlook.com>
>> Signed-off-by: Kameron Carr <kameroncarr@linux.microsoft.com>
>> ---
>> arch/arm64/hyperv/mshyperv.c | 5 +++++
>> drivers/hv/hv_common.c | 17 +++++++++++++----
>> include/asm-generic/mshyperv.h | 1 +
>> 3 files changed, 19 insertions(+), 4 deletions(-)
>>
>> diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
>> index 46ab2da..da6c3aa0 100644
>> --- a/arch/arm64/hyperv/mshyperv.c
>> +++ b/arch/arm64/hyperv/mshyperv.c
>> @@ -182,3 +182,8 @@ bool hv_is_hyperv_initialized(void)
>> return hyperv_initialized;
>> }
>> EXPORT_SYMBOL_GPL(hv_is_hyperv_initialized);
>> +
>> +bool hv_isolation_type_cca(void)
>> +{
>> + return is_realm_world();
>> +}
>> diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
>> index 31256cb..a60c92c 100644
>> --- a/drivers/hv/hv_common.c
>> +++ b/drivers/hv/hv_common.c
>> @@ -476,6 +476,7 @@ int hv_common_cpu_init(unsigned int cpu)
>> u64 msr_vp_index;
>> gfp_t flags;
>> const int pgcount = hv_output_page_exists() ? 2 : 1;
>> + const size_t alloc_size = ALIGN((size_t)pgcount * HV_HYP_PAGE_SIZE, PAGE_SIZE);
>> void *mem;
>> int ret = 0;
>>
>> @@ -489,7 +490,7 @@ int hv_common_cpu_init(unsigned int cpu)
>> * online and then taken offline
>> */
>> if (!*inputarg) {
>> - mem = kmalloc_array(pgcount, HV_HYP_PAGE_SIZE, flags);
>> + mem = kmalloc(alloc_size, flags);
>> if (!mem)
>> return -ENOMEM;
>>
>> @@ -499,14 +500,16 @@ int hv_common_cpu_init(unsigned int cpu)
>> }
>>
>> if (!ms_hyperv.paravisor_present &&
>> - (hv_isolation_type_snp() || hv_isolation_type_tdx())) {
>> - ret = set_memory_decrypted((unsigned long)mem, pgcount);
>> + (hv_isolation_type_snp() || hv_isolation_type_tdx() ||
>> + hv_isolation_type_cca())) {
>
> Could this big "if" statement use "hv_is_isolation_supported()" instead
> of explicitly testing for each CoCo VM type? I ask partly because
> Mukesh Rathor has just submitted a patch [1] that introduces a new
> function that does something almost exactly the same as
> hv_is_isolation_supported() and uses it here.
>
> You don't provide the non-stub hv_is_isolation_supported() until
> Patch 6 of this series, but the weak stub should allow everything to
> build if a bisection splits this patch series.
Including your response to Mukesh for context:
> Any reason not to use hv_is_isolation_supported()? Your
> new function seems conceptually equivalent, though at a
> detailed level it handles VBS isolation differently from
> hv_is_isolation_supported(). But I don't think including
> VBS isolation here is a problem since set_memory_decrypted()
> is a no-op with VBS isolation.
I'm not fully convinced that calling set_memory_decrypted() is always a
no-op for VBS.
I see that on VBS VMs, ms_hyperv_init_platform() calls hv_vtom_init().
If set_memory_decrypted() calls hv_mark_gpa_visibility(), you will try
to use the inputarg before it has been initialized.
Please let me know if my understanding is incorrect.
--
Regards,
Kameron
> Michael
>
> [1] https://lore.kernel.org/linux-hyperv/20261111022036.351231-2-mrathor@linux.microsoft.com/
>
>> + ret = set_memory_decrypted((unsigned long)mem,
>> + alloc_size >> PAGE_SHIFT);
>> if (ret) {
>> /* It may be unsafe to free 'mem' */
>> return ret;
>> }
>>
>> - memset(mem, 0x00, pgcount * HV_HYP_PAGE_SIZE);
>> + memset(mem, 0x00, alloc_size);
>> }
>>
>> /*
>> @@ -666,6 +669,12 @@ bool __weak hv_isolation_type_tdx(void)
>> }
>> EXPORT_SYMBOL_GPL(hv_isolation_type_tdx);
>>
>> +bool __weak hv_isolation_type_cca(void)
>> +{
>> + return false;
>> +}
>> +EXPORT_SYMBOL_GPL(hv_isolation_type_cca);
>> +
>> void __weak hv_setup_vmbus_handler(void (*handler)(void))
>> {
>> }
>> diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
>> index bf601d6..1fa79ab 100644
>> --- a/include/asm-generic/mshyperv.h
>> +++ b/include/asm-generic/mshyperv.h
>> @@ -79,6 +79,7 @@ u64 hv_do_fast_hypercall16(u16 control, u64 input1, u64
>> input2);
>>
>> bool hv_isolation_type_snp(void);
>> bool hv_isolation_type_tdx(void);
>> +bool hv_isolation_type_cca(void);
>>
>> /*
>> * On architectures where Hyper-V doesn't support AEOI (e.g., ARM64),
>> --
>> 2.45.4
>>
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v6 5/6] arm64: hyperv: Route hypercalls through RSI host call in CCA Realms
2026-10-31 0:14 [PATCH v6 0/6] arm64: hyperv: Add Realm support for Hyper-V Kameron Carr
` (3 preceding siblings ...)
2026-10-31 0:14 ` [PATCH v6 4/6] Drivers: hv: Mark shared memory as decrypted " Kameron Carr
@ 2026-10-31 0:14 ` Kameron Carr
2026-10-31 0:14 ` [PATCH v6 6/6] arm64: hyperv: Implement hv_is_isolation_supported() for " Kameron Carr
5 siblings, 0 replies; 18+ messages in thread
From: Kameron Carr @ 2026-10-31 0:14 UTC (permalink / raw)
To: decui, haiyangz, mhklinux, wei.liu
Cc: arnd, catalin.marinas, linux-arch, linux-arm-kernel,
linux-hyperv, linux-kernel, lpieralisi, mark.rutland,
sudeep.holla, thuth, will
Modify the five hypercall wrapper functions to check is_realm_world()
and use the per-CPU rsi_host_call structure when inside a Realm.
Reviewed-by: Michael Kelley <mhklinux@outlook.com>
Signed-off-by: Kameron Carr <kameroncarr@linux.microsoft.com>
---
arch/arm64/hyperv/hv_core.c | 155 ++++++++++++++++++++++++++++--------
1 file changed, 121 insertions(+), 34 deletions(-)
diff --git a/arch/arm64/hyperv/hv_core.c b/arch/arm64/hyperv/hv_core.c
index e33a9e3..2f6fc14 100644
--- a/arch/arm64/hyperv/hv_core.c
+++ b/arch/arm64/hyperv/hv_core.c
@@ -12,11 +12,43 @@
#include <linux/export.h>
#include <linux/mm.h>
#include <linux/arm-smccc.h>
+#include <linux/arm-rsi-cmds.h>
#include <linux/module.h>
+#include <linux/smp.h>
#include <asm-generic/bug.h>
#include <hyperv/hvhdk.h>
#include <asm/mshyperv.h>
+/*
+ * hv_do_rsi_hypercall - Helper function to invoke a hypercall from a
+ * Realm world using the RSI interface.
+ */
+static u64 hv_do_rsi_hypercall(u64 control, u64 input1, u64 input2)
+{
+ struct rsi_host_call *hostcall;
+ unsigned long flags;
+ u64 ret;
+
+ if (!hv_hostcall_array)
+ return HV_STATUS_INVALID_HYPERCALL_INPUT;
+
+ local_irq_save(flags);
+ hostcall = &hv_hostcall_array[smp_processor_id()];
+ memset(hostcall, 0, sizeof(*hostcall));
+ hostcall->gprs[0] = HV_FUNC_ID;
+ hostcall->gprs[1] = control;
+ hostcall->gprs[2] = input1;
+ hostcall->gprs[3] = input2;
+
+ if (rsi_host_call(virt_to_phys(hostcall)) == RSI_SUCCESS)
+ ret = hostcall->gprs[0];
+ else
+ ret = HV_STATUS_INVALID_HYPERCALL_INPUT;
+
+ local_irq_restore(flags);
+ return ret;
+}
+
/*
* hv_do_hypercall- Invoke the specified hypercall
*/
@@ -29,8 +61,11 @@ u64 hv_do_hypercall(u64 control, void *input, void *output)
input_address = input ? virt_to_phys(input) : 0;
output_address = output ? virt_to_phys(output) : 0;
- arm_smccc_1_1_hvc(HV_FUNC_ID, control,
- input_address, output_address, &res);
+ if (is_realm_world())
+ return hv_do_rsi_hypercall(control, input_address, output_address);
+
+ arm_smccc_1_1_hvc(HV_FUNC_ID, control, input_address,
+ output_address, &res);
return res.a0;
}
EXPORT_SYMBOL_GPL(hv_do_hypercall);
@@ -48,6 +83,9 @@ u64 hv_do_fast_hypercall8(u16 code, u64 input)
control = (u64)code | HV_HYPERCALL_FAST_BIT;
+ if (is_realm_world())
+ return hv_do_rsi_hypercall(control, input, 0);
+
arm_smccc_1_1_hvc(HV_FUNC_ID, control, input, &res);
return res.a0;
}
@@ -65,6 +103,9 @@ u64 hv_do_fast_hypercall16(u16 code, u64 input1, u64 input2)
control = (u64)code | HV_HYPERCALL_FAST_BIT;
+ if (is_realm_world())
+ return hv_do_rsi_hypercall(control, input1, input2);
+
arm_smccc_1_1_hvc(HV_FUNC_ID, control, input1, input2, &res);
return res.a0;
}
@@ -76,24 +117,44 @@ EXPORT_SYMBOL_GPL(hv_do_fast_hypercall16);
void hv_set_vpreg(u32 msr, u64 value)
{
struct arm_smccc_res res;
+ struct rsi_host_call *hostcall;
+ unsigned long flags;
+ u64 status;
- arm_smccc_1_1_hvc(HV_FUNC_ID,
- HVCALL_SET_VP_REGISTERS | HV_HYPERCALL_FAST_BIT |
- HV_HYPERCALL_REP_COMP_1,
- HV_PARTITION_ID_SELF,
- HV_VP_INDEX_SELF,
- msr,
- 0,
- value,
- 0,
- &res);
+ if (is_realm_world()) {
+ local_irq_save(flags);
+ hostcall = &hv_hostcall_array[smp_processor_id()];
+ memset(hostcall, 0, sizeof(*hostcall));
+ hostcall->gprs[0] = HV_FUNC_ID;
+ hostcall->gprs[1] = HVCALL_SET_VP_REGISTERS |
+ HV_HYPERCALL_FAST_BIT |
+ HV_HYPERCALL_REP_COMP_1;
+ hostcall->gprs[2] = HV_PARTITION_ID_SELF;
+ hostcall->gprs[3] = HV_VP_INDEX_SELF;
+ hostcall->gprs[4] = msr;
+ hostcall->gprs[6] = value;
+
+ if (rsi_host_call(virt_to_phys(hostcall)) == RSI_SUCCESS)
+ status = hostcall->gprs[0];
+ else
+ status = HV_STATUS_INVALID_HYPERCALL_INPUT;
+ local_irq_restore(flags);
+ } else {
+ arm_smccc_1_1_hvc(HV_FUNC_ID,
+ HVCALL_SET_VP_REGISTERS |
+ HV_HYPERCALL_FAST_BIT |
+ HV_HYPERCALL_REP_COMP_1,
+ HV_PARTITION_ID_SELF, HV_VP_INDEX_SELF, msr,
+ 0, value, 0, &res);
+ status = res.a0;
+ }
/*
- * Something is fundamentally broken in the hypervisor if
- * setting a VP register fails. There's really no way to
- * continue as a guest VM, so panic.
+ * Something is fundamentally broken in the hypervisor (or, in a
+ * Realm, the RMM denied the host call) if setting a VP register
+ * fails. There's really no way to continue as a guest VM, so panic.
*/
- BUG_ON(!hv_result_success(res.a0));
+ BUG_ON(!hv_result_success(status));
}
EXPORT_SYMBOL_GPL(hv_set_vpreg);
@@ -108,29 +169,55 @@ void hv_get_vpreg_128(u32 msr, struct hv_get_vp_registers_output *result)
{
struct arm_smccc_1_2_regs args;
struct arm_smccc_1_2_regs res;
+ struct rsi_host_call *hostcall;
+ unsigned long flags;
+ u64 status;
- args.a0 = HV_FUNC_ID;
- args.a1 = HVCALL_GET_VP_REGISTERS | HV_HYPERCALL_FAST_BIT |
- HV_HYPERCALL_REP_COMP_1;
- args.a2 = HV_PARTITION_ID_SELF;
- args.a3 = HV_VP_INDEX_SELF;
- args.a4 = msr;
+ if (is_realm_world()) {
+ local_irq_save(flags);
+ hostcall = &hv_hostcall_array[smp_processor_id()];
+ memset(hostcall, 0, sizeof(*hostcall));
- /*
- * Use the SMCCC 1.2 interface because the results are in registers
- * beyond X0-X3.
- */
- arm_smccc_1_2_hvc(&args, &res);
+ hostcall->gprs[0] = HV_FUNC_ID;
+ hostcall->gprs[1] = HVCALL_GET_VP_REGISTERS |
+ HV_HYPERCALL_FAST_BIT |
+ HV_HYPERCALL_REP_COMP_1;
+ hostcall->gprs[2] = HV_PARTITION_ID_SELF;
+ hostcall->gprs[3] = HV_VP_INDEX_SELF;
+ hostcall->gprs[4] = msr;
+
+ if (rsi_host_call(virt_to_phys(hostcall)) == RSI_SUCCESS) {
+ status = hostcall->gprs[0];
+ result->as64.low = hostcall->gprs[6];
+ result->as64.high = hostcall->gprs[7];
+ } else {
+ status = HV_STATUS_INVALID_HYPERCALL_INPUT;
+ }
+ local_irq_restore(flags);
+ } else {
+ args.a0 = HV_FUNC_ID;
+ args.a1 = HVCALL_GET_VP_REGISTERS | HV_HYPERCALL_FAST_BIT |
+ HV_HYPERCALL_REP_COMP_1;
+ args.a2 = HV_PARTITION_ID_SELF;
+ args.a3 = HV_VP_INDEX_SELF;
+ args.a4 = msr;
+
+ /*
+ * Use the SMCCC 1.2 interface because the results are in
+ * registers beyond X0-X3.
+ */
+ arm_smccc_1_2_hvc(&args, &res);
+ status = res.a0;
+ result->as64.low = res.a6;
+ result->as64.high = res.a7;
+ }
/*
- * Something is fundamentally broken in the hypervisor if
- * getting a VP register fails. There's really no way to
- * continue as a guest VM, so panic.
+ * Something is fundamentally broken in the hypervisor (or, in a
+ * Realm, the RMM denied the host call) if getting a VP register
+ * fails. There's really no way to continue as a guest VM, so panic.
*/
- BUG_ON(!hv_result_success(res.a0));
-
- result->as64.low = res.a6;
- result->as64.high = res.a7;
+ BUG_ON(!hv_result_success(status));
}
EXPORT_SYMBOL_GPL(hv_get_vpreg_128);
--
2.45.4
^ permalink raw reply [flat|nested] 18+ messages in thread* [PATCH v6 6/6] arm64: hyperv: Implement hv_is_isolation_supported() for CCA Realms
2026-10-31 0:14 [PATCH v6 0/6] arm64: hyperv: Add Realm support for Hyper-V Kameron Carr
` (4 preceding siblings ...)
2026-10-31 0:14 ` [PATCH v6 5/6] arm64: hyperv: Route hypercalls through RSI host call in " Kameron Carr
@ 2026-10-31 0:14 ` Kameron Carr
2026-11-11 18:01 ` Michael Kelley
5 siblings, 1 reply; 18+ messages in thread
From: Kameron Carr @ 2026-10-31 0:14 UTC (permalink / raw)
To: decui, haiyangz, mhklinux, wei.liu
Cc: arnd, catalin.marinas, linux-arch, linux-arm-kernel,
linux-hyperv, linux-kernel, lpieralisi, mark.rutland,
sudeep.holla, thuth, will
Provide an arm64 implementation of hv_is_isolation_supported() that
overrides the __weak default in drivers/hv/hv_common.c.
The implementation deliberately does not depend on
hv_is_hyperv_initialized() because hv_common_init() consults
hv_is_isolation_supported() before hyperv_initialized is set.
Reviewed-by: Michael Kelley <mhklinux@outlook.com>
Signed-off-by: Kameron Carr <kameroncarr@linux.microsoft.com>
---
arch/arm64/hyperv/mshyperv.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
index da6c3aa0..8a2c446 100644
--- a/arch/arm64/hyperv/mshyperv.c
+++ b/arch/arm64/hyperv/mshyperv.c
@@ -187,3 +187,8 @@ bool hv_isolation_type_cca(void)
{
return is_realm_world();
}
+
+bool hv_is_isolation_supported(void)
+{
+ return is_realm_world();
+}
--
2.45.4
^ permalink raw reply [flat|nested] 18+ messages in thread* RE: [PATCH v6 6/6] arm64: hyperv: Implement hv_is_isolation_supported() for CCA Realms
2026-10-31 0:14 ` [PATCH v6 6/6] arm64: hyperv: Implement hv_is_isolation_supported() for " Kameron Carr
@ 2026-11-11 18:01 ` Michael Kelley
2026-11-11 19:33 ` Kameron Carr
0 siblings, 1 reply; 18+ messages in thread
From: Michael Kelley @ 2026-11-11 18:01 UTC (permalink / raw)
To: Kameron Carr, decui, haiyangz, wei.liu
Cc: arnd, catalin.marinas, linux-arch, linux-arm-kernel,
linux-hyperv, linux-kernel, lpieralisi, mark.rutland,
sudeep.holla, thuth, will
From: Kameron Carr <kameroncarr@linux.microsoft.com> Sent: Friday, October 30, 2026 5:14 PM
>
> Provide an arm64 implementation of hv_is_isolation_supported() that
> overrides the __weak default in drivers/hv/hv_common.c.
>
> The implementation deliberately does not depend on
> hv_is_hyperv_initialized() because hv_common_init() consults
> hv_is_isolation_supported() before hyperv_initialized is set.
Quibble: What's the genesis of this statement about
hv_is_hyperv_initialized()? On the x86 side, hv_is_isolation_supported()
doesn't depend on hv_is_hyperv_initialized(), so I don't think you
are making a distinction vs. what x86 does. The statement seems
like it might be a leftover from an early version of this patch set.
Michael
>
> Reviewed-by: Michael Kelley <mhklinux@outlook.com>
> Signed-off-by: Kameron Carr <kameroncarr@linux.microsoft.com>
> ---
> arch/arm64/hyperv/mshyperv.c | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
> index da6c3aa0..8a2c446 100644
> --- a/arch/arm64/hyperv/mshyperv.c
> +++ b/arch/arm64/hyperv/mshyperv.c
> @@ -187,3 +187,8 @@ bool hv_isolation_type_cca(void)
> {
> return is_realm_world();
> }
> +
> +bool hv_is_isolation_supported(void)
> +{
> + return is_realm_world();
> +}
> --
> 2.45.4
>
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v6 6/6] arm64: hyperv: Implement hv_is_isolation_supported() for CCA Realms
2026-11-11 18:01 ` Michael Kelley
@ 2026-11-11 19:33 ` Kameron Carr
0 siblings, 0 replies; 18+ messages in thread
From: Kameron Carr @ 2026-11-11 19:33 UTC (permalink / raw)
To: Michael Kelley, decui, wei.liu
Cc: arnd, catalin.marinas, linux-arch, linux-arm-kernel,
linux-hyperv, linux-kernel, lpieralisi, mark.rutland,
sudeep.holla, thuth, will, haiyangz
On 11/11/2026 10:01 AM, Michael Kelley wrote:
> From: Kameron Carr <kameroncarr@linux.microsoft.com> Sent: Friday, October 30, 2026 5:14 PM
>>
>> Provide an arm64 implementation of hv_is_isolation_supported() that
>> overrides the __weak default in drivers/hv/hv_common.c.
>>
>> The implementation deliberately does not depend on
>> hv_is_hyperv_initialized() because hv_common_init() consults
>> hv_is_isolation_supported() before hyperv_initialized is set.
>
> Quibble: What's the genesis of this statement about
> hv_is_hyperv_initialized()? On the x86 side, hv_is_isolation_supported()
> doesn't depend on hv_is_hyperv_initialized(), so I don't think you
> are making a distinction vs. what x86 does. The statement seems
> like it might be a leftover from an early version of this patch set.
From what I recall, I wrote this line after going down a long rabbit
hole attempting to have functional parity with x86
hv_is_isolation_supported(). I agree that is doesn't make sense without
context.
I couldn't find equivalent methods for checking if the Realm is running
on Hyper-V. I initially considered using hv_is_hyperv_initialized(), but
that ran into ordering issue described above. I eventually concluded
that just returning is_realm_world() is sufficient, since
hv_is_isolation_supported() is never used to determine whether the VM is
running on Hyper-V.
The comment would be more clear if it simply pointed out that
hv_is_isolation_supported() functionally differs on ARM64 vs. x86
because it does not check whether it is running on Hyper-V.
I believe Wei already applied this series to hyperv-next, but perhaps he
can remove this line from the commit message.
--
Regards,
Kameron
> Michael
>
>>
>> Reviewed-by: Michael Kelley <mhklinux@outlook.com>
>> Signed-off-by: Kameron Carr <kameroncarr@linux.microsoft.com>
>> ---
>> arch/arm64/hyperv/mshyperv.c | 5 +++++
>> 1 file changed, 5 insertions(+)
>>
>> diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
>> index da6c3aa0..8a2c446 100644
>> --- a/arch/arm64/hyperv/mshyperv.c
>> +++ b/arch/arm64/hyperv/mshyperv.c
>> @@ -187,3 +187,8 @@ bool hv_isolation_type_cca(void)
>> {
>> return is_realm_world();
>> }
>> +
>> +bool hv_is_isolation_supported(void)
>> +{
>> + return is_realm_world();
>> +}
>> --
>> 2.45.4
>>
^ permalink raw reply [flat|nested] 18+ messages in thread