diff options
-rw-r--r-- | hw/arm/virt.c | 23 | ||||
-rw-r--r-- | target/arm/kvm.c | 4 | ||||
-rw-r--r-- | target/arm/kvm_arm.h | 6 |
3 files changed, 23 insertions, 10 deletions
diff --git a/hw/arm/virt.c b/hw/arm/virt.c index c08bf11297..aa2bbd14e0 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -2548,27 +2548,36 @@ static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine, static int virt_kvm_type(MachineState *ms, const char *type_str) { VirtMachineState *vms = VIRT_MACHINE(ms); - int max_vm_pa_size = kvm_arm_get_max_vm_ipa_size(ms); - int requested_pa_size; + int max_vm_pa_size, requested_pa_size; + bool fixed_ipa; + + max_vm_pa_size = kvm_arm_get_max_vm_ipa_size(ms, &fixed_ipa); /* we freeze the memory map to compute the highest gpa */ virt_set_memmap(vms); requested_pa_size = 64 - clz64(vms->highest_gpa); + /* + * KVM requires the IPA size to be at least 32 bits. + */ + if (requested_pa_size < 32) { + requested_pa_size = 32; + } + if (requested_pa_size > max_vm_pa_size) { error_report("-m and ,maxmem option values " "require an IPA range (%d bits) larger than " "the one supported by the host (%d bits)", requested_pa_size, max_vm_pa_size); - exit(1); + exit(1); } /* - * By default we return 0 which corresponds to an implicit legacy - * 40b IPA setting. Otherwise we return the actual requested PA - * logsize + * We return the requested PA log size, unless KVM only supports + * the implicit legacy 40b IPA setting, in which case the kvm_type + * must be 0. */ - return requested_pa_size > 40 ? requested_pa_size : 0; + return fixed_ipa ? 0 : requested_pa_size; } static void virt_machine_class_init(ObjectClass *oc, void *data) diff --git a/target/arm/kvm.c b/target/arm/kvm.c index bebea90122..d8381ba224 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -230,12 +230,14 @@ bool kvm_arm_pmu_supported(void) return kvm_check_extension(kvm_state, KVM_CAP_ARM_PMU_V3); } -int kvm_arm_get_max_vm_ipa_size(MachineState *ms) +int kvm_arm_get_max_vm_ipa_size(MachineState *ms, bool *fixed_ipa) { KVMState *s = KVM_STATE(ms->accelerator); int ret; ret = kvm_check_extension(s, KVM_CAP_ARM_VM_IPA_SIZE); + *fixed_ipa = ret <= 0; + return ret > 0 ? ret : 40; } diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h index 68ec970c4f..34f8daa377 100644 --- a/target/arm/kvm_arm.h +++ b/target/arm/kvm_arm.h @@ -311,10 +311,12 @@ bool kvm_arm_sve_supported(void); /** * kvm_arm_get_max_vm_ipa_size: * @ms: Machine state handle + * @fixed_ipa: True when the IPA limit is fixed at 40. This is the case + * for legacy KVM. * * Returns the number of bits in the IPA address space supported by KVM */ -int kvm_arm_get_max_vm_ipa_size(MachineState *ms); +int kvm_arm_get_max_vm_ipa_size(MachineState *ms, bool *fixed_ipa); /** * kvm_arm_sync_mpstate_to_kvm: @@ -409,7 +411,7 @@ static inline void kvm_arm_add_vcpu_properties(Object *obj) g_assert_not_reached(); } -static inline int kvm_arm_get_max_vm_ipa_size(MachineState *ms) +static inline int kvm_arm_get_max_vm_ipa_size(MachineState *ms, bool *fixed_ipa) { g_assert_not_reached(); } |