[Qemu-devel] [PATCH] x86: Clean up CPU reset
From: Jan Kiszka Signed-off-by: Jan Kiszka --- hw/pc.c | 22 -- 1 files changed, 4 insertions(+), 18 deletions(-) diff --git a/hw/pc.c b/hw/pc.c index 1848151..8b9e70a 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -812,20 +812,12 @@ void pc_acpi_smi_interrupt(void *opaque, int irq, int level) } } -static void bsp_cpu_reset(void *opaque) +static void pc_cpu_reset(void *opaque) { CPUState *env = opaque; cpu_reset(env); -env->halted = 0; -} - -static void ap_cpu_reset(void *opaque) -{ -CPUState *env = opaque; - -cpu_reset(env); -env->halted = 1; +env->halted = !cpu_is_bsp(env); } static CPUState *pc_new_cpu(const char *cpu_model) @@ -839,16 +831,10 @@ static CPUState *pc_new_cpu(const char *cpu_model) } if ((env->cpuid_features & CPUID_APIC) || smp_cpus > 1) { env->cpuid_apic_id = env->cpu_index; -/* APIC reset callback resets cpu */ env->apic_state = apic_init(env, env->cpuid_apic_id); } -if (cpu_is_bsp(env)) { -qemu_register_reset(bsp_cpu_reset, env); -env->halted = 0; -} else { -qemu_register_reset(ap_cpu_reset, env); -env->halted = 1; -} +qemu_register_reset(pc_cpu_reset, env); +pc_cpu_reset(env); return env; } -- 1.6.0.2
[Qemu-devel] [PATCH] x86: Fix INIT processing
From: Jan Kiszka This fixes a regression of 0e26b7b892: Reset halted also on INIT. Signed-off-by: Jan Kiszka --- target-i386/helper.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/target-i386/helper.c b/target-i386/helper.c index 718394c..e134340 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -1151,6 +1151,7 @@ void do_cpu_init(CPUState *env) cpu_reset(env); env->interrupt_request = sipi; apic_init_reset(env->apic_state); +env->halted = !cpu_is_bsp(env); } void do_cpu_sipi(CPUState *env) -- 1.6.0.2
Re: [Qemu-devel] [PATCH] virtio-pci: fix bus master bug setting on load
On 06/17/2010 10:15 AM, Alex Williamson wrote: The comment suggests we're checking for the driver in the ready state and bus master disabled, but the code is checking that it's not in the ready state. Signed-off-by: Alex Williamson Found-by: Amit Shah Applied. Thanks. Regards, Anthony Liguori --- hw/virtio-pci.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index e101fa0..7a86a81 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -155,7 +155,7 @@ static int virtio_pci_load_config(void * opaque, QEMUFile *f) /* Try to find out if the guest has bus master disabled, but is in ready state. Then we have a buggy guest OS. */ -if (!(proxy->vdev->status& VIRTIO_CONFIG_S_DRIVER_OK)&& +if ((proxy->vdev->status& VIRTIO_CONFIG_S_DRIVER_OK)&& !(proxy->pci_dev.config[PCI_COMMAND]& PCI_COMMAND_MASTER)) { proxy->bugs |= VIRTIO_PCI_BUG_BUS_MASTER; }
Re: [Qemu-devel] [PATCH-V7 01/10] virtio-9p: Introduces an option to specify the security model.
On 06/14/2010 03:34 PM, Venkateswararao Jujjuri (JV) wrote: The new option is: -fsdev fstype,id=myid,path=/share_path/,security_model=[mapped|passthrough] -virtfs fstype,path=/share_path/,security_model=[mapped|passthrough],mnt_tag=tag In the case of mapped security model, files are created with QEMU user credentials and the client-user's credentials are saved in extended attributes. Whereas in the case of passthrough security model, files on the filesystem are directly created with client-user's credentials. Signed-off-by: Venkateswararao Jujjuri Applied all. Thanks. Regards, Anthony Liguori --- fsdev/qemu-fsdev.c |9 - fsdev/qemu-fsdev.h |1 + hw/virtio-9p.c |9 + qemu-config.c |6 ++ qemu-options.hx| 15 +++ vl.c | 18 +++--- 6 files changed, 50 insertions(+), 8 deletions(-) diff --git a/fsdev/qemu-fsdev.c b/fsdev/qemu-fsdev.c index 813e1f7..ad69b0e 100644 --- a/fsdev/qemu-fsdev.c +++ b/fsdev/qemu-fsdev.c @@ -34,7 +34,7 @@ int qemu_fsdev_add(QemuOpts *opts) return -1; } - for (i = 0; i< ARRAY_SIZE(FsTypes); i++) { +for (i = 0; i< ARRAY_SIZE(FsTypes); i++) { if (strcmp(FsTypes[i].name, qemu_opt_get(opts, "fstype")) == 0) { break; } @@ -46,10 +46,17 @@ int qemu_fsdev_add(QemuOpts *opts) return -1; } +if (qemu_opt_get(opts, "security_model") == NULL) { +fprintf(stderr, "fsdev: No security_model specified.\n"); +return -1; +} + fsle = qemu_malloc(sizeof(*fsle)); fsle->fse.fsdev_id = qemu_strdup(qemu_opts_id(opts)); fsle->fse.path = qemu_strdup(qemu_opt_get(opts, "path")); +fsle->fse.security_model = qemu_strdup(qemu_opt_get(opts, +"security_model")); fsle->fse.ops = FsTypes[i].ops; QTAILQ_INSERT_TAIL(&fstype_entries, fsle, next); diff --git a/fsdev/qemu-fsdev.h b/fsdev/qemu-fsdev.h index b50fbe0..6c27881 100644 --- a/fsdev/qemu-fsdev.h +++ b/fsdev/qemu-fsdev.h @@ -40,6 +40,7 @@ typedef struct FsTypeTable { typedef struct FsTypeEntry { char *fsdev_id; char *path; +char *security_model; FileOperations *ops; } FsTypeEntry; diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c index 038bb39..2530488 100644 --- a/hw/virtio-9p.c +++ b/hw/virtio-9p.c @@ -2253,6 +2253,15 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf) exit(1); } +if (!strcmp(fse->security_model, "passthrough")&& +!strcmp(fse->security_model, "mapped")) { +/* user haven't specified a correct security option */ +fprintf(stderr, "one of the following must be specified as the" +"security option:\n\t security_model=passthrough \n\t " +"security_model=mapped\n"); +return NULL; +} + if (lstat(fse->path,&stat)) { fprintf(stderr, "share path %s does not exist\n", fse->path); exit(1); diff --git a/qemu-config.c b/qemu-config.c index 5a4e61b..95abe61 100644 --- a/qemu-config.c +++ b/qemu-config.c @@ -163,6 +163,9 @@ QemuOptsList qemu_fsdev_opts = { }, { .name = "path", .type = QEMU_OPT_STRING, +}, { +.name = "security_model", +.type = QEMU_OPT_STRING, }, { /*End of list */ } }, @@ -184,6 +187,9 @@ QemuOptsList qemu_virtfs_opts = { }, { .name = "mount_tag", .type = QEMU_OPT_STRING, +}, { +.name = "security_model", +.type = QEMU_OPT_STRING, }, { /*End of list */ } diff --git a/qemu-options.hx b/qemu-options.hx index a6928b7..d1d2272 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -486,7 +486,7 @@ ETEXI DEFHEADING(File system options:) DEF("fsdev", HAS_ARG, QEMU_OPTION_fsdev, -"-fsdev local,id=id,path=path\n", +"-fsdev local,id=id,path=path,security_model=[mapped|passthrough]\n", QEMU_ARCH_ALL) STEXI @@ -502,7 +502,7 @@ The specific Fstype will determine the applicable options. Options to each backend are described below. -...@item -fsdev local ,i...@var{id} ,pa...@var{path} +...@item -fsdev local ,i...@var{id} ,pa...@var{path} ,security_mod...@var{security_model} Create a file-system-"device" for local-filesystem. @@ -510,6 +510,9 @@ Create a file-system-"device" for local-filesystem. @option{path} specifies the path to be exported. @option{path} is required. +...@option{security_model} specifies the security model to be followed. +...@option{security_model} is required. + @end table ETEXI #endif @@ -518,7 +521,7 @@ ETEXI DEFHEADING(Virtual File system pass-through options:) DEF("virtfs", HAS_ARG, QEMU_OPTION_virtfs, -"-virtfs local,path=path,mount_tag=tag\n", +"-virtfs local,path=path,mount_tag=tag,security_model=[mapped|passthrough]\n", QEMU_ARCH_ALL) STEXI @@ -534,7 +537,7 @@ The speci
Re: [Qemu-devel] [PATCH] give some useful error messages when tap open
On 06/02/2010 12:33 PM, Luiz Capitulino wrote: From: Michael Tokarev In net/tap-linux.c, when manipulation of /dev/net/tun fails, it prints (with fprintf) something like this: warning: could not open /dev/net/tun: no virtual network emulation this has 2 issues: 1) it is not a warning really, it's a fatal error (kvm exits after that), 2) there's no indication as of what's actually wrong: printing errno there is helpful. The patch below removes the "warning" prefix, uses %m (since it's linux, %m is available as format modifier), and changes fprintf() to %qemu_error(). Now it prints something like this instead: could not configure /dev/net/tun: Device or resource busy (there are 2 messages like that in the same function) This fixes Debian bug #578154, see http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=578154 Signed-off-by: Michael Tokarev Signed-off-by: Luiz Capitulino Applied. Thanks. Regards, Anthony Liguori --- IMPORTANT: this an old fix that got forgotten, probably because it was submitted in the middle of thread. I've just compiled tested it. net/tap-linux.c |8 +--- 1 files changed, 5 insertions(+), 3 deletions(-) diff --git a/net/tap-linux.c b/net/tap-linux.c index 03b8301..c92983c 100644 --- a/net/tap-linux.c +++ b/net/tap-linux.c @@ -33,14 +33,16 @@ #include "qemu-common.h" #include "qemu-error.h" +#define PATH_NET_TUN "/dev/net/tun" + int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required) { struct ifreq ifr; int fd, ret; -TFR(fd = open("/dev/net/tun", O_RDWR)); +TFR(fd = open(PATH_NET_TUN, O_RDWR)); if (fd< 0) { -fprintf(stderr, "warning: could not open /dev/net/tun: no virtual network emulation\n"); +error_report("could not open %s: %m", PATH_NET_TUN); return -1; } memset(&ifr, 0, sizeof(ifr)); @@ -71,7 +73,7 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required pstrcpy(ifr.ifr_name, IFNAMSIZ, "tap%d"); ret = ioctl(fd, TUNSETIFF, (void *)&ifr); if (ret != 0) { -fprintf(stderr, "warning: could not configure /dev/net/tun: no virtual network emulation\n"); +error_report("could not configure %s (%s): %m", PATH_NET_TUN, ifr.ifr_name); close(fd); return -1; }
Re: [Qemu-devel] [PATCH v3 1/5] Exit if incoming migration fails
On 06/09/2010 07:10 AM, Juan Quintela wrote: Signed-off-by: Juan Quintela Applied 1&2 as we discussed. Thanks. Regards, Anthony Liguori --- migration.c | 16 ++-- migration.h |2 +- vl.c|7 ++- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/migration.c b/migration.c index fbf2339..ecc67f1 100644 --- a/migration.c +++ b/migration.c @@ -36,22 +36,26 @@ static uint32_t max_throttle = (32<< 20); static MigrationState *current_migration; -void qemu_start_incoming_migration(const char *uri) +int qemu_start_incoming_migration(const char *uri) { const char *p; +int ret; if (strstart(uri, "tcp:",&p)) -tcp_start_incoming_migration(p); +ret = tcp_start_incoming_migration(p); #if !defined(WIN32) else if (strstart(uri, "exec:",&p)) -exec_start_incoming_migration(p); +ret = exec_start_incoming_migration(p); else if (strstart(uri, "unix:",&p)) -unix_start_incoming_migration(p); +ret = unix_start_incoming_migration(p); else if (strstart(uri, "fd:",&p)) -fd_start_incoming_migration(p); +ret = fd_start_incoming_migration(p); #endif -else +else { fprintf(stderr, "unknown migration protocol: %s\n", uri); +ret = -EPROTONOSUPPORT; +} +return ret; } int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data) diff --git a/migration.h b/migration.h index 97eef4a..e048bb2 100644 --- a/migration.h +++ b/migration.h @@ -50,7 +50,7 @@ struct FdMigrationState void *opaque; }; -void qemu_start_incoming_migration(const char *uri); +int qemu_start_incoming_migration(const char *uri); int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data); diff --git a/vl.c b/vl.c index 7121cd0..c35b46e 100644 --- a/vl.c +++ b/vl.c @@ -3826,7 +3826,12 @@ int main(int argc, char **argv, char **envp) } if (incoming) { -qemu_start_incoming_migration(incoming); +int ret = qemu_start_incoming_migration(incoming); +if (ret< 0) { +fprintf(stderr, "Migration failed. Exit code %s(%d), exiting.\n", +incoming, ret); +exit(ret); +} } else if (autostart) { vm_start(); }
Re: [Qemu-devel] [PATCH-V2] [virtio-9p] Flush the debug message out to the log file.
On 06/02/2010 10:24 AM, Venkateswararao Jujjuri (JV) wrote: This patch fluesh the debug messages to the log file at the end of each debug message. Changes from V1: Used fflush instead fseek for the flush. Signed-off-by: Venkateswararao Jujjuri Applied. Thanks. Regards, Anthony Liguori --- hw/virtio-9p-debug.c |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/hw/virtio-9p-debug.c b/hw/virtio-9p-debug.c index 2fb2673..e4ab4bc 100644 --- a/hw/virtio-9p-debug.c +++ b/hw/virtio-9p-debug.c @@ -481,4 +481,6 @@ void pprint_pdu(V9fsPDU *pdu) } fprintf(llogfile, ")\n"); +/* Flush the log message out */ +fflush(llogfile); }
Re: [Qemu-devel] [PATCH] Extra scan codes for missing keys
On 06/01/2010 10:32 PM, Bernhard M. Wiedemann wrote: The code comes from http://lists.gnu.org/archive/html/qemu-devel/2010-05/msg02788.html Without this patch it is not possible to send at least 10 special characters (\|'"`~:;[]{}) via the monitor sendkey command. Signed-off-by: Bernhard M. Wiedemann Applied. Thanks. Regards, Anthony Liguori --- monitor.c |7 ++- 1 files changed, 6 insertions(+), 1 deletions(-) diff --git a/monitor.c b/monitor.c index 15b53b9..1635040 100644 --- a/monitor.c +++ b/monitor.c @@ -1563,7 +1563,8 @@ static const KeyDef key_defs[] = { { 0x17, "i" }, { 0x18, "o" }, { 0x19, "p" }, - +{ 0x1a, "bracket_left" }, +{ 0x1b, "bracket_right" }, { 0x1c, "ret" }, { 0x1e, "a" }, @@ -1575,7 +1576,11 @@ static const KeyDef key_defs[] = { { 0x24, "j" }, { 0x25, "k" }, { 0x26, "l" }, +{ 0x27, "semicolon" }, +{ 0x28, "apostrophe" }, +{ 0x29, "grave_accent" }, +{ 0x2b, "backslash" }, { 0x2c, "z" }, { 0x2d, "x" }, { 0x2e, "c" },
Re: [Qemu-devel] [PATCH] virtio-9p: Rearrange fileop structures
On 06/01/2010 03:30 PM, Venkateswararao Jujjuri (JV) wrote: This patch rearranges the fileop structures by moving the structure definitions from virtio-9p.c to virtio-9p.h file. No functional changes. Signed-off-by: Venkateswararao Jujjuri --- Applied. Thanks. Regards, Anthony Liguori hw/virtio-9p.c | 185 ++-- hw/virtio-9p.h | 92 2 files changed, 138 insertions(+), 139 deletions(-) diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c index e5d0112..038bb39 100644 --- a/hw/virtio-9p.c +++ b/hw/virtio-9p.c @@ -21,6 +21,52 @@ int dotu = 1; int debug_9p_pdu; +enum { +Oread = 0x00, +Owrite = 0x01, +Ordwr = 0x02, +Oexec = 0x03, +Oexcl = 0x04, +Otrunc = 0x10, +Orexec = 0x20, +Orclose = 0x40, +Oappend = 0x80, +}; + +static int omode_to_uflags(int8_t mode) +{ +int ret = 0; + +switch (mode& 3) { +case Oread: +ret = O_RDONLY; +break; +case Ordwr: +ret = O_RDWR; +break; +case Owrite: +ret = O_WRONLY; +break; +case Oexec: +ret = O_RDONLY; +break; +} + +if (mode& Otrunc) { +ret |= O_TRUNC; +} + +if (mode& Oappend) { +ret |= O_APPEND; +} + +if (mode& Oexcl) { +ret |= O_EXCL; +} + +return ret; +} + static int v9fs_do_lstat(V9fsState *s, V9fsString *path, struct stat *stbuf) { return s->ops->lstat(&s->ctx, path->data, stbuf); @@ -995,14 +1041,6 @@ out: v9fs_string_free(&aname); } -typedef struct V9fsStatState { -V9fsPDU *pdu; -size_t offset; -V9fsStat v9stat; -V9fsFidState *fidp; -struct stat stbuf; -} V9fsStatState; - static void v9fs_stat_post_lstat(V9fsState *s, V9fsStatState *vs, int err) { if (err == -1) { @@ -1053,19 +1091,6 @@ out: qemu_free(vs); } -typedef struct V9fsWalkState { -V9fsPDU *pdu; -size_t offset; -int16_t nwnames; -int name_idx; -V9fsQID *qids; -V9fsFidState *fidp; -V9fsFidState *newfidp; -V9fsString path; -V9fsString *wnames; -struct stat stbuf; -} V9fsWalkState; - static void v9fs_walk_complete(V9fsState *s, V9fsWalkState *vs, int err) { complete_pdu(s, vs->pdu, err); @@ -1229,62 +1254,6 @@ out: v9fs_walk_complete(s, vs, err); } -typedef struct V9fsOpenState { -V9fsPDU *pdu; -size_t offset; -int8_t mode; -V9fsFidState *fidp; -V9fsQID qid; -struct stat stbuf; - -} V9fsOpenState; - -enum { -Oread = 0x00, -Owrite = 0x01, -Ordwr = 0x02, -Oexec = 0x03, -Oexcl = 0x04, -Otrunc = 0x10, -Orexec = 0x20, -Orclose = 0x40, -Oappend = 0x80, -}; - -static int omode_to_uflags(int8_t mode) -{ -int ret = 0; - -switch (mode& 3) { -case Oread: -ret = O_RDONLY; -break; -case Ordwr: -ret = O_RDWR; -break; -case Owrite: -ret = O_WRONLY; -break; -case Oexec: -ret = O_RDONLY; -break; -} - -if (mode& Otrunc) { -ret |= O_TRUNC; -} - -if (mode& Oappend) { -ret |= O_APPEND; -} - -if (mode& Oexcl) { -ret |= O_EXCL; -} - -return ret; -} - static void v9fs_open_post_opendir(V9fsState *s, V9fsOpenState *vs, int err) { if (vs->fidp->dir == NULL) { @@ -1387,25 +1356,6 @@ out: complete_pdu(s, pdu, err); } -typedef struct V9fsReadState { -V9fsPDU *pdu; -size_t offset; -int32_t count; -int32_t total; -int64_t off; -V9fsFidState *fidp; -struct iovec iov[128]; /* FIXME: bad, bad, bad */ -struct iovec *sg; -off_t dir_pos; -struct dirent *dent; -struct stat stbuf; -V9fsString name; -V9fsStat v9stat; -int32_t len; -int32_t cnt; -int32_t max_count; -} V9fsReadState; - static void v9fs_read_post_readdir(V9fsState *, V9fsReadState *, ssize_t); static void v9fs_read_post_seekdir(V9fsState *s, V9fsReadState *vs, ssize_t err) @@ -1593,19 +1543,6 @@ out: qemu_free(vs); } -typedef struct V9fsWriteState { -V9fsPDU *pdu; -size_t offset; -int32_t len; -int32_t count; -int32_t total; -int64_t off; -V9fsFidState *fidp; -struct iovec iov[128]; /* FIXME: bad, bad, bad */ -struct iovec *sg; -int cnt; -} V9fsWriteState; - static void v9fs_write_post_writev(V9fsState *s, V9fsWriteState *vs, ssize_t err) { @@ -1702,19 +1639,6 @@ out: qemu_free(vs); } -typedef struct V9fsCreateState { -V9fsPDU *pdu; -size_t offset; -V9fsFidState *fidp; -V9fsQID qid; -int32_t perm; -int8_t mode; -struct stat stbuf; -V9fsString name; -V9fsString extension; -V9fsString fullname; -} V9fsCreateState; - static void v9fs_post_create(V9fsState *s, V9fsCreateState *vs, int err) { if (err == 0) { @@ -1934,12 +1858,6 @@ static void v9f
Re: [Qemu-devel] SPARC not booting SMP Linux kernel
2010/6/22 陈宇飞 : > > On 2010-6-22, at 下午1:46, Artyom Tarasenko wrote: > >> 2010/4/28 陈宇飞 : >>> I've tested the latest git HEAD version. But still has the problem. >>> >>> Investigating Linux kernel execution shows that the function which will >>> clear the interrupt is not executed. >>> >>> Here's the relevant kernel code. >>> >>> maybe_smp4m_msg: >>> GET_PROCESSOR4M_ID(o3) >>> set sun4m_interrupts, %l5 >>> ld [%l5], %o5 >>> sethi %hi(0x4000), %o2 >>> sll %o3, 12, %o3 >>> ld [%o5 + %o3], %o1 >>> andcc %o1, %o2, %g0 >>> be,asmp4m_ticker /* Jump to smp4m_ticker, which will clear >>> interrupt */ >>>cmp%l7, 14 /* Comparing the interrupt level*/ >>> st %o2, [%o5 + 0x4] >>> WRITE_PAUSE >>> ld [%o5], %g0 >>> WRITE_PAUSE >>> or %l0, PSR_PIL, %l4 >>> wr %l4, 0x0, %psr >>> WRITE_PAUSE >>> wr %l4, PSR_ET, %psr >>> WRITE_PAUSE >>> callsmp_reschedule_irq >>>nop >>> >>> RESTORE_ALL >>> >> >> actually what would be interesting to look at is the code of >> smp4m_ticker - the routine which should clear the irq. >> On 4/27/10, 陈宇飞 wrote: > Actually this has been test before. > > http://lists.gnu.org/archive/html/qemu-devel/2006-08/msg00512.html That was before I added SMP support to OpenBIOS. > I've tested Debian 3.1 (with Linux 2.4.27.3) and Debian 4.0 (with > Linux 2.6.18.6), on both qemu 0.10.6 and 0.12.3, emulating machine is > set to SS-20. > > 1. non-smp kernel successfully boots with both -smp 1 or -smp 2. > 2. smp kernel can only boot with -smp 1. (The 2.6 kernel is cross > compiled by gcc 4.2.4 since no binary package is available) > > Some investigation with qemu's debug message and Linux kernel dump > (the 2.6 kernel) shows that > > 1. When the boot cpu tries to start cpu 1, cpu 1 calls > local_irq_enable. After that, cpu 1 get's lot's of level 14 interrupt. >> >> Is 'cpu 1' the first or the second cpu? > > 'cpu 1' is the second cpu. > >> > 2. Printing out the executed TBs' pc values shows that kernel > interrupt handler is executed. > 3. Qemu's do_interrupt debug message shows that cpu 1 always get level > 14 interrupt at the same pc, which is the nop instruction just after > the "mov %g1, %psr" instruction. > > I guess that the interrupt is not cleared even after the execution of > the interrupt handler. I've found debian installation report which > boots smp linux kernel, so I thinks this problem is caused by qemu? >> >> Can you please try the patch http://patchwork.ozlabs.org/patch/56338/ ? >> Does it improve the situation? > > I've tested this patch, but still have the same problem. Can you try enabling debug in hw/slavio_timer.c and hw/slavio_intctl.c and look whether the second cpu tries to write any register there between the interrupts? > I'm tring to fix this problem but I'm not familiar with sparc > architecture, is there any clue? This sounds awfully familiar to the problems Solaris had with interrupts. Does the problem still exist with git HEAD version of QEMU? > -- > Best regards, > Chen Yufei > > -- Regards, Artyom Tarasenko solaris/sparc under qemu blog: http://tyom.blogspot.com/
[Qemu-devel] [Bug 597402] [NEW] qemu does not call unlink() on temp files in snapshot mode
Public bug reported: == overview == When booting guests in snapshot mode qemu never calls unlink() on the files storing changes to the images. This results in large amounts of disk space being used over time. This bug seems to have been introduced by qemu git commit b6ce07aa83bdee3cfd2610f270a0ce304e78df95 == steps to reproduce == 1) Boot a guest like so: qemu -m 512 -drive file=/scratch/images/mdroth/rhel54_64_base.raw,snapshot=on == actual results == /tmp/vl.* files are created and never unlinked/deleted. for example: mdr...@illuin:~/dev/kvm/qemu-build$ x86_64-softmmu/qemu-system-x86_64 -m 512 -drive file=/media/secondary/vm/fc12_64_base.raw,snapshot=on & [1] 24080 mdr...@illuin:~/dev/kvm/qemu-build$ ls -l /tmp/vl* -rw--- 1 mdroth mdroth 262144 2010-06-22 14:21 /tmp/vl.tFSAmR mdr...@illuin:~/dev/kvm/qemu-build$ fuser /tmp/vl* /tmp/vl.tFSAmR: 24080 == expected results == temporary files should immediately be unlink()'ed and not be present in the file listing. == system details == mdr...@illuin:~/dev/kvm/qemu-build$ uname -a Linux illuin 2.6.31-17-generic #54-Ubuntu SMP Thu Dec 10 17:01:44 UTC 2009 x86_64 GNU/Linux latest commit (cada87c432e3b9cd55869a24055baf2b7bc0b70c) from qemu.git master branch: mdr...@illuin:~/dev/kvm/qemu-build$ x86_64-softmmu/qemu-system-x86_64 --version QEMU emulator version 0.12.50, Copyright (c) 2003-2008 Fabrice Bellard ** Affects: qemu Importance: Undecided Status: New -- qemu does not call unlink() on temp files in snapshot mode https://bugs.launchpad.net/bugs/597402 You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. Status in QEMU: New Bug description: == overview == When booting guests in snapshot mode qemu never calls unlink() on the files storing changes to the images. This results in large amounts of disk space being used over time. This bug seems to have been introduced by qemu git commit b6ce07aa83bdee3cfd2610f270a0ce304e78df95 == steps to reproduce == 1) Boot a guest like so: qemu -m 512 -drive file=/scratch/images/mdroth/rhel54_64_base.raw,snapshot=on == actual results == /tmp/vl.* files are created and never unlinked/deleted. for example: mdr...@illuin:~/dev/kvm/qemu-build$ x86_64-softmmu/qemu-system-x86_64 -m 512 -drive file=/media/secondary/vm/fc12_64_base.raw,snapshot=on & [1] 24080 mdr...@illuin:~/dev/kvm/qemu-build$ ls -l /tmp/vl* -rw--- 1 mdroth mdroth 262144 2010-06-22 14:21 /tmp/vl.tFSAmR mdr...@illuin:~/dev/kvm/qemu-build$ fuser /tmp/vl* /tmp/vl.tFSAmR: 24080 == expected results == temporary files should immediately be unlink()'ed and not be present in the file listing. == system details == mdr...@illuin:~/dev/kvm/qemu-build$ uname -a Linux illuin 2.6.31-17-generic #54-Ubuntu SMP Thu Dec 10 17:01:44 UTC 2009 x86_64 GNU/Linux latest commit (cada87c432e3b9cd55869a24055baf2b7bc0b70c) from qemu.git master branch: mdr...@illuin:~/dev/kvm/qemu-build$ x86_64-softmmu/qemu-system-x86_64 --version QEMU emulator version 0.12.50, Copyright (c) 2003-2008 Fabrice Bellard
[Qemu-devel] [Bug 524447] Re: virsh save is very slow
Just a note that the 0.8.1 release available in maverick gives me about a 50-second save for a 512M memory image (producing 100M outfile). The patch listed above and suspected of speeding the saves is not in 0.8.1. When I hand-apply just that patch, saves take about 8 seconds, but restore fails. Presumably taking the whole of latest git (or 0.8.2 whenever it is released) will result in both working and fast save/restore. -- virsh save is very slow https://bugs.launchpad.net/bugs/524447 You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. Status in libvirt virtualization API: Unknown Status in QEMU: Invalid Status in “libvirt” package in Ubuntu: Confirmed Status in “qemu-kvm” package in Ubuntu: Confirmed Bug description: As reported here: http://www.redhat.com/archives/libvir-list/2009-December/msg00203.html "virsh save" is very slow - it writes the image at around 1MB/sec on my test system. (I think I saw a bug report for this issue on Fedora's bugzilla, but I can't find it now...) Confirmed under Karmic.
[Qemu-devel] [PATCH 13/13] QMP: Drop old input object checking
Previous commit added qmp_check_input_obj(), it does all the checking we need. Signed-off-by: Luiz Capitulino --- monitor.c |6 -- 1 files changed, 0 insertions(+), 6 deletions(-) diff --git a/monitor.c b/monitor.c index a24a152..c558cc7 100644 --- a/monitor.c +++ b/monitor.c @@ -4239,9 +4239,6 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) if (!obj) { qerror_report(QERR_QMP_BAD_INPUT_OBJECT, "execute"); goto err_input; -} else if (qobject_type(obj) != QTYPE_QSTRING) { -qerror_report(QERR_QMP_BAD_INPUT_OBJECT_MEMBER, "execute", "string"); -goto err_input; } cmd_name = qstring_get_str(qobject_to_qstring(obj)); @@ -4273,9 +4270,6 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) obj = qdict_get(input, "arguments"); if (!obj) { args = qdict_new(); -} else if (qobject_type(obj) != QTYPE_QDICT) { -qerror_report(QERR_QMP_BAD_INPUT_OBJECT_MEMBER, "arguments", "object"); -goto err_input; } else { args = qobject_to_qdict(obj); QINCREF(args); -- 1.7.1.359.gd0b8d
[Qemu-devel] [PATCH 06/13] QDict: Introduce qdict_get_try_bool()
Signed-off-by: Luiz Capitulino --- qdict.c | 18 ++ qdict.h |1 + 2 files changed, 19 insertions(+), 0 deletions(-) diff --git a/qdict.c b/qdict.c index a28a0a9..dee0fb4 100644 --- a/qdict.c +++ b/qdict.c @@ -308,6 +308,24 @@ int64_t qdict_get_try_int(const QDict *qdict, const char *key, } /** + * qdict_get_try_bool(): Try to get a bool mapped by 'key' + * + * Return bool mapped by 'key', if it is not present in the + * dictionary or if the stored object is not of QBool type + * 'def_value' will be returned. + */ +int qdict_get_try_bool(const QDict *qdict, const char *key, int def_value) +{ +QObject *obj; + +obj = qdict_get(qdict, key); +if (!obj || qobject_type(obj) != QTYPE_QBOOL) +return def_value; + +return qbool_get_int(qobject_to_qbool(obj)); +} + +/** * qdict_get_try_str(): Try to get a pointer to the stored string * mapped by 'key' * diff --git a/qdict.h b/qdict.h index 0e7a43f..929d8d2 100644 --- a/qdict.h +++ b/qdict.h @@ -61,6 +61,7 @@ QDict *qdict_get_qdict(const QDict *qdict, const char *key); const char *qdict_get_str(const QDict *qdict, const char *key); int64_t qdict_get_try_int(const QDict *qdict, const char *key, int64_t def_value); +int qdict_get_try_bool(const QDict *qdict, const char *key, int def_value); const char *qdict_get_try_str(const QDict *qdict, const char *key); #endif /* QDICT_H */ -- 1.7.1.359.gd0b8d
[Qemu-devel] [PATCH 07/13] Monitor: handle optional '-' arg as a bool
Historically, user monitor arguments beginning with '-' (eg. '-f') were passed as integers down to handlers. I've maintained this behavior in the new monitor because we didn't have a boolean type at the very beginning of QMP. Today we have it and this behavior is causing trouble to QMP's argument checker. This commit fixes the problem by doing the following changes: 1. User Monitor Before: the optional arg was represented as a QInt, we'd pass 1 down to handlers if the user specified the argument or 0 otherwise This commit: the optional arg is represented as a QBool, we pass true down to handlers if the user specified the argument, otherwise _nothing_ is passed 2. QMP Before: the client was required to pass the arg as QBool, but we'd convert it to QInt internally. If the argument wasn't passed, we'd pass 0 down This commit: still require a QBool, but doesn't do any conversion and doesn't pass any default value 3. Convert existing handlers (do_eject()/do_migrate()) to the new way Before: Both handlers would expect a QInt value, either 0 or 1 This commit: Change the handlers to accept a QBool, they handle the following cases: A) true is passed: the option is enabled B) false is passed: the option is disabled C) nothing is passed: option not specified, use default behavior Signed-off-by: Luiz Capitulino --- blockdev.c |2 +- migration.c | 16 +++- monitor.c | 17 +++-- 3 files changed, 11 insertions(+), 24 deletions(-) diff --git a/blockdev.c b/blockdev.c index b376884..5844eac 100644 --- a/blockdev.c +++ b/blockdev.c @@ -523,7 +523,7 @@ static int eject_device(Monitor *mon, BlockDriverState *bs, int force) int do_eject(Monitor *mon, const QDict *qdict, QObject **ret_data) { BlockDriverState *bs; -int force = qdict_get_int(qdict, "force"); +int force = qdict_get_try_bool(qdict, "force", 0); const char *filename = qdict_get_str(qdict, "device"); bs = bdrv_find(filename); diff --git a/migration.c b/migration.c index 64ed36e..4f466b7 100644 --- a/migration.c +++ b/migration.c @@ -58,7 +58,9 @@ int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data) { MigrationState *s = NULL; const char *p; -int detach = qdict_get_int(qdict, "detach"); +int detach = qdict_get_try_bool(qdict, "detach", 0); +int blk = qdict_get_try_bool(qdict, "blk", 0); +int inc = qdict_get_try_bool(qdict, "inc", 0); const char *uri = qdict_get_str(qdict, "uri"); if (current_migration && @@ -69,21 +71,17 @@ int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data) if (strstart(uri, "tcp:", &p)) { s = tcp_start_outgoing_migration(mon, p, max_throttle, detach, - (int)qdict_get_int(qdict, "blk"), - (int)qdict_get_int(qdict, "inc")); + blk, inc); #if !defined(WIN32) } else if (strstart(uri, "exec:", &p)) { s = exec_start_outgoing_migration(mon, p, max_throttle, detach, - (int)qdict_get_int(qdict, "blk"), - (int)qdict_get_int(qdict, "inc")); + blk, inc); } else if (strstart(uri, "unix:", &p)) { s = unix_start_outgoing_migration(mon, p, max_throttle, detach, - (int)qdict_get_int(qdict, "blk"), - (int)qdict_get_int(qdict, "inc")); + blk, inc); } else if (strstart(uri, "fd:", &p)) { s = fd_start_outgoing_migration(mon, p, max_throttle, detach, -(int)qdict_get_int(qdict, "blk"), -(int)qdict_get_int(qdict, "inc")); +blk, inc); #endif } else { monitor_printf(mon, "unknown migration protocol: %s\n", uri); diff --git a/monitor.c b/monitor.c index 05a7ed1..3df8174 100644 --- a/monitor.c +++ b/monitor.c @@ -3560,7 +3560,7 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon, case '-': { const char *tmp = p; -int has_option, skip_key = 0; +int skip_key = 0; /* option */ c = *typestr++; @@ -3568,7 +3568,6 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon, goto bad_type; while (qemu_isspace(*p)) p++; -has_option = 0; if (*p == '-') { p++; if(c != *p) { @@ -3584,11 +3583,11 @@ static const mon
[Qemu-devel] [PATCH 08/13] QMP: New argument checker (first part)
Current QMP's argument checker is more complex than it should be and has (at least) one serious bug: it ignores unknown arguments. To solve both problems we introduce a new argument checker. It's added on top of the existing one, so that there are no regressions during the transition. This commit introduces the first part of the new checker, which is run by qmp_check_client_args() and does the following: 1. Check if all mandatory arguments were provided 2. Set flags for argument validation In order to do that, we transform the args_type string (from qemu-montor.hx) into a qdict and iterate over it. Next commit adds the new checker's second part: type checking and invalid argument detection. Signed-off-by: Luiz Capitulino --- monitor.c | 106 + 1 files changed, 106 insertions(+), 0 deletions(-) diff --git a/monitor.c b/monitor.c index 3df8174..b4fe5ba 100644 --- a/monitor.c +++ b/monitor.c @@ -177,6 +177,9 @@ static inline void mon_print_count_init(Monitor *mon) { } static inline int mon_print_count_get(const Monitor *mon) { return 0; } #endif /* CONFIG_DEBUG_MONITOR */ +/* QMP checker flags */ +#define QMP_CHECKER_OTYPE 1 /* O-type argument is present */ + static QLIST_HEAD(mon_list, Monitor) mon_list; static const mon_cmd_t mon_cmds[]; @@ -4135,6 +4138,104 @@ static int invalid_qmp_mode(const Monitor *mon, const char *cmd_name) return (qmp_cmd_mode(mon) ? is_cap : !is_cap); } +/* + * - Check if the client has passed all mandatory args + * - Set special flags for argument validation + */ +static int check_mandatory_args(const QDict *cmd_args, +const QDict *client_args, int *flags) +{ +const QDictEntry *ent; + +for (ent = qdict_first(cmd_args); ent; ent = qdict_next(cmd_args, ent)) { +const char *cmd_arg_name = qdict_entry_key(ent); +QString *type = qobject_to_qstring(qdict_entry_value(ent)); +assert(type != NULL); + +if (qstring_get_str(type)[0] == 'O') { +assert((*flags & QMP_CHECKER_OTYPE) == 0); +*flags |= QMP_CHECKER_OTYPE; +} else if (qstring_get_str(type)[0] != '-' && + qstring_get_str(type)[1] != '?' && + !qdict_haskey(client_args, cmd_arg_name)) { +qerror_report(QERR_MISSING_PARAMETER, cmd_arg_name); +return -1; +} +} + +return 0; +} + +static QDict *qdict_from_args_type(const char *args_type) +{ +int i; +QDict *qdict; +QString *key, *type, *cur_qs; + +assert(args_type != NULL); + +qdict = qdict_new(); + +if (args_type == NULL || args_type[0] == '\0') { +/* no args, empty qdict */ +goto out; +} + +key = qstring_new(); +type = qstring_new(); + +cur_qs = key; + +for (i = 0;; i++) { +switch (args_type[i]) { +case ',': +case '\0': +qdict_put(qdict, qstring_get_str(key), type); +QDECREF(key); +if (args_type[i] == '\0') { +goto out; +} +type = qstring_new(); /* qdict has ref */ +cur_qs = key = qstring_new(); +break; +case ':': +cur_qs = type; +break; +default: +qstring_append_chr(cur_qs, args_type[i]); +break; +} +} + +out: +return qdict; +} + +/* + * Client argument checking rules: + * + * 1. Client must provide all mandatory arguments + */ +static int qmp_check_client_args(const mon_cmd_t *cmd, QDict *client_args) +{ +int flags, err; +QDict *cmd_args; + +cmd_args = qdict_from_args_type(cmd->args_type); + +flags = 0; +err = check_mandatory_args(cmd_args, client_args, &flags); +if (err) { +goto out; +} + +/* TODO: Check client args type */ + +out: +QDECREF(cmd_args); +return err; +} + static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) { int err; @@ -4210,6 +4311,11 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) QDECREF(input); +err = qmp_check_client_args(cmd, args); +if (err < 0) { +goto err_out; +} + err = monitor_check_qmp_args(cmd, args); if (err < 0) { goto err_out; -- 1.7.1.359.gd0b8d
[Qemu-devel] [PATCH 09/13] QMP: New argument checker (second part)
This commit introduces the second (and last) part of QMP's new argument checker. The job is done by check_client_args_type(), it iterates over the client's argument qdict and for for each argument it checks if it exists and if its type is valid. It's important to observe the following changes from the existing argument checker: - If the handler accepts an O-type argument, unknown arguments are passed down to it. It's up to O-type handlers to validate their arguments - Boolean types (eg. 'b' and '-') don't accept integers anymore, only json-bool - Argument types '/' and '.' are currently unsupported under QMP, thus they're not handled Signed-off-by: Luiz Capitulino --- monitor.c | 100 - 1 files changed, 99 insertions(+), 1 deletions(-) diff --git a/monitor.c b/monitor.c index b4fe5ba..8d074c2 100644 --- a/monitor.c +++ b/monitor.c @@ -4139,6 +4139,101 @@ static int invalid_qmp_mode(const Monitor *mon, const char *cmd_name) } /* + * Argument validation rules: + * + * 1. The argument must exist in cmd_args qdict + * 2. The argument type must be the expected one + * + * Special case: If the argument doesn't exist in cmd_args and + * the QMP_CHECKER_OTYPE flag is set, then the + * argument is considered an O-type one and the + * checking is skipped for it. + */ +static int check_client_args_type(const QDict *client_args, + const QDict *cmd_args, int flags) +{ +const QDictEntry *ent; + +for (ent = qdict_first(client_args); ent;ent = qdict_next(client_args,ent)){ +QObject *obj; +QString *arg_type; +const QObject *client_arg = qdict_entry_value(ent); +const char *client_arg_name = qdict_entry_key(ent); + +obj = qdict_get(cmd_args, client_arg_name); +if (!obj) { +if (flags & QMP_CHECKER_OTYPE) { +/* + * This handler accepts O-type arguments, it's up to it to + * check for unknowns and validate its type. + */ +continue; +} +/* client arg doesn't exist */ +qerror_report(QERR_INVALID_PARAMETER, client_arg_name); +return -1; +} + +arg_type = qobject_to_qstring(obj); +assert(arg_type != NULL); + +/* check if argument's type is correct */ +switch (qstring_get_str(arg_type)[0]) { +case 'F': +case 'B': +case 's': +if (qobject_type(client_arg) != QTYPE_QSTRING) { +qerror_report(QERR_INVALID_PARAMETER_TYPE, client_arg_name, + "string"); +return -1; +} +break; +case 'i': +case 'l': +case 'M': +if (qobject_type(client_arg) != QTYPE_QINT) { +qerror_report(QERR_INVALID_PARAMETER_TYPE, client_arg_name, + "int"); +return -1; +} +break; +case 'f': +case 'T': +if (qobject_type(client_arg) != QTYPE_QINT && +qobject_type(client_arg) != QTYPE_QFLOAT) { +qerror_report(QERR_INVALID_PARAMETER_TYPE, client_arg_name, + "number"); + return -1; +} +break; +case 'b': +case '-': +if (qobject_type(client_arg) != QTYPE_QBOOL) { +qerror_report(QERR_INVALID_PARAMETER_TYPE, client_arg_name, + "bool"); + return -1; +} +break; +case 'O': +/* XXX: this argument has the same name of the O-type defined in +in qemu-monitor.hx. This is not allowed, right? */ +qerror_report(QERR_INVALID_PARAMETER, client_arg_name); +return -1; +case '/': +case '.': +/* + * These types are not supported by QMP and thus are not + * handled here. Fall through. + */ +default: +abort(); +} +} + +return 0; +} + +/* * - Check if the client has passed all mandatory args * - Set special flags for argument validation */ @@ -4215,6 +4310,9 @@ out: * Client argument checking rules: * * 1. Client must provide all mandatory arguments + * 2. Each argument provided by the client must be expected + * 3. Each argument provided by the client must have the type expected + *by the command */ static int qmp_check_client_args(const mon_cmd_t *cmd, QDict *client_args) { @@ -4229,7 +4327,7 @@ static int qmp_check_client_args(const mon_cmd_t *cmd, QDict *client_args) goto out; } -/* TODO: Check client args type */ +err = check_client_args_type(client_args, cmd_args, flags); out: QDECREF(cmd_args); -- 1.7.1.359.gd0
[Qemu-devel] [PATCH 10/13] QMP: Drop old client argument checker
Previous two commits added qmp_check_client_args(), which fully replaces this code and is way better. It's important to note that the new checker doesn't support the '/' arg type. As we don't have any of those handlers converted to QMP, this is just dead code. Signed-off-by: Luiz Capitulino --- monitor.c | 176 - 1 files changed, 0 insertions(+), 176 deletions(-) diff --git a/monitor.c b/monitor.c index 8d074c2..2a29095 100644 --- a/monitor.c +++ b/monitor.c @@ -3961,177 +3961,6 @@ static int monitor_can_read(void *opaque) return (mon->suspend_cnt == 0) ? 1 : 0; } -typedef struct CmdArgs { -QString *name; -int type; -int flag; -int optional; -} CmdArgs; - -static int check_opt(const CmdArgs *cmd_args, const char *name, QDict *args) -{ -if (!cmd_args->optional) { -qerror_report(QERR_MISSING_PARAMETER, name); -return -1; -} - -return 0; -} - -static int check_arg(const CmdArgs *cmd_args, QDict *args) -{ -QObject *value; -const char *name; - -name = qstring_get_str(cmd_args->name); - -if (!args) { -return check_opt(cmd_args, name, args); -} - -value = qdict_get(args, name); -if (!value) { -return check_opt(cmd_args, name, args); -} - -switch (cmd_args->type) { -case 'F': -case 'B': -case 's': -if (qobject_type(value) != QTYPE_QSTRING) { -qerror_report(QERR_INVALID_PARAMETER_TYPE, name, "string"); -return -1; -} -break; -case '/': { -int i; -const char *keys[] = { "count", "format", "size", NULL }; - -for (i = 0; keys[i]; i++) { -QObject *obj = qdict_get(args, keys[i]); -if (!obj) { -qerror_report(QERR_MISSING_PARAMETER, name); -return -1; -} -if (qobject_type(obj) != QTYPE_QINT) { -qerror_report(QERR_INVALID_PARAMETER_TYPE, name, "int"); -return -1; -} -} -break; -} -case 'i': -case 'l': -case 'M': -if (qobject_type(value) != QTYPE_QINT) { -qerror_report(QERR_INVALID_PARAMETER_TYPE, name, "int"); -return -1; -} -break; -case 'f': -case 'T': -if (qobject_type(value) != QTYPE_QINT && qobject_type(value) != QTYPE_QFLOAT) { -qerror_report(QERR_INVALID_PARAMETER_TYPE, name, "number"); -return -1; -} -break; -case 'b': -if (qobject_type(value) != QTYPE_QBOOL) { -qerror_report(QERR_INVALID_PARAMETER_TYPE, name, "bool"); -return -1; -} -break; -case '-': -if (qobject_type(value) != QTYPE_QINT && -qobject_type(value) != QTYPE_QBOOL) { -qerror_report(QERR_INVALID_PARAMETER_TYPE, name, "bool"); -return -1; -} -break; -case 'O': -default: -/* impossible */ -abort(); -} - -return 0; -} - -static void cmd_args_init(CmdArgs *cmd_args) -{ -cmd_args->name = qstring_new(); -cmd_args->type = cmd_args->flag = cmd_args->optional = 0; -} - -static int check_opts(QemuOptsList *opts_list, QDict *args) -{ -assert(!opts_list->desc->name); -return 0; -} - -/* - * This is not trivial, we have to parse Monitor command's argument - * type syntax to be able to check the arguments provided by clients. - * - * In the near future we will be using an array for that and will be - * able to drop all this parsing... - */ -static int monitor_check_qmp_args(const mon_cmd_t *cmd, QDict *args) -{ -int err; -const char *p; -CmdArgs cmd_args; -QemuOptsList *opts_list; - -if (cmd->args_type == NULL) { -return (qdict_size(args) == 0 ? 0 : -1); -} - -err = 0; -cmd_args_init(&cmd_args); -opts_list = NULL; - -for (p = cmd->args_type;; p++) { -if (*p == ':') { -cmd_args.type = *++p; -p++; -if (cmd_args.type == '-') { -cmd_args.flag = *p++; -cmd_args.optional = 1; -} else if (cmd_args.type == 'O') { -opts_list = qemu_find_opts(qstring_get_str(cmd_args.name)); -assert(opts_list); -} else if (*p == '?') { -cmd_args.optional = 1; -p++; -} - -assert(*p == ',' || *p == '\0'); -if (opts_list) { -err = check_opts(opts_list, args); -opts_list = NULL; -} else { -err = check_arg(&cmd_args, args); -QDECREF(cmd_args.name); -cmd_args_init(&cmd_args)
[Qemu-devel] [PATCH 04/13] QDict: Introduce new iteration API
It's composed of functions qdict_first() and qdict_next(), plus functions to access QDictEntry values. This API was suggested by Markus Armbruster and it offers full control over the iteration process. The usage is simple, the following example prints all keys in 'qdict' (it's hopefully better than any English description): QDict *qdict; const QDictEntry *ent; [...] for (ent = qdict_first(qdict); ent; ent = qdict_next(qdict, ent)) { printf("%s ", qdict_entry_key(ent)); } Signed-off-by: Luiz Capitulino --- qdict.c | 37 + qdict.h |2 ++ 2 files changed, 39 insertions(+), 0 deletions(-) diff --git a/qdict.c b/qdict.c index c467763..a28a0a9 100644 --- a/qdict.c +++ b/qdict.c @@ -345,6 +345,43 @@ void qdict_iter(const QDict *qdict, } } +static QDictEntry *qdict_next_entry(const QDict *qdict, int first_bucket) +{ +int i; + +for (i = first_bucket; i < QDICT_BUCKET_MAX; i++) { +if (!QLIST_EMPTY(&qdict->table[i])) { +return QLIST_FIRST(&qdict->table[i]); +} +} + +return NULL; +} + +/** + * qdict_first(): Return first qdict entry for iteration. + */ +const QDictEntry *qdict_first(const QDict *qdict) +{ +return qdict_next_entry(qdict, 0); +} + +/** + * qdict_next(): Return next qdict entry in an iteration. + */ +const QDictEntry *qdict_next(const QDict *qdict, const QDictEntry *entry) +{ +QDictEntry *ret; + +ret = QLIST_NEXT(entry, next); +if (!ret) { +unsigned int bucket = tdb_hash(entry->key) % QDICT_BUCKET_MAX; +ret = qdict_next_entry(qdict, bucket + 1); +} + +return ret; +} + /** * qentry_destroy(): Free all the memory allocated by a QDictEntry */ diff --git a/qdict.h b/qdict.h index 0c8de3c..0e7a43f 100644 --- a/qdict.h +++ b/qdict.h @@ -45,6 +45,8 @@ QDict *qobject_to_qdict(const QObject *obj); void qdict_iter(const QDict *qdict, void (*iter)(const char *key, QObject *obj, void *opaque), void *opaque); +const QDictEntry *qdict_first(const QDict *qdict); +const QDictEntry *qdict_next(const QDict *qdict, const QDictEntry *entry); /* Helper to qdict_put_obj(), accepts any object */ #define qdict_put(qdict, key, obj) \ -- 1.7.1.359.gd0b8d
[Qemu-devel] [PATCH 11/13] QError: Introduce QERR_QMP_UNEXPECTED_INPUT_OBJECT_MEMBER
Signed-off-by: Luiz Capitulino --- qerror.c |4 qerror.h |3 +++ 2 files changed, 7 insertions(+), 0 deletions(-) diff --git a/qerror.c b/qerror.c index 44d0bf8..8a10557 100644 --- a/qerror.c +++ b/qerror.c @@ -177,6 +177,10 @@ static const QErrorStringTable qerror_table[] = { .desc = "QMP input object member '%(member)' expects '%(expected)'", }, { +.error_fmt = QERR_QMP_UNEXPECTED_INPUT_OBJECT_MEMBER, +.desc = "QMP input object member '%(member)' is unexpected", +}, +{ .error_fmt = QERR_SET_PASSWD_FAILED, .desc = "Could not set password", }, diff --git a/qerror.h b/qerror.h index 77ae574..ef59430 100644 --- a/qerror.h +++ b/qerror.h @@ -148,6 +148,9 @@ QError *qobject_to_qerror(const QObject *obj); #define QERR_QMP_BAD_INPUT_OBJECT_MEMBER \ "{ 'class': 'QMPBadInputObjectMember', 'data': { 'member': %s, 'expected': %s } }" +#define QERR_QMP_UNEXPECTED_INPUT_OBJECT_MEMBER \ +"{ 'class': 'QMPUnexpectedInputObjectMember', 'data': { 'member': %s } }" + #define QERR_SET_PASSWD_FAILED \ "{ 'class': 'SetPasswdFailed', 'data': {} }" -- 1.7.1.359.gd0b8d
[Qemu-devel] [PATCH 02/13] QDict: Small terminology change
Let's call a 'hash' only what is returned by our hash function, anything else is a 'bucket'. This helps avoiding confusion with regard to how we traverse our table. Signed-off-by: Luiz Capitulino --- check-qdict.c |2 +- qdict.c | 24 qdict.h |4 ++-- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/check-qdict.c b/check-qdict.c index 2c3089f..1b070f4 100644 --- a/check-qdict.c +++ b/check-qdict.c @@ -50,7 +50,7 @@ START_TEST(qdict_put_obj_test) qdict_put_obj(qdict, "", QOBJECT(qint_from_int(num))); fail_unless(qdict_size(qdict) == 1); -ent = QLIST_FIRST(&qdict->table[12345 % QDICT_HASH_SIZE]); +ent = QLIST_FIRST(&qdict->table[12345 % QDICT_BUCKET_MAX]); qi = qobject_to_qint(ent->value); fail_unless(qint_get_int(qi) == num); diff --git a/qdict.c b/qdict.c index c974d6f..71be2eb 100644 --- a/qdict.c +++ b/qdict.c @@ -86,11 +86,11 @@ static QDictEntry *alloc_entry(const char *key, QObject *value) * qdict_find(): List lookup function */ static QDictEntry *qdict_find(const QDict *qdict, - const char *key, unsigned int hash) + const char *key, unsigned int bucket) { QDictEntry *entry; -QLIST_FOREACH(entry, &qdict->table[hash], next) +QLIST_FOREACH(entry, &qdict->table[bucket], next) if (!strcmp(entry->key, key)) return entry; @@ -110,11 +110,11 @@ static QDictEntry *qdict_find(const QDict *qdict, */ void qdict_put_obj(QDict *qdict, const char *key, QObject *value) { -unsigned int hash; +unsigned int bucket; QDictEntry *entry; -hash = tdb_hash(key) % QDICT_HASH_SIZE; -entry = qdict_find(qdict, key, hash); +bucket = tdb_hash(key) % QDICT_BUCKET_MAX; +entry = qdict_find(qdict, key, bucket); if (entry) { /* replace key's value */ qobject_decref(entry->value); @@ -122,7 +122,7 @@ void qdict_put_obj(QDict *qdict, const char *key, QObject *value) } else { /* allocate a new entry */ entry = alloc_entry(key, value); -QLIST_INSERT_HEAD(&qdict->table[hash], entry, next); +QLIST_INSERT_HEAD(&qdict->table[bucket], entry, next); qdict->size++; } } @@ -137,7 +137,7 @@ QObject *qdict_get(const QDict *qdict, const char *key) { QDictEntry *entry; -entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_HASH_SIZE); +entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_BUCKET_MAX); return (entry == NULL ? NULL : entry->value); } @@ -148,8 +148,8 @@ QObject *qdict_get(const QDict *qdict, const char *key) */ int qdict_haskey(const QDict *qdict, const char *key) { -unsigned int hash = tdb_hash(key) % QDICT_HASH_SIZE; -return (qdict_find(qdict, key, hash) == NULL ? 0 : 1); +unsigned int bucket = tdb_hash(key) % QDICT_BUCKET_MAX; +return (qdict_find(qdict, key, bucket) == NULL ? 0 : 1); } /** @@ -318,7 +318,7 @@ void qdict_iter(const QDict *qdict, int i; QDictEntry *entry; -for (i = 0; i < QDICT_HASH_SIZE; i++) { +for (i = 0; i < QDICT_BUCKET_MAX; i++) { QLIST_FOREACH(entry, &qdict->table[i], next) iter(entry->key, entry->value, opaque); } @@ -347,7 +347,7 @@ void qdict_del(QDict *qdict, const char *key) { QDictEntry *entry; -entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_HASH_SIZE); +entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_BUCKET_MAX); if (entry) { QLIST_REMOVE(entry, next); qentry_destroy(entry); @@ -366,7 +366,7 @@ static void qdict_destroy_obj(QObject *obj) assert(obj != NULL); qdict = qobject_to_qdict(obj); -for (i = 0; i < QDICT_HASH_SIZE; i++) { +for (i = 0; i < QDICT_BUCKET_MAX; i++) { QDictEntry *entry = QLIST_FIRST(&qdict->table[i]); while (entry) { QDictEntry *tmp = QLIST_NEXT(entry, next); diff --git a/qdict.h b/qdict.h index 72ea563..dcd2b29 100644 --- a/qdict.h +++ b/qdict.h @@ -18,7 +18,7 @@ #include "qemu-queue.h" #include -#define QDICT_HASH_SIZE 512 +#define QDICT_BUCKET_MAX 512 typedef struct QDictEntry { char *key; @@ -29,7 +29,7 @@ typedef struct QDictEntry { typedef struct QDict { QObject_HEAD; size_t size; -QLIST_HEAD(,QDictEntry) table[QDICT_HASH_SIZE]; +QLIST_HEAD(,QDictEntry) table[QDICT_BUCKET_MAX]; } QDict; /* Object API */ -- 1.7.1.359.gd0b8d
[Qemu-devel] [PATCH 05/13] check-qdict: Introduce test for the new iteration API
Signed-off-by: Luiz Capitulino --- check-qdict.c | 31 +++ 1 files changed, 31 insertions(+), 0 deletions(-) diff --git a/check-qdict.c b/check-qdict.c index 1b070f4..6afce5a 100644 --- a/check-qdict.c +++ b/check-qdict.c @@ -194,6 +194,36 @@ START_TEST(qobject_to_qdict_test) } END_TEST +START_TEST(qdict_iterapi_test) +{ +int count; +const QDictEntry *ent; + +fail_unless(qdict_first(tests_dict) == NULL); + +qdict_put(tests_dict, "key1", qint_from_int(1)); +qdict_put(tests_dict, "key2", qint_from_int(2)); +qdict_put(tests_dict, "key3", qint_from_int(3)); + +count = 0; +for (ent = qdict_first(tests_dict); ent; ent = qdict_next(tests_dict, ent)){ +fail_unless(qdict_haskey(tests_dict, qdict_entry_key(ent)) == 1); +count++; +} + +fail_unless(count == qdict_size(tests_dict)); + +/* Do it again to test restarting */ +count = 0; +for (ent = qdict_first(tests_dict); ent; ent = qdict_next(tests_dict, ent)){ +fail_unless(qdict_haskey(tests_dict, qdict_entry_key(ent)) == 1); +count++; +} + +fail_unless(count == qdict_size(tests_dict)); +} +END_TEST + /* * Errors test-cases */ @@ -338,6 +368,7 @@ static Suite *qdict_suite(void) tcase_add_test(qdict_public2_tcase, qdict_haskey_test); tcase_add_test(qdict_public2_tcase, qdict_del_test); tcase_add_test(qdict_public2_tcase, qobject_to_qdict_test); +tcase_add_test(qdict_public2_tcase, qdict_iterapi_test); qdict_errors_tcase = tcase_create("Errors"); suite_add_tcase(s, qdict_errors_tcase); -- 1.7.1.359.gd0b8d
[Qemu-devel] [PATCH 12/13] QMP: Introduce qmp_check_input_obj()
This is similar to qmp_check_client_args(), but it checks if the input object follows the specification (QMP/qmp-spec.txt section 2.3). As we're limited to three keys, the work here is quite simple: we iterate over the input object, checking each time if the current argument complies to the specification. Signed-off-by: Luiz Capitulino --- monitor.c | 45 + 1 files changed, 45 insertions(+), 0 deletions(-) diff --git a/monitor.c b/monitor.c index 2a29095..a24a152 100644 --- a/monitor.c +++ b/monitor.c @@ -4163,6 +4163,46 @@ out: return err; } +/* + * Input object checking rules + * + * 1. "execute" key must exist (not checked here) + * 2. "execute" key must be a string + * 3. "arguments" key must be a dict + * 4. "id" key can be anything (ie. json-value) + * 5. Any argument not listed above is considered unexpected + */ +static int qmp_check_input_obj(const QDict *input_obj) +{ +const QDictEntry *ent; + +for (ent = qdict_first(input_obj); ent; ent = qdict_next(input_obj, ent)) { +const char *arg_name = qdict_entry_key(ent); +const QObject *arg_obj = qdict_entry_value(ent); + +if (!strcmp(arg_name, "execute")) { +if (qobject_type(arg_obj) != QTYPE_QSTRING) { +qerror_report(QERR_QMP_BAD_INPUT_OBJECT_MEMBER, "execute", + "string"); +return -1; +} +} else if (!strcmp(arg_name, "arguments")) { +if (qobject_type(arg_obj) != QTYPE_QDICT) { +qerror_report(QERR_QMP_BAD_INPUT_OBJECT_MEMBER, "arguments", + "object"); +return -1; +} +} else if (!strcmp(arg_name, "id")) { +/* FIXME: check duplicated IDs for async commands */ +} else { +qerror_report(QERR_QMP_UNEXPECTED_INPUT_OBJECT_MEMBER, arg_name); +return -1; +} +} + +return 0; +} + static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) { int err; @@ -4187,6 +4227,11 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) input = qobject_to_qdict(obj); +err = qmp_check_input_obj(input); +if (err < 0) { +goto err_input; +} + mon->mc->id = qdict_get(input, "id"); qobject_incref(mon->mc->id); -- 1.7.1.359.gd0b8d
[Qemu-devel] [PATCH 01/13] QDict: Rename 'err_value'
A missing key is not an error. Signed-off-by: Luiz Capitulino --- qdict.c |6 +++--- qdict.h |2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/qdict.c b/qdict.c index 175bc17..c974d6f 100644 --- a/qdict.c +++ b/qdict.c @@ -272,16 +272,16 @@ const char *qdict_get_str(const QDict *qdict, const char *key) * * Return integer mapped by 'key', if it is not present in * the dictionary or if the stored object is not of QInt type - * 'err_value' will be returned. + * 'def_value' will be returned. */ int64_t qdict_get_try_int(const QDict *qdict, const char *key, - int64_t err_value) + int64_t def_value) { QObject *obj; obj = qdict_get(qdict, key); if (!obj || qobject_type(obj) != QTYPE_QINT) -return err_value; +return def_value; return qint_get_int(qobject_to_qint(obj)); } diff --git a/qdict.h b/qdict.h index 5e5902c..72ea563 100644 --- a/qdict.h +++ b/qdict.h @@ -56,7 +56,7 @@ QList *qdict_get_qlist(const QDict *qdict, const char *key); QDict *qdict_get_qdict(const QDict *qdict, const char *key); const char *qdict_get_str(const QDict *qdict, const char *key); int64_t qdict_get_try_int(const QDict *qdict, const char *key, - int64_t err_value); + int64_t def_value); const char *qdict_get_try_str(const QDict *qdict, const char *key); #endif /* QDICT_H */ -- 1.7.1.359.gd0b8d
[Qemu-devel] [PATCH v2 00/13]: QMP: Replace client argument checker
Current QMP's client argument checker code is more complex than it should be and has a flaw: it ignores unknown arguments. This series solves both problems by introducing a new, simple and ultra-poweful argument checker. This wasn't trivial to get right due to the number of errors combinations, so review is very appreciated. changelog - v1 -> v2 - Introduce new iteration API and use it - Handle O-type correctly (I hope so) - Address several small issues found by Markus
[Qemu-devel] [PATCH 03/13] QDict: Introduce functions to retrieve QDictEntry values
Next commit will introduce a new QDict iteration API which returns QDictEntry entries, but we don't want users to directly access its members since QDictEntry should be private to QDict. In the near future this kind of data type will be turned into a forward reference. Signed-off-by: Luiz Capitulino --- qdict.c | 21 + qdict.h |2 ++ 2 files changed, 23 insertions(+), 0 deletions(-) diff --git a/qdict.c b/qdict.c index 71be2eb..c467763 100644 --- a/qdict.c +++ b/qdict.c @@ -83,6 +83,27 @@ static QDictEntry *alloc_entry(const char *key, QObject *value) } /** + * qdict_entry_value(): Return qdict entry value + * + * Return weak reference. + */ +QObject *qdict_entry_value(const QDictEntry *entry) +{ +return entry->value; +} + +/** + * qdict_entry_key(): Return qdict entry key + * + * Return a *pointer* to the string, it has to be duplicated before being + * stored. + */ +const char *qdict_entry_key(const QDictEntry *entry) +{ +return entry->key; +} + +/** * qdict_find(): List lookup function */ static QDictEntry *qdict_find(const QDict *qdict, diff --git a/qdict.h b/qdict.h index dcd2b29..0c8de3c 100644 --- a/qdict.h +++ b/qdict.h @@ -34,6 +34,8 @@ typedef struct QDict { /* Object API */ QDict *qdict_new(void); +const char *qdict_entry_key(const QDictEntry *entry); +QObject *qdict_entry_value(const QDictEntry *entry); size_t qdict_size(const QDict *qdict); void qdict_put_obj(QDict *qdict, const char *key, QObject *value); void qdict_del(QDict *qdict, const char *key); -- 1.7.1.359.gd0b8d
[Qemu-devel] [Bug 597362] [NEW] qemu-system-sparc singlestep not work in gdbstub
Public bug reported: Debugging with gdb-stub does not work with qemu-system-sparc target Qemu compiled from current git tree. execution string: qemu-system-sparc.exe -s -S -m 256 -L Bios -hda sparc.img -boot c connect with telnet localhost 1234 enter '$s#73' (without quotes, this is single step command to gdb stub) gdb stub reply '+' (without quotes, as it accept command) After this qemu continuously execute instructions in single step mode and does not exit to gdb stub after each executed instruction with interrupt signal ("T%02xthread:%02x;" /gdb_vm_state_change in gdbstub.c/ ); If we look at target-sparc/translate.c, we can see that gen_helper_debug() is not called in single step mode: if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) && (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) && !s->singlestep) { /* jump to same page: we can use a direct jump */ tcg_gen_goto_tb(tb_num); tcg_gen_movi_tl(cpu_pc, pc); tcg_gen_movi_tl(cpu_npc, npc); tcg_gen_exit_tb((long)tb + tb_num); } else { /* jump to another page: currently not optimized */ tcg_gen_movi_tl(cpu_pc, pc); tcg_gen_movi_tl(cpu_npc, npc); tcg_gen_exit_tb(0); } = /* if single step mode, we generate only one instruction and generate an exception */ if (dc->singlestep) { break; } If we look similar code at target-sh4/translate.c we can see that is called in this cases: if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) && !ctx->singlestep_enabled) { /* Use a direct jump if in same page and singlestep not enabled */ tcg_gen_goto_tb(n); tcg_gen_movi_i32(cpu_pc, dest); tcg_gen_exit_tb((long) tb + n); } else { tcg_gen_movi_i32(cpu_pc, dest); if (ctx->singlestep_enabled) gen_helper_debug(); tcg_gen_exit_tb(0); } if (tb->cflags & CF_LAST_IO) gen_io_end(); if (env->singlestep_enabled) { tcg_gen_movi_i32(cpu_pc, ctx.pc); gen_helper_debug(); } else { == ** Affects: qemu Importance: Undecided Status: New -- qemu-system-sparc singlestep not work in gdbstub https://bugs.launchpad.net/bugs/597362 You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. Status in QEMU: New Bug description: Debugging with gdb-stub does not work with qemu-system-sparc target Qemu compiled from current git tree. execution string: qemu-system-sparc.exe -s -S -m 256 -L Bios -hda sparc.img -boot c connect with telnet localhost 1234 enter '$s#73' (without quotes, this is single step command to gdb stub) gdb stub reply '+' (without quotes, as it accept command) After this qemu continuously execute instructions in single step mode and does not exit to gdb stub after each executed instruction with interrupt signal ("T%02xthread:%02x;" /gdb_vm_state_change in gdbstub.c/ ); If we look at target-sparc/translate.c, we can see that gen_helper_debug() is not called in single step mode: if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) && (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) && !s->singlestep) { /* jump to same page: we can use a direct jump */ tcg_gen_goto_tb(tb_num); tcg_gen_movi_tl(cpu_pc, pc); tcg_gen_movi_tl(cpu_npc, npc); tcg_gen_exit_tb((long)tb + tb_num); } else { /* jump to another page: currently not optimized */ tcg_gen_movi_tl(cpu_pc, pc); tcg_gen_movi_tl(cpu_npc, npc); tcg_gen_exit_tb(0); } = /* if single step mode, we generate only one instruction and generate an exception */ if (dc->singlestep) { break; } If we look similar code at target-sh4/translate.c we can see that is called in this cases: if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) && !ctx->singlestep_enabled) { /* Use a direct jump if in same page and singlestep not enabled */ tcg_gen_goto_tb(n); tcg_gen_movi_i32(cpu_pc, dest); tcg_gen_exit_tb((long) tb + n); } else { tcg_gen_movi_i32(cpu_pc, dest); if (ctx->singlestep_enabled) gen_helper_debug(); tcg_gen_exit_tb(0); } if (tb->cflags & CF_LAST_IO) gen_io_end(); if (env->singlestep_enabled) { tcg_gen_movi_i32(cpu_pc, ctx.pc); gen_helper_debug(); } else { ==
Re: [Qemu-devel] Re: block: format vs. protocol, and how they stack
On Tue, Jun 22, 2010 at 05:40:02PM +0100, Jamie Lokier wrote: > Kevin Wolf wrote: > > > The "protocol" parlance breaks down when we move away from the simple > > > stuff. For instance, qcow2 needs two children: the block driver > > > providing the delta bits (in qcow2 format), and the block driver > > > providing the base bits (whose configuration happens to be stored in the > > > delta bits). > > > > Backing files are different. When talking about opening images (which is > > what we do here) the main difference is that they can be opened only > > after the image itself has been opened. I don't think we should include > > them in this discussion. > > Imho, being unable to override the qcow2 backing file from the command > line / monitor is very annoying, if you've moved files from another > machine or just renamed them for tidiness. It's especially bad if the > supplied qcow2 file has an absolute path in it, quite bad if it has > subdirectories or ".." components, annoying if you've been given > several qcow2 files all of which have the name "backing-file" stored > in them which are different images because they were originally on > different machines, and awful if it has the name of a block device in it. FYI, in the scenario where you've moved backing files around, you can use qemu-img to update the location qemu-img rebase -u -b /path/to/newbackingfile.img demo.img Regards, Daniel -- |: Red Hat, Engineering, London-o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :| |: http://autobuild.org-o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
[Qemu-devel] [Bug 597351] [NEW] Slow UDP performance with virtio device
Public bug reported: I'm working on an app that is very sensitive to round-trip latency between the guest and host, and qemu/kvm seems to be significantly slower than it needs to be. The attached program is a ping/pong over UDP. Call it with a single argument to start a listener/echo server on that port. With three arguments it becomes a counted "pinger" that will exit after a specified number of round trips for performance measurements. For example: $ gcc -o udp-pong udp-pong.c $ ./udp-pong 12345 & # start a listener on port 12345 $ time ./udp-pong 127.0.0.1 12345 100 # time a million round trips When run on the loopback device on a single machine (true on the host or within a guest), I get about 100k/s. When run across a port forward using "user" networking on qemu (or kvm, the performance is the same) and the default rtl8139 driver (both the host and guest are Ubuntu Lucid), I get about 10k/s. This seems very slow, but perhaps unavoidably so? When run in the same configuration using the "virtio" driver, I get only 2k/s. This is almost certainly a bug in the virtio driver, given that it's a paravirtualized device that is 5x slower than the "slow" hardware emulation. I get no meaningful change in performance between kvm/qemu. ** Affects: qemu Importance: Undecided Status: New -- Slow UDP performance with virtio device https://bugs.launchpad.net/bugs/597351 You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. Status in QEMU: New Bug description: I'm working on an app that is very sensitive to round-trip latency between the guest and host, and qemu/kvm seems to be significantly slower than it needs to be. The attached program is a ping/pong over UDP. Call it with a single argument to start a listener/echo server on that port. With three arguments it becomes a counted "pinger" that will exit after a specified number of round trips for performance measurements. For example: $ gcc -o udp-pong udp-pong.c $ ./udp-pong 12345 & # start a listener on port 12345 $ time ./udp-pong 127.0.0.1 12345 100 # time a million round trips When run on the loopback device on a single machine (true on the host or within a guest), I get about 100k/s. When run across a port forward using "user" networking on qemu (or kvm, the performance is the same) and the default rtl8139 driver (both the host and guest are Ubuntu Lucid), I get about 10k/s. This seems very slow, but perhaps unavoidably so? When run in the same configuration using the "virtio" driver, I get only 2k/s. This is almost certainly a bug in the virtio driver, given that it's a paravirtualized device that is 5x slower than the "slow" hardware emulation. I get no meaningful change in performance between kvm/qemu.
[Qemu-devel] [Bug 597351] Re: Slow UDP performance with virtio device
** Attachment added: "udp-pong.c" http://launchpadlibrarian.net/50751155/udp-pong.c -- Slow UDP performance with virtio device https://bugs.launchpad.net/bugs/597351 You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. Status in QEMU: New Bug description: I'm working on an app that is very sensitive to round-trip latency between the guest and host, and qemu/kvm seems to be significantly slower than it needs to be. The attached program is a ping/pong over UDP. Call it with a single argument to start a listener/echo server on that port. With three arguments it becomes a counted "pinger" that will exit after a specified number of round trips for performance measurements. For example: $ gcc -o udp-pong udp-pong.c $ ./udp-pong 12345 & # start a listener on port 12345 $ time ./udp-pong 127.0.0.1 12345 100 # time a million round trips When run on the loopback device on a single machine (true on the host or within a guest), I get about 100k/s. When run across a port forward using "user" networking on qemu (or kvm, the performance is the same) and the default rtl8139 driver (both the host and guest are Ubuntu Lucid), I get about 10k/s. This seems very slow, but perhaps unavoidably so? When run in the same configuration using the "virtio" driver, I get only 2k/s. This is almost certainly a bug in the virtio driver, given that it's a paravirtualized device that is 5x slower than the "slow" hardware emulation. I get no meaningful change in performance between kvm/qemu.
Re: [Qemu-devel] Re: block: format vs. protocol, and how they stack
Markus Armbruster wrote: > A possible reason why we currently expose format and protocol at the > user interface is to avoid stacking there. Pragmatic solution?: A few generic flags in each stacking module ("format/protocol/transport"), which govern which other modules are allowed to stack on top or underneath. For example, vvfat may provide a blockdev-like abstraction, along with flags STACK_ABOVE_ONLY_RAW | STACK_BELOW_ONLY_DIRECTORY, which means "raw" and "blkdebug" are allowed above (of course ;-) but other things like the image formats shouldn't be. And below, it can't stack on a blockdev-like abstraction, but needs a directory and uses filesystem operations on it - the thing that Plan9fs needs. Btw, I think we expose "format" because "virtual disk image file format" is a useful and meaningful concept to users. When someone needs to use a .VMDK file, they know it as a "VMDK format file", not "I must use the VMDK protocol with this file". -- Jamie
Re: [Qemu-devel] Re: block: format vs. protocol, and how they stack
Kevin Wolf wrote: > > The "protocol" parlance breaks down when we move away from the simple > > stuff. For instance, qcow2 needs two children: the block driver > > providing the delta bits (in qcow2 format), and the block driver > > providing the base bits (whose configuration happens to be stored in the > > delta bits). > > Backing files are different. When talking about opening images (which is > what we do here) the main difference is that they can be opened only > after the image itself has been opened. I don't think we should include > them in this discussion. Imho, being unable to override the qcow2 backing file from the command line / monitor is very annoying, if you've moved files from another machine or just renamed them for tidiness. It's especially bad if the supplied qcow2 file has an absolute path in it, quite bad if it has subdirectories or ".." components, annoying if you've been given several qcow2 files all of which have the name "backing-file" stored in them which are different images because they were originally on different machines, and awful if it has the name of a block device in it. So, imho, for the discussion of command line / QMP options, there should be reserved a place for giving the name of the backing file through command line/monitor/QMP, along with the backing file's formats/protocols/transports/options, and so on recursively in a tree structure of arbitrary depth. There is also the matter of qcow2 files encoding the path, but not necessarily all the blockdev options that you might want to use to access the backing file, such as cache=. In QMP it's obviously quite simple to accept a full child blockdev specification object as a qcow2-specific parameter, thus not needing any further discussion in this thread. It's less obvious how to do it on the command line or human monitor. -- Jamie
Re: [Qemu-devel] Re: block: format vs. protocol, and how they stack
Christoph Hellwig wrote: > On Mon, Jun 21, 2010 at 09:51:23AM -0500, Anthony Liguori wrote: > > I can appreciate the desire to keep protocols and formats as an internal > > distinction but as a user visible concept, I think your two examples > > highlight why exposing protocols as formats make sense. A user doesn't > > necessarily care what's happening under the cover. I think: > > > > -blockdev format=qcow2,file=image.qcow2,id=blk1 > > > > and: > > > > -blockdev protocol=vvfat,file=/tmp/dir,id=blk1 > > > > Would cause a bit of confusion. It's not immediately clear why vvfat is > > a protocol and qcow2 isn't. It's really an implementation detail that > > we implement qcow2 on top of a "protocol" called file. > > Everything involving vvfat will end up in sheer confusion, and that's > because vvfat is such a beast. But it's a rather traditional example > of a "protocol". Unlike qcow2 / vmdk / vpc it can not be stacked on > an arbitrary protocol (file/nbd/http), but rather accessed a directory > tree. There is no technical reason why vvfat couldn't be stacked on top of FTP or HTTP-DAV or RSYNC or SCP, or even "wget -R". Basically anything with multiple files addressed by paths, and a way to retrieve directories to find all the paths. vvfat doesn't stack on top of "file-like protocols", it stacks conceptually on top of "directory tree-like protocols", of which there is currently one. The arrival of Plan9fs may motivate the addition of more. You can't meaningfully stack "qcow2" or any other format than "raw" on top of the virtual file image created by vvfat. So that's another reason it isn't the same as other "protocols". -- Jamie
[Qemu-devel] [PATCH] qcow2: Fix error handling during metadata preallocation
People were wondering why qemu-img check failed after they tried to preallocate a large qcow2 file and ran out of disk space. Signed-off-by: Kevin Wolf --- block/qcow2.c | 15 +-- 1 files changed, 9 insertions(+), 6 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index d29e6b6..9ee34b6 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -805,14 +805,14 @@ static int preallocate(BlockDriverState *bs) while (nb_sectors) { num = MIN(nb_sectors, INT_MAX >> 9); ret = qcow2_alloc_cluster_offset(bs, offset, 0, num, &num, &meta); - if (ret < 0) { -return -1; +return ret; } -if (qcow2_alloc_cluster_link_l2(bs, &meta) < 0) { +ret = qcow2_alloc_cluster_link_l2(bs, &meta); +if (ret < 0) { qcow2_free_any_clusters(bs, meta.cluster_offset, meta.nb_clusters); -return -1; +return ret; } /* There are no dependent requests, but we need to remove our request @@ -833,7 +833,10 @@ static int preallocate(BlockDriverState *bs) if (meta.cluster_offset != 0) { uint8_t buf[512]; memset(buf, 0, 512); -bdrv_write(bs->file, (meta.cluster_offset >> 9) + num - 1, buf, 1); +ret = bdrv_write(bs->file, (meta.cluster_offset >> 9) + num - 1, buf, 1); +if (ret < 0) { +return ret; +} } return 0; @@ -1030,7 +1033,7 @@ exit: BlockDriver *drv = bdrv_find_format("qcow2"); bs = bdrv_new(""); bdrv_open(bs, filename, BDRV_O_CACHE_WB | BDRV_O_RDWR, drv); -preallocate(bs); +ret = preallocate(bs); bdrv_close(bs); } -- 1.6.6.1
[Qemu-devel] Re: KVM call agenda for June 22
On 06/22/2010 09:10 AM, Juan Quintela wrote: Alexander Graf wrote: Alex Williamson wrote: On Tue, 2010-06-22 at 07:49 -0500, Anthony Liguori wrote: On 06/22/2010 07:04 AM, Juan Quintela wrote: Chris Wright wrote: Please send in any agenda items you are interested in covering. If we have a lack of agenda items I'll cancel the week's call. As we have no agenda. This week call gets cancelled. Could we send the agenda note out a little bit earlier? The note arrived at 12:55am CST and we decided we had no agenda at 7:04am CST. That's a pretty short window and I imagine a lot of people in the US are not actually awake during that period of time :-) Indeed, open at midnight, closed at 6am here. If anyone is still interested, I'd like to talk about canonical device paths (vmstate/ramblock naming). In fact, the only times the call was canceled right after it started was when Anthony was on vacation. I think the canceling rule doesn't make sense when he's around. Oops. I was asked to run meeting or cancel it if nobody sent anything to the agenda. I didn't look at the time that the agenda was sent, sorry. And I think we canceled the meeting 2-3 weeks ago, no? I think for the past month or so, whether the meeting gets cancelled is based on a race condition between me finishing my first cup of coffee and you sending out the cancellation note ;-) Regards, Anthony Liguori Later, Juan.
[Qemu-devel] Re: RFC qdev path semantics
On 06/16/2010 04:46 AM, Markus Armbruster wrote: A number of changes to qdev paths have been proposed in various threads. It's becoming harder to keep track of them, so let me sum them up in one place. Please correct me if I misrepresent your ideas. Honestly, I think we've gone off the deep end here. Let's simplify. We need to uniquely identify ram allocations for the purposes of savevm. Let's do this: qdev has a vmsd property. When the qdev device is initialized, it invokes vmstate_register_with_alias_id. Let's have vmstate_register_with_alias_id return a unique identifier. Today, it should be derived from the section header. In the future, it should be a qdev path (as should the section header). We need have a qdev->vmsd_base. pci_add_option_rom() will pass qdev->vmsd_base + a unique suffix to qemu_ram_alloc() which should be in the form '/suffix'. This suffix only need to identify the ram area uniquely for for pci_add_option_rom, it should probably be '/PCI-ROM'. Today, this means that the ram allocations will be consistent with VMState which is a good thing on the wire. In the future, when we have full qdev conversion, we can easily switch to using qdev paths as the vmsd_base with almost no code change. Regards, Anthony Liguori
Re: [Qemu-devel] Re: block: format vs. protocol, and how they stack
Kevin Wolf writes: > Am 21.06.2010 18:21, schrieb Markus Armbruster: >> Christoph Hellwig writes: >> [...] >>> The user basically can specify two things: >>> >>> - a transport protocol. Normally this is just the filesystem >>>interface, but it can also be nbd, http or for really sick people >>>vvfat. This is a setting which can't be guessed, btw - it needs >>>to be explicitly set in some way, with file used as a reasonable >>>fallback. >>> >>> - an image format. This one interprets the content the transport >>>protocol delivers to us. This can either be raw for not interpreting >>>it all, or things like qcow2 / vmdk to add more functionality to it. >> >> You describe the special case where format and protocol make some sense: >> you have a block driver that can transport bits in arbitrary formats, >> and a block driver that interprets bits without caring for transport. > > No, that's not a special case. It's the only case there is. > >> In the general case, we have things like vvfat that make people wonder >> whether it's a format or a protocol. You can't stack it onto a >> transport, so it can't be a format! You can't stack a format on it, so >> it can't be a protocol! > > Sure you can stack formats on it. raw and blkdebug are the ones that > will be happy with the data that vvfat provides. You can stack raw and blkdebug on *anything*. And that includes qcow2. Does that make qcow2 a protocol? Are we running in circles yet? :) I've come the conclusion that distinguishing between format and protocol doesn't help. It only breeds confusion (and e-mail, lots of e-mail). I've rethought blockdev_add, and I think I can do quite well without format and protocol. Let me try that in practice. I'll post revised docs & code when I have them.
[Qemu-devel] Re: KVM call agenda for June 22
Anthony Liguori wrote: > On 06/22/2010 09:10 AM, Juan Quintela wrote: > I think for the past month or so, whether the meeting gets cancelled > is based on a race condition between me finishing my first cup of > coffee and you sending out the cancellation note ;-) This is my 1st cancellation note, so ... But from there on, I will talk with Chris about sending it on his Sunday night or my Monday morning (i.e. 24h before the decission to cancel (or not)) the call. Sorry for the inconvenience, Juan. > Regards, > > Anthony Liguori > >> Later, Juan. >>
[Qemu-devel] Re: KVM call agenda for June 22
Alexander Graf wrote: > Alex Williamson wrote: >> On Tue, 2010-06-22 at 07:49 -0500, Anthony Liguori wrote: >> >>> On 06/22/2010 07:04 AM, Juan Quintela wrote: >>> Chris Wright wrote: > Please send in any agenda items you are interested in covering. > > If we have a lack of agenda items I'll cancel the week's call. > > As we have no agenda. This week call gets cancelled. >>> Could we send the agenda note out a little bit earlier? >>> >>> The note arrived at 12:55am CST and we decided we had no agenda at >>> 7:04am CST. That's a pretty short window and I imagine a lot of people >>> in the US are not actually awake during that period of time :-) >>> >> >> Indeed, open at midnight, closed at 6am here. If anyone is still >> interested, I'd like to talk about canonical device paths >> (vmstate/ramblock naming). >> > > In fact, the only times the call was canceled right after it started was > when Anthony was on vacation. I think the canceling rule doesn't make > sense when he's around. Oops. I was asked to run meeting or cancel it if nobody sent anything to the agenda. I didn't look at the time that the agenda was sent, sorry. And I think we canceled the meeting 2-3 weeks ago, no? Later, Juan.
[Qemu-devel] [PATCH 08/14] qcow2: Use bdrv_(p)write_sync for metadata writes
Use bdrv_(p)write_sync to ensure metadata integrity in case of a crash. Signed-off-by: Kevin Wolf --- block/qcow2-cluster.c | 24 block/qcow2-refcount.c | 24 block/qcow2-snapshot.c | 23 +++ block/qcow2.c | 10 +- 4 files changed, 40 insertions(+), 41 deletions(-) diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index 5760ad6..166922f 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -64,8 +64,8 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size) BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_WRITE_TABLE); for(i = 0; i < s->l1_size; i++) new_l1_table[i] = cpu_to_be64(new_l1_table[i]); -ret = bdrv_pwrite(bs->file, new_l1_table_offset, new_l1_table, new_l1_size2); -if (ret != new_l1_size2) +ret = bdrv_pwrite_sync(bs->file, new_l1_table_offset, new_l1_table, new_l1_size2); +if (ret < 0) goto fail; for(i = 0; i < s->l1_size; i++) new_l1_table[i] = be64_to_cpu(new_l1_table[i]); @@ -74,8 +74,8 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size) BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_ACTIVATE_TABLE); cpu_to_be32w((uint32_t*)data, new_l1_size); cpu_to_be64w((uint64_t*)(data + 4), new_l1_table_offset); -ret = bdrv_pwrite(bs->file, offsetof(QCowHeader, l1_size), data,sizeof(data)); -if (ret != sizeof(data)) { +ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, l1_size), data,sizeof(data)); +if (ret < 0) { goto fail; } qemu_free(s->l1_table); @@ -87,7 +87,7 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size) fail: qemu_free(new_l1_table); qcow2_free_clusters(bs, new_l1_table_offset, new_l1_size2); -return ret < 0 ? ret : -EIO; +return ret; } void qcow2_l2_cache_reset(BlockDriverState *bs) @@ -207,7 +207,7 @@ static int write_l1_entry(BlockDriverState *bs, int l1_index) } BLKDBG_EVENT(bs->file, BLKDBG_L1_UPDATE); -ret = bdrv_pwrite(bs->file, s->l1_table_offset + 8 * l1_start_index, +ret = bdrv_pwrite_sync(bs->file, s->l1_table_offset + 8 * l1_start_index, buf, sizeof(buf)); if (ret < 0) { return ret; @@ -263,7 +263,7 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table) } /* write the l2 table to the file */ BLKDBG_EVENT(bs->file, BLKDBG_L2_ALLOC_WRITE); -ret = bdrv_pwrite(bs->file, l2_offset, l2_table, +ret = bdrv_pwrite_sync(bs->file, l2_offset, l2_table, s->l2_size * sizeof(uint64_t)); if (ret < 0) { goto fail; @@ -413,8 +413,8 @@ static int copy_sectors(BlockDriverState *bs, uint64_t start_sect, &s->aes_encrypt_key); } BLKDBG_EVENT(bs->file, BLKDBG_COW_WRITE); -ret = bdrv_write(bs->file, (cluster_offset >> 9) + n_start, - s->cluster_data, n); +ret = bdrv_write_sync(bs->file, (cluster_offset >> 9) + n_start, +s->cluster_data, n); if (ret < 0) return ret; return 0; @@ -631,10 +631,10 @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs, BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE_COMPRESSED); l2_table[l2_index] = cpu_to_be64(cluster_offset); -if (bdrv_pwrite(bs->file, +if (bdrv_pwrite_sync(bs->file, l2_offset + l2_index * sizeof(uint64_t), l2_table + l2_index, -sizeof(uint64_t)) != sizeof(uint64_t)) +sizeof(uint64_t)) < 0) return 0; return cluster_offset; @@ -655,7 +655,7 @@ static int write_l2_entries(BlockDriverState *bs, uint64_t *l2_table, int ret; BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE); -ret = bdrv_pwrite(bs->file, l2_offset + start_offset, +ret = bdrv_pwrite_sync(bs->file, l2_offset + start_offset, &l2_table[l2_start_index], len); if (ret < 0) { return ret; diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index 41e1da9..c2d0e61 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -44,8 +44,8 @@ static int write_refcount_block(BlockDriverState *bs) } BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_UPDATE); -if (bdrv_pwrite(bs->file, s->refcount_block_cache_offset, -s->refcount_block_cache, size) != size) +if (bdrv_pwrite_sync(bs->file, s->refcount_block_cache_offset, +s->refcount_block_cache, size) < 0) { return -EIO; } @@ -269,7 +269,7 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index) /* Now the new refcount block needs to be written to disk */ BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE); -ret = bdrv_pwrite(bs->file, new_block, s->refcount_block_cache, +ret = bdrv_pwrite_sync(bs->file, new_block, s->refcount_block_cache, s->cluster_size); if (ret < 0) { goto fail_block; @@ -279,7 +27
[Qemu-devel] [PATCH 14/14] qcow2: Don't try to check tables that couldn't be loaded
Trying to check them leads to a second error message which is more confusing than helpful: Can't get refcount for cluster 0: Invalid argument ERROR cluster 0 refcount=-22 reference=1 Signed-off-by: Kevin Wolf --- block/qcow2-refcount.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index cedf57e..4a96d98 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -1174,6 +1174,7 @@ int qcow2_check_refcounts(BlockDriverState *bs) if (refcount1 < 0) { fprintf(stderr, "Can't get refcount for cluster %d: %s\n", i, strerror(-refcount1)); +continue; } refcount2 = refcount_table[i]; -- 1.6.6.1
[Qemu-devel] [PATCH 11/14] qemu-io: check registered fds in command_loop()
From: MORITA Kazutaka Some block drivers use an aio handler and do I/O completion routines in it. However, the handler is not invoked if we only do aio_read/write, because registered fds are not checked at all. This patch registers an aio handler of STDIO to checks whether we can read a command without blocking, and calls qemu_aio_wait() in command_loop(). Any other handlers can be invoked when user input is idle. Signed-off-by: MORITA Kazutaka Signed-off-by: Kevin Wolf --- cmd.c | 33 ++--- 1 files changed, 30 insertions(+), 3 deletions(-) diff --git a/cmd.c b/cmd.c index 2336334..db2c9c4 100644 --- a/cmd.c +++ b/cmd.c @@ -24,6 +24,7 @@ #include #include "cmd.h" +#include "qemu-aio.h" #define _(x) x /* not gettext support yet */ @@ -149,10 +150,20 @@ add_args_command( args_func = af; } +static void prep_fetchline(void *opaque) +{ +int *fetchable = opaque; + +qemu_aio_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL, NULL, NULL); +*fetchable= 1; +} + +static char *get_prompt(void); + void command_loop(void) { - int c, i, j = 0, done = 0; + int c, i, j = 0, done = 0, fetchable = 0, prompted = 0; char*input; char**v; const cmdinfo_t *ct; @@ -186,7 +197,21 @@ command_loop(void) free(cmdline); return; } + while (!done) { +if (!prompted) { +printf("%s", get_prompt()); +fflush(stdout); +qemu_aio_set_fd_handler(STDIN_FILENO, prep_fetchline, NULL, NULL, +NULL, &fetchable); +prompted = 1; +} + +qemu_aio_wait(); + +if (!fetchable) { +continue; +} if ((input = fetchline()) == NULL) break; v = breakline(input, &c); @@ -199,7 +224,11 @@ command_loop(void) v[0]); } doneline(input, v); + +prompted = 0; +fetchable = 0; } +qemu_aio_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL, NULL, NULL); } /* from libxcmd/input.c */ @@ -270,8 +299,6 @@ fetchline(void) if (!line) return NULL; - printf("%s", get_prompt()); - fflush(stdout); if (!fgets(line, MAXREADLINESZ, stdin)) { free(line); return NULL; -- 1.6.6.1
[Qemu-devel] [PATCH 10/14] vpc: Use bdrv_(p)write_sync for metadata writes
Use bdrv_(p)write_sync to ensure metadata integrity in case of a crash. Signed-off-by: Kevin Wolf --- block/vpc.c |9 + 1 files changed, 5 insertions(+), 4 deletions(-) diff --git a/block/vpc.c b/block/vpc.c index f1f73e2..e50509e 100644 --- a/block/vpc.c +++ b/block/vpc.c @@ -261,7 +261,7 @@ static inline int64_t get_sector_offset(BlockDriverState *bs, s->last_bitmap_offset = bitmap_offset; memset(bitmap, 0xff, s->bitmap_size); -bdrv_pwrite(bs->file, bitmap_offset, bitmap, s->bitmap_size); +bdrv_pwrite_sync(bs->file, bitmap_offset, bitmap, s->bitmap_size); } //printf("sector: %" PRIx64 ", index: %x, offset: %x, bioff: %" PRIx64 ", bloff: %" PRIx64 "\n", @@ -311,7 +311,7 @@ static int rewrite_footer(BlockDriverState* bs) BDRVVPCState *s = bs->opaque; int64_t offset = s->free_data_block_offset; -ret = bdrv_pwrite(bs->file, offset, s->footer_buf, HEADER_SIZE); +ret = bdrv_pwrite_sync(bs->file, offset, s->footer_buf, HEADER_SIZE); if (ret < 0) return ret; @@ -346,7 +346,8 @@ static int64_t alloc_block(BlockDriverState* bs, int64_t sector_num) // Initialize the block's bitmap memset(bitmap, 0xff, s->bitmap_size); -bdrv_pwrite(bs->file, s->free_data_block_offset, bitmap, s->bitmap_size); +bdrv_pwrite_sync(bs->file, s->free_data_block_offset, bitmap, +s->bitmap_size); // Write new footer (the old one will be overwritten) s->free_data_block_offset += s->block_size + s->bitmap_size; @@ -357,7 +358,7 @@ static int64_t alloc_block(BlockDriverState* bs, int64_t sector_num) // Write BAT entry to disk bat_offset = s->bat_offset + (4 * index); bat_value = be32_to_cpu(s->pagetable[index]); -ret = bdrv_pwrite(bs->file, bat_offset, &bat_value, 4); +ret = bdrv_pwrite_sync(bs->file, bat_offset, &bat_value, 4); if (ret < 0) goto fail; -- 1.6.6.1
[Qemu-devel] [PATCH 07/14] qcow: Use bdrv_(p)write_sync for metadata writes
Use bdrv_(p)write_sync to ensure metadata integrity in case of a crash. Signed-off-by: Kevin Wolf --- block/qcow.c | 18 ++ 1 files changed, 10 insertions(+), 8 deletions(-) diff --git a/block/qcow.c b/block/qcow.c index 449858f..816103d 100644 --- a/block/qcow.c +++ b/block/qcow.c @@ -273,8 +273,9 @@ static uint64_t get_cluster_offset(BlockDriverState *bs, /* update the L1 entry */ s->l1_table[l1_index] = l2_offset; tmp = cpu_to_be64(l2_offset); -if (bdrv_pwrite(bs->file, s->l1_table_offset + l1_index * sizeof(tmp), -&tmp, sizeof(tmp)) != sizeof(tmp)) +if (bdrv_pwrite_sync(bs->file, +s->l1_table_offset + l1_index * sizeof(tmp), +&tmp, sizeof(tmp)) < 0) return 0; new_l2_table = 1; } @@ -302,8 +303,8 @@ static uint64_t get_cluster_offset(BlockDriverState *bs, l2_table = s->l2_cache + (min_index << s->l2_bits); if (new_l2_table) { memset(l2_table, 0, s->l2_size * sizeof(uint64_t)); -if (bdrv_pwrite(bs->file, l2_offset, l2_table, s->l2_size * sizeof(uint64_t)) != -s->l2_size * sizeof(uint64_t)) +if (bdrv_pwrite_sync(bs->file, l2_offset, l2_table, +s->l2_size * sizeof(uint64_t)) < 0) return 0; } else { if (bdrv_pread(bs->file, l2_offset, l2_table, s->l2_size * sizeof(uint64_t)) != @@ -368,8 +369,8 @@ static uint64_t get_cluster_offset(BlockDriverState *bs, /* update L2 table */ tmp = cpu_to_be64(cluster_offset); l2_table[l2_index] = tmp; -if (bdrv_pwrite(bs->file, -l2_offset + l2_index * sizeof(tmp), &tmp, sizeof(tmp)) != sizeof(tmp)) +if (bdrv_pwrite_sync(bs->file, l2_offset + l2_index * sizeof(tmp), +&tmp, sizeof(tmp)) < 0) return 0; } return cluster_offset; @@ -835,8 +836,9 @@ static int qcow_make_empty(BlockDriverState *bs) int ret; memset(s->l1_table, 0, l1_length); -if (bdrv_pwrite(bs->file, s->l1_table_offset, s->l1_table, l1_length) < 0) - return -1; +if (bdrv_pwrite_sync(bs->file, s->l1_table_offset, s->l1_table, +l1_length) < 0) +return -1; ret = bdrv_truncate(bs->file, s->l1_table_offset + l1_length); if (ret < 0) return ret; -- 1.6.6.1
[Qemu-devel] [PATCH 06/14] cow: Use bdrv_(p)write_sync for metadata writes
Use bdrv_(p)write_sync to ensure metadata integrity in case of a crash. While at it, correct the wrong usage of errno. Signed-off-by: Kevin Wolf --- block/cow.c | 20 +++- 1 files changed, 11 insertions(+), 9 deletions(-) diff --git a/block/cow.c b/block/cow.c index d146434..eedcc48 100644 --- a/block/cow.c +++ b/block/cow.c @@ -97,17 +97,18 @@ static inline int cow_set_bit(BlockDriverState *bs, int64_t bitnum) { uint64_t offset = sizeof(struct cow_header_v2) + bitnum / 8; uint8_t bitmap; +int ret; -if (bdrv_pread(bs->file, offset, &bitmap, sizeof(bitmap)) != - sizeof(bitmap)) { - return -errno; +ret = bdrv_pread(bs->file, offset, &bitmap, sizeof(bitmap)); +if (ret < 0) { + return ret; } bitmap |= (1 << (bitnum % 8)); -if (bdrv_pwrite(bs->file, offset, &bitmap, sizeof(bitmap)) != - sizeof(bitmap)) { - return -errno; +ret = bdrv_pwrite_sync(bs->file, offset, &bitmap, sizeof(bitmap)); +if (ret < 0) { + return ret; } return 0; } @@ -116,10 +117,11 @@ static inline int is_bit_set(BlockDriverState *bs, int64_t bitnum) { uint64_t offset = sizeof(struct cow_header_v2) + bitnum / 8; uint8_t bitmap; +int ret; -if (bdrv_pread(bs->file, offset, &bitmap, sizeof(bitmap)) != - sizeof(bitmap)) { - return -errno; +ret = bdrv_pread(bs->file, offset, &bitmap, sizeof(bitmap)); +if (ret < 0) { + return ret; } return !!(bitmap & (1 << (bitnum % 8))); -- 1.6.6.1
[Qemu-devel] [PATCH 12/14] virtio-blk: fix the list operation in virtio_blk_load().
From: Yoshiaki Tamura Although it is really rare to get in to the while loop, the list operation in the loop is obviously wrong. Signed-off-by: Yoshiaki Tamura Signed-off-by: Kevin Wolf --- hw/virtio-blk.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c index 75878eb..0bf929a 100644 --- a/hw/virtio-blk.c +++ b/hw/virtio-blk.c @@ -470,7 +470,7 @@ static int virtio_blk_load(QEMUFile *f, void *opaque, int version_id) VirtIOBlockReq *req = virtio_blk_alloc_request(s); qemu_get_buffer(f, (unsigned char*)&req->elem, sizeof(req->elem)); req->next = s->rq; -s->rq = req->next; +s->rq = req; } return 0; -- 1.6.6.1
[Qemu-devel] [PATCH 04/14] monitor: allow device to be ejected if no disk is inserted
From: Eduardo Habkost This changes the monitor eject_device() function to not check for bdrv_is_inserted(). Example run where the bug manifests itself: (output of 'info block' is stripped to include only the CD-ROM device) (qemu) info block ide1-cd0: type=cdrom removable=1 locked=0 [not inserted] (qemu) change ide1-cd0 /dev/cdrom host_cdrom (qemu) info block ide1-cd0: type=cdrom removable=1 locked=0 file=/dev/cdrom ro=1 drv=host_cdrom encrypted=0 (qemu) eject ide1-cd0 (qemu) info block ide1-cd0: type=cdrom removable=1 locked=0 file=/dev/cdrom ro=1 drv=host_cdrom encrypted=0 # at this point, a disk was inserted on the host CD-ROM drive (qemu) info block ide1-cd0: type=cdrom removable=1 locked=0 file=/dev/cdrom ro=1 drv=host_cdrom encrypted=0 (qemu) eject ide1-cd0 (qemu) info block ide1-cd0: type=cdrom removable=1 locked=0 [not inserted] (qemu) The first eject command didn't work because the is_inserted() check failed. I have no clue why the code had the is_inserted() check, as it doesn't matter if there is a disk present at the host drive, when the user wants the virtual device to be disconnected from the host device. The is_inserted() check has another side effect: a memory leak if the "change" command is used multiple times, as do_change() calls eject_device() before re-opening the block device, but bdrv_close() is never called. Signed-off-by: Eduardo Habkost Signed-off-by: Kevin Wolf --- blockdev.c | 22 ++ 1 files changed, 10 insertions(+), 12 deletions(-) diff --git a/blockdev.c b/blockdev.c index b376884..3b8c606 100644 --- a/blockdev.c +++ b/blockdev.c @@ -503,20 +503,18 @@ void do_commit(Monitor *mon, const QDict *qdict) static int eject_device(Monitor *mon, BlockDriverState *bs, int force) { -if (bdrv_is_inserted(bs)) { -if (!force) { -if (!bdrv_is_removable(bs)) { -qerror_report(QERR_DEVICE_NOT_REMOVABLE, - bdrv_get_device_name(bs)); -return -1; -} -if (bdrv_is_locked(bs)) { -qerror_report(QERR_DEVICE_LOCKED, bdrv_get_device_name(bs)); -return -1; -} +if (!force) { +if (!bdrv_is_removable(bs)) { +qerror_report(QERR_DEVICE_NOT_REMOVABLE, + bdrv_get_device_name(bs)); +return -1; +} +if (bdrv_is_locked(bs)) { +qerror_report(QERR_DEVICE_LOCKED, bdrv_get_device_name(bs)); +return -1; } -bdrv_close(bs); } +bdrv_close(bs); return 0; } -- 1.6.6.1
[Qemu-devel] [PATCH 09/14] vmdk: Use bdrv_(p)write_sync for metadata writes
Use bdrv_(p)write_sync to ensure metadata integrity in case of a crash. Signed-off-by: Kevin Wolf --- block/vmdk.c | 10 +- 1 files changed, 5 insertions(+), 5 deletions(-) diff --git a/block/vmdk.c b/block/vmdk.c index e659908..2d4ba42 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -150,7 +150,7 @@ static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid) pstrcat(desc, sizeof(desc), tmp_desc); } -if (bdrv_pwrite(bs->file, 0x200, desc, DESC_SIZE) != DESC_SIZE) +if (bdrv_pwrite_sync(bs->file, 0x200, desc, DESC_SIZE) < 0) return -1; return 0; } @@ -471,14 +471,14 @@ static int vmdk_L2update(BlockDriverState *bs, VmdkMetaData *m_data) BDRVVmdkState *s = bs->opaque; /* update L2 table */ -if (bdrv_pwrite(bs->file, ((int64_t)m_data->l2_offset * 512) + (m_data->l2_index * sizeof(m_data->offset)), -&(m_data->offset), sizeof(m_data->offset)) != sizeof(m_data->offset)) +if (bdrv_pwrite_sync(bs->file, ((int64_t)m_data->l2_offset * 512) + (m_data->l2_index * sizeof(m_data->offset)), +&(m_data->offset), sizeof(m_data->offset)) < 0) return -1; /* update backup L2 table */ if (s->l1_backup_table_offset != 0) { m_data->l2_offset = s->l1_backup_table[m_data->l1_index]; -if (bdrv_pwrite(bs->file, ((int64_t)m_data->l2_offset * 512) + (m_data->l2_index * sizeof(m_data->offset)), -&(m_data->offset), sizeof(m_data->offset)) != sizeof(m_data->offset)) +if (bdrv_pwrite_sync(bs->file, ((int64_t)m_data->l2_offset * 512) + (m_data->l2_index * sizeof(m_data->offset)), +&(m_data->offset), sizeof(m_data->offset)) < 0) return -1; } -- 1.6.6.1
[Qemu-devel] [PULL 00/14] Block patches
The following changes since commit cada87c432e3b9cd55869a24055baf2b7bc0b70c: Blue Swirl (1): Update OpenBIOS images are available in the git repository at: git://repo.or.cz/qemu/kevin.git for-anthony Christoph Hellwig (1): block: fix physical_block_size calculation Eduardo Habkost (1): monitor: allow device to be ejected if no disk is inserted Kevin Wolf (8): block: Add bdrv_(p)write_sync cow: Use bdrv_(p)write_sync for metadata writes qcow: Use bdrv_(p)write_sync for metadata writes qcow2: Use bdrv_(p)write_sync for metadata writes vmdk: Use bdrv_(p)write_sync for metadata writes vpc: Use bdrv_(p)write_sync for metadata writes qcow2: Fix qemu-img check segfault on corrupted images qcow2: Don't try to check tables that couldn't be loaded MORITA Kazutaka (1): qemu-io: check registered fds in command_loop() Nicholas Bellinger (2): scsi-bus: Add PERSISTENT_RESERVE_OUT SCSIRequest->cmd.mode setup scsi-bus: Add MAINTENANCE_IN and MAINTENANCE_OUT SCSIRequest xfer and mode assignments Yoshiaki Tamura (1): virtio-blk: fix the list operation in virtio_blk_load(). block.c| 37 + block.h|4 block/cow.c| 20 +++- block/qcow.c | 18 ++ block/qcow2-cluster.c | 24 block/qcow2-refcount.c | 39 --- block/qcow2-snapshot.c | 23 +++ block/qcow2.c | 10 +- block/vmdk.c | 10 +- block/vpc.c|9 + block_int.h|4 +++- blockdev.c | 22 ++ cmd.c | 33 ++--- hw/scsi-bus.c | 11 +++ hw/scsi-defs.h |2 ++ hw/virtio-blk.c|2 +- 16 files changed, 181 insertions(+), 87 deletions(-)
[Qemu-devel] [PATCH 13/14] qcow2: Fix qemu-img check segfault on corrupted images
With corrupted images, we can easily get an cluster index that exceeds the array size of the temporary refcount table. Signed-off-by: Kevin Wolf --- block/qcow2-refcount.c | 14 +++--- 1 files changed, 11 insertions(+), 3 deletions(-) diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index c2d0e61..cedf57e 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -1140,22 +1140,30 @@ int qcow2_check_refcounts(BlockDriverState *bs) s->refcount_table_offset, s->refcount_table_size * sizeof(uint64_t)); for(i = 0; i < s->refcount_table_size; i++) { -int64_t offset; +uint64_t offset, cluster; offset = s->refcount_table[i]; +cluster = offset >> s->cluster_bits; /* Refcount blocks are cluster aligned */ if (offset & (s->cluster_size - 1)) { fprintf(stderr, "ERROR refcount block %d is not " "cluster aligned; refcount table entry corrupted\n", i); errors++; +continue; +} + +if (cluster >= nb_clusters) { +fprintf(stderr, "ERROR refcount block %d is outside image\n", i); +errors++; +continue; } if (offset != 0) { errors += inc_refcounts(bs, refcount_table, nb_clusters, offset, s->cluster_size); -if (refcount_table[offset / s->cluster_size] != 1) { +if (refcount_table[cluster] != 1) { fprintf(stderr, "ERROR refcount block %d refcount=%d\n", -i, refcount_table[offset / s->cluster_size]); +i, refcount_table[cluster]); } } } -- 1.6.6.1
[Qemu-devel] [PATCH 03/14] block: fix physical_block_size calculation
From: Christoph Hellwig Both SCSI and virtio expect the physical block size relative to the logical block size. So get the factor first before calculating the log2. Reported-by: Mike Cao Signed-off-by: Christoph Hellwig Signed-off-by: Kevin Wolf --- block_int.h |4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/block_int.h b/block_int.h index e3bfd19..b64a009 100644 --- a/block_int.h +++ b/block_int.h @@ -224,7 +224,9 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf) { unsigned int exp = 0, size; -for (size = conf->physical_block_size; size > 512; size >>= 1) { +for (size = conf->physical_block_size; +size > conf->logical_block_size; +size >>= 1) { exp++; } -- 1.6.6.1
[Qemu-devel] [PATCH 02/14] scsi-bus: Add MAINTENANCE_IN and MAINTENANCE_OUT SCSIRequest xfer and mode assignments
From: Nicholas Bellinger This patch updates hw/scsi-bus.c to add MAINTENANCE_IN and MAINTENANCE_OUT case in scsi_req_length() for TYPE_ROM with MMC commands. It also adds the MAINTENANCE_OUT case in scsi_req_xfer_mode() to set SCSI_XFER_TO_DEV for outgoing write data. Signed-off-by: Nicholas A. Bellinger Acked-by: Gerd Hoffmann Signed-off-by: Kevin Wolf --- hw/scsi-bus.c | 10 ++ hw/scsi-defs.h |2 ++ 2 files changed, 12 insertions(+), 0 deletions(-) diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index 3575ba3..24bd060 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -242,6 +242,13 @@ static int scsi_req_length(SCSIRequest *req, uint8_t *cmd) case INQUIRY: req->cmd.xfer = cmd[4] | (cmd[3] << 8); break; +case MAINTENANCE_OUT: +case MAINTENANCE_IN: +if (req->dev->type == TYPE_ROM) { +/* GPCMD_REPORT_KEY and GPCMD_SEND_KEY from multi media commands */ +req->cmd.xfer = cmd[9] | (cmd[8] << 8); +} +break; } return 0; } @@ -307,6 +314,7 @@ static void scsi_req_xfer_mode(SCSIRequest *req) case SEND_VOLUME_TAG: case WRITE_LONG_2: case PERSISTENT_RESERVE_OUT: +case MAINTENANCE_OUT: req->cmd.mode = SCSI_XFER_TO_DEV; break; default: @@ -387,6 +395,8 @@ static const char *scsi_command_name(uint8_t cmd) [ SPACE] = "SPACE", [ INQUIRY ] = "INQUIRY", [ RECOVER_BUFFERED_DATA] = "RECOVER_BUFFERED_DATA", +[ MAINTENANCE_IN ] = "MAINTENANCE_IN", +[ MAINTENANCE_OUT ] = "MAINTENANCE_OUT", [ MODE_SELECT ] = "MODE_SELECT", [ RESERVE ] = "RESERVE", [ RELEASE ] = "RELEASE", diff --git a/hw/scsi-defs.h b/hw/scsi-defs.h index 5890094..a4a3518 100644 --- a/hw/scsi-defs.h +++ b/hw/scsi-defs.h @@ -84,6 +84,8 @@ #define MODE_SENSE_10 0x5a #define PERSISTENT_RESERVE_IN 0x5e #define PERSISTENT_RESERVE_OUT 0x5f +#define MAINTENANCE_IN0xa3 +#define MAINTENANCE_OUT 0xa4 #define MOVE_MEDIUM 0xa5 #define READ_12 0xa8 #define WRITE_12 0xaa -- 1.6.6.1
[Qemu-devel] [PATCH 05/14] block: Add bdrv_(p)write_sync
Add new functions that write and flush the written data to disk immediately. This is what needs to be used for image format metadata to maintain integrity for cache=... modes that don't use O_DSYNC. (Actually, we only need barriers, and therefore the functions are defined as such, but flushes is what is implemented in this patch - we can try to change that later) Signed-off-by: Kevin Wolf --- block.c | 37 + block.h |4 2 files changed, 41 insertions(+), 0 deletions(-) diff --git a/block.c b/block.c index 3fc2969..e71a771 100644 --- a/block.c +++ b/block.c @@ -1010,6 +1010,43 @@ int bdrv_pwrite(BlockDriverState *bs, int64_t offset, return count1; } +/* + * Writes to the file and ensures that no writes are reordered across this + * request (acts as a barrier) + * + * Returns 0 on success, -errno in error cases. + */ +int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset, +const void *buf, int count) +{ +int ret; + +ret = bdrv_pwrite(bs, offset, buf, count); +if (ret < 0) { +return ret; +} + +/* No flush needed for cache=writethrough, it uses O_DSYNC */ +if ((bs->open_flags & BDRV_O_CACHE_MASK) != 0) { +bdrv_flush(bs); +} + +return 0; +} + +/* + * Writes to the file and ensures that no writes are reordered across this + * request (acts as a barrier) + * + * Returns 0 on success, -errno in error cases. + */ +int bdrv_write_sync(BlockDriverState *bs, int64_t sector_num, +const uint8_t *buf, int nb_sectors) +{ +return bdrv_pwrite_sync(bs, BDRV_SECTOR_SIZE * sector_num, +buf, BDRV_SECTOR_SIZE * nb_sectors); +} + /** * Truncate file to 'offset' bytes (needed only for file protocols) */ diff --git a/block.h b/block.h index 9df9b38..6a157f4 100644 --- a/block.h +++ b/block.h @@ -80,6 +80,10 @@ int bdrv_pread(BlockDriverState *bs, int64_t offset, void *buf, int count); int bdrv_pwrite(BlockDriverState *bs, int64_t offset, const void *buf, int count); +int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset, +const void *buf, int count); +int bdrv_write_sync(BlockDriverState *bs, int64_t sector_num, +const uint8_t *buf, int nb_sectors); int bdrv_truncate(BlockDriverState *bs, int64_t offset); int64_t bdrv_getlength(BlockDriverState *bs); void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr); -- 1.6.6.1
[Qemu-devel] [PATCH 01/14] scsi-bus: Add PERSISTENT_RESERVE_OUT SCSIRequest->cmd.mode setup
From: Nicholas Bellinger This patch updates hw/scsi-bus.c to add the PERSISTENT_RESERVE_OUT cdb case in scsi_req_xfer_mode() to set SCSI_XFER_TO_DEV for outgoing WRITE data. Signed-off-by: Nicholas A. Bellinger Acked-by: Gerd Hoffmann Signed-off-by: Kevin Wolf --- hw/scsi-bus.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index 055a94d..3575ba3 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -306,6 +306,7 @@ static void scsi_req_xfer_mode(SCSIRequest *req) case MEDIUM_SCAN: case SEND_VOLUME_TAG: case WRITE_LONG_2: +case PERSISTENT_RESERVE_OUT: req->cmd.mode = SCSI_XFER_TO_DEV; break; default: -- 1.6.6.1
[Qemu-devel] [PATCH v5 0/6] MIPS: Initial support for fulong (Loongson-2E based) mini pc.
Changes from V4: Doesn't include the PMON binary to avoid license issues. -- Huacai Chen
[Qemu-devel] [PATCH v5 6/6] MIPS: Initial support of fulong mini pc (machine construction)
Signed-off-by: Huacai Chen --- Makefile.target|2 +- hw/mips_fulong2e.c | 416 2 files changed, 417 insertions(+), 1 deletions(-) create mode 100644 hw/mips_fulong2e.c diff --git a/Makefile.target b/Makefile.target index 4b23e6d..a4c8e8e 100644 --- a/Makefile.target +++ b/Makefile.target @@ -221,7 +221,7 @@ obj-mips-y += vga.o i8259.o obj-mips-y += g364fb.o jazz_led.o obj-mips-y += gt64xxx.o mc146818rtc.o obj-mips-y += piix4.o cirrus_vga.o -obj-mips-$(CONFIG_FULONG) += bonito.o vt82c686.o +obj-mips-$(CONFIG_FULONG) += bonito.o vt82c686.o mips_fulong2e.o obj-microblaze-y = petalogix_s3adsp1800_mmu.o diff --git a/hw/mips_fulong2e.c b/hw/mips_fulong2e.c new file mode 100644 index 000..d03c897 --- /dev/null +++ b/hw/mips_fulong2e.c @@ -0,0 +1,416 @@ +/* + * QEMU fulong 2e mini pc support + * + * Copyright (c) 2008 yajin (ya...@vm-kernel.org) + * Copyright (c) 2009 chenming (chenm...@rdc.faw.com.cn) + * Copyright (c) 2010 Huacai Chen (zltjiang...@gmail.com) + * This code is licensed under the GNU GPL v2. + */ + +/* + * Fulong 2e mini pc is based on ICT/ST Loongson 2e CPU (MIPS III like, 800MHz) + * http://www.linux-mips.org/wiki/Fulong + * + * Loongson 2e user manual: + * http://www.loongsondeveloper.com/doc/Loongson2EUserGuide.pdf + */ + +#include "hw.h" +#include "pc.h" +#include "fdc.h" +#include "net.h" +#include "boards.h" +#include "smbus.h" +#include "block.h" +#include "flash.h" +#include "mips.h" +#include "mips_cpudevs.h" +#include "pci.h" +#include "usb-uhci.h" +#include "qemu-char.h" +#include "sysemu.h" +#include "audio/audio.h" +#include "qemu-log.h" +#include "loader.h" +#include "mips-bios.h" +#include "ide.h" +#include "elf.h" +#include "vt82c686.h" +#include "mc146818rtc.h" + +#define DEBUG_FULONG2E_INIT + +#define ENVP_ADDR 0x80002000l +#define ENVP_NB_ENTRIES16 +#define ENVP_ENTRY_SIZE256 + +#define MAX_IDE_BUS 2 + +/* + * PMON is not part of qemu and released with BSD license, anyone + * who want to build a pmon binary please first git-clone the source + * from the git repository at: + * http://www.loongson.cn/support/git/pmon + * Then follow the "Compile Guide" available at: + * http://dev.lemote.com/code/pmon + * + * Notes: + * 1, don't use the source at http://dev.lemote.com/http_git/pmon.git + * 2, use "Bonito2edev" to replace "dir_corresponding_to_your_target_hardware" + * in the "Compile Guide". + */ +#define FULONG_BIOSNAME "pmon_fulong2e.bin" + +/* PCI SLOT in fulong 2e */ +#define FULONG2E_VIA_SLOT5 +#define FULONG2E_ATI_SLOT6 +#define FULONG2E_RTL8139_SLOT7 + +static PITState *pit; + +static struct _loaderparams { +int ram_size; +const char *kernel_filename; +const char *kernel_cmdline; +const char *initrd_filename; +} loaderparams; + +static void prom_set(uint32_t* prom_buf, int index, const char *string, ...) +{ +va_list ap; +int32_t table_addr; + +if (index >= ENVP_NB_ENTRIES) +return; + +if (string == NULL) { +prom_buf[index] = 0; +return; +} + +table_addr = sizeof(int32_t) * ENVP_NB_ENTRIES + index * ENVP_ENTRY_SIZE; +prom_buf[index] = tswap32(ENVP_ADDR + table_addr); + +va_start(ap, string); +vsnprintf((char *)prom_buf + table_addr, ENVP_ENTRY_SIZE, string, ap); +va_end(ap); +} + +static int64_t load_kernel (CPUState *env) +{ +int64_t kernel_entry, kernel_low, kernel_high; +int index = 0; +long initrd_size; +ram_addr_t initrd_offset; +uint32_t *prom_buf; +long prom_size; + +if (load_elf(loaderparams.kernel_filename, cpu_mips_kseg0_to_phys, NULL, + (uint64_t *)&kernel_entry, (uint64_t *)&kernel_low, + (uint64_t *)&kernel_high, 0, ELF_MACHINE, 1) < 0) { +fprintf(stderr, "qemu: could not load kernel '%s'\n", +loaderparams.kernel_filename); +exit(1); +} + +/* load initrd */ +initrd_size = 0; +initrd_offset = 0; +if (loaderparams.initrd_filename) { +initrd_size = get_image_size (loaderparams.initrd_filename); +if (initrd_size > 0) { +initrd_offset = (kernel_high + ~TARGET_PAGE_MASK) & TARGET_PAGE_MASK; +if (initrd_offset + initrd_size > ram_size) { +fprintf(stderr, +"qemu: memory too small for initial ram disk '%s'\n", +loaderparams.initrd_filename); +exit(1); +} +initrd_size = load_image_targphys(loaderparams.initrd_filename, + initrd_offset, ram_size - initrd_offset); +} +if (initrd_size == (target_ulong) -1) { +fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", +loaderparams.initrd_filename); +exit(1); +} +} + +/* Setup prom parameters. */ +prom_size = ENVP_NB_ENTRIES * (sizeof(int32_t)
Re: [Qemu-devel] Re: KVM call agenda for June 22
On 06/22/10 15:23, Alexander Graf wrote: > Alex Williamson wrote: >>> Could we send the agenda note out a little bit earlier? >>> >>> The note arrived at 12:55am CST and we decided we had no agenda at >>> 7:04am CST. That's a pretty short window and I imagine a lot of people >>> in the US are not actually awake during that period of time :-) >>> >> >> Indeed, open at midnight, closed at 6am here. If anyone is still >> interested, I'd like to talk about canonical device paths >> (vmstate/ramblock naming). >> > > In fact, the only times the call was canceled right after it started was > when Anthony was on vacation. I think the canceling rule doesn't make > sense when he's around. It sounds like we should have the call and modify Chris' crontab to send out the note 18 hours earlier :) Cheers, Jes
[Qemu-devel] [PATCH v5 5/6] MIPS: Initial support of fulong mini pc (CPU definition)
Signed-off-by: Huacai Chen --- target-mips/mips-defs.h |4 target-mips/translate_init.c | 35 +++ 2 files changed, 39 insertions(+), 0 deletions(-) diff --git a/target-mips/mips-defs.h b/target-mips/mips-defs.h index a7f4697..bf094a3 100644 --- a/target-mips/mips-defs.h +++ b/target-mips/mips-defs.h @@ -41,6 +41,8 @@ #defineASE_MICROMIPS 0x0008 /* Chip specific instructions. */ +#defineINSN_LOONGSON2E 0x2000 +#defineINSN_LOONGSON2F 0x4000 #defineINSN_VR54XX 0x8000 /* MIPS CPU defines. */ @@ -49,6 +51,8 @@ #defineCPU_MIPS3 (CPU_MIPS2 | ISA_MIPS3) #defineCPU_MIPS4 (CPU_MIPS3 | ISA_MIPS4) #defineCPU_VR54XX (CPU_MIPS4 | INSN_VR54XX) +#defineCPU_LOONGSON2E (CPU_MIPS3 | INSN_LOONGSON2E) +#defineCPU_LOONGSON2F (CPU_MIPS3 | INSN_LOONGSON2F) #defineCPU_MIPS5 (CPU_MIPS4 | ISA_MIPS5) diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c index b79ed56..0d9899e 100644 --- a/target-mips/translate_init.c +++ b/target-mips/translate_init.c @@ -454,6 +454,41 @@ static const mips_def_t mips_defs[] = .insn_flags = CPU_MIPS64R2 | ASE_MIPS3D, .mmu_type = MMU_TYPE_R4000, }, +{ +.name = "Loongson-2E", +.CP0_PRid = 0x6302, +/*64KB I-cache and d-cache. 4 way with 32 bit cache line size*/ +.CP0_Config0 = (0x1<<17) | (0x1<<16) | (0x1<<11) | (0x1<<8) | (0x1<<5) | + (0x1<<4) | (0x1<<1), +/* Note: Config1 is only used internally, Loongson-2E has only Config0. */ +.CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU), +.SYNCI_Step = 16, +.CCRes = 2, +.CP0_Status_rw_bitmask = 0x35D0, +.CP1_fcr0 = (0x5 << FCR0_PRID) | (0x1 << FCR0_REV), +.SEGBITS = 40, +.PABITS = 40, +.insn_flags = CPU_LOONGSON2E, +.mmu_type = MMU_TYPE_R4000, +}, +{ + .name = "Loongson-2F", + .CP0_PRid = 0x6303, + /*64KB I-cache and d-cache. 4 way with 32 bit cache line size*/ + .CP0_Config0 = (0x1<<17) | (0x1<<16) | (0x1<<11) | (0x1<<8) | (0x1<<5) | + (0x1<<4) | (0x1<<1), + /* Note: Config1 is only used internally, Loongson-2F has only Config0. */ + .CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU), + .SYNCI_Step = 16, + .CCRes = 2, + .CP0_Status_rw_bitmask = 0xF5D0FF1F, /*bit5:7 not writeable*/ + .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x1 << FCR0_REV), + .SEGBITS = 40, + .PABITS = 40, + .insn_flags = CPU_LOONGSON2F, + .mmu_type = MMU_TYPE_R4000, +}, + #endif }; -- 1.7.0.4
[Qemu-devel] [PATCH v5 3/6] MIPS: Initial support of VIA IDE controller used by fulong mini pc
Signed-off-by: Huacai Chen --- Makefile.objs|1 + default-configs/mips64el-softmmu.mak |1 + hw/ide.h |1 + hw/ide/via.c | 191 ++ 4 files changed, 194 insertions(+), 0 deletions(-) create mode 100644 hw/ide/via.c diff --git a/Makefile.objs b/Makefile.objs index 2bfb6d1..ddd1d10 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -202,6 +202,7 @@ hw-obj-$(CONFIG_IDE_ISA) += ide/isa.o hw-obj-$(CONFIG_IDE_PIIX) += ide/piix.o hw-obj-$(CONFIG_IDE_CMD646) += ide/cmd646.o hw-obj-$(CONFIG_IDE_MACIO) += ide/macio.o +hw-obj-$(CONFIG_IDE_VIA) += ide/via.o # SCSI layer hw-obj-y += lsi53c895a.o diff --git a/default-configs/mips64el-softmmu.mak b/default-configs/mips64el-softmmu.mak index d35d923..85b7838 100644 --- a/default-configs/mips64el-softmmu.mak +++ b/default-configs/mips64el-softmmu.mak @@ -21,6 +21,7 @@ CONFIG_IDE_QDEV=y CONFIG_IDE_PCI=y CONFIG_IDE_ISA=y CONFIG_IDE_PIIX=y +CONFIG_IDE_VIA=y CONFIG_NE2000_ISA=y CONFIG_SOUND=y CONFIG_VIRTIO_PCI=y diff --git a/hw/ide.h b/hw/ide.h index 0e7d540..bb635b6 100644 --- a/hw/ide.h +++ b/hw/ide.h @@ -12,6 +12,7 @@ void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table, int secondary_ide_enabled); void pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); void pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); +void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); /* ide-macio.c */ int pmac_ide_init (DriveInfo **hd_table, qemu_irq irq, diff --git a/hw/ide/via.c b/hw/ide/via.c new file mode 100644 index 000..d933caf --- /dev/null +++ b/hw/ide/via.c @@ -0,0 +1,191 @@ +/* + * QEMU IDE Emulation: PCI VIA82C686B support. + * + * Copyright (c) 2003 Fabrice Bellard + * Copyright (c) 2006 Openedhand Ltd. + * Copyright (c) 2010 Huacai Chen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include "block.h" +#include "block_int.h" +#include "sysemu.h" +#include "dma.h" + +#include + +static uint32_t bmdma_readb(void *opaque, uint32_t addr) +{ +BMDMAState *bm = opaque; +uint32_t val; + +switch (addr & 3) { +case 0: +val = bm->cmd; +break; +case 2: +val = bm->status; +break; +default: +val = 0xff; +break; +} +#ifdef DEBUG_IDE +printf("bmdma: readb 0x%02x : 0x%02x\n", addr, val); +#endif +return val; +} + +static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val) +{ +BMDMAState *bm = opaque; +#ifdef DEBUG_IDE +printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val); +#endif +switch (addr & 3) { +case 2: +bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06); +break; +default:; +} +} + +static void bmdma_map(PCIDevice *pci_dev, int region_num, +pcibus_t addr, pcibus_t size, int type) +{ +PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev); +int i; + +for(i = 0;i < 2; i++) { +BMDMAState *bm = &d->bmdma[i]; +d->bus[i].bmdma = bm; +bm->bus = d->bus+i; +qemu_add_vm_change_state_handler(ide_dma_restart_cb, bm); + +register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm); + +register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm); +register_ioport_read(addr, 4, 1, bmdma_readb, bm); + +register_ioport_write(addr + 4, 4, 1, bmdma_addr_writeb, bm); +register_ioport_read(addr + 4, 4, 1, bmdma_addr_readb, bm); +register_ioport_write(addr + 4, 4, 2, bmdma_addr_writew, bm); +register_ioport_read(addr + 4, 4, 2, bmdma_addr_readw, bm); +register_ioport_write(addr + 4, 4, 4, bmdma_addr_writel, bm); +register_ioport_read(addr + 4, 4, 4, bmdma_addr_readl, bm); +addr += 8; +} +} + +static void via_reset(void *opaqu
[Qemu-devel] [PATCH v5 2/6] MIPS: Initial support of vt82686b south bridge used by fulong mini pc
Signed-off-by: Huacai Chen --- Makefile.target |2 +- hw/pci_ids.h|8 + hw/vt82c686.c | 569 +++ hw/vt82c686.h | 11 + 4 files changed, 589 insertions(+), 1 deletions(-) create mode 100644 hw/vt82c686.c create mode 100644 hw/vt82c686.h diff --git a/Makefile.target b/Makefile.target index 36de833..4b23e6d 100644 --- a/Makefile.target +++ b/Makefile.target @@ -221,7 +221,7 @@ obj-mips-y += vga.o i8259.o obj-mips-y += g364fb.o jazz_led.o obj-mips-y += gt64xxx.o mc146818rtc.o obj-mips-y += piix4.o cirrus_vga.o -obj-mips-$(CONFIG_FULONG) += bonito.o +obj-mips-$(CONFIG_FULONG) += bonito.o vt82c686.o obj-microblaze-y = petalogix_s3adsp1800_mmu.o diff --git a/hw/pci_ids.h b/hw/pci_ids.h index fe7a121..39e9f1d 100644 --- a/hw/pci_ids.h +++ b/hw/pci_ids.h @@ -78,6 +78,14 @@ #define PCI_VENDOR_ID_XILINX 0x10ee +#define PCI_VENDOR_ID_VIA0x1106 +#define PCI_DEVICE_ID_VIA_ISA_BRIDGE 0x0686 +#define PCI_DEVICE_ID_VIA_IDE0x0571 +#define PCI_DEVICE_ID_VIA_UHCI 0x3038 +#define PCI_DEVICE_ID_VIA_ACPI 0x3057 +#define PCI_DEVICE_ID_VIA_AC97 0x3058 +#define PCI_DEVICE_ID_VIA_MC97 0x3068 + #define PCI_VENDOR_ID_MARVELL0x11ab #define PCI_VENDOR_ID_ENSONIQ0x1274 diff --git a/hw/vt82c686.c b/hw/vt82c686.c new file mode 100644 index 000..e7aca0c --- /dev/null +++ b/hw/vt82c686.c @@ -0,0 +1,569 @@ +/* + * VT82C686B south bridge support + * + * Copyright (c) 2008 yajin (ya...@vm-kernel.org) + * Copyright (c) 2009 chenming (chenm...@rdc.faw.com.cn) + * Copyright (c) 2010 Huacai Chen (zltjiang...@gmail.com) + * This code is licensed under the GNU GPL v2. + */ + +#include "hw.h" +#include "pc.h" +#include "vt82c686.h" +#include "i2c.h" +#include "smbus.h" +#include "pci.h" +#include "isa.h" +#include "sysbus.h" +#include "mips.h" +#include "apm.h" +#include "acpi.h" +#include "pm_smbus.h" +#include "sysemu.h" +#include "qemu-timer.h" + +typedef uint32_t pci_addr_t; +#include "pci_host.h" +//#define DEBUG_VT82C686B + +#ifdef DEBUG_VT82C686B +#define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __FUNCTION__, ##__VA_ARGS__) +#else +#define DPRINTF(fmt, ...) +#endif + +typedef struct SuperIOConfig +{ +uint8_t config[0xff]; +uint8_t index; +uint8_t data; +} SuperIOConfig; + +typedef struct VT82C686BState { +PCIDevice dev; +SuperIOConfig *superio_conf; +} VT82C686BState; + +static void superio_ioport_writeb(void *opaque, uint32_t addr, uint32_t data) +{ +int can_write; +SuperIOConfig *superio_conf = (SuperIOConfig *)opaque; + +DPRINTF("superio_ioport_writeb address 0x%x val 0x%x \n", addr, data); +if (addr == 0x3f0) { +superio_conf->index = data & 0xff; +} else { +/* 0x3f1 */ +switch (superio_conf->index) { +case 0x00 ... 0xdf: +case 0xe4: +case 0xe5: +case 0xe9 ... 0xed: +case 0xf3: +case 0xf5: +case 0xf7: +case 0xf9 ... 0xfb: +case 0xfd ... 0xff: +can_write = 0; +break; +default: +can_write = 1; + +if (can_write) { +switch (superio_conf->index) { +case 0xe7: +if ((data & 0xff) != 0xfe) { +DPRINTF("chage uart 1 base. unsupported yet \n"); +} +break; +case 0xe8: +if ((data & 0xff) != 0xbe) { +DPRINTF("chage uart 2 base. unsupported yet \n"); +} +break; + +default: +superio_conf->config[superio_conf->index] = data & 0xff; +} +} +} +superio_conf->config[superio_conf->index] = data & 0xff; +} +} + +static uint32_t superio_ioport_readb(void *opaque, uint32_t addr) +{ +SuperIOConfig *superio_conf = (SuperIOConfig *)opaque; + +DPRINTF("superio_ioport_readb address 0x%x \n", addr); +return (superio_conf->config[superio_conf->index]); +} + +static void vt82c686b_reset(void * opaque) +{ +PCIDevice *d = opaque; +uint8_t *pci_conf = d->config; +VT82C686BState *vt82c = DO_UPCAST(VT82C686BState, dev, d); + +pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x00c0); +pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL); +pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM); + +pci_conf[0x48] = 0x01; /* Miscellaneous Control 3 */ +pci_conf[0x4a] = 0x04; /* IDE interrupt Routing */ +pci_conf[0x4f] = 0x03; /* DMA/Master Mem Access Control 3 */ +pci_conf[0x50] = 0x2d; /* PnP DMA Request Control */ +pci_conf[0x59] = 0x04; +pci_conf[0x5a] = 0x04; /* KBC/RTC Control*/ +pci_conf[0x5f] = 0x04; +pci_conf[0x77] = 0x10; /*
[Qemu-devel] [PATCH v5 4/6] MIPS: Initial support of VIA USB controller used by fulong mini pc
Signed-off-by: Huacai Chen --- hw/usb-uhci.c | 29 + hw/usb-uhci.h |1 + 2 files changed, 30 insertions(+), 0 deletions(-) diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c index 624d55b..accfe2e 100644 --- a/hw/usb-uhci.c +++ b/hw/usb-uhci.c @@ -1149,6 +1149,25 @@ static int usb_uhci_piix4_initfn(PCIDevice *dev) pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL); pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371AB_2); +pci_set_byte(pci_conf + PCI_LATENCY_TIMER, 0x16); + +/* USB misc control 1/2 */ +pci_set_long(pci_conf + 0x40,0x1000); +/* PM capability */ +pci_set_long(pci_conf + 0x80,0x00020001); +/* USB legacy support */ +pci_set_long(pci_conf + 0xc0,0x2000); + +return usb_uhci_common_initfn(s); +} + +static int usb_uhci_vt82c686b_initfn(PCIDevice *dev) +{ +UHCIState *s = DO_UPCAST(UHCIState, dev, dev); +uint8_t *pci_conf = s->dev.config; + +pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_VIA); +pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_VIA_UHCI); return usb_uhci_common_initfn(s); } @@ -1164,6 +1183,11 @@ static PCIDeviceInfo uhci_info[] = { .qdev.vmsd= &vmstate_uhci, .init = usb_uhci_piix4_initfn, },{ +.qdev.name= "vt82c686b-usb-uhci", +.qdev.size= sizeof(UHCIState), +.qdev.vmsd= &vmstate_uhci, +.init = usb_uhci_vt82c686b_initfn, +},{ /* end of list */ } }; @@ -1183,3 +1207,8 @@ void usb_uhci_piix4_init(PCIBus *bus, int devfn) { pci_create_simple(bus, devfn, "piix4-usb-uhci"); } + +void usb_uhci_vt82c686b_init(PCIBus *bus, int devfn) +{ +pci_create_simple(bus, devfn, "vt82c686b-usb-uhci"); +} diff --git a/hw/usb-uhci.h b/hw/usb-uhci.h index 911948e..3e4d377 100644 --- a/hw/usb-uhci.h +++ b/hw/usb-uhci.h @@ -5,5 +5,6 @@ void usb_uhci_piix3_init(PCIBus *bus, int devfn); void usb_uhci_piix4_init(PCIBus *bus, int devfn); +void usb_uhci_vt82c686b_init(PCIBus *bus, int devfn); #endif -- 1.7.0.4
[Qemu-devel] [PATCH v5 1/6] MIPS: Initial support of bonito north bridge used by fulong mini pc
Signed-off-by: Huacai Chen --- Makefile.target |1 + default-configs/mips64el-softmmu.mak |1 + hw/bonito.c | 809 ++ hw/mips.h|3 + 4 files changed, 814 insertions(+), 0 deletions(-) create mode 100644 hw/bonito.c diff --git a/Makefile.target b/Makefile.target index 478b89d..36de833 100644 --- a/Makefile.target +++ b/Makefile.target @@ -221,6 +221,7 @@ obj-mips-y += vga.o i8259.o obj-mips-y += g364fb.o jazz_led.o obj-mips-y += gt64xxx.o mc146818rtc.o obj-mips-y += piix4.o cirrus_vga.o +obj-mips-$(CONFIG_FULONG) += bonito.o obj-microblaze-y = petalogix_s3adsp1800_mmu.o diff --git a/default-configs/mips64el-softmmu.mak b/default-configs/mips64el-softmmu.mak index b372c1d..d35d923 100644 --- a/default-configs/mips64el-softmmu.mak +++ b/default-configs/mips64el-softmmu.mak @@ -29,3 +29,4 @@ CONFIG_DP8393X=y CONFIG_DS1225Y=y CONFIG_MIPSNET=y CONFIG_PFLASH_CFI01=y +CONFIG_FULONG=y diff --git a/hw/bonito.c b/hw/bonito.c new file mode 100644 index 000..8b81032 --- /dev/null +++ b/hw/bonito.c @@ -0,0 +1,809 @@ +/* + * bonito north bridge support + * + * Copyright (c) 2008 yajin (ya...@vm-kernel.org) + * Copyright (c) 2010 Huacai Chen (zltjiang...@gmail.com) + * + * This code is licensed under the GNU GPL v2. + */ + +/* + * fulong 2e mini pc has a bonito north bridge. + */ + +/* what is the meaning of devfn in qemu and IDSEL in bonito northbridge? + * + * devfn pci_slot<<3 + funno + * one pci bus can have 32 devices and each device can have 8 functions. + * + * In bonito north bridge, pci slot = IDSEL bit - 12. + * For example, PCI_IDSEL_VIA686B = 17, + * pci slot = 17-12=5 + * + * so + * VT686B_FUN0's devfn = (5<<3)+0 + * VT686B_FUN1's devfn = (5<<3)+1 + * + * qemu also uses pci address for north bridge to access pci config register. + * bus_no [23:16] + * dev_no [15:11] + * fun_no [10:8] + * reg_no [7:2] + * + * so function bonito_sbridge_pciaddr for the translation from + * north bridge address to pci address. + */ + +#include + +#include "hw.h" +#include "pci.h" +#include "pc.h" +#include "mips.h" +#include "pci_host.h" +#include "sysemu.h" + +//#define DEBUG_BONITO + +#ifdef DEBUG_BONITO +#define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __FUNCTION__, ##__VA_ARGS__) +#else +#define DPRINTF(fmt, ...) +#endif + +/* from linux soure code. include/asm-mips/mips-boards/bonito64.h*/ +#define BONITO_BOOT_BASE0x1fc0 +#define BONITO_BOOT_SIZE0x0010 +#define BONITO_BOOT_TOP (BONITO_BOOT_BASE+BONITO_BOOT_SIZE-1) +#define BONITO_FLASH_BASE 0x1c00 +#define BONITO_FLASH_SIZE 0x0300 +#define BONITO_FLASH_TOP(BONITO_FLASH_BASE+BONITO_FLASH_SIZE-1) +#define BONITO_SOCKET_BASE 0x1f80 +#define BONITO_SOCKET_SIZE 0x0040 +#define BONITO_SOCKET_TOP (BONITO_SOCKET_BASE+BONITO_SOCKET_SIZE-1) +#define BONITO_REG_BASE 0x1fe0 +#define BONITO_REG_SIZE 0x0004 +#define BONITO_REG_TOP (BONITO_REG_BASE+BONITO_REG_SIZE-1) +#define BONITO_DEV_BASE 0x1ff0 +#define BONITO_DEV_SIZE 0x0010 +#define BONITO_DEV_TOP (BONITO_DEV_BASE+BONITO_DEV_SIZE-1) +#define BONITO_PCILO_BASE 0x1000 +#define BONITO_PCILO_BASE_VA0xb000 +#define BONITO_PCILO_SIZE 0x0c00 +#define BONITO_PCILO_TOP(BONITO_PCILO_BASE+BONITO_PCILO_SIZE-1) +#define BONITO_PCILO0_BASE 0x1000 +#define BONITO_PCILO1_BASE 0x1400 +#define BONITO_PCILO2_BASE 0x1800 +#define BONITO_PCIHI_BASE 0x2000 +#define BONITO_PCIHI_SIZE 0x2000 +#define BONITO_PCIHI_TOP(BONITO_PCIHI_BASE+BONITO_PCIHI_SIZE-1) +#define BONITO_PCIIO_BASE 0x1fd0 +#define BONITO_PCIIO_BASE_VA0xbfd0 +#define BONITO_PCIIO_SIZE 0x0001 +#define BONITO_PCIIO_TOP(BONITO_PCIIO_BASE+BONITO_PCIIO_SIZE-1) +#define BONITO_PCICFG_BASE 0x1fe8 +#define BONITO_PCICFG_SIZE 0x0008 +#define BONITO_PCICFG_TOP (BONITO_PCICFG_BASE+BONITO_PCICFG_SIZE-1) + + +#define BONITO_PCICONFIGBASE0x00 +#define BONITO_REGBASE 0x100 + +#define BONITO_PCICONFIG_BASE (BONITO_PCICONFIGBASE+BONITO_REG_BASE) +#define BONITO_PCICONFIG_SIZE (0x100) + +#define BONITO_INTERNAL_REG_BASE (BONITO_REGBASE+BONITO_REG_BASE) +#define BONITO_INTERNAL_REG_SIZE (0x70) + +#define BONITO_SPCICONFIG_BASE (BONITO_PCICFG_BASE) +#define BONITO_SPCICONFIG_SIZE (BONITO_PCICFG_SIZE) + + + +/* 1. Bonito h/w Configuration */ +/* Power on register */ + +#define BONITO_BONPONCFG(0x00 >> 2) /* 0x100 */ +#define BONITO_BONGENCFG_OFFSET 0x4 +#define BONITO_BONGENCFG(BONITO_BONGENCFG_OFFSET>>2) /*0x104 */ + +/* 2. IO & IDE configuration */ +#define BONITO_IODEVCFG (0x08 >> 2) /* 0x108 */ + +/* 3. IO & IDE configuration */ +#define BONITO_SDCFG(0x0c >> 2) /* 0x10c */ + +/* 4. PCI
[Qemu-devel] Re: KVM call agenda for June 22
Alex Williamson wrote: > On Tue, 2010-06-22 at 07:49 -0500, Anthony Liguori wrote: > >> On 06/22/2010 07:04 AM, Juan Quintela wrote: >> >>> Chris Wright wrote: >>> >>> Please send in any agenda items you are interested in covering. If we have a lack of agenda items I'll cancel the week's call. >>> As we have no agenda. This week call gets cancelled. >>> >>> >> Could we send the agenda note out a little bit earlier? >> >> The note arrived at 12:55am CST and we decided we had no agenda at >> 7:04am CST. That's a pretty short window and I imagine a lot of people >> in the US are not actually awake during that period of time :-) >> > > Indeed, open at midnight, closed at 6am here. If anyone is still > interested, I'd like to talk about canonical device paths > (vmstate/ramblock naming). > In fact, the only times the call was canceled right after it started was when Anthony was on vacation. I think the canceling rule doesn't make sense when he's around. Alex
[Qemu-devel] Re: KVM call agenda for June 22
On Tue, 2010-06-22 at 07:49 -0500, Anthony Liguori wrote: > On 06/22/2010 07:04 AM, Juan Quintela wrote: > > Chris Wright wrote: > > > >> Please send in any agenda items you are interested in covering. > >> > >> If we have a lack of agenda items I'll cancel the week's call. > >> > > As we have no agenda. This week call gets cancelled. > > > > Could we send the agenda note out a little bit earlier? > > The note arrived at 12:55am CST and we decided we had no agenda at > 7:04am CST. That's a pretty short window and I imagine a lot of people > in the US are not actually awake during that period of time :-) Indeed, open at midnight, closed at 6am here. If anyone is still interested, I'd like to talk about canonical device paths (vmstate/ramblock naming). Alex
[Qemu-devel] Re: [PATCH v3] QMP: Introduce the documentation for query-netdev and info netdev
On Tue, Jun 22, 2010 at 10:06 AM, Luiz Capitulino wrote: > On Mon, 21 Jun 2010 17:31:28 -0300 > Miguel Di Ciurcio Filho wrote: > >> These commands show the information about active backend network devices. >> >> Changes from v2 >> --- >> - Got rid of vlans, a separate command for them will be created if needed >> - Removed socket as a type (it is used to connect vlans) >> - 'script', 'downscript' and 'vhostfd' are now optional when type is 'tap' >> - Reworded the explanation of 'peer' >> >> Signed-off-by: Miguel Di Ciurcio Filho >> --- >> qemu-monitor.hx | 96 >> +++ >> 1 files changed, 96 insertions(+), 0 deletions(-) >> >> diff --git a/qemu-monitor.hx b/qemu-monitor.hx >> index 9f62b94..cffd69e 100644 >> --- a/qemu-monitor.hx >> +++ b/qemu-monitor.hx >> @@ -1674,6 +1674,102 @@ show the various VLANs and the associated devices >> ETEXI >> >> STEXI >> +...@item info netdev >> +show information about the current backend network devices >> +ETEXI >> +SQMP >> +query-netdev >> + >> + >> +Each device is represented by a json-object. The returned value is a >> json-array >> +of all devices. >> + >> +Each json-object contains the following: >> + >> +- "id": the device's ID, must be unique (json-string) >> +- "type": device type (json-string) >> + - Possible values: "tap", "user", "vde" > > What has happened to socket? Looks good otherwise. > Socket does not support an 1:1 relationship and it is used just to connect vlans, as I explained in the changelog. $ qemu -netdev type=socket,listen=:3000,id=ss -device e1000,netdev=ss qemu: -device e1000,netdev=ss: Property 'e1000.netdev' can't find value 'ss' Regards, Miguel
[Qemu-devel] Re: block: format vs. protocol, and how they stack
On 06/22/2010 07:57 AM, Kevin Wolf wrote: and it will be turned into something sensible automagically (namely adding a file blockdev underneath and passing the file parameter to that one), but if you want to change an option, you need to specify both? -blockdev id=foo,format=qcow2,parent=foo_file -blockdev id=foo_file,format=file,file=foo.qcow2,cache=off What about read-only? Good question. If a user specifies file, I think the (or generic block layer) should have wide latitude to decide how to creating that backing format which could include propagating options that it thinks are reasonable (like readonly). Right, if we get to use a default value, we can propagate things that the generic block layer knows. However, as soon as someone specifies a protocol explicitly, he'll need to add readonly=on to each -blockdev in the chain? Yes. I think once you do an explicit option, you have to be very careful. My concern is seeing something like: -blockdev id=foo,format=qcow2,file=blah.img,funkyopt=value or: -blockdev id=foo,format=qcow2,protocol=[file=blah.img,funkyopt=value] I think the later syntax is overwhelming. If the semantics of the former syntax is "passthrough any options we don't understand at this layer", I'm afraid it gets too confusing about which level actually processed the option (and it certainly doesn't deal with propagation). The former involves definitely too much magic for assigning the options to the right blockdev. The latter would be more comprehensible, but isn't really nice either. On the other hand, funkyopt might be something as common as cache, and I'd hate to require specifying the protocol explicitly in a second -blockdev referenced by another ID when you just want to change the cache option. I understand the concern but I think one of the big problems with -drive and bdrv_open today is they are far too magical. We shouldn't make the same mistake again. We ought to keep in my the 80/20 rule. In this case, I'm fairly certain that it's closer to 99% of users are only doing 1% of what is actually possible and generally that's going to either be -hda foo.img or -blockdev file=foo.img,option=value. Regards, Anthony Liguori Kevin
[Qemu-devel] Re: [PATCH v3] QMP: Introduce the documentation for query-netdev and info netdev
On Mon, 21 Jun 2010 17:31:28 -0300 Miguel Di Ciurcio Filho wrote: > These commands show the information about active backend network devices. > > Changes from v2 > --- > - Got rid of vlans, a separate command for them will be created if needed > - Removed socket as a type (it is used to connect vlans) > - 'script', 'downscript' and 'vhostfd' are now optional when type is 'tap' > - Reworded the explanation of 'peer' > > Signed-off-by: Miguel Di Ciurcio Filho > --- > qemu-monitor.hx | 96 > +++ > 1 files changed, 96 insertions(+), 0 deletions(-) > > diff --git a/qemu-monitor.hx b/qemu-monitor.hx > index 9f62b94..cffd69e 100644 > --- a/qemu-monitor.hx > +++ b/qemu-monitor.hx > @@ -1674,6 +1674,102 @@ show the various VLANs and the associated devices > ETEXI > > STEXI > +...@item info netdev > +show information about the current backend network devices > +ETEXI > +SQMP > +query-netdev > + > + > +Each device is represented by a json-object. The returned value is a > json-array > +of all devices. > + > +Each json-object contains the following: > + > +- "id": the device's ID, must be unique (json-string) > +- "type": device type (json-string) > +- Possible values: "tap", "user", "vde" What has happened to socket? Looks good otherwise. > +- "peer": ID of the frontend guest device, if not available means that this > + netdev is not connected to a guest device yet (json-string, optional) > +- "info": json-object containing the configuration information about the > device. > +- When "type" is "tap", the following values might be available: > +- "fd": available if connected to an already opened TAP interface > + (json-int, optional) > +- "script": path to an script used to configure the interface, > + available only if an script is used. (json-string, optional, > only > + present if "fd" is not present) > +- "downscript": path to an script used to deconfigure the > interface, > + available only if an script is used. (json-string, optional, > only > + present if "fd" is not present) > +- "ifname": name of the attached host interface (json-string, > only > + present if "fd" is not present) > +- "vhost": vhost acceleration status, true if enabled, false > + otherwise (json-boolean) > +- "vnet_hdr": true if the IFF_VNET_HDR flag must be set and is in > + use, false otherwise (json-boolean) > +- "vhostfd": fd used to connect the device to an already opened > + vhost net device (json-int, optional) > +- "sndbuf": send buffer size, in bytes (json-int) > +- When "type" is "vde", the following values might be available: > +- "sock": path to the VDE listening socket (json-string) > +- "port": port number connected to virtual switch (json-int) > +- "group": group name (json-string) > +- "mode": permission mode, in octal (json-int) > +- When "type" is "user", the following values might be available: > +- "hostname": client hostname reported by the builtin DHCP > server, > + (json-string, optional) > +- "restrict": true if guest is isolated from the host, > + false otherwise (json-boolean) > +- "net": network address (json-string) > +- "netmask": netmask (json-string) > +- "host": guest-visible address of the host (json-string) > +- "tftp": root directory of the built-in TFTP server > (json-string, > + optional) > +- "bootfile": BOOTP filename (json-string, optional) > +- "dhcpstart": the first of the 16 IPs the built-in DHCP server > can > + assign (json-string) > +- "dns": guest-visible address of the virtual nameserver > + (json-string) > +- "smb": root directory of the built-in SMB server (json-string, > + optional) > +- "smbserver": IP address of the built-in SMB server > (json-string, > + optional) > +- "hostfwd": guest port number to forward incoming TCP or UDP > + connections (json-int, optional) > +- "guestfwd": IP address and port to forward guest TCP > connections > + (json-int, optional) > + > +Example: > + > +-> { "execute": "query-netdev" } > +<- { > + "return": [ > + { > +"id": "tap.0", > +"type": "tap", > +"peer": "e1000.0", > +"info": { > + "script": "/etc/qemu-ifup", > + "downscript": "/etc/qemu-ifdown", > + "ifname": "tap0", > + "vhost": true > +}, > + }, > + { > +"id": "user.0", > +"type": "
Re: [Qemu-devel] [patch 2/3] QEMU-C-F: Introducing qemu userspace tool qemu-core-filter.
Hrm, the way you've sent this patch makes Thunderbird unhappy. It appears the whole thing is treated as an attachment. In the future, I'd suggest avoiding the Content-Disposition tag On 06/21/2010 11:01 PM, Mahesh Salgaonkar wrote: Qemu userspace tool to filter out guest OS memory from qemu core file. Use '--enable-core-filter' option while running ./configure script to build qemu-core-filter tool. This is a post-processing tool works offline on qemu coredumps. This tool helps to reuce the size of qemu core file (generated by qemu crash) by removing guest OS memory from original core file. Currently it is only supported for Linux on x86 and x86_64. There are a few problems with a tool like this. The first is that it depends on very specific internals of qemu (namely, the way we allocate ram). If we applied this, we would get subtle breakages if we made even the slightest changes to qemu. IMHO, the value is also questionable. There is quite a bit of sensitive data left in the core file after removing guest memory. Any DMA buffer may contain very sensitive data (for instance, if you crash during a read of /etc/shadow). Even the CPU registers can contain sensitive data. I think the only really viable approach to this problem is to take a white list approach instead of a black list approach. That means extracting useful information that we're reasonably confident preserves privacy. That would be information like a back trace, the crash reason, etc. Tools like apport and ABT already do exactly this and they also present an interface to the user to validate the data before sending it. They also provide a way to collect other information (like host dmesg). Regards, Anthony Liguori
[Qemu-devel] Re: block: format vs. protocol, and how they stack
Am 22.06.2010 14:39, schrieb Anthony Liguori: > On 06/22/2010 03:10 AM, Kevin Wolf wrote: >> Am 21.06.2010 17:34, schrieb Anthony Liguori: >> >>> On 06/21/2010 09:01 AM, Kevin Wolf wrote: >>> No, what I'm saying is that even in your model -blockdev format=qcow2,file=image.qcow2,id=blk1 becomes qcow2 -> file automatically, whereas -blockdev format=vvfat,file=/tmp/dir/,id=blk1 doesn't become vvfat -> file, but stays just vvfat. >>> I should say, that -blockdev format= vs. -blockdev transport= is >>> definitely at a place where I don't care that much. >>> >>> The things that I think are most important are: >>> >>> 1) That we have structured options that map well to config file without >>> trickery to do nesting >>> 2) That we don't automagically pass options through from the first layer >>> down to subsequent layers >>> >> Does this mean that you need to specify the protocol explicitly for any >> non-trivial case? So if you want to use just default for everything you >> can use >> >>-blockdev id=foo,format=qcow2,file=foo.qcow2 >> > > Yes. I think we should explicitly support an option like file. Makes sense. I don't really like adding some special magic for file, but I do see that it's a requirement to make at least the simplest case easy - and this was about the only clear result of my discussion with Markus before he posted his proposal. >> and it will be turned into something sensible automagically (namely >> adding a file blockdev underneath and passing the file parameter to that >> one), but if you want to change an option, you need to specify both? >> >>-blockdev id=foo,format=qcow2,parent=foo_file >>-blockdev id=foo_file,format=file,file=foo.qcow2,cache=off >> >> What about read-only? > > Good question. If a user specifies file, I think the (or generic block > layer) should have wide latitude to decide how to creating that backing > format which could include propagating options that it thinks are > reasonable (like readonly). Right, if we get to use a default value, we can propagate things that the generic block layer knows. However, as soon as someone specifies a protocol explicitly, he'll need to add readonly=on to each -blockdev in the chain? > My concern is seeing something like: > > -blockdev id=foo,format=qcow2,file=blah.img,funkyopt=value > > or: > > -blockdev id=foo,format=qcow2,protocol=[file=blah.img,funkyopt=value] > > I think the later syntax is overwhelming. If the semantics of the > former syntax is "passthrough any options we don't understand at this > layer", I'm afraid it gets too confusing about which level actually > processed the option (and it certainly doesn't deal with propagation). The former involves definitely too much magic for assigning the options to the right blockdev. The latter would be more comprehensible, but isn't really nice either. On the other hand, funkyopt might be something as common as cache, and I'd hate to require specifying the protocol explicitly in a second -blockdev referenced by another ID when you just want to change the cache option. Kevin
[Qemu-devel] [PATCH 5/7] Only export phys_mem create functions for !CONFIG_USER_ONLY builds
From: Jes Sorensen Signed-off-by: Jes Sorensen --- qemu-kvm.h |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/qemu-kvm.h b/qemu-kvm.h index c9b93dc..6dd3a01 100644 --- a/qemu-kvm.h +++ b/qemu-kvm.h @@ -835,6 +835,7 @@ void qemu_kvm_cpuid_on_env(CPUState *env); void kvm_inject_interrupt(CPUState *env, int mask); void kvm_update_after_sipi(CPUState *env); void kvm_update_interrupt_request(CPUState *env); +#ifndef CONFIG_USER_ONLY void *kvm_cpu_create_phys_mem(target_phys_addr_t start_addr, unsigned long size, int log, int writable); @@ -842,6 +843,7 @@ void kvm_cpu_destroy_phys_mem(target_phys_addr_t start_addr, unsigned long size); void kvm_qemu_log_memory(target_phys_addr_t start, target_phys_addr_t size, int log); +#endif int kvm_qemu_create_memory_alias(uint64_t phys_start, uint64_t len, uint64_t target_phys); int kvm_qemu_destroy_memory_alias(uint64_t phys_start); -- 1.7.0.1
[Qemu-devel] [PATCH 6/7] Only treat KVM specific cmdline options for KVM enabled builds
From: Jes Sorensen This fixes build breakage for target MIPS etc. Signed-off-by: Jes Sorensen --- vl.c |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/vl.c b/vl.c index 0ee963c..79f91d5 100644 --- a/vl.c +++ b/vl.c @@ -2459,6 +2459,7 @@ int main(int argc, char **argv, char **envp) case QEMU_OPTION_no_kvm: kvm_allowed = 0; break; +#ifdef CONFIG_KVM case QEMU_OPTION_no_kvm_irqchip: { kvm_irqchip = 0; kvm_pit = 0; @@ -2476,6 +2477,7 @@ int main(int argc, char **argv, char **envp) kvm_nested = 1; break; } +#endif #if defined(TARGET_I386) || defined(TARGET_X86_64) || defined(TARGET_IA64) || defined(__linux__) case QEMU_OPTION_pcidevice: if (assigned_devices_index >= MAX_DEV_ASSIGN_CMDLINE) { -- 1.7.0.1
[Qemu-devel] [PATCH 2/7] Remove duplicate kvm_init() stub from qemu-kvm.h
From: Jes Sorensen Avoid build conflicts and move prototype out of CONFIG_KVM to make the stub in kvm-stub.c visible. Signed-off-by: Jes Sorensen --- qemu-kvm.h | 29 - 1 files changed, 12 insertions(+), 17 deletions(-) diff --git a/qemu-kvm.h b/qemu-kvm.h index 3ace503..c9b93dc 100644 --- a/qemu-kvm.h +++ b/qemu-kvm.h @@ -107,18 +107,6 @@ int kvm_set_mce(CPUState *env, struct kvm_x86_mce *mce); #endif /*! - * \brief Create new KVM context - * - * This creates a new kvm_context. A KVM context is a small area of data that - * holds information about the KVM instance that gets created by this call.\n - * This should always be your first call to KVM. - * - * \param opaque Not used - * \return NULL on failure - */ -int kvm_init(int smp_cpus); - -/*! * \brief Disable the in-kernel IRQCHIP creation * * In-kernel irqchip is enabled by default. If userspace irqchip is to be used, @@ -806,11 +794,6 @@ typedef struct kvm_vcpu_context *kvm_vcpu_context_t; struct kvm_pit_state { }; -static inline int kvm_init(int smp_cpus) -{ -return 0; -} - static inline void kvm_inject_x86_mce(CPUState *cenv, int bank, uint64_t status, uint64_t mcg_status, uint64_t addr, uint64_t misc, @@ -823,6 +806,18 @@ static inline void kvm_inject_x86_mce(CPUState *cenv, int bank, #endif /* !CONFIG_KVM */ +/*! + * \brief Create new KVM context + * + * This creates a new kvm_context. A KVM context is a small area of data that + * holds information about the KVM instance that gets created by this call.\n + * This should always be your first call to KVM. + * + * \param opaque Not used + * \return NULL on failure + */ +int kvm_init(int smp_cpus); + int kvm_main_loop(void); int kvm_init_ap(void); int kvm_vcpu_inited(CPUState *env); -- 1.7.0.1
[Qemu-devel] [PATCH 7/7] Declare no_hpet variable for all targets
From: Jes Sorensen We need to declare 'int no_hpet' for all targets to avoid build failure on no x86 builds. Signed-off-by: Jes Sorensen --- vl.c |2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/vl.c b/vl.c index 79f91d5..c2e99fc 100644 --- a/vl.c +++ b/vl.c @@ -207,9 +207,7 @@ int smp_cores = 1; int smp_threads = 1; const char *vnc_display; int acpi_enabled = 1; -#ifdef TARGET_I386 int no_hpet = 0; -#endif int fd_bootchk = 1; int no_reboot = 0; int no_shutdown = 0; -- 1.7.0.1
[Qemu-devel] Re: [PATCH V5 1/2] qemu: Generic task offloading framework: threadlets
On 06/22/2010 01:18 PM, Gautham R Shenoy wrote: From: Aneesh Kumar K.V This patch creates a generic asynchronous-task-offloading infrastructure named threadlets. The core idea has been borrowed from the threading framework that is being used by paio. The reason for creating this generic infrastructure is so that other subsystems, such as virtio-9p could make use of it for offloading tasks that could block. The patch creates a global queue on-to which subsystems can queue their tasks to be executed asynchronously. The patch also provides API's that allow a subsystem to create a private queue with an associated pool of threads. [...@in.ibm.com: Facelift of the code, Documentation, cancel_threadlet and other helpers] Signed-off-by: Aneesh Kumar K.V Signed-off-by: Gautham R Shenoy --- Makefile.objs |3 + docs/async-support.txt | 141 qemu-threadlets.c | 170 qemu-threadlets.h | 48 ++ 4 files changed, 361 insertions(+), 1 deletions(-) create mode 100644 docs/async-support.txt create mode 100644 qemu-threadlets.c create mode 100644 qemu-threadlets.h diff --git a/Makefile.objs b/Makefile.objs index 1a942e5..5d48ace 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -9,6 +9,8 @@ qobject-obj-y += qerror.o block-obj-y = cutils.o cache-utils.o qemu-malloc.o qemu-option.o module.o block-obj-y += nbd.o block.o aio.o aes.o osdep.o qemu-config.o +block-obj-$(CONFIG_POSIX) += qemu-thread.o +block-obj-$(CONFIG_POSIX) += qemu-threadlets.o block-obj-$(CONFIG_POSIX) += posix-aio-compat.o block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o @@ -109,7 +111,6 @@ common-obj-y += iov.o common-obj-$(CONFIG_VNC_TLS) += vnc-tls.o vnc-auth-vencrypt.o common-obj-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o common-obj-$(CONFIG_COCOA) += cocoa.o -common-obj-$(CONFIG_IOTHREAD) += qemu-thread.o common-obj-y += notify.o event_notifier.o common-obj-y += qemu-timer.o diff --git a/docs/async-support.txt b/docs/async-support.txt new file mode 100644 index 000..0f12c8d --- /dev/null +++ b/docs/async-support.txt @@ -0,0 +1,141 @@ +== How to use the various asynchronous models supported in Qemu == + +== Threadlets == + +Q.1: What are threadlets ? +A.1: Threadlets is an infrastructure within QEMU that allows other subsystems + to offload possibly blocking work to a queue to be processed by a pool + of threads asynchrnonously. + +Q.2: When would one want to use threadlets ? +A.2: Threadlets are useful when there are operations that can be performed + outside the context of the VCPU/IO threads inorder to free these latter + to service any other guest requests. + +Q.3: I have some work that can be executed in an asynchronous context. How + should I go about it ? +A.3: One could follow the steps listed below: + + - Define a function which would do the asynchrnous work. + void my_threadlet_func(ThreadletWork *work) + { + } + + - Declare an object of type ThreadletWork; + ThreadletWork work; + + + - Assign a value to the "func" member of ThreadletWork object. + work.func = my_threadlet_func; + + - Submit the threadlet to the global queue. + submit_threadlet(&work); + + - Continue servicing some other guest operations. + +Q.4: I want to my_threadlet_func to access some non-global data. How do I do + that ? +A.4: Suppose you want my_threadlet_func to access some non-global data-object + of type myPrivateData. In that case one could follow the following steps. + + - Define a member of the type ThreadletWork within myPrivateData. + typdef myPrivateData { + ...; + ...; + ...; + ThreadletWork work; + } myPrivateData; + + myPrivateData myData; + + - Initialize myData.work as described in A.3 + myData.work.func = my_threadlet_func; + submit_threadlet(&myData.work); + + - Access the myData object inside my_threadlet_func() using container_of + primitive + void my_threadlet_func(ThreadletWork *work) + { + myPrivateData *mydata_ptr; + mydata_ptr = container_of(work, myPrivateData, work); + + /* mydata_ptr now points to myData object */ + } + +Q.5: Are there any precautions one must take while sharing data with the + Asynchrnous thread-pool ? +A.5: Yes, make sure that the helper function of the type my_threadlet_func() + does not access/modify data when it can be accessed or modified in the + context of VCPU thread or IO thread. This is because the asynchronous + threads in the pool can run in parallel with the VCPU/IOThreads as shown + in the figure. + + A typical workflow is as follows: + + VCPU/IOThread + | + | (1) + | + V +Offload work
[Qemu-devel] [PATCH 4/7] Build certain drivers for MIPS as well.
From: Jes Sorensen pcspk.o i8254.o acpi.o acpi_piix4.o are all required for MIPS as well, add them to Makefile.target accordingly. Signed-off-by: Jes Sorensen --- Makefile.target |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/Makefile.target b/Makefile.target index b0bb434..730e392 100644 --- a/Makefile.target +++ b/Makefile.target @@ -245,6 +245,8 @@ obj-ppc-$(CONFIG_KVM) += kvm_ppc.o obj-ppc-$(CONFIG_FDT) += device_tree.o obj-mips-y = mips_r4k.o mips_jazz.o mips_malta.o mips_mipssim.o +obj-mips-y += pcspk.o i8254.o +obj-mips-y += acpi.o acpi_piix4.o obj-mips-y += mips_addr.o mips_timer.o mips_int.o obj-mips-y += vga.o i8259.o obj-mips-y += g364fb.o jazz_led.o -- 1.7.0.1
[Qemu-devel] [PATCH 1/7] Only call kvm_set_irqfd() if CONFIG_KVM is defined
From: Jes Sorensen This avoids breaking the build for non KVM targets where kvm_set_irqfd() is not defined. Signed-off-by: Jes Sorensen --- hw/virtio-pci.c |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index d497eae..938937e 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -430,6 +430,7 @@ static void virtio_pci_guest_notifier_read(void *opaque) static int virtio_pci_mask_notifier(PCIDevice *dev, unsigned vector, void *opaque, int masked) { +#ifdef CONFIG_KVM VirtQueue *vq = opaque; EventNotifier *notifier = virtio_queue_get_guest_notifier(vq); int r = kvm_set_irqfd(dev->msix_irq_entries[vector].gsi, @@ -446,6 +447,9 @@ static int virtio_pci_mask_notifier(PCIDevice *dev, unsigned vector, NULL, NULL, NULL); } return 0; +#else +return -ENOSYS; +#endif } static int virtio_pci_set_guest_notifier(void *opaque, int n, bool assign) -- 1.7.0.1
[Qemu-devel] [PATCH 3/7] time_drift_fix is x86 only, rather than !ia64
From: Jes Sorensen time_drift_fix is only present on x86, not just on !ia64. This allows the code to build for other archs, like MIPS. Signed-off-by: Jes Sorensen --- hw/i8259.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/hw/i8259.c b/hw/i8259.c index a8ae069..e89d831 100644 --- a/hw/i8259.c +++ b/hw/i8259.c @@ -237,7 +237,7 @@ int pic_read_irq(PicState2 *s) if (irq >= 0) { pic_intack(&s->pics[0], irq); -#ifndef TARGET_IA64 +#ifdef TARGET_I386 if (time_drift_fix && irq == 0) { extern int64_t timer_acks, timer_ints_to_push; timer_acks++; -- 1.7.0.1
[Qemu-devel] [PATCH v4 0/7] Fix building qemu-kvm for non KVM target
From: Jes Sorensen Hi, This set of patches fixes building qemu-kvm for non KVM targets, as reported in http://sourceforge.net/tracker/?func=detail&atid=893831&aid=2984626&group_id=180599 One of the main problem is that we have a tendency to move things from Makefile.objs to Makefile.target in order to be able to use TARGET_I386 etc in hw/*.c files. IMHO we need to start clamping down on this harder and move things into separate files rather than the #ifdef hacks. Hence this patch fixes the short term problem, but there is more work to do for the longer term. This version is just a rebase against the latest version of qemu-kvm, and I fixed up the commit messages a bit to remove a couple of duplicated statements. Cheers, Jes Jes Sorensen (7): Only call kvm_set_irqfd() if CONFIG_KVM is defined Remove duplicate kvm_init() stub from qemu-kvm.h time_drift_fix is x86 only, rather than !ia64 Build certain drivers for MIPS as well. Only export phys_mem create functions for !CONFIG_USER_ONLY builds Only treat KVM specific cmdline options for KVM enabled builds Declare no_hpet variable for all targets Makefile.target |2 ++ hw/i8259.c |2 +- hw/virtio-pci.c |4 qemu-kvm.h | 31 ++- vl.c|4 ++-- 5 files changed, 23 insertions(+), 20 deletions(-)
[Qemu-devel] Re: KVM call agenda for June 22
On 06/22/2010 07:04 AM, Juan Quintela wrote: Chris Wright wrote: Please send in any agenda items you are interested in covering. If we have a lack of agenda items I'll cancel the week's call. As we have no agenda. This week call gets cancelled. Could we send the agenda note out a little bit earlier? The note arrived at 12:55am CST and we decided we had no agenda at 7:04am CST. That's a pretty short window and I imagine a lot of people in the US are not actually awake during that period of time :-) Regards, Anthony Liguori Thanks, Juan. thanks, -chris -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[Qemu-devel] Re: block: format vs. protocol, and how they stack
On 06/22/2010 03:10 AM, Kevin Wolf wrote: Am 21.06.2010 17:34, schrieb Anthony Liguori: On 06/21/2010 09:01 AM, Kevin Wolf wrote: No, what I'm saying is that even in your model -blockdev format=qcow2,file=image.qcow2,id=blk1 becomes qcow2 -> file automatically, whereas -blockdev format=vvfat,file=/tmp/dir/,id=blk1 doesn't become vvfat -> file, but stays just vvfat. I should say, that -blockdev format= vs. -blockdev transport= is definitely at a place where I don't care that much. The things that I think are most important are: 1) That we have structured options that map well to config file without trickery to do nesting 2) That we don't automagically pass options through from the first layer down to subsequent layers Does this mean that you need to specify the protocol explicitly for any non-trivial case? So if you want to use just default for everything you can use -blockdev id=foo,format=qcow2,file=foo.qcow2 Yes. I think we should explicitly support an option like file. and it will be turned into something sensible automagically (namely adding a file blockdev underneath and passing the file parameter to that one), but if you want to change an option, you need to specify both? -blockdev id=foo,format=qcow2,parent=foo_file -blockdev id=foo_file,format=file,file=foo.qcow2,cache=off What about read-only? Good question. If a user specifies file, I think the (or generic block layer) should have wide latitude to decide how to creating that backing format which could include propagating options that it thinks are reasonable (like readonly). My concern is seeing something like: -blockdev id=foo,format=qcow2,file=blah.img,funkyopt=value or: -blockdev id=foo,format=qcow2,protocol=[file=blah.img,funkyopt=value] I think the later syntax is overwhelming. If the semantics of the former syntax is "passthrough any options we don't understand at this layer", I'm afraid it gets too confusing about which level actually processed the option (and it certainly doesn't deal with propagation). Regards, Anthony Liguori Is it something that must be specified for each single node in the chain to actually get the right semantics? Kevin
[Qemu-devel] Re: [PATCH v2 0/3] pci: fix resource leak in pci qdev and hot plug.
On Tue, Jun 22, 2010 at 11:55:32AM +0900, Isaku Yamahata wrote: > pci qdev exit code patch(pci_unregister_device) doesn't release > all the resource allocated by pci qdev initialization.(pci_qdev_init) > This patch series sorts it out and make pci::hotplug error code to the caller. > > Isaku Yamahata (3): > pci: fix memory leak of PCIDevice::romfile. > pci: option rom clean up. > pci hotplug: make pci hotplug return value to caller. Applied (tweaked 3/3 to assert on unregister: if we can not cleanup, we are in an unknown state). > hw/pci.c | 26 ++ > 1 files changed, 22 insertions(+), 4 deletions(-)
Re: [Qemu-devel] [PATCH] stop cpus before forking.
On 06/16/2010 07:58 PM, Glauber Costa wrote: It is, and the fix would be to create the APIC memory slot as sharable across forks (should be easy to fix in the kernel). Kernel pages are already shared across fork, no? What are kernel pages in this context? The APIC access page is an ordinary user page. -- error compiling committee.c: too many arguments to function
[Qemu-devel] Re: KVM call agenda for June 22
Chris Wright wrote: > Please send in any agenda items you are interested in covering. > > If we have a lack of agenda items I'll cancel the week's call. As we have no agenda. This week call gets cancelled. Thanks, Juan. > thanks, > -chris
Re: [Qemu-devel] Re: [PATCH v2] QMP: Introduce the documentation for query-netdev and info netdev
Jan Kiszka writes: > Markus Armbruster wrote: >> Jan Kiszka writes: >> >>> Luiz Capitulino wrote: On Fri, 18 Jun 2010 13:26:27 -0300 Miguel Di Ciurcio Filho wrote: > These commands show the information about active backend network devices. > > Signed-off-by: Miguel Di Ciurcio Filho > --- > qemu-monitor.hx | 105 > +++ > 1 files changed, 105 insertions(+), 0 deletions(-) > > diff --git a/qemu-monitor.hx b/qemu-monitor.hx > index 9f62b94..8fc5ed6 100644 > --- a/qemu-monitor.hx > +++ b/qemu-monitor.hx > @@ -1674,6 +1674,111 @@ show the various VLANs and the associated devices > ETEXI > > STEXI > +...@item info netdev > +show information about the current backend network devices > +ETEXI > +SQMP > +query-netdev > + > + > +Each device is represented by a json-object. The returned value is a > json-array > +of all devices. > + > +Each json-object contains the following: > + > +- "id": the device's ID, must be unique (json-string) There were some talking about changing this to 'device. Jan, Markus? >>> Only for qdev. Should be a different namespace here. >> >> Huh? >> >> We need to point to the NIC here, i.e. we need a unambigous name. >> Device ID is fine, but it's optional. Canonical qdev path? > > Unless I'm still on the wrong track: 'peer' should point to the > front-end, this ID describes the back-end, and that's not a qdev thing. > Still, dumping the peer's qdev path along its (optional) ID might be > worth a thought. One of us is probably confused, and it could well be me :) Frontend / backend is difficult for the directionally challenged, so let's use "guest NIC" and "host network device". A guest NIC's peer points to a host network device, and vice versa. query-netdev is about host network devices. Thus, peer identifes a guest NIC.
[Qemu-devel] Re: [PATCH v2 3/3] pci hotplug: make pci hotplug return value to caller.
On Tue, Jun 22, 2010 at 11:55:35AM +0900, Isaku Yamahata wrote: > make pci hotplug callback return value to caller. > And when returning error, allocated resources are freed. > > Signed-off-by: Isaku Yamahata > --- > hw/pci.c | 15 +++ > 1 files changed, 11 insertions(+), 4 deletions(-) > > diff --git a/hw/pci.c b/hw/pci.c > index 75acbd3..76418c5 100644 > --- a/hw/pci.c > +++ b/hw/pci.c > @@ -1626,8 +1626,16 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo > *base) > pci_dev->romfile = qemu_strdup(info->romfile); > pci_add_option_rom(pci_dev); > > -if (qdev->hotplugged) > -bus->hotplug(bus->hotplug_qdev, pci_dev, 1); > +if (qdev->hotplugged) { > +rc = bus->hotplug(bus->hotplug_qdev, pci_dev, 1); > +if (rc != 0) { > +int rc1 = pci_unregister_device(&pci_dev->qdev); > +if (rc1) { > +error_report("pci_unregister_device failed in > pci_qdev_init.\n"); > +} This should be assert. > +return rc; > +} > +} > return 0; > } > > @@ -1635,8 +1643,7 @@ static int pci_unplug_device(DeviceState *qdev) > { > PCIDevice *dev = DO_UPCAST(PCIDevice, qdev, qdev); > > -dev->bus->hotplug(dev->bus->hotplug_qdev, dev, 0); > -return 0; > +return dev->bus->hotplug(dev->bus->hotplug_qdev, dev, 0); > } > > void pci_qdev_register(PCIDeviceInfo *info) > -- > 1.6.6.1
[Qemu-devel] [PATCH V5 2/2] qemu: Convert AIO code to use threadlets.
This patch makes the paio subsystem use the threadlet framework thereby decoupling asynchronous threading framework portion out of posix-aio-compat.c The patch has been tested with fstress. Signed-off-by: Gautham R Shenoy --- posix-aio-compat.c | 152 1 files changed, 24 insertions(+), 128 deletions(-) diff --git a/posix-aio-compat.c b/posix-aio-compat.c index b43c531..370b679 100644 --- a/posix-aio-compat.c +++ b/posix-aio-compat.c @@ -28,6 +28,7 @@ #include "block_int.h" #include "block/raw-posix-aio.h" +#include "qemu-threadlets.h" struct qemu_paiocb { @@ -50,6 +51,7 @@ struct qemu_paiocb { struct qemu_paiocb *next; int async_context_id; +ThreadletWork work; }; typedef struct PosixAioState { @@ -57,16 +59,6 @@ typedef struct PosixAioState { struct qemu_paiocb *first_aio; } PosixAioState; - -static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; -static pthread_t thread_id; -static pthread_attr_t attr; -static int max_threads = 64; -static int cur_threads = 0; -static int idle_threads = 0; -static QTAILQ_HEAD(, qemu_paiocb) request_list; - #ifdef CONFIG_PREADV static int preadv_present = 1; #else @@ -84,39 +76,6 @@ static void die(const char *what) die2(errno, what); } -static void mutex_lock(pthread_mutex_t *mutex) -{ -int ret = pthread_mutex_lock(mutex); -if (ret) die2(ret, "pthread_mutex_lock"); -} - -static void mutex_unlock(pthread_mutex_t *mutex) -{ -int ret = pthread_mutex_unlock(mutex); -if (ret) die2(ret, "pthread_mutex_unlock"); -} - -static int cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, - struct timespec *ts) -{ -int ret = pthread_cond_timedwait(cond, mutex, ts); -if (ret && ret != ETIMEDOUT) die2(ret, "pthread_cond_timedwait"); -return ret; -} - -static void cond_signal(pthread_cond_t *cond) -{ -int ret = pthread_cond_signal(cond); -if (ret) die2(ret, "pthread_cond_signal"); -} - -static void thread_create(pthread_t *thread, pthread_attr_t *attr, - void *(*start_routine)(void*), void *arg) -{ -int ret = pthread_create(thread, attr, start_routine, arg); -if (ret) die2(ret, "pthread_create"); -} - static ssize_t handle_aiocb_ioctl(struct qemu_paiocb *aiocb) { int ret; @@ -300,47 +259,27 @@ static ssize_t handle_aiocb_rw(struct qemu_paiocb *aiocb) return nbytes; } -static void *aio_thread(void *unused) +static void aio_thread(ThreadletWork *work) { -pid_t pid; - -pid = getpid(); - -while (1) { -struct qemu_paiocb *aiocb; -ssize_t ret = 0; -qemu_timeval tv; -struct timespec ts; - -qemu_gettimeofday(&tv); -ts.tv_sec = tv.tv_sec + 10; -ts.tv_nsec = 0; -mutex_lock(&lock); +pid_t pid; -while (QTAILQ_EMPTY(&request_list) && - !(ret == ETIMEDOUT)) { -ret = cond_timedwait(&cond, &lock, &ts); -} +struct qemu_paiocb *aiocb = container_of(work, struct qemu_paiocb, work); +ssize_t ret = 0; -if (QTAILQ_EMPTY(&request_list)) -break; +pid = getpid(); -aiocb = QTAILQ_FIRST(&request_list); -QTAILQ_REMOVE(&request_list, aiocb, node); -aiocb->active = 1; -idle_threads--; -mutex_unlock(&lock); +aiocb->active = 1; -switch (aiocb->aio_type & QEMU_AIO_TYPE_MASK) { -case QEMU_AIO_READ: -case QEMU_AIO_WRITE: +switch (aiocb->aio_type & QEMU_AIO_TYPE_MASK) { +case QEMU_AIO_READ: +case QEMU_AIO_WRITE: ret = handle_aiocb_rw(aiocb); break; -case QEMU_AIO_FLUSH: -ret = handle_aiocb_flush(aiocb); -break; -case QEMU_AIO_IOCTL: +case QEMU_AIO_FLUSH: +ret = handle_aiocb_flush(aiocb); +break; +case QEMU_AIO_IOCTL: ret = handle_aiocb_ioctl(aiocb); break; default: @@ -349,57 +288,25 @@ static void *aio_thread(void *unused) break; } -mutex_lock(&lock); -aiocb->ret = ret; -idle_threads++; -mutex_unlock(&lock); +aiocb->ret = ret; -if (kill(pid, aiocb->ev_signo)) die("kill failed"); -} - -idle_threads--; -cur_threads--; -mutex_unlock(&lock); - -return NULL; -} - -static void spawn_thread(void) -{ -sigset_t set, oldset; - -cur_threads++; -idle_threads++; - -/* block all signals */ -if (sigfillset(&set)) die("sigfillset"); -if (sigprocmask(SIG_SETMASK, &set, &oldset)) die("sigprocmask"); - -thread_create(&thread_id, &attr, aio_thread, NULL); - -if (sigprocmask(SIG_SETMASK, &oldset, NULL)) die("sigprocmask restore"); +if (kill(pid, aiocb->ev_signo)) die("kill failed"); } static void qemu_paio_submit(struct qemu_paiocb *aiocb) { aioc
[Qemu-devel] [PATCH V5 1/2] qemu: Generic task offloading framework: threadlets
From: Aneesh Kumar K.V This patch creates a generic asynchronous-task-offloading infrastructure named threadlets. The core idea has been borrowed from the threading framework that is being used by paio. The reason for creating this generic infrastructure is so that other subsystems, such as virtio-9p could make use of it for offloading tasks that could block. The patch creates a global queue on-to which subsystems can queue their tasks to be executed asynchronously. The patch also provides API's that allow a subsystem to create a private queue with an associated pool of threads. [...@in.ibm.com: Facelift of the code, Documentation, cancel_threadlet and other helpers] Signed-off-by: Aneesh Kumar K.V Signed-off-by: Gautham R Shenoy --- Makefile.objs |3 + docs/async-support.txt | 141 qemu-threadlets.c | 170 qemu-threadlets.h | 48 ++ 4 files changed, 361 insertions(+), 1 deletions(-) create mode 100644 docs/async-support.txt create mode 100644 qemu-threadlets.c create mode 100644 qemu-threadlets.h diff --git a/Makefile.objs b/Makefile.objs index 1a942e5..5d48ace 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -9,6 +9,8 @@ qobject-obj-y += qerror.o block-obj-y = cutils.o cache-utils.o qemu-malloc.o qemu-option.o module.o block-obj-y += nbd.o block.o aio.o aes.o osdep.o qemu-config.o +block-obj-$(CONFIG_POSIX) += qemu-thread.o +block-obj-$(CONFIG_POSIX) += qemu-threadlets.o block-obj-$(CONFIG_POSIX) += posix-aio-compat.o block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o @@ -109,7 +111,6 @@ common-obj-y += iov.o common-obj-$(CONFIG_VNC_TLS) += vnc-tls.o vnc-auth-vencrypt.o common-obj-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o common-obj-$(CONFIG_COCOA) += cocoa.o -common-obj-$(CONFIG_IOTHREAD) += qemu-thread.o common-obj-y += notify.o event_notifier.o common-obj-y += qemu-timer.o diff --git a/docs/async-support.txt b/docs/async-support.txt new file mode 100644 index 000..0f12c8d --- /dev/null +++ b/docs/async-support.txt @@ -0,0 +1,141 @@ +== How to use the various asynchronous models supported in Qemu == + +== Threadlets == + +Q.1: What are threadlets ? +A.1: Threadlets is an infrastructure within QEMU that allows other subsystems + to offload possibly blocking work to a queue to be processed by a pool + of threads asynchrnonously. + +Q.2: When would one want to use threadlets ? +A.2: Threadlets are useful when there are operations that can be performed + outside the context of the VCPU/IO threads inorder to free these latter + to service any other guest requests. + +Q.3: I have some work that can be executed in an asynchronous context. How + should I go about it ? +A.3: One could follow the steps listed below: + + - Define a function which would do the asynchrnous work. + void my_threadlet_func(ThreadletWork *work) + { + } + + - Declare an object of type ThreadletWork; + ThreadletWork work; + + + - Assign a value to the "func" member of ThreadletWork object. + work.func = my_threadlet_func; + + - Submit the threadlet to the global queue. + submit_threadlet(&work); + + - Continue servicing some other guest operations. + +Q.4: I want to my_threadlet_func to access some non-global data. How do I do + that ? +A.4: Suppose you want my_threadlet_func to access some non-global data-object + of type myPrivateData. In that case one could follow the following steps. + + - Define a member of the type ThreadletWork within myPrivateData. + typdef myPrivateData { + ...; + ...; + ...; + ThreadletWork work; + } myPrivateData; + + myPrivateData myData; + + - Initialize myData.work as described in A.3 + myData.work.func = my_threadlet_func; + submit_threadlet(&myData.work); + + - Access the myData object inside my_threadlet_func() using container_of + primitive + void my_threadlet_func(ThreadletWork *work) + { + myPrivateData *mydata_ptr; + mydata_ptr = container_of(work, myPrivateData, work); + + /* mydata_ptr now points to myData object */ + } + +Q.5: Are there any precautions one must take while sharing data with the + Asynchrnous thread-pool ? +A.5: Yes, make sure that the helper function of the type my_threadlet_func() + does not access/modify data when it can be accessed or modified in the + context of VCPU thread or IO thread. This is because the asynchronous + threads in the pool can run in parallel with the VCPU/IOThreads as shown + in the figure. + + A typical workflow is as follows: + + VCPU/IOThread + | + | (1) + | + V +Offload work (2) + |---> to threadlets ---
[Qemu-devel] [PATCH V5 0/2] Threadlets: A generic task offloading framework
Hi, This is the v5 of the patch-series to have a generic asynchronous task offloading framework (called threadlets) within qemu. V4 can be found here: http://lists.gnu.org/archive/html/qemu-devel/2010-06/msg02152.html Changes from V4: = - Updated the Makefile to make the object files depend on CONFIG_POSIX. - Did away with the pthread_barrier_init() and pthread_barrier_wait(). - Did away with flush_threadlet_queue() helper. - Fixed the attribution in copyright, helper names. - Fixed the idle-thread-exit logic. - Added documentation in docs/ Description = This patch series decouples the asynchronous threading framework implementation from posix-aio-compat.c to implement a generic asynchronous task offloading threading framework called threadlets which can be used by other subsystems within QEMU. Currently within QEMU, the AIO subsystem (paio) creates a bunch of asynchronous threads to offload any blocking operations so that the vcpu threads and the IO thread can go back to servicing any other guest requests. This offloading framework can be used by subsystems such as virtio-9p, Asynchronous encoding for vnc-server, so that the vcpu thread can offload blocking operations on to the asynchronous threads and resume servicing any other guest requests. The asynchronous threads, after finishing the blocking operations can then transfer the control over to the IO thread so that the latter can handle the post_blocking_operation(). The patch series passed fsstress test without any issues. Could it be considered for inclusion ? --- Aneesh Kumar K.V (1): qemu: Generic task offloading framework: threadlets Gautham R Shenoy (1): qemu: Convert AIO code to use threadlets. Makefile.objs |3 + docs/async-support.txt | 141 posix-aio-compat.c | 152 +++ qemu-threadlets.c | 170 qemu-threadlets.h | 48 ++ 5 files changed, 385 insertions(+), 129 deletions(-) create mode 100644 docs/async-support.txt create mode 100644 qemu-threadlets.c create mode 100644 qemu-threadlets.h -- Thanks and Regards gautham.
[Qemu-devel] [PATCH 2/2] qcow2: Don't try to check tables that couldn't be loaded
Trying to check them leads to a second error message which is more confusing than helpful: Can't get refcount for cluster 0: Invalid argument ERROR cluster 0 refcount=-22 reference=1 Signed-off-by: Kevin Wolf --- block/qcow2-refcount.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index cedf57e..4a96d98 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -1174,6 +1174,7 @@ int qcow2_check_refcounts(BlockDriverState *bs) if (refcount1 < 0) { fprintf(stderr, "Can't get refcount for cluster %d: %s\n", i, strerror(-refcount1)); +continue; } refcount2 = refcount_table[i]; -- 1.6.6.1
[Qemu-devel] [PATCH 1/2] qcow2: Fix qemu-img check segfault on corrupted images
With corrupted images, we can easily get an cluster index that exceeds the array size of the temporary refcount table. Signed-off-by: Kevin Wolf --- block/qcow2-refcount.c | 14 +++--- 1 files changed, 11 insertions(+), 3 deletions(-) diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index c2d0e61..cedf57e 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -1140,22 +1140,30 @@ int qcow2_check_refcounts(BlockDriverState *bs) s->refcount_table_offset, s->refcount_table_size * sizeof(uint64_t)); for(i = 0; i < s->refcount_table_size; i++) { -int64_t offset; +uint64_t offset, cluster; offset = s->refcount_table[i]; +cluster = offset >> s->cluster_bits; /* Refcount blocks are cluster aligned */ if (offset & (s->cluster_size - 1)) { fprintf(stderr, "ERROR refcount block %d is not " "cluster aligned; refcount table entry corrupted\n", i); errors++; +continue; +} + +if (cluster >= nb_clusters) { +fprintf(stderr, "ERROR refcount block %d is outside image\n", i); +errors++; +continue; } if (offset != 0) { errors += inc_refcounts(bs, refcount_table, nb_clusters, offset, s->cluster_size); -if (refcount_table[offset / s->cluster_size] != 1) { +if (refcount_table[cluster] != 1) { fprintf(stderr, "ERROR refcount block %d refcount=%d\n", -i, refcount_table[offset / s->cluster_size]); +i, refcount_table[cluster]); } } } -- 1.6.6.1
[Qemu-devel] [PATCH 0/2] qcow2: qemu-img check fixes
Kevin Wolf (2): qcow2: Fix qemu-img check segfault on corrupted images qcow2: Don't try to check tables that couldn't be loaded block/qcow2-refcount.c | 15 --- 1 files changed, 12 insertions(+), 3 deletions(-)
Re: [Qemu-devel] u-boot on 'qemu-system-mips64 -M mips'
Thank you for your reply. > so EPC is set to bfc0ee94 which is : > movn s1,v1,v0 > >> From what I understand when reading the mips IV manual, the movn ins is > only for mips IV / 32bit and not 64bit. Looks like the qemu code has > been written following this. (This also explains why qemu-system-mips is > fine and not qemu-system-mips64). > > Arnaud I understand that the relaation between MIPS32/MIPS64 arch is upper compatible (from MIPS32 to MIPS64). I wonder if this fact (the movn ins is only for mips IV / 32bit and not 64bit) be true, umm. Please let me know the list of instructions like this (32/64 not compatible) if you know, or give me a hint to investigate? Noritata KAWAKATSU. (2010/06/22 18:09), Arnaud Patard (Rtp) wrote: KAWAKATSU Noritaka writes: Hi, Hi, I have built u-boot binary for 'qemu-system-mips -M mips'. It is fine to run ths u-boot binary. But the same u-boot binary does not run on 'qemu-system-mips64 -M mips'. I do not understand what happends on the qemu-mips64 execution. Is this a bug for qemu-system-mips64 ? Or should I build u-boot binary by another configuration? -- * u-boot building steps (1) build the gcc 4.5 cross-compiler for mips from the source. (2) build u-boot(2010.03) by the (1)compiler. (3) copy the u-boot.bin to /usr/share/qemu/mips_bios.bin * qemu(mips) execution command $ qemu-system-mips -L /usr/share/qemu -d in_asm -nographic * get /tmp/qemu.log the execution seems fine. * qemu(mips64) execution command $ qemu-system-mips64 -L /usr/share/qemu -d in_asm -nographic * get /tmp/qemu.log the execution seems not fine. Something is wrong? - /tmp/qemu.log (last 10-20 lines) [qemu-system-mips64] IN: 0xbfc0ee8c: xori v0,v0,0x3d 0xbfc0ee90: li v1,-1 0xbfc0ee94: movn s1,v1,v0 0xbfc0ee98: lw ra,52(sp) 0xbfc0ee9c: move v0,s1 0xbfc0eea0: lw s3,48(sp) 0xbfc0eea4: lw s2,44(sp) 0xbfc0eea8: lw s1,40(sp) 0xbfc0eeac: lw s0,36(sp) 0xbfc0eeb0: jr ra 0xbfc0eeb4: addiu sp,sp,56 helper_raise_exception_err: 20 0 do_interrupt enter: PC bfc0ee94 EPC reserved instruction exception do_interrupt: PC bfc00380 EPC bfc0ee94 cause 10 S 0042 C 00808428 A D so EPC is set to bfc0ee94 which is : movn s1,v1,v0 From what I understand when reading the mips IV manual, the movn ins is only for mips IV / 32bit and not 64bit. Looks like the qemu code has been written following this. (This also explains why qemu-system-mips is fine and not qemu-system-mips64). Arnaud
Re: [Qemu-devel] [PATCH] qemu-option: Reject anti-social IDs
On 06/08/2010 02:54 PM, Markus Armbruster wrote: Restrict IDs to letters, digits, '-', '.', '_', starting with a letter. This takes care of '/' in qdev IDs breaking qbus_find(). Broke autotest (used leading numeric char). Patch posted. -- error compiling committee.c: too many arguments to function
[Qemu-devel] [PATCH v2] seabios: acpi: allow qemu to load dsdt as external acpi table.
allow qemu to load dsdt as external acpi table. Signed-off-by: Isaku Yamahata --- changes v1 -> v2. - load qemu table first and they try default dsdt table if qemu doesn't supply dsdt. Thus unnecessary malloc_high()/free() is avoided. --- src/acpi.c | 49 + 1 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/acpi.c b/src/acpi.c index 0559443..b75f9af 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -126,6 +126,11 @@ struct fadt_descriptor_rev1 } PACKED; /* + * Differentiated System Descrition Table (DSDT) + */ +#define DSDT_SIGNATURE 0x54445344 // DSDT + +/* * MADT values and structures */ @@ -280,6 +285,11 @@ static inline u32 cpu_to_le32(u32 x) return x; } +static inline u32 le32_to_cpu(u32 x) +{ +return x; +} + static void build_header(struct acpi_table_header *h, u32 sig, int len, u8 rev) { @@ -295,14 +305,20 @@ build_header(struct acpi_table_header *h, u32 sig, int len, u8 rev) h->checksum -= checksum(h, len); } +static void fill_dsdt(struct fadt_descriptor_rev1 *fadt, void *dsdt) +{ +fadt->dsdt = cpu_to_le32((u32)dsdt); +fadt->checksum -= checksum(fadt, sizeof(*fadt)); +dprintf(1, "ACPI DSDT=%p\n", dsdt); +} + static void* build_fadt(int bdf) { struct fadt_descriptor_rev1 *fadt = malloc_high(sizeof(*fadt)); struct facs_descriptor_rev1 *facs = memalign_high(64, sizeof(*facs)); -void *dsdt = malloc_high(sizeof(AmlCode)); -if (!fadt || !facs || !dsdt) { +if (!fadt || !facs) { warn_noalloc(); return NULL; } @@ -312,13 +328,11 @@ build_fadt(int bdf) facs->signature = FACS_SIGNATURE; facs->length = cpu_to_le32(sizeof(*facs)); -/* DSDT */ -memcpy(dsdt, AmlCode, sizeof(AmlCode)); - /* FADT */ memset(fadt, 0, sizeof(*fadt)); fadt->firmware_ctrl = cpu_to_le32((u32)facs); -fadt->dsdt = cpu_to_le32((u32)dsdt); +fadt->dsdt = 0; /* dsdt will be filled later in acpi_bios_init() +by fill_dsdt() */ fadt->model = 1; fadt->reserved1 = 0; int pm_sci_int = pci_config_readb(bdf, PCI_INTERRUPT_LINE); @@ -634,7 +648,8 @@ acpi_bios_init(void) } while(0) // Add tables -ACPI_INIT_TABLE(build_fadt(bdf)); +struct fadt_descriptor_rev1 *fadt = build_fadt(bdf); +ACPI_INIT_TABLE(fadt); ACPI_INIT_TABLE(build_ssdt()); ACPI_INIT_TABLE(build_madt()); ACPI_INIT_TABLE(build_hpet()); @@ -649,12 +664,30 @@ acpi_bios_init(void) warn_noalloc(); continue; } -ACPI_INIT_TABLE(qemu_cfg_next_acpi_table_load(addr, len)); +struct acpi_table_header *header = +qemu_cfg_next_acpi_table_load(addr, len); +if (header->signature == DSDT_SIGNATURE) { +if (fadt) { +fill_dsdt(fadt, addr); +} +} else { +ACPI_INIT_TABLE(header); +} if (tbl_idx == MAX_ACPI_TABLES) { warn_noalloc(); break; } } +if (fadt && !fadt->dsdt) { +/* default DSDT */ +void *dsdt = malloc_high(sizeof(AmlCode)); +if (!dsdt) { +warn_noalloc(); +return; +} +memcpy(dsdt, AmlCode, sizeof(AmlCode)); +fill_dsdt(fadt, dsdt); +} struct rsdt_descriptor_rev1 *rsdt; size_t rsdt_len = sizeof(*rsdt) + sizeof(u32) * tbl_idx; -- 1.6.6.1
[Qemu-devel] [PATCH v2 0/8] seabios: pci: multi pci bus support
Changes v1 -> v2: - simplified foreachpci_in_bus() - add overlap check during pci bar assignemnt. - use c99 initialization. Patch description: This patch set allows seabios to initialize multi pci bus and 64bit BAR. Currently seabios is able to initialize only pci root bus. However multi pci bus support is wanted because - more pci bus is wanted in qemu for many slots - pci express support is commin in qemu which requires multi pci bus. those patches on Qemu part are under way, though. Isaku Yamahata (8): seabios: pci: introduce foreachpci_in_bus() helper macro. seabios: pciinit: factor out pci bar region allocation logic. seabios: pciinit: make pci memory space assignment 64bit aware. seabios: pciinit: make pci bar assigner preferchable memory aware. seabios: pciinit: factor out bar offset calculation. seabios: pciinit: make bar offset calculation pci bridge aware. seabios: pciinit: pci bridge bus initialization. seabios: pciinit: initialize pci bridge filtering registers. src/config.h | 17 +++ src/pci.h | 10 ++ src/pciinit.c | 324 + 3 files changed, 306 insertions(+), 45 deletions(-)
Re: [Qemu-devel] Re: [PATCH v2] QMP: Introduce the documentation for query-netdev and info netdev
Markus Armbruster wrote: > Jan Kiszka writes: > >> Luiz Capitulino wrote: >>> On Fri, 18 Jun 2010 13:26:27 -0300 >>> Miguel Di Ciurcio Filho wrote: >>> These commands show the information about active backend network devices. Signed-off-by: Miguel Di Ciurcio Filho --- qemu-monitor.hx | 105 +++ 1 files changed, 105 insertions(+), 0 deletions(-) diff --git a/qemu-monitor.hx b/qemu-monitor.hx index 9f62b94..8fc5ed6 100644 --- a/qemu-monitor.hx +++ b/qemu-monitor.hx @@ -1674,6 +1674,111 @@ show the various VLANs and the associated devices ETEXI STEXI +...@item info netdev +show information about the current backend network devices +ETEXI +SQMP +query-netdev + + +Each device is represented by a json-object. The returned value is a json-array +of all devices. + +Each json-object contains the following: + +- "id": the device's ID, must be unique (json-string) >>> There were some talking about changing this to 'device. Jan, Markus? >> Only for qdev. Should be a different namespace here. > > Huh? > > We need to point to the NIC here, i.e. we need a unambigous name. > Device ID is fine, but it's optional. Canonical qdev path? Unless I'm still on the wrong track: 'peer' should point to the front-end, this ID describes the back-end, and that's not a qdev thing. Still, dumping the peer's qdev path along its (optional) ID might be worth a thought. Jan -- Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
Re: [Qemu-devel] u-boot on 'qemu-system-mips64 -M mips'
KAWAKATSU Noritaka writes: > Hi, Hi, > > I have built u-boot binary for 'qemu-system-mips -M mips'. > It is fine to run ths u-boot binary. > But the same u-boot binary does not run on 'qemu-system-mips64 -M mips'. > > I do not understand what happends on the qemu-mips64 execution. > Is this a bug for qemu-system-mips64 ? > Or should I build u-boot binary by another configuration? > > -- > * u-boot building steps > (1) build the gcc 4.5 cross-compiler for mips from the source. > (2) build u-boot(2010.03) by the (1)compiler. > (3) copy the u-boot.bin to /usr/share/qemu/mips_bios.bin > * qemu(mips) execution command > $ qemu-system-mips -L /usr/share/qemu -d in_asm -nographic > * get /tmp/qemu.log > the execution seems fine. > > * qemu(mips64) execution command > $ qemu-system-mips64 -L /usr/share/qemu -d in_asm -nographic > * get /tmp/qemu.log > the execution seems not fine. Something is wrong? > > > > - /tmp/qemu.log (last 10-20 lines) [qemu-system-mips64] > IN: > 0xbfc0ee8c: xori v0,v0,0x3d > 0xbfc0ee90: li v1,-1 > 0xbfc0ee94: movn s1,v1,v0 > 0xbfc0ee98: lw ra,52(sp) > 0xbfc0ee9c: move v0,s1 > 0xbfc0eea0: lw s3,48(sp) > 0xbfc0eea4: lw s2,44(sp) > 0xbfc0eea8: lw s1,40(sp) > 0xbfc0eeac: lw s0,36(sp) > 0xbfc0eeb0: jr ra > 0xbfc0eeb4: addiusp,sp,56 > > helper_raise_exception_err: 20 0 > do_interrupt enter: PC bfc0ee94 EPC reserved > instruction exception > do_interrupt: PC bfc00380 EPC bfc0ee94 cause 10 > S 0042 C 00808428 A D so EPC is set to bfc0ee94 which is : movn s1,v1,v0 >From what I understand when reading the mips IV manual, the movn ins is only for mips IV / 32bit and not 64bit. Looks like the qemu code has been written following this. (This also explains why qemu-system-mips is fine and not qemu-system-mips64). Arnaud
[Qemu-devel] [PATCH v2 2/8] seabios: pciinit: factor out pci bar region allocation logic.
factor out pci bar region allocation logic. Signed-off-by: Isaku Yamahata --- src/pciinit.c | 84 - 1 files changed, 47 insertions(+), 37 deletions(-) diff --git a/src/pciinit.c b/src/pciinit.c index 0556ee2..488c77b 100644 --- a/src/pciinit.c +++ b/src/pciinit.c @@ -37,6 +37,50 @@ static void pci_set_io_region_addr(u16 bdf, int region_num, u32 addr) dprintf(1, "region %d: 0x%08x\n", region_num, addr); } +static void pci_bios_allocate_region(u16 bdf, int region_num) +{ +u32 *paddr; +int ofs; +if (region_num == PCI_ROM_SLOT) +ofs = PCI_ROM_ADDRESS; +else +ofs = PCI_BASE_ADDRESS_0 + region_num * 4; + +u32 old = pci_config_readl(bdf, ofs); +u32 mask; +if (region_num == PCI_ROM_SLOT) { +mask = PCI_ROM_ADDRESS_MASK; +pci_config_writel(bdf, ofs, mask); +} else { +if (old & PCI_BASE_ADDRESS_SPACE_IO) +mask = PCI_BASE_ADDRESS_IO_MASK; +else +mask = PCI_BASE_ADDRESS_MEM_MASK; +pci_config_writel(bdf, ofs, ~0); +} +u32 val = pci_config_readl(bdf, ofs); +pci_config_writel(bdf, ofs, old); + +if (val != 0) { +u32 size = (~(val & mask)) + 1; +if (val & PCI_BASE_ADDRESS_SPACE_IO) +paddr = &pci_bios_io_addr; +else +paddr = &pci_bios_mem_addr; +*paddr = ALIGN(*paddr, size); +pci_set_io_region_addr(bdf, region_num, *paddr); +*paddr += size; +} +} + +static void pci_bios_allocate_regions(u16 bdf) +{ +int i; +for (i = 0; i < PCI_NUM_REGIONS; i++) { +pci_bios_allocate_region(bdf, i); +} +} + /* return the global irq number corresponding to a given device irq pin. We could also use the bus number to have a more precise mapping. */ @@ -78,8 +122,7 @@ static void pci_bios_init_bridges(u16 bdf) static void pci_bios_init_device(u16 bdf) { int class; -u32 *paddr; -int i, pin, pic_irq, vendor_id, device_id; +int pin, pic_irq, vendor_id, device_id; class = pci_config_readw(bdf, PCI_CLASS_DEVICE); vendor_id = pci_config_readw(bdf, PCI_VENDOR_ID); @@ -94,7 +137,7 @@ static void pci_bios_init_device(u16 bdf) /* PIIX3/PIIX4 IDE */ pci_config_writew(bdf, 0x40, 0x8000); // enable IDE0 pci_config_writew(bdf, 0x42, 0x8000); // enable IDE1 -goto default_map; +pci_bios_allocate_regions(bdf); } else { /* IDE: we map it as in ISA mode */ pci_set_io_region_addr(bdf, 0, PORT_ATA1_CMD_BASE); @@ -121,41 +164,8 @@ static void pci_bios_init_device(u16 bdf) } break; default: -default_map: /* default memory mappings */ -for (i = 0; i < PCI_NUM_REGIONS; i++) { -int ofs; -if (i == PCI_ROM_SLOT) -ofs = PCI_ROM_ADDRESS; -else -ofs = PCI_BASE_ADDRESS_0 + i * 4; - -u32 old = pci_config_readl(bdf, ofs); -u32 mask; -if (i == PCI_ROM_SLOT) { -mask = PCI_ROM_ADDRESS_MASK; -pci_config_writel(bdf, ofs, mask); -} else { -if (old & PCI_BASE_ADDRESS_SPACE_IO) -mask = PCI_BASE_ADDRESS_IO_MASK; -else -mask = PCI_BASE_ADDRESS_MEM_MASK; -pci_config_writel(bdf, ofs, ~0); -} -u32 val = pci_config_readl(bdf, ofs); -pci_config_writel(bdf, ofs, old); - -if (val != 0) { -u32 size = (~(val & mask)) + 1; -if (val & PCI_BASE_ADDRESS_SPACE_IO) -paddr = &pci_bios_io_addr; -else -paddr = &pci_bios_mem_addr; -*paddr = ALIGN(*paddr, size); -pci_set_io_region_addr(bdf, i, *paddr); -*paddr += size; -} -} +pci_bios_allocate_regions(bdf); break; } -- 1.6.6.1
[Qemu-devel] [PATCH v2 4/8] seabios: pciinit: make pci bar assigner preferchable memory aware.
Make pci bar assigner preferchable memory aware. This is needed for PCI bridge support because memory space and prefetchable memory space is filtered independently based on memory base/limit and prefetchable memory base/limit of pci bridge. On bus 0, such a distinction isn't necessary so keep existing behavior by checking bus=0. With this patch, pci mem assignment area has been decreased. To make seabios behave as before for compatible reason, define CONFIG_OLD_PCIMEM_ASSIGNMENT. Signed-off-by: Isaku Yamahata --- changes v1 -> v2. - introduced BUILD_PCI{MEM, PERFMEM}_{START, SIZE, END} - added range overlap check of pci mem/perfmem area. --- src/config.h | 17 + src/pciinit.c | 49 ++--- 2 files changed, 59 insertions(+), 7 deletions(-) diff --git a/src/config.h b/src/config.h index ad569c6..b1e17de 100644 --- a/src/config.h +++ b/src/config.h @@ -151,7 +151,24 @@ // 32KB for shadow ram copying (works around emulator deficiencies) #define BUILD_BIOS_TMP_ADDR 0x3 #define BUILD_MAX_HIGHMEM 0xe000 + +// Support old pci mem assignment behaviour +//#define CONFIG_OLD_PCIMEM_ASSIGNMENT1 +#if CONFIG_OLD_PCIMEM_ASSIGNMENT +#define BUILD_PCIMEM_START0xf000 +#define BUILD_PCIMEM_SIZE (BUILD_PCIMEM_END - BUILD_PCIMEM_START) +#define BUILD_PCIMEM_END 0xfec0/* IOAPIC is mapped at */ +#define BUILD_PCIPREFMEM_START0 +#define BUILD_PCIPREFMEM_SIZE 0 +#define BUILD_PCIPREFMEM_END 0 +#else #define BUILD_PCIMEM_START0xf000 +#define BUILD_PCIMEM_SIZE 0x0800/* half- of pci window */ +#define BUILD_PCIMEM_END (BUILD_PCIMEM_START + BUILD_PCIMEM_SIZE) +#define BUILD_PCIPREFMEM_STARTBUILD_PCIMEM_END +#define BUILD_PCIPREFMEM_SIZE (BUILD_PCIPREFMEM_END - BUILD_PCIPREFMEM_START) +#define BUILD_PCIPREFMEM_END 0xfec0/* IOAPIC is mapped at */ +#endif #define BUILD_APIC_ADDR 0xfee0 #define BUILD_IOAPIC_ADDR 0xfec0 diff --git a/src/pciinit.c b/src/pciinit.c index b635e44..a65c58d 100644 --- a/src/pciinit.c +++ b/src/pciinit.c @@ -16,6 +16,7 @@ static u32 pci_bios_io_addr; static u32 pci_bios_mem_addr; +static u32 pci_bios_prefmem_addr; /* host irqs corresponding to PCI irqs A-D */ static u8 pci_irqs[4] = { 10, 10, 11, 11 @@ -66,21 +67,54 @@ static int pci_bios_allocate_region(u16 bdf, int region_num) u32 val = pci_config_readl(bdf, ofs); pci_config_writel(bdf, ofs, old); +u32 size = (~(val & mask)) + 1; if (val != 0) { -u32 size = (~(val & mask)) + 1; -if (val & PCI_BASE_ADDRESS_SPACE_IO) +if (val & PCI_BASE_ADDRESS_SPACE_IO) { paddr = &pci_bios_io_addr; -else +if (ALIGN(*paddr, size) + size >= 64 * 1024) { +dprintf(1, +"io region of (bdf 0x%x bar %d) can't be mapped.\n", +bdf, region_num); +size = 0; +} +} else if ((val & PCI_BASE_ADDRESS_MEM_PREFETCH) && + /* keep behaviour on bus = 0 */ + pci_bdf_to_bus(bdf) != 0 && + /* If pci_bios_prefmem_addr == 0, keep old behaviour */ + pci_bios_prefmem_addr != 0) { +paddr = &pci_bios_prefmem_addr; +if (ALIGN(*paddr, size) + size >= BUILD_PCIPREFMEM_END) { +dprintf(1, +"prefmem region of (bdf 0x%x bar %d) can't be mapped. " +"decrease BUILD_PCIMEM_SIZE and recompile. size %x\n", +bdf, region_num, BUILD_PCIPREFMEM_SIZE); +size = 0; +} +} else { paddr = &pci_bios_mem_addr; -*paddr = ALIGN(*paddr, size); -pci_set_io_region_addr(bdf, region_num, *paddr); -*paddr += size; +if (ALIGN(*paddr, size) + size >= BUILD_PCIMEM_END) { +dprintf(1, +"mem region of (bdf 0x%x bar %d) can't be mapped. " +"increase BUILD_PCIMEM_SIZE and recompile. size %x\n", +bdf, region_num, BUILD_PCIMEM_SIZE); +size = 0; +} +} +if (size > 0) { +*paddr = ALIGN(*paddr, size); +pci_set_io_region_addr(bdf, region_num, *paddr); +*paddr += size; +} } int is_64bit = !(val & PCI_BASE_ADDRESS_SPACE_IO) && (val & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64; if (is_64bit) { -pci_config_writel(bdf, ofs + 4, 0); +if (size > 0) { +pci_config_writel(bdf, ofs + 4, 0); +} else { +pci_config_writel(bdf, ofs + 4, ~0); +} } return is_64bit; } @@ -220,6 +254,7 @@ pci_setup(void) pci_bios_io_addr = 0xc000; pci_bios_mem_addr = BUILD_PCIMEM_START; +pci_bios_prefmem_addr = BUIL
[Qemu-devel] [PATCH v2 7/8] seabios: pciinit: pci bridge bus initialization.
pci bridge bus initialization. Signed-off-by: Isaku Yamahata --- src/pciinit.c | 70 + 1 files changed, 70 insertions(+), 0 deletions(-) diff --git a/src/pciinit.c b/src/pciinit.c index 23b79bc..d22ee10 100644 --- a/src/pciinit.c +++ b/src/pciinit.c @@ -247,6 +247,74 @@ static void pci_bios_init_device(u16 bdf) } } +static void +pci_bios_init_bus_rec(int bus, u8 *pci_bus) +{ +int bdf, max; +u16 class; + +dprintf(1, "PCI: %s bus = 0x%x\n", __func__, bus); + +/* prevent accidental access to unintended devices */ +foreachpci_in_bus(bdf, max, bus) { +class = pci_config_readw(bdf, PCI_CLASS_DEVICE); +if (class == PCI_CLASS_BRIDGE_PCI) { +pci_config_writeb(bdf, PCI_SECONDARY_BUS, 255); +pci_config_writeb(bdf, PCI_SUBORDINATE_BUS, 0); +} +} + +foreachpci_in_bus(bdf, max, bus) { +class = pci_config_readw(bdf, PCI_CLASS_DEVICE); +if (class != PCI_CLASS_BRIDGE_PCI) { +continue; +} +dprintf(1, "PCI: %s bdf = 0x%x\n", __func__, bdf); + +u8 pribus = pci_config_readb(bdf, PCI_PRIMARY_BUS); +if (pribus != bus) { +dprintf(1, "PCI: primary bus = 0x%x -> 0x%x\n", pribus, bus); +pci_config_writeb(bdf, PCI_PRIMARY_BUS, bus); +} else { +dprintf(1, "PCI: primary bus = 0x%x\n", pribus); +} + +u8 secbus = pci_config_readb(bdf, PCI_SECONDARY_BUS); +(*pci_bus)++; +if (*pci_bus != secbus) { +dprintf(1, "PCI: secondary bus = 0x%x -> 0x%x\n", +secbus, *pci_bus); +secbus = *pci_bus; +pci_config_writeb(bdf, PCI_SECONDARY_BUS, secbus); +} else { +dprintf(1, "PCI: secondary bus = 0x%x\n", secbus); +} + +/* set to max for access to all subordinate buses. + later set it to accurate value */ +u8 subbus = pci_config_readb(bdf, PCI_SUBORDINATE_BUS); +pci_config_writeb(bdf, PCI_SUBORDINATE_BUS, 255); + +pci_bios_init_bus_rec(secbus, pci_bus); + +if (subbus != *pci_bus) { +dprintf(1, "PCI: subordinate bus = 0x%x -> 0x%x\n", +subbus, *pci_bus); +subbus = *pci_bus; +} else { +dprintf(1, "PCI: subordinate bus = 0x%x\n", subbus); +} +pci_config_writeb(bdf, PCI_SUBORDINATE_BUS, subbus); +} +} + +static void +pci_bios_init_bus(void) +{ +u8 pci_bus = 0; +pci_bios_init_bus_rec(0 /* host bus */, &pci_bus); +} + void pci_setup(void) { @@ -260,6 +328,8 @@ pci_setup(void) pci_bios_mem_addr = BUILD_PCIMEM_START; pci_bios_prefmem_addr = BUILD_PCIPREFMEM_START; +pci_bios_init_bus(); + int bdf, max; foreachpci(bdf, max) { pci_bios_init_bridges(bdf); -- 1.6.6.1