Skip to content

Commit 373beef

Browse files
jpbruckerMarc Zyngier
authored and
Marc Zyngier
committed
KVM: arm64: nvhe: Ignore SVE hint in SMCCC function ID
When SVE is enabled, the host may set bit 16 in SMCCC function IDs, a hint that indicates an unused SVE state. At the moment NVHE doesn't account for this bit when inspecting the function ID, and rejects most calls. Clear the hint bit before comparing function IDs. About version compatibility: the host's PSCI driver initially probes the firmware for a SMCCC version number. If the firmware implements a protocol recent enough (1.3), subsequent SMCCC calls have the hint bit set. Since the hint bit was reserved in earlier versions of the protocol, clearing it is fine regardless of the version in use. When a new hint is added to the protocol in the future, it will be added to ARM_SMCCC_CALL_HINTS and NVHE will handle it straight away. This patch only clears known hints and leaves reserved bits as is, because future SMCCC versions could use reserved bits as modifiers for the function ID, rather than hints. Fixes: cfa7ff9 ("arm64: smccc: Support SMCCC v1.3 SVE register saving hint") Reported-by: Ben Horgan <[email protected]> Signed-off-by: Jean-Philippe Brucker <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 3579dc7 commit 373beef

File tree

7 files changed

+13
-8
lines changed

7 files changed

+13
-8
lines changed

arch/arm64/include/asm/kvm_hyp.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ void deactivate_traps_vhe_put(struct kvm_vcpu *vcpu);
118118

119119
u64 __guest_enter(struct kvm_vcpu *vcpu);
120120

121-
bool kvm_host_psci_handler(struct kvm_cpu_context *host_ctxt);
121+
bool kvm_host_psci_handler(struct kvm_cpu_context *host_ctxt, u32 func_id);
122122

123123
#ifdef __KVM_NVHE_HYPERVISOR__
124124
void __noreturn __hyp_do_panic(struct kvm_cpu_context *host_ctxt, u64 spsr,

arch/arm64/kvm/hyp/include/nvhe/ffa.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@
1212
#define FFA_MAX_FUNC_NUM 0x7F
1313

1414
int hyp_ffa_init(void *pages);
15-
bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt);
15+
bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id);
1616

1717
#endif /* __KVM_HYP_FFA_H */

arch/arm64/kvm/hyp/nvhe/ffa.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -634,9 +634,8 @@ static bool do_ffa_features(struct arm_smccc_res *res,
634634
return true;
635635
}
636636

637-
bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt)
637+
bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
638638
{
639-
DECLARE_REG(u64, func_id, host_ctxt, 0);
640639
struct arm_smccc_res res;
641640

642641
/*

arch/arm64/kvm/hyp/nvhe/hyp-init.S

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ __do_hyp_init:
5757
cmp x0, #HVC_STUB_HCALL_NR
5858
b.lo __kvm_handle_stub_hvc
5959

60+
bic x0, x0, #ARM_SMCCC_CALL_HINTS
6061
mov x3, #KVM_HOST_SMCCC_FUNC(__kvm_hyp_init)
6162
cmp x0, x3
6263
b.eq 1f

arch/arm64/kvm/hyp/nvhe/hyp-main.c

+6-2
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,7 @@ static void handle_host_hcall(struct kvm_cpu_context *host_ctxt)
368368
if (static_branch_unlikely(&kvm_protected_mode_initialized))
369369
hcall_min = __KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize;
370370

371+
id &= ~ARM_SMCCC_CALL_HINTS;
371372
id -= KVM_HOST_SMCCC_ID(0);
372373

373374
if (unlikely(id < hcall_min || id >= ARRAY_SIZE(host_hcall)))
@@ -392,11 +393,14 @@ static void default_host_smc_handler(struct kvm_cpu_context *host_ctxt)
392393

393394
static void handle_host_smc(struct kvm_cpu_context *host_ctxt)
394395
{
396+
DECLARE_REG(u64, func_id, host_ctxt, 0);
395397
bool handled;
396398

397-
handled = kvm_host_psci_handler(host_ctxt);
399+
func_id &= ~ARM_SMCCC_CALL_HINTS;
400+
401+
handled = kvm_host_psci_handler(host_ctxt, func_id);
398402
if (!handled)
399-
handled = kvm_host_ffa_handler(host_ctxt);
403+
handled = kvm_host_ffa_handler(host_ctxt, func_id);
400404
if (!handled)
401405
default_host_smc_handler(host_ctxt);
402406

arch/arm64/kvm/hyp/nvhe/psci-relay.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -273,9 +273,8 @@ static unsigned long psci_1_0_handler(u64 func_id, struct kvm_cpu_context *host_
273273
}
274274
}
275275

276-
bool kvm_host_psci_handler(struct kvm_cpu_context *host_ctxt)
276+
bool kvm_host_psci_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
277277
{
278-
DECLARE_REG(u64, func_id, host_ctxt, 0);
279278
unsigned long ret;
280279

281280
switch (kvm_host_psci_config.version) {

include/linux/arm-smccc.h

+2
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@
6767
#define ARM_SMCCC_VERSION_1_3 0x10003
6868

6969
#define ARM_SMCCC_1_3_SVE_HINT 0x10000
70+
#define ARM_SMCCC_CALL_HINTS ARM_SMCCC_1_3_SVE_HINT
71+
7072

7173
#define ARM_SMCCC_VERSION_FUNC_ID \
7274
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \

0 commit comments

Comments
 (0)