Re: [PATCH RESEND 02/18] tests: Rename test-x86-cpuid.c to test-x86-apicid.c

2023-02-14 Thread wangyanan (Y)

在 2023/2/15 11:35, Zhao Liu 写道:

On Wed, Feb 15, 2023 at 10:36:34AM +0800, wangyanan (Y) wrote:

Date: Wed, 15 Feb 2023 10:36:34 +0800
From: "wangyanan (Y)" 
Subject: Re: [PATCH RESEND 02/18] tests: Rename test-x86-cpuid.c to
  test-x86-apicid.c

在 2023/2/13 17:36, Zhao Liu 写道:

From: Zhao Liu 

In fact, this unit tests APIC ID other than CPUID.
Rename to test-x86-apicid.c to make its name more in line with its
actual content.

Signed-off-by: Zhao Liu 
---
   MAINTAINERS| 2 +-
   tests/unit/meson.build | 4 ++--
   tests/unit/{test-x86-cpuid.c => test-x86-apicid.c} | 2 +-
   3 files changed, 4 insertions(+), 4 deletions(-)
   rename tests/unit/{test-x86-cpuid.c => test-x86-apicid.c} (99%)

diff --git a/MAINTAINERS b/MAINTAINERS
index 96e25f62acaa..71c1bc24371b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1679,7 +1679,7 @@ F: include/hw/southbridge/piix.h
   F: hw/misc/sga.c
   F: hw/isa/apm.c
   F: include/hw/isa/apm.h
-F: tests/unit/test-x86-cpuid.c
+F: tests/unit/test-x86-apicid.c
   F: tests/qtest/test-x86-cpuid-compat.c
   PC Chipset
diff --git a/tests/unit/meson.build b/tests/unit/meson.build
index ffa444f4323c..a9df2843e92e 100644
--- a/tests/unit/meson.build
+++ b/tests/unit/meson.build
@@ -20,8 +20,8 @@ tests = {
 'test-opts-visitor': [testqapi],
 'test-visitor-serialization': [testqapi],
 'test-bitmap': [],
-  # all code tested by test-x86-cpuid is inside topology.h
-  'test-x86-cpuid': [],
+  # all code tested by test-x86-apicid is inside topology.h
+  'test-x86-apicid': [],
 'test-cutils': [],
 'test-div128': [],
 'test-shift128': [],
diff --git a/tests/unit/test-x86-cpuid.c b/tests/unit/test-x86-apicid.c
similarity index 99%
rename from tests/unit/test-x86-cpuid.c
rename to tests/unit/test-x86-apicid.c
index bfabc0403a1a..2b104f86d7c2 100644
--- a/tests/unit/test-x86-cpuid.c
+++ b/tests/unit/test-x86-apicid.c
@@ -1,5 +1,5 @@
   /*
- *  Test code for x86 CPUID and Topology functions
+ *  Test code for x86 APIC ID and Topology functions
*

I'm not very sure. The "CPUID" sounds like a general test for kinds of CPU
IDs.

CPUID usually refers to that basic instruction in the x86 to obtain basic
cpu information. So such naming is prone to ambiguity.

The cpu topology info of x86 is parsed based on the apic id, including
the sub-ids of each topology levels (such as thread id/core id...etc.).
These sub-ids are all part of the apic id.


Besides APIC IDs computed from x86_apicid_from_cpu_idx(), there are also
topo IDs computed from x86_topo_ids_from_idx() although this kind of IDs
are not tested in test-x86-cpuid.c so far.

What about "test-x86-topo.c" or "test-x86-topo-ids.c"?

The first one is general enough, I think.

Thanks,
Yanan

*  Copyright (c) 2012 Red Hat Inc.
*





Re: [PATCH RESEND 06/18] i386: Introduce module-level cpu topology to CPUX86State

2023-02-14 Thread wangyanan (Y)

在 2023/2/13 17:36, Zhao Liu 写道:

From: Zhuocheng Ding 

smp command has the "clusters" parameter but x86 hasn't supported that
level. Though "clusters" was introduced to help define L2 cache topology
[1], using cluster to define x86's L2 cache topology will cause the
compatibility problem:

Well, the smp parameter "clusters" isn't destined to define L2 cache
topology. It's actually a CPU topology level concept above cores, in
which the cores may share some resources (the resources can be L2
cache or some others like L3 cache tags, depending on the Archs).

On some ARM64 chips, cores in the same cluster share a L2 and
hold their own L1D/I separately. There are also chips, where cores
in the same cluster have their own L2 & L1D/I cache separately,
and share a L3 cache tag.

Currently, x86 defaults that the L2 cache is shared in one core, which
actually implies a default setting "cores per L2 cache is 1" and
therefore implicitly defaults to having as many L2 caches as cores.

For example (i386 PC machine):
-smp 16,sockets=2,dies=2,cores=2,threads=2,maxcpus=16 (*)

Considering the topology of the L2 cache, this (*) implicitly means "1
core per L2 cache" and "2 L2 caches per die".

If we use cluster to configure L2 cache topology with the new default
setting "clusters per L2 cache is 1", the above semantics will change
to "2 cores per cluster" and "1 cluster per L2 cache", that is, "2
cores per L2 cache".

So the same command (*) will cause changes in the L2 cache topology,
further affecting the performance of the virtual machine.

Therefore, x86 should only treat cluster as a cpu topology level and
avoid using it to change L2 cache by default for compatibility.

Agree. I think all the smp parameters only indicates the CPU hierarchy,
while the cache layout is much more flexible.


"cluster" in smp is the CPU topology level which is between "core" and
die.

For x86, the "cluster" in smp is corresponding to the module level [2],
which is above the core level. So use the "module" other than "cluster"
in i386 code.

And please note that x86 already has a cpu topology level also named
"cluster" [2], this level is at the upper level of the package. Here,
the cluster in x86 cpu topology is completely different from the
"clusters" as the smp parameter. After the module level is introduced,
the cluster as the smp parameter will actually refer to the module level
of x86.

I see. So the reason for use of "module" instead of "cluster" is that there
is already cluster concept above Package in the x86 reference.

Thanks,
Yanan

[1]: 0d87178 (hw/core/machine: Introduce CPU cluster topology support)
[2]: SDM, vol.3, ch.9, 9.9.1 Hierarchical Mapping of Shared Resources.

Signed-off-by: Zhuocheng Ding 
Co-developed-by: Zhao Liu 
Signed-off-by: Zhao Liu 
---
  hw/i386/x86.c | 1 +
  target/i386/cpu.c | 1 +
  target/i386/cpu.h | 6 ++
  3 files changed, 8 insertions(+)

diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index eaff4227bd68..ae1bb562d6e2 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -306,6 +306,7 @@ void x86_cpu_pre_plug(HotplugHandler *hotplug_dev,
  init_topo_info(_info, x86ms);
  
  env->nr_dies = ms->smp.dies;

+env->nr_modules = ms->smp.clusters;
  
  /*

   * If APIC ID is not set,
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 4cda84eb96f1..61ec9a7499b8 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -6781,6 +6781,7 @@ static void x86_cpu_initfn(Object *obj)
  CPUX86State *env = >env;
  
  env->nr_dies = 1;

+env->nr_modules = 1;
  cpu_set_cpustate_pointers(cpu);
  
  object_property_add(obj, "feature-words", "X86CPUFeatureWordInfo",

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index d4bc19577a21..f3afea765982 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1810,7 +1810,13 @@ typedef struct CPUArchState {
  
  TPRAccess tpr_access_type;
  
+/* Number of dies per package. */

  unsigned nr_dies;
+/*
+ * Number of modules per die. Module level in x86 cpu topology is
+ * corresponding to smp.clusters.
+ */
+unsigned nr_modules;
  } CPUX86State;
  
  struct kvm_msrs;





Re: DMAR fault with qemu 7.2 and Ubuntu 22.04 base image

2023-02-14 Thread Klaus Jensen
On Feb 15 12:01, Major Saheb wrote:
> > Assuming you are *not* explicitly configuring shadow doorbells, then I
> > think you might have a broken driver that does not properly reset the
> > controller before using it (are you tripping CC.EN?). That could explain
> > the admin queue size of 32 (default admin queue depth for the Linux nvme
> > driver) as well as the db/ei_addrs being left over. And behavior wrt.
> > how the Linux driver disables the device might have changed between the
> > kernel version used in Ubuntu 20.04 and 22.04.
> 
> Thanks Klaus, I didn't had the driver source, so I acquired it and
> looked into it, the driver was not toggling the cc.en nor waiting for
> csts.ready the right way. So I implemented it and it started working
> perfectly.
> - R
> 
> On Tue, Feb 14, 2023 at 8:26 PM Klaus Jensen  wrote:
> >
> > On Feb 14 14:05, Klaus Jensen wrote:
> > > On Feb 14 17:34, Major Saheb wrote:
> > > > Thanks Peter for the reply. I tried to connect gdb to qemu and able to
> > > > break 'vtd_iova_to_slpte()', I dumped the following with both Ubuntu
> > > > 20.04 base image container which is the success case and Ubuntu 22.04
> > > > base image container which is failure case
> > > > One thing I observed is the NvmeSQueue::dma_addr is correctly set to
> > > > '0x8', however in failure case this value is 0x1196b1000. A
> > > > closer look indicates more fields in NvmeSQueue might be corrupted,
> > > > for example we are setting admin queue size as 512 but in failure case
> > > > it is showing 32.
> > > >
> > >
> > > Hi Major,
> > >
> > > It's obviously pretty bad if hw/nvme somehow corrupts the SQ structure,
> > > but it's difficult to say from this output.
> > >
> > > Are you configuring shadow doorbells (the db_addr and ei_addr's are
> > > set in both cases)?
> > >
> > > > > > Following is the partial qemu command line that I am using
> > > > > >
> > > > > > -device 
> > > > > > intel-iommu,intremap=on,caching-mode=on,eim=on,device-iotlb=on,aw-bits=48
> > > > > >
> > >
> > > I'm not sure if caching-mode=on and device-iotlb=on leads to any issues
> > > here? As far as I understand, this is mostly used with stuff like vhost.
> > > I've tested and developed vfio-based drivers against hw/nvme excessively
> > > and I'm not using anything besides `-device intel-iommu`.
> > >
> > > Do I undestand correctly that your setup is "just" a Ubuntu 22.04 guest
> > > with a container and a user-space driver to interact with the nvme
> > > devices available on the guest? No nested virtualization with vfio
> > > passthrough?
> >
> > Assuming you are *not* explicitly configuring shadow doorbells, then I
> > think you might have a broken driver that does not properly reset the
> > controller before using it (are you tripping CC.EN?). That could explain
> > the admin queue size of 32 (default admin queue depth for the Linux nvme
> > driver) as well as the db/ei_addrs being left over. And behavior wrt.
> > how the Linux driver disables the device might have changed between the
> > kernel version used in Ubuntu 20.04 and 22.04.

Awesome. Occam's Razor strikes again ;)


signature.asc
Description: PGP signature


Re: [PATCH v10 04/12] migration/qemu-file: Add qemu_file_get_to_fd()

2023-02-14 Thread Juan Quintela
Avihai Horon  wrote:
> Add new function qemu_file_get_to_fd() that allows reading data from
> QEMUFile and writing it straight into a given fd.
>
> This will be used later in VFIO migration code.
>
> Signed-off-by: Avihai Horon 
> Reviewed-by: Vladimir Sementsov-Ogievskiy 
> Reviewed-by: Cédric Le Goater 

Reviewed-by: Juan Quintela 




Re: [PATCH] target/s390x/arch_dump: Simplify memory allocation in s390x_write_elf64_notes()

2023-02-14 Thread Thomas Huth

On 15/02/2023 08.10, Philippe Mathieu-Daudé wrote:

On 15/2/23 06:48, Thomas Huth wrote:

We are not on a hot path here, so there is no real need for the logic
here with the split heap and stack space allocation. Simplify it by
always allocating memory from the heap.

Suggested-by: Philippe Mathieu-Daudé 
Signed-off-by: Thomas Huth 
---
  Based-on: <20230214141056.680969-1-th...@redhat.com>

  target/s390x/arch_dump.c | 20 ++--
  1 file changed, 6 insertions(+), 14 deletions(-)

