Re: [Qemu-devel] KVM: Windows 64-bit troubles with user space irqchip
On Tue, Feb 01, 2011 at 07:02:03PM +0100, Jan Kiszka wrote: Hi, testing my KVM patches, I noticed that none of the 64-bit Windows versions I have around (early Win7 2003 server) boot in KVM mode when using 2 or more VCPUs and the user space irqchip. This applies to both upstream KVM and qemu-kvm, with our without any of my current patches. A subtle difference in the APIC/IOAPIC emulation? Can anyone confirm this? Just booted windows7-64 on qemu-kvm -no-kvm-irqchip + latest kernel here. -- Gleb.
Re: [Qemu-devel] KVM: Windows 64-bit troubles with user space irqchip
On Wed, Feb 02, 2011 at 02:09:24PM +0100, Jan Kiszka wrote: On 2011-02-02 14:05, Avi Kivity wrote: On 02/02/2011 02:50 PM, Jan Kiszka wrote: Opps, -smp 1. With -smp 2 it boot almost completely and then hangs. Ah, good (or not good). With Windows 2003 Server, I actually get a Blue Screen (Stop 0x00b8). Userspace APIC is broken since it may run with an outdated cr8, does reverting 27a4f7976d5 help? -ECOMMITNOTFOUND, neither in qemu-kvm nor upstream. This is kernel commit, but it is too old. I am pretty sure userspace irq chip worked back then. -- Gleb.
[Qemu-devel] [PATCH 1/2] Add virtagent file system freeze/thaw
From: Jes Sorensen jes.soren...@redhat.com Implement freeze/thaw support in the guest, allowing the host to request the guest freezes all it's file systems before a live snapshot is performed. - fsfreeze(): Walk the list of mounted local real file systems, and freeze them. - fsthaw(): Walk the list of previously frozen file systems and thaw them. - fsstatus(): Return the current status of freeze/thaw. The host must poll this function, in case fsfreeze() returned with a timeout, to wait for the operation to finish. Signed-off-by: Jes Sorensen jes.soren...@redhat.com --- virtagent-common.h |8 ++ virtagent-server.c | 190 2 files changed, 198 insertions(+), 0 deletions(-) diff --git a/virtagent-common.h b/virtagent-common.h index 5d8f5c1..7c6d9ef 100644 --- a/virtagent-common.h +++ b/virtagent-common.h @@ -61,6 +61,14 @@ typedef struct VAContext { const char *channel_path; } VAContext; +enum va_fsfreeze_status { +FREEZE_ERROR = -1, +FREEZE_THAWED = 0, +FREEZE_INPROGRESS = 1, +FREEZE_FROZEN = 2, +FREEZE_THAWINPROGRESS = 3, +}; + enum va_job_status { VA_JOB_STATUS_PENDING = 0, VA_JOB_STATUS_OK, diff --git a/virtagent-server.c b/virtagent-server.c index 7bb35b2..ffbe163 100644 --- a/virtagent-server.c +++ b/virtagent-server.c @@ -14,6 +14,10 @@ #include syslog.h #include qemu_socket.h #include virtagent-common.h +#include mntent.h +#include sys/types.h +#include sys/ioctl.h +#include linux/fs.h static VAServerData *va_server_data; static bool va_enable_syslog = false; /* enable syslog'ing of RPCs */ @@ -217,6 +221,186 @@ static xmlrpc_value *va_hello(xmlrpc_env *env, return result; } + +/* + * Walk the mount table and build a list of local file systems + */ + +struct direntry { +char *dirname; +char *devtype; +struct direntry *next; +}; + +static struct direntry *va_mount_list; +static int va_fsfreeze_status; + +static int build_mount_list(void) +{ +struct mntent *mnt; +struct direntry *entry; +struct direntry *next; +char const *mtab = MOUNTED; +FILE *fp; + +fp = setmntent(mtab, r); +if (!fp) { + fprintf(stderr, unable to read mtab\n); + goto fail; +} + +while ((mnt = getmntent(fp))) { + /* +* An entry which device name doesn't start with a '/' is +* either a dummy file system or a network file system. +* Add special handling for smbfs and cifs as is done by +* coreutils as well. +*/ + if ((mnt-mnt_fsname[0] != '/') || + (strcmp(mnt-mnt_type, smbfs) == 0) || + (strcmp(mnt-mnt_type, cifs) == 0)) { + continue; + } + + entry = qemu_malloc(sizeof(struct direntry)); + entry-dirname = qemu_strdup(mnt-mnt_dir); + entry-devtype = qemu_strdup(mnt-mnt_type); + entry-next = va_mount_list; + + va_mount_list = entry; +} + +endmntent(fp); + +return 0; + +fail: +while(va_mount_list) { + next = va_mount_list-next; +qemu_free(va_mount_list-dirname); +qemu_free(va_mount_list-devtype); +qemu_free(va_mount_list); +va_mount_list = next; +} + +return -1; +} + +/* + * va_fsfreeze(): Walk list of mounted file systems in the guest, and + * freeze the ones which are real local file systems. + * rpc return values: Number of file systems frozen, -1 on error. + */ +static xmlrpc_value *va_fsfreeze(xmlrpc_env *env, + xmlrpc_value *params, + void *user_data) +{ +xmlrpc_int32 ret = 0, i = 0; +xmlrpc_value *result; +struct direntry *entry; +int fd; +SLOG(va_fsfreeze()); + +if (va_fsfreeze_status != FREEZE_THAWED) { +ret = 0; +goto out; +} + +ret = build_mount_list(); +if (ret 0) { +goto out; +} + +va_fsfreeze_status = FREEZE_INPROGRESS; + +entry = va_mount_list; +while(entry) { +fd = qemu_open(entry-dirname, O_RDONLY); +if (fd == -1) { +ret = errno; +goto error; +} +ret = ioctl(fd, FIFREEZE); +close(fd); +if (ret 0 ret != EOPNOTSUPP) { +goto error; +} + +entry = entry-next; +i++; +} + +va_fsfreeze_status = FREEZE_FROZEN; +ret = i; +out: +result = xmlrpc_build_value(env, i, ret); +return result; +error: +if (i 0) { +va_fsfreeze_status = FREEZE_ERROR; +} +goto out; +} + +/* + * va_fsthaw(): Walk list of frozen file systems in the guest, and + * thaw them. + * rpc return values: Number of file systems thawed on success, -1 on error. + */ +static xmlrpc_value *va_fsthaw(xmlrpc_env *env, + xmlrpc_value *params, + void *user_data) +{ +xmlrpc_int32 ret; +xmlrpc_value *result; +
[Qemu-devel] [PATCH V10 13/15] xen: Initialize event channels and io rings
From: Arun Sharma arun.sha...@intel.com Open and bind event channels; map ioreq and buffered ioreq rings. Signed-off-by: Arun Sharma arun.sha...@intel.com Signed-off-by: Anthony PERARD anthony.per...@citrix.com Signed-off-by: Stefano Stabellini stefano.stabell...@eu.citrix.com Acked-by: Alexander Graf ag...@suse.de --- hw/xen_common.h |2 + xen-all.c | 413 ++- 2 files changed, 414 insertions(+), 1 deletions(-) diff --git a/hw/xen_common.h b/hw/xen_common.h index 3a08f6a..d0b1a92 100644 --- a/hw/xen_common.h +++ b/hw/xen_common.h @@ -39,4 +39,6 @@ static inline int xc_fd(xc_interface *xen_xc) } #endif +void destroy_hvm_domain(void); + #endif /* QEMU_HW_XEN_COMMON_H */ diff --git a/xen-all.c b/xen-all.c index 84ed333..592bcaf 100644 --- a/xen-all.c +++ b/xen-all.c @@ -8,12 +8,58 @@ #include config.h +#include sys/mman.h + #include hw/pci.h #include hw/xen_common.h #include hw/xen_backend.h #include xen-mapcache.h +#include xen/hvm/ioreq.h +#include xen/hvm/params.h + +//#define DEBUG_XEN + +#ifdef DEBUG_XEN +#define DPRINTF(fmt, ...) \ +do { fprintf(stderr, xen: fmt, ## __VA_ARGS__); } while (0) +#else +#define DPRINTF(fmt, ...) \ +do { } while (0) +#endif + +/* Compatibility with older version */ +#if __XEN_LATEST_INTERFACE_VERSION__ 0x0003020a +# define xen_vcpu_eport(shared_page, i) \ +(shared_page-vcpu_iodata[i].vp_eport) +# define xen_vcpu_ioreq(shared_page, vcpu) \ +(shared_page-vcpu_iodata[vcpu].vp_ioreq) +# define FMT_ioreq_size PRIx64 +#else +# define xen_vcpu_eport(shared_page, i) \ +(shared_page-vcpu_ioreq[i].vp_eport) +# define xen_vcpu_ioreq(shared_page, vcpu) \ +(shared_page-vcpu_ioreq[vcpu]) +# define FMT_ioreq_size u +#endif + +#define BUFFER_IO_MAX_DELAY 100 + +typedef struct XenIOState { +shared_iopage_t *shared_page; +buffered_iopage_t *buffered_io_page; +QEMUTimer *buffered_io_timer; +/* the evtchn port for polling the notification, */ +evtchn_port_t *ioreq_local_port; +/* the evtchn fd for polling */ +XenEvtchn xce_handle; +/* which vcpu we are serving */ +int send_vcpu; + +Notifier exit; +} XenIOState; + /* Xen specific function for piix pci */ int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num) @@ -106,7 +152,7 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size) pfn_list[i] = (ram_addr TARGET_PAGE_BITS) + i; } -if (xc_domain_populate_physmap_exact(xen_xc, xen_domid, nr_pfn, 0, 0, pfn_list)) { +if (xc_ops.domain_populate_physmap_exact(xen_xc, xen_domid, nr_pfn, 0, 0, pfn_list)) { hw_error(xen: failed to populate ram at %lx, ram_addr); } @@ -114,10 +160,312 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size) } +/* VCPU Operations, MMIO, IO ring ... */ + +/* get the ioreq packets from share mem */ +static ioreq_t *cpu_get_ioreq_from_shared_memory(XenIOState *state, int vcpu) +{ +ioreq_t *req = xen_vcpu_ioreq(state-shared_page, vcpu); + +if (req-state != STATE_IOREQ_READY) { +DPRINTF(I/O request not ready: +%x, ptr: %x, port: %PRIx64, +data: %PRIx64, count: % FMT_ioreq_size , size: % FMT_ioreq_size \n, +req-state, req-data_is_ptr, req-addr, +req-data, req-count, req-size); +return NULL; +} + +xen_rmb(); /* see IOREQ_READY /then/ read contents of ioreq */ + +req-state = STATE_IOREQ_INPROCESS; +return req; +} + +/* use poll to get the port notification */ +/* ioreq_vec--out,the */ +/* retval--the number of ioreq packet */ +static ioreq_t *cpu_get_ioreq(XenIOState *state) +{ +int i; +evtchn_port_t port; + +port = xc_evtchn_ops.pending(state-xce_handle); +if (port != -1) { +for (i = 0; i smp_cpus; i++) { +if (state-ioreq_local_port[i] == port) { +break; +} +} + +if (i == smp_cpus) { +hw_error(Fatal error while trying to get io event!\n); +} + +/* unmask the wanted port again */ +xc_evtchn_ops.unmask(state-xce_handle, port); + +/* get the io packet from shared memory */ +state-send_vcpu = i; +return cpu_get_ioreq_from_shared_memory(state, i); +} + +/* read error or read nothing */ +return NULL; +} + +static uint32_t do_inp(pio_addr_t addr, unsigned long size) +{ +switch (size) { +case 1: +return cpu_inb(addr); +case 2: +return cpu_inw(addr); +case 4: +return cpu_inl(addr); +default: +hw_error(inp: bad size: %04FMT_pioaddr %lx, addr, size); +} +} + +static void do_outp(pio_addr_t addr, +unsigned long size, uint32_t val) +{ +switch (size) { +case 1: +return cpu_outb(addr, val); +case 2: +return cpu_outw(addr, val); +case 4: +return cpu_outl(addr, val); +
Re: [Qemu-devel] KVM: Windows 64-bit troubles with user space irqchip
On 2011-02-02 14:05, Avi Kivity wrote: On 02/02/2011 02:50 PM, Jan Kiszka wrote: Opps, -smp 1. With -smp 2 it boot almost completely and then hangs. Ah, good (or not good). With Windows 2003 Server, I actually get a Blue Screen (Stop 0x00b8). Userspace APIC is broken since it may run with an outdated cr8, does reverting 27a4f7976d5 help? -ECOMMITNOTFOUND, neither in qemu-kvm nor upstream. Jan -- Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
Re: [Qemu-devel] KVM: Windows 64-bit troubles with user space irqchip
On Wed, Feb 02, 2011 at 03:14:26PM +0200, Avi Kivity wrote: On 02/02/2011 03:11 PM, Gleb Natapov wrote: On Wed, Feb 02, 2011 at 02:09:24PM +0100, Jan Kiszka wrote: On 2011-02-02 14:05, Avi Kivity wrote: On 02/02/2011 02:50 PM, Jan Kiszka wrote: Opps, -smp 1. With -smp 2 it boot almost completely and then hangs. Ah, good (or not good). With Windows 2003 Server, I actually get a Blue Screen (Stop 0x00b8). Userspace APIC is broken since it may run with an outdated cr8, does reverting 27a4f7976d5 help? -ECOMMITNOTFOUND, neither in qemu-kvm nor upstream. This is kernel commit, but it is too old. I am pretty sure userspace irq chip worked back then. I have memories of it failing autotest, but the conclusion was that the commit did not cause the problem, simply enlarged the window in which it could happen. Ah, I remember something like that. RHEL6 kernel + qemu-kvm fails in the same way so problem is not new. -- Gleb.
Re: [Qemu-devel] KVM: Windows 64-bit troubles with user space irqchip
On 02/02/2011 03:11 PM, Gleb Natapov wrote: On Wed, Feb 02, 2011 at 02:09:24PM +0100, Jan Kiszka wrote: On 2011-02-02 14:05, Avi Kivity wrote: On 02/02/2011 02:50 PM, Jan Kiszka wrote: Opps, -smp 1. With -smp 2 it boot almost completely and then hangs. Ah, good (or not good). With Windows 2003 Server, I actually get a Blue Screen (Stop 0x00b8). Userspace APIC is broken since it may run with an outdated cr8, does reverting 27a4f7976d5 help? -ECOMMITNOTFOUND, neither in qemu-kvm nor upstream. This is kernel commit, but it is too old. I am pretty sure userspace irq chip worked back then. I have memories of it failing autotest, but the conclusion was that the commit did not cause the problem, simply enlarged the window in which it could happen. -- error compiling committee.c: too many arguments to function
[Qemu-devel] Re: [PATCH v2] make tsc stable over migration and machine start
On 2011-02-02 13:16, Glauber Costa wrote: If the machine is stopped, we should not record two different tsc values upon a save operation. The same problem happens with kvmclock. But kvmclock is taking a different diretion, being now seen as a separate device. Since this is unlikely to happen with the tsc, I am taking the approach here of simply registering a handler for state change, and using a per-CPUState variable that prevents double updates for the TSC. Signed-off-by: Glauber Costa glom...@redhat.com CC: Jan Kiszka jan.kis...@web.de --- v2: updated tsc validation logic, as asked by Jan --- target-i386/cpu.h |1 + target-i386/kvm.c | 18 +- 2 files changed, 18 insertions(+), 1 deletions(-) diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 6d619e8..6bb2e87 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -732,6 +732,7 @@ typedef struct CPUX86State { uint32_t sipi_vector; uint32_t cpuid_kvm_features; uint32_t cpuid_svm_features; +bool tsc_valid; /* in order to simplify APIC support, we leave this pointer to the user */ diff --git a/target-i386/kvm.c b/target-i386/kvm.c index ecb8405..9cc198a 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -302,6 +302,15 @@ void kvm_inject_x86_mce(CPUState *cenv, int bank, uint64_t status, static int _kvm_arch_init_vcpu(CPUState *env); +static void cpu_update_state(void *opaque, int running, int reason) +{ +CPUState *env = opaque; + +if (running) { +env-tsc_valid = false; +} +} + int kvm_arch_init_vcpu(CPUState *env) { int r; @@ -444,6 +453,8 @@ int kvm_arch_init_vcpu(CPUState *env) } #endif +qemu_add_vm_change_state_handler(cpu_update_state, env); + return kvm_vcpu_ioctl(env, KVM_SET_CPUID2, cpuid_data); } @@ -1093,7 +1104,12 @@ static int kvm_get_msrs(CPUState *env) msrs[n++].index = MSR_STAR; if (kvm_has_msr_hsave_pa(env)) msrs[n++].index = MSR_VM_HSAVE_PA; -msrs[n++].index = MSR_IA32_TSC; + +if (!env-tsc_valid) { +msrs[n++].index = MSR_IA32_TSC; +env-tsc_valid = !vm_running; +} + #ifdef TARGET_X86_64 if (lm_capable_kernel) { msrs[n++].index = MSR_CSTAR; Yep. Reviewed-by: Jan Kiszka jan.kis...@siemens.com -- Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
Re: [Qemu-devel] KVM: Windows 64-bit troubles with user space irqchip
On 02/02/2011 02:50 PM, Jan Kiszka wrote: Opps, -smp 1. With -smp 2 it boot almost completely and then hangs. Ah, good (or not good). With Windows 2003 Server, I actually get a Blue Screen (Stop 0x00b8). Userspace APIC is broken since it may run with an outdated cr8, does reverting 27a4f7976d5 help? -- error compiling committee.c: too many arguments to function
[Qemu-devel] [PATCH v2] make tsc stable over migration and machine start
If the machine is stopped, we should not record two different tsc values upon a save operation. The same problem happens with kvmclock. But kvmclock is taking a different diretion, being now seen as a separate device. Since this is unlikely to happen with the tsc, I am taking the approach here of simply registering a handler for state change, and using a per-CPUState variable that prevents double updates for the TSC. Signed-off-by: Glauber Costa glom...@redhat.com CC: Jan Kiszka jan.kis...@web.de --- v2: updated tsc validation logic, as asked by Jan --- target-i386/cpu.h |1 + target-i386/kvm.c | 18 +- 2 files changed, 18 insertions(+), 1 deletions(-) diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 6d619e8..6bb2e87 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -732,6 +732,7 @@ typedef struct CPUX86State { uint32_t sipi_vector; uint32_t cpuid_kvm_features; uint32_t cpuid_svm_features; +bool tsc_valid; /* in order to simplify APIC support, we leave this pointer to the user */ diff --git a/target-i386/kvm.c b/target-i386/kvm.c index ecb8405..9cc198a 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -302,6 +302,15 @@ void kvm_inject_x86_mce(CPUState *cenv, int bank, uint64_t status, static int _kvm_arch_init_vcpu(CPUState *env); +static void cpu_update_state(void *opaque, int running, int reason) +{ +CPUState *env = opaque; + +if (running) { +env-tsc_valid = false; +} +} + int kvm_arch_init_vcpu(CPUState *env) { int r; @@ -444,6 +453,8 @@ int kvm_arch_init_vcpu(CPUState *env) } #endif +qemu_add_vm_change_state_handler(cpu_update_state, env); + return kvm_vcpu_ioctl(env, KVM_SET_CPUID2, cpuid_data); } @@ -1093,7 +1104,12 @@ static int kvm_get_msrs(CPUState *env) msrs[n++].index = MSR_STAR; if (kvm_has_msr_hsave_pa(env)) msrs[n++].index = MSR_VM_HSAVE_PA; -msrs[n++].index = MSR_IA32_TSC; + +if (!env-tsc_valid) { +msrs[n++].index = MSR_IA32_TSC; +env-tsc_valid = !vm_running; +} + #ifdef TARGET_X86_64 if (lm_capable_kernel) { msrs[n++].index = MSR_CSTAR; -- 1.7.2.3
Re: [Qemu-devel] KVM: Windows 64-bit troubles with user space irqchip
On 2011-02-02 14:05, Avi Kivity wrote: On 02/02/2011 02:50 PM, Jan Kiszka wrote: Opps, -smp 1. With -smp 2 it boot almost completely and then hangs. Ah, good (or not good). With Windows 2003 Server, I actually get a Blue Screen (Stop 0x00b8). Userspace APIC is broken since it may run with an outdated cr8, does reverting 27a4f7976d5 help? Can you elaborate on what is broken? The way hw/apic.c maintains the tpr? Would it make sense to compare this against the in-kernel model? Or do you mean something else? Jan -- Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
RE: [Qemu-devel] [PATCH] Correct win32 timers deleting v.3
Hello. Anybody interested in this patch? Pavel Dovgaluk -Original Message- From: qemu-devel-bounces+pavel.dovgaluk=ispras...@nongnu.org [mailto:qemu- devel-bounces+pavel.dovgaluk=ispras...@nongnu.org] On Behalf Of Pavel Dovgaluk Sent: Wednesday, January 26, 2011 11:06 AM To: qemu-devel@nongnu.org Subject: [Qemu-devel] [PATCH] Correct win32 timers deleting v.3 This patch fixes resource leaks caused by quitting qemu with exit() function on win32 host. Timer object should be freed not only at the end of the main function, but by every of the application exits. v.3: Fixed all the issues found in previous messages with patch. Signed-off-by: Pavel Dovgalyuk pavel.dovga...@gmail.com --- qemu-timer.c | 16 +--- vl.c |1 - 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/qemu-timer.c b/qemu-timer.c index 95814af..86d77a6 100644 --- a/qemu-timer.c +++ b/qemu-timer.c @@ -972,7 +972,10 @@ static int win32_start_timer(struct qemu_alarm_timer *t) timeGetDevCaps(tc, sizeof(tc)); data-period = tc.wPeriodMin; -timeBeginPeriod(data-period); +if (timeBeginPeriod(data-period) != TIMERR_NOERROR) { +fprintf(stderr, Failed to initialize win32 alarm timer\n); +return -1; +} flags = TIME_CALLBACK_FUNCTION; if (alarm_has_dynticks(t)) @@ -990,6 +993,7 @@ static int win32_start_timer(struct qemu_alarm_timer *t) fprintf(stderr, Failed to initialize win32 alarm timer: %ld\n, GetLastError()); timeEndPeriod(data-period); +data-period = 0; return -1; } @@ -1000,8 +1004,12 @@ static void win32_stop_timer(struct qemu_alarm_timer *t) { struct qemu_alarm_win32 *data = t-priv; -timeKillEvent(data-timerId); -timeEndPeriod(data-period); +if (data-timerId) { +timeKillEvent(data-timerId); +} +if (data-period) { +timeEndPeriod(data-period); +} } static void win32_rearm_timer(struct qemu_alarm_timer *t) @@ -1027,6 +1035,7 @@ static void win32_rearm_timer(struct qemu_alarm_timer *t) GetLastError()); timeEndPeriod(data-period); +data-period = 0; exit(1); } } @@ -1061,6 +1070,7 @@ int init_timer_alarm(void) t-pending = 1; alarm_timer = t; qemu_add_vm_change_state_handler(alarm_timer_on_change_state_rearm, t); +atexit(quit_timers); return 0; diff --git a/vl.c b/vl.c index 0292184..c4b25b0 100644 --- a/vl.c +++ b/vl.c @@ -3118,7 +3118,6 @@ int main(int argc, char **argv, char **envp) os_setup_post(); main_loop(); -quit_timers(); net_cleanup(); return 0;
[Qemu-devel] Re: [PATCH] make tsc stable over migration and machine start
On Tue, 2011-02-01 at 21:26 +0100, Jan Kiszka wrote: On 2011-02-01 20:17, Glauber Costa wrote: If the machine is stopped, we should not record two different tsc values upon a save operation. The same problem happens with kvmclock. But kvmclock is taking a different diretion, being now seen as a separate device. Since this is unlikely to happen with the tsc, I am taking the approach here of simply registering a handler for state change, and using a per-CPUState variable that prevents double updates for the TSC. Signed-off-by: Glauber Costa glom...@redhat.com --- target-i386/cpu.h |1 + target-i386/kvm.c | 19 ++- 2 files changed, 19 insertions(+), 1 deletions(-) diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 6d619e8..7f1c4f8 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -732,6 +732,7 @@ typedef struct CPUX86State { uint32_t sipi_vector; uint32_t cpuid_kvm_features; uint32_t cpuid_svm_features; +uint8_t update_tsc; bool please. /* in order to simplify APIC support, we leave this pointer to the user */ diff --git a/target-i386/kvm.c b/target-i386/kvm.c index ecb8405..c3925be 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -302,6 +302,16 @@ void kvm_inject_x86_mce(CPUState *cenv, int bank, uint64_t status, static int _kvm_arch_init_vcpu(CPUState *env); +static void cpu_update_state(void *opaque, int running, int reason) +{ +CPUState *env = opaque; + +if (!running) { +env-update_tsc = 1; +} +} + + Additional blank line. int kvm_arch_init_vcpu(CPUState *env) { int r; @@ -444,6 +454,8 @@ int kvm_arch_init_vcpu(CPUState *env) } #endif +qemu_add_vm_change_state_handler(cpu_update_state, env); + return kvm_vcpu_ioctl(env, KVM_SET_CPUID2, cpuid_data); } @@ -1093,7 +1105,12 @@ static int kvm_get_msrs(CPUState *env) msrs[n++].index = MSR_STAR; if (kvm_has_msr_hsave_pa(env)) msrs[n++].index = MSR_VM_HSAVE_PA; -msrs[n++].index = MSR_IA32_TSC; + +if (env-update_tsc) { +msrs[n++].index = MSR_IA32_TSC; +env-update_tsc = 0; +} + #ifdef TARGET_X86_64 if (lm_capable_kernel) { msrs[n++].index = MSR_CSTAR; Not quite the logic I'm using for kvmclock: Ok. I have all the interest in keeping the same logic. I will respin. cpu_update_state() if running tsc_valid = false; kvm_get_msrs() ... if (!tsc_valid) read_tsc tsc_valid = !vm_running; That ensure we always read the tsc while the VM is running, and not only after it was stopped (might otherwise be surprising when once visualizing the MSRs). Jan
Re: [Qemu-devel] KVM: Windows 64-bit troubles with user space irqchip
On 2011-02-02 12:55, Gleb Natapov wrote: On Tue, Feb 01, 2011 at 07:02:03PM +0100, Jan Kiszka wrote: Hi, testing my KVM patches, I noticed that none of the 64-bit Windows versions I have around (early Win7 2003 server) boot in KVM mode when using 2 or more VCPUs and the user space irqchip. This applies to both upstream KVM and qemu-kvm, with our without any of my current patches. A subtle difference in the APIC/IOAPIC emulation? Can anyone confirm this? Just booted windows7-64 on qemu-kvm -no-kvm-irqchip + latest kernel here. Strange. -smp 2? Jan -- Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
[Qemu-devel] [PATCH 2/2] Add monitor commands for fsfreeze support
From: Jes Sorensen jes.soren...@redhat.com This patch adds the following monitor commands: agent_fsfreeze: - Freezes all local file systems in the guest. Command will print the number of file systems that were frozen. agent_fsthaw: - Thaws all local file systems in the guest. Command will print the number of file systems that were thawed. agent_fsstatus: - Prints the current status of file systems in the guest: Thawed, frozen, thaw in progress, freeze in progress, error. Signed-off-by: Jes Sorensen jes.soren...@redhat.com --- hmp-commands.hx| 48 +++ virtagent-common.h |1 + virtagent.c| 235 virtagent.h|9 ++ 4 files changed, 293 insertions(+), 0 deletions(-) diff --git a/hmp-commands.hx b/hmp-commands.hx index 9c7ac0b..f4150da 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1310,6 +1310,54 @@ STEXI Fetch and re-negotiate guest agent capabilties ETEXI +{ +.name = agent_fsfreeze, +.args_type = , +.params = , +.help = Freeze all local file systems mounted in the guest, +.user_print = do_agent_fsfreeze_print, +.mhandler.cmd_async = do_agent_fsfreeze, +.flags = MONITOR_CMD_ASYNC, +}, + +STEXI +@item agent_fsfreeze +@findex agent_fsfreeze +Freeze all local mounted file systems in guest +ETEXI + +{ +.name = agent_fsthaw, +.args_type = , +.params = , +.help = Thaw all local file systems mounted in the guest, +.user_print = do_agent_fsthaw_print, +.mhandler.cmd_async = do_agent_fsthaw, +.flags = MONITOR_CMD_ASYNC, +}, + +STEXI +@item agent_fsthaw +@findex agent_fsthaw +Thaw all local mounted file systems in guest +ETEXI + +{ +.name = agent_fsstatus, +.args_type = , +.params = , +.help = Display status of file system freeze progress in guest, +.user_print = do_agent_fsstatus_print, +.mhandler.cmd_async = do_agent_fsstatus, +.flags = MONITOR_CMD_ASYNC, +}, + +STEXI +@item agent_fsstatus +@findex agent_fsstatus +Get status of file system freeze in guest +ETEXI + STEXI @end table ETEXI diff --git a/virtagent-common.h b/virtagent-common.h index 7c6d9ef..ff7bf23 100644 --- a/virtagent-common.h +++ b/virtagent-common.h @@ -24,6 +24,7 @@ #include monitor.h #include virtagent-server.h #include virtagent.h +#include qint.h #define DEBUG_VA diff --git a/virtagent.c b/virtagent.c index b5e7944..4277802 100644 --- a/virtagent.c +++ b/virtagent.c @@ -640,3 +640,238 @@ int va_send_hello(void) xmlrpc_DECREF(params); return ret; } + +void do_agent_fsfreeze_print(Monitor *mon, const QObject *data) +{ +TRACE(called); + +monitor_printf(mon, File systems frozen: % PRId64 \n, + qint_get_int((qobject_to_qint(data; +} + +static void do_agent_fsfreeze_cb(const char *resp_data, + size_t resp_data_len, + MonitorCompletion *mon_cb, + void *mon_data) +{ +xmlrpc_value *resp = NULL; +xmlrpc_env env; +xmlrpc_int32 retval = 0; +QInt *qint; + +TRACE(called); + +if (resp_data == NULL) { +LOG(error handling RPC request); +return; +} + +xmlrpc_env_init(env); +resp = xmlrpc_parse_response(env, resp_data, resp_data_len); +if (va_rpc_has_error(env)) { +LOG(error parsing RPC response); +return; +} + +xmlrpc_parse_value(env, resp, i, retval); +if (va_rpc_has_error(env)) { +retval = -1; +goto out; +} + +out: +qint = qint_from_int(retval); +xmlrpc_DECREF(resp); +if (mon_cb) { +mon_cb(mon_data, QOBJECT(qint)); +} +qobject_decref(QOBJECT(qint)); +} + +int do_agent_fsfreeze(Monitor *mon, const QDict *mon_params, + MonitorCompletion cb, void *opaque) +{ +xmlrpc_env env; +xmlrpc_value *params; +int ret; + +TRACE(called); + +xmlrpc_env_init(env); +params = xmlrpc_build_value(env, ()); +if (va_rpc_has_error(env)) { +return -1; +} + +ret = va_do_rpc(env, va.fsfreeze, params, do_agent_fsfreeze_cb, +cb, opaque); +if (ret) { +qerror_report(QERR_VA_FAILED, ret, strerror(ret)); +} +xmlrpc_DECREF(params); +return ret; +} + +void do_agent_fsthaw_print(Monitor *mon, const QObject *data) +{ +TRACE(called); + +monitor_printf(mon, File systems thawed: % PRId64 \n, + qint_get_int((qobject_to_qint(data; +} + +static void do_agent_fsthaw_cb(const char *resp_data, + size_t resp_data_len, + MonitorCompletion *mon_cb, + void *mon_data) +{ +xmlrpc_value *resp = NULL; +xmlrpc_env env; +xmlrpc_int32
[Qemu-devel] Re: [PATCH 1/2] Add virtagent file system freeze/thaw
On 02/01/11 17:50, Michael Roth wrote: On 02/01/2011 04:58 AM, jes.soren...@redhat.com wrote: +enum vs_fsfreeze_status { +FREEZE_ERROR = -1, +FREEZE_THAWED = 0, +FREEZE_INPROGRESS = 1, +FREEZE_FROZEN = 2, +FREEZE_THAWINPROGRESS = 3, +}; Any reason for vs_* vs. va_*? H let me see if I can find a good excuse for that typo :) diff --git a/virtagent-server.c b/virtagent-server.c index 7bb35b2..cf2a3f0 100644 --- a/virtagent-server.c +++ b/virtagent-server.c @@ -14,6 +14,13 @@ #includesyslog.h #include qemu_socket.h #include virtagent-common.h +#includemntent.h +#includesys/types.h +#includesys/stat.h +#includesys/errno.h +#includesys/ioctl.h +#includefcntl.h +#includelinux/fs.h Can probably clean these up a bit, I believe fcntl.h/errno.h/stat.h are already available at least. Carry-over from writing the code outside of qemu. Would be much cleaner than relying on the include everything and the kitchen sink in a global header file, but thats how it is :( + +fsfreeze_status = FREEZE_INPROGRESS; + +entry = mount_list; I think as we start adding more and more stateful RPCs, free-floating state variables can start getting a bit hairy to keep track of. Eventually I'd like to have state information that only applies to a subset of RPCs consolidated into a single object. I wouldn't focus on this too much because I'd like to have an interface to do this in the future (mainly so they can state objects can register themselves and provide a reset() function that can be called when, for instance, an agent disconnects/reconnects), but in the meantime I think it would be more readable to have a global va_fsfreeze_state object to track freeze status and mount points. Urgh, what do you mean by object here? I have to admit the word object always makes me cringe I changed the variables to have the va_ prefix. +static xmlrpc_value *va_fsstatus(xmlrpc_env *env, + xmlrpc_value *params, + void *user_data) +{ +xmlrpc_value *result = xmlrpc_build_value(env, i, fsfreeze_status); +SLOG(va_fsstatus()); +return result; +} Hmm, you mentioned before that these freezes may be long-running jobs...do the ioctl()'s not return until completion? There is global timeout in virtagent, currently under a minute, to prevent a virtagent monitor command from hanging the monitor session, so if it's unlikely you'll fit in this window we'll need to work on something to better support these this kinds of situations. I think 1 minute is fine, but we should probably look at something a little more flexible for handling commands over the longer term. Maybe have virtagent spawn threads for executing some commands? The 3 main approaches would be: 1) allow command-specific timeouts with values that are sane for the command in question, and potentially allow timeouts to be disabled 2) fork() long running jobs and provide a mechanism for them to provide asynchronous updates to us to we can query status 3) fork() long running jobs, have them provide status information elsewhere, and provide a polling function to check that status 3) would likely require something like writing status to a file and then provide a polling function to check it, which doesn't work here so that's probably out. I'd initially planned on doing 2) at some point, but I'm beginning to think 1) is the better approach, since qemu opts in on how long it's willing to hang for a particular command, so there's not really any surprises. At least not to qemu...users might get worried after a while, so there is a bit of a trade-off. But it's also more user-friendlyno need for polling or dealing with asynchronous updates to figure out when an RPC has actually finished. Seem reasonable? I am not sure which is really the best solution. Basically we will need to classify commands into two categories, so if you issue a certain type of command, like agent_fsfreeze() (basically when the agent is in FREEZE_FROZEN state) only status commands are allowed to execute in parallel. Anything that tries to issue a write to the file system will hang until agent_fsthaw is called. However it would be useful to be able to call in for non-blocking status commands etc. I'll post a v2 in a minute that addresses the issues pointed out by Stefan and you. I think the threading/timeout aspect is something we need to look at for the longer term. Cheers, Jes
Re: [Qemu-devel] KVM: Windows 64-bit troubles with user space irqchip
On 02/02/2011 04:30 PM, Jan Kiszka wrote: On 2011-02-02 14:05, Avi Kivity wrote: On 02/02/2011 02:50 PM, Jan Kiszka wrote: Opps, -smp 1. With -smp 2 it boot almost completely and then hangs. Ah, good (or not good). With Windows 2003 Server, I actually get a Blue Screen (Stop 0x00b8). Userspace APIC is broken since it may run with an outdated cr8, does reverting 27a4f7976d5 help? Can you elaborate on what is broken? The way hw/apic.c maintains the tpr? Would it make sense to compare this against the in-kernel model? Or do you mean something else? The problem, IIRC, was that we look up the TPR but it may already have been changed by the running vcpu. Not 100% sure. If that is indeed the problem then the fix would be to process the APIC in vcpu context (which is what the kernel does - we set a bit in the IRR and all further processing is synchronous). -- error compiling committee.c: too many arguments to function
[Qemu-devel] [PATCH V10 09/15] xen: Introduce the Xen mapcache
From: Jun Nakajima jun.nakaj...@intel.com On IA32 host or IA32 PAE host, at present, generally, we can't create an HVM guest with more than 2G memory, because generally it's almost impossible for Qemu to find a large enough and consecutive virtual address space to map an HVM guest's whole physical address space. The attached patch fixes this issue using dynamic mapping based on little blocks of memory. Each call to qemu_get_ram_ptr makes a call to qemu_map_cache with the lock option, so mapcache will not unmap these ram_ptr. Signed-off-by: Jun Nakajima jun.nakaj...@intel.com Signed-off-by: Anthony PERARD anthony.per...@citrix.com Signed-off-by: Stefano Stabellini stefano.stabell...@eu.citrix.com --- Makefile.target |3 + configure |3 + exec.c | 40 ++- hw/xen.h| 13 ++ xen-all.c | 64 +++ xen-mapcache-stub.c | 40 +++ xen-mapcache.c | 310 +++ xen-mapcache.h | 22 xen-stub.c |4 + 9 files changed, 495 insertions(+), 4 deletions(-) create mode 100644 xen-mapcache-stub.c create mode 100644 xen-mapcache.c create mode 100644 xen-mapcache.h diff --git a/Makefile.target b/Makefile.target index 7a4fd72..b2edcd4 100644 --- a/Makefile.target +++ b/Makefile.target @@ -207,9 +207,12 @@ QEMU_CFLAGS += $(VNC_JPEG_CFLAGS) QEMU_CFLAGS += $(VNC_PNG_CFLAGS) # xen support +CONFIG_NO_XEN_MAPCACHE = $(if $(subst n,,$(CONFIG_XEN_MAPCACHE)),n,y) obj-$(CONFIG_XEN) += xen_interfaces.o obj-$(CONFIG_XEN) += xen-all.o obj-$(CONFIG_NO_XEN) += xen-stub.o +obj-$(CONFIG_XEN_MAPCACHE) += xen-mapcache.o +obj-$(CONFIG_NO_XEN_MAPCACHE) += xen-mapcache-stub.o # xen backend driver support obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o diff --git a/configure b/configure index fde9bad..c9a13e1 100755 --- a/configure +++ b/configure @@ -3069,6 +3069,9 @@ case $target_arch2 in echo CONFIG_XEN=y $config_target_mak echo LIBS+=$xen_libs $config_target_mak echo CONFIG_XEN_CTRL_INTERFACE_VERSION=$xen_ctrl_version $config_target_mak + if test $cpu = i386 -o $cpu = x86_64; then + echo CONFIG_XEN_MAPCACHE=y $config_target_mak + fi fi esac case $target_arch2 in diff --git a/exec.c b/exec.c index e950df2..3b137dc 100644 --- a/exec.c +++ b/exec.c @@ -32,6 +32,7 @@ #include hw/qdev.h #include osdep.h #include kvm.h +#include hw/xen.h #include qemu-timer.h #if defined(CONFIG_USER_ONLY) #include qemu.h @@ -51,6 +52,8 @@ #include libutil.h #endif #endif +#else /* !CONFIG_USER_ONLY */ +#include xen-mapcache.h #endif //#define DEBUG_TB_INVALIDATE @@ -2835,6 +2838,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name, } } +new_block-offset = find_ram_offset(size); if (host) { new_block-host = host; } else { @@ -2856,13 +2860,15 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); #else -new_block-host = qemu_vmalloc(size); +if (xen_mapcache_enabled()) { +xen_ram_alloc(new_block-offset, size); +} else { +new_block-host = qemu_vmalloc(size); +} #endif qemu_madvise(new_block-host, size, QEMU_MADV_MERGEABLE); } } - -new_block-offset = find_ram_offset(size); new_block-length = size; QLIST_INSERT_HEAD(ram_list.blocks, new_block, next); @@ -2903,7 +2909,11 @@ void qemu_ram_free(ram_addr_t addr) #if defined(TARGET_S390X) defined(CONFIG_KVM) munmap(block-host, block-length); #else -qemu_vfree(block-host); +if (xen_mapcache_enabled()) { +qemu_invalidate_entry(block-host); +} else { +qemu_vfree(block-host); +} #endif } qemu_free(block); @@ -2929,6 +2939,15 @@ void *qemu_get_ram_ptr(ram_addr_t addr) if (addr - block-offset block-length) { QLIST_REMOVE(block, next); QLIST_INSERT_HEAD(ram_list.blocks, block, next); +if (xen_mapcache_enabled()) { +/* We need to check if the requested address is in the RAM + * because we don't want to map the entire memory in QEMU. + */ +if (block-offset == 0) { +return qemu_map_cache(addr, 0, 1); +} +block-host = qemu_map_cache(block-offset, block-length, 1); +} return block-host + (addr - block-offset); } } @@ -2964,11 +2983,21 @@ int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr) uint8_t *host = ptr; QLIST_FOREACH(block, ram_list.blocks, next) { +/* This case append when the
[Qemu-devel] Re: [PATCH 15/19] savevm: introduce qemu_savevm_trans_{begin, commit}.
2011/2/2 Paolo Bonzini pbonz...@redhat.com: On 02/01/2011 07:21 PM, Yoshiaki Tamura wrote: Paolo, I refactored the savevm functions. Could you give me your comments? I didn't review it thoroughly, but the abstractions seem okay. Thanks. Since It got a bit messy, I wanted hear your opinion. Yoshi Paolo -- 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] [PATCH V10 01/15] xen: Replace some tab-indents with spaces (clean-up).
From: Anthony PERARD anthony.per...@citrix.com Signed-off-by: Anthony PERARD anthony.per...@citrix.com Acked-by: Alexander Graf ag...@suse.de --- hw/xen_backend.c | 308 +- hw/xen_disk.c| 394 +++--- hw/xen_nic.c | 222 +++--- 3 files changed, 462 insertions(+), 462 deletions(-) diff --git a/hw/xen_backend.c b/hw/xen_backend.c index a2e408f..860b038 100644 --- a/hw/xen_backend.c +++ b/hw/xen_backend.c @@ -59,7 +59,7 @@ int xenstore_write_str(const char *base, const char *node, const char *val) snprintf(abspath, sizeof(abspath), %s/%s, base, node); if (!xs_write(xenstore, 0, abspath, val, strlen(val))) - return -1; +return -1; return 0; } @@ -95,7 +95,7 @@ int xenstore_read_int(const char *base, const char *node, int *ival) val = xenstore_read_str(base, node); if (val 1 == sscanf(val, %d, ival)) - rc = 0; +rc = 0; qemu_free(val); return rc; } @@ -134,16 +134,16 @@ int xenstore_read_fe_int(struct XenDevice *xendev, const char *node, int *ival) const char *xenbus_strstate(enum xenbus_state state) { - static const char *const name[] = { - [ XenbusStateUnknown ] = Unknown, - [ XenbusStateInitialising ] = Initialising, - [ XenbusStateInitWait ] = InitWait, - [ XenbusStateInitialised ] = Initialised, - [ XenbusStateConnected] = Connected, - [ XenbusStateClosing ] = Closing, - [ XenbusStateClosed ] = Closed, - }; - return (state ARRAY_SIZE(name)) ? name[state] : INVALID; +static const char *const name[] = { +[ XenbusStateUnknown ] = Unknown, +[ XenbusStateInitialising ] = Initialising, +[ XenbusStateInitWait ] = InitWait, +[ XenbusStateInitialised ] = Initialised, +[ XenbusStateConnected] = Connected, +[ XenbusStateClosing ] = Closing, +[ XenbusStateClosed ] = Closed, +}; +return (state ARRAY_SIZE(name)) ? name[state] : INVALID; } int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state) @@ -152,9 +152,9 @@ int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state) rc = xenstore_write_be_int(xendev, state, state); if (rc 0) - return rc; +return rc; xen_be_printf(xendev, 1, backend state: %s - %s\n, - xenbus_strstate(xendev-be_state), xenbus_strstate(state)); + xenbus_strstate(xendev-be_state), xenbus_strstate(state)); xendev-be_state = state; return 0; } @@ -166,13 +166,13 @@ struct XenDevice *xen_be_find_xendev(const char *type, int dom, int dev) struct XenDevice *xendev; QTAILQ_FOREACH(xendev, xendevs, next) { - if (xendev-dom != dom) - continue; - if (xendev-dev != dev) - continue; - if (strcmp(xendev-type, type) != 0) - continue; - return xendev; +if (xendev-dom != dom) +continue; +if (xendev-dev != dev) +continue; +if (strcmp(xendev-type, type) != 0) +continue; +return xendev; } return NULL; } @@ -188,7 +188,7 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev, xendev = xen_be_find_xendev(type, dom, dev); if (xendev) - return xendev; +return xendev; /* init new xendev */ xendev = qemu_mallocz(ops-size); @@ -199,9 +199,9 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev, dom0 = xs_get_domain_path(xenstore, 0); snprintf(xendev-be, sizeof(xendev-be), %s/backend/%s/%d/%d, -dom0, xendev-type, xendev-dom, xendev-dev); + dom0, xendev-type, xendev-dom, xendev-dev); snprintf(xendev-name, sizeof(xendev-name), %s-%d, -xendev-type, xendev-dev); + xendev-type, xendev-dev); free(dom0); xendev-debug = debug; @@ -209,28 +209,28 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev, xendev-evtchndev = xc_evtchn_open(); if (xendev-evtchndev 0) { - xen_be_printf(NULL, 0, can't open evtchn device\n); - qemu_free(xendev); - return NULL; +xen_be_printf(NULL, 0, can't open evtchn device\n); +qemu_free(xendev); +return NULL; } fcntl(xc_evtchn_fd(xendev-evtchndev), F_SETFD, FD_CLOEXEC); if (ops-flags DEVOPS_FLAG_NEED_GNTDEV) { - xendev-gnttabdev = xc_gnttab_open(); - if (xendev-gnttabdev 0) { - xen_be_printf(NULL, 0, can't open gnttab device\n); - xc_evtchn_close(xendev-evtchndev); - qemu_free(xendev); - return NULL; - } +xendev-gnttabdev = xc_gnttab_open(); +if (xendev-gnttabdev 0) { +
[Qemu-devel] Re: [V4 PATCH 3/8] Add client side interfaces for chroot environment
On Tue, Feb 1, 2011 at 5:26 AM, M. Mohan Kumar mo...@in.ibm.com wrote: +/* Receive file descriptor and error status from chroot process */ +static int v9fs_receivefd(int sockfd, int *error) The return value and int *error overlap in functionality. Would it be possible to have only one mechanism for returning errors? *error = 0 is never done so a caller that passes an uninitialized local variable gets back junk when the function succeeds. It would be safer to clear it at the start of this function. Inconsistent use of errno constants and -1: return -EIO; return -1; /* == -EPERM, probably not what you wanted */ How about getting rid of int *error and returning the -errno? If if_error is set then return -fd_info.error. +/* + * V9fsFileObjectRequest is written into the socket by QEMU process. + * Then this request is read by chroot process using read_request function + */ +static int v9fs_write_request(int sockfd, V9fsFileObjectRequest *request) +{ + int retval, length; + char *buff, *buffp; + + length = sizeof(request-data) + request-data.path_len + + request-data.oldpath_len; + + buff = qemu_malloc(length); + buffp = buff; + memcpy(buffp, request-data, sizeof(request-data)); + buffp += sizeof(request-data); + memcpy(buffp, request-path.path, request-data.path_len); + buffp += request-data.path_len; + memcpy(buffp, request-path.old_path, request-data.oldpath_len); + + retval = qemu_write_full(sockfd, buff, length); qemu_free(buff); Also, weren't you doing the malloc() + single write() to avoid interleaved write()? Is that still necessary, I thought a mutex was introduced? It's probably worth adding a comment to explain why you're doing the malloc + write. Stefan
[Qemu-devel] [PATCH V10 02/15] xen: Make xen build only on x86 target.
From: Anthony PERARD anthony.per...@citrix.com Signed-off-by: Anthony PERARD anthony.per...@citrix.com Acked-by: Alexander Graf ag...@suse.de --- Makefile.objs |4 Makefile.target |4 +++- configure |5 + 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/Makefile.objs b/Makefile.objs index 93406ff..d91b9bc 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -150,10 +150,6 @@ slirp-obj-y += slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o slirp-obj-y += tcp_subr.o tcp_timer.o udp.o bootp.o tftp.o common-obj-$(CONFIG_SLIRP) += $(addprefix slirp/, $(slirp-obj-y)) -# xen backend driver support -common-obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o -common-obj-$(CONFIG_XEN) += xen_console.o xenfb.o xen_disk.o xen_nic.o - ## # libuser diff --git a/Makefile.target b/Makefile.target index b0ba95f..db29e96 100644 --- a/Makefile.target +++ b/Makefile.target @@ -206,7 +206,9 @@ QEMU_CFLAGS += $(VNC_JPEG_CFLAGS) QEMU_CFLAGS += $(VNC_PNG_CFLAGS) # xen backend driver support -obj-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o +obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o +obj-$(CONFIG_XEN) += xen_console.o xenfb.o xen_disk.o xen_nic.o +obj-i386-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o # Inter-VM PCI shared memory obj-$(CONFIG_KVM) += ivshmem.o diff --git a/configure b/configure index 210670c..5a9121d 100755 --- a/configure +++ b/configure @@ -1151,7 +1151,6 @@ int main(void) { xs_daemon_open(); xc_interface_open(); return 0; } EOF if compile_prog $xen_libs ; then xen=yes -libs_softmmu=$xen_libs $libs_softmmu else if test $xen = yes ; then feature_not_found xen @@ -2674,9 +2673,6 @@ if test $bluez = yes ; then echo CONFIG_BLUEZ=y $config_host_mak echo BLUEZ_CFLAGS=$bluez_cflags $config_host_mak fi -if test $xen = yes ; then - echo CONFIG_XEN=y $config_host_mak -fi if test $io_thread = yes ; then echo CONFIG_IOTHREAD=y $config_host_mak echo CONFIG_THREAD=y $config_host_mak @@ -3012,6 +3008,7 @@ case $target_arch2 in i386|x86_64) if test $xen = yes -a $target_softmmu = yes ; then echo CONFIG_XEN=y $config_target_mak + echo LIBS+=$xen_libs $config_target_mak fi esac case $target_arch2 in -- 1.7.1
[Qemu-devel] Re: stable-0.14 is now open
On 02/02/2011 03:17 AM, Anthony Liguori wrote: Please start sending patches and pull requests specifically against this branch. The 0.14.0-rc0 will be officially announced tomorrow once the mirrors propagate. I would like the alarm timer fixes in 0.14. Paolo
[Qemu-devel] [PATCH V10 08/15] xen: Introduce Xen Interrupt Controller
From: Anthony PERARD anthony.per...@citrix.com Every set_irq call makes a Xen hypercall. Signed-off-by: Anthony PERARD anthony.per...@citrix.com Signed-off-by: Stefano Stabellini stefano.stabell...@eu.citrix.com --- hw/pc_piix.c |8 ++-- hw/xen.h |2 ++ xen-all.c| 12 xen-stub.c |5 + 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/hw/pc_piix.c b/hw/pc_piix.c index 765877c..27d9030 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -98,8 +98,12 @@ static void pc_init1(ram_addr_t ram_size, pc_memory_init(ram_size, kernel_filename, kernel_cmdline, initrd_filename, below_4g_mem_size, above_4g_mem_size); -cpu_irq = pc_allocate_cpu_irq(); -i8259 = i8259_init(cpu_irq[0]); +if (!xen_enabled()) { +cpu_irq = pc_allocate_cpu_irq(); +i8259 = i8259_init(cpu_irq[0]); +} else { +i8259 = xen_interrupt_controller_init(); +} isa_irq_state = qemu_mallocz(sizeof(*isa_irq_state)); isa_irq_state-i8259 = i8259; if (pci_enabled) { diff --git a/hw/xen.h b/hw/xen.h index 2a53f8b..37d7b99 100644 --- a/hw/xen.h +++ b/hw/xen.h @@ -35,6 +35,8 @@ int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num); void xen_piix3_set_irq(void *opaque, int irq_num, int level); void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len); +qemu_irq *xen_interrupt_controller_init(void); + void pci_xen_platform_init(PCIBus *bus); int xen_init(int smp_cpus); diff --git a/xen-all.c b/xen-all.c index 123decb..73149f2 100644 --- a/xen-all.c +++ b/xen-all.c @@ -42,6 +42,18 @@ void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len) } } +/* Xen Interrupt Controller */ + +static void xen_set_irq(void *opaque, int irq, int level) +{ +xc_hvm_set_isa_irq_level(xen_xc, xen_domid, irq, level); +} + +qemu_irq *xen_interrupt_controller_init(void) +{ +return qemu_allocate_irqs(xen_set_irq, NULL, 16); +} + /* Initialise Xen */ int xen_init(int smp_cpus) diff --git a/xen-stub.c b/xen-stub.c index ba95537..bc2ae12 100644 --- a/xen-stub.c +++ b/xen-stub.c @@ -24,6 +24,11 @@ void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len) { } +qemu_irq *xen_interrupt_controller_init(void) +{ +return NULL; +} + void pci_xen_platform_init(PCIBus *bus) { } -- 1.7.1
[Qemu-devel] [0.14+master][PATCH 3/3] mc146818rtc: Handle host clock warps
Make use of the new warp notifier to update the RTC whenever rtc_clock is the host clock and that happens to jump backward. This avoids that the RTC stalls for the period the host clock was set back. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- hw/mc146818rtc.c | 17 + 1 files changed, 17 insertions(+), 0 deletions(-) diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c index a1b0e31..04da794 100644 --- a/hw/mc146818rtc.c +++ b/hw/mc146818rtc.c @@ -572,6 +572,21 @@ static const VMStateDescription vmstate_rtc = { } }; +static void rtc_clock_warp(QEMUClock *clock, int64_t now, void *opaque) +{ +RTCState *s = opaque; + +rtc_set_date_from_host(s-dev); +s-next_second_time = now + (get_ticks_per_sec() * 99) / 100; +qemu_mod_timer(s-second_timer2, s-next_second_time); +rtc_timer_update(s, now); +#ifdef TARGET_I386 +if (rtc_td_hack) { +rtc_coalesced_timer_update(s); +} +#endif +} + static void rtc_reset(void *opaque) { RTCState *s = opaque; @@ -608,6 +623,8 @@ static int rtc_initfn(ISADevice *dev) s-second_timer = qemu_new_timer(rtc_clock, rtc_update_second, s); s-second_timer2 = qemu_new_timer(rtc_clock, rtc_update_second2, s); +qemu_register_clock_warp(rtc_clock, rtc_clock_warp, s); + s-next_second_time = qemu_get_clock(rtc_clock) + (get_ticks_per_sec() * 99) / 100; qemu_mod_timer(s-second_timer2, s-next_second_time); -- 1.7.1
[Qemu-devel] [PATCH V10 10/15] configure: Always use 64bits target physical addresses with xen enabled.
From: Anthony PERARD anthony.per...@citrix.com With MapCache, we can handle a 64b target, even with a 32b host/qemu. So, we need to have target_phys_addr_t to 64bits. Signed-off-by: Anthony PERARD anthony.per...@citrix.com Acked-by: Alexander Graf ag...@suse.de --- configure |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/configure b/configure index c9a13e1..76177d8 100755 --- a/configure +++ b/configure @@ -3066,6 +3066,7 @@ echo TARGET_ABI_DIR=$TARGET_ABI_DIR $config_target_mak case $target_arch2 in i386|x86_64) if test $xen = yes -a $target_softmmu = yes ; then + target_phys_bits=64 echo CONFIG_XEN=y $config_target_mak echo LIBS+=$xen_libs $config_target_mak echo CONFIG_XEN_CTRL_INTERFACE_VERSION=$xen_ctrl_version $config_target_mak -- 1.7.1
[Qemu-devel] Re: [PATCH 0/4] fix/add CONFIG_* options for VMWare device emulation
On 02/01/2011 07:10 PM, Blue Swirl wrote: One way to solve this which would preserve the device model would be to add stub devices. For example, hw/vmmouse-stub.c would be: void *vmmouse_init(void *m) { return NULL; } This is the wrong direction, unless you can somehow automatically generate the stub file. The only other solution I can think of is weak symbols. There are subtle differences between Windows and Linux weak symbols, but luckily we do not care about it. See http://cygwin.com/ml/cygwin/2010-04/msg00281.html Paolo
[Qemu-devel] Re: [0.14] Queue of 0.14 patches/pull?
On 01/28/2011 03:21 PM, Yoshiaki Tamura wrote: http://permalink.gmane.org/gmane.comp.emulators.qemu/91096 should be applied in any case, as it is a regression from 0.12. Oops, I forgot to list it:) Thanks for catching. This one is still missing in 0.14. Paolo
[Qemu-devel] Re: [PATCH 15/19] savevm: introduce qemu_savevm_trans_{begin, commit}.
On 02/01/2011 07:21 PM, Yoshiaki Tamura wrote: Paolo, I refactored the savevm functions. Could you give me your comments? I didn't review it thoroughly, but the abstractions seem okay. Paolo
Re: [Qemu-devel] [PATCHv8 12/16] Add bootindex parameter to net/block/fd device
Gleb Natapov g...@redhat.com writes: If bootindex is specified on command line a string that describes device in firmware readable way is added into sorted list. Later this list will be passed into firmware to control boot order. Signed-off-by: Gleb Natapov g...@redhat.com Just noticed something that slipped through review: [...] diff --git a/vl.c b/vl.c index 2cd263e..dadc161 100644 --- a/vl.c +++ b/vl.c [...] @@ -693,6 +704,35 @@ static void restore_boot_devices(void *opaque) qemu_free(standard_boot_devices); } +void add_boot_device_path(int32_t bootindex, DeviceState *dev, + const char *suffix) +{ +FWBootEntry *node, *i; + +if (bootindex 0) { +return; +} + +assert(dev != NULL || suffix != NULL); + +node = qemu_mallocz(sizeof(FWBootEntry)); +node-bootindex = bootindex; +node-suffix = strdup(suffix); qemu_strdup()? +node-dev = dev; + +QTAILQ_FOREACH(i, fw_boot_order, link) { +if (i-bootindex == bootindex) { +fprintf(stderr, Two devices with same boot index %d\n, bootindex); +exit(1); +} else if (i-bootindex bootindex) { +continue; +} +QTAILQ_INSERT_BEFORE(i, node, link); +return; +} +QTAILQ_INSERT_TAIL(fw_boot_order, node, link); +} + static void numa_add(const char *optarg) { char option[128];
Re: [Qemu-devel] [PATCH 7/7] ahci: work around bug with level interrupts
Am 01.02.2011 21:10, schrieb Alexander Graf: On 01.02.2011, at 20:58, Aurelien Jarno wrote: On Tue, Feb 01, 2011 at 07:35:01PM +0100, Alexander Graf wrote: When using level based interrupts, the interrupt is treated the same as an edge triggered one: leaving the line up does not retrigger the interrupt. In fact, when not lowering the line, we won't ever get a new interrupt inside the guest. So let's always retrigger an interrupt as soon as the OS ack'ed something on the device. This way we're sure the guest doesn't starve on interrupts until someone fixes the actual interrupt path. Signed-off-by: Alexander Graf ag...@suse.de --- v2 - v3: - add comment about the interrupt hack --- hw/ide/ahci.c |8 ++-- 1 files changed, 6 insertions(+), 2 deletions(-) diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c index 98bdf70..95e1cf7 100644 --- a/hw/ide/ahci.c +++ b/hw/ide/ahci.c @@ -152,11 +152,15 @@ static void ahci_check_irq(AHCIState *s) } } +/* XXX We lower the interrupt line here because of a bug with interrupt + handling in Qemu. When leaving a line up, the interrupt does + not get retriggered automatically currently. Once that bug is fixed, + this workaround is not necessary anymore and we only need to lower + in the else branch. */ +ahci_irq_lower(s, NULL); if (s-control_regs.irqstatus (s-control_regs.ghc HOST_CTL_IRQ_EN)) { ahci_irq_raise(s, NULL); -} else { -ahci_irq_lower(s, NULL); } } It's a lot better that way, however I think we should still keep the correct code. Also given this problem only concerns the i386 target (ppc code is actually a bit strange, but at the end does the correct thing), it's something we should probably mention. What about something like that? While I dislike #if 0s in released code in general, it's fine with me. I know what I meant based on the comment, but for others this might make it more explicit. How would we go about committing this? Kevin, will you just change the code inside your tree? I would prefer if you sent a new version of this patch. Kevin
[Qemu-devel] [PATCH 7/7] ahci: work around bug with level interrupts
When using level based interrupts, the interrupt is treated the same as an edge triggered one: leaving the line up does not retrigger the interrupt. In fact, when not lowering the line, we won't ever get a new interrupt inside the guest. So let's always retrigger an interrupt as soon as the OS ack'ed something on the device. This way we're sure the guest doesn't starve on interrupts until someone fixes the actual interrupt path. Signed-off-by: Alexander Graf ag...@suse.de --- v2 - v3: - add comment about the interrupt hack v3 - v4: - embed non-workaround version in the code --- hw/ide/ahci.c | 13 + 1 files changed, 13 insertions(+), 0 deletions(-) diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c index 98bdf70..10377ca 100644 --- a/hw/ide/ahci.c +++ b/hw/ide/ahci.c @@ -152,12 +152,25 @@ static void ahci_check_irq(AHCIState *s) } } +/* XXX We always lower the interrupt line here because of a bug with + interrupt handling in Qemu. When leaving a line up, the interrupt + does not get retriggered automatically currently. Once that bug is + fixed, this workaround is not necessary anymore and we only need to + lower in the else branch. */ +#if 0 if (s-control_regs.irqstatus (s-control_regs.ghc HOST_CTL_IRQ_EN)) { ahci_irq_raise(s, NULL); } else { ahci_irq_lower(s, NULL); } +#else +ahci_irq_lower(s, NULL); +if (s-control_regs.irqstatus +(s-control_regs.ghc HOST_CTL_IRQ_EN)) { +ahci_irq_raise(s, NULL); +} +#endif } static void ahci_trigger_irq(AHCIState *s, AHCIDevice *d, -- 1.6.0.2
[Qemu-devel] [PATCH v2 0/2] virtagent - fsfreeze support
From: Jes Sorensen jes.soren...@redhat.com Hi This is a first attempt to add fsfreeze support to virtagent. The idea is for the guest agent to walk the list of locally mounted file systems in the guest, and issuing an ioctl to freeze them. The host can then do a live snapshot of the guest, obtaining stable file systems. After the snapshot, the host then calls the thaw function in virtagent, which goes through the list of previously frozen file systems and unfreezes them. The list walking ignores remote file systems such as NFS and CIFS as well as all pseudo file systems. The guest agent code is in the first patch, and host agent code is in the second patch. For now there is only human monitor support, but it should be pretty straight forward to add QMP support as well. Comments and suggestions welcome! v2 of the patch addresses the issues pointed out by Stefan and Michael. Cheers, Jes Jes Sorensen (2): Add virtagent file system freeze/thaw Add monitor commands for fsfreeze support hmp-commands.hx| 48 +++ virtagent-common.h |9 ++ virtagent-server.c | 190 ++ virtagent.c| 235 virtagent.h|9 ++ 5 files changed, 491 insertions(+), 0 deletions(-) -- 1.7.3.5
[Qemu-devel] [PATCH] do not pass NULL to strdup.
Also use qemu_strdup() instead of strdup() in bootindex code. Signed-off-by: Gleb Natapov g...@redhat.com --- Should go to stable too. diff --git a/vl.c b/vl.c index 655617f..ed2cdfa 100644 --- a/vl.c +++ b/vl.c @@ -738,7 +738,7 @@ void add_boot_device_path(int32_t bootindex, DeviceState *dev, node = qemu_mallocz(sizeof(FWBootEntry)); node-bootindex = bootindex; -node-suffix = strdup(suffix); +node-suffix = suffix ? qemu_strdup(suffix) : NULL; node-dev = dev; QTAILQ_FOREACH(i, fw_boot_order, link) { @@ -785,7 +785,7 @@ char *get_boot_devices_list(uint32_t *size) } else if (devpath) { bootpath = devpath; } else { -bootpath = strdup(i-suffix); +bootpath = qemu_strdup(i-suffix); assert(bootpath); } -- Gleb.
[Qemu-devel] [PATCH V10 05/15] xen: Add xenfv machine
From: Anthony PERARD anthony.per...@citrix.com Introduce the Xen FV (Fully Virtualized) machine to Qemu, some more Xen specific call will be added in further patches. Signed-off-by: Anthony PERARD anthony.per...@citrix.com --- hw/pc.c | 19 +-- hw/pc_piix.c | 21 - hw/xen.h |4 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/hw/pc.c b/hw/pc.c index 4dfdc0b..ab9d365 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -41,6 +41,7 @@ #include sysemu.h #include blockdev.h #include ui/qemu-spice.h +#include xen.h /* output Bochs bios info messages */ //#define DEBUG_BIOS @@ -906,7 +907,11 @@ static void pc_cpu_reset(void *opaque) CPUState *env = opaque; cpu_reset(env); -env-halted = !cpu_is_bsp(env); +if (!xen_enabled()) { +env-halted = !cpu_is_bsp(env); +} else { +env-halted = 1; +} } static CPUState *pc_new_cpu(const char *cpu_model) @@ -940,7 +945,12 @@ void pc_cpus_init(const char *cpu_model) #endif } -for(i = 0; i smp_cpus; i++) { +if (!xen_enabled()) { +for(i = 0; i smp_cpus; i++) { +pc_new_cpu(cpu_model); +} +} else { +/* Xen require only one Qemu VCPU */ pc_new_cpu(cpu_model); } } @@ -968,6 +978,11 @@ void pc_memory_init(ram_addr_t ram_size, *above_4g_mem_size_p = above_4g_mem_size; *below_4g_mem_size_p = below_4g_mem_size; +if (xen_enabled()) { +/* Nothing to do for Xen */ +return; +} + #if TARGET_PHYS_ADDR_BITS == 32 if (above_4g_mem_size 0) { hw_error(To much RAM for 32-bit physical address); diff --git a/hw/pc_piix.c b/hw/pc_piix.c index 7b74473..0ab8907 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -36,6 +36,10 @@ #include sysbus.h #include arch_init.h #include blockdev.h +#include xen.h +#ifdef CONFIG_XEN +# include xen/hvm/hvm_info_table.h +#endif #define MAX_IDE_BUS 2 @@ -86,7 +90,9 @@ static void pc_init1(ram_addr_t ram_size, pc_cpus_init(cpu_model); -vmport_init(); +if (!xen_enabled()) { +vmport_init(); +} /* allocate ram and load rom/bios */ pc_memory_init(ram_size, kernel_filename, kernel_cmdline, initrd_filename, @@ -376,6 +382,16 @@ static QEMUMachine isapc_machine = { .max_cpus = 1, }; +#ifdef CONFIG_XEN +static QEMUMachine xenfv_machine = { +.name = xenfv, +.desc = Xen Fully-virtualized PC, +.init = pc_init_pci, +.max_cpus = HVM_MAX_VCPUS, +.default_machine_opts = accel=xen, +}; +#endif + static void pc_machine_init(void) { qemu_register_machine(pc_machine); @@ -384,6 +400,9 @@ static void pc_machine_init(void) qemu_register_machine(pc_machine_v0_11); qemu_register_machine(pc_machine_v0_10); qemu_register_machine(isapc_machine); +#ifdef CONFIG_XEN +qemu_register_machine(xenfv_machine); +#endif } machine_init(pc_machine_init); diff --git a/hw/xen.h b/hw/xen.h index 183cbb5..3984069 100644 --- a/hw/xen.h +++ b/hw/xen.h @@ -31,4 +31,8 @@ static inline int xen_enabled(void) int xen_init(int smp_cpus); +#if defined(CONFIG_XEN) CONFIG_XEN_CTRL_INTERFACE_VERSION 400 +# define HVM_MAX_VCPUS 32 +#endif + #endif /* QEMU_HW_XEN_H */ -- 1.7.1
Re: [Qemu-devel] [PATCH 7/7] ahci: work around bug with level interrupts
Kevin Wolf wrote: Am 01.02.2011 21:10, schrieb Alexander Graf: On 01.02.2011, at 20:58, Aurelien Jarno wrote: On Tue, Feb 01, 2011 at 07:35:01PM +0100, Alexander Graf wrote: When using level based interrupts, the interrupt is treated the same as an edge triggered one: leaving the line up does not retrigger the interrupt. In fact, when not lowering the line, we won't ever get a new interrupt inside the guest. So let's always retrigger an interrupt as soon as the OS ack'ed something on the device. This way we're sure the guest doesn't starve on interrupts until someone fixes the actual interrupt path. Signed-off-by: Alexander Graf ag...@suse.de --- v2 - v3: - add comment about the interrupt hack --- hw/ide/ahci.c |8 ++-- 1 files changed, 6 insertions(+), 2 deletions(-) diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c index 98bdf70..95e1cf7 100644 --- a/hw/ide/ahci.c +++ b/hw/ide/ahci.c @@ -152,11 +152,15 @@ static void ahci_check_irq(AHCIState *s) } } +/* XXX We lower the interrupt line here because of a bug with interrupt + handling in Qemu. When leaving a line up, the interrupt does + not get retriggered automatically currently. Once that bug is fixed, + this workaround is not necessary anymore and we only need to lower + in the else branch. */ +ahci_irq_lower(s, NULL); if (s-control_regs.irqstatus (s-control_regs.ghc HOST_CTL_IRQ_EN)) { ahci_irq_raise(s, NULL); -} else { -ahci_irq_lower(s, NULL); } } It's a lot better that way, however I think we should still keep the correct code. Also given this problem only concerns the i386 target (ppc code is actually a bit strange, but at the end does the correct thing), it's something we should probably mention. What about something like that? While I dislike #if 0s in released code in general, it's fine with me. I know what I meant based on the comment, but for others this might make it more explicit. How would we go about committing this? Kevin, will you just change the code inside your tree? I would prefer if you sent a new version of this patch. Ok, done :) Alex
[Qemu-devel] [PATCH V10 04/15] xen: Add initialisation of Xen
From: Anthony PERARD anthony.per...@citrix.com Signed-off-by: Anthony PERARD anthony.per...@citrix.com Acked-by: Alexander Graf ag...@suse.de --- Makefile.target |3 +++ hw/xen.h| 13 + vl.c|2 ++ xen-all.c | 29 + xen-stub.c | 17 + 5 files changed, 64 insertions(+), 0 deletions(-) create mode 100644 xen-all.c create mode 100644 xen-stub.c diff --git a/Makefile.target b/Makefile.target index d09719f..00bb690 100644 --- a/Makefile.target +++ b/Makefile.target @@ -3,6 +3,7 @@ GENERATED_HEADERS = config-target.h CONFIG_NO_PCI = $(if $(subst n,,$(CONFIG_PCI)),n,y) CONFIG_NO_KVM = $(if $(subst n,,$(CONFIG_KVM)),n,y) +CONFIG_NO_XEN = $(if $(subst n,,$(CONFIG_XEN)),n,y) include ../config-host.mak include config-devices.mak @@ -207,6 +208,8 @@ QEMU_CFLAGS += $(VNC_PNG_CFLAGS) # xen support obj-$(CONFIG_XEN) += xen_interfaces.o +obj-$(CONFIG_XEN) += xen-all.o +obj-$(CONFIG_NO_XEN) += xen-stub.o # xen backend driver support obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o diff --git a/hw/xen.h b/hw/xen.h index 780dcf7..183cbb5 100644 --- a/hw/xen.h +++ b/hw/xen.h @@ -18,4 +18,17 @@ enum xen_mode { extern uint32_t xen_domid; extern enum xen_mode xen_mode; +extern int xen_allowed; + +static inline int xen_enabled(void) +{ +#ifdef CONFIG_XEN +return xen_allowed; +#else +return 0; +#endif +} + +int xen_init(int smp_cpus); + #endif /* QEMU_HW_XEN_H */ diff --git a/vl.c b/vl.c index 626f4e1..38fa281 100644 --- a/vl.c +++ b/vl.c @@ -259,6 +259,7 @@ static NotifierList machine_init_done_notifiers = static int tcg_allowed = 1; int kvm_allowed = 0; +int xen_allowed = 0; uint32_t xen_domid; enum xen_mode xen_mode = XEN_EMULATE; @@ -1836,6 +1837,7 @@ static struct { int *allowed; } accel_list[] = { { tcg, tcg, tcg_available, tcg_init, tcg_allowed }, +{ xen, Xen, xen_available, xen_init, xen_allowed }, { kvm, KVM, kvm_available, kvm_init, kvm_allowed }, }; diff --git a/xen-all.c b/xen-all.c new file mode 100644 index 000..8d77d42 --- /dev/null +++ b/xen-all.c @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2010 Citrix Ltd. + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ + +#include config.h + +#include hw/xen_common.h +#include hw/xen_backend.h + +/* Initialise Xen */ + +int xen_init(int smp_cpus) +{ +if (xen_mode == XEN_EMULATE) { +xen_mode = XEN_ATTACH; +} +xen_interfaces_init(); +xen_xc = xc_ops.interface_open(0, 0, 0); +if (xen_xc == XC_HANDLER_INITIAL_VALUE) { +xen_be_printf(NULL, 0, can't open xen interface\n); +return -1; +} + +return 0; +} diff --git a/xen-stub.c b/xen-stub.c new file mode 100644 index 000..0fa9c51 --- /dev/null +++ b/xen-stub.c @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2010 Citrix Ltd. + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ + +#include config.h + +#include qemu-common.h +#include hw/xen.h + +int xen_init(int smp_cpus) +{ +return -ENOSYS; +} -- 1.7.1
Re: [Qemu-devel] KVM: Windows 64-bit troubles with user space irqchip
On 2011-02-02 15:43, Jan Kiszka wrote: On 2011-02-02 15:35, Avi Kivity wrote: On 02/02/2011 04:30 PM, Jan Kiszka wrote: On 2011-02-02 14:05, Avi Kivity wrote: On 02/02/2011 02:50 PM, Jan Kiszka wrote: Opps, -smp 1. With -smp 2 it boot almost completely and then hangs. Ah, good (or not good). With Windows 2003 Server, I actually get a Blue Screen (Stop 0x00b8). Userspace APIC is broken since it may run with an outdated cr8, does reverting 27a4f7976d5 help? Can you elaborate on what is broken? The way hw/apic.c maintains the tpr? Would it make sense to compare this against the in-kernel model? Or do you mean something else? The problem, IIRC, was that we look up the TPR but it may already have been changed by the running vcpu. Not 100% sure. If that is indeed the problem then the fix would be to process the APIC in vcpu context (which is what the kernel does - we set a bit in the IRR and all further processing is synchronous). You mean: user space changes the tpr value while the vcpu is in KVM_RUN, then we return from the kernel and overwrite the tpr in the apic with the vcpu's view, right? Hmm, probably rather that there is a discrepancy between tpr and irr. The latter is changed asynchronously /wrt to the vcpu, the former /wrt the user space device model. Run apic_set_irq on the vcpu? Jan -- Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
[Qemu-devel] Re: [PATCH 1/3] use nanoseconds everywhere for timeout computation
On 02/01/2011 07:47 PM, Aurelien Jarno wrote: qemu_get_clock() which can return different unit depending on what you ask (and in my opinion should simply disappear because it's the best way to have bugs), Agreed. Paolo
Re: [Qemu-devel] KVM: Windows 64-bit troubles with user space irqchip
On 2011-02-02 17:39, Gleb Natapov wrote: On Wed, Feb 02, 2011 at 05:36:53PM +0100, Jan Kiszka wrote: On 2011-02-02 17:29, Gleb Natapov wrote: On Wed, Feb 02, 2011 at 04:52:11PM +0100, Jan Kiszka wrote: On 2011-02-02 16:46, Gleb Natapov wrote: On Wed, Feb 02, 2011 at 04:35:25PM +0100, Jan Kiszka wrote: On 2011-02-02 16:09, Avi Kivity wrote: On 02/02/2011 04:52 PM, Jan Kiszka wrote: On 2011-02-02 15:43, Jan Kiszka wrote: On 2011-02-02 15:35, Avi Kivity wrote: On 02/02/2011 04:30 PM, Jan Kiszka wrote: On 2011-02-02 14:05, Avi Kivity wrote: On 02/02/2011 02:50 PM, Jan Kiszka wrote: Opps, -smp 1. With -smp 2 it boot almost completely and then hangs. Ah, good (or not good). With Windows 2003 Server, I actually get a Blue Screen (Stop 0x00b8). Userspace APIC is broken since it may run with an outdated cr8, does reverting 27a4f7976d5 help? Can you elaborate on what is broken? The way hw/apic.c maintains the tpr? Would it make sense to compare this against the in-kernel model? Or do you mean something else? The problem, IIRC, was that we look up the TPR but it may already have been changed by the running vcpu. Not 100% sure. If that is indeed the problem then the fix would be to process the APIC in vcpu context (which is what the kernel does - we set a bit in the IRR and all further processing is synchronous). You mean: user space changes the tpr value while the vcpu is in KVM_RUN, then we return from the kernel and overwrite the tpr in the apic with the vcpu's view, right? Hmm, probably rather that there is a discrepancy between tpr and irr. The latter is changed asynchronously /wrt to the vcpu, the former /wrt the user space device model. And yet, both are synchronized via qemu_mutex. So we're still missing something in this picture. Run apic_set_irq on the vcpu? static void apic_set_irq(APICState *s, int vector_num, int trigger_mode) { apic_irq_delivered += !get_bit(s-irr, vector_num); trace_apic_set_irq(apic_irq_delivered); set_bit(s-irr, vector_num); This is even more async with kernel irqchip if (trigger_mode) set_bit(s-tmr, vector_num); else reset_bit(s-tmr, vector_num); This is protected by qemu_mutex apic_update_irq(s); This will be run the next time the vcpu exits, via apic_get_interrupt(). The decision to pend an IRQ (and potentially kick the vcpu) takes place immediately in acip_update_irq. And it is based on current irr as well as tpr. But we update again when user space returns with a new value. } Did you check whether reverting that commit helps? Just did so, and I can no longer reproduce the problem. Hmm... If there is no problem in the logic of this commit (and I do not see one yet) then we somewhere miss kicking vcpu when interrupt, that should be handled, arrives? I'm not yet confident about the logic of the kernel patch: mov to cr8 is serializing. If the guest raises the tpr and then signals this with a succeeding, non vm-exiting instruction to the other vcpus, one of those could inject an interrupt with a higher priority than the previous tpr, but a lower one than current tpr. QEMU user space would accept this interrupt - and would likely surprise the guest. Do I miss something? Injection happens by vcpu thread on cpu entry: run-request_interrupt_window = kvm_arch_try_push_interrupts(env); and tpr is synced on vcpu exit, so I do not yet see how what you describe above may happen since during injection vcpu should see correct tpr. Hmm, maybe this is the key: Once we call into apic_get_interrupt (because CPU_INTERRUPT_HARD was set as described above) and we find a pending irq below the tpr, we inject a spurious vector instead. That should be easy to verify. I expect Windows to BSOD upon receiving spurious vector though. I hacked spurious irq injection away, but the issue remains. At the same time, Windows is receiving tons of spurious interrupts without any complaints, even without that tpr optimization in the kernel. So this is obviously not yet the key. Let's try your idea that we miss a wakeup. Jan -- Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
Re: [Qemu-devel] [PATCH 1/2] Add virtagent file system freeze/thaw
On Tue, Feb 1, 2011 at 10:58 AM, jes.soren...@redhat.com wrote: From: Jes Sorensen jes.soren...@redhat.com Implement freeze/thaw support in the guest, allowing the host to request the guest freezes all it's file systems before a live snapshot is performed. - fsfreeze(): Walk the list of mounted local real file systems, and freeze them. Does this add a requirement that guest agent code issues no disk I/O in its main loop (e.g. logging)? Otherwise we might deadlock ourselves waiting for I/O which is never issued. Stefan
[Qemu-devel] [0.14+master][PATCH 0/3] Let RTC follow backward jumps of host clock immediately
By default, we base the mc146818 RTC on the host clock (CLOCK_REALTIME). This works fine if only the frequency of the host clock is tuned (e.g. by NTP) or if it is set to a future time. However, if the host is tuned backward, e.g. because NTP obtained the correct time after the guest was already started or the admin decided to tune the local time, we see an unpleasant effect in the guest: The RTC will stall for the period the host clock is set back. We identified that one prominent guest affected by this is Windows which relies on the periodic RTC interrupt for time keeping. This series address the issue by detecting those warps and providing a callback mechanism to device models. The RTC is enabled to update its timers and register content immediately. Tested successfully both with hwclock in a Linux guest and by monitoring the Windows clock while fiddling with the host time. Note that if this kind of RTC adjustment is not wanted, the user is still free to decouple the RTC from the host clock and base it on the VM clock - just like before. Jan Kiszka (3): qemu-timer: Consolidate qemu_get_clock and qemu_get_clock_ns qemu-timer: Introduce warp callback mc146818rtc: Handle host clock warps hw/mc146818rtc.c | 17 qemu-timer.c | 77 -- qemu-timer.h |5 +++ 3 files changed, 85 insertions(+), 14 deletions(-)
[Qemu-devel] [Bug 606658] Re: system_powerdown broken
** Changed in: qemu Status: Confirmed = Fix Committed -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/606658 Title: system_powerdown broken Status in QEMU: Fix Committed Bug description: I discovered that system_powerdown does nothing. Debian, kvm, qemu version: 0.12.4
[Qemu-devel] [0.14+master][PATCH 1/3] qemu-timer: Consolidate qemu_get_clock and qemu_get_clock_ns
Both functions have a lot in common, push those bits into a shared helper. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- qemu-timer.c | 27 +-- 1 files changed, 13 insertions(+), 14 deletions(-) diff --git a/qemu-timer.c b/qemu-timer.c index db1ec49..94c1073 100644 --- a/qemu-timer.c +++ b/qemu-timer.c @@ -504,11 +504,9 @@ static void qemu_run_timers(QEMUClock *clock) } } -int64_t qemu_get_clock(QEMUClock *clock) +static int64_t get_clock_common(QEMUClock *clock) { switch(clock-type) { -case QEMU_CLOCK_REALTIME: -return get_clock() / 100; default: case QEMU_CLOCK_VIRTUAL: if (use_icount) { @@ -521,20 +519,21 @@ int64_t qemu_get_clock(QEMUClock *clock) } } +int64_t qemu_get_clock(QEMUClock *clock) +{ +if (clock-type == QEMU_CLOCK_REALTIME) { +return get_clock() / 100; +} else { +return get_clock_common(clock); +} +} + int64_t qemu_get_clock_ns(QEMUClock *clock) { -switch(clock-type) { -case QEMU_CLOCK_REALTIME: +if (clock-type == QEMU_CLOCK_REALTIME) { return get_clock(); -default: -case QEMU_CLOCK_VIRTUAL: -if (use_icount) { -return cpu_get_icount(); -} else { -return cpu_get_clock(); -} -case QEMU_CLOCK_HOST: -return get_clock_realtime(); +} else { +return get_clock_common(clock); } } -- 1.7.1
Re: [Qemu-devel] KVM: Windows 64-bit troubles with user space irqchip
On Wed, Feb 02, 2011 at 04:52:11PM +0100, Jan Kiszka wrote: On 2011-02-02 16:46, Gleb Natapov wrote: On Wed, Feb 02, 2011 at 04:35:25PM +0100, Jan Kiszka wrote: On 2011-02-02 16:09, Avi Kivity wrote: On 02/02/2011 04:52 PM, Jan Kiszka wrote: On 2011-02-02 15:43, Jan Kiszka wrote: On 2011-02-02 15:35, Avi Kivity wrote: On 02/02/2011 04:30 PM, Jan Kiszka wrote: On 2011-02-02 14:05, Avi Kivity wrote: On 02/02/2011 02:50 PM, Jan Kiszka wrote: Opps, -smp 1. With -smp 2 it boot almost completely and then hangs. Ah, good (or not good). With Windows 2003 Server, I actually get a Blue Screen (Stop 0x00b8). Userspace APIC is broken since it may run with an outdated cr8, does reverting 27a4f7976d5 help? Can you elaborate on what is broken? The way hw/apic.c maintains the tpr? Would it make sense to compare this against the in-kernel model? Or do you mean something else? The problem, IIRC, was that we look up the TPR but it may already have been changed by the running vcpu. Not 100% sure. If that is indeed the problem then the fix would be to process the APIC in vcpu context (which is what the kernel does - we set a bit in the IRR and all further processing is synchronous). You mean: user space changes the tpr value while the vcpu is in KVM_RUN, then we return from the kernel and overwrite the tpr in the apic with the vcpu's view, right? Hmm, probably rather that there is a discrepancy between tpr and irr. The latter is changed asynchronously /wrt to the vcpu, the former /wrt the user space device model. And yet, both are synchronized via qemu_mutex. So we're still missing something in this picture. Run apic_set_irq on the vcpu? static void apic_set_irq(APICState *s, int vector_num, int trigger_mode) { apic_irq_delivered += !get_bit(s-irr, vector_num); trace_apic_set_irq(apic_irq_delivered); set_bit(s-irr, vector_num); This is even more async with kernel irqchip if (trigger_mode) set_bit(s-tmr, vector_num); else reset_bit(s-tmr, vector_num); This is protected by qemu_mutex apic_update_irq(s); This will be run the next time the vcpu exits, via apic_get_interrupt(). The decision to pend an IRQ (and potentially kick the vcpu) takes place immediately in acip_update_irq. And it is based on current irr as well as tpr. But we update again when user space returns with a new value. } Did you check whether reverting that commit helps? Just did so, and I can no longer reproduce the problem. Hmm... If there is no problem in the logic of this commit (and I do not see one yet) then we somewhere miss kicking vcpu when interrupt, that should be handled, arrives? I'm not yet confident about the logic of the kernel patch: mov to cr8 is serializing. If the guest raises the tpr and then signals this with a succeeding, non vm-exiting instruction to the other vcpus, one of those could inject an interrupt with a higher priority than the previous tpr, but a lower one than current tpr. QEMU user space would accept this interrupt - and would likely surprise the guest. Do I miss something? Injection happens by vcpu thread on cpu entry: run-request_interrupt_window = kvm_arch_try_push_interrupts(env); and tpr is synced on vcpu exit, so I do not yet see how what you describe above may happen since during injection vcpu should see correct tpr. -- Gleb.
[Qemu-devel] [0.14+master][PATCH 2/3] qemu-timer: Introduce warp callback
QEMU_CLOCK_HOST is based on the system time which may jump backward in case the admin or NTP adjusts it. RTC emulations and other device models can suffer in this case as timers will stall for the period the clock was tuned back. This adds a detection mechanism that checks on every host clock readout if the new time is before the last result. In that case callbacks are fired that any interested device model can register with the clock. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- qemu-timer.c | 52 +++- qemu-timer.h |5 + 2 files changed, 56 insertions(+), 1 deletions(-) diff --git a/qemu-timer.c b/qemu-timer.c index 94c1073..2b98c8a 100644 --- a/qemu-timer.c +++ b/qemu-timer.c @@ -152,9 +152,17 @@ void cpu_disable_ticks(void) #define QEMU_CLOCK_VIRTUAL 1 #define QEMU_CLOCK_HOST 2 +struct QEMUClockWarpListener { +QEMUClockWarpCB cb; +void *opaque; +QTAILQ_ENTRY(QEMUClockWarpListener) entry; +}; + struct QEMUClock { int type; int enabled; +QTAILQ_HEAD(warp_listeners, QEMUClockWarpListener) warp_listeners; +int64_t last; /* XXX: add frequency */ }; @@ -382,9 +390,15 @@ static QEMUTimer *active_timers[QEMU_NUM_CLOCKS]; static QEMUClock *qemu_new_clock(int type) { QEMUClock *clock; + clock = qemu_mallocz(sizeof(QEMUClock)); clock-type = type; clock-enabled = 1; +QTAILQ_INIT(clock-warp_listeners); +/* required to detect report backward jumps */ +if (type == QEMU_CLOCK_HOST) { +clock-last = get_clock_realtime(); +} return clock; } @@ -506,6 +520,9 @@ static void qemu_run_timers(QEMUClock *clock) static int64_t get_clock_common(QEMUClock *clock) { +struct QEMUClockWarpListener *listener; +int64_t now, last; + switch(clock-type) { default: case QEMU_CLOCK_VIRTUAL: @@ -515,7 +532,15 @@ static int64_t get_clock_common(QEMUClock *clock) return cpu_get_clock(); } case QEMU_CLOCK_HOST: -return get_clock_realtime(); +now = get_clock_realtime(); +last = clock-last; +clock-last = now; +if (now last) { +QTAILQ_FOREACH(listener, clock-warp_listeners, entry) { +listener-cb(clock, now, listener-opaque); +} +} +return now; } } @@ -537,6 +562,31 @@ int64_t qemu_get_clock_ns(QEMUClock *clock) } } +void qemu_register_clock_warp(QEMUClock *clock, QEMUClockWarpCB cb, + void *opaque) +{ +struct QEMUClockWarpListener *listener = +qemu_malloc(sizeof(struct QEMUClockWarpListener)); + +listener-cb = cb; +listener-opaque = opaque; +QTAILQ_INSERT_TAIL(clock-warp_listeners, listener, entry); +} + +void qemu_unregister_clock_warp(QEMUClock *clock, QEMUClockWarpCB cb, +void *opaque) +{ +struct QEMUClockWarpListener *listener; + +QTAILQ_FOREACH(listener, clock-warp_listeners, entry) { +if (listener-cb == cb listener-opaque == opaque) { +QTAILQ_REMOVE(clock-warp_listeners, listener, entry); +qemu_free(listener); +break; +} +} +} + void init_clocks(void) { rt_clock = qemu_new_clock(QEMU_CLOCK_REALTIME); diff --git a/qemu-timer.h b/qemu-timer.h index 8cd8f83..a7b37da 100644 --- a/qemu-timer.h +++ b/qemu-timer.h @@ -13,6 +13,7 @@ /* timers */ typedef struct QEMUClock QEMUClock; +typedef void (*QEMUClockWarpCB)(QEMUClock *clock, int64_t now, void *opaque); typedef void QEMUTimerCB(void *opaque); /* The real time clock should be used only for stuff which does not @@ -36,6 +37,10 @@ extern QEMUClock *host_clock; int64_t qemu_get_clock(QEMUClock *clock); int64_t qemu_get_clock_ns(QEMUClock *clock); void qemu_clock_enable(QEMUClock *clock, int enabled); +void qemu_register_clock_warp(QEMUClock *clock, QEMUClockWarpCB cb, + void *opaque); +void qemu_unregister_clock_warp(QEMUClock *clock, QEMUClockWarpCB cb, +void *opaque); QEMUTimer *qemu_new_timer(QEMUClock *clock, QEMUTimerCB *cb, void *opaque); void qemu_free_timer(QEMUTimer *ts); -- 1.7.1
Re: [Qemu-devel] KVM: Windows 64-bit troubles with user space irqchip
On Wed, Feb 02, 2011 at 05:36:53PM +0100, Jan Kiszka wrote: On 2011-02-02 17:29, Gleb Natapov wrote: On Wed, Feb 02, 2011 at 04:52:11PM +0100, Jan Kiszka wrote: On 2011-02-02 16:46, Gleb Natapov wrote: On Wed, Feb 02, 2011 at 04:35:25PM +0100, Jan Kiszka wrote: On 2011-02-02 16:09, Avi Kivity wrote: On 02/02/2011 04:52 PM, Jan Kiszka wrote: On 2011-02-02 15:43, Jan Kiszka wrote: On 2011-02-02 15:35, Avi Kivity wrote: On 02/02/2011 04:30 PM, Jan Kiszka wrote: On 2011-02-02 14:05, Avi Kivity wrote: On 02/02/2011 02:50 PM, Jan Kiszka wrote: Opps, -smp 1. With -smp 2 it boot almost completely and then hangs. Ah, good (or not good). With Windows 2003 Server, I actually get a Blue Screen (Stop 0x00b8). Userspace APIC is broken since it may run with an outdated cr8, does reverting 27a4f7976d5 help? Can you elaborate on what is broken? The way hw/apic.c maintains the tpr? Would it make sense to compare this against the in-kernel model? Or do you mean something else? The problem, IIRC, was that we look up the TPR but it may already have been changed by the running vcpu. Not 100% sure. If that is indeed the problem then the fix would be to process the APIC in vcpu context (which is what the kernel does - we set a bit in the IRR and all further processing is synchronous). You mean: user space changes the tpr value while the vcpu is in KVM_RUN, then we return from the kernel and overwrite the tpr in the apic with the vcpu's view, right? Hmm, probably rather that there is a discrepancy between tpr and irr. The latter is changed asynchronously /wrt to the vcpu, the former /wrt the user space device model. And yet, both are synchronized via qemu_mutex. So we're still missing something in this picture. Run apic_set_irq on the vcpu? static void apic_set_irq(APICState *s, int vector_num, int trigger_mode) { apic_irq_delivered += !get_bit(s-irr, vector_num); trace_apic_set_irq(apic_irq_delivered); set_bit(s-irr, vector_num); This is even more async with kernel irqchip if (trigger_mode) set_bit(s-tmr, vector_num); else reset_bit(s-tmr, vector_num); This is protected by qemu_mutex apic_update_irq(s); This will be run the next time the vcpu exits, via apic_get_interrupt(). The decision to pend an IRQ (and potentially kick the vcpu) takes place immediately in acip_update_irq. And it is based on current irr as well as tpr. But we update again when user space returns with a new value. } Did you check whether reverting that commit helps? Just did so, and I can no longer reproduce the problem. Hmm... If there is no problem in the logic of this commit (and I do not see one yet) then we somewhere miss kicking vcpu when interrupt, that should be handled, arrives? I'm not yet confident about the logic of the kernel patch: mov to cr8 is serializing. If the guest raises the tpr and then signals this with a succeeding, non vm-exiting instruction to the other vcpus, one of those could inject an interrupt with a higher priority than the previous tpr, but a lower one than current tpr. QEMU user space would accept this interrupt - and would likely surprise the guest. Do I miss something? Injection happens by vcpu thread on cpu entry: run-request_interrupt_window = kvm_arch_try_push_interrupts(env); and tpr is synced on vcpu exit, so I do not yet see how what you describe above may happen since during injection vcpu should see correct tpr. Hmm, maybe this is the key: Once we call into apic_get_interrupt (because CPU_INTERRUPT_HARD was set as described above) and we find a pending irq below the tpr, we inject a spurious vector instead. That should be easy to verify. I expect Windows to BSOD upon receiving spurious vector though. -- Gleb.
Re: [Qemu-devel] KVM: Windows 64-bit troubles with user space irqchip
On 2011-02-02 15:35, Avi Kivity wrote: On 02/02/2011 04:30 PM, Jan Kiszka wrote: On 2011-02-02 14:05, Avi Kivity wrote: On 02/02/2011 02:50 PM, Jan Kiszka wrote: Opps, -smp 1. With -smp 2 it boot almost completely and then hangs. Ah, good (or not good). With Windows 2003 Server, I actually get a Blue Screen (Stop 0x00b8). Userspace APIC is broken since it may run with an outdated cr8, does reverting 27a4f7976d5 help? Can you elaborate on what is broken? The way hw/apic.c maintains the tpr? Would it make sense to compare this against the in-kernel model? Or do you mean something else? The problem, IIRC, was that we look up the TPR but it may already have been changed by the running vcpu. Not 100% sure. If that is indeed the problem then the fix would be to process the APIC in vcpu context (which is what the kernel does - we set a bit in the IRR and all further processing is synchronous). You mean: user space changes the tpr value while the vcpu is in KVM_RUN, then we return from the kernel and overwrite the tpr in the apic with the vcpu's view, right? Jan -- Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
Re: [Qemu-devel] KVM: Windows 64-bit troubles with user space irqchip
On 02/02/2011 05:35 PM, Jan Kiszka wrote: And yet, both are synchronized via qemu_mutex. So we're still missing something in this picture. Run apic_set_irq on the vcpu? static void apic_set_irq(APICState *s, int vector_num, int trigger_mode) { apic_irq_delivered += !get_bit(s-irr, vector_num); trace_apic_set_irq(apic_irq_delivered); set_bit(s-irr, vector_num); This is even more async with kernel irqchip if (trigger_mode) set_bit(s-tmr, vector_num); else reset_bit(s-tmr, vector_num); This is protected by qemu_mutex apic_update_irq(s); This will be run the next time the vcpu exits, via apic_get_interrupt(). The decision to pend an IRQ (and potentially kick the vcpu) takes place immediately in acip_update_irq. And it is based on current irr as well as tpr. But we update again when user space returns with a new value. Right. My current understanding is that it is correct. But I distinctly remember that I came to a different conclusion when the failure first occurred (and the conclusion was that the patch did not cause the problem, just made it much more likely to see a not-up-to-date TPR). } Did you check whether reverting that commit helps? Just did so, and I can no longer reproduce the problem. Hmm... At least we have a pointer. -- error compiling committee.c: too many arguments to function
Re: [Qemu-devel] [PATCH] do not pass NULL to strdup.
Gleb Natapov g...@redhat.com writes: Also use qemu_strdup() instead of strdup() in bootindex code. Signed-off-by: Gleb Natapov g...@redhat.com --- Should go to stable too. Yes, please! By the way, putting 0.14 in the subject should help with that.
Re: [Qemu-devel] KVM: Windows 64-bit troubles with user space irqchip
On Wed, Feb 02, 2011 at 12:58:47PM +0100, Jan Kiszka wrote: On 2011-02-02 12:55, Gleb Natapov wrote: On Tue, Feb 01, 2011 at 07:02:03PM +0100, Jan Kiszka wrote: Hi, testing my KVM patches, I noticed that none of the 64-bit Windows versions I have around (early Win7 2003 server) boot in KVM mode when using 2 or more VCPUs and the user space irqchip. This applies to both upstream KVM and qemu-kvm, with our without any of my current patches. A subtle difference in the APIC/IOAPIC emulation? Can anyone confirm this? Just booted windows7-64 on qemu-kvm -no-kvm-irqchip + latest kernel here. Strange. -smp 2? Opps, -smp 1. With -smp 2 it boot almost completely and then hangs. -- Gleb.
Re: [Qemu-devel] KVM: Windows 64-bit troubles with user space irqchip
On 2011-02-02 16:46, Gleb Natapov wrote: On Wed, Feb 02, 2011 at 04:35:25PM +0100, Jan Kiszka wrote: On 2011-02-02 16:09, Avi Kivity wrote: On 02/02/2011 04:52 PM, Jan Kiszka wrote: On 2011-02-02 15:43, Jan Kiszka wrote: On 2011-02-02 15:35, Avi Kivity wrote: On 02/02/2011 04:30 PM, Jan Kiszka wrote: On 2011-02-02 14:05, Avi Kivity wrote: On 02/02/2011 02:50 PM, Jan Kiszka wrote: Opps, -smp 1. With -smp 2 it boot almost completely and then hangs. Ah, good (or not good). With Windows 2003 Server, I actually get a Blue Screen (Stop 0x00b8). Userspace APIC is broken since it may run with an outdated cr8, does reverting 27a4f7976d5 help? Can you elaborate on what is broken? The way hw/apic.c maintains the tpr? Would it make sense to compare this against the in-kernel model? Or do you mean something else? The problem, IIRC, was that we look up the TPR but it may already have been changed by the running vcpu. Not 100% sure. If that is indeed the problem then the fix would be to process the APIC in vcpu context (which is what the kernel does - we set a bit in the IRR and all further processing is synchronous). You mean: user space changes the tpr value while the vcpu is in KVM_RUN, then we return from the kernel and overwrite the tpr in the apic with the vcpu's view, right? Hmm, probably rather that there is a discrepancy between tpr and irr. The latter is changed asynchronously /wrt to the vcpu, the former /wrt the user space device model. And yet, both are synchronized via qemu_mutex. So we're still missing something in this picture. Run apic_set_irq on the vcpu? static void apic_set_irq(APICState *s, int vector_num, int trigger_mode) { apic_irq_delivered += !get_bit(s-irr, vector_num); trace_apic_set_irq(apic_irq_delivered); set_bit(s-irr, vector_num); This is even more async with kernel irqchip if (trigger_mode) set_bit(s-tmr, vector_num); else reset_bit(s-tmr, vector_num); This is protected by qemu_mutex apic_update_irq(s); This will be run the next time the vcpu exits, via apic_get_interrupt(). The decision to pend an IRQ (and potentially kick the vcpu) takes place immediately in acip_update_irq. And it is based on current irr as well as tpr. But we update again when user space returns with a new value. } Did you check whether reverting that commit helps? Just did so, and I can no longer reproduce the problem. Hmm... If there is no problem in the logic of this commit (and I do not see one yet) then we somewhere miss kicking vcpu when interrupt, that should be handled, arrives? I'm not yet confident about the logic of the kernel patch: mov to cr8 is serializing. If the guest raises the tpr and then signals this with a succeeding, non vm-exiting instruction to the other vcpus, one of those could inject an interrupt with a higher priority than the previous tpr, but a lower one than current tpr. QEMU user space would accept this interrupt - and would likely surprise the guest. Do I miss something? Jan -- Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
Re: [Qemu-devel] [PATCH 1/2] Add virtagent file system freeze/thaw
On 02/02/11 08:57, Stefan Hajnoczi wrote: On Tue, Feb 1, 2011 at 10:58 AM, jes.soren...@redhat.com wrote: From: Jes Sorensen jes.soren...@redhat.com Implement freeze/thaw support in the guest, allowing the host to request the guest freezes all it's file systems before a live snapshot is performed. - fsfreeze(): Walk the list of mounted local real file systems, and freeze them. Does this add a requirement that guest agent code issues no disk I/O in its main loop (e.g. logging)? Otherwise we might deadlock ourselves waiting for I/O which is never issued. Yes very much so[1] - one reason why it would be nice to have virtagent use threads to execute the actual commands. We should probably add a flag to agent commands indicating whether they issue disk I/O or not, so we can block attempts to execute commands that do so, while the guest is frozen. Cheers, Jes [1] speaking from experience ... a Linux desktop gets really upset if you freeze the file systems from a command in an xterm ho hum
[Qemu-devel] [PATCH V10 00/15] Xen device model support
From: Anthony PERARD anthony.per...@citrix.com Hi, There is a lot of change since the V9 of the Xen device model. One of theme is to use the 'pc' machine for Xen instead of duplicate this machine in another file. Here is the change since the last version: - typedef of qemu_xc_interface, qemu_xc_gnttab and qemu_xc_evtchn have been renamed to XenXC, XenGnttab and XenEvtchn; - replace asprintf by snprintf; - rename Xen i8259 to Xen Interrupt Controller; - remove xen_redirect.h file and replace all Xen calls to use xen_interfaces calls; - add copyright header in some files; - in mapcache, use RLIMIT_AS to have the max mapcache size, instead of have a max depends on the architecture; - in mapcache, set rlimit_as.rlim_cur = rlimit_as.rlim_max; - in xen platform pci device, removed the throttle; - qemu_ram_ptr_unlock renamed to qemu_put_ram_ptr; - put specific xen calls into pc_piix and xen_machine_fv have been removed; - fix few coding style. This series depends on the series Introduce machine QemuOpts. You can find a git tree here: git://xenbits.xen.org/people/aperard/qemu-dm.git qemu-dm-v10 Anthony PERARD (12): xen: Replace some tab-indents with spaces (clean-up). xen: Make xen build only on x86 target. xen: Support new libxc calls from xen unstable. xen: Add initialisation of Xen xen: Add xenfv machine piix_pci: Introduces Xen specific call for irq. xen: Introduce Xen Interrupt Controller configure: Always use 64bits target physical addresses with xen enabled. Introduce qemu_put_ram_ptr vl.c: Introduce getter for shutdown_requested and reset_requested. xen: Set running state in xenstore. xen: Add Xen hypercall for sleep state in the cmos_s3 callback. Arun Sharma (1): xen: Initialize event channels and io rings Jun Nakajima (1): xen: Introduce the Xen mapcache Steven Smith (1): xen: Add the Xen platform pci device Makefile.objs|4 - Makefile.target | 14 ++- configure| 71 ++- cpu-common.h |1 + exec.c | 50 - hw/hw.h |3 + hw/pc.c | 19 ++- hw/pc_piix.c | 39 +++- hw/pci_ids.h |2 + hw/piix_pci.c| 28 +++- hw/xen.h | 41 hw/xen_backend.c | 372 hw/xen_backend.h |7 +- hw/xen_common.h | 40 +++-- hw/xen_console.c | 10 +- hw/xen_devconfig.c | 10 +- hw/xen_disk.c| 402 ++- hw/xen_domainbuild.c | 29 ++-- hw/xen_interfaces.c | 191 + hw/xen_interfaces.h | 198 + hw/xen_nic.c | 230 ++-- hw/xen_platform.c| 348 ++ hw/xenfb.c | 14 +- sysemu.h |2 + vl.c | 12 + xen-all.c| 579 ++ xen-mapcache-stub.c | 40 xen-mapcache.c | 344 ++ xen-mapcache.h | 22 ++ xen-stub.c | 47 30 files changed, 2599 insertions(+), 570 deletions(-) create mode 100644 hw/xen_interfaces.c create mode 100644 hw/xen_interfaces.h create mode 100644 hw/xen_platform.c create mode 100644 xen-all.c create mode 100644 xen-mapcache-stub.c create mode 100644 xen-mapcache.c create mode 100644 xen-mapcache.h create mode 100644 xen-stub.c
[Qemu-devel] [PATCH V10 07/15] piix_pci: Introduces Xen specific call for irq.
From: Anthony PERARD anthony.per...@citrix.com This patch introduces Xen specific call in piix_pci. The specific part for Xen is in write_config, set_irq and get_pirq. Signed-off-by: Anthony PERARD anthony.per...@citrix.com Signed-off-by: Stefano Stabellini stefano.stabell...@eu.citrix.com Acked-by: Alexander Graf ag...@suse.de --- hw/piix_pci.c | 28 ++-- hw/xen.h |6 ++ xen-all.c | 31 +++ xen-stub.c| 13 + 4 files changed, 76 insertions(+), 2 deletions(-) diff --git a/hw/piix_pci.c b/hw/piix_pci.c index 358da58..152fcc0 100644 --- a/hw/piix_pci.c +++ b/hw/piix_pci.c @@ -29,6 +29,7 @@ #include isa.h #include sysbus.h #include range.h +#include xen.h /* * I440FX chipset data sheet. @@ -151,6 +152,13 @@ static void i440fx_write_config(PCIDevice *dev, } } +static void i440fx_write_config_xen(PCIDevice *dev, +uint32_t address, uint32_t val, int len) +{ +xen_piix_pci_write_config_client(address, val, len); +i440fx_write_config(dev, address, val, len); +} + static int i440fx_load_old(QEMUFile* f, void *opaque, int version_id) { PCII440FXState *d = opaque; @@ -230,13 +238,21 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq * s-bus = b; qdev_init_nofail(dev); -d = pci_create_simple(b, 0, i440FX); +if (xen_enabled()) { +d = pci_create_simple(b, 0, i440FX-xen); +} else { +d = pci_create_simple(b, 0, i440FX); +} *pi440fx_state = DO_UPCAST(PCII440FXState, dev, d); piix3 = DO_UPCAST(PIIX3State, dev, pci_create_simple_multifunction(b, -1, true, PIIX3)); piix3-pic = pic; -pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3, 4); +if (xen_enabled()) { +pci_bus_irqs(b, xen_piix3_set_irq, xen_pci_slot_get_pirq, piix3, 4); +} else { +pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3, 4); +} (*pi440fx_state)-piix3 = piix3; *piix3_devfn = piix3-dev.devfn; @@ -352,6 +368,14 @@ static PCIDeviceInfo i440fx_info[] = { .init = i440fx_initfn, .config_write = i440fx_write_config, },{ +.qdev.name= i440FX-xen, +.qdev.desc= Host bridge, +.qdev.size= sizeof(PCII440FXState), +.qdev.vmsd= vmstate_i440fx, +.qdev.no_user = 1, +.init = i440fx_initfn, +.config_write = i440fx_write_config_xen, +},{ .qdev.name= PIIX3, .qdev.desc= ISA bridge, .qdev.size= sizeof(PIIX3State), diff --git a/hw/xen.h b/hw/xen.h index 53a2ca4..2a53f8b 100644 --- a/hw/xen.h +++ b/hw/xen.h @@ -8,6 +8,8 @@ */ #include inttypes.h +#include qemu-common.h + /* xen-machine.c */ enum xen_mode { XEN_EMULATE = 0, // xen emulation, using xenner (default) @@ -29,6 +31,10 @@ static inline int xen_enabled(void) #endif } +int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num); +void xen_piix3_set_irq(void *opaque, int irq_num, int level); +void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len); + void pci_xen_platform_init(PCIBus *bus); int xen_init(int smp_cpus); diff --git a/xen-all.c b/xen-all.c index 8d77d42..123decb 100644 --- a/xen-all.c +++ b/xen-all.c @@ -8,9 +8,40 @@ #include config.h +#include hw/pci.h #include hw/xen_common.h #include hw/xen_backend.h +/* Xen specific function for piix pci */ + +int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num) +{ +return irq_num + ((pci_dev-devfn 3) 2); +} + +void xen_piix3_set_irq(void *opaque, int irq_num, int level) +{ +xc_hvm_set_pci_intx_level(xen_xc, xen_domid, 0, 0, irq_num 2, + irq_num 3, level); +} + +void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len) +{ +int i; + +/* Scan for updates to PCI link routes (0x60-0x63). */ +for (i = 0; i len; i++) { +uint8_t v = (val (8 * i)) 0xff; +if (v 0x80) { +v = 0; +} +v = 0xf; +if (((address + i) = 0x60) ((address + i) = 0x63)) { +xc_hvm_set_pci_link_route(xen_xc, xen_domid, address + i - 0x60, v); +} +} +} + /* Initialise Xen */ int xen_init(int smp_cpus) diff --git a/xen-stub.c b/xen-stub.c index a6d5850..ba95537 100644 --- a/xen-stub.c +++ b/xen-stub.c @@ -11,6 +11,19 @@ #include qemu-common.h #include hw/xen.h +int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num) +{ +return -1; +} + +void xen_piix3_set_irq(void *opaque, int irq_num, int level) +{ +} + +void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len) +{ +} + void pci_xen_platform_init(PCIBus *bus) { } -- 1.7.1
[Qemu-devel] Re: [PATCH 0/4] fix/add CONFIG_* options for VMWare device emulation
On Wed, Feb 2, 2011 at 7:55 AM, Paolo Bonzini pbonz...@redhat.com wrote: On 02/01/2011 07:10 PM, Blue Swirl wrote: One way to solve this which would preserve the device model would be to add stub devices. For example, hw/vmmouse-stub.c would be: void *vmmouse_init(void *m) { return NULL; } This is the wrong direction, unless you can somehow automatically generate the stub file. The only other solution I can think of is weak symbols. There are subtle differences between Windows and Linux weak symbols, but luckily we do not care about it. See http://cygwin.com/ml/cygwin/2010-04/msg00281.html Boards should create optional devices so that failure in the device creation is handled more intelligently. For example, pci_vmsvga_init() is just a wrapper (a bit useless one also) to pci_create_simple(bus, -1, vmware-svga). pci_create_simple() in turn uses qdev_init_nofail() which aborts if the device can't be created. Instead, non-aborting version should be used so that if 'vmware-svga' device can't be initialized, a fallback device (VGA) could be used or error message printed. In this case, vmmouse and vmport are not converted to qdev but that should be done anyway.
[Qemu-devel] [PATCH V10 12/15] vl.c: Introduce getter for shutdown_requested and reset_requested.
From: Anthony PERARD anthony.per...@citrix.com Introduce two functions qemu_shutdown_requested_get and qemu_reset_requested_get to get the value of shutdown/reset_requested without reset it. Signed-off-by: Anthony PERARD anthony.per...@citrix.com Signed-off-by: Stefano Stabellini stefano.stabell...@eu.citrix.com Acked-by: Alexander Graf ag...@suse.de --- sysemu.h |2 ++ vl.c | 10 ++ 2 files changed, 12 insertions(+), 0 deletions(-) diff --git a/sysemu.h b/sysemu.h index 23ae17e..ada9692 100644 --- a/sysemu.h +++ b/sysemu.h @@ -51,6 +51,8 @@ void cpu_disable_ticks(void); void qemu_system_reset_request(void); void qemu_system_shutdown_request(void); void qemu_system_powerdown_request(void); +int qemu_shutdown_requested_get(void); +int qemu_reset_requested_get(void); int qemu_shutdown_requested(void); int qemu_reset_requested(void); int qemu_powerdown_requested(void); diff --git a/vl.c b/vl.c index 38fa281..14e5bd6 100644 --- a/vl.c +++ b/vl.c @@ -1204,6 +1204,16 @@ static int powerdown_requested; int debug_requested; int vmstop_requested; +int qemu_shutdown_requested_get(void) +{ +return shutdown_requested; +} + +int qemu_reset_requested_get(void) +{ +return reset_requested; +} + int qemu_shutdown_requested(void) { int r = shutdown_requested; -- 1.7.1
[Qemu-devel] [PATCH V10 11/15] Introduce qemu_put_ram_ptr
From: Anthony PERARD anthony.per...@citrix.com This function allows to unlock a ram_ptr give by qemu_get_ram_ptr. After a call to qemu_put_ram_ptr, the pointer may be unmap from QEMU when used with Xen. Signed-off-by: Anthony PERARD anthony.per...@citrix.com Acked-by: Alexander Graf ag...@suse.de --- cpu-common.h |1 + exec.c | 10 ++ xen-mapcache.c | 34 ++ 3 files changed, 45 insertions(+), 0 deletions(-) diff --git a/cpu-common.h b/cpu-common.h index 6d4a898..6f935cc 100644 --- a/cpu-common.h +++ b/cpu-common.h @@ -55,6 +55,7 @@ void *qemu_get_ram_ptr(ram_addr_t addr); /* Same but slower, to use for migration, where the order of * RAMBlocks must not change. */ void *qemu_safe_ram_ptr(ram_addr_t addr); +void qemu_put_ram_ptr(void *addr); /* This should not be used by devices. */ int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr); ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr); diff --git a/exec.c b/exec.c index 3b137dc..2f8773f 100644 --- a/exec.c +++ b/exec.c @@ -2977,6 +2977,13 @@ void *qemu_safe_ram_ptr(ram_addr_t addr) return NULL; } +void qemu_put_ram_ptr(void *addr) +{ +if (xen_mapcache_enabled()) { +qemu_map_cache_unlock(addr); +} +} + int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr) { RAMBlock *block; @@ -3692,6 +3699,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, cpu_physical_memory_set_dirty_flags( addr1, (0xff ~CODE_DIRTY_FLAG)); } +qemu_put_ram_ptr(ptr); } } else { if ((pd ~TARGET_PAGE_MASK) IO_MEM_ROM @@ -3722,6 +3730,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, ptr = qemu_get_ram_ptr(pd TARGET_PAGE_MASK) + (addr ~TARGET_PAGE_MASK); memcpy(buf, ptr, l); +qemu_put_ram_ptr(ptr); } } len -= l; @@ -3762,6 +3771,7 @@ void cpu_physical_memory_write_rom(target_phys_addr_t addr, /* ROM/RAM case */ ptr = qemu_get_ram_ptr(addr1); memcpy(ptr, buf, l); +qemu_put_ram_ptr(ptr); } len -= l; buf += l; diff --git a/xen-mapcache.c b/xen-mapcache.c index 43a5ed9..abf9bb2 100644 --- a/xen-mapcache.c +++ b/xen-mapcache.c @@ -195,6 +195,40 @@ uint8_t *qemu_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size, u return mapcache-last_address_vaddr + address_offset; } +void qemu_map_cache_unlock(void *buffer) +{ +MapCacheEntry *entry = NULL, *pentry = NULL; +MapCacheRev *reventry; +target_phys_addr_t paddr_index; +int found = 0; + +QTAILQ_FOREACH(reventry, mapcache-locked_entries, next) { +if (reventry-vaddr_req == buffer) { +paddr_index = reventry-paddr_index; +found = 1; +break; +} +} +if (!found) { +return; +} +QTAILQ_REMOVE(mapcache-locked_entries, reventry, next); +qemu_free(reventry); + +entry = mapcache-entry[paddr_index % mapcache-nr_buckets]; +while (entry entry-paddr_index != paddr_index) { +pentry = entry; +entry = entry-next; +} +if (!entry) { +return; +} +entry-lock--; +if (entry-lock 0) { +entry-lock--; +} +} + ram_addr_t qemu_ram_addr_from_mapcache(void *ptr) { MapCacheRev *reventry; -- 1.7.1
[Qemu-devel] Re: [PATCH 3/7] Add support for glib based threading and convert qemu thread to use it
On 02/02/2011 11:32 AM, Paolo Bonzini wrote: On 01/24/2011 10:00 PM, Anthony Liguori wrote: int qemu_mutex_trylock(QemuMutex *mutex) { -return pthread_mutex_trylock(mutex-lock); +return g_static_mutex_trylock(mutex-lock); This is missing a ! Good catch. Regards, Anthony Liguori Paolo
Re: [Qemu-devel] KVM: Windows 64-bit troubles with user space irqchip
On 2011-02-02 13:35, Gleb Natapov wrote: On Wed, Feb 02, 2011 at 12:58:47PM +0100, Jan Kiszka wrote: On 2011-02-02 12:55, Gleb Natapov wrote: On Tue, Feb 01, 2011 at 07:02:03PM +0100, Jan Kiszka wrote: Hi, testing my KVM patches, I noticed that none of the 64-bit Windows versions I have around (early Win7 2003 server) boot in KVM mode when using 2 or more VCPUs and the user space irqchip. This applies to both upstream KVM and qemu-kvm, with our without any of my current patches. A subtle difference in the APIC/IOAPIC emulation? Can anyone confirm this? Just booted windows7-64 on qemu-kvm -no-kvm-irqchip + latest kernel here. Strange. -smp 2? Opps, -smp 1. With -smp 2 it boot almost completely and then hangs. Ah, good (or not good). With Windows 2003 Server, I actually get a Blue Screen (Stop 0x00b8). Jan -- Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
[Qemu-devel] [PATCH V10 15/15] xen: Add Xen hypercall for sleep state in the cmos_s3 callback.
From: Anthony PERARD anthony.per...@citrix.com Signed-off-by: Anthony PERARD anthony.per...@citrix.com --- hw/pc_piix.c |6 +- hw/xen.h |1 + xen-all.c|9 + xen-stub.c |4 4 files changed, 19 insertions(+), 1 deletions(-) diff --git a/hw/pc_piix.c b/hw/pc_piix.c index 27d9030..f86873d 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -176,7 +176,11 @@ static void pc_init1(ram_addr_t ram_size, uint8_t *eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */ i2c_bus *smbus; -cmos_s3 = qemu_allocate_irqs(pc_cmos_set_s3_resume, rtc_state, 1); +if (!xen_enabled()) { +cmos_s3 = qemu_allocate_irqs(pc_cmos_set_s3_resume, rtc_state, 1); +} else { +cmos_s3 = qemu_allocate_irqs(xen_cmos_set_s3_resume, rtc_state, 1); +} smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt, first_cpu, 1); /* TODO: Populate SPD eeprom data. */ smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100, diff --git a/hw/xen.h b/hw/xen.h index a67b5bd..5bcbd6f 100644 --- a/hw/xen.h +++ b/hw/xen.h @@ -43,6 +43,7 @@ static inline int xen_mapcache_enabled(void) int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num); void xen_piix3_set_irq(void *opaque, int irq_num, int level); void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len); +void xen_cmos_set_s3_resume(void *opaque, int irq, int level); qemu_irq *xen_interrupt_controller_init(void); diff --git a/xen-all.c b/xen-all.c index 5892bd8..4eb53b3 100644 --- a/xen-all.c +++ b/xen-all.c @@ -11,6 +11,7 @@ #include sys/mman.h #include hw/pci.h +#include hw/pc.h #include hw/xen_common.h #include hw/xen_backend.h @@ -92,6 +93,14 @@ void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len) } } +void xen_cmos_set_s3_resume(void *opaque, int irq, int level) +{ +pc_cmos_set_s3_resume(opaque, irq, level); +if (level) { +xc_set_hvm_param(xen_xc, xen_domid, HVM_PARAM_ACPI_S_STATE, 3); +} +} + /* Xen Interrupt Controller */ static void xen_set_irq(void *opaque, int irq, int level) diff --git a/xen-stub.c b/xen-stub.c index 86486f8..0d2a663 100644 --- a/xen-stub.c +++ b/xen-stub.c @@ -24,6 +24,10 @@ void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len) { } +void xen_cmos_set_s3_resume(void *opaque, int irq, int level) +{ +} + void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size) { } -- 1.7.1
[Qemu-devel] [PATCH 3/3] usb: control buffer fixes
Windows allows control transfers to pass up to 4k of data, so raise our control buffer size to 4k. For control out transfers the usb core code copies the control request data to a buffer before calling the device's handle_control callback. Add a check for overflowing the buffer before copying the data. Signed-off-by: Hans de Goede hdego...@redhat.com --- hw/usb.c |6 ++ hw/usb.h |2 +- 2 files changed, 7 insertions(+), 1 deletions(-) diff --git a/hw/usb.c b/hw/usb.c index 560b3e4..4379c2a 100644 --- a/hw/usb.c +++ b/hw/usb.c @@ -98,6 +98,12 @@ static int do_token_setup(USBDevice *s, USBPacket *p) s-setup_len = ret; s-setup_state = SETUP_STATE_DATA; } else { +if (s-setup_len sizeof(s-data_buf)) { +fprintf(stderr, +usb_generic_handle_packet: ctrl buffer too small (%d %zu)\n, +s-setup_len, sizeof(s-data_buf)); +return USB_RET_STALL; +} if (s-setup_len == 0) s-setup_state = SETUP_STATE_ACK; else diff --git a/hw/usb.h b/hw/usb.h index 412ce02..51ccc86 100644 --- a/hw/usb.h +++ b/hw/usb.h @@ -167,7 +167,7 @@ struct USBDevice { int state; uint8_t setup_buf[8]; -uint8_t data_buf[1024]; +uint8_t data_buf[4096]; int remote_wakeup; int setup_state; int setup_len; -- 1.7.3.2
[Qemu-devel] [PATCH 1/3] usb: Pass the packet to the device's handle_control callback
This allows using the generic usb_generic_handle_packet function from device code which does ASYNC control requests (such as the linux host pass through code). Signed-off-by: Hans de Goede hdego...@redhat.com --- hw/bt-hid.c |6 +++--- hw/usb-bt.c |6 +++--- hw/usb-desc.c |4 ++-- hw/usb-desc.h |4 ++-- hw/usb-hid.c|6 +++--- hw/usb-hub.c|6 +++--- hw/usb-msd.c|6 +++--- hw/usb-net.c|6 +++--- hw/usb-serial.c |6 +++--- hw/usb-wacom.c |6 +++--- hw/usb.c| 11 +++ hw/usb.h|2 +- usb-bsd.c |1 + 13 files changed, 37 insertions(+), 33 deletions(-) diff --git a/hw/bt-hid.c b/hw/bt-hid.c index abdfd35..09120af 100644 --- a/hw/bt-hid.c +++ b/hw/bt-hid.c @@ -323,7 +323,7 @@ static void bt_hid_control_transaction(struct bt_hid_device_s *s, break; } s-proto = parameter; -s-usbdev-info-handle_control(s-usbdev, SET_PROTOCOL, s-proto, 0, 0, +s-usbdev-info-handle_control(s-usbdev, NULL, SET_PROTOCOL, s-proto, 0, 0, NULL); ret = BT_HS_SUCCESSFUL; break; @@ -333,7 +333,7 @@ static void bt_hid_control_transaction(struct bt_hid_device_s *s, ret = BT_HS_ERR_INVALID_PARAMETER; break; } -s-usbdev-info-handle_control(s-usbdev, GET_IDLE, 0, 0, 1, +s-usbdev-info-handle_control(s-usbdev, NULL, GET_IDLE, 0, 0, 1, s-control-sdu_out(s-control, 1)); s-control-sdu_submit(s-control); break; @@ -346,7 +346,7 @@ static void bt_hid_control_transaction(struct bt_hid_device_s *s, /* We don't need to know about the Idle Rate here really, * so just pass it on to the device. */ -ret = s-usbdev-info-handle_control(s-usbdev, +ret = s-usbdev-info-handle_control(s-usbdev, NULL, SET_IDLE, data[1], 0, 0, NULL) ? BT_HS_SUCCESSFUL : BT_HS_ERR_INVALID_PARAMETER; /* XXX: Does this generate a handshake? */ diff --git a/hw/usb-bt.c b/hw/usb-bt.c index 22e6845..baae487 100644 --- a/hw/usb-bt.c +++ b/hw/usb-bt.c @@ -372,13 +372,13 @@ static void usb_bt_handle_reset(USBDevice *dev) s-altsetting = 0; } -static int usb_bt_handle_control(USBDevice *dev, int request, int value, -int index, int length, uint8_t *data) +static int usb_bt_handle_control(USBDevice *dev, USBPacket *p, + int request, int value, int index, int length, uint8_t *data) { struct USBBtState *s = (struct USBBtState *) dev-opaque; int ret; -ret = usb_desc_handle_control(dev, request, value, index, length, data); +ret = usb_desc_handle_control(dev, p, request, value, index, length, data); if (ret = 0) { switch (request) { case DeviceRequest | USB_REQ_GET_CONFIGURATION: diff --git a/hw/usb-desc.c b/hw/usb-desc.c index 62591f2..6558a6c 100644 --- a/hw/usb-desc.c +++ b/hw/usb-desc.c @@ -344,8 +344,8 @@ int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len return ret; } -int usb_desc_handle_control(USBDevice *dev, int request, int value, -int index, int length, uint8_t *data) +int usb_desc_handle_control(USBDevice *dev, USBPacket *p, +int request, int value, int index, int length, uint8_t *data) { const USBDesc *desc = dev-info-usb_desc; int i, ret = -1; diff --git a/hw/usb-desc.h b/hw/usb-desc.h index ac734ab..3234cb8 100644 --- a/hw/usb-desc.h +++ b/hw/usb-desc.h @@ -86,7 +86,7 @@ void usb_desc_set_string(USBDevice *dev, uint8_t index, const char *str); const char *usb_desc_get_string(USBDevice *dev, uint8_t index); int usb_desc_string(USBDevice *dev, int index, uint8_t *dest, size_t len); int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len); -int usb_desc_handle_control(USBDevice *dev, int request, int value, -int index, int length, uint8_t *data); +int usb_desc_handle_control(USBDevice *dev, USBPacket *p, +int request, int value, int index, int length, uint8_t *data); #endif /* QEMU_HW_USB_DESC_H */ diff --git a/hw/usb-hid.c b/hw/usb-hid.c index 90a2b49..bbedeb7 100644 --- a/hw/usb-hid.c +++ b/hw/usb-hid.c @@ -665,13 +665,13 @@ static void usb_hid_set_next_idle(USBHIDState *s, int64_t curtime) s-next_idle_clock = curtime + (get_ticks_per_sec() * s-idle * 4) / 1000; } -static int usb_hid_handle_control(USBDevice *dev, int request, int value, - int index, int length, uint8_t *data) +static int usb_hid_handle_control(USBDevice *dev, USBPacket *p, + int request, int value, int index, int length, uint8_t *data) { USBHIDState *s = (USBHIDState *)dev; int ret; -ret = usb_desc_handle_control(dev, request, value, index, length, data); +ret = usb_desc_handle_control(dev, p, request, value, index,
[Qemu-devel] [PATCH 2/3] usb-linux: use usb_generic_handle_packet()
Make the linux usb host passthrough code use the usb_generic_handle_packet() function, rather then the curent DYI code. This removes 200 lines of almost identical code. Signed-off-by: Hans de Goede hdego...@redhat.com --- hw/usb.c| 41 +- hw/usb.h|1 + usb-linux.c | 269 ++- 3 files changed, 66 insertions(+), 245 deletions(-) diff --git a/hw/usb.c b/hw/usb.c index 895ad07..560b3e4 100644 --- a/hw/usb.c +++ b/hw/usb.c @@ -63,9 +63,10 @@ void usb_wakeup(USBDevice *dev) protocol) */ -#define SETUP_STATE_IDLE 0 -#define SETUP_STATE_DATA 1 -#define SETUP_STATE_ACK 2 +#define SETUP_STATE_IDLE 0 +#define SETUP_STATE_SETUP 1 +#define SETUP_STATE_DATA 2 +#define SETUP_STATE_ACK 3 static int do_token_setup(USBDevice *s, USBPacket *p) { @@ -86,6 +87,10 @@ static int do_token_setup(USBDevice *s, USBPacket *p) if (s-setup_buf[0] USB_DIR_IN) { ret = s-info-handle_control(s, p, request, value, index, s-setup_len, s-data_buf); +if (ret == USB_RET_ASYNC) { + s-setup_state = SETUP_STATE_SETUP; + return USB_RET_ASYNC; +} if (ret 0) return ret; @@ -235,6 +240,36 @@ int usb_generic_handle_packet(USBDevice *s, USBPacket *p) } } +/* ctrl complete function for devices which use usb_generic_handle_packet and + may return USB_RET_ASYNC from their handle_control callback. Device code + which does this *must* call this function instead of the normal + usb_packet_complete to complete their async control packets. */ +void usb_generic_async_ctrl_complete(USBDevice *s, USBPacket *p) +{ +if (p-len 0) { +s-setup_state = SETUP_STATE_IDLE; +} + +switch (s-setup_state) { +case SETUP_STATE_SETUP: +if (p-len s-setup_len) { +s-setup_len = p-len; +} +s-setup_state = SETUP_STATE_DATA; +p-len = 8; +break; + +case SETUP_STATE_ACK: +s-setup_state = SETUP_STATE_IDLE; +p-len = 0; +break; + +default: +break; +} +usb_packet_complete(p); +} + /* XXX: fix overflow */ int set_usb_string(uint8_t *buf, const char *str) { diff --git a/hw/usb.h b/hw/usb.h index c06000a..412ce02 100644 --- a/hw/usb.h +++ b/hw/usb.h @@ -293,6 +293,7 @@ static inline void usb_cancel_packet(USBPacket * p) void usb_attach(USBPort *port, USBDevice *dev); void usb_wakeup(USBDevice *dev); int usb_generic_handle_packet(USBDevice *s, USBPacket *p); +void usb_generic_async_ctrl_complete(USBDevice *s, USBPacket *p); int set_usb_string(uint8_t *buf, const char *str); void usb_send_msg(USBDevice *dev, int msg); diff --git a/usb-linux.c b/usb-linux.c index 3ef8198..950e439 100644 --- a/usb-linux.c +++ b/usb-linux.c @@ -54,14 +54,6 @@ struct usb_ctrltransfer { void *data; }; -struct usb_ctrlrequest { -uint8_t bRequestType; -uint8_t bRequest; -uint16_t wValue; -uint16_t wIndex; -uint16_t wLength; -}; - typedef int USBScanFunc(void *opaque, int bus_num, int addr, int devpath, int class_id, int vendor_id, int product_id, const char *product_name, int speed); @@ -108,26 +100,6 @@ struct endp_data { int max_packet_size; }; -enum { -CTRL_STATE_IDLE = 0, -CTRL_STATE_SETUP, -CTRL_STATE_DATA, -CTRL_STATE_ACK -}; - -/* - * Control transfer state. - * Note that 'buffer' _must_ follow 'req' field because - * we need contigious buffer when we submit control URB. - */ -struct ctrl_struct { -uint16_t len; -uint16_t offset; -uint8_t state; -struct usb_ctrlrequest req; -uint8_t buffer[8192]; -}; - struct USBAutoFilter { uint32_t bus_num; uint32_t addr; @@ -146,7 +118,6 @@ typedef struct USBHostDevice { int closing; Notifier exit; -struct ctrl_struct ctrl; struct endp_data endp_table[MAX_ENDPOINTS]; /* Host side address */ @@ -269,26 +240,6 @@ static void async_free(AsyncURB *aurb) qemu_free(aurb); } -static void async_complete_ctrl(USBHostDevice *s, USBPacket *p) -{ -switch(s-ctrl.state) { -case CTRL_STATE_SETUP: -if (p-len s-ctrl.len) -s-ctrl.len = p-len; -s-ctrl.state = CTRL_STATE_DATA; -p-len = 8; -break; - -case CTRL_STATE_ACK: -s-ctrl.state = CTRL_STATE_IDLE; -p-len = 0; -break; - -default: -break; -} -} - static void async_complete(void *opaque) { USBHostDevice *s = opaque; @@ -333,9 +284,6 @@ static void async_complete(void *opaque) switch (aurb-urb.status) { case 0: p-len = aurb-urb.actual_length; -if (aurb-urb.type == USBDEVFS_URB_TYPE_CONTROL) { -async_complete_ctrl(s, p); -} break; case -EPIPE: @@ -348,7 +296,11 @@ static void
[Qemu-devel] [PATCH V10 03/15] xen: Support new libxc calls from xen unstable.
From: Anthony PERARD anthony.per...@citrix.com This patch adds a generic layer for xc calls, allowing us to choose between the xenner and xen implementations at runtime. It also update the libxenctrl calls in Qemu to use the new interface, otherwise Qemu wouldn't be able to build against new versions of the library. We check libxenctrl version in configure, from Xen 3.3.0 to Xen unstable. Signed-off-by: Anthony PERARD anthony.per...@citrix.com Signed-off-by: Stefano Stabellini stefano.stabell...@eu.citrix.com Acked-by: Alexander Graf ag...@suse.de --- Makefile.target |3 + configure| 62 +++- hw/xen_backend.c | 74 ++- hw/xen_backend.h |7 +- hw/xen_common.h | 38 ++ hw/xen_console.c | 10 +- hw/xen_devconfig.c | 10 +- hw/xen_disk.c| 28 --- hw/xen_domainbuild.c | 29 hw/xen_interfaces.c | 191 hw/xen_interfaces.h | 198 ++ hw/xen_nic.c | 36 +- hw/xenfb.c | 14 ++-- 13 files changed, 584 insertions(+), 116 deletions(-) create mode 100644 hw/xen_interfaces.c create mode 100644 hw/xen_interfaces.h diff --git a/Makefile.target b/Makefile.target index db29e96..d09719f 100644 --- a/Makefile.target +++ b/Makefile.target @@ -205,6 +205,9 @@ QEMU_CFLAGS += $(VNC_SASL_CFLAGS) QEMU_CFLAGS += $(VNC_JPEG_CFLAGS) QEMU_CFLAGS += $(VNC_PNG_CFLAGS) +# xen support +obj-$(CONFIG_XEN) += xen_interfaces.o + # xen backend driver support obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o obj-$(CONFIG_XEN) += xen_console.o xenfb.o xen_disk.o xen_nic.o diff --git a/configure b/configure index 5a9121d..fde9bad 100755 --- a/configure +++ b/configure @@ -126,6 +126,7 @@ vnc_jpeg= vnc_png= vnc_thread=no xen= +xen_ctrl_version= linux_aio= attr= vhost_net= @@ -1144,13 +1145,71 @@ fi if test $xen != no ; then xen_libs=-lxenstore -lxenctrl -lxenguest + + # Xen unstable cat $TMPC EOF #include xenctrl.h #include xs.h -int main(void) { xs_daemon_open(); xc_interface_open(); return 0; } +#include stdint.h +#include xen/hvm/hvm_info_table.h +#if !defined(HVM_MAX_VCPUS) +# error HVM_MAX_VCPUS not defined +#endif +int main(void) { + xc_interface *xc; + xs_daemon_open(); + xc = xc_interface_open(0, 0, 0); + xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0); + xc_gnttab_open(NULL, 0); + return 0; +} EOF if compile_prog $xen_libs ; then +xen_ctrl_version=410 +xen=yes + + # Xen 4.0.0 + elif ( + cat $TMPC EOF +#include xenctrl.h +#include xs.h +#include stdint.h +#include xen/hvm/hvm_info_table.h +#if !defined(HVM_MAX_VCPUS) +# error HVM_MAX_VCPUS not defined +#endif +int main(void) { + xs_daemon_open(); + xc_interface_open(); + xc_gnttab_open(); + xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0); + return 0; +} +EOF + compile_prog $xen_libs +) ; then +xen_ctrl_version=400 +xen=yes + + # Xen 3.3.0, 3.4.0 + elif ( + cat $TMPC EOF +#include xenctrl.h +#include xs.h +int main(void) { + xs_daemon_open(); + xc_interface_open(); + xc_gnttab_open(); + xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0); + return 0; +} +EOF + compile_prog $xen_libs +) ; then +xen_ctrl_version=330 xen=yes + + # Xen not found or unsupported else if test $xen = yes ; then feature_not_found xen @@ -3009,6 +3068,7 @@ case $target_arch2 in if test $xen = yes -a $target_softmmu = yes ; then echo CONFIG_XEN=y $config_target_mak echo LIBS+=$xen_libs $config_target_mak + echo CONFIG_XEN_CTRL_INTERFACE_VERSION=$xen_ctrl_version $config_target_mak fi esac case $target_arch2 in diff --git a/hw/xen_backend.c b/hw/xen_backend.c index 860b038..cf081e1 100644 --- a/hw/xen_backend.c +++ b/hw/xen_backend.c @@ -43,7 +43,8 @@ /* - */ /* public */ -int xen_xc; +XenXC xen_xc = XC_HANDLER_INITIAL_VALUE; +XenGnttab xen_xcg = XC_HANDLER_INITIAL_VALUE; struct xs_handle *xenstore = NULL; const char *xen_protocol; @@ -58,7 +59,7 @@ int xenstore_write_str(const char *base, const char *node, const char *val) char abspath[XEN_BUFSIZE]; snprintf(abspath, sizeof(abspath), %s/%s, base, node); -if (!xs_write(xenstore, 0, abspath, val, strlen(val))) +if (!xs_ops.write(xenstore, 0, abspath, val, strlen(val))) return -1; return 0; } @@ -70,7 +71,7 @@ char *xenstore_read_str(const char *base, const char *node) char *str, *ret = NULL; snprintf(abspath, sizeof(abspath), %s/%s, base, node); -str = xs_read(xenstore, 0, abspath, len); +str = xs_ops.read(xenstore, 0, abspath, len); if (str != NULL) { /* move to qemu-allocated memory to make sure * callers can savely qemu_free() stuff. */ @@ -197,7 +198,7 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int
[Qemu-devel] [PATCH V10 14/15] xen: Set running state in xenstore.
From: Anthony PERARD anthony.per...@citrix.com This tells to the xen management tool that the machine can begin run. Signed-off-by: Anthony PERARD anthony.per...@citrix.com Acked-by: Alexander Graf ag...@suse.de --- xen-all.c | 23 +++ 1 files changed, 23 insertions(+), 0 deletions(-) diff --git a/xen-all.c b/xen-all.c index 592bcaf..5892bd8 100644 --- a/xen-all.c +++ b/xen-all.c @@ -57,6 +57,8 @@ typedef struct XenIOState { /* which vcpu we are serving */ int send_vcpu; +struct xs_handle *xenstore; + Notifier exit; } XenIOState; @@ -425,6 +427,17 @@ static void cpu_handle_ioreq(void *opaque) } } +static void xenstore_record_dm_state(XenIOState *s, const char *state) +{ +char path[50]; + +snprintf(path, sizeof (path), /local/domain/0/device-model/%u/state, xen_domid); +if (!xs_ops.write(s-xenstore, XBT_NULL, path, state, strlen(state))) { +fprintf(stderr, error recording dm state\n); +exit(1); +} +} + static void xen_main_loop_prepare(XenIOState *state) { int evtchn_fd = -1; @@ -440,6 +453,9 @@ static void xen_main_loop_prepare(XenIOState *state) if (evtchn_fd != -1) { qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, state); } + +/* record state running */ +xenstore_record_dm_state(state, running); } @@ -458,6 +474,7 @@ static void xen_exit_notifier(Notifier *n) XenIOState *state = container_of(n, XenIOState, exit); xc_evtchn_ops.close(state-xce_handle); +xs_ops.daemon_close(state-xenstore); } int xen_init(int smp_cpus) @@ -484,6 +501,12 @@ int xen_init(int smp_cpus) return -errno; } +state-xenstore = xs_ops.daemon_open(); +if (state-xenstore == NULL) { +perror(xen: xenstore open); +return -errno; +} + state-exit.notify = xen_exit_notifier; qemu_add_exit_notifier(state-exit); -- 1.7.1
Re: [Qemu-devel] [PATCHv8 12/16] Add bootindex parameter to net/block/fd device
On Wed, Feb 02, 2011 at 05:10:04PM +0200, Gleb Natapov wrote: On Wed, Feb 02, 2011 at 04:08:07PM +0100, Markus Armbruster wrote: Gleb Natapov g...@redhat.com writes: If bootindex is specified on command line a string that describes device in firmware readable way is added into sorted list. Later this list will be passed into firmware to control boot order. Signed-off-by: Gleb Natapov g...@redhat.com Just noticed something that slipped through review: [...] diff --git a/vl.c b/vl.c index 2cd263e..dadc161 100644 --- a/vl.c +++ b/vl.c [...] @@ -693,6 +704,35 @@ static void restore_boot_devices(void *opaque) qemu_free(standard_boot_devices); } +void add_boot_device_path(int32_t bootindex, DeviceState *dev, + const char *suffix) +{ +FWBootEntry *node, *i; + +if (bootindex 0) { +return; +} + +assert(dev != NULL || suffix != NULL); + +node = qemu_mallocz(sizeof(FWBootEntry)); +node-bootindex = bootindex; +node-suffix = strdup(suffix); qemu_strdup()? Yap. Will fix. BTW we have 40 uses of strdup and 75 uses of qemu_strdup. +node-dev = dev; + +QTAILQ_FOREACH(i, fw_boot_order, link) { +if (i-bootindex == bootindex) { +fprintf(stderr, Two devices with same boot index %d\n, bootindex); +exit(1); +} else if (i-bootindex bootindex) { +continue; +} +QTAILQ_INSERT_BEFORE(i, node, link); +return; +} +QTAILQ_INSERT_TAIL(fw_boot_order, node, link); +} + static void numa_add(const char *optarg) { char option[128]; -- Gleb. -- 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 -- Gleb.
[Qemu-devel] [PATCH V10 06/15] xen: Add the Xen platform pci device
From: Steven Smith ssm...@xensource.com Introduce a new emulated PCI device, specific to fully virtualized Xen guests. The device is necessary for PV on HVM drivers to work. Signed-off-by: Steven Smith ssm...@xensource.com Signed-off-by: Anthony PERARD anthony.per...@citrix.com Signed-off-by: Stefano Stabellini stefano.stabell...@eu.citrix.com --- Makefile.target |1 + hw/hw.h |3 + hw/pc_piix.c |4 + hw/pci_ids.h |2 + hw/xen.h |2 + hw/xen_platform.c | 348 + xen-stub.c|4 + 7 files changed, 364 insertions(+), 0 deletions(-) create mode 100644 hw/xen_platform.c diff --git a/Makefile.target b/Makefile.target index 00bb690..7a4fd72 100644 --- a/Makefile.target +++ b/Makefile.target @@ -215,6 +215,7 @@ obj-$(CONFIG_NO_XEN) += xen-stub.o obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o obj-$(CONFIG_XEN) += xen_console.o xenfb.o xen_disk.o xen_nic.o obj-i386-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o +obj-i386-$(CONFIG_XEN) += xen_platform.o # Inter-VM PCI shared memory obj-$(CONFIG_KVM) += ivshmem.o diff --git a/hw/hw.h b/hw/hw.h index dd993de..298df31 100644 --- a/hw/hw.h +++ b/hw/hw.h @@ -672,6 +672,9 @@ extern const VMStateDescription vmstate_i2c_slave; #define VMSTATE_INT32_LE(_f, _s) \ VMSTATE_SINGLE(_f, _s, 0, vmstate_info_int32_le, int32_t) +#define VMSTATE_UINT8_TEST(_f, _s, _t) \ +VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint8, uint8_t) + #define VMSTATE_UINT16_TEST(_f, _s, _t) \ VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint16, uint16_t) diff --git a/hw/pc_piix.c b/hw/pc_piix.c index 0ab8907..765877c 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -120,6 +120,10 @@ static void pc_init1(ram_addr_t ram_size, pc_vga_init(pci_enabled? pci_bus: NULL); +if (xen_enabled()) { +pci_xen_platform_init(pci_bus); +} + /* init basic PC hardware */ pc_basic_device_init(isa_irq, floppy_controller, rtc_state); diff --git a/hw/pci_ids.h b/hw/pci_ids.h index ea3418c..6e9eabc 100644 --- a/hw/pci_ids.h +++ b/hw/pci_ids.h @@ -108,3 +108,5 @@ #define PCI_DEVICE_ID_INTEL_82371AB 0x7111 #define PCI_DEVICE_ID_INTEL_82371AB_20x7112 #define PCI_DEVICE_ID_INTEL_82371AB_30x7113 + +#define PCI_VENDOR_ID_XENSOURCE 0x5853 diff --git a/hw/xen.h b/hw/xen.h index 3984069..53a2ca4 100644 --- a/hw/xen.h +++ b/hw/xen.h @@ -29,6 +29,8 @@ static inline int xen_enabled(void) #endif } +void pci_xen_platform_init(PCIBus *bus); + int xen_init(int smp_cpus); #if defined(CONFIG_XEN) CONFIG_XEN_CTRL_INTERFACE_VERSION 400 diff --git a/hw/xen_platform.c b/hw/xen_platform.c new file mode 100644 index 000..383cfcf --- /dev/null +++ b/hw/xen_platform.c @@ -0,0 +1,348 @@ +/* + * XEN platform pci device, formerly known as the event channel device + * + * Copyright (c) 2003-2004 Intel Corp. + * Copyright (c) 2006 XenSource + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the Software), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include hw.h +#include pc.h +#include pci.h +#include irq.h +#include xen_common.h +#include net.h +#include xen_backend.h +#include qemu-log.h +#include rwhandler.h + +#include assert.h +#include xenguest.h + +//#define DEBUG_PLATFORM + +#ifdef DEBUG_PLATFORM +#define DPRINTF(fmt, ...) do { \ +fprintf(stderr, xen_platform: fmt, ## __VA_ARGS__); \ +} while (0) +#else +#define DPRINTF(fmt, ...) do { } while (0) +#endif + +#define PFFLAG_ROM_LOCK 1 /* Sets whether ROM memory area is RW or RO */ + +typedef struct PCIXenPlatformState { +PCIDevice pci_dev; +uint8_t flags; /* used only for version_id == 2 */ +int drivers_blacklisted; +uint16_t driver_product_version; + +/* Log from guest drivers */ +char log_buffer[4096]; +int log_buffer_off; +} PCIXenPlatformState; + +#define
[Qemu-devel] [PATCH 3/4] pci: add creation functions that may fail
Signed-off-by: Blue Swirl blauwir...@gmail.com --- hw/pci.c | 20 hw/pci.h |4 2 files changed, 24 insertions(+), 0 deletions(-) diff --git a/hw/pci.c b/hw/pci.c index d5bbba9..5e6e216 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -1708,6 +1708,21 @@ PCIDevice *pci_create_multifunction(PCIBus *bus, int devfn, bool multifunction, return DO_UPCAST(PCIDevice, qdev, dev); } +PCIDevice *pci_try_create_multifunction(PCIBus *bus, int devfn, +bool multifunction, +const char *name) +{ +DeviceState *dev; + +dev = qdev_try_create(bus-qbus, name); +if (!dev) { +return NULL; +} +qdev_prop_set_uint32(dev, addr, devfn); +qdev_prop_set_bit(dev, multifunction, multifunction); +return DO_UPCAST(PCIDevice, qdev, dev); +} + PCIDevice *pci_create_simple_multifunction(PCIBus *bus, int devfn, bool multifunction, const char *name) @@ -1727,6 +1742,11 @@ PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name) return pci_create_simple_multifunction(bus, devfn, false, name); } +PCIDevice *pci_try_create(PCIBus *bus, int devfn, const char *name) +{ +return pci_try_create_multifunction(bus, devfn, false, name); +} + static int pci_find_space(PCIDevice *pdev, uint8_t size) { int config_size = pci_config_size(pdev); diff --git a/hw/pci.h b/hw/pci.h index 0d2753f..113e556 100644 --- a/hw/pci.h +++ b/hw/pci.h @@ -453,8 +453,12 @@ PCIDevice *pci_create_multifunction(PCIBus *bus, int devfn, bool multifunction, PCIDevice *pci_create_simple_multifunction(PCIBus *bus, int devfn, bool multifunction, const char *name); +PCIDevice *pci_try_create_multifunction(PCIBus *bus, int devfn, +bool multifunction, +const char *name); PCIDevice *pci_create(PCIBus *bus, int devfn, const char *name); PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name); +PCIDevice *pci_try_create(PCIBus *bus, int devfn, const char *name); static inline int pci_is_express(const PCIDevice *d) { -- 1.6.2.4
[Qemu-devel] [PATCH 0/4] Make vmware_vga optional
Handle device creation failure for vmware_vga at board level. Use standard VGA instead. Blue Swirl (4): vmware_vga: refactor device creation qdev: add creation function that may fail pci: add creation functions that may fail x86,MIPS: make vmware_vga optional hw/mips_malta.c |6 +- hw/pc.c | 11 --- hw/pci.c| 20 hw/pci.h|4 hw/qdev.c | 14 +- hw/qdev.h |1 + hw/vmware_vga.c |5 - hw/vmware_vga.h | 12 +++- 8 files changed, 62 insertions(+), 11 deletions(-)
[Qemu-devel] [PATCH 4/4] x86,MIPS: make vmware_vga optional
Allow failure with vmware_vga device creation and use standard VGA instead. Signed-off-by: Blue Swirl blauwir...@gmail.com --- hw/mips_malta.c |6 +- hw/pc.c | 11 --- hw/vmware_vga.h | 11 +-- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/hw/mips_malta.c b/hw/mips_malta.c index 2d3f242..930c51c 100644 --- a/hw/mips_malta.c +++ b/hw/mips_malta.c @@ -957,7 +957,11 @@ void mips_malta_init (ram_addr_t ram_size, if (cirrus_vga_enabled) { pci_cirrus_vga_init(pci_bus); } else if (vmsvga_enabled) { -pci_vmsvga_init(pci_bus); +if (!pci_vmsvga_init(pci_bus)) { +fprintf(stderr, Warning: vmware_vga not available, + using standard VGA instead\n); +pci_vga_init(pci_bus); +} } else if (std_vga_enabled) { pci_vga_init(pci_bus); } diff --git a/hw/pc.c b/hw/pc.c index 4dfdc0b..fcee09a 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -1053,10 +1053,15 @@ void pc_vga_init(PCIBus *pci_bus) isa_cirrus_vga_init(); } } else if (vmsvga_enabled) { -if (pci_bus) -pci_vmsvga_init(pci_bus); -else +if (pci_bus) { +if (!pci_vmsvga_init(pci_bus)) { +fprintf(stderr, Warning: vmware_vga not available, + using standard VGA instead\n); +pci_vga_init(pci_bus); +} +} else { fprintf(stderr, %s: vmware_vga: no PCI bus\n, __FUNCTION__); +} #ifdef CONFIG_SPICE } else if (qxl_enabled) { if (pci_bus) diff --git a/hw/vmware_vga.h b/hw/vmware_vga.h index e7bcb22..5132573 100644 --- a/hw/vmware_vga.h +++ b/hw/vmware_vga.h @@ -4,9 +4,16 @@ #include qemu-common.h /* vmware_vga.c */ -static inline void pci_vmsvga_init(PCIBus *bus) +static inline bool pci_vmsvga_init(PCIBus *bus) { -pci_create_simple(bus, -1, vmware-svga); +PCIDevice *dev; + +dev = pci_try_create(bus, -1, vmware-svga); +if (!dev || qdev_init(dev-qdev) 0) { +return false; +} else { +return true; +} } #endif -- 1.6.2.4
Re: [Qemu-devel] KVM: Windows 64-bit troubles with user space irqchip
On 02/02/2011 04:52 PM, Jan Kiszka wrote: On 2011-02-02 15:43, Jan Kiszka wrote: On 2011-02-02 15:35, Avi Kivity wrote: On 02/02/2011 04:30 PM, Jan Kiszka wrote: On 2011-02-02 14:05, Avi Kivity wrote: On 02/02/2011 02:50 PM, Jan Kiszka wrote: Opps, -smp 1. With -smp 2 it boot almost completely and then hangs. Ah, good (or not good). With Windows 2003 Server, I actually get a Blue Screen (Stop 0x00b8). Userspace APIC is broken since it may run with an outdated cr8, does reverting 27a4f7976d5 help? Can you elaborate on what is broken? The way hw/apic.c maintains the tpr? Would it make sense to compare this against the in-kernel model? Or do you mean something else? The problem, IIRC, was that we look up the TPR but it may already have been changed by the running vcpu. Not 100% sure. If that is indeed the problem then the fix would be to process the APIC in vcpu context (which is what the kernel does - we set a bit in the IRR and all further processing is synchronous). You mean: user space changes the tpr value while the vcpu is in KVM_RUN, then we return from the kernel and overwrite the tpr in the apic with the vcpu's view, right? Hmm, probably rather that there is a discrepancy between tpr and irr. The latter is changed asynchronously /wrt to the vcpu, the former /wrt the user space device model. And yet, both are synchronized via qemu_mutex. So we're still missing something in this picture. Run apic_set_irq on the vcpu? static void apic_set_irq(APICState *s, int vector_num, int trigger_mode) { apic_irq_delivered += !get_bit(s-irr, vector_num); trace_apic_set_irq(apic_irq_delivered); set_bit(s-irr, vector_num); This is even more async with kernel irqchip if (trigger_mode) set_bit(s-tmr, vector_num); else reset_bit(s-tmr, vector_num); This is protected by qemu_mutex apic_update_irq(s); This will be run the next time the vcpu exits, via apic_get_interrupt(). } Did you check whether reverting that commit helps? -- error compiling committee.c: too many arguments to function
Re: [Qemu-devel] [PATCHv8 12/16] Add bootindex parameter to net/block/fd device
On Wed, Feb 02, 2011 at 04:08:07PM +0100, Markus Armbruster wrote: Gleb Natapov g...@redhat.com writes: If bootindex is specified on command line a string that describes device in firmware readable way is added into sorted list. Later this list will be passed into firmware to control boot order. Signed-off-by: Gleb Natapov g...@redhat.com Just noticed something that slipped through review: [...] diff --git a/vl.c b/vl.c index 2cd263e..dadc161 100644 --- a/vl.c +++ b/vl.c [...] @@ -693,6 +704,35 @@ static void restore_boot_devices(void *opaque) qemu_free(standard_boot_devices); } +void add_boot_device_path(int32_t bootindex, DeviceState *dev, + const char *suffix) +{ +FWBootEntry *node, *i; + +if (bootindex 0) { +return; +} + +assert(dev != NULL || suffix != NULL); + +node = qemu_mallocz(sizeof(FWBootEntry)); +node-bootindex = bootindex; +node-suffix = strdup(suffix); qemu_strdup()? Yap. Will fix. +node-dev = dev; + +QTAILQ_FOREACH(i, fw_boot_order, link) { +if (i-bootindex == bootindex) { +fprintf(stderr, Two devices with same boot index %d\n, bootindex); +exit(1); +} else if (i-bootindex bootindex) { +continue; +} +QTAILQ_INSERT_BEFORE(i, node, link); +return; +} +QTAILQ_INSERT_TAIL(fw_boot_order, node, link); +} + static void numa_add(const char *optarg) { char option[128]; -- Gleb.
Re: [Qemu-devel] KVM: Windows 64-bit troubles with user space irqchip
On 2011-02-02 16:09, Avi Kivity wrote: On 02/02/2011 04:52 PM, Jan Kiszka wrote: On 2011-02-02 15:43, Jan Kiszka wrote: On 2011-02-02 15:35, Avi Kivity wrote: On 02/02/2011 04:30 PM, Jan Kiszka wrote: On 2011-02-02 14:05, Avi Kivity wrote: On 02/02/2011 02:50 PM, Jan Kiszka wrote: Opps, -smp 1. With -smp 2 it boot almost completely and then hangs. Ah, good (or not good). With Windows 2003 Server, I actually get a Blue Screen (Stop 0x00b8). Userspace APIC is broken since it may run with an outdated cr8, does reverting 27a4f7976d5 help? Can you elaborate on what is broken? The way hw/apic.c maintains the tpr? Would it make sense to compare this against the in-kernel model? Or do you mean something else? The problem, IIRC, was that we look up the TPR but it may already have been changed by the running vcpu. Not 100% sure. If that is indeed the problem then the fix would be to process the APIC in vcpu context (which is what the kernel does - we set a bit in the IRR and all further processing is synchronous). You mean: user space changes the tpr value while the vcpu is in KVM_RUN, then we return from the kernel and overwrite the tpr in the apic with the vcpu's view, right? Hmm, probably rather that there is a discrepancy between tpr and irr. The latter is changed asynchronously /wrt to the vcpu, the former /wrt the user space device model. And yet, both are synchronized via qemu_mutex. So we're still missing something in this picture. Run apic_set_irq on the vcpu? static void apic_set_irq(APICState *s, int vector_num, int trigger_mode) { apic_irq_delivered += !get_bit(s-irr, vector_num); trace_apic_set_irq(apic_irq_delivered); set_bit(s-irr, vector_num); This is even more async with kernel irqchip if (trigger_mode) set_bit(s-tmr, vector_num); else reset_bit(s-tmr, vector_num); This is protected by qemu_mutex apic_update_irq(s); This will be run the next time the vcpu exits, via apic_get_interrupt(). The decision to pend an IRQ (and potentially kick the vcpu) takes place immediately in acip_update_irq. And it is based on current irr as well as tpr. But we update again when user space returns with a new value. } Did you check whether reverting that commit helps? Just did so, and I can no longer reproduce the problem. Hmm... Jan -- Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
Re: [Qemu-devel] KVM: Windows 64-bit troubles with user space irqchip
On Wed, Feb 02, 2011 at 04:35:25PM +0100, Jan Kiszka wrote: On 2011-02-02 16:09, Avi Kivity wrote: On 02/02/2011 04:52 PM, Jan Kiszka wrote: On 2011-02-02 15:43, Jan Kiszka wrote: On 2011-02-02 15:35, Avi Kivity wrote: On 02/02/2011 04:30 PM, Jan Kiszka wrote: On 2011-02-02 14:05, Avi Kivity wrote: On 02/02/2011 02:50 PM, Jan Kiszka wrote: Opps, -smp 1. With -smp 2 it boot almost completely and then hangs. Ah, good (or not good). With Windows 2003 Server, I actually get a Blue Screen (Stop 0x00b8). Userspace APIC is broken since it may run with an outdated cr8, does reverting 27a4f7976d5 help? Can you elaborate on what is broken? The way hw/apic.c maintains the tpr? Would it make sense to compare this against the in-kernel model? Or do you mean something else? The problem, IIRC, was that we look up the TPR but it may already have been changed by the running vcpu. Not 100% sure. If that is indeed the problem then the fix would be to process the APIC in vcpu context (which is what the kernel does - we set a bit in the IRR and all further processing is synchronous). You mean: user space changes the tpr value while the vcpu is in KVM_RUN, then we return from the kernel and overwrite the tpr in the apic with the vcpu's view, right? Hmm, probably rather that there is a discrepancy between tpr and irr. The latter is changed asynchronously /wrt to the vcpu, the former /wrt the user space device model. And yet, both are synchronized via qemu_mutex. So we're still missing something in this picture. Run apic_set_irq on the vcpu? static void apic_set_irq(APICState *s, int vector_num, int trigger_mode) { apic_irq_delivered += !get_bit(s-irr, vector_num); trace_apic_set_irq(apic_irq_delivered); set_bit(s-irr, vector_num); This is even more async with kernel irqchip if (trigger_mode) set_bit(s-tmr, vector_num); else reset_bit(s-tmr, vector_num); This is protected by qemu_mutex apic_update_irq(s); This will be run the next time the vcpu exits, via apic_get_interrupt(). The decision to pend an IRQ (and potentially kick the vcpu) takes place immediately in acip_update_irq. And it is based on current irr as well as tpr. But we update again when user space returns with a new value. } Did you check whether reverting that commit helps? Just did so, and I can no longer reproduce the problem. Hmm... If there is no problem in the logic of this commit (and I do not see one yet) then we somewhere miss kicking vcpu when interrupt, that should be handled, arrives? -- Gleb.
Re: [Qemu-devel] Fosdem
Hi Alex, Am 30.01.2011 um 16:26 schrieb Alexander Graf: Is anyone else going to Fosdem? We could try to set up an unofficial qemu meeting if there are enough people around. So far the list of people active in Qemu development and there I'm aware of are: - Alexander Graf - Hans de Goede Please reply to all on this mail if you're coming too. I am. Thanks for the reminder! ;) Andreas
[Qemu-devel] Re: [PATCH 0/4] fix/add CONFIG_* options for VMWare device emulation
On Wed, Feb 2, 2011 at 5:37 PM, Eduardo Habkost ehabk...@redhat.com wrote: On Wed, Feb 02, 2011 at 05:16:23PM +, Blue Swirl wrote: On Wed, Feb 2, 2011 at 7:55 AM, Paolo Bonzini pbonz...@redhat.com wrote: On 02/01/2011 07:10 PM, Blue Swirl wrote: One way to solve this which would preserve the device model would be to add stub devices. For example, hw/vmmouse-stub.c would be: void *vmmouse_init(void *m) { return NULL; } This is the wrong direction, unless you can somehow automatically generate the stub file. The only other solution I can think of is weak symbols. There are subtle differences between Windows and Linux weak symbols, but luckily we do not care about it. See http://cygwin.com/ml/cygwin/2010-04/msg00281.html Boards should create optional devices so that failure in the device creation is handled more intelligently. For example, pci_vmsvga_init() is just a wrapper (a bit useless one also) to pci_create_simple(bus, -1, vmware-svga). pci_create_simple() in turn uses qdev_init_nofail() which aborts if the device can't be created. Instead, non-aborting version should be used so that if 'vmware-svga' device can't be initialized, a fallback device (VGA) could be used or error message printed. In this case, vmmouse and vmport are not converted to qdev but that should be done anyway. In the meantime, what should we do? Keep the CONFIG_VMWARE_VGA option broken and useless just to avoid an #ifdef? Please try the patch set I just sent.
Re: [Qemu-devel] KVM: Windows 64-bit troubles with user space irqchip
On 2011-02-02 17:29, Gleb Natapov wrote: On Wed, Feb 02, 2011 at 04:52:11PM +0100, Jan Kiszka wrote: On 2011-02-02 16:46, Gleb Natapov wrote: On Wed, Feb 02, 2011 at 04:35:25PM +0100, Jan Kiszka wrote: On 2011-02-02 16:09, Avi Kivity wrote: On 02/02/2011 04:52 PM, Jan Kiszka wrote: On 2011-02-02 15:43, Jan Kiszka wrote: On 2011-02-02 15:35, Avi Kivity wrote: On 02/02/2011 04:30 PM, Jan Kiszka wrote: On 2011-02-02 14:05, Avi Kivity wrote: On 02/02/2011 02:50 PM, Jan Kiszka wrote: Opps, -smp 1. With -smp 2 it boot almost completely and then hangs. Ah, good (or not good). With Windows 2003 Server, I actually get a Blue Screen (Stop 0x00b8). Userspace APIC is broken since it may run with an outdated cr8, does reverting 27a4f7976d5 help? Can you elaborate on what is broken? The way hw/apic.c maintains the tpr? Would it make sense to compare this against the in-kernel model? Or do you mean something else? The problem, IIRC, was that we look up the TPR but it may already have been changed by the running vcpu. Not 100% sure. If that is indeed the problem then the fix would be to process the APIC in vcpu context (which is what the kernel does - we set a bit in the IRR and all further processing is synchronous). You mean: user space changes the tpr value while the vcpu is in KVM_RUN, then we return from the kernel and overwrite the tpr in the apic with the vcpu's view, right? Hmm, probably rather that there is a discrepancy between tpr and irr. The latter is changed asynchronously /wrt to the vcpu, the former /wrt the user space device model. And yet, both are synchronized via qemu_mutex. So we're still missing something in this picture. Run apic_set_irq on the vcpu? static void apic_set_irq(APICState *s, int vector_num, int trigger_mode) { apic_irq_delivered += !get_bit(s-irr, vector_num); trace_apic_set_irq(apic_irq_delivered); set_bit(s-irr, vector_num); This is even more async with kernel irqchip if (trigger_mode) set_bit(s-tmr, vector_num); else reset_bit(s-tmr, vector_num); This is protected by qemu_mutex apic_update_irq(s); This will be run the next time the vcpu exits, via apic_get_interrupt(). The decision to pend an IRQ (and potentially kick the vcpu) takes place immediately in acip_update_irq. And it is based on current irr as well as tpr. But we update again when user space returns with a new value. } Did you check whether reverting that commit helps? Just did so, and I can no longer reproduce the problem. Hmm... If there is no problem in the logic of this commit (and I do not see one yet) then we somewhere miss kicking vcpu when interrupt, that should be handled, arrives? I'm not yet confident about the logic of the kernel patch: mov to cr8 is serializing. If the guest raises the tpr and then signals this with a succeeding, non vm-exiting instruction to the other vcpus, one of those could inject an interrupt with a higher priority than the previous tpr, but a lower one than current tpr. QEMU user space would accept this interrupt - and would likely surprise the guest. Do I miss something? Injection happens by vcpu thread on cpu entry: run-request_interrupt_window = kvm_arch_try_push_interrupts(env); and tpr is synced on vcpu exit, so I do not yet see how what you describe above may happen since during injection vcpu should see correct tpr. Hmm, maybe this is the key: Once we call into apic_get_interrupt (because CPU_INTERRUPT_HARD was set as described above) and we find a pending irq below the tpr, we inject a spurious vector instead. Jan -- Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
Re: [Qemu-devel] Fosdem
On Wed, Feb 02, 2011 at 08:06:40PM +0100, Andreas Färber wrote: Hi Alex, Am 30.01.2011 um 16:26 schrieb Alexander Graf: Is anyone else going to Fosdem? We could try to set up an unofficial qemu meeting if there are enough people around. So far the list of people active in Qemu development and there I'm aware of are: - Alexander Graf - Hans de Goede Please reply to all on this mail if you're coming too. I am. Thanks for the reminder! ;) Andreas Me three.
[Qemu-devel] Re: [PATCH 3/7] Add support for glib based threading and convert qemu thread to use it
On 01/24/2011 10:00 PM, Anthony Liguori wrote: int qemu_mutex_trylock(QemuMutex *mutex) { -return pthread_mutex_trylock(mutex-lock); +return g_static_mutex_trylock(mutex-lock); This is missing a ! Paolo
[Qemu-devel] [PING 0.14] Missing patches (mostly fixes)
Hello, these are some patches which I found on my stack of open patches. All of them should go into 0.14, and at least some of them could also be applied to 0.13. [PATCH] hw/fmopl: Fix buffer access out-of-bounds errors (http://patchwork.ozlabs.org/patch/79054/) [PATCH] linux-user: Fix possible realloc memory leak (http://patchwork.ozlabs.org/patch/79217/) [PATCH 1/3] tests: Fix two memory leaks (http://patchwork.ozlabs.org/patch/79945/) [PATCH 2/3] check-qdict: Fix possible crash (http://patchwork.ozlabs.org/patch/79946/) [PATCH 3/3] w64: Fix problem with missing sigset_t (http://patchwork.ozlabs.org/patch/79947/) [PATCH 1/3] pci: Fix memory leak (http://patchwork.ozlabs.org/patch/79996/) [PATCH 2/3] ppc405: Fix memory leak (http://patchwork.ozlabs.org/patch/79997/) [PATCH 3/3] s390: Fix memory leak (http://patchwork.ozlabs.org/patch/79998/) [PATCH] Fix trivial endianness bugs (http://patchwork.ozlabs.org/patch/80223/) [PATCH] HACKING: Update status of format checking (http://lists.nongnu.org/archive/html/qemu-devel/2011-01/msg02476.html) [PATCH] mingw32: Fix definitions for PRId64, PRIx64, PRIu64, PRIo64 (http://patchwork.ozlabs.org/patch/74276/) Regards, Stefan Weil
[Qemu-devel] [PATCH 1/4] vmware_vga: refactor device creation
Turn vmsvga_init into an inline function. Signed-off-by: Blue Swirl blauwir...@gmail.com --- hw/vmware_vga.c |5 - hw/vmware_vga.h |5 - 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c index 6c59053..4656767 100644 --- a/hw/vmware_vga.c +++ b/hw/vmware_vga.c @@ -1309,11 +1309,6 @@ static int pci_vmsvga_initfn(PCIDevice *dev) return 0; } -void pci_vmsvga_init(PCIBus *bus) -{ -pci_create_simple(bus, -1, vmware-svga); -} - static PCIDeviceInfo vmsvga_info = { .qdev.name= vmware-svga, .qdev.size= sizeof(struct pci_vmsvga_state_s), diff --git a/hw/vmware_vga.h b/hw/vmware_vga.h index 2e0813c..e7bcb22 100644 --- a/hw/vmware_vga.h +++ b/hw/vmware_vga.h @@ -4,6 +4,9 @@ #include qemu-common.h /* vmware_vga.c */ -void pci_vmsvga_init(PCIBus *bus); +static inline void pci_vmsvga_init(PCIBus *bus) +{ +pci_create_simple(bus, -1, vmware-svga); +} #endif -- 1.6.2.4
[Qemu-devel] [PATCH 2/4] qdev: add creation function that may fail
Signed-off-by: Blue Swirl blauwir...@gmail.com --- hw/qdev.c | 14 +- hw/qdev.h |1 + 2 files changed, 14 insertions(+), 1 deletions(-) diff --git a/hw/qdev.c b/hw/qdev.c index c7fec44..1aa1ea0 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -106,6 +106,18 @@ static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info) initialize the actual device emulation. */ DeviceState *qdev_create(BusState *bus, const char *name) { +DeviceState *dev; + +dev = qdev_try_create(bus, name); +if (!dev) { +hw_error(Unknown device '%s' for bus '%s'\n, name, bus-info-name); +} + +return dev; +} + +DeviceState *qdev_try_create(BusState *bus, const char *name) +{ DeviceInfo *info; if (!bus) { @@ -114,7 +126,7 @@ DeviceState *qdev_create(BusState *bus, const char *name) info = qdev_find_info(bus-info, name); if (!info) { -hw_error(Unknown device '%s' for bus '%s'\n, name, bus-info-name); +return NULL; } return qdev_create_from_info(bus, info); diff --git a/hw/qdev.h b/hw/qdev.h index 9808f85..8a13ec9 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -122,6 +122,7 @@ typedef struct GlobalProperty { /*** Board API. This should go away once we have a machine config file. ***/ DeviceState *qdev_create(BusState *bus, const char *name); +DeviceState *qdev_try_create(BusState *bus, const char *name); int qdev_device_help(QemuOpts *opts); DeviceState *qdev_device_add(QemuOpts *opts); int qdev_init(DeviceState *dev) QEMU_WARN_UNUSED_RESULT; -- 1.6.2.4
[Qemu-devel] [PATCH 0.14] Fix build on 32 bit hosts
Signed-off-by: Blue Swirl blauwir...@gmail.com --- target-i386/helper.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/target-i386/helper.c b/target-i386/helper.c index 1217452..4bbf9b1 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -1148,7 +1148,7 @@ void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status, continue; } -qemu_inject_x86_mce(env, 1, 0xa000, 0, 0, 0); +qemu_inject_x86_mce(env, 1, 0xa000ULL, 0, 0, 0); } } } -- 1.6.2.4
[Qemu-devel] Re: [PATCH 0/4] fix/add CONFIG_* options for VMWare device emulation
On Wed, Feb 02, 2011 at 05:16:23PM +, Blue Swirl wrote: On Wed, Feb 2, 2011 at 7:55 AM, Paolo Bonzini pbonz...@redhat.com wrote: On 02/01/2011 07:10 PM, Blue Swirl wrote: One way to solve this which would preserve the device model would be to add stub devices. For example, hw/vmmouse-stub.c would be: void *vmmouse_init(void *m) { return NULL; } This is the wrong direction, unless you can somehow automatically generate the stub file. The only other solution I can think of is weak symbols. There are subtle differences between Windows and Linux weak symbols, but luckily we do not care about it. See http://cygwin.com/ml/cygwin/2010-04/msg00281.html Boards should create optional devices so that failure in the device creation is handled more intelligently. For example, pci_vmsvga_init() is just a wrapper (a bit useless one also) to pci_create_simple(bus, -1, vmware-svga). pci_create_simple() in turn uses qdev_init_nofail() which aborts if the device can't be created. Instead, non-aborting version should be used so that if 'vmware-svga' device can't be initialized, a fallback device (VGA) could be used or error message printed. In this case, vmmouse and vmport are not converted to qdev but that should be done anyway. In the meantime, what should we do? Keep the CONFIG_VMWARE_VGA option broken and useless just to avoid an #ifdef? -- Eduardo
Re: [Qemu-devel] [PATCH 1/4] Add config-devices.h again
On Tue, Feb 01, 2011 at 07:14:00PM +0100, Stefan Weil wrote: + #include config-host.h #include config-target.h + +/* We want to include different config files for specific targets + And for the common library. They need a different name because + we don't want to rely in paths */ on paths? Is this a grammar question (english is not my native language, sorry), or you didn't understand what the message above meant? BTW, this comes from the original patch by Juan (I just restored it), so he may have a better explanation for this comment. -- Eduardo
[Qemu-devel] [PATCH 02/20] qdev: add data pointer to Property
For later use by PROP_TYPE_ENUM, will store enumeration name/value table there. --- hw/qdev.h |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/hw/qdev.h b/hw/qdev.h index fa3221b..3d9acd7 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -83,6 +83,7 @@ struct Property { int offset; int bitnr; void *defval; +void *data; }; enum PropertyType { -- 1.7.4
[Qemu-devel] [PATCH 00/20] usb-ccid (v16)
This patchset adds three new devices, usb-ccid, ccid-card-passthru and ccid-card-emulated, providing a CCID bus, a simple passthru protocol implementing card requiring a client, and a standalone emulated card. It also introduces a new directory libcaccard with CAC card emulation, CAC is a type of ISO 7816 smart card. Tree for pull: git://anongit.freedesktop.org/~alon/qemu usb_ccid.v16 v15-v16 changes: * split vscard_common introducing patch for ease of review * sum of commit logs for the v15-v16 commits: (whitespace fixes removed for space, see original commit messages in later patches) * usb-ccid: * fix abort on client answer after card remove * enable migration * remove side affect code from asserts * return consistent self-powered state * mask out reserved bits in ccid_set_parameters * add missing abRFU in SetParameters (no affect on linux guest) * vscard_common.h protocol change: * VSCMsgInit capabilities and magic * removed ReaderResponse, will use Error instead with code==VSC_SUCCESS. * added Flush and FlushComplete, remove Reconnect. * define VSCARD_MAGIC * added error code VSC_SUCCESS. * ccid-card-passthru * return correct size * return error instead of assert if client sent too large ATR * don't assert if client sent too large a size, but add asserts for indices to buffer * reset vscard_in indices on chardev disconnect * handle init from client * error if no chardev supplied * use ntoh, hton * eradicate reader_id_t * remove Reconnect usage (removed from VSCARD protocol) * send VSC_SUCCESS on card insert/remove and reader add/remove * ccid-card-emulated * fix error reporting in initfn v14-v15 changes: * add patch with --enable-smartcard and --disable-smartcard and only disable ccid-card-emulated if nss not found. * add patch with description strings * s/libcaccard/libcacard/ in docs/ccid.txt v13-v14 changes: - support device_del/device_add on ccid-card-* and usb-ccid * usb-ccid: * lose card reference when card device deleted * check slot number and deny adding a slot if one is already added. * ccid-card-*: use qdev_simple_unplug_cb in both emulated and passthru ccid cards, the exitfn already takes care of triggering card removal in the usb dev. * libcacard: * remove double include of config-host.mak * add replay of card events to libcacard to support second and more emulation * don't initialize more then once (doesn't support it right now, so one thread, NSS thread, is left when device_del is done) * add VCARD_EMUL_INIT_ALREADY_INITED * ccid-card-emulated: * take correct mutexes on signaling to fix deadlocks on device_del * allow card insertion/removal event without proper reader insertion event v12-v13 changes: * libcacard: * fix Makefile clean to remove vscclient * fix double include of config-host in Makefile * usb-ccid: remove attach/detach logic, usb is always attached. Guest doesn't care if there is a reader attached with no card anyway. * ccid-card-passthru: don't close chr_dev on removal, makes it possible to use device_del/device_add to create remove/insertion for debugging. v11-v12 changes: * fix out of tree build v10-v11 changes: * fix last patch that removed one of the doc files. * updated flow table in docs/ccid.txt v8-v10 changes: * usb-ccid: * add slot for future use (Gerd) * ifdef ENABLE_MIGRATION for migration support on account of usb migration not being ready in general. (Gerd) * verbosified commit messages. (Gerd) * put libcacard docs in libcacard commit. (Gerd) v8-v9 changes: * Blue Swirl comments: * white space fixes * enabled by default, disabled only if missing nss * forgotten fix from v8 (don't build libcacard.so) * added a note about device being little endian * library renamed from libcaccard to libcacard * squashed both of libcacard patches, they touched different files anyway. v7-v8 changes: * Blue Swirl comments: * usb-ccid: deannonymize some structs * usb-ccid: coding style change - answer_t and bulk_in_t fixed * usb-ccid: handle endianess conversion between guest and host * usb-ccid: s/ccid_bulk_in_copy_out/ccid_bulk_in_copy_to_guest/ * ccid-card-emulated: fix segfault if backend not specified * ccid-card-emulated: let last reader inserted win * libcaccard: remove double vscard_common.h v6-v7 changes: * external libcaccard became internal directory libcaccard * statically link object files into qemu * produce libcaccard.so for usage by external projects * applied coding style to new code (please check me) - did not use the qemu options parsing for libcaccard, since it seems to draw large amounts of qemu code (monitor for instance). v5-v6 changes: * really remove static debug (I apologize for claiming to have done so before) v4-v5 changes: * rebased to latest * remove static debug in card devices * fix --enable-smartcard to link * stall instead of assert when exceeding
[Qemu-devel] [PATCH 09/20] ccid: add passthru card device
The passthru ccid card is a device sitting on the usb-ccid bus and using a chardevice to communicate with a remote device using the VSCard protocol defined in libcacard/vscard_common.h Usage docs available in following patch in docs/ccid.txt Signed-off-by: Alon Levy al...@redhat.com --- Makefile.objs |2 +- hw/ccid-card-passthru.c | 273 +++ 2 files changed, 274 insertions(+), 1 deletions(-) create mode 100644 hw/ccid-card-passthru.c diff --git a/Makefile.objs b/Makefile.objs index a1f3853..94c36a2 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -195,7 +195,7 @@ hw-obj-$(CONFIG_FDC) += fdc.o hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o hw-obj-$(CONFIG_DMA) += dma.o -hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o +hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o ccid-card-passthru.o # PPC devices hw-obj-$(CONFIG_OPENPIC) += openpic.o diff --git a/hw/ccid-card-passthru.c b/hw/ccid-card-passthru.c new file mode 100644 index 000..6ec4f21 --- /dev/null +++ b/hw/ccid-card-passthru.c @@ -0,0 +1,273 @@ +/* + * CCID Card Device emulation + * + * Copyright (c) 2010 Red Hat. + * Written by Alon Levy. + * + * This code is licenced under the LGPL. + */ + +#include qemu-char.h +#include monitor.h +#include hw/ccid.h +#include libcacard/vscard_common.h + +#define DPRINTF(card, lvl, fmt, ...) \ +do { if (lvl = card-debug) { printf(ccid-card: fmt , ## __VA_ARGS__); } } while (0) + +/* Passthru card */ + + +// TODO: do we still need this? +uint8_t DEFAULT_ATR[] = { +/* From some example somewhere + 0x3B, 0xB0, 0x18, 0x00, 0xD1, 0x81, 0x05, 0xB1, 0x40, 0x38, 0x1F, 0x03, 0x28 + */ + +/* From an Athena smart card */ + 0x3B, 0xD5, 0x18, 0xFF, 0x80, 0x91, 0xFE, 0x1F, 0xC3, 0x80, 0x73, 0xC8, 0x21, 0x13, 0x08 + +}; /* maximum size of ATR - from 7816-3 */ + + +#define PASSTHRU_DEV_NAME ccid-card-passthru +#define VSCARD_IN_SIZE 65536 +#define MAX_ATR_SIZE40 + +typedef struct PassthruState PassthruState; + +struct PassthruState { +CCIDCardState base; +CharDriverState *cs; +uint8_t vscard_in_data[VSCARD_IN_SIZE]; +uint32_t vscard_in_pos; +uint32_t vscard_in_hdr; +uint8_t atr[MAX_ATR_SIZE]; +uint8_t atr_length; +uint8_t debug; +}; + +/* VSCard protocol over chardev + * This code should not depend on the card type. + * */ + +static void ccid_card_vscard_send_msg( +PassthruState *s, VSCMsgType type, reader_id_t reader_id, +const uint8_t* payload, uint32_t length) +{ +VSCMsgHeader scr_msg_header; + +scr_msg_header.type = type; +scr_msg_header.reader_id = reader_id; +scr_msg_header.length = length; +qemu_chr_write(s-cs, (uint8_t*)scr_msg_header, sizeof(VSCMsgHeader)); +qemu_chr_write(s-cs, payload, length); +} + +static void ccid_card_vscard_send_apdu( +PassthruState *s, const uint8_t* apdu, uint32_t length) +{ +ccid_card_vscard_send_msg(s, VSC_APDU, VSCARD_MINIMAL_READER_ID, apdu, length); +} + +static void ccid_card_vscard_send_error( +PassthruState *s, reader_id_t reader_id, VSCErrorCode code) +{ +VSCMsgError msg = {.code=code}; + +ccid_card_vscard_send_msg(s, VSC_Error, reader_id, (uint8_t*)msg, sizeof(msg)); +} + +static void ccid_card_vscard_send_init(PassthruState *s) +{ +VSCMsgInit msg = {.version=VSCARD_VERSION}; + +ccid_card_vscard_send_msg(s, VSC_Init, VSCARD_UNDEFINED_READER_ID, + (uint8_t*)msg, sizeof(msg)); +} + +static int ccid_card_vscard_can_read(void *opaque) +{ +return 65535; +} + +static void ccid_card_vscard_handle_message(PassthruState *card, +VSCMsgHeader* scr_msg_header) +{ +uint8_t *data = (uint8_t*)scr_msg_header[1]; + +switch (scr_msg_header-type) { +case VSC_ATR: +DPRINTF(card, 1, VSC_ATR %d\n, scr_msg_header-length); +assert(scr_msg_header-length = MAX_ATR_SIZE); +memcpy(card-atr, data, scr_msg_header-length); +card-atr_length = scr_msg_header-length; +ccid_card_card_inserted(card-base); +break; +case VSC_APDU: +ccid_card_send_apdu_to_guest(card-base, data, scr_msg_header-length); +break; +case VSC_CardRemove: +DPRINTF(card, 1, VSC_CardRemove\n); +ccid_card_card_removed(card-base); +break; +case VSC_Init: +break; +case VSC_Error: +ccid_card_card_error(card-base, *(uint64_t*)data); +break; +case VSC_ReaderAdd: +if (ccid_card_ccid_attach(card-base) 0) { +ccid_card_vscard_send_error(card, VSCARD_UNDEFINED_READER_ID, + VSC_CANNOT_ADD_MORE_READERS); +} else { +ccid_card_vscard_send_msg(card, VSC_ReaderAddResponse, + VSCARD_MINIMAL_READER_ID, NULL, 0); +} +break; +case
[Qemu-devel] [PATCH 08/20] libcacard/vscard_common.h update (v15-v16)
Protocol change: * VSCMsgInit capabilities and magic * removed ReaderResponse, will use Error instead with code==VSC_SUCCESS. * adaded Flush and FlushComplete, remove Reconnect. * define VSCARD_MAGIC * added error code VSC_SUCCESS. Fixes: * update VSCMsgInit comment * fix message type enum * remove underscore from wrapping define * update copyright * updated comments. * Header comment updated * remove C++ style comment * fix comment for VSCMsgError * give names to enums in typedefs Signed-off-by: Alon Levy al...@redhat.com --- libcacard/vscard_common.h | 103 ++-- 1 files changed, 70 insertions(+), 33 deletions(-) diff --git a/libcacard/vscard_common.h b/libcacard/vscard_common.h index 9ff1295..5cb6eb5 100644 --- a/libcacard/vscard_common.h +++ b/libcacard/vscard_common.h @@ -1,20 +1,25 @@ /* Virtual Smart Card protocol definition * - * This protocol is between a host implementing a group of virtual smart card - * reader, and a client implementing a virtual smart card, or passthrough to - * a real card. + * This protocol is between a host using virtual smart card readers, + * and a client providing the smart cards, perhaps by emulating them or by + * access to real cards. + * + * Definitions for this protocol: + * Host - user of the card + * Client - owner of the card * * The current implementation passes the raw APDU's from 7816 and additionally * contains messages to setup and teardown readers, handle insertion and - * removal of cards, negotiate the protocol and provide for error responses. + * removal of cards, negotiate the protocol via capabilities and provide + * for error responses. * - * Copyright (c) 2010 Red Hat. + * Copyright (c) 2011 Red Hat. * * This code is licensed under the LGPL. */ -#ifndef _VSCARD_COMMON_H -#define _VSCARD_COMMON_H +#ifndef VSCARD_COMMON_H +#define VSCARD_COMMON_H #include stdint.h @@ -40,91 +45,123 @@ * something that cannot be accomodated with the existing protocol. */ -#define VSCARD_VERSION MAKE_VERSION(0,0,1) +#define VSCARD_VERSION MAKE_VERSION(0,0,2) -typedef enum { -VSC_Init, +typedef enum VSCMsgType { +VSC_Init = 1, VSC_Error, VSC_ReaderAdd, -VSC_ReaderAddResponse, VSC_ReaderRemove, VSC_ATR, VSC_CardRemove, VSC_APDU, -VSC_Reconnect +VSC_Flush, +VSC_FlushComplete } VSCMsgType; -typedef enum { +typedef enum VSCErrorCode { +VSC_SUCCESS=0, VSC_GENERAL_ERROR=1, VSC_CANNOT_ADD_MORE_READERS, +VSC_CARD_ALREAY_INSERTED, } VSCErrorCode; -typedef uint32_t reader_id_t; -#define VSCARD_UNDEFINED_READER_ID 0x +#define VSCARD_UNDEFINED_READER_ID 0x #define VSCARD_MINIMAL_READER_ID0 +#define VSCARD_MAGIC (*(uint32_t*)VSCD) + +/* Header + * Each message starts with the header. + * type - message type + * reader_id - used by messages that are reader specific + * length - length of payload (not including header, i.e. zero for + * messages containing empty payloads) + */ typedef struct VSCMsgHeader { -VSCMsgType type; -reader_id_t reader_id; +uint32_t type; +uint32_t reader_id; uint32_t length; uint8_tdata[0]; } VSCMsgHeader; /* VSCMsgInit Client - Host - * Host replies with allocated reader id in ReaderAddResponse + * Client sends it on connection, with its own capabilities. + * Host replies with VSCMsgInit filling in its capabilities. + * + * It is not meant to be used for negotiation, i.e. sending more then + * once from any side, but could be used for that in the future. * */ typedef struct VSCMsgInit { +uint32_t magic; uint32_t version; +uint32_t capabilities[1]; /* receiver must check length, + array may grow in the future*/ } VSCMsgInit; /* VSCMsgError Client - Host + * This message is a response to any of: + * Reader Add + * Reader Remove + * Card Remove + * If the operation was successful then VSC_SUCCESS + * is returned, other wise a specific error code. * */ typedef struct VSCMsgError { uint32_t code; } VSCMsgError; /* VSCMsgReaderAdd Client - Host - * Host replies with allocated reader id in ReaderAddResponse - * name - name of the reader on client side. + * Host replies with allocated reader id in VSCMsgError with code==SUCCESS. + * + * name - name of the reader on client side, UTF-8 encoded. Only used + * for client presentation (may be translated to the device presented to the + * guest), protocol wise only reader_id is important. * */ typedef struct VSCMsgReaderAdd { uint8_tname[0]; } VSCMsgReaderAdd; -/* VSCMsgReaderAddResponse Host - Client - * Reply to ReaderAdd - * */ -typedef struct VSCMsgReaderAddResponse { -} VSCMsgReaderAddResponse; - /* VSCMsgReaderRemove Client - Host + * The client's reader has been removed. * */ typedef struct VSCMsgReaderRemove { } VSCMsgReaderRemove; /*
[Qemu-devel] [PATCH 01/20] qdev: add print_options callback
another callback added to PropertyInfo, for later use by PROP_TYPE_ENUM. Allows printing of runtime computed options when doing: qemu -device foo,? --- hw/qdev.c | 10 +- hw/qdev.h |1 + 2 files changed, 10 insertions(+), 1 deletions(-) diff --git a/hw/qdev.c b/hw/qdev.c index c7fec44..0b2ad3d 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -187,7 +187,15 @@ int qdev_device_help(QemuOpts *opts) if (!prop-info-parse) { continue; /* no way to set it, don't show */ } -error_printf(%s.%s=%s\n, info-name, prop-name, prop-info-name); +if (prop-info-print_options) { +char buf[256]; +int ret; +ret = prop-info-print_options(info, prop, buf, sizeof(buf) - 3); +error_printf(%s.%s=%s%s\n, info-name, prop-name, buf, +ret == sizeof(buf) - 3 ? ... : ); +} else { +error_printf(%s.%s=%s\n, info-name, prop-name, prop-info-name); +} } return 1; } diff --git a/hw/qdev.h b/hw/qdev.h index 9808f85..fa3221b 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -109,6 +109,7 @@ struct PropertyInfo { enum PropertyType type; int (*parse)(DeviceState *dev, Property *prop, const char *str); int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len); +int (*print_options)(DeviceInfo *info, Property *prop, char *dest, size_t len); void (*free)(DeviceState *dev, Property *prop); }; -- 1.7.4
[Qemu-devel] [PATCH 04/20] qdev-properties: parse_enum: don't cast a void*
--- hw/qdev-properties.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c index 3157721..9108f18 100644 --- a/hw/qdev-properties.c +++ b/hw/qdev-properties.c @@ -75,7 +75,7 @@ DEFINE_PROP_ENUM(foo, State, foo, 1, foo_enum_table), static int parse_enum(DeviceState *dev, Property *prop, const char *str) { uint8_t *ptr = qdev_get_prop_ptr(dev, prop); -EnumTable *option = (EnumTable*)prop-data; +EnumTable *option = prop-data; while (option-name != NULL) { if (!strncmp(str, option-name, strlen(option-name))) { -- 1.7.4
[Qemu-devel] [PATCH 06/20] usb-ccid: review fixes (v15-v16)
I'll fold it before submitting the version to be applied, but I hope keeping it as a separate patch will make reviewing easier. Behavioral changes: * fix abort on client answer after card remove * enable migration * remove side affect code from asserts * return consistent self-powered state * mask out reserved bits in ccid_set_parameters * add missing abRFU in SetParameters (no affect on linux guest) whitefixes / comments / consts defines: * remove stale comment * remove ccid_print_pending_answers if no DEBUG_CCID * replace printf's with DPRINTF, remove DEBUG_CCID, add verbosity defines * use error_report * update copyright (most of the code is not original) * reword known bug comment * add missing closing quote in comment * add missing whitespace on one line * s/CCID_SetParameter/CCID_SetParameters/ * add comments * use define for max packet size Comment for return consistent self-powered state: the Configuration Descriptor bmAttributes claims we are self powered, but we were returning not self powered to USB_REQ_GET_STATUS control message. In practice, this message is not sent by a linux 2.6.35.10-74.fc14.x86_64 guest (not tested on other guests), unless you issue lsusb -v as root (for example). Signed-off-by: Alon Levy al...@redhat.com --- hw/ccid.h |7 +++ hw/usb-ccid.c | 115 - 2 files changed, 63 insertions(+), 59 deletions(-) diff --git a/hw/ccid.h b/hw/ccid.h index af59070..f5dcfae 100644 --- a/hw/ccid.h +++ b/hw/ccid.h @@ -6,11 +6,16 @@ typedef struct CCIDCardState CCIDCardState; typedef struct CCIDCardInfo CCIDCardInfo; +/* state of the CCID Card device (i.e. hw/ccid-card-*.c) + */ struct CCIDCardState { DeviceState qdev; uint32_tslot; // For future use with multiple slot reader. }; +/* callbacks to be used by the CCID device (hw/usb-ccid.c) to call + * into the smartcard device (hw/ccid-card-*.c) + */ struct CCIDCardInfo { DeviceInfo qdev; void (*print)(Monitor *mon, CCIDCardState *card, int indent); @@ -20,6 +25,8 @@ struct CCIDCardInfo { int (*initfn)(CCIDCardState *card); }; +/* API for smartcard calling the CCID device (used by hw/ccid-card-*.c) + */ void ccid_card_send_apdu_to_guest(CCIDCardState *card, uint8_t* apdu, uint32_t len); void ccid_card_card_removed(CCIDCardState *card); void ccid_card_card_inserted(CCIDCardState *card); diff --git a/hw/usb-ccid.c b/hw/usb-ccid.c index 58f69a6..09e39ac 100644 --- a/hw/usb-ccid.c +++ b/hw/usb-ccid.c @@ -1,15 +1,18 @@ /* * CCID Device emulation * - * Based on usb-serial.c: + * Written by Alon Levy, with contributions from Robert Relyea. + * + * Based on usb-serial.c, see it's copyright and attributions below. + * + * This code is licenced under the GNU LGPL, version 2 or later. + * + * --- + * + * usb-serial.c copyright and attribution: * Copyright (c) 2006 CodeSourcery. * Copyright (c) 2008 Samuel Thibault samuel.thiba...@ens-lyon.org * Written by Paul Brook, reused for FTDI by Samuel Thibault, - * Reused for CCID by Alon Levy. - * Contributed to by Robert Relyea - * Copyright (c) 2010 Red Hat. - * - * This code is licenced under the LGPL. */ /* References: @@ -19,22 +22,16 @@ * Specification for Integrated Circuit(s) Cards Interface Devices * * Endianess note: from the spec (1.3) - * Fields that are larger than a byte are stored in little endian + * Fields that are larger than a byte are stored in little endian * * KNOWN BUGS * 1. remove/insert can sometimes result in removed state instead of inserted. * This is a result of the following: - * symptom: dmesg shows ERMOTEIO (-121), pcscd shows -99. This happens - * when we send a too short packet, seen in uhci-usb.c, resulting from - * a urb requesting SPD and us returning a smaller packet. + * symptom: dmesg shows ERMOTEIO (-121), pcscd shows -99. This can happen + * when a short packet is sent, as seen in uhci-usb.c, resulting from a urb + * from the guest requesting SPD and us returning a smaller packet. * Not sure which messages trigger this. * - * Migration note: - * - * All the VMStateDescription's are left here for future use, but - * not enabled right now since there is no support for USB migration. - * - * To enable define ENABLE_MIGRATION */ #include qemu-common.h @@ -44,11 +41,14 @@ #include hw/ccid.h -//#define DEBUG_CCID - #define DPRINTF(s, lvl, fmt, ...) \ do { if (lvl = s-debug) { printf(usb-ccid: fmt , ## __VA_ARGS__); } } while (0) +#define D_WARN 1 +#define D_INFO 2 +#define D_MORE_INFO 3 +#define D_VERBOSE 4 + #define CCID_DEV_NAME usb-ccid /* The two options for variable sized buffers: @@ -64,6 +64,8 @@ do { if (lvl = s-debug) { printf(usb-ccid: fmt , ## __VA_ARGS__); } } while #define InterfaceOutClass ((USB_DIR_OUT|USB_TYPE_CLASS|USB_RECIP_INTERFACE)8) #define InterfaceInClass ((USB_DIR_IN |USB_TYPE_CLASS|USB_RECIP_INTERFACE)8) +#define CCID_MAX_PACKET_SIZE
[Qemu-devel] [PATCH 03/20] qdev-properties: add PROP_TYPE_ENUM
Example usage: EnumTable foo_enum_table[] = { {bar, 1}, {buz, 2}, {NULL, 0}, }; DEFINE_PROP_ENUM(foo, State, foo, 1, foo_enum_table) When using qemu -device foodev,? it will appear as: foodev.foo=bar/buz --- hw/qdev-properties.c | 60 ++ hw/qdev.h| 15 2 files changed, 75 insertions(+), 0 deletions(-) diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c index a493087..3157721 100644 --- a/hw/qdev-properties.c +++ b/hw/qdev-properties.c @@ -63,6 +63,66 @@ PropertyInfo qdev_prop_bit = { .print = print_bit, }; +/* --- Enumeration --- */ +/* Example usage: +EnumTable foo_enum_table[] = { +{bar, 1}, +{buz, 2}, +{NULL, 0}, +}; +DEFINE_PROP_ENUM(foo, State, foo, 1, foo_enum_table), + */ +static int parse_enum(DeviceState *dev, Property *prop, const char *str) +{ +uint8_t *ptr = qdev_get_prop_ptr(dev, prop); +EnumTable *option = (EnumTable*)prop-data; + +while (option-name != NULL) { +if (!strncmp(str, option-name, strlen(option-name))) { +*ptr = option-value; +return 0; +} +option++; +} +return -EINVAL; +} + +static int print_enum(DeviceState *dev, Property *prop, char *dest, size_t len) +{ +uint32_t *p = qdev_get_prop_ptr(dev, prop); +EnumTable *option = (EnumTable*)prop-data; +while (option-name != NULL) { +if (*p == option-value) { +return snprintf(dest, len, %s, option-name); +} +option++; +} +return 0; +} + +static int print_enum_options(DeviceInfo *info, Property *prop, char *dest, size_t len) +{ +int ret = 0; +EnumTable *option = (EnumTable*)prop-data; +while (option-name != NULL) { +ret += snprintf(dest + ret, len - ret, %s, option-name); +if (option[1].name != NULL) { +ret += snprintf(dest + ret, len - ret, /); +} +option++; +} +return ret; +} + +PropertyInfo qdev_prop_enum = { +.name = enum, +.type = PROP_TYPE_ENUM, +.size = sizeof(uint32_t), +.parse = parse_enum, +.print = print_enum, +.print_options = print_enum_options, +}; + /* --- 8bit integer --- */ static int parse_uint8(DeviceState *dev, Property *prop, const char *str) diff --git a/hw/qdev.h b/hw/qdev.h index 3d9acd7..3701d83 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -102,6 +102,7 @@ enum PropertyType { PROP_TYPE_VLAN, PROP_TYPE_PTR, PROP_TYPE_BIT, +PROP_TYPE_ENUM, }; struct PropertyInfo { @@ -121,6 +122,11 @@ typedef struct GlobalProperty { QTAILQ_ENTRY(GlobalProperty) next; } GlobalProperty; +typedef struct EnumTable { +const char *name; +uint32_tvalue; +} EnumTable; + /*** Board API. This should go away once we have a machine config file. ***/ DeviceState *qdev_create(BusState *bus, const char *name); @@ -235,6 +241,7 @@ extern PropertyInfo qdev_prop_drive; extern PropertyInfo qdev_prop_netdev; extern PropertyInfo qdev_prop_vlan; extern PropertyInfo qdev_prop_pci_devfn; +extern PropertyInfo qdev_prop_enum; #define DEFINE_PROP(_name, _state, _field, _prop, _type) { \ .name = (_name),\ @@ -257,6 +264,14 @@ extern PropertyInfo qdev_prop_pci_devfn; + type_check(uint32_t,typeof_field(_state, _field)), \ .defval= (bool[]) { (_defval) }, \ } +#define DEFINE_PROP_ENUM(_name, _state, _field, _defval, _options) {\ +.name = (_name), \ +.info = (qdev_prop_enum), \ +.offset= offsetof(_state, _field) \ ++ type_check(uint32_t,typeof_field(_state, _field)),\ +.defval= (uint32_t[]) { (_defval) },\ +.data = (void*)(_options), \ +} #define DEFINE_PROP_UINT8(_n, _s, _f, _d) \ DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint8, uint8_t) -- 1.7.4
[Qemu-devel] RFC: New API for PPC for vcpu mmu access
Below is a proposal for a new API for PPC to allow KVM clients to set MMU state in a vcpu. BookE processors have one or more software managed TLBs and currently there is no mechanism for Qemu to initialize or access them. This is needed for normal initialization as well as debug. There are 4 APIs: -KVM_PPC_SET_MMU_TYPE allows the client to negotiate the type of MMU with KVM-- the type determines the size and format of the data in the other APIs -KVM_PPC_INVALIDATE_TLB invalidates all TLB entries in all TLBs in the vcpu -KVM_PPC_SET_TLBE sets a TLB entry-- the Power architecture specifies the format of the MMU data passed in -KVM_PPC_GET_TLB allows searching, reading a specific TLB entry, or iterating over an entire TLB. Some TLBs may have an unspecified geometry and thus the need to be able to iterate in order to dump the TLB. The Power architecture specifies the format of the MMU data Feedback welcome. Thanks, Stuart Yoder -- KVM PPC MMU API --- User space can query whether the APIs to access the vcpu mmu is available with the KVM_CHECK_EXTENSION API using the KVM_CAP_PPC_MMU argument. If the KVM_CAP_PPC_MMU return value is non-zero it specifies that the following APIs are available: KVM_PPC_SET_MMU_TYPE KVM_PPC_INVALIDATE_TLB KVM_PPC_SET_TLBE KVM_PPC_GET_MMU KVM_PPC_SET_MMU_TYPE Capability: KVM_CAP_PPC_SET_MMU_TYPE Architectures: powerpc Type: vcpu ioctl Parameters: __u32 mmu_type (in) Returns: 0 if specified MMU type is supported, else -1 Sets the MMU type. Valid input values are: BOOKE_NOHV 0x1 BOOKE_HV 0x2 A return value of 0x0 indicates that KVM supports the specified MMU type. KVM_PPC_INVALIDATE_TLB -- Capability: KVM_CAP_PPC_MMU Architectures: powerpc Type: vcpu ioctl Parameters: none Returns: 0 on success, -1 on error Invalidates all TLB entries in all TLBs of the vcpu. KVM_PPC_SET_TLBE Capability: KVM_CAP_PPC_MMU Architectures: powerpc Type: vcpu ioctl Parameters: For mmu types BOOKE_NOHV and BOOKE_HV : struct kvm_ppc_booke_mmu (in) Returns: 0 on success, -1 on error Sets an MMU entry in a virtual CPU. For mmu types BOOKE_NOHV and BOOKE_HV: To write a TLB entry, set the mas fields of kvm_ppc_booke_mmu as per the Power architecture. struct kvm_ppc_booke_mmu { union { __u64 mas0_1; struct { __u32 mas0; __u32 mas1; }; }; __u64 mas2; union { __u64 mas7_3 struct { __u32 mas7; __u32 mas3; }; }; union { __u64 mas5_6 struct { __u64 mas5; __u64 mas6; }; } __u32 mas8; }; For a mmu type of BOOKE_NOHV, the mas5 and mas8 fields in kvm_ppc_booke_mmu are present but not supported. KVM_PPC_GET_TLB --- Capability: KVM_CAP_PPC_MMU Architectures: powerpc Type: vcpu ioctl Parameters: struct kvm_ppc_get_mmu (in/out) Returns: 0 on success -1 on error errno = ENOENT when iterating and there are no more entries to read Reads an MMU entry from a virtual CPU. struct kvm_ppc_get_mmu { /* in */ void *mmu; __u32 flags; /* a bitmask of flags to the API */ /* TLB_READ_FIRST 0x1 */ /* TLB_SEARCH 0x2 */ /* out */ __u32 max_entries; }; For mmu types BOOKE_NOHV and BOOKE_HV : The void *mmu field of kvm_ppc_get_mmu points to a struct of type struct kvm_ppc_booke_mmu. If TLBnCFG[NENTRY] 0 and TLBnCFG[ASSOC] 0, the TLB has of known number of entries and associativity. The mas0[ESEL] and mas2[EPN] fields specify which entry to read. If TLBnCFG[NENTRY] == 0 the number of TLB entries is undefined and this API can be used to iterate over the entire TLB selected with TLBSEL in mas0. -To read a TLB entry: set the following fields in the mmu struct (struct kvm_ppc_booke_mmu): flags=0 mas0[TLBSEL] // select which TLB is being read mas0[ESEL] // select which entry is being read mas2[EPN]// effective address On return the following fields are updated as per the Power architecture: mas0 mas1 mas2 mas3 mas7 -To iterate over a TLB (read all entries):
[Qemu-devel] [PATCH 18/20] ccid: add qdev description strings
Signed-off-by: Alon Levy al...@redhat.com --- hw/ccid-card-emulated.c |1 + hw/ccid-card-passthru.c |1 + hw/usb-ccid.c |1 + 3 files changed, 3 insertions(+), 0 deletions(-) diff --git a/hw/ccid-card-emulated.c b/hw/ccid-card-emulated.c index 09ce770..2e25daa 100644 --- a/hw/ccid-card-emulated.c +++ b/hw/ccid-card-emulated.c @@ -525,6 +525,7 @@ EnumTable backend_enum_table[] = { static CCIDCardInfo emulated_card_info = { .qdev.name = EMULATED_DEV_NAME, +.qdev.desc = emulated smartcard, .qdev.size = sizeof(EmulatedState), .initfn = emulated_initfn, .exitfn = emulated_exitfn, diff --git a/hw/ccid-card-passthru.c b/hw/ccid-card-passthru.c index f3f3da9..f290bea 100644 --- a/hw/ccid-card-passthru.c +++ b/hw/ccid-card-passthru.c @@ -306,6 +306,7 @@ static VMStateDescription passthru_vmstate = { static CCIDCardInfo passthru_card_info = { .qdev.name = PASSTHRU_DEV_NAME, +.qdev.desc = passthrough smartcard, .qdev.size = sizeof(PassthruState), .qdev.vmsd = passthru_vmstate, .initfn = passthru_initfn, diff --git a/hw/usb-ccid.c b/hw/usb-ccid.c index 09e39ac..27a7103 100644 --- a/hw/usb-ccid.c +++ b/hw/usb-ccid.c @@ -1330,6 +1330,7 @@ static VMStateDescription ccid_vmstate = { static struct USBDeviceInfo ccid_info = { .product_desc = QEMU USB CCID, .qdev.name = CCID_DEV_NAME, +.qdev.desc = CCID Rev 1.1 smartcard reader, .qdev.size = sizeof(USBCCIDState), .init = ccid_initfn, .handle_packet = usb_generic_handle_packet, -- 1.7.4
[Qemu-devel] [PATCH 07/20] introduce libcacard/vscard_common.h
Signed-off-by: Alon Levy al...@redhat.com --- libcacard/vscard_common.h | 130 + 1 files changed, 130 insertions(+), 0 deletions(-) create mode 100644 libcacard/vscard_common.h diff --git a/libcacard/vscard_common.h b/libcacard/vscard_common.h new file mode 100644 index 000..9ff1295 --- /dev/null +++ b/libcacard/vscard_common.h @@ -0,0 +1,130 @@ +/* Virtual Smart Card protocol definition + * + * This protocol is between a host implementing a group of virtual smart card + * reader, and a client implementing a virtual smart card, or passthrough to + * a real card. + * + * The current implementation passes the raw APDU's from 7816 and additionally + * contains messages to setup and teardown readers, handle insertion and + * removal of cards, negotiate the protocol and provide for error responses. + * + * Copyright (c) 2010 Red Hat. + * + * This code is licensed under the LGPL. + */ + +#ifndef _VSCARD_COMMON_H +#define _VSCARD_COMMON_H + +#include stdint.h + +#define VERSION_MAJOR_BITS 11 +#define VERSION_MIDDLE_BITS 11 +#define VERSION_MINOR_BITS 10 + +#define MAKE_VERSION(major, middle, minor) \ + ( (major (VERSION_MINOR_BITS + VERSION_MIDDLE_BITS)) \ + | (middle VERSION_MINOR_BITS) \ + | (minor) ) + +/** IMPORTANT NOTE on VERSION + * + * The version below MUST be changed whenever a change in this file is made. + * + * The last digit, the minor, is for bug fix changes only. + * + * The middle digit is for backward / forward compatible changes, updates + * to the existing messages, addition of fields. + * + * The major digit is for a breaking change of protocol, presumably + * something that cannot be accomodated with the existing protocol. + */ + +#define VSCARD_VERSION MAKE_VERSION(0,0,1) + +typedef enum { +VSC_Init, +VSC_Error, +VSC_ReaderAdd, +VSC_ReaderAddResponse, +VSC_ReaderRemove, +VSC_ATR, +VSC_CardRemove, +VSC_APDU, +VSC_Reconnect +} VSCMsgType; + +typedef enum { +VSC_GENERAL_ERROR=1, +VSC_CANNOT_ADD_MORE_READERS, +} VSCErrorCode; + +typedef uint32_t reader_id_t; +#define VSCARD_UNDEFINED_READER_ID 0x +#define VSCARD_MINIMAL_READER_ID0 + +typedef struct VSCMsgHeader { +VSCMsgType type; +reader_id_t reader_id; +uint32_t length; +uint8_tdata[0]; +} VSCMsgHeader; + +/* VSCMsgInit Client - Host + * Host replies with allocated reader id in ReaderAddResponse + * */ +typedef struct VSCMsgInit { +uint32_t version; +} VSCMsgInit; + +/* VSCMsgError Client - Host + * */ +typedef struct VSCMsgError { +uint32_t code; +} VSCMsgError; + +/* VSCMsgReaderAdd Client - Host + * Host replies with allocated reader id in ReaderAddResponse + * name - name of the reader on client side. + * */ +typedef struct VSCMsgReaderAdd { +uint8_tname[0]; +} VSCMsgReaderAdd; + +/* VSCMsgReaderAddResponse Host - Client + * Reply to ReaderAdd + * */ +typedef struct VSCMsgReaderAddResponse { +} VSCMsgReaderAddResponse; + +/* VSCMsgReaderRemove Client - Host + * */ +typedef struct VSCMsgReaderRemove { +} VSCMsgReaderRemove; + +/* VSCMsgATRClient - Host + * Answer to reset. Sent for card insertion or card reset. + * */ +typedef struct VSCMsgATR { +uint8_t atr[0]; +} VSCMsgATR; + +/* VSCMsgCardRemove Client - Host + * */ +typedef struct VSCMsgCardRemove { +} VSCMsgCardRemove; + +/* VSCMsgAPDU Client - Host + * */ +typedef struct VSCMsgAPDU { +uint8_tdata[0]; +} VSCMsgAPDU; + +/* VSCMsgReconnect Host - Client + * */ +typedef struct VSCMsgReconnect { +uint32_t ip; +uint16_t port; +} VSCMsgReconnect; + +#endif -- 1.7.4
[Qemu-devel] [PATCH 15/20] ccid-card-emulated: review fixes (v15-v16)
* fix error reporting in initfn * bump copyright year * update copyright license Signed-off-by: Alon Levy al...@redhat.com --- hw/ccid-card-emulated.c | 19 --- 1 files changed, 12 insertions(+), 7 deletions(-) diff --git a/hw/ccid-card-emulated.c b/hw/ccid-card-emulated.c index 3c5bf6c..09ce770 100644 --- a/hw/ccid-card-emulated.c +++ b/hw/ccid-card-emulated.c @@ -15,10 +15,10 @@ * If you use a non default db for the certificates you can specify it using the db parameter. * * - * Copyright (c) 2010 Red Hat. + * Copyright (c) 2011 Red Hat. * Written by Alon Levy. * - * This code is licenced under the LGPL. + * This code is licenced under the GNU LGPL, version 2 or later. */ #include pthread.h @@ -458,20 +458,25 @@ static int emulated_initfn(CCIDCardState *base) } ASSERT(card-backend); /* 0 is not a value in the enumeration */ /* TODO: a passthru backened that works on local machine. third card type? */ -if (card-backend == BACKEND_CERTIFICATES - card-cert1 != NULL card-cert2 != NULL card-cert3 != NULL) { -ret = emulated_initialize_vcard_from_certificates(card); -} else { -if (card-backend != BACKEND_CERTIFICATES) { +if (card-backend == BACKEND_CERTIFICATES) { +if (card-cert1 != NULL card-cert2 != NULL card-cert3 != NULL) { +ret = emulated_initialize_vcard_from_certificates(card); +} else { printf(%s: you must provide all three certs for certificates backend\n, EMULATED_DEV_NAME); return -1; } +} else { if (card-backend != BACKEND_NSS_EMULATED) { printf(%s: bad backend specified. The options are:\n%s (default), %s.\n, EMULATED_DEV_NAME, BACKEND_NSS_EMULATED_NAME, BACKEND_CERTIFICATES_NAME); return -1; } +if (card-cert1 != NULL || card-cert2 != NULL || card-cert3 != NULL) { +printf(%s: unexpected cert parameters to nss emulated backend\n, + EMULATED_DEV_NAME); +return -1; +} /* default to mirroring the local hardware readers */ ret = wrap_vcard_emul_init(NULL); } -- 1.7.4
[Qemu-devel] [PATCH 13/20] ccid: add ccid-card-emulated device (v2)
This devices uses libcacard (internal) to emulate a smartcard conforming to the CAC standard. It attaches to the usb-ccid bus. Usage instructions (example command lines) are in the following patch in docs/ccid.txt. It uses libcacard which uses nss, so it can work with both hw cards and certificates (files). changes from v1: remove stale comments, use only c-style comments bugfix, forgot to set recv_len change reader name to 'Virtual Reader' Signed-off-by: Alon Levy al...@redhat.com --- Makefile.objs |2 +- hw/ccid-card-emulated.c | 534 +++ hw/ccid-card-passthru.c |1 - 3 files changed, 535 insertions(+), 2 deletions(-) create mode 100644 hw/ccid-card-emulated.c diff --git a/Makefile.objs b/Makefile.objs index 3fba145..459bbdb 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -195,7 +195,7 @@ hw-obj-$(CONFIG_FDC) += fdc.o hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o hw-obj-$(CONFIG_DMA) += dma.o -hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o ccid-card-passthru.o +hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o ccid-card-passthru.o ccid-card-emulated.o # PPC devices hw-obj-$(CONFIG_OPENPIC) += openpic.o diff --git a/hw/ccid-card-emulated.c b/hw/ccid-card-emulated.c new file mode 100644 index 000..5531ce1 --- /dev/null +++ b/hw/ccid-card-emulated.c @@ -0,0 +1,534 @@ +/* + * CCID Card Device. Emulated card. + * + * It can be used to provide access to the local hardware in a non exclusive + * way, or it can use certificates. It requires the usb-ccid bus. + * + * Usage 1: standard, mirror hardware reader+card: + * qemu .. -usb -device usb-ccid -device ccid-card-emulated + * + * Usage 2: use certificates, no hardware required + * one time: create the certificates: + * for i in 1 2 3; do certutil -d /etc/pki/nssdb -x -t CT,CT,CT -S -s CN=user$i -n user$i; done + * qemu .. -usb -device usb-ccid -device ccid-card-emulated,cert1=user1,cert2=user2,cert3=user3 + * + * If you use a non default db for the certificates you can specify it using the db parameter. + * + * + * Copyright (c) 2010 Red Hat. + * Written by Alon Levy. + * + * This code is licenced under the LGPL. + */ + +#include pthread.h +#include eventt.h +#include vevent.h +#include vreader.h +#include vcard_emul.h +#include qemu-char.h +#include monitor.h +#include hw/ccid.h + +#define DPRINTF(card, lvl, fmt, ...) \ +do { if (lvl = card-debug) { printf(ccid-card-emul: %s: fmt , __func__, ## __VA_ARGS__); } } while (0) + +#define EMULATED_DEV_NAME ccid-card-emulated + +#define BACKEND_NSS_EMULATED nss-emulated /* the default */ +#define BACKEND_CERTIFICATES certificates + +typedef struct EmulatedState EmulatedState; + +enum { +EMUL_READER_INSERT = 0, +EMUL_READER_REMOVE, +EMUL_CARD_INSERT, +EMUL_CARD_REMOVE, +EMUL_GUEST_APDU, +EMUL_RESPONSE_APDU, +EMUL_ERROR, +}; + +static const char* emul_event_to_string(uint32_t emul_event) +{ +switch (emul_event) { +case EMUL_READER_INSERT: return EMUL_READER_INSERT; +case EMUL_READER_REMOVE: return EMUL_READER_REMOVE; +case EMUL_CARD_INSERT: return EMUL_CARD_INSERT; +case EMUL_CARD_REMOVE: return EMUL_CARD_REMOVE; +case EMUL_GUEST_APDU: return EMUL_GUEST_APDU; +case EMUL_RESPONSE_APDU: return EMUL_RESPONSE_APDU; +case EMUL_ERROR: return EMUL_ERROR; +default: +break; +} +return UNKNOWN; +} + +typedef struct EmulEvent { +QSIMPLEQ_ENTRY(EmulEvent) entry; +union { +struct { +uint32_t type; +} gen; +struct { +uint32_t type; +uint64_t code; +} error; +struct { +uint32_t type; +uint32_t len; +uint8_t data[]; +} data; +} p; +} EmulEvent; + +#define MAX_ATR_SIZE 40 +struct EmulatedState { +CCIDCardState base; +uint8_t debug; +char*backend; +char*cert1; +char*cert2; +char*cert3; +char*db; +uint8_t atr[MAX_ATR_SIZE]; +uint8_t atr_length; +QSIMPLEQ_HEAD(event_list, EmulEvent) event_list; +pthread_mutex_t event_list_mutex; +VReader *reader; +QSIMPLEQ_HEAD(guest_apdu_list, EmulEvent) guest_apdu_list; +pthread_mutex_t vreader_mutex; /* and guest_apdu_list mutex */ +pthread_mutex_t handle_apdu_mutex; +pthread_cond_t handle_apdu_cond; +int pipe[2]; +int quit_apdu_thread; +pthread_mutex_t apdu_thread_quit_mutex; +pthread_cond_t apdu_thread_quit_cond; +}; + +static void emulated_apdu_from_guest(CCIDCardState *base, const uint8_t *apdu, uint32_t len) +{ +EmulatedState *card = DO_UPCAST(EmulatedState, base, base); +EmulEvent *event = (EmulEvent*)malloc(sizeof(EmulEvent) + len); + +assert(event); +event-p.data.type = EMUL_GUEST_APDU; +event-p.data.len = len; +memcpy(event-p.data.data, apdu, len); +
[Qemu-devel] [PATCH 05/20] usb-ccid: add CCID bus
A CCID device is a smart card reader. It is a USB device, defined at [1]. This patch introduces the usb-ccid device that is a ccid bus. Next patches will introduce two card types to use it, a passthru card and an emulated card. [1] http://www.usb.org/developers/devclass_docs/DWG_Smart-Card_CCID_Rev110. Signed-off-by: Alon Levy al...@redhat.com --- Makefile.objs |1 + configure |6 + hw/ccid.h | 35 ++ hw/usb-ccid.c | 1355 + 4 files changed, 1397 insertions(+), 0 deletions(-) create mode 100644 hw/ccid.h create mode 100644 hw/usb-ccid.c diff --git a/Makefile.objs b/Makefile.objs index f1c7bfe..a1f3853 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -195,6 +195,7 @@ hw-obj-$(CONFIG_FDC) += fdc.o hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o hw-obj-$(CONFIG_DMA) += dma.o +hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o # PPC devices hw-obj-$(CONFIG_OPENPIC) += openpic.o diff --git a/configure b/configure index 598e8e1..14a035a 100755 --- a/configure +++ b/configure @@ -174,6 +174,7 @@ trace_backend=nop trace_file=trace spice= rbd= +smartcard=yes # parse CC options first for opt do @@ -2472,6 +2473,7 @@ echo Trace output file $trace_file-pid echo spice support $spice echo rbd support $rbd echo xfsctl support$xfs +echo smartcard support $smartcard if test $sdl_too_old = yes; then echo - Your SDL version is too old - please upgrade to have SDL support @@ -2744,6 +2746,10 @@ if test $spice = yes ; then echo CONFIG_SPICE=y $config_host_mak fi +if test $smartcard = yes ; then + echo CONFIG_SMARTCARD=y $config_host_mak +fi + # XXX: suppress that if [ $bsd = yes ] ; then echo CONFIG_BSD=y $config_host_mak diff --git a/hw/ccid.h b/hw/ccid.h new file mode 100644 index 000..af59070 --- /dev/null +++ b/hw/ccid.h @@ -0,0 +1,35 @@ +#ifndef __CCID_H__ +#define __CCID_H__ + +#include qdev.h + +typedef struct CCIDCardState CCIDCardState; +typedef struct CCIDCardInfo CCIDCardInfo; + +struct CCIDCardState { +DeviceState qdev; +uint32_tslot; // For future use with multiple slot reader. +}; + +struct CCIDCardInfo { +DeviceInfo qdev; +void (*print)(Monitor *mon, CCIDCardState *card, int indent); +const uint8_t *(*get_atr)(CCIDCardState *card, uint32_t *len); +void (*apdu_from_guest)(CCIDCardState *card, const uint8_t *apdu, uint32_t len); +int (*exitfn)(CCIDCardState *card); +int (*initfn)(CCIDCardState *card); +}; + +void ccid_card_send_apdu_to_guest(CCIDCardState *card, uint8_t* apdu, uint32_t len); +void ccid_card_card_removed(CCIDCardState *card); +void ccid_card_card_inserted(CCIDCardState *card); +void ccid_card_card_error(CCIDCardState *card, uint64_t error); +void ccid_card_qdev_register(CCIDCardInfo *card); + +/* support guest visible insertion/removal of ccid devices based on actual + * devices connected/removed. Called by card implementation (passthru, local) */ +int ccid_card_ccid_attach(CCIDCardState *card); +void ccid_card_ccid_detach(CCIDCardState *card); + +#endif // __CCID_H__ + diff --git a/hw/usb-ccid.c b/hw/usb-ccid.c new file mode 100644 index 000..58f69a6 --- /dev/null +++ b/hw/usb-ccid.c @@ -0,0 +1,1355 @@ +/* + * CCID Device emulation + * + * Based on usb-serial.c: + * Copyright (c) 2006 CodeSourcery. + * Copyright (c) 2008 Samuel Thibault samuel.thiba...@ens-lyon.org + * Written by Paul Brook, reused for FTDI by Samuel Thibault, + * Reused for CCID by Alon Levy. + * Contributed to by Robert Relyea + * Copyright (c) 2010 Red Hat. + * + * This code is licenced under the LGPL. + */ + +/* References: + * + * CCID Specification Revision 1.1 April 22nd 2005 + * Universal Serial Bus, Device Class: Smart Card + * Specification for Integrated Circuit(s) Cards Interface Devices + * + * Endianess note: from the spec (1.3) + * Fields that are larger than a byte are stored in little endian + * + * KNOWN BUGS + * 1. remove/insert can sometimes result in removed state instead of inserted. + * This is a result of the following: + * symptom: dmesg shows ERMOTEIO (-121), pcscd shows -99. This happens + * when we send a too short packet, seen in uhci-usb.c, resulting from + * a urb requesting SPD and us returning a smaller packet. + * Not sure which messages trigger this. + * + * Migration note: + * + * All the VMStateDescription's are left here for future use, but + * not enabled right now since there is no support for USB migration. + * + * To enable define ENABLE_MIGRATION + */ + +#include qemu-common.h +#include qemu-error.h +#include usb.h +#include monitor.h + +#include hw/ccid.h + +//#define DEBUG_CCID + +#define DPRINTF(s, lvl, fmt, ...) \ +do { if (lvl = s-debug) { printf(usb-ccid: fmt , ## __VA_ARGS__); } } while (0) + +#define CCID_DEV_NAME usb-ccid + +/* The two options for variable sized buffers: + * make them constant size, for large enough constant, + * or handle the migration complexity -