Re: [PATCH 12/24] bsd-user/arm/target_arch_sigtramp.h: Signal Trampoline for arm

2021-10-25 Thread Kyle Evans
On Tue, Oct 19, 2021 at 11:45 AM Warner Losh  wrote:
>
> Copy of the signal trampoline code for arm, as well as setup_sigtramp to
> write it to the stack.
>
> Signed-off-by: Stacey Son 
> Signed-off-by: Warner Losh 
> ---
>  bsd-user/arm/target_arch_sigtramp.h | 52 +
>  1 file changed, 52 insertions(+)
>  create mode 100644 bsd-user/arm/target_arch_sigtramp.h
>
> diff --git a/bsd-user/arm/target_arch_sigtramp.h 
> b/bsd-user/arm/target_arch_sigtramp.h
> new file mode 100644
> index 00..ed53d336ed
> --- /dev/null
> +++ b/bsd-user/arm/target_arch_sigtramp.h
> @@ -0,0 +1,52 @@
> +/*
> + *  arm sysarch() system call emulation
> + *
> + *  Copyright (c) 2013 Stacey D. Son
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License as published by
> + *  the Free Software Foundation; either version 2 of the License, or
> + *  (at your option) any later version.
> + *
> + *  This program is distributed in the hope that it will be useful,
> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *  GNU General Public License for more details.
> + *
> + *  You should have received a copy of the GNU General Public License
> + *  along with this program; if not, see .
> + */
> +
> +#ifndef _TARGET_ARCH_SIGTRAMP_H_
> +#define _TARGET_ARCH_SIGTRAMP_H_
> +
> +/* Compare to arm/arm/locore.S ENTRY_NP(sigcode) */
> +static inline abi_long setup_sigtramp(abi_ulong offset, unsigned sigf_uc,
> +unsigned sys_sigreturn)
> +{
> +int i;
> +uint32_t sys_exit = TARGET_FREEBSD_NR_exit;
> +/*
> + * The code has to load r7 manually rather than using
> + * "ldr r7, =SYS_return to make sure the size of the
> + * code is correct.
> + */
> +uint32_t sigtramp_code[] = {
> +/* 1 */ 0xE1AD,  /* mov r0, sp */
> +/* 2 */ 0xE280 + sigf_uc,/* add r0, r0, #SIGF_UC */
> +/* 3 */ 0xE59F700C,  /* ldr r7, [pc, #12] */
> +/* 4 */ 0xEF00 + sys_sigreturn,  /* swi (SYS_sigreturn) */
> +/* 5 */ 0xE59F7008,  /* ldr r7, [pc, #8] */
> +/* 6 */ 0xEF00 + sys_exit,   /* swi (SYS_exit)*/
> +/* 7 */ 0xEAFA,  /* b . -16 */
> +/* 8 */ sys_sigreturn,
> +/* 9 */ sys_exit
> +};
> +
> +for (i = 0; i < 9; i++) {
> +tswap32s(_code[i]);
> +}
> +
> +return memcpy_to_target(offset, sigtramp_code, TARGET_SZSIGCODE);
> +}
> +#endif /* _TARGET_ARCH_SIGTRAMP_H_ */
> --
> 2.32.0
>

Reviewed-by: Kyle Evans 



Re: [PATCH 10/24] bsd-user/arm/target_arch_reg.h: Implement core dump register copying

2021-10-25 Thread Kyle Evans
On Tue, Oct 19, 2021 at 11:45 AM Warner Losh  wrote:
>
> Implement the register copying routines to extract registers from the
> cpu for core dump generation.
>
> Signed-off-by: Stacey Son 
> Signed-off-by: Warner Losh 
> ---
>  bsd-user/arm/target_arch_reg.h | 60 ++
>  1 file changed, 60 insertions(+)
>  create mode 100644 bsd-user/arm/target_arch_reg.h
>
> diff --git a/bsd-user/arm/target_arch_reg.h b/bsd-user/arm/target_arch_reg.h
> new file mode 100644
> index 00..ef5ed5154f
> --- /dev/null
> +++ b/bsd-user/arm/target_arch_reg.h
> @@ -0,0 +1,60 @@
> +/*
> + *  FreeBSD arm register structures
> + *
> + *  Copyright (c) 2015 Stacey Son
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License as published by
> + *  the Free Software Foundation; either version 2 of the License, or
> + *  (at your option) any later version.
> + *
> + *  This program is distributed in the hope that it will be useful,
> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *  GNU General Public License for more details.
> + *
> + *  You should have received a copy of the GNU General Public License
> + *  along with this program; if not, see .
> + */
> +
> +#ifndef _TARGET_ARCH_REG_H_
> +#define _TARGET_ARCH_REG_H_
> +
> +/* See sys/arm/include/reg.h */
> +typedef struct target_reg {
> +uint32_tr[13];
> +uint32_tr_sp;
> +uint32_tr_lr;
> +uint32_tr_pc;
> +uint32_tr_cpsr;
> +} target_reg_t;
> +
> +typedef struct target_fp_reg {
> +uint32_tfp_exponent;
> +uint32_tfp_mantissa_hi;
> +u_int32_t   fp_mantissa_lo;
> +} target_fp_reg_t;
> +
> +typedef struct target_fpreg {
> +uint32_tfpr_fpsr;
> +target_fp_reg_t fpr[8];
> +} target_fpreg_t;
> +
> +#define tswapreg(ptr)   tswapal(ptr)
> +
> +static inline void target_copy_regs(target_reg_t *regs, const CPUARMState 
> *env)
> +{
> +int i;
> +
> +for (i = 0; i < 13; i++) {
> +regs->r[i] = tswapreg(env->regs[i + 1]);
> +}
> +regs->r_sp = tswapreg(env->regs[13]);
> +regs->r_lr = tswapreg(env->regs[14]);
> +regs->r_pc = tswapreg(env->regs[15]);
> +regs->r_cpsr = tswapreg(cpsr_read((CPUARMState *)env));
> +}
> +
> +#undef tswapreg
> +
> +#endif /* !_TARGET_ARCH_REG_H_ */
> --
> 2.32.0
>

Reviewed-by: Kyle Evans 



Re: [PATCH 08/24] bsd-user/arm/target_arch_cpu.h: Implement data abort exceptions

2021-10-25 Thread Kyle Evans
On Tue, Oct 19, 2021 at 11:45 AM Warner Losh  wrote:
>
> Implement EXCP_PREFETCH_ABORT AND EXCP_DATA_ABORT. Both of these data
> exceptions cause a SIGSEGV.
>
> Signed-off-by: Klye Evans 
> Signed-off-by: Olivier Houchard 
> Signed-off-by: Stacey Son 
> Signed-off-by: Warner Losh 
> ---
>  bsd-user/arm/target_arch_cpu.h | 11 +++
>  1 file changed, 11 insertions(+)
>
> diff --git a/bsd-user/arm/target_arch_cpu.h b/bsd-user/arm/target_arch_cpu.h
> index f22384676a..62d6ee89b6 100644
> --- a/bsd-user/arm/target_arch_cpu.h
> +++ b/bsd-user/arm/target_arch_cpu.h
> @@ -60,6 +60,17 @@ static inline void target_cpu_loop(CPUARMState *env)
>  case EXCP_INTERRUPT:
>  /* just indicate that signals should be handled asap */
>  break;
> +case EXCP_PREFETCH_ABORT:
> +/* See arm/arm/trap.c prefetch_abort_handler() */
> +case EXCP_DATA_ABORT:
> +/* See arm/arm/trap.c data_abort_handler() */
> +info.si_signo = TARGET_SIGSEGV;
> +info.si_errno = 0;
> +/* XXX: check env->error_code */
> +info.si_code = 0;
> +info.si_addr = env->exception.vaddress;
> +queue_signal(env, info.si_signo, );
> +break;
>  case EXCP_DEBUG:
>  {
>
> --
> 2.32.0
>

Reviewed-by: Kyle Evans 



Re: [PATCH 1/9] qapi: New special feature flag "unstable"

2021-10-25 Thread Markus Armbruster
John Snow  writes:

> On Mon, Oct 25, 2021 at 1:26 AM Markus Armbruster  wrote:
>
>> By convention, names starting with "x-" are experimental.  The parts
>> of external interfaces so named may be withdrawn or changed
>> incompatibly in future releases.
>>
>> Drawback: promoting something from experimental to stable involves a
>> name change.  Client code needs to be updated.
>>
>> Moreover, the convention is not universally observed:
>>
>> * QOM type "input-barrier" has properties "x-origin", "y-origin".
>>   Looks accidental, but it's ABI since 4.2.
>>
>> * QOM types "memory-backend-file", "memory-backend-memfd",
>>   "memory-backend-ram", and "memory-backend-epc" have a property
>>   "x-use-canonical-path-for-ramblock-id" that is documented to be
>>   stable despite its name.
>>
>> We could document these exceptions, but documentation helps only
>> humans.  We want to recognize "unstable" in code, like "deprecated".
>>
>> Replace the convention by a new special feature flag "unstable".  It
>> will be recognized by the QAPI generator, like the existing feature
>> flag "deprecated", and unlike regular feature flags.
>>
>> This commit updates documentation and prepares tests.  The next commit
>> updates the QAPI schema.  The remaining patches update the QAPI
>> generator and wire up -compat policy checking.
>>
>> Signed-off-by: Markus Armbruster 

[...]

> Feels odd to combine the doc update *and* test prep, but eh, whatever.

I admit this is what was left after patch splitting and reshuffling.

> Reviewed-by: John Snow 

Thanks!




Re: [PATCH v3 00/22] QEMU RISC-V AIA support

2021-10-25 Thread Anup Patel
Hi Alistair,

On Sat, Oct 23, 2021 at 2:17 PM Anup Patel  wrote:
>
> The advanced interrupt architecture (AIA) extends the per-HART local
> interrupt support. Along with this, it also adds IMSIC (MSI contrllor)
> and Advanced PLIC (wired interrupt controller).
>
> The latest AIA draft specification can be found here:
> https://github.com/riscv/riscv-aia/releases/download/0.2-draft.27/riscv-interrupts-027.pdf
>
> This series adds RISC-V AIA support in QEMU which includes emulating all
> AIA local CSRs, APLIC, and IMSIC. Only AIA local interrupt filtering is
> not implemented because we don't have any local interrupt greater than 12.
>
> To enable AIA in QEMU, use one of the following:
> 1) Only AIA local interrupt CSRs: Pass "x-aia=true" as CPU paramenter
>in the QEMU command-line
> 2) Only APLIC for virt machine: Pass "aia=aplic" as machine parameter
>in the QEMU command-line
> 3) Both APLIC and IMSIC for virt machine: Pass "aia=aplic-imsic" as
>machine parameter in the QEMU command-line
> 4) Both APLIC and IMSIC with 2 guest files for virt machine: Pass
>"aia=aplic-imsic,aia-guests=2" as machine parameter in the QEMU
>command-line
>
> To test series, we require OpenSBI and Linux with AIA support which can
> be found in riscv_aia_v1 branch at:
> https://github.com/avpatel/opensbi.git
> https://github.com/avpatel/linux.git
>
> This series can be found riscv_aia_v3 branch at:
> https://github.com/avpatel/qemu.git
>
> Changes since v2:
>  - Update PATCH4 to check and inject interrupt after V=1 when
>transitioning from V=0 to V=1
>
> Changes since v1:
>  - Revamped whole series and created more granular patches
>  - Added HGEIE and HGEIP CSR emulation for H-extension
>  - Added APLIC emulation
>  - Added IMSIC emulation
>
> Anup Patel (22):
>   target/riscv: Fix trap cause for RV32 HS-mode CSR access from RV64
> HS-mode
>   target/riscv: Implement SGEIP bit in hip and hie CSRs
>   target/riscv: Implement hgeie and hgeip CSRs
>   target/riscv: Improve delivery of guest external interrupts
>   target/riscv: Allow setting CPU feature from machine/device emulation
>   target/riscv: Add AIA cpu feature
>   target/riscv: Add defines for AIA CSRs
>   target/riscv: Allow AIA device emulation to set ireg rmw callback
>   target/riscv: Implement AIA local interrupt priorities
>   target/riscv: Implement AIA CSRs for 64 local interrupts on RV32
>   target/riscv: Implement AIA hvictl and hviprioX CSRs
>   target/riscv: Implement AIA interrupt filtering CSRs
>   target/riscv: Implement AIA mtopi, stopi, and vstopi CSRs
>   target/riscv: Implement AIA xiselect and xireg CSRs
>   target/riscv: Implement AIA IMSIC interface CSRs
>   hw/riscv: virt: Use AIA INTC compatible string when available
>   target/riscv: Allow users to force enable AIA CSRs in HART
>   hw/intc: Add RISC-V AIA APLIC device emulation
>   hw/riscv: virt: Add optional AIA APLIC support to virt machine
>   hw/intc: Add RISC-V AIA IMSIC device emulation
>   hw/riscv: virt: Add optional AIA IMSIC support to virt machine
>   docs/system: riscv: Document AIA options for virt machine

The PATCH19 and PATCH21 uses "aplic,xxx" and "imsic,xxx" DT
properties which is not allowed as-per Linux DT schema checker
because "aplic" and "imsic" prefixes are not vendor names. Instead
of this we should use "riscv" prefix which is registered vendor in
Linux DT bindings.

I will send v4 to fix the above.

Regards,
Anup

>
>  docs/system/riscv/virt.rst|   16 +
>  hw/intc/Kconfig   |6 +
>  hw/intc/meson.build   |2 +
>  hw/intc/riscv_aplic.c |  970 +
>  hw/intc/riscv_imsic.c |  443 
>  hw/riscv/Kconfig  |2 +
>  hw/riscv/virt.c   |  694 +++---
>  include/hw/intc/riscv_aplic.h |   73 ++
>  include/hw/intc/riscv_imsic.h |   68 ++
>  include/hw/riscv/virt.h   |   40 +-
>  target/riscv/cpu.c|   97 ++-
>  target/riscv/cpu.h|   67 +-
>  target/riscv/cpu_bits.h   |  132 
>  target/riscv/cpu_helper.c |  300 +++-
>  target/riscv/csr.c| 1273 ++---
>  target/riscv/machine.c|   24 +-
>  16 files changed, 3901 insertions(+), 306 deletions(-)
>  create mode 100644 hw/intc/riscv_aplic.c
>  create mode 100644 hw/intc/riscv_imsic.c
>  create mode 100644 include/hw/intc/riscv_aplic.h
>  create mode 100644 include/hw/intc/riscv_imsic.h
>
> --
> 2.25.1
>



Re: [RFC PATCH v4 20/20] vdpa: Add custom IOTLB translations to SVQ

2021-10-25 Thread Jason Wang
On Wed, Oct 20, 2021 at 7:57 PM Eugenio Perez Martin
 wrote:
>
> On Wed, Oct 20, 2021 at 11:03 AM Jason Wang  wrote:
> >
> > On Wed, Oct 20, 2021 at 2:52 PM Eugenio Perez Martin
> >  wrote:
> > >
> > > On Wed, Oct 20, 2021 at 4:07 AM Jason Wang  wrote:
> > > >
> > > > On Wed, Oct 20, 2021 at 10:02 AM Jason Wang  wrote:
> > > > >
> > > > > On Tue, Oct 19, 2021 at 6:29 PM Eugenio Perez Martin
> > > > >  wrote:
> > > > > >
> > > > > > On Tue, Oct 19, 2021 at 11:25 AM Jason Wang  
> > > > > > wrote:
> > > > > > >
> > > > > > >
> > > > > > > 在 2021/10/1 下午3:06, Eugenio Pérez 写道:
> > > > > > > > Use translations added in VhostIOVATree in SVQ.
> > > > > > > >
> > > > > > > > Now every element needs to store the previous address also, so 
> > > > > > > > VirtQueue
> > > > > > > > can consume the elements properly. This adds a little overhead 
> > > > > > > > per VQ
> > > > > > > > element, having to allocate more memory to stash them. As a 
> > > > > > > > possible
> > > > > > > > optimization, this allocation could be avoided if the 
> > > > > > > > descriptor is not
> > > > > > > > a chain but a single one, but this is left undone.
> > > > > > > >
> > > > > > > > TODO: iova range should be queried before, and add logic to 
> > > > > > > > fail when
> > > > > > > > GPA is outside of its range and memory listener or svq add it.
> > > > > > > >
> > > > > > > > Signed-off-by: Eugenio Pérez 
> > > > > > > > ---
> > > > > > > >   hw/virtio/vhost-shadow-virtqueue.h |   4 +-
> > > > > > > >   hw/virtio/vhost-shadow-virtqueue.c | 130 
> > > > > > > > -
> > > > > > > >   hw/virtio/vhost-vdpa.c |  40 -
> > > > > > > >   hw/virtio/trace-events |   1 +
> > > > > > > >   4 files changed, 152 insertions(+), 23 deletions(-)
> > > > > > > >
> > > > > > > > diff --git a/hw/virtio/vhost-shadow-virtqueue.h 
> > > > > > > > b/hw/virtio/vhost-shadow-virtqueue.h
> > > > > > > > index b7baa424a7..a0e6b5267a 100644
> > > > > > > > --- a/hw/virtio/vhost-shadow-virtqueue.h
> > > > > > > > +++ b/hw/virtio/vhost-shadow-virtqueue.h
> > > > > > > > @@ -11,6 +11,7 @@
> > > > > > > >   #define VHOST_SHADOW_VIRTQUEUE_H
> > > > > > > >
> > > > > > > >   #include "hw/virtio/vhost.h"
> > > > > > > > +#include "hw/virtio/vhost-iova-tree.h"
> > > > > > > >
> > > > > > > >   typedef struct VhostShadowVirtqueue VhostShadowVirtqueue;
> > > > > > > >
> > > > > > > > @@ -28,7 +29,8 @@ bool vhost_svq_start(struct vhost_dev *dev, 
> > > > > > > > unsigned idx,
> > > > > > > >   void vhost_svq_stop(struct vhost_dev *dev, unsigned idx,
> > > > > > > >   VhostShadowVirtqueue *svq);
> > > > > > > >
> > > > > > > > -VhostShadowVirtqueue *vhost_svq_new(struct vhost_dev *dev, int 
> > > > > > > > idx);
> > > > > > > > +VhostShadowVirtqueue *vhost_svq_new(struct vhost_dev *dev, int 
> > > > > > > > idx,
> > > > > > > > +VhostIOVATree *iova_map);
> > > > > > > >
> > > > > > > >   void vhost_svq_free(VhostShadowVirtqueue *vq);
> > > > > > > >
> > > > > > > > diff --git a/hw/virtio/vhost-shadow-virtqueue.c 
> > > > > > > > b/hw/virtio/vhost-shadow-virtqueue.c
> > > > > > > > index 2fd0bab75d..9db538547e 100644
> > > > > > > > --- a/hw/virtio/vhost-shadow-virtqueue.c
> > > > > > > > +++ b/hw/virtio/vhost-shadow-virtqueue.c
> > > > > > > > @@ -11,12 +11,19 @@
> > > > > > > >   #include "hw/virtio/vhost-shadow-virtqueue.h"
> > > > > > > >   #include "hw/virtio/vhost.h"
> > > > > > > >   #include "hw/virtio/virtio-access.h"
> > > > > > > > +#include "hw/virtio/vhost-iova-tree.h"
> > > > > > > >
> > > > > > > >   #include "standard-headers/linux/vhost_types.h"
> > > > > > > >
> > > > > > > >   #include "qemu/error-report.h"
> > > > > > > >   #include "qemu/main-loop.h"
> > > > > > > >
> > > > > > > > +typedef struct SVQElement {
> > > > > > > > +VirtQueueElement elem;
> > > > > > > > +void **in_sg_stash;
> > > > > > > > +void **out_sg_stash;
> > > > > > > > +} SVQElement;
> > > > > > > > +
> > > > > > > >   /* Shadow virtqueue to relay notifications */
> > > > > > > >   typedef struct VhostShadowVirtqueue {
> > > > > > > >   /* Shadow vring */
> > > > > > > > @@ -46,8 +53,11 @@ typedef struct VhostShadowVirtqueue {
> > > > > > > >   /* Virtio device */
> > > > > > > >   VirtIODevice *vdev;
> > > > > > > >
> > > > > > > > +/* IOVA mapping if used */
> > > > > > > > +VhostIOVATree *iova_map;
> > > > > > > > +
> > > > > > > >   /* Map for returning guest's descriptors */
> > > > > > > > -VirtQueueElement **ring_id_maps;
> > > > > > > > +SVQElement **ring_id_maps;
> > > > > > > >
> > > > > > > >   /* Next head to expose to device */
> > > > > > > >   uint16_t avail_idx_shadow;
> > > > > > > > @@ -79,13 +89,6 @@ bool 
> > > > > > > > vhost_svq_valid_device_features(uint64_t *dev_features)
> > > > > > > >   continue;
> > > > > > > >
> > > > > > > >   case VIRTIO_F_ACCESS_PLATFORM:
> > > > > > 

Re: [RFC PATCH v4 18/20] vhost: Add VhostIOVATree

2021-10-25 Thread Jason Wang
On Thu, Oct 21, 2021 at 10:34 PM Eugenio Perez Martin
 wrote:
>
> On Thu, Oct 21, 2021 at 10:12 AM Jason Wang  wrote:
> >
> > On Thu, Oct 21, 2021 at 3:03 PM Eugenio Perez Martin
> >  wrote:
> > >
> > > On Thu, Oct 21, 2021 at 4:34 AM Jason Wang  wrote:
> > > >
> > > > On Wed, Oct 20, 2021 at 8:07 PM Eugenio Perez Martin
> > > >  wrote:
> > > > >
> > > > > On Wed, Oct 20, 2021 at 11:01 AM Jason Wang  
> > > > > wrote:
> > > > > >
> > > > > > On Wed, Oct 20, 2021 at 3:54 PM Eugenio Perez Martin
> > > > > >  wrote:
> > > > > > >
> > > > > > > On Tue, Oct 19, 2021 at 11:23 AM Jason Wang  
> > > > > > > wrote:
> > > > > > > >
> > > > > > > > On Tue, Oct 19, 2021 at 4:32 PM Jason Wang 
> > > > > > > >  wrote:
> > > > > > > > >
> > > > > > > > >
> > > > > > > > > 在 2021/10/1 下午3:06, Eugenio Pérez 写道:
> > > > > > > > > > This tree is able to look for a translated address from an 
> > > > > > > > > > IOVA address.
> > > > > > > > > >
> > > > > > > > > > At first glance is similar to util/iova-tree. However, SVQ 
> > > > > > > > > > working on
> > > > > > > > > > devices with limited IOVA space need more capabilities, 
> > > > > > > > > > like allocating
> > > > > > > > > > IOVA chunks or perform reverse translations (qemu addresses 
> > > > > > > > > > to iova).
> > > > > > > > >
> > > > > > > > >
> > > > > > > > > I don't see any reverse translation is used in the shadow 
> > > > > > > > > code. Or
> > > > > > > > > anything I missed?
> > > > > > > >
> > > > > > > > Ok, it looks to me that it is used in the iova allocator. But I 
> > > > > > > > think
> > > > > > > > it's better to decouple it to an independent allocator instead 
> > > > > > > > of
> > > > > > > > vhost iova tree.
> > > > > > > >
> > > > > > >
> > > > > > > Reverse translation is used every time a buffer is made available,
> > > > > > > since buffers content are not copied, only the descriptors to SVQ
> > > > > > > vring.
> > > > > >
> > > > > > I may miss something but I didn't see the code? Qemu knows the VA of
> > > > > > virtqueue, and the VA of the VQ is stored in the VirtQueueElem?
> > > > > >
> > > > >
> > > > > It's used in the patch 20/20, could that be the misunderstanding? The
> > > > > function calling it is vhost_svq_translate_addr.
> > > > >
> > > > > Qemu knows the VA address of the buffer, but it must offer a valid SVQ
> > > > > iova to the device. That is the translation I mean.
> > > >
> > > > Ok, I get you. So if I understand correctly, what you did is:
> > > >
> > > > 1) allocate IOVA during region_add
> > > > 2) preform VA->IOVA reverse lookup in handle_kick
> > > >
> > > > This should be fine, but here're some suggestions:
> > > >
> > > > 1) remove the assert(map) in vhost_svq_translate_addr() since guest
> > > > can add e.g BAR address
> > >
> > > Wouldn't VirtQueue block them in virtqueue_pop / address_space_read_*
> > > functions? I'm fine to remove it but I would say it adds value against
> > > coding error.
> >
> > I think not. Though these addresses were excluded in
> > vhost_vdpa_listener_skipped_section(). For Qemu memory core, they are
> > valid addresses. Qemu emulate how hardware work (e.g pci p2p), so dma
> > to bar is allowed.
> >
>
> Ok I will treat them as errors.
>
> > >
> > > > 2) we probably need a better name vhost_iova_tree_alloc(), maybe
> > > > "vhost_iova_tree_map_alloc()"
> > > >
> > >
> > > Ok I will change for the next version.
> > >
> > > > There's actually another method.
> > > >
> > > > 1) don't do IOVA/map allocation in region_add()
> > > > 2) do the allocation in handle_kick(), then we know the IOVA so no
> > > > reverse lookup
> > > >
> > > > The advantage is that this can work for the case of vIOMMU. And they
> > > > should perform the same:
> > > >
> > > > 1) you method avoid the iova allocation per sg
> > > > 2) my method avoid the reverse lookup per sg
> > > >
> > >
> > > It's somehow doable, but we are replacing a tree search with a linear
> > > insertion at this moment.
> > >
> > > I would say that guest's IOVA -> qemu vaddr part works with no change
> > > for vIOMMU, since VirtQueue's virtqueue_pop already gives us the vaddr
> > > even in the case of vIOMMU.
> >
> > So in this case:
> >
> > 1) listener gives us GPA->host IOVA (host IOVA is allocated per GPA)
>
> Right, that was a miss from my side, I think I get your point way better now.
>
> So now vhost-iova-tree translates GPA -> host IOVA in vIOMMU case, and
> it is updated at the same frequency than guest physical memory hotplug
> / unplug (little during migration, I guess). There are special entries
> for SVQ vrings, that the tree does not map with GPA for obvious
> reasons, and you cannot locate them when looking by GPA.

Yes.

>
> Let's assume too that only SVQ vrings have been sent as IOMMU / IOTLB
> map, with the relation Host iova -> qemu's VA.
>
> > 2) virtqueue_pop gives us guest IOVA -> VA
> >
> > We still need extra logic to lookup the vIOMMU to get the guest IOVA
> > GPA then we can know the host IOVA.
> >
>
> That's 

[PATCH v3 2/2] tests/unit: Add an unit test for smp parsing

2021-10-25 Thread Yanan Wang
Now that we have a generic parser smp_parse(), let's add an unit
test for the code. All possible valid/invalid SMP configurations
that the user can specify are covered.

Signed-off-by: Yanan Wang 
Reviewed-by: Andrew Jones 
---
 MAINTAINERS |   1 +
 tests/unit/meson.build  |   1 +
 tests/unit/test-smp-parse.c | 594 
 3 files changed, 596 insertions(+)
 create mode 100644 tests/unit/test-smp-parse.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 80ec27d76a..310a9512ea 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1633,6 +1633,7 @@ F: include/hw/boards.h
 F: include/hw/core/cpu.h
 F: include/hw/cpu/cluster.h
 F: include/sysemu/numa.h
+F: tests/unit/test-smp-parse.c
 T: git https://gitlab.com/ehabkost/qemu.git machine-next
 
 Xtensa Machines
diff --git a/tests/unit/meson.build b/tests/unit/meson.build
index 7c297d7e5c..5e81525bef 100644
--- a/tests/unit/meson.build
+++ b/tests/unit/meson.build
@@ -45,6 +45,7 @@ tests = {
   'test-uuid': [],
   'ptimer-test': ['ptimer-test-stubs.c', meson.project_source_root() / 
'hw/core/ptimer.c'],
   'test-qapi-util': [],
+  'test-smp-parse': [qom, meson.project_source_root() / 
'hw/core/machine-smp.c'],
 }
 
 if have_system or have_tools
diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c
new file mode 100644
index 00..e96abe9ba4
--- /dev/null
+++ b/tests/unit/test-smp-parse.c
@@ -0,0 +1,594 @@
+/*
+ * SMP parsing unit-tests
+ *
+ * Copyright (c) 2021 Huawei Technologies Co., Ltd
+ *
+ * Authors:
+ *  Yanan Wang 
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qom/object.h"
+#include "qemu/module.h"
+#include "qapi/error.h"
+
+#include "hw/boards.h"
+
+#define T true
+#define F false
+
+#define MIN_CPUS 1   /* set the min CPUs supported by the machine as 1 */
+#define MAX_CPUS 512 /* set the max CPUs supported by the machine as 512 */
+
+/*
+ * Used to define the generic 3-level CPU topology hierarchy
+ *  -sockets/cores/threads
+ */
+#define SMP_CONFIG_GENERIC(ha, a, hb, b, hc, c, hd, d, he, e) \
+{ \
+.has_cpus= ha, .cpus= a,  \
+.has_sockets = hb, .sockets = b,  \
+.has_cores   = hc, .cores   = c,  \
+.has_threads = hd, .threads = d,  \
+.has_maxcpus = he, .maxcpus = e,  \
+}
+
+#define CPU_TOPOLOGY_GENERIC(a, b, c, d, e)   \
+{ \
+.cpus = a,\
+.sockets  = b,\
+.cores= c,\
+.threads  = d,\
+.max_cpus = e,\
+}
+
+/*
+ * Currently a 4-level topology hierarchy is supported on PC machines
+ *  -sockets/dies/cores/threads
+ */
+#define SMP_CONFIG_WITH_DIES(ha, a, hb, b, hc, c, hd, d, he, e, hf, f) \
+{ \
+.has_cpus= ha, .cpus= a,  \
+.has_sockets = hb, .sockets = b,  \
+.has_dies= hc, .dies= c,  \
+.has_cores   = hd, .cores   = d,  \
+.has_threads = he, .threads = e,  \
+.has_maxcpus = hf, .maxcpus = f,  \
+}
+
+/**
+ * @config - the given SMP configuration
+ * @expect_prefer_sockets - the expected parsing result for the
+ * valid configuration, when sockets are preferred over cores
+ * @expect_prefer_cores - the expected parsing result for the
+ * valid configuration, when cores are preferred over sockets
+ * @expect_error - the expected error report when the given
+ * configuration is invalid
+ */
+typedef struct SMPTestData {
+SMPConfiguration config;
+CpuTopology expect_prefer_sockets;
+CpuTopology expect_prefer_cores;
+const char *expect_error;
+} SMPTestData;
+
+/* Type info of the tested machine */
+static const TypeInfo smp_machine_info = {
+.name = TYPE_MACHINE,
+.parent = TYPE_OBJECT,
+.class_size = sizeof(MachineClass),
+.instance_size = sizeof(MachineState),
+};
+
+/*
+ * List all the possible valid sub-collections of the generic 5
+ * topology parameters (i.e. cpus/maxcpus/sockets/cores/threads),
+ * then test the automatic calculation algorithm of the missing
+ * values in the parser.
+ */
+static struct SMPTestData data_generic_valid[] = {
+{
+/* config: no configuration provided
+ * expect: cpus=1,sockets=1,cores=1,threads=1,maxcpus=1 */
+.config = SMP_CONFIG_GENERIC(F, 0, F, 0, F, 0, F, 0, F, 0),
+ 

[PATCH v3 1/2] hw/core/machine: Split out the smp parsing code

2021-10-25 Thread Yanan Wang
We are going to introduce an unit test for the parser smp_parse()
in hw/core/machine.c, but now machine.c is only built in softmmu.

In order to solve the build dependency on the smp parsing code and
avoid building unrelated stuff for the unit tests, move the tested
code from machine.c into a separate file, i.e., machine-smp.c and
build it in common field.

Signed-off-by: Yanan Wang 
Reviewed-by: Andrew Jones 
---
 MAINTAINERS   |   1 +
 hw/core/machine-smp.c | 181 ++
 hw/core/machine.c | 159 -
 hw/core/meson.build   |   2 +
 include/hw/boards.h   |   1 +
 5 files changed, 185 insertions(+), 159 deletions(-)
 create mode 100644 hw/core/machine-smp.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 894dc43105..80ec27d76a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1623,6 +1623,7 @@ F: cpu.c
 F: hw/core/cpu.c
 F: hw/core/machine-qmp-cmds.c
 F: hw/core/machine.c
+F: hw/core/machine-smp.c
 F: hw/core/null-machine.c
 F: hw/core/numa.c
 F: hw/cpu/cluster.c
diff --git a/hw/core/machine-smp.c b/hw/core/machine-smp.c
new file mode 100644
index 00..116a0cbbfa
--- /dev/null
+++ b/hw/core/machine-smp.c
@@ -0,0 +1,181 @@
+/*
+ * QEMU Machine core (related to -smp parsing)
+ *
+ * Copyright (c) 2021 Huawei Technologies Co., Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License,
+ * or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "hw/boards.h"
+#include "qapi/error.h"
+
+/*
+ * Report information of a machine's supported CPU topology hierarchy.
+ * Topology members will be ordered from the largest to the smallest
+ * in the string.
+ */
+static char *cpu_hierarchy_to_string(MachineState *ms)
+{
+MachineClass *mc = MACHINE_GET_CLASS(ms);
+GString *s = g_string_new(NULL);
+
+g_string_append_printf(s, "sockets (%u)", ms->smp.sockets);
+
+if (mc->smp_props.dies_supported) {
+g_string_append_printf(s, " * dies (%u)", ms->smp.dies);
+}
+
+g_string_append_printf(s, " * cores (%u)", ms->smp.cores);
+g_string_append_printf(s, " * threads (%u)", ms->smp.threads);
+
+return g_string_free(s, false);
+}
+
+/*
+ * smp_parse - Generic function used to parse the given SMP configuration
+ *
+ * Any missing parameter in "cpus/maxcpus/sockets/cores/threads" will be
+ * automatically computed based on the provided ones.
+ *
+ * In the calculation of omitted sockets/cores/threads: we prefer sockets
+ * over cores over threads before 6.2, while preferring cores over sockets
+ * over threads since 6.2.
+ *
+ * In the calculation of cpus/maxcpus: When both maxcpus and cpus are omitted,
+ * maxcpus will be computed from the given parameters and cpus will be set
+ * equal to maxcpus. When only one of maxcpus and cpus is given then the
+ * omitted one will be set to its given counterpart's value. Both maxcpus and
+ * cpus may be specified, but maxcpus must be equal to or greater than cpus.
+ *
+ * For compatibility, apart from the parameters that will be computed, newly
+ * introduced topology members which are likely to be target specific should
+ * be directly set as 1 if they are omitted (e.g. dies for PC since 4.1).
+ */
+void smp_parse(MachineState *ms, SMPConfiguration *config, Error **errp)
+{
+MachineClass *mc = MACHINE_GET_CLASS(ms);
+unsigned cpus= config->has_cpus ? config->cpus : 0;
+unsigned sockets = config->has_sockets ? config->sockets : 0;
+unsigned dies= config->has_dies ? config->dies : 0;
+unsigned cores   = config->has_cores ? config->cores : 0;
+unsigned threads = config->has_threads ? config->threads : 0;
+unsigned maxcpus = config->has_maxcpus ? config->maxcpus : 0;
+
+/*
+ * Specified CPU topology parameters must be greater than zero,
+ * explicit configuration like "cpus=0" is not allowed.
+ */
+if ((config->has_cpus && config->cpus == 0) ||
+(config->has_sockets && config->sockets == 0) ||
+(config->has_dies && config->dies == 0) ||
+(config->has_cores && config->cores == 0) ||
+(config->has_threads && config->threads == 0) ||
+(config->has_maxcpus && config->maxcpus == 0)) {
+warn_report("Deprecated CPU topology (considered invalid): "
+"CPU topology parameters must be greater than zero");
+}
+
+/*
+ * If not supported by the machine, a topology parameter must be

[PATCH v3 0/2] hw/core/machine: Add an unit test for smp_parse

2021-10-25 Thread Yanan Wang
Hi,

This is v3 which introduces an unit test for generic smp_parse.

We have had enough discussions about what kind of SMP configurations
by the user should be considered valid and what should be invalid.
Since we have finished optimizing the SMP parsing code, then this
test normatively listed all the possible valid/invalid configurations
that the user can provide. This can be a testing tool when we
introduce new topology members and need to touch the parsing code.

For your reference, some related discussion is here:
https://lore.kernel.org/qemu-devel/yoxf+sxzusjdb...@redhat.com/

Changelog:
v2->v3:
- add Andrew's R-b for PATCH #1
- drop an unused macro definition in PATCH #2
- v2: 
https://lore.kernel.org/qemu-devel/20211013074119.23028-1-wangyana...@huawei.com/

v1->v2:
- split smp_parse out into a separate .c file instead of a header (patch #1)
- dropped an unnecessary function and add Andrew's R-b (patch #2)
- v1: 
https://lore.kernel.org/qemu-devel/20211010103954.20644-1-wangyana...@huawei.com/

Yanan Wang (2):
  hw/core/machine: Split out the smp parsing code
  tests/unit: Add an unit test for smp parsing

 MAINTAINERS |   2 +
 hw/core/machine-smp.c   | 181 +++
 hw/core/machine.c   | 159 --
 hw/core/meson.build |   2 +
 include/hw/boards.h |   1 +
 tests/unit/meson.build  |   1 +
 tests/unit/test-smp-parse.c | 594 
 7 files changed, 781 insertions(+), 159 deletions(-)
 create mode 100644 hw/core/machine-smp.c
 create mode 100644 tests/unit/test-smp-parse.c

--
2.19.1




Re: [PATCH v2 2/2] tests/unit: Add an unit test for smp parsing

2021-10-25 Thread wangyanan (Y)



On 2021/10/13 15:41, Yanan Wang wrote:

Now that we have a generic parser smp_parse(), let's add an unit
test for the code. All possible valid/invalid SMP configurations
that the user can specify are covered.

Signed-off-by: Yanan Wang 
Reviewed-by: Andrew Jones 
---
  MAINTAINERS |   1 +
  tests/unit/meson.build  |   1 +
  tests/unit/test-smp-parse.c | 604 
  3 files changed, 606 insertions(+)
  create mode 100644 tests/unit/test-smp-parse.c

diff --git a/MAINTAINERS b/MAINTAINERS
index eeeb13ab75..516517ffe4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1632,6 +1632,7 @@ F: include/hw/boards.h
  F: include/hw/core/cpu.h
  F: include/hw/cpu/cluster.h
  F: include/sysemu/numa.h
+F: tests/unit/test-smp-parse.c
  T: git https://gitlab.com/ehabkost/qemu.git machine-next
  
  Xtensa Machines

diff --git a/tests/unit/meson.build b/tests/unit/meson.build
index 7c297d7e5c..5e81525bef 100644
--- a/tests/unit/meson.build
+++ b/tests/unit/meson.build
@@ -45,6 +45,7 @@ tests = {
'test-uuid': [],
'ptimer-test': ['ptimer-test-stubs.c', meson.project_source_root() / 
'hw/core/ptimer.c'],
'test-qapi-util': [],
+  'test-smp-parse': [qom, meson.project_source_root() / 
'hw/core/machine-smp.c'],
  }
  
  if have_system or have_tools

diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c
new file mode 100644
index 00..ed01942207
--- /dev/null
+++ b/tests/unit/test-smp-parse.c
@@ -0,0 +1,604 @@
+/*
+ * SMP parsing unit-tests
+ *
+ * Copyright (c) 2021 Huawei Technologies Co., Ltd
+ *
+ * Authors:
+ *  Yanan Wang 
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qom/object.h"
+#include "qemu/module.h"
+#include "qapi/error.h"
+
+#include "hw/boards.h"
+
+#define T true
+#define F false
+
+#define MIN_CPUS 1   /* set the min CPUs supported by the machine as 1 */
+#define MAX_CPUS 512 /* set the max CPUs supported by the machine as 512 */
+
+/*
+ * Used to define the generic 3-level CPU topology hierarchy
+ *  -sockets/cores/threads
+ */
+#define SMP_CONFIG_GENERIC(ha, a, hb, b, hc, c, hd, d, he, e) \
+{ \
+.has_cpus= ha, .cpus= a,  \
+.has_sockets = hb, .sockets = b,  \
+.has_cores   = hc, .cores   = c,  \
+.has_threads = hd, .threads = d,  \
+.has_maxcpus = he, .maxcpus = e,  \
+}
+
+#define CPU_TOPOLOGY_GENERIC(a, b, c, d, e)   \
+{ \
+.cpus = a,\
+.sockets  = b,\
+.cores= c,\
+.threads  = d,\
+.max_cpus = e,\
+}
+
+/*
+ * Currently a 4-level topology hierarchy is supported on PC machines
+ *  -sockets/dies/cores/threads
+ */
+#define SMP_CONFIG_WITH_DIES(ha, a, hb, b, hc, c, hd, d, he, e, hf, f) \
+{ \
+.has_cpus= ha, .cpus= a,  \
+.has_sockets = hb, .sockets = b,  \
+.has_dies= hc, .dies= c,  \
+.has_cores   = hd, .cores   = d,  \
+.has_threads = he, .threads = e,  \
+.has_maxcpus = hf, .maxcpus = f,  \
+}
+
+#define CPU_TOPOLOGY_WITH_DIES(a, b, c, d, e, f)  \
+{ \
+.cpus = a,\
+.sockets  = b,\
+.dies = c,\
+.cores= d,\
+.threads  = e,\
+.max_cpus = f,\
+}

After double checking, just found that this macro definition is not
used any more. I will drop it in v3. Given that this is minor update,
I'll still keep the R-b.

Thanks,
Yanan

+
+/**
+ * @config - the given SMP configuration
+ * @expect_prefer_sockets - the expected parsing result for the
+ * valid configuration, when sockets are preferred over cores
+ * @expect_prefer_cores - the expected parsing result for the
+ * valid configuration, when cores are preferred over sockets
+ * @expect_error - the expected error report when the given
+ * configuration is invalid
+ */
+typedef struct SMPTestData {
+SMPConfiguration config;
+CpuTopology expect_prefer_sockets;
+CpuTopology 

Re: Commit abb0cd93494 breaks -singlestep -d in_asm,cpu with qemu-system-sh4

2021-10-25 Thread Richard Henderson

On 10/25/21 2:16 PM, BALATON Zoltan wrote:

Hello,

Commit abb0cd93494 (accel/tcg: Split out log_cpu_exec) seems to have broken -singlestep -d 
in_asm,cpu output with qemu-system-sh4 after a delay slot. Since that commit I get:


pc=0xac80003e sr=0x50f1 pr=0x fpscr=0x00040001
spc=0x ssr=0x gbr=0x vbr=0x
sgr=0x dbr=0x delayed_pc=0x fpul=0x
r0=0x8cc9d000 r1=0xacc9d000 r2=0xe000 r3=0x8c80
r4=0x r5=0x r6=0x r7=0x
r8=0x r9=0x r10=0x r11=0x
r12=0x r13=0x r14=0x r15=0x
r16=0x r17=0x50f0 r18=0x r19=0x
r20=0x r21=0x r22=0x r23=0x

IN:
0xac800040:  bt.s   0xac80001a

pc=0xac800040 sr=0x50f1 pr=0x fpscr=0x00040001
spc=0x ssr=0x gbr=0x vbr=0x
sgr=0x dbr=0x delayed_pc=0x fpul=0x
r0=0x8cc9cfe0 r1=0xacc9d000 r2=0xe000 r3=0x8c80
r4=0x r5=0x r6=0x r7=0x
r8=0x r9=0x r10=0x r11=0x
r12=0x r13=0x r14=0x r15=0x
r16=0x r17=0x50f0 r18=0x r19=0x
r20=0x r21=0x r22=0x r23=0x

IN:
0xac800042:  add    #-32,r1

pc=0xac800042 sr=0x50f1 pr=0x fpscr=0x00040001
spc=0x ssr=0x gbr=0x vbr=0x
sgr=0x dbr=0x delayed_pc=0xac80001a fpul=0x
r0=0x8cc9cfe0 r1=0xacc9d000 r2=0xe000 r3=0x8c80
r4=0x r5=0x r6=0x r7=0x
r8=0x r9=0x r10=0x r11=0x
r12=0x r13=0x r14=0x r15=0x
r16=0x r17=0x50f0 r18=0x r19=0x
r20=0x r21=0x r22=0x r23=0x
in conditional delay slot (delayed_pc=0xac80001a)
pc=0xac80001a sr=0x50f1 pr=0x fpscr=0x00040001
spc=0x ssr=0x gbr=0x vbr=0x
sgr=0x dbr=0x delayed_pc=0xac80001a fpul=0x
r0=0x8cc9cfe0 r1=0xacc9cfe0 r2=0xe000 r3=0x8c80
r4=0x r5=0x r6=0x r7=0x
r8=0x r9=0x r10=0x r11=0x
r12=0x r13=0x r14=0x r15=0x
r16=0x r17=0x50f0 r18=0x r19=0x
r20=0x r21=0x r22=0x r23=0x
pc=0xac80001c sr=0x50f1 pr=0x fpscr=0x00040001
spc=0x ssr=0x gbr=0x vbr=0x
sgr=0x dbr=0x delayed_pc=0xac80001a fpul=0x
r0=0x8cc9cfe0 r1=0xacc9cfe0 r2=0xe000 r3=0x8c80
r4=0x r5=0x r6=0x r7=0x
r8=0x r9=0x r10=0x r11=0x
r12=0x r13=0x r14=0x r15=0x
r16=0x r17=0x50f0 r18=0x r19=0x
r20=0x r21=0x r22=0x r23=0x

After the first delay slot no more in_asm output is printed.


I don't think it's broken, it's just logging more (lots more) than it used to do -- that 
was part of the changes in that patch set.  If I turn off logging, and let -singlestep run 
by itself, it takes some time but I do get to a login prompt.



r~



[PATCH v5 06/26] arm: qemu: Add a devicetree file for qemu_arm64

2021-10-25 Thread Simon Glass
Add this file, generated from qemu, so there is a reference devicetree
in the U-Boot tree.

Signed-off-by: Simon Glass 
---

(no changes since v1)

 arch/arm/dts/Makefile|   2 +-
 arch/arm/dts/qemu-arm64.dts  | 381 +++
 configs/qemu_arm64_defconfig |   1 +
 3 files changed, 383 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/dts/qemu-arm64.dts

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 7ab8b145f3f..e70293bb849 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -1153,7 +1153,7 @@ dtb-$(CONFIG_TARGET_IMX8MM_CL_IOT_GATE_OPTEE) += 
imx8mm-cl-iot-gate-optee.dtb
 
 dtb-$(CONFIG_TARGET_EA_LPC3250DEVKITV2) += lpc3250-ea3250.dtb
 
-dtb-$(CONFIG_ARCH_QEMU) += qemu-arm.dtb
+dtb-$(CONFIG_ARCH_QEMU) += qemu-arm.dtb qemu-arm64.dtb
 
 targets += $(dtb-y)
 
diff --git a/arch/arm/dts/qemu-arm64.dts b/arch/arm/dts/qemu-arm64.dts
new file mode 100644
index 000..7590e49cc84
--- /dev/null
+++ b/arch/arm/dts/qemu-arm64.dts
@@ -0,0 +1,381 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Sample device tree for qemu_arm64
+
+ * Copyright 2021 Google LLC
+ */
+
+/dts-v1/;
+
+/ {
+   interrupt-parent = <0x8001>;
+   #size-cells = <0x02>;
+   #address-cells = <0x02>;
+   compatible = "linux,dummy-virt";
+
+   psci {
+   migrate = <0xc405>;
+   cpu_on = <0xc403>;
+   cpu_off = <0x8402>;
+   cpu_suspend = <0xc401>;
+   method = "hvc";
+   compatible = "arm,psci-0.2\0arm,psci";
+   };
+
+   memory@4000 {
+   reg = <0x00 0x4000 0x00 0x800>;
+   device_type = "memory";
+   };
+
+   platform@c00 {
+   interrupt-parent = <0x8001>;
+   ranges = <0x00 0x00 0xc00 0x200>;
+   #address-cells = <0x01>;
+   #size-cells = <0x01>;
+   compatible = "qemu,platform\0simple-bus";
+   };
+
+   fw-cfg@902 {
+   dma-coherent;
+   reg = <0x00 0x902 0x00 0x18>;
+   compatible = "qemu,fw-cfg-mmio";
+   };
+
+   virtio_mmio@a00 {
+   dma-coherent;
+   interrupts = <0x00 0x10 0x01>;
+   reg = <0x00 0xa00 0x00 0x200>;
+   compatible = "virtio,mmio";
+   };
+
+   virtio_mmio@a000200 {
+   dma-coherent;
+   interrupts = <0x00 0x11 0x01>;
+   reg = <0x00 0xa000200 0x00 0x200>;
+   compatible = "virtio,mmio";
+   };
+
+   virtio_mmio@a000400 {
+   dma-coherent;
+   interrupts = <0x00 0x12 0x01>;
+   reg = <0x00 0xa000400 0x00 0x200>;
+   compatible = "virtio,mmio";
+   };
+
+   virtio_mmio@a000600 {
+   dma-coherent;
+   interrupts = <0x00 0x13 0x01>;
+   reg = <0x00 0xa000600 0x00 0x200>;
+   compatible = "virtio,mmio";
+   };
+
+   virtio_mmio@a000800 {
+   dma-coherent;
+   interrupts = <0x00 0x14 0x01>;
+   reg = <0x00 0xa000800 0x00 0x200>;
+   compatible = "virtio,mmio";
+   };
+
+   virtio_mmio@a000a00 {
+   dma-coherent;
+   interrupts = <0x00 0x15 0x01>;
+   reg = <0x00 0xa000a00 0x00 0x200>;
+   compatible = "virtio,mmio";
+   };
+
+   virtio_mmio@a000c00 {
+   dma-coherent;
+   interrupts = <0x00 0x16 0x01>;
+   reg = <0x00 0xa000c00 0x00 0x200>;
+   compatible = "virtio,mmio";
+   };
+
+   virtio_mmio@a000e00 {
+   dma-coherent;
+   interrupts = <0x00 0x17 0x01>;
+   reg = <0x00 0xa000e00 0x00 0x200>;
+   compatible = "virtio,mmio";
+   };
+
+   virtio_mmio@a001000 {
+   dma-coherent;
+   interrupts = <0x00 0x18 0x01>;
+   reg = <0x00 0xa001000 0x00 0x200>;
+   compatible = "virtio,mmio";
+   };
+
+   virtio_mmio@a001200 {
+   dma-coherent;
+   interrupts = <0x00 0x19 0x01>;
+   reg = <0x00 0xa001200 0x00 0x200>;
+   compatible = "virtio,mmio";
+   };
+
+   virtio_mmio@a001400 {
+   dma-coherent;
+   interrupts = <0x00 0x1a 0x01>;
+   reg = <0x00 0xa001400 0x00 0x200>;
+   compatible = "virtio,mmio";
+   };
+
+   virtio_mmio@a001600 {
+   dma-coherent;
+   interrupts = <0x00 0x1b 0x01>;
+   reg = <0x00 0xa001600 0x00 0x200>;
+   compatible = "virtio,mmio";
+   };
+
+   virtio_mmio@a001800 {
+   dma-coherent;
+   interrupts = <0x00 0x1c 0x01>;
+   reg = <0x00 0xa001800 0x00 0x200>;
+   compatible = "virtio,mmio";
+   };
+
+   virtio_mmio@a001a00 

[PATCH v5 07/26] riscv: qemu: Add devicetree files for qemu_riscv32/64

2021-10-25 Thread Simon Glass
Add these files, generated from qemu, so there is a reference devicetree
in the U-Boot tree.

Split the existing qemu-virt into two, since we need a different
devicetree for 32- and 64-bit machines.

Signed-off-by: Simon Glass 
---

(no changes since v1)

 arch/riscv/dts/Makefile  |   2 +-
 arch/riscv/dts/qemu-virt.dts |   8 -
 arch/riscv/dts/qemu-virt32.dts   | 217 +++
 arch/riscv/dts/qemu-virt64.dts   | 217 +++
 configs/qemu-riscv32_defconfig   |   1 +
 configs/qemu-riscv32_smode_defconfig |   1 +
 configs/qemu-riscv32_spl_defconfig   |   2 +-
 configs/qemu-riscv64_defconfig   |   1 +
 configs/qemu-riscv64_smode_defconfig |   1 +
 configs/qemu-riscv64_spl_defconfig   |   2 +-
 10 files changed, 441 insertions(+), 11 deletions(-)
 delete mode 100644 arch/riscv/dts/qemu-virt.dts
 create mode 100644 arch/riscv/dts/qemu-virt32.dts
 create mode 100644 arch/riscv/dts/qemu-virt64.dts

diff --git a/arch/riscv/dts/Makefile b/arch/riscv/dts/Makefile
index b6e9166767b..90d3f35e6e3 100644
--- a/arch/riscv/dts/Makefile
+++ b/arch/riscv/dts/Makefile
@@ -2,7 +2,7 @@
 
 dtb-$(CONFIG_TARGET_AX25_AE350) += ae350_32.dtb ae350_64.dtb
 dtb-$(CONFIG_TARGET_MICROCHIP_ICICLE) += microchip-mpfs-icicle-kit.dtb
-dtb-$(CONFIG_TARGET_QEMU_VIRT) += qemu-virt.dtb
+dtb-$(CONFIG_TARGET_QEMU_VIRT) += qemu-virt32.dtb qemu-virt64.dtb
 dtb-$(CONFIG_TARGET_OPENPITON_RISCV64) += openpiton-riscv64.dtb
 dtb-$(CONFIG_TARGET_SIFIVE_UNLEASHED) += hifive-unleashed-a00.dtb
 dtb-$(CONFIG_TARGET_SIFIVE_UNMATCHED) += hifive-unmatched-a00.dtb
diff --git a/arch/riscv/dts/qemu-virt.dts b/arch/riscv/dts/qemu-virt.dts
deleted file mode 100644
index fecff542b91..000
--- a/arch/riscv/dts/qemu-virt.dts
+++ /dev/null
@@ -1,8 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) 2021, Bin Meng 
- */
-
-/dts-v1/;
-
-#include "binman.dtsi"
diff --git a/arch/riscv/dts/qemu-virt32.dts b/arch/riscv/dts/qemu-virt32.dts
new file mode 100644
index 000..3c449413523
--- /dev/null
+++ b/arch/riscv/dts/qemu-virt32.dts
@@ -0,0 +1,217 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021, Bin Meng 
+ */
+
+/dts-v1/;
+
+#include "binman.dtsi"
+
+/ {
+   #address-cells = <0x02>;
+   #size-cells = <0x02>;
+   compatible = "riscv-virtio";
+   model = "riscv-virtio,qemu";
+
+   fw-cfg@1010 {
+   dma-coherent;
+   reg = <0x00 0x1010 0x00 0x18>;
+   compatible = "qemu,fw-cfg-mmio";
+   };
+
+   flash@2000 {
+   bank-width = <0x04>;
+   reg = <0x00 0x2000 0x00 0x200
+   0x00 0x2200 0x00 0x200>;
+   compatible = "cfi-flash";
+   };
+
+   chosen {
+   bootargs = [00];
+   stdout-path = "/soc/uart@1000";
+   };
+
+   memory@8000 {
+   device_type = "memory";
+   reg = <0x00 0x8000 0x00 0x800>;
+   };
+
+   cpus {
+   #address-cells = <0x01>;
+   #size-cells = <0x00>;
+   timebase-frequency = <0x989680>;
+
+   cpu@0 {
+   phandle = <0x01>;
+   device_type = "cpu";
+   reg = <0x00>;
+   status = "okay";
+   compatible = "riscv";
+   riscv,isa = "rv32imafdcsu";
+   mmu-type = "riscv,sv32";
+
+   interrupt-controller {
+   #interrupt-cells = <0x01>;
+   interrupt-controller;
+   compatible = "riscv,cpu-intc";
+   phandle = <0x02>;
+   };
+   };
+
+   cpu-map {
+
+   cluster0 {
+
+   core0 {
+   cpu = <0x01>;
+   };
+   };
+   };
+   };
+
+   soc {
+   #address-cells = <0x02>;
+   #size-cells = <0x02>;
+   compatible = "simple-bus";
+   ranges;
+
+   rtc@101000 {
+   interrupts = <0x0b>;
+   interrupt-parent = <0x03>;
+   reg = <0x00 0x101000 0x00 0x1000>;
+   compatible = "google,goldfish-rtc";
+   };
+
+   uart@1000 {
+   interrupts = <0x0a>;
+   interrupt-parent = <0x03>;
+   clock-frequency = <0x384000>;
+   reg = <0x00 0x1000 0x00 0x100>;
+   compatible = "ns16550a";
+   };
+
+   poweroff {
+   value = <0x>;
+   offset = <0x00>;
+   regmap = <0x04>;
+

[PATCH v5 04/26] arm: riscv: qemu: Explain how to extract the generated dt

2021-10-25 Thread Simon Glass
QEMU currently generates a devicetree for use with U-Boot. Explain how to
obtain it.

Also explain how to merge it to produce a devicetree with the U-Boot
features included.

Signed-off-by: Simon Glass 
---

Changes in v5:
- Merge RISC-V and ARM patches since they are similar

 doc/board/emulation/qemu-arm.rst   |  3 ++
 doc/board/emulation/qemu-riscv.rst |  3 ++
 doc/develop/devicetree/dt_qemu.rst | 48 ++
 doc/develop/devicetree/index.rst   |  1 +
 4 files changed, 55 insertions(+)
 create mode 100644 doc/develop/devicetree/dt_qemu.rst

diff --git a/doc/board/emulation/qemu-arm.rst b/doc/board/emulation/qemu-arm.rst
index 97b6ec64905..a39df046fc3 100644
--- a/doc/board/emulation/qemu-arm.rst
+++ b/doc/board/emulation/qemu-arm.rst
@@ -21,6 +21,9 @@ The 'virt' platform provides the following as the basic 
functionality:
 
 Additionally, a number of optional peripherals can be added to the PCI bus.
 
+See :doc:`../../develop/devicetree/dt_qemu` for information on how to see
+the devicetree actually generated by QEMU.
+
 Building U-Boot
 ---
 Set the CROSS_COMPILE environment variable as usual, and run:
diff --git a/doc/board/emulation/qemu-riscv.rst 
b/doc/board/emulation/qemu-riscv.rst
index 4b8e104a215..3409fff8117 100644
--- a/doc/board/emulation/qemu-riscv.rst
+++ b/doc/board/emulation/qemu-riscv.rst
@@ -13,6 +13,9 @@ The QEMU virt machine models a generic RISC-V virtual machine 
with support for
 the VirtIO standard networking and block storage devices. It has CLINT, PLIC,
 16550A UART devices in addition to VirtIO and it also uses device-tree to pass
 configuration information to guest software. It implements RISC-V privileged
+
+See :doc:`../../develop/devicetree/dt_qemu` for information on how to see
+the devicetree actually generated by QEMU.
 architecture spec v1.10.
 
 Building U-Boot
diff --git a/doc/develop/devicetree/dt_qemu.rst 
b/doc/develop/devicetree/dt_qemu.rst
new file mode 100644
index 000..1392a2cae97
--- /dev/null
+++ b/doc/develop/devicetree/dt_qemu.rst
@@ -0,0 +1,48 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Devicetree in QEMU
+==
+
+For QEMU on ARM, RISC-V and one PPC target, the devicetree is created on the
+fly by QEMU. It is intended for use in Linux but can be used by U-Boot also,
+so long as any nodes/properties needed by U-Boot are merged in.
+
+When `CONFIG_OF_BOARD` is enabled
+
+
+Obtaining the QEMU devicetree
+-
+
+Where QEMU generates its own devicetree to pass to U-Boot tou can use
+`-dtb u-boot.dtb` to force QEMU to use U-Boot's in-tree version.
+
+To obtain the devicetree that qemu generates, add `-machine dumpdtb=qemu.dtb`,
+e.g.::
+
+qemu-system-arm -machine virt -machine dumpdtb=qemu.dtb
+
+qemu-system-aarch64 -machine virt -machine dumpdtb=qemu.dtb
+
+qemu-system-riscv64 -machine virt -machine dumpdtb=qemu.dtb
+
+
+Merging in U-Boot nodes/properties
+--
+
+Various U-Boot features require nodes and properties in the U-Boot devicetree
+and at present QEMU is unaware of these. To use these you must manually merge
+in the appropriate pieces.
+
+One way to do this is with dtc. This command runs dtc on each .dtb file in 
turn,
+to produce a text file. It drops the duplicate header on the qemu one. Then it
+joins them up and runs them through dtc to compile the output::
+
+qemu-system-arm -machine virt -machine dumpdtb=qemu.dtb
+cat  <(dtc -I dtb qemu.dtb) <(dtc -I dtb  u-boot.dtb |grep -v /dts-v1/) 
|dtc - -o merged.dtb
+
+You can then run qemu with the merged devicetree, e.g.::
+
+qemu-system-arm -machine virt -nographic -bios u-boot.bin -dtb merged.dtb
+
+Note that there seems to be a bug in some versions of qemu where the output of
+dumpdtb does not quite match what is provided to U-Boot.
diff --git a/doc/develop/devicetree/index.rst b/doc/develop/devicetree/index.rst
index b5b33dfea0f..fc2fb41b1bb 100644
--- a/doc/develop/devicetree/index.rst
+++ b/doc/develop/devicetree/index.rst
@@ -12,3 +12,4 @@ build-time and runtime configuration.
intro
control
dt_update
+   dt_qemu
-- 
2.33.0.1079.g6e70778dc9-goog




[PATCH v5 05/26] arm: qemu: Add a devicetree file for qemu_arm

2021-10-25 Thread Simon Glass
Add this file, generated from qemu, so there is a reference devicetree
in the U-Boot tree.

Signed-off-by: Simon Glass 
---

(no changes since v1)

 arch/arm/dts/Makefile  |   2 +
 arch/arm/dts/qemu-arm.dts  | 402 +
 configs/qemu_arm_defconfig |   1 +
 3 files changed, 405 insertions(+)
 create mode 100644 arch/arm/dts/qemu-arm.dts

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index a88aecc5bd9..7ab8b145f3f 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -1153,6 +1153,8 @@ dtb-$(CONFIG_TARGET_IMX8MM_CL_IOT_GATE_OPTEE) += 
imx8mm-cl-iot-gate-optee.dtb
 
 dtb-$(CONFIG_TARGET_EA_LPC3250DEVKITV2) += lpc3250-ea3250.dtb
 
+dtb-$(CONFIG_ARCH_QEMU) += qemu-arm.dtb
+
 targets += $(dtb-y)
 
 # Add any required device tree compiler flags here
diff --git a/arch/arm/dts/qemu-arm.dts b/arch/arm/dts/qemu-arm.dts
new file mode 100644
index 000..fed558ced98
--- /dev/null
+++ b/arch/arm/dts/qemu-arm.dts
@@ -0,0 +1,402 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Sample device tree for qemu_arm
+
+ * Copyright 2021 Google LLC
+ */
+
+/dts-v1/;
+
+/ {
+   interrupt-parent = <0x8001>;
+   #size-cells = <0x02>;
+   #address-cells = <0x02>;
+   compatible = "linux,dummy-virt";
+
+   psci {
+   migrate = <0x8405>;
+   cpu_on = <0x8403>;
+   cpu_off = <0x8402>;
+   cpu_suspend = <0x8401>;
+   method = "hvc";
+   compatible = "arm,psci-0.2\0arm,psci";
+   };
+
+   memory@4000 {
+   reg = <0x00 0x4000 0x00 0x800>;
+   device_type = "memory";
+   };
+
+   platform@c00 {
+   interrupt-parent = <0x8001>;
+   ranges = <0x00 0x00 0xc00 0x200>;
+   #address-cells = <0x01>;
+   #size-cells = <0x01>;
+   compatible = "qemu,platform\0simple-bus";
+   };
+
+   fw-cfg@902 {
+   dma-coherent;
+   reg = <0x00 0x902 0x00 0x18>;
+   compatible = "qemu,fw-cfg-mmio";
+   };
+
+   virtio_mmio@a00 {
+   dma-coherent;
+   interrupts = <0x00 0x10 0x01>;
+   reg = <0x00 0xa00 0x00 0x200>;
+   compatible = "virtio,mmio";
+   };
+
+   virtio_mmio@a000200 {
+   dma-coherent;
+   interrupts = <0x00 0x11 0x01>;
+   reg = <0x00 0xa000200 0x00 0x200>;
+   compatible = "virtio,mmio";
+   };
+
+   virtio_mmio@a000400 {
+   dma-coherent;
+   interrupts = <0x00 0x12 0x01>;
+   reg = <0x00 0xa000400 0x00 0x200>;
+   compatible = "virtio,mmio";
+   };
+
+   virtio_mmio@a000600 {
+   dma-coherent;
+   interrupts = <0x00 0x13 0x01>;
+   reg = <0x00 0xa000600 0x00 0x200>;
+   compatible = "virtio,mmio";
+   };
+
+   virtio_mmio@a000800 {
+   dma-coherent;
+   interrupts = <0x00 0x14 0x01>;
+   reg = <0x00 0xa000800 0x00 0x200>;
+   compatible = "virtio,mmio";
+   };
+
+   virtio_mmio@a000a00 {
+   dma-coherent;
+   interrupts = <0x00 0x15 0x01>;
+   reg = <0x00 0xa000a00 0x00 0x200>;
+   compatible = "virtio,mmio";
+   };
+
+   virtio_mmio@a000c00 {
+   dma-coherent;
+   interrupts = <0x00 0x16 0x01>;
+   reg = <0x00 0xa000c00 0x00 0x200>;
+   compatible = "virtio,mmio";
+   };
+
+   virtio_mmio@a000e00 {
+   dma-coherent;
+   interrupts = <0x00 0x17 0x01>;
+   reg = <0x00 0xa000e00 0x00 0x200>;
+   compatible = "virtio,mmio";
+   };
+
+   virtio_mmio@a001000 {
+   dma-coherent;
+   interrupts = <0x00 0x18 0x01>;
+   reg = <0x00 0xa001000 0x00 0x200>;
+   compatible = "virtio,mmio";
+   };
+
+   virtio_mmio@a001200 {
+   dma-coherent;
+   interrupts = <0x00 0x19 0x01>;
+   reg = <0x00 0xa001200 0x00 0x200>;
+   compatible = "virtio,mmio";
+   };
+
+   virtio_mmio@a001400 {
+   dma-coherent;
+   interrupts = <0x00 0x1a 0x01>;
+   reg = <0x00 0xa001400 0x00 0x200>;
+   compatible = "virtio,mmio";
+   };
+
+   virtio_mmio@a001600 {
+   dma-coherent;
+   interrupts = <0x00 0x1b 0x01>;
+   reg = <0x00 0xa001600 0x00 0x200>;
+   compatible = "virtio,mmio";
+   };
+
+   virtio_mmio@a001800 {
+   dma-coherent;
+   interrupts = <0x00 0x1c 0x01>;
+   reg = <0x00 0xa001800 0x00 0x200>;
+   compatible = "virtio,mmio";
+   };
+
+   virtio_mmio@a001a00 {
+   dma-coherent;
+ 

[PATCH v5 00/26] fdt: Make OF_BOARD a boolean option

2021-10-25 Thread Simon Glass
With Ilias' efforts we have dropped OF_PRIOR_STAGE and OF_HOSTFILE so
there are only three ways to obtain a devicetree:

   - OF_SEPARATE - the normal way, where the devicetree is built and
  appended to U-Boot
   - OF_EMBED - for development purposes, the devicetree is embedded in
  the ELF file (also used for EFI)
   - OF_BOARD - the board figures it out on its own

The last one is currently set up so that no devicetree is needed at all
in the U-Boot tree. Most boards do provide one, but some don't. Some
don't even provide instructions on how to boot on the board.

The problems with this approach are documented in another patch in this
series: "doc: Add documentation about devicetree usage"

In practice, OF_BOARD is not really distinct from OF_SEPARATE. Any board
can obtain its devicetree at runtime, even it is has a devicetree built
in U-Boot. This is because U-Boot may be a second-stage bootloader and its
caller may have a better idea about the hardware available in the machine.
This is the case with a few QEMU boards, for example.

So it makes no sense to have OF_BOARD as a 'choice'. It should be an
option, available with either OF_SEPARATE or OF_EMBED.

This series makes this change, adding various missing devicetree files
(and placeholders) to make the build work.

Note: If board maintainers are able to add their own patch to add the
files, some patches in this series can be dropped.

It also provides a few qemu clean-ups discovered along the way.

Note: This breaks the qemu-riscv64_spl test, which still needs
investigation.

[1] 
https://patchwork.ozlabs.org/project/uboot/patch/20210919215111.3830278-3-...@chromium.org/

Changes in v5:
- Bring into the OF_BOARD series
- Rebase to master and drop mention of OF_PRIOR_STAGE, since removed
- Refer to the 'control' DTB in the first paragraph
- Use QEMU instead of qemu
- Merge RISC-V and ARM patches since they are similar
- Add new patches to clean up fdtdec_setup() and surrounds

Changes in v3:
- Clarify the 'bug' refered to at the top
- Reword 'This means that there' paragraph to explain U-Boot-specific things
- Move to doc/develop/devicetree now that OF_CONTROL is in the docs

Changes in v2:
- Fix typos per Sean (thank you!) and a few others
- Add a 'Use of U-Boot /config node' section
- Drop mention of dm-verity since that actually uses the kernel cmdline
- Explain that OF_BOARD will still work after these changes (in
  'Once this bug is fixed...' paragraph)
- Expand a bit on the reason why the 'Current situation' is bad
- Clarify in a second place that Linux and U-Boot use the same devicetree
  in 'To be clear, while U-Boot...'
- Expand on why we should have rules for other projects in
  'Devicetree in another project'
- Add a comment as to why devicetree in U-Boot is not 'bad design'
- Reword 'in-tree U-Boot devicetree' to 'devicetree source in U-Boot'
- Rewrite 'Devicetree generated on-the-fly in another project' to cover
  points raised on v1
- Add 'Why does U-Boot have its nodes and properties?'
- Add 'Why not have two devicetrees?'

Ilias Apalodimas (1):
  sandbox: Remove OF_HOSTFILE

Simon Glass (25):
  doc: Add documentation about devicetree usage
  arm: qemu: Mention -nographic in the docs
  arm: riscv: qemu: Explain how to extract the generated dt
  arm: qemu: Add a devicetree file for qemu_arm
  arm: qemu: Add a devicetree file for qemu_arm64
  riscv: qemu: Add devicetree files for qemu_riscv32/64
  arm: rpi: Add a devicetree file for rpi_4
  arm: vexpress: Add a devicetree file for juno
  arm: xenguest_arm64: Add a fake devicetree file
  arm: octeontx: Add a fake devicetree file
  arm: xilinx_versal_virt: Add a devicetree file
  arm: bcm7xxx: Add a devicetree file
  arm: qemu-ppce500: Add a devicetree file
  arm: highbank: Add a fake devicetree file
  fdt: Make OF_BOARD a bool option
  Drop CONFIG_BINMAN_STANDALONE_FDT
  doc: Update info on devicetree update
  fdt: Move MULTI_DTB_FIT handling out of fdtdec_setup()
  fdt: Drop #ifdefs with MULTI_DTB_FIT
  fdt: Drop CONFIG_SPL_BUILD check in fdtdec_setup()
  fdt: Drop #ifdef around board_fdt_blob_setup()
  fdt: Use if() for fdtcontroladdr check
  fdt: Drop OF_CONTROL check in fdtdec_setup()
  fdt: Drop remaining preprocessor macros in fdtdec_setup()
  fdt: Don't call board_fdt_blob_setup() without OF_BOARD

 Makefile  |7 +-
 arch/arm/dts/Makefile |   20 +-
 arch/arm/dts/bcm2711-rpi-4-b.dts  | 1958 +
 arch/arm/dts/bcm7xxx.dts  |   15 +
 arch/arm/dts/highbank.dts |   14 +
 arch/arm/dts/juno-r2.dts  | 1038 +++
 arch/arm/dts/octeontx.dts |   14 +
 arch/arm/dts/qemu-arm.dts |  402 +
 arch/arm/dts/qemu-arm64.dts   |  381 
 arch/arm/dts/xenguest-arm64.dts   |   15 +
 arch/arm/dts/xilinx-versal-virt.dts   |  307 
 arch/powerpc/dts/Makefile |1 +
 

[PATCH v5 03/26] arm: qemu: Mention -nographic in the docs

2021-10-25 Thread Simon Glass
Without this option QEMU appears to hang. Add it to avoid confusion.

Signed-off-by: Simon Glass 
---

(no changes since v1)

 doc/board/emulation/qemu-arm.rst | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/doc/board/emulation/qemu-arm.rst b/doc/board/emulation/qemu-arm.rst
index 8d7fda10f15..97b6ec64905 100644
--- a/doc/board/emulation/qemu-arm.rst
+++ b/doc/board/emulation/qemu-arm.rst
@@ -41,14 +41,15 @@ The minimal QEMU command line to get U-Boot up and running 
is:
 
 - For ARM::
 
-qemu-system-arm -machine virt -bios u-boot.bin
+qemu-system-arm -machine virt -nographic -bios u-boot.bin
 
 - For AArch64::
 
-qemu-system-aarch64 -machine virt -cpu cortex-a57 -bios u-boot.bin
+qemu-system-aarch64 -machine virt -nographic -cpu cortex-a57 -bios 
u-boot.bin
 
 Note that for some odd reason qemu-system-aarch64 needs to be explicitly
-told to use a 64-bit CPU or it will boot in 32-bit mode.
+told to use a 64-bit CPU or it will boot in 32-bit mode. The -nographic 
argument
+ensures that output appears on the terminal. Use Ctrl-A X to quit.
 
 Additional persistent U-boot environment support can be added as follows:
 
-- 
2.33.0.1079.g6e70778dc9-goog




Re: [PATCH] hvf: arm: Ignore cache operations on MMIO

2021-10-25 Thread Richard Henderson

On 10/25/21 12:13 PM, Alexander Graf wrote:

+/*
+ * We ran into an instruction that traps for data, but is not
+ * hardware predecoded. This should not ever happen for well
+ * behaved guests. Let's try to see if we can somehow rescue
+ * the situation.
+ */
+
+cpu_synchronize_state(cpu);
+if (cpu_memory_rw_debug(cpu, env->pc, , 4, 0)) {


This isn't correct, since this would be a physical address access, and env->pc 
is virtual.

Phil's idea of cpu_ldl_data may be correct, and cpu_ldl_code may be slightly more so, 
because we got EC_DATAABORT not EC_INSNABORT, which means that the virtual address at 
env->pc is mapped and executable.


However, in the event that there's some sort of race condition in between this data abort 
and hvf stopping all threads for the vm exit, by which the page tables could have been 
modified between here and there, then cpu_ldl_code *could* produce another exception.


In which case the interface that gdbstub uses, cc->memory_rw_debug, will be 
most correct.



@@ -1156,6 +1183,11 @@ int hvf_vcpu_exec(CPUState *cpu)
   hvf_exit->exception.physical_address, isv,
   iswrite, s1ptw, len, srt);
  
+if (!isv) {

+g_assert(hvf_emulate_insn(cpu));
+advance_pc = true;
+break;
+}
  assert(isv);


Ouch.  HVF really passes along an invalid syndrome?  I was expecting that you'd be able to 
avoid all of the instruction parsing and check syndrome.cm (bit 8) for a cache management 
instruction.



r~



[PATCH] hw/arm/virt: Expose empty NUMA nodes through ACPI

2021-10-25 Thread Gavin Shan
The empty NUMA nodes, where no memory resides, aren't exposed
through ACPI SRAT table. It's not user preferred behaviour because
the corresponding memory node devices are missed from the guest
kernel as the following example shows, and memory can't be hot
added to these empty NUMA nodes at later point.

  /home/gavin/sandbox/qemu.main/build/qemu-system-aarch64 \
  -accel kvm -machine virt,gic-version=host   \
  -cpu host -smp 4,sockets=2,cores=2,threads=1\
  -m 1024M,slots=16,maxmem=64G\
  -object memory-backend-ram,id=mem0,size=512M\
  -object memory-backend-ram,id=mem1,size=512M\
  -numa node,nodeid=0,cpus=0-1,memdev=mem0\
  -numa node,nodeid=1,cpus=2-3,memdev=mem1\
  -numa node,nodeid=2 \
  -numa node,nodeid=3 \
 :
  guest# ls /sys/devices/system/node | grep node
  node0
  node1
  node2

This exposes these empty NUMA nodes through ACPI SRAT table. With
this applied, the corresponding memory node devices can be found
from the guest. Note that the hotpluggable capability is explicitly
given to these empty NUMA nodes for sake of completeness.

  guest# ls /sys/devices/system/node | grep node
  node0
  node1
  node2
  node3

Signed-off-by: Gavin Shan 
---
 hw/arm/virt-acpi-build.c | 14 +-
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 674f902652..a4c95b2f64 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -526,6 +526,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
 const CPUArchIdList *cpu_list = mc->possible_cpu_arch_ids(ms);
 AcpiTable table = { .sig = "SRAT", .rev = 3, .oem_id = vms->oem_id,
 .oem_table_id = vms->oem_table_id };
+MemoryAffinityFlags flags;
 
 acpi_table_begin(, table_data);
 build_append_int_noprefix(table_data, 1, 4); /* Reserved */
@@ -547,12 +548,15 @@ build_srat(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
 
 mem_base = vms->memmap[VIRT_MEM].base;
 for (i = 0; i < ms->numa_state->num_nodes; ++i) {
-if (ms->numa_state->nodes[i].node_mem > 0) {
-build_srat_memory(table_data, mem_base,
-  ms->numa_state->nodes[i].node_mem, i,
-  MEM_AFFINITY_ENABLED);
-mem_base += ms->numa_state->nodes[i].node_mem;
+if (ms->numa_state->nodes[i].node_mem) {
+flags = MEM_AFFINITY_ENABLED;
+} else {
+flags = MEM_AFFINITY_ENABLED | MEM_AFFINITY_HOTPLUGGABLE;
 }
+
+build_srat_memory(table_data, mem_base,
+  ms->numa_state->nodes[i].node_mem, i, flags);
+mem_base += ms->numa_state->nodes[i].node_mem;
 }
 
 if (ms->nvdimms_state->is_enabled) {
-- 
2.23.0




Re: [RFC 0/2] tls: add macros for coroutine-safe TLS variables

2021-10-25 Thread Warner Losh
On Mon, Oct 25, 2021 at 10:18 AM Richard Henderson <
richard.hender...@linaro.org> wrote:

> On 10/25/21 7:07 AM, Stefan Hajnoczi wrote:
> > This is a preview of how we can solve the coroutines TLS problem.
> Coroutines
> > re-entered from another thread sometimes see stale TLS values. This
> happens
> > because compilers may cache values across yield points, so a value from
> the
> > previous thread will be used when the coroutine is re-entered in another
> > thread.
>
> I'm not thrilled by this, but I guess it does work.
>
> It could be worthwhile to add some inline asm instead for specific hosts
> -- one
> instruction instead of an out-of-line call.
>
>
> > Serge Guelton developed this technique, see the first patch for details.
> I'm
> > submitting it for discussion before I go ahead with a full conversion of
> the
> > source tree.
> >
> > Todo:
> > - Convert all uses of __thread
> > - Extend checkpatch.pl to reject code that uses __thread
>
> Absolutely not.  *Perhaps* one or two tls variables which are accessible
> by coroutines,
> but there are plenty that have absolutely no relation.  Especially
> everything related to
> user-only execution.
>

I had the same worry. I'd also worry that the hoops that are jumped through
for
coroutines would somehow conflict with the low-level user-only execution
environment. I mean, it should be fine, but I know I'd be cranky if I traced
obscure regressions to being forced to use this construct...

Warner


> r~
>
>


Re: Commit abb0cd93494 breaks -singlestep -d in_asm,cpu with qemu-system-sh4

2021-10-25 Thread BALATON Zoltan

On Mon, 25 Oct 2021, Philippe Mathieu-Daudé wrote:

On 10/25/21 23:16, BALATON Zoltan wrote:

Hello,

Commit abb0cd93494 (accel/tcg: Split out log_cpu_exec) seems to have
broken -singlestep -d in_asm,cpu output with qemu-system-sh4 after a
delay slot.

[...]

However I still don't understand how the delayed branch ends up at
0x8c800964 instead of 0x8c801528 above. Is this ouput not showing some
already translated TBs even with -singlestep -d in_asm,cpu,nochain and
that's why I see those cpu dumps without instructions? What's the
correct way to get a trace of all executed instructions?


IIUC this commit you now need to use both cpu,exec to get the output?


Nope, I get the same even adding exec. I think it now also prints 
registers for already translated instructions where in_asm produces no 
ouput whereas before it was only dumping state when in_asm also had ouput. 
So now we get a lot more cpu state but we don't really know what they are 
for. Not sure what's the use of that, the previous output looked more 
useful.


Regards,
BALATON Zoltan

Re: Looking for advise on debugging a non-boot kernel on qemu-system-sh4

2021-10-25 Thread BALATON Zoltan

On Tue, 26 Oct 2021, John Paul Adrian Glaubitz wrote:

Hi Zoltan!

On 10/23/21 15:22, BALATON Zoltan wrote:

You either need to strip the kernel with "strip vmlinux" or use the image from 
arch/sh/
boot/zImage.


I've actually used that kernel but looked at the wrong uncompressed size, it's 
indeed just
9.2MB when stripped so that should work. I was trying to debug further and 
found two problems:

Commit abb0cd93494 (accel/tcg: Split out log_cpu_exec) seems to have broken 
-singlestep -d in_asm,cpu
output with sh after a delay slot. Since that commit I get:
(...)
This seems to take a wrong turn at the delayed branch and somehow ends up at 
0x8c800964 instead of
0x8c801528 but I'm not sure where to look firther why. I'm cc-ing Richard for 
both the -d cpu and
this hoping he has some more insight.


Shall we open a bug report?


Well, we don't know yet what to put in the bug report apart from there is 
some bug somewhere. That's not too useful. I now understand that the -d 
output is not showing already translated TBs (I knew this but most of the 
time with -singlestep it gives good results anyway) but here it runs the 
loops without further output then we only see the first loop iteration and 
the end result. So the problem is not that it goes to 0x8c800964 as I 
think that's part of the loop for decompressing the kernel but it seems 
something is overwriting 0x8c800964 while it still expects to run code 
from there but I don't know what and why. One way to find could be to 
disassemble the kernel code and compare that with the -d output and check 
every instruction manually but that takes a lot of time or if you have a 
cross debugger you could try attaching that to QEMU and try to debug it 
that way but I don't have that either. Any other idea how to find out what 
is happening?


Regards,
BALATON Zoltan



Re: [PATCH] hw/riscv: opentitan: Fixup the PLIC context addresses

2021-10-25 Thread Alistair Francis
On Mon, Oct 25, 2021 at 2:16 PM Bin Meng  wrote:
>
> On Mon, Oct 25, 2021 at 12:07 PM Alistair Francis
>  wrote:
> >
> > From: Alistair Francis 
> >
> > Fixup the PLIC context address to correctly support the threshold and
> > claim register.
> >
> > Fixes: ef63100648 ("hw/riscv: opentitan: Update to the latest build")
> > Signed-off-by: Alistair Francis 
> > ---
> >  hw/riscv/opentitan.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> >
>
> Reviewed-by: Bin Meng 

Thanks!

Applied to riscv-to-apply.next

Alistair



Re: [PATCH v17 5/8] target/riscv: Print new PM CSRs in QEMU logs

2021-10-25 Thread Alistair Francis
On Tue, Oct 26, 2021 at 3:36 AM Alexey Baturo  wrote:
>
> Signed-off-by: Alexey Baturo 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.c | 7 +++
>  1 file changed, 7 insertions(+)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 6b767a4a0b..16fac64806 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -271,6 +271,13 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, 
> int flags)
>  CSR_MSCRATCH,
>  CSR_SSCRATCH,
>  CSR_SATP,
> +CSR_MMTE,
> +CSR_UPMBASE,
> +CSR_UPMMASK,
> +CSR_SPMBASE,
> +CSR_SPMMASK,
> +CSR_MPMBASE,
> +CSR_MPMMASK,
>  };
>
>  for (int i = 0; i < ARRAY_SIZE(dump_csrs); ++i) {
> --
> 2.30.2
>
>



Re: Looking for advise on debugging a non-boot kernel on qemu-system-sh4

2021-10-25 Thread John Paul Adrian Glaubitz
Hi Zoltan!

On 10/23/21 15:22, BALATON Zoltan wrote:
>> You either need to strip the kernel with "strip vmlinux" or use the image 
>> from arch/sh/
>> boot/zImage.
> 
> I've actually used that kernel but looked at the wrong uncompressed size, 
> it's indeed just
> 9.2MB when stripped so that should work. I was trying to debug further and 
> found two problems:
> 
> Commit abb0cd93494 (accel/tcg: Split out log_cpu_exec) seems to have broken 
> -singlestep -d in_asm,cpu
> output with sh after a delay slot. Since that commit I get:
> (...) 
> This seems to take a wrong turn at the delayed branch and somehow ends up at 
> 0x8c800964 instead of
> 0x8c801528 but I'm not sure where to look firther why. I'm cc-ing Richard for 
> both the -d cpu and
> this hoping he has some more insight.

Shall we open a bug report?

Adrian

-- 
 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer - glaub...@debian.org
`. `'   Freie Universitaet Berlin - glaub...@physik.fu-berlin.de
  `-GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913




Re: Commit abb0cd93494 breaks -singlestep -d in_asm,cpu with qemu-system-sh4

2021-10-25 Thread Philippe Mathieu-Daudé
On 10/25/21 23:16, BALATON Zoltan wrote:
> Hello,
> 
> Commit abb0cd93494 (accel/tcg: Split out log_cpu_exec) seems to have
> broken -singlestep -d in_asm,cpu output with qemu-system-sh4 after a
> delay slot.
[...]
> However I still don't understand how the delayed branch ends up at
> 0x8c800964 instead of 0x8c801528 above. Is this ouput not showing some
> already translated TBs even with -singlestep -d in_asm,cpu,nochain and
> that's why I see those cpu dumps without instructions? What's the
> correct way to get a trace of all executed instructions?

IIUC this commit you now need to use both cpu,exec to get the output?



Commit abb0cd93494 breaks -singlestep -d in_asm,cpu with qemu-system-sh4

2021-10-25 Thread BALATON Zoltan

Hello,

Commit abb0cd93494 (accel/tcg: Split out log_cpu_exec) seems to have 
broken -singlestep -d in_asm,cpu output with qemu-system-sh4 after a delay 
slot. Since that commit I get:


pc=0xac80003e sr=0x50f1 pr=0x fpscr=0x00040001
spc=0x ssr=0x gbr=0x vbr=0x
sgr=0x dbr=0x delayed_pc=0x fpul=0x
r0=0x8cc9d000 r1=0xacc9d000 r2=0xe000 r3=0x8c80
r4=0x r5=0x r6=0x r7=0x
r8=0x r9=0x r10=0x r11=0x
r12=0x r13=0x r14=0x r15=0x
r16=0x r17=0x50f0 r18=0x r19=0x
r20=0x r21=0x r22=0x r23=0x

IN:
0xac800040:  bt.s   0xac80001a

pc=0xac800040 sr=0x50f1 pr=0x fpscr=0x00040001
spc=0x ssr=0x gbr=0x vbr=0x
sgr=0x dbr=0x delayed_pc=0x fpul=0x
r0=0x8cc9cfe0 r1=0xacc9d000 r2=0xe000 r3=0x8c80
r4=0x r5=0x r6=0x r7=0x
r8=0x r9=0x r10=0x r11=0x
r12=0x r13=0x r14=0x r15=0x
r16=0x r17=0x50f0 r18=0x r19=0x
r20=0x r21=0x r22=0x r23=0x

IN:
0xac800042:  add#-32,r1

pc=0xac800042 sr=0x50f1 pr=0x fpscr=0x00040001
spc=0x ssr=0x gbr=0x vbr=0x
sgr=0x dbr=0x delayed_pc=0xac80001a fpul=0x
r0=0x8cc9cfe0 r1=0xacc9d000 r2=0xe000 r3=0x8c80
r4=0x r5=0x r6=0x r7=0x
r8=0x r9=0x r10=0x r11=0x
r12=0x r13=0x r14=0x r15=0x
r16=0x r17=0x50f0 r18=0x r19=0x
r20=0x r21=0x r22=0x r23=0x
in conditional delay slot (delayed_pc=0xac80001a)
pc=0xac80001a sr=0x50f1 pr=0x fpscr=0x00040001
spc=0x ssr=0x gbr=0x vbr=0x
sgr=0x dbr=0x delayed_pc=0xac80001a fpul=0x
r0=0x8cc9cfe0 r1=0xacc9cfe0 r2=0xe000 r3=0x8c80
r4=0x r5=0x r6=0x r7=0x
r8=0x r9=0x r10=0x r11=0x
r12=0x r13=0x r14=0x r15=0x
r16=0x r17=0x50f0 r18=0x r19=0x
r20=0x r21=0x r22=0x r23=0x
pc=0xac80001c sr=0x50f1 pr=0x fpscr=0x00040001
spc=0x ssr=0x gbr=0x vbr=0x
sgr=0x dbr=0x delayed_pc=0xac80001a fpul=0x
r0=0x8cc9cfe0 r1=0xacc9cfe0 r2=0xe000 r3=0x8c80
r4=0x r5=0x r6=0x r7=0x
r8=0x r9=0x r10=0x r11=0x
r12=0x r13=0x r14=0x r15=0x
r16=0x r17=0x50f0 r18=0x r19=0x
r20=0x r21=0x r22=0x r23=0x

After the first delay slot no more in_asm output is printed. Going back to 
the commit before or reverting that commit I get normal output:



IN:
0x8c801574:  bra0x8c801528

pc=0x8c801574 sr=0x50f0 pr=0x8c8013d6 fpscr=0x00040001
spc=0x ssr=0x gbr=0x vbr=0x
sgr=0x dbr=0x delayed_pc=0x8c801594 fpul=0x
r0=0x0007 r1=0x000e r2=0x8cca1084 r3=0xfff9
r4=0x0137 r5=0xfffa r6=0x8cca1570 r7=0x0012
r8=0x8cca1044 r9=0x0011 r10=0x0005 r11=0x00097d36
r12=0x8cca1014 r13=0x000f r14=0x8cc0183c r15=0x8cca0f80
r16=0x r17=0x50f0 r18=0x r19=0x
r20=0x r21=0x r22=0x r23=0x

IN:
0x8c801576:  add#-7,r5

pc=0x8c801576 sr=0x50f0 pr=0x8c8013d6 fpscr=0x00040001
spc=0x ssr=0x gbr=0x vbr=0x
sgr=0x dbr=0x delayed_pc=0x8c801528 fpul=0x
r0=0x0007 r1=0x000e r2=0x8cca1084 r3=0xfff9
r4=0x0137 r5=0xfffa r6=0x8cca1570 r7=0x0012
r8=0x8cca1044 r9=0x0011 r10=0x0005 r11=0x00097d36
r12=0x8cca1014 r13=0x000f r14=0x8cc0183c r15=0x8cca0f80
r16=0x r17=0x50f0 r18=0x r19=0x
r20=0x r21=0x r22=0x r23=0x
in delay slot (delayed_pc=0x8c801528)

IN:
0x8c800964:  .word 0x

pc=0x8c800964 sr=0x50f1 pr=0x8c801654 fpscr=0x00040001
spc=0x ssr=0x gbr=0x vbr=0x
sgr=0x dbr=0x delayed_pc=0x8c800964 fpul=0x
r0=0x001b r1=0xac8009ca r2=0x8cc9956d r3=0xfefe
r4=0x8cca1014 r5=0x r6=0x0142850a r7=0x8cc5001e
r8=0x8cca1044 r9=0x0102 r10=0x r11=0x
r12=0xac8009ca r13=0xac8009aa r14=0x r15=0x8cca0f28
r16=0x r17=0x50f0 r18=0x r19=0x
r20=0x r21=0x r22=0x r23=0x

Re: [PATCH v2] hw/i386: Rename default_bus_bypass_iommu

2021-10-25 Thread Michael S. Tsirkin
On Mon, Oct 25, 2021 at 11:47:38AM +0100, Jean-Philippe Brucker wrote:
> Since commit d8fb7d0969d5 ("vl: switch -M parsing to keyval"), machine
> parameter definitions cannot use underscores, because keyval_dashify()
> transforms them to dashes and the parser doesn't find the parameter.
> 
> This affects option default_bus_bypass_iommu which was introduced in the
> same release:
> 
> $ qemu-system-x86_64 -M q35,default_bus_bypass_iommu=on
> qemu-system-x86_64: Property 'pc-q35-6.1-machine.default-bus-bypass-iommu' 
> not found
> 
> Rename the parameter to "default-bus-bypass-iommu". Passing
> "default_bus_bypass_iommu" is still valid since the underscore are
> transformed automatically.
> 
> Fixes: c9e96b04fc19 ("hw/i386: Add a default_bus_bypass_iommu pc machine 
> option")
> Reviewed-by: Eric Auger 
> Reviewed-by: Philippe Mathieu-Daudé 
> Tested-by: Eric Auger 
> Signed-off-by: Jean-Philippe Brucker 

Reviewed-by: Michael S. Tsirkin 

> ---
> v1: 
> https://lore.kernel.org/qemu-devel/20211013160607.649990-3-jean-phili...@linaro.org/
> v2: no change, added review tag and resending to be merged separately
> from the equivalent arm fix
> ---
>  hw/i386/pc.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index 86223acfd3..54e4c00dce 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -1718,7 +1718,7 @@ static void pc_machine_class_init(ObjectClass *oc, void 
> *data)
>  object_class_property_add_bool(oc, "hpet",
>  pc_machine_get_hpet, pc_machine_set_hpet);
>  
> -object_class_property_add_bool(oc, "default_bus_bypass_iommu",
> +object_class_property_add_bool(oc, "default-bus-bypass-iommu",
>  pc_machine_get_default_bus_bypass_iommu,
>  pc_machine_set_default_bus_bypass_iommu);
>  
> -- 
> 2.33.0




Re: [PATCH] hvf: arm: Ignore cache operations on MMIO

2021-10-25 Thread Philippe Mathieu-Daudé
On 10/25/21 21:13, Alexander Graf wrote:
> Apple's Hypervisor.Framework forwards cache operations as MMIO traps
> into user space. For MMIO however, these have no meaning: There is no
> cache attached to them.
> 
> So let's filter SYS instructions for DATA exits out and treat them as nops.
> 
> This fixes OpenBSD booting as guest.
> 
> Signed-off-by: Alexander Graf 
> Reported-by: AJ Barris 
> ---
>  target/arm/hvf/hvf.c | 32 
>  1 file changed, 32 insertions(+)
> 
> diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
> index bff3e0cde7..46ff4892a7 100644
> --- a/target/arm/hvf/hvf.c
> +++ b/target/arm/hvf/hvf.c
> @@ -1098,6 +1098,33 @@ static void hvf_sync_vtimer(CPUState *cpu)
>  }
>  }
>  
> +static bool hvf_emulate_insn(CPUState *cpu)
> +{
> +ARMCPU *arm_cpu = ARM_CPU(cpu);
> +CPUARMState *env = _cpu->env;
> +uint32_t insn;
> +
> +/*
> + * We ran into an instruction that traps for data, but is not
> + * hardware predecoded. This should not ever happen for well
> + * behaved guests. Let's try to see if we can somehow rescue
> + * the situation.
> + */
> +
> +cpu_synchronize_state(cpu);
> +if (cpu_memory_rw_debug(cpu, env->pc, , 4, 0)) {

What about using cpu_ldl_data()?

> +/* Could not read the instruction */
> +return false;
> +}
> +
> +if ((insn & 0xffc0) == 0xd500) {

Could there be an endianess issue here?

Otherwise,
Reviewed-by: Philippe Mathieu-Daudé 

> +/* MSR/MRS/SYS/SYSL - happens for cache ops which are nops on data */
> +return true;
> +}
> +
> +return false;
> +}
> +
>  int hvf_vcpu_exec(CPUState *cpu)
>  {
>  ARMCPU *arm_cpu = ARM_CPU(cpu);
> @@ -1156,6 +1183,11 @@ int hvf_vcpu_exec(CPUState *cpu)
>   hvf_exit->exception.physical_address, isv,
>   iswrite, s1ptw, len, srt);
>  
> +if (!isv) {
> +g_assert(hvf_emulate_insn(cpu));
> +advance_pc = true;
> +break;
> +}
>  assert(isv);
>  
>  if (iswrite) {
> 




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

2021-10-25 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 
---
 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 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 

[ PATCH v3 04/10] target/riscv: pmu: Make number of counters configurable

2021-10-25 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 
---
 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 3b55f5ed0036..aec94101a4c0 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -598,7 +598,7 @@ static Property riscv_cpu_properties[] = {
 DEFINE_PROP_BOOL("x-zbs", RISCVCPU, cfg.ext_zbs, false),
 DEFINE_PROP_BOOL("x-h", RISCVCPU, cfg.ext_h, false),
 DEFINE_PROP_BOOL("x-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_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index ebc1a8754032..d0a722e7cbe1 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -294,10 +294,10 @@ struct RISCVCPU {
 bool ext_zbb;
 bool ext_zbc;
 bool ext_zbs;
-bool ext_pmu;
 bool ext_ifencei;
 bool ext_icsr;
 
+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 c486eeaffeb8..a7249eaf917f 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -57,15 +57,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_is_32bit(env) && 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;
+}
+
+return RISCV_EXCP_NONE;
+#endif
+}
+
 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_CYCLE;
+bool brv32 = riscv_cpu_is_32bit(env);
+
+if (brv32 && csrno >= CSR_CYCLEH) {
+/* Offset for RV32 hpmcounternh counters */
+base_csrno += 0x80;
+}
+ctr_index = csrno - base_csrno;
 
-if (!cpu->cfg.ext_pmu) {
-/* The Counters extensions is not enabled */
+if (!cpu->cfg.pmu_num || ctr_index >= (cpu->cfg.pmu_num + 3)) {
+/* The PMU is not enabled or counter is out of range */
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
@@ -93,7 +123,7 @@ static RISCVException ctr(CPURISCVState *env, int csrno)
 }
 break;
 }
-if (riscv_cpu_is_32bit(env)) {
+if (brv32) {
 switch (csrno) {
 case CSR_CYCLEH:
 if (!get_field(env->mcounteren, COUNTEREN_CY)) {
@@ -148,7 +178,7 @@ static RISCVException ctr(CPURISCVState *env, int csrno)
 }
 break;
 }
-if (riscv_cpu_is_32bit(env)) {
+if (brv32) {
 switch (csrno) {
 case CSR_CYCLEH:
 if (!get_field(env->hcounteren, COUNTEREN_CY) &&
@@ -1720,35 +1750,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,read_zero },
-[CSR_MHPMCOUNTER15]  = { "mhpmcounter15",  any,read_zero },
-

[ PATCH v3 01/10] target/riscv: Fix PMU CSR predicate function

2021-10-25 Thread Atish Patra
The predicate function calculates the counter index incorrectly for
hpmcounterx. Fix the counter index to reflect correct CSR number.

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 23fbbd32162a..1ec776013435 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -89,8 +89,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;
@@ -116,8 +117,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.31.1




Re: [PATCH 6/9] qapi: Generalize command policy checking

2021-10-25 Thread John Snow
On Mon, Oct 25, 2021 at 1:25 AM Markus Armbruster  wrote:

> The code to check command policy can see special feature flag
> 'deprecated' as command flag QCO_DEPRECATED.  I want to make feature
> flag 'unstable' visible there as well, so I can add policy for it.
>
> To let me make it visible, add member @special_features (a bitset of
> QapiSpecialFeature) to QmpCommand, and adjust the generator to pass it
> through qmp_register_command().  Then replace "QCO_DEPRECATED in
> @flags" by QAPI_DEPRECATED in @special_features", and drop
> QCO_DEPRECATED.
>
> Signed-off-by: Markus Armbruster 
> ---
>  include/qapi/qmp/dispatch.h  | 5 +++--
>  monitor/misc.c   | 6 --
>  qapi/qmp-dispatch.c  | 2 +-
>  qapi/qmp-registry.c  | 4 +++-
>  storage-daemon/qemu-storage-daemon.c | 3 ++-
>  scripts/qapi/commands.py | 9 -
>  6 files changed, 17 insertions(+), 12 deletions(-)
>
> diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h
> index 0ce88200b9..1e4240fd0d 100644
> --- a/include/qapi/qmp/dispatch.h
> +++ b/include/qapi/qmp/dispatch.h
> @@ -25,7 +25,6 @@ typedef enum QmpCommandOptions
>  QCO_ALLOW_OOB =  (1U << 1),
>  QCO_ALLOW_PRECONFIG   =  (1U << 2),
>  QCO_COROUTINE =  (1U << 3),
> -QCO_DEPRECATED=  (1U << 4),
>  } QmpCommandOptions;
>
>  typedef struct QmpCommand
> @@ -34,6 +33,7 @@ typedef struct QmpCommand
>  /* Runs in coroutine context if QCO_COROUTINE is set */
>  QmpCommandFunc *fn;
>  QmpCommandOptions options;
> +unsigned special_features;
>  QTAILQ_ENTRY(QmpCommand) node;
>  bool enabled;
>  const char *disable_reason;
> @@ -42,7 +42,8 @@ typedef struct QmpCommand
>  typedef QTAILQ_HEAD(QmpCommandList, QmpCommand) QmpCommandList;
>
>  void qmp_register_command(QmpCommandList *cmds, const char *name,
> -  QmpCommandFunc *fn, QmpCommandOptions options);
> +  QmpCommandFunc *fn, QmpCommandOptions options,
> +  unsigned special_features);
>  const QmpCommand *qmp_find_command(const QmpCommandList *cmds,
> const char *name);
>  void qmp_disable_command(QmpCommandList *cmds, const char *name,
> diff --git a/monitor/misc.c b/monitor/misc.c
> index 3556b177f6..c2d227a07c 100644
> --- a/monitor/misc.c
> +++ b/monitor/misc.c
> @@ -230,11 +230,13 @@ static void monitor_init_qmp_commands(void)
>
>  qmp_init_marshal(_commands);
>
> -qmp_register_command(_commands, "device_add", qmp_device_add, 0);
> +qmp_register_command(_commands, "device_add",
> + qmp_device_add, 0, 0);
>
>  QTAILQ_INIT(_cap_negotiation_commands);
>  qmp_register_command(_cap_negotiation_commands,
> "qmp_capabilities",
> - qmp_marshal_qmp_capabilities,
> QCO_ALLOW_PRECONFIG);
> + qmp_marshal_qmp_capabilities,
> + QCO_ALLOW_PRECONFIG, 0);
>  }
>
>  /* Set the current CPU defined by the user. Callers must hold BQL. */
> diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
> index 7e943a0af5..8cca18c891 100644
> --- a/qapi/qmp-dispatch.c
> +++ b/qapi/qmp-dispatch.c
> @@ -176,7 +176,7 @@ QDict *qmp_dispatch(const QmpCommandList *cmds,
> QObject *request,
>"The command %s has not been found", command);
>  goto out;
>  }
> -if (cmd->options & QCO_DEPRECATED) {
> +if (cmd->special_features & 1u << QAPI_DEPRECATED) {
>  switch (compat_policy.deprecated_input) {
>  case COMPAT_POLICY_INPUT_ACCEPT:
>  break;
> diff --git a/qapi/qmp-registry.c b/qapi/qmp-registry.c
> index f78c064aae..485bc5e6fc 100644
> --- a/qapi/qmp-registry.c
> +++ b/qapi/qmp-registry.c
> @@ -16,7 +16,8 @@
>  #include "qapi/qmp/dispatch.h"
>
>  void qmp_register_command(QmpCommandList *cmds, const char *name,
> -  QmpCommandFunc *fn, QmpCommandOptions options)
> +  QmpCommandFunc *fn, QmpCommandOptions options,
> +  unsigned special_features)
>  {
>  QmpCommand *cmd = g_malloc0(sizeof(*cmd));
>
> @@ -27,6 +28,7 @@ void qmp_register_command(QmpCommandList *cmds, const
> char *name,
>  cmd->fn = fn;
>  cmd->enabled = true;
>  cmd->options = options;
> +cmd->special_features = special_features;
>  QTAILQ_INSERT_TAIL(cmds, cmd, node);
>  }
>
> diff --git a/storage-daemon/qemu-storage-daemon.c
> b/storage-daemon/qemu-storage-daemon.c
> index 10a1a33761..52cf17e8ac 100644
> --- a/storage-daemon/qemu-storage-daemon.c
> +++ b/storage-daemon/qemu-storage-daemon.c
> @@ -146,7 +146,8 @@ static void init_qmp_commands(void)
>
>  QTAILQ_INIT(_cap_negotiation_commands);
>  qmp_register_command(_cap_negotiation_commands,
> "qmp_capabilities",
> - qmp_marshal_qmp_capabilities,
> QCO_ALLOW_PRECONFIG);
> + 

Re: [PATCH v4 04/19] host-utils: add unit tests for divu128/divs128

2021-10-25 Thread Richard Henderson

On 10/25/21 12:11 PM, Luis Pires wrote:

Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
  tests/unit/meson.build   |   1 +
  tests/unit/test-div128.c | 197 +++
  2 files changed, 198 insertions(+)
  create mode 100644 tests/unit/test-div128.c


I'm queuing patches 1-4 into tcg-next.


r~



Re: [PATCH 5/9] qapi: Generalize struct member policy checking

2021-10-25 Thread John Snow
On Mon, Oct 25, 2021 at 1:25 AM Markus Armbruster  wrote:

> The generated visitor functions call visit_deprecated_accept() and
> visit_deprecated() when visiting a struct member with special feature
> flag 'deprecated'.  This makes the feature flag visible to the actual
> visitors.  I want to make feature flag 'unstable' visible there as
> well, so I can add policy for it.
>
> To let me make it visible, replace these functions by
> visit_policy_reject() and visit_policy_skip(), which take the member's
> special features as an argument.  Note that the new functions have the
> opposite sense, i.e. the return value flips.
>
> Signed-off-by: Markus Armbruster 
> ---
>  include/qapi/visitor-impl.h   |  6 --
>  include/qapi/visitor.h| 17 +
>  qapi/qapi-forward-visitor.c   | 16 +---
>  qapi/qapi-visit-core.c| 22 --
>  qapi/qobject-input-visitor.c  | 15 ++-
>  qapi/qobject-output-visitor.c |  9 ++---
>  qapi/trace-events |  4 ++--
>  scripts/qapi/visit.py | 14 +++---
>  8 files changed, 63 insertions(+), 40 deletions(-)
>
> diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
> index 72b6537bef..2badec5ba4 100644
> --- a/include/qapi/visitor-impl.h
> +++ b/include/qapi/visitor-impl.h
> @@ -114,10 +114,12 @@ struct Visitor
>  void (*optional)(Visitor *v, const char *name, bool *present);
>
>  /* Optional */
> -bool (*deprecated_accept)(Visitor *v, const char *name, Error **errp);
> +bool (*policy_reject)(Visitor *v, const char *name,
> +  unsigned special_features, Error **errp);
>
>  /* Optional */
> -bool (*deprecated)(Visitor *v, const char *name);
> +bool (*policy_skip)(Visitor *v, const char *name,
> +unsigned special_features);
>
>  /* Must be set */
>  VisitorType type;
> diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
> index dcb96018a9..d53a84c9ba 100644
> --- a/include/qapi/visitor.h
> +++ b/include/qapi/visitor.h
> @@ -461,22 +461,31 @@ void visit_end_alternate(Visitor *v, void **obj);
>  bool visit_optional(Visitor *v, const char *name, bool *present);
>
>  /*
> - * Should we reject deprecated member @name?
> + * Should we reject member @name due to policy?
> + *
> + * @special_features is the member's special features encoded as a
> + * bitset of QapiSpecialFeature.
>   *
>   * @name must not be NULL.  This function is only useful between
>   * visit_start_struct() and visit_end_struct(), since only objects
>   * have deprecated members.
>   */
> -bool visit_deprecated_accept(Visitor *v, const char *name, Error **errp);
> +bool visit_policy_reject(Visitor *v, const char *name,
> + unsigned special_features, Error **errp);
>
>  /*
> - * Should we visit deprecated member @name?
> + *
> + * Should we skip member @name due to policy?
> + *
> + * @special_features is the member's special features encoded as a
> + * bitset of QapiSpecialFeature.
>   *
>   * @name must not be NULL.  This function is only useful between
>   * visit_start_struct() and visit_end_struct(), since only objects
>   * have deprecated members.
>   */
> -bool visit_deprecated(Visitor *v, const char *name);
> +bool visit_policy_skip(Visitor *v, const char *name,
> +   unsigned special_features);
>
>  /*
>   * Set policy for handling deprecated management interfaces.
> diff --git a/qapi/qapi-forward-visitor.c b/qapi/qapi-forward-visitor.c
> index a4b111e22a..25d098aa8a 100644
> --- a/qapi/qapi-forward-visitor.c
> +++ b/qapi/qapi-forward-visitor.c
> @@ -246,25 +246,27 @@ static void forward_field_optional(Visitor *v, const
> char *name, bool *present)
>  visit_optional(ffv->target, name, present);
>  }
>
> -static bool forward_field_deprecated_accept(Visitor *v, const char *name,
> -Error **errp)
> +static bool forward_field_policy_reject(Visitor *v, const char *name,
> +unsigned special_features,
> +Error **errp)
>  {
>  ForwardFieldVisitor *ffv = to_ffv(v);
>
>  if (!forward_field_translate_name(ffv, , errp)) {
>  return false;
>  }
> -return visit_deprecated_accept(ffv->target, name, errp);
> +return visit_policy_reject(ffv->target, name, special_features, errp);
>  }
>
> -static bool forward_field_deprecated(Visitor *v, const char *name)
> +static bool forward_field_policy_skip(Visitor *v, const char *name,
> +  unsigned special_features)
>  {
>  ForwardFieldVisitor *ffv = to_ffv(v);
>
>  if (!forward_field_translate_name(ffv, , NULL)) {
>  return false;
>  }
> -return visit_deprecated(ffv->target, name);
> +return visit_policy_skip(ffv->target, name, special_features);
>  }
>
>  static void forward_field_complete(Visitor *v, void *opaque)
> @@ -313,8 

[PATCH v4 19/19] target/ppc: Move ddedpd[q], denbcd[q], dscli[q], dscri[q] to decodetree

2021-10-25 Thread Luis Pires
Move the following instructions to decodetree:
ddedpd:  DFP Decode DPD To BCD
ddedpdq: DFP Decode DPD To BCD Quad
denbcd:  DFP Encode BCD To DPD
denbcdq: DFP Encode BCD To DPD Quad
dscli:   DFP Shift Significand Left Immediate
dscliq:  DFP Shift Significand Left Immediate Quad
dscri:   DFP Shift Significand Right Immediate
dscriq:  DFP Shift Significand Right Immediate Quad

Also deleted dfp-ops.c.inc, now that all PPC DFP instructions were
moved to decodetree.

Signed-off-by: Luis Pires 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
---
 target/ppc/dfp_helper.c | 16 -
 target/ppc/helper.h | 16 -
 target/ppc/insn32.decode| 28 +++
 target/ppc/translate.c  |  2 --
 target/ppc/translate/dfp-impl.c.inc | 53 +
 target/ppc/translate/dfp-ops.c.inc  | 40 --
 6 files changed, 68 insertions(+), 87 deletions(-)
 delete mode 100644 target/ppc/translate/dfp-ops.c.inc

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index d950d0d3fc..0d01ac3de0 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -1131,8 +1131,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b,  \
 set_dfp##size(t, );\
 }
 
-DFP_HELPER_DEDPD(ddedpd, 64)
-DFP_HELPER_DEDPD(ddedpdq, 128)
+DFP_HELPER_DEDPD(DDEDPD, 64)
+DFP_HELPER_DEDPD(DDEDPDQ, 128)
 
 static inline uint8_t dfp_get_bcd_digit_64(ppc_vsr_t *t, unsigned n)
 {
@@ -1199,8 +1199,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b, \
 set_dfp##size(t, );   \
 }
 
-DFP_HELPER_ENBCD(denbcd, 64)
-DFP_HELPER_ENBCD(denbcdq, 128)
+DFP_HELPER_ENBCD(DENBCD, 64)
+DFP_HELPER_ENBCD(DENBCDQ, 128)
 
 #define DFP_HELPER_XEX(op, size)   \
 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b) \
@@ -1387,7 +1387,7 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *a,\
 set_dfp##size(t, );  \
 }
 
-DFP_HELPER_SHIFT(dscli, 64, 1)
-DFP_HELPER_SHIFT(dscliq, 128, 1)
-DFP_HELPER_SHIFT(dscri, 64, 0)
-DFP_HELPER_SHIFT(dscriq, 128, 0)
+DFP_HELPER_SHIFT(DSCLI, 64, 1)
+DFP_HELPER_SHIFT(DSCLIQ, 128, 1)
+DFP_HELPER_SHIFT(DSCRI, 64, 0)
+DFP_HELPER_SHIFT(DSCRIQ, 128, 0)
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 4c2a349ce6..6fa3e15fe9 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -738,18 +738,18 @@ DEF_HELPER_3(DCFFIXQQ, void, env, fprp, avr)
 DEF_HELPER_3(DCTFIX, void, env, fprp, fprp)
 DEF_HELPER_3(DCTFIXQ, void, env, fprp, fprp)
 DEF_HELPER_3(DCTFIXQQ, void, env, avr, fprp)
-DEF_HELPER_4(ddedpd, void, env, fprp, fprp, i32)
-DEF_HELPER_4(ddedpdq, void, env, fprp, fprp, i32)
-DEF_HELPER_4(denbcd, void, env, fprp, fprp, i32)
-DEF_HELPER_4(denbcdq, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DDEDPD, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DDEDPDQ, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DENBCD, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DENBCDQ, void, env, fprp, fprp, i32)
 DEF_HELPER_3(DXEX, void, env, fprp, fprp)
 DEF_HELPER_3(DXEXQ, void, env, fprp, fprp)
 DEF_HELPER_4(DIEX, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(DIEXQ, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dscri, void, env, fprp, fprp, i32)
-DEF_HELPER_4(dscriq, void, env, fprp, fprp, i32)
-DEF_HELPER_4(dscli, void, env, fprp, fprp, i32)
-DEF_HELPER_4(dscliq, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DSCRI, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DSCRIQ, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DSCLI, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DSCLIQ, void, env, fprp, fprp, i32)
 
 DEF_HELPER_1(tbegin, void, env)
 DEF_HELPER_FLAGS_1(fixup_thrm, TCG_CALL_NO_RWG, void, env)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 2ce8b0ab95..6aec1c0728 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -74,6 +74,16 @@
 _bfl  bf l:bool ra rb
 @X_bfl  .. bf:3 - l:1 ra:5 rb:5 ..- _bfl
 
+_tb_sp_rc rt rb sp rc:bool
+@X_tb_sp_rc .. rt:5 sp:2 ... rb:5 .. rc:1   _tb_sp_rc
+
+@X_tbp_sp_rc.. 0 sp:2 ... 0 .. rc:1 _tb_sp_rc 
rt=%x_frtp rb=%x_frbp
+
+_tb_s_rc  rt rb s:bool rc:bool
+@X_tb_s_rc  .. rt:5 s:1  rb:5 .. rc:1   _tb_s_rc
+
+@X_tbp_s_rc .. 0 s:1  0 .. rc:1 _tb_s_rc 
rt=%x_frtp rb=%x_frbp
+
 _frtp_vrb frtp vrb
 @X_frtp_vrb .. 0 . vrb:5 .. .   _frtp_vrb 
frtp=%x_frtp
 
@@ -86,6 +96,12 @@
 %z22_frap   17:4 !function=times_2
 @Z22_bf_frap.. bf:3 .. 0 dm:6 . .   _bf_fra 
fra=%z22_frap
 
+_ta_sh_rc   rt ra sh rc:bool
+@Z22_ta_sh_rc   .. rt:5 ra:5 sh:6 . rc:1_ta_sh_rc
+
+%z22_frtp   22:4 !function=times_2
+@Z22_tap_sh_rc  .. 0 0 sh:6 

Re: [PATCH v4 02/17] qemu/int128: addition of a few 128-bit operations

2021-10-25 Thread Richard Henderson

On 10/25/21 8:47 AM, Philippe Mathieu-Daudé wrote:

On 10/25/21 14:28, Frédéric Pétrot wrote:

Addition of not, xor, div and rem on 128-bit integers, used in particular
within div/rem and csr helpers for computations on 128-bit registers in
the 128-bit riscv target.

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


If you ever have to respin, please split the logical operations in
one patch and the div/rem in another.


I have pulled out these logicals into a separate patch and applied to tcg-next.  I'll 
handle division relative to the PPC64 DFP patch set.



r~




Re: [PATCH v4 01/17] exec/memop: Rename MO_Q definition as MO_UQ and add MO_UO

2021-10-25 Thread Richard Henderson

On 10/25/21 5:28 AM, Frédéric Pétrot wrote:

-MO_LEQ   = MO_LE | MO_Q,
+MO_LEQ   = MO_LE | MO_UQ,


Again, I mentioned that this would require renaming as well...


-MO_BEQ   = MO_BE | MO_Q,
+MO_BEQ   = MO_BE | MO_UQ,


... and this...


+MO_TEUQ  = MO_TE | MO_UQ,
  MO_TESW  = MO_TE | MO_SW,
  MO_TESL  = MO_TE | MO_SL,
-MO_TEQ   = MO_TE | MO_Q,
+MO_TEQ   = MO_TE | MO_UQ,
+MO_TESQ  = MO_TE | MO_SQ,
+MO_TEO   = MO_TE | MO_UO,


... but you only did MO_TEQ to MO_TEUQ.

Please split the renames from the additions.


r~



[PATCH v4 18/19] target/ppc: Move dct{dp, qpq}, dr{sp, dpq}, dc{f, t}fix[q], dxex[q] to decodetree

2021-10-25 Thread Luis Pires
Move the following instructions to decodetree:
dctdp:   DFP Convert To DFP Long
dctqpq:  DFP Convert To DFP Extended
drsp:DFP Round To DFP Short
drdpq:   DFP Round To DFP Long
dcffix:  DFP Convert From Fixed
dcffixq: DFP Convert From Fixed Quad
dctfix:  DFP Convert To Fixed
dctfixq: DFP Convert To Fixed Quad
dxex:DFP Extract Biased Exponent
dxexq:   DFP Extract Biased Exponent Quad

Signed-off-by: Luis Pires 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
---
 target/ppc/dfp_helper.c | 20 +--
 target/ppc/helper.h | 20 +--
 target/ppc/insn32.decode| 23 
 target/ppc/translate/dfp-impl.c.inc | 54 ++---
 target/ppc/translate/dfp-ops.c.inc  | 22 
 5 files changed, 69 insertions(+), 70 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index a50a73d3c0..d950d0d3fc 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -885,7 +885,7 @@ static void RINTN_PPs(struct PPC_DFP *dfp)
 DFP_HELPER_RINT(DRINTN, RINTN_PPs, 64)
 DFP_HELPER_RINT(DRINTNQ, RINTN_PPs, 128)
 
-void helper_dctdp(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
+void helper_DCTDP(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
 struct PPC_DFP dfp;
 ppc_vsr_t vb;
@@ -901,7 +901,7 @@ void helper_dctdp(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b)
 dfp_set_FPRF_from_FRT();
 }
 
-void helper_dctqpq(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
+void helper_DCTQPQ(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
 struct PPC_DFP dfp;
 ppc_vsr_t vb;
@@ -916,7 +916,7 @@ void helper_dctqpq(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b)
 set_dfp128(t, );
 }
 
-void helper_drsp(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
+void helper_DRSP(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
 struct PPC_DFP dfp;
 uint32_t t_short = 0;
@@ -934,7 +934,7 @@ void helper_drsp(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b)
 set_dfp64(t, );
 }
 
-void helper_drdpq(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
+void helper_DRDPQ(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
 struct PPC_DFP dfp;
 dfp_prepare_decimal128(, 0, b, env);
@@ -972,8 +972,8 @@ static void CFFIX_PPs(struct PPC_DFP *dfp)
 dfp_check_for_XX(dfp);
 }
 
-DFP_HELPER_CFFIX(dcffix, 64)
-DFP_HELPER_CFFIX(dcffixq, 128)
+DFP_HELPER_CFFIX(DCFFIX, 64)
+DFP_HELPER_CFFIX(DCFFIXQ, 128)
 
 void helper_DCFFIXQQ(CPUPPCState *env, ppc_fprp_t *t, ppc_avr_t *b)
 {
@@ -1022,8 +1022,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b)  \
 set_dfp64(t, );\
 }
 
-DFP_HELPER_CTFIX(dctfix, 64)
-DFP_HELPER_CTFIX(dctfixq, 128)
+DFP_HELPER_CTFIX(DCTFIX, 64)
+DFP_HELPER_CTFIX(DCTFIXQ, 128)
 
 void helper_DCTFIXQQ(CPUPPCState *env, ppc_avr_t *t, ppc_fprp_t *b)
 {
@@ -1233,8 +1233,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b) \
 }  \
 }
 
-DFP_HELPER_XEX(dxex, 64)
-DFP_HELPER_XEX(dxexq, 128)
+DFP_HELPER_XEX(DXEX, 64)
+DFP_HELPER_XEX(DXEXQ, 128)
 
 static void dfp_set_raw_exp_64(ppc_vsr_t *t, uint64_t raw)
 {
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index cb05cc168c..4c2a349ce6 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -728,22 +728,22 @@ DEF_HELPER_5(DRINTX, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DRINTXQ, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DRINTN, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DRINTNQ, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_3(dctdp, void, env, fprp, fprp)
-DEF_HELPER_3(dctqpq, void, env, fprp, fprp)
-DEF_HELPER_3(drsp, void, env, fprp, fprp)
-DEF_HELPER_3(drdpq, void, env, fprp, fprp)
-DEF_HELPER_3(dcffix, void, env, fprp, fprp)
-DEF_HELPER_3(dcffixq, void, env, fprp, fprp)
+DEF_HELPER_3(DCTDP, void, env, fprp, fprp)
+DEF_HELPER_3(DCTQPQ, void, env, fprp, fprp)
+DEF_HELPER_3(DRSP, void, env, fprp, fprp)
+DEF_HELPER_3(DRDPQ, void, env, fprp, fprp)
+DEF_HELPER_3(DCFFIX, void, env, fprp, fprp)
+DEF_HELPER_3(DCFFIXQ, void, env, fprp, fprp)
 DEF_HELPER_3(DCFFIXQQ, void, env, fprp, avr)
-DEF_HELPER_3(dctfix, void, env, fprp, fprp)
-DEF_HELPER_3(dctfixq, void, env, fprp, fprp)
+DEF_HELPER_3(DCTFIX, void, env, fprp, fprp)
+DEF_HELPER_3(DCTFIXQ, void, env, fprp, fprp)
 DEF_HELPER_3(DCTFIXQQ, void, env, avr, fprp)
 DEF_HELPER_4(ddedpd, void, env, fprp, fprp, i32)
 DEF_HELPER_4(ddedpdq, void, env, fprp, fprp, i32)
 DEF_HELPER_4(denbcd, void, env, fprp, fprp, i32)
 DEF_HELPER_4(denbcdq, void, env, fprp, fprp, i32)
-DEF_HELPER_3(dxex, void, env, fprp, fprp)
-DEF_HELPER_3(dxexq, void, env, fprp, fprp)
+DEF_HELPER_3(DXEX, void, env, fprp, fprp)
+DEF_HELPER_3(DXEXQ, void, env, fprp, fprp)
 DEF_HELPER_4(DIEX, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(DIEXQ, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(dscri, void, env, fprp, fprp, i32)
diff --git 

[ PATCH v3 09/10] target/riscv: Add few cache related PMU events

2021-10-25 Thread 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 
---
 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 d41d5cd27c14..66cdfca547cc 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)
 {
@@ -750,6 +753,28 @@ void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr 
addr,
 }
 #endif /* !CONFIG_USER_ONLY */
 
+
+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)
@@ -847,6 +872,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.31.1




[ PATCH v3 05/10] target/riscv: Implement mcountinhibit CSR

2021-10-25 Thread Atish Patra
As per the privilege specification v1.11, mcountinhibit allows to start/stop
a pmu counter selectively.

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  |  5 +++--
 4 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index d0a722e7cbe1..b421eefa623f 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -217,6 +217,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 999187a9ee2d..72b1485e621f 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -275,6 +275,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 a7249eaf917f..faf02e12ec34 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -766,6 +766,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)
 {
@@ -1780,6 +1802,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 16a08302daff..20dea0843604 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -140,8 +140,8 @@ static const VMStateDescription vmstate_hyper = {
 
 const VMStateDescription vmstate_riscv_cpu = {
 .name = "cpu",
-.version_id = 2,
-.minimum_version_id = 2,
+.version_id = 3,
+.minimum_version_id = 3,
 .fields = (VMStateField[]) {
 VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
 VMSTATE_UINT64_ARRAY(env.fpr, RISCVCPU, 32),
@@ -177,6 +177,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.31.1




[PATCH v4 17/19] target/ppc: Move dqua[q], drrnd[q] to decodetree

2021-10-25 Thread Luis Pires
Move the following instructions to decodetree:
dqua:   DFP Quantize
dquaq:  DFP Quantize Quad
drrnd:  DFP Reround
drrndq: DFP Reround Quad

Signed-off-by: Luis Pires 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
---
 target/ppc/dfp_helper.c |  8 ++---
 target/ppc/helper.h |  8 ++---
 target/ppc/insn32.decode| 18 +--
 target/ppc/translate/dfp-impl.c.inc | 50 +
 target/ppc/translate/dfp-ops.c.inc  | 25 ---
 5 files changed, 47 insertions(+), 62 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index df3e6c7cb1..a50a73d3c0 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -769,8 +769,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *a,\
 set_dfp##size(t, );  \
 }
 
-DFP_HELPER_QUA(dqua, 64)
-DFP_HELPER_QUA(dquaq, 128)
+DFP_HELPER_QUA(DQUA, 64)
+DFP_HELPER_QUA(DQUAQ, 128)
 
 static void _dfp_reround(uint8_t rmc, int32_t ref_sig, int32_t xmax,
  struct PPC_DFP *dfp)
@@ -847,8 +847,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *a,\
 set_dfp##size(t, );  \
 }
 
-DFP_HELPER_RRND(drrnd, 64)
-DFP_HELPER_RRND(drrndq, 128)
+DFP_HELPER_RRND(DRRND, 64)
+DFP_HELPER_RRND(DRRNDQ, 128)
 
 #define DFP_HELPER_RINT(op, postprocs, size)   
\
 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b,   
\
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 520cce8378..cb05cc168c 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -720,10 +720,10 @@ DEF_HELPER_3(DTSTSFI, i32, env, i32, fprp)
 DEF_HELPER_3(DTSTSFIQ, i32, env, i32, fprp)
 DEF_HELPER_5(DQUAI, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DQUAIQ, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(dqua, void, env, fprp, fprp, fprp, i32)
-DEF_HELPER_5(dquaq, void, env, fprp, fprp, fprp, i32)
-DEF_HELPER_5(drrnd, void, env, fprp, fprp, fprp, i32)
-DEF_HELPER_5(drrndq, void, env, fprp, fprp, fprp, i32)
+DEF_HELPER_5(DQUA, void, env, fprp, fprp, fprp, i32)
+DEF_HELPER_5(DQUAQ, void, env, fprp, fprp, fprp, i32)
+DEF_HELPER_5(DRRND, void, env, fprp, fprp, fprp, i32)
+DEF_HELPER_5(DRRNDQ, void, env, fprp, fprp, fprp, i32)
 DEF_HELPER_5(DRINTX, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DRINTXQ, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DRINTN, void, env, fprp, fprp, i32, i32)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index f0e17580e0..86dbdada47 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -77,11 +77,19 @@
 %z22_frap   17:4 !function=times_2
 @Z22_bf_frap.. bf:3 .. 0 dm:6 . .   _bf_fra 
fra=%z22_frap
 
-_tb frt frb r:bool rmc rc:bool
-@Z23_tb .. frt:5  r:1 frb:5 rmc:2  rc:1 _tb
+_tabfrt fra frb rmc rc:bool
+@Z23_tab.. frt:5 fra:5 frb:5 rmc:2  rc:1_tab
 
 %z23_frtp   22:4 !function=times_2
+%z23_frap   17:4 !function=times_2
 %z23_frbp   12:4 !function=times_2
+@Z23_tabp   .. 0 0 0 rmc:2  rc:1_tab 
frt=%z23_frtp fra=%z23_frap frb=%z23_frbp
+
+@Z23_tp_a_bp.. 0 fra:5 0 rmc:2  rc:1_tab 
frt=%z23_frtp frb=%z23_frbp
+
+_tb frt frb r:bool rmc rc:bool
+@Z23_tb .. frt:5  r:1 frb:5 rmc:2  rc:1 _tb
+
 @Z23_tbp.. 0  r:1 0 rmc:2  rc:1 _tb 
frt=%z23_frtp frb=%z23_frbp
 
 _te_tb  te frt frb rmc rc:bool
@@ -211,6 +219,12 @@ DTSTSFIQ11 ... - .. . 1010100011 -  
@X_bf_uim_bp
 DQUAI   111011 . . . .. 0111 .  @Z23_te_tb
 DQUAIQ  11 . . . .. 0111 .  @Z23_te_tbp
 
+DQUA111011 . . . .. 0011 .  @Z23_tab
+DQUAQ   11 . . . .. 0011 .  @Z23_tabp
+
+DRRND   111011 . . . .. 00100011 .  @Z23_tab
+DRRNDQ  11 . . . .. 00100011 .  @Z23_tp_a_bp
+
 DRINTX  111011 .  . . .. 01100011 . @Z23_tb
 DRINTXQ 11 .  . . .. 01100011 . @Z23_tbp
 
diff --git a/target/ppc/translate/dfp-impl.c.inc 
b/target/ppc/translate/dfp-impl.c.inc
index cb481d028a..30d65ffb46 100644
--- a/target/ppc/translate/dfp-impl.c.inc
+++ b/target/ppc/translate/dfp-impl.c.inc
@@ -86,28 +86,25 @@ static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a)  
 \
 return true; \
 }
 
-#define GEN_DFP_T_A_B_I32_Rc(name, i32fld)   \
-static void gen_##name(DisasContext *ctx)\
-{\
-TCGv_ptr rt, ra, rb; \
-TCGv_i32 i32;\
-if (unlikely(!ctx->fpu_enabled)) {   \
-

[ PATCH v3 03/10] target/riscv: pmu: Rename the counters extension to pmu

2021-10-25 Thread 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.

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

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 1d69d1887e63..3b55f5ed0036 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -598,7 +598,7 @@ static Property riscv_cpu_properties[] = {
 DEFINE_PROP_BOOL("x-zbs", RISCVCPU, cfg.ext_zbs, false),
 DEFINE_PROP_BOOL("x-h", RISCVCPU, cfg.ext_h, false),
 DEFINE_PROP_BOOL("x-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_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 9e55b2f5b170..ebc1a8754032 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -294,7 +294,7 @@ struct RISCVCPU {
 bool ext_zbb;
 bool ext_zbc;
 bool ext_zbs;
-bool ext_counters;
+bool ext_pmu;
 bool ext_ifencei;
 bool ext_icsr;
 
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index de484c74d3b4..c486eeaffeb8 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -64,7 +64,7 @@ static RISCVException ctr(CPURISCVState *env, int csrno)
 RISCVCPU *cpu = RISCV_CPU(cs);
 int ctr_index;
 
-if (!cpu->cfg.ext_counters) {
+if (!cpu->cfg.ext_pmu) {
 /* The Counters extensions is not enabled */
 return RISCV_EXCP_ILLEGAL_INST;
 }
-- 
2.31.1




[ PATCH v3 00/10] Improve PMU support

2021-10-25 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 riscv]# perf stat -e r8005 -e r8007 \
-e r8006 -e r00020002 -e r00020004 -e branch-misses 
\
-e cache-misses -e dTLB-load-misses -e dTLB-store-misses -e iTLB-load-misses \
-e cycles -e instructions perf bench sched messaging -g 15 -l 10 \
Running with 15*40 (== 600) tasks.
Time: 6.578

 Performance counter stats for './hackbench -pipe 15 process':

 1,794  r8005  (52.59%) --> SBI_PMU_FW_SET_TIMER
 2,859  r8007  (60.74%) --> SBI_PMU_FW_IPI_RECVD
 4,205  r8006  (68.71%) --> SBI_PMU_FW_IPI_SENT
 0  r00020002  (81.69%)
   r00020004  (0.00%)
   branch-misses  (0.00%)
   cache-misses   (0.00%)
 7,878,328  dTLB-load-misses   (15.60%)
   680,270  dTLB-store-misses  (28.45%)
 8,287,931  iTLB-load-misses   (39.24%)
20,008,506,675  cycles (48.60%)
21,484,427,932  instructions   # 1.07  insn per cycle (56.60%)

   1.681344735 seconds time elapsed

   0.61446 seconds user
   8.313254000 seconds sys


Perf record:

[root@fedora-riscv 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 15 -l 10
# Running 'sched/messaging' benchmark:
# 20 sender and receiver processes per group
# 15 groups == 600 processes run

 Total time: 1.261 [sec]
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.101 MB perf.data (845 samples) ]

[root@fedora-riscv riscv]# perf report
Available samples   
407 cycles _
407 instructions   _
18 dTLB-load-misses_
2 dTLB-store-misses_
11 iTLB-load-misses_
..

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/opensbi/tree/pmu_sscofpmf_v2 
[3] https://github.com/atishp04/linux/tree/riscv_pmu_v4
[4] https://github.com/atishp04/qemu/tree/riscv_pmu_v3

Atish Patra (10):
target/riscv: Fix PMU CSR predicate function
target/riscv: Implement PMU CSR predicate function for
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: Add few cache related PMU events
hw/riscv: virt: Add PMU DT node to the device tree

hw/riscv/virt.c   |  36 ++
target/riscv/cpu.c|  14 +-
target/riscv/cpu.h|  51 ++-
target/riscv/cpu_bits.h   |  59 +++
target/riscv/cpu_helper.c |  26 ++
target/riscv/csr.c| 827 +-
target/riscv/machine.c|  30 +-
target/riscv/meson.build  |   1 +
target/riscv/pmp.c|   1 +
target/riscv/pmu.c| 434 
target/riscv/pmu.h|  37 ++
11 files changed, 1332 

[ PATCH v3 06/10] target/riscv: Add support for hpmcounters/hpmevents

2021-10-25 Thread 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 
---
 target/riscv/cpu.h |  12 ++
 target/riscv/csr.c | 468 -
 target/riscv/machine.c |   3 +
 3 files changed, 331 insertions(+), 152 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index b421eefa623f..e7dc90d001ac 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -103,6 +103,9 @@ typedef struct CPURISCVState CPURISCVState;
 
 #define RV_VLEN_MAX 256
 
+#define RV_MAX_MHPMEVENTS 29
+#define RV_MAX_MHPMCOUNTERS 32
+
 FIELD(VTYPE, VLMUL, 0, 2)
 FIELD(VTYPE, VSEW, 2, 3)
 FIELD(VTYPE, VEDIV, 5, 2)
@@ -219,6 +222,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 faf02e12ec34..6757543090be 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -79,6 +79,15 @@ static RISCVException mctr(CPURISCVState *env, int csrno)
 #endif
 }
 
+static RISCVException mctr32(CPURISCVState *env, int csrno)
+{
+if (!riscv_cpu_is_32bit(env)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+return mctr(env, csrno);
+}
+
 static RISCVException ctr(CPURISCVState *env, int csrno)
 {
 #if !defined(CONFIG_USER_ONLY)
@@ -426,6 +435,7 @@ static RISCVException read_instret(CPURISCVState *env, int 
csrno,
 #else
 *val = cpu_get_host_ticks();
 #endif
+
 return RISCV_EXCP_NONE;
 }
 
@@ -441,9 +451,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)
@@ -1742,157 +1819,244 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 [CSR_PMPADDR15] =  { "pmpaddr15", pmp, read_pmpaddr, write_pmpaddr },
 
 /* 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]   = { "hpmcounter17",   ctr,read_zero },
-[CSR_HPMCOUNTER18]   = { 

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

2021-10-25 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 
---
 hw/riscv/virt.c| 36 ++
 target/riscv/pmp.c |  1 +
 target/riscv/pmu.c | 63 ++
 3 files changed, 100 insertions(+)

diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index ec0cb69b8c73..b246d2e339eb 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,39 @@ 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;
+RISCVCPU hart;
+uint32_t *pmu_cells;
+MachineState *mc = MACHINE(s);
+
+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");
+hart = s->soc[0].harts[0];
+if (hart.cfg.ext_sscof) {
+qemu_fdt_setprop_cell(mc->fdt, pmu_name, "#interrupt-cells", 1);
+qemu_fdt_setprop(mc->fdt, pmu_name, "interrupts-extended", pmu_cells,
+ s->soc[socket].num_harts * sizeof(uint32_t) * 2);
+}
+riscv_pmu_generate_fdt_node(mc->fdt, 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,
@@ -445,6 +479,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/pmp.c b/target/riscv/pmp.c
index 54abf425835c..2e2145e51903 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -25,6 +25,7 @@
 #include "cpu.h"
 #include "trace.h"
 #include "exec/exec-all.h"
+#include "sysemu/device_tree.h"
 
 static void pmp_write_cfg(CPURISCVState *env, uint32_t addr_index,
 uint8_t val);
diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
index 25bdbdf48ff7..9e11af85576d 100644
--- a/target/riscv/pmu.c
+++ b/target/riscv/pmu.c
@@ -19,9 +19,72 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "pmu.h"
+#include "sysemu/device_tree.h"
 
 #define RISCV_TIMEBASE_FREQ 10 /* 1Ghz */
 
+/**
+ * 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.
+ */
+void riscv_pmu_generate_fdt_node(void *fdt, char *pmu_name)
+{
+uint32_t fdt_event_map[6] = {};
+uint32_t fdt_event_ctr_map[20] = {};
+uint32_t fdt_raw_event_ctr_map[6] = {};
+
+/* Dummy event and mhpmevent values */
+fdt_event_map[0] = cpu_to_be32(0x0009);
+fdt_event_map[1] = cpu_to_be32(0x);
+fdt_event_map[2] = cpu_to_be32(0x0200);
+fdt_event_map[3] = cpu_to_be32(0x0001);
+fdt_event_map[4] = cpu_to_be32(0x0100);
+fdt_event_map[5] = cpu_to_be32(0x0002);
+qemu_fdt_setprop(fdt, pmu_name, "pmu,event-to-mhpmevent",
+ fdt_event_map, sizeof(fdt_event_map));
+
+   /* 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(0x0FF9);
+
+   /* 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(0x0FFC);
+
+   /* 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] = cpu_to_be32(0x1F0);
+
+   /* SBI_PMU_HW_CACHE_DTLB : WRITE : MISS */
+   fdt_event_ctr_map[9] = cpu_to_be32(0x0001001B);
+   fdt_event_ctr_map[10] = cpu_to_be32(0x0001001B);
+   

[ PATCH v3 07/10] target/riscv: Support mcycle/minstret write operation

2021-10-25 Thread 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 
---
 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 e7dc90d001ac..da34614ad788 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -103,7 +103,7 @@ typedef struct CPURISCVState CPURISCVState;
 
 #define RV_VLEN_MAX 256
 
-#define RV_MAX_MHPMEVENTS 29
+#define RV_MAX_MHPMEVENTS 32
 #define RV_MAX_MHPMCOUNTERS 32
 
 FIELD(VTYPE, VLMUL, 0, 2)
@@ -112,6 +112,19 @@ FIELD(VTYPE, VEDIV, 5, 2)
 FIELD(VTYPE, RESERVED, 7, sizeof(target_ulong) * 8 - 9)
 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 */
@@ -222,13 +235,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 6757543090be..1ce1bb0868d7 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"
 
@@ -423,41 +424,33 @@ static RISCVException write_vstart(CPURISCVState *env, 
int csrno,
 }
 
 /* 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];
 
@@ -466,7 +459,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;
 
@@ -475,52 +468,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 can keep incrementing from the given value */
+

[ PATCH v3 02/10] target/riscv: Implement PMU CSR predicate function for

2021-10-25 Thread 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.

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 1ec776013435..de484c74d3b4 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -62,12 +62,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.31.1




[PATCH v4 11/19] target/ppc: Implement DCTFIXQQ

2021-10-25 Thread Luis Pires
Implement the following PowerISA v3.1 instruction:
dctfixqq: DFP Convert To Fixed Quadword Quad

Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 target/ppc/dfp_helper.c | 52 +
 target/ppc/helper.h |  1 +
 target/ppc/insn32.decode|  5 +++
 target/ppc/translate/dfp-impl.c.inc | 17 ++
 4 files changed, 75 insertions(+)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 6b837c4450..6ab46d7db5 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -51,6 +51,11 @@ static void set_dfp128(ppc_fprp_t *dfp, ppc_vsr_t *src)
 dfp[1].VsrD(0) = src->VsrD(1);
 }
 
+static void set_dfp128_to_avr(ppc_avr_t *dst, ppc_vsr_t *src)
+{
+*dst = *src;
+}
+
 struct PPC_DFP {
 CPUPPCState *env;
 ppc_vsr_t vt, va, vb;
@@ -1020,6 +1025,53 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b)  \
 DFP_HELPER_CTFIX(dctfix, 64)
 DFP_HELPER_CTFIX(dctfixq, 128)
 
+void helper_DCTFIXQQ(CPUPPCState *env, ppc_avr_t *t, ppc_fprp_t *b)
+{
+struct PPC_DFP dfp;
+dfp_prepare_decimal128(, 0, b, env);
+
+if (unlikely(decNumberIsSpecial())) {
+uint64_t invalid_flags = FP_VX | FP_VXCVI;
+if (decNumberIsInfinite()) {
+if (decNumberIsNegative()) {
+dfp.vt.VsrD(0) = INT64_MIN;
+dfp.vt.VsrD(1) = 0;
+} else {
+dfp.vt.VsrD(0) = INT64_MAX;
+dfp.vt.VsrD(1) = UINT64_MAX;
+}
+} else { /* NaN */
+dfp.vt.VsrD(0) = INT64_MIN;
+dfp.vt.VsrD(1) = 0;
+if (decNumberIsSNaN()) {
+invalid_flags |= FP_VXSNAN;
+}
+}
+dfp_set_FPSCR_flag(, invalid_flags, FP_VE);
+} else if (unlikely(decNumberIsZero())) {
+dfp.vt.VsrD(0) = 0;
+dfp.vt.VsrD(1) = 0;
+} else {
+decNumberToIntegralExact(, , );
+decNumberIntegralToInt128(, ,
+(1), (0));
+if (decContextTestStatus(, DEC_Invalid_operation)) {
+if (decNumberIsNegative()) {
+dfp.vt.VsrD(0) = INT64_MIN;
+dfp.vt.VsrD(1) = 0;
+} else {
+dfp.vt.VsrD(0) = INT64_MAX;
+dfp.vt.VsrD(1) = UINT64_MAX;
+}
+dfp_set_FPSCR_flag(, FP_VX | FP_VXCVI, FP_VE);
+} else {
+dfp_check_for_XX();
+}
+}
+
+set_dfp128_to_avr(t, );
+}
+
 static inline void dfp_set_bcd_digit_64(ppc_vsr_t *t, uint8_t digit,
 unsigned n)
 {
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index fff7bd46ad..20041ce977 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -737,6 +737,7 @@ DEF_HELPER_3(dcffixq, void, env, fprp, fprp)
 DEF_HELPER_3(DCFFIXQQ, void, env, fprp, avr)
 DEF_HELPER_3(dctfix, void, env, fprp, fprp)
 DEF_HELPER_3(dctfixq, void, env, fprp, fprp)
+DEF_HELPER_3(DCTFIXQQ, void, env, avr, fprp)
 DEF_HELPER_4(ddedpd, void, env, fprp, fprp, i32)
 DEF_HELPER_4(ddedpdq, void, env, fprp, fprp, i32)
 DEF_HELPER_4(denbcd, void, env, fprp, fprp, i32)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 92ea2d0739..6d97f9ae3b 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -47,6 +47,10 @@
 %x_frtp 22:4 !function=times_2
 @X_frtp_vrb .. 0 . vrb:5 .. .   _frtp_vrb 
frtp=%x_frtp
 
+_vrt_frbp vrt frbp
+%x_frbp 12:4 !function=times_2
+@X_vrt_frbp .. vrt:5 . 0 .. .   _vrt_frbp 
frbp=%x_frbp
+
 ### Fixed-Point Load Instructions
 
 LBZ 100010 . .  @D
@@ -128,6 +132,7 @@ SETNBCR 01 . . - 00 -   
@X_bi
 ### Decimal Floating-Point Conversion Instructions
 
 DCFFIXQQ11 . 0 . 100010 -   @X_frtp_vrb
+DCTFIXQQ11 . 1 . 100010 -   @X_vrt_frbp
 
 ## Vector Bit Manipulation Instruction
 
diff --git a/target/ppc/translate/dfp-impl.c.inc 
b/target/ppc/translate/dfp-impl.c.inc
index d5b66567a6..e149777481 100644
--- a/target/ppc/translate/dfp-impl.c.inc
+++ b/target/ppc/translate/dfp-impl.c.inc
@@ -247,3 +247,20 @@ static bool trans_DCFFIXQQ(DisasContext *ctx, arg_DCFFIXQQ 
*a)
 
 return true;
 }
+
+static bool trans_DCTFIXQQ(DisasContext *ctx, arg_DCTFIXQQ *a)
+{
+TCGv_ptr rt, rb;
+
+REQUIRE_INSNS_FLAGS2(ctx, DFP);
+REQUIRE_FPU(ctx);
+REQUIRE_VECTOR(ctx);
+
+rt = gen_avr_ptr(a->vrt);
+rb = gen_fprp_ptr(a->frbp);
+gen_helper_DCTFIXQQ(cpu_env, rt, rb);
+tcg_temp_free_ptr(rt);
+tcg_temp_free_ptr(rb);
+
+return true;
+}
-- 
2.25.1




Re: [PATCH v4] isa-applesmc: provide OSK forwarding on Apple hosts

2021-10-25 Thread Alexander Graf



On 25.10.21 17:10, Daniel P. Berrangé wrote:

On Mon, Oct 25, 2021 at 04:53:57PM +0200, Alexander Graf wrote:

On 25.10.21 16:47, Daniel P. Berrangé wrote:

On Mon, Oct 25, 2021 at 04:42:22PM +0200, Alexander Graf wrote:

On 25.10.21 16:22, Daniel P. Berrangé wrote:

On Mon, Oct 25, 2021 at 12:13:32PM +0200, Alexander Graf wrote:

On 22.10.21 18:14, Vladislav Yaroshchuk wrote:

On Apple hosts we can read AppleSMC OSK key directly from host's
SMC and forward this value to QEMU Guest.

Usage:
`-device isa-applesmc,hostosk=on`

Apple licence allows use and run up to two additional copies
or instances of macOS operating within virtual operating system
environments on each Apple-branded computer that is already running
the Apple Software, for purposes of:
- software development
- testing during software development
- using macOS Server
- personal, non-commercial use

Guest macOS requires AppleSMC with correct OSK. The most legal
way to pass it to the Guest is to forward the key from host SMC
without any value exposion.

Based on 
https://web.archive.org/web/20200103161737/osxbook.com/book/bonus/chapter7/tpmdrmmyth/

Signed-off-by: Vladislav Yaroshchuk 
@@ -331,6 +464,25 @@ static void applesmc_isa_realize(DeviceState *dev, Error 
**errp)
 isa_register_ioport(>parent_obj, >io_err,
 s->iobase + APPLESMC_ERR_PORT);
+if (s->hostosk_flag) {
+/*
+ * Property 'hostosk' has higher priority than 'osk'
+ * and shadows it.
+ * Free user-provided 'osk' property value
+ */
+if (s->osk) {
+warn_report("isa-applesmc.osk is shadowed "
+"by isa-applesmc.hostosk");
+g_free(s->osk);
+}
+
+if (!applesmc_read_host_osk(>osk, )) {
+/* On host OSK retrieval error report a warning */
+error_report_err(err);
+s->osk = default_osk;
+}
+}

This part is yucky. A few things:

1) QEMU in general does not fail user requested operations silently. If the
user explicitly asked to read the host OSK and we couldn't, it must
propagate that error.
2) In tandem to the above, I think the only consistent CX is to make both
options mutually exclusive. The easiest way to achieve that IMHO would be to
overload the "osk" property. If it is "host", then use the host one.
3) Should we make "osk"="host" the default on macOS as well then? Of course,
that one should *not* fail hard when it can't read the key, because it's an
implicit request rather than an explicit one.

The problem with using a magic string value for the existing "osk"
parameter is that this is not introspectable by management apps.

What introspectability would you like to have?

Essentially to answer the question

"Does this QEMU support OSK passthrough from the host"

Mgmt apps like libvirt introspect using various query-XXX QMP commands.
For devices, the typical approach is to ask for the list of properties
the device supports. If we're just accepting a new magic value on an
existing property there is no way to query for existance of that feature.
If we add a "host-osk=bool" parameter introspectability is trivially
satisfied.


Ok, the only flow that remains sensible in that case to me sounds like the
following:

Just need an extra check upfront:

  if (s->osk && s->use_hoist_osk)
  error_setg(errp, ...)
  else
  

if (s->osk) {
     /* Use osk */

This should fail hard if the provided value is the wrong length - currently
it falls back with a warning IIUC.


} else if (s->use_host_osk) {
     /* Use host OSK. Fail hard if we can't find it */
} else if (can_use_host_osk) {
     /* See if we can extract the key from the host. If not, fall back to old
behavior */
} else {
     /* Old fallback behavior */

Was this old fallback behaviour actually useful ? IIUC it means it is using


   static char default_osk[64] = "This is a dummy key. Enter the real key "
 "using the -osk parameter";

which obviously isn't a valid key that will work with any gust OS that
cares. I guess it at least let QEMU startup, but any the guest OS that
checks the key will be unhappy.

If if don't think default_osk is actually useful, then we could simplify
further to

  if (s->osk && s->use_host_osk) {
  error_setg(errp, ...)
  } else if (s->osk) {
 /* Use osk. Fail hard if invalid (ie wrong length) */
  } else if (s->use_host_osk) {
 /* Use host OSK. Fail hard if we can't find it */
  } else {
 /* try to use host OSK, fail hard if we can't find it or non-OS-X build */
  }



In the example above, use_host_osk=on and use_host_osk=off yield the 
exact same behavior, so we don't need the switch, no?


Alex




[PATCH v4 10/19] libdecnumber: Introduce decNumberIntegralToInt128

2021-10-25 Thread Luis Pires
This will be used to implement PowerPC's dctfixqq.

Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 include/libdecnumber/decNumber.h  |  2 +
 include/libdecnumber/decNumberLocal.h |  2 +-
 libdecnumber/decContext.c |  7 +-
 libdecnumber/decNumber.c  | 95 +++
 4 files changed, 102 insertions(+), 4 deletions(-)

diff --git a/include/libdecnumber/decNumber.h b/include/libdecnumber/decNumber.h
index 0cf69c7db2..41bc2a0d36 100644
--- a/include/libdecnumber/decNumber.h
+++ b/include/libdecnumber/decNumber.h
@@ -124,6 +124,8 @@
   uint32_tdecNumberToUInt32(const decNumber *, decContext *);
   int32_t decNumberToInt32(const decNumber *, decContext *);
   int64_t decNumberIntegralToInt64(const decNumber *dn, decContext *set);
+  voiddecNumberIntegralToInt128(const decNumber *dn, decContext *set,
+uint64_t *plow, uint64_t *phigh);
   uint8_t   * decNumberGetBCD(const decNumber *, uint8_t *);
   decNumber * decNumberSetBCD(decNumber *, const uint8_t *, uint32_t);
 
diff --git a/include/libdecnumber/decNumberLocal.h 
b/include/libdecnumber/decNumberLocal.h
index 4d53c077f2..6198ca8593 100644
--- a/include/libdecnumber/decNumberLocal.h
+++ b/include/libdecnumber/decNumberLocal.h
@@ -98,7 +98,7 @@
 
   /* Shared lookup tables*/
   extern const uByte  DECSTICKYTAB[10]; /* re-round digits if sticky  */
-  extern const uLong  DECPOWERS[19];/* powers of ten table*/
+  extern const uLong  DECPOWERS[20];/* powers of ten table*/
   /* The following are included from decDPD.h*/
   extern const uShort DPD2BIN[1024];   /* DPD -> 0-999   */
   extern const uShort BIN2DPD[1000];   /* 0-999 -> DPD   */
diff --git a/libdecnumber/decContext.c b/libdecnumber/decContext.c
index 7d97a65ac5..1956edf0a7 100644
--- a/libdecnumber/decContext.c
+++ b/libdecnumber/decContext.c
@@ -53,12 +53,13 @@ static  const  Flag *mfctop=(Flag *) /* -> top 
byte */
 const uByte DECSTICKYTAB[10]={1,1,2,3,4,6,6,7,8,9}; /* used if sticky */
 
 /* -- */
-/* Powers of ten (powers[n]==10**n, 0<=n<=9) */
+/* Powers of ten (powers[n]==10**n, 0<=n<=19) */
 /* -- */
-const uLong DECPOWERS[19] = {1, 10, 100, 1000, 1, 10, 100,
+const uLong DECPOWERS[20] = {1, 10, 100, 1000, 1, 10, 100,
   1000, 1, 10, 100ULL, 1000ULL,
   1ULL, 10ULL, 100ULL, 1000ULL,
-  1ULL, 10ULL, 100ULL, };
+  1ULL, 10ULL, 100ULL,
+  1000ULL,};
 
 /* -- */
 /* decContextClearStatus -- clear bits in current status */
diff --git a/libdecnumber/decNumber.c b/libdecnumber/decNumber.c
index d7716ce175..31282adafd 100644
--- a/libdecnumber/decNumber.c
+++ b/libdecnumber/decNumber.c
@@ -264,6 +264,7 @@ static decNumber * decTrim(decNumber *, decContext *, Flag, 
Int *);
 static IntdecUnitAddSub(const Unit *, Int, const Unit *, Int, Int,
  Unit *, Int);
 static IntdecUnitCompare(const Unit *, Int, const Unit *, Int, Int);
+static boolmulUInt128ByPowOf10(uLong *, uLong *, uInt);
 
 #if !DECSUBSET
 /* decFinish == decFinalize when no subset arithmetic needed */
@@ -542,6 +543,68 @@ Invalid:
 return 0;
 } /* decNumberIntegralToInt64 */
 
+/* -- */
+/* decNumberIntegralToInt128 -- conversion to int128  */
+/**/
+/*  dn is the decNumber to convert.  dn is assumed to have been   */
+/*rounded to a floating point integer value.  */
+/*  set is the context for reporting errors   */
+/*  returns the converted decNumber via plow and phigh*/
+/**/
+/* Invalid is set if the decNumber is a NaN, Infinite or is out of*/
+/* range for a signed 128 bit integer.*/
+/* -- */
+
+void decNumberIntegralToInt128(const decNumber *dn, decContext *set,
+uint64_t *plow, uint64_t *phigh)
+{
+int d;/* work */
+const Unit *up;   /* .. */
+uint64_t lo = 0, hi = 0;
+
+if (decNumberIsSpecial(dn) || (dn->exponent < 0) ||
+   (dn->digits + dn->exponent > 39)) {
+goto Invalid;
+}
+
+up = dn->lsu; /* -> lsu */
+
+for (d = (dn->digits - 1) / DECDPUN; d >= 0; d--) {
+if 

Re: [PATCH 9/9] qapi: Extend -compat to set policy for unstable interfaces

2021-10-25 Thread John Snow
On Mon, Oct 25, 2021 at 1:26 AM Markus Armbruster  wrote:

> New option parameters unstable-input and unstable-output set policy
> for unstable interfaces just like deprecated-input and
> deprecated-output set policy for deprecated interfaces (see commit
> 6dd75472d5 "qemu-options: New -compat to set policy for deprecated
> interfaces").  This is intended for testing users of the management
> interfaces.  It is experimental.
>
> For now, this covers only syntactic aspects of QMP, i.e. stuff tagged
> with feature 'unstable'.  We may want to extend it to cover semantic
> aspects, or the command line.
>
> Note that there is no good way for management application to detect
> presence of these new option parameters: they are not visible output
> of query-qmp-schema or query-command-line-options.  Tolerable, because
> it's meant for testing.  If running with -compat fails, skip the test.
>
> Signed-off-by: Markus Armbruster 
> ---
>  qapi/compat.json  |  6 +-
>  include/qapi/util.h   |  1 +
>  qapi/qmp-dispatch.c   |  6 ++
>  qapi/qobject-output-visitor.c |  8 ++--
>  qemu-options.hx   | 20 +++-
>  scripts/qapi/events.py| 10 ++
>  scripts/qapi/schema.py| 10 ++
>  7 files changed, 49 insertions(+), 12 deletions(-)
>
> diff --git a/qapi/compat.json b/qapi/compat.json
> index 74a8493d3d..9bc9804abb 100644
> --- a/qapi/compat.json
> +++ b/qapi/compat.json
> @@ -47,9 +47,13 @@
>  #
>  # @deprecated-input: how to handle deprecated input (default 'accept')
>  # @deprecated-output: how to handle deprecated output (default 'accept')
> +# @unstable-input: how to handle unstable input (default 'accept')
> +# @unstable-output: how to handle unstable output (default 'accept')
>  #
>  # Since: 6.0
>  ##
>  { 'struct': 'CompatPolicy',
>'data': { '*deprecated-input': 'CompatPolicyInput',
> -'*deprecated-output': 'CompatPolicyOutput' } }
> +'*deprecated-output': 'CompatPolicyOutput',
> +'*unstable-input': 'CompatPolicyInput',
> +'*unstable-output': 'CompatPolicyOutput' } }
> diff --git a/include/qapi/util.h b/include/qapi/util.h
> index 0cc98db9f9..81a2b13a33 100644
> --- a/include/qapi/util.h
> +++ b/include/qapi/util.h
> @@ -13,6 +13,7 @@
>
>  typedef enum {
>  QAPI_DEPRECATED,
> +QAPI_UNSTABLE,
>  } QapiSpecialFeature;
>
>  typedef struct QEnumLookup {
> diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
> index e29ade134c..c5c6e521a2 100644
> --- a/qapi/qmp-dispatch.c
> +++ b/qapi/qmp-dispatch.c
> @@ -59,6 +59,12 @@ bool compat_policy_input_ok(unsigned special_features,
>  error_class, kind, name, errp)) {
>  return false;
>  }
> +if ((special_features & (1u << QAPI_UNSTABLE))
> +&& !compat_policy_input_ok1("Unstable",
> +policy->unstable_input,
> +error_class, kind, name, errp)) {
> +return false;
> +}
>  return true;
>  }
>
> diff --git a/qapi/qobject-output-visitor.c b/qapi/qobject-output-visitor.c
> index b5c6564cbb..74770edd73 100644
> --- a/qapi/qobject-output-visitor.c
> +++ b/qapi/qobject-output-visitor.c
> @@ -212,8 +212,12 @@ static bool qobject_output_type_null(Visitor *v,
> const char *name,
>  static bool qobject_output_policy_skip(Visitor *v, const char *name,
> unsigned special_features)
>  {
> -return !(special_features && 1u << QAPI_DEPRECATED)
> -|| v->compat_policy.deprecated_output ==
> COMPAT_POLICY_OUTPUT_HIDE;
> +CompatPolicy *pol = >compat_policy;
> +
> +return ((special_features & 1u << QAPI_DEPRECATED)
> +&& pol->deprecated_output == COMPAT_POLICY_OUTPUT_HIDE)
> +|| ((special_features & 1u << QAPI_UNSTABLE)
> +&& pol->unstable_output == COMPAT_POLICY_OUTPUT_HIDE);
>  }
>
>  /* Finish building, and return the root object.
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 5f375bbfa6..f051536b63 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -3641,7 +3641,9 @@ DEFHEADING(Debug/Expert options:)
>
>  DEF("compat", HAS_ARG, QEMU_OPTION_compat,
>  "-compat
> [deprecated-input=accept|reject|crash][,deprecated-output=accept|hide]\n"
> -"Policy for handling deprecated management
> interfaces\n",
> +"Policy for handling deprecated management
> interfaces\n"
> +"-compat
> [unstable-input=accept|reject|crash][,unstable-output=accept|hide]\n"
> +"Policy for handling unstable management
> interfaces\n",
>  QEMU_ARCH_ALL)
>  SRST
>  ``-compat
> [deprecated-input=@var{input-policy}][,deprecated-output=@var{output-policy}]``
> @@ -3659,6 +3661,22 @@ SRST
>  Suppress deprecated command results and events
>
>  Limitation: covers only syntactic aspects of QMP.
> +
> +``-compat
> 

[PATCH v4 09/19] host-utils: Introduce mulu128

2021-10-25 Thread Luis Pires
Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 include/qemu/host-utils.h | 36 
 1 file changed, 36 insertions(+)

diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index a3a7ced78d..ca979dc6cc 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -590,6 +590,42 @@ static inline bool umul64_overflow(uint64_t x, uint64_t y, 
uint64_t *ret)
 #endif
 }
 
+/*
+ * Unsigned 128x64 multiplication.
+ * Returns true if the result got truncated to 128 bits.
+ * Otherwise, returns false and the multiplication result via plow and phigh.
+ */
+static inline bool mulu128(uint64_t *plow, uint64_t *phigh, uint64_t factor)
+{
+#if defined(CONFIG_INT128) && \
+(__has_builtin(__builtin_mul_overflow) || __GNUC__ >= 5)
+bool res;
+__uint128_t r;
+__uint128_t f = ((__uint128_t)*phigh << 64) | *plow;
+res = __builtin_mul_overflow(f, factor, );
+
+*plow = r;
+*phigh = r >> 64;
+
+return res;
+#else
+uint64_t dhi = *phigh;
+uint64_t dlo = *plow;
+uint64_t ahi;
+uint64_t blo, bhi;
+
+if (dhi == 0) {
+mulu64(plow, phigh, dlo, factor);
+return false;
+}
+
+mulu64(plow, , dlo, factor);
+mulu64(, , dhi, factor);
+
+return uadd64_overflow(ahi, blo, phigh) || bhi != 0;
+#endif
+}
+
 /**
  * uadd64_carry - addition with carry-in and carry-out
  * @x, @y: addends
-- 
2.25.1




Re: [PATCH 8/9] qapi: Factor out compat_policy_input_ok()

2021-10-25 Thread John Snow
On Mon, Oct 25, 2021 at 1:25 AM Markus Armbruster  wrote:

> The code to check policy for handling deprecated input is triplicated.
> Factor it out into compat_policy_input_ok() before I mess with it in
> the next commit.
>
> Signed-off-by: Markus Armbruster 
>


(Skipping C-only patches for quick review. I'll trust you on these.)

--js


Re: [PATCH 7/9] qapi: Generalize enum member policy checking

2021-10-25 Thread John Snow
On Mon, Oct 25, 2021 at 1:26 AM Markus Armbruster  wrote:

> The code to check enumeration value policy can see special feature
> flag 'deprecated' in QEnumLookup member flags[value].  I want to make
> feature flag 'unstable' visible there as well, so I can add policy for
> it.
>
> Instead of extending flags[], replace it by @special_features (a
> bitset of QapiSpecialFeature), because that's how special features get
> passed around elsewhere.
>
> Signed-off-by: Markus Armbruster 
> ---
>  include/qapi/util.h|  5 +
>  qapi/qapi-visit-core.c |  3 ++-
>  scripts/qapi/types.py  | 22 --
>  3 files changed, 15 insertions(+), 15 deletions(-)
>
> diff --git a/include/qapi/util.h b/include/qapi/util.h
> index 7a8d5c7d72..0cc98db9f9 100644
> --- a/include/qapi/util.h
> +++ b/include/qapi/util.h
> @@ -15,12 +15,9 @@ typedef enum {
>  QAPI_DEPRECATED,
>  } QapiSpecialFeature;
>
> -/* QEnumLookup flags */
> -#define QAPI_ENUM_DEPRECATED 1
> -
>  typedef struct QEnumLookup {
>  const char *const *array;
> -const unsigned char *const flags;
> +const unsigned char *const special_features;
>  const int size;
>  } QEnumLookup;
>
> diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
> index b4a81f1757..5572d90efb 100644
> --- a/qapi/qapi-visit-core.c
> +++ b/qapi/qapi-visit-core.c
> @@ -407,7 +407,8 @@ static bool input_type_enum(Visitor *v, const char
> *name, int *obj,
>  return false;
>  }
>
> -if (lookup->flags && (lookup->flags[value] & QAPI_ENUM_DEPRECATED)) {
> +if (lookup->special_features
> +&& (lookup->special_features[value] & QAPI_DEPRECATED)) {
>  switch (v->compat_policy.deprecated_input) {
>  case COMPAT_POLICY_INPUT_ACCEPT:
>  break;
> diff --git a/scripts/qapi/types.py b/scripts/qapi/types.py
> index ab2441adc9..3013329c24 100644
> --- a/scripts/qapi/types.py
> +++ b/scripts/qapi/types.py
> @@ -16,7 +16,7 @@
>  from typing import List, Optional
>
>  from .common import c_enum_const, c_name, mcgen
> -from .gen import QAPISchemaModularCVisitor, ifcontext
> +from .gen import QAPISchemaModularCVisitor, gen_special_features,
> ifcontext
>  from .schema import (
>  QAPISchema,
>  QAPISchemaEnumMember,
> @@ -39,7 +39,7 @@ def gen_enum_lookup(name: str,
>  members: List[QAPISchemaEnumMember],
>  prefix: Optional[str] = None) -> str:
>  max_index = c_enum_const(name, '_MAX', prefix)
> -flags = ''
> +feats = ''
>  ret = mcgen('''
>
>  const QEnumLookup %(c_name)s_lookup = {
> @@ -54,19 +54,21 @@ def gen_enum_lookup(name: str,
>  ''',
>   index=index, name=memb.name)
>  ret += memb.ifcond.gen_endif()
> -if 'deprecated' in (f.name for f in memb.features):
> -flags += mcgen('''
> -[%(index)s] = QAPI_ENUM_DEPRECATED,
> -''',
> -   index=index)
>
> -if flags:
> +special_features = gen_special_features(memb.features)
> +if special_features != '0':
>

Though, I have to admit the common reoccurrence of this pattern suggests to
me that gen_special_features really ought to be returning something false-y
in these cases. Something about testing for the empty case with something
that represents, but isn't empty, gives me a brief pause.

Not willing to wage war over it.


> +feats += mcgen('''
> +[%(index)s] = %(special_features)s,
> +''',
> +   index=index, special_features=special_features)
> +
> +if feats:
>  ret += mcgen('''
>  },
> -.flags = (const unsigned char[%(max_index)s]) {
> +.special_features = (const unsigned char[%(max_index)s]) {
>  ''',
>   max_index=max_index)
> -ret += flags
> +ret += feats
>
>  ret += mcgen('''
>  },
> --
> 2.31.1
>
>
Python bits: Acked-by: John Snow 


[PATCH v4 07/19] target/ppc: Introduce REQUIRE_FPU

2021-10-25 Thread Luis Pires
From: Fernando Valle 

Signed-off-by: Fernando Valle 
Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 target/ppc/translate.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index c2fafebd1c..48a484eef6 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -7477,6 +7477,14 @@ static int times_4(DisasContext *ctx, int x)
 }   \
 } while (0)
 
+#define REQUIRE_FPU(ctx)\
+do {\
+if (unlikely(!(ctx)->fpu_enabled)) {\
+gen_exception((ctx), POWERPC_EXCP_FPU); \
+return true;\
+}   \
+} while (0)
+
 /*
  * Helpers for implementing sets of trans_* functions.
  * Defer the implementation of NAME to FUNC, with optional extra arguments.
-- 
2.25.1




Re: [PATCH 4/9] qapi: Tools for sets of special feature flags in generated code

2021-10-25 Thread John Snow
On Mon, Oct 25, 2021 at 1:25 AM Markus Armbruster  wrote:

> New enum QapiSpecialFeature enumerates the special feature flags.
>
> New helper gen_special_features() returns code to represent a
> collection of special feature flags as a bitset.
>
> The next few commits will put them to use.
>
> Signed-off-by: Markus Armbruster 
> ---
>  include/qapi/util.h|  4 
>  scripts/qapi/gen.py| 13 +
>  scripts/qapi/schema.py |  3 +++
>  3 files changed, 20 insertions(+)
>
> diff --git a/include/qapi/util.h b/include/qapi/util.h
> index 257c600f99..7a8d5c7d72 100644
> --- a/include/qapi/util.h
> +++ b/include/qapi/util.h
> @@ -11,6 +11,10 @@
>  #ifndef QAPI_UTIL_H
>  #define QAPI_UTIL_H
>
> +typedef enum {
> +QAPI_DEPRECATED,
> +} QapiSpecialFeature;
> +
>  /* QEnumLookup flags */
>  #define QAPI_ENUM_DEPRECATED 1
>
> diff --git a/scripts/qapi/gen.py b/scripts/qapi/gen.py
> index 2ec1e7b3b6..9d07b88cf6 100644
> --- a/scripts/qapi/gen.py
> +++ b/scripts/qapi/gen.py
> @@ -29,6 +29,7 @@
>  mcgen,
>  )
>  from .schema import (
> +QAPISchemaFeature,
>  QAPISchemaIfCond,
>  QAPISchemaModule,
>  QAPISchemaObjectType,
> @@ -37,6 +38,18 @@
>  from .source import QAPISourceInfo
>
>
> +def gen_special_features(features: QAPISchemaFeature):
> +ret = ''
> +sep = ''
> +
> +for feat in features:
> +if feat.is_special():
> +ret += ('%s1u << QAPI_%s' % (sep, feat.name.upper()))
>

Building the constant name here "feels" fragile, but I'll trust that the
test suite and/or the compiler will catch us if we accidentally goof up
this mapping. In the interest of simplicity, then, "sure, why not."


> +sep = ' | '
> +
>
+return ret or '0'
> +
>

Subjectively more pythonic:

special_features = [f"1u << QAPI_{feat.name.upper()}" for feat in features
if feat.is_special()]
ret = ' | '.join(special_features)
return ret or '0'

A bit more dense, but more functional. Up to you, but I find join() easier
to read and reason about for the presence of separators.


> +
>  class QAPIGen:
>  def __init__(self, fname: str):
>  self.fname = fname
> diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py
> index 6d5f46509a..55f82d7389 100644
> --- a/scripts/qapi/schema.py
> +++ b/scripts/qapi/schema.py
> @@ -725,6 +725,9 @@ def connect_doc(self, doc):
>  class QAPISchemaFeature(QAPISchemaMember):
>  role = 'feature'
>
> +def is_special(self):
> +return self.name in ('deprecated')
> +
>

alrighty.

(Briefly wondered: is it worth naming special features as a property of the
class, but with only two names, it's probably fine enough to leave it
embedded in the method logic. Only a style thing and doesn't have any
actual impact that I can imagine, so ... nevermind.)


>
>  class QAPISchemaObjectTypeMember(QAPISchemaMember):
>  def __init__(self, name, info, typ, optional, ifcond=None,
> features=None):
> --
> 2.31.1
>
>
Well, either way:

Reviewed-by: John Snow 


[PATCH v4 06/19] target/ppc: Move REQUIRE_ALTIVEC/VECTOR to translate.c

2021-10-25 Thread Luis Pires
From: Bruno Larsen 

Move REQUIRE_ALTIVEC to translate.c and rename it to REQUIRE_VECTOR.

Signed-off-by: Bruno Larsen 
Signed-off-by: Matheus Ferst 
Signed-off-by: Fernando Valle 
Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
Acked-by: David Gibson 
---
 target/ppc/translate.c |  8 
 target/ppc/translate/vector-impl.c.inc | 10 +-
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 518337bcb7..c2fafebd1c 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -7469,6 +7469,14 @@ static int times_4(DisasContext *ctx, int x)
 # define REQUIRE_64BIT(CTX)  REQUIRE_INSNS_FLAGS(CTX, 64B)
 #endif
 
+#define REQUIRE_VECTOR(CTX) \
+do {\
+if (unlikely(!(CTX)->altivec_enabled)) {\
+gen_exception((CTX), POWERPC_EXCP_VPU); \
+return true;\
+}   \
+} while (0)
+
 /*
  * Helpers for implementing sets of trans_* functions.
  * Defer the implementation of NAME to FUNC, with optional extra arguments.
diff --git a/target/ppc/translate/vector-impl.c.inc 
b/target/ppc/translate/vector-impl.c.inc
index 117ce9b137..197e903337 100644
--- a/target/ppc/translate/vector-impl.c.inc
+++ b/target/ppc/translate/vector-impl.c.inc
@@ -17,20 +17,12 @@
  * License along with this library; if not, see .
  */
 
-#define REQUIRE_ALTIVEC(CTX) \
-do {\
-if (unlikely(!(CTX)->altivec_enabled)) {\
-gen_exception((CTX), POWERPC_EXCP_VPU); \
-return true;\
-}   \
-} while (0)
-
 static bool trans_VCFUGED(DisasContext *ctx, arg_VX *a)
 {
 TCGv_i64 tgt, src, mask;
 
 REQUIRE_INSNS_FLAGS2(ctx, ISA310);
-REQUIRE_ALTIVEC(ctx);
+REQUIRE_VECTOR(ctx);
 
 tgt = tcg_temp_new_i64();
 src = tcg_temp_new_i64();
-- 
2.25.1




[PATCH v4 15/19] target/ppc: Move dcmp{u, o}[q], dts{tex, tsf, tsfi}[q] to decodetree

2021-10-25 Thread Luis Pires
Move the following instructions to decodetree:
dcmpu:DFP Compare Unordered
dcmpuq:   DFP Compare Unordered Quad
dcmpo:DFP Compare Ordered
dcmpoq:   DFP Compare Ordered Quad
dtstex:   DFP Test Exponent
dtstexq:  DFP Test Exponent Quad
dtstsf:   DFP Test Significance
dtstsfq:  DFP Test Significance Quad
dtstsfi:  DFP Test Significance Immediate
dtstsfiq: DFP Test Significance Immediate Quad

Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 target/ppc/dfp_helper.c | 20 
 target/ppc/helper.h | 20 
 target/ppc/insn32.decode| 29 +++
 target/ppc/translate/dfp-impl.c.inc | 74 +
 target/ppc/translate/dfp-ops.c.inc  | 31 
 5 files changed, 83 insertions(+), 91 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index da8eaaaff1..9be6809b33 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -507,8 +507,8 @@ static void CMPU_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXSNAN(dfp);
 }
 
-DFP_HELPER_BF_AB(dcmpu, decNumberCompare, CMPU_PPs, 64)
-DFP_HELPER_BF_AB(dcmpuq, decNumberCompare, CMPU_PPs, 128)
+DFP_HELPER_BF_AB(DCMPU, decNumberCompare, CMPU_PPs, 64)
+DFP_HELPER_BF_AB(DCMPUQ, decNumberCompare, CMPU_PPs, 128)
 
 static void CMPO_PPs(struct PPC_DFP *dfp)
 {
@@ -518,8 +518,8 @@ static void CMPO_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXVC(dfp);
 }
 
-DFP_HELPER_BF_AB(dcmpo, decNumberCompare, CMPO_PPs, 64)
-DFP_HELPER_BF_AB(dcmpoq, decNumberCompare, CMPO_PPs, 128)
+DFP_HELPER_BF_AB(DCMPO, decNumberCompare, CMPO_PPs, 64)
+DFP_HELPER_BF_AB(DCMPOQ, decNumberCompare, CMPO_PPs, 128)
 
 #define DFP_HELPER_TSTDC(op, size)   \
 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, uint32_t dcm)  \
@@ -633,8 +633,8 @@ uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, 
ppc_fprp_t *b) \
 return dfp.crbf; \
 }
 
-DFP_HELPER_TSTEX(dtstex, 64)
-DFP_HELPER_TSTEX(dtstexq, 128)
+DFP_HELPER_TSTEX(DTSTEX, 64)
+DFP_HELPER_TSTEX(DTSTEXQ, 128)
 
 #define DFP_HELPER_TSTSF(op, size)   \
 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, ppc_fprp_t *b) \
@@ -670,8 +670,8 @@ uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, 
ppc_fprp_t *b) \
 return dfp.crbf; \
 }
 
-DFP_HELPER_TSTSF(dtstsf, 64)
-DFP_HELPER_TSTSF(dtstsfq, 128)
+DFP_HELPER_TSTSF(DTSTSF, 64)
+DFP_HELPER_TSTSF(DTSTSFQ, 128)
 
 #define DFP_HELPER_TSTSFI(op, size) \
 uint32_t helper_##op(CPUPPCState *env, uint32_t a, ppc_fprp_t *b)   \
@@ -705,8 +705,8 @@ uint32_t helper_##op(CPUPPCState *env, uint32_t a, 
ppc_fprp_t *b)   \
 return dfp.crbf;\
 }
 
-DFP_HELPER_TSTSFI(dtstsfi, 64)
-DFP_HELPER_TSTSFI(dtstsfiq, 128)
+DFP_HELPER_TSTSFI(DTSTSFI, 64)
+DFP_HELPER_TSTSFI(DTSTSFIQ, 128)
 
 static void QUA_PPs(struct PPC_DFP *dfp)
 {
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 1f00e47b82..22bf167b15 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -704,20 +704,20 @@ DEF_HELPER_4(DMUL, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(DMULQ, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(DDIV, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(DDIVQ, void, env, fprp, fprp, fprp)
-DEF_HELPER_3(dcmpo, i32, env, fprp, fprp)
-DEF_HELPER_3(dcmpoq, i32, env, fprp, fprp)
-DEF_HELPER_3(dcmpu, i32, env, fprp, fprp)
-DEF_HELPER_3(dcmpuq, i32, env, fprp, fprp)
+DEF_HELPER_3(DCMPO, i32, env, fprp, fprp)
+DEF_HELPER_3(DCMPOQ, i32, env, fprp, fprp)
+DEF_HELPER_3(DCMPU, i32, env, fprp, fprp)
+DEF_HELPER_3(DCMPUQ, i32, env, fprp, fprp)
 DEF_HELPER_3(DTSTDC, i32, env, fprp, i32)
 DEF_HELPER_3(DTSTDCQ, i32, env, fprp, i32)
 DEF_HELPER_3(DTSTDG, i32, env, fprp, i32)
 DEF_HELPER_3(DTSTDGQ, i32, env, fprp, i32)
-DEF_HELPER_3(dtstex, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstexq, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstsf, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstsfq, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstsfi, i32, env, i32, fprp)
-DEF_HELPER_3(dtstsfiq, i32, env, i32, fprp)
+DEF_HELPER_3(DTSTEX, i32, env, fprp, fprp)
+DEF_HELPER_3(DTSTEXQ, i32, env, fprp, fprp)
+DEF_HELPER_3(DTSTSF, i32, env, fprp, fprp)
+DEF_HELPER_3(DTSTSFQ, i32, env, fprp, fprp)
+DEF_HELPER_3(DTSTSFI, i32, env, i32, fprp)
+DEF_HELPER_3(DTSTSFIQ, i32, env, i32, fprp)
 DEF_HELPER_5(dquai, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(dquaiq, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(dqua, void, env, fprp, fprp, fprp, i32)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index c4a8cc7ec5..aaeccebca0 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -50,6 +50,18 @@
 _bi   rt bi
 @X_bi   .. rt:5 bi:5 - .. - _bi
 
+_bf   bf ra rb
+@X_bf   .. bf:3 .. ra:5 rb:5 

[PATCH v4 16/19] target/ppc: Move dquai[q], drint{x, n}[q] to decodetree

2021-10-25 Thread Luis Pires
Move the following instructions to decodetree:
dquai:   DFP Quantize Immediate
dquaiq:  DFP Quantize Immediate Quad
drintx:  DFP Round to FP Integer With Inexact
drintxq: DFP Round to FP Integer With Inexact Quad
drintn:  DFP Round to FP Integer Without Inexact
drintnq: DFP Round to FP Integer Without Inexact Quad

Signed-off-by: Luis Pires 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
---
 target/ppc/dfp_helper.c | 12 +++
 target/ppc/helper.h | 12 +++
 target/ppc/insn32.decode| 23 +
 target/ppc/translate/dfp-impl.c.inc | 51 +
 target/ppc/translate/dfp-ops.c.inc  | 18 --
 5 files changed, 58 insertions(+), 58 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 9be6809b33..df3e6c7cb1 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -751,8 +751,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b,\
 set_dfp##size(t, );  \
 }
 
-DFP_HELPER_QUAI(dquai, 64)
-DFP_HELPER_QUAI(dquaiq, 128)
+DFP_HELPER_QUAI(DQUAI, 64)
+DFP_HELPER_QUAI(DQUAIQ, 128)
 
 #define DFP_HELPER_QUA(op, size)\
 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a,\
@@ -873,8 +873,8 @@ static void RINTX_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXSNAN(dfp);
 }
 
-DFP_HELPER_RINT(drintx, RINTX_PPs, 64)
-DFP_HELPER_RINT(drintxq, RINTX_PPs, 128)
+DFP_HELPER_RINT(DRINTX, RINTX_PPs, 64)
+DFP_HELPER_RINT(DRINTXQ, RINTX_PPs, 128)
 
 static void RINTN_PPs(struct PPC_DFP *dfp)
 {
@@ -882,8 +882,8 @@ static void RINTN_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXSNAN(dfp);
 }
 
-DFP_HELPER_RINT(drintn, RINTN_PPs, 64)
-DFP_HELPER_RINT(drintnq, RINTN_PPs, 128)
+DFP_HELPER_RINT(DRINTN, RINTN_PPs, 64)
+DFP_HELPER_RINT(DRINTNQ, RINTN_PPs, 128)
 
 void helper_dctdp(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 22bf167b15..520cce8378 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -718,16 +718,16 @@ DEF_HELPER_3(DTSTSF, i32, env, fprp, fprp)
 DEF_HELPER_3(DTSTSFQ, i32, env, fprp, fprp)
 DEF_HELPER_3(DTSTSFI, i32, env, i32, fprp)
 DEF_HELPER_3(DTSTSFIQ, i32, env, i32, fprp)
-DEF_HELPER_5(dquai, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(dquaiq, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DQUAI, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DQUAIQ, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(dqua, void, env, fprp, fprp, fprp, i32)
 DEF_HELPER_5(dquaq, void, env, fprp, fprp, fprp, i32)
 DEF_HELPER_5(drrnd, void, env, fprp, fprp, fprp, i32)
 DEF_HELPER_5(drrndq, void, env, fprp, fprp, fprp, i32)
-DEF_HELPER_5(drintx, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(drintxq, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(drintn, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(drintnq, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DRINTX, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DRINTXQ, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DRINTN, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DRINTNQ, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_3(dctdp, void, env, fprp, fprp)
 DEF_HELPER_3(dctqpq, void, env, fprp, fprp)
 DEF_HELPER_3(drsp, void, env, fprp, fprp)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index aaeccebca0..f0e17580e0 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -77,6 +77,18 @@
 %z22_frap   17:4 !function=times_2
 @Z22_bf_frap.. bf:3 .. 0 dm:6 . .   _bf_fra 
fra=%z22_frap
 
+_tb frt frb r:bool rmc rc:bool
+@Z23_tb .. frt:5  r:1 frb:5 rmc:2  rc:1 _tb
+
+%z23_frtp   22:4 !function=times_2
+%z23_frbp   12:4 !function=times_2
+@Z23_tbp.. 0  r:1 0 rmc:2  rc:1 _tb 
frt=%z23_frtp frb=%z23_frbp
+
+_te_tb  te frt frb rmc rc:bool
+@Z23_te_tb  .. frt:5 te:5 frb:5 rmc:2  rc:1 _te_tb
+
+@Z23_te_tbp .. 0 te:5 0 rmc:2  rc:1 _te_tb 
frt=%z23_frtp frb=%z23_frbp
+
 ### Fixed-Point Load Instructions
 
 LBZ 100010 . .  @D
@@ -194,6 +206,17 @@ DTSTSFQ 11 ... -- . . 1010100010 -  
@X_bf_a_bp
 DTSTSFI 111011 ... - .. . 1010100011 -  @X_bf_uim
 DTSTSFIQ11 ... - .. . 1010100011 -  @X_bf_uim_bp
 
+### Decimal Floating-Point Quantum Adjustment Instructions
+
+DQUAI   111011 . . . .. 0111 .  @Z23_te_tb
+DQUAIQ  11 . . . .. 0111 .  @Z23_te_tbp
+
+DRINTX  111011 .  . . .. 01100011 . @Z23_tb
+DRINTXQ 11 .  . . .. 01100011 . @Z23_tbp
+
+DRINTN  111011 .  . . .. 11100011 . @Z23_tb
+DRINTNQ 11 .  . . .. 11100011 . @Z23_tbp
+
 ### Decimal Floating-Point Conversion 

[PATCH v4 05/19] libdecnumber: introduce decNumberFrom[U]Int128

2021-10-25 Thread Luis Pires
This will be used to implement PowerPC's dcffixqq.

Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 include/libdecnumber/decNumber.h |  2 ++
 libdecnumber/decNumber.c | 36 
 2 files changed, 38 insertions(+)

diff --git a/include/libdecnumber/decNumber.h b/include/libdecnumber/decNumber.h
index aa115fed07..0cf69c7db2 100644
--- a/include/libdecnumber/decNumber.h
+++ b/include/libdecnumber/decNumber.h
@@ -116,6 +116,8 @@
   decNumber * decNumberFromUInt32(decNumber *, uint32_t);
   decNumber *decNumberFromInt64(decNumber *, int64_t);
   decNumber *decNumberFromUInt64(decNumber *, uint64_t);
+  decNumber *decNumberFromInt128(decNumber *, uint64_t, int64_t);
+  decNumber *decNumberFromUInt128(decNumber *, uint64_t, uint64_t);
   decNumber * decNumberFromString(decNumber *, const char *, decContext *);
   char * decNumberToString(const decNumber *, char *);
   char * decNumberToEngString(const decNumber *, char *);
diff --git a/libdecnumber/decNumber.c b/libdecnumber/decNumber.c
index 1ffe458ad8..d7716ce175 100644
--- a/libdecnumber/decNumber.c
+++ b/libdecnumber/decNumber.c
@@ -167,6 +167,7 @@
 /* -- */
 
 #include "qemu/osdep.h"
+#include "qemu/host-utils.h"
 #include "libdecnumber/dconfig.h"
 #include "libdecnumber/decNumber.h"
 #include "libdecnumber/decNumberLocal.h"
@@ -462,6 +463,41 @@ decNumber *decNumberFromUInt64(decNumber *dn, uint64_t uin)
 return dn;
 } /* decNumberFromUInt64 */
 
+decNumber *decNumberFromInt128(decNumber *dn, uint64_t lo, int64_t hi)
+{
+uint64_t unsig_hi = hi;
+if (hi < 0) {
+if (lo == 0) {
+unsig_hi = -unsig_hi;
+} else {
+unsig_hi = ~unsig_hi;
+lo = -lo;
+}
+}
+
+decNumberFromUInt128(dn, lo, unsig_hi);
+if (hi < 0) {
+dn->bits = DECNEG;/* sign needed */
+}
+return dn;
+} /* decNumberFromInt128 */
+
+decNumber *decNumberFromUInt128(decNumber *dn, uint64_t lo, uint64_t hi)
+{
+uint64_t rem;
+Unit *up; /* work pointer */
+decNumberZero(dn);/* clean */
+if (lo == 0 && hi == 0) {
+return dn;/* [or decGetDigits bad call] */
+}
+for (up = dn->lsu; hi > 0 || lo > 0; up++) {
+rem = divu128(, , DECDPUNMAX + 1);
+*up = (Unit)rem;
+}
+dn->digits = decGetDigits(dn->lsu, up - dn->lsu);
+return dn;
+} /* decNumberFromUInt128 */
+
 /* -- */
 /* to-int64 -- conversion to int64*/
 /**/
-- 
2.25.1




[PATCH v4 14/19] target/ppc: Move d{add, sub, mul, div, iex}[q] to decodetree

2021-10-25 Thread Luis Pires
Move the following instructions to decodetree:
dadd:  DFP Add
daddq: DFP Add Quad
dsub:  DFP Subtract
dsubq: DFP Subtract Quad
dmul:  DFP Multiply
dmulq: DFP Multiply Quad
ddiv:  DFP Divide
ddivq: DFP Divide Quad
diex:  DFP Insert Biased Exponent
diexq: DFP Insert Biased Exponent Quad

Signed-off-by: Luis Pires 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
---
 target/ppc/dfp_helper.c | 20 +--
 target/ppc/helper.h | 20 +--
 target/ppc/insn32.decode| 31 ++--
 target/ppc/translate/dfp-impl.c.inc | 56 ++---
 target/ppc/translate/dfp-ops.c.inc  | 19 --
 5 files changed, 76 insertions(+), 70 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index f3c1e525a3..da8eaaaff1 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -445,8 +445,8 @@ static void ADD_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXISI_add(dfp);
 }
 
-DFP_HELPER_TAB(dadd, decNumberAdd, ADD_PPs, 64)
-DFP_HELPER_TAB(daddq, decNumberAdd, ADD_PPs, 128)
+DFP_HELPER_TAB(DADD, decNumberAdd, ADD_PPs, 64)
+DFP_HELPER_TAB(DADDQ, decNumberAdd, ADD_PPs, 128)
 
 static void SUB_PPs(struct PPC_DFP *dfp)
 {
@@ -458,8 +458,8 @@ static void SUB_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXISI_subtract(dfp);
 }
 
-DFP_HELPER_TAB(dsub, decNumberSubtract, SUB_PPs, 64)
-DFP_HELPER_TAB(dsubq, decNumberSubtract, SUB_PPs, 128)
+DFP_HELPER_TAB(DSUB, decNumberSubtract, SUB_PPs, 64)
+DFP_HELPER_TAB(DSUBQ, decNumberSubtract, SUB_PPs, 128)
 
 static void MUL_PPs(struct PPC_DFP *dfp)
 {
@@ -471,8 +471,8 @@ static void MUL_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXIMZ(dfp);
 }
 
-DFP_HELPER_TAB(dmul, decNumberMultiply, MUL_PPs, 64)
-DFP_HELPER_TAB(dmulq, decNumberMultiply, MUL_PPs, 128)
+DFP_HELPER_TAB(DMUL, decNumberMultiply, MUL_PPs, 64)
+DFP_HELPER_TAB(DMULQ, decNumberMultiply, MUL_PPs, 128)
 
 static void DIV_PPs(struct PPC_DFP *dfp)
 {
@@ -486,8 +486,8 @@ static void DIV_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXIDI(dfp);
 }
 
-DFP_HELPER_TAB(ddiv, decNumberDivide, DIV_PPs, 64)
-DFP_HELPER_TAB(ddivq, decNumberDivide, DIV_PPs, 128)
+DFP_HELPER_TAB(DDIV, decNumberDivide, DIV_PPs, 64)
+DFP_HELPER_TAB(DDIVQ, decNumberDivide, DIV_PPs, 128)
 
 #define DFP_HELPER_BF_AB(op, dnop, postprocs, size)
\
 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, ppc_fprp_t *b)   
\
@@ -1299,8 +1299,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *a,  \
 set_dfp##size(t, );\
 }
 
-DFP_HELPER_IEX(diex, 64)
-DFP_HELPER_IEX(diexq, 128)
+DFP_HELPER_IEX(DIEX, 64)
+DFP_HELPER_IEX(DIEXQ, 128)
 
 static void dfp_clear_lmd_from_g5msb(uint64_t *t)
 {
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 30e9247a5a..1f00e47b82 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -696,14 +696,14 @@ DEF_HELPER_3(store_601_batu, void, env, i32, tl)
 #define dh_alias_fprp ptr
 #define dh_ctype_fprp ppc_fprp_t *
 
-DEF_HELPER_4(dadd, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(daddq, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dsub, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dsubq, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dmul, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dmulq, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(ddiv, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(ddivq, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DADD, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DADDQ, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DSUB, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DSUBQ, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DMUL, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DMULQ, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DDIV, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DDIVQ, void, env, fprp, fprp, fprp)
 DEF_HELPER_3(dcmpo, i32, env, fprp, fprp)
 DEF_HELPER_3(dcmpoq, i32, env, fprp, fprp)
 DEF_HELPER_3(dcmpu, i32, env, fprp, fprp)
@@ -744,8 +744,8 @@ DEF_HELPER_4(denbcd, void, env, fprp, fprp, i32)
 DEF_HELPER_4(denbcdq, void, env, fprp, fprp, i32)
 DEF_HELPER_3(dxex, void, env, fprp, fprp)
 DEF_HELPER_3(dxexq, void, env, fprp, fprp)
-DEF_HELPER_4(diex, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(diexq, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DIEX, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DIEXQ, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(dscri, void, env, fprp, fprp, i32)
 DEF_HELPER_4(dscriq, void, env, fprp, fprp, i32)
 DEF_HELPER_4(dscli, void, env, fprp, fprp, i32)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 38f8525d54..c4a8cc7ec5 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -37,6 +37,16 @@
   rt ra rb
 @X  .. rt:5 ra:5 rb:5 .. .  
 
+_rc   rt ra rb rc:bool
+@X_rc   .. rt:5 ra:5 rb:5 .. rc:1   _rc
+
+%x_frtp 22:4 !function=times_2
+%x_frap 17:4 !function=times_2

[PATCH] hvf: arm: Ignore cache operations on MMIO

2021-10-25 Thread Alexander Graf
Apple's Hypervisor.Framework forwards cache operations as MMIO traps
into user space. For MMIO however, these have no meaning: There is no
cache attached to them.

So let's filter SYS instructions for DATA exits out and treat them as nops.

This fixes OpenBSD booting as guest.

Signed-off-by: Alexander Graf 
Reported-by: AJ Barris 
---
 target/arm/hvf/hvf.c | 32 
 1 file changed, 32 insertions(+)

diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
index bff3e0cde7..46ff4892a7 100644
--- a/target/arm/hvf/hvf.c
+++ b/target/arm/hvf/hvf.c
@@ -1098,6 +1098,33 @@ static void hvf_sync_vtimer(CPUState *cpu)
 }
 }
 
+static bool hvf_emulate_insn(CPUState *cpu)
+{
+ARMCPU *arm_cpu = ARM_CPU(cpu);
+CPUARMState *env = _cpu->env;
+uint32_t insn;
+
+/*
+ * We ran into an instruction that traps for data, but is not
+ * hardware predecoded. This should not ever happen for well
+ * behaved guests. Let's try to see if we can somehow rescue
+ * the situation.
+ */
+
+cpu_synchronize_state(cpu);
+if (cpu_memory_rw_debug(cpu, env->pc, , 4, 0)) {
+/* Could not read the instruction */
+return false;
+}
+
+if ((insn & 0xffc0) == 0xd500) {
+/* MSR/MRS/SYS/SYSL - happens for cache ops which are nops on data */
+return true;
+}
+
+return false;
+}
+
 int hvf_vcpu_exec(CPUState *cpu)
 {
 ARMCPU *arm_cpu = ARM_CPU(cpu);
@@ -1156,6 +1183,11 @@ int hvf_vcpu_exec(CPUState *cpu)
  hvf_exit->exception.physical_address, isv,
  iswrite, s1ptw, len, srt);
 
+if (!isv) {
+g_assert(hvf_emulate_insn(cpu));
+advance_pc = true;
+break;
+}
 assert(isv);
 
 if (iswrite) {
-- 
2.30.1 (Apple Git-130)




[PATCH v4 12/19] target/ppc: Do not update nip on DFP instructions

2021-10-25 Thread Luis Pires
Before moving the existing DFP instructions to decodetree, drop the
nip update that shouldn't be done for these instructions.

Signed-off-by: Luis Pires 
---
 target/ppc/translate/dfp-impl.c.inc | 8 
 1 file changed, 8 deletions(-)

diff --git a/target/ppc/translate/dfp-impl.c.inc 
b/target/ppc/translate/dfp-impl.c.inc
index e149777481..1431d955c6 100644
--- a/target/ppc/translate/dfp-impl.c.inc
+++ b/target/ppc/translate/dfp-impl.c.inc
@@ -15,7 +15,6 @@ static void gen_##name(DisasContext *ctx)\
 gen_exception(ctx, POWERPC_EXCP_FPU);\
 return;  \
 }\
-gen_update_nip(ctx, ctx->base.pc_next - 4);  \
 rd = gen_fprp_ptr(rD(ctx->opcode));  \
 ra = gen_fprp_ptr(rA(ctx->opcode));  \
 rb = gen_fprp_ptr(rB(ctx->opcode));  \
@@ -36,7 +35,6 @@ static void gen_##name(DisasContext *ctx) \
 gen_exception(ctx, POWERPC_EXCP_FPU); \
 return;   \
 } \
-gen_update_nip(ctx, ctx->base.pc_next - 4);\
 ra = gen_fprp_ptr(rA(ctx->opcode));   \
 rb = gen_fprp_ptr(rB(ctx->opcode));   \
 gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \
@@ -54,7 +52,6 @@ static void gen_##name(DisasContext *ctx) \
 gen_exception(ctx, POWERPC_EXCP_FPU); \
 return;   \
 } \
-gen_update_nip(ctx, ctx->base.pc_next - 4);\
 uim = tcg_const_i32(UIMM5(ctx->opcode));  \
 rb = gen_fprp_ptr(rB(ctx->opcode));   \
 gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \
@@ -72,7 +69,6 @@ static void gen_##name(DisasContext *ctx) \
 gen_exception(ctx, POWERPC_EXCP_FPU); \
 return;   \
 } \
-gen_update_nip(ctx, ctx->base.pc_next - 4);   \
 ra = gen_fprp_ptr(rA(ctx->opcode));   \
 dcm = tcg_const_i32(DCM(ctx->opcode));\
 gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \
@@ -90,7 +86,6 @@ static void gen_##name(DisasContext *ctx) \
 gen_exception(ctx, POWERPC_EXCP_FPU); \
 return;   \
 } \
-gen_update_nip(ctx, ctx->base.pc_next - 4);   \
 rt = gen_fprp_ptr(rD(ctx->opcode));   \
 rb = gen_fprp_ptr(rB(ctx->opcode));   \
 u32_1 = tcg_const_i32(u32f1(ctx->opcode));\
@@ -114,7 +109,6 @@ static void gen_##name(DisasContext *ctx)\
 gen_exception(ctx, POWERPC_EXCP_FPU);\
 return;  \
 }\
-gen_update_nip(ctx, ctx->base.pc_next - 4);  \
 rt = gen_fprp_ptr(rD(ctx->opcode));  \
 ra = gen_fprp_ptr(rA(ctx->opcode));  \
 rb = gen_fprp_ptr(rB(ctx->opcode));  \
@@ -137,7 +131,6 @@ static void gen_##name(DisasContext *ctx)\
 gen_exception(ctx, POWERPC_EXCP_FPU);\
 return;  \
 }\
-gen_update_nip(ctx, ctx->base.pc_next - 4);  \
 rt = gen_fprp_ptr(rD(ctx->opcode));  \
 rb = gen_fprp_ptr(rB(ctx->opcode));  \
 gen_helper_##name(cpu_env, rt, rb);  \
@@ -157,7 +150,6 @@ static void gen_##name(DisasContext *ctx)  \
 gen_exception(ctx, POWERPC_EXCP_FPU);  \
 return;\
 }  \
-gen_update_nip(ctx, ctx->base.pc_next - 4);\
 rt = gen_fprp_ptr(rD(ctx->opcode));\
 rs = gen_fprp_ptr(fprfld(ctx->opcode));\
 i32 = tcg_const_i32(i32fld(ctx->opcode));  \
-- 
2.25.1




[PATCH v4 13/19] target/ppc: Move dtstdc[q]/dtstdg[q] to decodetree

2021-10-25 Thread Luis Pires
Move the following instructions to decodetree:
dtstdc:  DFP Test Data Class
dtstdcq: DFP Test Data Class Quad
dtstdg:  DFP Test Data Group
dtstdgq: DFP Test Data Group Quad

Signed-off-by: Luis Pires 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
---
 target/ppc/dfp_helper.c |  8 +++
 target/ppc/helper.h |  8 +++
 target/ppc/insn32.decode| 14 
 target/ppc/translate/dfp-impl.c.inc | 35 +
 target/ppc/translate/dfp-ops.c.inc  | 10 -
 5 files changed, 37 insertions(+), 38 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 6ab46d7db5..f3c1e525a3 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -546,8 +546,8 @@ uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, 
uint32_t dcm)  \
 return dfp.crbf; \
 }
 
-DFP_HELPER_TSTDC(dtstdc, 64)
-DFP_HELPER_TSTDC(dtstdcq, 128)
+DFP_HELPER_TSTDC(DTSTDC, 64)
+DFP_HELPER_TSTDC(DTSTDCQ, 128)
 
 #define DFP_HELPER_TSTDG(op, size)   \
 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, uint32_t dcm)  \
@@ -601,8 +601,8 @@ uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, 
uint32_t dcm)  \
 return dfp.crbf; \
 }
 
-DFP_HELPER_TSTDG(dtstdg, 64)
-DFP_HELPER_TSTDG(dtstdgq, 128)
+DFP_HELPER_TSTDG(DTSTDG, 64)
+DFP_HELPER_TSTDG(DTSTDGQ, 128)
 
 #define DFP_HELPER_TSTEX(op, size)   \
 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, ppc_fprp_t *b) \
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 20041ce977..30e9247a5a 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -708,10 +708,10 @@ DEF_HELPER_3(dcmpo, i32, env, fprp, fprp)
 DEF_HELPER_3(dcmpoq, i32, env, fprp, fprp)
 DEF_HELPER_3(dcmpu, i32, env, fprp, fprp)
 DEF_HELPER_3(dcmpuq, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstdc, i32, env, fprp, i32)
-DEF_HELPER_3(dtstdcq, i32, env, fprp, i32)
-DEF_HELPER_3(dtstdg, i32, env, fprp, i32)
-DEF_HELPER_3(dtstdgq, i32, env, fprp, i32)
+DEF_HELPER_3(DTSTDC, i32, env, fprp, i32)
+DEF_HELPER_3(DTSTDCQ, i32, env, fprp, i32)
+DEF_HELPER_3(DTSTDG, i32, env, fprp, i32)
+DEF_HELPER_3(DTSTDGQ, i32, env, fprp, i32)
 DEF_HELPER_3(dtstex, i32, env, fprp, fprp)
 DEF_HELPER_3(dtstexq, i32, env, fprp, fprp)
 DEF_HELPER_3(dtstsf, i32, env, fprp, fprp)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 6d97f9ae3b..38f8525d54 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -51,6 +51,12 @@
 %x_frbp 12:4 !function=times_2
 @X_vrt_frbp .. vrt:5 . 0 .. .   _vrt_frbp 
frbp=%x_frbp
 
+_bf_fra bf fra dm
+@Z22_bf_fra .. bf:3 .. fra:5 dm:6 . .   _bf_fra
+
+%z22_frap   17:4 !function=times_2
+@Z22_bf_frap.. bf:3 .. 0 dm:6 . .   _bf_fra 
fra=%z22_frap
+
 ### Fixed-Point Load Instructions
 
 LBZ 100010 . .  @D
@@ -129,6 +135,14 @@ SETBCR  01 . . - 011010 -   
@X_bi
 SETNBC  01 . . - 011100 -   @X_bi
 SETNBCR 01 . . - 00 -   @X_bi
 
+### Decimal Floating-Point Test Instructions
+
+DTSTDC  111011 ... -- . .. 01110 -  @Z22_bf_fra
+DTSTDCQ 11 ... -- . .. 01110 -  @Z22_bf_frap
+
+DTSTDG  111011 ... -- . .. 011100010 -  @Z22_bf_fra
+DTSTDGQ 11 ... -- . .. 011100010 -  @Z22_bf_frap
+
 ### Decimal Floating-Point Conversion Instructions
 
 DCFFIXQQ11 . 0 . 100010 -   @X_frtp_vrb
diff --git a/target/ppc/translate/dfp-impl.c.inc 
b/target/ppc/translate/dfp-impl.c.inc
index 1431d955c6..1a30c51467 100644
--- a/target/ppc/translate/dfp-impl.c.inc
+++ b/target/ppc/translate/dfp-impl.c.inc
@@ -60,21 +60,17 @@ static void gen_##name(DisasContext *ctx) \
 tcg_temp_free_ptr(rb);\
 }
 
-#define GEN_DFP_BF_A_DCM(name)\
-static void gen_##name(DisasContext *ctx) \
-{ \
-TCGv_ptr ra;  \
-TCGv_i32 dcm; \
-if (unlikely(!ctx->fpu_enabled)) {\
-gen_exception(ctx, POWERPC_EXCP_FPU); \
-return;   \
-} \
-ra = gen_fprp_ptr(rA(ctx->opcode));   \
-dcm = tcg_const_i32(DCM(ctx->opcode));\
-gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \
-  cpu_env, ra, dcm);  \
-tcg_temp_free_ptr(ra);\
-tcg_temp_free_i32(dcm);   \
+#define TRANS_DFP_BF_A_DCM(NAME) \

[PATCH v4 04/19] host-utils: add unit tests for divu128/divs128

2021-10-25 Thread Luis Pires
Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 tests/unit/meson.build   |   1 +
 tests/unit/test-div128.c | 197 +++
 2 files changed, 198 insertions(+)
 create mode 100644 tests/unit/test-div128.c

diff --git a/tests/unit/meson.build b/tests/unit/meson.build
index 7c297d7e5c..5ac2d9e943 100644
--- a/tests/unit/meson.build
+++ b/tests/unit/meson.build
@@ -23,6 +23,7 @@ tests = {
   # all code tested by test-x86-cpuid is inside topology.h
   'test-x86-cpuid': [],
   'test-cutils': [],
+  'test-div128': [],
   'test-shift128': [],
   'test-mul64': [],
   # all code tested by test-int128 is inside int128.h
diff --git a/tests/unit/test-div128.c b/tests/unit/test-div128.c
new file mode 100644
index 00..0bc25fe4a8
--- /dev/null
+++ b/tests/unit/test-div128.c
@@ -0,0 +1,197 @@
+/*
+ * Test 128-bit division functions
+ *
+ * Copyright (c) 2021 Instituto de Pesquisas Eldorado (eldorado.org.br)
+ *
+ * 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 .
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/host-utils.h"
+
+typedef struct {
+uint64_t high;
+uint64_t low;
+uint64_t rhigh;
+uint64_t rlow;
+uint64_t divisor;
+uint64_t remainder;
+} test_data_unsigned;
+
+typedef struct {
+int64_t high;
+uint64_t low;
+int64_t rhigh;
+uint64_t rlow;
+int64_t divisor;
+int64_t remainder;
+} test_data_signed;
+
+static const test_data_unsigned test_table_unsigned[] = {
+/* Dividend fits in 64 bits */
+{ 0xULL, 0xULL,
+  0xULL, 0xULL,
+  0x0001ULL, 0xULL},
+{ 0xULL, 0x0001ULL,
+  0xULL, 0x0001ULL,
+  0x0001ULL, 0xULL},
+{ 0xULL, 0x0003ULL,
+  0xULL, 0x0001ULL,
+  0x0002ULL, 0x0001ULL},
+{ 0xULL, 0x8000ULL,
+  0xULL, 0x8000ULL,
+  0x0001ULL, 0xULL},
+{ 0xULL, 0xa000ULL,
+  0xULL, 0x0002ULL,
+  0x4000ULL, 0x2000ULL},
+{ 0xULL, 0x8000ULL,
+  0xULL, 0x0001ULL,
+  0x8000ULL, 0xULL},
+
+/* Dividend > 64 bits, with MSB 0 */
+{ 0x123456789abcdefeULL, 0xefedcba987654321ULL,
+  0x123456789abcdefeULL, 0xefedcba987654321ULL,
+  0x0001ULL, 0xULL},
+{ 0x123456789abcdefeULL, 0xefedcba987654321ULL,
+  0x0001ULL, 0x000dULL,
+  0x123456789abcdefeULL, 0x03456789abcdf03bULL},
+{ 0x123456789abcdefeULL, 0xefedcba987654321ULL,
+  0x0123456789abcdefULL, 0xeefedcba98765432ULL,
+  0x0010ULL, 0x0001ULL},
+
+/* Dividend > 64 bits, with MSB 1 */
+{ 0xfeeddccbbaa99887ULL, 0x766554433221100fULL,
+  0xfeeddccbbaa99887ULL, 0x766554433221100fULL,
+  0x0001ULL, 0xULL},
+{ 0xfeeddccbbaa99887ULL, 0x766554433221100fULL,
+  0x0001ULL, 0xULL,
+  0xfeeddccbbaa99887ULL, 0x766554433221100fULL},
+{ 0xfeeddccbbaa99887ULL, 0x766554433221100fULL,
+  0x0feeddccbbaa9988ULL, 0x7766554433221100ULL,
+  0x0010ULL, 0x000fULL},
+{ 0xfeeddccbbaa99887ULL, 0x766554433221100fULL,
+  0x000eULL, 0x00f0f0f0f0f0f35aULL,
+  0x123456789abcdefeULL, 0x0f8922bc55ef90c3ULL},
+
+/**
+ * Divisor == 64 bits, with MSB 1
+ * and high 64 bits of dividend >= divisor
+ * (for testing normalization)
+ */
+{ 0xfeeddccbbaa99887ULL, 0x766554433221100fULL,
+  0x0001ULL, 0xULL,
+  0xfeeddccbbaa99887ULL, 0x766554433221100fULL},
+{ 0xfeeddccbbaa99887ULL, 0x766554433221100fULL,
+  0x0001ULL, 0xfddbb9977553310aULL,
+  0x8001ULL, 0x78899aabbccddf05ULL},
+
+/* Dividend > 64 bits, divisor almost as big */
+{ 0x0001ULL, 0x23456789abcdef01ULL,
+  0xULL, 0x000fULL,
+  0x123456789abcdefeULL, 0x123456789abcde1fULL},
+};
+
+static 

[PATCH v4 01/19] host-utils: move checks out of divu128/divs128

2021-10-25 Thread Luis Pires
In preparation for changing the divu128/divs128 implementations
to allow for quotients larger than 64 bits, move the div-by-zero
and overflow checks to the callers.

Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 include/hw/clock.h|  5 +++--
 include/qemu/host-utils.h | 36 +--
 target/ppc/int_helper.c   | 14 +-
 util/host-utils.c | 40 ++-
 4 files changed, 43 insertions(+), 52 deletions(-)

diff --git a/include/hw/clock.h b/include/hw/clock.h
index 11f67fb970..7443e6c4ab 100644
--- a/include/hw/clock.h
+++ b/include/hw/clock.h
@@ -324,8 +324,9 @@ static inline uint64_t clock_ns_to_ticks(const Clock *clk, 
uint64_t ns)
 return 0;
 }
 /*
- * Ignore divu128() return value as we've caught div-by-zero and don't
- * need different behaviour for overflow.
+ * BUG: when CONFIG_INT128 is not defined, the current implementation of
+ * divu128 does not return a valid truncated quotient, so the result will
+ * be wrong.
  */
 divu128(, , clk->period);
 return lo;
diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index ca9f3f021b..e82e6239af 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -52,36 +52,26 @@ static inline uint64_t muldiv64(uint64_t a, uint32_t b, 
uint32_t c)
 return (__int128_t)a * b / c;
 }
 
-static inline int divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
-{
-if (divisor == 0) {
-return 1;
-} else {
-__uint128_t dividend = ((__uint128_t)*phigh << 64) | *plow;
-__uint128_t result = dividend / divisor;
-*plow = result;
-*phigh = dividend % divisor;
-return result > UINT64_MAX;
-}
+static inline void divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
+{
+__uint128_t dividend = ((__uint128_t)*phigh << 64) | *plow;
+__uint128_t result = dividend / divisor;
+*plow = result;
+*phigh = dividend % divisor;
 }
 
-static inline int divs128(int64_t *plow, int64_t *phigh, int64_t divisor)
+static inline void divs128(int64_t *plow, int64_t *phigh, int64_t divisor)
 {
-if (divisor == 0) {
-return 1;
-} else {
-__int128_t dividend = ((__int128_t)*phigh << 64) | (uint64_t)*plow;
-__int128_t result = dividend / divisor;
-*plow = result;
-*phigh = dividend % divisor;
-return result != *plow;
-}
+__int128_t dividend = ((__int128_t)*phigh << 64) | (uint64_t)*plow;
+__int128_t result = dividend / divisor;
+*plow = result;
+*phigh = dividend % divisor;
 }
 #else
 void muls64(uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b);
 void mulu64(uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b);
-int divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor);
-int divs128(int64_t *plow, int64_t *phigh, int64_t divisor);
+void divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor);
+void divs128(int64_t *plow, int64_t *phigh, int64_t divisor);
 
 static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
 {
diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c
index f5dac3aa87..510faf24cf 100644
--- a/target/ppc/int_helper.c
+++ b/target/ppc/int_helper.c
@@ -104,10 +104,11 @@ uint64_t helper_divdeu(CPUPPCState *env, uint64_t ra, 
uint64_t rb, uint32_t oe)
 uint64_t rt = 0;
 int overflow = 0;
 
-overflow = divu128(, , rb);
-
-if (unlikely(overflow)) {
+if (unlikely(rb == 0 || ra >= rb)) {
+overflow = 1;
 rt = 0; /* Undefined */
+} else {
+divu128(, , rb);
 }
 
 if (oe) {
@@ -122,10 +123,13 @@ uint64_t helper_divde(CPUPPCState *env, uint64_t rau, 
uint64_t rbu, uint32_t oe)
 int64_t rt = 0;
 int64_t ra = (int64_t)rau;
 int64_t rb = (int64_t)rbu;
-int overflow = divs128(, , rb);
+int overflow = 0;
 
-if (unlikely(overflow)) {
+if (unlikely(rb == 0 || uabs64(ra) >= uabs64(rb))) {
+overflow = 1;
 rt = 0; /* Undefined */
+} else {
+divs128(, , rb);
 }
 
 if (oe) {
diff --git a/util/host-utils.c b/util/host-utils.c
index a789a11b46..701a371843 100644
--- a/util/host-utils.c
+++ b/util/host-utils.c
@@ -86,24 +86,23 @@ void muls64 (uint64_t *plow, uint64_t *phigh, int64_t a, 
int64_t b)
 *phigh = rh;
 }
 
-/* Unsigned 128x64 division.  Returns 1 if overflow (divide by zero or */
-/* quotient exceeds 64 bits).  Otherwise returns quotient via plow and */
-/* remainder via phigh. */
-int divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
+/*
+ * Unsigned 128-by-64 division. Returns quotient via plow and
+ * remainder via phigh.
+ * The result must fit in 64 bits (plow) - otherwise, the result
+ * is undefined.
+ * This function will cause a division by zero if passed a zero divisor.
+ */
+void divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
 {
 uint64_t dhi = *phigh;
 uint64_t dlo = *plow;

[PATCH v4 03/19] host-utils: add 128-bit quotient support to divu128/divs128

2021-10-25 Thread Luis Pires
These will be used to implement new decimal floating point
instructions from Power ISA 3.1.

The remainder is now returned directly by divu128/divs128,
freeing up phigh to receive the high 64 bits of the quotient.

Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 include/hw/clock.h|   6 +-
 include/qemu/host-utils.h |  20 +++---
 target/ppc/int_helper.c   |   9 +--
 util/host-utils.c | 127 ++
 4 files changed, 105 insertions(+), 57 deletions(-)

diff --git a/include/hw/clock.h b/include/hw/clock.h
index 7443e6c4ab..5c927cee7f 100644
--- a/include/hw/clock.h
+++ b/include/hw/clock.h
@@ -323,11 +323,7 @@ static inline uint64_t clock_ns_to_ticks(const Clock *clk, 
uint64_t ns)
 if (clk->period == 0) {
 return 0;
 }
-/*
- * BUG: when CONFIG_INT128 is not defined, the current implementation of
- * divu128 does not return a valid truncated quotient, so the result will
- * be wrong.
- */
+
 divu128(, , clk->period);
 return lo;
 }
diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index 08a17e16e5..a3a7ced78d 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -56,26 +56,32 @@ static inline uint64_t muldiv64(uint64_t a, uint32_t b, 
uint32_t c)
 return (__int128_t)a * b / c;
 }
 
-static inline void divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
+static inline uint64_t divu128(uint64_t *plow, uint64_t *phigh,
+   uint64_t divisor)
 {
 __uint128_t dividend = ((__uint128_t)*phigh << 64) | *plow;
 __uint128_t result = dividend / divisor;
+
 *plow = result;
-*phigh = dividend % divisor;
+*phigh = result >> 64;
+return dividend % divisor;
 }
 
-static inline void divs128(int64_t *plow, int64_t *phigh, int64_t divisor)
+static inline int64_t divs128(uint64_t *plow, int64_t *phigh,
+  int64_t divisor)
 {
-__int128_t dividend = ((__int128_t)*phigh << 64) | (uint64_t)*plow;
+__int128_t dividend = ((__int128_t)*phigh << 64) | *plow;
 __int128_t result = dividend / divisor;
+
 *plow = result;
-*phigh = dividend % divisor;
+*phigh = result >> 64;
+return dividend % divisor;
 }
 #else
 void muls64(uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b);
 void mulu64(uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b);
-void divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor);
-void divs128(int64_t *plow, int64_t *phigh, int64_t divisor);
+uint64_t divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor);
+int64_t divs128(uint64_t *plow, int64_t *phigh, int64_t divisor);
 
 static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
 {
diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c
index 510faf24cf..eeb7781a9e 100644
--- a/target/ppc/int_helper.c
+++ b/target/ppc/int_helper.c
@@ -120,7 +120,7 @@ uint64_t helper_divdeu(CPUPPCState *env, uint64_t ra, 
uint64_t rb, uint32_t oe)
 
 uint64_t helper_divde(CPUPPCState *env, uint64_t rau, uint64_t rbu, uint32_t 
oe)
 {
-int64_t rt = 0;
+uint64_t rt = 0;
 int64_t ra = (int64_t)rau;
 int64_t rb = (int64_t)rbu;
 int overflow = 0;
@@ -2506,6 +2506,7 @@ uint32_t helper_bcdcfsq(ppc_avr_t *r, ppc_avr_t *b, 
uint32_t ps)
 int cr;
 uint64_t lo_value;
 uint64_t hi_value;
+uint64_t rem;
 ppc_avr_t ret = { .u64 = { 0, 0 } };
 
 if (b->VsrSD(0) < 0) {
@@ -2541,10 +2542,10 @@ uint32_t helper_bcdcfsq(ppc_avr_t *r, ppc_avr_t *b, 
uint32_t ps)
  * In that case, we leave r unchanged.
  */
 } else {
-divu128(_value, _value, 1000ULL);
+rem = divu128(_value, _value, 1000ULL);
 
-for (i = 1; i < 16; hi_value /= 10, i++) {
-bcd_put_digit(, hi_value % 10, i);
+for (i = 1; i < 16; rem /= 10, i++) {
+bcd_put_digit(, rem % 10, i);
 }
 
 for (; i < 32; lo_value /= 10, i++) {
diff --git a/util/host-utils.c b/util/host-utils.c
index 701a371843..bcc772b8ec 100644
--- a/util/host-utils.c
+++ b/util/host-utils.c
@@ -87,72 +87,117 @@ void muls64 (uint64_t *plow, uint64_t *phigh, int64_t a, 
int64_t b)
 }
 
 /*
- * Unsigned 128-by-64 division. Returns quotient via plow and
- * remainder via phigh.
- * The result must fit in 64 bits (plow) - otherwise, the result
- * is undefined.
- * This function will cause a division by zero if passed a zero divisor.
+ * Unsigned 128-by-64 division.
+ * Returns the remainder.
+ * Returns quotient via plow and phigh.
+ * Also returns the remainder via the function return value.
  */
-void divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
+uint64_t divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
 {
 uint64_t dhi = *phigh;
 uint64_t dlo = *plow;
-unsigned i;
-uint64_t carry = 0;
+uint64_t rem, dhighest;
+int sh;
 
 if (divisor == 0 || dhi == 0) {
 *plow  = dlo / 

[PATCH v4 08/19] target/ppc: Implement DCFFIXQQ

2021-10-25 Thread Luis Pires
Implement the following PowerISA v3.1 instruction:
dcffixqq: DFP Convert From Fixed Quadword Quad

Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 target/ppc/dfp_helper.c | 12 
 target/ppc/helper.h |  1 +
 target/ppc/insn32.decode|  8 
 target/ppc/translate.c  |  5 +
 target/ppc/translate/dfp-impl.c.inc | 17 +
 5 files changed, 43 insertions(+)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 07341a69f5..6b837c4450 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -970,6 +970,18 @@ static void CFFIX_PPs(struct PPC_DFP *dfp)
 DFP_HELPER_CFFIX(dcffix, 64)
 DFP_HELPER_CFFIX(dcffixq, 128)
 
+void helper_DCFFIXQQ(CPUPPCState *env, ppc_fprp_t *t, ppc_avr_t *b)
+{
+struct PPC_DFP dfp;
+
+dfp_prepare_decimal128(, NULL, NULL, env);
+decNumberFromInt128(, (uint64_t)b->VsrD(1), (int64_t)b->VsrD(0));
+dfp_finalize_decimal128();
+CFFIX_PPs();
+
+set_dfp128(t, );
+}
+
 #define DFP_HELPER_CTFIX(op, size)\
 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)  \
 { \
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 4076aa281e..fff7bd46ad 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -734,6 +734,7 @@ DEF_HELPER_3(drsp, void, env, fprp, fprp)
 DEF_HELPER_3(drdpq, void, env, fprp, fprp)
 DEF_HELPER_3(dcffix, void, env, fprp, fprp)
 DEF_HELPER_3(dcffixq, void, env, fprp, fprp)
+DEF_HELPER_3(DCFFIXQQ, void, env, fprp, avr)
 DEF_HELPER_3(dctfix, void, env, fprp, fprp)
 DEF_HELPER_3(dctfixq, void, env, fprp, fprp)
 DEF_HELPER_4(ddedpd, void, env, fprp, fprp, i32)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 9fd8d6b817..92ea2d0739 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -43,6 +43,10 @@
 _bfl  bf l:bool ra rb
 @X_bfl  .. bf:3 - l:1 ra:5 rb:5 ..- _bfl
 
+_frtp_vrb frtp vrb
+%x_frtp 22:4 !function=times_2
+@X_frtp_vrb .. 0 . vrb:5 .. .   _frtp_vrb 
frtp=%x_frtp
+
 ### Fixed-Point Load Instructions
 
 LBZ 100010 . .  @D
@@ -121,6 +125,10 @@ SETBCR  01 . . - 011010 -   
@X_bi
 SETNBC  01 . . - 011100 -   @X_bi
 SETNBCR 01 . . - 00 -   @X_bi
 
+### Decimal Floating-Point Conversion Instructions
+
+DCFFIXQQ11 . 0 . 100010 -   @X_frtp_vrb
+
 ## Vector Bit Manipulation Instruction
 
 VCFUGED 000100 . . . 10101001101@VX
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 48a484eef6..6224cb3211 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -7438,6 +7438,11 @@ static inline void set_avr64(int regno, TCGv_i64 src, 
bool high)
 /*
  * Helpers for decodetree used by !function for decoding arguments.
  */
+static int times_2(DisasContext *ctx, int x)
+{
+return x * 2;
+}
+
 static int times_4(DisasContext *ctx, int x)
 {
 return x * 4;
diff --git a/target/ppc/translate/dfp-impl.c.inc 
b/target/ppc/translate/dfp-impl.c.inc
index 6c556dc2e1..d5b66567a6 100644
--- a/target/ppc/translate/dfp-impl.c.inc
+++ b/target/ppc/translate/dfp-impl.c.inc
@@ -230,3 +230,20 @@ GEN_DFP_T_FPR_I32_Rc(dscriq, rA, DCM)
 #undef GEN_DFP_T_A_B_I32_Rc
 #undef GEN_DFP_T_B_Rc
 #undef GEN_DFP_T_FPR_I32_Rc
+
+static bool trans_DCFFIXQQ(DisasContext *ctx, arg_DCFFIXQQ *a)
+{
+TCGv_ptr rt, rb;
+
+REQUIRE_INSNS_FLAGS2(ctx, DFP);
+REQUIRE_FPU(ctx);
+REQUIRE_VECTOR(ctx);
+
+rt = gen_fprp_ptr(a->frtp);
+rb = gen_avr_ptr(a->vrb);
+gen_helper_DCFFIXQQ(cpu_env, rt, rb);
+tcg_temp_free_ptr(rt);
+tcg_temp_free_ptr(rb);
+
+return true;
+}
-- 
2.25.1




[PATCH v4 02/19] host-utils: move udiv_qrnnd() to host-utils

2021-10-25 Thread Luis Pires
Move udiv_qrnnd() from include/fpu/softfloat-macros.h to host-utils,
so it can be reused by divu128().

Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 include/fpu/softfloat-macros.h | 82 --
 include/qemu/host-utils.h  | 81 +
 2 files changed, 81 insertions(+), 82 deletions(-)

diff --git a/include/fpu/softfloat-macros.h b/include/fpu/softfloat-macros.h
index 81c3fe8256..f35cdbfa63 100644
--- a/include/fpu/softfloat-macros.h
+++ b/include/fpu/softfloat-macros.h
@@ -8,7 +8,6 @@
  * so some portions are provided under:
  *  the SoftFloat-2a license
  *  the BSD license
- *  GPL-v2-or-later
  *
  * Any future contributions to this file after December 1st 2014 will be
  * taken to be licensed under the Softfloat-2a license unless specifically
@@ -75,10 +74,6 @@ this code that are retained.
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/* Portions of this work are licensed under the terms of the GNU GPL,
- * version 2 or later. See the COPYING file in the top-level directory.
- */
-
 #ifndef FPU_SOFTFLOAT_MACROS_H
 #define FPU_SOFTFLOAT_MACROS_H
 
@@ -585,83 +580,6 @@ static inline uint64_t estimateDiv128To64(uint64_t a0, 
uint64_t a1, uint64_t b)
 
 }
 
-/* From the GNU Multi Precision Library - longlong.h __udiv_qrnnd
- * (https://gmplib.org/repo/gmp/file/tip/longlong.h)
- *
- * Licensed under the GPLv2/LGPLv3
- */
-static inline uint64_t udiv_qrnnd(uint64_t *r, uint64_t n1,
-  uint64_t n0, uint64_t d)
-{
-#if defined(__x86_64__)
-uint64_t q;
-asm("divq %4" : "=a"(q), "=d"(*r) : "0"(n0), "1"(n1), "rm"(d));
-return q;
-#elif defined(__s390x__) && !defined(__clang__)
-/* Need to use a TImode type to get an even register pair for DLGR.  */
-unsigned __int128 n = (unsigned __int128)n1 << 64 | n0;
-asm("dlgr %0, %1" : "+r"(n) : "r"(d));
-*r = n >> 64;
-return n;
-#elif defined(_ARCH_PPC64) && defined(_ARCH_PWR7)
-/* From Power ISA 2.06, programming note for divdeu.  */
-uint64_t q1, q2, Q, r1, r2, R;
-asm("divdeu %0,%2,%4; divdu %1,%3,%4"
-: "="(q1), "=r"(q2)
-: "r"(n1), "r"(n0), "r"(d));
-r1 = -(q1 * d); /* low part of (n1<<64) - (q1 * d) */
-r2 = n0 - (q2 * d);
-Q = q1 + q2;
-R = r1 + r2;
-if (R >= d || R < r2) { /* overflow implies R > d */
-Q += 1;
-R -= d;
-}
-*r = R;
-return Q;
-#else
-uint64_t d0, d1, q0, q1, r1, r0, m;
-
-d0 = (uint32_t)d;
-d1 = d >> 32;
-
-r1 = n1 % d1;
-q1 = n1 / d1;
-m = q1 * d0;
-r1 = (r1 << 32) | (n0 >> 32);
-if (r1 < m) {
-q1 -= 1;
-r1 += d;
-if (r1 >= d) {
-if (r1 < m) {
-q1 -= 1;
-r1 += d;
-}
-}
-}
-r1 -= m;
-
-r0 = r1 % d1;
-q0 = r1 / d1;
-m = q0 * d0;
-r0 = (r0 << 32) | (uint32_t)n0;
-if (r0 < m) {
-q0 -= 1;
-r0 += d;
-if (r0 >= d) {
-if (r0 < m) {
-q0 -= 1;
-r0 += d;
-}
-}
-}
-r0 -= m;
-
-*r = r0;
-return (q1 << 32) | q0;
-#endif
-}
-
 /*
 | Returns an approximation to the square root of the 32-bit significand given
 | by `a'.  Considered as an integer, `a' must be at least 2^31.  If bit 0 of
diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index e82e6239af..08a17e16e5 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -23,6 +23,10 @@
  * THE SOFTWARE.
  */
 
+/* Portions of this work are licensed under the terms of the GNU GPL,
+ * version 2 or later. See the COPYING file in the top-level directory.
+ */
+
 #ifndef HOST_UTILS_H
 #define HOST_UTILS_H
 
@@ -726,4 +730,81 @@ void urshift(uint64_t *plow, uint64_t *phigh, int32_t 
shift);
  */
 void ulshift(uint64_t *plow, uint64_t *phigh, int32_t shift, bool *overflow);
 
+/* From the GNU Multi Precision Library - longlong.h __udiv_qrnnd
+ * (https://gmplib.org/repo/gmp/file/tip/longlong.h)
+ *
+ * Licensed under the GPLv2/LGPLv3
+ */
+static inline uint64_t udiv_qrnnd(uint64_t *r, uint64_t n1,
+  uint64_t n0, uint64_t d)
+{
+#if defined(__x86_64__)
+uint64_t q;
+asm("divq %4" : "=a"(q), "=d"(*r) : "0"(n0), "1"(n1), "rm"(d));
+return q;
+#elif defined(__s390x__) && !defined(__clang__)
+/* Need to use a TImode type to get an even register pair for DLGR.  */
+unsigned __int128 n = (unsigned __int128)n1 << 64 | n0;
+asm("dlgr %0, %1" : "+r"(n) : "r"(d));
+*r = n >> 64;
+return n;
+#elif defined(_ARCH_PPC64) && defined(_ARCH_PWR7)
+/* From Power ISA 2.06, programming note for divdeu.  */
+uint64_t q1, q2, Q, r1, r2, R;
+asm("divdeu %0,%2,%4; divdu %1,%3,%4"
+: "="(q1), "=r"(q2)
+: "r"(n1), "r"(n0), "r"(d));
+r1 = -(q1 * d); /* low part of 

[PATCH v4 00/19] target/ppc: DFP instructions using decodetree

2021-10-25 Thread Luis Pires
This series moves all existing DFP instructions to decodetree and
implements the 2 new instructions (dcffixqq and dctfixqq) from
Power ISA 3.1.

In order to implement dcffixqq, divu128/divs128 were modified to
support 128-bit quotients (previously, they were limited to 64-bit
quotients), along with adjustments being made to their existing callers.
libdecnumber was also expanded to allow creating decimal numbers from
128-bit integers.

Similarly, for dctfixqq, mulu128 (host-utils) and decNumberIntegralToInt128
(libdecnumber) were introduced to support 128-bit integers.

The remaining patches of this series move all of the already existing
DFP instructions to decodetree, and end up removing dfp-ops.c.inc, which
is no longer needed.

NOTE 1: The previous, non-decodetree code, was updating ctx->nip for all the
DFP instructions. I've removed that, but it would be great if someone could
confirm that updating nip really wasn't necessary.

NOTE 2: Some arithmetic function support for 128-bit integers was added,
for now, still using 64-bit pairs. In the near future, I think we should
modify all of them to use Int128 (and introduce UInt128). But I'll send
out an RFC to discuss how to do that in another patch series.

NOTE 3: The helper names are in uppercase, to match the instruction
names and to simplify the macros that define trans* functions.
Previously, this wasn't the case, as we were using lowercase instruction
names in the pre-decodetree code. Another standalone patch will be sent
later on, changing to uppercase the other new (decodetree) helpers whose
names are directly related to instruction names, eventually making PPC
helper names consistent.

The only patch still needing review is:
[PATCH v4 12/19] target/ppc: Do not update nip on DFP instructions

Changes in v4:
- Rebased against dgibson/ppc-for-6.2
- Skipped patches that were already applied (v3 1-4)
- Changed divu128/divs128 to return the remainder (rth)
- Moved changes that drop nip updates to a separate patch (rth)

Changes in v3:
- Split the uabs64 patch in 2
- Included patch to fix missing zero-extension in divs128
- Folded divisor == 0 into the dhi == 0 case in divu128
- Moved udiv_qrnnd from softfloat-macros.h to host-utils.h
- Used udiv_qrnnd in divu128
- Replaced int with bool in divs128
- Added unit test to check the divisor normalization in divu128
- Removed 'inline' from times_* functions in ppc/translate.c
- Used uadd64_overflow in mulu128
- Removed unnecessary 'else' from decNumberIntegralToInt128

Changes in v2:
- Renamed abs64() to uabs64()

Bruno Larsen (1):
  target/ppc: Move REQUIRE_ALTIVEC/VECTOR to translate.c

Fernando Valle (1):
  target/ppc: Introduce REQUIRE_FPU

Luis Pires (17):
  host-utils: move checks out of divu128/divs128
  host-utils: move udiv_qrnnd() to host-utils
  host-utils: add 128-bit quotient support to divu128/divs128
  host-utils: add unit tests for divu128/divs128
  libdecnumber: introduce decNumberFrom[U]Int128
  target/ppc: Implement DCFFIXQQ
  host-utils: Introduce mulu128
  libdecnumber: Introduce decNumberIntegralToInt128
  target/ppc: Implement DCTFIXQQ
  target/ppc: Do not update nip on DFP instructions
  target/ppc: Move dtstdc[q]/dtstdg[q] to decodetree
  target/ppc: Move d{add,sub,mul,div,iex}[q] to decodetree
  target/ppc: Move dcmp{u,o}[q],dts{tex,tsf,tsfi}[q] to decodetree
  target/ppc: Move dquai[q], drint{x,n}[q] to decodetree
  target/ppc: Move dqua[q], drrnd[q] to decodetree
  target/ppc: Move dct{dp,qpq},dr{sp,dpq},dc{f,t}fix[q],dxex[q] to
decodetree
  target/ppc: Move ddedpd[q],denbcd[q],dscli[q],dscri[q] to decodetree

 include/fpu/softfloat-macros.h |  82 -
 include/hw/clock.h |   5 +-
 include/libdecnumber/decNumber.h   |   4 +
 include/libdecnumber/decNumberLocal.h  |   2 +-
 include/qemu/host-utils.h  | 157 +++--
 libdecnumber/decContext.c  |   7 +-
 libdecnumber/decNumber.c   | 131 
 target/ppc/dfp_helper.c| 168 +++---
 target/ppc/helper.h| 106 ---
 target/ppc/insn32.decode   | 171 ++
 target/ppc/int_helper.c|  23 +-
 target/ppc/translate.c |  23 +-
 target/ppc/translate/dfp-impl.c.inc| 419 -
 target/ppc/translate/dfp-ops.c.inc | 165 --
 target/ppc/translate/vector-impl.c.inc |  10 +-
 tests/unit/meson.build |   1 +
 tests/unit/test-div128.c   | 197 
 util/host-utils.c  | 137 +---
 18 files changed, 1148 insertions(+), 660 deletions(-)
 delete mode 100644 target/ppc/translate/dfp-ops.c.inc
 create mode 100644 tests/unit/test-div128.c

-- 
2.25.1




Re: [PATCH v4 05/17] target/riscv: array for the 64 upper bits of 128-bit registers

2021-10-25 Thread Richard Henderson

On 10/25/21 5:28 AM, Frédéric Pétrot wrote:

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
---
  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(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH] hvf: Avoid mapping regions < PAGE_SIZE as ram

2021-10-25 Thread Alexander Graf



On 25.10.21 19:11, Paolo Bonzini wrote:

On 25/10/21 10:25, Alexander Graf wrote:
HVF has generic memory listener code that adds all RAM regions as HVF 
RAM
regions. However, HVF can only handle page aligned, page granule 
regions.


So let's ignore regions that are not page aligned and sized. They 
will be

trapped as MMIO instead.

Signed-off-by: Alexander Graf 
---
  accel/hvf/hvf-accel-ops.c | 6 ++
  1 file changed, 6 insertions(+)

diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
index 6bf319d34c..090155853a 100644
--- a/accel/hvf/hvf-accel-ops.c
+++ b/accel/hvf/hvf-accel-ops.c
@@ -135,6 +135,12 @@ static void hvf_set_phys_mem(MemoryRegionSection 
*section, bool add)

  }
  }
  +    if (int128_get64(section->size) & (qemu_real_host_page_size - 
1) ||
+    section->offset_within_address_space & 
(qemu_real_host_page_size - 1)) {

+    /* Not page aligned, so we can not map as RAM */
+    add = false;
+    }
+
  mem = hvf_find_overlap_slot(
  section->offset_within_address_space,
  int128_get64(section->size));



Queued, thanks.



You probably want v2 instead :)

Alex





Re: [PATCH 3/9] qapi: Eliminate QCO_NO_OPTIONS for a slight simplification

2021-10-25 Thread John Snow
On Mon, Oct 25, 2021 at 1:25 AM Markus Armbruster  wrote:

> Signed-off-by: Markus Armbruster 
> ---
>  include/qapi/qmp/dispatch.h | 1 -
>  monitor/misc.c  | 3 +--
>  scripts/qapi/commands.py| 5 +
>  3 files changed, 2 insertions(+), 7 deletions(-)
>
> diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h
> index 075203dc67..0ce88200b9 100644
> --- a/include/qapi/qmp/dispatch.h
> +++ b/include/qapi/qmp/dispatch.h
> @@ -21,7 +21,6 @@ typedef void (QmpCommandFunc)(QDict *, QObject **, Error
> **);
>
>  typedef enum QmpCommandOptions
>  {
> -QCO_NO_OPTIONS=  0x0,
>  QCO_NO_SUCCESS_RESP   =  (1U << 0),
>  QCO_ALLOW_OOB =  (1U << 1),
>  QCO_ALLOW_PRECONFIG   =  (1U << 2),
> diff --git a/monitor/misc.c b/monitor/misc.c
> index ffe7966870..3556b177f6 100644
> --- a/monitor/misc.c
> +++ b/monitor/misc.c
> @@ -230,8 +230,7 @@ static void monitor_init_qmp_commands(void)
>
>  qmp_init_marshal(_commands);
>
> -qmp_register_command(_commands, "device_add", qmp_device_add,
> - QCO_NO_OPTIONS);
> +qmp_register_command(_commands, "device_add", qmp_device_add, 0);
>
>  QTAILQ_INIT(_cap_negotiation_commands);
>  qmp_register_command(_cap_negotiation_commands,
> "qmp_capabilities",
> diff --git a/scripts/qapi/commands.py b/scripts/qapi/commands.py
> index 3654825968..c8a975528f 100644
> --- a/scripts/qapi/commands.py
> +++ b/scripts/qapi/commands.py
> @@ -229,15 +229,12 @@ def gen_register_command(name: str,
>  if coroutine:
>  options += ['QCO_COROUTINE']
>
> -if not options:
> -options = ['QCO_NO_OPTIONS']
> -
>  ret = mcgen('''
>  qmp_register_command(cmds, "%(name)s",
>   qmp_marshal_%(c_name)s, %(opts)s);
>  ''',
>  name=name, c_name=c_name(name),
> -opts=" | ".join(options))
> +opts=' | '.join(options) or 0)
>  return ret
>
>
>
I'm not a big fan of naked constants on the C side, but the generator
simplification is nice. I suppose it's worth the trade-off if you like it
better this way.

"eh".

Reviewed-by: John Snow 


Re: [PATCH v4 04/17] target/riscv: separation of bitwise logic and aritmetic helpers

2021-10-25 Thread Richard Henderson

On 10/25/21 5:28 AM, Frédéric Pétrot wrote:

Introduction of a gen_logic function for bitwise logic to implement
instructions in which not 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 
---
  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 e10c8769b3..5c7971b189 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -376,6 +376,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, DisasExtend ext,
+  void (*func)(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);
+
+gen_set_gpr(ctx, a->rd, dest);
+
+return true;
+}


I had asked for you to remove the DisasExtend argument, and you only did one of the two 
functions.


r~



Re: [PATCH 2/9] qapi: Mark unstable QMP parts with feature 'unstable'

2021-10-25 Thread John Snow
On Mon, Oct 25, 2021 at 1:25 AM Markus Armbruster  wrote:

> Add special feature 'unstable' everywhere the name starts with 'x-',
> except for InputBarrierProperties member x-origin and
> MemoryBackendProperties member x-use-canonical-path-for-ramblock-id,
> because these two are actually stable.
>
> Signed-off-by: Markus Armbruster 
> ---
>  qapi/block-core.json | 123 +++
>  qapi/migration.json  |  35 +---
>  qapi/misc.json   |   6 ++-
>  qapi/qom.json|  11 ++--
>  4 files changed, 130 insertions(+), 45 deletions(-)
>
> diff --git a/qapi/block-core.json b/qapi/block-core.json
> index 6d3217abb6..ce2c1352cb 100644
> --- a/qapi/block-core.json
> +++ b/qapi/block-core.json
> @@ -1438,6 +1438,9 @@
>  #
>  # @x-perf: Performance options. (Since 6.0)
>  #
> +# Features:
> +# @unstable: Member @x-perf is experimental.
> +#
>

It'd be a lot cooler if we could annotate the unstable member directly
instead of confusing it with the syntax that might describe the entire
struct/union/command/etc, but ... eh, it's just a doc field, so I'm not
gonna press on this. I don't have the energy to get into a doc formatting
standard discussion right now, so: sure, why not?


>  # Note: @on-source-error and @on-target-error only affect background
>  #   I/O.  If an error occurs during a guest write request, the
> device's
>  #   rerror/werror actions will be used.
> @@ -1452,7 +1455,9 @@
>  '*on-source-error': 'BlockdevOnError',
>  '*on-target-error': 'BlockdevOnError',
>  '*auto-finalize': 'bool', '*auto-dismiss': 'bool',
> -'*filter-node-name': 'str', '*x-perf': 'BackupPerf'  } }
> +'*filter-node-name': 'str',
> +'*x-perf': { 'type': 'BackupPerf',
> + 'features': [ 'unstable' ] } } }
>
>  ##
>  # @DriveBackup:
> @@ -1916,9 +1921,13 @@
>  #
>  # Get the block graph.
>  #
> +# Features:
> +# @unstable: This command is meant for debugging.
> +#
>  # Since: 4.0
>  ##
> -{ 'command': 'x-debug-query-block-graph', 'returns': 'XDbgBlockGraph' }
> +{ 'command': 'x-debug-query-block-graph', 'returns': 'XDbgBlockGraph',
> +  'features': [ 'unstable' ] }
>
>  ##
>  # @drive-mirror:
> @@ -2257,6 +2266,9 @@
>  #
>  # Get bitmap SHA256.
>  #
> +# Features:
> +# @unstable: This command is meant for debugging.
> +#
>  # Returns: - BlockDirtyBitmapSha256 on success
>  #  - If @node is not a valid block device, DeviceNotFound
>  #  - If @name is not found or if hashing has failed, GenericError
> with an
> @@ -2265,7 +2277,8 @@
>  # Since: 2.10
>  ##
>  { 'command': 'x-debug-block-dirty-bitmap-sha256',
> -  'data': 'BlockDirtyBitmap', 'returns': 'BlockDirtyBitmapSha256' }
> +  'data': 'BlockDirtyBitmap', 'returns': 'BlockDirtyBitmapSha256',
> +  'features': [ 'unstable' ] }
>
>  ##
>  # @blockdev-mirror:
> @@ -2495,27 +2508,57 @@
>  #
>  # Properties for throttle-group objects.
>  #
> -# The options starting with x- are aliases for the same key without x- in
> -# the @limits object. As indicated by the x- prefix, this is not a stable
> -# interface and may be removed or changed incompatibly in the future. Use
> -# @limits for a supported stable interface.
> -#
>  # @limits: limits to apply for this throttle group
>  #
> +# Features:
> +# @unstable: All members starting with x- are aliases for the same key
> +#without x- in the @limits object.  This is not a stable
> +#interface and may be removed or changed incompatibly in
> +#the future.  Use @limits for a supported stable
> +#interface.
> +#
>  # Since: 2.11
>  ##
>  { 'struct': 'ThrottleGroupProperties',
>'data': { '*limits': 'ThrottleLimits',
> -'*x-iops-total' : 'int', '*x-iops-total-max' : 'int',
> -'*x-iops-total-max-length' : 'int', '*x-iops-read' : 'int',
> -'*x-iops-read-max' : 'int', '*x-iops-read-max-length' : 'int',
> -'*x-iops-write' : 'int', '*x-iops-write-max' : 'int',
> -'*x-iops-write-max-length' : 'int', '*x-bps-total' : 'int',
> -'*x-bps-total-max' : 'int', '*x-bps-total-max-length' : 'int',
> -'*x-bps-read' : 'int', '*x-bps-read-max' : 'int',
> -'*x-bps-read-max-length' : 'int', '*x-bps-write' : 'int',
> -'*x-bps-write-max' : 'int', '*x-bps-write-max-length' : 'int',
> -'*x-iops-size' : 'int' } }
> +'*x-iops-total': { 'type': 'int',
> +   'features': [ 'unstable' ] },
> +'*x-iops-total-max': { 'type': 'int',
> +   'features': [ 'unstable' ] },
> +'*x-iops-total-max-length': { 'type': 'int',
> +  'features': [ 'unstable' ] },
> +'*x-iops-read': { 'type': 'int',
> +  'features': [ 'unstable' ] },
> +'*x-iops-read-max': { 'type': 'int',
> + 

Re: [PATCH v3 0/3] plugins: add a drcov plugin

2021-10-25 Thread Alex Bennée


NDNF  writes:

> These patches adds the ability to generate files in drcov format.
> Primary goal this scripts is to have coverage
> logfiles thatwork in Lighthouse.

Queued with some fixes to plugins/next, thanks.

-- 
Alex Bennée



Re: [PATCH 1/9] qapi: New special feature flag "unstable"

2021-10-25 Thread John Snow
On Mon, Oct 25, 2021 at 1:26 AM Markus Armbruster  wrote:

> By convention, names starting with "x-" are experimental.  The parts
> of external interfaces so named may be withdrawn or changed
> incompatibly in future releases.
>
> Drawback: promoting something from experimental to stable involves a
> name change.  Client code needs to be updated.
>
> Moreover, the convention is not universally observed:
>
> * QOM type "input-barrier" has properties "x-origin", "y-origin".
>   Looks accidental, but it's ABI since 4.2.
>
> * QOM types "memory-backend-file", "memory-backend-memfd",
>   "memory-backend-ram", and "memory-backend-epc" have a property
>   "x-use-canonical-path-for-ramblock-id" that is documented to be
>   stable despite its name.
>
> We could document these exceptions, but documentation helps only
> humans.  We want to recognize "unstable" in code, like "deprecated".
>
> Replace the convention by a new special feature flag "unstable".  It
> will be recognized by the QAPI generator, like the existing feature
> flag "deprecated", and unlike regular feature flags.
>
> This commit updates documentation and prepares tests.  The next commit
> updates the QAPI schema.  The remaining patches update the QAPI
> generator and wire up -compat policy checking.
>
> Signed-off-by: Markus Armbruster 
> ---
>  docs/devel/qapi-code-gen.rst| 9 ++---
>  tests/qapi-schema/qapi-schema-test.json | 7 +--
>  tests/qapi-schema/qapi-schema-test.out  | 5 +
>  3 files changed, 16 insertions(+), 5 deletions(-)
>
> diff --git a/docs/devel/qapi-code-gen.rst b/docs/devel/qapi-code-gen.rst
> index 4071c9074a..38f2d7aad3 100644
> --- a/docs/devel/qapi-code-gen.rst
> +++ b/docs/devel/qapi-code-gen.rst
> @@ -713,6 +713,10 @@ member as deprecated.  It is not supported elsewhere
> so far.
>  Interfaces so marked may be withdrawn in future releases in accordance
>  with QEMU's deprecation policy.
>
> +Feature "unstable" marks a command, event, enum value, or struct
> +member as unstable.  It is not supported elsewhere so far.  Interfaces
> +so marked may be withdrawn or changed incompatibly in future releases.
> +
>
>  Naming rules and reserved names
>  ---
> @@ -746,9 +750,8 @@ Member name ``u`` and names starting with ``has-`` or
> ``has_`` are reserved
>  for the generator, which uses them for unions and for tracking
>  optional members.
>
> -Any name (command, event, type, member, or enum value) beginning with
> -``x-`` is marked experimental, and may be withdrawn or changed
> -incompatibly in a future release.
> +Names beginning with ``x-`` used to signify "experimental".  This
> +convention has been replaced by special feature "unstable".
>
>  Pragmas ``command-name-exceptions`` and ``member-name-exceptions`` let
>  you violate naming rules.  Use for new code is strongly discouraged. See
> diff --git a/tests/qapi-schema/qapi-schema-test.json
> b/tests/qapi-schema/qapi-schema-test.json
> index b677ab861d..43b8697002 100644
> --- a/tests/qapi-schema/qapi-schema-test.json
> +++ b/tests/qapi-schema/qapi-schema-test.json
> @@ -273,7 +273,7 @@
>'data': { 'foo': { 'type': 'int', 'features': [ 'deprecated' ] } },
>'features': [ 'feature1' ] }
>  { 'struct': 'FeatureStruct2',
> -  'data': { 'foo': 'int' },
> +  'data': { 'foo': { 'type': 'int', 'features': [ 'unstable' ] } },
>'features': [ { 'name': 'feature1' } ] }
>  { 'struct': 'FeatureStruct3',
>'data': { 'foo': 'int' },
> @@ -331,7 +331,7 @@
>  { 'command': 'test-command-features1',
>'features': [ 'deprecated' ] }
>  { 'command': 'test-command-features3',
> -  'features': [ 'feature1', 'feature2' ] }
> +  'features': [ 'unstable', 'feature1', 'feature2' ] }
>
>  { 'command': 'test-command-cond-features1',
>'features': [ { 'name': 'feature1', 'if': 'TEST_IF_FEATURE_1'} ] }
> @@ -348,3 +348,6 @@
>
>  { 'event': 'TEST_EVENT_FEATURES1',
>'features': [ 'deprecated' ] }
> +
> +{ 'event': 'TEST_EVENT_FEATURES2',
> +  'features': [ 'unstable' ] }
> diff --git a/tests/qapi-schema/qapi-schema-test.out
> b/tests/qapi-schema/qapi-schema-test.out
> index 16846dbeb8..1f9585fa9b 100644
> --- a/tests/qapi-schema/qapi-schema-test.out
> +++ b/tests/qapi-schema/qapi-schema-test.out
> @@ -308,6 +308,7 @@ object FeatureStruct1
>  feature feature1
>  object FeatureStruct2
>  member foo: int optional=False
> +feature unstable
>  feature feature1
>  object FeatureStruct3
>  member foo: int optional=False
> @@ -373,6 +374,7 @@ command test-command-features1 None -> None
>  feature deprecated
>  command test-command-features3 None -> None
>  gen=True success_response=True boxed=False oob=False preconfig=False
> +feature unstable
>  feature feature1
>  feature feature2
>  command test-command-cond-features1 None -> None
> @@ -394,6 +396,9 @@ event TEST_EVENT_FEATURES0 FeatureStruct1
>  event TEST_EVENT_FEATURES1 None
>  boxed=False
>  feature deprecated
> +event 

RE: [PATCH v3 07/22] host-utils: add 128-bit quotient support to divu128/divs128

2021-10-25 Thread Luis Fernando Fujita Pires
From: Richard Henderson 
> > A new argument, prem, was added to divu128/divs128 to receive the
> > remainder, freeing up phigh to receive the high 64 bits of the
> > quotient.
> >
> > Signed-off-by: Luis Pires 
> 
> Why not return the remainder?  That would avoid the need for an extra
> argument, and the need for a conditional vs prem inside the division 
> functions.

No good reason, in fact. :)
I've changed that for the next version of the patch series. Thanks!

--
Luis Pires
Instituto de Pesquisas ELDORADO
Aviso Legal - Disclaimer 


RE: [PATCH v3 16/22] target/ppc: Move dtstdc[q]/dtstdg[q] to decodetree

2021-10-25 Thread Luis Fernando Fujita Pires
From: Richard Henderson 
> On 9/10/21 4:26 AM, Luis Pires wrote:
> > +_bf_fra bf fra dm
> > +@Z22_bf_fra .. bf:3 .. fra:5 dm:6 . .   _bf_fra
> > +
> > +%z22_frap   17:4 !function=times_2
> > +@Z22_bf_frap.. bf:3 .. 0 dm:6 . .   _bf_fra
> fra=%z22_frap
> 
> How confusing.  There's a typo in the manual for these insns, with the minor
> opcode (XO) field at the wrong location.  It's correct in the summary of
> instruction formats at the beginning of the manual.

Right! This was also the case for dscli[q]/dscri[q]. I've reported this, and it 
should be fixed in the next release of the ISA.

> Functional change: you're no longer storing nip.  It does seem wrong, but that
> fix should be broken out to a separate patch.

Thanks, I've moved the nip update changes to a separate patch in the new series.

--
Luis Pires
Instituto de Pesquisas ELDORADO
Aviso Legal - Disclaimer 


RE: [PATCH v3 15/22] target/ppc: Implement DCTFIXQQ

2021-10-25 Thread Luis Fernando Fujita Pires
From: Richard Henderson 

> > +static void set_dfp128_to_avr(ppc_avr_t *dst, ppc_vsr_t *src) {
> > +dst->VsrD(0) = src->VsrD(0);
> > +dst->VsrD(1) = src->VsrD(1);
> > +}
> 
> Given that these two are typedef of one another, I would think this is
> unnecessary and you should just write *dst = *src.

Done!

--
Luis Pires
Instituto de Pesquisas ELDORADO
Aviso Legal - Disclaimer 


Re: [PATCH] virtiofsd: Error on bad socket group name

2021-10-25 Thread Dr. David Alan Gilbert
* Dr. David Alan Gilbert (git) (dgilb...@redhat.com) wrote:
> From: "Dr. David Alan Gilbert" 
> 
> Make the '--socket-group=' option fail if the group name is unknown:
> 
> ./tools/virtiofsd/virtiofsd  --socket-group=zaphod
> vhost socket: unable to find group 'zaphod'
> 
> Reported-by: Xiaoling Gao 
> Signed-off-by: Dr. David Alan Gilbert 

Queued

> ---
>  tools/virtiofsd/fuse_virtio.c | 7 +++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/tools/virtiofsd/fuse_virtio.c b/tools/virtiofsd/fuse_virtio.c
> index 8f4fd165b9..39eebffb62 100644
> --- a/tools/virtiofsd/fuse_virtio.c
> +++ b/tools/virtiofsd/fuse_virtio.c
> @@ -999,6 +999,13 @@ static int fv_create_listen_socket(struct fuse_session 
> *se)
>   "vhost socket failed to set group to %s (%d): %m\n",
>   se->vu_socket_group, g->gr_gid);
>  }
> +} else {
> +fuse_log(FUSE_LOG_ERR,
> + "vhost socket: unable to find group '%s'\n",
> + se->vu_socket_group);
> +close(listen_sock);
> +umask(old_umask);
> +return -1;
>  }
>  }
>  umask(old_umask);
> -- 
> 2.31.1
> 
> 
-- 
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK




Re: [PATCH v17 3/8] target/riscv: Support CSRs required for RISC-V PM extension except for the h-mode

2021-10-25 Thread Richard Henderson

On 10/25/21 10:36 AM, Alexey Baturo wrote:

+/* User Pointer Masking */
+[CSR_UMTE]={ "umte",pointer_masking, read_umte,write_umte  
  },
+[CSR_UPMMASK] ={ "upmmask", pointer_masking, read_upmmask, 
write_upmmask },
+[CSR_UPMBASE] ={ "upmbase", pointer_masking, read_upmbase, 
write_upmbase },
+/* Machine Pointer Masking */
+[CSR_MMTE]={ "mmte",pointer_masking, read_mmte,write_mmte  
  },
+[CSR_MPMMASK] ={ "mpmmask", pointer_masking, read_mpmmask, 
write_mpmmask },
+[CSR_MPMBASE] ={ "mpmbase", pointer_masking, read_mpmbase, 
write_mpmbase },
+/* Supervisor Pointer Masking */
+[CSR_SMTE]={ "smte",pointer_masking, read_smte,write_smte  
  },
+[CSR_SPMMASK] ={ "spmmask", pointer_masking, read_spmmask, 
write_spmmask },
+[CSR_SPMBASE] ={ "spmbase", pointer_masking, read_spmbase, 
write_spmbase },


Surely the S-mode and U-mode csrs surely also depend on RVS and RVU 
respectively?


r~



Re: [Virtio-fs] [PATCH] virtiofsd: Error on bad socket group name

2021-10-25 Thread Dr. David Alan Gilbert
* Vivek Goyal (vgo...@redhat.com) wrote:
> On Thu, Oct 14, 2021 at 01:25:54PM +0100, Dr. David Alan Gilbert (git) wrote:
> > From: "Dr. David Alan Gilbert" 
> > 
> > Make the '--socket-group=' option fail if the group name is unknown:
> > 
> > ./tools/virtiofsd/virtiofsd  --socket-group=zaphod
> > vhost socket: unable to find group 'zaphod'
> > 
> > Reported-by: Xiaoling Gao 
> > Signed-off-by: Dr. David Alan Gilbert 
> 
> Hi Dave,
> 
> This looks good to me. Just a minor nit for code cleanup. It could
> be done in a separate patch or sometime later as well.
> 
> Reviewed-by: Vivek Goyal 

Thanks

> > ---
> >  tools/virtiofsd/fuse_virtio.c | 7 +++
> >  1 file changed, 7 insertions(+)
> > 
> > diff --git a/tools/virtiofsd/fuse_virtio.c b/tools/virtiofsd/fuse_virtio.c
> > index 8f4fd165b9..39eebffb62 100644
> > --- a/tools/virtiofsd/fuse_virtio.c
> > +++ b/tools/virtiofsd/fuse_virtio.c
> > @@ -999,6 +999,13 @@ static int fv_create_listen_socket(struct fuse_session 
> > *se)
> >   "vhost socket failed to set group to %s (%d): 
> > %m\n",
> >   se->vu_socket_group, g->gr_gid);
> >  }
> > +} else {
> > +fuse_log(FUSE_LOG_ERR,
> > + "vhost socket: unable to find group '%s'\n",
> > + se->vu_socket_group);
> > +close(listen_sock);
> > +umask(old_umask);
>   ^^^
> > +return -1;
> >  }
> >  }
> >  umask(old_umask);
> 
> This umask() call could be moved little early right after bind() call and
> that way we don't have to take care of calling umask(old_umask) in error
> path if group name could not be found.

