Re: [Qemu-devel] [PATCH v6 0/4] rbd improvements
Am 27.05.2011 01:07, schrieb Josh Durgin: > This patchset moves the complexity of the rbd format into librbd and > adds truncation support. > > Changes since v5: > * compare full string, not prefix, with "conf" in 2/4 > * when truncate fails, just return librbd's error > > Changes since v4: > * fixed cosmetic issues pointed out by Christian Brunner > > Changes since v3: > * trivially rebased > * updated copyright header > > Changes since v2: > * return values are checked in rbd_aio_rw_vector > * bdrv_truncate added > > Josh Durgin (4): > rbd: use the higher level librbd instead of just librados > rbd: allow configuration of rados from the rbd filename > rbd: check return values when scheduling aio > rbd: Add bdrv_truncate implementation > > block/rbd.c | 896 > +++-- > block/rbd_types.h | 71 - > configure | 33 +-- > 3 files changed, 334 insertions(+), 666 deletions(-) > delete mode 100644 block/rbd_types.h Thanks, applied to the block branch. Kevin
Re: [Qemu-devel] [PATCH 05/18] ide: Turn debug messages into assertions
Am 26.05.2011 23:12, schrieb Luiz Capitulino: > On Thu, 19 May 2011 14:33:19 +0200 > Kevin Wolf wrote: > >> These printfs aren't really debug messages, but clearly indicate a bug if >> they >> ever become effective. > > Then we have a bug somewhere, starting a VM with: > > # qemu -hda disks/test.img -enable-kvm -m 1G -cdrom /dev/sr0 > > Where the host's CDROM is empty, triggers one of these asserts: > > qmp-unstable/hw/ide/pci.c:299: bmdma_cmd_writeb: Assertion > `bm->bus->dma->aiocb == ((void *)0)' Hm, works for me. Do you need some guest OS interaction or do you get the crash immediately? Kevin
Re: [Qemu-devel] [PATCH 01/12] usb-linux: catch NODEV in more places.
On 05/26/11 20:20, Markus Armbruster wrote: Gerd Hoffmann writes: Factor out disconnect code (called when a device disappears) to a separate function. Add a check for NODEV errno to a few more places to make sure we notice disconnects. Ah, you mean ENODEV! Suddenly the subject makes sense. Fix it up? Done. thanks, Gerd
Re: [Qemu-devel] [PATCH 00/12] target-s390x: Several small fixes
Am 26.05.2011 23:48, schrieb Andreas Färber: Am 26.05.2011 um 00:17 schrieb Alexander Graf: On 26.05.2011, at 00:10, Peter Maydell wrote: On 25 May 2011 21:25, Stefan Weil wrote: Feel free to combine patches if larger patches are preferred. I'd vote for combining at least 03..12, having nine patches all of which have the same summary line is a bit confusing :-) I actually like them as individual patches. Makes bisecting a lot easier :). Stefan, could you add the function name or some other discriminator to the subject then, please? Andreas This would result in these subjects: 4 x target-s390x: Add missing tcg_temp_free_i64() in disas_a5 2 x target-s390x: Add missing tcg_temp_free_i64() in disas_s390_insn 1 x target-s390x: Add missing tcg_temp_free_i64() in disas_b2 1 x target-s390x: Add missing tcg_temp_free_i64() in do_mh 1 x target-s390x: Add missing tcg_temp_free_i64() in gen_jcc So there remain duplicate subjects. Adding the line number or a sequence number would look somehow strange. The subjects are identical simply because the changes are very similar. If needed, git provides the unique identification. Maybe combining the patches which share the same function and add this function name to the subject would be a compromise which still allows bisecting. Cheers, Stefan
[Qemu-devel] restoring suspend to disk images from qemu-0.12.5 to qemu-014.1 fails
Hi, restoring previously created qemu suspend to disk images with qemu-0.14.1 or 0.14.0 fails the loop in qemu_loadvm_state() seems to fallsly match an EOF and does not proceed with the rest of the sections same problem when migrating from 0.12.5 to 0.14.x any hints/ideas ? Regars, Jason
Re: [Qemu-devel] [PATCH 1/3] Add ppc_init_cacheline_sizes() function for OpenBSD.
On Thu, 26 May 2011, Brad wrote: > On 26/05/11 9:15 AM, malc wrote: > > On Thu, 26 May 2011, Brad wrote: > > > > > - Original message - > > > > On Wed, 25 May 2011, Brad wrote: > > > > > > > > > Add ppc_init_cacheline_sizes() function for OpenBSD to fix compilation > > > > > of PowerPC host support for OpenBSD/powerpc based architectures. > > > > > > > > > > Signed-off-by: Brad Smith > > > > > [..snip..] > > Well this is the behavior of our kernel no matter what the CPU type is. > > from sys/arch/powerpc/cpu.h.. > > > #define CACHELINE 32 /* Note that this value is really > hardwired */ > [..snip..] I sure hope that OpenBSD doesn't use this value for dcbz/a's on ppc's with less than 32 bytes per cache line and am not sure i want to take this patch even if the kernel itself does this, not without some nagging printf in the init cache line function urging OpenBSD kernel developers to fix things.. -- mailto:av1...@comtv.ru
[Qemu-devel] [Bug 720787] Re: Fails to compile on MacOS
Nigel's error is also topic in bug https://bugs.launchpad.net/qemu/+bug/726962 -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/720787 Title: Fails to compile on MacOS Status in QEMU: New Bug description: Make fails with: qemu-thread.c: In function 'qemu_mutex_timedlock': qemu-thread.c:75: warning: implicit declaration of function 'clock_gettime' qemu-thread.c:75: warning: nested extern declaration of 'clock_gettime' qemu-thread.c:75: error: 'CLOCK_REALTIME' undeclared (first use in this function) qemu-thread.c:75: error: (Each undeclared identifier is reported only once qemu-thread.c:75: error: for each function it appears in.) qemu-thread.c:78: warning: implicit declaration of function 'pthread_mutex_timedlock' qemu-thread.c:78: warning: nested extern declaration of 'pthread_mutex_timedlock' qemu-thread.c: In function 'qemu_cond_timedwait': qemu-thread.c:143: error: 'CLOCK_REALTIME' undeclared (first use in this function) make: *** [qemu-thread.o] Error 1 On Git commit commit 79f2b6fcdb7c06cdce6eccc796f5651f3efb843e Using "configure --enable-io-thread"
Re: [Qemu-devel] [Bug 788697] Re: [PowerPC] [patch] mtmsr does not preserve high bits of MSR
On 27.05.2011, at 01:33, Nathan Whitehorn wrote: > On 05/26/11 11:45, agraf wrote: >> On 26.05.2011, at 18:09, Nathan Whitehorn wrote: >> >>> ** Patch added: "mtmstr.diff" >>> >>> https://bugs.launchpad.net/bugs/788697/+attachment/2143748/+files/mtmstr.diff >>> >>> -- >>> You received this bug notification because you are a member of qemu- >>> devel-ml, which is subscribed to QEMU. >>> https://bugs.launchpad.net/bugs/788697 >>> >>> Title: >>> [PowerPC] [patch] mtmsr does not preserve high bits of MSR >>> >>> Status in QEMU: >>> New >>> >>> Bug description: >>> The mtmsr instruction on 64-bit PPC does not preserve the high-order >>> 32-bits of the MSR the way it is supposed to, instead setting them to >>> 0, which takes 64-bit code out of 64-bit mode. There is some code that >>> does the right thing, but it brokenly only preserves these bits when >>> the thread is not in 64-bit mode (i.e. when it doesn't matter). The >>> attached patch unconditionally enables this code when TARGET_PPC64 is >>> set, per the ISA spec, which fixes early boot failures trying to start >>> FreeBSD/powerpc64 under qemu. >>> >> >> Please send the patch as proper patch to the ML and CC me. > > What isn't proper about the patch? I'm happy to re-email it, but don't > want things to be in the wrong format. > -Nathan The patch needs a patch description in its header and a subject line (all of which are present in the bug, so it's a simple matter of copy&paste). Basically at the end of the day, I should be able to save the mail and "git am" on it and simply have it in my tree :). Also, does this get FreeBSD booting up to anything useful, so I can verify it helps? Alex
Re: [Qemu-devel] [Bug 788697] Re: [PowerPC] [patch] mtmsr does not preserve high bits of MSR
On 05/26/11 11:45, agraf wrote: > On 26.05.2011, at 18:09, Nathan Whitehorn wrote: > >> ** Patch added: "mtmstr.diff" >> >> https://bugs.launchpad.net/bugs/788697/+attachment/2143748/+files/mtmstr.diff >> >> -- >> You received this bug notification because you are a member of qemu- >> devel-ml, which is subscribed to QEMU. >> https://bugs.launchpad.net/bugs/788697 >> >> Title: >> [PowerPC] [patch] mtmsr does not preserve high bits of MSR >> >> Status in QEMU: >> New >> >> Bug description: >> The mtmsr instruction on 64-bit PPC does not preserve the high-order >> 32-bits of the MSR the way it is supposed to, instead setting them to >> 0, which takes 64-bit code out of 64-bit mode. There is some code that >> does the right thing, but it brokenly only preserves these bits when >> the thread is not in 64-bit mode (i.e. when it doesn't matter). The >> attached patch unconditionally enables this code when TARGET_PPC64 is >> set, per the ISA spec, which fixes early boot failures trying to start >> FreeBSD/powerpc64 under qemu. >> > > Please send the patch as proper patch to the ML and CC me. What isn't proper about the patch? I'm happy to re-email it, but don't want things to be in the wrong format. -Nathan -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/788697 Title: [PowerPC] [patch] mtmsr does not preserve high bits of MSR Status in QEMU: New Bug description: The mtmsr instruction on 64-bit PPC does not preserve the high-order 32-bits of the MSR the way it is supposed to, instead setting them to 0, which takes 64-bit code out of 64-bit mode. There is some code that does the right thing, but it brokenly only preserves these bits when the thread is not in 64-bit mode (i.e. when it doesn't matter). The attached patch unconditionally enables this code when TARGET_PPC64 is set, per the ISA spec, which fixes early boot failures trying to start FreeBSD/powerpc64 under qemu.
Re: [Qemu-devel] [PATCH 1/3] Add ppc_init_cacheline_sizes() function for OpenBSD.
On 26/05/11 9:15 AM, malc wrote: On Thu, 26 May 2011, Brad wrote: - Original message - On Wed, 25 May 2011, Brad wrote: Add ppc_init_cacheline_sizes() function for OpenBSD to fix compilation of PowerPC host support for OpenBSD/powerpc based architectures. Signed-off-by: Brad Smith --- cache-utils.c | 11 +-- 1 files changed, 9 insertions(+), 2 deletions(-) diff --git a/cache-utils.c b/cache-utils.c index 2db5af2..c319705 100644 --- a/cache-utils.c +++ b/cache-utils.c @@ -55,9 +55,16 @@ static void ppc_init_cacheline_sizes(void) qemu_cache_conf.icache_bsize = cacheline; } } -#endif -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#elif defined(__OpenBSD__) + +static void ppc_init_cacheline_sizes(void) +{ + qemu_cache_conf.dcache_bsize = 32; + qemu_cache_conf.icache_bsize = 32; +} + +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) #include #include #include This can't be right for most ppc64's. Well this is what OpenBSD currently does and runs on G5's in 32-bit mode only. Mode of operation does not, to the best of my knowledge, change the hardware limits, the cache line size will still be 128 on those G5s. Well this is the behavior of our kernel no matter what the CPU type is. from sys/arch/powerpc/cpu.h.. #define CACHELINE 32 /* Note that this value is really hardwired */ static __inline void syncicache(void *from, int len) { int l; char *p = from; len = len + (((u_int32_t) from) & (CACHELINESIZE - 1)); l = len; do { __asm __volatile ("dcbst 0,%0" :: "r"(p)); p += CACHELINESIZE; } while ((l -= CACHELINESIZE) > 0); __asm __volatile ("sync"); p = from; l = len; do { __asm __volatile ("icbi 0,%0" :: "r"(p)); p += CACHELINESIZE; } while ((l -= CACHELINESIZE) > 0); __asm __volatile ("isync"); } static __inline void invdcache(void *from, int len) { int l; char *p = from; len = len + (((u_int32_t) from) & (CACHELINESIZE - 1)); l = len; do { __asm __volatile ("dcbi 0,%0" :: "r"(p)); p += CACHELINESIZE; } while ((l -= CACHELINESIZE) > 0); __asm __volatile ("sync"); } -- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.
[Qemu-devel] [Bug 788886] [NEW] Crash with -m32 and gcc-4.2 on Mac OS X 64bit
Public bug reported: For building 32bit Qemu on Mac OS X 10.6.7 , i configure with --extra- cflags=-m32 --extra-ldflags=-m32. make with gcc-4.2 then crashes with: GEN qemu-options.def CCqemu-nbd.o gcc-4.2: -E, -S, -save-temps and -M options are not allowed with multiple -arch flags make: *** [qemu-nbd.o] Error 1 ** Affects: qemu Importance: Undecided Status: New -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/76 Title: Crash with -m32 and gcc-4.2 on Mac OS X 64bit Status in QEMU: New Bug description: For building 32bit Qemu on Mac OS X 10.6.7 , i configure with --extra- cflags=-m32 --extra-ldflags=-m32. make with gcc-4.2 then crashes with: GEN qemu-options.def CCqemu-nbd.o gcc-4.2: -E, -S, -save-temps and -M options are not allowed with multiple -arch flags make: *** [qemu-nbd.o] Error 1
[Qemu-devel] [PATCH v6 3/4] rbd: check return values when scheduling aio
If scheduling fails, the number of outstanding I/Os must be correct, or there will be a hang when waiting for everything to be flushed. Reviewed-by: Christian Brunner Reported-by: Stefan Hajnoczi Signed-off-by: Josh Durgin --- block/rbd.c | 24 1 files changed, 20 insertions(+), 4 deletions(-) diff --git a/block/rbd.c b/block/rbd.c index edf1086..f4da6ab 100644 --- a/block/rbd.c +++ b/block/rbd.c @@ -581,10 +581,14 @@ static BlockDriverAIOCB *rbd_aio_rw_vector(BlockDriverState *bs, rbd_completion_t c; int64_t off, size; char *buf; +int r; BDRVRBDState *s = bs->opaque; acb = qemu_aio_get(&rbd_aio_pool, bs, cb, opaque); +if (!acb) { +return NULL; +} acb->write = write; acb->qiov = qiov; acb->bounce = qemu_blockalign(bs, qiov->size); @@ -611,16 +615,28 @@ static BlockDriverAIOCB *rbd_aio_rw_vector(BlockDriverState *bs, rcb->buf = buf; rcb->s = acb->s; rcb->size = size; +r = rbd_aio_create_completion(rcb, (rbd_callback_t) rbd_finish_aiocb, &c); +if (r < 0) { +goto failed; +} if (write) { -rbd_aio_create_completion(rcb, (rbd_callback_t) rbd_finish_aiocb, &c); -rbd_aio_write(s->image, off, size, buf, c); +r = rbd_aio_write(s->image, off, size, buf, c); } else { -rbd_aio_create_completion(rcb, (rbd_callback_t) rbd_finish_aiocb, &c); -rbd_aio_read(s->image, off, size, buf, c); +r = rbd_aio_read(s->image, off, size, buf, c); +} + +if (r < 0) { +goto failed; } return &acb->common; + +failed: +qemu_free(rcb); +s->qemu_aio_count--; +qemu_aio_release(acb); +return NULL; } static BlockDriverAIOCB *qemu_rbd_aio_readv(BlockDriverState *bs, -- 1.7.2.3
[Qemu-devel] [PATCH v6 1/4] rbd: use the higher level librbd instead of just librados
librbd stacks on top of librados to provide access to rbd images. Using librbd simplifies the qemu code, and allows qemu to use new versions of the rbd format with few (if any) changes. Reviewed-by: Christian Brunner Signed-off-by: Josh Durgin Signed-off-by: Yehuda Sadeh --- block/rbd.c | 795 +++-- block/rbd_types.h | 71 - configure | 33 +-- 3 files changed, 226 insertions(+), 673 deletions(-) delete mode 100644 block/rbd_types.h diff --git a/block/rbd.c b/block/rbd.c index 249a590..2cee70d 100644 --- a/block/rbd.c +++ b/block/rbd.c @@ -1,20 +1,22 @@ /* * QEMU Block driver for RADOS (Ceph) * - * Copyright (C) 2010 Christian Brunner + * Copyright (C) 2010-2011 Christian Brunner , + * Josh Durgin * * This work is licensed under the terms of the GNU GPL, version 2. See * the COPYING file in the top-level directory. * */ +#include + #include "qemu-common.h" #include "qemu-error.h" -#include "rbd_types.h" #include "block_int.h" -#include +#include @@ -40,6 +42,13 @@ #define OBJ_MAX_SIZE (1UL << OBJ_DEFAULT_OBJ_ORDER) +#define RBD_MAX_CONF_NAME_SIZE 128 +#define RBD_MAX_CONF_VAL_SIZE 512 +#define RBD_MAX_CONF_SIZE 1024 +#define RBD_MAX_POOL_NAME_SIZE 128 +#define RBD_MAX_SNAP_NAME_SIZE 128 +#define RBD_MAX_SNAPS 100 + typedef struct RBDAIOCB { BlockDriverAIOCB common; QEMUBH *bh; @@ -48,7 +57,6 @@ typedef struct RBDAIOCB { char *bounce; int write; int64_t sector_num; -int aiocnt; int error; struct BDRVRBDState *s; int cancelled; @@ -59,7 +67,7 @@ typedef struct RADOSCB { RBDAIOCB *acb; struct BDRVRBDState *s; int done; -int64_t segsize; +int64_t size; char *buf; int ret; } RADOSCB; @@ -69,25 +77,22 @@ typedef struct RADOSCB { typedef struct BDRVRBDState { int fds[2]; -rados_pool_t pool; -rados_pool_t header_pool; -char name[RBD_MAX_OBJ_NAME_SIZE]; -char block_name[RBD_MAX_BLOCK_NAME_SIZE]; -uint64_t size; -uint64_t objsize; +rados_t cluster; +rados_ioctx_t io_ctx; +rbd_image_t image; +char name[RBD_MAX_IMAGE_NAME_SIZE]; int qemu_aio_count; +char *snap; int event_reader_pos; RADOSCB *event_rcb; } BDRVRBDState; -typedef struct rbd_obj_header_ondisk RbdHeader1; - static void rbd_aio_bh_cb(void *opaque); -static int rbd_next_tok(char *dst, int dst_len, -char *src, char delim, -const char *name, -char **p) +static int qemu_rbd_next_tok(char *dst, int dst_len, + char *src, char delim, + const char *name, + char **p) { int l; char *end; @@ -115,10 +120,10 @@ static int rbd_next_tok(char *dst, int dst_len, return 0; } -static int rbd_parsename(const char *filename, - char *pool, int pool_len, - char *snap, int snap_len, - char *name, int name_len) +static int qemu_rbd_parsename(const char *filename, + char *pool, int pool_len, + char *snap, int snap_len, + char *name, int name_len) { const char *start; char *p, *buf; @@ -131,12 +136,12 @@ static int rbd_parsename(const char *filename, buf = qemu_strdup(start); p = buf; -ret = rbd_next_tok(pool, pool_len, p, '/', "pool name", &p); +ret = qemu_rbd_next_tok(pool, pool_len, p, '/', "pool name", &p); if (ret < 0 || !p) { ret = -EINVAL; goto done; } -ret = rbd_next_tok(name, name_len, p, '@', "object name", &p); +ret = qemu_rbd_next_tok(name, name_len, p, '@', "object name", &p); if (ret < 0) { goto done; } @@ -145,123 +150,35 @@ static int rbd_parsename(const char *filename, goto done; } -ret = rbd_next_tok(snap, snap_len, p, '\0', "snap name", &p); +ret = qemu_rbd_next_tok(snap, snap_len, p, '\0', "snap name", &p); done: qemu_free(buf); return ret; } -static int create_tmap_op(uint8_t op, const char *name, char **tmap_desc) -{ -uint32_t len = strlen(name); -uint32_t len_le = cpu_to_le32(len); -/* total_len = encoding op + name + empty buffer */ -uint32_t total_len = 1 + (sizeof(uint32_t) + len) + sizeof(uint32_t); -uint8_t *desc = NULL; - -desc = qemu_malloc(total_len); - -*tmap_desc = (char *)desc; - -*desc = op; -desc++; -memcpy(desc, &len_le, sizeof(len_le)); -desc += sizeof(len_le); -memcpy(desc, name, len); -desc += len; -len = 0; /* no need for endian conversion for 0 */ -memcpy(desc, &len, sizeof(len)); -desc += sizeof(len); - -return (char *)desc - *tmap_desc; -} - -static void free_tmap_op(char *tmap_desc) -{ -qemu_free(tmap_desc); -} - -static int r
[Qemu-devel] [PATCH v6 2/4] rbd: allow configuration of rados from the rbd filename
The new format is rbd:pool/image[@snapshot][:option1=value1[:option2=value2...]] Each option is used to configure rados, and may be any Ceph option, or "conf". The "conf" option specifies a Ceph configuration file to read. This allows rbd volumes from more than one Ceph cluster to be used by specifying different monitor addresses, as well as having different logging levels or locations for different volumes. Reviewed-by: Christian Brunner Signed-off-by: Josh Durgin --- block/rbd.c | 119 ++ 1 files changed, 102 insertions(+), 17 deletions(-) diff --git a/block/rbd.c b/block/rbd.c index 2cee70d..edf1086 100644 --- a/block/rbd.c +++ b/block/rbd.c @@ -23,13 +23,17 @@ /* * When specifying the image filename use: * - * rbd:poolname/devicename + * rbd:poolname/devicename[@snapshotname][:option1=value1[:option2=value2...]] * * poolname must be the name of an existing rados pool * * devicename is the basename for all objects used to * emulate the raw device. * + * Each option given is used to configure rados, and may be + * any Ceph option, or "conf". The "conf" option specifies + * a Ceph configuration file to read. + * * Metadata information (image size, ...) is stored in an * object with the name "devicename.rbd". * @@ -123,7 +127,8 @@ static int qemu_rbd_next_tok(char *dst, int dst_len, static int qemu_rbd_parsename(const char *filename, char *pool, int pool_len, char *snap, int snap_len, - char *name, int name_len) + char *name, int name_len, + char *conf, int conf_len) { const char *start; char *p, *buf; @@ -135,28 +140,84 @@ static int qemu_rbd_parsename(const char *filename, buf = qemu_strdup(start); p = buf; +*snap = '\0'; +*conf = '\0'; ret = qemu_rbd_next_tok(pool, pool_len, p, '/', "pool name", &p); if (ret < 0 || !p) { ret = -EINVAL; goto done; } -ret = qemu_rbd_next_tok(name, name_len, p, '@', "object name", &p); -if (ret < 0) { -goto done; + +if (strchr(p, '@')) { +ret = qemu_rbd_next_tok(name, name_len, p, '@', "object name", &p); +if (ret < 0) { +goto done; +} +ret = qemu_rbd_next_tok(snap, snap_len, p, ':', "snap name", &p); +} else { +ret = qemu_rbd_next_tok(name, name_len, p, ':', "object name", &p); } -if (!p) { -*snap = '\0'; +if (ret < 0 || !p) { goto done; } -ret = qemu_rbd_next_tok(snap, snap_len, p, '\0', "snap name", &p); +ret = qemu_rbd_next_tok(conf, conf_len, p, '\0', "configuration", &p); done: qemu_free(buf); return ret; } +static int qemu_rbd_set_conf(rados_t cluster, const char *conf) +{ +char *p, *buf; +char name[RBD_MAX_CONF_NAME_SIZE]; +char value[RBD_MAX_CONF_VAL_SIZE]; +int ret = 0; + +buf = qemu_strdup(conf); +p = buf; + +while (p) { +ret = qemu_rbd_next_tok(name, sizeof(name), p, +'=', "conf option name", &p); +if (ret < 0) { +break; +} + +if (!p) { +error_report("conf option %s has no value", name); +ret = -EINVAL; +break; +} + +ret = qemu_rbd_next_tok(value, sizeof(value), p, +':', "conf option value", &p); +if (ret < 0) { +break; +} + +if (strcmp(name, "conf")) { +ret = rados_conf_set(cluster, name, value); +if (ret < 0) { +error_report("invalid conf option %s", name); +ret = -EINVAL; +break; +} +} else { +ret = rados_conf_read_file(cluster, value); +if (ret < 0) { +error_report("error reading conf file %s", value); +break; +} +} +} + +qemu_free(buf); +return ret; +} + static int qemu_rbd_create(const char *filename, QEMUOptionParameter *options) { int64_t bytes = 0; @@ -165,6 +226,7 @@ static int qemu_rbd_create(const char *filename, QEMUOptionParameter *options) char pool[RBD_MAX_POOL_NAME_SIZE]; char name[RBD_MAX_IMAGE_NAME_SIZE]; char snap_buf[RBD_MAX_SNAP_NAME_SIZE]; +char conf[RBD_MAX_CONF_SIZE]; char *snap = NULL; rados_t cluster; rados_ioctx_t io_ctx; @@ -172,7 +234,8 @@ static int qemu_rbd_create(const char *filename, QEMUOptionParameter *options) if (qemu_rbd_parsename(filename, pool, sizeof(pool), snap_buf, sizeof(snap_buf), - name, sizeof(name)) < 0) { + name, sizeof(name), + conf, sizeof(conf)) < 0) { return -EINVAL; } if (snap_buf[0] != '\0') { @@ -205,8 +268
[Qemu-devel] [PATCH v6 4/4] rbd: Add bdrv_truncate implementation
Reviewed-by: Christian Brunner Signed-off-by: Josh Durgin --- block/rbd.c | 14 ++ 1 files changed, 14 insertions(+), 0 deletions(-) diff --git a/block/rbd.c b/block/rbd.c index f4da6ab..bdc448a 100644 --- a/block/rbd.c +++ b/block/rbd.c @@ -688,6 +688,19 @@ static int64_t qemu_rbd_getlength(BlockDriverState *bs) return info.size; } +static int qemu_rbd_truncate(BlockDriverState *bs, int64_t offset) +{ +BDRVRBDState *s = bs->opaque; +int r; + +r = rbd_resize(s->image, offset); +if (r < 0) { +return r; +} + +return 0; +} + static int qemu_rbd_snap_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) { @@ -784,6 +797,7 @@ static BlockDriver bdrv_rbd = { .bdrv_get_info = qemu_rbd_getinfo, .create_options = qemu_rbd_create_options, .bdrv_getlength = qemu_rbd_getlength, +.bdrv_truncate = qemu_rbd_truncate, .protocol_name = "rbd", .bdrv_aio_readv = qemu_rbd_aio_readv, -- 1.7.2.3
[Qemu-devel] [PATCH v6 0/4] rbd improvements
This patchset moves the complexity of the rbd format into librbd and adds truncation support. Changes since v5: * compare full string, not prefix, with "conf" in 2/4 * when truncate fails, just return librbd's error Changes since v4: * fixed cosmetic issues pointed out by Christian Brunner Changes since v3: * trivially rebased * updated copyright header Changes since v2: * return values are checked in rbd_aio_rw_vector * bdrv_truncate added Josh Durgin (4): rbd: use the higher level librbd instead of just librados rbd: allow configuration of rados from the rbd filename rbd: check return values when scheduling aio rbd: Add bdrv_truncate implementation block/rbd.c | 896 +++-- block/rbd_types.h | 71 - configure | 33 +-- 3 files changed, 334 insertions(+), 666 deletions(-) delete mode 100644 block/rbd_types.h -- 1.7.2.3
Re: [Qemu-devel] [PATCH v5 4/4] rbd: Add bdrv_truncate implementation
On 05/26/2011 01:05 AM, Kevin Wolf wrote: Am 25.05.2011 22:34, schrieb Josh Durgin: Signed-off-by: Josh Durgin --- block/rbd.c | 15 +++ 1 files changed, 15 insertions(+), 0 deletions(-) diff --git a/block/rbd.c b/block/rbd.c index a44d160..b95b1eb 100644 --- a/block/rbd.c +++ b/block/rbd.c @@ -688,6 +688,20 @@ static int64_t qemu_rbd_getlength(BlockDriverState *bs) return info.size; } +static int qemu_rbd_truncate(BlockDriverState *bs, int64_t offset) +{ +BDRVRBDState *s = bs->opaque; +int r; + +r = rbd_resize(s->image, offset); +if (r< 0) { +error_report("failed to resize rbd image"); +return -EIO; +} Don't print an error message here. The caller will do it, too, so we end up with two error messages saying the same. Fixed. What kind of error code does rbd_resize return? If it is a valid errno value, you should return r instead of turning it into EIO. Kevin The error code is a standard errno value. Josh
Re: [Qemu-devel] [PATCH v5 2/4] rbd: allow configuration of rados from the rbd filename
On 05/26/2011 01:13 AM, Kevin Wolf wrote: Am 25.05.2011 22:34, schrieb Josh Durgin: The new format is rbd:pool/image[@snapshot][:option1=value1[:option2=value2...]] Each option is used to configure rados, and may be any Ceph option, or "conf". The "conf" option specifies a Ceph configuration file to read. This allows rbd volumes from more than one Ceph cluster to be used by specifying different monitor addresses, as well as having different logging levels or locations for different volumes. Signed-off-by: Josh Durgin --- block/rbd.c | 119 ++ 1 files changed, 102 insertions(+), 17 deletions(-) diff --git a/block/rbd.c b/block/rbd.c index 2cee70d..d346a21 100644 --- a/block/rbd.c +++ b/block/rbd.c @@ -23,13 +23,17 @@ /* * When specifying the image filename use: * - * rbd:poolname/devicename + * rbd:poolname/devicename[@snapshotname][:option1=value1[:option2=value2...]] * * poolname must be the name of an existing rados pool * * devicename is the basename for all objects used to * emulate the raw device. * + * Each option given is used to configure rados, and may be + * any Ceph option, or "conf". The "conf" option specifies + * a Ceph configuration file to read. + * * Metadata information (image size, ...) is stored in an * object with the name "devicename.rbd". * @@ -123,7 +127,8 @@ static int qemu_rbd_next_tok(char *dst, int dst_len, static int qemu_rbd_parsename(const char *filename, char *pool, int pool_len, char *snap, int snap_len, - char *name, int name_len) + char *name, int name_len, + char *conf, int conf_len) { const char *start; char *p, *buf; @@ -135,28 +140,84 @@ static int qemu_rbd_parsename(const char *filename, buf = qemu_strdup(start); p = buf; +*snap = '\0'; +*conf = '\0'; ret = qemu_rbd_next_tok(pool, pool_len, p, '/', "pool name",&p); if (ret< 0 || !p) { ret = -EINVAL; goto done; } -ret = qemu_rbd_next_tok(name, name_len, p, '@', "object name",&p); -if (ret< 0) { -goto done; + +if (strchr(p, '@')) { +ret = qemu_rbd_next_tok(name, name_len, p, '@', "object name",&p); +if (ret< 0) { +goto done; +} +ret = qemu_rbd_next_tok(snap, snap_len, p, ':', "snap name",&p); +} else { +ret = qemu_rbd_next_tok(name, name_len, p, ':', "object name",&p); } -if (!p) { -*snap = '\0'; +if (ret< 0 || !p) { goto done; } -ret = qemu_rbd_next_tok(snap, snap_len, p, '\0', "snap name",&p); +ret = qemu_rbd_next_tok(conf, conf_len, p, '\0', "configuration",&p); done: qemu_free(buf); return ret; } +static int qemu_rbd_set_conf(rados_t cluster, const char *conf) +{ +char *p, *buf; +char name[RBD_MAX_CONF_NAME_SIZE]; +char value[RBD_MAX_CONF_VAL_SIZE]; +int ret = 0; + +buf = qemu_strdup(conf); +p = buf; + +while (p) { +ret = qemu_rbd_next_tok(name, sizeof(name), p, +'=', "conf option name",&p); +if (ret< 0) { +break; +} + +if (!p) { +error_report("conf option %s has no value", name); +ret = -EINVAL; +break; +} + +ret = qemu_rbd_next_tok(value, sizeof(value), p, +':', "conf option value",&p); +if (ret< 0) { +break; +} + +if (strncmp(name, "conf", strlen("conf"))) { Do you really only want to check if name _starts_ with "conf"? Kevin That should just be strcmp. Josh
[Qemu-devel] [Bug 726962] Re: darwin user i386 no such directory
same with 0.14.1 with Mac OS X 10.6.7. target ppc-darwin-user has the same problem: CCppc-darwin-user/main.o cc1: warning: /Users/michael/Downloads/qemu-0.14.1/darwin-user/ppc: No such file or directory In file included from /Users/michael/Downloads/qemu-0.14.1/target-ppc/cpu.h:855, from /Users/michael/Downloads/qemu-0.14.1/darwin-user/qemu.h:7, from /Users/michael/Downloads/qemu-0.14.1/darwin-user/main.c:30: ../cpu-all.h:622:24: error: qemu-types.h: No such file or directory In file included from /Users/michael/Downloads/qemu-0.14.1/target-ppc/cpu.h:855, from /Users/michael/Downloads/qemu-0.14.1/darwin-user/qemu.h:7, from /Users/michael/Downloads/qemu-0.14.1/darwin-user/main.c:30: ../cpu-all.h:756: error: expected declaration specifiers or ‘...’ before ‘abi_ulong’ ../cpu-all.h:757: error: expected declaration specifiers or ‘...’ before ‘abi_ulong’ In file included from /Users/michael/Downloads/qemu-0.14.1/darwin-user/qemu.h:9, from /Users/michael/Downloads/qemu-0.14.1/darwin-user/main.c:30: ../thunk.h: In function ‘thunk_type_size’: ../thunk.h:104: error: ‘TARGET_ABI_BITS’ undeclared (first use in this function) ../thunk.h:104: error: (Each undeclared identifier is reported only once ../thunk.h:104: error: for each function it appears in.) ../thunk.h: In function ‘thunk_type_align’: ../thunk.h:141: error: ‘TARGET_ABI_BITS’ undeclared (first use in this function) In file included from /Users/michael/Downloads/qemu-0.14.1/darwin-user/main.c:30: /Users/michael/Downloads/qemu-0.14.1/darwin-user/qemu.h: At top level: /Users/michael/Downloads/qemu-0.14.1/darwin-user/qemu.h:100: warning: ‘struct sigaltstack’ declared inside parameter list /Users/michael/Downloads/qemu-0.14.1/darwin-user/qemu.h:100: warning: its scope is only this definition or declaration, which is probably not what you want /Users/michael/Downloads/qemu-0.14.1/darwin-user/qemu.h:109: warning: redundant redeclaration of ‘init_paths’ ../qemu-common.h:172: warning: previous declaration of ‘init_paths’ was here /Users/michael/Downloads/qemu-0.14.1/darwin-user/qemu.h:110: warning: redundant redeclaration of ‘path’ ../qemu-common.h:173: warning: previous declaration of ‘path’ was here /Users/michael/Downloads/qemu-0.14.1/darwin-user/main.c:74: warning: no previous prototype for ‘cpu_get_pic_interrupt’ /Users/michael/Downloads/qemu-0.14.1/darwin-user/main.c: In function ‘cpu_loop’: /Users/michael/Downloads/qemu-0.14.1/darwin-user/main.c:164: warning: cast to pointer from integer of different size /Users/michael/Downloads/qemu-0.14.1/darwin-user/main.c:173: warning: cast to pointer from integer of different size /Users/michael/Downloads/qemu-0.14.1/darwin-user/main.c:184: warning: cast to pointer from integer of different size /Users/michael/Downloads/qemu-0.14.1/darwin-user/main.c:280: warning: cast to pointer from integer of different size /Users/michael/Downloads/qemu-0.14.1/darwin-user/main.c:288: warning: cast to pointer from integer of different size /Users/michael/Downloads/qemu-0.14.1/darwin-user/main.c:300: warning: cast to pointer from integer of different size /Users/michael/Downloads/qemu-0.14.1/darwin-user/main.c:331: warning: cast to pointer from integer of different size /Users/michael/Downloads/qemu-0.14.1/darwin-user/main.c:393: warning: cast to pointer from integer of different size /Users/michael/Downloads/qemu-0.14.1/darwin-user/main.c: In function ‘main’: /Users/michael/Downloads/qemu-0.14.1/darwin-user/main.c:777: warning: assignment discards qualifiers from pointer target type make[1]: *** [main.o] Error 1 make: *** [subdir-ppc-darwin-user] Error 2 -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/726962 Title: darwin user i386 no such directory Status in QEMU: New Bug description: qemu-0.14.0/darwin-user/i386: No such file or directory I tried the current sources and the "stable". I am running mac os x 10.5.8 -- 64 bit on macbook pro. fusion works, virtualbox works, Q did on i386, but not 64 bit. I had "fink" installed, and changed /sw to be after /usr/local/bin so that I could put up the latest gmake to get around fink's problems. It won't compile with gcc42, so I am using XCode 4.0.1. What am I doing wrong? What did I miss? commit 417131fb9ad3f6dd7177a338cc5f143dec4d75f0 Author: Stefan Weil Date: Fri Feb 25 16:30:20 2011 -0600
[Qemu-devel] [Bug 788881] [NEW] i386-bsd-user and similar crash on Mac OS X
Public bug reported: 0.14.1 crashes on Mac OS X 64bit with some targets (*-bsd-user): CCi386-bsd-user/cpu-exec.o /Users/michael/Downloads/qemu-0.14.1/cpu-exec.c: In function ‘cpu_x86_signal_handler’: /Users/michael/Downloads/qemu-0.14.1/cpu-exec.c:895: error: dereferencing pointer to incomplete type /Users/michael/Downloads/qemu-0.14.1/cpu-exec.c:895: error: ‘REG_RIP’ undeclared (first use in this function) /Users/michael/Downloads/qemu-0.14.1/cpu-exec.c:895: error: (Each undeclared identifier is reported only once /Users/michael/Downloads/qemu-0.14.1/cpu-exec.c:895: error: for each function it appears in.) /Users/michael/Downloads/qemu-0.14.1/cpu-exec.c:897: error: dereferencing pointer to incomplete type /Users/michael/Downloads/qemu-0.14.1/cpu-exec.c:897: error: ‘REG_TRAPNO’ undeclared (first use in this function) /Users/michael/Downloads/qemu-0.14.1/cpu-exec.c:898: error: dereferencing pointer to incomplete type /Users/michael/Downloads/qemu-0.14.1/cpu-exec.c:898: error: ‘REG_ERR’ undeclared (first use in this function) /Users/michael/Downloads/qemu-0.14.1/cpu-exec.c:899: error: dereferencing pointer to incomplete type make[1]: *** [cpu-exec.o] Error 1 ** Affects: qemu Importance: Undecided Status: New -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/71 Title: i386-bsd-user and similar crash on Mac OS X Status in QEMU: New Bug description: 0.14.1 crashes on Mac OS X 64bit with some targets (*-bsd-user): CCi386-bsd-user/cpu-exec.o /Users/michael/Downloads/qemu-0.14.1/cpu-exec.c: In function ‘cpu_x86_signal_handler’: /Users/michael/Downloads/qemu-0.14.1/cpu-exec.c:895: error: dereferencing pointer to incomplete type /Users/michael/Downloads/qemu-0.14.1/cpu-exec.c:895: error: ‘REG_RIP’ undeclared (first use in this function) /Users/michael/Downloads/qemu-0.14.1/cpu-exec.c:895: error: (Each undeclared identifier is reported only once /Users/michael/Downloads/qemu-0.14.1/cpu-exec.c:895: error: for each function it appears in.) /Users/michael/Downloads/qemu-0.14.1/cpu-exec.c:897: error: dereferencing pointer to incomplete type /Users/michael/Downloads/qemu-0.14.1/cpu-exec.c:897: error: ‘REG_TRAPNO’ undeclared (first use in this function) /Users/michael/Downloads/qemu-0.14.1/cpu-exec.c:898: error: dereferencing pointer to incomplete type /Users/michael/Downloads/qemu-0.14.1/cpu-exec.c:898: error: ‘REG_ERR’ undeclared (first use in this function) /Users/michael/Downloads/qemu-0.14.1/cpu-exec.c:899: error: dereferencing pointer to incomplete type make[1]: *** [cpu-exec.o] Error 1
[Qemu-devel] Please help!
Hi everybody Where can I find the codes for monitor command "log in_asm". I want to know how QEMU monitor capture the executed instruction in ASM in a simultaneous way rather than a bunch of Logs. Thank you very much for your time. Best wishes
Re: [Qemu-devel] [PATCH] host-pcc: enable building with -m32 or -m64
On 05/26/2011 05:24 PM, Andreas Färber wrote: Am 26.05.2011 um 22:31 schrieb Stefan Berger: On 05/26/2011 04:20 PM, Andreas Färber wrote: Am 26.05.2011 um 21:00 schrieb Stefan Berger: With the below patch I can build either ppc (-m32) or ppc64 (-m64) versions of Qemu (on a ppc64 host) when passing these compiler flags via 'configure ... --extra-cflags="-m32"'. You probably meant "without passing"? Nack. Please don't hardcode -mXX in configure, it's -arch ppc vs. -arch ppc64 on my host/gcc. What's wrong with passing --extra-cflags? I posted the following patch today for compiling libcacard with -m32 on a 64 bit machine. http://lists.nongnu.org/archive/html/qemu-devel/2011-05/msg02909.html It adds LDFLAGS. This works fine on x86-64. Then trying this out on ppc64 with -m32 in extra-cflags I find the following in config-host.mak [...] HELPER_CFLAGS= LDFLAGS=-Wl,--warn-common -g ARLIBS_BEGIN= [...] The -m32 doesn't make it into LDFLAGS. The below patch fixed it for me following the pattern of x86-64 and i686 a bit further up in the case statement in configure. Erm, you did try --extra-ldflags for LDFLAGS, did you? That --extra-cflags doesn't end up there is intentional! No, I didn't. Here's what happened. On x86_64 host I used to be able to compile 32bit executables with --extra-cflags="-m32". That stopped working when libcacard showed up -- I posted a patch today -- only the linking of vscclient in libcacard/ didn't work. The "work-around" before the patch was --disable-smartcard. Now taking that same habit of passing --extra-cflags="-m32" to the ppc64 machine again didn't work, but was broken somewhere else. So this is where this is all coming from. Stefan Andreas
Re: [Qemu-devel] [PATCH 00/12] target-s390x: Several small fixes
Am 26.05.2011 um 00:17 schrieb Alexander Graf: On 26.05.2011, at 00:10, Peter Maydell wrote: On 25 May 2011 21:25, Stefan Weil wrote: Feel free to combine patches if larger patches are preferred. I'd vote for combining at least 03..12, having nine patches all of which have the same summary line is a bit confusing :-) I actually like them as individual patches. Makes bisecting a lot easier :). Stefan, could you add the function name or some other discriminator to the subject then, please? Andreas
Re: [Qemu-devel] [PATCH] target-ppc: Fix compilation error with --enable-debug
Am 26.05.2011 um 20:28 schrieb Stefan Weil : > Am 26.05.2011 20:05, schrieb Peter Maydell: >> The PPC helper functions booke206_tlbflush and booke_setpid both >> take an i32 argument, so we need to use TCGv_i32 rather than TCGv, >> to avoid a compilation failure when compiling in debug mode. >> >> Signed-off-by: Peter Maydell >> --- >> target-ppc/translate_init.c | 8 >> 1 files changed, 4 insertions(+), 4 deletions(-) >> > > See http://patchwork.ozlabs.org/patch/96665/ > > It's a waste of time if build fixes take more than 3 days to get committed. > > The typical process - several days until the maintainer accepts it, more > days until there is a pull request, even more days until it is pulled - > is good enough for new features, but too slow for bug fixes, especially > when they fix broken builds. I agree, but I think the solution to the problem is to not break builds. I'm currently spending all day setting up kvm-autotest for automated regression testing and am eagerly waiting on Stefan to get the buildbot stuff rolling on submaintainer trees. With those two things in place, we should be a lot safer. Alex >
Re: [Qemu-devel] [PATCH] ppc host, target-ppc: fix building of kvm.c
Am 26.05.2011 um 20:50 schrieb Stefan Berger : > Below patch fixes the following error when building on a ppc host: > > cc1: warnings being treated as errors > /root/qemu/qemu-git/target-ppc/kvm.c: In function kvm_arch_get_registers: > /root/qemu/qemu-git/target-ppc/kvm.c:188: error: unused variable sregs > > Signed-off-by: Stefan Berger Thanks :). I already posted a patch on the list to fix this issue, so this will be fixed soon. For the meantime, you could just acked-by mine :) Alex >
Re: [Qemu-devel] [PATCH] host-pcc: enable building with -m32 or -m64
Am 26.05.2011 um 22:31 schrieb Stefan Berger: On 05/26/2011 04:20 PM, Andreas Färber wrote: Am 26.05.2011 um 21:00 schrieb Stefan Berger: With the below patch I can build either ppc (-m32) or ppc64 (-m64) versions of Qemu (on a ppc64 host) when passing these compiler flags via 'configure ... --extra-cflags="-m32"'. You probably meant "without passing"? Nack. Please don't hardcode -mXX in configure, it's -arch ppc vs. - arch ppc64 on my host/gcc. What's wrong with passing --extra-cflags? I posted the following patch today for compiling libcacard with -m32 on a 64 bit machine. http://lists.nongnu.org/archive/html/qemu-devel/2011-05/msg02909.html It adds LDFLAGS. This works fine on x86-64. Then trying this out on ppc64 with -m32 in extra-cflags I find the following in config- host.mak [...] HELPER_CFLAGS= LDFLAGS=-Wl,--warn-common -g ARLIBS_BEGIN= [...] The -m32 doesn't make it into LDFLAGS. The below patch fixed it for me following the pattern of x86-64 and i686 a bit further up in the case statement in configure. Erm, you did try --extra-ldflags for LDFLAGS, did you? That --extra- cflags doesn't end up there is intentional! Andreas
Re: [Qemu-devel] [PATCH 5/6] Do constant folding for shift operations.
On 05/26/2011 01:25 PM, Blue Swirl wrote: >> I don't see the point. The C99 implementation defined escape hatch >> exists for weird cpus. Which we won't be supporting as a QEMU host. > > Maybe not, but a compiler with this property could arrive. For > example, GCC developers could decide that since this weirdness is > allowed by the standard, it may be implemented as well. If you like, you can write a configure test for it. But, honestly, essentially every place in qemu that uses shifts on signed types would have to be audited. Really. The C99 hook exists to efficiently support targets that don't have arithmetic shift operations. Honestly. r~
Re: [Qemu-devel] [PATCH 05/18] ide: Turn debug messages into assertions
On Thu, 19 May 2011 14:33:19 +0200 Kevin Wolf wrote: > These printfs aren't really debug messages, but clearly indicate a bug if they > ever become effective. Then we have a bug somewhere, starting a VM with: # qemu -hda disks/test.img -enable-kvm -m 1G -cdrom /dev/sr0 Where the host's CDROM is empty, triggers one of these asserts: qmp-unstable/hw/ide/pci.c:299: bmdma_cmd_writeb: Assertion `bm->bus->dma->aiocb == ((void *)0)' > Noone uses DEBUG_IDE, let's re-enable the check > unconditionally and make it an assertion instead of printfs in the device > emulation. > > Signed-off-by: Kevin Wolf > Reviewed-by: Stefan Hajnoczi > --- > hw/ide/pci.c |8 ++-- > 1 files changed, 2 insertions(+), 6 deletions(-) > > diff --git a/hw/ide/pci.c b/hw/ide/pci.c > index f5ac932..a4726ad 100644 > --- a/hw/ide/pci.c > +++ b/hw/ide/pci.c > @@ -296,12 +296,8 @@ void bmdma_cmd_writeb(void *opaque, uint32_t addr, > uint32_t val) > */ > if (bm->bus->dma->aiocb) { > qemu_aio_flush(); > -#ifdef DEBUG_IDE > -if (bm->bus->dma->aiocb) > -printf("ide_dma_cancel: aiocb still pending\n"); > -if (bm->status & BM_STATUS_DMAING) > -printf("ide_dma_cancel: BM_STATUS_DMAING still > pending\n"); > -#endif > +assert(bm->bus->dma->aiocb == NULL); > +assert((bm->status & BM_STATUS_DMAING) == 0); > } > } else { > bm->cur_addr = bm->addr;
Re: [Qemu-devel] [PATCH] host-pcc: enable building with -m32 or -m64
On Thu, 26 May 2011, Stefan Berger wrote: > On 05/26/2011 04:20 PM, Andreas F?rber wrote: > > Am 26.05.2011 um 21:00 schrieb Stefan Berger: > > > > > With the below patch I can build either ppc (-m32) or ppc64 (-m64) > > > versions of Qemu (on a ppc64 host) when passing these compiler flags via > > > 'configure ... --extra-cflags="-m32"'. > > > > You probably meant "without passing"? > > > > Nack. Please don't hardcode -mXX in configure, it's -arch ppc vs. -arch > > ppc64 on my host/gcc. What's wrong with passing --extra-cflags? > > > I posted the following patch today for compiling libcacard with -m32 on a 64 > bit machine. > > http://lists.nongnu.org/archive/html/qemu-devel/2011-05/msg02909.html > > It adds LDFLAGS. This works fine on x86-64. Then trying this out on ppc64 with > -m32 in extra-cflags I find the following in config-host.mak > > [...] > HELPER_CFLAGS= > LDFLAGS=-Wl,--warn-common -g > ARLIBS_BEGIN= > [...] > > The -m32 doesn't make it into LDFLAGS. The below patch fixed it for me > following the pattern of x86-64 and i686 a bit further up in the case > statement in configure. [..snip..] You can just do `./configure --cc="gcc -m[32|64]"' -- mailto:av1...@comtv.ru
Re: [Qemu-devel] [PATCH] host-pcc: enable building with -m32 or -m64
On 05/26/2011 04:20 PM, Andreas Färber wrote: Am 26.05.2011 um 21:00 schrieb Stefan Berger: With the below patch I can build either ppc (-m32) or ppc64 (-m64) versions of Qemu (on a ppc64 host) when passing these compiler flags via 'configure ... --extra-cflags="-m32"'. You probably meant "without passing"? Nack. Please don't hardcode -mXX in configure, it's -arch ppc vs. -arch ppc64 on my host/gcc. What's wrong with passing --extra-cflags? I posted the following patch today for compiling libcacard with -m32 on a 64 bit machine. http://lists.nongnu.org/archive/html/qemu-devel/2011-05/msg02909.html It adds LDFLAGS. This works fine on x86-64. Then trying this out on ppc64 with -m32 in extra-cflags I find the following in config-host.mak [...] HELPER_CFLAGS= LDFLAGS=-Wl,--warn-common -g ARLIBS_BEGIN= [...] The -m32 doesn't make it into LDFLAGS. The below patch fixed it for me following the pattern of x86-64 and i686 a bit further up in the case statement in configure. Stefan Andreas Signed-off-by: Stefan Berger --- configure |9 - 1 file changed, 8 insertions(+), 1 deletion(-) Index: qemu-git/configure === --- qemu-git.orig/configure +++ qemu-git/configure @@ -807,7 +807,14 @@ case "$cpu" in arm*) host_guest_base="yes" ;; -ppc*) +ppc) + QEMU_CFLAGS="-m32 $QEMU_CFLAGS" + LDFLAGS="-m32 $LDFLAGS" + host_guest_base="yes" + ;; +ppc64) + QEMU_CFLAGS="-m64 $QEMU_CFLAGS" + LDFLAGS="-m64 $LDFLAGS" host_guest_base="yes" ;; mips*)
Re: [Qemu-devel] Multi heterogenous CPU archs for SoC sim?
On Thu, May 26, 2011 at 11:07 PM, Lluís wrote: > Blue Swirl writes: > >> On Wed, May 25, 2011 at 10:20 PM, Peter Maydell >> wrote: >>> On 25 May 2011 19:44, Greg McGary wrote: I would like to create a QEMU model of an SoC that has several CPU cores having different architectures. I'm guessing this can be done. >>> >>> It's not supported currently as far as I'm aware. There was >>> at least one paper at the QEMU Forum earlier this year describing >>> an approach to multi-CPU environments (embedding QEMU into a >>> SystemC world) that basically saved and restored all QEMU's >>> global variables every time it switched cores... >>> >>> It would be good if it was supported in QEMU proper, but I >>> suspect you may be in for some large-scale restructuring work. > >> One of the long standing goals for QEMU has been to be able to use a >> single executable to emulate multiple architectures. I think for >> example the lines like >> #define cpu_init cpu_sparc_init >> #define cpu_exec cpu_sparc_exec >> etc. stand for this purpose, so there has been some consideration for this. > > Nicely handling per-arch functions would be one of the benefits of using > C++ in QEMU (I know, it's sufficient but not necessary). What were the > conclusions regarding such a change? I don't think the discussions gave enough motivation for the change. There's resistance to qdevification already and that is far from a real object model.
Re: [Qemu-devel] [PATCH 5/6] Do constant folding for shift operations.
On Thu, May 26, 2011 at 11:10 PM, Richard Henderson wrote: > On 05/26/2011 12:14 PM, Blue Swirl wrote: >> On Thu, May 26, 2011 at 4:56 PM, Richard Henderson wrote: >>> On 05/26/2011 05:36 AM, Kirill Batuzov wrote: > x = (int32_t)x >> (int32_t)y; > This expression has an implementation-defined behavior accroding to C99 6.5.7 so we decided to emulate signed shifts by hand. >>> >>> Technically, yes. In practice, no. GCC, ICC, LLVM, MSVC all know >>> what the user wants here and will implement it "properly". >> >> Can't this be probed by configure? Then a wrapper could be introduced >> for signed shifts. > > I don't see the point. The C99 implementation defined escape hatch > exists for weird cpus. Which we won't be supporting as a QEMU host. Maybe not, but a compiler with this property could arrive. For example, GCC developers could decide that since this weirdness is allowed by the standard, it may be implemented as well.
[Qemu-devel] Booting custom kernel in qemu
Hello, I'm trying to boot a custom linux kernel in qemu, and I plan to contribute the necessary work to make it work (this is the first step I'm taking to add OS support in qemu). I'm totally new to qemu, and I haven't found enough information to know how to start debugging the thing, so I thought of asking here. I wanted to launch the kernel in a terminal for practical purposes, so I tried: qemu -kernel bzImage -append console=ttyS0 There still was no output in the terminal after that, so I'm planning to attach qemu to gdb, and try to debug it that way. Can you please provide some help on how to debug the kernel in qemu ? -- Apelete
Re: [Qemu-devel] [PATCH v5 01/25] scsi: add tracing of scsi requests
On Thu, May 26, 2011 at 1:56 PM, Paolo Bonzini wrote: > Signed-off-by: Paolo Bonzini > Reviewed-by: Christoph Hellwig > --- > hw/scsi-bus.c | 6 ++ > trace-events | 6 ++ > 2 files changed, 12 insertions(+), 0 deletions(-) > > diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c > index ceeb4ec..0fd85fc 100644 > --- a/hw/scsi-bus.c > +++ b/hw/scsi-bus.c > @@ -4,6 +4,7 @@ > #include "scsi-defs.h" > #include "qdev.h" > #include "blockdev.h" > +#include "trace.h" > > static char *scsibus_get_fw_dev_path(DeviceState *dev); > > @@ -141,6 +142,7 @@ SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, > uint32_t tag, uint32_t l > req->lun = lun; > req->status = -1; > req->enqueued = true; > + trace_scsi_req_alloc(req->dev->id, req->lun, req->tag); > QTAILQ_INSERT_TAIL(&d->requests, req, next); > return req; > } > @@ -159,6 +161,7 @@ SCSIRequest *scsi_req_find(SCSIDevice *d, uint32_t tag) > > static void scsi_req_dequeue(SCSIRequest *req) > { > + trace_scsi_req_dequeue(req->dev->id, req->lun, req->tag); > if (req->enqueued) { > QTAILQ_REMOVE(&req->dev->requests, req, next); > req->enqueued = false; > @@ -195,6 +198,7 @@ static int scsi_req_length(SCSIRequest *req, uint8_t *cmd) > req->cmd.len = 12; > break; > default: > + trace_scsi_req_parse_bad(req->dev->id, req->lun, req->tag, cmd[0]); > return -1; > } > > @@ -392,6 +396,8 @@ int scsi_req_parse(SCSIRequest *req, uint8_t *buf) > memcpy(req->cmd.buf, buf, req->cmd.len); > scsi_req_xfer_mode(req); > req->cmd.lba = scsi_req_lba(req); > + trace_scsi_req_parsed(req->dev->id, req->lun, req->tag, buf[0], > + req->cmd.mode, req->cmd.xfer, req->cmd.lba); > return 0; > } > > diff --git a/trace-events b/trace-events > index 385cb00..b11b71d 100644 > --- a/trace-events > +++ b/trace-events > @@ -205,6 +205,12 @@ disable usb_set_config(int addr, int config, int ret) > "dev %d, config %d, ret %d > disable usb_clear_device_feature(int addr, int feature, int ret) "dev %d, > feature %d, ret %d" > disable usb_set_device_feature(int addr, int feature, int ret) "dev %d, > feature %d, ret %d" > > +# hw/scsi-bus.c > +disable scsi_req_alloc(int target, int lun, int tag) "target %d lun %d tag > %d" > +disable scsi_req_dequeue(int target, int lun, int tag) "target %d lun %d tag > %d" > +disable scsi_req_parsed(int target, int lun, int tag, int cmd, int mode, int > xfer, uint64_t lba) "target %d lun %d tag %d command %d dir %d length %d lba > %"PRIu64"" > +disable scsi_req_parse_bad(int target, int lun, int tag, int cmd) "target %d > lun %d tag %d command %d" Build fails with simpletrace enabled: CCoslib-posix.o cc1: warnings being treated as errors In file included from /src/qemu/oslib-posix.c:32: ./trace.h: In function 'trace_scsi_req_parsed': ./trace.h:716: error: implicit declaration of function 'trace7' ./trace.h:716: error: nested extern declaration of 'trace7'
Re: [Qemu-devel] [PATCH] host-pcc: enable building with -m32 or -m64
Am 26.05.2011 um 21:00 schrieb Stefan Berger: With the below patch I can build either ppc (-m32) or ppc64 (-m64) versions of Qemu (on a ppc64 host) when passing these compiler flags via 'configure ... --extra-cflags="-m32"'. You probably meant "without passing"? Nack. Please don't hardcode -mXX in configure, it's -arch ppc vs. - arch ppc64 on my host/gcc. What's wrong with passing --extra-cflags? Andreas Signed-off-by: Stefan Berger --- configure |9 - 1 file changed, 8 insertions(+), 1 deletion(-) Index: qemu-git/configure === --- qemu-git.orig/configure +++ qemu-git/configure @@ -807,7 +807,14 @@ case "$cpu" in arm*) host_guest_base="yes" ;; -ppc*) +ppc) + QEMU_CFLAGS="-m32 $QEMU_CFLAGS" + LDFLAGS="-m32 $LDFLAGS" + host_guest_base="yes" + ;; +ppc64) + QEMU_CFLAGS="-m64 $QEMU_CFLAGS" + LDFLAGS="-m64 $LDFLAGS" host_guest_base="yes" ;; mips*)
Re: [Qemu-devel] [PATCH 5/6] Do constant folding for shift operations.
On 05/26/2011 12:14 PM, Blue Swirl wrote: > On Thu, May 26, 2011 at 4:56 PM, Richard Henderson wrote: >> On 05/26/2011 05:36 AM, Kirill Batuzov wrote: x = (int32_t)x >> (int32_t)y; >>> This expression has an implementation-defined behavior accroding to >>> C99 6.5.7 so we decided to emulate signed shifts by hand. >> >> Technically, yes. In practice, no. GCC, ICC, LLVM, MSVC all know >> what the user wants here and will implement it "properly". > > Can't this be probed by configure? Then a wrapper could be introduced > for signed shifts. I don't see the point. The C99 implementation defined escape hatch exists for weird cpus. Which we won't be supporting as a QEMU host. r~
Re: [Qemu-devel] Multi heterogenous CPU archs for SoC sim?
Am 25.05.2011 um 20:44 schrieb Greg McGary: I would like to create a QEMU model of an SoC that has several CPU cores having different architectures. I'm guessing this can be done. In theory, many things are possible. In practice, it's a matter of manhours you're willing to invest. Without further details on your SoC it's hard to provide a useful answer. An SoC with mixed ARM Cortex-M4 and Cortex-M0, for instance, may be much easier to accomplish than mixing architectures with differing endianness and especially bitness. That will likely involve compiling for ceil(bitness) - since I don't see how linking hw/*.o compiled for diffent bit-widths would work - and making sure any lower-bitness architectures continue to work, while probably dropping in overall performance... Andreas
Re: [Qemu-devel] Multi heterogenous CPU archs for SoC sim?
Blue Swirl writes: > On Wed, May 25, 2011 at 10:20 PM, Peter Maydell > wrote: >> On 25 May 2011 19:44, Greg McGary wrote: >>> I would like to create a QEMU model of an SoC that has several >>> CPU cores having different architectures. I'm guessing this >>> can be done. >> >> It's not supported currently as far as I'm aware. There was >> at least one paper at the QEMU Forum earlier this year describing >> an approach to multi-CPU environments (embedding QEMU into a >> SystemC world) that basically saved and restored all QEMU's >> global variables every time it switched cores... >> >> It would be good if it was supported in QEMU proper, but I >> suspect you may be in for some large-scale restructuring work. > One of the long standing goals for QEMU has been to be able to use a > single executable to emulate multiple architectures. I think for > example the lines like > #define cpu_init cpu_sparc_init > #define cpu_exec cpu_sparc_exec > etc. stand for this purpose, so there has been some consideration for this. Nicely handling per-arch functions would be one of the benefits of using C++ in QEMU (I know, it's sufficient but not necessary). What were the conclusions regarding such a change? Lluis -- "And it's much the same thing with knowledge, for whenever you learn something new, the whole world becomes that much richer." -- The Princess of Pure Reason, as told by Norton Juster in The Phantom Tollbooth
Re: [Qemu-devel] [PATCH 0/6] target-arm: reduce usage of global env
On 25 May 2011 17:00, Peter Maydell wrote: > This patchset is largely aimed at rolling back the changes from an > earlier patchset of mine: > http://lists.gnu.org/archive/html/qemu-devel/2011-04/msg00244.html Some of these patches include the same TCGv_i32/_ptr error fixed in http://patchwork.ozlabs.org/patch/97559/; I'll submit a v2 once that patch has been committed. -- PMM
Re: [Qemu-devel] [PATCH 0/6] target-arm: reduce usage of global env
On 26 May 2011 20:01, Blue Swirl wrote: > On Wed, May 25, 2011 at 7:00 PM, Peter Maydell > wrote: >> This obviously still leaves some global CPUState use in op_helper.c, >> but it's a move in the right direction. > > Have you seen any measurable changes in performance? The discussion > about the performance effect of changes like this was not very > conclusive. Nope, I haven't measured. I was persuaded of the advantages of dropping global CPUState purely for (a) consistency and (b) avoiding nasty hacks. -- PMM
Re: [Qemu-devel] [PATCH] host-pcc: enable building with -m32 or -m64
On 05/26/2011 03:14 PM, malc wrote: On Thu, 26 May 2011, Stefan Berger wrote: With the below patch I can build either ppc (-m32) or ppc64 (-m64) versions of Qemu (on a ppc64 host) when passing these compiler flags via 'configure ... --extra-cflags="-m32"'. Signed-off-by: Stefan Berger --- configure |9 - 1 file changed, 8 insertions(+), 1 deletion(-) Index: qemu-git/configure === --- qemu-git.orig/configure +++ qemu-git/configure @@ -807,7 +807,14 @@ case "$cpu" in arm*) host_guest_base="yes" ;; -ppc*) +ppc) + QEMU_CFLAGS="-m32 $QEMU_CFLAGS" + LDFLAGS="-m32 $LDFLAGS" + host_guest_base="yes" + ;; +ppc64) + QEMU_CFLAGS="-m64 $QEMU_CFLAGS" + LDFLAGS="-m64 $LDFLAGS" host_guest_base="yes" ;; mips*) This isn't right, if one has particular toolchain and wants to build something that defaults to a different bitlength he should be able to do that, this patch attempts to outsmart the defaults and furthermore prevents one from overriding the settings. P.S. host-pcc... pcc? P.P.S. On the ppc64 machine i have, gcc defaults to 32bit and for a good reason - 64bit code is quite a bit slower when running typical workloads (64bit guest not being one of them though) Is it possible to change my ppc64 gcc compiler to produce 32bit binaries by default -- how? I'd like to test this case because for me not passing any parameters via --extra-cflags defaults to the ppc64 case above - obviously it will produce 64 bit binaries by default. -m32 then ends up in the ppc) case, -m64 again in the ppc64) case. Stefan
Re: [Qemu-devel] [PATCH 0/3]: QMP: Introduce inject-nmi command
On Thu, May 26, 2011 at 8:25 PM, Markus Armbruster wrote: > Luiz Capitulino writes: > >> On Fri, 6 May 2011 18:36:31 +0300 >> Blue Swirl wrote: >> >>> On Fri, May 6, 2011 at 12:08 PM, Markus Armbruster >>> wrote: >>> > Blue Swirl writes: >>> > >>> >> On Mon, May 2, 2011 at 6:57 PM, Luiz Capitulino >>> >> wrote: >>> >>> On Sat, 30 Apr 2011 09:33:15 +0300 >>> >>> Blue Swirl wrote: >>> >>> >>> On Sat, Apr 30, 2011 at 1:40 AM, Luiz Capitulino >>> wrote: >>> > This series introduces the inject-nmi command for QMP, which sends an >>> > NMI to _all_ guest's CPUs. >>> > >>> > Also note that this series changes the human monitor nmi command to >>> > use >>> > the QMP implementation, which means that it now has a DIFFERENT >>> > behavior. >>> > Please, check patch 3/3 for details. >>> >>> As discussed earlier, please change the QMP version for future >>> expandability so that instead of single command 'inject-nmi', 'inject' >>> takes parameter 'nmi'. HMP command 'nmi' can remain for now, but >>> 'inject' should be added. >>> >>> >>> >>> I'm not sure I agree with this, because we risky overloading 'inject' >>> >>> the >>> >>> same way we did with the 'change' command. >>> >>> >>> >>> What's 'inject' supposed to do in the future? >>> >> >>> >> Inject other IRQs, for example inject nmi could become an alias to >>> >> something like >>> >> inject /apic@fee0:l1int >>> >> which would be a shorthand for >>> >> raise /apic@fee0:l1int >>> >> lower /apic@fee0:l1int >>> >> >>> >> I think we only need a registration framework for IRQs and other signals. >>> > >>> > Yes, we could use nicer infrastructure for modeling IRQs. No, we >>> > shouldn't reject Lai's work because it doesn't get us there. Perfect is >>> > the enemy of good. >>> > >>> > Pick one: >>> > >>> > 1. We take inject-nmi now. Should we get a more general inject command >>> > like the one you envisage later, we can deprecate inject-nmi, and remove >>> > it after a suitable grace time. Big deal. We get the special problem >>> > solved now, without really compromising future solutions for the general >>> > problem. >>> > >>> > 2. We reject inject-nmi now. The itch Lai tries to scratch remains >>> > unscratched until we get a more general inject command. >>> > >>> > 2a. Rejection "motivates" Lai to solve the general problem[*]. Or maybe >>> > it motivates somebody else. We get the general problem solved sooner. >>> > And maybe I get a pony for my birthday, too. >>> > >>> > 2b. The general problem remains unsolved along with the special problem. >>> > We get nothing. >>> >>> 2c. Don't add full generic IRQ registration and aliases just now but >>> handle 'inject' with only 'nmi'. That way we introduce no legacy >>> baggage to the syntax. >> >> Can you give an example on how this is supposed to look like? > > No reply. When you demand a redesign to generalize a simple feature to > something only you envisage, please explain what exactly you want. > Documentation to stick into qmp-commands.hx would be a start. Here's > the baseline from Luiz, for your editing convenience. > > > inject-nmi > -- > > Inject an NMI on guest's CPUs. > > Arguments: None. > > Example: > > -> { "execute": "inject-nmi" } > <- { "return": {} } > > Note: inject-nmi is only supported for x86 guest currently, it will > returns "Unsupported" error for non-x86 guest. I think I explained it many times, but let's try again. inject -- Inject a signal on guest machine. Arguments: signal name. Example: -> { "execute": "inject", "arguments": { "signal": "nmi" } } <- { "return": {} } -> { "execute": "inject", "arguments": { "signal": "/apic@fee0:l1int" } } <- { "return": {} } Note: the set of signals supported depends on the CPU architecture and board type, unknown or unsupported names will return "Unsupported" error.
Re: [Qemu-devel] [PATCH 5/6] Do constant folding for shift operations.
On Thu, May 26, 2011 at 4:56 PM, Richard Henderson wrote: > On 05/26/2011 05:36 AM, Kirill Batuzov wrote: >>> x = (int32_t)x >> (int32_t)y; >>> >> This expression has an implementation-defined behavior accroding to >> C99 6.5.7 so we decided to emulate signed shifts by hand. > > Technically, yes. In practice, no. GCC, ICC, LLVM, MSVC all know > what the user wants here and will implement it "properly". Can't this be probed by configure? Then a wrapper could be introduced for signed shifts.
Re: [Qemu-devel] [PATCH] host-pcc: enable building with -m32 or -m64
On Thu, 26 May 2011, Stefan Berger wrote: > With the below patch I can build either ppc (-m32) or ppc64 (-m64) versions of > Qemu (on a ppc64 host) when passing these compiler flags via 'configure ... > --extra-cflags="-m32"'. > > Signed-off-by: Stefan Berger > > --- > configure |9 - > 1 file changed, 8 insertions(+), 1 deletion(-) > > Index: qemu-git/configure > === > --- qemu-git.orig/configure > +++ qemu-git/configure > @@ -807,7 +807,14 @@ case "$cpu" in > arm*) > host_guest_base="yes" > ;; > -ppc*) > +ppc) > + QEMU_CFLAGS="-m32 $QEMU_CFLAGS" > + LDFLAGS="-m32 $LDFLAGS" > + host_guest_base="yes" > + ;; > +ppc64) > + QEMU_CFLAGS="-m64 $QEMU_CFLAGS" > + LDFLAGS="-m64 $LDFLAGS" > host_guest_base="yes" > ;; > mips*) > This isn't right, if one has particular toolchain and wants to build something that defaults to a different bitlength he should be able to do that, this patch attempts to outsmart the defaults and furthermore prevents one from overriding the settings. P.S. host-pcc... pcc? P.P.S. On the ppc64 machine i have, gcc defaults to 32bit and for a good reason - 64bit code is quite a bit slower when running typical workloads (64bit guest not being one of them though) -- mailto:av1...@comtv.ru
Re: [Qemu-devel] Multi heterogenous CPU archs for SoC sim?
On Wed, May 25, 2011 at 10:20 PM, Peter Maydell wrote: > On 25 May 2011 19:44, Greg McGary wrote: >> I would like to create a QEMU model of an SoC that has several >> CPU cores having different architectures. I'm guessing this >> can be done. > > It's not supported currently as far as I'm aware. There was > at least one paper at the QEMU Forum earlier this year describing > an approach to multi-CPU environments (embedding QEMU into a > SystemC world) that basically saved and restored all QEMU's > global variables every time it switched cores... > > It would be good if it was supported in QEMU proper, but I > suspect you may be in for some large-scale restructuring work. One of the long standing goals for QEMU has been to be able to use a single executable to emulate multiple architectures. I think for example the lines like #define cpu_init cpu_sparc_init #define cpu_exec cpu_sparc_exec etc. stand for this purpose, so there has been some consideration for this.
Re: [Qemu-devel] [PATCH 0/6] target-arm: reduce usage of global env
On Wed, May 25, 2011 at 7:00 PM, Peter Maydell wrote: > This patchset is largely aimed at rolling back the changes from an > earlier patchset of mine: > http://lists.gnu.org/archive/html/qemu-devel/2011-04/msg00244.html > which made various Neon helper routines use the correct FP status > flags by having them use the global env. > > Since we've decided we're trying to get rid of the global CPUState > pointer (at least in C code), patches 1, 5, 6 here are basically > reverting patches 1,2,3 of that earlier patchset. In order not > to throw the baby out with the bathwater, patches 2, 3, 4 make > the helper routines which need to use the FP status take a pointer > to the fp status word. (In a few cases we can then merge them > with the equivalent VFP helpers.) > > This obviously still leaves some global CPUState use in op_helper.c, > but it's a move in the right direction. Have you seen any measurable changes in performance? The discussion about the performance effect of changes like this was not very conclusive.
[Qemu-devel] [PATCH] host-pcc: enable building with -m32 or -m64
With the below patch I can build either ppc (-m32) or ppc64 (-m64) versions of Qemu (on a ppc64 host) when passing these compiler flags via 'configure ... --extra-cflags="-m32"'. Signed-off-by: Stefan Berger --- configure |9 - 1 file changed, 8 insertions(+), 1 deletion(-) Index: qemu-git/configure === --- qemu-git.orig/configure +++ qemu-git/configure @@ -807,7 +807,14 @@ case "$cpu" in arm*) host_guest_base="yes" ;; -ppc*) +ppc) + QEMU_CFLAGS="-m32 $QEMU_CFLAGS" + LDFLAGS="-m32 $LDFLAGS" + host_guest_base="yes" + ;; +ppc64) + QEMU_CFLAGS="-m64 $QEMU_CFLAGS" + LDFLAGS="-m64 $LDFLAGS" host_guest_base="yes" ;; mips*)
[Qemu-devel] [PATCH] ppc host, target-ppc: fix building of kvm.c
Below patch fixes the following error when building on a ppc host: cc1: warnings being treated as errors /root/qemu/qemu-git/target-ppc/kvm.c: In function kvm_arch_get_registers: /root/qemu/qemu-git/target-ppc/kvm.c:188: error: unused variable sregs Signed-off-by: Stefan Berger --- target-ppc/kvm.c |2 ++ 1 file changed, 2 insertions(+) Index: qemu-git/target-ppc/kvm.c === --- qemu-git.orig/target-ppc/kvm.c +++ qemu-git/target-ppc/kvm.c @@ -185,7 +185,9 @@ int kvm_arch_put_registers(CPUState *env int kvm_arch_get_registers(CPUState *env) { struct kvm_regs regs; +#ifdef KVM_CAP_PPC_BOOKE_SREGS struct kvm_sregs sregs; +#endif uint32_t cr; int i, ret;
Re: [Qemu-devel] dynamically linked binaries under sparc-linux-user
On Tue, May 24, 2011 at 10:42 PM, Artyom Tarasenko wrote: > Should it be possible to use dynamically linked binaries under > sparc*-linux-user? > Under qemu-system-sparc the Debian 4.08r1 initrd works fine, but: > > master$ sparc-linux-user/qemu-sparc -strace -L > ../debian-4.08r1-initrd/ ../debian-4.08r1-initrd/bin/busybox > 14004 uname(0x409ffbae) = 0 > 14004 brk(NULL) = 0x00063000 > 14004 access("/etc/ld.so.nohwcap",F_OK) = -1 errno=2 (No such file or > directory) > 14004 mmap(NULL,4096,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0) > = 0x40a2c000 > 14004 access("/etc/ld.so.preload",R_OK) = -1 errno=2 (No such file or > directory) > 14004 open("/etc/ld.so.cache",O_RDONLY) = 3 > 14004 fstat64(3,0x409ff500) = 0 > 14004 mmap(NULL,195479,PROT_READ,MAP_PRIVATE,3,0) = 0x40a2d000 > 14004 close(3) = 0 > Segmentation fault > > The strange thing here is that it loads ld.so.cache. The guest fs > doesn't have it, but the host does: > > master$ ll ../../debian-4.08r1-initrd/etc/ld.so.cache /etc/ld.so.cache > ls: cannot access ../../debian-4.08r1-initrd/etc/ld.so.cache: No such > file or directory > -rw-r--r--. 1 root root 195479 2011-03-17 13:48 /etc/ld.so.cache > > Isn't this wrong? I'm not sure. It could be possible to construct a blacklist of host files that may not be accessible or visible to the guest but that wouldn't very robust either. Chrooting into a 100% guest architecture system should work better.
Re: [Qemu-devel] [PATCH] ppc: Fix compilation for ppc64-softmmu
On 21 May 2011 09:31, Alexander Graf wrote: > On 20.05.2011, at 22:30, Stefan Weil wrote: >> When QEMU was configured with --enable-debug-tcg, >> compilation fails in spr_write_booke206_mmucsr0() and in >> spr_write_booke_pid(). Similar changes are also needed >> in conditional code which is normally unused. > > Stefan (Hajnoczi), can we add --enable-debug-tcg builds > to the buildbot runs? --enable-debug implies --enable-debug-tcg, so I would think that just running both with and without --enable-debug would be sufficient. -- PMM
Re: [Qemu-devel] [PATCH] target-ppc: Fix compilation error with --enable-debug
On 26 May 2011 19:28, Stefan Weil wrote: > Am 26.05.2011 20:05, schrieb Peter Maydell: >> The PPC helper functions booke206_tlbflush and booke_setpid both >> take an i32 argument, so we need to use TCGv_i32 rather than TCGv, >> to avoid a compilation failure when compiling in debug mode. > See http://patchwork.ozlabs.org/patch/96665/ Oops; I did try searching my mail for a fix, but obviously failed to use the right search term. -- PMM
[Qemu-devel] block bug: tray status is not updated (and/or guest ignores it)
I'm testing with qemu.git (HEAD aa29141d84d), procedure: 1. Start a VM with: # qemu -hda disks/test.img -enable-kvm -m 1G -cdrom Fedora-14-x86_64-DVD.iso 2. Then inside the guest run: # eject /dev/sr0 && mount /dev/sr0 /mnt Results: Actual: The cdrom is successfully mounted Expected: The cdrom is not mounted (mount fails, medium not found) Git bisect tells the culprit is: 996faf1ad4a93342e381766d95686b16624f0dbd is the first bad commit commit 996faf1ad4a93342e381766d95686b16624f0dbd Author: Amit Shah Date: Tue Apr 12 21:36:07 2011 +0530 atapi: GESN: implement 'media' subcommand
Re: [Qemu-devel] [PATCH] target-ppc: Fix compilation error with --enable-debug
Am 26.05.2011 20:05, schrieb Peter Maydell: The PPC helper functions booke206_tlbflush and booke_setpid both take an i32 argument, so we need to use TCGv_i32 rather than TCGv, to avoid a compilation failure when compiling in debug mode. Signed-off-by: Peter Maydell --- target-ppc/translate_init.c | 8 1 files changed, 4 insertions(+), 4 deletions(-) See http://patchwork.ozlabs.org/patch/96665/ It's a waste of time if build fixes take more than 3 days to get committed. The typical process - several days until the maintainer accepts it, more days until there is a pull request, even more days until it is pulled - is good enough for new features, but too slow for bug fixes, especially when they fix broken builds. Cheers, Stefan W.
Re: [Qemu-devel] [PATCH] Buildfix: fix libcacard build with -m32 on 64bit machine
On Thu, May 26, 2011 at 01:56:54PM -0400, Stefan Berger wrote: > When configuring with --extra-cflags="-m32" on a 64bit machine the > following error appears during compilation: Thanks for the fix. Reviewed-by: Alon Levy > > make -C libhw64 V="1" TARGET_DIR="libhw64/" all > make[1]: Entering directory `/root/tmp/qemu-git/libhw64' > make[1]: Leaving directory `/root/tmp/qemu-git/libhw64' > make -C libcacard V="1" TARGET_DIR="libcacard/" all > make[1]: Entering directory `/root/tmp/qemu-git/libcacard' > gcc -lssl3 -lsmime3 -lnss3 -lnssutil3 -lplds4 -lplc4 -lnspr4 > -lpthread -ldl -lrt -o vscclient cac.o event.o vcard.o vreader.o > vcard_emul_nss.o vcard_emul_type.o card_7816.o ../osdep.o > ../oslib-posix.o ../qemu-thread-posix.o ../trace.o ../qemu-malloc.o > ../qemu-timer-common.o vscclient.o > cac.o: could not read symbols: File in wrong format > collect2: ld returned 1 exit status > make[1]: *** [vscclient] Error 1 > make[1]: Leaving directory `/root/tmp/qemu-git/libcacard' > make: *** [subdir-libcacard] Error 2 > > The LDFLAGS are not passed to the compiled. The below patch fixes it. > > Signed-off-by: Stefan Berger > > --- > libcacard/Makefile |2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > Index: qemu-git/libcacard/Makefile > === > --- qemu-git.orig/libcacard/Makefile > +++ qemu-git/libcacard/Makefile > @@ -9,7 +9,7 @@ QEMU_OBJS=$(addprefix ../, $(oslib-obj-y > QEMU_CFLAGS+=-I../ > > vscclient: $(libcacard-y) $(QEMU_OBJS) vscclient.o > -$(call quiet-command,$(CC) $(libcacard_libs) -lrt -o $@ $^," > LINK $(TARGET_DIR)$@") > +$(call quiet-command,$(CC) $(LDFLAGS) $(libcacard_libs) -lrt -o > $@ $^," LINK $(TARGET_DIR)$@") > > all: vscclient > >
Re: [Qemu-devel] [PATCH 01/12] usb-linux: catch NODEV in more places.
Gerd Hoffmann writes: > Factor out disconnect code (called when a device disappears) to a > separate function. Add a check for NODEV errno to a few more places to > make sure we notice disconnects. Ah, you mean ENODEV! Suddenly the subject makes sense. Fix it up? [...]
[Qemu-devel] [PATCH] target-ppc: Fix compilation error with --enable-debug
The PPC helper functions booke206_tlbflush and booke_setpid both take an i32 argument, so we need to use TCGv_i32 rather than TCGv, to avoid a compilation failure when compiling in debug mode. Signed-off-by: Peter Maydell --- target-ppc/translate_init.c |8 1 files changed, 4 insertions(+), 4 deletions(-) diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index b511afa..d11532c 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -1367,16 +1367,16 @@ static void spr_write_e500_l1csr0 (void *opaque, int sprn, int gprn) static void spr_write_booke206_mmucsr0 (void *opaque, int sprn, int gprn) { -TCGv t0 = tcg_const_i32(sprn); +TCGv_i32 t0 = tcg_const_i32(sprn); gen_helper_booke206_tlbflush(t0); -tcg_temp_free(t0); +tcg_temp_free_i32(t0); } static void spr_write_booke_pid (void *opaque, int sprn, int gprn) { -TCGv t0 = tcg_const_i32(sprn); +TCGv_i32 t0 = tcg_const_i32(sprn); gen_helper_booke_setpid(t0, cpu_gpr[gprn]); -tcg_temp_free(t0); +tcg_temp_free_i32(t0); } #endif -- 1.7.1
[Qemu-devel] [PATCH] Buildfix: fix libcacard build with -m32 on 64bit machine
When configuring with --extra-cflags="-m32" on a 64bit machine the following error appears during compilation: make -C libhw64 V="1" TARGET_DIR="libhw64/" all make[1]: Entering directory `/root/tmp/qemu-git/libhw64' make[1]: Leaving directory `/root/tmp/qemu-git/libhw64' make -C libcacard V="1" TARGET_DIR="libcacard/" all make[1]: Entering directory `/root/tmp/qemu-git/libcacard' gcc -lssl3 -lsmime3 -lnss3 -lnssutil3 -lplds4 -lplc4 -lnspr4 -lpthread -ldl -lrt -o vscclient cac.o event.o vcard.o vreader.o vcard_emul_nss.o vcard_emul_type.o card_7816.o ../osdep.o ../oslib-posix.o ../qemu-thread-posix.o ../trace.o ../qemu-malloc.o ../qemu-timer-common.o vscclient.o cac.o: could not read symbols: File in wrong format collect2: ld returned 1 exit status make[1]: *** [vscclient] Error 1 make[1]: Leaving directory `/root/tmp/qemu-git/libcacard' make: *** [subdir-libcacard] Error 2 The LDFLAGS are not passed to the compiled. The below patch fixes it. Signed-off-by: Stefan Berger --- libcacard/Makefile |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Index: qemu-git/libcacard/Makefile === --- qemu-git.orig/libcacard/Makefile +++ qemu-git/libcacard/Makefile @@ -9,7 +9,7 @@ QEMU_OBJS=$(addprefix ../, $(oslib-obj-y QEMU_CFLAGS+=-I../ vscclient: $(libcacard-y) $(QEMU_OBJS) vscclient.o -$(call quiet-command,$(CC) $(libcacard_libs) -lrt -o $@ $^," LINK $(TARGET_DIR)$@") +$(call quiet-command,$(CC) $(LDFLAGS) $(libcacard_libs) -lrt -o $@ $^," LINK $(TARGET_DIR)$@") all: vscclient
Re: [Qemu-devel] [PATCH] target-arm: Fix compilation failure for 64 bit hosts
Am 26.05.2011 13:03, schrieb Peter Maydell: Use the correct _ptr aliases for manipulating the pointer to the fp_status; this fixes a compilation failure on 64 bit hosts. Signed-off-by: Peter Maydell --- Apologies for the build breakage. target-arm/translate.c | 18 +- 1 files changed, 9 insertions(+), 9 deletions(-) Acked-by: Stefan Weil
Re: [Qemu-devel] [PATCH 0/3]: QMP: Introduce inject-nmi command
Luiz Capitulino writes: > On Fri, 6 May 2011 18:36:31 +0300 > Blue Swirl wrote: > >> On Fri, May 6, 2011 at 12:08 PM, Markus Armbruster wrote: >> > Blue Swirl writes: >> > >> >> On Mon, May 2, 2011 at 6:57 PM, Luiz Capitulino >> >> wrote: >> >>> On Sat, 30 Apr 2011 09:33:15 +0300 >> >>> Blue Swirl wrote: >> >>> >> On Sat, Apr 30, 2011 at 1:40 AM, Luiz Capitulino >> wrote: >> > This series introduces the inject-nmi command for QMP, which sends an >> > NMI to _all_ guest's CPUs. >> > >> > Also note that this series changes the human monitor nmi command to >> > use >> > the QMP implementation, which means that it now has a DIFFERENT >> > behavior. >> > Please, check patch 3/3 for details. >> >> As discussed earlier, please change the QMP version for future >> expandability so that instead of single command 'inject-nmi', 'inject' >> takes parameter 'nmi'. HMP command 'nmi' can remain for now, but >> 'inject' should be added. >> >>> >> >>> I'm not sure I agree with this, because we risky overloading 'inject' the >> >>> same way we did with the 'change' command. >> >>> >> >>> What's 'inject' supposed to do in the future? >> >> >> >> Inject other IRQs, for example inject nmi could become an alias to >> >> something like >> >> inject /apic@fee0:l1int >> >> which would be a shorthand for >> >> raise /apic@fee0:l1int >> >> lower /apic@fee0:l1int >> >> >> >> I think we only need a registration framework for IRQs and other signals. >> > >> > Yes, we could use nicer infrastructure for modeling IRQs. No, we >> > shouldn't reject Lai's work because it doesn't get us there. Perfect is >> > the enemy of good. >> > >> > Pick one: >> > >> > 1. We take inject-nmi now. Should we get a more general inject command >> > like the one you envisage later, we can deprecate inject-nmi, and remove >> > it after a suitable grace time. Big deal. We get the special problem >> > solved now, without really compromising future solutions for the general >> > problem. >> > >> > 2. We reject inject-nmi now. The itch Lai tries to scratch remains >> > unscratched until we get a more general inject command. >> > >> > 2a. Rejection "motivates" Lai to solve the general problem[*]. Or maybe >> > it motivates somebody else. We get the general problem solved sooner. >> > And maybe I get a pony for my birthday, too. >> > >> > 2b. The general problem remains unsolved along with the special problem. >> > We get nothing. >> >> 2c. Don't add full generic IRQ registration and aliases just now but >> handle 'inject' with only 'nmi'. That way we introduce no legacy >> baggage to the syntax. > > Can you give an example on how this is supposed to look like? No reply. When you demand a redesign to generalize a simple feature to something only you envisage, please explain what exactly you want. Documentation to stick into qmp-commands.hx would be a start. Here's the baseline from Luiz, for your editing convenience. inject-nmi -- Inject an NMI on guest's CPUs. Arguments: None. Example: -> { "execute": "inject-nmi" } <- { "return": {} } Note: inject-nmi is only supported for x86 guest currently, it will returns "Unsupported" error for non-x86 guest.
[Qemu-devel] [Bug 788734] [NEW] vmwgfx does not work in Linux guest in kvm
Public bug reported: loading the vmwgfx module of kernel 2.6.39-rc7 in kvm 0.14 results in [drm:vmw_driver_load] *ERROR* Hardware has no pitchlock and the kernel module fails. Consequently vmwgfx is broken, only the vmwlegacy driver works. ** Affects: qemu Importance: Undecided Status: New -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/788734 Title: vmwgfx does not work in Linux guest in kvm Status in QEMU: New Bug description: loading the vmwgfx module of kernel 2.6.39-rc7 in kvm 0.14 results in [drm:vmw_driver_load] *ERROR* Hardware has no pitchlock and the kernel module fails. Consequently vmwgfx is broken, only the vmwlegacy driver works.
Re: [Qemu-devel] [Bug 788697] Re: [PowerPC] [patch] mtmsr does not preserve high bits of MSR
On 26.05.2011, at 18:09, Nathan Whitehorn wrote: > ** Patch added: "mtmstr.diff" > > https://bugs.launchpad.net/bugs/788697/+attachment/2143748/+files/mtmstr.diff > > -- > You received this bug notification because you are a member of qemu- > devel-ml, which is subscribed to QEMU. > https://bugs.launchpad.net/bugs/788697 > > Title: > [PowerPC] [patch] mtmsr does not preserve high bits of MSR > > Status in QEMU: > New > > Bug description: > The mtmsr instruction on 64-bit PPC does not preserve the high-order > 32-bits of the MSR the way it is supposed to, instead setting them to > 0, which takes 64-bit code out of 64-bit mode. There is some code that > does the right thing, but it brokenly only preserves these bits when > the thread is not in 64-bit mode (i.e. when it doesn't matter). The > attached patch unconditionally enables this code when TARGET_PPC64 is > set, per the ISA spec, which fixes early boot failures trying to start > FreeBSD/powerpc64 under qemu. > Please send the patch as proper patch to the ML and CC me. Alex
[Qemu-devel] [Bug 788701] Re: qemu-user fails to run rpcgen (i386, x86_64)
** Summary changed: - qem-user fails to run rpcgen (i386, x86_64) + qemu-user fails to run rpcgen (i386, x86_64) -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/788701 Title: qemu-user fails to run rpcgen (i386, x86_64) Status in QEMU: New Bug description: Confirmed on qemu current development tree (git commit aa29141). While trying to run eglibc's rpcgen from native system by qemu-user, I get an error: qemu-x86_64 /usr/bin/rpcgen -c /dev/null fork: Invalid argument I am running a Debian Wheezy system and rpcgen comes from libc-dev- bin. Just in case I am attaching my rpcgen binaries from i386 and x86_64 systems. Very similar problem was mentioned on the QEMU forum on February 2007, so I guess it might be a known issue. Nevertheless, I was unable to find any information about bug reports, fixes nor workarounds for it so I'm reporting it here.
[Qemu-devel] [PATCH] hw/9118.c: Implement active-low interrupt support
The 9118 ethernet controller interrupt line is active low unless the IRQ config register is programmed to set both the IRQ_POL (polarity: active-high) and IRQ_TYPE (type: push-pull) bits: implement support for inverting the irq output in other configurations. This also requires that we support setting the bits in the first place, and that we correctly preserve them across software reset. Signed-off-by: Peter Maydell --- The motivation for this patch is actually an omap3 platform (overo) which uses the active-low configuration; the platforms in QEMU mainline which use it (vexpress and realview) both configure the chip to active-high, which is why this bug hasn't come to light before. I've tested that (a) my overo platform works with the change and (b) it doesn't regress vexpress. hw/lan9118.c | 12 +--- 1 files changed, 9 insertions(+), 3 deletions(-) diff --git a/hw/lan9118.c b/hw/lan9118.c index 4c42fe9..3f3c05d 100644 --- a/hw/lan9118.c +++ b/hw/lan9118.c @@ -228,6 +228,12 @@ static void lan9118_update(lan9118_state *s) if ((s->irq_cfg & IRQ_EN) == 0) { level = 0; } +if ((s->irq_cfg & (IRQ_TYPE | IRQ_POL)) != (IRQ_TYPE | IRQ_POL)) { +/* Interrupt is active low unless we're configured as + * active-high polarity, push-pull type. + */ +level = !level; +} qemu_set_irq(s->irq, level); } @@ -294,8 +300,7 @@ static void phy_reset(lan9118_state *s) static void lan9118_reset(DeviceState *d) { lan9118_state *s = FROM_SYSBUS(lan9118_state, sysbus_from_qdev(d)); - -s->irq_cfg &= ~(IRQ_TYPE | IRQ_POL); +s->irq_cfg &= (IRQ_TYPE | IRQ_POL); s->int_sts = 0; s->int_en = 0; s->fifo_int = 0x4800; @@ -904,7 +909,8 @@ static void lan9118_writel(void *opaque, target_phys_addr_t offset, switch (offset) { case CSR_IRQ_CFG: /* TODO: Implement interrupt deassertion intervals. */ -s->irq_cfg = (s->irq_cfg & IRQ_INT) | (val & IRQ_EN); +val &= (IRQ_EN | IRQ_POL | IRQ_TYPE); +s->irq_cfg = (s->irq_cfg & IRQ_INT) | val; break; case CSR_INT_STS: s->int_sts &= ~val; -- 1.7.1
[Qemu-devel] [Bug 788701] [NEW] qem-user fails to run rpcgen (i386, x86_64)
Public bug reported: Confirmed on qemu current development tree (git commit aa29141). While trying to run eglibc's rpcgen from native system by qemu-user, I get an error: qemu-x86_64 /usr/bin/rpcgen -c /dev/null fork: Invalid argument I am running a Debian Wheezy system and rpcgen comes from libc-dev-bin. Just in case I am attaching my rpcgen binaries from i386 and x86_64 systems. Very similar problem was mentioned on the QEMU forum on February 2007, so I guess it might be a known issue. Nevertheless, I was unable to find any information about bug reports, fixes nor workarounds for it so I'm reporting it here. ** Affects: qemu Importance: Undecided Status: New -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/788701 Title: qem-user fails to run rpcgen (i386, x86_64) Status in QEMU: New Bug description: Confirmed on qemu current development tree (git commit aa29141). While trying to run eglibc's rpcgen from native system by qemu-user, I get an error: qemu-x86_64 /usr/bin/rpcgen -c /dev/null fork: Invalid argument I am running a Debian Wheezy system and rpcgen comes from libc-dev- bin. Just in case I am attaching my rpcgen binaries from i386 and x86_64 systems. Very similar problem was mentioned on the QEMU forum on February 2007, so I guess it might be a known issue. Nevertheless, I was unable to find any information about bug reports, fixes nor workarounds for it so I'm reporting it here.
[Qemu-devel] [Bug 788701] Re: qem-user fails to run rpcgen (i386, x86_64)
** Attachment added: "rpcgen.tar.bz2" https://bugs.launchpad.net/bugs/788701/+attachment/2143749/+files/rpcgen.tar.bz2 -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/788701 Title: qem-user fails to run rpcgen (i386, x86_64) Status in QEMU: New Bug description: Confirmed on qemu current development tree (git commit aa29141). While trying to run eglibc's rpcgen from native system by qemu-user, I get an error: qemu-x86_64 /usr/bin/rpcgen -c /dev/null fork: Invalid argument I am running a Debian Wheezy system and rpcgen comes from libc-dev- bin. Just in case I am attaching my rpcgen binaries from i386 and x86_64 systems. Very similar problem was mentioned on the QEMU forum on February 2007, so I guess it might be a known issue. Nevertheless, I was unable to find any information about bug reports, fixes nor workarounds for it so I'm reporting it here.
[Qemu-devel] [Bug 788697] Re: [PowerPC] [patch] mtmsr does not preserve high bits of MSR
** Patch added: "mtmstr.diff" https://bugs.launchpad.net/bugs/788697/+attachment/2143748/+files/mtmstr.diff -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/788697 Title: [PowerPC] [patch] mtmsr does not preserve high bits of MSR Status in QEMU: New Bug description: The mtmsr instruction on 64-bit PPC does not preserve the high-order 32-bits of the MSR the way it is supposed to, instead setting them to 0, which takes 64-bit code out of 64-bit mode. There is some code that does the right thing, but it brokenly only preserves these bits when the thread is not in 64-bit mode (i.e. when it doesn't matter). The attached patch unconditionally enables this code when TARGET_PPC64 is set, per the ISA spec, which fixes early boot failures trying to start FreeBSD/powerpc64 under qemu.
[Qemu-devel] [Bug 788697] [NEW] [PowerPC] [patch] mtmsr does not preserve high bits of MSR
Public bug reported: The mtmsr instruction on 64-bit PPC does not preserve the high-order 32-bits of the MSR the way it is supposed to, instead setting them to 0, which takes 64-bit code out of 64-bit mode. There is some code that does the right thing, but it brokenly only preserves these bits when the thread is not in 64-bit mode (i.e. when it doesn't matter). The attached patch unconditionally enables this code when TARGET_PPC64 is set, per the ISA spec, which fixes early boot failures trying to start FreeBSD/powerpc64 under qemu. ** Affects: qemu Importance: Undecided Status: New -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/788697 Title: [PowerPC] [patch] mtmsr does not preserve high bits of MSR Status in QEMU: New Bug description: The mtmsr instruction on 64-bit PPC does not preserve the high-order 32-bits of the MSR the way it is supposed to, instead setting them to 0, which takes 64-bit code out of 64-bit mode. There is some code that does the right thing, but it brokenly only preserves these bits when the thread is not in 64-bit mode (i.e. when it doesn't matter). The attached patch unconditionally enables this code when TARGET_PPC64 is set, per the ISA spec, which fixes early boot failures trying to start FreeBSD/powerpc64 under qemu.
[Qemu-devel] [PATCH] xen: fix interrupt routing
xen: fix interrupt routing - remove i440FX-xen and i440fx_write_config_xen we don't need to intercept pci config writes to i440FX anymore; - introduce PIIX3-xen and piix3_write_config_xen we do need to intercept pci config write to the PCI-ISA bridge to update the PCI link routing; - set the number of PIIX3-xen interrupts lines to 128; Signed-off-by: Stefano Stabellini diff --git a/hw/pc.h b/hw/pc.h index 0dcbee7..6d5730b 100644 --- a/hw/pc.h +++ b/hw/pc.h @@ -176,7 +176,6 @@ struct PCII440FXState; typedef struct PCII440FXState PCII440FXState; PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn, qemu_irq *pic, ram_addr_t ram_size); -PCIBus *i440fx_xen_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq *pic, ram_addr_t ram_size); void i440fx_init_memory_mappings(PCII440FXState *d); /* piix4.c */ diff --git a/hw/pc_piix.c b/hw/pc_piix.c index 9a22a8a..ba198de 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -124,11 +124,7 @@ static void pc_init1(ram_addr_t ram_size, isa_irq = qemu_allocate_irqs(isa_irq_handler, isa_irq_state, 24); if (pci_enabled) { -if (!xen_enabled()) { -pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq, ram_size); -} else { -pci_bus = i440fx_xen_init(&i440fx_state, &piix3_devfn, isa_irq, ram_size); -} +pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq, ram_size); } else { pci_bus = NULL; i440fx_state = NULL; diff --git a/hw/piix_pci.c b/hw/piix_pci.c index 7f1c4cc..3d73a42 100644 --- a/hw/piix_pci.c +++ b/hw/piix_pci.c @@ -40,6 +40,7 @@ typedef PCIHostState I440FXState; #define PIIX_NUM_PIC_IRQS 16 /* i8259 * 2 */ #define PIIX_NUM_PIRQS 4ULL/* PIRQ[A-D] */ +#define XEN_PIIX_NUM_PIRQS 128ULL #define PIIX_PIRQC 0x60 typedef struct PIIX3State { @@ -78,6 +79,8 @@ struct PCII440FXState { #define I440FX_SMRAM0x72 static void piix3_set_irq(void *opaque, int pirq, int level); +static void piix3_write_config_xen(PCIDevice *dev, + uint32_t address, uint32_t val, int len); /* return the global irq number corresponding to a given device irq pin. We could also use the bus number to have a more precise @@ -173,13 +176,6 @@ static void i440fx_write_config(PCIDevice *dev, } } -static void i440fx_write_config_xen(PCIDevice *dev, -uint32_t address, uint32_t val, int len) -{ -xen_piix_pci_write_config_client(address, val, len); -i440fx_write_config(dev, address, val, len); -} - static int i440fx_load_old(QEMUFile* f, void *opaque, int version_id) { PCII440FXState *d = opaque; @@ -267,8 +263,17 @@ static PCIBus *i440fx_common_init(const char *device_name, d = pci_create_simple(b, 0, device_name); *pi440fx_state = DO_UPCAST(PCII440FXState, dev, d); -piix3 = DO_UPCAST(PIIX3State, dev, - pci_create_simple_multifunction(b, -1, true, "PIIX3")); +if (xen_enabled()) { +piix3 = DO_UPCAST(PIIX3State, dev, +pci_create_simple_multifunction(b, -1, true, "PIIX3-xen")); +pci_bus_irqs(b, xen_piix3_set_irq, xen_pci_slot_get_pirq, +piix3, XEN_PIIX_NUM_PIRQS); +} else { +piix3 = DO_UPCAST(PIIX3State, dev, +pci_create_simple_multifunction(b, -1, true, "PIIX3")); +pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3, +PIIX_NUM_PIRQS); +} piix3->pic = pic; (*pi440fx_state)->piix3 = piix3; @@ -289,21 +294,6 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, PCIBus *b; b = i440fx_common_init("i440FX", pi440fx_state, piix3_devfn, pic, ram_size); -pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, (*pi440fx_state)->piix3, - PIIX_NUM_PIRQS); - -return b; -} - -PCIBus *i440fx_xen_init(PCII440FXState **pi440fx_state, int *piix3_devfn, -qemu_irq *pic, ram_addr_t ram_size) -{ -PCIBus *b; - -b = i440fx_common_init("i440FX-xen", pi440fx_state, piix3_devfn, pic, ram_size); -pci_bus_irqs(b, xen_piix3_set_irq, xen_pci_slot_get_pirq, - (*pi440fx_state)->piix3, PIIX_NUM_PIRQS); - return b; } @@ -365,6 +355,13 @@ static void piix3_write_config(PCIDevice *dev, } } +static void piix3_write_config_xen(PCIDevice *dev, + uint32_t address, uint32_t val, int len) +{ +xen_piix_pci_write_config_client(address, val, len); +piix3_write_config(dev, address, val, len); +} + static void piix3_reset(void *opaque) { PIIX3State *d = opaque; @@ -465,14 +462,6 @@ static PCIDeviceInfo i440fx_info[] = { .init = i440fx_initfn, .config_write = i440fx_write_config, },{ -.qdev.name= "i440FX-xen", -.qdev.desc= "Host bridge", -.qdev.size= sizeof(PCII440FXState), -.qdev
Re: [Qemu-devel] [PATCH 5/6] Do constant folding for shift operations.
On 05/26/2011 05:36 AM, Kirill Batuzov wrote: >> x = (int32_t)x >> (int32_t)y; >> > This expression has an implementation-defined behavior accroding to > C99 6.5.7 so we decided to emulate signed shifts by hand. Technically, yes. In practice, no. GCC, ICC, LLVM, MSVC all know what the user wants here and will implement it "properly". r~
Re: [Qemu-devel] [PATCH 1/3] Add ppc_init_cacheline_sizes() function for OpenBSD.
On Thu, 26 May 2011, Brad wrote: > - Original message - > > On Wed, 25 May 2011, Brad wrote: > > > > > Add ppc_init_cacheline_sizes() function for OpenBSD to fix compilation > > > of PowerPC host support for OpenBSD/powerpc based architectures. > > > > > > Signed-off-by: Brad Smith > > > > > > --- > > > cache-utils.c | 11 +-- > > > 1 files changed, 9 insertions(+), 2 deletions(-) > > > > > > diff --git a/cache-utils.c b/cache-utils.c > > > index 2db5af2..c319705 100644 > > > --- a/cache-utils.c > > > +++ b/cache-utils.c > > > @@ -55,9 +55,16 @@ static void ppc_init_cacheline_sizes(void) > > > qemu_cache_conf.icache_bsize = cacheline; > > > } > > > } > > > -#endif > > > > > > -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) > > > +#elif defined(__OpenBSD__) > > > + > > > +static void ppc_init_cacheline_sizes(void) > > > +{ > > > + qemu_cache_conf.dcache_bsize = 32; > > > + qemu_cache_conf.icache_bsize = 32; > > > +} > > > + > > > +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) > > > #include > > > #include > > > #include > > > > > > > This can't be right for most ppc64's. > > Well this is what OpenBSD currently does and runs on G5's in 32-bit mode only. > Mode of operation does not, to the best of my knowledge, change the hardware limits, the cache line size will still be 128 on those G5s. -- mailto:av1...@comtv.ru
Re: [Qemu-devel] [PATCH 1/3] Add ppc_init_cacheline_sizes() function for OpenBSD.
- Original message - > On Wed, 25 May 2011, Brad wrote: > > > Add ppc_init_cacheline_sizes() function for OpenBSD to fix compilation > > of PowerPC host support for OpenBSD/powerpc based architectures. > > > > Signed-off-by: Brad Smith > > > > --- > > cache-utils.c | 11 +-- > > 1 files changed, 9 insertions(+), 2 deletions(-) > > > > diff --git a/cache-utils.c b/cache-utils.c > > index 2db5af2..c319705 100644 > > --- a/cache-utils.c > > +++ b/cache-utils.c > > @@ -55,9 +55,16 @@ static void ppc_init_cacheline_sizes(void) > > qemu_cache_conf.icache_bsize = cacheline; > > } > > } > > -#endif > > > > -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) > > +#elif defined(__OpenBSD__) > > + > > +static void ppc_init_cacheline_sizes(void) > > +{ > > + qemu_cache_conf.dcache_bsize = 32; > > + qemu_cache_conf.icache_bsize = 32; > > +} > > + > > +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) > > #include > > #include > > #include > > > > This can't be right for most ppc64's. Well this is what OpenBSD currently does and runs on G5's in 32-bit mode only. -- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.
Re: [Qemu-devel] [PATCH 1/2] QMP: add get_events(wait=True) option
On Thu, 26 May 2011 09:03:49 +0100 Stefan Hajnoczi wrote: > On Wed, May 25, 2011 at 10:15 PM, Luiz Capitulino > wrote: > > On Wed, 25 May 2011 19:48:00 +0100 > > Stefan Hajnoczi wrote: > > > >> The get_events() function polls for new QMP events and then returns. It > >> can be useful to wait for the next QMP event so add the boolean 'wait' > >> keyword argument. > >> > >> Signed-off-by: Stefan Hajnoczi > >> --- > >> QMP/qmp.py | 11 --- > >> 1 files changed, 8 insertions(+), 3 deletions(-) > >> > >> diff --git a/QMP/qmp.py b/QMP/qmp.py > >> index 14ce8b0..2565508 100644 > >> --- a/QMP/qmp.py > >> +++ b/QMP/qmp.py > >> @@ -43,7 +43,7 @@ class QEMUMonitorProtocol: > >> family = socket.AF_UNIX > >> return socket.socket(family, socket.SOCK_STREAM) > >> > >> - def __json_read(self): > >> + def __json_read(self, only_event=False): > >> while True: > >> data = self.__sockfile.readline() > >> if not data: > >> @@ -51,7 +51,8 @@ class QEMUMonitorProtocol: > >> resp = json.loads(data) > >> if 'event' in resp: > >> self.__events.append(resp) > >> - continue > >> + if not only_event: > >> + continue > >> return resp > >> > >> error = socket.error > >> @@ -106,9 +107,11 @@ class QEMUMonitorProtocol: > >> qmp_cmd['id'] = id > >> return self.cmd_obj(qmp_cmd) > >> > >> - def get_events(self): > >> + def get_events(self, wait=False): > >> """ > >> Get a list of available QMP events. > >> + > >> + @param wait: block until an event is available (bool) > >> """ > >> self.__sock.setblocking(0) > >> try: > >> @@ -118,6 +121,8 @@ class QEMUMonitorProtocol: > >> # No data available > >> pass > >> self.__sock.setblocking(1) > >> + if not self.__events and wait: > >> + self.__json_read(only_event=True) > >> return self.__events > > > > Maybe this is better (untested): > > I've tested it because that's how I implemented it first too :). > However, I don't want to block until the QMP monitor sends the next > event when there is already a received event pending. > > The patch I posted polls for new events first, then only blocks if > there are no events available. Ok, pushed both patches to the QMP queue. Thanks.
Re: [Qemu-devel] [PATCH 5/6] Do constant folding for shift operations.
On Fri, 20 May 2011, Richard Henderson wrote: > > On 05/20/2011 05:39 AM, Kirill Batuzov wrote: > > +case INDEX_op_sar_i32: > > +#if TCG_TARGET_REG_BITS == 64 > > +x &= 0x; > > +y &= 0x; > > +#endif > > +r = x & 0x8000; > > +x &= ~0x8000; > > +x >>= y; > > +r |= r - (r >> y); > > +x |= r; > > +return x; > > + > > Any reason you're emulating the 32-bit shift by > hand, rather than letting the compiler do it? I.e. > > x = (int32_t)x >> (int32_t)y; > This expression has an implementation-defined behavior accroding to C99 6.5.7 so we decided to emulate signed shifts by hand. Kirill.
Re: [Qemu-devel] [PATCH 1/3] Add ppc_init_cacheline_sizes() function for OpenBSD.
On Wed, 25 May 2011, Brad wrote: > Add ppc_init_cacheline_sizes() function for OpenBSD to fix compilation > of PowerPC host support for OpenBSD/powerpc based architectures. > > Signed-off-by: Brad Smith > > --- > cache-utils.c | 11 +-- > 1 files changed, 9 insertions(+), 2 deletions(-) > > diff --git a/cache-utils.c b/cache-utils.c > index 2db5af2..c319705 100644 > --- a/cache-utils.c > +++ b/cache-utils.c > @@ -55,9 +55,16 @@ static void ppc_init_cacheline_sizes(void) > qemu_cache_conf.icache_bsize = cacheline; > } > } > -#endif > > -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) > +#elif defined(__OpenBSD__) > + > +static void ppc_init_cacheline_sizes(void) > +{ > +qemu_cache_conf.dcache_bsize = 32; > +qemu_cache_conf.icache_bsize = 32; > +} > + > +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) > #include > #include > #include > This can't be right for most ppc64's. -- mailto:av1...@comtv.ru
[Qemu-devel] [PATCH v5 20/25] scsi: make write_data return void
The return value is unused anyway. Signed-off-by: Paolo Bonzini Reviewed-by: Christoph Hellwig --- hw/scsi-disk.c|6 ++ hw/scsi-generic.c |7 ++- hw/scsi.h |2 +- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index f3eba52..e0c384f 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -269,7 +269,7 @@ static void scsi_write_complete(void * opaque, int ret) } } -static int scsi_write_data(SCSIRequest *req) +static void scsi_write_data(SCSIRequest *req) { SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req); SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); @@ -281,7 +281,7 @@ static int scsi_write_data(SCSIRequest *req) if (r->req.cmd.mode != SCSI_XFER_TO_DEV) { DPRINTF("Data transfer direction invalid\n"); scsi_write_complete(r, -EINVAL); -return 0; +return; } n = r->iov.iov_len / 512; @@ -296,8 +296,6 @@ static int scsi_write_data(SCSIRequest *req) /* Invoke completion routine to fetch data from host. */ scsi_write_complete(r, 0); } - -return 0; } static void scsi_dma_restart_bh(void *opaque) diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c index fc015e0..579bab9 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -277,7 +277,7 @@ static void scsi_write_complete(void * opaque, int ret) /* Write data to a scsi device. Returns nonzero on failure. The transfer may complete asynchronously. */ -static int scsi_write_data(SCSIRequest *req) +static void scsi_write_data(SCSIRequest *req) { SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req->dev); SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req); @@ -287,16 +287,13 @@ static int scsi_write_data(SCSIRequest *req) if (r->len == 0) { r->len = r->buflen; scsi_req_data(&r->req, r->len); -return 0; +return; } ret = execute_command(s->bs, r, SG_DXFER_TO_DEV, scsi_write_complete); if (ret < 0) { scsi_command_complete(r, ret); -return 1; } - -return 0; } /* Return a pointer to the data buffer. */ diff --git a/hw/scsi.h b/hw/scsi.h index 5730faa..b56338d 100644 --- a/hw/scsi.h +++ b/hw/scsi.h @@ -77,7 +77,7 @@ struct SCSIDeviceInfo { void (*free_req)(SCSIRequest *req); int32_t (*send_command)(SCSIRequest *req, uint8_t *buf); void (*read_data)(SCSIRequest *req); -int (*write_data)(SCSIRequest *req); +void (*write_data)(SCSIRequest *req); void (*cancel_io)(SCSIRequest *req); uint8_t *(*get_buf)(SCSIRequest *req); int (*get_sense)(SCSIRequest *req, uint8_t *buf, int len); -- 1.7.4.4
[Qemu-devel] [PATCH v5 05/25] scsi-generic: do not use a stale aiocb
If a request is canceled after it has been completed, scsi_cancel_io would pass a stale aiocb to bdrv_aio_cancel. Avoid this. Signed-off-by: Paolo Bonzini Cc: Christoph Hellwig --- hw/scsi-generic.c |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c index f09458b..bd09983 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -91,6 +91,7 @@ static void scsi_command_complete(void *opaque, int ret) SCSIGenericReq *r = (SCSIGenericReq *)opaque; SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev); +r->req.aiocb = NULL; s->driver_status = r->io_header.driver_status; if (s->driver_status & SG_ERR_DRIVER_SENSE) s->senselen = r->io_header.sb_len_wr; @@ -163,6 +164,7 @@ static void scsi_read_complete(void * opaque, int ret) SCSIGenericReq *r = (SCSIGenericReq *)opaque; int len; +r->req.aiocb = NULL; if (ret) { DPRINTF("IO error ret %d\n", ret); scsi_command_complete(r, ret); @@ -229,6 +231,7 @@ static void scsi_write_complete(void * opaque, int ret) SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev); DPRINTF("scsi_write_complete() ret = %d\n", ret); +r->req.aiocb = NULL; if (ret) { DPRINTF("IO error\n"); scsi_command_complete(r, ret); -- 1.7.4.4
[Qemu-devel] [PATCH] target-arm: Fix compilation failure for 64 bit hosts
Use the correct _ptr aliases for manipulating the pointer to the fp_status; this fixes a compilation failure on 64 bit hosts. Signed-off-by: Peter Maydell --- Apologies for the build breakage. target-arm/translate.c | 18 +- 1 files changed, 9 insertions(+), 9 deletions(-) diff --git a/target-arm/translate.c b/target-arm/translate.c index 1501db1..f5507ec 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -980,20 +980,20 @@ static inline void gen_vfp_F1_ld0(int dp) #define VFP_GEN_ITOF(name) \ static inline void gen_vfp_##name(int dp, int neon) \ { \ -TCGv statusptr = tcg_temp_new_i32(); \ +TCGv_ptr statusptr = tcg_temp_new_ptr(); \ int offset; \ if (neon) { \ offset = offsetof(CPUState, vfp.standard_fp_status); \ } else { \ offset = offsetof(CPUState, vfp.fp_status); \ } \ -tcg_gen_addi_i32(statusptr, cpu_env, offset); \ +tcg_gen_addi_ptr(statusptr, cpu_env, offset); \ if (dp) { \ gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \ } else { \ gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \ } \ -tcg_temp_free_i32(statusptr); \ +tcg_temp_free_ptr(statusptr); \ } VFP_GEN_ITOF(uito) @@ -1003,20 +1003,20 @@ VFP_GEN_ITOF(sito) #define VFP_GEN_FTOI(name) \ static inline void gen_vfp_##name(int dp, int neon) \ { \ -TCGv statusptr = tcg_temp_new_i32(); \ +TCGv_ptr statusptr = tcg_temp_new_ptr(); \ int offset; \ if (neon) { \ offset = offsetof(CPUState, vfp.standard_fp_status); \ } else { \ offset = offsetof(CPUState, vfp.fp_status); \ } \ -tcg_gen_addi_i32(statusptr, cpu_env, offset); \ +tcg_gen_addi_ptr(statusptr, cpu_env, offset); \ if (dp) { \ gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \ } else { \ gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \ } \ -tcg_temp_free_i32(statusptr); \ +tcg_temp_free_ptr(statusptr); \ } VFP_GEN_FTOI(toui) @@ -1029,21 +1029,21 @@ VFP_GEN_FTOI(tosiz) static inline void gen_vfp_##name(int dp, int shift, int neon) \ { \ TCGv tmp_shift = tcg_const_i32(shift); \ -TCGv statusptr = tcg_temp_new_i32(); \ +TCGv_ptr statusptr = tcg_temp_new_ptr(); \ int offset; \ if (neon) { \ offset = offsetof(CPUState, vfp.standard_fp_status); \ } else { \ offset = offsetof(CPUState, vfp.fp_status); \ } \ -tcg_gen_addi_i32(statusptr, cpu_env, offset); \ +tcg_gen_addi_ptr(statusptr, cpu_env, offset); \ if (dp) { \ gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \ } else { \ gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, statusptr); \ } \ tcg_temp_free_i32(tmp_shift); \ -tcg_temp_free_i32(statusptr); \ +tcg_temp_free_ptr(statusptr); \ } VFP_GEN_FIX(tosh) VFP_GEN_FIX(tosl) -- 1.7.1
[Qemu-devel] [PATCH v5 24/25] scsi: rename arguments to the new callbacks
Signed-off-by: Paolo Bonzini Cc: Christoph Hellwig --- hw/esp.c | 10 +- hw/lsi53c895a.c | 20 ++-- hw/spapr_vscsi.c | 31 ++- hw/usb-msd.c | 10 +- 4 files changed, 34 insertions(+), 37 deletions(-) diff --git a/hw/esp.c b/hw/esp.c index 67f02ba..6d3f5d2 100644 --- a/hw/esp.c +++ b/hw/esp.c @@ -395,7 +395,7 @@ static void esp_do_dma(ESPState *s) esp_dma_done(s); } -static void esp_command_complete(SCSIRequest *req, uint32_t arg) +static void esp_command_complete(SCSIRequest *req, uint32_t status) { ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent); @@ -406,10 +406,10 @@ static void esp_command_complete(SCSIRequest *req, uint32_t arg) s->ti_size = 0; s->dma_left = 0; s->async_len = 0; -if (arg) { +if (status) { DPRINTF("Command failed\n"); } -s->status = arg; +s->status = status; s->rregs[ESP_RSTAT] = STAT_ST; esp_dma_done(s); if (s->current_req) { @@ -419,12 +419,12 @@ static void esp_command_complete(SCSIRequest *req, uint32_t arg) } } -static void esp_transfer_data(SCSIRequest *req, uint32_t arg) +static void esp_transfer_data(SCSIRequest *req, uint32_t len) { ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent); DPRINTF("transfer %d/%d\n", s->dma_left, s->ti_size); -s->async_len = arg; +s->async_len = len; s->async_buf = scsi_req_get_buf(req); if (s->dma_left) { esp_do_dma(s); diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c index abbdcfa..cc6d645 100644 --- a/hw/lsi53c895a.c +++ b/hw/lsi53c895a.c @@ -680,7 +680,7 @@ static void lsi_request_cancelled(SCSIRequest *req) /* Record that data is available for a queued command. Returns zero if the device was reselected, nonzero if the IO is deferred. */ -static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t arg) +static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t len) { lsi_request *p; @@ -693,7 +693,7 @@ static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t arg) if (p->pending) { BADF("Multiple IO pending for tag %d\n", tag); } -p->pending = arg; +p->pending = len; /* Reselect if waiting for it, or if reselection triggers an IRQ and the bus is free. Since no interrupt stacking is implemented in the emulation, it @@ -707,20 +707,20 @@ static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t arg) return 0; } else { DPRINTF("Queueing IO tag=0x%x\n", tag); -p->pending = arg; +p->pending = len; return 1; } } /* Callback to indicate that the SCSI layer has completed a command. */ -static void lsi_command_complete(SCSIRequest *req, uint32_t arg) +static void lsi_command_complete(SCSIRequest *req, uint32_t status) { LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent); int out; out = (s->sstat1 & PHASE_MASK) == PHASE_DO; -DPRINTF("Command complete status=%d\n", (int)arg); -s->status = arg; +DPRINTF("Command complete status=%d\n", (int)status); +s->status = status; s->command_complete = 2; if (s->waiting && s->dbc != 0) { /* Raise phase mismatch for short transfers. */ @@ -738,14 +738,14 @@ static void lsi_command_complete(SCSIRequest *req, uint32_t arg) } /* Callback to indicate that the SCSI layer has completed a transfer. */ -static void lsi_transfer_data(SCSIRequest *req, uint32_t arg) +static void lsi_transfer_data(SCSIRequest *req, uint32_t len) { LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent); int out; if (s->waiting == 1 || !s->current || req->tag != s->current->tag || (lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON))) { -if (lsi_queue_tag(s, req->tag, arg)) { +if (lsi_queue_tag(s, req->tag, len)) { return; } } @@ -753,8 +753,8 @@ static void lsi_transfer_data(SCSIRequest *req, uint32_t arg) out = (s->sstat1 & PHASE_MASK) == PHASE_DO; /* host adapter (re)connected */ -DPRINTF("Data ready tag=0x%x len=%d\n", req->tag, arg); -s->current->dma_len = arg; +DPRINTF("Data ready tag=0x%x len=%d\n", req->tag, len); +s->current->dma_len = len; s->command_complete = 1; if (s->waiting) { if (s->waiting == 1 || s->dbc == 0) { diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c index 57fa1cd..194db23 100644 --- a/hw/spapr_vscsi.c +++ b/hw/spapr_vscsi.c @@ -480,15 +480,15 @@ static void vscsi_send_request_sense(VSCSIState *s, vscsi_req *req) } /* Callback to indicate that the SCSI layer has completed a transfer. */ -static void vscsi_transfer_data(SCSIRequest *sreq, uint32_t arg) +static void vscsi_transfer_data(SCSIRequest *sreq, uint32_t len) { VSCSIState *s = DO_UPCAST(VSCSIState, vdev.qdev, sreq->bus->qbus.parent); vscsi_req *req = vscsi_find_req(s, s
[Qemu-devel] [PATCH v5 21/25] scsi-generic: Handle queue full
The sg driver currently has a hardcoded limit of commands it can handle simultaneously. When this limit is reached the driver will return -EDOM. So we need to capture this to enable proper return values here. Signed-off-by: Hannes Reinecke Signed-off-by: Paolo Bonzini Reviewed-by: Christoph Hellwig --- hw/scsi-generic.c |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c index 579bab9..7670606 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -124,6 +124,9 @@ static void scsi_command_complete(void *opaque, int ret) if (ret != 0) { switch (ret) { +case -EDOM: +r->req.status = TASK_SET_FULL; +break; case -EINVAL: r->req.status = CHECK_CONDITION; scsi_set_sense(s, SENSE_CODE(INVALID_FIELD)); -- 1.7.4.4
[Qemu-devel] [PATCH v5 23/25] scsi: split command_complete callback in two
Signed-off-by: Paolo Bonzini Cc: Christoph Hellwig --- hw/esp.c | 62 ++--- hw/lsi53c895a.c | 60 ++-- hw/scsi-bus.c|4 +- hw/scsi.h|9 + hw/spapr_vscsi.c | 101 ++ hw/usb-msd.c | 69 + 6 files changed, 167 insertions(+), 138 deletions(-) diff --git a/hw/esp.c b/hw/esp.c index 7af20a8..67f02ba 100644 --- a/hw/esp.c +++ b/hw/esp.c @@ -395,38 +395,43 @@ static void esp_do_dma(ESPState *s) esp_dma_done(s); } -static void esp_command_complete(SCSIRequest *req, int reason, uint32_t arg) +static void esp_command_complete(SCSIRequest *req, uint32_t arg) { ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent); -if (reason == SCSI_REASON_DONE) { -DPRINTF("SCSI Command complete\n"); -if (s->ti_size != 0) -DPRINTF("SCSI command completed unexpectedly\n"); -s->ti_size = 0; -s->dma_left = 0; -s->async_len = 0; -if (arg) -DPRINTF("Command failed\n"); -s->status = arg; -s->rregs[ESP_RSTAT] = STAT_ST; +DPRINTF("SCSI Command complete\n"); +if (s->ti_size != 0) { +DPRINTF("SCSI command completed unexpectedly\n"); +} +s->ti_size = 0; +s->dma_left = 0; +s->async_len = 0; +if (arg) { +DPRINTF("Command failed\n"); +} +s->status = arg; +s->rregs[ESP_RSTAT] = STAT_ST; +esp_dma_done(s); +if (s->current_req) { +scsi_req_unref(s->current_req); +s->current_req = NULL; +s->current_dev = NULL; +} +} + +static void esp_transfer_data(SCSIRequest *req, uint32_t arg) +{ +ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent); + +DPRINTF("transfer %d/%d\n", s->dma_left, s->ti_size); +s->async_len = arg; +s->async_buf = scsi_req_get_buf(req); +if (s->dma_left) { +esp_do_dma(s); +} else if (s->dma_counter != 0 && s->ti_size <= 0) { +/* If this was the last part of a DMA transfer then the + completion interrupt is deferred to here. */ esp_dma_done(s); -if (s->current_req) { -scsi_req_unref(s->current_req); -s->current_req = NULL; -s->current_dev = NULL; -} -} else { -DPRINTF("transfer %d/%d\n", s->dma_left, s->ti_size); -s->async_len = arg; -s->async_buf = scsi_req_get_buf(req); -if (s->dma_left) { -esp_do_dma(s); -} else if (s->dma_counter != 0 && s->ti_size <= 0) { -/* If this was the last part of a DMA transfer then the - completion interrupt is deferred to here. */ -esp_dma_done(s); -} } } @@ -725,6 +730,7 @@ void esp_init(target_phys_addr_t espaddr, int it_shift, } static const struct SCSIBusOps esp_scsi_ops = { +.transfer_data = esp_transfer_data, .complete = esp_command_complete, .cancel = esp_request_cancelled }; diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c index 925193d..abbdcfa 100644 --- a/hw/lsi53c895a.c +++ b/hw/lsi53c895a.c @@ -711,50 +711,57 @@ static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t arg) return 1; } } - /* Callback to indicate that the SCSI layer has completed a transfer. */ -static void lsi_command_complete(SCSIRequest *req, int reason, uint32_t arg) + + /* Callback to indicate that the SCSI layer has completed a command. */ +static void lsi_command_complete(SCSIRequest *req, uint32_t arg) { LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent); int out; out = (s->sstat1 & PHASE_MASK) == PHASE_DO; -if (reason == SCSI_REASON_DONE) { -DPRINTF("Command complete status=%d\n", (int)arg); -s->status = arg; -s->command_complete = 2; -if (s->waiting && s->dbc != 0) { -/* Raise phase mismatch for short transfers. */ -lsi_bad_phase(s, out, PHASE_ST); -} else { -lsi_set_phase(s, PHASE_ST); -} +DPRINTF("Command complete status=%d\n", (int)arg); +s->status = arg; +s->command_complete = 2; +if (s->waiting && s->dbc != 0) { +/* Raise phase mismatch for short transfers. */ +lsi_bad_phase(s, out, PHASE_ST); +} else { +lsi_set_phase(s, PHASE_ST); +} -if (s->current && req == s->current->req) { -scsi_req_unref(s->current->req); -qemu_free(s->current); -s->current = NULL; -} -lsi_resume_script(s); -return; +if (s->current && req == s->current->req) { +scsi_req_unref(s->current->req); +qemu_free(s->current); +s->current = NULL; } +lsi_resume_script(s); +} + + /* Callback to indicate that the SCSI layer has completed a transfer. */ +static void lsi_transfer_data(SCSIRequest *req, uint
[Qemu-devel] [PATCH v5 18/25] scsi: Implement 'get_sense' callback
From: Hannes Reinecke The get_sense callback copies existing sense information into the provided buffer. This is required if sense information should be transferred together with the command response. Signed-off-by: Hannes Reinecke Signed-off-by: Paolo Bonzini Reviewed-by: Christoph Hellwig --- hw/scsi-bus.c |9 + hw/scsi-disk.c| 11 +++ hw/scsi-generic.c | 18 ++ hw/scsi.h |2 ++ hw/spapr_vscsi.c | 10 +- 5 files changed, 49 insertions(+), 1 deletions(-) diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index 64ee464..126fd0f 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -156,6 +156,15 @@ uint8_t *scsi_req_get_buf(SCSIRequest *req) return req->dev->info->get_buf(req); } +int scsi_req_get_sense(SCSIRequest *req, uint8_t *buf, int len) +{ +if (req->dev->info->get_sense) { +return req->dev->info->get_sense(req, buf, len); +} else { +return 0; +} +} + int32_t scsi_req_enqueue(SCSIRequest *req, uint8_t *buf) { int32_t rc; diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index adee8fe..9567c7c 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -340,6 +340,14 @@ static uint8_t *scsi_get_buf(SCSIRequest *req) return (uint8_t *)r->iov.iov_base; } +/* Copy sense information into the provided buffer */ +static int scsi_get_sense(SCSIRequest *req, uint8_t *outbuf, int len) +{ +SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev); + +return scsi_build_sense(s->sense, outbuf, len, len > 14); +} + static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev); @@ -1257,6 +1265,7 @@ static SCSIDeviceInfo scsi_disk_info[] = { .write_data = scsi_write_data, .cancel_io= scsi_cancel_io, .get_buf = scsi_get_buf, +.get_sense= scsi_get_sense, .qdev.props = (Property[]) { DEFINE_SCSI_DISK_PROPERTIES(), DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false), @@ -1277,6 +1286,7 @@ static SCSIDeviceInfo scsi_disk_info[] = { .write_data = scsi_write_data, .cancel_io= scsi_cancel_io, .get_buf = scsi_get_buf, +.get_sense= scsi_get_sense, .qdev.props = (Property[]) { DEFINE_SCSI_DISK_PROPERTIES(), DEFINE_PROP_END_OF_LIST(), @@ -1296,6 +1306,7 @@ static SCSIDeviceInfo scsi_disk_info[] = { .write_data = scsi_write_data, .cancel_io= scsi_cancel_io, .get_buf = scsi_get_buf, +.get_sense= scsi_get_sense, .qdev.props = (Property[]) { DEFINE_SCSI_DISK_PROPERTIES(), DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false), diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c index 90f2a4a..fc015e0 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -79,6 +79,23 @@ static void scsi_clear_sense(SCSIGenericState *s) s->driver_status = 0; } +static int scsi_get_sense(SCSIRequest *req, uint8_t *outbuf, int len) +{ +SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req->dev); +int size = SCSI_SENSE_BUF_SIZE; + +if (!(s->driver_status & SG_ERR_DRIVER_SENSE)) { +size = scsi_build_sense(SENSE_CODE(NO_SENSE), s->sensebuf, +SCSI_SENSE_BUF_SIZE, 0); +} +if (size > len) { +size = len; +} +memcpy(outbuf, s->sensebuf, size); + +return size; +} + static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun) { SCSIRequest *req; @@ -535,6 +552,7 @@ static SCSIDeviceInfo scsi_generic_info = { .write_data = scsi_write_data, .cancel_io= scsi_cancel_io, .get_buf = scsi_get_buf, +.get_sense= scsi_get_sense, .qdev.props = (Property[]) { DEFINE_BLOCK_PROPERTIES(SCSIGenericState, qdev.conf), DEFINE_PROP_END_OF_LIST(), diff --git a/hw/scsi.h b/hw/scsi.h index edf6828..5730faa 100644 --- a/hw/scsi.h +++ b/hw/scsi.h @@ -80,6 +80,7 @@ struct SCSIDeviceInfo { int (*write_data)(SCSIRequest *req); void (*cancel_io)(SCSIRequest *req); uint8_t *(*get_buf)(SCSIRequest *req); +int (*get_sense)(SCSIRequest *req, uint8_t *buf, int len); }; struct SCSIBusOps { @@ -155,6 +156,7 @@ void scsi_req_continue(SCSIRequest *req); void scsi_req_data(SCSIRequest *req, int len); void scsi_req_complete(SCSIRequest *req); uint8_t *scsi_req_get_buf(SCSIRequest *req); +int scsi_req_get_sense(SCSIRequest *req, uint8_t *buf, int len); void scsi_req_abort(SCSIRequest *req, int status); void scsi_req_cancel(SCSIRequest *req); void scsi_device_purge_requests(SCSIDevice *sdev); diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c index 46b0c73..33bff6a 100644 --- a/hw/spapr_vscsi.c +++ b/hw/spapr_vscsi.c @@ -450,6 +450,15 @@ static void vscsi_send_request_sense(VSCSIState *s, vscsi_req *req) uint8_t *cdb = req
[Qemu-devel] [PATCH v5 08/25] scsi: Use 'SCSIRequest' directly
From: Hannes Reinecke Currently the SCSIRequest structure is abstracted away and cannot accessed directly from the driver. This requires the handler to do a lookup on an abstract 'tag' which identifies the SCSIRequest structure. With this patch the SCSIRequest structure is exposed to the driver. This allows use to use it directly as an argument to the SCSIDeviceInfo callback functions and remove the lookup. A new callback function 'alloc_req' is introduced matching 'free req'; unref'ing to free up resources after use is moved into the scsi_command_complete callbacks. This temporarily introduces a leak of requests that are cancelled, when they are removed from the queue and not from the driver. This is fixed later by introducing scsi_req_cancel. That patch in turn depends on this one, because the argument to scsi_req_cancel is a SCSIRequest. Signed-off-by: Hannes Reinecke Signed-off-by: Paolo Bonzini Reviewed-by: Christoph Hellwig --- hw/esp.c | 27 +++- hw/lsi53c895a.c | 56 ++--- hw/scsi-bus.c | 25 hw/scsi-disk.c| 118 +++-- hw/scsi-generic.c | 107 +++- hw/scsi.h | 21 +- hw/spapr_vscsi.c | 44 +++- hw/usb-msd.c | 27 +++- 8 files changed, 173 insertions(+), 252 deletions(-) diff --git a/hw/esp.c b/hw/esp.c index ae18401..7763c72 100644 --- a/hw/esp.c +++ b/hw/esp.c @@ -65,6 +65,7 @@ struct ESPState { uint32_t dma; SCSIBus bus; SCSIDevice *current_dev; +SCSIRequest *current_req; uint8_t cmdbuf[TI_BUFSZ]; uint32_t cmdlen; uint32_t do_cmd; @@ -209,7 +210,7 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf) if (s->current_dev) { /* Started a new command before the old one finished. Cancel it. */ -s->current_dev->info->cancel_io(s->current_dev, 0); +s->current_dev->info->cancel_io(s->current_req); s->async_len = 0; } @@ -232,7 +233,8 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid) DPRINTF("do_busid_cmd: busid 0x%x\n", busid); lun = busid & 7; -datalen = s->current_dev->info->send_command(s->current_dev, 0, buf, lun); +s->current_req = s->current_dev->info->alloc_req(s->current_dev, 0, lun); +datalen = s->current_dev->info->send_command(s->current_req, buf); s->ti_size = datalen; if (datalen != 0) { s->rregs[ESP_RSTAT] = STAT_TC; @@ -240,10 +242,10 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid) s->dma_counter = 0; if (datalen > 0) { s->rregs[ESP_RSTAT] |= STAT_DI; -s->current_dev->info->read_data(s->current_dev, 0); +s->current_dev->info->read_data(s->current_req); } else { s->rregs[ESP_RSTAT] |= STAT_DO; -s->current_dev->info->write_data(s->current_dev, 0); +s->current_dev->info->write_data(s->current_req); } } s->rregs[ESP_RINTR] = INTR_BS | INTR_FC; @@ -372,9 +374,9 @@ static void esp_do_dma(ESPState *s) if (s->async_len == 0) { if (to_device) { // ti_size is negative -s->current_dev->info->write_data(s->current_dev, 0); +s->current_dev->info->write_data(s->current_req); } else { -s->current_dev->info->read_data(s->current_dev, 0); +s->current_dev->info->read_data(s->current_req); /* If there is still data to be read from the device then complete the DMA operation immediately. Otherwise defer until the scsi layer has completed. */ @@ -388,10 +390,9 @@ static void esp_do_dma(ESPState *s) } } -static void esp_command_complete(SCSIBus *bus, int reason, uint32_t tag, - uint32_t arg) +static void esp_command_complete(SCSIRequest *req, int reason, uint32_t arg) { -ESPState *s = DO_UPCAST(ESPState, busdev.qdev, bus->qbus.parent); +ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent); if (reason == SCSI_REASON_DONE) { DPRINTF("SCSI Command complete\n"); @@ -405,11 +406,15 @@ static void esp_command_complete(SCSIBus *bus, int reason, uint32_t tag, s->sense = arg; s->rregs[ESP_RSTAT] = STAT_ST; esp_dma_done(s); -s->current_dev = NULL; +if (s->current_req) { +scsi_req_unref(s->current_req); +s->current_req = NULL; +s->current_dev = NULL; +} } else { DPRINTF("transfer %d/%d\n", s->dma_left, s->ti_size); s->async_len = arg; -s->async_buf = s->current_dev->info->get_buf(s->current_dev, 0); +s->async_buf = s->current_dev->info->get_buf(req); if (s->dma_left) { esp_do_dma(s); } else if (s->dma_counter != 0 && s->ti_size <= 0) { diff --git a/hw/l
[Qemu-devel] [PATCH v5 22/25] esp: rename sense to status
This mirrors the LSI patch that was recently committed. Signed-off-by: Paolo Bonzini Cc: Christoph Hellwig --- hw/esp.c | 10 +- 1 files changed, 5 insertions(+), 5 deletions(-) diff --git a/hw/esp.c b/hw/esp.c index cd6dfc7..7af20a8 100644 --- a/hw/esp.c +++ b/hw/esp.c @@ -61,7 +61,7 @@ struct ESPState { int32_t ti_size; uint32_t ti_rptr, ti_wptr; uint8_t ti_buf[TI_BUFSZ]; -uint32_t sense; +uint32_t status; uint32_t dma; SCSIBus bus; SCSIDevice *current_dev; @@ -318,8 +318,8 @@ static void handle_satn_stop(ESPState *s) static void write_response(ESPState *s) { -DPRINTF("Transfer status (sense=%d)\n", s->sense); -s->ti_buf[0] = s->sense; +DPRINTF("Transfer status (status=%d)\n", s->status); +s->ti_buf[0] = s->status; s->ti_buf[1] = 0; if (s->dma) { s->dma_memory_write(s->dma_opaque, s->ti_buf, 2); @@ -408,7 +408,7 @@ static void esp_command_complete(SCSIRequest *req, int reason, uint32_t arg) s->async_len = 0; if (arg) DPRINTF("Command failed\n"); -s->sense = arg; +s->status = arg; s->rregs[ESP_RSTAT] = STAT_ST; esp_dma_done(s); if (s->current_req) { @@ -688,7 +688,7 @@ static const VMStateDescription vmstate_esp = { VMSTATE_UINT32(ti_rptr, ESPState), VMSTATE_UINT32(ti_wptr, ESPState), VMSTATE_BUFFER(ti_buf, ESPState), -VMSTATE_UINT32(sense, ESPState), +VMSTATE_UINT32(status, ESPState), VMSTATE_UINT32(dma, ESPState), VMSTATE_BUFFER(cmdbuf, ESPState), VMSTATE_UINT32(cmdlen, ESPState), -- 1.7.4.4
[Qemu-devel] [PATCH v5 25/25] scsi: ignore LUN field in the CDB
The LUN field in the CDB is a historical relic. Ignore it as reserved, which is what modern SCSI specifications actually say. Signed-off-by: Paolo Bonzini Reviewed-by: Christoph Hellwig --- hw/scsi-disk.c|6 +++--- hw/scsi-generic.c |5 ++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index e0c384f..a8c7372 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -518,7 +518,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) memset(outbuf, 0, buflen); -if (req->lun || req->cmd.buf[1] >> 5) { +if (req->lun) { outbuf[0] = 0x7f; /* LUN not supported */ return buflen; } @@ -1024,9 +1024,9 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf) } #endif -if (req->lun || buf[1] >> 5) { +if (req->lun) { /* Only LUN 0 supported. */ -DPRINTF("Unimplemented LUN %d\n", req->lun ? req->lun : buf[1] >> 5); +DPRINTF("Unimplemented LUN %d\n", req->lun); if (command != REQUEST_SENSE && command != INQUIRY) { scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(LUN_NOT_SUPPORTED)); diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c index 7670606..8e59c7e 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -337,9 +337,8 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd) SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req); int ret; -if (cmd[0] != REQUEST_SENSE && -(req->lun != s->lun || (cmd[1] >> 5) != s->lun)) { -DPRINTF("Unimplemented LUN %d\n", req->lun ? req->lun : cmd[1] >> 5); +if (cmd[0] != REQUEST_SENSE && req->lun != s->lun) { +DPRINTF("Unimplemented LUN %d\n", req->lun); scsi_set_sense(s, SENSE_CODE(LUN_NOT_SUPPORTED)); r->req.status = CHECK_CONDITION; scsi_req_complete(&r->req); -- 1.7.4.4
[Qemu-devel] [PATCH v5 17/25] scsi: introduce scsi_req_get_buf
... and remove some SCSIDevice variables or fields that now become unused. Signed-off-by: Paolo Bonzini Reviewed-by: Christoph Hellwig --- hw/esp.c |2 +- hw/lsi53c895a.c |2 +- hw/scsi-bus.c|5 + hw/scsi.h|1 + hw/spapr_vscsi.c |8 ++-- hw/usb-msd.c |2 +- 6 files changed, 11 insertions(+), 9 deletions(-) diff --git a/hw/esp.c b/hw/esp.c index f41c4d3..cd6dfc7 100644 --- a/hw/esp.c +++ b/hw/esp.c @@ -419,7 +419,7 @@ static void esp_command_complete(SCSIRequest *req, int reason, uint32_t arg) } else { DPRINTF("transfer %d/%d\n", s->dma_left, s->ti_size); s->async_len = arg; -s->async_buf = s->current_dev->info->get_buf(req); +s->async_buf = scsi_req_get_buf(req); if (s->dma_left) { esp_do_dma(s); } else if (s->dma_counter != 0 && s->ti_size <= 0) { diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c index 2e2afec..925193d 100644 --- a/hw/lsi53c895a.c +++ b/hw/lsi53c895a.c @@ -569,7 +569,7 @@ static void lsi_do_dma(LSIState *s, int out) s->dnad += count; s->dbc -= count; if (s->current->dma_buf == NULL) { -s->current->dma_buf = dev->info->get_buf(s->current->req); +s->current->dma_buf = scsi_req_get_buf(s->current->req); } /* ??? Set SFBR to first data byte. */ if (out) { diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index a2ae912..64ee464 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -151,6 +151,11 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun) return d->info->alloc_req(d, tag, lun); } +uint8_t *scsi_req_get_buf(SCSIRequest *req) +{ +return req->dev->info->get_buf(req); +} + int32_t scsi_req_enqueue(SCSIRequest *req, uint8_t *buf) { int32_t rc; diff --git a/hw/scsi.h b/hw/scsi.h index 6fd75dd..edf6828 100644 --- a/hw/scsi.h +++ b/hw/scsi.h @@ -154,6 +154,7 @@ void scsi_req_print(SCSIRequest *req); void scsi_req_continue(SCSIRequest *req); void scsi_req_data(SCSIRequest *req, int len); void scsi_req_complete(SCSIRequest *req); +uint8_t *scsi_req_get_buf(SCSIRequest *req); void scsi_req_abort(SCSIRequest *req, int status); void scsi_req_cancel(SCSIRequest *req); void scsi_device_purge_requests(SCSIDevice *sdev); diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c index ab00bfd..46b0c73 100644 --- a/hw/spapr_vscsi.c +++ b/hw/spapr_vscsi.c @@ -74,7 +74,6 @@ typedef struct vscsi_req { union viosrp_iu iu; /* SCSI request tracking */ -SCSIDevice *sdev; SCSIRequest *sreq; uint32_tqtag; /* qemu tag != srp tag */ int lun; @@ -476,7 +475,6 @@ static void vscsi_command_complete(SCSIRequest *sreq, int reason, uint32_t arg) { VSCSIState *s = DO_UPCAST(VSCSIState, vdev.qdev, sreq->bus->qbus.parent); vscsi_req *req = vscsi_find_req(s, sreq); -SCSIDevice *sdev; uint8_t *buf; int32_t res_in = 0, res_out = 0; int len, rc = 0; @@ -487,7 +485,6 @@ static void vscsi_command_complete(SCSIRequest *sreq, int reason, uint32_t arg) fprintf(stderr, "VSCSI: Can't find request for tag 0x%x\n", sreq->tag); return; } -sdev = req->sdev; if (req->sensing) { if (reason == SCSI_REASON_DONE) { @@ -495,7 +492,7 @@ static void vscsi_command_complete(SCSIRequest *sreq, int reason, uint32_t arg) vscsi_send_rsp(s, req, CHECK_CONDITION, 0, 0); vscsi_put_req(s, req); } else { -uint8_t *buf = sdev->info->get_buf(sreq); +uint8_t *buf = scsi_req_get_buf(sreq); len = MIN(arg, SCSI_SENSE_BUF_SIZE); dprintf("VSCSI: Sense data, %d bytes:\n", len); @@ -539,7 +536,7 @@ static void vscsi_command_complete(SCSIRequest *sreq, int reason, uint32_t arg) * to write for writes (ie, how much is to be DMA'd) */ if (arg) { -buf = sdev->info->get_buf(sreq); +buf = scsi_req_get_buf(sreq); rc = vscsi_srp_transfer_data(s, req, req->writing, buf, arg); } if (rc < 0) { @@ -646,7 +643,6 @@ static int vscsi_queue_cmd(VSCSIState *s, vscsi_req *req) } return 1; } -req->sdev = sdev; req->lun = lun; req->sreq = scsi_req_new(sdev, req->qtag, lun); n = scsi_req_enqueue(req->sreq, srp->cmd.cdb); diff --git a/hw/usb-msd.c b/hw/usb-msd.c index d4c2234..78b57a6 100644 --- a/hw/usb-msd.c +++ b/hw/usb-msd.c @@ -247,7 +247,7 @@ static void usb_msd_command_complete(SCSIRequest *req, int reason, uint32_t arg) } assert((s->mode == USB_MSDM_DATAOUT) == (req->cmd.mode == SCSI_XFER_TO_DEV)); s->scsi_len = arg; -s->scsi_buf = s->scsi_dev->info->get_buf(req); +s->scsi_buf = scsi_req_get_buf(req); if (p) { usb_msd_copy_data(s); if (s->usb_len == 0) { -- 1.7.4.4
[Qemu-devel] [PATCH v5 16/25] scsi: introduce scsi_req_continue
Signed-off-by: Paolo Bonzini Cc: Christoph Hellwig --- hw/esp.c | 26 ++ hw/lsi53c895a.c | 22 -- hw/scsi-bus.c| 16 +--- hw/scsi.h|1 + hw/spapr_vscsi.c | 26 ++ hw/usb-msd.c | 15 --- trace-events |1 + 7 files changed, 47 insertions(+), 60 deletions(-) diff --git a/hw/esp.c b/hw/esp.c index 9f716e9..f41c4d3 100644 --- a/hw/esp.c +++ b/hw/esp.c @@ -253,11 +253,10 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid) s->dma_counter = 0; if (datalen > 0) { s->rregs[ESP_RSTAT] |= STAT_DI; -s->current_dev->info->read_data(s->current_req); } else { s->rregs[ESP_RSTAT] |= STAT_DO; -s->current_dev->info->write_data(s->current_req); } +scsi_req_continue(s->current_req); } s->rregs[ESP_RINTR] = INTR_BS | INTR_FC; s->rregs[ESP_RSEQ] = SEQ_CD; @@ -383,22 +382,17 @@ static void esp_do_dma(ESPState *s) else s->ti_size -= len; if (s->async_len == 0) { -if (to_device) { -// ti_size is negative -s->current_dev->info->write_data(s->current_req); -} else { -s->current_dev->info->read_data(s->current_req); -/* If there is still data to be read from the device then - complete the DMA operation immediately. Otherwise defer - until the scsi layer has completed. */ -if (s->dma_left == 0 && s->ti_size > 0) { -esp_dma_done(s); -} +scsi_req_continue(s->current_req); +/* If there is still data to be read from the device then + complete the DMA operation immediately. Otherwise defer + until the scsi layer has completed. */ +if (to_device || s->dma_left != 0 || s->ti_size == 0) { +return; } -} else { -/* Partially filled a scsi buffer. Complete immediately. */ -esp_dma_done(s); } + +/* Partially filled a scsi buffer. Complete immediately. */ +esp_dma_done(s); } static void esp_command_complete(SCSIRequest *req, int reason, uint32_t arg) diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c index 6d56e09..2e2afec 100644 --- a/hw/lsi53c895a.c +++ b/hw/lsi53c895a.c @@ -580,13 +580,7 @@ static void lsi_do_dma(LSIState *s, int out) s->current->dma_len -= count; if (s->current->dma_len == 0) { s->current->dma_buf = NULL; -if (out) { -/* Write the data. */ -dev->info->write_data(s->current->req); -} else { -/* Request any remaining data. */ -dev->info->read_data(s->current->req); -} +scsi_req_continue(s->current->req); } else { s->current->dma_buf += count; lsi_resume_script(s); @@ -791,14 +785,14 @@ static void lsi_do_command(LSIState *s) s->current->req = scsi_req_new(dev, s->current->tag, s->current_lun); n = scsi_req_enqueue(s->current->req, buf); -if (n > 0) { -lsi_set_phase(s, PHASE_DI); -dev->info->read_data(s->current->req); -} else if (n < 0) { -lsi_set_phase(s, PHASE_DO); -dev->info->write_data(s->current->req); +if (n) { +if (n > 0) { +lsi_set_phase(s, PHASE_DI); +} else if (n < 0) { +lsi_set_phase(s, PHASE_DO); +} +scsi_req_continue(s->current->req); } - if (!s->command_complete) { if (n) { /* Command did not complete immediately so disconnect. */ diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index 4506ac9..a2ae912 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -602,11 +602,21 @@ void scsi_req_unref(SCSIRequest *req) } } +/* Tell the device that we finished processing this chunk of I/O. It + will start the next chunk or complete the command. */ +void scsi_req_continue(SCSIRequest *req) +{ +trace_scsi_req_continue(req->dev->id, req->lun, req->tag); +if (req->cmd.mode == SCSI_XFER_TO_DEV) { +req->dev->info->write_data(req); +} else { +req->dev->info->read_data(req); +} +} + /* Called by the devices when data is ready for the HBA. The HBA should start a DMA operation to read or fill the device's data buffer. - Once it completes, calling one of req->dev->info->read_data or - req->dev->info->write_data (depending on the direction of the - transfer) will restart I/O. */ + 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); diff --git a/hw/scsi.h b/hw/scsi.h index 928cbf3..6fd75dd 100644 --- a/hw/scsi.h +++ b/hw/scsi.h @@ -151,6 +151,7 @@ void scsi_req_unref(SCSIRequest *req); int scsi_req_parse(SCSIRequest *req, uint8_t *buf); void scsi_req_print(SCSIRequest *req); +voi
[Qemu-devel] [PATCH v5 19/25] scsi-disk: add data direction checking
From: Hannes Reinecke scsi_req_parse() already provides for a data direction setting, so we should be using it to check for correct direction. And we should return the sense code 'INVALID FIELD IN CDB' in these cases. Signed-off-by: Hannes Reinecke Signed-off-by: Paolo Bonzini Reviewed-by: Christoph Hellwig --- hw/scsi-disk.c | 35 --- 1 files changed, 24 insertions(+), 11 deletions(-) diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 9567c7c..f3eba52 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -51,8 +51,6 @@ typedef struct SCSIDiskState SCSIDiskState; typedef struct SCSIDiskReq { SCSIRequest req; -/* ??? We should probably keep track of whether the data transfer is - a read or a write. Currently we rely on the host getting it right. */ /* Both sector and sector_count are in terms of qemu 512 byte blocks. */ uint64_t sector; uint32_t sector_count; @@ -180,6 +178,12 @@ static void scsi_read_data(SCSIRequest *req) /* No data transfer may already be in progress */ assert(r->req.aiocb == NULL); +if (r->req.cmd.mode == SCSI_XFER_TO_DEV) { +DPRINTF("Data transfer direction invalid\n"); +scsi_read_complete(r, -EINVAL); +return; +} + n = r->sector_count; if (n > SCSI_DMA_BUF_SIZE / 512) n = SCSI_DMA_BUF_SIZE / 512; @@ -216,16 +220,22 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type) if (type == SCSI_REQ_STATUS_RETRY_READ) { scsi_req_data(&r->req, 0); } -if (error == ENOMEM) { +switch (error) { +case ENOMEM: scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(TARGET_FAILURE)); -} else { +break; +case EINVAL: +scsi_command_complete(r, CHECK_CONDITION, + SENSE_CODE(INVALID_FIELD)); +break; +default: scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(IO_ERROR)); +break; } bdrv_mon_event(s->bs, BDRV_ACTION_REPORT, is_read); } - return 1; } @@ -268,6 +278,12 @@ static int scsi_write_data(SCSIRequest *req) /* No data transfer may already be in progress */ assert(r->req.aiocb == NULL); +if (r->req.cmd.mode != SCSI_XFER_TO_DEV) { +DPRINTF("Data transfer direction invalid\n"); +scsi_write_complete(r, -EINVAL); +return 0; +} + n = r->iov.iov_len / 512; if (n) { qemu_iovec_init_external(&r->qiov, &r->iov, 1); @@ -987,14 +1003,12 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf) SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req); SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev); int32_t len; -int is_write; uint8_t command; uint8_t *outbuf; int rc; command = buf[0]; outbuf = (uint8_t *)r->iov.iov_base; -is_write = 0; DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]); if (scsi_req_parse(&r->req, buf) != 0) { @@ -1074,7 +1088,6 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf) goto illegal_lba; r->sector = r->req.cmd.lba * s->cluster_size; r->sector_count = len * s->cluster_size; -is_write = 1; break; case MODE_SELECT: DPRINTF("Mode Select(6) (len %lu)\n", (long)r->req.cmd.xfer); @@ -1140,13 +1153,13 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf) scsi_command_complete(r, GOOD, SENSE_CODE(NO_SENSE)); } len = r->sector_count * 512 + r->iov.iov_len; -if (is_write) { -len = -len; +if (r->req.cmd.mode == SCSI_XFER_TO_DEV) { +return -len; } else { if (!r->sector_count) r->sector_count = -1; +return len; } -return len; } static void scsi_disk_reset(DeviceState *dev) -- 1.7.4.4
[Qemu-devel] [PATCH v5 14/25] scsi: do not call send_command directly
Move the common part of scsi-disk.c and scsi-generic.c to the SCSI layer. Signed-off-by: Paolo Bonzini Reviewed-by: Christoph Hellwig --- hw/esp.c |2 +- hw/lsi53c895a.c |2 +- hw/scsi-bus.c |9 - hw/scsi-disk.c|1 - hw/scsi-generic.c |1 - hw/scsi.h |2 +- hw/spapr_vscsi.c |4 ++-- hw/usb-msd.c |2 +- 8 files changed, 14 insertions(+), 9 deletions(-) diff --git a/hw/esp.c b/hw/esp.c index ba3fa94..49f3e7b 100644 --- a/hw/esp.c +++ b/hw/esp.c @@ -245,7 +245,7 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid) DPRINTF("do_busid_cmd: busid 0x%x\n", busid); lun = busid & 7; s->current_req = s->current_dev->info->alloc_req(s->current_dev, 0, lun); -datalen = s->current_dev->info->send_command(s->current_req, buf); +datalen = scsi_req_enqueue(s->current_req, buf); s->ti_size = datalen; if (datalen != 0) { s->rregs[ESP_RSTAT] = STAT_TC; diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c index f3a1488..538cb49 100644 --- a/hw/lsi53c895a.c +++ b/hw/lsi53c895a.c @@ -791,7 +791,7 @@ static void lsi_do_command(LSIState *s) s->current->req = dev->info->alloc_req(dev, s->current->tag, s->current_lun); -n = dev->info->send_command(s->current->req, buf); +n = scsi_req_enqueue(s->current->req, buf); if (n > 0) { lsi_set_phase(s, PHASE_DI); dev->info->read_data(s->current->req); diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index 732772a..afec0c8 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -146,12 +146,19 @@ SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t l return req; } -void scsi_req_enqueue(SCSIRequest *req) +int32_t scsi_req_enqueue(SCSIRequest *req, uint8_t *buf) { +int32_t rc; + assert(!req->enqueued); scsi_req_ref(req); req->enqueued = true; QTAILQ_INSERT_TAIL(&req->dev->requests, req, next); + +scsi_req_ref(req); +rc = req->dev->info->send_command(req, buf); +scsi_req_unref(req); +return rc; } static void scsi_req_dequeue(SCSIRequest *req) diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 63aa8f1..adee8fe 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -984,7 +984,6 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf) uint8_t *outbuf; int rc; -scsi_req_enqueue(req); command = buf[0]; outbuf = (uint8_t *)r->iov.iov_base; is_write = 0; diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c index 64cbe8b..90f2a4a 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -320,7 +320,6 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd) SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req); int ret; -scsi_req_enqueue(req); if (cmd[0] != REQUEST_SENSE && (req->lun != s->lun || (cmd[1] >> 5) != s->lun)) { DPRINTF("Unimplemented LUN %d\n", req->lun ? req->lun : cmd[1] >> 5); diff --git a/hw/scsi.h b/hw/scsi.h index 7a7c9ef..839bc0b 100644 --- a/hw/scsi.h +++ b/hw/scsi.h @@ -143,7 +143,7 @@ int scsi_build_sense(SCSISense sense, uint8_t *buf, int len, int fixed); int scsi_sense_valid(SCSISense sense); SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t lun); -void scsi_req_enqueue(SCSIRequest *req); +int32_t scsi_req_enqueue(SCSIRequest *req, uint8_t *buf); void scsi_req_free(SCSIRequest *req); SCSIRequest *scsi_req_ref(SCSIRequest *req); void scsi_req_unref(SCSIRequest *req); diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c index 9bcde72..125a454 100644 --- a/hw/spapr_vscsi.c +++ b/hw/spapr_vscsi.c @@ -459,7 +459,7 @@ static void vscsi_send_request_sense(VSCSIState *s, vscsi_req *req) cdb[4] = 96; cdb[5] = 0; req->sensing = 1; -n = sdev->info->send_command(req->sreq, cdb); +n = scsi_req_enqueue(req->sreq, cdb); dprintf("VSCSI: Queued request sense tag 0x%x\n", req->qtag); if (n < 0) { fprintf(stderr, "VSCSI: REQUEST_SENSE wants write data !?!?!?\n"); @@ -654,7 +654,7 @@ static int vscsi_queue_cmd(VSCSIState *s, vscsi_req *req) req->sdev = sdev; req->lun = lun; req->sreq = sdev->info->alloc_req(sdev, req->qtag, lun); -n = sdev->info->send_command(req->sreq, srp->cmd.cdb); +n = scsi_req_enqueue(req->sreq, srp->cmd.cdb); dprintf("VSCSI: Queued command tag 0x%x CMD 0x%x ID %d LUN %d ret: %d\n", req->qtag, srp->cmd.cdb[0], id, lun, n); diff --git a/hw/usb-msd.c b/hw/usb-msd.c index ce92682..ccfae61 100644 --- a/hw/usb-msd.c +++ b/hw/usb-msd.c @@ -378,7 +378,7 @@ static int usb_msd_handle_data(USBDevice *dev, USBPacket *p) s->residue = 0; s->scsi_len = 0; s->req = s->scsi_dev->info->alloc_req(s->scsi_dev, s->tag, 0); -s->scsi_dev->info->send_command(s->req, cbw.cmd); +scsi_req_enqueue(s->req, cbw.cmd); /* ??? Should check that USB
[Qemu-devel] [PATCH v5 12/25] scsi: use scsi_req_complete
Signed-off-by: Paolo Bonzini Reviewed-by: Christoph Hellwig --- hw/scsi-generic.c |5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c index c008e9c..229d24f 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -290,7 +290,6 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd) { SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req->dev); SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req); -SCSIBus *bus; int ret; scsi_req_enqueue(req); @@ -307,8 +306,8 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd) s->sensebuf[6] = 0x00; s->senselen = 7; s->driver_status = SG_ERR_DRIVER_SENSE; -bus = scsi_bus_from_device(&s->qdev); -bus->ops->complete(req, SCSI_REASON_DONE, CHECK_CONDITION); +r->req.status = CHECK_CONDITION; +scsi_req_complete(&r->req); return 0; } -- 1.7.4.4
[Qemu-devel] [PATCH v5 15/25] scsi: introduce scsi_req_new
Signed-off-by: Paolo Bonzini Reviewed-by: Christoph Hellwig --- hw/esp.c |2 +- hw/lsi53c895a.c |3 +-- hw/scsi-bus.c|5 + hw/scsi.h|1 + hw/spapr_vscsi.c |2 +- hw/usb-msd.c |2 +- 6 files changed, 10 insertions(+), 5 deletions(-) diff --git a/hw/esp.c b/hw/esp.c index 49f3e7b..9f716e9 100644 --- a/hw/esp.c +++ b/hw/esp.c @@ -244,7 +244,7 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid) DPRINTF("do_busid_cmd: busid 0x%x\n", busid); lun = busid & 7; -s->current_req = s->current_dev->info->alloc_req(s->current_dev, 0, lun); +s->current_req = scsi_req_new(s->current_dev, 0, lun); datalen = scsi_req_enqueue(s->current_req, buf); s->ti_size = datalen; if (datalen != 0) { diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c index 538cb49..6d56e09 100644 --- a/hw/lsi53c895a.c +++ b/hw/lsi53c895a.c @@ -788,8 +788,7 @@ static void lsi_do_command(LSIState *s) assert(s->current == NULL); s->current = qemu_mallocz(sizeof(lsi_request)); s->current->tag = s->select_tag; -s->current->req = dev->info->alloc_req(dev, s->current->tag, - s->current_lun); +s->current->req = scsi_req_new(dev, s->current->tag, s->current_lun); n = scsi_req_enqueue(s->current->req, buf); if (n > 0) { diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index afec0c8..4506ac9 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -146,6 +146,11 @@ SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t l return req; } +SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun) +{ +return d->info->alloc_req(d, tag, lun); +} + int32_t scsi_req_enqueue(SCSIRequest *req, uint8_t *buf) { int32_t rc; diff --git a/hw/scsi.h b/hw/scsi.h index 839bc0b..928cbf3 100644 --- a/hw/scsi.h +++ b/hw/scsi.h @@ -143,6 +143,7 @@ int scsi_build_sense(SCSISense sense, uint8_t *buf, int len, int fixed); int scsi_sense_valid(SCSISense sense); SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t lun); +SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun); int32_t scsi_req_enqueue(SCSIRequest *req, uint8_t *buf); void scsi_req_free(SCSIRequest *req); SCSIRequest *scsi_req_ref(SCSIRequest *req); diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c index 125a454..8032a17 100644 --- a/hw/spapr_vscsi.c +++ b/hw/spapr_vscsi.c @@ -653,7 +653,7 @@ static int vscsi_queue_cmd(VSCSIState *s, vscsi_req *req) req->sdev = sdev; req->lun = lun; -req->sreq = sdev->info->alloc_req(sdev, req->qtag, lun); +req->sreq = scsi_req_new(sdev, req->qtag, lun); n = scsi_req_enqueue(req->sreq, srp->cmd.cdb); dprintf("VSCSI: Queued command tag 0x%x CMD 0x%x ID %d LUN %d ret: %d\n", diff --git a/hw/usb-msd.c b/hw/usb-msd.c index ccfae61..efb15b0 100644 --- a/hw/usb-msd.c +++ b/hw/usb-msd.c @@ -377,7 +377,7 @@ static int usb_msd_handle_data(USBDevice *dev, USBPacket *p) s->tag, cbw.flags, cbw.cmd_len, s->data_len); s->residue = 0; s->scsi_len = 0; -s->req = s->scsi_dev->info->alloc_req(s->scsi_dev, s->tag, 0); +s->req = scsi_req_new(s->scsi_dev, s->tag, 0); scsi_req_enqueue(s->req, cbw.cmd); /* ??? Should check that USB and SCSI data transfer directions match. */ -- 1.7.4.4
[Qemu-devel] [PATCH v5 13/25] scsi: Update sense code handling
From: Hannes Reinecke The SCSI spec has a quite detailed list of sense codes available. It even mandates the use of specific ones for some failure cases. The current implementation just has one type of generic error which is actually a violation of the spec in certain cases. This patch introduces various predefined sense codes to have the sense code reporting more in line with the spec. On top of Hannes's patch I fixed the reply to REQUEST SENSE commands with DESC=0 and a small (<18) length. Signed-off-by: Hannes Reinecke Signed-off-by: Paolo Bonzini Reviewed-by: Christoph Hellwig --- hw/scsi-bus.c | 91 - hw/scsi-disk.c| 82 ++- hw/scsi-generic.c | 63 - hw/scsi.h | 39 ++- 4 files changed, 208 insertions(+), 67 deletions(-) diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index 20bffe2..732772a 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -154,7 +154,7 @@ void scsi_req_enqueue(SCSIRequest *req) QTAILQ_INSERT_TAIL(&req->dev->requests, req, next); } -void scsi_req_dequeue(SCSIRequest *req) +static void scsi_req_dequeue(SCSIRequest *req) { trace_scsi_req_dequeue(req->dev->id, req->lun, req->tag); if (req->enqueued) { @@ -391,6 +391,95 @@ int scsi_req_parse(SCSIRequest *req, uint8_t *buf) return 0; } +/* + * Predefined sense codes + */ + +/* No sense data available */ +const struct SCSISense sense_code_NO_SENSE = { +.key = NO_SENSE , .asc = 0x00 , .ascq = 0x00 +}; + +/* LUN not ready, Manual intervention required */ +const struct SCSISense sense_code_LUN_NOT_READY = { +.key = NOT_READY, .asc = 0x04, .ascq = 0x03 +}; + +/* LUN not ready, Medium not present */ +const struct SCSISense sense_code_NO_MEDIUM = { +.key = NOT_READY, .asc = 0x3a, .ascq = 0x00 +}; + +/* Hardware error, internal target failure */ +const struct SCSISense sense_code_TARGET_FAILURE = { +.key = HARDWARE_ERROR, .asc = 0x44, .ascq = 0x00 +}; + +/* Illegal request, invalid command operation code */ +const struct SCSISense sense_code_INVALID_OPCODE = { +.key = ILLEGAL_REQUEST, .asc = 0x20, .ascq = 0x00 +}; + +/* Illegal request, LBA out of range */ +const struct SCSISense sense_code_LBA_OUT_OF_RANGE = { +.key = ILLEGAL_REQUEST, .asc = 0x21, .ascq = 0x00 +}; + +/* Illegal request, Invalid field in CDB */ +const struct SCSISense sense_code_INVALID_FIELD = { +.key = ILLEGAL_REQUEST, .asc = 0x24, .ascq = 0x00 +}; + +/* Illegal request, LUN not supported */ +const struct SCSISense sense_code_LUN_NOT_SUPPORTED = { +.key = ILLEGAL_REQUEST, .asc = 0x25, .ascq = 0x00 +}; + +/* Command aborted, I/O process terminated */ +const struct SCSISense sense_code_IO_ERROR = { +.key = ABORTED_COMMAND, .asc = 0x00, .ascq = 0x06 +}; + +/* Command aborted, I_T Nexus loss occurred */ +const struct SCSISense sense_code_I_T_NEXUS_LOSS = { +.key = ABORTED_COMMAND, .asc = 0x29, .ascq = 0x07 +}; + +/* Command aborted, Logical Unit failure */ +const struct SCSISense sense_code_LUN_FAILURE = { +.key = ABORTED_COMMAND, .asc = 0x3e, .ascq = 0x01 +}; + +/* + * scsi_build_sense + * + * Build a sense buffer + */ +int scsi_build_sense(SCSISense sense, uint8_t *buf, int len, int fixed) +{ +if (!fixed && len < 8) { +return 0; +} + +memset(buf, 0, len); +if (fixed) { +/* Return fixed format sense buffer */ +buf[0] = 0xf0; +buf[2] = sense.key; +buf[7] = 7; +buf[12] = sense.asc; +buf[13] = sense.ascq; +return MIN(len, 18); +} else { +/* Return descriptor format sense buffer */ +buf[0] = 0x72; +buf[1] = sense.key; +buf[2] = sense.asc; +buf[3] = sense.ascq; +return 8; +} +} + static const char *scsi_command_name(uint8_t cmd) { static const char *names[] = { diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 08633db..63aa8f1 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -49,10 +49,6 @@ do { fprintf(stderr, "scsi-disk: " fmt , ## __VA_ARGS__); } while (0) typedef struct SCSIDiskState SCSIDiskState; -typedef struct SCSISense { -uint8_t key; -} SCSISense; - typedef struct SCSIDiskReq { SCSIRequest req; /* ??? We should probably keep track of whether the data transfer is @@ -111,24 +107,19 @@ static void scsi_disk_clear_sense(SCSIDiskState *s) memset(&s->sense, 0, sizeof(s->sense)); } -static void scsi_disk_set_sense(SCSIDiskState *s, uint8_t key) -{ -s->sense.key = key; -} - -static void scsi_req_set_status(SCSIDiskReq *r, int status, int sense_code) +static void scsi_req_set_status(SCSIDiskReq *r, int status, SCSISense sense) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); r->req.status = status; -scsi_disk_set_sense(s, sense_code); +s->sense = sense; } /* Helper function for command completion. */ -static void scsi_co
[Qemu-devel] [PATCH v5 10/25] scsi: introduce scsi_req_abort
This covers the case of canceling a request's I/O and still completing it. Signed-off-by: Paolo Bonzini Reviewed-by: Christoph Hellwig --- hw/scsi-bus.c|9 + hw/scsi.h|1 + hw/spapr_vscsi.c |8 ++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index cb3ba5f..ef8ba3b 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -549,6 +549,15 @@ void scsi_req_complete(SCSIRequest *req) scsi_req_unref(req); } +void scsi_req_abort(SCSIRequest *req, int status) +{ +req->status = status; +if (req->dev && req->dev->info->cancel_io) { +req->dev->info->cancel_io(req); +} +scsi_req_complete(req); +} + void scsi_device_purge_requests(SCSIDevice *sdev) { SCSIRequest *req; diff --git a/hw/scsi.h b/hw/scsi.h index f1d..970e812 100644 --- a/hw/scsi.h +++ b/hw/scsi.h @@ -114,6 +114,7 @@ int scsi_req_parse(SCSIRequest *req, uint8_t *buf); void scsi_req_print(SCSIRequest *req); void scsi_req_data(SCSIRequest *req, int len); void scsi_req_complete(SCSIRequest *req); +void scsi_req_abort(SCSIRequest *req, int status); void scsi_device_purge_requests(SCSIDevice *sdev); #endif diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c index e1fcba8..3553ac6 100644 --- a/hw/spapr_vscsi.c +++ b/hw/spapr_vscsi.c @@ -463,10 +463,8 @@ static void vscsi_send_request_sense(VSCSIState *s, vscsi_req *req) dprintf("VSCSI: Queued request sense tag 0x%x\n", req->qtag); if (n < 0) { fprintf(stderr, "VSCSI: REQUEST_SENSE wants write data !?!?!?\n"); -sdev->info->cancel_io(req->sreq); vscsi_makeup_sense(s, req, HARDWARE_ERROR, 0, 0); -vscsi_send_rsp(s, req, CHECK_CONDITION, 0, 0); -vscsi_put_req(s, req); +scsi_req_abort(req->sreq, CHECK_CONDITION); return; } else if (n == 0) { return; @@ -547,10 +545,8 @@ static void vscsi_command_complete(SCSIRequest *sreq, int reason, uint32_t arg) } if (rc < 0) { fprintf(stderr, "VSCSI: RDMA error rc=%d!\n", rc); -sdev->info->cancel_io(sreq); vscsi_makeup_sense(s, req, HARDWARE_ERROR, 0, 0); -vscsi_send_rsp(s, req, CHECK_CONDITION, 0, 0); -vscsi_put_req(s, req); +scsi_req_abort(req->sreq, CHECK_CONDITION); return; } -- 1.7.4.4
[Qemu-devel] [PATCH v5 04/25] scsi: introduce SCSIBusOps
There are more operations than a SCSI bus can handle, besides completing commands. One example, which this series will introduce, is cleaning up after a request is cancelled. More long term, a "SCSI bus" can represent the LUNs attached to a target; in this case, while all commands will ultimately reach a logical unit, it is the target who is in charge of answering REPORT LUNs. Signed-off-by: Paolo Bonzini Cc: Christoph Hellwig --- hw/esp.c |6 +- hw/lsi53c895a.c |6 +- hw/scsi-bus.c | 12 ++-- hw/scsi-generic.c |2 +- hw/scsi.h | 13 +++-- hw/spapr_vscsi.c |6 +- hw/usb-msd.c |6 +- 7 files changed, 34 insertions(+), 17 deletions(-) diff --git a/hw/esp.c b/hw/esp.c index fa9d2a2..ae18401 100644 --- a/hw/esp.c +++ b/hw/esp.c @@ -714,6 +714,10 @@ void esp_init(target_phys_addr_t espaddr, int it_shift, *dma_enable = qdev_get_gpio_in(dev, 1); } +static const struct SCSIBusOps esp_scsi_ops = { +.complete = esp_command_complete +}; + static int esp_init1(SysBusDevice *dev) { ESPState *s = FROM_SYSBUS(ESPState, dev); @@ -728,7 +732,7 @@ static int esp_init1(SysBusDevice *dev) qdev_init_gpio_in(&dev->qdev, esp_gpio_demux, 2); -scsi_bus_new(&s->bus, &dev->qdev, 0, ESP_MAX_DEVS, esp_command_complete); +scsi_bus_new(&s->bus, &dev->qdev, 0, ESP_MAX_DEVS, &esp_scsi_ops); return scsi_bus_legacy_handle_cmdline(&s->bus); } diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c index 2ce38a9..704e8ad 100644 --- a/hw/lsi53c895a.c +++ b/hw/lsi53c895a.c @@ -2205,6 +2205,10 @@ static int lsi_scsi_uninit(PCIDevice *d) return 0; } +static const struct SCSIBusOps lsi_scsi_ops = { +.complete = lsi_command_complete +}; + static int lsi_scsi_init(PCIDevice *dev) { LSIState *s = DO_UPCAST(LSIState, dev, dev); @@ -2241,7 +2245,7 @@ static int lsi_scsi_init(PCIDevice *dev) PCI_BASE_ADDRESS_SPACE_MEMORY, lsi_ram_mapfunc); QTAILQ_INIT(&s->queue); -scsi_bus_new(&s->bus, &dev->qdev, 1, LSI_MAX_DEVS, lsi_command_complete); +scsi_bus_new(&s->bus, &dev->qdev, 1, LSI_MAX_DEVS, &lsi_scsi_ops); if (!dev->qdev.hotplugged) { return scsi_bus_legacy_handle_cmdline(&s->bus); } diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index 191cbab..1850a87 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -21,13 +21,13 @@ static int next_scsi_bus; /* Create a scsi bus, and attach devices to it. */ void scsi_bus_new(SCSIBus *bus, DeviceState *host, int tcq, int ndev, - scsi_completionfn complete) + const SCSIBusOps *ops) { qbus_create_inplace(&bus->qbus, &scsi_bus_info, host, NULL); bus->busnr = next_scsi_bus++; bus->tcq = tcq; bus->ndev = ndev; -bus->complete = complete; +bus->ops = ops; bus->qbus.allow_hotplug = 1; } @@ -503,7 +503,7 @@ static const char *scsi_command_name(uint8_t cmd) void scsi_req_data(SCSIRequest *req, int len) { trace_scsi_req_data(req->dev->id, req->lun, req->tag, len); -req->bus->complete(req->bus, SCSI_REASON_DATA, req->tag, len); +req->bus->ops->complete(req->bus, SCSI_REASON_DATA, req->tag, len); } void scsi_req_print(SCSIRequest *req) @@ -538,9 +538,9 @@ void scsi_req_complete(SCSIRequest *req) { assert(req->status != -1); scsi_req_dequeue(req); -req->bus->complete(req->bus, SCSI_REASON_DONE, - req->tag, - req->status); +req->bus->ops->complete(req->bus, SCSI_REASON_DONE, +req->tag, +req->status); } static char *scsibus_get_fw_dev_path(DeviceState *dev) diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c index e4f1f30..f09458b 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -335,7 +335,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, s->senselen = 7; s->driver_status = SG_ERR_DRIVER_SENSE; bus = scsi_bus_from_device(d); -bus->complete(bus, SCSI_REASON_DONE, tag, CHECK_CONDITION); +bus->ops->complete(bus, SCSI_REASON_DONE, tag, CHECK_CONDITION); return 0; } diff --git a/hw/scsi.h b/hw/scsi.h index 7c09f32..d4ecc9b 100644 --- a/hw/scsi.h +++ b/hw/scsi.h @@ -16,10 +16,9 @@ enum scsi_reason { }; typedef struct SCSIBus SCSIBus; +typedef struct SCSIBusOps SCSIBusOps; typedef struct SCSIDevice SCSIDevice; typedef struct SCSIDeviceInfo SCSIDeviceInfo; -typedef void (*scsi_completionfn)(SCSIBus *bus, int reason, uint32_t tag, - uint32_t arg); enum SCSIXferMode { SCSI_XFER_NONE, /* TEST_UNIT_READY, ...*/ @@ -74,20 +73,22 @@ struct SCSIDeviceInfo { uint8_t *(*get_buf)(SCSIDevice *s, uint32_t tag); }; -typedef void (*SCSIAttachFn)(DeviceState *host, BlockDriverState *bdrv, - int unit); +struct SCSIBusOps { +void (*complete)(SCSIBus *bus, int reason, uint32_
[Qemu-devel] [PATCH v5 11/25] scsi: introduce scsi_req_cancel
This is for when the request must be dropped in the void, but still memory should be freed. To this end, the devices register a second callback in SCSIBusOps. Signed-off-by: Paolo Bonzini Reviewed-by: Christoph Hellwig --- hw/esp.c | 16 ++-- hw/lsi53c895a.c | 30 +- hw/scsi-bus.c | 17 ++--- hw/scsi-disk.c|1 - hw/scsi-generic.c |1 - hw/scsi.h |2 ++ hw/spapr_vscsi.c | 11 ++- hw/usb-msd.c | 19 +++ 8 files changed, 80 insertions(+), 17 deletions(-) diff --git a/hw/esp.c b/hw/esp.c index 7763c72..ba3fa94 100644 --- a/hw/esp.c +++ b/hw/esp.c @@ -188,6 +188,17 @@ static void esp_dma_enable(void *opaque, int irq, int level) } } +static void esp_request_cancelled(SCSIRequest *req) +{ +ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent); + +if (req == s->current_req) { +scsi_req_unref(s->current_req); +s->current_req = NULL; +s->current_dev = NULL; +} +} + static uint32_t get_cmd(ESPState *s, uint8_t *buf) { uint32_t dmalen; @@ -210,7 +221,7 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf) if (s->current_dev) { /* Started a new command before the old one finished. Cancel it. */ -s->current_dev->info->cancel_io(s->current_req); +scsi_req_cancel(s->current_req); s->async_len = 0; } @@ -720,7 +731,8 @@ void esp_init(target_phys_addr_t espaddr, int it_shift, } static const struct SCSIBusOps esp_scsi_ops = { -.complete = esp_command_complete +.complete = esp_command_complete, +.cancel = esp_request_cancelled }; static int esp_init1(SysBusDevice *dev) diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c index 1e08389..f3a1488 100644 --- a/hw/lsi53c895a.c +++ b/hw/lsi53c895a.c @@ -664,6 +664,26 @@ static lsi_request *lsi_find_by_tag(LSIState *s, uint32_t tag) return NULL; } +static void lsi_request_cancelled(SCSIRequest *req) +{ +LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent); +lsi_request *p; + +if (s->current && req == s->current->req) { +scsi_req_unref(req); +qemu_free(s->current); +s->current = NULL; +return; +} + +p = lsi_find_by_tag(s, req->tag); +if (p) { +QTAILQ_REMOVE(&s->queue, p, next); +scsi_req_unref(req); +qemu_free(p); +} +} + /* Record that data is available for a queued command. Returns zero if the device was reselected, nonzero if the IO is deferred. */ static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t arg) @@ -931,7 +951,7 @@ static void lsi_do_msgout(LSIState *s) /* The ABORT TAG message clears the current I/O process only. */ DPRINTF("MSG: ABORT TAG tag=0x%x\n", current_tag); if (current_req) { -current_dev->info->cancel_io(current_req->req); +scsi_req_cancel(current_req->req); } lsi_disconnect(s); break; @@ -956,7 +976,7 @@ static void lsi_do_msgout(LSIState *s) /* clear the current I/O process */ if (s->current) { -current_dev->info->cancel_io(s->current->req); +scsi_req_cancel(s->current->req); } /* As the current implemented devices scsi_disk and scsi_generic @@ -969,8 +989,7 @@ static void lsi_do_msgout(LSIState *s) id = current_tag & 0xff00; QTAILQ_FOREACH_SAFE(p, &s->queue, next, p_next) { if ((p->tag & 0xff00) == id) { -current_dev->info->cancel_io(p->req); -QTAILQ_REMOVE(&s->queue, p, next); +scsi_req_cancel(p->req); } } @@ -2227,7 +2246,8 @@ static int lsi_scsi_uninit(PCIDevice *d) } static const struct SCSIBusOps lsi_scsi_ops = { -.complete = lsi_command_complete +.complete = lsi_command_complete, +.cancel = lsi_request_cancelled }; static int lsi_scsi_init(PCIDevice *dev) diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index ef8ba3b..20bffe2 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -549,6 +549,19 @@ void scsi_req_complete(SCSIRequest *req) scsi_req_unref(req); } +void scsi_req_cancel(SCSIRequest *req) +{ +if (req->dev && req->dev->info->cancel_io) { +req->dev->info->cancel_io(req); +} +scsi_req_ref(req); +scsi_req_dequeue(req); +if (req->bus->ops->cancel) { +req->bus->ops->cancel(req); +} +scsi_req_unref(req); +} + void scsi_req_abort(SCSIRequest *req, int status) { req->status = status; @@ -564,9 +577,7 @@ void scsi_device_purge_requests(SCSIDevice *sdev) while (!QTAILQ_EMPTY(&sdev->requests)) { req = QTAILQ_FIRST(&sdev->requests); -sdev->info->cancel_io(req); -scsi_req_dequeue(req); -scsi_req_unref(req); +scsi_req_canc
[Qemu-devel] [PATCH v5 07/25] lsi: extract lsi_find_by_tag
Signed-off-by: Paolo Bonzini Reviewed-by: Christoph Hellwig --- hw/lsi53c895a.c | 63 +- 1 files changed, 38 insertions(+), 25 deletions(-) diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c index 704e8ad..1ebcde7 100644 --- a/hw/lsi53c895a.c +++ b/hw/lsi53c895a.c @@ -652,38 +652,51 @@ static void lsi_reselect(LSIState *s, lsi_request *p) } } -/* Record that data is available for a queued command. Returns zero if - the device was reselected, nonzero if the IO is deferred. */ -static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t arg) +static lsi_request *lsi_find_by_tag(LSIState *s, uint32_t tag) { lsi_request *p; QTAILQ_FOREACH(p, &s->queue, next) { if (p->tag == tag) { -if (p->pending) { -BADF("Multiple IO pending for tag %d\n", tag); -} -p->pending = arg; -/* Reselect if waiting for it, or if reselection triggers an IRQ - and the bus is free. - Since no interrupt stacking is implemented in the emulation, it - is also required that there are no pending interrupts waiting - for service from the device driver. */ -if (s->waiting == 1 || -(lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON) && - !(s->istat0 & (LSI_ISTAT0_SIP | LSI_ISTAT0_DIP { -/* Reselect device. */ -lsi_reselect(s, p); -return 0; -} else { -DPRINTF("Queueing IO tag=0x%x\n", tag); -p->pending = arg; -return 1; -} +return p; } } -BADF("IO with unknown tag %d\n", tag); -return 1; + +return NULL; +} + +/* Record that data is available for a queued command. Returns zero if + the device was reselected, nonzero if the IO is deferred. */ +static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t arg) +{ +lsi_request *p; + +p = lsi_find_by_tag(s, tag); +if (!p) { +BADF("IO with unknown tag %d\n", tag); +return 1; +} + +if (p->pending) { +BADF("Multiple IO pending for tag %d\n", tag); +} +p->pending = arg; +/* Reselect if waiting for it, or if reselection triggers an IRQ + and the bus is free. + Since no interrupt stacking is implemented in the emulation, it + is also required that there are no pending interrupts waiting + for service from the device driver. */ +if (s->waiting == 1 || +(lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON) && + !(s->istat0 & (LSI_ISTAT0_SIP | LSI_ISTAT0_DIP { +/* Reselect device. */ +lsi_reselect(s, p); +return 0; +} else { +DPRINTF("Queueing IO tag=0x%x\n", tag); +p->pending = arg; +return 1; +} } /* Callback to indicate that the SCSI layer has completed a transfer. */ -- 1.7.4.4
[Qemu-devel] [PATCH v5 06/25] scsi: reference-count requests
With the next patch, a device may hold SCSIRequest for an indefinite time. Split a rather big patch, and protect against access errors, by reference counting them. There is some ugliness in scsi_send_command implementation due to the need to unref the request when it fails. This will go away with the next patches, which move the unref'ing to the devices. Signed-off-by: Paolo Bonzini Cc: Christoph Hellwig --- hw/scsi-bus.c | 29 ++--- hw/scsi-disk.c| 23 +++ hw/scsi-generic.c | 24 hw/scsi.h |5 + 4 files changed, 58 insertions(+), 23 deletions(-) diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index 1850a87..20d6c51 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -136,6 +136,8 @@ SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t l SCSIRequest *req; req = qemu_mallocz(size); +/* Two references: one is passed back to the HBA, one is in d->requests. */ +req->refcount = 2; req->bus = scsi_bus_from_device(d); req->dev = d; req->tag = tag; @@ -159,21 +161,16 @@ SCSIRequest *scsi_req_find(SCSIDevice *d, uint32_t tag) return NULL; } -static void scsi_req_dequeue(SCSIRequest *req) +void scsi_req_dequeue(SCSIRequest *req) { trace_scsi_req_dequeue(req->dev->id, req->lun, req->tag); if (req->enqueued) { QTAILQ_REMOVE(&req->dev->requests, req, next); req->enqueued = false; +scsi_req_unref(req); } } -void scsi_req_free(SCSIRequest *req) -{ -scsi_req_dequeue(req); -qemu_free(req); -} - static int scsi_req_length(SCSIRequest *req, uint8_t *cmd) { switch (cmd[0] >> 5) { @@ -495,6 +492,22 @@ static const char *scsi_command_name(uint8_t cmd) return names[cmd]; } +SCSIRequest *scsi_req_ref(SCSIRequest *req) +{ +req->refcount++; +return req; +} + +void scsi_req_unref(SCSIRequest *req) +{ +if (--req->refcount == 0) { +if (req->dev->info->free_req) { +req->dev->info->free_req(req); +} +qemu_free(req); +} +} + /* Called by the devices when data is ready for the HBA. The HBA should start a DMA operation to read or fill the device's data buffer. Once it completes, calling one of req->dev->info->read_data or @@ -537,10 +550,12 @@ void scsi_req_print(SCSIRequest *req) void scsi_req_complete(SCSIRequest *req) { assert(req->status != -1); +scsi_req_ref(req); scsi_req_dequeue(req); req->bus->ops->complete(req->bus, SCSI_REASON_DONE, req->tag, req->status); +scsi_req_unref(req); } static char *scsibus_get_fw_dev_path(DeviceState *dev) diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 741cf39..87d7b93 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -98,10 +98,11 @@ static SCSIDiskReq *scsi_new_request(SCSIDiskState *s, uint32_t tag, return r; } -static void scsi_remove_request(SCSIDiskReq *r) +static void scsi_free_request(SCSIRequest *req) { +SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req); + qemu_vfree(r->iov.iov_base); -scsi_req_free(&r->req); } static SCSIDiskReq *scsi_find_request(SCSIDiskState *s, uint32_t tag) @@ -134,7 +135,6 @@ static void scsi_command_complete(SCSIDiskReq *r, int status, int sense) r->req.tag, status, sense); scsi_req_set_status(r, status, sense); scsi_req_complete(&r->req); -scsi_remove_request(r); } /* Cancel a pending data transfer. */ @@ -148,7 +148,7 @@ static void scsi_cancel_io(SCSIDevice *d, uint32_t tag) if (r->req.aiocb) bdrv_aio_cancel(r->req.aiocb); r->req.aiocb = NULL; -scsi_remove_request(r); +scsi_req_dequeue(&r->req); } } @@ -1033,7 +1033,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, uint8_t *buf, int lun) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d); -uint32_t len; +int32_t len; int is_write; uint8_t command; uint8_t *outbuf; @@ -1095,6 +1095,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, case REZERO_UNIT: rc = scsi_disk_emulate_command(r, outbuf); if (rc < 0) { +scsi_req_unref(&r->req); return 0; } @@ -1181,9 +1182,11 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]); fail: scsi_command_complete(r, CHECK_CONDITION, ILLEGAL_REQUEST); +scsi_req_unref(&r->req); return 0; illegal_lba: scsi_command_complete(r, CHECK_CONDITION, HARDWARE_ERROR); +scsi_req_unref(&r->req); return 0; } if (r->sector_count == 0 && r->iov.iov_len == 0) { @@ -1191,12 +1194,13 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, } len = r->sector_count * 512 + r->iov.iov_len;
[Qemu-devel] [PATCH v5 01/25] scsi: add tracing of scsi requests
Signed-off-by: Paolo Bonzini Reviewed-by: Christoph Hellwig --- hw/scsi-bus.c |6 ++ trace-events |6 ++ 2 files changed, 12 insertions(+), 0 deletions(-) diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index ceeb4ec..0fd85fc 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -4,6 +4,7 @@ #include "scsi-defs.h" #include "qdev.h" #include "blockdev.h" +#include "trace.h" static char *scsibus_get_fw_dev_path(DeviceState *dev); @@ -141,6 +142,7 @@ SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t l req->lun = lun; req->status = -1; req->enqueued = true; +trace_scsi_req_alloc(req->dev->id, req->lun, req->tag); QTAILQ_INSERT_TAIL(&d->requests, req, next); return req; } @@ -159,6 +161,7 @@ SCSIRequest *scsi_req_find(SCSIDevice *d, uint32_t tag) static void scsi_req_dequeue(SCSIRequest *req) { +trace_scsi_req_dequeue(req->dev->id, req->lun, req->tag); if (req->enqueued) { QTAILQ_REMOVE(&req->dev->requests, req, next); req->enqueued = false; @@ -195,6 +198,7 @@ static int scsi_req_length(SCSIRequest *req, uint8_t *cmd) req->cmd.len = 12; break; default: +trace_scsi_req_parse_bad(req->dev->id, req->lun, req->tag, cmd[0]); return -1; } @@ -392,6 +396,8 @@ int scsi_req_parse(SCSIRequest *req, uint8_t *buf) memcpy(req->cmd.buf, buf, req->cmd.len); scsi_req_xfer_mode(req); req->cmd.lba = scsi_req_lba(req); +trace_scsi_req_parsed(req->dev->id, req->lun, req->tag, buf[0], + req->cmd.mode, req->cmd.xfer, req->cmd.lba); return 0; } diff --git a/trace-events b/trace-events index 385cb00..b11b71d 100644 --- a/trace-events +++ b/trace-events @@ -205,6 +205,12 @@ disable usb_set_config(int addr, int config, int ret) "dev %d, config %d, ret %d disable usb_clear_device_feature(int addr, int feature, int ret) "dev %d, feature %d, ret %d" disable usb_set_device_feature(int addr, int feature, int ret) "dev %d, feature %d, ret %d" +# hw/scsi-bus.c +disable scsi_req_alloc(int target, int lun, int tag) "target %d lun %d tag %d" +disable scsi_req_dequeue(int target, int lun, int tag) "target %d lun %d tag %d" +disable scsi_req_parsed(int target, int lun, int tag, int cmd, int mode, int xfer, uint64_t lba) "target %d lun %d tag %d command %d dir %d length %d lba %"PRIu64"" +disable scsi_req_parse_bad(int target, int lun, int tag, int cmd) "target %d lun %d tag %d command %d" + # vl.c disable vm_state_notify(int running, int reason) "running %d reason %d" -- 1.7.4.4
[Qemu-devel] [PATCH v5 09/25] scsi: commonize purging requests
The code for canceling requests upon reset is already the same. Clean it up and move it to scsi-bus.c. Signed-off-by: Paolo Bonzini Reviewed-by: Christoph Hellwig --- hw/scsi-bus.c | 12 hw/scsi-disk.c| 18 ++ hw/scsi-generic.c | 18 ++ hw/scsi.h |1 + 4 files changed, 17 insertions(+), 32 deletions(-) diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index 46f60e1..cb3ba5f 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -549,6 +549,18 @@ void scsi_req_complete(SCSIRequest *req) scsi_req_unref(req); } +void scsi_device_purge_requests(SCSIDevice *sdev) +{ +SCSIRequest *req; + +while (!QTAILQ_EMPTY(&sdev->requests)) { +req = QTAILQ_FIRST(&sdev->requests); +sdev->info->cancel_io(req); +scsi_req_dequeue(req); +scsi_req_unref(req); +} +} + static char *scsibus_get_fw_dev_path(DeviceState *dev) { SCSIDevice *d = (SCSIDevice*)dev; diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index f7c09c9..38fbb05 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -1147,26 +1147,12 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf) return len; } -static void scsi_disk_purge_requests(SCSIDiskState *s) -{ -SCSIDiskReq *r; - -while (!QTAILQ_EMPTY(&s->qdev.requests)) { -r = DO_UPCAST(SCSIDiskReq, req, QTAILQ_FIRST(&s->qdev.requests)); -if (r->req.aiocb) { -bdrv_aio_cancel(r->req.aiocb); -} -scsi_req_dequeue(&r->req); -scsi_req_unref(&r->req); -} -} - static void scsi_disk_reset(DeviceState *dev) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev.qdev, dev); uint64_t nb_sectors; -scsi_disk_purge_requests(s); +scsi_device_purge_requests(&s->qdev); bdrv_get_geometry(s->bs, &nb_sectors); nb_sectors /= s->cluster_size; @@ -1180,7 +1166,7 @@ static void scsi_destroy(SCSIDevice *dev) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); -scsi_disk_purge_requests(s); +scsi_device_purge_requests(&s->qdev); blockdev_mark_auto_del(s->qdev.conf.bs); } diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c index 3740432..72c4cc7 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -424,32 +424,18 @@ static int get_stream_blocksize(BlockDriverState *bdrv) return (buf[9] << 16) | (buf[10] << 8) | buf[11]; } -static void scsi_generic_purge_requests(SCSIGenericState *s) -{ -SCSIGenericReq *r; - -while (!QTAILQ_EMPTY(&s->qdev.requests)) { -r = DO_UPCAST(SCSIGenericReq, req, QTAILQ_FIRST(&s->qdev.requests)); -if (r->req.aiocb) { -bdrv_aio_cancel(r->req.aiocb); -} -scsi_req_dequeue(&r->req); -scsi_req_unref(&r->req); -} -} - static void scsi_generic_reset(DeviceState *dev) { SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev.qdev, dev); -scsi_generic_purge_requests(s); +scsi_device_purge_requests(&s->qdev); } static void scsi_destroy(SCSIDevice *d) { SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d); -scsi_generic_purge_requests(s); +scsi_device_purge_requests(&s->qdev); blockdev_mark_auto_del(s->qdev.conf.bs); } diff --git a/hw/scsi.h b/hw/scsi.h index 19bd1ae..f1d 100644 --- a/hw/scsi.h +++ b/hw/scsi.h @@ -114,5 +114,6 @@ int scsi_req_parse(SCSIRequest *req, uint8_t *buf); void scsi_req_print(SCSIRequest *req); void scsi_req_data(SCSIRequest *req, int len); void scsi_req_complete(SCSIRequest *req); +void scsi_device_purge_requests(SCSIDevice *sdev); #endif -- 1.7.4.4
[Qemu-devel] [PATCH v5 02/25] scsi-generic: Remove bogus double complete
scsi-generic scsi_read_complete() should not -both- call the client complete callback with SCSI_REASON_DATA -and- call scsi_command_complete(). The former will cause the client to queue a new read or write request, while the later will free the request data structure, thus causing the new read or write request to use a freed/stale structure when it completes. This patch fixes the bug, fixing a crash with scsi-generic & RHEL5.5 installer. Cc: Benjamin Herrenschmidt Cc: David Gibson Signed-off-by: Paolo Bonzini Reviewed-by: Christoph Hellwig --- hw/scsi-generic.c |6 -- 1 files changed, 4 insertions(+), 2 deletions(-) diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c index 9be1cca..102f1da 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -172,9 +172,11 @@ static void scsi_read_complete(void * opaque, int ret) DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, len); r->len = -1; -r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, len); -if (len == 0) +if (len == 0) { scsi_command_complete(r, 0); +} else { +r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, len); +} } /* Read more data from scsi device into buffer. */ -- 1.7.4.4
[Qemu-devel] [PATCH v5 03/25] scsi: introduce scsi_req_data
This abstracts calling the command_complete callback, reducing churn in the following patches. Signed-off-by: Paolo Bonzini Reviewed-by: Christoph Hellwig --- hw/scsi-bus.c | 11 +++ hw/scsi-disk.c|8 hw/scsi-generic.c |6 +++--- hw/scsi.h |1 + trace-events |1 + 5 files changed, 20 insertions(+), 7 deletions(-) diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index 0fd85fc..191cbab 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -495,6 +495,17 @@ static const char *scsi_command_name(uint8_t cmd) return names[cmd]; } +/* Called by the devices when data is ready for the HBA. The HBA should + start a DMA operation to read or fill the device's data buffer. + Once it completes, calling one of req->dev->info->read_data or + req->dev->info->write_data (depending on the direction of the + transfer) 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->complete(req->bus, SCSI_REASON_DATA, req->tag, len); +} + void scsi_req_print(SCSIRequest *req) { FILE *fp = stderr; diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 397b9d6..741cf39 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -170,7 +170,7 @@ static void scsi_read_complete(void * opaque, int ret) n = r->iov.iov_len / 512; r->sector += n; r->sector_count -= n; -r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, r->iov.iov_len); +scsi_req_data(&r->req, r->iov.iov_len); } @@ -182,7 +182,7 @@ static void scsi_read_request(SCSIDiskReq *r) if (r->sector_count == (uint32_t)-1) { DPRINTF("Read buf_len=%zd\n", r->iov.iov_len); r->sector_count = 0; -r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, r->iov.iov_len); +scsi_req_data(&r->req, r->iov.iov_len); return; } DPRINTF("Read sector_count=%d\n", r->sector_count); @@ -245,7 +245,7 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type) vm_stop(VMSTOP_DISKFULL); } else { if (type == SCSI_REQ_STATUS_RETRY_READ) { -r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, 0); +scsi_req_data(&r->req, 0); } scsi_command_complete(r, CHECK_CONDITION, HARDWARE_ERROR); @@ -281,7 +281,7 @@ static void scsi_write_complete(void * opaque, int ret) } r->iov.iov_len = len; DPRINTF("Write complete tag=0x%x more=%d\n", r->req.tag, len); -r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, len); +scsi_req_data(&r->req, len); } } diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c index 102f1da..e4f1f30 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -175,7 +175,7 @@ static void scsi_read_complete(void * opaque, int ret) if (len == 0) { scsi_command_complete(r, 0); } else { -r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, len); +scsi_req_data(&r->req, len); } } @@ -212,7 +212,7 @@ static void scsi_read_data(SCSIDevice *d, uint32_t tag) DPRINTF("Sense: %d %d %d %d %d %d %d %d\n", r->buf[0], r->buf[1], r->buf[2], r->buf[3], r->buf[4], r->buf[5], r->buf[6], r->buf[7]); -r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, s->senselen); +scsi_req_data(&r->req, s->senselen); return; } @@ -263,7 +263,7 @@ static int scsi_write_data(SCSIDevice *d, uint32_t tag) if (r->len == 0) { r->len = r->buflen; -r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, r->len); +scsi_req_data(&r->req, r->len); return 0; } diff --git a/hw/scsi.h b/hw/scsi.h index d3b5d56..7c09f32 100644 --- a/hw/scsi.h +++ b/hw/scsi.h @@ -105,6 +105,7 @@ void scsi_req_free(SCSIRequest *req); int scsi_req_parse(SCSIRequest *req, uint8_t *buf); void scsi_req_print(SCSIRequest *req); +void scsi_req_data(SCSIRequest *req, int len); void scsi_req_complete(SCSIRequest *req); #endif diff --git a/trace-events b/trace-events index b11b71d..0340eb2 100644 --- a/trace-events +++ b/trace-events @@ -207,6 +207,7 @@ disable usb_set_device_feature(int addr, int feature, int ret) "dev %d, feature # hw/scsi-bus.c disable scsi_req_alloc(int target, int lun, int tag) "target %d lun %d tag %d" +disable scsi_req_data(int target, int lun, int tag, int len) "target %d lun %d tag %d len %d" disable scsi_req_dequeue(int target, int lun, int tag) "target %d lun %d tag %d" disable scsi_req_parsed(int target, int lun, int tag, int cmd, int mode, int xfer, uint64_t lba) "target %d lun %d tag %d command %d dir %d length %d lba %"PRIu64"" disable scsi_req_parse_bad(int target, int lun, int tag, int cmd) "target %d lun %d tag %d command %d" -- 1.7.4.4