Re: [Qemu-devel] [PATCH] bitops.h: Add field32() and field64() functions to extract bitfields
Blue Swirl blauwir...@gmail.com writes: On Tue, Jun 26, 2012 at 6:41 PM, Peter Maydell peter.mayd...@linaro.org wrote: On 26 June 2012 19:25, Blue Swirl blauwir...@gmail.com wrote: On Tue, Jun 26, 2012 at 6:11 PM, Peter Maydell peter.mayd...@linaro.org wrote: On 26 June 2012 18:58, Blue Swirl blauwir...@gmail.com wrote: On Mon, Jun 25, 2012 at 7:38 PM, Peter Maydell peter.mayd...@linaro.org wrote: +static inline uint64_t field64(uint64_t value, int start, int length) start and length could be unsigned. They could be, but is there any reason why they should be? set_bit(), clear_bit() etc use 'int' for bit numbers, so this is consistent with that. Negative shifts don't work, the line with assert() would get shorter and simpler and I like unsigned values. I don't like using unsigned for numbers that merely happen to always be positive (as opposed to actually requiring unsigned arithmetic)[*], so I think I'll stick with being consistent with the existing bitops functions, thanks :-) Consistency is a strong argument. Using unsigned types also produces better code in some cases. There Better code is an argument only if the effect can be demonstrated. are also operations which do not work well with signed integers (%, ). Operator is applicable here. It works exactly as well for negative right operand as it does for large positive right operand: undefined behavior. [*] the classic example of where that kind of thing can trip you up is the way it complicates the termination condition on a for (i = N; i = 0; i--) decreasing loop. Yup. There are more, e.g. fun with unwanted truncation or sign extension when mixing different integer types. Stick to int unless you have a compelling reason.
[Qemu-devel] [PATCH V2] Exynos4: add RTC device
Signed-off-by: Oleg Ogurtsov o.ogurt...@samsung.com --- hw/arm/Makefile.objs |1 + hw/exynos4210.c |8 + hw/exynos4210_rtc.c | 595 ++ 3 files changed, 604 insertions(+), 0 deletions(-) create mode 100644 hw/exynos4210_rtc.c diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index 88ff47d..0fdb832 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -11,6 +11,7 @@ obj-y += realview_gic.o realview.o arm_sysctl.o arm11mpcore.o a9mpcore.o obj-y += exynos4210_gic.o exynos4210_combiner.o exynos4210.o obj-y += exynos4_boards.o exynos4210_uart.o exynos4210_pwm.o obj-y += exynos4210_pmu.o exynos4210_mct.o exynos4210_fimd.o +obj-y += exynos4210_rtc.o obj-y += arm_l2x0.o obj-y += arm_mptimer.o a15mpcore.o obj-y += armv7m.o armv7m_nvic.o stellaris.o pl022.o stellaris_enet.o diff --git a/hw/exynos4210.c b/hw/exynos4210.c index 9c20b3f..6e105e0 100644 --- a/hw/exynos4210.c +++ b/hw/exynos4210.c @@ -33,6 +33,9 @@ /* PWM */ #define EXYNOS4210_PWM_BASE_ADDR 0x139D +/* RTC */ +#define EXYNOS4210_RTC_BASE_ADDR 0x1007 + /* MCT */ #define EXYNOS4210_MCT_BASE_ADDR 0x1005 @@ -258,6 +261,11 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem, s-irq_table[exynos4210_get_irq(22, 3)], s-irq_table[exynos4210_get_irq(22, 4)], NULL); +/* RTC */ +sysbus_create_varargs(exynos4210.rtc, EXYNOS4210_RTC_BASE_ADDR, + s-irq_table[exynos4210_get_irq(23, 0)], + s-irq_table[exynos4210_get_irq(23, 1)], + NULL); /* Multi Core Timer */ dev = qdev_create(NULL, exynos4210.mct); diff --git a/hw/exynos4210_rtc.c b/hw/exynos4210_rtc.c new file mode 100644 index 000..f781020 --- /dev/null +++ b/hw/exynos4210_rtc.c @@ -0,0 +1,595 @@ +/* + * Samsung exynos4210 Real Time Clock + * + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * Ogurtsov Oleg o.ogurt...@samsung.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see http://www.gnu.org/licenses/. + * + */ + +/* Description: + * Register RTCCON: + * CLKSEL Bit[1] not used + * CLKOUTEN Bit[9] not used + */ + +#include sysbus.h +#include qemu-timer.h +#include qemu-common.h +#include ptimer.h + +#include hw.h +#include qemu-timer.h +#include sysemu.h + +#include exynos4210.h + +#define DEBUG_RTC 0 + +#if DEBUG_RTC +#define DPRINTF(fmt, ...) \ +do { fprintf(stdout, RTC: [%24s:%5d] fmt, __func__, __LINE__, \ +## __VA_ARGS__); } while (0) +#else +#define DPRINTF(fmt, ...) do {} while (0) +#endif + +#define EXYNOS4210_RTC_REG_MEM_SIZE 0x0100 + +#define INTP0x0030 +#define RTCCON 0x0040 +#define TICCNT 0x0044 +#define RTCALM 0x0050 +#define ALMSEC 0x0054 +#define ALMMIN 0x0058 +#define ALMHOUR 0x005C +#define ALMDAY 0x0060 +#define ALMMON 0x0064 +#define ALMYEAR 0x0068 +#define BCDSEC 0x0070 +#define BCDMIN 0x0074 +#define BCDHOUR 0x0078 +#define BCDDAY 0x007C +#define BCDDAYWEEK 0x0080 +#define BCDMON 0x0084 +#define BCDYEAR 0x0088 +#define CURTICNT0x0090 + +#define TICK_TIMER_ENABLE 0x0100 +#define TICNT_THRESHHOLD2 + + +#define RTC_ENABLE 0x0001 + +#define INTP_TICK_ENABLE0x0001 +#define INTP_ALM_ENABLE 0x0002 + +#define ALARM_INT_ENABLE0x0040 + +#define RTC_BASE_FREQ 32768 + +typedef struct Exynos4210RTCState { +SysBusDevice busdev; +MemoryRegion iomem; + +/* registers */ +uint32_treg_intp; +uint32_treg_rtccon; +uint32_treg_ticcnt; +uint32_treg_rtcalm; +uint32_treg_almsec; +uint32_treg_almmin; +uint32_treg_almhour; +uint32_treg_almday; +uint32_treg_almmon; +uint32_treg_almyear; +uint32_treg_curticcnt; + +ptimer_state*ptimer;/* tick timer */ +ptimer_state*ptimer_1Hz;/* clock timer */ +uint32_tfreq; + +qemu_irqtick_irq; /* Time Tick Generator irq */ +qemu_irqalm_irq;/* alarm irq */ + +struct tm current_tm; /* current time
[Qemu-devel] [PATCH V2] Exynos4: add RTC device
Oleg Ogurtsov (1): Exynos4: add RTC device hw/arm/Makefile.objs |1 + hw/exynos4210.c |8 + hw/exynos4210_rtc.c | 595 ++ 3 files changed, 604 insertions(+), 0 deletions(-) create mode 100644 hw/exynos4210_rtc.c -- 1.7.5.4
Re: [Qemu-devel] [PATCH V2] Exynos4: add RTC device
On 27.06.2012 10:06, Oleg Ogurtsov wrote: Oleg Ogurtsov (1): Exynos4: add RTC device hw/arm/Makefile.objs |1 + hw/exynos4210.c |8 + hw/exynos4210_rtc.c | 595 ++ 3 files changed, 604 insertions(+), 0 deletions(-) create mode 100644 hw/exynos4210_rtc.c Sorry for header...
Re: [Qemu-devel] Fwd: qemu as dynamic binary translation infrastructure
Thanks for heading up. i am not sure this software is related to QEMU, but it seems that BlueStacks is a system-emulator. I would like to learn your experiences of qemu-user. If you read carefully the thread mentioned in the link I gave you, https://groups.google.com/forum/?fromgroups#!topic/android-x86/_3HoNJTi_Y0 It said, The QEMU implementation in Bluestacks (and maybe Intel?) is QEMU user mode emulation. ... If you install Bluestacks (beta or the production version in Asus Vibe), using adb, you can easily extract a file /system/bin/arm-runtime. This is the key file which Bluestacks uses to run ARM apps. Perform a binary analysis, and you will see it is in fact Qemu. That might give you a hint. ;) Regards, chenwj -- Wei-Ren Chen (陳韋任) Computer Systems Lab, Institute of Information Science, Academia Sinica, Taiwan (R.O.C.) Tel:886-2-2788-3799 #1667 Homepage: http://people.cs.nctu.edu.tw/~chenwj
[Qemu-devel] [PATCH v5] kvm: notify host when the guest is panicked
We can know the guest is panicked when the guest runs on xen. But we do not have such feature on kvm. Another purpose of this feature is: management app(for example: libvirt) can do auto dump when the guest is panicked. If management app does not do auto dump, the guest's user can do dump by hand if he sees the guest is panicked. We have three solutions to implement this feature: 1. use vmcall 2. use I/O port 3. use virtio-serial. We have decided to avoid touching hypervisor. The reason why I choose choose the I/O port is: 1. it is easier to implememt 2. it does not depend any virtual device 3. it can work when startint the kernel Signed-off-by: Wen Congyang we...@cn.fujitsu.com --- arch/ia64/include/asm/kvm_para.h|5 + arch/powerpc/include/asm/kvm_para.h |5 + arch/s390/include/asm/kvm_para.h|5 + arch/x86/include/asm/kvm_para.h |7 +++ arch/x86/kernel/kvm.c | 14 ++ include/linux/kvm_para.h| 13 + 6 files changed, 49 insertions(+), 0 deletions(-) diff --git a/arch/ia64/include/asm/kvm_para.h b/arch/ia64/include/asm/kvm_para.h index 2019cb9..187c0e2 100644 --- a/arch/ia64/include/asm/kvm_para.h +++ b/arch/ia64/include/asm/kvm_para.h @@ -31,6 +31,11 @@ static inline bool kvm_check_and_clear_guest_paused(void) return false; } +static inline unsigned int kvm_arch_pv_features(void) +{ + return 0; +} + #endif #endif diff --git a/arch/powerpc/include/asm/kvm_para.h b/arch/powerpc/include/asm/kvm_para.h index c18916b..be81aac 100644 --- a/arch/powerpc/include/asm/kvm_para.h +++ b/arch/powerpc/include/asm/kvm_para.h @@ -211,6 +211,11 @@ static inline bool kvm_check_and_clear_guest_paused(void) return false; } +static inline unsigned int kvm_arch_pv_features(void) +{ + return 0; +} + #endif /* __KERNEL__ */ #endif /* __POWERPC_KVM_PARA_H__ */ diff --git a/arch/s390/include/asm/kvm_para.h b/arch/s390/include/asm/kvm_para.h index a988329..3d993b7 100644 --- a/arch/s390/include/asm/kvm_para.h +++ b/arch/s390/include/asm/kvm_para.h @@ -154,6 +154,11 @@ static inline bool kvm_check_and_clear_guest_paused(void) return false; } +static inline unsigned int kvm_arch_pv_features(void) +{ + return 0; +} + #endif #endif /* __S390_KVM_PARA_H */ diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h index 63ab166..c8ad86e 100644 --- a/arch/x86/include/asm/kvm_para.h +++ b/arch/x86/include/asm/kvm_para.h @@ -89,6 +89,8 @@ struct kvm_vcpu_pv_apf_data { __u32 enabled; }; +#define KVM_PV_PORT(0x505UL) + #ifdef __KERNEL__ #include asm/processor.h @@ -221,6 +223,11 @@ static inline void kvm_disable_steal_time(void) } #endif +static inline unsigned int kvm_arch_pv_features(void) +{ + return inl(KVM_PV_PORT); +} + #endif /* __KERNEL__ */ #endif /* _ASM_X86_KVM_PARA_H */ diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index e554e5a..9a97f7e 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c @@ -328,6 +328,17 @@ static struct notifier_block kvm_pv_reboot_nb = { .notifier_call = kvm_pv_reboot_notify, }; +static int +kvm_pv_panic_notify(struct notifier_block *nb, unsigned long code, void *unused) +{ + outl(KVM_PV_PANICKED, KVM_PV_PORT); + return NOTIFY_DONE; +} + +static struct notifier_block kvm_pv_panic_nb = { + .notifier_call = kvm_pv_panic_notify, +}; + static u64 kvm_steal_clock(int cpu) { u64 steal; @@ -414,6 +425,9 @@ void __init kvm_guest_init(void) paravirt_ops_setup(); register_reboot_notifier(kvm_pv_reboot_nb); + if (kvm_pv_has_feature(KVM_PV_FEATURE_PANICKED)) + atomic_notifier_chain_register(panic_notifier_list, + kvm_pv_panic_nb); for (i = 0; i KVM_TASK_SLEEP_HASHSIZE; i++) spin_lock_init(async_pf_sleepers[i].lock); if (kvm_para_has_feature(KVM_FEATURE_ASYNC_PF)) diff --git a/include/linux/kvm_para.h b/include/linux/kvm_para.h index ff476dd..e73efcf 100644 --- a/include/linux/kvm_para.h +++ b/include/linux/kvm_para.h @@ -20,6 +20,12 @@ #define KVM_HC_FEATURES3 #define KVM_HC_PPC_MAP_MAGIC_PAGE 4 +/* The bit of the value read from KVM_PV_PORT */ +#define KVM_PV_FEATURE_PANICKED0 + +/* The value writen to KVM_PV_PORT */ +#define KVM_PV_PANICKED1 + /* * hypercalls use architecture specific */ @@ -33,5 +39,12 @@ static inline int kvm_para_has_feature(unsigned int feature) return 1; return 0; } + +static inline int kvm_pv_has_feature(unsigned int feature) +{ + if (kvm_arch_pv_features() (1UL feature)) + return 1; + return 0; +} #endif /* __KERNEL__ */ #endif /* __LINUX_KVM_PARA_H */ -- 1.7.1
[Qemu-devel] [PATCH 1/6 v5] start vm after reseting it
The guest should run after reseting it, but it does not run if its old state is RUN_STATE_INTERNAL_ERROR or RUN_STATE_PAUSED. Signed-off-by: Wen Congyang we...@cn.fujitsu.com --- block.h |2 ++ qmp.c |2 +- vl.c|3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/block.h b/block.h index d135652..d9570dd 100644 --- a/block.h +++ b/block.h @@ -365,6 +365,8 @@ void bdrv_disable_copy_on_read(BlockDriverState *bs); void bdrv_set_in_use(BlockDriverState *bs, int in_use); int bdrv_in_use(BlockDriverState *bs); +void iostatus_bdrv_it(void *opaque, BlockDriverState *bs); + enum BlockAcctType { BDRV_ACCT_READ, BDRV_ACCT_WRITE, diff --git a/qmp.c b/qmp.c index fee9fb2..a111dff 100644 --- a/qmp.c +++ b/qmp.c @@ -125,7 +125,7 @@ SpiceInfo *qmp_query_spice(Error **errp) }; #endif -static void iostatus_bdrv_it(void *opaque, BlockDriverState *bs) +void iostatus_bdrv_it(void *opaque, BlockDriverState *bs) { bdrv_iostatus_reset(bs); } diff --git a/vl.c b/vl.c index 1329c30..b38aa5f 100644 --- a/vl.c +++ b/vl.c @@ -1532,7 +1532,8 @@ static bool main_loop_should_exit(void) resume_all_vcpus(); if (runstate_check(RUN_STATE_INTERNAL_ERROR) || runstate_check(RUN_STATE_SHUTDOWN)) { -runstate_set(RUN_STATE_PAUSED); +bdrv_iterate(iostatus_bdrv_it, NULL); +vm_start(); } } if (qemu_powerdown_requested()) { -- 1.7.1
[Qemu-devel] [PATCH 2/6 v5] update linux headers
Signed-off-by: Wen Congyang we...@cn.fujitsu.com --- linux-headers/asm-x86/kvm_para.h |2 ++ linux-headers/linux/kvm_para.h |6 ++ 2 files changed, 8 insertions(+), 0 deletions(-) diff --git a/linux-headers/asm-x86/kvm_para.h b/linux-headers/asm-x86/kvm_para.h index f2ac46a..f9d858f 100644 --- a/linux-headers/asm-x86/kvm_para.h +++ b/linux-headers/asm-x86/kvm_para.h @@ -89,5 +89,7 @@ struct kvm_vcpu_pv_apf_data { __u32 enabled; }; +#define KVM_PV_PORT(0x505UL) + #endif /* _ASM_X86_KVM_PARA_H */ diff --git a/linux-headers/linux/kvm_para.h b/linux-headers/linux/kvm_para.h index 7bdcf93..4fbd625 100644 --- a/linux-headers/linux/kvm_para.h +++ b/linux-headers/linux/kvm_para.h @@ -20,6 +20,12 @@ #define KVM_HC_FEATURES3 #define KVM_HC_PPC_MAP_MAGIC_PAGE 4 +/* The bit of the value read from KVM_PV_PORT */ +#define KVM_PV_FEATURE_PANICKED0 + +/* The value writen to KVM_PV_PORT */ +#define KVM_PV_PANICKED1 + /* * hypercalls use architecture specific */ -- 1.7.1
[Qemu-devel] [PATCH 3/6 v5] add a new runstate: RUN_STATE_GUEST_PANICKED
Add a new runstate RUN_STATE_GUEST_PANICKED. The guest can be in this state if it is paused due to panicked event. Signed-off-by: Wen Congyang we...@cn.fujitsu.com --- qapi-schema.json |6 +- qmp.c|3 ++- vl.c |7 ++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/qapi-schema.json b/qapi-schema.json index 3b6e346..009f653 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -119,11 +119,15 @@ # @suspended: guest is suspended (ACPI S3) # # @watchdog: the watchdog action is configured to pause and has been triggered +# +# @guest-panicked: the panicked action is configured to pause and has been +# triggered. ## { 'enum': 'RunState', 'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused', 'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm', -'running', 'save-vm', 'shutdown', 'suspended', 'watchdog' ] } +'running', 'save-vm', 'shutdown', 'suspended', 'watchdog', +'guest-panicked' ] } ## # @StatusInfo: diff --git a/qmp.c b/qmp.c index a111dff..3b0c9bc 100644 --- a/qmp.c +++ b/qmp.c @@ -148,7 +148,8 @@ void qmp_cont(Error **errp) error_set(errp, QERR_MIGRATION_EXPECTED); return; } else if (runstate_check(RUN_STATE_INTERNAL_ERROR) || - runstate_check(RUN_STATE_SHUTDOWN)) { + runstate_check(RUN_STATE_SHUTDOWN) || + runstate_check(RUN_STATE_GUEST_PANICKED)) { error_set(errp, QERR_RESET_REQUIRED); return; } else if (runstate_check(RUN_STATE_SUSPENDED)) { diff --git a/vl.c b/vl.c index b38aa5f..c0e5d3c 100644 --- a/vl.c +++ b/vl.c @@ -361,6 +361,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_RUNNING, RUN_STATE_SAVE_VM }, { RUN_STATE_RUNNING, RUN_STATE_SHUTDOWN }, { RUN_STATE_RUNNING, RUN_STATE_WATCHDOG }, +{ RUN_STATE_RUNNING, RUN_STATE_GUEST_PANICKED }, { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING }, @@ -375,6 +376,9 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_WATCHDOG, RUN_STATE_RUNNING }, { RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE }, +{ RUN_STATE_GUEST_PANICKED, RUN_STATE_PAUSED }, +{ RUN_STATE_GUEST_PANICKED, RUN_STATE_FINISH_MIGRATE }, + { RUN_STATE_MAX, RUN_STATE_MAX }, }; @@ -1531,7 +1535,8 @@ static bool main_loop_should_exit(void) qemu_system_reset(VMRESET_REPORT); resume_all_vcpus(); if (runstate_check(RUN_STATE_INTERNAL_ERROR) || -runstate_check(RUN_STATE_SHUTDOWN)) { +runstate_check(RUN_STATE_SHUTDOWN) || +runstate_check(RUN_STATE_GUEST_PANICKED)) { bdrv_iterate(iostatus_bdrv_it, NULL); vm_start(); } -- 1.7.1
[Qemu-devel] [PATCH 4/6 v5] add a new qevent: QEVENT_GUEST_PANICKED
Add a new qevent QEVENT_GUEST_PANICKED. QEMU will emit this event if the guest is panicked. Signed-off-by: Wen Congyang we...@cn.fujitsu.com --- monitor.c |1 + monitor.h |1 + 2 files changed, 2 insertions(+), 0 deletions(-) diff --git a/monitor.c b/monitor.c index f6107ba..28f7482 100644 --- a/monitor.c +++ b/monitor.c @@ -458,6 +458,7 @@ static const char *monitor_event_names[] = { [QEVENT_SUSPEND] = SUSPEND, [QEVENT_WAKEUP] = WAKEUP, [QEVENT_BALLOON_CHANGE] = BALLOON_CHANGE, +[QEVENT_GUEST_PANICKED] = GUEST_PANICKED, }; QEMU_BUILD_BUG_ON(ARRAY_SIZE(monitor_event_names) != QEVENT_MAX) diff --git a/monitor.h b/monitor.h index 5f4de1b..cb7de8c 100644 --- a/monitor.h +++ b/monitor.h @@ -42,6 +42,7 @@ typedef enum MonitorEvent { QEVENT_SUSPEND, QEVENT_WAKEUP, QEVENT_BALLOON_CHANGE, +QEVENT_GUEST_PANICKED, /* Add to 'monitor_event_names' array in monitor.c when * defining new events here */ -- 1.7.1
[Qemu-devel] [PATCH 5/6 v5] deal with guest panicked event accoring to -onpanic parameter
When the guest is panicked, it will write 0x1 to the port KVM_PV_PORT. So if qemu reads 0x1 from this port, we can do the folloing three things according to the parameter -onpanic: 1. emit QEVENT_GUEST_PANICKED only 2. emit QEVENT_GUEST_PANICKED and pause the guest 3. emit QEVENT_GUEST_PANICKED and poweroff the guest 4. emit QEVENT_GUEST_PANICKED and reset the guest Note: if we emit QEVENT_GUEST_PANICKED only, and the management application does not receive this event(the management may not run when the event is emitted), the management won't know the guest is panicked. Signed-off-by: Wen Congyang we...@cn.fujitsu.com --- kvm-all.c | 101 +++ kvm-stub.c |9 + kvm.h |3 ++ qemu-options.hx | 15 vl.c| 10 + 5 files changed, 138 insertions(+), 0 deletions(-) diff --git a/kvm-all.c b/kvm-all.c index f8e4328..9494dd2 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -19,6 +19,8 @@ #include stdarg.h #include linux/kvm.h +#include linux/kvm_para.h +#include asm/kvm_para.h #include qemu-common.h #include qemu-barrier.h @@ -32,6 +34,9 @@ #include bswap.h #include memory.h #include exec-memory.h +#include iorange.h +#include qemu-objects.h +#include monitor.h /* This check must be after config-host.h is included */ #ifdef CONFIG_EVENTFD @@ -1931,3 +1936,99 @@ int kvm_on_sigbus(int code, void *addr) { return kvm_arch_on_sigbus(code, addr); } + +/* Possible values for action parameter. */ +#define PANICKED_REPORT 1 /* emit QEVENT_GUEST_PANICKED only */ +#define PANICKED_PAUSE 2 /* emit QEVENT_GUEST_PANICKED and pause VM */ +#define PANICKED_POWEROFF 3 /* emit QEVENT_GUEST_PANICKED and quit VM */ +#define PANICKED_RESET 4 /* emit QEVENT_GUEST_PANICKED and reset VM */ + +static int panicked_action = PANICKED_REPORT; + +static void kvm_pv_port_read(IORange *iorange, uint64_t offset, unsigned width, + uint64_t *data) +{ +*data = (1 KVM_PV_FEATURE_PANICKED); +} + +static void panicked_mon_event(const char *action) +{ +QObject *data; + +data = qobject_from_jsonf({ 'action': %s }, action); +monitor_protocol_event(QEVENT_GUEST_PANICKED, data); +qobject_decref(data); +} + +static void panicked_perform_action(void) +{ +switch (panicked_action) { +case PANICKED_REPORT: +panicked_mon_event(report); +break; + +case PANICKED_PAUSE: +panicked_mon_event(pause); +vm_stop(RUN_STATE_GUEST_PANICKED); +break; + +case PANICKED_POWEROFF: +panicked_mon_event(poweroff); +exit(0); +break; +case PANICKED_RESET: +panicked_mon_event(reset); +qemu_system_reset_request(); +break; +} +} + +static void kvm_pv_port_write(IORange *iorange, uint64_t offset, unsigned width, + uint64_t data) +{ +if (data == KVM_PV_PANICKED) { +panicked_perform_action(); +} +} + +static void kvm_pv_port_destructor(IORange *iorange) +{ +g_free(iorange); +} + +static IORangeOps pv_io_range_ops = { +.read = kvm_pv_port_read, +.write = kvm_pv_port_write, +.destructor = kvm_pv_port_destructor, +}; + +#if defined(KVM_PV_PORT) +void kvm_pv_port_init(void) +{ +IORange *pv_io_range = g_malloc(sizeof(IORange)); + +iorange_init(pv_io_range, pv_io_range_ops, KVM_PV_PORT, 1); +ioport_register(pv_io_range); +} +#else +void kvm_pv_port_init(void) +{ +} +#endif + +int select_panicked_action(const char *p) +{ +if (strcasecmp(p, none) == 0) { +panicked_action = PANICKED_REPORT; +} else if (strcasecmp(p, pause) == 0) { +panicked_action = PANICKED_PAUSE; +} else if (strcasecmp(p, poweroff) == 0) { +panicked_action = PANICKED_POWEROFF; +} else if (strcasecmp(p, reset) == 0) { +panicked_action = PANICKED_RESET; +} else { +return -1; +} + +return 0; +} diff --git a/kvm-stub.c b/kvm-stub.c index ec9a364..318e967 100644 --- a/kvm-stub.c +++ b/kvm-stub.c @@ -151,3 +151,12 @@ int kvm_irqchip_remove_irqfd(KVMState *s, int fd, int virq) { return -ENOSYS; } + +void kvm_pv_port_init(void) +{ +} + +int select_panicked_action(const char *p) +{ +return -1; +} diff --git a/kvm.h b/kvm.h index 9c7b0ea..d174d5a 100644 --- a/kvm.h +++ b/kvm.h @@ -64,6 +64,9 @@ int kvm_has_gsi_routing(void); int kvm_allows_irq0_override(void); +void kvm_pv_port_init(void); +int select_panicked_action(const char *p); + #ifdef NEED_CPU_H int kvm_init_vcpu(CPUArchState *env); diff --git a/qemu-options.hx b/qemu-options.hx index 8b66264..4a061bf 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -2743,6 +2743,21 @@ DEF(qtest-log, HAS_ARG, QEMU_OPTION_qtest_log, -qtest-log LOG specify tracing options\n, QEMU_ARCH_ALL) +DEF(onpanic, HAS_ARG, QEMU_OPTION_onpanic, \ +-onpanic none|pause|poweroff|reset\n \ +action when the
Re: [Qemu-devel] [RFC PATCH V1 1/2] arm_boot: added linux switch
On 27 June 2012 05:38, Peter Crosthwaite peter.crosthwa...@petalogix.com wrote: Ping! Whats the action item here? Put out an RFC about unifying bootloaders or some such? Something like that -- identify what all the architectures currently do with these command line arguments and propose something to bring the outliers into line, I guess. (We do still need the just load an ELF functionality but ideally as something consistently provided for all archs.) -- PMM
Re: [Qemu-devel] [PATCH] kvm: First step to push iothread lock out of inner run loop
On Tue, Jun 26, 2012 at 8:34 PM, Marcelo Tosatti mtosa...@redhat.com wrote: On Sat, Jun 23, 2012 at 12:55:49AM +0200, Jan Kiszka wrote: net.txt iothread flow = 1) Skip-work-if-device-locked select(tap fd ready) tap_send if (trylock(TAPState-NetClientState-dev)) proceed; else continue; (data remains in queue) tap_read_packet qemu_send_packet_async DRAWBACK: lock intensive. DRAWBACK: VCPU threads can starve IOTHREAD (can be fixed with a scheme such as trylock() marks a flag saying iothread wants lock. One alternative is to say the lock cannot be held across system calls or other long-running operations (similar to interrupt handler spinlocks in the kernel). But QEMU threads are still at the mercy of the scheduler or page faults, so perhaps this is not a good idea because waiting on the lock could tie up the iothread. 2) Queue-work-to-vcpu-context select(tap fd ready) tap_send if (trylock(TAPState-NetClientState-dev)) { proceed; } else { AddToDeviceWorkQueue(work); } tap_read_packet qemu_send_packet_async DRAWBACK: lock intensive DRAWBACK: cache effects This almost suggests we should invert packet reception for NICs. tap fd ready should add a work item and the guest device calls into net/tap.c to pull out any packets from the work function: tap_send dev_add_work(work); virtio_net_rx_work_fn while ((req = virtqueue_pop(rx_queue))) { if (!net_receive_packet(netclient, req-buf)) { break; /* no more packets available */ } /* ...mark req complete and push onto virtqueue... */ } virtqueue_notify(rx_queue); The idea is to avoid copies on the rx path and make the locking simple by always deferring to a work function (which can be invoked immediately if the device isn't locked). Stefan
[Qemu-devel] [PATCH 6/6 v5] deal with panicked event accoring to '-machine panic_action=action'
The action is the same as -onpanic parameter. Signed-off-by: Wen Congyang we...@cn.fujitsu.com --- qemu-config.c |4 qemu-options.hx |4 +++- vl.c|7 +++ 3 files changed, 14 insertions(+), 1 deletions(-) diff --git a/qemu-config.c b/qemu-config.c index 5c3296b..805e7c4 100644 --- a/qemu-config.c +++ b/qemu-config.c @@ -595,6 +595,10 @@ static QemuOptsList qemu_machine_opts = { .name = dt_compatible, .type = QEMU_OPT_STRING, .help = Overrides the \compatible\ property of the dt root node, +}, { +.name = panic_action, +.type = QEMU_OPT_STRING, +.help = The action what QEMU will do when the guest is panicked, }, { /* End of list */ } }, diff --git a/qemu-options.hx b/qemu-options.hx index 4a061bf..083a21d 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -33,7 +33,9 @@ DEF(machine, HAS_ARG, QEMU_OPTION_machine, \ property accel=accel1[:accel2[:...]] selects accelerator\n supported accelerators are kvm, xen, tcg (default: tcg)\n kernel_irqchip=on|off controls accelerated irqchip support\n -kvm_shadow_mem=size of KVM shadow MMU\n, +kvm_shadow_mem=size of KVM shadow MMU\n +panic_action=none|pause|poweroff|reset controls what QEmu\n +will do when the guest is panicked, QEMU_ARCH_ALL) STEXI @item -machine [type=]@var{name}[,prop=@var{value}[,...]] diff --git a/vl.c b/vl.c index 9164d29..7663699 100644 --- a/vl.c +++ b/vl.c @@ -2301,6 +2301,7 @@ int main(int argc, char **argv, char **envp) }; const char *trace_events = NULL; const char *trace_file = NULL; +const char *panic_action = NULL; atexit(qemu_run_exit_notifiers); error_set_progname(argv[0]); @@ -3372,10 +3373,16 @@ int main(int argc, char **argv, char **envp) kernel_filename = qemu_opt_get(machine_opts, kernel); initrd_filename = qemu_opt_get(machine_opts, initrd); kernel_cmdline = qemu_opt_get(machine_opts, append); +panic_action = qemu_opt_get(machine_opts, panic_action); } else { kernel_filename = initrd_filename = kernel_cmdline = NULL; } +if (panic_action select_panicked_action(panic_action) == -1) { +fprintf(stderr, Unknown -panic_action parameter\n); +exit(1); +} + if (!kernel_cmdline) { kernel_cmdline = ; } -- 1.7.1
Re: [Qemu-devel] [PATCH] kvm: First step to push iothread lock out of inner run loop
On Wed, Jun 27, 2012 at 8:39 AM, Stefan Hajnoczi stefa...@gmail.com wrote: On Tue, Jun 26, 2012 at 8:34 PM, Marcelo Tosatti mtosa...@redhat.com wrote: On Sat, Jun 23, 2012 at 12:55:49AM +0200, Jan Kiszka wrote: net.txt iothread flow = 1) Skip-work-if-device-locked select(tap fd ready) tap_send if (trylock(TAPState-NetClientState-dev)) proceed; else continue; (data remains in queue) tap_read_packet qemu_send_packet_async DRAWBACK: lock intensive. DRAWBACK: VCPU threads can starve IOTHREAD (can be fixed with a scheme such as trylock() marks a flag saying iothread wants lock. One alternative is to say the lock cannot be held across system calls or other long-running operations (similar to interrupt handler spinlocks in the kernel). But QEMU threads are still at the mercy of the scheduler or page faults, so perhaps this is not a good idea because waiting on the lock could tie up the iothread. 2) Queue-work-to-vcpu-context select(tap fd ready) tap_send if (trylock(TAPState-NetClientState-dev)) { proceed; } else { AddToDeviceWorkQueue(work); } tap_read_packet qemu_send_packet_async DRAWBACK: lock intensive DRAWBACK: cache effects This almost suggests we should invert packet reception for NICs. tap fd ready should add a work item and the guest device calls into net/tap.c to pull out any packets from the work function: tap_send dev_add_work(work); virtio_net_rx_work_fn while ((req = virtqueue_pop(rx_queue))) { if (!net_receive_packet(netclient, req-buf)) { break; /* no more packets available */ } /* ...mark req complete and push onto virtqueue... */ } virtqueue_notify(rx_queue); The idea is to avoid copies on the rx path and make the locking simple by always deferring to a work function (which can be invoked immediately if the device isn't locked). I just realized this approach bypasses net/queue.c. I think it works really well for the peer model (no VLANs). Basically flow control is dictated by the peer (receiver) and we don't need to use NetQueue anymore. Whether this works elegantly for slirp and other backends, I'm not sure yet. Stefan
Re: [Qemu-devel] [RFC] block: Removed coroutine ownership assumption
On Wed, Jun 27, 2012 at 4:05 AM, Peter Crosthwaite peter.crosthwa...@petalogix.com wrote: I still think this thread points out a major flaw in block+coroutines, regardless of the fact im using it from a machine model. This bug is going to happen in any coroutine code that touches the block layer (E.G. what happens if the next developer wants to implement a device using coroutines?). Yes, without my full series there is no bug today, but im just trying to save the next developer who decides to use corourites (whether that be in tree or out of tree) the potentially several hours of debugging around why did my coroutine get yielded randomly. That and of course minimisation of my own mainline diff. The if (qemu_is_coroutine()) fastpath taken by the block layer today hopefully won't be around forever. It's really a shortcut that allows code originally written with synchronous I/O in mind to work unmodified in a coroutine. Really we should get rid of bdrv_read() and friends so that all callers use either bdrv_aio_*() or bdrv_co_*(). Then all functions that yield will be marked coroutine_fn. Then you know for sure that the function may yield and you cannot rely on it not yielding. I'd like to see your code though because I still don't understand why it relies on the exact yield behavior. Have you pushed it to a public git repo? Stefan
Re: [Qemu-devel] [PATCH] kvm: First step to push iothread lock out of inner run loop
On 06/26/2012 10:34 PM, Marcelo Tosatti wrote: 1. read_lock(memmap_lock) 2. MemoryRegionSection mrs = lookup(addr) 3. qom_ref(mrs.mr-dev) 4. read_unlock(memmap_lock) 5. mutex_lock(dev-lock) 6. dispatch(mrs, addr, data, size) 7. mutex_unlock(dev-lock) 8. qom_unref(mrs.mr-object) The plan also includes eventually replacing read_lock() with rcu; so two devices can be accessed in parallel with no cacheline bouncing. -- error compiling committee.c: too many arguments to function
Re: [Qemu-devel] [RFC] block: Removed coroutine ownership assumption
On 27 June 2012 08:48, Stefan Hajnoczi stefa...@gmail.com wrote: I'd like to see your code though because I still don't understand why it relies on the exact yield behavior. Have you pushed it to a public git repo? I haven't seen Peter's code either, but his complaint makes sense to me -- the whole point of coroutines is that you can rely on the exact yield behaviour, surely. -- PMM
[Qemu-devel] Regression commit 6e008585 qdev: remove info from class
Before: $ qemu-system-x86_64 -display none -drive if=ide qemu-system-x86_64: Device needs media, but drive is empty qemu-system-x86_64: Initialization of device ide-hd failed [Exit 1 ] After: $ qemu-system-x86_64 -display none -drive if=ide qemu-system-x86_64: Device needs media, but drive is empty Segmentation fault (core dumped) [Exit 139 (SIGSEGV)] Debugger says: Program received signal SIGSEGV, Segmentation fault. 0x005878d9 in object_get_typename (obj=0x13b26e0) at /home/armbru/work/qemu/qom/object.c:441 441 return obj-class-type-name; #0 0x005878d9 in object_get_typename (obj=0x13b26e0) at /home/armbru/work/qemu/qom/object.c:441 #1 0x0056c28d in qdev_init_nofail (dev=0x13b26e0) at /home/armbru/work/qemu/hw/qdev.c:517 #2 0x004f1079 in ide_create_drive (bus=0x13ae978, unit=0, drive= 0x12b4550) at /home/armbru/work/qemu/hw/ide/qdev.c:108 #3 0x004f00d8 in pci_ide_create_devs (dev=0x13ae530, hd_table= 0x7fffdc50) at /home/armbru/work/qemu/hw/ide/pci.c:503 #4 0x004f0a82 in pci_piix3_ide_init (bus=0x1305170, hd_table= 0x7fffdc50, devfn=9) at /home/armbru/work/qemu/hw/ide/piix.c:225 #5 0x0067006b in pc_init1 (system_memory=0x12b4140, system_io= 0x12b4230, ram_size=134217728, boot_device=0x7fffe010 cad, kernel_filename=0x0, kernel_cmdline=0x797d4a , initrd_filename=0x0, cpu_model=0x0, pci_enabled=1, kvmclock_enabled=1) at /home/armbru/work/qemu/hw/pc_piix.c:257 #6 0x00670385 in pc_init_pci (ram_size=134217728, boot_device= 0x7fffe010 cad, kernel_filename=0x0, kernel_cmdline=0x797d4a , initrd_filename=0x0, cpu_model=0x0) at /home/armbru/work/qemu/hw/pc_piix.c:319 #7 0x00543408 in main (argc=5, argv=0x7fffe138, envp= 0x7fffe168) at /home/armbru/work/qemu/vl.c:3387
Re: [Qemu-devel] [RFC] block: Removed coroutine ownership assumption
On Wed, Jun 27, 2012 at 8:59 AM, Peter Maydell peter.mayd...@linaro.org wrote: On 27 June 2012 08:48, Stefan Hajnoczi stefa...@gmail.com wrote: I'd like to see your code though because I still don't understand why it relies on the exact yield behavior. Have you pushed it to a public git repo? I haven't seen Peter's code either, but his complaint makes sense to me -- the whole point of coroutines is that you can rely on the exact yield behaviour, surely. Not if you call coroutine_fn functions - these are explicitly marked as functions that yield. For example block or net I/O. The issue here is that there are some block.h functions that are not marked coroutine_fn but actually yield if running inside coroutine context. I think we could get rid of them with a little bit of work. Stefan
[Qemu-devel] [RFC PATCH 1/1] Stupid test case to demonstrate flawed crash handling
Makes make check hang: QTEST_QEMU_BINARY=x86_64-softmmu/qemu-system-x86_64 gtester -k --verbose -m=quick tests/crash-test tests/rtc-test TEST: tests/crash-test... (pid=972) qemu-system-x86_64: Device needs media, but drive is empty [Nothing happens, wait a while, then hit ^C] make: *** [check-qtest-x86_64] Interrupt Relies on the bug in -drive if=ide error handling I just reported[*], because I'm lazy. [*] Subject: Regression commit 6e008585 qdev: remove info from class Signed-off-by: Markus Armbruster arm...@redhat.com --- tests/Makefile |2 ++ tests/crash-test.c | 18 ++ 2 files changed, 20 insertions(+), 0 deletions(-) create mode 100644 tests/crash-test.c diff --git a/tests/Makefile b/tests/Makefile index d66ab19..7fcf7a9 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -20,6 +20,7 @@ check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh # All QTests for now are POSIX-only, but the dependencies are # really in libqtest, not in the testcases themselves. check-qtest-i386-y = tests/fdc-test$(EXESUF) +check-qtest-i386-y = tests/crash-test$(EXESUF) check-qtest-i386-y += tests/rtc-test$(EXESUF) check-qtest-x86_64-y = $(check-qtest-i386-y) check-qtest-sparc-y = tests/m48t59-test$(EXESUF) @@ -70,6 +71,7 @@ tests/test-visitor-serialization$(EXESUF): tests/test-visitor-serialization.o $( tests/rtc-test$(EXESUF): tests/rtc-test.o $(trace-obj-y) tests/m48t59-test$(EXESUF): tests/m48t59-test.o $(trace-obj-y) tests/fdc-test$(EXESUF): tests/fdc-test.o tests/libqtest.o $(trace-obj-y) +tests/crash-test$(EXESUF): tests/crash-test.o tests/libqtest.o $(trace-obj-y) # QTest rules diff --git a/tests/crash-test.c b/tests/crash-test.c new file mode 100644 index 000..d69dae0 --- /dev/null +++ b/tests/crash-test.c @@ -0,0 +1,18 @@ +#include glib.h +#include libqtest.h + +int main(int argc, char **argv) +{ +int ret; + +g_test_init(argc, argv, NULL); + +qtest_start(-display none -drive if=ide); +qtest_irq_intercept_in(global_qtest, ioapic); + +ret = g_test_run(); + +qtest_quit(global_qtest); + +return ret; +} -- 1.7.6.5
[Qemu-devel] Test harness goes into infinite loop when test case crashes
Maybe I'm doing something wrong. But for me, make check hangs when a test cases manages to crash QEMU. I include a stupid test case that does just that. Markus Armbruster (1): Stupid test case to demonstrate flawed crash handling tests/Makefile |2 ++ tests/crash-test.c | 18 ++ 2 files changed, 20 insertions(+), 0 deletions(-) create mode 100644 tests/crash-test.c -- 1.7.6.5
Re: [Qemu-devel] net: RFC New Socket-Based, Switched Network Backend (QDES)
On Tue, Jun 26, 2012 at 5:48 PM, Mike Lovell m...@dev-zero.net wrote: On 06/26/2012 02:29 AM, Stefan Hajnoczi wrote: On Mon, Jun 25, 2012 at 5:32 PM, Mike Lovell m...@dev-zero.net wrote: Oh. I forgot another reason why I decided to do this over using VDE. I'll do this one with an example. Say you have 3 virtual machines on 3 different hosts. Each host has a vde_switch process running, Switch A, B, and C. Each vde_switch has connections to the other 2 through some vde_plug's and netcat. In this case, VDE will disable one of the links between switches to prevent loops, say the link between Switch A and C. Traffic from the VM connected to Switch C that is destined for the VM on Switch A will have to traverse through Switch B. This is a suboptimal traffic flow. Especially when you consider that the traffic has to flow through 3 to 4 additional processes on each host for each direction. I haven't tried VDE myself but this sounds odd. Why can't you run a single vde_switch instance and connect multiple guests to it (with netcat)? you can connect multiple guests to a single vde_switch. as i understand it, the communication happens over a local unix domain socket. this would limit the guests on the same switch to the same host. so if you want guests on multiple hosts to talk using vde, i think you need a vde_switch on each host and then connect the vde_switch processes. It can be done with socat or netcat (unix_domain_socket_a - TCP - unix_domain_socket_b): http://www.dest-unreach.org/socat/doc/socat.html Another idea is to take the QDES code and turn it into a freestanding program that speaks the net/socket.c protocol. That way it works with existing QEMUs: launch the qdes daemon, then launch qemu -netdev socket,connect=qdes-host:qdes-port. Stefan
Re: [Qemu-devel] [RFC] block: Removed coroutine ownership assumption
Stefan Hajnoczi stefa...@gmail.com writes: On Wed, Jun 27, 2012 at 8:59 AM, Peter Maydell peter.mayd...@linaro.org wrote: On 27 June 2012 08:48, Stefan Hajnoczi stefa...@gmail.com wrote: I'd like to see your code though because I still don't understand why it relies on the exact yield behavior. Have you pushed it to a public git repo? I haven't seen Peter's code either, but his complaint makes sense to me -- the whole point of coroutines is that you can rely on the exact yield behaviour, surely. Not if you call coroutine_fn functions - these are explicitly marked as functions that yield. For example block or net I/O. I think you two are in violent agreement :) With coroutines, you can rely on the exact yield behavior. Of course, that doesn't do you any good unless you know which functions can yield. We make that easy by giving such functions distinctive names. Except when we don't: The issue here is that there are some block.h functions that are not marked coroutine_fn but actually yield if running inside coroutine context. I think we could get rid of them with a little bit of work. Sounds like a good idea.
Re: [Qemu-devel] [PATCH v4 0/7] file descriptor passing using pass-fd
Am 27.06.2012 00:28, schrieb Corey Bryant: On 06/26/2012 04:50 PM, Luiz Capitulino wrote: On Tue, 26 Jun 2012 13:45:52 +0200 Kevin Wolf kw...@redhat.com wrote: Am 26.06.2012 11:10, schrieb Daniel P. Berrange: I was thinking about some of the sources complexity when using FD passing from libvirt and wanted to raise one idea for discussion before we continue. With this proposed series, we have usage akin to: 1. pass_fd FDSET={M} - returns a string /dev/fd/N showing QEMU's view of the FD 2. drive_add file=/dev/fd/N 3. if failure: close_fd /dev/fd/N In fact, there are more steps: 4. use it successfully 5. close_fd /dev/fd/N I think it would well be possible that qemu just closes the fd when it's not used internally any more. pass-fd could have a flag indicating qemu to do that. It seems like libvirt would be in a better position to understand when a file is no longer in use, and then it can call close_fd. No? Of course the the only fd that needs to be closed is the originally passed fd. The dup'd fd's are closed by QEMU. No, libvirt doesn't know it, because the original file descriptor is still needed when qemu decides to reopen the file. So I think qemu needs some kind of refcounting anyway. One of the references is held by libvirt and it can drop it with close_fd, and the other one would be for the BlockDriverState or whatever you use the FD with. (There's a tricky part: When do you actually close the FD? If libvirt has dropped its reference and qemu reopens, for example because it has just probed the image format, we have a short time where the refcount would be 0, but we can't drop it anyway.) Kevin
Re: [Qemu-devel] [libvirt] [PATCH v4 0/7] file descriptor passing using pass-fd
Am 26.06.2012 20:40, schrieb Corey Bryant: Here is a quick proof of concept (ie untested) patch to demonstrate what I mean. It relies on Cory's patch which converts everything to use qemu_open. It is also still valuable to make the change to qemu_open() to support /dev/fd/N for passing FDs during QEMU initial startup for CLI args. IMHO, what I propose here is preferrable for QMP clients that our current plan of requiring use of 3 monitor commands (passfd, X, closefd). Thanks for the PoC. Two other required updates that I can think of would be: 1) Update change, block_stream, block_reopen, snapshot_blkdev, and perhaps other monitor commands to support receiving fd's via SCM_RIGHTS. Nevermind my comment. I see that your PoC supports passing nfds for any QMP command. I'm curious what Kevin's thoughts are on this and the overall approach. I'm not against introducing this nfd thing as a general feature for QMP commands instead of a separate pass-fd command. It's not obvious to me that everyone would agree with that, so let's CC Luiz at least. The that I'm unsure about is what we should do with qemu reopening the file. If you close the fd immediately, you obviously can't do that any more. Even worse, libvirt doesn't have a unique ID for each passed file descriptor any more, so even though we have introduced a QMP feature for file descriptor passing, we would still need to touch all commands to allow assigning a new fd. I think having one stable original fd that libvirt can refer to is much nicer. Kevin
Re: [Qemu-devel] [RFC] block: Removed coroutine ownership assumption
Am 22.06.2012 12:59, schrieb Peter Crosthwaite: On Fri, Jun 22, 2012 at 6:53 PM, Kevin Wolf kw...@redhat.com wrote: Am 22.06.2012 10:20, schrieb Peter Crosthwaite: [...] I thought that was the point of coroutines vs threads? coroutines you control yield behaviour explicitly whearas thread you cant? Well, I can see your point, although today no code in qemu makes use of the property that the caller could in theory know where the coroutine yields. I think it's also dangerous because there is a non-obvious dependency of the caller on the internals of the coroutine. A simple innocent looking refactoring of the coroutine might break assumptions that are made here. Other code in qemu that uses coroutines only makes use of the fact that coroutines can only be interrupted at known points, So within the block layer, will the block coroutines yield anywhere or only at a qemu_coroutine_yield() site? Would the block layer break if a couroutine could be pre-empted by the OS anywhere? So lets continue this to an example of multiple clients of qemu-coroutine. The block layer is one client. It defines three possible yields points (qemu_co_yield() sites) in block.c. Lets call them A,B and C. The co-routine policy is that your thread of control will not be pre-empted until locations A, B or C are reached (I.E. coroutines can only be interrupted at known points). Alls fair and it works. Now here is where it breaks. I have a device or machine model or whatever (lets call it foo) that uses co-routines. It decides that it wants its coroutines to stop at only at points D,E and F for ease of synchronization. If those coroutines however make calls into to the block layer, the block layer will think its in its own co-routine and potentially yield at any of points A,B and C. Thing is, my foo system doesn't care about the block layer implementation, so it shouldnt have awareness of the fact it used co-routines too. But because it talks to block, it can get yielded as any call into the block API which is awkward considering the point of coroutines is they can only be interrupted at known points. You have essentially defeated the purpose or coroutines in the first place. Foo's coroutines are behaving like preemptible threads (while blocks are behaving like coroutines). [snip] Maybe I'm misunderstanding the discussion, but there's three coroutine implementations, including one based on GThread. So in that case any coroutine can be preempted anywhere and there are no such guarantees as discussed here, are there? Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Re: [Qemu-devel] [RFC] block: Removed coroutine ownership assumption
On 27 June 2012 10:10, Andreas Färber afaer...@suse.de wrote: Maybe I'm misunderstanding the discussion, but there's three coroutine implementations, including one based on GThread. So in that case any coroutine can be preempted anywhere and there are no such guarantees as discussed here, are there? No, because the gthread-based implementation carefully ensures that it's only actually allowing one thread to execute at once: qemu_coroutine_switch() will make the calling thread block until some other coroutine switches back to it. Any failure to enforce the coroutine yield semantics would be a bug (and an indication of why having three separate backends is a bad idea :-)) -- PMM
Re: [Qemu-devel] [PATCH v4 0/7] file descriptor passing using pass-fd
Am 27.06.2012 00:54, schrieb Eric Blake: It seems like libvirt would be in a better position to understand when a file is no longer in use, and then it can call close_fd. No? Of course the the only fd that needs to be closed is the originally passed fd. The dup'd fd's are closed by QEMU. The more we discuss this, the more I'm convinced that commands like 'block-commit' that will reopen a file to change from O_RDONLY to O_RDWR will need to have an optional argument that says the name of the file to reopen. That is, I've seen three proposals: Thanks for the summary. In fact, after having read this, I start thinking that we're oversimplifying things because we're only thinking about one use case, block-commit. There are more: Live snapshot doesn't only put a new image on top, it must also make the old top-level image read-only. This isn't bad per se, but it shows that QMP commands can easily become bloated if you decide to change every command. The really bad case that nobody thought of is that, when block-commit has finished, we need to switch back to read-only. This is an event that is not triggered by a certain monitor command, but that comes from inside qemu. I'm almost sure that we'll see more of this as we add more asynchronous commands. This only works if we can pass the new file descriptor in advance. It would work nicely if you go with pass-fd and actually maintain a list of file descriptors for each /dev/fd/N, along with the different flags the file descriptors are meant for. I can't see how it would work with the temporary /dev/fdlist/N or the fd:name approach because they both imply that the original file descriptors are closed by the time that the QMP command returns. Kevin
Re: [Qemu-devel] [PATCH 1/4] dump: create writable files
At 06/27/2012 04:27 AM, Luiz Capitulino Wrote: On Wed, 20 Jun 2012 22:58:20 +0530 Rabin Vincent ra...@rab.in wrote: Make dump-guest-memory not create read-only files, so that it can overwrite a file created by a previous invocation without having it to be removed externally. I think we need a force parameter to do this, the command shouldn't overwrite files by default. Wen, can you review this series please? OK, I will review it after some days. Thanks Wen Congyang Signed-off-by: Rabin Vincent ra...@rab.in --- dump.c |3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dump.c b/dump.c index 2bf8d8d..5c5cb4d 100644 --- a/dump.c +++ b/dump.c @@ -845,7 +845,8 @@ void qmp_dump_guest_memory(bool paging, const char *file, bool has_begin, #endif if (strstart(file, file:, p)) { -fd = qemu_open(p, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR); +fd = qemu_open(p, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, + S_IRUSR | S_IWUSR); if (fd 0) { error_set(errp, QERR_OPEN_FILE_FAILED, p); return;
Re: [Qemu-devel] [PATCH v4 0/7] file descriptor passing using pass-fd
On Wed, Jun 27, 2012 at 11:16:32AM +0200, Kevin Wolf wrote: Am 27.06.2012 00:54, schrieb Eric Blake: It seems like libvirt would be in a better position to understand when a file is no longer in use, and then it can call close_fd. No? Of course the the only fd that needs to be closed is the originally passed fd. The dup'd fd's are closed by QEMU. The more we discuss this, the more I'm convinced that commands like 'block-commit' that will reopen a file to change from O_RDONLY to O_RDWR will need to have an optional argument that says the name of the file to reopen. That is, I've seen three proposals: Thanks for the summary. In fact, after having read this, I start thinking that we're oversimplifying things because we're only thinking about one use case, block-commit. There are more: Live snapshot doesn't only put a new image on top, it must also make the old top-level image read-only. This isn't bad per se, but it shows that QMP commands can easily become bloated if you decide to change every command. The really bad case that nobody thought of is that, when block-commit has finished, we need to switch back to read-only. This is an event that is not triggered by a certain monitor command, but that comes from inside qemu. I'm almost sure that we'll see more of this as we add more asynchronous commands. This only works if we can pass the new file descriptor in advance. It would work nicely if you go with pass-fd and actually maintain a list of file descriptors for each /dev/fd/N, along with the different flags the file descriptors are meant for. I can't see how it would work with the temporary /dev/fdlist/N or the fd:name approach because they both imply that the original file descriptors are closed by the time that the QMP command returns. What I don't understand though is that when you're reopening FDs, with the pass-fd command approach, you're merely dup'ing the original FDs that was passed in from the client. Why can't you alternatively just dup the FD you already have. I don't see why we need to keep the original FD around forever. If the QMP command handler nees the temporary /dev/fdlist/N file to exist for longer than the duration of the command, it can simply dup() it to get a permanent copy of its own. Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
Re: [Qemu-devel] [RFC] block: Removed coroutine ownership assumption
On Wed, Jun 27, 2012 at 6:33 PM, Markus Armbruster arm...@redhat.com wrote: Stefan Hajnoczi stefa...@gmail.com writes: On Wed, Jun 27, 2012 at 8:59 AM, Peter Maydell peter.mayd...@linaro.org wrote: On 27 June 2012 08:48, Stefan Hajnoczi stefa...@gmail.com wrote: I'd like to see your code though because I still don't understand why it relies on the exact yield behavior. Have you pushed it to a public git repo? I haven't seen Peter's code either, but his complaint makes sense to me -- the whole point of coroutines is that you can rely on the exact yield behaviour, surely. Not if you call coroutine_fn functions - these are explicitly marked as functions that yield. For example block or net I/O. Thats what I mean by assuming ownership of coroutines. If block marks half its API as coroutine_fn, then essentially you are saying block is mutually exclusive with other users of coroutine. Is it really that hard for the block layer to keep track of its own little collection of coroutines and just check that it owns the current context before taking the fast path? I think you two are in violent agreement :) With coroutines, you can rely on the exact yield behavior. Of course, that doesn't do you any good unless you know which functions can yield. We make that easy by giving such functions distinctive names. That brings a new problem, best illustrated by example. Suppose I ensure myself against yielding something like this: foo(void *opaque) { bdrv_foo(...); //this may yield! *((int*)opaque)++; //state++ /* some coroutine behaviour */ } from my device int state = 0; foo_co = qemu_couroutine_new(foo_fn); qemu_coroutine_enter(foo_co, state); while (state 1) { qemu_coroutined_enter(foo_co); } ... /* the other half of some coroutine behvaiour */ I have insured myself against bdrv_yielding by renentering it if im not at a valid yield point. But whats really wrong here is the block layer will be making assumption on re-entry of the coroutine, so I cant re-enter it witout wildly changing the behaviour of the block layer. If you adopt this mark it as coroutine poilcy, you end up with a system where half the functions in QEMU: A: may yield your coroutine B: if it does yield it, your not allowed to restart it Making them completely uncallable from coroutine context. Except when we don't: The issue here is that there are some block.h functions that are not marked coroutine_fn but actually yield if running inside coroutine context. I think we could get rid of them with a little bit of work. Sounds like a good idea.
[Qemu-devel] [Bug 1013714] Re: Data corruption after block migration (LV-LV)
Hello Paolo, We backported most of the block migration fixes from upstream to the RHEL6 qemu-kvm package ourselves and are now unable to reproduce the disk corruption problem anymore. So I guess the issues are (mostly) fixed upstream. You can close this bug, but I would still appreciate it if you could fix this in the RHEL6 package (other RH customers might appreciate that as well ;). We could even provide the patches if you like. -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1013714 Title: Data corruption after block migration (LV-LV) Status in QEMU: New Bug description: We quite frequently use the live block migration feature to move VM's between nodes without downtime. These sometimes result in data corruption on the receiving end. It only happens if the VM is actually doing I/O (doesn't have to be all that much to trigger the issue). We use logical volumes and each VM has two disks. We use cache=none for all VM disks. All guests use virtio (a mix of various Linux distro's and Windows 2008R2). We currently have two stacks in use and have seen the issue on both of them: Fedora - qemu-kvm 0.13 Scientific Linux 6.2 (RHEL derived) - qemu-kvm package 0.12.1.2 Even though we don't run the most recent versions of KVM I highly suspect this issue is still unreported and that filing a bug is therefore appropriate. (There doesn't seem to be any similar bug report in launchpad or RedHat's bugzilla and nothing related in change logs, release notes and git commit logs.) I have no idea where to look or where to start debugging this issue, but if there is any way I can provide useful debug information please let me know. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1013714/+subscriptions
Re: [Qemu-devel] [PATCH v4 0/7] file descriptor passing using pass-fd
Am 27.06.2012 11:20, schrieb Daniel P. Berrange: On Wed, Jun 27, 2012 at 11:16:32AM +0200, Kevin Wolf wrote: The really bad case that nobody thought of is that, when block-commit has finished, we need to switch back to read-only. This is an event that is not triggered by a certain monitor command, but that comes from inside qemu. I'm almost sure that we'll see more of this as we add more asynchronous commands. This only works if we can pass the new file descriptor in advance. It would work nicely if you go with pass-fd and actually maintain a list of file descriptors for each /dev/fd/N, along with the different flags the file descriptors are meant for. I can't see how it would work with the temporary /dev/fdlist/N or the fd:name approach because they both imply that the original file descriptors are closed by the time that the QMP command returns. What I don't understand though is that when you're reopening FDs, with the pass-fd command approach, you're merely dup'ing the original FDs that was passed in from the client. Why can't you alternatively just dup the FD you already have. That's easy: Because I don't know that I'm dealing with an FD. I think originally the whole point in this /dev/fd/ thing was that it would transparently enable the functionality for all parts of qemu: The block layer, of course, but also new char devices, migration targets, screenshot files or whatever else can deal with files. In this design the block layer doesn't even know that it's not a regular file. If we now decided to go for a design where the /dev/fd path isn't enough, but changes are needed to each subsystem where it should work, then this point doesn't apply any more and I cast my vote for abandoning everything starting with /dev/ and introducing a proper fd: protocol in the block layer, so that the block layer at least has a chance to know that it has to do treat this file specially. I don't see why we need to keep the original FD around forever. If the QMP command handler nees the temporary /dev/fdlist/N file to exist for longer than the duration of the command, it can simply dup() it to get a permanent copy of its own. If we're not going to make it transparent and if we don't care about QMP command bloat, we can choose completely different designs, yes. And then qemu could probably try to internally work around a suboptimal API. Kevin
[Qemu-devel] [PATCH v7 00/16] QEMU OpenRISC support
This is the OpenCores OpenRISC 1200 support for QEMU. Full implementation of the system-model and linux-user-model support. OpenRISC 1200 is a OpenCores open source CPU, its architecture manual can be found at http://opencores.org/svnget,or1k?file=/trunk/docs/openrisc_arch.pdf A OpenRISC Linux kernel contain initramfs for qemu-system-or32 testing can be found at https://docs.google.com/file/d/0BxeTrz3x0CBLSjR3Sk5Vd3h1eDA/edit?pli=1 A OpenRISC hello-world program for qemu-or32 testing can be found at https://docs.google.com/file/d/0BxeTrz3x0CBLN3RSWUFNYktrU2M/edit?pli=1 Signed-off-by: Jia Liu pro...@gmail.com --- Version History: v7: Addressed Max's review comments: - fix l.div*. Addressed Peter's review comments: - fix load_kernel(). Addressed WeiRen's review comments: - fix typo, l.div and load_kernel(). V6: Addressed Blue's review comments: - reimplement l.mul* l.mfspr. - fix l.mtspr l.sub. - some English typo fix. - some coding style fix. Addressed Max's review comments: - replace NE2000 with OpenCores 10/100 ethernet adapter, thanks for his patch. V5: Addressed Blue's review comments: - reimplement l.mul* l.mtspr l.add* l.sub* and more. - shoot bugs with --enable-debug-tcg. V4: Addressed Max's review comments: - fix l.div l.mac* l.mul*, and more. Addressed Richard, Wei-Ren and Andreas's review comments: - replace tcg_temp_new_i32 with tcg_temp_local_new_i32 in l.div translation. Addressed Andreas's review comments: - update to suit Makefile system. - add UPR CPUCFGR and MMUCFGR impelement. - add instruction check functions. Version History: V3: Addressed Stefan and Andreas's review comments: - use QEMU and OpenRISC's official name. Addressed Andreas's review comments: - reimplement cpu QOM. - combine target stubs and QOM implement. - use new commit message and subject. Addressed Max's review comments: - handle div zero exception. - reimplement float point instructions. - fix l.mac*, l.mul*, and more. V2: Addressed Malc, Weiren, Andreas and Blue's review comments: - reimplement cpu QOM. Addressed Andreas's review comments: - reimplement machine. - rewrite the Copyright Notice using better format. Addressed Blue and Weiren's review comments: - compiling with AREG0 and remove global env, no dyngen-exe longer. Addressed Max, Blue and Weiren's review comments: - handle div zero exception. - handle illegal instruction. Addressed Blue's review comments: - separate do_interrupt into intrpt.c form intrpt_helper.c. - add QEMU_NORETURN to raise_exception. - reimplement float instrutions. - fix type of linux syscall and termbits. - reimplement sim board. - use the LGPL web URL in Copyright Notice. - reimplemt branch instructions. - split taregt stubs, QOM and machine. V1: - add QEMU OpenRISC support. - well tested on x64 machine, and final tested x86 machine. Jia Liu (16): target-or32: Add target stubs and cpu support target-or32: Add target machine target-or32: Add MMU support target-or32: Add interrupt support target-or32: Add exception support target-or32: Add int instruction helpers target-or32: Add float instruction helpers target-or32: Add instruction translation target-or32: Add PIC support target-or32: Add timer support target-or32: Add a IIS dummy board target-or32: Add system instructions target-or32: Add gdb stub target-or32: Add linux syscall, signal and termbits target-or32: Add linux user support target-or32: Add testcases arch_init.c |2 + arch_init.h |1 + configure | 15 +- cpu-exec.c | 19 + default-configs/or32-linux-user.mak |1 + default-configs/or32-softmmu.mak|4 + elf.h |2 + gdbstub.c | 64 ++ hw/openrisc/Makefile.objs |3 + hw/openrisc_cpudev.h| 29 + hw/openrisc_pic.c | 78 ++ hw/openrisc_sim.c | 149 +++ hw/openrisc_timer.c | 160 linux-user/elfload.c| 41 + linux-user/main.c | 100 ++ linux-user/openrisc/syscall.h | 24 + linux-user/openrisc/syscall_nr.h| 506 ++ linux-user/openrisc/target_signal.h | 26 + linux-user/openrisc/termbits.h | 294 ++ linux-user/signal.c | 229 + linux-user/syscall.c|2 +- linux-user/syscall_defs.h | 40 +- poison.h|1 + target-openrisc/Makefile.objs |4 + target-openrisc/cpu.c | 240 + target-openrisc/cpu.h | 449 + target-openrisc/excp.c | 27 + target-openrisc/excp.h | 28 + target-openrisc/excp_helper.c | 27 + target-openrisc/fpu_helper.c| 275 ++ target-openrisc/helper.h| 70 ++ target-openrisc/int_helper.c| 85 ++ target-openrisc/intrpt.c
[Qemu-devel] [PATCH v7 01/16] target-or32: Add target stubs and cpu support
Add OpenRISC target stubs and cpu support. Signed-off-by: Jia Liu pro...@gmail.com --- arch_init.c |2 + arch_init.h |1 + configure| 14 +- cpu-exec.c |2 + default-configs/or32-softmmu.mak |4 + elf.h|2 + hw/openrisc/Makefile.objs|3 + hw/openrisc_cpudev.h | 29 hw/openrisc_pic.c| 30 hw/openrisc_timer.c | 30 poison.h |1 + target-openrisc/Makefile.objs|3 + target-openrisc/cpu.c| 240 +++ target-openrisc/cpu.h| 292 ++ target-openrisc/intrpt.c | 30 target-openrisc/machine.c| 30 target-openrisc/mmu.c| 39 + target-openrisc/mmu_helper.c | 43 ++ target-openrisc/translate.c | 75 ++ 19 files changed, 868 insertions(+), 2 deletions(-) create mode 100644 default-configs/or32-softmmu.mak create mode 100644 hw/openrisc/Makefile.objs create mode 100644 hw/openrisc_cpudev.h create mode 100644 hw/openrisc_pic.c create mode 100644 hw/openrisc_timer.c create mode 100644 target-openrisc/Makefile.objs create mode 100644 target-openrisc/cpu.c create mode 100644 target-openrisc/cpu.h create mode 100644 target-openrisc/intrpt.c create mode 100644 target-openrisc/machine.c create mode 100644 target-openrisc/mmu.c create mode 100644 target-openrisc/mmu_helper.c create mode 100644 target-openrisc/translate.c diff --git a/arch_init.c b/arch_init.c index a9e8b74..4b521e5 100644 --- a/arch_init.c +++ b/arch_init.c @@ -71,6 +71,8 @@ int graphic_depth = 15; #define QEMU_ARCH QEMU_ARCH_MICROBLAZE #elif defined(TARGET_MIPS) #define QEMU_ARCH QEMU_ARCH_MIPS +#elif defined(TARGET_OPENRISC) +#define QEMU_ARCH QEMU_ARCH_OPENRISC #elif defined(TARGET_PPC) #define QEMU_ARCH QEMU_ARCH_PPC #elif defined(TARGET_S390X) diff --git a/arch_init.h b/arch_init.h index c7cb94a..3dfea3b 100644 --- a/arch_init.h +++ b/arch_init.h @@ -16,6 +16,7 @@ enum { QEMU_ARCH_SH4 = 1024, QEMU_ARCH_SPARC = 2048, QEMU_ARCH_XTENSA = 4096, +QEMU_ARCH_OPENRISC = 8192, }; extern const uint32_t arch_type; diff --git a/configure b/configure index 37faee4..166a854 100755 --- a/configure +++ b/configure @@ -929,6 +929,7 @@ mips-softmmu \ mipsel-softmmu \ mips64-softmmu \ mips64el-softmmu \ +or32-softmmu \ ppc-softmmu \ ppcemb-softmmu \ ppc64-softmmu \ @@ -3511,7 +3512,7 @@ target_arch2=`echo $target | cut -d '-' -f 1` target_bigendian=no case $target_arch2 in - armeb|lm32|m68k|microblaze|mips|mipsn32|mips64|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb) + armeb|lm32|m68k|microblaze|mips|mipsn32|mips64|or32|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb) target_bigendian=yes ;; esac @@ -3627,6 +3628,11 @@ case $target_arch2 in target_phys_bits=64 target_long_alignment=8 ;; + or32) +TARGET_ARCH=openrisc +TARGET_BASE_ARCH=openrisc +target_phys_bits=32 + ;; ppc) gdb_xml_files=power-core.xml power-fpu.xml power-altivec.xml power-spe.xml target_phys_bits=64 @@ -3705,7 +3711,7 @@ symlink $source_path/Makefile.target $target_dir/Makefile case $target_arch2 in - alpha | sparc* | xtensa* | ppc*) + alpha | or32 | sparc* | xtensa* | ppc*) echo CONFIG_TCG_PASS_AREG0=y $config_target_mak ;; esac @@ -3879,6 +3885,10 @@ for i in $ARCH $TARGET_BASE_ARCH ; do echo CONFIG_MIPS_DIS=y $config_target_mak echo CONFIG_MIPS_DIS=y $libdis_config_mak ;; + or32) +echo CONFIG_OPENRISC_DIS=y $config_target_mak +echo CONFIG_OPENRISC_DIS=y $libdis_config_mak + ;; ppc*) echo CONFIG_PPC_DIS=y $config_target_mak echo CONFIG_PPC_DIS=y $libdis_config_mak diff --git a/cpu-exec.c b/cpu-exec.c index 624c409..7d0d87b 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -225,6 +225,7 @@ int cpu_exec(CPUArchState *env) #elif defined(TARGET_LM32) #elif defined(TARGET_MICROBLAZE) #elif defined(TARGET_MIPS) +#elif defined(TARGET_OPENRISC) #elif defined(TARGET_SH4) #elif defined(TARGET_CRIS) #elif defined(TARGET_S390X) @@ -630,6 +631,7 @@ int cpu_exec(CPUArchState *env) | env-cc_dest | (env-cc_x 4); #elif defined(TARGET_MICROBLAZE) #elif defined(TARGET_MIPS) +#elif defined(TARGET_OPENRISC) #elif defined(TARGET_SH4) #elif defined(TARGET_ALPHA) #elif defined(TARGET_CRIS) diff --git a/default-configs/or32-softmmu.mak b/default-configs/or32-softmmu.mak new file mode 100644 index 000..cce4746 --- /dev/null +++ b/default-configs/or32-softmmu.mak @@ -0,0 +1,4 @@ +# Default configuration for or32-softmmu + +CONFIG_SERIAL=y +CONFIG_OPENCORES_ETH=y diff --git a/elf.h b/elf.h index 9c9acfa..a21ea53 100644 --- a/elf.h +++ b/elf.h @@ -106,6 +106,8 @@ typedef int64_t
[Qemu-devel] [PATCH v7 03/16] target-or32: Add MMU support
Add OpenRISC MMU support. Signed-off-by: Jia Liu pro...@gmail.com --- target-openrisc/cpu.h| 75 +++- target-openrisc/mmu.c| 199 +- target-openrisc/mmu_helper.c | 20 + 3 files changed, 292 insertions(+), 2 deletions(-) diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h index 58c8081..dbb3f17 100644 --- a/target-openrisc/cpu.h +++ b/target-openrisc/cpu.h @@ -43,6 +43,12 @@ struct CPUOpenRISCState; #define NB_MMU_MODES3 +enum { +MMU_NOMMU_IDX = 0, +MMU_SUPERVISOR_IDX = 1, +MMU_USER_IDX = 2, +}; + #define TARGET_PAGE_BITS 13 #define TARGET_PHYS_ADDR_SPACE_BITS 32 @@ -206,6 +212,54 @@ enum { TTMR_M = (3 30), }; +/* TLB size */ +enum { +DTLB_WAYS = 1, +DTLB_SIZE = 64, +DTLB_MASK = (DTLB_SIZE-1), +ITLB_WAYS = 1, +ITLB_SIZE = 64, +ITLB_MASK = (ITLB_SIZE-1), +}; + +/* TLB prot */ +enum { +URE = (1 6), +UWE = (1 7), +SRE = (1 8), +SWE = (1 9), + +SXE = (1 6), +UXE = (1 7), +}; + +/* check if tlb available */ +enum { +TLBRET_INVALID = -3, +TLBRET_NOMATCH = -2, +TLBRET_BADADDR = -1, +TLBRET_MATCH = 0 +}; + +typedef struct OpenRISCTLBEntry { +uint32_t mr; +uint32_t tr; +} OpenRISCTLBEntry; + +#ifndef CONFIG_USER_ONLY +typedef struct CPUOpenRISCTLBContext { +OpenRISCTLBEntry itlb[ITLB_WAYS][ITLB_SIZE]; +OpenRISCTLBEntry dtlb[DTLB_WAYS][DTLB_SIZE]; + +int (*map_address_code)(struct CPUOpenRISCState *env, +target_phys_addr_t *physical, int *prot, +target_ulong address, int rw); +int (*map_address_data)(struct CPUOpenRISCState *env, +target_phys_addr_t *physical, int *prot, +target_ulong address, int rw); +} CPUOpenRISCTLBContext; +#endif + typedef struct CPUOpenRISCState CPUOpenRISCState; struct CPUOpenRISCState { target_ulong gpr[32]; /* General registers */ @@ -240,6 +294,8 @@ struct CPUOpenRISCState { CPU_COMMON #ifndef CONFIG_USER_ONLY +CPUOpenRISCTLBContext * tlb; + struct QEMUTimer *timer; uint32_t ttmr; /* Timer tick mode register */ uint32_t ttcr; /* Timer tick count register */ @@ -301,19 +357,33 @@ OpenRISCCPU *cpu_openrisc_init(const char *cpu_model); int cpu_openrisc_exec(CPUOpenRISCState *s); void do_interrupt(CPUOpenRISCState *env); void openrisc_translate_init(void); +int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env, target_ulong address, + int rw, int mmu_idx); #define cpu_list cpu_openrisc_list #define cpu_exec cpu_openrisc_exec #define cpu_gen_code cpu_openrisc_gen_code +#define cpu_handle_mmu_fault cpu_openrisc_handle_mmu_fault #define CPU_SAVE_VERSION 1 #ifndef CONFIG_USER_ONLY void cpu_openrisc_pic_reset(CPUOpenRISCState *env); +void cpu_openrisc_store_picsr(CPUOpenRISCState *env, uint32_t value); +void cpu_openrisc_store_picmr(CPUOpenRISCState *env, uint32_t value); void cpu_openrisc_timer_reset(CPUOpenRISCState *env); +void cpu_openrisc_store_count(CPUOpenRISCState *env, target_ulong count); +void cpu_openrisc_store_compare(CPUOpenRISCState *env, target_ulong value); +uint32_t cpu_openrisc_get_count(CPUOpenRISCState *env); void openrisc_mmu_init(CPUOpenRISCState *env); +int get_phys_nommu(CPUOpenRISCState *env, target_phys_addr_t *physical, + int *prot, target_ulong address, int rw); +int get_phys_code(CPUOpenRISCState *env, target_phys_addr_t *physical, + int *prot, target_ulong address, int rw); +int get_phys_data(CPUOpenRISCState *env, target_phys_addr_t *physical, + int *prot, target_ulong address, int rw); #endif static inline CPUOpenRISCState *cpu_init(const char *cpu_model) @@ -339,7 +409,10 @@ static inline void cpu_get_tb_cpu_state(CPUOpenRISCState *env, static inline int cpu_mmu_index(CPUOpenRISCState *env) { -return 0; +if (!(env-sr SR_IME)) { +return MMU_NOMMU_IDX; +} +return (env-sr SR_SM) == 0 ? MMU_USER_IDX : MMU_SUPERVISOR_IDX; } static inline bool cpu_has_work(CPUOpenRISCState *env) diff --git a/target-openrisc/mmu.c b/target-openrisc/mmu.c index cd82b7a..ecef2e1 100644 --- a/target-openrisc/mmu.c +++ b/target-openrisc/mmu.c @@ -27,13 +27,210 @@ #endif #ifndef CONFIG_USER_ONLY +int get_phys_nommu(CPUOpenRISCState *env, target_phys_addr_t *physical, + int *prot, target_ulong address, int rw) +{ +*physical = address; +*prot = PAGE_READ | PAGE_WRITE; +return TLBRET_MATCH; +} + +int get_phys_code(CPUOpenRISCState *env, target_phys_addr_t *physical, + int *prot, target_ulong address, int rw) +{ +int vpn = address TARGET_PAGE_BITS; +int idx = vpn ITLB_MASK; +int right = 0; + +if ((env-tlb-itlb[0][idx].mr TARGET_PAGE_BITS) != vpn) { +return TLBRET_NOMATCH; +} +if
[Qemu-devel] [PATCH v7 02/16] target-or32: Add target machine
Add OpenRISC machine. Signed-off-by: Jia Liu pro...@gmail.com --- target-openrisc/cpu.h | 67 - target-openrisc/machine.c | 22 ++- 2 files changed, 87 insertions(+), 2 deletions(-) diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h index 0b8e836..58c8081 100644 --- a/target-openrisc/cpu.h +++ b/target-openrisc/cpu.h @@ -48,6 +48,15 @@ struct CPUOpenRISCState; #define TARGET_PHYS_ADDR_SPACE_BITS 32 #define TARGET_VIRT_ADDR_SPACE_BITS 32 +#define SET_FP_CAUSE(reg, v)do {\ +(reg) = ((reg) ~(0x3f 12)) | \ +((v 0x3f) 12);\ +} while (0) +#define GET_FP_ENABLE(reg) (((reg) 7) 0x1f) +#define UPDATE_FP_FLAGS(reg, v) do {\ + (reg) |= ((v 0x1f) 2);\ + } while (0) + /* Internal flags, delay slot flag */ #define D_FLAG1 @@ -121,6 +130,40 @@ enum { IMMUCFGR_HTR = (1 11), }; +/* Float point control status register */ +enum { +FPCSR_FPEE = 1, +FPCSR_RM = (3 1), +FPCSR_OVF = (1 3), +FPCSR_UNF = (1 4), +FPCSR_SNF = (1 5), +FPCSR_QNF = (1 6), +FPCSR_ZF = (1 7), +FPCSR_IXF = (1 8), +FPCSR_IVF = (1 9), +FPCSR_INF = (1 10), +FPCSR_DZF = (1 11), +}; + +/* Exceptions indices */ +enum { +EXCP_RESET= 0x1, +EXCP_BUSERR = 0x2, +EXCP_DPF = 0x3, +EXCP_IPF = 0x4, +EXCP_TICK = 0x5, +EXCP_ALIGN= 0x6, +EXCP_ILLEGAL = 0x7, +EXCP_INT = 0x8, +EXCP_DTLBMISS = 0x9, +EXCP_ITLBMISS = 0xa, +EXCP_RANGE= 0xb, +EXCP_SYSCALL = 0xc, +EXCP_FPE = 0xd, +EXCP_TRAP = 0xe, +EXCP_NR, +}; + /* Supervisor register */ enum { SR_SM = 1, @@ -155,6 +198,14 @@ enum { OPENRISC_FEATURE_OR1200, }; +/* Tick Timer Mode Register */ +enum { +TTMR_TP = (0xfff), +TTMR_IP = (1 28), +TTMR_IE = (1 29), +TTMR_M = (3 30), +}; + typedef struct CPUOpenRISCState CPUOpenRISCState; struct CPUOpenRISCState { target_ulong gpr[32]; /* General registers */ @@ -163,12 +214,25 @@ struct CPUOpenRISCState { target_ulong ppc; /* Prev PC */ target_ulong jmp_pc; /* Jump PC */ +target_ulong machi; /* Multiply register MACHI */ +target_ulong maclo; /* Multiply register MACLO */ + +target_ulong fpmaddhi;/* Multiply and add float register FPMADDHI */ +target_ulong fpmaddlo;/* Multiply and add float register FPMADDLO */ + +target_ulong epcr;/* Exception PC register */ +target_ulong eear;/* Exception EA register */ + uint32_t sr; /* Supervisor register */ uint32_t vr; /* Version register */ uint32_t upr; /* Unit presence register */ uint32_t cpucfgr; /* CPU configure register */ uint32_t dmmucfgr;/* DMMU configure register */ uint32_t immucfgr;/* IMMU configure register */ +uint32_t esr; /* Exception supervisor register */ +uint32_t fpcsr; /* Float register */ +float_status fp_status; + uint32_t flags; /* cpu_flags, we only use it for exception in solt so far. */ uint32_t btaken; /* the SR_F bit */ @@ -269,7 +333,8 @@ static inline void cpu_get_tb_cpu_state(CPUOpenRISCState *env, { *pc = env-pc; *cs_base = 0; -*flags = 0; +/* D_FLAG -- branch instruction exception */ +*flags = (env-flags D_FLAG); } static inline int cpu_mmu_index(CPUOpenRISCState *env) diff --git a/target-openrisc/machine.c b/target-openrisc/machine.c index 11bf275..e5d59a7 100644 --- a/target-openrisc/machine.c +++ b/target-openrisc/machine.c @@ -20,11 +20,31 @@ #include hw/hw.h #include hw/boards.h +static const VMStateDescription vmstate_cpu = { +.name = cpu, +.version_id = CPU_SAVE_VERSION, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField[]) { +VMSTATE_UINT32_ARRAY(gpr, CPUOpenRISCState, 32), +VMSTATE_UINT32(sr, CPUOpenRISCState), +VMSTATE_UINT32(epcr, CPUOpenRISCState), +VMSTATE_UINT32(eear, CPUOpenRISCState), +VMSTATE_UINT32(esr, CPUOpenRISCState), +VMSTATE_UINT32(fpcsr, CPUOpenRISCState), +VMSTATE_UINT32(pc, CPUOpenRISCState), +VMSTATE_UINT32(npc, CPUOpenRISCState), +VMSTATE_UINT32(ppc, CPUOpenRISCState), +VMSTATE_END_OF_LIST() +} +}; + void cpu_save(QEMUFile *f, void *opaque) { +vmstate_save_state(f, vmstate_cpu, opaque); } int cpu_load(QEMUFile *f, void *opaque, int version_id) { -return 0; +return vmstate_load_state(f, vmstate_cpu, opaque, version_id); } -- 1.7.9.5
[Qemu-devel] [PATCH v7 05/16] target-or32: Add exception support
Add OpenRISC exception support. Signed-off-by: Jia Liu pro...@gmail.com --- target-openrisc/Makefile.objs |4 ++-- target-openrisc/excp.c| 27 +++ target-openrisc/excp.h| 28 target-openrisc/excp_helper.c | 27 +++ target-openrisc/helper.h |3 +++ 5 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 target-openrisc/excp.c create mode 100644 target-openrisc/excp.h create mode 100644 target-openrisc/excp_helper.c diff --git a/target-openrisc/Makefile.objs b/target-openrisc/Makefile.objs index 65f9391..382190a 100644 --- a/target-openrisc/Makefile.objs +++ b/target-openrisc/Makefile.objs @@ -1,3 +1,3 @@ obj-$(CONFIG_SOFTMMU) += machine.o -obj-y += cpu.o intrpt.o mmu.o translate.o -obj-y += intrpt_helper.o mmu_helper.o +obj-y += cpu.o excp.o intrpt.o mmu.o translate.o +obj-y += excp_helper.o intrpt_helper.o mmu_helper.o diff --git a/target-openrisc/excp.c b/target-openrisc/excp.c new file mode 100644 index 000..6d8c5dd --- /dev/null +++ b/target-openrisc/excp.c @@ -0,0 +1,27 @@ +/* + * OpenRISC exception. + * + * Copyright (c) 2011-2012 Jia Liu pro...@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see http://www.gnu.org/licenses/. + */ + +#include cpu.h +#include excp.h + +void QEMU_NORETURN raise_exception(CPUOpenRISCState *env, uint32_t excp) +{ +env-exception_index = excp; +cpu_loop_exit(env); +} diff --git a/target-openrisc/excp.h b/target-openrisc/excp.h new file mode 100644 index 000..885203b --- /dev/null +++ b/target-openrisc/excp.h @@ -0,0 +1,28 @@ +/* + * OpenRISC exception header. + * + * Copyright (c) 2011-2012 Jia Liu pro...@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see http://www.gnu.org/licenses/. + */ + +#ifndef QEMU_OPENRISC_EXCP_H +#define QEMU_OPENRISC_EXCP_H + +#include cpu.h +#include qemu-common.h + +void QEMU_NORETURN raise_exception(CPUOpenRISCState *env, uint32_t excp); + +#endif /* QEMU_OPENRISC_EXCP_H */ diff --git a/target-openrisc/excp_helper.c b/target-openrisc/excp_helper.c new file mode 100644 index 000..c7d4110 --- /dev/null +++ b/target-openrisc/excp_helper.c @@ -0,0 +1,27 @@ +/* + * OpenRISC exception helper routines + * + * Copyright (c) 2011-2012 Jia Liu pro...@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see http://www.gnu.org/licenses/. + */ + +#include cpu.h +#include helper.h +#include excp.h + +void HELPER(exception)(CPUOpenRISCState *env, uint32_t excp) +{ +raise_exception(env, excp); +} diff --git a/target-openrisc/helper.h b/target-openrisc/helper.h index 16d99b6..4e2a49f 100644 --- a/target-openrisc/helper.h +++ b/target-openrisc/helper.h @@ -19,6 +19,9 @@ #include def-helper.h +/* exception */ +DEF_HELPER_FLAGS_2(exception, 0, void, env, i32) + /* interrupt */ DEF_HELPER_FLAGS_1(rfe, 0, void, env) -- 1.7.9.5
[Qemu-devel] [PATCH v7 11/16] target-or32: Add a IIS dummy board
Add a IIS dummy board. Signed-off-by: Jia Liu pro...@gmail.com --- hw/openrisc/Makefile.objs |2 +- hw/openrisc_sim.c | 149 + 2 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 hw/openrisc_sim.c diff --git a/hw/openrisc/Makefile.objs b/hw/openrisc/Makefile.objs index 1c541a5..38ff8f5 100644 --- a/hw/openrisc/Makefile.objs +++ b/hw/openrisc/Makefile.objs @@ -1,3 +1,3 @@ -obj-y = openrisc_pic.o openrisc_timer.o +obj-y = openrisc_pic.o openrisc_sim.o openrisc_timer.o obj-y := $(addprefix ../,$(obj-y)) diff --git a/hw/openrisc_sim.c b/hw/openrisc_sim.c new file mode 100644 index 000..b0c1e69 --- /dev/null +++ b/hw/openrisc_sim.c @@ -0,0 +1,149 @@ +/* + * OpenRISC simulator for use as an IIS. + * + * Copyright (c) 2011-2012 Jia Liu pro...@gmail.com + * Feng Gao gf91...@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see http://www.gnu.org/licenses/. + */ + +#include hw.h +#include openrisc_cpudev.h +#include boards.h +#include elf.h +#include pc.h +#include loader.h +#include exec-memory.h +#include sysemu.h +#include sysbus.h +#include qtest.h + +#define KERNEL_LOAD_ADDR 0x100 + +static struct _loaderparams { +uint64_t ram_size; +const char *kernel_filename; +const char *kernel_cmdline; +const char *initrd_filename; +} loaderparams; + +static void main_cpu_reset(void *opaque) +{ +CPUOpenRISCState *env = opaque; +cpu_reset(ENV_GET_CPU(env)); +} + +static void openrisc_sim_net_init(MemoryRegion *address_space, + target_phys_addr_t base, + target_phys_addr_t descriptors, + qemu_irq irq, NICInfo *nd) +{ +DeviceState *dev; +SysBusDevice *s; + +dev = qdev_create(NULL, open_eth); +qdev_set_nic_properties(dev, nd); +qdev_init_nofail(dev); + +s = sysbus_from_qdev(dev); +sysbus_connect_irq(s, 0, irq); +memory_region_add_subregion(address_space, base, +sysbus_mmio_get_region(s, 0)); +memory_region_add_subregion(address_space, descriptors, +sysbus_mmio_get_region(s, 1)); +} + +static uint64_t openrisc_load_kernel(void) +{ +long kernel_size; +uint64_t elf_entry; +target_phys_addr_t entry; + +if (loaderparams.kernel_filename !qtest_enabled()) { +kernel_size = load_uimage(loaderparams.kernel_filename, + entry, NULL, NULL); +if (kernel_size 0) { +kernel_size = load_elf(loaderparams.kernel_filename, NULL, NULL, + elf_entry, NULL, NULL, 1, ELF_MACHINE, 1); +entry = elf_entry; +} + +if (kernel_size 0) { +fprintf(stderr, QEMU: couldn't load the kernel '%s'\n, +loaderparams.kernel_filename); +exit(1); +} +} + +return entry; +} + +static void openrisc_sim_init(ram_addr_t ram_size, + const char *boot_device, + const char *kernel_filename, + const char *kernel_cmdline, + const char *initrd_filename, + const char *cpu_model) +{ +CPUOpenRISCState *env; +MemoryRegion *ram = g_new(MemoryRegion, 1); + +if (!cpu_model) { +cpu_model = or1200; +} +env = cpu_init(cpu_model); +if (!env) { +fprintf(stderr, Unable to find CPU definition!\n); +exit(1); +} + +qemu_register_reset(main_cpu_reset, env); +main_cpu_reset(env); + +memory_region_init_ram(ram, openrisc.ram, ram_size); +memory_region_add_subregion(get_system_memory(), 0, ram); + +if (kernel_filename) { +loaderparams.ram_size = ram_size; +loaderparams.kernel_filename = kernel_filename; +loaderparams.kernel_cmdline = kernel_cmdline; +env-pc = openrisc_load_kernel(); +} + +cpu_openrisc_pic_init(env); +cpu_openrisc_clock_init(env); + +serial_mm_init(get_system_memory(), 0x9000, 0, + env-irq[2], 115200, serial_hds[0], DEVICE_NATIVE_ENDIAN); + +if (nd_table[0].vlan) { +openrisc_sim_net_init(get_system_memory(), 0x9200, + 0x92000400, env-irq[4],
Re: [Qemu-devel] [PATCH v3 5/6] qapi: convert sendkey
On 27/06/12 04:22, Luiz Capitulino wrote: On Wed, 20 Jun 2012 06:53:40 -0600 Eric Blakeebl...@redhat.com wrote: On 06/19/2012 10:47 PM, Amos Kong wrote: Convert 'sendkey' to use QAPI. do_sendkey() depends on some variables/functions in monitor.c, so reserve qmp_sendkey() to monitor.c key_defs[] in monitor.c is the mapping of key name to keycode, Keys' order in the enmu and key_defs[] is same. The interface looks like we have settled into something useful that libvirt can live with. I will leave a more thorough review of the series to those more familiar with qemu's internals. However, as long as we are fine-tuning things, I have some questions that might be worth one more spin: +## +# @sendkey: Should this be named 'send-key', given that most QMP commands separate words with '-' rather than squasheverythingtogether? Yes, that's right. still use sendkey for hmp ? +SQMP +sendkey +-- + +Send keys to VM. + +Arguments: + +keys array: +- key: key sequence (json-string) I'm not sure if json-string is the right designation any more. Rather, it is a json-array of key enum values. The content in brackets should be the description of key, which is the item of array. I think jaso-string is better. It's not the description for while array. + +- hold-time: time to delay key up events, milliseconds (josn-int, optional) s/josn/json/ Thanks. -- Amos.
Re: [Qemu-devel] [RFC] block: Removed coroutine ownership assumption
On Wed, Jun 27, 2012 at 10:25 AM, Peter Crosthwaite peter.crosthwa...@petalogix.com wrote: On Wed, Jun 27, 2012 at 6:33 PM, Markus Armbruster arm...@redhat.com wrote: Stefan Hajnoczi stefa...@gmail.com writes: On Wed, Jun 27, 2012 at 8:59 AM, Peter Maydell peter.mayd...@linaro.org wrote: On 27 June 2012 08:48, Stefan Hajnoczi stefa...@gmail.com wrote: I'd like to see your code though because I still don't understand why it relies on the exact yield behavior. Have you pushed it to a public git repo? I haven't seen Peter's code either, but his complaint makes sense to me -- the whole point of coroutines is that you can rely on the exact yield behaviour, surely. Not if you call coroutine_fn functions - these are explicitly marked as functions that yield. For example block or net I/O. Thats what I mean by assuming ownership of coroutines. If block marks half its API as coroutine_fn, then essentially you are saying block is mutually exclusive with other users of coroutine. Is it really that hard for the block layer to keep track of its own little collection of coroutines and just check that it owns the current context before taking the fast path? I think you two are in violent agreement :) With coroutines, you can rely on the exact yield behavior. Of course, that doesn't do you any good unless you know which functions can yield. We make that easy by giving such functions distinctive names. That brings a new problem, best illustrated by example. Suppose I ensure myself against yielding something like this: foo(void *opaque) { bdrv_foo(...); //this may yield! *((int*)opaque)++; //state++ /* some coroutine behaviour */ } from my device int state = 0; foo_co = qemu_couroutine_new(foo_fn); qemu_coroutine_enter(foo_co, state); while (state 1) { qemu_coroutined_enter(foo_co); } ... /* the other half of some coroutine behvaiour */ I have insured myself against bdrv_yielding by renentering it if im not at a valid yield point. But whats really wrong here is the block layer will be making assumption on re-entry of the coroutine, so I cant re-enter it witout wildly changing the behaviour of the block layer. If you adopt this mark it as coroutine poilcy, you end up with a system where half the functions in QEMU: A: may yield your coroutine B: if it does yield it, your not allowed to restart it Making them completely uncallable from coroutine context. Please link to real code, I'm having trouble understanding the example code and your argument. Stefan
Re: [Qemu-devel] [PATCH v2 0/3] Microblaze and Device Tree Maintainerships
On Tue, Jun 26, 2012 at 02:29:39PM +1000, Peter A. G. Crosthwaite wrote: Set some missing maintainer ships. Patch 1 is the Petalogix ML605 machine model (me). Patch 2 is the Xilinx EDK device suite (me + Edgar). Patch 3 is the device tree subsystem (me + Alex). Applied, Thanks! Changed since v1: Added Alexs ack for p3. Peter A. G. Crosthwaite (3): MAINTAINERS: Add Petalogix ml605 machine model MAINTAINERS: Added Xilinx EDK devices MAINTAINERS: Added device tree MAINTAINERS | 22 ++ 1 files changed, 22 insertions(+), 0 deletions(-) -- 1.7.3.2
[Qemu-devel] [PATCH v7 07/16] target-or32: Add float instruction helpers
Add OpenRISC float instruction helpers. Signed-off-by: Jia Liu pro...@gmail.com --- target-openrisc/Makefile.objs |2 +- target-openrisc/fpu_helper.c | 275 + target-openrisc/helper.h | 33 + 3 files changed, 309 insertions(+), 1 deletion(-) create mode 100644 target-openrisc/fpu_helper.c diff --git a/target-openrisc/Makefile.objs b/target-openrisc/Makefile.objs index 4286462..0d72c33 100644 --- a/target-openrisc/Makefile.objs +++ b/target-openrisc/Makefile.objs @@ -1,3 +1,3 @@ obj-$(CONFIG_SOFTMMU) += machine.o obj-y += cpu.o excp.o intrpt.o mmu.o translate.o -obj-y += excp_helper.o int_helper.o intrpt_helper.o mmu_helper.o +obj-y += excp_helper.o fpu_helper.o int_helper.o intrpt_helper.o mmu_helper.o diff --git a/target-openrisc/fpu_helper.c b/target-openrisc/fpu_helper.c new file mode 100644 index 000..40f5857 --- /dev/null +++ b/target-openrisc/fpu_helper.c @@ -0,0 +1,275 @@ +/* + * OpenRISC float helper routines + * + * Copyright (c) 2011-2012 Jia Liu pro...@gmail.com + * Feng Gao gf91...@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see http://www.gnu.org/licenses/. + */ + +#include cpu.h +#include helper.h +#include excp.h + +static inline uint32_t ieee_ex_to_openrisc(CPUOpenRISCState *env, int fexcp) +{ +int ret = 0; +if (fexcp) { +if (fexcp float_flag_invalid) { +env-fpcsr |= FPCSR_IVF; +ret = 1; +} +if (fexcp float_flag_overflow) { +env-fpcsr |= FPCSR_OVF; +ret = 1; +} +if (fexcp float_flag_underflow) { +env-fpcsr |= FPCSR_UNF; +ret = 1; +} +if (fexcp float_flag_divbyzero) { +env-fpcsr |= FPCSR_DZF; +ret = 1; +} +if (fexcp float_flag_inexact) { +env-fpcsr |= FPCSR_IXF; +ret = 1; +} +} + +return ret; +} + +static inline void update_fpcsr(CPUOpenRISCState *env) +{ +int tmp = ieee_ex_to_openrisc(env, + get_float_exception_flags(env-fp_status)); + +SET_FP_CAUSE(env-fpcsr, tmp); +if ((GET_FP_ENABLE(env-fpcsr) tmp) (env-fpcsr FPCSR_FPEE)) { +helper_exception(env, EXCP_FPE); +} else { +UPDATE_FP_FLAGS(env-fpcsr, tmp); +} +} + +uint64_t HELPER(itofd)(CPUOpenRISCState *env, uint64_t val) +{ +uint64_t itofd; +set_float_exception_flags(0, env-fp_status); +itofd = int32_to_float64(val, env-fp_status); +update_fpcsr(env); +return itofd; +} + +uint32_t HELPER(itofs)(CPUOpenRISCState *env, uint32_t val) +{ +uint32_t itofs; +set_float_exception_flags(0, env-fp_status); +itofs = int32_to_float32(val, env-fp_status); +update_fpcsr(env); +return itofs; +} + +uint64_t HELPER(ftoid)(CPUOpenRISCState *env, uint64_t val) +{ +uint64_t ftoid; +set_float_exception_flags(0, env-fp_status); +ftoid = float32_to_int64(val, env-fp_status); +update_fpcsr(env); +return ftoid; +} + +uint32_t HELPER(ftois)(CPUOpenRISCState *env, uint32_t val) +{ +uint32_t ftois; +set_float_exception_flags(0, env-fp_status); +ftois = float32_to_int32(val, env-fp_status); +update_fpcsr(env); +return ftois; +} + +#define FLOAT_OP(name, p) void helper_float_##_##p(void) + +#define FLOAT_CALC(name) \ +uint64_t helper_float_ ## name ## _d(CPUOpenRISCState *env, \ + uint64_t fdt0, uint64_t fdt1)\ +{ \ +uint64_t result; \ +set_float_exception_flags(0, env-fp_status);\ +result = float64_ ## name(fdt0, fdt1, env-fp_status); \ +update_fpcsr(env);\ +return result;\ +} \ + \ +uint32_t helper_float_ ## name ## _s(CPUOpenRISCState *env, \ + uint32_t fdt0, uint32_t fdt1)\ +{
[Qemu-devel] [PATCH v7 04/16] target-or32: Add interrupt support
Add OpenRISC interrupt support. Signed-off-by: Jia Liu pro...@gmail.com --- cpu-exec.c | 17 + target-openrisc/Makefile.objs |2 +- target-openrisc/cpu.h |9 ++- target-openrisc/helper.h| 25 +++ target-openrisc/intrpt.c| 44 + target-openrisc/intrpt_helper.c | 52 +++ 6 files changed, 147 insertions(+), 2 deletions(-) create mode 100644 target-openrisc/helper.h create mode 100644 target-openrisc/intrpt_helper.c diff --git a/cpu-exec.c b/cpu-exec.c index 7d0d87b..1d2fe6b 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -378,6 +378,23 @@ int cpu_exec(CPUArchState *env) do_interrupt(env); next_tb = 0; } +#elif defined(TARGET_OPENRISC) +{ +int idx = -1; +if ((interrupt_request CPU_INTERRUPT_HARD) + (env-sr SR_IEE)) { +idx = EXCP_INT; +} +if ((interrupt_request CPU_INTERRUPT_TIMER) + (env-sr SR_TEE)) { +idx = EXCP_TICK; +} +if (idx = 0) { +env-exception_index = idx; +do_interrupt(env); +next_tb = 0; +} +} #elif defined(TARGET_SPARC) if (interrupt_request CPU_INTERRUPT_HARD) { if (cpu_interrupts_enabled(env) diff --git a/target-openrisc/Makefile.objs b/target-openrisc/Makefile.objs index 21b76b2..65f9391 100644 --- a/target-openrisc/Makefile.objs +++ b/target-openrisc/Makefile.objs @@ -1,3 +1,3 @@ obj-$(CONFIG_SOFTMMU) += machine.o obj-y += cpu.o intrpt.o mmu.o translate.o -obj-y += mmu_helper.o +obj-y += intrpt_helper.o mmu_helper.o diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h index dbb3f17..d499dc4 100644 --- a/target-openrisc/cpu.h +++ b/target-openrisc/cpu.h @@ -66,6 +66,10 @@ enum { /* Internal flags, delay slot flag */ #define D_FLAG1 +/* Interrupt */ +#define NR_IRQS 32 +#define PIC_MASK 0x + /* Verison Register */ #define SPR_VR 0x003F @@ -304,6 +308,7 @@ struct CPUOpenRISCState { uint32_t picsr; /* Interrupt contrl register*/ #endif uint32_t feature; /* CPU Capabilities */ +void *irq[32]; /* Interrupt irq input */ }; #define TYPE_OPENRISC_CPU or32-cpu @@ -415,9 +420,11 @@ static inline int cpu_mmu_index(CPUOpenRISCState *env) return (env-sr SR_SM) == 0 ? MMU_USER_IDX : MMU_SUPERVISOR_IDX; } +#define CPU_INTERRUPT_TIMER CPU_INTERRUPT_TGT_INT_0 static inline bool cpu_has_work(CPUOpenRISCState *env) { -return true; +return env-interrupt_request (CPU_INTERRUPT_HARD | + CPU_INTERRUPT_TIMER); } #include exec-all.h diff --git a/target-openrisc/helper.h b/target-openrisc/helper.h new file mode 100644 index 000..16d99b6 --- /dev/null +++ b/target-openrisc/helper.h @@ -0,0 +1,25 @@ +/* + * OpenRISC helper defines + * + * Copyright (c) 2011-2012 Jia Liu pro...@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see http://www.gnu.org/licenses/. + */ + +#include def-helper.h + +/* interrupt */ +DEF_HELPER_FLAGS_1(rfe, 0, void, env) + +#include def-helper.h diff --git a/target-openrisc/intrpt.c b/target-openrisc/intrpt.c index a3bb7f8..9b02618 100644 --- a/target-openrisc/intrpt.c +++ b/target-openrisc/intrpt.c @@ -27,4 +27,48 @@ void do_interrupt(CPUOpenRISCState *env) { +#ifndef CONFIG_USER_ONLY +if (env-flags D_FLAG) { /* Delay Slot insn */ +env-flags = ~D_FLAG; +env-sr |= SR_DSX; +if (env-exception_index == EXCP_TICK|| +env-exception_index == EXCP_INT || +env-exception_index == EXCP_SYSCALL || +env-exception_index == EXCP_FPE) { +env-epcr = env-jmp_pc; +} else { +env-epcr = env-pc - 4; +} +} else { +if (env-exception_index == EXCP_TICK|| +env-exception_index == EXCP_INT || +env-exception_index == EXCP_SYSCALL || +
[Qemu-devel] [PATCH v7 12/16] target-or32: Add system instructions
Add OpenRISC system instructions. Signed-off-by: Jia Liu pro...@gmail.com --- target-openrisc/Makefile.objs |3 +- target-openrisc/helper.h |4 + target-openrisc/sys_helper.c | 244 + target-openrisc/translate.c | 10 ++ 4 files changed, 260 insertions(+), 1 deletion(-) create mode 100644 target-openrisc/sys_helper.c diff --git a/target-openrisc/Makefile.objs b/target-openrisc/Makefile.objs index 0d72c33..9d13a5d 100644 --- a/target-openrisc/Makefile.objs +++ b/target-openrisc/Makefile.objs @@ -1,3 +1,4 @@ obj-$(CONFIG_SOFTMMU) += machine.o obj-y += cpu.o excp.o intrpt.o mmu.o translate.o -obj-y += excp_helper.o fpu_helper.o int_helper.o intrpt_helper.o mmu_helper.o +obj-y += excp_helper.o fpu_helper.o int_helper.o intrpt_helper.o \ + mmu_helper.o sys_helper.o diff --git a/target-openrisc/helper.h b/target-openrisc/helper.h index 6eb259a..836a70b 100644 --- a/target-openrisc/helper.h +++ b/target-openrisc/helper.h @@ -63,4 +63,8 @@ DEF_HELPER_FLAGS_3(mul32, 0, tl, env, tl, tl) /* interrupt */ DEF_HELPER_FLAGS_1(rfe, 0, void, env) +/* sys */ +DEF_HELPER_FLAGS_4(mtspr, 0, void, env, tl, tl, tl) +DEF_HELPER_FLAGS_4(mfspr, 0, tl, env, tl, tl, tl) + #include def-helper.h diff --git a/target-openrisc/sys_helper.c b/target-openrisc/sys_helper.c new file mode 100644 index 000..a2691dc --- /dev/null +++ b/target-openrisc/sys_helper.c @@ -0,0 +1,244 @@ +/* + * OpenRISC system instructions helper routines + * + * Copyright (c) 2011-2012 Jia Liu pro...@gmail.com + * Zhizhou Zhang eto...@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see http://www.gnu.org/licenses/. + */ + +#include cpu.h +#include helper.h + +#define TO_SPR(group, number) (((group) 11) + (number)) + +void HELPER(mtspr)(CPUOpenRISCState *env, + target_ulong ra, target_ulong rb, target_ulong offset) +{ +#ifndef CONFIG_USER_ONLY +int spr = (ra | offset); +int idx; + +switch (spr) { +case TO_SPR(0, 0): /* VR */ +env-vr = rb; +break; + +case TO_SPR(0, 16): /* NPC */ +env-npc = rb; +break; + +case TO_SPR(0, 17): /* SR */ +if ((env-sr (SR_IME | SR_DME | SR_SM)) ^ +(rb (SR_IME | SR_DME | SR_SM))) { +tlb_flush(env, 1); +} +env-sr = rb; +env-sr |= SR_FO; /* FO is const equal to 1 */ +if (env-sr SR_DME) { +env-tlb-map_address_data = get_phys_data; +} else { +env-tlb-map_address_data = get_phys_nommu; +} + +if (env-sr SR_IME) { +env-tlb-map_address_code = get_phys_code; +} else { +env-tlb-map_address_code = get_phys_nommu; +} +break; + +case TO_SPR(0, 18): /* PPC */ +env-ppc = rb; +break; + +case TO_SPR(0, 32): /* EPCR */ +env-epcr = rb; +break; + +case TO_SPR(0, 48): /* EEAR */ +env-eear = rb; +break; + +case TO_SPR(0, 64): /* ESR */ +env-esr = rb; +break; +case TO_SPR(1, 512) ... TO_SPR(1, 639): /* DTLBW0MR 0-127 */ +idx = spr - TO_SPR(1, 512); +if (!(rb 1)) { +tlb_flush_page(env, env-tlb-dtlb[0][idx].mr TARGET_PAGE_MASK); +} +env-tlb-dtlb[0][idx].mr = rb; +break; + +case TO_SPR(1, 640) ... TO_SPR(1, 767): /* DTLBW0TR 0-127 */ +idx = spr - TO_SPR(1, 640); +env-tlb-dtlb[0][idx].tr = rb; +break; +case TO_SPR(1, 768) ... TO_SPR(1, 895): /* DTLBW1MR 0-127 */ +case TO_SPR(1, 896) ... TO_SPR(1, 1023): /* DTLBW1TR 0-127 */ +case TO_SPR(1, 1024) ... TO_SPR(1, 1151): /* DTLBW2MR 0-127 */ +case TO_SPR(1, 1152) ... TO_SPR(1, 1279): /* DTLBW2TR 0-127 */ +case TO_SPR(1, 1280) ... TO_SPR(1, 1407): /* DTLBW3MR 0-127 */ +case TO_SPR(1, 1408) ... TO_SPR(1, 1535): /* DTLBW3TR 0-127 */ +break; +case TO_SPR(2, 512) ... TO_SPR(2, 639): /* ITLBW0MR 0-127 */ +idx = spr - TO_SPR(2, 512); +if (!(rb 1)) { +tlb_flush_page(env, env-tlb-itlb[0][idx].mr TARGET_PAGE_MASK); +} +env-tlb-itlb[0][idx].mr = rb; +break; + +case TO_SPR(2, 640) ... TO_SPR(2, 767): /* ITLBW0TR 0-127 */ +idx = spr - TO_SPR(2, 640); +env-tlb-itlb[0][idx].tr = rb; +break; +case TO_SPR(2,
Re: [Qemu-devel] [PATCH 1/2] Add usb option in machine options to enable/disable usb
Hi Andreas, I send out this patch with vga enablement on papr, which needs usb enabled. Is there any more suggestion about this patch? Who else need to ack it? Thank you very much. :) On Mon, Jun 18, 2012 at 5:22 PM, Li Zhang zhlci...@gmail.com wrote: For pseries machine, it needs to enable usb to add keyboard or usb mouse. -usb option won't be used in the future, and machine options is a better way to enable usb. So this patch is to add usb option to machine options (-machine type=psereis,usb=on/off)to enable/disable usb controller. For specific machines, they will get the machine option and then create usb controller according to usb option. In this patch, usb is on by default on pseries. So, for -nodefault,usb should be set off in the command line as the following: -machine type=pseries,usb=off. Signed-off-by: Li Zhang zhlci...@linux.vnet.ibm.com --- hw/spapr.c | 10 ++ qemu-config.c | 4 2 files changed, 14 insertions(+), 0 deletions(-) diff --git a/hw/spapr.c b/hw/spapr.c index d0bddbc..8d158d7 100644 --- a/hw/spapr.c +++ b/hw/spapr.c @@ -529,6 +529,8 @@ static void ppc_spapr_init(ram_addr_t ram_size, long load_limit, rtas_limit, fw_size; long pteg_shift = 17; char *filename; + QemuOpts * machine_opts; + bool usb_on = false; spapr = g_malloc0(sizeof(*spapr)); QLIST_INIT(spapr-phbs); @@ -661,6 +663,14 @@ static void ppc_spapr_init(ram_addr_t ram_size, spapr_vscsi_create(spapr-vio_bus); } + machine_opts = qemu_opts_find(qemu_find_opts(machine), 0); + if (machine_opts) + usb_on = qemu_opt_get_bool(machine_opts, usb, true); + + if (usb_on) { + pci_create_simple(QLIST_FIRST(spapr-phbs)-host_state.bus, + -1, pci-ohci); + } if (rma_size (MIN_RMA_SLOF 20)) { fprintf(stderr, qemu: pSeries SLOF firmware requires = %ldM guest RMA (Real Mode Area memory)\n, MIN_RMA_SLOF); diff --git a/qemu-config.c b/qemu-config.c index bb3bff4..cdab765 100644 --- a/qemu-config.c +++ b/qemu-config.c @@ -583,6 +583,10 @@ static QemuOptsList qemu_machine_opts = { .name = dtb, .type = QEMU_OPT_STRING, .help = Linux kernel device tree file, + },{ + .name = usb, + .type = QEMU_OPT_BOOL, + .help = Set on/off to enable/disable usb, }, { /* End of list */ } }, -- 1.7.7.6 -- Best Regards -Li
[Qemu-devel] [PATCH v7 13/16] target-or32: Add gdb stub
Add OpenRISC gdb stub support. Signed-off-by: Jia Liu pro...@gmail.com --- gdbstub.c | 64 + 1 file changed, 64 insertions(+) diff --git a/gdbstub.c b/gdbstub.c index 08cf864..5d37dd9 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -1155,6 +1155,68 @@ static int cpu_gdb_write_register(CPUMIPSState *env, uint8_t *mem_buf, int n) return sizeof(target_ulong); } +#elif defined(TARGET_OPENRISC) + +#define NUM_CORE_REGS (32 + 3) + +static int cpu_gdb_read_register(CPUOpenRISCState *env, uint8_t *mem_buf, int n) +{ +if (n 32) { +GET_REG32(env-gpr[n]); +} else { +switch (n) { +case 32:/* PPC */ +GET_REG32(env-ppc); +break; + +case 33:/* NPC */ +GET_REG32(env-npc); +break; + +case 34:/* SR */ +GET_REG32(env-sr); +break; + +default: +break; +} +} +return 0; +} + +static int cpu_gdb_write_register(CPUOpenRISCState *env, + uint8_t *mem_buf, int n) +{ +uint32_t tmp; + +if (n NUM_CORE_REGS) { +return 0; +} + +tmp = ldl_p(mem_buf); + +if (n 32) { +env-gpr[n] = tmp; +} else { +switch (n) { +case 32: /* PPC */ +env-ppc = tmp; +break; + +case 33: /* NPC */ +env-npc = tmp; +break; + +case 34: /* SR */ +env-sr = tmp; +break; + +default: +break; +} +} +return 4; +} #elif defined (TARGET_SH4) /* Hint: Use set architecture sh4 in GDB to see fpu registers */ @@ -1924,6 +1986,8 @@ static void gdb_set_cpu_pc(GDBState *s, target_ulong pc) } #elif defined (TARGET_MICROBLAZE) s-c_cpu-sregs[SR_PC] = pc; +#elif defined(TARGET_OPENRISC) +s-c_cpu-pc = pc; #elif defined (TARGET_CRIS) s-c_cpu-pc = pc; #elif defined (TARGET_ALPHA) -- 1.7.9.5
[Qemu-devel] [PATCH v7 14/16] target-or32: Add linux syscall, signal and termbits
Add OpenRISC linux syscall, signal and termbits. Signed-off-by: Jia Liu pro...@gmail.com --- linux-user/openrisc/syscall.h | 24 ++ linux-user/openrisc/syscall_nr.h| 506 +++ linux-user/openrisc/target_signal.h | 26 ++ linux-user/openrisc/termbits.h | 294 4 files changed, 850 insertions(+) create mode 100644 linux-user/openrisc/syscall.h create mode 100644 linux-user/openrisc/syscall_nr.h create mode 100644 linux-user/openrisc/target_signal.h create mode 100644 linux-user/openrisc/termbits.h diff --git a/linux-user/openrisc/syscall.h b/linux-user/openrisc/syscall.h new file mode 100644 index 000..bdbb577 --- /dev/null +++ b/linux-user/openrisc/syscall.h @@ -0,0 +1,24 @@ +struct target_pt_regs { +union { +struct { +/* Named registers */ +uint32_t sr; /* Stored in place of r0 */ +target_ulong sp; /* r1 */ +}; +struct { +/* Old style */ +target_ulong offset[2]; +target_ulong gprs[30]; +}; +struct { +/* New style */ +target_ulong gpr[32]; +}; +}; +target_ulong pc; +target_ulong orig_gpr11; /* For restarting system calls */ +uint32_t syscallno;/* Syscall number (used by strace) */ +target_ulong dummy; /* Cheap alignment fix */ +}; + +#define UNAME_MACHINE openrisc diff --git a/linux-user/openrisc/syscall_nr.h b/linux-user/openrisc/syscall_nr.h new file mode 100644 index 000..f4ac91e --- /dev/null +++ b/linux-user/openrisc/syscall_nr.h @@ -0,0 +1,506 @@ +#define TARGET_NR_io_setup 0 +#define TARGET_NR_io_destroy 1 +#define TARGET_NR_io_submit 2 +#define TARGET_NR_io_cancel 3 +#define TARGET_NR_io_getevents 4 + +/* fs/xattr.c */ +#define TARGET_NR_setxattr 5 +#define TARGET_NR_lsetxattr 6 +#define TARGET_NR_fsetxattr 7 +#define TARGET_NR_getxattr 8 +#define TARGET_NR_lgetxattr 9 +#define TARGET_NR_fgetxattr 10 +#define TARGET_NR_listxattr 11 +#define TARGET_NR_llistxattr 12 +#define TARGET_NR_flistxattr 13 +#define TARGET_NR_removexattr 14 +#define TARGET_NR_lremovexattr 15 +#define TARGET_NR_fremovexattr 16 + +/* fs/dcache.c */ +#define TARGET_NR_getcwd 17 + +/* fs/cookies.c */ +#define TARGET_NR_lookup_dcookie 18 + +/* fs/eventfd.c */ +#define TARGET_NR_eventfd2 19 + +/* fs/eventpoll.c */ +#define TARGET_NR_epoll_create1 20 +#define TARGET_NR_epoll_ctl 21 +#define TARGET_NR_epoll_pwait 22 + +/* fs/fcntl.c */ +#define TARGET_NR_dup 23 +#define TARGET_NR_dup3 24 +#define TARGET_NR_3264_fcntl 25 + +/* fs/inotify_user.c */ +#define TARGET_NR_inotify_init1 26 +#define TARGET_NR_inotify_add_watch 27 +#define TARGET_NR_inotify_rm_watch 28 + +/* fs/ioctl.c */ +#define TARGET_NR_ioctl 29 + +/* fs/ioprio.c */ +#define TARGET_NR_ioprio_set 30 +#define TARGET_NR_ioprio_get 31 + +/* fs/locks.c */ +#define TARGET_NR_flock 32 + +/* fs/namei.c */ +#define TARGET_NR_mknodat 33 +#define TARGET_NR_mkdirat 34 +#define TARGET_NR_unlinkat 35 +#define TARGET_NR_symlinkat 36 +#define TARGET_NR_linkat 37 +#define TARGET_NR_renameat 38 + +/* fs/namespace.c */ +#define TARGET_NR_umount2 39 +#define TARGET_NR_mount 40 +#define TARGET_NR_pivot_root 41 + +/* fs/nfsctl.c */ +#define TARGET_NR_nfsservctl 42 + +/* fs/open.c */ +#define TARGET_NR_3264_statfs 43 +#define TARGET_NR_3264_fstatfs 44 +#define TARGET_NR_3264_truncate 45 +#define TARGET_NR_3264_ftruncate 46 + +#define TARGET_NR_fallocate 47 +#define TARGET_NR_faccessat 48 +#define TARGET_NR_chdir 49 +#define TARGET_NR_fchdir 50 +#define TARGET_NR_chroot 51 +#define TARGET_NR_fchmod 52 +#define TARGET_NR_fchmodat 53 +#define TARGET_NR_fchownat 54 +#define TARGET_NR_fchown 55 +#define TARGET_NR_openat 56 +#define TARGET_NR_close 57 +#define TARGET_NR_vhangup 58 + +/* fs/pipe.c */ +#define TARGET_NR_pipe2 59 + +/* fs/quota.c */ +#define TARGET_NR_quotactl 60 + +/* fs/readdir.c */ +#define TARGET_NR_getdents64 61 + +/* fs/read_write.c */ +#define TARGET_NR_3264_lseek 62 +#define TARGET_NR_read 63 +#define TARGET_NR_write 64 +#define TARGET_NR_readv 65 +#define TARGET_NR_writev 66 +#define TARGET_NR_pread64 67 +#define TARGET_NR_pwrite64 68 +#define TARGET_NR_preadv 69 +#define TARGET_NR_pwritev 70 + +/* fs/sendfile.c */ +#define TARGET_NR_3264_sendfile 71 + +/* fs/select.c */ +#define TARGET_NR_pselect6 72 +#define TARGET_NR_ppoll 73 + +/* fs/signalfd.c */ +#define TARGET_NR_signalfd4 74 + +/* fs/splice.c */ +#define TARGET_NR_vmsplice 75 +#define TARGET_NR_splice 76 +#define TARGET_NR_tee 77 + +/* fs/stat.c */ +#define TARGET_NR_readlinkat 78 +#define TARGET_NR_3264_fstatat 79 +#define TARGET_NR_3264_fstat 80 + +/* fs/sync.c */ +#define TARGET_NR_sync 81 +#define TARGET_NR_fsync 82 +#define TARGET_NR_fdatasync 83 + +#ifdef __ARCH_WANT_SYNC_FILE_RANGE2 +#define TARGET_NR_sync_file_range2 84 +#else +#define TARGET_NR_sync_file_range 84 +#endif + +/* fs/timerfd.c */ +#define TARGET_NR_timerfd_create 85 +#define
Re: [Qemu-devel] [PATCH 2/2] spapr: Add support for -vga option
Hi Andreas, This patch is to enable vga which works well on our internal tree. Would you please help review it? Any suggestion is appreciated. Thanks a lot. :) On Mon, Jun 18, 2012 at 5:34 PM, Li Zhang zhlci...@gmail.com wrote: Also instanciate the USB keyboard and mouse when that option is used (you can still use -device to create individual devices without all the defaults) Signed-off-by: Benjamin Herrenschmidt b...@kernel.crashing.org Signed-off-by: Li Zhang zhlci...@linux.vnet.ibm.com --- hw/spapr.c | 43 ++- 1 files changed, 42 insertions(+), 1 deletions(-) diff --git a/hw/spapr.c b/hw/spapr.c index 8d158d7..c7b6e9d 100644 --- a/hw/spapr.c +++ b/hw/spapr.c @@ -45,6 +45,8 @@ #include kvm.h #include kvm_ppc.h #include pci.h +#include pc.h +#include usb.h #include exec-memory.h @@ -82,6 +84,7 @@ #define PHANDLE_XICP 0x sPAPREnvironment *spapr; +static int spapr_has_graphics; qemu_irq spapr_allocate_irq(uint32_t hint, uint32_t *irq_num, enum xics_irq_type type) @@ -222,6 +225,9 @@ static void *spapr_create_fdt_skel(const char *cpu_model, _FDT((fdt_property(fdt, qemu,boot-kernel, kprop, sizeof(kprop; } _FDT((fdt_property_string(fdt, qemu,boot-device, boot_device))); + _FDT((fdt_property_cell(fdt, qemu,graphic-width, graphic_width))); + _FDT((fdt_property_cell(fdt, qemu,graphic-height, graphic_height))); + _FDT((fdt_property_cell(fdt, qemu,graphic-depth, graphic_depth))); _FDT((fdt_end_node(fdt))); @@ -457,7 +463,9 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr, } } - spapr_populate_chosen_stdout(fdt, spapr-vio_bus); + if (!spapr_has_graphics) { + spapr_populate_chosen_stdout(fdt, spapr-vio_bus); + } _FDT((fdt_pack(fdt))); @@ -510,6 +518,30 @@ static void spapr_cpu_reset(void *opaque) cpu_reset(CPU(cpu)); } +static int spapr_vga_init(PCIBus *pci_bus) +{ + /* Default is nothing */ +#if 0 /* Enable this once we merge a SLOF which works with Cirrus */ + if (cirrus_vga_enabled) { + pci_cirrus_vga_init(pci_bus); + } else +#endif + if (vmsvga_enabled) { + fprintf(stderr, Warning: vmware_vga not available, + using standard VGA instead\n); + pci_vga_init(pci_bus); +#ifdef CONFIG_SPICE + } else if (qxl_enabled) { + pci_create_simple(pci_bus, -1, qxl-vga); +#endif + } else if (std_vga_enabled) { + pci_vga_init(pci_bus); + } else { + return 0; + } + return 1; +} + /* pSeries LPAR / sPAPR hardware init */ static void ppc_spapr_init(ram_addr_t ram_size, const char *boot_device, @@ -663,6 +695,11 @@ static void ppc_spapr_init(ram_addr_t ram_size, spapr_vscsi_create(spapr-vio_bus); } + /* Graphics */ + if (spapr_vga_init(QLIST_FIRST(spapr-phbs)-host_state.bus)) { + spapr_has_graphics = 1; + } + machine_opts = qemu_opts_find(qemu_find_opts(machine), 0); if (machine_opts) usb_on = qemu_opt_get_bool(machine_opts, usb, true); @@ -670,6 +707,10 @@ static void ppc_spapr_init(ram_addr_t ram_size, if (usb_on) { pci_create_simple(QLIST_FIRST(spapr-phbs)-host_state.bus, -1, pci-ohci); + if (spapr_has_graphics) { + usbdevice_create(keyboard); + usbdevice_create(mouse); + } } if (rma_size (MIN_RMA_SLOF 20)) { fprintf(stderr, qemu: pSeries SLOF firmware requires = -- 1.7.7.6 -- Best Regards -Li
Re: [Qemu-devel] [PATCH v3 5/6] qapi: convert sendkey
On 27/06/12 04:21, Luiz Capitulino wrote: On Wed, 20 Jun 2012 12:47:40 +0800 Amos Kongak...@redhat.com wrote: Convert 'sendkey' to use QAPI. do_sendkey() depends on some variables/functions in monitor.c, so reserve qmp_sendkey() to monitor.c key_defs[] in monitor.c is the mapping of key name to keycode, Keys' order in the enmu and key_defs[] is same. Signed-off-by: Amos Kongak...@redhat.com --- hmp-commands.hx |2 +- hmp.c| 45 hmp.h|1 + monitor.c| 102 +++-- monitor.h|2 + qapi-schema.json | 45 qmp-commands.hx | 27 ++ 7 files changed, 165 insertions(+), 59 deletions(-) diff --git a/hmp-commands.hx b/hmp-commands.hx index e336251..fee4c14 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -505,7 +505,7 @@ ETEXI .args_type = keys:s,hold-time:i?, .params = keys [hold_ms], .help = send keys to the VM (e.g. 'sendkey ctrl-alt-f1', default hold time=100 ms), -.mhandler.cmd = do_sendkey, +.mhandler.cmd = hmp_sendkey, }, STEXI diff --git a/hmp.c b/hmp.c index b9cec1d..846e8b9 100644 --- a/hmp.c +++ b/hmp.c @@ -19,6 +19,7 @@ #include qemu-timer.h #include qmp-commands.h #include monitor.h +#include qapi-types.h static void hmp_handle_error(Monitor *mon, Error **errp) { @@ -1000,3 +1001,47 @@ void hmp_netdev_del(Monitor *mon, const QDict *qdict) qmp_netdev_del(id,err); hmp_handle_error(mon,err); } + +void hmp_sendkey(Monitor *mon, const QDict *qdict) +{ +const char *keys = qdict_get_str(qdict, keys); +KeyCodesList *keylist, *head = NULL, *tmp = NULL; +int has_hold_time = qdict_haskey(qdict, hold-time); +int hold_time = qdict_get_try_int(qdict, hold-time, -1); +Error *err = NULL; +char keyname_buf[16]; + Please, drop this blank line. +char *separator; +int keyname_len; + +while (1) { +separator = strchr(keys, '-'); +keyname_len = separator ? separator - keys : strlen(keys); +pstrcpy(keyname_buf, sizeof(keyname_buf), keys); + +/* Be compatible with old interface, convert user inputted */ +if (!strncmp(keyname_buf, , 1) keyname_len == 1) { +pstrcpy(keyname_buf, sizeof(keyname_buf), less); +keyname_len = 4; +} +keyname_buf[keyname_len] = 0; + +keylist = g_malloc0(sizeof(*keylist)); +keylist-value = get_key_index(keyname_buf); +keylist-next = NULL; + +if (tmp) +tmp-next = keylist; +tmp = keylist; +if (!head) +head = keylist; + +if (!separator) +break; +keys = separator + 1; +} + +qmp_sendkey(head, has_hold_time, hold_time,err); +hmp_handle_error(mon,err); +qapi_free_KeyCodesList(head); +} diff --git a/hmp.h b/hmp.h index 79d138d..bcc74d2 100644 --- a/hmp.h +++ b/hmp.h @@ -64,5 +64,6 @@ void hmp_device_del(Monitor *mon, const QDict *qdict); void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict); void hmp_netdev_add(Monitor *mon, const QDict *qdict); void hmp_netdev_del(Monitor *mon, const QDict *qdict); +void hmp_sendkey(Monitor *mon, const QDict *qdict); #endif diff --git a/monitor.c b/monitor.c index 6fa0104..863c0c6 100644 --- a/monitor.c +++ b/monitor.c @@ -1470,98 +1470,84 @@ static const KeyDef key_defs[] = { { 0, NULL }, }; -static int get_keycode(const char *key) +int get_key_index(const char *key) { This should be moved to hmp.c instead of making it public. The static 'key_defs' is used in this function, I tried to move key_defs definition to monitor.h, but I got this error: qemu/monitor.h:220:13: error: attempt to use poisoned TARGET_SPARC qemu/monitor.h:220:39: error: attempt to use poisoned TARGET_SPARC64 Where is the good place to define key_defs ? it would be used in monitor.c hmp.c -const KeyDef *p; +int i, keycode; char *endp; -int ret; +const KeyDef *p; -for(p = key_defs; p-name != NULL; p++) { -if (!strcmp(key, p-name)) -return p-keycode; +for (i = 0; KeyCodes_lookup[i] != NULL; i++) { +if (!strcmp(key, KeyCodes_lookup[i])) +return i; } + if (strstart(key, 0x, NULL)) { -ret = strtoul(key,endp, 0); -if (*endp == '\0' ret= 0x01 ret= 0xff) -return ret; +keycode = strtoul(key,endp, 0); +if (*endp == '\0' keycode= 0x01 keycode= 0xff) +i = 0; +for (p = key_defs; p-name != NULL; p++) { +if (keycode == p-keycode) +return i; +i++; +} } + return -1; } -#define MAX_KEYCODES 16 -static uint8_t keycodes[MAX_KEYCODES]; -static int nb_pending_keycodes; +static KeyCodesList *keycodes; static QEMUTimer *key_timer; static void
[Qemu-devel] [PATCH v2] bitops.h: Add field32() and field64() functions to extract bitfields
Add field32() and field64() functions which extract a particular bit field from a word and return it. Based on an idea by Jia Liu. Suggested-by: Jia Liu pro...@gmail.com Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- v1-v2: added missing brackets to field32() to bring it in to line with field64() (Still using 'int' rather than 'unsigned' for bit numbers as per rationale in previous discussion.) bitops.h | 28 1 files changed, 28 insertions(+), 0 deletions(-) diff --git a/bitops.h b/bitops.h index 07d1a06..ffbb387 100644 --- a/bitops.h +++ b/bitops.h @@ -269,4 +269,32 @@ static inline unsigned long hweight_long(unsigned long w) return count; } +/** + * field64 - return a specified bit field from a uint64_t value + * @value: The value to extract the bit field from + * @start: The lowest bit in the bit field (numbered from 0) + * @length: The length of the bit field + * + * Returns the value of the bit field extracted from the input value. + */ +static inline uint64_t field64(uint64_t value, int start, int length) +{ +assert(start = 0 start = 63 length 0 start + length = 64); +return (value start) (~0ULL (64 - length)); +} + +/** + * field32 - return a specified bit field from a uint32_t value + * @value: The value to extract the bit field from + * @start: The lowest bit in the bit field (numbered from 0) + * @length: The length of the bit field + * + * Returns the value of the bit field extracted from the input value. + */ +static inline uint32_t field32(uint32_t value, int start, int length) +{ +assert(start = 0 start = 31 length 0 start + length = 32); +return (value start) (~0U (32 - length)); +} + #endif -- 1.7.1
[Qemu-devel] [PATCH v7 09/16] target-or32: Add PIC support
Add OpenRISC Programmable Interrupt Controller support. Signed-off-by: Jia Liu pro...@gmail.com --- hw/openrisc_pic.c | 48 1 file changed, 48 insertions(+) diff --git a/hw/openrisc_pic.c b/hw/openrisc_pic.c index 0d14bbe..76bd792 100644 --- a/hw/openrisc_pic.c +++ b/hw/openrisc_pic.c @@ -28,3 +28,51 @@ void cpu_openrisc_pic_reset(CPUOpenRISCState *env) env-picmr = 0x; env-picsr = 0x; } + +/* OpenRISC pic handler */ +static void openrisc_pic_cpu_handler(void *opaque, int irq, int level) +{ +CPUOpenRISCState *env = (CPUOpenRISCState *)opaque; +int i; +uint32_t irq_bit = 1 irq; + +if (irq 31 || irq 0) { +return; +} + +if (level) { +env-picsr |= irq_bit; +} else { +env-picsr = ~irq_bit; +} + +for (i = 0; i 32; i++) { +if ((env-picsr (1 i)) (env-picmr (1 i))) { +cpu_interrupt(env, CPU_INTERRUPT_HARD); +} else { +cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); +env-picsr = ~(1 i); +} +} +} + +void cpu_openrisc_pic_init(CPUOpenRISCState *env) +{ +int i; +qemu_irq *qi; +qi = qemu_allocate_irqs(openrisc_pic_cpu_handler, env, NR_IRQS); + +for (i = 0; i NR_IRQS; i++) { +env-irq[i] = qi[i]; +} +} + +void cpu_openrisc_store_picmr(CPUOpenRISCState *env, uint32_t value) +{ +env-picmr |= value; +} + +void cpu_openrisc_store_picsr(CPUOpenRISCState *env, uint32_t value) +{ +env-picsr = ~value; +} -- 1.7.9.5
Re: [Qemu-devel] [PATCH] Revert rtl8139: do the network/host communication only in normal operating mode
On 06/04/2012 03:28 PM, Anthony Liguori wrote: Michael has some concern on this patch, so I post another patch of validating the rx buf instead of checking the opmode, please see http://lists.gnu.org/archive/html/qemu-devel/2012-05/msg02385.html. So maybe we can apply that or I need to send another patch on top of this reverting? I'll work it all out. I see the revert reverted, but I don't see the followup patch applied? A laboriously bisected regression here suggests this is the problem. -- error compiling committee.c: too many arguments to function
[Qemu-devel] [PATCH v13 01/13] Add MigrationParams structure
From: Isaku Yamahata yamah...@valinux.co.jp Signed-off-by: Isaku Yamahata yamah...@valinux.co.jp --- block-migration.c |8 migration.c | 13 - migration.h |8 ++-- qemu-common.h |1 + savevm.c | 13 + sysemu.h |3 ++- vmstate.h |2 +- 7 files changed, 31 insertions(+), 17 deletions(-) diff --git a/block-migration.c b/block-migration.c index fd2..b95b4e1 100644 --- a/block-migration.c +++ b/block-migration.c @@ -700,13 +700,13 @@ static int block_load(QEMUFile *f, void *opaque, int version_id) return 0; } -static void block_set_params(int blk_enable, int shared_base, void *opaque) +static void block_set_params(const MigrationParams *params, void *opaque) { -block_mig_state.blk_enable = blk_enable; -block_mig_state.shared_base = shared_base; +block_mig_state.blk_enable = params-blk; +block_mig_state.shared_base = params-shared; /* shared base means that blk_enable = 1 */ -block_mig_state.blk_enable |= shared_base; +block_mig_state.blk_enable |= params-shared; } void blk_mig_init(void) diff --git a/migration.c b/migration.c index 3f485d3..810727f 100644 --- a/migration.c +++ b/migration.c @@ -352,7 +352,7 @@ void migrate_fd_connect(MigrationState *s) migrate_fd_close); DPRINTF(beginning savevm\n); -ret = qemu_savevm_state_begin(s-file, s-blk, s-shared); +ret = qemu_savevm_state_begin(s-file, s-params); if (ret 0) { DPRINTF(failed, %d\n, ret); migrate_fd_error(s); @@ -361,15 +361,14 @@ void migrate_fd_connect(MigrationState *s) migrate_fd_put_ready(s); } -static MigrationState *migrate_init(int blk, int inc) +static MigrationState *migrate_init(const MigrationParams *params) { MigrationState *s = migrate_get_current(); int64_t bandwidth_limit = s-bandwidth_limit; memset(s, 0, sizeof(*s)); s-bandwidth_limit = bandwidth_limit; -s-blk = blk; -s-shared = inc; +s-params = *params; s-bandwidth_limit = bandwidth_limit; s-state = MIG_STATE_SETUP; @@ -394,9 +393,13 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk, Error **errp) { MigrationState *s = migrate_get_current(); +MigrationParams params; const char *p; int ret; +params.blk = blk; +params.shared = inc; + if (s-state == MIG_STATE_ACTIVE) { error_set(errp, QERR_MIGRATION_ACTIVE); return; @@ -411,7 +414,7 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk, return; } -s = migrate_init(blk, inc); +s = migrate_init(params); if (strstart(uri, tcp:, p)) { ret = tcp_start_outgoing_migration(s, p, errp); diff --git a/migration.h b/migration.h index 2e9ca2e..35207bd 100644 --- a/migration.h +++ b/migration.h @@ -19,6 +19,11 @@ #include notify.h #include error.h +struct MigrationParams { +bool blk; +bool shared; +}; + typedef struct MigrationState MigrationState; struct MigrationState @@ -31,8 +36,7 @@ struct MigrationState int (*close)(MigrationState *s); int (*write)(MigrationState *s, const void *buff, size_t size); void *opaque; -int blk; -int shared; +MigrationParams params; }; void process_incoming_migration(QEMUFile *f); diff --git a/qemu-common.h b/qemu-common.h index 9d9e603..c8c6b2a 100644 --- a/qemu-common.h +++ b/qemu-common.h @@ -17,6 +17,7 @@ typedef struct DeviceState DeviceState; struct Monitor; typedef struct Monitor Monitor; +typedef struct MigrationParams MigrationParams; /* we put basic includes here to avoid repeating them in device drivers */ #include stdlib.h diff --git a/savevm.c b/savevm.c index faa8145..d1d9020 100644 --- a/savevm.c +++ b/savevm.c @@ -1561,7 +1561,8 @@ bool qemu_savevm_state_blocked(Error **errp) return false; } -int qemu_savevm_state_begin(QEMUFile *f, int blk_enable, int shared) +int qemu_savevm_state_begin(QEMUFile *f, +const MigrationParams *params) { SaveStateEntry *se; int ret; @@ -1569,8 +1570,8 @@ int qemu_savevm_state_begin(QEMUFile *f, int blk_enable, int shared) QTAILQ_FOREACH(se, savevm_handlers, entry) { if(se-set_params == NULL) { continue; - } - se-set_params(blk_enable, shared, se-opaque); +} +se-set_params(params, se-opaque); } qemu_put_be32(f, QEMU_VM_FILE_MAGIC); @@ -1708,13 +1709,17 @@ void qemu_savevm_state_cancel(QEMUFile *f) static int qemu_savevm_state(QEMUFile *f) { int ret; +MigrationParams params = { +.blk = 0, +.shared = 0 +}; if (qemu_savevm_state_blocked(NULL)) { ret = -EINVAL; goto out; } -ret = qemu_savevm_state_begin(f, 0, 0); +ret = qemu_savevm_state_begin(f, params); if (ret 0) goto out; diff --git a/sysemu.h b/sysemu.h index
[Qemu-devel] [PATCH v13 12/13] Add set_cachesize command
Change XBZRLE cache size in bytes (the size should be a power of 2). If XBZRLE cache size is too small there will be many cache miss. Signed-off-by: Benoit Hudzia benoit.hud...@sap.com Signed-off-by: Petter Svard pett...@cs.umu.se Signed-off-by: Aidan Shribman aidan.shrib...@sap.com Signed-off-by: Orit Wasserman owass...@redhat.com --- arch_init.c |9 + hmp-commands.hx | 18 ++ hmp.c| 13 + hmp.h|1 + migration.c | 23 ++- migration.h |2 ++ qapi-schema.json | 16 qmp-commands.hx | 23 +++ 8 files changed, 104 insertions(+), 1 deletions(-) diff --git a/arch_init.c b/arch_init.c index bfc9f27..ae7c8b1 100644 --- a/arch_init.c +++ b/arch_init.c @@ -24,6 +24,7 @@ #include stdint.h #include stdarg.h #include stdlib.h +#include math.h #ifndef _WIN32 #include sys/types.h #include sys/mman.h @@ -192,6 +193,14 @@ static struct { .cache = NULL, }; + +void xbzrle_cache_resize(int64_t new_size) +{ +if (XBZRLE.cache != NULL) { +cache_resize(XBZRLE.cache, new_size/TARGET_PAGE_SIZE); +} +} + static void save_block_hdr(QEMUFile *f, RAMBlock *block, ram_addr_t offset, int cont, int flag) { diff --git a/hmp-commands.hx b/hmp-commands.hx index a0c8df2..ef60dc0 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -829,6 +829,24 @@ STEXI @item migrate_cancel @findex migrate_cancel Cancel the current VM migration. + +ETEXI + +{ +.name = migrate_set_cachesize, +.args_type = value:o, +.params = value, +.help = set cache size (in bytes) for XBZRLE migrations, + the cache size will be round down to the nearest power of 2.\n + The cache size effects the number of cache misses. + In case of a high cache miss ratio you need to increase the cache size, +.mhandler.cmd = hmp_migrate_set_cachesize, +}, + +STEXI +@item migrate_set_cachesize @var{value} +@findex migrate_set_cache +Set cache size to @var{value} (in bytes) for xbzrle migrations. ETEXI { diff --git a/hmp.c b/hmp.c index c275fab..0a27d2d 100644 --- a/hmp.c +++ b/hmp.c @@ -755,6 +755,19 @@ void hmp_migrate_set_downtime(Monitor *mon, const QDict *qdict) qmp_migrate_set_downtime(value, NULL); } +void hmp_migrate_set_cachesize(Monitor *mon, const QDict *qdict) +{ +int64_t value = qdict_get_int(qdict, value); +Error *err = NULL; + +qmp_migrate_set_cachesize(value, err); +if (err) { +monitor_printf(mon, %s\n, error_get_pretty(err)); +error_free(err); +return; +} +} + void hmp_migrate_set_speed(Monitor *mon, const QDict *qdict) { int64_t value = qdict_get_int(qdict, value); diff --git a/hmp.h b/hmp.h index 09ba198..7c5117d 100644 --- a/hmp.h +++ b/hmp.h @@ -53,6 +53,7 @@ void hmp_migrate_cancel(Monitor *mon, const QDict *qdict); void hmp_migrate_set_downtime(Monitor *mon, const QDict *qdict); void hmp_migrate_set_speed(Monitor *mon, const QDict *qdict); void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict); +void hmp_migrate_set_cachesize(Monitor *mon, const QDict *qdict); void hmp_set_password(Monitor *mon, const QDict *qdict); void hmp_expire_password(Monitor *mon, const QDict *qdict); void hmp_eject(Monitor *mon, const QDict *qdict); diff --git a/migration.c b/migration.c index 6063ed8..a892ae1 100644 --- a/migration.c +++ b/migration.c @@ -22,6 +22,7 @@ #include qemu_socket.h #include block-migration.h #include qmp-commands.h +#include math.h //#define DEBUG_MIGRATION @@ -43,7 +44,7 @@ enum { #define MAX_THROTTLE (32 20) /* Migration speed throttling */ -/* Migration XBZRLE cache size */ +/* Migration XBZRLE default cache size */ #define DEFAULT_MIGRATE_CACHE_SIZE (64 * 1024 * 1024) static NotifierList migration_state_notifiers = @@ -519,6 +520,26 @@ void qmp_migrate_cancel(Error **errp) migrate_fd_cancel(migrate_get_current()); } +void qmp_migrate_set_cachesize(int64_t value, Error **errp) +{ +MigrationState *s = migrate_get_current(); + +/* Check for truncation */ +if (value != (size_t)value) { +error_set(errp, QERR_INVALID_PARAMETER_VALUE, cache size, + exceeding address space); +return; +} + +/* no change */ +if (value == s-xbzrle_cache_size) { +return; +} + +s-xbzrle_cache_size = value; +xbzrle_cache_resize(value); +} + void qmp_migrate_set_speed(int64_t value, Error **errp) { MigrationState *s; diff --git a/migration.h b/migration.h index 4fe8122..83dba4a 100644 --- a/migration.h +++ b/migration.h @@ -107,4 +107,6 @@ int xbzrle_decode_buffer(uint8_t *src, int slen, uint8_t *dst, int dlen); int migrate_use_xbzrle(void); int64_t migrate_xbzrle_cache_size(void); +void xbzrle_cache_resize(int64_t new_size); + #endif diff --git a/qapi-schema.json
[Qemu-devel] [PATCH v13 08/13] Change ram_save_block to return -1 if there are no more changes
It will return 0 if the page is unmodifed. Signed-off-by: Orit Wasserman owass...@redhat.com --- arch_init.c | 15 +-- 1 files changed, 9 insertions(+), 6 deletions(-) diff --git a/arch_init.c b/arch_init.c index ee20c33..ef7b4d6 100644 --- a/arch_init.c +++ b/arch_init.c @@ -184,11 +184,11 @@ static void save_block_hdr(QEMUFile *f, RAMBlock *block, ram_addr_t offset, static RAMBlock *last_block; static ram_addr_t last_offset; -static int ram_save_block(QEMUFile *f) +static int ram_save_block(QEMUFile *f, int stage) { RAMBlock *block = last_block; ram_addr_t offset = last_offset; -int bytes_sent = 0; +int bytes_sent = -1; MemoryRegion *mr; if (!block) @@ -353,9 +353,12 @@ int ram_save_live(QEMUFile *f, int stage, void *opaque) while ((ret = qemu_file_rate_limit(f)) == 0) { int bytes_sent; -bytes_sent = ram_save_block(f); -bytes_transferred += bytes_sent; -if (bytes_sent == 0) { /* no more blocks */ +bytes_sent = ram_save_block(f, stage); +/* bytes_sent 0 represent unchanged page, + bytes_sent -1 represent no more blocks*/ +if (bytes_sent 0) { +bytes_transferred += bytes_sent; +} else if (bytes_sent == -1) { /* no more blocks */ break; } } @@ -378,7 +381,7 @@ int ram_save_live(QEMUFile *f, int stage, void *opaque) int bytes_sent; /* flush all remaining blocks regardless of rate limiting */ -while ((bytes_sent = ram_save_block(f)) != 0) { +while ((bytes_sent = ram_save_block(f, stage)) != -1) { bytes_transferred += bytes_sent; } memory_global_dirty_log_stop(); -- 1.7.7.6
[Qemu-devel] [PATCH v13 11/13] Add XBZRLE to ram_save_block and ram_save_live
In the outgoing migration check to see if the page is cached and changed than send compressed page by using save_xbrle_page function. In the incoming migration check to see if RAM_SAVE_FLAG_XBRLE is set and decompress the page (by using load_xbrle function). Signed-off-by: Benoit Hudzia benoit.hud...@sap.com Signed-off-by: Petter Svard pett...@cs.umu.se Signed-off-by: Aidan Shribman aidan.shrib...@sap.com Signed-off-by: Orit Wasserman owass...@redhat.com --- arch_init.c | 179 ++- migration.c | 26 - migration.h |4 + 3 files changed, 205 insertions(+), 4 deletions(-) diff --git a/arch_init.c b/arch_init.c index 6703c72..bfc9f27 100644 --- a/arch_init.c +++ b/arch_init.c @@ -43,6 +43,7 @@ #include hw/smbios.h #include exec-memory.h #include hw/pcspk.h +#include qemu/cache.h #ifdef DEBUG_ARCH_INIT #define DPRINTF(fmt, ...) \ @@ -102,6 +103,7 @@ const uint32_t arch_type = QEMU_ARCH; #define RAM_SAVE_FLAG_PAGE 0x08 #define RAM_SAVE_FLAG_EOS 0x10 #define RAM_SAVE_FLAG_CONTINUE 0x20 +#define RAM_SAVE_FLAG_XBZRLE 0x40 #ifdef __ALTIVEC__ #include altivec.h @@ -169,6 +171,27 @@ static int is_dup_page(uint8_t *page) return 1; } +/* XBZRLE (Xor Based Zero Length Encoding */ +typedef struct XBZRLEHeader { +uint16_t xh_len; +uint8_t xh_flags; +} XBZRLEHeader; + +/* struct contains XBZRLE cache and a static page + used by the compression */ +static struct { +/* buffer used for XBZRLE encoding */ +uint8_t *encoded_buf; +/* buffer used for XBZRLE decoding */ +uint8_t *decoded_buf; +/* Cache for XBZRLE */ +Cache *cache; +} XBZRLE = { +.encoded_buf = NULL, +.decoded_buf = NULL, +.cache = NULL, +}; + static void save_block_hdr(QEMUFile *f, RAMBlock *block, ram_addr_t offset, int cont, int flag) { @@ -181,6 +204,64 @@ static void save_block_hdr(QEMUFile *f, RAMBlock *block, ram_addr_t offset, } +#define ENCODING_FLAG_XBZRLE 0x1 + +static int save_xbzrle_page(QEMUFile *f, uint8_t *current_data, +ram_addr_t current_addr, RAMBlock *block, +ram_addr_t offset, int cont, int stage) +{ +int encoded_len = 0, bytes_sent = -1, ret = -1; +XBZRLEHeader hdr = { +.xh_len = 0, +.xh_flags = 0, +}; +uint8_t *prev_cached_page; + +/* Stage 1 cache the page and exit. + Stage 2 check to see if page is cached , if not cache the page. + Stage 3 check if the page is cached and if not exit. +*/ +if (stage == 1 || !cache_is_cached(XBZRLE.cache, current_addr)) { +cache_insert(XBZRLE.cache, current_addr, + g_memdup(current_data, TARGET_PAGE_SIZE)); +return -1; +} + +prev_cached_page = get_cached_data(XBZRLE.cache, current_addr); + +/* XBZRLE encoding (if there is no overflow) */ +encoded_len = xbzrle_encode_buffer(prev_cached_page, current_data, + TARGET_PAGE_SIZE, XBZRLE.encoded_buf, + TARGET_PAGE_SIZE); +if (encoded_len == 0) { +DPRINTF(Unmodifed page skipping\n); +return 0; +} else if (encoded_len == -1) { +DPRINTF(Overflow\n); +/* update data in the cache */ +memcpy(prev_cached_page, current_data, TARGET_PAGE_SIZE); +return -1; +} + +/* we need to update the data in the cache, in order to get the same data + we cached we decode the encoded page on the cached data */ +ret = xbzrle_decode_buffer(XBZRLE.encoded_buf, encoded_len, + prev_cached_page, TARGET_PAGE_SIZE); +g_assert(ret != -1); + +hdr.xh_len = encoded_len; +hdr.xh_flags |= ENCODING_FLAG_XBZRLE; + +/* Send XBZRLE based compressed page */ +save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_XBZRLE); +qemu_put_byte(f, hdr.xh_flags); +qemu_put_be16(f, hdr.xh_len); +qemu_put_buffer(f, XBZRLE.encoded_buf, encoded_len); +bytes_sent = encoded_len + sizeof(hdr); + +return bytes_sent; +} + static RAMBlock *last_block; static ram_addr_t last_offset; @@ -190,10 +271,13 @@ static int ram_save_block(QEMUFile *f, int stage) ram_addr_t offset = last_offset; int bytes_sent = -1; MemoryRegion *mr; +ram_addr_t current_addr; if (!block) block = QLIST_FIRST(ram_list.blocks); + + do { mr = block-mr; if (memory_region_get_dirty(mr, offset, TARGET_PAGE_SIZE, @@ -210,13 +294,31 @@ static int ram_save_block(QEMUFile *f, int stage) save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_COMPRESS); qemu_put_byte(f, *p); bytes_sent = 1; -} else { +} else if (migrate_use_xbzrle() stage != 3) { +current_addr = block-offset + offset; +/* In stage 1 we only cache the pages before sending them +
[Qemu-devel] [PATCH v13 10/13] Add xbzrle_encode_buffer and xbzrle_decode_buffer functions
Signed-off-by: Benoit Hudzia benoit.hud...@sap.com Signed-off-by: Petter Svard pett...@cs.umu.se Signed-off-by: Aidan Shribman aidan.shrib...@sap.com Signed-off-by: Orit Wasserman owass...@redhat.com --- migration.h |4 ++ savevm.c| 145 +++ 2 files changed, 149 insertions(+), 0 deletions(-) diff --git a/migration.h b/migration.h index 1ae99f1..7582ecb 100644 --- a/migration.h +++ b/migration.h @@ -99,4 +99,8 @@ void migrate_add_blocker(Error *reason); */ void migrate_del_blocker(Error *reason); +int xbzrle_encode_buffer(uint8_t *old_buf, uint8_t *new_buf, int slen, + uint8_t *dst, int dlen); +int xbzrle_decode_buffer(uint8_t *src, int slen, uint8_t *dst, int dlen); + #endif diff --git a/savevm.c b/savevm.c index d1d9020..26e7901 100644 --- a/savevm.c +++ b/savevm.c @@ -2374,3 +2374,148 @@ void vmstate_register_ram_global(MemoryRegion *mr) { vmstate_register_ram(mr, NULL); } + +/* + page = zrun nzrun + | zrun nzrun page + + zrun = length + + nzrun = length byte... + + length = uleb128 encoded integer + */ +int xbzrle_encode_buffer(uint8_t *old_buf, uint8_t *new_buf, int slen, + uint8_t *dst, int dlen) +{ +uint32_t zrun_len = 0, nzrun_len = 0; +int d = 0 , i = 0; +int res, xor; +uint8_t *nzrun_start = NULL; + +while (i slen) { +/* overflow */ +if (d + 2 dlen) { +return -1; +} + +/* not aligned to sizeof(long) */ +res = (slen - i) % sizeof(long); +if (res) { +while (!(old_buf[i] ^ new_buf[i]) ++i = res) { +zrun_len++; +} +} + +xor = (*(long *)(old_buf + i)) ^ (*(long *)(new_buf + i)); +while (i = slen - sizeof(long) !xor) { +i += sizeof(long); +zrun_len += sizeof(long); +xor = (*(long *)(old_buf + i)) ^ (*(long *)(new_buf + i)); +} + +/* not aligned to sizeof(long) */ +res = (slen - i) % sizeof(long); +if (res) { +while (!(old_buf[i] ^ new_buf[i]) ++i = res) { +zrun_len++; +} +} + +/* buffer unchanged */ +if (zrun_len == slen) { +return 0; +} + +/* skip last zero run */ +if (i == slen + 1) { +return d; +} + +d += uleb128_encode_small(dst + d, zrun_len); + +zrun_len = 0; +nzrun_start = new_buf + i; + +/* not aligned to sizeof(long) */ +res = (slen - i) % sizeof(long); +if (res) { +while ((old_buf[i] ^ new_buf[i]) != 0 ++i = res) { +nzrun_len++; +} +} + +xor = (*(long *)(old_buf + i)) ^ (*(long *)(new_buf + i)); +while (i = slen - sizeof(long) xor != 0) { +i += sizeof(long); +nzrun_len += sizeof(long); +xor = (*(long *)(old_buf + i)) ^ (*(long *)(new_buf + i)); +} + +/* not aligned to sizeof(long) */ +res = (slen - i) % sizeof(long); +if (res) { +while ((old_buf[i] ^ new_buf[i]) != 0 ++i = res) { +nzrun_len++; +} +} + +/* overflow */ +if (d + nzrun_len + 2 dlen) { +return -1; +} + +d += uleb128_encode_small(dst + d, nzrun_len); +memcpy(dst + d, nzrun_start, nzrun_len); +d += nzrun_len; +nzrun_len = 0; +} + +return d; +} + +int xbzrle_decode_buffer(uint8_t *src, int slen, uint8_t *dst, int dlen) +{ +int i = 0, d = 0; +int ret; +uint32_t count = 0; + +while (i slen) { + +/* zrun */ +ret = uleb128_decode_small(src + i, count); +if (ret 0) { +return -1; +} +i += ret; +d += count; + +/* overflow */ +if (d dlen) { +return -1; +} + +/* completed decoding */ +if (i == slen - 1) { +return d; +} + +/* nzrun */ +ret = uleb128_decode_small(src + i, count); +if (ret 0) { +return -1; +} +i += ret; + +/* overflow */ +if (d + count dlen) { +return -1; +} + +memcpy(dst + d , src + i, count); +d += count; +i += count; +} + +return d; +} -- 1.7.7.6
[Qemu-devel] [PATCH v7 10/16] target-or32: Add timer support
Add OpenRISC timer support. Signed-off-by: Jia Liu pro...@gmail.com --- hw/openrisc_timer.c | 130 +++ 1 file changed, 130 insertions(+) diff --git a/hw/openrisc_timer.c b/hw/openrisc_timer.c index df384f6..25cde1a 100644 --- a/hw/openrisc_timer.c +++ b/hw/openrisc_timer.c @@ -22,9 +22,139 @@ #include openrisc_cpudev.h #include qemu-timer.h +#define TIMER_FREQ(20 * 1000 * 1000)/* 20MHz */ + +/* The time when TTCR changes */ +static uint64_t last_clk; +static int is_counting; + +/* Timer Mode */ +enum { +TIMER_NONE = (0 30), +TIMER_INTR = (1 30), +TIMER_SHOT = (2 30), +TIMER_CONT = (3 30), +}; + /* Reset Timer */ void cpu_openrisc_timer_reset(CPUOpenRISCState *env) { env-ttmr = 0x; env-ttcr = 0x; } + +static void count_update(CPUOpenRISCState *env) +{ +uint64_t now, next; +uint32_t wait; + +now = qemu_get_clock_ns(vm_clock); +if (!is_counting) { +qemu_del_timer(env-timer); +last_clk = now; +return; +} + +env-ttcr += (uint32_t)muldiv64(now - last_clk, TIMER_FREQ, +get_ticks_per_sec()); +last_clk = now; + +if ((env-ttmr TTMR_TP) = (env-ttcr TTMR_TP)) { +wait = TTMR_TP - (env-ttcr TTMR_TP) + 1; +wait += env-ttmr TTMR_TP; +} else { +wait = (env-ttmr TTMR_TP) - (env-ttcr TTMR_TP); +} + +next = now + muldiv64(wait, get_ticks_per_sec(), TIMER_FREQ); +qemu_mod_timer(env-timer, next); +} + +static void count_start(CPUOpenRISCState *env) +{ +is_counting = 1; +count_update(env); +} + +static void count_stop(CPUOpenRISCState *env) +{ +is_counting = 0; +count_update(env); +} + +uint32_t cpu_openrisc_get_count(CPUOpenRISCState *env) +{ +count_update(env); +return env-ttcr; +} + +void cpu_openrisc_store_count(CPUOpenRISCState *env, uint32_t count) +{ +/* Store new count register */ +env-ttcr = count; +if (env-ttmr TIMER_NONE) { +return; +} +count_start(env); +} + +void cpu_openrisc_store_compare(CPUOpenRISCState *env, uint32_t value) +{ +int ip = env-ttmr TTMR_IP; + +if (value TTMR_IP) { /* Keep IP bit */ +env-ttmr = (value ~TTMR_IP) + ip; +} else { /* Clear IP bit */ +env-ttmr = value ~TTMR_IP; +env-interrupt_request = ~CPU_INTERRUPT_TIMER; +} +count_update(env); + +switch (env-ttmr TTMR_M) { +case TIMER_NONE: +count_stop(env); +break; +case TIMER_INTR: +count_start(env); +break; +case TIMER_SHOT: +count_start(env); +break; +case TIMER_CONT: +count_start(env); +break; +} +} + +static void openrisc_timer_cb(void *opaque) +{ +CPUOpenRISCState *env = opaque; + +if ((env-ttmr TTMR_IE) + qemu_timer_expired(env-timer, qemu_get_clock_ns(vm_clock))) { +env-ttmr |= TTMR_IP; +env-interrupt_request |= CPU_INTERRUPT_TIMER; +} + +switch (env-ttmr TTMR_M) { +case TIMER_NONE: +break; +case TIMER_INTR: +env-ttcr = 0; +count_start(env); +break; +case TIMER_SHOT: +count_stop(env); +break; +case TIMER_CONT: +count_start(env); +break; +} +} + +void cpu_openrisc_clock_init(CPUOpenRISCState *env) +{ +env-timer = qemu_new_timer_ns(vm_clock, openrisc_timer_cb, env); +env-ttmr = 0; +env-ttcr = 0; +} -- 1.7.9.5
[Qemu-devel] [PATCH v13 04/13] Add cache handling functions
Add LRU page cache mechanism. The page are accessed by their address. Signed-off-by: Benoit Hudzia benoit.hud...@sap.com Signed-off-by: Petter Svard pett...@cs.umu.se Signed-off-by: Aidan Shribman aidan.shrib...@sap.com Signed-off-by: Orit Wasserman owass...@redhat.com --- Makefile.objs|1 + cache.c | 217 ++ include/qemu/cache.h | 79 ++ qemu-common.h| 10 +++ 4 files changed, 307 insertions(+), 0 deletions(-) create mode 100644 cache.c create mode 100644 include/qemu/cache.h diff --git a/Makefile.objs b/Makefile.objs index 625c4d5..d9c6859 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -77,6 +77,7 @@ common-obj-y += qemu-char.o #aio.o common-obj-y += block-migration.o iohandler.o common-obj-y += pflib.o common-obj-y += bitmap.o bitops.o +common-obj-y += cache.o common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o common-obj-$(CONFIG_WIN32) += version.o diff --git a/cache.c b/cache.c new file mode 100644 index 000..729fc64 --- /dev/null +++ b/cache.c @@ -0,0 +1,217 @@ +/* + * Page cache for qemu + * The cache is base on a hash on the page address + * + * Copyright 2012 Red Hat, Inc. and/or its affiliates + * + * Authors: + * Orit Wasserman owass...@redhat.com + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include stdint.h +#include stdio.h +#include stdlib.h +#include strings.h +#include string.h +#include sys/time.h +#include sys/types.h +#include stdbool.h +#include glib.h +#include strings.h + +#include qemu-common.h +#include qemu/cache.h + +#ifdef DEBUG_CACHE +#define DPRINTF(fmt, ...) \ +do { fprintf(stdout, cache: fmt, ## __VA_ARGS__); } while (0) +#else +#define DPRINTF(fmt, ...) \ +do { } while (0) +#endif + +typedef struct CacheItem CacheItem; + +struct CacheItem { +uint64_t it_addr; +unsigned long it_age; +uint8_t *it_data; +}; + +struct Cache { +CacheItem *page_cache; +unsigned int page_size; +int64_t max_num_items; +uint64_t max_item_age; +int64_t num_items; +}; + +Cache *cache_init(int64_t num_pages, unsigned int page_size) +{ +int i; + +Cache *cache = g_malloc(sizeof(Cache)); +if (!cache) { +DPRINTF(Error allocation Cache\n); +return NULL; +} + +if (num_pages = 0) { +DPRINTF(invalid number pages\n); +return NULL; +} + +/* round down to the nearest power of 2 */ +if (!is_power_of_2(num_pages)) { +num_pages = 1 ffs(num_pages); +DPRINTF(rounding down to %ld\n, num_pages); +} +cache-page_size = page_size; +cache-num_items = 0; +cache-max_item_age = 0; +cache-max_num_items = num_pages; + +DPRINTF(Setting cache buckets to %lu\n, cache-max_num_items); + +cache-page_cache = g_malloc((cache-max_num_items) * + sizeof(CacheItem)); +if (!cache-page_cache) { +DPRINTF(could not allocate cache\n); +g_free(cache); +return NULL; +} + +for (i = 0; i cache-max_num_items; i++) { +cache-page_cache[i].it_data = NULL; +cache-page_cache[i].it_age = 0; +cache-page_cache[i].it_addr = -1; +} + +return cache; +} + +void cache_fini(Cache *cache) +{ +int i; + +g_assert(cache); +g_assert(cache-page_cache); + +for (i = 0; i cache-max_num_items; i++) { +g_free(cache-page_cache[i].it_data); +cache-page_cache[i].it_data = 0; +} + +g_free(cache-page_cache); +cache-page_cache = NULL; +} + +static unsigned long cache_get_cache_pos(const Cache *cache, uint64_t address) +{ +unsigned long pos; + +g_assert(cache-max_num_items); +pos = (address/cache-page_size) (cache-max_num_items - 1); +return pos; +} + +bool cache_is_cached(const Cache *cache, uint64_t addr) +{ +unsigned long pos; + +g_assert(cache); +g_assert(cache-page_cache); + +pos = cache_get_cache_pos(cache, addr); + +return (cache-page_cache[pos].it_addr == addr); +} + +static CacheItem *cache_get_by_addr(const Cache *cache, uint64_t addr) +{ +unsigned long pos; + +g_assert(cache); +g_assert(cache-page_cache); + +pos = cache_get_cache_pos(cache, addr); + +return cache-page_cache[pos]; +} + +uint8_t *get_cached_data(const Cache *cache, uint64_t addr) +{ +return cache_get_by_addr(cache, addr)-it_data; +} + +void cache_insert(Cache *cache, unsigned long addr, uint8_t *pdata) +{ + +CacheItem *it = NULL; + +g_assert(cache); +g_assert(cache-page_cache); + +/* actual update of entry */ +it = cache_get_by_addr(cache, addr); + +if (!it-it_data) { +cache-num_items++; +} + +it-it_data = pdata; +it-it_age = ++cache-max_item_age; +it-it_addr = addr; +} + +int cache_resize(Cache *cache, int64_t new_num_pages) +{ +Cache *new_cache; +int
[Qemu-devel] [PATCH v13 05/13] Add uleb encoding/decoding functions
Implement Unsigned Little Endian Base 128. Signed-off-by: Orit Wasserman owass...@redhat.com --- cutils.c | 32 qemu-common.h |8 2 files changed, 40 insertions(+), 0 deletions(-) diff --git a/cutils.c b/cutils.c index af308cd..3f81d53 100644 --- a/cutils.c +++ b/cutils.c @@ -549,3 +549,35 @@ int qemu_sendv(int sockfd, struct iovec *iov, int len, int iov_offset) return do_sendv_recvv(sockfd, iov, len, iov_offset, 1); } +/* + * Implementation of ULEB128 (http://en.wikipedia.org/wiki/LEB128) + * Input is limited to 14-bit numbers + */ +int uleb128_encode_small(uint8_t *out, uint32_t n) +{ +g_assert(n = 0x3fff); +if (n 0x80) { +*out++ = n; +return 1; +} else { +*out++ = (n 0x7f) | 0x80; +*out++ = n 7; +return 2; +} +} + +int uleb128_decode_small(const uint8_t *in, uint32_t *n) +{ +if (!(*in 0x80)) { +*n = *in++; +return 1; +} else { +*n = *in++ 0x7f; +/* we exceed 14 bit number */ +if (*in 0x80) { +return -1; +} +*n |= *in++ 7; +return 2; +} +} diff --git a/qemu-common.h b/qemu-common.h index 45b1d97..f7875ae 100644 --- a/qemu-common.h +++ b/qemu-common.h @@ -429,4 +429,12 @@ static inline bool is_power_of_2(int64_t value) #include module.h +/* + * Implementation of ULEB128 (http://en.wikipedia.org/wiki/LEB128) + * Input is limited to 14-bit numbers + */ + +int uleb128_encode_small(uint8_t *out, uint32_t n); +int uleb128_decode_small(const uint8_t *in, uint32_t *n); + #endif -- 1.7.7.6
[Qemu-devel] race condition in qemu-kvm-1.0.1
Hi, we recently came across multiple VMs racing and stopping working. It seems to happen when the system is at 100% cpu. One way to reproduce this is: qemu-kvm-1.0.1 with vnc-thread enabled cmdline (or similar): /usr/bin/qemu-kvm-1.0.1 -net tap,vlan=141,script=no,downscript=no,ifname=tap15,vnet_hdr -net nic,vlan=141,model=virtio,macaddr=52:54:00:ff:00:f7 -drive format=host_device,file=/dev/mapper/iqn.2001-05.com.equallogic:0-8a0906-efdf4e007-16700198c7f4fead-02-debug-race-hd01,if=virtio,cache=none,aio=native -m 2048 -smp 2,sockets=1,cores=2,threads=1 -monitor tcp:0:4026,server,nowait -vnc :26 -qmp tcp:0:3026,server,nowait -name 02-debug-race -boot order=dc,menu=off -cdrom /home/kvm/cdrom//root/ubuntu-12.04-server-amd64.iso -k de -pidfile /var/run/qemu/vm-221.pid -mem-prealloc -cpu host,+x2apic,model_id=Intel(R) Xeon(R) CPU L5640 @ 2.27GHz,-tsc -rtc base=utc -usb -usbdevice tablet -no-hpet -vga cirrus it is important that the attached virtio image contains only zeroes. if the system boots from cd, select boot from first harddisk. the hypervisor then hangs at 100% cpu and neither monitor nor qmp are responsive anymore. i have also seen customers reporting this when a VM is shut down. if this is connected to the threaded vnc server it might be important to connected at this time. debug backtrace attached. Thanks, Peter -- (gdb) file /usr/bin/qemu-kvm-1.0.1 Reading symbols from /usr/bin/qemu-kvm-1.0.1...done. (gdb) attach 5145 Attaching to program: /usr/bin/qemu-kvm-1.0.1, process 5145 Reading symbols from /lib64/ld-linux-x86-64.so.2...(no debugging symbols found)...done. Loaded symbols for /lib64/ld-linux-x86-64.so.2 [Thread debugging using libthread_db enabled] [New Thread 0x7f54d08b9700 (LWP 5253)] [New Thread 0x7f5552757700 (LWP 5152)] [New Thread 0x7f5552f58700 (LWP 5151)] 0x7f5553c6b5a3 in select () from /lib/libc.so.6 (gdb) info threads 4 Thread 0x7f5552f58700 (LWP 5151) 0x7f5553c6a747 in ioctl () from /lib/libc.so.6 3 Thread 0x7f5552757700 (LWP 5152) 0x7f5553c6a747 in ioctl () from /lib/libc.so.6 2 Thread 0x7f54d08b9700 (LWP 5253) 0x7f5553f1a85c in pthread_cond_wait@@GLIBC_2.3.2 () from /lib/libpthread.so.0 * 1 Thread 0x7f50d700 (LWP 5145) 0x7f5553c6b5a3 in select () from /lib/libc.so.6 (gdb) thread apply all bt Thread 4 (Thread 0x7f5552f58700 (LWP 5151)): #0 0x7f5553c6a747 in ioctl () from /lib/libc.so.6 #1 0x7f727830 in kvm_vcpu_ioctl (env=0x7f5557652f10, type=44672) at /usr/src/qemu-kvm-1.0.1/kvm-all.c:1101 #2 0x7f72728a in kvm_cpu_exec (env=0x7f5557652f10) at /usr/src/qemu-kvm-1.0.1/kvm-all.c:987 #3 0x7f6f5c08 in qemu_kvm_cpu_thread_fn (arg=0x7f5557652f10) at /usr/src/qemu-kvm-1.0.1/cpus.c:740 #4 0x7f5553f159ca in start_thread () from /lib/libpthread.so.0 #5 0x7f5553c72cdd in clone () from /lib/libc.so.6 #6 0x in ?? () Thread 3 (Thread 0x7f5552757700 (LWP 5152)): #0 0x7f5553c6a747 in ioctl () from /lib/libc.so.6 #1 0x7f727830 in kvm_vcpu_ioctl (env=0x7f555766ae60, type=44672) at /usr/src/qemu-kvm-1.0.1/kvm-all.c:1101 #2 0x7f72728a in kvm_cpu_exec (env=0x7f555766ae60) at /usr/src/qemu-kvm-1.0.1/kvm-all.c:987 #3 0x7f6f5c08 in qemu_kvm_cpu_thread_fn (arg=0x7f555766ae60) at /usr/src/qemu-kvm-1.0.1/cpus.c:740 #4 0x7f5553f159ca in start_thread () from /lib/libpthread.so.0 #5 0x7f5553c72cdd in clone () from /lib/libc.so.6 #6 0x in ?? () Thread 2 (Thread 0x7f54d08b9700 (LWP 5253)): #0 0x7f5553f1a85c in pthread_cond_wait@@GLIBC_2.3.2 () from /lib/libpthread.so.0 #1 0x7f679f5d in qemu_cond_wait (cond=0x7f5557ede1e0, mutex=0x7f5557ede210) at qemu-thread-posix.c:113 #2 0x7f6b06a1 in vnc_worker_thread_loop (queue=0x7f5557ede1e0) at ui/vnc-jobs-async.c:222 #3 0x7f6b0b7f in vnc_worker_thread (arg=0x7f5557ede1e0) at ui/vnc-jobs-async.c:318 #4 0x7f5553f159ca in start_thread () from /lib/libpthread.so.0 #5 0x7f5553c72cdd in clone () from /lib/libc.so.6 #6 0x in ?? () Thread 1 (Thread 0x7f50d700 (LWP 5145)): #0 0x7f5553c6b5a3 in select () from /lib/libc.so.6 #1 0x7f6516be in main_loop_wait (nonblocking=0) at main-loop.c:456 #2 0x7f647ad0 in main_loop () at /usr/src/qemu-kvm-1.0.1/vl.c:1482 #3 0x7f64c698 in main (argc=38, argv=0x79d894a8, envp=0x79d895e0) at /usr/src/qemu-kvm-1.0.1/vl.c:3523 (gdb) thread apply all bt full Thread 4 (Thread 0x7f5552f58700 (LWP 5151)): #0 0x7f5553c6a747 in ioctl () from /lib/libc.so.6 No symbol table info available. #1 0x7f727830 in kvm_vcpu_ioctl (env=0x7f5557652f10, type=44672) at /usr/src/qemu-kvm-1.0.1/kvm-all.c:1101 ret = 32597 arg = 0x0 ap = {{gp_offset = 24, fp_offset = 48, overflow_arg_area = 0x7f5552f57e50, reg_save_area = 0x7f5552f57d90}} #2 0x7f72728a in kvm_cpu_exec (env=0x7f5557652f10) at
[Qemu-devel] [PATCH v13 09/13] Add migration_end function
Signed-off-by: Orit Wasserman owass...@redhat.com --- arch_init.c |7 ++- 1 files changed, 6 insertions(+), 1 deletions(-) diff --git a/arch_init.c b/arch_init.c index ef7b4d6..6703c72 100644 --- a/arch_init.c +++ b/arch_init.c @@ -304,6 +304,11 @@ static void sort_ram_list(void) g_free(blocks); } +static void migration_end(void) +{ +memory_global_dirty_log_stop(); +} + int ram_save_live(QEMUFile *f, int stage, void *opaque) { ram_addr_t addr; @@ -313,7 +318,7 @@ int ram_save_live(QEMUFile *f, int stage, void *opaque) int ret; if (stage 0) { -memory_global_dirty_log_stop(); +migration_end(); return 0; } -- 1.7.7.6
[Qemu-devel] [PATCH v13 13/13] Add XBZRLE statistics
Signed-off-by: Benoit Hudzia benoit.hud...@sap.com Signed-off-by: Petter Svard pett...@cs.umu.se Signed-off-by: Aidan Shribman aidan.shrib...@sap.com Signed-off-by: Orit Wasserman owass...@redhat.com --- arch_init.c | 68 +- hmp.c| 13 ++ migration.c | 38 ++ migration.h |9 +++ qapi-schema.json | 40 +++ qmp-commands.hx | 38 - 6 files changed, 198 insertions(+), 8 deletions(-) diff --git a/arch_init.c b/arch_init.c index ae7c8b1..84a2e2a 100644 --- a/arch_init.c +++ b/arch_init.c @@ -201,8 +201,66 @@ void xbzrle_cache_resize(int64_t new_size) } } +/* accounting */ +typedef struct AccountingInfo { +uint64_t dup_pages; +uint64_t norm_pages; +uint64_t xbzrle_bytes; +uint64_t xbzrle_pages; +uint64_t xbzrle_cache_miss; +uint64_t iterations; +uint64_t xbzrle_overflows; +} AccountingInfo; + +static AccountingInfo acct_info; + +static void acct_clear(void) +{ +memset(acct_info, 0, sizeof(acct_info)); +} + +uint64_t dup_mig_bytes_transferred(void) +{ +return acct_info.dup_pages * TARGET_PAGE_SIZE; +} + +uint64_t dup_mig_pages_transferred(void) +{ +return acct_info.dup_pages; +} + +uint64_t norm_mig_bytes_transferred(void) +{ +return acct_info.norm_pages * TARGET_PAGE_SIZE; +} + +uint64_t norm_mig_pages_transferred(void) +{ +return acct_info.norm_pages; +} + +uint64_t xbzrle_mig_bytes_transferred(void) +{ +return acct_info.xbzrle_bytes; +} + +uint64_t xbzrle_mig_pages_transferred(void) +{ +return acct_info.xbzrle_pages; +} + +uint64_t xbzrle_mig_pages_cache_miss(void) +{ +return acct_info.xbzrle_cache_miss; +} + +uint64_t xbzrle_mig_pages_overflow(void) +{ +return acct_info.xbzrle_overflows; +} + static void save_block_hdr(QEMUFile *f, RAMBlock *block, ram_addr_t offset, -int cont, int flag) + int cont, int flag) { qemu_put_be64(f, offset | cont | flag); if (!cont) { @@ -233,6 +291,7 @@ static int save_xbzrle_page(QEMUFile *f, uint8_t *current_data, if (stage == 1 || !cache_is_cached(XBZRLE.cache, current_addr)) { cache_insert(XBZRLE.cache, current_addr, g_memdup(current_data, TARGET_PAGE_SIZE)); +acct_info.xbzrle_cache_miss++; return -1; } @@ -247,6 +306,7 @@ static int save_xbzrle_page(QEMUFile *f, uint8_t *current_data, return 0; } else if (encoded_len == -1) { DPRINTF(Overflow\n); +acct_info.xbzrle_overflows++; /* update data in the cache */ memcpy(prev_cached_page, current_data, TARGET_PAGE_SIZE); return -1; @@ -266,7 +326,9 @@ static int save_xbzrle_page(QEMUFile *f, uint8_t *current_data, qemu_put_byte(f, hdr.xh_flags); qemu_put_be16(f, hdr.xh_len); qemu_put_buffer(f, XBZRLE.encoded_buf, encoded_len); +acct_info.xbzrle_pages++; bytes_sent = encoded_len + sizeof(hdr); +acct_info.xbzrle_bytes += bytes_sent; return bytes_sent; } @@ -300,6 +362,7 @@ static int ram_save_block(QEMUFile *f, int stage) p = memory_region_get_ram_ptr(mr) + offset; if (is_dup_page(p)) { +acct_info.dup_pages++; save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_COMPRESS); qemu_put_byte(f, *p); bytes_sent = 1; @@ -322,6 +385,7 @@ static int ram_save_block(QEMUFile *f, int stage) save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_PAGE); qemu_put_buffer(f, p, TARGET_PAGE_SIZE); bytes_sent = TARGET_PAGE_SIZE; +acct_info.norm_pages++; } /* if page is unmodified lets continue to the next */ @@ -458,6 +522,7 @@ int ram_save_live(QEMUFile *f, int stage, void *opaque) return -1; } XBZRLE.encoded_buf = g_malloc0(TARGET_PAGE_SIZE); +acct_clear(); } /* Make sure all dirty bits are set */ @@ -492,6 +557,7 @@ int ram_save_live(QEMUFile *f, int stage, void *opaque) bytes_sent -1 represent no more blocks*/ if (bytes_sent 0) { bytes_transferred += bytes_sent; +acct_info.iterations++; } else if (bytes_sent == -1) { /* no more blocks */ break; } diff --git a/hmp.c b/hmp.c index 0a27d2d..b4d2f48 100644 --- a/hmp.c +++ b/hmp.c @@ -166,6 +166,19 @@ void hmp_info_migrate(Monitor *mon) info-disk-total 10); } +if (info-has_cache) { +monitor_printf(mon, cache size: % PRIu64 bytes\n, + info-cache-cache_size); +monitor_printf(mon, xbzrle transferred: % PRIu64 kbytes\n, + info-cache-xbzrle_bytes 10); +monitor_printf(mon, xbzrle pages: % PRIu64
Re: [Qemu-devel] [PATCH v7 08/16] target-or32: Add instruction translation
On Wed, Jun 27, 2012 at 1:54 PM, Jia Liu pro...@gmail.com wrote: Add OpenRISC instruction tanslation routines. Signed-off-by: Jia Liu pro...@gmail.com [...] + case 0x0009: + switch (op1) { + case 0x03: /* l.div */ + LOG_DIS(l.div r%d, r%d, r%d\n, rd, ra, rb); + { + int lab0 = gen_new_label(); + int lab1 = gen_new_label(); + int lab2 = gen_new_label(); + int lab3 = gen_new_label(); + TCGv_i32 sr_ove = tcg_temp_local_new_i32(); + if (rb == 0) { + tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY)); + tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE); + tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab0); + gen_exception(dc, EXCP_RANGE); + gen_set_label(lab0); + } else { + tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_R[rb], + 0x, lab1); + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[ra], + 0x8000, lab2); + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[rb], + 0x, lab2); + gen_set_label(lab1); + tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY)); + tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE); + tcg_gen_brcondi_tl(TCG_COND_EQ, sr_ove, SR_OVE, lab3); You used to have tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab2) here in previous series, why do you change NE to EQ? + gen_exception(dc, EXCP_RANGE); + gen_set_label(lab2); + tcg_gen_div_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); + gen_set_label(lab3); + } + tcg_temp_free_i32(sr_ove); + } + break; + + default: + gen_illegal_exception(dc); + break; + } + break; + + case 0x000a: + switch (op1) { + case 0x03: /* l.divu */ + LOG_DIS(l.divu r%d, r%d, r%d\n, rd, ra, rb); + { + int lab0 = gen_new_label(); + int lab1 = gen_new_label(); + int lab2 = gen_new_label(); + TCGv_i32 sr_ove = tcg_temp_local_new_i32(); + if (rb == 0) { + tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY)); + tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE); + tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab0); + gen_exception(dc, EXCP_RANGE); + gen_set_label(lab0); + } else { + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[rb], + 0x, lab1); + tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY)); + tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE); + tcg_gen_brcondi_tl(TCG_COND_EQ, sr_ove, SR_OVE, lab2); Same here. + gen_exception(dc, EXCP_RANGE); + gen_set_label(lab1); + tcg_gen_divu_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); + gen_set_label(lab2); + } + tcg_temp_free_i32(sr_ove); + } + break; -- Thanks. -- Max
[Qemu-devel] [PATCH v7 08/16] target-or32: Add instruction translation
Add OpenRISC instruction tanslation routines. Signed-off-by: Jia Liu pro...@gmail.com --- target-openrisc/translate.c | 1680 +++ 1 file changed, 1680 insertions(+) diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c index 1d87d76..ce99e49 100644 --- a/target-openrisc/translate.c +++ b/target-openrisc/translate.c @@ -26,6 +26,10 @@ #include qemu-log.h #include config.h +#include helper.h +#define GEN_HELPER 1 +#include helper.h + #define OPENRISC_DISAS #ifdef OPENRISC_DISAS @@ -34,14 +38,1690 @@ # define LOG_DIS(...) do { } while (0) #endif +typedef struct DisasContext { +CPUOpenRISCState *env; +TranslationBlock *tb; +target_ulong pc, ppc, npc; +uint32_t tb_flags, synced_flags, flags; +uint32_t is_jmp; +uint32_t mem_idx; +int singlestep_enabled; +uint32_t delayed_branch; +} DisasContext; + +static TCGv_ptr cpu_env; +static TCGv cpu_sr; +static TCGv cpu_R[32]; +static TCGv cpu_pc; +static TCGv jmp_pc;/* l.jr/l.jalr temp pc */ +static TCGv cpu_npc; +static TCGv cpu_ppc; +static TCGv_i32 env_btaken;/* bf/bnf , F flag taken */ +static TCGv_i32 fpcsr; +static TCGv machi, maclo; +static TCGv fpmaddhi, fpmaddlo; +static TCGv_i32 env_flags; +#include gen-icount.h + void openrisc_translate_init(void) { +static const char * const regnames[] = { +r0, r1, r2, r3, r4, r5, r6, r7, +r8, r9, r10, r11, r12, r13, r14, r15, +r16, r17, r18, r19, r20, r21, r22, r23, +r24, r25, r26, r27, r28, r29, r30, r31, +}; +int i; + +cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, env); +cpu_sr = tcg_global_mem_new(TCG_AREG0, +offsetof(CPUOpenRISCState, sr), sr); +env_flags = tcg_global_mem_new_i32(TCG_AREG0, + offsetof(CPUOpenRISCState, flags), + flags); +cpu_pc = tcg_global_mem_new(TCG_AREG0, +offsetof(CPUOpenRISCState, pc), pc); +cpu_npc = tcg_global_mem_new(TCG_AREG0, + offsetof(CPUOpenRISCState, npc), npc); +cpu_ppc = tcg_global_mem_new(TCG_AREG0, + offsetof(CPUOpenRISCState, ppc), ppc); +jmp_pc = tcg_global_mem_new(TCG_AREG0, +offsetof(CPUOpenRISCState, jmp_pc), jmp_pc); +env_btaken = tcg_global_mem_new_i32(TCG_AREG0, +offsetof(CPUOpenRISCState, btaken), +btaken); +fpcsr = tcg_global_mem_new_i32(TCG_AREG0, + offsetof(CPUOpenRISCState, fpcsr), + fpcsr); +machi = tcg_global_mem_new(TCG_AREG0, + offsetof(CPUOpenRISCState, machi), + machi); +maclo = tcg_global_mem_new(TCG_AREG0, + offsetof(CPUOpenRISCState, maclo), + maclo); +fpmaddhi = tcg_global_mem_new(TCG_AREG0, + offsetof(CPUOpenRISCState, fpmaddhi), + fpmaddhi); +fpmaddlo = tcg_global_mem_new(TCG_AREG0, + offsetof(CPUOpenRISCState, fpmaddlo), + fpmaddlo); +for (i = 0; i 32; i++) { +cpu_R[i] = tcg_global_mem_new(TCG_AREG0, + offsetof(CPUOpenRISCState, gpr[i]), + regnames[i]); +} +#define GEN_HELPER 2 +#include helper.h +} + +/* Writeback SR_F transaltion-space to execution-space. */ +static inline void wb_SR_F(void) +{ +int label; + +label = gen_new_label(); +tcg_gen_andi_tl(cpu_sr, cpu_sr, ~SR_F); +tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, label); +tcg_gen_ori_tl(cpu_sr, cpu_sr, SR_F); +gen_set_label(label); +} + +static inline int zero_extend(unsigned int val, int width) +{ +return val ((1 width) - 1); +} + +static inline int sign_extend(unsigned int val, int width) +{ +int sval; + +/* LSL */ +val = TARGET_LONG_BITS - width; +sval = val; +/* ASR. */ +sval = TARGET_LONG_BITS - width; +return sval; +} + +static inline void gen_sync_flags(DisasContext *dc) +{ +/* Sync the tb dependent flag between translate and runtime. */ +if (dc-tb_flags != dc-synced_flags) { +tcg_gen_movi_tl(env_flags, dc-tb_flags); +dc-synced_flags = dc-tb_flags; +} +} + +static void gen_exception(DisasContext *dc, unsigned int excp) +{ +TCGv_i32 tmp = tcg_const_i32(excp); +gen_helper_exception(cpu_env, tmp); +tcg_temp_free_i32(tmp); +} + +static void gen_illegal_exception(DisasContext *dc) +{ +tcg_gen_movi_tl(cpu_pc, dc-pc); +gen_exception(dc, EXCP_ILLEGAL); +dc-is_jmp = DISAS_UPDATE; +} + +#ifdef TARGET_OPENRISC64 +static void check_ob64s(DisasContext *dc) +{ +if
[Qemu-devel] [PATCH v13 02/13] Add migration capabilites
Add migration capabilites that can be queried by the management. The management can query the source QEMU and the destination QEMU in order to verify both support some migration capability (currently only XBZRLE). The managment can enable a capability for the next migration by using migrate_set_parameter command. Signed-off-by: Orit Wasserman owass...@redhat.com --- hmp-commands.hx | 16 hmp.c| 63 + hmp.h|2 + migration.c | 69 - migration.h |2 + monitor.c|7 + qapi-schema.json | 46 +++- qmp-commands.hx | 50 +++ 8 files changed, 252 insertions(+), 3 deletions(-) diff --git a/hmp-commands.hx b/hmp-commands.hx index f5d9d91..a0c8df2 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -861,6 +861,20 @@ Set maximum tolerated downtime (in seconds) for migration. ETEXI { +.name = migrate_set_parameter, +.args_type = capability:s,state:b, +.params = , +.help = Enable the usage of a capability for migration, +.mhandler.cmd = hmp_migrate_set_parameter, +}, + +STEXI +@item migrate_set_parameter @var{capability} @var{state} +@findex migrate_set_parameter +Enable/Disable the usage of a capability @var{capability} for migration. +ETEXI + +{ .name = client_migrate_info, .args_type = protocol:s,hostname:s,port:i?,tls-port:i?,cert-subject:s?, .params = protocol hostname port tls-port cert-subject, @@ -1419,6 +1433,8 @@ show CPU statistics show user network stack connection states @item info migrate show migration status +@item info migration_capabilities +show migration capabilities @item info balloon show balloon information @item info qtree diff --git a/hmp.c b/hmp.c index b9cec1d..c275fab 100644 --- a/hmp.c +++ b/hmp.c @@ -131,9 +131,19 @@ void hmp_info_mice(Monitor *mon) void hmp_info_migrate(Monitor *mon) { MigrationInfo *info; +MigrationCapabilityInfoList *cap; info = qmp_query_migrate(NULL); +if (info-has_params info-params) { +monitor_printf(mon, params: ); +for (cap = info-params; cap; cap = cap-next) { +monitor_printf(mon, %s: %s , + MigrationCapability_lookup[cap-value-capability], + cap-value-state ? on : off); +} +monitor_printf(mon, \n); +} if (info-has_status) { monitor_printf(mon, Migration status: %s\n, info-status); } @@ -159,6 +169,24 @@ void hmp_info_migrate(Monitor *mon) qapi_free_MigrationInfo(info); } +void hmp_info_migration_capabilities(Monitor *mon) +{ +MigrationCapabilityInfoList *caps_list, *cap; + +caps_list = qmp_query_migration_capabilities(NULL); +if (!caps_list) { +monitor_printf(mon, No migration capabilities found\n); +return; +} + +for (cap = caps_list; cap; cap = cap-next) { +monitor_printf(mon, %s , + MigrationCapability_lookup[cap-value-capability]); +} + +qapi_free_MigrationCapabilityInfoList(caps_list); +} + void hmp_info_cpus(Monitor *mon) { CpuInfoList *cpu_list, *cpu; @@ -733,6 +761,41 @@ void hmp_migrate_set_speed(Monitor *mon, const QDict *qdict) qmp_migrate_set_speed(value, NULL); } +void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict) +{ +const char *cap = qdict_get_str(qdict, capability); +bool state = qdict_get_bool(qdict, state); +Error *err = NULL; +MigrationCapabilityInfoList *params = NULL; +int i; + +for (i = 0; i MIGRATION_CAPABILITY_MAX; i++) { +if (strcmp(cap, MigrationCapability_lookup[i]) == 0) { +if (!params) { +params = g_malloc0(sizeof(*params)); +} +params-value = g_malloc0(sizeof(*params-value)); +params-value-capability = i; +params-value-state = state; +params-next = NULL; +qmp_migrate_set_parameters(params, err); +break; +} +} + +if (i == MIGRATION_CAPABILITY_MAX) { +error_set(err, QERR_INVALID_PARAMETER, cap); +} + +qapi_free_MigrationCapabilityInfoList(params); + +if (err) { +monitor_printf(mon, migrate_set_parameter: %s\n, + error_get_pretty(err)); +error_free(err); +} +} + void hmp_set_password(Monitor *mon, const QDict *qdict) { const char *protocol = qdict_get_str(qdict, protocol); diff --git a/hmp.h b/hmp.h index 79d138d..09ba198 100644 --- a/hmp.h +++ b/hmp.h @@ -25,6 +25,7 @@ void hmp_info_uuid(Monitor *mon); void hmp_info_chardev(Monitor *mon); void hmp_info_mice(Monitor *mon); void hmp_info_migrate(Monitor *mon); +void hmp_info_migration_capabilities(Monitor *mon); void hmp_info_cpus(Monitor
[Qemu-devel] [PATCH v7 06/16] target-or32: Add int instruction helpers
Add OpenRISC int instruction helpers. Signed-off-by: Jia Liu pro...@gmail.com --- target-openrisc/Makefile.objs |2 +- target-openrisc/helper.h |5 +++ target-openrisc/int_helper.c | 85 + 3 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 target-openrisc/int_helper.c diff --git a/target-openrisc/Makefile.objs b/target-openrisc/Makefile.objs index 382190a..4286462 100644 --- a/target-openrisc/Makefile.objs +++ b/target-openrisc/Makefile.objs @@ -1,3 +1,3 @@ obj-$(CONFIG_SOFTMMU) += machine.o obj-y += cpu.o excp.o intrpt.o mmu.o translate.o -obj-y += excp_helper.o intrpt_helper.o mmu_helper.o +obj-y += excp_helper.o int_helper.o intrpt_helper.o mmu_helper.o diff --git a/target-openrisc/helper.h b/target-openrisc/helper.h index 4e2a49f..c772951 100644 --- a/target-openrisc/helper.h +++ b/target-openrisc/helper.h @@ -22,6 +22,11 @@ /* exception */ DEF_HELPER_FLAGS_2(exception, 0, void, env, i32) +/* int */ +DEF_HELPER_FLAGS_1(ff1, 0, tl, tl) +DEF_HELPER_FLAGS_1(fl1, 0, tl, tl) +DEF_HELPER_FLAGS_3(mul32, 0, tl, env, tl, tl) + /* interrupt */ DEF_HELPER_FLAGS_1(rfe, 0, void, env) diff --git a/target-openrisc/int_helper.c b/target-openrisc/int_helper.c new file mode 100644 index 000..09cd70a --- /dev/null +++ b/target-openrisc/int_helper.c @@ -0,0 +1,85 @@ +/* + * OpenRISC int helper routines + * + * Copyright (c) 2011-2012 Jia Liu pro...@gmail.com + * Feng Gao gf91...@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see http://www.gnu.org/licenses/. + */ + +#include cpu.h +#include helper.h +#include excp.h + +target_ulong HELPER(ff1)(target_ulong x) +{ +target_ulong n = 0; + +if (x == 0) { +return 0; +} + +for (n = 32; x; n--) { +x = 1; +} +return n+1; +} + +target_ulong HELPER(fl1)(target_ulong x) +{ +target_ulong n = 0; + +if (x == 0) { +return 0; +} + +for (n = 0; x; n++) { +x = 1; +} +return n; +} + +target_ulong HELPER(mul32)(CPUOpenRISCState *env, + target_ulong ra, target_ulong rb) +{ +uint64_t result; +target_ulong high, cy; + +result = ra * rb; +/* regisiers in or32 is 32bit, so 32 is NOT a magic number. + or64 is not handled in this function, and not implement yet, + TARGET_LONG_BITS for or64 is 64, it will break this function, + so, we didn't use TARGET_LONG_BITS here. */ +high = result 32; +cy = result (32 - 1); + +if ((cy 0x1) == 0x0) { +if (high == 0x0) { +return result; +} +} + +if ((cy 0x1) == 0x1) { +if (high == 0x) { +return result; +} +} + +env-sr |= (SR_OV | SR_CY); +if (env-sr SR_OVE) { +raise_exception(env, EXCP_RANGE); +} + +return result; +} -- 1.7.9.5
[Qemu-devel] race condition in qemu-kvm-1.0.1
Hi, we recently came across multiple VMs racing and stopping working. It seems to happen when the system is at 100% cpu. One way to reproduce this is: qemu-kvm-1.0.1 with vnc-thread enabled cmdline (or similar): /usr/bin/qemu-kvm-1.0.1 -net tap,vlan=141,script=no,downscript=no,ifname=tap15,vnet_hdr -net nic,vlan=141,model=virtio,macaddr=52:54:00:ff:00:f7 -drive format=host_device,file=/dev/mapper/iqn.2001-05.com.equallogic:0-8a0906-efdf4e007-16700198c7f4fead-02-debug-race-hd01,if=virtio,cache=none,aio=native -m 2048 -smp 2,sockets=1,cores=2,threads=1 -monitor tcp:0:4026,server,nowait -vnc :26 -qmp tcp:0:3026,server,nowait -name 02-debug-race -boot order=dc,menu=off -cdrom /home/kvm/cdrom//root/ubuntu-12.04-server-amd64.iso -k de -pidfile /var/run/qemu/vm-221.pid -mem-prealloc -cpu host,+x2apic,model_id=Intel(R) Xeon(R) CPU L5640 @ 2.27GHz,-tsc -rtc base=utc -usb -usbdevice tablet -no-hpet -vga cirrus it is important that the attached virtio image contains only zeroes. if the system boots from cd, select boot from first harddisk. the hypervisor then hangs at 100% cpu and neither monitor nor qmp are responsive anymore. i have also seen customers reporting this when a VM is shut down. if this is connected to the threaded vnc server it might be important to connected at this time. debug backtrace attached. Thanks, Peter -- (gdb) file /usr/bin/qemu-kvm-1.0.1 Reading symbols from /usr/bin/qemu-kvm-1.0.1...done. (gdb) attach 5145 Attaching to program: /usr/bin/qemu-kvm-1.0.1, process 5145 Reading symbols from /lib64/ld-linux-x86-64.so.2...(no debugging symbols found)...done. Loaded symbols for /lib64/ld-linux-x86-64.so.2 [Thread debugging using libthread_db enabled] [New Thread 0x7f54d08b9700 (LWP 5253)] [New Thread 0x7f5552757700 (LWP 5152)] [New Thread 0x7f5552f58700 (LWP 5151)] 0x7f5553c6b5a3 in select () from /lib/libc.so.6 (gdb) info threads 4 Thread 0x7f5552f58700 (LWP 5151) 0x7f5553c6a747 in ioctl () from /lib/libc.so.6 3 Thread 0x7f5552757700 (LWP 5152) 0x7f5553c6a747 in ioctl () from /lib/libc.so.6 2 Thread 0x7f54d08b9700 (LWP 5253) 0x7f5553f1a85c in pthread_cond_wait@@GLIBC_2.3.2 () from /lib/libpthread.so.0 * 1 Thread 0x7f50d700 (LWP 5145) 0x7f5553c6b5a3 in select () from /lib/libc.so.6 (gdb) thread apply all bt Thread 4 (Thread 0x7f5552f58700 (LWP 5151)): #0 0x7f5553c6a747 in ioctl () from /lib/libc.so.6 #1 0x7f727830 in kvm_vcpu_ioctl (env=0x7f5557652f10, type=44672) at /usr/src/qemu-kvm-1.0.1/kvm-all.c:1101 #2 0x7f72728a in kvm_cpu_exec (env=0x7f5557652f10) at /usr/src/qemu-kvm-1.0.1/kvm-all.c:987 #3 0x7f6f5c08 in qemu_kvm_cpu_thread_fn (arg=0x7f5557652f10) at /usr/src/qemu-kvm-1.0.1/cpus.c:740 #4 0x7f5553f159ca in start_thread () from /lib/libpthread.so.0 #5 0x7f5553c72cdd in clone () from /lib/libc.so.6 #6 0x in ?? () Thread 3 (Thread 0x7f5552757700 (LWP 5152)): #0 0x7f5553c6a747 in ioctl () from /lib/libc.so.6 #1 0x7f727830 in kvm_vcpu_ioctl (env=0x7f555766ae60, type=44672) at /usr/src/qemu-kvm-1.0.1/kvm-all.c:1101 #2 0x7f72728a in kvm_cpu_exec (env=0x7f555766ae60) at /usr/src/qemu-kvm-1.0.1/kvm-all.c:987 #3 0x7f6f5c08 in qemu_kvm_cpu_thread_fn (arg=0x7f555766ae60) at /usr/src/qemu-kvm-1.0.1/cpus.c:740 #4 0x7f5553f159ca in start_thread () from /lib/libpthread.so.0 #5 0x7f5553c72cdd in clone () from /lib/libc.so.6 #6 0x in ?? () Thread 2 (Thread 0x7f54d08b9700 (LWP 5253)): #0 0x7f5553f1a85c in pthread_cond_wait@@GLIBC_2.3.2 () from /lib/libpthread.so.0 #1 0x7f679f5d in qemu_cond_wait (cond=0x7f5557ede1e0, mutex=0x7f5557ede210) at qemu-thread-posix.c:113 #2 0x7f6b06a1 in vnc_worker_thread_loop (queue=0x7f5557ede1e0) at ui/vnc-jobs-async.c:222 #3 0x7f6b0b7f in vnc_worker_thread (arg=0x7f5557ede1e0) at ui/vnc-jobs-async.c:318 #4 0x7f5553f159ca in start_thread () from /lib/libpthread.so.0 #5 0x7f5553c72cdd in clone () from /lib/libc.so.6 #6 0x in ?? () Thread 1 (Thread 0x7f50d700 (LWP 5145)): #0 0x7f5553c6b5a3 in select () from /lib/libc.so.6 #1 0x7f6516be in main_loop_wait (nonblocking=0) at main-loop.c:456 #2 0x7f647ad0 in main_loop () at /usr/src/qemu-kvm-1.0.1/vl.c:1482 #3 0x7f64c698 in main (argc=38, argv=0x79d894a8, envp=0x79d895e0) at /usr/src/qemu-kvm-1.0.1/vl.c:3523 (gdb) thread apply all bt full Thread 4 (Thread 0x7f5552f58700 (LWP 5151)): #0 0x7f5553c6a747 in ioctl () from /lib/libc.so.6 No symbol table info available. #1 0x7f727830 in kvm_vcpu_ioctl (env=0x7f5557652f10, type=44672) at /usr/src/qemu-kvm-1.0.1/kvm-all.c:1101 ret = 32597 arg = 0x0 ap = {{gp_offset = 24, fp_offset = 48, overflow_arg_area = 0x7f5552f57e50, reg_save_area = 0x7f5552f57d90}} #2 0x7f72728a in kvm_cpu_exec (env=0x7f5557652f10) at
[Qemu-devel] [PATCH v7 15/16] target-or32: Add linux user support
Add QEMU OpenRISC linux user support. Signed-off-by: Jia Liu pro...@gmail.com --- configure |1 + default-configs/or32-linux-user.mak |1 + linux-user/elfload.c| 41 +++ linux-user/main.c | 100 +++ linux-user/signal.c | 229 +++ linux-user/syscall.c|2 +- linux-user/syscall_defs.h | 40 +- target-openrisc/cpu.h | 12 ++ 8 files changed, 422 insertions(+), 4 deletions(-) create mode 100644 default-configs/or32-linux-user.mak diff --git a/configure b/configure index 166a854..593f1d3 100755 --- a/configure +++ b/configure @@ -956,6 +956,7 @@ microblaze-linux-user \ microblazeel-linux-user \ mips-linux-user \ mipsel-linux-user \ +or32-linux-user \ ppc-linux-user \ ppc64-linux-user \ ppc64abi32-linux-user \ diff --git a/default-configs/or32-linux-user.mak b/default-configs/or32-linux-user.mak new file mode 100644 index 000..808c1f9 --- /dev/null +++ b/default-configs/or32-linux-user.mak @@ -0,0 +1 @@ +# Default configuration for or32-linux-user diff --git a/linux-user/elfload.c b/linux-user/elfload.c index f3b1552..6b622d4 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -787,6 +787,47 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUMBState *env #endif /* TARGET_MICROBLAZE */ +#ifdef TARGET_OPENRISC + +#define ELF_START_MMAP 0x0800 + +#define elf_check_arch(x) ((x) == EM_OPENRISC) + +#define ELF_ARCH EM_OPENRISC +#define ELF_CLASS ELFCLASS32 +#define ELF_DATA ELFDATA2MSB + +static inline void init_thread(struct target_pt_regs *regs, + struct image_info *infop) +{ +regs-pc = infop-entry; +regs-gpr[1] = infop-start_stack; +} + +#define USE_ELF_CORE_DUMP +#define ELF_EXEC_PAGESIZE 8192 + +/* See linux kernel arch/openrisc/include/asm/elf.h. */ +#define ELF_NREG 34 /* gprs and pc, sr */ +typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG]; + +static void elf_core_copy_regs(target_elf_gregset_t *regs, + const CPUOpenRISCState *env) +{ +int i; + +for (i = 0; i 32; i++) { +(*regs)[i] = tswapl(env-gpr[i]); +} + +(*regs)[32] = tswapl(env-pc); +(*regs)[33] = tswapl(env-sr); +} +#define ELF_HWCAP 0 +#define ELF_PLATFORM NULL + +#endif /* TARGET_OPENRISC */ + #ifdef TARGET_SH4 #define ELF_START_MMAP 0x8000 diff --git a/linux-user/main.c b/linux-user/main.c index d0e0e4f..7ed897d 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -2306,6 +2306,93 @@ done_syscall: } #endif +#ifdef TARGET_OPENRISC + +void cpu_loop(CPUOpenRISCState *env) +{ +int trapnr, gdbsig; + +for (;;) { +trapnr = cpu_exec(env); +gdbsig = 0; + +switch (trapnr) { +case EXCP_RESET: +fprintf(stderr, \nReset request, exit, pc is %#x\n, env-pc); +exit(1); +break; +case EXCP_BUSERR: +fprintf(stderr, \nBus error, exit, pc is %#x\n, env-pc); +gdbsig = SIGBUS; +break; +case EXCP_DPF: +case EXCP_IPF: +cpu_dump_state(env, stderr, fprintf, 0); +gdbsig = TARGET_SIGSEGV; +break; +case EXCP_TICK: +fprintf(stderr, \nTick time interrupt pc is %#x\n, env-pc); +break; +case EXCP_ALIGN: +fprintf(stderr, \nAlignment pc is %#x\n, env-pc); +gdbsig = SIGBUS; +break; +case EXCP_ILLEGAL: +fprintf(stderr, \nIllegal instructionpc is %#x\n, env-pc); +gdbsig = SIGILL; +break; +case EXCP_INT: +fprintf(stderr, \nExternal interruptpc is %#x\n, env-pc); +break; +case EXCP_DTLBMISS: +case EXCP_ITLBMISS: +printf(TLB miss\n); +break; +case EXCP_RANGE: +fprintf(stderr, \nRange\n); +gdbsig = SIGSEGV; +break; +case EXCP_SYSCALL: +env-pc += 4; /* 0xc00; */ +env-gpr[11] = do_syscall(env, + env-gpr[11], /* return value */ + env-gpr[3], /* r3 - r7 are params */ + env-gpr[4], + env-gpr[5], + env-gpr[6], + env-gpr[7], + env-gpr[8], 0, 0); +break; +case EXCP_FPE: +fprintf(stderr, Floating point error\n); +break; +case EXCP_TRAP: +fprintf(stderr, Trap\n); +gdbsig = SIGTRAP; +break; +case EXCP_NR: +fprintf(stderr, NR\n); +break; +default: +fprintf(stderr, qemu: unhandled CPU exception %#x - aborting\n, \
[Qemu-devel] [PATCH v13 03/13] Add XBZRLE documentation
Signed-off-by: Orit Wasserman owass...@redhat.com --- docs/xbzrle.txt | 142 +++ 1 files changed, 142 insertions(+), 0 deletions(-) create mode 100644 docs/xbzrle.txt diff --git a/docs/xbzrle.txt b/docs/xbzrle.txt new file mode 100644 index 000..d29b0a7 --- /dev/null +++ b/docs/xbzrle.txt @@ -0,0 +1,142 @@ +XBZRLE (Xor Based Zero Run Length Encoding) +=== + +Using XBZRLE (Xor Based Zero Run Length Encoding) allows for the reduction +of VM downtime and the total live-migration time of Virtual machines. +It is particularly useful for virtual machines running memory write intensive +workloads that are typical of large enterprise applications such as SAP ERP +Systems, and generally speaking for any application that uses a sparse memory +update pattern. + +Instead of sending the changed guest memory page this solution will send a +compressed version of the updates, thus reducing the amount of data sent during +live migration. +In order to be able to calculate the update, the previous memory pages need to +be stored on the source. Those pages are stored in a dedicated cache +(hash table) and are +accessed by their address. +The larger the cache size the better the chances are that the page has already +been stored in the cache. +A small cache size will result in high cache miss rate. +Cache size can be changed before and during migration. + +Format +=== + +The compression format preforms a XOR between the previous and current content +of the page, where zero represents an unchanged value. +The page data delta is represented by zero and non zero runs. +A zero run is represented by its length (in bytes). +A non zero run is represented by its length (in bytes) and the new data. +The run length is encoded using ULEB128 (http://en.wikipedia.org/wiki/LEB128) + +page = zrun nzrun + | zrun nzrun page + +zrun = length + +nzrun = length byte... + +length = uleb128 encoded integer + +On the sender side XBZRLE is used as a compact delta encoding of page updates, +retrieving the old page content from the cache (default size of 512 MB). The +receiving side uses the existing page's content and XBZRLE to decode the new +page's content. + +This is a more compact way to store the deltas than the previous version. + +This work was originally based on research results published +VEE 2011: Evaluation of Delta Compression Techniques for Efficient Live +Migration of Large Virtual Machines by Benoit, Svard, Tordsson and Elmroth. +Additionally the delta encoder XBRLE was improved further using the XBZRLE +instead. + +XBZRLE has a sustained bandwidth of 2-2.5 GB/s for typical workloads making it +ideal for in-line, real-time encoding such as is needed for live-migration. + +Example +new buffer: +1100 zeros +1 2 3 4 5 6 7 8 9 a b c d e f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f +20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 +3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 +54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 0 0 67 0 69 +2984 zeros + +old buffer: +1100 zeros +5 6 7 8 9 a b c d e f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 +23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c +3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 +57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 0 0 6b 0 6d +2984 zeros + +encoded buffer: + +encoded length 118 + +e8 7 70 0 1 2 3 4 5 6 7 8 9 a b c d e f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c +1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 +37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 +51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 0 0 67 0 69 0 0 0 0 +0 0 a8 17 + +Migration Capabilities +== +In order to use XBZRLE the destination QEMU version should be able to +decode the new format. +Adding a new migration capabilities command that will allow external management +to query for it support. +A typical use for the destination +{qemu} info migrate_capabilities +{qemu} xbzrle, ... + +In order to enable capabilities for future live migration, +a new command migrate_set_parameter is introduced: +{qemu} migrate_set_parameter xbzrle + +Usage +== + +1. Activate xbzrle +2. Set the XBZRLE cache size - the cache size is in MBytes and should be a +power of 2. The cache default value is 64MBytes. +3. start outgoing migration + +A typical usage scenario: +{qemu} migrate_set_parameter xbzrle +{qemu} migrate_set_cachesize 256m +{qemu} migrate -d tcp:destination.host: +{qemu} info migrate +... +transferred ram-duplicate: A kbytes +transferred ram-normal: B kbytes +transferred ram-xbrle: C kbytes +overflow ram-xbrle: D pages +cache-miss ram-xbrle: E pages + +cache-miss: the number of cache misses to date - high
[Qemu-devel] [PATCH v13 06/13] Add save_block_hdr function
Signed-off-by: Benoit Hudzia benoit.hud...@sap.com Signed-off-by: Petter Svard pett...@cs.umu.se Signed-off-by: Aidan Shribman aidan.shrib...@sap.com Signed-off-by: Orit Wasserman owass...@redhat.com --- arch_init.c | 26 ++ 1 files changed, 14 insertions(+), 12 deletions(-) diff --git a/arch_init.c b/arch_init.c index a9e8b74..9dafb6e 100644 --- a/arch_init.c +++ b/arch_init.c @@ -161,6 +161,18 @@ static int is_dup_page(uint8_t *page) return 1; } +static void save_block_hdr(QEMUFile *f, RAMBlock *block, ram_addr_t offset, +int cont, int flag) +{ +qemu_put_be64(f, offset | cont | flag); +if (!cont) { +qemu_put_byte(f, strlen(block-idstr)); +qemu_put_buffer(f, (uint8_t *)block-idstr, +strlen(block-idstr)); +} + +} + static RAMBlock *last_block; static ram_addr_t last_offset; @@ -187,21 +199,11 @@ static int ram_save_block(QEMUFile *f) p = memory_region_get_ram_ptr(mr) + offset; if (is_dup_page(p)) { -qemu_put_be64(f, offset | cont | RAM_SAVE_FLAG_COMPRESS); -if (!cont) { -qemu_put_byte(f, strlen(block-idstr)); -qemu_put_buffer(f, (uint8_t *)block-idstr, -strlen(block-idstr)); -} +save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_COMPRESS); qemu_put_byte(f, *p); bytes_sent = 1; } else { -qemu_put_be64(f, offset | cont | RAM_SAVE_FLAG_PAGE); -if (!cont) { -qemu_put_byte(f, strlen(block-idstr)); -qemu_put_buffer(f, (uint8_t *)block-idstr, -strlen(block-idstr)); -} +save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_PAGE); qemu_put_buffer(f, p, TARGET_PAGE_SIZE); bytes_sent = TARGET_PAGE_SIZE; } -- 1.7.7.6
[Qemu-devel] [PATCH v13 07/13] Add debugging infrastructure
Signed-off-by: Orit Wasserman owass...@redhat.com --- arch_init.c | 33 +++-- 1 files changed, 27 insertions(+), 6 deletions(-) diff --git a/arch_init.c b/arch_init.c index 9dafb6e..ee20c33 100644 --- a/arch_init.c +++ b/arch_init.c @@ -44,6 +44,14 @@ #include exec-memory.h #include hw/pcspk.h +#ifdef DEBUG_ARCH_INIT +#define DPRINTF(fmt, ...) \ +do { fprintf(stdout, arch_init: fmt, ## __VA_ARGS__); } while (0) +#else +#define DPRINTF(fmt, ...) \ +do { } while (0) +#endif + #ifdef TARGET_SPARC int graphic_width = 1024; int graphic_height = 768; @@ -380,6 +388,9 @@ int ram_save_live(QEMUFile *f, int stage, void *opaque) expected_time = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth; +DPRINTF(ram_save_live: expected(%ld) = max(%ld)?\n, expected_time, +migrate_max_downtime()); + return (stage == 2) (expected_time = migrate_max_downtime()); } @@ -416,8 +427,11 @@ static inline void *host_from_stream_offset(QEMUFile *f, int ram_load(QEMUFile *f, void *opaque, int version_id) { ram_addr_t addr; -int flags; +int flags, ret = 0; int error; +static uint64_t seq_iter; + +seq_iter++; if (version_id 4 || version_id 4) { return -EINVAL; @@ -447,8 +461,10 @@ int ram_load(QEMUFile *f, void *opaque, int version_id) QLIST_FOREACH(block, ram_list.blocks, next) { if (!strncmp(id, block-idstr, sizeof(id))) { -if (block-length != length) -return -EINVAL; +if (block-length != length) { +ret = -EINVAL; +goto done; +} break; } } @@ -456,7 +472,8 @@ int ram_load(QEMUFile *f, void *opaque, int version_id) if (!block) { fprintf(stderr, Unknown ramblock \%s\, cannot accept migration\n, id); -return -EINVAL; +ret = -EINVAL; +goto done; } total_ram_bytes -= length; @@ -490,11 +507,15 @@ int ram_load(QEMUFile *f, void *opaque, int version_id) } error = qemu_file_get_error(f); if (error) { -return error; +ret = error; +goto done; } } while (!(flags RAM_SAVE_FLAG_EOS)); -return 0; +done: +DPRINTF(Completed load of VM with exit code %d seq iteration %ld\n, +ret, seq_iter); +return ret; } #ifdef HAS_AUDIO -- 1.7.7.6
Re: [Qemu-devel] [PATCH] kvm: First step to push iothread lock out of inner run loop
On Wed, Jun 27, 2012 at 08:41:49AM +0100, Stefan Hajnoczi wrote: On Wed, Jun 27, 2012 at 8:39 AM, Stefan Hajnoczi stefa...@gmail.com wrote: On Tue, Jun 26, 2012 at 8:34 PM, Marcelo Tosatti mtosa...@redhat.com wrote: On Sat, Jun 23, 2012 at 12:55:49AM +0200, Jan Kiszka wrote: net.txt iothread flow = 1) Skip-work-if-device-locked select(tap fd ready) tap_send if (trylock(TAPState-NetClientState-dev)) proceed; else continue; (data remains in queue) tap_read_packet qemu_send_packet_async DRAWBACK: lock intensive. DRAWBACK: VCPU threads can starve IOTHREAD (can be fixed with a scheme such as trylock() marks a flag saying iothread wants lock. One alternative is to say the lock cannot be held across system calls or other long-running operations (similar to interrupt handler spinlocks in the kernel). But QEMU threads are still at the mercy of the scheduler or page faults, so perhaps this is not a good idea because waiting on the lock could tie up the iothread. 2) Queue-work-to-vcpu-context select(tap fd ready) tap_send if (trylock(TAPState-NetClientState-dev)) { proceed; } else { AddToDeviceWorkQueue(work); } tap_read_packet qemu_send_packet_async DRAWBACK: lock intensive DRAWBACK: cache effects This almost suggests we should invert packet reception for NICs. tap fd ready should add a work item and the guest device calls into net/tap.c to pull out any packets from the work function: tap_send dev_add_work(work); virtio_net_rx_work_fn while ((req = virtqueue_pop(rx_queue))) { if (!net_receive_packet(netclient, req-buf)) { break; /* no more packets available */ } /* ...mark req complete and push onto virtqueue... */ } virtqueue_notify(rx_queue); The idea is to avoid copies on the rx path and make the locking simple by always deferring to a work function (which can be invoked immediately if the device isn't locked). I just realized this approach bypasses net/queue.c. I think it works really well for the peer model (no VLANs). Basically flow control is dictated by the peer (receiver) and we don't need to use NetQueue anymore. Whether this works elegantly for slirp and other backends, I'm not sure yet. Stefan Right. The advantage is only backends where performance matters need to be converted (and only net hw drivers that matter performance wise need to be converted). Apparently you guys have very different ideas on the higher level model here. It would be good to agree on one structure (including modifications on the one above) to follow and share the work on that direction. Having competing implementations in this case is a waste of time.
Re: [Qemu-devel] [PATCH v2] bitops.h: Add field32() and field64() functions to extract bitfields
Am 27.06.2012 12:29, schrieb Peter Maydell: Add field32() and field64() functions which extract a particular bit field from a word and return it. Based on an idea by Jia Liu. Suggested-by: Jia Liu pro...@gmail.com Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- v1-v2: added missing brackets to field32() to bring it in to line with field64() (Still using 'int' rather than 'unsigned' for bit numbers as per rationale in previous discussion.) Reviewed-by: Andreas Färber afaer...@suse.de Do you have followup patches that make use of this? Might illustrate what variables and types are being passed in. /-F bitops.h | 28 1 files changed, 28 insertions(+), 0 deletions(-) diff --git a/bitops.h b/bitops.h index 07d1a06..ffbb387 100644 --- a/bitops.h +++ b/bitops.h @@ -269,4 +269,32 @@ static inline unsigned long hweight_long(unsigned long w) return count; } +/** + * field64 - return a specified bit field from a uint64_t value + * @value: The value to extract the bit field from + * @start: The lowest bit in the bit field (numbered from 0) + * @length: The length of the bit field + * + * Returns the value of the bit field extracted from the input value. + */ +static inline uint64_t field64(uint64_t value, int start, int length) +{ +assert(start = 0 start = 63 length 0 start + length = 64); +return (value start) (~0ULL (64 - length)); +} + +/** + * field32 - return a specified bit field from a uint32_t value + * @value: The value to extract the bit field from + * @start: The lowest bit in the bit field (numbered from 0) + * @length: The length of the bit field + * + * Returns the value of the bit field extracted from the input value. + */ +static inline uint32_t field32(uint32_t value, int start, int length) +{ +assert(start = 0 start = 31 length 0 start + length = 32); +return (value start) (~0U (32 - length)); +} + #endif -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
[Qemu-devel] [PATCH v13 00/13] XBZRLE delta for live migration of large memory app
Changes from v12: - use bool for blk and shared params - use long when decoding buffer - fix QMP commands - always display migration parameters in info migrate - update current_addr inside the while loop in ram_save_block - display statistics after migration completes - fix other review comments from Eric Blake Changes from v11: - divide patch 7 to several smaller patches. - Use an array for setting migration parameters QMP only (there is not support for arrays in HMP commands). parameters can be enabled or disabled. - Do not use XBZRLE in stage 3 , it is a very sensitive stage and CPU can be an issue. - Fix review comments by Juan Quintela and Eric Blake Changes from v10: - Cache size will be in bytes, in case it is not a power of 2 it will be reduced to the nearest power of 2. - fix documentation - use cache_init with number of pages not cache size. Changes from v9: - move cache implementation to separate files. Kept our own implementation because GCache or GHashTable have no size limit. - Add migrate_set_parameter function - removed XBZRLE option from migrate command - add cache size information to query_migrate command - add documantation file - write/read the exact XBZRLE header format - fix other review comments by Anthony and Juan Changes from v8: Implement more effiecent cache_resize method fix set_cachesize command Changes from v7: Copy current page before encoding it, this will prevents page content change during the encoding. Allow changing the cache size during an active migration. Fix comments by Avi. Changes from v6: 1) add assert checks to ULEB encoding/decoding 2) no need to send last zero run Changes from v5: 1) Add migration capabilities 2) Use ULEB to encode run length 3) Do not send unmodified (dirty) page 3) Fix other patch comments Using GCache or GHashTable requires allocating new buffer on every content change and have no size limit , so I decided to keep the simple cache implementation. Changes from v4: 1) Rebase 2) divide patch into 9 patches 3) move memory allocation into cache_insert Future work : Use SSE for encoding. Page ranking acording to their dirty rate and automatic activation/deactivation of the feature - will be sent in a separate patch series. By using XBZRLE (Xor Based Zero Run Length Encoding) we can reduce VM downtime and total live-migration time of VMs running memory write intensive workloads typical of large enterprise applications such as SAP ERP Systems, and generally speaking for any application with a sparse memory update pattern. The compression format uses the fact that we will have many zero (zero represents an unchanged value). We repesent the page data delta by zero and non zero runs. We represent a zero run with it's length (in bytes). We represent a non zero run with it's length (in bytes) and the data. The run length is encoded using ULEB128 (http://en.wikipedia.org/wiki/LEB128) page = zrun nzrun | zrun nzrun page zrun = length nzrun = length byte... length = uleb128 encoded integer On the sender side XBZRLE is used as a compact delta encoding of page updates, retrieving the old page content from an LRU cache (default size of 512 MB). The receiving side uses the existing page content and XBZRLE to decode the new page content. This is a more compact way to store the delta than the previous version. This work was originally based on research results published VEE 2011: Evaluation of Delta Compression Techniques for Efficient Live Migration of Large Virtual Machines by Benoit, Svard, Tordsson and Elmroth. Additionally the delta encoder XBRLE was improved further using XBZRLE instead. XBZRLE has a sustained bandwidth of 2-2.5 GB/s for typical workloads making it ideal for in-line, real-time encoding such as is needed for live-migration. A typical usage scenario: {qemu} migrate_set_cachesize 256m {qemu} migrate_set_parameter xbzrle {qemu} migrate -d tcp:destination.host: {qemu} info migrate ... transferred ram: A kbytes remaining ram: B kbytes total ram: C kbytes cache size: D bytes xbzrle transferred: E kbytes xbzrle pages: F pages xbzrle cache miss: G xbzrle overflow : H Testing: live migration with XBZRLE completed in 110 seconds, without live migration was not able to complete. A simple synthetic memory r/w load generator: ..include stdlib.h ..include stdio.h ..int main() ..{ ..char *buf = (char *) calloc(4096, 4096); ..while (1) { ..int i; ..for (i = 0; i 4096 * 4; i++) { ..buf[i * 4096 / 4]++; ..} ..printf(.); ..} ..} Signed-off-by: Benoit Hudzia benoit.hud...@sap.com
Re: [Qemu-devel] [PATCH v2] bitops.h: Add field32() and field64() functions to extract bitfields
On 06/27/2012 04:29 AM, Peter Maydell wrote: Add field32() and field64() functions which extract a particular bit field from a word and return it. Based on an idea by Jia Liu. +static inline uint64_t field64(uint64_t value, int start, int length) +{ +assert(start = 0 start = 63 length 0 start + length = 64); You're failing to account for wraparound: field64(value, 63, MAX_INT) gives undefined behavior in the addition, and even on (most) platforms where it silently wraps around to a negative number, you have then missed triggering the assert and proceed to do more unefined behavior with a negative shift. You can solve that, and use one less conjunct, by using: assert(start = 0 length 0 (unsigned) start + length = 64); Same comment for field32(). -- Eric Blake ebl...@redhat.com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
Re: [Qemu-devel] [PATCH 1/2] Add usb option in machine options to enable/disable usb
Am 18.06.2012 11:22, schrieb Li Zhang: For pseries machine, it needs to enable usb to add keyboard or usb mouse. -usb option won't be used in the future, and machine options is a better way to enable usb. So this patch is to add usb option to machine options (-machine type=psereis,usb=on/off)to enable/disable pseries Space after ) please, Western fonts are probably more narrow. ;) usb controller. For specific machines, they will get the machine option and then create usb controller according to usb option. In this patch, usb is on by default on pseries. So, for -nodefault,usb should be set off in the command Space before usb please. line as the following: -machine type=pseries,usb=off. Signed-off-by: Li Zhang zhlci...@linux.vnet.ibm.com --- hw/spapr.c| 10 ++ qemu-config.c |4 2 files changed, 14 insertions(+), 0 deletions(-) diff --git a/hw/spapr.c b/hw/spapr.c index d0bddbc..8d158d7 100644 --- a/hw/spapr.c +++ b/hw/spapr.c @@ -529,6 +529,8 @@ static void ppc_spapr_init(ram_addr_t ram_size, long load_limit, rtas_limit, fw_size; long pteg_shift = 17; char *filename; +QemuOpts * machine_opts; QemuOpts *machine_opts; checkpatch.pl sometimes emits bogus warnings about this. +bool usb_on = false; Didn't you want this to be true for sPAPR in absence of -machine? Maybe use a more functional naming? It's either added or not, so add_usb perhaps or provide_usb? Purely stylistic of course. spapr = g_malloc0(sizeof(*spapr)); QLIST_INIT(spapr-phbs); @@ -661,6 +663,14 @@ static void ppc_spapr_init(ram_addr_t ram_size, spapr_vscsi_create(spapr-vio_bus); } +machine_opts = qemu_opts_find(qemu_find_opts(machine), 0); +if (machine_opts) +usb_on = qemu_opt_get_bool(machine_opts, usb, true); Still missing braces for if. Other than that looking good to me now. Where's 2/2? Please post the fixed version as a top-level [PATCH v4] along with a small change log after --- or in a cover letter. Andreas + +if (usb_on) { +pci_create_simple(QLIST_FIRST(spapr-phbs)-host_state.bus, + -1, pci-ohci); +} if (rma_size (MIN_RMA_SLOF 20)) { fprintf(stderr, qemu: pSeries SLOF firmware requires = %ldM guest RMA (Real Mode Area memory)\n, MIN_RMA_SLOF); diff --git a/qemu-config.c b/qemu-config.c index bb3bff4..cdab765 100644 --- a/qemu-config.c +++ b/qemu-config.c @@ -583,6 +583,10 @@ static QemuOptsList qemu_machine_opts = { .name = dtb, .type = QEMU_OPT_STRING, .help = Linux kernel device tree file, +},{ +.name = usb, +.type = QEMU_OPT_BOOL, +.help = Set on/off to enable/disable usb, }, { /* End of list */ } }, -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Re: [Qemu-devel] [Qemu-ppc] [PATCH 2/2] spapr: Add support for -vga option
On 18.06.2012, at 11:34, Li Zhang wrote: Also instanciate the USB keyboard and mouse when that option is used (you can still use -device to create individual devices without all the defaults) Signed-off-by: Benjamin Herrenschmidt b...@kernel.crashing.org Signed-off-by: Li Zhang zhlci...@linux.vnet.ibm.com --- hw/spapr.c | 43 ++- 1 files changed, 42 insertions(+), 1 deletions(-) diff --git a/hw/spapr.c b/hw/spapr.c index 8d158d7..c7b6e9d 100644 --- a/hw/spapr.c +++ b/hw/spapr.c @@ -45,6 +45,8 @@ #include kvm.h #include kvm_ppc.h #include pci.h +#include pc.h +#include usb.h #include exec-memory.h @@ -82,6 +84,7 @@ #define PHANDLE_XICP0x sPAPREnvironment *spapr; +static int spapr_has_graphics; qemu_irq spapr_allocate_irq(uint32_t hint, uint32_t *irq_num, enum xics_irq_type type) @@ -222,6 +225,9 @@ static void *spapr_create_fdt_skel(const char *cpu_model, _FDT((fdt_property(fdt, qemu,boot-kernel, kprop, sizeof(kprop; } _FDT((fdt_property_string(fdt, qemu,boot-device, boot_device))); +_FDT((fdt_property_cell(fdt, qemu,graphic-width, graphic_width))); +_FDT((fdt_property_cell(fdt, qemu,graphic-height, graphic_height))); +_FDT((fdt_property_cell(fdt, qemu,graphic-depth, graphic_depth))); _FDT((fdt_end_node(fdt))); @@ -457,7 +463,9 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr, } } -spapr_populate_chosen_stdout(fdt, spapr-vio_bus); +if (!spapr_has_graphics) { +spapr_populate_chosen_stdout(fdt, spapr-vio_bus); +} _FDT((fdt_pack(fdt))); @@ -510,6 +518,30 @@ static void spapr_cpu_reset(void *opaque) cpu_reset(CPU(cpu)); } +static int spapr_vga_init(PCIBus *pci_bus) +{ +/* Default is nothing */ +#if 0 /* Enable this once we merge a SLOF which works with Cirrus */ Ben, mind to push a working SLOF, we we can just enable all of it in one go and don't have to commit #if 0'ed code? Rest looks reasonable to me. Alex
[Qemu-devel] [PATCH] pseries: Add support for new KVM hash table control call
From: David Gibson da...@gibson.dropbear.id.au This adds support for then new reset htab ioctl which allows qemu to properly cleanup the MMU hash table when the guest is reset. With the corresponding kernel support, reset of a guest now works properly. This also paves the way for indicating a different size hash table to the kernel and for the kernel to be able to impose limits on the requested size. Signed-off-by: David Gibson da...@gibson.dropbear.id.au Signed-off-by: Benjamin Herrenschmidt b...@kernel.crashing.org --- hw/spapr.c | 88 -- hw/spapr.h |2 +- target-ppc/kvm.c | 17 ++ target-ppc/kvm_ppc.h |7 4 files changed, 82 insertions(+), 32 deletions(-) diff --git a/hw/spapr.c b/hw/spapr.c index a6bc5e8..e19dbd8 100644 --- a/hw/spapr.c +++ b/hw/spapr.c @@ -83,6 +83,8 @@ #define PHANDLE_XICP0x +#define HTAB_SIZE(spapr)(1ULL ((spapr)-htab_shift)) + sPAPREnvironment *spapr; static int spapr_has_graphics; @@ -111,12 +113,13 @@ qemu_irq spapr_allocate_irq(uint32_t hint, uint32_t *irq_num, return qirq; } -static int spapr_set_associativity(void *fdt, sPAPREnvironment *spapr) +static int spapr_fixup_cpu_dt(void *fdt, sPAPREnvironment *spapr) { int ret = 0, offset; CPUPPCState *env; char cpu_model[32]; int smt = kvmppc_smt_threads(); +uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr-htab_shift)}; assert(spapr-cpu_model); @@ -140,8 +143,16 @@ static int spapr_set_associativity(void *fdt, sPAPREnvironment *spapr) return offset; } -ret = fdt_setprop(fdt, offset, ibm,associativity, associativity, - sizeof(associativity)); +if (nb_numa_nodes 1) { +ret = fdt_setprop(fdt, offset, ibm,associativity, associativity, + sizeof(associativity)); +if (ret 0) { +return ret; +} +} + +ret = fdt_setprop(fdt, offset, ibm,pft-size, + pft_size_prop, sizeof(pft_size_prop)); if (ret 0) { return ret; } @@ -189,15 +200,13 @@ static void *spapr_create_fdt_skel(const char *cpu_model, target_phys_addr_t initrd_size, target_phys_addr_t kernel_size, const char *boot_device, - const char *kernel_cmdline, - long hash_shift) + const char *kernel_cmdline) { void *fdt; CPUPPCState *env; uint64_t mem_reg_property[2]; uint32_t start_prop = cpu_to_be32(initrd_base); uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size); -uint32_t pft_size_prop[] = {0, cpu_to_be32(hash_shift)}; char hypertas_prop[] = hcall-pft\0hcall-term\0hcall-dabr\0hcall-interrupt \0hcall-tce\0hcall-vio\0hcall-splpar\0hcall-bulk; char qemu_hypertas_prop[] = hcall-memop1; @@ -366,8 +375,6 @@ static void *spapr_create_fdt_skel(const char *cpu_model, _FDT((fdt_property_cell(fdt, timebase-frequency, tbfreq))); _FDT((fdt_property_cell(fdt, clock-frequency, cpufreq))); _FDT((fdt_property_cell(fdt, ibm,slb-size, env-slb_nr))); -_FDT((fdt_property(fdt, ibm,pft-size, - pft_size_prop, sizeof(pft_size_prop; _FDT((fdt_property_string(fdt, status, okay))); _FDT((fdt_property(fdt, 64-bit, NULL, 0))); @@ -502,11 +509,9 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr, } /* Advertise NUMA via ibm,associativity */ -if (nb_numa_nodes 1) { -ret = spapr_set_associativity(fdt, spapr); -if (ret 0) { -fprintf(stderr, Couldn't set up NUMA device tree properties\n); -} +ret = spapr_fixup_cpu_dt(fdt, spapr); +if (ret 0) { +fprintf(stderr, Couldn't finalize CPU device tree properties\n); } if (!spapr_has_graphics) { @@ -536,12 +541,34 @@ static void emulate_spapr_hypercall(CPUPPCState *env) env-gpr[3] = spapr_hypercall(env, env-gpr[3], env-gpr[4]); } -static void spapr_reset(void *opaque) +static void spapr_reset_htab(void *opaque) { sPAPREnvironment *spapr = (sPAPREnvironment *)opaque; +long shift; + +/* allocate hash page table. For now we always make this 16mb, + * later we should probably make it scale to the size of guest + * RAM */ + +shift = kvmppc_reset_htab(spapr-htab_shift); + +if (shift 0) { +/* Kernel handles htab, we don't need to allocate one */ +spapr-htab_shift = shift; +} else { +if (!spapr-htab) { +/* Allocate an htab if we don't yet have one */ +spapr-htab = qemu_memalign(HTAB_SIZE(spapr), HTAB_SIZE(spapr)); +} + +/* And clear it */ +
Re: [Qemu-devel] [PATCH] pseries: Add support for new KVM hash table control call
On Wed, 2012-06-27 at 22:10 +1000, Benjamin Herrenschmidt wrote: From: David Gibson da...@gibson.dropbear.id.au This adds support for then new reset htab ioctl which allows qemu to properly cleanup the MMU hash table when the guest is reset. With the corresponding kernel support, reset of a guest now works properly. Forgot to mention ... this depends on a newer linux kvm.h from Avi's -next branch, so don't apply this patch to qemu until kvm.h had the update adding the definitions for KVM_CAP_PPC_ALLOC_HTAB and KVM_PPC_ALLOCATE_HTAB. Cheers, Ben. This also paves the way for indicating a different size hash table to the kernel and for the kernel to be able to impose limits on the requested size. Signed-off-by: David Gibson da...@gibson.dropbear.id.au Signed-off-by: Benjamin Herrenschmidt b...@kernel.crashing.org --- hw/spapr.c | 88 -- hw/spapr.h |2 +- target-ppc/kvm.c | 17 ++ target-ppc/kvm_ppc.h |7 4 files changed, 82 insertions(+), 32 deletions(-) diff --git a/hw/spapr.c b/hw/spapr.c index a6bc5e8..e19dbd8 100644 --- a/hw/spapr.c +++ b/hw/spapr.c @@ -83,6 +83,8 @@ #define PHANDLE_XICP0x +#define HTAB_SIZE(spapr)(1ULL ((spapr)-htab_shift)) + sPAPREnvironment *spapr; static int spapr_has_graphics; @@ -111,12 +113,13 @@ qemu_irq spapr_allocate_irq(uint32_t hint, uint32_t *irq_num, return qirq; } -static int spapr_set_associativity(void *fdt, sPAPREnvironment *spapr) +static int spapr_fixup_cpu_dt(void *fdt, sPAPREnvironment *spapr) { int ret = 0, offset; CPUPPCState *env; char cpu_model[32]; int smt = kvmppc_smt_threads(); +uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr-htab_shift)}; assert(spapr-cpu_model); @@ -140,8 +143,16 @@ static int spapr_set_associativity(void *fdt, sPAPREnvironment *spapr) return offset; } -ret = fdt_setprop(fdt, offset, ibm,associativity, associativity, - sizeof(associativity)); +if (nb_numa_nodes 1) { +ret = fdt_setprop(fdt, offset, ibm,associativity, associativity, + sizeof(associativity)); +if (ret 0) { +return ret; +} +} + +ret = fdt_setprop(fdt, offset, ibm,pft-size, + pft_size_prop, sizeof(pft_size_prop)); if (ret 0) { return ret; } @@ -189,15 +200,13 @@ static void *spapr_create_fdt_skel(const char *cpu_model, target_phys_addr_t initrd_size, target_phys_addr_t kernel_size, const char *boot_device, - const char *kernel_cmdline, - long hash_shift) + const char *kernel_cmdline) { void *fdt; CPUPPCState *env; uint64_t mem_reg_property[2]; uint32_t start_prop = cpu_to_be32(initrd_base); uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size); -uint32_t pft_size_prop[] = {0, cpu_to_be32(hash_shift)}; char hypertas_prop[] = hcall-pft\0hcall-term\0hcall-dabr\0hcall-interrupt \0hcall-tce\0hcall-vio\0hcall-splpar\0hcall-bulk; char qemu_hypertas_prop[] = hcall-memop1; @@ -366,8 +375,6 @@ static void *spapr_create_fdt_skel(const char *cpu_model, _FDT((fdt_property_cell(fdt, timebase-frequency, tbfreq))); _FDT((fdt_property_cell(fdt, clock-frequency, cpufreq))); _FDT((fdt_property_cell(fdt, ibm,slb-size, env-slb_nr))); -_FDT((fdt_property(fdt, ibm,pft-size, - pft_size_prop, sizeof(pft_size_prop; _FDT((fdt_property_string(fdt, status, okay))); _FDT((fdt_property(fdt, 64-bit, NULL, 0))); @@ -502,11 +509,9 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr, } /* Advertise NUMA via ibm,associativity */ -if (nb_numa_nodes 1) { -ret = spapr_set_associativity(fdt, spapr); -if (ret 0) { -fprintf(stderr, Couldn't set up NUMA device tree properties\n); -} +ret = spapr_fixup_cpu_dt(fdt, spapr); +if (ret 0) { +fprintf(stderr, Couldn't finalize CPU device tree properties\n); } if (!spapr_has_graphics) { @@ -536,12 +541,34 @@ static void emulate_spapr_hypercall(CPUPPCState *env) env-gpr[3] = spapr_hypercall(env, env-gpr[3], env-gpr[4]); } -static void spapr_reset(void *opaque) +static void spapr_reset_htab(void *opaque) { sPAPREnvironment *spapr = (sPAPREnvironment *)opaque; +long shift; + +/* allocate hash page table. For now we always make this 16mb, + * later we should probably make it scale to the size of guest
Re: [Qemu-devel] [PATCH v3 5/6] qapi: convert sendkey
On 06/27/2012 03:59 AM, Amos Kong wrote: The interface looks like we have settled into something useful that libvirt can live with. I will leave a more thorough review of the series to those more familiar with qemu's internals. However, as long as we are fine-tuning things, I have some questions that might be worth one more spin: +## +# @sendkey: Should this be named 'send-key', given that most QMP commands separate words with '-' rather than squasheverythingtogether? Yes, that's right. still use sendkey for hmp ? Libvirt won't care if you rename the hmp command, once the QMP command is in place. However, for back-compat, since hmp already had 'sendkey', it probably makes sense to keep that naming instead of gratuitously changing it, so for now, I'd go with 'send-key' only for QMP. -- Eric Blake ebl...@redhat.com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
Re: [Qemu-devel] [PATCH v7 11/16] target-or32: Add a IIS dummy board
Hi Jia, On Wed, Jun 27, 2012 at 7:54 PM, Jia Liu pro...@gmail.com wrote: Add a IIS dummy board. Signed-off-by: Jia Liu pro...@gmail.com --- hw/openrisc/Makefile.objs | 2 +- hw/openrisc_sim.c | 149 + 2 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 hw/openrisc_sim.c diff --git a/hw/openrisc/Makefile.objs b/hw/openrisc/Makefile.objs index 1c541a5..38ff8f5 100644 --- a/hw/openrisc/Makefile.objs +++ b/hw/openrisc/Makefile.objs @@ -1,3 +1,3 @@ -obj-y = openrisc_pic.o openrisc_timer.o +obj-y = openrisc_pic.o openrisc_sim.o openrisc_timer.o obj-y := $(addprefix ../,$(obj-y)) diff --git a/hw/openrisc_sim.c b/hw/openrisc_sim.c new file mode 100644 index 000..b0c1e69 --- /dev/null +++ b/hw/openrisc_sim.c @@ -0,0 +1,149 @@ +/* + * OpenRISC simulator for use as an IIS. + * + * Copyright (c) 2011-2012 Jia Liu pro...@gmail.com + * Feng Gao gf91...@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see http://www.gnu.org/licenses/. + */ + +#include hw.h +#include openrisc_cpudev.h +#include boards.h +#include elf.h +#include pc.h +#include loader.h +#include exec-memory.h +#include sysemu.h +#include sysbus.h +#include qtest.h + +#define KERNEL_LOAD_ADDR 0x100 + Unused definition. +static struct _loaderparams { + uint64_t ram_size; + const char *kernel_filename; + const char *kernel_cmdline; + const char *initrd_filename; ram_size, kernel_cmdline and initrd_filename are all unused AFAICT? Can you simplify your bootloader by passing just the filename and none of this Linux specific stuff? +} loaderparams; + +static void main_cpu_reset(void *opaque) +{ + CPUOpenRISCState *env = opaque; + cpu_reset(ENV_GET_CPU(env)); +} + +static void openrisc_sim_net_init(MemoryRegion *address_space, + target_phys_addr_t base, + target_phys_addr_t descriptors, + qemu_irq irq, NICInfo *nd) +{ + DeviceState *dev; + SysBusDevice *s; + + dev = qdev_create(NULL, open_eth); + qdev_set_nic_properties(dev, nd); + qdev_init_nofail(dev); + + s = sysbus_from_qdev(dev); + sysbus_connect_irq(s, 0, irq); + memory_region_add_subregion(address_space, base, + sysbus_mmio_get_region(s, 0)); + memory_region_add_subregion(address_space, descriptors, + sysbus_mmio_get_region(s, 1)); +} + +static uint64_t openrisc_load_kernel(void) +{ cc Peter Maydell Re the bootloader discussion. - This is yet another bootloader. This one is just load elf else load uimage else load raw-image. No append, initrd, dtb etc. Not a blocker at this stage but looking ahead this will fall under the umbrella of the bootloader unifications we need to discuss. + long kernel_size; + uint64_t elf_entry; + target_phys_addr_t entry; + + if (loaderparams.kernel_filename !qtest_enabled()) { + kernel_size = load_uimage(loaderparams.kernel_filename, + entry, NULL, NULL); + if (kernel_size 0) { + kernel_size = load_elf(loaderparams.kernel_filename, NULL, NULL, + elf_entry, NULL, NULL, 1, ELF_MACHINE, 1); + entry = elf_entry; + } + + if (kernel_size 0) { + fprintf(stderr, QEMU: couldn't load the kernel '%s'\n, + loaderparams.kernel_filename); + exit(1); + } + } + + return entry; +} + +static void openrisc_sim_init(ram_addr_t ram_size, + const char *boot_device, + const char *kernel_filename, + const char *kernel_cmdline, + const char *initrd_filename, + const char *cpu_model) +{ + CPUOpenRISCState *env; + MemoryRegion *ram = g_new(MemoryRegion, 1); + + if (!cpu_model) { + cpu_model = or1200; + } + env = cpu_init(cpu_model); + if (!env) { + fprintf(stderr, Unable to find CPU definition!\n); + exit(1); + } + + qemu_register_reset(main_cpu_reset, env); + main_cpu_reset(env); +
Re: [Qemu-devel] [PATCH] pseries: Add support for new KVM hash table control call
On 27.06.2012, at 14:10, Benjamin Herrenschmidt wrote: From: David Gibson da...@gibson.dropbear.id.au This adds support for then new reset htab ioctl which allows qemu to properly cleanup the MMU hash table when the guest is reset. With the corresponding kernel support, reset of a guest now works properly. This also paves the way for indicating a different size hash table to the kernel and for the kernel to be able to impose limits on the requested size. Signed-off-by: David Gibson da...@gibson.dropbear.id.au Signed-off-by: Benjamin Herrenschmidt b...@kernel.crashing.org Thanks, applied to ppc-next. Next time, please base on top of a newer git base - I had to manually fix the patch to apply. Alex
Re: [Qemu-devel] [PATCH v7 08/16] target-or32: Add instruction translation
Hi Max, On Wed, Jun 27, 2012 at 7:03 PM, Max Filippov jcmvb...@gmail.com wrote: On Wed, Jun 27, 2012 at 1:54 PM, Jia Liu pro...@gmail.com wrote: Add OpenRISC instruction tanslation routines. Signed-off-by: Jia Liu pro...@gmail.com [...] + case 0x0009: + switch (op1) { + case 0x03: /* l.div */ + LOG_DIS(l.div r%d, r%d, r%d\n, rd, ra, rb); + { + int lab0 = gen_new_label(); + int lab1 = gen_new_label(); + int lab2 = gen_new_label(); + int lab3 = gen_new_label(); + TCGv_i32 sr_ove = tcg_temp_local_new_i32(); + if (rb == 0) { + tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY)); + tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE); + tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab0); + gen_exception(dc, EXCP_RANGE); + gen_set_label(lab0); + } else { + tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_R[rb], + 0x, lab1); + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[ra], + 0x8000, lab2); + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[rb], + 0x, lab2); + gen_set_label(lab1); + tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY)); + tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE); + tcg_gen_brcondi_tl(TCG_COND_EQ, sr_ove, SR_OVE, lab3); You used to have tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab2) here in previous series, why do you change NE to EQ? According to the OpenRISC Arch Manual. OV: Overflow flag 0 No overflow occured during last arithmetic operation 1 Overflow occured during last arithmetic operation OVE:Overflow flag Exception 0 Overflow flag does not cause an exception 1 Overflow flag causes range exception It will raise a exception, when sr_ove is 1. 0, not. If there was not a exception, that is, sr_ove is 0, we should use NE and jump to lab2, compute safety. but if there was a exception, that is, sr_ove is 1, we have to jump to lab3 to avoid crash QEMU. Keep it NE will run the test fine, too. I think maybe EQ is better. How it to be in your eyes? + gen_exception(dc, EXCP_RANGE); + gen_set_label(lab2); + tcg_gen_div_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); + gen_set_label(lab3); + } + tcg_temp_free_i32(sr_ove); + } + break; + + default: + gen_illegal_exception(dc); + break; + } + break; + + case 0x000a: + switch (op1) { + case 0x03: /* l.divu */ + LOG_DIS(l.divu r%d, r%d, r%d\n, rd, ra, rb); + { + int lab0 = gen_new_label(); + int lab1 = gen_new_label(); + int lab2 = gen_new_label(); + TCGv_i32 sr_ove = tcg_temp_local_new_i32(); + if (rb == 0) { + tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY)); + tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE); + tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab0); + gen_exception(dc, EXCP_RANGE); + gen_set_label(lab0); + } else { + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[rb], + 0x, lab1); + tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY)); + tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE); + tcg_gen_brcondi_tl(TCG_COND_EQ, sr_ove, SR_OVE, lab2); Same here. + gen_exception(dc, EXCP_RANGE); + gen_set_label(lab1); + tcg_gen_divu_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); + gen_set_label(lab2); + } + tcg_temp_free_i32(sr_ove); + } + break; -- Thanks. -- Max Regards, Jia.
[Qemu-devel] [PATCH] qdev: fix use-after-free in the error path of qdev_init_nofail
From Markus: Before: $ qemu-system-x86_64 -display none -drive if=ide qemu-system-x86_64: Device needs media, but drive is empty qemu-system-x86_64: Initialization of device ide-hd failed [Exit 1 ] After: $ qemu-system-x86_64 -display none -drive if=ide qemu-system-x86_64: Device needs media, but drive is empty Segmentation fault (core dumped) [Exit 139 (SIGSEGV)] This error always existed as qdev_init() frees the object. But QOM goes a bit further and purposefully sets the class pointer to NULL to help find use-after-free. It worked :-) Cc: Andreas Faerber afaer...@suse.de Reported-by: Markus Armbruster arm...@redhat.com Signed-off-by: Anthony Liguori aligu...@us.ibm.com --- hw/qdev.c |5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/hw/qdev.c b/hw/qdev.c index a6c4c02..af54467 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -258,9 +258,10 @@ int qdev_simple_unplug_cb(DeviceState *dev) way is somewhat unclean, and best avoided. */ void qdev_init_nofail(DeviceState *dev) { +const char *typename = object_get_typename(OBJECT(dev)); + if (qdev_init(dev) 0) { -error_report(Initialization of device %s failed, - object_get_typename(OBJECT(dev))); +error_report(Initialization of device %s failed, typename); exit(1); } } -- 1.7.5.4
Re: [Qemu-devel] [PATCH v3 5/6] qapi: convert sendkey
On Wed, 27 Jun 2012 17:59:04 +0800 Amos Kong ak...@redhat.com wrote: On 27/06/12 04:22, Luiz Capitulino wrote: On Wed, 20 Jun 2012 06:53:40 -0600 Eric Blakeebl...@redhat.com wrote: On 06/19/2012 10:47 PM, Amos Kong wrote: Convert 'sendkey' to use QAPI. do_sendkey() depends on some variables/functions in monitor.c, so reserve qmp_sendkey() to monitor.c key_defs[] in monitor.c is the mapping of key name to keycode, Keys' order in the enmu and key_defs[] is same. The interface looks like we have settled into something useful that libvirt can live with. I will leave a more thorough review of the series to those more familiar with qemu's internals. However, as long as we are fine-tuning things, I have some questions that might be worth one more spin: +## +# @sendkey: Should this be named 'send-key', given that most QMP commands separate words with '-' rather than squasheverythingtogether? Yes, that's right. still use sendkey for hmp ? Yes. +SQMP +sendkey +-- + +Send keys to VM. + +Arguments: + +keys array: +- key: key sequence (json-string) I'm not sure if json-string is the right designation any more. Rather, it is a json-array of key enum values. The content in brackets should be the description of key, which is the item of array. I think jaso-string is better. It's not the description for while array. Actually, you should call it a list of json-string.
Re: [Qemu-devel] [PATCH v2] bitops.h: Add field32() and field64() functions to extract bitfields
On 27 June 2012 12:29, Andreas Färber afaer...@suse.de wrote: Do you have followup patches that make use of this? Might illustrate what variables and types are being passed in. Here's a random snippet from the LPAE patch I'm working on: uint32_t t0sz = field32(env-cp15.c2_control, 0, 3); uint32_t t1sz = field32(env-cp15.c2_control, 16, 3); I expect that in almost all cases the size and length values will just be constants. -- PMM
Re: [Qemu-devel] [PATCH v7 11/16] target-or32: Add a IIS dummy board
Am 27.06.2012 14:25, schrieb Peter Crosthwaite: Hi Jia, On Wed, Jun 27, 2012 at 7:54 PM, Jia Liu pro...@gmail.com wrote: +static void openrisc_sim_init(ram_addr_t ram_size, + const char *boot_device, + const char *kernel_filename, + const char *kernel_cmdline, + const char *initrd_filename, + const char *cpu_model) +{ +CPUOpenRISCState *env; +MemoryRegion *ram = g_new(MemoryRegion, 1); + +if (!cpu_model) { +cpu_model = or1200; +} +env = cpu_init(cpu_model); +if (!env) { +fprintf(stderr, Unable to find CPU definition!\n); +exit(1); +} + +qemu_register_reset(main_cpu_reset, env); +main_cpu_reset(env); + I think this needs rebasing. Andreas a while back abstracted back to the CPU level instead for resets. Andreas can you confirm? should this be changed to pass the CPU QOM object to the reset instead? cc andreas. Thought I had commented that already... maybe I'm starting to confuse uc32 and or32? :) Yes please, cpu_or32_init() should be called and return an OpenRISCCPU *cpu. main_cpu_reset() should be passed the cpu, too. All new APIs (static helpers etc.) should use OpenRISCCPU, not CPUOpenRISCState. That will greatly simplify moving forward. Thanks for catching this, Peter. Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Re: [Qemu-devel] [PATCH v2] bitops.h: Add field32() and field64() functions to extract bitfields
On 27 June 2012 12:39, Eric Blake ebl...@redhat.com wrote: On 06/27/2012 04:29 AM, Peter Maydell wrote: +static inline uint64_t field64(uint64_t value, int start, int length) +{ + assert(start = 0 start = 63 length 0 start + length = 64); You're failing to account for wraparound: field64(value, 63, MAX_INT) gives undefined behavior in the addition, and even on (most) platforms where it silently wraps around to a negative number, you have then missed triggering the assert and proceed to do more unefined behavior with a negative shift. You can solve that, and use one less conjunct, by using: assert(start = 0 length 0 (unsigned) start + length = 64); Yes, that works (took me a minute to figure out that it relies on two positive ints not being able to overflow an unsigned int). -- PMM
Re: [Qemu-devel] [PATCH v2] bitops.h: Add field32() and field64() functions to extract bitfields
Eric Blake wrote: assert(start = 0 length 0 (unsigned) start + length = 64); This is shorter and avoids the ugly cast: assert(start = 0 length 0 length = 64 - start); Jay.
Re: [Qemu-devel] [PATCH v7 11/16] target-or32: Add a IIS dummy board
On Wed, Jun 27, 2012 at 11:04 PM, Andreas Färber afaer...@suse.de wrote: Am 27.06.2012 14:25, schrieb Peter Crosthwaite: Hi Jia, On Wed, Jun 27, 2012 at 7:54 PM, Jia Liu pro...@gmail.com wrote: +static void openrisc_sim_init(ram_addr_t ram_size, + const char *boot_device, + const char *kernel_filename, + const char *kernel_cmdline, + const char *initrd_filename, + const char *cpu_model) +{ + CPUOpenRISCState *env; + MemoryRegion *ram = g_new(MemoryRegion, 1); + + if (!cpu_model) { + cpu_model = or1200; + } + env = cpu_init(cpu_model); + if (!env) { + fprintf(stderr, Unable to find CPU definition!\n); + exit(1); + } + + qemu_register_reset(main_cpu_reset, env); + main_cpu_reset(env); + I think this needs rebasing. Andreas a while back abstracted back to the CPU level instead for resets. Andreas can you confirm? should this be changed to pass the CPU QOM object to the reset instead? cc andreas. Thought I had commented that already... maybe I'm starting to confuse uc32 and or32? :) Yes please, cpu_or32_init() should be called and return an OpenRISCCPU *cpu. main_cpu_reset() should be passed the cpu, too. All new APIs (static helpers etc.) should use OpenRISCCPU, not CPUOpenRISCState. That rule has significant impact on patches 9-10. Andreas, you may wish to check these out - they are psuedo device-models tightly coupled to the cpu env. Regards, Peter That will greatly simplify moving forward. Thanks for catching this, Peter. Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Re: [Qemu-devel] [PATCH 1/2] Add usb option in machine options to enable/disable usb
On Wed, Jun 27, 2012 at 8:00 PM, Andreas Färber afaer...@suse.de wrote: Am 18.06.2012 11:22, schrieb Li Zhang: For pseries machine, it needs to enable usb to add keyboard or usb mouse. -usb option won't be used in the future, and machine options is a better way to enable usb. So this patch is to add usb option to machine options (-machine type=psereis,usb=on/off)to enable/disable pseries Space after ) please, Western fonts are probably more narrow. ;) OK, I will correct it. usb controller. For specific machines, they will get the machine option and then create usb controller according to usb option. In this patch, usb is on by default on pseries. So, for -nodefault,usb should be set off in the command Space before usb please. line as the following: -machine type=pseries,usb=off. Signed-off-by: Li Zhang zhlci...@linux.vnet.ibm.com --- hw/spapr.c | 10 ++ qemu-config.c | 4 2 files changed, 14 insertions(+), 0 deletions(-) diff --git a/hw/spapr.c b/hw/spapr.c index d0bddbc..8d158d7 100644 --- a/hw/spapr.c +++ b/hw/spapr.c @@ -529,6 +529,8 @@ static void ppc_spapr_init(ram_addr_t ram_size, long load_limit, rtas_limit, fw_size; long pteg_shift = 17; char *filename; + QemuOpts * machine_opts; QemuOpts *machine_opts; checkpatch.pl sometimes emits bogus warnings about this. OK. I will use it to do that. :) + bool usb_on = false; Didn't you want this to be true for sPAPR in absence of -machine? It is set in the following: if (machine_opts) usb_on = qemu_opt_get_bool(machine_opts, usb, true); It means that when using -machine option, usb_on is set as true if usb option is not specified. Maybe use a more functional naming? It's either added or not, so add_usb perhaps or provide_usb? Purely stylistic of course. spapr = g_malloc0(sizeof(*spapr)); QLIST_INIT(spapr-phbs); @@ -661,6 +663,14 @@ static void ppc_spapr_init(ram_addr_t ram_size, spapr_vscsi_create(spapr-vio_bus); } + machine_opts = qemu_opts_find(qemu_find_opts(machine), 0); + if (machine_opts) + usb_on = qemu_opt_get_bool(machine_opts, usb, true); Still missing braces for if. Other than that looking good to me now. Where's 2/2? 2/2's title is as the following: [Qemu-devel][PATCH 2/2] spapr: Add support for -vga option. :) Please post the fixed version as a top-level [PATCH v4] along with a small change log after --- or in a cover letter. OK. I will do that. :) Andreas + + if (usb_on) { + pci_create_simple(QLIST_FIRST(spapr-phbs)-host_state.bus, + -1, pci-ohci); + } if (rma_size (MIN_RMA_SLOF 20)) { fprintf(stderr, qemu: pSeries SLOF firmware requires = %ldM guest RMA (Real Mode Area memory)\n, MIN_RMA_SLOF); diff --git a/qemu-config.c b/qemu-config.c index bb3bff4..cdab765 100644 --- a/qemu-config.c +++ b/qemu-config.c @@ -583,6 +583,10 @@ static QemuOptsList qemu_machine_opts = { .name = dtb, .type = QEMU_OPT_STRING, .help = Linux kernel device tree file, + },{ + .name = usb, + .type = QEMU_OPT_BOOL, + .help = Set on/off to enable/disable usb, }, { /* End of list */ } }, -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg -- Best Regards -Li
Re: [Qemu-devel] [PATCH] qdev: fix use-after-free in the error path of qdev_init_nofail
Am 27.06.2012 14:41, schrieb Anthony Liguori: From Markus: Before: $ qemu-system-x86_64 -display none -drive if=ide qemu-system-x86_64: Device needs media, but drive is empty qemu-system-x86_64: Initialization of device ide-hd failed [Exit 1 ] After: $ qemu-system-x86_64 -display none -drive if=ide qemu-system-x86_64: Device needs media, but drive is empty Segmentation fault (core dumped) [Exit 139 (SIGSEGV)] This error always existed as qdev_init() frees the object. But QOM goes a bit further and purposefully sets the class pointer to NULL to help find use-after-free. It worked :-) Cc: Andreas Faerber afaer...@suse.de Reported-by: Markus Armbruster arm...@redhat.com Signed-off-by: Anthony Liguori aligu...@us.ibm.com Reviewed-by: Andreas Färber afaer...@suse.de This together with the semantics discussions we're having makes me think we should attack QOM'ifying qdev sooner than later. I.e., reviewing what naming, chaining, etc. we can already change to align the TYPE_DEVICE-derived types with the generic QOM infrastructure. Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Re: [Qemu-devel] [PATCH v2] bitops.h: Add field32() and field64() functions to extract bitfields
On 06/27/2012 01:29 PM, Peter Maydell wrote: Add field32() and field64() functions which extract a particular bit field from a word and return it. Based on an idea by Jia Liu. +/** + * field64 - return a specified bit field from a uint64_t value + * @value: The value to extract the bit field from + * @start: The lowest bit in the bit field (numbered from 0) + * @length: The length of the bit field + * + * Returns the value of the bit field extracted from the input value. + */ +static inline uint64_t field64(uint64_t value, int start, int length) +{ +assert(start = 0 start = 63 length 0 start + length = 64); +return (value start) (~0ULL (64 - length)); +} + Undefined for length == 64, so better add that to the assert. I suggest adding the analogous functions for writing. I believe the common naming is extract/deposit. static inline uint64_t deposit64(uint64_t *pvalue, unsigned start, unsigned length, uint64_t fieldval) { uint64_t mask = (((uint64_t)1 length) - 1) start; *pvalue = (*pvalue ~mask) | ((fieldval start) mask); } Useful for setting a bit to a specific value. -- error compiling committee.c: too many arguments to function
Re: [Qemu-devel] [PATCH v3 5/6] qapi: convert sendkey
On Wed, 27 Jun 2012 18:22:48 +0800 Amos Kong ak...@redhat.com wrote: On 27/06/12 04:21, Luiz Capitulino wrote: On Wed, 20 Jun 2012 12:47:40 +0800 Amos Kongak...@redhat.com wrote: Convert 'sendkey' to use QAPI. do_sendkey() depends on some variables/functions in monitor.c, so reserve qmp_sendkey() to monitor.c key_defs[] in monitor.c is the mapping of key name to keycode, Keys' order in the enmu and key_defs[] is same. Signed-off-by: Amos Kongak...@redhat.com --- hmp-commands.hx |2 +- hmp.c| 45 hmp.h|1 + monitor.c| 102 +++-- monitor.h|2 + qapi-schema.json | 45 qmp-commands.hx | 27 ++ 7 files changed, 165 insertions(+), 59 deletions(-) diff --git a/hmp-commands.hx b/hmp-commands.hx index e336251..fee4c14 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -505,7 +505,7 @@ ETEXI .args_type = keys:s,hold-time:i?, .params = keys [hold_ms], .help = send keys to the VM (e.g. 'sendkey ctrl-alt-f1', default hold time=100 ms), -.mhandler.cmd = do_sendkey, +.mhandler.cmd = hmp_sendkey, }, STEXI diff --git a/hmp.c b/hmp.c index b9cec1d..846e8b9 100644 --- a/hmp.c +++ b/hmp.c @@ -19,6 +19,7 @@ #include qemu-timer.h #include qmp-commands.h #include monitor.h +#include qapi-types.h static void hmp_handle_error(Monitor *mon, Error **errp) { @@ -1000,3 +1001,47 @@ void hmp_netdev_del(Monitor *mon, const QDict *qdict) qmp_netdev_del(id,err); hmp_handle_error(mon,err); } + +void hmp_sendkey(Monitor *mon, const QDict *qdict) +{ +const char *keys = qdict_get_str(qdict, keys); +KeyCodesList *keylist, *head = NULL, *tmp = NULL; +int has_hold_time = qdict_haskey(qdict, hold-time); +int hold_time = qdict_get_try_int(qdict, hold-time, -1); +Error *err = NULL; +char keyname_buf[16]; + Please, drop this blank line. +char *separator; +int keyname_len; + +while (1) { +separator = strchr(keys, '-'); +keyname_len = separator ? separator - keys : strlen(keys); +pstrcpy(keyname_buf, sizeof(keyname_buf), keys); + +/* Be compatible with old interface, convert user inputted */ +if (!strncmp(keyname_buf, , 1) keyname_len == 1) { +pstrcpy(keyname_buf, sizeof(keyname_buf), less); +keyname_len = 4; +} +keyname_buf[keyname_len] = 0; + +keylist = g_malloc0(sizeof(*keylist)); +keylist-value = get_key_index(keyname_buf); +keylist-next = NULL; + +if (tmp) +tmp-next = keylist; +tmp = keylist; +if (!head) +head = keylist; + +if (!separator) +break; +keys = separator + 1; +} + +qmp_sendkey(head, has_hold_time, hold_time,err); +hmp_handle_error(mon,err); +qapi_free_KeyCodesList(head); +} diff --git a/hmp.h b/hmp.h index 79d138d..bcc74d2 100644 --- a/hmp.h +++ b/hmp.h @@ -64,5 +64,6 @@ void hmp_device_del(Monitor *mon, const QDict *qdict); void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict); void hmp_netdev_add(Monitor *mon, const QDict *qdict); void hmp_netdev_del(Monitor *mon, const QDict *qdict); +void hmp_sendkey(Monitor *mon, const QDict *qdict); #endif diff --git a/monitor.c b/monitor.c index 6fa0104..863c0c6 100644 --- a/monitor.c +++ b/monitor.c @@ -1470,98 +1470,84 @@ static const KeyDef key_defs[] = { { 0, NULL }, }; -static int get_keycode(const char *key) +int get_key_index(const char *key) { This should be moved to hmp.c instead of making it public. The static 'key_defs' is used in this function, I tried to move key_defs definition to monitor.h, but I got this error: qemu/monitor.h:220:13: error: attempt to use poisoned TARGET_SPARC qemu/monitor.h:220:39: error: attempt to use poisoned TARGET_SPARC64 Where is the good place to define key_defs ? it would be used in monitor.c hmp.c You could move it to input.c (whose functions are declared in console.h). Actually, qmp_sendkey() should be moved there too. But I'm now wondering if we're doing it right. The HMP interface is supposed to be a real QMP client. However, to support hex keycodes it has to have knowledge of the key mapping. Having access to key_defs if cheating, as hmp.c is internal to qemu. The two solutions I can think of are adding query-keymap or change send-key to also accept hex values (which could be done through a new command). Ideas? -const KeyDef *p; +int i, keycode; char *endp; -int ret; +const KeyDef *p; -for(p = key_defs; p-name !=
Re: [Qemu-devel] [PATCH v2] bitops.h: Add field32() and field64() functions to extract bitfields
On 06/27/2012 04:15 PM, Avi Kivity wrote: On 06/27/2012 01:29 PM, Peter Maydell wrote: Add field32() and field64() functions which extract a particular bit field from a word and return it. Based on an idea by Jia Liu. +/** + * field64 - return a specified bit field from a uint64_t value + * @value: The value to extract the bit field from + * @start: The lowest bit in the bit field (numbered from 0) + * @length: The length of the bit field + * + * Returns the value of the bit field extracted from the input value. + */ +static inline uint64_t field64(uint64_t value, int start, int length) +{ +assert(start = 0 start = 63 length 0 start + length = 64); +return (value start) (~0ULL (64 - length)); +} + Undefined for length == 64, so better add that to the assert. Er, please ignore. It's undefined for length == 0, but that's uninteresting and protected by the assert. -- error compiling committee.c: too many arguments to function
Re: [Qemu-devel] [PATCH v2] bitops.h: Add field32() and field64() functions to extract bitfields
On 27 June 2012 14:15, Avi Kivity a...@redhat.com wrote: I suggest adding the analogous functions for writing. I believe the common naming is extract/deposit. static inline uint64_t deposit64(uint64_t *pvalue, unsigned start, unsigned length, uint64_t fieldval) { uint64_t mask = (((uint64_t)1 length) - 1) start; *pvalue = (*pvalue ~mask) | ((fieldval start) mask); } Useful for setting a bit to a specific value. Do you have a use case in mind for this one? -- PMM
Re: [Qemu-devel] [PATCH 1/2] Add usb option in machine options to enable/disable usb
On Wed, Jun 27, 2012 at 11:13 PM, Li Zhang zhlci...@gmail.com wrote: On Wed, Jun 27, 2012 at 8:00 PM, Andreas Färber afaer...@suse.de wrote: Am 18.06.2012 11:22, schrieb Li Zhang: For pseries machine, it needs to enable usb to add keyboard or usb mouse. -usb option won't be used in Grammar: The pseries machine needs to enable USB to add a keyboard or USB mouse. The -usb option ... the future, and machine options is a better way to are a better way enable usb. So this patch is to add usb option to machine options So this patch adds a USB option ... (-machine type=psereis,usb=on/off)to enable/disable pseries Space after ) please, Western fonts are probably more narrow. ;) OK, I will correct it. usb controller. For specific machines, they will get the machine option and then create usb controller according to usb option. In this patch, usb is on by default on pseries. So, for -nodefault,usb should be set off in the command Space before usb please. line as the following: -machine type=pseries,usb=off. Signed-off-by: Li Zhang zhlci...@linux.vnet.ibm.com --- hw/spapr.c | 10 ++ qemu-config.c | 4 2 files changed, 14 insertions(+), 0 deletions(-) diff --git a/hw/spapr.c b/hw/spapr.c index d0bddbc..8d158d7 100644 --- a/hw/spapr.c +++ b/hw/spapr.c @@ -529,6 +529,8 @@ static void ppc_spapr_init(ram_addr_t ram_size, long load_limit, rtas_limit, fw_size; long pteg_shift = 17; char *filename; + QemuOpts * machine_opts; QemuOpts *machine_opts; checkpatch.pl sometimes emits bogus warnings about this. OK. I will use it to do that. :) + bool usb_on = false; Didn't you want this to be true for sPAPR in absence of -machine? It is set in the following: if (machine_opts) usb_on = qemu_opt_get_bool(machine_opts, usb, true); It means that when using -machine option, usb_on is set as true if usb option is not specified. Maybe use a more functional naming? It's either added or not, so add_usb perhaps or provide_usb? Purely stylistic of course. spapr = g_malloc0(sizeof(*spapr)); QLIST_INIT(spapr-phbs); @@ -661,6 +663,14 @@ static void ppc_spapr_init(ram_addr_t ram_size, spapr_vscsi_create(spapr-vio_bus); } + machine_opts = qemu_opts_find(qemu_find_opts(machine), 0); + if (machine_opts) + usb_on = qemu_opt_get_bool(machine_opts, usb, true); Still missing braces for if. Other than that looking good to me now. Where's 2/2? 2/2's title is as the following: [Qemu-devel][PATCH 2/2] spapr: Add support for -vga option. :) Please post the fixed version as a top-level [PATCH v4] along with a small change log after --- or in a cover letter. OK. I will do that. :) Andreas + + if (usb_on) { + pci_create_simple(QLIST_FIRST(spapr-phbs)-host_state.bus, + -1, pci-ohci); + } if (rma_size (MIN_RMA_SLOF 20)) { fprintf(stderr, qemu: pSeries SLOF firmware requires = %ldM guest RMA (Real Mode Area memory)\n, MIN_RMA_SLOF); diff --git a/qemu-config.c b/qemu-config.c index bb3bff4..cdab765 100644 --- a/qemu-config.c +++ b/qemu-config.c @@ -583,6 +583,10 @@ static QemuOptsList qemu_machine_opts = { .name = dtb, .type = QEMU_OPT_STRING, .help = Linux kernel device tree file, + },{ + .name = usb, + .type = QEMU_OPT_BOOL, + .help = Set on/off to enable/disable usb, }, { /* End of list */ } }, -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg -- Best Regards -Li