One to fight another day.

> Vivek
> > -- 
> > 2.31.1
> > 
> > ___
> > Virtio-fs mailing list
> > virtio...@redhat.com
> > https://listman.redhat.com/mailman/listinfo/virtio-fs
> > 
> 
> 
-- 
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK




Re: [PATCH v3 34/48] tcg/optimize: Split out fold_to_not

2021-10-25 Thread Richard Henderson

On 10/25/21 11:13 AM, Luis Fernando Fujita Pires wrote:

From: Richard Henderson 


   static bool fold_eqv(OptContext *ctx, TCGOp *op)  {
-return fold_const2(ctx, op);
+if (fold_const2(ctx, op) ||
+fold_xi_to_not(ctx, op, 0)) {


Should be fold_ix_to_not (not fold xi_to_not).


No, because for eqv we expect the second operand to be the constant -- eqv is
commutative.


Ah, got it! The previous code was wrong, and I failed to notice that eqv 
would've had its arguments swapped to have the constant as second.


Ah!  I failed to notice that the previous code was wrong.  ;-)


r~



RE: [PATCH v3 34/48] tcg/optimize: Split out fold_to_not

2021-10-25 Thread Luis Fernando Fujita Pires
From: Richard Henderson 

> >>   static bool fold_eqv(OptContext *ctx, TCGOp *op)  {
> >> -return fold_const2(ctx, op);
> >> +if (fold_const2(ctx, op) ||
> >> +fold_xi_to_not(ctx, op, 0)) {
> >
> > Should be fold_ix_to_not (not fold xi_to_not).
> 
> No, because for eqv we expect the second operand to be the constant -- eqv is
> commutative.

Ah, got it! The previous code was wrong, and I failed to notice that eqv 
would've had its arguments swapped to have the constant as second.

--
Luis Pires
Instituto de Pesquisas ELDORADO
Aviso Legal - Disclaimer 


Re: [PATCH 00/13] virtiofsd: Support notification queue and

2021-10-25 Thread Dr. David Alan Gilbert
* Vivek Goyal (vgo...@redhat.com) wrote:
> Hi,
> 
> Here are the patches to support notification queue and blocking
> posix locks. One of the biggest change since las time has been
> creation of custom thread pool for handling locking requests. 
> Thanks to Ioannis for doing most of the work on custom thread
> pool.
> 
> I have posted corresponding kernel changes here.
> 
> https://lore.kernel.org/linux-fsdevel/20210930143850.1188628-1-vgo...@redhat.com/T/#mb2d0fbfdb580ef33b6e812d0acbd16333b11f2cf

I'm queuing:
[PATCH 03/13] virtiofsd: Remove unused virtio_fs_config definition
[PATCH 04/13] virtiofsd: Add a helper to send element on virtqueue
[PATCH 05/13] virtiofsd: Add a helper to stop all queues

from this series; they're separate cleanups.

Dave

> Any feedback is welcome.
> 
> Thanks
> Vivek
> 
> Vivek Goyal (13):
>   virtio_fs.h: Add notification queue feature bit
>   virtiofsd: fuse.h header file changes for lock notification
>   virtiofsd: Remove unused virtio_fs_config definition
>   virtiofsd: Add a helper to send element on virtqueue
>   virtiofsd: Add a helper to stop all queues
>   vhost-user-fs: Use helpers to create/cleanup virtqueue
>   virtiofsd: Release file locks using F_UNLCK
>   virtiofsd: Create a notification queue
>   virtiofsd: Specify size of notification buffer using config space
>   virtiofsd: Custom threadpool for remote blocking posix locks requests
>   virtiofsd: Shutdown notification queue in the end
>   virtiofsd: Implement blocking posix locks
>   virtiofsd, seccomp: Add clock_nanosleep() to allow list
> 
>  hw/virtio/vhost-user-fs-pci.c  |   4 +-
>  hw/virtio/vhost-user-fs.c  | 158 --
>  include/hw/virtio/vhost-user-fs.h  |   4 +
>  include/standard-headers/linux/fuse.h  |  11 +-
>  include/standard-headers/linux/virtio_fs.h |   5 +
>  tools/virtiofsd/fuse_i.h   |   1 +
>  tools/virtiofsd/fuse_lowlevel.c|  37 ++-
>  tools/virtiofsd/fuse_lowlevel.h|  26 ++
>  tools/virtiofsd/fuse_virtio.c  | 339 +
>  tools/virtiofsd/meson.build|   1 +
>  tools/virtiofsd/passthrough_ll.c   |  91 +-
>  tools/virtiofsd/passthrough_seccomp.c  |   2 +
>  tools/virtiofsd/tpool.c| 331 
>  tools/virtiofsd/tpool.h|  18 ++
>  14 files changed, 915 insertions(+), 113 deletions(-)
>  create mode 100644 tools/virtiofsd/tpool.c
>  create mode 100644 tools/virtiofsd/tpool.h
> 
> -- 
> 2.31.1
> 
> 
-- 
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK




Re: [PATCH] virtiofsd: xattr mapping add a new type "unsupported"

2021-10-25 Thread Dr. David Alan Gilbert
* Vivek Goyal (vgo...@redhat.com) wrote:
> Right now for xattr remapping, we support types of "prefix", "ok" or "bad".
> Type "bad" returns -EPERM on setxattr and hides xattr in listxattr. For
> getxattr, mapping code returns -EPERM but getxattr code converts it to 
> -ENODATA.
> 
> I need a new semantics where if an xattr is unsupported, then
> getxattr()/setxattr() return -ENOTSUP and listxattr() should hide the xattr.
> This is needed to simulate that security.selinux is not supported by
> virtiofs filesystem and in that case client falls back to some default
> label specified by policy.
> 
> So add a new type "unsupported" which returns -ENOTSUP on getxattr() and
> setxattr() and hides xattrs in listxattr().
> 
> For example, one can use following mapping rule to not support
> security.selinux xattr and allow others.
> 
> "-o xattrmap=/unsupported/all/security.selinux/security.selinux//ok/all///"
> 
> Suggested-by: "Dr. David Alan Gilbert" 
> Signed-off-by: Vivek Goyal 

Queued

> ---
>  docs/tools/virtiofsd.rst |6 ++
>  tools/virtiofsd/passthrough_ll.c |   17 ++---
>  2 files changed, 20 insertions(+), 3 deletions(-)
> 
> Index: rhvgoyal-qemu/tools/virtiofsd/passthrough_ll.c
> ===
> --- rhvgoyal-qemu.orig/tools/virtiofsd/passthrough_ll.c   2021-09-22 
> 08:37:16.070377732 -0400
> +++ rhvgoyal-qemu/tools/virtiofsd/passthrough_ll.c2021-09-22 
> 14:17:09.543016250 -0400
> @@ -2465,6 +2465,11 @@ static void lo_flock(fuse_req_t req, fus
>   * Automatically reversed on read
>   */
>  #define XATTR_MAP_FLAG_PREFIX  (1 <<  2)
> +/*
> + * The attribute is unsupported;
> + * ENOTSUP on write, hidden on read.
> + */
> +#define XATTR_MAP_FLAG_UNSUPPORTED (1 <<  3)
>  
>  /* scopes */
>  /* Apply rule to get/set/remove */
> @@ -2636,6 +2641,8 @@ static void parse_xattrmap(struct lo_dat
>  tmp_entry.flags |= XATTR_MAP_FLAG_OK;
>  } else if (strstart(map, "bad", )) {
>  tmp_entry.flags |= XATTR_MAP_FLAG_BAD;
> +} else if (strstart(map, "unsupported", )) {
> +tmp_entry.flags |= XATTR_MAP_FLAG_UNSUPPORTED;
>  } else if (strstart(map, "map", )) {
>  /*
>   * map is sugar that adds a number of rules, and must be
> @@ -2646,8 +2653,8 @@ static void parse_xattrmap(struct lo_dat
>  } else {
>  fuse_log(FUSE_LOG_ERR,
>   "%s: Unexpected type;"
> - "Expecting 'prefix', 'ok', 'bad' or 'map' in rule 
> %zu\n",
> - __func__, lo->xattr_map_nentries);
> + "Expecting 'prefix', 'ok', 'bad', 'unsupported' or 
> 'map'"
> + " in rule %zu\n", __func__, lo->xattr_map_nentries);
>  exit(1);
>  }
>  
> @@ -2749,6 +2756,9 @@ static int xattr_map_client(const struct
>  if (cur_entry->flags & XATTR_MAP_FLAG_BAD) {
>  return -EPERM;
>  }
> +if (cur_entry->flags & XATTR_MAP_FLAG_UNSUPPORTED) {
> +return -ENOTSUP;
> +}
>  if (cur_entry->flags & XATTR_MAP_FLAG_OK) {
>  /* Unmodified name */
>  return 0;
> @@ -2788,7 +2798,8 @@ static int xattr_map_server(const struct
>  
>  if ((cur_entry->flags & XATTR_MAP_FLAG_SERVER) &&
>  (strstart(server_name, cur_entry->prepend, ))) {
> -if (cur_entry->flags & XATTR_MAP_FLAG_BAD) {
> +if (cur_entry->flags & XATTR_MAP_FLAG_BAD ||
> +cur_entry->flags & XATTR_MAP_FLAG_UNSUPPORTED) {
>  return -ENODATA;
>  }
>  if (cur_entry->flags & XATTR_MAP_FLAG_OK) {
> Index: rhvgoyal-qemu/docs/tools/virtiofsd.rst
> ===
> --- rhvgoyal-qemu.orig/docs/tools/virtiofsd.rst   2021-09-22 
> 08:37:15.938372097 -0400
> +++ rhvgoyal-qemu/docs/tools/virtiofsd.rst2021-09-22 14:44:09.814188712 
> -0400
> @@ -183,6 +183,12 @@ Using ':' as the separator a rule is of
>'ok' as either an explicit terminator or for special handling of certain
>patterns.
>  
> +- 'unsupported' - If a client tries to use a name matching 'key' it's
> +  denied using ENOTSUP; when the server passes an attribute
> +  name matching 'prepend' it's hidden.  In many ways it's use is very like
> +  'ok' as either an explicit terminator or for special handling of certain
> +  patterns.
> +
>  **key** is a string tested as a prefix on an attribute name originating
>  on the client.  It maybe empty in which case a 'client' rule
>  will always match on client names.
> 
> 
-- 
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK




[PATCH v17 7/8] target/riscv: Implement address masking functions required for RISC-V Pointer Masking extension

2021-10-25 Thread Alexey Baturo
From: Anatoly Parshintsev 

Signed-off-by: Anatoly Parshintsev 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.h|  2 ++
 target/riscv/cpu_helper.c | 18 ++
 target/riscv/translate.c  | 39 +--
 3 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index b2422e3f99..325908287d 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -410,6 +410,8 @@ FIELD(TB_FLAGS, HLSX, 10, 1)
 FIELD(TB_FLAGS, MSTATUS_HS_FS, 11, 2)
 /* The combination of MXL/SXL/UXL that applies to the current cpu mode. */
 FIELD(TB_FLAGS, XL, 13, 2)
+/* If PointerMasking should be applied */
+FIELD(TB_FLAGS, PM_ENABLED, 15, 1)
 
 #ifdef TARGET_RISCV32
 #define riscv_cpu_mxl(env)  ((void)(env), MXL_RV32)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 0d1132f39d..662228c238 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -107,6 +107,24 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
*pc,
 flags = FIELD_DP32(flags, TB_FLAGS, MSTATUS_HS_FS,
get_field(env->mstatus_hs, MSTATUS_FS));
 }
+if (riscv_has_ext(env, RVJ)) {
+int priv = flags & TB_FLAGS_PRIV_MMU_MASK;
+bool pm_enabled = false;
+switch (priv) {
+case PRV_U:
+pm_enabled = env->mmte & U_PM_ENABLE;
+break;
+case PRV_S:
+pm_enabled = env->mmte & S_PM_ENABLE;
+break;
+case PRV_M:
+pm_enabled = env->mmte & M_PM_ENABLE;
+break;
+default:
+g_assert_not_reached();
+}
+flags = FIELD_DP32(flags, TB_FLAGS, PM_ENABLED, pm_enabled);
+}
 #endif
 
 flags = FIELD_DP32(flags, TB_FLAGS, XL, cpu_get_xl(env));
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index a5e6fa145d..1d57bc97b5 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -36,6 +36,9 @@ static TCGv cpu_gpr[32], cpu_pc, cpu_vl;
 static TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */
 static TCGv load_res;
 static TCGv load_val;
+/* globals for PM CSRs */
+static TCGv pm_mask[4];
+static TCGv pm_base[4];
 
 #include "exec/gen-icount.h"
 
@@ -83,6 +86,10 @@ typedef struct DisasContext {
 TCGv zero;
 /* Space for 3 operands plus 1 extra for address computation. */
 TCGv temp[4];
+/* PointerMasking extension */
+bool pm_enabled;
+TCGv pm_mask;
+TCGv pm_base;
 } DisasContext;
 
 static inline bool has_ext(DisasContext *ctx, uint32_t ext)
@@ -272,11 +279,20 @@ static void gen_jal(DisasContext *ctx, int rd, 
target_ulong imm)
 }
 
 /*
- * Temp stub: generates address adjustment for PointerMasking
+ * Generates address adjustment for PointerMasking
  */
 static TCGv gen_pm_adjust_address(DisasContext *s, TCGv src)
 {
-return src;
+TCGv temp;
+if (!s->pm_enabled) {
+/* Load unmodified address */
+return src;
+} else {
+temp = temp_new(s);
+tcg_gen_andc_tl(temp, src, s->pm_mask);
+tcg_gen_or_tl(temp, temp, s->pm_base);
+return temp;
+}
 }
 
 #ifndef CONFIG_USER_ONLY
@@ -622,6 +638,10 @@ static void riscv_tr_init_disas_context(DisasContextBase 
*dcbase, CPUState *cs)
 ctx->cs = cs;
 ctx->ntemp = 0;
 memset(ctx->temp, 0, sizeof(ctx->temp));
+ctx->pm_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_ENABLED);
+int priv = tb_flags & TB_FLAGS_PRIV_MMU_MASK;
+ctx->pm_mask = pm_mask[priv];
+ctx->pm_base = pm_base[priv];
 
 ctx->zero = tcg_constant_tl(0);
 }
@@ -735,4 +755,19 @@ void riscv_translate_init(void)
  "load_res");
 load_val = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, load_val),
  "load_val");
+#ifndef CONFIG_USER_ONLY
+/* Assign PM CSRs to tcg globals */
+pm_mask[PRV_U] =
+  tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, upmmask), "upmmask");
+pm_base[PRV_U] =
+  tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, upmbase), "upmbase");
+pm_mask[PRV_S] =
+  tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, spmmask), "spmmask");
+pm_base[PRV_S] =
+  tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, spmbase), "spmbase");
+pm_mask[PRV_M] =
+  tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, mpmmask), "mpmmask");
+pm_base[PRV_M] =
+  tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, mpmbase), "mpmbase");
+#endif
 }
