mirror of
https://github.com/torvalds/linux.git
synced 2026-06-01 02:53:36 +02:00
KVM: arm64: Register 'selftest_vm' in the VM table
In preparation for extending the pKVM page ownership selftests to cover forceful reclaim of donated pages, rework the creation of the 'selftest_vm' so that it is registered in the VM table while the tests are running. Tested-by: Fuad Tabba <tabba@google.com> Tested-by: Mostafa Saleh <smostafa@google.com> Signed-off-by: Will Deacon <will@kernel.org> Link: https://patch.msgid.link/20260330144841.26181-35-will@kernel.org Signed-off-by: Marc Zyngier <maz@kernel.org>
This commit is contained in:
parent
c290df5278
commit
8972a99160
|
|
@ -76,6 +76,8 @@ static __always_inline void __load_host_stage2(void)
|
|||
|
||||
#ifdef CONFIG_NVHE_EL2_DEBUG
|
||||
void pkvm_ownership_selftest(void *base);
|
||||
struct pkvm_hyp_vcpu *init_selftest_vm(void *virt);
|
||||
void teardown_selftest_vm(void);
|
||||
#else
|
||||
static inline void pkvm_ownership_selftest(void *base) { }
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1648,53 +1648,18 @@ struct pkvm_expected_state {
|
|||
|
||||
static struct pkvm_expected_state selftest_state;
|
||||
static struct hyp_page *selftest_page;
|
||||
|
||||
static struct pkvm_hyp_vm selftest_vm = {
|
||||
.kvm = {
|
||||
.arch = {
|
||||
.mmu = {
|
||||
.arch = &selftest_vm.kvm.arch,
|
||||
.pgt = &selftest_vm.pgt,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct pkvm_hyp_vcpu selftest_vcpu = {
|
||||
.vcpu = {
|
||||
.arch = {
|
||||
.hw_mmu = &selftest_vm.kvm.arch.mmu,
|
||||
},
|
||||
.kvm = &selftest_vm.kvm,
|
||||
},
|
||||
};
|
||||
|
||||
static void init_selftest_vm(void *virt)
|
||||
{
|
||||
struct hyp_page *p = hyp_virt_to_page(virt);
|
||||
int i;
|
||||
|
||||
selftest_vm.kvm.arch.mmu.vtcr = host_mmu.arch.mmu.vtcr;
|
||||
WARN_ON(kvm_guest_prepare_stage2(&selftest_vm, virt));
|
||||
|
||||
for (i = 0; i < pkvm_selftest_pages(); i++) {
|
||||
if (p[i].refcount)
|
||||
continue;
|
||||
p[i].refcount = 1;
|
||||
hyp_put_page(&selftest_vm.pool, hyp_page_to_virt(&p[i]));
|
||||
}
|
||||
}
|
||||
static struct pkvm_hyp_vcpu *selftest_vcpu;
|
||||
|
||||
static u64 selftest_ipa(void)
|
||||
{
|
||||
return BIT(selftest_vm.pgt.ia_bits - 1);
|
||||
return BIT(selftest_vcpu->vcpu.arch.hw_mmu->pgt->ia_bits - 1);
|
||||
}
|
||||
|
||||
static void assert_page_state(void)
|
||||
{
|
||||
void *virt = hyp_page_to_virt(selftest_page);
|
||||
u64 size = PAGE_SIZE << selftest_page->order;
|
||||
struct pkvm_hyp_vcpu *vcpu = &selftest_vcpu;
|
||||
struct pkvm_hyp_vcpu *vcpu = selftest_vcpu;
|
||||
u64 phys = hyp_virt_to_phys(virt);
|
||||
u64 ipa[2] = { selftest_ipa(), selftest_ipa() + PAGE_SIZE };
|
||||
struct pkvm_hyp_vm *vm;
|
||||
|
|
@ -1709,10 +1674,10 @@ static void assert_page_state(void)
|
|||
WARN_ON(__hyp_check_page_state_range(phys, size, selftest_state.hyp));
|
||||
hyp_unlock_component();
|
||||
|
||||
guest_lock_component(&selftest_vm);
|
||||
guest_lock_component(vm);
|
||||
WARN_ON(__guest_check_page_state_range(vm, ipa[0], size, selftest_state.guest[0]));
|
||||
WARN_ON(__guest_check_page_state_range(vm, ipa[1], size, selftest_state.guest[1]));
|
||||
guest_unlock_component(&selftest_vm);
|
||||
guest_unlock_component(vm);
|
||||
}
|
||||
|
||||
#define assert_transition_res(res, fn, ...) \
|
||||
|
|
@ -1725,14 +1690,15 @@ void pkvm_ownership_selftest(void *base)
|
|||
{
|
||||
enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_RWX;
|
||||
void *virt = hyp_alloc_pages(&host_s2_pool, 0);
|
||||
struct pkvm_hyp_vcpu *vcpu = &selftest_vcpu;
|
||||
struct pkvm_hyp_vm *vm = &selftest_vm;
|
||||
struct pkvm_hyp_vcpu *vcpu;
|
||||
u64 phys, size, pfn, gfn;
|
||||
struct pkvm_hyp_vm *vm;
|
||||
|
||||
WARN_ON(!virt);
|
||||
selftest_page = hyp_virt_to_page(virt);
|
||||
selftest_page->refcount = 0;
|
||||
init_selftest_vm(base);
|
||||
selftest_vcpu = vcpu = init_selftest_vm(base);
|
||||
vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu);
|
||||
|
||||
size = PAGE_SIZE << selftest_page->order;
|
||||
phys = hyp_virt_to_phys(virt);
|
||||
|
|
@ -1856,6 +1822,7 @@ void pkvm_ownership_selftest(void *base)
|
|||
selftest_state.hyp = PKVM_PAGE_OWNED;
|
||||
assert_transition_res(0, __pkvm_host_donate_hyp, pfn, 1);
|
||||
|
||||
teardown_selftest_vm();
|
||||
selftest_page->refcount = 1;
|
||||
hyp_put_page(&host_s2_pool, virt);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -733,6 +733,55 @@ void __pkvm_unreserve_vm(pkvm_handle_t handle)
|
|||
hyp_spin_unlock(&vm_table_lock);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NVHE_EL2_DEBUG
|
||||
static struct pkvm_hyp_vm selftest_vm = {
|
||||
.kvm = {
|
||||
.arch = {
|
||||
.mmu = {
|
||||
.arch = &selftest_vm.kvm.arch,
|
||||
.pgt = &selftest_vm.pgt,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct pkvm_hyp_vcpu selftest_vcpu = {
|
||||
.vcpu = {
|
||||
.arch = {
|
||||
.hw_mmu = &selftest_vm.kvm.arch.mmu,
|
||||
},
|
||||
.kvm = &selftest_vm.kvm,
|
||||
},
|
||||
};
|
||||
|
||||
struct pkvm_hyp_vcpu *init_selftest_vm(void *virt)
|
||||
{
|
||||
struct hyp_page *p = hyp_virt_to_page(virt);
|
||||
int i;
|
||||
|
||||
selftest_vm.kvm.arch.mmu.vtcr = host_mmu.arch.mmu.vtcr;
|
||||
WARN_ON(kvm_guest_prepare_stage2(&selftest_vm, virt));
|
||||
|
||||
for (i = 0; i < pkvm_selftest_pages(); i++) {
|
||||
if (p[i].refcount)
|
||||
continue;
|
||||
p[i].refcount = 1;
|
||||
hyp_put_page(&selftest_vm.pool, hyp_page_to_virt(&p[i]));
|
||||
}
|
||||
|
||||
selftest_vm.kvm.arch.pkvm.handle = __pkvm_reserve_vm();
|
||||
insert_vm_table_entry(selftest_vm.kvm.arch.pkvm.handle, &selftest_vm);
|
||||
return &selftest_vcpu;
|
||||
}
|
||||
|
||||
void teardown_selftest_vm(void)
|
||||
{
|
||||
hyp_spin_lock(&vm_table_lock);
|
||||
remove_vm_table_entry(selftest_vm.kvm.arch.pkvm.handle);
|
||||
hyp_spin_unlock(&vm_table_lock);
|
||||
}
|
||||
#endif /* CONFIG_NVHE_EL2_DEBUG */
|
||||
|
||||
/*
|
||||
* Initialize the hypervisor copy of the VM state using host-donated memory.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user