Re: [Qemu-devel] [PATCH v2] Fix segfault on migration completion
Luiz Capitulino lcapitul...@redhat.com writes: A simple migration reproduces it: 1. Start the source VM with: # qemu [...] -S 2. Start the destination VM with: # qemu source VM cmd-line -incoming tcp:0: 3. In the source VM: (qemu) migrate -d tcp:0: 4. The source VM will segfault as soon as migration completes (might not happen in the first try) What is happening here is that qemu_file_put_notify() can end up closing 's-file' (in which case it's also set to NULL). The call stack is rather complex, but Eduardo helped tracking it to: select loop - migrate_fd_put_notify() - qemu_file_put_notify() - buffered_put_buffer() - migrate_fd_put_ready() - migrate_fd_completed() - migrate_fd_cleanup(). To be honest, it's not completely clear to me in which cases 's-file' is not closed (on error maybe)? But I doubt this fix will make anything worse. Reviewed-by: Paolo Bonzini pbonz...@redhat.com Acked-by: Eduardo Habkost ehabk...@redhat.com Signed-off-by: Luiz Capitulino lcapitul...@redhat.com --- V2: better commit log migration.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/migration.c b/migration.c index bdca72e..f6e6208 100644 --- a/migration.c +++ b/migration.c @@ -252,7 +252,7 @@ static void migrate_fd_put_notify(void *opaque) qemu_set_fd_handler2(s-fd, NULL, NULL, NULL, NULL); qemu_file_put_notify(s-file); -if (qemu_file_get_error(s-file)) { +if (s-file qemu_file_get_error(s-file)) { migrate_fd_error(s); } } I wonder whether we can lose the error in s-file by closing s-file before we get here. But even if we can, we still report more errors than before the series this patch fixes.
Re: [Qemu-devel] [PATCH 0/2] VGA related patches
Please thread together your patches so that the parts appear as replies to the cover letter. git-send-email should do that by default. Why? Disconnected parts can easily get separated in the list. When that happens, your reviewers need to hunt for parts. They may choose to review something else instead. Can't blame them; reviewing is more productive than hunting for parts.
Re: [Qemu-devel] [PATCH] cmd: Fix potential NULL pointer dereference
Pavel Borzenkov pavel.borzen...@gmail.com writes: Signed-off-by: Pavel Borzenkov pavel.borzen...@gmail.com --- Note, that almost all code in the file violates CODING STYLE. The changed lines are written wrt CODING STYLE (like commits 7d7d975c and c32d766a). --- cmd.c | 11 +++ 1 files changed, 3 insertions(+), 8 deletions(-) diff --git a/cmd.c b/cmd.c index f77897e..abcf206 100644 --- a/cmd.c +++ b/cmd.c @@ -49,7 +49,7 @@ void add_command( const cmdinfo_t *ci) { - cmdtab = realloc((void *)cmdtab, ++ncmds * sizeof(*cmdtab)); +cmdtab = g_realloc((void *)cmdtab, ++ncmds * sizeof(*cmdtab)); cmdtab[ncmds - 1] = *ci; qsort(cmdtab, ncmds, sizeof(*cmdtab), compare); } Inconsistent indentation. Either stick to the original indentation, or reindent the whole function. [More of the same...]
Re: [Qemu-devel] [PATCH] Support running QEMU on Valgrind
Alexander Graf ag...@suse.de writes: On 30.10.2011, at 13:07, Stefan Weil wrote: Valgrind is a tool which can automatically detect many kinds of bugs. Running QEMU on Valgrind with x86_64 hosts was not possible because Valgrind aborts when memalign is called with an alignment larger than 1 MiB. QEMU normally uses 2 MiB on Linux x86_64. Now the alignment is reduced to the page size when QEMU is running on Valgrind. valgrind.h is a copy from Valgrind svn trunk r12226 with trailing whitespace stripped but otherwise unmodified, so it still raises lots of errors when checked with scripts/checkpatch.pl. Can't we just require valgrind header files to be around when kvm is enabled? I would rather not copy code from other projects. Alternatively you could take the header and shrink it down to maybe 5 lines of inline asm code that would be a lot more readable :). You're #ifdef'ing on x86_64 already anyways. It is included here to avoid a dependency on Valgrind. Our usual way to avoid a hard dependency on something we want is to detect it in configure, then do something like #ifdef CONFIG_VALGRIND #include valgrind.h #else #define RUNNING_ON_VALGRIND 0 #endif [...]
[Qemu-devel] [0/14] Preliminary work for IOMMU emulation support (v3)
A while back, Eduard - Gabriel Munteanu send a series of patches implementing support for emulating the AMD IOMMU in conjunction with qemu emulated PCI devices. A revised patch series added support for the Intel IOMMU, and I also send a revised version of this series which added support for the hypervisor mediated IOMMU on the pseries machine. Richard Henderson also weighed in on the discussion, and there's still a cretain amount to be thrashed out in terms of exactly how to set up an IOMMU / DMA translation subsystem. However, really only 2 or 3 patches in any of these series have contained anything interesting. The rest of the series has been converting existing PCI emulated devices to use the new DMA interface which worked through the IOMMU translation, whatever it was. While we keep working out what we want for the guts of the IOMMU support, these device conversion patches keep bitrotting against updates to the various device implementations themselves. Really, regardless of whether we're actually implementing IOMMU translation, it makes sense that qemu code should distinguish between when it is really operating in CPU physical addresses and when it is operating in bus or DMA addresses which might have some kind of translation into physical addresses. This series, therefore, begins the conversion of existing PCI device emulation code to use new (stub) pci dma access functions. These are, for now, just defined to be untranslated cpu physical memory accesses, as before, but has three advantages: * It becomes obvious where the code is working with dma addresses, so it's easier to grep for what might be affected by an IOMMU or other bus address translation. * The new stubs take the PCIDevice *, from which any of the various suggested IOMMU interfaces should be able to locate the correct IOMMU translation context. * The new pci_dma_{read,write}() functions have a return value. When we do have IOMMU support, translation failures could lead to these functions failing, so we want a way to report it. This series converts all the easy cases. It doesn't yet handle devices which have both PCI and non-PCI variants, such as AHCI, OHCI and ne2k. Unlike the earlier version of this series, functions using scatter gather _are_ covered, though. Changes since v2: * Moved the stub functions from pci.c to pci.h, making them inlines * Changed the stX/ldX_pci_dma() functions call stX/ldX_phys() directly, rather than using pci_dma_rw(). This means that they should access the host memory atomically, previously this was an unstated and dangerous semantic change. * Cleaned up and split out definition of dma_addr_t, DMADirection and their use in the scatter/gather code. * Added a DMA_ADDR_FMT define for using dma_addr_t values in printf() and used this in some of the driver updates.
Re: [Qemu-devel] [PATCH] Support running QEMU on Valgrind
Alexander Graf ag...@suse.de writes: On 30.10.2011, at 15:30, Stefan Weil wrote: Am 30.10.2011 14:41, schrieb Alexander Graf: On 30.10.2011, at 13:07, Stefan Weil wrote: Valgrind is a tool which can automatically detect many kinds of bugs. Running QEMU on Valgrind with x86_64 hosts was not possible because Valgrind aborts when memalign is called with an alignment larger than 1 MiB. QEMU normally uses 2 MiB on Linux x86_64. Now the alignment is reduced to the page size when QEMU is running on Valgrind. valgrind.h is a copy from Valgrind svn trunk r12226 with trailing whitespace stripped but otherwise unmodified, so it still raises lots of errors when checked with scripts/checkpatch.pl. Can't we just require valgrind header files to be around when kvm is enabled? I would rather not copy code from other projects. Alternatively you could take the header and shrink it down to maybe 5 lines of inline asm code that would be a lot more readable :). You're #ifdef'ing on x86_64 already anyways. The patch is currently required for x86_64 hosts running Linux. I estimate that this is one of the most frequently used QEMU host platforms, and in most cases, KVM will be configured because this is the default and also because it is reasonable for this platform. How many of these hosts will have the Valgrind header around? I estimate less than 20 %, so configure would have to test whether valgrind.h is available or not. I think providing valgrind.h is a much better (and simpler) solution. Hrm. I see your point. Stripping valgrind.h is not a good idea: the file is specially designed to be included in other projects like QEMU. As soon as the 2 MiB alignment is used for other hosts (ppc64, ...), you would have to take more and more from the original code. The file was not designed to be readable. Although it contains lots of comments which improve readability, there remains code which is less easy to read. I cite one of those comments: /* The following defines the magic code sequences which the JITter spots and handles magically. Don't look too closely at them as they will rot your brain. Instead of rotting my brain, I prefer using a copy of the original code. Yes, copies are evil. Could we maybe use a git submodule to point to the valgrind repo and fetch it from there? Anyone sophisticated enough to make use of valgrind should be able to install valgrind.h just fine. It's not rocket science: # yum provides \*/valgrind.h [...] # yum install valgrind-devel [...]
[Qemu-devel] [PATCH 12/14] PCI IDE: Use PCI DMA stub functions
This updates the PCI IDE device emulation to use the explicit PCI DMA wrapper to initialize its scatter/gathjer structure. This means this driver should not need further changes when the sglist interface is extended to support IOMMUs. Signed-off-by: David Gibson da...@gibson.dropbear.id.au --- hw/ide/pci.c | 19 ++- 1 files changed, 10 insertions(+), 9 deletions(-) diff --git a/hw/ide/pci.c b/hw/ide/pci.c index f133c42..49b823d 100644 --- a/hw/ide/pci.c +++ b/hw/ide/pci.c @@ -62,7 +62,8 @@ static int bmdma_prepare_buf(IDEDMA *dma, int is_write) } prd; int l, len; -qemu_sglist_init(s-sg, s-nsector / (BMDMA_PAGE_SIZE / 512) + 1); +pci_dma_sglist_init(s-sg, bm-pci_dev-dev, +s-nsector / (BMDMA_PAGE_SIZE / 512) + 1); s-io_buffer_size = 0; for(;;) { if (bm-cur_prd_len == 0) { @@ -70,7 +71,7 @@ static int bmdma_prepare_buf(IDEDMA *dma, int is_write) if (bm-cur_prd_last || (bm-cur_addr - bm-addr) = BMDMA_PAGE_SIZE) return s-io_buffer_size != 0; -cpu_physical_memory_read(bm-cur_addr, (uint8_t *)prd, 8); +pci_dma_read(bm-pci_dev-dev, bm-cur_addr, (uint8_t *)prd, 8); bm-cur_addr += 8; prd.addr = le32_to_cpu(prd.addr); prd.size = le32_to_cpu(prd.size); @@ -112,7 +113,7 @@ static int bmdma_rw_buf(IDEDMA *dma, int is_write) if (bm-cur_prd_last || (bm-cur_addr - bm-addr) = BMDMA_PAGE_SIZE) return 0; -cpu_physical_memory_read(bm-cur_addr, (uint8_t *)prd, 8); +pci_dma_read(bm-pci_dev-dev, bm-cur_addr, (uint8_t *)prd, 8); bm-cur_addr += 8; prd.addr = le32_to_cpu(prd.addr); prd.size = le32_to_cpu(prd.size); @@ -127,11 +128,11 @@ static int bmdma_rw_buf(IDEDMA *dma, int is_write) l = bm-cur_prd_len; if (l 0) { if (is_write) { -cpu_physical_memory_write(bm-cur_prd_addr, - s-io_buffer + s-io_buffer_index, l); +pci_dma_write(bm-pci_dev-dev, bm-cur_prd_addr, + s-io_buffer + s-io_buffer_index, l); } else { -cpu_physical_memory_read(bm-cur_prd_addr, - s-io_buffer + s-io_buffer_index, l); +pci_dma_read(bm-pci_dev-dev, bm-cur_prd_addr, + s-io_buffer + s-io_buffer_index, l); } bm-cur_prd_addr += l; bm-cur_prd_len -= l; @@ -326,7 +327,7 @@ void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val) bm-cmd = val 0x09; } -static uint64_t bmdma_addr_read(void *opaque, target_phys_addr_t addr, +static uint64_t bmdma_addr_read(void *opaque, dma_addr_t addr, unsigned width) { BMDMAState *bm = opaque; @@ -340,7 +341,7 @@ static uint64_t bmdma_addr_read(void *opaque, target_phys_addr_t addr, return data; } -static void bmdma_addr_write(void *opaque, target_phys_addr_t addr, +static void bmdma_addr_write(void *opaque, dma_addr_t addr, uint64_t data, unsigned width) { BMDMAState *bm = opaque; -- 1.7.7
[Qemu-devel] [PATCH 07/14] es1370: Use PCI DMA stub functions
From: Eduard - Gabriel Munteanu eduard.munte...@linux360.ro This updates the es1370 device emulation to use the explicit PCI DMA functions, instead of directly calling physical memory access functions. Signed-off-by: Eduard - Gabriel Munteanu eduard.munte...@linux360.ro Signed-off-by: David Gibson da...@gibson.dropbear.id.au --- hw/es1370.c |5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/hw/es1370.c b/hw/es1370.c index 2daadde..c5c16b0 100644 --- a/hw/es1370.c +++ b/hw/es1370.c @@ -30,6 +30,7 @@ #include audiodev.h #include audio/audio.h #include pci.h +#include dma.h /* Missing stuff: SCTRL_P[12](END|ST)INC @@ -802,7 +803,7 @@ static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel, if (!acquired) break; -cpu_physical_memory_write (addr, tmpbuf, acquired); +pci_dma_write (s-dev, addr, tmpbuf, acquired); temp -= acquired; addr += acquired; @@ -816,7 +817,7 @@ static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel, int copied, to_copy; to_copy = audio_MIN ((size_t) temp, sizeof (tmpbuf)); -cpu_physical_memory_read (addr, tmpbuf, to_copy); +pci_dma_read (s-dev, addr, tmpbuf, to_copy); copied = AUD_write (voice, tmpbuf, to_copy); if (!copied) break; -- 1.7.7
[Qemu-devel] [PATCH 11/14] intel-hda: Use PCI DMA stub functions
This updates the intel-hda device emulation to use the explicit PCI DMA functions, instead of directly calling physical memory access functions. Signed-off-by: David Gibson da...@gibson.dropbear.id.au Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- hw/intel-hda.c | 14 +++--- 1 files changed, 7 insertions(+), 7 deletions(-) diff --git a/hw/intel-hda.c b/hw/intel-hda.c index f97775c..888ca96 100644 --- a/hw/intel-hda.c +++ b/hw/intel-hda.c @@ -24,6 +24,7 @@ #include audiodev.h #include intel-hda.h #include intel-hda-defs.h +#include dma.h /* - */ /* hda bus */ @@ -328,7 +329,7 @@ static void intel_hda_corb_run(IntelHDAState *d) rp = (d-corb_rp + 1) 0xff; addr = intel_hda_addr(d-corb_lbase, d-corb_ubase); -verb = ldl_le_phys(addr + 4*rp); +verb = ldl_le_pci_dma(d-pci, addr + 4*rp); d-corb_rp = rp; dprint(d, 2, %s: [rp 0x%x] verb 0x%08x\n, __FUNCTION__, rp, verb); @@ -360,8 +361,8 @@ static void intel_hda_response(HDACodecDevice *dev, bool solicited, uint32_t res ex = (solicited ? 0 : (1 4)) | dev-cad; wp = (d-rirb_wp + 1) 0xff; addr = intel_hda_addr(d-rirb_lbase, d-rirb_ubase); -stl_le_phys(addr + 8*wp, response); -stl_le_phys(addr + 8*wp + 4, ex); +stl_le_pci_dma(d-pci, addr + 8*wp, response); +stl_le_pci_dma(d-pci, addr + 8*wp + 4, ex); d-rirb_wp = wp; dprint(d, 2, %s: [wp 0x%x] response 0x%x, extra 0x%x\n, @@ -426,8 +427,7 @@ static bool intel_hda_xfer(HDACodecDevice *dev, uint32_t stnr, bool output, dprint(d, 3, dma: entry %d, pos %d/%d, copy %d\n, st-be, st-bp, st-bpl[st-be].len, copy); -cpu_physical_memory_rw(st-bpl[st-be].addr + st-bp, - buf, copy, !output); +pci_dma_rw(d-pci, st-bpl[st-be].addr + st-bp, buf, copy, !output); st-lpib += copy; st-bp += copy; buf += copy; @@ -449,7 +449,7 @@ static bool intel_hda_xfer(HDACodecDevice *dev, uint32_t stnr, bool output, } if (d-dp_lbase 0x01) { addr = intel_hda_addr(d-dp_lbase ~0x01, d-dp_ubase); -stl_le_phys(addr + 8*s, st-lpib); +stl_le_pci_dma(d-pci, addr + 8*s, st-lpib); } dprint(d, 3, dma: --\n); @@ -471,7 +471,7 @@ static void intel_hda_parse_bdl(IntelHDAState *d, IntelHDAStream *st) g_free(st-bpl); st-bpl = g_malloc(sizeof(bpl) * st-bentries); for (i = 0; i st-bentries; i++, addr += 16) { -cpu_physical_memory_read(addr, buf, 16); +pci_dma_read(d-pci, addr, buf, 16); st-bpl[i].addr = le64_to_cpu(*(uint64_t *)buf); st-bpl[i].len = le32_to_cpu(*(uint32_t *)(buf + 8)); st-bpl[i].flags = le32_to_cpu(*(uint32_t *)(buf + 12)); -- 1.7.7
[Qemu-devel] [PATCH 08/14] e1000: Use PCI DMA stub functions
From: Eduard - Gabriel Munteanu eduard.munte...@linux360.ro This updates the e1000 device emulation to use the explicit PCI DMA functions, instead of directly calling physical memory access functions. Signed-off-by: Eduard - Gabriel Munteanu eduard.munte...@linux360.ro Signed-off-by: David Gibson da...@gibson.dropbear.id.au --- hw/e1000.c | 29 +++-- 1 files changed, 15 insertions(+), 14 deletions(-) diff --git a/hw/e1000.c b/hw/e1000.c index ce8fc8b..986ed9c 100644 --- a/hw/e1000.c +++ b/hw/e1000.c @@ -31,6 +31,7 @@ #include net/checksum.h #include loader.h #include sysemu.h +#include dma.h #include e1000_hw.h @@ -465,7 +466,7 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp) bytes = split_size; if (tp-size + bytes msh) bytes = msh - tp-size; -cpu_physical_memory_read(addr, tp-data + tp-size, bytes); +pci_dma_read(s-dev, addr, tp-data + tp-size, bytes); if ((sz = tp-size + bytes) = hdr tp-size hdr) memmove(tp-header, tp-data, hdr); tp-size = sz; @@ -480,7 +481,7 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp) // context descriptor TSE is not set, while data descriptor TSE is set DBGOUT(TXERR, TCP segmentaion Error\n); } else { -cpu_physical_memory_read(addr, tp-data + tp-size, split_size); +pci_dma_read(s-dev, addr, tp-data + tp-size, split_size); tp-size += split_size; } @@ -496,7 +497,7 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp) } static uint32_t -txdesc_writeback(target_phys_addr_t base, struct e1000_tx_desc *dp) +txdesc_writeback(E1000State *s, dma_addr_t base, struct e1000_tx_desc *dp) { uint32_t txd_upper, txd_lower = le32_to_cpu(dp-lower.data); @@ -505,8 +506,8 @@ txdesc_writeback(target_phys_addr_t base, struct e1000_tx_desc *dp) txd_upper = (le32_to_cpu(dp-upper.data) | E1000_TXD_STAT_DD) ~(E1000_TXD_STAT_EC | E1000_TXD_STAT_LC | E1000_TXD_STAT_TU); dp-upper.data = cpu_to_le32(txd_upper); -cpu_physical_memory_write(base + ((char *)dp-upper - (char *)dp), - (void *)dp-upper, sizeof(dp-upper)); +pci_dma_write(s-dev, base + ((char *)dp-upper - (char *)dp), + (void *)dp-upper, sizeof(dp-upper)); return E1000_ICR_TXDW; } @@ -521,7 +522,7 @@ static uint64_t tx_desc_base(E1000State *s) static void start_xmit(E1000State *s) { -target_phys_addr_t base; +dma_addr_t base; struct e1000_tx_desc desc; uint32_t tdh_start = s-mac_reg[TDH], cause = E1000_ICS_TXQE; @@ -533,14 +534,14 @@ start_xmit(E1000State *s) while (s-mac_reg[TDH] != s-mac_reg[TDT]) { base = tx_desc_base(s) + sizeof(struct e1000_tx_desc) * s-mac_reg[TDH]; -cpu_physical_memory_read(base, (void *)desc, sizeof(desc)); +pci_dma_read(s-dev, base, (void *)desc, sizeof(desc)); DBGOUT(TX, index %d: %p : %x %x\n, s-mac_reg[TDH], (void *)(intptr_t)desc.buffer_addr, desc.lower.data, desc.upper.data); process_tx_desc(s, desc); -cause |= txdesc_writeback(base, desc); +cause |= txdesc_writeback(s, base, desc); if (++s-mac_reg[TDH] * sizeof(desc) = s-mac_reg[TDLEN]) s-mac_reg[TDH] = 0; @@ -668,7 +669,7 @@ e1000_receive(VLANClientState *nc, const uint8_t *buf, size_t size) { E1000State *s = DO_UPCAST(NICState, nc, nc)-opaque; struct e1000_rx_desc desc; -target_phys_addr_t base; +dma_addr_t base; unsigned int n, rdt; uint32_t rdh_start; uint16_t vlan_special = 0; @@ -713,7 +714,7 @@ e1000_receive(VLANClientState *nc, const uint8_t *buf, size_t size) desc_size = s-rxbuf_size; } base = rx_desc_base(s) + sizeof(desc) * s-mac_reg[RDH]; -cpu_physical_memory_read(base, (void *)desc, sizeof(desc)); +pci_dma_read(s-dev, base, (void *)desc, sizeof(desc)); desc.special = vlan_special; desc.status |= (vlan_status | E1000_RXD_STAT_DD); if (desc.buffer_addr) { @@ -722,9 +723,9 @@ e1000_receive(VLANClientState *nc, const uint8_t *buf, size_t size) if (copy_size s-rxbuf_size) { copy_size = s-rxbuf_size; } -cpu_physical_memory_write(le64_to_cpu(desc.buffer_addr), - (void *)(buf + desc_offset + vlan_offset), - copy_size); +pci_dma_write(s-dev, le64_to_cpu(desc.buffer_addr), + (void *)(buf + desc_offset + vlan_offset), + copy_size); } desc_offset += desc_size; desc.length = cpu_to_le16(desc_size); @@ -738,7 +739,7 @@ e1000_receive(VLANClientState *nc, const uint8_t *buf, size_t size) }
[Qemu-devel] [PATCH 02/14] Use dma_addr_t type for scatter/gather code
This patch uses the newly created dma_addr_t type throughout the scatter/gather handling code in dma-helpers.c whenever we need to represent a dma bus address. This makes a better distinction as to what is a bus address and what is a cpu physical address. Since we don't support IOMMUs yet, they can't be very different for now, but that will change in future, and this preliminary helps clarify what's going on. Signed-off-by: David Gibson da...@gibson.dropbear.id.au --- dma-helpers.c |5 ++--- dma.h |9 - 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/dma-helpers.c b/dma-helpers.c index 86d2d0a..bdcd38c 100644 --- a/dma-helpers.c +++ b/dma-helpers.c @@ -18,8 +18,7 @@ void qemu_sglist_init(QEMUSGList *qsg, int alloc_hint) qsg-size = 0; } -void qemu_sglist_add(QEMUSGList *qsg, target_phys_addr_t base, - target_phys_addr_t len) +void qemu_sglist_add(QEMUSGList *qsg, dma_addr_t base, dma_addr_t len) { if (qsg-nsg == qsg-nalloc) { qsg-nalloc = 2 * qsg-nalloc + 1; @@ -45,7 +44,7 @@ typedef struct { bool to_dev; bool in_cancel; int sg_cur_index; -target_phys_addr_t sg_cur_byte; +dma_addr_t sg_cur_byte; QEMUIOVector iov; QEMUBH *bh; DMAIOFunc *io_func; diff --git a/dma.h b/dma.h index 56e163a..a13209d 100644 --- a/dma.h +++ b/dma.h @@ -28,20 +28,19 @@ typedef enum { } DMADirection; struct ScatterGatherEntry { -target_phys_addr_t base; -target_phys_addr_t len; +dma_addr_t base; +dma_addr_t len; }; struct QEMUSGList { ScatterGatherEntry *sg; int nsg; int nalloc; -target_phys_addr_t size; +dma_addr_t size; }; void qemu_sglist_init(QEMUSGList *qsg, int alloc_hint); -void qemu_sglist_add(QEMUSGList *qsg, target_phys_addr_t base, - target_phys_addr_t len); +void qemu_sglist_add(QEMUSGList *qsg, dma_addr_t base, dma_addr_t len); void qemu_sglist_destroy(QEMUSGList *qsg); #endif -- 1.7.7
[Qemu-devel] [PATCH 04/14] rtl8139: Use PCI DMA stub functions
From: Eduard - Gabriel Munteanu eduard.munte...@linux360.ro This updates the rtl8139 device emulation to use the explicit PCI DMA functions, instead of directly calling physical memory access functions. Signed-off-by: Eduard - Gabriel Munteanu eduard.munte...@linux360.ro Signed-off-by: David Gibson da...@gibson.dropbear.id.au --- hw/rtl8139.c | 106 + 1 files changed, 54 insertions(+), 52 deletions(-) diff --git a/hw/rtl8139.c b/hw/rtl8139.c index 3753950..4c37993 100644 --- a/hw/rtl8139.c +++ b/hw/rtl8139.c @@ -53,6 +53,7 @@ #include hw.h #include pci.h +#include dma.h #include qemu-timer.h #include net.h #include loader.h @@ -427,9 +428,6 @@ typedef struct RTL8139TallyCounters /* Clears all tally counters */ static void RTL8139TallyCounters_clear(RTL8139TallyCounters* counters); -/* Writes tally counters to specified physical memory address */ -static void RTL8139TallyCounters_physical_memory_write(target_phys_addr_t tc_addr, RTL8139TallyCounters* counters); - typedef struct RTL8139State { PCIDevice dev; uint8_t phys[8]; /* mac address */ @@ -512,6 +510,9 @@ typedef struct RTL8139State { int rtl8139_mmio_io_addr_dummy; } RTL8139State; +/* Writes tally counters to memory via DMA */ +static void RTL8139TallyCounters_dma_write(RTL8139State *s, dma_addr_t tc_addr); + static void rtl8139_set_next_tctr_time(RTL8139State *s, int64_t current_time); static void prom9346_decode_command(EEprom9346 *eeprom, uint8_t command) @@ -773,15 +774,15 @@ static void rtl8139_write_buffer(RTL8139State *s, const void *buf, int size) if (size wrapped) { -cpu_physical_memory_write( s-RxBuf + s-RxBufAddr, - buf, size-wrapped ); +pci_dma_write(s-dev, s-RxBuf + s-RxBufAddr, + buf, size-wrapped); } /* reset buffer pointer */ s-RxBufAddr = 0; -cpu_physical_memory_write( s-RxBuf + s-RxBufAddr, - buf + (size-wrapped), wrapped ); +pci_dma_write(s-dev, s-RxBuf + s-RxBufAddr, + buf + (size-wrapped), wrapped); s-RxBufAddr = wrapped; @@ -790,13 +791,13 @@ static void rtl8139_write_buffer(RTL8139State *s, const void *buf, int size) } /* non-wrapping path or overwrapping enabled */ -cpu_physical_memory_write( s-RxBuf + s-RxBufAddr, buf, size ); +pci_dma_write(s-dev, s-RxBuf + s-RxBufAddr, buf, size); s-RxBufAddr += size; } #define MIN_BUF_SIZE 60 -static inline target_phys_addr_t rtl8139_addr64(uint32_t low, uint32_t high) +static inline dma_addr_t rtl8139_addr64(uint32_t low, uint32_t high) { #if TARGET_PHYS_ADDR_BITS 32 return low | ((target_phys_addr_t)high 32); @@ -979,24 +980,24 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_ /* w3 high 32bit of Rx buffer ptr */ int descriptor = s-currCPlusRxDesc; -target_phys_addr_t cplus_rx_ring_desc; +dma_addr_t cplus_rx_ring_desc; cplus_rx_ring_desc = rtl8139_addr64(s-RxRingAddrLO, s-RxRingAddrHI); cplus_rx_ring_desc += 16 * descriptor; DPRINTF(+++ C+ mode reading RX descriptor %d from host memory at -%08x %08x = TARGET_FMT_plx\n, descriptor, s-RxRingAddrHI, +%08x %08x = DMA_ADDR_FMT\n, descriptor, s-RxRingAddrHI, s-RxRingAddrLO, cplus_rx_ring_desc); uint32_t val, rxdw0,rxdw1,rxbufLO,rxbufHI; -cpu_physical_memory_read(cplus_rx_ring_desc,(uint8_t *)val, 4); +pci_dma_read(s-dev, cplus_rx_ring_desc, (uint8_t *)val, 4); rxdw0 = le32_to_cpu(val); -cpu_physical_memory_read(cplus_rx_ring_desc+4, (uint8_t *)val, 4); +pci_dma_read(s-dev, cplus_rx_ring_desc+4, (uint8_t *)val, 4); rxdw1 = le32_to_cpu(val); -cpu_physical_memory_read(cplus_rx_ring_desc+8, (uint8_t *)val, 4); +pci_dma_read(s-dev, cplus_rx_ring_desc+8, (uint8_t *)val, 4); rxbufLO = le32_to_cpu(val); -cpu_physical_memory_read(cplus_rx_ring_desc+12, (uint8_t *)val, 4); +pci_dma_read(s-dev, cplus_rx_ring_desc+12, (uint8_t *)val, 4); rxbufHI = le32_to_cpu(val); DPRINTF(+++ C+ mode RX descriptor %d %08x %08x %08x %08x\n, @@ -1060,16 +1061,16 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_ return size_; } -target_phys_addr_t rx_addr = rtl8139_addr64(rxbufLO, rxbufHI); +dma_addr_t rx_addr = rtl8139_addr64(rxbufLO, rxbufHI); /* receive/copy to target memory */ if (dot1q_buf) { -cpu_physical_memory_write(rx_addr, buf, 2 * ETHER_ADDR_LEN); -cpu_physical_memory_write(rx_addr + 2 * ETHER_ADDR_LEN, -buf + 2 * ETHER_ADDR_LEN + VLAN_HLEN, -size
[Qemu-devel] [PATCH 09/14] lsi53c895a: Use PCI DMA stub functions
From: Eduard - Gabriel Munteanu eduard.munte...@linux360.ro This updates the lsi53c895a device emulation to use the explicit PCI DMA functions, instead of directly calling physical memory access functions. Signed-off-by: Eduard - Gabriel Munteanu eduard.munte...@linux360.ro Signed-off-by: David Gibson da...@gibson.dropbear.id.au --- hw/lsi53c895a.c | 33 - 1 files changed, 16 insertions(+), 17 deletions(-) diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c index e077ec0..65996db 100644 --- a/hw/lsi53c895a.c +++ b/hw/lsi53c895a.c @@ -15,6 +15,8 @@ #include hw.h #include pci.h #include scsi.h +#include block_int.h +#include dma.h //#define DEBUG_LSI //#define DEBUG_LSI_REG @@ -390,10 +392,7 @@ static inline uint32_t read_dword(LSIState *s, uint32_t addr) { uint32_t buf; -/* XXX: an optimization here used to fast-path the read from scripts - * memory. But that bypasses any iommu. - */ -cpu_physical_memory_read(addr, (uint8_t *)buf, 4); +pci_dma_read(s-dev, addr, (uint8_t *)buf, 4); return cpu_to_le32(buf); } @@ -532,7 +531,7 @@ static void lsi_bad_selection(LSIState *s, uint32_t id) static void lsi_do_dma(LSIState *s, int out) { uint32_t count, id; -target_phys_addr_t addr; +dma_addr_t addr; SCSIDevice *dev; assert(s-current); @@ -562,7 +561,7 @@ static void lsi_do_dma(LSIState *s, int out) else if (s-sbms) addr |= ((uint64_t)s-sbms 32); -DPRINTF(DMA addr=0x TARGET_FMT_plx len=%d\n, addr, count); +DPRINTF(DMA addr=0x DMA_ADDR_FMT len=%d\n, addr, count); s-csbc += count; s-dnad += count; s-dbc -= count; @@ -571,9 +570,9 @@ static void lsi_do_dma(LSIState *s, int out) } /* ??? Set SFBR to first data byte. */ if (out) { -cpu_physical_memory_read(addr, s-current-dma_buf, count); +pci_dma_read(s-dev, addr, s-current-dma_buf, count); } else { -cpu_physical_memory_write(addr, s-current-dma_buf, count); +pci_dma_write(s-dev, addr, s-current-dma_buf, count); } s-current-dma_len -= count; if (s-current-dma_len == 0) { @@ -766,7 +765,7 @@ static void lsi_do_command(LSIState *s) DPRINTF(Send command len=%d\n, s-dbc); if (s-dbc 16) s-dbc = 16; -cpu_physical_memory_read(s-dnad, buf, s-dbc); +pci_dma_read(s-dev, s-dnad, buf, s-dbc); s-sfbr = buf[0]; s-command_complete = 0; @@ -817,7 +816,7 @@ static void lsi_do_status(LSIState *s) s-dbc = 1; status = s-status; s-sfbr = status; -cpu_physical_memory_write(s-dnad, status, 1); +pci_dma_write(s-dev, s-dnad, status, 1); lsi_set_phase(s, PHASE_MI); s-msg_action = 1; lsi_add_msg_byte(s, 0); /* COMMAND COMPLETE */ @@ -831,7 +830,7 @@ static void lsi_do_msgin(LSIState *s) len = s-msg_len; if (len s-dbc) len = s-dbc; -cpu_physical_memory_write(s-dnad, s-msg, len); +pci_dma_write(s-dev, s-dnad, s-msg, len); /* Linux drivers rely on the last byte being in the SIDL. */ s-sidl = s-msg[len - 1]; s-msg_len -= len; @@ -863,7 +862,7 @@ static void lsi_do_msgin(LSIState *s) static uint8_t lsi_get_msgbyte(LSIState *s) { uint8_t data; -cpu_physical_memory_read(s-dnad, data, 1); +pci_dma_read(s-dev, s-dnad, data, 1); s-dnad++; s-dbc--; return data; @@ -1015,8 +1014,8 @@ static void lsi_memcpy(LSIState *s, uint32_t dest, uint32_t src, int count) DPRINTF(memcpy dest 0x%08x src 0x%08x count %d\n, dest, src, count); while (count) { n = (count LSI_BUF_SIZE) ? LSI_BUF_SIZE : count; -cpu_physical_memory_read(src, buf, n); -cpu_physical_memory_write(dest, buf, n); +pci_dma_read(s-dev, src, buf, n); +pci_dma_write(s-dev, dest, buf, n); src += n; dest += n; count -= n; @@ -1084,7 +1083,7 @@ again: /* 32-bit Table indirect */ offset = sxt24(addr); -cpu_physical_memory_read(s-dsa + offset, (uint8_t *)buf, 8); +pci_dma_read(s-dev, s-dsa + offset, (uint8_t *)buf, 8); /* byte count is stored in bits 0:23 only */ s-dbc = cpu_to_le32(buf[0]) 0xff; s-rbc = s-dbc; @@ -1443,7 +1442,7 @@ again: n = (insn 7); reg = (insn 16) 0xff; if (insn (1 24)) { -cpu_physical_memory_read(addr, data, n); +pci_dma_read(s-dev, addr, data, n); DPRINTF(Load reg 0x%x size %d addr 0x%08x = %08x\n, reg, n, addr, *(int *)data); for (i = 0; i n; i++) { @@ -1454,7 +1453,7 @@ again: for (i = 0; i n; i++) { data[i] = lsi_reg_readb(s, reg + i); } -cpu_physical_memory_write(addr, data, n); +pci_dma_write(s-dev, addr, data, n); } } } -- 1.7.7
[Qemu-devel] [PATCH 05/14] eepro100: Use PCI DMA stub functions
From: Eduard - Gabriel Munteanu eduard.munte...@linux360.ro This updates the eepro100 device emulation to use the explicit PCI DMA functions, instead of directly calling physical memory access functions. Signed-off-by: Eduard - Gabriel Munteanu eduard.munte...@linux360.ro Signed-off-by: David Gibson d...@au1.ibm.com Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- hw/eepro100.c | 121 +++-- 1 files changed, 49 insertions(+), 72 deletions(-) diff --git a/hw/eepro100.c b/hw/eepro100.c index 4e3c52f..7d59e71 100644 --- a/hw/eepro100.c +++ b/hw/eepro100.c @@ -46,6 +46,7 @@ #include net.h #include eeprom93xx.h #include sysemu.h +#include dma.h /* QEMU sends frames smaller than 60 bytes to ethernet nics. * Such frames are rejected by real nics and their emulations. @@ -315,38 +316,6 @@ static const uint16_t eepro100_mdi_mask[] = { 0x, 0x, 0x, 0x, 0x, 0x, 0x, 0x, }; -/* Read a 16 bit little endian value from physical memory. */ -static uint16_t e100_ldw_le_phys(target_phys_addr_t addr) -{ -/* Load 16 bit (little endian) word from emulated hardware. */ -uint16_t val; -cpu_physical_memory_read(addr, val, sizeof(val)); -return le16_to_cpu(val); -} - -/* Read a 32 bit little endian value from physical memory. */ -static uint32_t e100_ldl_le_phys(target_phys_addr_t addr) -{ -/* Load 32 bit (little endian) word from emulated hardware. */ -uint32_t val; -cpu_physical_memory_read(addr, val, sizeof(val)); -return le32_to_cpu(val); -} - -/* Write a 16 bit little endian value to physical memory. */ -static void e100_stw_le_phys(target_phys_addr_t addr, uint16_t val) -{ -val = cpu_to_le16(val); -cpu_physical_memory_write(addr, val, sizeof(val)); -} - -/* Write a 32 bit little endian value to physical memory. */ -static void e100_stl_le_phys(target_phys_addr_t addr, uint32_t val) -{ -val = cpu_to_le32(val); -cpu_physical_memory_write(addr, val, sizeof(val)); -} - #define POLYNOMIAL 0x04c11db6 /* From FreeBSD */ @@ -744,21 +713,26 @@ static void dump_statistics(EEPRO100State * s) * values which really matter. * Number of data should check configuration!!! */ -cpu_physical_memory_write(s-statsaddr, s-statistics, s-stats_size); -e100_stl_le_phys(s-statsaddr + 0, s-statistics.tx_good_frames); -e100_stl_le_phys(s-statsaddr + 36, s-statistics.rx_good_frames); -e100_stl_le_phys(s-statsaddr + 48, s-statistics.rx_resource_errors); -e100_stl_le_phys(s-statsaddr + 60, s-statistics.rx_short_frame_errors); +pci_dma_write(s-dev, s-statsaddr, + (uint8_t *) s-statistics, s-stats_size); +stl_le_pci_dma(s-dev, s-statsaddr + 0, + s-statistics.tx_good_frames); +stl_le_pci_dma(s-dev, s-statsaddr + 36, + s-statistics.rx_good_frames); +stl_le_pci_dma(s-dev, s-statsaddr + 48, + s-statistics.rx_resource_errors); +stl_le_pci_dma(s-dev, s-statsaddr + 60, + s-statistics.rx_short_frame_errors); #if 0 -e100_stw_le_phys(s-statsaddr + 76, s-statistics.xmt_tco_frames); -e100_stw_le_phys(s-statsaddr + 78, s-statistics.rcv_tco_frames); +stw_le_pci_dma(s-dev, s-statsaddr + 76, s-statistics.xmt_tco_frames); +stw_le_pci_dma(s-dev, s-statsaddr + 78, s-statistics.rcv_tco_frames); missing(CU dump statistical counters); #endif } static void read_cb(EEPRO100State *s) { -cpu_physical_memory_read(s-cb_address, s-tx, sizeof(s-tx)); +pci_dma_read(s-dev, s-cb_address, (uint8_t *) s-tx, sizeof(s-tx)); s-tx.status = le16_to_cpu(s-tx.status); s-tx.command = le16_to_cpu(s-tx.command); s-tx.link = le32_to_cpu(s-tx.link); @@ -788,18 +762,17 @@ static void tx_command(EEPRO100State *s) } assert(tcb_bytes = sizeof(buf)); while (size tcb_bytes) { -uint32_t tx_buffer_address = e100_ldl_le_phys(tbd_address); -uint16_t tx_buffer_size = e100_ldw_le_phys(tbd_address + 4); +uint32_t tx_buffer_address = ldl_le_pci_dma(s-dev, tbd_address); +uint16_t tx_buffer_size = lduw_le_pci_dma(s-dev, tbd_address + 4); #if 0 -uint16_t tx_buffer_el = e100_ldw_le_phys(tbd_address + 6); +uint16_t tx_buffer_el = lduw_le_pci_dma(s-dev, tbd_address + 6); #endif tbd_address += 8; TRACE(RXTX, logout (TBD (simplified mode): buffer address 0x%08x, size 0x%04x\n, tx_buffer_address, tx_buffer_size)); tx_buffer_size = MIN(tx_buffer_size, sizeof(buf) - size); -cpu_physical_memory_read(tx_buffer_address, buf[size], - tx_buffer_size); +pci_dma_read(s-dev, tx_buffer_address, buf[size], tx_buffer_size); size += tx_buffer_size; } if (tbd_array == 0x) { @@ -810,16 +783,19 @@ static void tx_command(EEPRO100State *s) if (s-has_extended_tcb_support !(s-configuration[6]
[Qemu-devel] [PATCH 10/14] pcnet-pci: Use PCI DMA stub functions
From: Eduard - Gabriel Munteanu eduard.munte...@linux360.ro This updates the pcnet-pci device emulation to use the explicit PCI DMA functions, instead of directly calling physical memory access functions. Signed-off-by: Eduard - Gabriel Munteanu eduard.munte...@linux360.ro Signed-off-by: David Gibson da...@gibson.dropbear.id.au --- hw/pcnet-pci.c |6 -- 1 files changed, 4 insertions(+), 2 deletions(-) diff --git a/hw/pcnet-pci.c b/hw/pcnet-pci.c index fb2a00c..41a6e07 100644 --- a/hw/pcnet-pci.c +++ b/hw/pcnet-pci.c @@ -31,6 +31,7 @@ #include net.h #include loader.h #include qemu-timer.h +#include dma.h #include pcnet.h @@ -230,13 +231,13 @@ static const MemoryRegionOps pcnet_mmio_ops = { static void pci_physical_memory_write(void *dma_opaque, target_phys_addr_t addr, uint8_t *buf, int len, int do_bswap) { -cpu_physical_memory_write(addr, buf, len); +pci_dma_write(dma_opaque, addr, buf, len); } static void pci_physical_memory_read(void *dma_opaque, target_phys_addr_t addr, uint8_t *buf, int len, int do_bswap) { -cpu_physical_memory_read(addr, buf, len); +pci_dma_read(dma_opaque, addr, buf, len); } static void pci_pcnet_cleanup(VLANClientState *nc) @@ -302,6 +303,7 @@ static int pci_pcnet_init(PCIDevice *pci_dev) s-irq = pci_dev-irq[0]; s-phys_mem_read = pci_physical_memory_read; s-phys_mem_write = pci_physical_memory_write; +s-dma_opaque = pci_dev; if (!pci_dev-qdev.hotplugged) { static int loaded = 0; -- 1.7.7
Re: [Qemu-devel] [PATCH] cmd: Fix potential NULL pointer dereference
On Mon, Oct 31, 2011 at 10:27 AM, Markus Armbruster arm...@redhat.com wrote: Pavel Borzenkov pavel.borzen...@gmail.com writes: Signed-off-by: Pavel Borzenkov pavel.borzen...@gmail.com --- Note, that almost all code in the file violates CODING STYLE. The changed lines are written wrt CODING STYLE (like commits 7d7d975c and c32d766a). --- cmd.c | 11 +++ 1 files changed, 3 insertions(+), 8 deletions(-) diff --git a/cmd.c b/cmd.c index f77897e..abcf206 100644 --- a/cmd.c +++ b/cmd.c @@ -49,7 +49,7 @@ void add_command( const cmdinfo_t *ci) { - cmdtab = realloc((void *)cmdtab, ++ncmds * sizeof(*cmdtab)); + cmdtab = g_realloc((void *)cmdtab, ++ncmds * sizeof(*cmdtab)); cmdtab[ncmds - 1] = *ci; qsort(cmdtab, ncmds, sizeof(*cmdtab), compare); } Inconsistent indentation. Either stick to the original indentation, or reindent the whole function. I'll send second version with coding style fixes made in a separate commit. -- Pavel [More of the same...]
[Qemu-devel] [PATCH 13/14] usb-ehci: Use PCI DMA stub functions
This updates the usb-ehci device emulation to use the explicit PCI DMA wrapper to initialize its scatter/gathjer structure. This means this driver should not need further changes when the sglist interface is extended to support IOMMUs. Signed-off-by: David Gibson da...@gibson.dropbear.id.au --- hw/usb-ehci.c | 44 +--- 1 files changed, 25 insertions(+), 19 deletions(-) diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c index bd374c1..cdd5aae 100644 --- a/hw/usb-ehci.c +++ b/hw/usb-ehci.c @@ -1101,12 +1101,13 @@ static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val) // TODO : Put in common header file, duplication from usb-ohci.c /* Get an array of dwords from main memory */ -static inline int get_dwords(uint32_t addr, uint32_t *buf, int num) +static inline int get_dwords(EHCIState *ehci, uint32_t addr, + uint32_t *buf, int num) { int i; for(i = 0; i num; i++, buf++, addr += sizeof(*buf)) { -cpu_physical_memory_rw(addr,(uint8_t *)buf, sizeof(*buf), 0); +pci_dma_read(ehci-dev, addr, (uint8_t *)buf, sizeof(*buf)); *buf = le32_to_cpu(*buf); } @@ -1114,13 +1115,14 @@ static inline int get_dwords(uint32_t addr, uint32_t *buf, int num) } /* Put an array of dwords in to main memory */ -static inline int put_dwords(uint32_t addr, uint32_t *buf, int num) +static inline int put_dwords(EHCIState *ehci, uint32_t addr, + uint32_t *buf, int num) { int i; for(i = 0; i num; i++, buf++, addr += sizeof(*buf)) { uint32_t tmp = cpu_to_le32(*buf); -cpu_physical_memory_rw(addr,(uint8_t *)tmp, sizeof(tmp), 1); +pci_dma_write(ehci-dev, addr, (uint8_t *)tmp, sizeof(tmp)); } return 1; @@ -1169,7 +1171,8 @@ static int ehci_qh_do_overlay(EHCIQueue *q) q-qh.bufptr[1] = ~BUFPTR_CPROGMASK_MASK; q-qh.bufptr[2] = ~BUFPTR_FRAMETAG_MASK; -put_dwords(NLPTR_GET(q-qhaddr), (uint32_t *) q-qh, sizeof(EHCIqh) 2); +put_dwords(q-ehci, NLPTR_GET(q-qhaddr), (uint32_t *) q-qh, + sizeof(EHCIqh) 2); return 0; } @@ -1177,12 +1180,12 @@ static int ehci_qh_do_overlay(EHCIQueue *q) static int ehci_init_transfer(EHCIQueue *q) { uint32_t cpage, offset, bytes, plen; -target_phys_addr_t page; +dma_addr_t page; cpage = get_field(q-qh.token, QTD_TOKEN_CPAGE); bytes = get_field(q-qh.token, QTD_TOKEN_TBYTES); offset = q-qh.bufptr[0] ~QTD_BUFPTR_MASK; -qemu_sglist_init(q-sgl, 5); +pci_dma_sglist_init(q-sgl, q-ehci-dev, 5); while (bytes 0) { if (cpage 4) { @@ -1428,7 +1431,7 @@ static int ehci_process_itd(EHCIState *ehci, return USB_RET_PROCERR; } -qemu_sglist_init(ehci-isgl, 2); +pci_dma_sglist_init(ehci-isgl, ehci-dev, 2); if (off + len 4096) { /* transfer crosses page border */ uint32_t len2 = off + len - 4096; @@ -1532,7 +1535,8 @@ static int ehci_state_waitlisthead(EHCIState *ehci, int async) /* Find the head of the list (4.9.1.1) */ for(i = 0; i MAX_QH; i++) { -get_dwords(NLPTR_GET(entry), (uint32_t *) qh, sizeof(EHCIqh) 2); +get_dwords(ehci, NLPTR_GET(entry), (uint32_t *) qh, + sizeof(EHCIqh) 2); ehci_trace_qh(NULL, NLPTR_GET(entry), qh); if (qh.epchar QH_EPCHAR_H) { @@ -1629,7 +1633,8 @@ static EHCIQueue *ehci_state_fetchqh(EHCIState *ehci, int async) goto out; } -get_dwords(NLPTR_GET(q-qhaddr), (uint32_t *) q-qh, sizeof(EHCIqh) 2); +get_dwords(ehci, NLPTR_GET(q-qhaddr), + (uint32_t *) q-qh, sizeof(EHCIqh) 2); ehci_trace_qh(q, NLPTR_GET(q-qhaddr), q-qh); if (q-async == EHCI_ASYNC_INFLIGHT) { @@ -1698,7 +1703,7 @@ static int ehci_state_fetchitd(EHCIState *ehci, int async) assert(!async); entry = ehci_get_fetch_addr(ehci, async); -get_dwords(NLPTR_GET(entry),(uint32_t *) itd, +get_dwords(ehci, NLPTR_GET(entry), (uint32_t *) itd, sizeof(EHCIitd) 2); ehci_trace_itd(ehci, entry, itd); @@ -1706,8 +1711,8 @@ static int ehci_state_fetchitd(EHCIState *ehci, int async) return -1; } -put_dwords(NLPTR_GET(entry), (uint32_t *) itd, -sizeof(EHCIitd) 2); +put_dwords(ehci, NLPTR_GET(entry), (uint32_t *) itd, + sizeof(EHCIitd) 2); ehci_set_fetch_addr(ehci, async, itd.next); ehci_set_state(ehci, async, EST_FETCHENTRY); @@ -1722,7 +1727,7 @@ static int ehci_state_fetchsitd(EHCIState *ehci, int async) assert(!async); entry = ehci_get_fetch_addr(ehci, async); -get_dwords(NLPTR_GET(entry), (uint32_t *)sitd, +get_dwords(ehci, NLPTR_GET(entry), (uint32_t *)sitd, sizeof(EHCIsitd) 2); ehci_trace_sitd(ehci, entry, sitd); @@ -1784,7 +1789,8 @@ static int ehci_state_fetchqtd(EHCIQueue
[Qemu-devel] [PATCH 14/14] usb-uhci: Use PCI DMA stub functions
This updates the usb-uhci device emulation to use the explicit PCI DMA wrapper to initialize its scatter/gathjer structure. This means this driver should not need further changes when the sglist interface is extended to support IOMMUs. Signed-off-by: David Gibson da...@gibson.dropbear.id.au --- hw/usb-uhci.c | 22 +++--- 1 files changed, 11 insertions(+), 11 deletions(-) diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c index 171d787..f9e3ea5 100644 --- a/hw/usb-uhci.c +++ b/hw/usb-uhci.c @@ -178,7 +178,7 @@ static UHCIAsync *uhci_async_alloc(UHCIState *s) async-done = 0; async-isoc = 0; usb_packet_init(async-packet); -qemu_sglist_init(async-sgl, 1); +pci_dma_sglist_init(async-sgl, s-dev, 1); return async; } @@ -876,7 +876,7 @@ static void uhci_async_complete(USBPort *port, USBPacket *packet) uint32_t link = async-td; uint32_t int_mask = 0, val; -cpu_physical_memory_read(link ~0xf, (uint8_t *) td, sizeof(td)); +pci_dma_read(s-dev, link ~0xf, (uint8_t *) td, sizeof(td)); le32_to_cpus(td.link); le32_to_cpus(td.ctrl); le32_to_cpus(td.token); @@ -888,8 +888,8 @@ static void uhci_async_complete(USBPort *port, USBPacket *packet) /* update the status bits of the TD */ val = cpu_to_le32(td.ctrl); -cpu_physical_memory_write((link ~0xf) + 4, - (const uint8_t *)val, sizeof(val)); +pci_dma_write(s-dev, (link ~0xf) + 4, + (const uint8_t *)val, sizeof(val)); uhci_async_free(s, async); } else { async-done = 1; @@ -952,7 +952,7 @@ static void uhci_process_frame(UHCIState *s) DPRINTF(uhci: processing frame %d addr 0x%x\n , s-frnum, frame_addr); -cpu_physical_memory_read(frame_addr, (uint8_t *)link, 4); +pci_dma_read(s-dev, frame_addr, (uint8_t *)link, 4); le32_to_cpus(link); int_mask = 0; @@ -976,7 +976,7 @@ static void uhci_process_frame(UHCIState *s) break; } -cpu_physical_memory_read(link ~0xf, (uint8_t *) qh, sizeof(qh)); +pci_dma_read(s-dev, link ~0xf, (uint8_t *) qh, sizeof(qh)); le32_to_cpus(qh.link); le32_to_cpus(qh.el_link); @@ -996,7 +996,7 @@ static void uhci_process_frame(UHCIState *s) } /* TD */ -cpu_physical_memory_read(link ~0xf, (uint8_t *) td, sizeof(td)); +pci_dma_read(s-dev, link ~0xf, (uint8_t *) td, sizeof(td)); le32_to_cpus(td.link); le32_to_cpus(td.ctrl); le32_to_cpus(td.token); @@ -1010,8 +1010,8 @@ static void uhci_process_frame(UHCIState *s) if (old_td_ctrl != td.ctrl) { /* update the status bits of the TD */ val = cpu_to_le32(td.ctrl); -cpu_physical_memory_write((link ~0xf) + 4, - (const uint8_t *)val, sizeof(val)); +pci_dma_write(s-dev, (link ~0xf) + 4, + (const uint8_t *)val, sizeof(val)); } if (ret 0) { @@ -1039,8 +1039,8 @@ static void uhci_process_frame(UHCIState *s) /* update QH element link */ qh.el_link = link; val = cpu_to_le32(qh.el_link); -cpu_physical_memory_write((curr_qh ~0xf) + 4, - (const uint8_t *)val, sizeof(val)); +pci_dma_write(s-dev, (curr_qh ~0xf) + 4, + (const uint8_t *)val, sizeof(val)); if (!depth_first(link)) { /* done with this QH */ -- 1.7.7
[Qemu-devel] [PATCH 06/14] ac97: Use PCI DMA stub functions
From: Eduard - Gabriel Munteanu eduard.munte...@linux360.ro This updates the ac97 device emulation to use the explicit PCI DMA functions, instead of directly calling physical memory access functions. Signed-off-by: Eduard - Gabriel Munteanu eduard.munte...@linux360.ro Signed-off-by: David Gibson da...@gibson.dropbear.id.au --- hw/ac97.c |7 --- 1 files changed, 4 insertions(+), 3 deletions(-) diff --git a/hw/ac97.c b/hw/ac97.c index bc69d4e..6800af4 100644 --- a/hw/ac97.c +++ b/hw/ac97.c @@ -18,6 +18,7 @@ #include audiodev.h #include audio/audio.h #include pci.h +#include dma.h enum { AC97_Reset = 0x00, @@ -224,7 +225,7 @@ static void fetch_bd (AC97LinkState *s, AC97BusMasterRegs *r) { uint8_t b[8]; -cpu_physical_memory_read (r-bdbar + r-civ * 8, b, 8); +pci_dma_read (s-dev, r-bdbar + r-civ * 8, b, 8); r-bd_valid = 1; r-bd.addr = le32_to_cpu (*(uint32_t *) b[0]) ~3; r-bd.ctl_len = le32_to_cpu (*(uint32_t *) b[4]); @@ -973,7 +974,7 @@ static int write_audio (AC97LinkState *s, AC97BusMasterRegs *r, while (temp) { int copied; to_copy = audio_MIN (temp, sizeof (tmpbuf)); -cpu_physical_memory_read (addr, tmpbuf, to_copy); +pci_dma_read (s-dev, addr, tmpbuf, to_copy); copied = AUD_write (s-voice_po, tmpbuf, to_copy); dolog (write_audio max=%x to_copy=%x copied=%x\n, max, to_copy, copied); @@ -1054,7 +1055,7 @@ static int read_audio (AC97LinkState *s, AC97BusMasterRegs *r, *stop = 1; break; } -cpu_physical_memory_write (addr, tmpbuf, acquired); +pci_dma_write (s-dev, addr, tmpbuf, acquired); temp -= acquired; addr += acquired; nread += acquired; -- 1.7.7
[Qemu-devel] [PATCH 03/14] Add stub functions for PCI device models to do PCI DMA
This patch adds functions to pci.[ch] to perform PCI DMA operations. At present, these are just stubs which perform directly cpu physical memory accesses. Stubs are included which are analogous to cpu_physical_memory_{read,write}(), the stX_phys() and ldX_phys() functions and cpu_physical_memory_{map,unmap}(). In addition, a wrapper around qemu_sglist_init() is provided, which also takes a PCIDevice *. It's assumed that _init() is the only sglist function which will need wrapping, the idea being that once we have IOMMU support whatever IOMMU context handle the wrapper derives from the PCI device will be stored within the sglist structure for later use. Using these stubs, however, distinguishes PCI device DMA transactions from other accesses to physical memory, which will allow PCI IOMMU support to be added in one place, rather than updating every PCI driver at that time. That is, it allows us to update individual PCI drivers to support an IOMMU without having yet determined the details of how the IOMMU emulation will operate. This will let us remove the most bitrot-sensitive part of an IOMMU patch in advance. Signed-off-by: David Gibson da...@gibson.dropbear.id.au Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- hw/pci.h | 67 ++ 1 files changed, 67 insertions(+), 0 deletions(-) diff --git a/hw/pci.h b/hw/pci.h index 86a81c8..c449a90 100644 --- a/hw/pci.h +++ b/hw/pci.h @@ -6,6 +6,7 @@ #include qdev.h #include memory.h +#include dma.h /* PCI includes legacy ISA access. */ #include isa.h @@ -487,4 +488,70 @@ static inline uint32_t pci_config_size(const PCIDevice *d) return pci_is_express(d) ? PCIE_CONFIG_SPACE_SIZE : PCI_CONFIG_SPACE_SIZE; } +/* DMA access functions */ +static inline int pci_dma_rw(PCIDevice *dev, dma_addr_t addr, + void *buf, dma_addr_t len, DMADirection dir) +{ +cpu_physical_memory_rw(addr, buf, len, dir == DMA_DIRECTION_FROM_DEVICE); +return 0; +} + +static inline int pci_dma_read(PCIDevice *dev, dma_addr_t addr, + void *buf, dma_addr_t len) +{ +return pci_dma_rw(dev, addr, buf, len, DMA_DIRECTION_TO_DEVICE); +} + +static inline int pci_dma_write(PCIDevice *dev, dma_addr_t addr, +const void *buf, dma_addr_t len) +{ +return pci_dma_rw(dev, addr, (void *) buf, len, DMA_DIRECTION_FROM_DEVICE); +} + +#define PCI_DMA_DEFINE_LDST(_l, _s, _bits) \ +static inline uint##_bits##_t ld##_l##_pci_dma(PCIDevice *dev, \ + dma_addr_t addr) \ +{ \ +return ld##_l##_phys(addr); \ +} \ +static inline void st##_s##_pci_dma(PCIDevice *dev, \ + dma_addr_t addr, uint##_bits##_t val) \ +{ \ +st##_s##_phys(addr, val); \ +} + +PCI_DMA_DEFINE_LDST(ub, b, 8); +PCI_DMA_DEFINE_LDST(uw_le, w_le, 16) +PCI_DMA_DEFINE_LDST(l_le, l_le, 32); +PCI_DMA_DEFINE_LDST(q_le, q_le, 64); +PCI_DMA_DEFINE_LDST(uw_be, w_be, 16) +PCI_DMA_DEFINE_LDST(l_be, l_be, 32); +PCI_DMA_DEFINE_LDST(q_be, q_be, 64); + +#undef PCI_DMA_DEFINE_LDST + +static inline void *pci_dma_map(PCIDevice *dev, dma_addr_t addr, +dma_addr_t *plen, DMADirection dir) +{ +target_phys_addr_t len = *plen; +void *buf; + +buf = cpu_physical_memory_map(addr, len, dir == DMA_DIRECTION_FROM_DEVICE); +*plen = len; +return buf; +} + +static inline void pci_dma_unmap(PCIDevice *dev, void *buffer, dma_addr_t len, + DMADirection dir, dma_addr_t access_len) +{ +cpu_physical_memory_unmap(buffer, len, dir == DMA_DIRECTION_FROM_DEVICE, + access_len); +} + +static inline void pci_dma_sglist_init(QEMUSGList *qsg, PCIDevice *dev, + int alloc_hint) +{ +qemu_sglist_init(qsg, alloc_hint); +} + #endif -- 1.7.7
[Qemu-devel] [PATCH 01/14] Define DMA address and direction types
As a preliminary to adding more extensive DMA and IOMMU infrastructure support into qemu, this patch defines a dma_addr_t for storing DMA bus addresses and a DMADirection enum which describes whether a DMA is from an external device to main memory or from main memory to an external device. For now dma_addr_t is just defined to be target_phys_addr_t, but in future, we can change this to support machines where we have bus addresses which don't necessarily have the same format as CPU physical addresses. Signed-off-by: David Gibson da...@gibson.dropbear.id.au --- dma.h |9 + 1 files changed, 9 insertions(+), 0 deletions(-) diff --git a/dma.h b/dma.h index 2bdc236..56e163a 100644 --- a/dma.h +++ b/dma.h @@ -18,6 +18,15 @@ typedef struct ScatterGatherEntry ScatterGatherEntry; #if defined(TARGET_PHYS_ADDR_BITS) +typedef target_phys_addr_t dma_addr_t; + +#define DMA_ADDR_FMT TARGET_FMT_plx + +typedef enum { +DMA_DIRECTION_TO_DEVICE = 0, +DMA_DIRECTION_FROM_DEVICE = 1, +} DMADirection; + struct ScatterGatherEntry { target_phys_addr_t base; target_phys_addr_t len; -- 1.7.7
Re: [Qemu-devel] [PATCH v3 03/13] qemu-timer: move common code to qemu_rearm_alarm_timer
On Sat, Oct 22, 2011 at 00:26, Paolo Bonzini pbonz...@redhat.com wrote: Reviewed-by: Anthony Liguori aligu...@us.ibm.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- qemu-timer.c | 129 -- 1 files changed, 53 insertions(+), 76 deletions(-) diff --git a/qemu-timer.c b/qemu-timer.c index acf7a15..e2551f3 100644 --- a/qemu-timer.c +++ b/qemu-timer.c @@ -153,7 +153,7 @@ struct qemu_alarm_timer { char const *name; int (*start)(struct qemu_alarm_timer *t); void (*stop)(struct qemu_alarm_timer *t); - void (*rearm)(struct qemu_alarm_timer *t); + void (*rearm)(struct qemu_alarm_timer *t, int64_t nearest_delta_ns); #if defined(__linux__) int fd; timer_t timer; @@ -181,12 +181,46 @@ static inline int alarm_has_dynticks(struct qemu_alarm_timer *t) return !!t-rearm; } +static int64_t qemu_next_alarm_deadline(void) +{ + int64_t delta; + int64_t rtdelta; + + if (!use_icount vm_clock-active_timers) { + delta = vm_clock-active_timers-expire_time - + qemu_get_clock_ns(vm_clock); + } else { + delta = INT32_MAX; + } + if (host_clock-active_timers) { + int64_t hdelta = host_clock-active_timers-expire_time - + qemu_get_clock_ns(host_clock); + if (hdelta delta) { + delta = hdelta; + } + } + if (rt_clock-active_timers) { + rtdelta = (rt_clock-active_timers-expire_time - + qemu_get_clock_ns(rt_clock)); + if (rtdelta delta) { + delta = rtdelta; + } + } + + return delta; +} + static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t) { - if (!alarm_has_dynticks(t)) + int64_t nearest_delta_ns; + assert(alarm_has_dynticks(t)); mmtimer and win32 alarms have no rearm. Should we remove these two alarms? + if (!rt_clock-active_timers + !vm_clock-active_timers + !host_clock-active_timers) { return; - - t-rearm(t); + } + nearest_delta_ns = qemu_next_alarm_deadline(); + t-rearm(t, nearest_delta_ns); } /* TODO: MIN_TIMER_REARM_NS should be optimized */ @@ -196,23 +230,23 @@ static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t) static int mm_start_timer(struct qemu_alarm_timer *t); static void mm_stop_timer(struct qemu_alarm_timer *t); -static void mm_rearm_timer(struct qemu_alarm_timer *t); +static void mm_rearm_timer(struct qemu_alarm_timer *t, int64_t delta); static int win32_start_timer(struct qemu_alarm_timer *t); static void win32_stop_timer(struct qemu_alarm_timer *t); -static void win32_rearm_timer(struct qemu_alarm_timer *t); +static void win32_rearm_timer(struct qemu_alarm_timer *t, int64_t delta); #else static int unix_start_timer(struct qemu_alarm_timer *t); static void unix_stop_timer(struct qemu_alarm_timer *t); -static void unix_rearm_timer(struct qemu_alarm_timer *t); +static void unix_rearm_timer(struct qemu_alarm_timer *t, int64_t delta); #ifdef __linux__ static int dynticks_start_timer(struct qemu_alarm_timer *t); static void dynticks_stop_timer(struct qemu_alarm_timer *t); -static void dynticks_rearm_timer(struct qemu_alarm_timer *t); +static void dynticks_rearm_timer(struct qemu_alarm_timer *t, int64_t delta); #endif /* __linux__ */ @@ -715,8 +749,6 @@ void qemu_run_all_timers(void) qemu_run_timers(host_clock); } -static int64_t qemu_next_alarm_deadline(void); - #ifdef _WIN32 static void CALLBACK host_alarm_handler(PVOID lpParam, BOOLEAN unused) #else @@ -781,33 +813,6 @@ int64_t qemu_next_icount_deadline(void) return delta; } -static int64_t qemu_next_alarm_deadline(void) -{ - int64_t delta; - int64_t rtdelta; - - if (!use_icount vm_clock-active_timers) { - delta = vm_clock-active_timers-expire_time - - qemu_get_clock_ns(vm_clock); - } else { - delta = INT32_MAX; - } - if (host_clock-active_timers) { - int64_t hdelta = host_clock-active_timers-expire_time - - qemu_get_clock_ns(host_clock); - if (hdelta delta) - delta = hdelta; - } - if (rt_clock-active_timers) { - rtdelta = (rt_clock-active_timers-expire_time - - qemu_get_clock_ns(rt_clock)); - if (rtdelta delta) - delta = rtdelta; - } - - return delta; -} - #if defined(__linux__) #include compatfd.h @@ -860,20 +865,13 @@ static void dynticks_stop_timer(struct qemu_alarm_timer *t) timer_delete(host_timer); } -static void dynticks_rearm_timer(struct qemu_alarm_timer *t) +static void dynticks_rearm_timer(struct qemu_alarm_timer *t, + int64_t nearest_delta_ns) { timer_t host_timer = t-timer; struct itimerspec timeout; - int64_t nearest_delta_ns = INT64_MAX; int64_t
Re: [Qemu-devel] Why some ARM NEON helper functions need mask?
Thanks, Max and Chih-Min. It's much clear to me now. Regards, chenwj -- Wei-Ren Chen (陳韋任) Computer Systems Lab, Institute of Information Science, Academia Sinica, Taiwan (R.O.C.) Tel:886-2-2788-3799 #1667
Re: [Qemu-devel] [PULL] VirtFS update 7
On Tue, 25 Oct 2011 15:02:44 +0530, Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.com wrote: Hi, This include all the pending patches for 1.0 The following changes since commit 952e849c150b4f1b89f8728cba00f925c1d6e75b: Merge remote-tracking branch 'bonzini/split-main-loop-for-anthony' into staging (2011-10-24 10:51:12 -0500) are available in the git repository at: git://repo.or.cz/qemu/v9fs.git for-upstream-7 Aneesh Kumar K.V (5): hw/9pfs: Make VirtFS tracing work correctly hw/9pfs: Fix error handling in local_mknod configure: Update configure so that open_by_handle_at check returns correct value hw/9pfs: Abstract open state of fid to V9fsFidOpenState hw/9pfs: Add synthetic file system support using 9p Harsh Prateek Bora (2): qemu-queue: Introduce QLIST_INSERT_HEAD_RCU and dummy RCU wrappers. hw/9pfs: Replace rwlocks with RCU variants of interfaces. M. Mohan Kumar (2): qemu: Add opt_set_bool functionality hw/9pfs: Read-only support for 9p export Makefile.objs |1 + configure |2 +- fsdev/file-op-9p.h| 36 ++- fsdev/qemu-fsdev.c|8 +- fsdev/qemu-fsdev.h|1 + hw/9pfs/codir.c | 16 +- hw/9pfs/cofile.c | 37 ++-- hw/9pfs/virtio-9p-coth.h |6 +- hw/9pfs/virtio-9p-handle.c| 96 --- hw/9pfs/virtio-9p-local.c | 113 hw/9pfs/virtio-9p-synth.c | 571 + hw/9pfs/virtio-9p-synth.h | 50 hw/9pfs/virtio-9p.c | 122 ++--- hw/9pfs/virtio-9p.h | 27 ++- qemu-config.c |7 + qemu-option.c | 39 +++- qemu-option.h |3 +- qemu-options.hx | 23 ++- qemu-queue.h | 13 + qemu-thread.h |3 + scripts/analyse-9p-simpletrace.py | 164 ++-- trace-events |2 +- vl.c | 20 ++ 23 files changed, 1085 insertions(+), 275 deletions(-) create mode 100644 hw/9pfs/virtio-9p-synth.c create mode 100644 hw/9pfs/virtio-9p-synth.h The first patch of this pull request got applied to qemu master directly from the list. I have rebased the branch to avoid merge conflict. Here is the updated diffstat. The following changes since commit 375847a6c0330e3de0fd1589eeb5a364692b791e: MAINTAINERS: update wiki URL and machine names for target-xtensa (2011-10-30 10:58:08 +) are available in the git repository at: git://repo.or.cz/qemu/v9fs.git for-upstream-7 Aneesh Kumar K.V (4): hw/9pfs: Fix error handling in local_mknod configure: Update configure so that open_by_handle_at check returns correct value hw/9pfs: Abstract open state of fid to V9fsFidOpenState hw/9pfs: Add synthetic file system support using 9p Harsh Prateek Bora (2): qemu-queue: Introduce QLIST_INSERT_HEAD_RCU and dummy RCU wrappers. hw/9pfs: Replace rwlocks with RCU variants of interfaces. M. Mohan Kumar (2): qemu: Add opt_set_bool functionality hw/9pfs: Read-only support for 9p export Makefile.objs |1 + configure |2 +- fsdev/file-op-9p.h | 36 ++- fsdev/qemu-fsdev.c |8 +- fsdev/qemu-fsdev.h |1 + hw/9pfs/codir.c| 16 +- hw/9pfs/cofile.c | 37 ++-- hw/9pfs/virtio-9p-coth.h |6 +- hw/9pfs/virtio-9p-handle.c | 96 + hw/9pfs/virtio-9p-local.c | 113 + hw/9pfs/virtio-9p-synth.c | 571 hw/9pfs/virtio-9p-synth.h | 50 hw/9pfs/virtio-9p.c| 62 +- hw/9pfs/virtio-9p.h| 27 ++- qemu-config.c |7 + qemu-option.c | 39 +++- qemu-option.h |3 +- qemu-options.hx| 23 ++- qemu-queue.h | 13 + qemu-thread.h |3 + vl.c | 20 ++ 21 files changed, 973 insertions(+), 161 deletions(-) create mode 100644 hw/9pfs/virtio-9p-synth.c create mode 100644 hw/9pfs/virtio-9p-synth.h
Re: [Qemu-devel] [PATCH 1/2] seabios: Add Local APIC NMI Structure to ACPI MADT
(2011/10/28 21:48), Jun Koi wrote: 2011/10/28 Kenji Kaneshigekaneshige.ke...@jp.fujitsu.com: Avi, Jan, Could you comment on these patches? Inject-NMI doesn't work on Windows guest without these patches. sorry but i am really curious here: why Windows still works well even if it desnt see the inject-NMI? or there are still invisible side-effects that we are not awere of??? Without this patch, LVT LINT1 is not configured by Windows guest because seabios MADT has no ACPI NMI structure which is used by Windows to setup LVT. So NMI interrupt would not be sent to CPUs when NMI signal happens on LINT1. But qemu/kvm inject-nmi feature had a bug that it sent NMI to CPUs without emulating LAPIC LVT. As a result, NMI interrupt is sent to all the CPUs even though LVT LINT1 is not configured. This is why inject-nmi behaves as if it works well on Windows guest. Regards, Kenji Kaneshige
Re: [Qemu-devel] [PATCH 2/2] Documentation: Add syntax for using sheepdog devices
Am 29.10.2011 05:40, schrieb ronnie sahlberg: Hi Kevin, I agree that maybe we should have a link from the TOC down to the Device URL Syntax. I can create a patch to do so. For moving the existing Device URL Syntax information into 3.6 Disk Images, I am not sure. I think both have their place and they serve different purposes even if there is some overlap. Device URL Syntax: This contains a terse description of the syntax on how to specify these devices on the command line. This is really needed in the manpage. Very basic syntax description and an example command line or two. Qemu-doc: I see as much more detailed documentation than a simple manpage. It also includes howto type descriptions that show how to set it up end-to-end from creating a device image, how to configure a basic NDB server, and then how to make it available to QEMU. This I think is more a full end-to-end description with howto examples. I think it would make sense to have both. What do you think? If you agree this makes sense I will continue adding terse sections to Device URL Syntax but also start going through section 3.6 and make sure we also have howto-like examples on how to set it up on the server side as well. A section in 3.6 for iscsi could for example show how to create an image and export via STGT so that QEMU can access it as an iscsi lun. Sure, that sounds good. I just had the impression that currently the terse URL syntax description is in fact more extensive than section 3.6 which should be the full documentation. Kevin
Re: [Qemu-devel] [PATCH] qed: adjust the way to get nb_sectors
Am 31.10.2011 04:01, schrieb Zhi Yong Wu: It is better to use qiov.size in qed-table.c to get nb_sectors than iov.iov_len. Signed-off-by: Zhi Yong Wu wu...@linux.vnet.ibm.com The commit message should probably say why it's better. Not saying otherwise, but I can't see the different at the first sight. Kevin
Re: [Qemu-devel] [PATCH] qed: adjust the way to get nb_sectors
On Mon, Oct 31, 2011 at 4:10 PM, Kevin Wolf kw...@redhat.com wrote: Am 31.10.2011 04:01, schrieb Zhi Yong Wu: It is better to use qiov.size in qed-table.c to get nb_sectors than iov.iov_len. Signed-off-by: Zhi Yong Wu wu...@linux.vnet.ibm.com The commit message should probably say why it's better. Not saying otherwise, but I can't see the different at the first sight. They are equal, but if the number of iov isn't ONE, they will be not equal. qiov.size contains the sum of all iov's size while iov.iov_len is only the size of one iov. Although in current scenario, they are equal, but i think that it is better if qiov.size is used. 's Kevin -- Regards, Zhi Yong Wu
[Qemu-devel] Performance of USB2.0
Hello all, i want to use a virtual router which is connected to a cable box via an usb ethernet controller. The device itself runs properly at normal usage. But inside the virtual machine i get only about 7MBit. I configured the the usb device with the following xml syntax of libvirt: controller type='usb' index='0' model='ehci' address type='pci' domain='0x' bus='0x00' slot='0x07' function='0x0'/ /controller hostdev mode='subsystem' type='usb' managed='no' source vendor id='0x9710'/ product id='0x7830'/ /source /hostdev Inside the guest i get this output of lsusb: Bus 001 Device 002: ID 9710:7830 MosChip Semiconductor MCS7830 10/100 Mbps Ethernet adapter Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub lsusb -v shows this output for the root hub: Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Device Descriptor: bLength18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass9 Hub bDeviceSubClass 0 Unused bDeviceProtocol 0 Full speed (or root) hub bMaxPacketSize064 idVendor 0x1d6b Linux Foundation idProduct 0x0002 2.0 root hub bcdDevice2.06 iManufacturer 3 Linux 2.6.32-5-amd64 ehci_hcd iProduct2 EHCI Host Controller iSerial 1 :00:07.0 Does this Full speed mean, that it is still running with 12MBit? What is the status of High Speed USB (480Mbit) inside the guest? What versions do i need? I currently use Debian Sid: qemu-kvm (0.15.1) libvirt0-dbg (0.9.6-2) Kernel: Linux server 3.0.0-2-amd64 #1 SMP x86_64 GNU/Linux Regards Til
Re: [Qemu-devel] [PATCH 2/2] [WIP]Added target to build libvdisk
On 10/30/2011 07:04 PM, Saggi Mizrahi wrote: I wonder also what thread API should be used, qemu_thread versions used internally or standard ones. It would be logical to use qemu_thread versions but then the external user should use those too. I would prefer not to use qemu's threading as it'll expose internal APIs. I suggest glib's threading, Is it visible in any way to the client? Also, perhaps thread-safety should be left to the client so that they can use whatever API they like? Paolo
Re: [Qemu-devel] [PATCH 1/2] Better support for distros using /lib64 directories
On 10/30/2011 05:51 PM, Saggi Mizrahi wrote: Some distributions use lib64 directories for 64 bit libraries. Currently configure would always generate libdir as $PREFIX/lib. By checking if the current distro has a /lib64 directory we can assume it is using this convention. This doesn't work if people compile a 32-bit version of QEMU. The right directory could be obtained with gcc --print-multi-os-directory $CFLAGS, but I'm not sure whether it is a good thing to do. We should try to avoid gratuitous differences from Autoconf. The right thing to do would be to tweak the command-line supported by configure to the point that packagers can just use the same command-line that Autoconf uses (in RPM parlance that would be %configure). Paolo
Re: [Qemu-devel] [PATCH v3 03/13] qemu-timer: move common code to qemu_rearm_alarm_timer
On 10/31/2011 08:23 AM, TeLeMan wrote: static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t) { -if (!alarm_has_dynticks(t)) +int64_t nearest_delta_ns; +assert(alarm_has_dynticks(t)); mmtimer and win32 alarms have no rearm. Should we remove these two alarms? Yes. I think with iothread they are broken, or almost broken. Paolo
[Qemu-devel] [PATCH 0/2] Cocoa patches for 1.0
[Seems they didn't make it to the list yesterday] Hello, Here's two Cocoa patches I'd like to see pulled into 1.0. First, documenting the de facto maintainer. Second, fixing the build. Since qemu-system-* crashes after selecting an image file, I can only say that Juan's sheet patch compiles and would like to postpone it until it actually makes a difference. Unless Juan or someone has a use case that works on master. Regards, Andreas Cc: Juan Pineda j...@logician.com Andreas Färber (2): MAINTAINERS: Add Cocoa maintainer softfloat: Avoid uint16 type conflict on Darwin MAINTAINERS |5 + fpu/softfloat.h |3 +++ 2 files changed, 8 insertions(+), 0 deletions(-)
[Qemu-devel] [PATCH 1/2] MAINTAINERS: Add Cocoa maintainer
Degrade cocoa.m from Maintained to Odd Fixes. Signed-off-by: Andreas Färber andreas.faer...@web.de Cc: Anthony Liguori aligu...@us.ibm.com --- MAINTAINERS |5 + 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 2b4c5d7..c08951c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -446,6 +446,11 @@ M: Anthony Liguori aligu...@us.ibm.com S: Maintained F: ui/ +Cocoa graphics +M: Andreas Färber andreas.faer...@web.de +S: Odd Fixes +F: ui/cocoa.m + Main loop M: Anthony Liguori aligu...@us.ibm.com S: Supported -- 1.7.0.3
[Qemu-devel] [PATCH 2/2] softfloat: Avoid uint16 type conflict on Darwin
In file included from ./bswap.h:7, from ./qemu-common.h:106, from ./qemu-aio.h:17, from ./Block.h:4, from /System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Headers/FSEvents.h:28, from /System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Headers/CarbonCore.h:218, from /System/Library/Frameworks/CoreServices.framework/Frameworks/AE.framework/Headers/AE.h:20, from /System/Library/Frameworks/CoreServices.framework/Headers/CoreServices.h:21, from /System/Library/Frameworks/Foundation.framework/Headers/NSURLError.h:17, from /System/Library/Frameworks/Foundation.framework/Headers/Foundation.h:81, from /System/Library/Frameworks/Cocoa.framework/Headers/Cocoa.h:12, from ui/cocoa.m:25: /Users/andreas/QEMU/qemu/fpu/softfloat.h:60: error: conflicting types for ‘uint16’ /System/Library/Frameworks/Security.framework/Headers/cssmconfig.h:73: error: previous declaration of ‘uint16’ was here make: *** [ui/cocoa.o] Error 1 Apple's FSEvents.h has #include Block.h, which wants /usr/include/Block.h but due to case-insensitive file system and include path jungle gets QEMU's ./block.h, which in turn includes softfloat.h indirectly. Therefore work around the conflict in softfloat.h itself by renaming specifically uint16 on Darwin to qemu_uint16. This fixes the build until we have a more general solution. Signed-off-by: Andreas Färber andreas.faer...@web.de Cc: Juan Pineda j...@logician.com Cc: Peter Maydell peter.mayd...@linaro.org --- fpu/softfloat.h |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/fpu/softfloat.h b/fpu/softfloat.h index 07c2929..5320945 100644 --- a/fpu/softfloat.h +++ b/fpu/softfloat.h @@ -54,6 +54,9 @@ these four paragraphs for those parts of this code that are retained. | to the same as `int'. **/ typedef uint8_t flag; +#ifdef __APPLE__ +#define uint16 qemu_uint16 +#endif typedef uint8_t uint8; typedef int8_t int8; #ifndef _AIX -- 1.7.0.3
Re: [Qemu-devel] [PULL 0/3] 128-bit support for the memory API
On 10/31/2011 02:36 AM, David Gibson wrote: There is no direct use of signed arithmetic in the API (just in the implementation). Aliases can cause a region to move in either the positive or negative direction, and this requires either signed arithmetic or special casing the two directions. You keep saying we need signed arithmetic for this, but it's not really true. *If* you see aliases as shifting the entire aliases address space w.r.t., then just allowing a window to show through, you get negative offsets, yes, but that's by no means the only way t think about it. Obviously it's not the only way. We could insert checks for the direction, and for overflow/underflow. But I am looking for the most reliable way to prevent similar issues from popping up. There have been at least three bugs in this area. If we can use a heavy hammer here, it is worthwhile IMO. Sorry for being a little trollish, but I much prefer replacing function calls with infix operators, than getting a CVE for some overflow. It's basically one spot - the alias handling in render_memory_region() - that generates a negative start intermediate. I'm convinced it's pretty straightforward to remove this - making a patch for it just hasn't bubbled to the top of my priority queue, though. We keep adding, subtracting, and comparing stuff everywhere. I am fairly certain that you are right and there are no other trouble spot, but I am not absolutely sure, and I would like to be. Signed arithmetic is not the only motivation - overflow is another. Nothing prevents a user from placing a 64-bit 4k BAR at address ___f000; we could move to base/limit representation, but that will likely cause its own bugs. Finally, we should be able to represent both a 0-sized region and a 2^64 sized region. Note that an (inclusive) start/end representation also cannot represent a 0 sized region. Right. In theory we shouldn't generate zero sized regions, but can we trust call device code not to do that? Also, start/end or off-by-one size are easy to get wrong since C programmers assume half-inclusive regions. -- error compiling committee.c: too many arguments to function
[Qemu-devel] [PATCH] qemu-io: Handle create_iovec errors
Callers of create_iovec() didn't check for failure and continued with uninitialised data in error cases. This patch adds checks to each call. Signed-off-by: Kevin Wolf kw...@redhat.com --- qemu-io.c | 28 1 files changed, 24 insertions(+), 4 deletions(-) diff --git a/qemu-io.c b/qemu-io.c index 5af887e..1c49d44 100644 --- a/qemu-io.c +++ b/qemu-io.c @@ -596,6 +596,9 @@ static int readv_f(int argc, char **argv) nr_iov = argc - optind; buf = create_iovec(qiov, argv[optind], nr_iov, 0xab); +if (buf == NULL) { +return 0; +} gettimeofday(t1, NULL); cnt = do_aio_readv(qiov, offset, total); @@ -850,6 +853,9 @@ static int writev_f(int argc, char **argv) nr_iov = argc - optind; buf = create_iovec(qiov, argv[optind], nr_iov, pattern); +if (buf == NULL) { +return 0; +} gettimeofday(t1, NULL); cnt = do_aio_writev(qiov, offset, total); @@ -950,8 +956,8 @@ static int multiwrite_f(int argc, char **argv) } } -reqs = g_malloc(nr_reqs * sizeof(*reqs)); -buf = g_malloc(nr_reqs * sizeof(*buf)); +reqs = g_malloc0(nr_reqs * sizeof(*reqs)); +buf = g_malloc0(nr_reqs * sizeof(*buf)); qiovs = g_malloc(nr_reqs * sizeof(*qiovs)); for (i = 0; i nr_reqs; i++) { @@ -985,8 +991,12 @@ static int multiwrite_f(int argc, char **argv) nr_iov = j - optind; /* Build request */ +buf[i] = create_iovec(qiovs[i], argv[optind], nr_iov, pattern); +if (buf[i] == NULL) { +goto out; +} + reqs[i].qiov = qiovs[i]; -buf[i] = create_iovec(reqs[i].qiov, argv[optind], nr_iov, pattern); reqs[i].sector = offset 9; reqs[i].nb_sectors = reqs[i].qiov-size 9; @@ -1014,7 +1024,9 @@ static int multiwrite_f(int argc, char **argv) out: for (i = 0; i nr_reqs; i++) { qemu_io_free(buf[i]); -qemu_iovec_destroy(qiovs[i]); +if (reqs[i].qiov != NULL) { +qemu_iovec_destroy(qiovs[i]); +} } g_free(buf); g_free(reqs); @@ -1185,6 +1197,10 @@ static int aio_read_f(int argc, char **argv) nr_iov = argc - optind; ctx-buf = create_iovec(ctx-qiov, argv[optind], nr_iov, 0xab); +if (ctx-buf == NULL) { +free(ctx); +return 0; +} gettimeofday(ctx-t1, NULL); acb = bdrv_aio_readv(bs, ctx-offset 9, ctx-qiov, @@ -1280,6 +1296,10 @@ static int aio_write_f(int argc, char **argv) nr_iov = argc - optind; ctx-buf = create_iovec(ctx-qiov, argv[optind], nr_iov, pattern); +if (ctx-buf == NULL) { +free(ctx); +return 0; +} gettimeofday(ctx-t1, NULL); acb = bdrv_aio_writev(bs, ctx-offset 9, ctx-qiov, -- 1.7.6.4
[Qemu-devel] [PATCH] qemu-io: Fix multiwrite_f error handling
Without this fix, some qiovs can be leaked if an error occurs. Also a semicolon at the end of the command line would make the code walk beyond the end of argv. Signed-off-by: Kevin Wolf kw...@redhat.com --- qemu-io.c |9 ++--- 1 files changed, 6 insertions(+), 3 deletions(-) diff --git a/qemu-io.c b/qemu-io.c index 1c49d44..de26422 100644 --- a/qemu-io.c +++ b/qemu-io.c @@ -960,21 +960,21 @@ static int multiwrite_f(int argc, char **argv) buf = g_malloc0(nr_reqs * sizeof(*buf)); qiovs = g_malloc(nr_reqs * sizeof(*qiovs)); -for (i = 0; i nr_reqs; i++) { +for (i = 0; i nr_reqs optind argc; i++) { int j; /* Read the offset of the request */ offset = cvtnum(argv[optind]); if (offset 0) { printf(non-numeric offset argument -- %s\n, argv[optind]); -return 0; +goto out; } optind++; if (offset 0x1ff) { printf(offset %lld is not sector aligned\n, (long long)offset); -return 0; +goto out; } if (i == 0) { @@ -1005,6 +1005,9 @@ static int multiwrite_f(int argc, char **argv) pattern++; } +/* If there were empty requests at the end, ignore them */ +nr_reqs = i; + gettimeofday(t1, NULL); cnt = do_aio_multiwrite(reqs, nr_reqs, total); gettimeofday(t2, NULL); -- 1.7.6.4
Re: [Qemu-devel] [libvirt] RFC decoupling VM NIC provisioning from VM NIC connection to backend networks
On Fri, Oct 28, 2011 at 04:15:41PM -0700, Sumit Naiksatam (snaiksat) wrote: Hi, In its current implementation Libvirt makes sure that the network interfaces that it passes/provision to a VM (for example to qemu[-kvm]) are already connected to its backend (interfaces/networks) by the time the VM starts its boot process. In a non virtualized setup it would be like booting a machine with the Ethernet cable already plugged into a router/switch port. While in a non virtualized setup you can boot a machine first (with no physical connection to a router/switch) and later connect its NIC/s to the switch/router, when you boot a VM via Libvirt it is not possible to decouple the two actions (VM boot, cable plug/unplug). An example of case where the capability of decoupling the two actions mentioned above is a requirement in Quantum/NetStack which is the network service leveraged by OpenStack. The modular design of OpenStack allows you to: - provision VMs with NIC/s - create networks - create ports on networks - plug/unplug a VM NIC into/from a given port on a network (at runtime) Note that this runtime plug/unplug requirement has nothing to do with hot plug/unplug of NICs. The idea is more that of decoupling the provisioning of a VM from the connection of the VM to the network/s. This would make it possible to change (at run-time too) the networks the NIC/s of a given VM are connected to. For example, when a VM boots, its interfaces should be in link down state if the network admin has not connected the VM NIC/s to any network yet. Even though libvirt already provides a way to change the link state of an a VM NIC, link state and physical connection are two different things and should be manageable independently. Ideally the configuration syntax should be interface type and hypervisor type agnostic. Let's take QEMU[-kvm] as an example - when Libvirt starts a QEMU VM, it passes to QEMU a number of file descriptors that map to host backend interfaces (for example macvtap interfaces). In order to introduce this runtime plug/unplug capability, we need a mechanism that permits to delay the binding between the host macvtap interfaces and the guest taps (because you cannot know the fd of the macvtap interfaces before you create them). This means you need a mechanism that allows you to change such fd/s at runtime: - you can close/reset an fd (ie, when you disconnect a VM NIC from its network) - you can open/set an fd (ie, when you connect a VM NIC to a network) This could probably be a libvirt command that translates to a QEMU monitor command. Can the runtime plug/unplug capability described above be achieved (cleanly) with another mechanism? Is anybody working on implementing something similar? No, but I've long thought about doing this it is quite straightforward todo really. Ordinarily when we start QEMU we do qemu ... -device e1000,id=nic0,netdev=netdevnic0 \ -netdev user,id=netdevnic0 Todo what you describe we need to be able to: 1. Start QEMU with a NIC, but no netdev 2. Add a netdev to running QEMU. 3. Remove a netdev from a running QEMU 4. Associate a netdev with a NIC in running QEMU We can do 1: $ qemu ... -device e1000,id=nic0 But QEMU prints an annoying warning Warning: nic nic0 has no peer We can do 2 via the monitor: (qemu) netdev_add type=user,id=netdevnic0 We can do 3 via the monitor: (qemu) netdev_del netdevnic0 The problem is 4 - AFAICT we can't connect the existing NIC upto the newly hotplugged netdev, since we can't update the 'netdev' property in the NIC device. Also if we delete the netdev, we can't clear out the 'netdev' property in the NIC, so its dangling to a netdev that no longer exists. The latter is fairly harmless, since we can just re-use the name if adding a new backend later. The first problem is a bit of a pain, unless we plug in a 'user' backend on the CLI, and immediately netdev_del it before starting the CPUs. Ideally we'd have some way to set qdev properties for devices so we can associate the NIC with the new netdev. eg when adding a netdev: (qemu) netdev_add type=user,id=netdevnic0 (qemu) set nic0 netdev=netdevnic0 Or removing one (qemu) netdev_add netdevnic0 (qemu) unset nic0 netdev WRT to libvirt XML config. Normally you specifiy a NIC like interface type='network' mac address='52:54:00:0f:7d:ad'/ source network='default'/ model type='virtio'/ /interface To boot a guest without any netdev backend present, we'd introduce a new network type=none. eg interface type='none' mac address='52:54:00:0f:7d:ad'/ model type='virtio'/ /interface The existing API 'virDomainUpdateDevice', can then be used to change the interface config on the fly, adding or removing the netdev by passing in new XML with a different 'type' attribute source element. Finally, when adding removing the netdev backends to a running
[Qemu-devel] [Bug 882358] Re: device assignment doesn't work: error: requires KVM support
This is because kvm is not enabled by default even if I add KVM support when configuring qemu. Now it got fixed by the following commit. author Marcelo Tosatti mtosa...@redhat.com Thu, 27 Oct 2011 20:34:42 +0800 (10:34 -0200) committer Marcelo Tosatti mtosa...@redhat.com Thu, 27 Oct 2011 20:34:42 +0800 (10:34 -0200) commit 7879db7e9c09b92d9af1c143fbe2cc212ec89e4b Revert qemu-kvm: set default accelerator via target.conf This reverts commit a5c40eb1aa929a03157252db7337bc4ddd2435be. Jan says: Unless you fully install qemu, that conf is not picked up (or an older version is used). I'd still like to see this working with qemu started from a build directory... Signed-off-by: Marcelo Tosatti mtosa...@redhat.com -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/882358 Title: device assignment doesn't work: error: requires KVM support Status in QEMU: Fix Released Bug description: qemu.git commit:8843cf40c0f482949e6ae9d0119e45d6b96fe890 I met the following error when do device assignment with qemu in kvm host. ./x86_64-softmmu/qemu-system-x86_64 -smp 2 -m 1024 -device pci-assign,host=0e:00.0 -hda /root/jay/rhel6u1.img qemu-system-x86_64: -device pci-assign,host=0e:00.0: pci-assign: error: requires KVM support qemu-system-x86_64: -device pci-assign,host=0e:00.0: Device 'pci-assign' could not be initialized ./x86_64-softmmu/qemu-system-x86_64 -device ? 21 | grep -i pci-assign -name pci-assign, bus PCI, desc pass through host pci devices to the guest When configuring the qemu, it prints KVM support yes.My qemu configuration log and compiling log are attached. But commit edbb7c0d doesn't have this issue. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/882358/+subscriptions
[Qemu-devel] [Bug 882358] Re: device assignment doesn't work: error: requires KVM support
It works now. ** Changed in: qemu Status: New = Fix Released -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/882358 Title: device assignment doesn't work: error: requires KVM support Status in QEMU: Fix Released Bug description: qemu.git commit:8843cf40c0f482949e6ae9d0119e45d6b96fe890 I met the following error when do device assignment with qemu in kvm host. ./x86_64-softmmu/qemu-system-x86_64 -smp 2 -m 1024 -device pci-assign,host=0e:00.0 -hda /root/jay/rhel6u1.img qemu-system-x86_64: -device pci-assign,host=0e:00.0: pci-assign: error: requires KVM support qemu-system-x86_64: -device pci-assign,host=0e:00.0: Device 'pci-assign' could not be initialized ./x86_64-softmmu/qemu-system-x86_64 -device ? 21 | grep -i pci-assign -name pci-assign, bus PCI, desc pass through host pci devices to the guest When configuring the qemu, it prints KVM support yes.My qemu configuration log and compiling log are attached. But commit edbb7c0d doesn't have this issue. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/882358/+subscriptions
Re: [Qemu-devel] [Qemu test report] Autotest | Job ID: 1997 Upstream qemu.git sanity 10-30-2011 00:05:01 | Status: 1 Completed | Success Rate: 53.85 %
On Mon, 31 Oct 2011 00:01:07 -0200 Lucas Meneghel Rodrigues l...@redhat.com wrote: Hi folks, sending this to QEMU devel to inform the current problems we are able to reproduce on the current master branch. So, qemu.git is presenting problems as of latest master. None of the problems mentioned is happening on qemu-kvm.git. Original Message Subject: Autotest | Job ID: 1997 Upstream qemu.git sanity 10-30-2011 00:05:01 | Status: 1 Completed | Success Rate: 53.85 % Date: Sun, 30 Oct 2011 09:50:58 -0400 From: kvm-autot...@redhat.com To: l...@redhat.com, cr...@redhat.com Job ID: 1997 Job name: Upstream qemu.git sanity 10-30-2011 00:05:01 Summary: Host: virtlab208.virt.bos.redhat.com Status: Completed Status: 1 Completed Execution time (HH:MM:SS): 05:44:38 User tests executed: 26 User tests passed: 14 User tests failed: 12 User tests success rate: 53.85 % Failures: Test Name Status Reason kvm.qemu-git.virtio_blk.smp2.virtio_net.Win7.64.sp1.unattended_install.cdrom FAILTimeout elapsed while waiting for install to finish[context: waiting for installation to finish] ^ Here, the windows install timeout happened due to the floppy regression introduced by 212ec7baa28cc9d819234fed1541fc1423cfe3d8. We did try Kevin's patches and they did not fix the issue. kvm.qemu-git.virtio_blk.smp2.virtio_net.RHEL.6.1.x86_64.migrate.tcp FAILUnhandled LoginError: Client said 'connection refused' (output: 'ssh: connect to host 192.168.122.129 port 22: Connection refused\n')[context: logging into 'vm1'] kvm.qemu-git.virtio_blk.smp2.virtio_net.RHEL.6.1.x86_64.reboot FAILUnhandled LoginError: Client said 'connection refused' (output: 'ssh: connect to host 192.168.122.25 port 22: Connection refused\n')[context: logging into 'vm1'] kvm.qemu-git.virtio_blk.smp2.virtio_net.RHEL.6.1.x86_64.migrate.unix FAILUnhandled LoginError: Client said 'connection refused' (output: 'ssh: connect to host 192.168.122.3 port 22: Connection refused\n')[context: logging into 'vm1'] kvm.qemu-git.virtio_blk.smp2.virtio_net.RHEL.6.1.x86_64.migrate.exec FAILUnhandled MonitorSocketError: Could not send monitor command 'info migrate'([Errno 32] Broken pipe)[context: migrating 'vm1'] ^ All of those failures happened due to qemu segfaults during the migration process. I believe Luiz had a patch to possibly fix this migration issue, so copying him. Yes, it's already on the list: http://lists.gnu.org/archive/html/qemu-devel/2011-10/msg03597.html The segfaults generated core dumps, which we would be happy to scp to a public box, if someone is interested in them. Cheers, Lucas
Re: [Qemu-devel] GSoC mentor summit session how to bind students long-term
On Sat, Oct 29, 2011 at 04:00:34PM +0200, Alexander Graf wrote: During the GSoC mentor summit there was a pretty interesting session on how to get students to stick with your project even after GSoC has ended. So far we haven't really been exactly successful in that respect :). I'll just post my notes below: - send successful students to conferences - set expectations on what we expect from students after gsoc, lay out the achievement plan for students to times beyond gsoc - give students responsibility, make them maintain parts (makes it harder for them to just leave, because they feel obliged) - shove students to community, no sidechannel communication, make them do AOs on the public list My personal experience being a GSoC student was that responsibility and fellowship matters most - it's what makes contributing addictive. It's one thing to do an interesting project for 12 weeks but another to stick around because the group of developers have become your friends and you feel responsibility and satisfaction from supporting users on IRC/mailing lists. The easiest way to give students responsibility is to get them actively involved in supporting users on IRC/mailing lists and fixing bugs. Doing this in addition to the official GSoC project is more likely to keep them hooked. It helps turn them into a QEMU expert and someone who can help others - and hopefully they'll want to continue using this skill once the summer is over. Stefan
[Qemu-devel] [PATCH] hw/9pfs: use g_vasprintf() instead of rolling our own
Markus Armbruster arm...@redhat.com sent fixes for va_list vararg issues in v9fs_string_alloc_printf(). It turns out the function duplicates g_vasprintf() and can therefore be eliminated entirely. Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com --- hw/9pfs/virtio-9p.c | 103 ++- 1 files changed, 4 insertions(+), 99 deletions(-) diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c index 8b6813f..253919b 100644 --- a/hw/9pfs/virtio-9p.c +++ b/hw/9pfs/virtio-9p.c @@ -11,6 +11,9 @@ * */ +#include glib.h +#include glib/gprintf.h + #include hw/virtio.h #include hw/pc.h #include qemu_socket.h @@ -161,114 +164,16 @@ void v9fs_string_null(V9fsString *str) v9fs_string_free(str); } -static int number_to_string(void *arg, char type) -{ -unsigned int ret = 0; - -switch (type) { -case 'u': { -unsigned int num = *(unsigned int *)arg; - -do { -ret++; -num = num/10; -} while (num); -break; -} -case 'U': { -unsigned long num = *(unsigned long *)arg; -do { -ret++; -num = num/10; -} while (num); -break; -} -default: -printf(Number_to_string: Unknown number format\n); -return -1; -} - -return ret; -} - -static int GCC_FMT_ATTR(2, 0) -v9fs_string_alloc_printf(char **strp, const char *fmt, va_list ap) -{ -va_list ap2; -char *iter = (char *)fmt; -int len = 0; -int nr_args = 0; -char *arg_char_ptr; -unsigned int arg_uint; -unsigned long arg_ulong; - -/* Find the number of %'s that denotes an argument */ -for (iter = strstr(iter, %); iter; iter = strstr(iter, %)) { -nr_args++; -iter++; -} - -len = strlen(fmt) - 2*nr_args; - -if (!nr_args) { -goto alloc_print; -} - -va_copy(ap2, ap); - -iter = (char *)fmt; - -/* Now parse the format string */ -for (iter = strstr(iter, %); iter; iter = strstr(iter, %)) { -iter++; -switch (*iter) { -case 'u': -arg_uint = va_arg(ap2, unsigned int); -len += number_to_string((void *)arg_uint, 'u'); -break; -case 'l': -if (*++iter == 'u') { -arg_ulong = va_arg(ap2, unsigned long); -len += number_to_string((void *)arg_ulong, 'U'); -} else { -return -1; -} -break; -case 's': -arg_char_ptr = va_arg(ap2, char *); -len += strlen(arg_char_ptr); -break; -case 'c': -len += 1; -break; -default: -fprintf(stderr, - v9fs_string_alloc_printf:Incorrect format %c, *iter); -return -1; -} -iter++; -} - -alloc_print: -*strp = g_malloc((len + 1) * sizeof(**strp)); - -return vsprintf(*strp, fmt, ap); -} - void GCC_FMT_ATTR(2, 3) v9fs_string_sprintf(V9fsString *str, const char *fmt, ...) { va_list ap; -int err; v9fs_string_free(str); va_start(ap, fmt); -err = v9fs_string_alloc_printf(str-data, fmt, ap); -BUG_ON(err == -1); +str-size = g_vasprintf(str-data, fmt, ap); va_end(ap); - -str-size = err; } void v9fs_string_copy(V9fsString *lhs, V9fsString *rhs) -- 1.7.7
Re: [Qemu-devel] [Qemu-trivial] [PATCH 2/2] hw/9pfs: Supply missing va_end()
On Fri, Oct 28, 2011 at 9:52 AM, Markus Armbruster arm...@redhat.com wrote: C99 7.15.1: Each invocation of the va_start and va_copy macros shall be matched by a corresponding invocation of the va_end macro in the same function. Spotted by Coverity. Harmless on the (common) systems where va_end() does nothing. Signed-off-by: Markus Armbruster arm...@redhat.com --- hw/9pfs/virtio-9p.c | 4 1 files changed, 4 insertions(+), 0 deletions(-) Thanks for this patch. I looked at the surrounding code and it turns out this entire function duplicates g_vasprintf() from glib. I sent a patch to use g_vasprintf() and it therefore eliminates the varargs issue. Stefan
Re: [Qemu-devel] [PATCH 1/2] sysbus: Supply missing va_end()
On Fri, Oct 28, 2011 at 10:52:25AM +0200, Markus Armbruster wrote: C99 7.15.1: Each invocation of the va_start and va_copy macros shall be matched by a corresponding invocation of the va_end macro in the same function. Spotted by Coverity. Harmless on the (common) systems where va_end() does nothing. Signed-off-by: Markus Armbruster arm...@redhat.com --- hw/sysbus.c |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) Thanks, applied to the trivial patches -next tree: http://repo.or.cz/w/qemu/stefanha.git/shortlog/refs/heads/trivial-patches-next Stefan
Re: [Qemu-devel] [Qemu-trivial] [PATCH] qapi: fix typos in documentation JSON examples
On Fri, Oct 28, 2011 at 03:58:26PM +0100, Stefan Hajnoczi wrote: Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com --- docs/qapi-code-gen.txt |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Applied to the trivial patches -next tree: http://repo.or.cz/w/qemu/stefanha.git/shortlog/refs/heads/trivial-patches-next Stefan
Re: [Qemu-devel] [PATCH] acl: Fix use after free in qemu_acl_reset()
On Fri, Oct 28, 2011 at 05:07:02PM +0200, Markus Armbruster wrote: Reproducer: $ MALLOC_PERTURB_=234 qemu-system-x86_64 -vnc :0,acl,sasl [...] QEMU 0.15.50 monitor - type 'help' for more information (qemu) acl_add vnc.username fred allow acl: added rule at position 1 (qemu) acl_reset vnc.username Segmentation fault (core dumped) Spotted by Coverity. Signed-off-by: Markus Armbruster arm...@redhat.com --- acl.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Thanks, applied to the trivial patches -next tree: http://repo.or.cz/w/qemu/stefanha.git/shortlog/refs/heads/trivial-patches-next Stefan
Re: [Qemu-devel] [PATCH 0/3] Xen related patches
Am 28.10.2011 21:38, schrieb John Baboval: These are some xen related patches that have been sitting around in are queue waiting for us to re-base onto a modern qemu. Now that we're up-to-date, they're ready to share with the list. They are all things that enable successfully running windows in xen HVM guests. Support guest reboots when in Xen HVM mode Xen conditionals piix4 acpi xen support -John Your patches are corrupted by line wraps, and they don't use proper email threading. Please consider using git send-email, which automatically does both of this right. Kevin
Re: [Qemu-devel] [PATCH 3/3] piix4 acpi xen support
Please CC xen-devel on patches which impact the Xen support in qemu. On Fri, 2011-10-28 at 15:38 -0400, John Baboval wrote: When in xen mode, handle the view of pm ioport appropriately. I'm not entirely comfortable with this patch, since it relies on values that are hard coded into the DSDT that is shipped with Xen. There has to be a better way to handle it, but I haven't thought of what that might be yet... Perhaps there should be an acpi_xen.c. Or perhaps the Xen table should be modified to match the device model. Or perhaps there is a good way to match them up dynamically. Anthony Perard posted a patch to xen-devel last week (series entitled hvmloader/DSDT change to handle PCI hotplug with QEMU upstream) which makes the Xen ACPI tables compatible with the upstream QEMU PM registers etc. I think that covers this issue too? Ian. Signed-off-by: John V. Baboval john.babo...@virtualcomputer.com Signed-off-by: Tom Goetz tom.go...@virtualcomputer.com --- hw/acpi_piix4.c | 82 +-- 1 files changed, 73 insertions(+), 9 deletions(-) diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c index 29f0f76..277ae9f 100644 --- a/hw/acpi_piix4.c +++ b/hw/acpi_piix4.c @@ -24,6 +24,7 @@ #include sysemu.h #include range.h #include ioport.h +#include xen.h //#define DEBUG @@ -111,6 +112,35 @@ static void pm_ioport_write(IORange *ioport, uint64_t addr, unsigned width, (unsigned)addr, width, (unsigned)val); } +if (xen_enabled()) { +/* + * Only the PM control register is emulated in Qemu under Xen. The + * remaining registers are emulated by the hypervisor. + */ +int sus_typ; +s-pm1_cnt.cnt = val ~(ACPI_BITMASK_SLEEP_ENABLE); +if (val ACPI_BITMASK_SLEEP_ENABLE) { +/* change suspend type */ +sus_typ = (val 10) 7; +switch(sus_typ) { +case 6: /* soft power off */ +case 7: /* soft power off */ +qemu_system_shutdown_request(); +break; +case 5: +/* ACPI_BITMASK_WAKE_STATUS should be set on resume. + Pretend that resume was caused by power button */ +qemu_system_reset_request(); +if (s-pm1_cnt.cmos_s3) { +qemu_irq_raise(s-pm1_cnt.cmos_s3); +} +default: +break; +} +} +return; +} + switch(addr) { case 0x00: acpi_pm1_evt_write_sts(s-pm1a, s-tmr, val); @@ -136,6 +166,15 @@ static void pm_ioport_read(IORange *ioport, uint64_t addr, unsigned width, PIIX4PMState *s = container_of(ioport, PIIX4PMState, ioport); uint32_t val; +if (xen_enabled()) { +/* + * Only the PM control register is emulated in Qemu under Xen. The + * remaining registers are emulated by the hypervisor. + */ +val = s-pm1_cnt.cnt; +return; +} + switch(addr) { case 0x00: val = acpi_pm1_evt_get_sts(s-pm1a, s-tmr.overflow_time); @@ -181,19 +220,28 @@ static void acpi_dbg_writel(void *opaque, uint32_t addr, uint32_t val) PIIX4_DPRINTF(ACPI: DBG: 0x%08x\n, val); } +#define PMCNTRL0x04 static void pm_io_space_update(PIIX4PMState *s) { -uint32_t pm_io_base; +uint32_t pm_io_base, size; + +if (!(s-dev.config[0x80] 1) !xen_enabled()) { +return; +} -if (s-dev.config[0x80] 1) { -pm_io_base = le32_to_cpu(*(uint32_t *)(s-dev.config + 0x40)); -pm_io_base = 0xffc0; +pm_io_base = le32_to_cpu(*(uint32_t *)(s-dev.config + 0x40)); +pm_io_base = 0xffc0; +size = 16; -/* XXX: need to improve memory and ioport allocation */ -PIIX4_DPRINTF(PM: mapping to 0x%x\n, pm_io_base); -iorange_init(s-ioport, pm_iorange_ops, pm_io_base, 64); -ioport_register(s-ioport); +if (xen_enabled()) { +size = 2; +pm_io_base += PMCNTRL; } + +/* XXX: need to improve memory and ioport allocation */ +PIIX4_DPRINTF(PM: mapping to 0x%x\n, pm_io_base); +iorange_init(s-ioport, pm_iorange_ops, pm_io_base, size); +ioport_register(s-ioport); } static void pm_write_config(PCIDevice *d, @@ -326,6 +374,13 @@ static void piix4_pm_machine_ready(Notifier *n, void *opaque) } +#definePIIX4_BASE_IOADDR 0x1f40 +#definePIIX4_BASE_IOADDR_LO((PIIX4_BASE_IOADDR) 0xff) +#definePIIX4_BASE_IOADDR_HI((PIIX4_BASE_IOADDR)8) + +/* PM1a_CNT bits, as defined in the ACPI specification. */ +#define SCI_EN(1 0) + static int piix4_pm_initfn(PCIDevice *dev) { PIIX4PMState *s = DO_UPCAST(PIIX4PMState, dev, dev); @@ -337,7 +392,13 @@ static int piix4_pm_initfn(PCIDevice *dev) pci_conf[0x09] = 0x00;
Re: [Qemu-devel] Performance of USB2.0
Hi, On 10/31/2011 10:27 AM, Til Obes wrote: Hello all, i want to use a virtual router which is connected to a cable box via an usb ethernet controller. The device itself runs properly at normal usage. But inside the virtual machine i get only about 7MBit. I configured the the usb device with the following xml syntax of libvirt: controller type='usb' index='0' model='ehci' address type='pci' domain='0x' bus='0x00' slot='0x07' function='0x0'/ /controller hostdev mode='subsystem' type='usb' managed='no' source vendor id='0x9710'/ product id='0x7830'/ /source /hostdev Inside the guest i get this output of lsusb: Bus 001 Device 002: ID 9710:7830 MosChip Semiconductor MCS7830 10/100 Mbps Ethernet adapter Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub lsusb -v shows this output for the root hub: Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 9 Hub bDeviceSubClass 0 Unused bDeviceProtocol 0 Full speed (or root) hub bMaxPacketSize0 64 idVendor 0x1d6b Linux Foundation idProduct 0x0002 2.0 root hub bcdDevice 2.06 iManufacturer 3 Linux 2.6.32-5-amd64 ehci_hcd iProduct 2 EHCI Host Controller iSerial 1 :00:07.0 Does this Full speed mean, that it is still running with 12MBit? No, as lsusb says bDeviceProtocol 0 is standard for root hubs even for usb2 (so high speed / 480mbit capable) root hubs. What is the status of High Speed USB (480Mbit) inside the guest? It should work fine since qemu 0.15. If you're using libvirt to start qemu, then it will also pass -usb to qemu, so you will have both a usb-1 (uhci) and a usb-2 (ehci) controller inside your vm, since your hostdev xml code does not specify a bus the hostdev will likely get connected to the first usb bus which is the one attached to the uhci controller, although your lsusb output suggests otherwise (to my surprise). So assuming that I'm reading your lsusb output correct, the device does seem to be connected to the virtual ehci controller rather then to the virtual uhci controller, which more or less rules that out as the cause. This means that the likely cause is just that usb emulation / pass through causes quite a bit of overhead, which is not unexpected since both the usb protocol and the ehci controller interface are both quite hard to emulate. It is likely better to just use the usb nic directly from the host, and then pass it through the virtio-net using bridging. Regards, Hans
Re: [Qemu-devel] [PATCH] hw/9pfs: use g_vasprintf() instead of rolling our own
Stefan Hajnoczi stefa...@linux.vnet.ibm.com writes: Markus Armbruster arm...@redhat.com sent fixes for va_list vararg issues in v9fs_string_alloc_printf(). It turns out the function duplicates g_vasprintf() and can therefore be eliminated entirely. Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com --- hw/9pfs/virtio-9p.c | 103 ++- 1 files changed, 4 insertions(+), 99 deletions(-) *Much* better. Reviewed-by: Markus Armbruster arm...@redhat.com
Re: [Qemu-devel] GSoC mentor summit QEMU users session
On 29 October 2011 14:52, Alexander Graf ag...@suse.de wrote: We should also show people unmaintained areas. The conclusion was a wiki page with subsystems and status so people know what to expect. Maybe we could generate this from the MAINTAINERS file? Sounds like a good idea, although I think we might need to expand MAINTAINERS a bit -- I get the impression that there are a lot of little bits that fall into the gaps between the top-level areas marked out in MAINTAINERS. Also, an easy way of counterfighting the feeling ignored part is to tell people that they just hit an unmaintained area. There's nothing more frustrating than sending a patch and get no reply. Receiving a reply Sorry, this area is unmaintained. Please find someone to review it. would already be enough for most people. The difficulty that strikes me with this is that I'm not sure any one person can reliably look at a patch and say that's for an unmaintained area (at least, I know what areas I can review but I have no idea about everybody else...) So you can only really tell by default, ie if the patch sits for a few weeks without any reply... A lot of people seem to also have code that doesn't make sense upstream, for example implementing a one-off device that only really matters for their own devboard which nobody else owns. For such cases, having a plugin framework would be handy. I interestingly enough got into the same discussion on LinuxCon with some QEMU downstreams. If we get the qdev rework done then I think we're probably in a better position to have a plugin framework for devices. (There are some issues about API and ABI stability guarantees, of course.) -- PMM
Re: [Qemu-devel] [PATCH 3/3] piix4 acpi xen support
On Mon, Oct 31, 2011 at 12:41, Ian Campbell ian.campb...@citrix.com wrote: Please CC xen-devel on patches which impact the Xen support in qemu. On Fri, 2011-10-28 at 15:38 -0400, John Baboval wrote: When in xen mode, handle the view of pm ioport appropriately. I'm not entirely comfortable with this patch, since it relies on values that are hard coded into the DSDT that is shipped with Xen. There has to be a better way to handle it, but I haven't thought of what that might be yet... Perhaps there should be an acpi_xen.c. Or perhaps the Xen table should be modified to match the device model. Or perhaps there is a good way to match them up dynamically. Anthony Perard posted a patch to xen-devel last week (series entitled hvmloader/DSDT change to handle PCI hotplug with QEMU upstream) which makes the Xen ACPI tables compatible with the upstream QEMU PM registers etc. I think that covers this issue too? Actually, Xen unstable should already have the necessary change to cover everythings in this patch since a while. So QEMU does not need to be modified. If something does not work, could you tell me what? Regards, -- Anthony PERARD
[Qemu-devel] [PULL 00/55] Block patches
The following changes since commit b5a12aa204f842c8010ac9d2e4b115114dbf09f0: Merge branch 'rth/vis2' of git://repo.or.cz/qemu/rth (2011-10-27 20:27:07 +) are available in the git repository at: git://repo.or.cz/qemu/kevin.git for-anthony Dong Xu Wang (1): block: fix qcow2_co_flush deadlock Eric Sunshine (1): Teach block/vdi about discarded (no longer allocated) blocks Kevin Wolf (7): block: Remove dead code block: Fix bdrv_open use after free qcow: Fix bdrv_write_compressed error handling ide: Fix off-by-one error in array index check vmdk: Fix use of uninitialised value vmdk: Improve error handling vmdk: Fix possible segfaults Paolo Bonzini (38): scsi: pass correct sense code for ENOMEDIUM atapi/scsi: unify definitions for MMC atapi: move GESN definitions to scsi-defs.h atapi: cleanup/fix mode sense results scsi: notify the device when unit attention is reported scsi-disk: report media changed via unit attention sense codes scsi-disk: fix coding style issues (braces) scsi-disk: add stubs for more MMC commands scsi-disk: store valid mode pages in a table atapi/scsi-disk: make mode page values coherent between the two scsi-disk: support DVD profile in GET CONFIGURATION scsi-disk: support READ DVD STRUCTURE scsi-disk: report media changed via GET EVENT STATUS NOTIFICATION scsi: move tcq/ndev to SCSIBusOps (now SCSIBusInfo) qdev: switch children device list to QTAILQ scsi: remove devs array from SCSIBus scsi: implement REPORT LUNS for arbitrary LUNs scsi: allow arbitrary LUNs scsi: add channel to addressing scsi-disk: fail READ CAPACITY if LBA != 0 but PMI == 0 scsi-disk: fix retrying a flush scsi-generic: drop SCSIGenericState scsi-generic: remove scsi_req_fixup scsi-generic: check ioctl statuses when SG_IO succeeds scsi-generic: look at host status scsi-generic: snoop READ CAPACITY commands to get block size scsi-disk: do not duplicate BlockDriverState member scsi-disk: remove cluster_size scsi-disk: small clean up to INQUIRY scsi: move max_lba to SCSIDevice scsi: make reqops const scsi: export scsi_generic_reqops scsi: pass cdb to alloc_req scsi: do not call transfer_data after canceling a request scsi-disk: bump SCSIRequest reference count until aio completion runs scsi-generic: bump SCSIRequest reference count until aio completion runs scsi: push request restart to SCSIDevice scsi-disk: add scsi-block for device passthrough Ronnie Sahlberg (4): iSCSI block driver Documentation: Add iSCSI section Documentation: Describe NBD URL syntax Documentation: Add syntax for using sheepdog devices Stefan Hajnoczi (3): qemu-io: delete bs instead of leaking it block: set bs-read_only before .bdrv_open() block: reinitialize across bdrv_close()/bdrv_open() Zhi Yong Wu (1): qcow2: fix some errors and typo in qcow2.txt Makefile.objs|1 + block.c | 18 +- block/iscsi.c| 591 block/qcow.c | 30 ++- block/qcow2.c|2 + block/vdi.c | 23 +- block/vmdk.c | 30 ++- configure| 31 ++ docs/specs/qcow2.txt |6 +- hw/acpi_piix4.c |4 +- hw/esp.c | 16 +- hw/i2c.c |2 +- hw/ide/atapi.c | 119 +++- hw/ide/core.c|6 +- hw/ide/internal.h| 71 +- hw/ide/macio.c |2 +- hw/intel-hda.c |6 +- hw/lsi53c895a.c | 30 +- hw/qdev.c| 24 +- hw/qdev.h|4 +- hw/s390-virtio-bus.c |4 +- hw/scsi-bus.c| 279 + hw/scsi-defs.h | 90 ++ hw/scsi-disk.c | 824 +- hw/scsi-generic.c| 201 ++--- hw/scsi.h| 39 ++- hw/spapr_vio.c |6 +- hw/spapr_vscsi.c | 54 +++- hw/ssi.c |6 +- hw/usb-msd.c |8 +- qemu-io.c|5 +- qemu-options.hx | 90 ++ trace-events |7 + 33 files changed, 1979 insertions(+), 650 deletions(-) create mode 100644 block/iscsi.c
[Qemu-devel] [PATCH 02/55] Documentation: Add iSCSI section
From: Ronnie Sahlberg ronniesahlb...@gmail.com Add new section for device URL syntax for special files and describe the iSCSI URL with examples Signed-off-by: Ronnie Sahlberg ronniesahlb...@gmail.com Reviewed-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com Signed-off-by: Kevin Wolf kw...@redhat.com --- qemu-options.hx | 42 ++ 1 files changed, 42 insertions(+), 0 deletions(-) diff --git a/qemu-options.hx b/qemu-options.hx index 5d2a776..424bae9 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -148,6 +148,9 @@ Define a new drive. Valid options are: This option defines which disk image (@pxref{disk_images}) to use with this drive. If the filename contains comma, you must double it (for instance, file=my,,file to use file my,file). + +Special files such as iSCSI devices can be specified using protocol +specific URLs. See the section for Device URL Syntax for more information. @item if=@var{interface} This option defines on which type on interface the drive is connected. Available types are: ide, scsi, sd, mtd, floppy, pflash, virtio. @@ -1718,6 +1721,45 @@ ETEXI DEFHEADING() +STEXI +DEFHEADING(Device URL Syntax:) + +In addition to using normal file images for the emulated storage devices, +QEMU can also use networked resources such as iSCSI devices. These are +specified using a special URL syntax. + +@table @option +@item iSCSI +iSCSI support allows QEMU to access iSCSI resources directly and use as +images for the guest storage. Both disk and cdrom images are supported. + +Syntax for specifying iSCSI LUNs is +``iscsi://target-ip[:port]/target-iqn/lun'' + +Example (without authentication): +@example +qemu -cdrom iscsi://192.0.2.1/iqn.2001-04.com.example/2 \ +--drive file=iscsi://192.0.2.1/iqn.2001-04.com.example/1 +@end example + +Example (CHAP username/password via URL): +@example +qemu --drive file=iscsi://user%password@@192.0.2.1/iqn.2001-04.com.example/1 +@end example + +Example (CHAP username/password via environment variables): +@example +LIBISCSI_CHAP_USERNAME=user \ +LIBISCSI_CHAP_PASSWORD=password \ +qemu --drive file=iscsi://192.0.2.1/iqn.2001-04.com.example/1 +@end example + +iSCSI support is an optional feature of QEMU and only available when +compiled and linked against libiscsi. + +@end table +ETEXI + DEFHEADING(Bluetooth(R) options:) DEF(bt, HAS_ARG, QEMU_OPTION_bt, \ -- 1.7.6.4
[Qemu-devel] [PATCH 08/55] ide: Fix off-by-one error in array index check
Signed-off-by: Kevin Wolf kw...@redhat.com Reviewed-by: Paolo Bonzini pbonz...@redhat.com --- hw/ide/core.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/hw/ide/core.c b/hw/ide/core.c index 280a117..29305d3 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -2039,7 +2039,7 @@ static int ide_drive_pio_post_load(void *opaque, int version_id) { IDEState *s = opaque; -if (s-end_transfer_fn_idx ARRAY_SIZE(transfer_end_table)) { +if (s-end_transfer_fn_idx = ARRAY_SIZE(transfer_end_table)) { return -EINVAL; } s-end_transfer_func = transfer_end_table[s-end_transfer_fn_idx]; -- 1.7.6.4
[Qemu-devel] [PATCH 47/55] scsi: move max_lba to SCSIDevice
From: Paolo Bonzini pbonz...@redhat.com The field is only in scsi-disk for now. Moving it up to SCSIDevice makes it easier to reuse the scsi-generic reqops elsewhere. At the same time, make scsi-generic get max_lba from snooped READ CAPACITY commands as well. Signed-off-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Kevin Wolf kw...@redhat.com --- hw/scsi-disk.c| 15 +++ hw/scsi-generic.c |2 ++ hw/scsi.h |1 + 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index af1001d..74990a8 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -66,7 +66,6 @@ struct SCSIDiskState { SCSIDevice qdev; uint32_t removable; -uint64_t max_lba; bool media_changed; bool media_event; QEMUBH *bh; @@ -1175,7 +1174,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r) /* Returned value is the address of the last sector. */ nb_sectors--; /* Remember the new size for read/write sanity checking. */ -s-max_lba = nb_sectors; +s-qdev.max_lba = nb_sectors; /* Clip to 2TB, instead of returning capacity modulo 2TB. */ if (nb_sectors UINT32_MAX) { nb_sectors = UINT32_MAX; @@ -1230,7 +1229,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r) /* Returned value is the address of the last sector. */ nb_sectors--; /* Remember the new size for read/write sanity checking. */ -s-max_lba = nb_sectors; +s-qdev.max_lba = nb_sectors; outbuf[0] = (nb_sectors 56) 0xff; outbuf[1] = (nb_sectors 48) 0xff; outbuf[2] = (nb_sectors 40) 0xff; @@ -1345,7 +1344,7 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf) case READ_16: len = r-req.cmd.xfer / s-qdev.blocksize; DPRINTF(Read (sector % PRId64 , count %d)\n, r-req.cmd.lba, len); -if (r-req.cmd.lba s-max_lba) { +if (r-req.cmd.lba s-qdev.max_lba) { goto illegal_lba; } r-sector = r-req.cmd.lba * (s-qdev.blocksize / 512); @@ -1362,7 +1361,7 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf) DPRINTF(Write %s(sector % PRId64 , count %d)\n, (command 0xe) == 0xe ? And Verify : , r-req.cmd.lba, len); -if (r-req.cmd.lba s-max_lba) { +if (r-req.cmd.lba s-qdev.max_lba) { goto illegal_lba; } r-sector = r-req.cmd.lba * (s-qdev.blocksize / 512); @@ -1388,7 +1387,7 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf) case SEEK_10: DPRINTF(Seek(%d) (sector % PRId64 )\n, command == SEEK_6 ? 6 : 10, r-req.cmd.lba); -if (r-req.cmd.lba s-max_lba) { +if (r-req.cmd.lba s-qdev.max_lba) { goto illegal_lba; } break; @@ -1398,7 +1397,7 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf) DPRINTF(WRITE SAME(16) (sector % PRId64 , count %d)\n, r-req.cmd.lba, len); -if (r-req.cmd.lba s-max_lba) { +if (r-req.cmd.lba s-qdev.max_lba) { goto illegal_lba; } @@ -1457,7 +1456,7 @@ static void scsi_disk_reset(DeviceState *dev) if (nb_sectors) { nb_sectors--; } -s-max_lba = nb_sectors; +s-qdev.max_lba = nb_sectors; } static void scsi_destroy(SCSIDevice *dev) diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c index 4d7ad82..fcf23cd 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -174,9 +174,11 @@ static void scsi_read_complete(void * opaque, int ret) /* Snoop READ CAPACITY output to set the blocksize. */ if (r-req.cmd.buf[0] == READ_CAPACITY_10) { s-blocksize = ldl_be_p(r-buf[4]); +s-max_lba = ldl_be_p(r-buf[0]); } else if (r-req.cmd.buf[0] == SERVICE_ACTION_IN_16 (r-req.cmd.buf[1] 31) == SAI_READ_CAPACITY_16) { s-blocksize = ldl_be_p(r-buf[8]); +s-max_lba = ldq_be_p(r-buf[0]); } bdrv_set_buffer_alignment(s-conf.bs, s-blocksize); diff --git a/hw/scsi.h b/hw/scsi.h index c8649cf..d56e875 100644 --- a/hw/scsi.h +++ b/hw/scsi.h @@ -70,6 +70,7 @@ struct SCSIDevice uint32_t lun; int blocksize; int type; +uint64_t max_lba; }; /* cdrom.c */ -- 1.7.6.4
[Qemu-devel] 1.0 Hard Freeze Logistics
Hi, Here are the logistics for the upcoming 1.0 hard freeze. All dates are reflected in the wiki[1]. If you're a contributor and you've sent a series before the soft freeze deadline, you've already done everything you need to do so sit back and enjoy gorge yourself on Halloween candy. If you're a submaintainer, the deadline for PULL requests for 1.0 hard freeze will be EOD tomorrow (May 1st). I encourage all submaintainers to spend today and tomorrow reviewing any outstanding patches on the mailing list. I will do the same. Once everything is processed, I'll update VERSION, and tag v1.0-rc0. I will not upload a -rc0 tarball since this is basically a git snapshot. Unlike previous releases, we will do this stable development in HEAD. Our first release candidate will be tagged and released on November 7th (next Tuesday). I'll do the release that Monday evening so that the -rc1 build is available for out Test Day[2]. To make the Test Day more successful, please sign up to test a specific area on the Test[3] wiki page. We have a fairly long -rc cycle for this release so I expect submaintainers will continue to maintain patches in their tree. I also think it would be good to set up a -next staging tree but we can discuss that more in another thread. [1] http://wiki.qemu.org/Planning/1.0 [2] http://mid.gmane.org/4ea94d53.3000...@redhat.com [3] http://wiki.qemu.org/Planning/1.0/Testing Regards, Anthony Liguori
[Qemu-devel] [PATCH 36/55] scsi: add channel to addressing
From: Paolo Bonzini pbonz...@redhat.com This also requires little more than adding the new argument to scsi_device_find, and the qdev property. All devices by default end up on channel 0. Signed-off-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Kevin Wolf kw...@redhat.com --- hw/esp.c |4 ++-- hw/lsi53c895a.c |4 ++-- hw/scsi-bus.c| 24 +++- hw/scsi.h|5 +++-- hw/spapr_vscsi.c |9 +++-- 5 files changed, 25 insertions(+), 21 deletions(-) diff --git a/hw/esp.c b/hw/esp.c index 5742bb3..b698a43 100644 --- a/hw/esp.c +++ b/hw/esp.c @@ -217,7 +217,7 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf) s-async_len = 0; } -s-current_dev = scsi_device_find(s-bus, target, 0); +s-current_dev = scsi_device_find(s-bus, 0, target, 0); if (!s-current_dev) { // No such drive s-rregs[ESP_RSTAT] = 0; @@ -237,7 +237,7 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid) trace_esp_do_busid_cmd(busid); lun = busid 7; -current_lun = scsi_device_find(s-bus, s-current_dev-id, lun); +current_lun = scsi_device_find(s-bus, 0, s-current_dev-id, lun); s-current_req = scsi_req_new(current_lun, 0, lun, buf, NULL); datalen = scsi_req_enqueue(s-current_req); s-ti_size = datalen; diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c index d26e442..2984cea 100644 --- a/hw/lsi53c895a.c +++ b/hw/lsi53c895a.c @@ -767,7 +767,7 @@ static void lsi_do_command(LSIState *s) s-command_complete = 0; id = (s-select_tag 8) 0xf; -dev = scsi_device_find(s-bus, id, s-current_lun); +dev = scsi_device_find(s-bus, 0, id, s-current_lun); if (!dev) { lsi_bad_selection(s, id); return; @@ -1198,7 +1198,7 @@ again: } s-sstat0 |= LSI_SSTAT0_WOA; s-scntl1 = ~LSI_SCNTL1_IARB; -if (!scsi_device_find(s-bus, id, 0)) { +if (!scsi_device_find(s-bus, 0, id, 0)) { lsi_bad_selection(s, id); break; } diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index cec06db..bdd6e94 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -16,6 +16,7 @@ static struct BusInfo scsi_bus_info = { .size = sizeof(SCSIBus), .get_fw_dev_path = scsibus_get_fw_dev_path, .props = (Property[]) { +DEFINE_PROP_UINT32(channel, SCSIDevice, channel, 0), DEFINE_PROP_UINT32(scsi-id, SCSIDevice, id, -1), DEFINE_PROP_UINT32(lun, SCSIDevice, lun, -1), DEFINE_PROP_END_OF_LIST(), @@ -40,6 +41,10 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base) SCSIDevice *d; int rc = -1; +if (dev-channel bus-info-max_channel) { +error_report(bad scsi channel id: %d, dev-channel); +goto err; +} if (dev-id != -1 dev-id bus-info-max_target) { error_report(bad scsi device id: %d, dev-id); goto err; @@ -51,7 +56,7 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base) dev-lun = 0; } do { -d = scsi_device_find(bus, ++id, dev-lun); +d = scsi_device_find(bus, dev-channel, ++id, dev-lun); } while (d d-lun == dev-lun id = bus-info-max_target); if (id bus-info-max_target) { error_report(no free target); @@ -61,7 +66,7 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base) } else if (dev-lun == -1) { int lun = -1; do { -d = scsi_device_find(bus, dev-id, ++lun); +d = scsi_device_find(bus, dev-channel, dev-id, ++lun); } while (d d-lun == lun lun bus-info-max_lun); if (lun bus-info-max_lun) { error_report(no free lun); @@ -69,7 +74,7 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base) } dev-lun = lun; } else { -d = scsi_device_find(bus, dev-id, dev-lun); +d = scsi_device_find(bus, dev-channel, dev-id, dev-lun); if (dev-lun == d-lun dev != d) { qdev_free(d-qdev); } @@ -203,7 +208,7 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r) { DeviceState *qdev; int i, len, n; -int id; +int channel, id; bool found_lun0; if (r-req.cmd.xfer 16) { @@ -212,13 +217,14 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r) if (r-req.cmd.buf[2] 2) { return false; } +channel = r-req.dev-channel; id = r-req.dev-id; found_lun0 = false; n = 0; QTAILQ_FOREACH(qdev, r-req.bus-qbus.children, sibling) { SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev); -if (dev-id == id) { +if (dev-channel == channel dev-id == id) { if (dev-lun == 0) { found_lun0 = true; } @@ -240,7 +246,7 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r)
Re: [Qemu-devel] [PATCH v9 1/4] block: add the block queue support
On Fri, Oct 28, 2011 at 11:02 AM, Zhi Yong Wu wu...@linux.vnet.ibm.com wrote: +static void bdrv_io_limits_skip_set(void *opaque, + BlockAPIType co_type, + bool cb_skip, + bool limit_skip) { + RwCo *rwco; + BlockDriverAIOCBCoroutine *aioco; + + if (co_type == BDRV_API_SYNC) { + rwco = opaque; + rwco-limit_skip = limit_skip; + } else if (co_type == BDRV_API_ASYNC) { + aioco = opaque; + aioco-cb_skip = cb_skip; + aioco-limit_skip = limit_skip; + } else { + abort(); + } +} The main question I have about this series is why have different cases for sync, aio, and coroutines? Perhaps I'm missing something but this should all be much simpler. All read/write requests are processed in a coroutine (bdrv_co_do_readv()/bdrv_co_do_writev()). That is the place to perform I/O throttling. Throttling should not be aware of sync, aio, vs coroutines. Since all requests have coroutines you could use CoQueue and the actual queue waiting code in bdrv_co_do_readv()/bdrv_co_do_writev() becomes: if (bdrv_exceeds_io_limit(bs, sector_num, qiov, is_write)) { qemu_co_queue_wait(bs-throttled_reqs); /* Wait until this request is allowed to start */ while (bdrv_exceeds_io_limit(bs, sector_num, qiov, is_write)) { /* Re-inserting at the head of the CoQueue is equivalent to * the queue-flushing/queue-limit_exceeded behavior in your * patch. */ qemu_co_queue_wait_insert_head(bs-throttled_reqs); } } I think block/blk-queue.h isn't needed if you use the existing CoQueue structure. This is the main point I want to raise, just a few minor comments below which may not be relevant if you can drop BlockQueue. +static int qemu_block_queue_handler(BlockQueueAIOCB *request) +{ + int ret; + + BlockDriverState *bs = request-common.bs; + assert(bs); + + if (bs-io_limits_enabled) { I'm not sure why the BlockQueue needs to reach into BlockDriverState. Now BlockDriverState and BlockQueue know about and depend on each other. It's usually nicer to keep the relationship unidirectional, if possible. + ret = request-handler(request-common.bs, request-sector_num, + request-nb_sectors, request-qiov, + request, request-co_type); + } else { + if (request-co_type == BDRV_API_CO) { + qemu_coroutine_enter(request-co, request-cocb); + } else { + printf(%s, req: %p\n, __func__, (void *)request); Debug output should be removed. + bdrv_io_limits_issue_request(request, request-co_type); + } + + ret = BDRV_BLKQ_DEQ_PASS; + } + + return ret; +} + +void qemu_block_queue_submit(BlockQueue *queue, BlockDriverCompletionFunc *cb) +{ + BlockQueueAIOCB *request; + queue-flushing = true; + + /*QTAILQ_FOREACH_SAFE(request, queue-requests, entry, next) {*/ Commented out code should be removed. + while (!QTAILQ_EMPTY(queue-requests)) { + int ret = 0; + + request = QTAILQ_FIRST(queue-requests); + QTAILQ_REMOVE(queue-requests, request, entry); + queue-limit_exceeded = false; + ret = qemu_block_queue_handler(request); + if (ret == -EIO) { + cb(request, -EIO); + break; + } else if (ret == BDRV_BLKQ_ENQ_AGAIN) { + QTAILQ_INSERT_HEAD(queue-requests, request, entry); + break; + } else if (ret == BDRV_BLKQ_DEQ_PASS) { + cb(request, 0); + } What if ret is not -EIO, BDRV_BLKQ_ENQ_AGAIN, or BDRV_BLKQ_DEQ_PASS? I think the -EIO case should be the default that calls cb(request, ret). + } + + printf(%s, leave\n, __func__); Debug code should be removed. Stefan
Re: [Qemu-devel] Performance of USB2.0
Hi. Am 31.10.2011 13:46, schrieb Hans de Goede: If you're using libvirt to start qemu, then it will also pass -usb to qemu, so you will have both a usb-1 (uhci) and a usb-2 (ehci) controller inside your vm, since your hostdev xml code does not specify a bus the hostdev will likely get connected to the first usb bus which is the one attached to the uhci controller, although your lsusb output suggests otherwise (to my surprise). So assuming that I'm reading your lsusb output correct, the device does seem to be connected to the virtual ehci controller rather then to the virtual uhci controller, which more or less rules that out as the cause. The kernel output says: router:~# dmesg|grep usb [0.418314] usbcore: registered new interface driver usbfs [0.418401] usbcore: registered new interface driver hub [0.419256] usbcore: registered new device driver usb [0.488137] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002 [0.488144] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1 [0.488150] usb usb1: Product: EHCI Host Controller [0.488155] usb usb1: Manufacturer: Linux 2.6.32-5-amd64 ehci_hcd [0.488160] usb usb1: SerialNumber: :00:07.0 [0.488437] usb usb1: configuration #1 chosen from 1 choice [1.155604] usb 1-1: new high speed USB device using ehci_hcd and address 2 [1.665760] usb 1-1: New USB device found, idVendor=9710, idProduct=7830 [1.665781] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 [1.665784] usb 1-1: Product: USB-MAC Controller [1.665786] usb 1-1: Manufacturer: Moschip Semiconductor [1.665787] usb 1-1: SerialNumber: 3b0c00d1 [1.665886] usb 1-1: configuration #1 chosen from 1 choice [1.877906] usb 1-1: applying rev.C fixup [1.890249] usb 1-1: applying rev.C fixup [1.905011] eth2: register 'MOSCHIP usb-ethernet driver' at usb-:00:07.0-1, MOSCHIP 7830/7730 usb-NET adapter, 00:13:3b:0c:00:d1 [1.905028] usbcore: registered new interface driver MOSCHIP usb-ethernet driver So it should work with my configuration... This means that the likely cause is just that usb emulation / pass through causes quite a bit of overhead, which is not unexpected since both the usb protocol and the ehci controller interface are both quite hard to emulate. But 6Mbit from 480MBit is quite low, at least 100MBit should be realistic or? How can i debug this? It is likely better to just use the usb nic directly from the host, and then pass it through the virtio-net using bridging. Well the cable modem is only talking to the first mac address it gets. In my setup eth1 is the bridged nic to the cable box and it isnt working. Any suggestions how to solve this? Regards Til
[Qemu-devel] [PATCH 51/55] scsi: do not call transfer_data after canceling a request
From: Paolo Bonzini pbonz...@redhat.com Otherwise, if cancellation is faked by the AIO layer and goes through qemu_aio_flush, the whole request is completed synchronously during scsi_req_cancel. Using the enqueued flag would work here, but not in the next patches, so I'm introducing a new io_canceled flag. That's because scsi_req_data is a synchronous callback and the enqueued flag might be reset by the time it returns. scsi-disk cannot unref the request until after calling scsi_req_data. Signed-off-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Kevin Wolf kw...@redhat.com --- hw/scsi-bus.c | 23 +++ hw/scsi.h |1 + trace-events |1 + 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index 3cf571e..dfce5fb 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -1107,8 +1107,12 @@ void scsi_req_continue(SCSIRequest *req) Once it completes, calling scsi_req_continue will restart I/O. */ void scsi_req_data(SCSIRequest *req, int len) { -trace_scsi_req_data(req-dev-id, req-lun, req-tag, len); -req-bus-info-transfer_data(req, len); +if (req-io_canceled) { +trace_scsi_req_data_canceled(req-dev-id, req-lun, req-tag, len); +} else { +trace_scsi_req_data(req-dev-id, req-lun, req-tag, len); +req-bus-info-transfer_data(req, len); +} } void scsi_req_print(SCSIRequest *req) @@ -1173,11 +1177,15 @@ void scsi_req_complete(SCSIRequest *req, int status) void scsi_req_cancel(SCSIRequest *req) { -if (req-ops-cancel_io) { -req-ops-cancel_io(req); +if (!req-enqueued) { +return; } scsi_req_ref(req); scsi_req_dequeue(req); +req-io_canceled = true; +if (req-ops-cancel_io) { +req-ops-cancel_io(req); +} if (req-bus-info-cancel) { req-bus-info-cancel(req); } @@ -1186,10 +1194,17 @@ void scsi_req_cancel(SCSIRequest *req) void scsi_req_abort(SCSIRequest *req, int status) { +if (!req-enqueued) { +return; +} +scsi_req_ref(req); +scsi_req_dequeue(req); +req-io_canceled = true; if (req-ops-cancel_io) { req-ops-cancel_io(req); } scsi_req_complete(req, status); +scsi_req_unref(req); } void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense) diff --git a/hw/scsi.h b/hw/scsi.h index 8ea744a..fcc3455 100644 --- a/hw/scsi.h +++ b/hw/scsi.h @@ -51,6 +51,7 @@ struct SCSIRequest { uint8_t sense[SCSI_SENSE_BUF_SIZE]; uint32_t sense_len; bool enqueued; +bool io_canceled; void *hba_private; QTAILQ_ENTRY(SCSIRequest) next; }; diff --git a/trace-events b/trace-events index a888055..56443af 100644 --- a/trace-events +++ b/trace-events @@ -278,6 +278,7 @@ usb_host_claim_port(int bus, int hub, int port) bus %d, hub addr %d, port %d # hw/scsi-bus.c scsi_req_alloc(int target, int lun, int tag) target %d lun %d tag %d scsi_req_data(int target, int lun, int tag, int len) target %d lun %d tag %d len %d +scsi_req_data_canceled(int target, int lun, int tag, int len) target %d lun %d tag %d len %d scsi_req_dequeue(int target, int lun, int tag) target %d lun %d tag %d scsi_req_continue(int target, int lun, int tag) target %d lun %d tag %d scsi_req_parsed(int target, int lun, int tag, int cmd, int mode, int xfer) target %d lun %d tag %d command %d dir %d length %d -- 1.7.6.4
Re: [Qemu-devel] [PATCH v3 0/3] TLS abstraction layer for thread-local cpu_single_env on Linux
An early ping since I have no idea who counts as the submaintainer for this patchset and it definitely needs to go in for 1.0... thanks -- PMM On 28 October 2011 10:52, Peter Maydell peter.mayd...@linaro.org wrote: These patches add enough of the TLS abstraction layer to allow us to make cpu_single_env thread-local on Linux systems. This fixes the regression described in bug 823902 for the 1.0 release; we can add the Win32 and POSIX implementations later. I haven't included Paolo's Prepare Windows port for thread-local cpu_single_env patch -- it would be safe to do so but it isn't necessary until we actually implement TLS for Win32. Changes v1-v2: * fix Paolo's email address * split the darwin-user change out into a separate patch * drop the 'tls_' prefix from the cpu_single_env tls var name Changes v2-v3: * minor rearrangement of copyright notice in comment * added a missing Signed-off-by * fixed the name of the multiple-include-guard #define Paolo Bonzini (2): darwin-user/main.c: Drop unused cpu_single_env definition Make cpu_single_env thread-local Peter Maydell (1): qemu-tls.h: Add abstraction layer for TLS variables cpu-all.h | 4 +++- darwin-user/main.c | 2 -- exec.c | 2 +- qemu-tls.h | 52 4 files changed, 56 insertions(+), 4 deletions(-) create mode 100644 qemu-tls.h
[Qemu-devel] [PATCH 21/55] atapi: cleanup/fix mode sense results
From: Paolo Bonzini pbonz...@redhat.com The first two bytes (after the 8-byte ATAPI header) are the mode page number and the number of bytes after the length field itself. Make this clear in the code. The AUDIO_CTL page was filled with wrong values. It is not anymore in MMC, but at least keep the values sane. Signed-off-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Kevin Wolf kw...@redhat.com --- hw/ide/atapi.c | 10 ++ 1 files changed, 6 insertions(+), 4 deletions(-) diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c index 347c38d..e898da2 100644 --- a/hw/ide/atapi.c +++ b/hw/ide/atapi.c @@ -711,8 +711,8 @@ static void cmd_mode_sense(IDEState *s, uint8_t *buf) buf[6] = 0; buf[7] = 0; -buf[8] = 0x01; -buf[9] = 0x06; +buf[8] = MODE_PAGE_R_W_ERROR; +buf[9] = 16 - 10; buf[10] = 0x00; buf[11] = 0x05; buf[12] = 0x00; @@ -730,6 +730,8 @@ static void cmd_mode_sense(IDEState *s, uint8_t *buf) buf[6] = 0; buf[7] = 0; +buf[8] = MODE_PAGE_AUDIO_CTL; +buf[9] = 24 - 10; /* Fill with CDROM audio volume */ buf[17] = 0; buf[19] = 0; @@ -747,8 +749,8 @@ static void cmd_mode_sense(IDEState *s, uint8_t *buf) buf[6] = 0; buf[7] = 0; -buf[8] = 0x2a; -buf[9] = 0x12; +buf[8] = MODE_PAGE_CAPABILITIES; +buf[9] = 28 - 10; buf[10] = 0x00; buf[11] = 0x00; -- 1.7.6.4
[Qemu-devel] [PATCH 20/55] atapi: move GESN definitions to scsi-defs.h
From: Paolo Bonzini pbonz...@redhat.com As a complement to the previous patch, move definitions for GET EVENT STATUS NOTIFICATION from the two functions to scsi-defs.h. The NCR_* constants are just bit values corresponding to the ENC_* values, with no offsets even, so keep just one copy. Signed-off-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Kevin Wolf kw...@redhat.com --- hw/ide/atapi.c | 43 ++- hw/scsi-defs.h | 21 + 2 files changed, 27 insertions(+), 37 deletions(-) diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c index be3b728..347c38d 100644 --- a/hw/ide/atapi.c +++ b/hw/ide/atapi.c @@ -505,19 +505,6 @@ static int ide_dvd_read_structure(IDEState *s, int format, static unsigned int event_status_media(IDEState *s, uint8_t *buf) { -enum media_event_code { -MEC_NO_CHANGE = 0, /* Status unchanged */ -MEC_EJECT_REQUESTED, /* received a request from user to eject */ -MEC_NEW_MEDIA, /* new media inserted and ready for access */ -MEC_MEDIA_REMOVAL, /* only for media changers */ -MEC_MEDIA_CHANGED, /* only for media changers */ -MEC_BG_FORMAT_COMPLETED, /* MRW or DVD+RW b/g format completed */ -MEC_BG_FORMAT_RESTARTED, /* MRW or DVD+RW b/g format restarted */ -}; -enum media_status { -MS_TRAY_OPEN = 1, -MS_MEDIA_PRESENT = 2, -}; uint8_t event_code, media_status; media_status = 0; @@ -564,27 +551,6 @@ static void cmd_get_event_status_notification(IDEState *s, uint8_t notification_class; uint8_t supported_events; } QEMU_PACKED *gesn_event_header; - -enum notification_class_request_type { -NCR_RESERVED1 = 1 0, -NCR_OPERATIONAL_CHANGE = 1 1, -NCR_POWER_MANAGEMENT = 1 2, -NCR_EXTERNAL_REQUEST = 1 3, -NCR_MEDIA = 1 4, -NCR_MULTI_HOST = 1 5, -NCR_DEVICE_BUSY = 1 6, -NCR_RESERVED2 = 1 7, -}; -enum event_notification_class_field { -ENC_NO_EVENTS = 0, -ENC_OPERATIONAL_CHANGE, -ENC_POWER_MANAGEMENT, -ENC_EXTERNAL_REQUEST, -ENC_MEDIA, -ENC_MULTIPLE_HOSTS, -ENC_DEVICE_BUSY, -ENC_RESERVED, -}; unsigned int max_len, used_len; gesn_cdb = (void *)packet; @@ -606,8 +572,11 @@ static void cmd_get_event_status_notification(IDEState *s, * These are the supported events. * * We currently only support requests of the 'media' type. + * Notification class requests and supported event classes are bitmasks, + * but they are build from the same values as the notification class + * field. */ -gesn_event_header-supported_events = NCR_MEDIA; +gesn_event_header-supported_events = 1 GESN_MEDIA; /* * We use |= below to set the class field; other bits in this byte @@ -621,8 +590,8 @@ static void cmd_get_event_status_notification(IDEState *s, * notification_class_request_type enum above specifies the * priority: upper elements are higher prio than lower ones. */ -if (gesn_cdb-class NCR_MEDIA) { -gesn_event_header-notification_class |= ENC_MEDIA; +if (gesn_cdb-class (1 GESN_MEDIA)) { +gesn_event_header-notification_class |= GESN_MEDIA; used_len = event_status_media(s, buf); } else { gesn_event_header-notification_class = 0x80; /* No event available */ diff --git a/hw/scsi-defs.h b/hw/scsi-defs.h index 6bb4df7..5e6c9b7 100644 --- a/hw/scsi-defs.h +++ b/hw/scsi-defs.h @@ -203,6 +203,27 @@ * of MODE_PAGE_SENSE_POWER */ #define MODE_PAGE_CDROM 0x0d +/* Event notification classes for GET EVENT STATUS NOTIFICATION */ +#define GESN_NO_EVENTS0 +#define GESN_OPERATIONAL_CHANGE 1 +#define GESN_POWER_MANAGEMENT 2 +#define GESN_EXTERNAL_REQUEST 3 +#define GESN_MEDIA4 +#define GESN_MULTIPLE_HOSTS 5 +#define GESN_DEVICE_BUSY 6 + +/* Event codes for MEDIA event status notification */ +#define MEC_NO_CHANGE 0 +#define MEC_EJECT_REQUESTED 1 +#define MEC_NEW_MEDIA 2 +#define MEC_MEDIA_REMOVAL 3 /* only for media changers */ +#define MEC_MEDIA_CHANGED 4 /* only for media changers */ +#define MEC_BG_FORMAT_COMPLETED 5 /* MRW or DVD+RW b/g format completed */ +#define MEC_BG_FORMAT_RESTARTED 6 /* MRW or DVD+RW b/g format restarted */ + +#define MS_TRAY_OPEN 1 +#define MS_MEDIA_PRESENT 2 + /* * Based on values from linux/cdrom.h but extending CD_MINS * to the maximum common size allowed by the Orange's Book ATIP -- 1.7.6.4
[Qemu-devel] [PATCH 30/55] scsi-disk: report media changed via GET EVENT STATUS NOTIFICATION
From: Paolo Bonzini pbonz...@redhat.com This adds support for media change notification via the GET EVENT STATUS NOTIFICATION command, used by Linux versions 2.6.38 and newer. Signed-off-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Kevin Wolf kw...@redhat.com --- hw/scsi-disk.c | 57 --- 1 files changed, 53 insertions(+), 4 deletions(-) diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 8f8a94d..dd2b605 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -72,6 +72,7 @@ struct SCSIDiskState uint32_t removable; uint64_t max_lba; bool media_changed; +bool media_event; QEMUBH *bh; char *version; char *serial; @@ -687,11 +688,58 @@ fail: return -1; } -static int scsi_get_event_status_notification(SCSIDiskState *s, - SCSIDiskReq *r, uint8_t *outbuf) +static int scsi_event_status_media(SCSIDiskState *s, uint8_t *outbuf) { -scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE)); -return -1; +uint8_t event_code, media_status; + +media_status = 0; +if (s-tray_open) { +media_status = MS_TRAY_OPEN; +} else if (bdrv_is_inserted(s-bs)) { +media_status = MS_MEDIA_PRESENT; +} + +/* Event notification descriptor */ +event_code = MEC_NO_CHANGE; +if (media_status != MS_TRAY_OPEN s-media_event) { +event_code = MEC_NEW_MEDIA; +s-media_event = false; +} + +outbuf[0] = event_code; +outbuf[1] = media_status; + +/* These fields are reserved, just clear them. */ +outbuf[2] = 0; +outbuf[3] = 0; +return 4; +} + +static int scsi_get_event_status_notification(SCSIDiskState *s, SCSIDiskReq *r, + uint8_t *outbuf) +{ +int size; +uint8_t *buf = r-req.cmd.buf; +uint8_t notification_class_request = buf[4]; +if (s-qdev.type != TYPE_ROM) { +return -1; +} +if ((buf[1] 1) == 0) { +/* asynchronous */ +return -1; +} + +size = 4; +outbuf[0] = outbuf[1] = 0; +outbuf[3] = 1 GESN_MEDIA; /* supported events */ +if (notification_class_request (1 GESN_MEDIA)) { +outbuf[2] = GESN_MEDIA; +size += scsi_event_status_media(s, outbuf[size]); +} else { +outbuf[2] = 0x80; +} +stw_be_p(outbuf, size - 4); +return size; } static int scsi_get_configuration(SCSIDiskState *s, uint8_t *outbuf) @@ -1442,6 +1490,7 @@ static void scsi_cd_change_media_cb(void *opaque, bool load) s-media_changed = load; s-tray_open = !load; s-qdev.unit_attention = SENSE_CODE(UNIT_ATTENTION_NO_MEDIUM); +s-media_event = true; } static bool scsi_cd_is_tray_open(void *opaque) -- 1.7.6.4
[Qemu-devel] [PATCH 23/55] scsi-disk: report media changed via unit attention sense codes
From: Paolo Bonzini pbonz...@redhat.com Building on the previous patch, this one adds a media change callback to scsi-disk. Signed-off-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Kevin Wolf kw...@redhat.com --- hw/scsi-bus.c |5 + hw/scsi-disk.c | 29 - hw/scsi.h |2 ++ 3 files changed, 35 insertions(+), 1 deletions(-) diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index c190509..867b1a8 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -847,6 +847,11 @@ const struct SCSISense sense_code_RESET = { .key = UNIT_ATTENTION, .asc = 0x29, .ascq = 0x00 }; +/* Unit attention, No medium */ +const struct SCSISense sense_code_UNIT_ATTENTION_NO_MEDIUM = { +.key = UNIT_ATTENTION, .asc = 0x3a, .ascq = 0x00 +}; + /* Unit attention, Medium may have changed */ const struct SCSISense sense_code_MEDIUM_CHANGED = { .key = UNIT_ATTENTION, .asc = 0x28, .ascq = 0x00 diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index a6ef060..880cb22 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -71,6 +71,7 @@ struct SCSIDiskState int cluster_size; uint32_t removable; uint64_t max_lba; +bool media_changed; QEMUBH *bh; char *version; char *serial; @@ -1198,7 +1199,21 @@ static void scsi_destroy(SCSIDevice *dev) static void scsi_cd_change_media_cb(void *opaque, bool load) { -((SCSIDiskState *)opaque)-tray_open = !load; +SCSIDiskState *s = opaque; + +/* + * When a CD gets changed, we have to report an ejected state and + * then a loaded state to guests so that they detect tray + * open/close and media change events. Guests that do not use + * GET_EVENT_STATUS_NOTIFICATION to detect such tray open/close + * states rely on this behavior. + * + * media_changed governs the state machine used for unit attention + * report. media_event is used by GET EVENT STATUS NOTIFICATION. + */ +s-media_changed = load; +s-tray_open = !load; +s-qdev.unit_attention = SENSE_CODE(UNIT_ATTENTION_NO_MEDIUM); } static bool scsi_cd_is_tray_open(void *opaque) @@ -1217,6 +1232,15 @@ static const BlockDevOps scsi_cd_block_ops = { .is_medium_locked = scsi_cd_is_medium_locked, }; +static void scsi_disk_unit_attention_reported(SCSIDevice *dev) +{ +SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); +if (s-media_changed) { +s-media_changed = false; +s-qdev.unit_attention = SENSE_CODE(MEDIUM_CHANGED); +} +} + static int scsi_initfn(SCSIDevice *dev, uint8_t scsi_type) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); @@ -1329,6 +1353,7 @@ static SCSIDeviceInfo scsi_disk_info[] = { .init = scsi_hd_initfn, .destroy = scsi_destroy, .alloc_req= scsi_new_request, +.unit_attention_reported = scsi_disk_unit_attention_reported, .qdev.props = (Property[]) { DEFINE_SCSI_DISK_PROPERTIES(), DEFINE_PROP_BIT(removable, SCSIDiskState, removable, 0, false), @@ -1343,6 +1368,7 @@ static SCSIDeviceInfo scsi_disk_info[] = { .init = scsi_cd_initfn, .destroy = scsi_destroy, .alloc_req= scsi_new_request, +.unit_attention_reported = scsi_disk_unit_attention_reported, .qdev.props = (Property[]) { DEFINE_SCSI_DISK_PROPERTIES(), DEFINE_PROP_END_OF_LIST(), @@ -1356,6 +1382,7 @@ static SCSIDeviceInfo scsi_disk_info[] = { .init = scsi_disk_initfn, .destroy = scsi_destroy, .alloc_req= scsi_new_request, +.unit_attention_reported = scsi_disk_unit_attention_reported, .qdev.props = (Property[]) { DEFINE_SCSI_DISK_PROPERTIES(), DEFINE_PROP_BIT(removable, SCSIDiskState, removable, 0, false), diff --git a/hw/scsi.h b/hw/scsi.h index 6d40b8e..7004aaa 100644 --- a/hw/scsi.h +++ b/hw/scsi.h @@ -161,6 +161,8 @@ extern const struct SCSISense sense_code_IO_ERROR; extern const struct SCSISense sense_code_I_T_NEXUS_LOSS; /* Command aborted, Logical Unit failure */ extern const struct SCSISense sense_code_LUN_FAILURE; +/* LUN not ready, Medium not present */ +extern const struct SCSISense sense_code_UNIT_ATTENTION_NO_MEDIUM; /* Unit attention, Power on, reset or bus device reset occurred */ extern const struct SCSISense sense_code_RESET; /* Unit attention, Medium may have changed*/ -- 1.7.6.4
[Qemu-devel] [PATCH 45/55] scsi-disk: remove cluster_size
From: Paolo Bonzini pbonz...@redhat.com This field is redundant, and having it makes it more complicated to share reqops between the upcoming scsi-block and scsi-generic. Signed-off-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Kevin Wolf kw...@redhat.com --- hw/scsi-disk.c | 35 --- 1 files changed, 16 insertions(+), 19 deletions(-) diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 8a05031..f89e6c5 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -65,9 +65,6 @@ typedef struct SCSIDiskReq { struct SCSIDiskState { SCSIDevice qdev; -/* The qemu block layer uses a fixed 512 byte sector size. - This is the number of 512 byte blocks in a single scsi sector. */ -int cluster_size; uint32_t removable; uint64_t max_lba; bool media_changed; @@ -854,7 +851,7 @@ static int mode_sense_page(SCSIDiskState *s, int page, uint8_t **p_outbuf, bdrv_get_geometry_hint(bdrv, cylinders, heads, secs); p[4] = heads 0xff; p[5] = secs 0xff; -p[6] = s-cluster_size * 2; +p[6] = s-qdev.blocksize 8; p[8] = (cylinders 8) 0xff; p[9] = cylinders 0xff; /* Write precomp start cylinder, disabled */ @@ -983,7 +980,7 @@ static int scsi_disk_emulate_mode_sense(SCSIDiskReq *r, uint8_t *outbuf) } else { /* MODE_SENSE_10 */ outbuf[7] = 8; /* Block descriptor length */ } -nb_sectors /= s-cluster_size; +nb_sectors /= (s-qdev.blocksize / 512); if (nb_sectors 0xff) { nb_sectors = 0; } @@ -993,7 +990,7 @@ static int scsi_disk_emulate_mode_sense(SCSIDiskReq *r, uint8_t *outbuf) p[3] = nb_sectors 0xff; p[4] = 0; /* reserved */ p[5] = 0; /* bytes 5-7 are the sector size in bytes */ -p[6] = s-cluster_size * 2; +p[6] = s-qdev.blocksize 8; p[7] = 0; p += 8; } @@ -1044,7 +1041,7 @@ static int scsi_disk_emulate_read_toc(SCSIRequest *req, uint8_t *outbuf) start_track = req-cmd.buf[6]; bdrv_get_geometry(s-qdev.conf.bs, nb_sectors); DPRINTF(Read TOC (track %d format %d msf %d)\n, start_track, format, msf 1); -nb_sectors /= s-cluster_size; +nb_sectors /= s-qdev.blocksize / 512; switch (format) { case 0: toclen = cdrom_read_toc(nb_sectors, outbuf, msf, start_track); @@ -1179,7 +1176,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r) if ((req-cmd.buf[8] 1) == 0 req-cmd.lba) { goto illegal_request; } -nb_sectors /= s-cluster_size; +nb_sectors /= s-qdev.blocksize / 512; /* Returned value is the address of the last sector. */ nb_sectors--; /* Remember the new size for read/write sanity checking. */ @@ -1194,7 +1191,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r) outbuf[3] = nb_sectors 0xff; outbuf[4] = 0; outbuf[5] = 0; -outbuf[6] = s-cluster_size * 2; +outbuf[6] = s-qdev.blocksize 8; outbuf[7] = 0; buflen = 8; break; @@ -1234,7 +1231,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r) if ((req-cmd.buf[14] 1) == 0 req-cmd.lba) { goto illegal_request; } -nb_sectors /= s-cluster_size; +nb_sectors /= s-qdev.blocksize / 512; /* Returned value is the address of the last sector. */ nb_sectors--; /* Remember the new size for read/write sanity checking. */ @@ -1249,7 +1246,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r) outbuf[7] = nb_sectors 0xff; outbuf[8] = 0; outbuf[9] = 0; -outbuf[10] = s-cluster_size * 2; +outbuf[10] = s-qdev.blocksize 8; outbuf[11] = 0; outbuf[12] = 0; outbuf[13] = get_physical_block_exp(s-qdev.conf); @@ -1356,8 +1353,8 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf) if (r-req.cmd.lba s-max_lba) { goto illegal_lba; } -r-sector = r-req.cmd.lba * s-cluster_size; -r-sector_count = len * s-cluster_size; +r-sector = r-req.cmd.lba * (s-qdev.blocksize / 512); +r-sector_count = len * (s-qdev.blocksize / 512); break; case WRITE_6: case WRITE_10: @@ -1373,8 +1370,8 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf) if (r-req.cmd.lba s-max_lba) { goto illegal_lba; } -r-sector = r-req.cmd.lba * s-cluster_size; -r-sector_count = len * s-cluster_size; +r-sector = r-req.cmd.lba * (s-qdev.blocksize / 512); +r-sector_count = len * (s-qdev.blocksize / 512); break; case MODE_SELECT: DPRINTF(Mode Select(6) (len %lu)\n, (long)r-req.cmd.xfer); @@ -1417,8 +1414,9 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t
[Qemu-devel] [PATCH 01/55] iSCSI block driver
From: Ronnie Sahlberg ronniesahlb...@gmail.com This provides built-in support for iSCSI to QEMU. This has the advantage that the iSCSI devices need not be made visible to the host, which is useful if you have very many virtual machines and very many iscsi devices. It also has the benefit that non-root users of QEMU can access iSCSI devices across the network without requiring root privilege on the host. This driver interfaces with the multiplatform posix library for iscsi initiator/client access to iscsi devices hosted at git://github.com/sahlberg/libiscsi.git The patch adds the driver to interface with the iscsi library. It also updated the configure script to * by default, probe is libiscsi is available and if so, build qemu against libiscsi. * --enable-libiscsi Force a build against libiscsi. If libiscsi is not available the build will fail. * --disable-libiscsi Do not link against libiscsi, even if it is available. When linked with libiscsi, qemu gains support to access iscsi resources such as disks and cdrom directly, without having to make the devices visible to the host. You can specify devices using a iscsi url of the form : iscsi://[username[:password@]]host[:port]/target-iqn-name/lun When using authentication, the password can optionally be set with LIBISCSI_CHAP_PASSWORD=password to avoid it showing up in the process list Signed-off-by: Ronnie Sahlberg ronniesahlb...@gmail.com Reviewed-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com Signed-off-by: Kevin Wolf kw...@redhat.com --- Makefile.objs |1 + block/iscsi.c | 591 + configure | 31 +++ trace-events |6 + 4 files changed, 629 insertions(+), 0 deletions(-) create mode 100644 block/iscsi.c diff --git a/Makefile.objs b/Makefile.objs index 01587c8..d18417c 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -36,6 +36,7 @@ block-nested-y += qed-check.o block-nested-y += parallels.o nbd.o blkdebug.o sheepdog.o blkverify.o block-nested-$(CONFIG_WIN32) += raw-win32.o block-nested-$(CONFIG_POSIX) += raw-posix.o +block-nested-$(CONFIG_LIBISCSI) += iscsi.o block-nested-$(CONFIG_CURL) += curl.o block-nested-$(CONFIG_RBD) += rbd.o diff --git a/block/iscsi.c b/block/iscsi.c new file mode 100644 index 000..938c568 --- /dev/null +++ b/block/iscsi.c @@ -0,0 +1,591 @@ +/* + * QEMU Block driver for iSCSI images + * + * Copyright (c) 2010-2011 Ronnie Sahlberg ronniesahlb...@gmail.com + * + * 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 config-host.h + +#include poll.h +#include qemu-common.h +#include qemu-error.h +#include block_int.h +#include trace.h + +#include iscsi/iscsi.h +#include iscsi/scsi-lowlevel.h + + +typedef struct IscsiLun { +struct iscsi_context *iscsi; +int lun; +int block_size; +unsigned long num_blocks; +} IscsiLun; + +typedef struct IscsiAIOCB { +BlockDriverAIOCB common; +QEMUIOVector *qiov; +QEMUBH *bh; +IscsiLun *iscsilun; +struct scsi_task *task; +uint8_t *buf; +int status; +int canceled; +size_t read_size; +size_t read_offset; +} IscsiAIOCB; + +struct IscsiTask { +IscsiLun *iscsilun; +BlockDriverState *bs; +int status; +int complete; +}; + +static void +iscsi_abort_task_cb(struct iscsi_context *iscsi, int status, void *command_data, +void *private_data) +{ +} + +static void +iscsi_aio_cancel(BlockDriverAIOCB *blockacb) +{ +IscsiAIOCB *acb = (IscsiAIOCB *)blockacb; +IscsiLun *iscsilun = acb-iscsilun; + +acb-common.cb(acb-common.opaque, -ECANCELED); +acb-canceled = 1; + +/* send a task mgmt call to the target to cancel the task on the target */ +iscsi_task_mgmt_abort_task_async(iscsilun-iscsi, acb-task, + iscsi_abort_task_cb, NULL); + +/* then also cancel the task locally in libiscsi */ +iscsi_scsi_task_cancel(iscsilun-iscsi, acb-task);
Re: [Qemu-devel] [PATCH v2] trace: Add wildcard trace event support
On Mon, Oct 31, 2011 at 11:29:04AM +0800, Mark Wu wrote: A basic wildcard matching is supported in both the monitor command trace-event and the events list file. That means you can enable/disable the events having a common prefix in a batch. For example, virtio-blk trace events could be enabled using: trace-event virtio_blk_* on Signed-off-by: Mark Wu wu...@linux.vnet.ibm.com --- docs/tracing.txt |9 - net/queue.c |1 + trace/simple.c | 19 +-- trace/stderr.c | 17 - 4 files changed, 42 insertions(+), 4 deletions(-) Thanks, applied to the tracing tree: http://repo.or.cz/w/qemu/stefanha.git/shortlog/refs/heads/tracing I removed the net/queue.c hunk from the patch. Stefan
Re: [Qemu-devel] [libvirt] RFC decoupling VM NIC provisioning from VM NIC connection to backend networks
Daniel P. Berrange berra...@redhat.com writes: On Fri, Oct 28, 2011 at 04:15:41PM -0700, Sumit Naiksatam (snaiksat) wrote: Hi, In its current implementation Libvirt makes sure that the network interfaces that it passes/provision to a VM (for example to qemu[-kvm]) are already connected to its backend (interfaces/networks) by the time the VM starts its boot process. In a non virtualized setup it would be like booting a machine with the Ethernet cable already plugged into a router/switch port. While in a non virtualized setup you can boot a machine first (with no physical connection to a router/switch) and later connect its NIC/s to the switch/router, when you boot a VM via Libvirt it is not possible to decouple the two actions (VM boot, cable plug/unplug). An example of case where the capability of decoupling the two actions mentioned above is a requirement in Quantum/NetStack which is the network service leveraged by OpenStack. The modular design of OpenStack allows you to: - provision VMs with NIC/s - create networks - create ports on networks - plug/unplug a VM NIC into/from a given port on a network (at runtime) Note that this runtime plug/unplug requirement has nothing to do with hot plug/unplug of NICs. The idea is more that of decoupling the provisioning of a VM from the connection of the VM to the network/s. This would make it possible to change (at run-time too) the networks the NIC/s of a given VM are connected to. For example, when a VM boots, its interfaces should be in link down state if the network admin has not connected the VM NIC/s to any network yet. Even though libvirt already provides a way to change the link state of an a VM NIC, link state and physical connection are two different things and should be manageable independently. Ideally the configuration syntax should be interface type and hypervisor type agnostic. Let's take QEMU[-kvm] as an example - when Libvirt starts a QEMU VM, it passes to QEMU a number of file descriptors that map to host backend interfaces (for example macvtap interfaces). In order to introduce this runtime plug/unplug capability, we need a mechanism that permits to delay the binding between the host macvtap interfaces and the guest taps (because you cannot know the fd of the macvtap interfaces before you create them). This means you need a mechanism that allows you to change such fd/s at runtime: - you can close/reset an fd (ie, when you disconnect a VM NIC from its network) - you can open/set an fd (ie, when you connect a VM NIC to a network) This could probably be a libvirt command that translates to a QEMU monitor command. Can the runtime plug/unplug capability described above be achieved (cleanly) with another mechanism? Is anybody working on implementing something similar? No, but I've long thought about doing this it is quite straightforward todo really. Ordinarily when we start QEMU we do qemu ... -device e1000,id=nic0,netdev=netdevnic0 \ -netdev user,id=netdevnic0 Todo what you describe we need to be able to: 1. Start QEMU with a NIC, but no netdev 2. Add a netdev to running QEMU. 3. Remove a netdev from a running QEMU 4. Associate a netdev with a NIC in running QEMU We can do 1: $ qemu ... -device e1000,id=nic0 But QEMU prints an annoying warning Warning: nic nic0 has no peer We can do 2 via the monitor: (qemu) netdev_add type=user,id=netdevnic0 We can do 3 via the monitor: (qemu) netdev_del netdevnic0 The problem is 4 - AFAICT we can't connect the existing NIC upto the newly hotplugged netdev, since we can't update the 'netdev' property in the NIC device. Yes, that's the missing piece. Also if we delete the netdev, we can't clear out the 'netdev' property in the NIC, so its dangling to a netdev that no longer exists. Err, this sounds like we had a dangling pointer there. We don't. Until commit a083a89d, netdev_del disconnected the backend netdev from the frontend NIC (assigning null to property netdev), then deleted the netdev. Since then, we delay the actual deletion until the NIC goes away, because removing host netdev peer while guest is active leads to guest-visible inconsistency and/or crashes. I figure that needs to be fixed differently to enable dynamic network backend switching. The latter is fairly harmless, since we can just re-use the name if adding a new backend later. The first problem is a bit of a pain, unless we plug in a 'user' backend on the CLI, and immediately netdev_del it before starting the CPUs. Ideally we'd have some way to set qdev properties for devices so we can associate the NIC with the new netdev. eg when adding a netdev: (qemu) netdev_add type=user,id=netdevnic0 (qemu) set nic0 netdev=netdevnic0 Or removing one (qemu) netdev_add netdevnic0 (qemu) unset nic0 netdev Please work with Anthony to get this use case covered in QOM. WRT to
[Qemu-devel] [PATCH 18/55] scsi: pass correct sense code for ENOMEDIUM
From: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Kevin Wolf kw...@redhat.com --- hw/scsi-disk.c |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 6909578..9c62569 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -231,6 +231,9 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type) bdrv_iostatus_set_err(s-bs, error); } else { switch (error) { +case ENOMEDIUM: +scsi_check_condition(r, SENSE_CODE(NO_MEDIUM)); +break; case ENOMEM: scsi_check_condition(r, SENSE_CODE(TARGET_FAILURE)); break; -- 1.7.6.4
Re: [Qemu-devel] [PATCH] qed: adjust the way to get nb_sectors
On Mon, Oct 31, 2011 at 8:25 AM, Zhi Yong Wu zwu.ker...@gmail.com wrote: On Mon, Oct 31, 2011 at 4:10 PM, Kevin Wolf kw...@redhat.com wrote: Am 31.10.2011 04:01, schrieb Zhi Yong Wu: It is better to use qiov.size in qed-table.c to get nb_sectors than iov.iov_len. Signed-off-by: Zhi Yong Wu wu...@linux.vnet.ibm.com The commit message should probably say why it's better. Not saying otherwise, but I can't see the different at the first sight. They are equal, but if the number of iov isn't ONE, they will be not equal. qiov.size contains the sum of all iov's size while iov.iov_len is only the size of one iov. Although in current scenario, they are equal, but i think that it is better if qiov.size is used. I see your reasoning. Especially in qed_read_table_cb() it's nice to use qiov-size because that function doesn't obviously use a single struct iovec. If you want to change it I agree but please send a patch with a proper explanation that mentions that this is purely a refactoring (does not change behavior) and why. Stefan
[Qemu-devel] [PATCH 06/55] block: Fix bdrv_open use after free
tmp_filename was used outside the block it was defined in, i.e. after it went out of scope. Move its declaration to the top level. Signed-off-by: Kevin Wolf kw...@redhat.com --- block.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/block.c b/block.c index f86984f..d5ec0be 100644 --- a/block.c +++ b/block.c @@ -571,6 +571,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags, BlockDriver *drv) { int ret; +char tmp_filename[PATH_MAX]; if (flags BDRV_O_SNAPSHOT) { BlockDriverState *bs1; @@ -578,7 +579,6 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags, int is_protocol = 0; BlockDriver *bdrv_qcow2; QEMUOptionParameter *options; -char tmp_filename[PATH_MAX]; char backing_filename[PATH_MAX]; /* if snapshot, we create a temporary backing file and open it -- 1.7.6.4
[Qemu-devel] [PATCH 42/55] scsi-generic: look at host status
From: Paolo Bonzini pbonz...@redhat.com Pass down the host status so that failing transport can be detected by the guest. Similar treatment of host status could be done in virtio-blk, too. Signed-off-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Kevin Wolf kw...@redhat.com --- hw/scsi-generic.c | 20 1 files changed, 16 insertions(+), 4 deletions(-) diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c index c313749..5ad3d57 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -39,8 +39,13 @@ do { fprintf(stderr, scsi-generic: fmt , ## __VA_ARGS__); } while (0) #define SCSI_SENSE_BUF_SIZE 96 -#define SG_ERR_DRIVER_TIMEOUT 0x06 -#define SG_ERR_DRIVER_SENSE 0x08 +#define SG_ERR_DRIVER_TIMEOUT 0x06 +#define SG_ERR_DRIVER_SENSE0x08 + +#define SG_ERR_DID_OK 0x00 +#define SG_ERR_DID_NO_CONNECT 0x01 +#define SG_ERR_DID_BUS_BUSY0x02 +#define SG_ERR_DID_TIME_OUT0x03 #ifndef MAX_UINT #define MAX_UINT ((unsigned int)-1) @@ -68,8 +73,9 @@ static void scsi_command_complete(void *opaque, int ret) SCSIGenericReq *r = (SCSIGenericReq *)opaque; r-req.aiocb = NULL; -if (r-io_header.driver_status SG_ERR_DRIVER_SENSE) +if (r-io_header.driver_status SG_ERR_DRIVER_SENSE) { r-req.sense_len = r-io_header.sb_len_wr; +} if (ret != 0) { switch (ret) { @@ -86,9 +92,15 @@ static void scsi_command_complete(void *opaque, int ret) break; } } else { -if (r-io_header.driver_status SG_ERR_DRIVER_TIMEOUT) { +if (r-io_header.host_status == SG_ERR_DID_NO_CONNECT || +r-io_header.host_status == SG_ERR_DID_BUS_BUSY || +r-io_header.host_status == SG_ERR_DID_TIME_OUT || +(r-io_header.driver_status SG_ERR_DRIVER_TIMEOUT)) { status = BUSY; BADF(Driver Timeout\n); +} else if (r-io_header.host_status) { +status = CHECK_CONDITION; +scsi_req_build_sense(r-req, SENSE_CODE(I_T_NEXUS_LOSS)); } else if (r-io_header.status) { status = r-io_header.status; } else if (r-io_header.driver_status SG_ERR_DRIVER_SENSE) { -- 1.7.6.4
[Qemu-devel] [PATCH 48/55] scsi: make reqops const
From: Paolo Bonzini pbonz...@redhat.com Also delete a stale occurrence of SCSIReqOps inside SCSIDeviceInfo. Signed-off-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Kevin Wolf kw...@redhat.com --- hw/scsi-bus.c | 10 +- hw/scsi-disk.c|2 +- hw/scsi-generic.c |2 +- hw/scsi.h |7 +++ 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index bdd6e94..1f38ac8 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -160,7 +160,7 @@ static int32_t scsi_invalid_command(SCSIRequest *req, uint8_t *buf) return 0; } -struct SCSIReqOps reqops_invalid_opcode = { +static const struct SCSIReqOps reqops_invalid_opcode = { .size = sizeof(SCSIRequest), .send_command = scsi_invalid_command }; @@ -178,7 +178,7 @@ static int32_t scsi_unit_attention(SCSIRequest *req, uint8_t *buf) return 0; } -struct SCSIReqOps reqops_unit_attention = { +static const struct SCSIReqOps reqops_unit_attention = { .size = sizeof(SCSIRequest), .send_command = scsi_unit_attention }; @@ -386,7 +386,7 @@ static uint8_t *scsi_target_get_buf(SCSIRequest *req) return r-buf; } -struct SCSIReqOps reqops_target_command = { +static const struct SCSIReqOps reqops_target_command = { .size = sizeof(SCSITargetReq), .send_command = scsi_target_send_command, .read_data= scsi_target_read_data, @@ -394,8 +394,8 @@ struct SCSIReqOps reqops_target_command = { }; -SCSIRequest *scsi_req_alloc(SCSIReqOps *reqops, SCSIDevice *d, uint32_t tag, -uint32_t lun, void *hba_private) +SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, SCSIDevice *d, +uint32_t tag, uint32_t lun, void *hba_private) { SCSIRequest *req; diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 74990a8..77673f2 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -1588,7 +1588,7 @@ static int scsi_disk_initfn(SCSIDevice *dev) } } -static SCSIReqOps scsi_disk_reqops = { +static const SCSIReqOps scsi_disk_reqops = { .size = sizeof(SCSIDiskReq), .free_req = scsi_free_request, .send_command = scsi_send_command, diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c index fcf23cd..a5e77cb 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -420,7 +420,7 @@ static int scsi_generic_initfn(SCSIDevice *s) return 0; } -static SCSIReqOps scsi_generic_req_ops = { +static const SCSIReqOps scsi_generic_req_ops = { .size = sizeof(SCSIGenericReq), .free_req = scsi_free_request, .send_command = scsi_send_command, diff --git a/hw/scsi.h b/hw/scsi.h index d56e875..af558c3 100644 --- a/hw/scsi.h +++ b/hw/scsi.h @@ -41,7 +41,7 @@ struct SCSICommand { struct SCSIRequest { SCSIBus *bus; SCSIDevice*dev; -SCSIReqOps*ops; +const SCSIReqOps *ops; uint32_t refcount; uint32_t tag; uint32_t lun; @@ -96,7 +96,6 @@ struct SCSIDeviceInfo { SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun, void *hba_private); void (*unit_attention_reported)(SCSIDevice *s); -SCSIReqOps reqops; }; struct SCSIBusInfo { @@ -176,8 +175,8 @@ extern const struct SCSISense sense_code_DEVICE_INTERNAL_RESET; int scsi_sense_valid(SCSISense sense); -SCSIRequest *scsi_req_alloc(SCSIReqOps *reqops, SCSIDevice *d, uint32_t tag, -uint32_t lun, void *hba_private); +SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, SCSIDevice *d, +uint32_t tag, uint32_t lun, void *hba_private); SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun, uint8_t *buf, void *hba_private); int32_t scsi_req_enqueue(SCSIRequest *req); -- 1.7.6.4
[Qemu-devel] [PATCH 33/55] scsi: remove devs array from SCSIBus
From: Paolo Bonzini pbonz...@redhat.com Change the devs array into a linked list, and add a scsi_device_find function to navigate the children list instead. This lets the SCSI bus use more complex addressing, and HBAs can talk to the correct device when there are multiple LUNs per target. scsi_device_find may return another LUN on the same target if none is found that matches exactly. Signed-off-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Kevin Wolf kw...@redhat.com --- hw/esp.c |8 +--- hw/lsi53c895a.c | 22 +++--- hw/qdev.h|2 +- hw/scsi-bus.c| 53 ++--- hw/scsi.h|3 +-- hw/spapr_vscsi.c | 14 ++ 6 files changed, 50 insertions(+), 52 deletions(-) diff --git a/hw/esp.c b/hw/esp.c index d3fb1c6..aad290f 100644 --- a/hw/esp.c +++ b/hw/esp.c @@ -217,7 +217,8 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf) s-async_len = 0; } -if (target = ESP_MAX_DEVS || !s-bus.devs[target]) { +s-current_dev = scsi_device_find(s-bus, target, 0); +if (!s-current_dev) { // No such drive s-rregs[ESP_RSTAT] = 0; s-rregs[ESP_RINTR] = INTR_DC; @@ -225,7 +226,6 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf) esp_raise_irq(s); return 0; } -s-current_dev = s-bus.devs[target]; return dmalen; } @@ -233,10 +233,12 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid) { int32_t datalen; int lun; +SCSIDevice *current_lun; trace_esp_do_busid_cmd(busid); lun = busid 7; -s-current_req = scsi_req_new(s-current_dev, 0, lun, buf, NULL); +current_lun = scsi_device_find(s-bus, s-current_dev-id, lun); +s-current_req = scsi_req_new(current_lun, 0, lun, buf, NULL); datalen = scsi_req_enqueue(s-current_req); s-ti_size = datalen; if (datalen != 0) { diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c index 4eeb496..c15f167 100644 --- a/hw/lsi53c895a.c +++ b/hw/lsi53c895a.c @@ -531,7 +531,7 @@ static void lsi_bad_selection(LSIState *s, uint32_t id) /* Initiate a SCSI layer data transfer. */ static void lsi_do_dma(LSIState *s, int out) { -uint32_t count, id; +uint32_t count; target_phys_addr_t addr; SCSIDevice *dev; @@ -542,12 +542,8 @@ static void lsi_do_dma(LSIState *s, int out) return; } -id = (s-current-tag 8) 0xf; -dev = s-bus.devs[id]; -if (!dev) { -lsi_bad_selection(s, id); -return; -} +dev = s-current-req-dev; +assert(dev); count = s-dbc; if (count s-current-dma_len) @@ -771,7 +767,7 @@ static void lsi_do_command(LSIState *s) s-command_complete = 0; id = (s-select_tag 8) 0xf; -dev = s-bus.devs[id]; +dev = scsi_device_find(s-bus, id, s-current_lun); if (!dev) { lsi_bad_selection(s, id); return; @@ -1202,7 +1198,7 @@ again: } s-sstat0 |= LSI_SSTAT0_WOA; s-scntl1 = ~LSI_SCNTL1_IARB; -if (id = LSI_MAX_DEVS || !s-bus.devs[id]) { +if (!scsi_device_find(s-bus, id, 0)) { lsi_bad_selection(s, id); break; } @@ -1684,13 +1680,9 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val) if (val LSI_SCNTL1_RST) { if (!(s-sstat0 LSI_SSTAT0_RST)) { DeviceState *dev; -int id; -for (id = 0; id LSI_MAX_DEVS; id++) { -if (s-bus.devs[id]) { -dev = s-bus.devs[id]-qdev; -dev-info-reset(dev); -} +QTAILQ_FOREACH(dev, s-bus.qbus.children, sibling) { +dev-info-reset(dev); } s-sstat0 |= LSI_SSTAT0_RST; lsi_script_scsi_interrupt(s, LSI_SIST0_RST, 0); diff --git a/hw/qdev.h b/hw/qdev.h index a7cc48b..36a4198 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -73,7 +73,7 @@ struct BusState { const char *name; int allow_hotplug; int qdev_allocated; -QTAILQ_HEAD(, DeviceState) children; +QTAILQ_HEAD(ChildrenHead, DeviceState) children; QLIST_ENTRY(BusState) sibling; }; diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index d9d4e18..7104e98 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -37,12 +37,16 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base) SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev); SCSIDeviceInfo *info = DO_UPCAST(SCSIDeviceInfo, qdev, base); SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev-qdev.parent_bus); +SCSIDevice *olddev; int rc = -1; if (dev-id == -1) { -for (dev-id = 0; dev-id bus-info-ndev; dev-id++) { -if (bus-devs[dev-id] == NULL) +int id; +for (id = 0; id bus-info-ndev; id++) { +if
[Qemu-devel] [PATCH 37/55] scsi-disk: fail READ CAPACITY if LBA != 0 but PMI == 0
From: Paolo Bonzini pbonz...@redhat.com Tested by the Windows Logo Kit SCSI Compliance test. From SBC-3, paragraph 5.25: The LOGICAL BLOCK ADDRESS field shall be set to zero if the PMI bit is set to zero. If the PMI bit is set to zero and the LOGICAL BLOCK ADDRESS field is not set to zero, then the device server shall terminate the command with CHECK CONDITION status with the sense key set to ILLEGAL REQUEST and the additional sense code set to INVALID FIELD IN CDB. Signed-off-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Kevin Wolf kw...@redhat.com --- hw/scsi-disk.c |6 ++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 50fc3d6..6b139ac 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -1180,6 +1180,9 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r) if (!nb_sectors) { goto not_ready; } +if ((req-cmd.buf[8] 1) == 0 req-cmd.lba) { +goto illegal_request; +} nb_sectors /= s-cluster_size; /* Returned value is the address of the last sector. */ nb_sectors--; @@ -1232,6 +1235,9 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r) if (!nb_sectors) { goto not_ready; } +if ((req-cmd.buf[14] 1) == 0 req-cmd.lba) { +goto illegal_request; +} nb_sectors /= s-cluster_size; /* Returned value is the address of the last sector. */ nb_sectors--; -- 1.7.6.4
Re: [Qemu-devel] 1.0 Hard Freeze Logistics
On Mon, Oct 31, 2011 at 1:28 PM, Anthony Liguori aligu...@us.ibm.com wrote: To make the Test Day more successful, please sign up to test a specific area on the Test[3] wiki page. [...] [3] http://wiki.qemu.org/Planning/1.0/Testing I just signed up for several block and tracing tests and encourage everyone to get involved. If you're looking for something to do you can test CD-ROM support. Both host CD-ROM passthrough (/dev/cdrom) and ISO CD-ROM need testing, especially media change (eject and changing the CD-ROM). There have been many code changes in the area and we need to make sure things are working correctly :). Stefan
[Qemu-devel] [PATCH 53/55] scsi-generic: bump SCSIRequest reference count until aio completion runs
From: Paolo Bonzini pbonz...@redhat.com Same as before, but for scsi-generic. Signed-off-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Kevin Wolf kw...@redhat.com --- hw/scsi-generic.c | 18 ++ 1 files changed, 18 insertions(+), 0 deletions(-) diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c index 2f95f2d..9594cc1 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -113,6 +113,9 @@ static void scsi_command_complete(void *opaque, int ret) r, r-req.tag, status); scsi_req_complete(r-req, status); +if (!r-req.io_canceled) { +scsi_req_unref(r-req); +} } /* Cancel a pending data transfer. */ @@ -123,6 +126,11 @@ static void scsi_cancel_io(SCSIRequest *req) DPRINTF(Cancel tag=0x%x\n, req-tag); if (r-req.aiocb) { bdrv_aio_cancel(r-req.aiocb); + +/* This reference was left in by scsi_*_data. We take ownership of + * it independent of whether bdrv_aio_cancel completes the request + * or not. */ +scsi_req_unref(r-req); } r-req.aiocb = NULL; } @@ -183,6 +191,9 @@ static void scsi_read_complete(void * opaque, int ret) bdrv_set_buffer_alignment(s-conf.bs, s-blocksize); scsi_req_data(r-req, len); +if (!r-req.io_canceled) { +scsi_req_unref(r-req); +} } } @@ -194,6 +205,9 @@ static void scsi_read_data(SCSIRequest *req) int ret; DPRINTF(scsi_read_data 0x%x\n, req-tag); + +/* The request is used as the AIO opaque value, so add a ref. */ +scsi_req_ref(r-req); if (r-len == -1) { scsi_command_complete(r, 0); return; @@ -242,6 +256,8 @@ static void scsi_write_data(SCSIRequest *req) return; } +/* The request is used as the AIO opaque value, so add a ref. */ +scsi_req_ref(r-req); ret = execute_command(s-conf.bs, r, SG_DXFER_TO_DEV, scsi_write_complete); if (ret 0) { scsi_command_complete(r, ret); @@ -285,6 +301,8 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd) g_free(r-buf); r-buflen = 0; r-buf = NULL; +/* The request is used as the AIO opaque value, so add a ref. */ +scsi_req_ref(r-req); ret = execute_command(s-conf.bs, r, SG_DXFER_NONE, scsi_command_complete); if (ret 0) { scsi_command_complete(r, ret); -- 1.7.6.4
[Qemu-devel] [PATCH 27/55] atapi/scsi-disk: make mode page values coherent between the two
From: Paolo Bonzini pbonz...@redhat.com This patch adds to scsi-disk the missing mode page 0x01 for both disk and CD-ROM drives, and mode page 0x0e for CD drives only. A few offsets were wrong in atapi.c. Also change the 2Ah mode page to expose DVD media read capabilities in the IDE cdrom. This lets you run dvd+rw-mediainfo on the virtual DVD drives. Signed-off-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Kevin Wolf kw...@redhat.com --- hw/ide/atapi.c | 14 +++--- hw/scsi-disk.c | 33 - 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c index e898da2..90b6729 100644 --- a/hw/ide/atapi.c +++ b/hw/ide/atapi.c @@ -751,7 +751,7 @@ static void cmd_mode_sense(IDEState *s, uint8_t *buf) buf[8] = MODE_PAGE_CAPABILITIES; buf[9] = 28 - 10; -buf[10] = 0x00; +buf[10] = 0x3b; /* read CDR/CDRW/DVDROM/DVDR/DVDRAM */ buf[11] = 0x00; /* Claim PLAY_AUDIO capability (0x01) since some Linux @@ -760,14 +760,14 @@ static void cmd_mode_sense(IDEState *s, uint8_t *buf) buf[13] = 3 5; buf[14] = (1 0) | (1 3) | (1 5); if (s-tray_locked) { -buf[6] |= 1 1; +buf[14] |= 1 1; } -buf[15] = 0x00; -cpu_to_ube16(buf[16], 706); -buf[18] = 0; +buf[15] = 0x00; /* No volume mute control, no changer */ +cpu_to_ube16(buf[16], 704); /* 4x read speed */ +buf[18] = 0; /* Two volume levels */ buf[19] = 2; -cpu_to_ube16(buf[20], 512); -cpu_to_ube16(buf[22], 706); +cpu_to_ube16(buf[20], 512); /* 512k buffer */ +cpu_to_ube16(buf[22], 704); /* 4x read speed current */ buf[24] = 0; buf[25] = 0; buf[26] = 0; diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 8f3ada6..116e562 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -611,6 +611,8 @@ static int mode_sense_page(SCSIDiskState *s, int page, uint8_t **p_outbuf, [MODE_PAGE_HD_GEOMETRY]= (1 TYPE_DISK), [MODE_PAGE_FLEXIBLE_DISK_GEOMETRY] = (1 TYPE_DISK), [MODE_PAGE_CACHING]= (1 TYPE_DISK) | (1 TYPE_ROM), +[MODE_PAGE_R_W_ERROR] = (1 TYPE_DISK) | (1 TYPE_ROM), +[MODE_PAGE_AUDIO_CTL] = (1 TYPE_ROM), [MODE_PAGE_CAPABILITIES] = (1 TYPE_ROM), }; @@ -711,13 +713,26 @@ static int mode_sense_page(SCSIDiskState *s, int page, uint8_t **p_outbuf, } break; +case MODE_PAGE_R_W_ERROR: +p[1] = 10; +p[2] = 0x80; /* Automatic Write Reallocation Enabled */ +if (s-qdev.type == TYPE_ROM) { +p[3] = 0x20; /* Read Retry Count */ +} +break; + +case MODE_PAGE_AUDIO_CTL: +p[1] = 14; +break; + case MODE_PAGE_CAPABILITIES: p[1] = 0x14; if (page_control == 1) { /* Changeable Values */ break; } -p[2] = 3; // CD-R CD-RW read -p[3] = 0; // Writing not supported + +p[2] = 0x3b; /* CD-R CD-RW read */ +p[3] = 0; /* Writing not supported */ p[4] = 0x7f; /* Audio, composite, digital out, mode 2 form 12, multi session */ p[5] = 0xff; /* CD DA, DA accurate, RW supported, @@ -727,17 +742,17 @@ static int mode_sense_page(SCSIDiskState *s, int page, uint8_t **p_outbuf, /* Locking supported, jumper present, eject, tray */ p[7] = 0; /* no volume mute control, no changer */ -p[8] = (50 * 176) 8; // 50x read speed +p[8] = (50 * 176) 8; /* 50x read speed */ p[9] = (50 * 176) 0xff; -p[10] = 0 8; // No volume -p[11] = 0 0xff; -p[12] = 2048 8; // 2M buffer +p[10] = 2 8; /* Two volume levels */ +p[11] = 2 0xff; +p[12] = 2048 8; /* 2M buffer */ p[13] = 2048 0xff; -p[14] = (16 * 176) 8; // 16x read speed current +p[14] = (16 * 176) 8; /* 16x read speed current */ p[15] = (16 * 176) 0xff; -p[18] = (16 * 176) 8; // 16x write speed +p[18] = (16 * 176) 8; /* 16x write speed */ p[19] = (16 * 176) 0xff; -p[20] = (16 * 176) 8; // 16x write speed current +p[20] = (16 * 176) 8; /* 16x write speed current */ p[21] = (16 * 176) 0xff; break; -- 1.7.6.4
[Qemu-devel] [PATCH 03/55] Teach block/vdi about discarded (no longer allocated) blocks
From: Eric Sunshine sunsh...@sunshineco.com An entry in the VDI block map will hold an offset to the actual block if the block is allocated, or one of two specially-interpreted values if not allocated. Using VirtualBox terminology, value VDI_IMAGE_BLOCK_FREE (0x) represents a never-allocated block (semantically arbitrary content). VDI_IMAGE_BLOCK_ZERO (0xfffe) represents a discarded block (semantically zero-filled). block/vdi knows only about VDI_IMAGE_BLOCK_FREE. Teach it about VDI_IMAGE_BLOCK_ZERO. Signed-off-by: Eric Sunshine sunsh...@sunshineco.com Signed-off-by: Kevin Wolf kw...@redhat.com --- block/vdi.c | 23 ++- 1 files changed, 14 insertions(+), 9 deletions(-) diff --git a/block/vdi.c b/block/vdi.c index 883046d..523a640 100644 --- a/block/vdi.c +++ b/block/vdi.c @@ -114,8 +114,13 @@ void uuid_unparse(const uuid_t uu, char *out); */ #define VDI_TEXT QEMU VM Virtual Disk Image \n -/* Unallocated blocks use this index (no need to convert endianness). */ -#define VDI_UNALLOCATED UINT32_MAX +/* A never-allocated block; semantically arbitrary content. */ +#define VDI_UNALLOCATED 0xU + +/* A discarded (no longer allocated) block; semantically zero-filled. */ +#define VDI_DISCARDED 0xfffeU + +#define VDI_IS_ALLOCATED(X) ((X) VDI_DISCARDED) #if !defined(CONFIG_UUID) void uuid_generate(uuid_t out) @@ -307,10 +312,10 @@ static int vdi_check(BlockDriverState *bs, BdrvCheckResult *res) /* Check block map and value of blocks_allocated. */ for (block = 0; block s-header.blocks_in_image; block++) { uint32_t bmap_entry = le32_to_cpu(s-bmap[block]); -if (bmap_entry != VDI_UNALLOCATED) { +if (VDI_IS_ALLOCATED(bmap_entry)) { if (bmap_entry s-header.blocks_in_image) { blocks_allocated++; -if (bmap[bmap_entry] == VDI_UNALLOCATED) { +if (!VDI_IS_ALLOCATED(bmap[bmap_entry])) { bmap[bmap_entry] = bmap_entry; } else { fprintf(stderr, ERROR: block index % PRIu32 @@ -472,7 +477,7 @@ static int vdi_is_allocated(BlockDriverState *bs, int64_t sector_num, n_sectors = nb_sectors; } *pnum = n_sectors; -return bmap_entry != VDI_UNALLOCATED; +return VDI_IS_ALLOCATED(bmap_entry); } static void vdi_aio_cancel(BlockDriverAIOCB *blockacb) @@ -603,7 +608,7 @@ static void vdi_aio_read_cb(void *opaque, int ret) /* prepare next AIO request */ acb-n_sectors = n_sectors; bmap_entry = le32_to_cpu(s-bmap[block_index]); -if (bmap_entry == VDI_UNALLOCATED) { +if (!VDI_IS_ALLOCATED(bmap_entry)) { /* Block not allocated, return zeros, no need to wait. */ memset(acb-buf, 0, n_sectors * SECTOR_SIZE); ret = vdi_schedule_bh(vdi_aio_rw_bh, acb); @@ -685,7 +690,7 @@ static void vdi_aio_write_cb(void *opaque, int ret) if (acb-header_modified) { VdiHeader *header = acb-block_buffer; logout(now writing modified header\n); -assert(acb-bmap_first != VDI_UNALLOCATED); +assert(VDI_IS_ALLOCATED(acb-bmap_first)); *header = s-header; vdi_header_to_le(header); acb-header_modified = 0; @@ -699,7 +704,7 @@ static void vdi_aio_write_cb(void *opaque, int ret) goto done; } return; -} else if (acb-bmap_first != VDI_UNALLOCATED) { +} else if (VDI_IS_ALLOCATED(acb-bmap_first)) { /* One or more new blocks were allocated. */ uint64_t offset; uint32_t bmap_first; @@ -749,7 +754,7 @@ static void vdi_aio_write_cb(void *opaque, int ret) /* prepare next AIO request */ acb-n_sectors = n_sectors; bmap_entry = le32_to_cpu(s-bmap[block_index]); -if (bmap_entry == VDI_UNALLOCATED) { +if (!VDI_IS_ALLOCATED(bmap_entry)) { /* Allocate new block and write to it. */ uint64_t offset; uint8_t *block; -- 1.7.6.4
[Qemu-devel] [PATCH 49/55] scsi: export scsi_generic_reqops
From: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Kevin Wolf kw...@redhat.com --- hw/scsi-generic.c |2 +- hw/scsi.h |3 +++ 2 files changed, 4 insertions(+), 1 deletions(-) diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c index a5e77cb..32f50cd 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -420,7 +420,7 @@ static int scsi_generic_initfn(SCSIDevice *s) return 0; } -static const SCSIReqOps scsi_generic_req_ops = { +const SCSIReqOps scsi_generic_req_ops = { .size = sizeof(SCSIGenericReq), .free_req = scsi_free_request, .send_command = scsi_send_command, diff --git a/hw/scsi.h b/hw/scsi.h index af558c3..01c6655 100644 --- a/hw/scsi.h +++ b/hw/scsi.h @@ -197,4 +197,7 @@ void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense); int scsi_device_get_sense(SCSIDevice *dev, uint8_t *buf, int len, bool fixed); SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int target, int lun); +/* scsi-generic.c. */ +extern const SCSIReqOps scsi_generic_req_ops; + #endif -- 1.7.6.4
[Qemu-devel] [PATCH 28/55] scsi-disk: support DVD profile in GET CONFIGURATION
From: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Kevin Wolf kw...@redhat.com --- hw/scsi-disk.c | 50 ++ 1 files changed, 42 insertions(+), 8 deletions(-) diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 116e562..38b196b 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -567,6 +567,19 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) return buflen; } +static inline bool media_is_dvd(SCSIDiskState *s) +{ +uint64_t nb_sectors; +if (s-qdev.type != TYPE_ROM) { +return false; +} +if (!bdrv_is_inserted(s-bs)) { +return false; +} +bdrv_get_geometry(s-bs, nb_sectors); +return nb_sectors CD_MAX_SECTORS; +} + static int scsi_read_dvd_structure(SCSIDiskState *s, SCSIDiskReq *r, uint8_t *outbuf) { @@ -581,17 +594,38 @@ static int scsi_get_event_status_notification(SCSIDiskState *s, return -1; } -static int scsi_get_configuration(SCSIDiskState *s, SCSIDiskReq *r, - uint8_t *outbuf) +static int scsi_get_configuration(SCSIDiskState *s, uint8_t *outbuf) { +int current; + if (s-qdev.type != TYPE_ROM) { return -1; } -memset(outbuf, 0, 8); -/* ??? This should probably return much more information. For now - just return the basic header indicating the CD-ROM profile. */ -outbuf[7] = 8; /* CD-ROM */ -return 8; +current = media_is_dvd(s) ? MMC_PROFILE_DVD_ROM : MMC_PROFILE_CD_ROM; +memset(outbuf, 0, 40); +stl_be_p(outbuf[0], 36); /* Bytes after the data length field */ +stw_be_p(outbuf[6], current); +/* outbuf[8] - outbuf[19]: Feature 0 - Profile list */ +outbuf[10] = 0x03; /* persistent, current */ +outbuf[11] = 8; /* two profiles */ +stw_be_p(outbuf[12], MMC_PROFILE_DVD_ROM); +outbuf[14] = (current == MMC_PROFILE_DVD_ROM); +stw_be_p(outbuf[16], MMC_PROFILE_CD_ROM); +outbuf[18] = (current == MMC_PROFILE_CD_ROM); +/* outbuf[20] - outbuf[31]: Feature 1 - Core feature */ +stw_be_p(outbuf[20], 1); +outbuf[22] = 0x08 | 0x03; /* version 2, persistent, current */ +outbuf[23] = 8; +stl_be_p(outbuf[24], 1); /* SCSI */ +outbuf[28] = 1; /* DBE = 1, mandatory */ +/* outbuf[32] - outbuf[39]: Feature 3 - Removable media feature */ +stw_be_p(outbuf[32], 3); +outbuf[34] = 0x08 | 0x03; /* version 2, persistent, current */ +outbuf[35] = 4; +outbuf[36] = 0x39; /* tray, load=1, eject=1, unlocked at powerup, lock=1 */ +/* TODO: Random readable, CD read, DVD read, drive serial number, + power management */ +return 40; } static int scsi_emulate_mechanism_status(SCSIDiskState *s, uint8_t *outbuf) @@ -1024,7 +1058,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r) } break; case GET_CONFIGURATION: -buflen = scsi_get_configuration(s, r, outbuf); +buflen = scsi_get_configuration(s, outbuf); if (buflen 0) { goto illegal_request; } -- 1.7.6.4
[Qemu-devel] [PATCH 17/55] Documentation: Add syntax for using sheepdog devices
From: Ronnie Sahlberg ronniesahlb...@gmail.com Signed-off-by: Ronnie Sahlberg ronniesahlb...@gmail.com Signed-off-by: Kevin Wolf kw...@redhat.com --- qemu-options.hx | 27 +++ 1 files changed, 27 insertions(+), 0 deletions(-) diff --git a/qemu-options.hx b/qemu-options.hx index c55080c..8be6f4b 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1778,6 +1778,33 @@ Example for Unix Domain Sockets qemu --drive file=nbd:unix:/tmp/nbd-socket @end example +@item Sheepdog +Sheepdog is a distributed storage system for QEMU. +QEMU supports using either local sheepdog devices or remote networked +devices. + +Syntax for specifying a sheepdog device +@table @list +``sheepdog:vdiname'' + +``sheepdog:vdiname:snapid'' + +``sheepdog:vdiname:tag'' + +``sheepdog:host:port:vdiname'' + +``sheepdog:host:port:vdiname:snapid'' + +``sheepdog:host:port:vdiname:tag'' +@end table + +Example +@example +qemu --drive file=sheepdog:192.0.2.1:3:MyVirtualMachine +@end example + +See also @url{http://http://www.osrg.net/sheepdog/}. + @end table ETEXI -- 1.7.6.4
[Qemu-devel] [PATCH 12/55] Documentation: Describe NBD URL syntax
From: Ronnie Sahlberg ronniesahlb...@gmail.com This patch adds a short description of how to specify a NBD device to QEMU. Syntax for both TCP and Unix Domain Sockets are provided as well as examples. Signed-off-by: Ronnie Sahlberg ronniesahlb...@gmail.com Signed-off-by: Kevin Wolf kw...@redhat.com --- qemu-options.hx | 21 + 1 files changed, 21 insertions(+), 0 deletions(-) diff --git a/qemu-options.hx b/qemu-options.hx index 424bae9..c55080c 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1757,6 +1757,27 @@ qemu --drive file=iscsi://192.0.2.1/iqn.2001-04.com.example/1 iSCSI support is an optional feature of QEMU and only available when compiled and linked against libiscsi. +@item NBD +QEMU supports NBD (Network Block Devices) both using TCP protocol as well +as Unix Domain Sockets. + +Syntax for specifying a NBD device using TCP +``nbd:server-ip:port[:exportname=export]'' + +Syntax for specifying a NBD device using Unix Domain Sockets +``nbd:unix:domain-socket[:exportname=export]'' + + +Example for TCP +@example +qemu --drive file=nbd:192.0.2.1:3 +@end example + +Example for Unix Domain Sockets +@example +qemu --drive file=nbd:unix:/tmp/nbd-socket +@end example + @end table ETEXI -- 1.7.6.4
[Qemu-devel] [PATCH 54/55] scsi: push request restart to SCSIDevice
From: Paolo Bonzini pbonz...@redhat.com The request restart mechanism is generic and could be reused for scsi-generic. In the meanwhile, pushing it to SCSIDevice avoids that scsi_dma_restart_bh looks at SCSIGenericReqs when working on a scsi-block device. The code is the same that is already in hw/scsi-disk.c, with the type flags replaced by req-cmd.mode and a more generic way to requeue SCSI_XFER_NONE commands. I also added a missing call to qemu_del_vm_change_state_handler. Signed-off-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Kevin Wolf kw...@redhat.com --- hw/scsi-bus.c | 56 + hw/scsi-disk.c | 76 +-- hw/scsi.h |5 +++ 3 files changed, 68 insertions(+), 69 deletions(-) diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index dfce5fb..e6ebbd5 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -8,6 +8,7 @@ static char *scsibus_get_fw_dev_path(DeviceState *dev); static int scsi_req_parse(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf); +static void scsi_req_dequeue(SCSIRequest *req); static int scsi_build_sense(uint8_t *in_buf, int in_len, uint8_t *buf, int len, bool fixed); @@ -33,6 +34,53 @@ void scsi_bus_new(SCSIBus *bus, DeviceState *host, const SCSIBusInfo *info) bus-qbus.allow_hotplug = 1; } +static void scsi_dma_restart_bh(void *opaque) +{ +SCSIDevice *s = opaque; +SCSIRequest *req, *next; + +qemu_bh_delete(s-bh); +s-bh = NULL; + +QTAILQ_FOREACH_SAFE(req, s-requests, next, next) { +scsi_req_ref(req); +if (req-retry) { +req-retry = false; +switch (req-cmd.mode) { +case SCSI_XFER_FROM_DEV: +case SCSI_XFER_TO_DEV: +scsi_req_continue(req); +break; +case SCSI_XFER_NONE: +scsi_req_dequeue(req); +scsi_req_enqueue(req); +break; +} +} +scsi_req_unref(req); +} +} + +void scsi_req_retry(SCSIRequest *req) +{ +/* No need to save a reference, because scsi_dma_restart_bh just + * looks at the request list. */ +req-retry = true; +} + +static void scsi_dma_restart_cb(void *opaque, int running, RunState state) +{ +SCSIDevice *s = opaque; + +if (!running) { +return; +} +if (!s-bh) { +s-bh = qemu_bh_new(scsi_dma_restart_bh, s); +qemu_bh_schedule(s-bh); +} +} + static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base) { SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev); @@ -83,6 +131,10 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base) dev-info = info; QTAILQ_INIT(dev-requests); rc = dev-info-init(dev); +if (rc == 0) { +dev-vmsentry = qemu_add_vm_change_state_handler(scsi_dma_restart_cb, + dev); +} err: return rc; @@ -92,6 +144,9 @@ static int scsi_qdev_exit(DeviceState *qdev) { SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev); +if (dev-vmsentry) { +qemu_del_vm_change_state_handler(dev-vmsentry); +} if (dev-info-destroy) { dev-info-destroy(dev); } @@ -586,6 +641,7 @@ int32_t scsi_req_enqueue(SCSIRequest *req) static void scsi_req_dequeue(SCSIRequest *req) { trace_scsi_req_dequeue(req-dev-id, req-lun, req-tag); +req-retry = false; if (req-enqueued) { QTAILQ_REMOVE(req-dev-requests, req, next); req-enqueued = false; diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index bb07737..352d41f 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -42,12 +42,6 @@ do { fprintf(stderr, scsi-disk: fmt , ## __VA_ARGS__); } while (0) #define SCSI_DMA_BUF_SIZE131072 #define SCSI_MAX_INQUIRY_LEN 256 -#define SCSI_REQ_STATUS_RETRY 0x01 -#define SCSI_REQ_STATUS_RETRY_TYPE_MASK 0x06 -#define SCSI_REQ_STATUS_RETRY_READ 0x00 -#define SCSI_REQ_STATUS_RETRY_WRITE 0x02 -#define SCSI_REQ_STATUS_RETRY_FLUSH 0x04 - typedef struct SCSIDiskState SCSIDiskState; typedef struct SCSIDiskReq { @@ -58,7 +52,6 @@ typedef struct SCSIDiskReq { uint32_t buflen; struct iovec iov; QEMUIOVector qiov; -uint32_t status; BlockAcctCookie acct; } SCSIDiskReq; @@ -75,8 +68,7 @@ struct SCSIDiskState bool tray_locked; }; -static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type); -static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf); +static int scsi_handle_rw_error(SCSIDiskReq *r, int error); static void scsi_free_request(SCSIRequest *req) { @@ -102,7 +94,6 @@ static void scsi_cancel_io(SCSIRequest *req) SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req); DPRINTF(Cancel tag=0x%x\n, req-tag); -r-status = ~(SCSI_REQ_STATUS_RETRY | SCSI_REQ_STATUS_RETRY_TYPE_MASK); if (r-req.aiocb) { bdrv_aio_cancel(r-req.aiocb); @@ -139,7
[Qemu-devel] [PATCH 29/55] scsi-disk: support READ DVD STRUCTURE
From: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Kevin Wolf kw...@redhat.com --- hw/scsi-disk.c | 102 +++- 1 files changed, 101 insertions(+), 1 deletions(-) diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 38b196b..8f8a94d 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -580,10 +580,110 @@ static inline bool media_is_dvd(SCSIDiskState *s) return nb_sectors CD_MAX_SECTORS; } +static inline bool media_is_cd(SCSIDiskState *s) +{ +uint64_t nb_sectors; +if (s-qdev.type != TYPE_ROM) { +return false; +} +if (!bdrv_is_inserted(s-bs)) { +return false; +} +bdrv_get_geometry(s-bs, nb_sectors); +return nb_sectors = CD_MAX_SECTORS; +} + static int scsi_read_dvd_structure(SCSIDiskState *s, SCSIDiskReq *r, uint8_t *outbuf) { -scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE)); +static const int rds_caps_size[5] = { +[0] = 2048 + 4, +[1] = 4 + 4, +[3] = 188 + 4, +[4] = 2048 + 4, +}; + +uint8_t media = r-req.cmd.buf[1]; +uint8_t layer = r-req.cmd.buf[6]; +uint8_t format = r-req.cmd.buf[7]; +int size = -1; + +if (s-qdev.type != TYPE_ROM) { +return -1; +} +if (media != 0) { +scsi_check_condition(r, SENSE_CODE(INVALID_FIELD)); +return -1; +} + +if (format != 0xff) { +if (s-tray_open || !bdrv_is_inserted(s-bs)) { +scsi_check_condition(r, SENSE_CODE(NO_MEDIUM)); +return -1; +} +if (media_is_cd(s)) { +scsi_check_condition(r, SENSE_CODE(INCOMPATIBLE_FORMAT)); +return -1; +} +if (format = ARRAY_SIZE(rds_caps_size)) { +return -1; +} +size = rds_caps_size[format]; +memset(outbuf, 0, size); +} + +switch (format) { +case 0x00: { +/* Physical format information */ +uint64_t nb_sectors; +if (layer != 0) { +goto fail; +} +bdrv_get_geometry(s-bs, nb_sectors); + +outbuf[4] = 1; /* DVD-ROM, part version 1 */ +outbuf[5] = 0xf; /* 120mm disc, minimum rate unspecified */ +outbuf[6] = 1; /* one layer, read-only (per MMC-2 spec) */ +outbuf[7] = 0; /* default densities */ + +stl_be_p(outbuf[12], (nb_sectors 2) - 1); /* end sector */ +stl_be_p(outbuf[16], (nb_sectors 2) - 1); /* l0 end sector */ +break; +} + +case 0x01: /* DVD copyright information, all zeros */ +break; + +case 0x03: /* BCA information - invalid field for no BCA info */ +return -1; + +case 0x04: /* DVD disc manufacturing information, all zeros */ +break; + +case 0xff: { /* List capabilities */ +int i; +size = 4; +for (i = 0; i ARRAY_SIZE(rds_caps_size); i++) { +if (!rds_caps_size[i]) { +continue; +} +outbuf[size] = i; +outbuf[size + 1] = 0x40; /* Not writable, readable */ +stw_be_p(outbuf[size + 2], rds_caps_size[i]); +size += 4; +} +break; + } + +default: +return -1; +} + +/* Size of buffer, not including 2 byte size field */ +stw_be_p(outbuf, size - 2); +return size; + +fail: return -1; } -- 1.7.6.4
[Qemu-devel] [PATCH 25/55] scsi-disk: add stubs for more MMC commands
From: Paolo Bonzini pbonz...@redhat.com This patch adds a few stub implementations for MMC commands to scsi-disk, to be filled in later in the series. It also adds to scsi-defs.h constants for commands implemented by ide/atapi.c, when missing. Signed-off-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Kevin Wolf kw...@redhat.com --- hw/scsi-defs.h |3 ++ hw/scsi-disk.c | 67 +++ 2 files changed, 65 insertions(+), 5 deletions(-) diff --git a/hw/scsi-defs.h b/hw/scsi-defs.h index 5e6c9b7..d0a467a 100644 --- a/hw/scsi-defs.h +++ b/hw/scsi-defs.h @@ -113,6 +113,7 @@ #define READ_12 0xa8 #define WRITE_12 0xaa #define SERVICE_ACTION_IN_12 0xab +#define READ_DVD_STRUCTURE0xad #define WRITE_VERIFY_12 0xae #define VERIFY_12 0xaf #define SEARCH_HIGH_120xb0 @@ -122,6 +123,8 @@ #define SEND_VOLUME_TAG 0xb6 #define READ_DEFECT_DATA_12 0xb7 #define SET_CD_SPEED 0xbb +#define MECHANISM_STATUS 0xbd +#define READ_CD 0xbe /* * SERVICE ACTION IN subcodes diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 3a08848..bdb98ef 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -567,6 +567,43 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) return buflen; } +static int scsi_read_dvd_structure(SCSIDiskState *s, SCSIDiskReq *r, + uint8_t *outbuf) +{ +scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE)); +return -1; +} + +static int scsi_get_event_status_notification(SCSIDiskState *s, + SCSIDiskReq *r, uint8_t *outbuf) +{ +scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE)); +return -1; +} + +static int scsi_get_configuration(SCSIDiskState *s, SCSIDiskReq *r, + uint8_t *outbuf) +{ +if (s-qdev.type != TYPE_ROM) { +return -1; +} +memset(outbuf, 0, 8); +/* ??? This should probably return much more information. For now + just return the basic header indicating the CD-ROM profile. */ +outbuf[7] = 8; /* CD-ROM */ +return 8; +} + +static int scsi_emulate_mechanism_status(SCSIDiskState *s, uint8_t *outbuf) +{ +if (s-qdev.type != TYPE_ROM) { +return -1; +} +memset(outbuf, 0, 8); +outbuf[5] = 1; /* CD-ROM */ +return 8; +} + static int mode_sense_page(SCSIDiskState *s, int page, uint8_t **p_outbuf, int page_control) { @@ -964,12 +1001,29 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r) outbuf[7] = 0; buflen = 8; break; +case MECHANISM_STATUS: +buflen = scsi_emulate_mechanism_status(s, outbuf); +if (buflen 0) { +goto illegal_request; +} +break; case GET_CONFIGURATION: -memset(outbuf, 0, 8); -/* ??? This should probably return much more information. For now - just return the basic header indicating the CD-ROM profile. */ -outbuf[7] = 8; // CD-ROM -buflen = 8; +buflen = scsi_get_configuration(s, r, outbuf); +if (buflen 0) { +goto illegal_request; +} +break; +case GET_EVENT_STATUS_NOTIFICATION: +buflen = scsi_get_event_status_notification(s, r, outbuf); +if (buflen 0) { +goto illegal_request; +} +break; +case READ_DVD_STRUCTURE: +buflen = scsi_read_dvd_structure(s, r, outbuf); +if (buflen 0) { +goto illegal_request; +} break; case SERVICE_ACTION_IN_16: /* Service Action In subcommands. */ @@ -1073,7 +1127,10 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf) case ALLOW_MEDIUM_REMOVAL: case READ_CAPACITY_10: case READ_TOC: +case READ_DVD_STRUCTURE: case GET_CONFIGURATION: +case GET_EVENT_STATUS_NOTIFICATION: +case MECHANISM_STATUS: case SERVICE_ACTION_IN_16: case VERIFY_10: rc = scsi_disk_emulate_command(r); -- 1.7.6.4
Re: [Qemu-devel] [PATCH] dma: Avoid reentrancy in DMA transfer handlers
Am 28.10.2011 18:35, schrieb Paolo Bonzini: On 10/28/2011 04:18 PM, Kevin Wolf wrote: With the conversion of the block layer to coroutines, bdrv_read/write have changed to run a nested event loop that calls qemu_bh_poll. Consequently a scheduled BH can be called while a DMA transfer handler runs and this means that DMA_run becomes reentrant. Devices haven't been designed to cope with that, so instead of running a nested transfer handler just wait for the next invocation of the BH from the main loop. This fixes some problems with the floppy device. Signed-off-by: Kevin Wolfkw...@redhat.com --- hw/dma.c |9 + 1 files changed, 9 insertions(+), 0 deletions(-) diff --git a/hw/dma.c b/hw/dma.c index 8a7302a..e8d6341 100644 --- a/hw/dma.c +++ b/hw/dma.c @@ -358,6 +358,13 @@ static void DMA_run (void) struct dma_cont *d; int icont, ichan; int rearm = 0; +static int running = 0; + +if (running) { +goto out; +} else { +running = 1; +} d = dma_controllers; @@ -374,6 +381,8 @@ static void DMA_run (void) } } +out: +running = 0; if (rearm) qemu_bh_schedule_idle(dma_bh); } Hmm, I think you should set rearm = 1 to ensure the BH is run when ultimately you leave the sync read. Sorry for not spotting this before. I was about to agree, but in fact adding a rearm = 1; line leads to crashes, whereas in the version I posted it just works. So it looks like something is wrong with doing it, even though it seemed to make perfect sense at the first sight. Kevin
[Qemu-devel] [PATCH 44/55] scsi-disk: do not duplicate BlockDriverState member
From: Paolo Bonzini pbonz...@redhat.com Same as for scsi-generic, avoid duplication even if it causes longer lines. Signed-off-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Kevin Wolf kw...@redhat.com --- hw/scsi-disk.c | 92 +++ 1 files changed, 45 insertions(+), 47 deletions(-) diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index e800ab3..8a05031 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -65,7 +65,6 @@ typedef struct SCSIDiskReq { struct SCSIDiskState { SCSIDevice qdev; -BlockDriverState *bs; /* The qemu block layer uses a fixed 512 byte sector size. This is the number of 512 byte blocks in a single scsi sector. */ int cluster_size; @@ -119,7 +118,7 @@ static uint32_t scsi_init_iovec(SCSIDiskReq *r) if (!r-iov.iov_base) { r-buflen = SCSI_DMA_BUF_SIZE; -r-iov.iov_base = qemu_blockalign(s-bs, r-buflen); +r-iov.iov_base = qemu_blockalign(s-qdev.conf.bs, r-buflen); } r-iov.iov_len = MIN(r-sector_count * 512, r-buflen); qemu_iovec_init_external(r-qiov, r-iov, 1); @@ -134,7 +133,7 @@ static void scsi_read_complete(void * opaque, int ret) if (r-req.aiocb != NULL) { r-req.aiocb = NULL; -bdrv_acct_done(s-bs, r-acct); +bdrv_acct_done(s-qdev.conf.bs, r-acct); } if (ret) { @@ -158,7 +157,7 @@ static void scsi_flush_complete(void * opaque, int ret) if (r-req.aiocb != NULL) { r-req.aiocb = NULL; -bdrv_acct_done(s-bs, r-acct); +bdrv_acct_done(s-qdev.conf.bs, r-acct); } if (ret 0) { @@ -203,8 +202,8 @@ static void scsi_read_data(SCSIRequest *req) scsi_read_complete(r, -ENOMEDIUM); } n = scsi_init_iovec(r); -bdrv_acct_start(s-bs, r-acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ); -r-req.aiocb = bdrv_aio_readv(s-bs, r-sector, r-qiov, n, +bdrv_acct_start(s-qdev.conf.bs, r-acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ); +r-req.aiocb = bdrv_aio_readv(s-qdev.conf.bs, r-sector, r-qiov, n, scsi_read_complete, r); if (r-req.aiocb == NULL) { scsi_read_complete(r, -EIO); @@ -215,10 +214,10 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type) { int is_read = (type == SCSI_REQ_STATUS_RETRY_READ); SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r-req.dev); -BlockErrorAction action = bdrv_get_on_error(s-bs, is_read); +BlockErrorAction action = bdrv_get_on_error(s-qdev.conf.bs, is_read); if (action == BLOCK_ERR_IGNORE) { -bdrv_mon_event(s-bs, BDRV_ACTION_IGNORE, is_read); +bdrv_mon_event(s-qdev.conf.bs, BDRV_ACTION_IGNORE, is_read); return 0; } @@ -228,9 +227,9 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type) type = SCSI_REQ_STATUS_RETRY_TYPE_MASK; r-status |= SCSI_REQ_STATUS_RETRY | type; -bdrv_mon_event(s-bs, BDRV_ACTION_STOP, is_read); +bdrv_mon_event(s-qdev.conf.bs, BDRV_ACTION_STOP, is_read); vm_stop(RUN_STATE_IO_ERROR); -bdrv_iostatus_set_err(s-bs, error); +bdrv_iostatus_set_err(s-qdev.conf.bs, error); } else { switch (error) { case ENOMEDIUM: @@ -246,7 +245,7 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type) scsi_check_condition(r, SENSE_CODE(IO_ERROR)); break; } -bdrv_mon_event(s-bs, BDRV_ACTION_REPORT, is_read); +bdrv_mon_event(s-qdev.conf.bs, BDRV_ACTION_REPORT, is_read); } return 1; } @@ -259,7 +258,7 @@ static void scsi_write_complete(void * opaque, int ret) if (r-req.aiocb != NULL) { r-req.aiocb = NULL; -bdrv_acct_done(s-bs, r-acct); +bdrv_acct_done(s-qdev.conf.bs, r-acct); } if (ret) { @@ -300,8 +299,8 @@ static void scsi_write_data(SCSIRequest *req) if (s-tray_open) { scsi_write_complete(r, -ENOMEDIUM); } -bdrv_acct_start(s-bs, r-acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_WRITE); -r-req.aiocb = bdrv_aio_writev(s-bs, r-sector, r-qiov, n, +bdrv_acct_start(s-qdev.conf.bs, r-acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_WRITE); +r-req.aiocb = bdrv_aio_writev(s-qdev.conf.bs, r-sector, r-qiov, n, scsi_write_complete, r); if (r-req.aiocb == NULL) { scsi_write_complete(r, -ENOMEM); @@ -440,7 +439,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) case 0x83: /* Device identification page, mandatory */ { int max_len = 255 - 8; -int id_len = strlen(bdrv_get_device_name(s-bs)); +int id_len = strlen(bdrv_get_device_name(s-qdev.conf.bs)); if (id_len max_len) { id_len = max_len; @@ -454,7 +453,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
[Qemu-devel] [PATCH 14/55] qemu-io: delete bs instead of leaking it
From: Stefan Hajnoczi stefa...@linux.vnet.ibm.com Using bdrv_close() is not enough to free a BlockDriverState. Since we explicitly create it with bdrv_new(), use bdrv_delete() to close and delete it. Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com Signed-off-by: Kevin Wolf kw...@redhat.com --- qemu-io.c |5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/qemu-io.c b/qemu-io.c index c45a413..5af887e 100644 --- a/qemu-io.c +++ b/qemu-io.c @@ -1582,7 +1582,7 @@ static const cmdinfo_t map_cmd = { static int close_f(int argc, char **argv) { -bdrv_close(bs); +bdrv_delete(bs); bs = NULL; return 0; } @@ -1611,6 +1611,7 @@ static int openfile(char *name, int flags, int growable) if (bdrv_open(bs, name, flags, NULL) 0) { fprintf(stderr, %s: can't open device %s\n, progname, name); +bdrv_delete(bs); bs = NULL; return 1; } @@ -1834,7 +1835,7 @@ int main(int argc, char **argv) qemu_aio_flush(); if (bs) { -bdrv_close(bs); +bdrv_delete(bs); } return 0; } -- 1.7.6.4
[Qemu-devel] [PATCH 05/55] block: Remove dead code
Signed-off-by: Kevin Wolf kw...@redhat.com --- block.c |6 +- 1 files changed, 1 insertions(+), 5 deletions(-) diff --git a/block.c b/block.c index 70aab63..f86984f 100644 --- a/block.c +++ b/block.c @@ -2028,11 +2028,7 @@ const char *bdrv_get_encrypted_filename(BlockDriverState *bs) void bdrv_get_backing_filename(BlockDriverState *bs, char *filename, int filename_size) { -if (!bs-backing_file) { -pstrcpy(filename, filename_size, ); -} else { -pstrcpy(filename, filename_size, bs-backing_file); -} +pstrcpy(filename, filename_size, bs-backing_file); } int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num, -- 1.7.6.4
[Qemu-devel] [PATCH 43/55] scsi-generic: snoop READ CAPACITY commands to get block size
From: Paolo Bonzini pbonz...@redhat.com Instead of guessing the block size when there is no medium in the drive, wait for the guest to send a READ CAPACITY command and snoop it from there. Signed-off-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Kevin Wolf kw...@redhat.com --- hw/scsi-generic.c | 66 - 1 files changed, 25 insertions(+), 41 deletions(-) diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c index 5ad3d57..4d7ad82 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -155,6 +155,7 @@ static int execute_command(BlockDriverState *bdrv, static void scsi_read_complete(void * opaque, int ret) { SCSIGenericReq *r = (SCSIGenericReq *)opaque; +SCSIDevice *s = r-req.dev; int len; r-req.aiocb = NULL; @@ -170,6 +171,15 @@ static void scsi_read_complete(void * opaque, int ret) if (len == 0) { scsi_command_complete(r, 0); } else { +/* Snoop READ CAPACITY output to set the blocksize. */ +if (r-req.cmd.buf[0] == READ_CAPACITY_10) { +s-blocksize = ldl_be_p(r-buf[4]); +} else if (r-req.cmd.buf[0] == SERVICE_ACTION_IN_16 + (r-req.cmd.buf[1] 31) == SAI_READ_CAPACITY_16) { +s-blocksize = ldl_be_p(r-buf[8]); +} +bdrv_set_buffer_alignment(s-conf.bs, s-blocksize); + scsi_req_data(r-req, len); } } @@ -298,36 +308,6 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd) } } -static int get_blocksize(BlockDriverState *bdrv) -{ -uint8_t cmd[10]; -uint8_t buf[8]; -uint8_t sensebuf[8]; -sg_io_hdr_t io_header; -int ret; - -memset(cmd, 0, sizeof(cmd)); -memset(buf, 0, sizeof(buf)); -cmd[0] = READ_CAPACITY_10; - -memset(io_header, 0, sizeof(io_header)); -io_header.interface_id = 'S'; -io_header.dxfer_direction = SG_DXFER_FROM_DEV; -io_header.dxfer_len = sizeof(buf); -io_header.dxferp = buf; -io_header.cmdp = cmd; -io_header.cmd_len = sizeof(cmd); -io_header.mx_sb_len = sizeof(sensebuf); -io_header.sbp = sensebuf; -io_header.timeout = 6000; /* XXX */ - -ret = bdrv_ioctl(bdrv, SG_IO, io_header); -if (ret 0 || io_header.driver_status || io_header.host_status) { -return -1; -} -return (buf[4] 24) | (buf[5] 16) | (buf[6] 8) | buf[7]; -} - static int get_stream_blocksize(BlockDriverState *bdrv) { uint8_t cmd[6]; @@ -413,21 +393,25 @@ static int scsi_generic_initfn(SCSIDevice *s) /* define device state */ s-type = scsiid.scsi_type; DPRINTF(device type %d\n, s-type); -if (s-type == TYPE_TAPE) { +switch (s-type) { +case TYPE_TAPE: s-blocksize = get_stream_blocksize(s-conf.bs); if (s-blocksize == -1) { s-blocksize = 0; } -} else { -s-blocksize = get_blocksize(s-conf.bs); -/* removable media returns 0 if not present */ -if (s-blocksize = 0) { -if (s-type == TYPE_ROM || s-type == TYPE_WORM) { -s-blocksize = 2048; -} else { -s-blocksize = 512; -} -} +break; + +/* Make a guess for block devices, we'll fix it when the guest sends. + * READ CAPACITY. If they don't, they likely would assume these sizes + * anyway. (TODO: they could also send MODE SENSE). + */ +case TYPE_ROM: +case TYPE_WORM: +s-blocksize = 2048; +break; +default: +s-blocksize = 512; +break; } DPRINTF(block size %d\n, s-blocksize); -- 1.7.6.4
[Qemu-devel] [PATCH 13/55] block: fix qcow2_co_flush deadlock
From: Dong Xu Wang wdon...@linux.vnet.ibm.com If qcow2_cache_flush failed, s-lock will not be unlock. Signed-off-by: Dong Xu Wang wdon...@linux.vnet.ibm.com Signed-off-by: Kevin Wolf kw...@redhat.com --- block/qcow2.c |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index a181932..ef057d3 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1113,11 +1113,13 @@ static int qcow2_co_flush(BlockDriverState *bs) qemu_co_mutex_lock(s-lock); ret = qcow2_cache_flush(bs, s-l2_table_cache); if (ret 0) { +qemu_co_mutex_unlock(s-lock); return ret; } ret = qcow2_cache_flush(bs, s-refcount_block_cache); if (ret 0) { +qemu_co_mutex_unlock(s-lock); return ret; } qemu_co_mutex_unlock(s-lock); -- 1.7.6.4
[Qemu-devel] [PATCH] Error check find_ram_offset
Spotted via code review, we initialize offset to 0 to avoid a compiler warning, but in the unlikely case that offset is never set to something else, we should abort instead of return a value that will almost certainly cause problems. Signed-off-by: Alex Williamson alex.william...@redhat.com --- exec.c | 11 +-- 1 files changed, 9 insertions(+), 2 deletions(-) diff --git a/exec.c b/exec.c index 9dc4edb..70f6fb8 100644 --- a/exec.c +++ b/exec.c @@ -2874,7 +2874,7 @@ static void *file_ram_alloc(RAMBlock *block, static ram_addr_t find_ram_offset(ram_addr_t size) { RAMBlock *block, *next_block; -ram_addr_t offset = 0, mingap = RAM_ADDR_MAX; +ram_addr_t offset = RAM_ADDR_MAX, mingap = RAM_ADDR_MAX; if (QLIST_EMPTY(ram_list.blocks)) return 0; @@ -2890,10 +2890,17 @@ static ram_addr_t find_ram_offset(ram_addr_t size) } } if (next - end = size next - end mingap) { -offset = end; +offset = end; mingap = next - end; } } + +if (offset == RAM_ADDR_MAX) { +fprintf(stderr, Failed to find gap of requested size: % PRIu64 \n, +(uint64_t)size); +abort(); +} + return offset; }
[Qemu-devel] [PATCH 32/55] qdev: switch children device list to QTAILQ
From: Paolo Bonzini pbonz...@redhat.com SCSI buses will need to read the children list first-to-last. This requires using a QTAILQ, because hell breaks loose if you just try inserting at the tail (thus reversing the order of all existing visits from last-to-first to first-to-tail). Signed-off-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Kevin Wolf kw...@redhat.com --- hw/acpi_piix4.c |4 ++-- hw/i2c.c |2 +- hw/intel-hda.c |6 +++--- hw/qdev.c| 24 hw/qdev.h|4 ++-- hw/s390-virtio-bus.c |4 ++-- hw/spapr_vio.c |6 +++--- hw/ssi.c |6 +++--- 8 files changed, 28 insertions(+), 28 deletions(-) diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c index 29f0f76..d9075e6 100644 --- a/hw/acpi_piix4.c +++ b/hw/acpi_piix4.c @@ -276,7 +276,7 @@ static void piix4_update_hotplug(PIIX4PMState *s) s-pci0_hotplug_enable = ~0; -QLIST_FOREACH_SAFE(qdev, bus-children, sibling, next) { +QTAILQ_FOREACH_SAFE(qdev, bus-children, sibling, next) { PCIDeviceInfo *info = container_of(qdev-info, PCIDeviceInfo, qdev); PCIDevice *pdev = DO_UPCAST(PCIDevice, qdev, qdev); int slot = PCI_SLOT(pdev-devfn); @@ -486,7 +486,7 @@ static void pciej_write(void *opaque, uint32_t addr, uint32_t val) PCIDeviceInfo *info; int slot = ffs(val) - 1; -QLIST_FOREACH_SAFE(qdev, bus-children, sibling, next) { +QTAILQ_FOREACH_SAFE(qdev, bus-children, sibling, next) { dev = DO_UPCAST(PCIDevice, qdev, qdev); info = container_of(qdev-info, PCIDeviceInfo, qdev); if (PCI_SLOT(dev-devfn) == slot !info-no_hotplug) { diff --git a/hw/i2c.c b/hw/i2c.c index 49b9ecb..9bcf3e1 100644 --- a/hw/i2c.c +++ b/hw/i2c.c @@ -84,7 +84,7 @@ int i2c_start_transfer(i2c_bus *bus, uint8_t address, int recv) DeviceState *qdev; i2c_slave *slave = NULL; -QLIST_FOREACH(qdev, bus-qbus.children, sibling) { +QTAILQ_FOREACH(qdev, bus-qbus.children, sibling) { i2c_slave *candidate = I2C_SLAVE_FROM_QDEV(qdev); if (candidate-address == address) { slave = candidate; diff --git a/hw/intel-hda.c b/hw/intel-hda.c index f97775c..675b659 100644 --- a/hw/intel-hda.c +++ b/hw/intel-hda.c @@ -86,7 +86,7 @@ HDACodecDevice *hda_codec_find(HDACodecBus *bus, uint32_t cad) DeviceState *qdev; HDACodecDevice *cdev; -QLIST_FOREACH(qdev, bus-qbus.children, sibling) { +QTAILQ_FOREACH(qdev, bus-qbus.children, sibling) { cdev = DO_UPCAST(HDACodecDevice, qdev, qdev); if (cdev-cad == cad) { return cdev; @@ -490,7 +490,7 @@ static void intel_hda_notify_codecs(IntelHDAState *d, uint32_t stream, bool runn DeviceState *qdev; HDACodecDevice *cdev; -QLIST_FOREACH(qdev, d-codecs.qbus.children, sibling) { +QTAILQ_FOREACH(qdev, d-codecs.qbus.children, sibling) { cdev = DO_UPCAST(HDACodecDevice, qdev, qdev); if (cdev-info-stream) { cdev-info-stream(cdev, stream, running, output); @@ -1114,7 +1114,7 @@ static void intel_hda_reset(DeviceState *dev) d-wall_base_ns = qemu_get_clock_ns(vm_clock); /* reset codecs */ -QLIST_FOREACH(qdev, d-codecs.qbus.children, sibling) { +QTAILQ_FOREACH(qdev, d-codecs.qbus.children, sibling) { cdev = DO_UPCAST(HDACodecDevice, qdev, qdev); if (qdev-info-reset) { qdev-info-reset(qdev); diff --git a/hw/qdev.c b/hw/qdev.c index a223d41..50976dd 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -91,7 +91,7 @@ static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info) qdev_prop_set_defaults(dev, dev-info-props); qdev_prop_set_defaults(dev, dev-parent_bus-info-props); qdev_prop_set_globals(dev); -QLIST_INSERT_HEAD(bus-children, dev, sibling); +QTAILQ_INSERT_HEAD(bus-children, dev, sibling); if (qdev_hotplug) { assert(bus-allow_hotplug); dev-hotplugged = 1; @@ -408,7 +408,7 @@ void qdev_free(DeviceState *dev) if (dev-opts) qemu_opts_del(dev-opts); } -QLIST_REMOVE(dev, sibling); +QTAILQ_REMOVE(dev-parent_bus-children, dev, sibling); for (prop = dev-info-props; prop prop-name; prop++) { if (prop-info-free) { prop-info-free(dev, prop); @@ -510,7 +510,7 @@ int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn, } } -QLIST_FOREACH(dev, bus-children, sibling) { +QTAILQ_FOREACH(dev, bus-children, sibling) { err = qdev_walk_children(dev, devfn, busfn, opaque); if (err 0) { return err; @@ -560,7 +560,7 @@ static BusState *qbus_find_recursive(BusState *bus, const char *name, return bus; } -QLIST_FOREACH(dev, bus-children, sibling) { +QTAILQ_FOREACH(dev, bus-children, sibling) { QLIST_FOREACH(child, dev-child_bus, sibling) { ret = qbus_find_recursive(child, name, info);
[Qemu-devel] [PATCH 19/55] atapi/scsi: unify definitions for MMC
From: Paolo Bonzini pbonz...@redhat.com The definitions in ide/internal.h are duplicates, since ATAPI commands actually come from SCSI. Use the ones in scsi-defs.h and move the missing ones there. Two exceptions: - MODE_PAGE_WRITE_PARMS conflicts with the flexible disk geometry page in scsi-disk.c. It is unused, so pick the latter. - GPCMD_* is left in ide/internal.h, at least for now. Signed-off-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Kevin Wolf kw...@redhat.com --- hw/ide/atapi.c| 52 +++--- hw/ide/core.c |4 +- hw/ide/internal.h | 71 + hw/ide/macio.c|2 +- hw/scsi-bus.c |2 +- hw/scsi-defs.h| 66 + hw/scsi-disk.c|8 +++--- 7 files changed, 101 insertions(+), 104 deletions(-) diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c index 3f909c3..be3b728 100644 --- a/hw/ide/atapi.c +++ b/hw/ide/atapi.c @@ -154,10 +154,10 @@ void ide_atapi_io_error(IDEState *s, int ret) { /* XXX: handle more errors */ if (ret == -ENOMEDIUM) { -ide_atapi_cmd_error(s, SENSE_NOT_READY, +ide_atapi_cmd_error(s, NOT_READY, ASC_MEDIUM_NOT_PRESENT); } else { -ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, +ide_atapi_cmd_error(s, ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR); } } @@ -282,7 +282,7 @@ static void ide_atapi_cmd_check_status(IDEState *s) #ifdef DEBUG_IDE_ATAPI printf(atapi_cmd_check_status\n); #endif -s-error = MC_ERR | (SENSE_UNIT_ATTENTION 4); +s-error = MC_ERR | (UNIT_ATTENTION 4); s-status = ERR_STAT; s-nsector = 0; ide_set_irq(s-bus); @@ -354,7 +354,7 @@ static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret) ide_atapi_cmd_read_dma_cb, s); if (!s-bus-dma-aiocb) { /* Note: media not present is the most likely case */ -ide_atapi_cmd_error(s, SENSE_NOT_READY, +ide_atapi_cmd_error(s, NOT_READY, ASC_MEDIUM_NOT_PRESENT); goto eot; } @@ -595,7 +595,7 @@ static void cmd_get_event_status_notification(IDEState *s, /* It is fine by the MMC spec to not support async mode operations */ if (!(gesn_cdb-polled 0x01)) { /* asynchronous mode */ /* Only polling is supported, asynchronous mode is not. */ -ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, +ide_atapi_cmd_error(s, ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET); return; } @@ -643,8 +643,8 @@ static void cmd_request_sense(IDEState *s, uint8_t *buf) buf[7] = 10; buf[12] = s-asc; -if (s-sense_key == SENSE_UNIT_ATTENTION) { -s-sense_key = SENSE_NONE; +if (s-sense_key == UNIT_ATTENTION) { +s-sense_key = NO_SENSE; } ide_atapi_cmd_reply(s, 18, max_len); @@ -676,7 +676,7 @@ static void cmd_get_configuration(IDEState *s, uint8_t *buf) /* only feature 0 is supported */ if (buf[2] != 0 || buf[3] != 0) { -ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, +ide_atapi_cmd_error(s, ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET); return; } @@ -733,7 +733,7 @@ static void cmd_mode_sense(IDEState *s, uint8_t *buf) switch(action) { case 0: /* current values */ switch(code) { -case GPMODE_R_W_ERROR_PAGE: /* error recovery */ +case MODE_PAGE_R_W_ERROR: /* error recovery */ cpu_to_ube16(buf[0], 16 + 6); buf[2] = 0x70; buf[3] = 0; @@ -752,7 +752,7 @@ static void cmd_mode_sense(IDEState *s, uint8_t *buf) buf[15] = 0x00; ide_atapi_cmd_reply(s, 16, max_len); break; -case GPMODE_AUDIO_CTL_PAGE: +case MODE_PAGE_AUDIO_CTL: cpu_to_ube16(buf[0], 24 + 6); buf[2] = 0x70; buf[3] = 0; @@ -769,7 +769,7 @@ static void cmd_mode_sense(IDEState *s, uint8_t *buf) ide_atapi_cmd_reply(s, 24, max_len); break; -case GPMODE_CAPABILITIES_PAGE: +case MODE_PAGE_CAPABILITIES: cpu_to_ube16(buf[0], 28 + 6); buf[2] = 0x70; buf[3] = 0; @@ -813,14 +813,14 @@ static void cmd_mode_sense(IDEState *s, uint8_t *buf) goto error_cmd; default: case 3: /* saved values */ -ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, +ide_atapi_cmd_error(s, ILLEGAL_REQUEST, ASC_SAVING_PARAMETERS_NOT_SUPPORTED); break; } return; error_cmd: -ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET); +ide_atapi_cmd_error(s, ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET); } static void cmd_test_unit_ready(IDEState *s, uint8_t *buf) @@ -883,7 +883,7 @@ static void
[Qemu-devel] [PATCH 04/55] qcow2: fix some errors and typo in qcow2.txt
From: Zhi Yong Wu wu...@linux.vnet.ibm.com Signed-off-by: Zhi Yong Wu wu...@linux.vnet.ibm.com Signed-off-by: Kevin Wolf kw...@redhat.com --- docs/specs/qcow2.txt |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/specs/qcow2.txt b/docs/specs/qcow2.txt index 8fc3cb2..e792953 100644 --- a/docs/specs/qcow2.txt +++ b/docs/specs/qcow2.txt @@ -108,8 +108,8 @@ as follows: refcount_block_entries = (cluster_size / sizeof(uint16_t)) -refcount_block_index = (offset / cluster_size) % refcount_table_entries -refcount_table_index = (offset / cluster_size) / refcount_table_entries +refcount_block_index = (offset / cluster_size) % refcount_block_entries +refcount_table_index = (offset / cluster_size) / refcount_block_entries refcount_block = load_cluster(refcount_table[refcount_table_index]); return refcount_block[refcount_block_index]; @@ -211,7 +211,7 @@ switch the active L1 table, so that a different set of host clusters are exposed to the guest. When creating a snapshot, the L1 table should be copied and the refcount of all -L2 tables and clusters reachable form this L1 table must be increased, so that +L2 tables and clusters reachable from this L1 table must be increased, so that a write causes a COW and isn't visible in other snapshots. When loading a snapshot, bit 63 of all entries in the new active L1 table and -- 1.7.6.4