* [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; 8+ 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 related [flat|nested] 8+ 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
0 siblings, 0 replies; 8+ messages in thread
From: Dexuan Cui @ 2026-10-31 4:51 UTC (permalink / raw)
To: Kameron Carr, Haiyang Zhang, 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, sudeep.holla@kernel.org,
thuth@redhat.com, will@kernel.org
> 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] 8+ 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-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, 0 replies; 8+ 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 related [flat|nested] 8+ 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-10-31 0:14 ` [PATCH v6 4/6] Drivers: hv: Mark shared memory as decrypted " Kameron Carr
` (2 subsequent siblings)
5 siblings, 0 replies; 8+ 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 related [flat|nested] 8+ 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-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, 0 replies; 8+ 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 related [flat|nested] 8+ 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; 8+ 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 related [flat|nested] 8+ 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
5 siblings, 0 replies; 8+ 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 related [flat|nested] 8+ messages in thread