The number of user memslots can now be limited with KVM_CAP_MEMSLOTS_LIMIT and, when limited, per-VM KVM_CHECK_EXTENSION(KVM_CAP_NR_MEMSLOTS) should return the updated value. Signed-off-by: Vitaly Kuznetsov <vkuznets@xxxxxxxxxx> --- .../testing/selftests/kvm/include/kvm_util.h | 1 + tools/testing/selftests/kvm/lib/kvm_util.c | 30 ++++++++++++- .../selftests/kvm/set_memory_region_test.c | 43 ++++++++++++++++--- 3 files changed, 67 insertions(+), 7 deletions(-) diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h index 5cbb861525ed..eb759a54dfc6 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -86,6 +86,7 @@ enum vm_mem_backing_src_type { }; int kvm_check_cap(long cap); +int vm_check_cap(struct kvm_vm *vm, long cap); int vm_enable_cap(struct kvm_vm *vm, struct kvm_enable_cap *cap); int vcpu_enable_cap(struct kvm_vm *vm, uint32_t vcpu_id, struct kvm_enable_cap *cap); diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c index fa5a90e6c6f0..115947b77808 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -31,7 +31,7 @@ static void *align(void *x, size_t size) } /* - * Capability + * Check a global capability * * Input Args: * cap - Capability @@ -64,6 +64,34 @@ int kvm_check_cap(long cap) return ret; } +/* + * Check a per-VM capability + * + * Input Args: + * vm - Virtual Machine + * cap - Capability + * + * Output Args: None + * + * Return: + * On success, the Value corresponding to the capability (KVM_CAP_*) + * specified by the value of cap. On failure a TEST_ASSERT failure + * is produced. + * + * Looks up and returns the value corresponding to the capability + * (KVM_CAP_*) given by cap. + */ +int vm_check_cap(struct kvm_vm *vm, long cap) +{ + int ret; + + ret = ioctl(vm->fd, KVM_CHECK_EXTENSION, cap); + TEST_ASSERT(ret != -1, "KVM_CHECK_EXTENSION IOCTL failed,\n" + " rc: %i errno: %i", ret, errno); + + return ret; +} + /* VM Enable Capability * * Input Args: diff --git a/tools/testing/selftests/kvm/set_memory_region_test.c b/tools/testing/selftests/kvm/set_memory_region_test.c index f127ed31dba7..66ed011f26f3 100644 --- a/tools/testing/selftests/kvm/set_memory_region_test.c +++ b/tools/testing/selftests/kvm/set_memory_region_test.c @@ -330,14 +330,14 @@ static void test_zero_memory_regions(void) #endif /* __x86_64__ */ /* - * Test it can be added memory slots up to KVM_CAP_NR_MEMSLOTS, then any - * tentative to add further slots should fail. + * Test it can be added memory slots up to KVM_CAP_NR_MEMSLOTS/given limit, + * then any tentative to add further slots should fail. */ -static void test_add_max_memory_regions(void) +static void test_add_max_memory_regions(int limit) { int ret; struct kvm_vm *vm; - uint32_t max_mem_slots; + uint32_t max_mem_slots, vm_mem_slots; uint32_t slot; uint64_t guest_addr = 0x0; uint64_t mem_reg_npages; @@ -346,10 +346,38 @@ static void test_add_max_memory_regions(void) max_mem_slots = kvm_check_cap(KVM_CAP_NR_MEMSLOTS); TEST_ASSERT(max_mem_slots > 0, "KVM_CAP_NR_MEMSLOTS should be greater than 0"); - pr_info("Allowed number of memory slots: %i\n", max_mem_slots); + + if (!limit) + pr_info("Allowed number of memory slots: %i\n", max_mem_slots); vm = vm_create(VM_MODE_DEFAULT, 0, O_RDWR); + if (limit) { + struct kvm_enable_cap cap = { + .cap = KVM_CAP_MEMSLOTS_LIMIT, + .args[0] = limit + }; + + pr_info("Default max number of memory slots: %i\n", max_mem_slots); + + vm_mem_slots = vm_check_cap(vm, KVM_CAP_NR_MEMSLOTS); + TEST_ASSERT(vm_mem_slots == max_mem_slots, + "KVM_CAP_NR_MEMSLOTS for a newly created VM: %d" + " should equal to the global limit: %d", + vm_mem_slots, max_mem_slots); + + pr_info("Limiting the number of memory slots to: %i\n", limit); + + vm_enable_cap(vm, &cap); + vm_mem_slots = vm_check_cap(vm, KVM_CAP_NR_MEMSLOTS); + TEST_ASSERT(vm_mem_slots == limit, + "KVM_CAP_NR_MEMSLOTS was limited to: %d" + " but is currently set to %d instead", + limit, vm_mem_slots); + + max_mem_slots = vm_mem_slots; + } + mem_reg_npages = vm_calc_num_guest_pages(VM_MODE_DEFAULT, MEM_REGION_SIZE); /* Check it can be added memory slots up to the maximum allowed */ @@ -394,7 +422,10 @@ int main(int argc, char *argv[]) test_zero_memory_regions(); #endif - test_add_max_memory_regions(); + test_add_max_memory_regions(0); + + test_add_max_memory_regions(10); + #ifdef __x86_64__ if (argc > 1) -- 2.29.2