On Fri, 1 Mar 2019 14:47:07 +0100 Eric Auger <eric.au...@redhat.com> wrote:
> This patch implements the machine class kvm_type() callback. > It returns the number of bits requested to implement the whole GPA > range including the RAM and IO regions located beyond. > The returned value in passed though the KVM_CREATE_VM ioctl and s/in/is/ > this allows KVM to set the stage2 tables dynamically. > > To compute the highest GPA used in the memory map, kvm_type() > must freeze the memory map by calling virt_set_memmap(). > > Signed-off-by: Eric Auger <eric.au...@redhat.com> with fixed commit: Reviewed-by: Igor Mammedov <imamm...@redhat.com> > > --- > v10 -> v11: > - replace !kvm_enabled check by !vms->memmap > > v7 -> v8: > - remove vmc->no_extended_memmap and vms->extended_memmap > > v6 -> v7: > - Introduce RAMBASE and rename add LEGACY_ prefix in that patch > - use local variables with explicit names in virt_set_memmap: > device_memory_base, device_memory_size > - add an extended_memmap field in the class > > v5 -> v6: > - add some comments > - high IO region cannot start before 256GiB > --- > hw/arm/virt.c | 39 ++++++++++++++++++++++++++++++++++++++- > 1 file changed, 38 insertions(+), 1 deletion(-) > > diff --git a/hw/arm/virt.c b/hw/arm/virt.c > index 624f417cd4..300eaae26f 100644 > --- a/hw/arm/virt.c > +++ b/hw/arm/virt.c > @@ -1440,7 +1440,13 @@ static void machvirt_init(MachineState *machine) > bool firmware_loaded = bios_name || drive_get(IF_PFLASH, 0, 0); > bool aarch64 = true; > > - virt_set_memmap(vms); > + /* > + * In accelerated mode, the memory map is computed earlier in kvm_type() > + * to create a VM with the right number of IPA bits. > + */ > + if (!vms->memmap) { > + virt_set_memmap(vms); > + } > > /* We can probe only here because during property set > * KVM is not available yet > @@ -1829,6 +1835,36 @@ static HotplugHandler > *virt_machine_get_hotplug_handler(MachineState *machine, > return NULL; > } > > +/* > + * for arm64 kvm_type [7-0] encodes the requested number of bits > + * in the IPA address space > + */ > +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; > + > + /* we freeze the memory map to compute the highest gpa */ > + virt_set_memmap(vms); > + > + requested_pa_size = 64 - clz64(vms->highest_gpa); > + > + 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); > + } > + /* > + * By default we return 0 which corresponds to an implicit legacy > + * 40b IPA setting. Otherwise we return the actual requested PA > + * logsize > + */ > + return requested_pa_size > 40 ? requested_pa_size : 0; > +} > + > static void virt_machine_class_init(ObjectClass *oc, void *data) > { > MachineClass *mc = MACHINE_CLASS(oc); > @@ -1853,6 +1889,7 @@ static void virt_machine_class_init(ObjectClass *oc, > void *data) > mc->cpu_index_to_instance_props = virt_cpu_index_to_props; > mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15"); > mc->get_default_cpu_node_id = virt_get_default_cpu_node_id; > + mc->kvm_type = virt_kvm_type; > assert(!mc->get_hotplug_handler); > mc->get_hotplug_handler = virt_machine_get_hotplug_handler; > hc->plug = virt_machine_device_plug_cb;