diff --git a/target/s390x/arch_dump.c b/target/s390x/arch_dump.c
index a7c44ba49d..84e17effda 100644
--- a/target/s390x/arch_dump.c
+++ b/target/s390x/arch_dump.c
@@ -227,25 +227,23 @@ static int s390x_write_elf64_notes(const char 
*note_name,

 DumpState *s,
 const NoteFuncDesc *funcs)
  {
-    Note note, *notep;
+    g_autofree Note *notep = NULL;
  const NoteFuncDesc *nf;
-    int note_size, content_size;
+    int note_size, prev_size = 0, content_size;


We can start with:

   prev_size = sizeof(Note);

If this goes thru your tree, feel free to modify without respining.


But then I'd also need to initialize notep above differently, don't I?
And if I've got it right, this function sometimes also deals with chunks 
that are smaller, so I think it's cleaner if we start with zero instead of 
sizeof(Note).



Reviewed-by: Philippe Mathieu-Daudé 


Thanks!

 Thomas




Re: [PATCH v4 3/6] qapi: Add minor typing workaround for 3.6

2023-02-14 Thread Markus Armbruster
John Snow  writes:

> Pylint under 3.6 does not believe that Collection is subscriptable at
> runtime. It is, making this a Pylint
> bug. https://github.com/PyCQA/pylint/issues/2377
>
> They closed it as fixed, but that doesn't seem to be true as of Pylint
> 2.13.9, the latest version you can install under Python 3.6. 2.13.9 was
> released 2022-05-13, about seven months after the bug was closed.
>
> The least-annoying fix here is to just use the more specific type
> Sequence, only because it seems to work in 3.6.
>
> Signed-off-by: John Snow 
> ---
>  scripts/qapi/expr.py | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/scripts/qapi/expr.py b/scripts/qapi/expr.py
> index 5a1782b57ea..8701351fdfc 100644
> --- a/scripts/qapi/expr.py
> +++ b/scripts/qapi/expr.py
> @@ -33,11 +33,11 @@
>  
>  import re
>  from typing import (
> -Collection,
>  Dict,
>  Iterable,
>  List,
>  Optional,
> +Sequence,
>  Union,
>  cast,
>  )
> @@ -195,8 +195,8 @@ def check_defn_name_str(name: str, info: QAPISourceInfo, 
> meta: str) -> None:
>  def check_keys(value: _JSONObject,
> info: QAPISourceInfo,
> source: str,
> -   required: Collection[str],
> -   optional: Collection[str]) -> None:
> +   required: Sequence[str],
> +   optional: Sequence[str]) -> None:
>  """
>  Ensure that a dict has a specific set of keys.

The actual arguments are always List[str].  You actually used that until
v3 of the patch, and switched to the maximally general Collection[str]
in v4, with rationale that ended up in commit 538cd41065a:

qapi/expr.py: Modify check_keys to accept any Collection

This is a minor adjustment that lets parameters @required and
@optional take tuple arguments, in particular ().  Later patches will
make use of that.

No later patch ever did.

I'd prefer maximally stupid List[str], but it's no big deal either way.




Re: [PATCH 6/7] hw/isa: Assert isa_register_portio_list() gets non-NULL ISA device

2023-02-14 Thread Philippe Mathieu-Daudé

On 14/2/23 19:49, Richard Henderson wrote:

On 2/14/23 00:18, Philippe Mathieu-Daudé wrote:

  __attribute__((nonnull)) void a1(void *ptr)
  {
    // can no use assert(ptr) because compiler warning
  }


I briefly glossed over that...

I realize we'd probably want to add -fno-delete-null-pointer-checks 
if we make too much 


... here.  The compiler warning should go away with the right flag.


Doh, got it now!




Re: [PATCH] target/s390x/arch_dump: Simplify memory allocation in s390x_write_elf64_notes()

2023-02-14 Thread Philippe Mathieu-Daudé

On 15/2/23 06:48, Thomas Huth wrote:

We are not on a hot path here, so there is no real need for the logic
here with the split heap and stack space allocation. Simplify it by
always allocating memory from the heap.

Suggested-by: Philippe Mathieu-Daudé 
Signed-off-by: Thomas Huth 
---
  Based-on: <20230214141056.680969-1-th...@redhat.com>

  target/s390x/arch_dump.c | 20 ++--
  1 file changed, 6 insertions(+), 14 deletions(-)

diff --git a/target/s390x/arch_dump.c b/target/s390x/arch_dump.c
index a7c44ba49d..84e17effda 100644
--- a/target/s390x/arch_dump.c
+++ b/target/s390x/arch_dump.c
@@ -227,25 +227,23 @@ static int s390x_write_elf64_notes(const char *note_name,
 DumpState *s,
 const NoteFuncDesc *funcs)
  {
-Note note, *notep;
+g_autofree Note *notep = NULL;
  const NoteFuncDesc *nf;
-int note_size, content_size;
+int note_size, prev_size = 0, content_size;


We can start with:

  prev_size = sizeof(Note);

If this goes thru your tree, feel free to modify without respining.


Reviewed-by: Philippe Mathieu-Daudé 

Thanks!


  int ret = -1;
  
-assert(strlen(note_name) < sizeof(note.name));

+assert(strlen(note_name) < sizeof(notep->name));
  
  for (nf = funcs; nf->note_contents_func; nf++) {

-notep = 
  if (nf->pvonly && !s390_is_pv()) {
  continue;
  }
  
  content_size = nf->note_size_func ? nf->note_size_func() : nf->contents_size;

-note_size = sizeof(note) - sizeof(notep->contents) + content_size;
+note_size = sizeof(Note) - sizeof(notep->contents) + content_size;
  
-/* Notes with dynamic sizes need to allocate a note */

-if (nf->note_size_func) {
-notep = g_malloc(note_size);
+if (prev_size < note_size) {
+notep = g_realloc(notep, note_size);
  }





Re: [PATCH RESEND 05/18] i386/cpu: Consolidate the use of topo_info in cpu_x86_cpuid()

2023-02-14 Thread wangyanan (Y)

在 2023/2/15 15:10, Zhao Liu 写道:

On Wed, Feb 15, 2023 at 11:28:25AM +0800, wangyanan (Y) wrote:

Date: Wed, 15 Feb 2023 11:28:25 +0800
From: "wangyanan (Y)" 
Subject: Re: [PATCH RESEND 05/18] i386/cpu: Consolidate the use of
  topo_info in cpu_x86_cpuid()

在 2023/2/13 17:36, Zhao Liu 写道:

From: Zhao Liu 

In cpu_x86_cpuid(), there are many variables in representing the cpu
topology, e.g., topo_info, cs->nr_cores/cs->nr_threads.

Since the names of cs->nr_cores/cs->nr_threads does not accurately
represent its meaning, the use of cs->nr_cores/cs->nr_threads is prone
to confusion and mistakes.

And the structure X86CPUTopoInfo names its memebers clearly, thus the
variable "topo_info" should be preferred.

Suggested-by: Robert Hoo 
Signed-off-by: Zhao Liu 
---
   target/i386/cpu.c | 30 ++
   1 file changed, 18 insertions(+), 12 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 7833505092d8..4cda84eb96f1 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -5215,11 +5215,15 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
uint32_t count,
   uint32_t limit;
   uint32_t signature[3];
   X86CPUTopoInfo topo_info;
+uint32_t cpus_per_pkg;
   topo_info.dies_per_pkg = env->nr_dies;
   topo_info.cores_per_die = cs->nr_cores / env->nr_dies;
   topo_info.threads_per_core = cs->nr_threads;
+cpus_per_pkg = topo_info.dies_per_pkg * topo_info.cores_per_die *
+   topo_info.threads_per_core;
+
   /* Calculate & apply limits for different index ranges */
   if (index >= 0xC000) {
   limit = env->cpuid_xlevel2;
@@ -5255,8 +5259,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
uint32_t count,
   *ecx |= CPUID_EXT_OSXSAVE;
   }
   *edx = env->features[FEAT_1_EDX];
-if (cs->nr_cores * cs->nr_threads > 1) {
-*ebx |= (cs->nr_cores * cs->nr_threads) << 16;
+if (cpus_per_pkg > 1) {
+*ebx |= cpus_per_pkg << 16;
   *edx |= CPUID_HT;
   }
   if (!cpu->enable_pmu) {
@@ -5293,10 +5297,12 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
uint32_t count,
*/
   if (*eax & 31) {
   int host_vcpus_per_cache = 1 + ((*eax & 0x3FFC000) >> 14);
-int vcpus_per_socket = cs->nr_cores * cs->nr_threads;
-if (cs->nr_cores > 1) {
+int vcpus_per_socket = cpus_per_pkg;

Would it make sense to directly use cpus_per_pkg here

+int cores_per_socket = topo_info.cores_per_die *
+   topo_info.dies_per_pkg;

There are other places in cpu_x86_cpuid where cs->nr_cores is used
separately, why not make a global "cores_per_pkg" like cpus_per_pkg
and also tweak the other places?

Yeah, good idea.


+if (cores_per_socket > 1) {
   *eax &= ~0xFC00;
-*eax |= (pow2ceil(cs->nr_cores) - 1) << 26;
+*eax |= (pow2ceil(cores_per_socket) - 1) << 26;
   }
   if (host_vcpus_per_cache > vcpus_per_socket) {
   *eax &= ~0x3FFC000;
@@ -5436,12 +5442,12 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
uint32_t count,
   switch (count) {
   case 0:
   *eax = apicid_core_offset(_info);
-*ebx = cs->nr_threads;
+*ebx = topo_info.threads_per_core;

There are many other places in cpu_x86_cpuid where cs->nr_threads
is used separately, such as encode_cache_cpuid4(***), should we
replace them all?

In a previous patch [1], I replaced the use of cs->nr_threads/nr_cores in
the call of encode_cache_cpuid4().

The cleanest way is to pass topo_info to encode_cache_cpuid4(), but this
involves the modification of the interface format and the use of the
cache topo level, so I included it in a follow-up patch [2].

Ok, I see. I have not reached there.


[1]: [PATCH RESEND 04/18] i386/cpu: Fix number of addressable IDs in
  CPUID.04,
  https://lists.gnu.org/archive/html/qemu-devel/2023-02/msg03188.html
[2]: [PATCH RESEND 15/18] i386: Use CPUCacheInfo.share_level to encode
  CPUID[4].EAX[bits 25:14],
  https://lists.gnu.org/archive/html/qemu-devel/2023-02/msg03199.html


   *ecx |= CPUID_TOPOLOGY_LEVEL_SMT;
   break;
   case 1:
   *eax = apicid_pkg_offset(_info);
-*ebx = cs->nr_cores * cs->nr_threads;
+*ebx = cpus_per_pkg;
   *ecx |= CPUID_TOPOLOGY_LEVEL_CORE;
   break;
   default:
@@ -5472,7 +5478,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
uint32_t count,
   switch (count) {
   case 0:
   *eax = apicid_core_offset(_info);
-*ebx = cs->nr_threads;
+*ebx = topo_info.threads_per_core;
   *ecx |= CPUID_TOPOLOGY_LEVEL_SMT;
   break;
  

Re: [PATCH RESEND 05/18] i386/cpu: Consolidate the use of topo_info in cpu_x86_cpuid()

2023-02-14 Thread Zhao Liu
On Wed, Feb 15, 2023 at 11:28:25AM +0800, wangyanan (Y) wrote:
> Date: Wed, 15 Feb 2023 11:28:25 +0800
> From: "wangyanan (Y)" 
> Subject: Re: [PATCH RESEND 05/18] i386/cpu: Consolidate the use of
>  topo_info in cpu_x86_cpuid()
> 
> 在 2023/2/13 17:36, Zhao Liu 写道:
> > From: Zhao Liu 
> > 
> > In cpu_x86_cpuid(), there are many variables in representing the cpu
> > topology, e.g., topo_info, cs->nr_cores/cs->nr_threads.
> > 
> > Since the names of cs->nr_cores/cs->nr_threads does not accurately
> > represent its meaning, the use of cs->nr_cores/cs->nr_threads is prone
> > to confusion and mistakes.
> > 
> > And the structure X86CPUTopoInfo names its memebers clearly, thus the
> > variable "topo_info" should be preferred.
> > 
> > Suggested-by: Robert Hoo 
> > Signed-off-by: Zhao Liu 
> > ---
> >   target/i386/cpu.c | 30 ++
> >   1 file changed, 18 insertions(+), 12 deletions(-)
> > 
> > diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> > index 7833505092d8..4cda84eb96f1 100644
> > --- a/target/i386/cpu.c
> > +++ b/target/i386/cpu.c
> > @@ -5215,11 +5215,15 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t 
> > index, uint32_t count,
> >   uint32_t limit;
> >   uint32_t signature[3];
> >   X86CPUTopoInfo topo_info;
> > +uint32_t cpus_per_pkg;
> >   topo_info.dies_per_pkg = env->nr_dies;
> >   topo_info.cores_per_die = cs->nr_cores / env->nr_dies;
> >   topo_info.threads_per_core = cs->nr_threads;
> > +cpus_per_pkg = topo_info.dies_per_pkg * topo_info.cores_per_die *
> > +   topo_info.threads_per_core;
> > +
> >   /* Calculate & apply limits for different index ranges */
> >   if (index >= 0xC000) {
> >   limit = env->cpuid_xlevel2;
> > @@ -5255,8 +5259,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
> > uint32_t count,
> >   *ecx |= CPUID_EXT_OSXSAVE;
> >   }
> >   *edx = env->features[FEAT_1_EDX];
> > -if (cs->nr_cores * cs->nr_threads > 1) {
> > -*ebx |= (cs->nr_cores * cs->nr_threads) << 16;
> > +if (cpus_per_pkg > 1) {
> > +*ebx |= cpus_per_pkg << 16;
> >   *edx |= CPUID_HT;
> >   }
> >   if (!cpu->enable_pmu) {
> > @@ -5293,10 +5297,12 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t 
> > index, uint32_t count,
> >*/
> >   if (*eax & 31) {
> >   int host_vcpus_per_cache = 1 + ((*eax & 0x3FFC000) >> 14);
> > -int vcpus_per_socket = cs->nr_cores * cs->nr_threads;
> > -if (cs->nr_cores > 1) {
> > +int vcpus_per_socket = cpus_per_pkg;
> Would it make sense to directly use cpus_per_pkg here
> > +int cores_per_socket = topo_info.cores_per_die *
> > +   topo_info.dies_per_pkg;
> There are other places in cpu_x86_cpuid where cs->nr_cores is used
> separately, why not make a global "cores_per_pkg" like cpus_per_pkg
> and also tweak the other places?

Yeah, good idea.

> > +if (cores_per_socket > 1) {
> >   *eax &= ~0xFC00;
> > -*eax |= (pow2ceil(cs->nr_cores) - 1) << 26;
> > +*eax |= (pow2ceil(cores_per_socket) - 1) << 26;
> >   }
> >   if (host_vcpus_per_cache > vcpus_per_socket) {
> >   *eax &= ~0x3FFC000;
> > @@ -5436,12 +5442,12 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t 
> > index, uint32_t count,
> >   switch (count) {
> >   case 0:
> >   *eax = apicid_core_offset(_info);
> > -*ebx = cs->nr_threads;
> > +*ebx = topo_info.threads_per_core;
> There are many other places in cpu_x86_cpuid where cs->nr_threads
> is used separately, such as encode_cache_cpuid4(***), should we
> replace them all?

In a previous patch [1], I replaced the use of cs->nr_threads/nr_cores in
the call of encode_cache_cpuid4().

The cleanest way is to pass topo_info to encode_cache_cpuid4(), but this
involves the modification of the interface format and the use of the
cache topo level, so I included it in a follow-up patch [2].

[1]: [PATCH RESEND 04/18] i386/cpu: Fix number of addressable IDs in
 CPUID.04,
 https://lists.gnu.org/archive/html/qemu-devel/2023-02/msg03188.html
[2]: [PATCH RESEND 15/18] i386: Use CPUCacheInfo.share_level to encode
 CPUID[4].EAX[bits 25:14],
 https://lists.gnu.org/archive/html/qemu-devel/2023-02/msg03199.html

> >   *ecx |= CPUID_TOPOLOGY_LEVEL_SMT;
> >   break;
> >   case 1:
> >   *eax = apicid_pkg_offset(_info);
> > -*ebx = cs->nr_cores * cs->nr_threads;
> > +*ebx = cpus_per_pkg;
> >   *ecx |= CPUID_TOPOLOGY_LEVEL_CORE;
> >   break;
> >   default:
> > @@ -5472,7 +5478,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
> > uint32_t count,
> >   

[PATCH v2] memory: Optimize replay of guest mapping

2023-02-14 Thread Zhenzhong Duan
On x86, there are two notifiers registered due to vtd-ir memory region
splitting the whole address space. During replay of the address space
for each notifier, the whole address space is scanned which is
unnecessory.

We only need to scan the space belong to notifier montiored space.

Assert when notifier is used to monitor beyond iommu memory region's
address space.

Signed-off-by: Zhenzhong Duan 
---
v2: Add an assertion per Peter Xu
Tested only on x86 with a net card passed to guest(kvm/tcg), ping/ssh pass.

 hw/i386/intel_iommu.c | 2 +-
 softmmu/memory.c  | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 98a5c304a7d7..6b1de80e8573 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -3831,7 +3831,7 @@ static void vtd_iommu_replay(IOMMUMemoryRegion *iommu_mr, 
IOMMUNotifier *n)
 .domain_id = vtd_get_domain_id(s, , vtd_as->pasid),
 };
 
-vtd_page_walk(s, , 0, ~0ULL, , vtd_as->pasid);
+vtd_page_walk(s, , n->start, n->end, , vtd_as->pasid);
 }
 } else {
 trace_vtd_replay_ce_invalid(bus_n, PCI_SLOT(vtd_as->devfn),
diff --git a/softmmu/memory.c b/softmmu/memory.c
index 9d64efca269b..da7d84661972 100644
--- a/softmmu/memory.c
+++ b/softmmu/memory.c
@@ -1900,6 +1900,7 @@ int memory_region_register_iommu_notifier(MemoryRegion 
*mr,
 iommu_mr = IOMMU_MEMORY_REGION(mr);
 assert(n->notifier_flags != IOMMU_NOTIFIER_NONE);
 assert(n->start <= n->end);
+assert(n->end <= memory_region_size(mr));
 assert(n->iommu_idx >= 0 &&
n->iommu_idx < memory_region_iommu_num_indexes(iommu_mr));
 
@@ -1923,7 +1924,6 @@ uint64_t 
memory_region_iommu_get_min_page_size(IOMMUMemoryRegion *iommu_mr)
 
 void memory_region_iommu_replay(IOMMUMemoryRegion *iommu_mr, IOMMUNotifier *n)
 {
-MemoryRegion *mr = MEMORY_REGION(iommu_mr);
 IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_GET_CLASS(iommu_mr);
 hwaddr addr, granularity;
 IOMMUTLBEntry iotlb;
@@ -1936,7 +1936,7 @@ void memory_region_iommu_replay(IOMMUMemoryRegion 
*iommu_mr, IOMMUNotifier *n)
 
 granularity = memory_region_iommu_get_min_page_size(iommu_mr);
 
-for (addr = 0; addr < memory_region_size(mr); addr += granularity) {
+for (addr = n->start; addr < n->end; addr += granularity) {
 iotlb = imrc->translate(iommu_mr, addr, IOMMU_NONE, n->iommu_idx);
 if (iotlb.perm != IOMMU_NONE) {
 n->notify(n, );
-- 
2.25.1




Re: [PATCH 0/8] aspeed: I2C fixes, -drive removal (first step)

2023-02-14 Thread Markus Armbruster
Cédric Le Goater  writes:

> Hello,
>
> This series starts with a first set of patches fixing I2C slave mode
> in the Aspeed I2C controller, a test device and its associated test in
> avocado.
>
> Follow some cleanups which allow the use of block devices instead of
> drives. So that, instead of specifying :
>
>   -drive file=./flash-ast2600-evb,format=raw,if=mtd
>   -drive file=./ast2600-evb.pnor,format=raw,if=mtd
>   ...
>
> and guessing from the order which bus the device is attached to, we
> can use :
>
>   -blockdev node-name=fmc0,driver=file,filename=./bmc.img
>   -device mx66u51235f,bus=ssi.0,drive=fmc0
>   -blockdev node-name=fmc1,driver=file,filename=./bmc-alt.img
>   -device mx66u51235f,bus=ssi.0,drive=fmc1 
>   -blockdev node-name=pnor,driver=file,filename=./pnor
>   -device mx66l1g45g,bus=ssi.1,drive=pnor
>   ...
>
> It is not perfect, the CS index still depends on the order, but it is
> now possible to run a machine without -drive ...,if=mtd.

Lovely!

Does this cover all uses of IF_MTD, or only some?

> This lacks the final patch enabling the '-nodefaults' option by not
> creating the default devices if specified on the command line. It
> needs some more evaluation of the possible undesired effects. 

Are you thinking of something similar to the default CD-ROM, i.e. use
default_list to have -device suppress a certain kind of default devices,
and also have -nodefaults suppress them all?




Re: DMAR fault with qemu 7.2 and Ubuntu 22.04 base image

2023-02-14 Thread Major Saheb
> Assuming you are *not* explicitly configuring shadow doorbells, then I
> think you might have a broken driver that does not properly reset the
> controller before using it (are you tripping CC.EN?). That could explain
> the admin queue size of 32 (default admin queue depth for the Linux nvme
> driver) as well as the db/ei_addrs being left over. And behavior wrt.
> how the Linux driver disables the device might have changed between the
> kernel version used in Ubuntu 20.04 and 22.04.

Thanks Klaus, I didn't had the driver source, so I acquired it and
looked into it, the driver was not toggling the cc.en nor waiting for
csts.ready the right way. So I implemented it and it started working
perfectly.
- R

On Tue, Feb 14, 2023 at 8:26 PM Klaus Jensen  wrote:
>
> On Feb 14 14:05, Klaus Jensen wrote:
> > On Feb 14 17:34, Major Saheb wrote:
> > > Thanks Peter for the reply. I tried to connect gdb to qemu and able to
> > > break 'vtd_iova_to_slpte()', I dumped the following with both Ubuntu
> > > 20.04 base image container which is the success case and Ubuntu 22.04
> > > base image container which is failure case
> > > One thing I observed is the NvmeSQueue::dma_addr is correctly set to
> > > '0x8', however in failure case this value is 0x1196b1000. A
> > > closer look indicates more fields in NvmeSQueue might be corrupted,
> > > for example we are setting admin queue size as 512 but in failure case
> > > it is showing 32.
> > >
> >
> > Hi Major,
> >
> > It's obviously pretty bad if hw/nvme somehow corrupts the SQ structure,
> > but it's difficult to say from this output.
> >
> > Are you configuring shadow doorbells (the db_addr and ei_addr's are
> > set in both cases)?
> >
> > > > > Following is the partial qemu command line that I am using
> > > > >
> > > > > -device 
> > > > > intel-iommu,intremap=on,caching-mode=on,eim=on,device-iotlb=on,aw-bits=48
> > > > >
> >
> > I'm not sure if caching-mode=on and device-iotlb=on leads to any issues
> > here? As far as I understand, this is mostly used with stuff like vhost.
> > I've tested and developed vfio-based drivers against hw/nvme excessively
> > and I'm not using anything besides `-device intel-iommu`.
> >
> > Do I undestand correctly that your setup is "just" a Ubuntu 22.04 guest
> > with a container and a user-space driver to interact with the nvme
> > devices available on the guest? No nested virtualization with vfio
> > passthrough?
>
> Assuming you are *not* explicitly configuring shadow doorbells, then I
> think you might have a broken driver that does not properly reset the
> controller before using it (are you tripping CC.EN?). That could explain
> the admin queue size of 32 (default admin queue depth for the Linux nvme
> driver) as well as the db/ei_addrs being left over. And behavior wrt.
> how the Linux driver disables the device might have changed between the
> kernel version used in Ubuntu 20.04 and 22.04.



Re: [PATCH v1 RFC Zisslpcfi 4/9] target/riscv: helper functions for forward and backward cfi

2023-02-14 Thread LIU Zhiwei



On 2023/2/9 14:23, Deepak Gupta wrote:

Implementation for forward cfi and backward cfi needs helper function
to determine if currently fcfi and bcfi are enabled. Enable depends on
privilege mode and settings in sstatus/menvcfg/henvcfg/mseccfg CSRs.

Signed-off-by: Deepak Gupta 
Signed-off-by: Kip Walker  
---
  target/riscv/cpu.h|  2 ++
  target/riscv/cpu_helper.c | 51 +++
  2 files changed, 53 insertions(+)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 18db61a06a..d14ea4f91d 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -568,6 +568,8 @@ bool riscv_cpu_virt_enabled(CPURISCVState *env);
  void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
  bool riscv_cpu_two_stage_lookup(int mmu_idx);
  int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch);
+bool cpu_get_fcfien(CPURISCVState *env);
+bool cpu_get_bcfien(CPURISCVState *env);
  hwaddr riscv_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
  G_NORETURN void  riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
 MMUAccessType access_type, int 
mmu_idx,
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 9a28816521..a397023840 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -30,6 +30,7 @@
  #include "sysemu/cpu-timers.h"
  #include "cpu_bits.h"
  #include "debug.h"
+#include "pmp.h"
  
  int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)

  {
@@ -40,6 +41,56 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
  #endif
  }
  
+bool cpu_get_fcfien(CPURISCVState *env)

+{
+#ifdef CONFIG_USER_ONLY
+return false;
+#else
+/* no cfi extension, return false */
+if (!env_archcpu(env)->cfg.ext_cfi) {
+return false;
+}
+
+switch (env->priv) {
+case PRV_U:
+return (env->mstatus & MSTATUS_UFCFIEN) ? true : false;


It's not right. We should also check for menvcfg.cfie. The same to other 
checks in S mode or U mode.


Zhiwei


+case PRV_S:
+return (env->menvcfg & MENVCFG_SFCFIEN) ? true : false;
+case PRV_M:
+return (env->mseccfg & MSECCFG_MFCFIEN) ? true : false;
+default:
+g_assert_not_reached();
+}
+#endif
+}
+
+bool cpu_get_bcfien(CPURISCVState *env)
+{
+#ifdef CONFIG_USER_ONLY
+return false;
+#else
+/* no cfi extension, return false */
+if (!env_archcpu(env)->cfg.ext_cfi) {
+return false;
+}
+
+switch (env->priv) {
+case PRV_U:
+return (env->mstatus & MSTATUS_UBCFIEN) ? true : false;
+
+/*
+ * no gating for back cfi in M/S mode. back cfi is always on for
+ * M/S mode
+ */
+case PRV_S:
+case PRV_M:
+return true;
+default:
+g_assert_not_reached();
+}
+#endif
+}
+
  void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
target_ulong *cs_base, uint32_t *pflags)
  {




Re: [PATCH v1 RFC Zisslpcfi 3/9] target/riscv: implements CSRs and new bits in existing CSRs in zisslpcfi

2023-02-14 Thread LIU Zhiwei

I don't find the modification for read_mstatus.

Zhiwei

On 2023/2/15 13:47, LIU Zhiwei wrote:


On 2023/2/9 14:23, Deepak Gupta wrote:
CSR_SSP and CSR_LPLR are new CSR additions to cpu/hart. This patch 
allows

access to these CSRs. A predicate routine handles access to these CSR as
per specification.

This patch also implments new bit definitions in 
menvcfg/henvcfg/mstatus/
sstatus CSRs to master enabled cfi and enable forward cfi in S and M 
mode.

mstatus CSR holds forward and backward cfi enabling for U mode.

There is no enabling bit for backward cfi in S and M mode. It is always
enabled if extension is implemented by CPU.

Signed-off-by: Deepak Gupta 
Signed-off-by: Kip Walker  
---
  target/riscv/csr.c | 137 -
  target/riscv/pmp.c |   9 +++
  2 files changed, 145 insertions(+), 1 deletion(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 0db2c233e5..24e208ebed 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -163,6 +163,50 @@ static RISCVException ctr32(CPURISCVState *env, 
int csrno)

  return ctr(env, csrno);
  }
  +static RISCVException cfi(CPURISCVState *env, int csrno)
+{
+    /* no cfi extension */
+    if (!env_archcpu(env)->cfg.ext_cfi) {
+    return RISCV_EXCP_ILLEGAL_INST;
+    }
+    /*
+ * CONFIG_USER_MODE always allow access for now. Better for user 
mode only

+ * functionality
+ */
+#if !defined(CONFIG_USER_ONLY)
+    /* current priv not M */
+    if (env->priv != PRV_M) {
+    /* menvcfg says no CFI */
+    if (!get_field(env->menvcfg, MENVCFG_CFI)) {
+    return RISCV_EXCP_ILLEGAL_INST;
+    }
+
+    /* V = 1 and henvcfg says no CFI. raise virtual instr fault */
+    if (riscv_cpu_virt_enabled(env) &&
+    !get_field(env->henvcfg, HENVCFG_CFI)) {
+    return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+    }
+
+    /*
+ * LPLR and SSP are not accessible to U mode if disabled via 
status

+ * CSR
+ */
+    if (env->priv == PRV_U) {
+    if (csrno == CSR_LPLR &&
+    !get_field(env->mstatus, MSTATUS_UFCFIEN)) {
+    return RISCV_EXCP_ILLEGAL_INST;
+    }
+    if (csrno == CSR_SSP &&
+    !get_field(env->mstatus, MSTATUS_UBCFIEN)) {
+    return RISCV_EXCP_ILLEGAL_INST;
+    }
+    }
+    }
+#endif
+
+    return RISCV_EXCP_NONE;
+}
+
  #if !defined(CONFIG_USER_ONLY)
  static RISCVException mctr(CPURISCVState *env, int csrno)
  {
@@ -485,6 +529,32 @@ static RISCVException seed(CPURISCVState *env, 
int csrno)

  #endif
  }
  +/* Zisslpcfi CSR_LPLR read/write */
+static int read_lplr(CPURISCVState *env, int csrno, target_ulong *val)
+{
+    *val = env->lplr;
+    return RISCV_EXCP_NONE;
+}
+
+static int write_lplr(CPURISCVState *env, int csrno, target_ulong val)
+{
+    env->lplr = val & (LPLR_UL | LPLR_ML | LPLR_LL);
+    return RISCV_EXCP_NONE;
+}
+
+/* Zisslpcfi CSR_SSP read/write */
+static int read_ssp(CPURISCVState *env, int csrno, target_ulong *val)
+{
+    *val = env->ssp;
+    return RISCV_EXCP_NONE;
+}
+
+static int write_ssp(CPURISCVState *env, int csrno, target_ulong val)
+{
+    env->ssp = val;
+    return RISCV_EXCP_NONE;
+}
+
  /* User Floating-Point CSRs */
  static RISCVException read_fflags(CPURISCVState *env, int csrno,
    target_ulong *val)
@@ -1227,7 +1297,7 @@ static RISCVException 
write_mstatus(CPURISCVState *env, int csrno,

    /* flush tlb on mstatus fields that affect VM */
  if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP | MSTATUS_MPV |
-    MSTATUS_MPRV | MSTATUS_SUM)) {
+    MSTATUS_MPRV | MSTATUS_SUM | MSTATUS_UFCFIEN | 
MSTATUS_UBCFIEN)) {


These two fields should be guarded by the check of ext_cfi.

And MSTATUS_UBCFIEN field change don't need flush tlb.

I didn't get why we should flush tlb for forward cfi. For background, 
there are some enhancement for the PTE and PMP, we may need do some
memory adjustments. But forward cfi just adds some instructions. Why 
we should flush tlb? Does the tlb can't be used any more?



  tlb_flush(env_cpu(env));
  }
  mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
@@ -1250,6 +1320,11 @@ static RISCVException 
write_mstatus(CPURISCVState *env, int csrno,

  }
  }
  +    /* If cfi extension is available, then apply cfi status mask */
+    if (env_archcpu(env)->cfg.ext_cfi) {
+    mask |= CFISTATUS_M_MASK;
+    }
+
  mstatus = (mstatus & ~mask) | (val & mask);
    if (xl > MXL_RV32) {
@@ -1880,9 +1955,17 @@ static RISCVException 
write_menvcfg(CPURISCVState *env, int csrno,

    target_ulong val)
  {
  uint64_t mask = MENVCFG_FIOM | MENVCFG_CBIE | MENVCFG_CBCFE | 
MENVCFG_CBZE;

+    uint64_t cfi_mask = MENVCFG_CFI | MENVCFG_SFCFIEN;
    if (riscv_cpu_mxl(env) == MXL_RV64) {
  mask |= MENVCFG_PBMTE | MENVCFG_STCE;
+  

Re: [PATCH v1 RFC Zisslpcfi 5/9] target/riscv: state save and restore of zisslppcfi state

2023-02-14 Thread LIU Zhiwei



On 2023/2/9 14:24, Deepak Gupta wrote:

zisslpcfi's forward cfi if enabled on a hart, enables tracking of
indirect branches. CPU/hart internally keeps a state `elp` short
for expecting landing pad instruction. This state goes into
LP_EXPECTED on an indirect branch. But an interrupt/exception can occur
before target instruction is executed. In such a case this state must be
preserved so that it can be restored later. zisslpcfi saves elp state in
`sstatus` CSR.


And mstatus CSR.

Otherwise,

Reviewed-by: LIU Zhiwei 


This patch saves elp state in sstatus CSR on trap delivery
while restores from sstatus CSR on trap return.

Additionally state in sstatus CSR must have save and restore zisslpcfi
state on exiting from hypervisor and entering into hypervisor.

Signed-off-by: Deepak Gupta 
Signed-off-by: Kip Walker  
---
  target/riscv/cpu_bits.h   |  5 +
  target/riscv/cpu_helper.c | 26 ++
  target/riscv/op_helper.c  | 12 
  3 files changed, 43 insertions(+)

diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 1663ba5775..37100ec8f6 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -594,6 +594,11 @@ typedef enum {
  
  #define CFISTATUS_S_MASK(SSTATUS_UFCFIEN | SSTATUS_UBCFIEN | \

   SSTATUS_SPELP)
+/* enum for branch tracking state in cpu/hart */
+typedef enum {
+NO_LP_EXPECTED = 0,
+LP_EXPECTED = 1,
+} cfi_elp;
  
  /* hstatus CSR bits */

  #define HSTATUS_VSBE 0x0020
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index a397023840..fc188683c9 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -534,6 +534,16 @@ void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
  if (riscv_has_ext(env, RVF)) {
  mstatus_mask |= MSTATUS_FS;
  }
+
+/*
+ * If cfi extension available, menvcfg.CFI = 1 and henvcfg.CFI = 1,
+ * then apply CFI mask on mstatus
+ */
+if (env_archcpu(env)->cfg.ext_cfi &&
+get_field(env->menvcfg, MENVCFG_CFI) &&
+get_field(env->henvcfg, HENVCFG_CFI)) {
+mstatus_mask |= CFISTATUS_S_MASK;
+}
  bool current_virt = riscv_cpu_virt_enabled(env);
  
  g_assert(riscv_has_ext(env, RVH));

@@ -1723,6 +1733,10 @@ void riscv_cpu_do_interrupt(CPUState *cs)
  if (env->priv <= PRV_S &&
  cause < TARGET_LONG_BITS && ((deleg >> cause) & 1)) {
  /* handle the trap in S-mode */
+/* save elp status */
+if (cpu_get_fcfien(env)) {
+env->mstatus = set_field(env->mstatus, MSTATUS_SPELP, env->elp);
+}
  if (riscv_has_ext(env, RVH)) {
  uint64_t hdeleg = async ? env->hideleg : env->hedeleg;
  
@@ -1772,6 +1786,10 @@ void riscv_cpu_do_interrupt(CPUState *cs)

  riscv_cpu_set_mode(env, PRV_S);
  } else {
  /* handle the trap in M-mode */
+/* save elp status */
+if (cpu_get_fcfien(env)) {
+env->mstatus = set_field(env->mstatus, MSTATUS_MPELP, env->elp);
+}
  if (riscv_has_ext(env, RVH)) {
  if (riscv_cpu_virt_enabled(env)) {
  riscv_cpu_swap_hypervisor_regs(env);
@@ -1803,6 +1821,14 @@ void riscv_cpu_do_interrupt(CPUState *cs)
  riscv_cpu_set_mode(env, PRV_M);
  }
  
+/*

+ * Interrupt/exception/trap delivery is asynchronous event and as per
+ * Zisslpcfi spec CPU should clear up the ELP state. If cfi extension is
+ * available, clear ELP state.
+ */
+if (cpu->cfg.ext_cfi) {
+env->elp = NO_LP_EXPECTED;
+}
  /* NOTE: it is not necessary to yield load reservations here. It is only
   * necessary for an SC from "another hart" to cause a load reservation
   * to be yielded. Refer to the memory consistency model section of the
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 878bcb03b8..d15893aa82 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -176,6 +176,12 @@ target_ulong helper_sret(CPURISCVState *env)
  riscv_cpu_set_virt_enabled(env, prev_virt);
  }
  
+/* If forward cfi enabled for target, restore elp status */

+if (cpu_get_fcfien(env)) {
+env->elp = get_field(env->mstatus, MSTATUS_SPELP);
+env->mstatus = set_field(env->mstatus, MSTATUS_SPELP, 0);
+}
+
  riscv_cpu_set_mode(env, prev_priv);
  
  return retpc;

@@ -220,6 +226,12 @@ target_ulong helper_mret(CPURISCVState *env)
  riscv_cpu_set_virt_enabled(env, prev_virt);
  }
  
+/* If forward cfi enabled for target, restore elp status */

+if (cpu_get_fcfien(env)) {
+env->elp = get_field(env->mstatus, MSTATUS_MPELP);
+env->mstatus = set_field(env->mstatus, MSTATUS_MPELP, 0);
+}
+
  return retpc;
  }
  




Re: [PATCH v2 06/12] bsd-user: Helper routines h2t_old_sysctl

2023-02-14 Thread Warner Losh
On Tue, Feb 14, 2023 at 2:16 PM Richard Henderson <
richard.hender...@linaro.org> wrote:

> On 2/13/23 14:27, Warner Losh wrote:
> > +/*
> > + * Convert the old value from host to target.
>
> host vs guest is clearer language; "target" gets overloaded, even though
> still present in
> the code base.
>

OK. Will do. We have that all over the place upstream... I'll start there
too...


>
> > + *
> > + * For LONG and ULONG on ABI32, we need to 'down convert' the 8 byte
> quantities
> > + * to 4 bytes. The caller setup a buffer in host memory to get this
> data from
> > + * the kernel and pass it to us. We do the down conversion and adjust
> the length
> > + * so the caller knows what to write as the returned length into the
> target when
> > + * it copies the down converted values into the target.
> > + *
> > + * For normal integral types, we just need to byte swap. No size
> changes.
> > + *
> > + * For strings and node data, there's no conversion needed.
> > + *
> > + * For opaque data, per sysctl OID converts take care of it.
> > + */
> > +static void G_GNUC_UNUSED h2t_old_sysctl(void *holdp, size_t *holdlen,
> uint32_t kind)
>
> h2g.
>

OK.


> > +/*
> > + * hlen == 0 for CTLTYPE_STRING and CTLTYPE_NODE, which need no
> conversion
> > + * as well as CTLTYPE_OPAQUE, which needs special converters.
> > + */
> > +if (hlen == 0) {
> > +return;
> > +}
> > +
> > +while (len < *holdlen) {
> > +if (hlen == tlen) {
> > +switch (hlen) {
> > +case 1:
> > +/* Nothing needed: no byteswapping and assigning in
> place */
> > +break;
> > +case 2:
> > +*(uint16_t *)tp = tswap16(*(uint16_t *)hp);
> > +break;
> > +case 4:
> > +*(uint32_t *)tp = tswap32(*(uint32_t *)hp);
> > +break;
> > +case 8:
> > +*(uint64_t *)tp = tswap64(*(uint64_t *)hp);
> > +break;
> > +}
>
> default: g_assert_not_reached().
>

Ah!  I need that in several places... Thanks.


> > +}
> > +#ifdef TARGET_ABI32
> > +else {
> > +/*
> > + * Saturating assignment for the only two types that differ
> between
> > + * 32-bit and 64-bit machines. All other integral types
> have the
> > + * same, fixed size and will be converted w/o loss of
> precision
> > + * in the above switch.
> > + */
> > +switch (kind & CTLTYPE) {
> > +case CTLTYPE_LONG:
> > +*(abi_long *)tp = tswap32(h2t_long_sat(*(long *)hp));
> > +break;
> > +case CTLTYPE_ULONG:
> > +*(abi_ulong *)tp = tswap32(h2t_ulong_sat(*(u_long
> *)hp));
> > +break;
> > +}
>
> default: g_assert_not_reached().
>
> > +}
> > +#endif
>
> #else
>  g_assert_not_reached();
>

Gotcha... Thanks!

Warner


>
> r~
>


Re: [PATCH] target/s390x/arch_dump: Fix memory corruption in s390x_write_elf64_notes()

2023-02-14 Thread Thomas Huth

On 15/02/2023 06.20, Thomas Huth wrote:

On 14/02/2023 15.58, Philippe Mathieu-Daudé wrote:

On 14/2/23 15:10, Thomas Huth wrote:

"note_size" can be smaller than sizeof(note), so unconditionally calling
memset(notep, 0, sizeof(note)) could cause a memory corruption here in
case notep has been allocated dynamically, thus let's use note_size as
length argument for memset() instead.


Correct.

I wonder why use one notep* pointing to a stack allocated or a heap
allocated buffer. This isn't hot path, one heap use could simplify
this code complexity IMO.


You've got a point. I'll give it a try and send a v2.


Actually, it looked better as a separate, independent patch, so I sent it as 
"Simplify memory allocation in s390x_write_elf64_notes()" (based on this one 
here).


 Thomas




[PATCH] target/s390x/arch_dump: Simplify memory allocation in s390x_write_elf64_notes()

2023-02-14 Thread Thomas Huth
We are not on a hot path here, so there is no real need for the logic
here with the split heap and stack space allocation. Simplify it by
always allocating memory from the heap.

Suggested-by: Philippe Mathieu-Daudé 
Signed-off-by: Thomas Huth 
---
 Based-on: <20230214141056.680969-1-th...@redhat.com>

 target/s390x/arch_dump.c | 20 ++--
 1 file changed, 6 insertions(+), 14 deletions(-)

diff --git a/target/s390x/arch_dump.c b/target/s390x/arch_dump.c
index a7c44ba49d..84e17effda 100644
--- a/target/s390x/arch_dump.c
+++ b/target/s390x/arch_dump.c
@@ -227,25 +227,23 @@ static int s390x_write_elf64_notes(const char *note_name,
DumpState *s,
const NoteFuncDesc *funcs)
 {
-Note note, *notep;
+g_autofree Note *notep = NULL;
 const NoteFuncDesc *nf;
-int note_size, content_size;
+int note_size, prev_size = 0, content_size;
 int ret = -1;
 
-assert(strlen(note_name) < sizeof(note.name));
+assert(strlen(note_name) < sizeof(notep->name));
 
 for (nf = funcs; nf->note_contents_func; nf++) {
-notep = 
 if (nf->pvonly && !s390_is_pv()) {
 continue;
 }
 
 content_size = nf->note_size_func ? nf->note_size_func() : 
nf->contents_size;
-note_size = sizeof(note) - sizeof(notep->contents) + content_size;
+note_size = sizeof(Note) - sizeof(notep->contents) + content_size;
 
-/* Notes with dynamic sizes need to allocate a note */
-if (nf->note_size_func) {
-notep = g_malloc(note_size);
+if (prev_size < note_size) {
+notep = g_realloc(notep, note_size);
 }
 
 memset(notep, 0, note_size);
@@ -258,15 +256,9 @@ static int s390x_write_elf64_notes(const char *note_name,
 /* Get contents and write them out */
 (*nf->note_contents_func)(notep, cpu, id);
 ret = f(notep, note_size, s);
-
-if (nf->note_size_func) {
-g_free(notep);
-}
-
 if (ret < 0) {
 return -1;
 }
-
 }
 
 return 0;
-- 
2.31.1




Re: [PATCH v1 RFC Zisslpcfi 3/9] target/riscv: implements CSRs and new bits in existing CSRs in zisslpcfi

2023-02-14 Thread LIU Zhiwei



On 2023/2/9 14:23, Deepak Gupta wrote:

CSR_SSP and CSR_LPLR are new CSR additions to cpu/hart. This patch allows
access to these CSRs. A predicate routine handles access to these CSR as
per specification.

This patch also implments new bit definitions in menvcfg/henvcfg/mstatus/
sstatus CSRs to master enabled cfi and enable forward cfi in S and M mode.
mstatus CSR holds forward and backward cfi enabling for U mode.

There is no enabling bit for backward cfi in S and M mode. It is always
enabled if extension is implemented by CPU.

Signed-off-by: Deepak Gupta 
Signed-off-by: Kip Walker  
---
  target/riscv/csr.c | 137 -
  target/riscv/pmp.c |   9 +++
  2 files changed, 145 insertions(+), 1 deletion(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 0db2c233e5..24e208ebed 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -163,6 +163,50 @@ static RISCVException ctr32(CPURISCVState *env, int csrno)
  return ctr(env, csrno);
  }
  
+static RISCVException cfi(CPURISCVState *env, int csrno)

+{
+/* no cfi extension */
+if (!env_archcpu(env)->cfg.ext_cfi) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+/*
+ * CONFIG_USER_MODE always allow access for now. Better for user mode only
+ * functionality
+ */
+#if !defined(CONFIG_USER_ONLY)
+/* current priv not M */
+if (env->priv != PRV_M) {
+/* menvcfg says no CFI */
+if (!get_field(env->menvcfg, MENVCFG_CFI)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+/* V = 1 and henvcfg says no CFI. raise virtual instr fault */
+if (riscv_cpu_virt_enabled(env) &&
+!get_field(env->henvcfg, HENVCFG_CFI)) {
+return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+}
+
+/*
+ * LPLR and SSP are not accessible to U mode if disabled via status
+ * CSR
+ */
+if (env->priv == PRV_U) {
+if (csrno == CSR_LPLR &&
+!get_field(env->mstatus, MSTATUS_UFCFIEN)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+if (csrno == CSR_SSP &&
+!get_field(env->mstatus, MSTATUS_UBCFIEN)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+}
+}
+#endif
+
+return RISCV_EXCP_NONE;
+}
+
  #if !defined(CONFIG_USER_ONLY)
  static RISCVException mctr(CPURISCVState *env, int csrno)
  {
@@ -485,6 +529,32 @@ static RISCVException seed(CPURISCVState *env, int csrno)
  #endif
  }
  
+/* Zisslpcfi CSR_LPLR read/write */

+static int read_lplr(CPURISCVState *env, int csrno, target_ulong *val)
+{
+*val = env->lplr;
+return RISCV_EXCP_NONE;
+}
+
+static int write_lplr(CPURISCVState *env, int csrno, target_ulong val)
+{
+env->lplr = val & (LPLR_UL | LPLR_ML | LPLR_LL);
+return RISCV_EXCP_NONE;
+}
+
+/* Zisslpcfi CSR_SSP read/write */
+static int read_ssp(CPURISCVState *env, int csrno, target_ulong *val)
+{
+*val = env->ssp;
+return RISCV_EXCP_NONE;
+}
+
+static int write_ssp(CPURISCVState *env, int csrno, target_ulong val)
+{
+env->ssp = val;
+return RISCV_EXCP_NONE;
+}
+
  /* User Floating-Point CSRs */
  static RISCVException read_fflags(CPURISCVState *env, int csrno,
target_ulong *val)
@@ -1227,7 +1297,7 @@ static RISCVException write_mstatus(CPURISCVState *env, 
int csrno,
  
  /* flush tlb on mstatus fields that affect VM */

  if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP | MSTATUS_MPV |
-MSTATUS_MPRV | MSTATUS_SUM)) {
+MSTATUS_MPRV | MSTATUS_SUM | MSTATUS_UFCFIEN | MSTATUS_UBCFIEN)) {


These two fields should be guarded by the check of ext_cfi.

And MSTATUS_UBCFIEN field change don't need flush tlb.

I didn't get why we should flush tlb for forward cfi. For background, 
there are some enhancement for the PTE and PMP, we may need do some
memory adjustments. But forward cfi just adds some instructions. Why we 
should flush tlb? Does the tlb can't be used any more?



  tlb_flush(env_cpu(env));
  }
  mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
@@ -1250,6 +1320,11 @@ static RISCVException write_mstatus(CPURISCVState *env, 
int csrno,
  }
  }
  
+/* If cfi extension is available, then apply cfi status mask */

+if (env_archcpu(env)->cfg.ext_cfi) {
+mask |= CFISTATUS_M_MASK;
+}
+
  mstatus = (mstatus & ~mask) | (val & mask);
  
  if (xl > MXL_RV32) {

@@ -1880,9 +1955,17 @@ static RISCVException write_menvcfg(CPURISCVState *env, 
int csrno,
target_ulong val)
  {
  uint64_t mask = MENVCFG_FIOM | MENVCFG_CBIE | MENVCFG_CBCFE | 
MENVCFG_CBZE;
+uint64_t cfi_mask = MENVCFG_CFI | MENVCFG_SFCFIEN;
  
  if (riscv_cpu_mxl(env) == MXL_RV64) {

  mask |= MENVCFG_PBMTE | MENVCFG_STCE;
+if (env_archcpu(env)->cfg.ext_cfi) {
+mask |= cfi_mask;
+/* If any cfi 

Re: [PATCH] target/s390x/arch_dump: Fix memory corruption in s390x_write_elf64_notes()

2023-02-14 Thread Thomas Huth

On 14/02/2023 15.58, Philippe Mathieu-Daudé wrote:

On 14/2/23 15:10, Thomas Huth wrote:

"note_size" can be smaller than sizeof(note), so unconditionally calling
memset(notep, 0, sizeof(note)) could cause a memory corruption here in
case notep has been allocated dynamically, thus let's use note_size as
length argument for memset() instead.


Correct.

I wonder why use one notep* pointing to a stack allocated or a heap
allocated buffer. This isn't hot path, one heap use could simplify
this code complexity IMO.


You've got a point. I'll give it a try and send a v2.

 Thanks,
   Thomas




Re: [PATCH v1] Adding new machine Yosemitev2 in QEMU

2023-02-14 Thread karthikeyan Pasupathi
Ok, will do that.

On Tue, Feb 14, 2023 at 12:35 PM Cédric Le Goater  wrote:

> Hello,
>
> [ adding the lists ]
>
> >  > +static void fb_bmc_i2c_init(AspeedMachineState *bmc)
> >
> > The same routine name is proposed in the tiogapass patch :
> >
> >
> https://lore.kernel.org/qemu-devel/20230210122641.837614-1-pkarthikeyan1...@gmail.com/
> <
> https://lore.kernel.org/qemu-devel/20230210122641.837614-1-pkarthikeyan1...@gmail.com/
> >
> >
> > Do you have plans to populate the I2C buses differently ?
> >
> >
> > This is an initial patch we have been working on adding more specific
> configurations in the future.
>
> OK. Then please rename the routine with a "yosemite" like prefix.
>
> Thanks,
>
> C.
>
>
>


Re: [PATCH v1 RFC Zisslpcfi 2/9] target/riscv: zisslpcfi CSR, bit positions and other definitions

2023-02-14 Thread LIU Zhiwei



On 2023/2/9 14:23, Deepak Gupta wrote:

`zisslpcfi` extension adds two new CSRs. CSR_SSP and CSR_LPLR.
- CSR_SSP: This CSR holds shadow stack pointer for current privilege mode
CSR_SSP is accessible in all modes. Each mode must establish
it's own CSR_SSP.

- CSR_LPLR: This CSR holds label value set at the callsite by compiler.
 On call target label check instructions are emitted by
 compiler which check label value against value present in
 CSR_LPRL.

Enabling of `zisslpcfi` is controlled via menvcfg (for S/HS/VS/U/VU) and
henvcfg (for VS/VU) at bit position 60.

Each mode has enable/disable bits for forward cfi. Backward cfi doesn't
have separate enable/disable bits for S and M mode. User forward cfi and
user backward cfi enable/disable bits are in mstatus/sstatus CSR.
Supervisor forward cfi enable/disable bit are in menvcfg and henvcfg CSR.
Machine mode forward cfi enable/disable bit is in mseccfg CSR.

If forward cfi enabled, all indirect branches must land on a landing pad
instruction (`lpcll`, introduced in later commits). CPU/hart tracks this
internally using a landing pad tracker called `elp` short for `expecting
landing pad`. An interrupt can occur between an indirect branch and
target. If such an event occurs `elp` is saved away in mstatus/sstatus
CSR

Signed-off-by: Deepak Gupta 
Signed-off-by: Kip Walker  
---
  target/riscv/cpu.h  |  5 +
  target/riscv/cpu_bits.h | 25 +
  target/riscv/pmp.h  |  3 ++-
  3 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 9a923760b2..18db61a06a 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -181,6 +181,11 @@ struct CPUArchState {
  
  uint32_t features;
  
+/* CFI Extension user mode registers and state */

+uint32_t lplr;
+target_ulong ssp;
+cfi_elp  elp;


I think you are coding according the sections of the specification. 
However,  when upstream code,

don't add declaration or definition if you don't use it in this patch.

This patch should be split into patches where use these definitions.


+
  #ifdef CONFIG_USER_ONLY
  uint32_t elf_flags;
  #endif
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 8b0d7e20ea..1663ba5775 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -39,6 +39,10 @@
  
  /* Control and Status Registers */
  
+/* CFI CSRs */

+#define CSR_LPLR0x006

I didn't see the CSR encoding  number from the link in cover-letter.

+#define CSR_SSP 0x020
+
  /* User Trap Setup */
  #define CSR_USTATUS 0x000
  #define CSR_UIE 0x004
@@ -542,6 +546,10 @@
  #define MSTATUS_TVM 0x0010 /* since: priv-1.10 */
  #define MSTATUS_TW  0x0020 /* since: priv-1.10 */
  #define MSTATUS_TSR 0x0040 /* since: priv-1.10 */
+#define MSTATUS_UFCFIEN 0x0080 /* Zisslpcfi-0.1 */
+#define MSTATUS_UBCFIEN 0x0100 /* Zisslpcfi-0.1 */
+#define MSTATUS_SPELP   0x0200 /* Zisslpcfi-0.1 */
+#define MSTATUS_MPELP   0x0400 /* Zisslpcfi-0.1 */
  #define MSTATUS_GVA 0x40ULL
  #define MSTATUS_MPV 0x80ULL
  
@@ -572,12 +580,21 @@ typedef enum {

  #define SSTATUS_XS  0x00018000
  #define SSTATUS_SUM 0x0004 /* since: priv-1.10 */
  #define SSTATUS_MXR 0x0008
+#define SSTATUS_UFCFIEN MSTATUS_UFCFIEN /* Zisslpcfi-0.1 */
+#define SSTATUS_UBCFIEN MSTATUS_UBCFIEN /* Zisslpcfi-0.1 */
+#define SSTATUS_SPELP   MSTATUS_SPELP   /* Zisslpcfi-0.1 */
  
  #define SSTATUS64_UXL   0x0003ULL
  
  #define SSTATUS32_SD0x8000

  #define SSTATUS64_SD0x8000ULL
  
+#define CFISTATUS_M_MASK(MSTATUS_UFCFIEN | MSTATUS_UBCFIEN | \

+ MSTATUS_MPELP | MSTATUS_SPELP)
+
+#define CFISTATUS_S_MASK(SSTATUS_UFCFIEN | SSTATUS_UBCFIEN | \
+ SSTATUS_SPELP)

Why not the VSSTATUS?

+
  /* hstatus CSR bits */
  #define HSTATUS_VSBE 0x0020
  #define HSTATUS_GVA  0x0040
@@ -747,10 +764,14 @@ typedef enum RISCVException {
  #define MENVCFG_CBIE   (3UL << 4)
  #define MENVCFG_CBCFE  BIT(6)
  #define MENVCFG_CBZE   BIT(7)
+#define MENVCFG_SFCFIENBIT(59)
+#define MENVCFG_CFIBIT(60)


MENVCFG_CFIE according to the specification.  The definitions in other 
places  should also use X_CFIE.


The same comment here with Weiwei, or you can use BIT_ULL.

Zhiwei


  #define MENVCFG_PBMTE  (1ULL << 62)
  #define MENVCFG_STCE   (1ULL << 63)
  
  /* For RV32 */

+#define MENVCFGH_SFCFIEN   BIT(27)
+#define MENVCFGH_CFI   BIT(28)
  #define MENVCFGH_PBMTE BIT(30)
  #define MENVCFGH_STCE

Re: [PATCH RESEND 03/18] softmmu: Fix CPUSTATE.nr_cores' calculation

2023-02-14 Thread Zhao Liu
On Wed, Feb 15, 2023 at 10:58:07AM +0800, wangyanan (Y) wrote:
> Date: Wed, 15 Feb 2023 10:58:07 +0800
> From: "wangyanan (Y)" 
> Subject: Re: [PATCH RESEND 03/18] softmmu: Fix CPUSTATE.nr_cores'
>  calculation
> 
> Hi Zhao,
> 
> 在 2023/2/13 17:36, Zhao Liu 写道:
> > From: Zhuocheng Ding 
> > 
> > >From CPUState.nr_cores' comment, it represents "number of cores within
> > this CPU package".
> > 
> > After 003f230 (machine: Tweak the order of topology members in struct
> > CpuTopology), the meaning of smp.cores changed to "the number of cores
> > in one die", but this commit missed to change CPUState.nr_cores'
> > caculation, so that CPUState.nr_cores became wrong and now it
> > misses to consider numbers of clusters and dies.
> > 
> > At present, only i386 is using CPUState.nr_cores.
> > 
> > But as for i386, which supports die level, the uses of CPUState.nr_cores
> > are very confusing:
> > 
> > Early uses are based on the meaning of "cores per package" (before die
> > is introduced into i386), and later uses are based on "cores per die"
> > (after die's introduction).
> > 
> > This difference is due to that commit a94e142 (target/i386: Add CPUID.1F
> > generation support for multi-dies PCMachine) misunderstood that
> > CPUState.nr_cores means "cores per die" when caculated
> > CPUID.1FH.01H:EBX. After that, the changes in i386 all followed this
> > wrong understanding.
> > 
> > With the influence of 003f230 and a94e142, for i386 currently the result
> > of CPUState.nr_cores is "cores per die", thus the original uses of
> > CPUState.cores based on the meaning of "cores per package" are wrong
> > when mutiple dies exist:
> > 1. In cpu_x86_cpuid() of target/i386/cpu.c, CPUID.01H:EBX[bits 23:16] is
> > incorrect because it expects "cpus per package" but now the
> > result is "cpus per die".
> > 2. In cpu_x86_cpuid() of target/i386/cpu.c, for all leaves of CPUID.04H:
> > EAX[bits 31:26] is incorrect because they expect "cpus per package"
> > but now the result is "cpus per die". The error not only impacts the
> > EAX caculation in cache_info_passthrough case, but also impacts other
> > cases of setting cache topology for Intel CPU according to cpu
> > topology (specifically, the incoming parameter "num_cores" expects
> > "cores per package" in encode_cache_cpuid4()).
> > 3. In cpu_x86_cpuid() of target/i386/cpu.c, CPUID.0BH.01H:EBX[bits
> > 15:00] is incorrect because the EBX of 0BH.01H (core level) expects
> > "cpus per package", which may be different with 1FH.01H (The reason
> > is 1FH can support more levels. For QEMU, 1FH also supports die,
> > 1FH.01H:EBX[bits 15:00] expects "cpus per die").
> > 4. In cpu_x86_cpuid() of target/i386/cpu.c, when CPUID.8001H is
> > caculated, here "cpus per package" is expected to be checked, but in
> > fact, now it checks "cpus per die". Though "cpus per die" also works
> > for this code logic, this isn't consistent with AMD's APM.
> > 5. In cpu_x86_cpuid() of target/i386/cpu.c, CPUID.8008H:ECX expects
> > "cpus per package" but it obtains "cpus per die".
> > 6. In simulate_rdmsr() of target/i386/hvf/x86_emu.c, in
> > kvm_rdmsr_core_thread_count() of target/i386/kvm/kvm.c, and in
> > helper_rdmsr() of target/i386/tcg/sysemu/misc_helper.c,
> > MSR_CORE_THREAD_COUNT expects "cpus per package" and "cores per
> > package", but in these functions, it obtains "cpus per die" and
> > "cores per die".
> > 
> > On the other hand, these uses are correct now (they are added in/after
> > a94e142):
> > 1. In cpu_x86_cpuid() of target/i386/cpu.c, topo_info.cores_per_die
> > meets the actual meaning of CPUState.nr_cores ("cores per die").
> > 2. In cpu_x86_cpuid() of target/i386/cpu.c, vcpus_per_socket (in CPUID.
> > 04H's caculation) considers number of dies, so it's correct.
> > 3. In cpu_x86_cpuid() of target/i386/cpu.c, CPUID.1FH.01H:EBX[bits
> > 15:00] needs "cpus per die" and it gets the correct result, and
> > CPUID.1FH.02H:EBX[bits 15:00] gets correct "cpus per package".
> > 
> > When CPUState.nr_cores is correctly changed to "cores per package" again
> > , the above errors will be fixed without extra work, but the "currently"
> > correct cases will go wrong and need special handling to pass correct
> > "cpus/cores per die" they want.
> > 
> > Thus in this patch, we fix CPUState.nr_cores' caculation to fit the
> > original meaning "cores per package", as well as changing caculation of
> > topo_info.cores_per_die, vcpus_per_socket and CPUID.1FH.
> > 
> > In addition, in the nr_threads' comment, specify it represents the
> > number of threads in the "core" to avoid confusion.
> > 
> > Fixes: a94e142 (target/i386: Add CPUID.1F generation support for multi-dies 
> > PCMachine)
> > Fixes: 003f230 (machine: Tweak the order of topology members in struct 
> > CpuTopology)
> > Signed-off-by: Zhuocheng Ding 
> > Co-developed-by: Zhao Liu 
> > Signed-off-by: Zhao Liu 
> > ---
> >   

Re: [PATCH RESEND 05/18] i386/cpu: Consolidate the use of topo_info in cpu_x86_cpuid()

2023-02-14 Thread wangyanan (Y)

在 2023/2/13 17:36, Zhao Liu 写道:

From: Zhao Liu 

In cpu_x86_cpuid(), there are many variables in representing the cpu
topology, e.g., topo_info, cs->nr_cores/cs->nr_threads.

Since the names of cs->nr_cores/cs->nr_threads does not accurately
represent its meaning, the use of cs->nr_cores/cs->nr_threads is prone
to confusion and mistakes.

And the structure X86CPUTopoInfo names its memebers clearly, thus the
variable "topo_info" should be preferred.

Suggested-by: Robert Hoo 
Signed-off-by: Zhao Liu 
---
  target/i386/cpu.c | 30 ++
  1 file changed, 18 insertions(+), 12 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 7833505092d8..4cda84eb96f1 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -5215,11 +5215,15 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
uint32_t count,
  uint32_t limit;
  uint32_t signature[3];
  X86CPUTopoInfo topo_info;
+uint32_t cpus_per_pkg;
  
  topo_info.dies_per_pkg = env->nr_dies;

  topo_info.cores_per_die = cs->nr_cores / env->nr_dies;
  topo_info.threads_per_core = cs->nr_threads;
  
+cpus_per_pkg = topo_info.dies_per_pkg * topo_info.cores_per_die *

+   topo_info.threads_per_core;
+
  /* Calculate & apply limits for different index ranges */
  if (index >= 0xC000) {
  limit = env->cpuid_xlevel2;
@@ -5255,8 +5259,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
uint32_t count,
  *ecx |= CPUID_EXT_OSXSAVE;
  }
  *edx = env->features[FEAT_1_EDX];
-if (cs->nr_cores * cs->nr_threads > 1) {
-*ebx |= (cs->nr_cores * cs->nr_threads) << 16;
+if (cpus_per_pkg > 1) {
+*ebx |= cpus_per_pkg << 16;
  *edx |= CPUID_HT;
  }
  if (!cpu->enable_pmu) {
@@ -5293,10 +5297,12 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
uint32_t count,
   */
  if (*eax & 31) {
  int host_vcpus_per_cache = 1 + ((*eax & 0x3FFC000) >> 14);
-int vcpus_per_socket = cs->nr_cores * cs->nr_threads;
-if (cs->nr_cores > 1) {
+int vcpus_per_socket = cpus_per_pkg;

Would it make sense to directly use cpus_per_pkg here

+int cores_per_socket = topo_info.cores_per_die *
+   topo_info.dies_per_pkg;

There are other places in cpu_x86_cpuid where cs->nr_cores is used
separately, why not make a global "cores_per_pkg" like cpus_per_pkg
and also tweak the other places?

+if (cores_per_socket > 1) {
  *eax &= ~0xFC00;
-*eax |= (pow2ceil(cs->nr_cores) - 1) << 26;
+*eax |= (pow2ceil(cores_per_socket) - 1) << 26;
  }
  if (host_vcpus_per_cache > vcpus_per_socket) {
  *eax &= ~0x3FFC000;
@@ -5436,12 +5442,12 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
uint32_t count,
  switch (count) {
  case 0:
  *eax = apicid_core_offset(_info);
-*ebx = cs->nr_threads;
+*ebx = topo_info.threads_per_core;

There are many other places in cpu_x86_cpuid where cs->nr_threads
is used separately, such as encode_cache_cpuid4(***), should we
replace them all?

  *ecx |= CPUID_TOPOLOGY_LEVEL_SMT;
  break;
  case 1:
  *eax = apicid_pkg_offset(_info);
-*ebx = cs->nr_cores * cs->nr_threads;
+*ebx = cpus_per_pkg;
  *ecx |= CPUID_TOPOLOGY_LEVEL_CORE;
  break;
  default:
@@ -5472,7 +5478,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
uint32_t count,
  switch (count) {
  case 0:
  *eax = apicid_core_offset(_info);
-*ebx = cs->nr_threads;
+*ebx = topo_info.threads_per_core;
  *ecx |= CPUID_TOPOLOGY_LEVEL_SMT;
  break;
  case 1:
@@ -5482,7 +5488,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
uint32_t count,
  break;
  case 2:
  *eax = apicid_pkg_offset(_info);
-*ebx = cs->nr_cores * cs->nr_threads;
+*ebx = cpus_per_pkg;
  *ecx |= CPUID_TOPOLOGY_LEVEL_DIE;
  break;
  default:
@@ -5707,7 +5713,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
uint32_t count,
   * discards multiple thread information if it is set.
   * So don't set it here for Intel to make Linux guests happy.
   */
-if (cs->nr_cores * cs->nr_threads > 1) {
+if (cpus_per_pkg > 1) {
  if (env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1 ||
  env->cpuid_vendor2 != CPUID_VENDOR_INTEL_2 ||
  env->cpuid_vendor3 != CPUID_VENDOR_INTEL_3) {
@@ -5769,7 +5775,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
uint32_t count,
   *eax |= 

Re: [PATCH RESEND 02/18] tests: Rename test-x86-cpuid.c to test-x86-apicid.c

2023-02-14 Thread Zhao Liu
On Wed, Feb 15, 2023 at 10:36:34AM +0800, wangyanan (Y) wrote:
> Date: Wed, 15 Feb 2023 10:36:34 +0800
> From: "wangyanan (Y)" 
> Subject: Re: [PATCH RESEND 02/18] tests: Rename test-x86-cpuid.c to
>  test-x86-apicid.c
> 
> 在 2023/2/13 17:36, Zhao Liu 写道:
> > From: Zhao Liu 
> > 
> > In fact, this unit tests APIC ID other than CPUID.
> > Rename to test-x86-apicid.c to make its name more in line with its
> > actual content.
> > 
> > Signed-off-by: Zhao Liu 
> > ---
> >   MAINTAINERS| 2 +-
> >   tests/unit/meson.build | 4 ++--
> >   tests/unit/{test-x86-cpuid.c => test-x86-apicid.c} | 2 +-
> >   3 files changed, 4 insertions(+), 4 deletions(-)
> >   rename tests/unit/{test-x86-cpuid.c => test-x86-apicid.c} (99%)
> > 
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 96e25f62acaa..71c1bc24371b 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -1679,7 +1679,7 @@ F: include/hw/southbridge/piix.h
> >   F: hw/misc/sga.c
> >   F: hw/isa/apm.c
> >   F: include/hw/isa/apm.h
> > -F: tests/unit/test-x86-cpuid.c
> > +F: tests/unit/test-x86-apicid.c
> >   F: tests/qtest/test-x86-cpuid-compat.c
> >   PC Chipset
> > diff --git a/tests/unit/meson.build b/tests/unit/meson.build
> > index ffa444f4323c..a9df2843e92e 100644
> > --- a/tests/unit/meson.build
> > +++ b/tests/unit/meson.build
> > @@ -20,8 +20,8 @@ tests = {
> > 'test-opts-visitor': [testqapi],
> > 'test-visitor-serialization': [testqapi],
> > 'test-bitmap': [],
> > -  # all code tested by test-x86-cpuid is inside topology.h
> > -  'test-x86-cpuid': [],
> > +  # all code tested by test-x86-apicid is inside topology.h
> > +  'test-x86-apicid': [],
> > 'test-cutils': [],
> > 'test-div128': [],
> > 'test-shift128': [],
> > diff --git a/tests/unit/test-x86-cpuid.c b/tests/unit/test-x86-apicid.c
> > similarity index 99%
> > rename from tests/unit/test-x86-cpuid.c
> > rename to tests/unit/test-x86-apicid.c
> > index bfabc0403a1a..2b104f86d7c2 100644
> > --- a/tests/unit/test-x86-cpuid.c
> > +++ b/tests/unit/test-x86-apicid.c
> > @@ -1,5 +1,5 @@
> >   /*
> > - *  Test code for x86 CPUID and Topology functions
> > + *  Test code for x86 APIC ID and Topology functions
> >*
> I'm not very sure. The "CPUID" sounds like a general test for kinds of CPU
> IDs.

CPUID usually refers to that basic instruction in the x86 to obtain basic
cpu information. So such naming is prone to ambiguity.

The cpu topology info of x86 is parsed based on the apic id, including
the sub-ids of each topology levels (such as thread id/core id...etc.).
These sub-ids are all part of the apic id.

> Besides APIC IDs computed from x86_apicid_from_cpu_idx(), there are also
> topo IDs computed from x86_topo_ids_from_idx() although this kind of IDs
> are not tested in test-x86-cpuid.c so far.

What about "test-x86-topo.c" or "test-x86-topo-ids.c"?

> 
> Thanks,
> Yanan
> >*  Copyright (c) 2012 Red Hat Inc.
> >*
> 



Re: [RFC 06/52] hw/cpu: Introduce hybrid CPU topology

2023-02-14 Thread Zhao Liu
On Tue, Feb 14, 2023 at 07:23:37PM +0800, wangyanan (Y) wrote:
> Date: Tue, 14 Feb 2023 19:23:37 +0800
> From: "wangyanan (Y)" 
> Subject: Re: [RFC 06/52] hw/cpu: Introduce hybrid CPU topology
> 
> 在 2023/2/14 18:16, Zhao Liu 写道:
> > On Mon, Feb 13, 2023 at 09:18:05PM +0800, wangyanan (Y) wrote:
> > > Date: Mon, 13 Feb 2023 21:18:05 +0800
> > > From: "wangyanan (Y)" 
> > > Subject: Re: [RFC 06/52] hw/cpu: Introduce hybrid CPU topology
> > > 
> > > Hi Zhao,
> > > 
> > > 在 2023/2/13 17:49, Zhao Liu 写道:
> > > > From: Zhao Liu 
> > > > 
> > > > For smp systems, the parts in one topology level are the same. But now
> > > > there are more and more systems with hybrid architectures. Different
> > > > parts of the same topology level may have differences. For example,
> > > > Intel's Alder Lake series CPU has two types of cores, so the CPU
> > > > topology is no longer symmetrical.
> > > > 
> > > > The hybrid topology is compatible with the smp topology type, that is,
> > > > different parts on the same level of the hybrid topology can set to be
> > > > the same, but the hybrid topology will introduce more complexity (need
> > > > to allocate more memory, organized with array or linked-list), so the
> > > > original smp topology support is retained while introducing the hybrid
> > > > topology, and the hybrid topology is only built when the hybrid is
> > > > explicitly required.
> > > > 
> > > > Therefore, we introduce the definition support of hybrid cpu topology
> > > > here. At the same time, in order to unify with the original smp, we
> > > > introduce a new cpu topology structure that can support smp topology
> > > > or hybrid topology. This structure will replace the CpuTopology type (in
> > > > include/hw/boards.h) used by MachineState.smp.
> > > > 
> > > > As for now, we only support two hybrid topology levels: core and
> > > > cluster.
> > > > 
> > > > Signed-off-by: Zhao Liu 
> > > > ---
> > > >MAINTAINERS   |   1 +
> > > >include/hw/cpu/cpu-topology.h | 117 
> > > > ++
> > > >qapi/machine.json |  12 
> > > >3 files changed, 130 insertions(+)
> > > >create mode 100644 include/hw/cpu/cpu-topology.h
> > > > 
> > > > diff --git a/MAINTAINERS b/MAINTAINERS
> > > > index 58794885ced3..918a9418d98e 100644
> > > > --- a/MAINTAINERS
> > > > +++ b/MAINTAINERS
> > > > @@ -1742,6 +1742,7 @@ F: qapi/machine-target.json
> > > >F: include/hw/boards.h
> > > >F: include/hw/core/cpu.h
> > > >F: include/hw/cpu/cluster.h
> > > > +F: include/hw/cpu/cpu-topology.h
> > > Should't it be in include/hw/core/* directory?
> > Yes, I'll move it to the correct place.
> > 
> > > >F: include/sysemu/numa.h
> > > >F: tests/unit/test-smp-parse.c
> > > >T: git https://gitlab.com/ehabkost/qemu.git machine-next
> > > > diff --git a/include/hw/cpu/cpu-topology.h 
> > > > b/include/hw/cpu/cpu-topology.h
> > > > new file mode 100644
> > > > index ..8268ea3a8569
> > > > --- /dev/null
> > > > +++ b/include/hw/cpu/cpu-topology.h
> > > > @@ -0,0 +1,117 @@
> > > > +/*
> > > > + * CPU topology defination for Machine core
> > > > + *
> > > > + * Copyright (c) 2023 Intel Corporation
> > > > + * Author: Zhao Liu 
> > > > + *
> > > > + * This program is free software; you can redistribute it and/or modify
> > > > + * it under the terms of the GNU General Public License as published by
> > > > + * the Free Software Foundation; either version 2 of the License,
> > > > + * or (at your option) any later version.
> > > > + *
> > > > + * This program is distributed in the hope that it will be useful,
> > > > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > > > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > > > + * GNU General Public License for more details.
> > > > + *
> > > > + * You should have received a copy of the GNU General Public License
> > > > + * along with this program; if not, see .
> > > > + */
> > > > +
> > > > +#ifndef CPU_TOPOLOGY_H
> > > > +#define CPU_TOPOLOGY_H
> > > > +
> > > > +#include "qemu/queue.h"
> > > > +
> > > > +/**
> > > > + * SmpCpuTopology - smp cpu topology defination.
> > > > + *
> > > > + * For smp system, the parts in one topology level are the same.
> > > > + *
> > > > + * @sockets: the number of sockets on the machine
> > > > + * @dies: the number of dies in one socket
> > > > + * @clusters: the number of clusters in one die
> > > > + * @cores: the number of cores in one cluster
> > > > + * @threads: the number of threads in one core
> > > > + */
> > > > +typedef struct SmpCpuTopology {
> > > > +unsigned int sockets;
> > > > +unsigned int dies;
> > > > +unsigned int clusters;
> > > > +unsigned int cores;
> > > > +unsigned int threads;
> > > > +} SmpCpuTopology;
> > > > +
> > > > +/**
> > > > + * HybridCore - hybrid core topology defination:
> > > > + * @threads: the number of threads in one core.
> > > > + 

Re: [RFC 06/52] hw/cpu: Introduce hybrid CPU topology

2023-02-14 Thread Zhao Liu
On Tue, Feb 14, 2023 at 10:27:53AM +0100, Philippe Mathieu-Daudé wrote:
> Date: Tue, 14 Feb 2023 10:27:53 +0100
> From: Philippe Mathieu-Daudé 
> Subject: Re: [RFC 06/52] hw/cpu: Introduce hybrid CPU topology
> 
> On 14/2/23 10:30, Zhao Liu wrote:
> > On Mon, Feb 13, 2023 at 02:10:17PM +0100, Philippe Mathieu-Daudé wrote:
> > > Date: Mon, 13 Feb 2023 14:10:17 +0100
> > > From: Philippe Mathieu-Daudé 
> > > Subject: Re: [RFC 06/52] hw/cpu: Introduce hybrid CPU topology
> > > 
> > > On 13/2/23 10:49, Zhao Liu wrote:
> > > > From: Zhao Liu 
> > > > 
> > > > For smp systems, the parts in one topology level are the same. But now
> > > > there are more and more systems with hybrid architectures. Different
> > > > parts of the same topology level may have differences. For example,
> > > > Intel's Alder Lake series CPU has two types of cores, so the CPU
> > > > topology is no longer symmetrical.
> > > > 
> > > > The hybrid topology is compatible with the smp topology type, that is,
> > > > different parts on the same level of the hybrid topology can set to be
> > > > the same, but the hybrid topology will introduce more complexity (need
> > > > to allocate more memory, organized with array or linked-list), so the
> > > > original smp topology support is retained while introducing the hybrid
> > > > topology, and the hybrid topology is only built when the hybrid is
> > > > explicitly required.
> > > > 
> > > > Therefore, we introduce the definition support of hybrid cpu topology
> > > > here. At the same time, in order to unify with the original smp, we
> > > > introduce a new cpu topology structure that can support smp topology
> > > > or hybrid topology. This structure will replace the CpuTopology type (in
> > > > include/hw/boards.h) used by MachineState.smp.
> > > > 
> > > > As for now, we only support two hybrid topology levels: core and
> > > > cluster.
> > > > 
> > > > Signed-off-by: Zhao Liu 
> > > > ---
> > > >MAINTAINERS   |   1 +
> > > >include/hw/cpu/cpu-topology.h | 117 
> > > > ++
> > > >qapi/machine.json |  12 
> > > >3 files changed, 130 insertions(+)
> > > >create mode 100644 include/hw/cpu/cpu-topology.h
> > > > 
> > > > diff --git a/MAINTAINERS b/MAINTAINERS
> > > > index 58794885ced3..918a9418d98e 100644
> > > > --- a/MAINTAINERS
> > > > +++ b/MAINTAINERS
> > > > @@ -1742,6 +1742,7 @@ F: qapi/machine-target.json
> > > >F: include/hw/boards.h
> > > >F: include/hw/core/cpu.h
> > > >F: include/hw/cpu/cluster.h
> > > > +F: include/hw/cpu/cpu-topology.h
> > > >F: include/sysemu/numa.h
> > > >F: tests/unit/test-smp-parse.c
> > > >T: git https://gitlab.com/ehabkost/qemu.git machine-next
> > > 
> > > Worth splitting this section in 2, machine VS numa/clusters?
> > 
> > Do you mean splitting this header file into numa.h and cluster.h?
> 
> No, I meant the MAINTAINERS 'Machine' section.

I see. I will slit this.

> 
> > It seems that the cpu topology is not related to the content of
> > numa.h,
> 
> And you seem to agree ;)
> 
> > and it may be possible to merge some content into cluster.h,
> > but the definition in cluster.h is to use the cluster as a device
> > (if I understand correctly...) , and cpu_topology.h is just about
> > topology-related things.
> > 
> > I have not included the contents of cluster.h/cluster.c into hybrid
> > considerations, but only modified the topology defined by smp.
> > 
> > Zhao
> 



Re: [RFC 25/52] mips: Replace MachineState.smp access with topology helpers

2023-02-14 Thread Zhao Liu
On Tue, Feb 14, 2023 at 11:40:14AM +0800, Mi, Dapeng1 wrote:
> Date: Tue, 14 Feb 2023 11:40:14 +0800
> From: "Mi, Dapeng1" 
> Subject: RE: [RFC 25/52] mips: Replace MachineState.smp access with
>  topology helpers
> 
> > From: Zhao Liu 
> > Sent: Monday, February 13, 2023 5:50 PM
> > To: Eduardo Habkost ; Marcel Apfelbaum
> > ; Philippe Mathieu-Daud? ;
> > Yanan Wang ; Michael S . Tsirkin
> > ; Richard Henderson ; Paolo
> > Bonzini ; Eric Blake ; Markus
> > Armbruster 
> > Cc: qemu-devel@nongnu.org; Wang, Zhenyu Z ; Mi,
> > Dapeng1 ; Ding, Zhuocheng
> > ; Robert Hoo ;
> > Christopherson,, Sean ; Like Xu
> > ; Liu, Zhao1 ; Aleksandar
> > Rikalo ; Huacai Chen
> > ; Jiaxun Yang ; Aurelien
> > Jarno 
> > Subject: [RFC 25/52] mips: Replace MachineState.smp access with topology
> > helpers
> > 
> > From: Zhao Liu 
> > 
> > When MachineState.topo is introduced, the topology related structures
> > become complicated. So we wrapped the access to topology fields of
> > MachineState.topo into some helpers, and we are using these helpers
> > to replace the use of MachineState.smp.
> > 
> > For mips, it's straightforward to replace topology access with wrapped
> > generic interfaces.
> > 
> > Cc: Aleksandar Rikalo 
> > Cc: Huacai Chen 
> > Cc: Jiaxun Yang 
> > Cc: Aurelien Jarno 
> > Signed-off-by: Zhao Liu 
> > ---
> >  hw/mips/boston.c  |  8 +---
> >  hw/mips/loongson3_bootp.c |  7 ---
> >  hw/mips/loongson3_virt.c  |  8 +---
> >  hw/mips/malta.c   | 10 ++
> >  4 files changed, 20 insertions(+), 13 deletions(-)
> > 
> > diff --git a/hw/mips/boston.c b/hw/mips/boston.c
> > index a9d87f34378f..d02c88d769d4 100644
> > --- a/hw/mips/boston.c
> > +++ b/hw/mips/boston.c
> > @@ -514,7 +514,7 @@ static const void *create_fdt(BostonState *s,
> >const MemMapEntry *memmap, int *dt_size)
> >  {
> >  void *fdt;
> > -int cpu;
> > +int cpu, smp_cpus;
> >  MachineState *ms = s->mach;
> >  uint32_t platreg_ph, gic_ph, clk_ph;
> >  char *name, *gic_name, *platreg_name, *stdout_name;
> > @@ -542,7 +542,8 @@ static const void *create_fdt(BostonState *s,
> >  qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0);
> >  qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1);
> > 
> > -for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
> > +smp_cpus = machine_topo_get_cpus(ms);
> > +for (cpu = 0; cpu < smp_cpus; cpu++) {
> >  name = g_strdup_printf("/cpus/cpu@%d", cpu);
> >  qemu_fdt_add_subnode(fdt, name);
> >  qemu_fdt_setprop_string(fdt, name, "compatible", "img,mips");
> > @@ -702,7 +703,8 @@ static void boston_mach_init(MachineState *machine)
> >  object_initialize_child(OBJECT(machine), "cps", >cps, 
> > TYPE_MIPS_CPS);
> >  object_property_set_str(OBJECT(>cps), "cpu-type", machine->cpu_type,
> >  _fatal);
> > -object_property_set_int(OBJECT(>cps), "num-vp", machine->smp.cpus,
> > +object_property_set_int(OBJECT(>cps), "num-vp",
> > +machine_topo_get_cpus(machine),
> >  _fatal);
> 
> It's better move "_fatal);" to previous line.

Yes, this is no more than 80 characters.

> 
> >  qdev_connect_clock_in(DEVICE(>cps), "clk-in",
> >qdev_get_clock_out(dev, "cpu-refclk"));
> > diff --git a/hw/mips/loongson3_bootp.c b/hw/mips/loongson3_bootp.c
> > index f99af229327a..d9a92825ceae 100644
> > --- a/hw/mips/loongson3_bootp.c
> > +++ b/hw/mips/loongson3_bootp.c
> > @@ -40,9 +40,10 @@ static void init_cpu_info(void *g_cpuinfo, uint64_t
> > cpu_freq)
> >  }
> > 
> >  c->cpu_startup_core_id = cpu_to_le16(0);
> > -c->nr_cpus = cpu_to_le32(current_machine->smp.cpus);
> > -c->total_node = cpu_to_le32(DIV_ROUND_UP(current_machine->smp.cpus,
> > - LOONGSON3_CORE_PER_NODE));
> > +c->nr_cpus = cpu_to_le32(machine_topo_get_cpus(current_machine));
> > +c->total_node =
> > +cpu_to_le32(DIV_ROUND_UP(machine_topo_get_cpus(current_machine),
> > + LOONGSON3_CORE_PER_NODE));
> >  }
> > 
> >  static void init_memory_map(void *g_map, uint64_t ram_size)
> > diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
> > index 25534288dd81..c972bb43a1f7 100644
> > --- a/hw/mips/loongson3_virt.c
> > +++ b/hw/mips/loongson3_virt.c
> > @@ -271,8 +271,10 @@ static void fw_conf_init(unsigned long ram_size)
> >  hwaddr cfg_addr = virt_memmap[VIRT_FW_CFG].base;
> > 
> >  fw_cfg = fw_cfg_init_mem_wide(cfg_addr, cfg_addr + 8, 8, 0, NULL);
> > -fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)current_machine-
> > >smp.cpus);
> > -fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)current_machine-
> > >smp.max_cpus);
> > +fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS,
> > +   (uint16_t)machine_topo_get_cpus(current_machine));
> > +fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS,
> > + 

RE: [PATCH] memory: Optimize replay of guest mapping

2023-02-14 Thread Duan, Zhenzhong


>-Original Message-
>From: Peter Xu 
>Sent: Wednesday, February 15, 2023 1:29 AM
>To: Duan, Zhenzhong 
>Cc: Jason Wang ; qemu-devel@nongnu.org;
>m...@redhat.com; pbonz...@redhat.com; richard.hender...@linaro.org;
>edua...@habkost.net; marcel.apfelb...@gmail.com; da...@redhat.com;
>phi...@linaro.org
>Subject: Re: [PATCH] memory: Optimize replay of guest mapping
>
>On Tue, Feb 14, 2023 at 07:04:56AM +, Duan, Zhenzhong wrote:
>> >> @@ -1936,7 +1935,7 @@ void
>> >> memory_region_iommu_replay(IOMMUMemoryRegion *iommu_mr,
>> >IOMMUNotifier
>> >> *n)
>> >>
>> >>  granularity = memory_region_iommu_get_min_page_size(iommu_mr);
>> >>
>> >> -for (addr = 0; addr < memory_region_size(mr); addr += granularity) {
>> >> +for (addr = n->start; addr < n->end; addr += granularity) {
>> >
>> >Is [n->start, n->end] guaranteed to be the subset of
>memory_region_size(mr)?
>>
>> In current implementation it is.
>> [n->start, n->end] of notifier is derived from iommu memory region's
>> section which is a subset of iommu memory region itself.
>
>Yes, currently it seems to be guaranteed by the callers assuming they're
>always doing the right thing.
>
>Maybe it'll worth it to have memory_region_register_iommu_notifier() assert
>properly to make sure it always hold true?

Yea, good suggestion, will do in v2.

Thanks
Zhenzhong


Re: [PATCH RESEND 03/18] softmmu: Fix CPUSTATE.nr_cores' calculation

2023-02-14 Thread wangyanan (Y)

Hi Zhao,

在 2023/2/13 17:36, Zhao Liu 写道:

From: Zhuocheng Ding 

>From CPUState.nr_cores' comment, it represents "number of cores within
this CPU package".

After 003f230 (machine: Tweak the order of topology members in struct
CpuTopology), the meaning of smp.cores changed to "the number of cores
in one die", but this commit missed to change CPUState.nr_cores'
caculation, so that CPUState.nr_cores became wrong and now it
misses to consider numbers of clusters and dies.

At present, only i386 is using CPUState.nr_cores.

But as for i386, which supports die level, the uses of CPUState.nr_cores
are very confusing:

Early uses are based on the meaning of "cores per package" (before die
is introduced into i386), and later uses are based on "cores per die"
(after die's introduction).

This difference is due to that commit a94e142 (target/i386: Add CPUID.1F
generation support for multi-dies PCMachine) misunderstood that
CPUState.nr_cores means "cores per die" when caculated
CPUID.1FH.01H:EBX. After that, the changes in i386 all followed this
wrong understanding.

With the influence of 003f230 and a94e142, for i386 currently the result
of CPUState.nr_cores is "cores per die", thus the original uses of
CPUState.cores based on the meaning of "cores per package" are wrong
when mutiple dies exist:
1. In cpu_x86_cpuid() of target/i386/cpu.c, CPUID.01H:EBX[bits 23:16] is
incorrect because it expects "cpus per package" but now the
result is "cpus per die".
2. In cpu_x86_cpuid() of target/i386/cpu.c, for all leaves of CPUID.04H:
EAX[bits 31:26] is incorrect because they expect "cpus per package"
but now the result is "cpus per die". The error not only impacts the
EAX caculation in cache_info_passthrough case, but also impacts other
cases of setting cache topology for Intel CPU according to cpu
topology (specifically, the incoming parameter "num_cores" expects
"cores per package" in encode_cache_cpuid4()).
3. In cpu_x86_cpuid() of target/i386/cpu.c, CPUID.0BH.01H:EBX[bits
15:00] is incorrect because the EBX of 0BH.01H (core level) expects
"cpus per package", which may be different with 1FH.01H (The reason
is 1FH can support more levels. For QEMU, 1FH also supports die,
1FH.01H:EBX[bits 15:00] expects "cpus per die").
4. In cpu_x86_cpuid() of target/i386/cpu.c, when CPUID.8001H is
caculated, here "cpus per package" is expected to be checked, but in
fact, now it checks "cpus per die". Though "cpus per die" also works
for this code logic, this isn't consistent with AMD's APM.
5. In cpu_x86_cpuid() of target/i386/cpu.c, CPUID.8008H:ECX expects
"cpus per package" but it obtains "cpus per die".
6. In simulate_rdmsr() of target/i386/hvf/x86_emu.c, in
kvm_rdmsr_core_thread_count() of target/i386/kvm/kvm.c, and in
helper_rdmsr() of target/i386/tcg/sysemu/misc_helper.c,
MSR_CORE_THREAD_COUNT expects "cpus per package" and "cores per
package", but in these functions, it obtains "cpus per die" and
"cores per die".

On the other hand, these uses are correct now (they are added in/after
a94e142):
1. In cpu_x86_cpuid() of target/i386/cpu.c, topo_info.cores_per_die
meets the actual meaning of CPUState.nr_cores ("cores per die").
2. In cpu_x86_cpuid() of target/i386/cpu.c, vcpus_per_socket (in CPUID.
04H's caculation) considers number of dies, so it's correct.
3. In cpu_x86_cpuid() of target/i386/cpu.c, CPUID.1FH.01H:EBX[bits
15:00] needs "cpus per die" and it gets the correct result, and
CPUID.1FH.02H:EBX[bits 15:00] gets correct "cpus per package".

When CPUState.nr_cores is correctly changed to "cores per package" again
, the above errors will be fixed without extra work, but the "currently"
correct cases will go wrong and need special handling to pass correct
"cpus/cores per die" they want.

Thus in this patch, we fix CPUState.nr_cores' caculation to fit the
original meaning "cores per package", as well as changing caculation of
topo_info.cores_per_die, vcpus_per_socket and CPUID.1FH.

In addition, in the nr_threads' comment, specify it represents the
number of threads in the "core" to avoid confusion.

Fixes: a94e142 (target/i386: Add CPUID.1F generation support for multi-dies 
PCMachine)
Fixes: 003f230 (machine: Tweak the order of topology members in struct 
CpuTopology)
Signed-off-by: Zhuocheng Ding 
Co-developed-by: Zhao Liu 
Signed-off-by: Zhao Liu 
---
  include/hw/core/cpu.h | 2 +-
  softmmu/cpus.c| 2 +-
  target/i386/cpu.c | 9 -
  3 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index 2417597236bc..5253e4e839bb 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -274,7 +274,7 @@ struct qemu_work_item;
   *   QOM parent.
   * @tcg_cflags: Pre-computed cflags for this cpu.
   * @nr_cores: Number of cores within this CPU package.
- * @nr_threads: Number of threads within this CPU.
+ * @nr_threads: Number of threads within this 

Re: [PATCH 18/18] target/riscv: Move configuration check to envcfg CSRs predicate()

2023-02-14 Thread weiwei



On 2023/2/15 10:22, Bin Meng wrote:

On Tue, Feb 14, 2023 at 10:59 PM weiwei  wrote:


On 2023/2/14 22:27, Bin Meng wrote:

At present the envcfg CSRs predicate() routines are generic one like
smode(), hmode. The configuration check is done in the read / write
routine. Create a new predicate routine to cover such check, so that
gdbstub can correctly report its existence.

Signed-off-by: Bin Meng 

---

   target/riscv/csr.c | 98 +-
   1 file changed, 61 insertions(+), 37 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 37350b8a6d..284ccc09dd 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -41,40 +41,6 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
   }

   /* Predicates */
-#if !defined(CONFIG_USER_ONLY)
-static RISCVException smstateen_acc_ok(CPURISCVState *env, int index,
-   uint64_t bit)
-{
-bool virt = riscv_cpu_virt_enabled(env);
-RISCVCPU *cpu = env_archcpu(env);
-
-if (env->priv == PRV_M || !cpu->cfg.ext_smstateen) {
-return RISCV_EXCP_NONE;
-}
-
-if (!(env->mstateen[index] & bit)) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-
-if (virt) {
-if (!(env->hstateen[index] & bit)) {
-return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
-}
-
-if (env->priv == PRV_U && !(env->sstateen[index] & bit)) {
-return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
-}
-}
-
-if (env->priv == PRV_U && riscv_has_ext(env, RVS)) {
-if (!(env->sstateen[index] & bit)) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-}
-
-return RISCV_EXCP_NONE;
-}
-#endif

   static RISCVException fs(CPURISCVState *env, int csrno)
   {
@@ -318,6 +284,32 @@ static RISCVException umode32(CPURISCVState *env, int 
csrno)
   return umode(env, csrno);
   }

+static RISCVException envcfg(CPURISCVState *env, int csrno)
+{
+RISCVCPU *cpu = env_archcpu(env);
+riscv_csr_predicate_fn predicate;
+
+if (cpu->cfg.ext_smstateen) {
+return RISCV_EXCP_ILLEGAL_INST;
+}

This check seems not right here.  Why  ILLEGAL_INST is directly
triggered if smstateen is enabled?

This logic was there in the original codes. I was confused when I
looked at this as well.


Sorry, I didn't find the original codes. Do you mean this:

if (env->priv == PRV_M || !cpu->cfg.ext_smstateen) {
return RISCV_EXCP_NONE;
}

If so, I think the check here is to make the following *stateen related
check ignored when smstateen extension is disabled.

Regards,

Weiwei Li


Anyway, if it is an issue, it should be a separate patch.


It seems that smstateen related check will be done  for
senvcfg/henvcfg{h} when smstateen is enabled.


Regards,
Bin





Re: [PATCH v1 RFC Zisslpcfi 1/9] target/riscv: adding zimops and zisslpcfi extension to RISCV cpu config

2023-02-14 Thread LIU Zhiwei



On 2023/2/9 14:23, Deepak Gupta wrote:

Introducing riscv `zisslpcfi` extension to riscv target. `zisslpcfi`
extension provides hardware assistance to riscv hart to enable control
flow integrity (CFI) for software.

`zisslpcfi` extension expects hart to implement `zimops`. `zimops` stands
for "unprivileged integer maybe operations". `zimops` carve out certain
reserved opcodes encodings from integer spec to "may be operations"
encodings. `zimops` opcode encodings simply move 0 to rd.
`zisslpcfi` claims some of the `zimops` encodings and use them for shadow
stack management or indirect branch tracking. Any future extension can
also claim `zimops` encodings.


Does  the zimops has a independent specification? If so, you should give 
a link to this

specification.



This patch also adds a dependency check for `zimops` to be enabled if
`zisslpcfi` is enabled on the hart.


You should don't add two extensions in one patch. I think you should add 
them one by one.
And add the zimop first.  In my opinion, you should implement the whole 
zimop extension before
adding any patch for zisslpcfi, including the implementation of mop.rr 
and mop.r.




Signed-off-by: Deepak Gupta 
Signed-off-by: Kip Walker  
---
  target/riscv/cpu.c | 13 +
  target/riscv/cpu.h |  2 ++
  2 files changed, 15 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index cc75ca7667..6b4e90eb91 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -110,6 +110,8 @@ static const struct isa_ext_data isa_edata_arr[] = {
  ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot),
  ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt),
  ISA_EXT_DATA_ENTRY(xventanacondops, true, PRIV_VERSION_1_12_0, 
ext_XVentanaCondOps),
+ISA_EXT_DATA_ENTRY(zimops, true, PRIV_VERSION_1_12_0, ext_zimops),
+ISA_EXT_DATA_ENTRY(zisslpcfi, true, PRIV_VERSION_1_12_0, ext_cfi),

Add them one by one.

  };
  
  static bool isa_ext_is_enabled(RISCVCPU *cpu,

@@ -792,6 +794,11 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
  return;
  }
  
+if (cpu->cfg.ext_cfi && !cpu->cfg.ext_zimops) {

+error_setg(errp, "Zisslpcfi extension requires Zimops extension");
+return;
+}
+

Seems reasonable for me.

  /* Set the ISA extensions, checks should have happened above */
  if (cpu->cfg.ext_zdinx || cpu->cfg.ext_zhinx ||
  cpu->cfg.ext_zhinxmin) {
@@ -1102,6 +1109,12 @@ static Property riscv_cpu_properties[] = {
  #ifndef CONFIG_USER_ONLY
  DEFINE_PROP_UINT64("resetvec", RISCVCPU, env.resetvec, DEFAULT_RSTVEC),
  #endif
+/*
+ * Zisslpcfi CFI extension, Zisslpcfi implicitly means Zimops is
+ * implemented
+ */
+DEFINE_PROP_BOOL("zisslpcfi", RISCVCPU, cfg.ext_cfi, true),
+DEFINE_PROP_BOOL("zimops", RISCVCPU, cfg.ext_zimops, true),


Default value should be false.

Zhiwei

  
  DEFINE_PROP_BOOL("short-isa-string", RISCVCPU, cfg.short_isa_string, false),
  
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h

index f5609b62a2..9a923760b2 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -471,6 +471,8 @@ struct RISCVCPUConfig {
  uint32_t mvendorid;
  uint64_t marchid;
  uint64_t mimpid;
+bool ext_zimops;
+bool ext_cfi;
  
  /* Vendor-specific custom extensions */

  bool ext_XVentanaCondOps;




Re: [RFC 22/52] riscv: Replace MachineState.smp access with topology helpers

2023-02-14 Thread Zhao Liu
On Tue, Feb 14, 2023 at 10:17:45AM +0800, Mi, Dapeng1 wrote:
> Date: Tue, 14 Feb 2023 10:17:45 +0800
> From: "Mi, Dapeng1" 
> Subject: RE: [RFC 22/52] riscv: Replace MachineState.smp access with
>  topology helpers
> 
> > From: Zhao Liu 
> > Sent: Monday, February 13, 2023 5:50 PM
> > To: Eduardo Habkost ; Marcel Apfelbaum
> > ; Philippe Mathieu-Daud? ;
> > Yanan Wang ; Michael S . Tsirkin
> > ; Richard Henderson ; Paolo
> > Bonzini ; Eric Blake ; Markus
> > Armbruster 
> > Cc: qemu-devel@nongnu.org; Wang, Zhenyu Z ; Mi,
> > Dapeng1 ; Ding, Zhuocheng
> > ; Robert Hoo ;
> > Christopherson,, Sean ; Like Xu
> > ; Liu, Zhao1 ; Meng, Bin
> > ; Palmer Dabbelt ; Alistair
> > Francis ; Vijai Kumar K 
> > Subject: [RFC 22/52] riscv: Replace MachineState.smp access with topology
> > helpers
> > 
> > From: Zhao Liu 
> > 
> > When MachineState.topo is introduced, the topology related structures
> > become complicated. So we wrapped the access to topology fields of
> > MachineState.topo into some helpers, and we are using these helpers
> > to replace the use of MachineState.smp.
> > 
> > In the codes of riscv, it's straightforward to replace topology access
> > with wrapped generic interfaces.
> > 
> > Cc: Bin Meng 
> > Cc: Palmer Dabbelt 
> > Cc: Alistair Francis 
> > CC: Vijai Kumar K 
> > Signed-off-by: Zhao Liu 
> > ---
> >  hw/riscv/microchip_pfsoc.c | 11 ++-
> >  hw/riscv/numa.c| 21 +++--
> >  hw/riscv/opentitan.c   |  8 
> >  hw/riscv/shakti_c.c|  2 +-
> >  hw/riscv/sifive_e.c| 10 ++
> >  hw/riscv/sifive_u.c| 28 ++--
> >  hw/riscv/virt.c| 24 +---
> >  7 files changed, 55 insertions(+), 49 deletions(-)
> > 
> > diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
> > index 2b91e49561f1..30295cce17e7 100644
> > --- a/hw/riscv/microchip_pfsoc.c
> > +++ b/hw/riscv/microchip_pfsoc.c
> > @@ -164,7 +164,8 @@ static void microchip_pfsoc_soc_instance_init(Object
> > *obj)
> > 
> >  object_initialize_child(OBJECT(>u_cluster), "u-cpus", >u_cpus,
> >  TYPE_RISCV_HART_ARRAY);
> > -qdev_prop_set_uint32(DEVICE(>u_cpus), "num-harts", ms->smp.cpus - 
> > 1);
> > +qdev_prop_set_uint32(DEVICE(>u_cpus), "num-harts",
> > + machine_topo_get_cpus(ms) - 1);
> >  qdev_prop_set_uint32(DEVICE(>u_cpus), "hartid-base", 1);
> >  qdev_prop_set_string(DEVICE(>u_cpus), "cpu-type",
> >   TYPE_RISCV_CPU_SIFIVE_U54);
> > @@ -249,10 +250,10 @@ static void microchip_pfsoc_soc_realize(DeviceState
> > *dev, Error **errp)
> > 
> >  /* CLINT */
> >  riscv_aclint_swi_create(memmap[MICROCHIP_PFSOC_CLINT].base,
> > -0, ms->smp.cpus, false);
> > +0, machine_topo_get_cpus(ms), false);
> >  riscv_aclint_mtimer_create(
> >  memmap[MICROCHIP_PFSOC_CLINT].base + RISCV_ACLINT_SWI_SIZE,
> > -RISCV_ACLINT_DEFAULT_MTIMER_SIZE, 0, ms->smp.cpus,
> > +RISCV_ACLINT_DEFAULT_MTIMER_SIZE, 0, machine_topo_get_cpus(ms),
> >  RISCV_ACLINT_DEFAULT_MTIMECMP, RISCV_ACLINT_DEFAULT_MTIME,
> >  CLINT_TIMEBASE_FREQ, false);
> > 
> > @@ -276,11 +277,11 @@ static void microchip_pfsoc_soc_realize(DeviceState
> > *dev, Error **errp)
> >  l2lim_mem);
> > 
> >  /* create PLIC hart topology configuration string */
> > -plic_hart_config = riscv_plic_hart_config_string(ms->smp.cpus);
> > +plic_hart_config =
> > riscv_plic_hart_config_string(machine_topo_get_cpus(ms));
> > 
> >  /* PLIC */
> >  s->plic = sifive_plic_create(memmap[MICROCHIP_PFSOC_PLIC].base,
> > -plic_hart_config, ms->smp.cpus, 0,
> > +plic_hart_config, machine_topo_get_cpus(ms), 0,
> >  MICROCHIP_PFSOC_PLIC_NUM_SOURCES,
> >  MICROCHIP_PFSOC_PLIC_NUM_PRIORITIES,
> >  MICROCHIP_PFSOC_PLIC_PRIORITY_BASE,
> > diff --git a/hw/riscv/numa.c b/hw/riscv/numa.c
> > index 472010256183..1fabdc42e767 100644
> > --- a/hw/riscv/numa.c
> > +++ b/hw/riscv/numa.c
> > @@ -37,13 +37,14 @@ int riscv_socket_count(const MachineState *ms)
> > 
> >  int riscv_socket_first_hartid(const MachineState *ms, int socket_id)
> >  {
> > -int i, first_hartid = ms->smp.cpus;
> > +int i, first_hartid, cpus = machine_topo_get_cpus(ms);
> > 
> > +first_hartid = cpus;
> >  if (!numa_enabled(ms)) {
> >  return (!socket_id) ? 0 : -1;
> >  }
> > 
> > -for (i = 0; i < ms->smp.cpus; i++) {
> > +for (i = 0; i < cpus; i++) {
> >  if (ms->possible_cpus->cpus[i].props.node_id != socket_id) {
> >  continue;
> >  }
> > @@ -52,18 +53,18 @@ int riscv_socket_first_hartid(const MachineState *ms,
> > int socket_id)
> >  }
> >  }
> > 
> > -return (first_hartid < ms->smp.cpus) ? first_hartid : -1;
> > +return (first_hartid < cpus) ? first_hartid : -1;
> >  }
> > 
> >  int 

Re: [RFC 42/52] hw/machine: Add hybrid_supported in generic topo properties

2023-02-14 Thread Zhao Liu
On Tue, Feb 14, 2023 at 09:46:50AM +0800, wangyanan (Y) wrote:
> Date: Tue, 14 Feb 2023 09:46:50 +0800
> From: "wangyanan (Y)" 
> Subject: Re: [RFC 42/52] hw/machine: Add hybrid_supported in generic topo
>  properties
> 
> Hi Zhao,
> 
> 在 2023/2/13 17:50, Zhao Liu 写道:
> > From: Zhao Liu 
> > 
> > Since hybrid cpu topology configuration can benefit not only x86, but
> > also other architectures/platforms that have supported (in real
> > machines) or will support hybrid CPU topology, "-hybrid" can be generic.
> > 
> > So add the generic topology property to configure if support hybrid
> > cpu topology for architectures/platforms in SmpCompatProps.
> > 
> > Also rename SmpCompatProps to TopoCompatProps to make this structure
> > more generic for both smp topology and hybrid topology.
> > 
> > Signed-off-by: Zhao Liu 
> > ---
> >   include/hw/boards.h | 15 +++
> >   1 file changed, 11 insertions(+), 4 deletions(-)
> > 
> > diff --git a/include/hw/boards.h b/include/hw/boards.h
> > index 34ec035b5c9f..17be3485e823 100644
> > --- a/include/hw/boards.h
> > +++ b/include/hw/boards.h
> > @@ -127,19 +127,26 @@ typedef struct {
> >   } CPUArchIdList;
> >   /**
> > - * SMPCompatProps:
> > - * @prefer_sockets - whether sockets are preferred over cores in smp 
> > parsing
> > + * TopoCompatProps:
> > + * @hybrid_support - whether hybrid cpu topology are supported by machine.
> inconsistent with the name in the definition below.

Thanks! Will fix.

> > + *   Note that hybrid cpu topology requires to specify the
> > + *   topology of each core so that there will no longer be
> > + *   a default core topology, thus prefer_sockets won't 
> > work
> > + *   when hybrid_support is enabled.
> > + * @prefer_sockets - whether sockets are preferred over cores in smp 
> > parsing.
> > + *   Not work when hybrid_support is enabled.
> >* @dies_supported - whether dies are supported by the machine
> >* @clusters_supported - whether clusters are supported by the machine
> >* @has_clusters - whether clusters are explicitly specified in the user
> >* provided SMP configuration
> >*/
> >   typedef struct {
> > +bool hybrid_supported;
> >   bool prefer_sockets;
> >   bool dies_supported;
> >   bool clusters_supported;
> >   bool has_clusters;
> > -} SMPCompatProps;
> > +} TopoCompatProps;
> Also here. "Rename SMPCompatProps to TopoCompatProps and
> move it to cpu-topology.h and adapt the code" should be organized
> in one or more separate patches, being pre-patches together with
> the conversion of CpuTopology before. 

Do you think TopoCompatProps/SMPCompatProps should also be moved
into cpu-topology.h? It seems that SMPCompatProps is a collection
of properties of MachineClass.

> And put the "hybrid_supported"
> extension into another patch. Would this make it easier to review?

Yes, I agree. Thanks!

Zhao

> 
> Thanks,
> Yanan
> >   /**
> >* MachineClass:
> > @@ -281,7 +288,7 @@ struct MachineClass {
> >   bool nvdimm_supported;
> >   bool numa_mem_supported;
> >   bool auto_enable_numa;
> > -SMPCompatProps smp_props;
> > +TopoCompatProps smp_props;
> >   const char *default_ram_id;
> >   HotplugHandler *(*get_hotplug_handler)(MachineState *machine,
> 



Re: [PATCH RESEND 02/18] tests: Rename test-x86-cpuid.c to test-x86-apicid.c

2023-02-14 Thread wangyanan (Y)

在 2023/2/13 17:36, Zhao Liu 写道:

From: Zhao Liu 

In fact, this unit tests APIC ID other than CPUID.
Rename to test-x86-apicid.c to make its name more in line with its
actual content.

Signed-off-by: Zhao Liu 
---
  MAINTAINERS| 2 +-
  tests/unit/meson.build | 4 ++--
  tests/unit/{test-x86-cpuid.c => test-x86-apicid.c} | 2 +-
  3 files changed, 4 insertions(+), 4 deletions(-)
  rename tests/unit/{test-x86-cpuid.c => test-x86-apicid.c} (99%)

diff --git a/MAINTAINERS b/MAINTAINERS
index 96e25f62acaa..71c1bc24371b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1679,7 +1679,7 @@ F: include/hw/southbridge/piix.h
  F: hw/misc/sga.c
  F: hw/isa/apm.c
  F: include/hw/isa/apm.h
-F: tests/unit/test-x86-cpuid.c
+F: tests/unit/test-x86-apicid.c
  F: tests/qtest/test-x86-cpuid-compat.c
  
  PC Chipset

diff --git a/tests/unit/meson.build b/tests/unit/meson.build
index ffa444f4323c..a9df2843e92e 100644
--- a/tests/unit/meson.build
+++ b/tests/unit/meson.build
@@ -20,8 +20,8 @@ tests = {
'test-opts-visitor': [testqapi],
'test-visitor-serialization': [testqapi],
'test-bitmap': [],
-  # all code tested by test-x86-cpuid is inside topology.h
-  'test-x86-cpuid': [],
+  # all code tested by test-x86-apicid is inside topology.h
+  'test-x86-apicid': [],
'test-cutils': [],
'test-div128': [],
'test-shift128': [],
diff --git a/tests/unit/test-x86-cpuid.c b/tests/unit/test-x86-apicid.c
similarity index 99%
rename from tests/unit/test-x86-cpuid.c
rename to tests/unit/test-x86-apicid.c
index bfabc0403a1a..2b104f86d7c2 100644
--- a/tests/unit/test-x86-cpuid.c
+++ b/tests/unit/test-x86-apicid.c
@@ -1,5 +1,5 @@
  /*
- *  Test code for x86 CPUID and Topology functions
+ *  Test code for x86 APIC ID and Topology functions
   *
I'm not very sure. The "CPUID" sounds like a general test for kinds of 
CPU IDs.

Besides APIC IDs computed from x86_apicid_from_cpu_idx(), there are also
topo IDs computed from x86_topo_ids_from_idx() although this kind of IDs
are not tested in test-x86-cpuid.c so far.

Thanks,
Yanan

   *  Copyright (c) 2012 Red Hat Inc.
   *





Re: [RFC 09/52] hw/machine: Introduce core type for hybrid topology

2023-02-14 Thread Zhao Liu
On Tue, Feb 14, 2023 at 09:14:13AM +0800, Mi, Dapeng1 wrote:
> Date: Tue, 14 Feb 2023 09:14:13 +0800
> From: "Mi, Dapeng1" 
> Subject: RE: [RFC 09/52] hw/machine: Introduce core type for hybrid topology
> 
> > From: Zhao Liu 
> > Sent: Monday, February 13, 2023 5:50 PM
> > To: Eduardo Habkost ; Marcel Apfelbaum
> > ; Philippe Mathieu-Daud? ;
> > Yanan Wang ; Michael S . Tsirkin
> > ; Richard Henderson ; Paolo
> > Bonzini ; Eric Blake ; Markus
> > Armbruster 
> > Cc: qemu-devel@nongnu.org; Wang, Zhenyu Z ; Mi,
> > Dapeng1 ; Ding, Zhuocheng
> > ; Robert Hoo ;
> > Christopherson,, Sean ; Like Xu
> > ; Liu, Zhao1 
> > Subject: [RFC 09/52] hw/machine: Introduce core type for hybrid topology
> > 
> > From: Zhao Liu 
> > 
> > Under the hybrid cpu topology, some CPUs care about the core type.
> > For example, Intel's Alder Lake series CPU contains two types of cores:
> > Intel Core and Intel Atom. The type information of these two types is 
> > exposed in
> > 1A leaf of CPUID.
> > 
> > Core type should also be part of the hybrid topology, and
> > MachineState.cpu_type cannot provide different type information for 
> > different
> > cpus in the same machine, so add a type field for the core level in the 
> > hybrid cpu
> > topology.
> > 
> > Additionally, add a helper to get core type information from MachineState.
> > Though core_type is only used in hybrid case, don't use assert since it may 
> > be
> > used to initialize some generic fields.
> > 
> > Signed-off-by: Zhao Liu 
> > ---
> >  hw/core/machine-topo.c| 12 
> >  include/hw/boards.h   |  3 +++
> >  include/hw/cpu/cpu-topology.h |  2 ++
> >  3 files changed, 17 insertions(+)
> > 
> > diff --git a/hw/core/machine-topo.c b/hw/core/machine-topo.c index
> > b20160479629..e0ec07b53d42 100644
> > --- a/hw/core/machine-topo.c
> > +++ b/hw/core/machine-topo.c
> > @@ -51,6 +51,18 @@ unsigned int machine_topo_get_smp_threads(const
> > MachineState *ms)
> >  return ms->topo.smp.threads;
> >  }
> > 
> > +unsigned int machine_topo_get_hybrid_core_type(const MachineState *ms,
> > +   unsigned int cluster_id,
> > +   unsigned int core_id) {
> > +if (!machine_topo_is_smp(ms)) {
> > +return ms->topo.hybrid.cluster_list[cluster_id]
> > +   .core_list[core_id].core_type;
> > +} else {
> > +return 0;
> > +}
> > +}
> > +
> 
> We'd better not to return the hard-coded '0'. Suggest to define a 'enum'
> data structure to represent the core_type. This makes the code look more 
> intuitively.

Yes. I defined a core type 'enum' in x86 code, Here I can use a macro to
avoid hardcoding.

Zhao

> 
> >  unsigned int machine_topo_get_threads(const MachineState *ms,
> >unsigned int cluster_id,
> >unsigned int core_id) diff --git 
> > a/include/hw/boards.h
> > b/include/hw/boards.h index 34b64b012022..78e52af38cb1 100644
> > --- a/include/hw/boards.h
> > +++ b/include/hw/boards.h
> > @@ -484,6 +484,9 @@ unsigned int machine_topo_get_dies(const
> > MachineState *ms);  unsigned int machine_topo_get_clusters(const
> > MachineState *ms);  unsigned int machine_topo_get_smp_cores(const
> > MachineState *ms);  unsigned int machine_topo_get_smp_threads(const
> > MachineState *ms);
> > +unsigned int machine_topo_get_hybrid_core_type(const MachineState *ms,
> > +   unsigned int cluster_id,
> > +   unsigned int core_id);
> >  unsigned int machine_topo_get_threads(const MachineState *ms,
> >unsigned int cluster_id,
> >unsigned int core_id); diff --git 
> > a/include/hw/cpu/cpu-
> > topology.h b/include/hw/cpu/cpu-topology.h index
> > 8268ea3a8569..87d832556229 100644
> > --- a/include/hw/cpu/cpu-topology.h
> > +++ b/include/hw/cpu/cpu-topology.h
> > @@ -45,9 +45,11 @@ typedef struct SmpCpuTopology {
> >  /**
> >   * HybridCore - hybrid core topology defination:
> >   * @threads: the number of threads in one core.
> > + * @core_type: the type of current core.
> >   */
> >  typedef struct HybridCore {
> >  unsigned int threads;
> > +unsigned int core_type;
> >  } HybridCore;
> > 
> >  /**
> > --
> > 2.34.1
> 



Re: [RFC 08/52] machine: Add helpers to get cpu topology info from MachineState.topo

2023-02-14 Thread Zhao Liu
On Tue, Feb 14, 2023 at 09:12:11AM +0800, Mi, Dapeng1 wrote:
> Date: Tue, 14 Feb 2023 09:12:11 +0800
> From: "Mi, Dapeng1" 
> Subject: RE: [RFC 08/52] machine: Add helpers to get cpu topology info from
>  MachineState.topo
> 
> > From: Zhao Liu 
> > Sent: Monday, February 13, 2023 5:50 PM
> > To: Eduardo Habkost ; Marcel Apfelbaum
> > ; Philippe Mathieu-Daud? ;
> > Yanan Wang ; Michael S . Tsirkin
> > ; Richard Henderson ; Paolo
> > Bonzini ; Eric Blake ; Markus
> > Armbruster 
> > Cc: qemu-devel@nongnu.org; Wang, Zhenyu Z ; Mi,
> > Dapeng1 ; Ding, Zhuocheng
> > ; Robert Hoo ;
> > Christopherson,, Sean ; Like Xu
> > ; Liu, Zhao1 
> > Subject: [RFC 08/52] machine: Add helpers to get cpu topology info from
> > MachineState.topo
> > 
> > From: Zhao Liu 
> > 
> > When MachineState.topo is introduced, the topology related structures become
> > complicated. In the general case (hybrid or smp topology), accessing the
> > topology information needs to determine whether it is currently smp or 
> > hybrid
> > topology, and then access the corresponding MachineState.topo.smp or
> > MachineState.topo.hybrid.
> > 
> > The best way to do this is to wrap the access to the topology to avoid 
> > having to
> > check each time it is accessed.
> > 
> > The following helpers are provided here:
> > 
> > - General interfaces - no need to worry about whether the underlying
> >   topology is smp or hybrid:
> > 
> > * machine_topo_get_cpus()
> > * machine_topo_get_max_cpus()
> > * machine_topo_is_smp()
> > * machine_topo_get_sockets()
> > * machine_topo_get_dies()
> > * machine_topo_get_clusters()
> > * machine_topo_get_threads();
> > * machine_topo_get_cores();
> > * machine_topo_get_threads_by_idx()
> > * machine_topo_get_cores_by_idx()
> > * machine_topo_get_cores_per_socket()
> > * machine_topo_get_threads_per_socket()
> > 
> > - SMP-specific interfaces - provided for the cases that are clearly known 
> > to be
> > smp topology:
> > 
> > * machine_topo_get_smp_cores()
> > * machine_topo_get_smp_threads()
> > 
> > Since for hybrid topology, each core may has different threads, if someone
> > wants "cpus per core", the cpu_index is need to target a specific core
> > (machine_topo_get_threads_by_idx()). But for smp, there is no need to be so
> > troublesome, so for this case, we provide smp-specific interfaces.
> > 
> > Signed-off-by: Zhao Liu 
> > ---
> >  hw/core/machine-topo.c | 142
> > +
> >  include/hw/boards.h|  35 ++
> >  2 files changed, 177 insertions(+)
> > 
> > diff --git a/hw/core/machine-topo.c b/hw/core/machine-topo.c index
> > 7223f73f99b0..b20160479629 100644
> > --- a/hw/core/machine-topo.c
> > +++ b/hw/core/machine-topo.c
> > @@ -21,6 +21,148 @@
> >  #include "hw/boards.h"
> >  #include "qapi/error.h"
> > 
> > +unsigned int machine_topo_get_sockets(const MachineState *ms) {
> > +return machine_topo_is_smp(ms) ? ms->topo.smp.sockets :
> > + ms->topo.hybrid.sockets; }
> > +
> > +unsigned int machine_topo_get_dies(const MachineState *ms) {
> > +return machine_topo_is_smp(ms) ? ms->topo.smp.dies :
> > + ms->topo.hybrid.dies; }
> > +
> > +unsigned int machine_topo_get_clusters(const MachineState *ms) {
> > +return machine_topo_is_smp(ms) ? ms->topo.smp.clusters :
> > + ms->topo.hybrid.clusters; }
> > +
> > +unsigned int machine_topo_get_smp_cores(const MachineState *ms) {
> > +g_assert(machine_topo_is_smp(ms));
> > +return ms->topo.smp.cores;
> > +}
> > +
> > +unsigned int machine_topo_get_smp_threads(const MachineState *ms) {
> > +g_assert(machine_topo_is_smp(ms));
> > +return ms->topo.smp.threads;
> > +}
> > +
> > +unsigned int machine_topo_get_threads(const MachineState *ms,
> > +  unsigned int cluster_id,
> > +  unsigned int core_id) {
> > +if (machine_topo_is_smp(ms)) {
> > +return ms->topo.smp.threads;
> > +} else {
> > +return ms->topo.hybrid.cluster_list[cluster_id]
> > +   .core_list[core_id].threads;
> > +}
> > +
> > +return 0;
> > +}
> > +
> > +unsigned int machine_topo_get_cores(const MachineState *ms,
> > +unsigned int cluster_id) {
> > +if (machine_topo_is_smp(ms)) {
> > +return ms->topo.smp.cores;
> > +} else {
> > +return ms->topo.hybrid.cluster_list[cluster_id].cores;
> > +}
> > +}
> > +
> > +unsigned int machine_topo_get_threads_by_idx(const MachineState *ms,
> > + unsigned int cpu_index) {
> > +unsigned cpus_per_die;
> > +unsigned tmp_idx;
> > +HybridCluster *cluster;
> > +HybridCore *core;
> > +
> > +if (machine_topo_is_smp(ms)) {
> > +return ms->topo.smp.threads;
> > +}
> > +
> > +cpus_per_die = ms->topo.max_cpus / (ms->topo.hybrid.sockets *
> > +  

Re: [PATCH 18/18] target/riscv: Move configuration check to envcfg CSRs predicate()

2023-02-14 Thread Bin Meng
On Tue, Feb 14, 2023 at 10:59 PM weiwei  wrote:
>
>
> On 2023/2/14 22:27, Bin Meng wrote:
> > At present the envcfg CSRs predicate() routines are generic one like
> > smode(), hmode. The configuration check is done in the read / write
> > routine. Create a new predicate routine to cover such check, so that
> > gdbstub can correctly report its existence.
> >
> > Signed-off-by: Bin Meng 
> >
> > ---
> >
> >   target/riscv/csr.c | 98 +-
> >   1 file changed, 61 insertions(+), 37 deletions(-)
> >
> > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> > index 37350b8a6d..284ccc09dd 100644
> > --- a/target/riscv/csr.c
> > +++ b/target/riscv/csr.c
> > @@ -41,40 +41,6 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations 
> > *ops)
> >   }
> >
> >   /* Predicates */
> > -#if !defined(CONFIG_USER_ONLY)
> > -static RISCVException smstateen_acc_ok(CPURISCVState *env, int index,
> > -   uint64_t bit)
> > -{
> > -bool virt = riscv_cpu_virt_enabled(env);
> > -RISCVCPU *cpu = env_archcpu(env);
> > -
> > -if (env->priv == PRV_M || !cpu->cfg.ext_smstateen) {
> > -return RISCV_EXCP_NONE;
> > -}
> > -
> > -if (!(env->mstateen[index] & bit)) {
> > -return RISCV_EXCP_ILLEGAL_INST;
> > -}
> > -
> > -if (virt) {
> > -if (!(env->hstateen[index] & bit)) {
> > -return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> > -}
> > -
> > -if (env->priv == PRV_U && !(env->sstateen[index] & bit)) {
> > -return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> > -}
> > -}
> > -
> > -if (env->priv == PRV_U && riscv_has_ext(env, RVS)) {
> > -if (!(env->sstateen[index] & bit)) {
> > -return RISCV_EXCP_ILLEGAL_INST;
> > -}
> > -}
> > -
> > -return RISCV_EXCP_NONE;
> > -}
> > -#endif
> >
> >   static RISCVException fs(CPURISCVState *env, int csrno)
> >   {
> > @@ -318,6 +284,32 @@ static RISCVException umode32(CPURISCVState *env, int 
> > csrno)
> >   return umode(env, csrno);
> >   }
> >
> > +static RISCVException envcfg(CPURISCVState *env, int csrno)
> > +{
> > +RISCVCPU *cpu = env_archcpu(env);
> > +riscv_csr_predicate_fn predicate;
> > +
> > +if (cpu->cfg.ext_smstateen) {
> > +return RISCV_EXCP_ILLEGAL_INST;
> > +}
>
> This check seems not right here.  Why  ILLEGAL_INST is directly
> triggered if smstateen is enabled?

This logic was there in the original codes. I was confused when I
looked at this as well.

Anyway, if it is an issue, it should be a separate patch.

>
> It seems that smstateen related check will be done  for
> senvcfg/henvcfg{h} when smstateen is enabled.
>

Regards,
Bin



Re: [RFC 04/52] i386/WHPX: Fix error message when fail to set ProcessorCount

2023-02-14 Thread Zhao Liu
On Mon, Feb 13, 2023 at 01:41:19PM +, Daniel P. Berrangé wrote:
> Date: Mon, 13 Feb 2023 13:41:19 +
> From: "Daniel P. Berrangé" 
> Subject: Re: [RFC 04/52] i386/WHPX: Fix error message when fail to set
>  ProcessorCount
> 
> On Mon, Feb 13, 2023 at 05:49:47PM +0800, Zhao Liu wrote:
> > From: Zhao Liu 
> > 
> > 003f230 (machine: Tweak the order of topology members in struct
> > CpuTopology) changes the meaning of MachineState.smp.cores from "the
> > number of cores in one package" to "the number of cores in one die"
> > and doesn't fix other uses of MachineState.smp.cores. And because of
> > the introduction of cluster, now smp.cores just means "the number of
> > cores in one cluster". This clearly does not fit the semantics here.
> > 
> > And before this error message, WHvSetPartitionProperty() is called to
> > set prop.ProcessorCount.
> > 
> > So the error message should show the prop.ProcessorCount other than
> > "cores per cluster" or "cores per package".
> > 
> > Cc: Sunil Muthuswamy 
> > Signed-off-by: Zhao Liu 
> > ---
> >  target/i386/whpx/whpx-all.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> This patch and the 3 patches before it all look like basic bug
> fixes to current code, not really part of the new hybrid topology
> feature work.
> 
> As such I'd suggest sending these first four patches as a separate
> series, so the bug fixes can be merged fairly quickly. I expect the
> rest of the hybrid topology series is going to take a long time to
> get agreement on, so no need to delay the easy bug fixes.

Yes, I'll split out the first four. Thanks!

Zhao

> 
> > 
> > diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c
> > index e738d83e8191..fc349f887e47 100644
> > --- a/target/i386/whpx/whpx-all.c
> > +++ b/target/i386/whpx/whpx-all.c
> > @@ -2613,8 +2613,8 @@ static int whpx_accel_init(MachineState *ms)
> >  sizeof(WHV_PARTITION_PROPERTY));
> >  
> >  if (FAILED(hr)) {
> > -error_report("WHPX: Failed to set partition core count to %d,"
> > - " hr=%08lx", ms->smp.cores, hr);
> > +error_report("WHPX: Failed to set partition processor count to %d,"
> > + " hr=%08lx", prop.ProcessorCount, hr);
> >  ret = -EINVAL;
> >  goto error;
> >  }
> > -- 
> > 2.34.1
> > 
> > 
> 
> With 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 :|
> 



[PATCH v2 12/14] target/riscv: Fix check for vector load/store instructions when EEW=64

2023-02-14 Thread Weiwei Li
The V extension supports all vector load and store instructions except
the V extension does not support EEW=64 for index values when XLEN=32.
(Section 18.3)

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Daniel Henrique Barboza 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 9b2c5c9ac0..5dbdce073b 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -287,13 +287,12 @@ static bool vext_check_st_index(DisasContext *s, int vd, 
int vs2, int nf,
require_nf(vd, nf, s->lmul);
 
 /*
- * All Zve* extensions support all vector load and store instructions,
- * except Zve64* extensions do not support EEW=64 for index values
- * when XLEN=32. (Section 18.2)
+ * V extension supports all vector load and store instructions,
+ * except V extension does not support EEW=64 for index values
+ * when XLEN=32. (Section 18.3)
  */
 if (get_xl(s) == MXL_RV32) {
-ret &= (!has_ext(s, RVV) &&
-s->cfg_ptr->ext_zve64f ? eew != MO_64 : true);
+ret &= (eew != MO_64);
 }
 
 return ret;
-- 
2.25.1




[PATCH v2 13/14] target/riscv: Simplify check for EEW = 64 in trans_rvv.c.inc

2023-02-14 Thread Weiwei Li
Only V extension supports EEW = 64 in these cases: Zve64* extensions don't
support EEW = 64 in these cases as commented before the check.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Daniel Henrique Barboza 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 12 
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 5dbdce073b..fc0d0d60e8 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1998,8 +1998,7 @@ static bool vmulh_vv_check(DisasContext *s, arg_rmrr *a)
  * are not included for EEW=64 in Zve64*. (Section 18.2)
  */
 return opivv_check(s, a) &&
-   (!has_ext(s, RVV) &&
-s->cfg_ptr->ext_zve64f ? s->sew != MO_64 : true);
+   (!has_ext(s, RVV) ? s->sew != MO_64 : true);
 }
 
 static bool vmulh_vx_check(DisasContext *s, arg_rmrr *a)
@@ -2012,8 +2011,7 @@ static bool vmulh_vx_check(DisasContext *s, arg_rmrr *a)
  * are not included for EEW=64 in Zve64*. (Section 18.2)
  */
 return opivx_check(s, a) &&
-   (!has_ext(s, RVV) &&
-s->cfg_ptr->ext_zve64f ? s->sew != MO_64 : true);
+   (!has_ext(s, RVV) ? s->sew != MO_64 : true);
 }
 
 GEN_OPIVV_GVEC_TRANS(vmul_vv,  mul)
@@ -2230,8 +2228,7 @@ static bool vsmul_vv_check(DisasContext *s, arg_rmrr *a)
  * for EEW=64 in Zve64*. (Section 18.2)
  */
 return opivv_check(s, a) &&
-   (!has_ext(s, RVV) &&
-s->cfg_ptr->ext_zve64f ? s->sew != MO_64 : true);
+   (!has_ext(s, RVV) ? s->sew != MO_64 : true);
 }
 
 static bool vsmul_vx_check(DisasContext *s, arg_rmrr *a)
@@ -2242,8 +2239,7 @@ static bool vsmul_vx_check(DisasContext *s, arg_rmrr *a)
  * for EEW=64 in Zve64*. (Section 18.2)
  */
 return opivx_check(s, a) &&
-   (!has_ext(s, RVV) &&
-s->cfg_ptr->ext_zve64f ? s->sew != MO_64 : true);
+   (!has_ext(s, RVV) ? s->sew != MO_64 : true);
 }
 
 GEN_OPIVV_TRANS(vsmul_vv, vsmul_vv_check)
-- 
2.25.1




[PATCH v2 08/14] target/riscv: Simplify check for Zve32f and Zve64f

2023-02-14 Thread Weiwei Li
V/Zve64f depend on Zve32f, so we can only check Zve32f in these cases.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Daniel Henrique Barboza 
---
 target/riscv/cpu_helper.c   | 2 +-
 target/riscv/csr.c  | 3 +--
 target/riscv/insn_trans/trans_rvv.c.inc | 8 ++--
 3 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index ad8d82662c..6a3b8bd17b 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -51,7 +51,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
*pc,
 *pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc;
 *cs_base = 0;
 
-if (riscv_has_ext(env, RVV) || cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f) 
{
+if (cpu->cfg.ext_zve32f) {
 /*
  * If env->vl equals to VLMAX, we can use generic vector operation
  * expanders (GVEC) to accerlate the vector operations.
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index fa17d7770c..fbe690878b 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -93,8 +93,7 @@ static RISCVException vs(CPURISCVState *env, int csrno)
 CPUState *cs = env_cpu(env);
 RISCVCPU *cpu = RISCV_CPU(cs);
 
-if (env->misa_ext & RVV ||
-cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f) {
+if (cpu->cfg.ext_zve32f) {
 #if !defined(CONFIG_USER_ONLY)
 if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
 return RISCV_EXCP_ILLEGAL_INST;
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index bbb5c3a7b5..6f7ecf1a68 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -173,9 +173,7 @@ static bool do_vsetvl(DisasContext *s, int rd, int rs1, 
TCGv s2)
 {
 TCGv s1, dst;
 
-if (!require_rvv(s) ||
-!(has_ext(s, RVV) || s->cfg_ptr->ext_zve32f ||
-  s->cfg_ptr->ext_zve64f)) {
+if (!require_rvv(s) || !s->cfg_ptr->ext_zve32f) {
 return false;
 }
 
@@ -210,9 +208,7 @@ static bool do_vsetivli(DisasContext *s, int rd, TCGv s1, 
TCGv s2)
 {
 TCGv dst;
 
-if (!require_rvv(s) ||
-!(has_ext(s, RVV) || s->cfg_ptr->ext_zve32f ||
-  s->cfg_ptr->ext_zve64f)) {
+if (!require_rvv(s) || !s->cfg_ptr->ext_zve32f) {
 return false;
 }
 
-- 
2.25.1




[PATCH v2 06/14] target/riscv: Add propertie check for Zvfh{min} extensions

2023-02-14 Thread Weiwei Li
Add check for Zvfh and Zvfhmin.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index c5c60d9e4d..e9832ea544 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -768,6 +768,20 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 return;
 }
 
+if (cpu->cfg.ext_zvfh) {
+cpu->cfg.ext_zvfhmin = true;
+}
+
+if (cpu->cfg.ext_zvfhmin && !cpu->cfg.ext_zve32f) {
+error_setg(errp, "Zvfh/Zvfhmin extensions require Zve32f extension");
+return;
+}
+
+if (cpu->cfg.ext_zvfh && !cpu->cfg.ext_zfhmin) {
+error_setg(errp, "Zvfh extensions requires Zfhmin extension");
+return;
+}
+
 /* Set the ISA extensions, checks should have happened above */
 if (cpu->cfg.ext_zhinx) {
 cpu->cfg.ext_zhinxmin = true;
-- 
2.25.1




[PATCH v2 01/14] target/riscv: Fix the relationship between Zfhmin and Zfh

2023-02-14 Thread Weiwei Li
Zfhmin is part of Zfh, so Zfhmin will be enabled when Zfh is enabled.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 0dd2f0c753..eb0cd12a6a 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -729,7 +729,11 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 return;
 }
 
-if ((cpu->cfg.ext_zfh || cpu->cfg.ext_zfhmin) && !cpu->cfg.ext_f) {
+if (cpu->cfg.ext_zfh) {
+cpu->cfg.ext_zfhmin = true;
+}
+
+if (cpu->cfg.ext_zfhmin && !cpu->cfg.ext_f) {
 error_setg(errp, "Zfh/Zfhmin extensions require F extension");
 return;
 }
-- 
2.25.1




[PATCH v2 14/14] target/riscv: Expose properties for Zv* extensions

2023-02-14 Thread Weiwei Li
Expose Zve64d,Zvfh,Zvfhmin properties.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 44abadc811..9d309b1a7f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -101,6 +101,9 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zkt, true, PRIV_VERSION_1_12_0, ext_zkt),
 ISA_EXT_DATA_ENTRY(zve32f, true, PRIV_VERSION_1_12_0, ext_zve32f),
 ISA_EXT_DATA_ENTRY(zve64f, true, PRIV_VERSION_1_12_0, ext_zve64f),
+ISA_EXT_DATA_ENTRY(zve64d, true, PRIV_VERSION_1_12_0, ext_zve64d),
+ISA_EXT_DATA_ENTRY(zvfh, true, PRIV_VERSION_1_12_0, ext_zvfh),
+ISA_EXT_DATA_ENTRY(zvfhmin, true, PRIV_VERSION_1_12_0, ext_zvfhmin),
 ISA_EXT_DATA_ENTRY(zhinx, true, PRIV_VERSION_1_12_0, ext_zhinx),
 ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin),
 ISA_EXT_DATA_ENTRY(smaia, true, PRIV_VERSION_1_12_0, ext_smaia),
@@ -1126,6 +1129,7 @@ static Property riscv_cpu_extensions[] = {
 DEFINE_PROP_BOOL("Zfhmin", RISCVCPU, cfg.ext_zfhmin, false),
 DEFINE_PROP_BOOL("Zve32f", RISCVCPU, cfg.ext_zve32f, false),
 DEFINE_PROP_BOOL("Zve64f", RISCVCPU, cfg.ext_zve64f, false),
+DEFINE_PROP_BOOL("Zve64d", RISCVCPU, cfg.ext_zve64d, false),
 DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
 DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
 DEFINE_PROP_BOOL("sstc", RISCVCPU, cfg.ext_sstc, true),
@@ -1185,6 +1189,9 @@ static Property riscv_cpu_extensions[] = {
 DEFINE_PROP_BOOL("x-smaia", RISCVCPU, cfg.ext_smaia, false),
 DEFINE_PROP_BOOL("x-ssaia", RISCVCPU, cfg.ext_ssaia, false),
 
+DEFINE_PROP_BOOL("x-zvfh", RISCVCPU, cfg.ext_zvfh, false),
+DEFINE_PROP_BOOL("x-zvfhmin", RISCVCPU, cfg.ext_zvfhmin, false),
+
 DEFINE_PROP_END_OF_LIST(),
 };
 
-- 
2.25.1




[PATCH v2 05/14] target/riscv: Fix relationship between V, Zve*, F and D

2023-02-14 Thread Weiwei Li
Add dependence chain:
*  V => Zve64d => Zve64f => Zve32f => F
*  V => Zve64d => D

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
---
 target/riscv/cpu.c | 21 ++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 9a89bea2a3..c5c60d9e4d 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -743,12 +743,27 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 return;
 }
 
-if (cpu->cfg.ext_v && !cpu->cfg.ext_d) {
-error_setg(errp, "V extension requires D extension");
+/* The V vector extension depends on the Zve64d extension */
+if (cpu->cfg.ext_v) {
+cpu->cfg.ext_zve64d = true;
+}
+
+/* The Zve64d extension depends on the Zve64f extension */
+if (cpu->cfg.ext_zve64d) {
+cpu->cfg.ext_zve64f = true;
+}
+
+/* The Zve64f extension depends on the Zve32f extension */
+if (cpu->cfg.ext_zve64f) {
+cpu->cfg.ext_zve32f = true;
+}
+
+if (cpu->cfg.ext_zve64d && !cpu->cfg.ext_d) {
+error_setg(errp, "Zve64d/V extensions require D extension");
 return;
 }
 
-if ((cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f) && !cpu->cfg.ext_f) {
+if (cpu->cfg.ext_zve32f && !cpu->cfg.ext_f) {
 error_setg(errp, "Zve32f/Zve64f extensions require F extension");
 return;
 }
-- 
2.25.1




[PATCH v2 07/14] target/riscv: Indent fixes in cpu.c

2023-02-14 Thread Weiwei Li
Fix indent problems in vector related check.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.c | 44 ++--
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index e9832ea544..44abadc811 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -798,7 +798,7 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 }
 if (cpu->cfg.ext_f) {
 error_setg(errp,
-"Zfinx cannot be supported together with F extension");
+   "Zfinx cannot be supported together with F extension");
 return;
 }
 }
@@ -861,40 +861,40 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 ext |= RVV;
 if (!is_power_of_2(cpu->cfg.vlen)) {
 error_setg(errp,
-"Vector extension VLEN must be power of 2");
+   "Vector extension VLEN must be power of 2");
 return;
 }
 if (cpu->cfg.vlen > RV_VLEN_MAX || cpu->cfg.vlen < 128) {
 error_setg(errp,
-"Vector extension implementation only supports VLEN "
-"in the range [128, %d]", RV_VLEN_MAX);
+   "Vector extension implementation only supports VLEN "
+   "in the range [128, %d]", RV_VLEN_MAX);
 return;
 }
 if (!is_power_of_2(cpu->cfg.elen)) {
 error_setg(errp,
-"Vector extension ELEN must be power of 2");
+   "Vector extension ELEN must be power of 2");
 return;
 }
-if (cpu->cfg.elen > 64 || cpu->cfg.elen < 8) {
-error_setg(errp,
-"Vector extension implementation only supports ELEN "
-"in the range [8, 64]");
-return;
-}
-if (cpu->cfg.vext_spec) {
-if (!g_strcmp0(cpu->cfg.vext_spec, "v1.0")) {
-vext_version = VEXT_VERSION_1_00_0;
-} else {
+if (cpu->cfg.elen > 64 || cpu->cfg.elen < 8) {
 error_setg(errp,
-   "Unsupported vector spec version '%s'",
-   cpu->cfg.vext_spec);
+   "Vector extension implementation only supports ELEN "
+   "in the range [8, 64]");
 return;
 }
-} else {
-qemu_log("vector version is not specified, "
- "use the default value v1.0\n");
-}
-set_vext_version(env, vext_version);
+if (cpu->cfg.vext_spec) {
+if (!g_strcmp0(cpu->cfg.vext_spec, "v1.0")) {
+vext_version = VEXT_VERSION_1_00_0;
+} else {
+error_setg(errp,
+   "Unsupported vector spec version '%s'",
+   cpu->cfg.vext_spec);
+return;
+}
+} else {
+qemu_log("vector version is not specified, "
+ "use the default value v1.0\n");
+}
+set_vext_version(env, vext_version);
 }
 if (cpu->cfg.ext_j) {
 ext |= RVJ;
-- 
2.25.1




[PATCH v2 11/14] target/riscv: Add support for Zvfh/zvfhmin extensions

2023-02-14 Thread Weiwei Li
Zvfh supports vector float point instructions with SEW = 16
and supports conversions between 8-bit integers and binary16 values.

Zvfhmin supports vfwcvt.f.f.v and vfncvt.f.f.w instructions.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Daniel Henrique Barboza 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 31 +++--
 1 file changed, 29 insertions(+), 2 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 9053759546..9b2c5c9ac0 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -40,6 +40,7 @@ static bool require_rvf(DisasContext *s)
 
 switch (s->sew) {
 case MO_16:
+return s->cfg_ptr->ext_zvfh;
 case MO_32:
 return s->cfg_ptr->ext_zve32f;
 case MO_64:
@@ -57,6 +58,25 @@ static bool require_scale_rvf(DisasContext *s)
 
 switch (s->sew) {
 case MO_8:
+return s->cfg_ptr->ext_zvfh;
+case MO_16:
+return s->cfg_ptr->ext_zve32f;
+case MO_32:
+return s->cfg_ptr->ext_zve64d;
+default:
+return false;
+}
+}
+
+static bool require_scale_rvfmin(DisasContext *s)
+{
+if (s->mstatus_fs == 0) {
+return false;
+}
+
+switch (s->sew) {
+case MO_8:
+return s->cfg_ptr->ext_zvfhmin;
 case MO_16:
 return s->cfg_ptr->ext_zve32f;
 case MO_32:
@@ -2798,7 +2818,7 @@ static bool opxfv_widen_check(DisasContext *s, arg_rmr *a)
 static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
 {
 return opfv_widen_check(s, a) &&
-   require_scale_rvf(s) &&
+   require_scale_rvfmin(s) &&
(s->sew != MO_8);
 }
 
@@ -2909,6 +2929,13 @@ static bool opfxv_narrow_check(DisasContext *s, arg_rmr 
*a)
 }
 
 static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
+{
+return opfv_narrow_check(s, a) &&
+   require_scale_rvfmin(s) &&
+   (s->sew != MO_8);
+}
+
+static bool opffv_rod_narrow_check(DisasContext *s, arg_rmr *a)
 {
 return opfv_narrow_check(s, a) &&
require_scale_rvf(s) &&
@@ -2952,7 +2979,7 @@ GEN_OPFV_NARROW_TRANS(vfncvt_f_x_w, opfxv_narrow_check, 
vfncvt_f_x_w,
 GEN_OPFV_NARROW_TRANS(vfncvt_f_f_w, opffv_narrow_check, vfncvt_f_f_w,
   RISCV_FRM_DYN)
 /* Reuse the helper function from vfncvt.f.f.w */
-GEN_OPFV_NARROW_TRANS(vfncvt_rod_f_f_w, opffv_narrow_check, vfncvt_f_f_w,
+GEN_OPFV_NARROW_TRANS(vfncvt_rod_f_f_w, opffv_rod_narrow_check, vfncvt_f_f_w,
   RISCV_FRM_ROD)
 
 static bool opxfv_narrow_check(DisasContext *s, arg_rmr *a)
-- 
2.25.1




[PATCH v2 00/14] target/riscv: Some updates to float point related extensions

2023-02-14 Thread Weiwei Li
Specification for Zv* extensions can be found in:

https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc

The port is available here:
https://github.com/plctlab/plct-qemu/tree/plct-zvfh-upstream-v2

v2:

* improve the error message for vector related check suggested by Daniel 
Henrique Barboza in patch 5
* add similar simplification for check in csr.c/cpu_helper.c in patch 8
* fix typos in commit messages


Weiwei Li (14):
  target/riscv: Fix the relationship between Zfhmin and Zfh
  target/riscv: Fix the relationship between Zhinxmin and Zhinx
  target/riscv: Simplify the check for Zfhmin and Zhinxmin
  target/riscv: Add cfg properties for Zv* extensions
  target/riscv: Fix relationship between V, Zve*, F and  D
  target/riscv: Add propertie check for Zvfh{min} extensions
  target/riscv: Indent fixes in cpu.c
  target/riscv: Simplify check for Zve32f and Zve64f
  target/riscv: Replace check for F/D to Zve32f/Zve64d in
trans_rvv.c.inc
  target/riscv: Remove rebundunt check for zve32f and zve64f
  target/riscv: Add support for Zvfh/zvfhmin extensions
  target/riscv: Fix check for vector load/store instructions when EEW=64
  target/riscv: Simplify check for EEW = 64 in trans_rvv.c.inc
  target/riscv: Expose properties for Zv* extensions

 target/riscv/cpu.c|  99 
 target/riscv/cpu.h|   3 +
 target/riscv/cpu_helper.c |   2 +-
 target/riscv/csr.c|   3 +-
 target/riscv/insn_trans/trans_rvv.c.inc   | 184 +++---
 target/riscv/insn_trans/trans_rvzfh.c.inc |  25 ++-
 6 files changed, 146 insertions(+), 170 deletions(-)

-- 
2.25.1




[PATCH v2 09/14] target/riscv: Replace check for F/D to Zve32f/Zve64d in trans_rvv.c.inc

2023-02-14 Thread Weiwei Li
Check for Zve32f/Zve64d can overlap check for F/D.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Daniel Henrique Barboza 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 6f7ecf1a68..9b2711b94b 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -41,9 +41,9 @@ static bool require_rvf(DisasContext *s)
 switch (s->sew) {
 case MO_16:
 case MO_32:
-return has_ext(s, RVF);
+return s->cfg_ptr->ext_zve32f;
 case MO_64:
-return has_ext(s, RVD);
+return s->cfg_ptr->ext_zve64d;
 default:
 return false;
 }
@@ -58,9 +58,9 @@ static bool require_scale_rvf(DisasContext *s)
 switch (s->sew) {
 case MO_8:
 case MO_16:
-return has_ext(s, RVF);
+return s->cfg_ptr->ext_zve32f;
 case MO_32:
-return has_ext(s, RVD);
+return s->cfg_ptr->ext_zve64d;
 default:
 return false;
 }
-- 
2.25.1




[PATCH v2 02/14] target/riscv: Fix the relationship between Zhinxmin and Zhinx

2023-02-14 Thread Weiwei Li
Just like zfh and zfhmin, Zhinxmin is part of Zhinx so Zhinxmin
will be enabled when Zhinx is enabled.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index eb0cd12a6a..9a89bea2a3 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -754,8 +754,11 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 }
 
 /* Set the ISA extensions, checks should have happened above */
-if (cpu->cfg.ext_zdinx || cpu->cfg.ext_zhinx ||
-cpu->cfg.ext_zhinxmin) {
+if (cpu->cfg.ext_zhinx) {
+cpu->cfg.ext_zhinxmin = true;
+}
+
+if (cpu->cfg.ext_zdinx || cpu->cfg.ext_zhinxmin) {
 cpu->cfg.ext_zfinx = true;
 }
 
-- 
2.25.1




[PATCH v2 10/14] target/riscv: Remove rebundunt check for zve32f and zve64f

2023-02-14 Thread Weiwei Li
Require_zve32/64f have been overlapped by require_rvf/require_scale_rvf.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Daniel Henrique Barboza 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 128 
 1 file changed, 21 insertions(+), 107 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 9b2711b94b..9053759546 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -66,50 +66,6 @@ static bool require_scale_rvf(DisasContext *s)
 }
 }
 
-static bool require_zve32f(DisasContext *s)
-{
-/* RVV + Zve32f = RVV. */
-if (has_ext(s, RVV)) {
-return true;
-}
-
-/* Zve32f doesn't support FP64. (Section 18.2) */
-return s->cfg_ptr->ext_zve32f ? s->sew <= MO_32 : true;
-}
-
-static bool require_scale_zve32f(DisasContext *s)
-{
-/* RVV + Zve32f = RVV. */
-if (has_ext(s, RVV)) {
-return true;
-}
-
-/* Zve32f doesn't support FP64. (Section 18.2) */
-return s->cfg_ptr->ext_zve64f ? s->sew <= MO_16 : true;
-}
-
-static bool require_zve64f(DisasContext *s)
-{
-/* RVV + Zve64f = RVV. */
-if (has_ext(s, RVV)) {
-return true;
-}
-
-/* Zve64f doesn't support FP64. (Section 18.2) */
-return s->cfg_ptr->ext_zve64f ? s->sew <= MO_32 : true;
-}
-
-static bool require_scale_zve64f(DisasContext *s)
-{
-/* RVV + Zve64f = RVV. */
-if (has_ext(s, RVV)) {
-return true;
-}
-
-/* Zve64f doesn't support FP64. (Section 18.2) */
-return s->cfg_ptr->ext_zve64f ? s->sew <= MO_16 : true;
-}
-
 /* Destination vector register group cannot overlap source mask register. */
 static bool require_vm(int vm, int vd)
 {
@@ -2331,9 +2287,7 @@ static bool opfvv_check(DisasContext *s, arg_rmrr *a)
 return require_rvv(s) &&
require_rvf(s) &&
vext_check_isa_ill(s) &&
-   vext_check_sss(s, a->rd, a->rs1, a->rs2, a->vm) &&
-   require_zve32f(s) &&
-   require_zve64f(s);
+   vext_check_sss(s, a->rd, a->rs1, a->rs2, a->vm);
 }
 
 /* OPFVV without GVEC IR */
@@ -2421,9 +2375,7 @@ static bool opfvf_check(DisasContext *s, arg_rmrr *a)
 return require_rvv(s) &&
require_rvf(s) &&
vext_check_isa_ill(s) &&
-   vext_check_ss(s, a->rd, a->rs2, a->vm) &&
-   require_zve32f(s) &&
-   require_zve64f(s);
+   vext_check_ss(s, a->rd, a->rs2, a->vm);
 }
 
 /* OPFVF without GVEC IR */
@@ -2461,9 +2413,7 @@ static bool opfvv_widen_check(DisasContext *s, arg_rmrr 
*a)
require_scale_rvf(s) &&
(s->sew != MO_8) &&
vext_check_isa_ill(s) &&
-   vext_check_dss(s, a->rd, a->rs1, a->rs2, a->vm) &&
-   require_scale_zve32f(s) &&
-   require_scale_zve64f(s);
+   vext_check_dss(s, a->rd, a->rs1, a->rs2, a->vm);
 }
 
 /* OPFVV with WIDEN */
@@ -2506,9 +2456,7 @@ static bool opfvf_widen_check(DisasContext *s, arg_rmrr 
*a)
require_scale_rvf(s) &&
(s->sew != MO_8) &&
vext_check_isa_ill(s) &&
-   vext_check_ds(s, a->rd, a->rs2, a->vm) &&
-   require_scale_zve32f(s) &&
-   require_scale_zve64f(s);
+   vext_check_ds(s, a->rd, a->rs2, a->vm);
 }
 
 /* OPFVF with WIDEN */
@@ -2540,9 +2488,7 @@ static bool opfwv_widen_check(DisasContext *s, arg_rmrr 
*a)
require_scale_rvf(s) &&
(s->sew != MO_8) &&
vext_check_isa_ill(s) &&
-   vext_check_dds(s, a->rd, a->rs1, a->rs2, a->vm) &&
-   require_scale_zve32f(s) &&
-   require_scale_zve64f(s);
+   vext_check_dds(s, a->rd, a->rs1, a->rs2, a->vm);
 }
 
 /* WIDEN OPFVV with WIDEN */
@@ -2585,9 +2531,7 @@ static bool opfwf_widen_check(DisasContext *s, arg_rmrr 
*a)
require_scale_rvf(s) &&
(s->sew != MO_8) &&
vext_check_isa_ill(s) &&
-   vext_check_dd(s, a->rd, a->rs2, a->vm) &&
-   require_scale_zve32f(s) &&
-   require_scale_zve64f(s);
+   vext_check_dd(s, a->rd, a->rs2, a->vm);
 }
 
 /* WIDEN OPFVF with WIDEN */
@@ -2664,9 +2608,7 @@ static bool opfv_check(DisasContext *s, arg_rmr *a)
require_rvf(s) &&
vext_check_isa_ill(s) &&
/* OPFV instructions ignore vs1 check */
-   vext_check_ss(s, a->rd, a->rs2, a->vm) &&
-   require_zve32f(s) &&
-   require_zve64f(s);
+   vext_check_ss(s, a->rd, a->rs2, a->vm);
 }
 
 static bool do_opfv(DisasContext *s, arg_rmr *a,
@@ -2731,9 +2673,7 @@ static bool opfvv_cmp_check(DisasContext *s, arg_rmrr *a)
 return require_rvv(s) &&
require_rvf(s) &&
vext_check_isa_ill(s) &&
-   vext_check_mss(s, a->rd, a->rs1, a->rs2) &&
-   require_zve32f(s) &&
-   require_zve64f(s);
+   vext_check_mss(s, a->rd, a->rs1, a->rs2);
 }
 
 GEN_OPFVV_TRANS(vmfeq_vv, 

[PATCH v2 04/14] target/riscv: Add cfg properties for Zv* extensions

2023-02-14 Thread Weiwei Li
Add properties for Zve64d,Zvfh,Zvfhmin extensions.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 7128438d8e..54c6875617 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -462,7 +462,10 @@ struct RISCVCPUConfig {
 bool ext_zhinxmin;
 bool ext_zve32f;
 bool ext_zve64f;
+bool ext_zve64d;
 bool ext_zmmul;
+bool ext_zvfh;
+bool ext_zvfhmin;
 bool ext_smaia;
 bool ext_ssaia;
 bool ext_sscofpmf;
-- 
2.25.1




[PATCH v2 03/14] target/riscv: Simplify the check for Zfhmin and Zhinxmin

2023-02-14 Thread Weiwei Li
We needn't check Zfh and Zhinx in these instructions.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Daniel Henrique Barboza 
---
 target/riscv/insn_trans/trans_rvzfh.c.inc | 25 +++
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvzfh.c.inc 
b/target/riscv/insn_trans/trans_rvzfh.c.inc
index 2ad5716312..85fc1aa822 100644
--- a/target/riscv/insn_trans/trans_rvzfh.c.inc
+++ b/target/riscv/insn_trans/trans_rvzfh.c.inc
@@ -28,15 +28,14 @@
 }  \
 } while (0)
 
-#define REQUIRE_ZFH_OR_ZFHMIN(ctx) do {   \
-if (!(ctx->cfg_ptr->ext_zfh || ctx->cfg_ptr->ext_zfhmin)) { \
+#define REQUIRE_ZFHMIN(ctx) do {  \
+if (!ctx->cfg_ptr->ext_zfhmin) {  \
 return false; \
 } \
 } while (0)
 
-#define REQUIRE_ZFH_OR_ZFHMIN_OR_ZHINX_OR_ZHINXMIN(ctx) do { \
-if (!(ctx->cfg_ptr->ext_zfh || ctx->cfg_ptr->ext_zfhmin ||  \
-  ctx->cfg_ptr->ext_zhinx || ctx->cfg_ptr->ext_zhinxmin)) { \
+#define REQUIRE_ZFHMIN_OR_ZHINXMIN(ctx) do { \
+if (!(ctx->cfg_ptr->ext_zfhmin || ctx->cfg_ptr->ext_zhinxmin)) { \
 return false;\
 }\
 } while (0)
@@ -47,7 +46,7 @@ static bool trans_flh(DisasContext *ctx, arg_flh *a)
 TCGv t0;
 
 REQUIRE_FPU;
-REQUIRE_ZFH_OR_ZFHMIN(ctx);
+REQUIRE_ZFHMIN(ctx);
 
 decode_save_opc(ctx);
 t0 = get_gpr(ctx, a->rs1, EXT_NONE);
@@ -70,7 +69,7 @@ static bool trans_fsh(DisasContext *ctx, arg_fsh *a)
 TCGv t0;
 
 REQUIRE_FPU;
-REQUIRE_ZFH_OR_ZFHMIN(ctx);
+REQUIRE_ZFHMIN(ctx);
 
 decode_save_opc(ctx);
 t0 = get_gpr(ctx, a->rs1, EXT_NONE);
@@ -401,7 +400,7 @@ static bool trans_fmax_h(DisasContext *ctx, arg_fmax_h *a)
 static bool trans_fcvt_s_h(DisasContext *ctx, arg_fcvt_s_h *a)
 {
 REQUIRE_FPU;
-REQUIRE_ZFH_OR_ZFHMIN_OR_ZHINX_OR_ZHINXMIN(ctx);
+REQUIRE_ZFHMIN_OR_ZHINXMIN(ctx);
 
 TCGv_i64 dest = dest_fpr(ctx, a->rd);
 TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
@@ -418,7 +417,7 @@ static bool trans_fcvt_s_h(DisasContext *ctx, arg_fcvt_s_h 
*a)
 static bool trans_fcvt_d_h(DisasContext *ctx, arg_fcvt_d_h *a)
 {
 REQUIRE_FPU;
-REQUIRE_ZFH_OR_ZFHMIN_OR_ZHINX_OR_ZHINXMIN(ctx);
+REQUIRE_ZFHMIN_OR_ZHINXMIN(ctx);
 REQUIRE_ZDINX_OR_D(ctx);
 
 TCGv_i64 dest = dest_fpr(ctx, a->rd);
@@ -436,7 +435,7 @@ static bool trans_fcvt_d_h(DisasContext *ctx, arg_fcvt_d_h 
*a)
 static bool trans_fcvt_h_s(DisasContext *ctx, arg_fcvt_h_s *a)
 {
 REQUIRE_FPU;
-REQUIRE_ZFH_OR_ZFHMIN_OR_ZHINX_OR_ZHINXMIN(ctx);
+REQUIRE_ZFHMIN_OR_ZHINXMIN(ctx);
 
 TCGv_i64 dest = dest_fpr(ctx, a->rd);
 TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
@@ -452,7 +451,7 @@ static bool trans_fcvt_h_s(DisasContext *ctx, arg_fcvt_h_s 
*a)
 static bool trans_fcvt_h_d(DisasContext *ctx, arg_fcvt_h_d *a)
 {
 REQUIRE_FPU;
-REQUIRE_ZFH_OR_ZFHMIN_OR_ZHINX_OR_ZHINXMIN(ctx);
+REQUIRE_ZFHMIN_OR_ZHINXMIN(ctx);
 REQUIRE_ZDINX_OR_D(ctx);
 
 TCGv_i64 dest = dest_fpr(ctx, a->rd);
@@ -585,7 +584,7 @@ static bool trans_fcvt_h_wu(DisasContext *ctx, 
arg_fcvt_h_wu *a)
 static bool trans_fmv_x_h(DisasContext *ctx, arg_fmv_x_h *a)
 {
 REQUIRE_FPU;
-REQUIRE_ZFH_OR_ZFHMIN(ctx);
+REQUIRE_ZFHMIN(ctx);
 
 TCGv dest = dest_gpr(ctx, a->rd);
 
@@ -605,7 +604,7 @@ static bool trans_fmv_x_h(DisasContext *ctx, arg_fmv_x_h *a)
 static bool trans_fmv_h_x(DisasContext *ctx, arg_fmv_h_x *a)
 {
 REQUIRE_FPU;
-REQUIRE_ZFH_OR_ZFHMIN(ctx);
+REQUIRE_ZFHMIN(ctx);
 
 TCGv t0 = get_gpr(ctx, a->rs1, EXT_ZERO);
 
-- 
2.25.1




[PATCH v4 5/6] qapi: remove _JSONObject

2023-02-14 Thread John Snow
We can remove this alias as it only has two usages now, and no longer
pays for the confusion of "yet another type".

Signed-off-by: John Snow 
---
 scripts/qapi/expr.py   | 13 +++--
 scripts/qapi/parser.py |  5 ++---
 2 files changed, 5 insertions(+), 13 deletions(-)

diff --git a/scripts/qapi/expr.py b/scripts/qapi/expr.py
index 52153a2eec5..fc4defecc8e 100644
--- a/scripts/qapi/expr.py
+++ b/scripts/qapi/expr.py
@@ -48,14 +48,6 @@
 from .source import QAPISourceInfo
 
 
-# Deserialized JSON objects as returned by the parser.
-# The values of this mapping are not necessary to exhaustively type
-# here (and also not practical as long as mypy lacks recursive
-# types), because the purpose of this module is to interrogate that
-# type.
-_JSONObject = Dict[str, object]
-
-
 # See check_name_str(), below.
 valid_name = re.compile(r'(__[a-z0-9.-]+_)?'
 r'(x-)?'
@@ -192,7 +184,7 @@ def check_defn_name_str(name: str, info: QAPISourceInfo, 
meta: str) -> None:
 info, "%s name should not end in 'List'" % meta)
 
 
-def check_keys(value: _JSONObject,
+def check_keys(value: Dict[str, object],
info: QAPISourceInfo,
source: str,
required: Sequence[str],
@@ -256,7 +248,8 @@ def check_flags(expr: QAPIExpression) -> None:
 expr.info, "flags 'allow-oob' and 'coroutine' are incompatible")
 
 
-def check_if(expr: _JSONObject, info: QAPISourceInfo, source: str) -> None:
+def check_if(expr: Dict[str, object],
+ info: QAPISourceInfo, source: str) -> None:
 """
 Validate the ``if`` member of an object.
 
