Re: [Qemu-devel] [PATCH v5 05/14] vl: handle "-device dimm"
Il 27/06/2013 07:08, Wanlong Gao ha scritto: > Do we really need to specify the memory range? I suspect that we can > follow current design of normal memory in hot-plug memory. I think we can do both. I'm afraid that the configuration of the VM will not be perfectly reproducible without specifying the range, more so if you allow hotplug. > Currently, > we just specify the size of normal memory in each node, and the range > in normal memory is node by node. Then I think we can just specify > the memory size of hot-plug in each node, then the hot-plug memory > range is also node by node, and the whole hot-plug memory block is > just located after the normal memory block. If so, the option can > come like: > -numa > node,nodeid=0,mem=2G,cpus=0-1,mem-hotplug=2G,mem-policy=membind,mem-hostnode=0-1,mem-hotplug-policy=interleave,mem-hotplug-hostnode=1 > -numa > node,nodeid=1,mem=2G,cpus=2-3,mem-hotplug=2G,mem-policy=preferred,mem-hostnode=1,mem-hotplug-policy=membind,mem-hotplug-hostnode=0-1 I think specifying different policies and bindings for normal and hotplug memory is too much fine-grained. If you really want that, then you would need something like -numa node,nodeid=0,cpus=0-1 \ -numa mem,nodeid=0,size=2G,policy=membind,hostnode=0-1 \ -numa mem,nodeid=0,size=2G,policy=interleave,hostnode=1,populated=no Hmm... this actually doesn't look too bad, and it is much more future-proof. Eduardo, what do you think about it? Should Wanlong redo his patches to support this "-numa mem" syntax? Parsing it should be easy using the QemuOpts visitor, too. Paolo
[Qemu-devel] [PATCH 16/17] ppc64: Enable QEMU to run on POWER 8 DD1 chip.
From: Prerna Saxena This patch enables QEMU to launch VM guests on POWER8 chip. I have tested this to work with BML kernel on P8 dd1 chip. Signed-off-by: Prerna Saxena Signed-off-by: Alexey Kardashevskiy Reviewed-by: Paul Mackerras --- target-ppc/cpu-models.c |3 +++ target-ppc/cpu-models.h |1 + target-ppc/translate_init.c | 34 ++ 3 files changed, 38 insertions(+) diff --git a/target-ppc/cpu-models.c b/target-ppc/cpu-models.c index 9bb68c8..f8c64dd 100644 --- a/target-ppc/cpu-models.c +++ b/target-ppc/cpu-models.c @@ -1145,6 +1145,8 @@ "POWER7 v2.1") POWERPC_DEF("POWER7_v2.3", CPU_POWERPC_POWER7_v23, POWER7, "POWER7 v2.3") +POWERPC_DEF("POWER8_v0.1", CPU_POWERPC_POWER8_v01, POWER8, +"POWER8 v0.1") POWERPC_DEF("970", CPU_POWERPC_970,970, "PowerPC 970") POWERPC_DEF("970fx_v1.0",CPU_POWERPC_970FX_v10, 970FX, @@ -1390,6 +1392,7 @@ PowerPCCPUAlias ppc_cpu_aliases[] = { { "Dino", "POWER3" }, { "POWER3+", "631" }, { "POWER7", "POWER7_v2.3" }, +{ "POWER8", "POWER8_v0.1" }, { "970fx", "970fx_v3.1" }, { "970mp", "970mp_v1.1" }, { "Apache", "RS64" }, diff --git a/target-ppc/cpu-models.h b/target-ppc/cpu-models.h index 262ca47..b349ad2 100644 --- a/target-ppc/cpu-models.h +++ b/target-ppc/cpu-models.h @@ -556,6 +556,7 @@ enum { CPU_POWERPC_POWER7_v20 = 0x003F0200, CPU_POWERPC_POWER7_v21 = 0x003F0201, CPU_POWERPC_POWER7_v23 = 0x003F0203, +CPU_POWERPC_POWER8_v01 = 0x004B0100, CPU_POWERPC_970= 0x00390202, CPU_POWERPC_970FX_v10 = 0x00391100, CPU_POWERPC_970FX_v20 = 0x003C0200, diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 95aebf7..2502758 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -7011,6 +7011,40 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data) pcc->l1_dcache_size = 0x8000; pcc->l1_icache_size = 0x8000; } + +POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data) +{ +DeviceClass *dc = DEVICE_CLASS(oc); +PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + +dc->desc = "POWER8"; +pcc->init_proc = init_proc_POWER7; +pcc->check_pow = check_pow_nocheck; +pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | + PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | + PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | + PPC_FLOAT_STFIWX | + PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | + PPC_MEM_SYNC | PPC_MEM_EIEIO | + PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | + PPC_64B | PPC_ALTIVEC | + PPC_SEGMENT_64B | PPC_SLBI | + PPC_POPCNTB | PPC_POPCNTWD; +pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX; +pcc->msr_mask = 0x8204FF36ULL; +pcc->mmu_model = POWERPC_MMU_2_06; +#if defined(CONFIG_SOFTMMU) +pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault; +#endif +pcc->excp_model = POWERPC_EXCP_POWER7; +pcc->bus_model = PPC_FLAGS_INPUT_POWER7; +pcc->bfd_mach = bfd_mach_ppc64; +pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | + POWERPC_FLAG_BE | POWERPC_FLAG_PMM | + POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR; +pcc->l1_dcache_size = 0x8000; +pcc->l1_icache_size = 0x8000; +} #endif /* defined (TARGET_PPC64) */ -- 1.7.10.4
[Qemu-devel] [PATCH 15/17] pseries: savevm support with KVM
From: David Gibson At present, the savevm / migration support for the pseries machine will not work when KVM is enabled. That's because KVM manages the guest's hash page table in the host kernel, so qemu has no visibility of it. This patch fixes this by using new kernel interfaces to extract and reinsert the guest's hash table during the migration process. Signed-off-by: David Gibson Signed-off-by: Alexey Kardashevskiy --- hw/ppc/spapr.c | 106 ++-- include/hw/ppc/spapr.h |1 + target-ppc/kvm.c | 69 +++ target-ppc/kvm_ppc.h | 22 ++ 4 files changed, 176 insertions(+), 22 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 211f434..9489edc 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -744,17 +744,27 @@ static int htab_save_setup(QEMUFile *f, void *opaque) { sPAPREnvironment *spapr = opaque; -spapr->htab_save_index = 0; -spapr->htab_first_pass = true; - /* "Iteration" header */ qemu_put_be32(f, spapr->htab_shift); +if (spapr->htab) { +spapr->htab_save_index = 0; +spapr->htab_first_pass = true; +} else { +assert(kvm_enabled()); + +spapr->htab_fd = kvmppc_get_htab_fd(false); +if (spapr->htab_fd < 0) { +fprintf(stderr, "Unable to open fd for reading hash table from KVM: %s\n", +strerror(errno)); +return -1; +} +} + + return 0; } -#define MAX_ITERATION_NS500 /* 5 ms */ - static void htab_save_first_pass(QEMUFile *f, sPAPREnvironment *spapr, int64_t max_ns) { @@ -805,8 +815,8 @@ static void htab_save_first_pass(QEMUFile *f, sPAPREnvironment *spapr, spapr->htab_save_index = index; } -static bool htab_save_later_pass(QEMUFile *f, sPAPREnvironment *spapr, - int64_t max_ns) +static int htab_save_later_pass(QEMUFile *f, sPAPREnvironment *spapr, +int64_t max_ns) { bool final = max_ns < 0; int htabslots = HTAB_SIZE(spapr) / HASH_PTE_SIZE_64; @@ -879,21 +889,32 @@ static bool htab_save_later_pass(QEMUFile *f, sPAPREnvironment *spapr, spapr->htab_save_index = index; -return (examined >= htabslots) && (sent == 0); +return (examined >= htabslots) && (sent == 0) ? 1 : 0; } +#define MAX_ITERATION_NS500 /* 5 ms */ +#define MAX_KVM_BUF_SIZE2048 + static int htab_save_iterate(QEMUFile *f, void *opaque) { sPAPREnvironment *spapr = opaque; -bool nothingleft = false;; +int rc = 0; /* Iteration header */ qemu_put_be32(f, 0); -if (spapr->htab_first_pass) { +if (!spapr->htab) { +assert(kvm_enabled()); + +rc = kvmppc_save_htab(f, spapr->htab_fd, + MAX_KVM_BUF_SIZE, MAX_ITERATION_NS); +if (rc < 0) { +return rc; +} +} else if (spapr->htab_first_pass) { htab_save_first_pass(f, spapr, MAX_ITERATION_NS); } else { -nothingleft = htab_save_later_pass(f, spapr, MAX_ITERATION_NS); +rc = htab_save_later_pass(f, spapr, MAX_ITERATION_NS); } /* End marker */ @@ -901,7 +922,7 @@ static int htab_save_iterate(QEMUFile *f, void *opaque) qemu_put_be16(f, 0); qemu_put_be16(f, 0); -return nothingleft ? 1 : 0; +return rc; } static int htab_save_complete(QEMUFile *f, void *opaque) @@ -911,7 +932,20 @@ static int htab_save_complete(QEMUFile *f, void *opaque) /* Iteration header */ qemu_put_be32(f, 0); -htab_save_later_pass(f, spapr, -1); +if (!spapr->htab) { +int rc; + +assert(kvm_enabled()); + +rc = kvmppc_save_htab(f, spapr->htab_fd, MAX_KVM_BUF_SIZE, -1); +if (rc < 0) { +return rc; +} +close(spapr->htab_fd); +spapr->htab_fd = -1; +} else { +htab_save_later_pass(f, spapr, -1); +} /* End marker */ qemu_put_be32(f, 0); @@ -925,6 +959,7 @@ static int htab_load(QEMUFile *f, void *opaque, int version_id) { sPAPREnvironment *spapr = opaque; uint32_t section_hdr; +int fd = -1; if (version_id < 1 || version_id > 1) { fprintf(stderr, "htab_load() bad version\n"); @@ -941,6 +976,16 @@ static int htab_load(QEMUFile *f, void *opaque, int version_id) return 0; } +if (!spapr->htab) { +assert(kvm_enabled()); + +fd = kvmppc_get_htab_fd(true); +if (fd < 0) { +fprintf(stderr, "Unable to open fd to restore KVM hash table: %s\n", +strerror(errno)); +} +} + while (true) { uint32_t index; uint16_t n_valid, n_invalid; @@ -954,24 +999,41 @@ static int htab_load(QEMUFile *f, void *opaque, int version_id) break; } -if ((index + n_valid + n_invalid) >= +if ((index + n_valid + n_inv
[Qemu-devel] [PATCH 17/17] spapr-pci: rework MSI/MSIX
The specific of sPAPR platform is that the guest allocates MSI/MSIX vectors via RTAS hypercalls and only operates with global IRQ numbers. In the real hardware, PHB is expected to convert MSIMessage to an IRQ number. So it is up to the host kernel to setup correct MSIMessage in a real device and a PHB where a device sits on. Therefore MSIMessage handling is completely hidden in QEMU. Previously every PCI host bridge implemented its own MSI memory window to catch msi_notify()/msix_notify() calls from QEMU devices (virtio-pci or vfio) and redirect them to the guest via qemu_pulse_irq(). MSIMessage encoding was: * .addr - address within the PHB MSI window; * .data - the device index on PHB plus vector number. The MSI MR write function translated this MSIMessage to a global VIRQ number and called qemu_pulse_irq(). However the total number of IRQs is not really big (at the moment it is 1024 IRQs starting from 4096) and even 16bit data field of MSIMessage seems to be enough to store a VIRQ number there so no decoding will be needed. The patch does: 1. remove MSI windows from a PHB; 2. add a single memory region for all MSIs in the guest; 3. encode MSIMessage as: * .addr - a fixed address of SPAPR_PCI_MSI_WINDOW==0x400ULL; * .data as a IRQ number. 4. change IRQ allocator to align first IRQ number for MSI as it uses lowest .data bits to put a vector number; this is not required for MSI-X though as it has a per vector .data field. Signed-off-by: Alexey Kardashevskiy --- hw/ppc/spapr.c | 29 +++-- hw/ppc/spapr_pci.c | 94 ++- include/hw/pci-host/spapr.h |8 ++-- include/hw/ppc/spapr.h |4 +- 4 files changed, 73 insertions(+), 62 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 9489edc..75d29d8 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -88,6 +88,9 @@ int spapr_allocate_irq(int hint, bool lsi) if (hint) { irq = hint; +if (hint >= spapr->next_irq) { +spapr->next_irq = hint + 1; +} /* FIXME: we should probably check for collisions somehow */ } else { irq = spapr->next_irq++; @@ -103,22 +106,39 @@ int spapr_allocate_irq(int hint, bool lsi) return irq; } -/* Allocate block of consequtive IRQs, returns a number of the first */ -int spapr_allocate_irq_block(int num, bool lsi) +/* + * Allocate block of consequtive IRQs, returns a number of the first. + * If msi==true, aligns the first IRQ number to num. + */ +int spapr_allocate_irq_block(int num, bool lsi, bool msi) { int first = -1; -int i; +int i, hint = 0; + +/* + * MSIMesage::data is used for storing VIRQ so + * it has to be aligned to num to support multiple + * MSI vectors. MSI-X is not affected by this. + * The hint is used for the first IRQ, the rest should + * be allocated continously. + */ +if (msi) { +assert((num == 1) || (num == 2) || (num == 4) || + (num == 8) || (num == 16) || (num == 32)); +hint = (spapr->next_irq + num - 1) & ~(num - 1); +} for (i = 0; i < num; ++i) { int irq; -irq = spapr_allocate_irq(0, lsi); +irq = spapr_allocate_irq(hint, lsi); if (!irq) { return -1; } if (0 == i) { first = irq; +hint = 0; } /* If the above doesn't create a consecutive block then that's @@ -1252,6 +1272,7 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args) spapr_create_nvram(spapr); /* Set up PCI */ +spapr_pci_msi_init(spapr, SPAPR_PCI_MSI_WINDOW); spapr_pci_rtas_init(); phb = spapr_create_phb(spapr, 0); diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 4d8e3cd..23dbc0e 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -253,30 +253,6 @@ static int spapr_msicfg_find(sPAPRPHBState *phb, uint32_t config_addr, return -1; } -/* - * Set MSI/MSIX message data. - * This is required for msi_notify()/msix_notify() which - * will write at the addresses via spapr_msi_write(). - */ -static void spapr_msi_setmsg(PCIDevice *pdev, hwaddr addr, - bool msix, unsigned req_num) -{ -unsigned i; -MSIMessage msg = { .address = addr, .data = 0 }; - -if (!msix) { -msi_set_message(pdev, msg); -trace_spapr_pci_msi_setup(pdev->name, 0, msg.address); -return; -} - -for (i = 0; i < req_num; ++i) { -msg.address = addr | (i << 2); -msix_set_message(pdev, i, msg); -trace_spapr_pci_msi_setup(pdev->name, i, msg.address); -} -} - static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPREnvironment *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, @@ -288,9 +264,10 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPREnvironment *spapr, unsigned i
[Qemu-devel] [PATCH 12/17] pseries: savevm support for PCI host bridge
From: David Gibson This adds the necessary support for saving the state of the PAPR virtual PCI host bridge (or host bridges). Signed-off-by: David Gibson Signed-off-by: Alexey Kardashevskiy --- hw/ppc/spapr_pci.c | 49 +++ include/hw/pci-host/spapr.h |6 +++--- 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index c8c12c8..4d8e3cd 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -696,6 +696,54 @@ static Property spapr_phb_properties[] = { DEFINE_PROP_END_OF_LIST(), }; +static const VMStateDescription vmstate_spapr_pci_lsi = { +.name = "spapr_pci/lsi", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField []) { +VMSTATE_UINT32_EQUAL(irq, struct spapr_pci_lsi), + +VMSTATE_END_OF_LIST() +}, +}; + +static const VMStateDescription vmstate_spapr_pci_msi = { +.name = "spapr_pci/lsi", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField []) { +VMSTATE_UINT32(config_addr, struct spapr_pci_msi), +VMSTATE_UINT32(irq, struct spapr_pci_msi), +VMSTATE_UINT32(nvec, struct spapr_pci_msi), + +VMSTATE_END_OF_LIST() +}, +}; + +static const VMStateDescription vmstate_spapr_pci = { +.name = "spapr_pci", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField []) { +VMSTATE_UINT64_EQUAL(buid, sPAPRPHBState), +VMSTATE_UINT32_EQUAL(dma_liobn, sPAPRPHBState), +VMSTATE_UINT64_EQUAL(mem_win_addr, sPAPRPHBState), +VMSTATE_UINT64_EQUAL(mem_win_size, sPAPRPHBState), +VMSTATE_UINT64_EQUAL(io_win_addr, sPAPRPHBState), +VMSTATE_UINT64_EQUAL(io_win_size, sPAPRPHBState), +VMSTATE_UINT64_EQUAL(msi_win_addr, sPAPRPHBState), +VMSTATE_STRUCT_ARRAY(lsi_table, sPAPRPHBState, PCI_NUM_PINS, 0, + vmstate_spapr_pci_lsi, struct spapr_pci_lsi), +VMSTATE_STRUCT_ARRAY(msi_table, sPAPRPHBState, SPAPR_MSIX_MAX_DEVS, 0, + vmstate_spapr_pci_msi, struct spapr_pci_msi), + +VMSTATE_END_OF_LIST() +}, +}; + static void spapr_phb_class_init(ObjectClass *klass, void *data) { SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass); @@ -704,6 +752,7 @@ static void spapr_phb_class_init(ObjectClass *klass, void *data) sdc->init = spapr_phb_init; dc->props = spapr_phb_properties; dc->reset = spapr_phb_reset; +dc->vmsd = &vmstate_spapr_pci; } static const TypeInfo spapr_phb_info = { diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h index 1e23dbf..93f9511 100644 --- a/include/hw/pci-host/spapr.h +++ b/include/hw/pci-host/spapr.h @@ -52,14 +52,14 @@ typedef struct sPAPRPHBState { sPAPRTCETable *tcet; AddressSpace iommu_as; -struct { +struct spapr_pci_lsi { uint32_t irq; } lsi_table[PCI_NUM_PINS]; -struct { +struct spapr_pci_msi { uint32_t config_addr; uint32_t irq; -int nvec; +uint32_t nvec; } msi_table[SPAPR_MSIX_MAX_DEVS]; QLIST_ENTRY(sPAPRPHBState) list; -- 1.7.10.4
[Qemu-devel] [PATCH 09/17] pseries: rework PAPR virtual SCSI
The patch reimplements handling of indirect requests in order to simplify upcoming live migration support. - all pointers (except SCSIRequest*) were replaces with integer indexes and offsets; - DMA'ed srp_direct_buf kept untouched (ie. BE format); - vscsi_fetch_desc() is added, now it is the only place where descriptors are fetched and byteswapped; - vscsi_req struct fields converted to migration-friendly types; - many dprintf()'s fixed. This also removed an unused field 'lun' from the spapr_vscsi device which is assigned, but never used. So, remove it. [David Gibson: removed unused 'lun'] Signed-off-by: Alexey Kardashevskiy Cc: David Gibson --- hw/scsi/spapr_vscsi.c | 224 + 1 file changed, 131 insertions(+), 93 deletions(-) diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c index e8978bf..1e93102 100644 --- a/hw/scsi/spapr_vscsi.c +++ b/hw/scsi/spapr_vscsi.c @@ -75,20 +75,19 @@ typedef struct vscsi_req { /* SCSI request tracking */ SCSIRequest *sreq; uint32_tqtag; /* qemu tag != srp tag */ -int lun; -int active; -longdata_len; -int writing; -int senselen; +boolactive; +uint32_tdata_len; +boolwriting; +uint32_tsenselen; uint8_t sense[SCSI_SENSE_BUF_SIZE]; /* RDMA related bits */ uint8_t dma_fmt; -struct srp_direct_buf ext_desc; -struct srp_direct_buf *cur_desc; -struct srp_indirect_buf *ind_desc; -int local_desc; -int total_desc; +uint16_tlocal_desc; +uint16_ttotal_desc; +uint16_tcdb_offset; +uint16_tcur_desc_num; +uint16_tcur_desc_offset; } vscsi_req; #define TYPE_VIO_SPAPR_VSCSI_DEVICE "spapr-vscsi" @@ -264,93 +263,139 @@ static int vscsi_send_rsp(VSCSIState *s, vscsi_req *req, return 0; } -static inline void vscsi_swap_desc(struct srp_direct_buf *desc) +static inline struct srp_direct_buf vscsi_swap_desc(struct srp_direct_buf desc) { -desc->va = be64_to_cpu(desc->va); -desc->len = be32_to_cpu(desc->len); +desc.va = be64_to_cpu(desc.va); +desc.len = be32_to_cpu(desc.len); +return desc; +} + +static int vscsi_fetch_desc(VSCSIState *s, struct vscsi_req *req, +unsigned n, unsigned buf_offset, +struct srp_direct_buf *ret) +{ +struct srp_cmd *cmd = &req->iu.srp.cmd; + +switch (req->dma_fmt) { +case SRP_NO_DATA_DESC: { +dprintf("VSCSI: no data descriptor\n"); +return 0; +} +case SRP_DATA_DESC_DIRECT: { +*ret = *(struct srp_direct_buf *)(cmd->add_data + req->cdb_offset); +assert(req->cur_desc_num == 0); +dprintf("VSCSI: direct segment"); +break; +} +case SRP_DATA_DESC_INDIRECT: { +struct srp_indirect_buf *tmp = (struct srp_indirect_buf *) + (cmd->add_data + req->cdb_offset); +if (n < req->local_desc) { +*ret = tmp->desc_list[n]; +dprintf("VSCSI: indirect segment local tag=0x%x desc#%d/%d", +req->qtag, n, req->local_desc); + +} else if (n < req->total_desc) { +int rc; +struct srp_direct_buf tbl_desc = vscsi_swap_desc(tmp->table_desc); +unsigned desc_offset = (n - req->local_desc) * +sizeof(struct srp_direct_buf); + +if (desc_offset > tbl_desc.len) { +dprintf("VSCSI: #%d is ouf of range (%d bytes)\n", +n, desc_offset); +return -1; +} +rc = spapr_vio_dma_read(&s->vdev, tbl_desc.va + desc_offset, +ret, sizeof(struct srp_direct_buf)); +if (rc) { +dprintf("VSCSI: spapr_vio_dma_read -> %d reading ext_desc\n", +rc); +return rc; +} +dprintf("VSCSI: indirect segment ext. tag=0x%x desc#%d/%d { va=%"PRIx64" len=%x }", +req->qtag, n, req->total_desc, tbl_desc.va, tbl_desc.len); +} else { +dprintf("VSCSI: Out of descriptors !\n"); +return 0; +} +break; +} +default: +fprintf(stderr, "VSCSI: Unknown format %x\n", req->dma_fmt); +return -1; +} + +*ret = vscsi_swap_desc(*ret); +if (buf_offset > ret->len) { +dprintf(" offset=%x is out of a descriptor #%d boundary=%x\n", +buf_offset, req->cur_desc_num, ret->len); +return -1; +} +ret->va += buf_offset; +ret->len -= buf_offset; + +dprintf(" cur=%d offs
[Qemu-devel] [PATCH 14/17] pseries: Support for in-kernel XICS interrupt controller
From: David Gibson Recent (host) kernels support emulating the PAPR defined "XICS" interrupt controller system within KVM. This patch allows qemu to initialize and configure the in-kernel XICS, and keep its state in sync with qemu's XICS state as necessary. This should give considerable performance improvements. e.g. on a simple IPI ping-pong test between hardware threads, using qemu XICS gives us around 5,000 irqs/second, whereas the in-kernel XICS gives us around 70,000 irqs/s on the same hardware configuration. [Mike Qiu : fixed mistype which caused ics_set_kvm_state() to fail] Signed-off-by: David Gibson [aik: moved to a separate device] Signed-off-by: Alexey Kardashevskiy --- default-configs/ppc64-softmmu.mak |1 + hw/intc/Makefile.objs |1 + hw/intc/xics_kvm.c| 445 + hw/ppc/spapr.c| 32 ++- include/hw/ppc/xics.h | 13 ++ 5 files changed, 489 insertions(+), 3 deletions(-) create mode 100644 hw/intc/xics_kvm.c diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak index 69a9f8d..5b995f9 100644 --- a/default-configs/ppc64-softmmu.mak +++ b/default-configs/ppc64-softmmu.mak @@ -48,5 +48,6 @@ CONFIG_OPENPIC_KVM=$(and $(CONFIG_E500),$(CONFIG_KVM)) # For pSeries CONFIG_PCI_HOTPLUG=y CONFIG_XICS=$(CONFIG_PSERIES) +CONFIG_XICS_KVM=$(and $(CONFIG_PSERIES),$(CONFIG_KVM)) # For PReP CONFIG_MC146818RTC=y diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs index abe8f80..9e77afe 100644 --- a/hw/intc/Makefile.objs +++ b/hw/intc/Makefile.objs @@ -23,3 +23,4 @@ obj-$(CONFIG_OPENPIC) += openpic.o obj-$(CONFIG_OPENPIC_KVM) += openpic_kvm.o obj-$(CONFIG_SH4) += sh_intc.o obj-$(CONFIG_XICS) += xics.o +obj-$(CONFIG_XICS_KVM) += xics_kvm.o diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c new file mode 100644 index 000..d5604a7 --- /dev/null +++ b/hw/intc/xics_kvm.c @@ -0,0 +1,445 @@ +/* + * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator + * + * PAPR Virtualized Interrupt System, aka ICS/ICP aka xics, in-kernel emulation + * + * Copyright (c) 2013 David Gibson, IBM Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#include "hw/hw.h" +#include "trace.h" +#include "hw/ppc/spapr.h" +#include "hw/ppc/xics.h" +#include "kvm_ppc.h" +#include "qemu/config-file.h" + +#include + +struct icp_state_kvm { +struct icp_state parent; + +uint32_t set_xive_token; +uint32_t get_xive_token; +uint32_t int_off_token; +uint32_t int_on_token; +int kernel_xics_fd; +}; + +static void icp_get_kvm_state(struct icp_server_state *ss) +{ +uint64_t state; +struct kvm_one_reg reg = { +.id = KVM_REG_PPC_ICP_STATE, +.addr = (uintptr_t)&state, +}; +int ret; + +if (!ss->cs) { +return; /* kernel irqchip not in use */ +} + +ret = kvm_vcpu_ioctl(ss->cs, KVM_GET_ONE_REG, ®); +if (ret != 0) { +fprintf(stderr, "Unable to retrieve KVM interrupt controller state" +" for CPU %d: %s\n", ss->cs->cpu_index, strerror(errno)); +exit(1); +} + +ss->xirr = state >> KVM_REG_PPC_ICP_XISR_SHIFT; +ss->mfrr = (state >> KVM_REG_PPC_ICP_MFRR_SHIFT) +& KVM_REG_PPC_ICP_MFRR_MASK; +ss->pending_priority = (state >> KVM_REG_PPC_ICP_PPRI_SHIFT) +& KVM_REG_PPC_ICP_PPRI_MASK; +} + +static int icp_set_kvm_state(struct icp_server_state *ss) +{ +uint64_t state; +struct kvm_one_reg reg = { +.id = KVM_REG_PPC_ICP_STATE, +.addr = (uintptr_t)&state, +}; +int ret; + +if (!ss->cs) { +return 0; /* kernel irqchip not in use */ +} + +state = ((uint64_t)ss->xirr << KVM_REG_PPC_ICP_XISR_SHIFT) +| ((uint64_t)ss->mfrr << KVM_REG_PPC_ICP_MFRR_SHIFT) +| ((uint64_t)ss->pending_priority << KVM_REG_PPC_ICP_PPRI_SHIFT); + +ret = kvm_vcpu_ioctl(ss->cs,
[Qemu-devel] [PATCH 11/17] pseries: savevm support for pseries machine
From: David Gibson This adds the necessary pieces to implement savevm / migration for the pseries machine. The most complex part here is migrating the hash table - for the paravirtualized pseries machine the guest's hash page table is not stored within guest memory, but externally and the guest accesses it via hypercalls. This patch uses a hypervisor reserved bit of the HPTE as a dirty bit (tracking changes to the HPTE itself, not the page it references). This is used to implement a live migration style incremental save and restore of the hash table contents. In addition it adds VMStateDescription information to save and restore the (few) remaining pieces of state information needed by the pseries machine. Signed-off-by: David Gibson Signed-off-by: Alexey Kardashevskiy --- hw/ppc/spapr.c | 269 +++- hw/ppc/spapr_hcall.c |8 +- include/hw/ppc/spapr.h | 12 ++- 3 files changed, 281 insertions(+), 8 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index def3505..f989a22 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -32,6 +32,7 @@ #include "sysemu/cpus.h" #include "sysemu/kvm.h" #include "kvm_ppc.h" +#include "mmu-hash64.h" #include "hw/boards.h" #include "hw/ppc/ppc.h" @@ -667,7 +668,7 @@ static void spapr_cpu_reset(void *opaque) env->spr[SPR_HIOR] = 0; -env->external_htab = spapr->htab; +env->external_htab = (uint8_t *)spapr->htab; env->htab_base = -1; env->htab_mask = HTAB_SIZE(spapr) - 1; env->spr[SPR_SDR1] = (target_ulong)spapr->htab | @@ -719,6 +720,268 @@ static int spapr_vga_init(PCIBus *pci_bus) } } +static const VMStateDescription vmstate_spapr = { +.name = "spapr", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField []) { +VMSTATE_UINT32(next_irq, sPAPREnvironment), + +/* RTC offset */ +VMSTATE_UINT64(rtc_offset, sPAPREnvironment), + +VMSTATE_END_OF_LIST() +}, +}; + +#define HPTE(_table, _i) (void *)(((uint64_t *)(_table)) + ((_i) * 2)) +#define HPTE_VALID(_hpte) (tswap64(*((uint64_t *)(_hpte))) & HPTE64_V_VALID) +#define HPTE_DIRTY(_hpte) (tswap64(*((uint64_t *)(_hpte))) & HPTE64_V_HPTE_DIRTY) +#define CLEAN_HPTE(_hpte) ((*(uint64_t *)(_hpte)) &= tswap64(~HPTE64_V_HPTE_DIRTY)) + +static int htab_save_setup(QEMUFile *f, void *opaque) +{ +sPAPREnvironment *spapr = opaque; + +spapr->htab_save_index = 0; +spapr->htab_first_pass = true; + +/* "Iteration" header */ +qemu_put_be32(f, spapr->htab_shift); + +return 0; +} + +#define MAX_ITERATION_NS500 /* 5 ms */ + +static void htab_save_first_pass(QEMUFile *f, sPAPREnvironment *spapr, + int64_t max_ns) +{ +int htabslots = HTAB_SIZE(spapr) / HASH_PTE_SIZE_64; +int index = spapr->htab_save_index; +int64_t starttime = qemu_get_clock_ns(rt_clock); + +assert(spapr->htab_first_pass); + +do { +int chunkstart; + +/* Consume invalid HPTEs */ +while ((index < htabslots) + && !HPTE_VALID(HPTE(spapr->htab, index))) { +index++; +CLEAN_HPTE(HPTE(spapr->htab, index)); +} + +/* Consume valid HPTEs */ +chunkstart = index; +while ((index < htabslots) + && HPTE_VALID(HPTE(spapr->htab, index))) { +index++; +CLEAN_HPTE(HPTE(spapr->htab, index)); +} + +if (index > chunkstart) { +int n_valid = index - chunkstart; + +qemu_put_be32(f, chunkstart); +qemu_put_be16(f, n_valid); +qemu_put_be16(f, 0); +qemu_put_buffer(f, HPTE(spapr->htab, chunkstart), +HASH_PTE_SIZE_64 * n_valid); + +if ((qemu_get_clock_ns(rt_clock) - starttime) > max_ns) { +break; +} +} +} while ((index < htabslots) && !qemu_file_rate_limit(f)); + +if (index >= htabslots) { +assert(index == htabslots); +index = 0; +spapr->htab_first_pass = false; +} +spapr->htab_save_index = index; +} + +static bool htab_save_later_pass(QEMUFile *f, sPAPREnvironment *spapr, + int64_t max_ns) +{ +bool final = max_ns < 0; +int htabslots = HTAB_SIZE(spapr) / HASH_PTE_SIZE_64; +int examined = 0, sent = 0; +int index = spapr->htab_save_index; +int64_t starttime = qemu_get_clock_ns(rt_clock); + +assert(!spapr->htab_first_pass); + +do { +int chunkstart, invalidstart; + +/* Consume non-dirty HPTEs */ +while ((index < htabslots) + && !HPTE_DIRTY(HPTE(spapr->htab, index))) { +index++; +examined++; +} + +chunkstart = index; +/* Consume valid dirty HPTEs */ +while ((index < htabslots) + && HPTE_DIRTY(HPTE(spapr->htab, index)) +
[Qemu-devel] [PATCH 06/17] pseries: savevm support for VIO devices
From: David Gibson This patch adds helpers to allow PAPR VIO devices to save state common to all VIO devices during savevm. Signed-off-by: David Gibson Signed-off-by: Alexey Kardashevskiy --- hw/ppc/spapr_vio.c | 20 include/hw/ppc/spapr_vio.h |5 + 2 files changed, 25 insertions(+) diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c index 9c18741..565d883 100644 --- a/hw/ppc/spapr_vio.c +++ b/hw/ppc/spapr_vio.c @@ -542,6 +542,26 @@ static const TypeInfo spapr_vio_bridge_info = { .class_init= spapr_vio_bridge_class_init, }; +const VMStateDescription vmstate_spapr_vio = { +.name = "spapr_vio", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField []) { +/* Sanity check */ +VMSTATE_UINT32_EQUAL(reg, VIOsPAPRDevice), +VMSTATE_UINT32_EQUAL(irq, VIOsPAPRDevice), + +/* General VIO device state */ +VMSTATE_UINTTL(signal_state, VIOsPAPRDevice), +VMSTATE_UINT64(crq.qladdr, VIOsPAPRDevice), +VMSTATE_UINT32(crq.qsize, VIOsPAPRDevice), +VMSTATE_UINT32(crq.qnext, VIOsPAPRDevice), + +VMSTATE_END_OF_LIST() +}, +}; + static void vio_spapr_device_class_init(ObjectClass *klass, void *data) { DeviceClass *k = DEVICE_CLASS(klass); diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h index 3609327..46edc2a 100644 --- a/include/hw/ppc/spapr_vio.h +++ b/include/hw/ppc/spapr_vio.h @@ -134,4 +134,9 @@ VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus); void spapr_vio_quiesce(void); +extern const VMStateDescription vmstate_spapr_vio; + +#define VMSTATE_SPAPR_VIO(_f, _s) \ +VMSTATE_STRUCT(_f, _s, 0, vmstate_spapr_vio, VIOsPAPRDevice) + #endif /* _HW_SPAPR_VIO_H */ -- 1.7.10.4
[Qemu-devel] [PATCH 10/17] pseries: savevm support for PAPR virtual SCSI
From: David Gibson This patch adds the necessary support for saving the state of the PAPR VIO virtual SCSI device. This also saves and restores active SCSI requests. [aik: implemented vscsi_req save/restore] Signed-off-by: Alexey Kardashevskiy Cc: David Gibson --- hw/scsi/spapr_vscsi.c | 82 - 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c index 1e93102..4db3a47 100644 --- a/hw/scsi/spapr_vscsi.c +++ b/hw/scsi/spapr_vscsi.c @@ -579,6 +579,69 @@ static void vscsi_request_cancelled(SCSIRequest *sreq) vscsi_put_req(req); } +static const VMStateDescription vmstate_spapr_vscsi_req = { +.name = "spapr_vscsi_req", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField []) { +VMSTATE_BUFFER(crq.raw, vscsi_req), +VMSTATE_BUFFER(iu.srp.reserved, vscsi_req), +VMSTATE_UINT32(qtag, vscsi_req), +VMSTATE_BOOL(active, vscsi_req), +VMSTATE_UINT32(data_len, vscsi_req), +VMSTATE_BOOL(writing, vscsi_req), +VMSTATE_UINT32(senselen, vscsi_req), +VMSTATE_BUFFER(sense, vscsi_req), +VMSTATE_UINT8(dma_fmt, vscsi_req), +VMSTATE_UINT16(local_desc, vscsi_req), +VMSTATE_UINT16(total_desc, vscsi_req), +VMSTATE_UINT16(cdb_offset, vscsi_req), + /*Restart SCSI request from the beginning for now */ + /*VMSTATE_UINT16(cur_desc_num, vscsi_req), +VMSTATE_UINT16(cur_desc_offset, vscsi_req),*/ +VMSTATE_END_OF_LIST() +}, +}; + +static void vscsi_save_request(QEMUFile *f, SCSIRequest *sreq) +{ +vscsi_req *req = sreq->hba_private; +assert(req->active); + +vmstate_save_state(f, &vmstate_spapr_vscsi_req, req); + +dprintf("VSCSI: saving tag=%u, current desc#%d, offset=%x\n", +req->qtag, req->cur_desc_num, req->cur_desc_offset); +} + +static void *vscsi_load_request(QEMUFile *f, SCSIRequest *sreq) +{ +SCSIBus *bus = sreq->bus; +VSCSIState *s = VIO_SPAPR_VSCSI_DEVICE(bus->qbus.parent); +vscsi_req *req; +int rc; + +assert(sreq->tag < VSCSI_REQ_LIMIT); +req = &s->reqs[sreq->tag]; +assert(!req->active); + +memset(req, 0, sizeof(*req)); +rc = vmstate_load_state(f, &vmstate_spapr_vscsi_req, req, 1); +if (rc) { +fprintf(stderr, "VSCSI: failed loading request tag#%u\n", sreq->tag); +return NULL; +} +assert(req->active); + +req->sreq = scsi_req_ref(sreq); + +dprintf("VSCSI: restoring tag=%u, current desc#%d, offset=%x\n", +req->qtag, req->cur_desc_num, req->cur_desc_offset); + +return req; +} + static void vscsi_process_login(VSCSIState *s, vscsi_req *req) { union viosrp_iu *iu = &req->iu; @@ -933,7 +996,9 @@ static const struct SCSIBusInfo vscsi_scsi_info = { .transfer_data = vscsi_transfer_data, .complete = vscsi_command_complete, -.cancel = vscsi_request_cancelled +.cancel = vscsi_request_cancelled, +.save_request = vscsi_save_request, +.load_request = vscsi_load_request, }; static void spapr_vscsi_reset(VIOsPAPRDevice *dev) @@ -992,6 +1057,20 @@ static Property spapr_vscsi_properties[] = { DEFINE_PROP_END_OF_LIST(), }; +static const VMStateDescription vmstate_spapr_vscsi = { +.name = "spapr_vscsi", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField []) { +VMSTATE_SPAPR_VIO(vdev, VSCSIState), +/* VSCSI state */ +/* */ + +VMSTATE_END_OF_LIST() +}, +}; + static void spapr_vscsi_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -1006,6 +1085,7 @@ static void spapr_vscsi_class_init(ObjectClass *klass, void *data) k->signal_mask = 0x0001; dc->props = spapr_vscsi_properties; k->rtce_window_size = 0x1000; +dc->vmsd = &vmstate_spapr_vscsi; } static const TypeInfo spapr_vscsi_info = { -- 1.7.10.4
[Qemu-devel] [PATCH 13/17] target-ppc: Add helper for KVM_PPC_RTAS_DEFINE_TOKEN
From: David Gibson Recent PowerKVM allows the kernel to intercept some RTAS calls from the guest directly. This is used to implement the more efficient in-kernel XICS for example. qemu is still responsible for assigning the RTAS token numbers however, and needs to tell the kernel which RTAS function name is assigned to a given token value. This patch adds a convenience wrapper for the KVM_PPC_RTAS_DEFINE_TOKEN ioctl() which is used for this purpose. Signed-off-by: David Gibson Signed-off-by: Alexey Kardashevskiy --- target-ppc/kvm.c | 14 ++ target-ppc/kvm_ppc.h |7 +++ 2 files changed, 21 insertions(+) diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index c89dd58..33ddf63 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -1787,6 +1787,20 @@ static int kvm_ppc_register_host_cpu_type(void) return 0; } +int kvmppc_define_rtas_token(uint32_t token, const char *function) +{ +struct kvm_rtas_token_args args = { +.token = token, +}; + +if (!kvm_check_extension(kvm_state, KVM_CAP_PPC_RTAS)) { +return -ENOENT; +} + +strncpy(args.name, function, sizeof(args.name)); + +return kvm_vm_ioctl(kvm_state, KVM_PPC_RTAS_DEFINE_TOKEN, &args); +} bool kvm_arch_stop_on_emulation_error(CPUState *cpu) { diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h index 771cfbe..21939a8 100644 --- a/target-ppc/kvm_ppc.h +++ b/target-ppc/kvm_ppc.h @@ -38,6 +38,7 @@ uint64_t kvmppc_rma_size(uint64_t current_size, unsigned int hash_shift); #endif /* !CONFIG_USER_ONLY */ int kvmppc_fixup_cpu(PowerPCCPU *cpu); bool kvmppc_has_cap_epr(void); +int kvmppc_define_rtas_token(uint32_t token, const char *function); #else @@ -159,6 +160,12 @@ static inline bool kvmppc_has_cap_epr(void) { return false; } + +static inline int kvmppc_define_rtas_token(uint32_t token, + const char *function) +{ +return -1; +} #endif #ifndef CONFIG_KVM -- 1.7.10.4
[Qemu-devel] [PATCH 08/17] pseries: savevm support for PAPR TCE tables
From: David Gibson This patch adds the necessary VMStateDescription information to save the state of PAPR TCE tables (that is, the PAPR specified IOMMU). Signed-off-by: David Gibson Signed-off-by: Alexey Kardashevskiy --- hw/ppc/spapr_iommu.c | 25 + 1 file changed, 25 insertions(+) diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c index 91bc8e4..ba1f7b6 100644 --- a/hw/ppc/spapr_iommu.c +++ b/hw/ppc/spapr_iommu.c @@ -112,6 +112,25 @@ static IOMMUTLBEntry spapr_tce_translate_iommu(MemoryRegion *iommu, hwaddr addr) }; } +static const VMStateDescription vmstate_spapr_tce_table = { +.name = "spapr_iommu", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField []) { +/* Sanity check */ +VMSTATE_UINT32_EQUAL(liobn, sPAPRTCETable), +VMSTATE_UINT32_EQUAL(window_size, sPAPRTCETable), + +/* IOMMU state */ +VMSTATE_BOOL(bypass, sPAPRTCETable), +VMSTATE_VBUFFER_DIVIDE(table, sPAPRTCETable, 0, NULL, 0, window_size, + SPAPR_TCE_PAGE_SIZE / sizeof(sPAPRTCE)), + +VMSTATE_END_OF_LIST() +}, +}; + static MemoryRegionIOMMUOps spapr_iommu_ops = { .translate = spapr_tce_translate_iommu, }; @@ -156,6 +175,8 @@ sPAPRTCETable *spapr_tce_new_table(uint32_t liobn, size_t window_size) QLIST_INSERT_HEAD(&spapr_tce_tables, tcet, list); +vmstate_register(NULL, tcet->liobn, &vmstate_spapr_tce_table, tcet); + return tcet; } @@ -163,6 +184,10 @@ void spapr_tce_free(sPAPRTCETable *tcet) { QLIST_REMOVE(tcet, list); +vmstate_unregister(NULL, &vmstate_spapr_tce_table, tcet); + +QLIST_REMOVE(tcet, list); + if (!kvm_enabled() || (kvmppc_remove_spapr_tce(tcet->table, tcet->fd, tcet->window_size) != 0)) { -- 1.7.10.4
[Qemu-devel] [PATCH 05/17] pseries: savevm support for XICS interrupt controller
From: David Gibson This patch adds the necessary VMStateDescription information to support savevm/loadvm for the XICS interrupt controller used on the pseries machine. Signed-off-by: David Gibson [aik: added ics_resend() on post_load] Signed-off-by: Alexey Kardashevskiy --- hw/intc/xics.c | 63 1 file changed, 63 insertions(+) diff --git a/hw/intc/xics.c b/hw/intc/xics.c index 0e374c8..3e8f48f 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -497,6 +497,61 @@ static void xics_reset(DeviceState *d) xics_common_reset(XICS(d)); } +static int ics_post_load(void *opaque, int version_id) +{ +int i; +struct ics_state *ics = opaque; + +for (i = 0; i < ics->icp->nr_servers; i++) { +icp_resend(ics->icp, i); +} + +return 0; +} + +const VMStateDescription vmstate_icp_server = { +.name = "icp/server", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField []) { +/* Sanity check */ +VMSTATE_UINT32(xirr, struct icp_server_state), +VMSTATE_UINT8(pending_priority, struct icp_server_state), +VMSTATE_UINT8(mfrr, struct icp_server_state), +VMSTATE_END_OF_LIST() +}, +}; + +static const VMStateDescription vmstate_ics_irq = { +.name = "ics/irq", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField []) { +VMSTATE_UINT32(server, struct ics_irq_state), +VMSTATE_UINT8(priority, struct ics_irq_state), +VMSTATE_UINT8(saved_priority, struct ics_irq_state), +VMSTATE_UINT8(status, struct ics_irq_state), +VMSTATE_END_OF_LIST() +}, +}; + +const VMStateDescription vmstate_ics = { +.name = "ics", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.post_load = ics_post_load, +.fields = (VMStateField []) { +/* Sanity check */ +VMSTATE_UINT32_EQUAL(nr_irqs, struct ics_state), + +VMSTATE_STRUCT_VARRAY_POINTER_UINT32(irqs, struct ics_state, nr_irqs, vmstate_ics_irq, struct ics_irq_state), +VMSTATE_END_OF_LIST() +}, +}; + void xics_common_cpu_setup(struct icp_state *icp, PowerPCCPU *cpu) { CPUState *cs = CPU(cpu); @@ -523,7 +578,11 @@ void xics_common_cpu_setup(struct icp_state *icp, PowerPCCPU *cpu) void xics_cpu_setup(struct icp_state *icp, PowerPCCPU *cpu) { +CPUState *cs = CPU(cpu); +struct icp_server_state *ss = &icp->ss[cs->cpu_index]; + xics_common_cpu_setup(icp, cpu); +vmstate_register(NULL, cs->cpu_index, &vmstate_icp_server, ss); } void xics_common_init(struct icp_state *icp, qemu_irq_handler handler) @@ -555,6 +614,10 @@ static void xics_realize(DeviceState *dev, Error **errp) spapr_rtas_register("ibm,int-off", rtas_int_off); spapr_rtas_register("ibm,int-on", rtas_int_on); +/* We use each the ICS's offset into the global irq number space + * as an instance id. This means we can extend to multiple ICS + * instances without needing to change the savevm format */ +vmstate_register(NULL, icp->ics->offset, &vmstate_ics, icp->ics); } static Property xics_properties[] = { -- 1.7.10.4
[Qemu-devel] [PATCH 03/17] savevm: Implement VMS_DIVIDE flag
From: David Gibson The vmstate infrastructure includes a VMS_MULTIPY flag, and associated VMSTATE_VBUFFER_MULTIPLY helper macro. These can be used to save a variably sized buffer where the size in bytes of the buffer isn't directly accessible as a structure field, but an element count from which the size can be derived is. This patch adds an analogous VMS_DIVIDE option, which handles a variably sized buffer whose size is a submultiple of a field, rather than a multiple. For example a buffer containing per-page structures whose size is derived from a field storing the total address space described by the structures could use this construct. Signed-off-by: David Gibson Signed-off-by: Alexey Kardashevskiy --- include/migration/vmstate.h | 13 + savevm.c|8 2 files changed, 21 insertions(+) diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h index ebc4d09..787f1cb 100644 --- a/include/migration/vmstate.h +++ b/include/migration/vmstate.h @@ -98,6 +98,7 @@ enum VMStateFlags { VMS_MULTIPLY = 0x200, /* multiply "size" field by field_size */ VMS_VARRAY_UINT8 = 0x400, /* Array with size in uint8_t field*/ VMS_VARRAY_UINT32= 0x800, /* Array with size in uint32_t field*/ +VMS_DIVIDE = 0x1000, /* divide "size" field by field_size */ }; typedef struct { @@ -420,6 +421,18 @@ extern const VMStateInfo vmstate_info_bitmap; .start= (_start),\ } +#define VMSTATE_VBUFFER_DIVIDE(_field, _state, _version, _test, _start, _field_size, _divide) { \ +.name = (stringify(_field)), \ +.version_id = (_version), \ +.field_exists = (_test), \ +.size_offset = vmstate_offset_value(_state, _field_size, uint32_t),\ +.size = (_divide), \ +.info = &vmstate_info_buffer,\ +.flags= VMS_VBUFFER|VMS_POINTER|VMS_DIVIDE, \ +.offset = offsetof(_state, _field),\ +.start= (_start),\ +} + #define VMSTATE_VBUFFER(_field, _state, _version, _test, _start, _field_size) { \ .name = (stringify(_field)), \ .version_id = (_version), \ diff --git a/savevm.c b/savevm.c index 48cc2a9..c0fb4a3 100644 --- a/savevm.c +++ b/savevm.c @@ -1658,6 +1658,10 @@ int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd, if (field->flags & VMS_MULTIPLY) { size *= field->size; } +if (field->flags & VMS_DIVIDE) { +assert((size % field->size) == 0); +size /= field->size; +} } if (field->flags & VMS_ARRAY) { n_elems = field->num; @@ -1722,6 +1726,10 @@ void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd, if (field->flags & VMS_MULTIPLY) { size *= field->size; } +if (field->flags & VMS_DIVIDE) { +assert((size % field->size) == 0); +size /= field->size; +} } if (field->flags & VMS_ARRAY) { n_elems = field->num; -- 1.7.10.4
[Qemu-devel] [PATCH 07/17] pseries: savevm support for PAPR VIO logical lan
From: David Gibson This patch adds the necessary VMStateDescription information to support savevm/loadvm for the spapr_llan (PAPR logical lan) device. Signed-off-by: David Gibson Signed-off-by: Alexey Kardashevskiy --- hw/char/spapr_vty.c | 16 hw/net/spapr_llan.c | 24 ++-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/hw/char/spapr_vty.c b/hw/char/spapr_vty.c index 2993848..a799721 100644 --- a/hw/char/spapr_vty.c +++ b/hw/char/spapr_vty.c @@ -142,6 +142,21 @@ static Property spapr_vty_properties[] = { DEFINE_PROP_END_OF_LIST(), }; +static const VMStateDescription vmstate_spapr_vty = { +.name = "spapr_vty", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField []) { +VMSTATE_SPAPR_VIO(sdev, VIOsPAPRVTYDevice), + +VMSTATE_UINT32(in, VIOsPAPRVTYDevice), +VMSTATE_UINT32(out, VIOsPAPRVTYDevice), +VMSTATE_BUFFER(buf, VIOsPAPRVTYDevice), +VMSTATE_END_OF_LIST() +}, +}; + static void spapr_vty_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -152,6 +167,7 @@ static void spapr_vty_class_init(ObjectClass *klass, void *data) k->dt_type = "serial"; k->dt_compatible = "hvterm1"; dc->props = spapr_vty_properties; +dc->vmsd = &vmstate_spapr_vty; } static const TypeInfo spapr_vty_info = { diff --git a/hw/net/spapr_llan.c b/hw/net/spapr_llan.c index 03a09f2..46f7d5f 100644 --- a/hw/net/spapr_llan.c +++ b/hw/net/spapr_llan.c @@ -81,9 +81,9 @@ typedef struct VIOsPAPRVLANDevice { VIOsPAPRDevice sdev; NICConf nicconf; NICState *nic; -int isopen; +bool isopen; target_ulong buf_list; -int add_buf_ptr, use_buf_ptr, rx_bufs; +uint32_t add_buf_ptr, use_buf_ptr, rx_bufs; target_ulong rxq_ptr; } VIOsPAPRVLANDevice; @@ -500,6 +500,25 @@ static Property spapr_vlan_properties[] = { DEFINE_PROP_END_OF_LIST(), }; +static const VMStateDescription vmstate_spapr_llan = { +.name = "spapr_llan", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField []) { +VMSTATE_SPAPR_VIO(sdev, VIOsPAPRVLANDevice), +/* LLAN state */ +VMSTATE_BOOL(isopen, VIOsPAPRVLANDevice), +VMSTATE_UINTTL(buf_list, VIOsPAPRVLANDevice), +VMSTATE_UINT32(add_buf_ptr, VIOsPAPRVLANDevice), +VMSTATE_UINT32(use_buf_ptr, VIOsPAPRVLANDevice), +VMSTATE_UINT32(rx_bufs, VIOsPAPRVLANDevice), +VMSTATE_UINTTL(rxq_ptr, VIOsPAPRVLANDevice), + +VMSTATE_END_OF_LIST() +}, +}; + static void spapr_vlan_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -514,6 +533,7 @@ static void spapr_vlan_class_init(ObjectClass *klass, void *data) k->signal_mask = 0x1; dc->props = spapr_vlan_properties; k->rtce_window_size = 0x1000; +dc->vmsd = &vmstate_spapr_llan; } static const TypeInfo spapr_vlan_info = { -- 1.7.10.4
[Qemu-devel] [PATCH 04/17] target-ppc: Convert ppc cpu savevm to VMStateDescription
From: David Gibson The savevm code for the powerpc cpu emulation is currently based around the old register_savevm() rather than register_vmstate() method. It's also rather broken, missing some important state on some CPU models. This patch completely rewrites the savevm for target-ppc, using the new VMStateDescription approach. Exactly what needs to be saved in what configurations has been more carefully examined, too. This introduces a new version (5) of the cpu save format. The old load function is retained to support version 4 images. Signed-off-by: David Gibson [aik: ppc cpu savevm convertion fixed to use PowerPCCPU instead of CPUPPCState] Signed-off-by: Alexey Kardashevskiy --- target-ppc/cpu-qom.h|4 + target-ppc/cpu.h|8 +- target-ppc/machine.c| 533 --- target-ppc/translate_init.c |2 + 4 files changed, 454 insertions(+), 93 deletions(-) diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h index eb03a00..2b96b04 100644 --- a/target-ppc/cpu-qom.h +++ b/target-ppc/cpu-qom.h @@ -102,4 +102,8 @@ PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr); void ppc_cpu_do_interrupt(CPUState *cpu); +#ifndef CONFIG_USER_ONLY +extern const struct VMStateDescription vmstate_ppc_cpu; +#endif + #endif diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 0ede077..f30577d 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -948,7 +948,7 @@ struct CPUPPCState { #if defined(TARGET_PPC64) /* PowerPC 64 SLB area */ ppc_slb_t slb[64]; -int slb_nr; +int32_t slb_nr; #endif /* segment registers */ hwaddr htab_base; @@ -957,11 +957,11 @@ struct CPUPPCState { /* externally stored hash table */ uint8_t *external_htab; /* BATs */ -int nb_BATs; +uint32_t nb_BATs; target_ulong DBAT[2][8]; target_ulong IBAT[2][8]; /* PowerPC TLB registers (for 4xx, e500 and 60x software driven TLBs) */ -int nb_tlb; /* Total number of TLB */ +int32_t nb_tlb; /* Total number of TLB */ int tlb_per_way; /* Speed-up helper: used to avoid divisions at run time */ int nb_ways; /* Number of ways in the TLB set*/ int last_way;/* Last used way used to allocate TLB in a LRU way */ @@ -1176,8 +1176,6 @@ static inline CPUPPCState *cpu_init(const char *cpu_model) #define cpu_signal_handler cpu_ppc_signal_handler #define cpu_list ppc_cpu_list -#define CPU_SAVE_VERSION 4 - /* MMU modes definitions */ #define MMU_MODE0_SUFFIX _user #define MMU_MODE1_SUFFIX _kernel diff --git a/target-ppc/machine.c b/target-ppc/machine.c index 2d10adb..1fcc6bc 100644 --- a/target-ppc/machine.c +++ b/target-ppc/machine.c @@ -1,96 +1,12 @@ #include "hw/hw.h" #include "hw/boards.h" #include "sysemu/kvm.h" +#include "helper_regs.h" -void cpu_save(QEMUFile *f, void *opaque) +static int cpu_load_old(QEMUFile *f, void *opaque, int version_id) { -CPUPPCState *env = (CPUPPCState *)opaque; -unsigned int i, j; -uint32_t fpscr; -target_ulong xer; - -for (i = 0; i < 32; i++) -qemu_put_betls(f, &env->gpr[i]); -#if !defined(TARGET_PPC64) -for (i = 0; i < 32; i++) -qemu_put_betls(f, &env->gprh[i]); -#endif -qemu_put_betls(f, &env->lr); -qemu_put_betls(f, &env->ctr); -for (i = 0; i < 8; i++) -qemu_put_be32s(f, &env->crf[i]); -xer = cpu_read_xer(env); -qemu_put_betls(f, &xer); -qemu_put_betls(f, &env->reserve_addr); -qemu_put_betls(f, &env->msr); -for (i = 0; i < 4; i++) -qemu_put_betls(f, &env->tgpr[i]); -for (i = 0; i < 32; i++) { -union { -float64 d; -uint64_t l; -} u; -u.d = env->fpr[i]; -qemu_put_be64(f, u.l); -} -fpscr = env->fpscr; -qemu_put_be32s(f, &fpscr); -qemu_put_sbe32s(f, &env->access_type); -#if defined(TARGET_PPC64) -qemu_put_betls(f, &env->spr[SPR_ASR]); -qemu_put_sbe32s(f, &env->slb_nr); -#endif -qemu_put_betls(f, &env->spr[SPR_SDR1]); -for (i = 0; i < 32; i++) -qemu_put_betls(f, &env->sr[i]); -for (i = 0; i < 2; i++) -for (j = 0; j < 8; j++) -qemu_put_betls(f, &env->DBAT[i][j]); -for (i = 0; i < 2; i++) -for (j = 0; j < 8; j++) -qemu_put_betls(f, &env->IBAT[i][j]); -qemu_put_sbe32s(f, &env->nb_tlb); -qemu_put_sbe32s(f, &env->tlb_per_way); -qemu_put_sbe32s(f, &env->nb_ways); -qemu_put_sbe32s(f, &env->last_way); -qemu_put_sbe32s(f, &env->id_tlbs); -qemu_put_sbe32s(f, &env->nb_pids); -if (env->tlb.tlb6) { -// XXX assumes 6xx -for (i = 0; i < env->nb_tlb; i++) { -qemu_put_betls(f, &env->tlb.tlb6[i].pte0); -qemu_put_betls(f, &env->tlb.tlb6[i].pte1); -qemu_put_betls(f, &env->tlb.tlb6[i].EPN); -} -} -for (i = 0; i < 4; i++) -qemu_put_betls(
[Qemu-devel] [PATCH 02/17] pseries: rework XICS
Currently XICS interrupt controller is not a QEMU device. As we are going to support in-kernel emulated XICS which is a part of KVM, it make sense not to extend the existing XICS and have multiple KVM stub functions but to create yet another device and share pieces between fully emulated XICS and in-kernel XICS. The rework includes: * port to QOM * made few functions public to use from in-kernel XICS implementation * made VMStateDescription public to be used for in-kernel XICS migration * move xics_system_init() to spapr.c, it tries creating fully-emulated XICS now and will try in-kernel XICS in upcoming patches. Signed-off-by: Alexey Kardashevskiy --- hw/intc/xics.c| 109 ++--- hw/ppc/spapr.c| 28 + include/hw/ppc/xics.h | 59 -- 3 files changed, 141 insertions(+), 55 deletions(-) diff --git a/hw/intc/xics.c b/hw/intc/xics.c index 091912e..0e374c8 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -34,13 +34,6 @@ * ICP: Presentation layer */ -struct icp_server_state { -uint32_t xirr; -uint8_t pending_priority; -uint8_t mfrr; -qemu_irq output; -}; - #define XISR_MASK 0x00ff #define CPPR_MASK 0xff00 @@ -49,12 +42,6 @@ struct icp_server_state { struct ics_state; -struct icp_state { -long nr_servers; -struct icp_server_state *ss; -struct ics_state *ics; -}; - static void ics_reject(struct ics_state *ics, int nr); static void ics_resend(struct ics_state *ics); static void ics_eoi(struct ics_state *ics, int nr); @@ -171,27 +158,6 @@ static void icp_irq(struct icp_state *icp, int server, int nr, uint8_t priority) /* * ICS: Source layer */ - -struct ics_irq_state { -int server; -uint8_t priority; -uint8_t saved_priority; -#define XICS_STATUS_ASSERTED 0x1 -#define XICS_STATUS_SENT 0x2 -#define XICS_STATUS_REJECTED 0x4 -#define XICS_STATUS_MASKED_PENDING 0x8 -uint8_t status; -}; - -struct ics_state { -int nr_irqs; -int offset; -qemu_irq *qirqs; -bool *islsi; -struct ics_irq_state *irqs; -struct icp_state *icp; -}; - static int ics_valid_irq(struct ics_state *ics, uint32_t nr) { return (nr >= ics->offset) @@ -506,9 +472,8 @@ static void rtas_int_on(PowerPCCPU *cpu, sPAPREnvironment *spapr, rtas_st(rets, 0, 0); /* Success */ } -static void xics_reset(void *opaque) +void xics_common_reset(struct icp_state *icp) { -struct icp_state *icp = (struct icp_state *)opaque; struct ics_state *ics = icp->ics; int i; @@ -527,7 +492,12 @@ static void xics_reset(void *opaque) } } -void xics_cpu_setup(struct icp_state *icp, PowerPCCPU *cpu) +static void xics_reset(DeviceState *d) +{ +xics_common_reset(XICS(d)); +} + +void xics_common_cpu_setup(struct icp_state *icp, PowerPCCPU *cpu) { CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; @@ -551,37 +521,72 @@ void xics_cpu_setup(struct icp_state *icp, PowerPCCPU *cpu) } } -struct icp_state *xics_system_init(int nr_servers, int nr_irqs) +void xics_cpu_setup(struct icp_state *icp, PowerPCCPU *cpu) +{ +xics_common_cpu_setup(icp, cpu); +} + +void xics_common_init(struct icp_state *icp, qemu_irq_handler handler) { -struct icp_state *icp; -struct ics_state *ics; +struct ics_state *ics = icp->ics; -icp = g_malloc0(sizeof(*icp)); -icp->nr_servers = nr_servers; icp->ss = g_malloc0(icp->nr_servers*sizeof(struct icp_server_state)); ics = g_malloc0(sizeof(*ics)); -ics->nr_irqs = nr_irqs; +ics->nr_irqs = icp->nr_irqs; ics->offset = XICS_IRQ_BASE; -ics->irqs = g_malloc0(nr_irqs * sizeof(struct ics_irq_state)); -ics->islsi = g_malloc0(nr_irqs * sizeof(bool)); +ics->irqs = g_malloc0(ics->nr_irqs * sizeof(struct ics_irq_state)); +ics->islsi = g_malloc0(ics->nr_irqs * sizeof(bool)); icp->ics = ics; ics->icp = icp; -ics->qirqs = qemu_allocate_irqs(ics_set_irq, ics, nr_irqs); +ics->qirqs = qemu_allocate_irqs(handler, ics, ics->nr_irqs); +} -spapr_register_hypercall(H_CPPR, h_cppr); -spapr_register_hypercall(H_IPI, h_ipi); -spapr_register_hypercall(H_XIRR, h_xirr); -spapr_register_hypercall(H_EOI, h_eoi); +static void xics_realize(DeviceState *dev, Error **errp) +{ +struct icp_state *icp = XICS(dev); + +xics_common_init(icp, ics_set_irq); spapr_rtas_register("ibm,set-xive", rtas_set_xive); spapr_rtas_register("ibm,get-xive", rtas_get_xive); spapr_rtas_register("ibm,int-off", rtas_int_off); spapr_rtas_register("ibm,int-on", rtas_int_on); -qemu_register_reset(xics_reset, icp); +} + +static Property xics_properties[] = { +DEFINE_PROP_UINT32("nr_servers", struct icp_state, nr_servers, -1), +DEFINE_PROP_UINT32("nr_irqs", struct icp_state, nr_irqs, -1), +DEFINE_PROP_END_OF_LIST(), +}; + +static void xics_class_init(ObjectClass *oc, void *data) +{ +
[Qemu-devel] [PATCH 01/17] pseries: move interrupt controllers to hw/intc/
Signed-off-by: Alexey Kardashevskiy --- default-configs/ppc64-softmmu.mak |1 + hw/intc/Makefile.objs |1 + hw/{ppc => intc}/xics.c |0 hw/ppc/Makefile.objs |2 +- 4 files changed, 3 insertions(+), 1 deletion(-) rename hw/{ppc => intc}/xics.c (100%) diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak index cb279cb..69a9f8d 100644 --- a/default-configs/ppc64-softmmu.mak +++ b/default-configs/ppc64-softmmu.mak @@ -47,5 +47,6 @@ CONFIG_E500=y CONFIG_OPENPIC_KVM=$(and $(CONFIG_E500),$(CONFIG_KVM)) # For pSeries CONFIG_PCI_HOTPLUG=y +CONFIG_XICS=$(CONFIG_PSERIES) # For PReP CONFIG_MC146818RTC=y diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs index 2ba49d0..abe8f80 100644 --- a/hw/intc/Makefile.objs +++ b/hw/intc/Makefile.objs @@ -22,3 +22,4 @@ obj-$(CONFIG_OMAP) += omap_intc.o obj-$(CONFIG_OPENPIC) += openpic.o obj-$(CONFIG_OPENPIC_KVM) += openpic_kvm.o obj-$(CONFIG_SH4) += sh_intc.o +obj-$(CONFIG_XICS) += xics.o diff --git a/hw/ppc/xics.c b/hw/intc/xics.c similarity index 100% rename from hw/ppc/xics.c rename to hw/intc/xics.c diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs index be00d1d..7a1cd5d 100644 --- a/hw/ppc/Makefile.objs +++ b/hw/ppc/Makefile.objs @@ -1,7 +1,7 @@ # shared objects obj-y += ppc.o ppc_booke.o # IBM pSeries (sPAPR) -obj-$(CONFIG_PSERIES) += spapr.o xics.o spapr_vio.o spapr_events.o +obj-$(CONFIG_PSERIES) += spapr.o spapr_vio.o spapr_events.o obj-$(CONFIG_PSERIES) += spapr_hcall.o spapr_iommu.o spapr_rtas.o obj-$(CONFIG_PSERIES) += spapr_pci.o # PowerPC 4xx boards -- 1.7.10.4
[Qemu-devel] [PATCH 00/17 v3] spapr: migration, pci, msi, power8
This series spent quite a lot of time waiting when David's PCI series reaches the upstream but it does not seem to happen soon so I rebased those on top of agraf/ppc-next rebased on top qemu.org/master. While this series applies and compiles, the migration will often fail until the "migration: do not sent zero pages in bulk stage" patch is reverted or fixed somehow. Alexey Kardashevskiy (4): pseries: move interrupt controllers to hw/intc/ pseries: rework XICS pseries: rework PAPR virtual SCSI spapr-pci: rework MSI/MSIX David Gibson (12): savevm: Implement VMS_DIVIDE flag target-ppc: Convert ppc cpu savevm to VMStateDescription pseries: savevm support for XICS interrupt controller pseries: savevm support for VIO devices pseries: savevm support for PAPR VIO logical lan pseries: savevm support for PAPR TCE tables pseries: savevm support for PAPR virtual SCSI pseries: savevm support for pseries machine pseries: savevm support for PCI host bridge target-ppc: Add helper for KVM_PPC_RTAS_DEFINE_TOKEN pseries: Support for in-kernel XICS interrupt controller pseries: savevm support with KVM Prerna Saxena (1): ppc64: Enable QEMU to run on POWER 8 DD1 chip. default-configs/ppc64-softmmu.mak |2 + hw/char/spapr_vty.c | 16 ++ hw/intc/Makefile.objs |2 + hw/{ppc => intc}/xics.c | 172 hw/intc/xics_kvm.c| 445 +++ hw/net/spapr_llan.c | 24 +- hw/ppc/Makefile.objs |2 +- hw/ppc/spapr.c| 418 - hw/ppc/spapr_hcall.c |8 +- hw/ppc/spapr_iommu.c | 25 ++ hw/ppc/spapr_pci.c| 141 ++ hw/ppc/spapr_vio.c| 20 ++ hw/scsi/spapr_vscsi.c | 306 ++--- include/hw/pci-host/spapr.h | 14 +- include/hw/ppc/spapr.h| 17 +- include/hw/ppc/spapr_vio.h|5 + include/hw/ppc/xics.h | 72 - include/migration/vmstate.h | 13 + savevm.c |8 + target-ppc/cpu-models.c |3 + target-ppc/cpu-models.h |1 + target-ppc/cpu-qom.h |4 + target-ppc/cpu.h |8 +- target-ppc/kvm.c | 83 ++ target-ppc/kvm_ppc.h | 29 ++ target-ppc/machine.c | 533 +++-- target-ppc/translate_init.c | 36 +++ 27 files changed, 2088 insertions(+), 319 deletions(-) rename hw/{ppc => intc}/xics.c (80%) create mode 100644 hw/intc/xics_kvm.c -- 1.7.10.4
Re: [Qemu-devel] [PATCH v5 05/14] vl: handle "-device dimm"
On 06/26/2013 05:46 PM, Paolo Bonzini wrote: > Il 26/06/2013 11:13, Hu Tao ha scritto: >> From: Vasilis Liaskovitis >> >> Signed-off-by: Vasilis Liaskovitis >> Signed-off-by: Hu Tao >> --- >> vl.c | 51 +++ >> 1 file changed, 51 insertions(+) >> >> diff --git a/vl.c b/vl.c >> index 767e020..9d88a79 100644 >> --- a/vl.c >> +++ b/vl.c >> @@ -170,6 +170,7 @@ int main(int argc, char **argv) >> >> #include "ui/qemu-spice.h" >> #include "qapi/string-input-visitor.h" >> +#include "hw/mem-hotplug/dimm.h" >> >> //#define DEBUG_NET >> //#define DEBUG_SLIRP >> @@ -252,6 +253,7 @@ static QTAILQ_HEAD(, FWBootEntry) fw_boot_order = >> int nb_numa_nodes; >> uint64_t node_mem[MAX_NODES]; >> unsigned long *node_cpumask[MAX_NODES]; >> +int nb_hp_dimms; >> >> uint8_t qemu_uuid[16]; >> >> @@ -2338,6 +2340,50 @@ static int chardev_init_func(QemuOpts *opts, void >> *opaque) >> return 0; >> } >> >> +static int dimmcfg_init_func(QemuOpts *opts, void *opaque) >> +{ >> +const char *driver; >> +const char *id; >> +uint64_t node, size; >> +uint32_t populated; >> +const char *buf, *busbuf; >> + >> +/* DimmDevice configuration needs to be known in order to initialize >> chipset >> + * with correct memory and pci ranges. But all devices are created after >> + * chipset / machine initialization. In * order to avoid this problem, >> we >> + * parse dimm information earlier into dimmcfg structs. */ >> + >> +driver = qemu_opt_get(opts, "driver"); >> +if (!strcmp(driver, "dimm")) { >> + >> +id = qemu_opts_id(opts); >> +buf = qemu_opt_get(opts, "size"); >> +parse_option_size("size", buf, &size, NULL); >> +buf = qemu_opt_get(opts, "node"); >> +parse_option_number("node", buf, &node, NULL); >> +busbuf = qemu_opt_get(opts, "bus"); >> +buf = qemu_opt_get(opts, "populated"); >> +if (!buf) { >> +populated = 0; >> +} else { >> +populated = strcmp(buf, "on") ? 0 : 1; >> +} >> + >> +dimm_config_create((char *)id, size, busbuf ? busbuf : "membus.0", >> + node, nb_hp_dimms); >> + >> +/* if !populated, we just keep the config. The real device >> + * will be created in the future with a normal device_add >> + * command. */ >> +if (!populated) { >> +qemu_opts_del(opts); >> +} > > I think you need another option than -device dimm. For example it could > be declared together with the NUMA node. This could declare two NUMA > nodes, each with 2G of populated and 2G of unpopulated RAM: > >-numa node,mem-range=0-2G,mem-range-hotplug=4G-6G \ >-numa node,mem-range=2G-4G,mem-range-hotplug=6G-8G > > I'm not sure I like the names particularly though. CCing Eduardo, > Bandan and Wanlong Gao. Do we really need to specify the memory range? I suspect that we can follow current design of normal memory in hot-plug memory. Currently, we just specify the size of normal memory in each node, and the range in normal memory is node by node. Then I think we can just specify the memory size of hot-plug in each node, then the hot-plug memory range is also node by node, and the whole hot-plug memory block is just located after the normal memory block. If so, the option can come like: -numa node,nodeid=0,mem=2G,cpus=0-1,mem-hotplug=2G,mem-policy=membind,mem-hostnode=0-1,mem-hotplug-policy=interleave,mem-hotplug-hostnode=1 -numa node,nodeid=1,mem=2G,cpus=2-3,mem-hotplug=2G,mem-policy=preferred,mem-hostnode=1,mem-hotplug-policy=membind,mem-hotplug-hostnode=0-1 And each hot-plug memory device size can be assigned through "-device dimm,size=1G", assume that we specify 4 hot-plug memory devices and each 1G, then first two devices as we ranged belong to node0, and other two belong to node1. Then the hot-plug memory will have no effect on current normal memory design. Thanks, Wanlong Gao > > Paolo > >> +nb_hp_dimms++; >> +} >> + >> +return 0; >> +} >> + >> #ifdef CONFIG_VIRTFS >> static int fsdev_init_func(QemuOpts *opts, void *opaque) >> { >> @@ -4260,6 +4306,11 @@ int main(int argc, char **argv, char **envp) >> } >> qemu_add_globals(); >> >> +/* init generic devices */ >> +if (qemu_opts_foreach(qemu_find_opts("device"), >> + dimmcfg_init_func, NULL, 1) != 0) { >> +exit(1); >> +} >> qdev_machine_init(); >> >> QEMUMachineInitArgs args = { .ram_size = ram_size, >> > >
[Qemu-devel] [PATCH v3 6/7] net: using refcnt to manage NetClientState
With refcnt, NetClientState's user can run against deleter. Signed-off-by: Liu Ping Fan --- hw/core/qdev-properties-system.c | 35 +++ include/net/net.h| 3 +++ net/hub.c| 3 +++ net/net.c| 31 --- net/queue.c | 3 +++ net/slirp.c | 3 ++- 6 files changed, 74 insertions(+), 4 deletions(-) diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c index 0eada32..6632a24 100644 --- a/hw/core/qdev-properties-system.c +++ b/hw/core/qdev-properties-system.c @@ -181,6 +181,7 @@ static int parse_netdev(DeviceState *dev, const char *str, void **ptr) int queues, i = 0; int ret; +/* When return, hold ref for each peer */ queues = qemu_find_net_clients_except(str, peers, NET_CLIENT_OPTIONS_KIND_NIC, MAX_QUEUE_NUM); @@ -236,10 +237,28 @@ static void set_netdev(Object *obj, Visitor *v, void *opaque, set_pointer(obj, v, opaque, parse_netdev, name, errp); } +static void release_netdev(Object *obj, const char *name, void *opaque) +{ +DeviceState *dev = DEVICE(obj); +Property *prop = opaque; +NICPeers *peers_ptr = qdev_get_prop_ptr(dev, prop); +NICConf *conf = container_of(peers_ptr, NICConf, peers); +NetClientState **ptr = peers_ptr->ncs; +int i; + +for (i = 0; i < conf->queues; i++) { +if (ptr[i]) { +netclient_unref(ptr[i]); +ptr[i] = NULL; +} +} +} + PropertyInfo qdev_prop_netdev = { .name = "netdev", .get = get_netdev, .set = set_netdev, +.release = release_netdev, }; /* --- vlan --- */ @@ -302,6 +321,7 @@ static void set_vlan(Object *obj, Visitor *v, void *opaque, return; } +/* inc ref, released when unset property */ hubport = net_hub_port_find(id); if (!hubport) { error_set(errp, QERR_INVALID_PARAMETER_VALUE, @@ -311,11 +331,26 @@ static void set_vlan(Object *obj, Visitor *v, void *opaque, *ptr = hubport; } +static void release_vlan(Object *obj, const char *name, void *opaque) +{ +DeviceState *dev = DEVICE(obj); +Property *prop = opaque; +NICPeers *peers_ptr = qdev_get_prop_ptr(dev, prop); +/* With vlan property, the peers can not have multi-queue */ +NetClientState **ptr = &peers_ptr->ncs[0]; + +if (*ptr) { +netclient_unref(*ptr); +ptr = NULL; +} +} + PropertyInfo qdev_prop_vlan = { .name = "vlan", .print = print_vlan, .get = get_vlan, .set = set_vlan, +.release = release_vlan, }; int qdev_prop_set_drive(DeviceState *dev, const char *name, diff --git a/include/net/net.h b/include/net/net.h index 27aa5cb..9ab1fc7 100644 --- a/include/net/net.h +++ b/include/net/net.h @@ -64,6 +64,7 @@ typedef struct NetClientInfo { } NetClientInfo; struct NetClientState { +int ref; NetClientInfo *info; int link_down; QTAILQ_ENTRY(NetClientState) next; @@ -93,6 +94,8 @@ typedef struct NICState { NetClientState *qemu_find_netdev(const char *id); int qemu_find_net_clients_except(const char *id, NetClientState **ncs, NetClientOptionsKind type, int max); +void netclient_ref(NetClientState *nc); +void netclient_unref(NetClientState *nc); NetClientState *qemu_new_net_client(NetClientInfo *info, NetClientState *peer, const char *model, diff --git a/net/hub.c b/net/hub.c index df32074..9c6c559 100644 --- a/net/hub.c +++ b/net/hub.c @@ -201,6 +201,7 @@ NetClientState *net_hub_find_client_by_name(int hub_id, const char *name) peer = port->nc.peer; if (peer && strcmp(peer->name, name) == 0) { +netclient_ref(peer); return peer; } } @@ -223,6 +224,7 @@ NetClientState *net_hub_port_find(int hub_id) QLIST_FOREACH(port, &hub->ports, next) { nc = port->nc.peer; if (!nc) { +netclient_ref(&port->nc); return &(port->nc); } } @@ -231,6 +233,7 @@ NetClientState *net_hub_port_find(int hub_id) } nc = net_hub_add_port(hub_id, NULL); +netclient_ref(nc); return nc; } diff --git a/net/net.c b/net/net.c index 9f951b8..1ff41a7 100644 --- a/net/net.c +++ b/net/net.c @@ -206,6 +206,11 @@ static void qemu_net_client_setup(NetClientState *nc, assert(!peer->peer); nc->peer = peer; peer->peer = nc; +/* This pair reflects the peers can see each other, they + * will be released together in qemu_net_client_detach_flush. + */ +netclient_ref(peer); +netclient_ref(nc); } qemu_mutex_init(&nc->p
[Qemu-devel] [PATCH v3 7/7] net: hub use lock to protect ports list
Hub ports will run on multi-threads, so use lock to protect them. Signed-off-by: Liu Ping Fan --- net/hub.c | 25 - 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/net/hub.c b/net/hub.c index 9c6c559..2970f8e 100644 --- a/net/hub.c +++ b/net/hub.c @@ -37,6 +37,7 @@ struct NetHub { int id; QLIST_ENTRY(NetHub) next; int num_ports; +QemuMutex ports_lock; QLIST_HEAD(, NetHubPort) ports; }; @@ -47,6 +48,7 @@ static ssize_t net_hub_receive(NetHub *hub, NetHubPort *source_port, { NetHubPort *port; +qemu_mutex_lock(&hub->ports_lock); QLIST_FOREACH(port, &hub->ports, next) { if (port == source_port) { continue; @@ -54,6 +56,7 @@ static ssize_t net_hub_receive(NetHub *hub, NetHubPort *source_port, qemu_send_packet(&port->nc, buf, len); } +qemu_mutex_unlock(&hub->ports_lock); return len; } @@ -63,6 +66,7 @@ static ssize_t net_hub_receive_iov(NetHub *hub, NetHubPort *source_port, NetHubPort *port; ssize_t len = iov_size(iov, iovcnt); +qemu_mutex_lock(&hub->ports_lock); QLIST_FOREACH(port, &hub->ports, next) { if (port == source_port) { continue; @@ -70,6 +74,7 @@ static ssize_t net_hub_receive_iov(NetHub *hub, NetHubPort *source_port, qemu_sendv_packet(&port->nc, iov, iovcnt); } +qemu_mutex_unlock(&hub->ports_lock); return len; } @@ -80,6 +85,7 @@ static NetHub *net_hub_new(int id) hub = g_malloc(sizeof(*hub)); hub->id = id; hub->num_ports = 0; +qemu_mutex_init(&hub->ports_lock); QLIST_INIT(&hub->ports); QLIST_INSERT_HEAD(&hubs, hub, next); @@ -93,16 +99,19 @@ static int net_hub_port_can_receive(NetClientState *nc) NetHubPort *src_port = DO_UPCAST(NetHubPort, nc, nc); NetHub *hub = src_port->hub; +qemu_mutex_lock(&hub->ports_lock); QLIST_FOREACH(port, &hub->ports, next) { if (port == src_port) { continue; } if (qemu_can_send_packet(&port->nc)) { +qemu_mutex_unlock(&hub->ports_lock); return 1; } } +qemu_mutex_unlock(&hub->ports_lock); return 0; } @@ -155,8 +164,9 @@ static NetHubPort *net_hub_port_new(NetHub *hub, const char *name) port = DO_UPCAST(NetHubPort, nc, nc); port->id = id; port->hub = hub; - +qemu_mutex_lock(&hub->ports_lock); QLIST_INSERT_HEAD(&hub->ports, port, next); +qemu_mutex_unlock(&hub->ports_lock); return port; } @@ -197,14 +207,17 @@ NetClientState *net_hub_find_client_by_name(int hub_id, const char *name) QLIST_FOREACH(hub, &hubs, next) { if (hub->id == hub_id) { +qemu_mutex_lock(&hub->ports_lock); QLIST_FOREACH(port, &hub->ports, next) { peer = port->nc.peer; if (peer && strcmp(peer->name, name) == 0) { netclient_ref(peer); +qemu_mutex_unlock(&hub->ports_lock); return peer; } } +qemu_mutex_unlock(&hub->ports_lock); } } return NULL; @@ -221,13 +234,16 @@ NetClientState *net_hub_port_find(int hub_id) QLIST_FOREACH(hub, &hubs, next) { if (hub->id == hub_id) { +qemu_mutex_lock(&hub->ports_lock); QLIST_FOREACH(port, &hub->ports, next) { nc = port->nc.peer; if (!nc) { netclient_ref(&port->nc); +qemu_mutex_unlock(&hub->ports_lock); return &(port->nc); } } +qemu_mutex_unlock(&hub->ports_lock); break; } } @@ -247,12 +263,14 @@ void net_hub_info(Monitor *mon) QLIST_FOREACH(hub, &hubs, next) { monitor_printf(mon, "hub %d\n", hub->id); +qemu_mutex_lock(&hub->ports_lock); QLIST_FOREACH(port, &hub->ports, next) { if (port->nc.peer) { monitor_printf(mon, " \\ "); print_net_client(mon, port->nc.peer); } } +qemu_mutex_unlock(&hub->ports_lock); } } @@ -309,6 +327,7 @@ void net_hub_check_clients(void) QLIST_FOREACH(hub, &hubs, next) { int has_nic = 0, has_host_dev = 0; +qemu_mutex_lock(&hub->ports_lock); QLIST_FOREACH(port, &hub->ports, next) { peer = port->nc.peer; if (!peer) { @@ -331,6 +350,7 @@ void net_hub_check_clients(void) break; } } +qemu_mutex_unlock(&hub->ports_lock); if (has_host_dev && !has_nic) { fprintf(stderr, "Warning: vlan %d with no nics\n", hub->id); } @@ -346,12 +366,15 @@ bool net_hub_flush(NetClientState *nc) { NetHubPort *port; NetHubPort *source_port = DO_UPCAST(NetHubPort, nc, nc); +NetHub *hub = source_port->hub; int ret = 0; +
[Qemu-devel] [PATCH v3 3/7] net: introduce lock to protect NetQueue
NetQueue will be accessed by nc and its peers at the same time, need lock to protect it. Signed-off-by: Liu Ping Fan --- include/net/net.h | 1 + net/queue.c | 13 + 2 files changed, 14 insertions(+) diff --git a/include/net/net.h b/include/net/net.h index 43d85a1..2f72b26 100644 --- a/include/net/net.h +++ b/include/net/net.h @@ -5,6 +5,7 @@ #include "qemu-common.h" #include "qapi/qmp/qdict.h" #include "qemu/option.h" +#include "qemu/thread.h" #include "net/queue.h" #include "migration/vmstate.h" #include "qapi-types.h" diff --git a/net/queue.c b/net/queue.c index d508b7a..26399a1 100644 --- a/net/queue.c +++ b/net/queue.c @@ -56,6 +56,7 @@ struct NetQueue { uint32_t nq_maxlen; uint32_t nq_count; +QemuMutex lock; QTAILQ_HEAD(packets, NetPacket) packets; unsigned delivering : 1; @@ -88,6 +89,7 @@ NetQueue *qemu_new_net_queue(NetClientState *nc) queue->nq_maxlen = 1; queue->nq_count = 0; +qemu_mutex_init(&queue->lock); QTAILQ_INIT(&queue->packets); queue->delivering = 0; @@ -116,7 +118,9 @@ static void qemu_net_queue_append(NetQueue *queue, { NetPacket *packet; +qemu_mutex_lock(&queue->lock); if (queue->nq_count >= queue->nq_maxlen && !sent_cb) { +qemu_mutex_unlock(&queue->lock); return; /* drop if queue full and no callback */ } packet = g_malloc(sizeof(NetPacket) + size); @@ -128,6 +132,7 @@ static void qemu_net_queue_append(NetQueue *queue, queue->nq_count++; QTAILQ_INSERT_TAIL(&queue->packets, packet, entry); +qemu_mutex_unlock(&queue->lock); } static void qemu_net_queue_append_iov(NetQueue *queue, @@ -141,7 +146,9 @@ static void qemu_net_queue_append_iov(NetQueue *queue, size_t max_len = 0; int i; +qemu_mutex_lock(&queue->lock); if (queue->nq_count >= queue->nq_maxlen && !sent_cb) { +qemu_mutex_unlock(&queue->lock); return; /* drop if queue full and no callback */ } for (i = 0; i < iovcnt; i++) { @@ -163,6 +170,7 @@ static void qemu_net_queue_append_iov(NetQueue *queue, queue->nq_count++; QTAILQ_INSERT_TAIL(&queue->packets, packet, entry); +qemu_mutex_unlock(&queue->lock); } static ssize_t qemu_net_queue_deliver(NetQueue *queue, @@ -273,6 +281,7 @@ void qemu_net_queue_purge(NetQueue *queue, NetClientState *from) { NetPacket *packet, *next; +qemu_mutex_lock(&queue->lock); QTAILQ_FOREACH_SAFE(packet, &queue->packets, entry, next) { if (packet->sender == from) { QTAILQ_REMOVE(&queue->packets, packet, entry); @@ -280,10 +289,12 @@ void qemu_net_queue_purge(NetQueue *queue, NetClientState *from) g_free(packet); } } +qemu_mutex_unlock(&queue->lock); } bool qemu_net_queue_flush(NetQueue *queue) { +qemu_mutex_lock(&queue->lock); while (!QTAILQ_EMPTY(&queue->packets)) { NetPacket *packet; int ret; @@ -300,6 +311,7 @@ bool qemu_net_queue_flush(NetQueue *queue) if (ret == 0) { queue->nq_count++; QTAILQ_INSERT_HEAD(&queue->packets, packet, entry); +qemu_mutex_unlock(&queue->lock); return false; } @@ -309,5 +321,6 @@ bool qemu_net_queue_flush(NetQueue *queue) g_free(packet); } +qemu_mutex_unlock(&queue->lock); return true; } -- 1.8.1.4
[Qemu-devel] [PATCH v3 4/7] net: introduce lock to protect NetClientState's peer's access
Introduce nc->peer_lock to shield off the race of nc->peer's reader and deleter. With it, after deleter finish, no new qemu_send_packet_xx() will append packet to peer->send_queue, therefore no new reference from packet->sender to nc will exist in nc->peer->send_queue. The lock sequence: peer_lock then NetQueue->lock inside. Signed-off-by: Liu Ping Fan --- include/net/net.h | 7 ++ net/net.c | 64 +++ 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/include/net/net.h b/include/net/net.h index 2f72b26..27aa5cb 100644 --- a/include/net/net.h +++ b/include/net/net.h @@ -67,6 +67,11 @@ struct NetClientState { NetClientInfo *info; int link_down; QTAILQ_ENTRY(NetClientState) next; +/* protect the race access of peer only between reader and writer. + * to resolve the writer's race condition, resort on biglock. + * Lock sequence: holding peer_lock outside, then NetQueue->lock inside. + */ +QemuMutex peer_lock; NetClientState *peer; NetQueue *send_queue; char *model; @@ -79,6 +84,7 @@ struct NetClientState { typedef struct NICState { NetClientState *ncs; +NetClientState **pending_peer; NICConf *conf; void *opaque; bool peer_deleted; @@ -106,6 +112,7 @@ NetClientState *qemu_find_vlan_client_by_name(Monitor *mon, int vlan_id, const char *client_str); typedef void (*qemu_nic_foreach)(NICState *nic, void *opaque); void qemu_foreach_nic(qemu_nic_foreach func, void *opaque); +int qemu_can_send_packet_nolock(NetClientState *sender); int qemu_can_send_packet(NetClientState *nc); ssize_t qemu_sendv_packet(NetClientState *nc, const struct iovec *iov, int iovcnt); diff --git a/net/net.c b/net/net.c index 43a74e4..6fc50d8 100644 --- a/net/net.c +++ b/net/net.c @@ -204,6 +204,7 @@ static void qemu_net_client_setup(NetClientState *nc, nc->peer = peer; peer->peer = nc; } +qemu_mutex_init(&nc->peer_lock); QTAILQ_INSERT_TAIL(&net_clients, nc, next); nc->send_queue = qemu_new_net_queue(nc); @@ -243,6 +244,7 @@ NICState *qemu_new_nic(NetClientInfo *info, nic->ncs = (void *)nic + info->size; nic->conf = conf; nic->opaque = opaque; +nic->pending_peer = g_malloc0(sizeof(NetClientState *) * queues); for (i = 0; i < queues; i++) { qemu_net_client_setup(&nic->ncs[i], info, peers[i], model, name, @@ -301,6 +303,35 @@ static void qemu_free_net_client(NetClientState *nc) } } +/* Elimate the reference and sync with exit of rx/tx action. + * And flush out peer's queue. + */ +static void qemu_net_client_detach_flush(NetClientState *nc) +{ +NetClientState *peer; + +qemu_mutex_lock(&nc->peer_lock); +peer = nc->peer; +qemu_mutex_unlock(&nc->peer_lock); + +/* writer of peer's peer field*/ +if (peer) { +/* exclude the race with tx to @nc */ +qemu_mutex_lock(&peer->peer_lock); +peer->peer = NULL; +qemu_mutex_unlock(&peer->peer_lock); +} + +/* writer of self's peer field*/ +/* exclude the race with tx from @nc */ +qemu_mutex_lock(&nc->peer_lock); +nc->peer = NULL; +if (peer) { +qemu_net_queue_purge(peer->send_queue, nc); +} +qemu_mutex_unlock(&nc->peer_lock); +} + void qemu_del_net_client(NetClientState *nc) { NetClientState *ncs[MAX_QUEUE_NUM]; @@ -331,7 +362,9 @@ void qemu_del_net_client(NetClientState *nc) } for (i = 0; i < queues; i++) { +qemu_net_client_detach_flush(ncs[i]); qemu_cleanup_net_client(ncs[i]); +nic->pending_peer[i] = ncs[i]; } return; @@ -340,6 +373,7 @@ void qemu_del_net_client(NetClientState *nc) assert(nc->info->type != NET_CLIENT_OPTIONS_KIND_NIC); for (i = 0; i < queues; i++) { +qemu_net_client_detach_flush(ncs[i]); qemu_cleanup_net_client(ncs[i]); qemu_free_net_client(ncs[i]); } @@ -352,17 +386,19 @@ void qemu_del_nic(NICState *nic) /* If this is a peer NIC and peer has already been deleted, free it now. */ if (nic->peer_deleted) { for (i = 0; i < queues; i++) { -qemu_free_net_client(qemu_get_subqueue(nic, i)->peer); +qemu_free_net_client(nic->pending_peer[i]); } } for (i = queues - 1; i >= 0; i--) { NetClientState *nc = qemu_get_subqueue(nic, i); +qemu_net_client_detach_flush(nc); qemu_cleanup_net_client(nc); qemu_free_net_client(nc); } +g_free(nic->pending_peer); g_free(nic); } @@ -379,7 +415,7 @@ void qemu_foreach_nic(qemu_nic_foreach func, void *opaque) } } -int qemu_can_send_packet(NetClientState *sender) +int qemu_can_send_packet_nolock(NetClientState *sender) { if (!sender->peer) { return 1; @@ -394,6 +430,16 @@ int qemu_can_send_packet(NetClien
[Qemu-devel] [PATCH v3 5/7] net: introduce lock to protect net clients
Signed-off-by: Liu Ping Fan --- net/net.c | 20 1 file changed, 20 insertions(+) diff --git a/net/net.c b/net/net.c index 6fc50d8..9f951b8 100644 --- a/net/net.c +++ b/net/net.c @@ -45,6 +45,7 @@ # define CONFIG_NET_BRIDGE #endif +static QemuMutex net_clients_lock; static QTAILQ_HEAD(, NetClientState) net_clients; int default_net = 1; @@ -165,6 +166,7 @@ static char *assign_name(NetClientState *nc1, const char *model) char buf[256]; int id = 0; +qemu_mutex_lock(&net_clients_lock); QTAILQ_FOREACH(nc, &net_clients, next) { if (nc == nc1) { continue; @@ -173,6 +175,7 @@ static char *assign_name(NetClientState *nc1, const char *model) id++; } } +qemu_mutex_unlock(&net_clients_lock); snprintf(buf, sizeof(buf), "%s.%d", model, id); @@ -205,7 +208,9 @@ static void qemu_net_client_setup(NetClientState *nc, peer->peer = nc; } qemu_mutex_init(&nc->peer_lock); +qemu_mutex_lock(&net_clients_lock); QTAILQ_INSERT_TAIL(&net_clients, nc, next); +qemu_mutex_unlock(&net_clients_lock); nc->send_queue = qemu_new_net_queue(nc); nc->destructor = destructor; @@ -281,7 +286,9 @@ void *qemu_get_nic_opaque(NetClientState *nc) static void qemu_cleanup_net_client(NetClientState *nc) { +qemu_mutex_lock(&net_clients_lock); QTAILQ_REMOVE(&net_clients, nc, next); +qemu_mutex_unlock(&net_clients_lock); if (nc->info->cleanup) { nc->info->cleanup(nc); @@ -406,6 +413,7 @@ void qemu_foreach_nic(qemu_nic_foreach func, void *opaque) { NetClientState *nc; +qemu_mutex_lock(&net_clients_lock); QTAILQ_FOREACH(nc, &net_clients, next) { if (nc->info->type == NET_CLIENT_OPTIONS_KIND_NIC) { if (nc->queue_index == 0) { @@ -413,6 +421,7 @@ void qemu_foreach_nic(qemu_nic_foreach func, void *opaque) } } } +qemu_mutex_unlock(&net_clients_lock); } int qemu_can_send_packet_nolock(NetClientState *sender) @@ -615,13 +624,16 @@ NetClientState *qemu_find_netdev(const char *id) { NetClientState *nc; +qemu_mutex_lock(&net_clients_lock); QTAILQ_FOREACH(nc, &net_clients, next) { if (nc->info->type == NET_CLIENT_OPTIONS_KIND_NIC) continue; if (!strcmp(nc->name, id)) { +qemu_mutex_unlock(&net_clients_lock); return nc; } } +qemu_mutex_unlock(&net_clients_lock); return NULL; } @@ -632,6 +644,7 @@ int qemu_find_net_clients_except(const char *id, NetClientState **ncs, NetClientState *nc; int ret = 0; +qemu_mutex_lock(&net_clients_lock); QTAILQ_FOREACH(nc, &net_clients, next) { if (nc->info->type == type) { continue; @@ -643,6 +656,7 @@ int qemu_find_net_clients_except(const char *id, NetClientState **ncs, ret++; } } +qemu_mutex_unlock(&net_clients_lock); return ret; } @@ -1024,6 +1038,7 @@ void do_info_network(Monitor *mon, const QDict *qdict) net_hub_info(mon); +qemu_mutex_lock(&net_clients_lock); QTAILQ_FOREACH(nc, &net_clients, next) { peer = nc->peer; type = nc->info->type; @@ -1041,6 +1056,7 @@ void do_info_network(Monitor *mon, const QDict *qdict) print_net_client(mon, peer); } } +qemu_mutex_unlock(&net_clients_lock); } void qmp_set_link(const char *name, bool up, Error **errp) @@ -1094,6 +1110,7 @@ void net_cleanup(void) qemu_del_net_client(nc); } } +qemu_mutex_destroy(&net_clients_lock); } void net_check_clients(void) @@ -1115,6 +1132,7 @@ void net_check_clients(void) net_hub_check_clients(); +qemu_mutex_lock(&net_clients_lock); QTAILQ_FOREACH(nc, &net_clients, next) { if (!nc->peer) { fprintf(stderr, "Warning: %s %s has no peer\n", @@ -1122,6 +1140,7 @@ void net_check_clients(void) "nic" : "netdev", nc->name); } } +qemu_mutex_unlock(&net_clients_lock); /* Check that all NICs requested via -net nic actually got created. * NICs created via -device don't need to be checked here because @@ -1179,6 +1198,7 @@ int net_init_clients(void) #endif } +qemu_mutex_init(&net_clients_lock); QTAILQ_INIT(&net_clients); if (qemu_opts_foreach(qemu_find_opts("netdev"), net_init_netdev, NULL, 1) == -1) -- 1.8.1.4
[Qemu-devel] [PATCH v3 1/7] net: force NetQue opaque to be NetClientState
qemu_net_client_setup() is the only user of qemu_new_net_queue(), which will pass in NetClientState. By forcing it be a NetClientState, we can ref/unref NetQueue's owner Signed-off-by: Liu Ping Fan --- include/net/queue.h | 2 +- net/queue.c | 10 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/net/queue.h b/include/net/queue.h index fc02b33..1d9e4c3 100644 --- a/include/net/queue.h +++ b/include/net/queue.h @@ -34,7 +34,7 @@ typedef void (NetPacketSent) (NetClientState *sender, ssize_t ret); #define QEMU_NET_PACKET_FLAG_NONE 0 #define QEMU_NET_PACKET_FLAG_RAW (1<<0) -NetQueue *qemu_new_net_queue(void *opaque); +NetQueue *qemu_new_net_queue(NetClientState *nc); void qemu_del_net_queue(NetQueue *queue); diff --git a/net/queue.c b/net/queue.c index 859d02a..1937345 100644 --- a/net/queue.c +++ b/net/queue.c @@ -49,7 +49,7 @@ struct NetPacket { }; struct NetQueue { -void *opaque; +NetClientState *nc; uint32_t nq_maxlen; uint32_t nq_count; @@ -58,13 +58,13 @@ struct NetQueue { unsigned delivering : 1; }; -NetQueue *qemu_new_net_queue(void *opaque) +NetQueue *qemu_new_net_queue(NetClientState *nc) { NetQueue *queue; queue = g_malloc0(sizeof(NetQueue)); -queue->opaque = opaque; +queue->nc = nc; queue->nq_maxlen = 1; queue->nq_count = 0; @@ -154,7 +154,7 @@ static ssize_t qemu_net_queue_deliver(NetQueue *queue, ssize_t ret = -1; queue->delivering = 1; -ret = qemu_deliver_packet(sender, flags, data, size, queue->opaque); +ret = qemu_deliver_packet(sender, flags, data, size, queue->nc); queue->delivering = 0; return ret; @@ -169,7 +169,7 @@ static ssize_t qemu_net_queue_deliver_iov(NetQueue *queue, ssize_t ret = -1; queue->delivering = 1; -ret = qemu_deliver_packet_iov(sender, flags, iov, iovcnt, queue->opaque); +ret = qemu_deliver_packet_iov(sender, flags, iov, iovcnt, queue->nc); queue->delivering = 0; return ret; -- 1.8.1.4
[Qemu-devel] [PATCH v3 2/7] net: distinguish & defer nested call to BH
When network layer can run on multi-thread, nested call caused by nc->receive() will raise issue like deadlock. So postpone it to BH. We distinguish nested call "A->B->A" from parallel call "A->B, B->A" by using tls variable net_enter. Here A, B stands for a NetClientState. Signed-off-by: Liu Ping Fan --- net/queue.c | 48 ++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/net/queue.c b/net/queue.c index 1937345..d508b7a 100644 --- a/net/queue.c +++ b/net/queue.c @@ -24,6 +24,9 @@ #include "net/queue.h" #include "qemu/queue.h" #include "net/net.h" +#include "block/aio.h" +#include "qemu/main-loop.h" +#include "qemu/tls.h" /* The delivery handler may only return zero if it will call * qemu_net_queue_flush() when it determines that it is once again able @@ -58,6 +61,23 @@ struct NetQueue { unsigned delivering : 1; }; +typedef struct NetQueueBH { +QEMUBH *bh; +NetClientState *nc; +} NetQueueBH; + +static void qemu_net_queue_send_bh(void *opaque) +{ +NetQueueBH *q_bh = opaque; +NetQueue *queue = q_bh->nc->send_queue; + +qemu_net_queue_flush(queue); +qemu_bh_delete(q_bh->bh); +g_slice_free(NetQueueBH, q_bh); +} + +DEFINE_TLS(int, net_enter) = 0; + NetQueue *qemu_new_net_queue(NetClientState *nc) { NetQueue *queue; @@ -183,9 +203,20 @@ ssize_t qemu_net_queue_send(NetQueue *queue, NetPacketSent *sent_cb) { ssize_t ret; +int reenter; -if (queue->delivering || !qemu_can_send_packet(sender)) { +reenter = ++tls_var(net_enter); +assert(reenter <= 2); +if (queue->delivering || !qemu_can_send_packet(sender) || +reenter == 2) { qemu_net_queue_append(queue, sender, flags, data, size, sent_cb); +if (reenter == 2) { +NetQueueBH *que_bh = g_slice_new(NetQueueBH); +que_bh->bh = qemu_bh_new(qemu_net_queue_send_bh, que_bh); +que_bh->nc = queue->nc; +qemu_bh_schedule(que_bh->bh); + --tls_var(net_enter); +} return 0; } @@ -196,6 +227,7 @@ ssize_t qemu_net_queue_send(NetQueue *queue, } qemu_net_queue_flush(queue); + --tls_var(net_enter); return ret; } @@ -208,9 +240,20 @@ ssize_t qemu_net_queue_send_iov(NetQueue *queue, NetPacketSent *sent_cb) { ssize_t ret; +int reenter; -if (queue->delivering || !qemu_can_send_packet(sender)) { +reenter = ++tls_var(net_enter); +assert(reenter <= 2); +if (queue->delivering || !qemu_can_send_packet(sender) || +reenter == 2) { qemu_net_queue_append_iov(queue, sender, flags, iov, iovcnt, sent_cb); +if (reenter == 2) { +NetQueueBH *que_bh = g_slice_new(NetQueueBH); +que_bh->bh = qemu_bh_new(qemu_net_queue_send_bh, que_bh); +que_bh->nc = queue->nc; +qemu_bh_schedule(que_bh->bh); + --tls_var(net_enter); +} return 0; } @@ -221,6 +264,7 @@ ssize_t qemu_net_queue_send_iov(NetQueue *queue, } qemu_net_queue_flush(queue); +--tls_var(net_enter); return ret; } -- 1.8.1.4
[Qemu-devel] [PATCH v3 0/7] port network layer onto glib
This series only resolve the net core re-entrant problem. And defer the patches about glib to future. v2->v3: fix netlayer reenter detection by tls fix netdev property' nc reference problem v1->v2: introduce netqueue re-entrant detection and defer it to BH Liu Ping Fan (7): net: force NetQue opaque to be NetClientState net: distinguish & defer nested call to BH net: introduce lock to protect NetQueue net: introduce lock to protect NetClientState's peer's access net: introduce lock to protect net clients net: using refcnt to manage NetClientState net: hub use lock to protect ports list hw/core/qdev-properties-system.c | 35 include/net/net.h| 11 include/net/queue.h | 2 +- net/hub.c| 28 +- net/net.c| 113 --- net/queue.c | 74 ++--- net/slirp.c | 3 +- 7 files changed, 250 insertions(+), 16 deletions(-) -- 1.8.1.4
[Qemu-devel] [PATCH V3 6/7] monitor: improve "help" in auto completion for sub command
Now special case "help *" in auto completion can work with sub commands, such as "help info a*". Signed-off-by: Wenchao Xia --- monitor.c |6 ++ 1 files changed, 2 insertions(+), 4 deletions(-) diff --git a/monitor.c b/monitor.c index e0a4b67..1126540 100644 --- a/monitor.c +++ b/monitor.c @@ -4283,10 +4283,8 @@ static void monitor_find_completion_by_table(Monitor *mon, cmd_completion(mon, str, QKeyCode_lookup[i]); } } else if (!strcmp(cmd->name, "help|?")) { -readline_set_completion_index(mon->rs, strlen(str)); -for (cmd = mon->cmd_table; cmd->name != NULL; cmd++) { -cmd_completion(mon, str, cmd->name); -} +monitor_find_completion_by_table(mon, cmd_table, + args_cmdline[1]); } break; default: -- 1.7.1
[Qemu-devel] [PATCH V3 4/7] monitor: code move for parse_cmdline()
Also fix code style error reported by check script. Signed-off-by: Wenchao Xia --- monitor.c | 186 +++-- 1 files changed, 94 insertions(+), 92 deletions(-) diff --git a/monitor.c b/monitor.c index 54fc36f..aa641de 100644 --- a/monitor.c +++ b/monitor.c @@ -733,10 +733,103 @@ static int compare_cmd(const char *name, const char *list) return 0; } +static int get_str(char *buf, int buf_size, const char **pp) +{ +const char *p; +char *q; +int c; + +q = buf; +p = *pp; +while (qemu_isspace(*p)) { +p++; +} +if (*p == '\0') { +fail: +*q = '\0'; +*pp = p; +return -1; +} +if (*p == '\"') { +p++; +while (*p != '\0' && *p != '\"') { +if (*p == '\\') { +p++; +c = *p++; +switch (c) { +case 'n': +c = '\n'; +break; +case 'r': +c = '\r'; +break; +case '\\': +case '\'': +case '\"': +break; +default: +qemu_printf("unsupported escape code: '\\%c'\n", c); +goto fail; +} +if ((q - buf) < buf_size - 1) { +*q++ = c; +} +} else { +if ((q - buf) < buf_size - 1) { +*q++ = *p; +} +p++; +} +} +if (*p != '\"') { +qemu_printf("unterminated string\n"); +goto fail; +} +p++; +} else { +while (*p != '\0' && !qemu_isspace(*p)) { +if ((q - buf) < buf_size - 1) { +*q++ = *p; +} +p++; +} +} +*q = '\0'; +*pp = p; +return 0; +} + #define MAX_ARGS 16 +/* NOTE: this parser is an approximate form of the real command parser */ static void parse_cmdline(const char *cmdline, - int *pnb_args, char **args); + int *pnb_args, char **args) +{ +const char *p; +int nb_args, ret; +char buf[1024]; + +p = cmdline; +nb_args = 0; +for (;;) { +while (qemu_isspace(*p)) { +p++; +} +if (*p == '\0') { +break; +} +if (nb_args >= MAX_ARGS) { +break; +} +ret = get_str(buf, sizeof(buf), &p); +args[nb_args] = g_strdup(buf); +nb_args++; +if (ret < 0) { +break; +} +} +*pnb_args = nb_args; +} static void help_cmd_dump_one(Monitor *mon, const mon_cmd_t *cmd, @@ -3459,71 +3552,6 @@ static int get_double(Monitor *mon, double *pval, const char **pp) return 0; } -static int get_str(char *buf, int buf_size, const char **pp) -{ -const char *p; -char *q; -int c; - -q = buf; -p = *pp; -while (qemu_isspace(*p)) -p++; -if (*p == '\0') { -fail: -*q = '\0'; -*pp = p; -return -1; -} -if (*p == '\"') { -p++; -while (*p != '\0' && *p != '\"') { -if (*p == '\\') { -p++; -c = *p++; -switch(c) { -case 'n': -c = '\n'; -break; -case 'r': -c = '\r'; -break; -case '\\': -case '\'': -case '\"': -break; -default: -qemu_printf("unsupported escape code: '\\%c'\n", c); -goto fail; -} -if ((q - buf) < buf_size - 1) { -*q++ = c; -} -} else { -if ((q - buf) < buf_size - 1) { -*q++ = *p; -} -p++; -} -} -if (*p != '\"') { -qemu_printf("unterminated string\n"); -goto fail; -} -p++; -} else { -while (*p != '\0' && !qemu_isspace(*p)) { -if ((q - buf) < buf_size - 1) { -*q++ = *p; -} -p++; -} -} -*q = '\0'; -*pp = p; -return 0; -} - /* * Store the command-name in cmdname, and return a pointer to * the remaining of the command string. @@ -4145,32 +4173,6 @@ static void block_completion_it(void *opaque, BlockDriverState *bs) } } -/* NOTE: this parser is an approximate form of the real command parser */ -static void parse_cmdline(const char *cmdline, - int *pnb_args, char **args) -{ -const char *p; -int nb_args, ret; -char buf[1024]; - -p = cmdline; -nb_args = 0; -for(;;) {
[Qemu-devel] [PATCH V3 7/7] monitor: improve "help" to allow show tip of single command in sub group
A new parameter type 'S' is introduced to allow user input any string. "help info block" do not tip extra parameter error now. Signed-off-by: Wenchao Xia --- hmp-commands.hx |2 +- monitor.c | 30 +- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/hmp-commands.hx b/hmp-commands.hx index 915b0d1..8cf5f29 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -11,7 +11,7 @@ ETEXI { .name = "help|?", -.args_type = "name:s?", +.args_type = "name:S?", .params = "[cmd]", .help = "show the help", .mhandler.cmd = do_help_cmd, diff --git a/monitor.c b/monitor.c index 1126540..480f6a4 100644 --- a/monitor.c +++ b/monitor.c @@ -83,6 +83,7 @@ * 'F' filename * 'B' block device name * 's' string (accept optional quote) + * 'S' supported types, can be any string (accept optional quote) * 'O' option string of the form NAME=VALUE,... * parsed according to QemuOptsList given by its name * Example: 'device:O' uses qemu_device_opts. @@ -4011,6 +4012,31 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon, } } break; +case 'S': +{ +/* package all remaining string */ +int len; + +while (qemu_isspace(*p)) { +p++; +} +if (*typestr == '?') { +typestr++; +if (*p == '\0') { +/* no remaining string: NULL argument */ +break; +} +} +len = strlen(p); +if (len <= 0) { +monitor_printf(mon, "%s: string expected\n", + cmdname); +break; +} +qdict_put(qdict, key, qstring_from_str(p)); +p += len; +} +break; default: bad_type: monitor_printf(mon, "%s: unknown type '%c'\n", cmdname, c); @@ -4282,7 +4308,9 @@ static void monitor_find_completion_by_table(Monitor *mon, for (i = 0; i < Q_KEY_CODE_MAX; i++) { cmd_completion(mon, str, QKeyCode_lookup[i]); } -} else if (!strcmp(cmd->name, "help|?")) { +} +case 'S': +if (!strcmp(cmd->name, "help|?")) { monitor_find_completion_by_table(mon, cmd_table, args_cmdline[1]); } -- 1.7.1
[Qemu-devel] [PATCH V3 3/7] monitor: discard global variable *info_cmds in help functions
In help functions info_cmds is treated as sub command group now, not as a special case any more. Still help can't show message for single command under "info", since command parser reject additional parameter, which can be improved by change "help" item parameter define later. "log" is still treated as special help case. compare_cmd() is used instead of strcmp() in command searching. To tip better what the patch does, code moving is avoided by declare parse_cmdline() ahead. Signed-off-by: Wenchao Xia --- monitor.c | 67 +++-- 1 files changed, 56 insertions(+), 11 deletions(-) diff --git a/monitor.c b/monitor.c index 528e4a8..54fc36f 100644 --- a/monitor.c +++ b/monitor.c @@ -733,33 +733,80 @@ static int compare_cmd(const char *name, const char *list) return 0; } +#define MAX_ARGS 16 + +static void parse_cmdline(const char *cmdline, + int *pnb_args, char **args); + +static void help_cmd_dump_one(Monitor *mon, + const mon_cmd_t *cmd, + char **prefix_args, + int prefix_args_nb) +{ +int i; + +for (i = 0; i < prefix_args_nb; i++) { +monitor_printf(mon, "%s ", prefix_args[i]); +} +monitor_printf(mon, "%s %s -- %s\n", cmd->name, cmd->params, cmd->help); +} + static void help_cmd_dump(Monitor *mon, const mon_cmd_t *cmds, - const char *prefix, const char *name) + char **args, int nb_args, int arg_index) { const mon_cmd_t *cmd; +/* Dump all */ +if (arg_index >= nb_args) { +for (cmd = cmds; cmd->name != NULL; cmd++) { +help_cmd_dump_one(mon, cmd, args, arg_index); +} +return; +} + +/* Find one entry to dump */ for(cmd = cmds; cmd->name != NULL; cmd++) { -if (!name || !strcmp(name, cmd->name)) -monitor_printf(mon, "%s%s %s -- %s\n", prefix, cmd->name, - cmd->params, cmd->help); +if (compare_cmd(args[arg_index], cmd->name)) { +if (cmd->sub_table) { +help_cmd_dump(mon, cmd->sub_table, + args, nb_args, arg_index + 1); +} else { +help_cmd_dump_one(mon, cmd, args, arg_index); +} +break; +} } } static void help_cmd(Monitor *mon, const char *name) { -if (name && !strcmp(name, "info")) { -help_cmd_dump(mon, info_cmds, "info ", NULL); -} else { -help_cmd_dump(mon, mon->cmd_table, "", name); -if (name && !strcmp(name, "log")) { +char *args[MAX_ARGS]; +int nb_args = 0, i; + +if (name) { +/* special case for log */ +if (!strcmp(name, "log")) { const QEMULogItem *item; monitor_printf(mon, "Log items (comma separated):\n"); monitor_printf(mon, "%-10s %s\n", "none", "remove all logs"); for (item = qemu_log_items; item->mask != 0; item++) { monitor_printf(mon, "%-10s %s\n", item->name, item->help); } +return; +} + +parse_cmdline(name, &nb_args, args); +if (nb_args >= MAX_ARGS) { +goto cleanup; } } + +help_cmd_dump(mon, mon->cmd_table, args, nb_args, 0); + +cleanup: +for (i = 0; i < nb_args; i++) { +g_free(args[i]); +} } static void do_help_cmd(Monitor *mon, const QDict *qdict) @@ -3533,8 +3580,6 @@ static char *key_get_info(const char *type, char **key) static int default_fmt_format = 'x'; static int default_fmt_size = 4; -#define MAX_ARGS 16 - static int is_valid_option(const char *c, const char *typestr) { char option[3]; -- 1.7.1
[Qemu-devel] [PATCH V3 2/7] monitor: discard global variable *mon_cmds
New member *cmd_table is added in structure Monitor to avoid direct usage of *mon_cmds. Now monitor have an associated command table, when global variable *info_cmds is also discarded, structure Monitor would gain full control about how to deal with user input. Signed-off-by: Wenchao Xia --- monitor.c | 14 +- 1 files changed, 9 insertions(+), 5 deletions(-) diff --git a/monitor.c b/monitor.c index f3fdaa4..528e4a8 100644 --- a/monitor.c +++ b/monitor.c @@ -194,6 +194,7 @@ struct Monitor { CPUArchState *mon_cpu; BlockDriverCompletionFunc *password_completion_cb; void *password_opaque; +mon_cmd_t *cmd_table; QError *error; QLIST_HEAD(,mon_fd_t) fds; QLIST_ENTRY(Monitor) entry; @@ -749,7 +750,7 @@ static void help_cmd(Monitor *mon, const char *name) if (name && !strcmp(name, "info")) { help_cmd_dump(mon, info_cmds, "info ", NULL); } else { -help_cmd_dump(mon, mon_cmds, "", name); +help_cmd_dump(mon, mon->cmd_table, "", name); if (name && !strcmp(name, "log")) { const QEMULogItem *item; monitor_printf(mon, "Log items (comma separated):\n"); @@ -3975,7 +3976,7 @@ static void handle_user_command(Monitor *mon, const char *cmdline) qdict = qdict_new(); -cmd = monitor_parse_command(mon, cmdline, 0, mon_cmds, qdict); +cmd = monitor_parse_command(mon, cmdline, 0, mon->cmd_table, qdict); if (!cmd) goto out; @@ -4164,12 +4165,12 @@ static void monitor_find_completion(Monitor *mon, else cmdname = args[0]; readline_set_completion_index(mon->rs, strlen(cmdname)); -for(cmd = mon_cmds; cmd->name != NULL; cmd++) { +for (cmd = mon->cmd_table; cmd->name != NULL; cmd++) { cmd_completion(mon, cmdname, cmd->name); } } else { /* find the command */ -for (cmd = mon_cmds; cmd->name != NULL; cmd++) { +for (cmd = mon->cmd_table; cmd->name != NULL; cmd++) { if (compare_cmd(args[0], cmd->name)) { break; } @@ -4220,7 +4221,7 @@ static void monitor_find_completion(Monitor *mon, } } else if (!strcmp(cmd->name, "help|?")) { readline_set_completion_index(mon->rs, strlen(str)); -for (cmd = mon_cmds; cmd->name != NULL; cmd++) { +for (cmd = mon->cmd_table; cmd->name != NULL; cmd++) { cmd_completion(mon, str, cmd->name); } } @@ -4783,6 +4784,9 @@ void monitor_init(CharDriverState *chr, int flags) if (!default_mon || (flags & MONITOR_IS_DEFAULT)) default_mon = mon; +/* Always use *mon_cmds as root command table now. */ +mon->cmd_table = mon_cmds; + sortcmdlist(); } -- 1.7.1
[Qemu-devel] [PATCH V3 1/7] monitor: discard global variable *cur_mon in completion functions
Parameter *mon is added to replace *cur_mon, and readline_completion() pass rs->mon as value, which should be initialized in readline_init() called by monitor_init(). In short, structure ReadLineState controls where the action would be taken now. Signed-off-by: Wenchao Xia --- include/monitor/readline.h |3 +- monitor.c | 53 ++- readline.c |5 +-- 3 files changed, 36 insertions(+), 25 deletions(-) diff --git a/include/monitor/readline.h b/include/monitor/readline.h index fc9806e..0faf6e1 100644 --- a/include/monitor/readline.h +++ b/include/monitor/readline.h @@ -8,7 +8,8 @@ #define READLINE_MAX_COMPLETIONS 256 typedef void ReadLineFunc(Monitor *mon, const char *str, void *opaque); -typedef void ReadLineCompletionFunc(const char *cmdline); +typedef void ReadLineCompletionFunc(Monitor *mon, +const char *cmdline); typedef struct ReadLineState { char cmd_buf[READLINE_CMD_BUF_SIZE + 1]; diff --git a/monitor.c b/monitor.c index 70ae8f5..f3fdaa4 100644 --- a/monitor.c +++ b/monitor.c @@ -3999,7 +3999,7 @@ out: QDECREF(qdict); } -static void cmd_completion(const char *name, const char *list) +static void cmd_completion(Monitor *mon, const char *name, const char *list) { const char *p, *pstart; char cmd[128]; @@ -4017,7 +4017,7 @@ static void cmd_completion(const char *name, const char *list) memcpy(cmd, pstart, len); cmd[len] = '\0'; if (name[0] == '\0' || !strncmp(name, cmd, strlen(name))) { -readline_add_completion(cur_mon->rs, cmd); +readline_add_completion(mon->rs, cmd); } if (*p == '\0') break; @@ -4025,7 +4025,7 @@ static void cmd_completion(const char *name, const char *list) } } -static void file_completion(const char *input) +static void file_completion(Monitor *mon, const char *input) { DIR *ffs; struct dirent *d; @@ -4048,7 +4048,7 @@ static void file_completion(const char *input) pstrcpy(file_prefix, sizeof(file_prefix), p + 1); } #ifdef DEBUG_COMPLETION -monitor_printf(cur_mon, "input='%s' path='%s' prefix='%s'\n", +monitor_printf(mon, "input='%s' path='%s' prefix='%s'\n", input, path, file_prefix); #endif ffs = opendir(path); @@ -4075,20 +4075,27 @@ static void file_completion(const char *input) if (stat(file, &sb) == 0 && S_ISDIR(sb.st_mode)) { pstrcat(file, sizeof(file), "/"); } -readline_add_completion(cur_mon->rs, file); +readline_add_completion(mon->rs, file); } } closedir(ffs); } +typedef struct MonitorBlockComplete { +Monitor *mon; +const char *input; +} MonitorBlockComplete; + static void block_completion_it(void *opaque, BlockDriverState *bs) { const char *name = bdrv_get_device_name(bs); -const char *input = opaque; +MonitorBlockComplete *mbc = opaque; +Monitor *mon = mbc->mon; +const char *input = mbc->input; if (input[0] == '\0' || !strncmp(name, (char *)input, strlen(input))) { -readline_add_completion(cur_mon->rs, name); +readline_add_completion(mon->rs, name); } } @@ -4124,18 +4131,20 @@ static const char *next_arg_type(const char *typestr) return (p != NULL ? ++p : typestr); } -static void monitor_find_completion(const char *cmdline) +static void monitor_find_completion(Monitor *mon, +const char *cmdline) { const char *cmdname; char *args[MAX_ARGS]; int nb_args, i, len; const char *ptype, *str; const mon_cmd_t *cmd; +MonitorBlockComplete mbs; parse_cmdline(cmdline, &nb_args, args); #ifdef DEBUG_COMPLETION for(i = 0; i < nb_args; i++) { -monitor_printf(cur_mon, "arg%d = '%s'\n", i, (char *)args[i]); +monitor_printf(mon, "arg%d = '%s'\n", i, (char *)args[i]); } #endif @@ -4154,9 +4163,9 @@ static void monitor_find_completion(const char *cmdline) cmdname = ""; else cmdname = args[0]; -readline_set_completion_index(cur_mon->rs, strlen(cmdname)); +readline_set_completion_index(mon->rs, strlen(cmdname)); for(cmd = mon_cmds; cmd->name != NULL; cmd++) { -cmd_completion(cmdname, cmd->name); +cmd_completion(mon, cmdname, cmd->name); } } else { /* find the command */ @@ -4184,33 +4193,35 @@ static void monitor_find_completion(const char *cmdline) switch(*ptype) { case 'F': /* file completion */ -readline_set_completion_index(cur_mon->rs, strlen(str)); -file_completion(str); +readline_set_completion_index(mon->rs, strlen(str)); +file_completion(mon, str); break; case 'B': /* block device name completion */ -
[Qemu-devel] [PATCH V3 0/7] monitor: support sub command group in auto completion and help
Global variable *mon_cmds and *info_cmds are not directly used any more, *cur_mon is not used in completion related functions. It is possible to create a monitor with different command table now, but that requirement do not exist yet, so not changed it to save trouble. Log command is still a special case now, may be it can be converted as sub group later. Patch 1-3 make sure the functions can be re-entered safely. V2: General: To discard *info_comds more graceful, help related function is modified to support sub command too. Patch 6/7 are added to improve help related functions. Patch 5: not directly return to make sure args are freed. Address Luiz's comments: Split patch into small serial. struct mon_cmd_t was not moved into header file, instead mon_cmnd_t *cmd_table is added as a member in struct Monitor. 5/7: drop original code comments for "info" in monitor_find_completion(). v3: 5/7: add parameter **args_cmdline in parse_cmdline() to tell next valid parameter's position. This fix the issue in case command length in input is not equal to its name's length such as "help|?", and the case input start with space such as " s". 7/7: better commit message. Wenchao Xia (7): 1 monitor: discard global variable *cur_mon in completion functions 2 monitor: discard global variable *mon_cmds 3 monitor: discard global variable *info_cmds in help functions 4 monitor: code move for parse_cmdline() 5 monitor: support sub commands in auto completion 6 monitor: improve "help" in auto completion for sub command 7 monitor: improve "help" to allow show tip of single command in sub group hmp-commands.hx|2 +- include/monitor/readline.h |3 +- monitor.c | 382 readline.c |5 +- 4 files changed, 251 insertions(+), 141 deletions(-)
[Qemu-devel] [PATCH V3 5/7] monitor: support sub commands in auto completion
This patch allow auto completion work normal for sub command case, "info block [DEVICE]" can auto complete now, by re-enter the completion function. Also, original "info" is treated as a special case, now it is treated as a sub command group, global variable info_cmds is not used in any more. "help" command is still treated as a special case, since it is not a sub command group but want to auto complete command in root command table. parse_cmdline() takes another parameter now to tell next valid parameter's position in original cmdline. Signed-off-by: Wenchao Xia --- monitor.c | 62 +--- 1 files changed, 42 insertions(+), 20 deletions(-) diff --git a/monitor.c b/monitor.c index aa641de..e0a4b67 100644 --- a/monitor.c +++ b/monitor.c @@ -801,9 +801,24 @@ static int get_str(char *buf, int buf_size, const char **pp) #define MAX_ARGS 16 -/* NOTE: this parser is an approximate form of the real command parser */ +/* + * Parse the command line to get valid args. + * @cmdline: command line to be parsed. + * @pnb_args: location to store the number of args, must NOT be NULL. + * @args: location to store the args, which should be freed by caller, must + *NOT be NULL. + * @args_cmdline: location to store char position in @cmdline correspond to + *@args include '\0', can be NULL. + * + * For example, if @cmdline = " ab" and @args_cmdline != NULL, result will be: + * pnb_args = 1, args[0] = "ab", args_cmdline[0] = "ab", + * args_cmdline[1] = "\0". + * + * NOTE: this parser is an approximate form of the real command parser. Number + * of args have a limit of MAX_ARGS. + */ static void parse_cmdline(const char *cmdline, - int *pnb_args, char **args) + int *pnb_args, char **args, const char **args_cmdline) { const char *p; int nb_args, ret; @@ -811,14 +826,14 @@ static void parse_cmdline(const char *cmdline, p = cmdline; nb_args = 0; -for (;;) { +while (nb_args < MAX_ARGS) { while (qemu_isspace(*p)) { p++; } -if (*p == '\0') { -break; +if (args_cmdline) { +args_cmdline[nb_args] = p; } -if (nb_args >= MAX_ARGS) { +if (*p == '\0') { break; } ret = get_str(buf, sizeof(buf), &p); @@ -888,7 +903,7 @@ static void help_cmd(Monitor *mon, const char *name) return; } -parse_cmdline(name, &nb_args, args); +parse_cmdline(name, &nb_args, args, NULL); if (nb_args >= MAX_ARGS) { goto cleanup; } @@ -4179,17 +4194,18 @@ static const char *next_arg_type(const char *typestr) return (p != NULL ? ++p : typestr); } -static void monitor_find_completion(Monitor *mon, -const char *cmdline) +static void monitor_find_completion_by_table(Monitor *mon, + const mon_cmd_t *cmd_table, + const char *cmdline) { -const char *cmdname; +const char *cmdname, *args_cmdline[MAX_ARGS]; char *args[MAX_ARGS]; int nb_args, i, len; const char *ptype, *str; const mon_cmd_t *cmd; MonitorBlockComplete mbs; -parse_cmdline(cmdline, &nb_args, args); +parse_cmdline(cmdline, &nb_args, args, args_cmdline); #ifdef DEBUG_COMPLETION for(i = 0; i < nb_args; i++) { monitor_printf(mon, "arg%d = '%s'\n", i, (char *)args[i]); @@ -4212,12 +4228,12 @@ static void monitor_find_completion(Monitor *mon, else cmdname = args[0]; readline_set_completion_index(mon->rs, strlen(cmdname)); -for (cmd = mon->cmd_table; cmd->name != NULL; cmd++) { +for (cmd = cmd_table; cmd->name != NULL; cmd++) { cmd_completion(mon, cmdname, cmd->name); } } else { /* find the command */ -for (cmd = mon->cmd_table; cmd->name != NULL; cmd++) { +for (cmd = cmd_table; cmd->name != NULL; cmd++) { if (compare_cmd(args[0], cmd->name)) { break; } @@ -4226,6 +4242,12 @@ static void monitor_find_completion(Monitor *mon, goto cleanup; } +if (cmd->sub_table) { +monitor_find_completion_by_table(mon, cmd->sub_table, + args_cmdline[1]); +goto cleanup; +} + ptype = next_arg_type(cmd->args_type); for(i = 0; i < nb_args - 2; i++) { if (*ptype != '\0') { @@ -4252,13 +4274,7 @@ static void monitor_find_completion(Monitor *mon, bdrv_iterate(block_completion_it, &mbs); break; case 's': -/* XXX: more generic ? */ -if (!strcmp(cmd->name, "info")) { -readline_set_completion_index(mon->rs, strlen(str)); -for(cmd = in
[Qemu-devel] x86-64 apic panic on shutdown on 1.4.93.
I intermittently get this from current kernels running under currentish qemu-git. Look familiar to anybody? reboot: machine restart general protection fault: fff2 [#1] CPU: 0 PID: 44 Comm: oneit Not tainted 3.10.0-rc7+ #3 Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 task: 8800068fd500 ti: 880006a26000 task.ti: 880006a26000 RIP: 0010:[] [] lapic_shutdown+0x32/0x34 RSP: 0018:880006a27e28 EFLAGS: 0202 RAX: 2193fbf9078bfbf9 RBX: 0202 RCX: RDX: 81015f71 RSI: 00ff RDI: 00f0 RBP: fee1dead R08: 0400 R09: R10: R11: 88000699f500 R12: R13: 01234567 R14: 0004 R15: 00423872 FS: () GS:81308000() knlGS: CS: 0010 DS: ES: CR0: 8005003b CR2: 00657ad0 CR3: 0697c000 CR4: 06b0 DR0: DR1: DR2: DR3: DR6: DR7: Stack: 28121969 81013bda 03f9 81013dc5 8102ad4b Call Trace: [] ? native_machine_shutdown+0x6/0x1a [] ? native_machine_restart+0x1d/0x31 [] ? SyS_reboot+0x126/0x15b [] ? schedule_tail+0x1e/0x44 [] ? ret_from_fork+0xf/0xb0 [] ? system_call_fastpath+0x16/0x1b Code: 53 f6 c4 02 75 1b 31 c0 83 3d af 42 50 00 00 74 0c 31 c0 83 3d b4 42 50 00 00 0f 94 c0 85 c0 74 0a 9c 5b fa e8 88 ff ff ff 53 9d <5b> c3 50 e8 11 ec 00 00 e8 d6 2f ff ff 48 8b 05 43 4b 32 00 bf RIP [] lapic_shutdown+0x32/0x34 RSP ---[ end trace dd3c376274d1a087 ]---
Re: [Qemu-devel] fstrim and cache=none
On Wed, Jun 12, 2013 at 8:49 AM, Paolo Bonzini wrote: > Il 11/06/2013 19:18, Dusty Mabe ha scritto: >> On Tue, Jun 4, 2013 at 8:01 AM, Dusty Mabe wrote: >> Did you manage to find anything? > > No, I was (and am :)) on vacation. > Paolo, Hope you are enjoying your vacation. I have since deleted the VM I was doing this on but it won't be too hard to rebuild if you need me to as I have documented my steps and guest xml as part of a series of blog posts I did on fstrim within VMs. If you are interested you can find them all at the URLs below. I decided to write the posts because I could not find much step-by-step documentation on how to do this on the web. Please feel free to distribute to any who may find them useful. http://dustymabe.com/2013/06/11/recover-space-from-vm-disk-images-by-using-discardfstrim/ http://dustymabe.com/2013/06/21/guest-discardfstrim-on-thin-lvs/ http://dustymabe.com/2013/06/26/enabling-qemu-guest-agent-and-fstrim-again/ Thanks, Dusty
Re: [Qemu-devel] [PATCH 0/3] make bh safe with hot-unplug
On Wed, Jun 26, 2013 at 5:55 PM, Paolo Bonzini wrote: > Il 26/06/2013 11:44, liu ping fan ha scritto: >> On Wed, Jun 26, 2013 at 4:38 PM, Paolo Bonzini wrote: >>> Il 26/06/2013 10:20, liu ping fan ha scritto: >> On the other hand, pushing _delete() out of finalization path is not >> easy, since we do not what time the DeviceState has done with its bh. > > See above: > > - if the BH will run in the iothread, the BH is definitely not running > (because the BH runs under the BQL, and the reclaimer owns it) It works for the case in which the DeviceState's reclaimer calls _bh_delete(). But in another case(also exist in current code), where we call _bh_delete() in callback, the bh will be scheduled, and oops! >>> >>> But you may know that the BH is not scheduled after removal, too. >>> >> No, the removal can run in parallel with the other mmio-dispatch which >> can resort to schedule a bh. > > But then behavior is more or less undefined. Of course the device must > ensure that something sane happens, but that's the responsibility of the > device, not of the generic layer. > >> I.e, the removal can not call >> _bh_delete(), so it do not know whether bh will be scheduled or not. > > It can call qemu_bh_delete(), then all concurrent qemu_bh_schedule() > will be no-ops. > Great, with this ability, we can achieve it in a more elegant way -- rcu! BTW, the responsibility is also assigned to guest driver wrt its unplug behavior. >>> If you look at the memory work, for example, the owner patches happen to >>> be useful for BQL-less dispatch too, but they are solving existing >>> hot-unplug bugs. >>> >> Oh, I will read it again, since I had thought the owner is only used >> for the purpose of refcnt. > > It is. But it goes beyond BQL-less dispatch. Anything that gives away > the BQL between a map and unmap (including asynchronous I/O) needs an > owner. We have ignored that until now because we do not have memory unplug. > > What we need is separation of removal and reclamation. Without that, > any effort to make things unplug-safe is going to be way way more > complicated than necessary. > Agree, but when I tried for bh, I found the separation of removal and reclamation are not easy. We can not _bh_delete() in acpi_piix_eject_slot(), because mmio-dispatch can schedule a bh at the same time. >>> >>> acpi_piix_eject_slot() is removal, not reclamation. The plan there is >>> that qdev_free calls the exit callback immediately (which can do >>> qemu_bh_delete), and schedules an unref after the next RCU grace period. >>> At the next RCU grace period the BH will not be running, thus it is >>> safe to finalize the object. >>> >> I have two question: >> 1st, who trigger qdev_free? //Not figuring out the total design, but >> I feel it is quite different from kernel's design, where refcnt->0, >> then exit is called. > > qdev_free is triggered by the guest, but free is a misnomer. It is > really "make it inaccessible from the guest and management" (the kernel > equivalent would be removal of /dev and /sys entries, for example). The > actual "free" will happen later. > Without seeing your detail design, but I suggest that leaving the "exit" as it is, and pick out the inaccessible related code to removal. Finally, when refcnt->0, exit is called, and it play as the final sync point for the remaining access. Regards, Pingfan >> 2nd, _delete_bh() means even there is any not-severed request, the >> request will be canceled. Is it legal, and will not lose data(not >> sure, since I do not know who will call qdev_free)? > > That's something that should be ensured by the device. For example it > is not a problem to cancel virtio-net's tx_bh. If it is a problem, the > device must do something else. It could even be a bdrv_drain_all() in > the worst case. > > Paolo
[Qemu-devel] [PATCH v4] Add timestamp to error message
[Issue] When we offer a customer support service and a problem happens in a customer's system, we try to understand the problem by comparing what the customer reports with message logs of the customer's system. In this case, we often need to know when the problem happens. But, currently, there is no timestamp in qemu's error messages. Therefore, we may not be able to understand the problem based on error messages. [Solution] Add a timestamp to qemu's error message logged by error_report() with g_time_val_to_iso8601(). [TODO] Add timestamp to monitor_printf() and fprintf(). Signed-off-by: Seiji Aguchi --- Changelog v3 -> v4 - Correct email address of Signed-off-by. v2 -> v3 - Use g_time_val_to_iso8601() to get timestamp instead of copying libvirt's time-handling functions. According to discussion below, qemu doesn't need to take care if timestamp functions are async-signal safe or not. http://marc.info/?l=qemu-devel&m=136741841921265&w=2 Also, In the review of v2 patch, strftime() are recommended to format string. But it is not a suitable function to handle msec. Then, simply call g_time_val_to_iso8601(). - Intoroduce a common time-handling function to util/qemu-time.c. (Suggested by Daniel P. Berrange) v1 -> v2 - add an option, -msg timestamp={on|off}, to enable output message with timestamp --- include/qemu/time.h | 11 +++ qemu-options.hx | 12 util/Makefile.objs |1 + util/qemu-error.c |8 util/qemu-time.c| 24 vl.c| 28 6 files changed, 84 insertions(+), 0 deletions(-) create mode 100644 include/qemu/time.h create mode 100644 util/qemu-time.c diff --git a/include/qemu/time.h b/include/qemu/time.h new file mode 100644 index 000..f70739b --- /dev/null +++ b/include/qemu/time.h @@ -0,0 +1,11 @@ +#ifndef TIME_H +#define TIME_H + +#include "qemu-common.h" + +/* "1970-01-01T00:00:00.99Z" + '\0' */ +#define TIMESTAMP_LEN 28 +extern void qemu_get_timestamp_str(char (*timestr)[]); +extern bool enable_timestamp_msg; + +#endif /* !TIME_H */ diff --git a/qemu-options.hx b/qemu-options.hx index ca6fdf6..7890921 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -3102,3 +3102,15 @@ HXCOMM This is the last statement. Insert new options before this line! STEXI @end table ETEXI + +DEF("msg", HAS_ARG, QEMU_OPTION_msg, +"-msg [timestamp=on|off]\n" +"output message with timestamp (default: off)\n", +QEMU_ARCH_ALL) +STEXI +@item -msg timestamp=on|off +@findex - msg +Output message with timestamp. +Adding timestamp to messages with @option{timestamp=on} +(disabled by default). +ETEXI diff --git a/util/Makefile.objs b/util/Makefile.objs index dc72ab0..063db56 100644 --- a/util/Makefile.objs +++ b/util/Makefile.objs @@ -11,3 +11,4 @@ util-obj-y += iov.o aes.o qemu-config.o qemu-sockets.o uri.o notify.o util-obj-y += qemu-option.o qemu-progress.o util-obj-y += hexdump.o util-obj-y += crc32c.o +util-obj-y += qemu-time.o diff --git a/util/qemu-error.c b/util/qemu-error.c index 08a36f4..33fa9d3 100644 --- a/util/qemu-error.c +++ b/util/qemu-error.c @@ -12,6 +12,7 @@ #include #include "monitor/monitor.h" +#include "qemu/time.h" /* * Print to current monitor if we have one, else to stderr. @@ -196,6 +197,7 @@ void error_print_loc(void) } } +bool enable_timestamp_msg; /* * Print an error message to current monitor if we have one, else to stderr. * Format arguments like sprintf(). The result should not contain @@ -206,6 +208,12 @@ void error_print_loc(void) void error_report(const char *fmt, ...) { va_list ap; +char timestr[TIMESTAMP_LEN]; + +if (enable_timestamp_msg) { +qemu_get_timestamp_str(×tr); +error_printf("%s ", timestr); +} error_print_loc(); va_start(ap, fmt); diff --git a/util/qemu-time.c b/util/qemu-time.c new file mode 100644 index 000..37f7b9e --- /dev/null +++ b/util/qemu-time.c @@ -0,0 +1,24 @@ +/* + * Time handling + * + * Copyright (C) 2013 Hitachi Data Systems Corp. + * + * Authors: + * Seiji Aguchi + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ +#include "qemu/time.h" + +void qemu_get_timestamp_str(char (*timestr)[]) +{ +GTimeVal tv; +gchar *tmp_str = NULL; + +g_get_current_time(&tv); +tmp_str = g_time_val_to_iso8601(&tv); +g_strlcpy((gchar *)*timestr, tmp_str, TIMESTAMP_LEN); +g_free(tmp_str); +return; +} diff --git a/vl.c b/vl.c index 0a8f056..aee7350 100644 --- a/vl.c +++ b/vl.c @@ -171,6 +171,8 @@ int main(int argc, char **argv) #include "ui/qemu-spice.h" #include "qapi/string-input-visitor.h" +#include "qemu/time.h" + //#define DEBUG_NET //#define DEBUG_SLIRP @@ -516,6 +518,18 @@ static QemuOptsList qemu_realtime_opts = { }, }; +static QemuOptsList qemu_msg_opts = { +.name
Re: [Qemu-devel] [PATCH v3] Add timestamp to error message
> Signed-off-by: Seiji Aguchi I used wrong email address to Signed-off-by. Please ignore this patch. Seiji > -Original Message- > From: qemu-devel-bounces+seiji.aguchi=hds@nongnu.org > [mailto:qemu-devel-bounces+seiji.aguchi=hds@nongnu.org] > On Behalf Of Seiji Aguchi > Sent: Wednesday, June 26, 2013 6:21 PM > To: qemu-devel@nongnu.org > Cc: kw...@redhat.com; aligu...@us.ibm.com; Tomoki Sekiyama; m...@redhat.com; > stefa...@gmail.com; mtosa...@redhat.com; > arm...@redhat.com; lcapitul...@redhat.com; dle-deve...@lists.sourceforge.net; > av1...@comtv.ru; stefa...@redhat.com; > pbonz...@redhat.com > Subject: [Qemu-devel] [PATCH v3] Add timestamp to error message > > [Issue] > When we offer a customer support service and a problem happens > in a customer's system, we try to understand the problem by > comparing what the customer reports with message logs of the > customer's system. > > In this case, we often need to know when the problem happens. > > But, currently, there is no timestamp in qemu's error messages. > Therefore, we may not be able to understand the problem based on > error messages. > > [Solution] > Add a timestamp to qemu's error message logged by > error_report() with g_time_val_to_iso8601(). > > [TODO] > Add timestamp to monitor_printf() and fprintf(). > > Signed-off-by: Seiji Aguchi > --- > Changelog > v2 -> v3 > > - Use g_time_val_to_iso8601() to get timestamp instead of >copying libvirt's time-handling functions. > >According to discussion below, qemu doesn't need to take care >if timestamp functions are async-signal safe or not. > >http://marc.info/?l=qemu-devel&m=136741841921265&w=2 > >Also, In the review of v2 patch, strftime() are recommended to >format string. But it is not a suitable function to handle msec. > >Then, simply call g_time_val_to_iso8601(). > > - Intoroduce a common time-handling function to util/qemu-time.c. >(Suggested by Daniel P. Berrange) > > v1 -> v2 > > - add an option, -msg timestamp={on|off}, to enable output message with > timestamp > --- > include/qemu/time.h | 11 +++ > qemu-options.hx | 12 > util/Makefile.objs |1 + > util/qemu-error.c |8 > util/qemu-time.c| 24 > vl.c| 28 > 6 files changed, 84 insertions(+), 0 deletions(-) > create mode 100644 include/qemu/time.h > create mode 100644 util/qemu-time.c > > diff --git a/include/qemu/time.h b/include/qemu/time.h > new file mode 100644 > index 000..f70739b > --- /dev/null > +++ b/include/qemu/time.h > @@ -0,0 +1,11 @@ > +#ifndef TIME_H > +#define TIME_H > + > +#include "qemu-common.h" > + > +/* "1970-01-01T00:00:00.99Z" + '\0' */ > +#define TIMESTAMP_LEN 28 > +extern void qemu_get_timestamp_str(char (*timestr)[]); > +extern bool enable_timestamp_msg; > + > +#endif /* !TIME_H */ > diff --git a/qemu-options.hx b/qemu-options.hx > index ca6fdf6..7890921 100644 > --- a/qemu-options.hx > +++ b/qemu-options.hx > @@ -3102,3 +3102,15 @@ HXCOMM This is the last statement. Insert new options > before this line! > STEXI > @end table > ETEXI > + > +DEF("msg", HAS_ARG, QEMU_OPTION_msg, > +"-msg [timestamp=on|off]\n" > +"output message with timestamp (default: off)\n", > +QEMU_ARCH_ALL) > +STEXI > +@item -msg timestamp=on|off > +@findex - msg > +Output message with timestamp. > +Adding timestamp to messages with @option{timestamp=on} > +(disabled by default). > +ETEXI > diff --git a/util/Makefile.objs b/util/Makefile.objs > index dc72ab0..063db56 100644 > --- a/util/Makefile.objs > +++ b/util/Makefile.objs > @@ -11,3 +11,4 @@ util-obj-y += iov.o aes.o qemu-config.o qemu-sockets.o > uri.o notify.o > util-obj-y += qemu-option.o qemu-progress.o > util-obj-y += hexdump.o > util-obj-y += crc32c.o > +util-obj-y += qemu-time.o > diff --git a/util/qemu-error.c b/util/qemu-error.c > index 08a36f4..33fa9d3 100644 > --- a/util/qemu-error.c > +++ b/util/qemu-error.c > @@ -12,6 +12,7 @@ > > #include > #include "monitor/monitor.h" > +#include "qemu/time.h" > > /* > * Print to current monitor if we have one, else to stderr. > @@ -196,6 +197,7 @@ void error_print_loc(void) > } > } > > +bool enable_timestamp_msg; > /* > * Print an error message to current monitor if we have one, else to stderr. > * Format arguments like sprintf(). The result should not contain > @@ -206,6 +208,12 @@ void error_print_loc(void) > void error_report(const char *fmt, ...) > { > va_list ap; > +char timestr[TIMESTAMP_LEN]; > + > +if (enable_timestamp_msg) { > +qemu_get_timestamp_str(×tr); > +error_printf("%s ", timestr); > +} > > error_print_loc(); > va_start(ap, fmt); > diff --git a/util/qemu-time.c b/util/qemu-time.c > new file mode 100644 > index 000..37f7b9e > --- /dev/null > +++ b/util/qemu-time.c > @@ -0,0 +1,24 @@ > +/* > + * Time handlin
Re: [Qemu-devel] [PATCH V2 5/7] monitor: support sub commands in auto completion
于 2013-6-27 0:03, Luiz Capitulino 写道: On Wed, 26 Jun 2013 12:03:39 +0800 Wenchao Xia wrote: 于 2013-6-24 20:48, Wenchao Xia 写道: This patch allow auot completion work normal in sub command case, "info block [DEVICE]" can auto complete now, by re-enter the completion function. Also, original "info" is treated as a special case, now it is treated as a sub command group, global variable info_cmds is not used any more. "help" command is still treated as a special case, since it is not a sub command group but want to auto complete command in root command table. Signed-off-by: Wenchao Xia --- monitor.c | 36 1 files changed, 24 insertions(+), 12 deletions(-) diff --git a/monitor.c b/monitor.c index aa641de..f364a0d 100644 --- a/monitor.c +++ b/monitor.c @@ -4179,10 +4179,11 @@ static const char *next_arg_type(const char *typestr) return (p != NULL ? ++p : typestr); } -static void monitor_find_completion(Monitor *mon, -const char *cmdline) +static void monitor_find_completion_by_table(Monitor *mon, + const mon_cmd_t *cmd_table, + const char *cmdline) { -const char *cmdname; +const char *cmdname, *p; char *args[MAX_ARGS]; int nb_args, i, len; const char *ptype, *str; @@ -4212,12 +4213,12 @@ static void monitor_find_completion(Monitor *mon, else cmdname = args[0]; readline_set_completion_index(mon->rs, strlen(cmdname)); -for (cmd = mon->cmd_table; cmd->name != NULL; cmd++) { +for (cmd = cmd_table; cmd->name != NULL; cmd++) { cmd_completion(mon, cmdname, cmd->name); } } else { /* find the command */ -for (cmd = mon->cmd_table; cmd->name != NULL; cmd++) { +for (cmd = cmd_table; cmd->name != NULL; cmd++) { if (compare_cmd(args[0], cmd->name)) { break; } @@ -4226,6 +4227,17 @@ static void monitor_find_completion(Monitor *mon, goto cleanup; } +/* locate next valid string in original cmdline used by re-enter */ +p = cmdline + strlen(args[0]); +while (qemu_isspace(*p)) { +p++; +} + Here it can't handle command start with space such as " blk", I plan make parse_cmdline() return additional const char **args_cmdline, which point to cmdline correspond to each args. Just want to mention it to save reviewer's time, I'll fix it with any other comments:). I prefer you respin it first, because it's not unusual that a single change like this one ends up requiring more changes. Also, if the series is good enough I can apply it w/o having to wait for another version. OK, I'll respin. Thanks for your time. +if (cmd->sub_table) { +monitor_find_completion_by_table(mon, cmd->sub_table, p); +goto cleanup; +} + ptype = next_arg_type(cmd->args_type); for(i = 0; i < nb_args - 2; i++) { if (*ptype != '\0') { @@ -4252,13 +4264,7 @@ static void monitor_find_completion(Monitor *mon, bdrv_iterate(block_completion_it, &mbs); break; case 's': -/* XXX: more generic ? */ -if (!strcmp(cmd->name, "info")) { -readline_set_completion_index(mon->rs, strlen(str)); -for(cmd = info_cmds; cmd->name != NULL; cmd++) { -cmd_completion(mon, str, cmd->name); -} -} else if (!strcmp(cmd->name, "sendkey")) { +if (!strcmp(cmd->name, "sendkey")) { char *sep = strrchr(str, '-'); if (sep) str = sep + 1; @@ -4284,6 +4290,12 @@ cleanup: } } +static void monitor_find_completion(Monitor *mon, +const char *cmdline) +{ +return monitor_find_completion_by_table(mon, mon->cmd_table, cmdline); +} + static int monitor_can_read(void *opaque) { Monitor *mon = opaque; -- Best Regards Wenchao Xia
Re: [Qemu-devel] [PATCH 1/2] device_tree: Add qemu_devtree_setprop_sized_cells() utility function
On Wed, Jun 26, 2013 at 7:17 PM, David Gibson wrote: > On Wed, Jun 26, 2013 at 02:44:17PM +0200, Alexander Graf wrote: >> I've had a lengthy discussion about that with Anthony a while ago. >> His take was that this is perfectly reasonable, as long as the >> device tree generation code stays within the machine model. The >> machine would just traverse the QOM hierachy and generate device >> tree nodes for everything it knows. > > I also talked with Anthony about this. Although he's insistent on the > fdt generation staying within the machine, I think it would make sense > to have some shared helpers for this between the fdt platforms. FDT generation should stay in the machine but having helpers for platforms to share makes all the sense in the world. What I don't think makes sense is to move FDT generation logic to qdev*.c or anything like that. But if 99% of ARM/PPC just call fdt_build_generic_table() and then customize from there, that's fine by me. Regards, Anthony Liguori > Note that spapr already contains a half-arsed implementation of this. > > -- > 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
Re: [Qemu-devel] [PATCH 1/2] device_tree: Add qemu_devtree_setprop_sized_cells() utility function
On Wed, Jun 26, 2013 at 11:50:26AM +0100, Peter Maydell wrote: > On 26 June 2013 11:31, Alexander Graf wrote: > > I think it makes sense to make this API special-purpose for "reg". > > We currently have a generic "put any number of 32bit values into the > > property" function (qemu_devtree_setprop_cells). > > Yes, but that doesn't work for things that aren't simple arrays > of 32 bit values, so I think that a generic way to deal > with those too would be useful. If you wanted to write a > "ranges" property you'd need this too, so it doesn't just > apply to "reg". > > I think we could avoid the "varargs doesn't promote" problem > by using a varargs-macro wrapper: > > #define qemu_devtree_setprop_sized_cells(fdt, node, prop, ...) \ > do { \ > uint64_t args[] = { __VA_ARGS__ }; \ > do_qemu_devtree_setprop_sized_cells(fdt, node, prop, \ > args, sizeof(args)); > } while (0) > > which will promote everything (including the size arguments, > harmlessly) to uint64_t, and avoids having a varargs function. Heh. Oops, didn't read this before I suggested the same thing. Although a statement expression will let you actually get any fdt error codes out. > > Can't we also just add a qemu_devtree_setprop_reg() that walks > > the tree downwards in search for #address-cells and #size-cells > > and assembles the correct reg property from a list of 64bit > > arguments? > > Do we have an actual use for this? It seems pretty complicated. > I would expect that in practice there are two major use cases: > (a) create your own fdt from scratch (in which case you can > just make everything 64 bits and in any case will know > when creating nodes what the #address-cells etc are) > (b) modify an existing fdt, in which case you definitely don't > want to go poking around too deeply in the tree; anything > more than just "put an extra node in the root" is starting > to get pretty chancy. So, I tend to think that "reg" and "ranges" specific helpers would be nicer than having to add the size for every parameter. But I was thinking of passing in the address-cells and size-cells values rather than having the function dig around in the tree to get them. The other way to avoid varargs would be to have a helper that just adds one entry at a time, using fdt_appendprop(). -- 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 pgpP7GmDmDq6Z.pgp Description: PGP signature
Re: [Qemu-devel] [PATCH 1/2] device_tree: Add qemu_devtree_setprop_sized_cells() utility function
On Wed, Jun 26, 2013 at 09:49:51AM +0100, Peter Maydell wrote: > On 26 June 2013 00:38, David Gibson wrote: > > On Mon, Jun 24, 2013 at 12:02:39PM +0100, Peter Maydell wrote: > >> On 24 June 2013 11:56, Alexander Graf wrote: > >> > This looks pretty complicated for something actually quite > >> > simple: All you want is to pass in a number of 64bit values, > >> > rather than 32bit ones, right? > >> > >> Nope. If the device tree blob says #address-cells is 1 > >> and #size-cells is 1, then I want to pass in values to > >> go in 32 bit cells. If it says #address-cells is 2 but > >> #size-cells is still 1, then I want to pass in a value > >> for a 64 bit cell then one for a 32 bit cell. If they're > >> both 2 then I want to pass in values for two 64 bit > >> cells. > > > > Hmm.. the property certainly needs to be constructed that way. But I > > think Alex's point is that you could make the arguments all 64-bit, > > and then truncate them in the generated property. > > Er, the arguments *are* all 64 bits and truncated > in the generated property: > + * @...: 0-terminated list of uint32_t number-of-cells, uint64_t value pairs Duh, sorry, misread. That's even worse for the point below. uint32_t / uint64_t pairs, which will sometimes work if you mess that up, until you get the wrong platform / parameter combination. And the uint32_ts are things that could naturally be in just a plain old int or long, which might be 64-bit by default on some ABIs, and the uint64_ts could be addresses in 32-bit space which would naturally be stored in a 32-bit variable, but *must* be upcast to 64-bit or again this interface will break subtly on certain platforms. This is hair-tearing frustration waiting to happen. > > There's a bigger problem, though, that exists with both versions. In > > general people expect integer arguments like this not to care too much > > about the exact integer type, because it will be promoted to the right > > thing. Except with varargs it won't. So if you ever have a > > notionally 64-bit address that happens to fit in a 32-bit variable and > > you pass that it, this function will be broken. And the worst of it > > is, it'll work most of the time, until you happen to hit the wrong ABI > > and parameter combination :(. > > Do you have a suggested improvement to the API to avoid this? After some thought, yes, though it will need gcc extensions: /* Big fat comment saying not to use this function directly */ int __qemu_fdt_pack_ints(void *fdt, int n, uint64_t[]) { /* Error if n is not even */ /* take the u64s from the array in pairs, packing as the previous version */ } #define qemu_fdt_pack_ints(fdt, ...) \ ({ \ uint64_t _tmp[] = { __VA_ARGS__ }; \ __qemu_fdt_pack_ints((fdt), ARRAY_SIZE(_tmp), _tmp); \ }) -- 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 pgpkdITU4lqhm.pgp Description: PGP signature
Re: [Qemu-devel] [PATCH 1/2] device_tree: Add qemu_devtree_setprop_sized_cells() utility function
On Wed, Jun 26, 2013 at 02:44:17PM +0200, Alexander Graf wrote: > On 06/26/2013 02:38 PM, Peter Crosthwaite wrote: > >Hi, > > > >On Wed, Jun 26, 2013 at 8:50 PM, Peter Maydell > >wrote: > >>On 26 June 2013 11:31, Alexander Graf wrote: > >>>I think it makes sense to make this API special-purpose for "reg". > >>>We currently have a generic "put any number of 32bit values into the > >>>property" function (qemu_devtree_setprop_cells). > >>Yes, but that doesn't work for things that aren't simple arrays > >>of 32 bit values, so I think that a generic way to deal > >>with those too would be useful. If you wanted to write a > >>"ranges" property you'd need this too, so it doesn't just > >>apply to "reg". > >> > >+1. And wouldn't an implementation of such a reg-specific function > >back onto Peter's new function quite nicely anyway? > > > >>I think we could avoid the "varargs doesn't promote" problem > >>by using a varargs-macro wrapper: > >> > >>#define qemu_devtree_setprop_sized_cells(fdt, node, prop, ...) \ > >> do { \ > >> uint64_t args[] = { __VA_ARGS__ }; \ > >> do_qemu_devtree_setprop_sized_cells(fdt, node, prop, \ > >> args, sizeof(args)); > >> } while (0) > >> > >Are statement expressions sanctioned? Or do we need to give up the > >nice caller accessible return codes? > > > >And can we factor out common functionality (mainly the error checking) > >with existing set_prop_cells to make the interfaces consistent? (we > >need to get rid of those aborts sooner or later) > > > >>which will promote everything (including the size arguments, > >>harmlessly) to uint64_t, and avoids having a varargs function. > >> > >>>Can't we also just add a qemu_devtree_setprop_reg() that walks > >>>the tree downwards in search for #address-cells and #size-cells > >>>and assembles the correct reg property from a list of 64bit > >>>arguments? > >I have a patch in my tree that generalises qemu_devtree_getprop* to > >allow you walk parents for properties (as per the #foo-cells > >semantic). I use it for interrupt cells however, which kinda suggests > >that this wish for parent traversal is more generic than just > >populating reg. I think that Peters patch, along with a parent search > >friendly property search will be enough to be able to do whatever you > >want in only a handful of lines. > > > >>Do we have an actual use for this? It seems pretty complicated. > >>I would expect that in practice there are two major use cases: > >> (a) create your own fdt from scratch (in which case you can > >> just make everything 64 bits and in any case will know > >> when creating nodes what the #address-cells etc are) > >> (b) modify an existing fdt, in which case you definitely don't > >> want to go poking around too deeply in the tree; anything > >> more than just "put an extra node in the root" is starting > >> to get pretty chancy. > >> > >Looking to the future, what about -device adding a periph then having > >qemu add it to the dtb before boot? > > I've had a lengthy discussion about that with Anthony a while ago. > His take was that this is perfectly reasonable, as long as the > device tree generation code stays within the machine model. The > machine would just traverse the QOM hierachy and generate device > tree nodes for everything it knows. I also talked with Anthony about this. Although he's insistent on the fdt generation staying within the machine, I think it would make sense to have some shared helpers for this between the fdt platforms. Note that spapr already contains a half-arsed implementation of this. -- 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 pgpYK7QqDahFp.pgp Description: PGP signature
[Qemu-devel] [ANNOUNCE] QEMU 1.5.1 Stable released
Hi everyone, I am pleased to announce that the QEMU v1.5.1 stable release is now available at: http://wiki.qemu.org/download/qemu-1.5.1.tar.bz2 v1.5.1 is now tagged in the official qemu.git repository, and the stable-1.5 branch has been updated accordingly: http://git.qemu.org/?p=qemu.git;a=shortlog;h=refs/heads/stable-1.5 This release contains 55 build/bug fixes, and includes an important fix for the QMP management interface. QEMU v1.5.2 is planned for 2013-08-21. Thanks to everyone involved! 295d81c: Update VERSION for 1.5.1 release (Anthony Liguori) cc0bd7e: wdt_i6300esb: fix vmstate versioning (Michael Roth) 12e5b2b: virtio-rng: Fix crash with non-default backend (Cole Robinson) cb55efe: iscsi: reorganize iscsi_readcapacity_sync (Paolo Bonzini) 1b94fc4: iscsi: simplify freeing of tasks (Paolo Bonzini) 5e690bb: vhost-scsi: fix k->set_guest_notifiers() NULL dereference (Stefan Hajnoczi) 129db36: scsi-disk: scsi-block device for scsi pass-through should not be removable (Pavel Hrdina) 637d640: scsi-generic: check the return value of bdrv_aio_ioctl in execute_command (Pavel Hrdina) 9c4f5dd: scsi-generic: fix sign extension of READ CAPACITY(10) data (Paolo Bonzini) 3abd71c: scsi: reset cdrom tray statuses on scsi_disk_reset (Pavel Hrdina) 5fcb9bf: nbd: strip braces from literal IPv6 address in URI (Ján Tomko) 6c8cf5f: qemu-socket: allow hostnames starting with a digit (Ján Tomko) ce4e8f0: vmdk: byteswap VMDK4Header.desc_offset field (Stefan Hajnoczi) c683f1b: target-i386: cpu: Fix potential buffer overrun in get_register_name_32() (Igor Mammedov) 75e4aa9: pc: Fix crash when attempting to hotplug CPU with negative ID (Igor Mammedov) 055a7fc: smbios: Check R in -smbios type=0, release=R parses okay (Markus Armbruster) 93bc624: smbios: Fix -smbios type=0, release=... for big endian hosts (Markus Armbruster) 61fbaee: smbios: Clean up smbios_add_field() parameters (Markus Armbruster) 685ee2d: smbios: Convert to error_report() (Markus Armbruster) fa0f47d: log.h: Supply missing includes (Markus Armbruster) 7552569: error-report.h: Supply missing include (Markus Armbruster) 02d2672: tcg-ppc64: rotr_i32 rotates wrong amount (Anton Blanchard) 2917f6b: tcg-ppc64: Fix add2_i64 (Anton Blanchard) 9534f66: tcg-ppc64: bswap64 rotates output 32 bits (Anton Blanchard) d208f05: tcg-ppc64: Fix RLDCL opcode (Anton Blanchard) 6b6f105: ivshmem: add missing error exit(2) (Stefan Hajnoczi) 3202c02: Makefile: Install qemu-img and qemu-nbd man pages only if built (Andreas Färber) 5a893b0: tap: fix NULL dereference when passing invalid parameters to tap (Jason Wang) 0817fa9: create qemu_openpty_raw() helper function and move it to a separate file (Michael Tokarev) 5810174: blockdev: reset werror/rerror on drive_del (Stefan Hajnoczi) eeaa8d3: q35: set fw_name (Michael S. Tsirkin) c127070: target-i386: Fix aflag logic for CODE64 and the 0x67 prefix (Richard Henderson) 252a7c6: qemu-char: don't issue CHR_EVENT_OPEN in a BH (Michael Roth) 6f3718c: xilinx_axidma: Do not set DMA .notify to NULL after notify (Wendy Liang) 1fb147f: virtio-ccw: Fix unsetting of indicators. (Cornelia Huck) 72762f2: s390x/css: Fix concurrent sense. (Cornelia Huck) 31ba701: ui/gtk.c: Fix *BSD build of Gtk+ UI (Brad Smith) 9ca80c7: vmxnet3: fix NICState cleanup (Stefan Hajnoczi) a548bac: Fix usage of USB_DEV_FLAG_IS_HOST flag. (Michael Marineau) 9b5751e: host-libusb: Correct test for USB packet state (Ed Maste) 032ce1b: qdev: fix get_fw_dev_path to support to add nothing to fw_dev_path (Amos Kong) baa8a8b: do not check pointers after dereferencing them (Paolo Bonzini) 327e75b: xen: start PCI hole at 0xe000 (same as pc_init1 and qemu-xen-traditional) (Stefano Stabellini) 9e7fdaf: Remove OSS support for OpenBSD (Brad Smith) d503afb: target-i386: fix abort on bad PML4E/PDPTE/PDE/PTE addresses (Luiz Capitulino) 5b3ca29: update seabios to release 1.7.2.2 (Gerd Hoffmann) 7b9cdc5: Revert "roms: switch oldnoconfig to olddefconfig" (Gerd Hoffmann) 0565700: ide: Set BSY bit during FLUSH (Andreas Färber) ddaa83e: chardev: fix "info chardev" output (Gerd Hoffmann) 38ec6c1: xen_machine_pv: do not create a dummy CPU in machine->init (Stefano Stabellini) 951411f: main_loop: do not set nonblocking if xen_enabled() (Stefano Stabellini) 5c26608: xen: simplify xen_enabled (Stefano Stabellini) 3541912: qom/object: Don't poll cast cache for NULL objects (Peter Crosthwaite) 749806d: rtl8139: flush queued packets when RxBufPtr is written (Stefan Hajnoczi) a6fc2cd: hw/9pfs: use O_NOFOLLOW for mapped readlink operation (Aneesh Kumar K.V) eabdf85: hw/9pfs: Fix segfault with 9p2000.u (Aneesh Kumar K.V)
[Qemu-devel] [PATCH] i.MX: Implement a more complete version of the GPT timer.
* implement compare 1 2 and 3 registers * simplify Debug printf Signed-off-by: Jean-Christophe DUBOIS Reviewed-by: Peter Chubb --- hw/timer/imx_gpt.c | 439 - 1 file changed, 267 insertions(+), 172 deletions(-) diff --git a/hw/timer/imx_gpt.c b/hw/timer/imx_gpt.c index d8c4f0b..ad3e210 100644 --- a/hw/timer/imx_gpt.c +++ b/hw/timer/imx_gpt.c @@ -5,6 +5,7 @@ * Copyright (c) 2011 NICTA Pty Ltd * Originally written by Hans Jiang * Updated by Peter Chubb + * Updated by Jean-Christophe Dubois * * This code is licensed under GPL version 2 or later. See * the COPYING file in the top-level directory. @@ -18,10 +19,44 @@ #include "hw/sysbus.h" #include "hw/arm/imx.h" -//#define DEBUG_TIMER 1 -#ifdef DEBUG_TIMER +#define TYPE_IMX_GPT "imx.gpt" + +/* + * Define to 1 for debug messages + */ +#define DEBUG_TIMER 0 +#if DEBUG_TIMER + +static char const *imx_timerg_reg_name(uint32_t reg) +{ +switch (reg) { +case 0: +return "CR"; +case 1: +return "PR"; +case 2: +return "SR"; +case 3: +return "IR"; +case 4: +return "OCR1"; +case 5: +return "OCR2"; +case 6: +return "OCR3"; +case 7: +return "ICR1"; +case 8: +return "ICR2"; +case 9: +return "CNT"; +default: +return "[?]"; +} +} + # define DPRINTF(fmt, args...) \ - do { printf("imx_timer: " fmt , ##args); } while (0) + do { printf("%s: " fmt , __func__, ##args); } while (0) #else # define DPRINTF(fmt, args...) do {} while (0) #endif @@ -33,7 +68,7 @@ #define DEBUG_IMPLEMENTATION 1 #if DEBUG_IMPLEMENTATION # define IPRINTF(fmt, args...) \ -do { fprintf(stderr, "imx_timer: " fmt, ##args); } while (0) + do { fprintf(stderr, "%s: " fmt, __func__, ##args); } while (0) #else # define IPRINTF(fmt, args...) do {} while (0) #endif @@ -43,16 +78,7 @@ * * This timer counts up continuously while it is enabled, resetting itself * to 0 when it reaches TIMER_MAX (in freerun mode) or when it - * reaches the value of ocr1 (in periodic mode). WE simulate this using a - * QEMU ptimer counting down from ocr1 and reloading from ocr1 in - * periodic mode, or counting from ocr1 to zero, then TIMER_MAX - ocr1. - * waiting_rov is set when counting from TIMER_MAX. - * - * In the real hardware, there are three comparison registers that can - * trigger interrupts, and compare channel 1 can be used to - * force-reset the timer. However, this is a `bare-bones' - * implementation: only what Linux 3.x uses has been implemented - * (free-running timer from 0 to OCR1 or TIMER_MAX) . + * reaches the value of one of the ocrX (in periodic mode). */ #define TIMER_MAX 0XUL @@ -79,9 +105,13 @@ #define GPT_CR_FO3(1 << 31) /* Force Output Compare Channel 3 */ #define GPT_SR_OF1 (1 << 0) +#define GPT_SR_OF2 (1 << 1) +#define GPT_SR_OF3 (1 << 2) #define GPT_SR_ROV (1 << 5) #define GPT_IR_OF1IE (1 << 0) +#define GPT_IR_OF2IE (1 << 1) +#define GPT_IR_OF3IE (1 << 2) #define GPT_IR_ROVIE (1 << 5) typedef struct { @@ -101,15 +131,19 @@ typedef struct { uint32_t icr2; uint32_t cnt; -uint32_t waiting_rov; +uint32_t next_timeout; +uint32_t next_int; + +uint32_t freq; + qemu_irq irq; } IMXTimerGState; static const VMStateDescription vmstate_imx_timerg = { .name = "imx-timerg", -.version_id = 2, -.minimum_version_id = 2, -.minimum_version_id_old = 2, +.version_id = 3, +.minimum_version_id = 3, +.minimum_version_id_old = 3, .fields = (VMStateField[]) { VMSTATE_UINT32(cr, IMXTimerGState), VMSTATE_UINT32(pr, IMXTimerGState), @@ -121,7 +155,9 @@ static const VMStateDescription vmstate_imx_timerg = { VMSTATE_UINT32(icr1, IMXTimerGState), VMSTATE_UINT32(icr2, IMXTimerGState), VMSTATE_UINT32(cnt, IMXTimerGState), -VMSTATE_UINT32(waiting_rov, IMXTimerGState), +VMSTATE_UINT32(next_timeout, IMXTimerGState), +VMSTATE_UINT32(next_int, IMXTimerGState), +VMSTATE_UINT32(freq, IMXTimerGState), VMSTATE_PTIMER(timer, IMXTimerGState), VMSTATE_END_OF_LIST() } @@ -138,16 +174,14 @@ static const IMXClk imx_timerg_clocks[] = { NOCLK,/* 111 not defined */ }; - static void imx_timerg_set_freq(IMXTimerGState *s) { -int clksrc; -uint32_t freq; - -clksrc = (s->cr >> GPT_CR_CLKSRC_SHIFT) & GPT_CR_CLKSRC_MASK; -freq = imx_clock_frequency(s->ccm, imx_timerg_clocks[clksrc]) / (1 + s->pr); +uint32_t clksrc = extract32(s->cr, GPT_CR_CLKSRC_SHIFT, 3); +uint32_t freq = imx_clock_frequency(s->ccm, imx_timerg_clocks[clksrc]) +/ (1 + s->pr); +s->freq = freq; -DPRINTF("Setting gtimer clksrc %d to frequency %d\n", clksrc, freq); +DPRINTF("Setting clksrc %d to freq
Re: [Qemu-devel] [PULL 2/8] i.MX: Implement a more complete version of the GPT timer.
On 06/27/2013 12:15 AM, Peter Maydell wrote: On 26 June 2013 22:57, Jean-Christophe DUBOIS wrote: Names don't feel really useful in the second case as they are indistinguishable. Is the consensus around "generic" names (like MMIO or "Ctrl regs") without adding reference to the device a good one for all platforms? Just leave the memory region and vmstate names as they were before your patches. OK, I will. Now, please notice that the EPIT timer has been changed recently (on main line) with the exact same code model as the one proposed in this patch. So it is not on par either with any consensus that might have been made on VMState or memory region naming. JC (Personally I think it's entirely fine to include the device name in the memory region name. These strings are for debugging, so if I print region->name in my debugger it's much more helpful if it says "imx-serial" than if it just says "regs".) -- PMM
[Qemu-devel] [PATCH v3] Add timestamp to error message
[Issue] When we offer a customer support service and a problem happens in a customer's system, we try to understand the problem by comparing what the customer reports with message logs of the customer's system. In this case, we often need to know when the problem happens. But, currently, there is no timestamp in qemu's error messages. Therefore, we may not be able to understand the problem based on error messages. [Solution] Add a timestamp to qemu's error message logged by error_report() with g_time_val_to_iso8601(). [TODO] Add timestamp to monitor_printf() and fprintf(). Signed-off-by: Seiji Aguchi --- Changelog v2 -> v3 - Use g_time_val_to_iso8601() to get timestamp instead of copying libvirt's time-handling functions. According to discussion below, qemu doesn't need to take care if timestamp functions are async-signal safe or not. http://marc.info/?l=qemu-devel&m=136741841921265&w=2 Also, In the review of v2 patch, strftime() are recommended to format string. But it is not a suitable function to handle msec. Then, simply call g_time_val_to_iso8601(). - Intoroduce a common time-handling function to util/qemu-time.c. (Suggested by Daniel P. Berrange) v1 -> v2 - add an option, -msg timestamp={on|off}, to enable output message with timestamp --- include/qemu/time.h | 11 +++ qemu-options.hx | 12 util/Makefile.objs |1 + util/qemu-error.c |8 util/qemu-time.c| 24 vl.c| 28 6 files changed, 84 insertions(+), 0 deletions(-) create mode 100644 include/qemu/time.h create mode 100644 util/qemu-time.c diff --git a/include/qemu/time.h b/include/qemu/time.h new file mode 100644 index 000..f70739b --- /dev/null +++ b/include/qemu/time.h @@ -0,0 +1,11 @@ +#ifndef TIME_H +#define TIME_H + +#include "qemu-common.h" + +/* "1970-01-01T00:00:00.99Z" + '\0' */ +#define TIMESTAMP_LEN 28 +extern void qemu_get_timestamp_str(char (*timestr)[]); +extern bool enable_timestamp_msg; + +#endif /* !TIME_H */ diff --git a/qemu-options.hx b/qemu-options.hx index ca6fdf6..7890921 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -3102,3 +3102,15 @@ HXCOMM This is the last statement. Insert new options before this line! STEXI @end table ETEXI + +DEF("msg", HAS_ARG, QEMU_OPTION_msg, +"-msg [timestamp=on|off]\n" +"output message with timestamp (default: off)\n", +QEMU_ARCH_ALL) +STEXI +@item -msg timestamp=on|off +@findex - msg +Output message with timestamp. +Adding timestamp to messages with @option{timestamp=on} +(disabled by default). +ETEXI diff --git a/util/Makefile.objs b/util/Makefile.objs index dc72ab0..063db56 100644 --- a/util/Makefile.objs +++ b/util/Makefile.objs @@ -11,3 +11,4 @@ util-obj-y += iov.o aes.o qemu-config.o qemu-sockets.o uri.o notify.o util-obj-y += qemu-option.o qemu-progress.o util-obj-y += hexdump.o util-obj-y += crc32c.o +util-obj-y += qemu-time.o diff --git a/util/qemu-error.c b/util/qemu-error.c index 08a36f4..33fa9d3 100644 --- a/util/qemu-error.c +++ b/util/qemu-error.c @@ -12,6 +12,7 @@ #include #include "monitor/monitor.h" +#include "qemu/time.h" /* * Print to current monitor if we have one, else to stderr. @@ -196,6 +197,7 @@ void error_print_loc(void) } } +bool enable_timestamp_msg; /* * Print an error message to current monitor if we have one, else to stderr. * Format arguments like sprintf(). The result should not contain @@ -206,6 +208,12 @@ void error_print_loc(void) void error_report(const char *fmt, ...) { va_list ap; +char timestr[TIMESTAMP_LEN]; + +if (enable_timestamp_msg) { +qemu_get_timestamp_str(×tr); +error_printf("%s ", timestr); +} error_print_loc(); va_start(ap, fmt); diff --git a/util/qemu-time.c b/util/qemu-time.c new file mode 100644 index 000..37f7b9e --- /dev/null +++ b/util/qemu-time.c @@ -0,0 +1,24 @@ +/* + * Time handling + * + * Copyright (C) 2013 Hitachi Data Systems Corp. + * + * Authors: + * Seiji Aguchi + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ +#include "qemu/time.h" + +void qemu_get_timestamp_str(char (*timestr)[]) +{ +GTimeVal tv; +gchar *tmp_str = NULL; + +g_get_current_time(&tv); +tmp_str = g_time_val_to_iso8601(&tv); +g_strlcpy((gchar *)*timestr, tmp_str, TIMESTAMP_LEN); +g_free(tmp_str); +return; +} diff --git a/vl.c b/vl.c index 0a8f056..aee7350 100644 --- a/vl.c +++ b/vl.c @@ -171,6 +171,8 @@ int main(int argc, char **argv) #include "ui/qemu-spice.h" #include "qapi/string-input-visitor.h" +#include "qemu/time.h" + //#define DEBUG_NET //#define DEBUG_SLIRP @@ -516,6 +518,18 @@ static QemuOptsList qemu_realtime_opts = { }, }; +static QemuOptsList qemu_msg_opts = { +.name = "msg", +.head = QTAILQ_HEAD_INITIALIZER(qemu_msg
Re: [Qemu-devel] [PULL 2/8] i.MX: Implement a more complete version of the GPT timer.
Am 26.06.2013 23:57, schrieb Jean-Christophe DUBOIS: > On 06/26/2013 11:18 PM, Paolo Bonzini wrote: >> Il 26/06/2013 23:13, Jean-Christophe DUBOIS ha scritto: >>> On 06/26/2013 08:58 PM, Jean-Christophe DUBOIS wrote: On 06/26/2013 09:21 AM, Peter Crosthwaite wrote: > Hi > > On Wed, Jun 26, 2013 at 4:56 PM, Paolo Bonzini > wrote: >> Il 25/06/2013 22:53, Peter Maydell ha scritto: >>> On 25 June 2013 19:42, Paolo Bonzini wrote: Il 25/06/2013 20:21, Peter Maydell ha scritto: > @@ -416,7 +513,7 @@ static int imx_timerg_init(SysBusDevice *dev) > > sysbus_init_irq(dev, &s->irq); > memory_region_init_io(&s->iomem, &imx_timerg_ops, > - s, "imxg-timer", > + s, TYPE_IMX_GPT, > 0x1000); > sysbus_init_mmio(dev, &s->iomem); > There was some agreement that this is not a good change. >>> I agree (and more so regarding the use of the macro in the >>> vmstate name), but nobody actually posted any comment to >>> that effect against any of the versions of this patch that >>> got sent out for review... >> Yeah, the timing was bad... Can you post a revert, though? >> > The original string being replaced was a poor choice as well. IIUC the > consensus was string field of the memory regions is supposed to > indicate the purpose of the memory region for the device. Good > examples would be "Control regs" or "MMIO". Naming the memory region > after the device type is a redundancy as that info will come via > memory region owners. > > So rather than revert could you just choose something more descriptive? Peter (Maydell), How do you want to work this out? Do you revert it and we start over? Or should I provide a patch on top of the actual file to change the "wrong name"? Please advise. >>> I browsed through the various timer implementations in the hw/timer >>> directory and I was not able to spot one that would follow the >>> convention you indicated. >>> >>> Could you point me to a "good citizen" example? >> Here is one example (hw/pci-host/piix.c): >> >> memory_region_init_io(&s->conf_mem, &pci_host_conf_le_ops, s, >> "pci-conf-idx", 4); >> sysbus_add_io(dev, 0xcf8, &s->conf_mem); >> sysbus_init_ioports(&s->busdev, 0xcf8, 4); >> >> memory_region_init_io(&s->data_mem, &pci_host_data_le_ops, s, >> "pci-conf-data", 4); >> sysbus_add_io(dev, 0xcfc, &s->data_mem); >> sysbus_init_ioports(&s->busdev, 0xcfc, 4); >> >> Just reverting the changes to memory regions and vmstate names is enough >> for now. > > I tried to change the memory region name for the timer registers to > something not prepended wit the device name (I choose "regs") and here > is the result in the qemu console (I changes both EPIT and GPT timers). > We went from: > > (qemu) info mtree > memory > -7ffe (prio 0, RW): system > 1fffc000-1fff (prio 0, RW): kzm.sram > 43f9-43f90fff (prio 0, RW): imx-serial > 43f94000-43f94fff (prio 0, RW): imx-serial > 53f8-53f80fff (prio 0, RW): imx_ccm > 53f9-53f90fff (prio 0, RW): imx.gpt > 53f94000-53f94fff (prio 0, RW): imx.epit > 53f98000-53f98fff (prio 0, RW): imx.epit > 6800-68000fff (prio 0, RW): imx_avic > 8000-83ff (prio 0, RW): kzm.ram > 8800-8bff (prio 0, RW): alias ram.alias > @kzm.ram -03ff > b600-b6ff (prio 0, RW): lan9118-mmio > I/O > - (prio 0, RW): io > aliases > kzm.ram > 8000-83ff (prio 0, RW): kzm.ram > (qemu) > > to: > > (qemu) info mtree > memory > -7ffe (prio 0, RW): system > 1fffc000-1fff (prio 0, RW): kzm.sram > 43f9-43f90fff (prio 0, RW): imx-serial > 43f94000-43f94fff (prio 0, RW): imx-serial > 53f8-53f80fff (prio 0, RW): imx_ccm > 53f9-53f90fff (prio 0, RW): regs > 53f94000-53f94fff (prio 0, RW): regs > 53f98000-53f98fff (prio 0, RW): regs > 6800-68000fff (prio 0, RW): imx_avic > 8000-83ff (prio 0, RW): kzm.ram > 8800-8bff (prio 0, RW): alias ram.alias > @kzm.ram -03ff > b600-b6ff (prio 0, RW): lan9118-mmio > I/O > 00
Re: [Qemu-devel] [PULL 2/8] i.MX: Implement a more complete version of the GPT timer.
On 26 June 2013 22:57, Jean-Christophe DUBOIS wrote: > Names don't feel really useful in the second case as they are > indistinguishable. Is the consensus around "generic" names (like MMIO or > "Ctrl regs") without adding reference to the device a good one for all > platforms? Just leave the memory region and vmstate names as they were before your patches. (Personally I think it's entirely fine to include the device name in the memory region name. These strings are for debugging, so if I print region->name in my debugger it's much more helpful if it says "imx-serial" than if it just says "regs".) -- PMM
Re: [Qemu-devel] [PATCH v4 06/10] qemu-ga: Add Windows VSS provider to quiesce applications on fsfreeze
On 6/26/13 10:32 , "Laszlo Ersek" wrote: >On 06/25/13 18:03, Laszlo Ersek wrote: >> On 06/06/13 17:06, Tomoki Sekiyama wrote: > >Comparing the .def file and the provider header file: >... >(a) what is the reason for not listing DllCanUnloadNow() and >DllGetClassObject() in the header file? Because these two are reserved functions for COM, and not Referenced from qemu-ga.exe. >(b) Does STDAPI imply a return type? Or are you just going with the >implicit "int"? (Based on my encounters with EFIAPI, I think it's the >latter.) It is extracted as 'extern "C" HRESULT __stdcall'. (__stdcall specifies calling convention.) >>>+#define EVENT_NAME_FROZEN "Global\\QGAVSSEvent-frozen" >>> +#define EVENT_NAME_THAW "Global\\QGAVSSEvent-thaw" > >No idea what I'm talking about, but since we're qualifying the second >component with the "QGAVSSEvent" prefix, shouldn't we just replace the >first component ("Global") with it? Or would it effect "event routing"? >(Tangential question, anyway.) Latter. "Global\\" is a reserved namespace in Windows used for communication between services and the other program, so we can't omit this. >>> +const GUID CLSID_COMAdminCatalog = { 0xF618C514, 0xDFB8, 0x11d1, >>> +{0xA2, 0xCF, 0x00, 0x80, 0x5F, 0xC7, 0x92, 0x35} }; >>> +const GUID IID_ICOMAdminCatalog = { 0xDD662187, 0xDFC2, 0x11d1, >>> +{0xA2, 0xCF, 0x00, 0x80, 0x5F, 0xC7, 0x92, 0x35} }; >>> +const GUID CLSID_WbemLocator = { 0x4590f811, 0x1d3a, 0x11d0, >>> +{0x89, 0x1f, 0x00, 0xaa, 0x00, 0x4b, 0x2e, 0x24} }; >>> +const GUID IID_IWbemLocator = { 0xdc12a687, 0x737f, 0x11cf, >>> +{0x88, 0x4d, 0x00, 0xaa, 0x00, 0x4b, 0x2e, 0x24} }; > >Would it be possible to make these static? Not too important of course. Some of these are declared as "extern" in headers in MinGW or VSS SDK, so unfortunately we can't make them static. >>>+ >>> +static void errmsg(DWORD err, const char *text) >>> +{ >>> +char *msg = NULL, *nul = strchr(text, '('); >>> +int len = nul ? nul - text : -1; >>> + >>> +FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | >>> + FORMAT_MESSAGE_FROM_SYSTEM | >>>FORMAT_MESSAGE_IGNORE_INSERTS, >>> + NULL, err, MAKELANGID(LANG_NEUTRAL, >>>SUBLANG_DEFAULT), >>> + (char *)&msg, 0, NULL); > >(The FormatMessage() specification in MSDN is simply incredible. >"(char *)&msg", seriously? Your code is correct, but the interface is >unbelievable.) Yeah, really... >>> +printf("%.*s. (Error: %lx) %s\n", len, text, err, msg); > >(a) Since we're printing an error message here, I suspect it should go >to stderr. OK. >(b) In case "text" doesn't contain an opening paren, "len" is set to -1. >"A negative precision is taken as if the precision were omitted", IOW >the entire string will be printed. Clever! Maybe need some comments... >(c) Does DWORD expand to "uint32_t"? In that case "%lx" is too big on >64-bit (LP64). We should probably use "%x" or "%"PRIx32. (Or do we build >qemu-ga.exe only for 32-bit? I seem to remember something like that.) DWORD is typedef as unsigned long int. MinGW64 uses LLP64 model, so it is 32bit both in 32-bit and 64-bit MinGW. So if I use %x here, gcc outputs: qga/vss-win32-provider/install.cpp:44:57: warning: format '%x' expects argument of type 'unsigned int', but argument 4 has type 'DWORD {aka long unsigned int}' [-Wformat] >>>+snprintf(buf, sizeof(buf), "%s%s. (Error: %lx) %s\n", text, opt, >>>err, msg); >>> +MessageBox(NULL, buf, "Error from " QGA_PROVIDER_NAME, >>>MB_OK|MB_ICONERROR); > >Do you need a trailing newline for a message box? No. I will remove "\n". Thanks. >>> +/* Lookup Administrators group name from winmgmt */ >>> +static HRESULT GetAdminName(_bstr_t &name) >>> +{ > >I can see that you want to call GetAdminName() in chk(), hence you must >return a HRESULT and store the value through the parameter list. >However, can we keep the C++ features to a minimum? I'd prefer if the >non-const reference were replaced with a pointer-to-_bstr_t. >(Tangential, change only if you respin anyway and don't mind it.) OK, I will make this into 'static HRESULT GetAdminName(_bstr_t *name)'. >>> +if (!pEnum) { >>> +errmsg(E_FAIL, "Failed to query for Administrators"); >>> +goto out; > >I think you forgot to set "hr" to something ugly -- the code below the >"out" label will simply return it, and "hr" is currently something nice. >(The last chk() succeeded.) I will add "hr = E_FAIL;" here. Thanks. >>> +} > >This branch is probably for the case when ExecQuery() succeeds, but >doesn't return any rows, right? We must not come here (while the reference is accurate). It is just in case. >>> +chk(pEnum->Next(WBEM_INFINITE, 1, &pWobj, &returned)); >>> +if (returned == 0) { >>> +errmsg(E_FAIL, "Failed to query for Administrators"); >>> +goto out; >>> +} >>> + >>> +chk(pWobj->Get(_bstr_t(L"Name"), 0, &var, 0, 0)); >>> +name = var; > >This assigns a _variant_t to a _bstr
Re: [Qemu-devel] [PATCH] xen_disk: support cache backend option
Stefano Stabellini writes: > On Wed, 26 Jun 2013, Anthony Liguori wrote: >> Stefano Stabellini writes: >> >> > Support a backend option "cache" that specifies the cache mode that >> > should be used to open the disk file or device. >> > >> > See: http://marc.info/?l=xen-devel&m=137226872905057 >> > >> > Signed-off-by: Stefano Stabellini >> >> Is the guest setting this or a management tool? I thought we were >> moving to having the Xen management tools use QMP and the command line >> instead of putting this stuff in XenStore... > > And we are, in fact we have just introduced QMP based cpu hotplug in > libxl for HVM guests, using the existing cpu-add command. > > However this option would be part of the existing block protocol, that > like all the other PV protocols are entirely xenstore based. > I think it makes sense to introduce the cache configuration via xenstore > and make it part of the block interface so that other block backend > (like blkback and blktap) might support it too in the future. Otherwise > it would be a QEMU-only thing and moreover it would be the only block > related configuration for the PV backend to go via QMP when everything > else comes from xenstore. Pretty ugly. Bleck. I really wish we didn't have this logic in QEMU in the first place. I guess since it's already here though, extending it can't hurt. But please try to remove the whole set-things-up-via-Xenstore in the future. It will become a problem at some point as it's a pretty significant layering violation. Maybe the thing to do is move the logic out of the device and into a Xen-specific module that setups the device model based on Xenstore... Anyway, I guess: Acked-by: Anthony Liguori I would not use bdrv_parse_cache_flags since we may add more down the road. Regards, Anthony Liguori > > > >> Regards, >> >> Anthony Liguori >> >> > >> > diff --git a/hw/xen_disk.c b/hw/xen_disk.c >> > index f484404..092aa6b 100644 >> > --- a/hw/block/xen_disk.c >> > +++ b/hw/block/xen_disk.c >> > @@ -94,6 +94,7 @@ struct XenBlkDev { >> > char*type; >> > char*dev; >> > char*devtype; >> > +char*cache; >> > const char *fileproto; >> > const char *filename; >> > int ring_ref; >> > @@ -734,6 +735,12 @@ static int blk_init(struct XenDevice *xendev) >> > if (blkdev->devtype == NULL) { >> > blkdev->devtype = xenstore_read_be_str(&blkdev->xendev, >> > "device-type"); >> > } >> > +if (blkdev->cache == NULL) { >> > +blkdev->cache = xenstore_read_be_str(&blkdev->xendev, "cache"); >> > +} >> > +if (blkdev->cache == NULL) { >> > +blkdev->cache = g_strdup("writeback"); >> > +} >> > >> > /* do we have all we need? */ >> > if (blkdev->params == NULL || >> > @@ -774,6 +781,8 @@ out_error: >> > blkdev->dev = NULL; >> > g_free(blkdev->devtype); >> > blkdev->devtype = NULL; >> > +g_free(blkdev->cache); >> > +blkdev->cache = NULL; >> > return -1; >> > } >> > >> > @@ -782,8 +791,14 @@ static int blk_connect(struct XenDevice *xendev) >> > struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, >> > xendev); >> > int pers, index, qflags; >> > >> > -/* read-only ? */ >> > -qflags = BDRV_O_CACHE_WB | BDRV_O_NATIVE_AIO; >> > +if (!strcmp(blkdev->cache, "none")) { >> > +qflags = BDRV_O_NATIVE_AIO | BDRV_O_NOCACHE; >> > +} else if (!strcmp(blkdev->cache, "writethrough")) { >> > +qflags = 0; >> > +} else { >> > +/* default to writeback */ >> > +qflags = BDRV_O_NATIVE_AIO | BDRV_O_CACHE_WB; >> > +} >> > if (strcmp(blkdev->mode, "w") == 0) { >> > qflags |= BDRV_O_RDWR; >> > } >> > @@ -950,6 +965,7 @@ static int blk_free(struct XenDevice *xendev) >> > g_free(blkdev->type); >> > g_free(blkdev->dev); >> > g_free(blkdev->devtype); >> > +g_free(blkdev->cache); >> > qemu_bh_delete(blkdev->bh); >> > return 0; >> > } >>
Re: [Qemu-devel] [PULL 2/8] i.MX: Implement a more complete version of the GPT timer.
On 06/26/2013 11:18 PM, Paolo Bonzini wrote: Il 26/06/2013 23:13, Jean-Christophe DUBOIS ha scritto: On 06/26/2013 08:58 PM, Jean-Christophe DUBOIS wrote: On 06/26/2013 09:21 AM, Peter Crosthwaite wrote: Hi On Wed, Jun 26, 2013 at 4:56 PM, Paolo Bonzini wrote: Il 25/06/2013 22:53, Peter Maydell ha scritto: On 25 June 2013 19:42, Paolo Bonzini wrote: Il 25/06/2013 20:21, Peter Maydell ha scritto: @@ -416,7 +513,7 @@ static int imx_timerg_init(SysBusDevice *dev) sysbus_init_irq(dev, &s->irq); memory_region_init_io(&s->iomem, &imx_timerg_ops, - s, "imxg-timer", + s, TYPE_IMX_GPT, 0x1000); sysbus_init_mmio(dev, &s->iomem); There was some agreement that this is not a good change. I agree (and more so regarding the use of the macro in the vmstate name), but nobody actually posted any comment to that effect against any of the versions of this patch that got sent out for review... Yeah, the timing was bad... Can you post a revert, though? The original string being replaced was a poor choice as well. IIUC the consensus was string field of the memory regions is supposed to indicate the purpose of the memory region for the device. Good examples would be "Control regs" or "MMIO". Naming the memory region after the device type is a redundancy as that info will come via memory region owners. So rather than revert could you just choose something more descriptive? Peter (Maydell), How do you want to work this out? Do you revert it and we start over? Or should I provide a patch on top of the actual file to change the "wrong name"? Please advise. I browsed through the various timer implementations in the hw/timer directory and I was not able to spot one that would follow the convention you indicated. Could you point me to a "good citizen" example? Here is one example (hw/pci-host/piix.c): memory_region_init_io(&s->conf_mem, &pci_host_conf_le_ops, s, "pci-conf-idx", 4); sysbus_add_io(dev, 0xcf8, &s->conf_mem); sysbus_init_ioports(&s->busdev, 0xcf8, 4); memory_region_init_io(&s->data_mem, &pci_host_data_le_ops, s, "pci-conf-data", 4); sysbus_add_io(dev, 0xcfc, &s->data_mem); sysbus_init_ioports(&s->busdev, 0xcfc, 4); Just reverting the changes to memory regions and vmstate names is enough for now. I tried to change the memory region name for the timer registers to something not prepended wit the device name (I choose "regs") and here is the result in the qemu console (I changes both EPIT and GPT timers). We went from: (qemu) info mtree memory -7ffe (prio 0, RW): system 1fffc000-1fff (prio 0, RW): kzm.sram 43f9-43f90fff (prio 0, RW): imx-serial 43f94000-43f94fff (prio 0, RW): imx-serial 53f8-53f80fff (prio 0, RW): imx_ccm 53f9-53f90fff (prio 0, RW): imx.gpt 53f94000-53f94fff (prio 0, RW): imx.epit 53f98000-53f98fff (prio 0, RW): imx.epit 6800-68000fff (prio 0, RW): imx_avic 8000-83ff (prio 0, RW): kzm.ram 8800-8bff (prio 0, RW): alias ram.alias @kzm.ram -03ff b600-b6ff (prio 0, RW): lan9118-mmio I/O - (prio 0, RW): io aliases kzm.ram 8000-83ff (prio 0, RW): kzm.ram (qemu) to: (qemu) info mtree memory -7ffe (prio 0, RW): system 1fffc000-1fff (prio 0, RW): kzm.sram 43f9-43f90fff (prio 0, RW): imx-serial 43f94000-43f94fff (prio 0, RW): imx-serial 53f8-53f80fff (prio 0, RW): imx_ccm 53f9-53f90fff (prio 0, RW): regs 53f94000-53f94fff (prio 0, RW): regs 53f98000-53f98fff (prio 0, RW): regs 6800-68000fff (prio 0, RW): imx_avic 8000-83ff (prio 0, RW): kzm.ram 8800-8bff (prio 0, RW): alias ram.alias @kzm.ram -03ff b600-b6ff (prio 0, RW): lan9118-mmio I/O - (prio 0, RW): io aliases kzm.ram 8000-83ff (prio 0, RW): kzm.ram (qemu) Names don't feel really useful in the second case as they are indistinguishable. Is the consensus around "generic" names (like MMIO or "Ctrl regs") without adding reference to the device a good one for all platforms? JC Paolo
Re: [Qemu-devel] [PATCH] xen_disk: support cache backend option
On Wed, 26 Jun 2013, Anthony Liguori wrote: > Stefano Stabellini writes: > > > Support a backend option "cache" that specifies the cache mode that > > should be used to open the disk file or device. > > > > See: http://marc.info/?l=xen-devel&m=137226872905057 > > > > Signed-off-by: Stefano Stabellini > > Is the guest setting this or a management tool? I thought we were > moving to having the Xen management tools use QMP and the command line > instead of putting this stuff in XenStore... And we are, in fact we have just introduced QMP based cpu hotplug in libxl for HVM guests, using the existing cpu-add command. However this option would be part of the existing block protocol, that like all the other PV protocols are entirely xenstore based. I think it makes sense to introduce the cache configuration via xenstore and make it part of the block interface so that other block backend (like blkback and blktap) might support it too in the future. Otherwise it would be a QEMU-only thing and moreover it would be the only block related configuration for the PV backend to go via QMP when everything else comes from xenstore. Pretty ugly. > Regards, > > Anthony Liguori > > > > > diff --git a/hw/xen_disk.c b/hw/xen_disk.c > > index f484404..092aa6b 100644 > > --- a/hw/block/xen_disk.c > > +++ b/hw/block/xen_disk.c > > @@ -94,6 +94,7 @@ struct XenBlkDev { > > char*type; > > char*dev; > > char*devtype; > > +char*cache; > > const char *fileproto; > > const char *filename; > > int ring_ref; > > @@ -734,6 +735,12 @@ static int blk_init(struct XenDevice *xendev) > > if (blkdev->devtype == NULL) { > > blkdev->devtype = xenstore_read_be_str(&blkdev->xendev, > > "device-type"); > > } > > +if (blkdev->cache == NULL) { > > +blkdev->cache = xenstore_read_be_str(&blkdev->xendev, "cache"); > > +} > > +if (blkdev->cache == NULL) { > > +blkdev->cache = g_strdup("writeback"); > > +} > > > > /* do we have all we need? */ > > if (blkdev->params == NULL || > > @@ -774,6 +781,8 @@ out_error: > > blkdev->dev = NULL; > > g_free(blkdev->devtype); > > blkdev->devtype = NULL; > > +g_free(blkdev->cache); > > +blkdev->cache = NULL; > > return -1; > > } > > > > @@ -782,8 +791,14 @@ static int blk_connect(struct XenDevice *xendev) > > struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, > > xendev); > > int pers, index, qflags; > > > > -/* read-only ? */ > > -qflags = BDRV_O_CACHE_WB | BDRV_O_NATIVE_AIO; > > +if (!strcmp(blkdev->cache, "none")) { > > +qflags = BDRV_O_NATIVE_AIO | BDRV_O_NOCACHE; > > +} else if (!strcmp(blkdev->cache, "writethrough")) { > > +qflags = 0; > > +} else { > > +/* default to writeback */ > > +qflags = BDRV_O_NATIVE_AIO | BDRV_O_CACHE_WB; > > +} > > if (strcmp(blkdev->mode, "w") == 0) { > > qflags |= BDRV_O_RDWR; > > } > > @@ -950,6 +965,7 @@ static int blk_free(struct XenDevice *xendev) > > g_free(blkdev->type); > > g_free(blkdev->dev); > > g_free(blkdev->devtype); > > +g_free(blkdev->cache); > > qemu_bh_delete(blkdev->bh); > > return 0; > > } >
Re: [Qemu-devel] [PATCH] xen_disk: support cache backend option
On Wed, 26 Jun 2013, Paolo Bonzini wrote: > Il 26/06/2013 19:48, Stefano Stabellini ha scritto: > > +if (!strcmp(blkdev->cache, "none")) { > > +qflags = BDRV_O_NATIVE_AIO | BDRV_O_NOCACHE; > > +} else if (!strcmp(blkdev->cache, "writethrough")) { > > +qflags = 0; > > +} else { > > +/* default to writeback */ > > +qflags = BDRV_O_NATIVE_AIO | BDRV_O_CACHE_WB; > > +} > > You can use bdrv_parse_cache_flags. I didn't want to call to bdrv_parse_cache_flags because the options are slightly different (they are a subset) and they are going to become part of the block interface, so the parsing could diverge in the future. However as of today I could call bdrv_parse_cache_flags and it would work fine. > Note that BDRV_O_NATIVE_AIO > requires BDRV_O_NOCACHE too (but if you only specify BDRV_O_NATIVE_AIO > it's a no-op, not an error). Yeah, good point, I might as well remove it from there.
Re: [Qemu-devel] [PATCH v4 06/10] qemu-ga: Add Windows VSS provider to quiesce applications on fsfreeze
Il 26/06/2013 16:32, Laszlo Ersek ha scritto: >>> >> +#define EVENT_NAME_FROZEN "Global\\QGAVSSEvent-frozen" >>> >> +#define EVENT_NAME_THAW "Global\\QGAVSSEvent-thaw" > No idea what I'm talking about, but since we're qualifying the second > component with the "QGAVSSEvent" prefix, shouldn't we just replace the > first component ("Global") with it? Or would it effect "event routing"? Yes: http://msdn.microsoft.com/en-us/library/windows/desktop/ms684305%28v=vs.85%29.aspx says Terminal Services: The name can have a "Global\" or "Local\" prefix to explicitly open an object in the global or session namespace. The remainder of the name can contain any character except the backslash character (\). For more information, see Kernel Object Namespaces. Paolo
Re: [Qemu-devel] [PULL 2/8] i.MX: Implement a more complete version of the GPT timer.
Il 26/06/2013 23:13, Jean-Christophe DUBOIS ha scritto: > On 06/26/2013 08:58 PM, Jean-Christophe DUBOIS wrote: >> On 06/26/2013 09:21 AM, Peter Crosthwaite wrote: >>> Hi >>> >>> On Wed, Jun 26, 2013 at 4:56 PM, Paolo Bonzini >>> wrote: Il 25/06/2013 22:53, Peter Maydell ha scritto: > On 25 June 2013 19:42, Paolo Bonzini wrote: >> Il 25/06/2013 20:21, Peter Maydell ha scritto: >>> @@ -416,7 +513,7 @@ static int imx_timerg_init(SysBusDevice *dev) >>> >>> sysbus_init_irq(dev, &s->irq); >>> memory_region_init_io(&s->iomem, &imx_timerg_ops, >>> - s, "imxg-timer", >>> + s, TYPE_IMX_GPT, >>> 0x1000); >>> sysbus_init_mmio(dev, &s->iomem); >>> >> There was some agreement that this is not a good change. > I agree (and more so regarding the use of the macro in the > vmstate name), but nobody actually posted any comment to > that effect against any of the versions of this patch that > got sent out for review... Yeah, the timing was bad... Can you post a revert, though? >>> The original string being replaced was a poor choice as well. IIUC the >>> consensus was string field of the memory regions is supposed to >>> indicate the purpose of the memory region for the device. Good >>> examples would be "Control regs" or "MMIO". Naming the memory region >>> after the device type is a redundancy as that info will come via >>> memory region owners. >>> >>> So rather than revert could you just choose something more descriptive? >> Peter (Maydell), >> >> How do you want to work this out? >> >> Do you revert it and we start over? >> >> Or should I provide a patch on top of the actual file to change the >> "wrong name"? >> >> Please advise. > > I browsed through the various timer implementations in the hw/timer > directory and I was not able to spot one that would follow the > convention you indicated. > > Could you point me to a "good citizen" example? Here is one example (hw/pci-host/piix.c): memory_region_init_io(&s->conf_mem, &pci_host_conf_le_ops, s, "pci-conf-idx", 4); sysbus_add_io(dev, 0xcf8, &s->conf_mem); sysbus_init_ioports(&s->busdev, 0xcf8, 4); memory_region_init_io(&s->data_mem, &pci_host_data_le_ops, s, "pci-conf-data", 4); sysbus_add_io(dev, 0xcfc, &s->data_mem); sysbus_init_ioports(&s->busdev, 0xcfc, 4); Just reverting the changes to memory regions and vmstate names is enough for now. Paolo
Re: [Qemu-devel] [PULL 2/8] i.MX: Implement a more complete version of the GPT timer.
On 06/26/2013 08:58 PM, Jean-Christophe DUBOIS wrote: On 06/26/2013 09:21 AM, Peter Crosthwaite wrote: Hi On Wed, Jun 26, 2013 at 4:56 PM, Paolo Bonzini wrote: Il 25/06/2013 22:53, Peter Maydell ha scritto: On 25 June 2013 19:42, Paolo Bonzini wrote: Il 25/06/2013 20:21, Peter Maydell ha scritto: @@ -416,7 +513,7 @@ static int imx_timerg_init(SysBusDevice *dev) sysbus_init_irq(dev, &s->irq); memory_region_init_io(&s->iomem, &imx_timerg_ops, - s, "imxg-timer", + s, TYPE_IMX_GPT, 0x1000); sysbus_init_mmio(dev, &s->iomem); There was some agreement that this is not a good change. I agree (and more so regarding the use of the macro in the vmstate name), but nobody actually posted any comment to that effect against any of the versions of this patch that got sent out for review... Yeah, the timing was bad... Can you post a revert, though? The original string being replaced was a poor choice as well. IIUC the consensus was string field of the memory regions is supposed to indicate the purpose of the memory region for the device. Good examples would be "Control regs" or "MMIO". Naming the memory region after the device type is a redundancy as that info will come via memory region owners. So rather than revert could you just choose something more descriptive? Peter (Maydell), How do you want to work this out? Do you revert it and we start over? Or should I provide a patch on top of the actual file to change the "wrong name"? Please advise. I browsed through the various timer implementations in the hw/timer directory and I was not able to spot one that would follow the convention you indicated. Could you point me to a "good citizen" example? JC JC Regards, Peter Paolo
Re: [Qemu-devel] [PATCH] xen_disk: support cache backend option
Stefano Stabellini writes: > Support a backend option "cache" that specifies the cache mode that > should be used to open the disk file or device. > > See: http://marc.info/?l=xen-devel&m=137226872905057 > > Signed-off-by: Stefano Stabellini Is the guest setting this or a management tool? I thought we were moving to having the Xen management tools use QMP and the command line instead of putting this stuff in XenStore... Regards, Anthony Liguori > > diff --git a/hw/xen_disk.c b/hw/xen_disk.c > index f484404..092aa6b 100644 > --- a/hw/block/xen_disk.c > +++ b/hw/block/xen_disk.c > @@ -94,6 +94,7 @@ struct XenBlkDev { > char*type; > char*dev; > char*devtype; > +char*cache; > const char *fileproto; > const char *filename; > int ring_ref; > @@ -734,6 +735,12 @@ static int blk_init(struct XenDevice *xendev) > if (blkdev->devtype == NULL) { > blkdev->devtype = xenstore_read_be_str(&blkdev->xendev, > "device-type"); > } > +if (blkdev->cache == NULL) { > +blkdev->cache = xenstore_read_be_str(&blkdev->xendev, "cache"); > +} > +if (blkdev->cache == NULL) { > +blkdev->cache = g_strdup("writeback"); > +} > > /* do we have all we need? */ > if (blkdev->params == NULL || > @@ -774,6 +781,8 @@ out_error: > blkdev->dev = NULL; > g_free(blkdev->devtype); > blkdev->devtype = NULL; > +g_free(blkdev->cache); > +blkdev->cache = NULL; > return -1; > } > > @@ -782,8 +791,14 @@ static int blk_connect(struct XenDevice *xendev) > struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, > xendev); > int pers, index, qflags; > > -/* read-only ? */ > -qflags = BDRV_O_CACHE_WB | BDRV_O_NATIVE_AIO; > +if (!strcmp(blkdev->cache, "none")) { > +qflags = BDRV_O_NATIVE_AIO | BDRV_O_NOCACHE; > +} else if (!strcmp(blkdev->cache, "writethrough")) { > +qflags = 0; > +} else { > +/* default to writeback */ > +qflags = BDRV_O_NATIVE_AIO | BDRV_O_CACHE_WB; > +} > if (strcmp(blkdev->mode, "w") == 0) { > qflags |= BDRV_O_RDWR; > } > @@ -950,6 +965,7 @@ static int blk_free(struct XenDevice *xendev) > g_free(blkdev->type); > g_free(blkdev->dev); > g_free(blkdev->devtype); > +g_free(blkdev->cache); > qemu_bh_delete(blkdev->bh); > return 0; > }
[Qemu-devel] [PATCH v2 9/9] tcg-arm: Use AT_PLATFORM to detect the host ISA
With this we can generate armv7 insns even when the OS compiles for a lower common denominator. The macros are arranged so that when we do compile for a given ISA, all of the runtime checks for that ISA are optimized away. Signed-off-by: Richard Henderson --- tcg/arm/tcg-target.c | 22 +- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c index 763b173..a46d2e0 100644 --- a/tcg/arm/tcg-target.c +++ b/tcg/arm/tcg-target.c @@ -41,9 +41,11 @@ # endif #endif -#define use_armv5_instructions (__ARM_ARCH >= 5) -#define use_armv6_instructions (__ARM_ARCH >= 6) -#define use_armv7_instructions (__ARM_ARCH >= 7) +static int arm_arch = __ARM_ARCH; + +#define use_armv5_instructions (__ARM_ARCH >= 5 || arm_arch >= 5) +#define use_armv6_instructions (__ARM_ARCH >= 6 || arm_arch >= 6) +#define use_armv7_instructions (__ARM_ARCH >= 7 || arm_arch >= 7) #ifndef use_idiv_instructions bool use_idiv_instructions; @@ -2022,12 +2024,22 @@ static const TCGTargetOpDef arm_op_defs[] = { static void tcg_target_init(TCGContext *s) { -#if defined(CONFIG_GETAUXVAL) && !defined(use_idiv_instructions) +#if defined(CONFIG_GETAUXVAL) +/* Only probe for the platform and capabilities if we havn't already + determined maximum values at compile time. */ +# if !defined(use_idiv_instructions) { unsigned long hwcap = getauxval(AT_HWCAP); use_idiv_instructions = hwcap & (HWCAP_ARM_IDIVA | HWCAP_ARM_IDIVT); } -#endif +# endif +if (__ARM_ARCH < 7) { +const char *pl = (const char *)getauxval(AT_PLATFORM); +if (pl != NULL && pl[0] == 'v' && pl[1] >= '4' && pl[1] <= '9') { +arm_arch = pl[1] - '0'; +} +} +#endif /* GETAUXVAL */ tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0x); tcg_regset_set32(tcg_target_call_clobber_regs, 0, -- 1.8.1.4
[Qemu-devel] [PATCH v2 8/9] tcg-arm: Simplify logic in detecting the ARM ISA in use
GCC 4.8 defines a handy __ARM_ARCH symbol that we can use, which will make us nicely forward compatible with ARMv8 AArch32. Signed-off-by: Richard Henderson --- tcg/arm/tcg-target.c | 62 +--- 1 file changed, 20 insertions(+), 42 deletions(-) diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c index 2c46ceb..763b173 100644 --- a/tcg/arm/tcg-target.c +++ b/tcg/arm/tcg-target.c @@ -22,50 +22,28 @@ * THE SOFTWARE. */ -#if defined(__ARM_ARCH_7__) || \ -defined(__ARM_ARCH_7A__) || \ -defined(__ARM_ARCH_7EM__) || \ -defined(__ARM_ARCH_7M__) || \ -defined(__ARM_ARCH_7R__) -#define USE_ARMV7_INSTRUCTIONS +/* The __ARM_ARCH define is provided by gcc 4.8. Construct it otherwise. */ +#ifndef __ARM_ARCH +# if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \ + || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \ + || defined(__ARM_ARCH_7EM__) +# define __ARM_ARCH 7 +# elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \ + || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) \ + || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__) +# define __ARM_ARCH 6 +# elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5E__) \ + || defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5TE__) \ + || defined(__ARM_ARCH_5TEJ__) +# define __ARM_ARCH 5 +# else +# define __ARM_ARCH 4 +# endif #endif -#if defined(USE_ARMV7_INSTRUCTIONS) || \ -defined(__ARM_ARCH_6J__) || \ -defined(__ARM_ARCH_6K__) || \ -defined(__ARM_ARCH_6T2__) || \ -defined(__ARM_ARCH_6Z__) || \ -defined(__ARM_ARCH_6ZK__) -#define USE_ARMV6_INSTRUCTIONS -#endif - -#if defined(USE_ARMV6_INSTRUCTIONS) || \ -defined(__ARM_ARCH_5T__) || \ -defined(__ARM_ARCH_5TE__) || \ -defined(__ARM_ARCH_5TEJ__) -#define USE_ARMV5_INSTRUCTIONS -#endif - -#ifdef USE_ARMV5_INSTRUCTIONS -static const int use_armv5_instructions = 1; -#else -static const int use_armv5_instructions = 0; -#endif -#undef USE_ARMV5_INSTRUCTIONS - -#ifdef USE_ARMV6_INSTRUCTIONS -static const int use_armv6_instructions = 1; -#else -static const int use_armv6_instructions = 0; -#endif -#undef USE_ARMV6_INSTRUCTIONS - -#ifdef USE_ARMV7_INSTRUCTIONS -static const int use_armv7_instructions = 1; -#else -static const int use_armv7_instructions = 0; -#endif -#undef USE_ARMV7_INSTRUCTIONS +#define use_armv5_instructions (__ARM_ARCH >= 5) +#define use_armv6_instructions (__ARM_ARCH >= 6) +#define use_armv7_instructions (__ARM_ARCH >= 7) #ifndef use_idiv_instructions bool use_idiv_instructions; -- 1.8.1.4
[Qemu-devel] [PATCH v2 6/9] tcg: Simplify logic using TCG_OPF_NOT_PRESENT
Expand the definition of "not present" to include "should not be present". This means we can simplify the logic surrounding the generic tcg opcodes for which the host backend ought not be providing definitions. Signed-off-by: Richard Henderson --- tcg/tcg-opc.h | 26 +++--- tcg/tcg.c | 4 +--- tcg/tcg.h | 3 ++- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h index c94e255..a8af5b9 100644 --- a/tcg/tcg-opc.h +++ b/tcg/tcg-opc.h @@ -27,17 +27,21 @@ */ /* predefined ops */ -DEF(end, 0, 0, 0, 0) /* must be kept first */ -DEF(nop, 0, 0, 0, 0) -DEF(nop1, 0, 0, 1, 0) -DEF(nop2, 0, 0, 2, 0) -DEF(nop3, 0, 0, 3, 0) -DEF(nopn, 0, 0, 1, 0) /* variable number of parameters */ +DEF(end, 0, 0, 0, TCG_OPF_NOT_PRESENT) /* must be kept first */ +DEF(nop, 0, 0, 0, TCG_OPF_NOT_PRESENT) +DEF(nop1, 0, 0, 1, TCG_OPF_NOT_PRESENT) +DEF(nop2, 0, 0, 2, TCG_OPF_NOT_PRESENT) +DEF(nop3, 0, 0, 3, TCG_OPF_NOT_PRESENT) -DEF(discard, 1, 0, 0, 0) +/* variable number of parameters */ +DEF(nopn, 0, 0, 1, TCG_OPF_NOT_PRESENT) + +DEF(discard, 1, 0, 0, TCG_OPF_NOT_PRESENT) +DEF(set_label, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_NOT_PRESENT) + +/* variable number of parameters */ +DEF(call, 0, 1, 2, TCG_OPF_CALL_CLOBBER) -DEF(set_label, 0, 0, 1, TCG_OPF_BB_END) -DEF(call, 0, 1, 2, TCG_OPF_CALL_CLOBBER) /* variable number of parameters */ DEF(br, 0, 0, 1, TCG_OPF_BB_END) #define IMPL(X) (__builtin_constant_p(X) && !(X) ? TCG_OPF_NOT_PRESENT : 0) @@ -166,9 +170,9 @@ DEF(muls2_i64, 2, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_muls2_i64)) /* QEMU specific */ #if TARGET_LONG_BITS > TCG_TARGET_REG_BITS -DEF(debug_insn_start, 0, 0, 2, 0) +DEF(debug_insn_start, 0, 0, 2, TCG_OPF_NOT_PRESENT) #else -DEF(debug_insn_start, 0, 0, 1, 0) +DEF(debug_insn_start, 0, 0, 1, TCG_OPF_NOT_PRESENT) #endif DEF(exit_tb, 0, 0, 1, TCG_OPF_BB_END) DEF(goto_tb, 0, 0, 1, TCG_OPF_BB_END) diff --git a/tcg/tcg.c b/tcg/tcg.c index 1d8099c..c7e6567 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -1160,9 +1160,7 @@ void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs) i = 0; for (op = 0; op < ARRAY_SIZE(tcg_op_defs); op++) { const TCGOpDef *def = &tcg_op_defs[op]; -if (op < INDEX_op_call -|| op == INDEX_op_debug_insn_start -|| (def->flags & TCG_OPF_NOT_PRESENT)) { +if (def->flags & TCG_OPF_NOT_PRESENT) { /* Wrong entry in op definitions? */ if (def->used) { fprintf(stderr, "Invalid op definition for %s\n", def->name); diff --git a/tcg/tcg.h b/tcg/tcg.h index 28ca1bd..f3f9889 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -596,7 +596,8 @@ enum { TCG_OPF_SIDE_EFFECTS = 0x04, /* Instruction operands are 64-bits (otherwise 32-bits). */ TCG_OPF_64BIT= 0x08, -/* Instruction is optional and not implemented by the host. */ +/* Instruction is optional and not implemented by the host, or insn + is generic and should not be implemened by the host. */ TCG_OPF_NOT_PRESENT = 0x10, }; -- 1.8.1.4
[Qemu-devel] [PATCH v2 7/9] tcg-arm: Make use of conditional availability of opcodes for divide
We can now detect and use divide instructions at runtime, rather than having to restrict their availability to compile-time. Signed-off-by: Richard Henderson --- tcg/arm/tcg-target.c | 16 ++-- tcg/arm/tcg-target.h | 14 -- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c index 8321f80..2c46ceb 100644 --- a/tcg/arm/tcg-target.c +++ b/tcg/arm/tcg-target.c @@ -67,6 +67,13 @@ static const int use_armv7_instructions = 0; #endif #undef USE_ARMV7_INSTRUCTIONS +#ifndef use_idiv_instructions +bool use_idiv_instructions; +#endif +#ifdef CONFIG_GETAUXVAL +# include +#endif + #ifndef NDEBUG static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = { "%r0", @@ -2029,16 +2036,21 @@ static const TCGTargetOpDef arm_op_defs[] = { { INDEX_op_deposit_i32, { "r", "0", "rZ" } }, -#if TCG_TARGET_HAS_div_i32 { INDEX_op_div_i32, { "r", "r", "r" } }, { INDEX_op_divu_i32, { "r", "r", "r" } }, -#endif { -1 }, }; static void tcg_target_init(TCGContext *s) { +#if defined(CONFIG_GETAUXVAL) && !defined(use_idiv_instructions) +{ +unsigned long hwcap = getauxval(AT_HWCAP); +use_idiv_instructions = hwcap & (HWCAP_ARM_IDIVA | HWCAP_ARM_IDIVT); +} +#endif + tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0x); tcg_regset_set32(tcg_target_call_clobber_regs, 0, (1 << TCG_REG_R0) | diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h index 263ea03..5cd9d6a 100644 --- a/tcg/arm/tcg-target.h +++ b/tcg/arm/tcg-target.h @@ -49,6 +49,13 @@ typedef enum { #define TCG_TARGET_NB_REGS 16 +#ifdef __ARM_ARCH_EXT_IDIV__ +#define use_idiv_instructions 1 +#else +extern bool use_idiv_instructions; +#endif + + /* used for function call generation */ #define TCG_REG_CALL_STACK TCG_REG_R13 #define TCG_TARGET_STACK_ALIGN 8 @@ -73,12 +80,7 @@ typedef enum { #define TCG_TARGET_HAS_deposit_i32 1 #define TCG_TARGET_HAS_movcond_i32 1 #define TCG_TARGET_HAS_muls2_i321 - -#ifdef __ARM_ARCH_EXT_IDIV__ -#define TCG_TARGET_HAS_div_i32 1 -#else -#define TCG_TARGET_HAS_div_i32 0 -#endif +#define TCG_TARGET_HAS_div_i32 use_idiv_instructions #define TCG_TARGET_HAS_rem_i32 0 extern bool tcg_target_deposit_valid(int ofs, int len); -- 1.8.1.4
[Qemu-devel] [PATCH v2 2/9] tcg-arm: Don't implement rem
Signed-off-by: Richard Henderson --- tcg/arm/tcg-target.c | 14 -- tcg/arm/tcg-target.h | 3 +-- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c index 6be736b..8321f80 100644 --- a/tcg/arm/tcg-target.c +++ b/tcg/arm/tcg-target.c @@ -1926,18 +1926,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_divu_i32: tcg_out_udiv(s, COND_AL, args[0], args[1], args[2]); break; -case INDEX_op_rem_i32: -tcg_out_sdiv(s, COND_AL, TCG_REG_TMP, args[1], args[2]); -tcg_out_mul32(s, COND_AL, TCG_REG_TMP, TCG_REG_TMP, args[2]); -tcg_out_dat_reg(s, COND_AL, ARITH_SUB, args[0], args[1], TCG_REG_TMP, -SHIFT_IMM_LSL(0)); -break; -case INDEX_op_remu_i32: -tcg_out_udiv(s, COND_AL, TCG_REG_TMP, args[1], args[2]); -tcg_out_mul32(s, COND_AL, TCG_REG_TMP, TCG_REG_TMP, args[2]); -tcg_out_dat_reg(s, COND_AL, ARITH_SUB, args[0], args[1], TCG_REG_TMP, -SHIFT_IMM_LSL(0)); -break; default: tcg_abort(); @@ -2043,9 +2031,7 @@ static const TCGTargetOpDef arm_op_defs[] = { #if TCG_TARGET_HAS_div_i32 { INDEX_op_div_i32, { "r", "r", "r" } }, -{ INDEX_op_rem_i32, { "r", "r", "r" } }, { INDEX_op_divu_i32, { "r", "r", "r" } }, -{ INDEX_op_remu_i32, { "r", "r", "r" } }, #endif { -1 }, diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h index 2c5b4e7..263ea03 100644 --- a/tcg/arm/tcg-target.h +++ b/tcg/arm/tcg-target.h @@ -76,11 +76,10 @@ typedef enum { #ifdef __ARM_ARCH_EXT_IDIV__ #define TCG_TARGET_HAS_div_i32 1 -#define TCG_TARGET_HAS_rem_i32 1 #else #define TCG_TARGET_HAS_div_i32 0 -#define TCG_TARGET_HAS_rem_i32 0 #endif +#define TCG_TARGET_HAS_rem_i32 0 extern bool tcg_target_deposit_valid(int ofs, int len); #define TCG_TARGET_deposit_i32_valid tcg_target_deposit_valid -- 1.8.1.4
[Qemu-devel] [PATCH v2 4/9] tcg-ppc64: Don't implement rem
Signed-off-by: Richard Henderson --- tcg/ppc64/tcg-target.c | 26 -- tcg/ppc64/tcg-target.h | 4 ++-- 2 files changed, 2 insertions(+), 28 deletions(-) diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c index 606b73d..0678de2 100644 --- a/tcg/ppc64/tcg-target.c +++ b/tcg/ppc64/tcg-target.c @@ -1617,18 +1617,6 @@ static void tcg_out_op (TCGContext *s, TCGOpcode opc, const TCGArg *args, tcg_out32 (s, DIVWU | TAB (args[0], args[1], args[2])); break; -case INDEX_op_rem_i32: -tcg_out32 (s, DIVW | TAB (0, args[1], args[2])); -tcg_out32 (s, MULLW | TAB (0, 0, args[2])); -tcg_out32 (s, SUBF | TAB (args[0], 0, args[1])); -break; - -case INDEX_op_remu_i32: -tcg_out32 (s, DIVWU | TAB (0, args[1], args[2])); -tcg_out32 (s, MULLW | TAB (0, 0, args[2])); -tcg_out32 (s, SUBF | TAB (args[0], 0, args[1])); -break; - case INDEX_op_shl_i32: if (const_args[2]) { tcg_out_rlw(s, RLWINM, args[0], args[1], args[2], 0, 31 - args[2]); @@ -1786,16 +1774,6 @@ static void tcg_out_op (TCGContext *s, TCGOpcode opc, const TCGArg *args, case INDEX_op_divu_i64: tcg_out32 (s, DIVDU | TAB (args[0], args[1], args[2])); break; -case INDEX_op_rem_i64: -tcg_out32 (s, DIVD | TAB (0, args[1], args[2])); -tcg_out32 (s, MULLD | TAB (0, 0, args[2])); -tcg_out32 (s, SUBF | TAB (args[0], 0, args[1])); -break; -case INDEX_op_remu_i64: -tcg_out32 (s, DIVDU | TAB (0, args[1], args[2])); -tcg_out32 (s, MULLD | TAB (0, 0, args[2])); -tcg_out32 (s, SUBF | TAB (args[0], 0, args[1])); -break; case INDEX_op_qemu_ld8u: tcg_out_qemu_ld (s, args, 0); @@ -2064,8 +2042,6 @@ static const TCGTargetOpDef ppc_op_defs[] = { { INDEX_op_mul_i32, { "r", "r", "rI" } }, { INDEX_op_div_i32, { "r", "r", "r" } }, { INDEX_op_divu_i32, { "r", "r", "r" } }, -{ INDEX_op_rem_i32, { "r", "r", "r" } }, -{ INDEX_op_remu_i32, { "r", "r", "r" } }, { INDEX_op_sub_i32, { "r", "rI", "ri" } }, { INDEX_op_and_i32, { "r", "r", "ri" } }, { INDEX_op_or_i32, { "r", "r", "ri" } }, @@ -2108,8 +2084,6 @@ static const TCGTargetOpDef ppc_op_defs[] = { { INDEX_op_mul_i64, { "r", "r", "rI" } }, { INDEX_op_div_i64, { "r", "r", "r" } }, { INDEX_op_divu_i64, { "r", "r", "r" } }, -{ INDEX_op_rem_i64, { "r", "r", "r" } }, -{ INDEX_op_remu_i64, { "r", "r", "r" } }, { INDEX_op_neg_i64, { "r", "r" } }, { INDEX_op_not_i64, { "r", "r" } }, diff --git a/tcg/ppc64/tcg-target.h b/tcg/ppc64/tcg-target.h index 7c600f1..48fc6e2 100644 --- a/tcg/ppc64/tcg-target.h +++ b/tcg/ppc64/tcg-target.h @@ -76,7 +76,7 @@ typedef enum { /* optional instructions */ #define TCG_TARGET_HAS_div_i32 1 -#define TCG_TARGET_HAS_rem_i32 1 +#define TCG_TARGET_HAS_rem_i32 0 #define TCG_TARGET_HAS_rot_i32 1 #define TCG_TARGET_HAS_ext8s_i321 #define TCG_TARGET_HAS_ext16s_i32 1 @@ -97,7 +97,7 @@ typedef enum { #define TCG_TARGET_HAS_muls2_i320 #define TCG_TARGET_HAS_div_i64 1 -#define TCG_TARGET_HAS_rem_i64 1 +#define TCG_TARGET_HAS_rem_i64 0 #define TCG_TARGET_HAS_rot_i64 1 #define TCG_TARGET_HAS_ext8s_i641 #define TCG_TARGET_HAS_ext16s_i64 1 -- 1.8.1.4
Re: [Qemu-devel] [PATCH] xen_disk: support cache backend option
Il 26/06/2013 19:48, Stefano Stabellini ha scritto: > +if (!strcmp(blkdev->cache, "none")) { > +qflags = BDRV_O_NATIVE_AIO | BDRV_O_NOCACHE; > +} else if (!strcmp(blkdev->cache, "writethrough")) { > +qflags = 0; > +} else { > +/* default to writeback */ > +qflags = BDRV_O_NATIVE_AIO | BDRV_O_CACHE_WB; > +} You can use bdrv_parse_cache_flags. Note that BDRV_O_NATIVE_AIO requires BDRV_O_NOCACHE too (but if you only specify BDRV_O_NATIVE_AIO it's a no-op, not an error). Paolo
[Qemu-devel] [PATCH v2 1/9] tcg: Split rem requirement from div requirement
There are several hosts with only a "div" insn. Remainder is computed manually from the quotient and inputs. We can do this generically. Signed-off-by: Richard Henderson --- tcg/arm/tcg-target.h | 2 ++ tcg/hppa/tcg-target.h | 1 + tcg/ia64/tcg-target.h | 2 ++ tcg/mips/tcg-target.h | 1 + tcg/ppc/tcg-target.h | 1 + tcg/ppc64/tcg-target.h | 2 ++ tcg/sparc/tcg-target.h | 2 ++ tcg/tcg-op.h | 32 tcg/tcg-opc.h | 8 tcg/tcg.h | 3 +++ tcg/tci/tcg-target.h | 2 ++ 11 files changed, 48 insertions(+), 8 deletions(-) diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h index 3be41cc..2c5b4e7 100644 --- a/tcg/arm/tcg-target.h +++ b/tcg/arm/tcg-target.h @@ -76,8 +76,10 @@ typedef enum { #ifdef __ARM_ARCH_EXT_IDIV__ #define TCG_TARGET_HAS_div_i32 1 +#define TCG_TARGET_HAS_rem_i32 1 #else #define TCG_TARGET_HAS_div_i32 0 +#define TCG_TARGET_HAS_rem_i32 0 #endif extern bool tcg_target_deposit_valid(int ofs, int len); diff --git a/tcg/hppa/tcg-target.h b/tcg/hppa/tcg-target.h index ebd53d9..25467bd 100644 --- a/tcg/hppa/tcg-target.h +++ b/tcg/hppa/tcg-target.h @@ -85,6 +85,7 @@ typedef enum { /* optional instructions */ #define TCG_TARGET_HAS_div_i32 0 +#define TCG_TARGET_HAS_rem_i32 0 #define TCG_TARGET_HAS_rot_i32 1 #define TCG_TARGET_HAS_ext8s_i321 #define TCG_TARGET_HAS_ext16s_i32 1 diff --git a/tcg/ia64/tcg-target.h b/tcg/ia64/tcg-target.h index e3d72ea..f32d519 100644 --- a/tcg/ia64/tcg-target.h +++ b/tcg/ia64/tcg-target.h @@ -104,7 +104,9 @@ typedef enum { /* optional instructions */ #define TCG_TARGET_HAS_div_i32 0 +#define TCG_TARGET_HAS_rem_i32 0 #define TCG_TARGET_HAS_div_i64 0 +#define TCG_TARGET_HAS_rem_i64 0 #define TCG_TARGET_HAS_andc_i32 1 #define TCG_TARGET_HAS_andc_i64 1 #define TCG_TARGET_HAS_bswap16_i32 1 diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h index 6155327..a438950 100644 --- a/tcg/mips/tcg-target.h +++ b/tcg/mips/tcg-target.h @@ -79,6 +79,7 @@ typedef enum { /* optional instructions */ #define TCG_TARGET_HAS_div_i32 1 +#define TCG_TARGET_HAS_rem_i32 1 #define TCG_TARGET_HAS_not_i32 1 #define TCG_TARGET_HAS_nor_i32 1 #define TCG_TARGET_HAS_ext8s_i321 diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h index 17a6bb3..01b880e 100644 --- a/tcg/ppc/tcg-target.h +++ b/tcg/ppc/tcg-target.h @@ -78,6 +78,7 @@ typedef enum { /* optional instructions */ #define TCG_TARGET_HAS_div_i32 1 +#define TCG_TARGET_HAS_rem_i32 1 #define TCG_TARGET_HAS_rot_i32 1 #define TCG_TARGET_HAS_ext8s_i321 #define TCG_TARGET_HAS_ext16s_i32 1 diff --git a/tcg/ppc64/tcg-target.h b/tcg/ppc64/tcg-target.h index cb77634..7c600f1 100644 --- a/tcg/ppc64/tcg-target.h +++ b/tcg/ppc64/tcg-target.h @@ -76,6 +76,7 @@ typedef enum { /* optional instructions */ #define TCG_TARGET_HAS_div_i32 1 +#define TCG_TARGET_HAS_rem_i32 1 #define TCG_TARGET_HAS_rot_i32 1 #define TCG_TARGET_HAS_ext8s_i321 #define TCG_TARGET_HAS_ext16s_i32 1 @@ -96,6 +97,7 @@ typedef enum { #define TCG_TARGET_HAS_muls2_i320 #define TCG_TARGET_HAS_div_i64 1 +#define TCG_TARGET_HAS_rem_i64 1 #define TCG_TARGET_HAS_rot_i64 1 #define TCG_TARGET_HAS_ext8s_i641 #define TCG_TARGET_HAS_ext16s_i64 1 diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h index b5217be..dab52d7 100644 --- a/tcg/sparc/tcg-target.h +++ b/tcg/sparc/tcg-target.h @@ -86,6 +86,7 @@ typedef enum { /* optional instructions */ #define TCG_TARGET_HAS_div_i32 1 +#define TCG_TARGET_HAS_rem_i32 1 #define TCG_TARGET_HAS_rot_i32 0 #define TCG_TARGET_HAS_ext8s_i320 #define TCG_TARGET_HAS_ext16s_i32 0 @@ -109,6 +110,7 @@ typedef enum { #if TCG_TARGET_REG_BITS == 64 #define TCG_TARGET_HAS_div_i64 1 +#define TCG_TARGET_HAS_rem_i64 1 #define TCG_TARGET_HAS_rot_i64 0 #define TCG_TARGET_HAS_ext8s_i640 #define TCG_TARGET_HAS_ext16s_i64 0 diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h index 94f6043..364964d 100644 --- a/tcg/tcg-op.h +++ b/tcg/tcg-op.h @@ -731,8 +731,14 @@ static inline void tcg_gen_div_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) static inline void tcg_gen_rem_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) { -if (TCG_TARGET_HAS_div_i32) { +if (TCG_TARGET_HAS_rem_i32) { tcg_gen_op3_i32(INDEX_op_rem_i32, ret, arg1, arg2); +} else if (TCG_TARGET_HAS_div_i32) { +TCGv_i32 t0 = tcg_temp_new_i32(); +tcg_gen_op3_i32(INDEX_op_div_i32, t0, arg1, arg2); +tcg_gen_mul_i32(t0, t0, arg2); +tcg_gen_sub_i32(ret, arg1, t0); +tcg_temp_free_i32(t0); } else if (TCG_TARGET_HAS_div2
[Qemu-devel] [PATCH v2 3/9] tcg-ppc: Don't implement rem
Signed-off-by: Richard Henderson --- tcg/ppc/tcg-target.c | 14 -- tcg/ppc/tcg-target.h | 2 +- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c index 29ca934..453ab6b 100644 --- a/tcg/ppc/tcg-target.c +++ b/tcg/ppc/tcg-target.c @@ -1671,18 +1671,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args, tcg_out32 (s, DIVWU | TAB (args[0], args[1], args[2])); break; -case INDEX_op_rem_i32: -tcg_out32 (s, DIVW | TAB (0, args[1], args[2])); -tcg_out32 (s, MULLW | TAB (0, 0, args[2])); -tcg_out32 (s, SUBF | TAB (args[0], 0, args[1])); -break; - -case INDEX_op_remu_i32: -tcg_out32 (s, DIVWU | TAB (0, args[1], args[2])); -tcg_out32 (s, MULLW | TAB (0, 0, args[2])); -tcg_out32 (s, SUBF | TAB (args[0], 0, args[1])); -break; - case INDEX_op_mulu2_i32: if (args[0] == args[2] || args[0] == args[3]) { tcg_out32 (s, MULLW | TAB (0, args[2], args[3])); @@ -1992,8 +1980,6 @@ static const TCGTargetOpDef ppc_op_defs[] = { { INDEX_op_mul_i32, { "r", "r", "ri" } }, { INDEX_op_div_i32, { "r", "r", "r" } }, { INDEX_op_divu_i32, { "r", "r", "r" } }, -{ INDEX_op_rem_i32, { "r", "r", "r" } }, -{ INDEX_op_remu_i32, { "r", "r", "r" } }, { INDEX_op_mulu2_i32, { "r", "r", "r", "r" } }, { INDEX_op_sub_i32, { "r", "r", "ri" } }, { INDEX_op_and_i32, { "r", "r", "ri" } }, diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h index 01b880e..b42d97c 100644 --- a/tcg/ppc/tcg-target.h +++ b/tcg/ppc/tcg-target.h @@ -78,7 +78,7 @@ typedef enum { /* optional instructions */ #define TCG_TARGET_HAS_div_i32 1 -#define TCG_TARGET_HAS_rem_i32 1 +#define TCG_TARGET_HAS_rem_i32 0 #define TCG_TARGET_HAS_rot_i32 1 #define TCG_TARGET_HAS_ext8s_i321 #define TCG_TARGET_HAS_ext16s_i32 1 -- 1.8.1.4
[Qemu-devel] [PATCH v2 0/9] tcg: remainder and arm runtime detection
This patch set includes both the remainder series and arm runtime detection series that I've previouslyt posted separately, as there are small conflicts between the two series. Aside from rebasing vs master, the only other change is to fix the TCG_OPF_NOT_PRESENT problem wrt call that Claudio Fontana spotted. r~ Richard Henderson (9): tcg: Split rem requirement from div requirement tcg-arm: Don't implement rem tcg-ppc: Don't implement rem tcg-ppc64: Don't implement rem tcg: Allow non-constant control macros tcg: Simplify logic using TCG_OPF_NOT_PRESENT tcg-arm: Make use of conditional availability of opcodes for divide tcg-arm: Simplify logic in detecting the ARM ISA in use tcg-arm: Use AT_PLATFORM to detect the host ISA tcg/arm/tcg-target.c | 96 ++ tcg/arm/tcg-target.h | 15 tcg/hppa/tcg-target.h | 1 + tcg/ia64/tcg-target.h | 2 ++ tcg/mips/tcg-target.h | 1 + tcg/ppc/tcg-target.c | 14 tcg/ppc/tcg-target.h | 1 + tcg/ppc64/tcg-target.c | 26 -- tcg/ppc64/tcg-target.h | 2 ++ tcg/sparc/tcg-target.h | 2 ++ tcg/tcg-op.h | 32 ++--- tcg/tcg-opc.h | 36 ++- tcg/tcg.c | 4 +-- tcg/tcg.h | 6 +++- tcg/tci/tcg-target.h | 2 ++ 15 files changed, 116 insertions(+), 124 deletions(-) -- 1.8.1.4
[Qemu-devel] [PATCH v2 5/9] tcg: Allow non-constant control macros
This allows TCG_TARGET_HAS_* to be a variable rather than a constant, which allows easier support for differing ISA levels for the host. Signed-off-by: Richard Henderson --- tcg/tcg-opc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h index 12967fb..c94e255 100644 --- a/tcg/tcg-opc.h +++ b/tcg/tcg-opc.h @@ -40,7 +40,7 @@ DEF(set_label, 0, 0, 1, TCG_OPF_BB_END) DEF(call, 0, 1, 2, TCG_OPF_CALL_CLOBBER) /* variable number of parameters */ DEF(br, 0, 0, 1, TCG_OPF_BB_END) -#define IMPL(X) (X ? 0 : TCG_OPF_NOT_PRESENT) +#define IMPL(X) (__builtin_constant_p(X) && !(X) ? TCG_OPF_NOT_PRESENT : 0) #if TCG_TARGET_REG_BITS == 32 # define IMPL64 TCG_OPF_64BIT | TCG_OPF_NOT_PRESENT #else -- 1.8.1.4
Re: [Qemu-devel] [Xen-devel] [PATCH] Add Xen platform PCI device version 2.
--On 26 June 2013 12:06:31 + Paul Durrant wrote: The issue is the old s/w not the new s/w. The old drivers make assumptions about each other's presence as we can't change that because they are already out there. Then (without knowing the details) what's to prevent the new drivers not making such assumptions, and carrying some versioning information, such that we need one new PCI device now, but no more in the future? -- Alex Bligh
Re: [Qemu-devel] [PATCH v11 14/15] rdma: introduce MIG_STATE_NONE and change MIG_STATE_SETUP state transition
On 06/26/2013 10:57 AM, Paolo Bonzini wrote: Il 26/06/2013 16:09, Michael R. Hines ha scritto: *This requires some steps:* 1. First, maintain a new data structure: something like "These memory ranges are 'being unpinned'" - block all potential writes to these addresses until the unpinning completes. 2. Once the source unpin completes, send the asynchronous control channel message to the other side for unpinning. 2. Mark the data structure and return and allow the migration to continue with the next RDMA write. 3. Upon completion of the unpinning on the destination, respond to the source that it was finished. 4. Source then clears the data structure for the successfully unpinned memory ranges. 5. At this point, one or more writes may (or may not) be blocking on the unpinned memory areas and will poll the data structure and find that the unpinning has completed. 6. Then issue the new writes and proceed as normal. 7. Repeat step 1. After more discussion on IRC I think I understand this. It's not trivial, but not super-complex either... it would really be nice to add it to the protocol already in 1.6. Paolo I will submit this as a brand new patch series. I'm working on it right now. - Michael
Re: [Qemu-devel] [PULL 2/8] i.MX: Implement a more complete version of the GPT timer.
On 06/26/2013 09:21 AM, Peter Crosthwaite wrote: Hi On Wed, Jun 26, 2013 at 4:56 PM, Paolo Bonzini wrote: Il 25/06/2013 22:53, Peter Maydell ha scritto: On 25 June 2013 19:42, Paolo Bonzini wrote: Il 25/06/2013 20:21, Peter Maydell ha scritto: @@ -416,7 +513,7 @@ static int imx_timerg_init(SysBusDevice *dev) sysbus_init_irq(dev, &s->irq); memory_region_init_io(&s->iomem, &imx_timerg_ops, - s, "imxg-timer", + s, TYPE_IMX_GPT, 0x1000); sysbus_init_mmio(dev, &s->iomem); There was some agreement that this is not a good change. I agree (and more so regarding the use of the macro in the vmstate name), but nobody actually posted any comment to that effect against any of the versions of this patch that got sent out for review... Yeah, the timing was bad... Can you post a revert, though? The original string being replaced was a poor choice as well. IIUC the consensus was string field of the memory regions is supposed to indicate the purpose of the memory region for the device. Good examples would be "Control regs" or "MMIO". Naming the memory region after the device type is a redundancy as that info will come via memory region owners. So rather than revert could you just choose something more descriptive? Peter (Maydell), How do you want to work this out? Do you revert it and we start over? Or should I provide a patch on top of the actual file to change the "wrong name"? Please advise. JC Regards, Peter Paolo
[Qemu-devel] qemu-img create encryption
I've been doing some work with qemu-img and encrypted qcow2 images and have noticed that "qemu-img create" does not prompt for a password to encrypt new images, defaulting (from the documentation I've read) to the empty string as a password. Why does "qemu-img create" work this way? I haven't been able to find any good, authoritative sources on this topic, so if anyone knows of good documentation or rationale, please let me know. Thanks in advance, Peter H. smime.p7s Description: S/MIME cryptographic signature
[Qemu-devel] [PATCH qom-cpu v3 14/14] target-i386: Don't overuse CPUArchState
Use CPUX86State instead in dump support code. Signed-off-by: Andreas Färber --- target-i386/arch_dump.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/target-i386/arch_dump.c b/target-i386/arch_dump.c index d133228..10dc228 100644 --- a/target-i386/arch_dump.c +++ b/target-i386/arch_dump.c @@ -35,7 +35,7 @@ typedef struct { } x86_64_elf_prstatus; static int x86_64_write_elf64_note(WriteCoreDumpFunction f, - CPUArchState *env, int id, + CPUX86State *env, int id, void *opaque) { x86_64_user_regs_struct regs; @@ -119,7 +119,7 @@ typedef struct { char pad3[4]; } x86_elf_prstatus; -static void x86_fill_elf_prstatus(x86_elf_prstatus *prstatus, CPUArchState *env, +static void x86_fill_elf_prstatus(x86_elf_prstatus *prstatus, CPUX86State *env, int id) { memset(prstatus, 0, sizeof(x86_elf_prstatus)); @@ -144,7 +144,7 @@ static void x86_fill_elf_prstatus(x86_elf_prstatus *prstatus, CPUArchState *env, prstatus->pid = id; } -static int x86_write_elf64_note(WriteCoreDumpFunction f, CPUArchState *env, +static int x86_write_elf64_note(WriteCoreDumpFunction f, CPUX86State *env, int id, void *opaque) { x86_elf_prstatus prstatus; @@ -274,7 +274,7 @@ static void copy_segment(QEMUCPUSegment *d, SegmentCache *s) d->base = s->base; } -static void qemu_get_cpustate(QEMUCPUState *s, CPUArchState *env) +static void qemu_get_cpustate(QEMUCPUState *s, CPUX86State *env) { memset(s, 0, sizeof(QEMUCPUState)); @@ -321,7 +321,7 @@ static void qemu_get_cpustate(QEMUCPUState *s, CPUArchState *env) } static inline int cpu_write_qemu_note(WriteCoreDumpFunction f, - CPUArchState *env, + CPUX86State *env, void *opaque, int type) { -- 1.8.1.4
[Qemu-devel] [PATCH qom-cpu v3 12/14] target-s390x: Don't overuse ENV_GET_CPU()
Commit 3474b679486caa8f6448bae974e131370f360c13 (Utilize selective runtime reg sync for hot code paths) introduced two uses of ENV_GET_CPU() inside target-s390x/ KVM code. In one case we can use a direct CPU() cast instead. Cc: Jason J. Herne Signed-off-by: Andreas Färber --- target-s390x/kvm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c index b524c35..4660074 100644 --- a/target-s390x/kvm.c +++ b/target-s390x/kvm.c @@ -469,7 +469,7 @@ static int kvm_handle_css_inst(S390CPU *cpu, struct kvm_run *run, int r = 0; int no_cc = 0; CPUS390XState *env = &cpu->env; -CPUState *cs = ENV_GET_CPU(env); +CPUState *cs = CPU(cpu); if (ipa0 != 0xb2) { /* Not handled for now. */ -- 1.8.1.4
[Qemu-devel] [PATCH qom-cpu v3 10/14] timer/arm_mptimer: Build arm_mptimer only once
Since current_cpu is CPUState it no longer depends on CPUArchState. Signed-off-by: Andreas Färber --- hw/timer/Makefile.objs | 2 +- hw/timer/arm_mptimer.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs index 32b5c1a..eca5905 100644 --- a/hw/timer/Makefile.objs +++ b/hw/timer/Makefile.objs @@ -1,4 +1,5 @@ common-obj-$(CONFIG_ARM_TIMER) += arm_timer.o +common-obj-$(CONFIG_ARM_MPTIMER) += arm_mptimer.o common-obj-$(CONFIG_CADENCE) += cadence_ttc.o common-obj-$(CONFIG_DS1338) += ds1338.o common-obj-$(CONFIG_HPET) += hpet.o @@ -25,5 +26,4 @@ obj-$(CONFIG_PXA2XX) += pxa2xx_timer.o obj-$(CONFIG_SH4) += sh_timer.o obj-$(CONFIG_TUSB6010) += tusb6010.o -obj-$(CONFIG_ARM_MPTIMER) += arm_mptimer.o obj-$(CONFIG_MC146818RTC) += mc146818rtc.o diff --git a/hw/timer/arm_mptimer.c b/hw/timer/arm_mptimer.c index 6e817f3..38933b6 100644 --- a/hw/timer/arm_mptimer.c +++ b/hw/timer/arm_mptimer.c @@ -21,6 +21,7 @@ #include "hw/sysbus.h" #include "qemu/timer.h" +#include "qom/cpu.h" /* This device implements the per-cpu private timer and watchdog block * which is used in both the ARM11MPCore and Cortex-A9MP. -- 1.8.1.4
[Qemu-devel] [PATCH qom-cpu v3 04/14] linux-user: Clean up do_syscall() Coding Style for TARGET_NR_exit
In particular fix 6-/10-char indentation. Signed-off-by: Andreas Färber --- linux-user/syscall.c | 73 ++-- 1 file changed, 37 insertions(+), 36 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index cdd0c28..a2125fa 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5044,42 +5044,43 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, switch(num) { case TARGET_NR_exit: #ifdef CONFIG_USE_NPTL - /* In old applications this may be used to implement _exit(2). - However in threaded applictions it is used for thread termination, - and _exit_group is used for application termination. - Do thread termination if we have more then one thread. */ - /* FIXME: This probably breaks if a signal arrives. We should probably - be disabling signals. */ - if (first_cpu->next_cpu) { - TaskState *ts; - CPUArchState **lastp; - CPUArchState *p; - - cpu_list_lock(); - lastp = &first_cpu; - p = first_cpu; - while (p && p != (CPUArchState *)cpu_env) { - lastp = &p->next_cpu; - p = p->next_cpu; - } - /* If we didn't find the CPU for this thread then something is - horribly wrong. */ - if (!p) - abort(); - /* Remove the CPU from the list. */ - *lastp = p->next_cpu; - cpu_list_unlock(); - ts = ((CPUArchState *)cpu_env)->opaque; - if (ts->child_tidptr) { - put_user_u32(0, ts->child_tidptr); - sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX, -NULL, NULL, 0); - } - thread_env = NULL; - object_unref(OBJECT(ENV_GET_CPU(cpu_env))); - g_free(ts); - pthread_exit(NULL); - } +/* In old applications this may be used to implement _exit(2). + However in threaded applictions it is used for thread termination, + and _exit_group is used for application termination. + Do thread termination if we have more then one thread. */ +/* FIXME: This probably breaks if a signal arrives. We should probably + be disabling signals. */ +if (first_cpu->next_cpu) { +TaskState *ts; +CPUArchState **lastp; +CPUArchState *p; + +cpu_list_lock(); +lastp = &first_cpu; +p = first_cpu; +while (p && p != (CPUArchState *)cpu_env) { +lastp = &p->next_cpu; +p = p->next_cpu; +} +/* If we didn't find the CPU for this thread then something is + horribly wrong. */ +if (!p) { +abort(); +} +/* Remove the CPU from the list. */ +*lastp = p->next_cpu; +cpu_list_unlock(); +ts = ((CPUArchState *)cpu_env)->opaque; +if (ts->child_tidptr) { +put_user_u32(0, ts->child_tidptr); +sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX, + NULL, NULL, 0); +} +thread_env = NULL; +object_unref(OBJECT(ENV_GET_CPU(cpu_env))); +g_free(ts); +pthread_exit(NULL); +} #endif #ifdef TARGET_GPROF _mcleanup(); -- 1.8.1.4
[Qemu-devel] [PATCH] xen_disk: support cache backend option
Support a backend option "cache" that specifies the cache mode that should be used to open the disk file or device. See: http://marc.info/?l=xen-devel&m=137226872905057 Signed-off-by: Stefano Stabellini diff --git a/hw/xen_disk.c b/hw/xen_disk.c index f484404..092aa6b 100644 --- a/hw/block/xen_disk.c +++ b/hw/block/xen_disk.c @@ -94,6 +94,7 @@ struct XenBlkDev { char*type; char*dev; char*devtype; +char*cache; const char *fileproto; const char *filename; int ring_ref; @@ -734,6 +735,12 @@ static int blk_init(struct XenDevice *xendev) if (blkdev->devtype == NULL) { blkdev->devtype = xenstore_read_be_str(&blkdev->xendev, "device-type"); } +if (blkdev->cache == NULL) { +blkdev->cache = xenstore_read_be_str(&blkdev->xendev, "cache"); +} +if (blkdev->cache == NULL) { +blkdev->cache = g_strdup("writeback"); +} /* do we have all we need? */ if (blkdev->params == NULL || @@ -774,6 +781,8 @@ out_error: blkdev->dev = NULL; g_free(blkdev->devtype); blkdev->devtype = NULL; +g_free(blkdev->cache); +blkdev->cache = NULL; return -1; } @@ -782,8 +791,14 @@ static int blk_connect(struct XenDevice *xendev) struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev); int pers, index, qflags; -/* read-only ? */ -qflags = BDRV_O_CACHE_WB | BDRV_O_NATIVE_AIO; +if (!strcmp(blkdev->cache, "none")) { +qflags = BDRV_O_NATIVE_AIO | BDRV_O_NOCACHE; +} else if (!strcmp(blkdev->cache, "writethrough")) { +qflags = 0; +} else { +/* default to writeback */ +qflags = BDRV_O_NATIVE_AIO | BDRV_O_CACHE_WB; +} if (strcmp(blkdev->mode, "w") == 0) { qflags |= BDRV_O_RDWR; } @@ -950,6 +965,7 @@ static int blk_free(struct XenDevice *xendev) g_free(blkdev->type); g_free(blkdev->dev); g_free(blkdev->devtype); +g_free(blkdev->cache); qemu_bh_delete(blkdev->bh); return 0; }
[Qemu-devel] [PATCH qom-cpu v3 11/14] target-ppc: Don't overuse ENV_GET_CPU()
Commit b632a148b677b773ff155f9de840b37a653567b9 (target-ppc: QOM method dispatch for MMU fault handling) introduced a use of ENV_GET_CPU() inside target-ppc/ code. Use ppc_env_get_cpu() instead. Purely cosmetic, non-functional change to aid in locating and removing ENV_GET_CPU() usages. Signed-off-by: Andreas Färber --- target-ppc/mmu_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c index 68d5415..53deba5 100644 --- a/target-ppc/mmu_helper.c +++ b/target-ppc/mmu_helper.c @@ -2790,7 +2790,7 @@ void helper_booke206_tlbflush(CPUPPCState *env, uint32_t type) void tlb_fill(CPUPPCState *env, target_ulong addr, int is_write, int mmu_idx, uintptr_t retaddr) { -CPUState *cpu = ENV_GET_CPU(env); +CPUState *cpu = CPU(ppc_env_get_cpu(env)); PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); int ret; -- 1.8.1.4
[Qemu-devel] [PATCH qom-cpu v3 07/14] bsd-user: Change thread_env to CPUState
Signed-off-by: Andreas Färber --- bsd-user/elfload.c | 6 -- bsd-user/main.c| 6 +++--- bsd-user/qemu.h| 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c index 5e20510..93fd9e4 100644 --- a/bsd-user/elfload.c +++ b/bsd-user/elfload.c @@ -98,7 +98,7 @@ enum { static const char *get_elf_platform(void) { static char elf_platform[] = "i386"; -int family = (thread_env->cpuid_version >> 8) & 0xff; +int family = object_property_get_int(OBJECT(thread_cpu), "family", NULL); if (family > 6) family = 6; if (family >= 3) @@ -110,7 +110,9 @@ static const char *get_elf_platform(void) static uint32_t get_elf_hwcap(void) { -return thread_env->features[FEAT_1_EDX]; +X86CPU *cpu = X86_CPU(thread_cpu); + +return cpu->env.features[FEAT_1_EDX]; } #ifdef TARGET_X86_64 diff --git a/bsd-user/main.c b/bsd-user/main.c index 75dbd7f..1e92552 100644 --- a/bsd-user/main.c +++ b/bsd-user/main.c @@ -92,7 +92,7 @@ void fork_start(void) void fork_end(int child) { if (child) { -gdbserver_fork(thread_env); +gdbserver_fork((CPUArchState *)thread_cpu->env_ptr); } } @@ -713,7 +713,7 @@ static void usage(void) exit(1); } -THREAD CPUArchState *thread_env; +THREAD CPUState *thread_cpu; /* Assumes contents are already zeroed. */ void init_task_state(TaskState *ts) @@ -915,7 +915,7 @@ int main(int argc, char **argv) #if defined(TARGET_SPARC) || defined(TARGET_PPC) cpu_reset(ENV_GET_CPU(env)); #endif -thread_env = env; +thread_cpu = ENV_GET_CPU(env); if (getenv("QEMU_STRACE")) { do_strace = 1; diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h index a826086..325f564 100644 --- a/bsd-user/qemu.h +++ b/bsd-user/qemu.h @@ -139,7 +139,7 @@ abi_long do_openbsd_syscall(void *cpu_env, int num, abi_long arg1, abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6); void gemu_log(const char *fmt, ...) GCC_FMT_ATTR(1, 2); -extern THREAD CPUArchState *thread_env; +extern THREAD CPUState *thread_cpu; void cpu_loop(CPUArchState *env); char *target_strerror(int err); int get_osversion(void); -- 1.8.1.4
[Qemu-devel] [PATCH qom-cpu v3 02/14] cpu: Replace cpu_single_env with CPUState current_cpu
Move it to qom/cpu.h. Signed-off-by: Andreas Färber --- cpu-exec.c | 13 +++-- cpus.c | 41 - exec.c | 12 +++- hw/alpha/typhoon.c | 16 hw/arm/pxa2xx.c | 3 +-- hw/i386/kvmvapic.c | 6 -- hw/i386/pc.c| 11 ++- hw/intc/arm_gic.c | 3 +-- hw/intc/armv7m_nvic.c | 11 --- hw/intc/openpic.c | 7 ++- hw/mips/mips_fulong2e.c | 6 +++--- hw/mips/mips_jazz.c | 6 +++--- hw/mips/mips_malta.c| 6 +++--- hw/misc/vmport.c| 26 -- hw/ppc/mpc8544_guts.c | 3 ++- hw/ppc/prep.c | 6 +++--- hw/sparc/sun4m.c| 5 ++--- hw/timer/arm_mptimer.c | 8 +++- include/exec/cpu-all.h | 3 --- include/qom/cpu.h | 4 memory.c| 10 -- translate-all.c | 20 user-exec.c | 9 + 23 files changed, 120 insertions(+), 115 deletions(-) diff --git a/cpu-exec.c b/cpu-exec.c index ec46380..503b103 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -213,12 +213,12 @@ int cpu_exec(CPUArchState *env) cpu->halted = 0; } -cpu_single_env = env; +current_cpu = cpu; -/* As long as cpu_single_env is null, up to the assignment just above, +/* As long as current_cpu is null, up to the assignment just above, * requests by other threads to exit the execution loop are expected to * be issued using the exit_request global. We must make sure that our - * evaluation of the global value is performed past the cpu_single_env + * evaluation of the global value is performed past the current_cpu * value transition point, which requires a memory barrier as well as * an instruction scheduling constraint on modern architectures. */ smp_mb(); @@ -673,7 +673,8 @@ int cpu_exec(CPUArchState *env) } else { /* Reload env after longjmp - the compiler may have smashed all * local variables as longjmp is marked 'noreturn'. */ -env = cpu_single_env; +cpu = current_cpu; +env = cpu->env_ptr; } } /* for(;;) */ @@ -707,7 +708,7 @@ int cpu_exec(CPUArchState *env) #error unsupported target CPU #endif -/* fail safe : never use cpu_single_env outside cpu_exec() */ -cpu_single_env = NULL; +/* fail safe : never use current_cpu outside cpu_exec() */ +current_cpu = NULL; return ret; } diff --git a/cpus.c b/cpus.c index 86571f9..d51b875 100644 --- a/cpus.c +++ b/cpus.c @@ -118,10 +118,11 @@ TimersState timers_state; int64_t cpu_get_icount(void) { int64_t icount; -CPUArchState *env = cpu_single_env; +CPUState *cpu = current_cpu; icount = qemu_icount; -if (env) { +if (cpu) { +CPUArchState *env = cpu->env_ptr; if (!can_do_io(env)) { fprintf(stderr, "Bad clock read\n"); } @@ -468,8 +469,8 @@ static void cpu_handle_guest_debug(CPUState *cpu) static void cpu_signal(int sig) { -if (cpu_single_env) { -cpu_exit(ENV_GET_CPU(cpu_single_env)); +if (current_cpu) { +cpu_exit(current_cpu); } exit_request = 1; } @@ -660,10 +661,10 @@ void run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data) qemu_cpu_kick(cpu); while (!wi.done) { -CPUArchState *self_env = cpu_single_env; +CPUState *self_cpu = current_cpu; qemu_cond_wait(&qemu_work_cond, &qemu_global_mutex); -cpu_single_env = self_env; +current_cpu = self_cpu; } } @@ -733,7 +734,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg) qemu_mutex_lock(&qemu_global_mutex); qemu_thread_get_self(cpu->thread); cpu->thread_id = qemu_get_thread_id(); -cpu_single_env = cpu->env_ptr; +current_cpu = cpu; r = kvm_init_vcpu(cpu); if (r < 0) { @@ -781,9 +782,9 @@ static void *qemu_dummy_cpu_thread_fn(void *arg) cpu->created = true; qemu_cond_signal(&qemu_cpu_cond); -cpu_single_env = cpu->env_ptr; +current_cpu = cpu; while (1) { -cpu_single_env = NULL; +current_cpu = NULL; qemu_mutex_unlock_iothread(); do { int sig; @@ -794,7 +795,7 @@ static void *qemu_dummy_cpu_thread_fn(void *arg) exit(1); } qemu_mutex_lock_iothread(); -cpu_single_env = cpu->env_ptr; +current_cpu = cpu; qemu_wait_io_event_common(cpu); } @@ -894,12 +895,11 @@ void qemu_cpu_kick(CPUState *cpu) void qemu_cpu_kick_self(void) { #ifndef _WIN32 -assert(cpu_single_env); -CPUState *cpu_single_cpu = ENV_GET_CPU(cpu_single_env); +assert(current_cpu); -if (!cpu_single_cpu->thread_kicked) { -qemu_cpu_kick_thread(cpu_single_cpu); -cpu_single_cpu->thread_kicked = true; +if (!current_cpu->thread_kicked) { +qem
[Qemu-devel] [PATCH qom-cpu v3 06/14] linux-user: Change thread_env to CPUState
Signed-off-by: Andreas Färber --- linux-user/elfload.c | 16 +--- linux-user/linuxload.c | 3 ++- linux-user/main.c | 10 +- linux-user/qemu.h | 2 +- linux-user/signal.c| 12 +++- linux-user/syscall.c | 6 +++--- 6 files changed, 27 insertions(+), 22 deletions(-) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index d517450..7ce2eab 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -125,7 +125,7 @@ typedef abi_int target_pid_t; static const char *get_elf_platform(void) { static char elf_platform[] = "i386"; -int family = (thread_env->cpuid_version >> 8) & 0xff; +int family = object_property_get_int(OBJECT(thread_cpu), "family", NULL); if (family > 6) family = 6; if (family >= 3) @@ -137,7 +137,9 @@ static const char *get_elf_platform(void) static uint32_t get_elf_hwcap(void) { -return thread_env->features[FEAT_1_EDX]; +X86CPU *cpu = X86_CPU(thread_cpu); + +return cpu->env.features[FEAT_1_EDX]; } #ifdef TARGET_X86_64 @@ -404,7 +406,7 @@ static int validate_guest_space(unsigned long guest_base, static uint32_t get_elf_hwcap(void) { -CPUARMState *e = thread_env; +ARMCPU *cpu = ARM_CPU(thread_cpu); uint32_t hwcaps = 0; hwcaps |= ARM_HWCAP_ARM_SWP; @@ -415,7 +417,7 @@ static uint32_t get_elf_hwcap(void) /* probe for the extra features */ #define GET_FEATURE(feat, hwcap) \ -do {if (arm_feature(e, feat)) { hwcaps |= hwcap; } } while (0) +do { if (arm_feature(&cpu->env, feat)) { hwcaps |= hwcap; } } while (0) GET_FEATURE(ARM_FEATURE_VFP, ARM_HWCAP_ARM_VFP); GET_FEATURE(ARM_FEATURE_IWMMXT, ARM_HWCAP_ARM_IWMMXT); GET_FEATURE(ARM_FEATURE_THUMB2EE, ARM_HWCAP_ARM_THUMBEE); @@ -619,13 +621,13 @@ enum { static uint32_t get_elf_hwcap(void) { -CPUPPCState *e = thread_env; +PowerPCCPU *cpu = POWERPC_CPU(thread_cpu); uint32_t features = 0; /* We don't have to be terribly complete here; the high points are Altivec/FP/SPE support. Anything else is just a bonus. */ #define GET_FEATURE(flag, feature) \ -do {if (e->insns_flags & flag) features |= feature; } while(0) +do { if (cpu->env.insns_flags & flag) { features |= feature; } } while (0) GET_FEATURE(PPC_64B, QEMU_PPC_FEATURE_64); GET_FEATURE(PPC_FLOAT, QEMU_PPC_FEATURE_HAS_FPU); GET_FEATURE(PPC_ALTIVEC, QEMU_PPC_FEATURE_HAS_ALTIVEC); @@ -2667,7 +2669,7 @@ static int fill_note_info(struct elf_note_info *info, /* read and fill status of all threads */ cpu_list_lock(); for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { -if (cpu == ENV_GET_CPU(thread_env)) { +if (cpu == thread_cpu) { continue; } fill_thread_info(info, (CPUArchState *)cpu->env_ptr); diff --git a/linux-user/linuxload.c b/linux-user/linuxload.c index 381ab89..5cd6d91 100644 --- a/linux-user/linuxload.c +++ b/linux-user/linuxload.c @@ -89,7 +89,8 @@ static int prepare_binprm(struct linux_binprm *bprm) abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp, abi_ulong stringp, int push_ptr) { -TaskState *ts = (TaskState *)thread_env->opaque; +CPUArchState *env = thread_cpu->env_ptr; +TaskState *ts = (TaskState *)env->opaque; int n = sizeof(abi_ulong); abi_ulong envp; abi_ulong argv; diff --git a/linux-user/main.c b/linux-user/main.c index 564bed6..67ea9ba 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -120,7 +120,7 @@ void fork_end(int child) if (child) { /* Child processes created by fork() only have a single thread. Discard information about the parent threads. */ -first_cpu = ENV_GET_CPU(thread_env); +first_cpu = thread_cpu; first_cpu->next_cpu = NULL; pending_cpus = 0; pthread_mutex_init(&exclusive_lock, NULL); @@ -128,7 +128,7 @@ void fork_end(int child) pthread_cond_init(&exclusive_cond, NULL); pthread_cond_init(&exclusive_resume, NULL); pthread_mutex_init(&tcg_ctx.tb_ctx.tb_lock, NULL); -gdbserver_fork(thread_env); +gdbserver_fork((CPUArchState *)thread_cpu->env_ptr); } else { pthread_mutex_unlock(&exclusive_lock); pthread_mutex_unlock(&tcg_ctx.tb_ctx.tb_lock); @@ -232,7 +232,7 @@ void fork_start(void) void fork_end(int child) { if (child) { -gdbserver_fork(thread_env); +gdbserver_fork((CPUArchState *)thread_cpu->env_ptr); } } @@ -3150,7 +3150,7 @@ void cpu_loop(CPUS390XState *env) #endif /* TARGET_S390X */ -THREAD CPUArchState *thread_env; +THREAD CPUState *thread_cpu; void task_settid(TaskState *ts) { @@ -3640,7 +3640,7 @@ int main(int argc, char **argv, char **envp) cpu_reset(ENV_GET_CPU(env)); #endif -thread_env = env; +thread_cpu = ENV_GET_CPU(env); if (getenv("QEMU_STRACE")) {
[Qemu-devel] [PATCH qom-cpu v3 09/14] intc/openpic: Build openpic only once
Since current_cpu is CPUState it no longer depends on CPUPPCState. Move ppce500_set_mpic_proxy() to a new hw/ppc/ppc_e500.h because hw/ppc/ppc.h is too heavily using CPUPPCState and PowerPCCPU. Signed-off-by: Andreas Färber --- hw/intc/Makefile.objs | 2 +- hw/intc/openpic.c | 2 +- hw/ppc/ppc.c | 1 + include/hw/ppc/ppc.h | 2 -- include/hw/ppc/ppc_e500.h | 6 ++ 5 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 include/hw/ppc/ppc_e500.h diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs index 9c51ee0..0abd708 100644 --- a/hw/intc/Makefile.objs +++ b/hw/intc/Makefile.objs @@ -11,6 +11,7 @@ common-obj-$(CONFIG_SLAVIO) += slavio_intctl.o common-obj-$(CONFIG_IOAPIC) += ioapic_common.o common-obj-$(CONFIG_ARM_GIC) += arm_gic_common.o common-obj-$(CONFIG_ARM_GIC) += arm_gic.o +common-obj-$(CONFIG_OPENPIC) += openpic.o obj-$(CONFIG_APIC) += apic.o apic_common.o obj-$(CONFIG_ARM_GIC_KVM) += arm_gic_kvm.o @@ -19,5 +20,4 @@ obj-$(CONFIG_EXYNOS4) += exynos4210_gic.o exynos4210_combiner.o obj-$(CONFIG_GRLIB) += grlib_irqmp.o obj-$(CONFIG_IOAPIC) += ioapic.o obj-$(CONFIG_OMAP) += omap_intc.o -obj-$(CONFIG_OPENPIC) += openpic.o obj-$(CONFIG_SH4) += sh_intc.o diff --git a/hw/intc/openpic.c b/hw/intc/openpic.c index 86de0b3..6440400 100644 --- a/hw/intc/openpic.c +++ b/hw/intc/openpic.c @@ -37,10 +37,10 @@ #include "hw/ppc/mac.h" #include "hw/pci/pci.h" #include "hw/ppc/openpic.h" +#include "hw/ppc/ppc_e500.h" #include "hw/sysbus.h" #include "hw/pci/msi.h" #include "qemu/bitops.h" -#include "hw/ppc/ppc.h" //#define DEBUG_OPENPIC diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c index 554f244..e1c095c 100644 --- a/hw/ppc/ppc.c +++ b/hw/ppc/ppc.c @@ -23,6 +23,7 @@ */ #include "hw/hw.h" #include "hw/ppc/ppc.h" +#include "hw/ppc/ppc_e500.h" #include "qemu/timer.h" #include "sysemu/sysemu.h" #include "hw/timer/m48t59.h" diff --git a/include/hw/ppc/ppc.h b/include/hw/ppc/ppc.h index acaf0d6..cc2d78e 100644 --- a/include/hw/ppc/ppc.h +++ b/include/hw/ppc/ppc.h @@ -73,8 +73,6 @@ void ppc6xx_irq_init (CPUPPCState *env); void ppc970_irq_init (CPUPPCState *env); void ppcPOWER7_irq_init (CPUPPCState *env); -void ppce500_set_mpic_proxy(bool enabled); - /* PPC machines for OpenBIOS */ enum { ARCH_PREP = 0, diff --git a/include/hw/ppc/ppc_e500.h b/include/hw/ppc/ppc_e500.h new file mode 100644 index 000..b66c0e3 --- /dev/null +++ b/include/hw/ppc/ppc_e500.h @@ -0,0 +1,6 @@ +#ifndef HW_PPC_E500_H +#define HW_PPC_E500_H + +void ppce500_set_mpic_proxy(bool enabled); + +#endif -- 1.8.1.4
[Qemu-devel] [PATCH qom-cpu v3 00/14] QOM CPUState, part 10: CPU loops
Hello, This series changes cpu_single_env, first_cpu, next_cpu and thread_env to CPUState. v3 defers the removal of qemu_for_each_cpu() and drops CPU_INTERRUPT_* changes, renames cpu_single_cpu to current_cpu, while enforcing consistent use of ENV_GET_CPU() and CPUArchState macros. Available for testing at: git://github.com/afaerber/qemu-cpu.git qom-cpu-10.v3 https://github.com/afaerber/qemu-cpu/commits/qom-cpu-10.v3 Regards, Andreas v2 -> v3: * Dropped sh_intc change and CPU_INTERRUPT_* movement / enum conversion (rth). * Simplified alpha code by reusing a cpu variable (rth). * Renamed cpu_single_cpu to current_cpu and prepended KVM preparation patch. * Dropped qemu_for_each_cpu() removal (mst). * Rebased onto Paolo's iommu series. * Dropped cpu_next hunks in cpu_copy() no longer needed for CPUState::next_cpu. * Applied some preparatory patches to avoid large resends. * Appended ENV_GET_CPU() cleanups for ppc and s390x. * Appended CPUArchState cleanup for x86 dump support. * Prepended Coding Style cleanup for linux-user do_syscall() TARGET_NR_exit. v1 -> v2: * Fixed typo spotted by Li Guang. * Dropped qemu_for_each_cpu() conversion patches. * Applied most qemu_get_cpu() patches already. * Fixed Xen breakage due to NULL cpu_single_env (reported by Stefano). * Appended patch to drop qemu_for_each_cpu() (suggested by Markus). * Appended patches to build arm_gic, arm_mptimer, openpic and sh_intc only once. * Avoided some un-typed uses of CPUState::env_ptr. Cc: Anthony Liguori Cc: Blue Swirl Cc: Aurélien Jarno Cc: Markus Armbruster Cc: Paolo Bonzini (cpu_unassigned_access) Cc: Stefano Stabellini (dummy CPU thread changes) Cc: Peter Maydell (hwaddr, arm devs) Cc: Alexander Graf (openpic) Cc: Scott Wood (openpic) Andreas Färber (14): kvm: Free current_cpu identifier cpu: Replace cpu_single_env with CPUState current_cpu kvm: Change kvm_remove_all_breakpoints() argument to CPUState linux-user: Clean up do_syscall() Coding Style for TARGET_NR_exit cpu: Make first_cpu and next_cpu CPUState linux-user: Change thread_env to CPUState bsd-user: Change thread_env to CPUState intc/arm_gic: Build arm_gic only once intc/openpic: Build openpic only once timer/arm_mptimer: Build arm_mptimer only once target-ppc: Don't overuse ENV_GET_CPU() target-s390x: Don't overuse ENV_GET_CPU() target-s390x: Change handle_{hypercall,diag}() argument to S390CPU target-i386: Don't overuse CPUArchState bsd-user/elfload.c| 6 +- bsd-user/main.c | 6 +- bsd-user/qemu.h | 2 +- cpu-exec.c| 13 ++-- cpus.c| 167 -- cputlb.c | 4 +- dump.c| 16 ++--- exec.c| 55 --- gdbstub.c | 35 ++ hw/alpha/typhoon.c| 16 ++--- hw/arm/boot.c | 10 +-- hw/arm/exynos4_boards.c | 4 +- hw/arm/highbank.c | 2 +- hw/arm/pxa2xx.c | 3 +- hw/arm/realview.c | 2 +- hw/arm/vexpress.c | 2 +- hw/arm/xilinx_zynq.c | 2 +- hw/i386/kvm/clock.c | 12 ++-- hw/i386/kvmvapic.c| 19 -- hw/i386/pc.c | 28 hw/i386/pc_piix.c | 3 +- hw/intc/Makefile.objs | 4 +- hw/intc/arm_gic.c | 4 +- hw/intc/armv7m_nvic.c | 11 ++- hw/intc/openpic.c | 9 +-- hw/intc/sh_intc.c | 5 +- hw/isa/lpc_ich9.c | 2 +- hw/mips/mips_fulong2e.c | 6 +- hw/mips/mips_jazz.c | 6 +- hw/mips/mips_malta.c | 9 +-- hw/misc/vmport.c | 26 +--- hw/ppc/mpc8544_guts.c | 3 +- hw/ppc/ppc.c | 12 ++-- hw/ppc/prep.c | 12 ++-- hw/ppc/spapr.c| 27 hw/sparc/sun4m.c | 5 +- hw/timer/Makefile.objs| 2 +- hw/timer/arm_mptimer.c| 9 ++- include/exec/cpu-all.h| 4 -- include/exec/cpu-defs.h | 1 - include/hw/ppc/ppc.h | 2 - include/hw/ppc/ppc_e500.h | 6 ++ include/qom/cpu.h | 8 +++ include/sysemu/kvm.h | 10 +-- kvm-all.c | 53 --- kvm-stub.c| 6 +- linux-user/elfload.c | 21 +++--- linux-user/linuxload.c| 3 +- linux-user/main.c | 16 ++--- linux-user/qemu.h | 2 +- linux-user/signal.c | 12 ++-- linux-user/syscall.c | 80 +++--- memory.c | 10 ++- memory_mapping.c | 16 ++--- monitor.c | 4 +- target-i386/arch_dump.c | 17 +++-- target-i386/helper.c | 15 +++-- target-i386/kvm.c | 8 ++- target-i386/misc_helper.c | 2 +- target-mips/op_helper.c | 25 --- target-ppc/excp_helper.c | 9 ++- target-ppc/kvm.c | 2 +- target-ppc/mmu_helper.c | 2 +- target-s390x/kvm.c| 14 ++-- translate-all.c | 32 + user-exec.c |
[Qemu-devel] [PATCH qom-cpu v3 13/14] target-s390x: Change handle_{hypercall, diag}() argument to S390CPU
This allows to get rid of the last remaining ENV_GET_CPU() in target-s390x/ by using CPU() cast directly on the argument. Cc: Jason J. Herne Signed-off-by: Andreas Färber --- target-s390x/kvm.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c index 4660074..33ca7a7 100644 --- a/target-s390x/kvm.c +++ b/target-s390x/kvm.c @@ -607,9 +607,10 @@ static int handle_priv(S390CPU *cpu, struct kvm_run *run, return r; } -static int handle_hypercall(CPUS390XState *env, struct kvm_run *run) +static int handle_hypercall(S390CPU *cpu, struct kvm_run *run) { -CPUState *cs = ENV_GET_CPU(env); +CPUState *cs = CPU(cpu); +CPUS390XState *env = &cpu->env; kvm_s390_get_registers_partial(cs); cs->kvm_vcpu_dirty = true; @@ -618,13 +619,13 @@ static int handle_hypercall(CPUS390XState *env, struct kvm_run *run) return 0; } -static int handle_diag(CPUS390XState *env, struct kvm_run *run, int ipb_code) +static int handle_diag(S390CPU *cpu, struct kvm_run *run, int ipb_code) { int r = 0; switch (ipb_code) { case DIAG_KVM_HYPERCALL: -r = handle_hypercall(env, run); +r = handle_hypercall(cpu, run); break; case DIAG_KVM_BREAKPOINT: sleep(10); @@ -735,7 +736,6 @@ out: static int handle_instruction(S390CPU *cpu, struct kvm_run *run) { -CPUS390XState *env = &cpu->env; unsigned int ipa0 = (run->s390_sieic.ipa & 0xff00); uint8_t ipa1 = run->s390_sieic.ipa & 0x00ff; int ipb_code = (run->s390_sieic.ipb & 0x0fff) >> 16; @@ -749,7 +749,7 @@ static int handle_instruction(S390CPU *cpu, struct kvm_run *run) r = handle_priv(cpu, run, ipa0 >> 8, ipa1); break; case IPA0_DIAG: -r = handle_diag(env, run, ipb_code); +r = handle_diag(cpu, run, ipb_code); break; case IPA0_SIGP: r = handle_sigp(cpu, run, ipa1); -- 1.8.1.4
[Qemu-devel] [PATCH qom-cpu v3 08/14] intc/arm_gic: Build arm_gic only once
Since current_cpu is CPUState it no longer needs CPUArchState. Signed-off-by: Andreas Färber --- hw/intc/Makefile.objs | 2 +- hw/intc/arm_gic.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs index 3e68d2e..9c51ee0 100644 --- a/hw/intc/Makefile.objs +++ b/hw/intc/Makefile.objs @@ -10,9 +10,9 @@ common-obj-$(CONFIG_REALVIEW) += realview_gic.o common-obj-$(CONFIG_SLAVIO) += slavio_intctl.o common-obj-$(CONFIG_IOAPIC) += ioapic_common.o common-obj-$(CONFIG_ARM_GIC) += arm_gic_common.o +common-obj-$(CONFIG_ARM_GIC) += arm_gic.o obj-$(CONFIG_APIC) += apic.o apic_common.o -obj-$(CONFIG_ARM_GIC) += arm_gic.o obj-$(CONFIG_ARM_GIC_KVM) += arm_gic_kvm.o obj-$(CONFIG_STELLARIS) += armv7m_nvic.o obj-$(CONFIG_EXYNOS4) += exynos4210_gic.o exynos4210_combiner.o diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 5ac7e68..8ac0242 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -20,6 +20,7 @@ #include "hw/sysbus.h" #include "gic_internal.h" +#include "qom/cpu.h" //#define DEBUG_GIC -- 1.8.1.4
[Qemu-devel] [PATCH qom-cpu v3 03/14] kvm: Change kvm_remove_all_breakpoints() argument to CPUState
Acked-by: Paolo Bonzini Reviewed-by: Richard Henderson Signed-off-by: Andreas Färber --- gdbstub.c| 2 +- include/sysemu/kvm.h | 2 +- kvm-all.c| 6 +++--- kvm-stub.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index 3101a43..9e7f7a1 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -2019,7 +2019,7 @@ static void gdb_breakpoint_remove_all(void) CPUArchState *env; if (kvm_enabled()) { -kvm_remove_all_breakpoints(gdbserver_state->c_cpu); +kvm_remove_all_breakpoints(ENV_GET_CPU(gdbserver_state->c_cpu)); return; } diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index c88aee9..9460d5a 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -163,7 +163,7 @@ int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr, target_ulong len, int type); int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr, target_ulong len, int type); -void kvm_remove_all_breakpoints(CPUArchState *env); +void kvm_remove_all_breakpoints(CPUState *cpu); int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap); #ifndef _WIN32 int kvm_set_signal_mask(CPUState *cpu, const sigset_t *sigset); diff --git a/kvm-all.c b/kvm-all.c index d074597..ee0ee02 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -1981,11 +1981,11 @@ int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr, return 0; } -void kvm_remove_all_breakpoints(CPUArchState *env) +void kvm_remove_all_breakpoints(CPUState *cpu) { -CPUState *cpu = ENV_GET_CPU(env); struct kvm_sw_breakpoint *bp, *next; KVMState *s = cpu->kvm_state; +CPUArchState *env; QTAILQ_FOREACH_SAFE(bp, &s->kvm_sw_breakpoints, entry, next) { if (kvm_arch_remove_sw_breakpoint(cpu, bp) != 0) { @@ -2026,7 +2026,7 @@ int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr, return -EINVAL; } -void kvm_remove_all_breakpoints(CPUArchState *env) +void kvm_remove_all_breakpoints(CPUState *cpu) { } #endif /* !KVM_CAP_SET_GUEST_DEBUG */ diff --git a/kvm-stub.c b/kvm-stub.c index 76da61e..a6c2b01 100644 --- a/kvm-stub.c +++ b/kvm-stub.c @@ -95,7 +95,7 @@ int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr, return -EINVAL; } -void kvm_remove_all_breakpoints(CPUArchState *env) +void kvm_remove_all_breakpoints(CPUState *cpu) { } -- 1.8.1.4
[Qemu-devel] [PATCH qom-cpu v3 01/14] kvm: Free current_cpu identifier
Since CPU loops are done as last step in kvm_{insert,remove}_breakpoint() and kvm_remove_all_breakpoints(), we do not need to distinguish between invoking CPU and iterated CPUs and can thereby free the identifier for use as a global variable. Acked-by: Paolo Bonzini Signed-off-by: Andreas Färber --- include/sysemu/kvm.h | 10 +- kvm-all.c| 39 +-- kvm-stub.c | 6 +++--- 3 files changed, 25 insertions(+), 30 deletions(-) diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index fe8bc40..c88aee9 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -159,11 +159,11 @@ void *kvm_arch_ram_alloc(ram_addr_t size); void kvm_setup_guest_memory(void *start, size_t size); void kvm_flush_coalesced_mmio_buffer(void); -int kvm_insert_breakpoint(CPUArchState *current_env, target_ulong addr, +int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr, target_ulong len, int type); -int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr, +int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr, target_ulong len, int type); -void kvm_remove_all_breakpoints(CPUArchState *current_env); +void kvm_remove_all_breakpoints(CPUArchState *env); int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap); #ifndef _WIN32 int kvm_set_signal_mask(CPUState *cpu, const sigset_t *sigset); @@ -241,9 +241,9 @@ struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(CPUState *cpu, int kvm_sw_breakpoints_active(CPUState *cpu); -int kvm_arch_insert_sw_breakpoint(CPUState *current_cpu, +int kvm_arch_insert_sw_breakpoint(CPUState *cpu, struct kvm_sw_breakpoint *bp); -int kvm_arch_remove_sw_breakpoint(CPUState *current_cpu, +int kvm_arch_remove_sw_breakpoint(CPUState *cpu, struct kvm_sw_breakpoint *bp); int kvm_arch_insert_hw_breakpoint(target_ulong addr, target_ulong len, int type); diff --git a/kvm-all.c b/kvm-all.c index 7a1684e..d074597 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -1896,16 +1896,15 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap) return data.err; } -int kvm_insert_breakpoint(CPUArchState *current_env, target_ulong addr, +int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr, target_ulong len, int type) { -CPUState *current_cpu = ENV_GET_CPU(current_env); +CPUState *cpu = ENV_GET_CPU(env); struct kvm_sw_breakpoint *bp; -CPUArchState *env; int err; if (type == GDB_BREAKPOINT_SW) { -bp = kvm_find_sw_breakpoint(current_cpu, addr); +bp = kvm_find_sw_breakpoint(cpu, addr); if (bp) { bp->use_count++; return 0; @@ -1918,14 +1917,13 @@ int kvm_insert_breakpoint(CPUArchState *current_env, target_ulong addr, bp->pc = addr; bp->use_count = 1; -err = kvm_arch_insert_sw_breakpoint(current_cpu, bp); +err = kvm_arch_insert_sw_breakpoint(cpu, bp); if (err) { g_free(bp); return err; } -QTAILQ_INSERT_HEAD(¤t_cpu->kvm_state->kvm_sw_breakpoints, - bp, entry); +QTAILQ_INSERT_HEAD(&cpu->kvm_state->kvm_sw_breakpoints, bp, entry); } else { err = kvm_arch_insert_hw_breakpoint(addr, len, type); if (err) { @@ -1942,16 +1940,15 @@ int kvm_insert_breakpoint(CPUArchState *current_env, target_ulong addr, return 0; } -int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr, +int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr, target_ulong len, int type) { -CPUState *current_cpu = ENV_GET_CPU(current_env); +CPUState *cpu = ENV_GET_CPU(env); struct kvm_sw_breakpoint *bp; -CPUArchState *env; int err; if (type == GDB_BREAKPOINT_SW) { -bp = kvm_find_sw_breakpoint(current_cpu, addr); +bp = kvm_find_sw_breakpoint(cpu, addr); if (!bp) { return -ENOENT; } @@ -1961,12 +1958,12 @@ int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr, return 0; } -err = kvm_arch_remove_sw_breakpoint(current_cpu, bp); +err = kvm_arch_remove_sw_breakpoint(cpu, bp); if (err) { return err; } -QTAILQ_REMOVE(¤t_cpu->kvm_state->kvm_sw_breakpoints, bp, entry); +QTAILQ_REMOVE(&cpu->kvm_state->kvm_sw_breakpoints, bp, entry); g_free(bp); } else { err = kvm_arch_remove_hw_breakpoint(addr, len, type); @@ -1984,16 +1981,14 @@ int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr, return 0; } -void kvm_remove_all_breakpoints(CPUArchState *current_env) +void kvm_remove_all_breakpoints(CPUArchState *env) { -CPUState *current_c
[Qemu-devel] [Bug 1194954] [NEW] Windows 95 guest reboots itself on qemu 1.5.0 & 1.5.50 (GIT)
Public bug reported: When I begin to run a Windows 95 guest on these releases of qemu, it reboots itself more times without my permission (eg. without shutting it down properly), and when I'm installing Netscape 4.08 at, for example, 46% or 75%, it still reboots itself without completing the installation of the web browser. Is this an issue of main-loop.c? ** Affects: qemu Importance: Undecided Status: New ** Tags: 1.5.0 1.5.50 122 95 bug chicago qemu windows -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1194954 Title: Windows 95 guest reboots itself on qemu 1.5.0 & 1.5.50 (GIT) Status in QEMU: New Bug description: When I begin to run a Windows 95 guest on these releases of qemu, it reboots itself more times without my permission (eg. without shutting it down properly), and when I'm installing Netscape 4.08 at, for example, 46% or 75%, it still reboots itself without completing the installation of the web browser. Is this an issue of main-loop.c? To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1194954/+subscriptions
[Qemu-devel] [Bug 1194954] Re: Windows 95 guest reboots itself on qemu 1.5.0 & 1.5.50 (GIT)
update: this didn't happen on qemu 1.2.2 -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1194954 Title: Windows 95 guest reboots itself on qemu 1.5.0 & 1.5.50 (GIT) Status in QEMU: New Bug description: When I begin to run a Windows 95 guest on these releases of qemu, it reboots itself more times without my permission (eg. without shutting it down properly), and when I'm installing Netscape 4.08 at, for example, 46% or 75%, it still reboots itself without completing the installation of the web browser. Is this an issue of main-loop.c? To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1194954/+subscriptions
Re: [Qemu-devel] [PATCH V2 5/7] monitor: support sub commands in auto completion
On Wed, 26 Jun 2013 12:03:39 +0800 Wenchao Xia wrote: > 于 2013-6-24 20:48, Wenchao Xia 写道: > > This patch allow auot completion work normal in sub command case, > > "info block [DEVICE]" can auto complete now, by re-enter the completion > > function. Also, original "info" is treated as a special case, now it is > > treated as a sub command group, global variable info_cmds is not used > > any more. > > > > "help" command is still treated as a special case, since it is not a sub > > command group but want to auto complete command in root command table. > > > > Signed-off-by: Wenchao Xia > > --- > > monitor.c | 36 > > 1 files changed, 24 insertions(+), 12 deletions(-) > > > > diff --git a/monitor.c b/monitor.c > > index aa641de..f364a0d 100644 > > --- a/monitor.c > > +++ b/monitor.c > > @@ -4179,10 +4179,11 @@ static const char *next_arg_type(const char > > *typestr) > > return (p != NULL ? ++p : typestr); > > } > > > > -static void monitor_find_completion(Monitor *mon, > > -const char *cmdline) > > +static void monitor_find_completion_by_table(Monitor *mon, > > + const mon_cmd_t *cmd_table, > > + const char *cmdline) > > { > > -const char *cmdname; > > +const char *cmdname, *p; > > char *args[MAX_ARGS]; > > int nb_args, i, len; > > const char *ptype, *str; > > @@ -4212,12 +4213,12 @@ static void monitor_find_completion(Monitor *mon, > > else > > cmdname = args[0]; > > readline_set_completion_index(mon->rs, strlen(cmdname)); > > -for (cmd = mon->cmd_table; cmd->name != NULL; cmd++) { > > +for (cmd = cmd_table; cmd->name != NULL; cmd++) { > > cmd_completion(mon, cmdname, cmd->name); > > } > > } else { > > /* find the command */ > > -for (cmd = mon->cmd_table; cmd->name != NULL; cmd++) { > > +for (cmd = cmd_table; cmd->name != NULL; cmd++) { > > if (compare_cmd(args[0], cmd->name)) { > > break; > > } > > @@ -4226,6 +4227,17 @@ static void monitor_find_completion(Monitor *mon, > > goto cleanup; > > } > > > > +/* locate next valid string in original cmdline used by re-enter */ > > +p = cmdline + strlen(args[0]); > > +while (qemu_isspace(*p)) { > > +p++; > > +} > > + > Here it can't handle command start with space such as " blk", I plan > make parse_cmdline() return additional const char **args_cmdline, which > point to cmdline correspond to each args. Just want to > mention it to save reviewer's time, I'll fix it with any other > comments:). I prefer you respin it first, because it's not unusual that a single change like this one ends up requiring more changes. Also, if the series is good enough I can apply it w/o having to wait for another version. > > > > +if (cmd->sub_table) { > > +monitor_find_completion_by_table(mon, cmd->sub_table, p); > > +goto cleanup; > > +} > > + > > ptype = next_arg_type(cmd->args_type); > > for(i = 0; i < nb_args - 2; i++) { > > if (*ptype != '\0') { > > @@ -4252,13 +4264,7 @@ static void monitor_find_completion(Monitor *mon, > > bdrv_iterate(block_completion_it, &mbs); > > break; > > case 's': > > -/* XXX: more generic ? */ > > -if (!strcmp(cmd->name, "info")) { > > -readline_set_completion_index(mon->rs, strlen(str)); > > -for(cmd = info_cmds; cmd->name != NULL; cmd++) { > > -cmd_completion(mon, str, cmd->name); > > -} > > -} else if (!strcmp(cmd->name, "sendkey")) { > > +if (!strcmp(cmd->name, "sendkey")) { > > char *sep = strrchr(str, '-'); > > if (sep) > > str = sep + 1; > > @@ -4284,6 +4290,12 @@ cleanup: > > } > > } > > > > +static void monitor_find_completion(Monitor *mon, > > +const char *cmdline) > > +{ > > +return monitor_find_completion_by_table(mon, mon->cmd_table, cmdline); > > +} > > + > > static int monitor_can_read(void *opaque) > > { > > Monitor *mon = opaque; > > > >
Re: [Qemu-devel] [PATCH 2/2] fbdev: add monitor commands to enable/disable/query
On Wed, 26 Jun 2013 13:38:04 +0200 Gerd Hoffmann wrote: > This patch adds a fbdev monitor command to enable/disable > the fbdev display at runtime to both qmp and hmp. > > qmp: framebuffer-display enable=on|off scale=on|off device=/dev/fb > hmp: framebuffer-display on|off > > There is also a query-framebuffer command for qmp. > > Signed-off-by: Gerd Hoffmann > --- > hmp-commands.hx | 14 ++ > hmp.c|9 + > hmp.h|1 + > include/ui/console.h |1 + > qapi-schema.json | 43 +++ > qmp-commands.hx | 12 > qmp.c| 31 +++ > ui/fbdev.c | 20 > 8 files changed, 131 insertions(+) > > diff --git a/hmp-commands.hx b/hmp-commands.hx > index 915b0d1..283106d 100644 > --- a/hmp-commands.hx > +++ b/hmp-commands.hx > @@ -1563,7 +1563,21 @@ STEXI > @findex qemu-io > > Executes a qemu-io command on the given block device. > +ETEXI > + > +{ > +.name = "framebuffer-display", > +.args_type = "enable:b", > +.params = "on|off", > +.help = "enable/disable linux console framebuffer display", > +.mhandler.cmd = hmp_framebuffer_display, > +}, > + > +STEXI > +@item framebuffer-display on | off > +@findex framebuffer-display > > +enable/disable linux console framebuffer display. > ETEXI > > { > diff --git a/hmp.c b/hmp.c > index 494a9aa..55f195f 100644 > --- a/hmp.c > +++ b/hmp.c > @@ -1464,3 +1464,12 @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict) > > hmp_handle_error(mon, &err); > } > + > +void hmp_framebuffer_display(Monitor *mon, const QDict *qdict) > +{ > +int enable = qdict_get_bool(qdict, "enable"); > +Error *errp = NULL; > + > +qmp_framebuffer_display(enable, false, false, false, NULL, &errp); > +hmp_handle_error(mon, &errp); > +} > diff --git a/hmp.h b/hmp.h > index 56d2e92..c3a48e4 100644 > --- a/hmp.h > +++ b/hmp.h > @@ -86,5 +86,6 @@ void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict); > void hmp_chardev_add(Monitor *mon, const QDict *qdict); > void hmp_chardev_remove(Monitor *mon, const QDict *qdict); > void hmp_qemu_io(Monitor *mon, const QDict *qdict); > +void hmp_framebuffer_display(Monitor *mon, const QDict *qdict); > > #endif > diff --git a/include/ui/console.h b/include/ui/console.h > index 71b538a..5a9207d 100644 > --- a/include/ui/console.h > +++ b/include/ui/console.h > @@ -311,6 +311,7 @@ void sdl_display_init(DisplayState *ds, int full_screen, > int no_frame); > /* fbdev.c */ > int fbdev_display_init(const char *device, bool scale, Error **err); > void fbdev_display_uninit(void); > +FramebufferInfo *framebuffer_info(void); > > /* cocoa.m */ > void cocoa_display_init(DisplayState *ds, int full_screen); > diff --git a/qapi-schema.json b/qapi-schema.json > index 6cc07c2..715dc1f 100644 > --- a/qapi-schema.json > +++ b/qapi-schema.json > @@ -3608,3 +3608,46 @@ > '*cpuid-input-ecx': 'int', > 'cpuid-register': 'X86CPURegister32', > 'features': 'int' } } > + > +## > +# @framebuffer-display: Let me bike-shed: we're trying to make command's names verbs. So, we could call this framebuffer-display-set or maybe have two commands, framebuffer-display-enable and framebuffer-display-disable. I prefer the latter. > +# > +# Enable/disable linux console framebuffer display. > +# > +# @enable: whenever the framebuffer display should be enabled or disabled. > +# > +# @scale: #optional enables display scaling, default: off > +# > +# @device: #optional specifies framebuffer device, default: /dev/fb0 Actually, it will try to get the device name from an env variable first, which sounds too automatic for a building block API like QMP. You can do it for HMP, but QMP I guess it would be more appropriate to make the device name mandatory. > +# > +# Returns: Nothing. > +# > +# Since: 1.6 > +# > +## > +{ 'command': 'framebuffer-display', 'data': {'enable' : 'bool', > + '*scale' : 'bool', > + '*device' : 'str' } } > + > +## > +# @FramebufferInfo: > +# Missing docs. > +# Since 1.6 > +## > +{ 'type': 'FramebufferInfo', > + 'data': { 'enabled': 'bool', > +'*scale' : 'bool', > +'*device': 'str', Why is device optional? > +'*vtno' : 'int' } } > + > +## > +# @query-framebuffer: > +# > +# Query linux console framebuffer state. > +# > +# Returns: FramebufferInfo. > +# > +# Since: 1.6 > +# > +## > +{ 'command': 'query-framebuffer', 'returns': 'FramebufferInfo' } > diff --git a/qmp-commands.hx b/qmp-commands.hx > index 8cea5e5..e0661f0 100644 > --- a/qmp-commands.hx > +++ b/qmp-commands.hx > @@ -2997,3 +2997,15 @@ Example: > <- { "return": {} } > > EQMP > + > +{ > +.name = "framebuffer-display", > +.args_t
Re: [Qemu-devel] [PATCH v4 06/10] qemu-ga: Add Windows VSS provider to quiesce applications on fsfreeze
On 06/25/13 18:03, Laszlo Ersek wrote: > On 06/06/13 17:06, Tomoki Sekiyama wrote: Comparing the .def file and the provider header file: >> diff --git a/qga/vss-win32-provider/qga-provider.def >> b/qga/vss-win32-provider/qga-provider.def >> new file mode 100644 >> index 000..9f3afc8 >> --- /dev/null >> +++ b/qga/vss-win32-provider/qga-provider.def >> @@ -0,0 +1,10 @@ >> +LIBRARY "QGA-PROVIDER.DLL" >> + >> +EXPORTS >> +VSSCheckOSVersion PRIVATE >> +COMRegister PRIVATE >> +COMUnregister PRIVATE >> +DllCanUnloadNow PRIVATE >> +DllGetClassObject PRIVATE >> +DllRegisterServer PRIVATE >> +DllUnregisterServer PRIVATE >> diff --git a/qga/vss-win32-provider.h b/qga/vss-win32-provider.h >> new file mode 100644 >> index 000..a437e71 >> --- /dev/null >> +++ b/qga/vss-win32-provider.h >> @@ -0,0 +1,26 @@ >> +/* >> + * QEMU Guest Agent win32 VSS provider declarations >> + * >> + * Copyright Hitachi Data Systems Corp. 2013 >> + * >> + * Authors: >> + * Tomoki Sekiyama >> + * >> + * This work is licensed under the terms of the GNU GPL, version 2 or later. >> + * See the COPYING file in the top-level directory. >> + */ >> + >> +#ifndef VSS_WIN32_PROVIDER_H >> +#define VSS_WIN32_PROVIDER_H >> + >> +#include >> + >> +STDAPI VSSCheckOSVersion(void); >> + >> +STDAPI COMRegister(void); >> +STDAPI COMUnregister(void); >> + >> +STDAPI DllRegisterServer(void); >> +STDAPI DllUnregisterServer(void); >> + >> +#endif (a) what is the reason for not listing DllCanUnloadNow() and DllGetClassObject() in the header file? (b) Does STDAPI imply a return type? Or are you just going with the implicit "int"? (Based on my encounters with EFIAPI, I think it's the latter.) >> diff --git a/qga/vss-win32.h b/qga/vss-win32.h >> new file mode 100644 >> index 000..21655cf >> --- /dev/null >> +++ b/qga/vss-win32.h >> @@ -0,0 +1,86 @@ >> +/* >> + * QEMU Guest Agent win32 VSS common declarations >> + * >> + * Copyright Hitachi Data Systems Corp. 2013 >> + * >> + * Authors: >> + * Tomoki Sekiyama >> + * >> + * This work is licensed under the terms of the GNU GPL, version 2 or later. >> + * See the COPYING file in the top-level directory. >> + */ >> + >> +#ifndef VSS_WIN32_H >> +#define VSS_WIN32_H >> + >> +#define __MIDL_user_allocate_free_DEFINED__ >> +#include "config-host.h" >> +#include >> +#include >> + >> +/* Reduce warnings to include vss.h */ >> + >> +/* Ignore annotations for MS IDE */ >> +#define __in IN >> +#define __out OUT >> +#define __RPC_unique_pointer >> +#define __RPC_string >> +#define __RPC__deref_inout_opt >> +#define __RPC__out >> +#ifndef __RPC__out_ecount_part >> +#define __RPC__out_ecount_part(x, y) >> +#endif >> +#define _declspec(x) >> +#undef uuid >> +#define uuid(x) >> + >> +/* Undef some duplicated error codes redefined in vss.h */ >> +#undef VSS_E_BAD_STATE >> +#undef VSS_E_PROVIDER_NOT_REGISTERED >> +#undef VSS_E_PROVIDER_VETO >> +#undef VSS_E_OBJECT_NOT_FOUND >> +#undef VSS_E_VOLUME_NOT_SUPPORTED >> +#undef VSS_E_VOLUME_NOT_SUPPORTED_BY_PROVIDER >> +#undef VSS_E_OBJECT_ALREADY_EXISTS >> +#undef VSS_E_UNEXPECTED_PROVIDER_ERROR >> +#undef VSS_E_INVALID_XML_DOCUMENT >> +#undef VSS_E_MAXIMUM_NUMBER_OF_VOLUMES_REACHED >> +#undef VSS_E_MAXIMUM_NUMBER_OF_SNAPSHOTS_REACHED >> + >> +/* >> + * VSS headers must be installed from Microsoft VSS SDK 7.2 available at: >> + * http://www.microsoft.com/en-us/download/details.aspx?id=23490 >> + */ >> +#include "inc/win2003/vss.h" >> + >> +/* Macros to convert char definitions to wchar */ >> +#define _L(a) L##a >> +#define L(a) _L(a) (Sigh. The more windows code I'm looking at the more it convinces me that EFI was 100% meant for windows originally. Sad.) >> + >> +/* Constants for QGA VSS Provider */ >> + >> +#define QGA_PROVIDER_NAME "QEMU Guest Agent VSS Provider" >> +#define QGA_PROVIDER_LNAME L(QGA_PROVIDER_NAME) >> +#define QGA_PROVIDER_VERSION L(QEMU_VERSION) >> + >> +#define EVENT_NAME_FROZEN "Global\\QGAVSSEvent-frozen" >> +#define EVENT_NAME_THAW "Global\\QGAVSSEvent-thaw" No idea what I'm talking about, but since we're qualifying the second component with the "QGAVSSEvent" prefix, shouldn't we just replace the first component ("Global") with it? Or would it effect "event routing"? (Tangential question, anyway.) >> + >> +const GUID g_gProviderId = { 0x3629d4ed, 0xee09, 0x4e0e, >> +{0x9a, 0x5c, 0x6d, 0x8b, 0xa2, 0x87, 0x2a, 0xef} }; >> +const GUID g_gProviderVersion = { 0x11ef8b15, 0xcac6, 0x40d6, >> +{0x8d, 0x5c, 0x8f, 0xfc, 0x16, 0x3f, 0x24, 0xca} }; >> + >> +const CLSID CLSID_QGAVSSProvider = { 0x6e6a3492, 0x8d4d, 0x440c, >> +{0x96, 0x19, 0x5e, 0x5d, 0x0c, 0xc3, 0x1c, 0xa8} }; >> + >> +const TCHAR g_szClsid[] = TEXT("{6E6A3492-8D4D-440C-9619-5E5D0CC31CA8}"); OK, these match each other and "qga-provider.idl". >> +const TCHAR g_szProgid[] = TEXT("QGAVSSProvider"); >> + >> +/* Enums undefined in VSS SDK 7.2 but defined in newer Windows SDK */ >> +en
Re: [Qemu-devel] [PATCH] vmdk: remove wrong calculation of relative path
Am 26.06.2013 um 11:24 hat Fam Zheng geschrieben: > When creating image with backing file, the driver tries to calculate the > relative path from created image file to backing file, but the path > computation is incorrect. e.g.: > > $ qemu-img create -f vmdk -b vmdk-data-disk.vmdk vmdk-data-snapshot1 > Formatting 'vmdk-data-snapshot1', fmt=vmdk size=10737418240 > backing_file='vmdk-data-disk.vmdk' compat6=off zeroed_grain=off > > $ qemu-img info vmdk-data-snapshot1 > image: vmdk-data-snapshot1 > file format: vmdk > virtual size: 10G (10737418240 bytes) > disk size: 12K > -> backing file: disk.vmdk > > The common part in file names, "vmdk-data-", is incorrectly forgotten by > relative_path(). As the VMDK specification has no restriction on > parentNameHint to be relative path, we simply remove this by using the > backing_file option. > > Signed-off-by: Fam Zheng Nice one. Thanks, applied to the block branch. Kevin
Re: [Qemu-devel] [PATCH v11 14/15] rdma: introduce MIG_STATE_NONE and change MIG_STATE_SETUP state transition
Il 26/06/2013 16:09, Michael R. Hines ha scritto: > *This requires some steps:* > 1. First, maintain a new data structure: something like > "These memory ranges are 'being unpinned'" - block all potential writes > to these addresses until the unpinning completes. > 2. Once the source unpin completes, send the asynchronous control > channel message > to the other side for unpinning. > 2. Mark the data structure and return and allow the migration to continue > with the next RDMA write. > 3. Upon completion of the unpinning on the destination, > respond to the source that it was finished. > 4. Source then clears the data structure for the successfully unpinned > memory ranges. > 5. At this point, one or more writes may (or may not) be blocking on the > unpinned memory areas and will poll the data structure and find that > the unpinning has completed. > 6. Then issue the new writes and proceed as normal. > 7. Repeat step 1. After more discussion on IRC I think I understand this. It's not trivial, but not super-complex either... it would really be nice to add it to the protocol already in 1.6. Paolo
[Qemu-devel] [Bug 1173490] Re: virtio net adapter driver with kvm slow on winxp
spice-guest-tools-0.3 works well. In spice-guest-tools-0.52 and 0.59, svchost.exe will use 50% cpu. -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1173490 Title: virtio net adapter driver with kvm slow on winxp Status in QEMU: New Bug description: # lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description:Ubuntu 12.04.1 LTS Release:12.04 Codename: precise #virsh version Compiled against library: libvirt 1.0.4 Using library: libvirt 1.0.4 Using API: QEMU 1.0.4 Running hypervisor: QEMU 1.2.0 windows xp clean install with spice-guest-tools-0.52.exe from http://spice-space.org/download/windows/spice-guest-tools/spice-guest-tools-0.52.exe it comes very slow , and the Interrupts process got very high cpu usage(above 60%). when i switch the net adapter from virtio to default(rtl8139) ,it works well. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1173490/+subscriptions
[Qemu-devel] [PATCH v4] s390: Implement dump-guest-memory support for target s390x
With this patch dump-guest-memory on s390 produces an ELF formatted, crash-readable dump. In order to implement this, the arch-specific part of dump-guest-memory was added: target-s390x/arch_dump.c contains the whole set of function for writing Elf note sections of all types for s390x. Signed-off-by: Ekaterina Tumanova Signed-off-by: Jens Freimann [fixed indentation, use CamelCase, rename note_t to Note, use S390CPU] --- include/elf.h | 6 ++ target-s390x/Makefile.objs | 2 +- target-s390x/arch_dump.c | 213 + target-s390x/cpu-qom.h | 5 ++ target-s390x/cpu.c | 4 + 5 files changed, 229 insertions(+), 1 deletion(-) create mode 100644 target-s390x/arch_dump.c diff --git a/include/elf.h b/include/elf.h index cf0d3e2..58bfbf8 100644 --- a/include/elf.h +++ b/include/elf.h @@ -1348,11 +1348,17 @@ typedef struct elf64_shdr { /* Notes used in ET_CORE */ #define NT_PRSTATUS1 +#define NT_FPREGSET 2 #define NT_PRFPREG 2 #define NT_PRPSINFO3 #define NT_TASKSTRUCT 4 #define NT_AUXV6 #define NT_PRXFPREG 0x46e62b7f /* copied from gdb5.1/include/elf/common.h */ +#define NT_S390_PREFIX 0x305 /* s390 prefix register */ +#define NT_S390_CTRS0x304 /* s390 control registers */ +#define NT_S390_TODPREG 0x303 /* s390 TOD programmable register */ +#define NT_S390_TODCMP 0x302 /* s390 TOD clock comparator register */ +#define NT_S390_TIMER 0x301 /* s390 timer register */ /* Note header in a PT_NOTE section */ diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs index 4e63417..c34f654 100644 --- a/target-s390x/Makefile.objs +++ b/target-s390x/Makefile.objs @@ -1,4 +1,4 @@ obj-y += translate.o helper.o cpu.o interrupt.o obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o misc_helper.o -obj-$(CONFIG_SOFTMMU) += ioinst.o +obj-$(CONFIG_SOFTMMU) += ioinst.o arch_dump.o obj-$(CONFIG_KVM) += kvm.o diff --git a/target-s390x/arch_dump.c b/target-s390x/arch_dump.c new file mode 100644 index 000..bc8db62 --- /dev/null +++ b/target-s390x/arch_dump.c @@ -0,0 +1,213 @@ +/* + * writing ELF notes for s390x arch + * + * + * Copyright IBM Corp. 2012, 2013 + * + * Ekaterina Tumanova + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include "cpu.h" +#include "cpu-qom.h" +#include "elf.h" +#include "exec/cpu-all.h" +#include "sysemu/dump.h" +#include "sysemu/kvm.h" + + +struct S390xUserRegsStruct { +uint64_t psw[2]; +uint64_t gprs[16]; +uint32_t acrs[16]; +} QEMU_PACKED; + +typedef struct S390xUserRegsStruct S390xUserRegs; + +struct S390xElfPrstatusStruct { +uint8_t pad1[32]; +uint32_t pid; +uint8_t pad2[76]; +S390xUserRegs regs; +uint8_t pad3[16]; +} QEMU_PACKED; + +typedef struct S390xElfPrstatusStruct S390xElfPrstatus; + +struct S390xElfFpregsetStruct { +uint32_t fpc; +uint32_t pad; +uint64_t fprs[16]; +} QEMU_PACKED; + +typedef struct S390xElfFpregsetStruct S390xElfFpregset; + +typedef struct noteStruct { +Elf64_Nhdr hdr; +char name[5]; +char pad3[3]; +union { +S390xElfPrstatus prstatus; +S390xElfFpregset fpregset; +uint32_t prefix; +uint64_t timer; +uint64_t todcmp; +uint32_t todpreg; +uint64_t ctrs[16]; +} contents; +} QEMU_PACKED Note; + +static void s390x_write_elf64_prstatus(Note *note, S390CPU *cpu) +{ +int i; +S390xUserRegs *regs; + +note->hdr.n_type = cpu_to_be32(NT_PRSTATUS); + +regs = &(note->contents.prstatus.regs); +regs->psw[0] = cpu_to_be64(cpu->env.psw.mask); +regs->psw[1] = cpu_to_be64(cpu->env.psw.addr); +for (i = 0; i <= 15; i++) { +regs->acrs[i] = cpu_to_be32(cpu->env.aregs[i]); +regs->gprs[i] = cpu_to_be64(cpu->env.regs[i]); +} +} + +static void s390x_write_elf64_fpregset(Note *note, S390CPU *cpu) +{ +int i; + +note->hdr.n_type = cpu_to_be32(NT_FPREGSET); +note->contents.fpregset.fpc = cpu_to_be32(cpu->env.fpc); +for (i = 0; i <= 15; i++) { +note->contents.fpregset.fprs[i] = cpu_to_be64(cpu->env.fregs[i].ll); +} +} + + +static void s390x_write_elf64_timer(Note *note, S390CPU *cpu) +{ +note->hdr.n_type = cpu_to_be32(NT_S390_TIMER); +note->contents.timer = cpu_to_be64((uint64_t)(cpu->env.cputm)); +} + +static void s390x_write_elf64_todcmp(Note *note, S390CPU *cpu) +{ +note->hdr.n_type = cpu_to_be32(NT_S390_TODCMP); +note->contents.todcmp = cpu_to_be64((uint64_t)(cpu->env.ckc)); +} + +static void s390x_write_elf64_todpreg(Note *note, S390CPU *cpu) +{ +note->hdr.n_type = cpu_to_be32(NT_S390_TODPREG); +note->contents.todpreg = cpu_to_be32((uint32_t)(cpu->env.todpr)); +} + +static void s390x_write_elf64_ctrs(Note *note, S390CPU *cpu) +{ +int i; + +note->hdr.n_type = cpu_to_be32(NT