-- 
2.30.2




[PATCH v17 3/8] target/riscv: Support CSRs required for RISC-V PM extension except for the h-mode

2021-10-25 Thread Alexey Baturo
Signed-off-by: Alexey Baturo 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.c |   2 +
 target/riscv/cpu.h |  11 ++
 target/riscv/csr.c | 285 +
 3 files changed, 298 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 788fa0b11c..6b767a4a0b 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -367,6 +367,8 @@ static void riscv_cpu_reset(DeviceState *dev)
 env->mcause = 0;
 env->pc = env->resetvec;
 env->two_stage_lookup = false;
+/* mmte is supposed to have pm.current hardwired to 1 */
+env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT);
 #endif
 cs->exception_index = RISCV_EXCP_NONE;
 env->load_res = -1;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 1cfc6a53a0..b2422e3f99 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -238,6 +238,17 @@ struct CPURISCVState {
 
 /* True if in debugger mode.  */
 bool debugger;
+
+/*
+ * CSRs for PointerMasking extension
+ */
+target_ulong mmte;
+target_ulong mpmmask;
+target_ulong mpmbase;
+target_ulong spmmask;
+target_ulong spmbase;
+target_ulong upmmask;
+target_ulong upmbase;
 #endif
 
 float_status fp_status;
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 69e4d65fcd..9f41954894 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -192,6 +192,16 @@ static RISCVException hmode32(CPURISCVState *env, int 
csrno)
 
 }
 
