mirror of
https://github.com/torvalds/linux.git
synced 2026-05-25 07:33:19 +02:00
KVM: arm64: selftests: Create a VGICv3 for 'default' VMs
Start creating a VGICv3 by default unless explicitly opted-out by the test. While having an interrupt controller is nice, the real benefit here is clearing a hurdle for EL2 VMs which mandate the presence of a VGIC. Signed-off-by: Oliver Upton <oliver.upton@linux.dev> Signed-off-by: Marc Zyngier <maz@kernel.org>
This commit is contained in:
parent
b8daa7ceac
commit
8911c7dbc6
|
|
@ -176,8 +176,6 @@ static void test_init_timer_irq(struct kvm_vm *vm)
|
|||
pr_debug("ptimer_irq: %d; vtimer_irq: %d\n", ptimer_irq, vtimer_irq);
|
||||
}
|
||||
|
||||
static int gic_fd;
|
||||
|
||||
struct kvm_vm *test_vm_create(void)
|
||||
{
|
||||
struct kvm_vm *vm;
|
||||
|
|
@ -206,7 +204,6 @@ struct kvm_vm *test_vm_create(void)
|
|||
vcpu_init_descriptor_tables(vcpus[i]);
|
||||
|
||||
test_init_timer_irq(vm);
|
||||
gic_fd = vgic_v3_setup(vm, nr_vcpus, 64);
|
||||
|
||||
/* Make all the test's cmdline args visible to the guest */
|
||||
sync_global_to_guest(vm, test_args);
|
||||
|
|
@ -216,6 +213,5 @@ struct kvm_vm *test_vm_create(void)
|
|||
|
||||
void test_vm_cleanup(struct kvm_vm *vm)
|
||||
{
|
||||
close(gic_fd);
|
||||
kvm_vm_free(vm);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -935,8 +935,6 @@ static void test_init_timer_irq(struct kvm_vm *vm, struct kvm_vcpu *vcpu)
|
|||
pr_debug("ptimer_irq: %d; vtimer_irq: %d\n", ptimer_irq, vtimer_irq);
|
||||
}
|
||||
|
||||
static int gic_fd;
|
||||
|
||||
static void test_vm_create(struct kvm_vm **vm, struct kvm_vcpu **vcpu,
|
||||
enum arch_timer timer)
|
||||
{
|
||||
|
|
@ -951,7 +949,6 @@ static void test_vm_create(struct kvm_vm **vm, struct kvm_vcpu **vcpu,
|
|||
vcpu_args_set(*vcpu, 1, timer);
|
||||
|
||||
test_init_timer_irq(*vm, *vcpu);
|
||||
gic_fd = vgic_v3_setup(*vm, 1, 64);
|
||||
|
||||
sync_global_to_guest(*vm, test_args);
|
||||
sync_global_to_guest(*vm, CVAL_MAX);
|
||||
|
|
@ -960,7 +957,6 @@ static void test_vm_create(struct kvm_vm **vm, struct kvm_vcpu **vcpu,
|
|||
|
||||
static void test_vm_cleanup(struct kvm_vm *vm)
|
||||
{
|
||||
close(gic_fd);
|
||||
kvm_vm_free(vm);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -163,6 +163,8 @@ int main(int argc, char *argv[])
|
|||
struct kvm_vm *vm;
|
||||
uint64_t pfr0;
|
||||
|
||||
test_disable_default_vgic();
|
||||
|
||||
vm = vm_create_with_one_vcpu(&vcpu, NULL);
|
||||
pfr0 = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64PFR0_EL1));
|
||||
__TEST_REQUIRE(FIELD_GET(ID_AA64PFR0_EL1_GIC, pfr0),
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ static struct kvm_vm *setup_vm(void *guest_code, struct kvm_vcpu **source,
|
|||
*source = aarch64_vcpu_add(vm, 0, &init, guest_code);
|
||||
*target = aarch64_vcpu_add(vm, 1, &init, guest_code);
|
||||
|
||||
kvm_arch_vm_finalize_vcpus(vm);
|
||||
return vm;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -763,6 +763,7 @@ int main(void)
|
|||
vm = vm_create(1);
|
||||
vm_enable_cap(vm, KVM_CAP_ARM_WRITABLE_IMP_ID_REGS, 0);
|
||||
vcpu = vm_vcpu_add(vm, 0, guest_code);
|
||||
kvm_arch_vm_finalize_vcpus(vm);
|
||||
|
||||
/* Check for AARCH64 only system */
|
||||
val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64PFR0_EL1));
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ static struct kvm_vm *setup_vm(struct kvm_vcpu **vcpu)
|
|||
init.features[0] |= (1 << KVM_ARM_VCPU_PSCI_0_2);
|
||||
|
||||
*vcpu = aarch64_vcpu_add(vm, 0, &init, guest_main);
|
||||
kvm_arch_vm_finalize_vcpus(vm);
|
||||
return vm;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -994,6 +994,8 @@ int main(int ac, char **av)
|
|||
int pa_bits;
|
||||
int cnt_impl = 0;
|
||||
|
||||
test_disable_default_vgic();
|
||||
|
||||
pa_bits = vm_guest_mode_params[VM_MODE_DEFAULT].pa_bits;
|
||||
max_phys_size = 1ULL << pa_bits;
|
||||
|
||||
|
|
|
|||
|
|
@ -802,6 +802,7 @@ int main(int argc, char **argv)
|
|||
bool eoi_split = false;
|
||||
|
||||
TEST_REQUIRE(kvm_supports_vgic_v3());
|
||||
test_disable_default_vgic();
|
||||
|
||||
while ((opt = getopt(argc, argv, "hn:e:l:")) != -1) {
|
||||
switch (opt) {
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ static vm_paddr_t gpa_base;
|
|||
|
||||
static struct kvm_vm *vm;
|
||||
static struct kvm_vcpu **vcpus;
|
||||
static int gic_fd, its_fd;
|
||||
static int its_fd;
|
||||
|
||||
static struct test_data {
|
||||
bool request_vcpus_stop;
|
||||
|
|
@ -214,7 +214,6 @@ static void setup_test_data(void)
|
|||
|
||||
static void setup_gic(void)
|
||||
{
|
||||
gic_fd = vgic_v3_setup(vm, test_data.nr_cpus, 64);
|
||||
its_fd = vgic_its_setup(vm);
|
||||
}
|
||||
|
||||
|
|
@ -353,7 +352,6 @@ static void setup_vm(void)
|
|||
static void destroy_vm(void)
|
||||
{
|
||||
close(its_fd);
|
||||
close(gic_fd);
|
||||
kvm_vm_free(vm);
|
||||
free(vcpus);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@
|
|||
struct vpmu_vm {
|
||||
struct kvm_vm *vm;
|
||||
struct kvm_vcpu *vcpu;
|
||||
int gic_fd;
|
||||
};
|
||||
|
||||
static struct vpmu_vm vpmu_vm;
|
||||
|
|
@ -435,7 +434,8 @@ static void create_vpmu_vm(void *guest_code)
|
|||
init.features[0] |= (1 << KVM_ARM_VCPU_PMU_V3);
|
||||
vpmu_vm.vcpu = aarch64_vcpu_add(vpmu_vm.vm, 0, &init, guest_code);
|
||||
vcpu_init_descriptor_tables(vpmu_vm.vcpu);
|
||||
vpmu_vm.gic_fd = vgic_v3_setup(vpmu_vm.vm, 1, 64);
|
||||
|
||||
kvm_arch_vm_finalize_vcpus(vpmu_vm.vm);
|
||||
|
||||
/* Make sure that PMUv3 support is indicated in the ID register */
|
||||
dfr0 = vcpu_get_reg(vpmu_vm.vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64DFR0_EL1));
|
||||
|
|
@ -451,7 +451,6 @@ static void create_vpmu_vm(void *guest_code)
|
|||
|
||||
static void destroy_vpmu_vm(void)
|
||||
{
|
||||
close(vpmu_vm.gic_fd);
|
||||
kvm_vm_free(vpmu_vm.vm);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,38 +20,6 @@
|
|||
#include "guest_modes.h"
|
||||
#include "ucall_common.h"
|
||||
|
||||
#ifdef __aarch64__
|
||||
#include "arm64/vgic.h"
|
||||
|
||||
static int gic_fd;
|
||||
|
||||
static void arch_setup_vm(struct kvm_vm *vm, unsigned int nr_vcpus)
|
||||
{
|
||||
/*
|
||||
* The test can still run even if hardware does not support GICv3, as it
|
||||
* is only an optimization to reduce guest exits.
|
||||
*/
|
||||
gic_fd = vgic_v3_setup(vm, nr_vcpus, 64);
|
||||
}
|
||||
|
||||
static void arch_cleanup_vm(struct kvm_vm *vm)
|
||||
{
|
||||
if (gic_fd > 0)
|
||||
close(gic_fd);
|
||||
}
|
||||
|
||||
#else /* __aarch64__ */
|
||||
|
||||
static void arch_setup_vm(struct kvm_vm *vm, unsigned int nr_vcpus)
|
||||
{
|
||||
}
|
||||
|
||||
static void arch_cleanup_vm(struct kvm_vm *vm)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* How many host loops to run by default (one KVM_GET_DIRTY_LOG for each loop)*/
|
||||
#define TEST_HOST_LOOP_N 2UL
|
||||
|
||||
|
|
@ -166,8 +134,6 @@ static void run_test(enum vm_guest_mode mode, void *arg)
|
|||
vm_enable_cap(vm, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2,
|
||||
dirty_log_manual_caps);
|
||||
|
||||
arch_setup_vm(vm, nr_vcpus);
|
||||
|
||||
/* Start the iterations */
|
||||
iteration = 0;
|
||||
host_quit = false;
|
||||
|
|
@ -285,7 +251,6 @@ static void run_test(enum vm_guest_mode mode, void *arg)
|
|||
}
|
||||
|
||||
memstress_free_bitmaps(bitmaps, p->slots);
|
||||
arch_cleanup_vm(vm);
|
||||
memstress_destroy_vm(vm);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -585,6 +585,7 @@ static struct kvm_vm *create_vm(enum vm_guest_mode mode, struct kvm_vcpu **vcpu,
|
|||
|
||||
log_mode_create_vm_done(vm);
|
||||
*vcpu = vm_vcpu_add(vm, 0, guest_code);
|
||||
kvm_arch_vm_finalize_vcpus(vm);
|
||||
return vm;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@
|
|||
#ifndef SELFTEST_KVM_UTIL_ARCH_H
|
||||
#define SELFTEST_KVM_UTIL_ARCH_H
|
||||
|
||||
struct kvm_vm_arch {};
|
||||
struct kvm_vm_arch {
|
||||
bool has_gic;
|
||||
int gic_fd;
|
||||
};
|
||||
|
||||
#endif // SELFTEST_KVM_UTIL_ARCH_H
|
||||
|
|
|
|||
|
|
@ -301,5 +301,6 @@ void smccc_smc(uint32_t function_id, uint64_t arg0, uint64_t arg1,
|
|||
void wfi(void);
|
||||
|
||||
void test_wants_mte(void);
|
||||
void test_disable_default_vgic(void);
|
||||
|
||||
#endif /* SELFTEST_KVM_PROCESSOR_H */
|
||||
|
|
|
|||
|
|
@ -1257,7 +1257,9 @@ static inline int __vm_disable_nx_huge_pages(struct kvm_vm *vm)
|
|||
*/
|
||||
void kvm_selftest_arch_init(void);
|
||||
|
||||
void kvm_arch_vm_post_create(struct kvm_vm *vm);
|
||||
void kvm_arch_vm_post_create(struct kvm_vm *vm, unsigned int nr_vcpus);
|
||||
void kvm_arch_vm_finalize_vcpus(struct kvm_vm *vm);
|
||||
void kvm_arch_vm_release(struct kvm_vm *vm);
|
||||
|
||||
bool vm_is_gpa_protected(struct kvm_vm *vm, vm_paddr_t paddr);
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include "kvm_util.h"
|
||||
#include "processor.h"
|
||||
#include "ucall_common.h"
|
||||
#include "vgic.h"
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/sizes.h>
|
||||
|
|
@ -655,14 +656,37 @@ void wfi(void)
|
|||
}
|
||||
|
||||
static bool request_mte;
|
||||
static bool request_vgic = true;
|
||||
|
||||
void test_wants_mte(void)
|
||||
{
|
||||
request_mte = true;
|
||||
}
|
||||
|
||||
void kvm_arch_vm_post_create(struct kvm_vm *vm)
|
||||
void test_disable_default_vgic(void)
|
||||
{
|
||||
request_vgic = false;
|
||||
}
|
||||
|
||||
void kvm_arch_vm_post_create(struct kvm_vm *vm, unsigned int nr_vcpus)
|
||||
{
|
||||
if (request_mte && vm_check_cap(vm, KVM_CAP_ARM_MTE))
|
||||
vm_enable_cap(vm, KVM_CAP_ARM_MTE, 0);
|
||||
|
||||
if (request_vgic && kvm_supports_vgic_v3()) {
|
||||
vm->arch.gic_fd = __vgic_v3_setup(vm, nr_vcpus, 64);
|
||||
vm->arch.has_gic = true;
|
||||
}
|
||||
}
|
||||
|
||||
void kvm_arch_vm_finalize_vcpus(struct kvm_vm *vm)
|
||||
{
|
||||
if (vm->arch.has_gic)
|
||||
__vgic_v3_init(vm->arch.gic_fd);
|
||||
}
|
||||
|
||||
void kvm_arch_vm_release(struct kvm_vm *vm)
|
||||
{
|
||||
if (vm->arch.has_gic)
|
||||
close(vm->arch.gic_fd);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -517,7 +517,7 @@ struct kvm_vm *__vm_create(struct vm_shape shape, uint32_t nr_runnable_vcpus,
|
|||
guest_rng = new_guest_random_state(guest_random_seed);
|
||||
sync_global_to_guest(vm, guest_rng);
|
||||
|
||||
kvm_arch_vm_post_create(vm);
|
||||
kvm_arch_vm_post_create(vm, nr_runnable_vcpus);
|
||||
|
||||
return vm;
|
||||
}
|
||||
|
|
@ -555,6 +555,7 @@ struct kvm_vm *__vm_create_with_vcpus(struct vm_shape shape, uint32_t nr_vcpus,
|
|||
for (i = 0; i < nr_vcpus; ++i)
|
||||
vcpus[i] = vm_vcpu_add(vm, i, guest_code);
|
||||
|
||||
kvm_arch_vm_finalize_vcpus(vm);
|
||||
return vm;
|
||||
}
|
||||
|
||||
|
|
@ -805,6 +806,8 @@ void kvm_vm_release(struct kvm_vm *vmp)
|
|||
|
||||
/* Free cached stats metadata and close FD */
|
||||
kvm_stats_release(&vmp->stats);
|
||||
|
||||
kvm_arch_vm_release(vmp);
|
||||
}
|
||||
|
||||
static void __vm_mem_region_delete(struct kvm_vm *vm,
|
||||
|
|
@ -2330,7 +2333,15 @@ void kvm_get_stat(struct kvm_binary_stats *stats, const char *name,
|
|||
TEST_FAIL("Unable to find stat '%s'", name);
|
||||
}
|
||||
|
||||
__weak void kvm_arch_vm_post_create(struct kvm_vm *vm)
|
||||
__weak void kvm_arch_vm_post_create(struct kvm_vm *vm, unsigned int nr_vcpus)
|
||||
{
|
||||
}
|
||||
|
||||
__weak void kvm_arch_vm_finalize_vcpus(struct kvm_vm *vm)
|
||||
{
|
||||
}
|
||||
|
||||
__weak void kvm_arch_vm_release(struct kvm_vm *vm)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -625,7 +625,7 @@ void assert_on_unhandled_exception(struct kvm_vcpu *vcpu)
|
|||
REPORT_GUEST_ASSERT(uc);
|
||||
}
|
||||
|
||||
void kvm_arch_vm_post_create(struct kvm_vm *vm)
|
||||
void kvm_arch_vm_post_create(struct kvm_vm *vm, unsigned int nr_vcpus)
|
||||
{
|
||||
int r;
|
||||
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ static void finish_vm_setup(struct kvm_vm *vm)
|
|||
slot0 = memslot2region(vm, 0);
|
||||
ucall_init(vm, slot0->region.guest_phys_addr + slot0->region.memory_size);
|
||||
|
||||
kvm_arch_vm_post_create(vm);
|
||||
kvm_arch_vm_post_create(vm, 0);
|
||||
}
|
||||
|
||||
static struct kvm_vm *create_vm_two_memslots(void)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user