diff --git a/scripts/qapi/parser.py b/scripts/qapi/parser.py
index 50906e27d49..d570086e1a9 100644
--- a/scripts/qapi/parser.py
+++ b/scripts/qapi/parser.py
@@ -42,9 +42,8 @@
 _ExprValue = Union[List[object], Dict[str, object], str, bool]
 
 
-# FIXME: Consolidate and centralize definitions for _ExprValue,
-# JSONValue, and _JSONObject; currently scattered across several
-# modules.
+# FIXME: Consolidate and centralize definitions for _ExprValue and
+# JSONValue; currently scattered across several modules.
 
 
 class QAPIExpression(Dict[str, object]):
-- 
2.39.0




[PATCH v4 1/6] qapi: Update flake8 config

2023-02-14 Thread John Snow
New versions of flake8 don't like same-line comments. (It's a version
newer than what fc37 ships, but it still makes my life easier to fix it
now.)

Signed-off-by: John Snow 
Reviewed-by: Markus Armbruster 
---
 scripts/qapi/.flake8 | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/scripts/qapi/.flake8 b/scripts/qapi/.flake8
index 6b158c68b84..a873ff67309 100644
--- a/scripts/qapi/.flake8
+++ b/scripts/qapi/.flake8
@@ -1,2 +1,3 @@
 [flake8]