+/* Checks if PointerMasking registers could be accessed */
+static RISCVException pointer_masking(CPURISCVState *env, int csrno)
+{
+/* Check if j-ext is present */
+if (riscv_has_ext(env, RVJ)) {
+return RISCV_EXCP_NONE;
+}
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
 static RISCVException pmp(CPURISCVState *env, int csrno)
 {
 if (riscv_feature(env, RISCV_FEATURE_PMP)) {
@@ -1425,6 +1435,268 @@ static RISCVException write_pmpaddr(CPURISCVState *env, 
int csrno,
 return RISCV_EXCP_NONE;
 }
 
+/*
+ * Functions to access Pointer Masking feature registers
+ * We have to check if current priv lvl could modify
+ * csr in given mode
+ */
+static bool check_pm_current_disabled(CPURISCVState *env, int csrno)
+{
+int csr_priv = get_field(csrno, 0x300);
+int pm_current;
+
+/*
+ * If priv lvls differ that means we're accessing csr from higher priv lvl,
+ * so allow the access
+ */
+if (env->priv != csr_priv) {
+return false;
+}
+switch (env->priv) {
+case PRV_M:
+pm_current = get_field(env->mmte, M_PM_CURRENT);
+break;
+case PRV_S:
+pm_current = get_field(env->mmte, S_PM_CURRENT);
+break;
+case PRV_U:
+pm_current = get_field(env->mmte, U_PM_CURRENT);
+break;
+default:
+g_assert_not_reached();
+}
+/* It's same priv lvl, so we allow to modify csr only if pm.current==1 */
+return !pm_current;
+}
+
+static RISCVException read_mmte(CPURISCVState *env, int csrno,
+target_ulong *val)
+{
+*val = env->mmte & MMTE_MASK;
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_mmte(CPURISCVState *env, int csrno,
+ target_ulong val)
+{
+uint64_t mstatus;
+target_ulong wpri_val = val & MMTE_MASK;
+
+if (val != wpri_val) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s" TARGET_FMT_lx 
"\n",
+  "MMTE: WPRI violation written 0x", val,
+  "vs expected 0x", wpri_val);
+}
+/* for machine mode pm.current is hardwired to 1 */
+wpri_val |= MMTE_M_PM_CURRENT;
+
+/* hardwiring pm.instruction bit to 0, since it's not supported yet */
+wpri_val &= ~(MMTE_M_PM_INSN | MMTE_S_PM_INSN | MMTE_U_PM_INSN);
+env->mmte = wpri_val | PM_EXT_DIRTY;
+
+/* Set XS and SD bits, since PM CSRs are dirty */
+mstatus = env->mstatus | MSTATUS_XS;
+write_mstatus(env, csrno, mstatus);
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException read_smte(CPURISCVState *env, int csrno,
+target_ulong *val)
+{
+*val = env->mmte & SMTE_MASK;
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_smte(CPURISCVState *env, int csrno,
+ target_ulong val)
+{
+target_ulong wpri_val = val & SMTE_MASK;
+
+if (val != wpri_val) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s" TARGET_FMT_lx 
"\n",
+  "SMTE: WPRI violation written 0x", val,
+  "vs expected 0x", wpri_val);
+}
+
+/* if pm.current==0 we can't modify current PM CSRs */
+if (check_pm_current_disabled(env, csrno)) {
+return RISCV_EXCP_NONE;
+}
+
+wpri_val |= (env->mmte & ~SMTE_MASK);
+write_mmte(env, csrno, wpri_val);
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException read_umte(CPURISCVState *env, int csrno,
+target_ulong *val)
+{
+

[PATCH v17 8/8] target/riscv: Allow experimental J-ext to be turned on

2021-10-25 Thread Alexey Baturo
Signed-off-by: Alexey Baturo 
Reviewed-by: Alistair Francis 
Reviewed-by: Bin Meng 
Reviewed-by: Richard Henderson 
---
 target/riscv/cpu.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 16fac64806..7d53125dbc 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -562,6 +562,9 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 }
 set_vext_version(env, vext_version);
 }
+if (cpu->cfg.ext_j) {
+ext |= RVJ;
+}
 
 set_misa(env, env->misa_mxl, ext);
 }
@@ -637,6 +640,7 @@ static Property riscv_cpu_properties[] = {
 DEFINE_PROP_BOOL("x-zbc", RISCVCPU, cfg.ext_zbc, false),
 DEFINE_PROP_BOOL("x-zbs", RISCVCPU, cfg.ext_zbs, false),
 DEFINE_PROP_BOOL("x-h", RISCVCPU, cfg.ext_h, false),
+DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false),
 DEFINE_PROP_BOOL("x-v", RISCVCPU, cfg.ext_v, false),
 DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
 DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128),
