Re: [Qemu-devel] [Qemu-ppc] [PATCH] spapr: drop redundant statement in spapr_populate_drconf_memory()

2018-11-24 Thread David Gibson
On Fri, Nov 23, 2018 at 09:04:19AM +0100, Greg Kurz wrote:
> On Fri, 23 Nov 2018 11:20:37 +1100
> David Gibson  wrote:
> 
> > On Thu, Nov 22, 2018 at 03:31:36PM +0100, Greg Kurz wrote:
> > > Signed-off-by: Greg Kurz   
> > 
> > Applied to ppc-for-3.2.
> > 
> 
> AFAIK, next release will be 4.0.

Oh, right, I've renamed that.

> 
> > > ---
> > >  hw/ppc/spapr.c |2 --
> > >  1 file changed, 2 deletions(-)
> > > 
> > > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> > > index 9c41098b5781..7771a628f879 100644
> > > --- a/hw/ppc/spapr.c
> > > +++ b/hw/ppc/spapr.c
> > > @@ -893,8 +893,6 @@ static int 
> > > spapr_populate_drconf_memory(sPAPRMachineState *spapr, void *fdt)
> > >  /* ibm,associativity-lookup-arrays */
> > >  buf_len = (nr_nodes * 4 + 2) * sizeof(uint32_t);
> > >  cur_index = int_buf = g_malloc0(buf_len);
> > > -
> > > -cur_index = int_buf;
> > >  int_buf[0] = cpu_to_be32(nr_nodes);
> > >  int_buf[1] = cpu_to_be32(4); /* Number of entries per associativity 
> > > list */
> > >  cur_index += 2;
> > >   
> > 
> 



-- 
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] [RFC PATCH v2 2/3] kvm-all: Introduce kvm_set_singlestep

2018-11-24 Thread David Gibson
On Wed, Nov 21, 2018 at 04:13:46PM -0200, Fabiano Rosas wrote:
> This will be used in a future patch to implement an
> architecture-specific single step mechanism for POWER.
> 
> Signed-off-by: Fabiano Rosas 
> ---
>  accel/kvm/kvm-all.c  | 10 ++
>  exec.c   |  1 +
>  include/sysemu/kvm.h |  4 
>  target/arm/kvm.c |  4 
>  target/i386/kvm.c|  4 
>  target/mips/kvm.c|  4 
>  target/ppc/kvm.c |  4 
>  target/s390x/kvm.c   |  4 
>  8 files changed, 35 insertions(+)
> 
> diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
> index 4880a05399..4fb7199a15 100644
> --- a/accel/kvm/kvm-all.c
> +++ b/accel/kvm/kvm-all.c
> @@ -2313,6 +2313,11 @@ int kvm_update_guest_debug(CPUState *cpu, unsigned 
> long reinject_trap)
>  return data.err;
>  }
>  
> +void kvm_set_singlestep(CPUState *cs, int enabled)
> +{
> +kvm_arch_set_singlestep(cs, enabled);
> +}
> +
>  int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr,
>target_ulong len, int type)
>  {
> @@ -2439,6 +2444,11 @@ int kvm_remove_breakpoint(CPUState *cpu, target_ulong 
> addr,
>  void kvm_remove_all_breakpoints(CPUState *cpu)
>  {
>  }
> +
> +void kvm_set_singlestep(CPUState *cs, int enabled)
> +{
> +}

You could use stubs to avoid having to put this empty implementation
in every arch.

It also seems like it might be a good idea to report an error here,
rather than having set single step silently do nothing on arches which
don't support it yet.

>  #endif /* !KVM_CAP_SET_GUEST_DEBUG */
>  
>  static int kvm_set_signal_mask(CPUState *cpu, const sigset_t *sigset)
> diff --git a/exec.c b/exec.c
> index bb6170dbff..55614822c3 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -1233,6 +1233,7 @@ void cpu_single_step(CPUState *cpu, int enabled)
>  if (cpu->singlestep_enabled != enabled) {
>  cpu->singlestep_enabled = enabled;
>  if (kvm_enabled()) {
> +kvm_set_singlestep(cpu, enabled);
>  kvm_update_guest_debug(cpu, 0);
>  } else {
>  /* must flush all the translated code to avoid inconsistencies */
> diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
> index 97d8d9d0d5..a01a8d58dd 100644
> --- a/include/sysemu/kvm.h
> +++ b/include/sysemu/kvm.h
> @@ -259,6 +259,8 @@ int kvm_remove_breakpoint(CPUState *cpu, target_ulong 
> addr,
>  void kvm_remove_all_breakpoints(CPUState *cpu);
>  int kvm_update_guest_debug(CPUState *cpu, unsigned long reinject_trap);
>  
> +void kvm_set_singlestep(CPUState *cpu, int enabled);
> +
>  int kvm_on_sigbus_vcpu(CPUState *cpu, int code, void *addr);
>  int kvm_on_sigbus(int code, void *addr);
>  
> @@ -431,6 +433,8 @@ void kvm_arch_remove_all_hw_breakpoints(void);
>  
>  void kvm_arch_update_guest_debug(CPUState *cpu, struct kvm_guest_debug *dbg);
>  
> +void kvm_arch_set_singlestep(CPUState *cpu, int enabled);
> +
>  bool kvm_arch_stop_on_emulation_error(CPUState *cpu);
>  
>  int kvm_check_extension(KVMState *s, unsigned int extension);
> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
> index 44dd0ce6ce..dd8e43ab7e 100644
> --- a/target/arm/kvm.c
> +++ b/target/arm/kvm.c
> @@ -670,6 +670,10 @@ int kvm_arch_process_async_events(CPUState *cs)
>  return 0;
>  }
>  
> +void kvm_arch_set_singlestep(CPUState *cs, int enabled)
> +{
> +}
> +
>  /* The #ifdef protections are until 32bit headers are imported and can
>   * be removed once both 32 and 64 bit reach feature parity.
>   */
> diff --git a/target/i386/kvm.c b/target/i386/kvm.c
> index f524e7d929..ba56f2ee1f 100644
> --- a/target/i386/kvm.c
> +++ b/target/i386/kvm.c
> @@ -3521,6 +3521,10 @@ static int kvm_handle_debug(X86CPU *cpu,
>  return ret;
>  }
>  
> +void kvm_arch_set_singlestep(CPUState *cs, int enabled)
> +{
> +}
> +
>  void kvm_arch_update_guest_debug(CPUState *cpu, struct kvm_guest_debug *dbg)
>  {
>  const uint8_t type_code[] = {
> diff --git a/target/mips/kvm.c b/target/mips/kvm.c
> index 8e72850962..8035262131 100644
> --- a/target/mips/kvm.c
> +++ b/target/mips/kvm.c
> @@ -119,6 +119,10 @@ int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct 
> kvm_sw_breakpoint *bp)
>  return 0;
>  }
>  
> +void kvm_arch_set_singlestep(CPUState *cs, int enabled)
> +{
> +}
> +
>  static inline int cpu_mips_io_interrupts_pending(MIPSCPU *cpu)
>  {
>  CPUMIPSState *env = >env;
> diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
> index f81327d6cd..9d0b4f1f3f 100644
> --- a/target/ppc/kvm.c
> +++ b/target/ppc/kvm.c
> @@ -1551,6 +1551,10 @@ void kvm_arch_remove_all_hw_breakpoints(void)
>  nb_hw_breakpoint = nb_hw_watchpoint = 0;
>  }
>  
> +void kvm_arch_set_singlestep(CPUState *cs, int enabled)
> +{
> +}
> +
>  void kvm_arch_update_guest_debug(CPUState *cs, struct kvm_guest_debug *dbg)
>  {
>  int n;
> diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
> index 2ebf26adfe..4bde183458 100644
> --- a/target/s390x/kvm.c
> +++ b/target/s390x/kvm.c
> @@ -975,6 +975,10 @@ void 

Re: [Qemu-devel] [PATCH v5 23/24] hw/pvrdma: Do not clean resources on shutdown

2018-11-24 Thread Marcel Apfelbaum




On 11/22/18 2:14 PM, Yuval Shaia wrote:

All resources are already cleaned at rm_fini phase.

Signed-off-by: Yuval Shaia 
---
  hw/rdma/rdma_backend.c | 21 +
  1 file changed, 1 insertion(+), 20 deletions(-)

diff --git a/hw/rdma/rdma_backend.c b/hw/rdma/rdma_backend.c
index 6a1e39d4c0..8ab25e94b1 100644
--- a/hw/rdma/rdma_backend.c
+++ b/hw/rdma/rdma_backend.c
@@ -1075,28 +1075,9 @@ static int mad_init(RdmaBackendDev *backend_dev, 
CharBackend *mad_chr_be)
  
  static void mad_stop(RdmaBackendDev *backend_dev)

  {
-QObject *o_ctx_id;
-unsigned long cqe_ctx_id;
-BackendCtx *bctx;
-
-pr_dbg("Closing MAD\n");
+pr_dbg("Stopping MAD\n");
  
  disable_rdmacm_mux_async(backend_dev);

-
-/* Clear MAD buffers list */
-qemu_mutex_lock(_dev->recv_mads_list.lock);
-do {
-o_ctx_id = qlist_pop(backend_dev->recv_mads_list.list);
-if (o_ctx_id) {
-cqe_ctx_id = qnum_get_uint(qobject_to(QNum, o_ctx_id));
-bctx = rdma_rm_get_cqe_ctx(backend_dev->rdma_dev_res, cqe_ctx_id);
-if (bctx) {
-rdma_rm_dealloc_cqe_ctx(backend_dev->rdma_dev_res, cqe_ctx_id);
-g_free(bctx);
-}
-}
-} while (o_ctx_id);
-qemu_mutex_unlock(_dev->recv_mads_list.lock);
  }
  
  static void mad_fini(RdmaBackendDev *backend_dev)




Reviewed-by: Marcel Apfelbaum 

Thanks,
Marcel



Re: [Qemu-devel] [PATCH v5 17/24] hw/pvrdma: Fill error code in command's response

2018-11-24 Thread Marcel Apfelbaum




On 11/22/18 2:13 PM, Yuval Shaia wrote:

Driver checks error code let's set it.

Signed-off-by: Yuval Shaia 
---
  hw/rdma/vmw/pvrdma_cmd.c | 67 
  1 file changed, 48 insertions(+), 19 deletions(-)

diff --git a/hw/rdma/vmw/pvrdma_cmd.c b/hw/rdma/vmw/pvrdma_cmd.c
index 0d3c818c20..a326c5d470 100644
--- a/hw/rdma/vmw/pvrdma_cmd.c
+++ b/hw/rdma/vmw/pvrdma_cmd.c
@@ -131,7 +131,8 @@ static int query_port(PVRDMADev *dev, union pvrdma_cmd_req 
*req,
  
  if (rdma_backend_query_port(>backend_dev,

  (struct ibv_port_attr *))) {
-return -ENOMEM;
+resp->hdr.err = -ENOMEM;
+goto out;
  }
  
  memset(resp, 0, sizeof(*resp));

@@ -150,7 +151,9 @@ static int query_port(PVRDMADev *dev, union pvrdma_cmd_req 
*req,
  resp->attrs.active_width = 1;
  resp->attrs.active_speed = 1;
  
-return 0;

+out:
+pr_dbg("ret=%d\n", resp->hdr.err);
+return resp->hdr.err;
  }
  
  static int query_pkey(PVRDMADev *dev, union pvrdma_cmd_req *req,

@@ -170,7 +173,7 @@ static int query_pkey(PVRDMADev *dev, union pvrdma_cmd_req 
*req,
  resp->pkey = PVRDMA_PKEY;
  pr_dbg("pkey=0x%x\n", resp->pkey);
  
-return 0;

+return resp->hdr.err;
  }
  
  static int create_pd(PVRDMADev *dev, union pvrdma_cmd_req *req,

@@ -200,7 +203,9 @@ static int destroy_pd(PVRDMADev *dev, union pvrdma_cmd_req 
*req,
  
  rdma_rm_dealloc_pd(>rdma_dev_res, cmd->pd_handle);
  
-return 0;

+rsp->hdr.err = 0;
+
+return rsp->hdr.err;
  }
  
  static int create_mr(PVRDMADev *dev, union pvrdma_cmd_req *req,

@@ -251,7 +256,9 @@ static int destroy_mr(PVRDMADev *dev, union pvrdma_cmd_req 
*req,
  
  rdma_rm_dealloc_mr(>rdma_dev_res, cmd->mr_handle);
  
-return 0;

+rsp->hdr.err = 0;
+
+return rsp->hdr.err;
  }
  
  static int create_cq_ring(PCIDevice *pci_dev , PvrdmaRing **ring,

@@ -353,7 +360,8 @@ static int destroy_cq(PVRDMADev *dev, union pvrdma_cmd_req 
*req,
  cq = rdma_rm_get_cq(>rdma_dev_res, cmd->cq_handle);
  if (!cq) {
  pr_dbg("Invalid CQ handle\n");
-return -EINVAL;
+rsp->hdr.err = -EINVAL;
+goto out;
  }
  
  ring = (PvrdmaRing *)cq->opaque;

@@ -364,7 +372,11 @@ static int destroy_cq(PVRDMADev *dev, union pvrdma_cmd_req 
*req,
  
  rdma_rm_dealloc_cq(>rdma_dev_res, cmd->cq_handle);
  
-return 0;

+rsp->hdr.err = 0;
+
+out:
+pr_dbg("ret=%d\n", rsp->hdr.err);
+return rsp->hdr.err;
  }
  
  static int create_qp_rings(PCIDevice *pci_dev, uint64_t pdir_dma,

@@ -553,7 +565,8 @@ static int destroy_qp(PVRDMADev *dev, union pvrdma_cmd_req 
*req,
  qp = rdma_rm_get_qp(>rdma_dev_res, cmd->qp_handle);
  if (!qp) {
  pr_dbg("Invalid QP handle\n");
-return -EINVAL;
+rsp->hdr.err = -EINVAL;
+goto out;
  }
  
  rdma_rm_dealloc_qp(>rdma_dev_res, cmd->qp_handle);

@@ -567,7 +580,11 @@ static int destroy_qp(PVRDMADev *dev, union pvrdma_cmd_req 
*req,
  rdma_pci_dma_unmap(PCI_DEVICE(dev), ring->ring_state, TARGET_PAGE_SIZE);
  g_free(ring);
  
-return 0;

+rsp->hdr.err = 0;
+
+out:
+pr_dbg("ret=%d\n", rsp->hdr.err);
+return rsp->hdr.err;
  }
  
  static int create_bind(PVRDMADev *dev, union pvrdma_cmd_req *req,

@@ -580,7 +597,8 @@ static int create_bind(PVRDMADev *dev, union pvrdma_cmd_req 
*req,
  pr_dbg("index=%d\n", cmd->index);
  
  if (cmd->index >= MAX_PORT_GIDS) {

-return -EINVAL;
+rsp->hdr.err = -EINVAL;
+goto out;
  }
  
  pr_dbg("gid[%d]=0x%llx,0x%llx\n", cmd->index,

@@ -590,10 +608,15 @@ static int create_bind(PVRDMADev *dev, union 
pvrdma_cmd_req *req,
  rc = rdma_rm_add_gid(>rdma_dev_res, >backend_dev,
   dev->backend_eth_device_name, gid, cmd->index);
  if (rc < 0) {
-return -EINVAL;
+rsp->hdr.err = rc;
+goto out;
  }
  
-return 0;

+rsp->hdr.err = 0;
+
+out:
+pr_dbg("ret=%d\n", rsp->hdr.err);
+return rsp->hdr.err;
  }
  
  static int destroy_bind(PVRDMADev *dev, union pvrdma_cmd_req *req,

@@ -606,7 +629,8 @@ static int destroy_bind(PVRDMADev *dev, union 
pvrdma_cmd_req *req,
  pr_dbg("index=%d\n", cmd->index);
  
  if (cmd->index >= MAX_PORT_GIDS) {

-return -EINVAL;
+rsp->hdr.err = -EINVAL;
+goto out;
  }
  
  rc = rdma_rm_del_gid(>rdma_dev_res, >backend_dev,

@@ -617,7 +641,11 @@ static int destroy_bind(PVRDMADev *dev, union 
pvrdma_cmd_req *req,
  goto out;
  }
  
-return 0;

+rsp->hdr.err = 0;
+
+out:
+pr_dbg("ret=%d\n", rsp->hdr.err);
+return rsp->hdr.err;
  }
  
  static int create_uc(PVRDMADev *dev, union pvrdma_cmd_req *req,

@@ -634,9 +662,8 @@ static int create_uc(PVRDMADev *dev, union pvrdma_cmd_req 
*req,
  resp->hdr.err = rdma_rm_alloc_uc(>rdma_dev_res, cmd->pfn,
   >ctx_handle);
  
-pr_dbg("ret=%d\n", 

Re: [Qemu-devel] [PATCH v5 23/24] hw/pvrdma: Do not clean resources on shutdown

2018-11-24 Thread Yuval Shaia
On Thu, Nov 22, 2018 at 02:14:01PM +0200, Yuval Shaia wrote:
> All resources are already cleaned at rm_fini phase.

Please ignore this patch, i will squash it to patch #5.

> 
> Signed-off-by: Yuval Shaia 
> ---
>  hw/rdma/rdma_backend.c | 21 +
>  1 file changed, 1 insertion(+), 20 deletions(-)
> 
> diff --git a/hw/rdma/rdma_backend.c b/hw/rdma/rdma_backend.c
> index 6a1e39d4c0..8ab25e94b1 100644
> --- a/hw/rdma/rdma_backend.c
> +++ b/hw/rdma/rdma_backend.c
> @@ -1075,28 +1075,9 @@ static int mad_init(RdmaBackendDev *backend_dev, 
> CharBackend *mad_chr_be)
>  
>  static void mad_stop(RdmaBackendDev *backend_dev)
>  {
> -QObject *o_ctx_id;
> -unsigned long cqe_ctx_id;
> -BackendCtx *bctx;
> -
> -pr_dbg("Closing MAD\n");
> +pr_dbg("Stopping MAD\n");
>  
>  disable_rdmacm_mux_async(backend_dev);
> -
> -/* Clear MAD buffers list */
> -qemu_mutex_lock(_dev->recv_mads_list.lock);
> -do {
> -o_ctx_id = qlist_pop(backend_dev->recv_mads_list.list);
> -if (o_ctx_id) {
> -cqe_ctx_id = qnum_get_uint(qobject_to(QNum, o_ctx_id));
> -bctx = rdma_rm_get_cqe_ctx(backend_dev->rdma_dev_res, 
> cqe_ctx_id);
> -if (bctx) {
> -rdma_rm_dealloc_cqe_ctx(backend_dev->rdma_dev_res, 
> cqe_ctx_id);
> -g_free(bctx);
> -}
> -}
> -} while (o_ctx_id);
> -qemu_mutex_unlock(_dev->recv_mads_list.lock);
>  }
>  
>  static void mad_fini(RdmaBackendDev *backend_dev)
> -- 
> 2.17.2
> 



Re: [Qemu-devel] [PATCH v4 17/23] hw/pvrdma: Fill error code in command's response

2018-11-24 Thread Marcel Apfelbaum




On 11/18/18 2:28 PM, Yuval Shaia wrote:

Driver checks error code let's set it.

Signed-off-by: Yuval Shaia 
---
  hw/rdma/vmw/pvrdma_cmd.c | 67 
  1 file changed, 48 insertions(+), 19 deletions(-)

diff --git a/hw/rdma/vmw/pvrdma_cmd.c b/hw/rdma/vmw/pvrdma_cmd.c
index 0d3c818c20..a326c5d470 100644
--- a/hw/rdma/vmw/pvrdma_cmd.c
+++ b/hw/rdma/vmw/pvrdma_cmd.c
@@ -131,7 +131,8 @@ static int query_port(PVRDMADev *dev, union pvrdma_cmd_req 
*req,
  
  if (rdma_backend_query_port(>backend_dev,

  (struct ibv_port_attr *))) {
-return -ENOMEM;
+resp->hdr.err = -ENOMEM;
+goto out;
  }
  
  memset(resp, 0, sizeof(*resp));

@@ -150,7 +151,9 @@ static int query_port(PVRDMADev *dev, union pvrdma_cmd_req 
*req,
  resp->attrs.active_width = 1;
  resp->attrs.active_speed = 1;
  
-return 0;

+out:
+pr_dbg("ret=%d\n", resp->hdr.err);
+return resp->hdr.err;
  }
  
  static int query_pkey(PVRDMADev *dev, union pvrdma_cmd_req *req,

@@ -170,7 +173,7 @@ static int query_pkey(PVRDMADev *dev, union pvrdma_cmd_req 
*req,
  resp->pkey = PVRDMA_PKEY;
  pr_dbg("pkey=0x%x\n", resp->pkey);
  
-return 0;

+return resp->hdr.err;
  }
  
  static int create_pd(PVRDMADev *dev, union pvrdma_cmd_req *req,

@@ -200,7 +203,9 @@ static int destroy_pd(PVRDMADev *dev, union pvrdma_cmd_req 
*req,
  
  rdma_rm_dealloc_pd(>rdma_dev_res, cmd->pd_handle);
  
-return 0;

+rsp->hdr.err = 0;
+
+return rsp->hdr.err;
  }
  
  static int create_mr(PVRDMADev *dev, union pvrdma_cmd_req *req,

@@ -251,7 +256,9 @@ static int destroy_mr(PVRDMADev *dev, union pvrdma_cmd_req 
*req,
  
  rdma_rm_dealloc_mr(>rdma_dev_res, cmd->mr_handle);
  
-return 0;

+rsp->hdr.err = 0;
+
+return rsp->hdr.err;
  }
  
  static int create_cq_ring(PCIDevice *pci_dev , PvrdmaRing **ring,

@@ -353,7 +360,8 @@ static int destroy_cq(PVRDMADev *dev, union pvrdma_cmd_req 
*req,
  cq = rdma_rm_get_cq(>rdma_dev_res, cmd->cq_handle);
  if (!cq) {
  pr_dbg("Invalid CQ handle\n");
-return -EINVAL;
+rsp->hdr.err = -EINVAL;
+goto out;
  }
  
  ring = (PvrdmaRing *)cq->opaque;

@@ -364,7 +372,11 @@ static int destroy_cq(PVRDMADev *dev, union pvrdma_cmd_req 
*req,
  
  rdma_rm_dealloc_cq(>rdma_dev_res, cmd->cq_handle);
  
-return 0;

+rsp->hdr.err = 0;
+
+out:
+pr_dbg("ret=%d\n", rsp->hdr.err);
+return rsp->hdr.err;
  }
  
  static int create_qp_rings(PCIDevice *pci_dev, uint64_t pdir_dma,

@@ -553,7 +565,8 @@ static int destroy_qp(PVRDMADev *dev, union pvrdma_cmd_req 
*req,
  qp = rdma_rm_get_qp(>rdma_dev_res, cmd->qp_handle);
  if (!qp) {
  pr_dbg("Invalid QP handle\n");
-return -EINVAL;
+rsp->hdr.err = -EINVAL;
+goto out;
  }
  
  rdma_rm_dealloc_qp(>rdma_dev_res, cmd->qp_handle);

@@ -567,7 +580,11 @@ static int destroy_qp(PVRDMADev *dev, union pvrdma_cmd_req 
*req,
  rdma_pci_dma_unmap(PCI_DEVICE(dev), ring->ring_state, TARGET_PAGE_SIZE);
  g_free(ring);
  
-return 0;

+rsp->hdr.err = 0;
+
+out:
+pr_dbg("ret=%d\n", rsp->hdr.err);
+return rsp->hdr.err;
  }
  
  static int create_bind(PVRDMADev *dev, union pvrdma_cmd_req *req,

@@ -580,7 +597,8 @@ static int create_bind(PVRDMADev *dev, union pvrdma_cmd_req 
*req,
  pr_dbg("index=%d\n", cmd->index);
  
  if (cmd->index >= MAX_PORT_GIDS) {

-return -EINVAL;
+rsp->hdr.err = -EINVAL;
+goto out;
  }
  
  pr_dbg("gid[%d]=0x%llx,0x%llx\n", cmd->index,

@@ -590,10 +608,15 @@ static int create_bind(PVRDMADev *dev, union 
pvrdma_cmd_req *req,
  rc = rdma_rm_add_gid(>rdma_dev_res, >backend_dev,
   dev->backend_eth_device_name, gid, cmd->index);
  if (rc < 0) {
-return -EINVAL;
+rsp->hdr.err = rc;
+goto out;
  }
  
-return 0;

+rsp->hdr.err = 0;
+
+out:
+pr_dbg("ret=%d\n", rsp->hdr.err);
+return rsp->hdr.err;
  }
  
  static int destroy_bind(PVRDMADev *dev, union pvrdma_cmd_req *req,

@@ -606,7 +629,8 @@ static int destroy_bind(PVRDMADev *dev, union 
pvrdma_cmd_req *req,
  pr_dbg("index=%d\n", cmd->index);
  
  if (cmd->index >= MAX_PORT_GIDS) {

-return -EINVAL;
+rsp->hdr.err = -EINVAL;
+goto out;
  }
  
  rc = rdma_rm_del_gid(>rdma_dev_res, >backend_dev,

@@ -617,7 +641,11 @@ static int destroy_bind(PVRDMADev *dev, union 
pvrdma_cmd_req *req,
  goto out;
  }
  
-return 0;

+rsp->hdr.err = 0;
+
+out:
+pr_dbg("ret=%d\n", rsp->hdr.err);
+return rsp->hdr.err;
  }
  
  static int create_uc(PVRDMADev *dev, union pvrdma_cmd_req *req,

@@ -634,9 +662,8 @@ static int create_uc(PVRDMADev *dev, union pvrdma_cmd_req 
*req,
  resp->hdr.err = rdma_rm_alloc_uc(>rdma_dev_res, cmd->pfn,
   >ctx_handle);
  
-pr_dbg("ret=%d\n", 

Re: [Qemu-devel] [PATCH v3 17/23] hw/pvrdma: Fill error code in command's response

2018-11-24 Thread Marcel Apfelbaum




On 11/18/18 10:24 AM, Yuval Shaia wrote:

On Sat, Nov 17, 2018 at 02:22:31PM +0200, Marcel Apfelbaum wrote:


On 11/13/18 9:13 AM, Yuval Shaia wrote:

Driver checks error code let's set it.

Signed-off-by: Yuval Shaia 
---
   hw/rdma/vmw/pvrdma_cmd.c | 67 
   1 file changed, 48 insertions(+), 19 deletions(-)

diff --git a/hw/rdma/vmw/pvrdma_cmd.c b/hw/rdma/vmw/pvrdma_cmd.c
index 0d3c818c20..a326c5d470 100644
--- a/hw/rdma/vmw/pvrdma_cmd.c
+++ b/hw/rdma/vmw/pvrdma_cmd.c
@@ -131,7 +131,8 @@ static int query_port(PVRDMADev *dev, union pvrdma_cmd_req 
*req,
   if (rdma_backend_query_port(>backend_dev,
   (struct ibv_port_attr *))) {
-return -ENOMEM;
+resp->hdr.err = -ENOMEM;
+goto out;
   }
   memset(resp, 0, sizeof(*resp));
@@ -150,7 +151,9 @@ static int query_port(PVRDMADev *dev, union pvrdma_cmd_req 
*req,
   resp->attrs.active_width = 1;
   resp->attrs.active_speed = 1;
-return 0;
+out:
+pr_dbg("ret=%d\n", resp->hdr.err);
+return resp->hdr.err;
   }
   static int query_pkey(PVRDMADev *dev, union pvrdma_cmd_req *req,
@@ -170,7 +173,7 @@ static int query_pkey(PVRDMADev *dev, union pvrdma_cmd_req 
*req,
   resp->pkey = PVRDMA_PKEY;
   pr_dbg("pkey=0x%x\n", resp->pkey);
-return 0;
+return resp->hdr.err;
   }
   static int create_pd(PVRDMADev *dev, union pvrdma_cmd_req *req,
@@ -200,7 +203,9 @@ static int destroy_pd(PVRDMADev *dev, union pvrdma_cmd_req 
*req,
   rdma_rm_dealloc_pd(>rdma_dev_res, cmd->pd_handle);
-return 0;
+rsp->hdr.err = 0;
  with se

Is it possible to ensure err is 0 by default during hdr creation
instead of manually setting it every time?

Yes we can but since these handlers any fills some other fields in the
response i thought it will be clean if they will fill the op-status as
well.
I believe filling it at "handler" level is more modular.
Do you think filling it outside will make the code cleaner?


The only problem with manually clearing the filed
is one might forget to do it and we may see random
err codes in the future, hard to debug,

Thanks,
Marcel




Thanks,
Marcel


+
+return rsp->hdr.err;
   }
   static int create_mr(PVRDMADev *dev, union pvrdma_cmd_req *req,
@@ -251,7 +256,9 @@ static int destroy_mr(PVRDMADev *dev, union pvrdma_cmd_req 
*req,
   rdma_rm_dealloc_mr(>rdma_dev_res, cmd->mr_handle);
-return 0;
+rsp->hdr.err = 0;
+
+return rsp->hdr.err;
   }
   static int create_cq_ring(PCIDevice *pci_dev , PvrdmaRing **ring,
@@ -353,7 +360,8 @@ static int destroy_cq(PVRDMADev *dev, union pvrdma_cmd_req 
*req,
   cq = rdma_rm_get_cq(>rdma_dev_res, cmd->cq_handle);
   if (!cq) {
   pr_dbg("Invalid CQ handle\n");
-return -EINVAL;
+rsp->hdr.err = -EINVAL;
+goto out;
   }
   ring = (PvrdmaRing *)cq->opaque;
@@ -364,7 +372,11 @@ static int destroy_cq(PVRDMADev *dev, union pvrdma_cmd_req 
*req,
   rdma_rm_dealloc_cq(>rdma_dev_res, cmd->cq_handle);
-return 0;
+rsp->hdr.err = 0;
+
+out:
+pr_dbg("ret=%d\n", rsp->hdr.err);
+return rsp->hdr.err;
   }
   static int create_qp_rings(PCIDevice *pci_dev, uint64_t pdir_dma,
@@ -553,7 +565,8 @@ static int destroy_qp(PVRDMADev *dev, union pvrdma_cmd_req 
*req,
   qp = rdma_rm_get_qp(>rdma_dev_res, cmd->qp_handle);
   if (!qp) {
   pr_dbg("Invalid QP handle\n");
-return -EINVAL;
+rsp->hdr.err = -EINVAL;
+goto out;
   }
   rdma_rm_dealloc_qp(>rdma_dev_res, cmd->qp_handle);
@@ -567,7 +580,11 @@ static int destroy_qp(PVRDMADev *dev, union pvrdma_cmd_req 
*req,
   rdma_pci_dma_unmap(PCI_DEVICE(dev), ring->ring_state, TARGET_PAGE_SIZE);
   g_free(ring);
-return 0;
+rsp->hdr.err = 0;
+
+out:
+pr_dbg("ret=%d\n", rsp->hdr.err);
+return rsp->hdr.err;
   }
   static int create_bind(PVRDMADev *dev, union pvrdma_cmd_req *req,
@@ -580,7 +597,8 @@ static int create_bind(PVRDMADev *dev, union pvrdma_cmd_req 
*req,
   pr_dbg("index=%d\n", cmd->index);
   if (cmd->index >= MAX_PORT_GIDS) {
-return -EINVAL;
+rsp->hdr.err = -EINVAL;
+goto out;
   }
   pr_dbg("gid[%d]=0x%llx,0x%llx\n", cmd->index,
@@ -590,10 +608,15 @@ static int create_bind(PVRDMADev *dev, union 
pvrdma_cmd_req *req,
   rc = rdma_rm_add_gid(>rdma_dev_res, >backend_dev,
dev->backend_eth_device_name, gid, cmd->index);
   if (rc < 0) {
-return -EINVAL;
+rsp->hdr.err = rc;
+goto out;
   }
-return 0;
+rsp->hdr.err = 0;
+
+out:
+pr_dbg("ret=%d\n", rsp->hdr.err);
+return rsp->hdr.err;
   }
   static int destroy_bind(PVRDMADev *dev, union pvrdma_cmd_req *req,
@@ -606,7 +629,8 @@ static int destroy_bind(PVRDMADev *dev, union 
pvrdma_cmd_req *req,
   pr_dbg("index=%d\n", cmd->index);
   if (cmd->index >= MAX_PORT_GIDS) {
-return -EINVAL;
+rsp->hdr.err = 

Re: [Qemu-devel] [PATCH v5 05/24] hw/rdma: Add support for MAD packets

2018-11-24 Thread Yuval Shaia
On Sun, Nov 25, 2018 at 09:05:17AM +0200, Marcel Apfelbaum wrote:
> 
> 
> On 11/22/18 2:13 PM, Yuval Shaia wrote:
> > MAD (Management Datagram) packets are widely used by various modules
> > both in kernel and in user space for example the rdma_* API which is
> > used to create and maintain "connection" layer on top of RDMA uses
> > several types of MAD packets.
> > 
> > For more information please refer to chapter 13.4 in Volume 1
> > Architecture Specification, Release 1.1 available here:
> > https://www.infinibandta.org/ibta-specifications-download/
> > 
> > To support MAD packets the device uses an external utility
> > (contrib/rdmacm-mux) to relay packets from and to the guest driver.
> > 
> > Signed-off-by: Yuval Shaia 
> > ---
> >   hw/rdma/rdma_backend.c  | 275 +++-
> >   hw/rdma/rdma_backend.h  |   4 +-
> >   hw/rdma/rdma_backend_defs.h |  10 +-
> >   hw/rdma/vmw/pvrdma.h|   2 +
> >   hw/rdma/vmw/pvrdma_main.c   |   4 +-
> >   5 files changed, 285 insertions(+), 10 deletions(-)
> > 
> > diff --git a/hw/rdma/rdma_backend.c b/hw/rdma/rdma_backend.c
> > index 1e148398a2..7c220a5798 100644
> > --- a/hw/rdma/rdma_backend.c
> > +++ b/hw/rdma/rdma_backend.c
> > @@ -16,8 +16,13 @@
> >   #include "qemu/osdep.h"
> >   #include "qemu/error-report.h"
> >   #include "qapi/error.h"
> > +#include "qapi/qmp/qlist.h"
> > +#include "qapi/qmp/qnum.h"
> >   #include 
> > +#include 
> > +#include 
> > +#include 
> >   #include "trace.h"
> >   #include "rdma_utils.h"
> > @@ -33,16 +38,25 @@
> >   #define VENDOR_ERR_MAD_SEND 0x206
> >   #define VENDOR_ERR_INVLKEY  0x207
> >   #define VENDOR_ERR_MR_SMALL 0x208
> > +#define VENDOR_ERR_INV_MAD_BUFF 0x209
> > +#define VENDOR_ERR_INV_NUM_SGE  0x210
> >   #define THR_NAME_LEN 16
> >   #define THR_POLL_TO  5000
> > +#define MAD_HDR_SIZE sizeof(struct ibv_grh)
> > +
> >   typedef struct BackendCtx {
> > -uint64_t req_id;
> >   void *up_ctx;
> >   bool is_tx_req;
> > +struct ibv_sge sge; /* Used to save MAD recv buffer */
> >   } BackendCtx;
> > +struct backend_umad {
> > +struct ib_user_mad hdr;
> > +char mad[RDMA_MAX_PRIVATE_DATA];
> > +};
> > +
> >   static void (*comp_handler)(int status, unsigned int vendor_err, void 
> > *ctx);
> >   static void dummy_comp_handler(int status, unsigned int vendor_err, void 
> > *ctx)
> > @@ -286,6 +300,61 @@ static int build_host_sge_array(RdmaDeviceResources 
> > *rdma_dev_res,
> >   return 0;
> >   }
> > +static int mad_send(RdmaBackendDev *backend_dev, struct ibv_sge *sge,
> > +uint32_t num_sge)
> > +{
> > +struct backend_umad umad = {0};
> > +char *hdr, *msg;
> > +int ret;
> > +
> > +pr_dbg("num_sge=%d\n", num_sge);
> > +
> > +if (num_sge != 2) {
> > +return -EINVAL;
> > +}
> > +
> > +umad.hdr.length = sge[0].length + sge[1].length;
> > +pr_dbg("msg_len=%d\n", umad.hdr.length);
> > +
> > +if (umad.hdr.length > sizeof(umad.mad)) {
> > +return -ENOMEM;
> > +}
> > +
> > +umad.hdr.addr.qpn = htobe32(1);
> > +umad.hdr.addr.grh_present = 1;
> > +umad.hdr.addr.gid_index = backend_dev->backend_gid_idx;
> > +memcpy(umad.hdr.addr.gid, backend_dev->gid.raw, 
> > sizeof(umad.hdr.addr.gid));
> > +umad.hdr.addr.hop_limit = 1;
> > +
> > +hdr = rdma_pci_dma_map(backend_dev->dev, sge[0].addr, sge[0].length);
> > +if (!hdr) {
> > +pr_dbg("Fail to map to sge[0]\n");
> > +return -ENOMEM;
> > +}
> > +msg = rdma_pci_dma_map(backend_dev->dev, sge[1].addr, sge[1].length);
> > +if (!msg) {
> > +pr_dbg("Fail to map to sge[1]\n");
> > +rdma_pci_dma_unmap(backend_dev->dev, hdr, sge[0].length);
> > +return -ENOMEM;
> > +}
> > +
> > +pr_dbg_buf("mad_hdr", hdr, sge[0].length);
> > +pr_dbg_buf("mad_data", data, sge[1].length);
> > +
> > +memcpy([0], hdr, sge[0].length);
> > +memcpy([sge[0].length], msg, sge[1].length);
> > +
> > +rdma_pci_dma_unmap(backend_dev->dev, msg, sge[1].length);
> > +rdma_pci_dma_unmap(backend_dev->dev, hdr, sge[0].length);
> > +
> > +ret = qemu_chr_fe_write(backend_dev->mad_chr_be, (const uint8_t 
> > *),
> > +sizeof(umad));
> > +
> > +pr_dbg("qemu_chr_fe_write=%d\n", ret);
> > +
> > +return (ret != sizeof(umad));
> > +}
> > +
> >   void rdma_backend_post_send(RdmaBackendDev *backend_dev,
> >   RdmaBackendQP *qp, uint8_t qp_type,
> >   struct ibv_sge *sge, uint32_t num_sge,
> > @@ -304,9 +373,13 @@ void rdma_backend_post_send(RdmaBackendDev 
> > *backend_dev,
> >   comp_handler(IBV_WC_GENERAL_ERR, VENDOR_ERR_QP0, ctx);
> >   } else if (qp_type == IBV_QPT_GSI) {
> >   pr_dbg("QP1\n");
> > -comp_handler(IBV_WC_GENERAL_ERR, VENDOR_ERR_MAD_SEND, ctx);
> > +rc = mad_send(backend_dev, sge, num_sge);
> > +

Re: [Qemu-devel] [PATCH v5 13/24] hw/pvrdma: Make sure PCI function 0 is vmxnet3

2018-11-24 Thread Marcel Apfelbaum




On 11/22/18 2:13 PM, Yuval Shaia wrote:

Guest driver enforces it, we should also.

Signed-off-by: Yuval Shaia 
---
  hw/rdma/vmw/pvrdma.h  |  2 ++
  hw/rdma/vmw/pvrdma_main.c | 12 
  2 files changed, 14 insertions(+)

diff --git a/hw/rdma/vmw/pvrdma.h b/hw/rdma/vmw/pvrdma.h
index b019cb843a..10a3c4fb7c 100644
--- a/hw/rdma/vmw/pvrdma.h
+++ b/hw/rdma/vmw/pvrdma.h
@@ -20,6 +20,7 @@
  #include "hw/pci/pci.h"
  #include "hw/pci/msix.h"
  #include "chardev/char-fe.h"
+#include "hw/net/vmxnet3_defs.h"
  
  #include "../rdma_backend_defs.h"

  #include "../rdma_rm_defs.h"
@@ -85,6 +86,7 @@ typedef struct PVRDMADev {
  RdmaBackendDev backend_dev;
  RdmaDeviceResources rdma_dev_res;
  CharBackend mad_chr;
+VMXNET3State *func0;
  } PVRDMADev;
  #define PVRDMA_DEV(dev) OBJECT_CHECK(PVRDMADev, (dev), PVRDMA_HW_NAME)
  
diff --git a/hw/rdma/vmw/pvrdma_main.c b/hw/rdma/vmw/pvrdma_main.c

index ac8c092db0..b35b5dc5f0 100644
--- a/hw/rdma/vmw/pvrdma_main.c
+++ b/hw/rdma/vmw/pvrdma_main.c
@@ -565,6 +565,7 @@ static void pvrdma_realize(PCIDevice *pdev, Error **errp)
  PVRDMADev *dev = PVRDMA_DEV(pdev);
  Object *memdev_root;
  bool ram_shared = false;
+PCIDevice *func0;
  
  init_pr_dbg();
  
@@ -576,6 +577,17 @@ static void pvrdma_realize(PCIDevice *pdev, Error **errp)

  return;
  }
  
+func0 = pci_get_function_0(pdev);

+/* Break if not vmxnet3 device in slot 0 */
+if (strcmp(object_get_typename(>qdev.parent_obj), TYPE_VMXNET3)) {
+pr_dbg("func0 type is %s\n",
+   object_get_typename(>qdev.parent_obj));
+error_setg(errp, "Device on %x.0 must be %s", PCI_SLOT(pdev->devfn),
+   TYPE_VMXNET3);
+return;
+}
+dev->func0 = VMXNET3(func0);
+
  memdev_root = object_resolve_path("/objects", NULL);
  if (memdev_root) {
  object_child_foreach(memdev_root, pvrdma_check_ram_shared, 
_shared);


Reviewed-by: Marcel Apfelbaum 

Thanks,
Marcel



Re: [Qemu-devel] [PATCH v5 11/24] hw/pvrdma: Add support to allow guest to configure GID table

2018-11-24 Thread Marcel Apfelbaum




On 11/22/18 2:13 PM, Yuval Shaia wrote:

The control over the RDMA device's GID table is done by updating the
device's Ethernet function addresses.
Usually the first GID entry is determined by the MAC address, the second
by the first IPv6 address and the third by the IPv4 address. Other
entries can be added by adding more IP addresses. The opposite is the
same, i.e. whenever an address is removed, the corresponding GID entry
is removed.

The process is done by the network and RDMA stacks. Whenever an address
is added the ib_core driver is notified and calls the device driver
add_gid function which in turn update the device.

To support this in pvrdma device we need to hook into the create_bind
and destroy_bind HW commands triggered by pvrdma driver in guest.
Whenever changed is made to the pvrdma port's GID table a special QMP
messages is sent to be processed by libvirt to update the address of the
backend Ethernet device.

Signed-off-by: Yuval Shaia 
---
  hw/rdma/rdma_backend.c  | 336 +---
  hw/rdma/rdma_backend.h  |  22 +--
  hw/rdma/rdma_backend_defs.h |  11 +-
  hw/rdma/rdma_rm.c   | 104 ++-
  hw/rdma/rdma_rm.h   |  17 +-
  hw/rdma/rdma_rm_defs.h  |   9 +-
  hw/rdma/rdma_utils.h|  15 ++
  hw/rdma/vmw/pvrdma.h|   2 +-
  hw/rdma/vmw/pvrdma_cmd.c|  55 +++---
  hw/rdma/vmw/pvrdma_main.c   |  25 +--
  hw/rdma/vmw/pvrdma_qp_ops.c |  20 +++
  11 files changed, 453 insertions(+), 163 deletions(-)

diff --git a/hw/rdma/rdma_backend.c b/hw/rdma/rdma_backend.c
index 7c220a5798..8b5a111bf4 100644
--- a/hw/rdma/rdma_backend.c
+++ b/hw/rdma/rdma_backend.c
@@ -15,15 +15,18 @@
  
  #include "qemu/osdep.h"

  #include "qemu/error-report.h"
+#include "sysemu/sysemu.h"
  #include "qapi/error.h"
  #include "qapi/qmp/qlist.h"
  #include "qapi/qmp/qnum.h"
+#include "qapi/qapi-events-rdma.h"
  
  #include 

  #include 
  #include 
  #include 
  
+#include "contrib/rdmacm-mux/rdmacm-mux.h"

  #include "trace.h"
  #include "rdma_utils.h"
  #include "rdma_rm.h"
@@ -160,6 +163,71 @@ static void *comp_handler_thread(void *arg)
  return NULL;
  }
  
+static inline void disable_rdmacm_mux_async(RdmaBackendDev *backend_dev)

+{
+atomic_set(_dev->rdmacm_mux.can_receive, 0);
+}
+
+static inline void enable_rdmacm_mux_async(RdmaBackendDev *backend_dev)
+{
+atomic_set(_dev->rdmacm_mux.can_receive, sizeof(RdmaCmMuxMsg));


Why sizeof is used to set the can_receive field?


+}
+
+static inline int rdmacm_mux_can_process_async(RdmaBackendDev *backend_dev)
+{
+return atomic_read(_dev->rdmacm_mux.can_receive);
+}
+
+static int check_mux_op_status(CharBackend *mad_chr_be)
+{
+RdmaCmMuxMsg msg = {0};
+int ret;
+
+pr_dbg("Reading response\n");
+ret = qemu_chr_fe_read_all(mad_chr_be, (uint8_t *), sizeof(msg));
+if (ret != sizeof(msg)) {
+pr_dbg("Invalid message size %d, expecting %ld\n", ret, sizeof(msg));
+return -EIO;
+}
+
+if (msg.hdr.msg_type != RDMACM_MUX_MSG_TYPE_RESP) {
+pr_dbg("Invalid message type %d\n", msg.hdr.msg_type);
+return -EIO;
+}
+
+if (msg.hdr.err_code != RDMACM_MUX_ERR_CODE_OK) {
+pr_dbg("Operation failed in mux, error code %d\n", msg.hdr.err_code);
+return -EIO;
+}
+
+return 0;
+}
+
+static int exec_rdmacm_mux_req(RdmaBackendDev *backend_dev, RdmaCmMuxMsg *msg)
+{
+int rc = 0;
+
+pr_dbg("Executing request %d\n", msg->hdr.op_code);
+
+msg->hdr.msg_type = RDMACM_MUX_MSG_TYPE_REQ;
+disable_rdmacm_mux_async(backend_dev);
+rc = qemu_chr_fe_write(backend_dev->rdmacm_mux.chr_be,
+   (const uint8_t *)msg, sizeof(*msg));
+enable_rdmacm_mux_async(backend_dev);
+if (rc != sizeof(*msg)) {
+pr_dbg("Fail to send request to rdmacm_mux (rc=%d)\n", rc);
+return -EIO;
+}
+
+rc = check_mux_op_status(backend_dev->rdmacm_mux.chr_be);
+if (rc) {
+pr_dbg("Fail to execute rdmacm_mux request %d (rc=%d)\n",
+   msg->hdr.op_code, rc);
+}
+
+return 0;
+}
+
  static void stop_backend_thread(RdmaBackendThread *thread)
  {
  thread->run = false;
@@ -300,11 +368,11 @@ static int build_host_sge_array(RdmaDeviceResources 
*rdma_dev_res,
  return 0;
  }
  
-static int mad_send(RdmaBackendDev *backend_dev, struct ibv_sge *sge,

-uint32_t num_sge)
+static int mad_send(RdmaBackendDev *backend_dev, uint8_t sgid_idx,
+union ibv_gid *sgid, struct ibv_sge *sge, uint32_t num_sge)
  {
-struct backend_umad umad = {0};
-char *hdr, *msg;
+RdmaCmMuxMsg msg = {0};
+char *hdr, *data;
  int ret;
  
  pr_dbg("num_sge=%d\n", num_sge);

@@ -313,26 +381,31 @@ static int mad_send(RdmaBackendDev *backend_dev, struct 
ibv_sge *sge,
  return -EINVAL;
  }
  
-umad.hdr.length = sge[0].length + sge[1].length;

-pr_dbg("msg_len=%d\n", umad.hdr.length);
+msg.hdr.op_code = 

Re: [Qemu-devel] [PATCH v5 05/24] hw/rdma: Add support for MAD packets

2018-11-24 Thread Marcel Apfelbaum




On 11/22/18 2:13 PM, Yuval Shaia wrote:

MAD (Management Datagram) packets are widely used by various modules
both in kernel and in user space for example the rdma_* API which is
used to create and maintain "connection" layer on top of RDMA uses
several types of MAD packets.

For more information please refer to chapter 13.4 in Volume 1
Architecture Specification, Release 1.1 available here:
https://www.infinibandta.org/ibta-specifications-download/

To support MAD packets the device uses an external utility
(contrib/rdmacm-mux) to relay packets from and to the guest driver.

Signed-off-by: Yuval Shaia 
---
  hw/rdma/rdma_backend.c  | 275 +++-
  hw/rdma/rdma_backend.h  |   4 +-
  hw/rdma/rdma_backend_defs.h |  10 +-
  hw/rdma/vmw/pvrdma.h|   2 +
  hw/rdma/vmw/pvrdma_main.c   |   4 +-
  5 files changed, 285 insertions(+), 10 deletions(-)

diff --git a/hw/rdma/rdma_backend.c b/hw/rdma/rdma_backend.c
index 1e148398a2..7c220a5798 100644
--- a/hw/rdma/rdma_backend.c
+++ b/hw/rdma/rdma_backend.c
@@ -16,8 +16,13 @@
  #include "qemu/osdep.h"
  #include "qemu/error-report.h"
  #include "qapi/error.h"
+#include "qapi/qmp/qlist.h"
+#include "qapi/qmp/qnum.h"
  
  #include 

+#include 
+#include 
+#include 
  
  #include "trace.h"

  #include "rdma_utils.h"
@@ -33,16 +38,25 @@
  #define VENDOR_ERR_MAD_SEND 0x206
  #define VENDOR_ERR_INVLKEY  0x207
  #define VENDOR_ERR_MR_SMALL 0x208
+#define VENDOR_ERR_INV_MAD_BUFF 0x209
+#define VENDOR_ERR_INV_NUM_SGE  0x210
  
  #define THR_NAME_LEN 16

  #define THR_POLL_TO  5000
  
+#define MAD_HDR_SIZE sizeof(struct ibv_grh)

+
  typedef struct BackendCtx {
-uint64_t req_id;
  void *up_ctx;
  bool is_tx_req;
+struct ibv_sge sge; /* Used to save MAD recv buffer */
  } BackendCtx;
  
+struct backend_umad {

+struct ib_user_mad hdr;
+char mad[RDMA_MAX_PRIVATE_DATA];
+};
+
  static void (*comp_handler)(int status, unsigned int vendor_err, void *ctx);
  
  static void dummy_comp_handler(int status, unsigned int vendor_err, void *ctx)

@@ -286,6 +300,61 @@ static int build_host_sge_array(RdmaDeviceResources 
*rdma_dev_res,
  return 0;
  }
  
+static int mad_send(RdmaBackendDev *backend_dev, struct ibv_sge *sge,

+uint32_t num_sge)
+{
+struct backend_umad umad = {0};
+char *hdr, *msg;
+int ret;
+
+pr_dbg("num_sge=%d\n", num_sge);
+
+if (num_sge != 2) {
+return -EINVAL;
+}
+
+umad.hdr.length = sge[0].length + sge[1].length;
+pr_dbg("msg_len=%d\n", umad.hdr.length);
+
+if (umad.hdr.length > sizeof(umad.mad)) {
+return -ENOMEM;
+}
+
+umad.hdr.addr.qpn = htobe32(1);
+umad.hdr.addr.grh_present = 1;
+umad.hdr.addr.gid_index = backend_dev->backend_gid_idx;
+memcpy(umad.hdr.addr.gid, backend_dev->gid.raw, sizeof(umad.hdr.addr.gid));
+umad.hdr.addr.hop_limit = 1;
+
+hdr = rdma_pci_dma_map(backend_dev->dev, sge[0].addr, sge[0].length);
+if (!hdr) {
+pr_dbg("Fail to map to sge[0]\n");
+return -ENOMEM;
+}
+msg = rdma_pci_dma_map(backend_dev->dev, sge[1].addr, sge[1].length);
+if (!msg) {
+pr_dbg("Fail to map to sge[1]\n");
+rdma_pci_dma_unmap(backend_dev->dev, hdr, sge[0].length);
+return -ENOMEM;
+}
+
+pr_dbg_buf("mad_hdr", hdr, sge[0].length);
+pr_dbg_buf("mad_data", data, sge[1].length);
+
+memcpy([0], hdr, sge[0].length);
+memcpy([sge[0].length], msg, sge[1].length);
+
+rdma_pci_dma_unmap(backend_dev->dev, msg, sge[1].length);
+rdma_pci_dma_unmap(backend_dev->dev, hdr, sge[0].length);
+
+ret = qemu_chr_fe_write(backend_dev->mad_chr_be, (const uint8_t *),
+sizeof(umad));
+
+pr_dbg("qemu_chr_fe_write=%d\n", ret);
+
+return (ret != sizeof(umad));
+}
+
  void rdma_backend_post_send(RdmaBackendDev *backend_dev,
  RdmaBackendQP *qp, uint8_t qp_type,
  struct ibv_sge *sge, uint32_t num_sge,
@@ -304,9 +373,13 @@ void rdma_backend_post_send(RdmaBackendDev *backend_dev,
  comp_handler(IBV_WC_GENERAL_ERR, VENDOR_ERR_QP0, ctx);
  } else if (qp_type == IBV_QPT_GSI) {
  pr_dbg("QP1\n");
-comp_handler(IBV_WC_GENERAL_ERR, VENDOR_ERR_MAD_SEND, ctx);
+rc = mad_send(backend_dev, sge, num_sge);
+if (rc) {
+comp_handler(IBV_WC_GENERAL_ERR, VENDOR_ERR_MAD_SEND, ctx);
+} else {
+comp_handler(IBV_WC_SUCCESS, 0, ctx);
+}
  }
-pr_dbg("qp->ibqp is NULL for qp_type %d!!!\n", qp_type);
  return;
  }
  
@@ -370,6 +443,48 @@ out_free_bctx:

  g_free(bctx);
  }
  
+static unsigned int save_mad_recv_buffer(RdmaBackendDev *backend_dev,

+ struct ibv_sge *sge, uint32_t num_sge,
+ void *ctx)
+{
+BackendCtx 

Re: [Qemu-devel] [PATCH v2 15/21] pci-bridge/dec: Convert sysbus initfunction to realize function

2018-11-24 Thread maozy

Hi, Philippe

On 11/24/18 12:37 AM, Philippe Mathieu-Daudé wrote:

Hi Mao,

On 23/11/18 16:30, Mao Zhongyi wrote:

Use DeviceClass rather than SysBusDeviceClass in
pci_dec_21154_device_class_init().

Cc: da...@gibson.dropbear.id.au
Cc: m...@redhat.com
Cc: marcel.apfelb...@gmail.com
Cc: qemu-...@nongnu.org

Signed-off-by: Mao Zhongyi 
Signed-off-by: Zhang Shengju 
Reviewed-by: David Gibson 
Acked-by: David Gibson 
---
  hw/pci-bridge/dec.c | 11 +--
  1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/hw/pci-bridge/dec.c b/hw/pci-bridge/dec.c
index 84492d5e5f..5b21c20e50 100644
--- a/hw/pci-bridge/dec.c
+++ b/hw/pci-bridge/dec.c
@@ -98,7 +98,7 @@ PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn)
  return pci_bridge_get_sec_bus(br);
  }
  
-static int pci_dec_21154_device_init(SysBusDevice *dev)

+static void pci_dec_21154_device_realize(DeviceState *dev, Error **errp)
  {
  PCIHostState *phb;


Why don't you use:

SysBusDevice *sbd = SYS_BUS_DEVICE(dev);

like in all the other patches from this series...?


Oops, sorry, I missed this one, will fix it in v3.

Thanks,
Mao



  
@@ -108,9 +108,8 @@ static int pci_dec_21154_device_init(SysBusDevice *dev)

dev, "pci-conf-idx", 0x1000);
  memory_region_init_io(>data_mem, OBJECT(dev), _host_data_le_ops,
dev, "pci-data-idx", 0x1000);
-sysbus_init_mmio(dev, >conf_mem);
-sysbus_init_mmio(dev, >data_mem);
-return 0;
+sysbus_init_mmio(SYS_BUS_DEVICE(dev), >conf_mem);
+sysbus_init_mmio(SYS_BUS_DEVICE(dev), >data_mem);


... this would save extra type checking here, as explain by Peter:
https://lists.gnu.org/archive/html/qemu-devel/2018-11/msg03644.html


  }
  
  static void dec_21154_pci_host_realize(PCIDevice *d, Error **errp)

@@ -150,9 +149,9 @@ static const TypeInfo dec_21154_pci_host_info = {
  
  static void pci_dec_21154_device_class_init(ObjectClass *klass, void *data)

  {
-SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+DeviceClass *dc = DEVICE_CLASS(klass);
  
-sdc->init = pci_dec_21154_device_init;

+dc->realize = pci_dec_21154_device_realize;
  }
  
  static const TypeInfo pci_dec_21154_device_info = {










Re: [Qemu-devel] [PATCH v6 07/13] fpu: introduce hardfloat

2018-11-24 Thread Emilio G. Cota
On Sun, Nov 25, 2018 at 01:25:25 +0100, Aleksandar Markovic wrote:
> > Note: some architectures (at least PPC, there might be others) clear
> > the status flags passed to softfloat before most FP operations. This
> > precludes the use of hardfloat, so to avoid introducing a performance
> > regression for those targets, we add a flag to disable hardfloat.
> > In the long run though it would be good to fix the targets so that
> > at least the inexact flag passed to softfloat is indeed sticky.
> 
> Can you elaborate more on this paragraph?

Sure. We only use hardfloat when the inexact flag is already
set. If it isn't, we defer to softfloat. This is done for two
reasons:

- Computing the inexact flag requires duplicating
  most of what softfloat does, so it's not worth doing. Note
  that clearing and reading the host's fp flags is even
  slower, so that's not an option.

- The inexact flag is raised *very* frequently. The flag
  remains set (in the guest) unless guest code explicitly
  clears it, which few guest workloads do.

It therefore makes sense for hardfloat to only kick in once
the inexact flag has already been set.

Most targets directly keep the guest's FP flags in the same
struct (float_status) that is passed to softfloat ops.
PPC, however, keeps the state of the guest FP flags in one
place, and passes a pristine float_status to softfloat code
every time it calls it. Thus, given that hardfloat is
entirely implemented in softfloat.c, PPC targets cannot
currently take advantage of it.

Changing this in the PPC target is not impossible, but it will
require additional work that I'm not doing in this series, hence
my note. So for now, PPC targets just have hardfloat disabled
at compile time, which avoids adding overhead for a feature
that they cannot use.

Let me know if anything is unclear. Cheers,

Emilio



Re: [Qemu-devel] [PATCH 22/22] core/sysbus: remove the SysBusDeviceClass::initpath

2018-11-24 Thread maozy




On 11/24/18 2:19 AM, Peter Maydell wrote:

On Fri, 23 Nov 2018 at 18:16, Eduardo Habkost  wrote:

I think this is good enough for now (as long as there's a comment
like Peter suggested).  Allowing parent_realize to be NULL would
be inconvenient to all code that uses parent_realize today.


It was done in v2, please review.



Personally, I would love to get rid of parent_realize entirely.
We could simply provide a helper to let device subclasses call
the parent's realize function without the need to copy function
pointers around.


well, I will do it later.



Agreed -- parent_realize is a hack that is working around
a deficiency in our object model, and it would be nice to
deal with that. But let's do our cleanups one at a time :-)


OK, I see.

Thanks,
Mao



thanks
-- PMM







Re: [Qemu-devel] [PATCH v6 07/13] fpu: introduce hardfloat

2018-11-24 Thread Aleksandar Markovic
Hi, Emilio.

> Note: some architectures (at least PPC, there might be others) clear
> the status flags passed to softfloat before most FP operations. This
> precludes the use of hardfloat, so to avoid introducing a performance
> regression for those targets, we add a flag to disable hardfloat.
> In the long run though it would be good to fix the targets so that
> at least the inexact flag passed to softfloat is indeed sticky.

Can you elaborate more on this paragraph?

Thanks,
Aleksandar Markovic
On Nov 25, 2018 1:08 AM, "Emilio G. Cota"  wrote:

> The appended paves the way for leveraging the host FPU for a subset
> of guest FP operations. For most guest workloads (e.g. FP flags
> aren't ever cleared, inexact occurs often and rounding is set to the
> default [to nearest]) this will yield sizable performance speedups.
>
> The approach followed here avoids checking the FP exception flags register.
> See the added comment for details.
>
> This assumes that QEMU is running on an IEEE754-compliant FPU and
> that the rounding is set to the default (to nearest). The
> implementation-dependent specifics of the FPU should not matter; things
> like tininess detection and snan representation are still dealt with in
> soft-fp. However, this approach will break on most hosts if we compile
> QEMU with flags such as -ffast-math. We control the flags so this should
> be easy to enforce though.
>
> This patch just adds common code. Some operations will be migrated
> to hardfloat in subsequent patches to ease bisection.
>
> Note: some architectures (at least PPC, there might be others) clear
> the status flags passed to softfloat before most FP operations. This
> precludes the use of hardfloat, so to avoid introducing a performance
> regression for those targets, we add a flag to disable hardfloat.
> In the long run though it would be good to fix the targets so that
> at least the inexact flag passed to softfloat is indeed sticky.
>
> Signed-off-by: Emilio G. Cota 
> ---
>  fpu/softfloat.c | 315 
>  1 file changed, 315 insertions(+)
>
> diff --git a/fpu/softfloat.c b/fpu/softfloat.c
> index ecdc00c633..306a12fa8d 100644
> --- a/fpu/softfloat.c
> +++ b/fpu/softfloat.c
> @@ -83,6 +83,7 @@ this code that are retained.
>   * target-dependent and needs the TARGET_* macros.
>   */
>  #include "qemu/osdep.h"
> +#include 
>  #include "qemu/bitops.h"
>  #include "fpu/softfloat.h"
>
> @@ -95,6 +96,320 @@ this code that are retained.
>  *---
> -*/
>  #include "fpu/softfloat-macros.h"
>
> +/*
> + * Hardfloat
> + *
> + * Fast emulation of guest FP instructions is challenging for two reasons.
> + * First, FP instruction semantics are similar but not identical,
> particularly
> + * when handling NaNs. Second, emulating at reasonable speed the guest FP
> + * exception flags is not trivial: reading the host's flags register with
> a
> + * feclearexcept & fetestexcept pair is slow [slightly slower than
> soft-fp],
> + * and trapping on every FP exception is not fast nor pleasant to work
> with.
> + *
> + * We address these challenges by leveraging the host FPU for a subset of
> the
> + * operations. To do this we expand on the idea presented in this paper:
> + *
> + * Guo, Yu-Chuan, et al. "Translating the ARM Neon and VFP instructions
> in a
> + * binary translator." Software: Practice and Experience 46.12
> (2016):1591-1615.
> + *
> + * The idea is thus to leverage the host FPU to (1) compute FP operations
> + * and (2) identify whether FP exceptions occurred while avoiding
> + * expensive exception flag register accesses.
> + *
> + * An important optimization shown in the paper is that given that
> exception
> + * flags are rarely cleared by the guest, we can avoid recomputing some
> flags.
> + * This is particularly useful for the inexact flag, which is very
> frequently
> + * raised in floating-point workloads.
> + *
> + * We optimize the code further by deferring to soft-fp whenever FP
> exception
> + * detection might get hairy. Two examples: (1) when at least one operand
> is
> + * denormal/inf/NaN; (2) when operands are not guaranteed to lead to a 0
> result
> + * and the result is < the minimum normal.
> + */
> +#define GEN_INPUT_FLUSH__NOCHECK(name, soft_t)  \
> +static inline void name(soft_t *a, float_status *s) \
> +{   \
> +if (unlikely(soft_t ## _is_denormal(*a))) { \
> +*a = soft_t ## _set_sign(soft_t ## _zero,   \
> + soft_t ## _is_neg(*a));\
> +s->float_exception_flags |= float_flag_input_denormal;  \
> +}   \
> +}
> +
> +GEN_INPUT_FLUSH__NOCHECK(float32_input_flush__nocheck, float32)
> 

[Qemu-devel] [PATCH v6 13/13] hardfloat: implement float32/64 comparison

2018-11-24 Thread Emilio G. Cota
Performance results for fp-bench:

Host: Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz
- before:
cmp-single: 110.98 MFlops
cmp-double: 107.12 MFlops
- after:
cmp-single: 506.28 MFlops
cmp-double: 524.77 MFlops

Note that flattening both eq and eq_signaling versions
would give us extra performance (695v506, 615v524 Mflops
for single/double, respectively) but this would emit two
essentially identical functions for each eq/signaling pair,
which is a waste.

Aggregate performance improvement for the last few patches:
[ all charts in png: https://imgur.com/a/4yV8p ]

1. Host: Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz

   qemu-aarch64 NBench score; higher is better
 Host: Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz

  16 +-+---+-+===---+---===---+---+-+
  14 +-+..@@@&&.=...@@@&&.=...+-+
  12 +-+..@.@.&.=...@.@.&.=.+befor=== +-+
  10 +-+..@.@.&.=...@.@.&.=.+ad@@&& = +-+
   8 +-+...$$$%.@.&.=...@.@.&.=.+  @@u& = +-+
   6 +-+@@@&&=+***##.$%.@.&.=***##$$%+@.&.=..###$$%%@i& = +-+
   4 +-+...###$%%.@.&=.*.*.#.$%.@.&.=*.*.#.$%.@.&.=+**.#+$ +@m& = +-+
   2 +-+.***.#$.%.@.&=.*.*.#.$%.@.&.=*.*.#.$%.@.&.=.**.#+$+sqr& = +-+
   0 +-+-***##$%%@@&&=-***##$$%@@&&==***##$$%@@&&==-**##$$%+cmp==-+-+
FOURIERNEURAL NELU DECOMPOSITION gmean

  qemu-aarch64 SPEC06fp (test set) speedup over 
QEMU 4c2c1015905
  Host: Intel(R) Core(TM) i7-6700K CPU @ 
4.00GHz
error bars: 95% confidence interval

  4.5 
+-+---+-++-+-+-&---+-++-+-+-++-+-+-+-++-+---+-+
4 
+-+..+@@+...+-+
  3.5 
+-+..%%@&.@@..%%@&+++dsub
   +-+
  2.5 
+-+&&+...%%@&...+%%@..+%%&+..@@&+.%%@&+%%&+.+%@&++%%@&
  +-+
2 
+-+..+%%&..+%@&+.%%@&...+++..%%@...%%&.+$$@&..%%@&..%%@&...+%%&+.%%@&+..+%%@&.+%%&++$$@&++d%@&
  %%@&+-+
  1.5 
+-+**#$%&**#$@&**#%@&**$%@**#$%@**#$%&**#$@&**$%@&*#$%@**#$%@**#$%&**#%@&**$%@&*#$%@**#$%&**#$@&*+f%@&**$%@&+-+
  0.5 
+-+**#$%&**#$@&**#%@&**$%@**#$%@**#$%&**#$@&**$%@&*#$%@**#$%@**#$%&**#%@&**$%@&*#$%@**#$%&**#$@&+sqr@&**$%@&+-+
0 
+-+**#$%&**#$@&**#%@&**$%@**#$%@**#$%&**#$@&**$%@&*#$%@**#$%@**#$%&**#%@&**$%@&*#$%@**#$%&**#$@&*+cmp&**$%@&+-+
  
410.bw416.gam433.434.z435.436.cac437.lesli444.447.de450.so453454.ca459.GemsF465.tont470.lb4482.sphinxgeomean

2. Host: ARM Aarch64 A57 @ 2.4GHz

qemu-aarch64 NBench score; higher is better
 Host: Applied Micro X-Gene, Aarch64 A57 @ 2.4 GHz

5 +-+---+-+-+-+---+-+
  4.5 +-+@@@&==...+-+
  3 4 +-+..@@@&==@.@&.=.+before   +-+
3 +-+..@.@&.=@.@&.=.+ad@@@&== +-+
  2.5 +-+.##$$%%.@&.=@.@&.=.+  @m@& = +-+
2 +-+@@@&==.***#.$.%.@&.=.***#$$%%.@&.=.***#$$%%d@& = +-+
  1.5 +-+.***#$$%%.@&.=.*.*#.$.%.@&.=.*.*#.$.%.@&.=.*.*#+$ +f@& = +-+
  0.5 +-+.*.*#.$.%.@&.=.*.*#.$.%.@&.=.*.*#.$.%.@&.=.*.*#+$+sqr& = +-+
0 +-+-***#$$%%@@&==-***#$$%%@@&==-***#$$%%@@&==-***#$$%+cmp==-+-+
 FOURIERNEURAL NLU DECOMPOSITION gmean

Signed-off-by: Emilio G. Cota 
---
 fpu/softfloat.c | 109 +---
 1 file changed, 95 insertions(+), 14 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 4c6ecd1883..b29a2b6714 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -2899,28 +2899,109 @@ static int compare_floats(FloatParts a, FloatParts b, 
bool is_quiet,
 }
 }
 
-#define COMPARE(sz) \
-int float ## sz ## _compare(float ## sz a, float ## sz b,   \
-float_status *s)\
+#define COMPARE(name, attr, sz) \
+static int attr \
+name(float ## sz a, float ## sz b, bool is_quiet, float_status *s)  \
 {   \
 FloatParts pa = float ## sz ## _unpack_canonical(a, s); \
 FloatParts pb = float ## sz ## _unpack_canonical(b, s); \
-return compare_floats(pa, pb, false, s);\
-}   \
-int 

[Qemu-devel] [PATCH v6 07/13] fpu: introduce hardfloat

2018-11-24 Thread Emilio G. Cota
The appended paves the way for leveraging the host FPU for a subset
of guest FP operations. For most guest workloads (e.g. FP flags
aren't ever cleared, inexact occurs often and rounding is set to the
default [to nearest]) this will yield sizable performance speedups.

The approach followed here avoids checking the FP exception flags register.
See the added comment for details.

This assumes that QEMU is running on an IEEE754-compliant FPU and
that the rounding is set to the default (to nearest). The
implementation-dependent specifics of the FPU should not matter; things
like tininess detection and snan representation are still dealt with in
soft-fp. However, this approach will break on most hosts if we compile
QEMU with flags such as -ffast-math. We control the flags so this should
be easy to enforce though.

This patch just adds common code. Some operations will be migrated
to hardfloat in subsequent patches to ease bisection.

Note: some architectures (at least PPC, there might be others) clear
the status flags passed to softfloat before most FP operations. This
precludes the use of hardfloat, so to avoid introducing a performance
regression for those targets, we add a flag to disable hardfloat.
In the long run though it would be good to fix the targets so that
at least the inexact flag passed to softfloat is indeed sticky.

Signed-off-by: Emilio G. Cota 
---
 fpu/softfloat.c | 315 
 1 file changed, 315 insertions(+)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index ecdc00c633..306a12fa8d 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -83,6 +83,7 @@ this code that are retained.
  * target-dependent and needs the TARGET_* macros.
  */
 #include "qemu/osdep.h"
+#include 
 #include "qemu/bitops.h"
 #include "fpu/softfloat.h"
 
@@ -95,6 +96,320 @@ this code that are retained.
 **/
 #include "fpu/softfloat-macros.h"
 
+/*
+ * Hardfloat
+ *
+ * Fast emulation of guest FP instructions is challenging for two reasons.
+ * First, FP instruction semantics are similar but not identical, particularly
+ * when handling NaNs. Second, emulating at reasonable speed the guest FP
+ * exception flags is not trivial: reading the host's flags register with a
+ * feclearexcept & fetestexcept pair is slow [slightly slower than soft-fp],
+ * and trapping on every FP exception is not fast nor pleasant to work with.
+ *
+ * We address these challenges by leveraging the host FPU for a subset of the
+ * operations. To do this we expand on the idea presented in this paper:
+ *
+ * Guo, Yu-Chuan, et al. "Translating the ARM Neon and VFP instructions in a
+ * binary translator." Software: Practice and Experience 46.12 
(2016):1591-1615.
+ *
+ * The idea is thus to leverage the host FPU to (1) compute FP operations
+ * and (2) identify whether FP exceptions occurred while avoiding
+ * expensive exception flag register accesses.
+ *
+ * An important optimization shown in the paper is that given that exception
+ * flags are rarely cleared by the guest, we can avoid recomputing some flags.
+ * This is particularly useful for the inexact flag, which is very frequently
+ * raised in floating-point workloads.
+ *
+ * We optimize the code further by deferring to soft-fp whenever FP exception
+ * detection might get hairy. Two examples: (1) when at least one operand is
+ * denormal/inf/NaN; (2) when operands are not guaranteed to lead to a 0 result
+ * and the result is < the minimum normal.
+ */
+#define GEN_INPUT_FLUSH__NOCHECK(name, soft_t)  \
+static inline void name(soft_t *a, float_status *s) \
+{   \
+if (unlikely(soft_t ## _is_denormal(*a))) { \
+*a = soft_t ## _set_sign(soft_t ## _zero,   \
+ soft_t ## _is_neg(*a));\
+s->float_exception_flags |= float_flag_input_denormal;  \
+}   \
+}
+
+GEN_INPUT_FLUSH__NOCHECK(float32_input_flush__nocheck, float32)
+GEN_INPUT_FLUSH__NOCHECK(float64_input_flush__nocheck, float64)
+#undef GEN_INPUT_FLUSH__NOCHECK
+
+#define GEN_INPUT_FLUSH1(name, soft_t)  \
+static inline void name(soft_t *a, float_status *s) \
+{   \
+if (likely(!s->flush_inputs_to_zero)) { \
+return; \
+}   \
+soft_t ## _input_flush__nocheck(a, s);  \
+}
+
+GEN_INPUT_FLUSH1(float32_input_flush1, float32)
+GEN_INPUT_FLUSH1(float64_input_flush1, float64)
+#undef GEN_INPUT_FLUSH1
+
+#define GEN_INPUT_FLUSH2(name, soft_t)  \
+static inline void name(soft_t *a, 

[Qemu-devel] [PATCH v6 08/13] hardfloat: implement float32/64 addition and subtraction

2018-11-24 Thread Emilio G. Cota
Performance results (single and double precision) for fp-bench:

1. Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz
- before:
add-single: 135.07 MFlops
add-double: 131.60 MFlops
sub-single: 130.04 MFlops
sub-double: 133.01 MFlops
- after:
add-single: 443.04 MFlops
add-double: 301.95 MFlops
sub-single: 411.36 MFlops
sub-double: 293.15 MFlops

2. ARM Aarch64 A57 @ 2.4GHz
- before:
add-single: 44.79 MFlops
add-double: 49.20 MFlops
sub-single: 44.55 MFlops
sub-double: 49.06 MFlops
- after:
add-single: 93.28 MFlops
add-double: 88.27 MFlops
sub-single: 91.47 MFlops
sub-double: 88.27 MFlops

3. IBM POWER8E @ 2.1 GHz
- before:
add-single: 72.59 MFlops
add-double: 72.27 MFlops
sub-single: 75.33 MFlops
sub-double: 70.54 MFlops
- after:
add-single: 112.95 MFlops
add-double: 201.11 MFlops
sub-single: 116.80 MFlops
sub-double: 188.72 MFlops

Note that the IBM and ARM machines benefit from having
HARDFLOAT_2F{32,64}_USE_FP set to 0. Otherwise their performance
can suffer significantly:
- IBM Power8:
add-single: [1] 54.94 vs [0] 116.37 MFlops
add-double: [1] 58.92 vs [0] 201.44 MFlops
- Aarch64 A57:
add-single: [1] 80.72 vs [0] 93.24 MFlops
add-double: [1] 82.10 vs [0] 88.18 MFlops

On the Intel machine, having 2F64 set to 1 pays off, but it
doesn't for 2F32:
- Intel i7-6700K:
add-single: [1] 285.79 vs [0] 426.70 MFlops
add-double: [1] 302.15 vs [0] 278.82 MFlops

Signed-off-by: Emilio G. Cota 
---
 fpu/softfloat.c | 117 
 1 file changed, 98 insertions(+), 19 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 306a12fa8d..cc500b1618 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1050,49 +1050,128 @@ float16 QEMU_FLATTEN float16_add(float16 a, float16 b, 
float_status *status)
 return float16_round_pack_canonical(pr, status);
 }
 
-float32 QEMU_FLATTEN float32_add(float32 a, float32 b, float_status *status)
+float16 QEMU_FLATTEN float16_sub(float16 a, float16 b, float_status *status)
+{
+FloatParts pa = float16_unpack_canonical(a, status);
+FloatParts pb = float16_unpack_canonical(b, status);
+FloatParts pr = addsub_floats(pa, pb, true, status);
+
+return float16_round_pack_canonical(pr, status);
+}
+
+static float32 QEMU_SOFTFLOAT_ATTR
+soft_f32_addsub(float32 a, float32 b, bool subtract, float_status *status)
 {
 FloatParts pa = float32_unpack_canonical(a, status);
 FloatParts pb = float32_unpack_canonical(b, status);
-FloatParts pr = addsub_floats(pa, pb, false, status);
+FloatParts pr = addsub_floats(pa, pb, subtract, status);
 
 return float32_round_pack_canonical(pr, status);
 }
 
-float64 QEMU_FLATTEN float64_add(float64 a, float64 b, float_status *status)
+static inline float32 soft_f32_add(float32 a, float32 b, float_status *status)
+{
+return soft_f32_addsub(a, b, false, status);
+}
+
+static inline float32 soft_f32_sub(float32 a, float32 b, float_status *status)
+{
+return soft_f32_addsub(a, b, true, status);
+}
+
+static float64 QEMU_SOFTFLOAT_ATTR
+soft_f64_addsub(float64 a, float64 b, bool subtract, float_status *status)
 {
 FloatParts pa = float64_unpack_canonical(a, status);
 FloatParts pb = float64_unpack_canonical(b, status);
-FloatParts pr = addsub_floats(pa, pb, false, status);
+FloatParts pr = addsub_floats(pa, pb, subtract, status);
 
 return float64_round_pack_canonical(pr, status);
 }
 
-float16 QEMU_FLATTEN float16_sub(float16 a, float16 b, float_status *status)
+static inline float64 soft_f64_add(float64 a, float64 b, float_status *status)
 {
-FloatParts pa = float16_unpack_canonical(a, status);
-FloatParts pb = float16_unpack_canonical(b, status);
-FloatParts pr = addsub_floats(pa, pb, true, status);
+return soft_f64_addsub(a, b, false, status);
+}
 
-return float16_round_pack_canonical(pr, status);
+static inline float64 soft_f64_sub(float64 a, float64 b, float_status *status)
+{
+return soft_f64_addsub(a, b, true, status);
 }
 
-float32 QEMU_FLATTEN float32_sub(float32 a, float32 b, float_status *status)
+static float hard_f32_add(float a, float b)
 {
-FloatParts pa = float32_unpack_canonical(a, status);
-FloatParts pb = float32_unpack_canonical(b, status);
-FloatParts pr = addsub_floats(pa, pb, true, status);
+return a + b;
+}
 
-return float32_round_pack_canonical(pr, status);
+static float hard_f32_sub(float a, float b)
+{
+return a - b;
 }
 
-float64 QEMU_FLATTEN float64_sub(float64 a, float64 b, float_status *status)
+static double hard_f64_add(double a, double b)
 {
-FloatParts pa = float64_unpack_canonical(a, status);
-FloatParts pb = float64_unpack_canonical(b, status);
-FloatParts pr = addsub_floats(pa, pb, true, status);
+return a + b;
+}
 
-return float64_round_pack_canonical(pr, status);
+static double hard_f64_sub(double a, double b)
+{
+return a - b;
+}
+
+static bool f32_addsub_post(union_float32 a, union_float32 b)
+{
+if (QEMU_HARDFLOAT_2F32_USE_FP) {
+return 

[Qemu-devel] [PATCH v6 09/13] hardfloat: implement float32/64 multiplication

2018-11-24 Thread Emilio G. Cota
Performance results for fp-bench:

1. Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz
- before:
mul-single: 126.91 MFlops
mul-double: 118.28 MFlops
- after:
mul-single: 258.02 MFlops
mul-double: 197.96 MFlops

2. ARM Aarch64 A57 @ 2.4GHz
- before:
mul-single: 37.42 MFlops
mul-double: 38.77 MFlops
- after:
mul-single: 73.41 MFlops
mul-double: 76.93 MFlops

3. IBM POWER8E @ 2.1 GHz
- before:
mul-single: 58.40 MFlops
mul-double: 59.33 MFlops
- after:
mul-single: 60.25 MFlops
mul-double: 94.79 MFlops

Signed-off-by: Emilio G. Cota 
---
 fpu/softfloat.c | 54 +++--
 1 file changed, 52 insertions(+), 2 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index cc500b1618..58e67d9b80 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1232,7 +1232,8 @@ float16 QEMU_FLATTEN float16_mul(float16 a, float16 b, 
float_status *status)
 return float16_round_pack_canonical(pr, status);
 }
 
-float32 QEMU_FLATTEN float32_mul(float32 a, float32 b, float_status *status)
+static float32 QEMU_SOFTFLOAT_ATTR
+soft_f32_mul(float32 a, float32 b, float_status *status)
 {
 FloatParts pa = float32_unpack_canonical(a, status);
 FloatParts pb = float32_unpack_canonical(b, status);
@@ -1241,7 +1242,8 @@ float32 QEMU_FLATTEN float32_mul(float32 a, float32 b, 
float_status *status)
 return float32_round_pack_canonical(pr, status);
 }
 
-float64 QEMU_FLATTEN float64_mul(float64 a, float64 b, float_status *status)
+static float64 QEMU_SOFTFLOAT_ATTR
+soft_f64_mul(float64 a, float64 b, float_status *status)
 {
 FloatParts pa = float64_unpack_canonical(a, status);
 FloatParts pb = float64_unpack_canonical(b, status);
@@ -1250,6 +1252,54 @@ float64 QEMU_FLATTEN float64_mul(float64 a, float64 b, 
float_status *status)
 return float64_round_pack_canonical(pr, status);
 }
 
+static float hard_f32_mul(float a, float b)
+{
+return a * b;
+}
+
+static double hard_f64_mul(double a, double b)
+{
+return a * b;
+}
+
+static bool f32_mul_fast_test(union_float32 a, union_float32 b)
+{
+return float32_is_zero(a.s) || float32_is_zero(b.s);
+}
+
+static bool f64_mul_fast_test(union_float64 a, union_float64 b)
+{
+return float64_is_zero(a.s) || float64_is_zero(b.s);
+}
+
+static float32 f32_mul_fast_op(float32 a, float32 b, float_status *s)
+{
+bool signbit = float32_is_neg(a) ^ float32_is_neg(b);
+
+return float32_set_sign(float32_zero, signbit);
+}
+
+static float64 f64_mul_fast_op(float64 a, float64 b, float_status *s)
+{
+bool signbit = float64_is_neg(a) ^ float64_is_neg(b);
+
+return float64_set_sign(float64_zero, signbit);
+}
+
+float32 QEMU_FLATTEN
+float32_mul(float32 a, float32 b, float_status *s)
+{
+return float32_gen2(a, b, s, hard_f32_mul, soft_f32_mul,
+f32_is_zon2, NULL, f32_mul_fast_test, f32_mul_fast_op);
+}
+
+float64 QEMU_FLATTEN
+float64_mul(float64 a, float64 b, float_status *s)
+{
+return float64_gen2(a, b, s, hard_f64_mul, soft_f64_mul,
+f64_is_zon2, NULL, f64_mul_fast_test, f64_mul_fast_op);
+}
+
 /*
  * Returns the result of multiplying the floating-point values `a' and
  * `b' then adding 'c', with no intermediate rounding step after the
-- 
2.17.1




[Qemu-devel] [PATCH v6 11/13] hardfloat: implement float32/64 fused multiply-add

2018-11-24 Thread Emilio G. Cota
Performance results for fp-bench:

1. Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz
- before:
fma-single: 74.73 MFlops
fma-double: 74.54 MFlops
- after:
fma-single: 203.37 MFlops
fma-double: 169.37 MFlops

2. ARM Aarch64 A57 @ 2.4GHz
- before:
fma-single: 23.24 MFlops
fma-double: 23.70 MFlops
- after:
fma-single: 66.14 MFlops
fma-double: 63.10 MFlops

3. IBM POWER8E @ 2.1 GHz
- before:
fma-single: 37.26 MFlops
fma-double: 37.29 MFlops
- after:
fma-single: 48.90 MFlops
fma-double: 59.51 MFlops

Here having 3FP64 set to 1 pays off for x86_64:
[1] 170.15 vs [0] 153.12 MFlops

Signed-off-by: Emilio G. Cota 
---
 fpu/softfloat.c | 132 ++--
 1 file changed, 128 insertions(+), 4 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index e35ebfaae7..e03feafb6f 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1514,8 +1514,9 @@ float16 QEMU_FLATTEN float16_muladd(float16 a, float16 b, 
float16 c,
 return float16_round_pack_canonical(pr, status);
 }
 
-float32 QEMU_FLATTEN float32_muladd(float32 a, float32 b, float32 c,
-int flags, float_status 
*status)
+static float32 QEMU_SOFTFLOAT_ATTR
+soft_f32_muladd(float32 a, float32 b, float32 c, int flags,
+float_status *status)
 {
 FloatParts pa = float32_unpack_canonical(a, status);
 FloatParts pb = float32_unpack_canonical(b, status);
@@ -1525,8 +1526,9 @@ float32 QEMU_FLATTEN float32_muladd(float32 a, float32 b, 
float32 c,
 return float32_round_pack_canonical(pr, status);
 }
 
-float64 QEMU_FLATTEN float64_muladd(float64 a, float64 b, float64 c,
-int flags, float_status 
*status)
+static float64 QEMU_SOFTFLOAT_ATTR
+soft_f64_muladd(float64 a, float64 b, float64 c, int flags,
+float_status *status)
 {
 FloatParts pa = float64_unpack_canonical(a, status);
 FloatParts pb = float64_unpack_canonical(b, status);
@@ -1536,6 +1538,128 @@ float64 QEMU_FLATTEN float64_muladd(float64 a, float64 
b, float64 c,
 return float64_round_pack_canonical(pr, status);
 }
 
+float32 QEMU_FLATTEN
+float32_muladd(float32 xa, float32 xb, float32 xc, int flags, float_status *s)
+{
+union_float32 ua, ub, uc, ur;
+
+ua.s = xa;
+ub.s = xb;
+uc.s = xc;
+
+if (unlikely(!can_use_fpu(s))) {
+goto soft;
+}
+if (unlikely(flags & float_muladd_halve_result)) {
+goto soft;
+}
+
+float32_input_flush3(, , , s);
+if (unlikely(!f32_is_zon3(ua, ub, uc))) {
+goto soft;
+}
+/*
+ * When (a || b) == 0, there's no need to check for under/over flow,
+ * since we know the addend is (normal || 0) and the product is 0.
+ */
+if (float32_is_zero(ua.s) || float32_is_zero(ub.s)) {
+union_float32 up;
+bool prod_sign;
+
+prod_sign = float32_is_neg(ua.s) ^ float32_is_neg(ub.s);
+prod_sign ^= !!(flags & float_muladd_negate_product);
+up.s = float32_set_sign(float32_zero, prod_sign);
+
+if (flags & float_muladd_negate_c) {
+uc.h = -uc.h;
+}
+ur.h = up.h + uc.h;
+} else {
+if (flags & float_muladd_negate_product) {
+ua.h = -ua.h;
+}
+if (flags & float_muladd_negate_c) {
+uc.h = -uc.h;
+}
+
+ur.h = fmaf(ua.h, ub.h, uc.h);
+
+if (unlikely(f32_is_inf(ur))) {
+s->float_exception_flags |= float_flag_overflow;
+} else if (unlikely(fabsf(ur.h) <= FLT_MIN)) {
+goto soft;
+}
+}
+if (flags & float_muladd_negate_result) {
+return float32_chs(ur.s);
+}
+return ur.s;
+
+ soft:
+return soft_f32_muladd(ua.s, ub.s, uc.s, flags, s);
+}
+
+float64 QEMU_FLATTEN
+float64_muladd(float64 xa, float64 xb, float64 xc, int flags, float_status *s)
+{
+union_float64 ua, ub, uc, ur;
+
+ua.s = xa;
+ub.s = xb;
+uc.s = xc;
+
+if (unlikely(!can_use_fpu(s))) {
+goto soft;
+}
+if (unlikely(flags & float_muladd_halve_result)) {
+goto soft;
+}
+
+float64_input_flush3(, , , s);
+if (unlikely(!f64_is_zon3(ua, ub, uc))) {
+goto soft;
+}
+/*
+ * When (a || b) == 0, there's no need to check for under/over flow,
+ * since we know the addend is (normal || 0) and the product is 0.
+ */
+if (float64_is_zero(ua.s) || float64_is_zero(ub.s)) {
+union_float64 up;
+bool prod_sign;
+
+prod_sign = float64_is_neg(ua.s) ^ float64_is_neg(ub.s);
+prod_sign ^= !!(flags & float_muladd_negate_product);
+up.s = float64_set_sign(float64_zero, prod_sign);
+
+if (flags & float_muladd_negate_c) {
+uc.h = -uc.h;
+}
+ur.h = up.h + uc.h;
+} else {
+if (flags & float_muladd_negate_product) {
+ua.h = -ua.h;
+}
+if (flags & float_muladd_negate_c) {
+uc.h = -uc.h;
+}
+
+  

[Qemu-devel] [PATCH v6 06/13] tests/fp: add fp-bench

2018-11-24 Thread Emilio G. Cota
These microbenchmarks will allow us to measure the performance impact of
FP emulation optimizations. Note that we can measure both directly the impact
on the softfloat functions (with "-t soft"), or the impact on an
emulated workload (call with "-t host" and run under qemu user-mode).

Signed-off-by: Emilio G. Cota 
---
 tests/fp/fp-bench.c | 630 
 tests/fp/.gitignore |   1 +
 tests/fp/Makefile   |   5 +-
 3 files changed, 635 insertions(+), 1 deletion(-)
 create mode 100644 tests/fp/fp-bench.c

diff --git a/tests/fp/fp-bench.c b/tests/fp/fp-bench.c
new file mode 100644
index 00..f5bc5edebf
--- /dev/null
+++ b/tests/fp/fp-bench.c
@@ -0,0 +1,630 @@
+/*
+ * fp-bench.c - A collection of simple floating point microbenchmarks.
+ *
+ * Copyright (C) 2018, Emilio G. Cota 
+ *
+ * License: GNU GPL, version 2 or later.
+ *   See the COPYING file in the top-level directory.
+ */
+#ifndef HW_POISON_H
+#error Must define HW_POISON_H to work around TARGET_* poisoning
+#endif
+
+#include "qemu/osdep.h"
+#include 
+#include 
+#include "qemu/timer.h"
+#include "fpu/softfloat.h"
+
+/* amortize the computation of random inputs */
+#define OPS_PER_ITER 5
+
+#define MAX_OPERANDS 3
+
+#define SEED_A 0xdeadfacedeadface
+#define SEED_B 0xbadc0feebadc0fee
+#define SEED_C 0xbeefdeadbeefdead
+
+enum op {
+OP_ADD,
+OP_SUB,
+OP_MUL,
+OP_DIV,
+OP_FMA,
+OP_SQRT,
+OP_CMP,
+OP_MAX_NR,
+};
+
+static const char * const op_names[] = {
+[OP_ADD] = "add",
+[OP_SUB] = "sub",
+[OP_MUL] = "mul",
+[OP_DIV] = "div",
+[OP_FMA] = "mulAdd",
+[OP_SQRT] = "sqrt",
+[OP_CMP] = "cmp",
+[OP_MAX_NR] = NULL,
+};
+
+enum precision {
+PREC_SINGLE,
+PREC_DOUBLE,
+PREC_FLOAT32,
+PREC_FLOAT64,
+PREC_MAX_NR,
+};
+
+enum rounding {
+ROUND_EVEN,
+ROUND_ZERO,
+ROUND_DOWN,
+ROUND_UP,
+ROUND_TIEAWAY,
+N_ROUND_MODES,
+};
+
+static const char * const round_names[] = {
+[ROUND_EVEN] = "even",
+[ROUND_ZERO] = "zero",
+[ROUND_DOWN] = "down",
+[ROUND_UP] = "up",
+[ROUND_TIEAWAY] = "tieaway",
+};
+
+enum tester {
+TESTER_SOFT,
+TESTER_HOST,
+TESTER_MAX_NR,
+};
+
+static const char * const tester_names[] = {
+[TESTER_SOFT] = "soft",
+[TESTER_HOST] = "host",
+[TESTER_MAX_NR] = NULL,
+};
+
+union fp {
+float f;
+double d;
+float32 f32;
+float64 f64;
+uint64_t u64;
+};
+
+struct op_state;
+
+typedef float (*float_func_t)(const struct op_state *s);
+typedef double (*double_func_t)(const struct op_state *s);
+
+union fp_func {
+float_func_t float_func;
+double_func_t double_func;
+};
+
+typedef void (*bench_func_t)(void);
+
+struct op_desc {
+const char * const name;
+};
+
+#define DEFAULT_DURATION_SECS 1
+
+static uint64_t random_ops[MAX_OPERANDS] = {
+SEED_A, SEED_B, SEED_C,
+};
+static float_status soft_status;
+static enum precision precision;
+static enum op operation;
+static enum tester tester;
+static uint64_t n_completed_ops;
+static unsigned int duration = DEFAULT_DURATION_SECS;
+static int64_t ns_elapsed;
+/* disable optimizations with volatile */
+static volatile union fp res;
+
+/*
+ * From: https://en.wikipedia.org/wiki/Xorshift
+ * This is faster than rand_r(), and gives us a wider range (RAND_MAX is only
+ * guaranteed to be >= INT_MAX).
+ */
+static uint64_t xorshift64star(uint64_t x)
+{
+x ^= x >> 12; /* a */
+x ^= x << 25; /* b */
+x ^= x >> 27; /* c */
+return x * UINT64_C(2685821657736338717);
+}
+
+static void update_random_ops(int n_ops, enum precision prec)
+{
+int i;
+
+for (i = 0; i < n_ops; i++) {
+uint64_t r = random_ops[i];
+
+if (prec == PREC_SINGLE || PREC_FLOAT32) {
+do {
+r = xorshift64star(r);
+} while (!float32_is_normal(r));
+} else if (prec == PREC_DOUBLE || PREC_FLOAT64) {
+do {
+r = xorshift64star(r);
+} while (!float64_is_normal(r));
+} else {
+g_assert_not_reached();
+}
+random_ops[i] = r;
+}
+}
+
+static void fill_random(union fp *ops, int n_ops, enum precision prec,
+bool no_neg)
+{
+int i;
+
+for (i = 0; i < n_ops; i++) {
+switch (prec) {
+case PREC_SINGLE:
+case PREC_FLOAT32:
+ops[i].f32 = make_float32(random_ops[i]);
+if (no_neg && float32_is_neg(ops[i].f32)) {
+ops[i].f32 = float32_chs(ops[i].f32);
+}
+/* raise the exponent to limit the frequency of denormal results */
+ops[i].f32 |= 0x4000;
+break;
+case PREC_DOUBLE:
+case PREC_FLOAT64:
+ops[i].f64 = make_float64(random_ops[i]);
+if (no_neg && float64_is_neg(ops[i].f64)) {
+ops[i].f64 = float64_chs(ops[i].f64);
+}
+/* raise the exponent to limit the 

[Qemu-devel] [PATCH v6 03/13] target/tricore: use float32_is_denormal

2018-11-24 Thread Emilio G. Cota
Reviewed-by: Bastian Koppelmann 
Signed-off-by: Emilio G. Cota 
---
 target/tricore/fpu_helper.c | 9 ++---
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/target/tricore/fpu_helper.c b/target/tricore/fpu_helper.c
index df162902d6..31df462e4a 100644
--- a/target/tricore/fpu_helper.c
+++ b/target/tricore/fpu_helper.c
@@ -44,11 +44,6 @@ static inline uint8_t f_get_excp_flags(CPUTriCoreState *env)
   | float_flag_inexact);
 }
 
-static inline bool f_is_denormal(float32 arg)
-{
-return float32_is_zero_or_denormal(arg) && !float32_is_zero(arg);
-}
-
 static inline float32 f_maddsub_nan_result(float32 arg1, float32 arg2,
float32 arg3, float32 result,
uint32_t muladd_negate_c)
@@ -260,8 +255,8 @@ uint32_t helper_fcmp(CPUTriCoreState *env, uint32_t r1, 
uint32_t r2)
 set_flush_inputs_to_zero(0, >fp_status);
 
 result = 1 << (float32_compare_quiet(arg1, arg2, >fp_status) + 1);
-result |= f_is_denormal(arg1) << 4;
-result |= f_is_denormal(arg2) << 5;
+result |= float32_is_denormal(arg1) << 4;
+result |= float32_is_denormal(arg2) << 5;
 
 flags = f_get_excp_flags(env);
 if (flags) {
-- 
2.17.1




[Qemu-devel] [PATCH v6 04/13] softfloat: rename canonicalize to sf_canonicalize

2018-11-24 Thread Emilio G. Cota
glibc >= 2.25 defines canonicalize in commit eaf5ad0
(Add canonicalize, canonicalizef, canonicalizel., 2016-10-26).

Given that we'll be including  soon, prepare
for this by prefixing our canonicalize() with sf_ to avoid
clashing with the libc's canonicalize().

Reported-by: Bastian Koppelmann 
Tested-by: Bastian Koppelmann 
Signed-off-by: Emilio G. Cota 
---
 fpu/softfloat.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index e1eef954e6..ecdc00c633 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -336,8 +336,8 @@ static inline float64 float64_pack_raw(FloatParts p)
 #include "softfloat-specialize.h"
 
 /* Canonicalize EXP and FRAC, setting CLS.  */
-static FloatParts canonicalize(FloatParts part, const FloatFmt *parm,
-   float_status *status)
+static FloatParts sf_canonicalize(FloatParts part, const FloatFmt *parm,
+  float_status *status)
 {
 if (part.exp == parm->exp_max && !parm->arm_althp) {
 if (part.frac == 0) {
@@ -513,7 +513,7 @@ static FloatParts round_canonical(FloatParts p, 
float_status *s,
 static FloatParts float16a_unpack_canonical(float16 f, float_status *s,
 const FloatFmt *params)
 {
-return canonicalize(float16_unpack_raw(f), params, s);
+return sf_canonicalize(float16_unpack_raw(f), params, s);
 }
 
 static FloatParts float16_unpack_canonical(float16 f, float_status *s)
@@ -534,7 +534,7 @@ static float16 float16_round_pack_canonical(FloatParts p, 
float_status *s)
 
 static FloatParts float32_unpack_canonical(float32 f, float_status *s)
 {
-return canonicalize(float32_unpack_raw(f), _params, s);
+return sf_canonicalize(float32_unpack_raw(f), _params, s);
 }
 
 static float32 float32_round_pack_canonical(FloatParts p, float_status *s)
@@ -544,7 +544,7 @@ static float32 float32_round_pack_canonical(FloatParts p, 
float_status *s)
 
 static FloatParts float64_unpack_canonical(float64 f, float_status *s)
 {
-return canonicalize(float64_unpack_raw(f), _params, s);
+return sf_canonicalize(float64_unpack_raw(f), _params, s);
 }
 
 static float64 float64_round_pack_canonical(FloatParts p, float_status *s)
-- 
2.17.1




[Qemu-devel] [PATCH v6 10/13] hardfloat: implement float32/64 division

2018-11-24 Thread Emilio G. Cota
Performance results for fp-bench:

1. Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz
- before:
div-single: 34.84 MFlops
div-double: 34.04 MFlops
- after:
div-single: 275.23 MFlops
div-double: 216.38 MFlops

2. ARM Aarch64 A57 @ 2.4GHz
- before:
div-single: 9.33 MFlops
div-double: 9.30 MFlops
- after:
div-single: 51.55 MFlops
div-double: 15.09 MFlops

3. IBM POWER8E @ 2.1 GHz
- before:
div-single: 25.65 MFlops
div-double: 24.91 MFlops
- after:
div-single: 96.83 MFlops
div-double: 31.01 MFlops

Here setting 2FP64_USE_FP to 1 pays off for x86_64:
[1] 215.97 vs [0] 62.15 MFlops

Signed-off-by: Emilio G. Cota 
---
 fpu/softfloat.c | 64 +++--
 1 file changed, 62 insertions(+), 2 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 58e67d9b80..e35ebfaae7 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1624,7 +1624,8 @@ float16 float16_div(float16 a, float16 b, float_status 
*status)
 return float16_round_pack_canonical(pr, status);
 }
 
-float32 float32_div(float32 a, float32 b, float_status *status)
+static float32 QEMU_SOFTFLOAT_ATTR
+soft_f32_div(float32 a, float32 b, float_status *status)
 {
 FloatParts pa = float32_unpack_canonical(a, status);
 FloatParts pb = float32_unpack_canonical(b, status);
@@ -1633,7 +1634,8 @@ float32 float32_div(float32 a, float32 b, float_status 
*status)
 return float32_round_pack_canonical(pr, status);
 }
 
-float64 float64_div(float64 a, float64 b, float_status *status)
+static float64 QEMU_SOFTFLOAT_ATTR
+soft_f64_div(float64 a, float64 b, float_status *status)
 {
 FloatParts pa = float64_unpack_canonical(a, status);
 FloatParts pb = float64_unpack_canonical(b, status);
@@ -1642,6 +1644,64 @@ float64 float64_div(float64 a, float64 b, float_status 
*status)
 return float64_round_pack_canonical(pr, status);
 }
 
+static float hard_f32_div(float a, float b)
+{
+return a / b;
+}
+
+static double hard_f64_div(double a, double b)
+{
+return a / b;
+}
+
+static bool f32_div_pre(union_float32 a, union_float32 b)
+{
+if (QEMU_HARDFLOAT_2F32_USE_FP) {
+return (fpclassify(a.h) == FP_NORMAL || fpclassify(a.h) == FP_ZERO) &&
+   fpclassify(b.h) == FP_NORMAL;
+}
+return float32_is_zero_or_normal(a.s) && float32_is_normal(b.s);
+}
+
+static bool f64_div_pre(union_float64 a, union_float64 b)
+{
+if (QEMU_HARDFLOAT_2F64_USE_FP) {
+return (fpclassify(a.h) == FP_NORMAL || fpclassify(a.h) == FP_ZERO) &&
+   fpclassify(b.h) == FP_NORMAL;
+}
+return float64_is_zero_or_normal(a.s) && float64_is_normal(b.s);
+}
+
+static bool f32_div_post(union_float32 a, union_float32 b)
+{
+if (QEMU_HARDFLOAT_2F32_USE_FP) {
+return fpclassify(a.h) != FP_ZERO;
+}
+return !float32_is_zero(a.s);
+}
+
+static bool f64_div_post(union_float64 a, union_float64 b)
+{
+if (QEMU_HARDFLOAT_2F64_USE_FP) {
+return fpclassify(a.h) != FP_ZERO;
+}
+return !float64_is_zero(a.s);
+}
+
+float32 QEMU_FLATTEN
+float32_div(float32 a, float32 b, float_status *s)
+{
+return float32_gen2(a, b, s, hard_f32_div, soft_f32_div,
+f32_div_pre, f32_div_post, NULL, NULL);
+}
+
+float64 QEMU_FLATTEN
+float64_div(float64 a, float64 b, float_status *s)
+{
+return float64_gen2(a, b, s, hard_f64_div, soft_f64_div,
+f64_div_pre, f64_div_post, NULL, NULL);
+}
+
 /*
  * Float to Float conversions
  *
-- 
2.17.1




[Qemu-devel] [PATCH v6 01/13] fp-test: pick TARGET_ARM to get its specialization

2018-11-24 Thread Emilio G. Cota
This gets rid of the muladd errors due to not raising the invalid flag.

- Before:
Errors found in f64_mulAdd, rounding near_even, tininess before rounding:
+000.0  +7FF.0  +7FF.F
=> +7FF.F .  expected -7FF.F v
[...]

- After:
In 6133248 tests, no errors found in f64_mulAdd, rounding near_even, tininess 
before rounding.
[...]

Signed-off-by: Emilio G. Cota 
---
 tests/fp/Makefile | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tests/fp/Makefile b/tests/fp/Makefile
index d649a5a1db..49cdcd1bd2 100644
--- a/tests/fp/Makefile
+++ b/tests/fp/Makefile
@@ -29,6 +29,9 @@ QEMU_INCLUDES += -I$(TF_SOURCE_DIR)
 
 # work around TARGET_* poisoning
 QEMU_CFLAGS += -DHW_POISON_H
+# define a target to match testfloat's implementation-defined choices, such as
+# whether to raise the invalid flag when dealing with NaNs in muladd.
+QEMU_CFLAGS += -DTARGET_ARM
 
 # capstone has a platform.h file that clashes with softfloat's
 QEMU_CFLAGS := $(filter-out %capstone, $(QEMU_CFLAGS))
-- 
2.17.1




[Qemu-devel] [PATCH v6 00/13] hardfloat

2018-11-24 Thread Emilio G. Cota
v5: https://lists.gnu.org/archive/html/qemu-devel/2018-10/msg02793.html

Changes since v5:

- Rebase on rth/tcg-next-for-4.0

- Use QEMU_FLATTEN instead of __attribute__((flatten))

- Merge rth's cleanups (thanks!). With this, we now use a union to
  hold {float|float32} or {double|float64} types, which gets
  rid of most macros. I added a few optimizations (i.e. likely
  hints in some branches, and not using temp variables to hold
  the result of fpclassify) to roughly match (and sometimes
  surpass) v5's performance.

- float64_sqrt: use fpclassify, which gives a 1.5x speedup.

This series introduces no regressions to fp-test. You can test
hardfloat by passing "-f x" to fp-test (so that the inexact flag
is set before each operation) and using even rounding (fp-test's
default). Note that hardfloat does not affect operations with
other rounding modes.

Perf numbers for fp-bench running on several host machines are in
each commit log; numbers for several benchmarks (NBench, SPEC06fp)
are in the last patch's commit log. These numbers are a bit
outdated (they're from v2 or so), but I've decided to keep them
because they give a good idea of the speedups to expect, and I don't
have time to re-run them =)

I did re-run the numbers for sqrt and cmp, though, since the
implementation has changed quite a bit since v5. I didn't
re-run these on Aarch64 and PPC hosts due to lack of time,
but I doubt they'd change significantly.

You can fetch this series from:
  https://github.com/cota/qemu/tree/hardfloat-v6

Thanks,

Emilio





[Qemu-devel] [PATCH v6 12/13] hardfloat: implement float32/64 square root

2018-11-24 Thread Emilio G. Cota
Performance results for fp-bench:

Host: Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz
- before:
sqrt-single: 42.30 MFlops
sqrt-double: 22.97 MFlops
- after:
sqrt-single: 311.42 MFlops
sqrt-double: 311.08 MFlops

Here USE_FP makes a huge difference for f64's, with throughput
going from ~200 MFlops to ~300 MFlops.

Signed-off-by: Emilio G. Cota 
---
 fpu/softfloat.c | 60 +++--
 1 file changed, 58 insertions(+), 2 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index e03feafb6f..4c6ecd1883 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -3040,20 +3040,76 @@ float16 QEMU_FLATTEN float16_sqrt(float16 a, 
float_status *status)
 return float16_round_pack_canonical(pr, status);
 }
 
-float32 QEMU_FLATTEN float32_sqrt(float32 a, float_status *status)
+static float32 QEMU_SOFTFLOAT_ATTR
+soft_f32_sqrt(float32 a, float_status *status)
 {
 FloatParts pa = float32_unpack_canonical(a, status);
 FloatParts pr = sqrt_float(pa, status, _params);
 return float32_round_pack_canonical(pr, status);
 }
 
-float64 QEMU_FLATTEN float64_sqrt(float64 a, float_status *status)
+static float64 QEMU_SOFTFLOAT_ATTR
+soft_f64_sqrt(float64 a, float_status *status)
 {
 FloatParts pa = float64_unpack_canonical(a, status);
 FloatParts pr = sqrt_float(pa, status, _params);
 return float64_round_pack_canonical(pr, status);
 }
 
+float32 QEMU_FLATTEN float32_sqrt(float32 xa, float_status *s)
+{
+union_float32 ua, ur;
+
+ua.s = xa;
+if (unlikely(!can_use_fpu(s))) {
+goto soft;
+}
+
+float32_input_flush1(, s);
+if (QEMU_HARDFLOAT_1F32_USE_FP) {
+if (unlikely(!(fpclassify(ua.h) == FP_NORMAL ||
+   fpclassify(ua.h) == FP_ZERO) ||
+ signbit(ua.h))) {
+goto soft;
+}
+} else if (unlikely(!float32_is_zero_or_normal(ua.s) ||
+float32_is_neg(ua.s))) {
+goto soft;
+}
+ur.h = sqrtf(ua.h);
+return ur.s;
+
+ soft:
+return soft_f32_sqrt(ua.s, s);
+}
+
+float64 QEMU_FLATTEN float64_sqrt(float64 xa, float_status *s)
+{
+union_float64 ua, ur;
+
+ua.s = xa;
+if (unlikely(!can_use_fpu(s))) {
+goto soft;
+}
+
+float64_input_flush1(, s);
+if (QEMU_HARDFLOAT_1F64_USE_FP) {
+if (unlikely(!(fpclassify(ua.h) == FP_NORMAL ||
+   fpclassify(ua.h) == FP_ZERO) ||
+ signbit(ua.h))) {
+goto soft;
+}
+} else if (unlikely(!float64_is_zero_or_normal(ua.s) ||
+float64_is_neg(ua.s))) {
+goto soft;
+}
+ur.h = sqrt(ua.h);
+return ur.s;
+
+ soft:
+return soft_f64_sqrt(ua.s, s);
+}
+
 /*
 | The pattern for a default generated NaN.
 **/
-- 
2.17.1




[Qemu-devel] [PATCH v6 02/13] softfloat: add float{32, 64}_is_{de, }normal

2018-11-24 Thread Emilio G. Cota
This paves the way for upcoming work.

Reviewed-by: Bastian Koppelmann 
Reviewed-by: Alex Bennée 
Signed-off-by: Emilio G. Cota 
---
 include/fpu/softfloat.h | 20 
 1 file changed, 20 insertions(+)

diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 8fd9f9bbae..9eeccd88a5 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -464,6 +464,16 @@ static inline int float32_is_zero_or_denormal(float32 a)
 return (float32_val(a) & 0x7f80) == 0;
 }
 
+static inline bool float32_is_normal(float32 a)
+{
+return ((float32_val(a) + 0x0080) & 0x7fff) >= 0x0100;
+}
+
+static inline bool float32_is_denormal(float32 a)
+{
+return float32_is_zero_or_denormal(a) && !float32_is_zero(a);
+}
+
 static inline float32 float32_set_sign(float32 a, int sign)
 {
 return make_float32((float32_val(a) & 0x7fff) | (sign << 31));
@@ -605,6 +615,16 @@ static inline int float64_is_zero_or_denormal(float64 a)
 return (float64_val(a) & 0x7ff0LL) == 0;
 }
 
+static inline bool float64_is_normal(float64 a)
+{
+return ((float64_val(a) + (1ULL << 52)) & -1ULL >> 1) >= 1ULL << 53;
+}
+
+static inline bool float64_is_denormal(float64 a)
+{
+return float64_is_zero_or_denormal(a) && !float64_is_zero(a);
+}
+
 static inline float64 float64_set_sign(float64 a, int sign)
 {
 return make_float64((float64_val(a) & 0x7fffULL)
-- 
2.17.1




[Qemu-devel] [PATCH v6 05/13] softfloat: add float{32, 64}_is_zero_or_normal

2018-11-24 Thread Emilio G. Cota
These will gain some users very soon.

Signed-off-by: Emilio G. Cota 
---
 include/fpu/softfloat.h | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 9eeccd88a5..38a5e99cf3 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -474,6 +474,11 @@ static inline bool float32_is_denormal(float32 a)
 return float32_is_zero_or_denormal(a) && !float32_is_zero(a);
 }
 
+static inline bool float32_is_zero_or_normal(float32 a)
+{
+return float32_is_normal(a) || float32_is_zero(a);
+}
+
 static inline float32 float32_set_sign(float32 a, int sign)
 {
 return make_float32((float32_val(a) & 0x7fff) | (sign << 31));
@@ -625,6 +630,11 @@ static inline bool float64_is_denormal(float64 a)
 return float64_is_zero_or_denormal(a) && !float64_is_zero(a);
 }
 
+static inline bool float64_is_zero_or_normal(float64 a)
+{
+return float64_is_normal(a) || float64_is_zero(a);
+}
+
 static inline float64 float64_set_sign(float64 a, int sign)
 {
 return make_float64((float64_val(a) & 0x7fffULL)
-- 
2.17.1




Re: [Qemu-devel] [PATCH] hax: Support for Linux hosts

2018-11-24 Thread Kamil Rytarowski
On 22.11.2018 08:24, Kamil Rytarowski wrote:
> On 16.11.2018 13:52, Paolo Bonzini wrote:
>> On 14/11/18 14:04, Alexandro Sanchez Bach wrote:
>>> Intel HAXM supports now 32-bit and 64-bit Linux hosts. This patch includes
>>> the corresponding userland changes.
>>>
>>> Since the Darwin userland backend is POSIX-compliant, the hax-darwin.{c,h}
>>> files have been renamed to hax-posix.{c,h}. This prefix is consistent with
>>> the naming used in the rest of QEMU.
>>
>> What's the advantage of HAXM when Linux hosts can just run KVM?  I guess
>> avoiding bitrot?
>>
>> Paolo
>>
> 
> This patch is also useful for NetBSD, even if it's not a Linux host.
> There is a driver in progress again (thanks to the newly added Linux
> port, it's now much easier to get done).
> 
> I recommend to merge this patch.
> 

For the record, I've a functional version of HAXM for NetBSD as host.
Once you will merge this patch, I will submit another one to configure
to enable haxm for NetBSD.

I need to keep the patch by Alexandro in a local copy of qemu.



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [qemu-s390x] [PATCH 0/3] vfio-ccw: support hsch/csch (kernel part)

2018-11-24 Thread Halil Pasic
On Thu, 22 Nov 2018 17:54:29 +0100
Cornelia Huck  wrote:

> [This is the Linux kernel part, git tree is available at
> https://git.kernel.org/pub/scm/linux/kernel/git/kvms390/vfio-ccw.git
> vfio-ccw-caps
> 
> The companion QEMU patches are available at
> https://github.com/cohuck/qemu vfio-ccw-caps]
> 
> Currently, vfio-ccw only relays START SUBCHANNEL requests to the real
> device. This tends to work well for the most common 'good path'
> scenarios; however, as we emulate {HALT,CLEAR} SUBCHANNEL in QEMU,
> things like clearing pending requests at the device is currently not
> supported. This may be a problem for e.g. error recovery.
> 
> This patch series introduces capabilities (similar to what vfio-pci
> uses) and exposes a new async region for handling hsch/csch.

I'm on vacation and could not do more than skim over it real quick. FWIW
it looks very promising. I intend to give it an in depth review once I'm
back (i.e. second half of next week).

Regards,
Halil




[Qemu-devel] [Bug 1804961] Re: qemu-system-aarch64: Windows 10 ARM64 BSoD on boot while using virt-3.0

2018-11-24 Thread GH Cao
** Description changed:

  When I emulate a virt-3.0 machine, Windows 10 BSoD on boot, with the
  error code being ACPI_BIOS_ERROR(0x00A5), virt-2.12 boots fine.
  
  Windows Build: 10.0.17134.1
  QEMU version: 3.0.0
  Commandline: qemu-system-aarch64 -M virt -accel tcg,thread=multi -cpu 
cortex-a57 -smp 2 -m 2048 -bios QEMU_EFI.fd -device ramfb -device nec-usb-xhci 
-device usb-kbd -device usb-tablet -hda disk.vhd -vnc :0
  
  By the way, the patch to add DBG2 table discussed here
- https://lists.gnu.org/archive/html/qemu-devel/2015-09/msg02550.html
+ https://lists.gnu.org/archive/html/qemu-devel/2015-09/msg01719.html
  works (although minor change is required to adapt to the qemu 3.0.0
  code), the table is accepted by Windows (Windows require both DBG2 and
  SPCR to be valid for serial kernel debugging to work), so it may help
  further diagnosing this issue.

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1804961

Title:
  qemu-system-aarch64: Windows 10 ARM64 BSoD on boot while using
  virt-3.0

Status in QEMU:
  New

Bug description:
  When I emulate a virt-3.0 machine, Windows 10 BSoD on boot, with the
  error code being ACPI_BIOS_ERROR(0x00A5), virt-2.12 boots fine.

  Windows Build: 10.0.17134.1
  QEMU version: 3.0.0
  Commandline: qemu-system-aarch64 -M virt -accel tcg,thread=multi -cpu 
cortex-a57 -smp 2 -m 2048 -bios QEMU_EFI.fd -device ramfb -device nec-usb-xhci 
-device usb-kbd -device usb-tablet -hda disk.vhd -vnc :0

  By the way, the patch to add DBG2 table discussed here
  https://lists.gnu.org/archive/html/qemu-devel/2015-09/msg01719.html
  works (although minor change is required to adapt to the qemu 3.0.0
  code), the table is accepted by Windows (Windows require both DBG2 and
  SPCR to be valid for serial kernel debugging to work), so it may help
  further diagnosing this issue.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1804961/+subscriptions



[Qemu-devel] [Bug 1804961] [NEW] qemu-system-aarch64: Windows 10 ARM64 BSoD on boot while using virt-3.0

2018-11-24 Thread GH Cao
Public bug reported:

When I emulate a virt-3.0 machine, Windows 10 BSoD on boot, with the
error code being ACPI_BIOS_ERROR(0x00A5), virt-2.12 boots fine.

Windows Build: 10.0.17134.1
QEMU version: 3.0.0
Commandline: qemu-system-aarch64 -M virt -accel tcg,thread=multi -cpu 
cortex-a57 -smp 2 -m 2048 -bios QEMU_EFI.fd -device ramfb -device nec-usb-xhci 
-device usb-kbd -device usb-tablet -hda disk.vhd -vnc :0

By the way, the patch to add DBG2 table discussed here
https://lists.gnu.org/archive/html/qemu-devel/2015-09/msg02550.html
works (although minor change is required to adapt to the qemu 3.0.0
code), the table is accepted by Windows (Windows require both DBG2 and
SPCR to be valid for serial kernel debugging to work), so it may help
further diagnosing this issue.

** Affects: qemu
 Importance: Undecided
 Status: New

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1804961

Title:
  qemu-system-aarch64: Windows 10 ARM64 BSoD on boot while using
  virt-3.0

Status in QEMU:
  New

Bug description:
  When I emulate a virt-3.0 machine, Windows 10 BSoD on boot, with the
  error code being ACPI_BIOS_ERROR(0x00A5), virt-2.12 boots fine.

  Windows Build: 10.0.17134.1
  QEMU version: 3.0.0
  Commandline: qemu-system-aarch64 -M virt -accel tcg,thread=multi -cpu 
cortex-a57 -smp 2 -m 2048 -bios QEMU_EFI.fd -device ramfb -device nec-usb-xhci 
-device usb-kbd -device usb-tablet -hda disk.vhd -vnc :0

  By the way, the patch to add DBG2 table discussed here
  https://lists.gnu.org/archive/html/qemu-devel/2015-09/msg02550.html
  works (although minor change is required to adapt to the qemu 3.0.0
  code), the table is accepted by Windows (Windows require both DBG2 and
  SPCR to be valid for serial kernel debugging to work), so it may help
  further diagnosing this issue.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1804961/+subscriptions



[Qemu-devel] [Bug 1802465] Re: typing string via VNC is unreliable

2018-11-24 Thread Gao
In my case the problem is quite subtle. 
Nearly every time we send the key strokes, the guest os keeps receiving space 
or tab or new line character. And ending part of the text is truncated, where 
the truncated part is fixed depending on the keystrokes we are sending. 
Additionally, the keystrokes are mis-ordered at a higher frequency than 1 out 
of a few hundreds as you said. 

In brief,
- Repeatedly receiving space, tab or new line character as ending
- Truncation regarding ending part of key strokes
- characters are mis-ordered, lost, repeated 

A question is, how can you make character transaction faster with
vncdotool? In my case, vncdotool is typing fairly slow.

I found this debian bug report quite useful, what do you think?
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=758881

Re-producing procedures
---

I re-produced the problem in a slightly different way since your method
seems not working for me.

> qemu-img create tumbleweed.img 40G
> qemu-system-x86_64 -drive file=tumbleweed.img,if=virtio -boot d -cdrom 
> openSUSE-Tumbleweed-DVD-x86_64-Snapshot20181119-Media.iso -m 2048 
> --enable-kvm -display vnc=:1
> qemu-system-x86_64 -drive file=tumbleweed.img,if=virtio  -m 4G --enable-kvm 
> -display vnc=:1

** Bug watch added: Debian Bug tracker #758881
   https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=758881

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1802465

Title:
  typing string via VNC is unreliable

Status in QEMU:
  New

Bug description:
  QEMU version is 3.0.0

  # Description

  The problem is that, when typing string through VNC, it can be
  unreliable -- sometimes some key strokes get skipped, sometimes get
  swapped, sometimes get repeated.  There's no problem when typing
  through VNC on physical hardware.

  # Steps to reproduce

  1. Launch virtual machine by:

  qemu-kvm -display vnc=:1 -m 2048 opensuse-leap-15.qcow2

  2. Connect to VNC by:

  vncviewer -Shared :5901

  3. Simulate a series of key strokes by "vncdotool" [1]:

  vncdotool -s 127.0.0.1::5901 typefile strings_to_be_typed.txt

  4. Usually after a few hundred keys are typed, something goes wrong.

  I attached a screenshot that it mistypes " hello" to "h ello".

  [1] https://github.com/sibson/vncdotool

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1802465/+subscriptions



Re: [Qemu-devel] [PATCH V8 00/10] add pvpanic mmio support

2018-11-24 Thread no-reply
Hi,

This series failed docker-mingw@fedora build test. Please find the testing 
commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.

Type: series
Subject: [Qemu-devel] [PATCH V8 00/10] add pvpanic mmio support
Message-id: 1543078821-16636-1-git-send-email-peng.h...@zte.com.cn

=== TEST SCRIPT BEGIN ===
#!/bin/bash
time make docker-test-mingw@fedora SHOW_ENV=1 J=8
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
ba5859d pvpanic : update pvpanic document
e9ae729 hw/misc/pvpanic: realize the configure interface
8bb0b2c hw/misc/pvpanic: preparing for adding configure interface
3899ae7 hw/misc/pvpanic: add configure query interface
ea4cfe2 hw/arm/virt: add pvpanic device in virt acpi table
aeef256 hw/arm/virt: Use the pvpanic device
8042df6 hw/misc/pvpanic: moving structure definition to header file
cbc9265 hw/misc/pvpanic: Add the MMIO interface
e3f8879 hw/misc/pvpanic: Cosmetic renaming
c9bb96f hw/misc/pvpanic: Build the pvpanic device in $(common-obj)

=== OUTPUT BEGIN ===
  BUILD   fedora
make[1]: Entering directory `/var/tmp/patchew-tester-tmp-snk798eu/src'
  GEN 
/var/tmp/patchew-tester-tmp-snk798eu/src/docker-src.2018-11-24-04.02.53.28932/qemu.tar
Cloning into 
'/var/tmp/patchew-tester-tmp-snk798eu/src/docker-src.2018-11-24-04.02.53.28932/qemu.tar.vroot'...
done.
Checking out files:  46% (3013/6463)   
Checking out files:  47% (3038/6463)   
Checking out files:  48% (3103/6463)   
Checking out files:  49% (3167/6463)   
Checking out files:  50% (3232/6463)   
Checking out files:  51% (3297/6463)   
Checking out files:  52% (3361/6463)   
Checking out files:  53% (3426/6463)   
Checking out files:  54% (3491/6463)   
Checking out files:  55% (3555/6463)   
Checking out files:  56% (3620/6463)   
Checking out files:  57% (3684/6463)   
Checking out files:  58% (3749/6463)   
Checking out files:  59% (3814/6463)   
Checking out files:  60% (3878/6463)   
Checking out files:  61% (3943/6463)   
Checking out files:  62% (4008/6463)   
Checking out files:  63% (4072/6463)   
Checking out files:  64% (4137/6463)   
Checking out files:  65% (4201/6463)   
Checking out files:  66% (4266/6463)   
Checking out files:  67% (4331/6463)   
Checking out files:  68% (4395/6463)   
Checking out files:  69% (4460/6463)   
Checking out files:  70% (4525/6463)   
Checking out files:  71% (4589/6463)   
Checking out files:  72% (4654/6463)   
Checking out files:  73% (4718/6463)   
Checking out files:  74% (4783/6463)   
Checking out files:  75% (4848/6463)   
Checking out files:  76% (4912/6463)   
Checking out files:  77% (4977/6463)   
Checking out files:  78% (5042/6463)   
Checking out files:  79% (5106/6463)   
Checking out files:  80% (5171/6463)   
Checking out files:  81% (5236/6463)   
Checking out files:  82% (5300/6463)   
Checking out files:  83% (5365/6463)   
Checking out files:  84% (5429/6463)   
Checking out files:  85% (5494/6463)   
Checking out files:  86% (5559/6463)   
Checking out files:  87% (5623/6463)   
Checking out files:  88% (5688/6463)   
Checking out files:  89% (5753/6463)   
Checking out files:  90% (5817/6463)   
Checking out files:  91% (5882/6463)   
Checking out files:  92% (5946/6463)   
Checking out files:  93% (6011/6463)   
Checking out files:  94% (6076/6463)   
Checking out files:  95% (6140/6463)   
Checking out files:  96% (6205/6463)   
Checking out files:  97% (6270/6463)   
Checking out files:  98% (6334/6463)   
Checking out files:  99% (6399/6463)   
Checking out files: 100% (6463/6463)   
Checking out files: 100% (6463/6463), done.
Submodule 'dtc' (https://git.qemu.org/git/dtc.git) registered for path 'dtc'
Cloning into 'dtc'...
Submodule path 'dtc': checked out '88f18909db731a627456f26d779445f84e449536'
Submodule 'ui/keycodemapdb' (https://git.qemu.org/git/keycodemapdb.git) 
registered for path 'ui/keycodemapdb'
Cloning into 'ui/keycodemapdb'...
Submodule path 'ui/keycodemapdb': checked out 
'6b3d716e2b6472eb7189d3220552280ef3d832ce'
  COPYRUNNER
RUN test-mingw in qemu:fedora 
Packages installed:
SDL2-devel-2.0.9-1.fc28.x86_64
bc-1.07.1-5.fc28.x86_64
bison-3.0.4-9.fc28.x86_64
bluez-libs-devel-5.50-1.fc28.x86_64
brlapi-devel-0.6.7-19.fc28.x86_64
bzip2-1.0.6-26.fc28.x86_64
bzip2-devel-1.0.6-26.fc28.x86_64
ccache-3.4.2-2.fc28.x86_64
clang-6.0.1-2.fc28.x86_64
device-mapper-multipath-devel-0.7.4-3.git07e7bd5.fc28.x86_64
findutils-4.6.0-19.fc28.x86_64
flex-2.6.1-7.fc28.x86_64
gcc-8.2.1-5.fc28.x86_64
gcc-c++-8.2.1-5.fc28.x86_64
gettext-0.19.8.1-14.fc28.x86_64
git-2.17.2-1.fc28.x86_64
glib2-devel-2.56.3-2.fc28.x86_64
glusterfs-api-devel-4.1.5-1.fc28.x86_64
gnutls-devel-3.6.4-1.fc28.x86_64
gtk3-devel-3.22.30-1.fc28.x86_64
hostname-3.20-3.fc28.x86_64
libaio-devel-0.3.110-11.fc28.x86_64
libasan-8.2.1-5.fc28.x86_64
libattr-devel-2.4.48-3.fc28.x86_64
libcap-devel-2.25-9.fc28.x86_64
libcap-ng-devel-0.7.9-4.fc28.x86_64
libcurl-devel-7.59.0-8.fc28.x86_64

Re: [Qemu-devel] [PATCH 10/10] pvpanic : update pvpanic document

2018-11-24 Thread peng.hao2
I'm sorry to sent patches with unmodified title. 
Please ignore patch 1-10. I will re-send.
>Add mmio support info in docs/specs/pvpanic.txt.
>
>Signed-off-by: Peng Hao 
>---
>docs/specs/pvpanic.txt | 18 +++---
>1 file changed, 15 insertions(+), 3 deletions(-)
>
>diff --git a/docs/specs/pvpanic.txt b/docs/specs/pvpanic.txt
>index c7bbacc..2d06ee5 100644
>--- a/docs/specs/pvpanic.txt
>+++ b/docs/specs/pvpanic.txt
>@@ -1,14 +1,18 @@
>PVPANIC DEVICE
>==
>-pvpanic device is a simulated ISA device, through which a guest panic
>-event is sent to qemu, and a QMP event is generated. This allows
>+pvpanic device is a simulated ISA/SysBus device, through which a guest
>+panic event is sent to qemu, and a QMP event is generated. This allows
>management apps (e.g. libvirt) to be notified and respond to the event.
>-The management app has the option of waiting for GUEST_PANICKED events,
>+The ma:wqnagement app has the option of waiting for GUEST_PANICKED events,
>and/or polling for guest-panicked RunState, to learn when the pvpanic
>device has fired a panic event.
>+When pvpanic device is implemented as a ISA device, it supports IOPORT
>+mode. Since QEMU v3.2 pvpanic also supports MMIO mode, it will be
>+implemented as a SYSBUS device.
>+
>ISA Interface
>-
>@@ -19,6 +23,14 @@ Software should set only bits both itself and the device 
>recognize.
>Currently, only bit 0 is recognized, setting it indicates a guest panic
>has happened.
>+SYSBUS Interface
>+
>+
>+The SYSBUS interface is similar to the ISA interface except that it uses
>+MMIO. For example, the arm virt machine could put the pvpanic device at
>+[0x907, 0x9070001] and currently only the first byte is used.
>+
>+
>ACPI Interface
>--
>--
>1.8.3.1

[Qemu-devel] [PATCH V8 00/10] add pvpanic mmio support

2018-11-24 Thread Peng Hao
The first patches are simple cleanups:
 - patch 1 move the pvpanic device with the 'ocmmon objects' so we compile
   it once for the x86/arm/aarch64 archs,
 - patch 2 simply renames ISA fields/definitions to generic ones.
 
 Then instead of add/use the MMIO pvpanic device in the virt machine in an
 unique patch, I split it in two distinct patches:
 - patch 3 uses Peng Hao's work, but add the MMIO interface to the existing
device (no logical change).
 - patch 4 is Peng Hao's work in the virt machine (no logical change).
 - patch 5 add pvpanic device in acpi table in virt machine
 v2 from Peng Hao is:
 https://lists.gnu.org/archive/html/qemu-devel/2018-10/msg03433.html

v3 --> v4
 patch 1,2 no modification.
 patch 3, add TYPE_PANIC_MMIO for distinguishing different bus device,
  virt + isa_pvpanic will abnormally terminate virtual machine.
 patch 4, "pvpanic,mmio" --> "qemu,pvpanic-mmio".
 patch 5, newly added.

v4 --> v5
 patch 1,2 no modification.
 patch 3 delete PvpanicCommonState structure.
 patch 4 VIRT_PVPANIC_MMIO --> VIRT_PVPANIC
 correct VIRT_PVPANIC's overlap start address
 patch 5 no modification.

v5 --> v6
 add document.
  
v6 --> v7
 patch 5 modify device name from "PANC" to "PEVT".
 patch 6 modify document description.

v7 --> v8
 add configure interface for pvpanic-mmio

the kernel part of the series:
 
https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git/log/?h=char-misc-testing
 misc/pvpanic: remove a redundant comma
 misc/pvpanic: convert to SPDX license tags
 misc/pvpanic: change header file sort style
 misc/pvpanic: remove unnecessary header file
 misc/pvpanic : break dependency on ACPI
 misc/pvpanic : grouping ACPI related stuff
 misc/pvpanic: add support to get pvpanic device info FDT
 dt-bindings: misc/pvpanic: add document for pvpanic-mmio
 misc/pvpanic: add MMIO support
 misc/pvpanic: simplify the code using acpi_dev_resource_io
 pvpanic: move pvpanic to misc as common driver

Philippe Mathieu-Daudé (2):
  hw/misc/pvpanic: Build the pvpanic device in $(common-obj)
  hw/misc/pvpanic: Cosmetic renaming

Peng Hao (8):
  hw/misc/pvpanic: Add the MMIO interface
  hw/misc/pvpanic: moving structure definition to header file
  hw/arm/virt: Use the pvpanic device
  hw/arm/virt: add pvpanic device in virt acpi table
  hw/misc/pvpanic: add configure query interface
  hw/misc/pvpanic: preparing for adding configure interface
  hw/misc/pvpanic: realize the configure interface
  pvpanic : update pvpanic document
  
 default-configs/arm-softmmu.mak |  1 +
 docs/specs/pvpanic.txt  | 18 +--
 hw/arm/sysbus-fdt.c |  2 ++
 hw/arm/virt-acpi-build.c| 18 +++
 hw/arm/virt.c   | 22 +
 hw/misc/Makefile.objs   |  2 +-
 hw/misc/pvpanic.c   | 68 -
 include/hw/arm/virt.h   |  1 +
 include/hw/misc/pvpanic.h   | 34 +
 9 files changed, 140 insertions(+), 26 deletions(-)

-- 
1.8.3.1




[Qemu-devel] [PATCH V8 03/10] hw/misc/pvpanic: Add the MMIO interface

2018-11-24 Thread Peng Hao
Add pvpanic new type "TYPE_PVPANIC_MMIO"

Signed-off-by: Peng Hao 
---
 hw/misc/pvpanic.c | 36 
 include/hw/misc/pvpanic.h | 15 +++
 2 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c
index 0f23a67..2bcbfc5 100644
--- a/hw/misc/pvpanic.c
+++ b/hw/misc/pvpanic.c
@@ -2,10 +2,12 @@
  * QEMU simulated pvpanic device.
  *
  * Copyright Fujitsu, Corp. 2013
+ * Copyright (c) 2018 ZTE Ltd.
  *
  * Authors:
  * Wen Congyang 
  * Hu Tao 
+ * Peng Hao 
  *
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
@@ -57,20 +59,20 @@ typedef struct PVPanicISAState {
 } PVPanicISAState;
 
 /* return supported events on read */
-static uint64_t pvpanic_ioport_read(void *opaque, hwaddr addr, unsigned size)
+static uint64_t pvpanic_read(void *opaque, hwaddr addr, unsigned size)
 {
 return PVPANIC_PANICKED;
 }
 
-static void pvpanic_ioport_write(void *opaque, hwaddr addr, uint64_t val,
+static void pvpanic_write(void *opaque, hwaddr addr, uint64_t val,
  unsigned size)
 {
 handle_event(val);
 }
 
 static const MemoryRegionOps pvpanic_ops = {
-.read = pvpanic_ioport_read,
-.write = pvpanic_ioport_write,
+.read = pvpanic_read,
+.write = pvpanic_write,
 .impl = {
 .min_access_size = 1,
 .max_access_size = 1,
@@ -125,9 +127,35 @@ static TypeInfo pvpanic_isa_info = {
 .class_init= pvpanic_isa_class_init,
 };
 
+static void pvpanic_mmio_initfn(Object *obj)
+{
+PVPanicMMIOState *s = PVPANIC_MMIO_DEVICE(obj);
+SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+
+memory_region_init_io(>mr, OBJECT(s), _ops, s,
+  TYPE_PVPANIC_MMIO, 2);
+sysbus_init_mmio(sbd, >mr);
+}
+
+static void pvpanic_mmio_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+}
+
+static TypeInfo pvpanic_mmio_info = {
+.name  = TYPE_PVPANIC_MMIO,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(PVPanicMMIOState),
+.instance_init = pvpanic_mmio_initfn,
+.class_init= pvpanic_mmio_class_init,
+};
+
 static void pvpanic_register_types(void)
 {
 type_register_static(_isa_info);
+type_register_static(_mmio_info);
 }
 
 type_init(pvpanic_register_types)
diff --git a/include/hw/misc/pvpanic.h b/include/hw/misc/pvpanic.h
index 1ee071a..66dbdfe 100644
--- a/include/hw/misc/pvpanic.h
+++ b/include/hw/misc/pvpanic.h
@@ -15,9 +15,24 @@
 #define HW_MISC_PVPANIC_H
 
 #define TYPE_PVPANIC "pvpanic"
+#define TYPE_PVPANIC_MMIO "pvpanic-mmio"
 
 #define PVPANIC_IOPORT_PROP "ioport"
 
+/* PVPanicMMIOState for sysbus device and
+ * use mmio.
+ */
+typedef struct PVPanicMMIOState {
+SysBusDevice parent_obj;
+/**/
+
+/* public */
+MemoryRegion mr;
+} PVPanicMMIOState;
+
+#define PVPANIC_MMIO_DEVICE(obj)\
+OBJECT_CHECK(PVPanicMMIOState, (obj), TYPE_PVPANIC_MMIO)
+
 static inline uint16_t pvpanic_port(void)
 {
 Object *o = object_resolve_path_type("", TYPE_PVPANIC, NULL);
-- 
1.8.3.1




[Qemu-devel] [PATCH V8 07/10] hw/misc/pvpanic: add configure query interface

2018-11-24 Thread Peng Hao
Add configure query interface for pvpanic-mmio.

Signed-off-by: Peng Hao 
---
 include/hw/misc/pvpanic.h | 4 
 1 file changed, 4 insertions(+)

diff --git a/include/hw/misc/pvpanic.h b/include/hw/misc/pvpanic.h
index 066c707..1f20775 100644
--- a/include/hw/misc/pvpanic.h
+++ b/include/hw/misc/pvpanic.h
@@ -57,4 +57,8 @@ static inline uint16_t pvpanic_port(void)
 return object_property_get_uint(o, PVPANIC_IOPORT_PROP, NULL);
 }
 
+static inline Object *pvpanic_mmio(void)
+{
+return object_resolve_path_type("", TYPE_PVPANIC_MMIO, NULL);
+}
 #endif
-- 
1.8.3.1




[Qemu-devel] [PATCH V8 05/10] hw/arm/virt: Use the pvpanic device

2018-11-24 Thread Peng Hao
Add pvpanic device in arm virt machine.

Signed-off-by: Peng Hao 
---
 default-configs/arm-softmmu.mak |  1 +
 hw/arm/virt.c   | 22 ++
 include/hw/arm/virt.h   |  1 +
 3 files changed, 24 insertions(+)

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 2420491..50345df 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -159,3 +159,4 @@ CONFIG_PCI_DESIGNWARE=y
 CONFIG_STRONGARM=y
 CONFIG_HIGHBANK=y
 CONFIG_MUSICPAL=y
+CONFIG_PVPANIC=y
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index a2b8d8f..899131a 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -59,6 +59,7 @@
 #include "qapi/visitor.h"
 #include "standard-headers/linux/input.h"
 #include "hw/arm/smmuv3.h"
+#include "hw/misc/pvpanic.h"
 
 #define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
 static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
@@ -143,6 +144,7 @@ static const MemMapEntry a15memmap[] = {
 [VIRT_GPIO] =   { 0x0903, 0x1000 },
 [VIRT_SECURE_UART] ={ 0x0904, 0x1000 },
 [VIRT_SMMU] =   { 0x0905, 0x0002 },
+[VIRT_PVPANIC] ={ 0x0907, 0x0002 },
 [VIRT_MMIO] =   { 0x0a00, 0x0200 },
 /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
 [VIRT_PLATFORM_BUS] =   { 0x0c00, 0x0200 },
@@ -190,6 +192,24 @@ static bool cpu_type_valid(const char *cpu)
 return false;
 }
 
+static void create_pvpanic_device(const VirtMachineState *vms)
+{
+ char *nodename;
+ hwaddr base = vms->memmap[VIRT_PVPANIC].base;
+ hwaddr size = vms->memmap[VIRT_PVPANIC].size;
+
+ sysbus_create_simple(TYPE_PVPANIC_MMIO, base, NULL);
+
+ nodename = g_strdup_printf("/pvpanic-mmio@%" PRIx64, base);
+ qemu_fdt_add_subnode(vms->fdt, nodename);
+ qemu_fdt_setprop_string(vms->fdt, nodename,
+ "compatible", "qemu,pvpanic-mmio");
+ qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg",
+  2, base, 2, size);
+
+ g_free(nodename);
+}
+
 static void create_fdt(VirtMachineState *vms)
 {
 void *fdt = create_device_tree(>fdt_size);
@@ -1531,6 +1551,8 @@ static void machvirt_init(MachineState *machine)
 
 create_flash(vms, sysmem, secure_sysmem ? secure_sysmem : sysmem);
 
+create_pvpanic_device(vms);
+
 create_gic(vms, pic);
 
 fdt_add_pmu_nodes(vms);
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index 4cc57a7..937c124 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -66,6 +66,7 @@ enum {
 VIRT_GIC_REDIST,
 VIRT_GIC_REDIST2,
 VIRT_SMMU,
+VIRT_PVPANIC,
 VIRT_UART,
 VIRT_MMIO,
 VIRT_RTC,
-- 
1.8.3.1




[Qemu-devel] [PATCH V8 9/10] hw/misc/pvpanic: realize the configure interface

2018-11-24 Thread Peng Hao
Add configure interface for pvpanic-mmio. In qemu command line
use -device pvpanic-mmio to enable the device.

Signed-off-by: Peng Hao 
---
 hw/arm/virt-acpi-build.c | 5 -
 hw/arm/virt.c| 7 +++
 hw/misc/pvpanic.c| 1 +
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 4208e46..cbc415e 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -45,6 +45,7 @@
 #include "hw/arm/virt.h"
 #include "sysemu/numa.h"
 #include "kvm_arm.h"
+#include "hw/misc/pvpanic.h"
 
 #define ARM_SPI_BASE 32
 #define ACPI_POWER_BUTTON_DEVICE "PWRB"
@@ -785,7 +786,9 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
 acpi_dsdt_add_uart(scope, [VIRT_UART],
(irqmap[VIRT_UART] + ARM_SPI_BASE));
 acpi_dsdt_add_flash(scope, [VIRT_FLASH]);
-acpi_dsdt_add_pvpanic(scope, [VIRT_PVPANIC]);
+if (pvpanic_mmio()) {
+acpi_dsdt_add_pvpanic(scope, [VIRT_PVPANIC]);
+}
 acpi_dsdt_add_fw_cfg(scope, [VIRT_FW_CFG]);
 acpi_dsdt_add_virtio(scope, [VIRT_MMIO],
 (irqmap[VIRT_MMIO] + ARM_SPI_BASE), NUM_VIRTIO_TRANSPORTS);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 921220a..aeedc43 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -198,8 +198,6 @@ static void create_pvpanic_device(const VirtMachineState 
*vms)
  hwaddr base = vms->memmap[VIRT_PVPANIC].base;
  hwaddr size = vms->memmap[VIRT_PVPANIC].size;
 
- sysbus_create_simple(TYPE_PVPANIC_MMIO, base, NULL);
-
  nodename = g_strdup_printf("/pvpanic-mmio@%" PRIx64, base);
  qemu_fdt_add_subnode(vms->fdt, nodename);
  qemu_fdt_setprop_string(vms->fdt, nodename,
@@ -1330,6 +1328,9 @@ void virt_machine_done(Notifier *notifier, void *data)
 struct arm_boot_info *info = >bootinfo;
 AddressSpace *as = arm_boot_address_space(cpu, info);
 
+if (pvpanic_mmio()) {
+create_pvpanic_device(vms);
+}
 /*
  * If the user provided a dtb, we assume the dynamic sysbus nodes
  * already are integrated there. This corresponds to a use case where
@@ -1551,8 +1552,6 @@ static void machvirt_init(MachineState *machine)
 
 create_flash(vms, sysmem, secure_sysmem ? secure_sysmem : sysmem);
 
-create_pvpanic_device(vms);
-
 create_gic(vms, pic);
 
 fdt_add_pmu_nodes(vms);
diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c
index 6fea162..ce6f5cb 100644
--- a/hw/misc/pvpanic.c
+++ b/hw/misc/pvpanic.c
@@ -119,6 +119,7 @@ static void pvpanic_mmio_initfn(Object *obj)
 memory_region_init_io(>mr, OBJECT(s), _ops, s,
   TYPE_PVPANIC_MMIO, 2);
 sysbus_init_mmio(sbd, >mr);
+sysbus_mmio_map(sbd, 0, s->base);
 }
 
 static Property pvpanic_mmio_properties[] = {
-- 
1.8.3.1




[Qemu-devel] [PATCH V8 02/10] hw/misc/pvpanic: Cosmetic renaming

2018-11-24 Thread Peng Hao
From: Philippe Mathieu-Daudé 

To ease the MMIO device addition in the next patch, rename:
- ISA_PVPANIC_DEVICE -> PVPANIC_ISA_DEVICE.
- MemoryRegion io -> mr.

Signed-off-by: Philippe Mathieu-Daudé 
Signed-off-by: Peng Hao 
---
 hw/misc/pvpanic.c | 28 
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c
index 9d8961b..0f23a67 100644
--- a/hw/misc/pvpanic.c
+++ b/hw/misc/pvpanic.c
@@ -25,8 +25,8 @@
 /* The pv event value */
 #define PVPANIC_PANICKED(1 << PVPANIC_F_PANICKED)
 
-#define ISA_PVPANIC_DEVICE(obj)\
-OBJECT_CHECK(PVPanicState, (obj), TYPE_PVPANIC)
+#define PVPANIC_ISA_DEVICE(obj)\
+OBJECT_CHECK(PVPanicISAState, (obj), TYPE_PVPANIC)
 
 static void handle_event(int event)
 {
@@ -45,12 +45,16 @@ static void handle_event(int event)
 
 #include "hw/isa/isa.h"
 
-typedef struct PVPanicState {
+/* PVPanicISAState for ISA device and
+ * use ioport.
+ */
+typedef struct PVPanicISAState {
 ISADevice parent_obj;
-
-MemoryRegion io;
+/*< private>*/
 uint16_t ioport;
-} PVPanicState;
+/**/
+MemoryRegion mr;
+} PVPanicISAState;
 
 /* return supported events on read */
 static uint64_t pvpanic_ioport_read(void *opaque, hwaddr addr, unsigned size)
@@ -75,15 +79,15 @@ static const MemoryRegionOps pvpanic_ops = {
 
 static void pvpanic_isa_initfn(Object *obj)
 {
-PVPanicState *s = ISA_PVPANIC_DEVICE(obj);
+PVPanicISAState *s = PVPANIC_ISA_DEVICE(obj);
 
-memory_region_init_io(>io, OBJECT(s), _ops, s, "pvpanic", 1);
+memory_region_init_io(>mr, OBJECT(s), _ops, s, "pvpanic", 1);
 }
 
 static void pvpanic_isa_realizefn(DeviceState *dev, Error **errp)
 {
 ISADevice *d = ISA_DEVICE(dev);
-PVPanicState *s = ISA_PVPANIC_DEVICE(dev);
+PVPanicISAState *s = PVPANIC_ISA_DEVICE(dev);
 FWCfgState *fw_cfg = fw_cfg_find();
 uint16_t *pvpanic_port;
 
@@ -96,11 +100,11 @@ static void pvpanic_isa_realizefn(DeviceState *dev, Error 
**errp)
 fw_cfg_add_file(fw_cfg, "etc/pvpanic-port", pvpanic_port,
 sizeof(*pvpanic_port));
 
-isa_register_ioport(d, >io, s->ioport);
+isa_register_ioport(d, >mr, s->ioport);
 }
 
 static Property pvpanic_isa_properties[] = {
-DEFINE_PROP_UINT16(PVPANIC_IOPORT_PROP, PVPanicState, ioport, 0x505),
+DEFINE_PROP_UINT16(PVPANIC_IOPORT_PROP, PVPanicISAState, ioport, 0x505),
 DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -116,7 +120,7 @@ static void pvpanic_isa_class_init(ObjectClass *klass, void 
*data)
 static TypeInfo pvpanic_isa_info = {
 .name  = TYPE_PVPANIC,
 .parent= TYPE_ISA_DEVICE,
-.instance_size = sizeof(PVPanicState),
+.instance_size = sizeof(PVPanicISAState),
 .instance_init = pvpanic_isa_initfn,
 .class_init= pvpanic_isa_class_init,
 };
-- 
1.8.3.1




[Qemu-devel] [PATCH V8 10/10] pvpanic : update pvpanic document

2018-11-24 Thread Peng Hao
Add mmio support info in docs/specs/pvpanic.txt.

Signed-off-by: Peng Hao 
---
 docs/specs/pvpanic.txt | 18 +++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/docs/specs/pvpanic.txt b/docs/specs/pvpanic.txt
index c7bbacc..2d06ee5 100644
--- a/docs/specs/pvpanic.txt
+++ b/docs/specs/pvpanic.txt
@@ -1,14 +1,18 @@
 PVPANIC DEVICE
 ==
 
-pvpanic device is a simulated ISA device, through which a guest panic
-event is sent to qemu, and a QMP event is generated. This allows
+pvpanic device is a simulated ISA/SysBus device, through which a guest
+panic event is sent to qemu, and a QMP event is generated. This allows
 management apps (e.g. libvirt) to be notified and respond to the event.
 
-The management app has the option of waiting for GUEST_PANICKED events,
+The ma:wqnagement app has the option of waiting for GUEST_PANICKED events,
 and/or polling for guest-panicked RunState, to learn when the pvpanic
 device has fired a panic event.
 
+When pvpanic device is implemented as a ISA device, it supports IOPORT
+mode. Since QEMU v3.2 pvpanic also supports MMIO mode, it will be 
+implemented as a SYSBUS device.
+
 ISA Interface
 -
 
@@ -19,6 +23,14 @@ Software should set only bits both itself and the device 
recognize.
 Currently, only bit 0 is recognized, setting it indicates a guest panic
 has happened.
 
+SYSBUS Interface
+
+
+The SYSBUS interface is similar to the ISA interface except that it uses
+MMIO. For example, the arm virt machine could put the pvpanic device at
+[0x907, 0x9070001] and currently only the first byte is used.
+
+
 ACPI Interface
 --
 
-- 
1.8.3.1




[Qemu-devel] [PATCH V8 04/10] hw/misc/pvpanic: moving structure definition to header file

2018-11-24 Thread Peng Hao
Move structure definition to header file uniformly

Signed-off-by: Peng Hao 
---
 hw/misc/pvpanic.c | 16 
 include/hw/misc/pvpanic.h | 15 +++
 2 files changed, 15 insertions(+), 16 deletions(-)

diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c
index 2bcbfc5..aaa8b0c 100644
--- a/hw/misc/pvpanic.c
+++ b/hw/misc/pvpanic.c
@@ -27,9 +27,6 @@
 /* The pv event value */
 #define PVPANIC_PANICKED(1 << PVPANIC_F_PANICKED)
 
-#define PVPANIC_ISA_DEVICE(obj)\
-OBJECT_CHECK(PVPanicISAState, (obj), TYPE_PVPANIC)
-
 static void handle_event(int event)
 {
 static bool logged;
@@ -45,19 +42,6 @@ static void handle_event(int event)
 }
 }
 
-#include "hw/isa/isa.h"
-
-/* PVPanicISAState for ISA device and
- * use ioport.
- */
-typedef struct PVPanicISAState {
-ISADevice parent_obj;
-/*< private>*/
-uint16_t ioport;
-/**/
-MemoryRegion mr;
-} PVPanicISAState;
-
 /* return supported events on read */
 static uint64_t pvpanic_read(void *opaque, hwaddr addr, unsigned size)
 {
diff --git a/include/hw/misc/pvpanic.h b/include/hw/misc/pvpanic.h
index 66dbdfe..066c707 100644
--- a/include/hw/misc/pvpanic.h
+++ b/include/hw/misc/pvpanic.h
@@ -13,12 +13,24 @@
  */
 #ifndef HW_MISC_PVPANIC_H
 #define HW_MISC_PVPANIC_H
+#include "hw/isa/isa.h"
 
 #define TYPE_PVPANIC "pvpanic"
 #define TYPE_PVPANIC_MMIO "pvpanic-mmio"
 
 #define PVPANIC_IOPORT_PROP "ioport"
 
+/* PVPanicISAState for ISA device and
+ * use ioport.
+ */
+typedef struct PVPanicISAState {
+ISADevice parent_obj;
+/*< private>*/
+uint16_t ioport;
+/**/
+MemoryRegion mr;
+} PVPanicISAState;
+
 /* PVPanicMMIOState for sysbus device and
  * use mmio.
  */
@@ -30,6 +42,9 @@ typedef struct PVPanicMMIOState {
 MemoryRegion mr;
 } PVPanicMMIOState;
 
+#define PVPANIC_ISA_DEVICE(obj)\
+OBJECT_CHECK(PVPanicISAState, (obj), TYPE_PVPANIC)
+
 #define PVPANIC_MMIO_DEVICE(obj)\
 OBJECT_CHECK(PVPanicMMIOState, (obj), TYPE_PVPANIC_MMIO)
 
-- 
1.8.3.1




[Qemu-devel] [PATCH V8 08/10] hw/misc/pvpanic: preparing for adding configure interface

2018-11-24 Thread Peng Hao
Prepare for pvpanic-mmio configure interface.

Signed-off-by: Peng Hao 
---
 hw/arm/sysbus-fdt.c   | 2 ++
 hw/arm/virt.c | 1 +
 hw/misc/pvpanic.c | 7 +++
 include/hw/misc/pvpanic.h | 2 +-
 4 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c
index ad698d4..34577f3 100644
--- a/hw/arm/sysbus-fdt.c
+++ b/hw/arm/sysbus-fdt.c
@@ -38,6 +38,7 @@
 #include "hw/vfio/vfio-amd-xgbe.h"
 #include "hw/display/ramfb.h"
 #include "hw/arm/fdt.h"
+#include "hw/misc/pvpanic.h"
 
 /*
  * internal struct that contains the information to create dynamic
@@ -459,6 +460,7 @@ static const BindingEntry bindings[] = {
 VFIO_PLATFORM_BINDING("amd,xgbe-seattle-v1a", add_amd_xgbe_fdt_node),
 #endif
 TYPE_BINDING(TYPE_RAMFB_DEVICE, no_fdt_node),
+TYPE_BINDING(TYPE_PVPANIC_MMIO, no_fdt_node),
 TYPE_BINDING("", NULL), /* last element */
 };
 
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 899131a..921220a 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1785,6 +1785,7 @@ static void virt_machine_class_init(ObjectClass *oc, void 
*data)
 machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_AMD_XGBE);
 machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
 machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_PLATFORM);
+machine_class_allow_dynamic_sysbus_dev(mc, TYPE_PVPANIC_MMIO);
 mc->block_default_type = IF_VIRTIO;
 mc->no_cdrom = 1;
 mc->pci_allow_0_address = true;
diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c
index aaa8b0c..6fea162 100644
--- a/hw/misc/pvpanic.c
+++ b/hw/misc/pvpanic.c
@@ -121,10 +121,17 @@ static void pvpanic_mmio_initfn(Object *obj)
 sysbus_init_mmio(sbd, >mr);
 }
 
+static Property pvpanic_mmio_properties[] = {
+DEFINE_PROP_UINT32("mmio", PVPanicMMIOState, base, 0x0907),
+DEFINE_PROP_END_OF_LIST(),
+};
+
 static void pvpanic_mmio_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
 
+dc->user_creatable = true;
+dc->props = pvpanic_mmio_properties;
 set_bit(DEVICE_CATEGORY_MISC, dc->categories);
 }
 
diff --git a/include/hw/misc/pvpanic.h b/include/hw/misc/pvpanic.h
index 1f20775..e733e1e 100644
--- a/include/hw/misc/pvpanic.h
+++ b/include/hw/misc/pvpanic.h
@@ -37,7 +37,7 @@ typedef struct PVPanicISAState {
 typedef struct PVPanicMMIOState {
 SysBusDevice parent_obj;
 /**/
-
+uint32_t base;
 /* public */
 MemoryRegion mr;
 } PVPanicMMIOState;
-- 
1.8.3.1




[Qemu-devel] [PATCH V8 06/10] hw/arm/virt: add pvpanic device in virt acpi table

2018-11-24 Thread Peng Hao
Add pvpanic device in virt acpi table, so when kenrel command line
uses acpi=force, kernel can get info from acpi table.

Signed-off-by: Peng Hao 
---
 hw/arm/virt-acpi-build.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 5785fb6..4208e46 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -61,6 +61,20 @@ static void acpi_dsdt_add_cpus(Aml *scope, int smp_cpus)
 }
 }
 
+static void acpi_dsdt_add_pvpanic(Aml *scope, const MemMapEntry 
*pvpanic_memmap)
+{
+Aml *dev = aml_device("PEVT");
+aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0001")));
+aml_append(dev, aml_name_decl("_UID", aml_int(0)));
+
+Aml *crs = aml_resource_template();
+aml_append(crs, aml_memory32_fixed(pvpanic_memmap->base,
+   pvpanic_memmap->size, AML_READ_WRITE));
+
+aml_append(dev, aml_name_decl("_CRS", crs));
+aml_append(scope, dev);
+}
+
 static void acpi_dsdt_add_uart(Aml *scope, const MemMapEntry *uart_memmap,
uint32_t uart_irq)
 {
@@ -771,6 +785,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
 acpi_dsdt_add_uart(scope, [VIRT_UART],
(irqmap[VIRT_UART] + ARM_SPI_BASE));
 acpi_dsdt_add_flash(scope, [VIRT_FLASH]);
+acpi_dsdt_add_pvpanic(scope, [VIRT_PVPANIC]);
 acpi_dsdt_add_fw_cfg(scope, [VIRT_FW_CFG]);
 acpi_dsdt_add_virtio(scope, [VIRT_MMIO],
 (irqmap[VIRT_MMIO] + ARM_SPI_BASE), NUM_VIRTIO_TRANSPORTS);
-- 
1.8.3.1




[Qemu-devel] [PATCH V8 01/10] hw/misc/pvpanic: Build the pvpanic device in $(common-obj)

2018-11-24 Thread Peng Hao
From: Philippe Mathieu-Daudé 

The 'pvpanic' ISA device can be use by any machine with an ISA bus.

Reviewed-by: Peter Maydell 
Signed-off-by: Philippe Mathieu-Daudé 
Signed-off-by: Peng Hao 
---
 hw/misc/Makefile.objs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 680350b..c387ce4 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -8,6 +8,7 @@ common-obj-$(CONFIG_ISA_TESTDEV) += pc-testdev.o
 common-obj-$(CONFIG_PCI_TESTDEV) += pci-testdev.o
 common-obj-$(CONFIG_EDU) += edu.o
 common-obj-$(CONFIG_PCA9552) += pca9552.o
+common-obj-$(CONFIG_PVPANIC) += pvpanic.o
 
 common-obj-y += unimp.o
 common-obj-$(CONFIG_FW_CFG_DMA) += vmcoreinfo.o
@@ -70,7 +71,6 @@ obj-$(CONFIG_IOTKIT_SECCTL) += iotkit-secctl.o
 obj-$(CONFIG_IOTKIT_SYSCTL) += iotkit-sysctl.o
 obj-$(CONFIG_IOTKIT_SYSINFO) += iotkit-sysinfo.o
 
-obj-$(CONFIG_PVPANIC) += pvpanic.o
 obj-$(CONFIG_AUX) += auxbus.o
 obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o aspeed_sdmc.o
 obj-$(CONFIG_MSF2) += msf2-sysreg.o
-- 
1.8.3.1




[Qemu-devel] [PATCH 06/10] hw/arm/virt: add pvpanic device in virt acpi table

2018-11-24 Thread Peng Hao
Add pvpanic device in virt acpi table, so when kenrel command line
uses acpi=force, kernel can get info from acpi table.

Signed-off-by: Peng Hao 
---
 hw/arm/virt-acpi-build.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 5785fb6..4208e46 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -61,6 +61,20 @@ static void acpi_dsdt_add_cpus(Aml *scope, int smp_cpus)
 }
 }
 
+static void acpi_dsdt_add_pvpanic(Aml *scope, const MemMapEntry 
*pvpanic_memmap)
+{
+Aml *dev = aml_device("PEVT");
+aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0001")));
+aml_append(dev, aml_name_decl("_UID", aml_int(0)));
+
+Aml *crs = aml_resource_template();
+aml_append(crs, aml_memory32_fixed(pvpanic_memmap->base,
+   pvpanic_memmap->size, AML_READ_WRITE));
+
+aml_append(dev, aml_name_decl("_CRS", crs));
+aml_append(scope, dev);
+}
+
 static void acpi_dsdt_add_uart(Aml *scope, const MemMapEntry *uart_memmap,
uint32_t uart_irq)
 {
@@ -771,6 +785,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
 acpi_dsdt_add_uart(scope, [VIRT_UART],
(irqmap[VIRT_UART] + ARM_SPI_BASE));
 acpi_dsdt_add_flash(scope, [VIRT_FLASH]);
+acpi_dsdt_add_pvpanic(scope, [VIRT_PVPANIC]);
 acpi_dsdt_add_fw_cfg(scope, [VIRT_FW_CFG]);
 acpi_dsdt_add_virtio(scope, [VIRT_MMIO],
 (irqmap[VIRT_MMIO] + ARM_SPI_BASE), NUM_VIRTIO_TRANSPORTS);
-- 
1.8.3.1




[Qemu-devel] [PATCH 08/10] hw/misc/pvpanic: preparing for adding configure interface

2018-11-24 Thread Peng Hao
Prepare for pvpanic-mmio configure interface.

Signed-off-by: Peng Hao 
---
 hw/arm/sysbus-fdt.c   | 2 ++
 hw/arm/virt.c | 1 +
 hw/misc/pvpanic.c | 7 +++
 include/hw/misc/pvpanic.h | 2 +-
 4 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c
index ad698d4..34577f3 100644
--- a/hw/arm/sysbus-fdt.c
+++ b/hw/arm/sysbus-fdt.c
@@ -38,6 +38,7 @@
 #include "hw/vfio/vfio-amd-xgbe.h"
 #include "hw/display/ramfb.h"
 #include "hw/arm/fdt.h"
+#include "hw/misc/pvpanic.h"
 
 /*
  * internal struct that contains the information to create dynamic
@@ -459,6 +460,7 @@ static const BindingEntry bindings[] = {
 VFIO_PLATFORM_BINDING("amd,xgbe-seattle-v1a", add_amd_xgbe_fdt_node),
 #endif
 TYPE_BINDING(TYPE_RAMFB_DEVICE, no_fdt_node),
+TYPE_BINDING(TYPE_PVPANIC_MMIO, no_fdt_node),
 TYPE_BINDING("", NULL), /* last element */
 };
 
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 899131a..921220a 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1785,6 +1785,7 @@ static void virt_machine_class_init(ObjectClass *oc, void 
*data)
 machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_AMD_XGBE);
 machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
 machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_PLATFORM);
+machine_class_allow_dynamic_sysbus_dev(mc, TYPE_PVPANIC_MMIO);
 mc->block_default_type = IF_VIRTIO;
 mc->no_cdrom = 1;
 mc->pci_allow_0_address = true;
diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c
index aaa8b0c..6fea162 100644
--- a/hw/misc/pvpanic.c
+++ b/hw/misc/pvpanic.c
@@ -121,10 +121,17 @@ static void pvpanic_mmio_initfn(Object *obj)
 sysbus_init_mmio(sbd, >mr);
 }
 
+static Property pvpanic_mmio_properties[] = {
+DEFINE_PROP_UINT32("mmio", PVPanicMMIOState, base, 0x0907),
+DEFINE_PROP_END_OF_LIST(),
+};
+
 static void pvpanic_mmio_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
 
+dc->user_creatable = true;
+dc->props = pvpanic_mmio_properties;
 set_bit(DEVICE_CATEGORY_MISC, dc->categories);
 }
 
diff --git a/include/hw/misc/pvpanic.h b/include/hw/misc/pvpanic.h
index 1f20775..e733e1e 100644
--- a/include/hw/misc/pvpanic.h
+++ b/include/hw/misc/pvpanic.h
@@ -37,7 +37,7 @@ typedef struct PVPanicISAState {
 typedef struct PVPanicMMIOState {
 SysBusDevice parent_obj;
 /**/
-
+uint32_t base;
 /* public */
 MemoryRegion mr;
 } PVPanicMMIOState;
-- 
1.8.3.1




[Qemu-devel] [PATCH 02/10] hw/misc/pvpanic: Cosmetic renaming

2018-11-24 Thread Peng Hao
To ease the MMIO device addition in the next patch, rename:
- ISA_PVPANIC_DEVICE -> PVPANIC_ISA_DEVICE.
- MemoryRegion io -> mr.

Signed-off-by: Philippe Mathieu-Daudé 
Signed-off-by: Peng Hao 
---
 hw/misc/pvpanic.c | 28 
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c
index 9d8961b..0f23a67 100644
--- a/hw/misc/pvpanic.c
+++ b/hw/misc/pvpanic.c
@@ -25,8 +25,8 @@
 /* The pv event value */
 #define PVPANIC_PANICKED(1 << PVPANIC_F_PANICKED)
 
-#define ISA_PVPANIC_DEVICE(obj)\
-OBJECT_CHECK(PVPanicState, (obj), TYPE_PVPANIC)
+#define PVPANIC_ISA_DEVICE(obj)\
+OBJECT_CHECK(PVPanicISAState, (obj), TYPE_PVPANIC)
 
 static void handle_event(int event)
 {
@@ -45,12 +45,16 @@ static void handle_event(int event)
 
 #include "hw/isa/isa.h"
 
-typedef struct PVPanicState {
+/* PVPanicISAState for ISA device and
+ * use ioport.
+ */
+typedef struct PVPanicISAState {
 ISADevice parent_obj;
-
-MemoryRegion io;
+/*< private>*/
 uint16_t ioport;
-} PVPanicState;
+/**/
+MemoryRegion mr;
+} PVPanicISAState;
 
 /* return supported events on read */
 static uint64_t pvpanic_ioport_read(void *opaque, hwaddr addr, unsigned size)
@@ -75,15 +79,15 @@ static const MemoryRegionOps pvpanic_ops = {
 
 static void pvpanic_isa_initfn(Object *obj)
 {
-PVPanicState *s = ISA_PVPANIC_DEVICE(obj);
+PVPanicISAState *s = PVPANIC_ISA_DEVICE(obj);
 
-memory_region_init_io(>io, OBJECT(s), _ops, s, "pvpanic", 1);
+memory_region_init_io(>mr, OBJECT(s), _ops, s, "pvpanic", 1);
 }
 
 static void pvpanic_isa_realizefn(DeviceState *dev, Error **errp)
 {
 ISADevice *d = ISA_DEVICE(dev);
-PVPanicState *s = ISA_PVPANIC_DEVICE(dev);
+PVPanicISAState *s = PVPANIC_ISA_DEVICE(dev);
 FWCfgState *fw_cfg = fw_cfg_find();
 uint16_t *pvpanic_port;
 
@@ -96,11 +100,11 @@ static void pvpanic_isa_realizefn(DeviceState *dev, Error 
**errp)
 fw_cfg_add_file(fw_cfg, "etc/pvpanic-port", pvpanic_port,
 sizeof(*pvpanic_port));
 
-isa_register_ioport(d, >io, s->ioport);
+isa_register_ioport(d, >mr, s->ioport);
 }
 
 static Property pvpanic_isa_properties[] = {
-DEFINE_PROP_UINT16(PVPANIC_IOPORT_PROP, PVPanicState, ioport, 0x505),
+DEFINE_PROP_UINT16(PVPANIC_IOPORT_PROP, PVPanicISAState, ioport, 0x505),
 DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -116,7 +120,7 @@ static void pvpanic_isa_class_init(ObjectClass *klass, void 
*data)
 static TypeInfo pvpanic_isa_info = {
 .name  = TYPE_PVPANIC,
 .parent= TYPE_ISA_DEVICE,
-.instance_size = sizeof(PVPanicState),
+.instance_size = sizeof(PVPanicISAState),
 .instance_init = pvpanic_isa_initfn,
 .class_init= pvpanic_isa_class_init,
 };
-- 
1.8.3.1




[Qemu-devel] [PATCH 04/10] hw/misc/pvpanic: moving structure definition to header file

2018-11-24 Thread Peng Hao
Move structure definition to header file uniformly

Signed-off-by: Peng Hao 
---
 hw/misc/pvpanic.c | 16 
 include/hw/misc/pvpanic.h | 15 +++
 2 files changed, 15 insertions(+), 16 deletions(-)

diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c
index 2bcbfc5..aaa8b0c 100644
--- a/hw/misc/pvpanic.c
+++ b/hw/misc/pvpanic.c
@@ -27,9 +27,6 @@
 /* The pv event value */
 #define PVPANIC_PANICKED(1 << PVPANIC_F_PANICKED)
 
-#define PVPANIC_ISA_DEVICE(obj)\
-OBJECT_CHECK(PVPanicISAState, (obj), TYPE_PVPANIC)
-
 static void handle_event(int event)
 {
 static bool logged;
@@ -45,19 +42,6 @@ static void handle_event(int event)
 }
 }
 
-#include "hw/isa/isa.h"
-
-/* PVPanicISAState for ISA device and
- * use ioport.
- */
-typedef struct PVPanicISAState {
-ISADevice parent_obj;
-/*< private>*/
-uint16_t ioport;
-/**/
-MemoryRegion mr;
-} PVPanicISAState;
-
 /* return supported events on read */
 static uint64_t pvpanic_read(void *opaque, hwaddr addr, unsigned size)
 {
diff --git a/include/hw/misc/pvpanic.h b/include/hw/misc/pvpanic.h
index 66dbdfe..066c707 100644
--- a/include/hw/misc/pvpanic.h
+++ b/include/hw/misc/pvpanic.h
@@ -13,12 +13,24 @@
  */
 #ifndef HW_MISC_PVPANIC_H
 #define HW_MISC_PVPANIC_H
+#include "hw/isa/isa.h"
 
 #define TYPE_PVPANIC "pvpanic"
 #define TYPE_PVPANIC_MMIO "pvpanic-mmio"
 
 #define PVPANIC_IOPORT_PROP "ioport"
 
+/* PVPanicISAState for ISA device and
+ * use ioport.
+ */
+typedef struct PVPanicISAState {
+ISADevice parent_obj;
+/*< private>*/
+uint16_t ioport;
+/**/
+MemoryRegion mr;
+} PVPanicISAState;
+
 /* PVPanicMMIOState for sysbus device and
  * use mmio.
  */
@@ -30,6 +42,9 @@ typedef struct PVPanicMMIOState {
 MemoryRegion mr;
 } PVPanicMMIOState;
 
+#define PVPANIC_ISA_DEVICE(obj)\
+OBJECT_CHECK(PVPanicISAState, (obj), TYPE_PVPANIC)
+
 #define PVPANIC_MMIO_DEVICE(obj)\
 OBJECT_CHECK(PVPanicMMIOState, (obj), TYPE_PVPANIC_MMIO)
 
-- 
1.8.3.1




[Qemu-devel] [PATCH 01/10] hw/misc/pvpanic: Build the pvpanic device in $(common-obj)

2018-11-24 Thread Peng Hao
The 'pvpanic' ISA device can be use by any machine with an ISA bus.

Reviewed-by: Peter Maydell 
Signed-off-by: Philippe Mathieu-Daudé 
Signed-off-by: Peng Hao 
---
 hw/misc/Makefile.objs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 680350b..c387ce4 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -8,6 +8,7 @@ common-obj-$(CONFIG_ISA_TESTDEV) += pc-testdev.o
 common-obj-$(CONFIG_PCI_TESTDEV) += pci-testdev.o
 common-obj-$(CONFIG_EDU) += edu.o
 common-obj-$(CONFIG_PCA9552) += pca9552.o
+common-obj-$(CONFIG_PVPANIC) += pvpanic.o
 
 common-obj-y += unimp.o
 common-obj-$(CONFIG_FW_CFG_DMA) += vmcoreinfo.o
@@ -70,7 +71,6 @@ obj-$(CONFIG_IOTKIT_SECCTL) += iotkit-secctl.o
 obj-$(CONFIG_IOTKIT_SYSCTL) += iotkit-sysctl.o
 obj-$(CONFIG_IOTKIT_SYSINFO) += iotkit-sysinfo.o
 
-obj-$(CONFIG_PVPANIC) += pvpanic.o
 obj-$(CONFIG_AUX) += auxbus.o
 obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o aspeed_sdmc.o
 obj-$(CONFIG_MSF2) += msf2-sysreg.o
-- 
1.8.3.1




[Qemu-devel] [PATCH 10/10] pvpanic : update pvpanic document

2018-11-24 Thread Peng Hao
Add mmio support info in docs/specs/pvpanic.txt.

Signed-off-by: Peng Hao 
---
 docs/specs/pvpanic.txt | 18 +++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/docs/specs/pvpanic.txt b/docs/specs/pvpanic.txt
index c7bbacc..2d06ee5 100644
--- a/docs/specs/pvpanic.txt
+++ b/docs/specs/pvpanic.txt
@@ -1,14 +1,18 @@
 PVPANIC DEVICE
 ==
 
-pvpanic device is a simulated ISA device, through which a guest panic
-event is sent to qemu, and a QMP event is generated. This allows
+pvpanic device is a simulated ISA/SysBus device, through which a guest
+panic event is sent to qemu, and a QMP event is generated. This allows
 management apps (e.g. libvirt) to be notified and respond to the event.
 
-The management app has the option of waiting for GUEST_PANICKED events,
+The ma:wqnagement app has the option of waiting for GUEST_PANICKED events,
 and/or polling for guest-panicked RunState, to learn when the pvpanic
 device has fired a panic event.
 
+When pvpanic device is implemented as a ISA device, it supports IOPORT
+mode. Since QEMU v3.2 pvpanic also supports MMIO mode, it will be 
+implemented as a SYSBUS device.
+
 ISA Interface
 -
 
@@ -19,6 +23,14 @@ Software should set only bits both itself and the device 
recognize.
 Currently, only bit 0 is recognized, setting it indicates a guest panic
 has happened.
 
+SYSBUS Interface
+
+
+The SYSBUS interface is similar to the ISA interface except that it uses
+MMIO. For example, the arm virt machine could put the pvpanic device at
+[0x907, 0x9070001] and currently only the first byte is used.
+
+
 ACPI Interface
 --
 
-- 
1.8.3.1




[Qemu-devel] [PATCH 05/10] hw/arm/virt: Use the pvpanic device

2018-11-24 Thread Peng Hao
Add pvpanic device in arm virt machine.

Signed-off-by: Peng Hao 
---
 default-configs/arm-softmmu.mak |  1 +
 hw/arm/virt.c   | 22 ++
 include/hw/arm/virt.h   |  1 +
 3 files changed, 24 insertions(+)

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 2420491..50345df 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -159,3 +159,4 @@ CONFIG_PCI_DESIGNWARE=y
 CONFIG_STRONGARM=y
 CONFIG_HIGHBANK=y
 CONFIG_MUSICPAL=y
+CONFIG_PVPANIC=y
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index a2b8d8f..899131a 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -59,6 +59,7 @@
 #include "qapi/visitor.h"
 #include "standard-headers/linux/input.h"
 #include "hw/arm/smmuv3.h"
+#include "hw/misc/pvpanic.h"
 
 #define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
 static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
@@ -143,6 +144,7 @@ static const MemMapEntry a15memmap[] = {
 [VIRT_GPIO] =   { 0x0903, 0x1000 },
 [VIRT_SECURE_UART] ={ 0x0904, 0x1000 },
 [VIRT_SMMU] =   { 0x0905, 0x0002 },
+[VIRT_PVPANIC] ={ 0x0907, 0x0002 },
 [VIRT_MMIO] =   { 0x0a00, 0x0200 },
 /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
 [VIRT_PLATFORM_BUS] =   { 0x0c00, 0x0200 },
@@ -190,6 +192,24 @@ static bool cpu_type_valid(const char *cpu)
 return false;
 }
 
+static void create_pvpanic_device(const VirtMachineState *vms)
+{
+ char *nodename;
+ hwaddr base = vms->memmap[VIRT_PVPANIC].base;
+ hwaddr size = vms->memmap[VIRT_PVPANIC].size;
+
+ sysbus_create_simple(TYPE_PVPANIC_MMIO, base, NULL);
+
+ nodename = g_strdup_printf("/pvpanic-mmio@%" PRIx64, base);
+ qemu_fdt_add_subnode(vms->fdt, nodename);
+ qemu_fdt_setprop_string(vms->fdt, nodename,
+ "compatible", "qemu,pvpanic-mmio");
+ qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg",
+  2, base, 2, size);
+
+ g_free(nodename);
+}
+
 static void create_fdt(VirtMachineState *vms)
 {
 void *fdt = create_device_tree(>fdt_size);
@@ -1531,6 +1551,8 @@ static void machvirt_init(MachineState *machine)
 
 create_flash(vms, sysmem, secure_sysmem ? secure_sysmem : sysmem);
 
+create_pvpanic_device(vms);
+
 create_gic(vms, pic);
 
 fdt_add_pmu_nodes(vms);
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index 4cc57a7..937c124 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -66,6 +66,7 @@ enum {
 VIRT_GIC_REDIST,
 VIRT_GIC_REDIST2,
 VIRT_SMMU,
+VIRT_PVPANIC,
 VIRT_UART,
 VIRT_MMIO,
 VIRT_RTC,
-- 
1.8.3.1




[Qemu-devel] [PATCH] hw/misc/pvpanic: realize the configure interface

2018-11-24 Thread Peng Hao
Add configure interface for pvpanic-mmio. In qemu command line
use -device pvpanic-mmio to enable the device.

Signed-off-by: Peng Hao 
---
 hw/arm/virt-acpi-build.c | 5 -
 hw/arm/virt.c| 7 +++
 hw/misc/pvpanic.c| 1 +
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 4208e46..cbc415e 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -45,6 +45,7 @@
 #include "hw/arm/virt.h"
 #include "sysemu/numa.h"
 #include "kvm_arm.h"
+#include "hw/misc/pvpanic.h"
 
 #define ARM_SPI_BASE 32
 #define ACPI_POWER_BUTTON_DEVICE "PWRB"
@@ -785,7 +786,9 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
 acpi_dsdt_add_uart(scope, [VIRT_UART],
(irqmap[VIRT_UART] + ARM_SPI_BASE));
 acpi_dsdt_add_flash(scope, [VIRT_FLASH]);
-acpi_dsdt_add_pvpanic(scope, [VIRT_PVPANIC]);
+if (pvpanic_mmio()) {
+acpi_dsdt_add_pvpanic(scope, [VIRT_PVPANIC]);
+}
 acpi_dsdt_add_fw_cfg(scope, [VIRT_FW_CFG]);
 acpi_dsdt_add_virtio(scope, [VIRT_MMIO],
 (irqmap[VIRT_MMIO] + ARM_SPI_BASE), NUM_VIRTIO_TRANSPORTS);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 921220a..aeedc43 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -198,8 +198,6 @@ static void create_pvpanic_device(const VirtMachineState 
*vms)
  hwaddr base = vms->memmap[VIRT_PVPANIC].base;
  hwaddr size = vms->memmap[VIRT_PVPANIC].size;
 
- sysbus_create_simple(TYPE_PVPANIC_MMIO, base, NULL);
-
  nodename = g_strdup_printf("/pvpanic-mmio@%" PRIx64, base);
  qemu_fdt_add_subnode(vms->fdt, nodename);
  qemu_fdt_setprop_string(vms->fdt, nodename,
@@ -1330,6 +1328,9 @@ void virt_machine_done(Notifier *notifier, void *data)
 struct arm_boot_info *info = >bootinfo;
 AddressSpace *as = arm_boot_address_space(cpu, info);
 
+if (pvpanic_mmio()) {
+create_pvpanic_device(vms);
+}
 /*
  * If the user provided a dtb, we assume the dynamic sysbus nodes
  * already are integrated there. This corresponds to a use case where
@@ -1551,8 +1552,6 @@ static void machvirt_init(MachineState *machine)
 
 create_flash(vms, sysmem, secure_sysmem ? secure_sysmem : sysmem);
 
-create_pvpanic_device(vms);
-
 create_gic(vms, pic);
 
 fdt_add_pmu_nodes(vms);
diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c
index 6fea162..ce6f5cb 100644
--- a/hw/misc/pvpanic.c
+++ b/hw/misc/pvpanic.c
@@ -119,6 +119,7 @@ static void pvpanic_mmio_initfn(Object *obj)
 memory_region_init_io(>mr, OBJECT(s), _ops, s,
   TYPE_PVPANIC_MMIO, 2);
 sysbus_init_mmio(sbd, >mr);
+sysbus_mmio_map(sbd, 0, s->base);
 }
 
 static Property pvpanic_mmio_properties[] = {
-- 
1.8.3.1




[Qemu-devel] [PATCH 03/10] hw/misc/pvpanic: Add the MMIO interface

2018-11-24 Thread Peng Hao
Add pvpanic new type "TYPE_PVPANIC_MMIO"

Signed-off-by: Peng Hao 
---
 hw/misc/pvpanic.c | 36 
 include/hw/misc/pvpanic.h | 15 +++
 2 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c
index 0f23a67..2bcbfc5 100644
--- a/hw/misc/pvpanic.c
+++ b/hw/misc/pvpanic.c
@@ -2,10 +2,12 @@
  * QEMU simulated pvpanic device.
  *
  * Copyright Fujitsu, Corp. 2013
+ * Copyright (c) 2018 ZTE Ltd.
  *
  * Authors:
  * Wen Congyang 
  * Hu Tao 
+ * Peng Hao 
  *
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
@@ -57,20 +59,20 @@ typedef struct PVPanicISAState {
 } PVPanicISAState;
 
 /* return supported events on read */
-static uint64_t pvpanic_ioport_read(void *opaque, hwaddr addr, unsigned size)
+static uint64_t pvpanic_read(void *opaque, hwaddr addr, unsigned size)
 {
 return PVPANIC_PANICKED;
 }
 
-static void pvpanic_ioport_write(void *opaque, hwaddr addr, uint64_t val,
+static void pvpanic_write(void *opaque, hwaddr addr, uint64_t val,
  unsigned size)
 {
 handle_event(val);
 }
 
 static const MemoryRegionOps pvpanic_ops = {
-.read = pvpanic_ioport_read,
-.write = pvpanic_ioport_write,
+.read = pvpanic_read,
+.write = pvpanic_write,
 .impl = {
 .min_access_size = 1,
 .max_access_size = 1,
@@ -125,9 +127,35 @@ static TypeInfo pvpanic_isa_info = {
 .class_init= pvpanic_isa_class_init,
 };
 
+static void pvpanic_mmio_initfn(Object *obj)
+{
+PVPanicMMIOState *s = PVPANIC_MMIO_DEVICE(obj);
+SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+
+memory_region_init_io(>mr, OBJECT(s), _ops, s,
+  TYPE_PVPANIC_MMIO, 2);
+sysbus_init_mmio(sbd, >mr);
+}
+
+static void pvpanic_mmio_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+}
+
+static TypeInfo pvpanic_mmio_info = {
+.name  = TYPE_PVPANIC_MMIO,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(PVPanicMMIOState),
+.instance_init = pvpanic_mmio_initfn,
+.class_init= pvpanic_mmio_class_init,
+};
+
 static void pvpanic_register_types(void)
 {
 type_register_static(_isa_info);
+type_register_static(_mmio_info);
 }
 
 type_init(pvpanic_register_types)
diff --git a/include/hw/misc/pvpanic.h b/include/hw/misc/pvpanic.h
index 1ee071a..66dbdfe 100644
--- a/include/hw/misc/pvpanic.h
+++ b/include/hw/misc/pvpanic.h
@@ -15,9 +15,24 @@
 #define HW_MISC_PVPANIC_H
 
 #define TYPE_PVPANIC "pvpanic"
+#define TYPE_PVPANIC_MMIO "pvpanic-mmio"
 
 #define PVPANIC_IOPORT_PROP "ioport"
 
+/* PVPanicMMIOState for sysbus device and
+ * use mmio.
+ */
+typedef struct PVPanicMMIOState {
+SysBusDevice parent_obj;
+/**/
+
+/* public */
+MemoryRegion mr;
+} PVPanicMMIOState;
+
+#define PVPANIC_MMIO_DEVICE(obj)\
+OBJECT_CHECK(PVPanicMMIOState, (obj), TYPE_PVPANIC_MMIO)
+
 static inline uint16_t pvpanic_port(void)
 {
 Object *o = object_resolve_path_type("", TYPE_PVPANIC, NULL);
-- 
1.8.3.1




[Qemu-devel] [PATCH 07/10] hw/misc/pvpanic: add configure query interface

2018-11-24 Thread Peng Hao
Add configure query interface for pvpanic-mmio.

Signed-off-by: Peng Hao 
---
 include/hw/misc/pvpanic.h | 4 
 1 file changed, 4 insertions(+)

diff --git a/include/hw/misc/pvpanic.h b/include/hw/misc/pvpanic.h
index 066c707..1f20775 100644
--- a/include/hw/misc/pvpanic.h
+++ b/include/hw/misc/pvpanic.h
@@ -57,4 +57,8 @@ static inline uint16_t pvpanic_port(void)
 return object_property_get_uint(o, PVPANIC_IOPORT_PROP, NULL);
 }
 
+static inline Object *pvpanic_mmio(void)
+{
+return object_resolve_path_type("", TYPE_PVPANIC_MMIO, NULL);
+}
 #endif
-- 
1.8.3.1