-extend-ignore = E722  # Prefer pylint's bare-except checks to flake8's
+# Prefer pylint's bare-except checks to flake8's
+extend-ignore = E722
-- 
2.39.0




[PATCH v4 3/6] qapi: Add minor typing workaround for 3.6

2023-02-14 Thread John Snow
Pylint under 3.6 does not believe that Collection is subscriptable at
runtime. It is, making this a Pylint
bug. https://github.com/PyCQA/pylint/issues/2377

They closed it as fixed, but that doesn't seem to be true as of Pylint
2.13.9, the latest version you can install under Python 3.6. 2.13.9 was
released 2022-05-13, about seven months after the bug was closed.

The least-annoying fix here is to just use the more specific type
Sequence, only because it seems to work in 3.6.

Signed-off-by: John Snow 
---
 scripts/qapi/expr.py | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/scripts/qapi/expr.py b/scripts/qapi/expr.py
index 5a1782b57ea..8701351fdfc 100644
--- a/scripts/qapi/expr.py
+++ b/scripts/qapi/expr.py
@@ -33,11 +33,11 @@
 
 import re
 from typing import (
-Collection,
 Dict,
 Iterable,
 List,
 Optional,
+Sequence,
 Union,
 cast,
 )
@@ -195,8 +195,8 @@ def check_defn_name_str(name: str, info: QAPISourceInfo, 
meta: str) -> None:
 def check_keys(value: _JSONObject,
info: QAPISourceInfo,
source: str,
-   required: Collection[str],
-   optional: Collection[str]) -> None:
+   required: Sequence[str],
+   optional: Sequence[str]) -> None:
 """
 Ensure that a dict has a specific set of keys.
 
-- 
2.39.0




[PATCH v4 4/6] qapi/parser: add QAPIExpression type

2023-02-14 Thread John Snow
This patch creates a new type, QAPIExpression, which represents a parsed
expression complete with QAPIDoc and QAPISourceInfo.

This patch turns parser.exprs into a list of QAPIExpression instead,
and adjusts expr.py to match.

This allows the types we specify in parser.py to be "remembered" all the
way through expr.py and into schema.py. Several assertions around
packing and unpacking this data can be removed as a result.

Signed-off-by: John Snow 
---
 scripts/qapi/expr.py   | 82 +-
 scripts/qapi/parser.py | 46 ++--
 scripts/qapi/schema.py | 72 -
 3 files changed, 100 insertions(+), 100 deletions(-)

diff --git a/scripts/qapi/expr.py b/scripts/qapi/expr.py
index 8701351fdfc..52153a2eec5 100644
--- a/scripts/qapi/expr.py
+++ b/scripts/qapi/expr.py
@@ -44,7 +44,7 @@
 
 from .common import c_name
 from .error import QAPISemError
-from .parser import QAPIDoc
+from .parser import QAPIExpression
 from .source import QAPISourceInfo
 
 
@@ -229,12 +229,11 @@ def pprint(elems: Iterable[str]) -> str:
pprint(unknown), pprint(allowed)))
 
 
-def check_flags(expr: _JSONObject, info: QAPISourceInfo) -> None:
+def check_flags(expr: QAPIExpression) -> None:
 """
 Ensure flag members (if present) have valid values.
 
 :param expr: The expression to validate.
