Skip to content

Commit d34b764

Browse files
committed
KVM: arm64: Only insert reserved ranges when SMCCC filter is used
The reserved ranges are only useful for preventing userspace from adding a rule that intersects with functions we must handle in KVM. If userspace never writes to the SMCCC filter than this is all just wasted work/memory. Insert reserved ranges on the first call to KVM_ARM_VM_SMCCC_FILTER. Reviewed-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Oliver Upton <[email protected]>
1 parent bb17fb3 commit d34b764

File tree

1 file changed

+16
-6
lines changed

1 file changed

+16
-6
lines changed

arch/arm64/kvm/hypercalls.c

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,10 @@ static bool kvm_smccc_test_fw_bmap(struct kvm_vcpu *vcpu, u32 func_id)
133133
ARM_SMCCC_SMC_64, \
134134
0, ARM_SMCCC_FUNC_MASK)
135135

136-
static void init_smccc_filter(struct kvm *kvm)
136+
static int kvm_smccc_filter_insert_reserved(struct kvm *kvm)
137137
{
138138
int r;
139139

140-
mt_init(&kvm->arch.smccc_filter);
141-
142140
/*
143141
* Prevent userspace from handling any SMCCC calls in the architecture
144142
* range, avoiding the risk of misrepresenting Spectre mitigation status
@@ -148,14 +146,20 @@ static void init_smccc_filter(struct kvm *kvm)
148146
SMC32_ARCH_RANGE_BEGIN, SMC32_ARCH_RANGE_END,
149147
xa_mk_value(KVM_SMCCC_FILTER_HANDLE),
150148
GFP_KERNEL_ACCOUNT);
151-
WARN_ON_ONCE(r);
149+
if (r)
150+
goto out_destroy;
152151

153152
r = mtree_insert_range(&kvm->arch.smccc_filter,
154153
SMC64_ARCH_RANGE_BEGIN, SMC64_ARCH_RANGE_END,
155154
xa_mk_value(KVM_SMCCC_FILTER_HANDLE),
156155
GFP_KERNEL_ACCOUNT);
157-
WARN_ON_ONCE(r);
156+
if (r)
157+
goto out_destroy;
158158

159+
return 0;
160+
out_destroy:
161+
mtree_destroy(&kvm->arch.smccc_filter);
162+
return r;
159163
}
160164

161165
static bool kvm_smccc_filter_configured(struct kvm *kvm)
@@ -189,6 +193,12 @@ static int kvm_smccc_set_filter(struct kvm *kvm, struct kvm_smccc_filter __user
189193
goto out_unlock;
190194
}
191195

196+
if (!kvm_smccc_filter_configured(kvm)) {
197+
r = kvm_smccc_filter_insert_reserved(kvm);
198+
if (WARN_ON_ONCE(r))
199+
goto out_unlock;
200+
}
201+
192202
r = mtree_insert_range(&kvm->arch.smccc_filter, start, end,
193203
xa_mk_value(filter.action), GFP_KERNEL_ACCOUNT);
194204
if (r)
@@ -392,7 +402,7 @@ void kvm_arm_init_hypercalls(struct kvm *kvm)
392402
smccc_feat->std_hyp_bmap = KVM_ARM_SMCCC_STD_HYP_FEATURES;
393403
smccc_feat->vendor_hyp_bmap = KVM_ARM_SMCCC_VENDOR_HYP_FEATURES;
394404

395-
init_smccc_filter(kvm);
405+
mt_init(&kvm->arch.smccc_filter);
396406
}
397407

398408
void kvm_arm_teardown_hypercalls(struct kvm *kvm)

0 commit comments

Comments
 (0)