Re: [Qemu-devel] [PATCH] spapr/xive: H_INT_ESB is used for LSIs only

2019-06-30 Thread Cédric Le Goater
On 01/07/2019 07:07, David Gibson wrote:
> On Fri, Jun 21, 2019 at 05:05:45PM +0200, Cédric Le Goater wrote:
>> On 21/06/2019 16:52, Greg Kurz wrote:
>>> As indicated in the function header, this "hcall is only supported for
>>> LISNs that have the ESB hcall flag set to 1 when returned from hcall()
>>> H_INT_GET_SOURCE_INFO". We only set that flag for LSIs actually.
>>>
>>> Check that in h_int_esb().
>>
>> Indeed. H_INT_ESB should work on any IRQ, but I think it's better 
>> to check that the HCALL is only used with the IRQ requiring it.
> 
> I'm not so convinced.  It seems to me that specifically limiting this
> to certain things limits our options if we ever need future
> workarounds for problems with ESB mapping.
> 
> In addition using H_INT_ESB for non-LSIs could be useful for minimal
> guests (e.g. kvm-unit-tests) where mapping memory might be awkward.

Ah yes. This is true. There is no real reason for enforcing this
restriction in QEMU as H_INT_ESB should work on any irq. We can
keep it that way I guess. It would be a small deviation from PAPR.

Thanks,

C. 

> So, I'm not really seeing a compelling reason to apply this.
> 
>>
>>> Signed-off-by: Greg Kurz 
>>
>> Reviewed-by: Cédric Le Goater 
>>
>> Thanks,
>>
>> C.
>>
>>> ---
>>>  hw/intc/spapr_xive.c |6 ++
>>>  1 file changed, 6 insertions(+)
>>>
>>> diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
>>> index 58c2e5d890bd..01dd47ad5b02 100644
>>> --- a/hw/intc/spapr_xive.c
>>> +++ b/hw/intc/spapr_xive.c
>>> @@ -1408,6 +1408,12 @@ static target_ulong h_int_esb(PowerPCCPU *cpu,
>>>  return H_P2;
>>>  }
>>>  
>>> +if (!xive_source_irq_is_lsi(xsrc, lisn)) {
>>> +qemu_log_mask(LOG_GUEST_ERROR, "XIVE: LISN " TARGET_FMT_lx "isn't 
>>> LSI\n",
>>> +  lisn);
>>> +return H_P2;
>>> +}
>>> +
>>>  if (offset > (1ull << xsrc->esb_shift)) {
>>>  return H_P3;
>>>  }
>>>
>>
> 




Re: [Qemu-devel] [PATCH 03/10] ppc/pnv: Rework cache watch model of PnvXIVE

2019-06-30 Thread David Gibson
On Sun, Jun 30, 2019 at 10:45:54PM +0200, Cédric Le Goater wrote:
> When the software modifies the XIVE internal structures, ESB, EAS,
> END, NVT, it also must update the caches of the different XIVE
> sub-engines. HW offers a set of common interface for such purpose.
> 
> The CWATCH_SPEC register defines the block/index of the target and a
> set of flags to perform a full update and to watch for update
> conflicts.
> 
> The cache watch CWATCH_DATAX registers are then loaded with the target
> data with a first read on CWATCH_DATA0. Writing back is done in the
> opposit order, CWATCH_DATA0 triggering the update.
> 
> The SCRUB_TRIG registers are used to flush the cache in RAM, and to
> possibly invalidate it. Cache disablement is also an option but as we
> do not model the cache, these registers are no-ops
> 
> Today, the modeling of these registers is incorrect but it did not
> impact the set up of a baremetal system. However, running KVM requires
> a rework.
> 
> Fixes: 2dfa91a2aa5a ("ppc/pnv: add a XIVE interrupt controller model for 
> POWER9")
> Signed-off-by: Cédric Le Goater 

Pushing it for what counts as a bugfix this close to freeze, but I'll
take it.  Applied to ppc-for-4.1.

> ---
>  hw/intc/pnv_xive.c | 142 +
>  1 file changed, 106 insertions(+), 36 deletions(-)
> 
> diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
> index 9ab77feee9d8..4dc92ef1e372 100644
> --- a/hw/intc/pnv_xive.c
> +++ b/hw/intc/pnv_xive.c
> @@ -169,7 +169,7 @@ static uint64_t pnv_xive_vst_addr_indirect(PnvXive *xive, 
> uint32_t type,
>  vsd = ldq_be_dma(_space_memory, vsd_addr);
>  
>  if (!(vsd & VSD_ADDRESS_MASK)) {
> -xive_error(xive, "VST: invalid %s entry %x !?", info->name, 0);
> +xive_error(xive, "VST: invalid %s entry %x !?", info->name, idx);
>  return 0;
>  }
>  
> @@ -190,7 +190,7 @@ static uint64_t pnv_xive_vst_addr_indirect(PnvXive *xive, 
> uint32_t type,
>  vsd = ldq_be_dma(_space_memory, vsd_addr);
>  
>  if (!(vsd & VSD_ADDRESS_MASK)) {
> -xive_error(xive, "VST: invalid %s entry %x !?", info->name, 0);
> +xive_error(xive, "VST: invalid %s entry %x !?", info->name, idx);
>  return 0;
>  }
>  
> @@ -294,8 +294,12 @@ static int pnv_xive_write_end(XiveRouter *xrtr, uint8_t 
> blk, uint32_t idx,
>word_number);
>  }
>  
> -static int pnv_xive_end_update(PnvXive *xive, uint8_t blk, uint32_t idx)
> +static int pnv_xive_end_update(PnvXive *xive)
>  {
> +uint8_t  blk = GETFIELD(VC_EQC_CWATCH_BLOCKID,
> +   xive->regs[(VC_EQC_CWATCH_SPEC >> 3)]);
> +uint32_t idx = GETFIELD(VC_EQC_CWATCH_OFFSET,
> +   xive->regs[(VC_EQC_CWATCH_SPEC >> 3)]);
>  int i;
>  uint64_t eqc_watch[4];
>  
> @@ -307,6 +311,24 @@ static int pnv_xive_end_update(PnvXive *xive, uint8_t 
> blk, uint32_t idx)
>XIVE_VST_WORD_ALL);
>  }
>  
> +static void pnv_xive_end_cache_load(PnvXive *xive)
> +{
> +uint8_t  blk = GETFIELD(VC_EQC_CWATCH_BLOCKID,
> +   xive->regs[(VC_EQC_CWATCH_SPEC >> 3)]);
> +uint32_t idx = GETFIELD(VC_EQC_CWATCH_OFFSET,
> +   xive->regs[(VC_EQC_CWATCH_SPEC >> 3)]);
> +uint64_t eqc_watch[4] = { 0 };
> +int i;
> +
> +if (pnv_xive_vst_read(xive, VST_TSEL_EQDT, blk, idx, eqc_watch)) {
> +xive_error(xive, "VST: no END entry %x/%x !?", blk, idx);
> +}
> +
> +for (i = 0; i < ARRAY_SIZE(eqc_watch); i++) {
> +xive->regs[(VC_EQC_CWATCH_DAT0 >> 3) + i] = 
> be64_to_cpu(eqc_watch[i]);
> +}
> +}
> +
>  static int pnv_xive_get_nvt(XiveRouter *xrtr, uint8_t blk, uint32_t idx,
>  XiveNVT *nvt)
>  {
> @@ -320,8 +342,12 @@ static int pnv_xive_write_nvt(XiveRouter *xrtr, uint8_t 
> blk, uint32_t idx,
>word_number);
>  }
>  
> -static int pnv_xive_nvt_update(PnvXive *xive, uint8_t blk, uint32_t idx)
> +static int pnv_xive_nvt_update(PnvXive *xive)
>  {
> +uint8_t  blk = GETFIELD(PC_VPC_CWATCH_BLOCKID,
> +   xive->regs[(PC_VPC_CWATCH_SPEC >> 3)]);
> +uint32_t idx = GETFIELD(PC_VPC_CWATCH_OFFSET,
> +   xive->regs[(PC_VPC_CWATCH_SPEC >> 3)]);
>  int i;
>  uint64_t vpc_watch[8];
>  
> @@ -333,6 +359,24 @@ static int pnv_xive_nvt_update(PnvXive *xive, uint8_t 
> blk, uint32_t idx)
>XIVE_VST_WORD_ALL);
>  }
>  
> +static void pnv_xive_nvt_cache_load(PnvXive *xive)
> +{
> +uint8_t  blk = GETFIELD(PC_VPC_CWATCH_BLOCKID,
> +   xive->regs[(PC_VPC_CWATCH_SPEC >> 3)]);
> +uint32_t idx = GETFIELD(PC_VPC_CWATCH_OFFSET,
> +   xive->regs[(PC_VPC_CWATCH_SPEC >> 3)]);
> +uint64_t vpc_watch[8] = { 0 };
> +int i;
> +
> +if (pnv_xive_vst_read(xive, VST_TSEL_VPDT, blk, idx, vpc_watch)) {
> + 

Re: [Qemu-devel] [PATCH] spapr_pci: Unregister listeners before destroying the IOMMU address space

2019-06-30 Thread David Gibson
On Fri, Jun 21, 2019 at 11:27:33AM +0200, Greg Kurz wrote:
> Hot-unplugging a PHB with a VFIO device connected to it crashes QEMU:
> 
> -device spapr-pci-host-bridge,index=1,id=phb1 \
> -device vfio-pci,host=0034:01:00.3,id=vfio0
> 
> (qemu) device_del phb1
> [  357.207183] iommu: Removing device 0001:00:00.0 from group 1
> [  360.375523] rpadlpar_io: slot PHB 1 removed
> qemu-system-ppc64: memory.c:2742:
>  do_address_space_destroy: Assertion `QTAILQ_EMPTY(>listeners)' failed.
> 
> 'as' is the IOMMU address space, which indeed has a listener registered
> to by vfio_connect_container() when the VFIO device is realized. This
> listener is supposed to be unregistered by vfio_disconnect_container()
> when the VFIO device is finalized. Unfortunately, the VFIO device hasn't
> reached finalize yet at the time the PHB unrealize function is called,
> and address_space_destroy() gets called with the VFIO listener still
> being registered.
> 
> All regions have just been unmapped from the address space. Listeners
> aren't needed anymore at this point. Remove them before destroying the
> address space.
> 
> The VFIO code will try to remove them _again_ at device finalize,
> but it is okay since memory_listener_unregister() is idempotent.
> 
> Signed-off-by: Greg Kurz 

LGTM, applied.

> ---
>  hw/ppc/spapr_pci.c|6 ++
>  include/exec/memory.h |   10 ++
>  memory.c  |7 +++
>  3 files changed, 23 insertions(+)
> 
> diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
> index 2dca1e57f36c..eee92b102d5c 100644
> --- a/hw/ppc/spapr_pci.c
> +++ b/hw/ppc/spapr_pci.c
> @@ -1788,6 +1788,12 @@ static void spapr_phb_unrealize(DeviceState *dev, 
> Error **errp)
>  
>  memory_region_del_subregion(>iommu_root, >msiwindow);
>  
> +/*
> + * An attached PCI device may have memory listeners, eg. VFIO PCI. We 
> have
> + * unmapped all sections. Remove the listeners now, before destroying the
> + * address space.
> + */
> +address_space_remove_listeners(>iommu_as);
>  address_space_destroy(>iommu_as);
>  
>  qbus_set_hotplug_handler(BUS(phb->bus), NULL, _abort);
> diff --git a/include/exec/memory.h b/include/exec/memory.h
> index e6140e8a0489..1ba2e89aa8ce 100644
> --- a/include/exec/memory.h
> +++ b/include/exec/memory.h
> @@ -1757,6 +1757,16 @@ void address_space_init(AddressSpace *as, MemoryRegion 
> *root, const char *name);
>   */
>  void address_space_destroy(AddressSpace *as);
>  
> +/**
> + * address_space_remove_listeners: unregister all listerners of an address 
> space
> + *
> + * Removes all callbacks previously registered with 
> memory_listener_register()
> + * for @as.
> + *
> + * @as: an initialized #AddressSpace
> + */
> +void address_space_remove_listeners(AddressSpace *as);
> +
>  /**
>   * address_space_rw: read from or write to an address space.
>   *
> diff --git a/memory.c b/memory.c
> index 0a089a73ae1a..480f3d989b4f 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -2723,6 +2723,13 @@ void memory_listener_unregister(MemoryListener 
> *listener)
>  listener->address_space = NULL;
>  }
>  
> +void address_space_remove_listeners(AddressSpace *as)
> +{
> +while (!QTAILQ_EMPTY(>listeners)) {
> +memory_listener_unregister(QTAILQ_FIRST(>listeners));
> +}
> +}
> +
>  void address_space_init(AddressSpace *as, MemoryRegion *root, const char 
> *name)
>  {
>  memory_region_ref(root);
> 

-- 
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 01/10] ppc/xive: Force the Physical CAM line value to group mode

2019-06-30 Thread David Gibson
On Sun, Jun 30, 2019 at 10:45:52PM +0200, Cédric Le Goater wrote:
> When an interrupt needs to be delivered, the XIVE interrupt controller
> presenter scans the CAM lines of the thread interrupt contexts of the
> HW threads of the chip to find a matching vCPU. The interrupt context
> is composed of 4 different sets of registers: Physical, HV, OS and
> User.
> 
> The encoding of the Physical CAM line depends on the mode in which the
> interrupt controller is operating: CAM mode or block group mode.
> Block group mode being the default configuration today on POWER9 and
> the only one available on the next POWER10 generation, enforce this
> encoding in the Physical CAM line :
> 
> chip << 19 | 000 0 0001 thread (7Bit)
> 
> It fits the overall encoding of the NVT ids and simplifies the matching
> algorithm in the presenter.
> 
> Fixes: d514c48d41fb ("ppc/xive: hardwire the Physical CAM line of the thread 
> context")
> Signed-off-by: Cédric Le Goater 

Since this appears to be a fix, applied to ppc-for-4.1.

> ---
>  hw/intc/xive.c | 21 +
>  1 file changed, 5 insertions(+), 16 deletions(-)
> 
> diff --git a/hw/intc/xive.c b/hw/intc/xive.c
> index 6250c0414de8..3b1f9520ae9f 100644
> --- a/hw/intc/xive.c
> +++ b/hw/intc/xive.c
> @@ -1229,27 +1229,16 @@ XiveTCTX *xive_router_get_tctx(XiveRouter *xrtr, 
> CPUState *cs)
>  }
>  
>  /*
> - * By default on P9, the HW CAM line (23bits) is hardwired to :
> + * Encode the HW CAM line in the block group mode format :
>   *
> - *   0x000||0b1||4Bit chip number||7Bit Thread number.
> - *
> - * When the block grouping is enabled, the CAM line is changed to :
> - *
> - *   4Bit chip number||0x001||7Bit Thread number.
> + *   chip << 19 | 000 0 0001 thread (7Bit)
>   */
> -static uint32_t hw_cam_line(uint8_t chip_id, uint8_t tid)
> -{
> -return 1 << 11 | (chip_id & 0xf) << 7 | (tid & 0x7f);
> -}
> -
> -static bool xive_presenter_tctx_match_hw(XiveTCTX *tctx,
> - uint8_t nvt_blk, uint32_t nvt_idx)
> +static uint32_t xive_tctx_hw_cam_line(XiveTCTX *tctx)
>  {
>  CPUPPCState *env = _CPU(tctx->cs)->env;
>  uint32_t pir = env->spr_cb[SPR_PIR].default_value;
>  
> -return hw_cam_line((pir >> 8) & 0xf, pir & 0x7f) ==
> -hw_cam_line(nvt_blk, nvt_idx);
> +return xive_nvt_cam_line((pir >> 8) & 0xf, 1 << 7 | (pir & 0x7f));
>  }
>  
>  /*
> @@ -1285,7 +1274,7 @@ static int xive_presenter_tctx_match(XiveTCTX *tctx, 
> uint8_t format,
>  
>  /* PHYS ring */
>  if ((be32_to_cpu(qw3w2) & TM_QW3W2_VT) &&
> -xive_presenter_tctx_match_hw(tctx, nvt_blk, nvt_idx)) {
> +cam == xive_tctx_hw_cam_line(tctx)) {
>  return TM_QW3_HV_PHYS;
>  }
>  

-- 
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 02/10] ppc/xive: Make the PIPR register readonly

2019-06-30 Thread David Gibson
On Sun, Jun 30, 2019 at 10:45:53PM +0200, Cédric Le Goater wrote:
> When the hypervisor (KVM) dispatches a vCPU on a HW thread, it restores
> its thread interrupt context. The Pending Interrupt Priority Register
> (PIPR) is computed from the Interrupt Pending Buffer (IPB) and stores
> should not be allowed to change its value.
> 
> Fixes: 207d9fe98510 ("ppc/xive: introduce the XIVE interrupt thread context")
> Signed-off-by: Cédric Le Goater 

Applied to ppc-for-4.1.

> ---
>  hw/intc/xive.c | 32 
>  1 file changed, 16 insertions(+), 16 deletions(-)
> 
> diff --git a/hw/intc/xive.c b/hw/intc/xive.c
> index 3b1f9520ae9f..534f56f86bd5 100644
> --- a/hw/intc/xive.c
> +++ b/hw/intc/xive.c
> @@ -182,31 +182,31 @@ static uint64_t xive_tm_vt_poll(XiveTCTX *tctx, hwaddr 
> offset, unsigned size)
>   */
>  
>  static const uint8_t xive_tm_hw_view[] = {
> -/* QW-0 User */   3, 0, 0, 0,   0, 0, 0, 0,   3, 3, 3, 3,   0, 0, 0, 0,
> -/* QW-1 OS   */   3, 3, 3, 3,   3, 3, 0, 3,   3, 3, 3, 3,   0, 0, 0, 0,
> -/* QW-2 POOL */   0, 0, 3, 3,   0, 0, 0, 0,   3, 3, 3, 3,   0, 0, 0, 0,
> -/* QW-3 PHYS */   3, 3, 3, 3,   0, 3, 0, 3,   3, 0, 0, 3,   3, 3, 3, 0,
> +3, 0, 0, 0,   0, 0, 0, 0,   3, 3, 3, 3,   0, 0, 0, 0, /* QW-0 User */
> +3, 3, 3, 3,   3, 3, 0, 2,   3, 3, 3, 3,   0, 0, 0, 0, /* QW-1 OS   */
> +0, 0, 3, 3,   0, 0, 0, 0,   3, 3, 3, 3,   0, 0, 0, 0, /* QW-2 POOL */
> +3, 3, 3, 3,   0, 3, 0, 2,   3, 0, 0, 3,   3, 3, 3, 0, /* QW-3 PHYS */
>  };
>  
>  static const uint8_t xive_tm_hv_view[] = {
> -/* QW-0 User */   3, 0, 0, 0,   0, 0, 0, 0,   3, 3, 3, 3,   0, 0, 0, 0,
> -/* QW-1 OS   */   3, 3, 3, 3,   3, 3, 0, 3,   3, 3, 3, 3,   0, 0, 0, 0,
> -/* QW-2 POOL */   0, 0, 3, 3,   0, 0, 0, 0,   0, 3, 3, 3,   0, 0, 0, 0,
> -/* QW-3 PHYS */   3, 3, 3, 3,   0, 3, 0, 3,   3, 0, 0, 3,   0, 0, 0, 0,
> +3, 0, 0, 0,   0, 0, 0, 0,   3, 3, 3, 3,   0, 0, 0, 0, /* QW-0 User */
> +3, 3, 3, 3,   3, 3, 0, 2,   3, 3, 3, 3,   0, 0, 0, 0, /* QW-1 OS   */
> +0, 0, 3, 3,   0, 0, 0, 0,   0, 3, 3, 3,   0, 0, 0, 0, /* QW-2 POOL */
> +3, 3, 3, 3,   0, 3, 0, 2,   3, 0, 0, 3,   0, 0, 0, 0, /* QW-3 PHYS */
>  };
>  
>  static const uint8_t xive_tm_os_view[] = {
> -/* QW-0 User */   3, 0, 0, 0,   0, 0, 0, 0,   3, 3, 3, 3,   0, 0, 0, 0,
> -/* QW-1 OS   */   2, 3, 2, 2,   2, 2, 0, 2,   0, 0, 0, 0,   0, 0, 0, 0,
> -/* QW-2 POOL */   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,
> -/* QW-3 PHYS */   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,
> +3, 0, 0, 0,   0, 0, 0, 0,   3, 3, 3, 3,   0, 0, 0, 0, /* QW-0 User */
> +2, 3, 2, 2,   2, 2, 0, 2,   0, 0, 0, 0,   0, 0, 0, 0, /* QW-1 OS   */
> +0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0, /* QW-2 POOL */
> +0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0, /* QW-3 PHYS */
>  };
>  
>  static const uint8_t xive_tm_user_view[] = {
> -/* QW-0 User */   3, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,
> -/* QW-1 OS   */   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,
> -/* QW-2 POOL */   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,
> -/* QW-3 PHYS */   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,
> +3, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0, /* QW-0 User */
> +0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0, /* QW-1 OS   */
> +0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0, /* QW-2 POOL */
> +0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0, /* QW-3 PHYS */
>  };
>  
>  /*

-- 
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] [PULL 57/60] target/ppc: add HV support for POWER9

2019-06-30 Thread David Gibson
On Fri, Jun 28, 2019 at 03:20:32PM +0200, Philippe Mathieu-Daudé wrote:
> Hi,
> 
> On 3/12/19 8:58 PM, Cédric Le Goater wrote:
> > On 3/12/19 8:30 PM, Cleber Rosa wrote:
> >>> From: "Cleber Rosa" 
> >>> Sent: Tuesday, March 12, 2019 3:14:09 PM
> >>> Subject: Re: [Qemu-devel] [PULL 57/60] target/ppc: add HV support for 
> >>> POWER9
> >>>
> >>> On Tue, Mar 12, 2019 at 07:34:04PM +0100, Cédric Le Goater wrote:
>  On 3/12/19 4:01 PM, Cleber Rosa wrote:
> > On Sun, Mar 10, 2019 at 07:27:00PM +1100, David Gibson wrote:
> >> From: Cédric Le Goater 
> >>
> >> We now have enough support to boot a PowerNV machine with a POWER9
> >> processor. Allow HV mode on POWER9.
> >>
> >> Signed-off-by: Cédric Le Goater 
> >> Message-Id: <20190307223548.20516-16-...@kaod.org>
> >> Signed-off-by: David Gibson 
> >> ---
> >>  target/ppc/translate_init.inc.c | 3 ++-
> >>  1 file changed, 2 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/target/ppc/translate_init.inc.c
> >> b/target/ppc/translate_init.inc.c
> >> index af70a3b78c..0bd555eb19 100644
> >> --- a/target/ppc/translate_init.inc.c
> >> +++ b/target/ppc/translate_init.inc.c
> >> @@ -8895,7 +8895,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void
> >> *data)
> >> PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
> >> PPC_MEM_SYNC | PPC_MEM_EIEIO |
> >> PPC_MEM_TLBSYNC |
> >> -   PPC_64B | PPC_64BX | PPC_ALTIVEC |
> >> +   PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
> >> PPC_SEGMENT_64B | PPC_SLBI |
> >> PPC_POPCNTB | PPC_POPCNTWD |
> >> PPC_CILDST;
> >> @@ -8907,6 +8907,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void
> >> *data)
> >>  PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
> >>  PPC2_TM | PPC2_ISA300 | PPC2_PRCNTL;
> >>  pcc->msr_mask = (1ull << MSR_SF) |
> >> +(1ull << MSR_SHV) |
> >>  (1ull << MSR_TM) |
> >>  (1ull << MSR_VR) |
> >>  (1ull << MSR_VSX) |
> >>
> >>
> >
> > This change prevents a Fedora 29 kernel[1] from booting... is this
> > intended or a known limitation of the Fedora 29 kernel?
> 
>  The default CPU is still power8_v2.0. This is curious.
> 
> >>>
> >>> Are you sure?  I'm getting:
> >>>
> >>>  $ git rev-parse HEAD
> >>>  cfc3fef6b4e493bf1a7ee16790ad584e20dfbbd1
> >>>  $ ./ppc64-softmmu/qemu-system-ppc64 -qmp unix:/tmp/qmp-sock,server
> >>>  $ ./scripts/qmp/qom-get -s /tmp/qmp-sock 
> >>> /machine/unattached/device[0].type
> >>>  power9_v2.0-spapr-cpu-core
> > 
> > That's a pseries machine, not a powernv machine. pseries should use P9
> > processor by default but the patch above should not impact f29 on pseries. 
> > If it does, then we have a bug. 
> >  
> >> Looks like the overall default is "power9_v2.0", and then on pseries-3.1 
> >> and
> >> lower, it's "power8_v2.0", as per 34a6b015a98.
> > 
> > I was looking at pnv_machine_class_init() which sets the default CPU :
> > 
> > mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power8_v2.0");
> 
> I found this thread while trying auto-bisection for LP#1834613:
> https://bugs.launchpad.net/bugs/1834613
> 
> When trying the options suggested by Laurent here:
> https://lists.gnu.org/archive/html/qemu-devel/2019-06/msg06209.html
> 
> this one hangs:
> 
> $ qemu-system-ppc64 \
>  -kernel vmlinuz-vanilla \
>  -nographic -append "console=hvc0" \
>  -M cap-cfpc=broken,cap-sbbc=broken,cap-ibs=broken
> 
> but this one works:
> 
> $ qemu-system-ppc64 \
>  -kernel vmlinuz-vanilla \
>  -nographic -append "console=hvc0" \
>  -M pseries-3.1

Sorry, I missed most of this thread while on holidays.  What's the
actual bug here?

-- 
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 04/10] ppc/xive: Fix TM_PULL_POOL_CTX special operation

2019-06-30 Thread David Gibson
On Sun, Jun 30, 2019 at 10:45:55PM +0200, Cédric Le Goater wrote:
> When a CPU is reseted, the hypervisor (Linux or OPAL) invalidates the
> POOL interrupt context of a CPU with this special command. It returns
> the POOL CAM line value and resets the VP bit.
> 
> Fixes: 4836b45510aa ("ppc/xive: activate HV support")
> Signed-off-by: Cédric Le Goater 

Applied to ppc-for-4.1.

> ---
>  hw/intc/xive.c | 19 ++-
>  1 file changed, 10 insertions(+), 9 deletions(-)
> 
> diff --git a/hw/intc/xive.c b/hw/intc/xive.c
> index 534f56f86bd5..cf77bdb7d34a 100644
> --- a/hw/intc/xive.c
> +++ b/hw/intc/xive.c
> @@ -132,6 +132,11 @@ static void xive_tctx_set_cppr(XiveTCTX *tctx, uint8_t 
> ring, uint8_t cppr)
>  xive_tctx_notify(tctx, ring);
>  }
>  
> +static inline uint32_t xive_tctx_word2(uint8_t *ring)
> +{
> +return *((uint32_t *) [TM_WORD2]);
> +}
> +
>  /*
>   * XIVE Thread Interrupt Management Area (TIMA)
>   */
> @@ -150,11 +155,12 @@ static uint64_t xive_tm_ack_hv_reg(XiveTCTX *tctx, 
> hwaddr offset, unsigned size)
>  static uint64_t xive_tm_pull_pool_ctx(XiveTCTX *tctx, hwaddr offset,
>unsigned size)
>  {
> -uint64_t ret;
> +uint32_t qw2w2_prev = xive_tctx_word2(>regs[TM_QW2_HV_POOL]);
> +uint32_t qw2w2;
>  
> -ret = tctx->regs[TM_QW2_HV_POOL + TM_WORD2] & TM_QW2W2_POOL_CAM;
> -tctx->regs[TM_QW2_HV_POOL + TM_WORD2] &= ~TM_QW2W2_POOL_CAM;
> -return ret;
> +qw2w2 = xive_set_field32(TM_QW2W2_VP, qw2w2_prev, 0);
> +memcpy(>regs[TM_QW2_HV_POOL + TM_WORD2], , 4);
> +return qw2w2;
>  }
>  
>  static void xive_tm_vt_push(XiveTCTX *tctx, hwaddr offset,
> @@ -484,11 +490,6 @@ const MemoryRegionOps xive_tm_ops = {
>  },
>  };
>  
> -static inline uint32_t xive_tctx_word2(uint8_t *ring)
> -{
> -return *((uint32_t *) [TM_WORD2]);
> -}
> -
>  static char *xive_tctx_ring_print(uint8_t *ring)
>  {
>  uint32_t w2 = xive_tctx_word2(ring);

-- 
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] spapr/xive: H_INT_ESB is used for LSIs only

2019-06-30 Thread David Gibson
On Fri, Jun 21, 2019 at 05:05:45PM +0200, Cédric Le Goater wrote:
> On 21/06/2019 16:52, Greg Kurz wrote:
> > As indicated in the function header, this "hcall is only supported for
> > LISNs that have the ESB hcall flag set to 1 when returned from hcall()
> > H_INT_GET_SOURCE_INFO". We only set that flag for LSIs actually.
> > 
> > Check that in h_int_esb().
> 
> Indeed. H_INT_ESB should work on any IRQ, but I think it's better 
> to check that the HCALL is only used with the IRQ requiring it.

I'm not so convinced.  It seems to me that specifically limiting this
to certain things limits our options if we ever need future
workarounds for problems with ESB mapping.

In addition using H_INT_ESB for non-LSIs could be useful for minimal
guests (e.g. kvm-unit-tests) where mapping memory might be awkward.

So, I'm not really seeing a compelling reason to apply this.

> 
> > Signed-off-by: Greg Kurz 
> 
> Reviewed-by: Cédric Le Goater 
> 
> Thanks,
> 
> C.
> 
> > ---
> >  hw/intc/spapr_xive.c |6 ++
> >  1 file changed, 6 insertions(+)
> > 
> > diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
> > index 58c2e5d890bd..01dd47ad5b02 100644
> > --- a/hw/intc/spapr_xive.c
> > +++ b/hw/intc/spapr_xive.c
> > @@ -1408,6 +1408,12 @@ static target_ulong h_int_esb(PowerPCCPU *cpu,
> >  return H_P2;
> >  }
> >  
> > +if (!xive_source_irq_is_lsi(xsrc, lisn)) {
> > +qemu_log_mask(LOG_GUEST_ERROR, "XIVE: LISN " TARGET_FMT_lx "isn't 
> > LSI\n",
> > +  lisn);
> > +return H_P2;
> > +}
> > +
> >  if (offset > (1ull << xsrc->esb_shift)) {
> >  return H_P3;
> >  }
> > 
> 

-- 
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 0/2] spapr/xive: rework the mapping the KVM memory regions

2019-06-30 Thread David Gibson
On Fri, Jun 14, 2019 at 06:59:18PM +0200, Cédric Le Goater wrote:
> Hello,
> 
> Here is a small series simplifying the initialization sequence of the
> interrupt device by using memory regions specific for KVM. These are
> mapped as overlaps on top of the emulated device.

Applied, thanks.

> 
> Thanks,
> 
> C.
> 
> Cédric Le Goater (2):
>   spapr/xive: rework the mapping the KVM memory regions
>   spapr/xive: simplify spapr_irq_init_device() to remove the emulated
> init
> 
>  include/hw/ppc/spapr_irq.h  |  1 -
>  include/hw/ppc/spapr_xive.h |  2 +-
>  include/hw/ppc/xive.h   |  1 +
>  hw/intc/spapr_xive.c| 38 ++---
>  hw/intc/spapr_xive_kvm.c| 21 +++-
>  hw/ppc/spapr_irq.c  | 21 +++-
>  6 files changed, 27 insertions(+), 57 deletions(-)
> 

-- 
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] [QEMU-PPC] [PATCH 1/2] ppc/spapr: Add implementation of hcall H_PURR

2019-06-30 Thread David Gibson
On Mon, Jul 01, 2019 at 02:23:21PM +1000, Suraj Jitindar Singh wrote:
> On Fri, 2019-06-28 at 19:29 +1000, David Gibson wrote:
> > On Mon, Jun 24, 2019 at 03:58:11PM +1000, Suraj Jitindar Singh wrote:
> > > The hcall H_PURR is used by a guest to read the PURR (processor
> > > utilisation of resources register). A guest expects that this
> > > register
> > > will count at a rate of timebase scaled by the number of guest
> > > vcpus
> > > present in the vcore. That is the per vcpu purr will count at a
> > > rate of
> > > timebase / # vcpus per vcore.
> > > 
> > > Implement a handler for the H_PURR hcall and return the purr value
> > > divided by smp_threads so that the sum of the purr deltas across
> > > the
> > > vcpus of a vcore equals the timebase delta
> > > 
> > > Signed-off-by: Suraj Jitindar Singh 
> > 
> > Does this need something new advertised in the hypertas DT entry?
> 
> Hi David,
> 
> There doesn't seem to be a concensus on what the return value from the
> H_PURR hcall should be, whether it just returns the hardware value or
> does some adjusting of the value based on guest smt mode as I've
> implemented in the patch below.

*eyeroll*.  Lack of forethought in PAPR strikes again.

> As such please drop this patch series.

Ok, will do.

> 
> The guest can just read the purr register directly anyway and then
> interpret the values as it pleases.
> 
> Kind Regards,
> Suraj
> 
> > 
> > > ---
> > >  hw/ppc/spapr_hcall.c | 24 
> > >  1 file changed, 24 insertions(+)
> > > 
> > > diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
> > > index aae9fd2b3e..88b3343f04 100644
> > > --- a/hw/ppc/spapr_hcall.c
> > > +++ b/hw/ppc/spapr_hcall.c
> > > @@ -1819,6 +1819,27 @@ static target_ulong h_update_dt(PowerPCCPU
> > > *cpu, SpaprMachineState *spapr,
> > >  return H_SUCCESS;
> > >  }
> > >  
> > > +static target_ulong h_purr(PowerPCCPU *cpu, SpaprMachineState
> > > *spapr,
> > > +   target_ulong opcode, target_ulong
> > > *args)
> > > +{
> > > +CPUPPCState *env = >env;
> > > +target_ulong purr;
> > > +
> > > +if (kvm_enabled()) {
> > > +cpu_synchronize_state(CPU(cpu));
> > > +/*
> > > + * Divide by smp_threads so that the sum of the purr
> > > deltas across the
> > > + * vcpus of a vcore equal the timebase delta.
> > > + */
> > > +purr = env->spr[SPR_PURR] / smp_threads;
> > > +} else {
> > > +purr = cpu_ppc_load_purr(env);
> > > +}
> > > +args[0] = purr;
> > > +
> > > +return H_SUCCESS;
> > > +}
> > > +
> > >  static spapr_hcall_fn papr_hypercall_table[(MAX_HCALL_OPCODE / 4)
> > > + 1];
> > >  static spapr_hcall_fn kvmppc_hypercall_table[KVMPPC_HCALL_MAX -
> > > KVMPPC_HCALL_BASE + 1];
> > >  
> > > @@ -1915,6 +1936,9 @@ static void hypercall_register_types(void)
> > >  spapr_register_hypercall(H_LOGICAL_DCBF, h_logical_dcbf);
> > >  spapr_register_hypercall(KVMPPC_H_LOGICAL_MEMOP,
> > > h_logical_memop);
> > >  
> > > +/* hcall-purr */
> > > +spapr_register_hypercall(H_PURR, h_purr);
> > > +
> > >  /* qemu/KVM-PPC specific hcalls */
> > >  spapr_register_hypercall(KVMPPC_H_RTAS, h_rtas);
> > >  
> > 
> > 
> 

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


[Qemu-devel] [RISU RFC PATCH v2 11/14] x86.risu: add SSE4.1 and SSE4.2 instructions

2019-06-30 Thread Jan Bobek
Add SSE4.1 and SSE4.2 instructions to the x86 configuration file.

Signed-off-by: Jan Bobek 
---
 x86.risu | 69 
 1 file changed, 69 insertions(+)

diff --git a/x86.risu b/x86.risu
index 35992d6..a73e209 100644
--- a/x86.risu
+++ b/x86.risu
@@ -124,10 +124,12 @@ ADDSUBPDSSE3 1101 !emit { 
data16(); modrm(); mem(size =>
 
 PMULLW  MMX  11010101 !emit { modrm(); mem(size => 8); }
 PMULLW  SSE2 11010101 !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
+PMULLD  SSE4_1   00111000 0100 !emit { data16(); modrm(); 
mem(size => 16, align => 16); }
 PMULHW  MMX  11100101 !emit { modrm(); mem(size => 8); }
 PMULHW  SSE2 11100101 !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
 PMULHUW SSE  11100100 !emit { modrm(); mem(size => 8); }
 PMULHUW SSE2 11100100 !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
+PMULDQ  SSE4_1   00111000 00101000 !emit { data16(); modrm(); 
mem(size => 16, align => 16); }
 PMULUDQ_64  SSE2 0100 !emit { modrm(); mem(size => 8); }
 PMULUDQ SSE2 0100 !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
 
@@ -162,18 +164,28 @@ RSQRTSS SSE  01010010 !emit { rep(); 
modrm(); mem(size => 4)
 
 PMINUB  SSE  11011010 !emit { modrm(); mem(size => 8); }
 PMINUB  SSE2 11011010 !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
+PMINUW  SSE4_1   00111000 00111010 !emit { data16(); modrm(); 
mem(size => 16, align => 16); }
+PMINUD  SSE4_1   00111000 00111011 !emit { data16(); modrm(); 
mem(size => 16, align => 16); }
+PMINSB  SSE4_1   00111000 00111000 !emit { data16(); modrm(); 
mem(size => 16, align => 16); }
 PMINSW  SSE  11101010 !emit { modrm(); mem(size => 8); }
 PMINSW  SSE2 11101010 !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
+PMINSD  SSE4_1   00111000 00111001 !emit { data16(); modrm(); 
mem(size => 16, align => 16); }
 
 MINPS   SSE  01011101 !emit { modrm(); mem(size => 16, 
align => 16); }
 MINPD   SSE2 01011101 !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
 MINSS   SSE  01011101 !emit { rep(); modrm(); mem(size => 
4); }
 MINSD   SSE2 01011101 !emit { repne(); modrm(); mem(size 
=> 8); }
 
+PHMINPOSUW  SSE4_1   00111000 0101 !emit { data16(); modrm(); 
mem(size => 16, align => 16); }
+
 PMAXUB  SSE  1100 !emit { modrm(); mem(size => 8); }
 PMAXUB  SSE2 1100 !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
+PMAXUW  SSE4_1   00111000 0010 !emit { data16(); modrm(); 
mem(size => 16, align => 16); }
+PMAXUD  SSE4_1   00111000 0011 !emit { data16(); modrm(); 
mem(size => 16, align => 16); }
+PMAXSB  SSE4_1   00111000 0000 !emit { data16(); modrm(); 
mem(size => 16, align => 16); }
 PMAXSW  SSE  11101110 !emit { modrm(); mem(size => 8); }
 PMAXSW  SSE2 11101110 !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
+PMAXSD  SSE4_1   00111000 0001 !emit { data16(); modrm(); 
mem(size => 16, align => 16); }
 
 MAXPS   SSE  0101 !emit { modrm(); mem(size => 16, 
align => 16); }
 MAXPD   SSE2 0101 !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
@@ -187,6 +199,7 @@ PAVGW   SSE2 11100011 !emit { data16(); 
modrm(); mem(size =>
 
 PSADBW  SSE  0110 !emit { modrm(); mem(size => 8); }
 PSADBW  SSE2 0110 !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
+MPSADBW SSE4_1   00111010 0110 !emit { data16(); modrm(); 
mem(size => 16, align => 16); imm(size => 1); }
 
 PABSB_64SSSE3    00111000 00011100 !emit { modrm(); mem(size 
=> 8); }
 PABSB   SSSE3    00111000 00011100 !emit { data16(); modrm(); 
mem(size => 16, align => 16); }
@@ -202,6 +215,14 @@ PSIGNW  SSSE3    00111000 1001 !emit { 
data16(); modrm(); me
 PSIGND_64   SSSE3    00111000 1010 !emit { modrm(); mem(size 
=> 8); }
 PSIGND  SSSE3    00111000 1010 !emit { data16(); modrm(); 
mem(size => 16, align => 16); }
 
+DPPSSSE4_1   00111010 0100 !emit { data16(); modrm(); 
mem(size => 16, align => 16); imm(size => 1); }
+DPPDSSE4_1   00111010 0101 !emit { data16(); modrm(); 
mem(size => 16, align => 16); imm(size => 1); }
+
+ROUNDPS SSE4_1   00111010 1000 

[Qemu-devel] [RISU RFC PATCH v2 08/14] x86.risu: add SSE2 instructions

2019-06-30 Thread Jan Bobek
Add SSE2 instructions to the x86 configuration file.

Signed-off-by: Jan Bobek 
---
 x86.risu | 153 +++
 1 file changed, 153 insertions(+)

diff --git a/x86.risu b/x86.risu
index c29b210..9b63d6b 100644
--- a/x86.risu
+++ b/x86.risu
@@ -15,179 +15,332 @@
 # Data Transfer Instructions
 MOVDMMX  011 d 1110 !emit { modrm(mod => MOD_DIRECT, 
rm => ~REG_ESP); }
 MOVD_memMMX  011 d 1110 !emit { modrm(mod => ~MOD_DIRECT); 
mem(size => 4); }
+MOVDSSE2 011 d 1110 !emit { data16(); modrm(mod => 
MOD_DIRECT, rm => ~REG_ESP); }
+MOVD_memSSE2 011 d 1110 !emit { data16(); modrm(mod => 
~MOD_DIRECT); mem(size => 4); }
 MOVQMMX  011 d 1110 !emit { rex(w => 1); modrm(mod => 
MOD_DIRECT, rm => ~REG_ESP); }
 MOVQ_memMMX  011 d 1110 !emit { rex(w => 1); modrm(mod => 
~MOD_DIRECT); mem(size => 8); }
+MOVQSSE2 011 d 1110 !emit { data16(); rex(w => 1); 
modrm(mod => MOD_DIRECT, rm => ~REG_ESP); }
+MOVQ_memSSE2 011 d 1110 !emit { data16(); rex(w => 1); 
modrm(mod => ~MOD_DIRECT); mem(size => 8); }
 MOVQ_mm MMX  011 d  !emit { modrm(); mem(size => 8); }
+MOVQ_xmm1   SSE2 0110 !emit { rep(); modrm(); mem(size => 
8); }
+MOVQ_xmm2   SSE2 11010110 !emit { data16(); modrm(); mem(size 
=> 8); }
 
 MOVAPS  SSE  0010100 d !emit { modrm(); mem(size => 16, 
align => 16); }
+MOVAPD  SSE2 0010100 d !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
+MOVDQA  SSE2 011 d  !emit { data16(); modrm(); 
mem(size => 16, align => 16); }
 MOVUPS  SSE  0001000 d !emit { modrm(); mem(size => 16); }
+MOVUPD  SSE2 0001000 d !emit { data16(); modrm(); mem(size 
=> 16); }
+MOVDQU  SSE2 011 d  !emit { rep(); modrm(); mem(size 
=> 16); }
 MOVSS   SSE  0001000 d !emit { rep(); modrm(); mem(size => 
4); }
+MOVSD   SSE2 0001000 d !emit { repne(); modrm(); mem(size 
=> 8); }
+
+MOVQ2DQ SSE2 11010110 !emit { rep(); modrm(mod => 
MOD_DIRECT); }
+MOVDQ2Q SSE2 11010110 !emit { repne(); modrm(mod => 
MOD_DIRECT); }
 
 MOVLPS  SSE  0001001 d !emit { modrm(mod => ~MOD_DIRECT); 
mem(size => 8); }
+MOVLPD  SSE2 0001001 d !emit { data16(); modrm(mod => 
~MOD_DIRECT); mem(size => 8); }
 MOVHPS  SSE  0001011 d !emit { modrm(mod => ~MOD_DIRECT); 
mem(size => 8); }
+MOVHPD  SSE2 0001011 d !emit { data16(); modrm(mod => 
~MOD_DIRECT); mem(size => 8); }
 MOVLHPS SSE  00010110  !emit { modrm(mod => MOD_DIRECT); }
 MOVHLPS SSE  00010010  !emit { modrm(mod => MOD_DIRECT); }
 
 PMOVMSKBSSE  11010111 !emit { modrm(mod => MOD_DIRECT, reg 
=> ~REG_ESP); }
+PMOVMSKBSSE2 11010111 !emit { data16(); modrm(mod => 
MOD_DIRECT, reg => ~REG_ESP); }
 MOVMSKPSSSE  0101 !emit { modrm(mod => MOD_DIRECT, reg 
=> ~REG_ESP); }
+MOVMKSPDSSE2 0101 !emit { data16(); modrm(mod => 
MOD_DIRECT, reg => ~REG_ESP); }
 
 # Arithmetic Instructions
 PADDB   MMX  1100 !emit { modrm(); mem(size => 8); }
+PADDB   SSE2 1100 !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
 PADDW   MMX  1101 !emit { modrm(); mem(size => 8); }
+PADDW   SSE2 1101 !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
 PADDD   MMX  1110 !emit { modrm(); mem(size => 8); }
+PADDD   SSE2 1110 !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
 PADDQ   MMX  11010100 !emit { modrm(); mem(size => 8); }
+PADDQ   SSE2 11010100 !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
 PADDSB  MMX  11101100 !emit { modrm(); mem(size => 8); }
+PADDSB  SSE2 11101100 !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
 PADDSW  MMX  11101101 !emit { modrm(); mem(size => 8); }
+PADDSW  SSE2 11101101 !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
 PADDUSB MMX  11011100 !emit { modrm(); mem(size => 8); }
+PADDUSB SSE2 11011100 !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
 PADDUSW MMX  11011101 !emit { modrm(); mem(size => 8); }
+PADDUSW SSE2 11011101 !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
 
 ADDPS   SSE  01011000 !emit { modrm(); mem(size => 16, 
align => 16); }
+ADDPD   SSE2 01011000 !emit { 

[Qemu-devel] [RISU RFC PATCH v2 13/14] x86.risu: add AVX instructions

2019-06-30 Thread Jan Bobek
Add AVX instructions to the x86 configuration file.

Signed-off-by: Jan Bobek 
---
 x86.risu | 288 +++
 1 file changed, 288 insertions(+)

diff --git a/x86.risu b/x86.risu
index 17a5082..d3115ac 100644
--- a/x86.risu
+++ b/x86.risu
@@ -17,452 +17,736 @@ MOVDMMX  011 d 1110 !emit { 
modrm(mod => MOD_DIRECT, rm
 MOVD_memMMX  011 d 1110 !emit { modrm(mod => ~MOD_DIRECT); 
mem(size => 4); }
 MOVDSSE2 011 d 1110 !emit { data16(); modrm(mod => 
MOD_DIRECT, rm => ~REG_ESP); }
 MOVD_memSSE2 011 d 1110 !emit { data16(); modrm(mod => 
~MOD_DIRECT); mem(size => 4); }
+VMOVD   AVX  011 d 1110 !emit { vex(l => VEX_L_128, p => 
VEX_P_DATA16, m => VEX_M_0F, W => 0, v => VEX_V_UNUSED); modrm(mod => 
MOD_DIRECT, rm => ~REG_ESP); }
+VMOVD_mem   AVX  011 d 1110 !emit { vex(l => VEX_L_128, p => 
VEX_P_DATA16, m => VEX_M_0F, W => 0, v => VEX_V_UNUSED); modrm(mod => 
~MOD_DIRECT); mem(size => 4); }
 MOVQMMX  011 d 1110 !emit { rex(w => 1); modrm(mod => 
MOD_DIRECT, rm => ~REG_ESP); }
 MOVQ_memMMX  011 d 1110 !emit { rex(w => 1); modrm(mod => 
~MOD_DIRECT); mem(size => 8); }
 MOVQSSE2 011 d 1110 !emit { data16(); rex(w => 1); 
modrm(mod => MOD_DIRECT, rm => ~REG_ESP); }
 MOVQ_memSSE2 011 d 1110 !emit { data16(); rex(w => 1); 
modrm(mod => ~MOD_DIRECT); mem(size => 8); }
+VMOVQ   AVX  011 d 1110 !emit { vex(l => VEX_L_128, p => 
VEX_P_DATA16, m => VEX_M_0F, W => 1, v => VEX_V_UNUSED); modrm(mod => 
MOD_DIRECT, rm => ~REG_ESP); }
+VMOVQ_mem   AVX  011 d 1110 !emit { vex(l => VEX_L_128, p => 
VEX_P_DATA16, m => VEX_M_0F, W => 1, v => VEX_V_UNUSED); modrm(mod => 
~MOD_DIRECT); mem(size => 8); }
 MOVQ_mm MMX  011 d  !emit { modrm(); mem(size => 8); }
 MOVQ_xmm1   SSE2 0110 !emit { rep(); modrm(); mem(size => 
8); }
+VMOVQ_xmm1  AVX  0110 !emit { vex(l => VEX_L_128, p => 
VEX_P_REP, m => VEX_M_0F, v => VEX_V_UNUSED); modrm(); mem(size => 8); }
 MOVQ_xmm2   SSE2 11010110 !emit { data16(); modrm(); mem(size 
=> 8); }
+VMOVQ_xmm2  AVX  11010110 !emit { vex(l => VEX_L_128, p => 
VEX_P_DATA16, m => VEX_M_0F, v => VEX_V_UNUSED); modrm(); mem(size => 8); }
 
 MOVAPS  SSE  0010100 d !emit { modrm(); mem(size => 16, 
align => 16); }
+VMOVAPS AVX  0010100 d !emit { vex(l => VEX_L_128, m => 
VEX_M_0F, v => VEX_V_UNUSED); modrm(); mem(size => 16, align => 16); }
 MOVAPD  SSE2 0010100 d !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
+VMOVAPD AVX  0010100 d !emit { vex(l => VEX_L_128, p => 
VEX_P_DATA16, m => VEX_M_0F, v => VEX_V_UNUSED); modrm(); mem(size => 16, align 
=> 16); }
 MOVDQA  SSE2 011 d  !emit { data16(); modrm(); 
mem(size => 16, align => 16); }
+VMOVDQA AVX  011 d  !emit { vex(l => VEX_L_128, p => 
VEX_P_DATA16, m => VEX_M_0F, v => VEX_V_UNUSED); modrm(); mem(size => 16, align 
=> 16); }
 MOVUPS  SSE  0001000 d !emit { modrm(); mem(size => 16); }
+VMOVUPS AVX  0001000 d !emit { vex(l => VEX_L_128, m => 
VEX_M_0F, v => VEX_V_UNUSED); modrm(); mem(size => 16); }
 MOVUPD  SSE2 0001000 d !emit { data16(); modrm(); mem(size 
=> 16); }
+VMOVUPD AVX  0001000 d !emit { vex(l => VEX_L_128, p => 
VEX_P_DATA16, m => VEX_M_0F, v => VEX_V_UNUSED); modrm(); mem(size => 16); }
 MOVDQU  SSE2 011 d  !emit { rep(); modrm(); mem(size 
=> 16); }
+VMOVDQU AVX  011 d  !emit { vex(l => VEX_L_128, p => 
VEX_P_REP, m => VEX_M_0F, v => VEX_V_UNUSED); modrm(); mem(size => 16); }
 MOVSS   SSE  0001000 d !emit { rep(); modrm(); mem(size => 
4); }
+VMOVSS  AVX  0001000 d !emit { vex(l => VEX_L_128, p => 
VEX_P_REP, m => VEX_M_0F); modrm(mod => MOD_DIRECT); }
+VMOVSS_mem  AVX  0001000 d !emit { vex(l => VEX_L_128, p => 
VEX_P_REP, m => VEX_M_0F, v => VEX_V_UNUSED); modrm(mod => ~MOD_DIRECT); 
mem(size => 4); }
 MOVSD   SSE2 0001000 d !emit { repne(); modrm(); mem(size 
=> 8); }
+VMOVSD  AVX  0001000 d !emit { vex(l => VEX_L_128, p => 
VEX_P_REPNE, m => VEX_M_0F); modrm(mod => MOD_DIRECT); }
+VMOVSD_mem  AVX  0001000 d !emit { vex(l => VEX_L_128, p => 
VEX_P_REPNE, m => VEX_M_0F, v => VEX_V_UNUSED); modrm(mod => ~MOD_DIRECT); 
mem(size => 8); }
 
 MOVQ2DQ SSE2 11010110 !emit { rep(); modrm(mod => 
MOD_DIRECT); }
 MOVDQ2Q SSE2 11010110 !emit { repne(); modrm(mod => 
MOD_DIRECT); }
 
 MOVLPS  SSE  0001001 d !emit { modrm(mod => ~MOD_DIRECT); 

[Qemu-devel] [RISU RFC PATCH v2 06/14] x86.risu: add MMX instructions

2019-06-30 Thread Jan Bobek
Add an x86 configuration file with all MMX instructions.

Signed-off-by: Jan Bobek 
---
 x86.risu | 96 
 1 file changed, 96 insertions(+)
 create mode 100644 x86.risu

diff --git a/x86.risu b/x86.risu
new file mode 100644
index 000..f2dd9b0
--- /dev/null
+++ b/x86.risu
@@ -0,0 +1,96 @@
+###
+# Copyright (c) 2019 Linaro Limited
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Jan Bobek - initial implementation
+###
+
+# Input file for risugen defining x86 instructions
+.mode x86
+
+# Data Transfer Instructions
+MOVDMMX  011 d 1110 !emit { modrm(mod => MOD_DIRECT, 
rm => ~REG_ESP); }
+MOVD_memMMX  011 d 1110 !emit { modrm(mod => ~MOD_DIRECT); 
mem(size => 4); }
+MOVQMMX  011 d 1110 !emit { rex(w => 1); modrm(mod => 
MOD_DIRECT, rm => ~REG_ESP); }
+MOVQ_memMMX  011 d 1110 !emit { rex(w => 1); modrm(mod => 
~MOD_DIRECT); mem(size => 8); }
+MOVQ_mm MMX  011 d  !emit { modrm(); mem(size => 8); }
+
+# Arithmetic Instructions
+PADDB   MMX  1100 !emit { modrm(); mem(size => 8); }
+PADDW   MMX  1101 !emit { modrm(); mem(size => 8); }
+PADDD   MMX  1110 !emit { modrm(); mem(size => 8); }
+PADDQ   MMX  11010100 !emit { modrm(); mem(size => 8); }
+PADDSB  MMX  11101100 !emit { modrm(); mem(size => 8); }
+PADDSW  MMX  11101101 !emit { modrm(); mem(size => 8); }
+PADDUSB MMX  11011100 !emit { modrm(); mem(size => 8); }
+PADDUSW MMX  11011101 !emit { modrm(); mem(size => 8); }
+
+PSUBB   MMX  1000 !emit { modrm(); mem(size => 8); }
+PSUBW   MMX  1001 !emit { modrm(); mem(size => 8); }
+PSUBD   MMX  1010 !emit { modrm(); mem(size => 8); }
+PSUBSB  MMX  11101000 !emit { modrm(); mem(size => 8); }
+PSUBSW  MMX  11101001 !emit { modrm(); mem(size => 8); }
+PSUBUSB MMX  11011000 !emit { modrm(); mem(size => 8); }
+PSUBUSW MMX  11011001 !emit { modrm(); mem(size => 8); }
+
+PMULLW  MMX  11010101 !emit { modrm(); mem(size => 8); }
+PMULHW  MMX  11100101 !emit { modrm(); mem(size => 8); }
+
+PMADDWD MMX  0101 !emit { modrm(); mem(size => 8); }
+
+# Comparison Instructions
+PCMPEQB MMX  01110100 !emit { modrm(); mem(size => 8); }
+PCMPEQW MMX  01110101 !emit { modrm(); mem(size => 8); }
+PCMPEQD MMX  01110110 !emit { modrm(); mem(size => 8); }
+PCMPGTB MMX  01100100 !emit { modrm(); mem(size => 8); }
+PCMPGTW MMX  01100101 !emit { modrm(); mem(size => 8); }
+PCMPGTD MMX  01100110 !emit { modrm(); mem(size => 8); }
+
+# Logical Instructions
+PANDMMX  11011011 !emit { modrm(); mem(size => 8); }
+PANDN   MMX  1101 !emit { modrm(); mem(size => 8); }
+POR MMX  11101011 !emit { modrm(); mem(size => 8); }
+PXORMMX  1110 !emit { modrm(); mem(size => 8); }
+
+# Shift and Rotate Instructions
+PSLLW   MMX  0001 !emit { modrm(); mem(size => 8); }
+PSLLD   MMX  0010 !emit { modrm(); mem(size => 8); }
+PSLLQ   MMX  0011 !emit { modrm(); mem(size => 8); }
+
+PSLLW_imm   MMX  01110001 !emit { modrm(mod => MOD_DIRECT, reg 
=> 6); imm(size => 1); }
+PSLLD_imm   MMX  01110010 !emit { modrm(mod => MOD_DIRECT, reg 
=> 6); imm(size => 1); }
+PSLLQ_imm   MMX  01110011 !emit { modrm(mod => MOD_DIRECT, reg 
=> 6); imm(size => 1); }
+
+PSRLW   MMX  11010001 !emit { modrm(); mem(size => 8); }
+PSRLD   MMX  11010010 !emit { modrm(); mem(size => 8); }
+PSRLQ   MMX  11010011 !emit { modrm(); mem(size => 8); }
+
+PSRLW_imm   MMX  01110001 !emit { modrm(mod => MOD_DIRECT, reg 
=> 2); imm(size => 1); }
+PSRLD_imm   MMX  01110010 !emit { modrm(mod => MOD_DIRECT, reg 
=> 2); imm(size => 1); }
+PSRLQ_imm   MMX  01110011 !emit { modrm(mod => MOD_DIRECT, reg 
=> 2); imm(size => 1); }
+
+PSRAW   MMX  1111 !emit { modrm(); mem(size => 8); }
+PSRAD   MMX  11100010 !emit 

[Qemu-devel] [RISU RFC PATCH v2 07/14] x86.risu: add SSE instructions

2019-06-30 Thread Jan Bobek
Add SSE instructions to the x86 configuration file.

Signed-off-by: Jan Bobek 
---
 x86.risu | 100 +++
 1 file changed, 100 insertions(+)

diff --git a/x86.risu b/x86.risu
index f2dd9b0..c29b210 100644
--- a/x86.risu
+++ b/x86.risu
@@ -19,6 +19,18 @@ MOVQMMX  011 d 1110 !emit { rex(w => 
1); modrm(mod => MO
 MOVQ_memMMX  011 d 1110 !emit { rex(w => 1); modrm(mod => 
~MOD_DIRECT); mem(size => 8); }
 MOVQ_mm MMX  011 d  !emit { modrm(); mem(size => 8); }
 
+MOVAPS  SSE  0010100 d !emit { modrm(); mem(size => 16, 
align => 16); }
+MOVUPS  SSE  0001000 d !emit { modrm(); mem(size => 16); }
+MOVSS   SSE  0001000 d !emit { rep(); modrm(); mem(size => 
4); }
+
+MOVLPS  SSE  0001001 d !emit { modrm(mod => ~MOD_DIRECT); 
mem(size => 8); }
+MOVHPS  SSE  0001011 d !emit { modrm(mod => ~MOD_DIRECT); 
mem(size => 8); }
+MOVLHPS SSE  00010110  !emit { modrm(mod => MOD_DIRECT); }
+MOVHLPS SSE  00010010  !emit { modrm(mod => MOD_DIRECT); }
+
+PMOVMSKBSSE  11010111 !emit { modrm(mod => MOD_DIRECT, reg 
=> ~REG_ESP); }
+MOVMSKPSSSE  0101 !emit { modrm(mod => MOD_DIRECT, reg 
=> ~REG_ESP); }
+
 # Arithmetic Instructions
 PADDB   MMX  1100 !emit { modrm(); mem(size => 8); }
 PADDW   MMX  1101 !emit { modrm(); mem(size => 8); }
@@ -29,6 +41,9 @@ PADDSW  MMX  11101101 !emit { modrm(); 
mem(size => 8); }
 PADDUSB MMX  11011100 !emit { modrm(); mem(size => 8); }
 PADDUSW MMX  11011101 !emit { modrm(); mem(size => 8); }
 
+ADDPS   SSE  01011000 !emit { modrm(); mem(size => 16, 
align => 16); }
+ADDSS   SSE  01011000 !emit { rep(); modrm(); mem(size => 
4); }
+
 PSUBB   MMX  1000 !emit { modrm(); mem(size => 8); }
 PSUBW   MMX  1001 !emit { modrm(); mem(size => 8); }
 PSUBD   MMX  1010 !emit { modrm(); mem(size => 8); }
@@ -37,11 +52,47 @@ PSUBSW  MMX  11101001 !emit { modrm(); 
mem(size => 8); }
 PSUBUSB MMX  11011000 !emit { modrm(); mem(size => 8); }
 PSUBUSW MMX  11011001 !emit { modrm(); mem(size => 8); }
 
+SUBPS   SSE  01011100 !emit { modrm(); mem(size => 16, 
align => 16); }
+SUBSS   SSE  01011100 !emit { rep(); modrm(); mem(size => 
4); }
+
 PMULLW  MMX  11010101 !emit { modrm(); mem(size => 8); }
 PMULHW  MMX  11100101 !emit { modrm(); mem(size => 8); }
+PMULHUW SSE  11100100 !emit { modrm(); mem(size => 8); }
+
+MULPS   SSE  01011001 !emit { modrm(); mem(size => 16, 
align => 16); }
+MULSS   SSE  01011001 !emit { rep(); modrm(); mem(size => 
4); }
 
 PMADDWD MMX  0101 !emit { modrm(); mem(size => 8); }
 
+DIVPS   SSE  0100 !emit { modrm(); mem(size => 16, 
align => 16); }
+DIVSS   SSE  0100 !emit { rep(); modrm(); mem(size => 
4); }
+
+RCPPS   SSE  01010011 !emit { modrm(); mem(size => 16, 
align => 16); }
+RCPSS   SSE  01010011 !emit { rep(); modrm(); mem(size => 
4); }
+
+SQRTPS  SSE  01010001 !emit { modrm(); mem(size => 16, 
align => 16); }
+SQRTSS  SSE  01010001 !emit { rep(); modrm(); mem(size => 
4); }
+
+RSQRTPS SSE  01010010 !emit { modrm(); mem(size => 16, 
align => 16); }
+RSQRTSS SSE  01010010 !emit { rep(); modrm(); mem(size => 
4); }
+
+PMINUB  SSE  11011010 !emit { modrm(); mem(size => 8); }
+PMINSW  SSE  11101010 !emit { modrm(); mem(size => 8); }
+
+MINPS   SSE  01011101 !emit { modrm(); mem(size => 16, 
align => 16); }
+MINSS   SSE  01011101 !emit { rep(); modrm(); mem(size => 
4); }
+
+PMAXUB  SSE  1100 !emit { modrm(); mem(size => 8); }
+PMAXSW  SSE  11101110 !emit { modrm(); mem(size => 8); }
+
+MAXPS   SSE  0101 !emit { modrm(); mem(size => 16, 
align => 16); }
+MAXSS   SSE  0101 !emit { rep(); modrm(); mem(size => 
4); }
+
+PAVGB   SSE  1110 !emit { modrm(); mem(size => 8); }
+PAVGW   SSE  11100011 !emit { modrm(); mem(size => 8); }
+
+PSADBW  SSE  0110 !emit { modrm(); mem(size => 8); }
+
 # Comparison Instructions
 PCMPEQB MMX  01110100 !emit { modrm(); mem(size => 8); }
 PCMPEQW MMX  01110101 !emit { modrm(); mem(size => 

[Qemu-devel] [RISU RFC PATCH v2 10/14] x86.risu: add SSSE3 instructions

2019-06-30 Thread Jan Bobek
Add SSSE3 instructions to the x86 configuration file.

Signed-off-by: Jan Bobek 
---
 x86.risu | 38 ++
 1 file changed, 38 insertions(+)

diff --git a/x86.risu b/x86.risu
index 01181dd..35992d6 100644
--- a/x86.risu
+++ b/x86.risu
@@ -77,6 +77,13 @@ ADDPD   SSE2 01011000 !emit { data16(); 
modrm(); mem(size =>
 ADDSS   SSE  01011000 !emit { rep(); modrm(); mem(size => 
4); }
 ADDSD   SSE2 01011000 !emit { repne(); modrm(); mem(size 
=> 8); }
 
+PHADDW_64   SSSE3    00111000 0001 !emit { modrm(); mem(size 
=> 8); }
+PHADDW  SSSE3    00111000 0001 !emit { data16(); modrm(); 
mem(size => 16, align => 16); }
+PHADDD_64   SSSE3    00111000 0010 !emit { modrm(); mem(size 
=> 8); }
+PHADDD  SSSE3    00111000 0010 !emit { data16(); modrm(); 
mem(size => 16, align => 16); }
+PHADDSW_64  SSSE3    00111000 0011 !emit { modrm(); mem(size 
=> 8); }
+PHADDSW SSSE3    00111000 0011 !emit { data16(); modrm(); 
mem(size => 16, align => 16); }
+
 HADDPS  SSE3 0100 !emit { repne(); modrm(); mem(size 
=> 16, align => 16); }
 HADDPD  SSE3 0100 !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
 
@@ -102,6 +109,13 @@ SUBPD   SSE2 01011100 !emit { 
data16(); modrm(); mem(size =>
 SUBSS   SSE  01011100 !emit { rep(); modrm(); mem(size => 
4); }
 SUBSD   SSE2 01011100 !emit { repne(); modrm(); mem(size 
=> 8); }
 
+PHSUBW_64   SSSE3    00111000 0101 !emit { modrm(); mem(size 
=> 8); }
+PHSUBW  SSSE3    00111000 0101 !emit { data16(); modrm(); 
mem(size => 16, align => 16); }
+PHSUBD_64   SSSE3    00111000 0110 !emit { modrm(); mem(size 
=> 8); }
+PHSUBD  SSSE3    00111000 0110 !emit { data16(); modrm(); 
mem(size => 16, align => 16); }
+PHSUBSW_64  SSSE3    00111000 0111 !emit { modrm(); mem(size 
=> 8); }
+PHSUBSW SSSE3    00111000 0111 !emit { data16(); modrm(); 
mem(size => 16, align => 16); }
+
 HSUBPS  SSE3 0101 !emit { repne(); modrm(); mem(size 
=> 16, align => 16); }
 HSUBPD  SSE3 0101 !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
 
@@ -117,6 +131,9 @@ PMULHUW SSE2 11100100 !emit { data16(); 
modrm(); mem(size =>
 PMULUDQ_64  SSE2 0100 !emit { modrm(); mem(size => 8); }
 PMULUDQ SSE2 0100 !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
 
+PMULHRSW_64 SSSE3    00111000 1011 !emit { modrm(); mem(size 
=> 8); }
+PMULHRSWSSSE3    00111000 1011 !emit { data16(); modrm(); 
mem(size => 16, align => 16); }
+
 MULPS   SSE  01011001 !emit { modrm(); mem(size => 16, 
align => 16); }
 MULPD   SSE2 01011001 !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
 MULSS   SSE  01011001 !emit { rep(); modrm(); mem(size => 
4); }
@@ -124,6 +141,8 @@ MULSD   SSE2 01011001 !emit { repne(); 
modrm(); mem(size =>
 
 PMADDWD MMX  0101 !emit { modrm(); mem(size => 8); }
 PMADDWD SSE2 0101 !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
+PMADDUBSW_64SSSE3    00111000 0100 !emit { modrm(); mem(size 
=> 8); }
+PMADDUBSW   SSSE3    00111000 0100 !emit { data16(); modrm(); 
mem(size => 16, align => 16); }
 
 DIVPS   SSE  0100 !emit { modrm(); mem(size => 16, 
align => 16); }
 DIVPD   SSE2 0100 !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
@@ -169,6 +188,20 @@ PAVGW   SSE2 11100011 !emit { 
data16(); modrm(); mem(size =>
 PSADBW  SSE  0110 !emit { modrm(); mem(size => 8); }
 PSADBW  SSE2 0110 !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
 
+PABSB_64SSSE3    00111000 00011100 !emit { modrm(); mem(size 
=> 8); }
+PABSB   SSSE3    00111000 00011100 !emit { data16(); modrm(); 
mem(size => 16, align => 16); }
+PABSW_64SSSE3    00111000 00011101 !emit { modrm(); mem(size 
=> 8); }
+PABSW   SSSE3    00111000 00011101 !emit { data16(); modrm(); 
mem(size => 16, align => 16); }
+PABSD_64SSSE3    00111000 0000 !emit { modrm(); mem(size 
=> 8); }
+PABSD   SSSE3    00111000 0000 !emit { data16(); modrm(); 
mem(size => 16, align => 16); }
+
+PSIGNB_64   SSSE3    00111000 1000 !emit { modrm(); mem(size 
=> 8); }
+PSIGNB  SSSE3    00111000 1000 !emit { data16(); modrm(); 
mem(size => 16, align => 16); }
+PSIGNW_64   

[Qemu-devel] [RISU RFC PATCH v2 14/14] x86.risu: add AVX2 instructions

2019-06-30 Thread Jan Bobek
Add AVX2 instructions to the configuration file.

Signed-off-by: Jan Bobek 
---
 x86.risu | 257 +++
 1 file changed, 257 insertions(+)

diff --git a/x86.risu b/x86.risu
index d3115ac..74c4ce8 100644
--- a/x86.risu
+++ b/x86.risu
@@ -33,16 +33,22 @@ VMOVQ_xmm2  AVX  11010110 !emit { vex(l => 
VEX_L_128, p => VEX_P
 
 MOVAPS  SSE  0010100 d !emit { modrm(); mem(size => 16, 
align => 16); }
 VMOVAPS AVX  0010100 d !emit { vex(l => VEX_L_128, m => 
VEX_M_0F, v => VEX_V_UNUSED); modrm(); mem(size => 16, align => 16); }
+VMOVAPS AVX2 0010100 d !emit { vex(l => VEX_L_256, m => 
VEX_M_0F, v => VEX_V_UNUSED); modrm(); mem(size => 32, align => 32); }
 MOVAPD  SSE2 0010100 d !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
 VMOVAPD AVX  0010100 d !emit { vex(l => VEX_L_128, p => 
VEX_P_DATA16, m => VEX_M_0F, v => VEX_V_UNUSED); modrm(); mem(size => 16, align 
=> 16); }
+VMOVAPD AVX2 0010100 d !emit { vex(l => VEX_L_256, p => 
VEX_P_DATA16, m => VEX_M_0F, v => VEX_V_UNUSED); modrm(); mem(size => 32, align 
=> 32); }
 MOVDQA  SSE2 011 d  !emit { data16(); modrm(); 
mem(size => 16, align => 16); }
 VMOVDQA AVX  011 d  !emit { vex(l => VEX_L_128, p => 
VEX_P_DATA16, m => VEX_M_0F, v => VEX_V_UNUSED); modrm(); mem(size => 16, align 
=> 16); }
+VMOVDQA AVX2 011 d  !emit { vex(l => VEX_L_256, p => 
VEX_P_DATA16, m => VEX_M_0F, v => VEX_V_UNUSED); modrm(); mem(size => 32, align 
=> 32); }
 MOVUPS  SSE  0001000 d !emit { modrm(); mem(size => 16); }
 VMOVUPS AVX  0001000 d !emit { vex(l => VEX_L_128, m => 
VEX_M_0F, v => VEX_V_UNUSED); modrm(); mem(size => 16); }
+VMOVUPS AVX2 0001000 d !emit { vex(l => VEX_L_256, m => 
VEX_M_0F, v => VEX_V_UNUSED); modrm(); mem(size => 32); }
 MOVUPD  SSE2 0001000 d !emit { data16(); modrm(); mem(size 
=> 16); }
 VMOVUPD AVX  0001000 d !emit { vex(l => VEX_L_128, p => 
VEX_P_DATA16, m => VEX_M_0F, v => VEX_V_UNUSED); modrm(); mem(size => 16); }
+VMOVUPD AVX2 0001000 d !emit { vex(l => VEX_L_256, p => 
VEX_P_DATA16, m => VEX_M_0F, v => VEX_V_UNUSED); modrm(); mem(size => 32); }
 MOVDQU  SSE2 011 d  !emit { rep(); modrm(); mem(size 
=> 16); }
 VMOVDQU AVX  011 d  !emit { vex(l => VEX_L_128, p => 
VEX_P_REP, m => VEX_M_0F, v => VEX_V_UNUSED); modrm(); mem(size => 16); }
+VMOVDQU AVX2 011 d  !emit { vex(l => VEX_L_256, p => 
VEX_P_REP, m => VEX_M_0F, v => VEX_V_UNUSED); modrm(); mem(size => 32); }
 MOVSS   SSE  0001000 d !emit { rep(); modrm(); mem(size => 
4); }
 VMOVSS  AVX  0001000 d !emit { vex(l => VEX_L_128, p => 
VEX_P_REP, m => VEX_M_0F); modrm(mod => MOD_DIRECT); }
 VMOVSS_mem  AVX  0001000 d !emit { vex(l => VEX_L_128, p => 
VEX_P_REP, m => VEX_M_0F, v => VEX_V_UNUSED); modrm(mod => ~MOD_DIRECT); 
mem(size => 4); }
@@ -73,50 +79,67 @@ VMOVHLPSAVX  00010010  !emit { vex(l => 
VEX_L_128, m => VEX_
 PMOVMSKBSSE  11010111 !emit { modrm(mod => MOD_DIRECT, reg 
=> ~REG_ESP); }
 PMOVMSKBSSE2 11010111 !emit { data16(); modrm(mod => 
MOD_DIRECT, reg => ~REG_ESP); }
 VPMOVMSKB   AVX  11010111 !emit { vex(l => VEX_L_128, p => 
VEX_P_DATA16, m => VEX_M_0F, v => VEX_V_UNUSED); modrm(mod => MOD_DIRECT, reg 
=> ~REG_ESP); }
+VPMOVMSKB   AVX2 11010111 !emit { vex(l => VEX_L_256, p => 
VEX_P_DATA16, m => VEX_M_0F, v => VEX_V_UNUSED); modrm(mod => MOD_DIRECT, reg 
=> ~REG_ESP); }
 MOVMSKPSSSE  0101 !emit { modrm(mod => MOD_DIRECT, reg 
=> ~REG_ESP); }
 VMOVMSKPS   AVX  0101 !emit { vex(l => VEX_L_128, m => 
VEX_M_0F, v => VEX_V_UNUSED); modrm(mod => MOD_DIRECT, reg => ~REG_ESP); }
+VMOVMSKPS   AVX2 0101 !emit { vex(l => VEX_L_256, m => 
VEX_M_0F, v => VEX_V_UNUSED); modrm(mod => MOD_DIRECT, reg => ~REG_ESP); }
 MOVMKSPDSSE2 0101 !emit { data16(); modrm(mod => 
MOD_DIRECT, reg => ~REG_ESP); }
 VMOVMSKPD   AVX  0101 !emit { vex(l => VEX_L_128, p => 
VEX_P_DATA16, m => VEX_M_0F, v => VEX_V_UNUSED); modrm(mod => MOD_DIRECT, reg 
=> ~REG_ESP); }
+VMOVMSKPD   AVX2 0101 !emit { vex(l => VEX_L_256, p => 
VEX_P_DATA16, m => VEX_M_0F, v => VEX_V_UNUSED); modrm(mod => MOD_DIRECT, reg 
=> ~REG_ESP); }
 
 LDDQU   SSE3  !emit { repne(); modrm(mod => 
~MOD_DIRECT); mem(size => 16); }
 VLDDQU  AVX   !emit { vex(l => VEX_L_128, p => 
VEX_P_REPNE, m => VEX_M_0F, v => VEX_V_UNUSED); modrm(mod => ~MOD_DIRECT); 
mem(size => 16); }
+VLDDQU   

[Qemu-devel] [RISU RFC PATCH v2 05/14] risugen: allow all byte-aligned instructions

2019-06-30 Thread Jan Bobek
Accept all instructions whose bit length is divisible by 8. Note that
the maximum instruction length (as specified in the config file) is 32
bits, hence this change permits instructions which are 8 bits or 24
bits long (16-bit instructions have already been considered valid).

Note that while valid x86 instructions may be up to 15 bytes long, the
length constraint described above only applies to the main opcode
field, which is usually only 1 or 2 bytes long. Therefore, the primary
purpose of this change is to allow 1-byte x86 opcodes.

Reviewed-by: Richard Henderson 
Signed-off-by: Jan Bobek 
---
 risugen | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/risugen b/risugen
index 09a702a..17bf98f 100755
--- a/risugen
+++ b/risugen
@@ -229,12 +229,11 @@ sub parse_config_file($)
 push @fields, [ $var, $bitpos, $bitmask ];
 }
 }
-if ($bitpos == 16) {
-# assume this is a half-width thumb instruction
+if ($bitpos % 8 == 0) {
 # Note that we don't fiddle with the bitmasks or positions,
 # which means the generated insn will be in the high halfword!
-$insnwidth = 16;
-} elsif ($bitpos != 0) {
+$insnwidth -= $bitpos;
+} else {
 print STDERR "$file:$.: ($insn $enc) not enough bits specified\n";
 exit(1);
 }
-- 
2.20.1




[Qemu-devel] [RISU RFC PATCH v2 01/14] risugen_common: add insnv, randint_constr, rand_fill

2019-06-30 Thread Jan Bobek
Add three common utility functions:

- insnv allows emitting variable-length instructions in little-endian
  or big-endian byte order; it subsumes functionality of former
  insn16() and insn32() functions.

- randint_constr allows generating random integers according to
  several constraints passed as arguments.

- rand_fill uses randint_constr to fill a given hash with
  (optionally constrained) random values.

Signed-off-by: Jan Bobek 
---
 risugen_common.pm | 107 +++---
 1 file changed, 101 insertions(+), 6 deletions(-)

diff --git a/risugen_common.pm b/risugen_common.pm
index 71ee996..c5d861e 100644
--- a/risugen_common.pm
+++ b/risugen_common.pm
@@ -23,7 +23,8 @@ BEGIN {
 require Exporter;
 
 our @ISA = qw(Exporter);
-our @EXPORT = qw(open_bin close_bin set_endian insn32 insn16 $bytecount
+our @EXPORT = qw(open_bin close_bin set_endian insn32 insn16
+   $bytecount insnv randint_constr rand_fill
progress_start progress_update progress_end
eval_with_fields is_pow_of_2 sextract ctz
dump_insn_details);
@@ -37,7 +38,7 @@ my $bigendian = 0;
 # (default is little endian, 0).
 sub set_endian
 {
-$bigendian = @_;
+($bigendian) = @_;
 }
 
 sub open_bin
@@ -52,18 +53,112 @@ sub close_bin
 close(BIN) or die "can't close output file: $!";
 }
 
+sub insnv(%)
+{
+my (%args) = @_;
+
+# Default to big-endian order, so that the instruction bytes are
+# emitted in the same order as they are written in the
+# configuration file.
+$args{bigendian} = 1 unless defined $args{bigendian};
+
+my $bitcur = 0;
+my $bitend = 8 * $args{len};
+while ($bitcur < $bitend) {
+my $format;
+my $bitlen;
+
+if ($bitcur + 64 <= $bitend) {
+$format = "Q";
+$bitlen = 64;
+} elsif ($bitcur + 32 <= $bitend) {
+$format = "L";
+$bitlen = 32;
+} elsif ($bitcur + 16 <= $bitend) {
+$format = "S";
+$bitlen = 16;
+} else {
+$format = "C";
+$bitlen = 8;
+}
+
+$format .= ($args{bigendian} ? ">" : "<") if $bitlen > 8;
+
+my $bitmask = (1 << $bitlen) - 1;
+my $value = $args{value} >> ($args{bigendian}
+ ? $bitend - $bitcur - $bitlen
+ : $bitcur);
+
+print BIN pack($format, $value & $bitmask);
+$bytecount += $bitlen / 8;
+
+$bitcur += $bitlen;
+}
+}
+
 sub insn32($)
 {
 my ($insn) = @_;
-print BIN pack($bigendian ? "N" : "V", $insn);
-$bytecount += 4;
+insnv(value => $insn, len => 4, bigendian => $bigendian);
 }
 
 sub insn16($)
 {
 my ($insn) = @_;
-print BIN pack($bigendian ? "n" : "v", $insn);
-$bytecount += 2;
+insnv(value => $insn, len => 2, bigendian => $bigendian);
+}
+
+sub randint_constr(%)
+{
+my (%args) = @_;
+my $bitlen = $args{bitlen};
+my $halfrange = 1 << ($bitlen - 1);
+
+while (1) {
+my $value = int(rand(2 * $halfrange));
+$value -= $halfrange if defined $args{signed} && $args{signed};
+$value &= ~$args{fixedbitmask} if defined $args{fixedbitmask};
+$value |= $args{fixedbits} if defined $args{fixedbits};
+
+if (defined $args{constraint}) {
+# The idea is: if the most significant bit of
+# $args{constraint} is zero, $args{constraint} is the
+# value we want to return; if the most significant bit is
+# one, ~$args{constraint} (its bit inversion) is the value
+# we want to *avoid*, so we try again.
+
+if (!($args{constraint} >> 63)) {
+$value = $args{constraint};
+} elsif ($value == ~$args{constraint}) {
+next;
+}
+}
+
+return $value;
+}
+}
+
+sub rand_fill($$)
+{
+my ($target, $constraints) = @_;
+
+for (keys %{$target}) {
+my %args = (bitlen => $target->{$_}{bitlen});
+
+$args{fixedbits} = $target->{$_}{fixedbits}
+if defined $target->{$_}{fixedbits};
+$args{fixedbitmask} = $target->{$_}{fixedbitmask}
+if defined $target->{$_}{fixedbitmask};
+$args{signed} = $target->{$_}{signed}
+if defined $target->{$_}{signed};
+
+$args{constraint} = $constraints->{$_}
+if defined $constraints->{$_};
+
+$target->{$_} = randint_constr(%args);
+}
+
+return $target;
 }
 
 # Progress bar implementation
-- 
2.20.1




[Qemu-devel] [RISU RFC PATCH v2 09/14] x86.risu: add SSE3 instructions

2019-06-30 Thread Jan Bobek
Add SSE3 instructions to the x86 configuration file.

Signed-off-by: Jan Bobek 
---
 x86.risu | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/x86.risu b/x86.risu
index 9b63d6b..01181dd 100644
--- a/x86.risu
+++ b/x86.risu
@@ -49,6 +49,11 @@ PMOVMSKBSSE2 11010111 !emit { data16(); 
modrm(mod => MOD_DIR
 MOVMSKPSSSE  0101 !emit { modrm(mod => MOD_DIRECT, reg 
=> ~REG_ESP); }
 MOVMKSPDSSE2 0101 !emit { data16(); modrm(mod => 
MOD_DIRECT, reg => ~REG_ESP); }
 
+LDDQU   SSE3  !emit { repne(); modrm(mod => 
~MOD_DIRECT); mem(size => 16); }
+MOVSHDUPSSE3 00010110 !emit { rep(); modrm(); mem(size => 
16, align => 16); }
+MOVSLDUPSSE3 00010010 !emit { rep(); modrm(); mem(size => 
16, align => 16); }
+MOVDDUP SSE3 00010010 !emit { repne(); modrm(); mem(size 
=> 8); }
+
 # Arithmetic Instructions
 PADDB   MMX  1100 !emit { modrm(); mem(size => 8); }
 PADDB   SSE2 1100 !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
@@ -72,6 +77,9 @@ ADDPD   SSE2 01011000 !emit { data16(); 
modrm(); mem(size =>
 ADDSS   SSE  01011000 !emit { rep(); modrm(); mem(size => 
4); }
 ADDSD   SSE2 01011000 !emit { repne(); modrm(); mem(size 
=> 8); }
 
+HADDPS  SSE3 0100 !emit { repne(); modrm(); mem(size 
=> 16, align => 16); }
+HADDPD  SSE3 0100 !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
+
 PSUBB   MMX  1000 !emit { modrm(); mem(size => 8); }
 PSUBB   SSE2 1000 !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
 PSUBW   MMX  1001 !emit { modrm(); mem(size => 8); }
@@ -94,6 +102,12 @@ SUBPD   SSE2 01011100 !emit { data16(); 
modrm(); mem(size =>
 SUBSS   SSE  01011100 !emit { rep(); modrm(); mem(size => 
4); }
 SUBSD   SSE2 01011100 !emit { repne(); modrm(); mem(size 
=> 8); }
 
+HSUBPS  SSE3 0101 !emit { repne(); modrm(); mem(size 
=> 16, align => 16); }
+HSUBPD  SSE3 0101 !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
+
+ADDSUBPSSSE3 1101 !emit { repne(); modrm(); mem(size 
=> 16, align => 16); }
+ADDSUBPDSSE3 1101 !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
+
 PMULLW  MMX  11010101 !emit { modrm(); mem(size => 8); }
 PMULLW  SSE2 11010101 !emit { data16(); modrm(); mem(size 
=> 16, align => 16); }
 PMULHW  MMX  11100101 !emit { modrm(); mem(size => 8); }
-- 
2.20.1




[Qemu-devel] [RISU RFC PATCH v2 04/14] risugen_x86: add module

2019-06-30 Thread Jan Bobek
The risugen_x86.pm module contains most of the code specific to Intel
i386 and x86_64 architectures. This commit also adds --x86_64 option,
which enables emission of 64-bit (rather than 32-bit) assembly.

Signed-off-by: Jan Bobek 
---
 risugen|   6 +-
 risugen_x86.pm | 498 +
 2 files changed, 503 insertions(+), 1 deletion(-)
 create mode 100644 risugen_x86.pm

diff --git a/risugen b/risugen
index fe3d00e..09a702a 100755
--- a/risugen
+++ b/risugen
@@ -310,6 +310,7 @@ Valid options:
Useful to test before support for FP is available.
 --sve: enable sve floating point
 --be : generate instructions in Big-Endian byte order (ppc64 only).
+--x86_64 : generate 64-bit (rather than 32-bit) x86 code.
 --help   : print this message
 EOT
 }
@@ -322,6 +323,7 @@ sub main()
 my $fp_enabled = 1;
 my $sve_enabled = 0;
 my $big_endian = 0;
+my $is_x86_64 = 0;
 my ($infile, $outfile);
 
 GetOptions( "help" => sub { usage(); exit(0); },
@@ -338,6 +340,7 @@ sub main()
 },
 "be" => sub { $big_endian = 1; },
 "no-fp" => sub { $fp_enabled = 0; },
+"x86_64" => sub { $is_x86_64 = 1; },
 "sve" => sub { $sve_enabled = 1; },
 ) or return 1;
 # allow "--pattern re,re" and "--pattern re --pattern re"
@@ -372,7 +375,8 @@ sub main()
 'keys' => \@insn_keys,
 'arch' => $full_arch[0],
 'subarch' => $full_arch[1] || '',
-'bigendian' => $big_endian
+'bigendian' => $big_endian,
+'x86_64' => $is_x86_64
 );
 
 write_test_code(\%params);
diff --git a/risugen_x86.pm b/risugen_x86.pm
new file mode 100644
index 000..fd16c45
--- /dev/null
+++ b/risugen_x86.pm
@@ -0,0 +1,498 @@
+#!/usr/bin/perl -w
+###
+# Copyright (c) 2019 Linaro Limited
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Jan Bobek - initial implementation
+###
+
+# risugen_x86 -- risugen module for Intel i386/x86_64 architectures
+package risugen_x86;
+
+use strict;
+use warnings;
+
+use risugen_common;
+use risugen_x86_asm;
+use risugen_x86_emit;
+
+require Exporter;
+
+our @ISA= qw(Exporter);
+our @EXPORT = qw(write_test_code);
+
+use constant {
+RISUOP_COMPARE => 0,# compare registers
+RISUOP_TESTEND => 1,# end of test, stop
+RISUOP_SETMEMBLOCK => 2,# eax is address of memory block (8192 
bytes)
+RISUOP_GETMEMBLOCK => 3,# add the address of memory block to eax
+RISUOP_COMPAREMEM  => 4,# compare memory block
+
+# Maximum alignment restriction permitted for a memory op.
+MAXALIGN => 64,
+MEMBLOCK_LEN => 8192,
+};
+
+my $periodic_reg_random = 1;
+my $is_x86_64 = 0;
+
+sub write_risuop($)
+{
+my ($op) = @_;
+
+write_insn(opcode => X86OP_UD1,
+   modrm => {mod => MOD_DIRECT,
+ reg => REG_EAX,
+ rm => $op});
+}
+
+sub write_mov_rr($$)
+{
+my ($r1, $r2) = @_;
+
+my %insn = (opcode => X86OP_MOV,
+modrm => {mod => MOD_DIRECT,
+  reg => ($r1 & 0x7),
+  rm => ($r2 & 0x7)});
+
+$insn{rex}{w} = 1 if $is_x86_64;
+$insn{rex}{r} = 1 if $r1 >= 8;
+$insn{rex}{b} = 1 if $r2 >= 8;
+
+write_insn(%insn);
+}
+
+sub write_mov_reg_imm($$)
+{
+my ($reg, $imm) = @_;
+my %insn;
+
+if (0 <= $imm && $imm <= 0x) {
+%insn = (opcode => {value => 0xB8 | ($reg & 0x7), len => 1},
+ imm => {value => $imm, len => 4});
+} elsif (-0x8000 <= $imm && $imm <= 0x7fff) {
+%insn = (opcode => {value => 0xC7, len => 1},
+ modrm => {mod => MOD_DIRECT,
+   reg => 0, rm => ($reg & 0x7)},
+ imm => {value => $imm, len => 4});
+
+$insn{rex}{w} = 1 if $is_x86_64;
+} else {
+%insn = (rex => {w => 1},
+ opcode => {value => 0xB8 | ($reg & 0x7), len => 1},
+ imm => {value => $imm, len => 8});
+}
+
+$insn{rex}{b} = 1 if $reg >= 8;
+write_insn(%insn);
+}
+
+sub write_random_regdata()
+{
+my $reg_cnt = $is_x86_64 ? 16 : 8;
+my $bitlen = $is_x86_64 ? 64 : 32;
+
+# initialize flags register
+write_insn(opcode => X86OP_XOR,
+   modrm => {mod => MOD_DIRECT,
+ reg => REG_EAX,
+ rm => REG_EAX});
+write_insn(opcode => X86OP_SAHF);
+
+# general purpose registers
+for (my $reg = 0; $reg < 

[Qemu-devel] [RISU RFC PATCH v2 02/14] risugen_x86_asm: add module

2019-06-30 Thread Jan Bobek
The module risugen_x86_asm.pm exports several constants and the
function write_insn, which work in tandem to allow emission of x86
instructions in more clear and structured manner.

Signed-off-by: Jan Bobek 
---
 risugen_x86_asm.pm | 252 +
 1 file changed, 252 insertions(+)
 create mode 100644 risugen_x86_asm.pm

diff --git a/risugen_x86_asm.pm b/risugen_x86_asm.pm
new file mode 100644
index 000..5640531
--- /dev/null
+++ b/risugen_x86_asm.pm
@@ -0,0 +1,252 @@
+#!/usr/bin/perl -w
+###
+# Copyright (c) 2019 Linaro Limited
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Jan Bobek - initial implementation
+###
+
+# risugen_x86_asm -- risugen_x86's helper module for x86 assembly
+package risugen_x86_asm;
+
+use strict;
+use warnings;
+
+use risugen_common;
+
+our @ISA= qw(Exporter);
+our @EXPORT = qw(
+write_insn
+VEX_L_128 VEX_L_256
+VEX_P_NONE VEX_P_DATA16 VEX_P_REP VEX_P_REPNE
+VEX_M_0F VEX_M_0F38 VEX_M_0F3A
+VEX_V_UNUSED
+REG_EAX REG_ECX REG_EDX REG_EBX REG_ESP REG_EBP REG_ESI REG_EDI
+MOD_INDIRECT MOD_INDIRECT_DISP8 MOD_INDIRECT_DISP32 MOD_DIRECT
+X86PFX_DATA16 X86PFX_REPNE X86PFX_REP
+X86OP_LEA X86OP_XOR X86OP_ALU_imm8 X86OP_MOV X86OP_SAHF X86OP_CALL
+X86OP_JMP X86OP_UD1 X86OP_VMOVAPS X86OP_MOVAPS
+);
+
+use constant {
+VEX_L_128 => 0,
+VEX_L_256 => 1,
+
+VEX_P_NONE   => 0b00,
+VEX_P_DATA16 => 0b01,
+VEX_P_REP=> 0b10,
+VEX_P_REPNE  => 0b11,
+
+VEX_M_0F   => 0b1,
+VEX_M_0F38 => 0b00010,
+VEX_M_0F3A => 0b00011,
+
+VEX_V_UNUSED => 0b,
+
+REG_EAX => 0,
+REG_ECX => 1,
+REG_EDX => 2,
+REG_EBX => 3,
+REG_ESP => 4,
+REG_EBP => 5,
+REG_ESI => 6,
+REG_EDI => 7,
+
+MOD_INDIRECT=> 0b00,
+MOD_INDIRECT_DISP8  => 0b01,
+MOD_INDIRECT_DISP32 => 0b10,
+MOD_DIRECT  => 0b11,
+
+X86PFX_DATA16 => {value => 0x66, len => 1},
+X86PFX_REPNE  => {value => 0xF2, len => 1},
+X86PFX_REP=> {value => 0xF3, len => 1},
+
+X86OP_LEA  => {value => 0x8D, len => 1},
+X86OP_XOR  => {value => 0x33, len => 1},
+X86OP_ALU_imm8 => {value => 0x83, len => 1},
+X86OP_MOV  => {value => 0x8B, len => 1},
+X86OP_SAHF => {value => 0x9E, len => 1},
+X86OP_CALL => {value => 0xE8, len => 1},
+X86OP_JMP  => {value => 0xE9, len => 1},
+
+X86OP_UD1  => {value => 0x0FB9, len => 2},
+X86OP_VMOVAPS  => {value => 0x28, len => 1},
+X86OP_MOVAPS   => {value => 0x0F28, len => 2},
+};
+
+sub rex_encode(%)
+{
+my (%args) = @_;
+
+$args{w} = 0 unless defined $args{w};
+$args{r} = 0 unless defined $args{r};
+$args{x} = 0 unless defined $args{x};
+$args{b} = 0 unless defined $args{b};
+
+return (value => 0x40
+| (($args{w} ? 1 : 0) << 3)
+| (($args{r} ? 1 : 0) << 2)
+| (($args{x} ? 1 : 0) << 1)
+| ($args{b} ? 1 : 0),
+len => 1);
+}
+
+sub vex_encode(%)
+{
+my (%args) = @_;
+
+$args{r} = 1 unless defined $args{r};
+$args{x} = 1 unless defined $args{x};
+$args{b} = 1 unless defined $args{b};
+$args{v} = VEX_V_UNUSED unless defined $args{v};
+$args{p} = VEX_P_NONE unless defined $args{p};
+
+die "l field undefined"
+unless defined $args{l};
+die "v field out-of-range: $args{v}"
+unless 0b <= $args{v} && $args{v} <= 0b;
+die "p field out-of-range: $args{p}"
+unless 0b00 <= $args{p} && $args{p} <= 0b11;
+
+if ($args{x} && $args{b} && !defined $args{m} && !defined $args{w}) {
+# We can use the 2-byte VEX prefix
+return (value => (0xC5 << 8)
+| (($args{r} ? 1 : 0) << 7)
+| ($args{v} << 3)
+| (($args{l} ? 1 : 0) << 2)
+| $args{p},
+len => 2);
+} else {
+# We have to use the 3-byte VEX prefix
+die "m field undefined"
+unless defined $args{m};
+die "m field out-of-range: $args{m}"
+unless 0b0 <= $args{m} && $args{m} <= 0b1;
+die "w field undefined"
+unless defined $args{w};
+
+return (value => (0xC4 << 16)
+| (($args{r} ? 1 : 0) << 15)
+| (($args{x} ? 1 : 0) << 14)
+| (($args{b} ? 1 : 0) << 13)
+| ($args{m} << 8)
+| (($args{w} ? 1 : 0) << 7)
+| ($args{v} << 3)
+| (($args{l} ? 1 : 0) << 2)
+| $args{p},
+len => 3);
+}
+}
+
+sub modrm_encode(%)

[Qemu-devel] [RISU RFC PATCH v2 03/14] risugen_x86_emit: add module

2019-06-30 Thread Jan Bobek
The helper module risugen_x86_emit.pm exports a single function
"parse_emitblock", which serves to capture and return instruction
constraints described by "emit" blocks in an x86 configuration file.

Signed-off-by: Jan Bobek 
---
 risugen |  2 +-
 risugen_x86_emit.pm | 91 +
 2 files changed, 92 insertions(+), 1 deletion(-)
 create mode 100644 risugen_x86_emit.pm

diff --git a/risugen b/risugen
index e690b18..fe3d00e 100755
--- a/risugen
+++ b/risugen
@@ -43,7 +43,7 @@ my @pattern_re = ();# include pattern
 my @not_pattern_re = ();# exclude pattern
 
 # Valid block names (keys in blocks hash)
-my %valid_blockname = ( constraints => 1, memory => 1 );
+my %valid_blockname = ( constraints => 1, memory => 1, emit => 1 );
 
 sub parse_risu_directive($$@)
 {
diff --git a/risugen_x86_emit.pm b/risugen_x86_emit.pm
new file mode 100644
index 000..127a524
--- /dev/null
+++ b/risugen_x86_emit.pm
@@ -0,0 +1,91 @@
+#!/usr/bin/perl -w
+###
+# Copyright (c) 2019 Linaro Limited
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Jan Bobek - initial implementation
+###
+
+# risugen_x86_emit -- risugen_x86's helper module for emit blocks
+package risugen_x86_emit;
+
+use strict;
+use warnings;
+
+use risugen_common;
+use risugen_x86_asm;
+
+our @ISA= qw(Exporter);
+our @EXPORT = qw(parse_emitblock);
+
+my $emit_opts;
+
+sub rep(%)
+{
+my (%opts) = @_;
+$emit_opts->{rep} = \%opts;
+}
+
+sub repne(%)
+{
+my (%opts) = @_;
+$emit_opts->{repne} = \%opts;
+}
+
+sub data16(%)
+{
+my (%opts) = @_;
+$emit_opts->{data16} = \%opts;
+}
+
+sub rex(%)
+{
+my (%opts) = @_;
+$emit_opts->{rex} = \%opts;
+}
+
+sub vex(%)
+{
+my (%opts) = @_;
+$emit_opts->{vex} = \%opts;
+}
+
+sub modrm(%)
+{
+my (%opts) = @_;
+$emit_opts->{modrm} = \%opts;
+}
+
+sub mem(%)
+{
+my (%opts) = @_;
+$emit_opts->{mem} = \%opts;
+}
+
+sub imm(%)
+{
+my (%opts) = @_;
+$emit_opts->{imm} = \%opts;
+}
+
+sub parse_emitblock($$)
+{
+my ($rec, $insn) = @_;
+my $insnname = $rec->{name};
+my $opcode = $insn->{opcode}{value};
+
+$emit_opts = {};
+
+my $emitblock = $rec->{blocks}{"emit"};
+if (defined $emitblock) {
+eval_with_fields($insnname, $opcode, $rec, "emit", $emitblock);
+}
+
+return $emit_opts;
+}
+
+1;
-- 
2.20.1




[Qemu-devel] [RISU RFC PATCH v2 00/14] Support for generating x86 MMX/SSE/AVX test images

2019-06-30 Thread Jan Bobek
This is a v2 of the patch series first posted in [1]. This version also
implements the VEX prefix, hence all SIMD extensions up to AVX2 are
supported. Notable exceptions are LDMXCSR (cannot constrain memory
contents yet) and all forms of VGATHER (VSIB not implemented).

Note that this is still not the final version; I am planning to
implement randomization of VSIB to test VGATHER, and improve the way
registers are randomized (as discussed in e.g. [2]).

Changes since v1:
  - risugen_common: rewrote insnv to make it clearer, added a comment
to randint_constr;
  - risugen_x86_asm: fixed a typo in rex_encode;
  - risugen_x86: use more than one opcode in write_mov_reg_imm to
optimize space usage;
  - x86.risu: added all SIMD extensnions up to AVX2.

References:
  1. https://lists.nongnu.org/archive/html/qemu-devel/2019-06/msg04123.html
  2. https://lists.nongnu.org/archive/html/qemu-devel/2019-06/msg06489.html

Jan Bobek (14):
  risugen_common: add insnv, randint_constr, rand_fill
  risugen_x86_asm: add module
  risugen_x86_emit: add module
  risugen_x86: add module
  risugen: allow all byte-aligned instructions
  x86.risu: add MMX instructions
  x86.risu: add SSE instructions
  x86.risu: add SSE2 instructions
  x86.risu: add SSE3 instructions
  x86.risu: add SSSE3 instructions
  x86.risu: add SSE4.1 and SSE4.2 instructions
  x86.risu: add AES and PCLMULQDQ instructions
  x86.risu: add AVX instructions
  x86.risu: add AVX2 instructions

 risugen |   15 +-
 risugen_common.pm   |  107 -
 risugen_x86.pm  |  498 +
 risugen_x86_asm.pm  |  252 +++
 risugen_x86_emit.pm |   91 
 x86.risu| 1026 +++
 6 files changed, 1977 insertions(+), 12 deletions(-)
 create mode 100644 risugen_x86.pm
 create mode 100644 risugen_x86_asm.pm
 create mode 100644 risugen_x86_emit.pm
 create mode 100644 x86.risu

-- 
2.20.1




Re: [Qemu-devel] [QEMU-PPC] [PATCH 1/2] ppc/spapr: Add implementation of hcall H_PURR

2019-06-30 Thread Suraj Jitindar Singh
On Fri, 2019-06-28 at 19:29 +1000, David Gibson wrote:
> On Mon, Jun 24, 2019 at 03:58:11PM +1000, Suraj Jitindar Singh wrote:
> > The hcall H_PURR is used by a guest to read the PURR (processor
> > utilisation of resources register). A guest expects that this
> > register
> > will count at a rate of timebase scaled by the number of guest
> > vcpus
> > present in the vcore. That is the per vcpu purr will count at a
> > rate of
> > timebase / # vcpus per vcore.
> > 
> > Implement a handler for the H_PURR hcall and return the purr value
> > divided by smp_threads so that the sum of the purr deltas across
> > the
> > vcpus of a vcore equals the timebase delta
> > 
> > Signed-off-by: Suraj Jitindar Singh 
> 
> Does this need something new advertised in the hypertas DT entry?

Hi David,

There doesn't seem to be a concensus on what the return value from the
H_PURR hcall should be, whether it just returns the hardware value or
does some adjusting of the value based on guest smt mode as I've
implemented in the patch below.

As such please drop this patch series.

The guest can just read the purr register directly anyway and then
interpret the values as it pleases.

Kind Regards,
Suraj

> 
> > ---
> >  hw/ppc/spapr_hcall.c | 24 
> >  1 file changed, 24 insertions(+)
> > 
> > diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
> > index aae9fd2b3e..88b3343f04 100644
> > --- a/hw/ppc/spapr_hcall.c
> > +++ b/hw/ppc/spapr_hcall.c
> > @@ -1819,6 +1819,27 @@ static target_ulong h_update_dt(PowerPCCPU
> > *cpu, SpaprMachineState *spapr,
> >  return H_SUCCESS;
> >  }
> >  
> > +static target_ulong h_purr(PowerPCCPU *cpu, SpaprMachineState
> > *spapr,
> > +   target_ulong opcode, target_ulong
> > *args)
> > +{
> > +CPUPPCState *env = >env;
> > +target_ulong purr;
> > +
> > +if (kvm_enabled()) {
> > +cpu_synchronize_state(CPU(cpu));
> > +/*
> > + * Divide by smp_threads so that the sum of the purr
> > deltas across the
> > + * vcpus of a vcore equal the timebase delta.
> > + */
> > +purr = env->spr[SPR_PURR] / smp_threads;
> > +} else {
> > +purr = cpu_ppc_load_purr(env);
> > +}
> > +args[0] = purr;
> > +
> > +return H_SUCCESS;
> > +}
> > +
> >  static spapr_hcall_fn papr_hypercall_table[(MAX_HCALL_OPCODE / 4)
> > + 1];
> >  static spapr_hcall_fn kvmppc_hypercall_table[KVMPPC_HCALL_MAX -
> > KVMPPC_HCALL_BASE + 1];
> >  
> > @@ -1915,6 +1936,9 @@ static void hypercall_register_types(void)
> >  spapr_register_hypercall(H_LOGICAL_DCBF, h_logical_dcbf);
> >  spapr_register_hypercall(KVMPPC_H_LOGICAL_MEMOP,
> > h_logical_memop);
> >  
> > +/* hcall-purr */
> > +spapr_register_hypercall(H_PURR, h_purr);
> > +
> >  /* qemu/KVM-PPC specific hcalls */
> >  spapr_register_hypercall(KVMPPC_H_RTAS, h_rtas);
> >  
> 
> 



Re: [Qemu-devel] [PATCH v6 15/16] tcg/ppc: Update vector support to v2.07

2019-06-30 Thread Aleksandar Markovic
On Jun 30, 2019 5:12 PM, "Richard Henderson" 
wrote:
>
> On 6/30/19 3:37 PM, Aleksandar Markovic wrote:
> >>  bool have_isa_2_06;
> >>  bool have_isa_2_06_vsx;
> >> +bool have_isa_2_07_vsx;
> >
> > Does this flag indicate support for PowerISA 2.07 or VSX?
>
> VSX & 2.07,
>
> >> +if (hwcap2 & PPC_FEATURE2_ARCH_2_07) {
> >> +if (hwcap & PPC_FEATURE_HAS_VSX) {
> >> +have_isa_2_07_vsx = true;
> >> +}
> >> +}
>
> Like so.
>
> While it would have been possible to have one single have_isa_vsx, we
would
> then also have to check a second flag to see which revision.  Therefore I
> created these composite flags so that we only have to check one.
>

Yes, but, in this patch, for example, among other things, the support for
doubleword integer max/min vector operation is implemented. Why is the
existence of that support dependant on VSX (PPC_FEATURE_HAS_VSX)?

>
> r~


Re: [Qemu-devel] [PATCH v2 0/7] Qemu virtio pmem device

2019-06-30 Thread Pankaj Gupta



Ping.

> 
> This patch series has implementation for "virtio pmem"
>  device. "virtio pmem" is persistent memory(nvdimm) device in
>  guest which allows to bypass the guest page cache. This
>  also implements a VIRTIO based asynchronous flush mechanism.
>  Details of project idea for 'virtio pmem' flushing interface
>  is shared [2] & [3].
> 
>  Sharing Qemu device emulation in this patchset. Tested with
>  guest kernel driver [1]. This series is based on David's
>  memory device refactoring [5] work with modified version of
>  my initial virtio pmem [4] series.
> 
>  Usage:
>  ./qemu -name test -machine pc -m 8G,slots=240,maxmem=20G
>  -object memory-backend-file,id=mem1,share,mem-path=test.img,
>   size=4G,share
>  -device virtio-pmem-pci,memdev=mem1,id=nv1
> 
>  (qemu) info memory-devices
>   Memory device [virtio-pmem]: "nv1"
>   memaddr: 0x24000
>   size: 4294967296
>   memdev: /objects/mem1
> 
>  Implementation is divided into two parts:
>  New virtio pmem guest driver and qemu code changes for new
>  virtio pmem paravirtualized device. In this series we are
>  sharing Qemu device emulation.
> 
> 1. Guest virtio-pmem kernel driver
> -
>- Reads persistent memory range from paravirt device and
>  registers with 'nvdimm_bus'.
>- 'nvdimm/pmem' driver uses this information to allocate
>  persistent memory region and setup filesystem operations
>  to the allocated memory.
>- virtio pmem driver implements asynchronous flushing
>  interface to flush from guest to host.
> 
> 2. Qemu virtio-pmem device
> -
>- Creates virtio pmem device and exposes a memory range to
>  KVM guest.
>- At host side this is file backed memory which acts as
>  persistent memory.
>- Qemu side flush uses aio thread pool API's and virtio
>  for asynchronous guest multi request handling.
> 
>  Virtio-pmem security implications and suggested countermeasures:
>  ---
> 
>  In previous posting of kernel driver, there was discussion [7]
>  on possible implications of page cache side channel attacks with
>  virtio pmem. After thorough analysis of details of known side
>  channel attacks, below are the suggestions:
> 
>  - Depends entirely on how host backing image file is mapped
>into guest address space.
> 
>  - virtio-pmem device emulation, by default shared mapping is used
>to map host backing file. It is recommended to use separate
>backing file at host side for every guest. This will prevent
>any possibility of executing common code from multiple guests
>and any chance of inferring guest local data based based on
>execution time.
> 
>  - If backing file is required to be shared among multiple guests
>it is recommended to don't support host page cache eviction
>commands from the guest driver. This will avoid any possibility
>of inferring guest local data or host data from another guest.
> 
>  - Proposed device specification [6] for virtio-pmem device with
>details of possible security implications and suggested
>countermeasures for device emulation.
> 
> Changes from PATCH v1:
>  - Change proposed version from qemu 4.0 to 4.1 - Eric
>  - Remove virtio queue_add from unrealize function - Cornelia
> 
> [1] https://lkml.org/lkml/2019/6/12/624
> [2] https://www.spinics.net/lists/kvm/msg149761.html
> [3] https://www.spinics.net/lists/kvm/msg153095.html
> [4] https://marc.info/?l=linux-kernel=153572228719237=2
> [5] https://marc.info/?l=qemu-devel=153555721901824=2
> [6] https://lists.oasis-open.org/archives/virtio-dev/201903/msg00083.html
> [7] https://lkml.org/lkml/2019/1/9/1191
> 
>  Pankaj Gupta (3):
>   virtio-pmem: add virtio device
>   virtio-pmem: sync linux headers
>   virtio-pci: proxy for virtio-pmem
> 
>  David Hildenbrand (4):
>   virtio-pci: Allow to specify additional interfaces for the base type
>   hmp: Handle virtio-pmem when printing memory device infos
>   numa: Handle virtio-pmem in NUMA stats
>   pc: Support for virtio-pmem-pci
> 
>  hmp.c|   27 ++-
>  hw/i386/Kconfig  |1
>  hw/i386/pc.c |   72 ++
>  hw/virtio/Kconfig|   10 +
>  hw/virtio/Makefile.objs  |2
>  hw/virtio/virtio-pci.c   |1
>  hw/virtio/virtio-pci.h   |1
>  hw/virtio/virtio-pmem-pci.c  |  131 ++
>  hw/virtio/virtio-pmem-pci.h  |   34 
>  hw/virtio/virtio-pmem.c  |  189
>  +++
>  include/hw/pci/pci.h |1
>  include/hw/virtio/virtio-pmem.h  |   49 +++
>  include/standard-headers/linux/virtio_ids.h  |1
>  include/standard-headers/linux/virtio_pmem.h |   35 +
>  numa.c 

Re: [Qemu-devel] [RFC 1/1] hw/pvrdma: Add live migration support

2019-06-30 Thread Sukrit Bhatnagar
On Sun, 30 Jun 2019 at 13:43, Yuval Shaia  wrote:
>
> On Sat, Jun 29, 2019 at 06:15:21PM +0530, Sukrit Bhatnagar wrote:
> > On Fri, 28 Jun 2019 at 16:56, Dr. David Alan Gilbert
> >  wrote:
> > >
> > > * Yuval Shaia (yuval.sh...@oracle.com) wrote:
> > > > On Fri, Jun 21, 2019 at 08:15:41PM +0530, Sukrit Bhatnagar wrote:
> > > > > Define and register SaveVMHandlers pvrdma_save and
> > > > > pvrdma_load for saving and loading the device state,
> > > > > which currently includes only the dma, command slot
> > > > > and response slot addresses.
> > > > >
> > > > > Remap the DSR, command slot and response slot upon
> > > > > loading the addresses in the pvrdma_load function.
> > > > >
> > > > > Cc: Marcel Apfelbaum 
> > > > > Cc: Yuval Shaia 
> > > > > Signed-off-by: Sukrit Bhatnagar 
> > > > > ---
> > > > >  hw/rdma/vmw/pvrdma_main.c | 56 
> > > > > +++
> > > > >  1 file changed, 56 insertions(+)
> > > > >
> > > > > diff --git a/hw/rdma/vmw/pvrdma_main.c b/hw/rdma/vmw/pvrdma_main.c
> > > > > index adcf79cd63..cd8573173c 100644
> > > > > --- a/hw/rdma/vmw/pvrdma_main.c
> > > > > +++ b/hw/rdma/vmw/pvrdma_main.c
> > > > > @@ -28,6 +28,7 @@
> > > > >  #include "sysemu/sysemu.h"
> > > > >  #include "monitor/monitor.h"
> > > > >  #include "hw/rdma/rdma.h"
> > > > > +#include "migration/register.h"
> > > > >
> > > > >  #include "../rdma_rm.h"
> > > > >  #include "../rdma_backend.h"
> > > > > @@ -592,9 +593,62 @@ static void pvrdma_shutdown_notifier(Notifier 
> > > > > *n, void *opaque)
> > > > >  pvrdma_fini(pci_dev);
> > > > >  }
> > > > >
> > > > > +static void pvrdma_save(QEMUFile *f, void *opaque)
> > > > > +{
> > > > > +PVRDMADev *dev = PVRDMA_DEV(opaque);
> > > > > +
> > > > > +qemu_put_be64(f, dev->dsr_info.dma);
> > > > > +qemu_put_be64(f, dev->dsr_info.dsr->cmd_slot_dma);
> > > > > +qemu_put_be64(f, dev->dsr_info.dsr->resp_slot_dma);
> > > > > +}
> > > > > +
> > > > > +static int pvrdma_load(QEMUFile *f, void *opaque, int version_id)
> > > > > +{
> > > > > +PVRDMADev *dev = PVRDMA_DEV(opaque);
> > > > > +PCIDevice *pci_dev = PCI_DEVICE(dev);
> > > > > +
> > > > > +// Remap DSR
> > > > > +dev->dsr_info.dma = qemu_get_be64(f);
> > > > > +dev->dsr_info.dsr = rdma_pci_dma_map(pci_dev, dev->dsr_info.dma,
> > > > > +sizeof(struct 
> > > > > pvrdma_device_shared_region));
> > > > > +if (!dev->dsr_info.dsr) {
> > > > > +rdma_error_report("Failed to map to DSR");
> > > > > +return -1;
> > > > > +}
> > > > > +qemu_log("pvrdma_load: successfully remapped to DSR\n");
> > > > > +
> > > > > +// Remap cmd slot
> > > > > +dev->dsr_info.dsr->cmd_slot_dma = qemu_get_be64(f);
> > > > > +dev->dsr_info.req = rdma_pci_dma_map(pci_dev, 
> > > > > dev->dsr_info.dsr->cmd_slot_dma,
> > > > > + sizeof(union pvrdma_cmd_req));
> > > > > +if (!dev->dsr_info.req) {
> > > >
> > > > So this is where you hit the error, right?
> > > > All looks good to me, i wonder why the first pci_dma_map works fine but
> > > > second fails where the global BounceBuffer is marked as used.
> > > >
> > > > Anyone?
> > >
> > > I've got a few guesses:
> > >   a) My reading of address_space_map is that it gives a bounce buffer
> > > pointer and then it has to be freed; so if it's going wrong and using a
> > > bounce buffer, then the 1st call would work and only the 2nd would fail.
> >
> > In the scenario without any migration, the device is init and load_dsr()
> > is called when the guest writes to DSR in BAR1 of pvrdma.
> >
> > Inside the load_dsr(), there are similar calls to rdma_pci_dma_map().
> >
> > The difference is that when the address_space_map() is called there,
> > !memory_access_is_direct() condition is FALSE.
> > So, there is no use for BounceBuffer.
> >
> >
> > In the migration scenario, when the device at dest calls load and
> > subsequently rdma_pci_dma_map(), the !memory_access_is_direct()
> > condition is TRUE.
> > So, the first rdma_pci_dma_map() will set BounceBuffer from FALSE to
> > TRUE and succeed. But, the subsequent calls will fail at atomic_xchg().
> >
> > This BounceBuffer is only freed when address_space_unmap() is called.
> >
> >
> > I am guessing that when the address is translated to one in FlatView,
> > the MemoryRegion returned at dest is causing the issue.
> > To be honest, at this point I am not sure how FlatView translations works.
> >
> > I tried adding qemu_log to memory_access_is_direct(), but I guess it is
> > called too many times, so the vm stalls before it even starts.
> >
> > >   b) Perhaps the dma address read from the stream is bad, and isn't
> > > pointing into RAM properly - and that's why you're getting a bounce
> > > buffer.
> >
> > I have logged the addresses saved in pvrdma_save(), and the ones
> > loaded in pvrdma_load(). They are same. So, there is no problem in the
> > stream itself, I suppose.
> >
> > >   c) Do you 

Re: [Qemu-devel] [PATCH v5 4/8] numa: move numa global variable numa_info into MachineState

2019-06-30 Thread Tao Xu

On 6/28/2019 7:20 PM, Igor Mammedov wrote:

On Fri, 14 Jun 2019 23:56:22 +0800
Tao Xu  wrote:


Move existing numa global numa_info (renamed as "nodes") into NumaState.

Reviewed-by: Liu Jingqi 
Suggested-by: Igor Mammedov 
Suggested-by: Eduardo Habkost 
Signed-off-by: Tao Xu 
---

Changes in v5 -> v4:
 - Directly use ms->numa_state->nodes and not dereferencing
 ms->numa_state in the first place when ms->numa_state is possible
 NULL (Igor)


the sa,e like in previous patch,
use ms->numa_state->nodes directly whenever possible without using
intermediate local variable


---
  exec.c   |  2 +-
  hw/acpi/aml-build.c  |  6 --
  hw/arm/boot.c|  2 +-
  hw/arm/virt-acpi-build.c |  7 ---
  hw/arm/virt.c|  1 +
  hw/i386/pc.c |  4 ++--
  hw/ppc/spapr.c   |  4 +++-
  hw/ppc/spapr_pci.c   |  1 +
  include/sysemu/numa.h|  3 +++
  numa.c   | 15 +--
  10 files changed, 29 insertions(+), 16 deletions(-)

diff --git a/exec.c b/exec.c
index c7eb4af42d..0e30926588 100644
--- a/exec.c
+++ b/exec.c
@@ -1763,7 +1763,7 @@ long qemu_minrampagesize(void)
  if (hpsize > mainrampagesize &&
  (ms->numa_state == NULL ||
   ms->numa_state->num_nodes == 0 ||
- numa_info[0].node_memdev == NULL)) {
+ ms->numa_state->nodes[0].node_memdev == NULL)) {
  static bool warned;
  if (!warned) {
  error_report("Huge page support disabled (n/a for main memory).");
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index 63c1cae8c9..26ccc1a3e2 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -1737,8 +1737,10 @@ void build_slit(GArray *table_data, BIOSLinker *linker, 
MachineState *ms)
  build_append_int_noprefix(table_data, nb_numa_nodes, 8);
  for (i = 0; i < nb_numa_nodes; i++) {
  for (j = 0; j < nb_numa_nodes; j++) {
-assert(numa_info[i].distance[j]);
-build_append_int_noprefix(table_data, numa_info[i].distance[j], 1);
+assert(ms->numa_state->nodes[i].distance[j]);
+build_append_int_noprefix(table_data,
+  ms->numa_state->nodes[i].distance[j],
+  1);
  }
  }
  
diff --git a/hw/arm/boot.c b/hw/arm/boot.c

index 2af881e0f4..0c1572d118 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -600,7 +600,7 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info 
*binfo,
  if (ms->numa_state != NULL && ms->numa_state->num_nodes > 0) {
  mem_base = binfo->loader_start;
  for (i = 0; i < ms->numa_state->num_nodes; i++) {
-mem_len = numa_info[i].node_mem;
+mem_len = ms->numa_state->nodes[i].node_mem;
  rc = fdt_add_memory_node(fdt, acells, mem_base,
   scells, mem_len, i);
  if (rc < 0) {
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 9d2edd8023..422bbed2d3 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -536,11 +536,12 @@ build_srat(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
  
  mem_base = vms->memmap[VIRT_MEM].base;

  for (i = 0; i < nb_numa_nodes; ++i) {
-if (numa_info[i].node_mem > 0) {
+if (ms->numa_state->nodes[i].node_mem > 0) {
  numamem = acpi_data_push(table_data, sizeof(*numamem));
-build_srat_memory(numamem, mem_base, numa_info[i].node_mem, i,
+build_srat_memory(numamem, mem_base,
+  ms->numa_state->nodes[i].node_mem, i,
MEM_AFFINITY_ENABLED);
-mem_base += numa_info[i].node_mem;
+mem_base += ms->numa_state->nodes[i].node_mem;
  }
  }
  
diff --git a/hw/arm/virt.c b/hw/arm/virt.c

index d147cceab6..d3904d74dc 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -233,6 +233,7 @@ static void create_fdt(VirtMachineState *vms)
  int size = nb_numa_nodes * nb_numa_nodes * 3 * sizeof(uint32_t);
  uint32_t *matrix = g_malloc0(size);
  int idx, i, j;
+NodeInfo *numa_info = ms->numa_state->nodes;

  for (i = 0; i < nb_numa_nodes; i++) {
  for (j = 0; j < nb_numa_nodes; j++) {
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 5bab78e137..4cc84c5050 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1041,7 +1041,7 @@ static FWCfgState *bochs_bios_init(AddressSpace *as, 
PCMachineState *pcms)
  }
  for (i = 0; i < nb_numa_nodes; i++) {
  numa_fw_cfg[pcms->apic_id_limit + 1 + i] =
-cpu_to_le64(numa_info[i].node_mem);
+cpu_to_le64(ms->numa_state->nodes[i].node_mem);
  }
  fw_cfg_add_bytes(fw_cfg, FW_CFG_NUMA, numa_fw_cfg,
   (1 + pcms->apic_id_limit + nb_numa_nodes) *
@@ -1683,7 +1683,7 @@ void pc_guest_info_init(PCMachineState *pcms)
  pcms->node_mem = 

Re: [Qemu-devel] [PATCH v5 2/8] numa: move numa global variable nb_numa_nodes into MachineState

2019-06-30 Thread Tao Xu

On 6/28/2019 7:02 PM, Igor Mammedov wrote:

On Fri, 14 Jun 2019 23:56:20 +0800
Tao Xu  wrote:


Add struct NumaState in MachineState and move existing numa global
nb_numa_nodes(renamed as "num_nodes") into NumaState. And add variable
numa_support into MachineClass to decide which submachines support NUMA.

Reviewed-by: Liu Jingqi 

you are not supposed to keep Reviewed-bys on respin
unless changes that were made are trivial.
(
PS:
  it applies to the whole series
)


Suggested-by: Igor Mammedov 
Suggested-by: Eduardo Habkost 
Signed-off-by: Tao Xu 


In many places you are following pattern:
   int nb_numa_nodes = ms->numa_state->num_nodes;

even if local variable is only used once or twice within the function.
Pls use ms->numa_state->num_nodes directly instead if it doesn't hurt
readability.


Thank you for your comments. I will improve it.


more comments below...

---

Changes in v5 -> v4:
 - drop the helper machine_num_numa_nodes() and use
 machine->numa_state->num_nodes directly (Igor)
 - remove the unnecessary header include (Igor)
---
  exec.c  |  5 ++-
  hw/acpi/aml-build.c |  3 +-
  hw/arm/boot.c   |  4 +-
  hw/arm/virt-acpi-build.c|  8 +++-
  hw/arm/virt.c   |  5 ++-
  hw/core/machine.c   | 14 +--
  hw/i386/acpi-build.c|  2 +-
  hw/i386/pc.c|  7 +++-
  hw/mem/pc-dimm.c|  2 +
  hw/pci-bridge/pci_expander_bridge.c |  2 +
  hw/ppc/spapr.c  | 19 +++---
  hw/ppc/spapr_pci.c  |  1 +
  include/hw/acpi/aml-build.h |  2 +-
  include/hw/boards.h |  2 +
  include/sysemu/numa.h   | 13 +--
  monitor.c   | 11 +-
  numa.c  | 59 ++---
  17 files changed, 112 insertions(+), 47 deletions(-)

diff --git a/exec.c b/exec.c
index 4e734770c2..c7eb4af42d 100644
--- a/exec.c
+++ b/exec.c
@@ -1733,6 +1733,7 @@ long qemu_minrampagesize(void)
  long hpsize = LONG_MAX;
  long mainrampagesize;
  Object *memdev_root;
+MachineState *ms = MACHINE(qdev_get_machine());
  
  mainrampagesize = qemu_mempath_getpagesize(mem_path);
  
@@ -1760,7 +1761,9 @@ long qemu_minrampagesize(void)

   * so if its page size is smaller we have got to report that size instead.
   */
  if (hpsize > mainrampagesize &&
-(nb_numa_nodes == 0 || numa_info[0].node_memdev == NULL)) {
+(ms->numa_state == NULL ||
+ ms->numa_state->num_nodes == 0 ||
+ numa_info[0].node_memdev == NULL)) {
  static bool warned;
  if (!warned) {
  error_report("Huge page support disabled (n/a for main memory).");
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index 555c24f21d..63c1cae8c9 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -1726,10 +1726,11 @@ void build_srat_memory(AcpiSratMemoryAffinity *numamem, 
uint64_t base,
   * ACPI spec 5.2.17 System Locality Distance Information Table
   * (Revision 2.0 or later)
   */
-void build_slit(GArray *table_data, BIOSLinker *linker)
+void build_slit(GArray *table_data, BIOSLinker *linker, MachineState *ms)
  {
  int slit_start, i, j;
  slit_start = table_data->len;
+int nb_numa_nodes = ms->numa_state->num_nodes;
  
  acpi_data_push(table_data, sizeof(AcpiTableHeader));
  
diff --git a/hw/arm/boot.c b/hw/arm/boot.c

index 30acdbe824..2af881e0f4 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -597,9 +597,9 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info 
*binfo,
  }
  g_strfreev(node_path);
  
-if (nb_numa_nodes > 0) {

+if (ms->numa_state != NULL && ms->numa_state->num_nodes > 0) {
  mem_base = binfo->loader_start;
-for (i = 0; i < nb_numa_nodes; i++) {
+for (i = 0; i < ms->numa_state->num_nodes; i++) {
  mem_len = numa_info[i].node_mem;
  rc = fdt_add_memory_node(fdt, acells, mem_base,
   scells, mem_len, i);
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 4a64f9985c..9a22ce679c 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -517,7 +517,9 @@ build_srat(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
  int i, srat_start;
  uint64_t mem_base;
  MachineClass *mc = MACHINE_GET_CLASS(vms);
-const CPUArchIdList *cpu_list = mc->possible_cpu_arch_ids(MACHINE(vms));
+MachineState *ms = MACHINE(vms);
+const CPUArchIdList *cpu_list = mc->possible_cpu_arch_ids(ms);
+int nb_numa_nodes = ms->numa_state->num_nodes;
  
  srat_start = table_data->len;

  srat = acpi_data_push(table_data, sizeof(*srat));
@@ -759,6 +761,8 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables 
*tables)
  GArray *table_offsets;
  unsigned dsdt, xsdt;
  GArray 

Re: [Qemu-devel] [PATCH v5 6/8] hmat acpi: Build Memory Subsystem Address Range Structure(s) in ACPI HMAT

2019-06-30 Thread Tao Xu

On 6/27/2019 11:56 PM, Jonathan Cameron wrote:

On Fri, 14 Jun 2019 23:56:24 +0800
Tao Xu  wrote:


From: Liu Jingqi 

HMAT is defined in ACPI 6.2: 5.2.27 Heterogeneous Memory Attribute Table (HMAT).
The specification references below link:
http://www.uefi.org/sites/default/files/resources/ACPI_6_2.pdf

It describes the memory attributes, such as memory side cache
attributes and bandwidth and latency details, related to the
System Physical Address (SPA) Memory Ranges. The software is
expected to use this information as hint for optimization.

This structure describes the System Physical Address(SPA) range
occupied by memory subsystem and its associativity with processor
proximity domain as well as hint for memory usage.

Signed-off-by: Liu Jingqi 
Signed-off-by: Tao Xu 


Hi Tao,

Apologies if I missed an earlier discussion on this...

It's probably not letting an secrets out to say that there are very few
real hardware systems out there using the 6.2 version of HMAT.

Does it make sense to implement it rather than the somewhat tidied
up version in ACPI 6.3?

I would go so far as to say that one of the pushes behind making those
changes was that it shouldn't have much impact as no one was shipping
a firmware using the 6.2 version.  So any chance we can avoid
qemu effectively doing so, or at least defaulting to doing so?

I'm entirely in favor of the patch set in general btw as it's much
more useful than having to override with a hand crafted table, when
wanting to test unusual topologies.

Thanks,

Jonathan

Thanks for your suggestion. After discussion, we decide to use ACPI 6.3 
in next version.






Re: [Qemu-devel] [PATCH 1/2] tests/acceptance: Add test of NeXTcube framebuffer using OCR

2019-06-30 Thread Philippe Mathieu-Daudé
On 6/30/19 9:08 PM, Thomas Huth wrote:
> On 29/06/2019 17.00, Philippe Mathieu-Daudé wrote:
>> Add a test of the NeXTcube framebuffer using the Tesseract OCR
>> engine on a screenshot of the framebuffer device.
> 
> Wow, that's a funny idea, I like it!
> 
>> The test is very quick:
>>
>>   $ avocado --show=app,ocr run tests/acceptance/machine_m68k_nextcube.py
>>   JOB ID : f7d3c27976047036dc568183baf64c04863d9985
>>   JOB LOG: ~/avocado/job-results/job-2019-06-29T16.18-f7d3c27/job.log
>>   (1/1) 
>> tests/acceptance/machine_m68k_nextcube.py:NextCubeMachine.test_bootrom_framebuffer:
>>  |ocr:
>>   ue r pun Honl'flx ; 5‘ 55‘
>>   avg nca 25 MHZ, memary jag m
>>   Backplane slat «a
>>   Ethernet address a a r a r3 2
>>   Memgry sackets aea canflqured far 16MB Darlly page made stMs but have 16MB 
>> page made stMs )nstalled
>>   Memgry sackets a and 1 canflqured far 16MB Darlly page made stMs but have 
>> 16MB page made stMs )nstalled>   [...]
>>   Yestlnq the rpu, 5::
>>   system test raneg Errar egge 51
>>   Egg: cammand
>>   Default pggc devlce nut fauna
>>   NEXY>I
> 
> Hmm, the quality of the text is rather bad...
> 
>> Documentation on how to install tesseract:
>>   https://github.com/tesseract-ocr/tesseract/wiki#installation
> 
> ... according to that documentation, you're also supposed to install a
> language pack ... have you tried whether it gets better with
> tesseract-ocr-eng ?

Oops, I should had RTFM...

$ docker run -it -v /tmp:/tmp ubuntu:18.10
root@ed15d4d1ff4b:/# apt update && apt install -y tesseract-ocr-eng
[...]
root@ed15d4d1ff4b:/# tesseract /tmp/screenshot.pbm stdout
Warning. Invalid resolution 0 dpi. Using 70 instead.
Estimating resolution as 109
CPU HCesasa 25 Wz, memory 168 nS
Backplane slot #0

Ethernet address: 0:0:f:0:13:2

Nemory sockets 8-3 configured for 16MB parity page mode SIMMs but have
16MB page mode SIMMs installed
Nemory sockets @ and 1 configured for 16MB parity page mode SINMs but
have 16MB page mode SIMMs installed
Nemory sockets 4-7 configured for 16MB parity page mode SIMMs but have
16MB page mode SIMMs installed
Nemory sockets 2 and 3 configured for 16MB parity page mode SIMMs but
have 16MB page mode SIMMs installed
Nemory sockets 8-11 configured for 16MB parity page mode SIMMs but have
16"B page mode SIMMs installed
Nemory sockets 4 and 5 configured for 16MB parity page mode SIMMs but
have 16MB page mode SIMs installed
Nemory sockets 42-18 configured for 16MB parity page mode SIMMs but have
16MB page mode SIMNs installed
Nemory sockets 6 and 7 configured for 16MB parity page mode SIMMs but
have 16MB page mode SIMMs installed
Nemory size 64nB

Testing the FPU, SCC

System test failed. Error code 51

Boot command
Default boat device not found
Next>

Way better!



Re: [Qemu-devel] [PATCH 4/4] hw/i386: Introduce the microvm machine type

2019-06-30 Thread Michael S. Tsirkin
On Sat, Jun 29, 2019 at 12:17:22AM +0200, Paolo Bonzini wrote:
> On 28/06/19 16:06, Michael S. Tsirkin wrote:
> >> +assert(kvm_irqchip_in_kernel());
> > Hmm - irqchip in kernel actually increases the attack surface,
> > does it not? Or at least, the severity of the attacks.
> 
> Yeah, we should at least support split irqchip.  But, irqchip completely
> in userspace is slow when it is not broken, and it does not support
> APICv.  So it's not really feasible.
> 
> Paolo

Right, I meant split.

-- 
MST



Re: [Qemu-devel] [PATCH 2/4] hw/virtio: Factorize virtio-mmio headers

2019-06-30 Thread Michael S. Tsirkin
On Fri, Jun 28, 2019 at 10:50:47PM +0200, Sergio Lopez wrote:
> 
> Michael S. Tsirkin  writes:
> 
> > On Fri, Jun 28, 2019 at 01:53:47PM +0200, Sergio Lopez wrote:
> >> Put QOM and main struct definition in a separate header file, so it
> >> can be accesed from other components.
> >> 
> >> This is needed for the microvm machine type implementation.
> >> 
> >> Signed-off-by: Sergio Lopez 
> >
> > If you are going to productise virtio-mmio, then 1.0 support is a must.
> > I am not sure we want a new machine with 0.X mmio devices.
> > Especially considering that virtio-mmio does not have support for
> > transitional devices.
> 
> What are the practical implications of that?

On the plus side, this means we don't need to maintain a bunch of hacks
for old guests with quirky drivers.

On the minus side, this requires Linux guests 3.19 and up.




> >> ---
> >>  hw/virtio/virtio-mmio.c | 35 +---
> >>  hw/virtio/virtio-mmio.h | 60 +
> >>  2 files changed, 61 insertions(+), 34 deletions(-)
> >>  create mode 100644 hw/virtio/virtio-mmio.h
> >> 
> >> diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
> >> index 97b7f35496..87c7fe4d8d 100644
> >> --- a/hw/virtio/virtio-mmio.c
> >> +++ b/hw/virtio/virtio-mmio.c
> >> @@ -26,44 +26,11 @@
> >>  #include "qemu/host-utils.h"
> >>  #include "qemu/module.h"
> >>  #include "sysemu/kvm.h"
> >> -#include "hw/virtio/virtio-bus.h"
> >> +#include "virtio-mmio.h"
> >>  #include "qemu/error-report.h"
> >>  #include "qemu/log.h"
> >>  #include "trace.h"
> >>  
> >> -/* QOM macros */
> >> -/* virtio-mmio-bus */
> >> -#define TYPE_VIRTIO_MMIO_BUS "virtio-mmio-bus"
> >> -#define VIRTIO_MMIO_BUS(obj) \
> >> -OBJECT_CHECK(VirtioBusState, (obj), TYPE_VIRTIO_MMIO_BUS)
> >> -#define VIRTIO_MMIO_BUS_GET_CLASS(obj) \
> >> -OBJECT_GET_CLASS(VirtioBusClass, (obj), TYPE_VIRTIO_MMIO_BUS)
> >> -#define VIRTIO_MMIO_BUS_CLASS(klass) \
> >> -OBJECT_CLASS_CHECK(VirtioBusClass, (klass), TYPE_VIRTIO_MMIO_BUS)
> >> -
> >> -/* virtio-mmio */
> >> -#define TYPE_VIRTIO_MMIO "virtio-mmio"
> >> -#define VIRTIO_MMIO(obj) \
> >> -OBJECT_CHECK(VirtIOMMIOProxy, (obj), TYPE_VIRTIO_MMIO)
> >> -
> >> -#define VIRT_MAGIC 0x74726976 /* 'virt' */
> >> -#define VIRT_VERSION 1
> >> -#define VIRT_VENDOR 0x554D4551 /* 'QEMU' */
> >> -
> >> -typedef struct {
> >> -/* Generic */
> >> -SysBusDevice parent_obj;
> >> -MemoryRegion iomem;
> >> -qemu_irq irq;
> >> -/* Guest accessible state needing migration and reset */
> >> -uint32_t host_features_sel;
> >> -uint32_t guest_features_sel;
> >> -uint32_t guest_page_shift;
> >> -/* virtio-bus */
> >> -VirtioBusState bus;
> >> -bool format_transport_address;
> >> -} VirtIOMMIOProxy;
> >> -
> >>  static bool virtio_mmio_ioeventfd_enabled(DeviceState *d)
> >>  {
> >>  return kvm_eventfds_enabled();
> >> diff --git a/hw/virtio/virtio-mmio.h b/hw/virtio/virtio-mmio.h
> >> new file mode 100644
> >> index 00..2f3973f8c7
> >> --- /dev/null
> >> +++ b/hw/virtio/virtio-mmio.h
> >> @@ -0,0 +1,60 @@
> >> +/*
> >> + * Virtio MMIO bindings
> >> + *
> >> + * Copyright (c) 2011 Linaro Limited
> >> + *
> >> + * Author:
> >> + *  Peter Maydell 
> >> + *
> >> + * This program is free software; you can redistribute it and/or modify
> >> + * it under the terms of the GNU General Public License; either version 2
> >> + * of the License, or (at your option) any later version.
> >> + *
> >> + * This program is distributed in the hope that it will be useful,
> >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> >> + * GNU General Public License for more details.
> >> + *
> >> + * You should have received a copy of the GNU General Public License along
> >> + * with this program; if not, see .
> >> + */
> >> +
> >> +#ifndef QEMU_VIRTIO_MMIO_H
> >> +#define QEMU_VIRTIO_MMIO_H
> >> +
> >> +#include "hw/virtio/virtio-bus.h"
> >> +
> >> +/* QOM macros */
> >> +/* virtio-mmio-bus */
> >> +#define TYPE_VIRTIO_MMIO_BUS "virtio-mmio-bus"
> >> +#define VIRTIO_MMIO_BUS(obj) \
> >> +OBJECT_CHECK(VirtioBusState, (obj), TYPE_VIRTIO_MMIO_BUS)
> >> +#define VIRTIO_MMIO_BUS_GET_CLASS(obj) \
> >> +OBJECT_GET_CLASS(VirtioBusClass, (obj), TYPE_VIRTIO_MMIO_BUS)
> >> +#define VIRTIO_MMIO_BUS_CLASS(klass) \
> >> +OBJECT_CLASS_CHECK(VirtioBusClass, (klass), TYPE_VIRTIO_MMIO_BUS)
> >> +
> >> +/* virtio-mmio */
> >> +#define TYPE_VIRTIO_MMIO "virtio-mmio"
> >> +#define VIRTIO_MMIO(obj) \
> >> +OBJECT_CHECK(VirtIOMMIOProxy, (obj), TYPE_VIRTIO_MMIO)
> >> +
> >> +#define VIRT_MAGIC 0x74726976 /* 'virt' */
> >> +#define VIRT_VERSION 1
> >> +#define VIRT_VENDOR 0x554D4551 /* 'QEMU' */
> >> +
> >> +typedef struct {
> >> +/* Generic */
> >> +SysBusDevice parent_obj;
> >> +MemoryRegion iomem;
> >> +qemu_irq irq;
> >> + 

Re: [Qemu-devel] [PATCH] pc: Move compat_apic_id_mode variable to PCMachineClass

2019-06-30 Thread Michael S. Tsirkin
On Fri, Jun 28, 2019 at 05:02:27PM -0300, Eduardo Habkost wrote:
> Replace the static variable with a PCMachineClass field.  This
> will help us eventually get rid of the pc_compat_*() init
> functions.
> 
> Signed-off-by: Eduardo Habkost 

Reviewed-by: Michael S. Tsirkin 

Pls feel free to merge.

> ---
>  include/hw/i386/pc.h |  3 +++
>  hw/i386/pc.c | 22 +-
>  hw/i386/pc_piix.c|  3 ++-
>  3 files changed, 14 insertions(+), 14 deletions(-)
> 
> diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
> index c54cc54a47..853502f277 100644
> --- a/include/hw/i386/pc.h
> +++ b/include/hw/i386/pc.h
> @@ -134,6 +134,9 @@ typedef struct PCMachineClass {
>  
>  /* use PVH to load kernels that support this feature */
>  bool pvh_enabled;
> +
> +/* Enables contiguous-apic-ID mode */
> +bool compat_apic_id_mode;
>  } PCMachineClass;
>  
>  #define TYPE_PC_MACHINE "generic-pc-machine"
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index e96360b47a..3983621f1c 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -913,14 +913,6 @@ bool e820_get_entry(int idx, uint32_t type, uint64_t 
> *address, uint64_t *length)
>  return false;
>  }
>  
> -/* Enables contiguous-apic-ID mode, for compatibility */
> -static bool compat_apic_id_mode;
> -
> -void enable_compat_apic_id_mode(void)
> -{
> -compat_apic_id_mode = true;
> -}
> -
>  /* Calculates initial APIC ID for a specific CPU index
>   *
>   * Currently we need to be able to calculate the APIC ID from the CPU index
> @@ -928,13 +920,15 @@ void enable_compat_apic_id_mode(void)
>   * no concept of "CPU index", and the NUMA tables on fw_cfg need the APIC ID 
> of
>   * all CPUs up to max_cpus.
>   */
> -static uint32_t x86_cpu_apic_id_from_index(unsigned int cpu_index)
> +static uint32_t x86_cpu_apic_id_from_index(PCMachineState *pcms,
> +   unsigned int cpu_index)
>  {
> +PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
>  uint32_t correct_id;
>  static bool warned;
>  
>  correct_id = x86_apicid_from_cpu_idx(smp_cores, smp_threads, cpu_index);
> -if (compat_apic_id_mode) {
> +if (pcmc->compat_apic_id_mode) {
>  if (cpu_index != correct_id && !warned && !qtest_enabled()) {
>  error_report("APIC IDs set in compatibility mode, "
>   "CPU topology won't match the configuration");
> @@ -1533,7 +1527,8 @@ static void pc_new_cpu(const char *typename, int64_t 
> apic_id, Error **errp)
>  void pc_hot_add_cpu(const int64_t id, Error **errp)
>  {
>  MachineState *ms = MACHINE(qdev_get_machine());
> -int64_t apic_id = x86_cpu_apic_id_from_index(id);
> +PCMachineState *pcms = PC_MACHINE(ms);
> +int64_t apic_id = x86_cpu_apic_id_from_index(pcms, id);
>  Error *local_err = NULL;
>  
>  if (id < 0) {
> @@ -1569,7 +1564,7 @@ void pc_cpus_init(PCMachineState *pcms)
>   *
>   * This is used for FW_CFG_MAX_CPUS. See comments on bochs_bios_init().
>   */
> -pcms->apic_id_limit = x86_cpu_apic_id_from_index(max_cpus - 1) + 1;
> +pcms->apic_id_limit = x86_cpu_apic_id_from_index(pcms, max_cpus - 1) + 1;
>  possible_cpus = mc->possible_cpu_arch_ids(ms);
>  for (i = 0; i < smp_cpus; i++) {
>  pc_new_cpu(possible_cpus->cpus[i].type, 
> possible_cpus->cpus[i].arch_id,
> @@ -2660,6 +2655,7 @@ static int64_t pc_get_default_cpu_node_id(const 
> MachineState *ms, int idx)
>  
>  static const CPUArchIdList *pc_possible_cpu_arch_ids(MachineState *ms)
>  {
> +PCMachineState *pcms = PC_MACHINE(ms);
>  int i;
>  
>  if (ms->possible_cpus) {
> @@ -2679,7 +2675,7 @@ static const CPUArchIdList 
> *pc_possible_cpu_arch_ids(MachineState *ms)
>  
>  ms->possible_cpus->cpus[i].type = ms->cpu_type;
>  ms->possible_cpus->cpus[i].vcpus_count = 1;
> -ms->possible_cpus->cpus[i].arch_id = x86_cpu_apic_id_from_index(i);
> +ms->possible_cpus->cpus[i].arch_id = 
> x86_cpu_apic_id_from_index(pcms, i);
>  x86_topo_ids_from_apicid(ms->possible_cpus->cpus[i].arch_id,
>   smp_cores, smp_threads, );
>  ms->possible_cpus->cpus[i].props.has_socket_id = true;
> diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
> index c07c4a5b38..f29de58636 100644
> --- a/hw/i386/pc_piix.c
> +++ b/hw/i386/pc_piix.c
> @@ -358,7 +358,6 @@ static void pc_compat_1_4_fn(MachineState *machine)
>  static void pc_compat_1_3(MachineState *machine)
>  {
>  pc_compat_1_4_fn(machine);
> -enable_compat_apic_id_mode();
>  }
>  
>  /* PC compat function for pc-0.14 to pc-1.2 */
> @@ -708,6 +707,7 @@ DEFINE_I440FX_MACHINE(v1_4, "pc-i440fx-1.4", 
> pc_compat_1_4_fn,
>  
>  static void pc_i440fx_1_3_machine_options(MachineClass *m)
>  {
> +PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
>  static GlobalProperty compat[] = {
>  PC_CPU_MODEL_IDS("1.3.0")
>  { "usb-tablet", "usb_version", "1" },
> @@ -718,6 +718,7 @@ static void 

[Qemu-devel] [PATCH 06/10] ppc/xive: Provide escalation support

2019-06-30 Thread Cédric Le Goater
If the XIVE presenter can not find the NVT dispatched on any of the HW
threads, it can not deliver the interrupt. XIVE offers a mechanism to
handle such scenarios and inform the hypervisor that an action should
be taken.

The first action is to keep track of the pending priority of the
missed event. It is recorded in the IPB field of the NVT for a later
resend if backlog is activated ('b' bit) on the END.

An END can also escalate if configured: 'e' bit and setting of the EAS
in word 4 & 5 to let the HW look for the escalation END on which to
trigger a new event. Escalation has its own options to program
different behaviors :

 - unconditional escalation ('u' bit) with which the ESe PQ bits are
   not used.
 - silent/gather escalation ('s' bit), the sequence skips the
   notification process and jumps directly to the escalation.

KVM uses a combination of these. The first level END is configured to
enqueue, unconditionally notify, backlog and escalate and points to an
escalation END which is configured to escalate silently.

Signed-off-by: Cédric Le Goater 
---
 include/hw/ppc/xive_regs.h |   4 ++
 hw/intc/xive.c | 130 +++--
 2 files changed, 115 insertions(+), 19 deletions(-)

diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h
index 1a8c5b5e64f0..69af326ebf2c 100644
--- a/include/hw/ppc/xive_regs.h
+++ b/include/hw/ppc/xive_regs.h
@@ -207,6 +207,10 @@ typedef struct XiveEND {
 #define xive_end_is_notify(end)   (be32_to_cpu((end)->w0) & 
END_W0_UCOND_NOTIFY)
 #define xive_end_is_backlog(end)  (be32_to_cpu((end)->w0) & END_W0_BACKLOG)
 #define xive_end_is_escalate(end) (be32_to_cpu((end)->w0) & 
END_W0_ESCALATE_CTL)
+#define xive_end_is_uncond_escalation(end)  \
+(be32_to_cpu((end)->w0) & END_W0_UNCOND_ESCALATE)
+#define xive_end_is_silent_escalation(end)  \
+(be32_to_cpu((end)->w0) & END_W0_SILENT_ESCALATE)
 
 static inline uint64_t xive_end_qaddr(XiveEND *end)
 {
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 592c0b70f197..3970999f4837 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -1389,7 +1389,7 @@ static bool xive_presenter_match(XiveRouter *xrtr, 
uint8_t format,
  *
  * The parameters represent what is sent on the PowerBus
  */
-static void xive_presenter_notify(XiveRouter *xrtr, uint8_t format,
+static bool xive_presenter_notify(XiveRouter *xrtr, uint8_t format,
   uint8_t nvt_blk, uint32_t nvt_idx,
   bool cam_ignore, uint8_t priority,
   uint32_t logic_serv)
@@ -1402,13 +1402,13 @@ static void xive_presenter_notify(XiveRouter *xrtr, 
uint8_t format,
 if (xive_router_get_nvt(xrtr, nvt_blk, nvt_idx, )) {
 qemu_log_mask(LOG_GUEST_ERROR, "XIVE: no NVT %x/%x\n",
   nvt_blk, nvt_idx);
-return;
+return false;
 }
 
 if (!xive_nvt_is_valid()) {
 qemu_log_mask(LOG_GUEST_ERROR, "XIVE: NVT %x/%x is invalid\n",
   nvt_blk, nvt_idx);
-return;
+return false;
 }
 
 found = xive_presenter_match(xrtr, format, nvt_blk, nvt_idx, cam_ignore,
@@ -1416,19 +1416,55 @@ static void xive_presenter_notify(XiveRouter *xrtr, 
uint8_t format,
 if (found) {
 ipb_update(>regs[match.ring], priority);
 xive_tctx_notify(match.tctx, match.ring);
+}
+
+return found;
+}
+
+static void xive_router_end_backlog(XiveRouter *xrtr,
+uint8_t nvt_blk, uint32_t nvt_idx,
+uint8_t priority)
+{
+XiveNVT nvt;
+
+/* NVT cache lookup */
+if (xive_router_get_nvt(xrtr, nvt_blk, nvt_idx, )) {
+qemu_log_mask(LOG_GUEST_ERROR, "XIVE: no NVT %x/%x\n",
+  nvt_blk, nvt_idx);
+return;
+}
+
+if (!xive_nvt_is_valid()) {
+qemu_log_mask(LOG_GUEST_ERROR, "XIVE: NVT %x/%x is invalid\n",
+  nvt_blk, nvt_idx);
 return;
 }
 
 /* Record the IPB in the associated NVT structure */
 ipb_update((uint8_t *) , priority);
 xive_router_write_nvt(xrtr, nvt_blk, nvt_idx, , 4);
+}
 
-/*
- * If no matching NVT is dispatched on a HW thread :
- * - update the NVT structure if backlog is activated
- * - escalate (ESe PQ bits and EAS in w4-5) if escalation is
- *   activated
- */
+
+/*
+ * Notification using the END ESe/ESn bit (Event State Buffer for
+ * escalation and notification). Profide futher coalescing in the
+ * Router.
+ */
+static bool xive_router_end_es_notify(XiveRouter *xrtr, uint8_t end_blk,
+  uint32_t end_idx, XiveEND *end,
+  uint32_t end_esmask)
+{
+uint8_t pq = xive_get_field32(end_esmask, end->w1);
+bool notify = xive_esb_trigger();
+
+if (pq != xive_get_field32(end_esmask, end->w1)) {
+end->w1 = xive_set_field32(end_esmask, end->w1, pq);
+  

[Qemu-devel] [PATCH 08/10] ppc/xive: Extend XiveTCTX with an router object pointer

2019-06-30 Thread Cédric Le Goater
This is to perform lookups in the NVT table when a vCPU is dispatched
and possibly resend interrupts.

Future XIVE chip will use a different class for the model of the
interrupt controller. So use an 'Object *' instead of a 'XiveRouter *'.

Signed-off-by: Cédric Le Goater 
---
 include/hw/ppc/xive.h |  4 +++-
 hw/intc/xive.c| 11 ++-
 hw/ppc/pnv.c  |  2 +-
 hw/ppc/spapr_irq.c|  2 +-
 4 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
index d922524982d3..b764e1e4e6d4 100644
--- a/include/hw/ppc/xive.h
+++ b/include/hw/ppc/xive.h
@@ -321,6 +321,8 @@ typedef struct XiveTCTX {
 qemu_irqos_output;
 
 uint8_t regs[XIVE_TM_RING_COUNT * XIVE_TM_RING_SIZE];
+
+Object  *xrtr;
 } XiveTCTX;
 
 /*
@@ -416,7 +418,7 @@ void xive_tctx_tm_write(XiveTCTX *tctx, hwaddr offset, 
uint64_t value,
 uint64_t xive_tctx_tm_read(XiveTCTX *tctx, hwaddr offset, unsigned size);
 
 void xive_tctx_pic_print_info(XiveTCTX *tctx, Monitor *mon);
-Object *xive_tctx_create(Object *cpu, XiveRouter *xrtr, Error **errp);
+Object *xive_tctx_create(Object *cpu, Object *xrtr, Error **errp);
 
 static inline uint32_t xive_nvt_cam_line(uint8_t nvt_blk, uint32_t nvt_idx)
 {
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index f7ba1c3b622f..56700681884f 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -573,6 +573,14 @@ static void xive_tctx_realize(DeviceState *dev, Error 
**errp)
 Object *obj;
 Error *local_err = NULL;
 
+obj = object_property_get_link(OBJECT(dev), "xrtr", _err);
+if (!obj) {
+error_propagate(errp, local_err);
+error_prepend(errp, "required link 'xrtr' not found: ");
+return;
+}
+tctx->xrtr = obj;
+
 obj = object_property_get_link(OBJECT(dev), "cpu", _err);
 if (!obj) {
 error_propagate(errp, local_err);
@@ -657,7 +665,7 @@ static const TypeInfo xive_tctx_info = {
 .class_init= xive_tctx_class_init,
 };
 
-Object *xive_tctx_create(Object *cpu, XiveRouter *xrtr, Error **errp)
+Object *xive_tctx_create(Object *cpu, Object *xrtr, Error **errp)
 {
 Error *local_err = NULL;
 Object *obj;
@@ -666,6 +674,7 @@ Object *xive_tctx_create(Object *cpu, XiveRouter *xrtr, 
Error **errp)
 object_property_add_child(cpu, TYPE_XIVE_TCTX, obj, _abort);
 object_unref(obj);
 object_property_add_const_link(obj, "cpu", cpu, _abort);
+object_property_add_const_link(obj, "xrtr", xrtr, _abort);
 object_property_set_bool(obj, true, "realized", _err);
 if (local_err) {
 goto error;
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index b87e01e5b925..11916dc273c2 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -765,7 +765,7 @@ static void pnv_chip_power9_intc_create(PnvChip *chip, 
PowerPCCPU *cpu,
  * controller object is initialized afterwards. Hopefully, it's
  * only used at runtime.
  */
-obj = xive_tctx_create(OBJECT(cpu), XIVE_ROUTER(>xive), _err);
+obj = xive_tctx_create(OBJECT(cpu), OBJECT(>xive), _err);
 if (local_err) {
 error_propagate(errp, local_err);
 return;
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index b2b01e850de8..5b3c3c50967b 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -353,7 +353,7 @@ static void 
spapr_irq_cpu_intc_create_xive(SpaprMachineState *spapr,
 Object *obj;
 SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
 
-obj = xive_tctx_create(OBJECT(cpu), XIVE_ROUTER(spapr->xive), _err);
+obj = xive_tctx_create(OBJECT(cpu), OBJECT(spapr->xive), _err);
 if (local_err) {
 error_propagate(errp, local_err);
 return;
-- 
2.21.0




[Qemu-devel] [PATCH 07/10] ppc/xive: Improve 'info pic' support

2019-06-30 Thread Cédric Le Goater
Provide a better output of the XIVE END structures including the
escalation information and extend the PowerNV machine 'info pic'
command with a dump of the END EAS table used for escalations.

Signed-off-by: Cédric Le Goater 
---
 include/hw/ppc/xive.h  |  5 
 include/hw/ppc/xive_regs.h |  6 +
 hw/intc/pnv_xive.c |  9 +++
 hw/intc/spapr_xive.c   |  1 -
 hw/intc/xive.c | 48 +-
 5 files changed, 57 insertions(+), 12 deletions(-)

diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
index a6ee7e831d8b..d922524982d3 100644
--- a/include/hw/ppc/xive.h
+++ b/include/hw/ppc/xive.h
@@ -356,8 +356,6 @@ typedef struct XiveRouterClass {
 XiveTCTX *(*get_tctx)(XiveRouter *xrtr, CPUState *cs);
 } XiveRouterClass;
 
-void xive_eas_pic_print_info(XiveEAS *eas, uint32_t lisn, Monitor *mon);
-
 int xive_router_get_eas(XiveRouter *xrtr, uint8_t eas_blk, uint32_t eas_idx,
 XiveEAS *eas);
 int xive_router_get_end(XiveRouter *xrtr, uint8_t end_blk, uint32_t end_idx,
@@ -399,9 +397,6 @@ typedef struct XiveENDSource {
  */
 #define XIVE_PRIORITY_MAX  7
 
-void xive_end_pic_print_info(XiveEND *end, uint32_t end_idx, Monitor *mon);
-void xive_end_queue_pic_print_info(XiveEND *end, uint32_t width, Monitor *mon);
-
 /*
  * XIVE Thread Interrupt Management Aera (TIMA)
  *
diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h
index 69af326ebf2c..3fdf1a83b9b6 100644
--- a/include/hw/ppc/xive_regs.h
+++ b/include/hw/ppc/xive_regs.h
@@ -128,6 +128,8 @@ typedef struct XiveEAS {
 #define xive_eas_is_valid(eas)   (be64_to_cpu((eas)->w) & EAS_VALID)
 #define xive_eas_is_masked(eas)  (be64_to_cpu((eas)->w) & EAS_MASKED)
 
+void xive_eas_pic_print_info(XiveEAS *eas, uint32_t lisn, Monitor *mon);
+
 static inline uint64_t xive_get_field64(uint64_t mask, uint64_t word)
 {
 return (be64_to_cpu(word) & mask) >> ctz64(mask);
@@ -218,6 +220,10 @@ static inline uint64_t xive_end_qaddr(XiveEND *end)
 be32_to_cpu(end->w3);
 }
 
+void xive_end_pic_print_info(XiveEND *end, uint32_t end_idx, Monitor *mon);
+void xive_end_queue_pic_print_info(XiveEND *end, uint32_t width, Monitor *mon);
+void xive_end_eas_pic_print_info(XiveEND *end, uint32_t end_idx, Monitor *mon);
+
 /* Notification Virtual Target (NVT) */
 typedef struct XiveNVT {
 uint32_tw0;
diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index 4dc92ef1e372..ff1226485983 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -1593,6 +1593,15 @@ void pnv_xive_pic_print_info(PnvXive *xive, Monitor *mon)
 }
 xive_end_pic_print_info(, i, mon);
 }
+
+monitor_printf(mon, "XIVE[%x] END Escalation %08x .. %08x\n", blk, 0,
+   nr_ends - 1);
+for (i = 0; i < nr_ends; i++) {
+if (xive_router_get_end(xrtr, blk, i, )) {
+break;
+}
+xive_end_eas_pic_print_info(, i, mon);
+}
 }
 
 static void pnv_xive_reset(void *dev)
diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index 58c2e5d890bd..48cd50192f61 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -143,7 +143,6 @@ static void spapr_xive_end_pic_print_info(SpaprXive *xive, 
XiveEND *end,
priority, qindex, qentries, qaddr_base, qgen);
 
 xive_end_queue_pic_print_info(end, 6, mon);
-monitor_printf(mon, "]");
 }
 
 void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon)
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 3970999f4837..f7ba1c3b622f 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -1136,6 +1136,7 @@ void xive_end_queue_pic_print_info(XiveEND *end, uint32_t 
width, Monitor *mon)
be32_to_cpu(qdata));
 qindex = (qindex + 1) & (qentries - 1);
 }
+monitor_printf(mon, "]");
 }
 
 void xive_end_pic_print_info(XiveEND *end, uint32_t end_idx, Monitor *mon)
@@ -1146,24 +1147,36 @@ void xive_end_pic_print_info(XiveEND *end, uint32_t 
end_idx, Monitor *mon)
 uint32_t qsize = xive_get_field32(END_W0_QSIZE, end->w0);
 uint32_t qentries = 1 << (qsize + 10);
 
-uint32_t nvt = xive_get_field32(END_W6_NVT_INDEX, end->w6);
+uint32_t nvt_blk = xive_get_field32(END_W6_NVT_BLOCK, end->w6);
+uint32_t nvt_idx = xive_get_field32(END_W6_NVT_INDEX, end->w6);
 uint8_t priority = xive_get_field32(END_W7_F0_PRIORITY, end->w7);
+uint8_t pq;
 
 if (!xive_end_is_valid(end)) {
 return;
 }
 
-monitor_printf(mon, "  %08x %c%c%c%c%c prio:%d nvt:%04x eq:@%08"PRIx64
-   "% 6d/%5d ^%d", end_idx,
+pq = xive_get_field32(END_W1_ESn, end->w1);
+
+monitor_printf(mon, "  %08x %c%c %c%c%c%c%c%c%c prio:%d nvt:%02x/%04x",
+   end_idx,
+   pq & XIVE_ESB_VAL_P ? 'P' : '-',
+   pq & XIVE_ESB_VAL_Q ? 'Q' : '-',
xive_end_is_valid(end)? 'v' : '-',
xive_end_is_enqueue(end)  ? 'q' : '-',

[Qemu-devel] [PATCH 04/10] ppc/xive: Fix TM_PULL_POOL_CTX special operation

2019-06-30 Thread Cédric Le Goater
When a CPU is reseted, the hypervisor (Linux or OPAL) invalidates the
POOL interrupt context of a CPU with this special command. It returns
the POOL CAM line value and resets the VP bit.

Fixes: 4836b45510aa ("ppc/xive: activate HV support")
Signed-off-by: Cédric Le Goater 
---
 hw/intc/xive.c | 19 ++-
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 534f56f86bd5..cf77bdb7d34a 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -132,6 +132,11 @@ static void xive_tctx_set_cppr(XiveTCTX *tctx, uint8_t 
ring, uint8_t cppr)
 xive_tctx_notify(tctx, ring);
 }
 
+static inline uint32_t xive_tctx_word2(uint8_t *ring)
+{
+return *((uint32_t *) [TM_WORD2]);
+}
+
 /*
  * XIVE Thread Interrupt Management Area (TIMA)
  */
@@ -150,11 +155,12 @@ static uint64_t xive_tm_ack_hv_reg(XiveTCTX *tctx, hwaddr 
offset, unsigned size)
 static uint64_t xive_tm_pull_pool_ctx(XiveTCTX *tctx, hwaddr offset,
   unsigned size)
 {
-uint64_t ret;
+uint32_t qw2w2_prev = xive_tctx_word2(>regs[TM_QW2_HV_POOL]);
+uint32_t qw2w2;
 
-ret = tctx->regs[TM_QW2_HV_POOL + TM_WORD2] & TM_QW2W2_POOL_CAM;
-tctx->regs[TM_QW2_HV_POOL + TM_WORD2] &= ~TM_QW2W2_POOL_CAM;
-return ret;
+qw2w2 = xive_set_field32(TM_QW2W2_VP, qw2w2_prev, 0);
+memcpy(>regs[TM_QW2_HV_POOL + TM_WORD2], , 4);
+return qw2w2;
 }
 
 static void xive_tm_vt_push(XiveTCTX *tctx, hwaddr offset,
@@ -484,11 +490,6 @@ const MemoryRegionOps xive_tm_ops = {
 },
 };
 
-static inline uint32_t xive_tctx_word2(uint8_t *ring)
-{
-return *((uint32_t *) [TM_WORD2]);
-}
-
 static char *xive_tctx_ring_print(uint8_t *ring)
 {
 uint32_t w2 = xive_tctx_word2(ring);
-- 
2.21.0




[Qemu-devel] [PATCH 05/10] ppc/xive: Implement TM_PULL_OS_CTX special command

2019-06-30 Thread Cédric Le Goater
When a vCPU is not dispatched anymore on a HW thread, the Hypervisor
(KVM) invalidates the OS interrupt context of a vCPU with this special
command. It returns the OS CAM line value and resets the VO bit.

Signed-off-by: Cédric Le Goater 
---
 hw/intc/xive.c | 15 ++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index cf77bdb7d34a..592c0b70f197 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -334,6 +334,17 @@ static void xive_tm_set_os_pending(XiveTCTX *tctx, hwaddr 
offset,
 xive_tctx_notify(tctx, TM_QW1_OS);
 }
 
+static uint64_t xive_tm_pull_os_ctx(XiveTCTX *tctx, hwaddr offset,
+unsigned size)
+{
+uint32_t qw1w2_prev = xive_tctx_word2(>regs[TM_QW1_OS]);
+uint32_t qw1w2;
+
+qw1w2 = xive_set_field32(TM_QW1W2_VO, qw1w2_prev, 0);
+memcpy(>regs[TM_QW1_OS + TM_WORD2], , 4);
+return qw1w2;
+}
+
 /*
  * Define a mapping of "special" operations depending on the TIMA page
  * offset and the size of the operation.
@@ -360,6 +371,8 @@ static const XiveTmOp xive_tm_operations[] = {
 /* MMIOs above 2K : special operations with side effects */
 { XIVE_TM_OS_PAGE, TM_SPC_ACK_OS_REG, 2, NULL, xive_tm_ack_os_reg },
 { XIVE_TM_OS_PAGE, TM_SPC_SET_OS_PENDING, 1, xive_tm_set_os_pending, NULL 
},
+{ XIVE_TM_HV_PAGE, TM_SPC_PULL_OS_CTX,4, NULL, xive_tm_pull_os_ctx },
+{ XIVE_TM_HV_PAGE, TM_SPC_PULL_OS_CTX,8, NULL, xive_tm_pull_os_ctx },
 { XIVE_TM_HV_PAGE, TM_SPC_ACK_HV_REG, 2, NULL, xive_tm_ack_hv_reg },
 { XIVE_TM_HV_PAGE, TM_SPC_PULL_POOL_CTX,  4, NULL, xive_tm_pull_pool_ctx },
 { XIVE_TM_HV_PAGE, TM_SPC_PULL_POOL_CTX,  8, NULL, xive_tm_pull_pool_ctx },
@@ -403,7 +416,7 @@ void xive_tctx_tm_write(XiveTCTX *tctx, hwaddr offset, 
uint64_t value,
 if (offset & 0x800) {
 xto = xive_tm_find_op(offset, size, true);
 if (!xto) {
-qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid write access at TIMA"
+qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid write access at TIMA 
"
   "@%"HWADDR_PRIx"\n", offset);
 } else {
 xto->write_handler(tctx, offset, value, size);
-- 
2.21.0




[Qemu-devel] [PATCH 10/10] ppc/pnv: Dump the XIVE NVT table

2019-06-30 Thread Cédric Le Goater
This is to track the configuration of the base END index of the vCPU
and the Interrupt Pending Buffer. The NVT IPB is updated when an
interrupt can not be presented to a vCPU.

We try to loop on the full table skipping empty indirect pages which
are not necessarily allocated.

Signed-off-by: Cédric Le Goater 
---
 include/hw/ppc/xive_regs.h |  2 ++
 hw/intc/pnv_xive.c | 60 ++
 2 files changed, 62 insertions(+)

diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h
index 7ba0fb055174..50802bbdaab0 100644
--- a/include/hw/ppc/xive_regs.h
+++ b/include/hw/ppc/xive_regs.h
@@ -229,6 +229,8 @@ typedef struct XiveNVT {
 uint32_tw0;
 #define NVT_W0_VALID PPC_BIT32(0)
 uint32_tw1;
+#define NVT_W1_EQ_BLOCK  PPC_BITMASK32(0, 3)
+#define NVT_W1_EQ_INDEX  PPC_BITMASK32(4, 31)
 uint32_tw2;
 uint32_tw3;
 uint32_tw4;
diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index ff1226485983..8778c11623dc 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -121,6 +121,20 @@ static uint64_t pnv_xive_vst_page_size_allowed(uint32_t 
page_shift)
  page_shift == 21 || page_shift == 24;
 }
 
+static uint64_t pnv_xive_vst_indirect_page_shift(uint64_t vsd)
+{
+uint32_t page_shift;
+
+vsd = ldq_be_dma(_space_memory, vsd & VSD_ADDRESS_MASK);
+page_shift = GETFIELD(VSD_TSIZE, vsd) + 12;
+
+if (!pnv_xive_vst_page_size_allowed(page_shift)) {
+return 0;
+}
+
+return page_shift;
+}
+
 static uint64_t pnv_xive_vst_size(uint64_t vsd)
 {
 uint64_t vst_tsize = 1ull << (GETFIELD(VSD_TSIZE, vsd) + 12);
@@ -466,6 +480,24 @@ static uint32_t pnv_xive_nr_ends(PnvXive *xive)
 / vst_infos[VST_TSEL_EQDT].size;
 }
 
+static uint32_t pnv_xive_nr_indirect(PnvXive *xive, uint32_t type)
+{
+const XiveVstInfo *info = _infos[type];
+uint8_t blk = xive->chip->chip_id;
+uint32_t page_shift =
+pnv_xive_vst_indirect_page_shift(xive->vsds[type][blk]);
+
+return (1ull << page_shift) / info->size;
+}
+
+static uint32_t pnv_xive_nr_nvts(PnvXive *xive)
+{
+uint8_t blk = xive->chip->chip_id;
+
+return pnv_xive_vst_size(xive->vsds[VST_TSEL_VPDT][blk])
+/ vst_infos[VST_TSEL_VPDT].size;
+}
+
 /*
  * EDT Table
  *
@@ -1560,6 +1592,21 @@ static const MemoryRegionOps pnv_xive_pc_ops = {
 },
 };
 
+static void xive_nvt_pic_print_info(XiveNVT *nvt, uint32_t nvt_idx,
+Monitor *mon)
+{
+uint8_t  eq_blk = xive_get_field32(NVT_W1_EQ_BLOCK, nvt->w1);
+uint32_t eq_idx = xive_get_field32(NVT_W1_EQ_INDEX, nvt->w1);
+
+if (!xive_nvt_is_valid(nvt)) {
+return;
+}
+
+monitor_printf(mon, "  %08x end:%02x/%04x ipb:%02x\n", nvt_idx,
+   eq_blk, eq_idx,
+   xive_get_field32(NVT_W4_IPB, nvt->w4));
+}
+
 void pnv_xive_pic_print_info(PnvXive *xive, Monitor *mon)
 {
 XiveRouter *xrtr = XIVE_ROUTER(xive);
@@ -1567,8 +1614,11 @@ void pnv_xive_pic_print_info(PnvXive *xive, Monitor *mon)
 uint32_t srcno0 = XIVE_SRCNO(blk, 0);
 uint32_t nr_ipis = pnv_xive_nr_ipis(xive);
 uint32_t nr_ends = pnv_xive_nr_ends(xive);
+uint32_t nr_nvts = pnv_xive_nr_nvts(xive);
+uint32_t nr_indirect_nvts = pnv_xive_nr_indirect(xive, VST_TSEL_VPDT);
 XiveEAS eas;
 XiveEND end;
+XiveNVT nvt;
 int i;
 
 monitor_printf(mon, "XIVE[%x] Source %08x .. %08x\n", blk, srcno0,
@@ -1602,6 +1652,16 @@ void pnv_xive_pic_print_info(PnvXive *xive, Monitor *mon)
 }
 xive_end_eas_pic_print_info(, i, mon);
 }
+
+monitor_printf(mon, "XIVE[%x] NVTT %08x .. %08x\n", blk, 0, nr_nvts - 1);
+for (i = 0; i < nr_nvts; i++) {
+if (xive_router_get_nvt(xrtr, blk, i, )) {
+/* skip an indirect page */
+i += nr_indirect_nvts - 1;
+continue;
+}
+xive_nvt_pic_print_info(, i, mon);
+}
 }
 
 static void pnv_xive_reset(void *dev)
-- 
2.21.0




[Qemu-devel] [PATCH 02/10] ppc/xive: Make the PIPR register readonly

2019-06-30 Thread Cédric Le Goater
When the hypervisor (KVM) dispatches a vCPU on a HW thread, it restores
its thread interrupt context. The Pending Interrupt Priority Register
(PIPR) is computed from the Interrupt Pending Buffer (IPB) and stores
should not be allowed to change its value.

Fixes: 207d9fe98510 ("ppc/xive: introduce the XIVE interrupt thread context")
Signed-off-by: Cédric Le Goater 
---
 hw/intc/xive.c | 32 
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 3b1f9520ae9f..534f56f86bd5 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -182,31 +182,31 @@ static uint64_t xive_tm_vt_poll(XiveTCTX *tctx, hwaddr 
offset, unsigned size)
  */
 
 static const uint8_t xive_tm_hw_view[] = {
-/* QW-0 User */   3, 0, 0, 0,   0, 0, 0, 0,   3, 3, 3, 3,   0, 0, 0, 0,
-/* QW-1 OS   */   3, 3, 3, 3,   3, 3, 0, 3,   3, 3, 3, 3,   0, 0, 0, 0,
-/* QW-2 POOL */   0, 0, 3, 3,   0, 0, 0, 0,   3, 3, 3, 3,   0, 0, 0, 0,
-/* QW-3 PHYS */   3, 3, 3, 3,   0, 3, 0, 3,   3, 0, 0, 3,   3, 3, 3, 0,
+3, 0, 0, 0,   0, 0, 0, 0,   3, 3, 3, 3,   0, 0, 0, 0, /* QW-0 User */
+3, 3, 3, 3,   3, 3, 0, 2,   3, 3, 3, 3,   0, 0, 0, 0, /* QW-1 OS   */
+0, 0, 3, 3,   0, 0, 0, 0,   3, 3, 3, 3,   0, 0, 0, 0, /* QW-2 POOL */
+3, 3, 3, 3,   0, 3, 0, 2,   3, 0, 0, 3,   3, 3, 3, 0, /* QW-3 PHYS */
 };
 
 static const uint8_t xive_tm_hv_view[] = {
-/* QW-0 User */   3, 0, 0, 0,   0, 0, 0, 0,   3, 3, 3, 3,   0, 0, 0, 0,
-/* QW-1 OS   */   3, 3, 3, 3,   3, 3, 0, 3,   3, 3, 3, 3,   0, 0, 0, 0,
-/* QW-2 POOL */   0, 0, 3, 3,   0, 0, 0, 0,   0, 3, 3, 3,   0, 0, 0, 0,
-/* QW-3 PHYS */   3, 3, 3, 3,   0, 3, 0, 3,   3, 0, 0, 3,   0, 0, 0, 0,
+3, 0, 0, 0,   0, 0, 0, 0,   3, 3, 3, 3,   0, 0, 0, 0, /* QW-0 User */
+3, 3, 3, 3,   3, 3, 0, 2,   3, 3, 3, 3,   0, 0, 0, 0, /* QW-1 OS   */
+0, 0, 3, 3,   0, 0, 0, 0,   0, 3, 3, 3,   0, 0, 0, 0, /* QW-2 POOL */
+3, 3, 3, 3,   0, 3, 0, 2,   3, 0, 0, 3,   0, 0, 0, 0, /* QW-3 PHYS */
 };
 
 static const uint8_t xive_tm_os_view[] = {
-/* QW-0 User */   3, 0, 0, 0,   0, 0, 0, 0,   3, 3, 3, 3,   0, 0, 0, 0,
-/* QW-1 OS   */   2, 3, 2, 2,   2, 2, 0, 2,   0, 0, 0, 0,   0, 0, 0, 0,
-/* QW-2 POOL */   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,
-/* QW-3 PHYS */   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,
+3, 0, 0, 0,   0, 0, 0, 0,   3, 3, 3, 3,   0, 0, 0, 0, /* QW-0 User */
+2, 3, 2, 2,   2, 2, 0, 2,   0, 0, 0, 0,   0, 0, 0, 0, /* QW-1 OS   */
+0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0, /* QW-2 POOL */
+0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0, /* QW-3 PHYS */
 };
 
 static const uint8_t xive_tm_user_view[] = {
-/* QW-0 User */   3, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,
-/* QW-1 OS   */   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,
-/* QW-2 POOL */   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,
-/* QW-3 PHYS */   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,
+3, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0, /* QW-0 User */
+0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0, /* QW-1 OS   */
+0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0, /* QW-2 POOL */
+0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0, /* QW-3 PHYS */
 };
 
 /*
-- 
2.21.0




[Qemu-devel] [PATCH 09/10] ppc/xive: Synthesize interrupt from the saved IPB in the NVT

2019-06-30 Thread Cédric Le Goater
When an interrupt can not be presented to a vCPU, the XIVE presenter
updates the Interrupt Pending Buffer of the XIVE NVT if backlog is
activated in the END.

Later, when the same vCPU is dispatched, its context is pushed in the
thread context registers and the VO bit is set in the CAM line
word. The HW grabs the associated NVT to pull the pending bits, and
merge them with the IPB of the TIMA. If interrupts were missed while
the vCPU was not dispatched, these are synthesized in this sequence.

Signed-off-by: Cédric Le Goater 
---
 include/hw/ppc/xive.h  | 14 
 include/hw/ppc/xive_regs.h |  1 +
 hw/intc/xive.c | 67 --
 3 files changed, 80 insertions(+), 2 deletions(-)

diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
index b764e1e4e6d4..e4dcaa7a10e9 100644
--- a/include/hw/ppc/xive.h
+++ b/include/hw/ppc/xive.h
@@ -420,11 +420,25 @@ uint64_t xive_tctx_tm_read(XiveTCTX *tctx, hwaddr offset, 
unsigned size);
 void xive_tctx_pic_print_info(XiveTCTX *tctx, Monitor *mon);
 Object *xive_tctx_create(Object *cpu, Object *xrtr, Error **errp);
 
+/*
+ * The VP number space in a block is defined by the END_W6_NVT_INDEX
+ * field of the XIVE END
+ */
 static inline uint32_t xive_nvt_cam_line(uint8_t nvt_blk, uint32_t nvt_idx)
 {
 return (nvt_blk << 19) | nvt_idx;
 }
 
+static inline uint32_t xive_nvt_idx(uint32_t cam_line)
+{
+return cam_line & 0x7;
+}
+
+static inline uint32_t xive_nvt_blk(uint32_t cam_line)
+{
+return (cam_line >> 19) & 0xf;
+}
+
 /*
  * KVM XIVE device helpers
  */
diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h
index 3fdf1a83b9b6..7ba0fb055174 100644
--- a/include/hw/ppc/xive_regs.h
+++ b/include/hw/ppc/xive_regs.h
@@ -232,6 +232,7 @@ typedef struct XiveNVT {
 uint32_tw2;
 uint32_tw3;
 uint32_tw4;
+#define NVT_W4_IPB   PPC_BITMASK32(16, 23)
 uint32_tw5;
 uint32_tw6;
 uint32_tw7;
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 56700681884f..2225183e0e16 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -345,6 +345,62 @@ static uint64_t xive_tm_pull_os_ctx(XiveTCTX *tctx, hwaddr 
offset,
 return qw1w2;
 }
 
+static void xive_tctx_need_resend(XiveTCTX *tctx, uint8_t nvt_blk,
+ uint32_t nvt_idx)
+{
+XiveNVT nvt;
+uint8_t ipb;
+XiveRouter *xrtr = XIVE_ROUTER(tctx->xrtr);
+
+/*
+ * Grab the associated NVT to pull the pending bits, and merge
+ * them with the IPB of the thread interrupt context registers
+ */
+if (xive_router_get_nvt(xrtr, nvt_blk, nvt_idx, )) {
+qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid NVT %x/%x\n",
+  nvt_blk, nvt_idx);
+return;
+}
+
+ipb = xive_get_field32(NVT_W4_IPB, nvt.w4);
+
+if (ipb) {
+uint8_t *regs = >regs[TM_QW1_OS];
+
+/* Reset the NVT value */
+nvt.w4 = xive_set_field32(NVT_W4_IPB, nvt.w4, 0);
+xive_router_write_nvt(xrtr, nvt_blk, nvt_idx, , 4);
+
+/* Merge in current context */
+regs[TM_IPB] |= ipb;
+regs[TM_PIPR] = ipb_to_pipr(regs[TM_IPB]);
+
+/* Possibly resend */
+xive_tctx_notify(tctx, TM_QW1_OS);
+}
+}
+
+/*
+ * Updating the OS CAM line can trigger a resend of interrupt
+ */
+static void xive_tm_push_os_cam(XiveTCTX *tctx, hwaddr offset,
+   uint64_t value, unsigned size)
+{
+uint32_t qw1w2 = value;
+uint8_t nvt_blk = xive_nvt_blk(qw1w2);
+uint32_t nvt_idx = xive_nvt_idx(qw1w2);
+bool vo = !!(qw1w2 & TM_QW1W2_VO);
+
+/* First update the registers */
+qw1w2 = cpu_to_be32(qw1w2);
+memcpy(>regs[TM_QW1_OS + TM_WORD2], , 4);
+
+/* Check the interrupt pending bits */
+if (vo) {
+xive_tctx_need_resend(tctx, nvt_blk, nvt_idx);
+}
+}
+
 /*
  * Define a mapping of "special" operations depending on the TIMA page
  * offset and the size of the operation.
@@ -364,6 +420,7 @@ static const XiveTmOp xive_tm_operations[] = {
  * effects
  */
 { XIVE_TM_OS_PAGE, TM_QW1_OS + TM_CPPR,   1, xive_tm_set_os_cppr, NULL },
+{ XIVE_TM_HV_PAGE, TM_QW1_OS + TM_WORD2, 4, xive_tm_push_os_cam, NULL 
},
 { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_CPPR, 1, xive_tm_set_hv_cppr, NULL 
},
 { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_WORD2, 1, xive_tm_vt_push, NULL },
 { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_WORD2, 1, NULL, xive_tm_vt_poll },
@@ -1471,6 +1528,7 @@ static void xive_router_end_backlog(XiveRouter *xrtr,
 uint8_t priority)
 {
 XiveNVT nvt;
+uint8_t ipb;
 
 /* NVT cache lookup */
 if (xive_router_get_nvt(xrtr, nvt_blk, nvt_idx, )) {
@@ -1485,8 +1543,13 @@ static void xive_router_end_backlog(XiveRouter *xrtr,
 return;
 }
 
-/* Record the IPB in the associated NVT structure */
-ipb_update((uint8_t *) , priority);
+ 

[Qemu-devel] [PATCH 03/10] ppc/pnv: Rework cache watch model of PnvXIVE

2019-06-30 Thread Cédric Le Goater
When the software modifies the XIVE internal structures, ESB, EAS,
END, NVT, it also must update the caches of the different XIVE
sub-engines. HW offers a set of common interface for such purpose.

The CWATCH_SPEC register defines the block/index of the target and a
set of flags to perform a full update and to watch for update
conflicts.

The cache watch CWATCH_DATAX registers are then loaded with the target
data with a first read on CWATCH_DATA0. Writing back is done in the
opposit order, CWATCH_DATA0 triggering the update.

The SCRUB_TRIG registers are used to flush the cache in RAM, and to
possibly invalidate it. Cache disablement is also an option but as we
do not model the cache, these registers are no-ops

Today, the modeling of these registers is incorrect but it did not
impact the set up of a baremetal system. However, running KVM requires
a rework.

Fixes: 2dfa91a2aa5a ("ppc/pnv: add a XIVE interrupt controller model for 
POWER9")
Signed-off-by: Cédric Le Goater 
---
 hw/intc/pnv_xive.c | 142 +
 1 file changed, 106 insertions(+), 36 deletions(-)

diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index 9ab77feee9d8..4dc92ef1e372 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -169,7 +169,7 @@ static uint64_t pnv_xive_vst_addr_indirect(PnvXive *xive, 
uint32_t type,
 vsd = ldq_be_dma(_space_memory, vsd_addr);
 
 if (!(vsd & VSD_ADDRESS_MASK)) {
-xive_error(xive, "VST: invalid %s entry %x !?", info->name, 0);
+xive_error(xive, "VST: invalid %s entry %x !?", info->name, idx);
 return 0;
 }
 
@@ -190,7 +190,7 @@ static uint64_t pnv_xive_vst_addr_indirect(PnvXive *xive, 
uint32_t type,
 vsd = ldq_be_dma(_space_memory, vsd_addr);
 
 if (!(vsd & VSD_ADDRESS_MASK)) {
-xive_error(xive, "VST: invalid %s entry %x !?", info->name, 0);
+xive_error(xive, "VST: invalid %s entry %x !?", info->name, idx);
 return 0;
 }
 
@@ -294,8 +294,12 @@ static int pnv_xive_write_end(XiveRouter *xrtr, uint8_t 
blk, uint32_t idx,
   word_number);
 }
 
-static int pnv_xive_end_update(PnvXive *xive, uint8_t blk, uint32_t idx)
+static int pnv_xive_end_update(PnvXive *xive)
 {
+uint8_t  blk = GETFIELD(VC_EQC_CWATCH_BLOCKID,
+   xive->regs[(VC_EQC_CWATCH_SPEC >> 3)]);
+uint32_t idx = GETFIELD(VC_EQC_CWATCH_OFFSET,
+   xive->regs[(VC_EQC_CWATCH_SPEC >> 3)]);
 int i;
 uint64_t eqc_watch[4];
 
@@ -307,6 +311,24 @@ static int pnv_xive_end_update(PnvXive *xive, uint8_t blk, 
uint32_t idx)
   XIVE_VST_WORD_ALL);
 }
 
+static void pnv_xive_end_cache_load(PnvXive *xive)
+{
+uint8_t  blk = GETFIELD(VC_EQC_CWATCH_BLOCKID,
+   xive->regs[(VC_EQC_CWATCH_SPEC >> 3)]);
+uint32_t idx = GETFIELD(VC_EQC_CWATCH_OFFSET,
+   xive->regs[(VC_EQC_CWATCH_SPEC >> 3)]);
+uint64_t eqc_watch[4] = { 0 };
+int i;
+
+if (pnv_xive_vst_read(xive, VST_TSEL_EQDT, blk, idx, eqc_watch)) {
+xive_error(xive, "VST: no END entry %x/%x !?", blk, idx);
+}
+
+for (i = 0; i < ARRAY_SIZE(eqc_watch); i++) {
+xive->regs[(VC_EQC_CWATCH_DAT0 >> 3) + i] = be64_to_cpu(eqc_watch[i]);
+}
+}
+
 static int pnv_xive_get_nvt(XiveRouter *xrtr, uint8_t blk, uint32_t idx,
 XiveNVT *nvt)
 {
@@ -320,8 +342,12 @@ static int pnv_xive_write_nvt(XiveRouter *xrtr, uint8_t 
blk, uint32_t idx,
   word_number);
 }
 
-static int pnv_xive_nvt_update(PnvXive *xive, uint8_t blk, uint32_t idx)
+static int pnv_xive_nvt_update(PnvXive *xive)
 {
+uint8_t  blk = GETFIELD(PC_VPC_CWATCH_BLOCKID,
+   xive->regs[(PC_VPC_CWATCH_SPEC >> 3)]);
+uint32_t idx = GETFIELD(PC_VPC_CWATCH_OFFSET,
+   xive->regs[(PC_VPC_CWATCH_SPEC >> 3)]);
 int i;
 uint64_t vpc_watch[8];
 
@@ -333,6 +359,24 @@ static int pnv_xive_nvt_update(PnvXive *xive, uint8_t blk, 
uint32_t idx)
   XIVE_VST_WORD_ALL);
 }
 
+static void pnv_xive_nvt_cache_load(PnvXive *xive)
+{
+uint8_t  blk = GETFIELD(PC_VPC_CWATCH_BLOCKID,
+   xive->regs[(PC_VPC_CWATCH_SPEC >> 3)]);
+uint32_t idx = GETFIELD(PC_VPC_CWATCH_OFFSET,
+   xive->regs[(PC_VPC_CWATCH_SPEC >> 3)]);
+uint64_t vpc_watch[8] = { 0 };
+int i;
+
+if (pnv_xive_vst_read(xive, VST_TSEL_VPDT, blk, idx, vpc_watch)) {
+xive_error(xive, "VST: no NVT entry %x/%x !?", blk, idx);
+}
+
+for (i = 0; i < ARRAY_SIZE(vpc_watch); i++) {
+xive->regs[(PC_VPC_CWATCH_DAT0 >> 3) + i] = be64_to_cpu(vpc_watch[i]);
+}
+}
+
 static int pnv_xive_get_eas(XiveRouter *xrtr, uint8_t blk, uint32_t idx,
 XiveEAS *eas)
 {
@@ -346,12 +390,6 @@ static int pnv_xive_get_eas(XiveRouter *xrtr, uint8_t blk, 

[Qemu-devel] [PATCH 01/10] ppc/xive: Force the Physical CAM line value to group mode

2019-06-30 Thread Cédric Le Goater
When an interrupt needs to be delivered, the XIVE interrupt controller
presenter scans the CAM lines of the thread interrupt contexts of the
HW threads of the chip to find a matching vCPU. The interrupt context
is composed of 4 different sets of registers: Physical, HV, OS and
User.

The encoding of the Physical CAM line depends on the mode in which the
interrupt controller is operating: CAM mode or block group mode.
Block group mode being the default configuration today on POWER9 and
the only one available on the next POWER10 generation, enforce this
encoding in the Physical CAM line :

chip << 19 | 000 0 0001 thread (7Bit)

It fits the overall encoding of the NVT ids and simplifies the matching
algorithm in the presenter.

Fixes: d514c48d41fb ("ppc/xive: hardwire the Physical CAM line of the thread 
context")
Signed-off-by: Cédric Le Goater 
---
 hw/intc/xive.c | 21 +
 1 file changed, 5 insertions(+), 16 deletions(-)

diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 6250c0414de8..3b1f9520ae9f 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -1229,27 +1229,16 @@ XiveTCTX *xive_router_get_tctx(XiveRouter *xrtr, 
CPUState *cs)
 }
 
 /*
- * By default on P9, the HW CAM line (23bits) is hardwired to :
+ * Encode the HW CAM line in the block group mode format :
  *
- *   0x000||0b1||4Bit chip number||7Bit Thread number.
- *
- * When the block grouping is enabled, the CAM line is changed to :
- *
- *   4Bit chip number||0x001||7Bit Thread number.
+ *   chip << 19 | 000 0 0001 thread (7Bit)
  */
-static uint32_t hw_cam_line(uint8_t chip_id, uint8_t tid)
-{
-return 1 << 11 | (chip_id & 0xf) << 7 | (tid & 0x7f);
-}
-
-static bool xive_presenter_tctx_match_hw(XiveTCTX *tctx,
- uint8_t nvt_blk, uint32_t nvt_idx)
+static uint32_t xive_tctx_hw_cam_line(XiveTCTX *tctx)
 {
 CPUPPCState *env = _CPU(tctx->cs)->env;
 uint32_t pir = env->spr_cb[SPR_PIR].default_value;
 
-return hw_cam_line((pir >> 8) & 0xf, pir & 0x7f) ==
-hw_cam_line(nvt_blk, nvt_idx);
+return xive_nvt_cam_line((pir >> 8) & 0xf, 1 << 7 | (pir & 0x7f));
 }
 
 /*
@@ -1285,7 +1274,7 @@ static int xive_presenter_tctx_match(XiveTCTX *tctx, 
uint8_t format,
 
 /* PHYS ring */
 if ((be32_to_cpu(qw3w2) & TM_QW3W2_VT) &&
-xive_presenter_tctx_match_hw(tctx, nvt_blk, nvt_idx)) {
+cam == xive_tctx_hw_cam_line(tctx)) {
 return TM_QW3_HV_PHYS;
 }
 
-- 
2.21.0




[Qemu-devel] [PATCH 00/10] ppc/pnv: add XIVE support for KVM guests

2019-06-30 Thread Cédric Le Goater
Hello,

The QEMU PowerNV machine emulates a baremetal OpenPOWER system and
acts as an hypervisor (L0). Supporting emulation of KVM to run guests
(L1) requires a few more extensions, among which support for the XIVE
interrupt controller on POWER9 processor. 

The following changes fix some parts of the XIVE model and provide
support for escalations and resend. This mechanism is used by KVM to
kick a vCPU when it is not dispatched on a HW thread.

A series from Suraj adding guest support in the Radix MMU model of the
QEMU PowerNV machine is still required and will be send later. The
whole patchset can be found under :

  https://github.com/legoater/qemu/tree/powernv-4.1

Thanks,

C.

Cédric Le Goater (10):
  ppc/xive: Force the Physical CAM line value to group mode
  ppc/xive: Make the PIPR register readonly
  ppc/pnv: Rework cache watch model of PnvXIVE
  ppc/xive: Fix TM_PULL_POOL_CTX special operation
  ppc/xive: Implement TM_PULL_OS_CTX special command
  ppc/xive: Provide escalation support
  ppc/xive: Improve 'info pic' support
  ppc/xive: Extend XiveTCTX with an router object pointer
  ppc/xive: Synthesize interrupt from the saved IPB in the NVT
  ppc/pnv: Dump the XIVE NVT table

 include/hw/ppc/xive.h  |  23 ++-
 include/hw/ppc/xive_regs.h |  13 ++
 hw/intc/pnv_xive.c | 211 +++
 hw/intc/spapr_xive.c   |   1 -
 hw/intc/xive.c | 341 +
 hw/ppc/pnv.c   |   2 +-
 hw/ppc/spapr_irq.c |   2 +-
 7 files changed, 479 insertions(+), 114 deletions(-)

-- 
2.21.0




Re: [Qemu-devel] [PATCH 1/2] tests/acceptance: Add test of NeXTcube framebuffer using OCR

2019-06-30 Thread Thomas Huth
On 29/06/2019 17.00, Philippe Mathieu-Daudé wrote:
> Add a test of the NeXTcube framebuffer using the Tesseract OCR
> engine on a screenshot of the framebuffer device.

Wow, that's a funny idea, I like it!

> The test is very quick:
> 
>   $ avocado --show=app,ocr run tests/acceptance/machine_m68k_nextcube.py
>   JOB ID : f7d3c27976047036dc568183baf64c04863d9985
>   JOB LOG: ~/avocado/job-results/job-2019-06-29T16.18-f7d3c27/job.log
>   (1/1) 
> tests/acceptance/machine_m68k_nextcube.py:NextCubeMachine.test_bootrom_framebuffer:
>  |ocr:
>   ue r pun Honl'flx ; 5‘ 55‘
>   avg nca 25 MHZ, memary jag m
>   Backplane slat «a
>   Ethernet address a a r a r3 2
>   Memgry sackets aea canflqured far 16MB Darlly page made stMs but have 16MB 
> page made stMs )nstalled
>   Memgry sackets a and 1 canflqured far 16MB Darlly page made stMs but have 
> 16MB page made stMs )nstalled>   [...]
>   Yestlnq the rpu, 5::
>   system test raneg Errar egge 51
>   Egg: cammand
>   Default pggc devlce nut fauna
>   NEXY>I

Hmm, the quality of the text is rather bad...

> Documentation on how to install tesseract:
>   https://github.com/tesseract-ocr/tesseract/wiki#installation

... according to that documentation, you're also supposed to install a
language pack ... have you tried whether it gets better with
tesseract-ocr-eng ?

 Thomas




Re: [Qemu-devel] [PATCH 2/2] Acceptance tests: add SPICE protocol check

2019-06-30 Thread Cleber Rosa
On Fri, Jun 28, 2019 at 05:54:37PM -0300, Wainer dos Santos Moschetta wrote:
> 
> On 06/21/2019 03:09 AM, Cleber Rosa wrote:
> > This fires a QEMU binary with SPICE enabled, and does a basic
> > handshake, doing a basic client/server interaction and protocol
> > validation.
> > 
> > Signed-off-by: Cleber Rosa 
> > ---
> >   .travis.yml   |  5 +++-
> >   tests/Makefile.include|  6 +
> >   tests/acceptance/spice.py | 54 +++
> >   3 files changed, 64 insertions(+), 1 deletion(-)
> >   create mode 100644 tests/acceptance/spice.py
> > 
> > diff --git a/.travis.yml b/.travis.yml
> > index aeb9b211cd..6c9257a459 100644
> > --- a/.travis.yml
> > +++ b/.travis.yml
> > @@ -231,7 +231,7 @@ matrix:
> >   # Acceptance (Functional) tests
> >   - env:
> > -- CONFIG="--python=/usr/bin/python3 
> > --target-list=x86_64-softmmu,mips-softmmu,mips64el-softmmu,aarch64-softmmu,arm-softmmu,s390x-softmmu,alpha-softmmu"
> > +- CONFIG="--python=/usr/bin/python3 --enable-spice 
> > --target-list=x86_64-softmmu,mips-softmmu,mips64el-softmmu,aarch64-softmmu,arm-softmmu,s390x-softmmu,alpha-softmmu"
> >   - TEST_CMD="make check-acceptance"
> > after_failure:
> >   - cat tests/results/latest/job.log
> > @@ -240,6 +240,9 @@ matrix:
> > packages:
> >   - python3-pip
> >   - python3.5-venv
> > +- libspice-protocol-dev
> > +- libspice-server-dev
> > +
> >   # Using newer GCC with sanitizers
> >   - addons:
> >   apt:
> > diff --git a/tests/Makefile.include b/tests/Makefile.include
> > index 4c97da2878..7fc2d28099 100644
> > --- a/tests/Makefile.include
> > +++ b/tests/Makefile.include
> > @@ -1129,6 +1129,12 @@ AVOCADO_SHOW=app
> >   # Additional tags that are added to each occurence of "--filter-by-tags"
> >   AVOCADO_EXTRA_TAGS := ,-flaky
> > +# At last one test require spice to be enabled, allow it to be excluded
> > +# if it's not enabled
> > +ifneq ($(findstring y,"$(CONFIG_SPICE)"),y)
> > +AVOCADO_EXTRA_TAGS := $(AVOCADO_EXTRA_TAGS),-spice
> > +endif
> > +
> 
> Cleber, what about that improvement to avocado_qemu you were developing to
> parse the configure files then expose the enabled/disabled features to test
> code? Do you still plan to push it and so this proposal is just temporary?
>

That was actually a prototype that was done *before* the days of
"avocado_qemu"[1].  While the main reason for it to not have moved forward
back then was the requirement of a build environment, I believe we can
adapt some of the lessons learned there into a generic set of features
for the test runner.

Basically:

 * a generic capability mechanism should be present, with possibly many
   implementations (looking at the build environment is clearly one)

 * Jobs should be able to include/exlude tests based on capabilities
   (akin to how we're using tags)

 * for some other cases, tests should also be given a chance to loop at
   capabilities and decided to abort (cancel) at run time.

Having said that, I think we can start with the tools that we have,
which should serve to make the scope of those future enhancements and
features even clearer and better defined.

Regards,
- Cleber.

[1] - https://lists.gnu.org/archive/html/qemu-devel/2017-07/msg06757.html

> >   AVOCADO_TAGS=$(patsubst 
> > %-softmmu,--filter-by-tags=arch:%$(AVOCADO_EXTRA_TAGS), $(filter 
> > %-softmmu,$(TARGET_DIRS)))
> >   ifneq ($(findstring v2,"v$(PYTHON_VERSION)"),v2)
> > diff --git a/tests/acceptance/spice.py b/tests/acceptance/spice.py
> > new file mode 100644
> > index 00..aa22b1992d
> > --- /dev/null
> > +++ b/tests/acceptance/spice.py
> > @@ -0,0 +1,54 @@
> > +# Simple functional tests for SPICE functionality
> > +#
> > +# Copyright (c) 2019 Red Hat, Inc.
> > +#
> > +# Author:
> > +#  Cleber Rosa 
> > +#
> > +# This work is licensed under the terms of the GNU GPL, version 2 or
> > +# later.  See the COPYING file in the top-level directory.
> > +
> > +import socket
> > +import struct
> > +
> > +from avocado_qemu import Test
> > +from avocado.utils.network import find_free_port
> > +
> > +
> > +class Spice(Test):
> > +
> > +def test_protocol(self):
> > +"""
> > +:avocado: tags=quick
> > +:avocado: tags=spice
> > +"""
> > +port = find_free_port(5001, 5500, sequent=False)
> > +self.vm.add_args('-nodefaults', '-S',
> > + '-spice', 'port=%d,disable-ticketing' % port)
> > +self.vm.launch()
> > +
> > +RED_MAGIC = 0x51444552
> > +MAJOR_VERSION = 0x2
> > +
> > +client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
> > +client.connect(('127.0.0.1', port))
> > +red_link_mess = struct.pack('<10I',
> > +RED_MAGIC,  # magic
> > +MAJOR_VERSION,  # major version
> > +

Re: [Qemu-devel] [PATCH v6 00/16] tcg/ppc: Add vector opcodes

2019-06-30 Thread Mark Cave-Ayland
On 29/06/2019 14:00, Richard Henderson wrote:

> Changes since v5:
>   * Disable runtime altivec detection until all of the required
> opcodes are implemented.
> Because dup2 was last, that really means all of the pure altivec
> bits, so the initial patches are not bisectable in any meaningful
> sense.  I thought about reshuffling dup2 earlier, but that created
> too many conflicts and I was too lazy.
>   * Rearranged the patches a little bit to make sure that each
> one actually builds, which was not the case before.
>   * Folded in the fix to tcg_out_mem_long, as discussed in the
> followup within the v4 thread.
> 
> Changes since v4:
>   * Patch 1, "tcg/ppc: Introduce Altivec registers", is divided into
> ten smaller patches.
>   * The net result (code-wise) is not changed between former patch 1
> and ten new patches.
>   * Remaining (2-7) patches from v4 are applied verbatim.
>   * This means that code-wise v5 and v4 do not differ.
>   * v5 is devised to help debugging, and to better organize the code.
> 
> Changes since v3:
>   * Add support for bitsel, with the vsx xxsel insn.
>   * Rely on the new relocation overflow handling, so
> we don't require 3 insns for a vector load.
> 
> Changes since v2:
>   * Several generic tcg patches to improve dup vs dupi vs dupm.
> In particular, if a global temp (like guest r10) is not in
> a host register, we should duplicate from memory instead of
> loading to an integer register, spilling to stack, loading
> to a vector register, and then duplicating.
>   * I have more confidence that 32-bit ppc host should work
> this time around.  No testing on that front yet, but I've
> unified some code sequences with 64-bit ppc host.
>   * Base altivec now supports V128 only.  Moved V64 support to
> Power7 (v2.06), which has 64-bit load/store.
>   * Dropped support for 64-bit vector multiply using Power8.
> The expansion was too large compared to using integer regs.
> 
> Richard Henderson (16):
>   tcg/ppc: Introduce Altivec registers
>   tcg/ppc: Introduce macro VX4()
>   tcg/ppc: Introduce macros VRT(), VRA(), VRB(), VRC()
>   tcg/ppc: Enable tcg backend vector compilation
>   tcg/ppc: Add support for load/store/logic/comparison
>   tcg/ppc: Add support for vector maximum/minimum
>   tcg/ppc: Add support for vector add/subtract
>   tcg/ppc: Add support for vector saturated add/subtract
>   tcg/ppc: Prepare case for vector multiply
>   tcg/ppc: Support vector shift by immediate
>   tcg/ppc: Support vector multiply
>   tcg/ppc: Support vector dup2
>   tcg/ppc: Enable Altivec detection
>   tcg/ppc: Update vector support to v2.06
>   tcg/ppc: Update vector support to v2.07
>   tcg/ppc: Update vector support to v3.00
> 
>  tcg/ppc/tcg-target.h |   39 +-
>  tcg/ppc/tcg-target.opc.h |   13 +
>  tcg/ppc/tcg-target.inc.c | 1091 +++---
>  3 files changed, 1076 insertions(+), 67 deletions(-)
>  create mode 100644 tcg/ppc/tcg-target.opc.h

I don't have space for a full set of images on the G4, however I've tried boot 
tests
on installer CDs for MacOS 9, OS X 10.2, Linux and HelenOS and it looks good 
here.

Tested-by: Mark Cave-Ayland  [PPC32]


ATB,

Mark.



Re: [Qemu-devel] [PATCH 1/2] Acceptance tests: exclude "flaky" tests

2019-06-30 Thread Cleber Rosa
On Fri, Jun 28, 2019 at 05:43:09PM -0300, Wainer dos Santos Moschetta wrote:
> 
> On 06/21/2019 11:38 AM, Cleber Rosa wrote:
> > On Fri, Jun 21, 2019 at 09:03:33AM +0200, Philippe Mathieu-Daudé wrote:
> > > On 6/21/19 8:09 AM, Cleber Rosa wrote:
> > > > It's a fact that some tests may not be 100% reliable in all
> > > > environments.  While it's a tough call to remove a useful test that
> > > > from the tree because it may fail every 1/100th time (or so), having
> > > > human attention drawn to known issues is very bad for humans and for
> > > > the projects they manage.
> > > > 
> > > > As a compromise solution, this marks tests that are known to have
> > > > issues, or that exercises known issues in QEMU or other components,
> > > > and excludes them from the entry point.  As a consequence, tests
> > > > marked as "flaky" will not be executed as part of "make
> > > > check-acceptance".
> > > > 
> > > > Because such tests should be forgiven but never be forgotten, it's
> > > > possible to list them with (assuming "make check-venv" or "make
> > > > check-acceptance" has already initiatilized the venv):
> > > > 
> > > >$ ./tests/venv/bin/avocado list -t flaky tests/acceptance
> 
> It needs a Make target to run those flaky tests (If we ever agree on this
> idea of flaky tests). Other Avocado flags are passed (e.g. -t for tags) that
> can happen to fail tests on their absent. One clear example is the spice
> test on patch 02 of this series...
>

I was trying to avoid having so make "check-acceptance-*" rules that just
choosing one would be harder than writing an Avocado command line from
scratch... but I think you have a point here.  For once, this can be
used in a Travis job with an special "allow_failures" option set.

> Side note: check-acceptance seems to get growing in complexity that I worry
> will end up in pitfalls. is a Make target the proper way to implement
> complex test runs (I don't think so). Perhaps Avocado runner concept could
> help somehow?
>

I guess you mean the Avocado Job concept, and writing your own runner
based on those APIs.  If so, then absolutely yes.  I've shared with
Eduardo some of the use cases that we can solve much easily.  But, we
need to finish the last bits on the Avocado side, properly document
and support the API before attempting to use it here on QEMU.

> > > > 
> > > > The current list of tests marked as flaky are a result of running
> > > > the entire set of acceptance tests around 20 times.  The results
> > > > were then processed with a helper script[1].  That either confirmed
> > > > known issues (in the case of aarch64 and arm)[2] or revealed new
> > > > ones (mips).
> > > > 
> > > > This also bumps the Avocado version to one that includes a fix to the
> > > > parsing of multiple and mix "key:val" and simple tag values.
> > > > 
> > > > [1] 
> > > > https://raw.githubusercontent.com/avocado-framework/avocado/master/contrib/scripts/summarize-job-failures.py
> > > > [2] https://bugs.launchpad.net/qemu/+bug/1829779
> > > > 
> > > > Signed-off-by: Cleber Rosa 
> > > > ---
> > > >   docs/devel/testing.rst   | 17 +
> > > >   tests/Makefile.include   |  6 +-
> > > >   tests/acceptance/boot_linux_console.py   |  2 ++
> > > >   tests/acceptance/linux_ssh_mips_malta.py |  2 ++
> > > >   tests/requirements.txt   |  2 +-
> > > >   5 files changed, 27 insertions(+), 2 deletions(-)
> > > > 
> > > > diff --git a/docs/devel/testing.rst b/docs/devel/testing.rst
> > > > index da2d0fc964..ff4d8e2e1c 100644
> > > > --- a/docs/devel/testing.rst
> > > > +++ b/docs/devel/testing.rst
> > > > @@ -574,6 +574,23 @@ may be invoked by running:
> > > > tests/venv/bin/avocado run $OPTION1 $OPTION2 tests/acceptance/
> > > > +Tagging tests
> > > > +-
> > > > +
> > > > +flaky
> > > > +~
> > > > +
> > > > +If a test is known to fail intermittently, even if only every one
> > > > +hundredth time, it's highly advisable to mark it as a flaky test.
> > > > +This will prevent these individual tests from failing much larger
> > > > +jobs, will avoid human interaction and time wasted to verify a known
> > > > +issue, and worse of all, can lead to the discredit of automated
> > > > +testing.
> > > > +
> > > > +To mark a test as flaky, add to its docstring.::
> > > > +
> > > > +  :avocado: tags=flaky
> > > I certainly disagree with this patch, failing tests have to be fixed.
> > > Why not tag all the codebase flaky and sing "happy coding"?
> > > 
> > That's a great idea! :)
> > 
> > Now, seriously, I also resisted this for quite a long time.  The
> > reality, though, is that intermittent failures will continue to
> > appear, and letting tests (and jobs, and CI pipelines, and whatnot)
> > fail is a very bad idea.  We all agree that real fixes are better than
> > this, but many times they don't come quickly.
> 
> It seems to me that flaky test is just a case in a broaden scenario: run (or
> not) grouped tests. You 

Re: [Qemu-devel] [PATCH 3/3] tests/acceptance: Add boot linux with kvm test

2019-06-30 Thread Cleber Rosa
On Fri, Jun 28, 2019 at 05:18:46PM -0300, Eduardo Habkost wrote:
> On Fri, Jun 28, 2019 at 11:02:17AM -0400, Wainer dos Santos Moschetta wrote:
> > Until now the suite of acceptance tests doesn't exercise
> > QEMU with kvm enabled. So this introduces a simple test
> > that boots the Linux kernel and checks it boots on the
> > accelerator correctly.
> > 
> > Signed-off-by: Wainer dos Santos Moschetta 
> 
> Why not just change the existing test_x86_64_pc() test case to
> use KVM by default?  We can use "accel=kvm:tcg" to allow it to
> fall back to TCG if KVM is not available.
> 
> -- 
> Eduardo

I though of something similar, but not exactly the same.  An example
can be seen here:

  https://travis-ci.org/clebergnu/qemu/jobs/551437429#L3350

IMO, it's a good practice to be able to briefly describe what a test
does, given its name.  It's also very important for the test to
attempt to exercise the same behavior across executions.

I'm saying that because I don't think we should fallback to TCG if KVM
is not available, but instead, have two different tests that do each a
simpler and more predictable set of checks.  This would make it
simpler to find KVM issues when a given test fails but the TCG
continues to pass.  The tags (and other mechanisms) can be used to
select the tests that a given job should run though.

Regards!
- Cleber.



[Qemu-devel] [PATCH 1/5] sunhme: add trace event for logging PCI IRQ

2019-06-30 Thread Mark Cave-Ayland
Signed-off-by: Mark Cave-Ayland 
---
 hw/net/sunhme.c | 2 ++
 hw/net/trace-events | 1 +
 2 files changed, 3 insertions(+)

diff --git a/hw/net/sunhme.c b/hw/net/sunhme.c
index 1ebaee3c82..6d660a8238 100644
--- a/hw/net/sunhme.c
+++ b/hw/net/sunhme.c
@@ -209,6 +209,8 @@ static void sunhme_update_irq(SunHMEState *s)
 }
 
 level = (seb ? 1 : 0);
+trace_sunhme_update_irq(mifmask, mif, sebmask, seb, level);
+
 pci_set_irq(d, level);
 }
 
diff --git a/hw/net/trace-events b/hw/net/trace-events
index 3cd9e122df..d16273c579 100644
--- a/hw/net/trace-events
+++ b/hw/net/trace-events
@@ -359,6 +359,7 @@ sunhme_rx_filter_reject(void) "rejecting incoming frame"
 sunhme_rx_filter_accept(void) "accepting incoming frame"
 sunhme_rx_desc(uint32_t addr, int offset, uint32_t status, int len, int cr, 
int nr) "addr 0x%"PRIx32"(+0x%x) status 0x%"PRIx32 " len %d (ring %d/%d)"
 sunhme_rx_xsum_calc(uint16_t xsum) "calculated incoming xsum as 0x%x"
+sunhme_update_irq(uint32_t mifmask, uint32_t mif, uint32_t sebmask, uint32_t 
seb, int level) "mifmask: 0x%x  mif: 0x%x  sebmask: 0x%x  seb: 0x%x  level: %d"
 
 # virtio-net.c
 virtio_net_announce_notify(void) ""
-- 
2.11.0




[Qemu-devel] [PATCH 5/5] sunhme: ensure that RX descriptor ring overflow is indicated to client driver

2019-06-30 Thread Mark Cave-Ayland
On very busy networks connected via a tap interface, it is possible to overflow
the RX descriptor ring in the time between the client driver enabling the RX
MAC and finishing writing the final configuration to the NIC registers.

Ensure that we detect this condition and update the status register accordingly
to indicate an overflow has occurred (and the incoming packet dropped) in order
to prevent the client driver becoming confused.

Signed-off-by: Mark Cave-Ayland 
---
 hw/net/sunhme.c | 9 +
 hw/net/trace-events | 1 +
 2 files changed, 10 insertions(+)

diff --git a/hw/net/sunhme.c b/hw/net/sunhme.c
index cd076d642b..8b8603e696 100644
--- a/hw/net/sunhme.c
+++ b/hw/net/sunhme.c
@@ -44,6 +44,7 @@
 #define HME_SEBI_STAT  0x100
 #define HME_SEBI_STAT_LINUXBUG 0x108
 #define HME_SEB_STAT_RXTOHOST  0x1
+#define HME_SEB_STAT_NORXD 0x2
 #define HME_SEB_STAT_MIFIRQ0x80
 #define HME_SEB_STAT_HOSTTOTX  0x100
 #define HME_SEB_STAT_TXALL 0x200
@@ -787,6 +788,14 @@ static ssize_t sunhme_receive(NetClientState *nc, const 
uint8_t *buf,
 pci_dma_read(d, rb + cr * HME_DESC_SIZE, , 4);
 pci_dma_read(d, rb + cr * HME_DESC_SIZE + 4, , 4);
 
+/* If we don't own the current descriptor then indicate overflow error */
+if (!(status & HME_XD_OWN)) {
+s->sebregs[HME_SEBI_STAT >> 2] |= HME_SEB_STAT_NORXD;
+sunhme_update_irq(s);
+trace_sunhme_rx_norxd();
+return -1;
+}
+
 rxoffset = (s->erxregs[HME_ERXI_CFG >> 2] & HME_ERX_CFG_BYTEOFFSET) >>
 HME_ERX_CFG_BYTEOFFSET_SHIFT;
 
diff --git a/hw/net/trace-events b/hw/net/trace-events
index d16273c579..58665655cc 100644
--- a/hw/net/trace-events
+++ b/hw/net/trace-events
@@ -359,6 +359,7 @@ sunhme_rx_filter_reject(void) "rejecting incoming frame"
 sunhme_rx_filter_accept(void) "accepting incoming frame"
 sunhme_rx_desc(uint32_t addr, int offset, uint32_t status, int len, int cr, 
int nr) "addr 0x%"PRIx32"(+0x%x) status 0x%"PRIx32 " len %d (ring %d/%d)"
 sunhme_rx_xsum_calc(uint16_t xsum) "calculated incoming xsum as 0x%x"
+sunhme_rx_norxd(void) "no free rx descriptors available"
 sunhme_update_irq(uint32_t mifmask, uint32_t mif, uint32_t sebmask, uint32_t 
seb, int level) "mifmask: 0x%x  mif: 0x%x  sebmask: 0x%x  seb: 0x%x  level: %d"
 
 # virtio-net.c
-- 
2.11.0




[Qemu-devel] [PATCH 4/5] sunhme: fix return values from sunhme_receive() during receive packet processing

2019-06-30 Thread Mark Cave-Ayland
The current return values in sunhme_receive() when processing incoming packets
are inverted from what they should be. Make sure that we return 0 to indicate
the packet was discarded (and polling is to be disabled) and -1 to indicate
that the packet was discarded but polling for incoming data is to be continued.

Signed-off-by: Mark Cave-Ayland 
---
 hw/net/sunhme.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/net/sunhme.c b/hw/net/sunhme.c
index 14e7effb88..cd076d642b 100644
--- a/hw/net/sunhme.c
+++ b/hw/net/sunhme.c
@@ -728,7 +728,7 @@ static ssize_t sunhme_receive(NetClientState *nc, const 
uint8_t *buf,
 
 /* Do nothing if MAC RX disabled */
 if (!(s->macregs[HME_MACI_RXCFG >> 2] & HME_MAC_RXCFG_ENABLE)) {
-return -1;
+return 0;
 }
 
 trace_sunhme_rx_filter_destmac(buf[0], buf[1], buf[2],
@@ -757,14 +757,14 @@ static ssize_t sunhme_receive(NetClientState *nc, const 
uint8_t *buf,
 /* Didn't match hash filter */
 trace_sunhme_rx_filter_hash_nomatch();
 trace_sunhme_rx_filter_reject();
-return 0;
+return -1;
 } else {
 trace_sunhme_rx_filter_hash_match();
 }
 } else {
 /* Not for us */
 trace_sunhme_rx_filter_reject();
-return 0;
+return -1;
 }
 } else {
 trace_sunhme_rx_filter_promisc_match();
-- 
2.11.0




[Qemu-devel] [PATCH 2/5] sunhme: fix incorrect constant in sunhme_can_receive()

2019-06-30 Thread Mark Cave-Ayland
Due to a copy/paste error the wrong register was being checked in order to
determine if the NIC is able to receive data.

Signed-off-by: Mark Cave-Ayland 
---
 hw/net/sunhme.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/net/sunhme.c b/hw/net/sunhme.c
index 6d660a8238..e3a488ee1d 100644
--- a/hw/net/sunhme.c
+++ b/hw/net/sunhme.c
@@ -649,7 +649,7 @@ static int sunhme_can_receive(NetClientState *nc)
 {
 SunHMEState *s = qemu_get_nic_opaque(nc);
 
-return s->macregs[HME_MAC_RXCFG_ENABLE >> 2] & HME_MAC_RXCFG_ENABLE;
+return s->macregs[HME_MACI_RXCFG >> 2] & HME_MAC_RXCFG_ENABLE;
 }
 
 static void sunhme_link_status_changed(NetClientState *nc)
-- 
2.11.0




[Qemu-devel] [PATCH 0/5] sunhme: misc fixes for tap mode

2019-06-30 Thread Mark Cave-Ayland
This patchset contains a set of fixes found whilst investigating some privately
reported issues when using the sunhme device in tap mode on a busy network.

The first patch simply adds a trace-event for logging the PCI IRQ which was
useful in help diagnose the issues in the subsequent patches.

Patches 2-4 fix errors in enabling and disabling the receiver found during
local testing with NetBSD which toggles the receiver state on startup.

Finally patch 5 fixes a bug whereby on a busy network it is possible to
overflow the descriptor ring and therefore we must report this back correctly
to the OS to allow it to handle the situation accordingly.

Signed-off-by: Mark Cave-Ayland 

Mark Cave-Ayland (5):
  sunhme: add trace event for logging PCI IRQ
  sunhme: fix incorrect constant in sunhme_can_receive()
  sunhme: flush any queued packets when HME_MAC_RXCFG_ENABLE bit is
raised
  sunhme: fix return values from sunhme_receive() during receive packet
processing
  sunhme: ensure that RX descriptor ring overflow is indicated to client
driver

 hw/net/sunhme.c | 29 +
 hw/net/trace-events |  2 ++
 2 files changed, 27 insertions(+), 4 deletions(-)

-- 
2.11.0




[Qemu-devel] [PATCH 3/5] sunhme: flush any queued packets when HME_MAC_RXCFG_ENABLE bit is raised

2019-06-30 Thread Mark Cave-Ayland
Some client drivers use this bit to pause and resume the driver so make sure
that queued packets are flushed when the MAC is disabled and then reactivated.

Signed-off-by: Mark Cave-Ayland 
---
 hw/net/sunhme.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/hw/net/sunhme.c b/hw/net/sunhme.c
index e3a488ee1d..14e7effb88 100644
--- a/hw/net/sunhme.c
+++ b/hw/net/sunhme.c
@@ -373,10 +373,20 @@ static void sunhme_mac_write(void *opaque, hwaddr addr,
   uint64_t val, unsigned size)
 {
 SunHMEState *s = SUNHME(opaque);
+uint64_t oldval = s->macregs[addr >> 2];
 
 trace_sunhme_mac_write(addr, val);
 
 s->macregs[addr >> 2] = val;
+
+switch (addr) {
+case HME_MACI_RXCFG:
+if (!(oldval & HME_MAC_RXCFG_ENABLE) &&
+ (val & HME_MAC_RXCFG_ENABLE)) {
+qemu_flush_queued_packets(qemu_get_queue(s->nic));
+}
+break;
+}
 }
 
 static uint64_t sunhme_mac_read(void *opaque, hwaddr addr,
-- 
2.11.0




Re: [Qemu-devel] [PATCH v16 1/5] linux-user: Add support for translation of statx() syscall

2019-06-30 Thread Aleksandar Markovic
On Jun 29, 2019 6:06 AM, "Jim Wilson"  wrote:
>
> On Fri, Jun 28, 2019 at 5:53 PM Aleksandar Markovic
>  wrote:
> > This patch went trough several transformations in last few days, and I
am a little worried that we forgot the primary reasons/scenarios why want
it in the first place. In that light, may I ask you to recheck this latest
version of the patch, v16, against your scenarios (you mentioned earlier
you have two significantly different flavors of your scenario, one with
Ubuntu 16, and another with Ubuntu 19)?
>
> My use case is that I want 32-bit RISC-V user mode to work.  This
> requires a riscv syscall list patch that Palmer Dabbelt added to his
> patch set, and the statx patch that is part of your patch set.  The
> statx strace support is not required for this use case, but should be
> added for completeness as all of the other stat family functions have
> strace support, so statx should too.  Since the statx strace patch
> needs statx macros that old systems don't have, I test on Ubuntu 16
> (no host statx) and Ubuntu 19 (with host statx).  On Ubuntu 19, statx
> strace should be fully pretty printed.  On Ubuntu 16, qemu should
> still build despite the missing macros, and statx strace should be
> partially pretty printed because of the missing macros.
>
> I removed the old patches, updated qemu, added the new patches,
> rebuilt qemu, and reran the gcc testsuite for rv32/rv64 Ubuntu 16/19
> and it still works as expected.  I also manually checked strace for
> rv32/rv64 Ubuntu 16/19 and that also still works as expected.  So this
> looks good to me.
>

Thanks a bunch, Jim! Laurent, based on all the info, it looks to me v16 is
the way to go. Aleksandar R. can test his nanoMips scenarios later on,
since nanoMips user mode is not integrated yet anyway, but I hope
everything is fine there too.

Thanks again to all involved!

Aleksandar

> I'm leaving on a trip tomorrow, and only taking one laptop with me, so
> I won't have access to my Ubuntu 19 machine anymore.
>
> Jim


[Qemu-devel] [PATCH] hw/arm/virt: Add support for Cortex-A7

2019-06-30 Thread Jan Kiszka
From: Jan Kiszka 

No reason to deny this type.

Signed-off-by: Jan Kiszka 
---
 hw/arm/virt.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 431e2900fd..ed009fa447 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -176,6 +176,7 @@ static const int a15irqmap[] = {
 };

 static const char *valid_cpus[] = {
+ARM_CPU_TYPE_NAME("cortex-a7"),
 ARM_CPU_TYPE_NAME("cortex-a15"),
 ARM_CPU_TYPE_NAME("cortex-a53"),
 ARM_CPU_TYPE_NAME("cortex-a57"),
--
2.16.4



Re: [Qemu-devel] [PATCH v6 15/16] tcg/ppc: Update vector support to v2.07

2019-06-30 Thread Richard Henderson
On 6/30/19 3:37 PM, Aleksandar Markovic wrote:
>>  bool have_isa_2_06;
>>  bool have_isa_2_06_vsx;
>> +bool have_isa_2_07_vsx;
> 
> Does this flag indicate support for PowerISA 2.07 or VSX?

VSX & 2.07,

>> +    if (hwcap2 & PPC_FEATURE2_ARCH_2_07) {
>> +        if (hwcap & PPC_FEATURE_HAS_VSX) {
>> +            have_isa_2_07_vsx = true;
>> +        }
>> +    }

Like so.

While it would have been possible to have one single have_isa_vsx, we would
then also have to check a second flag to see which revision.  Therefore I
created these composite flags so that we only have to check one.


r~



[Qemu-devel] [PATCH 1/1] raw-posix.c - use max transfer length / max segemnt count only for SCSI passthrough

2019-06-30 Thread Maxim Levitsky
Regular block devices (/dev/sda*, /dev/nvme*, etc) interface is not limited
by the underlying storage limits, but rather the kernel block layer
takes care to split the requests that are too large/fragmented.

Doing so allows us to have less overhead in qemu.

Signed-off-by: Maxim Levitsky 
---
 block/file-posix.c | 16 +++-
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/block/file-posix.c b/block/file-posix.c
index ab05b51a66..66dad34f8a 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -1038,15 +1038,13 @@ static void raw_reopen_abort(BDRVReopenState *state)
 s->reopen_state = NULL;
 }
 
-static int hdev_get_max_transfer_length(BlockDriverState *bs, int fd)
+static int sg_get_max_transfer_length(BlockDriverState *bs, int fd)
 {
 #ifdef BLKSECTGET
 int max_bytes = 0;
-short max_sectors = 0;
-if (bs->sg && ioctl(fd, BLKSECTGET, _bytes) == 0) {
+
+if (ioctl(fd, BLKSECTGET, _bytes) == 0) {
 return max_bytes;
-} else if (!bs->sg && ioctl(fd, BLKSECTGET, _sectors) == 0) {
-return max_sectors << BDRV_SECTOR_BITS;
 } else {
 return -errno;
 }
@@ -1055,7 +1053,7 @@ static int hdev_get_max_transfer_length(BlockDriverState 
*bs, int fd)
 #endif
 }
 
-static int hdev_get_max_segments(const struct stat *st)
+static int sg_get_max_segments(const struct stat *st)
 {
 #ifdef CONFIG_LINUX
 char buf[32];
@@ -1106,12 +1104,12 @@ static void raw_refresh_limits(BlockDriverState *bs, 
Error **errp)
 struct stat st;
 
 if (!fstat(s->fd, )) {
-if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode)) {
-int ret = hdev_get_max_transfer_length(bs, s->fd);
+if (bs->sg) {
+int ret = sg_get_max_transfer_length(bs, s->fd);
 if (ret > 0 && ret <= BDRV_REQUEST_MAX_BYTES) {
 bs->bl.max_transfer = pow2floor(ret);
 }
-ret = hdev_get_max_segments();
+ret = sg_get_max_segments();
 if (ret > 0) {
 bs->bl.max_transfer = MIN(bs->bl.max_transfer,
   ret * getpagesize());
-- 
2.17.2




[Qemu-devel] [PATCH 0/1] RFC: don't obey the block device max transfer len / max segments for block devices

2019-06-30 Thread Maxim Levitsky
It looks like Linux block devices, even in O_DIRECT mode don't have any user 
visible
limit on transfer size / number of segments, which underlying block device can 
have.
The block layer takes care of enforcing these limits by splitting the bios.

By limiting the transfer sizes, we  force qemu to do the splitting itself which
introduces various overheads.
It is especially visible in nbd server, where the low max transfer size of the
underlying device forces us to advertise this over NBD, thus increasing the 
traffic overhead in case of
image conversion which benefits from large blocks.

More information can be found here:
https://bugzilla.redhat.com/show_bug.cgi?id=1647104

Tested this with qemu-img convert over nbd and natively and to my surprise, 
even native IO performance improved a bit.
(The device on which it was tested is Intel Optane DC P4800X, which has 128k 
max transfer size)

The benchmark:

Images were created using:

Sparse image:  qemu-img create -f qcow2 /dev/nvme0n1p3 1G / 10G / 100G
Allocated image: qemu-img create -f qcow2 /dev/nvme0n1p3 -o 
preallocation=metadata  1G / 10G / 100G

The test was:

 echo "convert native:"
 rm -rf /dev/shm/disk.img
 time qemu-img convert -p -f qcow2 -O raw -T none $FILE /dev/shm/disk.img > 
/dev/zero

 echo "convert via nbd:"
 qemu-nbd -k /tmp/nbd.sock -v  -f qcow2 $FILE -x export --cache=none 
--aio=native --fork
 rm -rf /dev/shm/disk.img
 time qemu-img convert -p -f raw -O raw 
nbd:unix:/tmp/nbd.sock:exportname=export /dev/shm/disk.img > /dev/zero

The results:

=
1G sparse image:
 native:
before: 0.027s
after: 0.027s
 nbd:
before: 0.287s
after: 0.035s

=
100G sparse image:
 native:
before: 0.028s
after: 0.028s
 nbd:
before: 23.796s
after: 0.109s

=
1G preallocated image:
 native:
   before: 0.454s
   after: 0.427s
 nbd:
   before: 0.649s
   after: 0.546s

The block limits of max transfer size/max segment size are retained
for the SCSI passthrough because in this case the kernel passes the userspace 
request
directly to the kernel scsi driver, bypassing the block layer, and thus there 
is no code to split
such requests.

What do you think?

Fam, since you was the original author of the code that added
these limits, could you share your opinion on that?
What was the reason besides SCSI passthrough?

Best regards,
Maxim Levitsky

Maxim Levitsky (1):
  raw-posix.c - use max transfer length / max segemnt count only for
SCSI passthrough

 block/file-posix.c | 16 +++-
 1 file changed, 7 insertions(+), 9 deletions(-)

-- 
2.17.2




Re: [Qemu-devel] [PATCH v6 15/16] tcg/ppc: Update vector support to v2.07

2019-06-30 Thread Aleksandar Markovic
On Jun 29, 2019 3:14 PM, "Richard Henderson" 
wrote:
>
> This includes single-word loads and stores, lots of double-word
> arithmetic, and a few extra logical operations.
>
> Signed-off-by: Richard Henderson 
> Signed-off-by: Aleksandar Markovic 
> ---
>  tcg/ppc/tcg-target.h |   3 +-
>  tcg/ppc/tcg-target.inc.c | 128 ++-
>  2 files changed, 103 insertions(+), 28 deletions(-)
>
> diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
> index 40544f996d..b8355d0a56 100644
> --- a/tcg/ppc/tcg-target.h
> +++ b/tcg/ppc/tcg-target.h
> @@ -61,6 +61,7 @@ typedef enum {
>  extern bool have_isa_altivec;
>  extern bool have_isa_2_06;
>  extern bool have_isa_2_06_vsx;
> +extern bool have_isa_2_07_vsx;
>  extern bool have_isa_3_00;
>
>  /* optional instructions automatically implemented */
> @@ -147,7 +148,7 @@ extern bool have_isa_3_00;
>  #define TCG_TARGET_HAS_v256 0
>
>  #define TCG_TARGET_HAS_andc_vec 1
> -#define TCG_TARGET_HAS_orc_vec  0
> +#define TCG_TARGET_HAS_orc_vec  have_isa_2_07_vsx
>  #define TCG_TARGET_HAS_not_vec  1
>  #define TCG_TARGET_HAS_neg_vec  0
>  #define TCG_TARGET_HAS_abs_vec  0
> diff --git a/tcg/ppc/tcg-target.inc.c b/tcg/ppc/tcg-target.inc.c
> index 50d1b5612c..af86ab07dd 100644
> --- a/tcg/ppc/tcg-target.inc.c
> +++ b/tcg/ppc/tcg-target.inc.c
> @@ -67,6 +67,7 @@ static tcg_insn_unit *tb_ret_addr;
>  bool have_isa_altivec;
>  bool have_isa_2_06;
>  bool have_isa_2_06_vsx;
> +bool have_isa_2_07_vsx;

Does this flag indicate support for PowerISA 2.07 or VSX?

If VSX support is implied by PowerISA 2.07, then “_vsx” suffix is really
not needed. If not, why are there two flavors of “2_06” flags (with and
without _vsx), and only one flavor if 2.07 (with _vsx) flg variables?

>  bool have_isa_3_00;
>
>  #define HAVE_ISA_2_06  have_isa_2_06
> @@ -473,10 +474,12 @@ static int tcg_target_const_match(tcg_target_long
val, TCGType type,
>  #define LVEWX  XO31(71)
>  #define LXSDX  XO31(588)  /* v2.06 */
>  #define LXVDSX XO31(332)  /* v2.06 */
> +#define LXSIWZXXO31(12)   /* v2.07 */
>
>  #define STVX   XO31(231)
>  #define STVEWX XO31(199)
>  #define STXSDX XO31(716)  /* v2.06 */
> +#define STXSIWXXO31(140)  /* v2.07 */
>
>  #define VADDSBSVX4(768)
>  #define VADDUBSVX4(512)
> @@ -487,6 +490,7 @@ static int tcg_target_const_match(tcg_target_long
val, TCGType type,
>  #define VADDSWSVX4(896)
>  #define VADDUWSVX4(640)
>  #define VADDUWMVX4(128)
> +#define VADDUDMVX4(192)   /* v2.07 */
>
>  #define VSUBSBSVX4(1792)
>  #define VSUBUBSVX4(1536)
> @@ -497,47 +501,62 @@ static int tcg_target_const_match(tcg_target_long
val, TCGType type,
>  #define VSUBSWSVX4(1920)
>  #define VSUBUWSVX4(1664)
>  #define VSUBUWMVX4(1152)
> +#define VSUBUDMVX4(1216)  /* v2.07 */
>
>  #define VMAXSB VX4(258)
>  #define VMAXSH VX4(322)
>  #define VMAXSW VX4(386)
> +#define VMAXSD VX4(450)   /* v2.07 */
>  #define VMAXUB VX4(2)
>  #define VMAXUH VX4(66)
>  #define VMAXUW VX4(130)
> +#define VMAXUD VX4(194)   /* v2.07 */
>  #define VMINSB VX4(770)
>  #define VMINSH VX4(834)
>  #define VMINSW VX4(898)
> +#define VMINSD VX4(962)   /* v2.07 */
>  #define VMINUB VX4(514)
>  #define VMINUH VX4(578)
>  #define VMINUW VX4(642)
> +#define VMINUD VX4(706)   /* v2.07 */
>
>  #define VCMPEQUB   VX4(6)
>  #define VCMPEQUH   VX4(70)
>  #define VCMPEQUW   VX4(134)
> +#define VCMPEQUD   VX4(199)   /* v2.07 */
>  #define VCMPGTSB   VX4(774)
>  #define VCMPGTSH   VX4(838)
>  #define VCMPGTSW   VX4(902)
> +#define VCMPGTSD   VX4(967)   /* v2.07 */
>  #define VCMPGTUB   VX4(518)
>  #define VCMPGTUH   VX4(582)
>  #define VCMPGTUW   VX4(646)
> +#define VCMPGTUD   VX4(711)   /* v2.07 */
>
>  #define VSLB   VX4(260)
>  #define VSLH   VX4(324)
>  #define VSLW   VX4(388)
> +#define VSLD   VX4(1476)  /* v2.07 */
>  #define VSRB   VX4(516)
>  #define VSRH   VX4(580)
>  #define VSRW   VX4(644)
> +#define VSRD   VX4(1732)  /* v2.07 */
>  #define VSRAB  VX4(772)
>  #define VSRAH  VX4(836)
>  #define VSRAW  VX4(900)
> +#define VSRAD  VX4(964)   /* v2.07 */
>  #define VRLB   VX4(4)
>  #define VRLH   VX4(68)
>  #define VRLW   VX4(132)
> +#define VRLD   VX4(196)   /* v2.07 */
>
>  #define VMULEUBVX4(520)
>  #define VMULEUHVX4(584)
> +#define VMULEUWVX4(648)   /* v2.07 */
>  #define VMULOUBVX4(8)
>  #define VMULOUHVX4(72)
> +#define VMULOUWVX4(136)   /* v2.07 */
> +#define VMULUWMVX4(137)   /* v2.07 */
>  #define VMSUMUHM   VX4(38)
>
>  #define VMRGHB VX4(12)
> @@ -555,6 +574,9 @@ static int tcg_target_const_match(tcg_target_long
val, TCGType type,
>  #define VNOR   VX4(1284)
>  #define VORVX4(1156)
>  #define VXOR   VX4(1220)
> 

Re: [Qemu-devel] [PATCH v6 15/16] tcg/ppc: Update vector support to v2.07

2019-06-30 Thread Aleksandar Markovic
On Jun 29, 2019 3:14 PM, "Richard Henderson" 
wrote:
>
> This includes single-word loads and stores, lots of double-word
> arithmetic, and a few extra logical operations.
>

This patch should be split into several units (so, treat shift, compare,
etc. separately).

The same for other similar patches from this series.

> Signed-off-by: Richard Henderson 
> Signed-off-by: Aleksandar Markovic 
> ---
>  tcg/ppc/tcg-target.h |   3 +-
>  tcg/ppc/tcg-target.inc.c | 128 ++-
>  2 files changed, 103 insertions(+), 28 deletions(-)
>
> diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
> index 40544f996d..b8355d0a56 100644
> --- a/tcg/ppc/tcg-target.h
> +++ b/tcg/ppc/tcg-target.h
> @@ -61,6 +61,7 @@ typedef enum {
>  extern bool have_isa_altivec;
>  extern bool have_isa_2_06;
>  extern bool have_isa_2_06_vsx;
> +extern bool have_isa_2_07_vsx;
>  extern bool have_isa_3_00;
>
>  /* optional instructions automatically implemented */
> @@ -147,7 +148,7 @@ extern bool have_isa_3_00;
>  #define TCG_TARGET_HAS_v256 0
>
>  #define TCG_TARGET_HAS_andc_vec 1
> -#define TCG_TARGET_HAS_orc_vec  0
> +#define TCG_TARGET_HAS_orc_vec  have_isa_2_07_vsx
>  #define TCG_TARGET_HAS_not_vec  1
>  #define TCG_TARGET_HAS_neg_vec  0
>  #define TCG_TARGET_HAS_abs_vec  0
> diff --git a/tcg/ppc/tcg-target.inc.c b/tcg/ppc/tcg-target.inc.c
> index 50d1b5612c..af86ab07dd 100644
> --- a/tcg/ppc/tcg-target.inc.c
> +++ b/tcg/ppc/tcg-target.inc.c
> @@ -67,6 +67,7 @@ static tcg_insn_unit *tb_ret_addr;
>  bool have_isa_altivec;
>  bool have_isa_2_06;
>  bool have_isa_2_06_vsx;
> +bool have_isa_2_07_vsx;
>  bool have_isa_3_00;
>
>  #define HAVE_ISA_2_06  have_isa_2_06
> @@ -473,10 +474,12 @@ static int tcg_target_const_match(tcg_target_long
val, TCGType type,
>  #define LVEWX  XO31(71)
>  #define LXSDX  XO31(588)  /* v2.06 */
>  #define LXVDSX XO31(332)  /* v2.06 */
> +#define LXSIWZXXO31(12)   /* v2.07 */
>
>  #define STVX   XO31(231)
>  #define STVEWX XO31(199)
>  #define STXSDX XO31(716)  /* v2.06 */
> +#define STXSIWXXO31(140)  /* v2.07 */
>
>  #define VADDSBSVX4(768)
>  #define VADDUBSVX4(512)
> @@ -487,6 +490,7 @@ static int tcg_target_const_match(tcg_target_long
val, TCGType type,
>  #define VADDSWSVX4(896)
>  #define VADDUWSVX4(640)
>  #define VADDUWMVX4(128)
> +#define VADDUDMVX4(192)   /* v2.07 */
>
>  #define VSUBSBSVX4(1792)
>  #define VSUBUBSVX4(1536)
> @@ -497,47 +501,62 @@ static int tcg_target_const_match(tcg_target_long
val, TCGType type,
>  #define VSUBSWSVX4(1920)
>  #define VSUBUWSVX4(1664)
>  #define VSUBUWMVX4(1152)
> +#define VSUBUDMVX4(1216)  /* v2.07 */
>
>  #define VMAXSB VX4(258)
>  #define VMAXSH VX4(322)
>  #define VMAXSW VX4(386)
> +#define VMAXSD VX4(450)   /* v2.07 */
>  #define VMAXUB VX4(2)
>  #define VMAXUH VX4(66)
>  #define VMAXUW VX4(130)
> +#define VMAXUD VX4(194)   /* v2.07 */
>  #define VMINSB VX4(770)
>  #define VMINSH VX4(834)
>  #define VMINSW VX4(898)
> +#define VMINSD VX4(962)   /* v2.07 */
>  #define VMINUB VX4(514)
>  #define VMINUH VX4(578)
>  #define VMINUW VX4(642)
> +#define VMINUD VX4(706)   /* v2.07 */
>
>  #define VCMPEQUB   VX4(6)
>  #define VCMPEQUH   VX4(70)
>  #define VCMPEQUW   VX4(134)
> +#define VCMPEQUD   VX4(199)   /* v2.07 */
>  #define VCMPGTSB   VX4(774)
>  #define VCMPGTSH   VX4(838)
>  #define VCMPGTSW   VX4(902)
> +#define VCMPGTSD   VX4(967)   /* v2.07 */
>  #define VCMPGTUB   VX4(518)
>  #define VCMPGTUH   VX4(582)
>  #define VCMPGTUW   VX4(646)
> +#define VCMPGTUD   VX4(711)   /* v2.07 */
>
>  #define VSLB   VX4(260)
>  #define VSLH   VX4(324)
>  #define VSLW   VX4(388)
> +#define VSLD   VX4(1476)  /* v2.07 */
>  #define VSRB   VX4(516)
>  #define VSRH   VX4(580)
>  #define VSRW   VX4(644)
> +#define VSRD   VX4(1732)  /* v2.07 */
>  #define VSRAB  VX4(772)
>  #define VSRAH  VX4(836)
>  #define VSRAW  VX4(900)
> +#define VSRAD  VX4(964)   /* v2.07 */
>  #define VRLB   VX4(4)
>  #define VRLH   VX4(68)
>  #define VRLW   VX4(132)
> +#define VRLD   VX4(196)   /* v2.07 */
>
>  #define VMULEUBVX4(520)
>  #define VMULEUHVX4(584)
> +#define VMULEUWVX4(648)   /* v2.07 */
>  #define VMULOUBVX4(8)
>  #define VMULOUHVX4(72)
> +#define VMULOUWVX4(136)   /* v2.07 */
> +#define VMULUWMVX4(137)   /* v2.07 */
>  #define VMSUMUHM   VX4(38)
>
>  #define VMRGHB VX4(12)
> @@ -555,6 +574,9 @@ static int tcg_target_const_match(tcg_target_long
val, TCGType type,
>  #define VNOR   VX4(1284)
>  #define VORVX4(1156)
>  #define VXOR   VX4(1220)
> +#define VEQV   VX4(1668)  /* v2.07 */
> +#define VNAND  VX4(1412)  /* v2.07 */
> +#define VORC   VX4(1348)  

Re: [Qemu-devel] [PATCH v6 04/16] tcg/ppc: Enable tcg backend vector compilation

2019-06-30 Thread Aleksandar Markovic
On Jun 30, 2019 12:48 PM, "Richard Henderson" 
wrote:
>
> On 6/30/19 11:46 AM, Aleksandar Markovic wrote:
> >
> >
> > On Saturday, June 29, 2019, Richard Henderson <
richard.hender...@linaro.org
> > > wrote:
> >
> > Introduce all of the flags required to enable tcg backend vector
support,
> > and a runtime flag to indicate the host supports Altivec
instructions.
> >
> >
> > If two flags have different purpose and usage, it is better that they
> > have different names. (perhaps one of them should have the suffix
“_runtime“)
>
> Huh?  They do have different names.  Very different names.
>

They do. If you leave the same name, you would make any search for that
name during future debugging/development more difficult.

> > Also, I am not sure if Altiveec can be reffered as isa, it is a
part/extension
> > of an isa, so “isa” seems  superfluous here.
>
> It also matches the other existing names, so I'll leave it as is.
>

If something is wrong in the old code, it does not mean one should continue
the same practice.

> > checkpatch warning should also be honored.
>
> It's bogus.

I don't think it is bogus. The comment should be converted to a regular
one-line ot perhaps multiline comment before if-statement. Althoug it may
be correct in the sense of C-syntax, noone expects coment to be inlined
into if-condition, and it makes the code feel obfuscated, rather than clear.

> > WARNING: Block comments use a leading /* on a separate line
> > #155: FILE: tcg/ppc/tcg-target.inc.c:2842:
> > +if (hwcap & /* PPC_FEATURE_HAS_ALTIVEC -- NOT YET */ 0) {
>
> It's not a block comment; the whole thing is on one line.
> I have no idea why it doesn't notice.
>
> In any case, this goes away in patch 13.
>
>
> r~


Re: [Qemu-devel] [PATCH v6 09/16] tcg/ppc: Prepare case for vector multiply

2019-06-30 Thread Aleksandar Markovic
On Jun 30, 2019 12:49 PM, "Richard Henderson" 
wrote:
>
> On 6/30/19 11:52 AM, Aleksandar Markovic wrote:
> >
> >
> > On Saturday, June 29, 2019, Richard Henderson <
richard.hender...@linaro.org
> > > wrote:
> >
> > This line is just preparation for full vector multiply support
> > in some of subsequent patches.
> >
> >
> > This patch should be aquashed into the patch on implementing multiply.
>
> Yes it should.
>
> Incidentally, why did you split it out in the first place?
>

I wanted to split the patch 1 from v4 into smaller patches, and use
remaining v4 patches as-is, so I did not want to meld this segment (from
patch 1) and one of remaining patches (mul), otherwise remaining patches
wouldn't be as-is.

But v5 was done mainly for debugging purposes. Normally, two mentioned
partches on “multiply” should obviously be melded.

>
> r~


Re: [Qemu-devel] [PATCH v6 04/16] tcg/ppc: Enable tcg backend vector compilation

2019-06-30 Thread Richard Henderson
On 6/30/19 11:46 AM, Aleksandar Markovic wrote:
> 
> 
> On Saturday, June 29, 2019, Richard Henderson  > wrote:
> 
> Introduce all of the flags required to enable tcg backend vector support,
> and a runtime flag to indicate the host supports Altivec instructions.
> 
> 
> If two flags have different purpose and usage, it is better that they
> have different names. (perhaps one of them should have the suffix “_runtime“)

Huh?  They do have different names.  Very different names.

> Also, I am not sure if Altiveec can be reffered as isa, it is a part/extension
> of an isa, so “isa” seems  superfluous here.

It also matches the other existing names, so I'll leave it as is.

> checkpatch warning should also be honored.

It's bogus.

> WARNING: Block comments use a leading /* on a separate line
> #155: FILE: tcg/ppc/tcg-target.inc.c:2842:
> +if (hwcap & /* PPC_FEATURE_HAS_ALTIVEC -- NOT YET */ 0) {

It's not a block comment; the whole thing is on one line.
I have no idea why it doesn't notice.

In any case, this goes away in patch 13.


r~



Re: [Qemu-devel] [PATCH v6 09/16] tcg/ppc: Prepare case for vector multiply

2019-06-30 Thread Richard Henderson
On 6/30/19 11:52 AM, Aleksandar Markovic wrote:
> 
> 
> On Saturday, June 29, 2019, Richard Henderson  > wrote:
> 
> This line is just preparation for full vector multiply support
> in some of subsequent patches.
> 
> 
> This patch should be aquashed into the patch on implementing multiply.

Yes it should.

Incidentally, why did you split it out in the first place?


r~



[Qemu-devel] [PATCH v9 1/2] hw/arm: Add arm SBSA reference machine, skeleton part

2019-06-30 Thread Hongbo Zhang
For the Aarch64, there is one machine 'virt', it is primarily meant to
run on KVM and execute virtualization workloads, but we need an
environment as faithful as possible to physical hardware, for supporting
firmware and OS development for pysical Aarch64 machines.

This patch introduces new machine type 'sbsa-ref' with main features:
 - Based on 'virt' machine type.
 - A new memory map.
 - CPU type cortex-a57.
 - EL2 and EL3 are enabled.
 - GIC version 3.
 - System bus AHCI controller.
 - System bus EHCI controller.
 - CDROM and hard disc on AHCI bus.
 - E1000E ethernet card on PCIE bus.
 - VGA display adaptor on PCIE bus.
 - No virtio deivces.
 - No fw_cfg device.
 - No ACPI table supplied.
 - Only minimal device tree nodes.

Arm Trusted Firmware and UEFI porting to this are done accordingly, and
it should supply ACPI tables to load OS, the minimal device tree nodes
supplied from this platform are only to pass the dynamic info reflecting
command line input to firmware, not for loading OS.

To make the review easier, this task is split into two patches, the
fundamental sceleton part and the peripheral devices part, this patch is
the first part.

Signed-off-by: Hongbo Zhang 
---
 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Kconfig  |  16 +++
 hw/arm/Makefile.objs|   1 +
 hw/arm/sbsa-ref.c   | 281 
 4 files changed, 299 insertions(+)
 create mode 100644 hw/arm/sbsa-ref.c

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 1f2e0e7..f9fdb73 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -19,6 +19,7 @@ CONFIG_SX1=y
 CONFIG_NSERIES=y
 CONFIG_STELLARIS=y
 CONFIG_REALVIEW=y
+CONFIG_SBSA_REF=y
 CONFIG_VERSATILE=y
 CONFIG_VEXPRESS=y
 CONFIG_ZYNQ=y
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 9aced9d..18e47b2 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -184,6 +184,22 @@ config REALVIEW
 select DS1338 # I2C RTC+NVRAM
 select USB_OHCI
 
+config SBSA_REF
+bool
+imply PCI_DEVICES
+select A15MPCORE
+select AHCI
+select ARM_SMMUV3
+select GPIO_KEY
+select PCI_EXPRESS
+select PCI_EXPRESS_GENERIC_BRIDGE
+select PFLASH_CFI01
+select PL011 # UART
+select PL031 # RTC
+select PL061 # GPIO
+select PLATFORM_BUS
+select USB_EHCI_SYSBUS
+
 config SABRELITE
 bool
 select FSL_IMX6
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 994e67d..43ce8d5 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -19,6 +19,7 @@ obj-$(CONFIG_SPITZ) += spitz.o
 obj-$(CONFIG_TOSA) += tosa.o
 obj-$(CONFIG_Z2) += z2.o
 obj-$(CONFIG_REALVIEW) += realview.o
+obj-$(CONFIG_SBSA_REF) += sbsa-ref.o
 obj-$(CONFIG_STELLARIS) += stellaris.o
 obj-$(CONFIG_COLLIE) += collie.o
 obj-$(CONFIG_VERSATILE) += versatilepb.o
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
new file mode 100644
index 000..eaf97e8
--- /dev/null
+++ b/hw/arm/sbsa-ref.c
@@ -0,0 +1,281 @@
+/*
+ * ARM SBSA Reference Platform emulation
+ *
+ * Copyright (c) 2018 Linaro Limited
+ * Written by Hongbo Zhang 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+#include "qemu/units.h"
+#include "sysemu/numa.h"
+#include "sysemu/sysemu.h"
+#include "exec/address-spaces.h"
+#include "exec/hwaddr.h"
+#include "kvm_arm.h"
+#include "hw/arm/boot.h"
+#include "hw/boards.h"
+#include "hw/intc/arm_gicv3_common.h"
+
+#define RAMLIMIT_GB 8192
+#define RAMLIMIT_BYTES (RAMLIMIT_GB * GiB)
+
+enum {
+SBSA_FLASH,
+SBSA_MEM,
+SBSA_CPUPERIPHS,
+SBSA_GIC_DIST,
+SBSA_GIC_REDIST,
+SBSA_SMMU,
+SBSA_UART,
+SBSA_RTC,
+SBSA_PCIE,
+SBSA_PCIE_MMIO,
+SBSA_PCIE_MMIO_HIGH,
+SBSA_PCIE_PIO,
+SBSA_PCIE_ECAM,
+SBSA_GPIO,
+SBSA_SECURE_UART,
+SBSA_SECURE_UART_MM,
+SBSA_SECURE_MEM,
+SBSA_AHCI,
+SBSA_EHCI,
+};
+
+typedef struct MemMapEntry {
+hwaddr base;
+hwaddr size;
+} MemMapEntry;
+
+typedef struct {
+MachineState parent;
+struct arm_boot_info bootinfo;
+int smp_cpus;
+void *fdt;
+int fdt_size;
+int psci_conduit;
+} SBSAMachineState;
+
+#define TYPE_SBSA_MACHINE   MACHINE_TYPE_NAME("sbsa-ref")
+#define SBSA_MACHINE(obj) \
+OBJECT_CHECK(SBSAMachineState, (obj), TYPE_SBSA_MACHINE)
+
+static const MemMapEntry 

[Qemu-devel] [PATCH v9 0/2] Add Arm SBSA Reference Machine

2019-06-30 Thread Hongbo Zhang
For the Aarch64, there is one machine 'virt', it is primarily meant to
run on KVM and execute virtualization workloads, but we need an
environment as faithful as possible to physical hardware,  to support
firmware and OS development for pysical Aarch64 machines.

This machine comes with:
 - Re-designed memory map.
 - CPU cortex-a57.
 - EL2 and EL3 enabled.
 - GIC version 3.
 - System bus AHCI controller.
 - System bus XHCI controller.
 - CDROM and hard disc on AHCI bus.
 - E1000E ethernet card on PCIE bus.
 - VGA display adaptor on PCIE bus.
 - Only minimal device tree nodes.
And without:
 - virtio deivces.
 - fw_cfg device.
 - ACPI tables.

Arm Trusted Firmware and UEFI porting to this are done accordingly, and
it should supply ACPI tables to load OS, the minimal device tree nodes
supplied from this platform are only to pass the dynamic info reflecting
command line input to firmware, not for loading OS.

v9 changes:
 - only a few lines update to refine the patch format, while the final
   sbsa-ref.c is kept same with v8

v8 changes:
 - rebase to latest QEMU tree
 - use new way of creating flash as in 'virt' machine
 - other minor typos and comments update

v7 changes:
 - edit memory map for PCIE slightly
 - add another secure UART which can be used for RAS and MM from EL0.

v6 changes:
 - rebased to the latest QEMU tree
 - rechecked all the header files included
 - added the newly introduced system bus EHCI controller
 - removed the machine_done callback due to commit 5614ca80
 - updated block comments styles according to checkpatch.pl
 - use Kconfig to add new file
 - use private SBSA* types defination instead of VIRT* in virt.h
   since nobody else using them so they are in the .c file instead
   of a new .h file

v5 changes:
 - removed more lines derived from virt.c
 - designed a new memory map
 - splitted former one patch into two for easier review
 - cancled previous EHCI and new HXCI coming later separately

V4 changes:
 - rebased to v3.0.0
 - removed timer, uart, rtc, *hci device tree nodes
   (others were removerd in v3)
 - other minore codes clean up, mainly unsed header files, comments etc.

V3 changes:
 - rename the platform 'sbsa-ref'
 - move all the codes to a separate file sbsa-ref.c
 - remove paravirtualized fw_cfg device
 - do not supply ACPI tables, since firmware will do it
 - supply only necessary DT nodes
 - and other minor code clean up

Hongbo Zhang (2):
  hw/arm: Add arm SBSA reference machine, skeleton part
  hw/arm: Add arm SBSA reference machine, devices part

 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Kconfig  |  16 +
 hw/arm/Makefile.objs|   1 +
 hw/arm/sbsa-ref.c   | 806 
 4 files changed, 824 insertions(+)
 create mode 100644 hw/arm/sbsa-ref.c

-- 
2.7.4




[Qemu-devel] [PATCH v9 2/2] hw/arm: Add arm SBSA reference machine, devices part

2019-06-30 Thread Hongbo Zhang
Following the previous patch, this patch adds peripheral devices to the
newly introduced SBSA-ref machine.

Signed-off-by: Hongbo Zhang 
---
 hw/arm/sbsa-ref.c | 525 ++
 1 file changed, 525 insertions(+)

diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
index eaf97e8..3b2b9cb 100644
--- a/hw/arm/sbsa-ref.c
+++ b/hw/arm/sbsa-ref.c
@@ -18,21 +18,41 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu-common.h"
 #include "qapi/error.h"
 #include "qemu/error-report.h"
 #include "qemu/units.h"
+#include "sysemu/device_tree.h"
 #include "sysemu/numa.h"
 #include "sysemu/sysemu.h"
 #include "exec/address-spaces.h"
 #include "exec/hwaddr.h"
 #include "kvm_arm.h"
 #include "hw/arm/boot.h"
+#include "hw/block/flash.h"
 #include "hw/boards.h"
+#include "hw/ide/internal.h"
+#include "hw/ide/ahci_internal.h"
 #include "hw/intc/arm_gicv3_common.h"
+#include "hw/loader.h"
+#include "hw/pci-host/gpex.h"
+#include "hw/usb.h"
+#include "net/net.h"
 
 #define RAMLIMIT_GB 8192
 #define RAMLIMIT_BYTES (RAMLIMIT_GB * GiB)
 
+#define NUM_IRQS256
+#define NUM_SMMU_IRQS   4
+#define NUM_SATA_PORTS  6
+
+#define VIRTUAL_PMU_IRQ7
+#define ARCH_GIC_MAINT_IRQ 9
+#define ARCH_TIMER_VIRT_IRQ11
+#define ARCH_TIMER_S_EL1_IRQ   13
+#define ARCH_TIMER_NS_EL1_IRQ  14
+#define ARCH_TIMER_NS_EL2_IRQ  10
+
 enum {
 SBSA_FLASH,
 SBSA_MEM,
@@ -67,6 +87,7 @@ typedef struct {
 void *fdt;
 int fdt_size;
 int psci_conduit;
+PFlashCFI01 *flash[2];
 } SBSAMachineState;
 
 #define TYPE_SBSA_MACHINE   MACHINE_TYPE_NAME("sbsa-ref")
@@ -113,6 +134,455 @@ static const int sbsa_ref_irqmap[] = {
 [SBSA_EHCI] = 11,
 };
 
+/*
+ * Firmware on this machine only uses ACPI table to load OS, these limited
+ * device tree nodes are just to let firmware know the info which varies from
+ * command line parameters, so it is not necessary to be fully compatible
+ * with the kernel CPU and NUMA binding rules.
+ */
+static void create_fdt(SBSAMachineState *sms)
+{
+void *fdt = create_device_tree(>fdt_size);
+const MachineState *ms = MACHINE(sms);
+int cpu;
+
+if (!fdt) {
+error_report("create_device_tree() failed");
+exit(1);
+}
+
+sms->fdt = fdt;
+
+qemu_fdt_setprop_string(fdt, "/", "compatible", "linux,sbsa-ref");
+qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2);
+qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2);
+
+if (have_numa_distance) {
+int size = nb_numa_nodes * nb_numa_nodes * 3 * sizeof(uint32_t);
+uint32_t *matrix = g_malloc0(size);
+int idx, i, j;
+
+for (i = 0; i < nb_numa_nodes; i++) {
+for (j = 0; j < nb_numa_nodes; j++) {
+idx = (i * nb_numa_nodes + j) * 3;
+matrix[idx + 0] = cpu_to_be32(i);
+matrix[idx + 1] = cpu_to_be32(j);
+matrix[idx + 2] = cpu_to_be32(numa_info[i].distance[j]);
+}
+}
+
+qemu_fdt_add_subnode(fdt, "/distance-map");
+qemu_fdt_setprop(fdt, "/distance-map", "distance-matrix",
+ matrix, size);
+g_free(matrix);
+}
+
+qemu_fdt_add_subnode(sms->fdt, "/cpus");
+
+for (cpu = sms->smp_cpus - 1; cpu >= 0; cpu--) {
+char *nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
+ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
+CPUState *cs = CPU(armcpu);
+
+qemu_fdt_add_subnode(sms->fdt, nodename);
+
+if (ms->possible_cpus->cpus[cs->cpu_index].props.has_node_id) {
+qemu_fdt_setprop_cell(sms->fdt, nodename, "numa-node-id",
+ms->possible_cpus->cpus[cs->cpu_index].props.node_id);
+}
+
+g_free(nodename);
+}
+}
+
+#define SBSA_FLASH_SECTOR_SIZE (256 * KiB)
+
+static PFlashCFI01 *sbsa_flash_create1(SBSAMachineState *sms,
+const char *name,
+const char *alias_prop_name)
+{
+/*
+ * Create a single flash device.  We use the same parameters as
+ * the flash devices on the Versatile Express board.
+ */
+DeviceState *dev = qdev_create(NULL, TYPE_PFLASH_CFI01);
+
+qdev_prop_set_uint64(dev, "sector-length", SBSA_FLASH_SECTOR_SIZE);
+qdev_prop_set_uint8(dev, "width", 4);
+qdev_prop_set_uint8(dev, "device-width", 2);
+qdev_prop_set_bit(dev, "big-endian", false);
+qdev_prop_set_uint16(dev, "id0", 0x89);
+qdev_prop_set_uint16(dev, "id1", 0x18);
+qdev_prop_set_uint16(dev, "id2", 0x00);
+qdev_prop_set_uint16(dev, "id3", 0x00);
+qdev_prop_set_string(dev, "name", name);
+object_property_add_child(OBJECT(sms), name, OBJECT(dev),
+  _abort);
+object_property_add_alias(OBJECT(sms), alias_prop_name,
+  OBJECT(dev), "drive", _abort);
+return PFLASH_CFI01(dev);
+}
+
+static void sbsa_flash_create(SBSAMachineState *sms)
+{
+sms->flash[0] = 

Re: [Qemu-devel] [PATCH v6 09/16] tcg/ppc: Prepare case for vector multiply

2019-06-30 Thread Aleksandar Markovic
On Saturday, June 29, 2019, Richard Henderson 
wrote:

> This line is just preparation for full vector multiply support
> in some of subsequent patches.
>
>
This patch should be aquashed into the patch on implementing multiply.



> Signed-off-by: Richard Henderson 
> Signed-off-by: Aleksandar Markovic 
> ---
>  tcg/ppc/tcg-target.inc.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/tcg/ppc/tcg-target.inc.c b/tcg/ppc/tcg-target.inc.c
> index 307e809fad..e19400609c 100644
> --- a/tcg/ppc/tcg-target.inc.c
> +++ b/tcg/ppc/tcg-target.inc.c
> @@ -3306,6 +3306,7 @@ static const TCGTargetOpDef
> *tcg_target_op_def(TCGOpcode op)
>
>  case INDEX_op_add_vec:
>  case INDEX_op_sub_vec:
> +case INDEX_op_mul_vec:
>  case INDEX_op_and_vec:
>  case INDEX_op_or_vec:
>  case INDEX_op_xor_vec:
> --
> 2.17.1
>
>
>


Re: [Qemu-devel] [PATCH v6 04/16] tcg/ppc: Enable tcg backend vector compilation

2019-06-30 Thread Aleksandar Markovic
On Saturday, June 29, 2019, Richard Henderson 
wrote:

> Introduce all of the flags required to enable tcg backend vector support,
> and a runtime flag to indicate the host supports Altivec instructions.
>
>
If two flags have different purpose and usage, it is better that they
have different
names. (perhaps one of them should have the suffix “_runtime“)

Also, I am not sure if Altiveec can be reffered as isa, it is a
part/extension of an isa, so “isa” seems  superfluous here.

checkpatch warning should also be honored.


> For now, do not actually set have_isa_altivec to true, because we have not
> yet added all of the code to actually generate all of the required insns.
> However, we must define these flags in order to disable ifndefs that create
> stub versions of the functions added here.
>
> The change to tcg_out_movi works around a buglet in tcg.c wherein if we
> do not define tcg_out_dupi_vec we get a declared but not defined Werror,
> but if we only declare it we get a defined but not used Werror.  We need
> to this change to tcg_out_movi eventually anyway, so it's no biggie.
>
> Signed-off-by: Richard Henderson 
> Signed-off-by: Aleksandar Markovic 
> ---
>  tcg/ppc/tcg-target.h | 25 
>  tcg/ppc/tcg-target.opc.h |  5 
>  tcg/ppc/tcg-target.inc.c | 65 ++--
>  3 files changed, 92 insertions(+), 3 deletions(-)
>  create mode 100644 tcg/ppc/tcg-target.opc.h
>
> diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
> index 690fa744e1..f6283f468b 100644
> --- a/tcg/ppc/tcg-target.h
> +++ b/tcg/ppc/tcg-target.h
> @@ -58,6 +58,7 @@ typedef enum {
>  TCG_AREG0 = TCG_REG_R27
>  } TCGReg;
>
> +extern bool have_isa_altivec;
>  extern bool have_isa_2_06;
>  extern bool have_isa_3_00;
>
> @@ -135,6 +136,30 @@ extern bool have_isa_3_00;
>  #define TCG_TARGET_HAS_mulsh_i641
>  #endif
>
> +/*
> + * While technically Altivec could support V64, it has no 64-bit store
> + * instruction and substituting two 32-bit stores makes the generated
> + * code quite large.
> + */
> +#define TCG_TARGET_HAS_v64  0
> +#define TCG_TARGET_HAS_v128 have_isa_altivec
> +#define TCG_TARGET_HAS_v256 0
> +
> +#define TCG_TARGET_HAS_andc_vec 0
> +#define TCG_TARGET_HAS_orc_vec  0
> +#define TCG_TARGET_HAS_not_vec  0
> +#define TCG_TARGET_HAS_neg_vec  0
> +#define TCG_TARGET_HAS_abs_vec  0
> +#define TCG_TARGET_HAS_shi_vec  0
> +#define TCG_TARGET_HAS_shs_vec  0
> +#define TCG_TARGET_HAS_shv_vec  0
> +#define TCG_TARGET_HAS_cmp_vec  0
> +#define TCG_TARGET_HAS_mul_vec  0
> +#define TCG_TARGET_HAS_sat_vec  0
> +#define TCG_TARGET_HAS_minmax_vec   0
> +#define TCG_TARGET_HAS_bitsel_vec   0
> +#define TCG_TARGET_HAS_cmpsel_vec   0
> +
>  void flush_icache_range(uintptr_t start, uintptr_t stop);
>  void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t);
>
> diff --git a/tcg/ppc/tcg-target.opc.h b/tcg/ppc/tcg-target.opc.h
> new file mode 100644
> index 00..fa680dd6a0
> --- /dev/null
> +++ b/tcg/ppc/tcg-target.opc.h
> @@ -0,0 +1,5 @@
> +/*
> + * Target-specific opcodes for host vector expansion.  These will be
> + * emitted by tcg_expand_vec_op.  For those familiar with GCC internals,
> + * consider these to be UNSPEC with names.
> + */
> diff --git a/tcg/ppc/tcg-target.inc.c b/tcg/ppc/tcg-target.inc.c
> index cfbd7ff12c..b938e9aac5 100644
> --- a/tcg/ppc/tcg-target.inc.c
> +++ b/tcg/ppc/tcg-target.inc.c
> @@ -64,6 +64,7 @@
>
>  static tcg_insn_unit *tb_ret_addr;
>
> +bool have_isa_altivec;
>  bool have_isa_2_06;
>  bool have_isa_3_00;
>
> @@ -717,10 +718,31 @@ static void tcg_out_movi_int(TCGContext *s, TCGType
> type, TCGReg ret,
>  }
>  }
>
> -static inline void tcg_out_movi(TCGContext *s, TCGType type, TCGReg ret,
> -tcg_target_long arg)
> +static void tcg_out_dupi_vec(TCGContext *s, TCGType type, TCGReg ret,
> + tcg_target_long val)
>  {
> -tcg_out_movi_int(s, type, ret, arg, false);
> +g_assert_not_reached();
> +}
> +
> +static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg ret,
> + tcg_target_long arg)
> +{
> +switch (type) {
> +case TCG_TYPE_I32:
> +case TCG_TYPE_I64:
> +tcg_debug_assert(ret < TCG_REG_V0);
> +tcg_out_movi_int(s, type, ret, arg, false);
> +break;
> +
> +case TCG_TYPE_V64:
> +case TCG_TYPE_V128:
> +tcg_debug_assert(ret >= TCG_REG_V0);
> +tcg_out_dupi_vec(s, type, ret, arg);
> +break;
> +
> +default:
> +g_assert_not_reached();
> +}
>  }
>
>  static bool mask_operand(uint32_t c, int *mb, int *me)
> @@ -2605,6 +2627,36 @@ static void tcg_out_op(TCGContext *s, TCGOpcode
> opc, const TCGArg *args,
>  }
>  }
>
> +int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, unsigned vece)
> +{
> +g_assert_not_reached();
> 

Re: [Qemu-devel] [PATCH v8 2/2] hw/arm: Add arm SBSA reference machine, devices part

2019-06-30 Thread Hongbo Zhang
On Sun, 23 Jun 2019 at 10:42, Hongbo Zhang  wrote:
>
> Following the previous patch, this patch adds peripheral devices to the
> newly introduced SBSA-ref machine.
>
> Signed-off-by: Hongbo Zhang 
> ---
>  hw/arm/sbsa-ref.c | 523 
> +-
>  1 file changed, 517 insertions(+), 6 deletions(-)
>
> diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
> index e68751e..3b2b9cb 100644
> --- a/hw/arm/sbsa-ref.c
> +++ b/hw/arm/sbsa-ref.c
> @@ -18,21 +18,41 @@
>   */
>
>  #include "qemu/osdep.h"
> +#include "qemu-common.h"
>  #include "qapi/error.h"
>  #include "qemu/error-report.h"
>  #include "qemu/units.h"
> +#include "sysemu/device_tree.h"
>  #include "sysemu/numa.h"
>  #include "sysemu/sysemu.h"
>  #include "exec/address-spaces.h"
>  #include "exec/hwaddr.h"
>  #include "kvm_arm.h"
>  #include "hw/arm/boot.h"
> +#include "hw/block/flash.h"
>  #include "hw/boards.h"
> +#include "hw/ide/internal.h"
> +#include "hw/ide/ahci_internal.h"
>  #include "hw/intc/arm_gicv3_common.h"
> +#include "hw/loader.h"
> +#include "hw/pci-host/gpex.h"
> +#include "hw/usb.h"
> +#include "net/net.h"
>
>  #define RAMLIMIT_GB 8192
>  #define RAMLIMIT_BYTES (RAMLIMIT_GB * GiB)
>
> +#define NUM_IRQS256
> +#define NUM_SMMU_IRQS   4
> +#define NUM_SATA_PORTS  6
> +
> +#define VIRTUAL_PMU_IRQ7
> +#define ARCH_GIC_MAINT_IRQ 9
> +#define ARCH_TIMER_VIRT_IRQ11
> +#define ARCH_TIMER_S_EL1_IRQ   13
> +#define ARCH_TIMER_NS_EL1_IRQ  14
> +#define ARCH_TIMER_NS_EL2_IRQ  10
> +
>  enum {
>  SBSA_FLASH,
>  SBSA_MEM,
> @@ -67,6 +87,7 @@ typedef struct {
>  void *fdt;
>  int fdt_size;
>  int psci_conduit;
> +PFlashCFI01 *flash[2];
>  } SBSAMachineState;
>
>  #define TYPE_SBSA_MACHINE   MACHINE_TYPE_NAME("sbsa-ref")
> @@ -113,6 +134,455 @@ static const int sbsa_ref_irqmap[] = {
>  [SBSA_EHCI] = 11,
>  };
>
> +/*
> + * Firmware on this machine only uses ACPI table to load OS, these limited
> + * device tree nodes are just to let firmware know the info which varies from
> + * command line parameters, so it is not necessary to be fully compatible
> + * with the kernel CPU and NUMA binding rules.
> + */
> +static void create_fdt(SBSAMachineState *sms)
> +{
> +void *fdt = create_device_tree(>fdt_size);
> +const MachineState *ms = MACHINE(sms);
> +int cpu;
> +
> +if (!fdt) {
> +error_report("create_device_tree() failed");
> +exit(1);
> +}
> +
> +sms->fdt = fdt;
> +
> +qemu_fdt_setprop_string(fdt, "/", "compatible", "linux,sbsa-ref");
> +qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2);
> +qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2);
> +
> +if (have_numa_distance) {
> +int size = nb_numa_nodes * nb_numa_nodes * 3 * sizeof(uint32_t);
> +uint32_t *matrix = g_malloc0(size);
> +int idx, i, j;
> +
> +for (i = 0; i < nb_numa_nodes; i++) {
> +for (j = 0; j < nb_numa_nodes; j++) {
> +idx = (i * nb_numa_nodes + j) * 3;
> +matrix[idx + 0] = cpu_to_be32(i);
> +matrix[idx + 1] = cpu_to_be32(j);
> +matrix[idx + 2] = cpu_to_be32(numa_info[i].distance[j]);
> +}
> +}
> +
> +qemu_fdt_add_subnode(fdt, "/distance-map");
> +qemu_fdt_setprop(fdt, "/distance-map", "distance-matrix",
> + matrix, size);
> +g_free(matrix);
> +}
> +
> +qemu_fdt_add_subnode(sms->fdt, "/cpus");
> +
> +for (cpu = sms->smp_cpus - 1; cpu >= 0; cpu--) {
> +char *nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
> +ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
> +CPUState *cs = CPU(armcpu);
> +
> +qemu_fdt_add_subnode(sms->fdt, nodename);
> +
> +if (ms->possible_cpus->cpus[cs->cpu_index].props.has_node_id) {
> +qemu_fdt_setprop_cell(sms->fdt, nodename, "numa-node-id",
> +ms->possible_cpus->cpus[cs->cpu_index].props.node_id);
> +}
> +
> +g_free(nodename);
> +}
> +}
> +
> +#define SBSA_FLASH_SECTOR_SIZE (256 * KiB)
> +
> +static PFlashCFI01 *sbsa_flash_create1(SBSAMachineState *sms,
> +const char *name,
> +const char *alias_prop_name)
> +{
> +/*
> + * Create a single flash device.  We use the same parameters as
> + * the flash devices on the Versatile Express board.
> + */
> +DeviceState *dev = qdev_create(NULL, TYPE_PFLASH_CFI01);
> +
> +qdev_prop_set_uint64(dev, "sector-length", SBSA_FLASH_SECTOR_SIZE);
> +qdev_prop_set_uint8(dev, "width", 4);
> +qdev_prop_set_uint8(dev, "device-width", 2);
> +qdev_prop_set_bit(dev, "big-endian", false);
> +qdev_prop_set_uint16(dev, "id0", 0x89);
> +qdev_prop_set_uint16(dev, "id1", 0x18);
> +qdev_prop_set_uint16(dev, "id2", 0x00);
> +qdev_prop_set_uint16(dev, "id3", 0x00);
> +qdev_prop_set_string(dev, 

Re: [Qemu-devel] RFC: Why does target/m68k RTE insn. use gen_exception

2019-06-30 Thread Richard Henderson
On 6/29/19 6:36 PM, Lucien Murray-Pitts wrote:
> On Sat, Jun 29, 2019 at 12:15:44PM +0200, Richard Henderson wrote:
>> On 6/28/19 5:50 PM, Lucien Murray-Pitts wrote:
>>>  op_helper.c
>>>static void m68k_interrupt_all(CPUM68KState *env, int is_hw)
>>>...
>>>  if (cs->exception_index == EXCP_ACCESS) {
>>>   ...
>>>   do_stack_frame(env, , 7, oldsr, 0, retaddr /*LMP: BROKEN - needs 
>>> PC NEXT*/);
>>>
>>> Actually according to the MC68000 manuals the "return address" (the PC 
>>> saved on
>>> the stack) can be upto 5 instructions later due to prefetch. So some pc_next
>>> would best be used here.
>>
>> The way I read it from the 68040 manual, it's "the pc of the instruction
>> executing at the time the fault was detected".  Well, we did in fact detect 
>> the
>> fault at "retaddr", so that seems to be the right answer.  The fact that real
>> hardware has a different pipeline and detects the fault later seems 
>> immaterial,
>> and largely irrelevant, since the programmer wasn't given any guarantees for
>> what sort of value appears in that slot.
>>
> 
> I was reading the 68000/68020, and based on your suggestion now the 68060 
> manual
> The 68000 is pretty rough, but I agree you could expect it to more likely be 
> the
> next or even upto 5 or so instructions away.
> 
> MC68000UM.pdf, 5.4.1 Bus Error Operation
>   the following information is placed on the supervisor stack:
> 1. Status register
> 2. Program counter (two words, which may be up to five words past the
>instruction being executed)
> 
> MC68000UM.pdf, 6.3.9.1 BUS ERROR.
>   ...value saved for the program counter is advanced 2–10 bytes beyond the
>   address of the first word of the instruction that made the reference causing
>   the bus error. If the bus error occurred during the fetch of the next
>   instruction, the saved program counter has a value in the vicinity of the
>   current instruction, even if the current instruction is a branch, a jump, or
>   a return instruction ...
> 
> MC68020UM.pdf, 6.1.2 Bus Error Exception
>   The saved PC value is the logical address of the instruction that was
>   executing at the time the fault was detected. This is not necessarily the
>   instruction that initiated the bus cycle since the processor overlaps
>   execution of instructions
>   (See 6.4 Bus Fault REcovery and 6.3.11 Return From Exception)
>   
> MC68060UM.pdf, 8.4.4.1 Program Counter (PC).
> On read access faults, the PC points to the instruction that caused the
> access error. This instruction is restarted when an RTE is executed, hence,
> the read cycle is re-executed. On read access errors on the second or later
> of misaligned reads, the read cycles that are successful prior to the access
> error are re-executed since the processor uses a restart model for recovery
> from exceptions.

Interesting.  Thanks for digging through the other manuals.

> In my case I think the original firmware expects to return after the
> faulting instruction, and the retry of the bus io is to be ignored
> (this is a memory map probe routine).

Oh my.  Ok, well, if there's software that relies on some advance, I guess we
can conditionally do that.  It'll take a bit of work...

In

  https://patchwork.ozlabs.org/patch/1072596/

I arrange for the length of the current instruction to be stored in qemu's
exception unwind data.  Within restore_state_to_opc, the "ilen" is stored into
an existing slot in s390's env structure; you'd have to add such a slot for 
m68k.

Given the length of the insn currently executing, you can reliably compute the
pc of the next instruction.  Which would let you advance the pc for this case,
for the appropriate cpu type.

> However for the m68k the do_transaction_failed function pointer field
> has not been implemented.
> 
> I implemented it in a rudamentary fashion copying from already existing
> m68k_cpu_unassigned_access.  I really dont know if this is the right way.
> 
>   void m68k_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
>   unsigned size, MMUAccessType access_type,
>   int mmu_idx, MemTxAttrs attrs,
>   MemTxResult response, uintptr_t retaddr)
>   {
>   cs->exception_index = EXCP_ACCESS;
>   cpu_loop_exit(cs);
>   }

At minimum that's going to need

  cpu_loop_exit_restore(cs, retaddr);

But usually store some of the addr and access_type data into fields so that you
can properly fill in the exception frame later.

> Then I reverted my device to the "mem with attributes" io with a return of
> MEMTX_ERROR and found that the behavior during single-step were the same as
> before.
> 
> I end up ISR+1 instruction stepped in.

So, earlier, I suggested adding a call to cpu_handle_debug_exception within
cpu_handle_exception.  Did you try that?


r~



Re: [Qemu-devel] [RFC 1/1] hw/pvrdma: Add live migration support

2019-06-30 Thread Yuval Shaia
On Sat, Jun 29, 2019 at 06:15:21PM +0530, Sukrit Bhatnagar wrote:
> On Fri, 28 Jun 2019 at 16:56, Dr. David Alan Gilbert
>  wrote:
> >
> > * Yuval Shaia (yuval.sh...@oracle.com) wrote:
> > > On Fri, Jun 21, 2019 at 08:15:41PM +0530, Sukrit Bhatnagar wrote:
> > > > Define and register SaveVMHandlers pvrdma_save and
> > > > pvrdma_load for saving and loading the device state,
> > > > which currently includes only the dma, command slot
> > > > and response slot addresses.
> > > >
> > > > Remap the DSR, command slot and response slot upon
> > > > loading the addresses in the pvrdma_load function.
> > > >
> > > > Cc: Marcel Apfelbaum 
> > > > Cc: Yuval Shaia 
> > > > Signed-off-by: Sukrit Bhatnagar 
> > > > ---
> > > >  hw/rdma/vmw/pvrdma_main.c | 56 +++
> > > >  1 file changed, 56 insertions(+)
> > > >
> > > > diff --git a/hw/rdma/vmw/pvrdma_main.c b/hw/rdma/vmw/pvrdma_main.c
> > > > index adcf79cd63..cd8573173c 100644
> > > > --- a/hw/rdma/vmw/pvrdma_main.c
> > > > +++ b/hw/rdma/vmw/pvrdma_main.c
> > > > @@ -28,6 +28,7 @@
> > > >  #include "sysemu/sysemu.h"
> > > >  #include "monitor/monitor.h"
> > > >  #include "hw/rdma/rdma.h"
> > > > +#include "migration/register.h"
> > > >
> > > >  #include "../rdma_rm.h"
> > > >  #include "../rdma_backend.h"
> > > > @@ -592,9 +593,62 @@ static void pvrdma_shutdown_notifier(Notifier *n, 
> > > > void *opaque)
> > > >  pvrdma_fini(pci_dev);
> > > >  }
> > > >
> > > > +static void pvrdma_save(QEMUFile *f, void *opaque)
> > > > +{
> > > > +PVRDMADev *dev = PVRDMA_DEV(opaque);
> > > > +
> > > > +qemu_put_be64(f, dev->dsr_info.dma);
> > > > +qemu_put_be64(f, dev->dsr_info.dsr->cmd_slot_dma);
> > > > +qemu_put_be64(f, dev->dsr_info.dsr->resp_slot_dma);
> > > > +}
> > > > +
> > > > +static int pvrdma_load(QEMUFile *f, void *opaque, int version_id)
> > > > +{
> > > > +PVRDMADev *dev = PVRDMA_DEV(opaque);
> > > > +PCIDevice *pci_dev = PCI_DEVICE(dev);
> > > > +
> > > > +// Remap DSR
> > > > +dev->dsr_info.dma = qemu_get_be64(f);
> > > > +dev->dsr_info.dsr = rdma_pci_dma_map(pci_dev, dev->dsr_info.dma,
> > > > +sizeof(struct 
> > > > pvrdma_device_shared_region));
> > > > +if (!dev->dsr_info.dsr) {
> > > > +rdma_error_report("Failed to map to DSR");
> > > > +return -1;
> > > > +}
> > > > +qemu_log("pvrdma_load: successfully remapped to DSR\n");
> > > > +
> > > > +// Remap cmd slot
> > > > +dev->dsr_info.dsr->cmd_slot_dma = qemu_get_be64(f);
> > > > +dev->dsr_info.req = rdma_pci_dma_map(pci_dev, 
> > > > dev->dsr_info.dsr->cmd_slot_dma,
> > > > + sizeof(union pvrdma_cmd_req));
> > > > +if (!dev->dsr_info.req) {
> > >
> > > So this is where you hit the error, right?
> > > All looks good to me, i wonder why the first pci_dma_map works fine but
> > > second fails where the global BounceBuffer is marked as used.
> > >
> > > Anyone?
> >
> > I've got a few guesses:
> >   a) My reading of address_space_map is that it gives a bounce buffer
> > pointer and then it has to be freed; so if it's going wrong and using a
> > bounce buffer, then the 1st call would work and only the 2nd would fail.
> 
> In the scenario without any migration, the device is init and load_dsr()
> is called when the guest writes to DSR in BAR1 of pvrdma.
> 
> Inside the load_dsr(), there are similar calls to rdma_pci_dma_map().
> 
> The difference is that when the address_space_map() is called there,
> !memory_access_is_direct() condition is FALSE.
> So, there is no use for BounceBuffer.
> 
> 
> In the migration scenario, when the device at dest calls load and
> subsequently rdma_pci_dma_map(), the !memory_access_is_direct()
> condition is TRUE.
> So, the first rdma_pci_dma_map() will set BounceBuffer from FALSE to
> TRUE and succeed. But, the subsequent calls will fail at atomic_xchg().
> 
> This BounceBuffer is only freed when address_space_unmap() is called.
> 
> 
> I am guessing that when the address is translated to one in FlatView,
> the MemoryRegion returned at dest is causing the issue.
> To be honest, at this point I am not sure how FlatView translations works.
> 
> I tried adding qemu_log to memory_access_is_direct(), but I guess it is
> called too many times, so the vm stalls before it even starts.
> 
> >   b) Perhaps the dma address read from the stream is bad, and isn't
> > pointing into RAM properly - and that's why you're getting a bounce
> > buffer.
> 
> I have logged the addresses saved in pvrdma_save(), and the ones
> loaded in pvrdma_load(). They are same. So, there is no problem in the
> stream itself, I suppose.
> 
> >   c) Do you have some ordering problems? i.e. is this code happening
> > before some other device has been loaded/initialised?  If you're relying
> > on some other state, then perhaps the right thing is to perform these
> > mappings later, at the end of migration, not during the loading itself.

Re: [Qemu-devel] [PATCH v3 0/7] Kconfig dependencies for MIPS machines (but Malta)

2019-06-30 Thread Aleksandar Markovic
On Mar 11, 2019 1:56 AM, "Philippe Mathieu-Daudé"  wrote:
>
> Express the MIPS machine dependencies with Kconfig.
>
> Due to its complexity, the Malta board fill follow in a different
> series.
>

Philippe,

What do we do with this series for 4.1?

Yours,
Aleksandar

> v3:
> - addressed review comments from Thomas and Aleksandar
>   (noted in each patch)
>
> v2: https://lists.gnu.org/archive/html/qemu-devel/2019-02/msg00887.html
> - Do not remove machines from the default config (Thomas)
> - Corrected comment about CONFIG_PCI_BONITO (Thomas)
>
> v1: https://www.mail-archive.com/qemu-devel@nongnu.org/msg593013.html
>
> $ git backport-diff -u kconfig_mips-v2
> Key:
> [] : patches are identical
> [] : number of functional differences between upstream/downstream
patch
> The flags [FC] indicate (F)unctional and (C)ontextual differences,
respectively
>
> 001/7:[] [--] 'hw/mips: Express dependencies of the MIPSsim machine
with kconfig'
> 002/7:[0001] [FC] 'hw/mips: Express dependencies of the Jazz machine with
kconfig'
> 003/7:[0002] [FC] 'hw/mips: Express dependencies of the r4k platform with
kconfig'
> 004/7:[down] 'hw/mips: Remove the redundant CONFIG_MIPS_ITU Makefile
variable'
> 005/7:[] [-C] 'hw/mips: Express dependencies of the Boston machine
with kconfig'
> 006/7:[] [-C] 'hw/pci-host: Use CONFIG_PCI_BONITO to select the
Bonito North Bridge'
> 007/7:[] [-C] 'hw/mips: Express dependencies of the Fulong 2E machine
with kconfig'
>
> Regards,
>
> Phil.
>
> Philippe Mathieu-Daudé (7):
>   hw/mips: Express dependencies of the MIPSsim machine with Kconfig
>   hw/mips: Express dependencies of the Jazz machine with Kconfig
>   hw/mips: Express dependencies of the r4k platform with Kconfig
>   hw/mips: Remove the redundant CONFIG_MIPS_ITU Makefile variable
>   hw/mips: Express dependencies of the Boston machine with Kconfig
>   hw/pci-host: Use CONFIG_PCI_BONITO to select the Bonito North Bridge
>   hw/mips: Express dependencies of the Fulong 2E machine with Kconfig
>
>  default-configs/mips-softmmu-common.mak |  4 ---
>  default-configs/mips64-softmmu.mak  |  5 ---
>  default-configs/mips64el-softmmu.mak| 11 ---
>  hw/isa/Kconfig  | 13 +---
>  hw/mips/Kconfig | 41 +
>  hw/misc/Kconfig |  3 --
>  hw/misc/Makefile.objs   |  2 +-
>  hw/pci-host/Kconfig |  4 +++
>  hw/pci-host/Makefile.objs   |  2 +-
>  9 files changed, 56 insertions(+), 29 deletions(-)
>
> --
> 2.20.1
>
>