Skip to content

Commit a8308b3

Browse files
ouptonMarc Zyngier
authored andcommitted
KVM: arm64: Refactor hvc filtering to support different actions
KVM presently allows userspace to filter guest hypercalls with bitmaps expressed via pseudo-firmware registers. These bitmaps have a narrow scope and, of course, can only allow/deny a particular call. A subsequent change to KVM will introduce a generalized UAPI for filtering hypercalls, allowing functions to be forwarded to userspace. Refactor the existing hypercall filtering logic to make room for more than two actions. While at it, generalize the function names around SMCCC as it is the basis for the upcoming UAPI. No functional change intended. Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com> Signed-off-by: Oliver Upton <oliver.upton@linux.dev> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20230404154050.2270077-7-oliver.upton@linux.dev
1 parent c2d2e9b commit a8308b3

2 files changed

Lines changed: 31 additions & 4 deletions

File tree

arch/arm64/include/uapi/asm/kvm.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,15 @@ enum {
469469
/* run->fail_entry.hardware_entry_failure_reason codes. */
470470
#define KVM_EXIT_FAIL_ENTRY_CPU_UNSUPPORTED (1ULL << 0)
471471

472+
enum kvm_smccc_filter_action {
473+
KVM_SMCCC_FILTER_HANDLE = 0,
474+
KVM_SMCCC_FILTER_DENY,
475+
476+
#ifdef __KERNEL__
477+
NR_SMCCC_FILTER_ACTIONS
478+
#endif
479+
};
480+
472481
#endif
473482

474483
#endif /* __ARM_KVM_H__ */

arch/arm64/kvm/hypercalls.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ static void kvm_ptp_get_time(struct kvm_vcpu *vcpu, u64 *val)
6565
val[3] = lower_32_bits(cycles);
6666
}
6767

68-
static bool kvm_hvc_call_default_allowed(u32 func_id)
68+
static bool kvm_smccc_default_allowed(u32 func_id)
6969
{
7070
switch (func_id) {
7171
/*
@@ -93,7 +93,7 @@ static bool kvm_hvc_call_default_allowed(u32 func_id)
9393
}
9494
}
9595

96-
static bool kvm_hvc_call_allowed(struct kvm_vcpu *vcpu, u32 func_id)
96+
static bool kvm_smccc_test_fw_bmap(struct kvm_vcpu *vcpu, u32 func_id)
9797
{
9898
struct kvm_smccc_features *smccc_feat = &vcpu->kvm->arch.smccc_feat;
9999

@@ -117,20 +117,38 @@ static bool kvm_hvc_call_allowed(struct kvm_vcpu *vcpu, u32 func_id)
117117
return test_bit(KVM_REG_ARM_VENDOR_HYP_BIT_PTP,
118118
&smccc_feat->vendor_hyp_bmap);
119119
default:
120-
return kvm_hvc_call_default_allowed(func_id);
120+
return false;
121121
}
122122
}
123123

124+
static u8 kvm_smccc_get_action(struct kvm_vcpu *vcpu, u32 func_id)
125+
{
126+
if (kvm_smccc_test_fw_bmap(vcpu, func_id) ||
127+
kvm_smccc_default_allowed(func_id))
128+
return KVM_SMCCC_FILTER_HANDLE;
129+
130+
return KVM_SMCCC_FILTER_DENY;
131+
}
132+
124133
int kvm_smccc_call_handler(struct kvm_vcpu *vcpu)
125134
{
126135
struct kvm_smccc_features *smccc_feat = &vcpu->kvm->arch.smccc_feat;
127136
u32 func_id = smccc_get_function(vcpu);
128137
u64 val[4] = {SMCCC_RET_NOT_SUPPORTED};
129138
u32 feature;
139+
u8 action;
130140
gpa_t gpa;
131141

132-
if (!kvm_hvc_call_allowed(vcpu, func_id))
142+
action = kvm_smccc_get_action(vcpu, func_id);
143+
switch (action) {
144+
case KVM_SMCCC_FILTER_HANDLE:
145+
break;
146+
case KVM_SMCCC_FILTER_DENY:
147+
goto out;
148+
default:
149+
WARN_RATELIMIT(1, "Unhandled SMCCC filter action: %d\n", action);
133150
goto out;
151+
}
134152

135153
switch (func_id) {
136154
case ARM_SMCCC_VERSION_FUNC_ID:

0 commit comments

Comments
 (0)