Re: [PATCH v4 04/11] target/riscv: pmu: Make number of counters configurable

2022-01-06 Thread Bin Meng
On Fri, Jan 7, 2022 at 10:18 AM Atish Patra  wrote:
>
> The RISC-V privilege specification provides flexibility to implement
> any number of counters from 29 programmable counters. However, the QEMU
> implements all the counters.
>
> Make it configurable through pmu config parameter which now will indicate
> how many programmable counters should be implemented by the cpu.
>
> Signed-off-by: Atish Patra 
> Signed-off-by: Atish Patra 
> ---
>  target/riscv/cpu.c |  2 +-
>  target/riscv/cpu.h |  2 +-
>  target/riscv/csr.c | 96 ++
>  3 files changed, 65 insertions(+), 35 deletions(-)
>

Reviewed-by: Bin Meng 



Re: [PATCH v4 02/11] target/riscv: Implement PMU CSR predicate function for S-mode

2022-01-06 Thread Bin Meng
On Fri, Jan 7, 2022 at 10:14 AM Atish Patra  wrote:
>
> From: Atish Patra 
>
> Currently, the predicate function for PMU related CSRs only works if
> virtualization is enabled. It also does not check mcounteren bits before
> before cycle/minstret/hpmcounterx access.
>
> Support supervisor mode access in the predicate function as well.
>
> Reviewed-by: Alistair Francis 
> Signed-off-by: Atish Patra 
> Signed-off-by: Atish Patra 
> ---
>  target/riscv/csr.c | 52 ++
>  1 file changed, 52 insertions(+)
>

Reviewed-by: Bin Meng 



Re: [PATCH] MAINTAINERS: Improve the PowerPC machines section

2022-01-06 Thread Mark Cave-Ayland

On 05/01/2022 10:48, Thomas Huth wrote:


Add some documentation files to the corresponding machine sections
and mention the machine names in the section titles where it is
not so obvious (e.g. that "taihu" is a 405 machine).

Signed-off-by: Thomas Huth 
---
  MAINTAINERS | 12 
  1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index f871d759fd..53cf0fdc00 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1245,7 +1245,7 @@ F: hw/openrisc/openrisc_sim.c
  
  PowerPC Machines

  
-405
+405 (ref405ep and taihu)
  L: qemu-...@nongnu.org
  S: Orphan
  F: hw/ppc/ppc405_boards.c
@@ -1281,6 +1281,7 @@ New World (mac99)
  M: Mark Cave-Ayland 
  L: qemu-...@nongnu.org
  S: Odd Fixes
+F: docs/system/ppc/powermac.rst
  F: hw/ppc/mac_newworld.c
  F: hw/pci-host/uninorth.c
  F: hw/pci-bridge/dec.[hc]
@@ -1299,6 +1300,7 @@ Old World (g3beige)
  M: Mark Cave-Ayland 
  L: qemu-...@nongnu.org
  S: Odd Fixes
+F: docs/system/ppc/powermac.rst
  F: hw/ppc/mac_oldworld.c
  F: hw/pci-host/grackle.c
  F: hw/misc/macio/
@@ -1312,6 +1314,7 @@ PReP
  M: Hervé Poussineau 
  L: qemu-...@nongnu.org
  S: Maintained
+F: docs/system/ppc/prep.rst
  F: hw/ppc/prep.c
  F: hw/ppc/prep_systemio.c
  F: hw/ppc/rs6000_mc.c
@@ -1324,7 +1327,7 @@ F: include/hw/isa/pc87312.h
  F: include/hw/rtc/m48t59.h
  F: tests/avocado/ppc_prep_40p.py
  
-sPAPR

+sPAPR (pseries)
  M: Cédric Le Goater 
  M: Daniel Henrique Barboza 
  R: David Gibson 
@@ -1336,8 +1339,8 @@ F: include/hw/*/spapr*
  F: hw/*/xics*
  F: include/hw/*/xics*
  F: pc-bios/slof.bin
-F: docs/specs/ppc-spapr-hcalls.txt
-F: docs/specs/ppc-spapr-hotplug.txt
+F: docs/system/ppc/pseries.rst
+F: docs/specs/ppc-spapr-*
  F: tests/qtest/spapr*
  F: tests/qtest/libqos/*spapr*
  F: tests/qtest/rtas*
@@ -1348,6 +1351,7 @@ PowerNV (Non-Virtualized)
  M: Cédric Le Goater 
  L: qemu-...@nongnu.org
  S: Maintained
+F: docs/system/ppc/powernv.rst
  F: hw/ppc/pnv*
  F: hw/intc/pnv*
  F: hw/intc/xics_pnv.c


For the New World and Old World machines:

Reviewed-by: Mark Cave-Ayland 


ATB,

Mark.



Re: [PATCH qemu] spapr: Force 32bit when resetting a core

2022-01-06 Thread Cédric Le Goater

On 1/7/22 08:24, Alexey Kardashevskiy wrote:

"PowerPC Processor binding to IEEE 1275" says in
"8.2.1. Initial Register Values" that the initial state is defined as
32bit so do it for both SLOF and VOF.

This should not cause behavioral change as SLOF switches to 64bit very
early anyway. As nothing enforces LE anywhere, this drops it for VOF.

The goal is to make VOF work with TCG as otherwise it barfs with
qemu: fatal: TCG hflags mismatch (current:0x6c04 rebuilt:0x6c00)

Signed-off-by: Alexey Kardashevskiy 
---
  hw/ppc/spapr_cpu_core.c | 5 +
  hw/ppc/spapr_vof.c  | 2 --
  2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index a57ba70a8781..a781e97f8d1d 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -37,6 +37,11 @@ static void spapr_reset_vcpu(PowerPCCPU *cpu)
  
  cpu_reset(cs);
  
+/*

+ * "PowerPC Processor binding to IEEE 1275" defines the initial MSR state
+ * as 32bit (MSR_SF=0) in "8.2.1. Initial Register Values".
+ */


Indeed but this seems to contradict 8b9f2118ca40 ("ppc64: set MSR_SF bit").

Laurent, would you remember the reason for forcing 64bit ? It's been a while
since.

Thanks,

C.



+env->msr &= ~(1ULL << MSR_SF);
  env->spr[SPR_HIOR] = 0;
  
  lpcr = env->spr[SPR_LPCR];

diff --git a/hw/ppc/spapr_vof.c b/hw/ppc/spapr_vof.c
index 40ce8fe0037c..a33f940c32bb 100644
--- a/hw/ppc/spapr_vof.c
+++ b/hw/ppc/spapr_vof.c
@@ -88,8 +88,6 @@ void spapr_vof_reset(SpaprMachineState *spapr, void *fdt, 
Error **errp)
  spapr_cpu_set_entry_state(first_ppc_cpu, SPAPR_ENTRY_POINT,
stack_ptr, spapr->initrd_base,
spapr->initrd_size);
-/* VOF is 32bit BE so enforce MSR here */
-first_ppc_cpu->env.msr &= ~((1ULL << MSR_SF) | (1ULL << MSR_LE));
  
  /*

   * At this point the expected allocation map is:






[PATCH qemu] spapr: Force 32bit when resetting a core

2022-01-06 Thread Alexey Kardashevskiy
"PowerPC Processor binding to IEEE 1275" says in
"8.2.1. Initial Register Values" that the initial state is defined as
32bit so do it for both SLOF and VOF.

This should not cause behavioral change as SLOF switches to 64bit very
early anyway. As nothing enforces LE anywhere, this drops it for VOF.

The goal is to make VOF work with TCG as otherwise it barfs with
qemu: fatal: TCG hflags mismatch (current:0x6c04 rebuilt:0x6c00)

Signed-off-by: Alexey Kardashevskiy 
---
 hw/ppc/spapr_cpu_core.c | 5 +
 hw/ppc/spapr_vof.c  | 2 --
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index a57ba70a8781..a781e97f8d1d 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -37,6 +37,11 @@ static void spapr_reset_vcpu(PowerPCCPU *cpu)
 
 cpu_reset(cs);
 
+/*
+ * "PowerPC Processor binding to IEEE 1275" defines the initial MSR state
+ * as 32bit (MSR_SF=0) in "8.2.1. Initial Register Values".
+ */
+env->msr &= ~(1ULL << MSR_SF);
 env->spr[SPR_HIOR] = 0;
 
 lpcr = env->spr[SPR_LPCR];
diff --git a/hw/ppc/spapr_vof.c b/hw/ppc/spapr_vof.c
index 40ce8fe0037c..a33f940c32bb 100644
--- a/hw/ppc/spapr_vof.c
+++ b/hw/ppc/spapr_vof.c
@@ -88,8 +88,6 @@ void spapr_vof_reset(SpaprMachineState *spapr, void *fdt, 
Error **errp)
 spapr_cpu_set_entry_state(first_ppc_cpu, SPAPR_ENTRY_POINT,
   stack_ptr, spapr->initrd_base,
   spapr->initrd_size);
-/* VOF is 32bit BE so enforce MSR here */
-first_ppc_cpu->env.msr &= ~((1ULL << MSR_SF) | (1ULL << MSR_LE));
 
 /*
  * At this point the expected allocation map is:
-- 
2.30.2




Re: [PATCH] q800: fix segfault with invalid MacROM

2022-01-06 Thread Thomas Huth

On 06/01/2022 13.22, Laurent Vivier wrote:

"qemu-system-m68k -M q800 -bios /dev/null" crahses with a segfault
in q800_init().
This happens because the code doesn't check that rom_ptr() returned
a non-NULL pointer .

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/756
Reported-by: Peter Maydell 
Signed-off-by: Laurent Vivier 
---
  hw/m68k/q800.c | 8 +++-
  1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c
index e4c7c9b88ad0..6261716c8f7e 100644
--- a/hw/m68k/q800.c
+++ b/hw/m68k/q800.c
@@ -672,10 +672,16 @@ static void q800_init(MachineState *machine)
  
  /* Remove qtest_enabled() check once firmware files are in the tree */

  if (!qtest_enabled()) {
-if (bios_size < 0 || bios_size > MACROM_SIZE) {
+if (bios_size == -1) {
  error_report("could not load MacROM '%s'", bios_name);
  exit(1);
  }
+if (bios_size != MACROM_SIZE) {
+error_report("Invalid size for MacROM '%s': %d bytes,"
+ " expected %d bytes", bios_name, bios_size,
+ MACROM_SIZE);
+exit(1);
+}
  
  ptr = rom_ptr(MACROM_ADDR, MACROM_SIZE);

  stl_phys(cs->as, 0, ldl_p(ptr));/* reset initial SP */


Reviewed-by: Thomas Huth 




Re: [PATCH] docs/can: convert to restructuredText

2022-01-06 Thread Thomas Huth

On 05/01/2022 20.52, Lucas Ramage wrote:

Hi Thomas,

I intentionally sent the email via my gmx address. But I want my commit under 
the infinite-omicron email address.

I had a few warnings on my end, but it builds fine with Sphinx v3.4.3 on Debian 
Bullseye. I can clean up the warnings in the new patch.


Yes, please do so. If you add "--enable-werror" to your "configure" options, 
the warnings should be turned into errors as well - and that's what we do in 
our CI, so the warnings have to be fixed first before this patch can be 
included.


 Thanks,
  Thomas




Re: [RFC PATCH v2 20/44] i386/tdx: Parse tdx metadata and store the result into TdxGuestState

2022-01-06 Thread Xiaoyao Li

On 1/7/2022 12:06 AM, Laszlo Ersek wrote:

On 01/04/22 14:08, Xiaoyao Li wrote:


+ Laszlo,

Regarding laoding TDVF as pflash, I have some questions:

- pflash requires KVM to support readonly mmeory. However, for TDX, it
doesn't support readonly memory. Is it a must? or we can make an
exception for TDX?

- I saw from
https://lists.gnu.org/archive/html/qemu-discuss/2018-04/msg00045.html,
you said when load OVMF as pflash, it's MMIO. But for TDVF, it's treated
as private memory. I'm not sure whether it will cause some potential
problem if loading TDVF with pflash.

Anyway I tried changing the existing pflash approach to load TDVF. It
can boot a TDX VM and no issue.


I have no comments on whether TDX should or should not use pflash.

If you go without pflash, then you likely will not have a
standards-conformant UEFI variable store. (Unless you reimplement the
variable arch protocols in edk2 on top of something else than the Fault
Tolerant Write and Firmware Volume Block protocols.) Whether a
conformant UEFI varstore matters to you (or to TDX in general) is
something I can't comment on.


Thanks for your reply! Laszlo

regarding "standards-conformant UEFI variable store", I guess you mean 
the change to UEFI non-volatile variables needs to be synced back to the 
OVMF_VARS.fd file. right?


If so, I need to sync with internal folks who are upstreaming TDVF 
support into OVMF.



(I've generally stopped commenting on confidential computing topics, but
this message allows for comments on just pflash, and how it impacts OVMF.)

Regarding pflash itself, the read-only KVM memslot is required for it.
Otherwise pflash cannot work as a "ROMD device" (= you can't flip it
back and forth between ROM mode and programming (MMIO) mode).


We don't need Read-only mode for TDVF so far. If for this purpose, is it 
acceptable that allowing a pflash without KVM readonly memslot support 
if read-only is not required for the specific pflash device?


We are trying to follow the existing usage of OVMF for TDX, since TDVF 
support will be landed in OVMF instead of a new separate binary.



Thanks
Laszlo






Re: [PATCH v8 07/18] target/riscv: setup everything for rv64 to support rv128 execution

2022-01-06 Thread Alistair Francis
On Fri, Jan 7, 2022 at 4:23 PM Frédéric Pétrot
 wrote:
>
> On 06/01/2022 22:24, Alistair Francis wrote:
> > On Fri, Jan 7, 2022 at 7:04 AM Frédéric Pétrot
> >  wrote:
> >>
> >> This patch adds the support of the '-cpu rv128' option to
> >> qemu-system-riscv64 so that we can indicate that we want to run rv128
> >> executables.
> >> Still, there is no support for 128-bit insns at that stage so qemu fails
> >> miserably (as expected) if launched with this option.
> >>
> >> Signed-off-by: Frédéric Pétrot 
> >> Co-authored-by: Fabien Portas 
> >> Reviewed-by: Alistair Francis 
> >> ---
> >>   include/disas/dis-asm.h |  1 +
> >>   target/riscv/cpu.h  |  1 +
> >>   disas/riscv.c   |  5 +
> >>   target/riscv/cpu.c  | 20 
> >>   target/riscv/gdbstub.c  |  5 +
> >>   5 files changed, 32 insertions(+)
> >>
> >> diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h
> >> index 08e1beec85..102a1e7f50 100644
> >> --- a/include/disas/dis-asm.h
> >> +++ b/include/disas/dis-asm.h
> >> @@ -459,6 +459,7 @@ int print_insn_nios2(bfd_vma, disassemble_info*);
> >>   int print_insn_xtensa   (bfd_vma, disassemble_info*);
> >>   int print_insn_riscv32  (bfd_vma, disassemble_info*);
> >>   int print_insn_riscv64  (bfd_vma, disassemble_info*);
> >> +int print_insn_riscv128 (bfd_vma, disassemble_info*);
> >>   int print_insn_rx(bfd_vma, disassemble_info *);
> >>   int print_insn_hexagon(bfd_vma, disassemble_info *);
> >>
> >> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> >> index fa5d238530..efe481f5fb 100644
> >> --- a/target/riscv/cpu.h
> >> +++ b/target/riscv/cpu.h
> >> @@ -38,6 +38,7 @@
> >>   #define TYPE_RISCV_CPU_ANY  RISCV_CPU_TYPE_NAME("any")
> >>   #define TYPE_RISCV_CPU_BASE32   RISCV_CPU_TYPE_NAME("rv32")
> >>   #define TYPE_RISCV_CPU_BASE64   RISCV_CPU_TYPE_NAME("rv64")
> >> +#define TYPE_RISCV_CPU_BASE128  RISCV_CPU_TYPE_NAME("rv128")
> >
> > As this series only adds partial support for 128-bit support, I think
> > we should probably change this to "x-rv128". That way we indicate to
> > users that it is experimental. That allows us more flexibility in the
> > future to have breaking changes and will hopefully avoid confusion
> > about the current state. What do you think? I can just make the change
> > when I apply the patches.
>
>Sure, this is clearly experimental (the spec is a draft) and should be
>marked so, I totally agree. Please make the change as you suggest,

Great!

Applied to riscv-to-apply.next

If you want to make sure my change didn't break anything you can test
the tree here: https://github.com/alistair23/qemu/tree/riscv-to-apply.next

I'll send a PR this weekend or next week.

Alistair

>
>Thanks,
>Frédéric
>
> >
> > Alistair
>
> --
> +---+
> | Frédéric Pétrot, Pr. Grenoble INP-Ensimag/TIMA,   Ensimag deputy director |
> | Mob/Pho: +33 6 74 57 99 65/+33 4 76 57 48 70  Ad augusta  per angusta |
> | http://tima.univ-grenoble-alpes.fr frederic.pet...@univ-grenoble-alpes.fr |
> +---+



Re: [PATCH v8 07/18] target/riscv: setup everything for rv64 to support rv128 execution

2022-01-06 Thread Frédéric Pétrot

On 06/01/2022 22:24, Alistair Francis wrote:

On Fri, Jan 7, 2022 at 7:04 AM Frédéric Pétrot
 wrote:


This patch adds the support of the '-cpu rv128' option to
qemu-system-riscv64 so that we can indicate that we want to run rv128
executables.
Still, there is no support for 128-bit insns at that stage so qemu fails
miserably (as expected) if launched with this option.

Signed-off-by: Frédéric Pétrot 
Co-authored-by: Fabien Portas 
Reviewed-by: Alistair Francis 
---
  include/disas/dis-asm.h |  1 +
  target/riscv/cpu.h  |  1 +
  disas/riscv.c   |  5 +
  target/riscv/cpu.c  | 20 
  target/riscv/gdbstub.c  |  5 +
  5 files changed, 32 insertions(+)

diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h
index 08e1beec85..102a1e7f50 100644
--- a/include/disas/dis-asm.h
+++ b/include/disas/dis-asm.h
@@ -459,6 +459,7 @@ int print_insn_nios2(bfd_vma, disassemble_info*);
  int print_insn_xtensa   (bfd_vma, disassemble_info*);
  int print_insn_riscv32  (bfd_vma, disassemble_info*);
  int print_insn_riscv64  (bfd_vma, disassemble_info*);
+int print_insn_riscv128 (bfd_vma, disassemble_info*);
  int print_insn_rx(bfd_vma, disassemble_info *);
  int print_insn_hexagon(bfd_vma, disassemble_info *);

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index fa5d238530..efe481f5fb 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -38,6 +38,7 @@
  #define TYPE_RISCV_CPU_ANY  RISCV_CPU_TYPE_NAME("any")
  #define TYPE_RISCV_CPU_BASE32   RISCV_CPU_TYPE_NAME("rv32")
  #define TYPE_RISCV_CPU_BASE64   RISCV_CPU_TYPE_NAME("rv64")
+#define TYPE_RISCV_CPU_BASE128  RISCV_CPU_TYPE_NAME("rv128")


As this series only adds partial support for 128-bit support, I think
we should probably change this to "x-rv128". That way we indicate to
users that it is experimental. That allows us more flexibility in the
future to have breaking changes and will hopefully avoid confusion
about the current state. What do you think? I can just make the change
when I apply the patches.


  Sure, this is clearly experimental (the spec is a draft) and should be
  marked so, I totally agree. Please make the change as you suggest,

  Thanks,
  Frédéric



Alistair


--
+---+
| Frédéric Pétrot, Pr. Grenoble INP-Ensimag/TIMA,   Ensimag deputy director |
| Mob/Pho: +33 6 74 57 99 65/+33 4 76 57 48 70  Ad augusta  per angusta |
| http://tima.univ-grenoble-alpes.fr frederic.pet...@univ-grenoble-alpes.fr |
+---+



Re: [PATCH v8 0/7] Add vmnet.framework based network backend

2022-01-06 Thread Jason Wang



在 2022/1/6 下午12:18, Jason Wang 写道:


在 2021/12/11 下午6:44, Vladislav Yaroshchuk 写道:

macOS provides networking API for VMs called 'vmnet.framework':
https://developer.apple.com/documentation/vmnet

We can provide its support as the new QEMU network backends which
represent three different vmnet.framework interface usage modes:

   * `vmnet-shared`:
 allows the guest to communicate with other guests in shared mode 
and

 also with external network (Internet) via NAT. Has (macOS-provided)
 DHCP server; subnet mask and IP range can be configured;

   * `vmnet-host`:
 allows the guest to communicate with other guests in host mode.
 By default has enabled DHCP as `vmnet-shared`, but providing
 network unique id (uuid) can make `vmnet-host` interfaces isolated
 from each other and also disables DHCP.

   * `vmnet-bridged`:
 bridges the guest with a physical network interface.

This backends cannot work on macOS Catalina 10.15 cause we use
vmnet.framework API provided only with macOS 11 and newer. Seems
that it is not a problem, because QEMU guarantees to work on two most
recent versions of macOS which now are Big Sur (11) and Monterey (12).

Also, we have one inconvenient restriction: vmnet.framework interfaces
can create only privileged user:
`$ sudo qemu-system-x86_64 -nic vmnet-shared`

Attempt of `vmnet-*` netdev creation being unprivileged user fails with
vmnet's 'general failure'.

This happens because vmnet.framework requires `com.apple.vm.networking`
entitlement which is: "restricted to developers of virtualization 
software.
To request this entitlement, contact your Apple representative." as 
Apple

documentation says:
https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_vm_networking 



One more note: we still have quite useful but not supported
'vmnet.framework' features as creating port forwarding rules, IPv6
NAT prefix specifying and so on.

Nevertheless, new backends work fine and tested within 
`qemu-system-x86-64`

on macOS Bir Sur 11.5.2 host with such nic models:
   * e1000-82545em
   * virtio-net-pci
   * vmxnet3

The guests were:
   * macOS 10.15.7
   * Ubuntu Bionic (server cloudimg)


This series partially reuses patches by Phillip Tennen:
https://patchew.org/QEMU/20210218134947.1860-1-phillip.en...@gmail.com/
So I included them signed-off line into one of the commit messages and
also here.



Applied.

Thanks



Reverted actually, though it can be built on macos but not Linux. I see 
thing like:


In file included from qapi/qapi-types-net.c:15:
qapi/qapi-types-net.h:411:9: error: unknown type name 
‘NetdevVmnetHostOptions’

  411 | NetdevVmnetHostOptions vmnet_host;
  | ^~
qapi/qapi-types-net.h:412:9: error: unknown type name 
‘NetdevVmnetSharedOptions’

  412 | NetdevVmnetSharedOptions vmnet_shared;
  | ^~~~
qapi/qapi-types-net.h:413:9: error: unknown type name 
‘NetdevVmnetBridgedOptions’

  413 | NetdevVmnetBridgedOptions vmnet_bridged;
  | ^



Thanks





Re: [PATCH v14 00/26] Add LoongArch linux-user emulation support

2022-01-06 Thread Richard Henderson

On 1/6/22 1:41 AM, Song Gao wrote:

Based-on:<20220106074740.1754661-1-gaos...@loongson.cn>

Hi all,

This series only support linux-user emulation.
More about LoongArch at:https://github.com/loongson/

The latest kernel:
   *https://github.com/loongson/linux/tree/loongarch-next

Patches need review:
   * 0018-linux-user-Add-LoongArch-specific-structures.patch
   * 0019-linux-user-Add-LoongArch-signal-support.patch


You're still blocked on no upstream kernel support.
As shown in patch 19, the kernel abi is still in flux.

It would be best if you could work toward getting full system emulation completed.  Then 
all of the basic cpu emulation can be merged and all you'd need to keep updating is the 
linux-user portions.



r~



Re: [PATCH v14 19/26] linux-user: Add LoongArch signal support

2022-01-06 Thread Richard Henderson

On 1/6/22 1:41 AM, Song Gao wrote:

+struct target_sigcontext {
+uint64_t sc_pc;
+uint64_t sc_regs[32];
+uint32_t sc_flags;
+uint32_t sc_fcsr;
+uint32_t sc_vcsr;
+uint64_t sc_fcc;
+uint64_t sc_scr[4];
+union fpureg sc_fpregs[32] __attribute__((aligned(32)));
+uint8_t sc_reserved[4096] __attribute__((aligned(16)));
+};


Does not match the current (December 31) kernel source.


+static inline void setup_sigcontext(CPULoongArchState *env,
+struct target_sigcontext *sc)


Don't bother with inline markers anywhere in this file.  Let the compiler 
decide.


+restore_sigcontext(CPULoongArchState *env, struct target_sigcontext *sc)
+{
+int i;
+
+__get_user(env->pc, >sc_pc);
+__get_user(env->fcsr0, >sc_fcsr);


You need to call restore_fp_status after this assignment, somewhere before the end of the 
function.


Otherwise this looks ok.


r~



Re: [PATCH 2/2] net/colo-compare.c: Update the default value comments

2022-01-06 Thread Jason Wang
On Mon, Dec 20, 2021 at 9:17 AM Zhang Chen  wrote:
>
> Make the comments consistent with the REGULAR_PACKET_CHECK_MS.
>
> Signed-off-by: Zhang Chen 

Applied.

Thanks

> ---
>  net/colo-compare.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/net/colo-compare.c b/net/colo-compare.c
> index 216de5a12b..62554b5b3c 100644
> --- a/net/colo-compare.c
> +++ b/net/colo-compare.c
> @@ -1267,7 +1267,7 @@ static void colo_compare_complete(UserCreatable *uc, 
> Error **errp)
>  }
>
>  if (!s->expired_scan_cycle) {
> -/* Set default value to 3000 MS */
> +/* Set default value to 1000 MS */
>  s->expired_scan_cycle = REGULAR_PACKET_CHECK_MS;
>  }
>
> --
> 2.25.1
>




Re: [PATCH 1/2] net/colo-compare.c: Optimize compare order for performance

2022-01-06 Thread Jason Wang
On Mon, Dec 20, 2021 at 9:16 AM Zhang Chen  wrote:
>
> COLO-compare use the glib function g_queue_find_custom to dump
> another VM's networking packet to compare. But this function always
> start find from the queue->head(here is the newest packet), It will
> reduce the success rate of comparison. So this patch reversed
> the order of the queues for performance.
>
> Signed-off-by: Zhang Chen 
> Reported-by: leirao 
> ---
>  net/colo-compare.c | 26 +-
>  1 file changed, 13 insertions(+), 13 deletions(-)

Applied.

Thanks

>
> diff --git a/net/colo-compare.c b/net/colo-compare.c
> index b966e7e514..216de5a12b 100644
> --- a/net/colo-compare.c
> +++ b/net/colo-compare.c
> @@ -197,7 +197,7 @@ static void 
> colo_compare_inconsistency_notify(CompareState *s)
>  /* Use restricted to colo_insert_packet() */
>  static gint seq_sorter(Packet *a, Packet *b, gpointer data)
>  {
> -return a->tcp_seq - b->tcp_seq;
> +return b->tcp_seq - a->tcp_seq;
>  }
>
>  static void fill_pkt_tcp_info(void *data, uint32_t *max_ack)
> @@ -421,13 +421,13 @@ pri:
>  if (g_queue_is_empty(>primary_list)) {
>  return;
>  }
> -ppkt = g_queue_pop_head(>primary_list);
> +ppkt = g_queue_pop_tail(>primary_list);
>  sec:
>  if (g_queue_is_empty(>secondary_list)) {
> -g_queue_push_head(>primary_list, ppkt);
> +g_queue_push_tail(>primary_list, ppkt);
>  return;
>  }
> -spkt = g_queue_pop_head(>secondary_list);
> +spkt = g_queue_pop_tail(>secondary_list);
>
>  if (ppkt->tcp_seq == ppkt->seq_end) {
>  colo_release_primary_pkt(s, ppkt);
> @@ -458,7 +458,7 @@ sec:
>  }
>  }
>  if (!ppkt) {
> -g_queue_push_head(>secondary_list, spkt);
> +g_queue_push_tail(>secondary_list, spkt);
>  goto pri;
>  }
>  }
> @@ -477,7 +477,7 @@ sec:
>  if (mark == COLO_COMPARE_FREE_PRIMARY) {
>  conn->compare_seq = ppkt->seq_end;
>  colo_release_primary_pkt(s, ppkt);
> -g_queue_push_head(>secondary_list, spkt);
> +g_queue_push_tail(>secondary_list, spkt);
>  goto pri;
>  } else if (mark == COLO_COMPARE_FREE_SECONDARY) {
>  conn->compare_seq = spkt->seq_end;
> @@ -490,8 +490,8 @@ sec:
>  goto pri;
>  }
>  } else {
> -g_queue_push_head(>primary_list, ppkt);
> -g_queue_push_head(>secondary_list, spkt);
> +g_queue_push_tail(>primary_list, ppkt);
> +g_queue_push_tail(>secondary_list, spkt);
>
>  #ifdef DEBUG_COLO_PACKETS
>  qemu_hexdump(stderr, "colo-compare ppkt", ppkt->data, ppkt->size);
> @@ -673,7 +673,7 @@ static void colo_compare_packet(CompareState *s, 
> Connection *conn,
>
>  while (!g_queue_is_empty(>primary_list) &&
> !g_queue_is_empty(>secondary_list)) {
> -pkt = g_queue_pop_head(>primary_list);
> +pkt = g_queue_pop_tail(>primary_list);
>  result = g_queue_find_custom(>secondary_list,
>   pkt, (GCompareFunc)HandlePacket);
>
> @@ -689,7 +689,7 @@ static void colo_compare_packet(CompareState *s, 
> Connection *conn,
>   * timeout, it will trigger a checkpoint request.
>   */
>  trace_colo_compare_main("packet different");
> -g_queue_push_head(>primary_list, pkt);
> +g_queue_push_tail(>primary_list, pkt);
>
>  colo_compare_inconsistency_notify(s);
>  break;
> @@ -819,7 +819,7 @@ static int compare_chr_send(CompareState *s,
>  entry->buf = g_malloc(size);
>  memcpy(entry->buf, buf, size);
>  }
> -g_queue_push_head(>send_list, entry);
> +g_queue_push_tail(>send_list, entry);
>
>  if (sendco->done) {
>  sendco->co = qemu_coroutine_create(_compare_chr_send, sendco);
> @@ -1347,7 +1347,7 @@ static void colo_flush_packets(void *opaque, void 
> *user_data)
>  Packet *pkt = NULL;
>
>  while (!g_queue_is_empty(>primary_list)) {
> -pkt = g_queue_pop_head(>primary_list);
> +pkt = g_queue_pop_tail(>primary_list);
>  compare_chr_send(s,
>   pkt->data,
>   pkt->size,
> @@ -1357,7 +1357,7 @@ static void colo_flush_packets(void *opaque, void 
> *user_data)
>  packet_destroy_partial(pkt, NULL);
>  }
>  while (!g_queue_is_empty(>secondary_list)) {
> -pkt = g_queue_pop_head(>secondary_list);
> +pkt = g_queue_pop_tail(>secondary_list);
>  packet_destroy(pkt, NULL);
>  }
>  }
> --
> 2.25.1
>




Re: [PATCH v2] net/filter: Optimize filter_send to coroutine

2022-01-06 Thread Jason Wang
On Mon, Dec 27, 2021 at 10:14 AM Zhang, Chen  wrote:
>
>
>
> > -Original Message-
> > From: Rao, Lei 
> > Sent: Monday, December 27, 2021 9:20 AM
> > To: Zhang, Chen ; lizhij...@cn.fujitsu.com;
> > jasow...@redhat.com
> > Cc: qemu-devel@nongnu.org; Rao, Lei ; Li Zhijian
> > 
> > Subject: [PATCH v2] net/filter: Optimize filter_send to coroutine
> >
> > This patch is to improve the logic of QEMU main thread sleep code in
> > qemu_chr_write_buffer() where it can be blocked and can't run other
> > coroutines during COLO IO stress test.
> >
> > Our approach is to put filter_send() in a coroutine. In this way,
> > filter_send() will call qemu_coroutine_yield() in qemu_co_sleep_ns(), so
> > that it can be scheduled out and QEMU main thread has opportunity to run
> > other tasks.
> >
> > Signed-off-by: Lei Rao 
> > Signed-off-by: Zhang Chen 
> > Reviewed-by: Li Zhijian 
>
> Looks good to me.
> Reviewed-by: Zhang Chen 

Applied.

Thanks

>
> Thanks
> Chen
>
> > ---
> >  net/filter-mirror.c | 66 
> > -
> >  1 file changed, 53 insertions(+), 13 deletions(-)
> >
> > diff --git a/net/filter-mirror.c b/net/filter-mirror.c index
> > f20240cc9f..34a63b5dbb 100644
> > --- a/net/filter-mirror.c
> > +++ b/net/filter-mirror.c
> > @@ -20,6 +20,7 @@
> >  #include "chardev/char-fe.h"
> >  #include "qemu/iov.h"
> >  #include "qemu/sockets.h"
> > +#include "block/aio-wait.h"
> >
> >  #define TYPE_FILTER_MIRROR "filter-mirror"
> >  typedef struct MirrorState MirrorState; @@ -42,20 +43,21 @@ struct
> > MirrorState {
> >  bool vnet_hdr;
> >  };
> >
> > -static int filter_send(MirrorState *s,
> > -   const struct iovec *iov,
> > -   int iovcnt)
> > +typedef struct FilterSendCo {
> > +MirrorState *s;
> > +char *buf;
> > +ssize_t size;
> > +bool done;
> > +int ret;
> > +} FilterSendCo;
> > +
> > +static int _filter_send(MirrorState *s,
> > +   char *buf,
> > +   ssize_t size)
> >  {
> >  NetFilterState *nf = NETFILTER(s);
> >  int ret = 0;
> > -ssize_t size = 0;
> >  uint32_t len = 0;
> > -char *buf;
> > -
> > -size = iov_size(iov, iovcnt);
> > -if (!size) {
> > -return 0;
> > -}
> >
> >  len = htonl(size);
> >  ret = qemu_chr_fe_write_all(>chr_out, (uint8_t *), sizeof(len));
> > @@ -80,10 +82,7 @@ static int filter_send(MirrorState *s,
> >  }
> >  }
> >
> > -buf = g_malloc(size);
> > -iov_to_buf(iov, iovcnt, 0, buf, size);
> >  ret = qemu_chr_fe_write_all(>chr_out, (uint8_t *)buf, size);
> > -g_free(buf);
> >  if (ret != size) {
> >  goto err;
> >  }
> > @@ -94,6 +93,47 @@ err:
> >  return ret < 0 ? ret : -EIO;
> >  }
> >
> > +static void coroutine_fn filter_send_co(void *opaque) {
> > +FilterSendCo *data = opaque;
> > +
> > +data->ret = _filter_send(data->s, data->buf, data->size);
> > +data->done = true;
> > +g_free(data->buf);
> > +aio_wait_kick();
> > +}
> > +
> > +static int filter_send(MirrorState *s,
> > +   const struct iovec *iov,
> > +   int iovcnt)
> > +{
> > +ssize_t size = iov_size(iov, iovcnt);
> > +char *buf = NULL;
> > +
> > +if (!size) {
> > +return 0;
> > +}
> > +
> > +buf = g_malloc(size);
> > +iov_to_buf(iov, iovcnt, 0, buf, size);
> > +
> > +FilterSendCo data = {
> > +.s = s,
> > +.size = size,
> > +.buf = buf,
> > +.ret = 0,
> > +};
> > +
> > +Coroutine *co = qemu_coroutine_create(filter_send_co, );
> > +qemu_coroutine_enter(co);
> > +
> > +while (!data.done) {
> > +aio_poll(qemu_get_aio_context(), true);
> > +}
> > +
> > +return data.ret;
> > +}
> > +
> >  static void redirector_to_filter(NetFilterState *nf,
> >   const uint8_t *buf,
> >   int len)
> > --
> > 2.32.0
>




Re: [PATCH v14 18/26] linux-user: Add LoongArch specific structures

2022-01-06 Thread Richard Henderson

On 1/6/22 1:41 AM, Song Gao wrote:

Signed-off-by: Song Gao
Signed-off-by: Xiaojuan Yang
---
  linux-user/loongarch64/target_structs.h | 47 +
  1 file changed, 47 insertions(+)
  create mode 100644 linux-user/loongarch64/target_structs.h


I've just sent a patch set such that this need be nothing but a re-include of 
generic/target_structs.h.



r~



[PATCH 2/2] linux-user: Move target_struct.h generic definitions to generic/

2022-01-06 Thread Richard Henderson
Most targets share the same generic ipc structure definitions.

Signed-off-by: Richard Henderson 
---
 linux-user/aarch64/target_structs.h| 59 +-
 linux-user/arm/target_structs.h| 52 +--
 linux-user/cris/target_structs.h   | 59 +-
 linux-user/generic/target_structs.h| 58 +
 linux-user/hexagon/target_structs.h| 55 +---
 linux-user/i386/target_structs.h   | 59 +-
 linux-user/m68k/target_structs.h   | 59 +-
 linux-user/microblaze/target_structs.h | 59 +-
 linux-user/nios2/target_structs.h  | 59 +-
 linux-user/openrisc/target_structs.h   | 59 +-
 linux-user/riscv/target_structs.h  | 47 +---
 linux-user/sh4/target_structs.h| 59 +-
 linux-user/x86_64/target_structs.h | 36 +---
 13 files changed, 70 insertions(+), 650 deletions(-)
 create mode 100644 linux-user/generic/target_structs.h

diff --git a/linux-user/aarch64/target_structs.h 
b/linux-user/aarch64/target_structs.h
index 7c748344ca..3a06f373c3 100644
--- a/linux-user/aarch64/target_structs.h
+++ b/linux-user/aarch64/target_structs.h
@@ -1,58 +1 @@
-/*
- * ARM AArch64 specific structures for linux-user
- *
- * Copyright (c) 2013 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see .
- */
-#ifndef AARCH64_TARGET_STRUCTS_H
-#define AARCH64_TARGET_STRUCTS_H
-
-struct target_ipc_perm {
-abi_int __key;  /* Key.  */
-abi_uint uid;   /* Owner's user ID.  */
-abi_uint gid;   /* Owner's group ID.  */
-abi_uint cuid;  /* Creator's user ID.  */
-abi_uint cgid;  /* Creator's group ID.  */
-abi_ushort mode;/* Read/write permission.  */
-abi_ushort __pad1;
-abi_ushort __seq;   /* Sequence number.  */
-abi_ushort __pad2;
-abi_ulong __unused1;
-abi_ulong __unused2;
-};
-
-struct target_shmid_ds {
-struct target_ipc_perm shm_perm;/* operation permission struct */
-abi_long shm_segsz; /* size of segment in bytes */
-abi_ulong shm_atime;/* time of last shmat() */
-#if TARGET_ABI_BITS == 32
-abi_ulong __unused1;
-#endif
-abi_ulong shm_dtime;/* time of last shmdt() */
-#if TARGET_ABI_BITS == 32
-abi_ulong __unused2;
-#endif
-abi_ulong shm_ctime;/* time of last change by shmctl() */
-#if TARGET_ABI_BITS == 32
-abi_ulong __unused3;
-#endif
-abi_int shm_cpid;   /* pid of creator */
-abi_int shm_lpid;   /* pid of last shmop */
-abi_ulong shm_nattch;   /* number of current attaches */
-abi_ulong __unused4;
-abi_ulong __unused5;
-};
-
-#endif
+#include "../generic/target_structs.h"
diff --git a/linux-user/arm/target_structs.h b/linux-user/arm/target_structs.h
index 25bf8dd3a5..3a06f373c3 100644
--- a/linux-user/arm/target_structs.h
+++ b/linux-user/arm/target_structs.h
@@ -1,51 +1 @@
-/*
- * ARM specific structures for linux-user
- *
- * Copyright (c) 2013 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see .
- */
-#ifndef ARM_TARGET_STRUCTS_H
-#define ARM_TARGET_STRUCTS_H
-
-struct target_ipc_perm {
-abi_int __key;  /* Key.  */
-abi_uint uid;   /* Owner's user ID.  */
-abi_uint gid;   /* Owner's group ID.  */
-abi_uint cuid;  /* Creator's user ID.  */
-  

[PATCH 1/2] linux-user/arm: Move target_oabi_flock64 out of target_structs.h

2022-01-06 Thread Richard Henderson
Place it next to copy_from/to_user_oabi_flock64, the only users,
inside the existing target-specific ifdef.  This leaves only
generic ipc structs in target_structs.h.

Signed-off-by: Richard Henderson 
---
 linux-user/arm/target_structs.h | 8 
 linux-user/syscall.c| 8 
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/linux-user/arm/target_structs.h b/linux-user/arm/target_structs.h
index 339b070bf1..25bf8dd3a5 100644
--- a/linux-user/arm/target_structs.h
+++ b/linux-user/arm/target_structs.h
@@ -48,12 +48,4 @@ struct target_shmid_ds {
 abi_ulong __unused4;
 abi_ulong __unused5;
 };
-
-struct target_oabi_flock64 {
-abi_short l_type;
-abi_short l_whence;
-abi_llong l_start;
-abi_llong l_len;
-abi_int   l_pid;
-} QEMU_PACKED;
 #endif
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index ce9d64896c..ca6e0b8fb0 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6927,6 +6927,14 @@ typedef abi_long from_flock64_fn(struct flock64 *fl, 
abi_ulong target_addr);
 typedef abi_long to_flock64_fn(abi_ulong target_addr, const struct flock64 
*fl);
 
 #if defined(TARGET_ARM) && TARGET_ABI_BITS == 32
+struct target_oabi_flock64 {
+abi_short l_type;
+abi_short l_whence;
+abi_llong l_start;
+abi_llong l_len;
+abi_int   l_pid;
+} QEMU_PACKED;
+
 static inline abi_long copy_from_user_oabi_flock64(struct flock64 *fl,
abi_ulong target_flock_addr)
 {
-- 
2.25.1




[PATCH 0/2] linux-user: Move target_struct.h generic definitions to generic/

2022-01-06 Thread Richard Henderson
I noticed this while reviewing loongarch64.

r~

Richard Henderson (2):
  linux-user/arm: Move target_oabi_flock64 out of target_structs.h
  linux-user: Move target_struct.h generic definitions to generic/

 linux-user/aarch64/target_structs.h| 59 +
 linux-user/arm/target_structs.h| 60 +-
 linux-user/cris/target_structs.h   | 59 +
 linux-user/generic/target_structs.h| 58 +
 linux-user/hexagon/target_structs.h| 55 +--
 linux-user/i386/target_structs.h   | 59 +
 linux-user/m68k/target_structs.h   | 59 +
 linux-user/microblaze/target_structs.h | 59 +
 linux-user/nios2/target_structs.h  | 59 +
 linux-user/openrisc/target_structs.h   | 59 +
 linux-user/riscv/target_structs.h  | 47 +---
 linux-user/sh4/target_structs.h| 59 +
 linux-user/x86_64/target_structs.h | 36 +---
 linux-user/syscall.c   |  8 
 14 files changed, 78 insertions(+), 658 deletions(-)
 create mode 100644 linux-user/generic/target_structs.h

-- 
2.25.1




Re: [PATCH v4 0/3] RISC-V: Populate mtval and stval

2022-01-06 Thread Alistair Francis
On Mon, Dec 20, 2021 at 4:49 PM Alistair Francis
 wrote:
>
> From: Alistair Francis 
>
> Populate mtval and stval when taking an illegal instruction exception.
>
> The RISC-V spec states that "The stval register can optionally also be
> used to return the faulting instruction bits on an illegal instruction
> exception...". In this case we are always writing the value on an
> illegal instruction.
>
> This doesn't match all CPUs (some CPUs won't write the data), but in
> QEMU let's just populate the value on illegal instructions. This won't
> break any guest software, but will provide more information to guests.
>
> Alistair Francis (3):
>   target/riscv: Set the opcode in DisasContext
>   target/riscv: Fixup setting GVA
>   target/riscv: Implement the stval/mtval illegal instruction

Thanks!

Applied to riscv-to-apply.next

Alistair

>
>  target/riscv/cpu.h|  2 ++
>  target/riscv/cpu_helper.c | 24 +---
>  target/riscv/translate.c  |  5 +
>  3 files changed, 16 insertions(+), 15 deletions(-)
>
> --
> 2.31.1
>



Re: [PATCH v2 3/7] target/ppc: powerpc_excp: Group unimplemented exceptions

2022-01-06 Thread Richard Henderson

On 1/5/22 12:40 PM, Fabiano Rosas wrote:

Signed-off-by: Fabiano Rosas
Reviewed-by: Cédric Le Goater
---
  target/ppc/excp_helper.c | 77 +---
  1 file changed, 8 insertions(+), 69 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [RFC 02/10] vhost: add 3 commands for vhost-vdpa

2022-01-06 Thread Jason Wang



在 2022/1/6 下午10:09, Michael S. Tsirkin 写道:

On Thu, Jan 06, 2022 at 10:34:20AM +0800, Jason Wang wrote:

On Wed, Jan 5, 2022 at 8:26 PM Michael S. Tsirkin  wrote:

On Wed, Jan 05, 2022 at 05:09:07PM +0800, Jason Wang wrote:

On Wed, Jan 5, 2022 at 4:37 PM Longpeng (Mike, Cloud Infrastructure
Service Product Dept.)  wrote:




-Original Message-
From: Jason Wang [mailto:jasow...@redhat.com]
Sent: Wednesday, January 5, 2022 3:54 PM
To: Michael S. Tsirkin 
Cc: Longpeng (Mike, Cloud Infrastructure Service Product Dept.)
; Stefan Hajnoczi ; Stefano
Garzarella ; Cornelia Huck ; pbonzini
; Gonglei (Arei) ; Yechuan
; Huangzhichao ; qemu-devel

Subject: Re: [RFC 02/10] vhost: add 3 commands for vhost-vdpa

On Wed, Jan 5, 2022 at 3:02 PM Michael S. Tsirkin  wrote:

On Wed, Jan 05, 2022 at 12:35:53PM +0800, Jason Wang wrote:

On Wed, Jan 5, 2022 at 8:59 AM Longpeng(Mike)  wrote:

From: Longpeng 

To support generic vdpa deivce, we need add the following ioctls:
- GET_VECTORS_NUM: the count of vectors that supported

Does this mean MSI vectors? If yes, it looks like a layer violation:
vhost is transport independent.

Well *guest* needs to know how many vectors device supports.
I don't think there's a way around that. Do you?

We have VHOST_SET_VRING/CONFIG_CALL which is per vq. I think we can
simply assume #vqs + 1?


Otherwise guests will at best be suboptimal.


  And it reveals device implementation
details which block (cross vendor) migration.

Thanks

Not necessarily, userspace can hide this from guest if it
wants to, just validate.

If we can hide it at vhost/uAPI level, it would be even better?


Not only MSI vectors, but also queue-size, #vqs, etc.

MSI is PCI specific, we have non PCI vDPA parent e.g VDUSE/simulator/mlx5

And it's something that is not guaranteed to be not changed. E.g some
drivers may choose to allocate MSI during set_status() which can fail
for various reasons.


Maybe the vhost level could expose the hardware's real capabilities
and let the userspace (QEMU) do the hiding? The userspace know how
to process them.

#MSI vectors is much more easier to be mediated than queue-size and #vqs.

For interrupts, we've already had VHOST_SET_X_KICK, we can keep
allocating eventfd based on #MSI vectors to make it work with any
number of MSI vectors that the virtual device had.

Right but if hardware does not support so many then what?
Just fail?

Or just trigger the callback of vqs that shares the vector.


Right but we want userspace to be able to report this to guest accurately
if it wants to. Guest can then configure itself correctly.



Having a query API would make things somewhat cleaner imho.

I may miss something,  even if we know #vectors, we still don't know
the associated virtqueues for a dedicated vector?

This is up to the guest.



Just to clarify the possible issue, this only works if vDPA parent is 
using the same irq binding policy as what viritio-pci did in the guest.


Consider vDPA has 3 vectors allocated:

host vector 0: tx/rx
host vector 1: cvq
host vector 2: config

So we return 3 for get_vectors. So the virtual device will have 3 
vectors in this case.


But a guest driver may do:

guest vector 0: tx (eventfd0)
guest vector 1: rx (eventfd1)
guest vector 2: cvq/config (eventfd2)

The irq handler of host vector0 will notify both eventfd0(guest vector0) 
and eventfd1(guest vector1) in this case.


And using such "vectors passthrough" may block migration between the 
vDPA device where the #vectors is the only difference.


Thanks





For queue-size, it's Ok to have a new uAPI but it's not a must, Qemu
can simply fail if SET_VRING_NUM fail.

For #vqs, it's OK to have a new uAPI since the emulated virtio-pci
device requires knowledge the #vqs in the config space. (still not a
must, we can enumerate #vqs per device type)

For the config size, it's OK but not a must, technically we can simply
relay what guest write to vhost-vdpa. It's just because current Qemu
require to have it during virtio device initialization.

Thanks


I agree but these ok things make for a cleaner API I think.

Right.

Thanks


Thanks




- GET_CONFIG_SIZE: the size of the virtio config space
- GET_VQS_NUM: the count of virtqueues that exported

Signed-off-by: Longpeng 
---
  linux-headers/linux/vhost.h | 10 ++
  1 file changed, 10 insertions(+)

diff --git a/linux-headers/linux/vhost.h b/linux-headers/linux/vhost.h
index c998860d7b..c5edd75d15 100644
--- a/linux-headers/linux/vhost.h
+++ b/linux-headers/linux/vhost.h
@@ -150,4 +150,14 @@
  /* Get the valid iova range */
  #define VHOST_VDPA_GET_IOVA_RANGE  _IOR(VHOST_VIRTIO, 0x78, \
  struct vhost_vdpa_iova_range)
+
+/* Get the number of vectors */
+#define VHOST_VDPA_GET_VECTORS_NUM _IOR(VHOST_VIRTIO, 0x79, int)
+
+/* Get the virtio config size */
+#define VHOST_VDPA_GET_CONFIG_SIZE _IOR(VHOST_VIRTIO, 0x80, int)
+
+/* Get the number of virtqueues */
+#define VHOST_VDPA_GET_VQS_NUM   

Re: [RFC 02/10] vhost: add 3 commands for vhost-vdpa

2022-01-06 Thread Jason Wang



在 2022/1/6 下午4:00, Longpeng (Mike, Cloud Infrastructure Service Product 
Dept.) 写道:

-Original Message-
From: Jason Wang [mailto:jasow...@redhat.com]
Sent: Thursday, January 6, 2022 10:34 AM
To: Michael S. Tsirkin
Cc: Longpeng (Mike, Cloud Infrastructure Service Product Dept.)
; Stefan Hajnoczi; Stefano
Garzarella; Cornelia Huck; pbonzini
; Gonglei (Arei); Yechuan
; Huangzhichao; qemu-devel

Subject: Re: [RFC 02/10] vhost: add 3 commands for vhost-vdpa

On Wed, Jan 5, 2022 at 8:26 PM Michael S. Tsirkin  wrote:

On Wed, Jan 05, 2022 at 05:09:07PM +0800, Jason Wang wrote:

On Wed, Jan 5, 2022 at 4:37 PM Longpeng (Mike, Cloud Infrastructure
Service Product Dept.)  wrote:



-Original Message-
From: Jason Wang [mailto:jasow...@redhat.com]
Sent: Wednesday, January 5, 2022 3:54 PM
To: Michael S. Tsirkin
Cc: Longpeng (Mike, Cloud Infrastructure Service Product Dept.)
; Stefan Hajnoczi; Stefano
Garzarella; Cornelia Huck;

pbonzini

; Gonglei (Arei); Yechuan
; Huangzhichao;

qemu-devel


Subject: Re: [RFC 02/10] vhost: add 3 commands for vhost-vdpa

On Wed, Jan 5, 2022 at 3:02 PM Michael S. Tsirkin  wrote:

On Wed, Jan 05, 2022 at 12:35:53PM +0800, Jason Wang wrote:

On Wed, Jan 5, 2022 at 8:59 AM Longpeng(Mike)

wrote:

From: Longpeng

To support generic vdpa deivce, we need add the following ioctls:
- GET_VECTORS_NUM: the count of vectors that supported

Does this mean MSI vectors? If yes, it looks like a layer violation:
vhost is transport independent.

Well*guest*  needs to know how many vectors device supports.
I don't think there's a way around that. Do you?

We have VHOST_SET_VRING/CONFIG_CALL which is per vq. I think we can
simply assume #vqs + 1?


Otherwise guests will at best be suboptimal.


  And it reveals device implementation
details which block (cross vendor) migration.

Thanks

Not necessarily, userspace can hide this from guest if it
wants to, just validate.

If we can hide it at vhost/uAPI level, it would be even better?


Not only MSI vectors, but also queue-size, #vqs, etc.

MSI is PCI specific, we have non PCI vDPA parent e.g VDUSE/simulator/mlx5

And it's something that is not guaranteed to be not changed. E.g some
drivers may choose to allocate MSI during set_status() which can fail
for various reasons.


Maybe the vhost level could expose the hardware's real capabilities
and let the userspace (QEMU) do the hiding? The userspace know how
to process them.

#MSI vectors is much more easier to be mediated than queue-size and #vqs.

For interrupts, we've already had VHOST_SET_X_KICK, we can keep
allocating eventfd based on #MSI vectors to make it work with any
number of MSI vectors that the virtual device had.

Right but if hardware does not support so many then what?
Just fail?

Or just trigger the callback of vqs that shares the vector.


Then we should disable PI if we need to share a vector in this case?



I may miss something, but I don't see any reason for doing this. I think 
the irqbypass manager and the arch specific PI codes should deal with 
this case.


Ling Shan (cced) told me it works in the past.

Thanks









Re: [PATCH] net: Fix uninitialized data usage

2022-01-06 Thread Jason Wang
On Fri, Jan 7, 2022 at 3:44 AM Philippe Mathieu-Daudé  wrote:
>
> On 6/1/22 19:28, Patrick Venture wrote:
> > From: Peter Foley 
> >
> > e.g.
> > 1109 15:16:20.151506 Uninitialized bytes in ioctl_common_pre at offset 0 
> > inside [0x7ffc516af9b8, 4)
> >   1109 15:16:20.151659 ==588974==WARNING: MemorySanitizer: 
> > use-of-uninitialized-value
> >   1109 15:16:20.312923 #0 0x5639b88acb21 in tap_probe_vnet_hdr_len 
> > third_party/qemu/net/tap-linux.c:183:9
> >   1109 15:16:20.312952 #1 0x5639b88afd66 in net_tap_fd_init 
> > third_party/qemu/net/tap.c:409:9
> >   1109 15:16:20.312954 #2 0x5639b88b2d1b in net_init_tap_one 
> > third_party/qemu/net/tap.c:681:19
> >   1109 15:16:20.312956 #3 0x5639b88b16a8 in net_init_tap 
> > third_party/qemu/net/tap.c:912:13
> >   1109 15:16:20.312957 #4 0x5639b8890175 in net_client_init1 
> > third_party/qemu/net/net.c:1110:9
> >   1109 15:16:20.312958 #5 0x5639b888f912 in net_client_init 
> > third_party/qemu/net/net.c:1208:15
> >   1109 15:16:20.312960 #6 0x5639b8894aa5 in net_param_nic 
> > third_party/qemu/net/net.c:1588:11
> >   1109 15:16:20.312961 #7 0x5639b900cd18 in qemu_opts_foreach 
> > third_party/qemu/util/qemu-option.c:1135:14
> >   1109 15:16:20.312962 #8 0x5639b889393c in net_init_clients 
> > third_party/qemu/net/net.c:1612:9
> >   1109 15:16:20.312964 #9 0x5639b717aaf3 in qemu_create_late_backends 
> > third_party/qemu/softmmu/vl.c:1962:5
> >   1109 15:16:20.312965 #10 0x5639b717aaf3 in qemu_init 
> > third_party/qemu/softmmu/vl.c:3694:5
> >   1109 15:16:20.312967 #11 0x5639b71083b8 in main 
> > third_party/qemu/softmmu/main.c:49:5
> >   1109 15:16:20.312968 #12 0x7f464de1d8d2 in __libc_start_main 
> > (/usr/grte/v5/lib64/libc.so.6+0x628d2)
> >   1109 15:16:20.312969 #13 0x5639b6bbd389 in _start 
> > /usr/grte/v5/debug-src/src/csu/../sysdeps/x86_64/start.S:120
> >   1109 15:16:20.312970
> >   1109 15:16:20.312975   Uninitialized value was stored to memory at
> >   1109 15:16:20.313393 #0 0x5639b88acbee in tap_probe_vnet_hdr_len 
> > third_party/qemu/net/tap-linux.c
> >   1109 15:16:20.313396 #1 0x5639b88afd66 in net_tap_fd_init 
> > third_party/qemu/net/tap.c:409:9
> >   1109 15:16:20.313398 #2 0x5639b88b2d1b in net_init_tap_one 
> > third_party/qemu/net/tap.c:681:19
> >   1109 15:16:20.313399 #3 0x5639b88b16a8 in net_init_tap 
> > third_party/qemu/net/tap.c:912:13
> >   1109 15:16:20.313400 #4 0x5639b8890175 in net_client_init1 
> > third_party/qemu/net/net.c:1110:9
> >   1109 15:16:20.313401 #5 0x5639b888f912 in net_client_init 
> > third_party/qemu/net/net.c:1208:15
> >   1109 15:16:20.313403 #6 0x5639b8894aa5 in net_param_nic 
> > third_party/qemu/net/net.c:1588:11
> >   1109 15:16:20.313404 #7 0x5639b900cd18 in qemu_opts_foreach 
> > third_party/qemu/util/qemu-option.c:1135:14
> >   1109 15:16:20.313405 #8 0x5639b889393c in net_init_clients 
> > third_party/qemu/net/net.c:1612:9
> >   1109 15:16:20.313407 #9 0x5639b717aaf3 in qemu_create_late_backends 
> > third_party/qemu/softmmu/vl.c:1962:5
> >   1109 15:16:20.313408 #10 0x5639b717aaf3 in qemu_init 
> > third_party/qemu/softmmu/vl.c:3694:5
> >   1109 15:16:20.313409 #11 0x5639b71083b8 in main 
> > third_party/qemu/softmmu/main.c:49:5
> >   1109 15:16:20.313410 #12 0x7f464de1d8d2 in __libc_start_main 
> > (/usr/grte/v5/lib64/libc.so.6+0x628d2)
> >   1109 15:16:20.313412 #13 0x5639b6bbd389 in _start 
> > /usr/grte/v5/debug-src/src/csu/../sysdeps/x86_64/start.S:120
> >   1109 15:16:20.313413
> >   1109 15:16:20.313417   Uninitialized value was stored to memory at
> >   1109 15:16:20.313791 #0 0x5639b88affbd in net_tap_fd_init 
> > third_party/qemu/net/tap.c:400:26
> >   1109 15:16:20.313826 #1 0x5639b88b2d1b in net_init_tap_one 
> > third_party/qemu/net/tap.c:681:19
> >   1109 15:16:20.313829 #2 0x5639b88b16a8 in net_init_tap 
> > third_party/qemu/net/tap.c:912:13
> >   1109 15:16:20.313831 #3 0x5639b8890175 in net_client_init1 
> > third_party/qemu/net/net.c:1110:9
> >   1109 15:16:20.313836 #4 0x5639b888f912 in net_client_init 
> > third_party/qemu/net/net.c:1208:15
> >   1109 15:16:20.313838 #5 0x5639b8894aa5 in net_param_nic 
> > third_party/qemu/net/net.c:1588:11
> >   1109 15:16:20.313839 #6 0x5639b900cd18 in qemu_opts_foreach 
> > third_party/qemu/util/qemu-option.c:1135:14
> >   1109 15:16:20.313841 #7 0x5639b889393c in net_init_clients 
> > third_party/qemu/net/net.c:1612:9
> >   1109 15:16:20.313843 #8 0x5639b717aaf3 in qemu_create_late_backends 
> > third_party/qemu/softmmu/vl.c:1962:5
> >   1109 15:16:20.313844 #9 0x5639b717aaf3 in qemu_init 
> > third_party/qemu/softmmu/vl.c:3694:5
> >   1109 15:16:20.313845 #10 0x5639b71083b8 in main 
> > third_party/qemu/softmmu/main.c:49:5
> >   1109 15:16:20.313846 #11 0x7f464de1d8d2 in __libc_start_main 
> > (/usr/grte/v5/lib64/libc.so.6+0x628d2)
> >   1109 15:16:20.313847 #12 

[PATCH v4 10/11] target/riscv: Add few cache related PMU events

2022-01-06 Thread Atish Patra
From: Atish Patra 

Qemu can monitor the following cache related PMU events through
tlb_fill functions.

1. DTLB load/store miss
3. ITLB prefetch miss

Increment the PMU counter in tlb_fill function.

Signed-off-by: Atish Patra 
Signed-off-by: Atish Patra 
---
 target/riscv/cpu_helper.c | 26 ++
 1 file changed, 26 insertions(+)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 10f3baba5339..bd7871f7b92f 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -21,10 +21,13 @@
 #include "qemu/log.h"
 #include "qemu/main-loop.h"
 #include "cpu.h"
+#include "pmu.h"
 #include "exec/exec-all.h"
 #include "tcg/tcg-op.h"
 #include "trace.h"
 #include "semihosting/common-semi.h"
+#include "cpu.h"
+#include "cpu_bits.h"
 
 int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
 {
@@ -846,6 +849,28 @@ void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr 
addr,
 riscv_raise_exception(env, cs->exception_index, retaddr);
 }
 
+
+static void pmu_tlb_fill_incr_ctr(RISCVCPU *cpu, MMUAccessType access_type)
+{
+enum riscv_pmu_event_idx pmu_event_type;
+
+switch (access_type) {
+case MMU_INST_FETCH:
+pmu_event_type = RISCV_PMU_EVENT_CACHE_ITLB_PREFETCH_MISS;
+break;
+case MMU_DATA_LOAD:
+pmu_event_type = RISCV_PMU_EVENT_CACHE_DTLB_READ_MISS;
+break;
+case MMU_DATA_STORE:
+pmu_event_type = RISCV_PMU_EVENT_CACHE_DTLB_WRITE_MISS;
+break;
+default:
+return;
+}
+
+riscv_pmu_incr_ctr(cpu, pmu_event_type);
+}
+
 bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
 MMUAccessType access_type, int mmu_idx,
 bool probe, uintptr_t retaddr)
@@ -942,6 +967,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 }
 }
 } else {
+pmu_tlb_fill_incr_ctr(cpu, access_type);
 /* Single stage lookup */
 ret = get_physical_address(env, , , address, NULL,
access_type, mmu_idx, true, false, false);
-- 
2.30.2




[PATCH v4 11/11] hw/riscv: virt: Add PMU DT node to the device tree

2022-01-06 Thread Atish Patra
Qemu virt machine can support few cache events and cycle/instret counters.
It also supports counter overflow for these events.

Add a DT node so that OpenSBI/Linux kernel is aware of the virt machine
capabilities. There are some dummy nodes added for testing as well.

Signed-off-by: Atish Patra 
Signed-off-by: Atish Patra 
---
 hw/riscv/virt.c| 38 ++
 target/riscv/pmu.c | 45 +
 target/riscv/pmu.h |  1 +
 3 files changed, 84 insertions(+)

diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 3af074148ef4..99154199091c 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -28,6 +28,7 @@
 #include "hw/qdev-properties.h"
 #include "hw/char/serial.h"
 #include "target/riscv/cpu.h"
+#include "target/riscv/pmu.h"
 #include "hw/riscv/riscv_hart.h"
 #include "hw/riscv/virt.h"
 #include "hw/riscv/boot.h"
@@ -406,6 +407,33 @@ static void create_fdt_socket_plic(RISCVVirtState *s,
 g_free(plic_cells);
 }
 
+static void create_fdt_socket_pmu(RISCVVirtState *s,
+  int socket, uint32_t *phandle,
+  uint32_t *intc_phandles)
+{
+int cpu;
+char *pmu_name;
+uint32_t *pmu_cells;
+MachineState *mc = MACHINE(s);
+RISCVCPU hart = s->soc[socket].harts[0];
+
+pmu_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2);
+
+for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
+pmu_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
+pmu_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_PMU_OVF);
+}
+
+pmu_name = g_strdup_printf("/soc/pmu");
+qemu_fdt_add_subnode(mc->fdt, pmu_name);
+qemu_fdt_setprop_string(mc->fdt, pmu_name, "compatible", "riscv,pmu");
+riscv_pmu_generate_fdt_node(mc->fdt, hart.cfg.pmu_num, pmu_name);
+
+g_free(pmu_name);
+g_free(pmu_cells);
+}
+
+
 static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
bool is_32_bit, uint32_t *phandle,
uint32_t *irq_mmio_phandle,
@@ -417,12 +445,20 @@ static void create_fdt_sockets(RISCVVirtState *s, const 
MemMapEntry *memmap,
 uint32_t *intc_phandles;
 MachineState *mc = MACHINE(s);
 uint32_t xplic_phandles[MAX_NODES];
+RISCVCPU hart;
 
 qemu_fdt_add_subnode(mc->fdt, "/cpus");
 qemu_fdt_setprop_cell(mc->fdt, "/cpus", "timebase-frequency",
   RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ);
 qemu_fdt_setprop_cell(mc->fdt, "/cpus", "#size-cells", 0x0);
 qemu_fdt_setprop_cell(mc->fdt, "/cpus", "#address-cells", 0x1);
+
+/* Add the node for isa extensions discovery */
+qemu_fdt_add_subnode(mc->fdt, "/cpus/riscv,isa-ext");
+hart = s->soc[0].harts[0];
+if (hart.cfg.ext_sscof) {
+qemu_fdt_setprop(mc->fdt, "/cpus/riscv,isa-ext", "sscofpmf", NULL, 0);
+}
 qemu_fdt_add_subnode(mc->fdt, "/cpus/cpu-map");
 
 for (socket = (riscv_socket_count(mc) - 1); socket >= 0; socket--) {
@@ -445,6 +481,8 @@ static void create_fdt_sockets(RISCVVirtState *s, const 
MemMapEntry *memmap,
 create_fdt_socket_plic(s, memmap, socket, phandle,
 intc_phandles, xplic_phandles);
 
+create_fdt_socket_pmu(s, socket, phandle, intc_phandles);
+
 g_free(intc_phandles);
 g_free(clust_name);
 }
diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
index 15f161059fb7..b58a09c85616 100644
--- a/target/riscv/pmu.c
+++ b/target/riscv/pmu.c
@@ -19,11 +19,56 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "pmu.h"
+#include "sysemu/device_tree.h"
 
 #define RISCV_TIMEBASE_FREQ 10 /* 1Ghz */
 #define MAKE_32BIT_MASK(shift, length) \
 (((uint32_t)(~0UL) >> (32 - (length))) << (shift))
 
+/**
+ * To keep it simple, any event can be mapped to any programmable counters in
+ * QEMU. The generic cycle & instruction count events can also be monitored
+ * using programmable counters. In that case, mcycle & minstret must continue
+ * to provide the correct value as well. Hetergenous PMU per hart is not
+ * supported yet. Thus, number of counters are same across all harts.
+ */
+void riscv_pmu_generate_fdt_node(void *fdt, int num_ctrs, char *pmu_name)
+{
+uint32_t fdt_event_ctr_map[20] = {};
+uint32_t cmask;
+
+/* All the programmable counters can map to any event */
+cmask = MAKE_32BIT_MASK(3, num_ctrs);
+
+   /* SBI_PMU_HW_CPU_CYCLES */
+   fdt_event_ctr_map[0] = cpu_to_be32(0x0001);
+   fdt_event_ctr_map[1] = cpu_to_be32(0x0001);
+   fdt_event_ctr_map[2] = cpu_to_be32(cmask | 1 << 0);
+
+   /* SBI_PMU_HW_INSTRUCTIONS */
+   fdt_event_ctr_map[3] = cpu_to_be32(0x0002);
+   fdt_event_ctr_map[4] = cpu_to_be32(0x0002);
+   fdt_event_ctr_map[5] = cpu_to_be32(cmask | 1 << 2);
+
+   /* SBI_PMU_HW_CACHE_DTLB : READ : MISS */
+   fdt_event_ctr_map[6] = cpu_to_be32(0x00010019);
+   fdt_event_ctr_map[7] = cpu_to_be32(0x00010019);
+   fdt_event_ctr_map[8] = 

Re: [RFC 03/10] vdpa: add the infrastructure of vdpa-dev

2022-01-06 Thread Jason Wang
On Thu, Jan 6, 2022 at 7:25 PM Stefan Hajnoczi  wrote:
>
> On Thu, Jan 06, 2022 at 01:22:19AM +, Longpeng (Mike, Cloud 
> Infrastructure Service Product Dept.) wrote:
> >
> >
> > > -Original Message-
> > > From: Stefan Hajnoczi [mailto:stefa...@redhat.com]
> > > Sent: Wednesday, January 5, 2022 5:49 PM
> > > To: Longpeng (Mike, Cloud Infrastructure Service Product Dept.)
> > > 
> > > Cc: m...@redhat.com; jasow...@redhat.com; sgarz...@redhat.com;
> > > coh...@redhat.com; pbonz...@redhat.com; Gonglei (Arei)
> > > ; Yechuan ; Huangzhichao
> > > ; qemu-devel@nongnu.org
> > > Subject: Re: [RFC 03/10] vdpa: add the infrastructure of vdpa-dev
> > >
> > > On Wed, Jan 05, 2022 at 08:58:53AM +0800, Longpeng(Mike) wrote:
> > > > +static const VirtioPCIDeviceTypeInfo vhost_vdpa_device_pci_info = {
> > > > +.base_name   = TYPE_VHOST_VDPA_DEVICE_PCI,
> > > > +.generic_name= "vhost-vdpa-device-pci",
> > > > +.transitional_name   = "vhost-vdpa-device-pci-transitional",
> > > > +.non_transitional_name   = 
> > > > "vhost-vdpa-device-pci-non-transitional",
> > >
> > > Does vDPA support Transitional VIRTIO devices?
> > >
> > > I expected this device to support Modern devices only.
> > >
> >
> > There's already a 0.95 vdpa driver (Alibaba ENI) in the kernel source and
> > supporting 0.95 devices is necessary for some older GuestOS.
> >
> > I'm OK if other guys also approve of supporting 1.0+ devices only :)
>
> If vDPA supports Transitional VIRTIO devices then it's fine to keep this
> code unchanged in this patch series.

Right, and I think that's the plan.

Thanks

>
> Stefan




[PATCH v4 08/11] target/riscv: Add sscofpmf extension support

2022-01-06 Thread Atish Patra
The Sscofpmf ('Ss' for Privileged arch and Supervisor-level extensions,
and 'cofpmf' for Count OverFlow and Privilege Mode Filtering)
extension allows the perf to handle overflow interrupts and filtering
support. This patch provides a framework for programmable
counters to leverage the extension. As the extension doesn't have any
provision for the overflow bit for fixed counters, the fixed events
can also be monitoring using programmable counters. The underlying
counters for cycle and instruction counters are always running. Thus,
a separate timer device is programmed to handle the overflow.

Signed-off-by: Atish Patra 
Signed-off-by: Atish Patra 
---
 target/riscv/cpu.c  |  12 ++
 target/riscv/cpu.h  |  25 +++
 target/riscv/cpu_bits.h |  55 +++
 target/riscv/csr.c  | 156 --
 target/riscv/pmu.c  | 346 +++-
 target/riscv/pmu.h  |   8 +
 6 files changed, 591 insertions(+), 11 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 9448c4335347..2ca9f8480b9d 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -22,6 +22,7 @@
 #include "qemu/ctype.h"
 #include "qemu/log.h"
 #include "cpu.h"
+#include "pmu.h"
 #include "internals.h"
 #include "exec/exec-all.h"
 #include "qapi/error.h"
@@ -569,6 +570,16 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 set_misa(env, env->misa_mxl, ext);
 }
 
+if (cpu->cfg.pmu_num) {
+if (!riscv_pmu_init(cpu, cpu->cfg.pmu_num) && cpu->cfg.ext_sscof) {
+cpu->pmu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
+  riscv_pmu_timer_cb, cpu);
+if (!cpu->pmu_timer) {
+cpu->cfg.ext_sscof = false;
+}
+}
+ }
+
 riscv_cpu_register_gdb_regs_for_features(cs);
 
 qemu_init_vcpu(cs);
@@ -628,6 +639,7 @@ static Property riscv_cpu_properties[] = {
 DEFINE_PROP_BOOL("u", RISCVCPU, cfg.ext_u, true),
 DEFINE_PROP_BOOL("v", RISCVCPU, cfg.ext_v, false),
 DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
+DEFINE_PROP_BOOL("sscof", RISCVCPU, cfg.ext_sscof, false),
 DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
 DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
 DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false),
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 5fe9c51b38c7..1e5f307df919 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -123,6 +123,8 @@ struct PMUCTRState {
 /* Snapshort value of a counter in RV32 */
 target_ulong mhpmcounterh_prev;
 bool started;
+/* Value beyond UINT32_MAX/UINT64_MAX before overflow interrupt trigger */
+target_ulong irq_overflow_left;
 };
 
 struct CPURISCVState {
@@ -245,6 +247,9 @@ struct CPURISCVState {
 /* PMU event selector configured values. First three are unused*/
 target_ulong mhpmevent_val[RV_MAX_MHPMEVENTS];
 
+/* PMU event selector configured values for RV32*/
+target_ulong mhpmeventh_val[RV_MAX_MHPMEVENTS];
+
 target_ulong sscratch;
 target_ulong mscratch;
 
@@ -339,6 +344,7 @@ struct RISCVCPU {
 bool ext_icsr;
 bool ext_zfh;
 bool ext_zfhmin;
+bool ext_sscof;
 
 uint8_t pmu_num;
 char *priv_spec;
@@ -352,6 +358,12 @@ struct RISCVCPU {
 bool epmp;
 uint64_t resetvec;
 } cfg;
+
+QEMUTimer *pmu_timer;
+/* A bitmask of Available programmable counters */
+uint32_t pmu_avail_ctrs;
+/* Mapping of events to counters */
+GHashTable *pmu_event_ctr_map;
 };
 
 static inline int riscv_has_ext(CPURISCVState *env, target_ulong ext)
@@ -526,6 +538,19 @@ enum {
 CSR_TABLE_SIZE = 0x1000
 };
 
+/**
+ * The event id are encoded based on the encoding specified in the
+ * SBI specification v0.3
+ */
+
+enum riscv_pmu_event_idx {
+RISCV_PMU_EVENT_HW_CPU_CYCLES = 0x01,
+RISCV_PMU_EVENT_HW_INSTRUCTIONS = 0x02,
+RISCV_PMU_EVENT_CACHE_DTLB_READ_MISS = 0x10019,
+RISCV_PMU_EVENT_CACHE_DTLB_WRITE_MISS = 0x1001B,
+RISCV_PMU_EVENT_CACHE_ITLB_PREFETCH_MISS = 0x10021,
+};
+
 /* CSR function table */
 extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
 
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index dbd9ce9a85a3..559b60675132 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -316,6 +316,37 @@
 #define CSR_MHPMEVENT29 0x33d
 #define CSR_MHPMEVENT30 0x33e
 #define CSR_MHPMEVENT31 0x33f
+
+#define CSR_MHPMEVENT3H 0x723
+#define CSR_MHPMEVENT4H 0x724
+#define CSR_MHPMEVENT5H 0x725
+#define CSR_MHPMEVENT6H 0x726
+#define CSR_MHPMEVENT7H 0x727
+#define CSR_MHPMEVENT8H 0x728
+#define CSR_MHPMEVENT9H 0x729
+#define CSR_MHPMEVENT10H0x72a
+#define CSR_MHPMEVENT11H0x72b
+#define CSR_MHPMEVENT12H0x72c
+#define CSR_MHPMEVENT13H0x72d
+#define CSR_MHPMEVENT14H0x72e
+#define CSR_MHPMEVENT15H0x72f
+#define CSR_MHPMEVENT16H 

[PATCH v4 01/11] target/riscv: Fix PMU CSR predicate function

2022-01-06 Thread Atish Patra
From: Atish Patra 

The predicate function calculates the counter index incorrectly for
hpmcounterx. Fix the counter index to reflect correct CSR number.

Fixes: e39a8320b088 ("target/riscv: Support the Virtual Instruction fault")

Reviewed-by: Alistair Francis 
Reviewed-by: Bin Meng 
Signed-off-by: Atish Patra 
Signed-off-by: Atish Patra 
---
 target/riscv/csr.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 146447eac5d5..53a621fdbaef 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -90,8 +90,9 @@ static RISCVException ctr(CPURISCVState *env, int csrno)
 }
 break;
 case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
-if (!get_field(env->hcounteren, 1 << (csrno - CSR_HPMCOUNTER3)) &&
-get_field(env->mcounteren, 1 << (csrno - CSR_HPMCOUNTER3))) {
+ctr_index = csrno - CSR_CYCLE;
+if (!get_field(env->hcounteren, 1 << ctr_index) &&
+ get_field(env->mcounteren, 1 << ctr_index)) {
 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
 }
 break;
@@ -117,8 +118,9 @@ static RISCVException ctr(CPURISCVState *env, int csrno)
 }
 break;
 case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
-if (!get_field(env->hcounteren, 1 << (csrno - 
CSR_HPMCOUNTER3H)) &&
-get_field(env->mcounteren, 1 << (csrno - 
CSR_HPMCOUNTER3H))) {
+ctr_index = csrno - CSR_CYCLEH;
+if (!get_field(env->hcounteren, 1 << ctr_index) &&
+ get_field(env->mcounteren, 1 << ctr_index)) {
 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
 }
 break;
-- 
2.30.2




[PATCH v4 06/11] target/riscv: Add support for hpmcounters/hpmevents

2022-01-06 Thread Atish Patra
From: Atish Patra 

With SBI PMU extension, user can use any of the available hpmcounters to
track any perf events based on the value written to mhpmevent csr.
Add read/write functionality for these csrs.

Signed-off-by: Atish Patra 
Signed-off-by: Atish Patra 
---
 target/riscv/cpu.h |  11 +
 target/riscv/csr.c | 468 -
 target/riscv/machine.c |   3 +
 3 files changed, 330 insertions(+), 152 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 6f2875fd9acd..39edc948d703 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -101,6 +101,8 @@ typedef struct CPURISCVState CPURISCVState;
 #endif
 
 #define RV_VLEN_MAX 1024
+#define RV_MAX_MHPMEVENTS 29
+#define RV_MAX_MHPMCOUNTERS 32
 
 FIELD(VTYPE, VLMUL, 0, 3)
 FIELD(VTYPE, VSEW, 3, 3)
@@ -224,6 +226,15 @@ struct CPURISCVState {
 
 target_ulong mcountinhibit;
 
+/* PMU counter configured values */
+target_ulong mhpmcounter_val[RV_MAX_MHPMCOUNTERS];
+
+/* for RV32 */
+target_ulong mhpmcounterh_val[RV_MAX_MHPMCOUNTERS];
+
+/* PMU event selector configured values */
+target_ulong mhpmevent_val[RV_MAX_MHPMEVENTS];
+
 target_ulong sscratch;
 target_ulong mscratch;
 
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 89d15b38be7c..58a9550bd898 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -80,6 +80,15 @@ static RISCVException mctr(CPURISCVState *env, int csrno)
 return RISCV_EXCP_NONE;
 }
 
+static RISCVException mctr32(CPURISCVState *env, int csrno)
+{
+if (riscv_cpu_mxl(env) != MXL_RV32) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+return mctr(env, csrno);
+}
+
 static RISCVException ctr(CPURISCVState *env, int csrno)
 {
 #if !defined(CONFIG_USER_ONLY)
@@ -464,6 +473,7 @@ static RISCVException read_instret(CPURISCVState *env, int 
csrno,
 #else
 *val = cpu_get_host_ticks();
 #endif
+
 return RISCV_EXCP_NONE;
 }
 
@@ -479,9 +489,76 @@ static RISCVException read_instreth(CPURISCVState *env, 
int csrno,
 #else
 *val = cpu_get_host_ticks() >> 32;
 #endif
+
+return RISCV_EXCP_NONE;
+}
+
+static int read_mhpmevent(CPURISCVState *env, int csrno, target_ulong *val)
+{
+int evt_index = csrno - CSR_MHPMEVENT3;
+
+*val = env->mhpmevent_val[evt_index];
+
+return RISCV_EXCP_NONE;
+}
+
+static int write_mhpmevent(CPURISCVState *env, int csrno, target_ulong val)
+{
+int evt_index = csrno - CSR_MHPMEVENT3;
+
+env->mhpmevent_val[evt_index] = val;
+
+return RISCV_EXCP_NONE;
+}
+
+static int write_mhpmcounter(CPURISCVState *env, int csrno, target_ulong val)
+{
+int ctr_index = csrno - CSR_MHPMCOUNTER3 + 3;
+
+env->mhpmcounter_val[ctr_index] = val;
+
 return RISCV_EXCP_NONE;
 }
 
+static int write_mhpmcounterh(CPURISCVState *env, int csrno, target_ulong val)
+{
+int ctr_index = csrno - CSR_MHPMCOUNTER3H + 3;
+
+env->mhpmcounterh_val[ctr_index] = val;
+
+return RISCV_EXCP_NONE;
+}
+
+static int read_hpmcounter(CPURISCVState *env, int csrno, target_ulong *val)
+{
+int ctr_index;
+
+if (env->priv == PRV_M) {
+ctr_index = csrno - CSR_MHPMCOUNTER3 + 3;
+} else {
+ctr_index = csrno - CSR_HPMCOUNTER3 + 3;
+}
+*val = env->mhpmcounter_val[ctr_index];
+
+return RISCV_EXCP_NONE;
+}
+
+static int read_hpmcounterh(CPURISCVState *env, int csrno, target_ulong *val)
+{
+int ctr_index;
+
+if (env->priv == PRV_M) {
+ctr_index = csrno - CSR_MHPMCOUNTER3H + 3;
+} else {
+ctr_index = csrno - CSR_HPMCOUNTER3H + 3;
+}
+
+*val = env->mhpmcounterh_val[ctr_index];
+
+return RISCV_EXCP_NONE;
+}
+
+
 #if defined(CONFIG_USER_ONLY)
 static RISCVException read_time(CPURISCVState *env, int csrno,
 target_ulong *val)
@@ -2082,157 +2159,244 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 [CSR_SPMBASE] ={ "spmbase", pointer_masking, read_spmbase, 
write_spmbase },
 
 /* Performance Counters */
-[CSR_HPMCOUNTER3]= { "hpmcounter3",ctr,read_zero },
-[CSR_HPMCOUNTER4]= { "hpmcounter4",ctr,read_zero },
-[CSR_HPMCOUNTER5]= { "hpmcounter5",ctr,read_zero },
-[CSR_HPMCOUNTER6]= { "hpmcounter6",ctr,read_zero },
-[CSR_HPMCOUNTER7]= { "hpmcounter7",ctr,read_zero },
-[CSR_HPMCOUNTER8]= { "hpmcounter8",ctr,read_zero },
-[CSR_HPMCOUNTER9]= { "hpmcounter9",ctr,read_zero },
-[CSR_HPMCOUNTER10]   = { "hpmcounter10",   ctr,read_zero },
-[CSR_HPMCOUNTER11]   = { "hpmcounter11",   ctr,read_zero },
-[CSR_HPMCOUNTER12]   = { "hpmcounter12",   ctr,read_zero },
-[CSR_HPMCOUNTER13]   = { "hpmcounter13",   ctr,read_zero },
-[CSR_HPMCOUNTER14]   = { "hpmcounter14",   ctr,read_zero },
-[CSR_HPMCOUNTER15]   = { "hpmcounter15",   ctr,read_zero },
-[CSR_HPMCOUNTER16]   = { "hpmcounter16",   ctr,read_zero },
-[CSR_HPMCOUNTER17]   = { 

[PATCH v4 09/11] target/riscv: Simplify counter predicate function

2022-01-06 Thread Atish Patra
All the hpmcounters and the fixed counters (CY, IR, TM) can be represented
as a unified counter. Thus, the predicate function doesn't need handle each
case separately.

Simplify the predicate function so that we just handle things differently
between RV32/RV64 and S/HS mode.

Signed-off-by: Atish Patra 
---
 target/riscv/csr.c | 111 -
 1 file changed, 10 insertions(+), 101 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index d3a8bba6a518..feb053eb3f7b 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -109,6 +109,7 @@ static RISCVException ctr(CPURISCVState *env, int csrno)
 CPUState *cs = env_cpu(env);
 RISCVCPU *cpu = RISCV_CPU(cs);
 int ctr_index;
+uint64_t ctr_mask;
 int base_csrno = CSR_CYCLE;
 bool rv32 = riscv_cpu_mxl(env) == MXL_RV32 ? true : false;
 
@@ -117,122 +118,30 @@ static RISCVException ctr(CPURISCVState *env, int csrno)
 base_csrno += 0x80;
 }
 ctr_index = csrno - base_csrno;
+ctr_mask = BIT(ctr_index);
 
 if ((csrno >= CSR_CYCLE && csrno <= CSR_INSTRET) ||
 (csrno >= CSR_CYCLEH && csrno <= CSR_INSTRETH)) {
 goto skip_ext_pmu_check;
 }
 
-if ((!cpu->cfg.pmu_num || !(cpu->pmu_avail_ctrs & BIT(ctr_index {
+if ((!cpu->cfg.pmu_num || !(cpu->pmu_avail_ctrs & ctr_mask))) {
 /* No counter is enabled in PMU or the counter is out of range */
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
 skip_ext_pmu_check:
 
-if (env->priv == PRV_S) {
-switch (csrno) {
-case CSR_CYCLE:
-if (!get_field(env->mcounteren, COUNTEREN_CY)) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-break;
-case CSR_TIME:
-if (!get_field(env->mcounteren, COUNTEREN_TM)) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-break;
-case CSR_INSTRET:
-if (!get_field(env->mcounteren, COUNTEREN_IR)) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-break;
-case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
-if (!get_field(env->mcounteren, 1 << ctr_index)) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-break;
-}
-if (rv32) {
-switch (csrno) {
-case CSR_CYCLEH:
-if (!get_field(env->mcounteren, COUNTEREN_CY)) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-break;
-case CSR_TIMEH:
-if (!get_field(env->mcounteren, COUNTEREN_TM)) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-break;
-case CSR_INSTRETH:
-if (!get_field(env->mcounteren, COUNTEREN_IR)) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-break;
-case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
-if (!get_field(env->mcounteren, 1 << ctr_index)) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-break;
-}
-}
+if ((env->priv == PRV_S) && (!get_field(env->mcounteren, ctr_mask))) {
+return RISCV_EXCP_ILLEGAL_INST;
 }
 
 if (riscv_cpu_virt_enabled(env)) {
-switch (csrno) {
-case CSR_CYCLE:
-if (!get_field(env->hcounteren, COUNTEREN_CY) &&
-get_field(env->mcounteren, COUNTEREN_CY)) {
-return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
-}
-break;
-case CSR_TIME:
-if (!get_field(env->hcounteren, COUNTEREN_TM) &&
-get_field(env->mcounteren, COUNTEREN_TM)) {
-return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
-}
-break;
-case CSR_INSTRET:
-if (!get_field(env->hcounteren, COUNTEREN_IR) &&
-get_field(env->mcounteren, COUNTEREN_IR)) {
-return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
-}
-break;
-case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
-if (!get_field(env->hcounteren, 1 << ctr_index) &&
- get_field(env->mcounteren, 1 << ctr_index)) {
-return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
-}
-break;
-}
-if (rv32) {
-switch (csrno) {
-case CSR_CYCLEH:
-if (!get_field(env->hcounteren, COUNTEREN_CY) &&
-get_field(env->mcounteren, COUNTEREN_CY)) {
-return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
-}
-break;
-case CSR_TIMEH:
-if (!get_field(env->hcounteren, COUNTEREN_TM) &&
-get_field(env->mcounteren, COUNTEREN_TM)) {
-return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
-}
-break;
-case CSR_INSTRETH:
-if 

[PATCH v4 00/11] Improve PMU support

2022-01-06 Thread Atish Patra
The latest version of the SBI specification includes a Performance Monitoring
Unit(PMU) extension[1] which allows the supervisor to start/stop/configure
various PMU events. The Sscofpmf ('Ss' for Privileged arch and Supervisor-level
extensions, and 'cofpmf' for Count OverFlow and Privilege Mode Filtering)
extension[2] allows the perf like tool to handle overflow interrupts and
filtering support.

This series implements full PMU infrastructure to support
PMU in virt machine. This will allow us to add any PMU events in future.

Currently, this series enables the following omu events.
1. cycle count
2. instruction count
3. DTLB load/store miss
4. ITLB prefetch miss

The first two are computed using host ticks while last three are counted during
cpu_tlb_fill. We can do both sampling and count from guest userspace.
This series has been tested on both RV64 and RV32. Both Linux[3] and Opensbi[4]
patches are required to get the perf working.

Here is an output of perf stat/report while running hackbench with OpenSBI & 
Linux
kernel patches applied [3].

Perf stat:
==
[root@fedora-riscv ~]# perf stat -e cycles -e instructions -e dTLB-load-misses 
-e dTLB-store-misses -e iTLB-load-misses \
> perf bench sched messaging -g 1 -l 10
# Running 'sched/messaging' benchmark:
# 20 sender and receiver processes per group
# 1 groups == 40 processes run

 Total time: 0.265 [sec]

 Performance counter stats for 'perf bench sched messaging -g 1 -l 10':

 4,167,825,362  cycles  

 4,166,609,256  instructions  #1.00  insn per cycle 

 3,092,026  dTLB-load-misses

   258,280  dTLB-store-misses   

 2,068,966  iTLB-load-misses


   0.585791767 seconds time elapsed

   0.373802000 seconds user
   1.042359000 seconds sys

Perf record:

[root@fedora-riscv ~]# perf record -e cycles -e instructions \
> -e dTLB-load-misses -e dTLB-store-misses -e iTLB-load-misses -c 1 \
> perf bench sched messaging -g 1 -l 10
# Running 'sched/messaging' benchmark:
# 20 sender and receiver processes per group
# 1 groups == 40 processes run

 Total time: 1.397 [sec]
[ perf record: Woken up 10 times to write data ]
Check IO/CPU overload!
[ perf record: Captured and wrote 8.211 MB perf.data (214486 samples) ]

[root@fedora-riscv riscv]# perf report
Available samples   
107K cycles◆
107K instructions  ▒
250 dTLB-load-misses   ▒
13 dTLB-store-misses   ▒
172 iTLB-load-misses  
..

Changes from v3->v4:
1. Removed the dummy events from pmu DT node.
2. Fixed pmu_avail_counters mask generation.
3. Added a patch to simplify the predicate function for counters. 

Changes from v2->v3:
1. Addressed all the comments on PATCH1-4.
2. Split patch1 into two separate patches.
3. Added explicit comments to explain the event types in DT node.
4. Rebased on latest Qemu.

Changes from v1->v2:
1. Dropped the ACks from v1 as signficant changes happened after v1.
2. sscofpmf support.
3. A generic counter management framework.

[1] https://github.com/riscv-non-isa/riscv-sbi-doc/blob/master/riscv-sbi.adoc
[2] https://drive.google.com/file/d/171j4jFjIkKdj5LWcExphq4xG_2sihbfd/edit
[3] https://github.com/atishp04/linux/tree/riscv_pmu_v5
[4] https://github.com/atishp04/qemu/tree/riscv_pmu_v4

Atish Patra (11):
target/riscv: Fix PMU CSR predicate function
target/riscv: Implement PMU CSR predicate function for S-mode
target/riscv: pmu: Rename the counters extension to pmu
target/riscv: pmu: Make number of counters configurable
target/riscv: Implement mcountinhibit CSR
target/riscv: Add support for hpmcounters/hpmevents
target/riscv: Support mcycle/minstret write operation
target/riscv: Add sscofpmf extension support
target/riscv: Simplify counter predicate function
target/riscv: Add few cache related PMU events
hw/riscv: virt: Add PMU DT node to the device tree

hw/riscv/virt.c   |  38 ++
target/riscv/cpu.c|  14 +-
target/riscv/cpu.h|  50 ++-
target/riscv/cpu_bits.h   |  59 +++
target/riscv/cpu_helper.c |  26 ++
target/riscv/csr.c| 828 +++---
target/riscv/machine.c|  26 ++
target/riscv/meson.build  |   1 +
target/riscv/pmu.c| 419 +++
target/riscv/pmu.h|  37 ++
10 files changed, 1268 insertions(+), 230 deletions(-)
create mode 100644 target/riscv/pmu.c
create mode 100644 target/riscv/pmu.h

--
2.30.2




[PATCH v4 05/11] target/riscv: Implement mcountinhibit CSR

2022-01-06 Thread Atish Patra
From: Atish Patra 

As per the privilege specification v1.11, mcountinhibit allows to start/stop
a pmu counter selectively.

Reviewed-by: Bin Meng 
Reviewed-by: Alistair Francis 
Signed-off-by: Atish Patra 
Signed-off-by: Atish Patra 
---
 target/riscv/cpu.h  |  2 ++
 target/riscv/cpu_bits.h |  4 
 target/riscv/csr.c  | 25 +
 target/riscv/machine.c  |  1 +
 4 files changed, 32 insertions(+)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index b353770596e8..6f2875fd9acd 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -222,6 +222,8 @@ struct CPURISCVState {
 target_ulong scounteren;
 target_ulong mcounteren;
 
+target_ulong mcountinhibit;
+
 target_ulong sscratch;
 target_ulong mscratch;
 
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 1e31f4d35f5b..dbd9ce9a85a3 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -283,6 +283,10 @@
 #define CSR_MHPMCOUNTER29   0xb1d
 #define CSR_MHPMCOUNTER30   0xb1e
 #define CSR_MHPMCOUNTER31   0xb1f
+
+/* Machine counter-inhibit register */
+#define CSR_MCOUNTINHIBIT   0x320
+
 #define CSR_MHPMEVENT3  0x323
 #define CSR_MHPMEVENT4  0x324
 #define CSR_MHPMEVENT5  0x325
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index e31c27e270a2..89d15b38be7c 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -834,6 +834,28 @@ static RISCVException write_mtvec(CPURISCVState *env, int 
csrno,
 return RISCV_EXCP_NONE;
 }
 
+static RISCVException read_mcountinhibit(CPURISCVState *env, int csrno,
+ target_ulong *val)
+{
+if (env->priv_ver < PRIV_VERSION_1_11_0) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+*val = env->mcountinhibit;
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_mcountinhibit(CPURISCVState *env, int csrno,
+  target_ulong val)
+{
+if (env->priv_ver < PRIV_VERSION_1_11_0) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+env->mcountinhibit = val;
+return RISCV_EXCP_NONE;
+}
+
 static RISCVException read_mcounteren(CPURISCVState *env, int csrno,
   target_ulong *val)
 {
@@ -2120,6 +2142,9 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 [CSR_MHPMCOUNTER30]  = { "mhpmcounter30",  mctr,   read_zero },
 [CSR_MHPMCOUNTER31]  = { "mhpmcounter31",  mctr,   read_zero },
 
+[CSR_MCOUNTINHIBIT]  = { "mcountinhibit",   any,read_mcountinhibit,
+   write_mcountinhibit },
+
 [CSR_MHPMEVENT3] = { "mhpmevent3", any,read_zero },
 [CSR_MHPMEVENT4] = { "mhpmevent4", any,read_zero },
 [CSR_MHPMEVENT5] = { "mhpmevent5", any,read_zero },
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index ad8248ebfda8..ea4a382c140a 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -205,6 +205,7 @@ const VMStateDescription vmstate_riscv_cpu = {
 VMSTATE_UINTTL(env.mtval, RISCVCPU),
 VMSTATE_UINTTL(env.scounteren, RISCVCPU),
 VMSTATE_UINTTL(env.mcounteren, RISCVCPU),
+VMSTATE_UINTTL(env.mcountinhibit, RISCVCPU),
 VMSTATE_UINTTL(env.sscratch, RISCVCPU),
 VMSTATE_UINTTL(env.mscratch, RISCVCPU),
 VMSTATE_UINT64(env.mfromhost, RISCVCPU),
-- 
2.30.2




[PATCH v4 04/11] target/riscv: pmu: Make number of counters configurable

2022-01-06 Thread Atish Patra
The RISC-V privilege specification provides flexibility to implement
any number of counters from 29 programmable counters. However, the QEMU
implements all the counters.

Make it configurable through pmu config parameter which now will indicate
how many programmable counters should be implemented by the cpu.

Signed-off-by: Atish Patra 
Signed-off-by: Atish Patra 
---
 target/riscv/cpu.c |  2 +-
 target/riscv/cpu.h |  2 +-
 target/riscv/csr.c | 96 ++
 3 files changed, 65 insertions(+), 35 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index df87489f6d87..9448c4335347 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -627,7 +627,7 @@ static Property riscv_cpu_properties[] = {
 DEFINE_PROP_BOOL("s", RISCVCPU, cfg.ext_s, true),
 DEFINE_PROP_BOOL("u", RISCVCPU, cfg.ext_u, true),
 DEFINE_PROP_BOOL("v", RISCVCPU, cfg.ext_v, false),
-DEFINE_PROP_BOOL("pmu", RISCVCPU, cfg.ext_pmu, true),
+DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
 DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
 DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
 DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false),
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 16d0b4f139ee..b353770596e8 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -312,12 +312,12 @@ struct RISCVCPU {
 bool ext_zbb;
 bool ext_zbc;
 bool ext_zbs;
-bool ext_pmu;
 bool ext_ifencei;
 bool ext_icsr;
 bool ext_zfh;
 bool ext_zfhmin;
 
+uint8_t pmu_num;
 char *priv_spec;
 char *user_spec;
 char *bext_spec;
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index a6e856b896a9..e31c27e270a2 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -58,15 +58,45 @@ static RISCVException vs(CPURISCVState *env, int csrno)
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
+static RISCVException mctr(CPURISCVState *env, int csrno)
+{
+#if !defined(CONFIG_USER_ONLY)
+CPUState *cs = env_cpu(env);
+RISCVCPU *cpu = RISCV_CPU(cs);
+int ctr_index;
+int base_csrno = CSR_MHPMCOUNTER3;
+
+if ((riscv_cpu_mxl(env) == MXL_RV32) && csrno >= CSR_MCYCLEH) {
+/* Offset for RV32 mhpmcounternh counters */
+base_csrno += 0x80;
+}
+ctr_index = csrno - base_csrno;
+if (!cpu->cfg.pmu_num || ctr_index >= cpu->cfg.pmu_num) {
+/* The PMU is not enabled or counter is out of range*/
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+#endif
+return RISCV_EXCP_NONE;
+}
+
 static RISCVException ctr(CPURISCVState *env, int csrno)
 {
 #if !defined(CONFIG_USER_ONLY)
 CPUState *cs = env_cpu(env);
 RISCVCPU *cpu = RISCV_CPU(cs);
 int ctr_index;
+int base_csrno = CSR_HPMCOUNTER3;
+bool rv32 = riscv_cpu_mxl(env) == MXL_RV32 ? true : false;
+
+if (rv32 && csrno >= CSR_CYCLEH) {
+/* Offset for RV32 hpmcounternh counters */
+base_csrno += 0x80;
+}
+ctr_index = csrno - base_csrno;
 
-if (!cpu->cfg.ext_pmu) {
-/* The PMU extension is not enabled */
+if (!cpu->cfg.pmu_num || ctr_index >= (cpu->cfg.pmu_num)) {
+/* No counter is enabled in PMU or the counter is out of range */
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
@@ -94,7 +124,7 @@ static RISCVException ctr(CPURISCVState *env, int csrno)
 }
 break;
 }
-if (riscv_cpu_is_32bit(env)) {
+if (rv32) {
 switch (csrno) {
 case CSR_CYCLEH:
 if (!get_field(env->mcounteren, COUNTEREN_CY)) {
@@ -149,7 +179,7 @@ static RISCVException ctr(CPURISCVState *env, int csrno)
 }
 break;
 }
-if (riscv_cpu_mxl(env) == MXL_RV32) {
+if (rv32) {
 switch (csrno) {
 case CSR_CYCLEH:
 if (!get_field(env->hcounteren, COUNTEREN_CY) &&
@@ -2060,35 +2090,35 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 [CSR_HPMCOUNTER30]   = { "hpmcounter30",   ctr,read_zero },
 [CSR_HPMCOUNTER31]   = { "hpmcounter31",   ctr,read_zero },
 
-[CSR_MHPMCOUNTER3]   = { "mhpmcounter3",   any,read_zero },
-[CSR_MHPMCOUNTER4]   = { "mhpmcounter4",   any,read_zero },
-[CSR_MHPMCOUNTER5]   = { "mhpmcounter5",   any,read_zero },
-[CSR_MHPMCOUNTER6]   = { "mhpmcounter6",   any,read_zero },
-[CSR_MHPMCOUNTER7]   = { "mhpmcounter7",   any,read_zero },
-[CSR_MHPMCOUNTER8]   = { "mhpmcounter8",   any,read_zero },
-[CSR_MHPMCOUNTER9]   = { "mhpmcounter9",   any,read_zero },
-[CSR_MHPMCOUNTER10]  = { "mhpmcounter10",  any,read_zero },
-[CSR_MHPMCOUNTER11]  = { "mhpmcounter11",  any,read_zero },
-[CSR_MHPMCOUNTER12]  = { "mhpmcounter12",  any,read_zero },
-[CSR_MHPMCOUNTER13]  = { "mhpmcounter13",  any,read_zero },
-[CSR_MHPMCOUNTER14]  = { "mhpmcounter14",  any,

[PATCH v4 03/11] target/riscv: pmu: Rename the counters extension to pmu

2022-01-06 Thread Atish Patra
From: Atish Patra 

The PMU counters are supported via cpu config "Counters" which doesn't
indicate the correct purpose of those counters.

Rename the config property to pmu to indicate that these counters
are performance monitoring counters. This aligns with cpu options for
ARM architecture as well.

Reviewed-by: Bin Meng 
Reviewed-by: Alistair Francis 
Signed-off-by: Atish Patra 
Signed-off-by: Atish Patra 
---
 target/riscv/cpu.c | 2 +-
 target/riscv/cpu.h | 2 +-
 target/riscv/csr.c | 4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 6ef3314bced8..df87489f6d87 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -627,7 +627,7 @@ static Property riscv_cpu_properties[] = {
 DEFINE_PROP_BOOL("s", RISCVCPU, cfg.ext_s, true),
 DEFINE_PROP_BOOL("u", RISCVCPU, cfg.ext_u, true),
 DEFINE_PROP_BOOL("v", RISCVCPU, cfg.ext_v, false),
-DEFINE_PROP_BOOL("Counters", RISCVCPU, cfg.ext_counters, true),
+DEFINE_PROP_BOOL("pmu", RISCVCPU, cfg.ext_pmu, true),
 DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
 DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
 DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false),
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index dc10f27093b0..16d0b4f139ee 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -312,7 +312,7 @@ struct RISCVCPU {
 bool ext_zbb;
 bool ext_zbc;
 bool ext_zbs;
-bool ext_counters;
+bool ext_pmu;
 bool ext_ifencei;
 bool ext_icsr;
 bool ext_zfh;
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 823cc306d74b..a6e856b896a9 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -65,8 +65,8 @@ static RISCVException ctr(CPURISCVState *env, int csrno)
 RISCVCPU *cpu = RISCV_CPU(cs);
 int ctr_index;
 
-if (!cpu->cfg.ext_counters) {
-/* The Counters extensions is not enabled */
+if (!cpu->cfg.ext_pmu) {
+/* The PMU extension is not enabled */
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
-- 
2.30.2




[PATCH v4 02/11] target/riscv: Implement PMU CSR predicate function for S-mode

2022-01-06 Thread Atish Patra
From: Atish Patra 

Currently, the predicate function for PMU related CSRs only works if
virtualization is enabled. It also does not check mcounteren bits before
before cycle/minstret/hpmcounterx access.

Support supervisor mode access in the predicate function as well.

Reviewed-by: Alistair Francis 
Signed-off-by: Atish Patra 
Signed-off-by: Atish Patra 
---
 target/riscv/csr.c | 52 ++
 1 file changed, 52 insertions(+)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 53a621fdbaef..823cc306d74b 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -63,12 +63,64 @@ static RISCVException ctr(CPURISCVState *env, int csrno)
 #if !defined(CONFIG_USER_ONLY)
 CPUState *cs = env_cpu(env);
 RISCVCPU *cpu = RISCV_CPU(cs);
+int ctr_index;
 
 if (!cpu->cfg.ext_counters) {
 /* The Counters extensions is not enabled */
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
+if (env->priv == PRV_S) {
+switch (csrno) {
+case CSR_CYCLE:
+if (!get_field(env->mcounteren, COUNTEREN_CY)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+break;
+case CSR_TIME:
+if (!get_field(env->mcounteren, COUNTEREN_TM)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+break;
+case CSR_INSTRET:
+if (!get_field(env->mcounteren, COUNTEREN_IR)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+break;
+case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
+ctr_index = csrno - CSR_CYCLE;
+if (!get_field(env->mcounteren, 1 << ctr_index)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+break;
+}
+if (riscv_cpu_is_32bit(env)) {
+switch (csrno) {
+case CSR_CYCLEH:
+if (!get_field(env->mcounteren, COUNTEREN_CY)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+break;
+case CSR_TIMEH:
+if (!get_field(env->mcounteren, COUNTEREN_TM)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+break;
+case CSR_INSTRETH:
+if (!get_field(env->mcounteren, COUNTEREN_IR)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+break;
+case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
+ctr_index = csrno - CSR_CYCLEH;
+if (!get_field(env->mcounteren, 1 << ctr_index)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+break;
+}
+}
+}
+
 if (riscv_cpu_virt_enabled(env)) {
 switch (csrno) {
 case CSR_CYCLE:
-- 
2.30.2




[PATCH v4 07/11] target/riscv: Support mcycle/minstret write operation

2022-01-06 Thread Atish Patra
From: Atish Patra 

mcycle/minstret are actually WARL registers and can be written with any
given value. With SBI PMU extension, it will be used to store a initial
value provided from supervisor OS. The Qemu also need prohibit the counter
increment if mcountinhibit is set.

Support mcycle/minstret through generic counter infrastructure.

Signed-off-by: Atish Patra 
Signed-off-by: Atish Patra 
---
 target/riscv/cpu.h   |  24 +--
 target/riscv/csr.c   | 144 ++-
 target/riscv/machine.c   |  26 ++-
 target/riscv/meson.build |   1 +
 target/riscv/pmu.c   |  32 +
 target/riscv/pmu.h   |  28 
 6 files changed, 200 insertions(+), 55 deletions(-)
 create mode 100644 target/riscv/pmu.c
 create mode 100644 target/riscv/pmu.h

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 39edc948d703..5fe9c51b38c7 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -101,7 +101,7 @@ typedef struct CPURISCVState CPURISCVState;
 #endif
 
 #define RV_VLEN_MAX 1024
-#define RV_MAX_MHPMEVENTS 29
+#define RV_MAX_MHPMEVENTS 32
 #define RV_MAX_MHPMCOUNTERS 32
 
 FIELD(VTYPE, VLMUL, 0, 3)
@@ -112,6 +112,19 @@ FIELD(VTYPE, VEDIV, 8, 2)
 FIELD(VTYPE, RESERVED, 10, sizeof(target_ulong) * 8 - 11)
 FIELD(VTYPE, VILL, sizeof(target_ulong) * 8 - 1, 1)
 
+typedef struct PMUCTRState PMUCTRState;
+struct PMUCTRState {
+/* Current value of a counter */
+target_ulong mhpmcounter_val;
+/* Current value of a counter in RV32*/
+target_ulong mhpmcounterh_val;
+/* Snapshot values of counter */
+target_ulong mhpmcounter_prev;
+/* Snapshort value of a counter in RV32 */
+target_ulong mhpmcounterh_prev;
+bool started;
+};
+
 struct CPURISCVState {
 target_ulong gpr[32];
 uint64_t fpr[32]; /* assume both F and D extensions */
@@ -226,13 +239,10 @@ struct CPURISCVState {
 
 target_ulong mcountinhibit;
 
-/* PMU counter configured values */
-target_ulong mhpmcounter_val[RV_MAX_MHPMCOUNTERS];
-
-/* for RV32 */
-target_ulong mhpmcounterh_val[RV_MAX_MHPMCOUNTERS];
+/* PMU counter state */
+PMUCTRState pmu_ctrs[RV_MAX_MHPMCOUNTERS];
 
-/* PMU event selector configured values */
+/* PMU event selector configured values. First three are unused*/
 target_ulong mhpmevent_val[RV_MAX_MHPMEVENTS];
 
 target_ulong sscratch;
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 58a9550bd898..d4449ada557c 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -20,6 +20,7 @@
 #include "qemu/osdep.h"
 #include "qemu/log.h"
 #include "cpu.h"
+#include "pmu.h"
 #include "qemu/main-loop.h"
 #include "exec/exec-all.h"
 
@@ -461,41 +462,33 @@ static int write_vcsr(CPURISCVState *env, int csrno, 
target_ulong val)
 }
 
 /* User Timers and Counters */
-static RISCVException read_instret(CPURISCVState *env, int csrno,
-   target_ulong *val)
+static target_ulong get_icount_ticks(bool brv32)
 {
+int64_t val;
+target_ulong result;
+
 #if !defined(CONFIG_USER_ONLY)
 if (icount_enabled()) {
-*val = icount_get();
+val = icount_get();
 } else {
-*val = cpu_get_host_ticks();
+val = cpu_get_host_ticks();
 }
 #else
-*val = cpu_get_host_ticks();
+val = cpu_get_host_ticks();
 #endif
 
-return RISCV_EXCP_NONE;
-}
-
-static RISCVException read_instreth(CPURISCVState *env, int csrno,
-target_ulong *val)
-{
-#if !defined(CONFIG_USER_ONLY)
-if (icount_enabled()) {
-*val = icount_get() >> 32;
+if (brv32) {
+result = val >> 32;
 } else {
-*val = cpu_get_host_ticks() >> 32;
+result = val;
 }
-#else
-*val = cpu_get_host_ticks() >> 32;
-#endif
 
-return RISCV_EXCP_NONE;
+return result;
 }
 
 static int read_mhpmevent(CPURISCVState *env, int csrno, target_ulong *val)
 {
-int evt_index = csrno - CSR_MHPMEVENT3;
+int evt_index = csrno - CSR_MCOUNTINHIBIT;
 
 *val = env->mhpmevent_val[evt_index];
 
@@ -504,7 +497,7 @@ static int read_mhpmevent(CPURISCVState *env, int csrno, 
target_ulong *val)
 
 static int write_mhpmevent(CPURISCVState *env, int csrno, target_ulong val)
 {
-int evt_index = csrno - CSR_MHPMEVENT3;
+int evt_index = csrno - CSR_MCOUNTINHIBIT;
 
 env->mhpmevent_val[evt_index] = val;
 
@@ -513,52 +506,99 @@ static int write_mhpmevent(CPURISCVState *env, int csrno, 
target_ulong val)
 
 static int write_mhpmcounter(CPURISCVState *env, int csrno, target_ulong val)
 {
-int ctr_index = csrno - CSR_MHPMCOUNTER3 + 3;
+int ctr_idx = csrno - CSR_MCYCLE;
+PMUCTRState *counter = >pmu_ctrs[ctr_idx];
 
-env->mhpmcounter_val[ctr_index] = val;
+counter->mhpmcounter_val = val;
+if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
+riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) {
+counter->mhpmcounter_prev = get_icount_ticks(false);
+ } else {
+/* Other counters 

Re: [PATCH v4 2/3] target/riscv: Fixup setting GVA

2022-01-06 Thread Bin Meng
On Thu, Jan 6, 2022 at 12:04 PM Alistair Francis  wrote:
>
> On Tue, Dec 21, 2021 at 5:30 PM Bin Meng  wrote:
> >
> > On Mon, Dec 20, 2021 at 2:49 PM Alistair Francis
> >  wrote:
> > >
> > > From: Alistair Francis 
> > >
> > > In preperation for adding support for the illegal instruction address
> >
> > typo: preparation
>
> Fixed
>
> >
> > > let's fixup the Hypervisor extension setting GVA logic and improve the
> > > variable names.
> > >
> > > Signed-off-by: Alistair Francis 
> > > ---
> > >  target/riscv/cpu_helper.c | 21 ++---
> > >  1 file changed, 6 insertions(+), 15 deletions(-)
> > >
> > > diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> > > index 9eeed38c7e..9e1f5ee177 100644
> > > --- a/target/riscv/cpu_helper.c
> > > +++ b/target/riscv/cpu_helper.c
> > > @@ -967,6 +967,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
> > >
> > >  RISCVCPU *cpu = RISCV_CPU(cs);
> > >  CPURISCVState *env = >env;
> > > +bool write_gva = false;
> > >  uint64_t s;
> > >
> > >  /* cs->exception is 32-bits wide unlike mcause which is XLEN-bits 
> > > wide
> > > @@ -975,7 +976,6 @@ void riscv_cpu_do_interrupt(CPUState *cs)
> > >  bool async = !!(cs->exception_index & RISCV_EXCP_INT_FLAG);
> > >  target_ulong cause = cs->exception_index & RISCV_EXCP_INT_MASK;
> > >  target_ulong deleg = async ? env->mideleg : env->medeleg;
> > > -bool write_tval = false;
> > >  target_ulong tval = 0;
> > >  target_ulong htval = 0;
> > >  target_ulong mtval2 = 0;
> > > @@ -1004,7 +1004,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
> > >  case RISCV_EXCP_INST_PAGE_FAULT:
> > >  case RISCV_EXCP_LOAD_PAGE_FAULT:
> > >  case RISCV_EXCP_STORE_PAGE_FAULT:
> > > -write_tval  = true;
> > > +write_gva = true;
> > >  tval = env->badaddr;
> > >  break;
> > >  default:
> > > @@ -1041,18 +1041,6 @@ void riscv_cpu_do_interrupt(CPUState *cs)
> > >  if (riscv_has_ext(env, RVH)) {
> > >  target_ulong hdeleg = async ? env->hideleg : env->hedeleg;
> > >
> > > -if (env->two_stage_lookup && write_tval) {
> > > -/*
> > > - * If we are writing a guest virtual address to stval, 
> > > set
> > > - * this to 1. If we are trapping to VS we will set this 
> > > to 0
> > > - * later.
> > > - */
> > > -env->hstatus = set_field(env->hstatus, HSTATUS_GVA, 1);
> > > -} else {
> > > -/* For other HS-mode traps, we set this to 0. */
> > > -env->hstatus = set_field(env->hstatus, HSTATUS_GVA, 0);
> > > -}
> > > -
> > >  if (riscv_cpu_virt_enabled(env) && ((hdeleg >> cause) & 1)) {
> > >  /* Trap to VS mode */
> > >  /*
> > > @@ -1063,7 +1051,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
> > >  cause == IRQ_VS_EXT) {
> > >  cause = cause - 1;
> > >  }
> > > -env->hstatus = set_field(env->hstatus, HSTATUS_GVA, 0);
> > > +write_gva = false;
> > >  } else if (riscv_cpu_virt_enabled(env)) {
> > >  /* Trap into HS mode, from virt */
> > >  riscv_cpu_swap_hypervisor_regs(env);
> > > @@ -1072,6 +1060,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
> > >  env->hstatus = set_field(env->hstatus, HSTATUS_SPV,
> > >   riscv_cpu_virt_enabled(env));
> > >
> > > +
> > >  htval = env->guest_phys_fault_addr;
> > >
> > >  riscv_cpu_set_virt_enabled(env, 0);
> > > @@ -1079,7 +1068,9 @@ void riscv_cpu_do_interrupt(CPUState *cs)
> > >  /* Trap into HS mode */
> > >  env->hstatus = set_field(env->hstatus, HSTATUS_SPV, 
> > > false);
> > >  htval = env->guest_phys_fault_addr;
> > > +write_gva = false;
> > >  }
> > > +env->hstatus = set_field(env->hstatus, HSTATUS_GVA, 
> > > write_gva);
> >
> > This does not look correct to me.
> >
> > The env->hstatus[GVA] should remain untouched in the 2nd and 3rd
> > branch. It only needs to be set in the first branch.
>
> The RISC-V spec says:
>
> ""'
> Field GVA (Guest Virtual Address) is written by the implementation
> whenever a trap is taken
> into HS-mode. For any trap (breakpoint, address misaligned, access
> fault, page fault, or guest-
> page fault) that writes a guest virtual address to stval, GVA is set
> to 1. For any other trap into
> HS-mode, GVA is set to 0.
> """
>
> So it has to be set in the second and third branches as they are
> trapping into HS mode. I guess we could not touch it in the first
> branch (Trap to VS mode), but that means we would need to ensure it is
> updated later, so it seems easiest to just clear it here.

Thanks for the info.

>
> In 

Re: [RFC PATCH] target/ppc: Remove xscmpnedp instruction

2022-01-06 Thread David Gibson
On Thu, Jan 06, 2022 at 02:02:01PM +0100, Greg Kurz wrote:
> On Thu, 6 Jan 2022 13:21:46 +0100
> Cédric Le Goater  wrote:
> 
> > On 1/6/22 12:23, Víctor Colombo wrote:
> > > xscmpnedp was added in ISA v3.0 but removed in v3.0B. This patch
> > > removes this instruction as it was not in the final version of v3.0.
> > > 
> > > RFC to know if you think this is the correct approach.
> > 
> > Usually we deprecate a feature for a minimum of two releases before
> > removing it. It might be overkill for this case since the P9 processor
> > implementation is based on v3.0B.
> > 
> > I would simply remove the instruction since it never existed on any
> > supported HW. I will wait for some more feedback.
> > 
> 
> I don't think it makes sense to keep this instruction if it only
> existed in pre-GA HW.

I agree.  If we have a vistigial POWER9 DD1 in the cpu table we should
probably remove that anyway.

> Acked-by: Greg Kurz 

Signed-off-by: David Gibson 

> 
> > Reviewed-by: Cédric Le Goater 
> > 
> > Thanks,
> > 
> > C.
> > 
> > 
> > > Signed-off-by: Víctor Colombo 
> > > ---
> > >   target/ppc/fpu_helper.c | 1 -
> > >   target/ppc/helper.h | 1 -
> > >   target/ppc/translate/vsx-impl.c.inc | 1 -
> > >   target/ppc/translate/vsx-ops.c.inc  | 1 -
> > >   4 files changed, 4 deletions(-)
> > > 
> > > diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
> > > index e5c29b53b8..f030858cf9 100644
> > > --- a/target/ppc/fpu_helper.c
> > > +++ b/target/ppc/fpu_helper.c
> > > @@ -2270,7 +2270,6 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt,   
> > >   \
> > >   VSX_SCALAR_CMP_DP(xscmpeqdp, eq, 1, 0)
> > >   VSX_SCALAR_CMP_DP(xscmpgedp, le, 1, 1)
> > >   VSX_SCALAR_CMP_DP(xscmpgtdp, lt, 1, 1)
> > > -VSX_SCALAR_CMP_DP(xscmpnedp, eq, 0, 0)
> > >   
> > >   void helper_xscmpexpdp(CPUPPCState *env, uint32_t opcode,
> > >  ppc_vsr_t *xa, ppc_vsr_t *xb)
> > > diff --git a/target/ppc/helper.h b/target/ppc/helper.h
> > > index f9c72dcd50..8f02cabaf5 100644
> > > --- a/target/ppc/helper.h
> > > +++ b/target/ppc/helper.h
> > > @@ -400,7 +400,6 @@ DEF_HELPER_5(xsnmsubdp, void, env, vsr, vsr, vsr, vsr)
> > >   DEF_HELPER_4(xscmpeqdp, void, env, vsr, vsr, vsr)
> > >   DEF_HELPER_4(xscmpgtdp, void, env, vsr, vsr, vsr)
> > >   DEF_HELPER_4(xscmpgedp, void, env, vsr, vsr, vsr)
> > > -DEF_HELPER_4(xscmpnedp, void, env, vsr, vsr, vsr)
> > >   DEF_HELPER_4(xscmpexpdp, void, env, i32, vsr, vsr)
> > >   DEF_HELPER_4(xscmpexpqp, void, env, i32, vsr, vsr)
> > >   DEF_HELPER_4(xscmpodp, void, env, i32, vsr, vsr)
> > > diff --git a/target/ppc/translate/vsx-impl.c.inc 
> > > b/target/ppc/translate/vsx-impl.c.inc
> > > index c08185e857..fbef496257 100644
> > > --- a/target/ppc/translate/vsx-impl.c.inc
> > > +++ b/target/ppc/translate/vsx-impl.c.inc
> > > @@ -1092,7 +1092,6 @@ GEN_VSX_HELPER_X1(xstsqrtdp, 0x14, 0x06, 0, 
> > > PPC2_VSX)
> > >   GEN_VSX_HELPER_X3(xscmpeqdp, 0x0C, 0x00, 0, PPC2_ISA300)
> > >   GEN_VSX_HELPER_X3(xscmpgtdp, 0x0C, 0x01, 0, PPC2_ISA300)
> > >   GEN_VSX_HELPER_X3(xscmpgedp, 0x0C, 0x02, 0, PPC2_ISA300)
> > > -GEN_VSX_HELPER_X3(xscmpnedp, 0x0C, 0x03, 0, PPC2_ISA300)
> > >   GEN_VSX_HELPER_X2_AB(xscmpexpdp, 0x0C, 0x07, 0, PPC2_ISA300)
> > >   GEN_VSX_HELPER_R2_AB(xscmpexpqp, 0x04, 0x05, 0, PPC2_ISA300)
> > >   GEN_VSX_HELPER_X2_AB(xscmpodp, 0x0C, 0x05, 0, PPC2_VSX)
> > > diff --git a/target/ppc/translate/vsx-ops.c.inc 
> > > b/target/ppc/translate/vsx-ops.c.inc
> > > index c974324c4c..67fa7b2e41 100644
> > > --- a/target/ppc/translate/vsx-ops.c.inc
> > > +++ b/target/ppc/translate/vsx-ops.c.inc
> > > @@ -197,7 +197,6 @@ GEN_XX3FORM_NAME(xsnmsubdp, "xsnmsubmdp", 0x04, 0x17, 
> > > PPC2_VSX),
> > >   GEN_XX3FORM(xscmpeqdp, 0x0C, 0x00, PPC2_ISA300),
> > >   GEN_XX3FORM(xscmpgtdp, 0x0C, 0x01, PPC2_ISA300),
> > >   GEN_XX3FORM(xscmpgedp, 0x0C, 0x02, PPC2_ISA300),
> > > -GEN_XX3FORM(xscmpnedp, 0x0C, 0x03, PPC2_ISA300),
> > >   GEN_XX3FORM(xscmpexpdp, 0x0C, 0x07, PPC2_ISA300),
> > >   GEN_VSX_XFORM_300(xscmpexpqp, 0x04, 0x05, 0x0061),
> > >   GEN_XX2IFORM(xscmpodp,  0x0C, 0x05, PPC2_VSX),
> > > 
> > 
> 

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [PATCH] Supporting AST2600 HACE engine accumulative mode

2022-01-06 Thread Troy Lee
On Thu, Jan 6, 2022 at 11:27 PM Peter Maydell  wrote:
>
> On Tue, 28 Dec 2021 at 03:34, Troy Lee  wrote:
> >
> > Hi Klaus,
> >
> > On Thu, Dec 23, 2021 at 11:57 PM Klaus Heinrich Kiwi
> >  wrote:
> > >
> > > Em qui., 23 de dez. de 2021 às 09:54, Cédric Le Goater  
> > > escreveu:
> > > >
> > > > [ Adding Klaus ]
> > >
> > > Thanks Cedric. It's been a while since I've looked at this but I'll do my 
> > > best..
> > >
> > > >
> > > > On 12/22/21 03:22, Troy Lee wrote:
>
>
> > > > > +/*
> > > > > + * Read the message length in bit from last 64/128 
> > > > > bits
> > > > > + * and tear the padding bits from iov
> > > > > + */
> > > > > +uint64_t stream_len;
> > > > > +
> > > > > +memcpy(_len, iov[i].iov_base + iov[i].iov_len 
> > > > > - 8, 8);
> > > > > +stream_len = __bswap_64(stream_len) / 8;
> > > > > +
> > >
> > > I no longer have access to the aspeed workbook I guess, but what is
> > > the actual specification here? is the message length 64 or 128 bits?
> > > and bswap seems arch-dependent - you probably want to be explicit if
> > > this is big or little-endian and use the appropriate conversion
> > > function.
> > The message length is described in RFC4634:
> > - SHA224 or SHA256 should be 64-bit.
> > - SHA384 or SHA512 should be 128-bit.
> > And it should be in big-endian.
>
> You can read a 64-bit BE value with
>  uint64_t val = ldq_be_p(iov[i].iov_base + iov[i].iov_len - 8);
> or similar. (We don't have a similar function for 128 bits because
> there's no fully-portable native C data type for that.)
>
> -- PMM

Thanks for the suggestion!
Troy Lee



Re: [PATCH v2 2/7] target/ppc: powerpc_excp: Keep 60x soft MMU logs active

2022-01-06 Thread Richard Henderson

On 1/5/22 12:40 PM, Fabiano Rosas wrote:

Remove the compile time definition and make the logging be controlled
by the `-d mmu` option in the cmdline.

Signed-off-by: Fabiano Rosas 
Reviewed-by: Cédric Le Goater 
---
  target/ppc/excp_helper.c | 15 ++-
  1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 2c5d5470de..ce86b2ae37 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -30,8 +30,6 @@
  #include "exec/cpu_ldst.h"
  #endif
  
-/* #define DEBUG_SOFTWARE_TLB */

-
  
/*/
  /* Exception processing */
  #if !defined(CONFIG_USER_ONLY)
@@ -137,7 +135,6 @@ static void dump_hcall(CPUPPCState *env)
  
  static void ppc_excp_debug_sw_tlb(CPUPPCState *env, int excp)

  {
-#if defined(DEBUG_SOFTWARE_TLB)
  const char *es;
  target_ulong *miss, *cmp;
  int en;
@@ -161,12 +158,12 @@ static void ppc_excp_debug_sw_tlb(CPUPPCState *env, int 
excp)
  miss = >spr[SPR_DMISS];
  cmp = >spr[SPR_DCMP];
  }
-qemu_log("6xx %sTLB miss: %cM " TARGET_FMT_lx " %cC "
- TARGET_FMT_lx " H1 " TARGET_FMT_lx " H2 "
- TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp,
- env->spr[SPR_HASH1], env->spr[SPR_HASH2],
- env->error_code);
-#endif
+
+qemu_log_mask(CPU_LOG_MMU, "6xx %sTLB miss: %cM " TARGET_FMT_lx " %cC "
+  TARGET_FMT_lx " H1 " TARGET_FMT_lx " H2 "
+  TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp,
+  env->spr[SPR_HASH1], env->spr[SPR_HASH2],
+  env->error_code);


Ah, then my comment wrt patch 1 applies to this one -- use the proper filter function at 
the top of this one, before all of the data collection for the actual logging.



r~



Re: [PATCH v2 1/7] target/ppc: powerpc_excp: Extract software TLB logging into a function

2022-01-06 Thread Richard Henderson

On 1/5/22 12:40 PM, Fabiano Rosas wrote:

Signed-off-by: Fabiano Rosas
---
  target/ppc/excp_helper.c | 63 +++-
  1 file changed, 36 insertions(+), 27 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index a779dc936a..2c5d5470de 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -135,6 +135,41 @@ static void dump_hcall(CPUPPCState *env)
env->nip);
  }
  
+static void ppc_excp_debug_sw_tlb(CPUPPCState *env, int excp)

+{
+#if defined(DEBUG_SOFTWARE_TLB)
+const char *es;
+target_ulong *miss, *cmp;
+int en;
+
+if (!qemu_log_enabled()) {
+return;
+}
+


Because code movement,
Reviewed-by: Richard Henderson 

Better is qemu_loglevel_mask(CPU_LOG_MMU)
and perhaps then you can remove the ifdef.


r~



Re: [PATCH] target/arm: Add missing FEAT_TLBIOS instructions

2022-01-06 Thread Richard Henderson

On 12/31/21 2:39 AM, Idan Horowitz wrote:

Some of the instructions added by the FEAT_TLBIOS extension were forgotten
when the extension was originally added to QEMU.

Fixes: 7113d618505b ("target/arm: Add support for FEAT_TLBIOS")
Signed-off-by: Idan Horowitz
---
  target/arm/helper.c | 32 
  1 file changed, 32 insertions(+)


Reviewed-by: Richard Henderson 


r~



Re: [ PATCH v3 08/10] target/riscv: Add sscofpmf extension support

2022-01-06 Thread Atish Patra
On Sun, Dec 26, 2021 at 8:38 PM Frank Chang  wrote:
>
> Atish Patra  於 2021年10月26日 週二 上午3:57寫道:
>>
>> The Sscofpmf ('Ss' for Privileged arch and Supervisor-level extensions,
>> and 'cofpmf' for Count OverFlow and Privilege Mode Filtering)
>> extension allows the perf to handle overflow interrupts and filtering
>> support. This patch provides a framework for programmable
>> counters to leverage the extension. As the extension doesn't have any
>> provision for the overflow bit for fixed counters, the fixed events
>> can also be monitoring using programmable counters. The underlying
>> counters for cycle and instruction counters are always running. Thus,
>> a separate timer device is programmed to handle the overflow.
>>
>> Signed-off-by: Atish Patra 
>> ---
>>  target/riscv/cpu.c  |  12 ++
>>  target/riscv/cpu.h  |  25 +++
>>  target/riscv/cpu_bits.h |  55 +++
>>  target/riscv/csr.c  | 150 +-
>>  target/riscv/machine.c  |   2 +-
>>  target/riscv/pmu.c  | 343 +++-
>>  target/riscv/pmu.h  |   9 ++
>>  7 files changed, 589 insertions(+), 7 deletions(-)
>>
>> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
>> index aec94101a4c0..757c646037bb 100644
>> --- a/target/riscv/cpu.c
>> +++ b/target/riscv/cpu.c
>> @@ -22,6 +22,7 @@
>>  #include "qemu/ctype.h"
>>  #include "qemu/log.h"
>>  #include "cpu.h"
>> +#include "pmu.h"
>>  #include "internals.h"
>>  #include "exec/exec-all.h"
>>  #include "qapi/error.h"
>> @@ -535,6 +536,16 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
>> **errp)
>>  set_misa(env, target_misa);
>>  }
>>
>> +if (cpu->cfg.pmu_num) {
>> +if (!riscv_pmu_init(cpu, cpu->cfg.pmu_num) && cpu->cfg.ext_sscof) {
>> +cpu->pmu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
>> +  riscv_pmu_timer_cb, cpu);
>> +if (!cpu->pmu_timer) {
>> +cpu->cfg.ext_sscof = false;
>> +}
>> +}
>> + }
>> +
>>  riscv_cpu_register_gdb_regs_for_features(cs);
>>
>>  qemu_init_vcpu(cs);
>> @@ -599,6 +610,7 @@ static Property riscv_cpu_properties[] = {
>>  DEFINE_PROP_BOOL("x-h", RISCVCPU, cfg.ext_h, false),
>>  DEFINE_PROP_BOOL("x-v", RISCVCPU, cfg.ext_v, false),
>>  DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
>> +DEFINE_PROP_BOOL("sscof", RISCVCPU, cfg.ext_sscof, false),
>>  DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
>>  DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
>>  DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
>> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
>> index da34614ad788..b66d8acff109 100644
>> --- a/target/riscv/cpu.h
>> +++ b/target/riscv/cpu.h
>> @@ -123,6 +123,8 @@ struct PMUCTRState {
>>  /* Snapshort value of a counter in RV32 */
>>  target_ulong mhpmcounterh_prev;
>>  bool started;
>> +/* Value beyond UINT32_MAX/UINT64_MAX before overflow interrupt trigger 
>> */
>> +target_ulong irq_overflow_left;
>>  };
>>
>>  struct CPURISCVState {
>> @@ -241,6 +243,9 @@ struct CPURISCVState {
>>  /* PMU event selector configured values. First three are unused*/
>>  target_ulong mhpmevent_val[RV_MAX_MHPMEVENTS];
>>
>> +/* PMU event selector configured values for RV32*/
>> +target_ulong mhpmeventh_val[RV_MAX_MHPMEVENTS];
>> +
>>  target_ulong sscratch;
>>  target_ulong mscratch;
>>
>> @@ -320,6 +325,7 @@ struct RISCVCPU {
>>  bool ext_zbs;
>>  bool ext_ifencei;
>>  bool ext_icsr;
>> +bool ext_sscof;
>>
>>  uint8_t pmu_num;
>>  char *priv_spec;
>> @@ -333,6 +339,12 @@ struct RISCVCPU {
>>  bool epmp;
>>  uint64_t resetvec;
>>  } cfg;
>> +
>> +QEMUTimer *pmu_timer;
>> +/* A bitmask of Available programmable counters */
>> +uint32_t pmu_avail_ctrs;
>> +/* Mapping of events to counters */
>> +GHashTable *pmu_event_ctr_map;
>>  };
>>
>>  static inline int riscv_has_ext(CPURISCVState *env, target_ulong ext)
>> @@ -528,6 +540,19 @@ enum {
>>  CSR_TABLE_SIZE = 0x1000
>>  };
>>
>> +/**
>> + * The event id are encoded based on the encoding specified in the
>> + * SBI specification v0.3
>> + */
>> +
>> +enum riscv_pmu_event_idx {
>> +RISCV_PMU_EVENT_HW_CPU_CYCLES = 0x01,
>> +RISCV_PMU_EVENT_HW_INSTRUCTIONS = 0x02,
>> +RISCV_PMU_EVENT_CACHE_DTLB_READ_MISS = 0x10019,
>> +RISCV_PMU_EVENT_CACHE_DTLB_WRITE_MISS = 0x1001B,
>> +RISCV_PMU_EVENT_CACHE_ITLB_PREFETCH_MISS = 0x10021,
>> +};
>> +
>>  /* CSR function table */
>>  extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
>>
>> diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
>> index 72b1485e621f..cd6523c1c6ee 100644
>> --- a/target/riscv/cpu_bits.h
>> +++ b/target/riscv/cpu_bits.h
>> @@ -308,6 +308,37 @@
>>  #define CSR_MHPMEVENT29 0x33d
>>  #define CSR_MHPMEVENT30 0x33e
>>  #define CSR_MHPMEVENT31 

Re: [PATCH v2 5/9] hw/rdma/rdma_utils: Rename rdma_pci_dma_map 'len' argument

2022-01-06 Thread Richard Henderson

On 1/4/22 12:54 AM, Philippe Mathieu-Daudé wrote:

From: Philippe Mathieu-Daudé

Various APIs use 'pval' naming for 'pointer to val'.
rdma_pci_dma_map() uses 'plen' for 'PCI length', but since
'PCI' is already explicit in the function name, simplify
and rename the argument 'len'. No logical change.

Signed-off-by: Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé
---
  hw/rdma/rdma_utils.h |  2 +-
  hw/rdma/rdma_utils.c | 14 +++---
  2 files changed, 8 insertions(+), 8 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2 7/9] hw/dma: Fix format string issues using dma_addr_t

2022-01-06 Thread Richard Henderson

On 1/4/22 12:54 AM, Philippe Mathieu-Daudé wrote:

Signed-off-by: Philippe Mathieu-Daudé
---
  hw/ide/ahci.c| 2 +-
  hw/rdma/trace-events | 2 +-
  2 files changed, 2 insertions(+), 2 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2 4/9] hw/dma: Remove CONFIG_USER_ONLY check

2022-01-06 Thread Richard Henderson

On 1/4/22 12:54 AM, Philippe Mathieu-Daudé wrote:

From: Philippe Mathieu-Daudé

DMA API should not be included in user-mode emulation.
If so, build should fail. Remove the CONFIG_USER_ONLY check.

Signed-off-by: Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé
---
  include/sysemu/dma.h | 3 ---
  1 file changed, 3 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2 6/9] hw/scsi: Rename SCSIRequest::resid as 'residual'

2022-01-06 Thread Richard Henderson

On 1/4/22 12:54 AM, Philippe Mathieu-Daudé wrote:

From: Philippe Mathieu-Daudé

The 'resid' field is slightly confusing and could be
interpreted as some ID. Rename it as 'residual' which
is clearer to review. No logical change.

Signed-off-by: Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé
---
  include/hw/scsi/scsi.h |  4 ++--
  hw/scsi/megasas.c  | 42 +-
  hw/scsi/scsi-bus.c | 10 +-
  hw/scsi/scsi-disk.c|  4 ++--
  softmmu/dma-helpers.c  | 26 +-
  5 files changed, 47 insertions(+), 39 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2 3/9] hw/pci: Document pci_dma_map()

2022-01-06 Thread Richard Henderson

On 1/4/22 12:54 AM, Philippe Mathieu-Daudé wrote:

From: Philippe Mathieu-Daudé 

Signed-off-by: Philippe Mathieu-Daudé 
Signed-off-by: Philippe Mathieu-Daudé 
---
  include/hw/pci/pci.h | 12 
  1 file changed, 12 insertions(+)

diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 5b36334a28a..07f08aa0626 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -876,6 +876,18 @@ PCI_DMA_DEFINE_LDST(q_be, q_be, 64);
  
  #undef PCI_DMA_DEFINE_LDST
  
+/**

+ * pci_dma_map: Map device PCI address space range into host virtual address
+ *
+ * May map a subset of the requested range, given by and returned in @plen.
+ * May return %NULL and set *@plen to zero(0), if resources needed to perform
+ * the mapping are exhausted.
+ *
+ * @dev: #PCIDevice to be accessed
+ * @addr: address within that device's address space
+ * @plen: pointer to length of buffer; updated on return
+ * @dir: indicates the transfer direction
+ */


As Peter recently mentioned, the ** format is off.
The description goes below the arguments.

Otherwise,
Reviewed-by: Richard Henderson 


r~



Re: [PATCH v2 2/9] hw/pci: Restrict pci-bus stub to sysemu

2022-01-06 Thread Richard Henderson

On 1/4/22 12:54 AM, Philippe Mathieu-Daudé wrote:

From: Philippe Mathieu-Daudé

Neither tools nor user-mode emulation require the PCI bus stub.

Signed-off-by: Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé
---
  stubs/meson.build | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2 1/9] hw/nvram: Restrict stub to sysemu and tools

2022-01-06 Thread Richard Henderson

On 1/4/22 12:54 AM, Philippe Mathieu-Daudé wrote:

+if have_system or have_tools

...

  if have_system
+  stub_ss.add(files('fw_cfg.c'))


Disconnect in tests?


r~



Re: [PATCH v1 25/34] linux-user/elfload: add extra logging for hole finding

2022-01-06 Thread Richard Henderson

On 1/5/22 5:50 AM, Alex Bennée wrote:

The various approaches to finding memory holes are quite complicated
to follow especially at a distance. Improve the logging so we can see
exactly what method found the space for the guest memory.

Signed-off-by: Alex Bennée
---
  linux-user/elfload.c | 18 ++
  1 file changed, 18 insertions(+)


Reviewed-by: Richard Henderson 

r~



[PATCH 4/5] hw/sensor: add Renesas raa229004 PMBus device

2022-01-06 Thread Titus Rwantare
The Renesas RAA229004 is a PMBus Multiphase Voltage Regulator

Signed-off-by: Titus Rwantare 
Reviewed-by: Hao Wu 
---
 hw/sensor/isl_pmbus.c | 18 ++
 include/hw/sensor/isl_pmbus.h |  1 +
 tests/qtest/isl_pmbus-test.c  |  7 +++
 3 files changed, 26 insertions(+)

diff --git a/hw/sensor/isl_pmbus.c b/hw/sensor/isl_pmbus.c
index 8cc7220a57..4ff848f663 100644
--- a/hw/sensor/isl_pmbus.c
+++ b/hw/sensor/isl_pmbus.c
@@ -194,6 +194,15 @@ static void isl69260_class_init(ObjectClass *klass, void 
*data)
 isl_pmbus_class_init(klass, data, 2);
 }
 
+static void raa229004_class_init(ObjectClass *klass, void *data)
+{
+ResettableClass *rc = RESETTABLE_CLASS(klass);
+DeviceClass *dc = DEVICE_CLASS(klass);
+dc->desc = "Renesas 229004 Digital Multiphase Voltage Regulator";
+rc->phases.exit = isl_pmbus_exit_reset;
+isl_pmbus_class_init(klass, data, 2);
+}
+
 static const TypeInfo isl69260_info = {
 .name = TYPE_ISL69260,
 .parent = TYPE_PMBUS_DEVICE,
@@ -202,9 +211,18 @@ static const TypeInfo isl69260_info = {
 .class_init = isl69260_class_init,
 };
 
+static const TypeInfo raa229004_info = {
+.name = TYPE_RAA229004,
+.parent = TYPE_PMBUS_DEVICE,
+.instance_size = sizeof(ISLState),
+.instance_init = raa22xx_init,
+.class_init = raa229004_class_init,
+};
+
 static void isl_pmbus_register_types(void)
 {
 type_register_static(_info);
+type_register_static(_info);
 }
 
 type_init(isl_pmbus_register_types)
diff --git a/include/hw/sensor/isl_pmbus.h b/include/hw/sensor/isl_pmbus.h
index 8115aaa698..a947fd3903 100644
--- a/include/hw/sensor/isl_pmbus.h
+++ b/include/hw/sensor/isl_pmbus.h
@@ -13,6 +13,7 @@
 #include "qom/object.h"
 
 #define TYPE_ISL69260   "isl69260"
+#define TYPE_RAA229004  "raa229004"
 
 struct ISLState {
 PMBusDevice parent;
diff --git a/tests/qtest/isl_pmbus-test.c b/tests/qtest/isl_pmbus-test.c
index 3e956f912c..5bdc247428 100644
--- a/tests/qtest/isl_pmbus-test.c
+++ b/tests/qtest/isl_pmbus-test.c
@@ -372,10 +372,17 @@ static void isl_pmbus_register_nodes(void)
 qos_node_create_driver("isl69260", i2c_device_create);
 qos_node_consumes("isl69260", "i2c-bus", );
 
+qos_node_create_driver("raa229004", i2c_device_create);
+qos_node_consumes("raa229004", "i2c-bus", );
+
 qos_add_test("test_defaults", "isl69260", test_defaults, NULL);
 qos_add_test("test_tx_rx", "isl69260", test_tx_rx, NULL);
 qos_add_test("test_rw_regs", "isl69260", test_rw_regs, NULL);
 qos_add_test("test_ro_regs", "isl69260", test_ro_regs, NULL);
 qos_add_test("test_ov_faults", "isl69260", test_voltage_faults, NULL);
+
+qos_add_test("test_tx_rx", "raa229004", test_tx_rx, NULL);
+qos_add_test("test_rw_regs", "raa229004", test_rw_regs, NULL);
+qos_add_test("test_ov_faults", "raa229004", test_voltage_faults, NULL);
 }
 libqos_init(isl_pmbus_register_nodes);
-- 
2.34.1.448.ga2b2bfdf31-goog




[PATCH 3/5] hw/sensor: add Intersil ISL69260 device model

2022-01-06 Thread Titus Rwantare
Signed-off-by: Titus Rwantare 
Reviewed-by: Hao Wu 
---
 MAINTAINERS   |   3 +
 hw/arm/Kconfig|   1 +
 hw/sensor/Kconfig |   5 +
 hw/sensor/isl_pmbus.c | 210 +++
 hw/sensor/meson.build |   1 +
 include/hw/sensor/isl_pmbus.h |  50 +
 tests/qtest/isl_pmbus-test.c  | 381 ++
 tests/qtest/meson.build   |   1 +
 8 files changed, 652 insertions(+)
 create mode 100644 hw/sensor/isl_pmbus.c
 create mode 100644 include/hw/sensor/isl_pmbus.h
 create mode 100644 tests/qtest/isl_pmbus-test.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 6349e3da1f..156c5812a8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3034,10 +3034,13 @@ M: Titus Rwantare 
 S: Maintained
 F: hw/i2c/pmbus_device.c
 F: hw/sensor/adm1272.c
+F: hw/sensor/isl_pmbus.c
 F: hw/sensor/max34451.c
 F: include/hw/i2c/pmbus_device.h
+F: include/hw/sensor/isl_pmbus.h
 F: tests/qtest/adm1272-test.c
 F: tests/qtest/max34451-test.c
+F: tests/qtest/isl_pmbus-test.c
 
 Firmware schema specifications
 M: Philippe Mathieu-Daudé 
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index e652590943..019099df96 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -393,6 +393,7 @@ config NPCM7XX
 select SMBUS
 select AT24C  # EEPROM
 select MAX34451
+select ISL_PMBUS
 select PL310  # cache controller
 select PMBUS
 select SERIAL
diff --git a/hw/sensor/Kconfig b/hw/sensor/Kconfig
index 9c8a049b06..f935d9cccb 100644
--- a/hw/sensor/Kconfig
+++ b/hw/sensor/Kconfig
@@ -21,3 +21,8 @@ config ADM1272
 config MAX34451
 bool
 depends on I2C
+
+config ISL_PMBUS
+bool
+depends on I2C
+
diff --git a/hw/sensor/isl_pmbus.c b/hw/sensor/isl_pmbus.c
new file mode 100644
index 00..8cc7220a57
--- /dev/null
+++ b/hw/sensor/isl_pmbus.c
@@ -0,0 +1,210 @@
+/*
+ * PMBus device for Renesas Digital Multiphase Voltage Regulators
+ *
+ * Copyright 2021 Google LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sensor/isl_pmbus.h"
+#include "hw/qdev-properties.h"
+#include "qapi/visitor.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+
+static uint8_t isl_pmbus_read_byte(PMBusDevice *pmdev)
+{
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: reading from unsupported register: 0x%02x\n",
+  __func__, pmdev->code);
+return 0xFF;
+}
+
+static int isl_pmbus_write_data(PMBusDevice *pmdev, const uint8_t *buf,
+  uint8_t len)
+{
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: write to unsupported register: 0x%02x\n",
+  __func__, pmdev->code);
+return 0xFF;
+}
+
+/* TODO: Implement coefficients support in pmbus_device.c for qmp */
+static void isl_pmbus_get(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+visit_type_uint16(v, name, (uint16_t *)opaque, errp);
+}
+
+static void isl_pmbus_set(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+PMBusDevice *pmdev = PMBUS_DEVICE(obj);
+uint16_t *internal = opaque;
+uint16_t value;
+if (!visit_type_uint16(v, name, , errp)) {
+return;
+}
+
+*internal = value;
+pmbus_check_limits(pmdev);
+}
+
+static void isl_pmbus_exit_reset(Object *obj)
+{
+PMBusDevice *pmdev = PMBUS_DEVICE(obj);
+
+pmdev->page = 0;
+pmdev->capability = ISL_CAPABILITY_DEFAULT;
+for (int i = 0; i < pmdev->num_pages; i++) {
+pmdev->pages[i].operation = ISL_OPERATION_DEFAULT;
+pmdev->pages[i].on_off_config = ISL_ON_OFF_CONFIG_DEFAULT;
+pmdev->pages[i].vout_mode = ISL_VOUT_MODE_DEFAULT;
+pmdev->pages[i].vout_command = ISL_VOUT_COMMAND_DEFAULT;
+pmdev->pages[i].vout_max = ISL_VOUT_MAX_DEFAULT;
+pmdev->pages[i].vout_margin_high = ISL_VOUT_MARGIN_HIGH_DEFAULT;
+pmdev->pages[i].vout_margin_low = ISL_VOUT_MARGIN_LOW_DEFAULT;
+pmdev->pages[i].vout_transition_rate = 
ISL_VOUT_TRANSITION_RATE_DEFAULT;
+pmdev->pages[i].vout_ov_fault_limit = ISL_VOUT_OV_FAULT_LIMIT_DEFAULT;
+pmdev->pages[i].ot_fault_limit = ISL_OT_FAULT_LIMIT_DEFAULT;
+pmdev->pages[i].ot_warn_limit = ISL_OT_WARN_LIMIT_DEFAULT;
+pmdev->pages[i].vin_ov_warn_limit = ISL_VIN_OV_WARN_LIMIT_DEFAULT;
+pmdev->pages[i].vin_uv_warn_limit = ISL_VIN_UV_WARN_LIMIT_DEFAULT;
+pmdev->pages[i].iin_oc_fault_limit = ISL_IIN_OC_FAULT_LIMIT_DEFAULT;
+pmdev->pages[i].ton_delay = ISL_TON_DELAY_DEFAULT;
+pmdev->pages[i].ton_rise = ISL_TON_RISE_DEFAULT;
+pmdev->pages[i].toff_fall = ISL_TOFF_FALL_DEFAULT;
+pmdev->pages[i].revision = ISL_REVISION_DEFAULT;
+
+pmdev->pages[i].read_vout = ISL_READ_VOUT_DEFAULT;
+pmdev->pages[i].read_iout = ISL_READ_IOUT_DEFAULT;
+pmdev->pages[i].read_pout = ISL_READ_POUT_DEFAULT;
+

[PATCH 2/5] hw/i2c: Added linear mode translation for pmbus devices

2022-01-06 Thread Titus Rwantare
From: Shengtan Mao 

Signed-off-by: Shengtan Mao 
Reviewed-by: Titus Rwantare 
---
 hw/i2c/pmbus_device.c | 18 ++
 include/hw/i2c/pmbus_device.h | 20 +++-
 2 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/hw/i2c/pmbus_device.c b/hw/i2c/pmbus_device.c
index 3beb02afad..1036c41c49 100644
--- a/hw/i2c/pmbus_device.c
+++ b/hw/i2c/pmbus_device.c
@@ -28,6 +28,24 @@ uint32_t pmbus_direct_mode2data(PMBusCoefficients c, 
uint16_t value)
 return x;
 }
 
+uint16_t pmbus_data2linear_mode(uint16_t value, int exp)
+{
+/* L = D * 2^(-e) */
+if (exp < 0) {
+return value << (-exp);
+}
+return value >> exp;
+}
+
+uint16_t pmbus_linear_mode2data(uint16_t value, int exp)
+{
+/* D = L * 2^e */
+if (exp < 0) {
+return value >> (-exp);
+}
+return value << exp;
+}
+
 void pmbus_send(PMBusDevice *pmdev, const uint8_t *data, uint16_t len)
 {
 if (pmdev->out_buf_len + len > SMBUS_DATA_MAX_LEN) {
diff --git a/include/hw/i2c/pmbus_device.h b/include/hw/i2c/pmbus_device.h
index 72c0483149..9a274247ab 100644
--- a/include/hw/i2c/pmbus_device.h
+++ b/include/hw/i2c/pmbus_device.h
@@ -446,7 +446,7 @@ typedef struct PMBusCoefficients {
  *
  * Y = (m * x - b) * 10^R
  *
- * @return uint32_t
+ * @return uint16_t
  */
 uint16_t pmbus_data2direct_mode(PMBusCoefficients c, uint32_t value);
 
@@ -459,6 +459,24 @@ uint16_t pmbus_data2direct_mode(PMBusCoefficients c, 
uint32_t value);
  */
 uint32_t pmbus_direct_mode2data(PMBusCoefficients c, uint16_t value);
 
+/**
+ * Convert sensor values to linear mode format
+ *
+ * L = D * 2^(-e)
+ *
+ * @return uint16
+ */
+uint16_t pmbus_data2linear_mode(uint16_t value, int exp);
+
+/**
+ * Convert linear mode formatted data into sensor reading
+ *
+ * D = L * 2^e
+ *
+ * @return uint16
+ */
+uint16_t pmbus_linear_mode2data(uint16_t value, int exp);
+
 /**
  * @brief Send a block of data over PMBus
  * Assumes that the bytes in the block are already ordered correctly,
-- 
2.34.1.448.ga2b2bfdf31-goog




[PATCH 0/5] Fixups for PMBus and new sensors

2022-01-06 Thread Titus Rwantare
This patch series contains updates to PMBus in QEMU along with some PMBus
device models for Renesas regulators.
I have also added myself to MAINTAINERS as this code is in use daily,
where I am responsible for it.

Shengtan Mao (1):
  hw/i2c: Added linear mode translation for pmbus devices

Titus Rwantare (4):
  hw/i2c: pmbus updates
  hw/sensor: add Intersil ISL69260 device model
  hw/sensor: add Renesas raa229004 PMBus device
  hw/misc: add Renesas raa228000 device

 MAINTAINERS   |  15 +-
 hw/arm/Kconfig|   1 +
 hw/i2c/pmbus_device.c | 106 +++-
 hw/sensor/Kconfig |   5 +
 hw/sensor/isl_pmbus.c | 278 
 hw/sensor/meson.build |   1 +
 include/hw/i2c/pmbus_device.h |  23 +-
 include/hw/sensor/isl_pmbus.h |  52 
 tests/qtest/isl_pmbus-test.c  | 460 ++
 tests/qtest/meson.build   |   1 +
 10 files changed, 930 insertions(+), 12 deletions(-)
 create mode 100644 hw/sensor/isl_pmbus.c
 create mode 100644 include/hw/sensor/isl_pmbus.h
 create mode 100644 tests/qtest/isl_pmbus-test.c

-- 
2.34.1.448.ga2b2bfdf31-goog




[PATCH 1/5] hw/i2c: pmbus updates

2022-01-06 Thread Titus Rwantare
  - add vout min register
  - add PEC unsupported warning to pmbus_device class
  - guard against out of range pmbus page accesses

Signed-off-by: Titus Rwantare 
Reviewed-by: Hao Wu 
---
 MAINTAINERS   | 12 -
 hw/i2c/pmbus_device.c | 88 +++
 include/hw/i2c/pmbus_device.h |  3 ++
 3 files changed, 92 insertions(+), 11 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index f871d759fd..6349e3da1f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2790,7 +2790,7 @@ R: Paolo Bonzini 
 R: Bandan Das 
 R: Stefan Hajnoczi 
 R: Thomas Huth 
-R: Darren Kenny  
+R: Darren Kenny 
 R: Qiuhao Li 
 S: Maintained
 F: tests/qtest/fuzz/
@@ -3029,6 +3029,16 @@ F: include/hw/i2c/smbus_master.h
 F: include/hw/i2c/smbus_slave.h
 F: include/hw/i2c/smbus_eeprom.h
 
+PMBus
+M: Titus Rwantare 
+S: Maintained
+F: hw/i2c/pmbus_device.c
+F: hw/sensor/adm1272.c
+F: hw/sensor/max34451.c
+F: include/hw/i2c/pmbus_device.h
+F: tests/qtest/adm1272-test.c
+F: tests/qtest/max34451-test.c
+
 Firmware schema specifications
 M: Philippe Mathieu-Daudé 
 R: Daniel P. Berrange 
diff --git a/hw/i2c/pmbus_device.c b/hw/i2c/pmbus_device.c
index 24f8f522d9..3beb02afad 100644
--- a/hw/i2c/pmbus_device.c
+++ b/hw/i2c/pmbus_device.c
@@ -89,16 +89,16 @@ void pmbus_send_string(PMBusDevice *pmdev, const char *data)
 }
 
 
-static uint64_t pmbus_receive_uint(const uint8_t *buf, uint8_t len)
+static uint64_t pmbus_receive_uint(PMBusDevice *pmdev)
 {
 uint64_t ret = 0;
 
 /* Exclude command code from return value */
-buf++;
-len--;
+pmdev->in_buf++;
+pmdev->in_buf_len--;
 
-for (int i = len - 1; i >= 0; i--) {
-ret = ret << 8 | buf[i];
+for (int i = pmdev->in_buf_len - 1; i >= 0; i--) {
+ret = ret << 8 | pmdev->in_buf[i];
 }
 return ret;
 }
@@ -110,7 +110,7 @@ uint8_t pmbus_receive8(PMBusDevice *pmdev)
   "%s: length mismatch. Expected 1 byte, got %d bytes\n",
   __func__, pmdev->in_buf_len - 1);
 }
-return pmbus_receive_uint(pmdev->in_buf, pmdev->in_buf_len);
+return pmbus_receive_uint(pmdev);
 }
 
 uint16_t pmbus_receive16(PMBusDevice *pmdev)
@@ -120,7 +120,7 @@ uint16_t pmbus_receive16(PMBusDevice *pmdev)
   "%s: length mismatch. Expected 2 bytes, got %d bytes\n",
   __func__, pmdev->in_buf_len - 1);
 }
-return pmbus_receive_uint(pmdev->in_buf, pmdev->in_buf_len);
+return pmbus_receive_uint(pmdev);
 }
 
 uint32_t pmbus_receive32(PMBusDevice *pmdev)
@@ -130,7 +130,7 @@ uint32_t pmbus_receive32(PMBusDevice *pmdev)
   "%s: length mismatch. Expected 4 bytes, got %d bytes\n",
   __func__, pmdev->in_buf_len - 1);
 }
-return pmbus_receive_uint(pmdev->in_buf, pmdev->in_buf_len);
+return pmbus_receive_uint(pmdev);
 }
 
 uint64_t pmbus_receive64(PMBusDevice *pmdev)
@@ -140,7 +140,7 @@ uint64_t pmbus_receive64(PMBusDevice *pmdev)
   "%s: length mismatch. Expected 8 bytes, got %d bytes\n",
   __func__, pmdev->in_buf_len - 1);
 }
-return pmbus_receive_uint(pmdev->in_buf, pmdev->in_buf_len);
+return pmbus_receive_uint(pmdev);
 }
 
 static uint8_t pmbus_out_buf_pop(PMBusDevice *pmdev)
@@ -243,18 +243,47 @@ void pmbus_check_limits(PMBusDevice *pmdev)
 }
 }
 
+/* assert the status_cml error upon receipt of malformed command */
+static void pmbus_cml_error(PMBusDevice *pmdev)
+{
+for (int i = 0; i < pmdev->num_pages; i++) {
+pmdev->pages[i].status_word |= PMBUS_STATUS_CML;
+pmdev->pages[i].status_cml |= PB_CML_FAULT_INVALID_CMD;
+}
+}
+
 static uint8_t pmbus_receive_byte(SMBusDevice *smd)
 {
 PMBusDevice *pmdev = PMBUS_DEVICE(smd);
 PMBusDeviceClass *pmdc = PMBUS_DEVICE_GET_CLASS(pmdev);
 uint8_t ret = 0xFF;
-uint8_t index = pmdev->page;
+uint8_t index;
 
 if (pmdev->out_buf_len != 0) {
 ret = pmbus_out_buf_pop(pmdev);
 return ret;
 }
 
+/*
+ * Reading from all pages will return the value from page 0,
+ * this is unspecified behaviour in general.
+ */
+if (pmdev->page == PB_ALL_PAGES) {
+index = 0;
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: tried to read from all pages\n",
+  __func__);
+pmbus_cml_error(pmdev);
+} else if (pmdev->page > pmdev->num_pages - 1) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: page %d is out of range\n",
+  __func__, pmdev->page);
+pmbus_cml_error(pmdev);
+return -1;
+} else {
+index = pmdev->page;
+}
+
 switch (pmdev->code) {
 case PMBUS_PAGE:
 pmbus_send8(pmdev, pmdev->page);
@@ -278,6 +307,11 @@ static uint8_t pmbus_receive_byte(SMBusDevice *smd)
 
 case PMBUS_CAPABILITY:
 pmbus_send8(pmdev, pmdev->capability);
+if (pmdev->capability & BIT(7)) {
+

[PATCH 5/5] hw/misc: add Renesas raa228000 device

2022-01-06 Thread Titus Rwantare
Signed-off-by: Titus Rwantare 
Reviewed-by: Hao Wu 
---
 hw/sensor/isl_pmbus.c | 50 ++
 include/hw/sensor/isl_pmbus.h |  1 +
 tests/qtest/isl_pmbus-test.c  | 78 +--
 3 files changed, 126 insertions(+), 3 deletions(-)

diff --git a/hw/sensor/isl_pmbus.c b/hw/sensor/isl_pmbus.c
index 4ff848f663..e3b42b119e 100644
--- a/hw/sensor/isl_pmbus.c
+++ b/hw/sensor/isl_pmbus.c
@@ -89,6 +89,24 @@ static void isl_pmbus_exit_reset(Object *obj)
 }
 }
 
+/* The raa228000 uses different direct mode coefficents from most isl devices 
*/
+static void raa228000_exit_reset(Object *obj)
+{
+isl_pmbus_exit_reset(obj);
+
+PMBusDevice *pmdev = PMBUS_DEVICE(obj);
+
+pmdev->pages[0].read_vout = 0;
+pmdev->pages[0].read_iout = 0;
+pmdev->pages[0].read_pout = 0;
+pmdev->pages[0].read_vin = 0;
+pmdev->pages[0].read_iin = 0;
+pmdev->pages[0].read_pin = 0;
+pmdev->pages[0].read_temperature_1 = 0;
+pmdev->pages[0].read_temperature_2 = 0;
+pmdev->pages[0].read_temperature_3 = 0;
+}
+
 static void isl_pmbus_add_props(Object *obj, uint64_t *flags, uint8_t pages)
 {
 PMBusDevice *pmdev = PMBUS_DEVICE(obj);
@@ -177,6 +195,20 @@ static void raa22xx_init(Object *obj)
 isl_pmbus_add_props(obj, flags, 2);
 }
 
+static void raa228000_init(Object *obj)
+{
+PMBusDevice *pmdev = PMBUS_DEVICE(obj);
+uint64_t flags[1];
+
+flags[0] = PB_HAS_VIN | PB_HAS_VOUT | PB_HAS_VOUT_MODE |
+   PB_HAS_VOUT_RATING | PB_HAS_VOUT_MARGIN | PB_HAS_IIN |
+   PB_HAS_IOUT | PB_HAS_PIN | PB_HAS_POUT | PB_HAS_TEMPERATURE |
+   PB_HAS_TEMP2 | PB_HAS_TEMP3 | PB_HAS_STATUS_MFR_SPECIFIC;
+
+pmbus_page_config(pmdev, 0, flags[0]);
+isl_pmbus_add_props(obj, flags, 1);
+}
+
 static void isl_pmbus_class_init(ObjectClass *klass, void *data, uint8_t pages)
 {
 PMBusDeviceClass *k = PMBUS_DEVICE_CLASS(klass);
@@ -194,6 +226,15 @@ static void isl69260_class_init(ObjectClass *klass, void 
*data)
 isl_pmbus_class_init(klass, data, 2);
 }
 
+static void raa228000_class_init(ObjectClass *klass, void *data)
+{
+ResettableClass *rc = RESETTABLE_CLASS(klass);
+DeviceClass *dc = DEVICE_CLASS(klass);
+dc->desc = "Renesas 228000 Digital Multiphase Voltage Regulator";
+rc->phases.exit = raa228000_exit_reset;
+isl_pmbus_class_init(klass, data, 1);
+}
+
 static void raa229004_class_init(ObjectClass *klass, void *data)
 {
 ResettableClass *rc = RESETTABLE_CLASS(klass);
@@ -219,9 +260,18 @@ static const TypeInfo raa229004_info = {
 .class_init = raa229004_class_init,
 };
 
+static const TypeInfo raa228000_info = {
+.name = TYPE_RAA228000,
+.parent = TYPE_PMBUS_DEVICE,
+.instance_size = sizeof(ISLState),
+.instance_init = raa228000_init,
+.class_init = raa228000_class_init,
+};
+
 static void isl_pmbus_register_types(void)
 {
 type_register_static(_info);
+type_register_static(_info);
 type_register_static(_info);
 }
 
diff --git a/include/hw/sensor/isl_pmbus.h b/include/hw/sensor/isl_pmbus.h
index a947fd3903..7ead1dc4a2 100644
--- a/include/hw/sensor/isl_pmbus.h
+++ b/include/hw/sensor/isl_pmbus.h
@@ -13,6 +13,7 @@
 #include "qom/object.h"
 
 #define TYPE_ISL69260   "isl69260"
+#define TYPE_RAA228000  "raa228000"
 #define TYPE_RAA229004  "raa229004"
 
 struct ISLState {
diff --git a/tests/qtest/isl_pmbus-test.c b/tests/qtest/isl_pmbus-test.c
index 5bdc247428..3b5fb2208d 100644
--- a/tests/qtest/isl_pmbus-test.c
+++ b/tests/qtest/isl_pmbus-test.c
@@ -149,6 +149,70 @@ static void test_defaults(void *obj, void *data, 
QGuestAllocator *alloc)
 g_assert_cmphex(i2c_value, ==, ISL_REVISION_DEFAULT);
 }
 
+static void raa228000_test_defaults(void *obj, void *data,
+QGuestAllocator *alloc)
+{
+uint16_t value, i2c_value;
+QI2CDevice *i2cdev = (QI2CDevice *)obj;
+
+value = qmp_isl_pmbus_get(TEST_ID, "vout[0]");
+g_assert_cmpuint(value, ==, 0);
+
+i2c_value = isl_pmbus_i2c_get16(i2cdev, PMBUS_READ_IOUT);
+g_assert_cmpuint(i2c_value, ==, 0);
+
+value = qmp_isl_pmbus_get(TEST_ID, "pout[0]");
+g_assert_cmpuint(value, ==, 0);
+
+i2c_value = i2c_get8(i2cdev, PMBUS_CAPABILITY);
+g_assert_cmphex(i2c_value, ==, ISL_CAPABILITY_DEFAULT);
+
+i2c_value = i2c_get8(i2cdev, PMBUS_OPERATION);
+g_assert_cmphex(i2c_value, ==, ISL_OPERATION_DEFAULT);
+
+i2c_value = i2c_get8(i2cdev, PMBUS_ON_OFF_CONFIG);
+g_assert_cmphex(i2c_value, ==, ISL_ON_OFF_CONFIG_DEFAULT);
+
+i2c_value = i2c_get8(i2cdev, PMBUS_VOUT_MODE);
+g_assert_cmphex(i2c_value, ==, ISL_VOUT_MODE_DEFAULT);
+
+i2c_value = isl_pmbus_i2c_get16(i2cdev, PMBUS_VOUT_COMMAND);
+g_assert_cmphex(i2c_value, ==, ISL_VOUT_COMMAND_DEFAULT);
+
+i2c_value = isl_pmbus_i2c_get16(i2cdev, PMBUS_VOUT_MAX);
+g_assert_cmphex(i2c_value, ==, ISL_VOUT_MAX_DEFAULT);
+
+i2c_value = isl_pmbus_i2c_get16(i2cdev, PMBUS_VOUT_MARGIN_HIGH);
+

Re: [PULL 00/52] virtio,pci,pc: features,fixes,cleanups

2022-01-06 Thread Richard Henderson

On 1/6/22 5:16 AM, Michael S. Tsirkin wrote:

Big changes that were tagged originally but did not make the cut:
- SRIOV/nvme (not sure they are my tree material anyway)
- TPM (blocked over Igor's compat concerns)
- ACPI ERST (some coding style violations)

The following changes since commit 7d4ae4d4978079d564d3b6354c90a949130409fe:

   Merge tag 'pull-request-2022-01-05' of https://gitlab.com/thuth/qemu into 
staging (2022-01-05 08:47:18 -0800)

are available in the Git repository at:

   git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_upstream

for you to fetch changes up to 9399c26697e7c9658d082c6390e143319decaef5:

   virtio/vhost-vsock: don't double close vhostfd, remove redundant cleanup 
(2022-01-06 07:16:25 -0500)


virtio,pci,pc: features,fixes,cleanups

New virtio mem options.
A vhost-user cleanup.
Control over smbios entry point type.
Config interrupt support for vdpa.
Fixes, cleanups all over the place.

Signed-off-by: Michael S. Tsirkin 


Andy Pei (1):
   hw/vhost-user-blk: turn on VIRTIO_BLK_F_SIZE_MAX feature for virtio blk 
device

Ani Sinha (2):
   MAINTAINERS: Add a separate entry for acpi/VIOT tables
   acpihp: simplify acpi_pcihp_disable_root_bus

Cindy Lu (10):
   virtio: introduce macro IRTIO_CONFIG_IRQ_IDX
   virtio-pci: decouple notifier from interrupt process
   virtio-pci: decouple the single vector from the interrupt process
   vhost: introduce new VhostOps vhost_set_config_call
   vhost-vdpa: add support for config interrupt
   virtio: add support for configure interrupt
   vhost: add support for configure interrupt
   virtio-net: add support for configure interrupt
   virtio-mmio: add support for configure interrupt
   virtio-pci: add support for configure interrupt

Daniil Tatianin (3):
   hw/scsi/vhost-scsi: don't leak vqs on error
   hw/scsi/vhost-scsi: don't double close vhostfd on error
   virtio/vhost-vsock: don't double close vhostfd, remove redundant cleanup

David Hildenbrand (12):
   virtio-mem: Don't skip alignment checks when warning about block size
   util/oslib-posix: Let touch_all_pages() return an error
   util/oslib-posix: Support MADV_POPULATE_WRITE for os_mem_prealloc()
   util/oslib-posix: Introduce and use MemsetContext for touch_all_pages()
   util/oslib-posix: Don't create too many threads with small memory or 
little pages
   util/oslib-posix: Avoid creating a single thread with MADV_POPULATE_WRITE
   util/oslib-posix: Support concurrent os_mem_prealloc() invocation
   util/oslib-posix: Forward SIGBUS to MCE handler under Linux
   virtio-mem: Support "prealloc=on" option
   linux-headers: sync VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE
   virtio-mem: Support VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE
   virtio-mem: Set "unplugged-inaccessible=auto" for the 7.0 machine on x86

Eduardo Habkost (3):
   smbios: Rename SMBIOS_ENTRY_POINT_* enums
   hw/smbios: Use qapi for SmbiosEntryPointType
   hw/i386: expose a "smbios-entry-point-type" PC machine property

Frederic Barrat (2):
   pci: Export the pci_intx() function
   pcie_aer: Don't trigger a LSI if none are defined

Igor Mammedov (4):
   acpi: fix QEMU crash when started with SLIC table
   tests: acpi: whitelist expected blobs before changing them
   tests: acpi: add SLIC table test
   tests: acpi: SLIC: update expected blobs

Jason Wang (1):
   intel-iommu: correctly check passthrough during translation

Laurent Vivier (1):
   trace-events,pci: unify trace events format

Michael S. Tsirkin (1):
   acpi: validate hotplug selector on access

Roman Kagan (9):
   vhost-user-blk: reconnect on any error during realize
   chardev/char-socket: tcp_chr_recv: don't clobber errno
   chardev/char-socket: tcp_chr_sync_read: don't clobber errno
   vhost-backend: avoid overflow on memslots_limit
   vhost-backend: stick to -errno error return convention
   vhost-vdpa: stick to -errno error return convention
   vhost-user: stick to -errno error return convention
   vhost: stick to -errno error return convention
   vhost-user-blk: propagate error return from generic vhost

Stefan Hajnoczi (1):
   virtio: signal after wrapping packed used_idx

Thomas Huth (2):
   hw/i386/pc: Add missing property descriptions
   docs: reSTify virtio-balloon-stats documentation and move to docs/interop

  qapi/machine.json  |  12 +
  hw/virtio/virtio-pci.h |   4 +-
  include/hw/firmware/smbios.h   |  10 +-
  include/hw/i386/pc.h   |   4 +
  include/hw/pci/pci.h   |   5 +
  include/hw/virtio/vhost-backend.h  |   3 +
  include/hw/virtio/vhost.h

[PATCH 1/4] linux-user: Do not special-case NULL for PR_GET_PDEATHSIG

2022-01-06 Thread Richard Henderson
The kernel does not special-case arg2 != NULL, so
neither should we.

Signed-off-by: Richard Henderson 
---
 linux-user/syscall.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index ce9d64896c..e8f9e0643e 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6444,7 +6444,7 @@ static abi_long do_prctl(CPUArchState *env, abi_long 
option, abi_long arg2,
 int deathsig;
 ret = get_errno(prctl(PR_GET_PDEATHSIG, ,
   arg3, arg4, arg5));
-if (!is_error(ret) && arg2 && put_user_s32(deathsig, arg2)) {
+if (!is_error(ret) && put_user_s32(deathsig, arg2)) {
 return -TARGET_EFAULT;
 }
 return ret;
-- 
2.25.1




[PATCH 4/4] linux-user: Implement capability prctls

2022-01-06 Thread Richard Henderson
This is PR_CAPBSET_READ, PR_CAPBSET_DROP and the "legacy"
PR_CAP_AMBIENT PR_GET_SECUREBITS, PR_SET_SECUREBITS.

All of these arguments are integer values only, and do not
require mapping of values between host and guest.

Signed-off-by: Richard Henderson 
---
 linux-user/syscall.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 8495f5e08e..4711afaf8c 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6504,10 +6504,15 @@ static abi_long do_prctl(CPUArchState *env, abi_long 
option, abi_long arg2,
 case PR_SET_UNALIGN:
 return do_prctl_set_unalign(env, arg2);
 
+case PR_CAP_AMBIENT:
+case PR_CAPBSET_READ:
+case PR_CAPBSET_DROP:
 case PR_GET_DUMPABLE:
 case PR_SET_DUMPABLE:
 case PR_GET_KEEPCAPS:
 case PR_SET_KEEPCAPS:
+case PR_GET_SECUREBITS:
+case PR_SET_SECUREBITS:
 case PR_GET_TIMING:
 case PR_SET_TIMING:
 case PR_GET_TIMERSLACK:
-- 
2.25.1




[PATCH 0/4] linux-user: prctl follow-ups

2022-01-06 Thread Richard Henderson
Hi Laurent, as requested.  I did all of the cap_task_prctl options,
and fixed a few existing bugs with PR_GET_DEATHSIG.

r~

Richard Henderson (4):
  linux-user: Do not special-case NULL for PR_GET_PDEATHSIG
  linux-user: Map signal number in PR_GET_PDEATHSIG
  linux-user: Implement PR_SET_PDEATHSIG
  linux-user: Implement capability prctls

 linux-user/syscall.c | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

-- 
2.25.1




[PATCH 3/4] linux-user: Implement PR_SET_PDEATHSIG

2022-01-06 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/syscall.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 9eb2fb2bb2..8495f5e08e 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6450,6 +6450,9 @@ static abi_long do_prctl(CPUArchState *env, abi_long 
option, abi_long arg2,
 }
 return ret;
 }
+case PR_SET_PDEATHSIG:
+return get_errno(prctl(PR_SET_PDEATHSIG, target_to_host_signal(arg2),
+   arg3, arg4, arg5));
 case PR_GET_NAME:
 {
 void *name = lock_user(VERIFY_WRITE, arg2, 16, 1);
-- 
2.25.1




[PATCH 2/4] linux-user: Map signal number in PR_GET_PDEATHSIG

2022-01-06 Thread Richard Henderson
Convert the host signal number to guest signal number
before returning the value to the guest.

Signed-off-by: Richard Henderson 
---
 linux-user/syscall.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index e8f9e0643e..9eb2fb2bb2 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6444,7 +6444,8 @@ static abi_long do_prctl(CPUArchState *env, abi_long 
option, abi_long arg2,
 int deathsig;
 ret = get_errno(prctl(PR_GET_PDEATHSIG, ,
   arg3, arg4, arg5));
-if (!is_error(ret) && put_user_s32(deathsig, arg2)) {
+if (!is_error(ret) &&
+put_user_s32(host_to_target_signal(deathsig), arg2)) {
 return -TARGET_EFAULT;
 }
 return ret;
-- 
2.25.1




Re: [PATCH V7 17/29] pci: export functions for cpr

2022-01-06 Thread Steven Sistare
On 1/5/2022 3:16 PM, Michael S. Tsirkin wrote:
> On Wed, Jan 05, 2022 at 12:22:25PM -0500, Steven Sistare wrote:
>> On 12/22/2021 6:07 PM, Michael S. Tsirkin wrote:
>>> On Wed, Dec 22, 2021 at 11:05:22AM -0800, Steve Sistare wrote:
 Export msix_is_pending, msix_init_vector_notifiers, and pci_update_mappings
 for use by cpr.  No functional change.

 Signed-off-by: Steve Sistare 
>>>
>>> With things like that, I prefer when the API is exported
>>> together with the patch that uses it.
>>> This was I can see why we are exporting these APIs.
>>> Esp wrt pci_update_mappings, it's designed as an
>>> internal API.
>>
>> Hi Michael, thanks very much for reviewing these patches.
>>
>> Serendipitously, I stopped calling pci_update_mappings from vfio code earlier
>> in the series.  I will revert its scope.
>>
>> I would prefer to keep this patch separate from the use of these functions in
>> "vfio-pci cpr part 2 msi", to make the latter smaller and easier to 
>> understand.
>> How about if I say more in this commit message? :
>>
>>   Export msix_is_pending and msix_init_vector_notifiers for use in vfio cpr.
>>   Both are needed in the vfio-pci post-load function during cpr-load.
>>   msix_is_pending is checked to enable the PBA memory region.
>>   msix_init_vector_notifiers is called to register notifier callbacks, 
>> without
>>   the other side effects of msix_set_vector_notifiers.
>>
>> - Steve
> 
> Well the reason the side effects are there is to avoid losing events,
> no? I'd like to figure out a bit better why we don't need them,

Currently I do not call vfio_msix_vector_do_use during resume, but
instead execute a subset of its actions in vfio_claim_vectors, which is
defined in vfio-cpr: cpr part 2.

> and when should users call msix_init_vector_notifiers versus
> msix_set_vector_notifiers.

If I call msix_set_vector_notifiers, it calls the use notifier
vfio_msix_vector_use, which calls vfio_msix_vector_do_use.  The latter
gets confused and breaks the vectors because vector-related fields are
only partially initialized.  The details are unimportant, because --

Instead of adding msix_init_vector_notifiers, I will call
msix_set_vector_notifiers, but bail from vfio_msix_vector_do_use if resuming.
Tested and works.

Thus this patch becomes simply "pci: export msix_is_pending".  I can keep it,
or fold it into "vfio-pci: cpr part 2 (msi)".  Your call.

- Steve

 ---
  hw/pci/msix.c | 20 ++--
  hw/pci/pci.c  |  3 +--
  include/hw/pci/msix.h |  5 +
  include/hw/pci/pci.h  |  1 +
  4 files changed, 21 insertions(+), 8 deletions(-)

 diff --git a/hw/pci/msix.c b/hw/pci/msix.c
 index ae9331c..73f4259 100644
 --- a/hw/pci/msix.c
 +++ b/hw/pci/msix.c
 @@ -64,7 +64,7 @@ static uint8_t *msix_pending_byte(PCIDevice *dev, int 
 vector)
  return dev->msix_pba + vector / 8;
  }
  
 -static int msix_is_pending(PCIDevice *dev, int vector)
 +int msix_is_pending(PCIDevice *dev, unsigned int vector)
  {
  return *msix_pending_byte(dev, vector) & msix_pending_mask(vector);
  }
 @@ -579,6 +579,17 @@ static void msix_unset_notifier_for_vector(PCIDevice 
 *dev, unsigned int vector)
  dev->msix_vector_release_notifier(dev, vector);
  }
  
 +void msix_init_vector_notifiers(PCIDevice *dev,
 +MSIVectorUseNotifier use_notifier,
 +MSIVectorReleaseNotifier release_notifier,
 +MSIVectorPollNotifier poll_notifier)
 +{
 +assert(use_notifier && release_notifier);
 +dev->msix_vector_use_notifier = use_notifier;
 +dev->msix_vector_release_notifier = release_notifier;
 +dev->msix_vector_poll_notifier = poll_notifier;
 +}
 +
  int msix_set_vector_notifiers(PCIDevice *dev,
MSIVectorUseNotifier use_notifier,
MSIVectorReleaseNotifier release_notifier,
 @@ -586,11 +597,8 @@ int msix_set_vector_notifiers(PCIDevice *dev,
  {
  int vector, ret;
  
 -assert(use_notifier && release_notifier);
 -
 -dev->msix_vector_use_notifier = use_notifier;
 -dev->msix_vector_release_notifier = release_notifier;
 -dev->msix_vector_poll_notifier = poll_notifier;
 +msix_init_vector_notifiers(dev, use_notifier, release_notifier,
 +   poll_notifier);
  
  if ((dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] &
  (MSIX_ENABLE_MASK | MSIX_MASKALL_MASK)) == MSIX_ENABLE_MASK) {
 diff --git a/hw/pci/pci.c b/hw/pci/pci.c
 index e5993c1..0fd21e1 100644
 --- a/hw/pci/pci.c
 +++ b/hw/pci/pci.c
 @@ -225,7 +225,6 @@ static const TypeInfo pcie_bus_info = {
  };
  
  static PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num);
 -static void 

[PATCH] hw/smbios: Add table 4 parameter, "processor-id"

2022-01-06 Thread Patrick Venture
This parameter is to be used in the processor_id lower 32-bit entry in
the type 4 table.  The upper 32-bits represent the features for the CPU.
This patch leaves those as 0 when the lower 32-bits are set.

This parameter is set as optional and if left will use the values from
the CPU model.

This enables hiding the host information from the guest and allowing AMD
VMs to run pretending to be Intel for some userspace software concerns.

Reviewed-by: Peter Foley 
Reviewed-by: Titus Rwantare 
Signed-off-by: Patrick Venture 
---
 hw/smbios/smbios.c | 19 ---
 qemu-options.hx|  1 +
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index 7397e56737..0553ee0b17 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -104,9 +104,11 @@ static struct {
 const char *sock_pfx, *manufacturer, *version, *serial, *asset, *part;
 uint64_t max_speed;
 uint64_t current_speed;
+uint32_t processor_id;
 } type4 = {
 .max_speed = DEFAULT_CPU_SPEED,
-.current_speed = DEFAULT_CPU_SPEED
+.current_speed = DEFAULT_CPU_SPEED,
+.processor_id = 0,
 };
 
 static struct {
@@ -327,6 +329,10 @@ static const QemuOptDesc qemu_smbios_type4_opts[] = {
 .name = "part",
 .type = QEMU_OPT_STRING,
 .help = "part number",
+}, {
+.name = "processor-id",
+.type = QEMU_OPT_NUMBER,
+.help = "processor id",
 },
 { /* end of list */ }
 };
@@ -669,8 +675,13 @@ static void smbios_build_type_4_table(MachineState *ms, 
unsigned instance)
 t->processor_type = 0x03; /* CPU */
 t->processor_family = 0x01; /* Other */
 SMBIOS_TABLE_SET_STR(4, processor_manufacturer_str, type4.manufacturer);
-t->processor_id[0] = cpu_to_le32(smbios_cpuid_version);
-t->processor_id[1] = cpu_to_le32(smbios_cpuid_features);
+if (type4.processor_id == 0) {
+t->processor_id[0] = cpu_to_le32(smbios_cpuid_version);
+t->processor_id[1] = cpu_to_le32(smbios_cpuid_features);
+} else {
+t->processor_id[0] = cpu_to_le32(type4.processor_id);
+t->processor_id[1] = 0;
+}
 SMBIOS_TABLE_SET_STR(4, processor_version_str, type4.version);
 t->voltage = 0;
 t->external_clock = cpu_to_le16(0); /* Unknown */
@@ -1292,6 +1303,8 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
 save_opt(, opts, "serial");
 save_opt(, opts, "asset");
 save_opt(, opts, "part");
+/* If the value is 0, it will take the value from the CPU model. */
+type4.processor_id = qemu_opt_get_number(opts, "processor-id", 0);
 type4.max_speed = qemu_opt_get_number(opts, "max-speed",
   DEFAULT_CPU_SPEED);
 type4.current_speed = qemu_opt_get_number(opts, "current-speed",
diff --git a/qemu-options.hx b/qemu-options.hx
index ec90505d84..3c51b6cf8f 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2527,6 +2527,7 @@ DEF("smbios", HAS_ARG, QEMU_OPTION_smbios,
 "specify SMBIOS type 3 fields\n"
 "-smbios 
type=4[,sock_pfx=str][,manufacturer=str][,version=str][,serial=str]\n"
 "  [,asset=str][,part=str][,max-speed=%d][,current-speed=%d]\n"
+"  [,processor-id=%d]\n"
 "specify SMBIOS type 4 fields\n"
 "-smbios type=11[,value=str][,path=filename]\n"
 "specify SMBIOS type 11 fields\n"
-- 
2.34.1.448.ga2b2bfdf31-goog




Re: [PATCH] target/riscv: Fix position of 'experimental' comment

2022-01-06 Thread Alistair Francis
On Fri, Jan 7, 2022 at 12:30 AM Philipp Tomsich
 wrote:
>
> When commit 0643c12e4b dropped the 'x-' prefix for Zb[abcs] and set
> them to be enabled by default, the comment about experimental
> extensions was kept in place above them.  This moves it down a few
> lines to only cover experimental extensions.
>
> References: 0643c12e4b ("target/riscv: Enable bitmanip Zb[abcs] instructions")
>
> Signed-off-by: Philipp Tomsich 

Thanks!

Applied to riscv-to-apply.next

Alistair

>
> ---
>
>  target/riscv/cpu.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 6ef3314bce..e322e729d2 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -640,11 +640,12 @@ static Property riscv_cpu_properties[] = {
>  DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128),
>  DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64),
>
> -/* These are experimental so mark with 'x-' */
>  DEFINE_PROP_BOOL("zba", RISCVCPU, cfg.ext_zba, true),
>  DEFINE_PROP_BOOL("zbb", RISCVCPU, cfg.ext_zbb, true),
>  DEFINE_PROP_BOOL("zbc", RISCVCPU, cfg.ext_zbc, true),
>  DEFINE_PROP_BOOL("zbs", RISCVCPU, cfg.ext_zbs, true),
> +
> +/* These are experimental so mark with 'x-' */
>  DEFINE_PROP_BOOL("x-h", RISCVCPU, cfg.ext_h, false),
>  DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false),
>  /* ePMP 0.9.3 */
> --
> 2.33.1
>
>



Re: [PATCH v2 1/2] qemu-storage-daemon: Add vhost-user-blk help

2022-01-06 Thread Eric Blake
On Thu, Dec 23, 2021 at 11:14:25AM +0100, Philippe Mathieu-Daudé wrote:
> Add missing vhost-user-blk help:
> 
>   $ qemu-storage-daemon -h
>   ...
> --export [type=]vhost-user-blk,id=,node-name=,
>  addr.type=unix,addr.path=[,writable=on|off]
>  [,logical-block-size=][,num-queues=]
>export the specified block node as a
>vhosts-user-blk device over UNIX domain socket

Why 'vhosts-' here instead of 'vhost'?

> --export [type=]vhost-user-blk,id=,node-name=,
>  fd,addr.str=[,writable=on|off]
>  [,logical-block-size=][,num-queues=]
>export the specified block node as a
>vhosts-user-blk device over file descriptor

here too.

>   ...
> 
> Fixes: 90fc91d50b7 ("convert vhost-user-blk server to block export API")
> Reported-by: Qing Wang 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  storage-daemon/qemu-storage-daemon.c | 13 +
>  1 file changed, 13 insertions(+)
> 
> diff --git a/storage-daemon/qemu-storage-daemon.c 
> b/storage-daemon/qemu-storage-daemon.c
> index 52cf17e8ace..0c19e128e3f 100644
> --- a/storage-daemon/qemu-storage-daemon.c
> +++ b/storage-daemon/qemu-storage-daemon.c
> @@ -104,6 +104,19 @@ static void help(void)
>  " export the specified block node over FUSE\n"
>  "\n"
>  #endif /* CONFIG_FUSE */
> +#ifdef CONFIG_VHOST_USER_BLK_SERVER
> +"  --export [type=]vhost-user-blk,id=,node-name=,\n"
> +"   addr.type=unix,addr.path=[,writable=on|off]\n"
> +"   [,logical-block-size=][,num-queues=]\n"
> +" export the specified block node as a\n"
> +" vhosts-user-blk device over UNIX domain socket\n"

This...

> +"  --export [type=]vhost-user-blk,id=,node-name=,\n"
> +"   fd,addr.str=[,writable=on|off]\n"
> +"   [,logical-block-size=][,num-queues=]\n"
> +" export the specified block node as a\n"
> +" vhosts-user-blk device over file descriptor\n"

...and this line would need the same tweak.

If you agree that it's a typo, then let's fix it, and you can have

Reviewed-by: Eric Blake 

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org




[PATCH v7 3/5] migration: Add zero-copy parameter for QMP/HMP for Linux

2022-01-06 Thread Leonardo Bras
Add property that allows zero-copy migration of memory pages,
and also includes a helper function migrate_use_zero_copy() to check
if it's enabled.

No code is introduced to actually do the migration, but it allow
future implementations to enable/disable this feature.

On non-Linux builds this parameter is compiled-out.

Signed-off-by: Leonardo Bras 
---
 qapi/migration.json   | 24 
 migration/migration.h |  5 +
 migration/migration.c | 32 
 migration/socket.c|  5 +
 monitor/hmp-cmds.c|  6 ++
 5 files changed, 72 insertions(+)

diff --git a/qapi/migration.json b/qapi/migration.json
index bbfd48cf0b..2e62ea6ebd 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -730,6 +730,13 @@
 #  will consume more CPU.
 #  Defaults to 1. (Since 5.0)
 #
+# @zero-copy: Controls behavior on sending memory pages on migration.
+# When true, enables a zero-copy mechanism for sending memory
+# pages, if host supports it.
+# Requires that QEMU be permitted to use locked memory for guest
+# RAM pages.
+# Defaults to false. (Since 7.0)
+#
 # @block-bitmap-mapping: Maps block nodes and bitmaps on them to
 #aliases for the purpose of dirty bitmap migration.  
Such
 #aliases may for example be the corresponding names on 
the
@@ -769,6 +776,7 @@
'xbzrle-cache-size', 'max-postcopy-bandwidth',
'max-cpu-throttle', 'multifd-compression',
'multifd-zlib-level' ,'multifd-zstd-level',
+   { 'name': 'zero-copy', 'if' : 'CONFIG_LINUX'},
'block-bitmap-mapping' ] }
 
 ##
@@ -895,6 +903,13 @@
 #  will consume more CPU.
 #  Defaults to 1. (Since 5.0)
 #
+# @zero-copy: Controls behavior on sending memory pages on migration.
+# When true, enables a zero-copy mechanism for sending memory
+# pages, if host supports it.
+# Requires that QEMU be permitted to use locked memory for guest
+# RAM pages.
+# Defaults to false. (Since 7.0)
+#
 # @block-bitmap-mapping: Maps block nodes and bitmaps on them to
 #aliases for the purpose of dirty bitmap migration.  
Such
 #aliases may for example be the corresponding names on 
the
@@ -949,6 +964,7 @@
 '*multifd-compression': 'MultiFDCompression',
 '*multifd-zlib-level': 'uint8',
 '*multifd-zstd-level': 'uint8',
+'*zero-copy': { 'type': 'bool', 'if': 'CONFIG_LINUX' },
 '*block-bitmap-mapping': [ 'BitmapMigrationNodeAlias' ] } }
 
 ##
@@ -1095,6 +,13 @@
 #  will consume more CPU.
 #  Defaults to 1. (Since 5.0)
 #
+# @zero-copy: Controls behavior on sending memory pages on migration.
+# When true, enables a zero-copy mechanism for sending memory
+# pages, if host supports it.
+# Requires that QEMU be permitted to use locked memory for guest
+# RAM pages.
+# Defaults to false. (Since 7.0)
+#
 # @block-bitmap-mapping: Maps block nodes and bitmaps on them to
 #aliases for the purpose of dirty bitmap migration.  
Such
 #aliases may for example be the corresponding names on 
the
@@ -1147,6 +1170,7 @@
 '*multifd-compression': 'MultiFDCompression',
 '*multifd-zlib-level': 'uint8',
 '*multifd-zstd-level': 'uint8',
+'*zero-copy': { 'type': 'bool', 'if': 'CONFIG_LINUX' },
 '*block-bitmap-mapping': [ 'BitmapMigrationNodeAlias' ] } }
 
 ##
diff --git a/migration/migration.h b/migration/migration.h
index 8130b703eb..1489eeb165 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -339,6 +339,11 @@ MultiFDCompression migrate_multifd_compression(void);
 int migrate_multifd_zlib_level(void);
 int migrate_multifd_zstd_level(void);
 
+#ifdef CONFIG_LINUX
+bool migrate_use_zero_copy(void);
+#else
+#define migrate_use_zero_copy() (false)
+#endif
 int migrate_use_xbzrle(void);
 uint64_t migrate_xbzrle_cache_size(void);
 bool migrate_colo_enabled(void);
diff --git a/migration/migration.c b/migration/migration.c
index 0652165610..aa8f1dc835 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -893,6 +893,10 @@ MigrationParameters *qmp_query_migrate_parameters(Error 
**errp)
 params->multifd_zlib_level = s->parameters.multifd_zlib_level;
 params->has_multifd_zstd_level = true;
 params->multifd_zstd_level = s->parameters.multifd_zstd_level;
+#ifdef CONFIG_LINUX
+params->has_zero_copy = true;
+params->zero_copy = s->parameters.zero_copy;
+#endif
 params->has_xbzrle_cache_size = true;
 params->xbzrle_cache_size = s->parameters.xbzrle_cache_size;
 params->has_max_postcopy_bandwidth = true;
@@ 

[PATCH v7 4/5] migration: Add migrate_use_tls() helper

2022-01-06 Thread Leonardo Bras
A lot of places check parameters.tls_creds in order to evaluate if TLS is
in use, and sometimes call migrate_get_current() just for that test.

Add new helper function migrate_use_tls() in order to simplify testing
for TLS usage.

Signed-off-by: Leonardo Bras 
Reviewed-by: Juan Quintela 
---
 migration/migration.h | 1 +
 migration/channel.c   | 6 +++---
 migration/migration.c | 9 +
 migration/multifd.c   | 5 +
 4 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/migration/migration.h b/migration/migration.h
index 1489eeb165..445d95bbf2 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -344,6 +344,7 @@ bool migrate_use_zero_copy(void);
 #else
 #define migrate_use_zero_copy() (false)
 #endif
+int migrate_use_tls(void);
 int migrate_use_xbzrle(void);
 uint64_t migrate_xbzrle_cache_size(void);
 bool migrate_colo_enabled(void);
diff --git a/migration/channel.c b/migration/channel.c
index c4fc000a1a..1a45b75d29 100644
--- a/migration/channel.c
+++ b/migration/channel.c
@@ -32,16 +32,16 @@
  */
 void migration_channel_process_incoming(QIOChannel *ioc)
 {
-MigrationState *s = migrate_get_current();
 Error *local_err = NULL;
 
 trace_migration_set_incoming_channel(
 ioc, object_get_typename(OBJECT(ioc)));
 
-if (s->parameters.tls_creds &&
-*s->parameters.tls_creds &&
+if (migrate_use_tls() &&
 !object_dynamic_cast(OBJECT(ioc),
  TYPE_QIO_CHANNEL_TLS)) {
+MigrationState *s = migrate_get_current();
+
 migration_tls_channel_process_incoming(s, ioc, _err);
 } else {
 migration_ioc_register_yank(ioc);
diff --git a/migration/migration.c b/migration/migration.c
index aa8f1dc835..7bcb800890 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -2573,6 +2573,15 @@ bool migrate_use_zero_copy(void)
 }
 #endif
 
+int migrate_use_tls(void)
+{
+MigrationState *s;
+
+s = migrate_get_current();
+
+return s->parameters.tls_creds && *s->parameters.tls_creds;
+}
+
 int migrate_use_xbzrle(void)
 {
 MigrationState *s;
diff --git a/migration/multifd.c b/migration/multifd.c
index 3242f688e5..677e942747 100644
--- a/migration/multifd.c
+++ b/migration/multifd.c
@@ -796,14 +796,11 @@ static bool multifd_channel_connect(MultiFDSendParams *p,
 QIOChannel *ioc,
 Error *error)
 {
-MigrationState *s = migrate_get_current();
-
 trace_multifd_set_outgoing_channel(
 ioc, object_get_typename(OBJECT(ioc)), p->tls_hostname, error);
 
 if (!error) {
-if (s->parameters.tls_creds &&
-*s->parameters.tls_creds &&
+if (migrate_use_tls() &&
 !object_dynamic_cast(OBJECT(ioc),
  TYPE_QIO_CHANNEL_TLS)) {
 multifd_tls_channel_connect(p, ioc, );
-- 
2.34.1




[PATCH v7 5/5] multifd: Implement zero copy write in multifd migration (multifd-zero-copy)

2022-01-06 Thread Leonardo Bras
Implement zero copy on nocomp_send_write(), by making use of QIOChannel
writev + flags & flush interface.

Change multifd_send_sync_main() so it can distinguish each iteration sync from
the setup and the completion, so a flush_zero_copy() can be called
after each iteration in order to make sure all dirty pages are sent
before a new iteration is started.

Also make it return -1 if flush_zero_copy() fails, in order to cancel
the migration process, and avoid resuming the guest in the target host
without receiving all current RAM.

This will work fine on RAM migration because the RAM pages are not usually 
freed,
and there is no problem on changing the pages content between 
writev_zero_copy() and
the actual sending of the buffer, because this change will dirty the page and
cause it to be re-sent on a next iteration anyway.

A lot of locked memory may be needed in order to use multid migration
with zero-copy enabled, so disabling the feature should be necessary for
low-privileged users trying to perform multifd migrations.

Signed-off-by: Leonardo Bras 
---
 migration/multifd.h   |  4 +++-
 migration/migration.c | 11 ++-
 migration/multifd.c   | 40 +++-
 migration/ram.c   | 29 ++---
 migration/socket.c|  5 +++--
 5 files changed, 73 insertions(+), 16 deletions(-)

diff --git a/migration/multifd.h b/migration/multifd.h
index e57adc783b..d9fbccdbe2 100644
--- a/migration/multifd.h
+++ b/migration/multifd.h
@@ -22,7 +22,7 @@ int multifd_load_cleanup(Error **errp);
 bool multifd_recv_all_channels_created(void);
 bool multifd_recv_new_channel(QIOChannel *ioc, Error **errp);
 void multifd_recv_sync_main(void);
-void multifd_send_sync_main(QEMUFile *f);
+int multifd_send_sync_main(QEMUFile *f, bool sync);
 int multifd_queue_page(QEMUFile *f, RAMBlock *block, ram_addr_t offset);
 
 /* Multifd Compression flags */
@@ -97,6 +97,8 @@ typedef struct {
 uint32_t packet_len;
 /* pointer to the packet */
 MultiFDPacket_t *packet;
+/* multifd flags for sending ram */
+int write_flags;
 /* multifd flags for each packet */
 uint32_t flags;
 /* size of the next packet that contains pages */
diff --git a/migration/migration.c b/migration/migration.c
index 7bcb800890..76a3313e66 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1476,7 +1476,16 @@ static bool migrate_params_check(MigrationParameters 
*params, Error **errp)
 error_prepend(errp, "Invalid mapping given for block-bitmap-mapping: 
");
 return false;
 }
-
+#ifdef CONFIG_LINUX
+if (params->zero_copy &&
+(!migrate_use_multifd() ||
+ params->multifd_compression != MULTIFD_COMPRESSION_NONE ||
+ (params->tls_creds && *params->tls_creds))) {
+error_setg(errp,
+   "Zero copy only available for non-compressed non-TLS 
multifd migration");
+return false;
+}
+#endif
 return true;
 }
 
diff --git a/migration/multifd.c b/migration/multifd.c
index 677e942747..1b6b7cc1a1 100644
--- a/migration/multifd.c
+++ b/migration/multifd.c
@@ -104,7 +104,8 @@ static int nocomp_send_prepare(MultiFDSendParams *p, Error 
**errp)
  */
 static int nocomp_send_write(MultiFDSendParams *p, uint32_t used, Error **errp)
 {
-return qio_channel_writev_all(p->c, p->pages->iov, used, errp);
+return qio_channel_writev_full_all_flags(p->c, p->pages->iov, used,
+ NULL, 0, p->write_flags, errp);
 }
 
 /**
@@ -582,19 +583,28 @@ void multifd_save_cleanup(void)
 multifd_send_state = NULL;
 }
 
-void multifd_send_sync_main(QEMUFile *f)
+int multifd_send_sync_main(QEMUFile *f, bool sync)
 {
 int i;
+bool flush_zero_copy;
 
 if (!migrate_use_multifd()) {
-return;
+return 0;
 }
 if (multifd_send_state->pages->num) {
 if (multifd_send_pages(f) < 0) {
 error_report("%s: multifd_send_pages fail", __func__);
-return;
+return 0;
 }
 }
+
+/*
+ * When using zero-copy, it's necessary to flush after each iteration to
+ * make sure pages from earlier iterations don't end up replacing newer
+ * pages.
+ */
+flush_zero_copy = sync && migrate_use_zero_copy();
+
 for (i = 0; i < migrate_multifd_channels(); i++) {
 MultiFDSendParams *p = _send_state->params[i];
 
@@ -605,7 +615,7 @@ void multifd_send_sync_main(QEMUFile *f)
 if (p->quit) {
 error_report("%s: channel %d has already quit", __func__, i);
 qemu_mutex_unlock(>mutex);
-return;
+return 0;
 }
 
 p->packet_num = multifd_send_state->packet_num++;
@@ -616,6 +626,17 @@ void multifd_send_sync_main(QEMUFile *f)
 ram_counters.transferred += p->packet_len;
 qemu_mutex_unlock(>mutex);
 qemu_sem_post(>sem);
+
+if (flush_zero_copy) {
+int ret;
+Error *err = NULL;
+
+  

[PATCH v7 0/5] MSG_ZEROCOPY + multifd

2022-01-06 Thread Leonardo Bras
This patch series intends to enable MSG_ZEROCOPY in QIOChannel, and make
use of it for multifd migration performance improvement, by reducing cpu
usage.

Patch #1 creates new callbacks for QIOChannel, allowing the implementation
of zero copy writing.

Patch #2 implements io_writev flags and io_flush() on QIOChannelSocket,
making use of MSG_ZEROCOPY on Linux.

Patch #3 adds a "zero_copy" migration property, only available with
CONFIG_LINUX, and compiled-out in any other architectures.
This migration property has to be enabled before multifd migration starts.

Patch #4 adds a helper function that allows to see if TLS is going to be used.
This helper will be later used in patch #5.

Patch #5 Makes use of QIOChannelSocket zero_copy implementation on
nocomp multifd migration.

Results:
In preliminary tests, the resource usage of __sys_sendmsg() reduced 15 times,
and the overall migration took 13-22% less time, based in synthetic cpu
workload.

In further tests, it was noted that, on multifd migration with 8 channels:
- On idle hosts, migration time reduced in 10% to 21%.
- On hosts busy with heavy cpu stress (1 stress thread per cpu, but
  not cpu-pinned) migration time reduced in ~25% by enabling zero-copy.
- On hosts with heavy cpu-pinned workloads (1 stress thread per cpu, 
  cpu-pinned), migration time reducted in ~66% by enabling zero-copy.

Above tests setup:
- Sending and Receiving hosts:
  - CPU : Intel(R) Xeon(R) Platinum 8276L CPU @ 2.20GHz (448 CPUS)
  - Network card: E810-C (100Gbps)
  - >1TB RAM
  - QEMU: Upstream master branch + This patchset
  - Linux: Upstream v5.15 
- VM configuration:
  - 28 VCPUs
  - 512GB RAM


---
Changes since v6:
- Remove io_writev_zero_copy(), and makes use of io_writev() new flags
  to achieve the same results.
- Rename io_flush_zero_copy() to io_flush()
- Previous patch #2 became too small, so it was squashed in previous
  patch #3 (now patch #2)

Changes since v5:
- flush_zero_copy now returns -1 on fail, 0 on success, and 1 when all
  processed writes were not able to use zerocopy in kernel.
- qio_channel_socket_poll() removed, using qio_channel_wait() instead
- ENOBUFS is now processed inside qio_channel_socket_writev_flags()
- Most zerocopy parameter validation moved to migrate_params_check(),
  leaving only feature test to socket_outgoing_migration() callback
- Naming went from *zerocopy to *zero_copy or *zero-copy, due to QAPI/QMP
  preferences
- Improved docs

Changes since v4:
- 3 patches got splitted in 6
- Flush is used for syncing after each iteration, instead of only at the end
- If zerocopy is not available, fail in connect instead of failing on write
- 'multifd-zerocopy' property renamed to 'zerocopy'
- Fail migrations that don't support zerocopy, if it's enabled.
- Instead of checking for zerocopy at each write, save the flags in
  MultiFDSendParams->write_flags and use them on write
- Reorganized flag usage in QIOChannelSocket 
- A lot of typos fixed
- More doc on buffer restrictions

Changes since v3:
- QIOChannel interface names changed from io_async_{writev,flush} to
  io_{writev,flush}_zerocopy
- Instead of falling back in case zerocopy is not implemented, return
  error and abort operation.
- Flush now waits as long as needed, or return error in case anything
  goes wrong, aborting the operation.
- Zerocopy is now conditional in multifd, being set by parameter
  multifd-zerocopy
- Moves zerocopy_flush to multifd_send_sync_main() from multifd_save_cleanup
  so migration can abort if flush goes wrong.
- Several other small improvements

Changes since v2:
- Patch #1: One more fallback
- Patch #2: Fall back to sync if fails to lock buffer memory in MSG_ZEROCOPY 
send.

Changes since v1:
- Reimplemented the patchset using async_write + async_flush approach.
- Implemented a flush to be able to tell whenever all data was written.


Leonardo Bras (5):
  QIOChannel: Add flags on io_writev and introduce io_flush callback
  QIOChannelSocket: Implement io_writev zero copy flag & io_flush for
CONFIG_LINUX
  migration: Add zero-copy parameter for QMP/HMP for Linux
  migration: Add migrate_use_tls() helper
  multifd: Implement zero copy write in multifd migration
(multifd-zero-copy)

 qapi/migration.json |  24 
 include/io/channel-socket.h |   2 +
 include/io/channel.h|  67 +-
 migration/migration.h   |   6 ++
 migration/multifd.h |   4 +-
 io/channel-buffer.c |   1 +
 io/channel-command.c|   1 +
 io/channel-file.c   |   1 +
 io/channel-socket.c | 109 ++--
 io/channel-tls.c|   1 +
 io/channel-websock.c|   1 +
 io/channel.c|  51 -
 migration/channel.c |   6 +-
 migration/migration.c   |  52 -
 migration/multifd.c |  45 ---
 migration/ram.c |  29 +++---
 migration/rdma.c|   1 +
 migration/socket.c  |   6 

[PATCH v7 1/5] QIOChannel: Add flags on io_writev and introduce io_flush callback

2022-01-06 Thread Leonardo Bras
Add flags to io_writev and introduce io_flush as optional callback to
QIOChannelClass, allowing the implementation of zero copy writes by
subclasses.

How to use them:
- Write data using qio_channel_writev(...,QIO_CHANNEL_WRITE_FLAG_ZERO_COPY),
- Wait write completion with qio_channel_flush().

Notes:
As some zero copy implementations work asynchronously, it's
recommended to keep the write buffer untouched until the return of
qio_channel_flush(), to avoid the risk of sending an updated buffer
instead of the buffer state during write.

As io_flush callback is optional, if a subclass does not implement it, then:
- io_flush will return 0 without changing anything.

Also, some functions like qio_channel_writev_full_all() were adapted to
receive a flag parameter. That allows shared code between zero copy and
non-zero copy writev, and also an easier implementation on new flags.

Signed-off-by: Leonardo Bras 
---
 include/io/channel.h | 67 +++-
 io/channel-buffer.c  |  1 +
 io/channel-command.c |  1 +
 io/channel-file.c|  1 +
 io/channel-socket.c  |  2 ++
 io/channel-tls.c |  1 +
 io/channel-websock.c |  1 +
 io/channel.c | 51 +++--
 migration/rdma.c |  1 +
 9 files changed, 98 insertions(+), 28 deletions(-)

diff --git a/include/io/channel.h b/include/io/channel.h
index 88988979f8..343766ce5b 100644
--- a/include/io/channel.h
+++ b/include/io/channel.h
@@ -32,12 +32,15 @@ OBJECT_DECLARE_TYPE(QIOChannel, QIOChannelClass,
 
 #define QIO_CHANNEL_ERR_BLOCK -2
 
+#define QIO_CHANNEL_WRITE_FLAG_ZERO_COPY 0x1
+
 typedef enum QIOChannelFeature QIOChannelFeature;
 
 enum QIOChannelFeature {
 QIO_CHANNEL_FEATURE_FD_PASS,
 QIO_CHANNEL_FEATURE_SHUTDOWN,
 QIO_CHANNEL_FEATURE_LISTEN,
+QIO_CHANNEL_FEATURE_WRITE_ZERO_COPY,
 };
 
 
@@ -104,6 +107,7 @@ struct QIOChannelClass {
  size_t niov,
  int *fds,
  size_t nfds,
+ int flags,
  Error **errp);
 ssize_t (*io_readv)(QIOChannel *ioc,
 const struct iovec *iov,
@@ -136,6 +140,8 @@ struct QIOChannelClass {
   IOHandler *io_read,
   IOHandler *io_write,
   void *opaque);
+int (*io_flush)(QIOChannel *ioc,
+Error **errp);
 };
 
 /* General I/O handling functions */
@@ -222,12 +228,13 @@ ssize_t qio_channel_readv_full(QIOChannel *ioc,
 
 
 /**
- * qio_channel_writev_full:
+ * qio_channel_writev_full_flags:
  * @ioc: the channel object
  * @iov: the array of memory regions to write data from
  * @niov: the length of the @iov array
  * @fds: an array of file handles to send
  * @nfds: number of file handles in @fds
+ * @flags: write flags (QIO_CHANNEL_WRITE_FLAG_*)
  * @errp: pointer to a NULL-initialized error object
  *
  * Write data to the IO channel, reading it from the
@@ -255,12 +262,16 @@ ssize_t qio_channel_readv_full(QIOChannel *ioc,
  * or QIO_CHANNEL_ERR_BLOCK if no data is can be sent
  * and the channel is non-blocking
  */
-ssize_t qio_channel_writev_full(QIOChannel *ioc,
-const struct iovec *iov,
-size_t niov,
-int *fds,
-size_t nfds,
-Error **errp);
+ssize_t qio_channel_writev_full_flags(QIOChannel *ioc,
+  const struct iovec *iov,
+  size_t niov,
+  int *fds,
+  size_t nfds,
+  int flags,
+  Error **errp);
+
+#define qio_channel_writev_full(ioc, iov, niov, fds, nfds, errp) \
+qio_channel_writev_full_flags(ioc, iov, niov, fds, nfds, 0, errp)
 
 /**
  * qio_channel_readv_all_eof:
@@ -831,12 +842,13 @@ int qio_channel_readv_full_all(QIOChannel *ioc,
Error **errp);
 
 /**
- * qio_channel_writev_full_all:
+ * qio_channel_writev_full_all_flags:
  * @ioc: the channel object
  * @iov: the array of memory regions to write data from
  * @niov: the length of the @iov array
  * @fds: an array of file handles to send
  * @nfds: number of file handles in @fds
+ * @flags: write flags (QIO_CHANNEL_WRITE_FLAG_*)
  * @errp: pointer to a NULL-initialized error object
  *
  *
@@ -846,13 +858,42 @@ int qio_channel_readv_full_all(QIOChannel *ioc,
  * to be written, yielding from the current coroutine
  * if required.
  *
+ * If QIO_CHANNEL_WRITE_FLAG_ZERO_COPY is passed in flags,
+ * instead of waiting for all requested data to be written,
+ * this function will wait until it's all queued for writing.
+ * In this case, if the buffer gets changed between queueing and
+ * sending, the updated buffer will be sent. If this is 

[PATCH v7 2/5] QIOChannelSocket: Implement io_writev zero copy flag & io_flush for CONFIG_LINUX

2022-01-06 Thread Leonardo Bras
For CONFIG_LINUX, implement the new zero copy flag and the optional callback
io_flush on QIOChannelSocket, but enables it only when MSG_ZEROCOPY
feature is available in the host kernel, which is checked on
qio_channel_socket_connect_sync()

qio_channel_socket_flush() was implemented by counting how many times
sendmsg(...,MSG_ZEROCOPY) was successfully called, and then reading the
socket's error queue, in order to find how many of them finished sending.
Flush will loop until those counters are the same, or until some error occurs.

Notes on using writev() with QIO_CHANNEL_WRITE_FLAG_ZERO_COPY:
1: Buffer
- As MSG_ZEROCOPY tells the kernel to use the same user buffer to avoid copying,
some caution is necessary to avoid overwriting any buffer before it's sent.
If something like this happen, a newer version of the buffer may be sent 
instead.
- If this is a problem, it's recommended to call qio_channel_flush() before 
freeing
or re-using the buffer.

2: Locked memory
- When using MSG_ZERCOCOPY, the buffer memory will be locked after queued, and
unlocked after it's sent.
- Depending on the size of each buffer, and how often it's sent, it may require
a larger amount of locked memory than usually available to non-root user.
- If the required amount of locked memory is not available, writev_zero_copy
will return an error, which can abort an operation like migration,
- Because of this, when an user code wants to add zero copy as a feature, it
requires a mechanism to disable it, so it can still be accessible to less
privileged users.

Signed-off-by: Leonardo Bras 
---
 include/io/channel-socket.h |   2 +
 io/channel-socket.c | 107 ++--
 2 files changed, 105 insertions(+), 4 deletions(-)

diff --git a/include/io/channel-socket.h b/include/io/channel-socket.h
index e747e63514..513c428fe4 100644
--- a/include/io/channel-socket.h
+++ b/include/io/channel-socket.h
@@ -47,6 +47,8 @@ struct QIOChannelSocket {
 socklen_t localAddrLen;
 struct sockaddr_storage remoteAddr;
 socklen_t remoteAddrLen;
+ssize_t zero_copy_queued;
+ssize_t zero_copy_sent;
 };
 
 
diff --git a/io/channel-socket.c b/io/channel-socket.c
index bfbd64787e..fb1e210ec5 100644
--- a/io/channel-socket.c
+++ b/io/channel-socket.c
@@ -26,6 +26,10 @@
 #include "io/channel-watch.h"
 #include "trace.h"
 #include "qapi/clone-visitor.h"
+#ifdef CONFIG_LINUX
+#include 
+#include 
+#endif
 
 #define SOCKET_MAX_FDS 16
 
@@ -55,6 +59,8 @@ qio_channel_socket_new(void)
 
 sioc = QIO_CHANNEL_SOCKET(object_new(TYPE_QIO_CHANNEL_SOCKET));
 sioc->fd = -1;
+sioc->zero_copy_queued = 0;
+sioc->zero_copy_sent = 0;
 
 ioc = QIO_CHANNEL(sioc);
 qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_SHUTDOWN);
@@ -154,6 +160,16 @@ int qio_channel_socket_connect_sync(QIOChannelSocket *ioc,
 return -1;
 }
 
+#ifdef CONFIG_LINUX
+int ret, v = 1;
+ret = qemu_setsockopt(fd, SOL_SOCKET, SO_ZEROCOPY, , sizeof(v));
+if (ret == 0) {
+/* Zero copy available on host */
+qio_channel_set_feature(QIO_CHANNEL(ioc),
+QIO_CHANNEL_FEATURE_WRITE_ZERO_COPY);
+}
+#endif
+
 return 0;
 }
 
@@ -534,6 +550,7 @@ static ssize_t qio_channel_socket_writev(QIOChannel *ioc,
 char control[CMSG_SPACE(sizeof(int) * SOCKET_MAX_FDS)];
 size_t fdsize = sizeof(int) * nfds;
 struct cmsghdr *cmsg;
+int sflags = 0;
 
 memset(control, 0, CMSG_SPACE(sizeof(int) * SOCKET_MAX_FDS));
 
@@ -558,15 +575,26 @@ static ssize_t qio_channel_socket_writev(QIOChannel *ioc,
 memcpy(CMSG_DATA(cmsg), fds, fdsize);
 }
 
+if (flags & QIO_CHANNEL_WRITE_FLAG_ZERO_COPY) {
+sflags = MSG_ZEROCOPY;
+}
+
  retry:
-ret = sendmsg(sioc->fd, , 0);
+ret = sendmsg(sioc->fd, , sflags);
 if (ret <= 0) {
-if (errno == EAGAIN) {
+switch (errno) {
+case EAGAIN:
 return QIO_CHANNEL_ERR_BLOCK;
-}
-if (errno == EINTR) {
+case EINTR:
 goto retry;
+case ENOBUFS:
+if (sflags & MSG_ZEROCOPY) {
+error_setg_errno(errp, errno,
+ "Process can't lock enough memory for using 
MSG_ZEROCOPY");
+return -1;
+}
 }
+
 error_setg_errno(errp, errno,
  "Unable to write to socket");
 return -1;
@@ -660,6 +688,74 @@ static ssize_t qio_channel_socket_writev(QIOChannel *ioc,
 }
 #endif /* WIN32 */
 
+
+#ifdef CONFIG_LINUX
+static int qio_channel_socket_flush(QIOChannel *ioc,
+Error **errp)
+{
+QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
+struct msghdr msg = {};
+struct sock_extended_err *serr;
+struct cmsghdr *cm;
+char control[CMSG_SPACE(sizeof(*serr))];
+int received;
+int ret = 1;
+
+msg.msg_control = control;
+msg.msg_controllen = sizeof(control);
+memset(control, 0, 

[PATCH] linux-user: rt_sigprocmask, check read perms first

2022-01-06 Thread Patrick Venture
From: Shu-Chun Weng 

Linux kernel does it this way (checks read permission before validating `how`)
and the latest version of ABSL's `AddressIsReadable()` depends on this
behavior.

c.f.  
https://github.com/torvalds/linux/blob/9539ba4308ad5bdca6cb41c7b73cbb9f796dcdd7/kernel/signal.c#L3147
Reviewed-by: Patrick Venture 
Signed-off-by: Shu-Chun Weng 
---
 linux-user/syscall.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index ce9d64896c..3070d31f34 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -9491,6 +9491,11 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 }
 
 if (arg2) {
+if (!(p = lock_user(VERIFY_READ, arg2, 
sizeof(target_sigset_t), 1)))
+return -TARGET_EFAULT;
+target_to_host_sigset(, p);
+unlock_user(p, arg2, 0);
+set_ptr = 
 switch(how) {
 case TARGET_SIG_BLOCK:
 how = SIG_BLOCK;
@@ -9504,11 +9509,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 default:
 return -TARGET_EINVAL;
 }
-if (!(p = lock_user(VERIFY_READ, arg2, 
sizeof(target_sigset_t), 1)))
-return -TARGET_EFAULT;
-target_to_host_sigset(, p);
-unlock_user(p, arg2, 0);
-set_ptr = 
 } else {
 how = 0;
 set_ptr = NULL;
-- 
2.34.1.448.ga2b2bfdf31-goog




Re: [PATCH] target/riscv: Fix position of 'experimental' comment

2022-01-06 Thread Alistair Francis
On Fri, Jan 7, 2022 at 12:30 AM Philipp Tomsich
 wrote:
>
> When commit 0643c12e4b dropped the 'x-' prefix for Zb[abcs] and set
> them to be enabled by default, the comment about experimental
> extensions was kept in place above them.  This moves it down a few
> lines to only cover experimental extensions.
>
> References: 0643c12e4b ("target/riscv: Enable bitmanip Zb[abcs] instructions")
>
> Signed-off-by: Philipp Tomsich 

Reviewed-by: Alistair Francis 

Alistair

>
> ---
>
>  target/riscv/cpu.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 6ef3314bce..e322e729d2 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -640,11 +640,12 @@ static Property riscv_cpu_properties[] = {
>  DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128),
>  DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64),
>
> -/* These are experimental so mark with 'x-' */
>  DEFINE_PROP_BOOL("zba", RISCVCPU, cfg.ext_zba, true),
>  DEFINE_PROP_BOOL("zbb", RISCVCPU, cfg.ext_zbb, true),
>  DEFINE_PROP_BOOL("zbc", RISCVCPU, cfg.ext_zbc, true),
>  DEFINE_PROP_BOOL("zbs", RISCVCPU, cfg.ext_zbs, true),
> +
> +/* These are experimental so mark with 'x-' */
>  DEFINE_PROP_BOOL("x-h", RISCVCPU, cfg.ext_h, false),
>  DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false),
>  /* ePMP 0.9.3 */
> --
> 2.33.1
>
>



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

2022-01-06 Thread Marc Zyngier
On Wed, 05 Jan 2022 09:22:39 +,
Eric Auger  wrote:
> 
> Hi Marc,
> 
> On 12/27/21 10:16 PM, Marc Zyngier wrote:
> > Even when the VM is configured with highmem=off, the highest_gpa
> > field includes devices that are above the 4GiB limit.
> > Similarily, nothing seem to check that the memory is within
> > the limit set by the highmem=off option.
> >
> > This leads to failures in virt_kvm_type() on systems that have
> > a crippled IPA range, as the reported IPA space is larger than
> > what it should be.
> >
> > Instead, honor the user-specified limit to only use the devices
> > at the lowest end of the spectrum, and fail if we have memory
> > crossing the 4GiB limit.
> >
> > Reviewed-by: Andrew Jones 
> > Signed-off-by: Marc Zyngier 
> > ---
> >  hw/arm/virt.c | 9 -
> >  1 file changed, 8 insertions(+), 1 deletion(-)
> >
> > diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> > index 8b600d82c1..84dd3b36fb 100644
> > --- a/hw/arm/virt.c
> > +++ b/hw/arm/virt.c
> > @@ -1678,6 +1678,11 @@ static void virt_set_memmap(VirtMachineState *vms)
> >  exit(EXIT_FAILURE);
> >  }
> >  
> > +if (!vms->highmem &&
> > +vms->memmap[VIRT_MEM].base + ms->maxram_size > 4 * GiB) {
> > +error_report("highmem=off, but memory crosses the 4GiB limit\n");
> > +exit(EXIT_FAILURE);
> 
> The memory is composed of initial memory and device memory.
> device memory is put after the initial memory but has a 1GB alignment
> On top of that you have 1G page alignment per device memory slot
> 
> so potentially the highest mem address is larger than
> vms->memmap[VIRT_MEM].base + ms->maxram_size.
> I would rather do the check on device_memory_base + device_memory_size

Yup, that's a good point.

There is also a corner case in one of the later patches where I check
this limit against the PA using the rounded-up device_memory_size.
This could result in returning an error if the last memory slot would
still fit in the PA space, but the rounded-up quantity wouldn't. I
don't think it matters much, but I'll fix it anyway.

> > +}
> >  /*
> >   * We compute the base of the high IO region depending on the
> >   * amount of initial and device memory. The device memory start/size
> > @@ -1707,7 +1712,9 @@ static void virt_set_memmap(VirtMachineState *vms)
> >  vms->memmap[i].size = size;
> >  base += size;
> >  }
> > -vms->highest_gpa = base - 1;
> > +vms->highest_gpa = (vms->highmem ?
> > +base :
> > +vms->memmap[VIRT_MEM].base + ms->maxram_size) - 1;
> As per the previous comment this looks wrong to me if !highmem.

Agreed.

> If !highmem, if RAM requirements are low we still could get benefit from
> REDIST2 and HIGH ECAM which could fit within the 4GB limit. But maybe we
> simply don't care?

I don't see how. These devices live at a minimum of 256GB, which
contradicts the very meaning of !highmem being a 4GB limit.

> If we don't, why don't we simply skip the extended_memmap overlay as
> suggested in v2? I did not get your reply sorry.

Because although this makes sense if you only care about a 32bit
limit, we eventually want to check against an arbitrary PA limit and
enable the individual devices that do fit in that space.

In order to do that, we need to compute the base addresses for these
extra devices. Also, computing 3 base addresses isn't going to be
massively expensive.

Thanks,

M.

-- 
Without deviation from the norm, progress is not possible.



Re: [PULL 00/27] Linux user for 7.0 patches

2022-01-06 Thread Richard Henderson

On 1/6/22 2:41 AM, Laurent Vivier wrote:

The following changes since commit fb084237a3b78b20fd9d888dffd673b6656ea3be:

   common-user: Really fix i386 calls to safe_syscall_set_errno_tail 
(2022-01-04 21:14:23 -0800)

are available in the Git repository at:

   https://gitlab.com/laurent_vivier/qemu.git 
tags/linux-user-for-7.0-pull-request

for you to fetch changes up to f0effdbc2a5b43422bc4c9c22641ef9dafa0c7ae:

   linux-user: netlink: update IFLA_BRPORT entries (2022-01-06 11:40:53 +0100)


linux-user pull request 20220106

update netlink entries
nios2 fixes
/proc/self/maps fixes
set/getscheduler update
prctl cleanup and fixes
target_signal.h cleanup
and some trivial fixes



Ahmed Abouzied (1):
   linux-user/syscall.c: malloc to g_try_malloc

Andrey Kazmin (1):
   linux-user/syscall.c: fix missed flag for shared memory in
 open_self_maps

Laurent Vivier (3):
   linux-user: netlink: update IFLA entries
   linux-user: netlink: Add IFLA_VFINFO_LIST
   linux-user: netlink: update IFLA_BRPORT entries

Martin Wilck (1):
   qemu-binfmt-conf.sh: fix -F option

Matthias Schiffer (1):
   linux-user/signal: Map exit signals in SIGCHLD siginfo_t

Philippe Mathieu-Daudé (2):
   linux-user/hexagon: Use generic target_stat64 structure
   linux-user: Mark cpu_loop() with noreturn attribute

Richard Henderson (13):
   linux-user: Split out do_prctl and subroutines
   linux-user: Disable more prctl subcodes
   linux-user: Add code for PR_GET/SET_UNALIGN
   target/alpha: Implement prctl_unalign_sigbus
   target/hppa: Implement prctl_unalign_sigbus
   target/sh4: Implement prctl_unalign_sigbus
   linux-user/nios2: Properly emulate EXCP_TRAP
   linux-user/nios2: Fixes for signal frame setup
   linux-user/elfload: Rename ARM_COMMPAGE to HI_COMMPAGE
   linux-user/nios2: Map a real kuser page
   linux-user/nios2: Fix EA vs PC confusion
   linux-user/nios2: Fix sigmask in setup_rt_frame
   linux-user/nios2: Use set_sigmask in do_rt_sigreturn

Song Gao (3):
   linux-user: Move target_signal.h generic definitions to
 generic/signal.h
   linux-user: target_syscall.h remove definition TARGET_MINSIGSTKSZ
   linux-user: Remove TARGET_SIGSTKSZ

Tonis Tiigi (2):
   linux-user: add sched_getattr support
   linux-user: call set/getscheduler set/getparam directly

  cpu.c |  20 +-
  include/hw/core/cpu.h |   3 +
  linux-user/aarch64/target_prctl.h | 160 ++
  linux-user/aarch64/target_signal.h|  18 -
  linux-user/aarch64/target_syscall.h   |  24 -
  linux-user/alpha/target_prctl.h   |   1 +
  linux-user/alpha/target_signal.h  |   1 -
  linux-user/alpha/target_syscall.h |   1 -
  linux-user/arm/target_prctl.h |   1 +
  linux-user/arm/target_signal.h|  18 -
  linux-user/arm/target_syscall.h   |   1 -
  linux-user/cris/target_prctl.h|   1 +
  linux-user/cris/target_signal.h   |  18 -
  linux-user/cris/target_syscall.h  |   1 -
  linux-user/elfload.c  |  66 ++-
  linux-user/fd-trans.c | 184 ++
  linux-user/generic/signal.h   |  15 +
  linux-user/generic/target_prctl_unalign.h |  27 +
  linux-user/hexagon/target_prctl.h |   1 +
  linux-user/hexagon/target_signal.h|  11 -
  linux-user/hppa/target_prctl.h|   1 +
  linux-user/hppa/target_signal.h   |   1 -
  linux-user/hppa/target_syscall.h  |   1 -
  linux-user/i386/target_prctl.h|   1 +
  linux-user/i386/target_signal.h   |  18 -
  linux-user/i386/target_syscall.h  |   1 -
  linux-user/m68k/target_prctl.h|   1 +
  linux-user/m68k/target_signal.h   |  18 -
  linux-user/m68k/target_syscall.h  |   1 -
  linux-user/microblaze/target_prctl.h  |   1 +
  linux-user/microblaze/target_signal.h |  18 -
  linux-user/microblaze/target_syscall.h|   1 -
  linux-user/mips/target_prctl.h|  88 +++
  linux-user/mips/target_signal.h   |   1 -
  linux-user/mips/target_syscall.h  |   7 -
  linux-user/mips64/target_prctl.h  |   1 +
  linux-user/mips64/target_signal.h |   1 -
  linux-user/mips64/target_syscall.h|   7 -
  linux-user/nios2/cpu_loop.c   |  93 +--
  linux-user/nios2/signal.c |  58 +-
  linux-user/nios2/target_prctl.h   |   1 +
  linux-user/nios2/target_signal.h  |  16 -
  linux-user/nios2/target_syscall.h |   1 -
  linux-user/openrisc/target_prctl.h|   1 +
  linux-user/openrisc/target_signal.h   |  23 -
  linux-user/openrisc/target_syscall.h  |   1 -
  linux-user/ppc/target_prctl.h |   1 +
  linux-user/ppc/target_signal.h|  18 -
  linux-user/ppc/target_syscall.h   |   1 -
  linux-user/riscv

Re: [PATCH v8 07/18] target/riscv: setup everything for rv64 to support rv128 execution

2022-01-06 Thread Alistair Francis
On Fri, Jan 7, 2022 at 7:04 AM Frédéric Pétrot
 wrote:
>
> This patch adds the support of the '-cpu rv128' option to
> qemu-system-riscv64 so that we can indicate that we want to run rv128
> executables.
> Still, there is no support for 128-bit insns at that stage so qemu fails
> miserably (as expected) if launched with this option.
>
> Signed-off-by: Frédéric Pétrot 
> Co-authored-by: Fabien Portas 
> Reviewed-by: Alistair Francis 
> ---
>  include/disas/dis-asm.h |  1 +
>  target/riscv/cpu.h  |  1 +
>  disas/riscv.c   |  5 +
>  target/riscv/cpu.c  | 20 
>  target/riscv/gdbstub.c  |  5 +
>  5 files changed, 32 insertions(+)
>
> diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h
> index 08e1beec85..102a1e7f50 100644
> --- a/include/disas/dis-asm.h
> +++ b/include/disas/dis-asm.h
> @@ -459,6 +459,7 @@ int print_insn_nios2(bfd_vma, disassemble_info*);
>  int print_insn_xtensa   (bfd_vma, disassemble_info*);
>  int print_insn_riscv32  (bfd_vma, disassemble_info*);
>  int print_insn_riscv64  (bfd_vma, disassemble_info*);
> +int print_insn_riscv128 (bfd_vma, disassemble_info*);
>  int print_insn_rx(bfd_vma, disassemble_info *);
>  int print_insn_hexagon(bfd_vma, disassemble_info *);
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index fa5d238530..efe481f5fb 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -38,6 +38,7 @@
>  #define TYPE_RISCV_CPU_ANY  RISCV_CPU_TYPE_NAME("any")
>  #define TYPE_RISCV_CPU_BASE32   RISCV_CPU_TYPE_NAME("rv32")
>  #define TYPE_RISCV_CPU_BASE64   RISCV_CPU_TYPE_NAME("rv64")
> +#define TYPE_RISCV_CPU_BASE128  RISCV_CPU_TYPE_NAME("rv128")

As this series only adds partial support for 128-bit support, I think
we should probably change this to "x-rv128". That way we indicate to
users that it is experimental. That allows us more flexibility in the
future to have breaking changes and will hopefully avoid confusion
about the current state. What do you think? I can just make the change
when I apply the patches.

Alistair



[PATCH v8 18/18] target/riscv: actual functions to realize crs 128-bit insns

2022-01-06 Thread Frédéric Pétrot
The csrs are accessed through function pointers: we add 128-bit read
operations in the table for three csrs (writes fallback to the
64-bit version as the upper 64-bit information is handled elsewhere):
- misa, as mxl is needed for proper operation,
- mstatus and sstatus, to return sd
In addition, we also add read and write accesses to the machine and
supervisor scratch registers.

Signed-off-by: Frédéric Pétrot 
Co-authored-by: Fabien Portas 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.h  |   7 ++
 target/riscv/cpu_bits.h |   3 +
 target/riscv/csr.c  | 195 +---
 3 files changed, 175 insertions(+), 30 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index edc7de7b17..a19c65bc1d 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -505,12 +505,19 @@ RISCVException riscv_csrrw_i128(CPURISCVState *env, int 
csrno,
 Int128 *ret_value,
 Int128 new_value, Int128 write_mask);
 
+typedef RISCVException (*riscv_csr_read128_fn)(CPURISCVState *env, int csrno,
+   Int128 *ret_value);
+typedef RISCVException (*riscv_csr_write128_fn)(CPURISCVState *env, int csrno,
+ Int128 new_value);
+
 typedef struct {
 const char *name;
 riscv_csr_predicate_fn predicate;
 riscv_csr_read_fn read;
 riscv_csr_write_fn write;
 riscv_csr_op_fn op;
+riscv_csr_read128_fn read128;
+riscv_csr_write128_fn write128;
 } riscv_csr_operations;
 
 /* CSR function table constants */
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 1e31f4d35f..5a6d49aa64 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -401,6 +401,7 @@
 
 #define MSTATUS32_SD0x8000
 #define MSTATUS64_SD0x8000ULL
+#define MSTATUSH128_SD  0x8000ULL
 
 #define MISA32_MXL  0xC000
 #define MISA64_MXL  0xC000ULL
@@ -423,6 +424,8 @@ typedef enum {
 #define SSTATUS_SUM 0x0004 /* since: priv-1.10 */
 #define SSTATUS_MXR 0x0008
 
+#define SSTATUS64_UXL   0x0003ULL
+
 #define SSTATUS32_SD0x8000
 #define SSTATUS64_SD0x8000ULL
 
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 4c6a44c0b8..adb3d4381d 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -481,7 +481,7 @@ static const target_ulong vs_delegable_excps = 
DELEGABLE_EXCPS &
   (1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT)));
 static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE |
 SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
-SSTATUS_SUM | SSTATUS_MXR | SSTATUS_VS;
+SSTATUS_SUM | SSTATUS_MXR | SSTATUS_VS | (target_ulong)SSTATUS64_UXL;
 static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP;
 static const target_ulong hip_writable_mask = MIP_VSSIP;
 static const target_ulong hvip_writable_mask = MIP_VSSIP | MIP_VSTIP | 
MIP_VSEIP;
@@ -527,6 +527,8 @@ static uint64_t add_status_sd(RISCVMXL xl, uint64_t status)
 return status | MSTATUS32_SD;
 case MXL_RV64:
 return status | MSTATUS64_SD;
+case MXL_RV128:
+return MSTATUSH128_SD;
 default:
 g_assert_not_reached();
 }
@@ -576,10 +578,11 @@ static RISCVException write_mstatus(CPURISCVState *env, 
int csrno,
 
 mstatus = (mstatus & ~mask) | (val & mask);
 
-if (riscv_cpu_mxl(env) == MXL_RV64) {
+RISCVMXL xl = riscv_cpu_mxl(env);
+if (xl > MXL_RV32) {
 /* SXL and UXL fields are for now read only */
-mstatus = set_field(mstatus, MSTATUS64_SXL, MXL_RV64);
-mstatus = set_field(mstatus, MSTATUS64_UXL, MXL_RV64);
+mstatus = set_field(mstatus, MSTATUS64_SXL, xl);
+mstatus = set_field(mstatus, MSTATUS64_UXL, xl);
 }
 env->mstatus = mstatus;
 
@@ -608,6 +611,20 @@ static RISCVException write_mstatush(CPURISCVState *env, 
int csrno,
 return RISCV_EXCP_NONE;
 }
 
+static RISCVException read_mstatus_i128(CPURISCVState *env, int csrno,
+Int128 *val)
+{
+*val = int128_make128(env->mstatus, add_status_sd(MXL_RV128, 
env->mstatus));
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException read_misa_i128(CPURISCVState *env, int csrno,
+ Int128 *val)
+{
+*val = int128_make128(env->misa_ext, (uint64_t)MXL_RV128 << 62);
+return RISCV_EXCP_NONE;
+}
+
 static RISCVException read_misa(CPURISCVState *env, int csrno,
 target_ulong *val)
 {
@@ -765,6 +782,21 @@ static RISCVException write_mcounteren(CPURISCVState *env, 
int csrno,
 }
 
 /* Machine Trap Handling */
+static RISCVException read_mscratch_i128(CPURISCVState *env, int csrno,
+ Int128 *val)
+{
+*val = 

[PATCH v8 16/18] target/riscv: helper functions to wrap calls to 128-bit csr insns

2022-01-06 Thread Frédéric Pétrot
Given the side effects they have, the csr instructions are realized as
helpers. We extend this existing infrastructure for 128-bit sized csr.
We return 128-bit values using the same approach as for div/rem.
Theses helpers all call a unique function that is currently a fallback
on the 64-bit version.
The trans_csrxx functions supporting 128-bit are yet to be implemented.

Signed-off-by: Frédéric Pétrot 
Co-authored-by: Fabien Portas 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.h   |  5 +
 target/riscv/helper.h|  3 +++
 target/riscv/csr.c   | 17 
 target/riscv/op_helper.c | 44 
 4 files changed, 69 insertions(+)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index f3a52fef32..edc7de7b17 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -25,6 +25,7 @@
 #include "exec/cpu-defs.h"
 #include "fpu/softfloat-types.h"
 #include "qom/object.h"
+#include "qemu/int128.h"
 #include "cpu_bits.h"
 
 #define TCG_GUEST_DEFAULT_MO 0
@@ -500,6 +501,10 @@ typedef RISCVException (*riscv_csr_op_fn)(CPURISCVState 
*env, int csrno,
   target_ulong new_value,
   target_ulong write_mask);
 
+RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
+Int128 *ret_value,
+Int128 new_value, Int128 write_mask);
+
 typedef struct {
 const char *name;
 riscv_csr_predicate_fn predicate;
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index a8ee8a362a..6cf6d6ce98 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -96,6 +96,9 @@ DEF_HELPER_FLAGS_1(fclass_h, TCG_CALL_NO_RWG_SE, tl, i64)
 DEF_HELPER_2(csrr, tl, env, int)
 DEF_HELPER_3(csrw, void, env, int, tl)
 DEF_HELPER_4(csrrw, tl, env, int, tl, tl)
+DEF_HELPER_2(csrr_i128, tl, env, int)
+DEF_HELPER_4(csrw_i128, void, env, int, tl, tl)
+DEF_HELPER_6(csrrw_i128, tl, env, int, tl, tl, tl, tl)
 #ifndef CONFIG_USER_ONLY
 DEF_HELPER_2(sret, tl, env, tl)
 DEF_HELPER_2(mret, tl, env, tl)
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 146447eac5..4c6a44c0b8 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1817,6 +1817,23 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
 return RISCV_EXCP_NONE;
 }
 
+RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
+   Int128 *ret_value,
+   Int128 new_value, Int128 write_mask)
+{
+/* fall back to 64-bit version for now */
+target_ulong ret_64;
+RISCVException ret = riscv_csrrw(env, csrno, _64,
+ int128_getlo(new_value),
+ int128_getlo(write_mask));
+
+if (ret_value) {
+*ret_value = int128_make64(ret_64);
+}
+
+return ret;
+}
+
 /*
  * Debugger support.  If not in user mode, set env->debugger before the
  * riscv_csrrw call and clear it after the call.
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 58d992e98a..6f040f2fb9 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -69,6 +69,50 @@ target_ulong helper_csrrw(CPURISCVState *env, int csr,
 return val;
 }
 
+target_ulong helper_csrr_i128(CPURISCVState *env, int csr)
+{
+Int128 rv = int128_zero();
+RISCVException ret = riscv_csrrw_i128(env, csr, ,
+  int128_zero(),
+  int128_zero());
+
+if (ret != RISCV_EXCP_NONE) {
+riscv_raise_exception(env, ret, GETPC());
+}
+
+env->retxh = int128_gethi(rv);
+return int128_getlo(rv);
+}
+
+void helper_csrw_i128(CPURISCVState *env, int csr,
+  target_ulong srcl, target_ulong srch)
+{
+RISCVException ret = riscv_csrrw_i128(env, csr, NULL,
+  int128_make128(srcl, srch),
+  UINT128_MAX);
+
+if (ret != RISCV_EXCP_NONE) {
+riscv_raise_exception(env, ret, GETPC());
+}
+}
+
+target_ulong helper_csrrw_i128(CPURISCVState *env, int csr,
+   target_ulong srcl, target_ulong srch,
+   target_ulong maskl, target_ulong maskh)
+{
+Int128 rv = int128_zero();
+RISCVException ret = riscv_csrrw_i128(env, csr, ,
+  int128_make128(srcl, srch),
+  int128_make128(maskl, maskh));
+
+if (ret != RISCV_EXCP_NONE) {
+riscv_raise_exception(env, ret, GETPC());
+}
+
+env->retxh = int128_gethi(rv);
+return int128_getlo(rv);
+}
+
 #ifndef CONFIG_USER_ONLY
 
 target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
-- 
2.34.1




[PATCH v8 17/18] target/riscv: modification of the trans_csrxx for 128-bit support

2022-01-06 Thread Frédéric Pétrot
As opposed to the gen_arith and gen_shift generation helpers, the csr insns
do not have a common prototype, so the choice to generate 32/64 or 128-bit
helper calls is done in the trans_csrxx functions.

Signed-off-by: Frédéric Pétrot 
Co-authored-by: Fabien Portas 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rvi.c.inc | 205 ++--
 1 file changed, 160 insertions(+), 45 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.c.inc 
b/target/riscv/insn_trans/trans_rvi.c.inc
index ca354130ec..3a0ae28fef 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -881,20 +881,78 @@ static bool do_csrrw(DisasContext *ctx, int rd, int rc, 
TCGv src, TCGv mask)
 return do_csr_post(ctx);
 }
 
+static bool do_csrr_i128(DisasContext *ctx, int rd, int rc)
+{
+TCGv destl = dest_gpr(ctx, rd);
+TCGv desth = dest_gprh(ctx, rd);
+TCGv_i32 csr = tcg_constant_i32(rc);
+
+if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
+gen_io_start();
+}
+gen_helper_csrr_i128(destl, cpu_env, csr);
+tcg_gen_ld_tl(desth, cpu_env, offsetof(CPURISCVState, retxh));
+gen_set_gpr128(ctx, rd, destl, desth);
+return do_csr_post(ctx);
+}
+
+static bool do_csrw_i128(DisasContext *ctx, int rc, TCGv srcl, TCGv srch)
+{
+TCGv_i32 csr = tcg_constant_i32(rc);
+
+if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
+gen_io_start();
+}
+gen_helper_csrw_i128(cpu_env, csr, srcl, srch);
+return do_csr_post(ctx);
+}
+
+static bool do_csrrw_i128(DisasContext *ctx, int rd, int rc,
+  TCGv srcl, TCGv srch, TCGv maskl, TCGv maskh)
+{
+TCGv destl = dest_gpr(ctx, rd);
+TCGv desth = dest_gprh(ctx, rd);
+TCGv_i32 csr = tcg_constant_i32(rc);
+
+if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
+gen_io_start();
+}
+gen_helper_csrrw_i128(destl, cpu_env, csr, srcl, srch, maskl, maskh);
+tcg_gen_ld_tl(desth, cpu_env, offsetof(CPURISCVState, retxh));
+gen_set_gpr128(ctx, rd, destl, desth);
+return do_csr_post(ctx);
+}
+
 static bool trans_csrrw(DisasContext *ctx, arg_csrrw *a)
 {
-TCGv src = get_gpr(ctx, a->rs1, EXT_NONE);
-
-/*
- * If rd == 0, the insn shall not read the csr, nor cause any of the
- * side effects that might occur on a csr read.
- */
-if (a->rd == 0) {
-return do_csrw(ctx, a->csr, src);
+if (get_xl(ctx) < MXL_RV128) {
+TCGv src = get_gpr(ctx, a->rs1, EXT_NONE);
+
+/*
+ * If rd == 0, the insn shall not read the csr, nor cause any of the
+ * side effects that might occur on a csr read.
+ */
+if (a->rd == 0) {
+return do_csrw(ctx, a->csr, src);
+}
+
+TCGv mask = tcg_constant_tl(-1);
+return do_csrrw(ctx, a->rd, a->csr, src, mask);
+} else {
+TCGv srcl = get_gpr(ctx, a->rs1, EXT_NONE);
+TCGv srch = get_gprh(ctx, a->rs1);
+
+/*
+ * If rd == 0, the insn shall not read the csr, nor cause any of the
+ * side effects that might occur on a csr read.
+ */
+if (a->rd == 0) {
+return do_csrw_i128(ctx, a->csr, srcl, srch);
+}
+
+TCGv mask = tcg_constant_tl(-1);
+return do_csrrw_i128(ctx, a->rd, a->csr, srcl, srch, mask, mask);
 }
-
-TCGv mask = tcg_constant_tl(-1);
-return do_csrrw(ctx, a->rd, a->csr, src, mask);
 }
 
 static bool trans_csrrs(DisasContext *ctx, arg_csrrs *a)
@@ -906,13 +964,24 @@ static bool trans_csrrs(DisasContext *ctx, arg_csrrs *a)
  * a zero value, the instruction will still attempt to write the
  * unmodified value back to the csr and will cause side effects.
  */
-if (a->rs1 == 0) {
-return do_csrr(ctx, a->rd, a->csr);
+if (get_xl(ctx) < MXL_RV128) {
+if (a->rs1 == 0) {
+return do_csrr(ctx, a->rd, a->csr);
+}
+
+TCGv ones = tcg_constant_tl(-1);
+TCGv mask = get_gpr(ctx, a->rs1, EXT_ZERO);
+return do_csrrw(ctx, a->rd, a->csr, ones, mask);
+} else {
+if (a->rs1 == 0) {
+return do_csrr_i128(ctx, a->rd, a->csr);
+}
+
+TCGv ones = tcg_constant_tl(-1);
+TCGv maskl = get_gpr(ctx, a->rs1, EXT_ZERO);
+TCGv maskh = get_gprh(ctx, a->rs1);
+return do_csrrw_i128(ctx, a->rd, a->csr, ones, ones, maskl, maskh);
 }
-
-TCGv ones = tcg_constant_tl(-1);
-TCGv mask = get_gpr(ctx, a->rs1, EXT_ZERO);
-return do_csrrw(ctx, a->rd, a->csr, ones, mask);
 }
 
 static bool trans_csrrc(DisasContext *ctx, arg_csrrc *a)
@@ -924,28 +993,54 @@ static bool trans_csrrc(DisasContext *ctx, arg_csrrc *a)
  * a zero value, the instruction will still attempt to write the
  * unmodified value back to the csr and will cause side effects.
  */
-if (a->rs1 == 0) {
-return do_csrr(ctx, a->rd, a->csr);
+if (get_xl(ctx) < MXL_RV128) {
+

[PATCH v8 11/18] target/riscv: support for 128-bit U-type instructions

2022-01-06 Thread Frédéric Pétrot
Adding the 128-bit version of lui and auipc, and introducing to that end
a "set register with immediat" function to handle extension on 128 bits.

Signed-off-by: Frédéric Pétrot 
Co-authored-by: Fabien Portas 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/translate.c| 21 +
 target/riscv/insn_trans/trans_rvi.c.inc |  8 
 2 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index b43efc9bc3..ba1ad1be5f 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -322,6 +322,27 @@ static void gen_set_gpr(DisasContext *ctx, int reg_num, 
TCGv t)
 }
 }
 
+static void gen_set_gpri(DisasContext *ctx, int reg_num, target_long imm)
+{
+if (reg_num != 0) {
+switch (get_ol(ctx)) {
+case MXL_RV32:
+tcg_gen_movi_tl(cpu_gpr[reg_num], (int32_t)imm);
+break;
+case MXL_RV64:
+case MXL_RV128:
+tcg_gen_movi_tl(cpu_gpr[reg_num], imm);
+break;
+default:
+g_assert_not_reached();
+}
+
+if (get_xl_max(ctx) == MXL_RV128) {
+tcg_gen_movi_tl(cpu_gprh[reg_num], -(imm < 0));
+}
+}
+}
+
 static void gen_set_gpr128(DisasContext *ctx, int reg_num, TCGv rl, TCGv rh)
 {
 assert(get_ol(ctx) == MXL_RV128);
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc 
b/target/riscv/insn_trans/trans_rvi.c.inc
index e572976e88..6113acc669 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -26,14 +26,14 @@ static bool trans_illegal(DisasContext *ctx, arg_empty *a)
 
 static bool trans_c64_illegal(DisasContext *ctx, arg_empty *a)
 {
- REQUIRE_64BIT(ctx);
- return trans_illegal(ctx, a);
+REQUIRE_64_OR_128BIT(ctx);
+return trans_illegal(ctx, a);
 }
 
 static bool trans_lui(DisasContext *ctx, arg_lui *a)
 {
 if (a->rd != 0) {
-tcg_gen_movi_tl(cpu_gpr[a->rd], a->imm);
+gen_set_gpri(ctx, a->rd, a->imm);
 }
 return true;
 }
@@ -41,7 +41,7 @@ static bool trans_lui(DisasContext *ctx, arg_lui *a)
 static bool trans_auipc(DisasContext *ctx, arg_auipc *a)
 {
 if (a->rd != 0) {
-tcg_gen_movi_tl(cpu_gpr[a->rd], a->imm + ctx->base.pc_next);
+gen_set_gpri(ctx, a->rd, a->imm + ctx->base.pc_next);
 }
 return true;
 }
-- 
2.34.1




[PATCH v8 12/18] target/riscv: support for 128-bit shift instructions

2022-01-06 Thread Frédéric Pétrot
Handling shifts for 32, 64 and 128 operation length for RV128, following the
general framework for handling various olens proposed by Richard.

Signed-off-by: Frédéric Pétrot 
Co-authored-by: Fabien Portas 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn32.decode  |  10 ++
 target/riscv/translate.c|  58 --
 target/riscv/insn_trans/trans_rvb.c.inc |  22 +--
 target/riscv/insn_trans/trans_rvi.c.inc | 224 ++--
 4 files changed, 270 insertions(+), 44 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index ddbf0da03c..a992c6d369 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -22,6 +22,7 @@
 %rs1   15:5
 %rd7:5
 %sh5   20:5
+%sh6   20:6
 
 %sh720:7
 %csr20:12
@@ -91,6 +92,9 @@
 # Formats 64:
 @sh5 ...  . .  ... . ...   shamt=%sh5  %rs1 
%rd
 
+# Formats 128:
+@sh6   .. .. . ... . ...  shamt=%sh6 %rs1 %rd
+
 # *** Privileged Instructions ***
 ecall    0 000 0 1110011
 ebreak  0001 0 000 0 1110011
@@ -166,6 +170,12 @@ sraw 010 .  . 101 . 0111011 @r
 ldu     . 111 . 011 @i
 lq      . 010 . 000 @i
 sq      . 100 . 0100011 @s
+sllid00 ..  . 001 . 1011011 @sh6
+srlid00 ..  . 101 . 1011011 @sh6
+sraid01 ..  . 101 . 1011011 @sh6
+slld 000 . .  001 . 011 @r
+srld 000 . .  101 . 011 @r
+srad 010 . .  101 . 011 @r
 
 # *** RV32M Standard Extension ***
 mul  001 .  . 000 . 0110011 @r
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index ba1ad1be5f..89220a5fae 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -635,7 +635,8 @@ static bool gen_arith_per_ol(DisasContext *ctx, arg_r *a, 
DisasExtend ext,
 }
 
 static bool gen_shift_imm_fn(DisasContext *ctx, arg_shift *a, DisasExtend ext,
- void (*func)(TCGv, TCGv, target_long))
+ void (*func)(TCGv, TCGv, target_long),
+ void (*f128)(TCGv, TCGv, TCGv, TCGv, target_long))
 {
 TCGv dest, src1;
 int max_len = get_olen(ctx);
@@ -647,26 +648,38 @@ static bool gen_shift_imm_fn(DisasContext *ctx, arg_shift 
*a, DisasExtend ext,
 dest = dest_gpr(ctx, a->rd);
 src1 = get_gpr(ctx, a->rs1, ext);
 
-func(dest, src1, a->shamt);
+if (max_len < 128) {
+func(dest, src1, a->shamt);
+gen_set_gpr(ctx, a->rd, dest);
+} else {
+TCGv src1h = get_gprh(ctx, a->rs1);
+TCGv desth = dest_gprh(ctx, a->rd);
 
-gen_set_gpr(ctx, a->rd, dest);
+if (f128 == NULL) {
+return false;
+}
+f128(dest, desth, src1, src1h, a->shamt);
+gen_set_gpr128(ctx, a->rd, dest, desth);
+}
 return true;
 }
 
 static bool gen_shift_imm_fn_per_ol(DisasContext *ctx, arg_shift *a,
 DisasExtend ext,
 void (*f_tl)(TCGv, TCGv, target_long),
-void (*f_32)(TCGv, TCGv, target_long))
+void (*f_32)(TCGv, TCGv, target_long),
+void (*f_128)(TCGv, TCGv, TCGv, TCGv,
+  target_long))
 {
 int olen = get_olen(ctx);
 if (olen != TARGET_LONG_BITS) {
 if (olen == 32) {
 f_tl = f_32;
-} else {
+} else if (olen != 128) {
 g_assert_not_reached();
 }
 }
-return gen_shift_imm_fn(ctx, a, ext, f_tl);
+return gen_shift_imm_fn(ctx, a, ext, f_tl, f_128);
 }
 
 static bool gen_shift_imm_tl(DisasContext *ctx, arg_shift *a, DisasExtend ext,
@@ -690,34 +703,49 @@ static bool gen_shift_imm_tl(DisasContext *ctx, arg_shift 
*a, DisasExtend ext,
 }
 
 static bool gen_shift(DisasContext *ctx, arg_r *a, DisasExtend ext,
-  void (*func)(TCGv, TCGv, TCGv))
+  void (*func)(TCGv, TCGv, TCGv),
+  void (*f128)(TCGv, TCGv, TCGv, TCGv, TCGv))
 {
-TCGv dest = dest_gpr(ctx, a->rd);
-TCGv src1 = get_gpr(ctx, a->rs1, ext);
 TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
 TCGv ext2 = tcg_temp_new();
+int max_len = get_olen(ctx);
 
-tcg_gen_andi_tl(ext2, src2, get_olen(ctx) - 1);
-func(dest, src1, ext2);
+tcg_gen_andi_tl(ext2, src2, max_len - 1);
 
-gen_set_gpr(ctx, a->rd, dest);
+TCGv dest = dest_gpr(ctx, a->rd);
+TCGv src1 = get_gpr(ctx, a->rs1, ext);
+
+if (max_len < 128) {
+func(dest, src1, ext2);
+gen_set_gpr(ctx, a->rd, dest);
+} else {
+TCGv src1h = get_gprh(ctx, a->rs1);
+TCGv desth = dest_gprh(ctx, a->rd);
+
+

[PATCH v8 15/18] target/riscv: adding high part of some csrs

2022-01-06 Thread Frédéric Pétrot
Adding the high part of a very minimal set of csr.

Signed-off-by: Frédéric Pétrot 
Co-authored-by: Fabien Portas 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.h | 4 
 target/riscv/machine.c | 2 ++
 2 files changed, 6 insertions(+)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index f05f2411ae..f3a52fef32 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -195,6 +195,10 @@ struct CPURISCVState {
 target_ulong hgatp;
 uint64_t htimedelta;
 
+/* Upper 64-bits of 128-bit CSRs */
+uint64_t mscratchh;
+uint64_t sscratchh;
+
 /* Virtual CSRs */
 /*
  * For RV32 this is 32-bit vsstatus and 32-bit vsstatush.
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index 8af9caabf5..13b9ab375b 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -179,6 +179,8 @@ static const VMStateDescription vmstate_rv128 = {
 .needed = rv128_needed,
 .fields = (VMStateField[]) {
 VMSTATE_UINTTL_ARRAY(env.gprh, RISCVCPU, 32),
+VMSTATE_UINT64(env.mscratchh, RISCVCPU),
+VMSTATE_UINT64(env.sscratchh, RISCVCPU),
 VMSTATE_END_OF_LIST()
 }
 };
-- 
2.34.1




[PATCH v8 09/18] target/riscv: accessors to registers upper part and 128-bit load/store

2022-01-06 Thread Frédéric Pétrot
Get function to retrieve the 64 top bits of a register, stored in the gprh
field of the cpu state. Set function that writes the 128-bit value at once.
The access to the gprh field can not be protected at compile time to make
sure it is accessed only in the 128-bit version of the processor because we
have no way to indicate that the misa_mxl_max field is const.

The 128-bit ISA adds ldu, lq and sq. We provide support for these
instructions. Note that (a) we compute only 64-bit addresses to actually
access memory, cowardly utilizing the existing address translation mechanism
of QEMU, and (b) we assume for now little-endian memory accesses.

Signed-off-by: Frédéric Pétrot 
Co-authored-by: Fabien Portas 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn16.decode  |  27 ++-
 target/riscv/insn32.decode  |   5 ++
 target/riscv/translate.c|  41 ++
 target/riscv/insn_trans/trans_rvi.c.inc | 100 ++--
 4 files changed, 163 insertions(+), 10 deletions(-)

diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index 2e9212663c..02c8f61b48 100644
--- a/target/riscv/insn16.decode
+++ b/target/riscv/insn16.decode
@@ -25,14 +25,17 @@
 # Immediates:
 %imm_ci12:s1 2:5
 %nzuimm_ciw7:4 11:2 5:1 6:1   !function=ex_shift_2
+%uimm_cl_q 10:1 5:2 11:2  !function=ex_shift_4
 %uimm_cl_d 5:2 10:3   !function=ex_shift_3
 %uimm_cl_w 5:1 10:3 6:1   !function=ex_shift_2
 %imm_cb12:s1 5:2 2:1 10:2 3:2 !function=ex_shift_1
 %imm_cj12:s1 8:1 9:2 6:1 7:1 2:1 11:1 3:3 !function=ex_shift_1
 
 %shimm_6bit   12:1 2:5   !function=ex_rvc_shifti
+%uimm_6bit_lq 2:4 12:1 6:1   !function=ex_shift_4
 %uimm_6bit_ld 2:3 12:1 5:2   !function=ex_shift_3
 %uimm_6bit_lw 2:2 12:1 4:3   !function=ex_shift_2
+%uimm_6bit_sq 7:4 11:2   !function=ex_shift_4
 %uimm_6bit_sd 7:3 10:3   !function=ex_shift_3
 %uimm_6bit_sw 7:2 9:4!function=ex_shift_2
 
@@ -54,16 +57,20 @@
 # Formats 16:
 @cr  . .  ..   rs2=%rs2_5   rs1=%rd %rd
 @ci... . . .  ..   imm=%imm_ci  rs1=%rd %rd
+@cl_q  ... . .  . ..   imm=%uimm_cl_q   rs1=%rs1_3  rd=%rs2_3
 @cl_d  ... ... ... .. ... ..   imm=%uimm_cl_d   rs1=%rs1_3  rd=%rs2_3
 @cl_w  ... ... ... .. ... ..   imm=%uimm_cl_w   rs1=%rs1_3  rd=%rs2_3
 @cs_2  ... ... ... .. ... ..   rs2=%rs2_3   rs1=%rs1_3  rd=%rs1_3
+@cs_q  ... ... ... .. ... ..   imm=%uimm_cl_q   rs1=%rs1_3  
rs2=%rs2_3
 @cs_d  ... ... ... .. ... ..   imm=%uimm_cl_d   rs1=%rs1_3  
rs2=%rs2_3
 @cs_w  ... ... ... .. ... ..   imm=%uimm_cl_w   rs1=%rs1_3  
rs2=%rs2_3
 @cj...... ..   imm=%imm_cj
 @cb_z  ... ... ... .. ... ..   imm=%imm_cb  rs1=%rs1_3  rs2=0
 
+@c_lqsp... . .  . ..   imm=%uimm_6bit_lq rs1=2 %rd
 @c_ldsp... . .  . ..   imm=%uimm_6bit_ld rs1=2 %rd
 @c_lwsp... . .  . ..   imm=%uimm_6bit_lw rs1=2 %rd
+@c_sqsp... . .  . ..   imm=%uimm_6bit_sq rs1=2 rs2=%rs2_5
 @c_sdsp... . .  . ..   imm=%uimm_6bit_sd rs1=2 rs2=%rs2_5
 @c_swsp... . .  . ..   imm=%uimm_6bit_sw rs1=2 rs2=%rs2_5
 @c_li  ... . .  . ..   imm=%imm_ci rs1=0 %rd
@@ -87,9 +94,15 @@
   illegal 000  000 000 00 --- 00
   addi000  ... ... .. ... 00 @c_addi4spn
 }
-fld   001  ... ... .. ... 00 @cl_d
+{
+  lq  001  ... ... .. ... 00 @cl_q
+  fld 001  ... ... .. ... 00 @cl_d
+}
 lw010  ... ... .. ... 00 @cl_w
-fsd   101  ... ... .. ... 00 @cs_d
+{
+  sq  101  ... ... .. ... 00 @cs_q
+  fsd 101  ... ... .. ... 00 @cs_d
+}
 sw110  ... ... .. ... 00 @cs_w
 
 # *** RV32C and RV64C specific Standard Extension (Quadrant 0) ***
@@ -132,7 +145,10 @@ addw  100 1 11 ... 01 ... 01 @cs_2
 
 # *** RV32/64C Standard Extension (Quadrant 2) ***
 slli  000 .  .  . 10 @c_shift2
-fld   001 .  .  . 10 @c_ldsp
+{
+  lq  001  ... ... .. ... 10 @c_lqsp
+  fld 001 .  .  . 10 @c_ldsp
+}
 {
   illegal 010 -  0  - 10 # c.lwsp, RES rd=0
   lw  010 .  .  . 10 @c_lwsp
@@ -147,7 +163,10 @@ fld   001 .  .  . 10 @c_ldsp
   jalr100 1  .  0 10 @c_jalr rd=1  # C.JALR
   add 100 1  .  . 10 @cr
 }
-fsd   101   ..  . 10 @c_sdsp
+{
+  sq  101  ... ... .. ... 10 @c_sqsp
+  fsd 101   ..  . 10 @c_sdsp
+}
 sw110 .  .  . 10 @c_swsp
 
 # *** RV32C and RV64C specific Standard Extension (Quadrant 2) ***
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 8617307b29..ddbf0da03c 100644
--- 

[PATCH v8 13/18] target/riscv: support for 128-bit arithmetic instructions

2022-01-06 Thread Frédéric Pétrot
Addition of 128-bit adds and subs in their various sizes,
"set if less than"s and branches.
Refactored the code to have a comparison function used for both stls and
branches.

Signed-off-by: Frédéric Pétrot 
Co-authored-by: Fabien Portas 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn32.decode  |   3 +
 target/riscv/translate.c|  63 --
 target/riscv/insn_trans/trans_rvb.c.inc |  20 +--
 target/riscv/insn_trans/trans_rvi.c.inc | 159 +---
 target/riscv/insn_trans/trans_rvm.c.inc |  26 ++--
 5 files changed, 222 insertions(+), 49 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index a992c6d369..42366d20fb 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -170,9 +170,12 @@ sraw 010 .  . 101 . 0111011 @r
 ldu     . 111 . 011 @i
 lq      . 010 . 000 @i
 sq      . 100 . 0100011 @s
+addid  .  000 . 1011011 @i
 sllid00 ..  . 001 . 1011011 @sh6
 srlid00 ..  . 101 . 1011011 @sh6
 sraid01 ..  . 101 . 1011011 @sh6
+addd 000 . .  000 . 011 @r
+subd 010 . .  000 . 011 @r
 slld 000 . .  001 . 011 @r
 srld 000 . .  101 . 011 @r
 srad 010 . .  101 . 011 @r
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 89220a5fae..4ae4345691 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -581,57 +581,96 @@ static bool gen_logic(DisasContext *ctx, arg_r *a,
 }
 
 static bool gen_arith_imm_fn(DisasContext *ctx, arg_i *a, DisasExtend ext,
- void (*func)(TCGv, TCGv, target_long))
+ void (*func)(TCGv, TCGv, target_long),
+ void (*f128)(TCGv, TCGv, TCGv, TCGv, target_long))
 {
 TCGv dest = dest_gpr(ctx, a->rd);
 TCGv src1 = get_gpr(ctx, a->rs1, ext);
 
-func(dest, src1, a->imm);
+if (get_ol(ctx) < MXL_RV128) {
+func(dest, src1, a->imm);
+gen_set_gpr(ctx, a->rd, dest);
+} else {
+if (f128 == NULL) {
+return false;
+}
 
-gen_set_gpr(ctx, a->rd, dest);
+TCGv src1h = get_gprh(ctx, a->rs1);
+TCGv desth = dest_gprh(ctx, a->rd);
+
+f128(dest, desth, src1, src1h, a->imm);
+gen_set_gpr128(ctx, a->rd, dest, desth);
+}
 return true;
 }
 
 static bool gen_arith_imm_tl(DisasContext *ctx, arg_i *a, DisasExtend ext,
- void (*func)(TCGv, TCGv, TCGv))
+ void (*func)(TCGv, TCGv, TCGv),
+ void (*f128)(TCGv, TCGv, TCGv, TCGv, TCGv, TCGv))
 {
 TCGv dest = dest_gpr(ctx, a->rd);
 TCGv src1 = get_gpr(ctx, a->rs1, ext);
 TCGv src2 = tcg_constant_tl(a->imm);
 
-func(dest, src1, src2);
+if (get_ol(ctx) < MXL_RV128) {
+func(dest, src1, src2);
+gen_set_gpr(ctx, a->rd, dest);
+} else {
+if (f128 == NULL) {
+return false;
+}
 
-gen_set_gpr(ctx, a->rd, dest);
+TCGv src1h = get_gprh(ctx, a->rs1);
+TCGv src2h = tcg_constant_tl(-(a->imm < 0));
+TCGv desth = dest_gprh(ctx, a->rd);
+
+f128(dest, desth, src1, src1h, src2, src2h);
+gen_set_gpr128(ctx, a->rd, dest, desth);
+}
 return true;
 }
 
 static bool gen_arith(DisasContext *ctx, arg_r *a, DisasExtend ext,
-  void (*func)(TCGv, TCGv, TCGv))
+  void (*func)(TCGv, TCGv, TCGv),
+  void (*f128)(TCGv, TCGv, TCGv, TCGv, TCGv, TCGv))
 {
 TCGv dest = dest_gpr(ctx, a->rd);
 TCGv src1 = get_gpr(ctx, a->rs1, ext);
 TCGv src2 = get_gpr(ctx, a->rs2, ext);
 
-func(dest, src1, src2);
+if (get_ol(ctx) < MXL_RV128) {
+func(dest, src1, src2);
+gen_set_gpr(ctx, a->rd, dest);
+} else {
+if (f128 == NULL) {
+return false;
+}
 
-gen_set_gpr(ctx, a->rd, dest);
+TCGv src1h = get_gprh(ctx, a->rs1);
+TCGv src2h = get_gprh(ctx, a->rs2);
+TCGv desth = dest_gprh(ctx, a->rd);
+
+f128(dest, desth, src1, src1h, src2, src2h);
+gen_set_gpr128(ctx, a->rd, dest, desth);
+}
 return true;
 }
 
 static bool gen_arith_per_ol(DisasContext *ctx, arg_r *a, DisasExtend ext,
  void (*f_tl)(TCGv, TCGv, TCGv),
- void (*f_32)(TCGv, TCGv, TCGv))
+ void (*f_32)(TCGv, TCGv, TCGv),
+ void (*f_128)(TCGv, TCGv, TCGv, TCGv, TCGv, TCGv))
 {
 int olen = get_olen(ctx);
 
 if (olen != TARGET_LONG_BITS) {
 if (olen == 32) {
 f_tl = f_32;
-} else {
+} else if (olen != 128) {
 

[PATCH v8 14/18] target/riscv: support for 128-bit M extension

2022-01-06 Thread Frédéric Pétrot
Mult are generated inline (using a cool trick pointed out by Richard), but
for div and rem, given the complexity of the implementation of these
instructions, we call helpers to produce their behavior. From an
implementation standpoint, the helpers return the low part of the results,
while the high part is temporarily stored in a dedicated field of cpu_env
that is used to update the architectural register in the generation wrapper.

Signed-off-by: Frédéric Pétrot 
Co-authored-by: Fabien Portas 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.h  |   3 +
 target/riscv/helper.h   |   6 +
 target/riscv/insn32.decode  |   7 +
 target/riscv/m128_helper.c  | 109 ++
 target/riscv/insn_trans/trans_rvm.c.inc | 182 ++--
 target/riscv/meson.build|   1 +
 6 files changed, 295 insertions(+), 13 deletions(-)
 create mode 100644 target/riscv/m128_helper.c

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index efe481f5fb..f05f2411ae 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -143,6 +143,9 @@ struct CPURISCVState {
 uint32_t misa_ext;  /* current extensions */
 uint32_t misa_ext_mask; /* max ext for this cpu */
 
+/* 128-bit helpers upper part return value */
+target_ulong retxh;
+
 uint32_t features;
 
 #ifdef CONFIG_USER_ONLY
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index c15497e4a1..a8ee8a362a 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1101,3 +1101,9 @@ DEF_HELPER_5(vsext_vf2_d, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vsext_vf4_w, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vsext_vf4_d, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vsext_vf8_d, void, ptr, ptr, ptr, env, i32)
+
+/* 128-bit integer multiplication and division */
+DEF_HELPER_5(divu_i128, tl, env, tl, tl, tl, tl)
+DEF_HELPER_5(divs_i128, tl, env, tl, tl, tl, tl)
+DEF_HELPER_5(remu_i128, tl, env, tl, tl, tl, tl)
+DEF_HELPER_5(rems_i128, tl, env, tl, tl, tl, tl)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 42366d20fb..5bbedc254c 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -197,6 +197,13 @@ divuw001 .  . 101 . 0111011 @r
 remw 001 .  . 110 . 0111011 @r
 remuw001 .  . 111 . 0111011 @r
 
+# *** RV128M Standard Extension (in addition to RV64M) ***
+muld 001 .  . 000 . 011 @r
+divd 001 .  . 100 . 011 @r
+divud001 .  . 101 . 011 @r
+remd 001 .  . 110 . 011 @r
+remud001 .  . 111 . 011 @r
+
 # *** RV32A Standard Extension ***
 lr_w   00010 . . 0 . 010 . 010 @atom_ld
 sc_w   00011 . . . . 010 . 010 @atom_st
diff --git a/target/riscv/m128_helper.c b/target/riscv/m128_helper.c
new file mode 100644
index 00..7bf115b85e
--- /dev/null
+++ b/target/riscv/m128_helper.c
@@ -0,0 +1,109 @@
+/*
+ * RISC-V Emulation Helpers for QEMU.
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
+ * Copyright (c) 2017-2018 SiFive, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 .
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "qemu/main-loop.h"
+#include "exec/exec-all.h"
+#include "exec/helper-proto.h"
+
+target_ulong HELPER(divu_i128)(CPURISCVState *env,
+   target_ulong ul, target_ulong uh,
+   target_ulong vl, target_ulong vh)
+{
+target_ulong ql, qh;
+Int128 q;
+
+if (vl == 0 && vh == 0) { /* Handle special behavior on div by zero */
+ql = ~0x0;
+qh = ~0x0;
+} else {
+q = int128_divu(int128_make128(ul, uh), int128_make128(vl, vh));
+ql = int128_getlo(q);
+qh = int128_gethi(q);
+}
+
+env->retxh = qh;
+return ql;
+}
+
+target_ulong HELPER(remu_i128)(CPURISCVState *env,
+   target_ulong ul, target_ulong uh,
+   target_ulong vl, target_ulong vh)
+{
+target_ulong rl, rh;
+Int128 r;
+
+if (vl == 0 && vh == 0) {
+rl = ul;
+rh = uh;
+} else {
+r = int128_remu(int128_make128(ul, uh), int128_make128(vl, vh));
+rl = int128_getlo(r);
+rh = int128_gethi(r);
+}
+
+env->retxh = 

Re: [PATCH] net: Fix uninitialized data usage

2022-01-06 Thread Peter Foley
Yeah, but this same pattern is used elsewhere in the file, so I went with
being consistent.

On Thu, Jan 6, 2022, 2:44 PM Philippe Mathieu-Daudé  wrote:

> On 6/1/22 19:28, Patrick Venture wrote:
> > From: Peter Foley 
> >
> > e.g.
> > 1109 15:16:20.151506 Uninitialized bytes in ioctl_common_pre at offset 0
> inside [0x7ffc516af9b8, 4)
> >   1109 15:16:20.151659 ==588974==WARNING: MemorySanitizer:
> use-of-uninitialized-value
> >   1109 15:16:20.312923 #0 0x5639b88acb21 in tap_probe_vnet_hdr_len
> third_party/qemu/net/tap-linux.c:183:9
> >   1109 15:16:20.312952 #1 0x5639b88afd66 in net_tap_fd_init
> third_party/qemu/net/tap.c:409:9
> >   1109 15:16:20.312954 #2 0x5639b88b2d1b in net_init_tap_one
> third_party/qemu/net/tap.c:681:19
> >   1109 15:16:20.312956 #3 0x5639b88b16a8 in net_init_tap
> third_party/qemu/net/tap.c:912:13
> >   1109 15:16:20.312957 #4 0x5639b8890175 in net_client_init1
> third_party/qemu/net/net.c:1110:9
> >   1109 15:16:20.312958 #5 0x5639b888f912 in net_client_init
> third_party/qemu/net/net.c:1208:15
> >   1109 15:16:20.312960 #6 0x5639b8894aa5 in net_param_nic
> third_party/qemu/net/net.c:1588:11
> >   1109 15:16:20.312961 #7 0x5639b900cd18 in qemu_opts_foreach
> third_party/qemu/util/qemu-option.c:1135:14
> >   1109 15:16:20.312962 #8 0x5639b889393c in net_init_clients
> third_party/qemu/net/net.c:1612:9
> >   1109 15:16:20.312964 #9 0x5639b717aaf3 in
> qemu_create_late_backends third_party/qemu/softmmu/vl.c:1962:5
> >   1109 15:16:20.312965 #10 0x5639b717aaf3 in qemu_init
> third_party/qemu/softmmu/vl.c:3694:5
> >   1109 15:16:20.312967 #11 0x5639b71083b8 in main
> third_party/qemu/softmmu/main.c:49:5
> >   1109 15:16:20.312968 #12 0x7f464de1d8d2 in __libc_start_main
> (/usr/grte/v5/lib64/libc.so.6+0x628d2)
> >   1109 15:16:20.312969 #13 0x5639b6bbd389 in _start
> /usr/grte/v5/debug-src/src/csu/../sysdeps/x86_64/start.S:120
> >   1109 15:16:20.312970
> >   1109 15:16:20.312975   Uninitialized value was stored to memory at
> >   1109 15:16:20.313393 #0 0x5639b88acbee in tap_probe_vnet_hdr_len
> third_party/qemu/net/tap-linux.c
> >   1109 15:16:20.313396 #1 0x5639b88afd66 in net_tap_fd_init
> third_party/qemu/net/tap.c:409:9
> >   1109 15:16:20.313398 #2 0x5639b88b2d1b in net_init_tap_one
> third_party/qemu/net/tap.c:681:19
> >   1109 15:16:20.313399 #3 0x5639b88b16a8 in net_init_tap
> third_party/qemu/net/tap.c:912:13
> >   1109 15:16:20.313400 #4 0x5639b8890175 in net_client_init1
> third_party/qemu/net/net.c:1110:9
> >   1109 15:16:20.313401 #5 0x5639b888f912 in net_client_init
> third_party/qemu/net/net.c:1208:15
> >   1109 15:16:20.313403 #6 0x5639b8894aa5 in net_param_nic
> third_party/qemu/net/net.c:1588:11
> >   1109 15:16:20.313404 #7 0x5639b900cd18 in qemu_opts_foreach
> third_party/qemu/util/qemu-option.c:1135:14
> >   1109 15:16:20.313405 #8 0x5639b889393c in net_init_clients
> third_party/qemu/net/net.c:1612:9
> >   1109 15:16:20.313407 #9 0x5639b717aaf3 in
> qemu_create_late_backends third_party/qemu/softmmu/vl.c:1962:5
> >   1109 15:16:20.313408 #10 0x5639b717aaf3 in qemu_init
> third_party/qemu/softmmu/vl.c:3694:5
> >   1109 15:16:20.313409 #11 0x5639b71083b8 in main
> third_party/qemu/softmmu/main.c:49:5
> >   1109 15:16:20.313410 #12 0x7f464de1d8d2 in __libc_start_main
> (/usr/grte/v5/lib64/libc.so.6+0x628d2)
> >   1109 15:16:20.313412 #13 0x5639b6bbd389 in _start
> /usr/grte/v5/debug-src/src/csu/../sysdeps/x86_64/start.S:120
> >   1109 15:16:20.313413
> >   1109 15:16:20.313417   Uninitialized value was stored to memory at
> >   1109 15:16:20.313791 #0 0x5639b88affbd in net_tap_fd_init
> third_party/qemu/net/tap.c:400:26
> >   1109 15:16:20.313826 #1 0x5639b88b2d1b in net_init_tap_one
> third_party/qemu/net/tap.c:681:19
> >   1109 15:16:20.313829 #2 0x5639b88b16a8 in net_init_tap
> third_party/qemu/net/tap.c:912:13
> >   1109 15:16:20.313831 #3 0x5639b8890175 in net_client_init1
> third_party/qemu/net/net.c:1110:9
> >   1109 15:16:20.313836 #4 0x5639b888f912 in net_client_init
> third_party/qemu/net/net.c:1208:15
> >   1109 15:16:20.313838 #5 0x5639b8894aa5 in net_param_nic
> third_party/qemu/net/net.c:1588:11
> >   1109 15:16:20.313839 #6 0x5639b900cd18 in qemu_opts_foreach
> third_party/qemu/util/qemu-option.c:1135:14
> >   1109 15:16:20.313841 #7 0x5639b889393c in net_init_clients
> third_party/qemu/net/net.c:1612:9
> >   1109 15:16:20.313843 #8 0x5639b717aaf3 in
> qemu_create_late_backends third_party/qemu/softmmu/vl.c:1962:5
> >   1109 15:16:20.313844 #9 0x5639b717aaf3 in qemu_init
> third_party/qemu/softmmu/vl.c:3694:5
> >   1109 15:16:20.313845 #10 0x5639b71083b8 in main
> third_party/qemu/softmmu/main.c:49:5
> >   1109 15:16:20.313846 #11 0x7f464de1d8d2 in __libc_start_main
> (/usr/grte/v5/lib64/libc.so.6+0x628d2)
> >   1109 15:16:20.313847 #12 0x5639b6bbd389 in _start
> 

[PATCH v8 05/18] target/riscv: separation of bitwise logic and arithmetic helpers

2022-01-06 Thread Frédéric Pétrot
Introduction of a gen_logic function for bitwise logic to implement
instructions in which no propagation of information occurs between bits and
use of this function on the bitwise instructions.

Signed-off-by: Frédéric Pétrot 
Co-authored-by: Fabien Portas 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/translate.c| 27 +
 target/riscv/insn_trans/trans_rvb.c.inc |  6 +++---
 target/riscv/insn_trans/trans_rvi.c.inc | 12 +--
 3 files changed, 36 insertions(+), 9 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 502bf0d009..c3b4950ad0 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -475,6 +475,33 @@ static int ex_rvc_shifti(DisasContext *ctx, int imm)
 /* Include the auto-generated decoder for 32 bit insn */
 #include "decode-insn32.c.inc"
 
+static bool gen_logic_imm_fn(DisasContext *ctx, arg_i *a,
+ void (*func)(TCGv, TCGv, target_long))
+{
+TCGv dest = dest_gpr(ctx, a->rd);
+TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
+
+func(dest, src1, a->imm);
+
+gen_set_gpr(ctx, a->rd, dest);
+
+return true;
+}
+
+static bool gen_logic(DisasContext *ctx, arg_r *a,
+  void (*func)(TCGv, TCGv, TCGv))
+{
+TCGv dest = dest_gpr(ctx, a->rd);
+TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
+TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
+
+func(dest, src1, src2);
+
+gen_set_gpr(ctx, a->rd, dest);
+
+return true;
+}
+
 static bool gen_arith_imm_fn(DisasContext *ctx, arg_i *a, DisasExtend ext,
  void (*func)(TCGv, TCGv, target_long))
 {
diff --git a/target/riscv/insn_trans/trans_rvb.c.inc 
b/target/riscv/insn_trans/trans_rvb.c.inc
index c8d31907c5..de2cd613b1 100644
--- a/target/riscv/insn_trans/trans_rvb.c.inc
+++ b/target/riscv/insn_trans/trans_rvb.c.inc
@@ -86,19 +86,19 @@ static bool trans_cpop(DisasContext *ctx, arg_cpop *a)
 static bool trans_andn(DisasContext *ctx, arg_andn *a)
 {
 REQUIRE_ZBB(ctx);
-return gen_arith(ctx, a, EXT_NONE, tcg_gen_andc_tl);
+return gen_logic(ctx, a, tcg_gen_andc_tl);
 }
 
 static bool trans_orn(DisasContext *ctx, arg_orn *a)
 {
 REQUIRE_ZBB(ctx);
-return gen_arith(ctx, a, EXT_NONE, tcg_gen_orc_tl);
+return gen_logic(ctx, a, tcg_gen_orc_tl);
 }
 
 static bool trans_xnor(DisasContext *ctx, arg_xnor *a)
 {
 REQUIRE_ZBB(ctx);
-return gen_arith(ctx, a, EXT_NONE, tcg_gen_eqv_tl);
+return gen_logic(ctx, a, tcg_gen_eqv_tl);
 }
 
 static bool trans_min(DisasContext *ctx, arg_min *a)
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc 
b/target/riscv/insn_trans/trans_rvi.c.inc
index 4a2aefe3a5..51607b3d40 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -252,17 +252,17 @@ static bool trans_sltiu(DisasContext *ctx, arg_sltiu *a)
 
 static bool trans_xori(DisasContext *ctx, arg_xori *a)
 {
-return gen_arith_imm_fn(ctx, a, EXT_NONE, tcg_gen_xori_tl);
+return gen_logic_imm_fn(ctx, a, tcg_gen_xori_tl);
 }
 
 static bool trans_ori(DisasContext *ctx, arg_ori *a)
 {
-return gen_arith_imm_fn(ctx, a, EXT_NONE, tcg_gen_ori_tl);
+return gen_logic_imm_fn(ctx, a, tcg_gen_ori_tl);
 }
 
 static bool trans_andi(DisasContext *ctx, arg_andi *a)
 {
-return gen_arith_imm_fn(ctx, a, EXT_NONE, tcg_gen_andi_tl);
+return gen_logic_imm_fn(ctx, a, tcg_gen_andi_tl);
 }
 
 static bool trans_slli(DisasContext *ctx, arg_slli *a)
@@ -319,7 +319,7 @@ static bool trans_sltu(DisasContext *ctx, arg_sltu *a)
 
 static bool trans_xor(DisasContext *ctx, arg_xor *a)
 {
-return gen_arith(ctx, a, EXT_NONE, tcg_gen_xor_tl);
+return gen_logic(ctx, a, tcg_gen_xor_tl);
 }
 
 static bool trans_srl(DisasContext *ctx, arg_srl *a)
@@ -334,12 +334,12 @@ static bool trans_sra(DisasContext *ctx, arg_sra *a)
 
 static bool trans_or(DisasContext *ctx, arg_or *a)
 {
-return gen_arith(ctx, a, EXT_NONE, tcg_gen_or_tl);
+return gen_logic(ctx, a, tcg_gen_or_tl);
 }
 
 static bool trans_and(DisasContext *ctx, arg_and *a)
 {
-return gen_arith(ctx, a, EXT_NONE, tcg_gen_and_tl);
+return gen_logic(ctx, a, tcg_gen_and_tl);
 }
 
 static bool trans_addiw(DisasContext *ctx, arg_addiw *a)
-- 
2.34.1




[PATCH v8 10/18] target/riscv: support for 128-bit bitwise instructions

2022-01-06 Thread Frédéric Pétrot
The 128-bit bitwise instructions do not need any function prototype change
as the functions can be applied independently on the lower and upper part of
the registers.

Signed-off-by: Frédéric Pétrot 
Co-authored-by: Fabien Portas 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/translate.c | 21 +++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index d4cf965c9e..b43efc9bc3 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -523,7 +523,15 @@ static bool gen_logic_imm_fn(DisasContext *ctx, arg_i *a,
 
 func(dest, src1, a->imm);
 
-gen_set_gpr(ctx, a->rd, dest);
+if (get_xl(ctx) == MXL_RV128) {
+TCGv src1h = get_gprh(ctx, a->rs1);
+TCGv desth = dest_gprh(ctx, a->rd);
+
+func(desth, src1h, -(a->imm < 0));
+gen_set_gpr128(ctx, a->rd, dest, desth);
+} else {
+gen_set_gpr(ctx, a->rd, dest);
+}
 
 return true;
 }
@@ -537,7 +545,16 @@ static bool gen_logic(DisasContext *ctx, arg_r *a,
 
 func(dest, src1, src2);
 
-gen_set_gpr(ctx, a->rd, dest);
+if (get_xl(ctx) == MXL_RV128) {
+TCGv src1h = get_gprh(ctx, a->rs1);
+TCGv src2h = get_gprh(ctx, a->rs2);
+TCGv desth = dest_gprh(ctx, a->rd);
+
+func(desth, src1h, src2h);
+gen_set_gpr128(ctx, a->rd, dest, desth);
+} else {
+gen_set_gpr(ctx, a->rd, dest);
+}
 
 return true;
 }
-- 
2.34.1




[PATCH v8 06/18] target/riscv: array for the 64 upper bits of 128-bit registers

2022-01-06 Thread Frédéric Pétrot
The upper 64-bit of the 128-bit registers have now a place inside
the cpu state structure, and are created as globals for future use.

Signed-off-by: Frédéric Pétrot 
Co-authored-by: Fabien Portas 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.h   |  2 ++
 target/riscv/cpu.c   |  9 +
 target/riscv/machine.c   | 20 
 target/riscv/translate.c |  5 -
 4 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index dc10f27093..fa5d238530 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -112,6 +112,7 @@ FIELD(VTYPE, VILL, sizeof(target_ulong) * 8 - 1, 1)
 
 struct CPURISCVState {
 target_ulong gpr[32];
+target_ulong gprh[32]; /* 64 top bits of the 128-bit registers */
 uint64_t fpr[32]; /* assume both F and D extensions */
 
 /* vector coprocessor state. */
@@ -344,6 +345,7 @@ static inline bool riscv_feature(CPURISCVState *env, int 
feature)
 #include "cpu_user.h"
 
 extern const char * const riscv_int_regnames[];
+extern const char * const riscv_int_regnamesh[];
 extern const char * const riscv_fpr_regnames[];
 
 const char *riscv_cpu_get_trap_name(target_ulong cause, bool async);
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 29749e834f..7b8197db98 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -42,6 +42,15 @@ const char * const riscv_int_regnames[] = {
   "x28/t3",  "x29/t4", "x30/t5", "x31/t6"
 };
 
+const char * const riscv_int_regnamesh[] = {
+  "x0h/zeroh", "x1h/rah",  "x2h/sph",   "x3h/gph",   "x4h/tph",  "x5h/t0h",
+  "x6h/t1h",   "x7h/t2h",  "x8h/s0h",   "x9h/s1h",   "x10h/a0h", "x11h/a1h",
+  "x12h/a2h",  "x13h/a3h", "x14h/a4h",  "x15h/a5h",  "x16h/a6h", "x17h/a7h",
+  "x18h/s2h",  "x19h/s3h", "x20h/s4h",  "x21h/s5h",  "x22h/s6h", "x23h/s7h",
+  "x24h/s8h",  "x25h/s9h", "x26h/s10h", "x27h/s11h", "x28h/t3h", "x29h/t4h",
+  "x30h/t5h",  "x31h/t6h"
+};
+
 const char * const riscv_fpr_regnames[] = {
   "f0/ft0",   "f1/ft1",  "f2/ft2",   "f3/ft3",   "f4/ft4",  "f5/ft5",
   "f6/ft6",   "f7/ft7",  "f8/fs0",   "f9/fs1",   "f10/fa0", "f11/fa1",
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index ad8248ebfd..8af9caabf5 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -164,6 +164,25 @@ static const VMStateDescription vmstate_pointermasking = {
 }
 };
 
+static bool rv128_needed(void *opaque)
+{
+RISCVCPU *cpu = opaque;
+CPURISCVState *env = >env;
+
+return env->misa_mxl_max == MXL_RV128;
+}
+
+static const VMStateDescription vmstate_rv128 = {
+.name = "cpu/rv128",
+.version_id = 1,
+.minimum_version_id = 1,
+.needed = rv128_needed,
+.fields = (VMStateField[]) {
+VMSTATE_UINTTL_ARRAY(env.gprh, RISCVCPU, 32),
+VMSTATE_END_OF_LIST()
+}
+};
+
 const VMStateDescription vmstate_riscv_cpu = {
 .name = "cpu",
 .version_id = 3,
@@ -218,6 +237,7 @@ const VMStateDescription vmstate_riscv_cpu = {
 _hyper,
 _vector,
 _pointermasking,
+_rv128,
 NULL
 }
 };
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index c3b4950ad0..6c400e8452 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -33,7 +33,7 @@
 #include "internals.h"
 
 /* global register indices */
-static TCGv cpu_gpr[32], cpu_pc, cpu_vl, cpu_vstart;
+static TCGv cpu_gpr[32], cpu_gprh[32], cpu_pc, cpu_vl, cpu_vstart;
 static TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */
 static TCGv load_res;
 static TCGv load_val;
@@ -858,10 +858,13 @@ void riscv_translate_init(void)
  * unless you specifically block reads/writes to reg 0.
  */
 cpu_gpr[0] = NULL;
+cpu_gprh[0] = NULL;
 
 for (i = 1; i < 32; i++) {
 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
 offsetof(CPURISCVState, gpr[i]), riscv_int_regnames[i]);
+cpu_gprh[i] = tcg_global_mem_new(cpu_env,
+offsetof(CPURISCVState, gprh[i]), riscv_int_regnamesh[i]);
 }
 
 for (i = 0; i < 32; i++) {
-- 
2.34.1




[PATCH v8 07/18] target/riscv: setup everything for rv64 to support rv128 execution

2022-01-06 Thread Frédéric Pétrot
This patch adds the support of the '-cpu rv128' option to
qemu-system-riscv64 so that we can indicate that we want to run rv128
executables.
Still, there is no support for 128-bit insns at that stage so qemu fails
miserably (as expected) if launched with this option.

Signed-off-by: Frédéric Pétrot 
Co-authored-by: Fabien Portas 
Reviewed-by: Alistair Francis 
---
 include/disas/dis-asm.h |  1 +
 target/riscv/cpu.h  |  1 +
 disas/riscv.c   |  5 +
 target/riscv/cpu.c  | 20 
 target/riscv/gdbstub.c  |  5 +
 5 files changed, 32 insertions(+)

diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h
index 08e1beec85..102a1e7f50 100644
--- a/include/disas/dis-asm.h
+++ b/include/disas/dis-asm.h
@@ -459,6 +459,7 @@ int print_insn_nios2(bfd_vma, disassemble_info*);
 int print_insn_xtensa   (bfd_vma, disassemble_info*);
 int print_insn_riscv32  (bfd_vma, disassemble_info*);
 int print_insn_riscv64  (bfd_vma, disassemble_info*);
+int print_insn_riscv128 (bfd_vma, disassemble_info*);
 int print_insn_rx(bfd_vma, disassemble_info *);
 int print_insn_hexagon(bfd_vma, disassemble_info *);
 
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index fa5d238530..efe481f5fb 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -38,6 +38,7 @@
 #define TYPE_RISCV_CPU_ANY  RISCV_CPU_TYPE_NAME("any")
 #define TYPE_RISCV_CPU_BASE32   RISCV_CPU_TYPE_NAME("rv32")
 #define TYPE_RISCV_CPU_BASE64   RISCV_CPU_TYPE_NAME("rv64")
+#define TYPE_RISCV_CPU_BASE128  RISCV_CPU_TYPE_NAME("rv128")
 #define TYPE_RISCV_CPU_IBEX RISCV_CPU_TYPE_NAME("lowrisc-ibex")
 #define TYPE_RISCV_CPU_SHAKTI_C RISCV_CPU_TYPE_NAME("shakti-c")
 #define TYPE_RISCV_CPU_SIFIVE_E31   RISCV_CPU_TYPE_NAME("sifive-e31")
diff --git a/disas/riscv.c b/disas/riscv.c
index 793ad14c27..03c8dc9961 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -3090,3 +3090,8 @@ int print_insn_riscv64(bfd_vma memaddr, struct 
disassemble_info *info)
 {
 return print_insn_riscv(memaddr, info, rv64);
 }
+
+int print_insn_riscv128(bfd_vma memaddr, struct disassemble_info *info)
+{
+return print_insn_riscv(memaddr, info, rv128);
+}
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7b8197db98..e3ba53d4d2 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -178,6 +178,19 @@ static void rv64_sifive_e_cpu_init(Object *obj)
 set_priv_version(env, PRIV_VERSION_1_10_0);
 qdev_prop_set_bit(DEVICE(obj), "mmu", false);
 }
+
+static void rv128_base_cpu_init(Object *obj)
+{
+if (qemu_tcg_mttcg_enabled()) {
+/* Missing 128-bit aligned atomics */
+error_report("128-bit RISC-V currently does not work with Multi "
+ "Threaded TCG. Please use: -accel tcg,thread=single");
+exit(EXIT_FAILURE);
+}
+CPURISCVState *env = _CPU(obj)->env;
+/* We set this in the realise function */
+set_misa(env, MXL_RV128, 0);
+}
 #else
 static void rv32_base_cpu_init(Object *obj)
 {
@@ -402,6 +415,9 @@ static void riscv_cpu_disas_set_info(CPUState *s, 
disassemble_info *info)
 case MXL_RV64:
 info->print_insn = print_insn_riscv64;
 break;
+case MXL_RV128:
+info->print_insn = print_insn_riscv128;
+break;
 default:
 g_assert_not_reached();
 }
@@ -464,6 +480,8 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 #ifdef TARGET_RISCV64
 case MXL_RV64:
 break;
+case MXL_RV128:
+break;
 #endif
 case MXL_RV32:
 break;
@@ -672,6 +690,7 @@ static gchar *riscv_gdb_arch_name(CPUState *cs)
 case MXL_RV32:
 return g_strdup("riscv:rv32");
 case MXL_RV64:
+case MXL_RV128:
 return g_strdup("riscv:rv64");
 default:
 g_assert_not_reached();
@@ -826,6 +845,7 @@ static const TypeInfo riscv_cpu_type_infos[] = {
 DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51,   rv64_sifive_e_cpu_init),
 DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54,   rv64_sifive_u_cpu_init),
 DEFINE_CPU(TYPE_RISCV_CPU_SHAKTI_C, rv64_sifive_u_cpu_init),
+DEFINE_CPU(TYPE_RISCV_CPU_BASE128,  rv128_base_cpu_init),
 #endif
 };
 
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index 881ab33392..a5429b92d4 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -280,6 +280,11 @@ static int riscv_gen_dynamic_csr_xml(CPUState *cs, int 
base_reg)
 int bitsize = 16 << env->misa_mxl_max;
 int i;
 
+/* Until gdb knows about 128-bit registers */
+if (bitsize > 64) {
+bitsize = 64;
+}
+
 g_string_printf(s, "");
 g_string_append_printf(s, "");
 g_string_append_printf(s, "");
-- 
2.34.1




[PATCH v8 04/18] target/riscv: additional macros to check instruction support

2022-01-06 Thread Frédéric Pétrot
Given that the 128-bit version of the riscv spec adds new instructions, and
that some instructions that were previously only available in 64-bit mode
are now available for both 64-bit and 128-bit, we added new macros to check
for the processor mode during translation.
Although RV128 is a superset of RV64, we keep for now the RV64 only tests
for extensions other than RVI and RVM.

Signed-off-by: Frédéric Pétrot 
Co-authored-by: Fabien Portas 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/translate.c | 20 
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 5df6c0d800..502bf0d009 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -443,10 +443,22 @@ EX_SH(12)
 }  \
 } while (0)
 
-#define REQUIRE_64BIT(ctx) do {\
-if (get_xl(ctx) < MXL_RV64) {  \
-return false;  \
-}  \
+#define REQUIRE_64BIT(ctx) do { \
+if (get_xl(ctx) != MXL_RV64) {  \
+return false;   \
+}   \
+} while (0)
+
+#define REQUIRE_128BIT(ctx) do {\
+if (get_xl(ctx) != MXL_RV128) { \
+return false;   \
+}   \
+} while (0)
+
+#define REQUIRE_64_OR_128BIT(ctx) do { \
+if (get_xl(ctx) == MXL_RV32) { \
+return false;  \
+}  \
 } while (0)
 
 static int ex_rvc_register(DisasContext *ctx, int reg)
-- 
2.34.1




[PATCH v8 08/18] target/riscv: moving some insns close to similar insns

2022-01-06 Thread Frédéric Pétrot
lwu and ld are functionally close to the other loads, but were after the
stores in the source file.
Similarly, xor was away from or and and by two arithmetic functions, while
the immediate versions were nicely put together.
This patch moves the aforementioned loads after lhu, and xor above or,
where they more logically belong.

Signed-off-by: Frédéric Pétrot 
Co-authored-by: Fabien Portas 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rvi.c.inc | 34 -
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.c.inc 
b/target/riscv/insn_trans/trans_rvi.c.inc
index 51607b3d40..710f5e6a85 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -176,6 +176,18 @@ static bool trans_lhu(DisasContext *ctx, arg_lhu *a)
 return gen_load(ctx, a, MO_TEUW);
 }
 
+static bool trans_lwu(DisasContext *ctx, arg_lwu *a)
+{
+REQUIRE_64BIT(ctx);
+return gen_load(ctx, a, MO_TEUL);
+}
+
+static bool trans_ld(DisasContext *ctx, arg_ld *a)
+{
+REQUIRE_64BIT(ctx);
+return gen_load(ctx, a, MO_TEUQ);
+}
+
 static bool gen_store(DisasContext *ctx, arg_sb *a, MemOp memop)
 {
 TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
@@ -207,18 +219,6 @@ static bool trans_sw(DisasContext *ctx, arg_sw *a)
 return gen_store(ctx, a, MO_TESL);
 }
 
-static bool trans_lwu(DisasContext *ctx, arg_lwu *a)
-{
-REQUIRE_64BIT(ctx);
-return gen_load(ctx, a, MO_TEUL);
-}
-
-static bool trans_ld(DisasContext *ctx, arg_ld *a)
-{
-REQUIRE_64BIT(ctx);
-return gen_load(ctx, a, MO_TEUQ);
-}
-
 static bool trans_sd(DisasContext *ctx, arg_sd *a)
 {
 REQUIRE_64BIT(ctx);
@@ -317,11 +317,6 @@ static bool trans_sltu(DisasContext *ctx, arg_sltu *a)
 return gen_arith(ctx, a, EXT_SIGN, gen_sltu);
 }
 
-static bool trans_xor(DisasContext *ctx, arg_xor *a)
-{
-return gen_logic(ctx, a, tcg_gen_xor_tl);
-}
-
 static bool trans_srl(DisasContext *ctx, arg_srl *a)
 {
 return gen_shift(ctx, a, EXT_ZERO, tcg_gen_shr_tl);
@@ -332,6 +327,11 @@ static bool trans_sra(DisasContext *ctx, arg_sra *a)
 return gen_shift(ctx, a, EXT_SIGN, tcg_gen_sar_tl);
 }
 
+static bool trans_xor(DisasContext *ctx, arg_xor *a)
+{
+return gen_logic(ctx, a, tcg_gen_xor_tl);
+}
+
 static bool trans_or(DisasContext *ctx, arg_or *a)
 {
 return gen_logic(ctx, a, tcg_gen_or_tl);
-- 
2.34.1




[PATCH v8 01/18] exec/memop: Adding signedness to quad definitions

2022-01-06 Thread Frédéric Pétrot
Renaming defines for quad in their various forms so that their signedness is
now explicit.
Done using git grep as suggested by Philippe, with a bit of hand edition to
keep assignments aligned.

Signed-off-by: Frédéric Pétrot 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 include/exec/memop.h   |  8 +--
 include/tcg/tcg-op.h   |  4 +-
 target/arm/translate-a32.h |  4 +-
 accel/tcg/cputlb.c | 30 +--
 accel/tcg/user-exec.c  |  8 +--
 target/alpha/translate.c   | 32 ++--
 target/arm/helper-a64.c|  8 +--
 target/arm/translate-a64.c |  8 +--
 target/arm/translate-neon.c|  6 +--
 target/arm/translate-sve.c | 10 ++--
 target/arm/translate-vfp.c |  8 +--
 target/arm/translate.c |  2 +-
 target/cris/translate.c|  2 +-
 target/hppa/translate.c|  4 +-
 target/i386/tcg/mem_helper.c   |  2 +-
 target/i386/tcg/translate.c| 36 +++---
 target/m68k/op_helper.c|  2 +-
 target/mips/tcg/translate.c| 58 +++---
 target/mips/tcg/tx79_translate.c   |  8 +--
 target/ppc/translate.c | 32 ++--
 target/s390x/tcg/mem_helper.c  |  8 +--
 target/s390x/tcg/translate.c   |  8 +--
 target/sh4/translate.c | 12 ++---
 target/sparc/translate.c   | 36 +++---
 target/tricore/translate.c |  4 +-
 target/xtensa/translate.c  |  4 +-
 tcg/tcg.c  |  4 +-
 tcg/tci.c  | 16 +++---
 accel/tcg/ldst_common.c.inc|  8 +--
 target/mips/tcg/micromips_translate.c.inc  | 10 ++--
 target/ppc/translate/fixedpoint-impl.c.inc | 22 
 target/ppc/translate/fp-impl.c.inc |  4 +-
 target/ppc/translate/vsx-impl.c.inc| 42 
 target/riscv/insn_trans/trans_rva.c.inc| 22 
 target/riscv/insn_trans/trans_rvd.c.inc|  4 +-
 target/riscv/insn_trans/trans_rvh.c.inc|  4 +-
 target/riscv/insn_trans/trans_rvi.c.inc|  4 +-
 target/s390x/tcg/translate_vx.c.inc| 18 +++
 tcg/aarch64/tcg-target.c.inc   |  2 +-
 tcg/arm/tcg-target.c.inc   | 10 ++--
 tcg/i386/tcg-target.c.inc  | 12 ++---
 tcg/mips/tcg-target.c.inc  | 12 ++---
 tcg/ppc/tcg-target.c.inc   | 16 +++---
 tcg/riscv/tcg-target.c.inc |  6 +--
 tcg/s390x/tcg-target.c.inc | 18 +++
 tcg/sparc/tcg-target.c.inc | 16 +++---
 target/s390x/tcg/insn-data.def | 28 +--
 47 files changed, 311 insertions(+), 311 deletions(-)

diff --git a/include/exec/memop.h b/include/exec/memop.h
index 04264ffd6b..72c2f0ff3d 100644
--- a/include/exec/memop.h
+++ b/include/exec/memop.h
@@ -85,29 +85,29 @@ typedef enum MemOp {
 MO_UB= MO_8,
 MO_UW= MO_16,
 MO_UL= MO_32,
+MO_UQ= MO_64,
 MO_SB= MO_SIGN | MO_8,
 MO_SW= MO_SIGN | MO_16,
 MO_SL= MO_SIGN | MO_32,
-MO_Q = MO_64,
 
 MO_LEUW  = MO_LE | MO_UW,
 MO_LEUL  = MO_LE | MO_UL,
+MO_LEUQ  = MO_LE | MO_UQ,
 MO_LESW  = MO_LE | MO_SW,
 MO_LESL  = MO_LE | MO_SL,
-MO_LEQ   = MO_LE | MO_Q,
 
 MO_BEUW  = MO_BE | MO_UW,
 MO_BEUL  = MO_BE | MO_UL,
+MO_BEUQ  = MO_BE | MO_UQ,
 MO_BESW  = MO_BE | MO_SW,
 MO_BESL  = MO_BE | MO_SL,
-MO_BEQ   = MO_BE | MO_Q,
 
 #ifdef NEED_CPU_H
 MO_TEUW  = MO_TE | MO_UW,
 MO_TEUL  = MO_TE | MO_UL,
+MO_TEUQ  = MO_TE | MO_UQ,
 MO_TESW  = MO_TE | MO_SW,
 MO_TESL  = MO_TE | MO_SL,
-MO_TEQ   = MO_TE | MO_Q,
 #endif
 
 MO_SSIZE = MO_SIZE | MO_SIGN,
diff --git a/include/tcg/tcg-op.h b/include/tcg/tcg-op.h
index 0545a6224c..caa0a63612 100644
--- a/include/tcg/tcg-op.h
+++ b/include/tcg/tcg-op.h
@@ -894,7 +894,7 @@ static inline void tcg_gen_qemu_ld32s(TCGv ret, TCGv addr, 
int mem_index)
 
 static inline void tcg_gen_qemu_ld64(TCGv_i64 ret, TCGv addr, int mem_index)
 {
-tcg_gen_qemu_ld_i64(ret, addr, mem_index, MO_TEQ);
+tcg_gen_qemu_ld_i64(ret, addr, mem_index, MO_TEUQ);
 }
 
 static inline void tcg_gen_qemu_st8(TCGv arg, TCGv addr, int mem_index)
@@ -914,7 +914,7 @@ static inline void tcg_gen_qemu_st32(TCGv arg, TCGv addr, 
int mem_index)
 
 static inline void tcg_gen_qemu_st64(TCGv_i64 arg, TCGv addr, int mem_index)
 {
-tcg_gen_qemu_st_i64(arg, addr, mem_index, MO_TEQ);
+tcg_gen_qemu_st_i64(arg, addr, mem_index, MO_TEUQ);
 }
 
 void tcg_gen_atomic_cmpxchg_i32(TCGv_i32, TCGv, TCGv_i32, TCGv_i32,
diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
index 17af8dc95a..5be4b9b834 100644

[PATCH v8 03/18] qemu/int128: addition of div/rem 128-bit operations

2022-01-06 Thread Frédéric Pétrot
Addition of div and rem on 128-bit integers, using the 128/64->128 divu and
64x64->128 mulu in host-utils.
These operations will be used within div/rem helpers in the 128-bit riscv
target.

Signed-off-by: Frédéric Pétrot 
Co-authored-by: Fabien Portas 
Reviewed-by: Alistair Francis 
---
 include/qemu/int128.h |  27 
 util/int128.c | 147 ++
 util/meson.build  |   1 +
 3 files changed, 175 insertions(+)
 create mode 100644 util/int128.c

diff --git a/include/qemu/int128.h b/include/qemu/int128.h
index b6d517aea4..2c4064256c 100644
--- a/include/qemu/int128.h
+++ b/include/qemu/int128.h
@@ -172,6 +172,26 @@ static inline Int128 bswap128(Int128 a)
 #endif
 }
 
+static inline Int128 int128_divu(Int128 a, Int128 b)
+{
+return (__uint128_t)a / (__uint128_t)b;
+}
+
+static inline Int128 int128_remu(Int128 a, Int128 b)
+{
+return (__uint128_t)a % (__uint128_t)b;
+}
+
+static inline Int128 int128_divs(Int128 a, Int128 b)
+{
+return a / b;
+}
+
+static inline Int128 int128_rems(Int128 a, Int128 b)
+{
+return a % b;
+}
+
 #else /* !CONFIG_INT128 */
 
 typedef struct Int128 Int128;
@@ -379,6 +399,11 @@ static inline Int128 bswap128(Int128 a)
 return int128_make128(bswap64(a.hi), bswap64(a.lo));
 }
 
+Int128 int128_divu(Int128, Int128);
+Int128 int128_remu(Int128, Int128);
+Int128 int128_divs(Int128, Int128);
+Int128 int128_rems(Int128, Int128);
+
 #endif /* CONFIG_INT128 */
 
 static inline void bswap128s(Int128 *s)
@@ -386,4 +411,6 @@ static inline void bswap128s(Int128 *s)
 *s = bswap128(*s);
 }
 
+#define UINT128_MAX int128_make128(~0LL, ~0LL)
+
 #endif /* INT128_H */
diff --git a/util/int128.c b/util/int128.c
new file mode 100644
index 00..ed8f25fef1
--- /dev/null
+++ b/util/int128.c
@@ -0,0 +1,147 @@
+/*
+ * 128-bit division and remainder for compilers not supporting __int128
+ *
+ * Copyright (c) 2021 Frédéric Pétrot 
+ *
+ * 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 "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/host-utils.h"
+#include "qemu/int128.h"
+
+#ifndef CONFIG_INT128
+
+/*
+ * Division and remainder algorithms for 128-bit due to Stefan Kanthak,
+ * https://skanthak.homepage.t-online.de/integer.html#udivmodti4
+ * Preconditions:
+ * - function should never be called with v equals to 0, it has to
+ *   be dealt with beforehand
+ * - quotien pointer must be valid
+ */
+static Int128 divrem128(Int128 u, Int128 v, Int128 *q)
+{
+Int128 qq;
+uint64_t hi, lo, tmp;
+int s = clz64(v.hi);
+
+if (s == 64) {
+/* we have uu÷0v => let's use divu128 */
+hi = u.hi;
+lo = u.lo;
+tmp = divu128(, , v.lo);
+*q = int128_make128(lo, hi);
+return int128_make128(tmp, 0);
+} else {
+hi = int128_gethi(int128_lshift(v, s));
+
+if (hi > u.hi) {
+lo = u.lo;
+tmp = u.hi;
+divu128(, , hi);
+lo = int128_gethi(int128_lshift(int128_make128(lo, 0), s));
+} else { /* prevent overflow */
+lo = u.lo;
+tmp = u.hi - hi;
+divu128(, , hi);
+lo = int128_gethi(int128_lshift(int128_make128(lo, 1), s));
+}
+
+qq = int128_make64(lo);
+
+tmp = lo * v.hi;
+mulu64(, , lo, v.lo);
+hi += tmp;
+
+if (hi < tmp /* quotient * divisor >= 2**128 > dividend */
+|| hi > u.hi /* quotient * divisor > dividend */
+|| (hi == u.hi && lo > u.lo)) {
+qq.lo -= 1;
+mulu64(, , qq.lo, v.lo);
+hi += qq.lo * v.hi;
+}
+
+*q = qq;
+u.hi -= hi + (u.lo < lo);
+u.lo -= lo;
+return u;
+}
+}
+
+Int128 int128_divu(Int128 a, Int128 b)
+{
+Int128 q;
+divrem128(a, b, );
+return q;
+}
+
+Int128 int128_remu(Int128 a, Int128 b)
+{
+Int128 q;
+return divrem128(a, b, );
+}
+
+Int128 int128_divs(Int128 a, 

[PATCH v8 02/18] exec/memop: Adding signed quad and octo defines

2022-01-06 Thread Frédéric Pétrot
Adding defines to handle signed 64-bit and unsigned 128-bit quantities in
memory accesses.

Signed-off-by: Frédéric Pétrot 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 include/exec/memop.h | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/include/exec/memop.h b/include/exec/memop.h
index 72c2f0ff3d..2a885f3917 100644
--- a/include/exec/memop.h
+++ b/include/exec/memop.h
@@ -86,28 +86,35 @@ typedef enum MemOp {
 MO_UW= MO_16,
 MO_UL= MO_32,
 MO_UQ= MO_64,
+MO_UO= MO_128,
 MO_SB= MO_SIGN | MO_8,
 MO_SW= MO_SIGN | MO_16,
 MO_SL= MO_SIGN | MO_32,
+MO_SQ= MO_SIGN | MO_64,
+MO_SO= MO_SIGN | MO_128,
 
 MO_LEUW  = MO_LE | MO_UW,
 MO_LEUL  = MO_LE | MO_UL,
 MO_LEUQ  = MO_LE | MO_UQ,
 MO_LESW  = MO_LE | MO_SW,
 MO_LESL  = MO_LE | MO_SL,
+MO_LESQ  = MO_LE | MO_SQ,
 
 MO_BEUW  = MO_BE | MO_UW,
 MO_BEUL  = MO_BE | MO_UL,
 MO_BEUQ  = MO_BE | MO_UQ,
 MO_BESW  = MO_BE | MO_SW,
 MO_BESL  = MO_BE | MO_SL,
+MO_BESQ  = MO_BE | MO_SQ,
 
 #ifdef NEED_CPU_H
 MO_TEUW  = MO_TE | MO_UW,
 MO_TEUL  = MO_TE | MO_UL,
 MO_TEUQ  = MO_TE | MO_UQ,
+MO_TEUO  = MO_TE | MO_UO,
 MO_TESW  = MO_TE | MO_SW,
 MO_TESL  = MO_TE | MO_SL,
+MO_TESQ  = MO_TE | MO_SQ,
 #endif
 
 MO_SSIZE = MO_SIZE | MO_SIGN,
-- 
2.34.1




[PATCH v8 00/18] Adding partial support for 128-bit riscv target

2022-01-06 Thread Frédéric Pétrot
This series of patches provides partial 128-bit support for the riscv
target architecture, namely RVI and RVM, with minimal csr support.

Thanks for the reviews and advices.

v8:
- rebase on riscv-to-apply.next

v7:
- code motion following reviews
- correction of a bug preventing riscv{32,64}-linux-user to compile
- sync with master
- Note that 'make check' fails for 5 qemu-iotests cases, namely
  040, 041, 127, 256, and 267, but they also fail with
  qemu-system-riscv{32,64} from current master

v6:
- support for '-cpu rv128' in qemu-system-riscv64 to handle 128-bit
  executables (no more qemu-system-riscv128)
- remove useless (and buggy) big-endian support in lq/sq

v5:
- split the memop define renaming and addition in two patches
- 128-bit div/rem operations using host-utils functions
- removed useless rv128 tests at various places
- refactoring the slt/bxx part so as to share the comparison part
- refactoring the 128-bit csr handling to share code more largely
  Also forwarding writes to the 64-bit version when not 128-bit version
  exists, as a vast majority of the csrs does not use the upper 64-bits

v4: 
- safer and cleaner access to the gpr upper part
- locals for load/store/div/rem helpers
- cleans out the 128-bit div/rem code
- corrects numerous bugs and performs optimizations on shifts and mults
- withdraws the change in page size and the vm schemes we introduced

v3:
- v2 refactored following Richard's xl patch changes

v2:
- load and store making use of new memop.h sizes
- use of the existing Int128 computations in helpers, and addition of
  a few more operations there, in particular division and remainder
- refactoring of the calls to the code generation helpers
- split of the patch in smaller pieces

v1:
- introducing support for rv128 for basic integer and M extension insns


Frédéric Pétrot (18):
  exec/memop: Adding signedness to quad definitions
  exec/memop: Adding signed quad and octo defines
  qemu/int128: addition of div/rem 128-bit operations
  target/riscv: additional macros to check instruction support
  target/riscv: separation of bitwise logic and arithmetic helpers
  target/riscv: array for the 64 upper bits of 128-bit registers
  target/riscv: setup everything for rv64 to support rv128 execution
  target/riscv: moving some insns close to similar insns
  target/riscv: accessors to registers upper part and 128-bit load/store
  target/riscv: support for 128-bit bitwise instructions
  target/riscv: support for 128-bit U-type instructions
  target/riscv: support for 128-bit shift instructions
  target/riscv: support for 128-bit arithmetic instructions
  target/riscv: support for 128-bit M extension
  target/riscv: adding high part of some csrs
  target/riscv: helper functions to wrap calls to 128-bit csr insns
  target/riscv: modification of the trans_csrxx for 128-bit support
  target/riscv: actual functions to realize crs 128-bit insns

 include/disas/dis-asm.h|   1 +
 include/exec/memop.h   |  15 +-
 include/qemu/int128.h  |  27 +
 include/tcg/tcg-op.h   |   4 +-
 target/arm/translate-a32.h |   4 +-
 target/riscv/cpu.h |  22 +
 target/riscv/cpu_bits.h|   3 +
 target/riscv/helper.h  |   9 +
 target/riscv/insn16.decode |  27 +-
 target/riscv/insn32.decode |  25 +
 accel/tcg/cputlb.c |  30 +-
 accel/tcg/user-exec.c  |   8 +-
 disas/riscv.c  |   5 +
 target/alpha/translate.c   |  32 +-
 target/arm/helper-a64.c|   8 +-
 target/arm/translate-a64.c |   8 +-
 target/arm/translate-neon.c|   6 +-
 target/arm/translate-sve.c |  10 +-
 target/arm/translate-vfp.c |   8 +-
 target/arm/translate.c |   2 +-
 target/cris/translate.c|   2 +-
 target/hppa/translate.c|   4 +-
 target/i386/tcg/mem_helper.c   |   2 +-
 target/i386/tcg/translate.c|  36 +-
 target/m68k/op_helper.c|   2 +-
 target/mips/tcg/translate.c|  58 +-
 target/mips/tcg/tx79_translate.c   |   8 +-
 target/ppc/translate.c |  32 +-
 target/riscv/cpu.c |  29 +
 target/riscv/csr.c | 194 +-
 target/riscv/gdbstub.c |   5 +
 target/riscv/m128_helper.c | 109 +++
 target/riscv/machine.c |  22 +
 target/riscv/op_helper.c   |  44 ++
 target/riscv/translate.c   | 252 ++-
 target/s390x/tcg/mem_helper.c  |   8 +-
 target/s390x/tcg/translate.c   |   8 +-
 target/sh4/translate.c |  12 +-
 target/sparc/translate.c   |  36 +-
 

  1   2   3   4   >