Re: [PATCH 2/2] hw/arm/virt: Don't create device-tree node for empty NUMA node

2021-10-06 Thread Andrew Jones
On Wed, Oct 06, 2021 at 06:22:09PM +0800, Gavin Shan wrote:
> The empty NUMA node, where no memory resides, are allowed. For
> example, the following command line specifies two empty NUMA nodes.
> With this, QEMU fails to boot because of the conflicting device-tree
> node names, as the following error message indicates.
> 
>   /home/gavin/sandbox/qemu.main/build/qemu-system-aarch64 \
>   -accel kvm -machine virt,gic-version=host   \
>   -cpu host -smp 4,sockets=2,cores=2,threads=1\
>   -m 1024M,slots=16,maxmem=64G\
>   -object memory-backend-ram,id=mem0,size=512M\
>   -object memory-backend-ram,id=mem1,size=512M\
>   -numa node,nodeid=0,cpus=0-1,memdev=mem0\
>   -numa node,nodeid=1,cpus=2-3,memdev=mem1\
>   -numa node,nodeid=2 \
>   -numa node,nodeid=3
> :
>   qemu-system-aarch64: FDT: Failed to create subnode /memory@8000: 
> FDT_ERR_EXISTS
> 
> As specified by linux device-tree binding document, the device-tree
> nodes for these empty NUMA nodes shouldn't be generated. However,
> the corresponding NUMA node IDs should be included in the distance
> map device-tree node. This skips populating the device-tree nodes
> for these empty NUMA nodes to avoid the error, so that QEMU can be
> started successfully.
> 
> Signed-off-by: Gavin Shan 
> ---
>  hw/arm/boot.c | 4 
>  1 file changed, 4 insertions(+)
> 
> diff --git a/hw/arm/boot.c b/hw/arm/boot.c
> index 57efb61ee4..4e5898fcdc 100644
> --- a/hw/arm/boot.c
> +++ b/hw/arm/boot.c
> @@ -603,6 +603,10 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info 
> *binfo,
>  mem_base = binfo->loader_start;
>  for (i = 0; i < ms->numa_state->num_nodes; i++) {
>  mem_len = ms->numa_state->nodes[i].node_mem;
> +if (!mem_len) {
> +continue;
> +}
> +
>  rc = fdt_add_memory_node(fdt, acells, mem_base,
>   scells, mem_len, i);
>  if (rc < 0) {
> -- 
> 2.23.0
>

Reviewed-by: Andrew Jones 




Re: [PATCH 1/2] numa: Set default distance map if needed

2021-10-06 Thread Andrew Jones
On Wed, Oct 06, 2021 at 06:22:08PM +0800, Gavin Shan wrote:
> The following option is used to specify the distance map. It's
> possible the option isn't provided by user. In this case, the
> distance map isn't populated and exposed to platform. On the
> other hand, the empty NUMA node, where no memory resides, is
> allowed on ARM64 virt platform. For these empty NUMA nodes,
> their corresponding device-tree nodes aren't populated, but
> their NUMA IDs should be included in the "/distance-map"
> device-tree node, so that kernel can probe them properly if
> device-tree is used.
> 
>   -numa,dist,src=,dst=,val=
> 
> So when user doesn't specify distance map, we need to generate
> the default distance map, where the local and remote distances
> are 10 and 20 separately. This adds an extra parameter to the
> exiting complete_init_numa_distance() to generate the default
> distance map for this case.
> 
> Signed-off-by: Gavin Shan 
> ---
>  hw/core/numa.c | 13 +++--
>  1 file changed, 11 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/core/numa.c b/hw/core/numa.c
> index 510d096a88..fdb3a4aeca 100644
> --- a/hw/core/numa.c
> +++ b/hw/core/numa.c
> @@ -594,7 +594,7 @@ static void validate_numa_distance(MachineState *ms)
>  }
>  }
>  
> -static void complete_init_numa_distance(MachineState *ms)
> +static void complete_init_numa_distance(MachineState *ms, bool is_default)
>  {
>  int src, dst;
>  NodeInfo *numa_info = ms->numa_state->nodes;
> @@ -609,6 +609,8 @@ static void complete_init_numa_distance(MachineState *ms)
>  if (numa_info[src].distance[dst] == 0) {
>  if (src == dst) {
>  numa_info[src].distance[dst] = NUMA_DISTANCE_MIN;
> +} else if (is_default) {
> +numa_info[src].distance[dst] = NUMA_DISTANCE_DEFAULT;
>  } else {
>  numa_info[src].distance[dst] = 
> numa_info[dst].distance[src];
>  }
> @@ -716,13 +718,20 @@ void numa_complete_configuration(MachineState *ms)
>   * A->B != distance B->A, then that means the distance table is
>   * asymmetric. In this case, the distances for both directions
>   * of all node pairs are required.
> + *
> + * The default node pair distances, which are 10 and 20 for the
> + * local and remote nodes separatly, are provided if user doesn't
> + * specify any node pair distances.
>   */
>  if (ms->numa_state->have_numa_distance) {
>  /* Validate enough NUMA distance information was provided. */
>  validate_numa_distance(ms);
>  
>  /* Validation succeeded, now fill in any missing distances. */
> -complete_init_numa_distance(ms);
> +complete_init_numa_distance(ms, false);
> +} else {
> +complete_init_numa_distance(ms, true);
> +ms->numa_state->have_numa_distance = true;
>  }
>  }
>  }
> -- 
> 2.23.0
>

With this patch we'll always generate a distance map when there's a numa
config now. Is there any reason a user would not want to do that? I.e.
should we still give the user the choice of presenting a distance map?
Also, does the addition of a distance map in DTs for compat machine types
matter?

Otherwise patch looks good to me.

Thanks,
drew




Re: [PATCH v3 2/3] hw/arm/virt_acpi_build: Generate DBG2 table

2021-10-06 Thread Andrew Jones
On Mon, Sep 27, 2021 at 03:17:31PM +0200, Eric Auger wrote:
> ARM SBBR specification mandates DBG2 table (Debug Port Table 2)
> since v1.0 (ARM DEN0044F 8.3.1.7 DBG2).
> 
> The DBG2 table allows to describe one or more debug ports.
> 
> Generate an DBG2 table featuring a single debug port, the PL011.
> 
> The DBG2 specification can be found at
> "Microsoft Debug Port Table 2 (DBG2)"
> https://docs.microsoft.com/en-us/windows-hardware/drivers/bringup/acpi-debug-port-table?redirectedfrom=MSDN
> 
> Signed-off-by: Eric Auger 
> 
> ---
> 
> v2 -> v3:
> Took into account all comments from Igor on v2:
> mostly style adjustment, revision references
> 
> v1 -> v2:
> - rebased on Igor's refactoring
> ---
>  hw/arm/virt-acpi-build.c | 62 +++-
>  1 file changed, 61 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
> index 6cec97352b..257d0fee17 100644
> --- a/hw/arm/virt-acpi-build.c
> +++ b/hw/arm/virt-acpi-build.c
> @@ -616,6 +616,63 @@ build_gtdt(GArray *table_data, BIOSLinker *linker, 
> VirtMachineState *vms)
>  acpi_table_end(linker, );
>  }
>  
> +/* Debug Port Table 2 (DBG2) */
> +static void
> +build_dbg2(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)

nit: I didn't think QEMU liked this style, i.e. QEMU prefers

 static void build_dbg2(GArray *table_data, BIOSLinker *linker,
VirtMachineState *vms)

Eh, I see that hw/arm/virt-acpi-build.c is full of the format you have
here, so never mind.

> +{
> +AcpiTable table = { .sig = "DBG2", .rev = 3, .oem_id = vms->oem_id,

Can you explain where the .rev = 3 comes from? The spec says "For this
version of the specification, this value is 0."


> +.oem_table_id = vms->oem_table_id };
> +int dbg2devicelength;
> +const char name[] = "COM0";
> +const int namespace_length = sizeof(name);
> +
> +acpi_table_begin(, table_data);
> +
> +dbg2devicelength = 22 /* BaseAddressRegister[] offset */ +
> +   12 /* BaseAddressRegister[] */ +
> +   4 /* AddressSize[] */ +

I'd personally prefer the '+' before the comment, but maybe Igor has a
special ACPI code format preference here.

> +   namespace_length /* NamespaceString[] */;
> +
> +/* OffsetDbgDeviceInfo */
> +build_append_int_noprefix(table_data, 44, 4);
> +/* NumberDbgDeviceInfo */
> +build_append_int_noprefix(table_data, 1, 4);
> +
> +/* Table 2. Debug Device Information structure format */
> +build_append_int_noprefix(table_data, 0, 1); /* Revision */
> +build_append_int_noprefix(table_data, dbg2devicelength, 2); /* Length */
> +/* NumberofGenericAddressRegisters */
> +build_append_int_noprefix(table_data, 1, 1);
> +/* NameSpaceStringLength */
> +build_append_int_noprefix(table_data, namespace_length, 2);
> +build_append_int_noprefix(table_data, 38, 2); /* NameSpaceStringOffset */
> +build_append_int_noprefix(table_data, 0, 2); /* OemDataLength */
> +/* OemDataOffset (0 means no OEM data) */
> +build_append_int_noprefix(table_data, 0, 2);
> +
> +/* Port Type */
> +build_append_int_noprefix(table_data, 0x8000 /* Serial */, 2);
> +/* Port Subtype */
> +build_append_int_noprefix(table_data, 0x3 /* ARM PL011 UART */, 2);
> +build_append_int_noprefix(table_data, 0, 2); /* Reserved */
> +/* BaseAddressRegisterOffset */
> +build_append_int_noprefix(table_data, 22, 2);
> +/* AddressSizeOffset */
> +build_append_int_noprefix(table_data, 34, 2);
> +
> +/* BaseAddressRegister[] */
> +build_append_gas(table_data, AML_AS_SYSTEM_MEMORY, 8, 0, 1,
> + vms->memmap[VIRT_UART].base);
> +
> +/* AddressSize[] */
> +build_append_int_noprefix(table_data, 0x1000 /* Register Space */, 4);
> +
> +/* NamespaceString[] */
> +g_array_append_vals(table_data, name, namespace_length);
> +
> +acpi_table_end(linker, );
> +};
> +
>  /*
>   * ACPI spec, Revision 5.1 Errata A
>   * 5.2.12 Multiple APIC Description Table (MADT)
> @@ -875,7 +932,7 @@ void virt_acpi_build(VirtMachineState *vms, 
> AcpiBuildTables *tables)
>  dsdt = tables_blob->len;
>  build_dsdt(tables_blob, tables->linker, vms);
>  
> -/* FADT MADT GTDT MCFG SPCR pointed to by RSDT */
> +/* FADT MADT GTDT MCFG SPCR DBG2 pointed to by RSDT */
>  acpi_add_table(table_offsets, tables_blob);
>  build_fadt_rev5(tables_blob, tables->linker, vms, dsdt);
>  
> @@ -898,6 +955,9 @@ void virt_acpi_build(VirtMachineState *vms, 
> AcpiBuildTables *tables)
>  acpi_add_table(table_offsets, tables_blob);
>  build_spcr(tables_blob, tables->linker, vms);
>  
> +acpi_add_table(table_offsets, tables_blob);
> +build_dbg2(tables_blob, tables->linker, vms);
> +
>  if (vms->ras) {
>  build_ghes_error_table(tables->hardware_errors, tables->linker);
>  acpi_add_table(table_offsets, 

Re: [PATCH v2 4/5] hw/arm/virt: Use the PA range to compute the memory map

2021-10-04 Thread Andrew Jones
On Sun, Oct 03, 2021 at 05:46:04PM +0100, Marc Zyngier wrote:
> The highmem attribute is nothing but another way to express the
> PA range of a VM. To support HW that has a smaller PA range then
> what QEMU assumes, pass this PA range to the virt_set_memmap()
> function, allowing it to correctly exclude highmem devices
> if they are outside of the PA range.
> 
> Signed-off-by: Marc Zyngier 
> ---
>  hw/arm/virt.c | 46 +++---
>  1 file changed, 35 insertions(+), 11 deletions(-)
> 
> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> index 9d2abdbd5f..a572e0c9d9 100644
> --- a/hw/arm/virt.c
> +++ b/hw/arm/virt.c
> @@ -1610,10 +1610,10 @@ static uint64_t virt_cpu_mp_affinity(VirtMachineState 
> *vms, int idx)
>  return arm_cpu_mp_affinity(idx, clustersz);
>  }
>  
> -static void virt_set_memmap(VirtMachineState *vms)
> +static void virt_set_memmap(VirtMachineState *vms, int pa_bits)
>  {
>  MachineState *ms = MACHINE(vms);
> -hwaddr base, device_memory_base, device_memory_size;
> +hwaddr base, device_memory_base, device_memory_size, memtop;
>  int i;
>  
>  vms->memmap = extended_memmap;
> @@ -1628,9 +1628,12 @@ static void virt_set_memmap(VirtMachineState *vms)
>  exit(EXIT_FAILURE);
>  }
>  
> -if (!vms->highmem &&
> -vms->memmap[VIRT_MEM].base + ms->maxram_size > 4 * GiB) {
> -error_report("highmem=off, but memory crosses the 4GiB limit\n");
> +if (!vms->highmem)
> + pa_bits = 32;
> +
> +if (vms->memmap[VIRT_MEM].base + ms->maxram_size > BIT_ULL(pa_bits)) {
> + error_report("Addressing limited to %d bits, but memory exceeds it 
> by %llu bytes\n",
> +  pa_bits, vms->memmap[VIRT_MEM].base + ms->maxram_size 
> - BIT_ULL(pa_bits));
>  exit(EXIT_FAILURE);
>  }
>  /*
> @@ -1645,7 +1648,7 @@ static void virt_set_memmap(VirtMachineState *vms)
>  device_memory_size = ms->maxram_size - ms->ram_size + ms->ram_slots * 
> GiB;
>  
>  /* Base address of the high IO region */
> -base = device_memory_base + ROUND_UP(device_memory_size, GiB);
> +memtop = base = device_memory_base + ROUND_UP(device_memory_size, GiB);
>  if (base < device_memory_base) {
>  error_report("maxmem/slots too huge");
>  exit(EXIT_FAILURE);
> @@ -1662,9 +1665,17 @@ static void virt_set_memmap(VirtMachineState *vms)
>  vms->memmap[i].size = size;
>  base += size;
>  }
> -vms->highest_gpa = (vms->highmem ?
> -base :
> -vms->memmap[VIRT_MEM].base + ms->maxram_size) - 1;
> +
> +/*
> + * If base fits within pa_bits, all good. If it doesn't, limit it
> + * to the end of RAM, which is guaranteed to fit within pa_bits.

We tested that

  vms->memmap[VIRT_MEM].base + ms->maxram_size

fits within pa_bits, but here we're setting highest_gpa to

  ROUND_UP(vms->memmap[VIRT_MEM].base + ms->ram_size, GiB) +
  ROUND_UP(ms->maxram_size - ms->ram_size + ms->ram_slots * GiB, GiB)

which will be larger. Shouldn't we test memtop instead to make this
guarantee?


> + */
> +if (base <= BIT_ULL(pa_bits)) {
> +vms->highest_gpa = base -1;
> +} else {
> +vms->highest_gpa = memtop - 1;
> +}
> +
>  if (device_memory_size > 0) {
>  ms->device_memory = g_malloc0(sizeof(*ms->device_memory));
>  ms->device_memory->base = device_memory_base;
> @@ -1860,7 +1871,20 @@ static void machvirt_init(MachineState *machine)
>   * to create a VM with the right number of IPA bits.
>   */
>  if (!vms->memmap) {
> -virt_set_memmap(vms);
> +ARMCPU *armcpu = ARM_CPU(first_cpu);


I think it's too early to use first_cpu here (although, I'll admit I'm
always confused as to what gets initialized when...) Assuming we need to
realize the cpus first, then we don't do that until a bit further down
in this function. I wonder if it's possible to delay this memmap setup
until after cpu realization. I see the memmap getting used prior when
calculating virt_max_cpus, but that looks like it needs to be updated
anyway to take highmem into account as to whether or not we should
consider the high gicv3 redist region in the calculation.

> +int pa_bits;
> +
> +if (object_property_get_bool(OBJECT(first_cpu), "aarch64", NULL)) {
> +pa_bits = arm_pamax(armcpu);
> +} else if (arm_feature(>env, ARM_FEATURE_LPAE)) {
> +/* v7 with LPAE */
> +pa_bits = 40;
> +} else {
> +/* Anything else */
> +pa_bits = 32;
> +}
> +
> +virt_set_memmap(vms, pa_bits);
>  }
>  
>  /* We can probe only here because during property set
> @@ -2596,7 +2620,7 @@ static int virt_kvm_type(MachineState *ms, const char 
> *type_str)
>  max_vm_pa_size = kvm_arm_get_max_vm_ipa_size(ms, _ipa);
>  
>  /* we freeze the memory map to compute the highest gpa */
> -virt_set_memmap(vms);

Re: [PATCH v2 4/5] hw/arm/virt: Use the PA range to compute the memory map

2021-10-04 Thread Andrew Jones
On Sun, Oct 03, 2021 at 05:46:04PM +0100, Marc Zyngier wrote:
...
> @@ -1662,9 +1665,17 @@ static void virt_set_memmap(VirtMachineState *vms)
>  vms->memmap[i].size = size;
>  base += size;
>  }
> -vms->highest_gpa = (vms->highmem ?
> -base :
> -vms->memmap[VIRT_MEM].base + ms->maxram_size) - 1;
> +
> +/*
> + * If base fits within pa_bits, all good. If it doesn't, limit it
> + * to the end of RAM, which is guaranteed to fit within pa_bits.
> + */
> +if (base <= BIT_ULL(pa_bits)) {
> +vms->highest_gpa = base -1;
^ missing space here

> +} else {
> +vms->highest_gpa = memtop - 1;
> +}
> +
>  if (device_memory_size > 0) {
>  ms->device_memory = g_malloc0(sizeof(*ms->device_memory));
>  ms->device_memory->base = device_memory_base;

Thanks,
drew




Re: [PATCH v2 2/5] hw/arm/virt: Add a control for the the highmem redistributors

2021-10-04 Thread Andrew Jones
On Mon, Oct 04, 2021 at 11:44:08AM +0200, Andrew Jones wrote:
> On Sun, Oct 03, 2021 at 05:46:02PM +0100, Marc Zyngier wrote:
...
> >  
> > -return MACHINE(vms)->smp.cpus > redist0_capacity ? 2 : 1;
> > +return (MACHINE(vms)->smp.cpus > redist0_capacity &&
> > +vms->highmem_redists) ? 2 : 1;
> 
> Wouldn't it be equivalent to just use vms->highmem here?

OK, I see in the last patch that we may disable highmem_redists
but not highmem.

In that case,

Reviewed-by: Andrew Jones 

Thanks,
drew




Re: [PATCH v2 3/5] hw/arm/virt: Honor highmem setting when computing the memory map

2021-10-04 Thread Andrew Jones
On Sun, Oct 03, 2021 at 05:46:03PM +0100, Marc Zyngier wrote:
> Even when the VM is configured with highmem=off, the highest_gpa
> field includes devices that are above the 4GiB limit.
> Similarily, nothing seem to check that the memory is within
> the limit set by the highmem=off option.
> 
> This leads to failures in virt_kvm_type() on systems that have
> a crippled IPA range, as the reported IPA space is larger than
> what it should be.
> 
> Instead, honor the user-specified limit to only use the devices
> at the lowest end of the spectrum, and fail if we have memory
> crossing the 4GiB limit.
> 
> Signed-off-by: Marc Zyngier 
> ---
>  hw/arm/virt.c | 9 -
>  1 file changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> index bcf58f677d..9d2abdbd5f 100644
> --- a/hw/arm/virt.c
> +++ b/hw/arm/virt.c
> @@ -1628,6 +1628,11 @@ static void virt_set_memmap(VirtMachineState *vms)
>  exit(EXIT_FAILURE);
>  }
>  
> +if (!vms->highmem &&
> +vms->memmap[VIRT_MEM].base + ms->maxram_size > 4 * GiB) {
> +error_report("highmem=off, but memory crosses the 4GiB limit\n");
> +exit(EXIT_FAILURE);
> +}
>  /*
>   * We compute the base of the high IO region depending on the
>   * amount of initial and device memory. The device memory start/size
> @@ -1657,7 +1662,9 @@ static void virt_set_memmap(VirtMachineState *vms)
>  vms->memmap[i].size = size;
>  base += size;
>  }
> -vms->highest_gpa = base - 1;
> +vms->highest_gpa = (vms->highmem ?
> +base :
> +vms->memmap[VIRT_MEM].base + ms->maxram_size) - 1;
>  if (device_memory_size > 0) {
>  ms->device_memory = g_malloc0(sizeof(*ms->device_memory));
>  ms->device_memory->base = device_memory_base;
> -- 
> 2.30.2
>

Reviewed-by: Andrew Jones 




Re: [PATCH v2 5/5] hw/arm/virt: Disable highmem devices that don't fit in the PA range

2021-10-04 Thread Andrew Jones
On Sun, Oct 03, 2021 at 05:46:05PM +0100, Marc Zyngier wrote:
> Make sure both the highmem PCIe and GICv3 regions are disabled when
> they don't fully fit in the PA range.
> 
> Signed-off-by: Marc Zyngier 
> ---
>  hw/arm/virt.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> index a572e0c9d9..756f67b6c8 100644
> --- a/hw/arm/virt.c
> +++ b/hw/arm/virt.c
> @@ -1673,6 +1673,9 @@ static void virt_set_memmap(VirtMachineState *vms, int 
> pa_bits)
>  if (base <= BIT_ULL(pa_bits)) {
>  vms->highest_gpa = base -1;
>  } else {
> +/* Advertise that we have disabled the highmem devices */
> +vms->highmem_ecam = false;
> +vms->highmem_redists = false;
>  vms->highest_gpa = memtop - 1;
>  }
>  
> -- 
> 2.30.2
>

Reviewed-by: Andrew Jones 




Re: [PATCH v2 2/5] hw/arm/virt: Add a control for the the highmem redistributors

