KVM: selftests: add powerpc support
cover KVM: selftests: add powerpc support
Hi All,
This series primarly adds KVM selftests support for powerpc (64-bit, BookS, radix MMU).
This patch series is originally Nick's work. I have mainly only rebased it on the latest upstream tree. Since the rebase required few changes to all four patches, I have dropped the earlier Acked-by from Michael Ellerman.
Since the last series was posted three years ago [1], I am resetting the version to RFC and posting an early version (few tests still pending) for getting any early review comments. BTW, I ran this on P9 (PowerNV) with radix and haven't found any regressions so far.
Note that I am planning to run this selftests with different configurations as well on PowerPC and will share the test results soon. This rebase was done as part of a larger effort to improve the selftests infrastructure for Linux on PowerPC tree. Thanks to Harsh and Maddy for their help on this.
[1]: https://lore.kernel.org/all/[email protected]/
Nicholas Piggin (4):
KVM: selftests: Move pgd_created check into virt_pgd_alloc
KVM: selftests: Add aligned guest physical page allocator
KVM: PPC: selftests: add support for powerpc
KVM: PPC: selftests: powerpc enable kvm_create_max_vcpus test
MAINTAINERS | 2 + tools/testing/selftests/kvm/Makefile | 2 +- tools/testing/selftests/kvm/Makefile.kvm | 10 + .../testing/selftests/kvm/include/kvm_util.h | 34 +- .../selftests/kvm/include/powerpc/hcall.h | 17 + .../kvm/include/powerpc/kvm_util_arch.h | 22 + .../selftests/kvm/include/powerpc/ppc_asm.h | 32 ++ .../selftests/kvm/include/powerpc/processor.h | 38 ++ .../selftests/kvm/include/powerpc/ucall.h | 21 + .../selftests/kvm/kvm_create_max_vcpus.c | 9 + .../selftests/kvm/lib/arm64/processor.c | 4 - tools/testing/selftests/kvm/lib/guest_modes.c | 20 +- tools/testing/selftests/kvm/lib/kvm_util.c | 41 +- .../selftests/kvm/lib/loongarch/processor.c | 4 - .../selftests/kvm/lib/powerpc/handlers.S | 93 ++++ .../testing/selftests/kvm/lib/powerpc/hcall.c | 45 ++ .../selftests/kvm/lib/powerpc/processor.c | 481 ++++++++++++++++++ .../testing/selftests/kvm/lib/powerpc/ucall.c | 22 + .../selftests/kvm/lib/riscv/processor.c | 4 - .../selftests/kvm/lib/s390/processor.c | 4 - .../testing/selftests/kvm/lib/x86/processor.c | 9 +- 21 files changed, 869 insertions(+), 45 deletions(-) create mode 100644 tools/testing/selftests/kvm/include/powerpc/hcall.h create mode 100644 tools/testing/selftests/kvm/include/powerpc/kvm_util_arch.h create mode 100644 tools/testing/selftests/kvm/include/powerpc/ppc_asm.h create mode 100644 tools/testing/selftests/kvm/include/powerpc/processor.h create mode 100644 tools/testing/selftests/kvm/include/powerpc/ucall.h create mode 100644 tools/testing/selftests/kvm/lib/powerpc/handlers.S create mode 100644 tools/testing/selftests/kvm/lib/powerpc/hcall.c create mode 100644 tools/testing/selftests/kvm/lib/powerpc/processor.c create mode 100644 tools/testing/selftests/kvm/lib/powerpc/ucall.c
--
2.39.5
RFC 1/4 KVM: selftests: Move pgd_created check into virt_pgd_alloc
From: Nicholas Piggin <[email protected]>
virt_arch_pgd_alloc all do the same test and set of pgd_created. Move this into common code.
--- tools/testing/selftests/kvm/include/kvm_util.h | 5 +++++ tools/testing/selftests/kvm/lib/arm64/processor.c | 4 ---- tools/testing/selftests/kvm/lib/loongarch/processor.c | 4 ---- tools/testing/selftests/kvm/lib/riscv/processor.c | 4 ---- tools/testing/selftests/kvm/lib/s390/processor.c | 4 ---- tools/testing/selftests/kvm/lib/x86/processor.c | 9 +++------ 6 files changed, 8 insertions(+), 22 deletions(-)
tools/testing/selftests/kvm/include/kvm_util.h +5 -0
@@ -1197,7 +1197,12 @@ void virt_arch_pgd_alloc(struct kvm_vm *vm);static inline void virt_pgd_alloc (struct kvm_vm *vm) { +if (vm->mmu.pgd_created) +return ; +virt_arch_pgd_alloc (vm); + + vm->mmu.pgd_created = true; }/*
tools/testing/selftests/kvm/lib/arm64/processor.c +0 -4
@@ -112,13 +112,9 @@ void virt_arch_pgd_alloc(struct kvm_vm *vm) {size_t nr_pages =vm_page_align (vm,ptrs_per_pgd (vm) *8 ) / vm->page_size; -if (vm->mmu.pgd_created) -return ; - vm->mmu.pgd =vm_phy_pages_alloc (vm, nr_pages,KVM_GUEST_PAGE_TABLE_MIN_PADDR , vm->memslots[MEM_REGION_PT ]); - vm->mmu.pgd_created = true; } static void _virt_pg_map(struct kvm_vm *vm, gva_t gva, gpa_t gpa,
tools/testing/selftests/kvm/lib/loongarch/processor.c +0 -4
@@ -51,9 +51,6 @@ void virt_arch_pgd_alloc(struct kvm_vm *vm)int i;gpa_t child, table; -if (vm->mmu.pgd_created) -return ; - child = table =0 ;for (i =0 ; i < vm->mmu.pgtable_levels; i++) { invalid_pgtable[i] = child;
@@ -64,7 +61,6 @@ void virt_arch_pgd_alloc(struct kvm_vm *vm) child = table; } vm->mmu.pgd = table; - vm->mmu.pgd_created = true; }static int virt_pte_none (u64 *ptep,int level)
tools/testing/selftests/kvm/lib/riscv/processor.c +0 -4
@@ -66,13 +66,9 @@ void virt_arch_pgd_alloc(struct kvm_vm *vm) {size_t nr_pages =vm_page_align (vm,ptrs_per_pte (vm) *8 ) / vm->page_size; -if (vm->mmu.pgd_created) -return ; - vm->mmu.pgd =vm_phy_pages_alloc (vm, nr_pages,KVM_GUEST_PAGE_TABLE_MIN_PADDR , vm->memslots[MEM_REGION_PT ]); - vm->mmu.pgd_created = true; }void virt_arch_pg_map (struct kvm_vm *vm,gva_t gva,gpa_t gpa)
tools/testing/selftests/kvm/lib/s390/processor.c +0 -4
@@ -17,16 +17,12 @@ void virt_arch_pgd_alloc(struct kvm_vm *vm)TEST_ASSERT (vm->page_size ==PAGE_SIZE ,"Unsupported page size: 0x%x" , vm->page_size); -if (vm->mmu.pgd_created) -return ; - gpa =vm_phy_pages_alloc (vm,PAGES_PER_REGION ,KVM_GUEST_PAGE_TABLE_MIN_PADDR , vm->memslots[MEM_REGION_PT ]);memset (addr_gpa2hva (vm, gpa),0xff ,PAGES_PER_REGION * vm->page_size); vm->mmu.pgd = gpa; - vm->mmu.pgd_created = true; }/*
tools/testing/selftests/kvm/lib/x86/processor.c +3 -6
@@ -164,12 +164,9 @@ bool kvm_is_tdp_enabled(void)static void virt_mmu_init (struct kvm_vm *vm,struct kvm_mmu *mmu,struct pte_masks *pte_masks) { -/* If needed, create the top-level page table. */ -if (!mmu->pgd_created) { - mmu->pgd =vm_alloc_page_table (vm); - mmu->pgd_created = true; - mmu->arch.pte_masks = *pte_masks; - } +/* Create the top-level page table. */ + mmu->pgd =vm_alloc_page_table (vm); + mmu->arch.pte_masks = *pte_masks; TEST_ASSERT(mmu->pgtable_levels == 4 || mmu->pgtable_levels == 5, "Selftests MMU only supports 4-level and 5-level paging, not %u-level paging",
Signature · 1 line
2.39.5
RFC 2/4 KVM: selftests: Add aligned guest physical page allocator
In reply to Ritesh Harjani (IBM)From: Nicholas Piggin <[email protected]>
powerpc will require this to allocate MMU tables in guest memory that are larger than guest base page size.
--- .../testing/selftests/kvm/include/kvm_util.h | 20 +++++++++-- tools/testing/selftests/kvm/lib/kvm_util.c | 33 +++++++++---------- 2 files changed, 33 insertions(+), 20 deletions(-)
tools/testing/selftests/kvm/include/kvm_util.h +17 -3
@@ -991,8 +991,8 @@ void kvm_gsi_routing_write(struct kvm_vm *vm, struct kvm_irq_routing *routing);const char *exit_reason_str (unsigned int exit_reason);gpa_t vm_phy_page_alloc (struct kvm_vm *vm,gpa_t min_gpa,u32 memslot); -gpa_t __vm_phy_pages_alloc (struct kvm_vm *vm,size_t num,gpa_t min_gpa, -u32 memslot,bool protected); +gpa_t __vm_phy_pages_alloc (struct kvm_vm *vm,size_t num,size_t align, +gpa_t min_gpa,u32 memslot,bool protected);gpa_t vm_alloc_page_table (struct kvm_vm *vm); static inline gpa_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,
@@ -1003,10 +1003,24 @@ static inline gpa_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,* protected memory, as the majority of memory for such VMs is * protected, i.e. using shared memory is effectively opt-in. */ -return __vm_phy_pages_alloc (vm, num, min_gpa, memslot, +return __vm_phy_pages_alloc (vm, num,1 , min_gpa, memslot,vm_arch_has_protected_memory (vm)); } +static inline gpa_t vm_phy_pages_alloc_align (struct kvm_vm *vm,size_t num, +size_t align,gpa_t min_gpa, +u32 memslot) +{ +/* +* By default, allocate memory as protected for VMs that support +* protected memory, as the majority of memory for such VMs is +* protected, i.e. using shared memory is effectively opt-in. +*/ +return __vm_phy_pages_alloc (vm, num, align, min_gpa, memslot, +vm_arch_has_protected_memory (vm)); +} + +/* * ____vm_create() does KVM_CREATE_VM and little else. __vm_create() also * loads the test binary into guest memory and creates an IRQ chip (x86 only).
tools/testing/selftests/kvm/lib/kvm_util.c +16 -17
@@ -1442,7 +1442,7 @@ static gva_t ____vm_alloc(struct kvm_vm *vm, size_t sz, gva_t min_gva,u64 pages = (sz >> vm->page_shift) + ((sz % vm->page_size) !=0 );virt_pgd_alloc (vm); -gpa_t gpa =__vm_phy_pages_alloc (vm, pages, +gpa_t gpa =__vm_phy_pages_alloc (vm, pages,1 ,KVM_UTIL_MIN_PFN * vm->page_size, vm->memslots[type], protected);
@@ -2021,7 +2021,7 @@ const char *exit_reason_str(unsigned int exit_reason)* and their base address is returned. A TEST_ASSERT failure occurs if * not enough pages are available at or above min_gpa. */ -gpa_t __vm_phy_pages_alloc (struct kvm_vm *vm,size_t num, +gpa_t __vm_phy_pages_alloc (struct kvm_vm *vm,size_t num,size_t align,gpa_t min_gpa,u32 memslot,bool protected) {
@@ -2039,23 +2039,22 @@ gpa_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,TEST_ASSERT (!protected || region->protected_phy_pages,"Region doesn't support protected memory" ); - base = pg = min_gpa >> vm->page_shift; -do { -for (; pg < base + num; ++pg) { -if (!sparsebit_is_set (region->unused_phy_pages, pg)) { - base = pg =sparsebit_next_set (region->unused_phy_pages, pg); -break ; + base = min_gpa >> vm->page_shift; +again: + base = (base + align -1 ) & ~(align -1 ); +for (pg = base; pg < base + num; ++pg) { +if (!sparsebit_is_set (region->unused_phy_pages, pg)) { + base =sparsebit_next_set (region->unused_phy_pages, pg); +if (!base) { +fprintf (stderr,"No guest physical page available, " +"min_gpa: 0x%lx page_size: 0x%x memslot: %u\n" , + min_gpa, vm->page_size, memslot); +fputs ("---- vm dump ----\n" , stderr); +vm_dump (stderr, vm,2 ); +abort (); } + goto again; } - }while (pg && pg != base + num); - -if (pg ==0 ) { -fprintf (stderr,"No guest physical page available, " -"min_gpa: 0x%lx page_size: 0x%x memslot: %u\n" , - min_gpa, vm->page_size, memslot); -fputs ("---- vm dump ----\n" , stderr); -vm_dump (stderr, vm,2 ); -abort (); }for (pg = base; pg < base + num; ++pg) {
Signature · 1 line
2.39.5
RFC 3/4 KVM: PPC: selftests: add support for powerpc
In reply to Ritesh Harjani (IBM)From: Nicholas Piggin <[email protected]>
Implement KVM selftests support for powerpc (Book3S-64).
ucalls are implemented with an unsupported PAPR hcall number which will always cause KVM to exit to userspace.
Virtual memory is implemented for the radix MMU, and only a base page size is supported (both 4K and 64K).
Guest interrupts are taken in real-mode, so require a page allocated at gRA 0x0. Interrupt entry is complicated because gVA:gRA is not 1:1 mapped (like the kernel is), so the MMU can not just be switched on and off.
--- MAINTAINERS | 2 + tools/testing/selftests/kvm/Makefile | 2 +- tools/testing/selftests/kvm/Makefile.kvm | 10 + .../testing/selftests/kvm/include/kvm_util.h | 9 + .../selftests/kvm/include/powerpc/hcall.h | 17 + .../kvm/include/powerpc/kvm_util_arch.h | 22 + .../selftests/kvm/include/powerpc/ppc_asm.h | 32 ++ .../selftests/kvm/include/powerpc/processor.h | 38 ++ .../selftests/kvm/include/powerpc/ucall.h | 21 + tools/testing/selftests/kvm/lib/guest_modes.c | 20 +- tools/testing/selftests/kvm/lib/kvm_util.c | 8 + .../selftests/kvm/lib/powerpc/handlers.S | 93 ++++ .../testing/selftests/kvm/lib/powerpc/hcall.c | 45 ++ .../selftests/kvm/lib/powerpc/processor.c | 481 ++++++++++++++++++ .../testing/selftests/kvm/lib/powerpc/ucall.c | 22 + 15 files changed, 819 insertions(+), 3 deletions(-) create mode 100644 tools/testing/selftests/kvm/include/powerpc/hcall.h create mode 100644 tools/testing/selftests/kvm/include/powerpc/kvm_util_arch.h create mode 100644 tools/testing/selftests/kvm/include/powerpc/ppc_asm.h create mode 100644 tools/testing/selftests/kvm/include/powerpc/processor.h create mode 100644 tools/testing/selftests/kvm/include/powerpc/ucall.h create mode 100644 tools/testing/selftests/kvm/lib/powerpc/handlers.S create mode 100644 tools/testing/selftests/kvm/lib/powerpc/hcall.c create mode 100644 tools/testing/selftests/kvm/lib/powerpc/processor.c create mode 100644 tools/testing/selftests/kvm/lib/powerpc/ucall.c
MAINTAINERS +2 -0
@@ -14115,6 +14115,8 @@ F: arch/powerpc/include/asm/kvm* F: arch/powerpc/include/uapi/asm/kvm* F: arch/powerpc/kernel/kvm* F: arch/powerpc/kvm/ +F: tools/testing/selftests/kvm/*/powerpc/ +F: tools/testing/selftests/kvm/powerpc/ KERNEL VIRTUAL MACHINE FOR RISC-V (KVM/riscv) M: Anup Patel <[email protected]>
tools/testing/selftests/kvm/Makefile +1 -1
@@ -3,7 +3,7 @@ top_srcdir = ../../../.. include $(top_srcdir)/scripts/subarch.include ARCH ?= $(SUBARCH) -ifeq ($(ARCH),$(filter $(ARCH),arm64 s390 riscv x86 x86_64 loongarch)) +ifeq ($(ARCH),$(filter $(ARCH),arm64 s390 riscv x86 x86_64 loongarch powerpc)) # Top-level selftests allows ARCH=x86_64 :-( ifeq ($(ARCH),x86_64) override ARCH := x86
tools/testing/selftests/kvm/Makefile.kvm +10 -0
@@ -52,6 +52,11 @@ LIBKVM_loongarch += lib/loongarch/processor.c LIBKVM_loongarch += lib/loongarch/ucall.c LIBKVM_loongarch += lib/loongarch/exception.S +LIBKVM_powerpc += lib/powerpc/handlers.S +LIBKVM_powerpc += lib/powerpc/processor.c +LIBKVM_powerpc += lib/powerpc/ucall.c +LIBKVM_powerpc += lib/powerpc/hcall.c + # Non-compiled test targets TEST_PROGS_x86 += x86/nx_huge_pages_test.sh
@@ -239,6 +244,11 @@ TEST_GEN_PROGS_loongarch += memslot_perf_test TEST_GEN_PROGS_loongarch += set_memory_region_test TEST_GEN_PROGS_loongarch += steal_time +TEST_GEN_PROGS_powerpc = $(TEST_GEN_PROGS_COMMON) +TEST_GEN_PROGS_powerpc += access_tracking_perf_test +TEST_GEN_PROGS_powerpc += dirty_log_perf_test +TEST_GEN_PROGS_powerpc += hardware_disable_test + SPLIT_TESTS += arch_timer SPLIT_TESTS += get-reg-list
tools/testing/selftests/kvm/include/kvm_util.h +9 -0
@@ -209,6 +209,9 @@ enum vm_guest_mode {VM_MODE_P41V48_4K ,VM_MODE_P41V39_4K , +VM_MODE_P52V52_4K ,/* For powerpc64 */ +VM_MODE_P52V52_64K , + NUM_VM_MODES, };
@@ -268,6 +271,12 @@ extern enum vm_guest_mode vm_mode_default;#define MIN_PAGE_SHIFT 12U#define ptes_per_page (page_size) ((page_size) / 8) +#elif defined(__powerpc64__) + +#define VM_MODE_DEFAULT vm_mode_default +#define MIN_PAGE_SHIFT 12U +#define ptes_per_page (page_size) ((page_size) / 8) +#endif #define VM_SHAPE_DEFAULT VM_SHAPE(VM_MODE_DEFAULT)
tools/testing/selftests/kvm/include/powerpc/hcall.h new file +17 -0
@@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +* powerpc hcall defines +*/ +#ifndef SELFTEST_KVM_HCALL_H +#define SELFTEST_KVM_HCALL_H + +#include <linux/compiler.h> + +/* Ucalls use unimplemented PAPR hcall 0 which exits KVM */ +#define H_UCALL 0 + +int64_t hcall0 (uint64_t token); +int64_t hcall1 (uint64_t token,uint64_t arg1); +int64_t hcall2 (uint64_t token,uint64_t arg1,uint64_t arg2); + +#endif
tools/testing/selftests/kvm/include/powerpc/kvm_util_arch.h new file +22 -0
@@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef SELFTEST_KVM_UTIL_ARCH_H +#define SELFTEST_KVM_UTIL_ARCH_H + +#include <stdint.h> + +#include "kvm_util_types.h" + +struct kvm_mmu_arch {}; + +/* Page table fragment cache for guest page tables < page size */ +struct vm_pt_frag_cache { +gpa_t page; +size_t page_nr_used; +}; + +struct kvm_vm_arch { +gpa_t prtb;/* process table */ +struct vm_pt_frag_cache pt_frag_cache[2 ];/* 256B and 4KB PT caches */ +}; + +#endif /* SELFTEST_KVM_UTIL_ARCH_H */
tools/testing/selftests/kvm/include/powerpc/ppc_asm.h new file +32 -0
@@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +* powerpc asm specific defines +*/ +#ifndef SELFTEST_KVM_PPC_ASM_H +#define SELFTEST_KVM_PPC_ASM_H + +#define STACK_FRAME_MIN_SIZE 112/* Could be 32 on ELFv2 */ +#define STACK_REDZONE_SIZE 512 + +#define INT_FRAME_SIZE (STACK_FRAME_MIN_SIZE + STACK_REDZONE_SIZE) + +#define SPR_SRR0 0x01a +#define SPR_SRR1 0x01b +#define SPR_CFAR 0x01c + +#define MSR_SF 0x8000000000000000ULL +#define MSR_HV 0x1000000000000000ULL +#define MSR_VEC 0x0000000002000000ULL +#define MSR_VSX 0x0000000000800000ULL +#define MSR_EE 0x0000000000008000ULL +#define MSR_PR 0x0000000000004000ULL +#define MSR_FP 0x0000000000002000ULL +#define MSR_ME 0x0000000000001000ULL +#define MSR_IR 0x0000000000000020ULL +#define MSR_DR 0x0000000000000010ULL +#define MSR_RI 0x0000000000000002ULL +#define MSR_LE 0x0000000000000001ULL + +#define LPCR_ILE 0x0000000002000000ULL + +#endif
tools/testing/selftests/kvm/include/powerpc/processor.h new file +38 -0
@@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +* powerpc processor specific defines +*/ +#ifndef SELFTEST_KVM_PROCESSOR_H +#define SELFTEST_KVM_PROCESSOR_H + +#include <linux/compiler.h> +#include "ppc_asm.h" + +extern unsigned char __interrupts_start[]; +extern unsigned char __interrupts_end[]; + +struct kvm_vm ; +struct kvm_vcpu ; + +struct ex_regs { +uint64_t gprs[32 ]; +uint64_t nia; +uint64_t msr; +uint64_t cfar; +uint64_t lr; +uint64_t ctr; +uint64_t xer; +uint32_t cr; +uint32_t trap; +uint64_t vaddr;/* vaddr of this struct */ +}; + +void vm_install_exception_handler (struct kvm_vm *vm,int vector, +void (*handler)(struct ex_regs *)); + +static inline void cpu_relax (void ) +{ + asmvolatile ("" :::"memory" ); +} + +#endif
tools/testing/selftests/kvm/include/powerpc/ucall.h new file +21 -0
@@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef SELFTEST_KVM_UCALL_H +#define SELFTEST_KVM_UCALL_H + +#include "hcall.h" + +#define UCALL_EXIT_REASON KVM_EXIT_PAPR_HCALL + +#define UCALL_R4_UCALL 0x5715/* regular ucall, r5 contains ucall pointer */ +#define UCALL_R4_SIMPLE 0x0000/* simple exit usable by asm with no ucall data */ + +static inline void ucall_arch_init (struct kvm_vm *vm,gpa_t mmio_gpa) +{ +} + +static inline void ucall_arch_do_ucall (gva_t uc) +{ +hcall2 (H_UCALL ,UCALL_R4_UCALL , (uintptr_t )(uc)); +} + +#endif
tools/testing/selftests/kvm/lib/guest_modes.c +18 -2
@@ -4,16 +4,20 @@*/ #include "guest_modes.h" -#if defined(__aarch64__) || defined(__riscv) +#if defined(__aarch64__) || defined(__riscv) || defined(__powerpc64__)#include "processor.h" enum vm_guest_mode vm_mode_default;#endif +#if defined(__powerpc64__) +#include <unistd.h> +#endif +struct guest_mode guest_modes[NUM_VM_MODES ];void guest_modes_append_default (void ) { -#if !defined(__aarch64__) && !defined(__riscv) +#if !defined(__aarch64__) && !defined(__riscv) && !defined(__powerpc64__)guest_mode_append (VM_MODE_DEFAULT , true);#endif
@@ -108,6 +112,18 @@ void guest_modes_append_default(void) TEST_ASSERT(vm_mode_default != NUM_VM_MODES, "No supported mode!"); }#endif +#ifdef __powerpc64__ + { +TEST_REQUIRE (kvm_has_cap (KVM_CAP_PPC_MMU_RADIX)); +/* Radix guest EA and RA are 52-bit on POWER9 and POWER10 */ +if (sysconf (_SC_PAGESIZE) ==4096 ) + vm_mode_default =VM_MODE_P52V52_4K ; +else + vm_mode_default =VM_MODE_P52V52_64K ; +guest_mode_append (VM_MODE_P52V52_4K , true); +guest_mode_append (VM_MODE_P52V52_64K , true); + } +#endif }void for_each_guest_mode (void (*func)(enum vm_guest_mode ,void *),void *arg)
tools/testing/selftests/kvm/lib/kvm_util.c +8 -0
@@ -218,6 +218,8 @@ const char *vm_guest_mode_string(u32 i) [VM_MODE_P41V57_4K] = "PA-bits:41, VA-bits:57, 4K pages", [VM_MODE_P41V48_4K] = "PA-bits:41, VA-bits:48, 4K pages", [VM_MODE_P41V39_4K] = "PA-bits:41, VA-bits:39, 4K pages", + [VM_MODE_P52V52_4K] = "PA-bits:52, VA-bits:52, 4K pages", + [VM_MODE_P52V52_64K ] ="PA-bits:52, VA-bits:52, 64K pages" , };_Static_assert (sizeof (strings)/sizeof (char *) ==NUM_VM_MODES ,"Missing new mode strings?" );
@@ -254,6 +256,8 @@ const struct vm_guest_mode_params vm_guest_mode_params[] = { [VM_MODE_P41V57_4K] = { 41, 57, 0x1000, 12 }, [VM_MODE_P41V48_4K] = { 41, 48, 0x1000, 12 }, [VM_MODE_P41V39_4K] = { 41, 39, 0x1000, 12 }, + [VM_MODE_P52V52_4K] = { 52, 52, 0x1000, 12 }, + [VM_MODE_P52V52_64K] = { 52, 52, 0x10000, 16 }, };_Static_assert (sizeof (vm_guest_mode_params)/sizeof (struct vm_guest_mode_params ) ==NUM_VM_MODES ,"Missing new mode params?" );
@@ -371,6 +375,10 @@ struct kvm_vm *____vm_create(struct vm_shape shape)case VM_MODE_P41V39_4K : vm->mmu.pgtable_levels =3 ;break ; +case VM_MODE_P52V52_4K : +case VM_MODE_P52V52_64K : + vm->mmu.pgtable_levels =4 ; +break ;default :TEST_FAIL ("Unknown guest mode: 0x%x" , vm->mode); }
tools/testing/selftests/kvm/lib/powerpc/handlers.S new file +93 -0
93 lines not on this page · raw message
tools/testing/selftests/kvm/lib/powerpc/hcall.c new file +45 -0
45 lines not on this page · raw message
tools/testing/selftests/kvm/lib/powerpc/processor.c new file +481 -0
481 lines not on this page · raw message
tools/testing/selftests/kvm/lib/powerpc/ucall.c new file +22 -0
@@ -0,0 +1,22 @@ +// SPDX-License-Identifier: GPL-2.0 +/* +* ucall support. A ucall is a "hypercall to host userspace". +*/ +#include "kvm_util.h" +#include "ucall_common.h" +#include "hcall.h" + +void *ucall_arch_get_ucall (struct kvm_vcpu *vcpu) +{ +struct kvm_run *run = vcpu->run; + +if (run->exit_reason ==UCALL_EXIT_REASON && + run->papr_hcall.nr ==H_UCALL ) { +struct kvm_regs regs; + +vcpu_regs_get (vcpu, ®s); +if (regs.gpr[4 ] ==UCALL_R4_UCALL ) +return (void *)regs.gpr[5 ]; + } +return NULL ; +}
Signature · 1 line
2.39.5
RFC 4/4 KVM: PPC: selftests: powerpc enable kvm_create_max_vcpus test
In reply to Ritesh Harjani (IBM)From: Nicholas Piggin <[email protected]>
powerpc's maximum permitted vCPU ID depends on the VM's SMT mode, and the maximum reported by KVM_CAP_MAX_VCPU_ID exceeds a simple non-SMT VM's limit.
The powerpc KVM selftest port uses non-SMT VMs, so add a workaround to the kvm_create_max_vcpus test case to limit vCPU IDs to KVM_CAP_MAX_VCPUS on powerpc.
--- tools/testing/selftests/kvm/kvm_create_max_vcpus.c | 9 +++++++++ 1 file changed, 9 insertions(+)
tools/testing/selftests/kvm/kvm_create_max_vcpus.c +9 -0
@@ -56,6 +56,15 @@ int main(int argc, char *argv[])"KVM_MAX_VCPU_IDS (%d) must be at least as large as KVM_MAX_VCPUS (%d)." , kvm_max_vcpu_id, kvm_max_vcpus); +#ifdef __powerpc64__ +/* +* powerpc has a particular format for the vcpu ID that depends on +* the guest SMT mode, and the max ID cap is too large for non-SMT +* modes, where the maximum ID is the same as the maximum vCPUs. +*/ + kvm_max_vcpu_id = kvm_max_vcpus; +#endif +test_vcpu_creation (0 , kvm_max_vcpus);if (kvm_max_vcpu_id > kvm_max_vcpus)
Signature · 1 line
2.39.5