-:param info: QAPI schema source file information.
 
 :raise QAPISemError:
 When certain flags have an invalid value, or when
@@ -243,18 +242,18 @@ def check_flags(expr: _JSONObject, info: QAPISourceInfo) 
-> None:
 for key in ('gen', 'success-response'):
 if key in expr and expr[key] is not False:
 raise QAPISemError(
-info, "flag '%s' may only use false value" % key)
+expr.info, "flag '%s' may only use false value" % key)
 for key in ('boxed', 'allow-oob', 'allow-preconfig', 'coroutine'):
 if key in expr and expr[key] is not True:
 raise QAPISemError(
-info, "flag '%s' may only use true value" % key)
+expr.info, "flag '%s' may only use true value" % key)
 if 'allow-oob' in expr and 'coroutine' in expr:
 # This is not necessarily a fundamental incompatibility, but
 # we don't have a use case and the desired semantics isn't
 # obvious.  The simplest solution is to forbid it until we get
 # a use case for it.
-raise QAPISemError(info, "flags 'allow-oob' and 'coroutine' "
- "are incompatible")
+raise QAPISemError(
+expr.info, "flags 'allow-oob' and 'coroutine' are incompatible")
 
 
 def check_if(expr: _JSONObject, info: QAPISourceInfo, source: str) -> None:
