Re: [Qemu-devel] [PATCH 00/13] target/openrisc: Convert to decodetree.py

2018-05-04 Thread Stafford Horne
On Thu, May 03, 2018 at 10:40:17PM -0700, Richard Henderson wrote:
> While the openrisc decode isn't particularly complicated,
> the result, I think, is still cleaner.

Hi Richard,

I agree this does look clean, thanks for doing this.

I reviewed all and everything seems good, do you plan to send the PR during the
merge window?

-Stafford

> 
> r~
> 
> 
> Richard Henderson (13):
>   target-openrisc: Write back result before FPE exception
>   target/openrisc: Start conversion to decodetree.py
>   target/openrisc: Convert branch insns
>   target/openrisc: Convert memory insns
>   target/openrisc: Convert remainder of dec_misc insns
>   target/openrisc: Convert dec_calc
>   target/openrisc: Convert dec_mac
>   target/openrisc: Convert dec_logic
>   target/openrisc: Convert dec_M
>   target/openrisc: Convert dec_comp
>   target/openrisc: Convert dec_compi
>   target/openrisc: Convert dec_float
>   target/openrisc: Merge disas_openrisc_insn
> 
>  target/openrisc/helper.h  |   25 +-
>  target/openrisc/fpu_helper.c  |  250 ++
>  target/openrisc/translate.c   | 1847 
> +++--
>  target/openrisc/Makefile.objs |9 +
>  target/openrisc/insns.decode  |  189 +
>  5 files changed, 1110 insertions(+), 1210 deletions(-)
>  create mode 100644 target/openrisc/insns.decode
> 
> -- 
> 2.14.3
> 



Re: [Qemu-devel] [PATCH 13/13] target/openrisc: Merge disas_openrisc_insn

2018-05-04 Thread Stafford Horne
On Thu, May 03, 2018 at 10:40:30PM -0700, Richard Henderson wrote:
> Signed-off-by: Richard Henderson 

Acked-by: Stafford Horne 

> ---
>  target/openrisc/translate.c | 15 ++-
>  1 file changed, 6 insertions(+), 9 deletions(-)
> 
> diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
> index 66e493220e..3866106bf6 100644
> --- a/target/openrisc/translate.c
> +++ b/target/openrisc/translate.c
> @@ -1373,14 +1373,6 @@ static bool trans_lf_sfle_s(DisasContext *dc, arg_ab 
> *a, uint32_t insn)
>  return true;
>  }
>  
> -static void disas_openrisc_insn(DisasContext *dc, OpenRISCCPU *cpu)
> -{
> -uint32_t insn = cpu_ldl_code(>env, dc->pc);
> -if (!decode(dc, insn)) {
> -gen_illegal_exception(dc);
> -}
> -}
> -
>  void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
>  {
>  CPUOpenRISCState *env = cs->env_ptr;
> @@ -1388,6 +1380,7 @@ void gen_intermediate_code(CPUState *cs, struct 
> TranslationBlock *tb)
>  struct DisasContext ctx, *dc = 
>  uint32_t pc_start;
>  uint32_t next_page_start;
> +uint32_t insn;
>  int num_insns;
>  int max_insns;
>  
> @@ -1449,7 +1442,11 @@ void gen_intermediate_code(CPUState *cs, struct 
> TranslationBlock *tb)
>  if (num_insns == max_insns && (tb_cflags(tb) & CF_LAST_IO)) {
>  gen_io_start();
>  }
> -disas_openrisc_insn(dc, cpu);
> +
> +insn = cpu_ldl_code(>env, dc->pc);
> +if (!decode(dc, insn)) {
> +gen_illegal_exception(dc);
> +}
>  dc->pc = dc->pc + 4;
>  
>  /* delay slot */
> -- 
> 2.14.3
> 



Re: [Qemu-devel] [PATCH 12/13] target/openrisc: Convert dec_float

2018-05-04 Thread Stafford Horne
On Thu, May 03, 2018 at 10:40:29PM -0700, Richard Henderson wrote:
> Signed-off-by: Richard Henderson 

Acked-by: Stafford Horne 

> ---
>  target/openrisc/translate.c  | 359 
> +++
>  target/openrisc/insns.decode |  21 +++
>  2 files changed, 149 insertions(+), 231 deletions(-)
> 
> diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
 



Re: [Qemu-devel] [PATCH 10/13] target/openrisc: Convert dec_comp

2018-05-04 Thread Stafford Horne
On Thu, May 03, 2018 at 10:40:27PM -0700, Richard Henderson wrote:
> Signed-off-by: Richard Henderson 

Acked-by: Stafford Horne 

> ---
>  target/openrisc/translate.c  | 120 
> +--
>  target/openrisc/insns.decode |  15 ++
>  2 files changed, 73 insertions(+), 62 deletions(-)
> 
> diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
 



Re: [Qemu-devel] [PATCH 11/13] target/openrisc: Convert dec_compi

2018-05-04 Thread Stafford Horne
On Thu, May 03, 2018 at 10:40:28PM -0700, Richard Henderson wrote:
> Signed-off-by: Richard Henderson 

Acked-by: Stafford Horne 

> ---
>  target/openrisc/translate.c  | 116 
> +--
>  target/openrisc/insns.decode |  12 +
>  2 files changed, 70 insertions(+), 58 deletions(-)
> 
> diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
 



Re: [Qemu-devel] [PATCH 09/13] target/openrisc: Convert dec_M

2018-05-04 Thread Stafford Horne
On Thu, May 03, 2018 at 10:40:26PM -0700, Richard Henderson wrote:
> Signed-off-by: Richard Henderson 

Acked-by: Stafford Horne 

> ---
>  target/openrisc/translate.c  | 41 +
>  target/openrisc/insns.decode |  3 +++
>  2 files changed, 16 insertions(+), 28 deletions(-)
> 
> diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
 



Re: [Qemu-devel] [PATCH 08/13] target/openrisc: Convert dec_logic

2018-05-04 Thread Stafford Horne
On Thu, May 03, 2018 at 10:40:25PM -0700, Richard Henderson wrote:
> Signed-off-by: Richard Henderson 

Acked-by: Stafford Horne 

> ---
>  target/openrisc/translate.c  | 62 
> +++-
>  target/openrisc/insns.decode |  6 +
>  2 files changed, 32 insertions(+), 36 deletions(-)
> 
> diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
 



Re: [Qemu-devel] [PATCH 07/13] target/openrisc: Convert dec_mac

2018-05-04 Thread Stafford Horne
On Thu, May 03, 2018 at 10:40:24PM -0700, Richard Henderson wrote:
> Signed-off-by: Richard Henderson 

Acked-by: Stafford Horne 

> ---
>  target/openrisc/translate.c  | 55 
> ++--
>  target/openrisc/insns.decode |  5 
>  2 files changed, 27 insertions(+), 33 deletions(-)
> 
> diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
 



Re: [Qemu-devel] [PATCH 06/13] target/openrisc: Convert dec_calc

2018-05-04 Thread Stafford Horne
On Thu, May 03, 2018 at 10:40:23PM -0700, Richard Henderson wrote:
> Signed-off-by: Richard Henderson 

Acked-by: Stafford Horne 

> ---
>  target/openrisc/translate.c  | 322 
> +++
>  target/openrisc/insns.decode |  76 +++---
>  2 files changed, 229 insertions(+), 169 deletions(-)
> 
> diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
 



Re: [Qemu-devel] [PATCH v4 02/11] machine: make MemoryHotplugState accessible via the machine

2018-05-04 Thread Marcel Apfelbaum



On 05/04/2018 10:26 PM, Eduardo Habkost wrote:

On Mon, Apr 23, 2018 at 06:51:17PM +0200, David Hildenbrand wrote:
[...]

+/* always allocate the device memory information */
+machine->device_memory = g_malloc(sizeof(*machine->device_memory));

[...]

-/* initialize hotplug memory address space */
+/* always allocate the device memory information */
+machine->device_memory = g_malloc(sizeof(*machine->device_memory));

This makes QEMU crash because machine->device_memory->base is initialized with
garbage:

#1  0x7fffef30a8f8 in abort () at /lib64/libc.so.6
#2  0x7fffef302026 in __assert_fail_base () at /lib64/libc.so.6
#3  0x7fffef3020d2 in  () at /lib64/libc.so.6
#4  0x55833483 in int128_get64 (a=) at 
.../qemu-build/include/qemu/int128.h:22
#5  0x55837c2e in memory_region_size (a=) at 
.../qemu-build/memory.c:1735
#6  0x55837c2e in memory_region_size (mr=) at 
.../qemu-build/memory.c:1739
#7  0x558a2b14 in pc_memory_init (pcms=pcms@entry=0x56850050, 
system_memory=system_memory@entry=0x56851e00, 
rom_memory=rom_memory@entry=0x568b8120, 
ram_memory=ram_memory@entry=0x7fffd630)
 at .../qemu-build/hw/i386/pc.c:1440
#8  0x558a5a73 in pc_init1 (machine=0x56850050, pci_type=0x55cb6fd0 
"i440FX", host_type=0x55c43e41 "i440FX-pcihost") at 
.../qemu-build/hw/i386/pc_piix.c:179
#9  0x559abbda in machine_run_board_init (machine=0x56850050) at 
.../qemu-build/hw/core/machine.c:829
#10 0x557dc515 in main (argc=, argv=, 
envp=) at .../qemu-build/vl.c:4563


I will squash the following fixup:

 From 6216fdb28476ed21c4ced4672003c9c7cb0e04d2 Mon Sep 17 00:00:00 2001
From: David Hildenbrand 
Date: Fri, 4 May 2018 15:54:46 +0200
Subject: [PATCH] memory-device: fix device_memory creation on pc and spapr

We have to inititalize the struct to 0. Otherwise, without "maxmem",
the content is undefined, which might result in random asserts
striking when e.g. reading out the size of the contained memory region.

Signed-off-by: David Hildenbrand 
---
  hw/i386/pc.c   | 2 +-
  hw/ppc/spapr.c | 2 +-
  2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index ffcd7b85d9..868893d0a1 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1372,7 +1372,7 @@ void pc_memory_init(PCMachineState *pcms,
  }
  
  /* always allocate the device memory information */

-machine->device_memory = g_malloc(sizeof(*machine->device_memory));
+machine->device_memory = g_malloc0(sizeof(*machine->device_memory));
  
  /* initialize device memory address space */

  if (pcmc->has_reserved_memory &&
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index ef05075232..a1abcba6ad 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2637,7 +2637,7 @@ static void spapr_machine_init(MachineState *machine)
  memory_region_add_subregion(sysmem, 0, ram);
  
  /* always allocate the device memory information */

-machine->device_memory = g_malloc(sizeof(*machine->device_memory));
+machine->device_memory = g_malloc0(sizeof(*machine->device_memory));
  
  /* initialize hotplug memory address space */

  if (machine->ram_size < machine->maxram_size) {


Reviewed-by: Marcel Apfelbaum

Thanks,
Marcel



Re: [Qemu-devel] [PATCH 05/13] target/openrisc: Convert remainder of dec_misc insns

2018-05-04 Thread Stafford Horne
On Thu, May 03, 2018 at 10:40:22PM -0700, Richard Henderson wrote:
> Signed-off-by: Richard Henderson 

Acked-by: Stafford Horne 

> ---
>  target/openrisc/translate.c  | 279 
> +++
>  target/openrisc/insns.decode |  35 +-
>  2 files changed, 151 insertions(+), 163 deletions(-)
> 
> diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c




Re: [Qemu-devel] [PATCH 04/13] target/openrisc: Convert memory insns

2018-05-04 Thread Stafford Horne
On Thu, May 03, 2018 at 10:40:21PM -0700, Richard Henderson wrote:

Acked-by: Stafford Horne 

> Signed-off-by: Richard Henderson 
> ---
>  target/openrisc/translate.c  | 275 
> +--
>  target/openrisc/insns.decode |  24 
>  2 files changed, 160 insertions(+), 139 deletions(-)
> 
> diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
 



Re: [Qemu-devel] [PATCH 03/13] target/openrisc: Convert branch insns

2018-05-04 Thread Stafford Horne
On Thu, May 03, 2018 at 10:40:20PM -0700, Richard Henderson wrote:
> Signed-off-by: Richard Henderson 

Acked-by: Stafford Horne 

> ---
>  target/openrisc/translate.c  | 149 
> +--
>  target/openrisc/insns.decode |  12 
>  2 files changed, 83 insertions(+), 78 deletions(-)
> 
> diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
 



Re: [Qemu-devel] [PATCH 02/13] target/openrisc: Start conversion to decodetree.py

2018-05-04 Thread Stafford Horne
On Thu, May 03, 2018 at 10:40:19PM -0700, Richard Henderson wrote:
> Begin with the 0x08 major opcode, the system instructions.
> 
> Signed-off-by: Richard Henderson 

Acked-by: Stafford Horne 
> ---
>  target/openrisc/translate.c   | 79 
> +--
>  target/openrisc/Makefile.objs |  9 +
>  target/openrisc/insns.decode  | 28 +++
>  3 files changed, 76 insertions(+), 40 deletions(-)
>  create mode 100644 target/openrisc/insns.decode
 



Re: [Qemu-devel] [PATCH 01/13] target-openrisc: Write back result before FPE exception

2018-05-04 Thread Stafford Horne
On Thu, May 03, 2018 at 10:40:18PM -0700, Richard Henderson wrote:
> From: Richard Henderson 
> 
> The architecture manual is unclear about this, but the or1ksim
> does writeback before the exception.  This requires splitting
> the helpers in half, with the exception raised by the second.

I dont really see a problem with this, ccing bandvig who did a lot of the fpu
hardware implementation in mor1kx.

> Reviewed-by: Bastian Koppelmann 
> Signed-off-by: Richard Henderson 

Acked-by: Stafford Horne 

> ---
>  target/openrisc/helper.h |  25 +++--
>  target/openrisc/fpu_helper.c | 250 
> +--
>  target/openrisc/translate.c  | 101 ++---
>  3 files changed, 125 insertions(+), 251 deletions(-)
> 
 



Re: [Qemu-devel] [PATCH v3 06/35] spapr/xive: introduce a XIVE interrupt presenter model

2018-05-04 Thread David Gibson
On Fri, May 04, 2018 at 03:11:57PM +0200, Cédric Le Goater wrote:
> On 05/04/2018 06:51 AM, David Gibson wrote:
> > On Thu, May 03, 2018 at 06:06:14PM +0200, Cédric Le Goater wrote:
> >> On 05/03/2018 07:35 AM, David Gibson wrote:
> >>> On Thu, Apr 26, 2018 at 11:27:21AM +0200, Cédric Le Goater wrote:
>  On 04/26/2018 09:11 AM, David Gibson wrote:
> > On Thu, Apr 19, 2018 at 02:43:02PM +0200, Cédric Le Goater wrote:
> >> The XIVE presenter engine uses a set of registers to handle priority
> >> management and interrupt acknowledgment among other things. The most
> >> important ones being :
> >>
> >>   - Interrupt Priority Register (PIPR)
> >>   - Interrupt Pending Buffer (IPB)
> >>   - Current Processor Priority (CPPR)
> >>   - Notification Source Register (NSR)
> >>
> >> There is one set of registers per level of privilege, four in all :
> >> HW, HV pool, OS and User. These are called rings. All registers are
> >> accessible through a specific MMIO region called the Thread Interrupt
> >> Management Areas (TIMA) but, depending on the privilege level of the
> >> CPU, the view of the TIMA is filtered. The sPAPR machine runs at the
> >> OS privilege and therefore can only accesses the OS and the User
> >> rings. The others are for hypervisor levels.
> >>
> >> The CPU interrupt state is modeled with a XiveNVT object which stores
> >> the values of the different registers. The different TIMA views are
> >> mapped at the same address for each CPU and 'current_cpu' is used to
> >> retrieve the XiveNVT holding the ring registers.
> >>
> >> Signed-off-by: Cédric Le Goater 
> >> ---
> >>
> >>  Changes since v2 :
> >>
> >>  - introduced the XiveFabric interface
> >>
> >>  hw/intc/spapr_xive.c|  25 
> >>  hw/intc/xive.c  | 279 
> >> 
> >>  include/hw/ppc/spapr_xive.h |   5 +
> >>  include/hw/ppc/xive.h   |  31 +
> >>  include/hw/ppc/xive_regs.h  |  84 +
> >>  5 files changed, 424 insertions(+)
> >>
> >> diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
> >> index 90cde8a4082d..f07832bf0a00 100644
> >> --- a/hw/intc/spapr_xive.c
> >> +++ b/hw/intc/spapr_xive.c
> >> @@ -13,6 +13,7 @@
> >>  #include "target/ppc/cpu.h"
> >>  #include "sysemu/cpus.h"
> >>  #include "monitor/monitor.h"
> >> +#include "hw/ppc/spapr.h"
> >>  #include "hw/ppc/spapr_xive.h"
> >>  #include "hw/ppc/xive.h"
> >>  #include "hw/ppc/xive_regs.h"
> >> @@ -95,6 +96,22 @@ static void spapr_xive_realize(DeviceState *dev, 
> >> Error **errp)
> >>  
> >>  /* Allocate the Interrupt Virtualization Table */
> >>  xive->ivt = g_new0(XiveIVE, xive->nr_irqs);
> >> +
> >> +/* The Thread Interrupt Management Area has the same address for
> >> + * each chip. On sPAPR, we only need to expose the User and OS
> >> + * level views of the TIMA.
> >> + */
> >> +xive->tm_base = XIVE_TM_BASE;
> >
> > The constant should probably have PAPR in the name somewhere, since
> > it's just for PAPR machines (same for the ESB mappings, actually).
> 
>  ok. 
> 
>  I have also made 'tm_base' a property, like 'vc_base' for ESBs, in 
>  case we want to change the value when the guest is instantiated. 
>  I doubt it but this is an address in the global address space, so 
>  letting the machine have control is better I think.
> >>>
> >>> I agree.
> >>>
> >> +
> >> +memory_region_init_io(>tm_mmio_user, OBJECT(xive),
> >> +  _tm_user_ops, xive, "xive.tima.user",
> >> +  1ull << TM_SHIFT);
> >> +sysbus_init_mmio(SYS_BUS_DEVICE(dev), >tm_mmio_user);
> >> +
> >> +memory_region_init_io(>tm_mmio_os, OBJECT(xive),
> >> +  _tm_os_ops, xive, "xive.tima.os",
> >> +  1ull << TM_SHIFT);
> >> +sysbus_init_mmio(SYS_BUS_DEVICE(dev), >tm_mmio_os);
> >>  }
> >>  
> >>  static XiveIVE *spapr_xive_get_ive(XiveFabric *xf, uint32_t lisn)
> >> @@ -104,6 +121,13 @@ static XiveIVE *spapr_xive_get_ive(XiveFabric 
> >> *xf, uint32_t lisn)
> >>  return lisn < xive->nr_irqs ? >ivt[lisn] : NULL;
> >>  }
> >>  
> >> +static XiveNVT *spapr_xive_get_nvt(XiveFabric *xf, uint32_t server)
> >> +{
> >> +PowerPCCPU *cpu = spapr_find_cpu(server);
> >> +
> >> +return cpu ? XIVE_NVT(cpu->intc) : NULL;
> >> +}
> >
> > So this is a bit of a tangent, but I've been thinking of implementing
> > a scheme where there's an opaque pointer in the cpu structure for the
> > use of the machine.  I'm planning for that to replace the intc pointer
> > (which isn't really used directly by the 

Re: [Qemu-devel] [PATCH v3 02/35] ppc/xive: add support for the LSI interrupt sources

2018-05-04 Thread David Gibson
On Fri, May 04, 2018 at 04:25:16PM +0200, Cédric Le Goater wrote:
> On 04/27/2018 04:43 AM, David Gibson wrote:
>  I did some work on that topic a while ago :
> 
>   https://patchwork.ozlabs.org/cover/836782/
> 
>  But we stopped exploring the idea. May be it was not the good approach.
>  The PHBs LSIs would benefit from such a split though.
> >>> So, no, I don't think that was a good approach, but that doesn't mean
> >>> other ways of rearranging the irq numbers aren't ok.  The thing here
> >>> is that we don't want to think of an "irq allocator" - there are some
> >>> bits like that in there already, but they were always a mistake.
> >>>
> >>> We have lots of irq space (both XICS and XIVE) so instead we should
> >>> come up with a static mapping of irqs to devices.
> >> yes. I would prefer that also. 
> >>
> >> We could change the spapr_irq_alloc() routine to get a block of 
> >> IRQs in the range defined for a device family, and use a device 
> >> id to offset in that family range ? Here are some figures :
> >>
> >> device familyblock size  max devices  
> >>
> >> EVENT_CLASS_EPOW  1   1  
> >> EVENT_CLASS_HOT_PLUG  1   1   
> >> VIO_VSCSI 1  10  
> >> VIO_LLAN  1  10  
> >> VIO_VTY   1   5  
> >>   
> >> PCI/PHB1024   5  
> > No, I'm thinking we should eliminate spapr_irq_alloc() entirely.
> > Well, ok, not entirely, we'll still need it for the old machine
> > types.  But remove it's use for the current machine type completely.
> > 
> > Instead we have an explicit map of ranges for various purposes.  The
> > one-off things like EPOW and HOTPLUG can have plain constant values.
> > PCI LSIs will be calculated as something like PCI_IRQ_BASE +  > index>*4 + .  The VIO devices we handle as VIO_BASE +  > value> or something.
> > 
> > MSIs will still need some sort of allocation, but we can do that
> > within a range set aside for them.
> 
> Should we address the static mapping of irqs before introducing XIVE ? 

Yes, I think so.

> I don't think it changes much of the architecture now that the allocator
> is under the machine. However, I wonder what would be the impact of 
> PHB hotplug.

I don't think it should be too bad.  We now require that PHBs have the
'index' parameter set, and that won't change with hotplug.  We can
then set aside a region of irq #s for each index of PHB.

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


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH v3 07/35] spapr/xive: introduce the XIVE Event Queues

2018-05-04 Thread David Gibson
On Fri, May 04, 2018 at 03:29:02PM +0200, Cédric Le Goater wrote:
> On 05/04/2018 07:19 AM, David Gibson wrote:
> > On Thu, May 03, 2018 at 04:37:29PM +0200, Cédric Le Goater wrote:
> >> On 05/03/2018 08:25 AM, David Gibson wrote:
> >>> On Thu, May 03, 2018 at 08:07:54AM +0200, Cédric Le Goater wrote:
>  On 05/03/2018 07:45 AM, David Gibson wrote:
> > On Thu, Apr 26, 2018 at 11:48:06AM +0200, Cédric Le Goater wrote:
> >> On 04/26/2018 09:25 AM, David Gibson wrote:
> >>> On Thu, Apr 19, 2018 at 02:43:03PM +0200, Cédric Le Goater wrote:
>  The Event Queue Descriptor (EQD) table is an internal table of the
>  XIVE routing sub-engine. It specifies on which Event Queue the event
>  data should be posted when an exception occurs (later on pulled by 
>  the
>  OS) and which Virtual Processor to notify.
> >>>
> >>> Uhhh.. I thought the IVT said which queue and vp to notify, and the
> >>> EQD gave metadata for event queues.
> >>
> >> yes. the above poorly written. The Event Queue Descriptor contains the
> >> guest address of the event queue in which the data is written. I will 
> >> rephrase.  
> >>
> >> The IVT contains IVEs which indeed define for an IRQ which EQ to 
> >> notify 
> >> and what data to push on the queue. 
> >>  
>  The Event Queue is a much
>  more complex structure but we start with a simple model for the sPAPR
>  machine.
> 
>  There is one XiveEQ per priority and these are stored under the XIVE
>  virtualization presenter (sPAPRXiveNVT). EQs are simply indexed with 
>  :
> 
> (server << 3) | (priority & 0x7)
> 
>  This is not in the XIVE architecture but as the EQ index is never
>  exposed to the guest, in the hcalls nor in the device tree, we are
>  free to use what fits best the current model.
> >>
> >> This EQ indexing is important to notice because it will also show up 
> >> in KVM to build the IVE from the KVM irq state.
> >
> > Ok, are you saying that while this combined EQ index will never appear
> > in guest <-> host interfaces, 
> 
>  Indeed.
> 
> > it might show up in qemu <-> KVM interfaces?
> 
>  Not directly but it is part of the IVE as the IVE_EQ_INDEX field. When
>  dumped, it has to be built in some ways, compatible with the emulated 
>  mode in QEMU. 
> >>>
> >>> Hrm.  But is the exact IVE contents visible to qemu (for a PAPR
> >>> guest)?  
> >>
> >> The guest only uses hcalls which arguments are :
> >>  
> >>- cpu numbers,
> >>- priority numbers from defined ranges, 
> >>- logical interrupt numbers.  
> >>- physical address of the EQ 
> >>
> >> The visible parts for the guest of the IVE are the 'priority', the 'cpu', 
> >> and the 'eisn', which is the effective IRQ number the guest is assigning 
> >> to the source. The 'eisn" will be pushed in the EQ.
> > 
> > Ok.
> > 
> >> The IVE EQ index is not visible.
> > 
> > Good.
> > 
> >>> I would have thought the qemu <-> KVM interfaces would have
> >>> abstracted this the same way the guest <-> KVM interfaces do.  > Or is 
> >>> there a reason not to?
> >>
> >> It is practical to dump 64bit IVEs directly from KVM into the QEMU 
> >> internal structures because it fits the emulated mode without doing 
> >> any translation ... This might be seen as a shortcut. You will tell 
> >> me when you reach the KVM part.   
> > 
> > Ugh.. exposing to qemu the raw IVEs sounds like a bad idea to me.
> 
> You definitely need to in QEMU in emulation mode. The whole routing 
> relies on it. 

I'm not exactly sure what you mean by "emulation mode" here.  Above,
I'm talking specifically about a KVM HV, PAPR guest.

> > When we migrate, we're going to have to assign the guest (server,
> > priority) tuples to host EQ indicies, and I think it makes more sense
> > to do that in KVM and hide the raw indices from qemu than to have qemu
> > mangle them explicitly on migration.
> 
> We will need some mangling mechanism for the KVM ioctls saving and
> restoring state. This is very similar to XICS. 
>  
>  Signed-off-by: Cédric Le Goater 
> >>>
> >>> Is the EQD actually modifiable by a guest?  Or are the settings of the
> >>> EQs fixed by PAPR?
> >>
> >> The guest uses the H_INT_SET_QUEUE_CONFIG hcall to define the address
> >> of the event queue for a couple prio/server.
> >
> > Ok, so the EQD can be modified by the guest.  In which case we need to
> > work out what object owns it, since it'll need to migrate it.
> 
>  Indeed. The EQD are CPU related as there is one EQD per couple (cpu, 
>  priority). The KVM patchset dumps/restores the eight XiveEQ struct 
>  using per cpu ioctls. The EQ in the OS RAM is marked dirty at that
>  stage.
> >>>
> >>> To make sure I'm clear: for PAPR there's a 

Re: [Qemu-devel] [PATCH v3 04/35] spapr/xive: introduce a XIVE interrupt controller for sPAPR

2018-05-04 Thread David Gibson
On Fri, May 04, 2018 at 03:05:08PM +0200, Cédric Le Goater wrote:
> On 05/04/2018 05:33 AM, David Gibson wrote:
> > On Thu, May 03, 2018 at 06:50:09PM +0200, Cédric Le Goater wrote:
> >> On 05/03/2018 07:22 AM, David Gibson wrote:
> >>> On Thu, Apr 26, 2018 at 12:43:29PM +0200, Cédric Le Goater wrote:
>  On 04/26/2018 06:20 AM, David Gibson wrote:
> > On Tue, Apr 24, 2018 at 11:46:04AM +0200, Cédric Le Goater wrote:
> >> On 04/24/2018 08:51 AM, David Gibson wrote:
> >>> On Thu, Apr 19, 2018 at 02:43:00PM +0200, Cédric Le Goater wrote:
>  sPAPRXive is a model for the XIVE interrupt controller device of the
>  sPAPR machine. It holds the routing XIVE table, the Interrupt
>  Virtualization Entry (IVE) table which associates interrupt source
>  numbers with targets.
> 
>  Also extend the XiveFabric with an accessor to the IVT. This will be
>  needed by the routing algorithm.
> 
>  Signed-off-by: Cédric Le Goater 
>  ---
> 
>   May be should introduce a XiveRouter model to hold the IVT. To be
>   discussed.
> >>>
> >>> Yeah, maybe.  Am I correct in thinking that on pnv there could be more
> >>> than one XiveRouter?
> >>
> >> There is only one, the main IC. 
> >
> > Ok, that's what I thought originally.  In that case some of the stuff
> > in the patches really doesn't make sense to me.
> 
>  well, there is one IC per chip on powernv, but we haven't reach that part
>  yet.
> >>>
> >>> Hmm.  There's some things we can delay dealing with, but I don't think
> >>> this is one of them.  I think we need to understand how multichip is
> >>> going to work in order to come up with a sane architecture.  Otherwise
> >>> I fear we'll end up with something that we either need to horribly
> >>> bastardize for multichip, or have to rework things dramatically
> >>> leading to migration nightmares.
> >>
> >> So, it is all controlled by MMIO, so we should be fine on that part. 
> >> As for the internal tables, they are all configured by firmware, using
> >> a chip identifier (block). I need to check how the remote XIVE are 
> >> accessed. I think this is by MMIO. 
> > 
> > Right, but for powernv we execute OPAL inside the VM, rather than
> > emulating its effects.  So we still need to model the actual hardware
> > interfaces.  OPAL hides the details from the kernel, but not from us
> > on the other side.
> 
> Yes. This is the case in the current model. I took a look today and
> I have a few fixes for the MMIO layout for P9 chips which I will send.
> 
> As for XIVE, the model needs to be a little more  complex to support 
> VSD_MODE_FORWARD tables which describe how to forward a notification
> to another XIVE IC on another chip. They contain an address on which 
> to load, This is another hop in the notification chain.  

Ah, ok.  So is that mode and address configured in the (bare metal)
IVT as well?  Or is that a different piece of configuration?

> >> I haven't looked at multichip XIVE support but I am not too worried as 
> >> the framework is already in place for the machine.
> >>  
> >>> If we did have a XiveRouter, I'm not sure we'd need the XiveFabric
> >>> interface, possibly its methods could just be class methods of
> >>> XiveRouter.
> >>
> >> Yes. We could introduce a XiveRouter to share the ivt table between 
> >> the sPAPRXive and the PnvXIVE models, the interrupt controllers of
> >> the machines. Methods would provide way to get the ivt/eq/nvt
> >> objects required for routing. I need to add a set_eq() to push the
> >> EQ data.
> >
> > Hrm.  Well, to add some more clarity, let's say the XiveRouter is the
> > object which owns the IVT.  
> 
>  OK. that would be a model with some state and not an interface.
> >>>
> >>> Yes.  For papr variant it would have the whole IVT contents as its
> >>> state.  For the powernv, just the registers telling it where to find
> >>> the IVT in RAM.
> >>>
> > It may or may not do other stuff as well.
> 
>  Its only task would be to do the final event routing: get the IVE,
>  get the EQ, push the EQ DATA in the OS event queue, notify the CPU.
> >>>
> >>> That seems like a lot of steps.  Up to push the EQ DATA, certainly.
> >>> And I guess it'll have to ping an NVT somehow, but I'm not sure it
> >>> should know about CPUs as such.
> >>
> >> For PowerNV, the concept could be generalized, yes. An NVT can 
> >> contain the interrupt state of a logical server but the common 
> >> case is baremetal without guests for QEMU and so we have a NVT 
> >> per cpu. 
> > 
> > Hmm.  We eventually want to support a kernel running guests under
> > qemu/powernv though, right?  
> 
> arg. an emulated hypervisor ! OK let's say this is a long term goal :) 
> 
> > So even if we don't allow it right now,
> > we don't want allowing that to require major surgery to our

Re: [Qemu-devel] [Qemu-ppc] [PATCH] target/ppc: only save guest timebase once after stopping

2018-05-04 Thread David Gibson
On Fri, May 04, 2018 at 07:18:13AM -0500, Michael Roth wrote:
> Quoting Greg Kurz (2018-05-04 04:37:24)
> > On Thu,  3 May 2018 23:20:44 -0500
> > Michael Roth  wrote:
> > 
> > > In some cases (e.g. spapr) we record guest timebase after qmp_stop()
> > > via a runstate hook so we can restore it on qmp_cont(). If a migration
> > > occurs in between those events we end up saving it again, this time
> > > based on the current timebase the guest would be seeing had it been
> > > running. This has the effect of advancing the guest timebase while
> > > it is stopped, which is not what the code intends.
> > > 
> > 
> > Hi Mike,
> > 
> > The current behavior was introduced by:
> > 
> > commit 42043e4f1241eeb77f87f5816b5cf0b6e9583ed7
> > Author: Laurent Vivier 
> > Date:   Fri Jan 27 13:24:58 2017 +0100
> > 
> > spapr: clock should count only if vm is running
> > 
> > and we have this in the changelog:
> > 
> > We keep timebase_pre_save to reduce the clock difference on
> > migration like in:
> > 6053a86 kvmclock: reduce kvmclock difference on migration
> > 
> > 
> > So your patch totally negates ^^ ? Also, I can't see a case where
> 
> Yah... this is a bit confusing. On one hand, the patch/summary is clearly
> trying to avoid the guest time from advancing while it is stopped, which
> is in the spirit of this patch. But at the same time it is trying to
> compensate for loss of time (relative to host) due to downtime window.
> 
> I think the subtlety is in the amount of time... saving at pre_save
> rather than vm_stop() compensates for the normal downtime window, which
> is *usually* small (5s is the figure they quote in the notes there and
> in the motivating 6053a86 "kvmclock: reduce kvmclock difference on
> migration"). The delays between vm_stop and vm_cont via something like
> virsh suspend/resume is unbounded, unhowever, hence the rationale for
> the runstate hook (?).

> So maybe small jumps are considered okay, and large ones not? If that's
> the reasoning, then this patch is addressing the later, so it's not
> necessarily in conflict with that motivation, but the implementation
> does negate the small jumps we try to avoid via pre_save hook since
> we'll end up keep the version we saved just after vm_stop instead.

So, the size of the jump is an important difference in practice, but I
don't think it's what we should base our decisions on.  Rather, we
should be basing the decision on the *reason* for the jump.

If it's due to an explicit user requested stoppage, then we should
stop the clock.  The user has basically asked for the VM to be put
into statis, and that won't really work if we don't stop the clock.

If the stoppage is due to an internal detail for what, from the user's
point of view, is supposed to be a still-running VM (i.e. a
migration), then the clock should continue.  Otherwise it will be
wrong, afterwards.

> I would note that the downtime window itself, while usually small, can
> also be quite large. With 1GB hugepages we've seen some guests requiring
> downtime windows to be set to 25s until QEMU would start cut-over. Also
> rcu_cpu_stall_timeout is configurable...it's possible if we set it to
> 5s it could trigger on the jump the guest experiences from pre_save (I
> haven't tested that though).

> Maybe trying to compensate for downtime is a generally bad idea and we
> should just leave it up to NTP/etc? Or maybe we should choose a specific
> upper bound on how much migration downtime we're willing to compensate
> for and enforce that directly? E.g. tb->saved becomes tb->saved_time and
> we check the difference in pre_save before calling timebase_save()
> again.

Yes, downtimes can sometimes be long.  I still think it's correct to
keep the clock going in that case.  The guest may give warnings
because it's seeing something funny with the clock.  Something *is*
funny with the clock, and those warnings are correct.  Basically, when
the downtime is that long we can't really maintain the illusion of a
continuously running VM.  Pretending we can by fudging the clocks is
not doing our users a service

> > So your patch totally negates ^^ ? Also, I can't see a case where
> > timebase_save() could be called from vmstate_save_state() while the
> > VM is running, ie, you could drop timebase_pre_save()... or am I
> > *probably* missing something ?
> 
> Yah, I didn't notice that my patch completely negated the pre_save
> hook... for some reason I was thinking that would continue to function
> normally if we didn't call qmp_stop() explicitly but that's clearly not
> the case. So yah, dropping timebase_pre_save() is essentially what my
> patch is doing...
> 
> > 
> > > Other than simple jumps in time, this has been seen to trigger what
> > > appear to be RCU-related crashes in recent kernels when the advance
> > > exceeds rcu_cpu_stall_timeout, and it can be triggered by fairly
> > > common operations such as `virsh migrate ... --timeout 

Re: [Qemu-devel] [Qemu-ppc] [PATCH] target/ppc: only save guest timebase once after stopping

2018-05-04 Thread David Gibson
On Fri, May 04, 2018 at 03:50:28PM +0200, Greg Kurz wrote:
> On Fri, 04 May 2018 07:18:13 -0500
> Michael Roth  wrote:
> 
> > Quoting Greg Kurz (2018-05-04 04:37:24)
> > > On Thu,  3 May 2018 23:20:44 -0500
> > > Michael Roth  wrote:
> > >   
> > > > In some cases (e.g. spapr) we record guest timebase after qmp_stop()
> > > > via a runstate hook so we can restore it on qmp_cont(). If a migration
> > > > occurs in between those events we end up saving it again, this time
> > > > based on the current timebase the guest would be seeing had it been
> > > > running. This has the effect of advancing the guest timebase while
> > > > it is stopped, which is not what the code intends.
> > > >   
> > > 
> > > Hi Mike,
> > > 
> > > The current behavior was introduced by:
> > > 
> > > commit 42043e4f1241eeb77f87f5816b5cf0b6e9583ed7
> > > Author: Laurent Vivier 
> > > Date:   Fri Jan 27 13:24:58 2017 +0100
> > > 
> > > spapr: clock should count only if vm is running
> > > 
> > > and we have this in the changelog:
> > > 
> > > We keep timebase_pre_save to reduce the clock difference on
> > > migration like in:
> > > 6053a86 kvmclock: reduce kvmclock difference on migration
> > > 
> > > 
> > > So your patch totally negates ^^ ? Also, I can't see a case where  
> > 
> > Yah... this is a bit confusing. On one hand, the patch/summary is clearly
> > trying to avoid the guest time from advancing while it is stopped, which
> > is in the spirit of this patch. But at the same time it is trying to
> > compensate for loss of time (relative to host) due to downtime window.
> > 
> 
> Yeah... not sure why Laurent decided to address both in the same patch...
> maybe just because we already had the pre_save hook ?
> 
> > I think the subtlety is in the amount of time... saving at pre_save
> > rather than vm_stop() compensates for the normal downtime window, which
> > is *usually* small (5s is the figure they quote in the notes there and
> > in the motivating 6053a86 "kvmclock: reduce kvmclock difference on
> > migration"). The delays between vm_stop and vm_cont via something like
> > virsh suspend/resume is unbounded, unhowever, hence the rationale for
> > the runstate hook (?).
> > 
> 
> That's my understanding as well.
> 
> > So maybe small jumps are considered okay, and large ones not? If that's
> > the reasoning, then this patch is addressing the later, so it's not
> > necessarily in conflict with that motivation, but the implementation
> > does negate the small jumps we try to avoid via pre_save hook since
> > we'll end up keep the version we saved just after vm_stop instead.
> > 
> > I would note that the downtime window itself, while usually small, can
> > also be quite large. With 1GB hugepages we've seen some guests requiring
> > downtime windows to be set to 25s until QEMU would start cut-over. Also
> > rcu_cpu_stall_timeout is configurable...it's possible if we set it to
> > 5s it could trigger on the jump the guest experiences from pre_save (I
> > haven't tested that though).
> > 
> > Maybe trying to compensate for downtime is a generally bad idea and we
> > should just leave it up to NTP/etc? 
> 
> My understanding of NTP is that it isn't designed to cope with sudden
> time differences, which is exactly what happens in our case.

I think so too.  I mean it will correct things right eventually,
unless the jump is *really* huge, but it's not a good enough solution
that we shouldn't at least try to keep the guest's wall-time clock
correct across the migration.

> > Or maybe we should choose a specific
> > upper bound on how much migration downtime we're willing to compensate
> > for and enforce that directly? E.g. tb->saved becomes tb->saved_time and
> > we check the difference in pre_save before calling timebase_save()
> > again.
> > 
> 
> This would maybe allow to reach a compromise between the current code
> and your patch... but it would still be difficult to come up with
> a sensible value for this upper bound, wouldn't it ?
> 
> > > So your patch totally negates ^^ ? Also, I can't see a case where
> > > timebase_save() could be called from vmstate_save_state() while the
> > > VM is running, ie, you could drop timebase_pre_save()... or am I
> > > *probably* missing something ?  
> > 
> > Yah, I didn't notice that my patch completely negated the pre_save
> > hook... for some reason I was thinking that would continue to function
> > normally if we didn't call qmp_stop() explicitly but that's clearly not
> > the case. So yah, dropping timebase_pre_save() is essentially what my
> > patch is doing...
> > 
> 
> 
> How does Linux cope with standard software suspend or hibernate ? It also
> causes a downtime and it doesn't generate RCU stalls AFAIK... would it
> be possible/make sense for migration to look like an hibernate ?
> 

In that case the guest is aware of the stoppage, and knows to a)
correct its internal clock afterwards 

Re: [Qemu-devel] [PATCH] ppc440_pcix: Fix a typo in setting a register (Coverity CID1390577)

2018-05-04 Thread David Gibson
On Fri, May 04, 2018 at 10:45:50AM +0200, BALATON Zoltan wrote:
> Signed-off-by: BALATON Zoltan 

Applied to ppc-for-2.13.  There won't be a pull request until after
I'm back from holidays in a month, though. Sorry.

> ---
>  hw/ppc/ppc440_pcix.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/ppc/ppc440_pcix.c b/hw/ppc/ppc440_pcix.c
> index b1307e6..d8af04b 100644
> --- a/hw/ppc/ppc440_pcix.c
> +++ b/hw/ppc/ppc440_pcix.c
> @@ -257,7 +257,7 @@ static void ppc440_pcix_reg_write4(void *opaque, hwaddr 
> addr,
>  break;
>  case PCIX0_PIM2SAL:
>  s->pim[2].sa &= 0xULL;
> -s->pim[2].sa = val;
> +s->pim[2].sa |= val;
>  ppc440_pcix_update_pim(s, 2);
>  break;
>  case PCIX0_PIM2LAL:

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


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH 17/20] sdcard: Add SDFrameData struct and data frame checksum functions

2018-05-04 Thread Philippe Mathieu-Daudé
On 05/04/2018 12:59 PM, Philippe Mathieu-Daudé wrote:
> The block transfers data frames are upto 512 bytes and use a 16-bit CRC.
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  include/hw/sd/sd.h | 29 +
>  hw/sd/sdmmc-internal.c | 10 ++
>  2 files changed, 39 insertions(+)
> 
> diff --git a/include/hw/sd/sd.h b/include/hw/sd/sd.h
> index c76be51b32..6bf9daf559 100644
> --- a/include/hw/sd/sd.h
> +++ b/include/hw/sd/sd.h
> @@ -102,6 +102,17 @@ typedef struct SDFrame136 {
>  uint8_t crc;
>  } SDFrame136;
>  
> +/**
> + * SDFrameData: 512 bytes block transfers
> + *
> + * @content: block data
> + * @crc: 16-bit CRC checksum
> + */
> +typedef struct SDFrameData {
> +uint8_t content[512];
> +uint16_t crc;
> +} SDFrameData;
> +
>  typedef struct SDFrame48 SDRequest;
>  
>  typedef struct SDState SDState;
> @@ -212,6 +223,14 @@ void sd_update_frame48_checksum(SDFrame48 *frame, bool 
> is_response);
>   */
>  void sd_update_frame136_checksum(SDFrame136 *frame);
>  
> +/**
> + * sd_update_framedata_checksum:
> + * @frame: the #SDFrameData to verify
> + *
> + * Update the 16-bit CRC checksum of a SD data frame (up to 512 bytes).
> + */
> +void sd_update_framedata_checksum(SDFrameData *frame);

Since the frame size is variable, this function needs a size_t argument.

> +
>  /**
>   * sd_verify_frame48_checksum:
>   * @frame: the #SDFrame48 to verify
> @@ -233,6 +252,16 @@ bool sd_verify_frame48_checksum(SDFrame48 *frame, bool 
> is_response);
>   */
>  bool sd_verify_frame136_checksum(SDFrame136 *frame);
>  
> +/**
> + * sd_verify_framedata_checksum:
> + * @frame: the #SDFrameData to verify
> + *
> + * Verify the 16-bit CRC checksum of a SD data frame.
> + *
> + * Returns: A boolean indicating whether the frame 16-bit CRC is correct.
> + */
> +bool sd_verify_framedata_checksum(SDFrameData *frame);

Ditto.

> +
>  /* Legacy functions to be used only by non-qdevified callers */
>  SDState *sd_init(BlockBackend *bs, bool is_spi);
>  int sd_do_command(SDState *sd, SDRequest *req,
> diff --git a/hw/sd/sdmmc-internal.c b/hw/sd/sdmmc-internal.c
> index 68350a2304..0e82e69d99 100644
> --- a/hw/sd/sdmmc-internal.c
> +++ b/hw/sd/sdmmc-internal.c
> @@ -134,6 +134,11 @@ bool sd_verify_frame136_checksum(SDFrame136 *frame)
>  return sd_calc_frame136_crc7(frame) == frame->crc;
>  }
>  
> +bool sd_verify_framedata_checksum(SDFrameData *frame)
> +{
> +return sd_crc16(frame->content, sizeof(frame->content)) == frame->crc;

I'll probably replace sizeof(frame->content) by a 'length' argument,
or add a 'length' member to SDFrameData.

> +}
> +
>  void sd_update_frame48_checksum(SDFrame48 *frame, bool is_response)
>  {
>  frame->crc = sd_calc_frame48_crc7(frame->cmd, frame->arg, is_response);
> @@ -144,6 +149,11 @@ void sd_update_frame136_checksum(SDFrame136 *frame)
>  frame->crc = (sd_crc7(frame->content, sizeof(frame->content)) << 1) | 1;
>  }
>  
> +void sd_update_framedata_checksum(SDFrameData *frame)
> +{
> +frame->crc = sd_crc16(frame->content, sizeof(frame->content));
> +}
> +
>  void sd_prepare_frame48(SDFrame48 *frame, uint8_t cmd, uint32_t arg,
>  bool is_response, bool gen_crc)
>  {
> 



Re: [Qemu-devel] [PATCH v8 11/35] RISC-V: Mark ROM read-only after copying in code

2018-05-04 Thread Michael Clark
On Sat, May 5, 2018 at 11:54 AM, Alistair Francis 
wrote:

> On Fri, May 4, 2018 at 4:44 PM Alistair Francis 
> wrote:
>
> > On Thu, May 3, 2018 at 6:45 PM Michael Clark  wrote:
>
>
>
> > > On Sat, Apr 28, 2018 at 4:17 AM, Alistair Francis <
> alistai...@gmail.com>
> > wrote:
>
> > >> On Thu, Apr 26, 2018 at 10:34 PM Michael Clark 
> wrote:
>
>
>
> > >> > On Fri, Apr 27, 2018 at 5:22 PM, Michael Clark 
> wrote:
>
>
>
> > >> >> On Fri, Apr 27, 2018 at 4:48 AM, Alistair Francis <
> > alistai...@gmail.com>
> > >> wrote:
>
> > >> >>> On Wed, Apr 25, 2018 at 5:03 PM Michael Clark 
> wrote:
>
> > >> >>> > The sifive_u machine already marks its ROM readonly. This fixes
> > >> >>> > the remaining boards. This commit also makes all boards use
> > >> >>> > mask_rom as the variable name for the ROM. This change also
> > >> >>> > makes space for the maximum device tree size size and adds
> > >> >>> > an explicit bounds check and error message.
>
> > >> >>> > Cc: Sagar Karandikar 
> > >> >>> > Cc: Bastian Koppelmann 
> > >> >>> > Cc: Palmer Dabbelt 
> > >> >>> > Cc: Alistair Francis 
> > >> >>> > Signed-off-by: Michael Clark 
> > >> >>> > ---
> > >> >>> >   hw/riscv/sifive_e.c | 20 +++-
> > >> >>> >   hw/riscv/sifive_u.c | 46
> ++-
> > >> >>> >   hw/riscv/spike.c| 64
> > >> >>> -
> > >> >>> >   hw/riscv/virt.c | 38 +++--
> > >> >>> >   include/hw/riscv/virt.h |  4 
> > >> >>> >   5 files changed, 93 insertions(+), 79 deletions(-)
>
> > >> >>> > diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
> > >> >>> > index 39e4cb4..0c8b8e9 100644
> > >> >>> > --- a/hw/riscv/sifive_e.c
> > >> >>> > +++ b/hw/riscv/sifive_e.c
> > >> >>> > @@ -74,14 +74,6 @@ static const struct MemmapEntry {
> > >> >>> >   [SIFIVE_E_DTIM] = { 0x8000, 0x4000 }
> > >> >>> >   };
>
> > >> >>> > -static void copy_le32_to_phys(hwaddr pa, uint32_t *rom, size_t
> > len)
> > >> >>> > -{
> > >> >>> > -int i;
> > >> >>> > -for (i = 0; i < (len >> 2); i++) {
> > >> >>> > -stl_phys(_space_memory, pa + (i << 2),
> rom[i]);
> > >> >>> > -}
> > >> >>> > -}
> > >> >>> > -
> > >> >>> >   static uint64_t load_kernel(const char *kernel_filename)
> > >> >>> >   {
> > >> >>> >   uint64_t kernel_entry, kernel_high;
> > >> >>> > @@ -112,6 +104,7 @@ static void riscv_sifive_e_init(
> MachineState
> > >> *machine)
> > >> >>> >   MemoryRegion *main_mem = g_new(MemoryRegion, 1);
> > >> >>> >   MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
> > >> >>> >   MemoryRegion *xip_mem = g_new(MemoryRegion, 1);
> > >> >>> > +int i;
>
> > >> >>> >   /* Initialize SOC */
> > >> >>> >   object_initialize(>soc, sizeof(s->soc),
> > >> TYPE_RISCV_HART_ARRAY);
> > >> >>> > @@ -131,7 +124,7 @@ static void riscv_sifive_e_init(
> MachineState
> > >> *machine)
> > >> >>> >   memmap[SIFIVE_E_DTIM].base, main_mem);
>
> > >> >>> >   /* Mask ROM */
> > >> >>> > -memory_region_init_ram(mask_rom, NULL,
> "riscv.sifive.e.mrom",
> > >> >>> > +memory_region_init_rom(mask_rom, NULL,
> "riscv.sifive.e.mrom",
> > >> >>> >   memmap[SIFIVE_E_MROM].size, _fatal);
> > >> >>> >   memory_region_add_subregion(sys_mem,
> > >> >>> >   memmap[SIFIVE_E_MROM].base, mask_rom);
> > >> >>> > @@ -185,9 +178,12 @@ static void riscv_sifive_e_init(
> MachineState
> > >> >>> *machine)
> > >> >>> >   0x00028067,/* 0x1004: jr  t0 */
> > >> >>> >   };
>
> > >> >>> > -/* copy in the reset vector */
> > >> >>> > -copy_le32_to_phys(memmap[SIFIVE_E_MROM].base, reset_vec,
> > >> >>> sizeof(reset_vec));
> > >> >>> > -memory_region_set_readonly(mask_rom, true);
> > >> >>> > +/* copy in the reset vector in little_endian byte order */
> > >> >>> > +for (i = 0; i < sizeof(reset_vec) >> 2; i++) {
> > >> >>> > +reset_vec[i] = cpu_to_le32(reset_vec[i]);
> > >> >>> > +}
> > >> >>> > +rom_add_blob_fixed_as("mrom.reset", reset_vec,
> > sizeof(reset_vec),
> > >> >>> > +  memmap[SIFIVE_E_MROM].base,
> > >> >>> _space_memory);
>
> > >> >>> >   if (machine->kernel_filename) {
> > >> >>> >   load_kernel(machine->kernel_filename);
> > >> >>> > diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> > >> >>> > index 115618b..11ba4c3 100644
> > >> >>> > --- a/hw/riscv/sifive_u.c
> > >> >>> > +++ b/hw/riscv/sifive_u.c
> > >> >>> > @@ -52,7 +52,7 @@ static const struct MemmapEntry {
> > >> >>> >   hwaddr size;
> > >> >>> >   } sifive_u_memmap[] = {
> > >> >>> >   [SIFIVE_U_DEBUG] ={0x0,  0x100 },
> > >> >>> > -[SIFIVE_U_MROM] = { 0x1000, 0x2000 

Re: [Qemu-devel] [PATCH v8 11/35] RISC-V: Mark ROM read-only after copying in code

2018-05-04 Thread Alistair Francis
On Fri, May 4, 2018 at 4:44 PM Alistair Francis 
wrote:

> On Thu, May 3, 2018 at 6:45 PM Michael Clark  wrote:



> > On Sat, Apr 28, 2018 at 4:17 AM, Alistair Francis 
> wrote:

> >> On Thu, Apr 26, 2018 at 10:34 PM Michael Clark  wrote:



> >> > On Fri, Apr 27, 2018 at 5:22 PM, Michael Clark 
wrote:



> >> >> On Fri, Apr 27, 2018 at 4:48 AM, Alistair Francis <
> alistai...@gmail.com>
> >> wrote:

> >> >>> On Wed, Apr 25, 2018 at 5:03 PM Michael Clark 
wrote:

> >> >>> > The sifive_u machine already marks its ROM readonly. This fixes
> >> >>> > the remaining boards. This commit also makes all boards use
> >> >>> > mask_rom as the variable name for the ROM. This change also
> >> >>> > makes space for the maximum device tree size size and adds
> >> >>> > an explicit bounds check and error message.

> >> >>> > Cc: Sagar Karandikar 
> >> >>> > Cc: Bastian Koppelmann 
> >> >>> > Cc: Palmer Dabbelt 
> >> >>> > Cc: Alistair Francis 
> >> >>> > Signed-off-by: Michael Clark 
> >> >>> > ---
> >> >>> >   hw/riscv/sifive_e.c | 20 +++-
> >> >>> >   hw/riscv/sifive_u.c | 46
++-
> >> >>> >   hw/riscv/spike.c| 64
> >> >>> -
> >> >>> >   hw/riscv/virt.c | 38 +++--
> >> >>> >   include/hw/riscv/virt.h |  4 
> >> >>> >   5 files changed, 93 insertions(+), 79 deletions(-)

> >> >>> > diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
> >> >>> > index 39e4cb4..0c8b8e9 100644
> >> >>> > --- a/hw/riscv/sifive_e.c
> >> >>> > +++ b/hw/riscv/sifive_e.c
> >> >>> > @@ -74,14 +74,6 @@ static const struct MemmapEntry {
> >> >>> >   [SIFIVE_E_DTIM] = { 0x8000, 0x4000 }
> >> >>> >   };

> >> >>> > -static void copy_le32_to_phys(hwaddr pa, uint32_t *rom, size_t
> len)
> >> >>> > -{
> >> >>> > -int i;
> >> >>> > -for (i = 0; i < (len >> 2); i++) {
> >> >>> > -stl_phys(_space_memory, pa + (i << 2), rom[i]);
> >> >>> > -}
> >> >>> > -}
> >> >>> > -
> >> >>> >   static uint64_t load_kernel(const char *kernel_filename)
> >> >>> >   {
> >> >>> >   uint64_t kernel_entry, kernel_high;
> >> >>> > @@ -112,6 +104,7 @@ static void riscv_sifive_e_init(MachineState
> >> *machine)
> >> >>> >   MemoryRegion *main_mem = g_new(MemoryRegion, 1);
> >> >>> >   MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
> >> >>> >   MemoryRegion *xip_mem = g_new(MemoryRegion, 1);
> >> >>> > +int i;

> >> >>> >   /* Initialize SOC */
> >> >>> >   object_initialize(>soc, sizeof(s->soc),
> >> TYPE_RISCV_HART_ARRAY);
> >> >>> > @@ -131,7 +124,7 @@ static void riscv_sifive_e_init(MachineState
> >> *machine)
> >> >>> >   memmap[SIFIVE_E_DTIM].base, main_mem);

> >> >>> >   /* Mask ROM */
> >> >>> > -memory_region_init_ram(mask_rom, NULL,
"riscv.sifive.e.mrom",
> >> >>> > +memory_region_init_rom(mask_rom, NULL,
"riscv.sifive.e.mrom",
> >> >>> >   memmap[SIFIVE_E_MROM].size, _fatal);
> >> >>> >   memory_region_add_subregion(sys_mem,
> >> >>> >   memmap[SIFIVE_E_MROM].base, mask_rom);
> >> >>> > @@ -185,9 +178,12 @@ static void riscv_sifive_e_init(MachineState
> >> >>> *machine)
> >> >>> >   0x00028067,/* 0x1004: jr  t0 */
> >> >>> >   };

> >> >>> > -/* copy in the reset vector */
> >> >>> > -copy_le32_to_phys(memmap[SIFIVE_E_MROM].base, reset_vec,
> >> >>> sizeof(reset_vec));
> >> >>> > -memory_region_set_readonly(mask_rom, true);
> >> >>> > +/* copy in the reset vector in little_endian byte order */
> >> >>> > +for (i = 0; i < sizeof(reset_vec) >> 2; i++) {
> >> >>> > +reset_vec[i] = cpu_to_le32(reset_vec[i]);
> >> >>> > +}
> >> >>> > +rom_add_blob_fixed_as("mrom.reset", reset_vec,
> sizeof(reset_vec),
> >> >>> > +  memmap[SIFIVE_E_MROM].base,
> >> >>> _space_memory);

> >> >>> >   if (machine->kernel_filename) {
> >> >>> >   load_kernel(machine->kernel_filename);
> >> >>> > diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> >> >>> > index 115618b..11ba4c3 100644
> >> >>> > --- a/hw/riscv/sifive_u.c
> >> >>> > +++ b/hw/riscv/sifive_u.c
> >> >>> > @@ -52,7 +52,7 @@ static const struct MemmapEntry {
> >> >>> >   hwaddr size;
> >> >>> >   } sifive_u_memmap[] = {
> >> >>> >   [SIFIVE_U_DEBUG] ={0x0,  0x100 },
> >> >>> > -[SIFIVE_U_MROM] = { 0x1000, 0x2000 },
> >> >>> > +[SIFIVE_U_MROM] = { 0x1000,0x11000 },
> >> >>> >   [SIFIVE_U_CLINT] ={  0x200,0x1 },
> >> >>> >   [SIFIVE_U_PLIC] = {  0xc00,  0x400 },
> >> >>> >   [SIFIVE_U_UART0] ={ 0x10013000, 0x1000 },
> >> >>> > @@ -60,14 +60,6 @@ static const 

Re: [Qemu-devel] [PATCH v8 11/35] RISC-V: Mark ROM read-only after copying in code

2018-05-04 Thread Alistair Francis
On Thu, May 3, 2018 at 6:45 PM Michael Clark  wrote:



> On Sat, Apr 28, 2018 at 4:17 AM, Alistair Francis 
wrote:

>> On Thu, Apr 26, 2018 at 10:34 PM Michael Clark  wrote:



>> > On Fri, Apr 27, 2018 at 5:22 PM, Michael Clark  wrote:



>> >> On Fri, Apr 27, 2018 at 4:48 AM, Alistair Francis <
alistai...@gmail.com>
>> wrote:

>> >>> On Wed, Apr 25, 2018 at 5:03 PM Michael Clark  wrote:

>> >>> > The sifive_u machine already marks its ROM readonly. This fixes
>> >>> > the remaining boards. This commit also makes all boards use
>> >>> > mask_rom as the variable name for the ROM. This change also
>> >>> > makes space for the maximum device tree size size and adds
>> >>> > an explicit bounds check and error message.

>> >>> > Cc: Sagar Karandikar 
>> >>> > Cc: Bastian Koppelmann 
>> >>> > Cc: Palmer Dabbelt 
>> >>> > Cc: Alistair Francis 
>> >>> > Signed-off-by: Michael Clark 
>> >>> > ---
>> >>> >   hw/riscv/sifive_e.c | 20 +++-
>> >>> >   hw/riscv/sifive_u.c | 46 ++-
>> >>> >   hw/riscv/spike.c| 64
>> >>> -
>> >>> >   hw/riscv/virt.c | 38 +++--
>> >>> >   include/hw/riscv/virt.h |  4 
>> >>> >   5 files changed, 93 insertions(+), 79 deletions(-)

>> >>> > diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
>> >>> > index 39e4cb4..0c8b8e9 100644
>> >>> > --- a/hw/riscv/sifive_e.c
>> >>> > +++ b/hw/riscv/sifive_e.c
>> >>> > @@ -74,14 +74,6 @@ static const struct MemmapEntry {
>> >>> >   [SIFIVE_E_DTIM] = { 0x8000, 0x4000 }
>> >>> >   };

>> >>> > -static void copy_le32_to_phys(hwaddr pa, uint32_t *rom, size_t
len)
>> >>> > -{
>> >>> > -int i;
>> >>> > -for (i = 0; i < (len >> 2); i++) {
>> >>> > -stl_phys(_space_memory, pa + (i << 2), rom[i]);
>> >>> > -}
>> >>> > -}
>> >>> > -
>> >>> >   static uint64_t load_kernel(const char *kernel_filename)
>> >>> >   {
>> >>> >   uint64_t kernel_entry, kernel_high;
>> >>> > @@ -112,6 +104,7 @@ static void riscv_sifive_e_init(MachineState
>> *machine)
>> >>> >   MemoryRegion *main_mem = g_new(MemoryRegion, 1);
>> >>> >   MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
>> >>> >   MemoryRegion *xip_mem = g_new(MemoryRegion, 1);
>> >>> > +int i;

>> >>> >   /* Initialize SOC */
>> >>> >   object_initialize(>soc, sizeof(s->soc),
>> TYPE_RISCV_HART_ARRAY);
>> >>> > @@ -131,7 +124,7 @@ static void riscv_sifive_e_init(MachineState
>> *machine)
>> >>> >   memmap[SIFIVE_E_DTIM].base, main_mem);

>> >>> >   /* Mask ROM */
>> >>> > -memory_region_init_ram(mask_rom, NULL, "riscv.sifive.e.mrom",
>> >>> > +memory_region_init_rom(mask_rom, NULL, "riscv.sifive.e.mrom",
>> >>> >   memmap[SIFIVE_E_MROM].size, _fatal);
>> >>> >   memory_region_add_subregion(sys_mem,
>> >>> >   memmap[SIFIVE_E_MROM].base, mask_rom);
>> >>> > @@ -185,9 +178,12 @@ static void riscv_sifive_e_init(MachineState
>> >>> *machine)
>> >>> >   0x00028067,/* 0x1004: jr  t0 */
>> >>> >   };

>> >>> > -/* copy in the reset vector */
>> >>> > -copy_le32_to_phys(memmap[SIFIVE_E_MROM].base, reset_vec,
>> >>> sizeof(reset_vec));
>> >>> > -memory_region_set_readonly(mask_rom, true);
>> >>> > +/* copy in the reset vector in little_endian byte order */
>> >>> > +for (i = 0; i < sizeof(reset_vec) >> 2; i++) {
>> >>> > +reset_vec[i] = cpu_to_le32(reset_vec[i]);
>> >>> > +}
>> >>> > +rom_add_blob_fixed_as("mrom.reset", reset_vec,
sizeof(reset_vec),
>> >>> > +  memmap[SIFIVE_E_MROM].base,
>> >>> _space_memory);

>> >>> >   if (machine->kernel_filename) {
>> >>> >   load_kernel(machine->kernel_filename);
>> >>> > diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
>> >>> > index 115618b..11ba4c3 100644
>> >>> > --- a/hw/riscv/sifive_u.c
>> >>> > +++ b/hw/riscv/sifive_u.c
>> >>> > @@ -52,7 +52,7 @@ static const struct MemmapEntry {
>> >>> >   hwaddr size;
>> >>> >   } sifive_u_memmap[] = {
>> >>> >   [SIFIVE_U_DEBUG] ={0x0,  0x100 },
>> >>> > -[SIFIVE_U_MROM] = { 0x1000, 0x2000 },
>> >>> > +[SIFIVE_U_MROM] = { 0x1000,0x11000 },
>> >>> >   [SIFIVE_U_CLINT] ={  0x200,0x1 },
>> >>> >   [SIFIVE_U_PLIC] = {  0xc00,  0x400 },
>> >>> >   [SIFIVE_U_UART0] ={ 0x10013000, 0x1000 },
>> >>> > @@ -60,14 +60,6 @@ static const struct MemmapEntry {
>> >>> >   [SIFIVE_U_DRAM] = { 0x8000,0x0 },
>> >>> >   };

>> >>> > -static void copy_le32_to_phys(hwaddr pa, uint32_t *rom, size_t
len)
>> >>> > -{
>> >>> > -int i;
>> >>> > -for (i = 0; i < (len >> 2); i++) {
>> >>> > 

Re: [Qemu-devel] [PATCH v6 0/4] slirp: Add query-usernet QMP command

2018-05-04 Thread no-reply
Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 20180504074207.22634-1-f...@redhat.com
Subject: [Qemu-devel] [PATCH v6 0/4] slirp: Add query-usernet QMP command

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
failed=1
echo
fi
n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag]   patchew/20180504074207.22634-1-f...@redhat.com -> 
patchew/20180504074207.22634-1-f...@redhat.com
Switched to a new branch 'test'
c08e6e3a7f tests: Use query-usernet instead of 'info usernet'
c493a69267 slirp: Add "query-usernet" QMP command
5150e445b4 slirp: Use QAPI enum to replace TCPS_* macros
0f3b1a240b qapi: Introduce UsernetTcpState

=== OUTPUT BEGIN ===
Checking PATCH 1/4: qapi: Introduce UsernetTcpState...
Checking PATCH 2/4: slirp: Use QAPI enum to replace TCPS_* macros...
ERROR: code indent should never use tabs
#112: FILE: slirp/tcp_input.c:88:
+^I(tp)->t_state == USERNET_TCP_STATE_ESTABLISHED) { \$

ERROR: code indent should never use tabs
#121: FILE: slirp/tcp_input.c:193:
+^Iif (tp->t_state == USERNET_TCP_STATE_SYN_RECEIVED && ti->ti_len)$

ERROR: code indent should never use tabs
#130: FILE: slirp/tcp_input.c:460:
+^I  tp->t_state = USERNET_TCP_STATE_LISTEN;$

ERROR: code indent should never use tabs
#139: FILE: slirp/tcp_input.c:476:
+^Iif (tp->t_state == USERNET_TCP_STATE_CLOSED)$

ERROR: braces {} are necessary for all arms of this statement
#139: FILE: slirp/tcp_input.c:476:
+   if (tp->t_state == USERNET_TCP_STATE_CLOSED)
[...]

ERROR: code indent should never use tabs
#148: FILE: slirp/tcp_input.c:495:
+^Iif (optp && tp->t_state != USERNET_TCP_STATE_LISTEN)$

ERROR: braces {} are necessary for all arms of this statement
#148: FILE: slirp/tcp_input.c:495:
+   if (optp && tp->t_state != USERNET_TCP_STATE_LISTEN)
[...]

ERROR: code indent should never use tabs
#157: FILE: slirp/tcp_input.c:516:
+^Iif (tp->t_state == USERNET_TCP_STATE_ESTABLISHED &&$

ERROR: code indent should never use tabs
#166: FILE: slirp/tcp_input.c:618:
+^Icase USERNET_TCP_STATE_LISTEN: {$

ERROR: code indent should never use tabs
#175: FILE: slirp/tcp_input.c:729:
+^Itp->t_state = USERNET_TCP_STATE_SYN_RECEIVED;$

ERROR: code indent should never use tabs
#184: FILE: slirp/tcp_input.c:763:
+^I  tp->t_state = USERNET_TCP_STATE_SYN_RECEIVED;$

ERROR: code indent should never use tabs
#188: FILE: slirp/tcp_input.c:766:
+^I} /* case USERNET_TCP_STATE_LISTEN */$

ERROR: code indent should never use tabs
#197: FILE: slirp/tcp_input.c:780:
+^Icase USERNET_TCP_STATE_SYN_SENT:$

ERROR: code indent should never use tabs
#206: FILE: slirp/tcp_input.c:807:
+^I^I^Itp->t_state = USERNET_TCP_STATE_ESTABLISHED;$

ERROR: code indent should never use tabs
#215: FILE: slirp/tcp_input.c:818:
+^I^I^Itp->t_state = USERNET_TCP_STATE_SYN_RECEIVED;$

ERROR: code indent should never use tabs
#224: FILE: slirp/tcp_input.c:888:
+^Itp->t_state > USERNET_TCP_STATE_CLOSE_WAIT && ti->ti_len) {$

ERROR: code indent should never use tabs
#233: FILE: slirp/tcp_input.c:907:
+^I^I^Itp->t_state == USERNET_TCP_STATE_TIME_WAIT &&$

ERROR: code indent should never use tabs
#247: FILE: slirp/tcp_input.c:943:
+^Icase USERNET_TCP_STATE_SYN_RECEIVED:$

ERROR: code indent should never use tabs
#248: FILE: slirp/tcp_input.c:944:
+^Icase USERNET_TCP_STATE_ESTABLISHED:$

ERROR: code indent should never use tabs
#249: FILE: slirp/tcp_input.c:945:
+^Icase USERNET_TCP_STATE_FIN_WAIT_1:$

ERROR: code indent should never use tabs
#250: FILE: slirp/tcp_input.c:946:
+^Icase USERNET_TCP_STATE_FIN_WAIT_2:$

ERROR: code indent should never use tabs
#251: FILE: slirp/tcp_input.c:947:
+^Icase USERNET_TCP_STATE_CLOSE_WAIT:$

ERROR: code indent should never use tabs
#252: FILE: slirp/tcp_input.c:948:
+^I^Itp->t_state = USERNET_TCP_STATE_CLOSED;$

ERROR: code indent should never use tabs
#259: FILE: slirp/tcp_input.c:952:
+^Icase USERNET_TCP_STATE_CLOSING:$

ERROR: code indent should never use tabs
#260: FILE: slirp/tcp_input.c:953:
+^Icase USERNET_TCP_STATE_LAST_ACK:$

ERROR: code indent should never use tabs
#261: FILE: slirp/tcp_input.c:954:
+^Icase USERNET_TCP_STATE_TIME_WAIT:$

ERROR: code indent should never use tabs
#270: FILE: slirp/tcp_input.c:982:
+^Icase USERNET_TCP_STATE_SYN_RECEIVED:$

ERROR: code indent should never use tabs
#276: FILE: slirp/tcp_input.c:987:
+^I^Itp->t_state = USERNET_TCP_STATE_ESTABLISHED;$

ERROR: code indent should never use tabs

Re: [Qemu-devel] [PATCH 08/20] sdcard: Fix sd_crc*() style

2018-05-04 Thread Alistair Francis
On Fri, May 4, 2018 at 9:03 AM Philippe Mathieu-Daudé 
wrote:

> Fix style to keep patchew/checkpatch happy when moving this code
> in the next patch.

> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Alistair Francis 

Alistair

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

> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> index 3708ec1d72..a28ef8de5e 100644
> --- a/hw/sd/sd.c
> +++ b/hw/sd/sd.c
> @@ -243,12 +243,14 @@ static uint8_t sd_crc7(const void *message, size_t
width)
>   uint8_t shift_reg = 0x00;
>   const uint8_t *msg = (const uint8_t *)message;

> -for (i = 0; i < width; i ++, msg ++)
> -for (bit = 7; bit >= 0; bit --) {
> +for (i = 0; i < width; i++, msg++) {
> +for (bit = 7; bit >= 0; bit--) {
>   shift_reg <<= 1;
> -if ((shift_reg >> 7) ^ ((*msg >> bit) & 1))
> +if ((shift_reg >> 7) ^ ((*msg >> bit) & 1)) {
>   shift_reg ^= 0x89;
> +}
>   }
> +}

>   return shift_reg;
>   }
> @@ -260,12 +262,14 @@ static uint16_t sd_crc16(const void *message,
size_t width)
>   const uint16_t *msg = (const uint16_t *)message;
>   width <<= 1;

> -for (i = 0; i < width; i ++, msg ++)
> -for (bit = 15; bit >= 0; bit --) {
> +for (i = 0; i < width; i++, msg++) {
> +for (bit = 15; bit >= 0; bit--) {
>   shift_reg <<= 1;
> -if ((shift_reg >> 15) ^ ((*msg >> bit) & 1))
> +if ((shift_reg >> 15) ^ ((*msg >> bit) & 1)) {
>   shift_reg ^= 0x1011;
> +}
>   }
> +}

>   return shift_reg;
>   }
> --
> 2.17.0



Re: [Qemu-devel] [PATCH 06/20] sdcard: Add a "validate-crc" property

2018-05-04 Thread Alistair Francis
On Fri, May 4, 2018 at 9:00 AM Philippe Mathieu-Daudé 
wrote:

> Since not all modelled controllers use the CRC verification (which is
> somehow expensive), let the controller have a configurable property
> to enable verification.

> So far only the Milkymist controller uses it.

> This silent the Coverity warning:

>"Code block is unreachable because of the syntactic structure of the
code (CWE-561)"

> and fixes the following issue:

> - CID1005332 (hw/sd/sd.c::sd_req_crc_validate) Structurally dead code

> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Alistair Francis 

Alistair

> ---
>   hw/sd/milkymist-memcard.c |  1 +
>   hw/sd/sd.c| 12 
>   2 files changed, 9 insertions(+), 4 deletions(-)

> diff --git a/hw/sd/milkymist-memcard.c b/hw/sd/milkymist-memcard.c
> index d8cbb7b681..04babc092f 100644
> --- a/hw/sd/milkymist-memcard.c
> +++ b/hw/sd/milkymist-memcard.c
> @@ -278,6 +278,7 @@ static void milkymist_memcard_realize(DeviceState
*dev, Error **errp)
>   blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL;
>   carddev = qdev_create(>sdbus.qbus, TYPE_SD_CARD);
>   qdev_prop_set_drive(carddev, "drive", blk, );
> +object_property_set_bool(OBJECT(carddev), true, "validate-crc",
);
>   object_property_set_bool(OBJECT(carddev), true, "realized", );
>   if (err) {
>   error_setg(errp, "failed to init SD card: %s",
error_get_pretty(err));
> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> index be75e118c0..801ddc2cb5 100644
> --- a/hw/sd/sd.c
> +++ b/hw/sd/sd.c
> @@ -93,6 +93,7 @@ struct SDState {
>   /* Configurable properties */
>   BlockBackend *blk;
>   bool spi;
> +bool validate_crc;

>   uint32_t mode;/* current card mode, one of SDCardModes */
>   int32_t state;/* current card state, one of SDCardStates */
> @@ -496,10 +497,12 @@ static bool sd_verify_frame48_checksum(SDFrame48
*frame)
>   return crc == frame->crc;
>   }

> -static int sd_req_crc_validate(SDRequest *req)
> +static bool sd_req_crc_validate(SDState *sd, SDRequest *req)
>   {
> -return 0;
> -return !sd_verify_frame48_checksum(req); /* TODO */
> +if (sd->validate_crc) {
> +return sd_verify_frame48_checksum(req);
> +}
> +return true;
>   }

>   static void sd_update_frame48_checksum(SDFrame48 *frame)
> @@ -1685,7 +1688,7 @@ int sd_do_command(SDState *sd, SDRequest *req,
>   return 0;
>   }

> -if (sd_req_crc_validate(req)) {
> +if (!sd_req_crc_validate(sd, req)) {
>   sd->card_status |= COM_CRC_ERROR;
>   rtype = sd_illegal;
>   goto send_response;
> @@ -2134,6 +2137,7 @@ static Property sd_properties[] = {
>* board to ensure that ssi transfers only occur when the chip select
>* is asserted.  */
>   DEFINE_PROP_BOOL("spi", SDState, spi, false),
> +DEFINE_PROP_BOOL("validate-crc", SDState, validate_crc, false),
>   DEFINE_PROP_END_OF_LIST()
>   };

> --
> 2.17.0



Re: [Qemu-devel] [PATCH v1 1/4] hw/riscv/sifive_u: Create a U54 SoC object

2018-05-04 Thread Michael Clark
On Sat, May 5, 2018 at 8:12 AM, Alistair Francis 
wrote:

> Create a SiFive Unleashed U54 SoC and use that in the sifive_u machine.
>
> We leave the SoC, RAM, device tree and reset/fdt loading as part of the
> machine. All the other device creation has been moved to the SoC.
>

There is a tiny problem that we will have to resolve with renaming,
otherwise we will end up with lots of SOCs that are the essentially same
with a different CPU.

There is an intention to add a HiFive1 and HiFiveU board in the future
however we were very explicit in renaming sifive_e300 and sifive_u500 to
sifive_e and sifive_u.

If you read the code more closely you'll notice that we instantiate the
sifive_u board with a U34 if 32-bit and a U54 if 64-bit.

#if defined(TARGET_RISCV32)
#define SIFIVE_U_CPU TYPE_RISCV_CPU_SIFIVE_U34
#elif defined(TARGET_RISCV64)
#define SIFIVE_U_CPU TYPE_RISCV_CPU_SIFIVE_U54
#endif

The rationale is that sifive_e and sifive_u can eventually be customized to
represent different configurations of SiFive Core IP. We won't want to end
up hardcoding specific models in sifive_e or sifive_u

SiFive have been talking internally about having sifive_e and sifive_u
reconfigurable, possibly even to the extend where we can configure with a
memory map. This is somewhat consistent with what SiFive do internally as
the FE310 and FU540 are configurations generated by a core generator.

Now comes the question of whether its the right time to add a 'hifive1' or
'hifiveu' machine. I don't think it is immediately necessary. The thought
being that we would be able to give a configuration string of file to sifive_u
e.g. "e51,u54,u54,u54". There is a different between the U54 and the U54-MC
which has an E51 core for management tasks. The PLIC has already been
written with this in mind, and is re-configurable to support the U54-MC
memory layout.

In anycase. The change is simply to use sifive_u_soc or sifive_u without
the 54 (given it configures with a U34 in 32-bit like the sifive_e
configures with an E51 in 64-bit mode, both valid configurations)

Signed-off-by: Alistair Francis 
> ---
>  hw/riscv/sifive_u.c | 90 -
>  include/hw/riscv/sifive_u.h | 16 ++-
>  2 files changed, 82 insertions(+), 24 deletions(-)
>
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index 9f3d184b72..4924f92262 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -114,10 +114,10 @@ static void create_fdt(SiFiveUState *s, const struct
> MemmapEntry *memmap,
>  qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0);
>  qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1);
>
> -for (cpu = s->soc.num_harts - 1; cpu >= 0; cpu--) {
> +for (cpu = s->soc.cpus.num_harts - 1; cpu >= 0; cpu--) {
>  nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
>  char *intc = g_strdup_printf("/cpus/cpu@%d/interrupt-controller",
> cpu);
> -char *isa = riscv_isa_string(>soc.harts[cpu]);
> +char *isa = riscv_isa_string(>soc.cpus.harts[cpu]);
>  qemu_fdt_add_subnode(fdt, nodename);
>  qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
>SIFIVE_U_CLOCK_FREQ);
> @@ -138,8 +138,8 @@ static void create_fdt(SiFiveUState *s, const struct
> MemmapEntry *memmap,
>  g_free(nodename);
>  }
>
> -cells =  g_new0(uint32_t, s->soc.num_harts * 4);
> -for (cpu = 0; cpu < s->soc.num_harts; cpu++) {
> +cells =  g_new0(uint32_t, s->soc.cpus.num_harts * 4);
> +for (cpu = 0; cpu < s->soc.cpus.num_harts; cpu++) {
>  nodename =
>  g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
>  uint32_t intc_phandle = qemu_fdt_get_phandle(fdt, nodename);
> @@ -157,12 +157,12 @@ static void create_fdt(SiFiveUState *s, const struct
> MemmapEntry *memmap,
>  0x0, memmap[SIFIVE_U_CLINT].base,
>  0x0, memmap[SIFIVE_U_CLINT].size);
>  qemu_fdt_setprop(fdt, nodename, "interrupts-extended",
> -cells, s->soc.num_harts * sizeof(uint32_t) * 4);
> +cells, s->soc.cpus.num_harts * sizeof(uint32_t) * 4);
>  g_free(cells);
>  g_free(nodename);
>
> -cells =  g_new0(uint32_t, s->soc.num_harts * 4);
> -for (cpu = 0; cpu < s->soc.num_harts; cpu++) {
> +cells =  g_new0(uint32_t, s->soc.cpus.num_harts * 4);
> +for (cpu = 0; cpu < s->soc.cpus.num_harts; cpu++) {
>  nodename =
>  g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
>  uint32_t intc_phandle = qemu_fdt_get_phandle(fdt, nodename);
> @@ -179,7 +179,7 @@ static void create_fdt(SiFiveUState *s, const struct
> MemmapEntry *memmap,
>  qemu_fdt_setprop_string(fdt, nodename, "compatible", "riscv,plic0");
>  qemu_fdt_setprop(fdt, nodename, "interrupt-controller", NULL, 0);
>  qemu_fdt_setprop(fdt, nodename, "interrupts-extended",
> -cells, s->soc.num_harts * sizeof(uint32_t) 

[Qemu-devel] [PATCH v3 08/10] target/arm: Fill in disas_ldst_atomic

2018-05-04 Thread Richard Henderson
This implements all of the v8.1-Atomics instructions except
for compare-and-swap, which is decoded elsewhere.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
v3: Do not zero-extend X[s] via the third parameter to read_cpu_reg.

---
 target/arm/translate-a64.c | 38 --
 1 file changed, 36 insertions(+), 2 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 6acad791e6..c13858a690 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -84,6 +84,7 @@ typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
 typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
 typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
 typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
+typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, TCGMemOp);
 
 /* Note that the gvec expanders operate on offsets + sizes.  */
 typedef void GVecGen2Fn(unsigned, uint32_t, uint32_t, uint32_t, uint32_t);
@@ -2772,6 +2773,8 @@ static void disas_ldst_atomic(DisasContext *s, uint32_t 
insn,
 int rn = extract32(insn, 5, 5);
 int o3_opc = extract32(insn, 12, 4);
 int feature = ARM_FEATURE_V8_ATOMICS;
+TCGv_i64 tcg_rn, tcg_rs;
+AtomicThreeOpFn *fn;
 
 if (is_vector) {
 unallocated_encoding(s);
@@ -2779,14 +2782,32 @@ static void disas_ldst_atomic(DisasContext *s, uint32_t 
insn,
 }
 switch (o3_opc) {
 case 000: /* LDADD */
+fn = tcg_gen_atomic_fetch_add_i64;
+break;
 case 001: /* LDCLR */
+fn = tcg_gen_atomic_fetch_and_i64;
+break;
 case 002: /* LDEOR */
+fn = tcg_gen_atomic_fetch_xor_i64;
+break;
 case 003: /* LDSET */
+fn = tcg_gen_atomic_fetch_or_i64;
+break;
 case 004: /* LDSMAX */
+fn = tcg_gen_atomic_fetch_smax_i64;
+break;
 case 005: /* LDSMIN */
+fn = tcg_gen_atomic_fetch_smin_i64;
+break;
 case 006: /* LDUMAX */
+fn = tcg_gen_atomic_fetch_umax_i64;
+break;
 case 007: /* LDUMIN */
+fn = tcg_gen_atomic_fetch_umin_i64;
+break;
 case 010: /* SWP */
+fn = tcg_gen_atomic_xchg_i64;
+break;
 default:
 unallocated_encoding(s);
 return;
@@ -2796,8 +2817,21 @@ static void disas_ldst_atomic(DisasContext *s, uint32_t 
insn,
 return;
 }
 
-(void)rs;
-(void)rn;
+if (rn == 31) {
+gen_check_sp_alignment(s);
+}
+tcg_rn = cpu_reg_sp(s, rn);
+tcg_rs = read_cpu_reg(s, rs, true);
+
+if (o3_opc == 1) { /* LDCLR */
+tcg_gen_not_i64(tcg_rs, tcg_rs);
+}
+
+/* The tcg atomic primitives are all full barriers.  Therefore we
+ * can ignore the Acquire and Release bits of this instruction.
+ */
+fn(cpu_reg(s, rt), tcg_rn, tcg_rs, get_mem_index(s),
+   s->be_data | size | MO_ALIGN);
 }
 
 /* Load/store register (all forms) */
-- 
2.14.3




Re: [Qemu-devel] [PATCH 0/3] Document intent for supported build platforms and bump min glib to 2.42

2018-05-04 Thread Paolo Bonzini
On 04/05/2018 18:00, Daniel P. Berrangé wrote:
> Based on that doc and https://repology.org/metapackage/glib/versions,
> I identified that we could feasibly set min glib to 2.42. Note that
> this would be dropping RHEL-6 as a build host (RHEL-6.0 came out in
> 2010 so that's reasonable to drop IMHO). It would still cover 2 major
> Debian versions and 2 most recent Ubuntu LTS (16.04, 18.04, but *not*
> 14.04). This min glib lets us remove almost all our compat code.

Queued after adding to patch 3 the removal of CentOS 6 and min-glib
Dockerfiles.

Paolo



Re: [Qemu-devel] [PATCH v2 0/5] Removal of deprecated -no-kvm* options

2018-05-04 Thread Paolo Bonzini
On 04/05/2018 19:01, Thomas Huth wrote:
> The -no-kvm* options are a remainder of the ancient "qemu-kvm"
> fork. They have never been officially documented in our qemu-doc,
> they have been marked as deprecated in the sources since a very
> long time, and we've marked them as deprecated in our qemu-doc
> since QEMU v2.10. So far I haven't seen any complaints that we
> should keep them, so it's time to remove these old parameters now.
> 
> While I'm at it, this patch series also removes a left-over from
> the "-tdf" option (which has been removed with QEMU v2.12) and
> fixes a deficiency in the option parsing code that has been
> revealed by the remainder of the "-tdf" option.
> 
> Thomas Huth (5):
>   qemu-options: Remove remainders of the -tdf option
>   qemu-options: Bail out on unsupported options instead of silently
> ignoring them
>   qemu-options: Remove deprecated -no-kvm-pit-reinjection
>   qemu-options: Remove deprecated -no-kvm-irqchip
>   qemu-options: Remove deprecated -no-kvm

I'm not that sure anymore about -no-kvm.  It can come in handy for
distros (*cough* RHEL *cough) that only ship a qemu-kvm binary with
default accelerator "-machine accel=kvm:tcg".

Yeah, "-accel tcg" is only a few characters later, but it is a
relatively recent addition.

Paolo



Re: [Qemu-devel] [PATCH v2 0/5] Removal of deprecated -no-kvm* options

2018-05-04 Thread Paolo Bonzini
On 04/05/2018 19:01, Thomas Huth wrote:
> The -no-kvm* options are a remainder of the ancient "qemu-kvm"
> fork. They have never been officially documented in our qemu-doc,
> they have been marked as deprecated in the sources since a very
> long time, and we've marked them as deprecated in our qemu-doc
> since QEMU v2.10. So far I haven't seen any complaints that we
> should keep them, so it's time to remove these old parameters now.
> 
> While I'm at it, this patch series also removes a left-over from
> the "-tdf" option (which has been removed with QEMU v2.12) and
> fixes a deficiency in the option parsing code that has been
> revealed by the remainder of the "-tdf" option.
> 
> Thomas Huth (5):
>   qemu-options: Remove remainders of the -tdf option
>   qemu-options: Bail out on unsupported options instead of silently
> ignoring them
>   qemu-options: Remove deprecated -no-kvm-pit-reinjection
>   qemu-options: Remove deprecated -no-kvm-irqchip
>   qemu-options: Remove deprecated -no-kvm
> 
>  include/qemu-common.h |  2 +-
>  os-posix.c|  6 +-
>  os-win32.c|  4 ++--
>  qemu-doc.texi | 15 ---
>  qemu-options.hx   | 13 -
>  vl.c  | 26 --
>  6 files changed, 12 insertions(+), 54 deletions(-)
> 

Queued patches 1-4 waiting for more discussion, thanks.

Paolo



Re: [Qemu-devel] [PATCH v2] qemu-options: Mark -virtioconsole as deprecated

2018-05-04 Thread Paolo Bonzini
On 04/05/2018 17:13, Thomas Huth wrote:
> The qemu-doc already states that this option is only maintained for
> backward compatibility and "-device virtconsole" should be used
> instead. So let's take the next step and mark this option officially
> as deprecated.
> 
> Reviewed-by: Markus Armbruster 
> Signed-off-by: Thomas Huth 
> ---
>  v2:
>  - Addressed Markus' review feedback from v1
> 
>  qemu-doc.texi   | 5 +
>  qemu-options.hx | 5 +
>  vl.c| 2 ++
>  3 files changed, 8 insertions(+), 4 deletions(-)
> 
> diff --git a/qemu-doc.texi b/qemu-doc.texi
> index 0ed0f19..4add403 100644
> --- a/qemu-doc.texi
> +++ b/qemu-doc.texi
> @@ -2931,6 +2931,11 @@ The @code{-localtime} option has been replaced by 
> @code{-rtc base=localtime}.
>  
>  The @code{-startdate} option has been replaced by @code{-rtc 
> base=@var{date}}.
>  
> +@subsection -virtioconsole (since 2.13.0)
> +
> +Option @option{-virtioconsole} has been replaced by
> +@option{-device virtconsole}.
> +
>  @section qemu-img command line arguments
>  
>  @subsection convert -s (since 2.0.0)
> diff --git a/qemu-options.hx b/qemu-options.hx
> index c611766..091ded6 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -3675,10 +3675,7 @@ STEXI
>  @item -virtioconsole @var{c}
>  @findex -virtioconsole
>  Set virtio console.
> -
> -This option is maintained for backward compatibility.
> -
> -Please use @code{-device virtconsole} for the new way of invocation.
> +This option is deprecated, please use @option{-device virtconsole} instead.
>  ETEXI
>  
>  DEF("show-cursor", 0, QEMU_OPTION_show_cursor, \
> diff --git a/vl.c b/vl.c
> index 806eec2..519e54f 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -3598,6 +3598,8 @@ int main(int argc, char **argv, char **envp)
>  }
>  break;
>  case QEMU_OPTION_virtiocon:
> +warn_report("This option is deprecated, "
> +"use '-device virtconsole' instead");
>  add_device_config(DEV_VIRTCON, optarg);
>  default_virtcon = 0;
>  if (strncmp(optarg, "mon:", 4) == 0) {
> 

Queued, thanks.

Paolo



[Qemu-devel] [PATCH v1 3/4] hw/riscv/sifive_u: Connect the Cadence GEM Ethernet device

2018-05-04 Thread Alistair Francis
Connect the Cadence GEM ethernet device. This also requires us to
expose the plic interrupt lines.

Signed-off-by: Alistair Francis 
---
 default-configs/riscv32-softmmu.mak |  1 +
 default-configs/riscv64-softmmu.mak |  1 +
 hw/riscv/sifive_u.c | 29 +
 include/hw/riscv/sifive_u.h |  6 +-
 4 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/default-configs/riscv32-softmmu.mak 
b/default-configs/riscv32-softmmu.mak
index f9e742120c..9a1c42e8b2 100644
--- a/default-configs/riscv32-softmmu.mak
+++ b/default-configs/riscv32-softmmu.mak
@@ -2,3 +2,4 @@
 
 CONFIG_SERIAL=y
 CONFIG_VIRTIO=y
+CONFIG_CADENCE=y
diff --git a/default-configs/riscv64-softmmu.mak 
b/default-configs/riscv64-softmmu.mak
index f9e742120c..9a1c42e8b2 100644
--- a/default-configs/riscv64-softmmu.mak
+++ b/default-configs/riscv64-softmmu.mak
@@ -2,3 +2,4 @@
 
 CONFIG_SERIAL=y
 CONFIG_VIRTIO=y
+CONFIG_CADENCE=y
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 4924f92262..e4c7539b89 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -58,8 +58,11 @@ static const struct MemmapEntry {
 [SIFIVE_U_UART0] ={ 0x10013000, 0x1000 },
 [SIFIVE_U_UART1] ={ 0x10023000, 0x1000 },
 [SIFIVE_U_DRAM] = { 0x8000,0x0 },
+[SIFIVE_U_GEM] =  { 0x100900FC, 0x1000 },
 };
 
+#define GEM_REVISION0x10070109
+
 static uint64_t load_kernel(const char *kernel_filename)
 {
 uint64_t kernel_entry, kernel_high;
@@ -294,6 +297,9 @@ static void riscv_sifive_u54_init(Object *obj)
memmap[SIFIVE_U_MROM].size, _fatal);
 memory_region_add_subregion(system_memory, memmap[SIFIVE_U_MROM].base,
 mask_rom);
+
+object_initialize(>gem, sizeof(s->gem), TYPE_CADENCE_GEM);
+qdev_set_parent_bus(DEVICE(>gem), sysbus_get_default());
 }
 
 static void riscv_sifive_u54_realize(DeviceState *dev, Error **errp)
@@ -301,6 +307,10 @@ static void riscv_sifive_u54_realize(DeviceState *dev, 
Error **errp)
 SiFiveU54State *s = RISCV_U54_SOC(dev);
 const struct MemmapEntry *memmap = sifive_u_memmap;
 MemoryRegion *system_memory = get_system_memory();
+qemu_irq plic_gpios[SIFIVE_U_PLIC_NUM_SOURCES];
+int i;
+Error *err = NULL;
+NICInfo *nd = _table[0];
 
 object_property_set_bool(OBJECT(>cpus), true, "realized",
  _abort);
@@ -324,6 +334,25 @@ static void riscv_sifive_u54_realize(DeviceState *dev, 
Error **errp)
 sifive_clint_create(memmap[SIFIVE_U_CLINT].base,
 memmap[SIFIVE_U_CLINT].size, smp_cpus,
 SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE);
+
+for (i = 0; i < SIFIVE_U_PLIC_NUM_SOURCES; i++) {
+plic_gpios[i] = qdev_get_gpio_in(DEVICE(s->plic), i);
+}
+
+if (nd->used) {
+qemu_check_nic_model(nd, TYPE_CADENCE_GEM);
+qdev_set_nic_properties(DEVICE(>gem), nd);
+}
+object_property_set_int(OBJECT(>gem), GEM_REVISION, "revision",
+_abort);
+object_property_set_bool(OBJECT(>gem), true, "realized", );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(>gem), 0, memmap[SIFIVE_U_GEM].base);
+sysbus_connect_irq(SYS_BUS_DEVICE(>gem), 0,
+   plic_gpios[53]);
 }
 
 static void riscv_sifive_u_machine_init(MachineClass *mc)
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index 0f8bdd8fab..d40d851999 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -19,6 +19,8 @@
 #ifndef HW_SIFIVE_U_H
 #define HW_SIFIVE_U_H
 
+#include "hw/net/cadence_gem.h"
+
 #define TYPE_RISCV_U54_SOC "riscv.sifive.u54"
 #define RISCV_U54_SOC(obj) \
 OBJECT_CHECK(SiFiveU54State, (obj), TYPE_RISCV_U54_SOC)
@@ -30,6 +32,7 @@ typedef struct SiFiveU54State {
 /*< public >*/
 RISCVHartArrayState cpus;
 DeviceState *plic;
+CadenceGEMState gem;
 } SiFiveU54State;
 
 typedef struct SiFiveUState {
@@ -49,7 +52,8 @@ enum {
 SIFIVE_U_PLIC,
 SIFIVE_U_UART0,
 SIFIVE_U_UART1,
-SIFIVE_U_DRAM
+SIFIVE_U_DRAM,
+SIFIVE_U_GEM
 };
 
 enum {
-- 
2.17.0




[Qemu-devel] [PATCH v1 4/4] hw/riscv/sifive_e: Create a E31 SoC object

2018-05-04 Thread Alistair Francis
Signed-off-by: Alistair Francis 
---
 hw/riscv/sifive_e.c | 97 +++--
 include/hw/riscv/sifive_e.h | 16 +-
 2 files changed, 86 insertions(+), 27 deletions(-)

diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
index e4ecb7aa4b..0ab5e3ca45 100644
--- a/hw/riscv/sifive_e.c
+++ b/hw/riscv/sifive_e.c
@@ -102,18 +102,12 @@ static void riscv_sifive_e_init(MachineState *machine)
 SiFiveEState *s = g_new0(SiFiveEState, 1);
 MemoryRegion *sys_mem = get_system_memory();
 MemoryRegion *main_mem = g_new(MemoryRegion, 1);
-MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
-MemoryRegion *xip_mem = g_new(MemoryRegion, 1);
 int i;
 
-/* Initialize SOC */
-object_initialize(>soc, sizeof(s->soc), TYPE_RISCV_HART_ARRAY);
+/* Initialize SoC */
+object_initialize(>soc, sizeof(s->soc), TYPE_RISCV_E31_SOC);
 object_property_add_child(OBJECT(machine), "soc", OBJECT(>soc),
   _abort);
-object_property_set_str(OBJECT(>soc), SIFIVE_E_CPU, "cpu-type",
-_abort);
-object_property_set_int(OBJECT(>soc), smp_cpus, "num-harts",
-_abort);
 object_property_set_bool(OBJECT(>soc), true, "realized",
 _abort);
 
@@ -123,11 +117,57 @@ static void riscv_sifive_e_init(MachineState *machine)
 memory_region_add_subregion(sys_mem,
 memmap[SIFIVE_E_DTIM].base, main_mem);
 
+/* Mask ROM reset vector */
+uint32_t reset_vec[2] = {
+0x204002b7,/* 0x1000: lui t0,0x20400 */
+0x00028067,/* 0x1004: jr  t0 */
+};
+
+/* copy in the reset vector in little_endian byte order */
+for (i = 0; i < sizeof(reset_vec) >> 2; i++) {
+reset_vec[i] = cpu_to_le32(reset_vec[i]);
+}
+rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec),
+  memmap[SIFIVE_E_MROM].base, _space_memory);
+
+if (machine->kernel_filename) {
+load_kernel(machine->kernel_filename);
+}
+}
+
+static void riscv_sifive_e31_init(Object *obj)
+{
+const struct MemmapEntry *memmap = sifive_e_memmap;
+
+SiFiveE31State *s = RISCV_E31_SOC(obj);
+MemoryRegion *sys_mem = get_system_memory();
+MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
+
+object_initialize(>cpus, sizeof(s->cpus), TYPE_RISCV_HART_ARRAY);
+object_property_add_child(obj, "cpus", OBJECT(>cpus),
+  _abort);
+object_property_set_str(OBJECT(>cpus), SIFIVE_E_CPU, "cpu-type",
+_abort);
+object_property_set_int(OBJECT(>cpus), smp_cpus, "num-harts",
+_abort);
+
 /* Mask ROM */
 memory_region_init_rom(mask_rom, NULL, "riscv.sifive.e.mrom",
 memmap[SIFIVE_E_MROM].size, _fatal);
 memory_region_add_subregion(sys_mem,
 memmap[SIFIVE_E_MROM].base, mask_rom);
+}
+
+static void riscv_sifive_e31_realize(DeviceState *dev, Error **errp)
+{
+const struct MemmapEntry *memmap = sifive_e_memmap;
+
+SiFiveE31State *s = RISCV_E31_SOC(dev);
+MemoryRegion *sys_mem = get_system_memory();
+MemoryRegion *xip_mem = g_new(MemoryRegion, 1);
+
+object_property_set_bool(OBJECT(>cpus), true, "realized",
+_abort);
 
 /* MMIO */
 s->plic = sifive_plic_create(memmap[SIFIVE_E_PLIC].base,
@@ -171,23 +211,6 @@ static void riscv_sifive_e_init(MachineState *machine)
 memmap[SIFIVE_E_XIP].size, _fatal);
 memory_region_set_readonly(xip_mem, true);
 memory_region_add_subregion(sys_mem, memmap[SIFIVE_E_XIP].base, xip_mem);
-
-/* Mask ROM reset vector */
-uint32_t reset_vec[2] = {
-0x204002b7,/* 0x1000: lui t0,0x20400 */
-0x00028067,/* 0x1004: jr  t0 */
-};
-
-/* copy in the reset vector in little_endian byte order */
-for (i = 0; i < sizeof(reset_vec) >> 2; i++) {
-reset_vec[i] = cpu_to_le32(reset_vec[i]);
-}
-rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec),
-  memmap[SIFIVE_E_MROM].base, _space_memory);
-
-if (machine->kernel_filename) {
-load_kernel(machine->kernel_filename);
-}
 }
 
 static void riscv_sifive_e_machine_init(MachineClass *mc)
@@ -198,3 +221,27 @@ static void riscv_sifive_e_machine_init(MachineClass *mc)
 }
 
 DEFINE_MACHINE("sifive_e", riscv_sifive_e_machine_init)
+
+static void riscv_sifive_e31_class_init(ObjectClass *oc, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(oc);
+
+dc->realize = riscv_sifive_e31_realize;
+/* Reason: Uses serial_hds in realize function, thus can't be used twice */
+dc->user_creatable = false;
+}
+
+static const TypeInfo riscv_sifive_e31_type_info = {
+.name = TYPE_RISCV_E31_SOC,
+.parent = TYPE_DEVICE,
+.instance_size = sizeof(SiFiveE31State),
+.instance_init = riscv_sifive_e31_init,
+.class_init 

[Qemu-devel] [PATCH v1 0/4] RISC-V: SoCify the SiFive boards and connect the

2018-05-04 Thread Alistair Francis
This series has two tasks:
 1. To conver the SiFive U and E machines into SoCs and boards
 2. To connect the Cadence GEM device to teh SiFive U board

After this series the SiFive E and U boards have their SoCs split into
seperate QEMU objects, which can be used on future boards if desired.

The RISC-V Virt and Spike boards have not been converted. They haven't
been converted as they aren't physical boards, so it doesn't make a
whole lot of sense to split them into an SoC and board. The only
disadvantage with this is that they now differ to the SiFive boards.

This series also connect the Cadence GEM device to the SiFive U board.
There are some interrupt line changes requried before this is possible.

Based-on: <1524699938-6764-1-git-send-email-...@sifive.com>

Alistair Francis (4):
  hw/riscv/sifive_u: Create a U54 SoC object
  hw/riscv/sifive_plic: Use gpios instead of irqs
  hw/riscv/sifive_u: Connect the Cadence GEM Ethernet device
  hw/riscv/sifive_e: Create a E31 SoC object

 default-configs/riscv32-softmmu.mak |   1 +
 default-configs/riscv64-softmmu.mak |   1 +
 hw/riscv/sifive_e.c |  97 +--
 hw/riscv/sifive_plic.c  |   5 +-
 hw/riscv/sifive_u.c | 119 +++-
 include/hw/riscv/sifive_e.h |  16 +++-
 include/hw/riscv/sifive_u.h |  22 -
 7 files changed, 205 insertions(+), 56 deletions(-)

-- 
2.17.0




[Qemu-devel] [PATCH v1 1/4] hw/riscv/sifive_u: Create a U54 SoC object

2018-05-04 Thread Alistair Francis
Create a SiFive Unleashed U54 SoC and use that in the sifive_u machine.

We leave the SoC, RAM, device tree and reset/fdt loading as part of the
machine. All the other device creation has been moved to the SoC.

Signed-off-by: Alistair Francis 
---
 hw/riscv/sifive_u.c | 90 -
 include/hw/riscv/sifive_u.h | 16 ++-
 2 files changed, 82 insertions(+), 24 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 9f3d184b72..4924f92262 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -114,10 +114,10 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0);
 qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1);
 
-for (cpu = s->soc.num_harts - 1; cpu >= 0; cpu--) {
+for (cpu = s->soc.cpus.num_harts - 1; cpu >= 0; cpu--) {
 nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
 char *intc = g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
-char *isa = riscv_isa_string(>soc.harts[cpu]);
+char *isa = riscv_isa_string(>soc.cpus.harts[cpu]);
 qemu_fdt_add_subnode(fdt, nodename);
 qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
   SIFIVE_U_CLOCK_FREQ);
@@ -138,8 +138,8 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 g_free(nodename);
 }
 
-cells =  g_new0(uint32_t, s->soc.num_harts * 4);
-for (cpu = 0; cpu < s->soc.num_harts; cpu++) {
+cells =  g_new0(uint32_t, s->soc.cpus.num_harts * 4);
+for (cpu = 0; cpu < s->soc.cpus.num_harts; cpu++) {
 nodename =
 g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
 uint32_t intc_phandle = qemu_fdt_get_phandle(fdt, nodename);
@@ -157,12 +157,12 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 0x0, memmap[SIFIVE_U_CLINT].base,
 0x0, memmap[SIFIVE_U_CLINT].size);
 qemu_fdt_setprop(fdt, nodename, "interrupts-extended",
-cells, s->soc.num_harts * sizeof(uint32_t) * 4);
+cells, s->soc.cpus.num_harts * sizeof(uint32_t) * 4);
 g_free(cells);
 g_free(nodename);
 
-cells =  g_new0(uint32_t, s->soc.num_harts * 4);
-for (cpu = 0; cpu < s->soc.num_harts; cpu++) {
+cells =  g_new0(uint32_t, s->soc.cpus.num_harts * 4);
+for (cpu = 0; cpu < s->soc.cpus.num_harts; cpu++) {
 nodename =
 g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
 uint32_t intc_phandle = qemu_fdt_get_phandle(fdt, nodename);
@@ -179,7 +179,7 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_string(fdt, nodename, "compatible", "riscv,plic0");
 qemu_fdt_setprop(fdt, nodename, "interrupt-controller", NULL, 0);
 qemu_fdt_setprop(fdt, nodename, "interrupts-extended",
-cells, s->soc.num_harts * sizeof(uint32_t) * 4);
+cells, s->soc.cpus.num_harts * sizeof(uint32_t) * 4);
 qemu_fdt_setprop_cells(fdt, nodename, "reg",
 0x0, memmap[SIFIVE_U_PLIC].base,
 0x0, memmap[SIFIVE_U_PLIC].size);
@@ -215,17 +215,12 @@ static void riscv_sifive_u_init(MachineState *machine)
 SiFiveUState *s = g_new0(SiFiveUState, 1);
 MemoryRegion *system_memory = get_system_memory();
 MemoryRegion *main_mem = g_new(MemoryRegion, 1);
-MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
 int i;
 
-/* Initialize SOC */
-object_initialize(>soc, sizeof(s->soc), TYPE_RISCV_HART_ARRAY);
+/* Initialize SoC */
+object_initialize(>soc, sizeof(s->soc), TYPE_RISCV_U54_SOC);
 object_property_add_child(OBJECT(machine), "soc", OBJECT(>soc),
   _abort);
-object_property_set_str(OBJECT(>soc), SIFIVE_U_CPU, "cpu-type",
-_abort);
-object_property_set_int(OBJECT(>soc), smp_cpus, "num-harts",
-_abort);
 object_property_set_bool(OBJECT(>soc), true, "realized",
 _abort);
 
@@ -233,17 +228,11 @@ static void riscv_sifive_u_init(MachineState *machine)
 memory_region_init_ram(main_mem, NULL, "riscv.sifive.u.ram",
machine->ram_size, _fatal);
 memory_region_add_subregion(system_memory, memmap[SIFIVE_U_DRAM].base,
-main_mem);
+main_mem);
 
 /* create device tree */
 create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
 
-/* boot rom */
-memory_region_init_rom(mask_rom, NULL, "riscv.sifive.u.mrom",
-   memmap[SIFIVE_U_MROM].size, _fatal);
-memory_region_add_subregion(system_memory, memmap[SIFIVE_U_MROM].base,
-mask_rom);
-
 if (machine->kernel_filename) {
 load_kernel(machine->kernel_filename);
 }
@@ -282,6 +271,39 @@ static void 

[Qemu-devel] [PATCH v1 2/4] hw/riscv/sifive_plic: Use gpios instead of irqs

2018-05-04 Thread Alistair Francis
Instead of creating the interrupt in lines with qemu_allocate_irq() use
qdev_init_gpio_in() as this gives us the ability to use the qdev*gpio*()
helpers later on.

Signed-off-by: Alistair Francis 
---
 hw/riscv/sifive_plic.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/hw/riscv/sifive_plic.c b/hw/riscv/sifive_plic.c
index a4ac910ca9..81b6b5245b 100644
--- a/hw/riscv/sifive_plic.c
+++ b/hw/riscv/sifive_plic.c
@@ -431,7 +431,6 @@ static void sifive_plic_irq_request(void *opaque, int irq, 
int level)
 static void sifive_plic_realize(DeviceState *dev, Error **errp)
 {
 SiFivePLICState *plic = SIFIVE_PLIC(dev);
-int i;
 
 memory_region_init_io(>mmio, OBJECT(dev), _plic_ops, plic,
   TYPE_SIFIVE_PLIC, plic->aperture_size);
@@ -444,9 +443,7 @@ static void sifive_plic_realize(DeviceState *dev, Error 
**errp)
 plic->enable = g_new0(uint32_t, plic->bitfield_words * plic->num_addrs);
 sysbus_init_mmio(SYS_BUS_DEVICE(dev), >mmio);
 plic->irqs = g_new0(qemu_irq, plic->num_sources + 1);
-for (i = 0; i <= plic->num_sources; i++) {
-plic->irqs[i] = qemu_allocate_irq(sifive_plic_irq_request, plic, i);
-}
+qdev_init_gpio_in(dev, sifive_plic_irq_request, plic->num_sources);
 }
 
 static void sifive_plic_class_init(ObjectClass *klass, void *data)
-- 
2.17.0




Re: [Qemu-devel] cover letter cc's [was: [PATCH 60/67] hw/s390x: add include directory headers]

2018-05-04 Thread Michael S. Tsirkin
On Fri, May 04, 2018 at 08:07:53AM -0500, Eric Blake wrote:
> [adding a cross-post to the git mailing list]
> 
> On 05/04/2018 02:10 AM, Cornelia Huck wrote:
> > On Thu, 3 May 2018 22:51:40 +0300
> > "Michael S. Tsirkin"  wrote:
> > 
> > > This way they are easier to find using standard rules.
> > > 
> > > Signed-off-by: Michael S. Tsirkin 
> > > ---
> ...
> 
> > [Goes to find cover letter to figure out what this is all about.
> > *Please*, cc: people on the cover letter so they can see immediately
> > what this is trying to do!]
> 
> Is there an EASY way to make 'git format-patch --cover-letter $commitid'
> (and git send-email, by extension) automatically search for all cc's any any
> of the N/M patches, and auto-cc ALL of those recipients on the 0/N cover
> letter?  And if that is not something easily built into git format-patch
> directly, is it something that can easily be added to sendemail.cccmd?  This
> is not the first time that someone has complained that automatic cc's are
> not sending the cover letter context to a particular maintainer interested
> (and auto-cc'd) in only a subset of an overall series.
> 
> On the other hand, cc'ing all recipients for a largely mechanical patch
> series that was split into 67 parts, in part because it touches so many
> different maintainers' areas, may make the cover letter have so many
> recipients that various mail gateways start rejecting it as potential spam.

I do this sometimes (pipe to this script):

grep -e ^Signed-off-by -e ^Acked -e ^Reported -e ^Tested -e ^Cc | sed 
's/.*.*//'|sort | uniq | sed 's/^/Cc: /'


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



Re: [Qemu-devel] [PATCH 0/3] Document intent for supported build platforms and bump min glib to 2.42

2018-05-04 Thread Daniel P . Berrangé
On Fri, May 04, 2018 at 09:40:06PM +0200, Olaf Hering wrote:
> Am Fri,  4 May 2018 17:00:23 +0100
> schrieb Daniel P. Berrangé :
> 
> >   - I suggested following libvirt's lead in writing a policy for how
> > we pick supported OS targets to inform maintainers when min versions
> > can be increased.
> 
> Since Xen depends on qemu, it also means that SLE11 will disappear
> silently for them.

There's still option of using existing QEMU versions on old distros, or
building a new parallel installed glib to support new QEMU, if old distro
support is needed.

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



Re: [Qemu-devel] [PATCH v2 00/10] target/arm: Implement v8.1-Atomics

2018-05-04 Thread no-reply
Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 20180504183021.19318-1-richard.hender...@linaro.org
Subject: [Qemu-devel] [PATCH v2 00/10] target/arm: Implement v8.1-Atomics

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
failed=1
echo
fi
n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 t [tag update]
patchew/20180504171540.25813-1-peter.mayd...@linaro.org -> 
patchew/20180504171540.25813-1-peter.mayd...@linaro.org
 * [new tag]   
patchew/20180504183021.19318-1-richard.hender...@linaro.org -> 
patchew/20180504183021.19318-1-richard.hender...@linaro.org
Switched to a new branch 'test'
85278ba514 target/arm: Enable ARM_FEATURE_V8_ATOMICS for user-only
94bdcba55b target/arm: Implement CAS and CASP
62f42319cf target/arm: Fill in disas_ldst_atomic
8d29049006 target/arm: Introduce ARM_FEATURE_V8_ATOMICS and initial decode
faec1dbe5a target/riscv: Use new atomic min/max expanders
1fa0baa271 tcg: Use GEN_ATOMIC_HELPER_FN for opposite endian atomic add
bb9e6b5cdb tcg: Introduce atomic helpers for integer min/max
b0c37750f7 target/xtensa: Use new min/max expanders
3373196e98 target/arm: Use new min/max expanders
38706ce634 tcg: Introduce helpers for integer min/max

=== OUTPUT BEGIN ===
Checking PATCH 1/10: tcg: Introduce helpers for integer min/max...
Checking PATCH 2/10: target/arm: Use new min/max expanders...
Checking PATCH 3/10: target/xtensa: Use new min/max expanders...
Checking PATCH 4/10: tcg: Introduce atomic helpers for integer min/max...
ERROR: memory barrier without comment
#56: FILE: accel/tcg/atomic_template.h:137:
+smp_mb();   \

ERROR: memory barrier without comment
#96: FILE: accel/tcg/atomic_template.h:285:
+smp_mb();   \

total: 2 errors, 0 warnings, 236 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 5/10: tcg: Use GEN_ATOMIC_HELPER_FN for opposite endian atomic 
add...
Checking PATCH 6/10: target/riscv: Use new atomic min/max expanders...
Checking PATCH 7/10: target/arm: Introduce ARM_FEATURE_V8_ATOMICS and initial 
decode...
Checking PATCH 8/10: target/arm: Fill in disas_ldst_atomic...
Checking PATCH 9/10: target/arm: Implement CAS and CASP...
Checking PATCH 10/10: target/arm: Enable ARM_FEATURE_V8_ATOMICS for user-only...
=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

Re: [Qemu-devel] [PATCH 2/3] glib: bump min required glib library version to 2.42

2018-05-04 Thread Eric Blake

On 05/04/2018 11:00 AM, Daniel P. Berrangé wrote:

Per supported platforms doc, the various min glib on relevant distros is:

   RHEL-7: 2.50.3
   Debian (Stretch): 2.50.3
   Debian (Jessie): 2.42.1
   OpenBSD (Ports): 2.54.3
   FreeBSD (Ports): 2.50.3
   OpenSUSE Leap 15: 2.54.3
   Ubuntu (Xenial): 2.48.0
   macOS (Homebrew): 2.56.0



Worth listing mingw in this list (at least the cross-compile environment 
that docker tests from Fedora)?



This suggests that a minimum glib of 2.42 is a reasonable target

Signed-off-by: Daniel P. Berrangé 
---



+++ b/trace/simple.c
@@ -36,9 +36,9 @@
   * Trace records are written out by a dedicated thread.  The thread waits for
   * records to become available, writes them out, and then waits again.
   */
-static CompatGMutex trace_lock;
-static CompatGCond trace_available_cond;
-static CompatGCond trace_empty_cond;
+static GMuttex trace_lock;


As pointed out by patchew, this is a typo.

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



Re: [Qemu-devel] [PATCH 0/3] Document intent for supported build platforms and bump min glib to 2.42

2018-05-04 Thread Daniel P . Berrangé
CC'ing xen-devel in case Xen maintainers have a need for something that
will that conflict with this proposal wrt supported build platforms.

On Fri, May 04, 2018 at 05:00:23PM +0100, Daniel P. Berrangé wrote:
> This short series is a followup the discussions around min glib version
> when Olaf found we had accidentally increased the min glib by using a
> newer function:
> 
>   https://lists.gnu.org/archive/html/qemu-devel/2018-04/msg02699.html
> 
> Some key points from that thread
> 
>   - Although we have a docker job that tries to test the min glib
> version is adhered to, that's only run post-build, not by Peter's
> merge tests, nor by patchew.
> 
>   - The docker min glib test failed to detect the problem anyway
> because RHEL had backported the symbol in question.
> 
>   - The docker min glib test only builds with certain configure
> options so isn't foolproof.
> 
>   - The modern distros we implicitly care about have way newer glib
> than 2.22
> 
>   - Peter's OS-X build host previously had 2.22, but after switching
> from fink to homebrew now has 2.56
> 
>   - I suggested following libvirt's lead in writing a policy for how
> we pick supported OS targets to inform maintainers when min versions
> can be increased.
> 
> This series writes such a document largely based on one I wrote for
> libvirt with a few changes, largely around OS-X and *BSD. Note it
> is not meant to be an exhaustive list of distros we'll build on, rather
> a representative selection, so that we can identify the range of 3rd
> party library versions we need to care about. So if your favourite
> distro is missing, dont be alarmed, as it probably ships similar
> vintage software to one of those listed - if not feel free to suggest
> additions.
> 
> Based on that doc and https://repology.org/metapackage/glib/versions,
> I identified that we could feasibly set min glib to 2.42. Note that
> this would be dropping RHEL-6 as a build host (RHEL-6.0 came out in
> 2010 so that's reasonable to drop IMHO). It would still cover 2 major
> Debian versions and 2 most recent Ubuntu LTS (16.04, 18.04, but *not*
> 14.04). This min glib lets us remove almost all our compat code.
> 
> Most interestingly, thanks tothe new min version being greater than
> 2.32, we can now use GLIB_VERSION_MAX_ALLOWED to validate the correct
> API usage according to our min version:
> 
>   
> https://developer.gnome.org/glib/stable/glib-Version-Information.html#GLIB-VERSION-MAX-ALLOWED:CAPS
> 
> This means that *all* our CI jobs & developer builds will be enforcing
> the min version, so means very many more conditionally built features
> will get their build validated against min glib version. This would
> do a much better job of catching mistakes than our min-glib docker
> job, making that obsolete.
> 
> Daniel P. Berrangé (3):
>   qemu-doc: provide details of supported build platforms
>   glib: bump min required glib library version to 2.42
>   glib: enforce the minimum required version and warn about old APIs
> 
>  configure   |   6 +-
>  include/glib-compat.h   | 362 
> ++--
>  qemu-doc.texi   |  68 +
>  tests/test-qmp-event.c  |   2 +-
>  tests/tpm-emu.h |   4 +-
>  tests/vhost-user-test.c |   4 +-
>  trace/simple.c  |   6 +-
>  7 files changed, 123 insertions(+), 329 deletions(-)
> 
> -- 
> 2.14.3
> 

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



Re: [Qemu-devel] [PATCH 0/3] Document intent for supported build platforms and bump min glib to 2.42

2018-05-04 Thread Olaf Hering
Am Fri,  4 May 2018 17:00:23 +0100
schrieb Daniel P. Berrangé :

>   - I suggested following libvirt's lead in writing a policy for how
> we pick supported OS targets to inform maintainers when min versions
> can be increased.

Since Xen depends on qemu, it also means that SLE11 will disappear silently for 
them.

Olaf


pgp5wB61MWdj_.pgp
Description: Digitale Signatur von OpenPGP


Re: [Qemu-devel] [PATCH] virtio-balloon: fix internal stat name array to match Linux kernel

2018-05-04 Thread Michael S. Tsirkin
On Fri, May 04, 2018 at 09:30:45AM -0700, Jonathan Helman wrote:
> The Linux kernel commit b4325044 ("virtio_balloon: add array
> of stat names") defines an array of stat name strings for consumers
> of the virtio interface to use via the virtio_balloon.h header
> file, rather than requiring each consumer to define its own. But at
> present, the stat names defined in this array by the Linux kernel
> do not match up with those defined internally by QEMU. This patch
> fixes this inconsistency by changing the QEMU stat names to match
> those defined by the Linux kernel.
> 
> Signed-off-by: Jonathan Helman 
> Cc: Rob Gardner 
> Cc: Thomas Tai 

So pls import the header from Linux so we can stop maintaining it
in QEMU.

> ---
>  docs/virtio-balloon-stats.txt | 4 ++--
>  hw/virtio/virtio-balloon.c| 4 ++--
>  2 files changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/docs/virtio-balloon-stats.txt b/docs/virtio-balloon-stats.txt
> index 9985e1d..7c69fdb 100644
> --- a/docs/virtio-balloon-stats.txt
> +++ b/docs/virtio-balloon-stats.txt
> @@ -34,8 +34,8 @@ which will return a dictionary containing:
>- stat-total-memory
>- stat-available-memory
>- stat-disk-caches
> -  - stat-htlb-pgalloc
> -  - stat-htlb-pgfail
> +  - stat-hugetlb-allocations
> +  - stat-hugetlb-failures
>  
>o A key named last-update, which contains the last stats update
>  timestamp in seconds. Since this timestamp is generated by the host,
> diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
> index 1f7a87f..8421d9f 100644
> --- a/hw/virtio/virtio-balloon.c
> +++ b/hw/virtio/virtio-balloon.c
> @@ -52,8 +52,8 @@ static const char *balloon_stat_names[] = {
> [VIRTIO_BALLOON_S_MEMTOT] = "stat-total-memory",
> [VIRTIO_BALLOON_S_AVAIL] = "stat-available-memory",
> [VIRTIO_BALLOON_S_CACHES] = "stat-disk-caches",
> -   [VIRTIO_BALLOON_S_HTLB_PGALLOC] = "stat-htlb-pgalloc",
> -   [VIRTIO_BALLOON_S_HTLB_PGFAIL] = "stat-htlb-pgfail",
> +   [VIRTIO_BALLOON_S_HTLB_PGALLOC] = "stat-hugetlb-allocations",
> +   [VIRTIO_BALLOON_S_HTLB_PGFAIL] = "stat-hugetlb-failures",
> [VIRTIO_BALLOON_S_NR] = NULL
>  };
>  
> -- 
> 1.8.3.1
> 
> Based-on: <1524799751-151698-5-git-send-email-...@redhat.com>
> ([PULL 4/4] virtio-balloon: add hugetlb page allocation counts)



[Qemu-devel] [PATCH v3 5/8] xen_disk: remove use of grant map/unmap

2018-05-04 Thread Paul Durrant
Now that the (native or emulated) xen_be_copy_grant_refs() helper is
always available, the xen_disk code can be significantly simplified by
removing direct use of grant map and unmap operations.

Signed-off-by: Paul Durrant 
---
Cc: Stefano Stabellini 
Cc: Anthony Perard 
Cc: Kevin Wolf 
Cc: Max Reitz 

v2:
 - Squashed in separate patche removing persistent grant use
 - Re-based
---
 hw/block/xen_disk.c | 370 
 1 file changed, 25 insertions(+), 345 deletions(-)

diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index 66ed2b7..28be8b6 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -36,27 +36,9 @@
 
 /* - */
 
-static int batch_maps   = 0;
-
-/* - */
-
 #define BLOCK_SIZE  512
 #define IOCB_COUNT  (BLKIF_MAX_SEGMENTS_PER_REQUEST + 2)
 
-struct PersistentGrant {
-void *page;
-struct XenBlkDev *blkdev;
-};
-
-typedef struct PersistentGrant PersistentGrant;
-
-struct PersistentRegion {
-void *addr;
-int num;
-};
-
-typedef struct PersistentRegion PersistentRegion;
-
 struct ioreq {
 blkif_request_t req;
 int16_t status;
@@ -65,14 +47,11 @@ struct ioreq {
 off_t   start;
 QEMUIOVectorv;
 int presync;
-uint8_t mapped;
 
 /* grant mapping */
 uint32_trefs[BLKIF_MAX_SEGMENTS_PER_REQUEST];
-int prot;
 void*page[BLKIF_MAX_SEGMENTS_PER_REQUEST];
 void*pages;
-int num_unmap;
 
 /* aio status */
 int aio_inflight;
@@ -103,7 +82,6 @@ struct XenBlkDev {
 int protocol;
 blkif_back_rings_t  rings;
 int more_work;
-int cnt_map;
 
 /* request lists */
 QLIST_HEAD(inflight_head, ioreq) inflight;
@@ -114,13 +92,7 @@ struct XenBlkDev {
 int requests_finished;
 unsigned intmax_requests;
 
-/* Persistent grants extension */
 gbooleanfeature_discard;
-gbooleanfeature_persistent;
-GTree   *persistent_gnts;
-GSList  *persistent_regions;
-unsigned intpersistent_gnt_count;
-unsigned intmax_grants;
 
 /* qemu block driver */
 DriveInfo   *dinfo;
@@ -139,10 +111,8 @@ static void ioreq_reset(struct ioreq *ioreq)
 ioreq->status = 0;
 ioreq->start = 0;
 ioreq->presync = 0;
-ioreq->mapped = 0;
 
 memset(ioreq->refs, 0, sizeof(ioreq->refs));
-ioreq->prot = 0;
 memset(ioreq->page, 0, sizeof(ioreq->page));
 ioreq->pages = NULL;
 
@@ -156,37 +126,6 @@ static void ioreq_reset(struct ioreq *ioreq)
 qemu_iovec_reset(>v);
 }
 
-static gint int_cmp(gconstpointer a, gconstpointer b, gpointer user_data)
-{
-uint ua = GPOINTER_TO_UINT(a);
-uint ub = GPOINTER_TO_UINT(b);
-return (ua > ub) - (ua < ub);
-}
-
-static void destroy_grant(gpointer pgnt)
-{
-PersistentGrant *grant = pgnt;
-struct XenBlkDev *blkdev = grant->blkdev;
-struct XenDevice *xendev = >xendev;
-
-xen_be_unmap_grant_ref(xendev, grant->page);
-grant->blkdev->persistent_gnt_count--;
-xen_pv_printf(xendev, 3, "unmapped grant %p\n", grant->page);
-g_free(grant);
-}
-
-static void remove_persistent_region(gpointer data, gpointer dev)
-{
-PersistentRegion *region = data;
-struct XenBlkDev *blkdev = dev;
-struct XenDevice *xendev = >xendev;
-
-xen_be_unmap_grant_refs(xendev, region->addr, region->num);
-xen_pv_printf(xendev, 3, "unmapped grant region %p with %d pages\n",
-  region->addr, region->num);
-g_free(region);
-}
-
 static struct ioreq *ioreq_start(struct XenBlkDev *blkdev)
 {
 struct ioreq *ioreq = NULL;
@@ -254,7 +193,6 @@ static int ioreq_parse(struct ioreq *ioreq)
   ioreq->req.handle, ioreq->req.id, ioreq->req.sector_number);
 switch (ioreq->req.operation) {
 case BLKIF_OP_READ:
-ioreq->prot = PROT_WRITE; /* to memory */
 break;
 case BLKIF_OP_FLUSH_DISKCACHE:
 ioreq->presync = 1;
@@ -263,7 +201,6 @@ static int ioreq_parse(struct ioreq *ioreq)
 }
 /* fall through */
 case BLKIF_OP_WRITE:
-ioreq->prot = PROT_READ; /* from memory */
 break;
 case BLKIF_OP_DISCARD:
 return 0;
@@ -310,173 +247,6 @@ err:
 return -1;
 }
 
-static void ioreq_unmap(struct ioreq *ioreq)
-{
-struct XenBlkDev *blkdev = ioreq->blkdev;
-struct XenDevice *xendev = >xendev;
-int i;
-
-if (ioreq->num_unmap == 0 || ioreq->mapped == 0) {
-return;
-}
-if (batch_maps) {
-if (!ioreq->pages) {
-return;
-}
- 

[Qemu-devel] [PATCH v3 8/8] xen_disk: be consistent with use of xendev and blkdev->xendev

2018-05-04 Thread Paul Durrant
Certain functions in xen_disk are called with a pointer to xendev
(struct XenDevice *). They then use continer_of() to acces the surrounding
blkdev (struct XenBlkDev) but then in various places use >xendev
when use of the original xendev pointer is shorter to express and clearly
equivalent.

This patch is a purely cosmetic patch which makes sure there is a xendev
pointer on stack for any function where the pointer is need on multiple
occasions modified those functions to use it consistently.

Signed-off-by: Paul Durrant 
---
Cc: Stefano Stabellini 
Cc: Anthony Perard 
Cc: Kevin Wolf 
Cc: Max Reitz 

v2:
 - Re-based
---
 hw/block/xen_disk.c | 90 +++--
 1 file changed, 46 insertions(+), 44 deletions(-)

diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index 28651c5..9fbc0cd 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -178,10 +178,11 @@ static void ioreq_release(struct ioreq *ioreq, bool 
finish)
 static int ioreq_parse(struct ioreq *ioreq)
 {
 struct XenBlkDev *blkdev = ioreq->blkdev;
+struct XenDevice *xendev = >xendev;
 size_t len;
 int i;
 
-xen_pv_printf(>xendev, 3,
+xen_pv_printf(xendev, 3,
   "op %d, nr %d, handle %d, id %" PRId64 ", sector %" PRId64 
"\n",
   ioreq->req.operation, ioreq->req.nr_segments,
   ioreq->req.handle, ioreq->req.id, ioreq->req.sector_number);
@@ -199,28 +200,28 @@ static int ioreq_parse(struct ioreq *ioreq)
 case BLKIF_OP_DISCARD:
 return 0;
 default:
-xen_pv_printf(>xendev, 0, "error: unknown operation (%d)\n",
+xen_pv_printf(xendev, 0, "error: unknown operation (%d)\n",
   ioreq->req.operation);
 goto err;
 };
 
 if (ioreq->req.operation != BLKIF_OP_READ && blkdev->mode[0] != 'w') {
-xen_pv_printf(>xendev, 0, "error: write req for ro device\n");
+xen_pv_printf(xendev, 0, "error: write req for ro device\n");
 goto err;
 }
 
 ioreq->start = ioreq->req.sector_number * blkdev->file_blk;
 for (i = 0; i < ioreq->req.nr_segments; i++) {
 if (i == BLKIF_MAX_SEGMENTS_PER_REQUEST) {
-xen_pv_printf(>xendev, 0, "error: nr_segments too big\n");
+xen_pv_printf(xendev, 0, "error: nr_segments too big\n");
 goto err;
 }
 if (ioreq->req.seg[i].first_sect > ioreq->req.seg[i].last_sect) {
-xen_pv_printf(>xendev, 0, "error: first > last sector\n");
+xen_pv_printf(xendev, 0, "error: first > last sector\n");
 goto err;
 }
 if (ioreq->req.seg[i].last_sect * BLOCK_SIZE >= XC_PAGE_SIZE) {
-xen_pv_printf(>xendev, 0, "error: page crossing\n");
+xen_pv_printf(xendev, 0, "error: page crossing\n");
 goto err;
 }
 
@@ -228,7 +229,7 @@ static int ioreq_parse(struct ioreq *ioreq)
 ioreq->size += len;
 }
 if (ioreq->start + ioreq->size > blkdev->file_size) {
-xen_pv_printf(>xendev, 0, "error: access beyond end of 
file\n");
+xen_pv_printf(xendev, 0, "error: access beyond end of file\n");
 goto err;
 }
 return 0;
@@ -244,7 +245,7 @@ static int ioreq_grant_copy(struct ioreq *ioreq)
 struct XenDevice *xendev = >xendev;
 XenGrantCopySegment segs[BLKIF_MAX_SEGMENTS_PER_REQUEST];
 int i, count, rc;
-int64_t file_blk = ioreq->blkdev->file_blk;
+int64_t file_blk = blkdev->file_blk;
 bool to_domain = (ioreq->req.operation == BLKIF_OP_READ);
 void *virt = ioreq->buf;
 
@@ -272,7 +273,7 @@ static int ioreq_grant_copy(struct ioreq *ioreq)
 rc = xen_be_copy_grant_refs(xendev, to_domain, segs, count);
 
 if (rc) {
-xen_pv_printf(>blkdev->xendev, 0,
+xen_pv_printf(xendev, 0,
   "failed to copy data %d\n", rc);
 ioreq->aio_errors++;
 return -1;
@@ -287,11 +288,12 @@ static void qemu_aio_complete(void *opaque, int ret)
 {
 struct ioreq *ioreq = opaque;
 struct XenBlkDev *blkdev = ioreq->blkdev;
+struct XenDevice *xendev = >xendev;
 
 aio_context_acquire(blkdev->ctx);
 
 if (ret != 0) {
-xen_pv_printf(>xendev, 0, "%s I/O error\n",
+xen_pv_printf(xendev, 0, "%s I/O error\n",
   ioreq->req.operation == BLKIF_OP_READ ? "read" : 
"write");
 ioreq->aio_errors++;
 }
@@ -625,16 +627,17 @@ static void blk_alloc(struct XenDevice *xendev)
 
 static void blk_parse_discard(struct XenBlkDev *blkdev)
 {
+struct XenDevice *xendev = >xendev;
 int enable;
 
 blkdev->feature_discard = true;
 
-if (xenstore_read_be_int(>xendev, "discard-enable", ) == 0) 
{
+if (xenstore_read_be_int(xendev, "discard-enable", ) == 0) {
 blkdev->feature_discard = !!enable;
 }
 
 if (blkdev->feature_discard) {
-

[Qemu-devel] [PATCH v3 3/8] xen: remove other open-coded use of libxengnttab

2018-05-04 Thread Paul Durrant
Now that helpers are available in xen_backend, use them throughout all
Xen PV backends.

Signed-off-by: Paul Durrant 
---
Cc: Stefano Stabellini 
Cc: Anthony Perard 
Cc: Greg Kurz 
Cc: Paolo Bonzini 
Cc: Jason Wang 
Cc: Gerd Hoffmann 

v2:
 - New in v2
---
 hw/9pfs/xen-9p-backend.c | 32 +++-
 hw/char/xen_console.c|  9 -
 hw/net/xen_nic.c | 34 +++---
 hw/usb/xen-usb.c | 37 +
 4 files changed, 51 insertions(+), 61 deletions(-)

diff --git a/hw/9pfs/xen-9p-backend.c b/hw/9pfs/xen-9p-backend.c
index 95e50c4..6026780 100644
--- a/hw/9pfs/xen-9p-backend.c
+++ b/hw/9pfs/xen-9p-backend.c
@@ -331,14 +331,14 @@ static int xen_9pfs_free(struct XenDevice *xendev)
 
 for (i = 0; i < xen_9pdev->num_rings; i++) {
 if (xen_9pdev->rings[i].data != NULL) {
-xengnttab_unmap(xen_9pdev->xendev.gnttabdev,
-xen_9pdev->rings[i].data,
-(1 << xen_9pdev->rings[i].ring_order));
+xen_be_unmap_grant_refs(_9pdev->xendev,
+xen_9pdev->rings[i].data,
+(1 << xen_9pdev->rings[i].ring_order));
 }
 if (xen_9pdev->rings[i].intf != NULL) {
-xengnttab_unmap(xen_9pdev->xendev.gnttabdev,
-xen_9pdev->rings[i].intf,
-1);
+xen_be_unmap_grant_refs(_9pdev->xendev,
+xen_9pdev->rings[i].intf,
+1);
 }
 if (xen_9pdev->rings[i].bh != NULL) {
 qemu_bh_delete(xen_9pdev->rings[i].bh);
@@ -390,11 +390,10 @@ static int xen_9pfs_connect(struct XenDevice *xendev)
 }
 g_free(str);
 
-xen_9pdev->rings[i].intf =  xengnttab_map_grant_ref(
-xen_9pdev->xendev.gnttabdev,
-xen_9pdev->xendev.dom,
-xen_9pdev->rings[i].ref,
-PROT_READ | PROT_WRITE);
+xen_9pdev->rings[i].intf =
+xen_be_map_grant_ref(_9pdev->xendev,
+ xen_9pdev->rings[i].ref,
+ PROT_READ | PROT_WRITE);
 if (!xen_9pdev->rings[i].intf) {
 goto out;
 }
@@ -403,12 +402,11 @@ static int xen_9pfs_connect(struct XenDevice *xendev)
 goto out;
 }
 xen_9pdev->rings[i].ring_order = ring_order;
-xen_9pdev->rings[i].data = xengnttab_map_domain_grant_refs(
-xen_9pdev->xendev.gnttabdev,
-(1 << ring_order),
-xen_9pdev->xendev.dom,
-xen_9pdev->rings[i].intf->ref,
-PROT_READ | PROT_WRITE);
+xen_9pdev->rings[i].data =
+xen_be_map_grant_refs(_9pdev->xendev,
+  xen_9pdev->rings[i].intf->ref,
+  (1 << ring_order),
+  PROT_READ | PROT_WRITE);
 if (!xen_9pdev->rings[i].data) {
 goto out;
 }
diff --git a/hw/char/xen_console.c b/hw/char/xen_console.c
index bdfaa40..8b4b4bf 100644
--- a/hw/char/xen_console.c
+++ b/hw/char/xen_console.c
@@ -233,12 +233,11 @@ static int con_initialise(struct XenDevice *xendev)
 if (!xendev->dev) {
 xen_pfn_t mfn = con->ring_ref;
 con->sring = xenforeignmemory_map(xen_fmem, con->xendev.dom,
-  PROT_READ|PROT_WRITE,
+  PROT_READ | PROT_WRITE,
   1, , NULL);
 } else {
-con->sring = xengnttab_map_grant_ref(xendev->gnttabdev, 
con->xendev.dom,
- con->ring_ref,
- PROT_READ|PROT_WRITE);
+con->sring = xen_be_map_grant_ref(xendev, con->ring_ref,
+  PROT_READ | PROT_WRITE);
 }
 if (!con->sring)
return -1;
@@ -267,7 +266,7 @@ static void con_disconnect(struct XenDevice *xendev)
 if (!xendev->dev) {
 xenforeignmemory_unmap(xen_fmem, con->sring, 1);
 } else {
-xengnttab_unmap(xendev->gnttabdev, con->sring, 1);
+xen_be_unmap_grant_ref(xendev, con->sring);
 }
 con->sring = NULL;
 }
diff --git a/hw/net/xen_nic.c b/hw/net/xen_nic.c
index 20c43a6..73d6f1b 100644
--- a/hw/net/xen_nic.c
+++ b/hw/net/xen_nic.c
@@ -160,9 +160,8 @@ static void net_tx_packets(struct XenNetDev *netdev)
   (txreq.flags & NETTXF_more_data)  ? " more_data" 
 : "",
   (txreq.flags & NETTXF_extra_info) ? " 
extra_info" : "");
 
-page = 

Re: [Qemu-devel] [PATCH v4 02/11] machine: make MemoryHotplugState accessible via the machine

2018-05-04 Thread Eduardo Habkost
On Mon, Apr 23, 2018 at 06:51:17PM +0200, David Hildenbrand wrote:
[...]
> +/* always allocate the device memory information */
> +machine->device_memory = g_malloc(sizeof(*machine->device_memory));
[...]
> -/* initialize hotplug memory address space */
> +/* always allocate the device memory information */
> +machine->device_memory = g_malloc(sizeof(*machine->device_memory));

This makes QEMU crash because machine->device_memory->base is initialized with
garbage:

#1  0x7fffef30a8f8 in abort () at /lib64/libc.so.6
#2  0x7fffef302026 in __assert_fail_base () at /lib64/libc.so.6
#3  0x7fffef3020d2 in  () at /lib64/libc.so.6
#4  0x55833483 in int128_get64 (a=) at 
.../qemu-build/include/qemu/int128.h:22
#5  0x55837c2e in memory_region_size (a=) at 
.../qemu-build/memory.c:1735
#6  0x55837c2e in memory_region_size (mr=) at 
.../qemu-build/memory.c:1739
#7  0x558a2b14 in pc_memory_init (pcms=pcms@entry=0x56850050, 
system_memory=system_memory@entry=0x56851e00, 
rom_memory=rom_memory@entry=0x568b8120, 
ram_memory=ram_memory@entry=0x7fffd630)
at .../qemu-build/hw/i386/pc.c:1440
#8  0x558a5a73 in pc_init1 (machine=0x56850050, 
pci_type=0x55cb6fd0 "i440FX", host_type=0x55c43e41 "i440FX-pcihost") at 
.../qemu-build/hw/i386/pc_piix.c:179
#9  0x559abbda in machine_run_board_init (machine=0x56850050) at 
.../qemu-build/hw/core/machine.c:829
#10 0x557dc515 in main (argc=, argv=, 
envp=) at .../qemu-build/vl.c:4563


I will squash the following fixup:

>From 6216fdb28476ed21c4ced4672003c9c7cb0e04d2 Mon Sep 17 00:00:00 2001
From: David Hildenbrand 
Date: Fri, 4 May 2018 15:54:46 +0200
Subject: [PATCH] memory-device: fix device_memory creation on pc and spapr

We have to inititalize the struct to 0. Otherwise, without "maxmem",
the content is undefined, which might result in random asserts
striking when e.g. reading out the size of the contained memory region.

Signed-off-by: David Hildenbrand 
---
 hw/i386/pc.c   | 2 +-
 hw/ppc/spapr.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index ffcd7b85d9..868893d0a1 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1372,7 +1372,7 @@ void pc_memory_init(PCMachineState *pcms,
 }
 
 /* always allocate the device memory information */
-machine->device_memory = g_malloc(sizeof(*machine->device_memory));
+machine->device_memory = g_malloc0(sizeof(*machine->device_memory));
 
 /* initialize device memory address space */
 if (pcmc->has_reserved_memory &&
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index ef05075232..a1abcba6ad 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2637,7 +2637,7 @@ static void spapr_machine_init(MachineState *machine)
 memory_region_add_subregion(sysmem, 0, ram);
 
 /* always allocate the device memory information */
-machine->device_memory = g_malloc(sizeof(*machine->device_memory));
+machine->device_memory = g_malloc0(sizeof(*machine->device_memory));
 
 /* initialize hotplug memory address space */
 if (machine->ram_size < machine->maxram_size) {
-- 
2.14.3


-- 
Eduardo



[Qemu-devel] [PATCH v3 2/8] xen_disk: remove open-coded use of libxengnttab

2018-05-04 Thread Paul Durrant
Now that helpers are present in xen_backend, this patch removes open-coded
calls to libxengnttab from the xen_disk code.

This patch also fixes one whitspace error in the assignment of the
XenDevOps initialise method.

Signed-off-by: Paul Durrant 
---
Cc: Stefano Stabellini 
Cc: Anthony Perard 
Cc: Kevin Wolf 
Cc: Max Reitz 

v2:
 - New in v2
---
 hw/block/xen_disk.c | 122 ++--
 1 file changed, 32 insertions(+), 90 deletions(-)

diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index f74fcd4..66ed2b7 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -68,7 +68,6 @@ struct ioreq {
 uint8_t mapped;
 
 /* grant mapping */
-uint32_tdomids[BLKIF_MAX_SEGMENTS_PER_REQUEST];
 uint32_trefs[BLKIF_MAX_SEGMENTS_PER_REQUEST];
 int prot;
 void*page[BLKIF_MAX_SEGMENTS_PER_REQUEST];
@@ -142,7 +141,6 @@ static void ioreq_reset(struct ioreq *ioreq)
 ioreq->presync = 0;
 ioreq->mapped = 0;
 
-memset(ioreq->domids, 0, sizeof(ioreq->domids));
 memset(ioreq->refs, 0, sizeof(ioreq->refs));
 ioreq->prot = 0;
 memset(ioreq->page, 0, sizeof(ioreq->page));
@@ -168,16 +166,12 @@ static gint int_cmp(gconstpointer a, gconstpointer b, 
gpointer user_data)
 static void destroy_grant(gpointer pgnt)
 {
 PersistentGrant *grant = pgnt;
-xengnttab_handle *gnt = grant->blkdev->xendev.gnttabdev;
+struct XenBlkDev *blkdev = grant->blkdev;
+struct XenDevice *xendev = >xendev;
 
-if (xengnttab_unmap(gnt, grant->page, 1) != 0) {
-xen_pv_printf(>blkdev->xendev, 0,
-  "xengnttab_unmap failed: %s\n",
-  strerror(errno));
-}
+xen_be_unmap_grant_ref(xendev, grant->page);
 grant->blkdev->persistent_gnt_count--;
-xen_pv_printf(>blkdev->xendev, 3,
-  "unmapped grant %p\n", grant->page);
+xen_pv_printf(xendev, 3, "unmapped grant %p\n", grant->page);
 g_free(grant);
 }
 
@@ -185,15 +179,10 @@ static void remove_persistent_region(gpointer data, 
gpointer dev)
 {
 PersistentRegion *region = data;
 struct XenBlkDev *blkdev = dev;
-xengnttab_handle *gnt = blkdev->xendev.gnttabdev;
+struct XenDevice *xendev = >xendev;
 
-if (xengnttab_unmap(gnt, region->addr, region->num) != 0) {
-xen_pv_printf(>xendev, 0,
-  "xengnttab_unmap region %p failed: %s\n",
-  region->addr, strerror(errno));
-}
-xen_pv_printf(>xendev, 3,
-  "unmapped grant region %p with %d pages\n",
+xen_be_unmap_grant_refs(xendev, region->addr, region->num);
+xen_pv_printf(xendev, 3, "unmapped grant region %p with %d pages\n",
   region->addr, region->num);
 g_free(region);
 }
@@ -304,7 +293,6 @@ static int ioreq_parse(struct ioreq *ioreq)
 goto err;
 }
 
-ioreq->domids[i] = blkdev->xendev.dom;
 ioreq->refs[i]   = ioreq->req.seg[i].gref;
 
 mem = ioreq->req.seg[i].first_sect * blkdev->file_blk;
@@ -324,7 +312,8 @@ err:
 
 static void ioreq_unmap(struct ioreq *ioreq)
 {
-xengnttab_handle *gnt = ioreq->blkdev->xendev.gnttabdev;
+struct XenBlkDev *blkdev = ioreq->blkdev;
+struct XenDevice *xendev = >xendev;
 int i;
 
 if (ioreq->num_unmap == 0 || ioreq->mapped == 0) {
@@ -334,11 +323,7 @@ static void ioreq_unmap(struct ioreq *ioreq)
 if (!ioreq->pages) {
 return;
 }
-if (xengnttab_unmap(gnt, ioreq->pages, ioreq->num_unmap) != 0) {
-xen_pv_printf(>blkdev->xendev, 0,
-  "xengnttab_unmap failed: %s\n",
-  strerror(errno));
-}
+xen_be_unmap_grant_refs(xendev, ioreq->pages, ioreq->num_unmap);
 ioreq->blkdev->cnt_map -= ioreq->num_unmap;
 ioreq->pages = NULL;
 } else {
@@ -346,11 +331,7 @@ static void ioreq_unmap(struct ioreq *ioreq)
 if (!ioreq->page[i]) {
 continue;
 }
-if (xengnttab_unmap(gnt, ioreq->page[i], 1) != 0) {
-xen_pv_printf(>blkdev->xendev, 0,
-  "xengnttab_unmap failed: %s\n",
-  strerror(errno));
-}
+xen_be_unmap_grant_ref(xendev, ioreq->page[i]);
 ioreq->blkdev->cnt_map--;
 ioreq->page[i] = NULL;
 }
@@ -360,14 +341,14 @@ static void ioreq_unmap(struct ioreq *ioreq)
 
 static int ioreq_map(struct ioreq *ioreq)
 {
-xengnttab_handle *gnt = ioreq->blkdev->xendev.gnttabdev;
-uint32_t domids[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+struct XenBlkDev *blkdev = ioreq->blkdev;
+struct XenDevice *xendev = >xendev;
 uint32_t refs[BLKIF_MAX_SEGMENTS_PER_REQUEST];
 void *page[BLKIF_MAX_SEGMENTS_PER_REQUEST];
  

[Qemu-devel] [PATCH v3 4/8] xen_backend: add an emulation of grant copy

2018-05-04 Thread Paul Durrant
Not all Xen environments support the xengnttab_grant_copy() operation.
E.g. where the OS is FreeBSD or Xen is older than 4.8.0.

This patch introduces an emulation of that operation using
xengnttab_map_domain_grant_refs() and memcpy() for those environments.

Signed-off-by: Paul Durrant 
---
Cc: Stefano Stabellini 
Cc: Anthony Perard 

v2:
 - New in v2
---
 hw/xen/xen_backend.c | 53 
 1 file changed, 53 insertions(+)

diff --git a/hw/xen/xen_backend.c b/hw/xen/xen_backend.c
index 50412d6..3c3fc2c 100644
--- a/hw/xen/xen_backend.c
+++ b/hw/xen/xen_backend.c
@@ -146,6 +146,55 @@ void xen_be_unmap_grant_refs(struct XenDevice *xendev, 
void *ptr,
 }
 }
 
+static int compat_copy_grant_refs(struct XenDevice *xendev,
+  bool to_domain,
+  XenGrantCopySegment segs[],
+  unsigned int nr_segs)
+{
+uint32_t *refs = g_new(uint32_t, nr_segs);
+int prot = to_domain ? PROT_WRITE : PROT_READ;
+void *pages;
+unsigned int i;
+
+for (i = 0; i < nr_segs; i++) {
+XenGrantCopySegment *seg = [i];
+
+refs[i] = to_domain ?
+seg->dest.foreign.ref : seg->source.foreign.ref;
+}
+
+pages = xengnttab_map_domain_grant_refs(xendev->gnttabdev, nr_segs,
+xen_domid, refs, prot);
+if (!pages) {
+xen_pv_printf(xendev, 0,
+  "xengnttab_map_domain_grant_refs failed: %s\n",
+  strerror(errno));
+g_free(refs);
+return -1;
+}
+
+for (i = 0; i < nr_segs; i++) {
+XenGrantCopySegment *seg = [i];
+void *page = pages + (i * XC_PAGE_SIZE);
+
+if (to_domain) {
+memcpy(page + seg->dest.foreign.offset, seg->source.virt,
+   seg->len);
+} else {
+memcpy(seg->dest.virt, page + seg->source.foreign.offset,
+   seg->len);
+}
+}
+
+if (xengnttab_unmap(xendev->gnttabdev, pages, nr_segs)) {
+xen_pv_printf(xendev, 0, "xengnttab_unmap failed: %s\n",
+  strerror(errno));
+}
+
+g_free(refs);
+return 0;
+}
+
 int xen_be_copy_grant_refs(struct XenDevice *xendev,
bool to_domain,
XenGrantCopySegment segs[],
@@ -157,6 +206,10 @@ int xen_be_copy_grant_refs(struct XenDevice *xendev,
 
 assert(xendev->ops->flags & DEVOPS_FLAG_NEED_GNTDEV);
 
+if (!xen_feature_grant_copy) {
+return compat_copy_grant_refs(xendev, to_domain, segs, nr_segs);
+}
+
 xengnttab_segs = g_new0(xengnttab_grant_copy_segment_t, nr_segs);
 
 for (i = 0; i < nr_segs; i++) {
-- 
2.1.4




[Qemu-devel] [PATCH v3 6/8] xen_backend: make the xen_feature_grant_copy flag private

2018-05-04 Thread Paul Durrant
There is no longer any use of this flag outside of the xen_backend code.

Signed-off-by: Paul Durrant 
---
Cc: Stefano Stabellini 
Cc: Anthony Perard 

v2:
 - New in v2
---
 hw/xen/xen_backend.c | 2 +-
 include/hw/xen/xen_backend.h | 1 -
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/hw/xen/xen_backend.c b/hw/xen/xen_backend.c
index 3c3fc2c..9a8e877 100644
--- a/hw/xen/xen_backend.c
+++ b/hw/xen/xen_backend.c
@@ -44,9 +44,9 @@ BusState *xen_sysbus;
 /* public */
 struct xs_handle *xenstore = NULL;
 const char *xen_protocol;
-bool xen_feature_grant_copy;
 
 /* private */
+static bool xen_feature_grant_copy;
 static int debug;
 
 int xenstore_write_be_str(struct XenDevice *xendev, const char *node, const 
char *val)
diff --git a/include/hw/xen/xen_backend.h b/include/hw/xen/xen_backend.h
index 29bf1c3..9c17fdd 100644
--- a/include/hw/xen/xen_backend.h
+++ b/include/hw/xen/xen_backend.h
@@ -16,7 +16,6 @@
 /* variables */
 extern struct xs_handle *xenstore;
 extern const char *xen_protocol;
-extern bool xen_feature_grant_copy;
 extern DeviceState *xen_sysdev;
 extern BusState *xen_sysbus;
 
-- 
2.1.4




[Qemu-devel] [PATCH v3 7/8] xen_disk: use a single entry iovec

2018-05-04 Thread Paul Durrant
Since xen_disk now always copies data to and from a guest there is no need
to maintain a vector entry corresponding to every page of a request.
This means there is less per-request state to maintain so the ioreq
structure can shrink significantly.

Signed-off-by: Paul Durrant 
---
Cc: Stefano Stabellini 
Cc: Anthony Perard 
Cc: Kevin Wolf 
Cc: Max Reitz 

v3:
 - Un-break by fixing mis-placed qemu_iovec_add()

v2:
 - Re-based
---
 hw/block/xen_disk.c | 76 +++--
 1 file changed, 21 insertions(+), 55 deletions(-)

diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index 28be8b6..28651c5 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -46,13 +46,10 @@ struct ioreq {
 /* parsed request */
 off_t   start;
 QEMUIOVectorv;
+void*buf;
+size_t  size;
 int presync;
 
-/* grant mapping */
-uint32_trefs[BLKIF_MAX_SEGMENTS_PER_REQUEST];
-void*page[BLKIF_MAX_SEGMENTS_PER_REQUEST];
-void*pages;
-
 /* aio status */
 int aio_inflight;
 int aio_errors;
@@ -110,12 +107,10 @@ static void ioreq_reset(struct ioreq *ioreq)
 memset(>req, 0, sizeof(ioreq->req));
 ioreq->status = 0;
 ioreq->start = 0;
+ioreq->buf = NULL;
+ioreq->size = 0;
 ioreq->presync = 0;
 
-memset(ioreq->refs, 0, sizeof(ioreq->refs));
-memset(ioreq->page, 0, sizeof(ioreq->page));
-ioreq->pages = NULL;
-
 ioreq->aio_inflight = 0;
 ioreq->aio_errors = 0;
 
@@ -138,7 +133,7 @@ static struct ioreq *ioreq_start(struct XenBlkDev *blkdev)
 ioreq = g_malloc0(sizeof(*ioreq));
 ioreq->blkdev = blkdev;
 blkdev->requests_total++;
-qemu_iovec_init(>v, BLKIF_MAX_SEGMENTS_PER_REQUEST);
+qemu_iovec_init(>v, 1);
 } else {
 /* get one from freelist */
 ioreq = QLIST_FIRST(>freelist);
@@ -183,7 +178,6 @@ static void ioreq_release(struct ioreq *ioreq, bool finish)
 static int ioreq_parse(struct ioreq *ioreq)
 {
 struct XenBlkDev *blkdev = ioreq->blkdev;
-uintptr_t mem;
 size_t len;
 int i;
 
@@ -230,13 +224,10 @@ static int ioreq_parse(struct ioreq *ioreq)
 goto err;
 }
 
-ioreq->refs[i]   = ioreq->req.seg[i].gref;
-
-mem = ioreq->req.seg[i].first_sect * blkdev->file_blk;
 len = (ioreq->req.seg[i].last_sect - ioreq->req.seg[i].first_sect + 1) 
* blkdev->file_blk;
-qemu_iovec_add(>v, (void*)mem, len);
+ioreq->size += len;
 }
-if (ioreq->start + ioreq->v.size > blkdev->file_size) {
+if (ioreq->start + ioreq->size > blkdev->file_size) {
 xen_pv_printf(>xendev, 0, "error: access beyond end of 
file\n");
 goto err;
 }
@@ -247,35 +238,6 @@ err:
 return -1;
 }
 
-static void ioreq_free_copy_buffers(struct ioreq *ioreq)
-{
-int i;
-
-for (i = 0; i < ioreq->v.niov; i++) {
-ioreq->page[i] = NULL;
-}
-
-qemu_vfree(ioreq->pages);
-}
-
-static int ioreq_init_copy_buffers(struct ioreq *ioreq)
-{
-int i;
-
-if (ioreq->v.niov == 0) {
-return 0;
-}
-
-ioreq->pages = qemu_memalign(XC_PAGE_SIZE, ioreq->v.niov * XC_PAGE_SIZE);
-
-for (i = 0; i < ioreq->v.niov; i++) {
-ioreq->page[i] = ioreq->pages + i * XC_PAGE_SIZE;
-ioreq->v.iov[i].iov_base = ioreq->page[i];
-}
-
-return 0;
-}
-
 static int ioreq_grant_copy(struct ioreq *ioreq)
 {
 struct XenBlkDev *blkdev = ioreq->blkdev;
@@ -284,25 +246,27 @@ static int ioreq_grant_copy(struct ioreq *ioreq)
 int i, count, rc;
 int64_t file_blk = ioreq->blkdev->file_blk;
 bool to_domain = (ioreq->req.operation == BLKIF_OP_READ);
+void *virt = ioreq->buf;
 
-if (ioreq->v.niov == 0) {
+if (ioreq->req.nr_segments == 0) {
 return 0;
 }
 
-count = ioreq->v.niov;
+count = ioreq->req.nr_segments;
 
 for (i = 0; i < count; i++) {
 if (to_domain) {
-segs[i].dest.foreign.ref = ioreq->refs[i];
+segs[i].dest.foreign.ref = ioreq->req.seg[i].gref;
 segs[i].dest.foreign.offset = ioreq->req.seg[i].first_sect * 
file_blk;
-segs[i].source.virt = ioreq->v.iov[i].iov_base;
+segs[i].source.virt = virt;
 } else {
-segs[i].source.foreign.ref = ioreq->refs[i];
+segs[i].source.foreign.ref = ioreq->req.seg[i].gref;
 segs[i].source.foreign.offset = ioreq->req.seg[i].first_sect * 
file_blk;
-segs[i].dest.virt = ioreq->v.iov[i].iov_base;
+segs[i].dest.virt = virt;
 }
 segs[i].len = (ioreq->req.seg[i].last_sect
- ioreq->req.seg[i].first_sect + 1) * file_blk;
+virt += segs[i].len;
 }
 
 rc = 

[Qemu-devel] [PATCH v3 0/8] xen_disk: legacy code removal and cleanup

2018-05-04 Thread Paul Durrant
The grant copy operation was added to libxengnttab in Xen 4.8.0 (released
nearly 18 months ago) but the xen_disk PV backend QEMU is still carrying
a significant amount of code purely to remain compatible with older
versions of Xen.

As can be inferred from the diff stats below, removing this support for
older versions of Xen from QEMU reduces the size of the xen_disk source by
around 320 lines (~25%).
 
This versionseries maintains compatibility with older Xen, and OS
not supporting the grant copy operation, by adding an emulation of it
into the xen_backend code. Thus xen_disk can be simplified without
regressing support for any environment. This series also performs
general cleanup of the code by introducing and consistently using
helper functions for calling into libxenttab.

Paul Durrant (8):
  xen_backend: add grant table helpers
  xen_disk: remove open-coded use of libxengnttab
  xen: remove other open-coded use of libxengnttab
  xen_backend: add an emulation of grant copy
  xen_disk: remove use of grant map/unmap
  xen_backend: make the xen_feature_grant_copy flag private
  xen_disk: use a single entry iovec
  xen_disk: be consistent with use of xendev and blkdev->xendev

 hw/9pfs/xen-9p-backend.c |  32 ++-
 hw/block/xen_disk.c  | 614 +++
 hw/char/xen_console.c|   9 +-
 hw/net/xen_nic.c |  34 ++-
 hw/usb/xen-usb.c |  37 ++-
 hw/xen/xen_backend.c | 178 -
 include/hw/xen/xen_backend.h |  34 ++-
 7 files changed, 351 insertions(+), 587 deletions(-)
---
Cc: Anthony Perard 
Cc: Gerd Hoffmann 
Cc: Greg Kurz 
Cc: Jason Wang 
Cc: Kevin Wolf 
Cc: Max Reitz 
Cc: Paolo Bonzini 
Cc: Stefano Stabellini 

-- 
2.1.4




[Qemu-devel] [PATCH v3 1/8] xen_backend: add grant table helpers

2018-05-04 Thread Paul Durrant
This patch adds grant table helper functions to the xen_backend code to
localize error reporting and use of xen_domid.

The patch also defers the call to xengnttab_open() until just before the
initialise method in XenDevOps is invoked. This method is responsible for
mapping the shared ring. No prior method requires access to the grant table.

Signed-off-by: Paul Durrant 
---
Cc: Stefano Stabellini 
Cc: Anthony Perard 

v2:
 - New in v2
---
 hw/xen/xen_backend.c | 123 ++-
 include/hw/xen/xen_backend.h |  33 
 2 files changed, 144 insertions(+), 12 deletions(-)

diff --git a/hw/xen/xen_backend.c b/hw/xen/xen_backend.c
index 7445b50..50412d6 100644
--- a/hw/xen/xen_backend.c
+++ b/hw/xen/xen_backend.c
@@ -106,6 +106,103 @@ int xen_be_set_state(struct XenDevice *xendev, enum 
xenbus_state state)
 return 0;
 }
 
+void xen_be_set_max_grant_refs(struct XenDevice *xendev,
+   unsigned int nr_refs)
+{
+assert(xendev->ops->flags & DEVOPS_FLAG_NEED_GNTDEV);
+
+if (xengnttab_set_max_grants(xendev->gnttabdev, nr_refs)) {
+xen_pv_printf(xendev, 0, "xengnttab_set_max_grants failed: %s\n",
+  strerror(errno));
+}
+}
+
+void *xen_be_map_grant_refs(struct XenDevice *xendev, uint32_t *refs,
+unsigned int nr_refs, int prot)
+{
+void *ptr;
+
+assert(xendev->ops->flags & DEVOPS_FLAG_NEED_GNTDEV);
+
+ptr = xengnttab_map_domain_grant_refs(xendev->gnttabdev, nr_refs,
+  xen_domid, refs, prot);
+if (!ptr) {
+xen_pv_printf(xendev, 0,
+  "xengnttab_map_domain_grant_refs failed: %s\n",
+  strerror(errno));
+}
+
+return ptr;
+}
+
+void xen_be_unmap_grant_refs(struct XenDevice *xendev, void *ptr,
+ unsigned int nr_refs)
+{
+assert(xendev->ops->flags & DEVOPS_FLAG_NEED_GNTDEV);
+
+if (xengnttab_unmap(xendev->gnttabdev, ptr, nr_refs)) {
+xen_pv_printf(xendev, 0, "xengnttab_unmap failed: %s\n",
+  strerror(errno));
+}
+}
+
+int xen_be_copy_grant_refs(struct XenDevice *xendev,
+   bool to_domain,
+   XenGrantCopySegment segs[],
+   unsigned int nr_segs)
+{
+xengnttab_grant_copy_segment_t *xengnttab_segs;
+unsigned int i;
+int rc;
+
+assert(xendev->ops->flags & DEVOPS_FLAG_NEED_GNTDEV);
+
+xengnttab_segs = g_new0(xengnttab_grant_copy_segment_t, nr_segs);
+
+for (i = 0; i < nr_segs; i++) {
+XenGrantCopySegment *seg = [i];
+xengnttab_grant_copy_segment_t *xengnttab_seg = _segs[i];
+
+if (to_domain) {
+xengnttab_seg->flags = GNTCOPY_dest_gref;
+xengnttab_seg->dest.foreign.domid = xen_domid;
+xengnttab_seg->dest.foreign.ref = seg->dest.foreign.ref;
+xengnttab_seg->dest.foreign.offset = seg->dest.foreign.offset;
+xengnttab_seg->source.virt = seg->source.virt;
+} else {
+xengnttab_seg->flags = GNTCOPY_source_gref;
+xengnttab_seg->source.foreign.domid = xen_domid;
+xengnttab_seg->source.foreign.ref = seg->source.foreign.ref;
+xengnttab_seg->source.foreign.offset =
+seg->source.foreign.offset;
+xengnttab_seg->dest.virt = seg->dest.virt;
+}
+
+xengnttab_seg->len = seg->len;
+}
+
+rc = xengnttab_grant_copy(xendev->gnttabdev, nr_segs, xengnttab_segs);
+
+if (rc) {
+xen_pv_printf(xendev, 0, "xengnttab_copy failed: %s\n",
+  strerror(errno));
+}
+
+for (i = 0; i < nr_segs; i++) {
+xengnttab_grant_copy_segment_t *xengnttab_seg =
+_segs[i];
+
+if (xengnttab_seg->status != GNTST_okay) {
+xen_pv_printf(xendev, 0, "segment[%u] status: %d\n", i,
+  xengnttab_seg->status);
+rc = -1;
+}
+}
+
+g_free(xengnttab_segs);
+return rc;
+}
+
 /*
  * get xen backend device, allocate a new one if it doesn't exist.
  */
@@ -149,18 +246,6 @@ static struct XenDevice *xen_be_get_xendev(const char 
*type, int dom, int dev,
 }
 qemu_set_cloexec(xenevtchn_fd(xendev->evtchndev));
 
-if (ops->flags & DEVOPS_FLAG_NEED_GNTDEV) {
-xendev->gnttabdev = xengnttab_open(NULL, 0);
-if (xendev->gnttabdev == NULL) {
-xen_pv_printf(NULL, 0, "can't open gnttab device\n");
-xenevtchn_close(xendev->evtchndev);
-qdev_unplug(DEVICE(xendev), NULL);
-return NULL;
-}
-} else {
-xendev->gnttabdev = NULL;
-}
-
 xen_pv_insert_xendev(xendev);
 
 if (xendev->ops->alloc) {
@@ -322,6 +407,16 @@ static int xen_be_try_initialise(struct XenDevice *xendev)
 }
 }
 
+

[Qemu-devel] [PATCH v2 08/10] target/arm: Fill in disas_ldst_atomic

2018-05-04 Thread Richard Henderson
This implements all of the v8.1-Atomics instructions except
for compare-and-swap, which is decoded elsewhere.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/arm/translate-a64.c | 38 --
 1 file changed, 36 insertions(+), 2 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 6acad791e6..5af6028089 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -84,6 +84,7 @@ typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
 typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
 typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
 typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
+typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, TCGMemOp);
 
 /* Note that the gvec expanders operate on offsets + sizes.  */
 typedef void GVecGen2Fn(unsigned, uint32_t, uint32_t, uint32_t, uint32_t);
@@ -2772,6 +2773,8 @@ static void disas_ldst_atomic(DisasContext *s, uint32_t 
insn,
 int rn = extract32(insn, 5, 5);
 int o3_opc = extract32(insn, 12, 4);
 int feature = ARM_FEATURE_V8_ATOMICS;
+TCGv_i64 tcg_rn, tcg_rs;
+AtomicThreeOpFn *fn;
 
 if (is_vector) {
 unallocated_encoding(s);
@@ -2779,14 +2782,32 @@ static void disas_ldst_atomic(DisasContext *s, uint32_t 
insn,
 }
 switch (o3_opc) {
 case 000: /* LDADD */
+fn = tcg_gen_atomic_fetch_add_i64;
+break;
 case 001: /* LDCLR */
+fn = tcg_gen_atomic_fetch_and_i64;
+break;
 case 002: /* LDEOR */
+fn = tcg_gen_atomic_fetch_xor_i64;
+break;
 case 003: /* LDSET */
+fn = tcg_gen_atomic_fetch_or_i64;
+break;
 case 004: /* LDSMAX */
+fn = tcg_gen_atomic_fetch_smax_i64;
+break;
 case 005: /* LDSMIN */
+fn = tcg_gen_atomic_fetch_smin_i64;
+break;
 case 006: /* LDUMAX */
+fn = tcg_gen_atomic_fetch_umax_i64;
+break;
 case 007: /* LDUMIN */
+fn = tcg_gen_atomic_fetch_umin_i64;
+break;
 case 010: /* SWP */
+fn = tcg_gen_atomic_xchg_i64;
+break;
 default:
 unallocated_encoding(s);
 return;
@@ -2796,8 +2817,21 @@ static void disas_ldst_atomic(DisasContext *s, uint32_t 
insn,
 return;
 }
 
-(void)rs;
-(void)rn;
+if (rn == 31) {
+gen_check_sp_alignment(s);
+}
+tcg_rn = cpu_reg_sp(s, rn);
+tcg_rs = read_cpu_reg(s, rs, false);
+
+if (o3_opc == 1) { /* LDCLR */
+tcg_gen_not_i64(tcg_rs, tcg_rs);
+}
+
+/* The tcg atomic primitives are all full barriers.  Therefore we
+ * can ignore the Acquire and Release bits of this instruction.
+ */
+fn(cpu_reg(s, rt), tcg_rn, tcg_rs, get_mem_index(s),
+   s->be_data | size | MO_ALIGN);
 }
 
 /* Load/store register (all forms) */
-- 
2.14.3




[Qemu-devel] [PATCH v2 09/10] target/arm: Implement CAS and CASP

2018-05-04 Thread Richard Henderson
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/arm/helper-a64.h|   2 +
 target/arm/helper-a64.c|  43 
 target/arm/translate-a64.c | 119 +++--
 3 files changed, 161 insertions(+), 3 deletions(-)

diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
index ef4ddfe9d8..b8028ac98c 100644
--- a/target/arm/helper-a64.h
+++ b/target/arm/helper-a64.h
@@ -51,6 +51,8 @@ DEF_HELPER_FLAGS_4(paired_cmpxchg64_le_parallel, 
TCG_CALL_NO_WG,
 DEF_HELPER_FLAGS_4(paired_cmpxchg64_be, TCG_CALL_NO_WG, i64, env, i64, i64, 
i64)
 DEF_HELPER_FLAGS_4(paired_cmpxchg64_be_parallel, TCG_CALL_NO_WG,
i64, env, i64, i64, i64)
+DEF_HELPER_5(casp_le_parallel, void, env, i32, i64, i64, i64)
+DEF_HELPER_5(casp_be_parallel, void, env, i32, i64, i64, i64)
 DEF_HELPER_FLAGS_3(advsimd_maxh, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
 DEF_HELPER_FLAGS_3(advsimd_minh, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
 DEF_HELPER_FLAGS_3(advsimd_maxnumh, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
index afb25ad20c..549ed3513e 100644
--- a/target/arm/helper-a64.c
+++ b/target/arm/helper-a64.c
@@ -636,6 +636,49 @@ uint64_t HELPER(paired_cmpxchg64_be_parallel)(CPUARMState 
*env, uint64_t addr,
 return do_paired_cmpxchg64_be(env, addr, new_lo, new_hi, true, GETPC());
 }
 
+/* Writes back the old data into Rs.  */
+void HELPER(casp_le_parallel)(CPUARMState *env, uint32_t rs, uint64_t addr,
+  uint64_t new_lo, uint64_t new_hi)
+{
+uintptr_t ra = GETPC();
+#ifndef CONFIG_ATOMIC128
+cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
+#else
+Int128 oldv, cmpv, newv;
+
+cmpv = int128_make128(env->xregs[rs], env->xregs[rs + 1]);
+newv = int128_make128(new_lo, new_hi);
+
+int mem_idx = cpu_mmu_index(env, false);
+TCGMemOpIdx oi = make_memop_idx(MO_LEQ | MO_ALIGN_16, mem_idx);
+oldv = helper_atomic_cmpxchgo_le_mmu(env, addr, cmpv, newv, oi, ra);
+
+env->xregs[rs] = int128_getlo(oldv);
+env->xregs[rs + 1] = int128_gethi(oldv);
+#endif
+}
+
+void HELPER(casp_be_parallel)(CPUARMState *env, uint32_t rs, uint64_t addr,
+  uint64_t new_hi, uint64_t new_lo)
+{
+uintptr_t ra = GETPC();
+#ifndef CONFIG_ATOMIC128
+cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
+#else
+Int128 oldv, cmpv, newv;
+
+cmpv = int128_make128(env->xregs[rs + 1], env->xregs[rs]);
+newv = int128_make128(new_lo, new_hi);
+
+int mem_idx = cpu_mmu_index(env, false);
+TCGMemOpIdx oi = make_memop_idx(MO_LEQ | MO_ALIGN_16, mem_idx);
+oldv = helper_atomic_cmpxchgo_be_mmu(env, addr, cmpv, newv, oi, ra);
+
+env->xregs[rs + 1] = int128_getlo(oldv);
+env->xregs[rs] = int128_gethi(oldv);
+#endif
+}
+
 /*
  * AdvSIMD half-precision
  */
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 5af6028089..08debc7a93 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -2114,6 +2114,103 @@ static void gen_store_exclusive(DisasContext *s, int 
rd, int rt, int rt2,
 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
 }
 
+static void gen_compare_and_swap(DisasContext *s, int rs, int rt,
+ int rn, int size)
+{
+TCGv_i64 tcg_rs = cpu_reg(s, rs);
+TCGv_i64 tcg_rt = cpu_reg(s, rt);
+int memidx = get_mem_index(s);
+TCGv_i64 addr = cpu_reg_sp(s, rn);
+
+if (rn == 31) {
+gen_check_sp_alignment(s);
+}
+tcg_gen_atomic_cmpxchg_i64(tcg_rs, addr, tcg_rs, tcg_rt, memidx,
+   size | MO_ALIGN | s->be_data);
+}
+
+static void gen_compare_and_swap_pair(DisasContext *s, int rs, int rt,
+  int rn, int size)
+{
+TCGv_i64 s1 = cpu_reg(s, rs);
+TCGv_i64 s2 = cpu_reg(s, rs + 1);
+TCGv_i64 t1 = cpu_reg(s, rt);
+TCGv_i64 t2 = cpu_reg(s, rt + 1);
+TCGv_i64 addr = cpu_reg_sp(s, rn);
+int memidx = get_mem_index(s);
+
+if (rn == 31) {
+gen_check_sp_alignment(s);
+}
+
+if (size == 2) {
+TCGv_i64 cmp = tcg_temp_new_i64();
+TCGv_i64 val = tcg_temp_new_i64();
+
+if (s->be_data == MO_LE) {
+tcg_gen_concat32_i64(val, t1, t2);
+tcg_gen_concat32_i64(cmp, s1, s2);
+} else {
+tcg_gen_concat32_i64(val, t2, t1);
+tcg_gen_concat32_i64(cmp, s2, s1);
+}
+
+tcg_gen_atomic_cmpxchg_i64(cmp, addr, cmp, val, memidx,
+   MO_64 | MO_ALIGN | s->be_data);
+tcg_temp_free_i64(val);
+
+if (s->be_data == MO_LE) {
+tcg_gen_extr32_i64(s1, s2, cmp);
+} else {
+tcg_gen_extr32_i64(s2, s1, cmp);
+}
+tcg_temp_free_i64(cmp);
+} else if (tb_cflags(s->base.tb) & CF_PARALLEL) {
+TCGv_i32 tcg_rs = tcg_const_i32(rs);
+
+if 

[Qemu-devel] [PATCH] handle all fdt_get_phandle_errors

2018-05-04 Thread Jonathan Marler
Signed-off-by: Jonathan Marler 
---
 device_tree.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/device_tree.c b/device_tree.c
index 52c3358..2b75905 100644
--- a/device_tree.c
+++ b/device_tree.c
@@ -379,8 +379,12 @@ uint32_t qemu_fdt_get_phandle(void *fdt, const char
*path)

 r = fdt_get_phandle(fdt, findnode_nofail(fdt, path));
 if (r == 0) {
-error_report("%s: Couldn't get phandle for %s: %s", __func__,
- path, fdt_strerror(r));
+error_report("%s: Node %s does not have a 'phandle'", __func__,
+ path);
+exit(1);
+}
+if (r == -1) {
+error_report("%s: Couldn't get phandle for %s", __func__, path);
 exit(1);
 }

-- 
2.1.4


[Qemu-devel] [PATCH v2 07/10] target/arm: Introduce ARM_FEATURE_V8_ATOMICS and initial decode

2018-05-04 Thread Richard Henderson
The insns in the ARMv8.1-Atomics are added to the existing
load/store exclusive and load/store reg opcode spaces.
Rearrange the top-level decoders for these to accomodate.
The Atomics insns themselves still generate Unallocated.

Signed-off-by: Richard Henderson 
---
 target/arm/cpu.h   |   2 +
 linux-user/elfload.c   |   1 +
 target/arm/translate-a64.c | 182 +
 3 files changed, 139 insertions(+), 46 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 44e6b77151..f71a78d908 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1449,6 +1449,8 @@ enum arm_features {
 ARM_FEATURE_V8_SHA3, /* implements SHA3 part of v8 Crypto Extensions */
 ARM_FEATURE_V8_SM3, /* implements SM3 part of v8 Crypto Extensions */
 ARM_FEATURE_V8_SM4, /* implements SM4 part of v8 Crypto Extensions */
+ARM_FEATURE_V8_1,
+ARM_FEATURE_V8_ATOMICS = ARM_FEATURE_V8_1, /* mandatory extension */
 ARM_FEATURE_V8_RDM, /* implements v8.1 simd round multiply */
 ARM_FEATURE_V8_FP16, /* implements v8.2 half-precision float */
 ARM_FEATURE_V8_FCMA, /* has complex number part of v8.3 extensions.  */
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 36d52194bc..13bc78d0c8 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -581,6 +581,7 @@ static uint32_t get_elf_hwcap(void)
 GET_FEATURE(ARM_FEATURE_V8_SHA512, ARM_HWCAP_A64_SHA512);
 GET_FEATURE(ARM_FEATURE_V8_FP16,
 ARM_HWCAP_A64_FPHP | ARM_HWCAP_A64_ASIMDHP);
+GET_FEATURE(ARM_FEATURE_V8_ATOMICS, ARM_HWCAP_A64_ATOMICS);
 GET_FEATURE(ARM_FEATURE_V8_RDM, ARM_HWCAP_A64_ASIMDRDM);
 GET_FEATURE(ARM_FEATURE_V8_FCMA, ARM_HWCAP_A64_FCMA);
 #undef GET_FEATURE
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index d916fea3a3..6acad791e6 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -2147,62 +2147,98 @@ static void disas_ldst_excl(DisasContext *s, uint32_t 
insn)
 int rt = extract32(insn, 0, 5);
 int rn = extract32(insn, 5, 5);
 int rt2 = extract32(insn, 10, 5);
-int is_lasr = extract32(insn, 15, 1);
 int rs = extract32(insn, 16, 5);
-int is_pair = extract32(insn, 21, 1);
-int is_store = !extract32(insn, 22, 1);
-int is_excl = !extract32(insn, 23, 1);
+int is_lasr = extract32(insn, 15, 1);
+int o2_L_o1_o0 = extract32(insn, 21, 3) * 2 | is_lasr;
 int size = extract32(insn, 30, 2);
 TCGv_i64 tcg_addr;
 
-if ((!is_excl && !is_pair && !is_lasr) ||
-(!is_excl && is_pair) ||
-(is_pair && size < 2)) {
-unallocated_encoding(s);
+switch (o2_L_o1_o0) {
+case 0x0: /* STXR */
+case 0x1: /* STLXR */
+if (rn == 31) {
+gen_check_sp_alignment(s);
+}
+if (is_lasr) {
+tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
+}
+tcg_addr = read_cpu_reg_sp(s, rn, 1);
+gen_store_exclusive(s, rs, rt, rt2, tcg_addr, size, false);
 return;
-}
 
-if (rn == 31) {
-gen_check_sp_alignment(s);
-}
-tcg_addr = read_cpu_reg_sp(s, rn, 1);
-
-/* Note that since TCG is single threaded load-acquire/store-release
- * semantics require no extra if (is_lasr) { ... } handling.
- */
-
-if (is_excl) {
-if (!is_store) {
-s->is_ldex = true;
-gen_load_exclusive(s, rt, rt2, tcg_addr, size, is_pair);
-if (is_lasr) {
-tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
-}
-} else {
-if (is_lasr) {
-tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
-}
-gen_store_exclusive(s, rs, rt, rt2, tcg_addr, size, is_pair);
+case 0x4: /* LDXR */
+case 0x5: /* LDAXR */
+if (rn == 31) {
+gen_check_sp_alignment(s);
 }
-} else {
-TCGv_i64 tcg_rt = cpu_reg(s, rt);
-bool iss_sf = disas_ldst_compute_iss_sf(size, false, 0);
+tcg_addr = read_cpu_reg_sp(s, rn, 1);
+s->is_ldex = true;
+gen_load_exclusive(s, rt, rt2, tcg_addr, size, false);
+if (is_lasr) {
+tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
+}
+return;
 
+case 0x9: /* STLR */
 /* Generate ISS for non-exclusive accesses including LASR.  */
-if (is_store) {
+if (rn == 31) {
+gen_check_sp_alignment(s);
+}
+tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
+tcg_addr = read_cpu_reg_sp(s, rn, 1);
+do_gpr_st(s, cpu_reg(s, rt), tcg_addr, size, true, rt,
+  disas_ldst_compute_iss_sf(size, false, 0), is_lasr);
+return;
+
+case 0xd: /* LDAR */
+/* Generate ISS for non-exclusive accesses including LASR.  */
+if (rn == 31) {
+gen_check_sp_alignment(s);
+}
+tcg_addr = read_cpu_reg_sp(s, rn, 1);
+do_gpr_ld(s, cpu_reg(s, rt), tcg_addr, size, false, 

[Qemu-devel] [PATCH v2 04/10] tcg: Introduce atomic helpers for integer min/max

2018-05-04 Thread Richard Henderson
Given that this atomic operation will be used by both risc-v
and aarch64, let's not duplicate code across the two targets.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 accel/tcg/atomic_template.h | 71 +
 accel/tcg/tcg-runtime.h |  8 +
 tcg/tcg-op.h| 34 ++
 tcg/tcg.h   |  8 +
 tcg/tcg-op.c|  8 +
 5 files changed, 129 insertions(+)

diff --git a/accel/tcg/atomic_template.h b/accel/tcg/atomic_template.h
index e022df4571..2489dd3ec1 100644
--- a/accel/tcg/atomic_template.h
+++ b/accel/tcg/atomic_template.h
@@ -25,18 +25,22 @@
 #elif DATA_SIZE == 8
 # define SUFFIX q
 # define DATA_TYPE  uint64_t
+# define SDATA_TYPE int64_t
 # define BSWAP  bswap64
 #elif DATA_SIZE == 4
 # define SUFFIX l
 # define DATA_TYPE  uint32_t
+# define SDATA_TYPE int32_t
 # define BSWAP  bswap32
 #elif DATA_SIZE == 2
 # define SUFFIX w
 # define DATA_TYPE  uint16_t
+# define SDATA_TYPE int16_t
 # define BSWAP  bswap16
 #elif DATA_SIZE == 1
 # define SUFFIX b
 # define DATA_TYPE  uint8_t
+# define SDATA_TYPE int8_t
 # define BSWAP
 #else
 # error unsupported data size
@@ -118,6 +122,39 @@ GEN_ATOMIC_HELPER(or_fetch)
 GEN_ATOMIC_HELPER(xor_fetch)
 
 #undef GEN_ATOMIC_HELPER
+
+/* These helpers are, as a whole, full barriers.  Within the helper,
+ * the leading barrier is explicit and the trailing barrier is within
+ * cmpxchg primitive.
+ */
+#define GEN_ATOMIC_HELPER_FN(X, FN, XDATA_TYPE, RET)\
+ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr,   \
+ABI_TYPE xval EXTRA_ARGS)   \
+{   \
+ATOMIC_MMU_DECLS;   \
+XDATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;  \
+XDATA_TYPE cmp, old, new, val = xval;   \
+smp_mb();   \
+cmp = atomic_read__nocheck(haddr);  \
+do {\
+old = cmp; new = FN(old, val);  \
+cmp = atomic_cmpxchg__nocheck(haddr, old, new); \
+} while (cmp != old);   \
+ATOMIC_MMU_CLEANUP; \
+return RET; \
+}
+
+GEN_ATOMIC_HELPER_FN(fetch_smin, MIN, SDATA_TYPE, old)
+GEN_ATOMIC_HELPER_FN(fetch_umin, MIN,  DATA_TYPE, old)
+GEN_ATOMIC_HELPER_FN(fetch_smax, MAX, SDATA_TYPE, old)
+GEN_ATOMIC_HELPER_FN(fetch_umax, MAX,  DATA_TYPE, old)
+
+GEN_ATOMIC_HELPER_FN(smin_fetch, MIN, SDATA_TYPE, new)
+GEN_ATOMIC_HELPER_FN(umin_fetch, MIN,  DATA_TYPE, new)
+GEN_ATOMIC_HELPER_FN(smax_fetch, MAX, SDATA_TYPE, new)
+GEN_ATOMIC_HELPER_FN(umax_fetch, MAX,  DATA_TYPE, new)
+
+#undef GEN_ATOMIC_HELPER_FN
 #endif /* DATA SIZE >= 16 */
 
 #undef END
@@ -233,6 +270,39 @@ ABI_TYPE ATOMIC_NAME(add_fetch)(CPUArchState *env, 
target_ulong addr,
 ldo = ldn;
 }
 }
+
+/* These helpers are, as a whole, full barriers.  Within the helper,
+ * the leading barrier is explicit and the trailing barrier is within
+ * cmpxchg primitive.
+ */
+#define GEN_ATOMIC_HELPER_FN(X, FN, XDATA_TYPE, RET)\
+ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr,   \
+ABI_TYPE xval EXTRA_ARGS)   \
+{   \
+ATOMIC_MMU_DECLS;   \
+XDATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;  \
+XDATA_TYPE ldo, ldn, old, new, val = xval;  \
+smp_mb();   \
+ldn = atomic_read__nocheck(haddr);  \
+do {\
+ldo = ldn; old = BSWAP(ldo); new = FN(old, val);\
+ldn = atomic_cmpxchg__nocheck(haddr, ldo, BSWAP(new));  \
+} while (ldo != ldn);   \
+ATOMIC_MMU_CLEANUP; \
+return RET; \
+}
+
+GEN_ATOMIC_HELPER_FN(fetch_smin, MIN, SDATA_TYPE, old)
+GEN_ATOMIC_HELPER_FN(fetch_umin, MIN,  DATA_TYPE, old)
+GEN_ATOMIC_HELPER_FN(fetch_smax, MAX, SDATA_TYPE, old)
+GEN_ATOMIC_HELPER_FN(fetch_umax, MAX,  DATA_TYPE, old)
+
+GEN_ATOMIC_HELPER_FN(smin_fetch, MIN, SDATA_TYPE, new)
+GEN_ATOMIC_HELPER_FN(umin_fetch, MIN,  DATA_TYPE, new)
+GEN_ATOMIC_HELPER_FN(smax_fetch, MAX, SDATA_TYPE, new)
+GEN_ATOMIC_HELPER_FN(umax_fetch, MAX,  DATA_TYPE, new)
+
+#undef 

[Qemu-devel] [PATCH v2 10/10] target/arm: Enable ARM_FEATURE_V8_ATOMICS for user-only

2018-05-04 Thread Richard Henderson
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/arm/cpu64.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 991d764674..c50dcd4077 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -248,6 +248,7 @@ static void aarch64_max_initfn(Object *obj)
 set_feature(>env, ARM_FEATURE_V8_SM4);
 set_feature(>env, ARM_FEATURE_V8_PMULL);
 set_feature(>env, ARM_FEATURE_CRC);
+set_feature(>env, ARM_FEATURE_V8_ATOMICS);
 set_feature(>env, ARM_FEATURE_V8_RDM);
 set_feature(>env, ARM_FEATURE_V8_FP16);
 set_feature(>env, ARM_FEATURE_V8_FCMA);
-- 
2.14.3




[Qemu-devel] [PATCH v2 03/10] target/xtensa: Use new min/max expanders

2018-05-04 Thread Richard Henderson
The generic expanders replace nearly identical code in the translator.

Acked-by: Max Filippov 
Signed-off-by: Richard Henderson 
---
 target/xtensa/translate.c | 50 +++
 1 file changed, 33 insertions(+), 17 deletions(-)

diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c
index 4f6d03059f..bad5cdb009 100644
--- a/target/xtensa/translate.c
+++ b/target/xtensa/translate.c
@@ -1527,10 +1527,8 @@ static void translate_clamps(DisasContext *dc, const 
uint32_t arg[],
 TCGv_i32 tmp1 = tcg_const_i32(-1u << arg[2]);
 TCGv_i32 tmp2 = tcg_const_i32((1 << arg[2]) - 1);
 
-tcg_gen_movcond_i32(TCG_COND_GT, tmp1,
-cpu_R[arg[1]], tmp1, cpu_R[arg[1]], tmp1);
-tcg_gen_movcond_i32(TCG_COND_LT, cpu_R[arg[0]],
-tmp1, tmp2, tmp1, tmp2);
+tcg_gen_smax_i32(tmp1, tmp1, cpu_R[arg[1]]);
+tcg_gen_smin_i32(cpu_R[arg[0]], tmp1, tmp2);
 tcg_temp_free(tmp1);
 tcg_temp_free(tmp2);
 }
@@ -1855,13 +1853,35 @@ static void translate_memw(DisasContext *dc, const 
uint32_t arg[],
 tcg_gen_mb(TCG_BAR_SC | TCG_MO_ALL);
 }
 
-static void translate_minmax(DisasContext *dc, const uint32_t arg[],
- const uint32_t par[])
+static void translate_smin(DisasContext *dc, const uint32_t arg[],
+   const uint32_t par[])
 {
 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
-tcg_gen_movcond_i32(par[0], cpu_R[arg[0]],
-cpu_R[arg[1]], cpu_R[arg[2]],
-cpu_R[arg[1]], cpu_R[arg[2]]);
+tcg_gen_smin_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
+}
+}
+
+static void translate_umin(DisasContext *dc, const uint32_t arg[],
+   const uint32_t par[])
+{
+if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
+tcg_gen_umin_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
+}
+}
+
+static void translate_smax(DisasContext *dc, const uint32_t arg[],
+   const uint32_t par[])
+{
+if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
+tcg_gen_smax_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
+}
+}
+
+static void translate_umax(DisasContext *dc, const uint32_t arg[],
+   const uint32_t par[])
+{
+if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
+tcg_gen_umax_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
 }
 }
 
@@ -2984,23 +3004,19 @@ static const XtensaOpcodeOps core_ops[] = {
 .par = (const uint32_t[]){TCG_COND_NE},
 }, {
 .name = "max",
-.translate = translate_minmax,
-.par = (const uint32_t[]){TCG_COND_GE},
+.translate = translate_smax,
 }, {
 .name = "maxu",
-.translate = translate_minmax,
-.par = (const uint32_t[]){TCG_COND_GEU},
+.translate = translate_umax,
 }, {
 .name = "memw",
 .translate = translate_memw,
 }, {
 .name = "min",
-.translate = translate_minmax,
-.par = (const uint32_t[]){TCG_COND_LT},
+.translate = translate_smin,
 }, {
 .name = "minu",
-.translate = translate_minmax,
-.par = (const uint32_t[]){TCG_COND_LTU},
+.translate = translate_umin,
 }, {
 .name = "mov",
 .translate = translate_mov,
-- 
2.14.3




[Qemu-devel] [PATCH v2 05/10] tcg: Use GEN_ATOMIC_HELPER_FN for opposite endian atomic add

2018-05-04 Thread Richard Henderson
Suggested-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 accel/tcg/atomic_template.h | 49 +++--
 1 file changed, 7 insertions(+), 42 deletions(-)

diff --git a/accel/tcg/atomic_template.h b/accel/tcg/atomic_template.h
index 2489dd3ec1..3f41ef2782 100644
--- a/accel/tcg/atomic_template.h
+++ b/accel/tcg/atomic_template.h
@@ -229,48 +229,6 @@ GEN_ATOMIC_HELPER(xor_fetch)
 
 #undef GEN_ATOMIC_HELPER
 
-/* Note that for addition, we need to use a separate cmpxchg loop instead
-   of bswaps for the reverse-host-endian helpers.  */
-ABI_TYPE ATOMIC_NAME(fetch_add)(CPUArchState *env, target_ulong addr,
- ABI_TYPE val EXTRA_ARGS)
-{
-ATOMIC_MMU_DECLS;
-DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
-DATA_TYPE ldo, ldn, ret, sto;
-
-ldo = atomic_read__nocheck(haddr);
-while (1) {
-ret = BSWAP(ldo);
-sto = BSWAP(ret + val);
-ldn = atomic_cmpxchg__nocheck(haddr, ldo, sto);
-if (ldn == ldo) {
-ATOMIC_MMU_CLEANUP;
-return ret;
-}
-ldo = ldn;
-}
-}
-
-ABI_TYPE ATOMIC_NAME(add_fetch)(CPUArchState *env, target_ulong addr,
- ABI_TYPE val EXTRA_ARGS)
-{
-ATOMIC_MMU_DECLS;
-DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
-DATA_TYPE ldo, ldn, ret, sto;
-
-ldo = atomic_read__nocheck(haddr);
-while (1) {
-ret = BSWAP(ldo) + val;
-sto = BSWAP(ret);
-ldn = atomic_cmpxchg__nocheck(haddr, ldo, sto);
-if (ldn == ldo) {
-ATOMIC_MMU_CLEANUP;
-return ret;
-}
-ldo = ldn;
-}
-}
-
 /* These helpers are, as a whole, full barriers.  Within the helper,
  * the leading barrier is explicit and the trailing barrier is within
  * cmpxchg primitive.
@@ -302,6 +260,13 @@ GEN_ATOMIC_HELPER_FN(umin_fetch, MIN,  DATA_TYPE, new)
 GEN_ATOMIC_HELPER_FN(smax_fetch, MAX, SDATA_TYPE, new)
 GEN_ATOMIC_HELPER_FN(umax_fetch, MAX,  DATA_TYPE, new)
 
+/* Note that for addition, we need to use a separate cmpxchg loop instead
+   of bswaps for the reverse-host-endian helpers.  */
+#define ADD(X, Y)   (X + Y)
+GEN_ATOMIC_HELPER_FN(fetch_add, ADD, DATA_TYPE, old)
+GEN_ATOMIC_HELPER_FN(add_fetch, ADD, DATA_TYPE, new)
+#undef ADD
+
 #undef GEN_ATOMIC_HELPER_FN
 #endif /* DATA_SIZE >= 16 */
 
-- 
2.14.3




[Qemu-devel] [PATCH v2 06/10] target/riscv: Use new atomic min/max expanders

2018-05-04 Thread Richard Henderson
Reviewed-by: Michael Clark 
Signed-off-by: Richard Henderson 
---
 target/riscv/translate.c | 72 ++--
 1 file changed, 20 insertions(+), 52 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 808eab7f50..9cab717088 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -725,7 +725,6 @@ static void gen_atomic(DisasContext *ctx, uint32_t opc,
 TCGv src1, src2, dat;
 TCGLabel *l1, *l2;
 TCGMemOp mop;
-TCGCond cond;
 bool aq, rl;
 
 /* Extract the size of the atomic operation.  */
@@ -823,60 +822,29 @@ static void gen_atomic(DisasContext *ctx, uint32_t opc,
 tcg_gen_atomic_fetch_or_tl(src2, src1, src2, ctx->mem_idx, mop);
 gen_set_gpr(rd, src2);
 break;
-
 case OPC_RISC_AMOMIN:
-cond = TCG_COND_LT;
-goto do_minmax;
-case OPC_RISC_AMOMAX:
-cond = TCG_COND_GT;
-goto do_minmax;
-case OPC_RISC_AMOMINU:
-cond = TCG_COND_LTU;
-goto do_minmax;
-case OPC_RISC_AMOMAXU:
-cond = TCG_COND_GTU;
-goto do_minmax;
-do_minmax:
-/* Handle the RL barrier.  The AQ barrier is handled along the
-   parallel path by the SC atomic cmpxchg.  On the serial path,
-   of course, barriers do not matter.  */
-if (rl) {
-tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
-}
-if (tb_cflags(ctx->tb) & CF_PARALLEL) {
-l1 = gen_new_label();
-gen_set_label(l1);
-} else {
-l1 = NULL;
-}
-
 gen_get_gpr(src1, rs1);
 gen_get_gpr(src2, rs2);
-if ((mop & MO_SSIZE) == MO_SL) {
-/* Sign-extend the register comparison input.  */
-tcg_gen_ext32s_tl(src2, src2);
-}
-dat = tcg_temp_local_new();
-tcg_gen_qemu_ld_tl(dat, src1, ctx->mem_idx, mop);
-tcg_gen_movcond_tl(cond, src2, dat, src2, dat, src2);
-
-if (tb_cflags(ctx->tb) & CF_PARALLEL) {
-/* Parallel context.  Make this operation atomic by verifying
-   that the memory didn't change while we computed the result.  */
-tcg_gen_atomic_cmpxchg_tl(src2, src1, dat, src2, ctx->mem_idx, 
mop);
-
-/* If the cmpxchg failed, retry. */
-/* ??? There is an assumption here that this will eventually
-   succeed, such that we don't live-lock.  This is not unlike
-   a similar loop that the compiler would generate for e.g.
-   __atomic_fetch_and_xor, so don't worry about it.  */
-tcg_gen_brcond_tl(TCG_COND_NE, dat, src2, l1);
-} else {
-/* Serial context.  Directly store the result.  */
-tcg_gen_qemu_st_tl(src2, src1, ctx->mem_idx, mop);
-}
-gen_set_gpr(rd, dat);
-tcg_temp_free(dat);
+tcg_gen_atomic_fetch_smin_tl(src2, src1, src2, ctx->mem_idx, mop);
+gen_set_gpr(rd, src2);
+break;
+case OPC_RISC_AMOMAX:
+gen_get_gpr(src1, rs1);
+gen_get_gpr(src2, rs2);
+tcg_gen_atomic_fetch_smax_tl(src2, src1, src2, ctx->mem_idx, mop);
+gen_set_gpr(rd, src2);
+break;
+case OPC_RISC_AMOMINU:
+gen_get_gpr(src1, rs1);
+gen_get_gpr(src2, rs2);
+tcg_gen_atomic_fetch_umin_tl(src2, src1, src2, ctx->mem_idx, mop);
+gen_set_gpr(rd, src2);
+break;
+case OPC_RISC_AMOMAXU:
+gen_get_gpr(src1, rs1);
+gen_get_gpr(src2, rs2);
+tcg_gen_atomic_fetch_umax_tl(src2, src1, src2, ctx->mem_idx, mop);
+gen_set_gpr(rd, src2);
 break;
 
 default:
-- 
2.14.3




[Qemu-devel] [PATCH v2 02/10] target/arm: Use new min/max expanders

2018-05-04 Thread Richard Henderson
The generic expanders replace nearly identical code in the translator.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/arm/translate-a64.c | 46 ++
 1 file changed, 14 insertions(+), 32 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index bff4e13bf6..d916fea3a3 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -6021,15 +6021,18 @@ static void disas_simd_across_lanes(DisasContext *s, 
uint32_t insn)
 tcg_gen_add_i64(tcg_res, tcg_res, tcg_elt);
 break;
 case 0x0a: /* SMAXV / UMAXV */
-tcg_gen_movcond_i64(is_u ? TCG_COND_GEU : TCG_COND_GE,
-tcg_res,
-tcg_res, tcg_elt, tcg_res, tcg_elt);
+if (is_u) {
+tcg_gen_umax_i64(tcg_res, tcg_res, tcg_elt);
+} else {
+tcg_gen_smax_i64(tcg_res, tcg_res, tcg_elt);
+}
 break;
 case 0x1a: /* SMINV / UMINV */
-tcg_gen_movcond_i64(is_u ? TCG_COND_LEU : TCG_COND_LE,
-tcg_res,
-tcg_res, tcg_elt, tcg_res, tcg_elt);
-break;
+if (is_u) {
+tcg_gen_umin_i64(tcg_res, tcg_res, tcg_elt);
+} else {
+tcg_gen_smin_i64(tcg_res, tcg_res, tcg_elt);
+}
 break;
 default:
 g_assert_not_reached();
@@ -9931,27 +9934,6 @@ static void disas_simd_3same_logic(DisasContext *s, 
uint32_t insn)
 }
 }
 
-/* Helper functions for 32 bit comparisons */
-static void gen_max_s32(TCGv_i32 res, TCGv_i32 op1, TCGv_i32 op2)
-{
-tcg_gen_movcond_i32(TCG_COND_GE, res, op1, op2, op1, op2);
-}
-
-static void gen_max_u32(TCGv_i32 res, TCGv_i32 op1, TCGv_i32 op2)
-{
-tcg_gen_movcond_i32(TCG_COND_GEU, res, op1, op2, op1, op2);
-}
-
-static void gen_min_s32(TCGv_i32 res, TCGv_i32 op1, TCGv_i32 op2)
-{
-tcg_gen_movcond_i32(TCG_COND_LE, res, op1, op2, op1, op2);
-}
-
-static void gen_min_u32(TCGv_i32 res, TCGv_i32 op1, TCGv_i32 op2)
-{
-tcg_gen_movcond_i32(TCG_COND_LEU, res, op1, op2, op1, op2);
-}
-
 /* Pairwise op subgroup of C3.6.16.
  *
  * This is called directly or via the handle_3same_float for float pairwise
@@ -10051,7 +10033,7 @@ static void handle_simd_3same_pair(DisasContext *s, int 
is_q, int u, int opcode,
 static NeonGenTwoOpFn * const fns[3][2] = {
 { gen_helper_neon_pmax_s8, gen_helper_neon_pmax_u8 },
 { gen_helper_neon_pmax_s16, gen_helper_neon_pmax_u16 },
-{ gen_max_s32, gen_max_u32 },
+{ tcg_gen_smax_i32, tcg_gen_umax_i32 },
 };
 genfn = fns[size][u];
 break;
@@ -10061,7 +10043,7 @@ static void handle_simd_3same_pair(DisasContext *s, int 
is_q, int u, int opcode,
 static NeonGenTwoOpFn * const fns[3][2] = {
 { gen_helper_neon_pmin_s8, gen_helper_neon_pmin_u8 },
 { gen_helper_neon_pmin_s16, gen_helper_neon_pmin_u16 },
-{ gen_min_s32, gen_min_u32 },
+{ tcg_gen_smin_i32, tcg_gen_umin_i32 },
 };
 genfn = fns[size][u];
 break;
@@ -10516,7 +10498,7 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
 static NeonGenTwoOpFn * const fns[3][2] = {
 { gen_helper_neon_max_s8, gen_helper_neon_max_u8 },
 { gen_helper_neon_max_s16, gen_helper_neon_max_u16 },
-{ gen_max_s32, gen_max_u32 },
+{ tcg_gen_smax_i32, tcg_gen_umax_i32 },
 };
 genfn = fns[size][u];
 break;
@@ -10527,7 +10509,7 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
 static NeonGenTwoOpFn * const fns[3][2] = {
 { gen_helper_neon_min_s8, gen_helper_neon_min_u8 },
 { gen_helper_neon_min_s16, gen_helper_neon_min_u16 },
-{ gen_min_s32, gen_min_u32 },
+{ tcg_gen_smin_i32, tcg_gen_umin_i32 },
 };
 genfn = fns[size][u];
 break;
-- 
2.14.3




[Qemu-devel] [PATCH v2 00/10] target/arm: Implement v8.1-Atomics

2018-05-04 Thread Richard Henderson
This implements the Atomics extension, which is mandatory for v8.1.
While testing the v8.2-SVE extension, I've run into issues with the
GCC testsuite expecting this to exist.

Missing is the wiring up of the system registers to indicate that
the extension exists, but we have no system CPU model that would
exercise such a setting.

Changes since v2:
  * New patch to use a helper macro for opposite-endian
atomic_fetch_add and atomic_add_fetch, as suggested
by pm215.
  * Introduce ARM_FEATURE_V8_1 and define ARM_FEATURE_V8_ATOMICS
in terms of that, reinforcing the mandatory nature of
the extension.
  * Typo fix in patch 8.


Peter, do you want to take the whole thing into target-arm.next,
or have it split?  We have a review and an ack for the riscv and
xtensa patches.


r~


Richard Henderson (10):
  tcg: Introduce helpers for integer min/max
  target/arm: Use new min/max expanders
  target/xtensa: Use new min/max expanders
  tcg: Introduce atomic helpers for integer min/max
  tcg: Use GEN_ATOMIC_HELPER_FN for opposite endian atomic add
  target/riscv: Use new atomic min/max expanders
  target/arm: Introduce ARM_FEATURE_V8_ATOMICS and initial decode
  target/arm: Fill in disas_ldst_atomic
  target/arm: Implement CAS and CASP
  target/arm: Enable ARM_FEATURE_V8_ATOMICS for user-only

 accel/tcg/atomic_template.h | 112 -
 accel/tcg/tcg-runtime.h |   8 +
 target/arm/cpu.h|   2 +
 target/arm/helper-a64.h |   2 +
 tcg/tcg-op.h|  50 ++
 tcg/tcg.h   |   8 +
 linux-user/elfload.c|   1 +
 target/arm/cpu64.c  |   1 +
 target/arm/helper-a64.c |  43 +
 target/arm/translate-a64.c  | 375 +++-
 target/riscv/translate.c|  72 +++--
 target/xtensa/translate.c   |  50 --
 tcg/tcg-op.c|  48 ++
 13 files changed, 587 insertions(+), 185 deletions(-)

-- 
2.14.3




[Qemu-devel] [PATCH v2 01/10] tcg: Introduce helpers for integer min/max

2018-05-04 Thread Richard Henderson
These operations are re-invented by several targets so far.
Several supported hosts have insns for these, so place the
expanders out-of-line for a future introduction of tcg opcodes.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 tcg/tcg-op.h | 16 
 tcg/tcg-op.c | 40 
 2 files changed, 56 insertions(+)

diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index 5d2c91a1b6..0451e2752e 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -324,6 +324,10 @@ void tcg_gen_ext8u_i32(TCGv_i32 ret, TCGv_i32 arg);
 void tcg_gen_ext16u_i32(TCGv_i32 ret, TCGv_i32 arg);
 void tcg_gen_bswap16_i32(TCGv_i32 ret, TCGv_i32 arg);
 void tcg_gen_bswap32_i32(TCGv_i32 ret, TCGv_i32 arg);
+void tcg_gen_smin_i32(TCGv_i32, TCGv_i32 arg1, TCGv_i32 arg2);
+void tcg_gen_smax_i32(TCGv_i32, TCGv_i32 arg1, TCGv_i32 arg2);
+void tcg_gen_umin_i32(TCGv_i32, TCGv_i32 arg1, TCGv_i32 arg2);
+void tcg_gen_umax_i32(TCGv_i32, TCGv_i32 arg1, TCGv_i32 arg2);
 
 static inline void tcg_gen_discard_i32(TCGv_i32 arg)
 {
@@ -517,6 +521,10 @@ void tcg_gen_ext32u_i64(TCGv_i64 ret, TCGv_i64 arg);
 void tcg_gen_bswap16_i64(TCGv_i64 ret, TCGv_i64 arg);
 void tcg_gen_bswap32_i64(TCGv_i64 ret, TCGv_i64 arg);
 void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg);
+void tcg_gen_smin_i64(TCGv_i64, TCGv_i64 arg1, TCGv_i64 arg2);
+void tcg_gen_smax_i64(TCGv_i64, TCGv_i64 arg1, TCGv_i64 arg2);
+void tcg_gen_umin_i64(TCGv_i64, TCGv_i64 arg1, TCGv_i64 arg2);
+void tcg_gen_umax_i64(TCGv_i64, TCGv_i64 arg1, TCGv_i64 arg2);
 
 #if TCG_TARGET_REG_BITS == 64
 static inline void tcg_gen_discard_i64(TCGv_i64 arg)
@@ -1025,6 +1033,10 @@ void tcg_gen_stl_vec(TCGv_vec r, TCGv_ptr base, TCGArg 
offset, TCGType t);
 #define tcg_gen_mulu2_tl tcg_gen_mulu2_i64
 #define tcg_gen_muls2_tl tcg_gen_muls2_i64
 #define tcg_gen_mulsu2_tl tcg_gen_mulsu2_i64
+#define tcg_gen_smin_tl tcg_gen_smin_i64
+#define tcg_gen_umin_tl tcg_gen_umin_i64
+#define tcg_gen_smax_tl tcg_gen_smax_i64
+#define tcg_gen_umax_tl tcg_gen_umax_i64
 #define tcg_gen_atomic_cmpxchg_tl tcg_gen_atomic_cmpxchg_i64
 #define tcg_gen_atomic_xchg_tl tcg_gen_atomic_xchg_i64
 #define tcg_gen_atomic_fetch_add_tl tcg_gen_atomic_fetch_add_i64
@@ -1123,6 +1135,10 @@ void tcg_gen_stl_vec(TCGv_vec r, TCGv_ptr base, TCGArg 
offset, TCGType t);
 #define tcg_gen_mulu2_tl tcg_gen_mulu2_i32
 #define tcg_gen_muls2_tl tcg_gen_muls2_i32
 #define tcg_gen_mulsu2_tl tcg_gen_mulsu2_i32
+#define tcg_gen_smin_tl tcg_gen_smin_i32
+#define tcg_gen_umin_tl tcg_gen_umin_i32
+#define tcg_gen_smax_tl tcg_gen_smax_i32
+#define tcg_gen_umax_tl tcg_gen_umax_i32
 #define tcg_gen_atomic_cmpxchg_tl tcg_gen_atomic_cmpxchg_i32
 #define tcg_gen_atomic_xchg_tl tcg_gen_atomic_xchg_i32
 #define tcg_gen_atomic_fetch_add_tl tcg_gen_atomic_fetch_add_i32
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
index 34b96d68f3..5b82c3be8d 100644
--- a/tcg/tcg-op.c
+++ b/tcg/tcg-op.c
@@ -1033,6 +1033,26 @@ void tcg_gen_bswap32_i32(TCGv_i32 ret, TCGv_i32 arg)
 }
 }
 
+void tcg_gen_smin_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b)
+{
+tcg_gen_movcond_i32(TCG_COND_LT, ret, a, b, a, b);
+}
+
+void tcg_gen_umin_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b)
+{
+tcg_gen_movcond_i32(TCG_COND_LTU, ret, a, b, a, b);
+}
+
+void tcg_gen_smax_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b)
+{
+tcg_gen_movcond_i32(TCG_COND_LT, ret, a, b, b, a);
+}
+
+void tcg_gen_umax_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b)
+{
+tcg_gen_movcond_i32(TCG_COND_LTU, ret, a, b, b, a);
+}
+
 /* 64-bit ops */
 
 #if TCG_TARGET_REG_BITS == 32
@@ -2438,6 +2458,26 @@ void tcg_gen_mulsu2_i64(TCGv_i64 rl, TCGv_i64 rh, 
TCGv_i64 arg1, TCGv_i64 arg2)
 tcg_temp_free_i64(t2);
 }
 
+void tcg_gen_smin_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b)
+{
+tcg_gen_movcond_i64(TCG_COND_LT, ret, a, b, a, b);
+}
+
+void tcg_gen_umin_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b)
+{
+tcg_gen_movcond_i64(TCG_COND_LTU, ret, a, b, a, b);
+}
+
+void tcg_gen_smax_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b)
+{
+tcg_gen_movcond_i64(TCG_COND_LT, ret, a, b, b, a);
+}
+
+void tcg_gen_umax_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b)
+{
+tcg_gen_movcond_i64(TCG_COND_LTU, ret, a, b, b, a);
+}
+
 /* Size changing operations.  */
 
 void tcg_gen_extrl_i64_i32(TCGv_i32 ret, TCGv_i64 arg)
-- 
2.14.3




Re: [Qemu-devel] [PATCH] monitor: report entirety of hmp command on error

2018-05-04 Thread Eric Blake

On 05/04/2018 09:49 AM, Collin Walling wrote:

When a user incorrectly provides an hmp command, an error response will be
printed that prompts the user to try "help ". However, when
the command contains multiple parts e.g. "info skeys", only the last
whitespace delimited string will be reported (in this example "info" will
be dropped and the message will read "Try "help skeys" for more information",
which is incorrect).

Let's correct this by capturing the full name of the command as we recurse
through the function monitor_parse_command.

Reported-by: Mikhail Fokin 
Signed-off-by: Collin Walling 


Side note:

git shortlog --author=Collin

lists two different spellings for your name based on your previous 
contributions.  You may want to propose a patch to .mailmap to settle on 
the variant that you prefer, so that people grabbing statistics from git 
don't get as confused.


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



Re: [Qemu-devel] [PATCH] monitor: report entirety of hmp command on error

2018-05-04 Thread Eric Blake

On 05/04/2018 01:02 PM, Collin Walling wrote:


So rather than trying to reconstruct a string, you could reuse what you already 
have.  This is a shorter patch that I think accomplishes the same goal:

diff --git i/monitor.c w/monitor.c
index 39f8ee17ba7..38736b3a20d 100644
--- i/monitor.c
+++ w/monitor.c
@@ -3371,6 +3371,7 @@ static void handle_hmp_command(Monitor *mon, const char 
*cmdline)
  {
  QDict *qdict;
  const mon_cmd_t *cmd;
+    const char *cmd_start = cmdline;

  trace_handle_hmp_command(mon, cmdline);

@@ -3381,8 +3382,11 @@ static void handle_hmp_command(Monitor *mon, const char 
*cmdline)

  qdict = monitor_parse_arguments(mon, , cmd);
  if (!qdict) {
-    monitor_printf(mon, "Try \"help %s\" for more information\n",
-   cmd->name);
+    while (cmdline > cmd_start && qemu_isspace(cmdline[-1])) {
+    cmdline--;
+    }
+    monitor_printf(mon, "Try \"help %.*s\" for more information\n",
+   (int)(cmdline - cmd_start), cmd_start);
  return;
  }





Very interesting... you managed to reuse what was in cmdline without printing 
anything extraneous that
the user might have provided... nicely done!

Your print statement is intriguing to me... I'm not entirely sure how it works.


The format specifiers in printf are %[flags][width][.precision]format. 
So I'm requesting a precision-limited string print (which says the 
maximum number of characters to print, rather than the usual semantics 
of printing until the trailing NUL is found), and the precision of .* 
(instead of a more typical .1 or similar) says that the precision will 
be an int argument to printf rather than inline (the width argument can 
also be passed via *).  The cast to int is annoyingly part of the 
specification (subtracting two pointers within a string results in a 
ptrdiff_t, but on 64-bit platforms, ptrdiff_t and int are not equally 
handled through vararg functions).  And that exact style of printf() 
magic was already in use in monitor_parse_command() that your patch 
attempt was touching (see where cmdp_start is used).  And if you really 
want weird, 'man 3 printf' states that "%.*s" is equivalent to 
"%2$.*1$s" (the $ syntax is for cases cases where you need to consume 
printf arguments out-of-order, often when dealing with translated strings).




How would you like to move forward with this patch?


I'm more than happy to let you post a v2 of the patch, incorporating the 
ideas you just learned from me.  (Or, if you do nothing, then in a week 
or so, I'll probably notice the patch is still sitting unapplied in my 
local repository and submit it myself - but then I wouldn't be helping 
the qemu community grow...)


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



Re: [Qemu-devel] [PATCH] monitor: report entirety of hmp command on error

2018-05-04 Thread Collin Walling
On 05/04/2018 11:19 AM, Eric Blake wrote:
> On 05/04/2018 09:49 AM, Collin Walling wrote:
>> When a user incorrectly provides an hmp command, an error response will be
>> printed that prompts the user to try "help ". However, when
>> the command contains multiple parts e.g. "info skeys", only the last
>> whitespace delimited string will be reported (in this example "info" will
>> be dropped and the message will read "Try "help skeys" for more information",
>> which is incorrect).
> 
> What's the exact formula for reproducing this?  I tried:
> 
> $ ./x86_64-softmmu/qemu-system-x86_64 -nodefaults -nographic --monitor stdio
> QEMU 2.12.50 monitor - type 'help' for more information
> (qemu) info skeys
> unknown command: 'info skeys'
> 
> Oh, I see now:
> 
> (qemu) info uuid blah
> uuid: extraneous characters at the end of line
> Try "help uuid" for more information
> (qemu) help uuid
> (qemu)
> 
> You'll want to update your commit message to document something that is 
> reproducible (you may be adding an 'info skeys', but until that is in, it 
> doesn't make a good example).
> 
>>
>> Let's correct this by capturing the full name of the command as we recurse
>> through the function monitor_parse_command.
>>
>> Reported-by: Mikhail Fokin 
>> Signed-off-by: Collin Walling 
>> ---
>>   monitor.c | 15 +++
>>   1 file changed, 11 insertions(+), 4 deletions(-)
>>
>> diff --git a/monitor.c b/monitor.c
>> index 39f8ee1..d4844b4 100644
>> --- a/monitor.c
>> +++ b/monitor.c
>> @@ -2964,7 +2964,8 @@ static const mon_cmd_t *search_dispatch_table(const 
>> mon_cmd_t *disp_table,
>>   static const mon_cmd_t *monitor_parse_command(Monitor *mon,
>>     const char *cmdp_start,
>>     const char **cmdp,
>> -  mon_cmd_t *table)
>> +  mon_cmd_t *table,
>> +  char *fullname)
> 
> Umm, how is fullname any better than cmdp_start that we already have?
> 
>>   {
>>   const char *p;
>>   const mon_cmd_t *cmd;
>> @@ -2987,10 +2988,14 @@ static const mon_cmd_t 
>> *monitor_parse_command(Monitor *mon,
>>   p++;
>>   }
>>   +    strncat(fullname, cmdname, strlen(cmdname));
> 
> gcc 8 is pickier about using strncat() [perhaps too picky - see 
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85602], but it is generally NOT 
> the function you want to be using.
> 
>> +
>>   *cmdp = p;
>>   /* search sub command */
>>   if (cmd->sub_table != NULL && *p != '\0') {
>> -    return monitor_parse_command(mon, cmdp_start, cmdp, cmd->sub_table);
>> +    strncat(fullname, " ", 1);
>> +    return monitor_parse_command(mon, cmdp_start, cmdp, cmd->sub_table,
>> + fullname);
> 
> See, you're reconstructing a command into fullname, which already matches the 
> original command in cmdp_start, so I see no reason to change the signature.
> 
>>   }
>>     return cmd;
>> @@ -3371,10 +3376,12 @@ static void handle_hmp_command(Monitor *mon, const 
>> char *cmdline)
>>   {
>>   QDict *qdict;
>>   const mon_cmd_t *cmd;
>> +    char fullname[256];
> 
> EWWW. Don't do that.  You are just ASKING for a buffer overflow exploit that 
> prints the wrong thing or causes a security hole, when I intentionally type a 
> super-long garbage command into HMP.
> 
>>     trace_handle_hmp_command(mon, cmdline);
>>   -    cmd = monitor_parse_command(mon, cmdline, , mon->cmd_table);
>> +    cmd = monitor_parse_command(mon, cmdline, , mon->cmd_table,
>> +    fullname);
> 
> Note that even without your patch, this call updates 'cmdline' to point to 
> the position within the original string (although that position has already 
> skipped spaces).
> 
>>   if (!cmd) {
>>   return;
>>   }
>> @@ -3382,7 +3389,7 @@ static void handle_hmp_command(Monitor *mon, const 
>> char *cmdline)
>>   qdict = monitor_parse_arguments(mon, , cmd);
>>   if (!qdict) {
>>   monitor_printf(mon, "Try \"help %s\" for more information\n",
>> -   cmd->name);
>> +   fullname);
> 
> So rather than trying to reconstruct a string, you could reuse what you 
> already have.  This is a shorter patch that I think accomplishes the same 
> goal:
> 
> diff --git i/monitor.c w/monitor.c
> index 39f8ee17ba7..38736b3a20d 100644
> --- i/monitor.c
> +++ w/monitor.c
> @@ -3371,6 +3371,7 @@ static void handle_hmp_command(Monitor *mon, const char 
> *cmdline)
>  {
>  QDict *qdict;
>  const mon_cmd_t *cmd;
> +    const char *cmd_start = cmdline;
> 
>  trace_handle_hmp_command(mon, cmdline);
> 
> @@ -3381,8 +3382,11 @@ static void handle_hmp_command(Monitor *mon, const 
> char *cmdline)
> 
>  qdict = monitor_parse_arguments(mon, , cmd);
>  if (!qdict) 

Re: [Qemu-devel] [PULL 00/24] target-arm queue

2018-05-04 Thread Peter Maydell
On 4 May 2018 at 18:15, Peter Maydell <peter.mayd...@linaro.org> wrote:
> target-arm queue: Eric's SMMUv3 patchset, and an array
> of minor bugfixes and improvements from various others.
>
> thanks
> -- PMM
>
> The following changes since commit c8b7e627b4269a3bc3ae41d9f420547a47e6d9b9:
>
>   Merge remote-tracking branch 'remotes/ericb/tags/pull-nbd-2018-05-04' into 
> staging (2018-05-04 14:42:46 +0100)
>
> are available in the Git repository at:
>
>   git://git.linaro.org/people/pmaydell/qemu-arm.git 
> tags/pull-target-arm-20180504
>
> for you to fetch changes up to 5680740c92993e9b3f3e011f2a2c394070e33f56:
>
>   hw/arm/virt: Introduce the iommu option (2018-05-04 18:05:52 +0100)
>
> 
> target-arm queue:
>  * Emulate the SMMUv3 (IOMMU); one will be created in the 'virt' board
>if the commandline includes "-machine iommu=smmuv3"
>  * target/arm: Implement v8M VLLDM and VLSTM
>  * hw/arm: Don't fail qtest due to missing SD card in -nodefaults mode
>  * Some fixes to silence Coverity false-positives
>  * arm: boot: set boot_info starting from first_cpu
>(fixes a technical bug not visible in practice)
>  * hw/net/smc91c111: Convert away from old_mmio
>  * hw/usb/tusb6010: Convert away from old_mmio
>  * hw/char/cmsdk-apb-uart.c: Accept more input after character read
>  * target/arm: Make MPUIR write-ignored on OMAP, StrongARM
>  * hw/arm/virt: Add linux,pci-domain property

Oops, 32-bit compile failures for format string issues;

hw/arm/trace.h: In function ‘_nocheck__trace_smmu_ptw_level’:
hw/arm/trace.h:215:18: error: format ‘%lx’ expects argument of type
‘long unsigned int’, but argument 7 has type ‘size_t {aka unsigned
int}’ [-Werror=format=]
 qemu_log("%d@%zd.%06zd:smmu_ptw_level " "level=%d
iova=0x%"PRIx64" subpage_sz=0x%lx baseaddr=0x%"PRIx64" offset=%d =>
pte=0x%"PRIx64 "\n",
  ^
hw/arm/trace.h: In function ‘_nocheck__trace_smmuv3_write_mmio_idr’:
hw/arm/trace.h:606:18: error: format ‘%lx’ expects argument of type
‘long unsigned int’, but argument 5 has type ‘uint64_t {aka long long
unsigned int}’ [-Werror=format=]
 qemu_log("%d@%zd.%06zd:smmuv3_write_mmio_idr " "write to
RO/Unimpl reg 0x%lx val64:0x%lx" "\n",
  ^
hw/arm/trace.h:606:18: error: format ‘%lx’ expects argument of type
‘long unsigned int’, but argument 6 has type ‘uint64_t {aka long long
unsigned int}’ [-Werror=format=]
hw/arm/trace.h: In function ‘_nocheck__trace_smmuv3_find_ste_2lvl’:
hw/arm/trace.h:721:18: error: format ‘%lx’ expects argument of type
‘long unsigned int’, but argument 5 has type ‘uint64_t {aka long long
unsigned int}’ [-Werror=format=]
 qemu_log("%d@%zd.%06zd:smmuv3_find_ste_2lvl "
"strtab_base:0x%lx l1ptr:0x%"PRIx64" l1_off:0x%x, l2ptr:0x%"PRIx64"
l2_off:0x%x max_l2_ste:%d" "\n",
  ^

size_t arguments need %zx, not %lx, and uint64_t arguments need
%"PRIx64", not %lx. I'll squash in the changes to the relevant patches.

thanks
-- PMM



[Qemu-devel] [PULL 00/24] target-arm queue

2018-05-04 Thread Peter Maydell
v2: fixed format string errors in trace messages.

-- PMM

The following changes since commit c8b7e627b4269a3bc3ae41d9f420547a47e6d9b9:

  Merge remote-tracking branch 'remotes/ericb/tags/pull-nbd-2018-05-04' into 
staging (2018-05-04 14:42:46 +0100)

are available in the Git repository at:

  git://git.linaro.org/people/pmaydell/qemu-arm.git 
tags/pull-target-arm-20180504-1

for you to fetch changes up to e24e3454829579eb815ec95d7b3679b0f65845b4:

  hw/arm/virt: Introduce the iommu option (2018-05-04 18:52:58 +0100)


target-arm queue:
 * Emulate the SMMUv3 (IOMMU); one will be created in the 'virt' board
   if the commandline includes "-machine iommu=smmuv3"
 * target/arm: Implement v8M VLLDM and VLSTM
 * hw/arm: Don't fail qtest due to missing SD card in -nodefaults mode
 * Some fixes to silence Coverity false-positives
 * arm: boot: set boot_info starting from first_cpu
   (fixes a technical bug not visible in practice)
 * hw/net/smc91c111: Convert away from old_mmio
 * hw/usb/tusb6010: Convert away from old_mmio
 * hw/char/cmsdk-apb-uart.c: Accept more input after character read
 * target/arm: Make MPUIR write-ignored on OMAP, StrongARM
 * hw/arm/virt: Add linux,pci-domain property


Eric Auger (11):
  hw/arm/smmu-common: smmu base device and datatypes
  hw/arm/smmu-common: IOMMU memory region and address space setup
  hw/arm/smmu-common: VMSAv8-64 page table walk
  hw/arm/smmuv3: Wired IRQ and GERROR helpers
  hw/arm/smmuv3: Queue helpers
  hw/arm/smmuv3: Implement MMIO write operations
  hw/arm/smmuv3: Event queue recording helper
  hw/arm/smmuv3: Implement translate callback
  hw/arm/smmuv3: Abort on vfio or vhost case
  target/arm/kvm: Translate the MSI doorbell in kvm_arch_fixup_msi_route
  hw/arm/virt: Introduce the iommu option

Igor Mammedov (1):
  arm: boot: set boot_info starting from first_cpu

Jan Kiszka (1):
  hw/arm/virt: Add linux,pci-domain property

Mathew Maidment (1):
  target/arm: Correct MPUIR privilege level in 
register_cp_regs_for_features() conditional case

Patrick Oppenlander (1):
  hw/char/cmsdk-apb-uart.c: Accept more input after character read

Peter Maydell (3):
  hw/usb/tusb6010: Convert away from old_mmio
  hw/net/smc91c111: Convert away from old_mmio
  target/arm: Implement v8M VLLDM and VLSTM

Prem Mallappa (3):
  hw/arm/smmuv3: Skeleton
  hw/arm/virt: Add SMMUv3 to the virt board
  hw/arm/virt-acpi-build: Add smmuv3 node in IORT table

Richard Henderson (2):
  target/arm: Tidy conditions in handle_vec_simd_shri
  target/arm: Tidy condition in disas_simd_two_reg_misc

Thomas Huth (1):
  hw/arm: Don't fail qtest due to missing SD card in -nodefaults mode

 hw/arm/Makefile.objs|1 +
 hw/arm/smmu-internal.h  |   99 +++
 hw/arm/smmuv3-internal.h|  621 ++
 include/hw/acpi/acpi-defs.h |   15 +
 include/hw/arm/smmu-common.h|  145 +
 include/hw/arm/smmuv3.h |   87 +++
 include/hw/arm/virt.h   |   10 +
 hw/arm/boot.c   |2 +-
 hw/arm/omap1.c  |8 +-
 hw/arm/omap2.c  |8 +-
 hw/arm/pxa2xx.c |   15 +-
 hw/arm/smmu-common.c|  372 +++
 hw/arm/smmuv3.c | 1191 +++
 hw/arm/virt-acpi-build.c|   55 +-
 hw/arm/virt.c   |  101 ++-
 hw/char/cmsdk-apb-uart.c|1 +
 hw/net/smc91c111.c  |   54 +-
 hw/usb/tusb6010.c   |   40 +-
 target/arm/helper.c |2 +-
 target/arm/kvm.c|   38 +-
 target/arm/translate-a64.c  |   12 +-
 target/arm/translate.c  |   17 +-
 default-configs/aarch64-softmmu.mak |1 +
 hw/arm/trace-events |   37 ++
 target/arm/trace-events |3 +
 25 files changed, 2868 insertions(+), 67 deletions(-)
 create mode 100644 hw/arm/smmu-internal.h
 create mode 100644 hw/arm/smmuv3-internal.h
 create mode 100644 include/hw/arm/smmu-common.h
 create mode 100644 include/hw/arm/smmuv3.h
 create mode 100644 hw/arm/smmu-common.c
 create mode 100644 hw/arm/smmuv3.c



Re: [Qemu-devel] [PATCH 0/2] qemu-iotests: post-QEMU 2.12 fixes for 185

2018-05-04 Thread Jeff Cody
On Fri, May 04, 2018 at 04:50:12PM +0100, Stefan Hajnoczi wrote:
> The 185 qemu-iotests test case was in a bad state for the QEMU 2.12 release.
> We fudged the expected test output to make it pass, except for
> non-deterministic behavior.
> 
> These patches get us back to pre-QEMU 2.12.  Notably the offsets reported in
> block job events now correspond to smaller buffer sizes because the job 
> doesn't
> iterate during drain.
> 
> It's worth mentioning that the test case is still non-deterministic.  For more
> on that, see the first patch.
> 
> Stefan Hajnoczi (2):
>   qemu-iotests: reduce chance of races in 185
>   blockjob: do not cancel timer in resume
> 
>  blockjob.c | 22 +++---
>  tests/qemu-iotests/185 | 12 
>  tests/qemu-iotests/185.out | 10 +-
>  3 files changed, 32 insertions(+), 12 deletions(-)
> 
> -- 
> 2.14.3
>

This series has a minor collision with my block branch in the output; would
you like me to just merge together the appropriate 185.out when applying?

-Jeff



Re: [Qemu-devel] [PATCH 1/2] qemu-iotests: reduce chance of races in 185

2018-05-04 Thread Vladimir Sementsov-Ogievskiy

04.05.2018 18:50, Stefan Hajnoczi wrote:

Commit 8565c3ab537e78f3e69977ec2c609dc9417a806e ("qemu-iotests: fix
185") identified a race condition in a sub-test.

Similar issues also affect the other sub-tests.  If disk I/O completes
quickly, it races with the QMP 'quit' command.  This causes spurious
test failures because QMP events are emitted in an unpredictable order.

This test relies on QEMU internals and there is no QMP API for getting
deterministic behavior needed to make this test 100% reliable.  At the
same time, the test is useful and it would be a shame to remove it.

Add sleep 0.5 to reduce the chance of races.  This is not a real fix but
appears to reduce spurious failures in practice.

Cc: Vladimir Sementsov-Ogievskiy 
Signed-off-by: Stefan Hajnoczi 
---
  tests/qemu-iotests/185 | 12 
  tests/qemu-iotests/185.out |  4 ++--
  2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/tests/qemu-iotests/185 b/tests/qemu-iotests/185
index 298d88d04e..975404c99d 100755
--- a/tests/qemu-iotests/185
+++ b/tests/qemu-iotests/185
@@ -118,6 +118,9 @@ _send_qemu_cmd $h \
'speed': 65536 } }" \
  "return"
  
+# If we don't sleep here 'quit' command races with disk I/O

+sleep 0.5
+
  _send_qemu_cmd $h "{ 'execute': 'quit' }" "return"
  wait=1 _cleanup_qemu
  
@@ -137,6 +140,9 @@ _send_qemu_cmd $h \

'speed': 65536 } }" \
  "return"
  
+# If we don't sleep here 'quit' command races with disk I/O

+sleep 0.5
+
  _send_qemu_cmd $h "{ 'execute': 'quit' }" "return"
  wait=1 _cleanup_qemu
  
@@ -183,6 +189,9 @@ _send_qemu_cmd $h \

'speed': 65536 } }" \
  "return"
  
+# If we don't sleep here 'quit' command races with disk I/O

+sleep 0.5
+
  _send_qemu_cmd $h "{ 'execute': 'quit' }" "return"
  wait=1 _cleanup_qemu
  
@@ -201,6 +210,9 @@ _send_qemu_cmd $h \

'speed': 65536 } }" \
  "return"
  
+# If we don't sleep here 'quit' command races with disk I/O

+sleep 0.5
+
  _send_qemu_cmd $h "{ 'execute': 'quit' }" "return"
  wait=1 _cleanup_qemu
  
diff --git a/tests/qemu-iotests/185.out b/tests/qemu-iotests/185.out

index 2c4b04de73..1f21e79c13 100644
--- a/tests/qemu-iotests/185.out
+++ b/tests/qemu-iotests/185.out
@@ -26,9 +26,9 @@ Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 
backing_file=TEST_DIR/t.q
  
  {"return": {}}

  {"return": {}}
-{"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", 
"data": {"guest": false}}
  {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "disk", 
"len": 4194304, "offset": 4194304, "speed": 65536, "type": "commit"}}
+{"return": {}}
+{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", 
"data": {"guest": false}}
  {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "disk", 
"len": 4194304, "offset": 4194304, "speed": 65536, "type": "commit"}}
  
  === Start mirror job and exit qemu ===


Hm, it looks strange, that commit was done with such a small speed in 
0.5 seconds...


--
Best regards,
Vladimir




[Qemu-devel] [PULL 21/24] target/arm/kvm: Translate the MSI doorbell in kvm_arch_fixup_msi_route

2018-05-04 Thread Peter Maydell
From: Eric Auger 

In case the MSI is translated by an IOMMU we need to fixup the
MSI route with the translated address.

Signed-off-by: Eric Auger 
Signed-off-by: Bharat Bhushan 
Message-id: 1524665762-31355-12-git-send-email-eric.au...@redhat.com
Reviewed-by: Peter Maydell 
Signed-off-by: Peter Maydell 
---
 target/arm/kvm.c| 38 +-
 target/arm/trace-events |  3 +++
 2 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index ecc39ac295..5141d0adc5 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -20,8 +20,10 @@
 #include "sysemu/kvm.h"
 #include "kvm_arm.h"
 #include "cpu.h"
+#include "trace.h"
 #include "internals.h"
 #include "hw/arm/arm.h"
+#include "hw/pci/pci.h"
 #include "exec/memattrs.h"
 #include "exec/address-spaces.h"
 #include "hw/boards.h"
@@ -649,7 +651,41 @@ int kvm_arm_vgic_probe(void)
 int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
  uint64_t address, uint32_t data, PCIDevice *dev)
 {
-return 0;
+AddressSpace *as = pci_device_iommu_address_space(dev);
+hwaddr xlat, len, doorbell_gpa;
+MemoryRegionSection mrs;
+MemoryRegion *mr;
+int ret = 1;
+
+if (as == _space_memory) {
+return 0;
+}
+
+/* MSI doorbell address is translated by an IOMMU */
+
+rcu_read_lock();
+mr = address_space_translate(as, address, , , true);
+if (!mr) {
+goto unlock;
+}
+mrs = memory_region_find(mr, xlat, 1);
+if (!mrs.mr) {
+goto unlock;
+}
+
+doorbell_gpa = mrs.offset_within_address_space;
+memory_region_unref(mrs.mr);
+
+route->u.msi.address_lo = doorbell_gpa;
+route->u.msi.address_hi = doorbell_gpa >> 32;
+
+trace_kvm_arm_fixup_msi_route(address, doorbell_gpa);
+
+ret = 0;
+
+unlock:
+rcu_read_unlock();
+return ret;
 }
 
 int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route,
diff --git a/target/arm/trace-events b/target/arm/trace-events
index 9e37131115..6b759f9d4f 100644
--- a/target/arm/trace-events
+++ b/target/arm/trace-events
@@ -8,3 +8,6 @@ arm_gt_tval_write(int timer, uint64_t value) "gt_tval_write: 
timer %d value 0x%"
 arm_gt_ctl_write(int timer, uint64_t value) "gt_ctl_write: timer %d value 0x%" 
PRIx64
 arm_gt_imask_toggle(int timer, int irqstate) "gt_ctl_write: timer %d IMASK 
toggle, new irqstate %d"
 arm_gt_cntvoff_write(uint64_t value) "gt_cntvoff_write: value 0x%" PRIx64
+
+# target/arm/kvm.c
+kvm_arm_fixup_msi_route(uint64_t iova, uint64_t gpa) "MSI iova = 0x%"PRIx64" 
is translated into 0x%"PRIx64
-- 
2.17.0




[Qemu-devel] [PULL 18/24] hw/arm/smmuv3: Event queue recording helper

2018-05-04 Thread Peter Maydell
From: Eric Auger 

Let's introduce a helper function aiming at recording an
event in the event queue.

Signed-off-by: Eric Auger 
Reviewed-by: Peter Maydell 
Message-id: 1524665762-31355-9-git-send-email-eric.au...@redhat.com
Signed-off-by: Peter Maydell 
---
 hw/arm/smmuv3-internal.h | 148 ++-
 hw/arm/smmuv3.c  | 108 ++--
 hw/arm/trace-events  |   1 +
 3 files changed, 249 insertions(+), 8 deletions(-)

diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
index 282285d310..2d50300a56 100644
--- a/hw/arm/smmuv3-internal.h
+++ b/hw/arm/smmuv3-internal.h
@@ -206,8 +206,6 @@ static inline void smmu_write_cmdq_err(SMMUv3State *s, 
uint32_t err_type)
 s->cmdq.cons = FIELD_DP32(s->cmdq.cons, CMDQ_CONS, ERR, err_type);
 }
 
-void smmuv3_write_eventq(SMMUv3State *s, Evt *evt);
-
 /* Commands */
 
 typedef enum SMMUCommandType {
@@ -314,4 +312,150 @@ enum { /* Command completion notification */
 
 #define SMMU_FEATURE_2LVL_STE (1 << 0)
 
+/* Events */
+
+typedef enum SMMUEventType {
+SMMU_EVT_OK = 0x00,
+SMMU_EVT_F_UUT,
+SMMU_EVT_C_BAD_STREAMID   ,
+SMMU_EVT_F_STE_FETCH  ,
+SMMU_EVT_C_BAD_STE,
+SMMU_EVT_F_BAD_ATS_TREQ   ,
+SMMU_EVT_F_STREAM_DISABLED,
+SMMU_EVT_F_TRANS_FORBIDDEN,
+SMMU_EVT_C_BAD_SUBSTREAMID,
+SMMU_EVT_F_CD_FETCH   ,
+SMMU_EVT_C_BAD_CD ,
+SMMU_EVT_F_WALK_EABT  ,
+SMMU_EVT_F_TRANSLATION  = 0x10,
+SMMU_EVT_F_ADDR_SIZE  ,
+SMMU_EVT_F_ACCESS ,
+SMMU_EVT_F_PERMISSION ,
+SMMU_EVT_F_TLB_CONFLICT = 0x20,
+SMMU_EVT_F_CFG_CONFLICT   ,
+SMMU_EVT_E_PAGE_REQ = 0x24,
+} SMMUEventType;
+
+static const char *event_stringify[] = {
+[SMMU_EVT_OK]   = "SMMU_EVT_OK",
+[SMMU_EVT_F_UUT]= "SMMU_EVT_F_UUT",
+[SMMU_EVT_C_BAD_STREAMID]   = "SMMU_EVT_C_BAD_STREAMID",
+[SMMU_EVT_F_STE_FETCH]  = "SMMU_EVT_F_STE_FETCH",
+[SMMU_EVT_C_BAD_STE]= "SMMU_EVT_C_BAD_STE",
+[SMMU_EVT_F_BAD_ATS_TREQ]   = "SMMU_EVT_F_BAD_ATS_TREQ",
+[SMMU_EVT_F_STREAM_DISABLED]= "SMMU_EVT_F_STREAM_DISABLED",
+[SMMU_EVT_F_TRANS_FORBIDDEN]= "SMMU_EVT_F_TRANS_FORBIDDEN",
+[SMMU_EVT_C_BAD_SUBSTREAMID]= "SMMU_EVT_C_BAD_SUBSTREAMID",
+[SMMU_EVT_F_CD_FETCH]   = "SMMU_EVT_F_CD_FETCH",
+[SMMU_EVT_C_BAD_CD] = "SMMU_EVT_C_BAD_CD",
+[SMMU_EVT_F_WALK_EABT]  = "SMMU_EVT_F_WALK_EABT",
+[SMMU_EVT_F_TRANSLATION]= "SMMU_EVT_F_TRANSLATION",
+[SMMU_EVT_F_ADDR_SIZE]  = "SMMU_EVT_F_ADDR_SIZE",
+[SMMU_EVT_F_ACCESS] = "SMMU_EVT_F_ACCESS",
+[SMMU_EVT_F_PERMISSION] = "SMMU_EVT_F_PERMISSION",
+[SMMU_EVT_F_TLB_CONFLICT]   = "SMMU_EVT_F_TLB_CONFLICT",
+[SMMU_EVT_F_CFG_CONFLICT]   = "SMMU_EVT_F_CFG_CONFLICT",
+[SMMU_EVT_E_PAGE_REQ]   = "SMMU_EVT_E_PAGE_REQ",
+};
+
+static inline const char *smmu_event_string(SMMUEventType type)
+{
+if (type < ARRAY_SIZE(event_stringify)) {
+return event_stringify[type] ? event_stringify[type] : "UNKNOWN";
+} else {
+return "INVALID";
+}
+}
+
+/*  Encode an event record */
+typedef struct SMMUEventInfo {
+SMMUEventType type;
+uint32_t sid;
+bool recorded;
+bool record_trans_faults;
+union {
+struct {
+uint32_t ssid;
+bool ssv;
+dma_addr_t addr;
+bool rnw;
+bool pnu;
+bool ind;
+   } f_uut;
+   struct SSIDInfo {
+uint32_t ssid;
+bool ssv;
+   } c_bad_streamid;
+   struct SSIDAddrInfo {
+uint32_t ssid;
+bool ssv;
+dma_addr_t addr;
+   } f_ste_fetch;
+   struct SSIDInfo c_bad_ste;
+   struct {
+dma_addr_t addr;
+bool rnw;
+   } f_transl_forbidden;
+   struct {
+uint32_t ssid;
+   } c_bad_substream;
+   struct SSIDAddrInfo f_cd_fetch;
+   struct SSIDInfo c_bad_cd;
+   struct FullInfo {
+bool stall;
+uint16_t stag;
+uint32_t ssid;
+bool ssv;
+bool s2;
+dma_addr_t addr;
+bool rnw;
+bool pnu;
+bool ind;
+uint8_t class;
+dma_addr_t addr2;
+   } f_walk_eabt;
+   struct FullInfo f_translation;
+   struct FullInfo f_addr_size;
+   struct FullInfo f_access;
+   struct FullInfo f_permission;
+   struct SSIDInfo f_cfg_conflict;
+   /**
+* not supported yet:
+* 

[Qemu-devel] [PULL 20/24] hw/arm/smmuv3: Abort on vfio or vhost case

2018-05-04 Thread Peter Maydell
From: Eric Auger 

At the moment, the SMMUv3 does not support notification on
TLB invalidation. So let's log an error as soon as such notifier
gets enabled.

Signed-off-by: Eric Auger 
Reviewed-by: Peter Maydell 
Message-id: 1524665762-31355-11-git-send-email-eric.au...@redhat.com
Signed-off-by: Peter Maydell 
---
 hw/arm/smmuv3.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
index d896834764..b3026dea20 100644
--- a/hw/arm/smmuv3.c
+++ b/hw/arm/smmuv3.c
@@ -1147,12 +1147,23 @@ static void smmuv3_class_init(ObjectClass *klass, void 
*data)
 dc->realize = smmu_realize;
 }
 
+static void smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
+   IOMMUNotifierFlag old,
+   IOMMUNotifierFlag new)
+{
+if (old == IOMMU_NOTIFIER_NONE) {
+warn_report("SMMUV3 does not support vhost/vfio integration yet: "
+"devices of those types will not function properly");
+}
+}
+
 static void smmuv3_iommu_memory_region_class_init(ObjectClass *klass,
   void *data)
 {
 IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass);
 
 imrc->translate = smmuv3_translate;
+imrc->notify_flag_changed = smmuv3_notify_flag_changed;
 }
 
 static const TypeInfo smmuv3_type_info = {
-- 
2.17.0




Re: [Qemu-devel] release retrospective, next release timing, numbering

2018-05-04 Thread Max Reitz
On 2018-05-02 09:59, Daniel P. Berrangé wrote:
> On Wed, May 02, 2018 at 12:43:10AM -0700, Liviu Ionescu wrote:
>> On 2 May 2018 at 10:38:09, Cornelia Huck (coh...@redhat.com) wrote:
>>
>>> a) Bump major version once a year, so we'll have 3.0, 3.1,
>>> 3.3,
>> 4.0, 4.1, 4.2, 5.0, ...etc We missed the first release this
>> year, so we would only have 3.0 and 3.1 this year.
>>
>> b) Bump major release when minor version gets double-digits.
>> eg 3.0, 3.1, , 3.9, 3.9, 4.0, , 4.9, 5.0...

 It's just a matter of taste, but I think I'd prefer variant b).
>>> That
 will bump the major release approx. every three years which
>>> sounds like
 a good time frame for me.
>>>
>>> I think anything that keeps release numbers in ascending order
>>> would
>>> basically work :)
>>
>> not really.
>>
>> I suggest you use semantic versioning:
>>
>> https://semver.org
> 
> No, not semver. It is not a good match for the way QEMU is handling
> incompatible changes. Our deprecation policy lets us include incompatible
> changes in *any* release. So with semver that would force a major version
> bump on every release which is madness.

FWIW, I think that just means that our deprecation policy is weird.

As a developer, it's great, of course.  You can break everything, just
put up a heads-up two versions in advance.

But I'm grateful I'm not a direct user of qemu (i.e. without libvirt).
I imagine it to be pretty stressful if I have to check on every (or
every second...) release that qemu doesn't show up new deprecation
notices for something I'm using.

Maybe it would make sense to collect things we want to deprecate and
then have a major release every year where we do that deprecation.  As a
user, I'd much prefer that to the possibility of everything changing all
the time.

Max



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PULL 24/24] hw/arm/virt: Introduce the iommu option

2018-05-04 Thread Peter Maydell
From: Eric Auger 

ARM virt machine now exposes a new "iommu" option.
The SMMUv3 IOMMU is instantiated using -machine virt,iommu=smmuv3.

Signed-off-by: Eric Auger 
Signed-off-by: Prem Mallappa 
Reviewed-by: Peter Maydell 
Message-id: 1524665762-31355-15-git-send-email-eric.au...@redhat.com
Signed-off-by: Peter Maydell 
---
 hw/arm/virt.c | 36 
 1 file changed, 36 insertions(+)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index b085f0b9b4..11b9f599ca 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1561,6 +1561,34 @@ static void virt_set_gic_version(Object *obj, const char 
*value, Error **errp)
 }
 }
 
+static char *virt_get_iommu(Object *obj, Error **errp)
+{
+VirtMachineState *vms = VIRT_MACHINE(obj);
+
+switch (vms->iommu) {
+case VIRT_IOMMU_NONE:
+return g_strdup("none");
+case VIRT_IOMMU_SMMUV3:
+return g_strdup("smmuv3");
+default:
+g_assert_not_reached();
+}
+}
+
+static void virt_set_iommu(Object *obj, const char *value, Error **errp)
+{
+VirtMachineState *vms = VIRT_MACHINE(obj);
+
+if (!strcmp(value, "smmuv3")) {
+vms->iommu = VIRT_IOMMU_SMMUV3;
+} else if (!strcmp(value, "none")) {
+vms->iommu = VIRT_IOMMU_NONE;
+} else {
+error_setg(errp, "Invalid iommu value");
+error_append_hint(errp, "Valid values are none, smmuv3.\n");
+}
+}
+
 static CpuInstanceProperties
 virt_cpu_index_to_props(MachineState *ms, unsigned cpu_index)
 {
@@ -1693,6 +1721,14 @@ static void virt_2_12_instance_init(Object *obj)
 NULL);
 }
 
+/* Default disallows iommu instantiation */
+vms->iommu = VIRT_IOMMU_NONE;
+object_property_add_str(obj, "iommu", virt_get_iommu, virt_set_iommu, 
NULL);
+object_property_set_description(obj, "iommu",
+"Set the IOMMU type. "
+"Valid values are none and smmuv3",
+NULL);
+
 vms->memmap = a15memmap;
 vms->irqmap = a15irqmap;
 }
-- 
2.17.0




[Qemu-devel] [PULL 16/24] hw/arm/smmuv3: Queue helpers

2018-05-04 Thread Peter Maydell
From: Eric Auger 

We introduce helpers to read/write into the command and event
circular queues.

smmuv3_write_eventq and smmuv3_cmq_consume will become static
in subsequent patches.

Invalidation commands are not yet dealt with. We do not cache
data that need to be invalidated. This will change with vhost
integration.

Signed-off-by: Eric Auger 
Signed-off-by: Prem Mallappa 
Reviewed-by: Peter Maydell 
Message-id: 1524665762-31355-7-git-send-email-eric.au...@redhat.com
Signed-off-by: Peter Maydell 
---
 hw/arm/smmuv3-internal.h | 163 +++
 hw/arm/smmuv3.c  | 136 
 hw/arm/trace-events  |   5 ++
 3 files changed, 304 insertions(+)

diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
index e27c128c07..223d8406ed 100644
--- a/hw/arm/smmuv3-internal.h
+++ b/hw/arm/smmuv3-internal.h
@@ -153,4 +153,167 @@ static inline bool smmuv3_gerror_irq_enabled(SMMUv3State 
*s)
 void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq irq, uint32_t gerror_mask);
 void smmuv3_write_gerrorn(SMMUv3State *s, uint32_t gerrorn);
 
+/* Queue Handling */
+
+#define Q_BASE(q)  ((q)->base & SMMU_BASE_ADDR_MASK)
+#define WRAP_MASK(q)   (1 << (q)->log2size)
+#define INDEX_MASK(q)  (((1 << (q)->log2size)) - 1)
+#define WRAP_INDEX_MASK(q) ((1 << ((q)->log2size + 1)) - 1)
+
+#define Q_CONS(q) ((q)->cons & INDEX_MASK(q))
+#define Q_PROD(q) ((q)->prod & INDEX_MASK(q))
+
+#define Q_CONS_ENTRY(q)  (Q_BASE(q) + (q)->entry_size * Q_CONS(q))
+#define Q_PROD_ENTRY(q)  (Q_BASE(q) + (q)->entry_size * Q_PROD(q))
+
+#define Q_CONS_WRAP(q) (((q)->cons & WRAP_MASK(q)) >> (q)->log2size)
+#define Q_PROD_WRAP(q) (((q)->prod & WRAP_MASK(q)) >> (q)->log2size)
+
+static inline bool smmuv3_q_full(SMMUQueue *q)
+{
+return ((q->cons ^ q->prod) & WRAP_INDEX_MASK(q)) == WRAP_MASK(q);
+}
+
+static inline bool smmuv3_q_empty(SMMUQueue *q)
+{
+return (q->cons & WRAP_INDEX_MASK(q)) == (q->prod & WRAP_INDEX_MASK(q));
+}
+
+static inline void queue_prod_incr(SMMUQueue *q)
+{
+q->prod = (q->prod + 1) & WRAP_INDEX_MASK(q);
+}
+
+static inline void queue_cons_incr(SMMUQueue *q)
+{
+/*
+ * We have to use deposit for the CONS registers to preserve
+ * the ERR field in the high bits.
+ */
+q->cons = deposit32(q->cons, 0, q->log2size + 1, q->cons + 1);
+}
+
+static inline bool smmuv3_cmdq_enabled(SMMUv3State *s)
+{
+return FIELD_EX32(s->cr[0], CR0, CMDQEN);
+}
+
+static inline bool smmuv3_eventq_enabled(SMMUv3State *s)
+{
+return FIELD_EX32(s->cr[0], CR0, EVENTQEN);
+}
+
+static inline void smmu_write_cmdq_err(SMMUv3State *s, uint32_t err_type)
+{
+s->cmdq.cons = FIELD_DP32(s->cmdq.cons, CMDQ_CONS, ERR, err_type);
+}
+
+void smmuv3_write_eventq(SMMUv3State *s, Evt *evt);
+
+/* Commands */
+
+typedef enum SMMUCommandType {
+SMMU_CMD_NONE= 0x00,
+SMMU_CMD_PREFETCH_CONFIG   ,
+SMMU_CMD_PREFETCH_ADDR,
+SMMU_CMD_CFGI_STE,
+SMMU_CMD_CFGI_STE_RANGE,
+SMMU_CMD_CFGI_CD,
+SMMU_CMD_CFGI_CD_ALL,
+SMMU_CMD_CFGI_ALL,
+SMMU_CMD_TLBI_NH_ALL = 0x10,
+SMMU_CMD_TLBI_NH_ASID,
+SMMU_CMD_TLBI_NH_VA,
+SMMU_CMD_TLBI_NH_VAA,
+SMMU_CMD_TLBI_EL3_ALL= 0x18,
+SMMU_CMD_TLBI_EL3_VA = 0x1a,
+SMMU_CMD_TLBI_EL2_ALL= 0x20,
+SMMU_CMD_TLBI_EL2_ASID,
+SMMU_CMD_TLBI_EL2_VA,
+SMMU_CMD_TLBI_EL2_VAA,
+SMMU_CMD_TLBI_S12_VMALL  = 0x28,
+SMMU_CMD_TLBI_S2_IPA = 0x2a,
+SMMU_CMD_TLBI_NSNH_ALL   = 0x30,
+SMMU_CMD_ATC_INV = 0x40,
+SMMU_CMD_PRI_RESP,
+SMMU_CMD_RESUME  = 0x44,
+SMMU_CMD_STALL_TERM,
+SMMU_CMD_SYNC,
+} SMMUCommandType;
+
+static const char *cmd_stringify[] = {
+[SMMU_CMD_PREFETCH_CONFIG] = "SMMU_CMD_PREFETCH_CONFIG",
+[SMMU_CMD_PREFETCH_ADDR]   = "SMMU_CMD_PREFETCH_ADDR",
+[SMMU_CMD_CFGI_STE]= "SMMU_CMD_CFGI_STE",
+[SMMU_CMD_CFGI_STE_RANGE]  = "SMMU_CMD_CFGI_STE_RANGE",
+[SMMU_CMD_CFGI_CD] = "SMMU_CMD_CFGI_CD",
+[SMMU_CMD_CFGI_CD_ALL] = "SMMU_CMD_CFGI_CD_ALL",
+[SMMU_CMD_CFGI_ALL]= "SMMU_CMD_CFGI_ALL",
+[SMMU_CMD_TLBI_NH_ALL] = "SMMU_CMD_TLBI_NH_ALL",
+[SMMU_CMD_TLBI_NH_ASID]= "SMMU_CMD_TLBI_NH_ASID",
+[SMMU_CMD_TLBI_NH_VA]  = "SMMU_CMD_TLBI_NH_VA",
+[SMMU_CMD_TLBI_NH_VAA] = "SMMU_CMD_TLBI_NH_VAA",
+[SMMU_CMD_TLBI_EL3_ALL]= "SMMU_CMD_TLBI_EL3_ALL",
+[SMMU_CMD_TLBI_EL3_VA] = "SMMU_CMD_TLBI_EL3_VA",
+[SMMU_CMD_TLBI_EL2_ALL]= "SMMU_CMD_TLBI_EL2_ALL",
+[SMMU_CMD_TLBI_EL2_ASID]   = "SMMU_CMD_TLBI_EL2_ASID",
+[SMMU_CMD_TLBI_EL2_VA] = "SMMU_CMD_TLBI_EL2_VA",
+[SMMU_CMD_TLBI_EL2_VAA]= "SMMU_CMD_TLBI_EL2_VAA",
+[SMMU_CMD_TLBI_S12_VMALL]  = "SMMU_CMD_TLBI_S12_VMALL",
+[SMMU_CMD_TLBI_S2_IPA] = "SMMU_CMD_TLBI_S2_IPA",
+[SMMU_CMD_TLBI_NSNH_ALL]   = 

Re: [Qemu-devel] release retrospective, next release timing, numbering

2018-05-04 Thread Richard Henderson
On 05/04/2018 06:20 AM, Kevin Wolf wrote:
> I'm not sure what the exact systemd model is, but as we came to the
> conclusion that there is no semantic difference between major and minor
> version number for QEMU, I'd just merge them.
> 
> This would result in 3.0 for the next release, 3.1 etc. would be stable
> releases, and the December release would be 4.0.
> 
> It feels like the minimal change to fix our existing versioning scheme.

This is very similar to what GCC started to use at version 5.

https://gcc.gnu.org/develop.html#num_scheme

I do think it makes sense to drop minor versions, leaving only major +
patchlevel (which then appears to be minor version).


r~



[Qemu-devel] [PULL 19/24] hw/arm/smmuv3: Implement translate callback

2018-05-04 Thread Peter Maydell
From: Eric Auger 

This patch implements the IOMMU Memory Region translate()
callback. Most of the code relates to the translation
configuration decoding and check (STE, CD).

Signed-off-by: Eric Auger 
Signed-off-by: Prem Mallappa 
Message-id: 1524665762-31355-10-git-send-email-eric.au...@redhat.com
Reviewed-by: Peter Maydell 
Signed-off-by: Peter Maydell 
---
 hw/arm/smmuv3-internal.h | 160 +
 hw/arm/smmuv3.c  | 358 +++
 hw/arm/trace-events  |   9 +
 3 files changed, 527 insertions(+)

diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
index 2d50300a56..a9d714b56e 100644
--- a/hw/arm/smmuv3-internal.h
+++ b/hw/arm/smmuv3-internal.h
@@ -458,4 +458,164 @@ typedef struct SMMUEventInfo {
 
 void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo *event);
 
+/* Configuration Data */
+
+/* STE Level 1 Descriptor */
+typedef struct STEDesc {
+uint32_t word[2];
+} STEDesc;
+
+/* CD Level 1 Descriptor */
+typedef struct CDDesc {
+uint32_t word[2];
+} CDDesc;
+
+/* Stream Table Entry(STE) */
+typedef struct STE {
+uint32_t word[16];
+} STE;
+
+/* Context Descriptor(CD) */
+typedef struct CD {
+uint32_t word[16];
+} CD;
+
+/* STE fields */
+
+#define STE_VALID(x)   extract32((x)->word[0], 0, 1)
+
+#define STE_CONFIG(x)  extract32((x)->word[0], 1, 3)
+#define STE_CFG_S1_ENABLED(config) (config & 0x1)
+#define STE_CFG_S2_ENABLED(config) (config & 0x2)
+#define STE_CFG_ABORT(config)  (!(config & 0x4))
+#define STE_CFG_BYPASS(config) (config == 0x4)
+
+#define STE_S1FMT(x)   extract32((x)->word[0], 4 , 2)
+#define STE_S1CDMAX(x) extract32((x)->word[1], 27, 5)
+#define STE_S1STALLD(x)extract32((x)->word[2], 27, 1)
+#define STE_EATS(x)extract32((x)->word[2], 28, 2)
+#define STE_STRW(x)extract32((x)->word[2], 30, 2)
+#define STE_S2VMID(x)  extract32((x)->word[4], 0 , 16)
+#define STE_S2T0SZ(x)  extract32((x)->word[5], 0 , 6)
+#define STE_S2SL0(x)   extract32((x)->word[5], 6 , 2)
+#define STE_S2TG(x)extract32((x)->word[5], 14, 2)
+#define STE_S2PS(x)extract32((x)->word[5], 16, 3)
+#define STE_S2AA64(x)  extract32((x)->word[5], 19, 1)
+#define STE_S2HD(x)extract32((x)->word[5], 24, 1)
+#define STE_S2HA(x)extract32((x)->word[5], 25, 1)
+#define STE_S2S(x) extract32((x)->word[5], 26, 1)
+#define STE_CTXPTR(x)   \
+({  \
+unsigned long addr; \
+addr = (uint64_t)extract32((x)->word[1], 0, 16) << 32;  \
+addr |= (uint64_t)((x)->word[0] & 0xffc0);  \
+addr;   \
+})
+
+#define STE_S2TTB(x)\
+({  \
+unsigned long addr; \
+addr = (uint64_t)extract32((x)->word[7], 0, 16) << 32;  \
+addr |= (uint64_t)((x)->word[6] & 0xfff0);  \
+addr;   \
+})
+
+static inline int oas2bits(int oas_field)
+{
+switch (oas_field) {
+case 0:
+return 32;
+case 1:
+return 36;
+case 2:
+return 40;
+case 3:
+return 42;
+case 4:
+return 44;
+case 5:
+return 48;
+}
+return -1;
+}
+
+static inline int pa_range(STE *ste)
+{
+int oas_field = MIN(STE_S2PS(ste), SMMU_IDR5_OAS);
+
+if (!STE_S2AA64(ste)) {
+return 40;
+}
+
+return oas2bits(oas_field);
+}
+
+#define MAX_PA(ste) ((1 << pa_range(ste)) - 1)
+
+/* CD fields */
+
+#define CD_VALID(x)   extract32((x)->word[0], 30, 1)
+#define CD_ASID(x)extract32((x)->word[1], 16, 16)
+#define CD_TTB(x, sel)  \
+({  \
+uint64_t hi, lo;\
+hi = extract32((x)->word[(sel) * 2 + 3], 0, 19);\
+hi <<= 32;  \
+lo = (x)->word[(sel) * 2 + 2] & ~0xfULL;\
+hi | lo;\
+})
+
+#define CD_TSZ(x, sel)   extract32((x)->word[0], (16 * (sel)) + 0, 6)
+#define CD_TG(x, sel)extract32((x)->word[0], (16 * (sel)) + 6, 2)
+#define CD_EPD(x, sel)   extract32((x)->word[0], (16 * (sel)) + 14, 1)
+#define CD_ENDI(x)   extract32((x)->word[0], 15, 1)
+#define CD_IPS(x)extract32((x)->word[1], 0 , 3)
+#define CD_TBI(x)extract32((x)->word[1], 6 , 2)
+#define CD_HD(x) extract32((x)->word[1], 10 , 1)
+#define CD_HA(x) extract32((x)->word[1], 11 , 1)
+#define CD_S(x)  

[Qemu-devel] [PULL 13/24] hw/arm/smmu-common: VMSAv8-64 page table walk

2018-05-04 Thread Peter Maydell
From: Eric Auger 

This patch implements the page table walk for VMSAv8-64.

Signed-off-by: Eric Auger 
Signed-off-by: Prem Mallappa 
Message-id: 1524665762-31355-4-git-send-email-eric.au...@redhat.com
Reviewed-by: Peter Maydell 
Signed-off-by: Peter Maydell 
---
 hw/arm/smmu-internal.h   |  99 
 include/hw/arm/smmu-common.h |  14 +++
 hw/arm/smmu-common.c | 222 +++
 hw/arm/trace-events  |   9 +-
 4 files changed, 343 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/smmu-internal.h

diff --git a/hw/arm/smmu-internal.h b/hw/arm/smmu-internal.h
new file mode 100644
index 00..7794d6d394
--- /dev/null
+++ b/hw/arm/smmu-internal.h
@@ -0,0 +1,99 @@
+/*
+ * ARM SMMU support - Internal API
+ *
+ * Copyright (c) 2017 Red Hat, Inc.
+ * Copyright (C) 2014-2016 Broadcom Corporation
+ * Written by Prem Mallappa, Eric Auger
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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
+ * 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 HW_ARM_SMMU_INTERNAL_H
+#define HW_ARM_SMMU_INTERNAL_H
+
+#define TBI0(tbi) ((tbi) & 0x1)
+#define TBI1(tbi) ((tbi) & 0x2 >> 1)
+
+/* PTE Manipulation */
+
+#define ARM_LPAE_PTE_TYPE_SHIFT 0
+#define ARM_LPAE_PTE_TYPE_MASK  0x3
+
+#define ARM_LPAE_PTE_TYPE_BLOCK 1
+#define ARM_LPAE_PTE_TYPE_TABLE 3
+
+#define ARM_LPAE_L3_PTE_TYPE_RESERVED   1
+#define ARM_LPAE_L3_PTE_TYPE_PAGE   3
+
+#define ARM_LPAE_PTE_VALID  (1 << 0)
+
+#define PTE_ADDRESS(pte, shift) \
+(extract64(pte, shift, 47 - shift + 1) << shift)
+
+#define is_invalid_pte(pte) (!(pte & ARM_LPAE_PTE_VALID))
+
+#define is_reserved_pte(pte, level)  \
+((level == 3) && \
+ ((pte & ARM_LPAE_PTE_TYPE_MASK) == ARM_LPAE_L3_PTE_TYPE_RESERVED))
+
+#define is_block_pte(pte, level) \
+((level < 3) &&  \
+ ((pte & ARM_LPAE_PTE_TYPE_MASK) == ARM_LPAE_PTE_TYPE_BLOCK))
+
+#define is_table_pte(pte, level)\
+((level < 3) && \
+ ((pte & ARM_LPAE_PTE_TYPE_MASK) == ARM_LPAE_PTE_TYPE_TABLE))
+
+#define is_page_pte(pte, level) \
+((level == 3) &&\
+ ((pte & ARM_LPAE_PTE_TYPE_MASK) == ARM_LPAE_L3_PTE_TYPE_PAGE))
+
+/* access permissions */
+
+#define PTE_AP(pte) \
+(extract64(pte, 6, 2))
+
+#define PTE_APTABLE(pte) \
+(extract64(pte, 61, 2))
+
+/*
+ * TODO: At the moment all transactions are considered as privileged (EL1)
+ * as IOMMU translation callback does not pass user/priv attributes.
+ */
+#define is_permission_fault(ap, perm) \
+(((perm) & IOMMU_WO) && ((ap) & 0x2))
+
+#define PTE_AP_TO_PERM(ap) \
+(IOMMU_ACCESS_FLAG(true, !((ap) & 0x2)))
+
+/* Level Indexing */
+
+static inline int level_shift(int level, int granule_sz)
+{
+return granule_sz + (3 - level) * (granule_sz - 3);
+}
+
+static inline uint64_t level_page_mask(int level, int granule_sz)
+{
+return ~(MAKE_64BIT_MASK(0, level_shift(level, granule_sz)));
+}
+
+static inline
+uint64_t iova_level_offset(uint64_t iova, int inputsize,
+   int level, int gsz)
+{
+return ((iova & MAKE_64BIT_MASK(0, inputsize)) >> level_shift(level, gsz)) 
&
+MAKE_64BIT_MASK(0, gsz - 3);
+}
+
+#endif
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
index 8b947774b0..c41eb5c3b0 100644
--- a/include/hw/arm/smmu-common.h
+++ b/include/hw/arm/smmu-common.h
@@ -128,4 +128,18 @@ static inline uint16_t smmu_get_sid(SMMUDevice *sdev)
 {
 return PCI_BUILD_BDF(pci_bus_num(sdev->bus), sdev->devfn);
 }
+
+/**
+ * smmu_ptw - Perform the page table walk for a given iova / access flags
+ * pair, according to @cfg translation config
+ */
+int smmu_ptw(SMMUTransCfg *cfg, dma_addr_t iova, IOMMUAccessFlags perm,
+ IOMMUTLBEntry *tlbe, SMMUPTWEventInfo *info);
+
+/**
+ * select_tt - compute which translation table shall be used according to
+ * the input iova and translation config and return the TT specific info
+ */
+SMMUTransTableInfo *select_tt(SMMUTransCfg *cfg, dma_addr_t iova);
+
 #endif  /* 

[Qemu-devel] [PULL 23/24] hw/arm/virt-acpi-build: Add smmuv3 node in IORT table

2018-05-04 Thread Peter Maydell
From: Prem Mallappa 

This patch builds the smmuv3 node in the ACPI IORT table.

The RID space of the root complex, which spans 0x0-0x1
maps to streamid space 0x0-0x1 in smmuv3, which in turn
maps to deviceid space 0x0-0x1 in the ITS group.

The guest must feature the IOMMU probe deferral series
(https://lkml.org/lkml/2017/4/10/214) which fixes streamid
multiple lookup. This bug is not related to the SMMU emulation.

Signed-off-by: Prem Mallappa 
Signed-off-by: Eric Auger 
Reviewed-by: Shannon Zhao 
Message-id: 1524665762-31355-14-git-send-email-eric.au...@redhat.com
Signed-off-by: Peter Maydell 
---
 include/hw/acpi/acpi-defs.h | 15 ++
 hw/arm/virt-acpi-build.c| 55 -
 2 files changed, 63 insertions(+), 7 deletions(-)

diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
index 5955eb4fc0..af8e023968 100644
--- a/include/hw/acpi/acpi-defs.h
+++ b/include/hw/acpi/acpi-defs.h
@@ -628,6 +628,21 @@ struct AcpiIortItsGroup {
 } QEMU_PACKED;
 typedef struct AcpiIortItsGroup AcpiIortItsGroup;
 
+struct AcpiIortSmmu3 {
+ACPI_IORT_NODE_HEADER_DEF
+uint64_t base_address;
+uint32_t flags;
+uint32_t reserved2;
+uint64_t vatos_address;
+uint32_t model;
+uint32_t event_gsiv;
+uint32_t pri_gsiv;
+uint32_t gerr_gsiv;
+uint32_t sync_gsiv;
+AcpiIortIdMapping id_mapping_array[0];
+} QEMU_PACKED;
+typedef struct AcpiIortSmmu3 AcpiIortSmmu3;
+
 struct AcpiIortRC {
 ACPI_IORT_NODE_HEADER_DEF
 AcpiIortMemoryAccess memory_properties;
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index c7c6a57ec5..92ceee9c0f 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -393,19 +393,26 @@ build_rsdp(GArray *rsdp_table, BIOSLinker *linker, 
unsigned xsdt_tbl_offset)
 }
 
 static void
-build_iort(GArray *table_data, BIOSLinker *linker)
+build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
 {
-int iort_start = table_data->len;
+int nb_nodes, iort_start = table_data->len;
 AcpiIortIdMapping *idmap;
 AcpiIortItsGroup *its;
 AcpiIortTable *iort;
-size_t node_size, iort_length;
+AcpiIortSmmu3 *smmu;
+size_t node_size, iort_length, smmu_offset = 0;
 AcpiIortRC *rc;
 
 iort = acpi_data_push(table_data, sizeof(*iort));
 
+if (vms->iommu == VIRT_IOMMU_SMMUV3) {
+nb_nodes = 3; /* RC, ITS, SMMUv3 */
+} else {
+nb_nodes = 2; /* RC, ITS */
+}
+
 iort_length = sizeof(*iort);
-iort->node_count = cpu_to_le32(2); /* RC and ITS nodes */
+iort->node_count = cpu_to_le32(nb_nodes);
 iort->node_offset = cpu_to_le32(sizeof(*iort));
 
 /* ITS group node */
@@ -418,6 +425,34 @@ build_iort(GArray *table_data, BIOSLinker *linker)
 its->its_count = cpu_to_le32(1);
 its->identifiers[0] = 0; /* MADT translation_id */
 
+if (vms->iommu == VIRT_IOMMU_SMMUV3) {
+int irq =  vms->irqmap[VIRT_SMMU];
+
+/* SMMUv3 node */
+smmu_offset = iort->node_offset + node_size;
+node_size = sizeof(*smmu) + sizeof(*idmap);
+iort_length += node_size;
+smmu = acpi_data_push(table_data, node_size);
+
+smmu->type = ACPI_IORT_NODE_SMMU_V3;
+smmu->length = cpu_to_le16(node_size);
+smmu->mapping_count = cpu_to_le32(1);
+smmu->mapping_offset = cpu_to_le32(sizeof(*smmu));
+smmu->base_address = cpu_to_le64(vms->memmap[VIRT_SMMU].base);
+smmu->event_gsiv = cpu_to_le32(irq);
+smmu->pri_gsiv = cpu_to_le32(irq + 1);
+smmu->gerr_gsiv = cpu_to_le32(irq + 2);
+smmu->sync_gsiv = cpu_to_le32(irq + 3);
+
+/* Identity RID mapping covering the whole input RID range */
+idmap = >id_mapping_array[0];
+idmap->input_base = 0;
+idmap->id_count = cpu_to_le32(0x);
+idmap->output_base = 0;
+/* output IORT node is the ITS group node (the first node) */
+idmap->output_reference = cpu_to_le32(iort->node_offset);
+}
+
 /* Root Complex Node */
 node_size = sizeof(*rc) + sizeof(*idmap);
 iort_length += node_size;
@@ -438,8 +473,14 @@ build_iort(GArray *table_data, BIOSLinker *linker)
 idmap->input_base = 0;
 idmap->id_count = cpu_to_le32(0x);
 idmap->output_base = 0;
-/* output IORT node is the ITS group node (the first node) */
-idmap->output_reference = cpu_to_le32(iort->node_offset);
+
+if (vms->iommu == VIRT_IOMMU_SMMUV3) {
+/* output IORT node is the smmuv3 node */
+idmap->output_reference = cpu_to_le32(smmu_offset);
+} else {
+/* output IORT node is the ITS group node (the first node) */
+idmap->output_reference = cpu_to_le32(iort->node_offset);
+}
 
 iort->length = cpu_to_le32(iort_length);
 
@@ -777,7 +818,7 @@ void 

[Qemu-devel] [PULL 17/24] hw/arm/smmuv3: Implement MMIO write operations

2018-05-04 Thread Peter Maydell
From: Eric Auger 

Now we have relevant helpers for queue and irq
management, let's implement MMIO write operations.

Signed-off-by: Eric Auger 
Signed-off-by: Prem Mallappa 
Reviewed-by: Peter Maydell 
Message-id: 1524665762-31355-8-git-send-email-eric.au...@redhat.com
Signed-off-by: Peter Maydell 
---
 hw/arm/smmuv3-internal.h |   8 +-
 hw/arm/smmuv3.c  | 170 +--
 hw/arm/trace-events  |   6 ++
 3 files changed, 174 insertions(+), 10 deletions(-)

diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
index 223d8406ed..282285d310 100644
--- a/hw/arm/smmuv3-internal.h
+++ b/hw/arm/smmuv3-internal.h
@@ -61,6 +61,8 @@ REG32(CR0, 0x20)
 FIELD(CR0, EVENTQEN,  2, 1)
 FIELD(CR0, CMDQEN,3, 1)
 
+#define SMMU_CR0_RESERVED 0xFC20
+
 REG32(CR0ACK,  0x24)
 REG32(CR1, 0x28)
 REG32(CR2, 0x2c)
@@ -149,10 +151,6 @@ static inline bool smmuv3_gerror_irq_enabled(SMMUv3State 
*s)
 return FIELD_EX32(s->irq_ctrl, IRQ_CTRL, GERROR_IRQEN);
 }
 
-/* public until callers get introduced */
-void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq irq, uint32_t gerror_mask);
-void smmuv3_write_gerrorn(SMMUv3State *s, uint32_t gerrorn);
-
 /* Queue Handling */
 
 #define Q_BASE(q)  ((q)->base & SMMU_BASE_ADDR_MASK)
@@ -314,6 +312,6 @@ enum { /* Command completion notification */
 addr; \
 })
 
-int smmuv3_cmdq_consume(SMMUv3State *s);
+#define SMMU_FEATURE_2LVL_STE (1 << 0)
 
 #endif
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
index 8f50f1565b..d581ada3d7 100644
--- a/hw/arm/smmuv3.c
+++ b/hw/arm/smmuv3.c
@@ -38,7 +38,8 @@
  * @irq: irq type
  * @gerror_mask: mask of gerrors to toggle (relevant if @irq is GERROR)
  */
-void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq irq, uint32_t gerror_mask)
+static void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq irq,
+   uint32_t gerror_mask)
 {
 
 bool pulse = false;
@@ -75,7 +76,7 @@ void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq irq, uint32_t 
gerror_mask)
 }
 }
 
-void smmuv3_write_gerrorn(SMMUv3State *s, uint32_t new_gerrorn)
+static void smmuv3_write_gerrorn(SMMUv3State *s, uint32_t new_gerrorn)
 {
 uint32_t pending = s->gerror ^ s->gerrorn;
 uint32_t toggled = s->gerrorn ^ new_gerrorn;
@@ -174,7 +175,7 @@ static void smmuv3_init_regs(SMMUv3State *s)
 s->sid_split = 0;
 }
 
-int smmuv3_cmdq_consume(SMMUv3State *s)
+static int smmuv3_cmdq_consume(SMMUv3State *s)
 {
 SMMUCmdError cmd_error = SMMU_CERROR_NONE;
 SMMUQueue *q = >cmdq;
@@ -270,11 +271,170 @@ int smmuv3_cmdq_consume(SMMUv3State *s)
 return 0;
 }
 
+static MemTxResult smmu_writell(SMMUv3State *s, hwaddr offset,
+   uint64_t data, MemTxAttrs attrs)
+{
+switch (offset) {
+case A_GERROR_IRQ_CFG0:
+s->gerror_irq_cfg0 = data;
+return MEMTX_OK;
+case A_STRTAB_BASE:
+s->strtab_base = data;
+return MEMTX_OK;
+case A_CMDQ_BASE:
+s->cmdq.base = data;
+s->cmdq.log2size = extract64(s->cmdq.base, 0, 5);
+if (s->cmdq.log2size > SMMU_CMDQS) {
+s->cmdq.log2size = SMMU_CMDQS;
+}
+return MEMTX_OK;
+case A_EVENTQ_BASE:
+s->eventq.base = data;
+s->eventq.log2size = extract64(s->eventq.base, 0, 5);
+if (s->eventq.log2size > SMMU_EVENTQS) {
+s->eventq.log2size = SMMU_EVENTQS;
+}
+return MEMTX_OK;
+case A_EVENTQ_IRQ_CFG0:
+s->eventq_irq_cfg0 = data;
+return MEMTX_OK;
+default:
+qemu_log_mask(LOG_UNIMP,
+  "%s Unexpected 64-bit access to 0x%"PRIx64" (WI)\n",
+  __func__, offset);
+return MEMTX_OK;
+}
+}
+
+static MemTxResult smmu_writel(SMMUv3State *s, hwaddr offset,
+   uint64_t data, MemTxAttrs attrs)
+{
+switch (offset) {
+case A_CR0:
+s->cr[0] = data;
+s->cr0ack = data & ~SMMU_CR0_RESERVED;
+/* in case the command queue has been enabled */
+smmuv3_cmdq_consume(s);
+return MEMTX_OK;
+case A_CR1:
+s->cr[1] = data;
+return MEMTX_OK;
+case A_CR2:
+s->cr[2] = data;
+return MEMTX_OK;
+case A_IRQ_CTRL:
+s->irq_ctrl = data;
+return MEMTX_OK;
+case A_GERRORN:
+smmuv3_write_gerrorn(s, data);
+/*
+ * By acknowledging the CMDQ_ERR, SW may notify cmds can
+ * be processed again
+ */
+smmuv3_cmdq_consume(s);
+return MEMTX_OK;
+case A_GERROR_IRQ_CFG0: /* 64b */
+s->gerror_irq_cfg0 = deposit64(s->gerror_irq_cfg0, 0, 32, data);
+return MEMTX_OK;
+case A_GERROR_IRQ_CFG0 + 4:
+

[Qemu-devel] [PULL 12/24] hw/arm/smmu-common: IOMMU memory region and address space setup

2018-05-04 Thread Peter Maydell
From: Eric Auger 

We set up the infrastructure to enumerate all the PCI devices
attached to the SMMU and create an associated IOMMU memory
region and address space.

Those info are stored in SMMUDevice objects. The devices are
grouped according to the PCIBus they belong to. A hash table
indexed by the PCIBus pointer is used. Also an array indexed by
the bus number allows to find the list of SMMUDevices.

Signed-off-by: Eric Auger 
Signed-off-by: Prem Mallappa 
Reviewed-by: Peter Maydell 
Message-id: 1524665762-31355-3-git-send-email-eric.au...@redhat.com
Signed-off-by: Peter Maydell 
---
 include/hw/arm/smmu-common.h |  8 +
 hw/arm/smmu-common.c | 69 
 hw/arm/trace-events  |  3 ++
 3 files changed, 80 insertions(+)

diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
index d682be82d2..8b947774b0 100644
--- a/include/hw/arm/smmu-common.h
+++ b/include/hw/arm/smmu-common.h
@@ -120,4 +120,12 @@ typedef struct {
 #define ARM_SMMU_GET_CLASS(obj)  \
 OBJECT_GET_CLASS(SMMUBaseClass, (obj), TYPE_ARM_SMMU)
 
+/* Return the SMMUPciBus handle associated to a PCI bus number */
+SMMUPciBus *smmu_find_smmu_pcibus(SMMUState *s, uint8_t bus_num);
+
+/* Return the stream ID of an SMMU device */
+static inline uint16_t smmu_get_sid(SMMUDevice *sdev)
+{
+return PCI_BUILD_BDF(pci_bus_num(sdev->bus), sdev->devfn);
+}
 #endif  /* HW_ARM_SMMU_COMMON */
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
index e086ff52a5..3d64bcfac2 100644
--- a/hw/arm/smmu-common.c
+++ b/hw/arm/smmu-common.c
@@ -28,8 +28,69 @@
 #include "qemu/error-report.h"
 #include "hw/arm/smmu-common.h"
 
+/**
+ * The bus number is used for lookup when SID based invalidation occurs.
+ * In that case we lazily populate the SMMUPciBus array from the bus hash
+ * table. At the time the SMMUPciBus is created (smmu_find_add_as), the bus
+ * numbers may not be always initialized yet.
+ */
+SMMUPciBus *smmu_find_smmu_pcibus(SMMUState *s, uint8_t bus_num)
+{
+SMMUPciBus *smmu_pci_bus = s->smmu_pcibus_by_bus_num[bus_num];
+
+if (!smmu_pci_bus) {
+GHashTableIter iter;
+
+g_hash_table_iter_init(, s->smmu_pcibus_by_busptr);
+while (g_hash_table_iter_next(, NULL, (void **)_pci_bus)) {
+if (pci_bus_num(smmu_pci_bus->bus) == bus_num) {
+s->smmu_pcibus_by_bus_num[bus_num] = smmu_pci_bus;
+return smmu_pci_bus;
+}
+}
+}
+return smmu_pci_bus;
+}
+
+static AddressSpace *smmu_find_add_as(PCIBus *bus, void *opaque, int devfn)
+{
+SMMUState *s = opaque;
+SMMUPciBus *sbus = g_hash_table_lookup(s->smmu_pcibus_by_busptr, bus);
+SMMUDevice *sdev;
+
+if (!sbus) {
+sbus = g_malloc0(sizeof(SMMUPciBus) +
+ sizeof(SMMUDevice *) * SMMU_PCI_DEVFN_MAX);
+sbus->bus = bus;
+g_hash_table_insert(s->smmu_pcibus_by_busptr, bus, sbus);
+}
+
+sdev = sbus->pbdev[devfn];
+if (!sdev) {
+char *name = g_strdup_printf("%s-%d-%d",
+ s->mrtypename,
+ pci_bus_num(bus), devfn);
+sdev = sbus->pbdev[devfn] = g_new0(SMMUDevice, 1);
+
+sdev->smmu = s;
+sdev->bus = bus;
+sdev->devfn = devfn;
+
+memory_region_init_iommu(>iommu, sizeof(sdev->iommu),
+ s->mrtypename,
+ OBJECT(s), name, 1ULL << SMMU_MAX_VA_BITS);
+address_space_init(>as,
+   MEMORY_REGION(>iommu), name);
+trace_smmu_add_mr(name);
+g_free(name);
+}
+
+return >as;
+}
+
 static void smmu_base_realize(DeviceState *dev, Error **errp)
 {
+SMMUState *s = ARM_SMMU(dev);
 SMMUBaseClass *sbc = ARM_SMMU_GET_CLASS(dev);
 Error *local_err = NULL;
 
@@ -38,6 +99,14 @@ static void smmu_base_realize(DeviceState *dev, Error **errp)
 error_propagate(errp, local_err);
 return;
 }
+
+s->smmu_pcibus_by_busptr = g_hash_table_new(NULL, NULL);
+
+if (s->primary_bus) {
+pci_setup_iommu(s->primary_bus, smmu_find_add_as, s);
+} else {
+error_setg(errp, "SMMU is not attached to any PCI bus!");
+}
 }
 
 static void smmu_base_reset(DeviceState *dev)
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
index 193063ed99..8e8b53c95d 100644
--- a/hw/arm/trace-events
+++ b/hw/arm/trace-events
@@ -2,3 +2,6 @@
 
 # hw/arm/virt-acpi-build.c
 virt_acpi_setup(void) "No fw cfg or ACPI disabled. Bailing out."
+
+# hw/arm/smmu-common.c
+smmu_add_mr(const char *name) "%s"
\ No newline at end of file
-- 
2.17.0




[Qemu-devel] [PULL 15/24] hw/arm/smmuv3: Wired IRQ and GERROR helpers

2018-05-04 Thread Peter Maydell
From: Eric Auger 

We introduce some helpers to handle wired IRQs and especially
GERROR interrupt. SMMU writes GERROR register on GERROR event
and SW acks GERROR interrupts by setting GERRORn.

The Wired interrupts are edge sensitive hence the pulse usage.

Signed-off-by: Eric Auger 
Signed-off-by: Prem Mallappa 
Reviewed-by: Peter Maydell 
Message-id: 1524665762-31355-6-git-send-email-eric.au...@redhat.com
Signed-off-by: Peter Maydell 
---
 hw/arm/smmuv3-internal.h | 14 +
 hw/arm/smmuv3.c  | 64 
 hw/arm/trace-events  |  3 ++
 3 files changed, 81 insertions(+)

diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
index 8da38d46c0..e27c128c07 100644
--- a/hw/arm/smmuv3-internal.h
+++ b/hw/arm/smmuv3-internal.h
@@ -139,4 +139,18 @@ static inline uint32_t smmuv3_idreg(int regoffset)
 return smmuv3_ids[regoffset / 4];
 }
 
+static inline bool smmuv3_eventq_irq_enabled(SMMUv3State *s)
+{
+return FIELD_EX32(s->irq_ctrl, IRQ_CTRL, EVENTQ_IRQEN);
+}
+
+static inline bool smmuv3_gerror_irq_enabled(SMMUv3State *s)
+{
+return FIELD_EX32(s->irq_ctrl, IRQ_CTRL, GERROR_IRQEN);
+}
+
+/* public until callers get introduced */
+void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq irq, uint32_t gerror_mask);
+void smmuv3_write_gerrorn(SMMUv3State *s, uint32_t gerrorn);
+
 #endif
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
index b61f274393..c0cedcaba3 100644
--- a/hw/arm/smmuv3.c
+++ b/hw/arm/smmuv3.c
@@ -31,6 +31,70 @@
 #include "hw/arm/smmuv3.h"
 #include "smmuv3-internal.h"
 
+/**
+ * smmuv3_trigger_irq - pulse @irq if enabled and update
+ * GERROR register in case of GERROR interrupt
+ *
+ * @irq: irq type
+ * @gerror_mask: mask of gerrors to toggle (relevant if @irq is GERROR)
+ */
+void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq irq, uint32_t gerror_mask)
+{
+
+bool pulse = false;
+
+switch (irq) {
+case SMMU_IRQ_EVTQ:
+pulse = smmuv3_eventq_irq_enabled(s);
+break;
+case SMMU_IRQ_PRIQ:
+qemu_log_mask(LOG_UNIMP, "PRI not yet supported\n");
+break;
+case SMMU_IRQ_CMD_SYNC:
+pulse = true;
+break;
+case SMMU_IRQ_GERROR:
+{
+uint32_t pending = s->gerror ^ s->gerrorn;
+uint32_t new_gerrors = ~pending & gerror_mask;
+
+if (!new_gerrors) {
+/* only toggle non pending errors */
+return;
+}
+s->gerror ^= new_gerrors;
+trace_smmuv3_write_gerror(new_gerrors, s->gerror);
+
+pulse = smmuv3_gerror_irq_enabled(s);
+break;
+}
+}
+if (pulse) {
+trace_smmuv3_trigger_irq(irq);
+qemu_irq_pulse(s->irq[irq]);
+}
+}
+
+void smmuv3_write_gerrorn(SMMUv3State *s, uint32_t new_gerrorn)
+{
+uint32_t pending = s->gerror ^ s->gerrorn;
+uint32_t toggled = s->gerrorn ^ new_gerrorn;
+
+if (toggled & ~pending) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "guest toggles non pending errors = 0x%x\n",
+  toggled & ~pending);
+}
+
+/*
+ * We do not raise any error in case guest toggles bits corresponding
+ * to not active IRQs (CONSTRAINED UNPREDICTABLE)
+ */
+s->gerrorn = new_gerrorn;
+
+trace_smmuv3_write_gerrorn(toggled & pending, s->gerrorn);
+}
+
 static void smmuv3_init_regs(SMMUv3State *s)
 {
 /**
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
index 2f3d74a497..b77f8d2d1a 100644
--- a/hw/arm/trace-events
+++ b/hw/arm/trace-events
@@ -15,3 +15,6 @@ smmu_get_pte(uint64_t baseaddr, int index, uint64_t pteaddr, 
uint64_t pte) "base
 
 #hw/arm/smmuv3.c
 smmuv3_read_mmio(uint64_t addr, uint64_t val, unsigned size, uint32_t r) 
"addr: 0x%"PRIx64" val:0x%"PRIx64" size: 0x%x(%d)"
+smmuv3_trigger_irq(int irq) "irq=%d"
+smmuv3_write_gerror(uint32_t toggled, uint32_t gerror) "toggled=0x%x, new 
GERROR=0x%x"
+smmuv3_write_gerrorn(uint32_t acked, uint32_t gerrorn) "acked=0x%x, new 
GERRORN=0x%x"
-- 
2.17.0




[Qemu-devel] [PULL 08/24] target/arm: Tidy condition in disas_simd_two_reg_misc

2018-05-04 Thread Peter Maydell
From: Richard Henderson 

Path analysis shows that size == 3 && !is_q has been eliminated.

Fixes: Coverity CID1385853
Signed-off-by: Richard Henderson 
Reviewed-by: Alex Bennée 
Message-id: 20180501180455.11214-3-richard.hender...@linaro.org
Signed-off-by: Peter Maydell 
---
 target/arm/translate-a64.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 97950dce1a..6d49f30b4a 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -11473,7 +11473,11 @@ static void disas_simd_two_reg_misc(DisasContext *s, 
uint32_t insn)
 /* All 64-bit element operations can be shared with scalar 2misc */
 int pass;
 
-for (pass = 0; pass < (is_q ? 2 : 1); pass++) {
+/* Coverity claims (size == 3 && !is_q) has been eliminated
+ * from all paths leading to here.
+ */
+tcg_debug_assert(is_q);
+for (pass = 0; pass < 2; pass++) {
 TCGv_i64 tcg_op = tcg_temp_new_i64();
 TCGv_i64 tcg_res = tcg_temp_new_i64();
 
-- 
2.17.0




[Qemu-devel] [PULL 09/24] hw/arm: Don't fail qtest due to missing SD card in -nodefaults mode

2018-05-04 Thread Peter Maydell
From: Thomas Huth 

When running omap1/2 or pxa2xx based ARM machines with -nodefaults,
they bail out immediately complaining about a "missing SecureDigital
device". That's not how the "default" devices in vl.c are meant to
work - it should be possible for a board to also start up without
default devices. So let's turn the error message and exit() into
a warning instead.

Signed-off-by: Thomas Huth 
Message-id: 1525326811-3233-1-git-send-email-th...@redhat.com
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Peter Maydell 
Signed-off-by: Peter Maydell 
---
 hw/arm/omap1.c  |  8 
 hw/arm/omap2.c  |  8 
 hw/arm/pxa2xx.c | 15 +++
 3 files changed, 15 insertions(+), 16 deletions(-)

diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c
index 24673abfca..e54c1f8f99 100644
--- a/hw/arm/omap1.c
+++ b/hw/arm/omap1.c
@@ -30,6 +30,7 @@
 #include "hw/arm/soc_dma.h"
 #include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
+#include "sysemu/qtest.h"
 #include "qemu/range.h"
 #include "hw/sysbus.h"
 #include "qemu/cutils.h"
@@ -3987,12 +3988,11 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion 
*system_memory,
 omap_findclk(s, "dpll3"));
 
 dinfo = drive_get(IF_SD, 0, 0);
-if (!dinfo) {
-error_report("missing SecureDigital device");
-exit(1);
+if (!dinfo && !qtest_enabled()) {
+warn_report("missing SecureDigital device");
 }
 s->mmc = omap_mmc_init(0xfffb7800, system_memory,
-   blk_by_legacy_dinfo(dinfo),
+   dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
qdev_get_gpio_in(s->ih[1], OMAP_INT_OQN),
>drq[OMAP_DMA_MMC_TX],
 omap_findclk(s, "mmc_ck"));
diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c
index 80663533e1..b8d0910a1f 100644
--- a/hw/arm/omap2.c
+++ b/hw/arm/omap2.c
@@ -25,6 +25,7 @@
 #include "cpu.h"
 #include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
+#include "sysemu/qtest.h"
 #include "hw/boards.h"
 #include "hw/hw.h"
 #include "hw/arm/arm.h"
@@ -2486,12 +2487,11 @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion 
*sysmem,
  s->drq[OMAP24XX_DMA_GPMC]);
 
 dinfo = drive_get(IF_SD, 0, 0);
-if (!dinfo) {
-error_report("missing SecureDigital device");
-exit(1);
+if (!dinfo && !qtest_enabled()) {
+warn_report("missing SecureDigital device");
 }
 s->mmc = omap2_mmc_init(omap_l4tao(s->l4, 9),
-blk_by_legacy_dinfo(dinfo),
+dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
 qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_MMC_IRQ),
 >drq[OMAP24XX_DMA_MMC1_TX],
 omap_findclk(s, "mmc_fclk"), omap_findclk(s, "mmc_iclk"));
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index 928a0431d6..a2803fdee4 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -21,6 +21,7 @@
 #include "chardev/char-fe.h"
 #include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
+#include "sysemu/qtest.h"
 #include "qemu/cutils.h"
 
 static struct {
@@ -2095,12 +2096,11 @@ PXA2xxState *pxa270_init(MemoryRegion *address_space,
 s->gpio = pxa2xx_gpio_init(0x40e0, s->cpu, s->pic, 121);
 
 dinfo = drive_get(IF_SD, 0, 0);
-if (!dinfo) {
-error_report("missing SecureDigital device");
-exit(1);
+if (!dinfo && !qtest_enabled()) {
+warn_report("missing SecureDigital device");
 }
 s->mmc = pxa2xx_mmci_init(address_space, 0x4110,
-blk_by_legacy_dinfo(dinfo),
+dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
 qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC),
 qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_MMCI),
 qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_MMCI));
@@ -2220,12 +2220,11 @@ PXA2xxState *pxa255_init(MemoryRegion *address_space, 
unsigned int sdram_size)
 s->gpio = pxa2xx_gpio_init(0x40e0, s->cpu, s->pic, 85);
 
 dinfo = drive_get(IF_SD, 0, 0);
-if (!dinfo) {
-error_report("missing SecureDigital device");
-exit(1);
+if (!dinfo && !qtest_enabled()) {
+warn_report("missing SecureDigital device");
 }
 s->mmc = pxa2xx_mmci_init(address_space, 0x4110,
-blk_by_legacy_dinfo(dinfo),
+dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
 qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC),
 qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_MMCI),
 qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_MMCI));
-- 
2.17.0




[Qemu-devel] [PULL 22/24] hw/arm/virt: Add SMMUv3 to the virt board

2018-05-04 Thread Peter Maydell
From: Prem Mallappa 

Add code to instantiate an smmuv3 in virt machine. A new iommu
integer member is introduced in VirtMachineState to store the type
of the iommu in use.

Signed-off-by: Prem Mallappa 
Signed-off-by: Eric Auger 
Reviewed-by: Peter Maydell 
Message-id: 1524665762-31355-13-git-send-email-eric.au...@redhat.com
Signed-off-by: Peter Maydell 
---
 include/hw/arm/virt.h | 10 +++
 hw/arm/virt.c | 64 ++-
 2 files changed, 73 insertions(+), 1 deletion(-)

diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index ba0c1a4faa..886372cdbb 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -38,6 +38,7 @@
 
 #define NUM_GICV2M_SPIS   64
 #define NUM_VIRTIO_TRANSPORTS 32
+#define NUM_SMMU_IRQS  4
 
 #define ARCH_GICV3_MAINT_IRQ  9
 
@@ -59,6 +60,7 @@ enum {
 VIRT_GIC_V2M,
 VIRT_GIC_ITS,
 VIRT_GIC_REDIST,
+VIRT_SMMU,
 VIRT_UART,
 VIRT_MMIO,
 VIRT_RTC,
@@ -74,6 +76,12 @@ enum {
 VIRT_SECURE_MEM,
 };
 
+typedef enum VirtIOMMUType {
+VIRT_IOMMU_NONE,
+VIRT_IOMMU_SMMUV3,
+VIRT_IOMMU_VIRTIO,
+} VirtIOMMUType;
+
 typedef struct MemMapEntry {
 hwaddr base;
 hwaddr size;
@@ -97,6 +105,7 @@ typedef struct {
 bool its;
 bool virt;
 int32_t gic_version;
+VirtIOMMUType iommu;
 struct arm_boot_info bootinfo;
 const MemMapEntry *memmap;
 const int *irqmap;
@@ -106,6 +115,7 @@ typedef struct {
 uint32_t clock_phandle;
 uint32_t gic_phandle;
 uint32_t msi_phandle;
+uint32_t iommu_phandle;
 int psci_conduit;
 } VirtMachineState;
 
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index dc0c0335a2..b085f0b9b4 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -58,6 +58,7 @@
 #include "hw/smbios/smbios.h"
 #include "qapi/visitor.h"
 #include "standard-headers/linux/input.h"
+#include "hw/arm/smmuv3.h"
 
 #define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
 static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
@@ -141,6 +142,7 @@ static const MemMapEntry a15memmap[] = {
 [VIRT_FW_CFG] = { 0x0902, 0x0018 },
 [VIRT_GPIO] =   { 0x0903, 0x1000 },
 [VIRT_SECURE_UART] ={ 0x0904, 0x1000 },
+[VIRT_SMMU] =   { 0x0905, 0x0002 },
 [VIRT_MMIO] =   { 0x0a00, 0x0200 },
 /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
 [VIRT_PLATFORM_BUS] =   { 0x0c00, 0x0200 },
@@ -161,6 +163,7 @@ static const int a15irqmap[] = {
 [VIRT_SECURE_UART] = 8,
 [VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */
 [VIRT_GIC_V2M] = 48, /* ...to 48 + NUM_GICV2M_SPIS - 1 */
+[VIRT_SMMU] = 74,/* ...to 74 + NUM_SMMU_IRQS - 1 */
 [VIRT_PLATFORM_BUS] = 112, /* ...to 112 + PLATFORM_BUS_NUM_IRQS -1 */
 };
 
@@ -942,7 +945,57 @@ static void create_pcie_irq_map(const VirtMachineState 
*vms,
0x7   /* PCI irq */);
 }
 
-static void create_pcie(const VirtMachineState *vms, qemu_irq *pic)
+static void create_smmu(const VirtMachineState *vms, qemu_irq *pic,
+PCIBus *bus)
+{
+char *node;
+const char compat[] = "arm,smmu-v3";
+int irq =  vms->irqmap[VIRT_SMMU];
+int i;
+hwaddr base = vms->memmap[VIRT_SMMU].base;
+hwaddr size = vms->memmap[VIRT_SMMU].size;
+const char irq_names[] = "eventq\0priq\0cmdq-sync\0gerror";
+DeviceState *dev;
+
+if (vms->iommu != VIRT_IOMMU_SMMUV3 || !vms->iommu_phandle) {
+return;
+}
+
+dev = qdev_create(NULL, "arm-smmuv3");
+
+object_property_set_link(OBJECT(dev), OBJECT(bus), "primary-bus",
+ _abort);
+qdev_init_nofail(dev);
+sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
+for (i = 0; i < NUM_SMMU_IRQS; i++) {
+sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
+}
+
+node = g_strdup_printf("/smmuv3@%" PRIx64, base);
+qemu_fdt_add_subnode(vms->fdt, node);
+qemu_fdt_setprop(vms->fdt, node, "compatible", compat, sizeof(compat));
+qemu_fdt_setprop_sized_cells(vms->fdt, node, "reg", 2, base, 2, size);
+
+qemu_fdt_setprop_cells(vms->fdt, node, "interrupts",
+GIC_FDT_IRQ_TYPE_SPI, irq, GIC_FDT_IRQ_FLAGS_EDGE_LO_HI,
+GIC_FDT_IRQ_TYPE_SPI, irq + 1, GIC_FDT_IRQ_FLAGS_EDGE_LO_HI,
+GIC_FDT_IRQ_TYPE_SPI, irq + 2, GIC_FDT_IRQ_FLAGS_EDGE_LO_HI,
+GIC_FDT_IRQ_TYPE_SPI, irq + 3, GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
+
+qemu_fdt_setprop(vms->fdt, node, "interrupt-names", irq_names,
+ sizeof(irq_names));
+
+qemu_fdt_setprop_cell(vms->fdt, node, "clocks", vms->clock_phandle);
+qemu_fdt_setprop_string(vms->fdt, node, "clock-names", "apb_pclk");
+qemu_fdt_setprop(vms->fdt, node, 

[Qemu-devel] [PULL 10/24] target/arm: Implement v8M VLLDM and VLSTM

2018-05-04 Thread Peter Maydell
For v8M the instructions VLLDM and VLSTM support lazy saving
and restoring of the secure floating-point registers. Even
if the floating point extension is not implemented, these
instructions must act as NOPs in Secure state, so they can
be used as part of the secure-to-nonsecure call sequence.

Fixes: https://bugs.launchpad.net/qemu/+bug/1768295
Cc: qemu-sta...@nongnu.org
Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
Message-id: 20180503105730.5958-1-peter.mayd...@linaro.org
---
 target/arm/translate.c | 17 -
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/target/arm/translate.c b/target/arm/translate.c
index 9bc2ce1a0b..ad208867a7 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -10795,8 +10795,23 @@ static void disas_thumb2_insn(DisasContext *s, 
uint32_t insn)
 /* Coprocessor.  */
 if (arm_dc_feature(s, ARM_FEATURE_M)) {
 /* We don't currently implement M profile FP support,
- * so this entire space should give a NOCP fault.
+ * so this entire space should give a NOCP fault, with
+ * the exception of the v8M VLLDM and VLSTM insns, which
+ * must be NOPs in Secure state and UNDEF in Nonsecure state.
  */
+if (arm_dc_feature(s, ARM_FEATURE_V8) &&
+(insn & 0xffa00f00) == 0xec200a00) {
+/* 0b1110_1100_0x1x___1010__
+ *  - VLLDM, VLSTM
+ * We choose to UNDEF if the RAZ bits are non-zero.
+ */
+if (!s->v8m_secure || (insn & 0x0040f0ff)) {
+goto illegal_op;
+}
+/* Just NOP since FP support is not implemented */
+break;
+}
+/* All other insns: NOCP */
 gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
default_exception_el(s));
 break;
-- 
2.17.0




[Qemu-devel] [PULL 14/24] hw/arm/smmuv3: Skeleton

2018-05-04 Thread Peter Maydell
From: Prem Mallappa 

This patch implements a skeleton for the smmuv3 device.
Datatypes and register definitions are introduced. The MMIO
region, the interrupts and the queue are initialized.

Only the MMIO read operation is implemented here.

Signed-off-by: Prem Mallappa 
Signed-off-by: Eric Auger 
Reviewed-by: Peter Maydell 
Message-id: 1524665762-31355-5-git-send-email-eric.au...@redhat.com
Signed-off-by: Peter Maydell 
---
 hw/arm/Makefile.objs |   2 +-
 hw/arm/smmuv3-internal.h | 142 +++
 include/hw/arm/smmuv3.h  |  87 ++
 hw/arm/smmuv3.c  | 366 +++
 hw/arm/trace-events  |   3 +
 5 files changed, 599 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/smmuv3-internal.h
 create mode 100644 include/hw/arm/smmuv3.h
 create mode 100644 hw/arm/smmuv3.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 558436f3a5..d51fcecaf2 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -35,4 +35,4 @@ obj-$(CONFIG_MPS2) += mps2-tz.o
 obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
 obj-$(CONFIG_IOTKIT) += iotkit.o
 obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o mcimx7d-sabre.o
-obj-$(CONFIG_ARM_SMMUV3) += smmu-common.o
+obj-$(CONFIG_ARM_SMMUV3) += smmu-common.o smmuv3.o
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
new file mode 100644
index 00..8da38d46c0
--- /dev/null
+++ b/hw/arm/smmuv3-internal.h
@@ -0,0 +1,142 @@
+/*
+ * ARM SMMUv3 support - Internal API
+ *
+ * Copyright (C) 2014-2016 Broadcom Corporation
+ * Copyright (c) 2017 Red Hat, Inc.
+ * Written by Prem Mallappa, Eric Auger
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 HW_ARM_SMMU_V3_INTERNAL_H
+#define HW_ARM_SMMU_V3_INTERNAL_H
+
+#include "hw/arm/smmu-common.h"
+
+/* MMIO Registers */
+
+REG32(IDR0,0x0)
+FIELD(IDR0, S1P, 1 , 1)
+FIELD(IDR0, TTF, 2 , 2)
+FIELD(IDR0, COHACC,  4 , 1)
+FIELD(IDR0, ASID16,  12, 1)
+FIELD(IDR0, TTENDIAN,21, 2)
+FIELD(IDR0, STALL_MODEL, 24, 2)
+FIELD(IDR0, TERM_MODEL,  26, 1)
+FIELD(IDR0, STLEVEL, 27, 2)
+
+REG32(IDR1,0x4)
+FIELD(IDR1, SIDSIZE,  0 , 6)
+FIELD(IDR1, EVENTQS,  16, 5)
+FIELD(IDR1, CMDQS,21, 5)
+
+#define SMMU_IDR1_SIDSIZE 16
+#define SMMU_CMDQS   19
+#define SMMU_EVENTQS 19
+
+REG32(IDR2,0x8)
+REG32(IDR3,0xc)
+REG32(IDR4,0x10)
+REG32(IDR5,0x14)
+ FIELD(IDR5, OAS, 0, 3);
+ FIELD(IDR5, GRAN4K,  4, 1);
+ FIELD(IDR5, GRAN16K, 5, 1);
+ FIELD(IDR5, GRAN64K, 6, 1);
+
+#define SMMU_IDR5_OAS 4
+
+REG32(IIDR,0x1c)
+REG32(CR0, 0x20)
+FIELD(CR0, SMMU_ENABLE,   0, 1)
+FIELD(CR0, EVENTQEN,  2, 1)
+FIELD(CR0, CMDQEN,3, 1)
+
+REG32(CR0ACK,  0x24)
+REG32(CR1, 0x28)
+REG32(CR2, 0x2c)
+REG32(STATUSR, 0x40)
+REG32(IRQ_CTRL,0x50)
+FIELD(IRQ_CTRL, GERROR_IRQEN,0, 1)
+FIELD(IRQ_CTRL, PRI_IRQEN,   1, 1)
+FIELD(IRQ_CTRL, EVENTQ_IRQEN,2, 1)
+
+REG32(IRQ_CTRL_ACK,0x54)
+REG32(GERROR,  0x60)
+FIELD(GERROR, CMDQ_ERR,   0, 1)
+FIELD(GERROR, EVENTQ_ABT_ERR, 2, 1)
+FIELD(GERROR, PRIQ_ABT_ERR,   3, 1)
+FIELD(GERROR, MSI_CMDQ_ABT_ERR,   4, 1)
+FIELD(GERROR, MSI_EVENTQ_ABT_ERR, 5, 1)
+FIELD(GERROR, MSI_PRIQ_ABT_ERR,   6, 1)
+FIELD(GERROR, MSI_GERROR_ABT_ERR, 7, 1)
+FIELD(GERROR, MSI_SFM_ERR,8, 1)
+
+REG32(GERRORN, 0x64)
+
+#define A_GERROR_IRQ_CFG0  0x68 /* 64b */
+REG32(GERROR_IRQ_CFG1, 0x70)
+REG32(GERROR_IRQ_CFG2, 0x74)
+
+#define A_STRTAB_BASE  0x80 /* 64b */
+
+#define SMMU_BASE_ADDR_MASK 0xffe0
+
+REG32(STRTAB_BASE_CFG, 0x88)
+FIELD(STRTAB_BASE_CFG, FMT,  16, 2)
+FIELD(STRTAB_BASE_CFG, SPLIT,6 , 5)
+FIELD(STRTAB_BASE_CFG, LOG2SIZE, 0 , 6)
+
+#define A_CMDQ_BASE0x90 /* 64b */
+REG32(CMDQ_PROD,   0x98)
+REG32(CMDQ_CONS,   0x9c)
+FIELD(CMDQ_CONS, ERR, 24, 7)
+
+#define A_EVENTQ_BASE  0xa0 /* 64b */
+REG32(EVENTQ_PROD, 0xa8)
+REG32(EVENTQ_CONS, 0xac)
+
+#define A_EVENTQ_IRQ_CFG0  0xb0 /* 64b */

[Qemu-devel] [PULL 07/24] target/arm: Tidy conditions in handle_vec_simd_shri

2018-05-04 Thread Peter Maydell
From: Richard Henderson 

The (size > 3 && !is_q) condition is identical to the preceeding test
of bit 3 in immh; eliminate it.  For the benefit of Coverity, assert
that size is within the bounds we expect.

Fixes: Coverity CID1385846
Fixes: Coverity CID1385849
Fixes: Coverity CID1385852
Fixes: Coverity CID1385857
Signed-off-by: Richard Henderson 
Reviewed-by: Alex Bennée 
Message-id: 20180501180455.11214-2-richard.hender...@linaro.org
Signed-off-by: Peter Maydell 
---
 target/arm/translate-a64.c | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index bff4e13bf6..97950dce1a 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -9019,11 +9019,7 @@ static void handle_vec_simd_shri(DisasContext *s, bool 
is_q, bool is_u,
 unallocated_encoding(s);
 return;
 }
-
-if (size > 3 && !is_q) {
-unallocated_encoding(s);
-return;
-}
+tcg_debug_assert(size <= 3);
 
 if (!fp_access_check(s)) {
 return;
-- 
2.17.0




[Qemu-devel] [PULL 01/24] hw/arm/virt: Add linux, pci-domain property

2018-05-04 Thread Peter Maydell
From: Jan Kiszka 

This allows to pin the host controller in the Linux PCI domain space.
Linux requires that property to be available consistently or not at all,
in which case the domain number becomes unstable on additions/removals.
Adding it here won't make a difference in practice for most setups as we
only expose one controller.

However, enabling Jailhouse on top may introduce another controller, and
that one would like to have stable address as well. So the property is
needed for the first controller as well.

Signed-off-by: Jan Kiszka 
Message-id: 3301c5bc-7b47-1b0e-8ce4-30435057a...@web.de
Reviewed-by: Peter Maydell 
Signed-off-by: Peter Maydell 
---
 hw/arm/virt.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index a18291c5d5..dc0c0335a2 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1023,6 +1023,7 @@ static void create_pcie(const VirtMachineState *vms, 
qemu_irq *pic)
 qemu_fdt_setprop_string(vms->fdt, nodename, "device_type", "pci");
 qemu_fdt_setprop_cell(vms->fdt, nodename, "#address-cells", 3);
 qemu_fdt_setprop_cell(vms->fdt, nodename, "#size-cells", 2);
+qemu_fdt_setprop_cell(vms->fdt, nodename, "linux,pci-domain", 0);
 qemu_fdt_setprop_cells(vms->fdt, nodename, "bus-range", 0,
nr_pcie_buses - 1);
 qemu_fdt_setprop(vms->fdt, nodename, "dma-coherent", NULL, 0);
-- 
2.17.0




Re: [Qemu-devel] [RFC PATCH 0/6] generic way to deprecate machines

2018-05-04 Thread Thomas Huth
On 08.11.2017 03:28, Philippe Mathieu-Daudé wrote:
> Hi,
> 
> This series intends to provide a simple and common way to deprecate
> machines between releases. It may be extended to deprecate devices.

*ping*

Philippe, I just discovered your findings wrt to the Gumstix machines on
https://wiki.qemu.org/Features/LegacyRemoval#Deprecated_machines ...
sounds reasonable, so I think we should really continue here and mark
those as deprecated. And pc-0.10 and pc-0.11, too.

Do you have some spare time to respin your patch series?

 Thomas



[Qemu-devel] [PULL 06/24] arm: boot: set boot_info starting from first_cpu

2018-05-04 Thread Peter Maydell
From: Igor Mammedov 

Even though nothing is currently broken (since all boards
use first_cpu as boot cpu), make sure that boot_info is set
on all CPUs.
If some board would like support heterogenuos setup (i.e.
init boot_info on subset of CPUs) in future, it should add
a reasonable API to do it, instead of starting assigning
boot_info from some CPU and till the end of present CPUs
list.

Ref:
"Message-ID: 

[Qemu-devel] [PULL 05/24] hw/net/smc91c111: Convert away from old_mmio

2018-05-04 Thread Peter Maydell
Convert the smc91c111 device away from using the old_mmio field of
MemoryRegionOps. This device is used by several Arm board models.

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
Message-id: 20180427173611.10281-3-peter.mayd...@linaro.org
---
 hw/net/smc91c111.c | 54 +-
 1 file changed, 25 insertions(+), 29 deletions(-)

diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c
index 3b16dcf5a1..c8cc5379b7 100644
--- a/hw/net/smc91c111.c
+++ b/hw/net/smc91c111.c
@@ -625,37 +625,33 @@ static uint32_t smc91c111_readb(void *opaque, hwaddr 
offset)
 return 0;
 }
 
-static void smc91c111_writew(void *opaque, hwaddr offset,
- uint32_t value)
+static uint64_t smc91c111_readfn(void *opaque, hwaddr addr, unsigned size)
 {
-smc91c111_writeb(opaque, offset, value & 0xff);
-smc91c111_writeb(opaque, offset + 1, value >> 8);
+int i;
+uint32_t val = 0;
+
+for (i = 0; i < size; i++) {
+val |= smc91c111_readb(opaque, addr + i) << (i * 8);
+}
+return val;
 }
 
-static void smc91c111_writel(void *opaque, hwaddr offset,
- uint32_t value)
+static void smc91c111_writefn(void *opaque, hwaddr addr,
+   uint64_t value, unsigned size)
 {
+int i = 0;
+
 /* 32-bit writes to offset 0xc only actually write to the bank select
-   register (offset 0xe)  */
-if (offset != 0xc)
-smc91c111_writew(opaque, offset, value & 0x);
-smc91c111_writew(opaque, offset + 2, value >> 16);
-}
+ * register (offset 0xe), so skip the first two bytes we would write.
+ */
+if (addr == 0xc && size == 4) {
+i += 2;
+}
 
-static uint32_t smc91c111_readw(void *opaque, hwaddr offset)
-{
-uint32_t val;
-val = smc91c111_readb(opaque, offset);
-val |= smc91c111_readb(opaque, offset + 1) << 8;
-return val;
-}
-
-static uint32_t smc91c111_readl(void *opaque, hwaddr offset)
-{
-uint32_t val;
-val = smc91c111_readw(opaque, offset);
-val |= smc91c111_readw(opaque, offset + 2) << 16;
-return val;
+for (; i < size; i++) {
+smc91c111_writeb(opaque, addr + i,
+ extract32(value, i * 8, 8));
+}
 }
 
 static int smc91c111_can_receive_nc(NetClientState *nc)
@@ -747,10 +743,10 @@ static const MemoryRegionOps smc91c111_mem_ops = {
 /* The special case for 32 bit writes to 0xc means we can't just
  * set .impl.min/max_access_size to 1, unfortunately
  */
-.old_mmio = {
-.read = { smc91c111_readb, smc91c111_readw, smc91c111_readl, },
-.write = { smc91c111_writeb, smc91c111_writew, smc91c111_writel, },
-},
+.read = smc91c111_readfn,
+.write = smc91c111_writefn,
+.valid.min_access_size = 1,
+.valid.max_access_size = 4,
 .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-- 
2.17.0




[Qemu-devel] [PULL 11/24] hw/arm/smmu-common: smmu base device and datatypes

2018-05-04 Thread Peter Maydell
From: Eric Auger 

The patch introduces the smmu base device and class for the ARM
smmu. Devices for specific versions will be derived from this
base device.

We also introduce some important datatypes.

Signed-off-by: Eric Auger 
Signed-off-by: Prem Mallappa 
Reviewed-by: Peter Maydell 
Message-id: 1524665762-31355-2-git-send-email-eric.au...@redhat.com
Signed-off-by: Peter Maydell 
---
 hw/arm/Makefile.objs|   1 +
 include/hw/arm/smmu-common.h| 123 
 hw/arm/smmu-common.c|  81 ++
 default-configs/aarch64-softmmu.mak |   1 +
 4 files changed, 206 insertions(+)
 create mode 100644 include/hw/arm/smmu-common.h
 create mode 100644 hw/arm/smmu-common.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 2885e3e234..558436f3a5 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -35,3 +35,4 @@ obj-$(CONFIG_MPS2) += mps2-tz.o
 obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
 obj-$(CONFIG_IOTKIT) += iotkit.o
 obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o mcimx7d-sabre.o
+obj-$(CONFIG_ARM_SMMUV3) += smmu-common.o
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
new file mode 100644
index 00..d682be82d2
--- /dev/null
+++ b/include/hw/arm/smmu-common.h
@@ -0,0 +1,123 @@
+/*
+ * ARM SMMU Support
+ *
+ * Copyright (C) 2015-2016 Broadcom Corporation
+ * Copyright (c) 2017 Red Hat, Inc.
+ * Written by Prem Mallappa, Eric Auger
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HW_ARM_SMMU_COMMON_H
+#define HW_ARM_SMMU_COMMON_H
+
+#include "hw/sysbus.h"
+#include "hw/pci/pci.h"
+
+#define SMMU_PCI_BUS_MAX  256
+#define SMMU_PCI_DEVFN_MAX256
+
+#define SMMU_MAX_VA_BITS  48
+
+/*
+ * Page table walk error types
+ */
+typedef enum {
+SMMU_PTW_ERR_NONE,
+SMMU_PTW_ERR_WALK_EABT,   /* Translation walk external abort */
+SMMU_PTW_ERR_TRANSLATION, /* Translation fault */
+SMMU_PTW_ERR_ADDR_SIZE,   /* Address Size fault */
+SMMU_PTW_ERR_ACCESS,  /* Access fault */
+SMMU_PTW_ERR_PERMISSION,  /* Permission fault */
+} SMMUPTWEventType;
+
+typedef struct SMMUPTWEventInfo {
+SMMUPTWEventType type;
+dma_addr_t addr; /* fetched address that induced an abort, if any */
+} SMMUPTWEventInfo;
+
+typedef struct SMMUTransTableInfo {
+bool disabled; /* is the translation table disabled? */
+uint64_t ttb;  /* TT base address */
+uint8_t tsz;   /* input range, ie. 2^(64 -tsz)*/
+uint8_t granule_sz;/* granule page shift */
+} SMMUTransTableInfo;
+
+/*
+ * Generic structure populated by derived SMMU devices
+ * after decoding the configuration information and used as
+ * input to the page table walk
+ */
+typedef struct SMMUTransCfg {
+int stage; /* translation stage */
+bool aa64; /* arch64 or aarch32 translation table */
+bool disabled; /* smmu is disabled */
+bool bypassed; /* translation is bypassed */
+bool aborted;  /* translation is aborted */
+uint64_t ttb;  /* TT base address */
+uint8_t oas;   /* output address width */
+uint8_t tbi;   /* Top Byte Ignore */
+uint16_t asid;
+SMMUTransTableInfo tt[2];
+} SMMUTransCfg;
+
+typedef struct SMMUDevice {
+void   *smmu;
+PCIBus *bus;
+intdevfn;
+IOMMUMemoryRegion  iommu;
+AddressSpace   as;
+} SMMUDevice;
+
+typedef struct SMMUNotifierNode {
+SMMUDevice *sdev;
+QLIST_ENTRY(SMMUNotifierNode) next;
+} SMMUNotifierNode;
+
+typedef struct SMMUPciBus {
+PCIBus   *bus;
+SMMUDevice   *pbdev[0]; /* Parent array is sparse, so dynamically alloc */
+} SMMUPciBus;
+
+typedef struct SMMUState {
+/*  */
+SysBusDevice  dev;
+const char *mrtypename;
+MemoryRegion iomem;
+
+GHashTable *smmu_pcibus_by_busptr;
+GHashTable *configs; /* cache for configuration data */
+GHashTable *iotlb;
+SMMUPciBus *smmu_pcibus_by_bus_num[SMMU_PCI_BUS_MAX];
+PCIBus *pci_bus;
+QLIST_HEAD(, SMMUNotifierNode) notifiers_list;
+uint8_t bus_num;
+PCIBus *primary_bus;
+} SMMUState;
+
+typedef struct {
+/*  */
+SysBusDeviceClass parent_class;
+
+/*< public >*/
+
+DeviceRealize parent_realize;
+
+} SMMUBaseClass;
+
+#define TYPE_ARM_SMMU "arm-smmu"
+#define ARM_SMMU(obj) 

  1   2   3   4   >