Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.12 145 lines 4.1 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) 2020, Google LLC. 4 */ 5 6#include "kvm_util.h" 7#include "perf_test_util.h" 8#include "processor.h" 9 10struct perf_test_args perf_test_args; 11 12uint64_t guest_test_phys_mem; 13 14/* 15 * Guest virtual memory offset of the testing memory slot. 16 * Must not conflict with identity mapped test code. 17 */ 18static uint64_t guest_test_virt_mem = DEFAULT_GUEST_TEST_MEM; 19 20/* 21 * Continuously write to the first 8 bytes of each page in the 22 * specified region. 23 */ 24static void guest_code(uint32_t vcpu_id) 25{ 26 struct perf_test_vcpu_args *vcpu_args = &perf_test_args.vcpu_args[vcpu_id]; 27 uint64_t gva; 28 uint64_t pages; 29 int i; 30 31 /* Make sure vCPU args data structure is not corrupt. */ 32 GUEST_ASSERT(vcpu_args->vcpu_id == vcpu_id); 33 34 gva = vcpu_args->gva; 35 pages = vcpu_args->pages; 36 37 while (true) { 38 for (i = 0; i < pages; i++) { 39 uint64_t addr = gva + (i * perf_test_args.guest_page_size); 40 41 if (i % perf_test_args.wr_fract == 0) 42 *(uint64_t *)addr = 0x0123456789ABCDEF; 43 else 44 READ_ONCE(*(uint64_t *)addr); 45 } 46 47 GUEST_SYNC(1); 48 } 49} 50 51struct kvm_vm *perf_test_create_vm(enum vm_guest_mode mode, int vcpus, 52 uint64_t vcpu_memory_bytes, 53 enum vm_mem_backing_src_type backing_src) 54{ 55 struct kvm_vm *vm; 56 uint64_t guest_num_pages; 57 58 pr_info("Testing guest mode: %s\n", vm_guest_mode_string(mode)); 59 60 perf_test_args.host_page_size = getpagesize(); 61 perf_test_args.guest_page_size = vm_guest_mode_params[mode].page_size; 62 63 guest_num_pages = vm_adjust_num_guest_pages(mode, 64 (vcpus * vcpu_memory_bytes) / perf_test_args.guest_page_size); 65 66 TEST_ASSERT(vcpu_memory_bytes % perf_test_args.host_page_size == 0, 67 "Guest memory size is not host page size aligned."); 68 TEST_ASSERT(vcpu_memory_bytes % perf_test_args.guest_page_size == 0, 69 "Guest memory size is not guest page size aligned."); 70 71 vm = vm_create_with_vcpus(mode, vcpus, 72 (vcpus * vcpu_memory_bytes) / perf_test_args.guest_page_size, 73 0, guest_code, NULL); 74 75 perf_test_args.vm = vm; 76 77 /* 78 * If there should be more memory in the guest test region than there 79 * can be pages in the guest, it will definitely cause problems. 80 */ 81 TEST_ASSERT(guest_num_pages < vm_get_max_gfn(vm), 82 "Requested more guest memory than address space allows.\n" 83 " guest pages: %lx max gfn: %x vcpus: %d wss: %lx]\n", 84 guest_num_pages, vm_get_max_gfn(vm), vcpus, 85 vcpu_memory_bytes); 86 87 guest_test_phys_mem = (vm_get_max_gfn(vm) - guest_num_pages) * 88 perf_test_args.guest_page_size; 89 guest_test_phys_mem &= ~(perf_test_args.host_page_size - 1); 90#ifdef __s390x__ 91 /* Align to 1M (segment size) */ 92 guest_test_phys_mem &= ~((1 << 20) - 1); 93#endif 94 pr_info("guest physical test memory offset: 0x%lx\n", guest_test_phys_mem); 95 96 /* Add an extra memory slot for testing */ 97 vm_userspace_mem_region_add(vm, backing_src, guest_test_phys_mem, 98 PERF_TEST_MEM_SLOT_INDEX, 99 guest_num_pages, 0); 100 101 /* Do mapping for the demand paging memory slot */ 102 virt_map(vm, guest_test_virt_mem, guest_test_phys_mem, guest_num_pages, 0); 103 104 ucall_init(vm, NULL); 105 106 return vm; 107} 108 109void perf_test_destroy_vm(struct kvm_vm *vm) 110{ 111 ucall_uninit(vm); 112 kvm_vm_free(vm); 113} 114 115void perf_test_setup_vcpus(struct kvm_vm *vm, int vcpus, 116 uint64_t vcpu_memory_bytes, 117 bool partition_vcpu_memory_access) 118{ 119 vm_paddr_t vcpu_gpa; 120 struct perf_test_vcpu_args *vcpu_args; 121 int vcpu_id; 122 123 for (vcpu_id = 0; vcpu_id < vcpus; vcpu_id++) { 124 vcpu_args = &perf_test_args.vcpu_args[vcpu_id]; 125 126 vcpu_args->vcpu_id = vcpu_id; 127 if (partition_vcpu_memory_access) { 128 vcpu_args->gva = guest_test_virt_mem + 129 (vcpu_id * vcpu_memory_bytes); 130 vcpu_args->pages = vcpu_memory_bytes / 131 perf_test_args.guest_page_size; 132 vcpu_gpa = guest_test_phys_mem + 133 (vcpu_id * vcpu_memory_bytes); 134 } else { 135 vcpu_args->gva = guest_test_virt_mem; 136 vcpu_args->pages = (vcpus * vcpu_memory_bytes) / 137 perf_test_args.guest_page_size; 138 vcpu_gpa = guest_test_phys_mem; 139 } 140 141 pr_debug("Added VCPU %d with test mem gpa [%lx, %lx)\n", 142 vcpu_id, vcpu_gpa, vcpu_gpa + 143 (vcpu_args->pages * perf_test_args.guest_page_size)); 144 } 145}