tools/testing/selftests/kvm/lib/kvm_util.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/kvm/lib/kvm_util.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/kvm/lib/kvm_util.c
Extension
.c
Size
63414 bytes
Lines
2307
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

if (vm->va_bits == 57) {
			vm->mmu.pgtable_levels = 5;
		} else {
			TEST_ASSERT(vm->va_bits == 48,
				    "Unexpected guest virtual address width: %d",
				    vm->va_bits);
			vm->mmu.pgtable_levels = 4;
		}
#else
		TEST_FAIL("VM_MODE_PXXVYY_4K not supported on non-x86 platforms");
#endif
		break;
	case VM_MODE_P47V64_4K:
		vm->mmu.pgtable_levels = 5;
		break;
	case VM_MODE_P44V64_4K:
		vm->mmu.pgtable_levels = 5;
		break;
	case VM_MODE_P56V57_4K:
	case VM_MODE_P50V57_4K:
	case VM_MODE_P41V57_4K:
		vm->mmu.pgtable_levels = 5;
		break;
	case VM_MODE_P56V48_4K:
	case VM_MODE_P50V48_4K:
	case VM_MODE_P41V48_4K:
		vm->mmu.pgtable_levels = 4;
		break;
	case VM_MODE_P56V39_4K:
	case VM_MODE_P50V39_4K:
	case VM_MODE_P41V39_4K:
		vm->mmu.pgtable_levels = 3;
		break;
	default:
		TEST_FAIL("Unknown guest mode: 0x%x", vm->mode);
	}

#ifdef __aarch64__
	TEST_ASSERT(!vm->type, "ARM doesn't support test-provided types");
	if (vm->pa_bits != 40)
		vm->type = KVM_VM_TYPE_ARM_IPA_SIZE(vm->pa_bits);
#endif

	vm_open(vm);

	/* Limit to VA-bit canonical virtual addresses. */
	vm->vpages_valid = sparsebit_alloc();
	vm_populate_gva_bitmap(vm);

	/* Limit physical addresses to PA-bits. */
	vm->max_gfn = vm_compute_max_gfn(vm);

	/* Allocate and setup memory for guest. */
	vm->vpages_mapped = sparsebit_alloc();

	return vm;
}

static u64 vm_nr_pages_required(enum vm_guest_mode mode,
				u32 nr_runnable_vcpus,
				u64 extra_mem_pages)
{
	u64 page_size = vm_guest_mode_params[mode].page_size;
	u64 nr_pages;

	TEST_ASSERT(nr_runnable_vcpus,
		    "Use vm_create_barebones() for VMs that _never_ have vCPUs");

	TEST_ASSERT(nr_runnable_vcpus <= kvm_check_cap(KVM_CAP_MAX_VCPUS),
		    "nr_vcpus = %d too large for host, max-vcpus = %d",
		    nr_runnable_vcpus, kvm_check_cap(KVM_CAP_MAX_VCPUS));

	/*
	 * Arbitrarily allocate 512 pages (2mb when page size is 4kb) for the
	 * test code and other per-VM assets that will be loaded into memslot0.
	 */
	nr_pages = 512;

	/* Account for the per-vCPU stacks on behalf of the test. */
	nr_pages += nr_runnable_vcpus * DEFAULT_STACK_PGS;

	/*
	 * Account for the number of pages needed for the page tables.  The
	 * maximum page table size for a memory region will be when the
	 * smallest page size is used. Considering each page contains x page
	 * table descriptors, the total extra size for page tables (for extra
	 * N pages) will be: N/x+N/x^2+N/x^3+... which is definitely smaller
	 * than N/x*2.
	 */
	nr_pages += (nr_pages + extra_mem_pages) / PTES_PER_MIN_PAGE * 2;

Annotation

Implementation Notes