diff options
Diffstat (limited to 'tools/testing/selftests/kvm/lib/kvm_util.c')
| -rw-r--r-- | tools/testing/selftests/kvm/lib/kvm_util.c | 67 | 
1 files changed, 53 insertions, 14 deletions
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c index 6e49bb039376..80a338b5403c 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -8,6 +8,7 @@  #include "test_util.h"  #include "kvm_util.h"  #include "kvm_util_internal.h" +#include "processor.h"  #include <assert.h>  #include <sys/mman.h> @@ -84,7 +85,7 @@ int vm_enable_cap(struct kvm_vm *vm, struct kvm_enable_cap *cap)  	return ret;  } -static void vm_open(struct kvm_vm *vm, int perm, unsigned long type) +static void vm_open(struct kvm_vm *vm, int perm)  {  	vm->kvm_fd = open(KVM_DEV_PATH, perm);  	if (vm->kvm_fd < 0) @@ -95,18 +96,19 @@ static void vm_open(struct kvm_vm *vm, int perm, unsigned long type)  		exit(KSFT_SKIP);  	} -	vm->fd = ioctl(vm->kvm_fd, KVM_CREATE_VM, type); +	vm->fd = ioctl(vm->kvm_fd, KVM_CREATE_VM, vm->type);  	TEST_ASSERT(vm->fd >= 0, "KVM_CREATE_VM ioctl failed, "  		"rc: %i errno: %i", vm->fd, errno);  }  const char * const vm_guest_mode_string[] = { -	"PA-bits:52, VA-bits:48, 4K pages", -	"PA-bits:52, VA-bits:48, 64K pages", -	"PA-bits:48, VA-bits:48, 4K pages", -	"PA-bits:48, VA-bits:48, 64K pages", -	"PA-bits:40, VA-bits:48, 4K pages", -	"PA-bits:40, VA-bits:48, 64K pages", +	"PA-bits:52,  VA-bits:48,  4K pages", +	"PA-bits:52,  VA-bits:48, 64K pages", +	"PA-bits:48,  VA-bits:48,  4K pages", +	"PA-bits:48,  VA-bits:48, 64K pages", +	"PA-bits:40,  VA-bits:48,  4K pages", +	"PA-bits:40,  VA-bits:48, 64K pages", +	"PA-bits:ANY, VA-bits:48,  4K pages",  };  _Static_assert(sizeof(vm_guest_mode_string)/sizeof(char *) == NUM_VM_MODES,  	       "Missing new mode strings?"); @@ -130,17 +132,17 @@ _Static_assert(sizeof(vm_guest_mode_string)/sizeof(char *) == NUM_VM_MODES,   * descriptor to control the created VM is created with the permissions   * given by perm (e.g. O_RDWR).   */ -struct kvm_vm *_vm_create(enum vm_guest_mode mode, uint64_t phy_pages, -			  int perm, unsigned long type) +struct kvm_vm *_vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int perm)  {  	struct kvm_vm *vm; +	DEBUG("Testing guest mode: %s\n", vm_guest_mode_string(mode)); +  	vm = calloc(1, sizeof(*vm));  	TEST_ASSERT(vm != NULL, "Insufficient Memory");  	vm->mode = mode; -	vm->type = type; -	vm_open(vm, perm, type); +	vm->type = 0;  	/* Setup mode specific traits. */  	switch (vm->mode) { @@ -186,10 +188,32 @@ struct kvm_vm *_vm_create(enum vm_guest_mode mode, uint64_t phy_pages,  		vm->page_size = 0x10000;  		vm->page_shift = 16;  		break; +	case VM_MODE_PXXV48_4K: +#ifdef __x86_64__ +		kvm_get_cpu_address_width(&vm->pa_bits, &vm->va_bits); +		TEST_ASSERT(vm->va_bits == 48, "Linear address width " +			    "(%d bits) not supported", vm->va_bits); +		vm->pgtable_levels = 4; +		vm->page_size = 0x1000; +		vm->page_shift = 12; +		DEBUG("Guest physical address width detected: %d\n", +		      vm->pa_bits); +#else +		TEST_ASSERT(false, "VM_MODE_PXXV48_4K not supported on " +			    "non-x86 platforms"); +#endif +		break;  	default:  		TEST_ASSERT(false, "Unknown guest mode, mode: 0x%x", mode);  	} +#ifdef __aarch64__ +	if (vm->pa_bits != 40) +		vm->type = KVM_VM_TYPE_ARM_IPA_SIZE(vm->pa_bits); +#endif + +	vm_open(vm, perm); +  	/* Limit to VA-bit canonical virtual addresses. */  	vm->vpages_valid = sparsebit_alloc();  	sparsebit_set_num(vm->vpages_valid, @@ -212,7 +236,7 @@ struct kvm_vm *_vm_create(enum vm_guest_mode mode, uint64_t phy_pages,  struct kvm_vm *vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int perm)  { -	return _vm_create(mode, phy_pages, perm, 0); +	return _vm_create(mode, phy_pages, perm);  }  /* @@ -232,7 +256,7 @@ void kvm_vm_restart(struct kvm_vm *vmp, int perm)  {  	struct userspace_mem_region *region; -	vm_open(vmp, perm, vmp->type); +	vm_open(vmp, perm);  	if (vmp->has_irqchip)  		vm_create_irqchip(vmp); @@ -1628,3 +1652,18 @@ bool vm_is_unrestricted_guest(struct kvm_vm *vm)  	return val == 'Y';  } + +unsigned int vm_get_page_size(struct kvm_vm *vm) +{ +	return vm->page_size; +} + +unsigned int vm_get_page_shift(struct kvm_vm *vm) +{ +	return vm->page_shift; +} + +unsigned int vm_get_max_gfn(struct kvm_vm *vm) +{ +	return vm->max_gfn; +}  |