2021-10-04 Thread Andrew Jones
On Sun, Oct 03, 2021 at 05:46:02PM +0100, Marc Zyngier wrote:
> Just like we can control the enablement of the highmem PCIe region
> using highmem_ecam, let's add a control for the highmem GICv3
> redistributor region.
> 
> Similarily to highmem_ecam, these redistributors are disabled when
> highmem is off.
> 
> Signed-off-by: Marc Zyngier 
> ---
>  hw/arm/virt-acpi-build.c | 2 ++
>  hw/arm/virt.c| 3 +++
>  include/hw/arm/virt.h| 4 +++-
>  3 files changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
> index d7bef0e627..f0d0b662b7 100644
> --- a/hw/arm/virt-acpi-build.c
> +++ b/hw/arm/virt-acpi-build.c
> @@ -792,6 +792,8 @@ void virt_acpi_build(VirtMachineState *vms, 
> AcpiBuildTables *tables)
>  acpi_add_table(table_offsets, tables_blob);
>  build_fadt_rev5(tables_blob, tables->linker, vms, dsdt);
>  
> +vms->highmem_redists &= vms->highmem;
> +
>  acpi_add_table(table_offsets, tables_blob);
>  build_madt(tables_blob, tables->linker, vms);
>  
> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> index 8021d545c3..bcf58f677d 100644
> --- a/hw/arm/virt.c
> +++ b/hw/arm/virt.c
> @@ -2053,6 +2053,8 @@ static void machvirt_init(MachineState *machine)
>  
>  virt_flash_fdt(vms, sysmem, secure_sysmem ?: sysmem);
>  
> +vms->highmem_redists &= vms->highmem;
> +
>  create_gic(vms, sysmem);
>  
>  virt_cpu_post_init(vms, sysmem);
> @@ -2750,6 +2752,7 @@ static void virt_instance_init(Object *obj)
>  vms->gic_version = VIRT_GIC_VERSION_NOSEL;
>  
>  vms->highmem_ecam = !vmc->no_highmem_ecam;
> +vms->highmem_redists = true;
>  
>  if (vmc->no_its) {
>  vms->its = false;
> diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
> index b461b8d261..787cc8a27d 100644
> --- a/include/hw/arm/virt.h
> +++ b/include/hw/arm/virt.h
> @@ -141,6 +141,7 @@ struct VirtMachineState {
>  bool secure;
>  bool highmem;
>  bool highmem_ecam;
> +bool highmem_redists;
>  bool its;
>  bool tcg_its;
>  bool virt;
> @@ -187,7 +188,8 @@ static inline int 
> virt_gicv3_redist_region_count(VirtMachineState *vms)
>  
>  assert(vms->gic_version == VIRT_GIC_VERSION_3);
>  
> -return MACHINE(vms)->smp.cpus > redist0_capacity ? 2 : 1;
> +return (MACHINE(vms)->smp.cpus > redist0_capacity &&
> +vms->highmem_redists) ? 2 : 1;

Wouldn't it be equivalent to just use vms->highmem here?

>  }
>  
>  #endif /* QEMU_ARM_VIRT_H */
> -- 
> 2.30.2
> 

Thanks,
drew




Re: [PATCH v2 1/5] hw/arm/virt: Key enablement of highmem PCIe on highmem_ecam

2021-10-04 Thread Andrew Jones
On Sun, Oct 03, 2021 at 05:46:01PM +0100, Marc Zyngier wrote:
> Currently, the highmem PCIe region is oddly keyed on the highmem
> attribute instead of highmem_ecam. Move the enablement of this PCIe
> region over to highmem_ecam.
> 
> Signed-off-by: Marc Zyngier 
> ---
>  hw/arm/virt-acpi-build.c | 10 --
>  hw/arm/virt.c|  4 ++--
>  2 files changed, 6 insertions(+), 8 deletions(-)
> 
> diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
> index 037cc1fd82..d7bef0e627 100644
> --- a/hw/arm/virt-acpi-build.c
> +++ b/hw/arm/virt-acpi-build.c
> @@ -157,10 +157,9 @@ static void acpi_dsdt_add_virtio(Aml *scope,
>  }
>  
>  static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
> -  uint32_t irq, bool use_highmem, bool 
> highmem_ecam,
> -  VirtMachineState *vms)
> +  uint32_t irq, VirtMachineState *vms)
>  {
> -int ecam_id = VIRT_ECAM_ID(highmem_ecam);
> +int ecam_id = VIRT_ECAM_ID(vms->highmem_ecam);
>  struct GPEXConfig cfg = {
>  .mmio32 = memmap[VIRT_PCIE_MMIO],
>  .pio= memmap[VIRT_PCIE_PIO],
> @@ -169,7 +168,7 @@ static void acpi_dsdt_add_pci(Aml *scope, const 
> MemMapEntry *memmap,
>  .bus= vms->bus,
>  };
>  
> -if (use_highmem) {
> +if (vms->highmem_ecam) {
>  cfg.mmio64 = memmap[VIRT_HIGH_PCIE_MMIO];
>  }
>  
> @@ -712,8 +711,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, 
> VirtMachineState *vms)
>  acpi_dsdt_add_fw_cfg(scope, [VIRT_FW_CFG]);
>  acpi_dsdt_add_virtio(scope, [VIRT_MMIO],
>  (irqmap[VIRT_MMIO] + ARM_SPI_BASE), 
> NUM_VIRTIO_TRANSPORTS);
> -acpi_dsdt_add_pci(scope, memmap, (irqmap[VIRT_PCIE] + ARM_SPI_BASE),
> -  vms->highmem, vms->highmem_ecam, vms);
> +acpi_dsdt_add_pci(scope, memmap, (irqmap[VIRT_PCIE] + ARM_SPI_BASE), 
> vms);

While tidying this interface, could also remove the superfluous ().

>  if (vms->acpi_dev) {
>  build_ged_aml(scope, "\\_SB."GED_DEVICE,
>HOTPLUG_HANDLER(vms->acpi_dev),
> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> index 7170aaacd5..8021d545c3 100644
> --- a/hw/arm/virt.c
> +++ b/hw/arm/virt.c
> @@ -1362,7 +1362,7 @@ static void create_pcie(VirtMachineState *vms)
>   mmio_reg, base_mmio, size_mmio);
>  memory_region_add_subregion(get_system_memory(), base_mmio, mmio_alias);
>  
> -if (vms->highmem) {
> +if (vms->highmem_ecam) {
>  /* Map high MMIO space */
>  MemoryRegion *high_mmio_alias = g_new0(MemoryRegion, 1);
>  
> @@ -1416,7 +1416,7 @@ static void create_pcie(VirtMachineState *vms)
>  qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg",
>   2, base_ecam, 2, size_ecam);
>  
> -if (vms->highmem) {
> +if (vms->highmem_ecam) {
>  qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "ranges",
>   1, FDT_PCI_RANGE_IOPORT, 2, 0,
>   2, base_pio, 2, size_pio,
> -- 
> 2.30.2
> 


Reviewed-by: Andrew Jones 

Thanks,
drew




Re: [PATCH] hw/arm/virt: Allow additions to the generated device tree

2021-09-29 Thread Andrew Jones
On Wed, Sep 29, 2021 at 09:09:59AM -0600, Simon Glass wrote:
> Hi Peter,
> 
> On Wed, 29 Sept 2021 at 03:10, Peter Maydell  wrote:
> >
> > On Wed, 29 Sept 2021 at 04:01, Simon Glass  wrote:
> > > On Tue, 28 Sept 2021 at 03:21, Peter Maydell  
> > > wrote:
> > > > So what *is* this patch doing? The subject says "Allow additions to
> > > > the generated device tree", and the patch adds an option to
> > > > "Merge a device tree binary (dtb) file into the generated device tree".
> > > > That sounds exactly like "combine two bits of dtb" -- the one the
> > > > user provides to the -dtbi option and the one QEMU generates
> > > > internally.
> > >
> > > Yes that's right, but as you say one of them is generated by QEMU. It
> > > is fixing a problem caused by QEMU's generation of the device tree,
> > > since it provides no wat to augment the device tree without my patch.
> >
> > You can augment it in the guest if you need to add guest-specific stuff.
> 
> This was also discussed, see below.
> 
> >
> > > > > The only current working option is to just pass the U-Boot dtb through
> > > > > and not use QEMU's on-the-fly-generated dtb at all. But I am assuming
> > > > > there is a reason why QEMU generates that dtb, so that would not be
> > > > > desirable?
> > > >
> > > > QEMU generates the dtb to tell the guest what hardware is
> > > > present and where it is. We don't guarantee that that hardware
> > > > arrangement is necessarily stable between QEMU versions (in
> > > > practice there are generally additions and not deletions or
> > > > moves, but in theory there might be). All the guest is supposed
> > > > to assume is the location of RAM and flash; everything else it
> > > > must look in the dtb to determine.
> > >
> > > Yes, so that is going to severely limit the usefulness of the virtio
> > > support, for example. But we can just ignore it for CI, I suppose,
> > > since we can use fixed parameters to QEMU, if you don't want to allow
> > > more control of the device tree.
> >
> > virtio-mmio devices should already be correctly indicated in the
> > device tree. virtio-pci devices can be found by probing the PCI
> > bus in the usual way (and you can find out where the PCI controller
> > is by looking in the dtb).
> 
> Which device tree? The one generated by QEMU or the one we would
> actually use, in U-Boot?
> 
> >
> > > This patch is really just augmenting what QEMU is already doing and
> > > solving a problem that it has. I don't see it as creating a new boot
> > > mechanism or being a weird tweak. If anything, it puts the tweaking in
> > > the hands of the user. It seems like something you would be keen on,
> > > from that POV.
> >
> > I absolutely see it as a weird tweak. It's something that
> > only u-boot seems to care about, and it's adding an extra
> > user-facing command line option that is basically
> > "if you need to boot u-boot you need this". The user should
> > not need to "control" the dtb, because QEMU should already
> > be creating a dtb which describes the hardware it is exposing
> > to the guest.
> 
> I don't even know how to respond to that. Anything that uses
> devicetree for control will need to have its bindings respected. It is
> QEMU that is confused here, with its idea that if it just creates
> whatever it feels like, it will be suitable for the payload. It may be
> suitable for linux because it was coded up that way, but it is not
> suitable in general. Each project can have its own device tree
> bindings, yes?
> 
> See for example barebox which has the same problem:
> https://www.barebox.org/doc/latest/devicetree/bindings/barebox/barebox,environment.html
> 
> >
> > > > Guest software running on the "virt" board needs to know it is
> > > > running on the "virt" board and deal with the interface and
> > > > information that QEMU provides. (For instance, Arm Trusted
> > > > Firmware and UEFI both have done this.)
> > >
> > > Well unfortunately this is in conflict, based on what you have said in
> > > this thread. We can either have virtio support (use QEMU-generated
> > > device tree) or have U-Boot work correctly (use -dtb). Do you have any
> > > other ideas?
> >
> > I've already suggested what I think you should do: have u-boot
> > combine the dtb it gets from QEMU with the dtb-extras stuff
> > it wants for its own purposes, with the latter supplied in
> > any of a bunch of workable ways (extra file loaded in memory,
> > concatenate the dtb blob with the u-boot binary at compile
> > time, whatever; rough analogy with however u-boot gets the
> > full dtb on hardware platforms where there is none).
> 
> Unfortunately this is not practical for reasons I explained
> previously. To recap:
> 
> - this is not how real boards work (they expect their dtb to be provided)
> - It adds code to the early stage of U-Boot which would not be there
> in a real system
> - this code takes a long time to run, particularly with the cache off or in 
> SPL
> - we don't have access to a second dtb anyway
> 
> 

Re: [PATCH v2 2/2] qemu-options: Add missing "sockets=2,maxcpus=2" to CLI "-smp 2"

2021-09-29 Thread Andrew Jones
On Tue, Sep 28, 2021 at 08:11:34PM +0800, Yanan Wang wrote:
> There is one numa config example in qemu-options.hx currently
> using "-smp 2" and assuming that there will be 2 sockets and
> 2 cpus totally. However now the actual calculation logic of
> missing sockets and cores is not immutable and is considered
> liable to change. Although we will get maxcpus=2 finally based
> on current parser, it's always stable to specify it explicitly.
> 
> So "-smp 2,sockets=2,maxcpus=2" will be optimal when we expect
> multiple sockets and 2 cpus totally.
> 
> Signed-off-by: Yanan Wang 
> Reviewed-by: Philippe Mathieu-Daude 
> ---
>  qemu-options.hx | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/qemu-options.hx b/qemu-options.hx
> index dcd9595650..ff8917c5e1 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -395,7 +395,7 @@ SRST
>  -m 2G \
>  -object memory-backend-ram,size=1G,id=m0 \
>  -object memory-backend-ram,size=1G,id=m1 \
> --smp 2 \
> +-smp 2,sockets=2,maxcpus=2 \
>  -numa node,nodeid=0,memdev=m0 \
>  -numa node,nodeid=1,memdev=m1,initiator=0 \
>  -numa cpu,node-id=0,socket-id=0 \
> -- 
> 2.19.1
>

Reviewed-by: Andrew Jones 




Re: [PATCH v2 1/2] qemu-options: Tweak [,maxcpus=cpus] to [,maxcpus=maxcpus]

2021-09-29 Thread Andrew Jones
On Tue, Sep 28, 2021 at 08:11:33PM +0800, Yanan Wang wrote:
> In qemu-option.hx, there is "-smp [[cpus=]n][,maxcpus=cpus]..." in the
> DEF part, and "-smp [[cpus=]n][,maxcpus=maxcpus]..." in the RST part.
> Obviously the later is right, let's fix the previous one.
> 
> Signed-off-by: Yanan Wang 
> Reviewed-by: Damien Hedde 
> ---
>  qemu-options.hx | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 5c1b0311c0..dcd9595650 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -200,7 +200,7 @@ SRST
>  ERST
>  
>  DEF("smp", HAS_ARG, QEMU_OPTION_smp,
> -"-smp 
> [[cpus=]n][,maxcpus=cpus][,sockets=sockets][,dies=dies][,cores=cores][,threads=threads]\n"
> +"-smp 
> [[cpus=]n][,maxcpus=maxcpus][,sockets=sockets][,dies=dies][,cores=cores][,threads=threads]\n"
>  "set the number of CPUs to 'n' [default=1]\n"
>  "maxcpus= maximum number of total CPUs, including\n"
>  "offline CPUs for hotplug, etc\n"
> -- 
> 2.19.1
>

Reviewed-by: Andrew Jones 




Re: [PATCH v9 07/16] qtest/numa-test: Use detailed -smp CLI in test_def_cpu_split

2021-09-10 Thread Andrew Jones
On Fri, Sep 10, 2021 at 03:30:16PM +0800, Yanan Wang wrote:
> Since commit 80d7835749 (qemu-options: rewrite help for -smp options),
> the preference of sockets/cores in -smp parsing is considered liable
> to change, and actually we are going to change it in a coming commit.
> So it'll be more stable to use detailed -smp CLIs in the testcases
> that have strong dependency on the parsing results.
> 
> Currently, test_def_cpu_split use "-smp 8" and will get 8 CPU sockets
> based on current parsing rule. But if we change to prefer cores over
> sockets we will get one CPU socket will 8 cores, and this testcase
> will not get expected numa set by default on x86_64 (Ok on aarch64).
> 
> So now explicitly use "-smp 8,sockets=8" to avoid affect from parsing
> logic change.
> 
> Cc: Thomas Huth 
> Cc: Laurent Vivier 
> Cc: Paolo Bonzini 
> Cc: Igor Mammedov 
> Signed-off-by: Yanan Wang 
> ---
>  tests/qtest/numa-test.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/tests/qtest/numa-test.c b/tests/qtest/numa-test.c
> index fd7a2e80a0..90bf68a5b3 100644
> --- a/tests/qtest/numa-test.c
> +++ b/tests/qtest/numa-test.c
> @@ -42,7 +42,8 @@ static void test_def_cpu_split(const void *data)
>  g_autofree char *s = NULL;
>  g_autofree char *cli = NULL;
>  
> -cli = make_cli(data, "-machine smp.cpus=8 -numa node,memdev=ram -numa 
> node");
> +cli = make_cli(data, "-machine smp.cpus=8,smp.sockets=8 "
> + "-numa node,memdev=ram -numa node");
>  qts = qtest_init(cli);
>  
>  s = qtest_hmp(qts, "info numa");
> -- 
> 2.23.0
>

 
Reviewed-by: Andrew Jones 




Re: [PATCH v9 06/16] qtest/numa-test: Use detailed -smp CLIs in pc_dynamic_cpu_cfg

2021-09-10 Thread Andrew Jones
On Fri, Sep 10, 2021 at 03:30:15PM +0800, Yanan Wang wrote:
> Since commit 80d7835749 (qemu-options: rewrite help for -smp options),
> the preference of sockets/cores in -smp parsing is considered liable
> to change, and actually we are going to change it in a coming commit.
> So it'll be more stable to use detailed -smp CLIs in testing if we
> have strong dependency on the parsing results.
> 
> pc_dynamic_cpu_cfg currently assumes/needs that there will be 2 CPU
> sockets with "-smp 2". To avoid breaking the test because of parsing
> logic change, now explicitly use "-smp 2,sockets=2".
> 
> Cc: Thomas Huth 
> Cc: Laurent Vivier 
> Cc: Paolo Bonzini 
> Cc: Igor Mammedov 
> Signed-off-by: Yanan Wang 
> ---
>  tests/qtest/numa-test.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/tests/qtest/numa-test.c b/tests/qtest/numa-test.c
> index c677cd63c4..fd7a2e80a0 100644
> --- a/tests/qtest/numa-test.c
> +++ b/tests/qtest/numa-test.c
> @@ -265,7 +265,8 @@ static void pc_dynamic_cpu_cfg(const void *data)
>  QTestState *qs;
>  g_autofree char *cli = NULL;
>  
> -cli = make_cli(data, "-nodefaults --preconfig -machine smp.cpus=2");
> +cli = make_cli(data, "-nodefaults --preconfig "
> + "-machine smp.cpus=2,smp.sockets=2");
>  qs = qtest_init(cli);
>  
>  /* create 2 numa nodes */
> -- 
> 2.23.0
>

 
Reviewed-by: Andrew Jones 




Re: Questions on setting guest CPU models with ARM kvm enabled

2021-09-10 Thread Andrew Jones
On Fri, Sep 10, 2021 at 10:40:30AM +0800, Jingyi Wang wrote:
> Hi all,
> On ARM hardware, as qemu docs describes, "Named CPU models generally
> do not work with KVM." May I ask what is the main obstacle to setting a
> guest CPU model on later host hardware?

Currently KVM does not give the user (QEMU) control over ID registers.
You cannot migrate a model using KVM to another host because you cannot
write the model's ID registers to KVM if they do not exactly match the
destination host's ID registers. Changing that behavior is just a matter
of coding, but at least one register, MIDR, will still cause problems
with guests that use it to modify their behavior, e.g. to enable
workarounds for errata. A general solution to that problem is not
really possible. See [1] for where I wrote more about that.

> 
> For example, if I want to start Cortex-A57 guest on Cortex-A72 host,
> I noticed that there is not much big difference between these two CPU
> models(Please correct me if I'm wrong), what work should I do?

You may be able to find two systems that you deem "close enough" to
attempt to migrate. [1] has some proposals for attempting to support
"close enough" migrations.

Also, Peng Liang was working on attempting to make ID registers user
controlled [2],[3]. However, I think the approach was trying to do too
much too fast. We need to take baby steps towards CPU models. Also,
I heard somebody from Google might be trying to give users control
over ID registers, but I haven't seen patches.

IMO, a first baby step towards CPU models would be changing the
reject list we currently have in KVM for what features we expose
to the guest (see arch/arm64/kvm/sys_regs.c:read_id_reg) to an allow
list. The second step would be to give user control to ID registers,
which would mean each ID register set_user function would need to
learn how to sanity check its register value, which would probably
need to be done in a some vcpu finalize function, since there can be
inter-register dependencies. KVM will also have to give up control
over registers like MIDR, because the fields are implementation
defined, so there's no way to sanity check them.

Once KVM has these changes, then we'd need to build models in QEMU,
advertise the model capabilities to upper layers, etc. in order for
them to be used. But, we'd still leave a big burden on the users to
determine what safe migrations are, due to the errata problem I
mentioned above.

The last sentence of the last paragraph is why we've never really
considered all the work to be worth it. However, I would welcome
some baby steps, particularly the KVM reject-list to allow-list
change, which would ensure safer execution of guests in general,
not just for migration.

Thanks,
drew

[1] 
https://yhbt.net/lore/all/cabgnm92-phwg3x41tcvfermv9-hnu5gypz_pa9-ixfbscfu...@mail.gmail.com/T/#ma3475a71f6ad34853470c8b38cd4ff43815b79d9
[2] https://www.mail-archive.com/qemu-devel@nongnu.org/msg756323.html
[3] https://lists.cs.columbia.edu/pipermail/kvmarm/2020-November/043011.html




Re: [PATCH v2 0/3] hw/arm/virt_acpi_build: Generate DBG2 table

2021-09-08 Thread Andrew Jones
On Mon, Sep 06, 2021 at 02:31:36PM +0200, Eric Auger wrote:
> This series generates the ACPI DBG2 table along with machvirt.
> It applies on top of Igor's
> [PATCH v2 00/35] acpi: refactor error prone build_header() and
> packed structures usage in ACPI tables
> 
> The DBG2 specification can be found at
> https://docs.microsoft.com/en-us/windows-hardware/drivers/bringup/acpi-debug-port-table.
> 
> DBG2 is mandated by ARM SBBR since its v1.0 release (the rationale
> behind is Windows requires it on all systems).
> 
> The DBG2 is used to describe a debug port, used by the kernel debugger.

Hi Eric,

Did you test this in some way with a Linux guest?

Thanks,
drew

> 
> This series and its dependency can be found at
> https://github.com/eauger/qemu.git
> branch: dbg2-v2-igor-v2-fix
> 
> History:
> v1 -> v2:
> - rebase on top of Igor's series and use acpi_init_table/acpi_table_composed
>   and build_append_int_noprefix()
> 
> Eric Auger (3):
>   tests/acpi: Add void table for virt/DBG2 bios-tables-test
>   bios-tables-test: Generate reference table for virt/DBG2
>   hw/arm/virt_acpi_build: Generate DBG2 table
> 
>  hw/arm/virt-acpi-build.c  |  64 +-
>  tests/data/acpi/virt/DBG2 | Bin 0 -> 87 bytes
>  2 files changed, 63 insertions(+), 1 deletion(-)
>  create mode 100644 tests/data/acpi/virt/DBG2
> 
> -- 
> 2.26.3
> 




Re: [PATCH v6 0/5] hw/arm/virt: Introduce cpu topology support

2021-09-06 Thread Andrew Jones
On Fri, Sep 03, 2021 at 03:38:13PM +0800, wangyanan (Y) wrote:
> 
> On 2021/9/3 15:25, Peter Maydell wrote:
> > On Fri, 3 Sept 2021 at 08:05, wangyanan (Y)  wrote:
> > > 
> > > On 2021/9/2 23:56, Peter Maydell wrote:
> > > > On Tue, 24 Aug 2021 at 13:20, Yanan Wang  wrote:
> > > > > This new version is based on patch series [1] which introduces some
> > > > > fix and improvement for smp parsing.
> > > > > 
> > > > > Description:
> > > > > Once the view of an accurate virtual cpu topology is provided to 
> > > > > guest,
> > > > > with a well-designed vCPU pinning to the pCPU we may get a huge 
> > > > > benefit,
> > > > > e.g., the scheduling performance improvement. See Dario Faggioli's
> > > > > research and the related performance tests in [2] for reference.
> > > > > 
> > > > > This patch series introduces cpu topology support for ARM platform.
> > > > > Both cpu-map in DT and ACPI PPTT table are introduced to store the
> > > > > topology information. And we only describe the topology information
> > > > > to 6.2 and newer virt machines, considering compatibility.
> > > > > 
> > > > > patches not yet reviewed: #1 and #3.
> > > > > 
> > > > > [1] 
> > > > > https://lore.kernel.org/qemu-devel/20210823122804.7692-1-wangyana...@huawei.com/
> > > > > [2] 
> > > > > https://kvmforum2020.sched.com/event/eE1y/virtual-topology-for-virtual-machines
> > > > > -friend-or-foe-dario-faggioli-suse
> > > > Hi; this series doesn't apply to current head-of-git. Is it
> > > > intended to be based on some other series ?
> > > > 
> > > Yes, it was based on the -smp parsing changes in [1] which hasn't been
> > > picked yet. Given that [1] somehow affects the topology parsing results
> > > which we will describe to guest, I think it may be better that [1] can be
> > > merged first and then this series follows.
> > OK. I'll ignore this for now; please resend once that other series
> > has been accepted.
> Got it.

Also, you'll likely want to rebase on Igor's acpi refactor series[*]

[*] https://www.mail-archive.com/qemu-devel@nongnu.org/msg822151.html

Thanks,
drew

> 
> Thanks,
> Yanan
> > thanks
> > -- PMM
> > 
> > .
> 




Re: [PATCH v6 1/3] target-arm: Add support for Fujitsu A64FX

2021-08-31 Thread Andrew Jones
On Tue, Aug 31, 2021 at 05:29:38PM +0900, Shuuichirou Ishii wrote:
> Add a definition for the Fujitsu A64FX processor.
> 
> The A64FX processor does not implement the AArch32 Execution state,
> so there are no associated AArch32 Identification registers.
> 
> For SVE, the A64FX processor supports only 128,256 and 512bit vector lengths.
> 
> The Identification registers value are defined based on the FX700,
> and have been tested and confirmed.
> 
> Signed-off-by: Shuuichirou Ishii 
> ---
>  target/arm/cpu64.c | 48 ++
>  1 file changed, 48 insertions(+)
>

I already gave my r-b on the last posting, but here it is again

Reviewed-by: Andrew Jones 




Re: [PATCH v5 2/3] hw/arm/virt: target-arm: Add A64FX processor support to virt machine

2021-08-30 Thread Andrew Jones
On Mon, Aug 30, 2021 at 05:28:19PM +0900, Shuuichirou Ishii wrote:
> Add -cpu a64fx to use A64FX processor when -machine virt option is specified.
> In addition, add a64fx to the Supported guest CPU types in the virt.rst 
> document.
> 
> Signed-off-by: Shuuichirou Ishii 
> ---
>  docs/system/arm/virt.rst | 1 +
>  hw/arm/virt.c| 1 +
>  2 files changed, 2 insertions(+)
> 
> diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
> index 59acf0eeaf..850787495b 100644
> --- a/docs/system/arm/virt.rst
> +++ b/docs/system/arm/virt.rst
> @@ -55,6 +55,7 @@ Supported guest CPU types:
>  - ``cortex-a53`` (64-bit)
>  - ``cortex-a57`` (64-bit)
>  - ``cortex-a72`` (64-bit)
> +- ``a64fx`` (64-bit)
>  - ``host`` (with KVM only)
>  - ``max`` (same as ``host`` for KVM; best possible emulation with TCG)
>  
> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> index 86c8a4ca3d..3fa4295a78 100644
> --- a/hw/arm/virt.c
> +++ b/hw/arm/virt.c
> @@ -200,6 +200,7 @@ static const char *valid_cpus[] = {
>  ARM_CPU_TYPE_NAME("cortex-a53"),
>  ARM_CPU_TYPE_NAME("cortex-a57"),
>  ARM_CPU_TYPE_NAME("cortex-a72"),
> +ARM_CPU_TYPE_NAME("a64fx"),
>  ARM_CPU_TYPE_NAME("host"),
>  ARM_CPU_TYPE_NAME("max"),
>  };
> -- 
> 2.27.0
>

Reviewed-by: Andrew Jones 




Re: [PATCH v5 3/3] tests/arm-cpu-features: Add A64FX processor related

2021-08-30 Thread Andrew Jones
On Mon, Aug 30, 2021 at 05:28:20PM +0900, Shuuichirou Ishii wrote:

nit: A commit message would be nice, even if it's just a simple
sentence expanding on the summary.

> Signed-off-by: Shuuichirou Ishii 
> ---
>  tests/qtest/arm-cpu-features.c | 13 +
>  1 file changed, 13 insertions(+)
> 
> diff --git a/tests/qtest/arm-cpu-features.c b/tests/qtest/arm-cpu-features.c
> index 8252b85bb8..90a87f0ea9 100644
> --- a/tests/qtest/arm-cpu-features.c
> +++ b/tests/qtest/arm-cpu-features.c
> @@ -473,6 +473,19 @@ static void test_query_cpu_model_expansion(const void 
> *data)
>  assert_has_feature_enabled(qts, "cortex-a57", "pmu");
>  assert_has_feature_enabled(qts, "cortex-a57", "aarch64");
>  
> +assert_has_feature_enabled(qts, "a64fx", "pmu");
> +assert_has_feature_enabled(qts, "a64fx", "aarch64");
> +/*
> + * A64FX does not support any other vector lengths besides those
> + * that are enabled by default(128bit, 256bits, 512bit).
> + */
> +assert_has_feature_enabled(qts, "a64fx", "sve");
> +assert_sve_vls(qts, "a64fx", 0xb, NULL);
> +assert_error(qts, "a64fx", "cannot enable sve384",
> + "{ 'sve384': true }");
> +assert_error(qts, "a64fx", "cannot enable sve640",
> + "{ 'sve640': true }");
> +
>  sve_tests_default(qts, "max");
>  pauth_tests_default(qts, "max");
>  
> -- 
> 2.27.0
>

Reviewed-by: Andrew Jones 




Re: [PATCH v5 1/3] target-arm: Add support for Fujitsu A64FX

2021-08-30 Thread Andrew Jones
On Mon, Aug 30, 2021 at 05:28:18PM +0900, Shuuichirou Ishii wrote:
> Add a definition for the Fujitsu A64FX processor.
> 
> The A64FX processor does not implement the AArch32 Execution state,
> so there are no associated AArch32 Identification registers.
> 
> For SVE, the A64FX processor supports only 128,256 and 512bit vector lengths.
> 
> Signed-off-by: Shuuichirou Ishii 
> ---
>  target/arm/cpu64.c | 48 ++
>  1 file changed, 48 insertions(+)
> 
> diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
> index 2f0cbddab5..15245a60a8 100644
> --- a/target/arm/cpu64.c
> +++ b/target/arm/cpu64.c
> @@ -841,10 +841,58 @@ static void aarch64_max_initfn(Object *obj)
>  cpu_max_set_sve_max_vq, NULL, NULL);
>  }
>  
> +static void aarch64_a64fx_initfn(Object *obj)
> +{
> +ARMCPU *cpu = ARM_CPU(obj);
> +
> +cpu->dtb_compatible = "arm,a64fx";
> +set_feature(>env, ARM_FEATURE_V8);
> +set_feature(>env, ARM_FEATURE_NEON);
> +set_feature(>env, ARM_FEATURE_GENERIC_TIMER);
> +set_feature(>env, ARM_FEATURE_AARCH64);
> +set_feature(>env, ARM_FEATURE_EL2);
> +set_feature(>env, ARM_FEATURE_EL3);
> +set_feature(>env, ARM_FEATURE_PMU);
> +cpu->midr = 0x461f0010;
> +cpu->revidr = 0x;
> +cpu->ctr = 0x86668006;
> +cpu->reset_sctlr = 0x3180;
> +cpu->isar.id_aa64pfr0 =   0x00010111; /* No RAS Extensions */
> +cpu->isar.id_aa64pfr1 = 0x;
> +cpu->isar.id_aa64dfr0 = 0x10305408;
> +cpu->isar.id_aa64dfr1 = 0x;
> +cpu->id_aa64afr0 = 0x;
> +cpu->id_aa64afr1 = 0x;
> +cpu->isar.id_aa64mmfr0 = 0x1122;
> +cpu->isar.id_aa64mmfr1 = 0x11212100;
> +cpu->isar.id_aa64mmfr2 = 0x1011;
> +cpu->isar.id_aa64isar0 = 0x10211120;
> +cpu->isar.id_aa64isar1 = 0x00010001;
> +cpu->isar.id_aa64zfr0 = 0x;
> +cpu->clidr = 0x8023;
> +cpu->ccsidr[0] = 0x7007e01c; /* 64KB L1 dcache */
> +cpu->ccsidr[1] = 0x2007e01c; /* 64KB L1 icache */
> +cpu->ccsidr[2] = 0x70ffe07c; /* 8MB L2 cache */
> +cpu->dcz_blocksize = 6; /* 256 bytes */
> +cpu->gic_num_lrs = 4;
> +cpu->gic_vpribits = 5;
> +cpu->gic_vprebits = 5;
> +
> +/* Suppport of A64FX's vector length are 128,256 and 512bit only */
> +aarch64_add_sve_properties(obj);
> +bitmap_zero(cpu->sve_vq_supported, ARM_MAX_VQ);
> +set_bit(0, cpu->sve_vq_supported); /* 128bit */
> +set_bit(1, cpu->sve_vq_supported); /* 256bit */
> +set_bit(3, cpu->sve_vq_supported); /* 512bit */
> +
> +/* TODO:  Add A64FX specific HPC extension registers */
> +}
> +
>  static const ARMCPUInfo aarch64_cpus[] = {
>  { .name = "cortex-a57", .initfn = aarch64_a57_initfn },
>  { .name = "cortex-a53", .initfn = aarch64_a53_initfn },
>  { .name = "cortex-a72", .initfn = aarch64_a72_initfn },
> +{ .name = "a64fx",  .initfn = aarch64_a64fx_initfn },
>  { .name = "max",.initfn = aarch64_max_initfn },
>  };
>  
> -- 
> 2.27.0
>

For the SVE stuff,

Reviewed-by: Andrew Jones 

Question: For testing, did you dump all the ID registers on this
model and compare them with a dump of ID registers from real
hardware? If so, that would be good info to put in the commit
message or at least the cover letter.

Thanks,
drew




Re: [PATCH v2 0/4] target/arm/cpu: Introduce sve_vq_supported bitmap

2021-08-27 Thread Andrew Jones
pu->sve_vq_init, max_vq);
> bitmap_or(cpu->sve_vq_map, cpu->sve_vq_map, tmp, max_vq);
> 
> As a result, enter a routine where the following process will be executed.
> 
> error_setg(errp, "cannot set sve-max-vq=%d", cpu->sve_max_vq);

This is the correct behavior and the rest of the error message explains
why

 error_append_hint(errp, "This CPU does not support "
   "the vector length %d-bits.\n", vq * 128);

In A64FX's case that will point out the vector length 384-bits, which
indeed A64FX does not support.

As I've stated a few different times, the sve-max-vq property is of
marginal use, as it only works for CPU models that support all vector
lengths, including non-power-of-2 lengths. This is because the property
says to enable all vector lengths smaller and including sve-max-vq and to
disable all the rest, but if the CPU doesn't support non-power-of-2 vector
lengths, then sve-max-vq will not work for anything other than max-vq=1
and max-vq=2. For this reason, I didn't even bring this property over to
the 'host' cpu type. I think I once suggested that you don't bring it over
to A64FX either and I'll suggest that again.

> 
> Therefore, We have applied the following fix, is this ok?

No :-)

Thanks,
drew

> 
> --- a/target/arm/cpu.c
> +++ b/target/arm/cpu.c
> @@ -1350,10 +1350,12 @@ void arm_cpu_finalize_features(ARMCPU *cpu, Error 
> **errp)
>  Error *local_err = NULL;
> 
>  if (arm_feature(>env, ARM_FEATURE_AARCH64)) {
> -arm_cpu_sve_finalize(cpu, _err);
> -if (local_err != NULL) {
> -error_propagate(errp, local_err);
> -return;
> +if (!arm_feature(>env, ARM_FEATURE_A64FX)) {
> +arm_cpu_sve_finalize(cpu, _err);
> +if (local_err != NULL) {
> +error_propagate(errp, local_err);
> +return;
> +}
>  }
> ----
> 
> Please your comments if we have misunderstood.
> Best regards.
> 
> > -Original Message-
> > From: Andrew Jones 
> > Sent: Tuesday, August 24, 2021 1:07 AM
> > To: qemu-devel@nongnu.org; qemu-...@nongnu.org
> > Cc: Ishii, Shuuichirou/石井 周一郎 ;
> > richard.hender...@linaro.org; peter.mayd...@linaro.org; phi...@redhat.com
> > Subject: [PATCH v2 0/4] target/arm/cpu: Introduce sve_vq_supported bitmap
> > 
> > v2:
> >  - Completed testing
> >  - Removed extra space in an error message
> >  - Added Phil's r-b's
> > 
> > While reviewing the new A64FX CPU type it became clear that CPU types should
> > be able to specify which SVE vector lengths are supported. This series adds 
> > a new
> > bitmap member to ARMCPU and modifies arm_cpu_sve_finalize() to validate
> > inputs against it.
> > So far we only need to set the bitmap for the 'max' CPU type though and, 
> > since it
> > supports all vector lengths, we just fill the whole thing.
> > 
> > This series was inspired by Richard Henderson's suggestion to replace
> > arm_cpu_sve_finalize's kvm_supported bitmap with something that could be
> > shared with TCG.
> > 
> > Thanks,
> > drew
> > 
> > 
> > Andrew Jones (4):
> >   target/arm/cpu: Introduce sve_vq_supported bitmap
> >   target/arm/kvm64: Ensure sve vls map is completely clear
> >   target/arm/cpu64: Replace kvm_supported with sve_vq_supported
> >   target/arm/cpu64: Validate sve vector lengths are supported
> > 
> >  target/arm/cpu.h   |   4 ++
> >  target/arm/cpu64.c | 118
> > +
> >  target/arm/kvm64.c |   2 +-
> >  3 files changed, 61 insertions(+), 63 deletions(-)
> > 
> > --
> > 2.31.1
> 




Re: [PATCH v6 1/5] hw/arm/virt: Only describe cpu topology since virt-6.2

2021-08-24 Thread Andrew Jones
On Tue, Aug 24, 2021 at 08:20:12PM +0800, Yanan Wang wrote:
> On existing older machine types, without cpu topology described
> in ACPI or DT, the guest will populate one by default. With the
> topology described, it will read the information and set up its
> topology as instructed, but that may not be the same as what was
> getting used by default. It's possible that an user application
> has a dependency on the default topology and if the default one
> gets changed it will probably behave differently.
> 
> Based on above consideration we'd better only describe topology
> information to the guest on 6.2 and later machine types.
> 
> Signed-off-by: Yanan Wang 
> ---
>  hw/arm/virt.c | 3 +++
>  include/hw/arm/virt.h | 4 +++-
>  2 files changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> index ae029680da..82f2eba6bd 100644
> --- a/hw/arm/virt.c
> +++ b/hw/arm/virt.c
> @@ -2795,9 +2795,12 @@ DEFINE_VIRT_MACHINE_AS_LATEST(6, 2)
>  
>  static void virt_machine_6_1_options(MachineClass *mc)
>  {
> +VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
> +
>  virt_machine_6_2_options(mc);
>  compat_props_add(mc->compat_props, hw_compat_6_1, hw_compat_6_1_len);
>  mc->smp_props.prefer_sockets = true;
> +vmc->no_cpu_topology = true;
>  }
>  DEFINE_VIRT_MACHINE(6, 1)
>  
> diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
> index 9661c46699..6ab21ea90e 100644
> --- a/include/hw/arm/virt.h
> +++ b/include/hw/arm/virt.h
> @@ -124,11 +124,13 @@ struct VirtMachineClass {
>  bool claim_edge_triggered_timers;
>  bool smbios_old_sys_ver;
>  bool no_highmem_ecam;
> -bool no_ged;   /* Machines < 4.2 has no support for ACPI GED device */
> +bool no_ged;   /* Machines < 4.2 have no support for ACPI GED device */
>  bool kvm_no_adjvtime;
>  bool no_kvm_steal_time;
>  bool acpi_expose_flash;
>  bool no_secure_gpio;
> +/* Machines < 6.2 have no support for describing cpu topology to guest */
> +bool no_cpu_topology;
>  };
>  
>  struct VirtMachineState {
> -- 
> 2.19.1
>

Reviewed-by: Andrew Jones 




Re: [PATCH v2 3/4] target/arm/cpu64: Replace kvm_supported with sve_vq_supported

2021-08-24 Thread Andrew Jones
On Tue, Aug 24, 2021 at 08:28:55AM +0200, Andrew Jones wrote:
> On Mon, Aug 23, 2021 at 10:53:48AM -0700, Richard Henderson wrote:
> > On 8/23/21 9:06 AM, Andrew Jones wrote:
> > > Now that we have an ARMCPU member sve_vq_supported we no longer
> > > need the local kvm_supported bitmap for KVM's supported vector
> > > lengths.
> > > 
> > > Signed-off-by: Andrew Jones 
> > > Reviewed-by: Philippe Mathieu-Daudé 
> > > ---
> > >   target/arm/cpu64.c | 19 +++
> > >   1 file changed, 11 insertions(+), 8 deletions(-)
> > > 
> > > diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
> > > index eb9318c83b74..557fd4757740 100644
> > > --- a/target/arm/cpu64.c
> > > +++ b/target/arm/cpu64.c
> > > @@ -265,14 +265,17 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
> > >* any of the above.  Finally, if SVE is not disabled, then at 
> > > least one
> > >* vector length must be enabled.
> > >*/
> > > -DECLARE_BITMAP(kvm_supported, ARM_MAX_VQ);
> > >   DECLARE_BITMAP(tmp, ARM_MAX_VQ);
> > >   uint32_t vq, max_vq = 0;
> > > -/* Collect the set of vector lengths supported by KVM. */
> > > -bitmap_zero(kvm_supported, ARM_MAX_VQ);
> > > +/*
> > > + * CPU models specify a set of supported vector lengths which are
> > > + * enabled by default.  Attempting to enable any vector length not 
> > > set
> > > + * in the supported bitmap results in an error.  When KVM is enabled 
> > > we
> > > + * fetch the supported bitmap from the host.
> > > + */
> > >   if (kvm_enabled() && kvm_arm_sve_supported()) {
> > > -kvm_arm_sve_get_vls(CPU(cpu), kvm_supported);
> > > +kvm_arm_sve_get_vls(CPU(cpu), cpu->sve_vq_supported);
> > >   } else if (kvm_enabled()) {
> > >   assert(!cpu_isar_feature(aa64_sve, cpu));
> > >   }
> > 
> > I think this whole stanza should now be moved into
> > kvm_arm_get_host_cpu_features, where we detect sve and fetch
> > ID_AA64ZFR0_EL1.
> > 
> > As a separate patch, since this one is simply the variable rename.
> 
> Good idea. I'll do that for v3.

Actually, I'll post an independent series for this idea rather than
a v3 with another patch. With enough changes we can avoid several
scratch vcpus, but that's getting too far outside the scope of this
series.

Thanks,
drew




Re: [PATCH v2 3/4] target/arm/cpu64: Replace kvm_supported with sve_vq_supported

2021-08-24 Thread Andrew Jones
On Mon, Aug 23, 2021 at 10:53:48AM -0700, Richard Henderson wrote:
> On 8/23/21 9:06 AM, Andrew Jones wrote:
> > Now that we have an ARMCPU member sve_vq_supported we no longer
> > need the local kvm_supported bitmap for KVM's supported vector
> > lengths.
> > 
> > Signed-off-by: Andrew Jones 
> > Reviewed-by: Philippe Mathieu-Daudé 
> > ---
> >   target/arm/cpu64.c | 19 +++
> >   1 file changed, 11 insertions(+), 8 deletions(-)
> > 
> > diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
> > index eb9318c83b74..557fd4757740 100644
> > --- a/target/arm/cpu64.c
> > +++ b/target/arm/cpu64.c
> > @@ -265,14 +265,17 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
> >* any of the above.  Finally, if SVE is not disabled, then at least 
> > one
> >* vector length must be enabled.
> >*/
> > -DECLARE_BITMAP(kvm_supported, ARM_MAX_VQ);
> >   DECLARE_BITMAP(tmp, ARM_MAX_VQ);
> >   uint32_t vq, max_vq = 0;
> > -/* Collect the set of vector lengths supported by KVM. */
> > -bitmap_zero(kvm_supported, ARM_MAX_VQ);
> > +/*
> > + * CPU models specify a set of supported vector lengths which are
> > + * enabled by default.  Attempting to enable any vector length not set
> > + * in the supported bitmap results in an error.  When KVM is enabled we
> > + * fetch the supported bitmap from the host.
> > + */
> >   if (kvm_enabled() && kvm_arm_sve_supported()) {
> > -kvm_arm_sve_get_vls(CPU(cpu), kvm_supported);
> > +kvm_arm_sve_get_vls(CPU(cpu), cpu->sve_vq_supported);
> >   } else if (kvm_enabled()) {
> >   assert(!cpu_isar_feature(aa64_sve, cpu));
> >   }
> 
> I think this whole stanza should now be moved into
> kvm_arm_get_host_cpu_features, where we detect sve and fetch
> ID_AA64ZFR0_EL1.
> 
> As a separate patch, since this one is simply the variable rename.

Good idea. I'll do that for v3.

> 
> Reviewed-by: Richard Henderson 
>

Thanks,
drew 




Re: [PATCH v2 4/4] target/arm/cpu64: Validate sve vector lengths are supported

2021-08-24 Thread Andrew Jones
On Mon, Aug 23, 2021 at 11:04:49AM -0700, Richard Henderson wrote:
> On 8/23/21 9:06 AM, Andrew Jones wrote:
> > Future CPU types may specify which vector lengths are supported.
> > We can apply nearly the same logic to validate those lengths
> > as we do for KVM's supported vector lengths. We merge the code
> > where we can, but unfortunately can't completely merge it because
> > KVM requires all vector lengths, power-of-two or not, smaller than
> > the maximum enabled length to also be enabled. The architecture
> > only requires all the power-of-two lengths, though, so TCG will
> > only enforce that.
> > 
> > Signed-off-by: Andrew Jones 
> > ---
> >   target/arm/cpu64.c | 101 -
> >   1 file changed, 45 insertions(+), 56 deletions(-)
> 
> 
> Reviewed-by: Richard Henderson 
> 
> > +} else {
> > +if (kvm_enabled()) {
> 
> Nit: better as
> 
> } else if (...) {
> 
> if I'm reading all of the diff context correctly.
>

Yeah, the diff is definitely not easy to read, or even the code
after its applied for that matter... We can't use 'else if' here
because the 'else { if' is part of a pattern like below

  if (...) {
 if (...) {

 } else {

 }
  } else {
 if (kvm_enabled()) {

 } else {

 }
  }

Thanks,
drew




[PATCH v2 4/4] target/arm/cpu64: Validate sve vector lengths are supported

2021-08-23 Thread Andrew Jones
Future CPU types may specify which vector lengths are supported.
We can apply nearly the same logic to validate those lengths
as we do for KVM's supported vector lengths. We merge the code
where we can, but unfortunately can't completely merge it because
KVM requires all vector lengths, power-of-two or not, smaller than
the maximum enabled length to also be enabled. The architecture
only requires all the power-of-two lengths, though, so TCG will
only enforce that.

Signed-off-by: Andrew Jones 
---
 target/arm/cpu64.c | 101 -
 1 file changed, 45 insertions(+), 56 deletions(-)

diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 557fd4757740..2f0cbddab568 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -329,35 +329,26 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
 break;
 }
 }
-max_vq = vq <= ARM_MAX_VQ ? vq - 1 : ARM_MAX_VQ;
-bitmap_andnot(cpu->sve_vq_map, cpu->sve_vq_supported,
-  cpu->sve_vq_init, max_vq);
-if (max_vq == 0 || bitmap_empty(cpu->sve_vq_map, max_vq)) {
-error_setg(errp, "cannot disable sve%d", vq * 128);
-error_append_hint(errp, "Disabling sve%d results in all "
-  "vector lengths being disabled.\n",
-  vq * 128);
-error_append_hint(errp, "With SVE enabled, at least one "
-  "vector length must be enabled.\n");
-return;
-}
 } else {
 /* Disabling a power-of-two disables all larger lengths. */
-if (test_bit(0, cpu->sve_vq_init)) {
-error_setg(errp, "cannot disable sve128");
-error_append_hint(errp, "Disabling sve128 results in all "
-  "vector lengths being disabled.\n");
-error_append_hint(errp, "With SVE enabled, at least one "
-  "vector length must be enabled.\n");
-return;
-}
-for (vq = 2; vq <= ARM_MAX_VQ; vq <<= 1) {
+for (vq = 1; vq <= ARM_MAX_VQ; vq <<= 1) {
 if (test_bit(vq - 1, cpu->sve_vq_init)) {
 break;
 }
 }
-max_vq = vq <= ARM_MAX_VQ ? vq - 1 : ARM_MAX_VQ;
-bitmap_complement(cpu->sve_vq_map, cpu->sve_vq_init, max_vq);
+}
+
+max_vq = vq <= ARM_MAX_VQ ? vq - 1 : ARM_MAX_VQ;
+bitmap_andnot(cpu->sve_vq_map, cpu->sve_vq_supported,
+  cpu->sve_vq_init, max_vq);
+if (max_vq == 0 || bitmap_empty(cpu->sve_vq_map, max_vq)) {
+error_setg(errp, "cannot disable sve%d", vq * 128);
+error_append_hint(errp, "Disabling sve%d results in all "
+  "vector lengths being disabled.\n",
+  vq * 128);
+error_append_hint(errp, "With SVE enabled, at least one "
+  "vector length must be enabled.\n");
+return;
 }
 
 max_vq = find_last_bit(cpu->sve_vq_map, max_vq) + 1;
@@ -393,46 +384,44 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
 assert(max_vq != 0);
 bitmap_clear(cpu->sve_vq_map, max_vq, ARM_MAX_VQ - max_vq);
 
-if (kvm_enabled()) {
-/* Ensure the set of lengths matches what KVM supports. */
-bitmap_xor(tmp, cpu->sve_vq_map, cpu->sve_vq_supported, max_vq);
-if (!bitmap_empty(tmp, max_vq)) {
-vq = find_last_bit(tmp, max_vq) + 1;
-if (test_bit(vq - 1, cpu->sve_vq_map)) {
-if (cpu->sve_max_vq) {
-error_setg(errp, "cannot set sve-max-vq=%d",
-   cpu->sve_max_vq);
-error_append_hint(errp, "This KVM host does not support "
-  "the vector length %d-bits.\n",
-  vq * 128);
-error_append_hint(errp, "It may not be possible to use "
-  "sve-max-vq with this KVM host. Try "
-  "using only sve properties.\n");
-} else {
-error_setg(errp, "cannot enable sve%d", vq * 128);
-error_append_hint(errp, "This KVM host does not support "
-  "the vector length %d-bits.\n",
-  vq * 128);
-}
+/* Ensure the set of lengths matche

[PATCH v2 2/4] target/arm/kvm64: Ensure sve vls map is completely clear

2021-08-23 Thread Andrew Jones
bitmap_clear() only clears the given range. While the given
range should be sufficient in this case we might as well be
100% sure all bits are zeroed by using bitmap_zero().

Signed-off-by: Andrew Jones 
Reviewed-by: Philippe Mathieu-Daudé 
---
 target/arm/kvm64.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
index 59982d470d37..e790d6c9a573 100644
--- a/target/arm/kvm64.c
+++ b/target/arm/kvm64.c
@@ -740,7 +740,7 @@ void kvm_arm_sve_get_vls(CPUState *cs, unsigned long *map)
 uint32_t vq = 0;
 int i, j;
 
-bitmap_clear(map, 0, ARM_MAX_VQ);
+bitmap_zero(map, ARM_MAX_VQ);
 
 /*
  * KVM ensures all host CPUs support the same set of vector lengths.
-- 
2.31.1




[PATCH v2 3/4] target/arm/cpu64: Replace kvm_supported with sve_vq_supported

2021-08-23 Thread Andrew Jones
Now that we have an ARMCPU member sve_vq_supported we no longer
need the local kvm_supported bitmap for KVM's supported vector
lengths.

Signed-off-by: Andrew Jones 
Reviewed-by: Philippe Mathieu-Daudé 
---
 target/arm/cpu64.c | 19 +++
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index eb9318c83b74..557fd4757740 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -265,14 +265,17 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
  * any of the above.  Finally, if SVE is not disabled, then at least one
  * vector length must be enabled.
  */
-DECLARE_BITMAP(kvm_supported, ARM_MAX_VQ);
 DECLARE_BITMAP(tmp, ARM_MAX_VQ);
 uint32_t vq, max_vq = 0;
 
-/* Collect the set of vector lengths supported by KVM. */
-bitmap_zero(kvm_supported, ARM_MAX_VQ);
+/*
+ * CPU models specify a set of supported vector lengths which are
+ * enabled by default.  Attempting to enable any vector length not set
+ * in the supported bitmap results in an error.  When KVM is enabled we
+ * fetch the supported bitmap from the host.
+ */
 if (kvm_enabled() && kvm_arm_sve_supported()) {
-kvm_arm_sve_get_vls(CPU(cpu), kvm_supported);
+kvm_arm_sve_get_vls(CPU(cpu), cpu->sve_vq_supported);
 } else if (kvm_enabled()) {
 assert(!cpu_isar_feature(aa64_sve, cpu));
 }
@@ -299,7 +302,7 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
  * For KVM we have to automatically enable all supported 
unitialized
  * lengths, even when the smaller lengths are not all 
powers-of-two.
  */
-bitmap_andnot(tmp, kvm_supported, cpu->sve_vq_init, max_vq);
+bitmap_andnot(tmp, cpu->sve_vq_supported, cpu->sve_vq_init, 
max_vq);
 bitmap_or(cpu->sve_vq_map, cpu->sve_vq_map, tmp, max_vq);
 } else {
 /* Propagate enabled bits down through required powers-of-two. */
@@ -322,12 +325,12 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
 /* Disabling a supported length disables all larger lengths. */
 for (vq = 1; vq <= ARM_MAX_VQ; ++vq) {
 if (test_bit(vq - 1, cpu->sve_vq_init) &&
-test_bit(vq - 1, kvm_supported)) {
+test_bit(vq - 1, cpu->sve_vq_supported)) {
 break;
 }
 }
 max_vq = vq <= ARM_MAX_VQ ? vq - 1 : ARM_MAX_VQ;
-bitmap_andnot(cpu->sve_vq_map, kvm_supported,
+bitmap_andnot(cpu->sve_vq_map, cpu->sve_vq_supported,
   cpu->sve_vq_init, max_vq);
 if (max_vq == 0 || bitmap_empty(cpu->sve_vq_map, max_vq)) {
 error_setg(errp, "cannot disable sve%d", vq * 128);
@@ -392,7 +395,7 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
 
 if (kvm_enabled()) {
 /* Ensure the set of lengths matches what KVM supports. */
-bitmap_xor(tmp, cpu->sve_vq_map, kvm_supported, max_vq);
+bitmap_xor(tmp, cpu->sve_vq_map, cpu->sve_vq_supported, max_vq);
 if (!bitmap_empty(tmp, max_vq)) {
 vq = find_last_bit(tmp, max_vq) + 1;
 if (test_bit(vq - 1, cpu->sve_vq_map)) {
-- 
2.31.1




[PATCH v2 0/4] target/arm/cpu: Introduce sve_vq_supported bitmap

2021-08-23 Thread Andrew Jones
v2:
 - Completed testing
 - Removed extra space in an error message
 - Added Phil's r-b's

While reviewing the new A64FX CPU type it became clear that CPU
types should be able to specify which SVE vector lengths are
supported. This series adds a new bitmap member to ARMCPU and
modifies arm_cpu_sve_finalize() to validate inputs against it.
So far we only need to set the bitmap for the 'max' CPU type
though and, since it supports all vector lengths, we just fill
the whole thing.

This series was inspired by Richard Henderson's suggestion to
replace arm_cpu_sve_finalize's kvm_supported bitmap with something
that could be shared with TCG.

Thanks,
drew


Andrew Jones (4):
  target/arm/cpu: Introduce sve_vq_supported bitmap
  target/arm/kvm64: Ensure sve vls map is completely clear
  target/arm/cpu64: Replace kvm_supported with sve_vq_supported
  target/arm/cpu64: Validate sve vector lengths are supported

 target/arm/cpu.h   |   4 ++
 target/arm/cpu64.c | 118 +
 target/arm/kvm64.c |   2 +-
 3 files changed, 61 insertions(+), 63 deletions(-)

-- 
2.31.1




[PATCH v2 1/4] target/arm/cpu: Introduce sve_vq_supported bitmap

2021-08-23 Thread Andrew Jones
Allow CPUs that support SVE to specify which SVE vector lengths they
support by setting them in this bitmap. Currently only the 'max' and
'host' CPU types supports SVE and 'host' requires KVM which obtains
its supported bitmap from the host. So, we only need to initialize the
bitmap for 'max' with TCG. And, since 'max' should support all SVE
vector lengths we simply fill the bitmap. Future CPU types may have
less trivial maps though.

Signed-off-by: Andrew Jones 
Reviewed-by: Philippe Mathieu-Daudé 
---
 target/arm/cpu.h   | 4 
 target/arm/cpu64.c | 2 ++
 2 files changed, 6 insertions(+)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 9f0a5f84d503..cc645b57421f 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1019,9 +1019,13 @@ struct ARMCPU {
  * While processing properties during initialization, corresponding
  * sve_vq_init bits are set for bits in sve_vq_map that have been
  * set by properties.
+ *
+ * Bits set in sve_vq_supported represent valid vector lengths for
+ * the CPU type.
  */
 DECLARE_BITMAP(sve_vq_map, ARM_MAX_VQ);
 DECLARE_BITMAP(sve_vq_init, ARM_MAX_VQ);
+DECLARE_BITMAP(sve_vq_supported, ARM_MAX_VQ);
 
 /* Generic timer counter frequency, in Hz */
 uint64_t gt_cntfrq_hz;
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index c690318a9b63..eb9318c83b74 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -840,6 +840,8 @@ static void aarch64_max_initfn(Object *obj)
 /* Default to PAUTH on, with the architected algorithm. */
 qdev_property_add_static(DEVICE(obj), _cpu_pauth_property);
 qdev_property_add_static(DEVICE(obj), _cpu_pauth_impdef_property);
+
+bitmap_fill(cpu->sve_vq_supported, ARM_MAX_VQ);
 }
 
 aarch64_add_sve_properties(obj);
-- 
2.31.1




Re: [PATCH 0/4] target/arm/cpu: Introduce sve_vq_supported bitmap

2021-08-23 Thread Andrew Jones
On Thu, Aug 19, 2021 at 09:37:54PM +0200, Andrew Jones wrote:
> While reviewing the new A64FX CPU type it became clear that CPU
> types should be able to specify which SVE vector lengths are
> supported. This series adds a new bitmap member to ARMCPU and
> modifies arm_cpu_sve_finalize() to validate inputs against it.
> So far we only need to set the bitmap for the 'max' CPU type
> though and, since it supports all vector lengths, we just fill
> the whole thing.
> 
> This series was inspired by Richard Henderson's suggestion to
> replace arm_cpu_sve_finalize's kvm_supported bitmap with something
> that could be shared with TCG.
> 
> So far I've only lightly tested this. I'll do more testing and
> report back later. I'd also be happy to get test results from
> others.

I did more testing and it looks good to me except for the extra
space in an error message that I reported in patch 4.

Thanks,
drew

> 
> Thanks,
> drew
> 
> Andrew Jones (4):
>   target/arm/cpu: Introduce sve_vq_supported bitmap
>   target/arm/kvm64: Ensure sve vls map is completely clear
>   target/arm/cpu64: Replace kvm_supported with sve_vq_supported
>   target/arm/cpu64: Validate sve vector lengths are supported
> 
>  target/arm/cpu.h   |   4 ++
>  target/arm/cpu64.c | 118 +
>  target/arm/kvm64.c |   2 +-
>  3 files changed, 61 insertions(+), 63 deletions(-)
> 
> -- 
> 2.31.1
> 




Re: [PATCH 4/4] target/arm/cpu64: Validate sve vector lengths are supported

2021-08-23 Thread Andrew Jones
On Thu, Aug 19, 2021 at 09:37:58PM +0200, Andrew Jones wrote:
> Future CPU types may specify which vector lengths are supported.
> We can apply nearly the same logic to validate those lengths
> as we do for KVM's supported vector lengths. We merge the code
> where we can, but unfortunately can't completely merge it because
> KVM requires all vector lengths, power-of-two or not, smaller than
> the maximum enabled length to also be enabled. The architecture
> only requires all the power-of-two lengths, though, so TCG will
> only enforce that.
> 
> Signed-off-by: Andrew Jones 
> ---
>  target/arm/cpu64.c | 101 -
>  1 file changed, 45 insertions(+), 56 deletions(-)
> 
> diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
> index 557fd4757740..9cb41c442600 100644
> --- a/target/arm/cpu64.c
> +++ b/target/arm/cpu64.c
> @@ -329,35 +329,26 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
>  break;
>  }
>  }
> -max_vq = vq <= ARM_MAX_VQ ? vq - 1 : ARM_MAX_VQ;
> -bitmap_andnot(cpu->sve_vq_map, cpu->sve_vq_supported,
> -  cpu->sve_vq_init, max_vq);
> -if (max_vq == 0 || bitmap_empty(cpu->sve_vq_map, max_vq)) {
> -error_setg(errp, "cannot disable sve%d", vq * 128);
> -error_append_hint(errp, "Disabling sve%d results in all "
> -  "vector lengths being disabled.\n",
> -  vq * 128);
> -error_append_hint(errp, "With SVE enabled, at least one "
> -  "vector length must be enabled.\n");
> -return;
> -}
>  } else {
>  /* Disabling a power-of-two disables all larger lengths. */
> -if (test_bit(0, cpu->sve_vq_init)) {
> -error_setg(errp, "cannot disable sve128");
> -error_append_hint(errp, "Disabling sve128 results in all "
> -  "vector lengths being disabled.\n");
> -error_append_hint(errp, "With SVE enabled, at least one "
> -  "vector length must be enabled.\n");
> -return;
> -}
> -for (vq = 2; vq <= ARM_MAX_VQ; vq <<= 1) {
> +for (vq = 1; vq <= ARM_MAX_VQ; vq <<= 1) {
>  if (test_bit(vq - 1, cpu->sve_vq_init)) {
>  break;
>  }
>  }
> -max_vq = vq <= ARM_MAX_VQ ? vq - 1 : ARM_MAX_VQ;
> -bitmap_complement(cpu->sve_vq_map, cpu->sve_vq_init, max_vq);
> +}
> +
> +max_vq = vq <= ARM_MAX_VQ ? vq - 1 : ARM_MAX_VQ;
> +bitmap_andnot(cpu->sve_vq_map, cpu->sve_vq_supported,
> +  cpu->sve_vq_init, max_vq);
> +if (max_vq == 0 || bitmap_empty(cpu->sve_vq_map, max_vq)) {
> +error_setg(errp, "cannot disable sve%d", vq * 128);
> +error_append_hint(errp, "Disabling sve%d results in all "
> +  "vector lengths being disabled.\n",
> +  vq * 128);
> +error_append_hint(errp, "With SVE enabled, at least one "
> +  "vector length must be enabled.\n");
> +return;
>  }
>  
>  max_vq = find_last_bit(cpu->sve_vq_map, max_vq) + 1;
> @@ -393,46 +384,44 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
>  assert(max_vq != 0);
>  bitmap_clear(cpu->sve_vq_map, max_vq, ARM_MAX_VQ - max_vq);
>  
> -if (kvm_enabled()) {
> -/* Ensure the set of lengths matches what KVM supports. */
> -bitmap_xor(tmp, cpu->sve_vq_map, cpu->sve_vq_supported, max_vq);
> -if (!bitmap_empty(tmp, max_vq)) {
> -vq = find_last_bit(tmp, max_vq) + 1;
> -if (test_bit(vq - 1, cpu->sve_vq_map)) {
> -if (cpu->sve_max_vq) {
> -error_setg(errp, "cannot set sve-max-vq=%d",
> -   cpu->sve_max_vq);
> -error_append_hint(errp, "This KVM host does not support "
> -  "the vector length %d-bits.\n",
> -  vq * 128);
> -error_append_hint(errp, "It may not be possible to use "
> -  "sve-max-vq w

Re: [PATCH 1/3] hw/arm/virt: KVM: Probe for KVM_CAP_ARM_VM_IPA_SIZE when creating scratch VM

2021-08-23 Thread Andrew Jones
On Sun, Aug 22, 2021 at 03:44:39PM +0100, Marc Zyngier wrote:
> Although we probe for the IPA limits imposed by KVM (and the hardware)
> when computing the memory map, we still use the old style '0' when
> creating a scratch VM in kvm_arm_create_scratch_host_vcpu().
> 
> On systems that are severely IPA challenged (such as the Apple M1),
> this results in a failure as KVM cannot use the default 40bit that
> '0' represents.
> 
> Instead, probe for the extension and use the reported IPA limit
> if available.
> 
> Cc: Andrew Jones 
> Cc: Eric Auger 
> Cc: Peter Maydell 
> Signed-off-by: Marc Zyngier 
> ---
>  target/arm/kvm.c | 7 ++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
> index d8381ba224..cc3371a99b 100644
> --- a/target/arm/kvm.c
> +++ b/target/arm/kvm.c
> @@ -70,12 +70,17 @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t 
> *cpus_to_try,
>struct kvm_vcpu_init *init)
>  {
>  int ret = 0, kvmfd = -1, vmfd = -1, cpufd = -1;
> +int max_vm_pa_size;
>  
>  kvmfd = qemu_open_old("/dev/kvm", O_RDWR);
>  if (kvmfd < 0) {
>  goto err;
>  }
> -vmfd = ioctl(kvmfd, KVM_CREATE_VM, 0);
> +max_vm_pa_size = ioctl(kvmfd, KVM_CHECK_EXTENSION, 
> KVM_CAP_ARM_VM_IPA_SIZE);
> +if (max_vm_pa_size < 0) {
> +max_vm_pa_size = 0;
> +}
> +    vmfd = ioctl(kvmfd, KVM_CREATE_VM, max_vm_pa_size);
>  if (vmfd < 0) {
>  goto err;
>  }
> -- 
> 2.30.2
>

Reviewed-by: Andrew Jones 




Re: [PATCH v2 3/3] docs/about: Add the missing release record in the subject

2021-08-23 Thread Andrew Jones
On Mon, Aug 23, 2021 at 11:00:05AM +0800, Yanan Wang wrote:
> Commit 29e0447551
> (docs/about/removed-features: Document removed CLI options from QEMU v3.1)
> has recorded some CLI options as replaced/removed from QEMU v3.1, but one
> of the subjects has missed the release record. Let's fix it.
> 
> Reported-by: Cornelia Huck 
> Signed-off-by: Yanan Wang 
> ---
>  docs/about/removed-features.rst | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/docs/about/removed-features.rst b/docs/about/removed-features.rst
> index 1c926a8bc1..8feeead449 100644
> --- a/docs/about/removed-features.rst
> +++ b/docs/about/removed-features.rst
> @@ -140,8 +140,8 @@ Use ``-rtc driftfix=slew`` instead.
>  
>  Replaced by ``-rtc base=date``.
>  
> -``-vnc ...,tls=...``, ``-vnc ...,x509=...`` & ``-vnc ...,x509verify=...``
> -'
> +``-vnc ...,tls=...``, ``-vnc ...,x509=...`` & ``-vnc ...,x509verify=...`` 
> (removed in 3.1)
> +''
>  
>  The "tls-creds" option should be used instead to point to a "tls-creds-x509"
>  object created using "-object".
> -- 
> 2.19.1
>

Reviewed-by: Andrew Jones 




Re: [PATCH v2 2/3] docs/about: Unify the subject format

2021-08-23 Thread Andrew Jones
On Mon, Aug 23, 2021 at 11:00:04AM +0800, Yanan Wang wrote:
> There is a mixture of "since/removed in X.Y" vs "since/removed in X.Y.Z"
> in the subjects in deprecated.rst/removed-features.rst. It will be better
> to use an unified format. It seems unlikely that we will ever deprecate
> something in a stable release, and even more unlikely that we'll remove
> something in one, so the short versions look like the thing we want to
> standardize on.
> 
> So here we unify the subject format in deprecated.rst to "since X.Y", and
> unify the subject format in removed-features.rst to "removed in X.Y".
> 
> Signed-off-by: Yanan Wang 
> Reviewed-by: Cornelia Huck 
> ---
>  docs/about/deprecated.rst   | 56 -
>  docs/about/removed-features.rst | 28 ++++-----
>  2 files changed, 42 insertions(+), 42 deletions(-)
>

Reviewed-by: Andrew Jones 




Re: [PATCH v2 1/3] docs/about: Remove the duplicated doc

2021-08-23 Thread Andrew Jones
On Mon, Aug 23, 2021 at 11:00:03AM +0800, Yanan Wang wrote:
> There are two places describing the same thing about deprecation
> of invalid topologies of -smp CLI, so remove the duplicated one.
> 
> Signed-off-by: Yanan Wang 
> Reviewed-by: Cornelia Huck 
> ---
>  docs/about/removed-features.rst | 13 -
>  1 file changed, 13 deletions(-)
> 
> diff --git a/docs/about/removed-features.rst b/docs/about/removed-features.rst
> index cbfa1a8e31..6a9c5bb484 100644
> --- a/docs/about/removed-features.rst
> +++ b/docs/about/removed-features.rst
> @@ -647,19 +647,6 @@ as ignored. Currently, users are responsible for making 
> sure the backing storage
>  specified with ``-mem-path`` can actually provide the guest RAM configured 
> with
>  ``-m`` and QEMU fails to start up if RAM allocation is unsuccessful.
>  
> -``-smp`` (invalid topologies) (removed 5.2)
> -'''
> -
> -CPU topology properties should describe whole machine topology including
> -possible CPUs.
> -
> -However, historically it was possible to start QEMU with an incorrect 
> topology
> -where *n* <= *sockets* * *cores* * *threads* < *maxcpus*,
> -which could lead to an incorrect topology enumeration by the guest.
> -Support for invalid topologies is removed, the user must ensure
> -topologies described with -smp include all possible cpus, i.e.
> -*sockets* * *cores* * *threads* = *maxcpus*.
> -
>  ``-machine enforce-config-section=on|off`` (removed 5.2)
>  
>  
> -- 
> 2.19.1
>

 
Reviewed-by: Andrew Jones 




[PATCH 3/4] target/arm/cpu64: Replace kvm_supported with sve_vq_supported

2021-08-19 Thread Andrew Jones
Now that we have an ARMCPU member sve_vq_supported we no longer
need the local kvm_supported bitmap for KVM's supported vector
lengths.

Signed-off-by: Andrew Jones 
---
 target/arm/cpu64.c | 19 +++
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index eb9318c83b74..557fd4757740 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -265,14 +265,17 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
  * any of the above.  Finally, if SVE is not disabled, then at least one
  * vector length must be enabled.
  */
-DECLARE_BITMAP(kvm_supported, ARM_MAX_VQ);
 DECLARE_BITMAP(tmp, ARM_MAX_VQ);
 uint32_t vq, max_vq = 0;
 
-/* Collect the set of vector lengths supported by KVM. */
-bitmap_zero(kvm_supported, ARM_MAX_VQ);
+/*
+ * CPU models specify a set of supported vector lengths which are
+ * enabled by default.  Attempting to enable any vector length not set
+ * in the supported bitmap results in an error.  When KVM is enabled we
+ * fetch the supported bitmap from the host.
+ */
 if (kvm_enabled() && kvm_arm_sve_supported()) {
-kvm_arm_sve_get_vls(CPU(cpu), kvm_supported);
+kvm_arm_sve_get_vls(CPU(cpu), cpu->sve_vq_supported);
 } else if (kvm_enabled()) {
 assert(!cpu_isar_feature(aa64_sve, cpu));
 }
@@ -299,7 +302,7 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
  * For KVM we have to automatically enable all supported 
unitialized
  * lengths, even when the smaller lengths are not all 
powers-of-two.
  */
-bitmap_andnot(tmp, kvm_supported, cpu->sve_vq_init, max_vq);
+bitmap_andnot(tmp, cpu->sve_vq_supported, cpu->sve_vq_init, 
max_vq);
 bitmap_or(cpu->sve_vq_map, cpu->sve_vq_map, tmp, max_vq);
 } else {
 /* Propagate enabled bits down through required powers-of-two. */
@@ -322,12 +325,12 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
 /* Disabling a supported length disables all larger lengths. */
 for (vq = 1; vq <= ARM_MAX_VQ; ++vq) {
 if (test_bit(vq - 1, cpu->sve_vq_init) &&
-test_bit(vq - 1, kvm_supported)) {
+test_bit(vq - 1, cpu->sve_vq_supported)) {
 break;
 }
 }
 max_vq = vq <= ARM_MAX_VQ ? vq - 1 : ARM_MAX_VQ;
-bitmap_andnot(cpu->sve_vq_map, kvm_supported,
+bitmap_andnot(cpu->sve_vq_map, cpu->sve_vq_supported,
   cpu->sve_vq_init, max_vq);
 if (max_vq == 0 || bitmap_empty(cpu->sve_vq_map, max_vq)) {
 error_setg(errp, "cannot disable sve%d", vq * 128);
@@ -392,7 +395,7 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
 
 if (kvm_enabled()) {
 /* Ensure the set of lengths matches what KVM supports. */
-bitmap_xor(tmp, cpu->sve_vq_map, kvm_supported, max_vq);
+bitmap_xor(tmp, cpu->sve_vq_map, cpu->sve_vq_supported, max_vq);
 if (!bitmap_empty(tmp, max_vq)) {
 vq = find_last_bit(tmp, max_vq) + 1;
 if (test_bit(vq - 1, cpu->sve_vq_map)) {
-- 
2.31.1




[PATCH 4/4] target/arm/cpu64: Validate sve vector lengths are supported

2021-08-19 Thread Andrew Jones
Future CPU types may specify which vector lengths are supported.
We can apply nearly the same logic to validate those lengths
as we do for KVM's supported vector lengths. We merge the code
where we can, but unfortunately can't completely merge it because
KVM requires all vector lengths, power-of-two or not, smaller than
the maximum enabled length to also be enabled. The architecture
only requires all the power-of-two lengths, though, so TCG will
only enforce that.

Signed-off-by: Andrew Jones 
---
 target/arm/cpu64.c | 101 -
 1 file changed, 45 insertions(+), 56 deletions(-)

diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 557fd4757740..9cb41c442600 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -329,35 +329,26 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
 break;
 }
 }
-max_vq = vq <= ARM_MAX_VQ ? vq - 1 : ARM_MAX_VQ;
-bitmap_andnot(cpu->sve_vq_map, cpu->sve_vq_supported,
-  cpu->sve_vq_init, max_vq);
-if (max_vq == 0 || bitmap_empty(cpu->sve_vq_map, max_vq)) {
-error_setg(errp, "cannot disable sve%d", vq * 128);
-error_append_hint(errp, "Disabling sve%d results in all "
-  "vector lengths being disabled.\n",
-  vq * 128);
-error_append_hint(errp, "With SVE enabled, at least one "
-  "vector length must be enabled.\n");
-return;
-}
 } else {
 /* Disabling a power-of-two disables all larger lengths. */
-if (test_bit(0, cpu->sve_vq_init)) {
-error_setg(errp, "cannot disable sve128");
-error_append_hint(errp, "Disabling sve128 results in all "
-  "vector lengths being disabled.\n");
-error_append_hint(errp, "With SVE enabled, at least one "
-  "vector length must be enabled.\n");
-return;
-}
-for (vq = 2; vq <= ARM_MAX_VQ; vq <<= 1) {
+for (vq = 1; vq <= ARM_MAX_VQ; vq <<= 1) {
 if (test_bit(vq - 1, cpu->sve_vq_init)) {
 break;
 }
 }
-max_vq = vq <= ARM_MAX_VQ ? vq - 1 : ARM_MAX_VQ;
-bitmap_complement(cpu->sve_vq_map, cpu->sve_vq_init, max_vq);
+}
+
+max_vq = vq <= ARM_MAX_VQ ? vq - 1 : ARM_MAX_VQ;
+bitmap_andnot(cpu->sve_vq_map, cpu->sve_vq_supported,
+  cpu->sve_vq_init, max_vq);
+if (max_vq == 0 || bitmap_empty(cpu->sve_vq_map, max_vq)) {
+error_setg(errp, "cannot disable sve%d", vq * 128);
+error_append_hint(errp, "Disabling sve%d results in all "
+  "vector lengths being disabled.\n",
+  vq * 128);
+error_append_hint(errp, "With SVE enabled, at least one "
+  "vector length must be enabled.\n");
+return;
 }
 
 max_vq = find_last_bit(cpu->sve_vq_map, max_vq) + 1;
@@ -393,46 +384,44 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
 assert(max_vq != 0);
 bitmap_clear(cpu->sve_vq_map, max_vq, ARM_MAX_VQ - max_vq);
 
-if (kvm_enabled()) {
-/* Ensure the set of lengths matches what KVM supports. */
-bitmap_xor(tmp, cpu->sve_vq_map, cpu->sve_vq_supported, max_vq);
-if (!bitmap_empty(tmp, max_vq)) {
-vq = find_last_bit(tmp, max_vq) + 1;
-if (test_bit(vq - 1, cpu->sve_vq_map)) {
-if (cpu->sve_max_vq) {
-error_setg(errp, "cannot set sve-max-vq=%d",
-   cpu->sve_max_vq);
-error_append_hint(errp, "This KVM host does not support "
-  "the vector length %d-bits.\n",
-  vq * 128);
-error_append_hint(errp, "It may not be possible to use "
-  "sve-max-vq with this KVM host. Try "
-  "using only sve properties.\n");
-} else {
-error_setg(errp, "cannot enable sve%d", vq * 128);
-error_append_hint(errp, "This KVM host does not support "
-  "the vector length %d-bits.\n",
-  vq * 128);
-}
+/* Ensure the set of lengths matche

[PATCH 1/4] target/arm/cpu: Introduce sve_vq_supported bitmap

2021-08-19 Thread Andrew Jones
Allow CPUs that support SVE to specify which SVE vector lengths they
support by setting them in this bitmap. Currently only the 'max' and
'host' CPU types supports SVE and 'host' requires KVM which obtains
its supported bitmap from the host. So, we only need to initialize the
bitmap for 'max' with TCG. And, since 'max' should support all SVE
vector lengths we simply fill the bitmap. Future CPU types may have
less trivial maps though.

Signed-off-by: Andrew Jones 
---
 target/arm/cpu.h   | 4 
 target/arm/cpu64.c | 2 ++
 2 files changed, 6 insertions(+)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 9f0a5f84d503..cc645b57421f 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1019,9 +1019,13 @@ struct ARMCPU {
  * While processing properties during initialization, corresponding
  * sve_vq_init bits are set for bits in sve_vq_map that have been
  * set by properties.
+ *
+ * Bits set in sve_vq_supported represent valid vector lengths for
+ * the CPU type.
  */
 DECLARE_BITMAP(sve_vq_map, ARM_MAX_VQ);
 DECLARE_BITMAP(sve_vq_init, ARM_MAX_VQ);
+DECLARE_BITMAP(sve_vq_supported, ARM_MAX_VQ);
 
 /* Generic timer counter frequency, in Hz */
 uint64_t gt_cntfrq_hz;
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index c690318a9b63..eb9318c83b74 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -840,6 +840,8 @@ static void aarch64_max_initfn(Object *obj)
 /* Default to PAUTH on, with the architected algorithm. */
 qdev_property_add_static(DEVICE(obj), _cpu_pauth_property);
 qdev_property_add_static(DEVICE(obj), _cpu_pauth_impdef_property);
+
+bitmap_fill(cpu->sve_vq_supported, ARM_MAX_VQ);
 }
 
 aarch64_add_sve_properties(obj);
-- 
2.31.1




[PATCH 2/4] target/arm/kvm64: Ensure sve vls map is completely clear

2021-08-19 Thread Andrew Jones
bitmap_clear() only clears the given range. While the given
range should be sufficient in this case we might as well be
100% sure all bits are zeroed by using bitmap_zero().

Signed-off-by: Andrew Jones 
---
 target/arm/kvm64.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
index 59982d470d37..e790d6c9a573 100644
--- a/target/arm/kvm64.c
+++ b/target/arm/kvm64.c
@@ -740,7 +740,7 @@ void kvm_arm_sve_get_vls(CPUState *cs, unsigned long *map)
 uint32_t vq = 0;
 int i, j;
 
-bitmap_clear(map, 0, ARM_MAX_VQ);
+bitmap_zero(map, ARM_MAX_VQ);
 
 /*
  * KVM ensures all host CPUs support the same set of vector lengths.
-- 
2.31.1




[PATCH 0/4] target/arm/cpu: Introduce sve_vq_supported bitmap

2021-08-19 Thread Andrew Jones
While reviewing the new A64FX CPU type it became clear that CPU
types should be able to specify which SVE vector lengths are
supported. This series adds a new bitmap member to ARMCPU and
modifies arm_cpu_sve_finalize() to validate inputs against it.
So far we only need to set the bitmap for the 'max' CPU type
though and, since it supports all vector lengths, we just fill
the whole thing.

This series was inspired by Richard Henderson's suggestion to
replace arm_cpu_sve_finalize's kvm_supported bitmap with something
that could be shared with TCG.

So far I've only lightly tested this. I'll do more testing and
report back later. I'd also be happy to get test results from
others.

Thanks,
drew

Andrew Jones (4):
  target/arm/cpu: Introduce sve_vq_supported bitmap
  target/arm/kvm64: Ensure sve vls map is completely clear
  target/arm/cpu64: Replace kvm_supported with sve_vq_supported
  target/arm/cpu64: Validate sve vector lengths are supported

 target/arm/cpu.h   |   4 ++
 target/arm/cpu64.c | 118 +
 target/arm/kvm64.c |   2 +-
 3 files changed, 61 insertions(+), 63 deletions(-)

-- 
2.31.1




Re: [PATCH v4 1/3] target-arm: Add support for Fujitsu A64FX

2021-08-18 Thread Andrew Jones
On Wed, Aug 18, 2021 at 08:29:15AM +, ishii.shuuic...@fujitsu.com wrote:
> 
> We appreciate everyone's comments.
> Before making the V5 patch, please let me check the patch contents.
> 
> > This looks reasonable to me, but you also need the 'sve' property that 
> > states sve in
> > supported at all.
> > > > So maybe we should just go ahead and add all sve* properties, 
> 
> In response to the above comment,
> We understood that the sve property will be added to the v4 patch.
> 
> i.e. 
> (QEMU) query-cpu-model-expansion type=full model={"name":"a64fx"}
> {"return": {"model": {"name": "a64fx", "props": {"sve128": false, "sve256": 
> true, "sve": true, "sve512": true, "aarch64": true, "pmu": true
> 
> > > > but
> > > > then make sure the default vq map is correct.
> 
> Furthermore, We understood that I need to add the above process as well, is 
> that correct?
> 
> > That's a good idea. I'll send a patch with your suggested-by.
> 
> If that's correct,
> In the current v4 patch, in the aarch64_a64fx_initfn function, 
> the a64fx_cpu_set_sve function is executed to set the SVE property, 
> and the arm_cpu_sve_finalize function is not called. 
> 
> In which function is it appropriate to execute the modulo max_vq function 
> (or equivalent process)?
> 
> If We are not understanding you correctly,
> We would appreciate your comments.

Richard's suggestion is to generalize the "supported" bitmap concept,
which is currently only used for KVM, in order to also use it for
TCG cpu models. The 'max' cpu type will have the trivial all-set
supported bitmap, but the a64fx will have a specific one. I plan to
do this "supported" bitmap generalization and apply it to the TCG
max cpu type. You'll need to rebase this series on those patches and
provide the a64fx supported bitmap.

I think this will be more clear once I get the patch posted (which I
haven't started writing yet). I'll try to get it posted by tomorrow
evening though, since I have vacation on Friday.

Thanks,
drew


> 
> Best regards.
> 
> > -Original Message-
> > From: Andrew Jones 
> > Sent: Wednesday, August 18, 2021 1:28 AM
> > To: Richard Henderson 
> > Cc: Ishii, Shuuichirou/石井 周一郎 ;
> > peter.mayd...@linaro.org; qemu-...@nongnu.org; qemu-devel@nongnu.org
> > Subject: Re: [PATCH v4 1/3] target-arm: Add support for Fujitsu A64FX
> > 
> > On Tue, Aug 17, 2021 at 05:53:34AM -1000, Richard Henderson wrote:
> > > On 8/17/21 5:36 AM, Andrew Jones wrote:
> > > > On Tue, Aug 17, 2021 at 05:23:17AM -1000, Richard Henderson wrote:
> > > > > On 8/17/21 1:56 AM, Andrew Jones wrote:
> > > > > > I guess it's fine. You could easily create a new
> > > > > > cpu_arm_set_sve_vq() which would forbid changing the properties
> > > > > > if you wanted to, but then we need to answer Peter's question in
> > > > > > order to see if there's a precedent for that type of property.
> > > > >
> > > > > I don't see the point in read-only properties.  If the user wants
> > > > > to set non-standard values on the command-line, let them.  What is
> > > > > most important is getting the correct default from '-cpu a64fx'.
> > > > >
> > > >
> > > > So maybe we should just go ahead and add all sve* properties, but
> > > > then make sure the default vq map is correct.
> > >
> > > I think that's the right answer.
> > >
> > > Presently we have a kvm_supported variable that's initialized by
> > > kvm_arm_sve_get_vls().  I think we want to rename that variable and
> > > provide a version of that function for tcg. Probably we should have
> > > done that before, with a trivial function for -cpu max to set all bits.
> > >
> > > Then eliminate most of the other kvm_enabled() checks in
> > > arm_cpu_sve_finalize.  I think the only one we keep is the last, where
> > > we verify that the final sve_vq_map matches kvm_enabled exactly, modulo
> > max_vq.
> > >
> > > This should minimize the differences in behaviour between tcg and kvm.
> > 
> > That's a good idea. I'll send a patch with your suggested-by.
> > 
> > Thanks,
> > drew
> 




Re: [PATCH v4 1/3] target-arm: Add support for Fujitsu A64FX

2021-08-17 Thread Andrew Jones
On Tue, Aug 17, 2021 at 05:53:34AM -1000, Richard Henderson wrote:
> On 8/17/21 5:36 AM, Andrew Jones wrote:
> > On Tue, Aug 17, 2021 at 05:23:17AM -1000, Richard Henderson wrote:
> > > On 8/17/21 1:56 AM, Andrew Jones wrote:
> > > > I guess it's fine. You could easily create a new cpu_arm_set_sve_vq()
> > > > which would forbid changing the properties if you wanted to, but then
> > > > we need to answer Peter's question in order to see if there's a
> > > > precedent for that type of property.
> > > 
> > > I don't see the point in read-only properties.  If the user wants to set
> > > non-standard values on the command-line, let them.  What is most important
> > > is getting the correct default from '-cpu a64fx'.
> > > 
> > 
> > So maybe we should just go ahead and add all sve* properties, but then
> > make sure the default vq map is correct.
> 
> I think that's the right answer.
> 
> Presently we have a kvm_supported variable that's initialized by
> kvm_arm_sve_get_vls().  I think we want to rename that variable and provide
> a version of that function for tcg. Probably we should have done that
> before, with a trivial function for -cpu max to set all bits.
> 
> Then eliminate most of the other kvm_enabled() checks in
> arm_cpu_sve_finalize.  I think the only one we keep is the last, where we
> verify that the final sve_vq_map matches kvm_enabled exactly, modulo max_vq.
> 
> This should minimize the differences in behaviour between tcg and kvm.

That's a good idea. I'll send a patch with your suggested-by.

Thanks,
drew




Re: [PATCH v4 1/3] target-arm: Add support for Fujitsu A64FX

2021-08-17 Thread Andrew Jones
On Tue, Aug 17, 2021 at 05:23:17AM -1000, Richard Henderson wrote:
> On 8/17/21 1:56 AM, Andrew Jones wrote:
> > I guess it's fine. You could easily create a new cpu_arm_set_sve_vq()
> > which would forbid changing the properties if you wanted to, but then
> > we need to answer Peter's question in order to see if there's a
> > precedent for that type of property.
> 
> I don't see the point in read-only properties.  If the user wants to set
> non-standard values on the command-line, let them.  What is most important
> is getting the correct default from '-cpu a64fx'.
>

So maybe we should just go ahead and add all sve* properties, but then
make sure the default vq map is correct.

Thanks,
drew




Re: [PULL 1/1] machine: Disallow specifying topology parameters as zero

2021-08-17 Thread Andrew Jones
On Tue, Aug 17, 2021 at 01:37:15PM +0100, Peter Maydell wrote:
> On Tue, 17 Aug 2021 at 13:22, Andrew Jones  wrote:
> >
> > On Tue, Aug 17, 2021 at 01:06:19PM +0100, Peter Maydell wrote:
> > > On Tue, 17 Aug 2021 at 13:02, Andrew Jones  wrote:
> > > >
> > > > On Mon, Aug 16, 2021 at 11:37:21PM +0200, Paolo Bonzini wrote:
> > > > > How do we know that no one has ever used such configuration? The 
> > > > > conversion
> > > > > was meant to be bug-compatible.
> > > >
> > > > We don't. But we do know that a zero input value was never documented
> > > > prior to 1e63fe68580, which has not yet been released. Can we claim
> > > > that an undocumented input value has undefined behavior, giving us
> > > > freedom to modify that behavior until it is documented?
> > >
> > > Dunno; I definitely don't want a behaviour-change patch at this
> > > point in the release-cycle, though...
> > >
> >
> > Can we replace this patch with the following one for now? And then
> > discuss this further before committing to supporting a zero input?
> 
> If you can agree on that and send out a patch and get it reviewed
> within the next three hours or so...

I posted the patch. Agreement/disagreement can come in the form of
ack/nack. Hopefully in time...

Thanks,
drew




[PATCH] qapi/machine.json: Remove zero value reference from SMPConfiguration documentation

2021-08-17 Thread Andrew Jones
Commit 1e63fe685804 ("machine: pass QAPI struct to mc->smp_parse")
introduced documentation stating that a zero input value for an SMP
parameter indicates that its value should be automatically configured.
This is indeed how things work today, but we'd like to change that.
Avoid documenting behaviors we want to leave undefined for the time
being, giving us freedom to change it later.

Fixes: 1e63fe685804 ("machine: pass QAPI struct to mc->smp_parse")
Signed-off-by: Andrew Jones 
---
 qapi/machine.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/qapi/machine.json b/qapi/machine.json
index c3210ee1fb24..157712f00614 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -1288,7 +1288,7 @@
 ##
 # @SMPConfiguration:
 #
-# Schema for CPU topology configuration.  "0" or a missing value lets
+# Schema for CPU topology configuration.  A missing value lets
 # QEMU figure out a suitable value based on the ones that are provided.
 #
 # @cpus: number of virtual CPUs in the virtual machine
-- 
2.31.1




Re: [PULL 1/1] machine: Disallow specifying topology parameters as zero

2021-08-17 Thread Andrew Jones
On Tue, Aug 17, 2021 at 01:06:19PM +0100, Peter Maydell wrote:
> On Tue, 17 Aug 2021 at 13:02, Andrew Jones  wrote:
> >
> > On Mon, Aug 16, 2021 at 11:37:21PM +0200, Paolo Bonzini wrote:
> > > How do we know that no one has ever used such configuration? The 
> > > conversion
> > > was meant to be bug-compatible.
> >
> > We don't. But we do know that a zero input value was never documented
> > prior to 1e63fe68580, which has not yet been released. Can we claim
> > that an undocumented input value has undefined behavior, giving us
> > freedom to modify that behavior until it is documented?
> 
> Dunno; I definitely don't want a behaviour-change patch at this
> point in the release-cycle, though...
>

Can we replace this patch with the following one for now? And then
discuss this further before committing to supporting a zero input?

Thanks,
drew

Author: Andrew Jones 
Date:   Tue Aug 17 14:17:29 2021 +0200

qapi/machine.json: Remove zero value reference from SMPConfiguration 
documentation

Commit 1e63fe685804 ("machine: pass QAPI struct to mc->smp_parse")
introduced documentation stating that a zero input value for an SMP
parameter indicates that its value should be automatically configured.
This is indeed how things work today, but we'd like to change that.
Avoid documenting behaviors we want to leave undefined for the time
being, giving us freedom to change it later.

Fixes: 1e63fe685804 ("machine: pass QAPI struct to mc->smp_parse")
Signed-off-by: Andrew Jones 

diff --git a/qapi/machine.json b/qapi/machine.json
index c3210ee1fb24..157712f00614 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -1288,7 +1288,7 @@
 ##
 # @SMPConfiguration:
 #
-# Schema for CPU topology configuration.  "0" or a missing value lets
+# Schema for CPU topology configuration.  A missing value lets
 # QEMU figure out a suitable value based on the ones that are provided.
 #
 # @cpus: number of virtual CPUs in the virtual machine




Re: [PULL 1/1] machine: Disallow specifying topology parameters as zero

2021-08-17 Thread Andrew Jones
On Mon, Aug 16, 2021 at 11:37:21PM +0200, Paolo Bonzini wrote:
> How do we know that no one has ever used such configuration? The conversion
> was meant to be bug-compatible.

We don't. But we do know that a zero input value was never documented
prior to 1e63fe68580, which has not yet been released. Can we claim
that an undocumented input value has undefined behavior, giving us
freedom to modify that behavior until it is documented?

Thanks,
drew

> 
> Paolo
> 
> Il lun 16 ago 2021, 23:06 Eduardo Habkost  ha scritto:
> 
> > From: Yanan Wang 
> >
> > In the SMP configuration, we should either provide a topology
> > parameter with a reasonable value (greater than zero) or just
> > omit it and QEMU will compute the missing value. Users should
> > have never provided a configuration with parameters as zero
> > (e.g. -smp 8,sockets=0) which should be treated as invalid.
> >
> > But commit 1e63fe68580 (machine: pass QAPI struct to mc->smp_parse)
> > has added some doc which implied that 'anything=0' is valid and
> > has the same semantics as omitting a parameter.
> >
> > To avoid meaningless configurations possibly introduced by users
> > in the future and consequently a necessary deprecation process,
> > fix the doc and also add the corresponding sanity check.
> >
> > Fixes: 1e63fe68580 (machine: pass QAPI struct to mc->smp_parse)
> > Suggested-by: Andrew Jones 
> > Signed-off-by: Yanan Wang 
> > Reviewed-by: Daniel P. Berrange 
> > Tested-by: Daniel P. Berrange 
> > Reviewed-by: Andrew Jones 
> > Reviewed-by: Cornelia Huck 
> > Message-Id: <20210816024522.143124-2-wangyana...@huawei.com>
> > Signed-off-by: Eduardo Habkost 
> > ---
> >  hw/core/machine.c | 14 ++
> >  qapi/machine.json |  6 +++---
> >  qemu-options.hx   | 12 +++-
> >  3 files changed, 24 insertions(+), 8 deletions(-)
> >
> > diff --git a/hw/core/machine.c b/hw/core/machine.c
> > index 54e040587dd..a7e119469aa 100644
> > --- a/hw/core/machine.c
> > +++ b/hw/core/machine.c
> > @@ -832,6 +832,20 @@ static void machine_set_smp(Object *obj, Visitor *v,
> > const char *name,
> >  return;
> >  }
> >
> > +/*
> > + * A specified topology parameter must be greater than zero,
> > + * explicit configuration like "cpus=0" is not allowed.
> > + */
> > +if ((config->has_cpus && config->cpus == 0) ||
> > +(config->has_sockets && config->sockets == 0) ||
> > +(config->has_dies && config->dies == 0) ||
> > +(config->has_cores && config->cores == 0) ||
> > +(config->has_threads && config->threads == 0) ||
> > +(config->has_maxcpus && config->maxcpus == 0)) {
> > +error_setg(errp, "CPU topology parameters must be greater than
> > zero");
> > +goto out_free;
> > +}
> > +
> >  mc->smp_parse(ms, config, errp);
> >  if (*errp) {
> >  goto out_free;
> > diff --git a/qapi/machine.json b/qapi/machine.json
> > index c3210ee1fb2..9272cb3cf8b 100644
> > --- a/qapi/machine.json
> > +++ b/qapi/machine.json
> > @@ -1288,8 +1288,8 @@
> >  ##
> >  # @SMPConfiguration:
> >  #
> > -# Schema for CPU topology configuration.  "0" or a missing value lets
> > -# QEMU figure out a suitable value based on the ones that are provided.
> > +# Schema for CPU topology configuration. A missing value lets QEMU
> > +# figure out a suitable value based on the ones that are provided.
> >  #
> >  # @cpus: number of virtual CPUs in the virtual machine
> >  #
> > @@ -1297,7 +1297,7 @@
> >  #
> >  # @dies: number of dies per socket in the CPU topology
> >  #
> > -# @cores: number of cores per thread in the CPU topology
> > +# @cores: number of cores per die in the CPU topology
> >  #
> >  # @threads: number of threads per core in the CPU topology
> >  #
> > diff --git a/qemu-options.hx b/qemu-options.hx
> > index 83aa59a920f..aee622f577d 100644
> > --- a/qemu-options.hx
> > +++ b/qemu-options.hx
> > @@ -227,11 +227,13 @@ SRST
> >  of computing the CPU maximum count.
> >
> >  Either the initial CPU count, or at least one of the topology
> > parameters
> > -must be specified. Values for any omitted parameters will be computed
> > -from those which are given. Historically preference was given to the
> > -coarsest topology parameters when computi

Re: [PATCH v4 1/3] target-arm: Add support for Fujitsu A64FX

2021-08-17 Thread Andrew Jones
On Tue, Aug 17, 2021 at 06:43:58AM +, ishii.shuuic...@fujitsu.com wrote:
> 
> > On Thu, 12 Aug 2021 at 10:25, Andrew Jones  wrote:
> > > On second thought, do we want the QMP CPU model expansion query to
> > > show that this CPU type has sve,sve128,sve256,sve512? If so, then our
> > > SVE work isn't complete, because we need those properties, set true by
> > > default, but forbidden from changing.
> > 
> > Do we have precedent elsewhere (arm, x86, wherever) for "this CPU object
> > exposes these properties as constant unwriteable" ?
> 
> We have not yet conducted a confirmation of Peter's question, but...
> 
> > On second thought, do we want the QMP CPU model expansion query to show that
> > this CPU type has sve,sve128,sve256,sve512? If so, then our SVE work isn't
> > complete, because we need those properties, set true by default, but 
> > forbidden
> > from changing.
> 
> Based on Andrew's comment, 
> We have created a patch based on v4 that works as intended in QMP.
> 
> --
> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> index 162e46afc3..2d9f779cb6 100644
> --- a/target/arm/cpu.c
> +++ b/target/arm/cpu.c
> @@ -1345,29 +1345,12 @@ static void arm_cpu_finalizefn(Object *obj)
>  #endif
>  }
> 
> -static void a64fx_cpu_set_sve(ARMCPU *cpu)
> -{
> -/* Suppport of A64FX's vector length are 128,256 and 512bit only */
> -bitmap_zero(cpu->sve_vq_map, ARM_MAX_VQ);
> -bitmap_zero(cpu->sve_vq_init, ARM_MAX_VQ);
> -set_bit(0, cpu->sve_vq_map); /* 128bit */
> -set_bit(0, cpu->sve_vq_init);
> -set_bit(1, cpu->sve_vq_map); /* 256bit */
> -set_bit(1, cpu->sve_vq_init);
> -set_bit(3, cpu->sve_vq_map); /* 512bit */
> -set_bit(3, cpu->sve_vq_init);
> -
> -cpu->sve_max_vq = find_last_bit(cpu->sve_vq_map, ARM_MAX_VQ) + 1;
> -}
> -
>  void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp)
>  {
>  Error *local_err = NULL;
> 
>  if (arm_feature(>env, ARM_FEATURE_AARCH64)) {
> -if (arm_feature(>env, ARM_FEATURE_A64FX)) {
> -a64fx_cpu_set_sve(cpu);
> -} else {
> +if (!arm_feature(>env, ARM_FEATURE_A64FX)) {
>  arm_cpu_sve_finalize(cpu, _err);
>  if (local_err != NULL) {
>  error_propagate(errp, local_err);
> diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
> index 5e7e885f9d..1ec2a7c6da 100644
> --- a/target/arm/cpu64.c
> +++ b/target/arm/cpu64.c
> @@ -847,6 +847,23 @@ static void aarch64_max_initfn(Object *obj)
>  cpu_max_set_sve_max_vq, NULL, NULL);
>  }
> 
> +static void a64fx_cpu_set_sve(Object *obj)
> +{
> +int i;
> +Error *errp = NULL;
> +ARMCPU *cpu = ARM_CPU(obj);
> +/* Suppport of A64FX's vector length are 128,256 and 512bit only */
> +const char *vl[] = {"sve128", "sve256", "sve512"};
> +
> +for(i = 0; i  +object_property_add(obj, vl[i], "bool", cpu_arm_get_sve_vq,
> +cpu_arm_set_sve_vq, NULL, NULL);
> +object_property_set_bool(obj, vl[i], true, );
> +}
> +
> +cpu->sve_max_vq = find_last_bit(cpu->sve_vq_map, ARM_MAX_VQ) + 1;
> +}
> +
>  static void aarch64_a64fx_initfn(Object *obj)
>  {
>  ARMCPU *cpu = ARM_CPU(obj);
> @@ -885,6 +902,9 @@ static void aarch64_a64fx_initfn(Object *obj)
>  cpu->gic_vpribits = 5;
>  cpu->gic_vprebits = 5;
> 
> +/* Set SVE properties */
> +a64fx_cpu_set_sve(obj);
> +
>  /* TODO:  Add A64FX specific HPC extension registers */
>  }
> --
> 
> In the case of the patch above,
> it is possible to identify only the SVE vector length supported by A64FX from 
> QMP, 
> as shown in the following result.
> 
> --
> Welcome to the QMP low-level shell!
> Connected to QEMU 6.0.93
> 
> (QEMU) query-cpu-model-expansion type=full model={"name":"a64fx"}
> {"return": {"model": {"name": "a64fx", "props": {"sve128": true, "sve256": 
> true, "sve512": true, "aarch64": true, "pmu": true
> (QEMU)
> --
> 
> How about this kind of fix?

This looks reasonable to me, but you also need the 'sve' property that
states sve in supported at all.

> However, by allowing the sve128, sve256, and sve512 properties to be 
> specified, 
> the user can explicitly change the settings (ex: sve128=off), 
> but the only properties that can be set is the vector length supported by 
> A64FX. 
> We personally think th

Re: [PATCH for-6.2 v5 3/5] hw/arm/virt: Add cpu-map to device tree

2021-08-17 Thread Andrew Jones
On Tue, Aug 17, 2021 at 10:10:44AM +0800, wangyanan (Y) wrote:
> Hi,
> On 2021/8/5 20:39, Yanan Wang wrote:
> > From: Andrew Jones 
> > 
> > Support device tree CPU topology descriptions.
> > 
> > In accordance with the Devicetree Specification, the Linux Doc
> > "arm/cpus.yaml" requires that cpus and cpu nodes in the DT are
> > present. And we have already met the requirement by generating
> > /cpus/cpu@* nodes for members within ms->smp.cpus. Accordingly,
> > we should also create subnodes in cpu-map for the present cpus,
> > each of which relates to an unique cpu node.
> > 
> > The Linux Doc "cpu/cpu-topology.txt" states that the hierarchy
> > of CPUs in a SMP system is defined through four entities and
> > they are socket/cluster/core/thread. It is also required that
> > a socket node's child nodes must be one or more cluster nodes.
> > Given that currently we are only provided with information of
> > socket/core/thread, we assume there is one cluster child node
> > in each socket node when creating cpu-map.
> > 
> > Signed-off-by: Andrew Jones 
> > Co-developed-by: Yanan Wang 
> > Signed-off-by: Yanan Wang 
> > ---
> >   hw/arm/virt.c | 59 ++-
> >   1 file changed, 49 insertions(+), 10 deletions(-)
> > 
> > diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> > index 82f2eba6bd..d1e294be95 100644
> > --- a/hw/arm/virt.c
> > +++ b/hw/arm/virt.c
> > @@ -350,20 +350,21 @@ static void fdt_add_cpu_nodes(const VirtMachineState 
> > *vms)
> >   int cpu;
> >   int addr_cells = 1;
> >   const MachineState *ms = MACHINE(vms);
> > +const VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
> >   int smp_cpus = ms->smp.cpus;
> >   /*
> > - * From Documentation/devicetree/bindings/arm/cpus.txt
> > - *  On ARM v8 64-bit systems value should be set to 2,
> > - *  that corresponds to the MPIDR_EL1 register size.
> > - *  If MPIDR_EL1[63:32] value is equal to 0 on all CPUs
> > - *  in the system, #address-cells can be set to 1, since
> > - *  MPIDR_EL1[63:32] bits are not used for CPUs
> > - *  identification.
> > + * See Linux Documentation/devicetree/bindings/arm/cpus.yaml
> > + * On ARM v8 64-bit systems value should be set to 2,
> > + * that corresponds to the MPIDR_EL1 register size.
> > + * If MPIDR_EL1[63:32] value is equal to 0 on all CPUs
> > + * in the system, #address-cells can be set to 1, since
> > + * MPIDR_EL1[63:32] bits are not used for CPUs
> > + * identification.
> >*
> > - *  Here we actually don't know whether our system is 32- or 64-bit 
> > one.
> > - *  The simplest way to go is to examine affinity IDs of all our CPUs. 
> > If
> > - *  at least one of them has Aff3 populated, we set #address-cells to 
> > 2.
> > + * Here we actually don't know whether our system is 32- or 64-bit one.
> > + * The simplest way to go is to examine affinity IDs of all our CPUs. 
> > If
> > + * at least one of them has Aff3 populated, we set #address-cells to 2.
> >*/
> >   for (cpu = 0; cpu < smp_cpus; cpu++) {
> >   ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
> > @@ -406,8 +407,46 @@ static void fdt_add_cpu_nodes(const VirtMachineState 
> > *vms)
> >   ms->possible_cpus->cpus[cs->cpu_index].props.node_id);
> >   }
> > +if (!vmc->no_cpu_topology) {
> > +qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle",
> > +  qemu_fdt_alloc_phandle(ms->fdt));
> > +}
> > +
> >   g_free(nodename);
> >   }
> > +
> > +if (!vmc->no_cpu_topology) {
> > +/*
> > + * See Linux Documentation/devicetree/bindings/cpu/cpu-topology.txt
> > + * In a SMP system, the hierarchy of CPUs is defined through four
> > + * entities that are used to describe the layout of physical CPUs
> > + * in the system: socket/cluster/core/thread.
> > + */
> > +qemu_fdt_add_subnode(ms->fdt, "/cpus/cpu-map");
> > +
> > +for (cpu = smp_cpus - 1; cpu >= 0; cpu--) {
> > +char *cpu_path = g_strdup_printf("/cpus/cpu@%d", cpu);
> > +char *map_path;
> > +
> > +if (ms->smp.threads > 1) {
> > +map_path = g_strdup_printf(
> > +  

Re: [PATCH v4 1/3] target-arm: Add support for Fujitsu A64FX

2021-08-12 Thread Andrew Jones
On Thu, Aug 12, 2021 at 11:16:50AM +0200, Andrew Jones wrote:
> On Thu, Aug 12, 2021 at 03:04:38PM +0900, Shuuichirou Ishii wrote:
> > Add a definition for the Fujitsu A64FX processor.
> > 
> > The A64FX processor does not implement the AArch32 Execution state,
> > so there are no associated AArch32 Identification registers.
> > 
> > For SVE, the A64FX processor supports only 128,256 and 512bit vector 
> > lengths.
> > 
> > Signed-off-by: Shuuichirou Ishii 
> > ---
> >  target/arm/cpu.c   | 27 +++
> >  target/arm/cpu.h   |  1 +
> >  target/arm/cpu64.c | 42 ++
> >  3 files changed, 66 insertions(+), 4 deletions(-)
> > 
> > diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> > index 2866dd7658..162e46afc3 100644
> > --- a/target/arm/cpu.c
> > +++ b/target/arm/cpu.c
> > @@ -1345,15 +1345,34 @@ static void arm_cpu_finalizefn(Object *obj)
> >  #endif
> >  }
> >  
> > +static void a64fx_cpu_set_sve(ARMCPU *cpu)
> > +{
> > +/* Suppport of A64FX's vector length are 128,256 and 512bit only */
> > +bitmap_zero(cpu->sve_vq_map, ARM_MAX_VQ);
> > +bitmap_zero(cpu->sve_vq_init, ARM_MAX_VQ);
> > +set_bit(0, cpu->sve_vq_map); /* 128bit */
> > +set_bit(0, cpu->sve_vq_init);
> > +set_bit(1, cpu->sve_vq_map); /* 256bit */
> > +set_bit(1, cpu->sve_vq_init);
> > +set_bit(3, cpu->sve_vq_map); /* 512bit */
> > +set_bit(3, cpu->sve_vq_init);
> > +
> > +cpu->sve_max_vq = find_last_bit(cpu->sve_vq_map, ARM_MAX_VQ) + 1;
> > +}
> > +
> >  void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp)
> >  {
> >  Error *local_err = NULL;
> >  
> >  if (arm_feature(>env, ARM_FEATURE_AARCH64)) {
> > -arm_cpu_sve_finalize(cpu, _err);
> > -if (local_err != NULL) {
> > -error_propagate(errp, local_err);
> > -return;
> > +if (arm_feature(>env, ARM_FEATURE_A64FX)) {
> > +a64fx_cpu_set_sve(cpu);
> > +} else {
> > +arm_cpu_sve_finalize(cpu, _err);
> > +if (local_err != NULL) {
> > +error_propagate(errp, local_err);
> > +return;
> > +}
> >  }
> >  
> >  /*
> > diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> > index 9f0a5f84d5..84ebca731a 100644
> > --- a/target/arm/cpu.h
> > +++ b/target/arm/cpu.h
> > @@ -2145,6 +2145,7 @@ enum arm_features {
> >  ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
> >  ARM_FEATURE_M_MAIN, /* M profile Main Extension */
> >  ARM_FEATURE_V8_1M, /* M profile extras only in v8.1M and later */
> > +ARM_FEATURE_A64FX, /* Fujitsu A64FX processor */
> >  };
> >  
> >  static inline int arm_feature(CPUARMState *env, int feature)
> > diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
> > index c690318a9b..5e7e885f9d 100644
> > --- a/target/arm/cpu64.c
> > +++ b/target/arm/cpu64.c
> > @@ -847,10 +847,52 @@ static void aarch64_max_initfn(Object *obj)
> >  cpu_max_set_sve_max_vq, NULL, NULL);
> >  }
> >  
> > +static void aarch64_a64fx_initfn(Object *obj)
> > +{
> > +ARMCPU *cpu = ARM_CPU(obj);
> > +
> > +cpu->dtb_compatible = "arm,a64fx";
> > +set_feature(>env, ARM_FEATURE_A64FX);
> > +set_feature(>env, ARM_FEATURE_V8);
> > +set_feature(>env, ARM_FEATURE_NEON);
> > +set_feature(>env, ARM_FEATURE_GENERIC_TIMER);
> > +set_feature(>env, ARM_FEATURE_AARCH64);
> > +set_feature(>env, ARM_FEATURE_EL2);
> > +set_feature(>env, ARM_FEATURE_EL3);
> > +set_feature(>env, ARM_FEATURE_PMU);
> > +cpu->midr = 0x461f0010;
> > +cpu->revidr = 0x;
> > +cpu->ctr = 0x86668006;
> > +cpu->reset_sctlr = 0x3180;
> > +cpu->isar.id_aa64pfr0 =   0x00010111; /* No RAS Extensions */
> > +cpu->isar.id_aa64pfr1 = 0x;
> > +cpu->isar.id_aa64dfr0 = 0x10305408;
> > +cpu->isar.id_aa64dfr1 = 0x;
> > +cpu->id_aa64afr0 = 0x;
> > +cpu->id_aa64afr1 = 0x;
> > +cpu->isar.id_aa64mmfr0 = 0x1122;
> > +cpu->isar.id_aa64mmfr1 = 0x11212100;
> > +cpu->isar.id_aa64mmfr2 = 0x1011;
> > +cpu->isar.id_aa64i

Re: [PATCH v4 1/3] target-arm: Add support for Fujitsu A64FX

2021-08-12 Thread Andrew Jones
On Thu, Aug 12, 2021 at 03:04:38PM +0900, Shuuichirou Ishii wrote:
> Add a definition for the Fujitsu A64FX processor.
> 
> The A64FX processor does not implement the AArch32 Execution state,
> so there are no associated AArch32 Identification registers.
> 
> For SVE, the A64FX processor supports only 128,256 and 512bit vector lengths.
> 
> Signed-off-by: Shuuichirou Ishii 
> ---
>  target/arm/cpu.c   | 27 +++
>  target/arm/cpu.h   |  1 +
>  target/arm/cpu64.c | 42 ++
>  3 files changed, 66 insertions(+), 4 deletions(-)
> 
> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> index 2866dd7658..162e46afc3 100644
> --- a/target/arm/cpu.c
> +++ b/target/arm/cpu.c
> @@ -1345,15 +1345,34 @@ static void arm_cpu_finalizefn(Object *obj)
>  #endif
>  }
>  
> +static void a64fx_cpu_set_sve(ARMCPU *cpu)
> +{
> +/* Suppport of A64FX's vector length are 128,256 and 512bit only */
> +bitmap_zero(cpu->sve_vq_map, ARM_MAX_VQ);
> +bitmap_zero(cpu->sve_vq_init, ARM_MAX_VQ);
> +set_bit(0, cpu->sve_vq_map); /* 128bit */
> +set_bit(0, cpu->sve_vq_init);
> +set_bit(1, cpu->sve_vq_map); /* 256bit */
> +set_bit(1, cpu->sve_vq_init);
> +set_bit(3, cpu->sve_vq_map); /* 512bit */
> +set_bit(3, cpu->sve_vq_init);
> +
> +cpu->sve_max_vq = find_last_bit(cpu->sve_vq_map, ARM_MAX_VQ) + 1;
> +}
> +
>  void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp)
>  {
>  Error *local_err = NULL;
>  
>  if (arm_feature(>env, ARM_FEATURE_AARCH64)) {
> -arm_cpu_sve_finalize(cpu, _err);
> -if (local_err != NULL) {
> -error_propagate(errp, local_err);
> -return;
> +if (arm_feature(>env, ARM_FEATURE_A64FX)) {
> +a64fx_cpu_set_sve(cpu);
> +} else {
> +arm_cpu_sve_finalize(cpu, _err);
> +if (local_err != NULL) {
> +error_propagate(errp, local_err);
> +return;
> +}
>  }
>  
>  /*
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index 9f0a5f84d5..84ebca731a 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -2145,6 +2145,7 @@ enum arm_features {
>  ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
>  ARM_FEATURE_M_MAIN, /* M profile Main Extension */
>  ARM_FEATURE_V8_1M, /* M profile extras only in v8.1M and later */
> +ARM_FEATURE_A64FX, /* Fujitsu A64FX processor */
>  };
>  
>  static inline int arm_feature(CPUARMState *env, int feature)
> diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
> index c690318a9b..5e7e885f9d 100644
> --- a/target/arm/cpu64.c
> +++ b/target/arm/cpu64.c
> @@ -847,10 +847,52 @@ static void aarch64_max_initfn(Object *obj)
>  cpu_max_set_sve_max_vq, NULL, NULL);
>  }
>  
> +static void aarch64_a64fx_initfn(Object *obj)
> +{
> +ARMCPU *cpu = ARM_CPU(obj);
> +
> +cpu->dtb_compatible = "arm,a64fx";
> +set_feature(>env, ARM_FEATURE_A64FX);
> +set_feature(>env, ARM_FEATURE_V8);
> +set_feature(>env, ARM_FEATURE_NEON);
> +set_feature(>env, ARM_FEATURE_GENERIC_TIMER);
> +set_feature(>env, ARM_FEATURE_AARCH64);
> +set_feature(>env, ARM_FEATURE_EL2);
> +set_feature(>env, ARM_FEATURE_EL3);
> +set_feature(>env, ARM_FEATURE_PMU);
> +cpu->midr = 0x461f0010;
> +cpu->revidr = 0x;
> +cpu->ctr = 0x86668006;
> +cpu->reset_sctlr = 0x3180;
> +cpu->isar.id_aa64pfr0 =   0x00010111; /* No RAS Extensions */
> +cpu->isar.id_aa64pfr1 = 0x;
> +cpu->isar.id_aa64dfr0 = 0x10305408;
> +cpu->isar.id_aa64dfr1 = 0x;
> +cpu->id_aa64afr0 = 0x;
> +cpu->id_aa64afr1 = 0x;
> +cpu->isar.id_aa64mmfr0 = 0x1122;
> +cpu->isar.id_aa64mmfr1 = 0x11212100;
> +cpu->isar.id_aa64mmfr2 = 0x1011;
> +cpu->isar.id_aa64isar0 = 0x10211120;
> +cpu->isar.id_aa64isar1 = 0x00010001;
> +cpu->isar.id_aa64zfr0 = 0x;
> +cpu->clidr = 0x8023;
> +cpu->ccsidr[0] = 0x7007e01c; /* 64KB L1 dcache */
> +cpu->ccsidr[1] = 0x2007e01c; /* 64KB L1 icache */
> +cpu->ccsidr[2] = 0x70ffe07c; /* 8MB L2 cache */
> +cpu->dcz_blocksize = 6; /* 256 bytes */
> +cpu->gic_num_lrs = 4;
> +cpu->gic_vpribits = 5;
> +cpu->gic_vprebits = 5;
> +
> +/* TODO:  Add A64FX specific HPC extension registers */
> +}
> +
>  static const ARMCPUInfo aarch64_cpus[] = {
>  { .name = "cortex-a57", .initfn = aarch64_a57_initfn },
>  { .name = "cortex-a53", .initfn = aarch64_a53_initfn },
>  { .name = "cortex-a72", .initfn = aarch64_a72_initfn },
> +{ .name = "a64fx",  .initfn = aarch64_a64fx_initfn },
>  { .name = "max",.initfn = aarch64_max_initfn },
>  };
>  
> -- 
> 2.27.0
>

For the SVE related bits

Reviewed-by: Andrew Jones 




Re: [PATCH for-6.2] hw/arm/virt_acpi_build: Generate DBG2 table

2021-08-10 Thread Andrew Jones
On Tue, Aug 10, 2021 at 12:25:07PM +0200, Eric Auger wrote:
> Hello Ard,
> On 8/10/21 11:36 AM, Ard Biesheuvel wrote:
> > On Tue, 10 Aug 2021 at 10:31, Eric Auger  wrote:
> >> ARM SBBR specification mandates DBG2 table (Debug Port Table 2).
> >> this latter allows to describe one or more debug ports.
> >>
> >> Generate an DBG2 table featuring a single debug port, the PL011.
> >>
> >> The DBG2 specification can be found at:
> >> https://docs.microsoft.com/en-us/windows-hardware/drivers/bringup/acpi-debug-port-table?redirectedfrom=MSDN
> >>
> > Have the legal issues around this table been resolved in the mean
> > time?
> I don't know exactly what they are. Adding Al and Jon in the loop they
> have more information about this.
> How did you resolve the issue for EDK2
> (DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/Dbg2Generator.c)?
> >  Also, any clue why this table is mandatory to begin with? The
> > SBBR has been very trigger happy lately with making things mandatory
> > that aren't truly required from a functional perspective.
> It seems there are kernel FW test suites that check all mandated tables
> are available and they currently fail for ARM virt.
> Indeed from a function pov, I don't know much about its usage on ARM.

There's also a bug with getting console output on tty0 with graphical VMs

https://bugzilla.redhat.com/show_bug.cgi?id=1661288

Discussion that includes DBG2 as a possible solution starts around comment
47. I just skimmed the BZ again though and there doesn't appear to be a
clear consensus that DBG2 is the solution.

Thanks,
drew

> 
> Maybe the SBBR spec should not flag the DBG2 as mandatory and test
> suites shall be updated. I think this should be clarified at ARM then,
> all the more so if there are legal issues as its spec is owned by Microsoft?
> 
> Thanks
> 
> Eric
> >
> >
> >> Signed-off-by: Eric Auger 
> >>
> >> ---
> >>
> >> Tested by comparing the content with the table generated
> >> by EDK2 along with the SBSA-REF machine (code generated by
> >> DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/Dbg2Generator.c).
> >>
> >> I reused the Generic Address Structure filled by QEMU in the SPCR, ie.
> >> bit_width = 8 and byte access. While EDK2 sets bit_width = 32 and
> >> dword access. Also the name exposed by acpica tools is different:
> >> 'COM0' in my case where '\_SB.COM0' in SBSA-REF case?
> >> ---
> >>  hw/arm/virt-acpi-build.c| 77 -
> >>  include/hw/acpi/acpi-defs.h | 50 
> >>  2 files changed, 126 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
> >> index 037cc1fd82..35f27b41df 100644
> >> --- a/hw/arm/virt-acpi-build.c
> >> +++ b/hw/arm/virt-acpi-build.c
> >> @@ -563,6 +563,78 @@ build_gtdt(GArray *table_data, BIOSLinker *linker, 
> >> VirtMachineState *vms)
> >>   vms->oem_table_id);
> >>  }
> >>
> >> +#define ACPI_DBG2_PL011_UART_LENGTH 0x1000
> >> +
> >> +/* DBG2 */
> >> +static void
> >> +build_dbg2(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
> >> +{
> >> +int addr_offset, addrsize_offset, namespace_offset, namespace_length;
> >> +const MemMapEntry *uart_memmap = >memmap[VIRT_UART];
> >> +struct AcpiGenericAddress *base_address;
> >> +int dbg2_start = table_data->len;
> >> +AcpiDbg2Device *dbg2dev;
> >> +char name[] = "COM0";
> >> +AcpiDbg2Table *dbg2;
> >> +uint32_t *addr_size;
> >> +uint8_t *namespace;
> >> +
> >> +dbg2 = acpi_data_push(table_data, sizeof *dbg2);
> >> +dbg2->info_offset = sizeof *dbg2;
> >> +dbg2->info_count = 1;
> >> +
> >> +/* debug device info structure */
> >> +
> >> +dbg2dev = acpi_data_push(table_data, sizeof(AcpiDbg2Device));
> >> +
> >> +dbg2dev->revision = 0;
> >> +namespace_length = sizeof name;
> >> +dbg2dev->length = sizeof *dbg2dev + sizeof(struct AcpiGenericAddress) 
> >> +
> >> +  4 + namespace_length;
> >> +dbg2dev->register_count = 1;
> >> +
> >> +addr_offset = sizeof *dbg2dev;
> >> +addrsize_offset = addr_offset + sizeof(struct AcpiGenericAddress);
> >> +namespace_offset = addrsize_offset + 4;
> >> +
> >> +dbg2dev->namepath_length = cpu_to_le16(namespace_length);
> >> +dbg2dev->namepath_offset = cpu_to_le16(namespace_offset);
> >> +dbg2dev->oem_data_length = cpu_to_le16(0);
> >> +dbg2dev->oem_data_offset = cpu_to_le16(0); /* No OEM data is present 
> >> */
> >> +dbg2dev->port_type = cpu_to_le16(ACPI_DBG2_SERIAL_PORT);
> >> +dbg2dev->port_subtype = cpu_to_le16(ACPI_DBG2_ARM_PL011);
> >> +
> >> +dbg2dev->base_address_offset = cpu_to_le16(addr_offset);
> >> +dbg2dev->address_size_offset = cpu_to_le16(addrsize_offset);
> >> +
> >> +/*
> >> + * variable length content:
> >> + * BaseAddressRegister[1]
> >> + * AddressSize[1]
> >> + * NamespaceString[1]
> >> + */
> >> +
> >> +base_address = acpi_data_push(table_data,
> 

Re: [PATCH v3 1/3] target-arm: cpu64: Add support for Fujitsu A64FX

2021-08-10 Thread Andrew Jones
On Tue, Aug 10, 2021 at 08:23:39AM +, ishii.shuuic...@fujitsu.com wrote:
> 
> Thanks for your comments.
> 
> Before reposting the fix patch series,
> based on your comments and the v3 1/3 patch,
> we have considered the following fixes.
> 
> If you have any comments on the fixes, please let us know.
> 
> ---
> 
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index 9f0a5f84d5..84ebca731a 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -2145,6 +2145,7 @@ enum arm_features {
>  ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
>  ARM_FEATURE_M_MAIN, /* M profile Main Extension */
>  ARM_FEATURE_V8_1M, /* M profile extras only in v8.1M and later */
> +ARM_FEATURE_A64FX, /* Fujitsu A64FX processor */
>  };
> 
>  static inline int arm_feature(CPUARMState *env, int feature)
> diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
> index 612644941b..62dcb6a919 100644
> --- a/target/arm/cpu64.c
> +++ b/target/arm/cpu64.c
> @@ -248,6 +248,21 @@ static void aarch64_a72_initfn(Object *obj)
>  define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo);
>  }
> 
> +static void a64fx_cpu_set_sve(ARMCPU *cpu)
> +{
> +/* Suppport of A64FX's vector length are 128,256 and 512byte only */

Missing spaces in text and s/byte/bit/

> +bitmap_zero(cpu->sve_vq_map, ARM_MAX_VQ);
> +bitmap_zero(cpu->sve_vq_init, ARM_MAX_VQ);
> +set_bit(0, cpu->sve_vq_map); /* 128byte */
> +set_bit(0, cpu->sve_vq_init);
> +set_bit(1, cpu->sve_vq_map); /* 256byte */
> +set_bit(1, cpu->sve_vq_init);
> +set_bit(3, cpu->sve_vq_map); /* 512byte */
> +set_bit(3, cpu->sve_vq_init);

For all the comments in the above function s/byte/bit/

> +cpu->sve_max_vq = find_last_bit(cpu->sve_vq_map, ARM_MAX_VQ) + 1;
> +

Extra blank line

> +}
>  void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
>  {
>  /*
> @@ -448,6 +463,10 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
> 
>  /* From now on sve_max_vq is the actual maximum supported length. */
>  cpu->sve_max_vq = max_vq;
> +
> +   if(arm_feature(>env, ARM_FEATURE_A64FX)) {
> +a64fx_cpu_set_sve(cpu);
> +}

Bad indentation and spacing, but I don't think this is the right place
for this. I wouldn't even let ARM_FEATURE_A64FX enter
arm_cpu_sve_finalize, since we know it doesn't support sve cpu properties.
While it's ugly wherever we put it, since we have to special case it, I
think it's less ugly at the callsite

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 2866dd765882..225800ec361c 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1350,10 +1350,14 @@ void arm_cpu_finalize_features(ARMCPU *cpu, Error 
**errp)
 Error *local_err = NULL;
 
 if (arm_feature(>env, ARM_FEATURE_AARCH64)) {
-arm_cpu_sve_finalize(cpu, _err);
-if (local_err != NULL) {
-error_propagate(errp, local_err);
-return;
+if (arm_feature(>env, ARM_FEATURE_A64FX)) {
+a64fx_cpu_set_sve(cpu);
+} else {
+arm_cpu_sve_finalize(cpu, _err);
+if (local_err != NULL) {
+error_propagate(errp, local_err);
+return;
+}
 }
 
 /*

>  }
> 
>  static void cpu_max_get_sve_max_vq(Object *obj, Visitor *v, const char *name,
> @@ -852,6 +871,7 @@ static void aarch64_a64fx_initfn(Object *obj)
>  ARMCPU *cpu = ARM_CPU(obj);
> 
>  cpu->dtb_compatible = "arm,a64fx";
> +set_feature(>env, ARM_FEATURE_A64FX);
>  set_feature(>env, ARM_FEATURE_V8);
>  set_feature(>env, ARM_FEATURE_NEON);
>  set_feature(>env, ARM_FEATURE_GENERIC_TIMER);
> @@ -884,10 +904,6 @@ static void aarch64_a64fx_initfn(Object *obj)
>  cpu->gic_vpribits = 5;
>  cpu->gic_vprebits = 5;
>  /* TODO:  Add A64FX specific HPC extension registers */
> -
> -aarch64_add_sve_properties(obj);
> -object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_max_vq,
> -cpu_max_set_sve_max_vq, NULL, NULL);
>  }
> 
>  static const ARMCPUInfo aarch64_cpus[] = {

Otherwise looks OK to me.

Thanks,
drew

> 
> ---
> 
> Best regards.
> 
> 
> > -Original Message-
> > From: Andrew Jones 
> > Sent: Thursday, August 5, 2021 8:25 PM
> > To: Ishii, Shuuichirou 
> > Cc: peter.mayd...@linaro.org; qemu-...@nongnu.org; qemu-devel@nongnu.org
> > Subject: Re: [PATCH v3 1/3] target-arm: cpu64: Add support for Fujitsu A64FX
> > 
> > On Thu, Aug 05, 2021 at 04:30:43PM +0900, Shuuichirou Ishii wrote:
> > > Add a definition for the Fujitsu A64FX processor.
> > >
> > &g

Re: [PATCH v3 1/3] target-arm: cpu64: Add support for Fujitsu A64FX

2021-08-05 Thread Andrew Jones
On Thu, Aug 05, 2021 at 04:30:43PM +0900, Shuuichirou Ishii wrote:
> Add a definition for the Fujitsu A64FX processor.
> 
> The A64FX processor does not implement the AArch32 Execution state,
> so there are no associated AArch32 Identification registers.
> 
> Signed-off-by: Shuuichirou Ishii 
> ---
>  target/arm/cpu64.c | 44 
>  1 file changed, 44 insertions(+)
> 
> diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
> index c690318a9b..612644941b 100644
> --- a/target/arm/cpu64.c
> +++ b/target/arm/cpu64.c
> @@ -847,10 +847,54 @@ static void aarch64_max_initfn(Object *obj)
>  cpu_max_set_sve_max_vq, NULL, NULL);
>  }
>  
> +static void aarch64_a64fx_initfn(Object *obj)
> +{
> +ARMCPU *cpu = ARM_CPU(obj);
> +
> +cpu->dtb_compatible = "arm,a64fx";
> +set_feature(>env, ARM_FEATURE_V8);
> +set_feature(>env, ARM_FEATURE_NEON);
> +set_feature(>env, ARM_FEATURE_GENERIC_TIMER);
> +set_feature(>env, ARM_FEATURE_AARCH64);
> +set_feature(>env, ARM_FEATURE_EL2);
> +set_feature(>env, ARM_FEATURE_EL3);
> +set_feature(>env, ARM_FEATURE_PMU);
> +cpu->midr = 0x461f0010;
> +cpu->revidr = 0x;
> +cpu->ctr = 86668006;
> +cpu->reset_sctlr = 0x3180;
> +cpu->isar.id_aa64pfr0 =   0x00010111; /* No RAS Extensions */
> +cpu->isar.id_aa64pfr1 = 0x;
> +cpu->isar.id_aa64dfr0 = 0x10305408;
> +cpu->isar.id_aa64dfr1 = 0x;
> +cpu->id_aa64afr0 = 0x;
> +cpu->id_aa64afr1 = 0x;
> +cpu->isar.id_aa64mmfr0 = 0x1122;
> +cpu->isar.id_aa64mmfr1 = 0x11212100;
> +cpu->isar.id_aa64mmfr2 = 0x1011;
> +cpu->isar.id_aa64isar0 = 0x10211120;
> +cpu->isar.id_aa64isar1 = 0x00010001;
> +cpu->isar.id_aa64zfr0 = 0x;
> +cpu->clidr = 0x8023;
> +cpu->ccsidr[0] = 0x7007e01c; /* 64KB L1 dcache */
> +cpu->ccsidr[1] = 0x2007e01c; /* 64KB L1 icache */
> +cpu->ccsidr[2] = 0x70ffe07c; /* 8MB L2 cache */
> +cpu->dcz_blocksize = 6; /* 256 bytes */
> +cpu->gic_num_lrs = 4;
> +cpu->gic_vpribits = 5;
> +cpu->gic_vprebits = 5;
> +/* TODO:  Add A64FX specific HPC extension registers */
> +
> +aarch64_add_sve_properties(obj);
> +object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_max_vq,
> +cpu_max_set_sve_max_vq, NULL, NULL);

I'm not a huge fan of the sve-max-vq property since it's not a good idea
to use it with KVM, because it's not explicit enough for migration[1]. I
realize the a64fx cpu type will likely never be used with KVM, but since
sve-max-vq isn't necessary[2], than I would avoid propagating it to
another cpu type. Finally, if you want the a64fx cpu model to represent
the current a64fx cpu, then don't you want to explicitly set the supported
vector lengths[3] and deny the user the option to change them? You could
do that by directly setting the vq map and not adding the sve properties.

[1] With KVM, sve-max-vq only tells you the maximum vq, but it won't tell
you that the host doesn't support non-power-of-2 vector lengths. So you
don't get an explicit vector length list on the command line. Being
explicit is the only safe way to migrate (see
docs/system/arm/cpu-features.rst:"SVE CPU Property Recommendations").

[2] If a shorthand is desired for specifying vector lengths, then just
use a single sve property. For example, sve-max-vq=4 and sve512=on
are identical (but keep [1] in mind).

[3] a64fx only support 128, 256, and 512 bit vector lengths, afaik.

Thanks,
drew

> +}
> +
>  static const ARMCPUInfo aarch64_cpus[] = {
>  { .name = "cortex-a57", .initfn = aarch64_a57_initfn },
>  { .name = "cortex-a53", .initfn = aarch64_a53_initfn },
>  { .name = "cortex-a72", .initfn = aarch64_a72_initfn },
> +{ .name = "a64fx",  .initfn = aarch64_a64fx_initfn },
>  { .name = "max",.initfn = aarch64_max_initfn },
>  };
>  
> -- 
> 2.27.0
> 
> 




Re: [PATCH for-6.2 v4 14/14] tests/unit: Add a unit test for smp parsing

2021-08-03 Thread Andrew Jones
On Tue, Aug 03, 2021 at 04:05:27PM +0800, Yanan Wang wrote:
> Add a QEMU unit test for the parsing of given SMP configuration.
> Since all the parsing logic is in generic function smp_parse(),
> this test passes different SMP configurations to the function
> and compare the parsing result with what is expected.
> 
> In the test, all possible collections of the topology parameters
> and the corresponding expected results are listed, including the
> valid and invalid ones.
> 
> The preference of sockets over cores and the preference of cores
> over sockets, and the support of multi-dies are also considered.
> 
> Signed-off-by: Yanan Wang 
> ---
>  MAINTAINERS |   1 +
>  tests/unit/meson.build  |   1 +
>  tests/unit/test-smp-parse.c | 892 
>  3 files changed, 894 insertions(+)
>  create mode 100644 tests/unit/test-smp-parse.c
>

Reviewed-by: Andrew Jones 




Re: [PATCH for-6.2 v4 13/14] machine: Split out the smp parsing code

2021-08-03 Thread Andrew Jones
On Tue, Aug 03, 2021 at 04:05:26PM +0800, Yanan Wang wrote:
> We are going to introduce an unit test for the parser smp_parse()
> in hw/core/machine.c, but now machine.c is only built in softmmu.
> 
> In order to solve the build dependency on the smp parsing code and
> avoid building unrelated stuff for the unit tests, move the related
> code from machine.c into a new common file, i.e., machine-smp.c.
> 
> Signed-off-by: Yanan Wang 
> ---
>  MAINTAINERS   |   1 +
>  hw/core/machine-smp.c | 199 ++
>  hw/core/machine.c | 177 -
>  hw/core/meson.build   |   1 +
>  include/hw/boards.h   |   1 +
>  5 files changed, 202 insertions(+), 177 deletions(-)
>  create mode 100644 hw/core/machine-smp.c
>

Reviewed-by: Andrew Jones 




Re: [PATCH for-6.2 v4 12/14] machine: Put all sanity-check in the generic SMP parser

2021-08-03 Thread Andrew Jones
On Tue, Aug 03, 2021 at 04:05:25PM +0800, Yanan Wang wrote:
> Put both sanity-check of the input SMP configuration and sanity-check
> of the output SMP configuration uniformly in the generic parser. Then
> machine_set_smp() will become cleaner, also all the invalid scenarios
> can be tested only by calling the parser.
> 
> Signed-off-by: Yanan Wang 
> ---
>  hw/core/machine.c | 63 +++
>  1 file changed, 31 insertions(+), 32 deletions(-)
>

Reviewed-by: Andrew Jones 




Re: [PATCH for-6.2 v4 01/14] machine: Minor refactor/cleanup for the smp parsers

2021-08-03 Thread Andrew Jones
On Tue, Aug 03, 2021 at 04:05:14PM +0800, Yanan Wang wrote:
> To pave the way for the functional improvement in later patches,
> make some refactor/cleanup for the smp parsers, including using
> local maxcpus instead of ms->smp.max_cpus in the calculation,
> defaulting dies to 0 initially like other members, cleanup the
> sanity check for dies.
> 
> No functional change intended.
> 
> Signed-off-by: Yanan Wang 
> ---
>  hw/core/machine.c | 19 +++
>  hw/i386/pc.c  | 23 ++-
>  2 files changed, 25 insertions(+), 17 deletions(-)
>

Reviewed-by: Andrew Jones 




Re: [PATCH for-6.2 v3 11/11] machine: Move smp_prefer_sockets to struct SMPCompatProps

2021-07-28 Thread Andrew Jones
On Wed, Jul 28, 2021 at 11:48:48AM +0800, Yanan Wang wrote:
> Now we have a common structure SMPCompatProps used to store information
> about SMP compatibility stuff, so we can also move smp_prefer_sockets
> there for cleaner code.
> 
> No functional change intended.
> 
> Signed-off-by: Yanan Wang 
> ---
>  hw/arm/virt.c  | 2 +-
>  hw/core/machine.c  | 2 +-
>  hw/i386/pc_piix.c  | 2 +-
>  hw/i386/pc_q35.c   | 2 +-
>  hw/ppc/spapr.c | 2 +-
>  hw/s390x/s390-virtio-ccw.c | 2 +-
>  include/hw/boards.h| 3 ++-
>  7 files changed, 8 insertions(+), 7 deletions(-)
> 
> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> index 7babea40dc..ae029680da 100644
> --- a/hw/arm/virt.c
> +++ b/hw/arm/virt.c
> @@ -2797,7 +2797,7 @@ static void virt_machine_6_1_options(MachineClass *mc)
>  {
>  virt_machine_6_2_options(mc);
>  compat_props_add(mc->compat_props, hw_compat_6_1, hw_compat_6_1_len);
> -mc->smp_prefer_sockets = true;
> +mc->smp_props.prefer_sockets = true;
>  }
>  DEFINE_VIRT_MACHINE(6, 1)
>  
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index 8f84e38e2e..61d1f643f4 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -834,7 +834,7 @@ static void smp_parse(MachineState *ms, SMPConfiguration 
> *config, Error **errp)
>  } else {
>  maxcpus = maxcpus > 0 ? maxcpus : cpus;
>  
> -if (mc->smp_prefer_sockets) {
> +if (mc->smp_props.prefer_sockets) {
>  /* prefer sockets over cores over threads before 6.2 */
>  if (sockets == 0) {
>  cores = cores > 0 ? cores : 1;
> diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
> index 9b811fc6ca..a60ebfc2c1 100644
> --- a/hw/i386/pc_piix.c
> +++ b/hw/i386/pc_piix.c
> @@ -432,7 +432,7 @@ static void pc_i440fx_6_1_machine_options(MachineClass *m)
>  m->is_default = false;
>  compat_props_add(m->compat_props, hw_compat_6_1, hw_compat_6_1_len);
>  compat_props_add(m->compat_props, pc_compat_6_1, pc_compat_6_1_len);
> -m->smp_prefer_sockets = true;
> +m->smp_props.prefer_sockets = true;
>  }
>  
>  DEFINE_I440FX_MACHINE(v6_1, "pc-i440fx-6.1", NULL,
> diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
> index 88efb7fde4..4b622ffb82 100644
> --- a/hw/i386/pc_q35.c
> +++ b/hw/i386/pc_q35.c
> @@ -372,7 +372,7 @@ static void pc_q35_6_1_machine_options(MachineClass *m)
>  m->alias = NULL;
>  compat_props_add(m->compat_props, hw_compat_6_1, hw_compat_6_1_len);
>  compat_props_add(m->compat_props, pc_compat_6_1, pc_compat_6_1_len);
> -m->smp_prefer_sockets = true;
> +m->smp_props.prefer_sockets = true;
>  }
>  
>  DEFINE_Q35_MACHINE(v6_1, "pc-q35-6.1", NULL,
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index a481fade51..efdea43c0d 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -4702,7 +4702,7 @@ static void 
> spapr_machine_6_1_class_options(MachineClass *mc)
>  {
>  spapr_machine_6_2_class_options(mc);
>  compat_props_add(mc->compat_props, hw_compat_6_1, hw_compat_6_1_len);
> -mc->smp_prefer_sockets = true;
> +mc->smp_props.prefer_sockets = true;
>  }
>  
>  DEFINE_SPAPR_MACHINE(6_1, "6.1", false);
> diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
> index b40e647883..5bdef9b4d7 100644
> --- a/hw/s390x/s390-virtio-ccw.c
> +++ b/hw/s390x/s390-virtio-ccw.c
> @@ -809,7 +809,7 @@ static void ccw_machine_6_1_class_options(MachineClass 
> *mc)
>  {
>  ccw_machine_6_2_class_options(mc);
>  compat_props_add(mc->compat_props, hw_compat_6_1, hw_compat_6_1_len);
> -mc->smp_prefer_sockets = true;
> +mc->smp_props.prefer_sockets = true;
>  }
>  DEFINE_CCW_MACHINE(6_1, "6.1", false);
>  
> diff --git a/include/hw/boards.h b/include/hw/boards.h
> index 72123f594d..23671a0f8f 100644
> --- a/include/hw/boards.h
> +++ b/include/hw/boards.h
> @@ -110,9 +110,11 @@ typedef struct {
>  
>  /**
>   * SMPCompatProps:
> + * @prefer_sockets - whether sockets is preferred over cores in smp parsing
>   * @dies_supported - whether dies is supported by the machine
>   */
>  typedef struct {
> +bool prefer_sockets;
>  bool dies_supported;
>  } SMPCompatProps;
>  
> @@ -250,7 +252,6 @@ struct MachineClass {
>  bool nvdimm_supported;
>  bool numa_mem_supported;
>  bool auto_enable_numa;
> -bool smp_prefer_sockets;
>  SMPCompatProps smp_props;
>  const char *default_ram_id;
>  
> -- 
> 2.19.1
>

 
Reviewed-by: Andrew Jones 




Re: [PATCH for-6.2 v3 09/11] machine: Make smp_parse generic enough for all arches

2021-07-28 Thread Andrew Jones
On Wed, Jul 28, 2021 at 10:38:57PM +0200, Andrew Jones wrote:
> On Wed, Jul 28, 2021 at 11:48:46AM +0800, Yanan Wang wrote:
> > @@ -248,6 +256,7 @@ struct MachineClass {
> >  bool numa_mem_supported;
> >  bool auto_enable_numa;
> >  bool smp_prefer_sockets;
> > +SMPCompatProps smp_props;
> >  const char *default_ram_id;
> >  
> >  HotplugHandler *(*get_hotplug_handler)(MachineState *machine,
> > -- 
> > 2.19.1
> >
> 
> What about putting smp_prefer_sockets in SMPCompatProps too (as
> prefer_sockets)?

Ah, I see patch 11/11 does that.

Thanks,
drew

> 
> Otherwise
> 
> Reviewed-by: Andrew Jones 




Re: [PATCH for-6.2 v3 10/11] machine: Remove smp_parse callback from MachineClass

2021-07-28 Thread Andrew Jones
On Wed, Jul 28, 2021 at 11:48:47AM +0800, Yanan Wang wrote:
> Now we have a generic smp parser for all arches, and there will
> not be any other arch specific ones, so let's remove the callback
> from MachineClass and call the parser directly.
> 
> Signed-off-by: Yanan Wang 
> ---
>  hw/core/machine.c   | 3 +--
>  include/hw/boards.h | 5 -
>  2 files changed, 1 insertion(+), 7 deletions(-)
> 
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index 76b6c3bc64..8f84e38e2e 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -934,7 +934,7 @@ static void machine_set_smp(Object *obj, Visitor *v, 
> const char *name,
>  goto out_free;
>  }
>  
> -mc->smp_parse(ms, config, errp);
> +smp_parse(ms, config, errp);
>  if (errp) {
>  goto out_free;
>  }
> @@ -963,7 +963,6 @@ static void machine_class_init(ObjectClass *oc, void 
> *data)
>  /* Default 128 MB as guest ram size */
>  mc->default_ram_size = 128 * MiB;
>  mc->rom_file_has_mr = true;
> -mc->smp_parse = smp_parse;
>  
>  /* numa node memory size aligned on 8MB by default.
>   * On Linux, each node's border has to be 8MB aligned
> diff --git a/include/hw/boards.h b/include/hw/boards.h
> index 0631900c08..72123f594d 100644
> --- a/include/hw/boards.h
> +++ b/include/hw/boards.h
> @@ -177,10 +177,6 @@ typedef struct {
>   *kvm-type may be NULL if it is not needed.
>   * @numa_mem_supported:
>   *true if '--numa node.mem' option is supported and false otherwise
> - * @smp_parse:
> - *The function pointer to hook different machine specific functions for
> - *parsing "smp-opts" from QemuOpts to MachineState::CpuTopology and more
> - *machine specific topology fields, such as smp_dies for PCMachine.
>   * @hotplug_allowed:
>   *If the hook is provided, then it'll be called for each device
>   *hotplug to check whether the device hotplug is allowed.  Return
> @@ -217,7 +213,6 @@ struct MachineClass {
>  void (*reset)(MachineState *state);
>  void (*wakeup)(MachineState *state);
>  int (*kvm_type)(MachineState *machine, const char *arg);
> -void (*smp_parse)(MachineState *ms, SMPConfiguration *config, Error 
> **errp);
>  
>  BlockInterfaceType block_default_type;
>  int units_per_default_bus;
> -- 
> 2.19.1
>

 
Reviewed-by: Andrew Jones 




Re: [PATCH for-6.2 v3 09/11] machine: Make smp_parse generic enough for all arches

2021-07-28 Thread Andrew Jones
On Wed, Jul 28, 2021 at 11:48:46AM +0800, Yanan Wang wrote:
> Currently the only difference between smp_parse and pc_smp_parse
> is the support of dies parameter and the related error reporting.
> With some arch compat variables like "bool dies_supported", we can
> make smp_parse generic enough for all arches and the PC specific
> one can be removed.
> 
> Making smp_parse() generic enough can reduce code duplication and
> ease the code maintenance, and also allows extending the topology
> with more arch specific members (e.g., clusters) in the future.
> 
> Suggested-by: Andrew Jones 
> Signed-off-by: Yanan Wang 
> ---
>  hw/core/machine.c   | 96 +++--
>  hw/i386/pc.c| 83 +--
>  include/hw/boards.h |  9 +
>  3 files changed, 93 insertions(+), 95 deletions(-)
> 
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index 9223ece3ea..76b6c3bc64 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -15,6 +15,7 @@
>  #include "qapi/qmp/qerror.h"
>  #include "sysemu/replay.h"
>  #include "qemu/units.h"
> +#include "qemu/cutils.h"
>  #include "hw/boards.h"
>  #include "hw/loader.h"
>  #include "qapi/error.h"
> @@ -744,20 +745,87 @@ void machine_set_cpu_numa_node(MachineState *machine,
>  }
>  }
>  
> +static char *cpu_topology_hierarchy(MachineState *ms)
> +{
> +MachineClass *mc = MACHINE_GET_CLASS(ms);
> +SMPCompatProps *smp_props = >smp_props;
> +char topo_msg[256] = "";
> +
> +/*
> + * Topology members should be ordered from the largest to the smallest.
> + * Concept of sockets/cores/threads is supported by default and will be
> + * reported in the hierarchy. Unsupported members will not be reported.
> + */
> +g_autofree char *sockets_msg = g_strdup_printf(
> +" * sockets (%u)", ms->smp.sockets);
> +pstrcat(topo_msg, sizeof(topo_msg), sockets_msg);
> +
> +if (smp_props->dies_supported) {
> +g_autofree char *dies_msg = g_strdup_printf(
> +" * dies (%u)", ms->smp.dies);
> +pstrcat(topo_msg, sizeof(topo_msg), dies_msg);
> +}
> +
> +g_autofree char *cores_msg = g_strdup_printf(
> +" * cores (%u)", ms->smp.cores);
> +pstrcat(topo_msg, sizeof(topo_msg), cores_msg);
> +
> +g_autofree char *threads_msg = g_strdup_printf(
> +" * threads (%u)", ms->smp.threads);
> +pstrcat(topo_msg, sizeof(topo_msg), threads_msg);
> +
> +return g_strdup_printf("%s", topo_msg + 3);
> +}
> +
> +/*
> + * smp_parse - Generic function used to parse the given SMP configuration
> + *
> + * A topology parameter must be omitted or specified equal to 1 if it's
> + * not supported by the machine. Concept of sockets/cores/threads is
> + * supported by default. Unsupported members will not be reported in
> + * the cpu topology hierarchy message.
> + *
> + * For compatibility, if omitted the arch-specific members (e.g. dies)
> + * will not be computed, but will directly default to 1 instead. This
> + * logic should also apply to future introduced ones.
> + *
> + * Omitted arch-neutral members, i.e., cpus/sockets/cores/threads/maxcpus
> + * will be computed based on the provided ones. When both maxcpus and cpus
> + * are omitted, maxcpus will be computed from the given parameters and cpus
> + * will be set equal to maxcpus. When only one of maxcpus and cpus is given
> + * then the omitted one will be set to its given counterpart's value.
> + * Both maxcpus and cpus may be specified, but maxcpus must be equal to or
> + * greater than cpus.
> + *
> + * In calculation of omitted sockets/cores/threads, we prefer sockets over
> + * cores over threads before 6.2, while preferring cores over sockets over
> + * threads since 6.2.
> + */
>  static void smp_parse(MachineState *ms, SMPConfiguration *config, Error 
> **errp)
>  {
>  MachineClass *mc = MACHINE_GET_CLASS(ms);
>  unsigned cpus= config->has_cpus ? config->cpus : 0;
>  unsigned sockets = config->has_sockets ? config->sockets : 0;
> +unsigned dies= config->has_dies ? config->dies : 0;
>  unsigned cores   = config->has_cores ? config->cores : 0;
>  unsigned threads = config->has_threads ? config->threads : 0;
>  unsigned maxcpus = config->has_maxcpus ? config->maxcpus : 0;
>  
> -if (config->has_dies && config->dies > 1) {
> +/*
> + * A topology parameter must be omitted or specified equal to 1,

Re: [PATCH for-6.2 v3 06/11] machine: Prefer cores over sockets in smp parsing since 6.2

2021-07-28 Thread Andrew Jones
  ccw_machine_6_2_class_options(mc);
>  compat_props_add(mc->compat_props, hw_compat_6_1, hw_compat_6_1_len);
> +mc->smp_prefer_sockets = true;
>  }
>  DEFINE_CCW_MACHINE(6_1, "6.1", false);
>  
> diff --git a/include/hw/boards.h b/include/hw/boards.h
> index 463a5514f9..2ae039b74f 100644
> --- a/include/hw/boards.h
> +++ b/include/hw/boards.h
> @@ -247,6 +247,7 @@ struct MachineClass {
>  bool nvdimm_supported;
>  bool numa_mem_supported;
>  bool auto_enable_numa;
> +bool smp_prefer_sockets;
>  const char *default_ram_id;
>  
>  HotplugHandler *(*get_hotplug_handler)(MachineState *machine,
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 0912236b4b..450f511ca7 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -234,7 +234,8 @@ SRST
>  Historically preference was given to the coarsest topology parameters
>  when computing missing values (ie sockets preferred over cores, which
>  were preferred over threads), however, this behaviour is considered
> -liable to change.
> +liable to change. Prior to 6.2 the preference was sockets over cores
> +over threads. Since 6.2 the preference is cores over sockets over 
> threads.
>  ERST
>  
>  DEF("numa", HAS_ARG, QEMU_OPTION_numa,
> -- 
> 2.19.1
>

 
Reviewed-by: Andrew Jones 




Re: [PATCH for-6.2 v3 04/11] machine: Improve the error reporting of smp parsing

2021-07-28 Thread Andrew Jones
On Wed, Jul 28, 2021 at 11:48:41AM +0800, Yanan Wang wrote:
> We have two requirements for a valid SMP configuration:
> the product of "sockets * cores * threads" must represent all the
> possible cpus, i.e., max_cpus, and then must include the initially
> present cpus, i.e., smp_cpus.
> 
> So we only need to ensure 1) "sockets * cores * threads == maxcpus"
> at first and then ensure 2) "maxcpus >= cpus". With a reasonable
> order of the sanity check, we can simplify the error reporting code.
> When reporting an error message we also report the exact value of
> each topology member to make users easily see what's going on.
> 
> Signed-off-by: Yanan Wang 
> ---
>  hw/core/machine.c | 22 +-
>  hw/i386/pc.c  | 24 ++--
>  2 files changed, 19 insertions(+), 27 deletions(-)
> 
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index 958e6e7107..e879163c3b 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -777,25 +777,21 @@ static void smp_parse(MachineState *ms, 
> SMPConfiguration *config, Error **errp)
>  maxcpus = maxcpus > 0 ? maxcpus : sockets * cores * threads;
>  cpus = cpus > 0 ? cpus : maxcpus;
>  
> -if (sockets * cores * threads < cpus) {
> -error_setg(errp, "cpu topology: "
> -   "sockets (%u) * cores (%u) * threads (%u) < "
> -   "smp_cpus (%u)",
> -   sockets, cores, threads, cpus);
> +if (sockets * cores * threads != maxcpus) {
> +error_setg(errp, "Invalid CPU topology: "
> +   "product of the hierarchy must match maxcpus: "
> +   "sockets (%u) * cores (%u) * threads (%u) "
> +   "!= maxcpus (%u)",
> +   sockets, cores, threads, maxcpus);
>  return;
>  }
>  
>  if (maxcpus < cpus) {
> -error_setg(errp, "maxcpus must be equal to or greater than smp");
> -return;
> -}
> -
> -if (sockets * cores * threads != maxcpus) {
>  error_setg(errp, "Invalid CPU topology: "
> +   "maxcpus must be equal to or greater than smp: "
> "sockets (%u) * cores (%u) * threads (%u) "
> -   "!= maxcpus (%u)",
> -   sockets, cores, threads,
> -   maxcpus);
> +   "== maxcpus (%u) < smp_cpus (%u)",
> +   sockets, cores, threads, maxcpus, cpus);
>  return;
>  }
>  
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index 9ad7ae5254..3e403a7129 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -747,25 +747,21 @@ static void pc_smp_parse(MachineState *ms, 
> SMPConfiguration *config, Error **err
>  maxcpus = maxcpus > 0 ? maxcpus : sockets * dies * cores * threads;
>  cpus = cpus > 0 ? cpus : maxcpus;
>  
> -if (sockets * dies * cores * threads < cpus) {
> -error_setg(errp, "cpu topology: "
> -   "sockets (%u) * dies (%u) * cores (%u) * threads (%u) < "
> -   "smp_cpus (%u)",
> -   sockets, dies, cores, threads, cpus);
> +if (sockets * cores * threads != maxcpus) {
> +error_setg(errp, "Invalid CPU topology: "
> +   "product of the hierarchy must match maxcpus: "
> +   "sockets (%u) * dies (%u) * cores (%u) * threads (%u) "
> +   "!= maxcpus (%u)",
> +   sockets, dies, cores, threads, maxcpus);
>  return;
>  }
>  
>  if (maxcpus < cpus) {
> -error_setg(errp, "maxcpus must be equal to or greater than smp");
> -return;
> -}
> -
> -if (sockets * dies * cores * threads != maxcpus) {
> -error_setg(errp, "Invalid CPU topology deprecated: "
> +error_setg(errp, "Invalid CPU topology: "
> +   "maxcpus must be equal to or greater than smp: "
> "sockets (%u) * dies (%u) * cores (%u) * threads (%u) "
> -   "!= maxcpus (%u)",
> -   sockets, dies, cores, threads,
> -   maxcpus);
> +   "== maxcpus (%u) < smp_cpus (%u)",
> +   sockets, dies, cores, threads, maxcpus, cpus);
>  return;
>  }
>  
> -- 
> 2.19.1
>

 
Reviewed-by: Andrew Jones 




Re: [PATCH for-6.2 v3 03/11] machine: Set the value of cpus to match maxcpus if it's omitted

2021-07-28 Thread Andrew Jones
eads == 0) {
> +threads = maxcpus / (sockets * dies * cores);
> +}
>  }
>  
> +maxcpus = maxcpus > 0 ? maxcpus : sockets * dies * cores * threads;
> +cpus = cpus > 0 ? cpus : maxcpus;
> +
>  if (sockets * dies * cores * threads < cpus) {
>  error_setg(errp, "cpu topology: "
> "sockets (%u) * dies (%u) * cores (%u) * threads (%u) < "
> diff --git a/qemu-options.hx b/qemu-options.hx
> index e077aa80bf..0912236b4b 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -210,9 +210,14 @@ SRST
>  Simulate a SMP system with '\ ``n``\ ' CPUs initially present on
>  the machine type board. On boards supporting CPU hotplug, the optional
>  '\ ``maxcpus``\ ' parameter can be set to enable further CPUs to be
> -added at runtime. If omitted the maximum number of CPUs will be
> -set to match the initial CPU count. Both parameters are subject to
> -an upper limit that is determined by the specific machine type chosen.
> +added at runtime. When both parameters are omitted, the maximum number
> +of CPUs will be calculated from the provided topology members and the
> +initial CPU count will match the maximum number. When only one of them
> +is given then the omitted one will be set to its counterpart's value.
> +Both parameters may be specified, but the maximum number of CPUs must
> +equal to or greater than the initial CPU count. Both parameters are

be equal to

> +subject to an upper limit that is determined by the specific machine
> +type chosen.
>  
>  To control reporting of CPU topology information, the number of sockets,
>  dies per socket, cores per die, and threads per core can be specified.
> -- 
> 2.19.1
>

Otherwise

Reviewed-by: Andrew Jones 




Re: [PATCH for-6.2 v3 01/11] machine: Minor refactor/cleanup for the smp parsers

2021-07-28 Thread Andrew Jones
On Wed, Jul 28, 2021 at 11:48:38AM +0800, Yanan Wang wrote:
> To pave the way for the functional improvement in later patches,
> make some refactor/cleanup for the smp parsers, including using
> local maxcpus instead of ms->smp.max_cpus in the calculation,
> defaulting dies to 0 initially like other members, cleanup the
> sanity check for dies.
> 
> No functional change intended.
> 
> Signed-off-by: Yanan Wang 
> ---
>  hw/core/machine.c | 19 +++
>  hw/i386/pc.c  | 23 ++-
>  2 files changed, 25 insertions(+), 17 deletions(-)
> 
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index e1533dfc47..ffc0629854 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -747,9 +747,11 @@ static void smp_parse(MachineState *ms, SMPConfiguration 
> *config, Error **errp)
>  unsigned sockets = config->has_sockets ? config->sockets : 0;
>  unsigned cores   = config->has_cores ? config->cores : 0;
>  unsigned threads = config->has_threads ? config->threads : 0;
> +unsigned maxcpus = config->has_maxcpus ? config->maxcpus : 0;
>  
> -if (config->has_dies && config->dies != 0 && config->dies != 1) {
> +if (config->has_dies && config->dies > 1) {
>  error_setg(errp, "dies not supported by this machine's CPU 
> topology");
> +return;
>  }
>  
>  /* compute missing values, prefer sockets over cores over threads */
> @@ -760,8 +762,8 @@ static void smp_parse(MachineState *ms, SMPConfiguration 
> *config, Error **errp)
>  sockets = sockets > 0 ? sockets : 1;
>  cpus = cores * threads * sockets;
>  } else {
> -ms->smp.max_cpus = config->has_maxcpus ? config->maxcpus : cpus;
> -sockets = ms->smp.max_cpus / (cores * threads);
> +maxcpus = maxcpus > 0 ? maxcpus : cpus;
> +sockets = maxcpus / (sockets * cores);

Should be divided by (cores * threads) like before.

Thanks,
drew




Re: [PATCH v2 3/3] target/arm: Add sve-default-vector-length cpu property

2021-07-26 Thread Andrew Jones
On Mon, Jul 26, 2021 at 08:33:52AM -1000, Richard Henderson wrote:
> On 7/26/21 4:59 AM, Andrew Jones wrote:
> > > +SVE User-mode Default Vector Length Property
> > > +
> > > +
> > > +For qemu-aarch64, the cpu property `sve-default-vector-length=N` is
> > > +defined to mirror the Linux kernel parameter file
> > > +`/proc/sys/abi/sve_default_vector_length`.  The default length, `N`,
> > > +is in units of bytes and must be between 16 and 8192.
> > 
> > Hmm. If a user inputs anything greater than 256, then won't it get
> > silently reduced to 256?
> 
> Yes.
> 
> > > +If not specified, the default vector length is 64.
> > > +
> > > +If the default length is larger than the maximum vector length enabled
> > > +with `sve` properties, the actual vector length will be reduced.
> > 
> > Here it's pointed out that the default may be reduced, but it implies that
> > that only happens if an sve property is also given. Won't users wonder
> > why they're only getting vectors that are 256 bytes large even when they
> > ask for more?
> 
> I guess adding that 256 is the maximum length supported by qemu should be 
> sufficient?
>

Works for me.

Thanks,
drew 




Re: [PATCH v2 0/3] target/arm: Add sve-default-vector-length cpu property

2021-07-26 Thread Andrew Jones
On Mon, Jul 26, 2021 at 01:42:45PM +0100, Peter Maydell wrote:
> On Fri, 23 Jul 2021 at 21:34, Richard Henderson
>  wrote:
> >
> > This is intended to resolve #482.
> >
> > Changes for v2:
> >   * Split out length bounding fix to new patch.
> >   * Use byte units for sve-default-vector-length.
> >   * Support undocumented -1 "maximum".
> >   * Add documentation.
> 
> I'm going to apply this to target-arm.next with the following
> docs tweak squashed into patch 3:
> 
> diff --git a/docs/system/arm/cpu-features.rst 
> b/docs/system/arm/cpu-features.rst
> index 4ff36cc83f0..7b97df442aa 100644
> --- a/docs/system/arm/cpu-features.rst
> +++ b/docs/system/arm/cpu-features.rst
> @@ -379,11 +379,14 @@ example's (1), (4), and (6) exhibit recommended
> uses of the properties.
>  SVE User-mode Default Vector Length Property
>  
> 
> -For qemu-aarch64, the cpu property `sve-default-vector-length=N` is
> +For qemu-aarch64, the cpu property ``sve-default-vector-length=N`` is
>  defined to mirror the Linux kernel parameter file
> -`/proc/sys/abi/sve_default_vector_length`.  The default length, `N`,
> -is in units of bytes and must be between 16 and 8192.
> +``/proc/sys/abi/sve_default_vector_length``.  The default length, ``N``,
> +is in units of bytes and must be between 16 and 8192.
>  If not specified, the default vector length is 64.
> 
>  If the default length is larger than the maximum vector length enabled
> -with `sve` properties, the actual vector length will be reduced.
> +with ``sve`` properties, the actual vector length will be reduced.
> +
> +If this property is set to ``-1`` then the default vector length
> +is set to the maximum possible length.

This file is full of single backtick usage. Isn't it better to stay
consistent? Or do we need a patch that converts all the rest now?

Thanks,
drew

> 
> thanks
> -- PMM
> 




Re: [PATCH v2 3/3] target/arm: Add sve-default-vector-length cpu property

2021-07-26 Thread Andrew Jones
On Fri, Jul 23, 2021 at 10:33:44AM -1000, Richard Henderson wrote:
> Mirror the behavour of /proc/sys/abi/sve_default_vector_length
> under the real linux kernel.  We have no way of passing along
> a real default across exec like the kernel can, but this is a
> decent way of adjusting the startup vector length of a process.
> 
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/482
> Signed-off-by: Richard Henderson 
> ---
>  docs/system/arm/cpu-features.rst | 11 ++
>  target/arm/cpu.h |  5 +++
>  target/arm/cpu.c | 14 ++--
>  target/arm/cpu64.c   | 60 
>  4 files changed, 88 insertions(+), 2 deletions(-)
> 
> diff --git a/docs/system/arm/cpu-features.rst 
> b/docs/system/arm/cpu-features.rst
> index c455442eaf..4ff36cc83f 100644
> --- a/docs/system/arm/cpu-features.rst
> +++ b/docs/system/arm/cpu-features.rst
> @@ -376,3 +376,14 @@ verbose command lines.  However, the recommended way to 
> select vector
>  lengths is to explicitly enable each desired length.  Therefore only
>  example's (1), (4), and (6) exhibit recommended uses of the properties.
>  
> +SVE User-mode Default Vector Length Property
> +
> +
> +For qemu-aarch64, the cpu property `sve-default-vector-length=N` is
> +defined to mirror the Linux kernel parameter file
> +`/proc/sys/abi/sve_default_vector_length`.  The default length, `N`,
> +is in units of bytes and must be between 16 and 8192.  

Hmm. If a user inputs anything greater than 256, then won't it get
silently reduced to 256?

> +If not specified, the default vector length is 64.
> +
> +If the default length is larger than the maximum vector length enabled
> +with `sve` properties, the actual vector length will be reduced.

Here it's pointed out that the default may be reduced, but it implies that
that only happens if an sve property is also given. Won't users wonder
why they're only getting vectors that are 256 bytes large even when they
ask for more?

Thanks,
drew

> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index be9a4dceae..9f0a5f84d5 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -1006,6 +1006,11 @@ struct ARMCPU {
>  /* Used to set the maximum vector length the cpu will support.  */
>  uint32_t sve_max_vq;
>  
> +#ifdef CONFIG_USER_ONLY
> +/* Used to set the default vector length at process start. */
> +uint32_t sve_default_vq;
> +#endif
> +
>  /*
>   * In sve_vq_map each set bit is a supported vector length of
>   * (bit-number + 1) * 16 bytes, i.e. each bit number + 1 is the vector
> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> index 752b15bb79..2866dd7658 100644
> --- a/target/arm/cpu.c
> +++ b/target/arm/cpu.c
> @@ -201,7 +201,8 @@ static void arm_cpu_reset(DeviceState *dev)
>  env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 16, 2, 3);
>  /* with reasonable vector length */
>  if (cpu_isar_feature(aa64_sve, cpu)) {
> -env->vfp.zcr_el[1] = MIN(cpu->sve_max_vq - 1, 3);
> +env->vfp.zcr_el[1] =
> +aarch64_sve_zcr_get_valid_len(cpu, cpu->sve_default_vq - 1);
>  }
>  /*
>   * Enable TBI0 but not TBI1.
> @@ -1051,7 +1052,16 @@ static void arm_cpu_initfn(Object *obj)
>  QLIST_INIT(>pre_el_change_hooks);
>  QLIST_INIT(>el_change_hooks);
>  
> -#ifndef CONFIG_USER_ONLY
> +#ifdef CONFIG_USER_ONLY
> +# ifdef TARGET_AARCH64
> +/*
> + * The linux kernel defaults to 512-bit vectors, when sve is supported.
> + * See documentation for /proc/sys/abi/sve_default_vector_length, and
> + * our corresponding sve-default-vector-length cpu property.
> + */
> +cpu->sve_default_vq = 4;
> +# endif
> +#else
>  /* Our inbound IRQ and FIQ lines */
>  if (kvm_enabled()) {
>  /* VIRQ and VFIQ are unused with KVM but we add them to maintain
> diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
> index c7a1626bec..c690318a9b 100644
> --- a/target/arm/cpu64.c
> +++ b/target/arm/cpu64.c
> @@ -559,6 +559,59 @@ static void cpu_arm_set_sve(Object *obj, bool value, 
> Error **errp)
>  cpu->isar.id_aa64pfr0 = t;
>  }
>  
> +#ifdef CONFIG_USER_ONLY
> +/* Mirror linux /proc/sys/abi/sve_default_vector_length. */
> +static void cpu_arm_set_sve_default_vec_len(Object *obj, Visitor *v,
> +const char *name, void *opaque,
> +Error **errp)
> +{
> +ARMCPU *cpu = ARM_CPU(obj);
> +int32_t default_len, default_vq, remainder;
> +
> +if (!visit_type_int32(v, name, _len, errp)) {
> +return;
> +}
> +
> +/* Undocumented, but the kernel allows -1 to indicate "maximum". */
> +if (default_len == -1) {
> +cpu->sve_default_vq = ARM_MAX_VQ;
> +return;
> +}
> +
> +default_vq = default_len / 16;
> +remainder = default_len % 16;
> +
> +/*
> + * Note that 

Re: [PATCH for-6.1 v2] machine: Disallow specifying topology parameters as zero

2021-07-22 Thread Andrew Jones
On Thu, Jul 22, 2021 at 11:43:26PM +0800, Yanan Wang wrote:
> In the SMP configuration, we should either specify a topology
> parameter with a reasonable value (equal to or greater than 1)
> or just leave it omitted and QEMU will calculate its value.
> Configurations which explicitly specify the topology parameters
> as zero like "sockets=0" are meaningless, so disallow them.
> 
> However, the commit 1e63fe685804d
> (machine: pass QAPI struct to mc->smp_parse) has documented that
> '0' has the same semantics as omitting a parameter in the qapi
> comment for SMPConfiguration. So this patch fixes the doc and
> also adds the corresponding sanity check in the smp parsers.
> 
> Suggested-by: Andrew Jones 
> Signed-off-by: Yanan Wang 
> ---
>  hw/core/machine.c | 14 ++
>  qapi/machine.json |  6 +++---
>  qemu-options.hx   | 12 +++-
>  3 files changed, 24 insertions(+), 8 deletions(-)

With Daniel's suggested changes for v3

Reviewed-by: Andrew Jones 




Re: [PATCH for-6.2 v2 04/11] machine: Use the computed parameters to calculate omitted cpus

2021-07-22 Thread Andrew Jones
On Thu, Jul 22, 2021 at 10:59:11PM +0800, wangyanan (Y) wrote:
> Ok. If we remove the rounding, then the calculation code has to be modified
> to be like the following. We have to separately consider the case that cpus
> and maxcpus are both omitted (e.g. -smp sockets=16).
> 
> maxcpus = maxcpus > 0 ? maxcpus : cpus;
> 
> if (cpus == 0 && maxcpus == 0) {
>     sockets = sockets > 0 ? sockets : 1;
>     cores = cores > 0 ? cores : 1;
>     threads = threads > 0 ? threads : 1;
>     goto cal;
> }
> 
> if (sockets == 0) {
> ...
> } else if (cores == 0) {
> ...
> } else if (threads == 0) {
> ...
> }
> 
> cal:
> maxcpus = maxcpus > 0 ? maxcpus : sockets * cores * threads;
> cpus = cpus > 0 ? cpus : maxcpus;

Whatever works, but hopefully you can avoid an ugly goto.

Thanks,
drew




Re: [PATCH for-6.1 0/1] machine: Disallow specifying topology parameters as zero

2021-07-22 Thread Andrew Jones
On Thu, Jul 22, 2021 at 08:02:16AM +0200, Cornelia Huck wrote:
> On Thu, Jul 22 2021, Yanan Wang  wrote:
> 
> > In the SMP configuration, we should either specify a topology
> > parameter with a reasonable value (equal to or greater than 1)
> > or just leave it omitted and QEMU will calculate its value.
> > Configurations which explicitly specify the topology parameters
> > as zero like "sockets=0" are meaningless, so disallow them.
> >
> > However; the commit 1e63fe685804d
> > (machine: pass QAPI struct to mc->smp_parse) has documented that
> > '0' has the same semantics as omitting a parameter in the qapi
> > comment for SMPConfiguration. So this patch fixes the doc and
> > also adds the corresponding sanity check in the smp parsers.
> 
> Are we expecting any real users to have used that 'parameter=0'
> behaviour? I expect that libvirt and other management software already
> did the right thing; unfortunately, sometimes weird configuration lines
> tend to persist in search results.

I understand this concern. I think the only documentation we had prior to
commit 1e63fe685804 was

DEF("smp", HAS_ARG, QEMU_OPTION_smp,
"-smp 
[cpus=]n[,maxcpus=cpus][,cores=cores][,threads=threads][,dies=dies][,sockets=sockets]\n"
"set the number of CPUs to 'n' [default=1]\n"
"maxcpus= maximum number of total cpus, including\n"
"offline CPUs for hotplug, etc\n"
"cores= number of CPU cores on one socket (for PC, it's on 
one die)\n"
"threads= number of threads on one CPU core\n"
"dies= number of CPU dies on one socket (for PC only)\n"
"sockets= number of discrete sockets in the system\n",
QEMU_ARCH_ALL)
SRST
``-smp 
[cpus=]n[,cores=cores][,threads=threads][,dies=dies][,sockets=sockets][,maxcpus=maxcpus]``
Simulate an SMP system with n CPUs. On the PC target, up to 255 CPUs
are supported. On Sparc32 target, Linux limits the number of usable
CPUs to 4. For the PC target, the number of cores per die, the
number of threads per cores, the number of dies per packages and the
total number of sockets can be specified. Missing values will be
computed. If any on the three values is given, the total number of
CPUs n can be omitted. maxcpus specifies the maximum number of
hotpluggable CPUs.
ERST

This doesn't mention zero inputs and even implies non-zero inputs.

I'm not sure if we need to worry about the odd command line that used zero
for some parameters. What do you think?

Thanks,
drew


> 
> >
> > This patch originly comes form [1], and it was suggested that
> > this patch fixing the doc should be sent for 6.1 to avoid a
> > deprecation process in the future.
> >
> > [1] https://lore.kernel.org/qemu-devel/ypwsthpiza3mf...@redhat.com/
> >
> > Yanan Wang (1):
> >   machine: Disallow specifying topology parameters as zero
> >
> >  hw/core/machine.c | 30 ++
> >  hw/i386/pc.c  | 33 -
> >  qapi/machine.json |  6 +++---
> >  3 files changed; 49 insertions(+); 20 deletions(-)
> 




Re: [PATCH for-6.2 v2 11/11] tests/unit: Add a unit test for smp parsing

2021-07-22 Thread Andrew Jones
On Thu, Jul 22, 2021 at 02:15:18PM +0800, wangyanan (Y) wrote:
> On 2021/7/20 2:57, Andrew Jones wrote:
> > On Mon, Jul 19, 2021 at 11:20:43AM +0800, Yanan Wang wrote:
> > > Add a QEMU unit test for the parsing of given SMP configuration.
> > > Since all the parsing logic is in generic function smp_parse(),
> > > this test passes diffenent SMP configurations to the function
> > > and compare the parsing result with what is expected.
> > > 
> > > In the test, all possible collections of the topology parameters
> > > and the corressponding expected results are listed, including the
> > > valid and invalid ones.
> > > 
> > > The preference of sockets over cores and the preference of cores
> > > over sockets, and the support of multi-dies are also considered.
> > > 
> > > Signed-off-by: Yanan Wang 
> > > ---
> > >   MAINTAINERS |1 +
> > >   tests/unit/meson.build  |1 +
> > >   tests/unit/test-smp-parse.c | 1117 +++
> > >   3 files changed, 1119 insertions(+)
> > >   create mode 100644 tests/unit/test-smp-parse.c
> > > 
> > > diff --git a/MAINTAINERS b/MAINTAINERS
> > > index 70633e3bf4..160dba2e57 100644
> > > --- a/MAINTAINERS
> > > +++ b/MAINTAINERS
> > > @@ -1636,6 +1636,7 @@ F: include/hw/boards.h
> > >   F: include/hw/core/cpu.h
> > >   F: include/hw/cpu/cluster.h
> > >   F: include/sysemu/numa.h
> > > +F: tests/unit/test-smp-parse.c
> > >   T: git https://gitlab.com/ehabkost/qemu.git machine-next
> > >   Xtensa Machines
> > > diff --git a/tests/unit/meson.build b/tests/unit/meson.build
> > > index 3e0504dd21..694a924627 100644
> > > --- a/tests/unit/meson.build
> > > +++ b/tests/unit/meson.build
> > > @@ -44,6 +44,7 @@ tests = {
> > > 'test-uuid': [],
> > > 'ptimer-test': ['ptimer-test-stubs.c', meson.source_root() / 
> > > 'hw/core/ptimer.c'],
> > > 'test-qapi-util': [],
> > > +  'test-smp-parse': [qom, meson.source_root() / 'hw/core/machine-smp.c'],
> > >   }
> > >   if have_system or have_tools
> > > diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c
> > > new file mode 100644
> > > index 00..bc1d324c3d
> > > --- /dev/null
> > > +++ b/tests/unit/test-smp-parse.c
> > > @@ -0,0 +1,1117 @@
> > > +/*
> > > + * SMP parsing unit-tests
> > > + *
> > > + * Copyright (C) 2021, Huawei, Inc.
> > > + *
> > > + * Authors:
> > > + *  Yanan Wang 
> > > + *
> > > + * This work is licensed under the terms of the GNU LGPL, version 2.1 or 
> > > later.
> > > + * See the COPYING.LIB file in the top-level directory.
> > > + */
> > > +
> > > +#include "qemu/osdep.h"
> > > +#include "qom/object.h"
> > > +#include "qemu/module.h"
> > > +#include "qapi/error.h"
> > > +
> > > +#include "hw/boards.h"
> > > +
> > > +#define T true
> > > +#define F false
> > > +
> > > +/**
> > > + * SMPTestData:
> > > + * @config - the given SMP configuration for parsing
> > > + * @should_be_valid - whether the given configuration is supposed to be 
> > > valid
> > > + * @expect - the CPU topology info expected to be parsed out
> > > + */
> > > +typedef struct SMPTestData {
> > > +SMPConfiguration config;
> > > +bool should_be_valid;
> > Long way to say 'valid'.
> Indeed..., "valid" should be enough.
> > > +CpuTopology expect;
> > > +} SMPTestData;
> > > +
> > > +/* the specific machine type info for this test */
> > > +static const TypeInfo smp_machine_info = {
> > > +.name = TYPE_MACHINE,
> > > +.parent = TYPE_OBJECT,
> > > +.class_size = sizeof(MachineClass),
> > > +.instance_size = sizeof(MachineState),
> > > +};
> > > +
> > > +/*
> > > + * prefer sockets over cores over threads before 6.2.
> > > + * all possible SMP configurations and the corressponding expected 
> > > outputs
> > corresponding (please run spell check on your commit messages)
> > 
> Ok, I missed the check.
> > > + * are listed for testing, including the valid and invalid ones.
> > > + */
> > > +static struct SMPTestData prefer_sockets[] = {
> > > +{
> >

Re: [PATCH for-6.2 v2 10/11] machine: Split out the smp parsing code

2021-07-22 Thread Andrew Jones
On Thu, Jul 22, 2021 at 02:24:03PM +0800, wangyanan (Y) wrote:
> On 2021/7/20 1:20, Andrew Jones wrote:
> > On Mon, Jul 19, 2021 at 11:20:42AM +0800, Yanan Wang wrote:
> > > We are going to introduce an unit test for the parser smp_parse()
> > > in hw/core/machine.c, but now machine.c is only built in softmmu.
> > > 
> > > In order to solve the build dependency on the smp parsing code and
> > > avoid building unrelated stuff for the unit tests, move the related
> > > code from machine.c into a new common file, i.e., machine-smp.c.
> > > 
> > > Signed-off-by: Yanan Wang 
> > > ---
> > >   MAINTAINERS   |   1 +
> > >   hw/core/machine-smp.c | 124 ++
> > >   hw/core/machine.c | 109 -
> > >   hw/core/meson.build   |   1 +
> > >   include/hw/boards.h   |   1 +
> > >   5 files changed, 127 insertions(+), 109 deletions(-)
> > >   create mode 100644 hw/core/machine-smp.c
> > > 
> > > diff --git a/MAINTAINERS b/MAINTAINERS
> > > index 9100f9a043..70633e3bf4 100644
> > > --- a/MAINTAINERS
> > > +++ b/MAINTAINERS
> > > @@ -1626,6 +1626,7 @@ F: cpu.c
> > >   F: hw/core/cpu.c
> > >   F: hw/core/machine-qmp-cmds.c
> > >   F: hw/core/machine.c
> > > +F: hw/core/machine-smp.c

I just noticed that the spacing in this change might not be right.

> > >   F: hw/core/null-machine.c
> > >   F: hw/core/numa.c
> > >   F: hw/cpu/cluster.c
> > > diff --git a/hw/core/machine-smp.c b/hw/core/machine-smp.c
> > > new file mode 100644
> > > index 00..6a00cfe44a
> > > --- /dev/null
> > > +++ b/hw/core/machine-smp.c
> > > @@ -0,0 +1,124 @@
> > > +/*
> > > + * QEMU Machine (related to SMP configuration)
> > > + *
> > > + * Copyright (C) 2014 Red Hat Inc
> > > + *
> > > + * Authors:
> > > + *   Marcel Apfelbaum 
> > This header was obviously copy+pasted without being updated.
> Yes, the header was kept unchanged.
> 
> But actually I'm not completely sure which field should be updated. :)
> Should I add "Copyright (C) 2021, Huawei, Inc." and also the authorship
> "Yanan Wang " behind the existing ones
> or just replace them?

I see what you were attempting to do now. You were deriving this new work
(a source file) from an existing work and you wanted to preserve the
original copyright and authorship. It's not so simple with these types of
projects though. In this case, smp_parse wasn't even part of the original
machine.c file (it came over with commit 6f479566a87d). I think it's
pretty common for these projects to just put whatever your preferred
(or your employer's preferred) copyright/authorship on new files. So, I'd
just replace the fields.

I'm interested in what others have to say about this though.

Thanks,
drew


> > > + *
> > > + * This work is licensed under the terms of the GNU GPL, version 2 or 
> > > later.
> > > + * See the COPYING file in the top-level directory.
> > > + */
> > > +
> > > +#include "qemu/osdep.h"
> > > +#include "hw/boards.h"
> > > +#include "qapi/error.h"
> > > +
> > > +/*
> > > + * smp_parse - Generic function used to parse the given SMP configuration
> > > + *
> > > + * The topology parameters must be specified equal to or great than one
> > > + * or just omitted, explicit configuration like "cpus=0" is not allowed.
> > > + * The omitted parameters will be calculated based on the provided ones.
> > > + *
> > > + * maxcpus will default to the value of cpus if omitted and will be used
> > > + * to compute the missing sockets/cores/threads. cpus will be calculated
> > > + * from the computed parametrs if omitted.
> > > + *
> > > + * In calculation of omitted arch-netural sockets/cores/threads, we 
> > > prefer
> > > + * sockets over cores over threads before 6.2, while prefer cores over
> > > + * sockets over threads since 6.2 on. The arch-specific dies will 
> > > directly
> > > + * default to 1 if omitted.
> > > + */
> > > +void smp_parse(MachineState *ms, SMPConfiguration *config, Error **errp)
> > > +{
> > > +MachineClass *mc = MACHINE_GET_CLASS(ms);
> > > +unsigned cpus= config->has_cpus ? config->cpus : 0;
> > > +unsigned sockets = config->has_sockets ? config->sockets : 0;
> > > +unsigned d

Re: [PATCH for-6.2 v2 05/11] machine: Improve the error reporting of smp parsing

2021-07-22 Thread Andrew Jones
On Thu, Jul 22, 2021 at 04:10:32PM +0800, wangyanan (Y) wrote:
> On 2021/7/20 0:53, Andrew Jones wrote:
> > On Mon, Jul 19, 2021 at 11:20:37AM +0800, Yanan Wang wrote:
> > > We totally have two requirements for a valid SMP configuration:
> > s/totally//
> > 
> > > the sum of "sockets * dies * cores * threads" must represent all
> > the product
> > 
> > > the possible cpus, i.e., max_cpus, and must include the initial
> > > present cpus, i.e., smp_cpus.
> > > 
> > > We only need to ensure "sockets * dies * cores * threads == maxcpus"
> > > at first and then ensure "sockets * dies * cores * threads >= cpus".
> > Or, "maxcpus >= cpus"
> > 
> > > With a reasonable order of the sanity-check, we can simplify the
> > > error reporting code.
> > > 
> > > Signed-off-by: Yanan Wang 
> > > ---
> > >   hw/core/machine.c | 25 ++---
> > >   1 file changed, 10 insertions(+), 15 deletions(-)
> > > 
> > > diff --git a/hw/core/machine.c b/hw/core/machine.c
> > > index 668f0a1553..8b4d07d3fc 100644
> > > --- a/hw/core/machine.c
> > > +++ b/hw/core/machine.c
> > > @@ -788,21 +788,6 @@ static void smp_parse(MachineState *ms, 
> > > SMPConfiguration *config, Error **errp)
> > >   cpus = cpus > 0 ? cpus : sockets * dies * cores * threads;
> > >   maxcpus = maxcpus > 0 ? maxcpus : cpus;
> > > -if (sockets * dies * cores * threads < cpus) {
> > > -g_autofree char *dies_msg = g_strdup_printf(
> > > -mc->smp_dies_supported ? " * dies (%u)" : "", dies);
> > > -error_setg(errp, "cpu topology: "
> > > -   "sockets (%u)%s * cores (%u) * threads (%u) < "
> > > -   "smp_cpus (%u)",
> > > -   sockets, dies_msg, cores, threads, cpus);
> > > -return;
> > > -}
> > > -
> > > -if (maxcpus < cpus) {
> > > -error_setg(errp, "maxcpus must be equal to or greater than smp");
> > > -return;
> > > -}
> > This may be redundant when determining a valid config, but by checking it
> > separately we can provide a more useful error message.
> Yes, this message is more useful. Can we also report the exact values of the
> parameters within this error message ?

sure

> How about the following:
> 
> if (sockets * cores * threads != maxcpus) {
>     error_setg("product of the topology must be equal to maxcpus"
>    "sockets (%u) * cores (%u) * threads (%u)"
>    "!= maxcpus (%u)",
>    sockets, cores, threads, maxcpus);
> return;
> }
> 
> if (maxcpus < cpus) {
>     error_setg("maxcpus must be equal to or greater than smp:"
>    "sockets (%u) * cores (%u) * threads (%u)"
>    "== maxcpus (%u) < smp_cpus (%u)",
>    sockets, cores, threads, maxcpus, cpus);
> return;
> }

OK by me

Thanks,
drew

> 
> Thanks,
> Yanan
> .
> > > -
> > >   if (sockets * dies * cores * threads != maxcpus) {
> > >   g_autofree char *dies_msg = g_strdup_printf(
> > >   mc->smp_dies_supported ? " * dies (%u)" : "", dies);
> > > @@ -814,6 +799,16 @@ static void smp_parse(MachineState *ms, 
> > > SMPConfiguration *config, Error **errp)
> > >   return;
> > >   }
> > > +if (sockets * dies * cores * threads < cpus) {
> > > +g_autofree char *dies_msg = g_strdup_printf(
> > > +mc->smp_dies_supported ? " * dies (%u)" : "", dies);
> > > +error_setg(errp, "Invalid CPU topology: "
> > > +   "sockets (%u)%s * cores (%u) * threads (%u) < "
> > > +   "smp_cpus (%u)",
> > > +   sockets, dies_msg, cores, threads, cpus);
> > > +return;
> > > +}
> > > +
> > >   ms->smp.cpus = cpus;
> > >   ms->smp.sockets = sockets;
> > >   ms->smp.dies = dies;
> > > -- 
> > > 2.19.1
> > > 
> > I'm not sure we need this patch.
> > 
> > Thanks,
> > drew
> > 
> > .
> 




Re: [PATCH for-6.2 v2 04/11] machine: Use the computed parameters to calculate omitted cpus

2021-07-22 Thread Andrew Jones
On Thu, Jul 22, 2021 at 12:42:55PM +0800, wangyanan (Y) wrote:
> On 2021/7/20 0:42, Andrew Jones wrote:
> > On Mon, Jul 19, 2021 at 11:20:36AM +0800, Yanan Wang wrote:
> > > Currently we directly calculate the omitted cpus based on the already
> > > provided parameters. This makes some cmdlines like:
> > >-smp maxcpus=16
> > >-smp sockets=2,maxcpus=16
> > >-smp sockets=2,dies=2,maxcpus=16
> > >-smp sockets=2,cores=4,maxcpus=16
> > > not work. We should probably use the computed paramters to calculate
> > > cpus when maxcpus is provided while cpus is omitted, which will make
> > > above configs start to work.
> > > 
> > > Note: change in this patch won't affect any existing working cmdlines
> > > but allows more incomplete configs to be valid.
> > > 
> > > Signed-off-by: Yanan Wang 
> > > ---
> > >   hw/core/machine.c | 17 +
> > >   1 file changed, 9 insertions(+), 8 deletions(-)
> > > 
> > > diff --git a/hw/core/machine.c b/hw/core/machine.c
> > > index c9f15b15a5..668f0a1553 100644
> > > --- a/hw/core/machine.c
> > > +++ b/hw/core/machine.c
> > > @@ -767,26 +767,27 @@ static void smp_parse(MachineState *ms, 
> > > SMPConfiguration *config, Error **errp)
> > >   return;
> > >   }
> > > -/* compute missing values, prefer sockets over cores over threads */
> > >   maxcpus = maxcpus > 0 ? maxcpus : cpus;
> > > -if (cpus == 0) {
> > > -sockets = sockets > 0 ? sockets : 1;
> > > -cores = cores > 0 ? cores : 1;
> > > -threads = threads > 0 ? threads : 1;
> > > -cpus = sockets * dies * cores * threads;
> > > -maxcpus = maxcpus > 0 ? maxcpus : cpus;
> > > -} else if (sockets == 0) {
> > > +/* compute missing values, prefer sockets over cores over threads */
> > > +if (sockets == 0) {
> > >   cores = cores > 0 ? cores : 1;
> > >   threads = threads > 0 ? threads : 1;
> > >   sockets = maxcpus / (dies * cores * threads);
> > > +sockets = sockets > 0 ? sockets : 1;
> > >   } else if (cores == 0) {
> > >   threads = threads > 0 ? threads : 1;
> > >   cores = maxcpus / (sockets * dies * threads);
> > > +cores = cores > 0 ? cores : 1;
> > >   } else if (threads == 0) {
> > >   threads = maxcpus / (sockets * dies * cores);
> > > +threads = threads > 0 ? threads : 1;
> > >   }
> > I didn't think we wanted this rounding which this patch adds back into
> > cores and threads and now also sockets.
> Firstly, I think we can agree that with or without the rounding, the invalid
> configs will still be reported as invalid. So the only difference is in the
> err
> message (either report 0 or 1 of a fractional parameter). :)

An error message that says the inputs produced a fractional parameter
would be even better. If the code gets too hairy because some parameters
may be zero and without additional checks we'd risk divide by zeros,
then maybe we should output ("fractional %s", param_name) and exit at the
same places we're currently rounding up.

> 
> I added back the rounding because this patch indeed need it, we start
> to use the computed parameters to calculate cpus, so we have to ensure
> that the computed parameters are at least 1. If both cpus and maxcpus
> are omitted (e.g. -smp sockets=16), without the rounding we will get
> zeroed cpus and maxcpus, and with the rounding we will get valid result
> like "cpus=16,sockets=16,cores=1,threads=1,maxcpus=16".
> 
> If a "0" or "1" in the error message doesn't make so much difference as
> assumed for the error reporting, I suggest that we probably can keep the
> rounding which makes the parser code concise.
> > > +/* use the computed parameters to calculate the omitted cpus */
> > > +cpus = cpus > 0 ? cpus : sockets * dies * cores * threads;
> > > +maxcpus = maxcpus > 0 ? maxcpus : cpus;
> > It doesn't really matter, but I think I'd rather write this like
> > 
> >   maxcpus = maxcpus > 0 ? maxcpus : sockets * dies * cores * threads;
> >   cpus = cpus > 0 ? cpus : maxcpus;
> Yes, there is no functional difference. But I think maybe we'd better keep
> some consistence with the "maxcpus = maxcpus > 0 ? maxcpus : cpus"
> at top this function and also with the smp doc in qemu-option.hx i.e.
> "If omitted the maximum number of CPUs will be set to match the initial
> CPU count" ?

I won't argue it too much, but I think we should be thinking about maxcpus
more than cpus if we're thinking about cpu topologies. I'd rather have
users keep in mind that whatever their topology generates is the max and
if they don't want to expose that many cpus to the guest then they should
provide an additional, smaller number 'cpus'. To get that mindset we may
need to adjust the documentation.

Thanks,
drew




Re: [PATCH for-6.2 v2 11/11] tests/unit: Add a unit test for smp parsing

2021-07-19 Thread Andrew Jones
On Mon, Jul 19, 2021 at 11:20:43AM +0800, Yanan Wang wrote:
> Add a QEMU unit test for the parsing of given SMP configuration.
> Since all the parsing logic is in generic function smp_parse(),
> this test passes diffenent SMP configurations to the function
> and compare the parsing result with what is expected.
> 
> In the test, all possible collections of the topology parameters
> and the corressponding expected results are listed, including the
> valid and invalid ones.
> 
> The preference of sockets over cores and the preference of cores
> over sockets, and the support of multi-dies are also considered.
> 
> Signed-off-by: Yanan Wang 
> ---
>  MAINTAINERS |1 +
>  tests/unit/meson.build  |1 +
>  tests/unit/test-smp-parse.c | 1117 +++
>  3 files changed, 1119 insertions(+)
>  create mode 100644 tests/unit/test-smp-parse.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 70633e3bf4..160dba2e57 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1636,6 +1636,7 @@ F: include/hw/boards.h
>  F: include/hw/core/cpu.h
>  F: include/hw/cpu/cluster.h
>  F: include/sysemu/numa.h
> +F: tests/unit/test-smp-parse.c
>  T: git https://gitlab.com/ehabkost/qemu.git machine-next
>  
>  Xtensa Machines
> diff --git a/tests/unit/meson.build b/tests/unit/meson.build
> index 3e0504dd21..694a924627 100644
> --- a/tests/unit/meson.build
> +++ b/tests/unit/meson.build
> @@ -44,6 +44,7 @@ tests = {
>'test-uuid': [],
>'ptimer-test': ['ptimer-test-stubs.c', meson.source_root() / 
> 'hw/core/ptimer.c'],
>'test-qapi-util': [],
> +  'test-smp-parse': [qom, meson.source_root() / 'hw/core/machine-smp.c'],
>  }
>  
>  if have_system or have_tools
> diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c
> new file mode 100644
> index 00..bc1d324c3d
> --- /dev/null
> +++ b/tests/unit/test-smp-parse.c
> @@ -0,0 +1,1117 @@
> +/*
> + * SMP parsing unit-tests
> + *
> + * Copyright (C) 2021, Huawei, Inc.
> + *
> + * Authors:
> + *  Yanan Wang 
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2.1 or 
> later.
> + * See the COPYING.LIB file in the top-level directory.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qom/object.h"
> +#include "qemu/module.h"
> +#include "qapi/error.h"
> +
> +#include "hw/boards.h"
> +
> +#define T true
> +#define F false
> +
> +/**
> + * SMPTestData:
> + * @config - the given SMP configuration for parsing
> + * @should_be_valid - whether the given configuration is supposed to be valid
> + * @expect - the CPU topology info expected to be parsed out
> + */
> +typedef struct SMPTestData {
> +SMPConfiguration config;
> +bool should_be_valid;

Long way to say 'valid'.

> +CpuTopology expect;
> +} SMPTestData;
> +
> +/* the specific machine type info for this test */
> +static const TypeInfo smp_machine_info = {
> +.name = TYPE_MACHINE,
> +.parent = TYPE_OBJECT,
> +.class_size = sizeof(MachineClass),
> +.instance_size = sizeof(MachineState),
> +};
> +
> +/*
> + * prefer sockets over cores over threads before 6.2.
> + * all possible SMP configurations and the corressponding expected outputs

corresponding (please run spell check on your commit messages)


> + * are listed for testing, including the valid and invalid ones.
> + */
> +static struct SMPTestData prefer_sockets[] = {
> +{
> +/* config: no smp configuration provided
> + * expect: cpus=1,sockets=1,dies=1,cores=1,threads=1,maxcpus=1 */
> +.config = (SMPConfiguration) { F, 0, F, 0, F, 0, F, 0, F, 0, F, 0 },

SMPConfiguration and CpuTopology have named fields so we could drop the
'expect: ...' comment line and instead do

 {
  /* no configuration provided */ 
  .config = { .has_cpus = F, .has_maxcpus = F, ... },
  .valid = T,
  .expect = { .sockets = 1, .cores = 1, ... },
 }, {
  ...
 }

which may be easier to maintain. OTOH, the concise form this approach has
is also nice. I don't think you should need the casts in the assignments
though.

> +.should_be_valid = true,
> +.expect = (CpuTopology) { 1, 1, 1, 1, 1, 1 },
> +}, {
> +/* config: -smp 8
> + * expect: cpus=8,sockets=8,dies=1,cores=1,threads=1,maxcpus=8 */
> +.config = (SMPConfiguration) { T, 8, F, 0, F, 0, F, 0, F, 0, F, 0 },
> +.should_be_valid = true,
> +.expect = (CpuTopology) { 8, 8, 1, 1, 1, 8 },
> +}, {
> +/* config: -smp sockets=2
> + * expect: cpus=2,sockets=2,dies=1,cores=1,threads=1,maxcpus=2 */
> +.config = (SMPConfiguration) { F, 0, T, 2, F, 0, F, 0, F, 0, F, 0 },
> +.should_be_valid = true,
> +.expect = (CpuTopology) { 2, 2, 1, 1, 1, 2 },
> +}, {
> +/* config: -smp cores=4
> + * expect: cpus=4,sockets=1,dies=1,cores=4,threads=1,maxcpus=4 */
> +.config = (SMPConfiguration) { F, 0, F, 0, F, 0, T, 4, F, 0, F, 0 },
> +.should_be_valid = true,
> +.expect = (CpuTopology) { 4, 

Re: [PATCH for-6.2 v2 10/11] machine: Split out the smp parsing code

2021-07-19 Thread Andrew Jones
s before 6.2 */
> -if (mc->smp_prefer_sockets) {
> -if (sockets == 0) {
> -cores = cores > 0 ? cores : 1;
> -threads = threads > 0 ? threads : 1;
> -sockets = maxcpus / (dies * cores * threads);
> -sockets = sockets > 0 ? sockets : 1;
> -} else if (cores == 0) {
> -threads = threads > 0 ? threads : 1;
> -cores = maxcpus / (sockets * dies * threads);
> -cores = cores > 0 ? cores : 1;
> -} else if (threads == 0) {
> -threads = maxcpus / (sockets * dies * cores);
> -threads = threads > 0 ? threads : 1;
> -}
> -/* prefer cores over sockets over threads since 6.2 */
> -} else {
> -if (cores == 0) {
> -sockets = sockets > 0 ? sockets : 1;
> -threads = threads > 0 ? threads : 1;
> -cores = maxcpus / (sockets * dies * threads);
> -cores = cores > 0 ? cores : 1;
> -} else if (sockets == 0) {
> -threads = threads > 0 ? threads : 1;
> -sockets = maxcpus / (dies * cores * threads);
> -sockets = sockets > 0 ? sockets : 1;
> -} else if (threads == 0) {
> -threads = maxcpus / (sockets * dies * cores);
> -threads = threads > 0 ? threads : 1;
> -}
> -}
> -
> -/* use the computed parameters to calculate the omitted cpus */
> -cpus = cpus > 0 ? cpus : sockets * dies * cores * threads;
> -maxcpus = maxcpus > 0 ? maxcpus : cpus;
> -
> -if (sockets * dies * cores * threads != maxcpus) {
> -g_autofree char *dies_msg = g_strdup_printf(
> -mc->smp_dies_supported ? " * dies (%u)" : "", dies);
> -error_setg(errp, "Invalid CPU topology: "
> -   "sockets (%u)%s * cores (%u) * threads (%u) "
> -   "!= maxcpus (%u)",
> -   sockets, dies_msg, cores, threads,
> -   maxcpus);
> -return;
> -}
> -
> -if (sockets * dies * cores * threads < cpus) {
> -g_autofree char *dies_msg = g_strdup_printf(
> -mc->smp_dies_supported ? " * dies (%u)" : "", dies);
> -error_setg(errp, "Invalid CPU topology: "
> -   "sockets (%u)%s * cores (%u) * threads (%u) < "
> -   "smp_cpus (%u)",
> -   sockets, dies_msg, cores, threads, cpus);
> -return;
> -}
> -
> -ms->smp.cpus = cpus;
> -ms->smp.sockets = sockets;
> -ms->smp.dies = dies;
> -ms->smp.cores = cores;
> -ms->smp.threads = threads;
> -ms->smp.max_cpus = maxcpus;
> -}
> -
>  static void machine_get_smp(Object *obj, Visitor *v, const char *name,
>  void *opaque, Error **errp)
>  {
> diff --git a/hw/core/meson.build b/hw/core/meson.build
> index 18f44fb7c2..6d727c7742 100644
> --- a/hw/core/meson.build
> +++ b/hw/core/meson.build
> @@ -14,6 +14,7 @@ hwcore_files = files(
>  )
>  
>  common_ss.add(files('cpu-common.c'))
> +common_ss.add(files('machine-smp.c'))
>  common_ss.add(when: 'CONFIG_FITLOADER', if_true: files('loader-fit.c'))
>  common_ss.add(when: 'CONFIG_GENERIC_LOADER', if_true: 
> files('generic-loader.c'))
>  common_ss.add(when: ['CONFIG_GUEST_LOADER', fdt], if_true: 
> files('guest-loader.c'))
> diff --git a/include/hw/boards.h b/include/hw/boards.h
> index 12ab0f5968..071eec1e74 100644
> --- a/include/hw/boards.h
> +++ b/include/hw/boards.h
> @@ -34,6 +34,7 @@ HotpluggableCPUList 
> *machine_query_hotpluggable_cpus(MachineState *machine);
>  void machine_set_cpu_numa_node(MachineState *machine,
> const CpuInstanceProperties *props,
> Error **errp);
> +void smp_parse(MachineState *ms, SMPConfiguration *config, Error **errp);
>  
>  /**
>   * machine_class_allow_dynamic_sysbus_dev: Add type to list of valid devices
> -- 
> 2.19.1
>

Otherwise

Reviewed-by: Andrew Jones 




Re: [PATCH for-6.2 v2 08/11] machine: Use ms instead of global current_machine in sanity-check

2021-07-19 Thread Andrew Jones
On Mon, Jul 19, 2021 at 11:20:40AM +0800, Yanan Wang wrote:
> In the sanity-check of smp_cpus and max_cpus against mc in function
> machine_set_smp(), we are now using ms->smp.max_cpus for the check
> but using current_machine->smp.max_cpus in the error message.
> Tweak this by uniformly using the local ms.
> 
> Signed-off-by: Yanan Wang 
> ---
>  hw/core/machine.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index c074425015..f5620c4d34 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -896,7 +896,7 @@ static void machine_set_smp(Object *obj, Visitor *v, 
> const char *name,
>  } else if (ms->smp.max_cpus > mc->max_cpus) {
>  error_setg(errp, "Invalid SMP CPUs %d. The max CPUs "
> "supported by machine '%s' is %d",
> -   current_machine->smp.max_cpus,
> +   ms->smp.max_cpus,
> mc->name, mc->max_cpus);
>  }
>  
> -- 
> 2.19.1
>

Reviewed-by: Andrew Jones 




Re: [PATCH for-6.2 v2 07/11] machine: Prefer cores over sockets in smp parsing since 6.2

2021-07-19 Thread Andrew Jones
On Mon, Jul 19, 2021 at 11:20:39AM +0800, Yanan Wang wrote:
> In the real SMP hardware topology world, it's much more likely that
> we have high cores-per-socket counts and few sockets totally. While
> the current preference of sockets over cores in smp parsing results
> in a virtual cpu topology with low cores-per-sockets counts and a
> large number of sockets, which is just contrary to the real world.
> 
> Given that it is better to make the virtual cpu topology be more
> reflective of the real world and also for the sake of compatibility,
> we start to prefer cores over sockets over threads in smp parsing
> since machine type 6.2 for different arches.
> 
> In this patch, a boolean "smp_prefer_sockets" is added, and we only
> enable the old preference on older machines and enable the new one
> since type 6.2 for all arches by using the machine compat mechanism.
> 
> Suggested-by: Daniel P. Berrange 
> Signed-off-by: Yanan Wang 
> ---
>  hw/arm/virt.c  |  1 +
>  hw/core/machine.c  | 59 +-
>  hw/i386/pc_piix.c  |  1 +
>  hw/i386/pc_q35.c   |  1 +
>  hw/ppc/spapr.c |  1 +
>  hw/s390x/s390-virtio-ccw.c |  1 +
>  include/hw/boards.h|  1 +
>  qemu-options.hx|  4 ++-
>  8 files changed, 55 insertions(+), 14 deletions(-)
> 
> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> index 01165f7f53..7babea40dc 100644
> --- a/hw/arm/virt.c
> +++ b/hw/arm/virt.c
> @@ -2797,6 +2797,7 @@ static void virt_machine_6_1_options(MachineClass *mc)
>  {
>  virt_machine_6_2_options(mc);
>  compat_props_add(mc->compat_props, hw_compat_6_1, hw_compat_6_1_len);
> +mc->smp_prefer_sockets = true;
>  }
>  DEFINE_VIRT_MACHINE(6, 1)
>  
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index 63439c4a6d..c074425015 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -744,6 +744,22 @@ void machine_set_cpu_numa_node(MachineState *machine,
>  }
>  }
>  
> +/*
> + * smp_parse - Generic function used to parse the given SMP configuration
> + *
> + * The topology parameters must be specified equal to or great than one
> + * or just omitted, explicit configuration like "cpus=0" is not allowed.
> + * The omitted parameters will be calculated based on the provided ones.
> + *
> + * maxcpus will default to the value of cpus if omitted and will be used
> + * to compute the missing sockets/cores/threads. cpus will be calculated
> + * from the computed parametrs if omitted.

parameters

Or how about something like this:

When both maxcpus and cpus are omitted maxcpus will be calculated from the
given parameters and cpus will be set equal to maxcpus. When only one of
maxcpus and cpus is given then the omitted one will be set to its given
counterpart's value. Both maxcpus and cpus may be specified, but cpus must
be less than or equal to maxcpus.

> + *
> + * In calculation of omitted arch-netural sockets/cores/threads, we prefer
> + * sockets over cores over threads before 6.2, while prefer cores over

while preferring

> + * sockets over threads since 6.2 on. The arch-specific dies will directly

s/on//

> + * default to 1 if omitted.
> + */
>  static void smp_parse(MachineState *ms, SMPConfiguration *config, Error 
> **errp)
>  {
>  MachineClass *mc = MACHINE_GET_CLASS(ms);
> @@ -772,19 +788,36 @@ static void smp_parse(MachineState *ms, 
> SMPConfiguration *config, Error **errp)
>  
>  maxcpus = maxcpus > 0 ? maxcpus : cpus;
>  
> -/* compute missing values, prefer sockets over cores over threads */
> -if (sockets == 0) {
> -cores = cores > 0 ? cores : 1;
> -threads = threads > 0 ? threads : 1;
> -sockets = maxcpus / (dies * cores * threads);
> -sockets = sockets > 0 ? sockets : 1;
> -} else if (cores == 0) {
> -threads = threads > 0 ? threads : 1;
> -cores = maxcpus / (sockets * dies * threads);
> -cores = cores > 0 ? cores : 1;
> -} else if (threads == 0) {
> -threads = maxcpus / (sockets * dies * cores);
> -threads = threads > 0 ? threads : 1;
> +/* prefer sockets over cores over threads before 6.2 */
> +if (mc->smp_prefer_sockets) {

please move the comment into the if, so...

> +if (sockets == 0) {
> +cores = cores > 0 ? cores : 1;
> +threads = threads > 0 ? threads : 1;
> +sockets = maxcpus / (dies * cores * threads);
> +sockets = sockets > 0 ? sockets : 1;
> +} else if (cores == 0) {
> +threads = threads > 0 ? threads : 1;
> +cores = maxcpus / (sockets * dies * threads);
> +cores = cores > 0 ? cores : 1;
> +} else if (threads == 0) {
> +threads = maxcpus / (sockets * dies * cores);
> +threads = threads > 0 ? threads : 1;
> +}
> +/* prefer cores over sockets over threads since 6.2 */

...here we can put the comment in the else

> +} else {
> +if (cores == 0) {
> 

Re: [PATCH for-6.2 v2 06/11] hw: Add compat machines for 6.2

2021-07-19 Thread Andrew Jones
On Mon, Jul 19, 2021 at 11:20:38AM +0800, Yanan Wang wrote:
> Add 6.2 machine types for arm/i440fx/q35/s390x/spapr.
> 
> Signed-off-by: Yanan Wang 
> ---
>  hw/arm/virt.c  |  9 -
>  hw/core/machine.c  |  3 +++
>  hw/i386/pc.c   |  3 +++
>  hw/i386/pc_piix.c  | 14 +-
>  hw/i386/pc_q35.c   | 13 -
>  hw/ppc/spapr.c | 15 +--
>  hw/s390x/s390-virtio-ccw.c | 14 +-
>  include/hw/boards.h|  3 +++
>  include/hw/i386/pc.h   |  3 +++
>  9 files changed, 71 insertions(+), 6 deletions(-)
> 
> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> index 81eda46b0b..01165f7f53 100644
> --- a/hw/arm/virt.c
> +++ b/hw/arm/virt.c
> @@ -2788,10 +2788,17 @@ static void machvirt_machine_init(void)
>  }
>  type_init(machvirt_machine_init);
>  
> +static void virt_machine_6_2_options(MachineClass *mc)
> +{
> +}
> +DEFINE_VIRT_MACHINE_AS_LATEST(6, 2)
> +
>  static void virt_machine_6_1_options(MachineClass *mc)
>  {
> +virt_machine_6_2_options(mc);
> +compat_props_add(mc->compat_props, hw_compat_6_1, hw_compat_6_1_len);
>  }
> -DEFINE_VIRT_MACHINE_AS_LATEST(6, 1)
> +DEFINE_VIRT_MACHINE(6, 1)
>  
>  static void virt_machine_6_0_options(MachineClass *mc)
>  {
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index 8b4d07d3fc..63439c4a6d 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -37,6 +37,9 @@
>  #include "hw/virtio/virtio.h"
>  #include "hw/virtio/virtio-pci.h"
>  
> +GlobalProperty hw_compat_6_1[] = {};
> +const size_t hw_compat_6_1_len = G_N_ELEMENTS(hw_compat_6_1);
> +
>  GlobalProperty hw_compat_6_0[] = {
>  { "gpex-pcihost", "allow-unmapped-accesses", "false" },
>  { "i8042", "extended-state", "false"},


> diff --git a/include/hw/boards.h b/include/hw/boards.h
> index b6161cee88..2832f0f8aa 100644
> --- a/include/hw/boards.h
> +++ b/include/hw/boards.h
> @@ -354,6 +354,9 @@ struct MachineState {
>  } \
>  type_init(machine_initfn##_register_types)
>  
> +extern GlobalProperty hw_compat_6_1[];
> +extern const size_t hw_compat_6_1_len;
> +
>  extern GlobalProperty hw_compat_6_0[];
>  extern const size_t hw_compat_6_0_len;
>

Arm and general parts look good to me

Reviewed-by: Andrew Jones 




Re: [PATCH for-6.2 v2 05/11] machine: Improve the error reporting of smp parsing

2021-07-19 Thread Andrew Jones
On Mon, Jul 19, 2021 at 11:20:37AM +0800, Yanan Wang wrote:
> We totally have two requirements for a valid SMP configuration:

s/totally//

> the sum of "sockets * dies * cores * threads" must represent all

the product

> the possible cpus, i.e., max_cpus, and must include the initial
> present cpus, i.e., smp_cpus.
> 
> We only need to ensure "sockets * dies * cores * threads == maxcpus"
> at first and then ensure "sockets * dies * cores * threads >= cpus".

Or, "maxcpus >= cpus"

> With a reasonable order of the sanity-check, we can simplify the
> error reporting code.
> 
> Signed-off-by: Yanan Wang 
> ---
>  hw/core/machine.c | 25 ++---
>  1 file changed, 10 insertions(+), 15 deletions(-)
> 
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index 668f0a1553..8b4d07d3fc 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -788,21 +788,6 @@ static void smp_parse(MachineState *ms, SMPConfiguration 
> *config, Error **errp)
>  cpus = cpus > 0 ? cpus : sockets * dies * cores * threads;
>  maxcpus = maxcpus > 0 ? maxcpus : cpus;
>  
> -if (sockets * dies * cores * threads < cpus) {
> -g_autofree char *dies_msg = g_strdup_printf(
> -mc->smp_dies_supported ? " * dies (%u)" : "", dies);
> -error_setg(errp, "cpu topology: "
> -   "sockets (%u)%s * cores (%u) * threads (%u) < "
> -   "smp_cpus (%u)",
> -   sockets, dies_msg, cores, threads, cpus);
> -return;
> -}
> -
> -if (maxcpus < cpus) {
> -error_setg(errp, "maxcpus must be equal to or greater than smp");
> -return;
> -}

This may be redundant when determining a valid config, but by checking it
separately we can provide a more useful error message.

> -
>  if (sockets * dies * cores * threads != maxcpus) {
>  g_autofree char *dies_msg = g_strdup_printf(
>  mc->smp_dies_supported ? " * dies (%u)" : "", dies);
> @@ -814,6 +799,16 @@ static void smp_parse(MachineState *ms, SMPConfiguration 
> *config, Error **errp)
>  return;
>  }
>  
> +if (sockets * dies * cores * threads < cpus) {
> +g_autofree char *dies_msg = g_strdup_printf(
> +mc->smp_dies_supported ? " * dies (%u)" : "", dies);
> +error_setg(errp, "Invalid CPU topology: "
> +   "sockets (%u)%s * cores (%u) * threads (%u) < "
> +   "smp_cpus (%u)",
> +   sockets, dies_msg, cores, threads, cpus);
> +return;
> +}
> +
>  ms->smp.cpus = cpus;
>  ms->smp.sockets = sockets;
>  ms->smp.dies = dies;
> -- 
> 2.19.1
>

I'm not sure we need this patch.

Thanks,
drew 




Re: [PATCH for-6.2 v2 02/11] machine: Make smp_parse generic enough for all arches

2021-07-19 Thread Andrew Jones
On Mon, Jul 19, 2021 at 05:36:39PM +0100, Daniel P. Berrangé wrote:
> On Mon, Jul 19, 2021 at 06:28:46PM +0200, Andrew Jones wrote:
> > On Mon, Jul 19, 2021 at 11:20:34AM +0800, Yanan Wang wrote:
> > > Currently the only difference between smp_parse and pc_smp_parse
> > > is the support of multi-dies and the related error reporting code.
> > > With an arch compat variable "bool smp_dies_supported", we can
> > > easily make smp_parse generic enough for all arches and the PC
> > > specific one can be removed.
> > > 
> > > Making smp_parse() generic enough can reduce code duplication and
> > > ease the code maintenance, and also allows extending the topology
> > > with more arch specific members (e.g., clusters) in the future.
> > > 
> > > No functional change intended.
> > > 
> > > Suggested-by: Andrew Jones 
> > > Signed-off-by: Yanan Wang 
> > > ---
> > >  hw/core/machine.c   | 28 ++---
> > >  hw/i386/pc.c| 76 +
> > >  include/hw/boards.h |  1 +
> > >  3 files changed, 19 insertions(+), 86 deletions(-)
> > > 
> > > diff --git a/hw/core/machine.c b/hw/core/machine.c
> > > index d73daa10f4..ed6712e964 100644
> > > --- a/hw/core/machine.c
> > > +++ b/hw/core/machine.c
> > > @@ -743,6 +743,7 @@ void machine_set_cpu_numa_node(MachineState *machine,
> > >  
> > >  static void smp_parse(MachineState *ms, SMPConfiguration *config, Error 
> > > **errp)
> > >  {
> > > +MachineClass *mc = MACHINE_GET_CLASS(ms);
> > >  unsigned cpus= config->has_cpus ? config->cpus : 0;
> > >  unsigned sockets = config->has_sockets ? config->sockets : 0;
> > >  unsigned dies= config->has_dies ? config->dies : 1;
> > > @@ -761,7 +762,7 @@ static void smp_parse(MachineState *ms, 
> > > SMPConfiguration *config, Error **errp)
> > >  return;
> > >  }
> > >  
> > > -if (dies > 1) {
> > > +if (!mc->smp_dies_supported && dies > 1) {
> > 
> > Won't this allow a user on an arch with !mc->smp_dies_supported to specify
> > dies=1?
> 
> Conceptually that is fine. Before the introduction of CPU sockets
> with 2+ dies, you can credibly say that all sockets had 1 die, so
> it is nreasonable for users to say -smp ,dies=1,
> 
> libvirt will unconditionally set dies=1 for all QEMU targets if
> the user didn't specify an explicit dies value
> 
> >  To not allow that, can we do
> > 
> >if (!mc->smp_dies_supported && config->has_dies)
> > 
> > instead?
> 
> I don't see that this is benefitting apps/users.

Other than maintaining consistency; erroring with "we don't support dies"
for 2+, but not for 1, is inconsistent, then I agree there isn't much
reason to disallow it, since we'll be using the value of 1 anyway
internally. I don't really have a strong preference here, so I'm fine with
allowing dies=1.

Thanks,
drew

> 
> 
> Regards,
> Daniel
> -- 
> |: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
> |: https://libvirt.org -o-https://fstop138.berrange.com :|
> |: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|
> 




Re: [PATCH for-6.2 v2 04/11] machine: Use the computed parameters to calculate omitted cpus

2021-07-19 Thread Andrew Jones
On Mon, Jul 19, 2021 at 11:20:36AM +0800, Yanan Wang wrote:
> Currently we directly calculate the omitted cpus based on the already
> provided parameters. This makes some cmdlines like:
>   -smp maxcpus=16
>   -smp sockets=2,maxcpus=16
>   -smp sockets=2,dies=2,maxcpus=16
>   -smp sockets=2,cores=4,maxcpus=16
> not work. We should probably use the computed paramters to calculate
> cpus when maxcpus is provided while cpus is omitted, which will make
> above configs start to work.
> 
> Note: change in this patch won't affect any existing working cmdlines
> but allows more incomplete configs to be valid.
> 
> Signed-off-by: Yanan Wang 
> ---
>  hw/core/machine.c | 17 +
>  1 file changed, 9 insertions(+), 8 deletions(-)
> 
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index c9f15b15a5..668f0a1553 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -767,26 +767,27 @@ static void smp_parse(MachineState *ms, 
> SMPConfiguration *config, Error **errp)
>  return;
>  }
>  
> -/* compute missing values, prefer sockets over cores over threads */
>  maxcpus = maxcpus > 0 ? maxcpus : cpus;
>  
> -if (cpus == 0) {
> -sockets = sockets > 0 ? sockets : 1;
> -cores = cores > 0 ? cores : 1;
> -threads = threads > 0 ? threads : 1;
> -cpus = sockets * dies * cores * threads;
> -maxcpus = maxcpus > 0 ? maxcpus : cpus;
> -} else if (sockets == 0) {
> +/* compute missing values, prefer sockets over cores over threads */
> +if (sockets == 0) {
>  cores = cores > 0 ? cores : 1;
>  threads = threads > 0 ? threads : 1;
>  sockets = maxcpus / (dies * cores * threads);
> +sockets = sockets > 0 ? sockets : 1;
>  } else if (cores == 0) {
>  threads = threads > 0 ? threads : 1;
>  cores = maxcpus / (sockets * dies * threads);
> +cores = cores > 0 ? cores : 1;
>  } else if (threads == 0) {
>  threads = maxcpus / (sockets * dies * cores);
> +threads = threads > 0 ? threads : 1;
>  }

I didn't think we wanted this rounding which this patch adds back into
cores and threads and now also sockets.

>  
> +/* use the computed parameters to calculate the omitted cpus */
> +cpus = cpus > 0 ? cpus : sockets * dies * cores * threads;
> +maxcpus = maxcpus > 0 ? maxcpus : cpus;

It doesn't really matter, but I think I'd rather write this like

 maxcpus = maxcpus > 0 ? maxcpus : sockets * dies * cores * threads;
 cpus = cpus > 0 ? cpus : maxcpus;

> +
>  if (sockets * dies * cores * threads < cpus) {
>  g_autofree char *dies_msg = g_strdup_printf(
>  mc->smp_dies_supported ? " * dies (%u)" : "", dies);
> -- 
> 2.19.1
> 

Thanks,
drew




Re: [PATCH for-6.2 v2 03/11] machine: Uniformly use maxcpus to calculate the omitted parameters

2021-07-19 Thread Andrew Jones
On Mon, Jul 19, 2021 at 11:20:35AM +0800, Yanan Wang wrote:
> We are currently using maxcpus to calculate the omitted sockets
> but using cpus to calculate the omitted cores/threads. This makes
> cmdlines like:
>   -smp cpus=8,maxcpus=16
>   -smp cpus=8,cores=4,maxcpus=16
>   -smp cpus=8,threads=2,maxcpus=16
> work fine but the ones like:
>   -smp cpus=8,sockets=2,maxcpus=16
>   -smp cpus=8,sockets=2,cores=4,maxcpus=16
>   -smp cpus=8,sockets=2,threads=2,maxcpus=16
> break the invalid cpu topology check.
> 
> Since we require for the valid config that the sum of "sockets * cores
> * dies * threads" should equal to the maxcpus, we should uniformly use
> maxcpus to calculate their omitted values.
> 
> Also the if-branch of "cpus == 0 || sockets == 0" was splited into two
> branches of "cpus == 0" and "sockets == 0" so that we can clearly read
> that we are parsing -smp cmdlines with a preference of cpus over sockets
> over cores over threads.
> 
> Note: change in this patch won't affect any existing working cmdlines
> but improves consistency and allow more incomplete configs to be valid.

We also remove rounding of cores and threads when the math doesn't come
out right, which could possible start reporting a bad config as invalid
which worked before. Or were you able to prove that that can't happen with
your testing?

> 
> Signed-off-by: Yanan Wang 
> ---
>  hw/core/machine.c | 30 +++---
>  1 file changed, 15 insertions(+), 15 deletions(-)
> 
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index ed6712e964..c9f15b15a5 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -768,24 +768,26 @@ static void smp_parse(MachineState *ms, 
> SMPConfiguration *config, Error **errp)
>  }
>  
>  /* compute missing values, prefer sockets over cores over threads */
> -if (cpus == 0 || sockets == 0) {
> +maxcpus = maxcpus > 0 ? maxcpus : cpus;
> +
> +if (cpus == 0) {
> +sockets = sockets > 0 ? sockets : 1;
>  cores = cores > 0 ? cores : 1;
>  threads = threads > 0 ? threads : 1;
> -if (cpus == 0) {
> -sockets = sockets > 0 ? sockets : 1;
> -cpus = sockets * dies * cores * threads;
> -} else {
> -maxcpus = maxcpus > 0 ? maxcpus : cpus;
> -sockets = maxcpus / (dies * cores * threads);
> -}
> +cpus = sockets * dies * cores * threads;
> +maxcpus = maxcpus > 0 ? maxcpus : cpus;
> +} else if (sockets == 0) {
> +cores = cores > 0 ? cores : 1;
> +threads = threads > 0 ? threads : 1;
> +sockets = maxcpus / (dies * cores * threads);
>  } else if (cores == 0) {
>  threads = threads > 0 ? threads : 1;
> -cores = cpus / (sockets * dies * threads);
> -cores = cores > 0 ? cores : 1;
> +cores = maxcpus / (sockets * dies * threads);
>  } else if (threads == 0) {
> -threads = cpus / (sockets * dies * cores);
> -threads = threads > 0 ? threads : 1;
> -} else if (sockets * dies * cores * threads < cpus) {
> +threads = maxcpus / (sockets * dies * cores);
> +}
> +
> +if (sockets * dies * cores * threads < cpus) {
>  g_autofree char *dies_msg = g_strdup_printf(
>  mc->smp_dies_supported ? " * dies (%u)" : "", dies);
>  error_setg(errp, "cpu topology: "
> @@ -795,8 +797,6 @@ static void smp_parse(MachineState *ms, SMPConfiguration 
> *config, Error **errp)
>  return;
>  }
>  
> -maxcpus = maxcpus > 0 ? maxcpus : cpus;
> -
>  if (maxcpus < cpus) {
>  error_setg(errp, "maxcpus must be equal to or greater than smp");
>  return;
> -- 
> 2.19.1
>

Reviewed-by: Andrew Jones 




Re: [PATCH for-6.2 v2 02/11] machine: Make smp_parse generic enough for all arches

2021-07-19 Thread Andrew Jones
On Mon, Jul 19, 2021 at 11:20:34AM +0800, Yanan Wang wrote:
> Currently the only difference between smp_parse and pc_smp_parse
> is the support of multi-dies and the related error reporting code.
> With an arch compat variable "bool smp_dies_supported", we can
> easily make smp_parse generic enough for all arches and the PC
> specific one can be removed.
> 
> Making smp_parse() generic enough can reduce code duplication and
> ease the code maintenance, and also allows extending the topology
> with more arch specific members (e.g., clusters) in the future.
> 
> No functional change intended.
> 
> Suggested-by: Andrew Jones 
> Signed-off-by: Yanan Wang 
> ---
>  hw/core/machine.c   | 28 ++---
>  hw/i386/pc.c| 76 +
>  include/hw/boards.h |  1 +
>  3 files changed, 19 insertions(+), 86 deletions(-)
> 
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index d73daa10f4..ed6712e964 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -743,6 +743,7 @@ void machine_set_cpu_numa_node(MachineState *machine,
>  
>  static void smp_parse(MachineState *ms, SMPConfiguration *config, Error 
> **errp)
>  {
> +MachineClass *mc = MACHINE_GET_CLASS(ms);
>  unsigned cpus= config->has_cpus ? config->cpus : 0;
>  unsigned sockets = config->has_sockets ? config->sockets : 0;
>  unsigned dies= config->has_dies ? config->dies : 1;
> @@ -761,7 +762,7 @@ static void smp_parse(MachineState *ms, SMPConfiguration 
> *config, Error **errp)
>  return;
>  }
>  
> -if (dies > 1) {
> +if (!mc->smp_dies_supported && dies > 1) {

Won't this allow a user on an arch with !mc->smp_dies_supported to specify
dies=1? To not allow that, can we do

   if (!mc->smp_dies_supported && config->has_dies)

instead?

>  error_setg(errp, "dies not supported by this machine's CPU 
> topology");
>  return;
>  }
> @@ -772,23 +773,25 @@ static void smp_parse(MachineState *ms, 
> SMPConfiguration *config, Error **errp)
>  threads = threads > 0 ? threads : 1;
>  if (cpus == 0) {
>  sockets = sockets > 0 ? sockets : 1;
> -cpus = cores * threads * sockets;
> +cpus = sockets * dies * cores * threads;
>  } else {
>  maxcpus = maxcpus > 0 ? maxcpus : cpus;
> -sockets = maxcpus / (cores * threads);
> +sockets = maxcpus / (dies * cores * threads);
>  }
>  } else if (cores == 0) {
>  threads = threads > 0 ? threads : 1;
> -cores = cpus / (sockets * threads);
> +cores = cpus / (sockets * dies * threads);
>  cores = cores > 0 ? cores : 1;
>  } else if (threads == 0) {
> -threads = cpus / (cores * sockets);
> +threads = cpus / (sockets * dies * cores);
>  threads = threads > 0 ? threads : 1;
> -} else if (sockets * cores * threads < cpus) {
> +} else if (sockets * dies * cores * threads < cpus) {
> +g_autofree char *dies_msg = g_strdup_printf(
> +mc->smp_dies_supported ? " * dies (%u)" : "", dies);
>  error_setg(errp, "cpu topology: "
> -   "sockets (%u) * cores (%u) * threads (%u) < "
> +   "sockets (%u)%s * cores (%u) * threads (%u) < "
> "smp_cpus (%u)",
> -   sockets, cores, threads, cpus);
> +   sockets, dies_msg, cores, threads, cpus);
>  return;
>  }
>  
> @@ -799,17 +802,20 @@ static void smp_parse(MachineState *ms, 
> SMPConfiguration *config, Error **errp)
>  return;
>  }
>  
> -if (sockets * cores * threads != maxcpus) {
> +if (sockets * dies * cores * threads != maxcpus) {
> +g_autofree char *dies_msg = g_strdup_printf(
> +mc->smp_dies_supported ? " * dies (%u)" : "", dies);
>  error_setg(errp, "Invalid CPU topology: "
> -   "sockets (%u) * cores (%u) * threads (%u) "
> +   "sockets (%u)%s * cores (%u) * threads (%u) "
> "!= maxcpus (%u)",
> -   sockets, cores, threads,
> +   sockets, dies_msg, cores, threads,
> maxcpus);
>  return;
>  }
>  
>  ms->smp.cpus = cpus;
>  ms->smp.sockets = sockets;
> +ms->smp.dies = dies;
>  ms->smp.cores = cores;
>  ms->smp.threads = threads;
>  ms->smp.max

Re: [PATCH for-6.2 v2 01/11] machine: Disallow specifying topology parameters as zero

2021-07-19 Thread Andrew Jones
On Mon, Jul 19, 2021 at 11:20:33AM +0800, Yanan Wang wrote:
> In the SMP configuration, we should either specify a topology
> parameter with a reasonable value (equal to or greater than 1)
> or just leave it omitted and QEMU will calculate its value.
> 
> Configurations which explicitly specify the topology parameters
> as zero like "sockets=0" are meaningless, so disallow them.
> 
> Suggested-by: Andrew Jones 
> Signed-off-by: Yanan Wang 
> ---
>  hw/core/machine.c | 31 +++
>  hw/i386/pc.c  | 29 +
>  qapi/machine.json |  4 ++--
>  3 files changed, 46 insertions(+), 18 deletions(-)
> 
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index 775add0795..d73daa10f4 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -745,11 +745,25 @@ static void smp_parse(MachineState *ms, 
> SMPConfiguration *config, Error **errp)
>  {
>  unsigned cpus= config->has_cpus ? config->cpus : 0;
>  unsigned sockets = config->has_sockets ? config->sockets : 0;
> +unsigned dies= config->has_dies ? config->dies : 1;
>  unsigned cores   = config->has_cores ? config->cores : 0;
>  unsigned threads = config->has_threads ? config->threads : 0;
> +unsigned maxcpus = config->has_maxcpus ? config->maxcpus : 0;
> +
> +if ((config->has_cpus && config->cpus == 0) ||
> +(config->has_sockets && config->sockets == 0) ||
> +(config->has_dies && config->dies == 0) ||
> +(config->has_cores && config->cores == 0) ||
> +(config->has_threads && config->threads == 0) ||
> +(config->has_maxcpus && config->maxcpus == 0)) {
> +error_setg(errp, "parameters must be equal to or greater than one"
> +   "if provided");

Missing a space between 'one' and 'if'. It's better to just put the whole
string on one line too (ignore the 80 char thing) for error grepping.

> +return;
> +}
>  
> -if (config->has_dies && config->dies != 0 && config->dies != 1) {
> +if (dies > 1) {
>  error_setg(errp, "dies not supported by this machine's CPU 
> topology");
> +return;
>  }
>  
>  /* compute missing values, prefer sockets over cores over threads */
> @@ -760,8 +774,8 @@ static void smp_parse(MachineState *ms, SMPConfiguration 
> *config, Error **errp)
>  sockets = sockets > 0 ? sockets : 1;
>  cpus = cores * threads * sockets;
>  } else {
> -ms->smp.max_cpus = config->has_maxcpus ? config->maxcpus : cpus;
> -sockets = ms->smp.max_cpus / (cores * threads);
> +maxcpus = maxcpus > 0 ? maxcpus : cpus;
> +sockets = maxcpus / (cores * threads);
>  }
>  } else if (cores == 0) {
>  threads = threads > 0 ? threads : 1;
> @@ -778,26 +792,27 @@ static void smp_parse(MachineState *ms, 
> SMPConfiguration *config, Error **errp)
>  return;
>  }
>  
> -ms->smp.max_cpus = config->has_maxcpus ? config->maxcpus : cpus;
> +maxcpus = maxcpus > 0 ? maxcpus : cpus;
>  
> -if (ms->smp.max_cpus < cpus) {
> +if (maxcpus < cpus) {
>  error_setg(errp, "maxcpus must be equal to or greater than smp");
>  return;
>  }
>  
> -if (sockets * cores * threads != ms->smp.max_cpus) {
> +if (sockets * cores * threads != maxcpus) {
>  error_setg(errp, "Invalid CPU topology: "
> "sockets (%u) * cores (%u) * threads (%u) "
> "!= maxcpus (%u)",
> sockets, cores, threads,
> -   ms->smp.max_cpus);
> +   maxcpus);
>  return;
>  }
>  
>  ms->smp.cpus = cpus;
> +ms->smp.sockets = sockets;
>  ms->smp.cores = cores;
>  ms->smp.threads = threads;
> -ms->smp.sockets = sockets;
> +ms->smp.max_cpus = maxcpus;
>  }
>  
>  static void machine_get_smp(Object *obj, Visitor *v, const char *name,
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index c2b9d62a35..c6b63c00a5 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -719,6 +719,18 @@ static void pc_smp_parse(MachineState *ms, 
> SMPConfiguration *config, Error **err
>  unsigned dies= config->has_dies ? config->dies : 1;
>  unsigned cores   = config->has_cores ? config->cores : 0;
>  unsigned threads = config->has_threads ? config->threads : 0;
&

Re: [PATCH] qtest/hyperv: Introduce a simple hyper-v test

2021-07-19 Thread Andrew Jones
On Mon, Jul 19, 2021 at 11:30:41AM +0200, Vitaly Kuznetsov wrote:
> Andrew Jones  writes:
> 
> > On Fri, Jul 16, 2021 at 02:55:28PM +0200, Vitaly Kuznetsov wrote:
> >> For the beginning, just test 'hv-passthrough' and a couple of custom
> >> Hyper-V  enlightenments configurations through QMP. Later, it would
> >> be great to complement this by checking CPUID values from within the
> >> guest.
> >> 
> >> Signed-off-by: Vitaly Kuznetsov 
> >> ---
> >> - Changes since "[PATCH v8 0/9] i386: KVM: expand Hyper-V features early":
> >>  make the test SKIP correctly when KVM is not present.
> >> ---
> >>  MAINTAINERS   |   1 +
> >>  tests/qtest/hyperv-test.c | 228 ++
> >>  tests/qtest/meson.build   |   3 +-
> >>  3 files changed, 231 insertions(+), 1 deletion(-)
> >>  create mode 100644 tests/qtest/hyperv-test.c
> >> 
> >> diff --git a/MAINTAINERS b/MAINTAINERS
> >> index 148153d74f5b..c1afd744edca 100644
> >> --- a/MAINTAINERS
> >> +++ b/MAINTAINERS
> >> @@ -1576,6 +1576,7 @@ F: hw/isa/apm.c
> >>  F: include/hw/isa/apm.h
> >>  F: tests/unit/test-x86-cpuid.c
> >>  F: tests/qtest/test-x86-cpuid-compat.c
> >> +F: tests/qtest/hyperv-test.c
> >>  
> >>  PC Chipset
> >>  M: Michael S. Tsirkin 
> >> diff --git a/tests/qtest/hyperv-test.c b/tests/qtest/hyperv-test.c
> >> new file mode 100644
> >> index ..2155e5d90970
> >> --- /dev/null
> >> +++ b/tests/qtest/hyperv-test.c
> >> @@ -0,0 +1,228 @@
> >> +/*
> >> + * Hyper-V emulation CPU feature test cases
> >> + *
> >> + * Copyright (c) 2021 Red Hat Inc.
> >> + * Authors:
> >> + *  Vitaly Kuznetsov 
> >> + *
> >> + * This work is licensed under the terms of the GNU GPL, version 2 or 
> >> later.
> >> + * See the COPYING file in the top-level directory.
> >> + */
> >> +#include 
> >> +#include 
> >> +
> >> +#include "qemu/osdep.h"
> >> +#include "qemu/bitops.h"
> >> +#include "libqos/libqtest.h"
> >> +#include "qapi/qmp/qdict.h"
> >> +#include "qapi/qmp/qjson.h"
> >> +
> >> +#define MACHINE_KVM "-machine pc-q35-5.2 -accel kvm "
> >> +#define QUERY_HEAD  "{ 'execute': 'query-cpu-model-expansion', " \
> >> +"  'arguments': { 'type': 'full', "
> >> +#define QUERY_TAIL  "}}"
> >> +
> >> +static bool kvm_enabled(QTestState *qts)
> >> +{
> >> +QDict *resp, *qdict;
> >> +bool enabled;
> >> +
> >> +resp = qtest_qmp(qts, "{ 'execute': 'query-kvm' }");
> >> +g_assert(qdict_haskey(resp, "return"));
> >> +qdict = qdict_get_qdict(resp, "return");
> >> +g_assert(qdict_haskey(qdict, "enabled"));
> >> +enabled = qdict_get_bool(qdict, "enabled");
> >> +qobject_unref(resp);
> >> +
> >> +return enabled;
> >> +}
> >> +
> >> +static bool kvm_has_cap(int cap)
> >> +{
> >> +int fd = open("/dev/kvm", O_RDWR);
> >> +int ret;
> >> +
> >> +if (fd < 0) {
> >> +return false;
> >> +}
> >> +
> >> +ret = ioctl(fd, KVM_CHECK_EXTENSION, cap);
> >> +
> >> +close(fd);
> >> +
> >> +return ret > 0;
> >> +}
> >> +
> >> +static QDict *do_query_no_props(QTestState *qts, const char *cpu_type)
> >> +{
> >> +return qtest_qmp(qts, QUERY_HEAD "'model': { 'name': %s }"
> >> +  QUERY_TAIL, cpu_type);
> >> +}
> >> +
> >> +static bool resp_has_props(QDict *resp)
> >> +{
> >> +QDict *qdict;
> >> +
> >> +g_assert(resp);
> >> +
> >> +if (!qdict_haskey(resp, "return")) {
> >> +return false;
> >> +}
> >> +qdict = qdict_get_qdict(resp, "return");
> >> +
> >> +if (!qdict_haskey(qdict, "model")) {
> >> +return false;
> >> +}
> >> +qdict = qdict_get_qdict(qdict, "model");
> >> +
> >> +return qdict_haskey(qdict, "props");
> >> +}
> >> +
> >> +st

Re: [PATCH] qtest/hyperv: Introduce a simple hyper-v test

2021-07-16 Thread Andrew Jones
On Fri, Jul 16, 2021 at 02:55:28PM +0200, Vitaly Kuznetsov wrote:
> For the beginning, just test 'hv-passthrough' and a couple of custom
> Hyper-V  enlightenments configurations through QMP. Later, it would
> be great to complement this by checking CPUID values from within the
> guest.
> 
> Signed-off-by: Vitaly Kuznetsov 
> ---
> - Changes since "[PATCH v8 0/9] i386: KVM: expand Hyper-V features early":
>  make the test SKIP correctly when KVM is not present.
> ---
>  MAINTAINERS   |   1 +
>  tests/qtest/hyperv-test.c | 228 ++
>  tests/qtest/meson.build   |   3 +-
>  3 files changed, 231 insertions(+), 1 deletion(-)
>  create mode 100644 tests/qtest/hyperv-test.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 148153d74f5b..c1afd744edca 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1576,6 +1576,7 @@ F: hw/isa/apm.c
>  F: include/hw/isa/apm.h
>  F: tests/unit/test-x86-cpuid.c
>  F: tests/qtest/test-x86-cpuid-compat.c
> +F: tests/qtest/hyperv-test.c
>  
>  PC Chipset
>  M: Michael S. Tsirkin 
> diff --git a/tests/qtest/hyperv-test.c b/tests/qtest/hyperv-test.c
> new file mode 100644
> index ..2155e5d90970
> --- /dev/null
> +++ b/tests/qtest/hyperv-test.c
> @@ -0,0 +1,228 @@
> +/*
> + * Hyper-V emulation CPU feature test cases
> + *
> + * Copyright (c) 2021 Red Hat Inc.
> + * Authors:
> + *  Vitaly Kuznetsov 
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + */
> +#include 
> +#include 
> +
> +#include "qemu/osdep.h"
> +#include "qemu/bitops.h"
> +#include "libqos/libqtest.h"
> +#include "qapi/qmp/qdict.h"
> +#include "qapi/qmp/qjson.h"
> +
> +#define MACHINE_KVM "-machine pc-q35-5.2 -accel kvm "
> +#define QUERY_HEAD  "{ 'execute': 'query-cpu-model-expansion', " \
> +"  'arguments': { 'type': 'full', "
> +#define QUERY_TAIL  "}}"
> +
> +static bool kvm_enabled(QTestState *qts)
> +{
> +QDict *resp, *qdict;
> +bool enabled;
> +
> +resp = qtest_qmp(qts, "{ 'execute': 'query-kvm' }");
> +g_assert(qdict_haskey(resp, "return"));
> +qdict = qdict_get_qdict(resp, "return");
> +g_assert(qdict_haskey(qdict, "enabled"));
> +enabled = qdict_get_bool(qdict, "enabled");
> +qobject_unref(resp);
> +
> +return enabled;
> +}
> +
> +static bool kvm_has_cap(int cap)
> +{
> +int fd = open("/dev/kvm", O_RDWR);
> +int ret;
> +
> +if (fd < 0) {
> +return false;
> +}
> +
> +ret = ioctl(fd, KVM_CHECK_EXTENSION, cap);
> +
> +close(fd);
> +
> +return ret > 0;
> +}
> +
> +static QDict *do_query_no_props(QTestState *qts, const char *cpu_type)
> +{
> +return qtest_qmp(qts, QUERY_HEAD "'model': { 'name': %s }"
> +  QUERY_TAIL, cpu_type);
> +}
> +
> +static bool resp_has_props(QDict *resp)
> +{
> +QDict *qdict;
> +
> +g_assert(resp);
> +
> +if (!qdict_haskey(resp, "return")) {
> +return false;
> +}
> +qdict = qdict_get_qdict(resp, "return");
> +
> +if (!qdict_haskey(qdict, "model")) {
> +return false;
> +}
> +qdict = qdict_get_qdict(qdict, "model");
> +
> +return qdict_haskey(qdict, "props");
> +}
> +
> +static QDict *resp_get_props(QDict *resp)
> +{
> +QDict *qdict;
> +
> +g_assert(resp);
> +g_assert(resp_has_props(resp));
> +
> +qdict = qdict_get_qdict(resp, "return");
> +qdict = qdict_get_qdict(qdict, "model");
> +qdict = qdict_get_qdict(qdict, "props");
> +
> +return qdict;
> +}
> +
> +static bool resp_get_feature(QDict *resp, const char *feature)
> +{
> +QDict *props;
> +
> +g_assert(resp);
> +g_assert(resp_has_props(resp));
> +props = resp_get_props(resp);
> +g_assert(qdict_get(props, feature));
> +return qdict_get_bool(props, feature);
> +}
> +
> +#define assert_has_feature(qts, cpu_type, feature) \
> +({ \
> +QDict *_resp = do_query_no_props(qts, cpu_type);   \
> +g_assert(_resp);   \
> +g_assert(resp_has_props(_resp));   \
> +g_assert(qdict_get(resp_get_props(_resp), feature));   \
> +qobject_unref(_resp);  \
> +})
> +
> +#define resp_assert_feature(resp, feature, expected_value) \
> +({ \
> +QDict *_props; \
> +   \
> +g_assert(_resp);   \
> +g_assert(resp_has_props(_resp));   \
> +_props = resp_get_props(_resp);\
> +g_assert(qdict_get(_props, feature)); 

Re: [RFC PATCH 6/6] machine: Tweak the order of topology members in struct CpuTopology

2021-07-12 Thread Andrew Jones
On Fri, Jul 02, 2021 at 06:07:39PM +0800, Yanan Wang wrote:
> Now that all the possible topology parameters are integrated in struct
> CpuTopology, tweak the order of topology members to be "cpus/sockets/
> dies/cores/threads/maxcpus" for readability and consistency. We also
> tweak the comment by adding explanation of dies parameter.
> 
> Signed-off-by: Yanan Wang 
> ---
>  hw/core/machine.c   | 4 ++--
>  include/hw/boards.h | 7 ---
>  2 files changed, 6 insertions(+), 5 deletions(-)

Reviewed-by: Andrew Jones 




Re: [RFC PATCH 3/6] pc/machine: Perform zero-check for the value of -smp dies

2021-07-12 Thread Andrew Jones
On Mon, Jul 12, 2021 at 05:05:43PM +0200, Andrew Jones wrote:
> On Mon, Jul 12, 2021 at 05:04:04PM +0200, Andrew Jones wrote:
> > On Fri, Jul 02, 2021 at 06:07:36PM +0800, Yanan Wang wrote:
> > > It's possible that dies parameter is explicitly specified as "dies=0"
> > > in the cmdline, if so we will wrongly calculate the other ommited
> > > parameters such as "sockets = maxcpus / (dies * cores * threads);"
> > > with a zeroed dies value.
> > > 
> > > So perform zero-check (default the value to 1 if zeroed) for -smp dies
> > > before using it to calculate other parameters.
> > 
> > OK, dies=0 may make some sense for a user that doesn't want to describe
> > dies.
> > 
> > Reviewed-by: Andrew Jones 
> 
> But... this is the pc smp parse function, not the general one, so maybe my
> comment from patch 1 should apply here as well, which is, that dies=0
> should be an error rather than silently changed to dies=1.

Also, after reading Daniel's comment on a later patch, I think anything=0
should just be an error, even for the general parser.

Thanks,
drew

> 
> > 
> > > 
> > > Fixes: 1b45842203540 (vl.c: Add -smp, dies=* command line support and 
> > > update doc)
> > > Signed-off-by: Yanan Wang 
> > > ---
> > >  hw/i386/pc.c | 4 +++-
> > >  1 file changed, 3 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > > index a44511c937..93d1f12a49 100644
> > > --- a/hw/i386/pc.c
> > > +++ b/hw/i386/pc.c
> > > @@ -714,12 +714,14 @@ static void pc_smp_parse(MachineState *ms, 
> > > SMPConfiguration *config, Error **err
> > >  {
> > >  unsigned cpus= config->has_cpus ? config->cpus : 0;
> > >  unsigned sockets = config->has_sockets ? config->sockets : 0;
> > > -unsigned dies= config->has_dies ? config->dies : 1;
> > > +unsigned dies= config->has_dies ? config->dies : 0;
> > >  unsigned cores   = config->has_cores ? config->cores : 0;
> > >  unsigned threads = config->has_threads ? config->threads : 0;
> > >  unsigned maxcpus = config->has_maxcpus ? config->maxcpus : 0;
> > >  
> > >  /* compute missing values, prefer sockets over cores over threads */
> > > +dies = dies > 0 ? dies : 1;
> > > +
> > >  if (cpus == 0 || sockets == 0) {
> > >  cores = cores > 0 ? cores : 1;
> > >  threads = threads > 0 ? threads : 1;
> > > -- 
> > > 2.19.1
> > > 




Re: [RFC PATCH 4/6] machine: Uniformly use maxcpus to calculate the missing values

2021-07-12 Thread Andrew Jones
On Fri, Jul 02, 2021 at 06:07:37PM +0800, Yanan Wang wrote:
> We are currently using maxcpus to calculate value of sockets but using
> cpus to calculate value of cores/threads. This makes cmdlines like
> "-smp 8,maxcpus=12,cores=4" work while "-smp 8,maxcpus=12,sockets=3"
> break the invalid cpu topology check.
> 
> This patch allows us to uniformly use maxcpus to calculate the missing
> values. Also the if branch of "cpus == 0 || sockets == 0" was splited
> into branches of "cpus == 0" and "sockets == 0" so that we can clearly
> figure out that we are parsing -smp cmdlines with a preference of cpus
> over sockets over cores over threads.
> 
> Signed-off-by: Yanan Wang 
> ---
>  hw/core/machine.c | 36 +++-
>  hw/i386/pc.c  | 37 +++--
>  2 files changed, 38 insertions(+), 35 deletions(-)
> 
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index 1e194677cd..58882835be 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -752,34 +752,36 @@ static void smp_parse(MachineState *ms, 
> SMPConfiguration *config, Error **errp)
>  }
>  
>  /* compute missing values, prefer sockets over cores over threads */
> -if (cpus == 0 || sockets == 0) {
> +maxcpus = maxcpus > 0 ? maxcpus : cpus;
> +
> +if (cpus == 0) {
> +sockets = sockets > 0 ? sockets : 1;
>  cores = cores > 0 ? cores : 1;
>  threads = threads > 0 ? threads : 1;
> -if (cpus == 0) {
> -sockets = sockets > 0 ? sockets : 1;
> -cpus = cores * threads * sockets;
> -} else {
> -maxcpus = maxcpus > 0 ? maxcpus : cpus;
> -sockets = maxcpus / (cores * threads);
> -sockets = sockets > 0 ? sockets : 1;
> -}
> +cpus = sockets * cores * threads;
> +maxcpus = maxcpus > 0 ? maxcpus : cpus;
> +} else if (sockets == 0) {
> +cores = cores > 0 ? cores : 1;
> +threads = threads > 0 ? threads : 1;
> +sockets = maxcpus / (cores * threads);
> +sockets = sockets > 0 ? sockets : 1;

As stated in the other patch, this rounding up of a fractional sockets
shouldn't be here. maxcpus or (cpus==maxcpus) should always be selected by
the user to be a product of whole number sockets, cores, threads.

>  } else if (cores == 0) {
>  threads = threads > 0 ? threads : 1;
> -cores = cpus / (sockets * threads);
> +cores = maxcpus / (sockets * threads);
>  cores = cores > 0 ? cores : 1;

Now that we're using maxcpus for the calculation, then no rounding for
cores either...

>  } else if (threads == 0) {
> -threads = cpus / (cores * sockets);
> +threads = maxcpus / (sockets * cores);
>  threads = threads > 0 ? threads : 1;

...or threads.

> -} else if (sockets * cores * threads < cpus) {
> +}
> +
> +if (sockets * cores * threads < cpus) {
>  error_setg(errp, "cpu topology: "
> -   "sockets (%u) * cores (%u) * threads (%u) < "
> -   "smp_cpus (%u)",
> +   "sockets (%u) * cores (%u) * threads (%u) "
> +   "< smp_cpus (%u)",

Why make this change?

> sockets, cores, threads, cpus);
>  return;
>  }
>  
> -maxcpus = maxcpus > 0 ? maxcpus : cpus;
> -
>  if (maxcpus < cpus) {
>  error_setg(errp, "maxcpus must be equal to or greater than smp");
>  return;
> @@ -795,9 +797,9 @@ static void smp_parse(MachineState *ms, SMPConfiguration 
> *config, Error **errp)
>  }
>  
>  ms->smp.cpus = cpus;
> +ms->smp.sockets = sockets;
>  ms->smp.cores = cores;
>  ms->smp.threads = threads;
> -ms->smp.sockets = sockets;
>  ms->smp.max_cpus = maxcpus;
>  }
>  
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index 93d1f12a49..1812f33ab1 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -721,35 +721,36 @@ static void pc_smp_parse(MachineState *ms, 
> SMPConfiguration *config, Error **err
>  
>  /* compute missing values, prefer sockets over cores over threads */
>  dies = dies > 0 ? dies : 1;
> +maxcpus = maxcpus > 0 ? maxcpus : cpus;
>  
> -if (cpus == 0 || sockets == 0) {
> +if (cpus == 0) {
> +sockets = sockets > 0 ? sockets : 1;
>  cores = cores > 0 ? cores : 1;
>  threads = threads > 0 ? threads : 1;
> -if (cpus == 0) {
> -sockets = sockets > 0 ? sockets : 1;
> -cpus = cores * threads * dies * sockets;
> -} else {
> -maxcpus = maxcpus > 0 ? maxcpus : cpus;
> -sockets = maxcpus / (dies * cores * threads);
> -sockets = sockets > 0 ? sockets : 1;
> -}
> +cpus = sockets * dies * cores * threads;
> +maxcpus = maxcpus > 0 ? maxcpus : cpus;
> +} else if (sockets == 0) {
> +cores = cores > 0 ? cores : 1;
> +threads = threads > 0 ? threads : 1;
> +sockets = maxcpus / 

Re: [RFC PATCH 3/6] pc/machine: Perform zero-check for the value of -smp dies

2021-07-12 Thread Andrew Jones
On Mon, Jul 12, 2021 at 05:04:04PM +0200, Andrew Jones wrote:
> On Fri, Jul 02, 2021 at 06:07:36PM +0800, Yanan Wang wrote:
> > It's possible that dies parameter is explicitly specified as "dies=0"
> > in the cmdline, if so we will wrongly calculate the other ommited
> > parameters such as "sockets = maxcpus / (dies * cores * threads);"
> > with a zeroed dies value.
> > 
> > So perform zero-check (default the value to 1 if zeroed) for -smp dies
> > before using it to calculate other parameters.
> 
> OK, dies=0 may make some sense for a user that doesn't want to describe
> dies.
> 
> Reviewed-by: Andrew Jones 

But... this is the pc smp parse function, not the general one, so maybe my
comment from patch 1 should apply here as well, which is, that dies=0
should be an error rather than silently changed to dies=1.

> 
> > 
> > Fixes: 1b45842203540 (vl.c: Add -smp, dies=* command line support and 
> > update doc)
> > Signed-off-by: Yanan Wang 
> > ---
> >  hw/i386/pc.c | 4 +++-
> >  1 file changed, 3 insertions(+), 1 deletion(-)
> > 
> > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > index a44511c937..93d1f12a49 100644
> > --- a/hw/i386/pc.c
> > +++ b/hw/i386/pc.c
> > @@ -714,12 +714,14 @@ static void pc_smp_parse(MachineState *ms, 
> > SMPConfiguration *config, Error **err
> >  {
> >  unsigned cpus= config->has_cpus ? config->cpus : 0;
> >  unsigned sockets = config->has_sockets ? config->sockets : 0;
> > -unsigned dies= config->has_dies ? config->dies : 1;
> > +unsigned dies= config->has_dies ? config->dies : 0;
> >  unsigned cores   = config->has_cores ? config->cores : 0;
> >  unsigned threads = config->has_threads ? config->threads : 0;
> >  unsigned maxcpus = config->has_maxcpus ? config->maxcpus : 0;
> >  
> >  /* compute missing values, prefer sockets over cores over threads */
> > +dies = dies > 0 ? dies : 1;
> > +
> >  if (cpus == 0 || sockets == 0) {
> >  cores = cores > 0 ? cores : 1;
> >  threads = threads > 0 ? threads : 1;
> > -- 
> > 2.19.1
> > 




Re: [RFC PATCH 3/6] pc/machine: Perform zero-check for the value of -smp dies

2021-07-12 Thread Andrew Jones
On Fri, Jul 02, 2021 at 06:07:36PM +0800, Yanan Wang wrote:
> It's possible that dies parameter is explicitly specified as "dies=0"
> in the cmdline, if so we will wrongly calculate the other ommited
> parameters such as "sockets = maxcpus / (dies * cores * threads);"
> with a zeroed dies value.
> 
> So perform zero-check (default the value to 1 if zeroed) for -smp dies
> before using it to calculate other parameters.

OK, dies=0 may make some sense for a user that doesn't want to describe
dies.

Reviewed-by: Andrew Jones 

> 
> Fixes: 1b45842203540 (vl.c: Add -smp, dies=* command line support and update 
> doc)
> Signed-off-by: Yanan Wang 
> ---
>  hw/i386/pc.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index a44511c937..93d1f12a49 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -714,12 +714,14 @@ static void pc_smp_parse(MachineState *ms, 
> SMPConfiguration *config, Error **err
>  {
>  unsigned cpus= config->has_cpus ? config->cpus : 0;
>  unsigned sockets = config->has_sockets ? config->sockets : 0;
> -unsigned dies= config->has_dies ? config->dies : 1;
> +unsigned dies= config->has_dies ? config->dies : 0;
>  unsigned cores   = config->has_cores ? config->cores : 0;
>  unsigned threads = config->has_threads ? config->threads : 0;
>  unsigned maxcpus = config->has_maxcpus ? config->maxcpus : 0;
>  
>  /* compute missing values, prefer sockets over cores over threads */
> +dies = dies > 0 ? dies : 1;
> +
>  if (cpus == 0 || sockets == 0) {
>  cores = cores > 0 ? cores : 1;
>  threads = threads > 0 ? threads : 1;
> -- 
> 2.19.1
> 




Re: [RFC PATCH 1/6] machine: Set the value of maxcpus to match cpus if specified as zero

2021-07-12 Thread Andrew Jones
On Fri, Jul 02, 2021 at 06:07:34PM +0800, Yanan Wang wrote:
> It is currently allowed to explicitly specified the topology parameters
> as 0 in the -smp cmdlines, such as -smp cpus=8,maxcpus=0,sockets=0. And
> for the values of cpus/sockets/cores/threads, we always determine that
> they are ommited if either set to 0 in the cmdline(e.g. sockets=0) or
> just not explicitly specified, then we compute the ommited values.
> 
> We probably should also treat "maxcpus=0" as ommited and then set the
> value to match smp cpus. This makes cmdlines like "-smp 8, maxcpus=0"
> start to work as "-smp 8,maxcpus=8,sockets=8,cores=1,threads=1".
> 
> Note that this patch won't affect any existing working cmdlines, but
> will allow configuration like "-smp cpus=n,maxcpus=0" to be valid.

Personally, I'd rather see -smp cpus=n,sockets=0 become an error than to
"fix" -smp cpus=n,maxcpus=0.

Thanks,
drew
 
> 
> Signed-off-by: Yanan Wang 
> ---
>  hw/core/machine.c | 14 --
>  hw/i386/pc.c  | 14 --
>  2 files changed, 16 insertions(+), 12 deletions(-)
> 
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index ffc076ae84..f17bbe3275 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -745,6 +745,7 @@ static void smp_parse(MachineState *ms, SMPConfiguration 
> *config, Error **errp)
>  unsigned sockets = config->has_sockets ? config->sockets : 0;
>  unsigned cores   = config->has_cores ? config->cores : 0;
>  unsigned threads = config->has_threads ? config->threads : 0;
> +unsigned maxcpus = config->has_maxcpus ? config->maxcpus : 0;
>  
>  if (config->has_dies && config->dies != 0 && config->dies != 1) {
>  error_setg(errp, "dies not supported by this machine's CPU 
> topology");
> @@ -758,8 +759,8 @@ static void smp_parse(MachineState *ms, SMPConfiguration 
> *config, Error **errp)
>  sockets = sockets > 0 ? sockets : 1;
>  cpus = cores * threads * sockets;
>  } else {
> -ms->smp.max_cpus = config->has_maxcpus ? config->maxcpus : cpus;
> -sockets = ms->smp.max_cpus / (cores * threads);
> +maxcpus = maxcpus > 0 ? maxcpus : cpus;
> +sockets = maxcpus / (cores * threads);
>  }
>  } else if (cores == 0) {
>  threads = threads > 0 ? threads : 1;
> @@ -776,19 +777,19 @@ static void smp_parse(MachineState *ms, 
> SMPConfiguration *config, Error **errp)
>  return;
>  }
>  
> -ms->smp.max_cpus = config->has_maxcpus ? config->maxcpus : cpus;
> +maxcpus = maxcpus > 0 ? maxcpus : cpus;
>  
> -if (ms->smp.max_cpus < cpus) {
> +if (maxcpus < cpus) {
>  error_setg(errp, "maxcpus must be equal to or greater than smp");
>  return;
>  }
>  
> -if (sockets * cores * threads != ms->smp.max_cpus) {
> +if (sockets * cores * threads != maxcpus) {
>  error_setg(errp, "Invalid CPU topology: "
> "sockets (%u) * cores (%u) * threads (%u) "
> "!= maxcpus (%u)",
> sockets, cores, threads,
> -   ms->smp.max_cpus);
> +   maxcpus);
>  return;
>  }
>  
> @@ -796,6 +797,7 @@ static void smp_parse(MachineState *ms, SMPConfiguration 
> *config, Error **errp)
>  ms->smp.cores = cores;
>  ms->smp.threads = threads;
>  ms->smp.sockets = sockets;
> +ms->smp.max_cpus = maxcpus;
>  }
>  
>  static void machine_class_init(ObjectClass *oc, void *data)
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index 8e1220db72..a9b22fdc01 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -717,6 +717,7 @@ static void pc_smp_parse(MachineState *ms, 
> SMPConfiguration *config, Error **err
>  unsigned dies= config->has_dies ? config->dies : 1;
>  unsigned cores   = config->has_cores ? config->cores : 0;
>  unsigned threads = config->has_threads ? config->threads : 0;
> +unsigned maxcpus = config->has_maxcpus ? config->maxcpus : 0;
>  
>  /* compute missing values, prefer sockets over cores over threads */
>  if (cpus == 0 || sockets == 0) {
> @@ -726,8 +727,8 @@ static void pc_smp_parse(MachineState *ms, 
> SMPConfiguration *config, Error **err
>  sockets = sockets > 0 ? sockets : 1;
>  cpus = cores * threads * dies * sockets;
>  } else {
> -ms->smp.max_cpus = config->has_maxcpus ? config->maxcpus : cpus;
> -sockets = ms->smp.max_cpus / (cores * threads * dies);
> +maxcpus = maxcpus > 0 ? maxcpus : cpus;
> +sockets = maxcpus / (dies * cores * threads);
>  }
>  } else if (cores == 0) {
>  threads = threads > 0 ? threads : 1;
> @@ -744,19 +745,19 @@ static void pc_smp_parse(MachineState *ms, 
> SMPConfiguration *config, Error **err
>  return;
>  }
>  
> -ms->smp.max_cpus = config->has_maxcpus ? config->maxcpus : cpus;
> +maxcpus = maxcpus > 0 ? maxcpus : cpus;
>  
> -if (ms->smp.max_cpus 

Re: [RFC PATCH 2/6] machine: Perform zero-check for the computed value of sockets

2021-07-12 Thread Andrew Jones
On Fri, Jul 02, 2021 at 06:07:35PM +0800, Yanan Wang wrote:
> We currently perform zero-check (default the value to 1 if zeroed)
> for the computed values of cores/threads, to make sure they are at
> least 1. For consistency, we probably should also default sockets
> to 1 if the computed value is zero. Note that this won't affect
> any existing working cmdlines but will improve the error reporting
> of the invalid ones such as "-smp 8,maxcpus=9,cores=10,threads=1".

How does this help error checking? If the user input values that compute a
fractional (rounded down to zero with integer division) value, then we'll
catch that with the sockets*cores*threads == maxcpus test now, but we may
not catch that after this patch.

Thanks,
drew

> 
> Signed-off-by: Yanan Wang 
> ---
>  hw/core/machine.c | 1 +
>  hw/i386/pc.c  | 1 +
>  2 files changed, 2 insertions(+)
> 
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index f17bbe3275..1e194677cd 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -761,6 +761,7 @@ static void smp_parse(MachineState *ms, SMPConfiguration 
> *config, Error **errp)
>  } else {
>  maxcpus = maxcpus > 0 ? maxcpus : cpus;
>  sockets = maxcpus / (cores * threads);
> +sockets = sockets > 0 ? sockets : 1;
>  }
>  } else if (cores == 0) {
>  threads = threads > 0 ? threads : 1;
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index a9b22fdc01..a44511c937 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -729,6 +729,7 @@ static void pc_smp_parse(MachineState *ms, 
> SMPConfiguration *config, Error **err
>  } else {
>  maxcpus = maxcpus > 0 ? maxcpus : cpus;
>  sockets = maxcpus / (dies * cores * threads);
> +sockets = sockets > 0 ? sockets : 1;
>  }
>  } else if (cores == 0) {
>  threads = threads > 0 ? threads : 1;
> -- 
> 2.19.1
> 




Re: [RFC PATCH v4 0/7] hw/arm/virt: Introduce cpu topology support

2021-06-30 Thread Andrew Jones
On Wed, Jun 30, 2021 at 05:37:42PM +0800, wangyanan (Y) wrote:
> On 2021/6/30 16:30, Andrew Jones wrote:
> > On Wed, Jun 30, 2021 at 02:36:31PM +0800, wangyanan (Y) wrote:
> > > Hi Drew, Igor,
> > > 
> > > I have a question below, hope for some explanation... :)
> > > 
> > > I'm trying to rearrange the smp_parse() helper to make it more scalable.
> > > But I wonder why we are currently using maxcpus to calculate the missing
> > > sockets while using *cpus* to calculate the missing cores and threads?
> > > 
> > > This makes the following cmdlines work fine,
> > > -smp cpus=8,maxcpus=12  <==>  -smp
> > > cpus=8,maxcpus=12,sockets=12,cores=1,threads=1
> > > -smp cpus=8,maxcpus=12,cores=6  <==>  -smp
> > > cpus=8,maxcpus=12,sockets=2,cores=6,threads=1
> > > -smp cpus=8,maxcpus=12,threads=2  <==>  -smp
> > > cpus=8,maxcpus=12,sockets=6,cores=1,threads=2
> > > 
> > > but the following ones break the invalid CPU topology check:
> > > -smp cpus=8,maxcpus=12,sockets=2  <==>  -smp
> > > cpus=8,maxcpus=12,sockets=2,cores=4,threads=1
> > > -smp cpus=8,maxcpus=12,sockets=4,threads=1  <==>  -smp
> > > cpus=8,maxcpus=12,sockets=4,cores=2,threads=1
> > > -smp maxcpus=12  <==>  -smp cpus=1,maxcpus=12,sockets=1,cores=1,threads=1
> > > -smp maxcpus=12,sockets=2  <==>  -smp
> > > cpus=2,maxcpus=12,sockets=2,cores=1,threads=1
> > > 
> > > IMO we should uniformly use maxcpus to calculate the missing sockets
> > > also cores and threads, which will allow all the above cmdlines work.
> > > Or maybe I missed something? I read the related discussion in [1] but
> > > didn't get an unambiguous conclusion.
> > > 
> > > [1] 
> > > https://patchwork.kernel.org/project/qemu-devel/patch/1535553121-80352-1-git-send-email-imamm...@redhat.com/
> > I agree that maxcpus should be used for all calculations.
> Thanks. From my view uniformly using maxcpus to calculate the missing
> values won't break any existing working cmdlines, but will allow some now
> being invalid and incomplete cmdlines to be valid. I will use maxcpus and
> test the parser for all possible parameter collections.
> > I think we need
> > to write -smp parsing from scratch using a set of clean requirements and
> > then use the machine compat stuff to switch to it. And also properly
> > document it with something like "Since 6.2..."
> I agree to rewrite the -smp parsing. But what's the meaning of clean
> requirements?
> Sorry I didn't get it.

I think -smp evolved without all the details considered up front. Now that
we've considered the details/requirements more completely, then let's
apply our knowledge of them to an implementation that gets them all
covered. Here's a quick list from the top of my head, there might be
some missing 

 - maxcpus should be used for computation of missing values
 - we should assume cores over sockets over threads
 - we should allow extending the topology with arch-specific
   members, such as dies, which will always default to 1 when
   not provided, rather than be computed
 - we should store the results in the smp machine properties

Thanks,
drew

> 
> Thanks,
> Yanan
> .
> > 
> > > Regards,
> > > Yanan
> > > .
> > > 
> > > On 2021/6/28 16:58, Andrew Jones wrote:
> > > > On Mon, Jun 28, 2021 at 04:43:05PM +0800, wangyanan (Y) wrote:
> > > > > Hi,
> > > > > On 2021/6/23 1:39, Daniel P. Berrangé wrote:
> > > > > > On Tue, Jun 22, 2021 at 07:29:34PM +0200, Andrew Jones wrote:
> > > > > > > On Tue, Jun 22, 2021 at 06:14:25PM +0100, Daniel P. Berrangé 
> > > > > > > wrote:
> > > > > > > > On Tue, Jun 22, 2021 at 05:40:13PM +0200, Igor Mammedov wrote:
> > > > > > > > > On Tue, 22 Jun 2021 16:29:15 +0200
> > > > > > > > > Andrew Jones  wrote:
> > > > > > > > > 
> > > > > > > > > > On Tue, Jun 22, 2021 at 03:10:57PM +0100, Daniel P. 
> > > > > > > > > > Berrangé wrote:
> > > > > > > > > > > On Tue, Jun 22, 2021 at 10:04:52PM +0800, wangyanan (Y) 
> > > > > > > > > > > wrote:
> > > > > > > > > > > > Hi Daniel,
> > > > > > > > > > > > 
> > > > > > > > > > > > On 2021/6/22 20:41, Daniel P. Berrangé wrote:
> > > > > > > >

<    1   2   3   4   5   6   7   8   9   10   >