@@ -19,7 +19,11 @@ int vcpu_affinity_parser(const struct option *opt, const char *arg, int unset);
"Specify random seed for Kernel Address Space " \
"Layout Randomization (KASLR)"), \
OPT_BOOLEAN('\0', "no-pvtime", &(cfg)->no_pvtime, "Disable" \
- " stolen time"),
+ " stolen time"), \
+ OPT_BOOLEAN('\0', "in-kernel-smccc", &(cfg)->in_kernel_smccc, \
+ "Disable userspace handling of SMCCC, instead" \
+ " relying on the in-kernel implementation"),
+
#include "arm-common/kvm-config-arch.h"
#endif /* KVM__KVM_CONFIG_ARCH_H */
@@ -38,7 +38,44 @@ out:
return true;
}
+static struct kvm_smccc_filter filter_ranges[] = {
+ {
+ .base = KVM_PSCI_FN_BASE,
+ .nr_functions = 4,
+ .action = KVM_SMCCC_FILTER_DENY,
+ },
+ {
+ .base = PSCI_0_2_FN_BASE,
+ .nr_functions = 0x20,
+ .action = KVM_SMCCC_FILTER_FWD_TO_USER,
+ },
+ {
+ .base = PSCI_0_2_FN64_BASE,
+ .nr_functions = 0x20,
+ .action = KVM_SMCCC_FILTER_FWD_TO_USER,
+ },
+};
+
void kvm__setup_smccc(struct kvm *kvm)
{
+ struct kvm_device_attr attr = {
+ .group = KVM_ARM_VM_SMCCC_CTRL,
+ .attr = KVM_ARM_VM_SMCCC_FILTER,
+ };
+ unsigned int i;
+ if (kvm->cfg.arch.in_kernel_smccc)
+ return;
+
+ if (ioctl(kvm->vm_fd, KVM_HAS_DEVICE_ATTR, &attr)) {
+ pr_debug("KVM SMCCC filter not supported");
+ return;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(filter_ranges); i++) {
+ attr.addr = (u64)&filter_ranges[i];
+
+ if (ioctl(kvm->vm_fd, KVM_SET_DEVICE_ATTR, &attr))
+ die_perror("KVM_SET_DEVICE_ATTR failed");
+ }
}
@@ -14,6 +14,7 @@ struct kvm_config_arch {
enum irqchip_type irqchip;
u64 fw_addr;
bool no_pvtime;
+ bool in_kernel_smccc;
};
int irqchip_parser(const struct option *opt, const char *arg, int unset);
kvmtool now has a PSCI implementation that complies with v1.0 of the specification. Use the SMCCC filter to start sending these calls out to userspace for further handling. While at it, shut the door on the legacy, KVM-specific v0.1 functions. Signed-off-by: Oliver Upton <oliver.upton@linux.dev> --- arm/aarch64/include/kvm/kvm-config-arch.h | 6 +++- arm/aarch64/smccc.c | 37 +++++++++++++++++++++++ arm/include/arm-common/kvm-config-arch.h | 1 + 3 files changed, 43 insertions(+), 1 deletion(-)