mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-19 08:14:25 +00:00
Use the kernel's canonical $(ARCH) paths instead of the raw target triple for KVM selftests directories. KVM selftests are quite nearly the only place in the entire kernel that using the target triple for directories, tools/testing/selftests/drivers/s390x being the lone holdout. Using the kernel's preferred nomenclature eliminates the minor, but annoying, friction of having to translate to KVM's selftests directories, e.g. for pattern matching, opening files, running selftests, etc. Opportunsitically delete file comments that reference the full path of the file, as they are obviously prone to becoming stale, and serve no known purpose. Reviewed-by: Muhammad Usama Anjum <usama.anjum@collabora.com> Acked-by: Claudio Imbrenda <imbrenda@linux.ibm.com> Acked-by: Andrew Jones <ajones@ventanamicro.com> Link: https://lore.kernel.org/r/20241128005547.4077116-16-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
106 lines
2.7 KiB
C
106 lines
2.7 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Copyright (C) 2020, Google LLC.
|
|
*
|
|
* Test that KVM emulates instructions in response to EPT violations when
|
|
* allow_smaller_maxphyaddr is enabled and guest.MAXPHYADDR < host.MAXPHYADDR.
|
|
*/
|
|
#include "flds_emulation.h"
|
|
|
|
#include "test_util.h"
|
|
#include "kvm_util.h"
|
|
#include "vmx.h"
|
|
|
|
#define MAXPHYADDR 36
|
|
|
|
#define MEM_REGION_GVA 0x0000123456789000
|
|
#define MEM_REGION_GPA 0x0000000700000000
|
|
#define MEM_REGION_SLOT 10
|
|
#define MEM_REGION_SIZE PAGE_SIZE
|
|
|
|
static void guest_code(bool tdp_enabled)
|
|
{
|
|
uint64_t error_code;
|
|
uint64_t vector;
|
|
|
|
vector = kvm_asm_safe_ec(FLDS_MEM_EAX, error_code, "a"(MEM_REGION_GVA));
|
|
|
|
/*
|
|
* When TDP is enabled, flds will trigger an emulation failure, exit to
|
|
* userspace, and then the selftest host "VMM" skips the instruction.
|
|
*
|
|
* When TDP is disabled, no instruction emulation is required so flds
|
|
* should generate #PF(RSVD).
|
|
*/
|
|
if (tdp_enabled) {
|
|
GUEST_ASSERT(!vector);
|
|
} else {
|
|
GUEST_ASSERT_EQ(vector, PF_VECTOR);
|
|
GUEST_ASSERT(error_code & PFERR_RSVD_MASK);
|
|
}
|
|
|
|
GUEST_DONE();
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
struct kvm_vcpu *vcpu;
|
|
struct kvm_vm *vm;
|
|
struct ucall uc;
|
|
uint64_t *pte;
|
|
uint64_t *hva;
|
|
uint64_t gpa;
|
|
int rc;
|
|
|
|
TEST_REQUIRE(kvm_has_cap(KVM_CAP_SMALLER_MAXPHYADDR));
|
|
|
|
vm = vm_create_with_one_vcpu(&vcpu, guest_code);
|
|
vcpu_args_set(vcpu, 1, kvm_is_tdp_enabled());
|
|
|
|
vcpu_set_cpuid_property(vcpu, X86_PROPERTY_MAX_PHY_ADDR, MAXPHYADDR);
|
|
|
|
rc = kvm_check_cap(KVM_CAP_EXIT_ON_EMULATION_FAILURE);
|
|
TEST_ASSERT(rc, "KVM_CAP_EXIT_ON_EMULATION_FAILURE is unavailable");
|
|
vm_enable_cap(vm, KVM_CAP_EXIT_ON_EMULATION_FAILURE, 1);
|
|
|
|
vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS,
|
|
MEM_REGION_GPA, MEM_REGION_SLOT,
|
|
MEM_REGION_SIZE / PAGE_SIZE, 0);
|
|
gpa = vm_phy_pages_alloc(vm, MEM_REGION_SIZE / PAGE_SIZE,
|
|
MEM_REGION_GPA, MEM_REGION_SLOT);
|
|
TEST_ASSERT(gpa == MEM_REGION_GPA, "Failed vm_phy_pages_alloc");
|
|
virt_map(vm, MEM_REGION_GVA, MEM_REGION_GPA, 1);
|
|
hva = addr_gpa2hva(vm, MEM_REGION_GPA);
|
|
memset(hva, 0, PAGE_SIZE);
|
|
|
|
pte = vm_get_page_table_entry(vm, MEM_REGION_GVA);
|
|
*pte |= BIT_ULL(MAXPHYADDR);
|
|
|
|
vcpu_run(vcpu);
|
|
|
|
/*
|
|
* When TDP is enabled, KVM must emulate in response the guest physical
|
|
* address that is illegal from the guest's perspective, but is legal
|
|
* from hardware's perspeective. This should result in an emulation
|
|
* failure exit to userspace since KVM doesn't support emulating flds.
|
|
*/
|
|
if (kvm_is_tdp_enabled()) {
|
|
handle_flds_emulation_failure_exit(vcpu);
|
|
vcpu_run(vcpu);
|
|
}
|
|
|
|
switch (get_ucall(vcpu, &uc)) {
|
|
case UCALL_ABORT:
|
|
REPORT_GUEST_ASSERT(uc);
|
|
break;
|
|
case UCALL_DONE:
|
|
break;
|
|
default:
|
|
TEST_FAIL("Unrecognized ucall: %lu", uc.cmd);
|
|
}
|
|
|
|
kvm_vm_free(vm);
|
|
|
|
return 0;
|
|
}
|