KVM: selftests: arm64: Add support for VM_MODE_P36V48_{4K,64K}
authorMarc Zyngier <maz@kernel.org>
Mon, 27 Dec 2021 12:48:08 +0000 (12:48 +0000)
committerMarc Zyngier <maz@kernel.org>
Tue, 28 Dec 2021 11:04:20 +0000 (11:04 +0000)
Some of the arm64 systems out there have an IPA space that is
positively tiny. Nonetheless, they make great KVM hosts.

Add support for 36bit IPA support with 4kB pages, which makes
some of the fruity machines happy. Whilst we're at it, add support
for 64kB pages as well, though these boxes have no support for it.

Reviewed-by: Andrew Jones <drjones@redhat.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20211227124809.1335409-6-maz@kernel.org
tools/testing/selftests/kvm/include/kvm_util.h
tools/testing/selftests/kvm/lib/aarch64/processor.c
tools/testing/selftests/kvm/lib/guest_modes.c
tools/testing/selftests/kvm/lib/kvm_util.c

index ec070d8007317bfa96dfa9b4b176ca25d14f230e..4e9e01631bc3704d87f7ab1b329054b8e5db400d 100644 (file)
@@ -48,6 +48,8 @@ enum vm_guest_mode {
        VM_MODE_PXXV48_4K,      /* For 48bits VA but ANY bits PA */
        VM_MODE_P47V64_4K,
        VM_MODE_P44V64_4K,
+       VM_MODE_P36V48_4K,
+       VM_MODE_P36V48_64K,
        NUM_VM_MODES,
 };
 
index d005543aa3e20f346fc26bc7bf07367ee7464532..70395c777ea48cca83284b62c614a9ca7d02fa70 100644 (file)
@@ -249,10 +249,12 @@ void aarch64_vcpu_setup(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_vcpu_init
        case VM_MODE_P52V48_64K:
        case VM_MODE_P48V48_64K:
        case VM_MODE_P40V48_64K:
+       case VM_MODE_P36V48_64K:
                tcr_el1 |= 1ul << 14; /* TG0 = 64KB */
                break;
        case VM_MODE_P48V48_4K:
        case VM_MODE_P40V48_4K:
+       case VM_MODE_P36V48_4K:
                tcr_el1 |= 0ul << 14; /* TG0 = 4KB */
                break;
        default:
@@ -272,6 +274,10 @@ void aarch64_vcpu_setup(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_vcpu_init
        case VM_MODE_P40V48_64K:
                tcr_el1 |= 2ul << 32; /* IPS = 40 bits */
                break;
+       case VM_MODE_P36V48_4K:
+       case VM_MODE_P36V48_64K:
+               tcr_el1 |= 1ul << 32; /* IPS = 36 bits */
+               break;
        default:
                TEST_FAIL("Unknown guest mode, mode: 0x%x", vm->mode);
        }
index 67144fdac4336951031a5c896f267838122f15ac..240f2d2e2d23d10370e0c7cc6b5bef6b7969c467 100644 (file)
@@ -37,6 +37,10 @@ void guest_modes_append_default(void)
                        if (ps4k)
                                vm_mode_default = VM_MODE_P40V48_4K;
                }
+               if (limit >= 36) {
+                       guest_mode_append(VM_MODE_P36V48_4K, ps4k, ps4k);
+                       guest_mode_append(VM_MODE_P36V48_64K, ps64k, ps64k);
+               }
 
                /*
                 * Pick the first supported IPA size if the default
index 8f2e0bb1ef96a4f2103fc89c94a13bde34f09f4a..643cb2e9a6536ae76be1541d6723027d3433539b 100644 (file)
@@ -172,6 +172,8 @@ const char *vm_guest_mode_string(uint32_t i)
                [VM_MODE_PXXV48_4K]     = "PA-bits:ANY, VA-bits:48,  4K pages",
                [VM_MODE_P47V64_4K]     = "PA-bits:47,  VA-bits:64,  4K pages",
                [VM_MODE_P44V64_4K]     = "PA-bits:44,  VA-bits:64,  4K pages",
+               [VM_MODE_P36V48_4K]     = "PA-bits:36,  VA-bits:48,  4K pages",
+               [VM_MODE_P36V48_64K]    = "PA-bits:36,  VA-bits:48, 64K pages",
        };
        _Static_assert(sizeof(strings)/sizeof(char *) == NUM_VM_MODES,
                       "Missing new mode strings?");
@@ -191,6 +193,8 @@ const struct vm_guest_mode_params vm_guest_mode_params[] = {
        [VM_MODE_PXXV48_4K]     = {  0,  0,  0x1000, 12 },
        [VM_MODE_P47V64_4K]     = { 47, 64,  0x1000, 12 },
        [VM_MODE_P44V64_4K]     = { 44, 64,  0x1000, 12 },
+       [VM_MODE_P36V48_4K]     = { 36, 48,  0x1000, 12 },
+       [VM_MODE_P36V48_64K]    = { 36, 48, 0x10000, 16 },
 };
 _Static_assert(sizeof(vm_guest_mode_params)/sizeof(struct vm_guest_mode_params) == NUM_VM_MODES,
               "Missing new mode params?");
@@ -252,9 +256,11 @@ struct kvm_vm *vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int perm)
                vm->pgtable_levels = 3;
                break;
        case VM_MODE_P40V48_4K:
+       case VM_MODE_P36V48_4K:
                vm->pgtable_levels = 4;
                break;
        case VM_MODE_P40V48_64K:
+       case VM_MODE_P36V48_64K:
                vm->pgtable_levels = 3;
                break;
        case VM_MODE_PXXV48_4K: