Re: [Qemu-devel] [Qemu-ppc] [PATCH] spapr: drop redundant statement in spapr_populate_drconf_memory()
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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)
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
** 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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)
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
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
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
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
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)
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
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
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
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
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
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