-- 
2.30.2




Re: [PATCH v3 36/48] tcg/optimize: Split out fold_xi_to_x

2021-10-25 Thread Richard Henderson

On 10/25/21 7:26 AM, Luis Fernando Fujita Pires wrote:

You missed adding 'fold_xi_to_x(ctx, op, -1)' to fold_orc() in this commit.
It ended up being added in patch 42, but it should be here.


Oops, yes.


And should we use fold_xi_to_x() to optimize multiply and divide when i==1, too?


A good idea; I'll put that in a new patch.


r~



[PATCH v17 2/8] target/riscv: Add CSR defines for RISC-V PM extension

2021-10-25 Thread Alexey Baturo
Signed-off-by: Alexey Baturo 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu_bits.h | 96 +
 1 file changed, 96 insertions(+)

diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index cffcd3a5df..aa0bce4e06 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -334,6 +334,38 @@
 #define CSR_MHPMCOUNTER30H  0xb9e
 #define CSR_MHPMCOUNTER31H  0xb9f
 
+/*
+ * User PointerMasking registers
+ * NB: actual CSR numbers might be changed in future
+ */
+#define CSR_UMTE0x4c0
+#define CSR_UPMMASK 0x4c1
+#define CSR_UPMBASE 0x4c2
+
+/*
+ * Machine PointerMasking registers
+ * NB: actual CSR numbers might be changed in future
+ */
+#define CSR_MMTE0x3c0
+#define CSR_MPMMASK 0x3c1
+#define CSR_MPMBASE 0x3c2
+
+/*
+ * Supervisor PointerMaster registers
+ * NB: actual CSR numbers might be changed in future
+ */
+#define CSR_SMTE0x1c0
+#define CSR_SPMMASK 0x1c1
+#define CSR_SPMBASE 0x1c2
+
+/*
+ * Hypervisor PointerMaster registers
+ * NB: actual CSR numbers might be changed in future
+ */
+#define CSR_VSMTE   0x2c0
+#define CSR_VSPMMASK0x2c1
+#define CSR_VSPMBASE0x2c2
+
 /* mstatus CSR bits */
 #define MSTATUS_UIE 0x0001
 #define MSTATUS_SIE 0x0002