@@ -447,12 +446,11 @@ def check_features(features: Optional[object],
 check_if(feat, info, source)
 
 
-def check_enum(expr: _JSONObject, info: QAPISourceInfo) -> None:
+def check_enum(expr: QAPIExpression) -> None:
 """
 Normalize and validate this expression as an ``enum`` definition.
 
 :param expr: The expression to validate.
-:param info: QAPI schema source file information.
 
 :raise QAPISemError: When ``expr`` is not a valid ``enum``.
 :return: None, ``expr`` is normalized in-place as needed.
@@ -460,6 +458,7 @@ def check_enum(expr: _JSONObject, info: QAPISourceInfo) -> 
None:
 name = expr['enum']
 members = expr['data']
 prefix = expr.get('prefix')
+info = expr.info
 
 if not isinstance(members, list):
 raise QAPISemError(info, "'data' must be an array")
@@ -486,12 +485,11 @@ def check_enum(expr: _JSONObject, info: QAPISourceInfo) 
-> None:
 check_features(member.get('features'), info)
 
 
-def check_struct(expr: _JSONObject, info: QAPISourceInfo) -> None:
+def check_struct(expr: QAPIExpression) -> None:
 """
 Normalize and validate this expression as a ``struct`` definition.
 
 :param expr: The expression to validate.
-:param info: QAPI schema source file information.
 
 :raise QAPISemError: When ``expr`` is not a valid ``struct``.
 :return: None, ``expr`` is normalized in-place as needed.
@@ -499,16 +497,15 @@ def check_struct(expr: _JSONObject, info: QAPISourceInfo) 
-> None:
 name = cast(str, expr['struct'])  # Checked in check_exprs
 members = expr['data']
 
-check_type(members, info, "'data'", allow_dict=name)
-check_type(expr.get('base'), info, "'base'")
+check_type(members, expr.info, "'data'", allow_dict=name)
+check_type(expr.get('base'), expr.info, "'base'")
 
 
-def check_union(expr: _JSONObject, info: QAPISourceInfo) -> None:
+def check_union(expr: QAPIExpression) -> None:
 """
 Normalize and validate this expression as a ``union`` definition.
 
 :param expr: The expression to validate.
-:param info: QAPI schema source file information.
 
 :raise QAPISemError: when ``expr`` is not a valid ``union``.
 :return: None, 

[PATCH v4 2/6] qapi: update pylint configuration

2023-02-14 Thread John Snow
Newer versions of pylint disable the "no-self-use" message by
default. Older versions don't, though. If we leave the suppressions in,
pylint yelps about useless options. Just tell pylint to shush.

Signed-off-by: John Snow 
Reviewed-by: Markus Armbruster 
---
 scripts/qapi/pylintrc | 1 +
 1 file changed, 1 insertion(+)

diff --git a/scripts/qapi/pylintrc b/scripts/qapi/pylintrc
index a7246282030..90546df5345 100644
--- a/scripts/qapi/pylintrc
+++ b/scripts/qapi/pylintrc
@@ -23,6 +23,7 @@ disable=fixme,
 too-many-statements,
 too-many-instance-attributes,
 consider-using-f-string,
+useless-option-value,
 
 [REPORTS]
 
-- 
2.39.0




[PATCH v4 0/6] qapi: static typing conversion, pt5c

2023-02-14 Thread John Snow
This is part five (c), and focuses on sharing strict types between
parser.py and expr.py.

gitlab: https://gitlab.com/jsnow/qemu/-/commits/python-qapi-cleanup-pt5c

Every commit should pass with:
 - `isort -c qapi/`
 - `flake8 qapi/`
 - `pylint --rcfile=qapi/pylintrc qapi/`
 - `mypy --config-file=qapi/mypy.ini qapi/`

V4:
 - Dropped the "split check_exprs" patch
 - Based the QAPIExpression class on Dict[str, object] instead
 - Removed the type workaround patch, which is no longer needed.
 - Added a new patch to fix a problem with Python 3.6 and pylint

V3:
 - Squashed a bunch of patches into the QAPIExpression patch
 - Added a few 'info' locals whenever there were >= 3 usages to help
   minimize some churn
 - Removed some type redundancy from docstrings
 - Brought along the two patches from pt0 that I want merged.
 - Removed 'pexpr' entirely, there's no intermediate state where it's
   needed now.
 - Minor style issues.

John Snow (6):
  qapi: Update flake8 config
  qapi: update pylint configuration
  qapi: Add minor typing workaround for 3.6
  qapi/parser: add QAPIExpression type
  qapi: remove _JSONObject
  qapi: remove JSON value FIXME

 scripts/qapi/.flake8   |   3 +-
 scripts/qapi/expr.py   | 101 -
 scripts/qapi/parser.py |  41 +
 scripts/qapi/pylintrc  |   1 +
 scripts/qapi/schema.py |  72 +++--
 5 files changed, 104 insertions(+), 114 deletions(-)

-- 
2.39.0





[PATCH v4 6/6] qapi: remove JSON value FIXME

2023-02-14 Thread John Snow
With the two major JSON-ish type hierarchies clarified for distinct
purposes; QAPIExpression for parsed expressions and JSONValue for
introspection data, remove this FIXME as no longer an action item.

A third JSON-y data type, _ExprValue, is not meant to represent JSON in
the abstract but rather only the possible legal return values from a
single function, get_expr(). It isn't appropriate to attempt to merge it
with either of the above two types.

In theory, it may be possible to define a completely agnostic
one-size-fits-all JSON type hierarchy that any other user could borrow -
in practice, it's tough to wrangle the differences between invariant,
covariant and contravariant types: input and output parameters demand
different properties of such a structure.

However, QAPIExpression serves to authoritatively type user input to the
QAPI parser, while JSONValue serves to authoritatively type qapi
generator *output* to be served back to client users at runtime via
QMP. The AST for these two types are different and cannot be wholly
merged into a unified syntax.

They could, in theory, share some JSON primitive definitions. In
practice, this is currently more trouble than it's worth with mypy's
current expressive power. As such, declare this "done enough for now".

Signed-off-by: John Snow 
---
 scripts/qapi/parser.py | 4 
 1 file changed, 4 deletions(-)

diff --git a/scripts/qapi/parser.py b/scripts/qapi/parser.py
index d570086e1a9..878f90b4583 100644
--- a/scripts/qapi/parser.py
+++ b/scripts/qapi/parser.py
@@ -42,10 +42,6 @@
 _ExprValue = Union[List[object], Dict[str, object], str, bool]
 
 
-# FIXME: Consolidate and centralize definitions for _ExprValue and
-# JSONValue; currently scattered across several modules.
-
-
 class QAPIExpression(Dict[str, object]):
 # pylint: disable=too-few-public-methods
 def __init__(self,
-- 
2.39.0




Re: [PULL 00/10] xenpvh machine

2023-02-14 Thread Stefano Stabellini
On Tue, 14 Feb 2023, Peter Maydell wrote:
> On Mon, 13 Feb 2023 at 22:34, Stefano Stabellini  
> wrote:
> >
> > On Mon, 13 Feb 2023, Peter Maydell wrote:
> > > On Fri, 10 Feb 2023 at 22:27, Stefano Stabellini  
> > > wrote:
> > > >
> > > > The following changes since commit 
> > > > 90595cc9396bb910b148391fea2e78dd8c6c8b27:
> > > >
> > > >   Merge tag 'migration-20230209-pull-request' of 
> > > > https://gitlab.com/juan.quintela/qemu into staging (2023-02-10 10:50:21 
> > > > +)
> > > >
> > > > are available in the Git repository at:
> > > >
> > > >   https://gitlab.com/sstabellini/qemu.git xenpvh
> > > >
> > > > for you to fetch changes up to 3f8ee848693872e3783cdcf2862be5421bb9cbcb:
> > > >
> > > >   meson.build: enable xenpv machine build for ARM (2023-02-10 14:23:47 
> > > > -0800)
> > >
> > > Hi -- 'xenpvh' doesn't appear to be a signed tag:
> > >
> > > >From https://gitlab.com/sstabellini/qemu
> > >  * branchxenpvh -> FETCH_HEAD
> > > error: FETCH_HEAD: cannot verify a non-tag object of type commit.
> > > Does not appear to be a signed tag
> >
> > Sorry "xenpvh" was a branch name. Here is the corresponding signed tag:
> >
> > https://gitlab.com/sstabellini/qemu xenpvh-tag
> 
> Something weird has happened here -- I'm getting merge conflicts
> in files in migration/ and in tests/unit/test-xbzrle.c, even though
> your pullreq diffstat says it doesn't touch those files. Can you
> try a rebase and resend?

Just sent as a full pull request patch series. Also here for
convenience:

https://gitlab.com/sstabellini/qemu xenpvh2



[PULL v2 09/10] hw/arm: introduce xenpvh machine

2023-02-14 Thread Stefano Stabellini
From: Vikram Garhwal 

Add a new machine xenpvh which creates a IOREQ server to register/connect with
Xen Hypervisor.

Optional: When CONFIG_TPM is enabled, it also creates a tpm-tis-device, adds a
TPM emulator and connects to swtpm running on host machine via chardev socket
and support TPM functionalities for a guest domain.

Extra command line for aarch64 xenpvh QEMU to connect to swtpm:
-chardev socket,id=chrtpm,path=/tmp/myvtpm2/swtpm-sock \
-tpmdev emulator,id=tpm0,chardev=chrtpm \
-machine tpm-base-addr=0x0c00 \

swtpm implements a TPM software emulator(TPM 1.2 & TPM 2) built on libtpms and
provides access to TPM functionality over socket, chardev and CUSE interface.
Github repo: https://github.com/stefanberger/swtpm
Example for starting swtpm on host machine:
mkdir /tmp/vtpm2
swtpm socket --tpmstate dir=/tmp/vtpm2 \
--ctrl type=unixio,path=/tmp/vtpm2/swtpm-sock &

Signed-off-by: Vikram Garhwal 
Signed-off-by: Stefano Stabellini 
Reviewed-by: Stefano Stabellini 
---
 docs/system/arm/xenpvh.rst|  34 +++
 docs/system/target-arm.rst|   1 +
 hw/arm/meson.build|   2 +
 hw/arm/xen_arm.c  | 182 ++
 include/hw/arm/xen_arch_hvm.h |   9 ++
 include/hw/xen/arch_hvm.h |   2 +
 6 files changed, 230 insertions(+)
 create mode 100644 docs/system/arm/xenpvh.rst
 create mode 100644 hw/arm/xen_arm.c
 create mode 100644 include/hw/arm/xen_arch_hvm.h

diff --git a/docs/system/arm/xenpvh.rst b/docs/system/arm/xenpvh.rst
new file mode 100644
index 00..e1655c7ab8
--- /dev/null
+++ b/docs/system/arm/xenpvh.rst
@@ -0,0 +1,34 @@
+XENPVH (``xenpvh``)
+=
+This machine creates a IOREQ server to register/connect with Xen Hypervisor.
+
+When TPM is enabled, this machine also creates a tpm-tis-device at a user input
+tpm base address, adds a TPM emulator and connects to a swtpm application
+running on host machine via chardev socket. This enables xenpvh to support TPM
+functionalities for a guest domain.
+
+More information about TPM use and installing swtpm linux application can be
+found at: docs/specs/tpm.rst.
+
+Example for starting swtpm on host machine:
+.. code-block:: console
+
+mkdir /tmp/vtpm2
+swtpm socket --tpmstate dir=/tmp/vtpm2 \
+--ctrl type=unixio,path=/tmp/vtpm2/swtpm-sock &
+
+Sample QEMU xenpvh commands for running and connecting with Xen:
+.. code-block:: console
+
+qemu-system-aarch64 -xen-domid 1 \
+-chardev socket,id=libxl-cmd,path=qmp-libxl-1,server=on,wait=off \
+-mon chardev=libxl-cmd,mode=control \
+-chardev socket,id=libxenstat-cmd,path=qmp-libxenstat-1,server=on,wait=off 
\
+-mon chardev=libxenstat-cmd,mode=control \
+-xen-attach -name guest0 -vnc none -display none -nographic \
+-machine xenpvh -m 1301 \
+-chardev socket,id=chrtpm,path=tmp/vtpm2/swtpm-sock \
+-tpmdev emulator,id=tpm0,chardev=chrtpm -machine tpm-base-addr=0x0C00
+
+In above QEMU command, last two lines are for connecting xenpvh QEMU to swtpm
+via chardev socket.
diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst
index 91ebc26c6d..af8d7c77d6 100644
--- a/docs/system/target-arm.rst
+++ b/docs/system/target-arm.rst
@@ -106,6 +106,7 @@ undocumented; you can get a complete list by running
arm/stm32
arm/virt
arm/xlnx-versal-virt
+   arm/xenpvh
 
 Emulated CPU architecture support
 =
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
index b545ba0e4f..1b2a01a005 100644
--- a/hw/arm/meson.build
+++ b/hw/arm/meson.build
@@ -62,6 +62,8 @@ arm_ss.add(when: 'CONFIG_FSL_IMX7', if_true: 
files('fsl-imx7.c', 'mcimx7d-sabre.
 arm_ss.add(when: 'CONFIG_ARM_SMMUV3', if_true: files('smmuv3.c'))
 arm_ss.add(when: 'CONFIG_FSL_IMX6UL', if_true: files('fsl-imx6ul.c', 
'mcimx6ul-evk.c'))
 arm_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_soc.c'))
+arm_ss.add(when: 'CONFIG_XEN', if_true: files('xen_arm.c'))
+arm_ss.add_all(xen_ss)
 
 softmmu_ss.add(when: 'CONFIG_ARM_SMMUV3', if_true: files('smmu-common.c'))
 softmmu_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4_boards.c'))
diff --git a/hw/arm/xen_arm.c b/hw/arm/xen_arm.c
new file mode 100644
index 00..eaca65af37
--- /dev/null
+++ b/hw/arm/xen_arm.c
@@ -0,0 +1,182 @@
+/*
+ * QEMU ARM Xen PVH Machine
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 

[PULL v2 05/10] include/hw/xen/xen_common: return error from xen_create_ioreq_server

2023-02-14 Thread Stefano Stabellini
From: Stefano Stabellini 

This is done to prepare for enabling xenpv support for ARM architecture.
On ARM it is possible to have a functioning xenpv machine with only the
PV backends and no IOREQ server. If the IOREQ server creation fails,
continue to the PV backends initialization.

Signed-off-by: Stefano Stabellini 
Signed-off-by: Vikram Garhwal 
Reviewed-by: Stefano Stabellini 
Reviewed-by: Paul Durrant 
---
 include/hw/xen/xen_common.h | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/include/hw/xen/xen_common.h b/include/hw/xen/xen_common.h
index 9a13a756ae..9ec69582b3 100644
--- a/include/hw/xen/xen_common.h
+++ b/include/hw/xen/xen_common.h
@@ -467,9 +467,10 @@ static inline void xen_unmap_pcidev(domid_t dom,
 {
 }
 
-static inline void xen_create_ioreq_server(domid_t dom,
-   ioservid_t *ioservid)
+static inline int xen_create_ioreq_server(domid_t dom,
+  ioservid_t *ioservid)
 {
+return 0;
 }
 
 static inline void xen_destroy_ioreq_server(domid_t dom,
@@ -600,8 +601,8 @@ static inline void xen_unmap_pcidev(domid_t dom,
   PCI_FUNC(pci_dev->devfn));
 }
 
-static inline void xen_create_ioreq_server(domid_t dom,
-   ioservid_t *ioservid)
+static inline int xen_create_ioreq_server(domid_t dom,
+  ioservid_t *ioservid)
 {
 int rc = xendevicemodel_create_ioreq_server(xen_dmod, dom,
 HVM_IOREQSRV_BUFIOREQ_ATOMIC,
@@ -609,12 +610,14 @@ static inline void xen_create_ioreq_server(domid_t dom,
 
 if (rc == 0) {
 trace_xen_ioreq_server_create(*ioservid);
-return;
+return rc;
 }
 
 *ioservid = 0;
 use_default_ioreq_server = true;
 trace_xen_default_ioreq_server();
+
+return rc;
 }
 
 static inline void xen_destroy_ioreq_server(domid_t dom,
-- 
2.25.1




[PULL v2 07/10] hw/xen/xen-hvm-common: Use g_new and error_report

2023-02-14 Thread Stefano Stabellini
From: Vikram Garhwal 

Replace g_malloc with g_new and perror with error_report.

Signed-off-by: Vikram Garhwal 
Reviewed-by: Stefano Stabellini 
Reviewed-by: Paul Durrant 
---
 hw/xen/xen-hvm-common.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/hw/xen/xen-hvm-common.c b/hw/xen/xen-hvm-common.c
index 5e3c7b073f..077c8dae5b 100644
--- a/hw/xen/xen-hvm-common.c
+++ b/hw/xen/xen-hvm-common.c
@@ -34,7 +34,7 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, 
MemoryRegion *mr,
 trace_xen_ram_alloc(ram_addr, size);
 
 nr_pfn = size >> TARGET_PAGE_BITS;
-pfn_list = g_malloc(sizeof (*pfn_list) * nr_pfn);
+pfn_list = g_new(xen_pfn_t, nr_pfn);
 
 for (i = 0; i < nr_pfn; i++) {
 pfn_list[i] = (ram_addr >> TARGET_PAGE_BITS) + i;
@@ -731,7 +731,7 @@ void destroy_hvm_domain(bool reboot)
 return;
 }
 if (errno != ENOTTY /* old Xen */) {
-perror("xendevicemodel_shutdown failed");
+error_report("xendevicemodel_shutdown failed with error %d", 
errno);
 }
 /* well, try the old thing then */
 }
@@ -801,7 +801,7 @@ static void xen_do_ioreq_register(XenIOState *state,
 }
 
 /* Note: cpus is empty at this point in init */
-state->cpu_by_vcpu_id = g_malloc0(max_cpus * sizeof(CPUState *));
+state->cpu_by_vcpu_id = g_new0(CPUState *, max_cpus);
 
 rc = xen_set_ioreq_server_state(xen_domid, state->ioservid, true);
 if (rc < 0) {
@@ -810,7 +810,7 @@ static void xen_do_ioreq_register(XenIOState *state,
 goto err;
 }
 
-state->ioreq_local_port = g_malloc0(max_cpus * sizeof (evtchn_port_t));
+state->ioreq_local_port = g_new0(evtchn_port_t, max_cpus);
 
 /* FIXME: how about if we overflow the page here? */
 for (i = 0; i < max_cpus; i++) {
@@ -864,13 +864,13 @@ void xen_register_ioreq(XenIOState *state, unsigned int 
max_cpus,
 
 state->xce_handle = xenevtchn_open(NULL, 0);
 if (state->xce_handle == NULL) {
-perror("xen: event channel open");
+error_report("xen: event channel open failed with error %d", errno);
 goto err;
 }
 
 state->xenstore = xs_daemon_open();
 if (state->xenstore == NULL) {
-perror("xen: xenstore open");
+error_report("xen: xenstore open failed with error %d", errno);
 goto err;
 }
 
-- 
2.25.1




[PULL v2 02/10] hw/i386/xen: rearrange xen_hvm_init_pc

2023-02-14 Thread Stefano Stabellini
From: Vikram Garhwal 

In preparation to moving most of xen-hvm code to an arch-neutral location,
move non IOREQ references to:
- xen_get_vmport_regs_pfn
- xen_suspend_notifier
- xen_wakeup_notifier
- xen_ram_init

towards the end of the xen_hvm_init_pc() function.

This is done to keep the common ioreq functions in one place which will be
moved to new function in next patch in order to make it common to both x86 and
aarch64 machines.

Signed-off-by: Vikram Garhwal 
Signed-off-by: Stefano Stabellini 
Reviewed-by: Paul Durrant 
---
 hw/i386/xen/xen-hvm.c | 49 ++-
 1 file changed, 25 insertions(+), 24 deletions(-)

diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
index b9a6f7f538..1fba0e0ae1 100644
--- a/hw/i386/xen/xen-hvm.c
+++ b/hw/i386/xen/xen-hvm.c
@@ -1416,12 +1416,6 @@ void xen_hvm_init_pc(PCMachineState *pcms, MemoryRegion 
**ram_memory)
 state->exit.notify = xen_exit_notifier;
 qemu_add_exit_notifier(>exit);
 
-state->suspend.notify = xen_suspend_notifier;
-qemu_register_suspend_notifier(>suspend);
-
-state->wakeup.notify = xen_wakeup_notifier;
-qemu_register_wakeup_notifier(>wakeup);
-
 /*
  * Register wake-up support in QMP query-current-machine API
  */
@@ -1432,23 +1426,6 @@ void xen_hvm_init_pc(PCMachineState *pcms, MemoryRegion 
**ram_memory)
 goto err;
 }
 
-rc = xen_get_vmport_regs_pfn(xen_xc, xen_domid, _pfn);
-if (!rc) {
-DPRINTF("shared vmport page at pfn %lx\n", ioreq_pfn);
-state->shared_vmport_page =
-xenforeignmemory_map(xen_fmem, xen_domid, PROT_READ|PROT_WRITE,
- 1, _pfn, NULL);
-if (state->shared_vmport_page == NULL) {
-error_report("map shared vmport IO page returned error %d 
handle=%p",
- errno, xen_xc);
-goto err;
-}
-} else if (rc != -ENOSYS) {
-error_report("get vmport regs pfn returned error %d, rc=%d",
- errno, rc);
-goto err;
-}
-
 /* Note: cpus is empty at this point in init */
 state->cpu_by_vcpu_id = g_new0(CPUState *, max_cpus);
 
@@ -1486,7 +1463,6 @@ void xen_hvm_init_pc(PCMachineState *pcms, MemoryRegion 
**ram_memory)
 #else
 xen_map_cache_init(NULL, state);
 #endif
-xen_ram_init(pcms, ms->ram_size, ram_memory);
 
 qemu_add_vm_change_state_handler(xen_hvm_change_state_handler, state);
 
@@ -1513,6 +1489,31 @@ void xen_hvm_init_pc(PCMachineState *pcms, MemoryRegion 
**ram_memory)
 QLIST_INIT(_physmap);
 xen_read_physmap(state);
 
+state->suspend.notify = xen_suspend_notifier;
+qemu_register_suspend_notifier(>suspend);
+
+state->wakeup.notify = xen_wakeup_notifier;
+qemu_register_wakeup_notifier(>wakeup);
+
+rc = xen_get_vmport_regs_pfn(xen_xc, xen_domid, _pfn);
+if (!rc) {
+DPRINTF("shared vmport page at pfn %lx\n", ioreq_pfn);
+state->shared_vmport_page =
+xenforeignmemory_map(xen_fmem, xen_domid, PROT_READ|PROT_WRITE,
+ 1, _pfn, NULL);
+if (state->shared_vmport_page == NULL) {
+error_report("map shared vmport IO page returned error %d 
handle=%p",
+ errno, xen_xc);
+goto err;
+}
+} else if (rc != -ENOSYS) {
+error_report("get vmport regs pfn returned error %d, rc=%d",
+ errno, rc);
+goto err;
+}
+
+xen_ram_init(pcms, ms->ram_size, ram_memory);
+
 /* Disable ACPI build because Xen handles it */
 pcms->acpi_build_enabled = false;
 
-- 
2.25.1




[PULL v2 01/10] hw/i386/xen/: move xen-mapcache.c to hw/xen/

2023-02-14 Thread Stefano Stabellini
From: Vikram Garhwal 

xen-mapcache.c contains common functions which can be used for enabling Xen on
aarch64 with IOREQ handling. Moving it out from hw/i386/xen to hw/xen to make it
accessible for both aarch64 and x86.

Signed-off-by: Vikram Garhwal 
Signed-off-by: Stefano Stabellini 
Reviewed-by: Paul Durrant 
---
 hw/i386/meson.build  | 1 +
 hw/i386/xen/meson.build  | 1 -
 hw/i386/xen/trace-events | 5 -
 hw/xen/meson.build   | 4 
 hw/xen/trace-events  | 5 +
 hw/{i386 => }/xen/xen-mapcache.c | 0
 6 files changed, 10 insertions(+), 6 deletions(-)
 rename hw/{i386 => }/xen/xen-mapcache.c (100%)

diff --git a/hw/i386/meson.build b/hw/i386/meson.build
index 213e2e82b3..cfdbfdcbcb 100644
--- a/hw/i386/meson.build
+++ b/hw/i386/meson.build
@@ -33,5 +33,6 @@ subdir('kvm')
 subdir('xen')
 
 i386_ss.add_all(xenpv_ss)
+i386_ss.add_all(xen_ss)
 
 hw_arch += {'i386': i386_ss}
diff --git a/hw/i386/xen/meson.build b/hw/i386/xen/meson.build
index be84130300..2fcc46e6ca 100644
--- a/hw/i386/xen/meson.build
+++ b/hw/i386/xen/meson.build
@@ -1,6 +1,5 @@
 i386_ss.add(when: 'CONFIG_XEN', if_true: files(
   'xen-hvm.c',
-  'xen-mapcache.c',
   'xen_apic.c',
   'xen_platform.c',
   'xen_pvdevice.c',
diff --git a/hw/i386/xen/trace-events b/hw/i386/xen/trace-events
index 5d6be61090..a0c89d91c4 100644
--- a/hw/i386/xen/trace-events
+++ b/hw/i386/xen/trace-events
@@ -21,8 +21,3 @@ xen_map_resource_ioreq(uint32_t id, void *addr) "id: %u addr: 
%p"
 cpu_ioreq_config_read(void *req, uint32_t sbdf, uint32_t reg, uint32_t size, 
uint32_t data) "I/O=%p sbdf=0x%x reg=%u size=%u data=0x%x"
 cpu_ioreq_config_write(void *req, uint32_t sbdf, uint32_t reg, uint32_t size, 
uint32_t data) "I/O=%p sbdf=0x%x reg=%u size=%u data=0x%x"
 
-# xen-mapcache.c
-xen_map_cache(uint64_t phys_addr) "want 0x%"PRIx64
-xen_remap_bucket(uint64_t index) "index 0x%"PRIx64
-xen_map_cache_return(void* ptr) "%p"
-
diff --git a/hw/xen/meson.build b/hw/xen/meson.build
index ae0ace3046..19d0637c46 100644
--- a/hw/xen/meson.build
+++ b/hw/xen/meson.build
@@ -22,3 +22,7 @@ else
 endif
 
 specific_ss.add_all(when: ['CONFIG_XEN', xen], if_true: xen_specific_ss)
+
+xen_ss = ss.source_set()
+
+xen_ss.add(when: 'CONFIG_XEN', if_true: files('xen-mapcache.c'))
diff --git a/hw/xen/trace-events b/hw/xen/trace-events
index 3da3fd8348..2c8f238f42 100644
--- a/hw/xen/trace-events
+++ b/hw/xen/trace-events
@@ -41,3 +41,8 @@ xs_node_vprintf(char *path, char *value) "%s %s"
 xs_node_vscanf(char *path, char *value) "%s %s"
 xs_node_watch(char *path) "%s"
 xs_node_unwatch(char *path) "%s"
+
+# xen-mapcache.c
+xen_map_cache(uint64_t phys_addr) "want 0x%"PRIx64
+xen_remap_bucket(uint64_t index) "index 0x%"PRIx64
+xen_map_cache_return(void* ptr) "%p"
diff --git a/hw/i386/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
similarity index 100%
rename from hw/i386/xen/xen-mapcache.c
rename to hw/xen/xen-mapcache.c
-- 
2.25.1




[PULL v2 04/10] xen-hvm: reorganize xen-hvm and move common function to xen-hvm-common

2023-02-14 Thread Stefano Stabellini
From: Stefano Stabellini 

This patch does following:
1. creates arch_handle_ioreq() and arch_xen_set_memory(). This is done in
preparation for moving most of xen-hvm code to an arch-neutral location,
move the x86-specific portion of xen_set_memory to arch_xen_set_memory.
Also, move handle_vmport_ioreq to arch_handle_ioreq.

2. Pure code movement: move common functions to hw/xen/xen-hvm-common.c
Extract common functionalities from hw/i386/xen/xen-hvm.c and move them to
hw/xen/xen-hvm-common.c. These common functions are useful for creating
an IOREQ server.

xen_hvm_init_pc() contains the architecture independent code for creating
and mapping a IOREQ server, connecting memory and IO listeners, initializing
a xen bus and registering backends. Moved this common xen code to a new
function xen_register_ioreq() which can be used by both x86 and ARM 
machines.

Following functions are moved to hw/xen/xen-hvm-common.c:
xen_vcpu_eport(), xen_vcpu_ioreq(), xen_ram_alloc(), xen_set_memory(),
xen_region_add(), xen_region_del(), xen_io_add(), xen_io_del(),
xen_device_realize(), xen_device_unrealize(),
cpu_get_ioreq_from_shared_memory(), cpu_get_ioreq(), do_inp(),
do_outp(), rw_phys_req_item(), read_phys_req_item(),
write_phys_req_item(), cpu_ioreq_pio(), cpu_ioreq_move(),
cpu_ioreq_config(), handle_ioreq(), handle_buffered_iopage(),
handle_buffered_io(), cpu_handle_ioreq(), xen_main_loop_prepare(),
xen_hvm_change_state_handler(), xen_exit_notifier(),
xen_map_ioreq_server(), destroy_hvm_domain() and
xen_shutdown_fatal_error()

3. Removed static type from below functions:
1. xen_region_add()
2. xen_region_del()
3. xen_io_add()
4. xen_io_del()
5. xen_device_realize()
6. xen_device_unrealize()
7. xen_hvm_change_state_handler()
8. cpu_ioreq_pio()
9. xen_exit_notifier()

4. Replace TARGET_PAGE_SIZE with XC_PAGE_SIZE to match the page side with Xen.

Signed-off-by: Vikram Garhwal 
Signed-off-by: Stefano Stabellini 
Reviewed-by: Stefano Stabellini 
Reviewed-by: Paul Durrant 
---
 hw/i386/xen/trace-events|   14 -
 hw/i386/xen/xen-hvm.c   | 1019 ++-
 hw/xen/meson.build  |5 +-
 hw/xen/trace-events |   14 +
 hw/xen/xen-hvm-common.c |  874 ++
 include/hw/i386/xen_arch_hvm.h  |   11 +
 include/hw/xen/arch_hvm.h   |3 +
 include/hw/xen/xen-hvm-common.h |   98 +++
 8 files changed, 1067 insertions(+), 971 deletions(-)
 create mode 100644 hw/xen/xen-hvm-common.c
 create mode 100644 include/hw/i386/xen_arch_hvm.h
 create mode 100644 include/hw/xen/arch_hvm.h
 create mode 100644 include/hw/xen/xen-hvm-common.h

diff --git a/hw/i386/xen/trace-events b/hw/i386/xen/trace-events
index a0c89d91c4..5d0a8d6dcf 100644
--- a/hw/i386/xen/trace-events
+++ b/hw/i386/xen/trace-events
@@ -7,17 +7,3 @@ xen_platform_log(char *s) "xen platform: %s"
 xen_pv_mmio_read(uint64_t addr) "WARNING: read from Xen PV Device MMIO space 
(address 0x%"PRIx64")"
 xen_pv_mmio_write(uint64_t addr) "WARNING: write to Xen PV Device MMIO space 
(address 0x%"PRIx64")"
 
-# xen-hvm.c
-xen_ram_alloc(unsigned long ram_addr, unsigned long size) "requested: 0x%lx, 
size 0x%lx"
-xen_client_set_memory(uint64_t start_addr, unsigned long size, bool log_dirty) 
"0x%"PRIx64" size 0x%lx, log_dirty %i"
-handle_ioreq(void *req, uint32_t type, uint32_t dir, uint32_t df, uint32_t 
data_is_ptr, uint64_t addr, uint64_t data, uint32_t count, uint32_t size) 
"I/O=%p type=%d dir=%d df=%d ptr=%d port=0x%"PRIx64" data=0x%"PRIx64" count=%d 
size=%d"
-handle_ioreq_read(void *req, uint32_t type, uint32_t df, uint32_t data_is_ptr, 
uint64_t addr, uint64_t data, uint32_t count, uint32_t size) "I/O=%p read 
type=%d df=%d ptr=%d port=0x%"PRIx64" data=0x%"PRIx64" count=%d size=%d"
-handle_ioreq_write(void *req, uint32_t type, uint32_t df, uint32_t 
data_is_ptr, uint64_t addr, uint64_t data, uint32_t count, uint32_t size) 
"I/O=%p write type=%d df=%d ptr=%d port=0x%"PRIx64" data=0x%"PRIx64" count=%d 
size=%d"
-cpu_ioreq_pio(void *req, uint32_t dir, uint32_t df, uint32_t data_is_ptr, 
uint64_t addr, uint64_t data, uint32_t count, uint32_t size) "I/O=%p pio dir=%d 
df=%d ptr=%d port=0x%"PRIx64" data=0x%"PRIx64" count=%d size=%d"
-cpu_ioreq_pio_read_reg(void *req, uint64_t data, uint64_t addr, uint32_t size) 
"I/O=%p pio read reg data=0x%"PRIx64" port=0x%"PRIx64" size=%d"
-cpu_ioreq_pio_write_reg(void *req, uint64_t data, uint64_t addr, uint32_t 
size) "I/O=%p pio write reg data=0x%"PRIx64" port=0x%"PRIx64" size=%d"
-cpu_ioreq_move(void *req, uint32_t dir, uint32_t df, uint32_t data_is_ptr, 
uint64_t addr, uint64_t data, uint32_t count, uint32_t size) "I/O=%p copy 
dir=%d df=%d ptr=%d port=0x%"PRIx64" data=0x%"PRIx64" count=%d size=%d"
-xen_map_resource_ioreq(uint32_t id, void *addr) "id: %u addr: %p"
-cpu_ioreq_config_read(void 

[PULL v2 10/10] meson.build: enable xenpv machine build for ARM

2023-02-14 Thread Stefano Stabellini
From: Vikram Garhwal 

Add CONFIG_XEN for aarch64 device to support build for ARM targets.

Signed-off-by: Vikram Garhwal 
Signed-off-by: Stefano Stabellini 
Reviewed-by: Alex Bennée 
---
 meson.build | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/meson.build b/meson.build
index 8292cdcec5..3f08bceba0 100644
--- a/meson.build
+++ b/meson.build
@@ -135,7 +135,7 @@ endif
 if cpu in ['x86', 'x86_64', 'arm', 'aarch64']
   # i386 emulator provides xenpv machine type for multiple architectures
   accelerator_targets += {
-'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
+'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu', 'aarch64-softmmu'],
   }
 endif
 if cpu in ['x86', 'x86_64']
-- 
2.25.1




[PULL v2 06/10] hw/xen/xen-hvm-common: skip ioreq creation on ioreq registration failure

2023-02-14 Thread Stefano Stabellini
From: Stefano Stabellini 

On ARM it is possible to have a functioning xenpv machine with only the
PV backends and no IOREQ server. If the IOREQ server creation fails continue
to the PV backends initialization.

Also, moved the IOREQ registration and mapping subroutine to new function
xen_do_ioreq_register().

Signed-off-by: Stefano Stabellini 
Signed-off-by: Vikram Garhwal 
Reviewed-by: Stefano Stabellini 
Reviewed-by: Paul Durrant 
---
 hw/xen/xen-hvm-common.c | 53 -
 1 file changed, 36 insertions(+), 17 deletions(-)

diff --git a/hw/xen/xen-hvm-common.c b/hw/xen/xen-hvm-common.c
index c2e1e08124..5e3c7b073f 100644
--- a/hw/xen/xen-hvm-common.c
+++ b/hw/xen/xen-hvm-common.c
@@ -781,25 +781,12 @@ err:
 exit(1);
 }
 
-void xen_register_ioreq(XenIOState *state, unsigned int max_cpus,
-MemoryListener xen_memory_listener)
+static void xen_do_ioreq_register(XenIOState *state,
+   unsigned int max_cpus,
+   MemoryListener xen_memory_listener)
 {
 int i, rc;
 
-state->xce_handle = xenevtchn_open(NULL, 0);
-if (state->xce_handle == NULL) {
-perror("xen: event channel open");
-goto err;
-}
-
-state->xenstore = xs_daemon_open();
-if (state->xenstore == NULL) {
-perror("xen: xenstore open");
-goto err;
-}
-
-xen_create_ioreq_server(xen_domid, >ioservid);
-
 state->exit.notify = xen_exit_notifier;
 qemu_add_exit_notifier(>exit);
 
@@ -863,12 +850,44 @@ void xen_register_ioreq(XenIOState *state, unsigned int 
max_cpus,
 QLIST_INIT(>dev_list);
 device_listener_register(>device_listener);
 
+return;
+
+err:
+error_report("xen hardware virtual machine initialisation failed");
+exit(1);
+}
+
+void xen_register_ioreq(XenIOState *state, unsigned int max_cpus,
+MemoryListener xen_memory_listener)
+{
+int rc;
+
+state->xce_handle = xenevtchn_open(NULL, 0);
+if (state->xce_handle == NULL) {
+perror("xen: event channel open");
+goto err;
+}
+
+state->xenstore = xs_daemon_open();
+if (state->xenstore == NULL) {
+perror("xen: xenstore open");
+goto err;
+}
+
+rc = xen_create_ioreq_server(xen_domid, >ioservid);
+if (!rc) {
+xen_do_ioreq_register(state, max_cpus, xen_memory_listener);
+} else {
+warn_report("xen: failed to create ioreq server");
+}
+
 xen_bus_init();
 
 xen_register_backend(state);
 
 return;
+
 err:
-error_report("xen hardware virtual machine initialisation failed");
+error_report("xen hardware virtual machine backend registration failed");
 exit(1);
 }
-- 
2.25.1




[PULL v2 08/10] meson.build: do not set have_xen_pci_passthrough for aarch64 targets

2023-02-14 Thread Stefano Stabellini
From: Stefano Stabellini 

have_xen_pci_passthrough is only used for Xen x86 VMs.

Signed-off-by: Stefano Stabellini 
Reviewed-by: Alex Bennée 
---
 meson.build | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/meson.build b/meson.build
index a76c855312..8292cdcec5 100644
--- a/meson.build
+++ b/meson.build
@@ -1471,6 +1471,8 @@ have_xen_pci_passthrough = 
get_option('xen_pci_passthrough') \
error_message: 'Xen PCI passthrough requested but Xen not enabled') 
\
   .require(targetos == 'linux',
error_message: 'Xen PCI passthrough not available on this 
platform') \
+  .require(cpu == 'x86'  or cpu == 'x86_64',
+   error_message: 'Xen PCI passthrough not available on this 
platform') \
   .allowed()
 
 
-- 
2.25.1




[PULL v2 0/10] xenpvh

2023-02-14 Thread Stefano Stabellini
The following changes since commit 6a50f64ca01d0a7b97f14f069762bfd88160f31e:

  Merge tag 'pull-request-2023-02-14' of https://gitlab.com/thuth/qemu into 
staging (2023-02-14 14:46:10 +)

are available in the Git repository at:

  https://gitlab.com/sstabellini/qemu xenpvh2

for you to fetch changes up to 86b01d58ca2840bea6e4e7260aad450a660fbd46:

  meson.build: enable xenpv machine build for ARM (2023-02-14 15:39:25 -0800)


Stefano Stabellini (5):
  hw/i386/xen/xen-hvm: move x86-specific fields out of XenIOState
  xen-hvm: reorganize xen-hvm and move common function to xen-hvm-common
  include/hw/xen/xen_common: return error from xen_create_ioreq_server
  hw/xen/xen-hvm-common: skip ioreq creation on ioreq registration failure
  meson.build: do not set have_xen_pci_passthrough for aarch64 targets

Vikram Garhwal (5):
  hw/i386/xen/: move xen-mapcache.c to hw/xen/
  hw/i386/xen: rearrange xen_hvm_init_pc
  hw/xen/xen-hvm-common: Use g_new and error_report
  hw/arm: introduce xenpvh machine
  meson.build: enable xenpv machine build for ARM

 docs/system/arm/xenpvh.rst   |   34 ++
 docs/system/target-arm.rst   |1 +
 hw/arm/meson.build   |2 +
 hw/arm/xen_arm.c |  182 +++
 hw/i386/meson.build  |1 +
 hw/i386/xen/meson.build  |1 -
 hw/i386/xen/trace-events |   19 -
 hw/i386/xen/xen-hvm.c| 1078 --
 hw/xen/meson.build   |7 +
 hw/xen/trace-events  |   19 +
 hw/xen/xen-hvm-common.c  |  893 +++
 hw/{i386 => }/xen/xen-mapcache.c |0
 include/hw/arm/xen_arch_hvm.h|9 +
 include/hw/i386/xen_arch_hvm.h   |   11 +
 include/hw/xen/arch_hvm.h|5 +
 include/hw/xen/xen-hvm-common.h  |   98 
 include/hw/xen/xen_common.h  |   13 +-
 meson.build  |4 +-
 18 files changed, 1364 insertions(+), 1013 deletions(-)
 create mode 100644 docs/system/arm/xenpvh.rst
 create mode 100644 hw/arm/xen_arm.c
 create mode 100644 hw/xen/xen-hvm-common.c
 rename hw/{i386 => }/xen/xen-mapcache.c (100%)
 create mode 100644 include/hw/arm/xen_arch_hvm.h
 create mode 100644 include/hw/i386/xen_arch_hvm.h
 create mode 100644 include/hw/xen/arch_hvm.h
 create mode 100644 include/hw/xen/xen-hvm-common.h



[PULL v2 03/10] hw/i386/xen/xen-hvm: move x86-specific fields out of XenIOState

2023-02-14 Thread Stefano Stabellini
From: Stefano Stabellini 

In preparation to moving most of xen-hvm code to an arch-neutral location, move:
- shared_vmport_page
- log_for_dirtybit
- dirty_bitmap
- suspend
- wakeup

out of XenIOState struct as these are only used on x86, especially the ones
related to dirty logging.
Updated XenIOState can be used for both aarch64 and x86.

Also, remove free_phys_offset as it was unused.

Signed-off-by: Stefano Stabellini 
Signed-off-by: Vikram Garhwal 
Reviewed-by: Paul Durrant 
Reviewed-by: Alex Bennée 
---
 hw/i386/xen/xen-hvm.c | 58 ---
 1 file changed, 27 insertions(+), 31 deletions(-)

diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
index 1fba0e0ae1..06c446e7be 100644
--- a/hw/i386/xen/xen-hvm.c
+++ b/hw/i386/xen/xen-hvm.c
@@ -73,6 +73,7 @@ struct shared_vmport_iopage {
 };
 typedef struct shared_vmport_iopage shared_vmport_iopage_t;
 #endif
+static shared_vmport_iopage_t *shared_vmport_page;
 
 static inline uint32_t xen_vcpu_eport(shared_iopage_t *shared_page, int i)
 {
@@ -95,6 +96,11 @@ typedef struct XenPhysmap {
 } XenPhysmap;
 
 static QLIST_HEAD(, XenPhysmap) xen_physmap;
+static const XenPhysmap *log_for_dirtybit;
+/* Buffer used by xen_sync_dirty_bitmap */
+static unsigned long *dirty_bitmap;
+static Notifier suspend;
+static Notifier wakeup;
 
 typedef struct XenPciDevice {
 PCIDevice *pci_dev;
@@ -105,7 +111,6 @@ typedef struct XenPciDevice {
 typedef struct XenIOState {
 ioservid_t ioservid;
 shared_iopage_t *shared_page;
-shared_vmport_iopage_t *shared_vmport_page;
 buffered_iopage_t *buffered_io_page;
 xenforeignmemory_resource_handle *fres;
 QEMUTimer *buffered_io_timer;
@@ -125,14 +130,8 @@ typedef struct XenIOState {
 MemoryListener io_listener;
 QLIST_HEAD(, XenPciDevice) dev_list;
 DeviceListener device_listener;
-hwaddr free_phys_offset;
-const XenPhysmap *log_for_dirtybit;
-/* Buffer used by xen_sync_dirty_bitmap */
-unsigned long *dirty_bitmap;
 
 Notifier exit;
-Notifier suspend;
-Notifier wakeup;
 } XenIOState;
 
 /* Xen specific function for piix pci */
@@ -462,10 +461,10 @@ static int xen_remove_from_physmap(XenIOState *state,
 }
 
 QLIST_REMOVE(physmap, list);
-if (state->log_for_dirtybit == physmap) {
-state->log_for_dirtybit = NULL;
-g_free(state->dirty_bitmap);
-state->dirty_bitmap = NULL;
+if (log_for_dirtybit == physmap) {
+log_for_dirtybit = NULL;
+g_free(dirty_bitmap);
+dirty_bitmap = NULL;
 }
 g_free(physmap);
 
@@ -626,16 +625,16 @@ static void xen_sync_dirty_bitmap(XenIOState *state,
 return;
 }
 
-if (state->log_for_dirtybit == NULL) {
-state->log_for_dirtybit = physmap;
-state->dirty_bitmap = g_new(unsigned long, bitmap_size);
-} else if (state->log_for_dirtybit != physmap) {
+if (log_for_dirtybit == NULL) {
+log_for_dirtybit = physmap;
+dirty_bitmap = g_new(unsigned long, bitmap_size);
+} else if (log_for_dirtybit != physmap) {
 /* Only one range for dirty bitmap can be tracked. */
 return;
 }
 
 rc = xen_track_dirty_vram(xen_domid, start_addr >> TARGET_PAGE_BITS,
-  npages, state->dirty_bitmap);
+  npages, dirty_bitmap);
 if (rc < 0) {
 #ifndef ENODATA
 #define ENODATA  ENOENT
@@ -650,7 +649,7 @@ static void xen_sync_dirty_bitmap(XenIOState *state,
 }
 
 for (i = 0; i < bitmap_size; i++) {
-unsigned long map = state->dirty_bitmap[i];
+unsigned long map = dirty_bitmap[i];
 while (map != 0) {
 j = ctzl(map);
 map &= ~(1ul << j);
@@ -676,12 +675,10 @@ static void xen_log_start(MemoryListener *listener,
 static void xen_log_stop(MemoryListener *listener, MemoryRegionSection 
*section,
  int old, int new)
 {
-XenIOState *state = container_of(listener, XenIOState, memory_listener);
-
 if (old & ~new & (1 << DIRTY_MEMORY_VGA)) {
-state->log_for_dirtybit = NULL;
-g_free(state->dirty_bitmap);
-state->dirty_bitmap = NULL;
+log_for_dirtybit = NULL;
+g_free(dirty_bitmap);
+dirty_bitmap = NULL;
 /* Disable dirty bit tracking */
 xen_track_dirty_vram(xen_domid, 0, 0, NULL);
 }
@@ -1021,9 +1018,9 @@ static void handle_vmport_ioreq(XenIOState *state, 
ioreq_t *req)
 {
 vmware_regs_t *vmport_regs;
 
-assert(state->shared_vmport_page);
+assert(shared_vmport_page);
 vmport_regs =
->shared_vmport_page->vcpu_vmport_regs[state->send_vcpu];
+_vmport_page->vcpu_vmport_regs[state->send_vcpu];
 QEMU_BUILD_BUG_ON(sizeof(*req) < sizeof(*vmport_regs));
 
 current_cpu = state->cpu_by_vcpu_id[state->send_vcpu];
@@ -1468,7 +1465,6 @@ void xen_hvm_init_pc(PCMachineState *pcms, MemoryRegion 
**ram_memory)
 
 state->memory_listener = xen_memory_listener;
 

Re: [PATCH 05/14] target/arm: Simplify register counting in arm_gen_dynamic_svereg_xml

2023-02-14 Thread Richard Henderson

On 2/14/23 09:42, Fabiano Rosas wrote:

@@ -310,8 +313,8 @@ int arm_gen_dynamic_svereg_xml(CPUState *cs, int base_reg)
  g_string_append_printf(s, "", base_reg++);
-info->num += 2;
  
+/* Define the predicate registers. */

  for (i = 0; i < 16; i++) {


There's a info->num++; at the end of this loop.


Good catch, thanks.


r~



Re: [PATCH v2 12/12] bsd-user: Add -strict

2023-02-14 Thread Richard Henderson

On 2/13/23 14:27, Warner Losh wrote:

Most of the time, it's useful to make our best effort, but sometimes we
want to know right away when we don't implement something. First place
we use it is for unknown syscalls.

Signed-off-by: Warner Losh 
---
  bsd-user/freebsd/os-syscall.c | 4 
  bsd-user/main.c   | 5 -
  bsd-user/qemu.h   | 1 +
  3 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/bsd-user/freebsd/os-syscall.c b/bsd-user/freebsd/os-syscall.c
index 179a20c304b..e2b26ecb8dd 100644
--- a/bsd-user/freebsd/os-syscall.c
+++ b/bsd-user/freebsd/os-syscall.c
@@ -508,6 +508,10 @@ static abi_long freebsd_syscall(void *cpu_env, int num, 
abi_long arg1,
  
  default:

  qemu_log_mask(LOG_UNIMP, "Unsupported syscall: %d\n", num);
+if (bsd_user_strict) {
+printf("Unimplemented system call %d\n", num);
+abort();
+}


Still don't like the printf.  I suggested alternatives against v1.

r~



Re: [PATCH v2 11/12] bsd-user: implement sysctlbyname(2)

2023-02-14 Thread Richard Henderson

On 2/13/23 14:27, Warner Losh wrote:

+oidplen = sizeof(oid) / sizeof(int);


ARRAY_SIZE(oid)

Otherwise,
Reviewed-by: Richard Henderson 


r~



Re: [PATCH v2 10/12] bsd-user: do_freebsd_sysctl helper for sysctl(2)

2023-02-14 Thread Richard Henderson

On 2/13/23 14:27, Warner Losh wrote:

+int32_t *snamep = g_malloc(sizeof(int32_t) * namelen), *p, *q, i;


g_new(int32_t, namelen)


+unlock_user(holdp, oldp, holdlen);
+unlock_user(holdp, oldp, ret == 0 ? holdlen : 0);


double-unlock.  clearly the first line is extra.

Otherwise,
Reviewed-by: Richard Henderson 


r~



Re: [PATCH v2 04/12] bsd-user: various helper routines for sysctl

2023-02-14 Thread Richard Henderson

On 2/14/23 11:31, Warner Losh wrote:

Right now they aren't used at all for ABI64...  But that's in later patches...  
We only do
special things for  LONG or ULONG on ABI32... Otherwise, the normal paths 
wouldn't
call these at all.


Yes, I've just seen patch 9, and agree they aren't needed for abi64.


r~



Re: [PATCH v2 09/12] bsd-user: Start translation of arch-specific sysctls

2023-02-14 Thread Richard Henderson

On 2/13/23 14:27, Warner Losh wrote:

+case HW_NCPU:
+if (oldlen) {
+(*(int32_t *)holdp) = tswap32(bsd_get_ncpu());
+}
+holdlen = sizeof(int32_t);
+ret = 0;
+goto out;


Anything using SYSCTL_INT should use abi_int.


+#if defined(TARGET_ARM)
+case HW_FLOATINGPT:
+if (oldlen) {
+ARMCPU *cpu = env_archcpu(env);
+*(abi_int *)holdp = cpu_isar_feature(aa32_vfp, cpu);
+}
+holdlen = sizeof(int32_t);


abi_int for consistency.

Otherwise,
Reviewed-by: Richard Henderson 


r~



Re: [PATCH v2 04/12] bsd-user: various helper routines for sysctl

2023-02-14 Thread Warner Losh
On Tue, Feb 14, 2023 at 1:52 PM Richard Henderson <
richard.hender...@linaro.org> wrote:

> On 2/13/23 14:27, Warner Losh wrote:
> > +#ifdef TARGET_ABI32
> > +/*
> > + * Limit the amount of available memory to be most of the 32-bit address
> > + * space. 0x100c000 was arrived at through trial and error as a good
> > + * definition of 'most'.
> > + */
> > +static const abi_ulong target_max_mem = UINT32_MAX - 0x100c000 + 1;
> > +
> > +static abi_ulong G_GNUC_UNUSED cap_memory(uint64_t mem)
> > +{
> > +if (((unsigned long)target_max_mem) < mem) {
> > +mem = target_max_mem;
> > +}
> > +
> > +return mem;
> > +}
> > +#endif
>
> Identity function for ABI64?
>

Indirectly, yes. For ABI64 we simply don't intercept these sysctl nodes.


> > +static unsigned long host_page_size;
> > +
> > +static abi_ulong G_GNUC_UNUSED scale_to_target_pages(uint64_t pages)
> > +{
> > +if (host_page_size == 0) {
> > +host_page_size = getpagesize();
> > +}
>
> qemu_real_host_page_size()
>

OK. Easy enough. That was a warning from checkpatch anyway that had slipped
my mind.


> > +
> > +pages = muldiv64(pages, host_page_size, TARGET_PAGE_SIZE);
> > +#ifdef TARGET_ABI32
> > +abi_ulong maxpages = target_max_mem / (abi_ulong)TARGET_PAGE_SIZE;
> > +
> > +if (((unsigned long)maxpages) < pages) {
> > +pages = maxpages;
> > +}
> > +#endif
>
> No need for either cast.  Just use MIN().
>

Gotcha.


> > +#ifdef TARGET_ABI32
> > +static abi_long G_GNUC_UNUSED h2t_long_sat(long l)
>
> h2g.
>

OK.


> > +{
> > +if (l > INT32_MAX) {
> > +l = INT32_MAX;
> > +} else if (l < INT32_MIN) {
> > +l = INT32_MIN;
> > +}
> > +return l;
> > +}
> > +
> > +static abi_ulong G_GNUC_UNUSED h2t_ulong_sat(u_long ul)
> > +{
> > +if (ul > UINT32_MAX) {
> > +ul = UINT32_MAX;
> > +}
> > +return ul;
> > +}
> > +#endif
>
> Anyway, identity functions for ABI64?
>

Right now they aren't used at all for ABI64...  But that's in later
patches...  We only do
special things for  LONG or ULONG on ABI32... Otherwise, the normal paths
wouldn't
call these at all.

Warner


Re: [PATCH 05/18] vfio/common: Add VFIOBitmap and (de)alloc functions

2023-02-14 Thread Alex Williamson
On Sun, 12 Feb 2023 17:36:49 +0200
Avihai Horon  wrote:

> On 27/01/2023 23:11, Alex Williamson wrote:
> > External email: Use caution opening links or attachments
> >
> >
> > On Thu, 26 Jan 2023 20:49:35 +0200
> > Avihai Horon  wrote:
> >  
> >> There are already two places where dirty page bitmap allocation and
> >> calculations are done in open code. With device dirty page tracking
> >> being added in next patches, there are going to be even more places.
> >>
> >> To avoid code duplication, introduce VFIOBitmap struct and corresponding
> >> alloc and dealloc functions and use them where applicable.
> >>
> >> Signed-off-by: Avihai Horon 
> >> ---
> >>   hw/vfio/common.c | 89 
> >>   1 file changed, 60 insertions(+), 29 deletions(-)
> >>
> >> diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> >> index 8e8ffbc046..e554573eb5 100644
> >> --- a/hw/vfio/common.c
> >> +++ b/hw/vfio/common.c
> >> @@ -319,6 +319,41 @@ const MemoryRegionOps vfio_region_ops = {
> >>* Device state interfaces
> >>*/
> >>
> >> +typedef struct {
> >> +unsigned long *bitmap;
> >> +hwaddr size;
> >> +hwaddr pages;
> >> +} VFIOBitmap;
> >> +
> >> +static VFIOBitmap *vfio_bitmap_alloc(hwaddr size)
> >> +{
> >> +VFIOBitmap *vbmap = g_try_new0(VFIOBitmap, 1);
> >> +if (!vbmap) {
> >> +errno = ENOMEM;
> >> +
> >> +return NULL;
> >> +}
> >> +
> >> +vbmap->pages = REAL_HOST_PAGE_ALIGN(size) / 
> >> qemu_real_host_page_size();
> >> +vbmap->size =  ROUND_UP(vbmap->pages, sizeof(__u64) * BITS_PER_BYTE) /
> >> +  BITS_PER_BYTE;
> >> +vbmap->bitmap = g_try_malloc0(vbmap->size);
> >> +if (!vbmap->bitmap) {
> >> +g_free(vbmap);
> >> +errno = ENOMEM;
> >> +
> >> +return NULL;
> >> +}
> >> +
> >> +return vbmap;
> >> +}
> >> +
> >> +static void vfio_bitmap_dealloc(VFIOBitmap *vbmap)
> >> +{
> >> +g_free(vbmap->bitmap);
> >> +g_free(vbmap);
> >> +}
> >> +
> >>   bool vfio_mig_active(void)
> >>   {
> >>   VFIOGroup *group;
> >> @@ -421,9 +456,14 @@ static int vfio_dma_unmap_bitmap(VFIOContainer 
> >> *container,
> >>   {
> >>   struct vfio_iommu_type1_dma_unmap *unmap;
> >>   struct vfio_bitmap *bitmap;
> >> -uint64_t pages = REAL_HOST_PAGE_ALIGN(size) / 
> >> qemu_real_host_page_size();
> >> +VFIOBitmap *vbmap;
> >>   int ret;
> >>
> >> +vbmap = vfio_bitmap_alloc(size);
> >> +if (!vbmap) {
> >> +return -errno;
> >> +}
> >> +
> >>   unmap = g_malloc0(sizeof(*unmap) + sizeof(*bitmap));
> >>
> >>   unmap->argsz = sizeof(*unmap) + sizeof(*bitmap);
> >> @@ -437,35 +477,28 @@ static int vfio_dma_unmap_bitmap(VFIOContainer 
> >> *container,
> >>* qemu_real_host_page_size to mark those dirty. Hence set 
> >> bitmap_pgsize
> >>* to qemu_real_host_page_size.
> >>*/
> >> -
> >>   bitmap->pgsize = qemu_real_host_page_size();
> >> -bitmap->size = ROUND_UP(pages, sizeof(__u64) * BITS_PER_BYTE) /
> >> -   BITS_PER_BYTE;
> >> +bitmap->size = vbmap->size;
> >> +bitmap->data = (__u64 *)vbmap->bitmap;
> >>
> >> -if (bitmap->size > container->max_dirty_bitmap_size) {
> >> -error_report("UNMAP: Size of bitmap too big 0x%"PRIx64,
> >> - (uint64_t)bitmap->size);
> >> +if (vbmap->size > container->max_dirty_bitmap_size) {
> >> +error_report("UNMAP: Size of bitmap too big 0x%"PRIx64, 
> >> vbmap->size);  
> > Why not pass the container to the alloc function so we can test this
> > consistently for each bitmap we allocate?  
> 
> Hi, sorry for the delay.
> 
> This test is relevant only for VFIO IOMMU dirty tracking. With device 
> dirty tracking it should be skipped.
> Do you think we should still move it to the alloc function?

Ah, ok.  Sounds like we'll have to live with a separate test for the
container path.  Thanks,

Alex




Re: [PATCH v2 08/12] bsd-user: common routine do_freebsd_sysctl_oid for all sysctl variants

2023-02-14 Thread Richard Henderson

On 2/13/23 14:27, Warner Losh wrote:

From: Juergen Lock 

do_freebsd_sysctl_oid filters out some of the binary and special sysctls
where host != target. None of the sysctls that have to be translated from
host to target are handled here.

Signed-off-by: Juergen Lock 
Co-Authored-by: Stacey Son 
Signed-off-by: Stacey Son 
Co-Authored-by: Warner Losh 
Signed-off-by: Warner Losh 
---
  bsd-user/freebsd/os-sys.c | 90 +--
  1 file changed, 86 insertions(+), 4 deletions(-)


Reviewed-by: Richard Henderson 


r~



Re: [PATCH v2 07/12] bsd-user: sysctl helper funtions: sysctl_name2oid and sysctl_oidfmt

2023-02-14 Thread Richard Henderson

On 2/13/23 14:27, Warner Losh wrote:

From: Juergen Lock

Helper functions for sysctl implementations. sysctl_name2oid and
sysctl_oidfmt convert oids between host and targets

Signed-off-by: Juergen Lock
Reviewed-by: Warner Losh
Signed-off-by: Warner Losh
---
  bsd-user/freebsd/os-sys.c | 18 ++
  1 file changed, 18 insertions(+)

diff --git a/bs


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2 06/12] bsd-user: Helper routines h2t_old_sysctl

2023-02-14 Thread Richard Henderson

On 2/13/23 14:27, Warner Losh wrote:

+/*
+ * Convert the old value from host to target.


host vs guest is clearer language; "target" gets overloaded, even though still present in 
the code base.



+ *
+ * For LONG and ULONG on ABI32, we need to 'down convert' the 8 byte quantities
+ * to 4 bytes. The caller setup a buffer in host memory to get this data from
+ * the kernel and pass it to us. We do the down conversion and adjust the 
length
+ * so the caller knows what to write as the returned length into the target 
when
+ * it copies the down converted values into the target.
+ *
+ * For normal integral types, we just need to byte swap. No size changes.
+ *
+ * For strings and node data, there's no conversion needed.
+ *
+ * For opaque data, per sysctl OID converts take care of it.
+ */
+static void G_GNUC_UNUSED h2t_old_sysctl(void *holdp, size_t *holdlen, 
uint32_t kind)


h2g.


+/*
+ * hlen == 0 for CTLTYPE_STRING and CTLTYPE_NODE, which need no conversion
+ * as well as CTLTYPE_OPAQUE, which needs special converters.
+ */
+if (hlen == 0) {
+return;
+}
+
+while (len < *holdlen) {
+if (hlen == tlen) {
+switch (hlen) {
+case 1:
+/* Nothing needed: no byteswapping and assigning in place */
+break;
+case 2:
+*(uint16_t *)tp = tswap16(*(uint16_t *)hp);
+break;
+case 4:
+*(uint32_t *)tp = tswap32(*(uint32_t *)hp);
+break;
+case 8:
+*(uint64_t *)tp = tswap64(*(uint64_t *)hp);
+break;
+}


default: g_assert_not_reached().


+}
+#ifdef TARGET_ABI32
+else {
+/*
+ * Saturating assignment for the only two types that differ between
+ * 32-bit and 64-bit machines. All other integral types have the
+ * same, fixed size and will be converted w/o loss of precision
+ * in the above switch.
+ */
+switch (kind & CTLTYPE) {
+case CTLTYPE_LONG:
+*(abi_long *)tp = tswap32(h2t_long_sat(*(long *)hp));
+break;
+case CTLTYPE_ULONG:
+*(abi_ulong *)tp = tswap32(h2t_ulong_sat(*(u_long *)hp));
+break;
+}


default: g_assert_not_reached().


+}
+#endif


#else
g_assert_not_reached();


r~



Re: [PATCH 00/10] Retire Fork-Based Fuzzing

2023-02-14 Thread Thomas Huth

On 14/02/2023 20.14, Alexander Bulekov wrote:

On 230214 2009, Thomas Huth wrote:

On 14/02/2023 17.08, Philippe Mathieu-Daudé wrote:

On 14/2/23 16:38, Stefan Hajnoczi wrote:

On Sat, Feb 04, 2023 at 11:29:41PM -0500, Alexander Bulekov wrote:

Hello,
This series removes fork-based fuzzing.
How does fork-based fuzzing work?
   * A single parent process initializes QEMU
   * We identify the devices we wish to fuzz (fuzzer-dependent)
   * Use QTest to PCI enumerate the devices
   * After that we start a fork-server which forks the process and executes
     fuzzer inputs inside the disposable children.

In a normal fuzzing process, everything happens in a single process.

Pros of fork-based fuzzing:
   * We only need to do common configuration once (e.g. PCI enumeration).
   * Fork provides a strong guarantee that fuzzer inputs will not
interfere with
     each-other
   * The fuzzing process can continue even after a child-process crashes
   * We can apply our-own timers to child-processes to exit slow
inputs, early

Cons of fork-based fuzzing:
   * Fork-based fuzzing is not supported by libfuzzer. We had to
build our own
     fork-server and rely on tricks using linker-scripts and shared-memory to
     support fuzzing. (
https://physics.bu.edu/~alxndr/libfuzzer-forkserver/ )
   * Fork-based fuzzing is currently the main blocker preventing
us from enabling
     other fuzzers such as AFL++ on OSS-Fuzz
   * Fork-based fuzzing may be a reason why coverage-builds are failing on
     OSS-Fuzz. Coverage is an important fuzzing metric which
would allow us to
     find parts of the code that are not well-covered.
   * Fork-based fuzzing has high overhead. fork() is an expensive
system-call,
     especially for processes running ASAN (with large/complex) VMA layouts.
   * Fork prevents us from effectively fuzzing devices that rely on
     threads (e.g. qxl).

These patches remove fork-based fuzzing and replace it with reboot-based
fuzzing for most cases. Misc notes about this change:
   * libfuzzer appears to be no longer in active development. As such, the
     current implementation of fork-based fuzzing (while having some nice
     advantages) is likely to hold us back in the future. If these changes
     are approved and appear to run successfully on OSS-Fuzz, we should be
     able to easily experiment with other fuzzing engines (AFL++).
   * Some device do not completely reset their state. This can lead to
     non-reproducible crashes. However, in my local tests, most crashes
     were reproducible. OSS-Fuzz shouldn't send us reports unless it can
     consistently reproduce a crash.
   * In theory, the corpus-format should not change, so the existing
     corpus-inputs on OSS-Fuzz will transfer to the new reset()-able
     fuzzers.
   * Each fuzzing process will now exit after a single crash is found. To
     continue the fuzzing process, use libfuzzer flags such as -jobs=-1
   * We no long control input-timeouts (those are handled by libfuzzer).
     Since timeouts on oss-fuzz can be many seconds long, I added a limit
     on the number of DMA bytes written.

Alexander Bulekov (10):
    hw/sparse-mem: clear memory on reset
    fuzz: add fuzz_reboot API
    fuzz/generic-fuzz: use reboots instead of forks to reset state
    fuzz/generic-fuzz: add a limit on DMA bytes written
    fuzz/virtio-scsi: remove fork-based fuzzer
    fuzz/virtio-net: remove fork-based fuzzer
    fuzz/virtio-blk: remove fork-based fuzzer
    fuzz/i440fx: remove fork-based fuzzer
    fuzz: remove fork-fuzzing scaffolding
    docs/fuzz: remove mentions of fork-based fuzzing

   docs/devel/fuzzing.rst  |  22 +-
   hw/mem/sparse-mem.c |  13 +++-
   meson.build |   4 -
   tests/qtest/fuzz/fork_fuzz.c    |  41 --
   tests/qtest/fuzz/fork_fuzz.h    |  23 --
   tests/qtest/fuzz/fork_fuzz.ld   |  56 --
   tests/qtest/fuzz/fuzz.c |   6 ++
   tests/qtest/fuzz/fuzz.h |   2 +-
   tests/qtest/fuzz/generic_fuzz.c | 111 +++-
   tests/qtest/fuzz/i440fx_fuzz.c  |  27 +--
   tests/qtest/fuzz/meson.build    |   6 +-
   tests/qtest/fuzz/virtio_blk_fuzz.c  |  51 ++---
   tests/qtest/fuzz/virtio_net_fuzz.c  |  54 ++
   tests/qtest/fuzz/virtio_scsi_fuzz.c |  51 ++---
   14 files changed, 72 insertions(+), 395 deletions(-)
   delete mode 100644 tests/qtest/fuzz/fork_fuzz.c
   delete mode 100644 tests/qtest/fuzz/fork_fuzz.h
   delete mode 100644 tests/qtest/fuzz/fork_fuzz.ld


Whose tree should this go through? Laurent's qtest tree?


Do you mean Thomas?


I thought Alexander would be doing pull requests for fuzzing-related patches
nowadays (since he's the listed maintainer for these files)? Or did I get
that wrong?


I have, though in the past I've been asked to send the PR to different
people. Who should I send this PR to?


I assume you should have enough experience with 

Re: [PATCH v2 6/7] CI: Stop building docs on centos8

2023-02-14 Thread Paolo Bonzini
Il mar 14 feb 2023, 18:26 Kevin Wolf  ha scritto:

> Am 14.02.2023 um 15:03 hat Paolo Bonzini geschrieben:
> > In the case of Python the issue is not the interpreter per se, though
> > there are a couple new feature in Python 3.7 that are quite nice (for
> > example improved data classes[1] or context variables[2]). The main
> > problem as far as I understood (and have seen in my experience) is
> > linting tools. New versions fix bugs that caused false positives, but
> > also become more strict at the same time. The newer versions at the
> > same time are very quick at dropping support for old versions of
> > Python; while older versions sometimes throw deprecation warnings on
> > new versions of Python. This makes it very hard to support a single
> > version of, say, mypy that works on all versions from RHEL8 and SLE15
> > to Fedora 38 and Ubuntu 23.04.
>
> Why do we have to support a single version of mypy? What is wrong with
> running an old mypy version with old Python version, and a newer mypy
> with newer Python versions?
>
> Sure, they will complain about different things, but it doesn't feel
> that different from supporting multiple C compilers in various versions.
>

It's more like having to support only C++03 on RHEL 8 and only C++20 in
Fedora 37, without even being able to use a preprocessor.

For example old versions might not understand some type annotations and
will fail mypy altogether, therefore even with newer versions you can't
annotate the whole source and have to fall back to non-strict mode.

Paolo


> Kevin
>
>


Re: [PATCH v2 04/12] bsd-user: various helper routines for sysctl

2023-02-14 Thread Richard Henderson

On 2/13/23 14:27, Warner Losh wrote:

+#ifdef TARGET_ABI32
+/*
+ * Limit the amount of available memory to be most of the 32-bit address
+ * space. 0x100c000 was arrived at through trial and error as a good
+ * definition of 'most'.
+ */
+static const abi_ulong target_max_mem = UINT32_MAX - 0x100c000 + 1;
+
+static abi_ulong G_GNUC_UNUSED cap_memory(uint64_t mem)
+{
+if (((unsigned long)target_max_mem) < mem) {
+mem = target_max_mem;
+}
+
+return mem;
+}
+#endif


Identity function for ABI64?


+static unsigned long host_page_size;
+
+static abi_ulong G_GNUC_UNUSED scale_to_target_pages(uint64_t pages)
+{
+if (host_page_size == 0) {
+host_page_size = getpagesize();
+}


qemu_real_host_page_size()



+
+pages = muldiv64(pages, host_page_size, TARGET_PAGE_SIZE);
+#ifdef TARGET_ABI32
+abi_ulong maxpages = target_max_mem / (abi_ulong)TARGET_PAGE_SIZE;
+
+if (((unsigned long)maxpages) < pages) {
+pages = maxpages;
+}
+#endif


No need for either cast.  Just use MIN().


+#ifdef TARGET_ABI32
+static abi_long G_GNUC_UNUSED h2t_long_sat(long l)


h2g.


+{
+if (l > INT32_MAX) {
+l = INT32_MAX;
+} else if (l < INT32_MIN) {
+l = INT32_MIN;
+}
+return l;
+}
+
+static abi_ulong G_GNUC_UNUSED h2t_ulong_sat(u_long ul)
+{
+if (ul > UINT32_MAX) {
+ul = UINT32_MAX;
+}
+return ul;
+}
+#endif


Anyway, identity functions for ABI64?


r~



Re: [PATCH v2 05/12] bsd-user: Helper routines oidfmt

2023-02-14 Thread Richard Henderson

On 2/13/23 14:27, Warner Losh wrote:

From: Stacey Son

oidfmt uses undocumented system call to get the type of the sysctl.

Co-Authored-by: Sean Bruno
Signed-off-by: Sean Bruno
Co-Authored-by: Juergen Lock
Signed-off-by: Juergen Lock
Co-Authored-by: Raphael Kubo da Costa
Signed-off-by: Raphael Kubo da Costa
Signed-off-by: Stacey Son
Reviewed-by: Warner Losh
Signed-off-by: Warner Losh
---
  bsd-user/freebsd/os-sys.c | 32 
  1 file changed, 32 insertions(+)


Acked-by: Richard Henderson 

r~



Re: [PATCH] ebpf: fix compatibility with libbpf 1.0+

2023-02-14 Thread Andrew Melnichenko
Hi, all.
In the future, there would be eBPF RSS + the helper for Libvirt interaction.
And those patches are required for future work. Technically they are
required for the current builds with linked libbpf 1.01.
Can we apply this patch?


On Wed, Dec 28, 2022 at 6:19 PM Andrew Melnichenko  wrote:
>
> Hi, it's a good idea to update the skeleton generation. Technically
> skeleton generation is not a part of Qemu building. The skeleton is
> already presented in the Qemu tree, so we skip dependencies from
> clang/bpftool.
> It's a good idea to have an updated bpf program and simplified
> Makefile with Qemu sources. And the skeleton in the Qemu tree should
> be identical to what the Makefile.ebpf would generate.
> I think having one patch with all changes to eBPF RSS is acceptable.
>
> On Tue, Dec 20, 2022 at 6:30 PM Shreesh Adiga
> <16567adigashre...@gmail.com> wrote:
> >
> > On Sun, Dec 18, 2022 at 05:15:04PM +0100, Philippe Mathieu-Daudé wrote:
> > > Hi,
> > >
> > > On 18/12/22 15:39, Shreesh Adiga wrote:
> > > > The current implementation fails to load on a system with
> > > > libbpf 1.0 and reports that legacy map definitions in 'maps'
> > > > section are not supported by libbpf v1.0+. This commit updates
> > > > the Makefile to add BTF (-g flag) and appropriately updates
> > > > the maps in rss.bpf.c and update the skeleton file in repo.
> > > >
> > > > Signed-off-by: Shreesh Adiga <16567adigashre...@gmail.com>
> > > > ---
> > > >   ebpf/rss.bpf.skeleton.h  | 1171 --
> > > >   tools/ebpf/Makefile.ebpf |8 +-
> > > >   tools/ebpf/rss.bpf.c |   43 +-
> > > >   3 files changed, 891 insertions(+), 331 deletions(-)
> > >
> > >
> > > > +static inline const void *rss_bpf__elf_bytes(size_t *sz)
> > > > +{
> > > > +   *sz = 20440;
> > > > +   return (const void *)"\
> > > >   
> > > > \x7f\x45\x4c\x46\x02\x01\x01\0\0\0\0\0\0\0\0\0\x01\0\xf7\0\x01\0\0\0\0\0\0\0\0\
> > > > -\0\0\0\0\0\0\0\0\0\0\0\x18\x1d\0\0\0\0\0\0\0\0\0\0\x40\0\0\0\0\0\x40\0\x0a\0\
> > > > -\x01\0\xbf\x18\0\0\0\0\0\0\xb7\x01\0\0\0\0\0\0\x63\x1a\x4c\xff\0\0\0\0\xbf\xa7\
> > > > -\0\0\0\0\0\0\x07\x07\0\0\x4c\xff\xff\xff\x18\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
> > > > +\0\0\0\0\0\0\0\0\0\0\0\x98\x4c\0\0\0\0\0\0\0\0\0\0\x40\0\0\0\0\0\x40\0\x0d\0\
> > > > +\x01\0\xbf\x19\0\0\0\0\0\0\xb7\x01\0\0\0\0\0\0\x63\x1a\x54\xff\0\0\0\0\xbf\xa7\
> > > > +\0\0\0\0\0\0\x07\x07\0\0\x54\xff\xff\xff\x18\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
> > > >   
> > > > \xbf\x72\0\0\0\0\0\0\x85\0\0\0\x01\0\0\0\xbf\x06\0\0\0\0\0\0\x18\x01\0\0\0\0\0\
> > > > -\0\0\0\0\0\0\0\0\0\xbf\x72\0\0\0\0\0\0\x85\0\0\0\x01\0\0\0\xbf\x07\0\0\0\0\0\0\
> > > > -\x18\0\0\0\xff\xff\xff\xff\0\0\0\0\0\0\0\0\x15\x06\x66\x02\0\0\0\0\xbf\x79\0\0\
> > > > -\0\0\0\0\x15\x09\x64\x02\0\0\0\0\x71\x61\0\0\0\0\0\0\x55\x01\x01\0\0\0\0\0\x05\
> > > > -\0\x5d\x02\0\0\0\0\xb7\x01\0\0\0\0\0\0\x63\x1a\xc0\xff\0\0\0\0\x7b\x1a\xb8\xff\
> > > > -\0\0\0\0\x7b\x1a\xb0\xff\0\0\0\0\x7b\x1a\xa8\xff\0\0\0\0\x7b\x1a\xa0\xff\0\0\0\
> > > > -\0\x63\x1a\x98\xff\0\0\0\0\x7b\x1a\x90\xff\0\0\0\0\x7b\x1a\x88\xff\0\0\0\0\x7b\
> > > > -\x1a\x80\xff\0\0\0\0\x7b\x1a\x78\xff\0\0\0\0\x7b\x1a\x70\xff\0\0\0\0\x7b\x1a\
> > > > -\x68\xff\0\0\0\0\x7b\x1a\x60\xff\0\0\0\0\x7b\x1a\x58\xff\0\0\0\0\x7b\x1a\x50\
> > > > -\xff\0\0\0\0\x15\x08\x4c\x02\0\0\0\0\x6b\x1a\xd0\xff\0\0\0\0\xbf\xa3\0\0\0\0\0\
> > > > -\0\x07\x03\0\0\xd0\xff\xff\xff\xbf\x81\0\0\0\0\0\0\xb7\x02\0\0\x0c\0\0\0\xb7\
> > > > +\0\0\0\0\0\0\0\0\0\xbf\x72\0\0\0\0\0\0\x85\0\0\0\x01\0\0\0\xbf\x08\0\0\0\0\0\0\
> > > > +\x18\0\0\0\xff\xff\xff\xff\0\0\0\0\0\0\0\0\x15\x06\x67\x02\0\0\0\0\xbf\x87\0\0\
> > > > +\0\0\0\0\x15\x07\x65\x02\0\0\0\0\x71\x61\0\0\0\0\0\0\x55\x01\x01\0\0\0\0\0\x05\
> > > > +\0\x5e\x02\0\0\0\0\xb7\x01\0\0\0\0\0\0\x63\x1a\xc8\xff\0\0\0\0\x7b\x1a\xc0\xff\
> > > > +\0\0\0\0\x7b\x1a\xb8\xff\0\0\0\0\x7b\x1a\xb0\xff\0\0\0\0\x7b\x1a\xa8\xff\0\0\0\
> > > > +\0\x63\x1a\xa0\xff\0\0\0\0\x7b\x1a\x98\xff\0\0\0\0\x7b\x1a\x90\xff\0\0\0\0\x7b\
> > > > +\x1a\x88\xff\0\0\0\0\x7b\x1a\x80\xff\0\0\0\0\x7b\x1a\x78\xff\0\0\0\0\x7b\x1a\
> > > > +\x70\xff\0\0\0\0\x7b\x1a\x68\xff\0\0\0\0\x7b\x1a\x60\xff\0\0\0\0\x7b\x1a\x58\
> > > > +\xff\0\0\0\0\x15\x09\x4d\x02\0\0\0\0\x6b\x1a\xd0\xff\0\0\0\0\xbf\xa3\0\0\0\0\0\
> > > [...]
> > >
> > > Can we have a build system step which generates this file and compare
> > > with what is committed in the repository that we can run in our CI?
> > >
> > > That would avoid the need of human review of this blob.
> > >
> > Here are the steps to verify:
> > Pull latest archlinux/archlinux docker image and get a bash shell inside
> > the container. Install the required toolchain packages.
> > pacman -Syu --noconfirm
> > pacman -S --noconfirm  bpf libbpf llvm clang make
> >
> > Confirm the versions:
> > clang 14.0.6
> > bpftool 7.0.0
> > libbpf 1.0.1
> >
> > After this, ensure that the files Makefile.ebpf and rss.bpf.c from this
> > patch exist at /home/shreesh/c/qemu/tools/ebpf/ inside the docker.
> > This path seems to be 

Re: [PATCH 0/4] qemu-img: Fix exit code for errors closing the image

2023-02-14 Thread Vladimir Sementsov-Ogievskiy

On 13.01.23 14:29, Kevin Wolf wrote:

Another thing that could be tried is making failure in .bdrv_close less
likely by doing things earlier. At least ENOSPC could probably be
avoided if dirty bitmaps clusters were allocated during the write
request that first sets a bit in them (I know too little about the
details how bitmaps are implemented in qcow2, though, maybe Vladimir can
help here).


That's possible but not trivial :)

Qcow2 does nothing with dirty bitmaps during normal operation. Only on close, 
it finds all persistent bitmaps and stores them somehow, mostly allocating new 
clusters on the fly.

So the simplest way look like:

- add generic handler .bitmap_changed in BlockDriver, to handle bitmap change 
in qcow2 (that's not only write, but may be bitmap_merge opertion).
- in a new handler allocate some clusters to produce a pool for dirty bitmaps 
saving (will need clusters for bitmap data and metadata (bitmap table, bitmap 
directory))
- in block/qcow2-bitmap.c switch qcow2_alloc_cluster() to a wrapper, that first 
tries to get a cluster from the pool and if it's empty fallback to 
qcow2_alloc_cluster()

Note also, that this will increase fragmentation.

Or, may be more effective would be to preallocate clusters on bitmap creation 
(and therefore on image resize).

More difficult would be rework the whole code to bind allocated clusters for 
each persistent dirty bitmap.

--
Best regards,
Vladimir




Re: [PATCH 06/14] target/arm: Hoist pred_width in arm_gen_dynamic_svereg_xml

2023-02-14 Thread Fabiano Rosas
Richard Henderson  writes:

> Signed-off-by: Richard Henderson 
> ---
>  target/arm/gdbstub64.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/target/arm/gdbstub64.c b/target/arm/gdbstub64.c
> index 8d174ff6e0..02a0256c5c 100644
> --- a/target/arm/gdbstub64.c
> +++ b/target/arm/gdbstub64.c
> @@ -283,6 +283,7 @@ int arm_gen_dynamic_svereg_xml(CPUState *cs, int 
> orig_base_reg)
>  GString *s = g_string_new(NULL);
>  DynamicGDBXMLInfo *info = >dyn_svereg_xml;
>  int reg_width = cpu->sve_max_vq * 128;
> +int pred_width = cpu->sve_max_vq * 16;
>  int base_reg = orig_base_reg;
>  int i;
>  
> @@ -319,14 +320,14 @@ int arm_gen_dynamic_svereg_xml(CPUState *cs, int 
> orig_base_reg)
>  g_string_append_printf(s,
> " " regnum=\"%d\" type=\"svep\"/>",
> -   i, cpu->sve_max_vq * 16, base_reg++);
> +   i, pred_width, base_reg++);
>  info->num++;
>  }
>  g_string_append_printf(s,
> " " regnum=\"%d\" group=\"vector\""
> " type=\"svep\"/>",
> -   cpu->sve_max_vq * 16, base_reg++);
> +   pred_width, base_reg++);
>  
>  /* Define the vector length pseudo-register. */
>  g_string_append_printf(s,

Reviewed-by: Fabiano Rosas 



Re: [PATCH v4 13/16] pci: introduce pci_find_the_only_child()

2023-02-14 Thread Anton Kuchin

On 13/02/2023 16:01, Vladimir Sementsov-Ogievskiy wrote:

To be used in further patch to identify the device hot-plugged into
pcie-root-port.

Signed-off-by: Vladimir Sementsov-Ogievskiy 

Reviewed-by: Anton Kuchin 

---
  include/hw/pci/pci.h |  1 +
  hw/pci/pci.c | 33 +
  2 files changed, 34 insertions(+)

diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index d5a40cd058..b6c9c44527 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -341,6 +341,7 @@ void pci_for_each_device_under_bus_reverse(PCIBus *bus,
  void pci_for_each_bus_depth_first(PCIBus *bus, pci_bus_ret_fn begin,
pci_bus_fn end, void *parent_state);
  PCIDevice *pci_get_function_0(PCIDevice *pci_dev);
+PCIDevice *pci_find_the_only_child(PCIBus *bus, int bus_num, Error **errp);
  
  /* Use this wrapper when specific scan order is not required. */

  static inline
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 208c16f450..34fd1fb5b8 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -1771,6 +1771,39 @@ void pci_for_each_device(PCIBus *bus, int bus_num,
  }
  }
  
+typedef struct TheOnlyChild {

+PCIDevice *dev;
+int count;
+} TheOnlyChild;
+
+static void the_only_child_fn(PCIBus *bus, PCIDevice *dev, void *opaque)
+{
+TheOnlyChild *s = opaque;
+
+s->dev = dev;
+s->count++;
+}
+
+PCIDevice *pci_find_the_only_child(PCIBus *bus, int bus_num, Error **errp)
+{
+TheOnlyChild res = {0};
+
+pci_for_each_device(bus, bus_num, the_only_child_fn, );
+
+if (!res.dev) {
+assert(res.count == 0);
+error_setg(errp, "No child devices found");
+return NULL;
+}
+
+if (res.count > 1) {
+error_setg(errp, "Several child devices found");
+return NULL;
+}
+
+return res.dev;
+}
+
  const pci_class_desc *get_class_desc(int class)
  {
  const pci_class_desc *desc;




Re: [PATCH 05/14] target/arm: Simplify register counting in arm_gen_dynamic_svereg_xml

2023-02-14 Thread Fabiano Rosas
Richard Henderson  writes:

> Rather than increment base_reg and num, compute num
> from the change to base_reg at the end.  Clean up some
> nearby comments.
>
> Signed-off-by: Richard Henderson 
> ---
>  target/arm/gdbstub64.c | 26 --
>  1 file changed, 16 insertions(+), 10 deletions(-)
>
> diff --git a/target/arm/gdbstub64.c b/target/arm/gdbstub64.c
> index 811833d8de..8d174ff6e0 100644
> --- a/target/arm/gdbstub64.c
> +++ b/target/arm/gdbstub64.c
> @@ -277,32 +277,35 @@ static void output_vector_union_type(GString *s, int 
> reg_width)
>  g_string_append(s, "");
>  }
>  
> -int arm_gen_dynamic_svereg_xml(CPUState *cs, int base_reg)
> +int arm_gen_dynamic_svereg_xml(CPUState *cs, int orig_base_reg)
>  {
>  ARMCPU *cpu = ARM_CPU(cs);
>  GString *s = g_string_new(NULL);
>  DynamicGDBXMLInfo *info = >dyn_svereg_xml;
> -int i, reg_width = (cpu->sve_max_vq * 128);
> -info->num = 0;
> +int reg_width = cpu->sve_max_vq * 128;
> +int base_reg = orig_base_reg;
> +int i;
> +
>  g_string_printf(s, "");
>  g_string_append_printf(s, "");
>  g_string_append_printf(s, "");
>  
> +/* Create the vector union type. */
>  output_vector_union_type(s, reg_width);
>  
> -/* Finally the sve prefix type */
> +/* Create the predicate vector type. */
>  g_string_append_printf(s,
> " count=\"%d\"/>",
> reg_width / 8);
>  
> -/* Then define each register in parts for each vq */
> +/* Define the vector registers. */
>  for (i = 0; i < 32; i++) {
>  g_string_append_printf(s,
> " " regnum=\"%d\" type=\"svev\"/>",
> i, reg_width, base_reg++);
> -info->num++;
>  }
> +
>  /* fpscr & status registers */
>  g_string_append_printf(s, " " regnum=\"%d\" group=\"float\""
> @@ -310,8 +313,8 @@ int arm_gen_dynamic_svereg_xml(CPUState *cs, int base_reg)
>  g_string_append_printf(s, " " regnum=\"%d\" group=\"float\""
> " type=\"int\"/>", base_reg++);
> -info->num += 2;
>  
> +/* Define the predicate registers. */
>  for (i = 0; i < 16; i++) {

There's a info->num++; at the end of this loop.

>  g_string_append_printf(s,
> " @@ -324,13 +327,16 @@ int arm_gen_dynamic_svereg_xml(CPUState *cs, int 
> base_reg)
> " regnum=\"%d\" group=\"vector\""
> " type=\"svep\"/>",
> cpu->sve_max_vq * 16, base_reg++);
> +
> +/* Define the vector length pseudo-register. */
>  g_string_append_printf(s,
> " " regnum=\"%d\" type=\"int\"/>",
> base_reg++);
> -info->num += 2;
> -g_string_append_printf(s, "");
> -info->desc = g_string_free(s, false);
>  
> +g_string_append_printf(s, "");
> +
> +info->desc = g_string_free(s, false);
> +info->num = base_reg - orig_base_reg;
>  return info->num;
>  }



Re: [PATCH v4 12/16] pcie: set power indicator to off on reset by default

2023-02-14 Thread Anton Kuchin

On 13/02/2023 16:00, Vladimir Sementsov-Ogievskiy wrote:

It should be zero, the only valid values are ON, OFF and BLINK.

Signed-off-by: Vladimir Sementsov-Ogievskiy 

Reviewed-by: Anton Kuchin 

---
  hw/pci/pcie.c | 1 +
  1 file changed, 1 insertion(+)

diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 90faf0710a..b8c24cf45f 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -684,6 +684,7 @@ void pcie_cap_slot_reset(PCIDevice *dev)
   PCI_EXP_SLTCTL_PDCE |
   PCI_EXP_SLTCTL_ABPE);
  pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTCTL,
+   PCI_EXP_SLTCTL_PWR_IND_OFF |
 PCI_EXP_SLTCTL_ATTN_IND_OFF);
  
  if (dev->cap_present & QEMU_PCIE_SLTCAP_PCP) {




Re: [PATCH v4 11/16] pcie: introduce pcie_sltctl_powered_off() helper

2023-02-14 Thread Anton Kuchin

On 13/02/2023 16:00, Vladimir Sementsov-Ogievskiy wrote:

In pcie_cap_slot_write_config() we check for PCI_EXP_SLTCTL_PWR_OFF in
a bad form. We should distinguish PCI_EXP_SLTCTL_PWR which is a "mask"
and PCI_EXP_SLTCTL_PWR_OFF which is value for that mask.

Better code is in pcie_cap_slot_unplug_request_cb() and in
pcie_cap_update_power(). Let's use same pattern everywhere. To simplify
things add also a helper.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Philippe Mathieu-Daudé 

Reviewed-by: Anton Kuchin 

---
  hw/pci/pcie.c | 16 ++--
  1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index db8360226f..90faf0710a 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -39,6 +39,11 @@
  #define PCIE_DEV_PRINTF(dev, fmt, ...)  \
  PCIE_DPRINTF("%s:%x "fmt, (dev)->name, (dev)->devfn, ## __VA_ARGS__)
  
+static bool pcie_sltctl_powered_off(uint16_t sltctl)

+{
+return (sltctl & PCI_EXP_SLTCTL_PCC) == PCI_EXP_SLTCTL_PWR_OFF
+&& (sltctl & PCI_EXP_SLTCTL_PIC) == PCI_EXP_SLTCTL_PWR_IND_OFF;
+}
  
  /***

   * pci express capability helper functions
@@ -395,6 +400,7 @@ static void pcie_cap_update_power(PCIDevice *hotplug_dev)
  
  if (sltcap & PCI_EXP_SLTCAP_PCP) {

  power = (sltctl & PCI_EXP_SLTCTL_PCC) == PCI_EXP_SLTCTL_PWR_ON;
+/* Don't we need to check also (sltctl & PCI_EXP_SLTCTL_PIC) ? */
  }
  
  pci_for_each_device(sec_bus, pci_bus_num(sec_bus),

@@ -579,8 +585,7 @@ void pcie_cap_slot_unplug_request_cb(HotplugHandler 
*hotplug_dev,
  return;
  }
  
-if (((sltctl & PCI_EXP_SLTCTL_PIC) == PCI_EXP_SLTCTL_PWR_IND_OFF) &&

-((sltctl & PCI_EXP_SLTCTL_PCC) == PCI_EXP_SLTCTL_PWR_OFF)) {
+if (pcie_sltctl_powered_off(sltctl)) {
  /* slot is powered off -> unplug without round-trip to the guest */
  pcie_cap_slot_do_unplug(hotplug_pdev);
  hotplug_event_notify(hotplug_pdev);
@@ -770,10 +775,9 @@ void pcie_cap_slot_write_config(PCIDevice *dev,
   * this is a work around for guests that overwrite
   * control of powered off slots before powering them on.
   */
-if ((sltsta & PCI_EXP_SLTSTA_PDS) && (val & PCI_EXP_SLTCTL_PCC) &&
-(val & PCI_EXP_SLTCTL_PIC) == PCI_EXP_SLTCTL_PWR_IND_OFF &&
-(!(old_slt_ctl & PCI_EXP_SLTCTL_PCC) ||
-(old_slt_ctl & PCI_EXP_SLTCTL_PIC) != PCI_EXP_SLTCTL_PWR_IND_OFF)) {
+if ((sltsta & PCI_EXP_SLTSTA_PDS) && pcie_sltctl_powered_off(val) &&
+!pcie_sltctl_powered_off(old_slt_ctl))
+{
  pcie_cap_slot_do_unplug(dev);
  }
  pcie_cap_update_power(dev);




Re: [PATCH v4 10/16] pcie: pcie_cap_slot_enable_power() use correct helper

2023-02-14 Thread Anton Kuchin

On 13/02/2023 16:00, Vladimir Sementsov-Ogievskiy wrote:

*_by_mask() helpers shouldn't be used here (and that's the only one).
*_by_mask() helpers do shift their value argument, but in pcie.c code
we use values that are already shifted appropriately.
Happily, PCI_EXP_SLTCTL_PWR_ON is zero, so shift doesn't matter. But if
we apply same helper for PCI_EXP_SLTCTL_PWR_OFF constant it will do
wrong thing.

So, let's use instead pci_word_test_and_clear_mask() which is already
used in the file to clear PCI_EXP_SLTCTL_PWR_OFF bit in
pcie_cap_slot_init() and pcie_cap_slot_reset().

Signed-off-by: Vladimir Sementsov-Ogievskiy 

Reviewed-by: Anton Kuchin 

---
  hw/pci/pcie.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index ccdb2377e1..db8360226f 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -373,8 +373,8 @@ void pcie_cap_slot_enable_power(PCIDevice *dev)
  uint32_t sltcap = pci_get_long(exp_cap + PCI_EXP_SLTCAP);
  
  if (sltcap & PCI_EXP_SLTCAP_PCP) {

-pci_set_word_by_mask(exp_cap + PCI_EXP_SLTCTL,
- PCI_EXP_SLTCTL_PCC, PCI_EXP_SLTCTL_PWR_ON);
+pci_word_test_and_clear_mask(exp_cap + PCI_EXP_SLTCTL,
+ PCI_EXP_SLTCTL_PCC);
  }
  }
  




Re: [PATCH v4 09/16] pcie: drop unused PCIExpressIndicator

2023-02-14 Thread Anton Kuchin



On 13/02/2023 16:00, Vladimir Sementsov-Ogievskiy wrote:

The structure type is unused. Also, it's the only user of corresponding
macros, so drop them too.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Philippe Mathieu-Daudé 

Reviewed-by: Anton Kuchin 

---
  include/hw/pci/pcie.h  | 8 
  include/hw/pci/pcie_regs.h | 5 -
  2 files changed, 13 deletions(-)

diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h
index 798a262a0a..3cc2b15957 100644
--- a/include/hw/pci/pcie.h
+++ b/include/hw/pci/pcie.h
@@ -27,14 +27,6 @@
  #include "hw/pci/pcie_sriov.h"
  #include "hw/hotplug.h"
  
-typedef enum {

-/* for attention and power indicator */
-PCI_EXP_HP_IND_RESERVED = PCI_EXP_SLTCTL_IND_RESERVED,
-PCI_EXP_HP_IND_ON   = PCI_EXP_SLTCTL_IND_ON,
-PCI_EXP_HP_IND_BLINK= PCI_EXP_SLTCTL_IND_BLINK,
-PCI_EXP_HP_IND_OFF  = PCI_EXP_SLTCTL_IND_OFF,
-} PCIExpressIndicator;
-
  typedef enum {
  /* these bits must match the bits in Slot Control/Status registers.
   * PCI_EXP_HP_EV_xxx = PCI_EXP_SLTCTL_xxxE = PCI_EXP_SLTSTA_xxx
diff --git a/include/hw/pci/pcie_regs.h b/include/hw/pci/pcie_regs.h
index 00b595a82e..1fe0bdd25b 100644
--- a/include/hw/pci/pcie_regs.h
+++ b/include/hw/pci/pcie_regs.h
@@ -66,11 +66,6 @@ typedef enum PCIExpLinkWidth {
  
  #define PCI_EXP_SLTCAP_PSN_SHIFTctz32(PCI_EXP_SLTCAP_PSN)
  
-#define PCI_EXP_SLTCTL_IND_RESERVED 0x0

-#define PCI_EXP_SLTCTL_IND_ON   0x1
-#define PCI_EXP_SLTCTL_IND_BLINK0x2
-#define PCI_EXP_SLTCTL_IND_OFF  0x3
-
  #define PCI_EXP_SLTCTL_SUPPORTED\
  (PCI_EXP_SLTCTL_ABPE |  \
   PCI_EXP_SLTCTL_PDCE |  \




Re: [PATCH v4 08/16] pcie_regs: drop duplicated indicator value macros

2023-02-14 Thread Anton Kuchin

On 13/02/2023 16:00, Vladimir Sementsov-Ogievskiy wrote:

We already have indicator values in
include/standard-headers/linux/pci_regs.h , no reason to reinvent them
in include/hw/pci/pcie_regs.h. (and we already have usage of
PCI_EXP_SLTCTL_PWR_IND_BLINK and PCI_EXP_SLTCTL_PWR_IND_OFF in
hw/pci/pcie.c, so let's be consistent)

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Philippe Mathieu-Daudé 

Reviewed-by: Anton Kuchin 

---
  include/hw/pci/pcie_regs.h |  9 -
  hw/pci/pcie.c  | 13 +++--
  2 files changed, 7 insertions(+), 15 deletions(-)

diff --git a/include/hw/pci/pcie_regs.h b/include/hw/pci/pcie_regs.h
index 963dc2e170..00b595a82e 100644
--- a/include/hw/pci/pcie_regs.h
+++ b/include/hw/pci/pcie_regs.h
@@ -70,15 +70,6 @@ typedef enum PCIExpLinkWidth {
  #define PCI_EXP_SLTCTL_IND_ON   0x1
  #define PCI_EXP_SLTCTL_IND_BLINK0x2
  #define PCI_EXP_SLTCTL_IND_OFF  0x3
-#define PCI_EXP_SLTCTL_AIC_SHIFTctz32(PCI_EXP_SLTCTL_AIC)
-#define PCI_EXP_SLTCTL_AIC_OFF  \
-(PCI_EXP_SLTCTL_IND_OFF << PCI_EXP_SLTCTL_AIC_SHIFT)
-
-#define PCI_EXP_SLTCTL_PIC_SHIFTctz32(PCI_EXP_SLTCTL_PIC)
-#define PCI_EXP_SLTCTL_PIC_OFF  \
-(PCI_EXP_SLTCTL_IND_OFF << PCI_EXP_SLTCTL_PIC_SHIFT)
-#define PCI_EXP_SLTCTL_PIC_ON  \
-(PCI_EXP_SLTCTL_IND_ON << PCI_EXP_SLTCTL_PIC_SHIFT)
  
  #define PCI_EXP_SLTCTL_SUPPORTED\

  (PCI_EXP_SLTCTL_ABPE |  \
diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 82ef723983..ccdb2377e1 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -634,8 +634,8 @@ void pcie_cap_slot_init(PCIDevice *dev, PCIESlot *s)
   PCI_EXP_SLTCTL_PIC |
   PCI_EXP_SLTCTL_AIC);
  pci_word_test_and_set_mask(dev->config + pos + PCI_EXP_SLTCTL,
-   PCI_EXP_SLTCTL_PIC_OFF |
-   PCI_EXP_SLTCTL_AIC_OFF);
+   PCI_EXP_SLTCTL_PWR_IND_OFF |
+   PCI_EXP_SLTCTL_ATTN_IND_OFF);
  pci_word_test_and_set_mask(dev->wmask + pos + PCI_EXP_SLTCTL,
 PCI_EXP_SLTCTL_PIC |
 PCI_EXP_SLTCTL_AIC |
@@ -679,7 +679,7 @@ void pcie_cap_slot_reset(PCIDevice *dev)
   PCI_EXP_SLTCTL_PDCE |
   PCI_EXP_SLTCTL_ABPE);
  pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTCTL,
-   PCI_EXP_SLTCTL_AIC_OFF);
+   PCI_EXP_SLTCTL_ATTN_IND_OFF);
  
  if (dev->cap_present & QEMU_PCIE_SLTCAP_PCP) {

  /* Downstream ports enforce device number 0. */
@@ -694,7 +694,8 @@ void pcie_cap_slot_reset(PCIDevice *dev)
 PCI_EXP_SLTCTL_PCC);
  }
  
-pic = populated ? PCI_EXP_SLTCTL_PIC_ON : PCI_EXP_SLTCTL_PIC_OFF;

+pic = populated ?
+PCI_EXP_SLTCTL_PWR_IND_ON : PCI_EXP_SLTCTL_PWR_IND_OFF;
  pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTCTL, pic);
  }
  
@@ -770,9 +771,9 @@ void pcie_cap_slot_write_config(PCIDevice *dev,

   * control of powered off slots before powering them on.
   */
  if ((sltsta & PCI_EXP_SLTSTA_PDS) && (val & PCI_EXP_SLTCTL_PCC) &&
-(val & PCI_EXP_SLTCTL_PIC) == PCI_EXP_SLTCTL_PIC_OFF &&
+(val & PCI_EXP_SLTCTL_PIC) == PCI_EXP_SLTCTL_PWR_IND_OFF &&
  (!(old_slt_ctl & PCI_EXP_SLTCTL_PCC) ||
-(old_slt_ctl & PCI_EXP_SLTCTL_PIC) != PCI_EXP_SLTCTL_PIC_OFF)) {
+(old_slt_ctl & PCI_EXP_SLTCTL_PIC) != PCI_EXP_SLTCTL_PWR_IND_OFF)) {
  pcie_cap_slot_do_unplug(dev);
  }
  pcie_cap_update_power(dev);




Re: [PATCH v4 07/16] pcie: pcie_cap_slot_write_config(): use correct macro

2023-02-14 Thread Anton Kuchin

On 13/02/2023 16:00, Vladimir Sementsov-Ogievskiy wrote:

PCI_EXP_SLTCTL_PIC_OFF is a value, and PCI_EXP_SLTCTL_PIC is a mask.
Happily PCI_EXP_SLTCTL_PIC_OFF is a maximum value for this mask and is
equal to the mask itself. Still the code looks like a bug. Let's make
it more reader-friendly.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Philippe Mathieu-Daudé 
---
  hw/pci/pcie.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 924fdabd15..82ef723983 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -770,9 +770,9 @@ void pcie_cap_slot_write_config(PCIDevice *dev,
   * control of powered off slots before powering them on.
   */
  if ((sltsta & PCI_EXP_SLTSTA_PDS) && (val & PCI_EXP_SLTCTL_PCC) &&
-(val & PCI_EXP_SLTCTL_PIC_OFF) == PCI_EXP_SLTCTL_PIC_OFF &&
+(val & PCI_EXP_SLTCTL_PIC) == PCI_EXP_SLTCTL_PIC_OFF &&
  (!(old_slt_ctl & PCI_EXP_SLTCTL_PCC) ||
-(old_slt_ctl & PCI_EXP_SLTCTL_PIC_OFF) != PCI_EXP_SLTCTL_PIC_OFF)) {
+(old_slt_ctl & PCI_EXP_SLTCTL_PIC) != PCI_EXP_SLTCTL_PIC_OFF)) {
  pcie_cap_slot_do_unplug(dev);
  }
  pcie_cap_update_power(dev);

Reviewed-by: Anton Kuchin 



  1   2   3   4   5   >