@@ -525,4 +557,68 @@ typedef enum RISCVException {
 #define MIE_UTIE   (1 << IRQ_U_TIMER)
 #define MIE_SSIE   (1 << IRQ_S_SOFT)
 #define MIE_USIE   (1 << IRQ_U_SOFT)
+
+/* General PointerMasking CSR bits*/
+#define PM_ENABLE   0x0001ULL
+#define PM_CURRENT  0x0002ULL
+#define PM_INSN 0x0004ULL
+#define PM_XS_MASK  0x0003ULL
+
+/* PointerMasking XS bits values */
+#define PM_EXT_DISABLE  0xULL
+#define PM_EXT_INITIAL  0x0001ULL
+#define PM_EXT_CLEAN0x0002ULL
+#define PM_EXT_DIRTY0x0003ULL
+
+/* Offsets for every pair of control bits per each priv level */
+#define XS_OFFSET0ULL
+#define U_OFFSET 2ULL
+#define S_OFFSET 5ULL
+#define M_OFFSET 8ULL
+
+#define PM_XS_BITS   (PM_XS_MASK << XS_OFFSET)
+#define U_PM_ENABLE  (PM_ENABLE  << U_OFFSET)
+#define U_PM_CURRENT (PM_CURRENT << U_OFFSET)
+#define U_PM_INSN(PM_INSN<< U_OFFSET)
+#define S_PM_ENABLE  (PM_ENABLE  << S_OFFSET)
+#define S_PM_CURRENT (PM_CURRENT << S_OFFSET)
+#define S_PM_INSN(PM_INSN<< S_OFFSET)
+#define M_PM_ENABLE  (PM_ENABLE  << M_OFFSET)
+#define M_PM_CURRENT (PM_CURRENT << M_OFFSET)
+#define M_PM_INSN(PM_INSN<< M_OFFSET)
+
+/* mmte CSR bits */
+#define MMTE_PM_XS_BITS PM_XS_BITS
+#define MMTE_U_PM_ENABLEU_PM_ENABLE
+#define MMTE_U_PM_CURRENT   U_PM_CURRENT
+#define MMTE_U_PM_INSN  U_PM_INSN
+#define MMTE_S_PM_ENABLES_PM_ENABLE
+#define MMTE_S_PM_CURRENT   S_PM_CURRENT
+#define MMTE_S_PM_INSN  S_PM_INSN
+#define MMTE_M_PM_ENABLEM_PM_ENABLE
+#define MMTE_M_PM_CURRENT   M_PM_CURRENT
+#define MMTE_M_PM_INSN  M_PM_INSN
+#define MMTE_MASK(MMTE_U_PM_ENABLE | MMTE_U_PM_CURRENT | MMTE_U_PM_INSN | \
+  MMTE_S_PM_ENABLE | MMTE_S_PM_CURRENT | MMTE_S_PM_INSN | \
+  MMTE_M_PM_ENABLE | MMTE_M_PM_CURRENT | MMTE_M_PM_INSN | \
+  MMTE_PM_XS_BITS)
+
+/* (v)smte CSR bits */
+#define SMTE_PM_XS_BITS PM_XS_BITS
+#define SMTE_U_PM_ENABLEU_PM_ENABLE
+#define SMTE_U_PM_CURRENT   U_PM_CURRENT
+#define SMTE_U_PM_INSN  U_PM_INSN
+#define SMTE_S_PM_ENABLES_PM_ENABLE
+#define SMTE_S_PM_CURRENT   S_PM_CURRENT
+#define SMTE_S_PM_INSN  S_PM_INSN
+#define SMTE_MASK(SMTE_U_PM_ENABLE | SMTE_U_PM_CURRENT | SMTE_U_PM_INSN | \
+  SMTE_S_PM_ENABLE | SMTE_S_PM_CURRENT | SMTE_S_PM_INSN | \
+  SMTE_PM_XS_BITS)
+
+/* umte CSR bits */
+#define UMTE_U_PM_ENABLEU_PM_ENABLE
+#define UMTE_U_PM_CURRENT   U_PM_CURRENT
+#define UMTE_U_PM_INSN  U_PM_INSN
+#define UMTE_MASK (UMTE_U_PM_ENABLE | MMTE_U_PM_CURRENT | UMTE_U_PM_INSN)
+
 #endif
-- 
2.30.2




[PATCH v17 4/8] target/riscv: Add J extension state description

2021-10-25 Thread Alexey Baturo
Signed-off-by: Alexey Baturo 
Reviewed-by: Alistair Francis 
---
 target/riscv/machine.c | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index f64b2a96c1..7b4c739564 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -84,6 +84,14 @@ static bool vector_needed(void *opaque)
 return riscv_has_ext(env, RVV);
 }
 
+static bool pointermasking_needed(void *opaque)
+{
+RISCVCPU *cpu = opaque;
+CPURISCVState *env = >env;
+
+return riscv_has_ext(env, RVJ);
+}
+
 static const VMStateDescription vmstate_vector = {
 .name = "cpu/vector",
 .version_id = 1,
@@ -100,6 +108,24 @@ static const VMStateDescription vmstate_vector = {
 }
 };
 
+static const VMStateDescription vmstate_pointermasking = {
+.name = "cpu/pointer_masking",
+.version_id = 1,
+.minimum_version_id = 1,
+.needed = pointermasking_needed,
+.fields = (VMStateField[]) {
+VMSTATE_UINTTL(env.mmte, RISCVCPU),
+VMSTATE_UINTTL(env.mpmmask, RISCVCPU),
+VMSTATE_UINTTL(env.mpmbase, RISCVCPU),
+VMSTATE_UINTTL(env.spmmask, RISCVCPU),
+VMSTATE_UINTTL(env.spmbase, RISCVCPU),
+VMSTATE_UINTTL(env.upmmask, RISCVCPU),
+VMSTATE_UINTTL(env.upmbase, RISCVCPU),
+
+VMSTATE_END_OF_LIST()
+}
+};
+
 static const VMStateDescription vmstate_hyper = {
 .name = "cpu/hyper",
 .version_id = 1,
@@ -191,6 +217,7 @@ const VMStateDescription vmstate_riscv_cpu = {
 _pmp,
 _hyper,
 _vector,
+_pointermasking,
 NULL
 }
 };
-- 
2.30.2




[PATCH v17 6/8] target/riscv: Support pointer masking for RISC-V for i/c/f/d/a types of instructions

2021-10-25 Thread Alexey Baturo
Signed-off-by: Alexey Baturo 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rva.c.inc | 3 +++
 target/riscv/insn_trans/trans_rvd.c.inc | 2 ++
 target/riscv/insn_trans/trans_rvf.c.inc | 2 ++
 target/riscv/insn_trans/trans_rvi.c.inc | 2 ++
 target/riscv/translate.c| 8 
 5 files changed, 17 insertions(+)

diff --git a/target/riscv/insn_trans/trans_rva.c.inc 
b/target/riscv/insn_trans/trans_rva.c.inc
index 6ea07d89b0..40fe132b04 100644
--- a/target/riscv/insn_trans/trans_rva.c.inc
+++ b/target/riscv/insn_trans/trans_rva.c.inc
@@ -25,6 +25,7 @@ static bool gen_lr(DisasContext *ctx, arg_atomic *a, MemOp 
mop)
 if (a->rl) {
 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
 }
+src1 = gen_pm_adjust_address(ctx, src1);
 tcg_gen_qemu_ld_tl(load_val, src1, ctx->mem_idx, mop);
 if (a->aq) {
 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
@@ -44,6 +45,7 @@ static bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp 
mop)
 TCGLabel *l2 = gen_new_label();
 
 src1 = get_gpr(ctx, a->rs1, EXT_ZERO);
+src1 = gen_pm_adjust_address(ctx, src1);
 tcg_gen_brcond_tl(TCG_COND_NE, load_res, src1, l1);
 
 /*
@@ -84,6 +86,7 @@ static bool gen_amo(DisasContext *ctx, arg_atomic *a,
 TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
 TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
 
+src1 = gen_pm_adjust_address(ctx, src1);
 func(dest, src1, src2, ctx->mem_idx, mop);
 
 gen_set_gpr(ctx, a->rd, dest);
diff --git a/target/riscv/insn_trans/trans_rvd.c.inc 
b/target/riscv/insn_trans/trans_rvd.c.inc
index db9ae15755..64fb0046f7 100644
--- a/target/riscv/insn_trans/trans_rvd.c.inc
+++ b/target/riscv/insn_trans/trans_rvd.c.inc
@@ -31,6 +31,7 @@ static bool trans_fld(DisasContext *ctx, arg_fld *a)
 tcg_gen_addi_tl(temp, addr, a->imm);
 addr = temp;
 }
+addr = gen_pm_adjust_address(ctx, addr);
 
 tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], addr, ctx->mem_idx, MO_TEQ);
 
@@ -51,6 +52,7 @@ static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
 tcg_gen_addi_tl(temp, addr, a->imm);
 addr = temp;
 }
+addr = gen_pm_adjust_address(ctx, addr);
 
 tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEQ);
 
diff --git a/target/riscv/insn_trans/trans_rvf.c.inc 
b/target/riscv/insn_trans/trans_rvf.c.inc
index bddbd418d9..b5459249c4 100644
--- a/target/riscv/insn_trans/trans_rvf.c.inc
+++ b/target/riscv/insn_trans/trans_rvf.c.inc
@@ -37,6 +37,7 @@ static bool trans_flw(DisasContext *ctx, arg_flw *a)
 tcg_gen_addi_tl(temp, addr, a->imm);
 addr = temp;
 }
+addr = gen_pm_adjust_address(ctx, addr);
 
 dest = cpu_fpr[a->rd];
 tcg_gen_qemu_ld_i64(dest, addr, ctx->mem_idx, MO_TEUL);
@@ -59,6 +60,7 @@ static bool trans_fsw(DisasContext *ctx, arg_fsw *a)
 tcg_gen_addi_tl(temp, addr, a->imm);
 addr = temp;
 }
+addr = gen_pm_adjust_address(ctx, addr);
 
 tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEUL);
 
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc 
b/target/riscv/insn_trans/trans_rvi.c.inc
index 91dc438a3a..e51dbc41c5 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -144,6 +144,7 @@ static bool gen_load(DisasContext *ctx, arg_lb *a, MemOp 
memop)
 tcg_gen_addi_tl(temp, addr, a->imm);
 addr = temp;
 }
+addr = gen_pm_adjust_address(ctx, addr);
 
 tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, memop);
 gen_set_gpr(ctx, a->rd, dest);
@@ -185,6 +186,7 @@ static bool gen_store(DisasContext *ctx, arg_sb *a, MemOp 
memop)
 tcg_gen_addi_tl(temp, addr, a->imm);
 addr = temp;
 }
+addr = gen_pm_adjust_address(ctx, addr);
 
 tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, memop);
 return true;
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index d38f87d718..a5e6fa145d 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -271,6 +271,14 @@ static void gen_jal(DisasContext *ctx, int rd, 
target_ulong imm)
 ctx->base.is_jmp = DISAS_NORETURN;
 }
 
+/*
+ * Temp stub: generates address adjustment for PointerMasking
+ */
+static TCGv gen_pm_adjust_address(DisasContext *s, TCGv src)
+{
+return src;
+}
+
 #ifndef CONFIG_USER_ONLY
 /* The states of mstatus_fs are:
  * 0 = disabled, 1 = initial, 2 = clean, 3 = dirty
-- 
2.30.2




[PATCH v17 1/8] target/riscv: Add J-extension into RISC-V

2021-10-25 Thread Alexey Baturo
Signed-off-by: Alexey Baturo 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Reviewed-by: Bin Meng 
---
 target/riscv/cpu.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index a33dc30be8..1cfc6a53a0 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -65,6 +65,7 @@
 #define RVS RV('S')
 #define RVU RV('U')
 #define RVH RV('H')
+#define RVJ RV('J')
 
 /* S extension denotes that Supervisor mode exists, however it is possible
to have a core that support S mode but does not have an MMU and there
@@ -291,6 +292,7 @@ struct RISCVCPU {
 bool ext_s;
 bool ext_u;
 bool ext_h;
+bool ext_j;
 bool ext_v;
 bool ext_zba;
 bool ext_zbb;
-- 
2.30.2




[PATCH v17 0/8] RISC-V Pointer Masking implementation

2021-10-25 Thread Alexey Baturo
v16:
Rebased against the latest tree

v15:
Renamed pm into pointer_masking in machine state.

v14:
Addressed Richard's comments from previous series.

v13:
Rebased QEMU and addressed Richard's comment.

v12:
Updated function for adjusting address with pointer masking to allocate and use 
temp register.

v11:
Addressed a few style issues Alistair mentioned in the previous review.

Alexey Baturo (7):
  target/riscv: Add J-extension into RISC-V
  target/riscv: Add CSR defines for RISC-V PM extension
  target/riscv: Support CSRs required for RISC-V PM extension except for
the h-mode
  target/riscv: Add J extension state description
  target/riscv: Print new PM CSRs in QEMU logs
  target/riscv: Support pointer masking for RISC-V for i/c/f/d/a types
of instructions
  target/riscv: Allow experimental J-ext to be turned on

Anatoly Parshintsev (1):
  target/riscv: Implement address masking functions required for RISC-V
Pointer Masking extension

 target/riscv/cpu.c  |  13 ++
 target/riscv/cpu.h  |  15 ++
 target/riscv/cpu_bits.h |  96 
 target/riscv/cpu_helper.c   |  18 ++
 target/riscv/csr.c  | 285 
 target/riscv/insn_trans/trans_rva.c.inc |   3 +
 target/riscv/insn_trans/trans_rvd.c.inc |   2 +
 target/riscv/insn_trans/trans_rvf.c.inc |   2 +
 target/riscv/insn_trans/trans_rvi.c.inc |   2 +
 target/riscv/machine.c  |  27 +++
 target/riscv/translate.c|  43 
 11 files changed, 506 insertions(+)

-- 
2.30.2




[PATCH v17 5/8] target/riscv: Print new PM CSRs in QEMU logs

2021-10-25 Thread Alexey Baturo
Signed-off-by: Alexey Baturo 
---
 target/riscv/cpu.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 6b767a4a0b..16fac64806 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -271,6 +271,13 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, 
int flags)
 CSR_MSCRATCH,
 CSR_SSCRATCH,
 CSR_SATP,
+CSR_MMTE,
+CSR_UPMBASE,
+CSR_UPMMASK,
+CSR_SPMBASE,
+CSR_SPMMASK,
+CSR_MPMBASE,
+CSR_MPMMASK,
 };
 
 for (int i = 0; i < ARRAY_SIZE(dump_csrs); ++i) {
-- 
2.30.2




Re: [PATCH v3 34/48] tcg/optimize: Split out fold_to_not

2021-10-25 Thread Richard Henderson

On 10/25/21 7:17 AM, Luis Fernando Fujita Pires wrote:

From: Richard Henderson 

Split out the conditional conversion from a more complex logical operation to a
simple NOT.  Create a couple more helpers to make this easy for the outer-most
logical operations.

Signed-off-by: Richard Henderson 
---
  tcg/optimize.c | 154 +++--
  1 file changed, 86 insertions(+), 68 deletions(-)



  static bool fold_eqv(OptContext *ctx, TCGOp *op)  {
-return fold_const2(ctx, op);
+if (fold_const2(ctx, op) ||
+fold_xi_to_not(ctx, op, 0)) {


Should be fold_ix_to_not (not fold xi_to_not).


No, because for eqv we expect the second operand to be the constant -- eqv is 
commutative.




  static bool fold_orc(OptContext *ctx, TCGOp *op)  {
-return fold_const2(ctx, op);
+if (fold_const2(ctx, op) ||
+fold_xi_to_not(ctx, op, 0)) {


But for orc you are correct.  Thanks.


r~



  1   2   3   >