Re: [Qemu-devel] [RFC PATCH] trace: Replace error with warning if event is not defined
Copying Stefan. scripts/get_maintainer.pl would've told you so :) Alexey Kardashevskiy a...@ozlabs.ru writes: At the moment QEMU exits if trace point is not defined which makes a developer life harder if he has to switch between branches with different traces implemented. This replaces error+exit wit WARNING if the tracepoint does not exist or not traceable. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- That would make my life easier indeed. Thanks :) --- trace/control.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/trace/control.c b/trace/control.c index 49f61e1..4aa02cf 100644 --- a/trace/control.c +++ b/trace/control.c @@ -112,15 +112,15 @@ void trace_backend_init_events(const char *fname) TraceEvent *ev = trace_event_name(line_ptr); if (ev == NULL) { fprintf(stderr, -error: trace event '%s' does not exist\n, line_ptr); -exit(1); -} -if (!trace_event_get_state_static(ev)) { +WARNING: trace event '%s' does not exist\n, +line_ptr); +} else if (!trace_event_get_state_static(ev)) { fprintf(stderr, -error: trace event '%s' is not traceable\n, line_ptr); -exit(1); +WARNING: trace event '%s' is not traceable\n, +line_ptr); +} else { +trace_event_set_state_dynamic(ev, enable); } -trace_event_set_state_dynamic(ev, enable); } } }
Re: [Qemu-devel] patch: add -kbddelay option
Dave Mielke d...@mielke.cc writes: [quoted lines by Dave Mielke on 2014/05/26 at 08:59 -0400] I'm sorry for quoting myself, but I'm doing it for context since I have a question: This patch, attached as qemu-kbddelay-1.patch, is a rework of the former curses UI patch so that the delay applies to key events in general. A new option, -kbddelay [duration=]msecs, controls it. As before, the default is 0, meaning no delay, in which case the timer and queue aren't used thus retaining the original behaviour. I've currently coded it so that there's a new option - -kbddelay. So, we have the following two options: (old) -k language (new) -kbddelay [duration=]msecs My question is if this is the best way to do it, or if the two options should be merged. For example: -k [language=]language,delay=msecs What do you think? *If* the feature is deemed useful: better extend -k. We generally prefer extensible options based on QemuOpts to proliferating ad hoc single-purpose options.
[Qemu-devel] [PATCH 0/2] test virtio-blk hotplug
It's worth to add a hotplug test to qtest, but without cooperation of guest OS, new devices can't be initialized by guest, and hot-unplug doesn't work. However, the new test can cover some part of code of hotplug/unplug. Amos Kong (2): virtio-blk-test.c: change pci_nop() to virtblk_init() virtio-blk-test.c: add hotplug subtest tests/virtio-blk-test.c | 68 - 1 file changed, 61 insertions(+), 7 deletions(-) -- 1.9.0
[Qemu-devel] [PATCH 2/2] virtio-blk-test.c: add hotplug subtest
This patch adds a new subtest, it hotplugs 29 * 8 = 232 virtio-blk devices to guest, and try to hot-unplug them. Note: the hot-unplug can't work without cooperation of guest OS. Signed-off-by: Amos Kong ak...@redhat.com --- tests/virtio-blk-test.c | 55 + 1 file changed, 55 insertions(+) diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c index 0fdec01..54d1272 100644 --- a/tests/virtio-blk-test.c +++ b/tests/virtio-blk-test.c @@ -7,11 +7,65 @@ * See the COPYING file in the top-level directory. */ +#include stdio.h #include glib.h #include string.h #include libqtest.h #include qemu/osdep.h +static void exec_hmp_cmd(const char *cmd, const char *expected_ret) +{ +QDict *response; +const char *response_return; + +response = qmp({\execute\: \human-monitor-command\, +\arguments\: { + \command-line\: \%s\ + }}, cmd); +g_assert(response); +response_return = qdict_get_try_str(response, return); +g_assert(response_return); +g_assert(strcmp(response_return, expected_ret) == 0); +QDECREF(response); +} + +static void test_blk_hotplug(void) +{ +char addr[6]; +char cmd[100]; +int i, j; + +/* Start with no network/block device, slots 3~0x1f are free */ +qtest_start(-net none); + +for (i = 3; i = 0x1f; i++) { +for (j = 7; j = 0; j--) { +sprintf(addr, %x.%x, i, j); +sprintf(cmd, drive_add 0x%s if=none,file=/dev/null,id=drv-%s, +addr, addr); +exec_hmp_cmd(cmd, OK\r\n); + +sprintf(cmd, device_add virtio-blk-pci,id=dev-%s,drive=drv-%s, + addr=0x%s,multifunction=on, addr, addr, addr); +exec_hmp_cmd(cmd, ); +} +} + +/* hot-unplug doesn't work without cooperation of guest OS */ +for (i = 3; i = 0x1f; i++) { +for (j = 7; j = 0; j--) { +sprintf(addr, %x.%x, i, j); +sprintf(cmd, drive_del drv-%s, addr); +exec_hmp_cmd(cmd, ); + +sprintf(cmd, device_del dev-%s, addr); +exec_hmp_cmd(cmd, ); +} +} + +qtest_end(); +} + /* Tests only initialization */ static void virtblk_init(void) { @@ -26,6 +80,7 @@ int main(int argc, char **argv) g_test_init(argc, argv, NULL); qtest_add_func(/virtio/blk/pci/init, virtblk_init); +qtest_add_func(/virtio/blk/pci/hotplug, test_blk_hotplug); ret = g_test_run(); -- 1.9.0
[Qemu-devel] [PATCH 1/2] virtio-blk-test.c: change pci_nop() to virtblk_init()
I want to add a new subtest in virtio-blk-test.c, it will start guest without network. The original pci_init() did nothing, but it's good to reserve a very simple initialization testing. Signed-off-by: Amos Kong ak...@redhat.com --- tests/virtio-blk-test.c | 13 ++--- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c index d53f875..0fdec01 100644 --- a/tests/virtio-blk-test.c +++ b/tests/virtio-blk-test.c @@ -12,9 +12,12 @@ #include libqtest.h #include qemu/osdep.h -/* Tests only initialization so far. TODO: Replace with functional tests */ -static void pci_nop(void) +/* Tests only initialization */ +static void virtblk_init(void) { +qtest_start(-drive id=drv0,if=none,file=/dev/null +-device virtio-blk-pci,drive=drv0); +qtest_end(); } int main(int argc, char **argv) @@ -22,13 +25,9 @@ int main(int argc, char **argv) int ret; g_test_init(argc, argv, NULL); -qtest_add_func(/virtio/blk/pci/nop, pci_nop); +qtest_add_func(/virtio/blk/pci/init, virtblk_init); -qtest_start(-drive id=drv0,if=none,file=/dev/null --device virtio-blk-pci,drive=drv0); ret = g_test_run(); -qtest_end(); - return ret; } -- 1.9.0
[Qemu-devel] How to enable more than 2047 MB RAM on 32 bit host systems for 32 bit guests?
Hi all, I would like to provide 3GB of RAM to my guest - I use kvm and don't see a real reason why this should not work. Currently, qemu-1.7.0 with kvm is in use. Any hints or solutions are welcome. Thanks. Best regards, Erik
Re: [Qemu-devel] [PATCH 5/9] target-ppc: Add POWER8 SPRs
On 05/27/2014 06:09 AM, Alexander Graf wrote: On 26.05.14 17:45, Alexey Kardashevskiy wrote: On 05/22/2014 04:08 AM, Tom Musta wrote: On 5/21/2014 1:20 AM, Alexey Kardashevskiy wrote: This adds helper which adds TAR/BESCRS/BESCRSU/BESCRR/BESCRRU/ EBBHR/EBBRR/BESCR/TFHAR/TFIAR/TEXASR/TEXASRU SPRs. This adds MMCR2/FSCR/MMCRS SPRs. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- target-ppc/cpu.h| 15 ++ target-ppc/translate_init.c | 123 ++-- 2 files changed, 112 insertions(+), 26 deletions(-) diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 262cf0f..72ed763 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -1258,6 +1258,10 @@ static inline int cpu_mmu_index (CPUPPCState *env) #define SPR_MPC_EIE (0x050) #define SPR_MPC_EID (0x051) #define SPR_MPC_NRI (0x052) +#define SPR_TFHAR (0x080) +#define SPR_TFIAR (0x081) +#define SPR_TEXASR(0x082) +#define SPR_TEXASRU (0x083) #define SPR_UCTRL (0x088) #define SPR_MPC_CMPA (0x090) #define SPR_MPC_CMPB (0x091) @@ -1270,6 +1274,7 @@ static inline int cpu_mmu_index (CPUPPCState *env) #define SPR_CTRL (0x098) #define SPR_MPC_CMPE (0x098) #define SPR_MPC_CMPF (0x099) +#define SPR_FSCR (0x099) #define SPR_MPC_CMPG (0x09A) #define SPR_MPC_CMPH (0x09B) #define SPR_MPC_LCTRL1(0x09C) @@ -1461,6 +1466,7 @@ static inline int cpu_mmu_index (CPUPPCState *env) #define SPR_MPC_MI_CTR(0x300) #define SPR_PERF1 (0x301) #define SPR_RCPU_MI_RBA1 (0x301) +#define SPR_POWER_UMMCR2 (0x301) #define SPR_PERF2 (0x302) #define SPR_RCPU_MI_RBA2 (0x302) #define SPR_MPC_MI_AP (0x302) @@ -1500,6 +1506,7 @@ static inline int cpu_mmu_index (CPUPPCState *env) #define SPR_MPC_MD_TW (0x30F) #define SPR_UPERF0(0x310) #define SPR_UPERF1(0x311) +#define SPR_POWER_MMCR2 (0x311) #define SPR_UPERF2(0x312) #define SPR_MMCRA (0x312) #define SPR_UPERF3(0x313) @@ -1519,11 +1526,18 @@ static inline int cpu_mmu_index (CPUPPCState *env) #define SPR_UPERFF(0x31F) #define SPR_RCPU_MI_RA0 (0x320) #define SPR_MPC_MI_DBCAM (0x320) +#define SPR_BESCRS(0x320) #define SPR_RCPU_MI_RA1 (0x321) #define SPR_MPC_MI_DBRAM0 (0x321) +#define SPR_BESCRSU (0x321) #define SPR_RCPU_MI_RA2 (0x322) #define SPR_MPC_MI_DBRAM1 (0x322) +#define SPR_BESCRR(0x322) #define SPR_RCPU_MI_RA3 (0x323) +#define SPR_BESCRRU (0x323) +#define SPR_EBBHR (0x324) +#define SPR_EBBRR (0x325) +#define SPR_BESCR (0x326) #define SPR_RCPU_L2U_RA0 (0x328) #define SPR_MPC_MD_DBCAM (0x328) #define SPR_RCPU_L2U_RA1 (0x329) @@ -1542,6 +1556,7 @@ static inline int cpu_mmu_index (CPUPPCState *env) #define SPR_440_ITV3 (0x377) #define SPR_440_CCR1 (0x378) #define SPR_DCRIPR(0x37B) +#define SPR_MMCRS (0x37E) #define SPR_PPR (0x380) #define SPR_750_GQR0 (0x390) #define SPR_440_DNV0 (0x390) diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 3c37e93..d23fcc6 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -7951,37 +7951,108 @@ POWERPC_FAMILY(POWER7P)(ObjectClass *oc, void *data) pcc-interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr; } -static void init_proc_POWER8(CPUPPCState *env) +static void get_spr_power8_branch_control(CPUPPCState *env) { -gen_spr_ne_601(env); -gen_spr_7xx(env); -/* Time base */ -gen_tbl(env); -gen_spr_book3s_ids(env); -gen_spr_book3s_common(env); -gen_spr_amr(env); -gen_spr_book3s_vr(env); -gen_spr_book3s_lpar(env); -gen_spr_book3s_purr(env); -gen_spr_book3s_debug(env); -gen_spr_book3s_pmu(env); -#if !defined(CONFIG_USER_ONLY) -env-slb_nr = 32; -#endif /* !CONFIG_USER_ONLY */ -init_excp_POWER7(env); -env-dcache_line_size = 128; -env-icache_line_size = 128; - -/* Allocate hardware IRQ controller */ -ppcPOWER7_irq_init(env); -/* Can't find information on what this should be on reset. This - * value is the one used by 74xx processors. */ -vscr_init(env, 0x0001); - spr_register(env, SPR_TAR, TAR, spr_read_generic, spr_write_generic, spr_read_generic, spr_write_generic, 0x); + +spr_register(env, SPR_BESCRS, BESCRS, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, spr_write_generic, +
Re: [Qemu-devel] [Qemu-trivial] [PATCH] Fix 'name' option to work with -readconfig
* Michael Tokarev (m...@tls.msk.ru) wrote: 06.05.2014 15:15, Dr. David Alan Gilbert (git) wrote: From: Dr. David Alan Gilbert dgilb...@redhat.com The 'name' option silently failed when used in config files ( http://lists.gnu.org/archive/html/qemu-devel/2014-04/msg00378.html ) Signed-off-by: Dr. David Alan Gilbert dgilb...@redhat.com Reported-by: William Dauchy wdau...@gmail.com Applied to -trivial, after: 1. Changing Reported/Tested-by as asked by William Dauchy 2. Adding a subject prefix (vl) 3. Adding commit message as suggested by Marcus 4. Adding Marcus's Reviewed-by. Oh ma... ;) Thank you! And please excuse me for it took so long. It'd be faster if I hadn't do all th e above ;) Thanks, and apologies for not fixing those up. Dave -- Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK
[Qemu-devel] [PATCH v3] rules.mak: Rewrite unnest-vars
The macro unnest-vars is the most important, complicated but hard to track magic in QEMU's build system. Rewrite it in a (hopefully) clearer way, with more comments, to make it easier to understand and maintain. Remove DSO_CFLAGS and module-objs-m that are not used. A bonus fix of this version is, per object variables are properly protected in save-objs and load-objs, before including sub-dir Makefile.objs, just as nested variables are. So the occasional same object name from different directory levels won't step on each other's foot. Signed-off-by: Fam Zheng f...@redhat.com --- v3: $(value $v) - $($v) in fix-paths. [Paolo] Fixed tab - 4 spaces. [Paolo] Fixed module-m. --- rules.mak | 227 ++ 1 file changed, 156 insertions(+), 71 deletions(-) diff --git a/rules.mak b/rules.mak index b12d312..1cdb5bf 100644 --- a/rules.mak +++ b/rules.mak @@ -78,13 +78,16 @@ endif %.o: %.dtrace $(call quiet-command,dtrace -o $@ -G -s $, GEN $(TARGET_DIR)$@) -DSO_CFLAGS := -fPIC -DBUILD_DSO +%$(DSOSUF): CFLAGS += -fPIC -DBUILD_DSO %$(DSOSUF): LDFLAGS += $(LDFLAGS_SHARED) -%$(DSOSUF): %.mo libqemustub.a +%$(DSOSUF): libqemustub.a module-common.o $(call LINK,$^) @# Copy to build root so modules can be loaded when program started without install $(if $(findstring /,$@),$(call quiet-command,cp $@ $(subst /,-,$@), CP$(subst /,-,$@))) +%.mo: + $(call quiet-command,touch $@, GEN$(TARGET_DIR)$@) + .PHONY: modules modules: @@ -161,82 +164,164 @@ clean: clean-timestamp # will delete the target of a rule if commands exit with a nonzero exit status .DELETE_ON_ERROR: -# magic to descend into other directories - -define push-var -$(eval save-$2-$1 = $(value $1)) -$(eval $1 :=) -endef - -define pop-var -$(eval subdir-$2-$1 := $(if $(filter $2,$(save-$2-$1)),$(addprefix $2,$($1 -$(eval $1 = $(value save-$2-$1) $$(subdir-$2-$1)) -$(eval save-$2-$1 :=) -endef - -define fix-obj-vars -$(if $2, $(foreach v,$($1), \ - $(if $($v-cflags), \ - $(eval $2/$v-cflags := $($v-cflags)) \ - $(eval $v-cflags := )) \ - $(if $($v-libs), \ - $(eval $2/$v-libs := $($v-libs)) \ - $(eval $v-libs := )) \ - $(if $($v-objs), \ - $(eval $2/$v-objs := $(addprefix $2/,$($v-objs))) \ - $(eval $v-objs := +# save-vars +# Usage: $(call save-vars, vars) +# Save each variable $v in $vars as save-vars-$v, save their object's +# variables, then clear $v. +define save-vars +$(foreach v,$1, +$(eval save-vars-$v := $(value $v)) +$(foreach o,$($v), +$(foreach k,cflags libs objs, +$(if $($o-$k), +$(eval save-vars-$o-$k := $($o-$k)) +$(eval $o-$k := +$(eval $v := )) endef -define unnest-dir -$(foreach var,$(nested-vars),$(call push-var,$(var),$1/)) -$(eval obj-parent-$1 := $(obj)) -$(eval obj := $(if $(obj),$(obj)/$1,$1)) -$(eval include $(SRC_PATH)/$1/Makefile.objs) -$(foreach v,$(nested-vars),$(call fix-obj-vars,$v,$(obj))) -$(eval obj := $(obj-parent-$1)) -$(eval obj-parent-$1 := ) -$(foreach var,$(nested-vars),$(call pop-var,$(var),$1/)) +# load-vars +# Usage: $(call load-vars, vars, add_var) +# Load the saved value for each variable in @vars, and the per object +# variables. +# Append @add_var's current value to the loaded value. +define load-vars +$(eval $2-new-value := $(value $2)) +$(foreach v,$1, +$(eval $v := $(value save-vars-$v)) +$(foreach o,$($v), +$(foreach k,cflags libs objs, +$(if $(save-vars-$o-$k), +$(eval $o-$k := $(save-vars-$o-$k)) +$(eval save-vars-$o-$k := +$(eval save-vars-$v := )) +$(eval $2 := $(value $2) $($2-new-value)) endef -define unnest-vars-1 -$(eval nested-dirs := $(filter-out \ -$(old-nested-dirs), \ -$(sort $(foreach var,$(nested-vars), $(filter %/, $($(var))) -$(if $(nested-dirs), - $(foreach dir,$(nested-dirs),$(call unnest-dir,$(patsubst %/,%,$(dir - $(eval old-nested-dirs := $(old-nested-dirs) $(nested-dirs)) - $(call unnest-vars-1)) +# fix-paths +# Usage: $(call fix-paths, obj_path, src_path, vars) +# Add prefix @obj_path to all objects in @vars, and add prefix @src_path to all +# directories in @vars. +define fix-paths +$(foreach v,$3, +$(foreach o,$($v), +$(if $($o-libs), +$(eval $1$o-libs := $($o-libs))) +$(if $($o-cflags), +$(eval $1$o-cflags := $($o-cflags))) +$(if $($o-objs), +$(eval $1$o-objs := $(addprefix $1,$($o-objs) +$(eval $v := $(addprefix $1,$(filter-out %/,$($v))) \ + $(addprefix $2,$(filter %/,$($v) endef -define process-modules -$(foreach o,$(filter %.o,$($1)), - $(eval $(patsubst %.o,%.mo,$o): $o) \ -
Re: [Qemu-devel] [Qemu-trivial] patch: add delay=msecs suboption to -display curses
[quoted lines by Gerd Hoffmann on 2014/05/27 at 07:44 +0200] What exactly is the problem? At the user level, the keyboard appears to be dead. An inspection of the udnerlying code reveals that the application itsllf is querying the MS-DOS keyboard input buffer in a bad way. Those apps can't be fixed, though, because the bad code is in a library which is statically linked into every app using it, which means lots of apps, many of which, as is always the case, may not even have source code anymore. Another thing to consider is that this, really, is a general problem. Most keyboard input code, especially in older days, would've nly ever been tested at typing speed. It should be expected, therefore, that there might be problems in some of it when input events arrive faster - in this case, infinitely fater. The solution I'm proposing, therefore, tackles it in a general way, and does nothing more than allow the user to request that, regardless of what the UI needs to do underneath, the keyboard events still arrive at the speed of a typist. Did you see my other question abot either adding -kbddelay [duration=]msecs or merging it into -k (-k [language=]language[,delay=msecs]? Which would be the better approach? -- Dave Mielke | 2213 Fox Crescent | The Bible is the very Word of God. Phone: 1-613-726-0014 | Ottawa, Ontario | http://Mielke.cc/bible/ EMail: d...@mielke.cc | Canada K2A 1H7 | http://FamilyRadio.com/
[Qemu-devel] [PATCH] qtest: fix hex2nib for capital characters
From: Sergey Fedorov serge.f...@gmail.com Signed-off-by: Sergey Fedorov serge.f...@gmail.com --- qtest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qtest.c b/qtest.c index 2aba20d..87ccd62 100644 --- a/qtest.c +++ b/qtest.c @@ -148,7 +148,7 @@ static int hex2nib(char ch) } else if (ch = 'a' ch = 'f') { return 10 + (ch - 'a'); } else if (ch = 'A' ch = 'F') { -return 10 + (ch - 'a'); +return 10 + (ch - 'A'); } else { return -1; } -- 1.9.1
Re: [Qemu-devel] [PATCH v3] rules.mak: Rewrite unnest-vars
Il 27/05/2014 09:54, Fam Zheng ha scritto: The macro unnest-vars is the most important, complicated but hard to track magic in QEMU's build system. Rewrite it in a (hopefully) clearer way, with more comments, to make it easier to understand and maintain. Remove DSO_CFLAGS and module-objs-m that are not used. A bonus fix of this version is, per object variables are properly protected in save-objs and load-objs, before including sub-dir Makefile.objs, just as nested variables are. So the occasional same object name from different directory levels won't step on each other's foot. Signed-off-by: Fam Zheng f...@redhat.com --- v3: $(value $v) - $($v) in fix-paths. [Paolo] Fixed tab - 4 spaces. [Paolo] Fixed module-m. --- rules.mak | 227 ++ 1 file changed, 156 insertions(+), 71 deletions(-) diff --git a/rules.mak b/rules.mak index b12d312..1cdb5bf 100644 --- a/rules.mak +++ b/rules.mak @@ -78,13 +78,16 @@ endif %.o: %.dtrace $(call quiet-command,dtrace -o $@ -G -s $, GEN $(TARGET_DIR)$@) -DSO_CFLAGS := -fPIC -DBUILD_DSO +%$(DSOSUF): CFLAGS += -fPIC -DBUILD_DSO %$(DSOSUF): LDFLAGS += $(LDFLAGS_SHARED) -%$(DSOSUF): %.mo libqemustub.a +%$(DSOSUF): libqemustub.a module-common.o $(call LINK,$^) @# Copy to build root so modules can be loaded when program started without install $(if $(findstring /,$@),$(call quiet-command,cp $@ $(subst /,-,$@), CP $(subst /,-,$@))) +%.mo: + $(call quiet-command,touch $@, GEN$(TARGET_DIR)$@) + .PHONY: modules modules: @@ -161,82 +164,164 @@ clean: clean-timestamp # will delete the target of a rule if commands exit with a nonzero exit status .DELETE_ON_ERROR: -# magic to descend into other directories - -define push-var -$(eval save-$2-$1 = $(value $1)) -$(eval $1 :=) -endef - -define pop-var -$(eval subdir-$2-$1 := $(if $(filter $2,$(save-$2-$1)),$(addprefix $2,$($1 -$(eval $1 = $(value save-$2-$1) $$(subdir-$2-$1)) -$(eval save-$2-$1 :=) -endef - -define fix-obj-vars -$(if $2, $(foreach v,$($1), \ - $(if $($v-cflags), \ - $(eval $2/$v-cflags := $($v-cflags)) \ - $(eval $v-cflags := )) \ - $(if $($v-libs), \ - $(eval $2/$v-libs := $($v-libs)) \ - $(eval $v-libs := )) \ - $(if $($v-objs), \ - $(eval $2/$v-objs := $(addprefix $2/,$($v-objs))) \ - $(eval $v-objs := +# save-vars +# Usage: $(call save-vars, vars) +# Save each variable $v in $vars as save-vars-$v, save their object's +# variables, then clear $v. +define save-vars +$(foreach v,$1, +$(eval save-vars-$v := $(value $v)) +$(foreach o,$($v), +$(foreach k,cflags libs objs, +$(if $($o-$k), +$(eval save-vars-$o-$k := $($o-$k)) +$(eval $o-$k := +$(eval $v := )) endef -define unnest-dir -$(foreach var,$(nested-vars),$(call push-var,$(var),$1/)) -$(eval obj-parent-$1 := $(obj)) -$(eval obj := $(if $(obj),$(obj)/$1,$1)) -$(eval include $(SRC_PATH)/$1/Makefile.objs) -$(foreach v,$(nested-vars),$(call fix-obj-vars,$v,$(obj))) -$(eval obj := $(obj-parent-$1)) -$(eval obj-parent-$1 := ) -$(foreach var,$(nested-vars),$(call pop-var,$(var),$1/)) +# load-vars +# Usage: $(call load-vars, vars, add_var) +# Load the saved value for each variable in @vars, and the per object +# variables. +# Append @add_var's current value to the loaded value. +define load-vars +$(eval $2-new-value := $(value $2)) +$(foreach v,$1, +$(eval $v := $(value save-vars-$v)) +$(foreach o,$($v), +$(foreach k,cflags libs objs, +$(if $(save-vars-$o-$k), +$(eval $o-$k := $(save-vars-$o-$k)) +$(eval save-vars-$o-$k := +$(eval save-vars-$v := )) +$(eval $2 := $(value $2) $($2-new-value)) endef -define unnest-vars-1 -$(eval nested-dirs := $(filter-out \ -$(old-nested-dirs), \ -$(sort $(foreach var,$(nested-vars), $(filter %/, $($(var))) -$(if $(nested-dirs), - $(foreach dir,$(nested-dirs),$(call unnest-dir,$(patsubst %/,%,$(dir - $(eval old-nested-dirs := $(old-nested-dirs) $(nested-dirs)) - $(call unnest-vars-1)) +# fix-paths +# Usage: $(call fix-paths, obj_path, src_path, vars) +# Add prefix @obj_path to all objects in @vars, and add prefix @src_path to all +# directories in @vars. +define fix-paths +$(foreach v,$3, +$(foreach o,$($v), +$(if $($o-libs), +$(eval $1$o-libs := $($o-libs))) +$(if $($o-cflags), +$(eval $1$o-cflags := $($o-cflags))) +$(if $($o-objs), +$(eval $1$o-objs := $(addprefix $1,$($o-objs) +$(eval $v := $(addprefix $1,$(filter-out %/,$($v))) \ + $(addprefix $2,$(filter %/,$($v) endef -define process-modules -$(foreach o,$(filter %.o,$($1)), -
[Qemu-devel] [PATCH V9 0/4] qemu-img: add preallocation=full
From: Hu Tao hu...@cn.fujitsu.com The purpose of this series is to use posix_fallocate() when creating img file to ensure there are disk space for it which is way fast than acturally writing to disk. But this only works in file system level. For cases like thin provisioning, an option full preallocation is added to write zeros to storage to ensure disk space. changes to v8 are mainly address Eric's comments, as: - round up image file size to nearest sector size - dont' blindly lose error info - target for 2.1 rather than 2.0 - and, rebase to latest git tree Hu Tao (4): qapi: introduce PreallocMode and a new PreallocMode full. raw, qcow2: don't convert file size to sector size raw-posix: Add full image preallocation option qcow2: Add full image preallocation option block/qcow2.c | 95 -- block/raw-posix.c | 64 +++ block/raw-win32.c | 5 ++- qapi-schema.json | 14 +++ tests/qemu-iotests/082.out | 54 +- 5 files changed, 184 insertions(+), 48 deletions(-) -- 1.9.3
Re: [Qemu-devel] [Qemu-stable] [PATCH 01/14] qemu-img: Plug memory leak on block option help error path
The Monday 26 May 2014 à 19:37:02 (+0200), Markus Armbruster wrote : Introduced in commit a283cb6; mostly harmless. Spotted by Coverity. Signed-off-by: Markus Armbruster arm...@redhat.com --- qemu-img.c | 1 + 1 file changed, 1 insertion(+) diff --git a/qemu-img.c b/qemu-img.c index 1ad899e..62ea27e 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -287,6 +287,7 @@ static int print_block_option_help(const char *filename, const char *fmt) proto_drv = bdrv_find_protocol(filename, true); if (!proto_drv) { error_report(Unknown protocol '%s', filename); +free_option_parameters(create_options); return 1; } create_options = append_option_parameters(create_options, -- 1.9.3 Reviewed-by: Benoit Canet ben...@irqsave.net
[Qemu-devel] [PATCH V9 1/4] qapi: introduce PreallocMode and a new PreallocMode full.
From: Hu Tao hu...@cn.fujitsu.com This patch prepares for the subsequent patches. Reviewed-by: Fam Zheng f...@redhat.com Reviewed-by: Eric Blake ebl...@redhat.com Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- block/qcow2.c| 8 qapi-schema.json | 14 ++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index a4b97e8..51f547d 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1594,7 +1594,7 @@ static int preallocate(BlockDriverState *bs) static int qcow2_create2(const char *filename, int64_t total_size, const char *backing_file, const char *backing_format, - int flags, size_t cluster_size, int prealloc, + int flags, size_t cluster_size, PreallocMode prealloc, QEMUOptionParameter *options, int version, Error **errp) { @@ -1771,7 +1771,7 @@ static int qcow2_create(const char *filename, QEMUOptionParameter *options, uint64_t sectors = 0; int flags = 0; size_t cluster_size = DEFAULT_CLUSTER_SIZE; -int prealloc = 0; +PreallocMode prealloc = PREALLOC_MODE_OFF; int version = 3; Error *local_err = NULL; int ret; @@ -1792,9 +1792,9 @@ static int qcow2_create(const char *filename, QEMUOptionParameter *options, } } else if (!strcmp(options-name, BLOCK_OPT_PREALLOC)) { if (!options-value.s || !strcmp(options-value.s, off)) { -prealloc = 0; +prealloc = PREALLOC_MODE_OFF; } else if (!strcmp(options-value.s, metadata)) { -prealloc = 1; +prealloc = PREALLOC_MODE_METADATA; } else { error_setg(errp, Invalid preallocation mode: '%s', options-value.s); diff --git a/qapi-schema.json b/qapi-schema.json index 7bc33ea..80abcb7 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -4722,3 +4722,17 @@ 'btn' : 'InputBtnEvent', 'rel' : 'InputMoveEvent', 'abs' : 'InputMoveEvent' } } + +## +# @PreallocMode +# +# Preallocation mode of QEMU image file +# +# @off: no preallocation +# @metadata: preallocate only for metadata +# @full: preallocate all data, including metadata +# +# Since 2.1 +## +{ 'enum': 'PreallocMode', + 'data': [ 'off', 'metadata', 'full' ] } -- 1.9.3
[Qemu-devel] [PATCH V9 3/4] raw-posix: Add full image preallocation option
From: Hu Tao hu...@cn.fujitsu.com This patch adds a new option preallocation for raw format, and implements full preallocation by writing zeros to disk. The metadata option is changed to use posix_fallocate() to ensure subsquent writes to image file won't fail because of lack of disk space. The purpose is to ensure disk space for image file. In cases posix_fallocate() is supported, metadata option can be used, otherwise (posix_fallocate() is not supported by filesystem, or in case of thin provisioning), full option has to be used. User has to choose the proper way to use. Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- block/raw-posix.c | 61 --- 1 file changed, 54 insertions(+), 7 deletions(-) diff --git a/block/raw-posix.c b/block/raw-posix.c index 710ea9b..07e2088 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -1246,6 +1246,7 @@ static int raw_create(const char *filename, QEMUOptionParameter *options, int fd; int result = 0; int64_t total_size = 0; +PreallocMode prealloc = PREALLOC_MODE_OFF; strstart(filename, file:, filename); @@ -1254,6 +1255,18 @@ static int raw_create(const char *filename, QEMUOptionParameter *options, if (!strcmp(options-name, BLOCK_OPT_SIZE)) { total_size = (options-value.n + BDRV_SECTOR_SIZE) BDRV_SECTOR_MASK; +} else if (!strcmp(options-name, BLOCK_OPT_PREALLOC)) { +if (!options-value.s || !strcmp(options-value.s, off)) { +prealloc = PREALLOC_MODE_OFF; +} else if (!strcmp(options-value.s, metadata)) { +prealloc = PREALLOC_MODE_METADATA; +} else if (!strcmp(options-value.s, full)) { +prealloc = PREALLOC_MODE_FULL; +} else { +error_setg(errp, Invalid preallocation mode: '%s', + options-value.s); +return -EINVAL; +} } options++; } @@ -1263,16 +1276,45 @@ static int raw_create(const char *filename, QEMUOptionParameter *options, if (fd 0) { result = -errno; error_setg_errno(errp, -result, Could not create file); -} else { -if (ftruncate(fd, total_size) != 0) { -result = -errno; -error_setg_errno(errp, -result, Could not resize file); +goto out; +} +if (ftruncate(fd, total_size) != 0) { +result = -errno; +error_setg_errno(errp, -result, Could not resize file); +goto out_close; +} +if (prealloc == PREALLOC_MODE_METADATA) { +/* posix_fallocate() doesn't set errno. */ +result = -posix_fallocate(fd, 0, total_size); +if (result != 0) { +error_setg_errno(errp, -result, + Could not preallocate data for the new file); } -if (qemu_close(fd) != 0) { -result = -errno; -error_setg_errno(errp, -result, Could not close the new file); +} else if (prealloc == PREALLOC_MODE_FULL) { +char *buf = g_malloc0(65536); +int64_t num = 0, left = total_size; + +while (left 0) { +num = MIN(left, 65536); +result = write(fd, buf, num); +if (result 0) { +result = -errno; +error_setg_errno(errp, -result, + Could not write to the new file); +g_free(buf); +goto out_close; +} +left -= num; } +fsync(fd); +g_free(buf); +} +out_close: +if (qemu_close(fd) != 0 result == 0) { +result = -errno; +error_setg_errno(errp, -result, Could not close the new file); } +out: return result; } @@ -1447,6 +1489,11 @@ static QEMUOptionParameter raw_create_options[] = { .type = OPT_SIZE, .help = Virtual disk size }, +{ +.name = BLOCK_OPT_PREALLOC, +.type = OPT_STRING, +.help = Preallocation mode (allowed values: off, metadata, full) +}, { NULL } }; -- 1.9.3
[Qemu-devel] [PATCH V9 2/4] raw, qcow2: don't convert file size to sector size
From: Hu Tao hu...@cn.fujitsu.com and avoid converting it back later. And round up file size to nearest sector. Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- block/qcow2.c | 8 block/raw-posix.c | 5 +++-- block/raw-win32.c | 5 +++-- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index 51f547d..81c2979 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1715,7 +1715,7 @@ static int qcow2_create2(const char *filename, int64_t total_size, } /* Okay, now that we have a valid image, let's give it the right size */ -ret = bdrv_truncate(bs, total_size * BDRV_SECTOR_SIZE); +ret = bdrv_truncate(bs, total_size); if (ret 0) { error_setg_errno(errp, -ret, Could not resize image); goto out; @@ -1768,7 +1768,7 @@ static int qcow2_create(const char *filename, QEMUOptionParameter *options, { const char *backing_file = NULL; const char *backing_fmt = NULL; -uint64_t sectors = 0; +uint64_t size = 0; int flags = 0; size_t cluster_size = DEFAULT_CLUSTER_SIZE; PreallocMode prealloc = PREALLOC_MODE_OFF; @@ -1779,7 +1779,7 @@ static int qcow2_create(const char *filename, QEMUOptionParameter *options, /* Read out options */ while (options options-name) { if (!strcmp(options-name, BLOCK_OPT_SIZE)) { -sectors = options-value.n / 512; +size = (options-value.n + BDRV_SECTOR_SIZE) BDRV_SECTOR_MASK; } else if (!strcmp(options-name, BLOCK_OPT_BACKING_FILE)) { backing_file = options-value.s; } else if (!strcmp(options-name, BLOCK_OPT_BACKING_FMT)) { @@ -1830,7 +1830,7 @@ static int qcow2_create(const char *filename, QEMUOptionParameter *options, return -EINVAL; } -ret = qcow2_create2(filename, sectors, backing_file, backing_fmt, flags, +ret = qcow2_create2(filename, size, backing_file, backing_fmt, flags, cluster_size, prealloc, options, version, local_err); if (local_err) { error_propagate(errp, local_err); diff --git a/block/raw-posix.c b/block/raw-posix.c index 6586a0c..710ea9b 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -1252,7 +1252,8 @@ static int raw_create(const char *filename, QEMUOptionParameter *options, /* Read out options */ while (options options-name) { if (!strcmp(options-name, BLOCK_OPT_SIZE)) { -total_size = options-value.n / BDRV_SECTOR_SIZE; +total_size = (options-value.n + BDRV_SECTOR_SIZE) +BDRV_SECTOR_MASK; } options++; } @@ -1263,7 +1264,7 @@ static int raw_create(const char *filename, QEMUOptionParameter *options, result = -errno; error_setg_errno(errp, -result, Could not create file); } else { -if (ftruncate(fd, total_size * BDRV_SECTOR_SIZE) != 0) { +if (ftruncate(fd, total_size) != 0) { result = -errno; error_setg_errno(errp, -result, Could not resize file); } diff --git a/block/raw-win32.c b/block/raw-win32.c index 064ea31..faa574b 100644 --- a/block/raw-win32.c +++ b/block/raw-win32.c @@ -489,7 +489,8 @@ static int raw_create(const char *filename, QEMUOptionParameter *options, /* Read out options */ while (options options-name) { if (!strcmp(options-name, BLOCK_OPT_SIZE)) { -total_size = options-value.n / 512; +total_size = (options-value.n + BDRV_SECTOR_SIZE) +BDRV_SECTOR_MASK; } options++; } @@ -501,7 +502,7 @@ static int raw_create(const char *filename, QEMUOptionParameter *options, return -EIO; } set_sparse(fd); -ftruncate(fd, total_size * 512); +ftruncate(fd, total_size); qemu_close(fd); return 0; } -- 1.9.3
[Qemu-devel] [PATCH V9 4/4] qcow2: Add full image preallocation option
From: Hu Tao hu...@cn.fujitsu.com This adds a preallocation=full mode to qcow2 image creation, which creates a non-sparse image file. Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- block/qcow2.c | 79 -- tests/qemu-iotests/082.out | 54 +++ 2 files changed, 103 insertions(+), 30 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index 81c2979..5807dc0 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1598,6 +1598,7 @@ static int qcow2_create2(const char *filename, int64_t total_size, QEMUOptionParameter *options, int version, Error **errp) { +QEMUOptionParameter *alloc_options = NULL; /* Calculate cluster_bits */ int cluster_bits; cluster_bits = ffs(cluster_size) - 1; @@ -1627,10 +1628,78 @@ static int qcow2_create2(const char *filename, int64_t total_size, Error *local_err = NULL; int ret; +if (prealloc == PREALLOC_MODE_FULL || prealloc == PREALLOC_MODE_METADATA) { +int64_t meta_size = 0; +unsigned nreftablee, nrefblocke, nl1e, nl2e; +BlockDriver *drv; + +total_size = align_offset(total_size, cluster_size); + +drv = bdrv_find_protocol(filename, true); +if (drv == NULL) { +error_setg(errp, Could not find protocol for file '%s', filename); +return -ENOENT; +} + +alloc_options = append_option_parameters(alloc_options, + drv-create_options); +alloc_options = append_option_parameters(alloc_options, options); + +/* header: 1 cluster */ +meta_size += cluster_size; + +/* total size of L2 tables */ +nl2e = total_size / cluster_size; +nl2e = align_offset(nl2e, cluster_size / sizeof(uint64_t)); +meta_size += nl2e * sizeof(uint64_t); + +/* total size of L1 tables */ +nl1e = nl2e * sizeof(uint64_t) / cluster_size; +nl1e = align_offset(nl1e, cluster_size / sizeof(uint64_t)); +meta_size += nl1e * sizeof(uint64_t); + +/* total size of refcount blocks + * + * note: every host cluster is reference-counted, including metadata + * (even refcount blocks are recursively included). + * Let: + * a = total_size (this is the guest disk size) + * m = meta size not including refcount blocks and refcount tables + * c = cluster size + * y1 = number of refcount blocks entries + * y2 = meta size including everything + * then, + * y1 = (y2 + a)/c + * y2 = y1 * sizeof(u16) + y1 * sizeof(u16) * sizeof(u64) / c + m + * we can get y1: + * y1 = (a + m) / (c - sizeof(u16) - sizeof(u16) * sizeof(u64) / c) + */ +nrefblocke = (total_size + meta_size + cluster_size) / +(cluster_size - sizeof(uint16_t) - + 1.0 * sizeof(uint16_t) * sizeof(uint64_t) / cluster_size); +nrefblocke = align_offset(nrefblocke, cluster_size / sizeof(uint16_t)); +meta_size += nrefblocke * sizeof(uint16_t); + +/* total size of refcount tables */ +nreftablee = nrefblocke * sizeof(uint16_t) / cluster_size; +nreftablee = align_offset(nreftablee, cluster_size / sizeof(uint64_t)); +meta_size += nreftablee * sizeof(uint64_t); + +set_option_parameter_int(alloc_options, BLOCK_OPT_SIZE, + total_size + meta_size); +if (prealloc == PREALLOC_MODE_FULL) { +set_option_parameter(alloc_options, BLOCK_OPT_PREALLOC, full); +} else if (prealloc == PREALLOC_MODE_METADATA) { +set_option_parameter(alloc_options, BLOCK_OPT_PREALLOC, metadata); +} + +options = alloc_options; +} + ret = bdrv_create_file(filename, options, local_err); if (ret 0) { error_propagate(errp, local_err); -return ret; +goto out_options; } bs = NULL; @@ -1638,7 +1707,7 @@ static int qcow2_create2(const char *filename, int64_t total_size, NULL, local_err); if (ret 0) { error_propagate(errp, local_err); -return ret; +goto out_options; } /* Write the header */ @@ -1760,6 +1829,8 @@ out: if (bs) { bdrv_unref(bs); } +out_options: +free_option_parameters(alloc_options); return ret; } @@ -1795,6 +1866,8 @@ static int qcow2_create(const char *filename, QEMUOptionParameter *options, prealloc = PREALLOC_MODE_OFF; } else if (!strcmp(options-value.s, metadata)) { prealloc = PREALLOC_MODE_METADATA; +} else if (!strcmp(options-value.s, full)) { +prealloc = PREALLOC_MODE_FULL; } else { error_setg(errp, Invalid preallocation mode: '%s',
[Qemu-devel] [RFC] qdict: issue about usb controller hot-plug/unplug
Hi, Those day, I'm working for usb controller hot-plugging/unplugging( not enable multifunction capability). Everything work well, but when I test the case of hot-plug/unplug reiteratively, qemu will be aborted: qemu-system-x86_64: qobject/qdict.c:432: qentry_destroy: Assertion `e-value != ((void *)0)' failed. the backtrace is: Program received signal SIGABRT, Aborted. 0x7ffd95ec2b55 in raise () from /lib64/libc.so.6 (gdb) bt #0 0x7ffd95ec2b55 in raise () from /lib64/libc.so.6 #1 0x7ffd95ec4131 in abort () from /lib64/libc.so.6 #2 0x7ffd95ebba10 in __assert_fail () from /lib64/libc.so.6 #3 0x7ffd98efcc66 in qentry_destroy (e=0x7ffd9996ebe8) at qobject/qdict.c:432 #4 0x7ffd98efce0d in qdict_destroy_obj (obj=0x7ffd998e0090) at qobject/qdict.c:472 #5 0x7ffd98e64446 in qobject_decref (obj=0x7ffd998e0090) at /mnt/sdb/gonglei/code/qemu/include/qapi/qmp/qobject.h:100 #6 0x7ffd98e6ccae in handle_user_command (mon=0x7ffd9982e160, cmdline=0x7ffd998447e0 device_add usb-ehci,id=ehci) at /mnt/sdb/gonglei/code/qemu/monitor.c:4163 #7 0x7ffd98e6ee1a in monitor_command_cb (opaque=0x7ffd9982e160, cmdline=0x7ffd998447e0 device_add usb-ehci,id=ehci, readline_opaque=0x0) at /mnt/sdb/gonglei/code/qemu/monitor.c:5021 #8 0x7ffd98f1ccbc in readline_handle_byte (rs=0x7ffd998447e0, ch=13) at util/readline.c:376 #9 0x7ffd98e6ed62 in monitor_read (opaque=0x7ffd9982e160, buf=0x7fff034c8600 \r\207L\003\377\177, size=1) at /mnt/sdb/gonglei/code/qemu/monitor.c:5004 #10 0x7ffd98d653cd in qemu_chr_be_write (s=0x7ffd998306a0, buf=0x7fff034c8600 \r\207L\003\377\177, len=1) at qemu-char.c:165 #11 0x7ffd98d6705f in fd_chr_read (chan=0x7ffd9982c950, cond=G_IO_IN, opaque=0x7ffd998306a0) at qemu-char.c:848 #12 0x7ffd979ac69a in g_main_context_dispatch () from /usr/lib64/libglib-2.0.so.0 #13 0x7ffd98d30431 in glib_pollfds_poll () at main-loop.c:190 #14 0x7ffd98d30529 in os_host_main_loop_wait (timeout=981534) at main-loop.c:235 #15 0x7ffd98d3061b in main_loop_wait (nonblocking=0) at main-loop.c:484 #16 0x7ffd98dc8191 in main_loop () at vl.c:2075 #17 0x7ffd98dcf732 in main (argc=18, argv=0x7fff034c9bf8, envp=0x7fff034c9c90) at vl.c:4556 Debug reiteratively, I find the conflict of memory. Qemu command line: ./qemu-system-x86_64 -enable-kvm -m 4096 -smp 4 -name win7 -boot c -drive file=/mnt/sdb/gonglei/image/win7_32_2U -vnc 0.0.0.0:10 -monitor stdio QEMU 2.0.50 monitor - type 'help' for more information (qemu) device_add usb-ehci,id=ehci gdb steps as below: Breakpoint 4, handle_user_command (mon=0x7fb8d242f160, cmdline=0x7fb8d24457e0 device_add usb-ehci,id=ehci) at /mnt/sdb/gonglei/code/qemu/monitor.c:4142 4142cmd = monitor_parse_command(mon, cmdline, 0, mon-cmd_table, qdict); (gdb) p qdict-table[262]// Gonglei: according to the tested result before, the qdict-table[262]'s memory will conflict $4 = (struct {...} *) 0x7fb8d2535848 (gdb) watch *(long *)0x7fb8d2535848 Hardware watchpoint 9: *(long *)0x7fb8d2535848 (gdb) c Continuing. [Thread 0x7fb8cc645700 (LWP 11554) exited] Hardware watchpoint 9: *(long *)0x7fb8d2535848 Old value = 0 New value = 140431779094136 0x7fb8d18ee15a in usb_bus_new (bus=0x7fb8d24ede78, bus_size=192, ops=0x7fb8d1f365d0 ehci_bus_ops, host=0x7fb8d24ed6e0) at hw/usb/bus.c:87 87 QTAILQ_INSERT_TAIL(busses, bus, next); (gdb) bt #0 0x7fb8d18ee15a in usb_bus_new (bus=0x7fb8d24ede78, bus_size=192, ops=0x7fb8d1f365d0 ehci_bus_ops, host=0x7fb8d24ed6e0) at hw/usb/bus.c:87 #1 0x7fb8d191043b in usb_ehci_realize (s=0x7fb8d24ede78, dev=0x7fb8d24ed6e0, errp=0x0) at hw/usb/hcd-ehci.c:2536 #2 0x7fb8d1908a51 in usb_ehci_pci_initfn (dev=0x7fb8d24ed6e0) at hw/usb/hcd-ehci-pci.c:66 #3 0x7fb8d18bec1b in pci_qdev_init (qdev=0x7fb8d24ed6e0) at hw/pci/pci.c:1769 #4 0x7fb8d1841dd1 in device_realize (dev=0x7fb8d24ed6e0, errp=0x7a7f6af8) at hw/core/qdev.c:182 #5 0x7fb8d1843871 in device_set_realized (obj=0x7fb8d24ed6e0, value=true, errp=0x7a7f6c98) at hw/core/qdev.c:757 #6 0x7fb8d1988cac in property_set_bool (obj=0x7fb8d24ed6e0, v=0x7fb8d25c05b0, opaque=0x7fb8d2568b90, name= 0x7fb8d1b58b11 realized, errp=0x7a7f6c98) at qom/object.c:1428 #7 0x7fb8d19874c1 in object_property_set (obj=0x7fb8d24ed6e0, v=0x7fb8d25c05b0, name=0x7fb8d1b58b11 realized, errp= 0x7a7f6c98) at qom/object.c:826 #8 0x7fb8d19893e9 in object_property_set_qobject (obj=0x7fb8d24ed6e0, value=0x7fb8d257b630, name=0x7fb8d1b58b11 realized, errp=0x7a7f6c98) at qom/qom-qobject.c:24 #9 0x7fb8d1987869 in object_property_set_bool (obj=0x7fb8d24ed6e0, value=true, name=0x7fb8d1b58b11 realized, errp= 0x7a7f6c98) at qom/object.c:890 #10 0x7fb8d196587a in qdev_device_add (opts=0x7fb8d2548030) at qdev-monitor.c:560 #11 0x7fb8d1965e8e in do_device_add (mon=0x7fb8d242f160, qdict=0x7fb8d2535000, ret_data=0x7a7f6d78) at
Re: [Qemu-devel] [RFC 1/3] using CPUMASK bitmaps to calculate cpu index
On Thu, 2014-05-22 at 15:26 +0200, Igor Mammedov wrote: On Tue, 13 May 2014 18:08:47 +0800 Chen Fan chen.fan.f...@cn.fujitsu.com wrote: instead of seeking the number of CPUs, using CPUMASK bitmaps to calculate the cpu index, also would be a gread benefit to remove cpu index. How would it help to remove cpu_index? I think the cpu_index is just a CPU counter,if we remove one sparse CPU by setting corresponding bit to zero. then adding a new one we could easily get this vacancy bit by find_first_zero_bit() rather than get a duplicate index by calculating the number of CPU. What if there is only one CPU at start nad there is a need to add CPU with cpu_index==10? Bitmap hardly changes here anything, it's just another way of doing: cpu_index = 0; CPU_FOREACH(some_cpu) { cpu_index++; } What would help however is replacing cpu_index at read points with CPUClass-get_arch_id() Then targets that need sparse index could override default get_arch_id() to suite their needs and use their own properties to set arch_id value. Caution: this change would cause migration breakage for target-i386, so x86_cpu_get_arch_id() should take care about it when used with old machine types. yes, but for migration, I think we should need to override the cpu index in function vmstate_register(NULL, cpu_index, vmstate_cpu_common, cpu) with an unique instance_id while hot-add/hot-remove CPU arbitrarily. maybe this unique instance_id can be 'apic-id'. Thanks, Chen Signed-off-by: Chen Fan chen.fan.f...@cn.fujitsu.com --- exec.c | 9 - include/qom/cpu.h | 9 + include/sysemu/sysemu.h | 7 --- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/exec.c b/exec.c index cf12049..2948841 100644 --- a/exec.c +++ b/exec.c @@ -473,16 +473,15 @@ void cpu_exec_init(CPUArchState *env) { CPUState *cpu = ENV_GET_CPU(env); CPUClass *cc = CPU_GET_CLASS(cpu); -CPUState *some_cpu; int cpu_index; #if defined(CONFIG_USER_ONLY) cpu_list_lock(); #endif -cpu_index = 0; -CPU_FOREACH(some_cpu) { -cpu_index++; -} +cpu_index = find_first_zero_bit(cc-cpu_present_mask, +MAX_CPUMASK_BITS); +set_bit(cpu_index, cc-cpu_present_mask); + cpu-cpu_index = cpu_index; cpu-numa_node = 0; QTAILQ_INIT(cpu-breakpoints); diff --git a/include/qom/cpu.h b/include/qom/cpu.h index df977c8..b8f46b1 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -70,6 +70,13 @@ typedef void (*CPUUnassignedAccess)(CPUState *cpu, hwaddr addr, struct TranslationBlock; +/* The following shall be true for all CPUs: + * cpu-cpu_index max_cpus = MAX_CPUMASK_BITS + * + * Note that cpu-get_arch_id() may be larger than MAX_CPUMASK_BITS. + */ +#define MAX_CPUMASK_BITS 255 + /** * CPUClass: * @class_by_name: Callback to map -cpu command line model name to an @@ -142,6 +149,8 @@ typedef struct CPUClass { const struct VMStateDescription *vmsd; int gdb_num_core_regs; const char *gdb_core_xml_file; + +DECLARE_BITMAP(cpu_present_mask, MAX_CPUMASK_BITS); } CPUClass; #ifdef HOST_WORDS_BIGENDIAN diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index ba5c7f8..04edb8b 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -134,13 +134,6 @@ extern QEMUClockType rtc_clock; #define MAX_NODES 64 -/* The following shall be true for all CPUs: - * cpu-cpu_index max_cpus = MAX_CPUMASK_BITS - * - * Note that cpu-get_arch_id() may be larger than MAX_CPUMASK_BITS. - */ -#define MAX_CPUMASK_BITS 255 - extern int nb_numa_nodes; extern uint64_t node_mem[MAX_NODES]; extern unsigned long *node_cpumask[MAX_NODES];
Re: [Qemu-devel] [PATCH 02/14] block/vvfat: Plug memory leak in enable_write_target()
The Monday 26 May 2014 à 19:37:03 (+0200), Markus Armbruster wrote : I figure the leak originated in bdrv_create2(), and was duplicated into callers when commit 91a073ak dropped that function. Looks like the other places have since been fixed. Spotted by Coverity. Signed-off-by: Markus Armbruster arm...@redhat.com --- block/vvfat.c | 1 + 1 file changed, 1 insertion(+) diff --git a/block/vvfat.c b/block/vvfat.c index c3af7ff..6a0d246 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -2927,6 +2927,7 @@ static int enable_write_target(BDRVVVFATState *s) set_option_parameter(options, BLOCK_OPT_BACKING_FILE, fat:); ret = bdrv_create(bdrv_qcow, s-qcow_filename, options, local_err); +free_option_parameters(options); if (ret 0) { qerror_report_err(local_err); error_free(local_err); -- 1.9.3 Reviewed-by: Benoit Canet ben...@irqsave.net
Re: [Qemu-devel] [PATCH 04/14] block: Plug memory leak on brv_open_image() error path
The Monday 26 May 2014 à 19:37:05 (+0200), Markus Armbruster wrote : Introduced in commit da557a. Spotted by Coverity. Signed-off-by: Markus Armbruster arm...@redhat.com --- block.c | 1 + 1 file changed, 1 insertion(+) diff --git a/block.c b/block.c index 40c5e1a..1996f84 100644 --- a/block.c +++ b/block.c @@ -1196,6 +1196,7 @@ int bdrv_open_image(BlockDriverState **pbs, const char *filename, bdref_key); ret = -EINVAL; } +QDECREF(image_options); goto done; } -- 1.9.3 Reviewed-by: Benoit Canet ben...@irqsave.net
[Qemu-devel] [PATCH v5 0/2] vmdk: Optimize cluster allocation
Fam Zheng (2): qemu-iotests: Add data pattern in version3 VMDK sample image in 059 vmdk: Optimize cluster allocation block/vmdk.c | 222 + tests/qemu-iotests/059 | 4 + tests/qemu-iotests/059.out | 202 ++- .../sample_images/iotest-version3.vmdk.bz2 | Bin 414 - 4764 bytes 4 files changed, 345 insertions(+), 83 deletions(-) -- 1.9.2
[Qemu-devel] [PATCH v5 2/2] vmdk: Optimize cluster allocation
This drops the unnecessary bdrv_truncate() from, and also improves, cluster allocation code path. Before, when we need a new cluster, get_cluster_offset truncates the image to bdrv_getlength() + cluster_size, and returns the offset of added area, i.e. the image length before truncating. This is not efficient, so it's now rewritten as: - Save the extent file length when opening. - When allocating cluster, use the saved length as cluster offset. - Don't truncate image, because we'll anyway write data there: just write any data at the EOF position, in descending priority: * New user data (cluster allocation happens in a write request). * Filling data in the beginning and/or ending of the new cluster, if not covered by user data: either backing file content (COW), or zero for standalone images. One major benifit of this change is, on host mounted NFS images, even over a fast network, ftruncate is slow (see the example below). This change significantly speeds up cluster allocation. Comparing by converting a cirros image (296M) to VMDK on an NFS mount point, over 1Gbe LAN: $ time qemu-img convert cirros-0.3.1.img /mnt/a.raw -O vmdk Before: real0m21.796s user0m0.130s sys 0m0.483s After: real0m2.017s user0m0.047s sys 0m0.190s We also get rid of unchecked bdrv_getlength() and bdrv_truncate(), and get a little more documentation in function comments. Tested that this passes qemu-iotests for all VMDK subformats. Signed-off-by: Fam Zheng f...@redhat.com --- V5: Don't leave new extent partially initialized. (Stefan) Align next cluster sector. (Stefan) Rename skip_start/skip_end to skip_start_sector/skip_end_sector. (Stefan) V4: Fix L2 table cache and image, and improve according to any other comments. (Kevin) V3: A new implementation following Kevin's suggestion. --- block/vmdk.c | 222 +-- 1 file changed, 140 insertions(+), 82 deletions(-) diff --git a/block/vmdk.c b/block/vmdk.c index 480ea37..df1211c 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -106,6 +106,7 @@ typedef struct VmdkExtent { uint32_t l2_cache_counts[L2_CACHE_SIZE]; int64_t cluster_sectors; +int64_t next_cluster_sector; char *type; } VmdkExtent; @@ -124,7 +125,6 @@ typedef struct BDRVVmdkState { } BDRVVmdkState; typedef struct VmdkMetaData { -uint32_t offset; unsigned int l1_index; unsigned int l2_index; unsigned int l2_offset; @@ -397,6 +397,7 @@ static int vmdk_add_extent(BlockDriverState *bs, { VmdkExtent *extent; BDRVVmdkState *s = bs-opaque; +int64_t length; if (cluster_sectors 0x20) { /* 0x20 * 512Bytes = 1GB for one cluster is unrealistic */ @@ -412,6 +413,11 @@ static int vmdk_add_extent(BlockDriverState *bs, return -EFBIG; } +length = bdrv_getlength(file); +if (length 0) { +return length; +} + s-extents = g_realloc(s-extents, (s-num_extents + 1) * sizeof(VmdkExtent)); extent = s-extents[s-num_extents]; @@ -427,6 +433,8 @@ static int vmdk_add_extent(BlockDriverState *bs, extent-l1_entry_sectors = l2_size * cluster_sectors; extent-l2_size = l2_size; extent-cluster_sectors = flat ? sectors : cluster_sectors; +extent-next_cluster_sector = +ROUND_UP(DIV_ROUND_UP(length, BDRV_SECTOR_SIZE), cluster_sectors); if (s-num_extents 1) { extent-end_sector = (*(extent - 1)).end_sector + extent-sectors; @@ -954,57 +962,97 @@ static int vmdk_refresh_limits(BlockDriverState *bs) return 0; } +/** + * get_whole_cluster + * + * Copy backing file's cluster that covers @sector_num, otherwise write zero, + * to the cluster at @cluster_sector_num. + * + * If @skip_start_sector @skip_end_sector, the relative range + * [@skip_start_sector, @skip_end_sector) is not copied or written, and leave + * it for call to write user data in the request. + */ static int get_whole_cluster(BlockDriverState *bs, -VmdkExtent *extent, -uint64_t cluster_offset, -uint64_t offset, -bool allocate) + VmdkExtent *extent, + uint64_t cluster_sector_num, + uint64_t sector_num, + uint64_t skip_start_sector, + uint64_t skip_end_sector) { int ret = VMDK_OK; -uint8_t *whole_grain = NULL; +int64_t cluster_bytes; +uint8_t *whole_grain; + +/* For COW, align request sector_num to cluster start */ +sector_num = QEMU_ALIGN_DOWN(sector_num, extent-cluster_sectors); +cluster_bytes = extent-cluster_sectors BDRV_SECTOR_BITS; +whole_grain = qemu_blockalign(bs, cluster_bytes); +if (!bs-backing_hd) { +memset(whole_grain, 0, skip_start_sector
Re: [Qemu-devel] [PATCH 05/14] qemu-io: Support multiple -o in open command
The Monday 26 May 2014 à 19:37:06 (+0200), Markus Armbruster wrote : Instead of ignoring all option values but the last one, multiple -o options now have the same meaning as having a single option with all settings in the order of their respective -o options. Same as commit 2dc8328 for qemu-img convert, except here we do it with QemuOpts rather than QEMUOptionParameter. Signed-off-by: Markus Armbruster arm...@redhat.com --- qemu-io.c | 14 +- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/qemu-io.c b/qemu-io.c index 9fcd72b..ef3fef6 100644 --- a/qemu-io.c +++ b/qemu-io.c @@ -118,6 +118,7 @@ static const cmdinfo_t open_cmd = { static QemuOptsList empty_opts = { .name = drive, +.merge_lists = true, .head = QTAILQ_HEAD_INITIALIZER(empty_opts.head), .desc = { /* no elements = accept any params */ @@ -132,7 +133,7 @@ static int open_f(BlockDriverState *bs, int argc, char **argv) int growable = 0; int c; QemuOpts *qopts; -QDict *opts = NULL; +QDict *opts; while ((c = getopt(argc, argv, snrgo:)) != EOF) { switch (c) { @@ -149,15 +150,14 @@ static int open_f(BlockDriverState *bs, int argc, char **argv) growable = 1; break; case 'o': -qopts = qemu_opts_parse(empty_opts, optarg, 0); -if (qopts == NULL) { +if (!qemu_opts_parse(empty_opts, optarg, 0)) { printf(could not parse option list -- %s\n, optarg); +qemu_opts_reset(empty_opts); return 0; } -opts = qemu_opts_to_qdict(qopts, opts); -qemu_opts_del(qopts); break; default: +qemu_opts_reset(empty_opts); return qemuio_command_usage(open_cmd); } } @@ -166,6 +166,10 @@ static int open_f(BlockDriverState *bs, int argc, char **argv) flags |= BDRV_O_RDWR; } +qopts = qemu_opts_find(empty_opts, NULL); +opts = qopts ? qemu_opts_to_qdict(qopts, NULL) : NULL; +qemu_opts_reset(empty_opts); + if (optind == argc - 1) { return openfile(argv[optind], flags, growable, opts); } else if (optind == argc) { -- 1.9.3 Reviewed-by: Benoit Canet ben...@irqsave.net
[Qemu-devel] [PATCH v7 0/3] EEH Support for VFIO devices on sPAPR
EEH Support for VFIO PCI Device The series of patches intend to support EEH for VFIO PCI devices on sPAPR platform. It requires corresponding host kernel support. Also, it was built on top of Alexey's VFIO-for-sPAPR git repository. QEMU: git://github.com/aik/qemu.git (branch: vfio) Kernel: http://linuxppc.10917.n7.nabble.com/PATCH-v7-0-3-EEH-Support-for-VFIO-PCI-Device-td82692.html Here are some highlights and I don't have experience with QEMU. Any comments should be appreciated. * EEH RTAS calls captured by sPAPR platform firstly, and then routed to VFIO for handling if VFIO can. Otheriwse, it will be routed to host kernel for handling via dedicated VFIO container IOCTL command. * PHB BUID is the identifier to one specific PHB, which is required information for EEH address mapping. In order to retrieve that from VFIO, the PCI bus struct has been extended to have additional field sysdata for that. * The guest can't do error injection until holding valid token. Each guest is allowed to have one token at once. The RTAS calls managing token is simply emulated in QEMU. However, the error injection has to be routed to host kernel by dedicated syscall. Changelog = v3 - v4: * Remove the error injection from the patchset. Mike or I will work on it later. * The IOCTL command is handled by VFIO PCI device instead of container. * sysdata in root bus to pass PHB BUID isn't needed. * Update the IOCTL argunemt according to kernel's changes. v4 - v6: * Header file update according to kerenl's change. * Split one ioctl command to 5. * Doesn't rely the kerenl to figure out RTAS return value. QEMU translate return value from ioctl() to RTAS return value insteadly. v6 - v7: * All ioctl commands go to VFIO container fd instead of PCI device fd. * QEMU figures out the PE address directly. * Rely on sPAPRVFIOPHBState, which is one-to-one mapping with IOMMU group. Gavin Shan (3): headers: Sync with Linux header VFIO: Helper function to retrieve container fd sPAPR: EEH support for VFIO PCI device hw/misc/vfio.c | 17 +++ hw/ppc/spapr.c | 1 + hw/ppc/spapr_pci.c | 1 + hw/ppc/spapr_pci_vfio.c | 332 include/hw/misc/vfio.h | 1 + include/hw/pci-host/spapr.h | 1 + include/hw/ppc/spapr.h | 1 + linux-headers/linux/vfio.h | 66 + 8 files changed, 420 insertions(+) -- 1.8.3.2
[Qemu-devel] [PATCH v5 1/2] qemu-iotests: Add data pattern in version3 VMDK sample image in 059
It's possible that we diverge from the specification with our implementation. Having a reference image in the test cases may detect such problems when we introduce a bug that can read what it creates, but can't handle a real VMDK. Signed-off-by: Fam Zheng f...@redhat.com --- tests/qemu-iotests/059 | 4 + tests/qemu-iotests/059.out | 202 - .../sample_images/iotest-version3.vmdk.bz2 | Bin 414 - 4764 bytes 3 files changed, 205 insertions(+), 1 deletion(-) diff --git a/tests/qemu-iotests/059 b/tests/qemu-iotests/059 index 26a2fd3..3c053c2 100755 --- a/tests/qemu-iotests/059 +++ b/tests/qemu-iotests/059 @@ -114,6 +114,10 @@ echo echo === Testing version 3 === _use_sample_img iotest-version3.vmdk.bz2 _img_info +for i in {0..99}; do +$QEMU_IO -r -c read -P $(( i % 10 + 0x30 )) $(( i * 64 * 1024 * 10 + i * 512 )) 512 $TEST_IMG \ +| _filter_qemu_io +done echo echo === Testing 4TB monolithicFlat creation and IO === diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out index eba0ded..0dadba6 100644 --- a/tests/qemu-iotests/059.out +++ b/tests/qemu-iotests/059.out @@ -2056,8 +2056,208 @@ wrote 512/512 bytes at offset 10240 === Testing version 3 === image: TEST_DIR/iotest-version3.IMGFMT file format: IMGFMT -virtual size: 1.0G (1073741824 bytes) +virtual size: 16G (17179869184 bytes) cluster_size: 65536 +read 512/512 bytes at offset 0 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 655872 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 1311744 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 1967616 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 2623488 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 3279360 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 3935232 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 4591104 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 5246976 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 5902848 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 6558720 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 7214592 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 7870464 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 8526336 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 9182208 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 9838080 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 10493952 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 11149824 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 11805696 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 12461568 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 13117440 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 13773312 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 14429184 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 15085056 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 15740928 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 16396800 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 17052672 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 17708544 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 18364416 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 19020288 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 19676160 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 20332032 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 20987904 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 21643776 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 22299648 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 22955520 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512
[Qemu-devel] [PATCH v7 3/3] sPAPR: EEH support for VFIO PCI device
The patch introduces EEH RTAS servers on sPAPR platform and handle them there. Each sPAPRPHBVFIOState is binding with only one IOMMU group, so it can be regarded as PE in nature. The PE address is maintained in sPAPRPHBState, which has default value 0x for non-VFIO PHBs. Otherwise, the PE address is equal to IOMMU group ID. It can be used to distinguish sPAPRVFIOPHBState from sPAPRPHBState. As we're going to support EEH functonality for VFIO PCI devices, we simply return error if the EEH RTAS call is routed to non-VFIO PHB whose PE address is 0x. Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com --- hw/ppc/spapr.c | 1 + hw/ppc/spapr_pci.c | 1 + hw/ppc/spapr_pci_vfio.c | 335 include/hw/pci-host/spapr.h | 1 + include/hw/ppc/spapr.h | 1 + 5 files changed, 339 insertions(+) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index eee0a7c..e394d0c 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1325,6 +1325,7 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args) spapr_pci_msi_init(spapr, SPAPR_PCI_MSI_WINDOW); spapr_pci_rtas_init(); spapr_tce_ddw_rtas_init(spapr); +spapr_eeh_rtas_init(spapr); phb = spapr_create_phb(spapr, 0); diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index a9f307a..0f2ac02 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -578,6 +578,7 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp) return; } +sphb-pe_addr = 0x; sphb-dtbusname = g_strdup_printf(pci@% PRIx64, sphb-buid); namebuf = alloca(strlen(sphb-dtbusname) + 32); diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio.c index decf3dd..5dbddd0 100644 --- a/hw/ppc/spapr_pci_vfio.c +++ b/hw/ppc/spapr_pci_vfio.c @@ -23,6 +23,8 @@ */ #include sys/types.h #include dirent.h +#include sys/ioctl.h +#include linux/vfio.h #include hw/hw.h #include hw/ppc/spapr.h @@ -52,6 +54,12 @@ static void spapr_phb_vfio_finish_realize(sPAPRPHBState *sphb, Error **errp) return; } +/* + * PE address isn't relevant to PCI config address any more. + * However, 0 is invalid PE address and can't be used. + */ +sphb-pe_addr = svphb-iommugroupid + 1; + ret = vfio_container_spapr_get_info(svphb-phb.iommu_as, svphb-iommugroupid, info); @@ -354,3 +362,330 @@ void spapr_tce_ddw_rtas_init(sPAPREnvironment *spapr) spapr_rtas_register(ibm,reset-pe-dma-window, rtas_ibm_reset_pe_dma_window); } + +static bool spapr_vfio_pci_addr_check(sPAPRPHBState *sphb, + uint32_t addr, bool is_pe_addr) +{ +PCIDevice *pdev = NULL; + +if (!sphb || !sphb-parent_obj.bus) { +return false; +} + +if (!is_pe_addr) { +pdev = pci_find_device(sphb-parent_obj.bus, + (addr 16) 0xFF, (addr 8) 0xFF); +if (!pdev) { +return false; +} +} else { +if (sphb-pe_addr != addr) { +return false; +} +} + +return true; +} + +static void rtas_ibm_set_eeh_option(PowerPCCPU *cpu, +sPAPREnvironment *spapr, +uint32_t token, uint32_t nargs, +target_ulong args, uint32_t nret, +target_ulong rets) +{ +struct vfio_eeh_pe_set_option option; +uint32_t addr; +uint64_t buid = ((uint64_t)rtas_ld(args, 1) 32) | rtas_ld(args, 2); +sPAPRPHBState *sphb = spapr_find_phb(spapr, buid); +sPAPRPHBVFIOState *svphb = SPAPR_PCI_VFIO_HOST_BRIDGE(sphb); +int32_t fd, ret; +bool valid = false; + +if (!sphb || sphb-pe_addr == 0x) { +rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR); +return; +} + +if ((nargs != 4) || (nret != 1)) { +rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR); +return; +} + +option.argsz = sizeof(option); +option.option = rtas_ld(args, 3); +addr = rtas_ld(args, 0); +switch (option.option) { +case VFIO_EEH_PE_SET_OPT_ENABLE: +valid = spapr_vfio_pci_addr_check(sphb, addr, false); +break; +case VFIO_EEH_PE_SET_OPT_DISABLE: +case VFIO_EEH_PE_SET_OPT_IO: +case VFIO_EEH_PE_SET_OPT_DMA: +valid = spapr_vfio_pci_addr_check(sphb, addr, true); +break; +default: +valid = false; +} + +if (!valid) { +rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR); +return; +} + +fd = vfio_get_container_fd_by_group_id(svphb-iommugroupid); +if (fd 0) { +rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR); +return; +} + +ret = ioctl(fd, VFIO_EEH_PE_SET_OPTION, option); +if (ret == 0) { +rtas_st(rets, 0, RTAS_OUT_SUCCESS); +} else { +rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
Re: [Qemu-devel] [RFC v1 05/25] memory: MemoryRegion: Add contained flag
On Fri, May 16, 2014 at 11:52 AM, Peter Crosthwaite peter.crosthwa...@xilinx.com wrote: Rather than use the .parent == NULL check to determine if a memory region is contained, add a purpose specific boolean flag. This allows for .parent to be easily converted to a link property while preserving all the semantics of the legacy API. Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com With the fixup of the container link property setter, this is obsoleted. Dropped. Regards, Peter
[Qemu-devel] [PATCH v7 1/3] headers: Sync with Linux header
The patch synchronizes with linux header (vfio.h). Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com --- linux-headers/linux/vfio.h | 66 ++ 1 file changed, 66 insertions(+) diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h index f0aa97d..4eda000 100644 --- a/linux-headers/linux/vfio.h +++ b/linux-headers/linux/vfio.h @@ -490,6 +490,72 @@ struct vfio_iommu_spapr_tce_reset { }; #define VFIO_IOMMU_SPAPR_TCE_RESET _IO(VFIO_TYPE, VFIO_BASE + 20) +/* + * EEH functionality can be enabled or disabled on one specific device. + * Also, the DMA or IO frozen state can be removed from the frozen PE + * if required. + */ +struct vfio_eeh_pe_set_option { + __u32 argsz; + __u32 flags; + __u32 option; +#define VFIO_EEH_PE_SET_OPT_DISABLE0 /* Disable EEH */ +#define VFIO_EEH_PE_SET_OPT_ENABLE 1 /* Enable EEH */ +#define VFIO_EEH_PE_SET_OPT_IO 2 /* Enable IO*/ +#define VFIO_EEH_PE_SET_OPT_DMA3 /* Enable DMA */ +}; + +#define VFIO_EEH_PE_SET_OPTION _IO(VFIO_TYPE, VFIO_BASE + 21) + +/* + * Each EEH PE should have unique address to be identified. PE's + * sharing mode is also useful information as well. + */ +#define VFIO_EEH_PE_GET_ADDRESS0 /* Get address */ +#define VFIO_EEH_PE_GET_MODE 1 /* Query mode */ +#define VFIO_EEH_PE_MODE_NONE 0 /* Not a PE */ +#define VFIO_EEH_PE_MODE_NOT_SHARED1 /* Exclusive*/ +#define VFIO_EEH_PE_MODE_SHARED2 /* Shared mode */ + +/* + * EEH PE might have been frozen because of PCI errors. Also, it might + * be experiencing reset for error revoery. The following command helps + * to get the state. + */ +struct vfio_eeh_pe_get_state { + __u32 argsz; + __u32 flags; + __u32 state; +}; + +#define VFIO_EEH_PE_GET_STATE _IO(VFIO_TYPE, VFIO_BASE + 22) + +/* + * Reset is the major step to recover problematic PE. The following + * command helps on that. + */ +struct vfio_eeh_pe_reset { + __u32 argsz; + __u32 flags; + __u32 option; +#define VFIO_EEH_PE_RESET_DEACTIVATE 0 /* Deactivate reset */ +#define VFIO_EEH_PE_RESET_HOT 1 /* Hot reset*/ +#define VFIO_EEH_PE_RESET_FUNDAMENTAL 3 /* Fundamental reset*/ +}; + +#define VFIO_EEH_PE_RESET _IO(VFIO_TYPE, VFIO_BASE + 23) + +/* + * One of the steps for recovery after PE reset is to configure the + * PCI bridges affected by the PE reset. + */ +struct vfio_eeh_pe_configure { + __u32 argsz; + __u32 flags; +}; + +#define VFIO_EEH_PE_CONFIGURE _IO(VFIO_TYPE, VFIO_BASE + 24) + /* * */ #endif /* VFIO_H */ -- 1.8.3.2
[Qemu-devel] [PATCH v7 2/3] VFIO: Helper function to retrieve container fd
The patch adds function vfio_get_container_fd_by_group_id() to retrieve the container's fd of the specified VFIO group. The fd will be used by subsequent patches. Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com --- hw/misc/vfio.c | 17 + include/hw/misc/vfio.h | 1 + 2 files changed, 18 insertions(+) diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c index 0796abf..424d467 100644 --- a/hw/misc/vfio.c +++ b/hw/misc/vfio.c @@ -4310,3 +4310,20 @@ put_group_exit: return n; } + +int vfio_get_container_fd_by_group_id(int32_t groupid) +{ +VFIOGroup *group; + +QLIST_FOREACH(group, group_list, next) { +if (group-groupid == groupid) { +if (group-container) { +return group-container-fd; +} else { +return -ENOENT; +} +} +} + +return -ENOENT; +} diff --git a/include/hw/misc/vfio.h b/include/hw/misc/vfio.h index 53ec665..a5afebd 100644 --- a/include/hw/misc/vfio.h +++ b/include/hw/misc/vfio.h @@ -30,4 +30,5 @@ static inline long vfio_kvm_notify(Notifier *n, unsigned request, void *data) return p.ret; } +extern int vfio_get_container_fd_by_group_id(int32_t groupid); #endif -- 1.8.3.2
Re: [Qemu-devel] [PATCH 06/14] qemu-io: Plug memory leak in open command
The Monday 26 May 2014 à 19:37:07 (+0200), Markus Armbruster wrote : Introduced in commit b543c5c. Spotted by Coverity. Signed-off-by: Markus Armbruster arm...@redhat.com --- qemu-io.c | 1 + 1 file changed, 1 insertion(+) diff --git a/qemu-io.c b/qemu-io.c index ef3fef6..ffbad25 100644 --- a/qemu-io.c +++ b/qemu-io.c @@ -175,6 +175,7 @@ static int open_f(BlockDriverState *bs, int argc, char **argv) } else if (optind == argc) { return openfile(NULL, flags, growable, opts); } else { +QDECREF(opts); return qemuio_command_usage(open_cmd); } } -- 1.9.3 There is still a potential leak in openfile() in if (qemuio_bs). Bests regards Benoît
Re: [Qemu-devel] [PATCH] tests: check empty qmp output visitor
On Tue, 2014-05-27 at 09:53 +0800, Amos Kong wrote: On Tue, May 20, 2014 at 07:19:49PM -0500, Michael Roth wrote: Quoting Marcel Apfelbaum (2014-05-20 10:07:59) Checks the output visitor behaviour for NULL values. Signed-off-by: Marcel Apfelbaum marce...@redhat.com --- Notes: - I didn't add Michael's Sob because I tweaked the test a little. Tweaked it so it didn't crash 100% of the time even after your fix? :) Another approach, since the expected behavior now is for qmp_output_get_qobject() to return NULL in this case, is to just assert(arg == NULL) and drop the qdict/QDECREF completely. Agree. We expecte arg is NULL, but this patch will still success when arg isn't NULL. Hi Amos, Thank you for your review. I already tweaked it and added it to my latest series. However, my previous concept was to check that it doesn't crash, and not to care if the result is NULL, or a Null Object pattern. But since now it will always return NULL, there is no reason not to assert it. Can we add the empty test after g_test_init()? We can make sure the out_visitor_data is really empty. I checked it and it is empty :), If it is really important for you, I'll re-spin only this patch. Thanks again, Marcel Amos. - To be added on top of qapi: output visitor crashes qemu if it encounters a NULL value, otherwise the test will fail. tests/test-qmp-output-visitor.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/tests/test-qmp-output-visitor.c b/tests/test-qmp-output-visitor.c index 9c15458..de1bf83 100644 --- a/tests/test-qmp-output-visitor.c +++ b/tests/test-qmp-output-visitor.c @@ -507,6 +507,19 @@ static void test_visitor_out_union_anon(TestOutputVisitorData *data, qapi_free_UserDefAnonUnion(tmp); } +static void test_visitor_out_empty(TestOutputVisitorData *data, + const void *unused) +{ +QObject *arg; +QDict *qdict; + +arg = qmp_output_get_qobject(data-qov); +if (arg) { +qdict = qobject_to_qdict(arg); +QDECREF(qdict); +} +} + static void init_native_list(UserDefNativeListUnion *cvalue) { int i; @@ -859,6 +872,8 @@ int main(int argc, char **argv) out_visitor_data, test_visitor_out_union_flat); output_visitor_test_add(/visitor/output/union-anon, out_visitor_data, test_visitor_out_union_anon); +output_visitor_test_add(/visitor/output/empty, +out_visitor_data, test_visitor_out_empty); output_visitor_test_add(/visitor/output/native_list/int, out_visitor_data, test_visitor_out_native_list_int); output_visitor_test_add(/visitor/output/native_list/int8, -- 1.8.3.1
Re: [Qemu-devel] [PATCH 03/14] qcow2: Plug memory leak on qcow2_invalidate_cache() error paths
The Monday 26 May 2014 à 19:37:04 (+0200), Markus Armbruster wrote : Introduced in commit 5a8a30d. Spotted by Coverity. Signed-off-by: Markus Armbruster arm...@redhat.com --- block/qcow2.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index a4b97e8..a54d2ba 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1308,6 +1308,7 @@ static void qcow2_invalidate_cache(BlockDriverState *bs, Error **errp) options = qdict_clone_shallow(bs-options); ret = qcow2_open(bs, options, flags, local_err); +QDECREF(options); if (local_err) { error_setg(errp, Could not reopen qcow2 layer: %s, error_get_pretty(local_err)); @@ -1318,8 +1319,6 @@ static void qcow2_invalidate_cache(BlockDriverState *bs, Error **errp) return; } -QDECREF(options); - if (crypt_method) { s-crypt_method = crypt_method; memcpy(s-aes_encrypt_key, aes_encrypt_key, sizeof(aes_encrypt_key)); -- 1.9.3 Reviewed-by: Benoit Canet ben...@irqsave.net
Re: [Qemu-devel] [Bug 1308341] Re: Multiple CPUs causes blue screen on Windows guest (14.04 regression)
Please upload zipped kernel dump or mini dump so it can be examined. Thanks, Yan. On May 26, 2014, at 12:41 PM, Gordon Kaltofen kalto...@dresearch-fe.de wrote: Hallo to all, this is my first post here. I have exactly the same problem occurred after Distribution Update Ubuntu Server x64 from 12.04.4 to 14.04. 1. I have Windows 7 32/64-Bit and Windows 2008 Server 64-Bit VMs, all show the same error with two dedicated cores (no pinning). In combination with the other statements I would say it is a general Windows problem - not specific. 2. I have an AMD Opteron 6272 (fam: 15, model: 01, stepping: 02, 16 cores) system. Therefore, this problem does not seem to be Intel/AMD architecture-specific. 3. I configured a couple of VMs ONE core and let it run over the weekend. They didn't crashing, but they reacted only very slowly an choppy. It seems that there is a fundamental error, which is responsible for the multi-core errors. After restarting the VM, the error is initially gone, even though the VM is still slow due to only one core. 4. I have the latest virtio drivers are installed in the Windows guest systems and use the devices Red Hat VirtIO SCSI and Ethernet (vers. 61.65.104.7400) drivers. Are these drivers installed in your VMs or do you use the IDE/SATA and RTL/Intel-NIC standard driver? 5. The VM images (qcow2) are located on a mdadm Raid1 volume of two SSDs. Since Linux kernel 3.7 ATA TRIM is possible with Linux software RAID, so I use the mount option 'discard'. I do not want to completely exclude the possibility that the error has to do with it. Is there now an indication of the cause of the failure and possibly even a workaround? -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1308341 Title: Multiple CPUs causes blue screen on Windows guest (14.04 regression) Status in QEMU: New Status in “qemu” package in Ubuntu: Confirmed Status in “virt-manager” package in Ubuntu: Confirmed Bug description: Configuring a Windows 7 guest using more than one CPU cases the guest to fail. This happens after a few hours after guest boot. This is the error on the blue screen: A clock interrupt was not received on a secondary processor within the allocated time interval After resetting, the guest will never boot and a new bluescreen with the error STOP: 0x005c appears. Shutting down the guest completely and restarting it will allow it to boot and run for a few hours again. The guest was created using virt-manager. The error happens with or without virtio devices and with both 32-bit and 64-bit Windows 7 guests. I am using Ubuntu 14.04 release candidate. qemu-kvm version 2.0.0~rc1+dfsg-0ubuntu3 To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1308341/+subscriptions
[Qemu-devel] [PATCH] [qemu-devel] fix wrong order when doing live block migration setup
If we want to track dirty blocks using dirty_maps on a BlockDriverState when doing live block-migration, its correspoding 'BlkMigDevState' should be add to block_mig_state.bmds_list firstly for subsequent processing. Otherwise set_dirty_tracking will do nothing on an empty list than allocating dirty_bitmaps for them. And what's the worse, bdrv_get_dirty_count will access the bmds-dirty_maps directly, there could be a segfault as the reasons above. Signed-off-by: chai wen chaiw.f...@cn.fujitsu.com --- block-migration.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/block-migration.c b/block-migration.c index 56951e0..43203aa 100644 --- a/block-migration.c +++ b/block-migration.c @@ -626,6 +626,7 @@ static int block_save_setup(QEMUFile *f, void *opaque) block_mig_state.submitted, block_mig_state.transferred); qemu_mutex_lock_iothread(); +init_blk_migration(f); /* start track dirty blocks */ ret = set_dirty_tracking(); @@ -635,7 +636,6 @@ static int block_save_setup(QEMUFile *f, void *opaque) return ret; } -init_blk_migration(f); qemu_mutex_unlock_iothread(); -- 1.7.1
Re: [Qemu-devel] [PATCH 07/14] qemu-io: Don't print NULL when open without non-option arg fails
The Monday 26 May 2014 à 19:37:08 (+0200), Markus Armbruster wrote : Reproducer: open -o a=b. Broken in commit fd0fee3. Signed-off-by: Markus Armbruster arm...@redhat.com --- qemu-io.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/qemu-io.c b/qemu-io.c index ffbad25..0daf413 100644 --- a/qemu-io.c +++ b/qemu-io.c @@ -61,7 +61,8 @@ static int openfile(char *name, int flags, int growable, QDict *opts) if (bdrv_open(qemuio_bs, name, NULL, opts, flags | BDRV_O_PROTOCOL, NULL, local_err)) { -fprintf(stderr, %s: can't open device %s: %s\n, progname, name, +fprintf(stderr, %s: can't open%s%s: %s\n, progname, +name ? device : , name ?: , name ?: seems to be a GNU C extension: see http://en.wikipedia.org/wiki/%3F:#C Don't we want this code to work on most compilers ? Best regards Benoît error_get_pretty(local_err)); error_free(local_err); return 1; @@ -72,7 +73,8 @@ static int openfile(char *name, int flags, int growable, QDict *opts) if (bdrv_open(qemuio_bs, name, NULL, opts, flags, NULL, local_err) 0) { -fprintf(stderr, %s: can't open device %s: %s\n, progname, name, +fprintf(stderr, %s: can't open%s%s: %s\n, progname, +name ? device : , name ?: , error_get_pretty(local_err)); error_free(local_err); bdrv_unref(qemuio_bs); -- 1.9.3
Re: [Qemu-devel] [PATCH V2 4/4] hw/machine: qemu machine opts as properties to QemuMachineState
On Mon, 2014-05-26 at 18:20 +0200, Andreas Färber wrote: Am 26.05.2014 14:40, schrieb Marcel Apfelbaum: Make machine's QemuOpts QOM properties of machine. The properties are automatically filled in. This opens the possiblity to create opts per machine rather than global. Signed-off-by: Marcel Apfelbaum marce...@redhat.com --- hw/core/machine.c | 256 include/hw/boards.h | 6 +- vl.c| 10 +- 3 files changed, 266 insertions(+), 6 deletions(-) I've updated the commit message and inserted some white lines after variable block, and on top the following name cleanup to match your machine_initfn(): Thanks! diff --git a/hw/core/machine.c b/hw/core/machine.c index 0989c60..cbba679 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -276,7 +276,7 @@ static void machine_initfn(Object *obj) machine_get_firmware, machine_set_firmware, NULL); } -static void qemu_machine_finalize(Object *obj) +static void machine_finalize(Object *obj) { MachineState *ms = MACHINE(obj); @@ -297,7 +297,7 @@ static const TypeInfo machine_info = { .class_size = sizeof(MachineClass), .instance_size = sizeof(MachineState), .instance_init = machine_initfn, -.instance_finalize = qemu_machine_finalize, +.instance_finalize = machine_finalize, }; static void machine_register_types(void) Further there's a line too long: diff --git a/vl.c b/vl.c index 676df6e..8267679 100644 --- a/vl.c +++ b/vl.c @@ -4216,7 +4216,8 @@ int main(int argc, char **argv, char **envp) } machine_opts = qemu_get_machine_opts(); -if (qemu_opt_foreach(machine_opts, object_set_property, current_machine, 1) 0) { +if (qemu_opt_foreach(machine_opts, object_set_property, current_machine, + 1) 0) { object_unref(OBJECT(current_machine)); exit(1); } which makes me whether you are intentionally doing 0 here while the surrounding code is doing != 0? Minor nit only, of course. Well, I kind of took this from -object way to fill in the properties :). I am OK other-way, but we should change them both. The same for line length. Thanks again, Marcel Regards, Andreas
Re: [Qemu-devel] [PATCH V2 0/4] machine: QemuOpts per machine
On Mon, 2014-05-26 at 18:42 +0200, Andreas Färber wrote: Am 26.05.2014 14:48, schrieb Michael S. Tsirkin: On Mon, May 26, 2014 at 03:40:54PM +0300, Marcel Apfelbaum wrote: V1 - V2: - Rebased on qom-next queue. - Patch 1/4: - Since there are a lot of discussions on the correct way to do the fix, added a FIXME comment to find a better way. - Patch 2/4: - Addressed Michael Roth's comments: - Added output visitor test - Tweaked it as advised - Patch 4/4 - Addressed Andreas Farber's comments: - Renamed machine_state - ms to conform with the other patches In the other one it's machine now, but I agree that ms is sufficiently understandable in machine.c. :) - Solved an issue discovered with make check: - Updated machine-kernel_cmdline to be an empty string if no string was supplied by the user. - All other comments were addressed in the mail thread (I hope...) For series: Acked-by: Michael S. Tsirkin m...@redhat.com I have them queued on qom-next, Thanks for handling it so quickly, Marcel but giving mdroth a chance to ack/nack the QAPI bits. I believe all his comments are addressed now, save for deeper investigations with armbru that I hope can be done as follow-up. https://github.com/afaerber/qemu-cpu/commits/qom-next Still build-testing on BSD. Regards, Andreas
Re: [Qemu-devel] [PATCH 08/14] blockdev: Plug memory leak in blockdev_init()
The Monday 26 May 2014 à 19:37:09 (+0200), Markus Armbruster wrote : blockdev_init() leaks bs_opts when qemu_opts_create() fails, i.e. when the ID is bad. Missed in commit ec9c10d. Signed-off-by: Markus Armbruster arm...@redhat.com --- blockdev.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/blockdev.c b/blockdev.c index 1cbcc1c..6460c70 100644 --- a/blockdev.c +++ b/blockdev.c @@ -352,7 +352,7 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts, opts = qemu_opts_create(qemu_common_drive_opts, id, 1, error); if (error) { error_propagate(errp, error); -return NULL; +goto err_no_opts; } qemu_opts_absorb_qdict(opts, bs_opts, error); @@ -565,8 +565,9 @@ bdrv_new_err: g_free(dinfo-id); g_free(dinfo); early_err: -QDECREF(bs_opts); qemu_opts_del(opts); +err_no_opts: +QDECREF(bs_opts); return NULL; } -- 1.9.3 Reviewed-by: Benoit Canet ben...@irqsave.net
[Qemu-devel] [PATCH memory v2 0/9] Memory Region QOMification
Hi Paolo, Andreas, This patch series QOMifies Memory regions. This is the Memory API specific subset of patches forming part of the Memory/GPIO/Sysbus QOMification. I think Paolo already has P1 enqeued. Including for ease of review. some QOM patches in P2-3 that cut down on later boilerplate. TBH I can live without them, if they not liked but they make life better IMO. For fuller context please see: http://lists.gnu.org/archive/html/qemu-devel/2014-05/msg03265.html Changed since v1: Split into subset series. Converted container link into low level link. Misc finer tweaks and patch re-orderings. Peter Crosthwaite (9): memory: Simplify mr_add_subregion() if-else qom: object: Ignore refs/unrefs of NULL qom: Publish object_resolve_link memory: Coreify subregion add functionality memory: MemoryRegion: factor out memory region re-adder memory: MemoryRegion: QOMify memory: MemoryRegion: Add container and addr props memory: MemoryRegion: Add may-overlap and priority props memory: MemoryRegion: Add size property include/exec/memory.h | 8 +- include/qom/object.h | 16 +++ memory.c | 312 +++--- qom/object.c | 27 ++--- 4 files changed, 303 insertions(+), 60 deletions(-) -- 1.9.3.1.ga73a6ad
[Qemu-devel] [PATCH memory v2 1/9] memory: Simplify mr_add_subregion() if-else
This if else is not needed. The previous call to memory_region_add (whether _overlap or not) will always set priority and may_overlap to desired values. And its not possible to get here without having called memory_region_add_subregion due to the null guard on parent. So we can just directly call memory_region_add_subregion_common. Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com --- memory.c | 8 +--- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/memory.c b/memory.c index 3f1df23..1352881 100644 --- a/memory.c +++ b/memory.c @@ -1501,8 +1501,6 @@ void memory_region_set_enabled(MemoryRegion *mr, bool enabled) void memory_region_set_address(MemoryRegion *mr, hwaddr addr) { MemoryRegion *parent = mr-parent; -int priority = mr-priority; -bool may_overlap = mr-may_overlap; if (addr == mr-addr || !parent) { mr-addr = addr; @@ -1512,11 +1510,7 @@ void memory_region_set_address(MemoryRegion *mr, hwaddr addr) memory_region_transaction_begin(); memory_region_ref(mr); memory_region_del_subregion(parent, mr); -if (may_overlap) { -memory_region_add_subregion_overlap(parent, addr, mr, priority); -} else { -memory_region_add_subregion(parent, addr, mr); -} +memory_region_add_subregion_common(parent, addr, mr); memory_region_unref(mr); memory_region_transaction_commit(); } -- 1.9.3.1.ga73a6ad
[Qemu-devel] [PATCH memory v2 2/9] qom: object: Ignore refs/unrefs of NULL
Just do nothing if passed NULL for a ref or unref. This avoids call sites that manage a combination of NULL or non-NULL pointers having to add iffery around every ref and unref. Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com --- qom/object.c | 14 -- 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/qom/object.c b/qom/object.c index e42b254..ec5adf4 100644 --- a/qom/object.c +++ b/qom/object.c @@ -714,11 +714,17 @@ GSList *object_class_get_list(const char *implements_type, void object_ref(Object *obj) { +if (!obj) { +return; +} atomic_inc(obj-ref); } void object_unref(Object *obj) { +if (!obj) { +return; +} g_assert(obj-ref 0); /* parent always holds a reference to its children */ @@ -1119,13 +1125,9 @@ static void object_set_link_property(Object *obj, Visitor *v, void *opaque, return; } -if (new_target) { -object_ref(new_target); -} +object_ref(new_target); *child = new_target; -if (old_target != NULL) { -object_unref(old_target); -} +object_unref(old_target); } static void object_release_link_property(Object *obj, const char *name, -- 1.9.3.1.ga73a6ad
[Qemu-devel] [PATCH memory v2 4/9] memory: Coreify subregion add functionality
Split off the core looping code that actually adds subregions into it's own fn. This prepares support for Memory Region qomification where setting the MR address or parent via QOM will back onto this more minimal function. Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com --- memory.c | 18 -- 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/memory.c b/memory.c index 1352881..dd0a576 100644 --- a/memory.c +++ b/memory.c @@ -1410,18 +1410,15 @@ void memory_region_del_eventfd(MemoryRegion *mr, memory_region_transaction_commit(); } -static void memory_region_add_subregion_common(MemoryRegion *mr, - hwaddr offset, - MemoryRegion *subregion) +static void do_memory_region_add_subregion_common(MemoryRegion *subregion) { +hwaddr offset = subregion-addr; +MemoryRegion *mr = subregion-parent; MemoryRegion *other; memory_region_transaction_begin(); -assert(!subregion-parent); memory_region_ref(subregion); -subregion-parent = mr; -subregion-addr = offset; QTAILQ_FOREACH(other, mr-subregions, subregions_link) { if (subregion-may_overlap || other-may_overlap) { continue; @@ -1455,6 +1452,15 @@ done: memory_region_transaction_commit(); } +static void memory_region_add_subregion_common(MemoryRegion *mr, + hwaddr offset, + MemoryRegion *subregion) +{ +assert(!subregion-parent); +subregion-parent = mr; +subregion-addr = offset; +do_memory_region_add_subregion_common(subregion); +} void memory_region_add_subregion(MemoryRegion *mr, hwaddr offset, -- 1.9.3.1.ga73a6ad
Re: [Qemu-devel] [Qemu-stable] [PATCH 09/14] blockdev: Plug memory leak in drive_init()
The Monday 26 May 2014 à 19:37:10 (+0200), Markus Armbruster wrote : Introduced in commit f298d07. Spotted by Coverity. Signed-off-by: Markus Armbruster arm...@redhat.com --- blockdev.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/blockdev.c b/blockdev.c index 6460c70..7ec7d79 100644 --- a/blockdev.c +++ b/blockdev.c @@ -941,6 +941,7 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type) /* Actual block device init: Functionality shared with blockdev-add */ dinfo = blockdev_init(filename, bs_opts, local_err); +bs_opts = NULL; if (dinfo == NULL) { if (local_err) { qerror_report_err(local_err); @@ -978,6 +979,7 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type) fail: qemu_opts_del(legacy_opts); +QDECREF(bs_opts); return dinfo; } -- 1.9.3 This commits seems to fix two thing a leak and a double free. Maybe reflecting this on the commit message would make the bs_opts = NULL; clearer. Best regards Benoît
[Qemu-devel] [PATCH memory v2 5/9] memory: MemoryRegion: factor out memory region re-adder
memory_region_set_address is mostly just a function that deletes and re-adds a memory region. Factor this generic functionality out into a re-usable function. This prepares support for further QOMification of MemoryRegion. Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com --- memory.c | 30 +++--- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/memory.c b/memory.c index dd0a576..aa25667 100644 --- a/memory.c +++ b/memory.c @@ -828,6 +828,23 @@ static void memory_region_destructor_rom_device(MemoryRegion *mr) qemu_ram_free(mr-ram_addr TARGET_PAGE_MASK); } +static void do_memory_region_add_subregion_common(MemoryRegion *subregion); + +static void memory_region_readd_subregion(MemoryRegion *mr) +{ +MemoryRegion *parent = mr-parent; + +if (parent) { +memory_region_transaction_begin(); +memory_region_ref(mr); +memory_region_del_subregion(parent, mr); +mr-parent = parent; +do_memory_region_add_subregion_common(mr); +memory_region_unref(mr); +memory_region_transaction_commit(); +} +} + void memory_region_init(MemoryRegion *mr, Object *owner, const char *name, @@ -1506,19 +1523,10 @@ void memory_region_set_enabled(MemoryRegion *mr, bool enabled) void memory_region_set_address(MemoryRegion *mr, hwaddr addr) { -MemoryRegion *parent = mr-parent; - -if (addr == mr-addr || !parent) { +if (addr != mr-addr) { mr-addr = addr; -return; +memory_region_readd_subregion(mr); } - -memory_region_transaction_begin(); -memory_region_ref(mr); -memory_region_del_subregion(parent, mr); -memory_region_add_subregion_common(parent, addr, mr); -memory_region_unref(mr); -memory_region_transaction_commit(); } void memory_region_set_alias_offset(MemoryRegion *mr, hwaddr offset) -- 1.9.3.1.ga73a6ad
[Qemu-devel] [PATCH memory v2 7/9] memory: MemoryRegion: Add container and addr props
Expose the already existing .parent and .addr fields as QOM properties. .parent (i.e. the field describing the memory region that contains this one in Memory hierachy) is renamed container. This is to avoid confusion with the owner field, which is much more akin to an actual QOM parent. Setting the .parent (container) will cause the memory subregion adding to happen. Nullifying or changing the .parent will delete or relocate (to a different container) the subregion resp. Setting or changing the address will relocate the memory region. Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com --- changed since v1: Converted container to low level link property and added subregion setup. memory.c | 108 +++ 1 file changed, 108 insertions(+) diff --git a/memory.c b/memory.c index d9d3c07..a95bb1e 100644 --- a/memory.c +++ b/memory.c @@ -16,6 +16,7 @@ #include exec/memory.h #include exec/address-spaces.h #include exec/ioport.h +#include qapi/visitor.h #include qemu/bitops.h #include qom/object.h #include trace.h @@ -861,9 +862,104 @@ void memory_region_init(MemoryRegion *mr, mr-name = g_strdup(name); } +static void memory_region_get_addr(Object *obj, Visitor *v, void *opaque, + const char *name, Error **errp) +{ +MemoryRegion *mr = MEMORY_REGION(obj); +Error *local_err = NULL; +uint64_t value = mr-addr; + +visit_type_uint64(v, value, name, local_err); +if (local_err) { +error_propagate(errp, local_err); +} +} + +static void memory_region_set_addr(Object *obj, Visitor *v, void *opaque, + const char *name, Error **errp) +{ +MemoryRegion *mr = MEMORY_REGION(obj); +Error *local_err = NULL; +uint64_t value; + +visit_type_uint64(v, value, name, local_err); +if (local_err) { +error_propagate(errp, local_err); +return; +} + +memory_region_set_address(mr, value); +} + +static void memory_region_set_container(Object *obj, Visitor *v, void *opaque, +const char *name, Error **errp) +{ +MemoryRegion *mr = MEMORY_REGION(obj); +Error *local_err = NULL; +MemoryRegion *old_parent = mr-parent; +MemoryRegion *new_parent = NULL; +char *path = NULL; + +visit_type_str(v, path, name, local_err); + +if (!local_err strcmp(path, ) != 0) { +new_parent = MEMORY_REGION(object_resolve_link(obj, name, path, + local_err)); +} + +if (local_err) { +error_propagate(errp, local_err); +return; +} + +object_ref(OBJECT(new_parent)); + +memory_region_transaction_begin(); +memory_region_ref(mr); +if (old_parent) { +memory_region_del_subregion(old_parent, mr); +} +mr-parent = new_parent; +if (new_parent) { +do_memory_region_add_subregion_common(mr); +} +memory_region_unref(mr); +memory_region_transaction_commit(); + +object_unref(OBJECT(old_parent)); +} + +static void memory_region_get_container(Object *obj, Visitor *v, void *opaque, +const char *name, Error **errp) +{ +MemoryRegion *mr = MEMORY_REGION(obj); +gchar *path = (gchar *); + +if (mr-parent) { +path = object_get_canonical_path(OBJECT(mr-parent)); +} +visit_type_str(v, path, name, errp); +if (mr-parent) { +g_free(path); +} +} + +static void memory_region_release_container(Object *obj, const char *name, +void *opaque) +{ +MemoryRegion *mr = MEMORY_REGION(obj); + +if (mr-parent) { +memory_region_del_subregion(mr-parent, mr); +object_unref(OBJECT(mr-parent)); +} +} + static void memory_region_initfn(Object *obj) { MemoryRegion *mr = MEMORY_REGION(obj); +gchar *container_link_type = g_strdup_printf(link%s, + TYPE_MEMORY_REGION); mr-ops = unassigned_mem_ops; mr-enabled = true; @@ -872,6 +968,18 @@ static void memory_region_initfn(Object *obj) QTAILQ_INIT(mr-subregions); memset(mr-subregions_link, 0, sizeof mr-subregions_link); QTAILQ_INIT(mr-coalesced); + +object_property_add(OBJECT(mr), container, container_link_type, +memory_region_get_container, +memory_region_set_container, +memory_region_release_container, +NULL, error_abort); +g_free(container_link_type); + +object_property_add(OBJECT(mr), addr, uint64, +memory_region_get_addr, +memory_region_set_addr, +NULL, NULL, error_abort); } static uint64_t unassigned_mem_read(void *opaque, hwaddr addr, -- 1.9.3.1.ga73a6ad
[Qemu-devel] [PATCH memory v2 8/9] memory: MemoryRegion: Add may-overlap and priority props
QOM propertyify the .may-overlap and .priority fields. The setters will re-add the memory as a subregion if needed (i.e. the values change when the memory region is already contained). Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com --- changed since v1: Converted priority to signed type include/exec/memory.h | 2 +- memory.c | 57 +++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/include/exec/memory.h b/include/exec/memory.h index 371c066..117c0d3 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -157,7 +157,7 @@ struct MemoryRegion { bool flush_coalesced_mmio; MemoryRegion *alias; hwaddr alias_offset; -int priority; +int32_t priority; bool may_overlap; QTAILQ_HEAD(subregions, MemoryRegion) subregions; QTAILQ_ENTRY(MemoryRegion) subregions_link; diff --git a/memory.c b/memory.c index a95bb1e..ee761a2 100644 --- a/memory.c +++ b/memory.c @@ -955,6 +955,55 @@ static void memory_region_release_container(Object *obj, const char *name, } } +static void memory_region_get_priority(Object *obj, Visitor *v, void *opaque, + const char *name, Error **errp) +{ +MemoryRegion *mr = MEMORY_REGION(obj); +Error *local_err = NULL; +uint32_t value = mr-addr; + +visit_type_uint32(v, value, name, local_err); +if (local_err) { +error_propagate(errp, local_err); +} +} + +static void memory_region_set_priority(Object *obj, Visitor *v, void *opaque, + const char *name, Error **errp) +{ +MemoryRegion *mr = MEMORY_REGION(obj); +Error *local_err = NULL; +uint32_t value; + +visit_type_uint32(v, value, name, local_err); +if (local_err) { +error_propagate(errp, local_err); +return; +} + +if (mr-priority != value) { +mr-priority = value; +memory_region_readd_subregion(mr); +} +} + +static bool memory_region_get_may_overlap(Object *obj, Error **errp) +{ +MemoryRegion *mr = MEMORY_REGION(obj); + +return mr-may_overlap; +} + +static void memory_region_set_may_overlap(Object *obj, bool value, Error **errp) +{ +MemoryRegion *mr = MEMORY_REGION(obj); + +if (mr-may_overlap != value) { +mr-may_overlap = value; +memory_region_readd_subregion(mr); +} +} + static void memory_region_initfn(Object *obj) { MemoryRegion *mr = MEMORY_REGION(obj); @@ -980,6 +1029,14 @@ static void memory_region_initfn(Object *obj) memory_region_get_addr, memory_region_set_addr, NULL, NULL, error_abort); +object_property_add(OBJECT(mr), priority, uint32, +memory_region_get_priority, +memory_region_set_priority, +NULL, NULL, error_abort); +object_property_add_bool(OBJECT(mr), may-overlap, + memory_region_get_may_overlap, + memory_region_set_may_overlap, + error_abort); } static uint64_t unassigned_mem_read(void *opaque, hwaddr addr, -- 1.9.3.1.ga73a6ad
[Qemu-devel] [PATCH memory v2 6/9] memory: MemoryRegion: QOMify
QOMify memory regions as an Object. The former init() and destroy() routines become instance_init() and instance_finalize() resp. memory_region_init() is re-implemented to be: object_initialize() + set fields memory_region_destroy() is re-implemented to call finalize(). Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com --- include/exec/memory.h | 6 ++ memory.c | 55 +-- 2 files changed, 42 insertions(+), 19 deletions(-) diff --git a/include/exec/memory.h b/include/exec/memory.h index 1d55ad9..371c066 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -31,10 +31,15 @@ #include qemu/queue.h #include qemu/int128.h #include qemu/notify.h +#include qom/object.h #define MAX_PHYS_ADDR_SPACE_BITS 62 #define MAX_PHYS_ADDR(((hwaddr)1 MAX_PHYS_ADDR_SPACE_BITS) - 1) +#define TYPE_MEMORY_REGION qemu:memory-region +#define MEMORY_REGION(obj) \ +OBJECT_CHECK(MemoryRegion, (obj), TYPE_MEMORY_REGION) + typedef struct MemoryRegionOps MemoryRegionOps; typedef struct MemoryRegionMmio MemoryRegionMmio; @@ -130,6 +135,7 @@ typedef struct CoalescedMemoryRange CoalescedMemoryRange; typedef struct MemoryRegionIoeventfd MemoryRegionIoeventfd; struct MemoryRegion { +Object parent_obj; /* All fields are private - violators will be prosecuted */ const MemoryRegionOps *ops; const MemoryRegionIOMMUOps *iommu_ops; diff --git a/memory.c b/memory.c index aa25667..d9d3c07 100644 --- a/memory.c +++ b/memory.c @@ -850,35 +850,28 @@ void memory_region_init(MemoryRegion *mr, const char *name, uint64_t size) { -mr-ops = unassigned_mem_ops; -mr-opaque = NULL; +object_initialize(mr, sizeof(*mr), TYPE_MEMORY_REGION); + +/* FIXME: convert all to Properties */ mr-owner = owner; -mr-iommu_ops = NULL; -mr-parent = NULL; mr-size = int128_make64(size); if (size == UINT64_MAX) { mr-size = int128_2_64(); } -mr-addr = 0; -mr-subpage = false; +mr-name = g_strdup(name); +} + +static void memory_region_initfn(Object *obj) +{ +MemoryRegion *mr = MEMORY_REGION(obj); + +mr-ops = unassigned_mem_ops; mr-enabled = true; -mr-terminates = false; -mr-ram = false; mr-romd_mode = true; -mr-readonly = false; -mr-rom_device = false; mr-destructor = memory_region_destructor_none; -mr-priority = 0; -mr-may_overlap = false; -mr-alias = NULL; QTAILQ_INIT(mr-subregions); memset(mr-subregions_link, 0, sizeof mr-subregions_link); QTAILQ_INIT(mr-coalesced); -mr-name = g_strdup(name); -mr-dirty_log_mask = 0; -mr-ioeventfd_nb = 0; -mr-ioeventfds = NULL; -mr-flush_coalesced_mmio = false; } static uint64_t unassigned_mem_read(void *opaque, hwaddr addr, @@ -1099,8 +1092,10 @@ void memory_region_init_reservation(MemoryRegion *mr, memory_region_init_io(mr, owner, unassigned_mem_ops, mr, name, size); } -void memory_region_destroy(MemoryRegion *mr) +static void memory_region_finalize(Object *obj) { +MemoryRegion *mr = MEMORY_REGION(obj); + assert(QTAILQ_EMPTY(mr-subregions)); assert(memory_region_transaction_depth == 0); mr-destructor(mr); @@ -1109,6 +1104,13 @@ void memory_region_destroy(MemoryRegion *mr) g_free(mr-ioeventfds); } +void memory_region_destroy(MemoryRegion *mr) +{ +/*FIXME: whatever the opposite of object initialize is, do it here */ +memory_region_finalize(OBJECT(mr)); +} + + Object *memory_region_owner(MemoryRegion *mr) { return mr-owner; @@ -1886,3 +1888,18 @@ void mtree_info(fprintf_function mon_printf, void *f) g_free(ml); } } + +static const TypeInfo memory_region_info = { +.parent = TYPE_OBJECT, +.name = TYPE_MEMORY_REGION, +.instance_size = sizeof(MemoryRegion), +.instance_init = memory_region_initfn, +.instance_finalize = memory_region_finalize, +}; + +static void memory_register_types(void) +{ +type_register_static(memory_region_info); +} + +type_init(memory_register_types) -- 1.9.3.1.ga73a6ad
Re: [Qemu-devel] [Qemu-trivial] patch: add delay=msecs suboption to -display curses
On Di, 2014-05-27 at 04:15 -0400, Dave Mielke wrote: [quoted lines by Gerd Hoffmann on 2014/05/27 at 07:44 +0200] What exactly is the problem? At the user level, the keyboard appears to be dead. An inspection of the udnerlying code reveals that the application itsllf is querying the MS-DOS keyboard input buffer in a bad way. Which means exactly? They are not prepared to find data for more than one key event in the buffer? Those apps can't be fixed, though, because the bad code is in a library which is statically linked into every app using it, which means lots of apps, many of which, as is always the case, may not even have source code anymore. Sure. Another thing to consider is that this, really, is a general problem. Most keyboard input code, especially in older days, would've nly ever been tested at typing speed. It should be expected, therefore, that there might be problems in some of it when input events arrive faster - in this case, infinitely fater. The solution I'm proposing, therefore, tackles it in a general way, and does nothing more than allow the user to request that, regardless of what the UI needs to do underneath, the keyboard events still arrive at the speed of a typist. I don't like the idea to do it in the UI code. I don't think the problem is as generic as you think it is. HID keyboards (usb, bluetooth) report keys in a completely different way, and probably your problem is specific to the ps/2 keyboard. I'd try to do it in the ps/2 code, and try to do it without a timer. Idea: Split the ps/2 keyboard queue into two. One will be guest-visible. The existing ps2 queue will do the job. The other, new queue will not be visible to the guest. Simliar to the queue you've added to the ui code. Put not more than one key event (1-3 scancodes) into the guest visible queue. Wait for the guest read the status register (signaling no more data) once. Then go refill the guest-visible queue from the invisible queue. With some luck this makes things work without a delay. If not we are not so lucky we have to fire a timer for queue refill after signaling no more data to the guest. Even in case we need a timer this is better than doing it in the ui code as we can arm the timer when we know the guest has actually seen the key event. So the guest being busy with something else and not polling the kbd for a time span longer than the delay will not break things, so we can use a pretty short delay. cheers, Gerd
[Qemu-devel] [PATCH memory v2 9/9] memory: MemoryRegion: Add size property
To allow devices to dynamically resize the device. The motivation is to allow devices with variable size to init their memory_region without size early and then correctly populate size at realize() time. Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com --- memory.c | 38 ++ 1 file changed, 38 insertions(+) diff --git a/memory.c b/memory.c index ee761a2..15c5d88 100644 --- a/memory.c +++ b/memory.c @@ -1004,6 +1004,40 @@ static void memory_region_set_may_overlap(Object *obj, bool value, Error **errp) } } +static void memory_region_get_size(Object *obj, Visitor *v, void *opaque, + const char *name, Error **errp) +{ +MemoryRegion *mr = MEMORY_REGION(obj); +Error *local_err = NULL; +uint64_t value = int128_get64(mr-size); + +visit_type_uint64(v, value, name, local_err); +if (local_err) { +error_propagate(errp, local_err); +} +} + +static void memory_region_set_size(Object *obj, Visitor *v, void *opaque, + const char *name, Error **errp) +{ +MemoryRegion *mr = MEMORY_REGION(obj); +Error *local_err = NULL; +uint64_t value; +Int128 v128; + +visit_type_uint64(v, value, name, local_err); +v128 = int128_make64(value); +if (local_err) { +error_propagate(errp, local_err); +return; +} + +if (!int128_eq(v128, mr-size)) { +mr-size = v128; +memory_region_readd_subregion(mr); +} +} + static void memory_region_initfn(Object *obj) { MemoryRegion *mr = MEMORY_REGION(obj); @@ -1037,6 +1071,10 @@ static void memory_region_initfn(Object *obj) memory_region_get_may_overlap, memory_region_set_may_overlap, error_abort); +object_property_add(OBJECT(mr), size, uint64, +memory_region_get_size, +memory_region_set_size, +NULL, NULL, error_abort); } static uint64_t unassigned_mem_read(void *opaque, hwaddr addr, -- 1.9.3.1.ga73a6ad
Re: [Qemu-devel] [RFC 1/3] using CPUMASK bitmaps to calculate cpu index
On Tue, 27 May 2014 08:39:00 + chen.fan.f...@cn.fujitsu.com chen.fan.f...@cn.fujitsu.com wrote: On Thu, 2014-05-22 at 15:26 +0200, Igor Mammedov wrote: On Tue, 13 May 2014 18:08:47 +0800 Chen Fan chen.fan.f...@cn.fujitsu.com wrote: instead of seeking the number of CPUs, using CPUMASK bitmaps to calculate the cpu index, also would be a gread benefit to remove cpu index. How would it help to remove cpu_index? I think the cpu_index is just a CPU counter,if we remove one sparse CPU by setting corresponding bit to zero. then adding a new one we could easily get this vacancy bit by find_first_zero_bit() rather than get a duplicate index by calculating the number of CPU. What if there is only one CPU at start nad there is a need to add CPU with cpu_index==10? Bitmap hardly changes here anything, it's just another way of doing: cpu_index = 0; CPU_FOREACH(some_cpu) { cpu_index++; } What would help however is replacing cpu_index at read points with CPUClass-get_arch_id() Then targets that need sparse index could override default get_arch_id() to suite their needs and use their own properties to set arch_id value. Caution: this change would cause migration breakage for target-i386, so x86_cpu_get_arch_id() should take care about it when used with old machine types. yes, but for migration, I think we should need to override the cpu index in function vmstate_register(NULL, cpu_index, vmstate_cpu_common, cpu) with an unique instance_id while hot-add/hot-remove CPU arbitrarily. maybe this unique instance_id can be 'apic-id'. you can use just get_arch_id() there instead. For target-i386 it returns apic id for other targets it's cpu_index. Just make sure that compat machine will use cpu_index so that migration for old machine types would work. Thanks, Chen Signed-off-by: Chen Fan chen.fan.f...@cn.fujitsu.com --- exec.c | 9 - include/qom/cpu.h | 9 + include/sysemu/sysemu.h | 7 --- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/exec.c b/exec.c index cf12049..2948841 100644 --- a/exec.c +++ b/exec.c @@ -473,16 +473,15 @@ void cpu_exec_init(CPUArchState *env) { CPUState *cpu = ENV_GET_CPU(env); CPUClass *cc = CPU_GET_CLASS(cpu); -CPUState *some_cpu; int cpu_index; #if defined(CONFIG_USER_ONLY) cpu_list_lock(); #endif -cpu_index = 0; -CPU_FOREACH(some_cpu) { -cpu_index++; -} +cpu_index = find_first_zero_bit(cc-cpu_present_mask, +MAX_CPUMASK_BITS); +set_bit(cpu_index, cc-cpu_present_mask); + cpu-cpu_index = cpu_index; cpu-numa_node = 0; QTAILQ_INIT(cpu-breakpoints); diff --git a/include/qom/cpu.h b/include/qom/cpu.h index df977c8..b8f46b1 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -70,6 +70,13 @@ typedef void (*CPUUnassignedAccess)(CPUState *cpu, hwaddr addr, struct TranslationBlock; +/* The following shall be true for all CPUs: + * cpu-cpu_index max_cpus = MAX_CPUMASK_BITS + * + * Note that cpu-get_arch_id() may be larger than MAX_CPUMASK_BITS. + */ +#define MAX_CPUMASK_BITS 255 + /** * CPUClass: * @class_by_name: Callback to map -cpu command line model name to an @@ -142,6 +149,8 @@ typedef struct CPUClass { const struct VMStateDescription *vmsd; int gdb_num_core_regs; const char *gdb_core_xml_file; + +DECLARE_BITMAP(cpu_present_mask, MAX_CPUMASK_BITS); } CPUClass; #ifdef HOST_WORDS_BIGENDIAN diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index ba5c7f8..04edb8b 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -134,13 +134,6 @@ extern QEMUClockType rtc_clock; #define MAX_NODES 64 -/* The following shall be true for all CPUs: - * cpu-cpu_index max_cpus = MAX_CPUMASK_BITS - * - * Note that cpu-get_arch_id() may be larger than MAX_CPUMASK_BITS. - */ -#define MAX_CPUMASK_BITS 255 - extern int nb_numa_nodes; extern uint64_t node_mem[MAX_NODES]; extern unsigned long *node_cpumask[MAX_NODES];
Re: [Qemu-devel] [v3][PATCH 0/5] xen: add Intel IGD passthrough support
Any further comments? Thanks Tiejun -Original Message- From: qemu-devel-bounces+tiejun.chen=intel@nongnu.org [mailto:qemu-devel-bounces+tiejun.chen=intel@nongnu.org] On Behalf Of Tiejun Chen Sent: Monday, May 26, 2014 5:43 PM To: anthony.per...@citrix.com; stefano.stabell...@eu.citrix.com; m...@redhat.com; kelly.zyta...@amd.com Cc: peter.mayd...@linaro.org; xen-de...@lists.xensource.com; Kay, Allen M; qemu-devel@nongnu.org; anth...@codemonkey.ws; Zhang, Yang Z Subject: [Qemu-devel] [v3][PATCH 0/5] xen: add Intel IGD passthrough support v3: * In this case, as we discussed we will give priority to devices to reserve a specific devfn by passing device_model_args_hvm = ['-device', 'xen-platform,addr=0x3'] and vga=none, so withdraw patch #1, #2 and #4. * Fix some typos. * Add more comments to make that readable. * To unmap igd_opregion when call xen_pt_unregister_vga_regions(). * Improve some return paths. * Force to convert igd_guest/host_opoegion as an unsigned long type while calling xc_domain_memory_mapping(). * We need to map 3 pages for opregion as hvmloader set. v2: * rebase on current qemu tree. * retrieve VGA bios from sysfs properly. * redefine some function name. * introduce bitmap to manage registe/runregister pci dev, and provide a common way to reserve some specific devfn. * introduce is_igd_passthrough() to make sure we touch physical host bridge only in IGD case. * We should return zero as an invalid address value while calling igd_read_opregion(). Additionally, now its also not necessary to recompile seabios with some extra steps like v1. The following patches are ported partially from Xen Qemu-traditional branch which are adding Intel IGD passthrough supporting to Qemu upstream. To pass through IGD to guest, user need to add following lines in Xen config file: gfx_passthru=1 pci=['00:02.0 at 2'] Now successfully boot Ubuntu 14.04 guests with IGD assigned in Haswell desktop with Latest Xen + Qemu upstream. Tiejun Chen (2): xen, gfx passthrough: create intel isa bridge xen, gfx passthrough: create host bridge to passthrough Yang Zhang (3): xen, gfx passthrough: basic graphics passthrough support xen, gfx passthrough: support Intel IGD passthrough with VT-D xen, gfx passthrough: add opregion mapping hw/pci-host/piix.c | 56 +- hw/xen/Makefile.objs | 2 +- hw/xen/xen-host-pci-device.c | 5 ++ hw/xen/xen-host-pci-device.h | 1 + hw/xen/xen_pt.c | 10 +++ hw/xen/xen_pt.h | 12 ++- hw/xen/xen_pt_config_init.c | 50 - hw/xen/xen_pt_graphics.c | 518 ++ qemu-options.hx | 9 +++ vl.c | 11 ++- 10 files changed, 668 insertions(+), 6 deletions(-) create mode 100644 hw/xen/xen_pt_graphics.c Thanks Tiejun
Re: [Qemu-devel] [PATCH 11/14] block/vvfat: Plug memory leak in check_directory_consistency()
The Monday 26 May 2014 à 19:37:12 (+0200), Markus Armbruster wrote : On error path. Introduced in commit a046433a. Spotted by Coverity. Signed-off-by: Markus Armbruster arm...@redhat.com --- block/vvfat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/vvfat.c b/block/vvfat.c index 6a0d246..2c82a5c 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -1864,7 +1864,7 @@ static int check_directory_consistency(BDRVVVFATState *s, if (s-used_clusters[cluster_num] USED_ANY) { fprintf(stderr, cluster %d used more than once\n, (int)cluster_num); - return 0; +goto fail; Hmm your editor display tabs at 8 chars so you put 12 chars of alignement. Anyway the patch seems correct. Reviewed-by: Benoit Canet ben...@irqsave.net } s-used_clusters[cluster_num] = USED_DIRECTORY; -- 1.9.3
[Qemu-devel] [PATCH memory v2 3/9] qom: Publish object_resolve_link
The lower level API object_resolve_path is already published to the world as part of the QOM API. Add object_resolve link as well. This allows QOM clients to roll their own link property setters without having to fallback to the less safe object_resolve_path. Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com --- include/qom/object.h | 16 qom/object.c | 13 ++--- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/include/qom/object.h b/include/qom/object.h index a641dcd..7f96ecf 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -1048,6 +1048,22 @@ Object *object_resolve_path_type(const char *path, const char *typename, Object *object_resolve_path_component(Object *parent, const gchar *part); /** + * object_resolve_link: + * @obj: The object containing the link property + * @name: Name of the link property + * @path: the path to resolve + * @errp: Error object to populate in case of error + * + * Lookup an object and ensure its type matches a link property type. This + * is similar to object_resolve_path() except type verification against the + * link property is performed. + * + * Returns: The matched object or NULL on path lookup failures. + */ +Object *object_resolve_link(Object *obj, const char *name, +const char *path, Error **errp); + +/** * object_property_add_child: * @obj: the object to add a property to * @name: the name of the property diff --git a/qom/object.c b/qom/object.c index ec5adf4..b9b2736 100644 --- a/qom/object.c +++ b/qom/object.c @@ -1058,17 +1058,8 @@ static void object_get_link_property(Object *obj, Visitor *v, void *opaque, } } -/* - * object_resolve_link: - * - * Lookup an object and ensure its type matches the link property type. This - * is similar to object_resolve_path() except type verification against the - * link property is performed. - * - * Returns: The matched object or NULL on path lookup failures. - */ -static Object *object_resolve_link(Object *obj, const char *name, - const char *path, Error **errp) +Object *object_resolve_link(Object *obj, const char *name, +const char *path, Error **errp) { const char *type; gchar *target_type; -- 1.9.3.1.ga73a6ad
Re: [Qemu-devel] [PATCH 12/14] block/vvfat: Plug memory leak in read_directory()
The Monday 26 May 2014 à 19:37:13 (+0200), Markus Armbruster wrote : Has always been leaky. Spotted by Coverity. Signed-off-by: Markus Armbruster arm...@redhat.com --- block/vvfat.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/block/vvfat.c b/block/vvfat.c index 2c82a5c..389704a 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -787,7 +787,9 @@ static int read_directory(BDRVVVFATState* s, int mapping_index) s-current_mapping-path=buffer; s-current_mapping-read_only = (st.st_mode (S_IWUSR | S_IWGRP | S_IWOTH)) == 0; - } + } else { +g_free(buffer); +} } closedir(dir); Reviewed-by: Benoit Canet ben...@irqsave.net -- 1.9.3
Re: [Qemu-devel] [PATCH 13/14] block/sheepdog: Plug memory leak in sd_snapshot_create()
The Monday 26 May 2014 à 19:37:14 (+0200), Markus Armbruster wrote : Has always been leaky. Spotted by Coverity. Signed-off-by: Markus Armbruster arm...@redhat.com --- block/sheepdog.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/block/sheepdog.c b/block/sheepdog.c index 2c3fb01..9a9a307 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -2149,6 +2149,7 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) strncpy(s-inode.tag, sn_info-name, sizeof(s-inode.tag)); /* we don't need to update entire object */ datalen = SD_INODE_SIZE - sizeof(s-inode.data_vdi_id); +inode = g_malloc(datalen); /* refresh inode. */ fd = connect_to_sdog(s); @@ -2171,8 +2172,6 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) goto cleanup; } -inode = (SheepdogInode *)g_malloc(datalen); - ret = read_object(fd, (char *)inode, vid_to_vdi_oid(new_vid), s-inode.nr_copies, datalen, 0, s-cache_flags); @@ -2186,6 +2185,7 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) s-inode.name, s-inode.snap_id, s-inode.vdi_id); cleanup: +g_free(inode); closesocket(fd); return ret; } -- 1.9.3 Reviewed-by: Benoit Canet ben...@irqsave.net
Re: [Qemu-devel] KVM call agenda for 2014-05-27
On Mon, 26 May 2014 14:00:20 +0200 Christian Borntraeger borntrae...@de.ibm.com wrote: On 21/05/14 23:43, Juan Quintela wrote: Hi Please, send any topic that you are interested in covering. (mostly) Michael Mueller - CPU models on s390 and other platforms. Interfaces/requirements/Contraints etc. Thanks, Juan. Call details: 15:00 CEST 13:00 UTC 09:00 EDT Every two weeks If you need phone number details, contact me privately. PS: Please send it to me,Michael and Jason. In case we get to this I have prepared a visual, see. attachment. Michael CPU-Model-Design-VS1255-v2.pdf Description: Adobe PDF document
Re: [Qemu-devel] [PATCH 14/14] qemu-img: Plug memory leak in convert command
The Monday 26 May 2014 à 19:37:15 (+0200), Markus Armbruster wrote : Introduced in commit 661a0f7. Spotted by Coverity. Signed-off-by: Markus Armbruster arm...@redhat.com --- qemu-img.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qemu-img.c b/qemu-img.c index 62ea27e..d118da5 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -1455,7 +1455,7 @@ static int img_convert(int argc, char **argv) ret = bdrv_parse_cache_flags(cache, flags); if (ret 0) { error_report(Invalid cache option: %s, cache); -return -1; +goto out; } out_bs = bdrv_new_open(target, out_filename, out_fmt, flags, true, quiet); -- 1.9.3 Reviewed-by: Benoit Canet ben...@irqsave.net
Re: [Qemu-devel] [PATCH 10/14] block/qapi: Plug memory leak in dump_qobject() case QTYPE_QERROR
The Monday 26 May 2014 à 19:37:11 (+0200), Markus Armbruster wrote : Introduced in commit a8d8ecb. Spotted by Coverity. Signed-off-by: Markus Armbruster arm...@redhat.com --- block/qapi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/block/qapi.c b/block/qapi.c index 75f44f1..97e1641 100644 --- a/block/qapi.c +++ b/block/qapi.c @@ -475,6 +475,7 @@ static void dump_qobject(fprintf_function func_fprintf, void *f, case QTYPE_QERROR: { QString *value = qerror_human((QError *)obj); func_fprintf(f, %s, qstring_get_str(value)); +QDECREF(value); break; } case QTYPE_NONE: -- 1.9.3 Reviewed-by: Benoit Canet ben...@irqsave.net
Re: [Qemu-devel] [RFC] qdict: issue about usb controller hot-plug/unplug
On Di, 2014-05-27 at 08:28 +, Gonglei (Arei) wrote: Hi, Those day, I'm working for usb controller hot-plugging/unplugging( not enable multifunction capability). Everything work well, but when I test the case of hot-plug/unplug reiteratively, qemu will be aborted: Guess you've removed the dc-hotpluggable = false and added a cleanup function? I don't know why the new qdict address will conflict with the global usb busses. tqh_last? Most likely something is missing in the cleanup, leading to a use-after-free. Usually Electric Fence is pretty good at catching them. http://www.pf-lug.de/projekte/haya/efence.php cheers, Gerd
Re: [Qemu-devel] [RFC] qdict: issue about usb controller hot-plug/unplug
-Original Message- From: Gerd Hoffmann [mailto:kra...@redhat.com] Sent: Tuesday, May 27, 2014 5:25 PM To: Gonglei (Arei) Cc: qemu-devel@nongnu.org; pbonz...@redhat.com; m...@redhat.com; lcapitul...@redhat.com; peter.mayd...@linaro.org Subject: Re: [RFC] qdict: issue about usb controller hot-plug/unplug On Di, 2014-05-27 at 08:28 +, Gonglei (Arei) wrote: Hi, Those day, I'm working for usb controller hot-plugging/unplugging( not enable multifunction capability). Everything work well, but when I test the case of hot-plug/unplug reiteratively, qemu will be aborted: Guess you've removed the dc-hotpluggable = false and added a cleanup function? Hum...That's it! I don't know why the new qdict address will conflict with the global usb busses. tqh_last? Most likely something is missing in the cleanup, leading to a use-after-free. Usually Electric Fence is pretty good at catching them. http://www.pf-lug.de/projekte/haya/efence.php I haven't use the tools before, but I am using Coverity for qemu code recently, hope I can get some useful clue. Thanks for your remind, Gerd. Best regards, -Gonglei
Re: [Qemu-devel] [PATCH] [qemu-devel] fix wrong order when doing live block migration setup
Hi, Sorry for forgetting to cc maintainers. I got this issue when doing live migration test, and simple steps to reproduce are master: qemu -enable-kvm -smp 1 -m 512 -drive file=/data1/src.img,if=virtio \ -net none -monitor stdio -vnc 0:2 slave: qemu -enable-kvm -smp 1 -m 512 -dirve file=/data2/dest.img,if=virtio \ -net none -monitor stdio -vnc 0:3 -incoming tcp:127.0.0.1: \ when doing migration cmd migrate -b tcp:127.0.0.1: in master's monitor, it throws out a segfault error. After checking some code of block migration, I think there is something wrong with the setup sequence in block migration setup. thanks chai wen On 05/27/2014 04:54 PM, chai wen wrote: If we want to track dirty blocks using dirty_maps on a BlockDriverState when doing live block-migration, its correspoding 'BlkMigDevState' should be add to block_mig_state.bmds_list firstly for subsequent processing. Otherwise set_dirty_tracking will do nothing on an empty list than allocating dirty_bitmaps for them. And what's the worse, bdrv_get_dirty_count will access the bmds-dirty_maps directly, there could be a segfault as the reasons above. Signed-off-by: chai wen chaiw.f...@cn.fujitsu.com --- block-migration.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/block-migration.c b/block-migration.c index 56951e0..43203aa 100644 --- a/block-migration.c +++ b/block-migration.c @@ -626,6 +626,7 @@ static int block_save_setup(QEMUFile *f, void *opaque) block_mig_state.submitted, block_mig_state.transferred); qemu_mutex_lock_iothread(); +init_blk_migration(f); /* start track dirty blocks */ ret = set_dirty_tracking(); @@ -635,7 +636,6 @@ static int block_save_setup(QEMUFile *f, void *opaque) return ret; } -init_blk_migration(f); qemu_mutex_unlock_iothread(); -- Regards Chai Wen
Re: [Qemu-devel] [v2 PATCH] target-mips: implement UserLocal Register
Hi Richard, On 27/05/14 03:38, Richard Henderson wrote: On 05/26/2014 07:32 PM, Petar Jovanovic wrote: From: Richard Henderson [rth7...@gmail.com] on behalf of Richard Henderson [r...@twiddle.net] Sent: Tuesday, May 27, 2014 3:35 AM To: Petar Jovanovic; Petar Jovanovic; qemu-devel@nongnu.org Cc: aurel...@aurel32.net; James Hogan Subject: Re: [v2 PATCH] target-mips: implement UserLocal Register On 05/26/2014 06:21 PM, Petar Jovanovic wrote: Because we do not know the content of CP0_HWREna. We can know the same way we know the content of CP0_Config3. Almost all the bits in CP0_Config3 including ULRI bit are read-only and preset by hardware, thus checking bit ULRI at translation time is the same as checking it at execution time. How can we know the content of CP0_HWREna at translation time? That's what tb-flags and env-hflags. An encoding of cpu state at translation time. I agree for the Config3 bit that it shouldn't change during execution of the guest so can be done at translation time, but I'm not convinced it's worth wasting tb-flags bits for CP0_HWREna state which the guest OS is free to change at any time, just to save a single branch each time it's used (which could be done in tcg easily enough to avoid the helper). Only a minority of code uses RDHWR, although admittedly UserLocal is the most widespread of the RDHWR registers due to it's use for thread local storage. A quick and non-scientific look (assuming all code is equal) at my MIPS32 buildroot userland shows 1286 rdhwrs of UserLocal in 14 million total lines of objdump (1 in 10929 instructions), and only a handful of the other rdhwr registers. Cheers James
Re: [Qemu-devel] [PATCH v3 3/9] target-ppc: Implement compat CPU option
On 23.05.14 04:26, Alexey Kardashevskiy wrote: This adds basic support for the compat CPU option. By specifying the compat property, the user can manually switch guest CPU mode from raw to architected. This defines feature disable bits which are not used yet as, for example, PowerISA 2.07 says if 2.06 mode is selected, the TM bit does not matter - transactional memory (TM) will be disabled because 2.06 does not define it at all. The same is true for VSX and 2.05 mode. So just setting a mode must be ok. This does not change the existing behavior as the actual compatibility mode support is coming in next patches. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- hw/ppc/spapr.c | 14 ++ target-ppc/cpu-qom.h| 2 ++ target-ppc/cpu.h| 11 +++ target-ppc/translate_init.c | 34 ++ 4 files changed, 61 insertions(+) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index aa17cae..5ea9640 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -210,6 +210,14 @@ static int spapr_fixup_cpu_smt_dt(void *fdt, int offset, PowerPCCPU *cpu, uint32_t gservers_prop[smt_threads * 2]; int index = ppc_get_vcpu_dt_id(cpu); +if (cpu-cpu_version) { +ret = fdt_setprop(fdt, offset, cpu-version, + cpu-cpu_version, sizeof(cpu-cpu_version)); +if (ret 0) { +return ret; +} +} + /* Build interrupt servers and gservers properties */ for (i = 0; i smt_threads; i++) { servers_prop[i] = cpu_to_be32(index + i); @@ -1289,6 +1297,12 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args) kvmppc_set_papr(cpu); } +if (cpu-max_compat) { +if (ppc_set_compat(cpu, cpu-max_compat) 0) { +exit(1); +} +} + xics_cpu_setup(spapr-icp, cpu); qemu_register_reset(spapr_cpu_reset, cpu); diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h index 533de8f..e88e1da 100644 --- a/target-ppc/cpu-qom.h +++ b/target-ppc/cpu-qom.h @@ -84,6 +84,7 @@ typedef struct PowerPCCPUClass { * @env: #CPUPPCState * @cpu_dt_id: CPU index used in the device tree. KVM uses this index too * @max_compat: Maximal supported logical PVR from the command line + * @cpu_version: Current logical PVR, zero if in raw mode * * A PowerPC CPU. */ @@ -95,6 +96,7 @@ struct PowerPCCPU { CPUPPCState env; int cpu_dt_id; uint32_t max_compat; +uint32_t cpu_version; }; static inline PowerPCCPU *ppc_env_get_cpu(CPUPPCState *env) diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index b035e91..d3b8236 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -1122,6 +1122,7 @@ void ppc_store_sdr1 (CPUPPCState *env, target_ulong value); void ppc_store_msr (CPUPPCState *env, target_ulong value); void ppc_cpu_list (FILE *f, fprintf_function cpu_fprintf); +int ppc_set_compat(PowerPCCPU *cpu, uint32_t cpu_version); /* Time-base and decrementer management */ #ifndef NO_CPU_IO_DEFS @@ -1338,6 +1339,7 @@ static inline int cpu_mmu_index (CPUPPCState *env) #define SPR_LPCR (0x13E) #define SPR_BOOKE_DVC2(0x13F) #define SPR_BOOKE_TSR (0x150) +#define SPR_PCR (0x152) #define SPR_BOOKE_TCR (0x154) #define SPR_BOOKE_TLB0PS (0x158) #define SPR_BOOKE_TLB1PS (0x159) @@ -2061,6 +2063,15 @@ enum { PPC_INTERRUPT_PERFM, /* Performance monitor interrupt*/ }; +/* Processor Compatibility mask (PCR) */ +enum { +PCR_COMPAT_2_05 = 1ul (63-62), +PCR_COMPAT_2_06 = 1ul (63-61), +PCR_VEC_DIS = 1ul (63-0), /* Vec. disable (bit NA since POWER8) */ +PCR_VSX_DIS = 1ul (63-1), /* VSX disable (bit NA since POWER8) */ +PCR_TM_DIS = 1ul (63-2), /* Trans. memory disable (POWER8) */ This breaks compilation on 32bit hosts with 05/27 01:53:16 ERROR| utils:0144| [stderr] In file included from /usr/local/autotest/tmp/virt/src/qemu/include/qemu-common.h:116:0, 05/27 01:53:16 ERROR| utils:0144| [stderr] from /usr/local/autotest/tmp/virt/src/qemu/exec.c:25: 05/27 01:53:16 ERROR| utils:0144| [stderr] /usr/local/autotest/tmp/virt/src/qemu/target-ppc/cpu.h:2071:5: error: left shift count = width of type [-Werror] 05/27 01:53:16 ERROR| utils:0144| [stderr] /usr/local/autotest/tmp/virt/src/qemu/target-ppc/cpu.h:2072:5: error: left shift count = width of type [-Werror] 05/27 01:53:16 ERROR| utils:0144| [stderr] /usr/local/autotest/tmp/virt/src/qemu/target-ppc/cpu.h:2073:5: error: left shift count = width of type [-Werror] 05/27 01:53:16 ERROR| utils:0144| [stderr] cc1: all warnings being treated as errors I've changed the 1 to be ULL instead of UL (which is usually bogus in TCG code) Alex
Re: [Qemu-devel] [PATCH 7/8] dump: Fix use-after-free in create_kdump_vmcore()
On 05/27/14 03:40, arei.gong...@huawei.com wrote: From: Gonglei arei.gong...@huawei.com Spotted by Coverity: (7) Event closed_arg: write_dump_pages(DumpState *) closes s-fd. [details] Also see events: [pass_closed_arg] 1490ret = write_dump_pages(s); (8) Event cond_false: Condition ret 0, taking false branch 1491if (ret 0) { 1492return -1; (9) Event if_end: End of if statement 1493} 1494 (10) Event pass_closed_arg: Passing closed handle s-fd as an argument to function write_end_flat_header(int). Also see events: [closed_arg] 1495ret = write_end_flat_header(s-fd); 1496if (ret 0) { 1497dump_error(s, dump: failed to write end flat header.\n); 1498return -1; 1499} 1500 1501dump_completed(s); 1502 1503return 0; 1504} Signed-off-by: Gonglei arei.gong...@huawei.com --- dump.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dump.c b/dump.c index e56b7cf..3a704e9 100644 --- a/dump.c +++ b/dump.c @@ -1296,6 +1296,7 @@ static int write_dump_pages(DumpState *s) /* prepare buffer to store compressed data */ len_buf_out = get_len_buf_out(s-page_size, s-flag_compress); if (len_buf_out == 0) { +ret = -1; dump_error(s, dump: failed to get length of output buffer.\n); goto out; } This patch conflicts with my pending set (which has one R-b from Paolo). Patch 7/7 of the series in question reworks get_len_buf_out(), and then write_dump_pages() asserts that the retval is zero. http://lists.nongnu.org/archive/html/qemu-devel/2014-05/msg03966.html Gonglei (Arei), can you please rebase this series on mine? And Luiz, can you please pick up my series? Thanks, Laszlo
Re: [Qemu-devel] [PATCH] [qemu-devel] fix wrong order when doing live block migration setup
On Tue, 05/27 16:54, chai wen wrote: If we want to track dirty blocks using dirty_maps on a BlockDriverState when doing live block-migration, its correspoding 'BlkMigDevState' should be add to block_mig_state.bmds_list firstly for subsequent processing. Otherwise set_dirty_tracking will do nothing on an empty list than allocating dirty_bitmaps for them. And what's the worse, bdrv_get_dirty_count will access the bmds-dirty_maps directly, there could be a segfault as the reasons above. Signed-off-by: chai wen chaiw.f...@cn.fujitsu.com --- block-migration.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/block-migration.c b/block-migration.c index 56951e0..43203aa 100644 --- a/block-migration.c +++ b/block-migration.c @@ -626,6 +626,7 @@ static int block_save_setup(QEMUFile *f, void *opaque) block_mig_state.submitted, block_mig_state.transferred); qemu_mutex_lock_iothread(); +init_blk_migration(f); Thanks for spotting this! I reverted the order of init_blk_migration and set_dirty_tracking in commit b8afb520e (block: Handle error of bdrv_getlength in bdrv_create_dirty_bitmap) incorrectly, thought that in this way, no clean up is needed if set_dirty_tracking fails. But by looking at savevm.c:qemu_savevm_state() we can see that qemu_savevm_state_cancel() will do the clean up automatically, so this fix is valid. Reviewed-by: Fam Zheng f...@redhat.com /* start track dirty blocks */ ret = set_dirty_tracking(); @@ -635,7 +636,6 @@ static int block_save_setup(QEMUFile *f, void *opaque) return ret; } -init_blk_migration(f); qemu_mutex_unlock_iothread(); -- 1.7.1
[Qemu-devel] [PATCH v3 18/24] target-ppc: Add POWER8's FSCR SPR
This adds an FSCR (Facility Status and Control Register) SPR. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- target-ppc/cpu.h| 1 + target-ppc/translate_init.c | 9 + 2 files changed, 10 insertions(+) diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index d0238e6..c2a84fd 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -1272,6 +1272,7 @@ static inline int cpu_mmu_index (CPUPPCState *env) #define SPR_CTRL (0x098) #define SPR_MPC_CMPE (0x098) #define SPR_MPC_CMPF (0x099) +#define SPR_FSCR (0x099) #define SPR_MPC_CMPG (0x09A) #define SPR_MPC_CMPH (0x09B) #define SPR_MPC_LCTRL1(0x09C) diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 6bcb41c..0682739 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -7598,6 +7598,14 @@ static void gen_spr_power8_branch_control(CPUPPCState *env) 0x); } +static void gen_spr_power8_common(CPUPPCState *env) +{ +spr_register_kvm(env, SPR_FSCR, FSCR, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, spr_write_generic, + KVM_REG_PPC_FSCR, 0x); +} + static void init_proc_POWER(CPUPPCState *env, int version) { gen_spr_ne_601(env); @@ -7640,6 +7648,7 @@ static void init_proc_POWER(CPUPPCState *env, int version) if (version = BOOK3S_CPU_POWER8) { gen_spr_power8_branch_control(env); gen_spr_power8_pmu(env); +gen_spr_power8_common(env); } #if !defined(CONFIG_USER_ONLY) switch (version) { -- 1.8.4.rc4
[Qemu-devel] [PATCH v3 10/24] target-ppc: Introduce and reuse generalized init_proc_POWER()
At the moment every POWER CPU family has its own init_proc_POWERX function. E500 already has common init function so we try to do the same thing. This introduces BOOK3S_CPU_TYPE enum with 2 values - 970 and POWER5+. This introduces generalized init_proc_POWER() which accepts a CPU type as a parameter. This uses new init function for 970 and POWER5+ CPU classes. 970 and POWER5+ use the same CPU class initialization except 3 things: 1. logical partitioning is controlled by LPCR (POWER5+) and HID4 (970) SPRs; 2. 970 does not have EAR (External Access Register) SPR and PowerISA 2.03 defines one so keep it only for POWER5+; 3. POWER5+ does not have ALTIVEC so insns_flags does not have PPC_ALTIVEC flag set and gen_spr_book3s_altivec() won't init ALTIVEC for POWER5+. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- target-ppc/translate_init.c | 85 ++--- 1 file changed, 27 insertions(+), 58 deletions(-) diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 7662730..5556b02 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -7273,6 +7273,11 @@ POWERPC_FAMILY(e600)(ObjectClass *oc, void *data) #define POWERPC970_HID5_INIT 0x #endif +enum BOOK3S_CPU_TYPE { +BOOK3S_CPU_970, +BOOK3S_CPU_POWER5PLUS, +}; + static int check_pow_970 (CPUPPCState *env) { if (env-spr[SPR_HID0] 0x01C0) { @@ -7474,6 +7479,15 @@ static void gen_spr_book3s_external_control(CPUPPCState *env) 0x); } +static void gen_spr_book3s_lpar(CPUPPCState *env) +{ +/* Logical partitionning */ +spr_register_kvm(env, SPR_LPCR, LPCR, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, spr_write_generic, + KVM_REG_PPC_LPCR, 0x); +} + static void gen_spr_970_lpar(CPUPPCState *env) { /* Logical partitionning */ @@ -7484,7 +7498,7 @@ static void gen_spr_970_lpar(CPUPPCState *env) 0x); } -static void init_proc_970 (CPUPPCState *env) +static void init_proc_POWER(CPUPPCState *env, int version) { gen_spr_ne_601(env); gen_tbl(env); @@ -7497,9 +7511,13 @@ static void init_proc_970 (CPUPPCState *env) gen_low_BATs(env); gen_spr_970_ctrl(env); gen_spr_970_pmu(env); -gen_spr_970_lpar(env); -gen_spr_book3s_external_control(env); +if (version = BOOK3S_CPU_POWER5PLUS) { +gen_spr_book3s_lpar(env); +gen_spr_book3s_external_control(env); +} else { +gen_spr_970_lpar(env); +} gen_spr_970_dbg(env); #if !defined(CONFIG_USER_ONLY) @@ -7512,6 +7530,11 @@ static void init_proc_970 (CPUPPCState *env) ppc970_irq_init(env); } +static void init_proc_970(CPUPPCState *env) +{ +init_proc_POWER(env, BOOK3S_CPU_970); +} + POWERPC_FAMILY(970)(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); @@ -7569,61 +7592,7 @@ static int check_pow_970FX (CPUPPCState *env) static void init_proc_power5plus(CPUPPCState *env) { -gen_spr_ne_601(env); -gen_spr_7xx(env); -/* Time base */ -gen_tbl(env); -/* Hardware implementation registers */ -/* XXX : not implemented */ -spr_register(env, SPR_HID0, HID0, - SPR_NOACCESS, SPR_NOACCESS, - spr_read_generic, spr_write_clear, - 0x6000); -/* XXX : not implemented */ -spr_register(env, SPR_HID1, HID1, - SPR_NOACCESS, SPR_NOACCESS, - spr_read_generic, spr_write_generic, - 0x); -/* XXX : not implemented */ -spr_register(env, SPR_970_HID5, HID5, - SPR_NOACCESS, SPR_NOACCESS, - spr_read_generic, spr_write_generic, - POWERPC970_HID5_INIT); -/* Memory management */ -/* XXX: not correct */ -gen_low_BATs(env); -spr_register(env, SPR_HIOR, SPR_HIOR, - SPR_NOACCESS, SPR_NOACCESS, - spr_read_hior, spr_write_hior, - 0x); -spr_register(env, SPR_CTRL, SPR_CTRL, - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, spr_write_generic, - 0x); -spr_register(env, SPR_UCTRL, SPR_UCTRL, - SPR_NOACCESS, SPR_NOACCESS, - spr_read_generic, SPR_NOACCESS, - 0x); -spr_register(env, SPR_VRSAVE, SPR_VRSAVE, - spr_read_generic, spr_write_generic, - spr_read_generic, spr_write_generic, - 0x); -/* Logical partitionning */ -spr_register_kvm(env, SPR_LPCR, LPCR, - SPR_NOACCESS, SPR_NOACCESS, - spr_read_generic, spr_write_generic, - KVM_REG_PPC_LPCR, 0x); -#if !defined(CONFIG_USER_ONLY) -env-slb_nr = 64; -#endif -init_excp_970(env); -env-dcache_line_size = 128; -env-icache_line_size = 128; -
[Qemu-devel] [PATCH v3 04/24] target-ppc: Copy and split gen_spr_7xx() for 970
This stops using 7xx common SPRs init function and adds separate set of helpers for 970. This does not copy ICTC SPR as neither 970 manual nor PowerISA mention it. This defines 970/book3s PMU SPRs constants as they differs from the ones used for 7XX. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- target-ppc/cpu.h| 20 ++ target-ppc/translate_init.c | 94 - 2 files changed, 113 insertions(+), 1 deletion(-) diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 5313075..0b7ee28 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -1470,15 +1470,21 @@ static inline int cpu_mmu_index (CPUPPCState *env) #define SPR_PERF3 (0x303) #define SPR_RCPU_MI_RBA3 (0x303) #define SPR_MPC_MI_EPN(0x303) +#define SPR_POWER_UPMC1 (0x303) #define SPR_PERF4 (0x304) +#define SPR_POWER_UPMC2 (0x304) #define SPR_PERF5 (0x305) #define SPR_MPC_MI_TWC(0x305) +#define SPR_POWER_UPMC3 (0x305) #define SPR_PERF6 (0x306) #define SPR_MPC_MI_RPN(0x306) +#define SPR_POWER_UPMC4 (0x306) #define SPR_PERF7 (0x307) +#define SPR_POWER_UPMC5 (0x307) #define SPR_PERF8 (0x308) #define SPR_RCPU_L2U_RBA0 (0x308) #define SPR_MPC_MD_CTR(0x308) +#define SPR_POWER_UPMC6 (0x308) #define SPR_PERF9 (0x309) #define SPR_RCPU_L2U_RBA1 (0x309) #define SPR_MPC_MD_CASID (0x309) @@ -1488,29 +1494,43 @@ static inline int cpu_mmu_index (CPUPPCState *env) #define SPR_PERFB (0x30B) #define SPR_RCPU_L2U_RBA3 (0x30B) #define SPR_MPC_MD_EPN(0x30B) +#define SPR_POWER_UMMCR0 (0X30B) #define SPR_PERFC (0x30C) #define SPR_MPC_MD_TWB(0x30C) +#define SPR_POWER_USIAR (0X30C) #define SPR_PERFD (0x30D) #define SPR_MPC_MD_TWC(0x30D) +#define SPR_POWER_USDAR (0X30D) #define SPR_PERFE (0x30E) #define SPR_MPC_MD_RPN(0x30E) +#define SPR_POWER_UMMCR1 (0X30E) #define SPR_PERFF (0x30F) #define SPR_MPC_MD_TW (0x30F) #define SPR_UPERF0(0x310) #define SPR_UPERF1(0x311) #define SPR_UPERF2(0x312) #define SPR_UPERF3(0x313) +#define SPR_POWER_PMC1(0X313) #define SPR_UPERF4(0x314) +#define SPR_POWER_PMC2(0X314) #define SPR_UPERF5(0x315) +#define SPR_POWER_PMC3(0X315) #define SPR_UPERF6(0x316) +#define SPR_POWER_PMC4(0X316) #define SPR_UPERF7(0x317) +#define SPR_POWER_PMC5(0X317) #define SPR_UPERF8(0x318) +#define SPR_POWER_PMC6(0X318) #define SPR_UPERF9(0x319) #define SPR_UPERFA(0x31A) #define SPR_UPERFB(0x31B) +#define SPR_POWER_MMCR0 (0X31B) #define SPR_UPERFC(0x31C) +#define SPR_POWER_SIAR(0X31C) #define SPR_UPERFD(0x31D) +#define SPR_POWER_SDAR(0X31D) #define SPR_UPERFE(0x31E) +#define SPR_POWER_MMCR1 (0X31E) #define SPR_UPERFF(0x31F) #define SPR_RCPU_MI_RA0 (0x320) #define SPR_MPC_MI_DBCAM (0x320) diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 302e61a..46401c7 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -7331,16 +7331,108 @@ static void gen_spr_book3s_altivec(CPUPPCState *env) vscr_init(env, 0x0001); } +static void gen_spr_book3s_dbg(CPUPPCState *env) +{ +spr_register_kvm(env, SPR_DABR, DABR, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, spr_write_generic, + KVM_REG_PPC_DABR, 0x); +} + +static void gen_spr_970_dbg(CPUPPCState *env) +{ +/* Breakpoints */ +spr_register(env, SPR_IABR, IABR, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, spr_write_generic, + 0x); +} + +static void gen_spr_book3s_pmu(CPUPPCState *env) +{ +spr_register(env, SPR_POWER_MMCR0, MMCR0, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, spr_write_generic, + 0x); +spr_register(env, SPR_POWER_MMCR1, MMCR1, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, spr_write_generic, + 0x); +spr_register(env, SPR_POWER_PMC1, PMC1, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, spr_write_generic, + 0x); +spr_register(env, SPR_POWER_PMC2, PMC2, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, spr_write_generic, + 0x); +spr_register(env, SPR_POWER_PMC3, PMC3, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, spr_write_generic, + 0x); +
[Qemu-devel] [PATCH v3 08/24] target-ppc: Add PMC7/8 to 970 class
Compared to PowerISA-compliant CPUs, 970 family has most of them plus PMC7/8 which are only present on 970 but not on POWER5 and later CPUs. Since we are changing SPRs for Book3s/970 families, let's add them too. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- target-ppc/cpu.h| 4 target-ppc/translate_init.c | 21 + 2 files changed, 25 insertions(+) diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index df0b3f1..f8a01ee 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -1488,9 +1488,11 @@ static inline int cpu_mmu_index (CPUPPCState *env) #define SPR_PERF9 (0x309) #define SPR_RCPU_L2U_RBA1 (0x309) #define SPR_MPC_MD_CASID (0x309) +#define SPR_970_UPMC7 (0X309) #define SPR_PERFA (0x30A) #define SPR_RCPU_L2U_RBA2 (0x30A) #define SPR_MPC_MD_AP (0x30A) +#define SPR_970_UPMC8 (0X30A) #define SPR_PERFB (0x30B) #define SPR_RCPU_L2U_RBA3 (0x30B) #define SPR_MPC_MD_EPN(0x30B) @@ -1523,7 +1525,9 @@ static inline int cpu_mmu_index (CPUPPCState *env) #define SPR_UPERF8(0x318) #define SPR_POWER_PMC6(0X318) #define SPR_UPERF9(0x319) +#define SPR_970_PMC7 (0X319) #define SPR_UPERFA(0x31A) +#define SPR_970_PMC8 (0X31A) #define SPR_UPERFB(0x31B) #define SPR_POWER_MMCR0 (0X31B) #define SPR_UPERFC(0x31C) diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index cdb647a..6fc8671 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -7445,6 +7445,26 @@ static void gen_spr_book3s_pmu(CPUPPCState *env) 0x); } +static void gen_spr_970_pmu(CPUPPCState *env) +{ +spr_register(env, SPR_970_PMC7, PMC7, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, spr_write_generic, + 0x); +spr_register(env, SPR_970_PMC8, PMC8, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, spr_write_generic, + 0x); +spr_register(env, SPR_970_UPMC7, UPMC7, + spr_read_ureg, spr_write_ureg, + spr_read_ureg, spr_write_ureg, + 0x); +spr_register(env, SPR_970_UPMC8, UPMC8, + spr_read_ureg, spr_write_ureg, + spr_read_ureg, spr_write_ureg, + 0x); +} + static void gen_spr_book3s_external_control(CPUPPCState *env) { /* External access control */ @@ -7466,6 +7486,7 @@ static void init_proc_970 (CPUPPCState *env) gen_spr_970_hior(env); gen_low_BATs(env); gen_spr_970_ctrl(env); +gen_spr_970_pmu(env); gen_spr_book3s_external_control(env); -- 1.8.4.rc4
[Qemu-devel] [PATCH v3 03/24] target-ppc: Refactor PPC970
This splits one init_proc_970() into a set of small helpers. Later init_proc_970() will be generalized and will call different set of helpers depending on the current CPU class. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- target-ppc/translate_init.c | 97 +++-- 1 file changed, 58 insertions(+), 39 deletions(-) diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 6cd4cd9..302e61a 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -7277,48 +7277,70 @@ static int check_pow_970 (CPUPPCState *env) return 0; } +static void gen_spr_970_hid(CPUPPCState *env) +{ +/* Hardware implementation registers */ +/* XXX : not implemented */ +spr_register(env, SPR_HID0, HID0, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, spr_write_clear, + 0x6000); +spr_register(env, SPR_HID1, HID1, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, spr_write_generic, + 0x); +spr_register(env, SPR_970_HID5, HID5, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, spr_write_generic, + POWERPC970_HID5_INIT); +} + +static void gen_spr_970_hior(CPUPPCState *env) +{ +spr_register(env, SPR_HIOR, SPR_HIOR, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_hior, spr_write_hior, + 0x); +} + +static void gen_spr_970_ctrl(CPUPPCState *env) +{ +spr_register(env, SPR_CTRL, SPR_CTRL, + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, spr_write_generic, + 0x); +spr_register(env, SPR_UCTRL, SPR_UCTRL, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, SPR_NOACCESS, + 0x); +} + +static void gen_spr_book3s_altivec(CPUPPCState *env) +{ +if (!(env-insns_flags PPC_ALTIVEC)) { +return; +} + +spr_register(env, SPR_VRSAVE, SPR_VRSAVE, + spr_read_generic, spr_write_generic, + spr_read_generic, spr_write_generic, + 0x); + +/* Can't find information on what this should be on reset. This + * value is the one used by 74xx processors. */ +vscr_init(env, 0x0001); +} + static void init_proc_970 (CPUPPCState *env) { gen_spr_ne_601(env); gen_spr_7xx(env); -/* Time base */ gen_tbl(env); -/* Hardware implementation registers */ -/* XXX : not implemented */ -spr_register(env, SPR_HID0, HID0, - SPR_NOACCESS, SPR_NOACCESS, - spr_read_generic, spr_write_clear, - 0x6000); -/* XXX : not implemented */ -spr_register(env, SPR_HID1, HID1, - SPR_NOACCESS, SPR_NOACCESS, - spr_read_generic, spr_write_generic, - 0x); -/* XXX : not implemented */ -spr_register(env, SPR_970_HID5, HID5, - SPR_NOACCESS, SPR_NOACCESS, - spr_read_generic, spr_write_generic, - POWERPC970_HID5_INIT); -/* Memory management */ -/* XXX: not correct */ +gen_spr_book3s_altivec(env); +gen_spr_970_hid(env); +gen_spr_970_hior(env); gen_low_BATs(env); -spr_register(env, SPR_HIOR, SPR_HIOR, - SPR_NOACCESS, SPR_NOACCESS, - spr_read_hior, spr_write_hior, - 0x); - -spr_register(env, SPR_CTRL, SPR_CTRL, - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, spr_write_generic, - 0x); -spr_register(env, SPR_UCTRL, SPR_UCTRL, - SPR_NOACCESS, SPR_NOACCESS, - spr_read_generic, SPR_NOACCESS, - 0x); -spr_register(env, SPR_VRSAVE, SPR_VRSAVE, - spr_read_generic, spr_write_generic, - spr_read_generic, spr_write_generic, - 0x); +gen_spr_970_ctrl(env); #if !defined(CONFIG_USER_ONLY) env-slb_nr = 64; #endif @@ -7327,9 +7349,6 @@ static void init_proc_970 (CPUPPCState *env) env-icache_line_size = 128; /* Allocate hardware IRQ controller */ ppc970_irq_init(env); -/* Can't find information on what this should be on reset. This - * value is the one used by 74xx processors. */ -vscr_init(env, 0x0001); } POWERPC_FAMILY(970)(ObjectClass *oc, void *data) -- 1.8.4.rc4
[Qemu-devel] [PATCH v3 15/24] target-ppc: Refactor class init for POWER7/8
This extends init_proc_POWER to support POWER7 and POWER8. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- target-ppc/translate_init.c | 96 - 1 file changed, 59 insertions(+), 37 deletions(-) diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index ca592ed..e39a44d 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -7276,6 +7276,9 @@ POWERPC_FAMILY(e600)(ObjectClass *oc, void *data) enum BOOK3S_CPU_TYPE { BOOK3S_CPU_970, BOOK3S_CPU_POWER5PLUS, +BOOK3S_CPU_POWER6, +BOOK3S_CPU_POWER7, +BOOK3S_CPU_POWER8 }; static int check_pow_970 (CPUPPCState *env) @@ -7582,28 +7585,70 @@ static void init_proc_POWER(CPUPPCState *env, int version) gen_spr_book3s_pmu(env); gen_spr_book3s_dbg(env); -gen_spr_970_hid(env); -gen_spr_970_hior(env); -gen_low_BATs(env); -gen_spr_970_ctrl(env); -gen_spr_970_pmu(env); - +switch (version) { +case BOOK3S_CPU_970: +case BOOK3S_CPU_POWER5PLUS: +gen_spr_970_hid(env); +gen_spr_970_hior(env); +gen_low_BATs(env); +gen_spr_970_ctrl(env); +gen_spr_970_pmu(env); +break; +case BOOK3S_CPU_POWER7: +case BOOK3S_CPU_POWER8: +default: +gen_spr_book3s_ids(env); +gen_spr_book3s_common(env); +gen_spr_amr(env); +gen_spr_book3s_purr(env); +break; +} if (version = BOOK3S_CPU_POWER5PLUS) { gen_spr_book3s_lpar(env); gen_spr_book3s_external_control(env); } else { gen_spr_970_lpar(env); } - -gen_spr_970_dbg(env); +if (version == BOOK3S_CPU_970) { +gen_spr_970_dbg(env); +} +if (version = BOOK3S_CPU_POWER6) { +gen_spr_book3s_pcr(env); +gen_spr_power6_dbg(env); +} +if (version = BOOK3S_CPU_POWER8) { +gen_spr_power8_branch_control(env); +} #if !defined(CONFIG_USER_ONLY) -env-slb_nr = 64; +switch (version) { +case BOOK3S_CPU_970: +case BOOK3S_CPU_POWER5PLUS: +env-slb_nr = 64; +break; +case BOOK3S_CPU_POWER7: +case BOOK3S_CPU_POWER8: +default: +env-slb_nr = 32; +break; +} #endif -init_excp_970(env); +/* Allocate hardware IRQ controller */ +switch (version) { +case BOOK3S_CPU_970: +case BOOK3S_CPU_POWER5PLUS: +init_excp_970(env); +ppc970_irq_init(env); +break; +case BOOK3S_CPU_POWER7: +case BOOK3S_CPU_POWER8: +default: +init_excp_POWER7(env); +ppcPOWER7_irq_init(env); +break; +} + env-dcache_line_size = 128; env-icache_line_size = 128; -/* Allocate hardware IRQ controller */ -ppc970_irq_init(env); } static void init_proc_970(CPUPPCState *env) @@ -7783,27 +7828,7 @@ static Property powerpc_servercpu_properties[] = { static void init_proc_POWER7 (CPUPPCState *env) { -gen_spr_ne_601(env); -gen_spr_7xx(env); -gen_spr_book3s_altivec(env); -gen_tbl(env); -gen_spr_book3s_ids(env); -gen_spr_book3s_purr(env); -gen_spr_book3s_common(env); -gen_spr_book3s_pmu(env); -gen_spr_book3s_lpar(env); -gen_spr_book3s_pcr(env); -gen_spr_power6_dbg(env); -gen_spr_amr(env); -#if !defined(CONFIG_USER_ONLY) -env-slb_nr = 32; -#endif -init_excp_POWER7(env); -env-dcache_line_size = 128; -env-icache_line_size = 128; - -/* Allocate hardware IRQ controller */ -ppcPOWER7_irq_init(env); +init_proc_POWER(env, BOOK3S_CPU_POWER7); } POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data) @@ -7930,10 +7955,7 @@ POWERPC_FAMILY(POWER7P)(ObjectClass *oc, void *data) static void init_proc_POWER8(CPUPPCState *env) { -/* inherit P7 */ -init_proc_POWER7(env); - -gen_spr_power8_branch_control(env); +init_proc_POWER(env, BOOK3S_CPU_POWER8); } POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data) -- 1.8.4.rc4
[Qemu-devel] [PATCH v3 13/24] target-ppc: Enable PMU SPRs migration
This enabled PMU SPRs migration by hooking hypv privileged versions with KVM one reg IDs. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- target-ppc/translate_init.c | 104 ++-- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 21916dd..8e1b465 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -7360,50 +7360,50 @@ static void gen_spr_970_dbg(CPUPPCState *env) static void gen_spr_book3s_pmu(CPUPPCState *env) { -spr_register(env, SPR_POWER_MMCR0, MMCR0, - SPR_NOACCESS, SPR_NOACCESS, - spr_read_generic, spr_write_generic, - 0x); -spr_register(env, SPR_POWER_MMCR1, MMCR1, - SPR_NOACCESS, SPR_NOACCESS, - spr_read_generic, spr_write_generic, - 0x); -spr_register(env, SPR_POWER_MMCRA, MMCRA, - SPR_NOACCESS, SPR_NOACCESS, - spr_read_generic, spr_write_generic, - 0x); -spr_register(env, SPR_POWER_PMC1, PMC1, - SPR_NOACCESS, SPR_NOACCESS, - spr_read_generic, spr_write_generic, - 0x); -spr_register(env, SPR_POWER_PMC2, PMC2, - SPR_NOACCESS, SPR_NOACCESS, - spr_read_generic, spr_write_generic, - 0x); -spr_register(env, SPR_POWER_PMC3, PMC3, - SPR_NOACCESS, SPR_NOACCESS, - spr_read_generic, spr_write_generic, - 0x); -spr_register(env, SPR_POWER_PMC4, PMC4, - SPR_NOACCESS, SPR_NOACCESS, - spr_read_generic, spr_write_generic, - 0x); -spr_register(env, SPR_POWER_PMC5, PMC5, - SPR_NOACCESS, SPR_NOACCESS, - spr_read_generic, spr_write_generic, - 0x); -spr_register(env, SPR_POWER_PMC6, PMC6, - SPR_NOACCESS, SPR_NOACCESS, - spr_read_generic, spr_write_generic, - 0x); -spr_register(env, SPR_POWER_SIAR, SIAR, - SPR_NOACCESS, SPR_NOACCESS, - spr_read_generic, SPR_NOACCESS, - 0x); -spr_register(env, SPR_POWER_SDAR, SDAR, - SPR_NOACCESS, SPR_NOACCESS, - spr_read_generic, SPR_NOACCESS, - 0x); +spr_register_kvm(env, SPR_POWER_MMCR0, MMCR0, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, spr_write_generic, + KVM_REG_PPC_MMCR0, 0x); +spr_register_kvm(env, SPR_POWER_MMCR1, MMCR1, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, spr_write_generic, + KVM_REG_PPC_MMCR1, 0x); +spr_register_kvm(env, SPR_POWER_MMCRA, MMCRA, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, spr_write_generic, + KVM_REG_PPC_MMCRA, 0x); +spr_register_kvm(env, SPR_POWER_PMC1, PMC1, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, spr_write_generic, + KVM_REG_PPC_PMC1, 0x); +spr_register_kvm(env, SPR_POWER_PMC2, PMC2, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, spr_write_generic, + KVM_REG_PPC_PMC2, 0x); +spr_register_kvm(env, SPR_POWER_PMC3, PMC3, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, spr_write_generic, + KVM_REG_PPC_PMC3, 0x); +spr_register_kvm(env, SPR_POWER_PMC4, PMC4, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, spr_write_generic, + KVM_REG_PPC_PMC4, 0x); +spr_register_kvm(env, SPR_POWER_PMC5, PMC5, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, spr_write_generic, + KVM_REG_PPC_PMC5, 0x); +spr_register_kvm(env, SPR_POWER_PMC6, PMC6, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, spr_write_generic, + KVM_REG_PPC_PMC6, 0x); +spr_register_kvm(env, SPR_POWER_SIAR, SIAR, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, SPR_NOACCESS, + KVM_REG_PPC_PMC5, 0x); +spr_register_kvm(env, SPR_POWER_SDAR, SDAR, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, SPR_NOACCESS, + KVM_REG_PPC_PMC6, 0x); spr_register(env, SPR_POWER_UMMCR0, UMMCR0, spr_read_ureg, spr_write_ureg, spr_read_ureg, spr_write_ureg, @@ -7452,14
[Qemu-devel] [PATCH v3 01/24] target-ppc: Rename 7XX/60x/74XX/e600 PMU SPRs
As defined in Linux kernel, PMC*, SIAR, MMCR0/1 have different numbers for 32 and 64 bit POWERPC. We are going to support 64bit versions too so let's rename 32bit ones to avoid confusion. This is a mechanical patch so it does not fix obvious mistake with these registers in POWER7 yet, this will be fixed later. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- target-ppc/cpu.h| 40 +- target-ppc/translate_init.c | 98 ++--- 2 files changed, 69 insertions(+), 69 deletions(-) diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 7b465b8..5313075 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -1566,24 +1566,24 @@ static inline int cpu_mmu_index (CPUPPCState *env) #define SPR_BOOKE_DCDBTRH (0x39D) #define SPR_BOOKE_ICDBTRL (0x39E) #define SPR_BOOKE_ICDBTRH (0x39F) -#define SPR_UMMCR2(0x3A0) -#define SPR_UPMC5 (0x3A1) -#define SPR_UPMC6 (0x3A2) +#define SPR_74XX_UMMCR2 (0x3A0) +#define SPR_7XX_UPMC5 (0x3A1) +#define SPR_7XX_UPMC6 (0x3A2) #define SPR_UBAMR (0x3A7) -#define SPR_UMMCR0(0x3A8) -#define SPR_UPMC1 (0x3A9) -#define SPR_UPMC2 (0x3AA) -#define SPR_USIAR (0x3AB) -#define SPR_UMMCR1(0x3AC) -#define SPR_UPMC3 (0x3AD) -#define SPR_UPMC4 (0x3AE) +#define SPR_7XX_UMMCR0(0x3A8) +#define SPR_7XX_UPMC1 (0x3A9) +#define SPR_7XX_UPMC2 (0x3AA) +#define SPR_7XX_USIAR (0x3AB) +#define SPR_7XX_UMMCR1(0x3AC) +#define SPR_7XX_UPMC3 (0x3AD) +#define SPR_7XX_UPMC4 (0x3AE) #define SPR_USDA (0x3AF) #define SPR_40x_ZPR (0x3B0) #define SPR_BOOKE_MAS7(0x3B0) -#define SPR_MMCR2 (0x3B0) -#define SPR_PMC5 (0x3B1) +#define SPR_74XX_MMCR2(0x3B0) +#define SPR_7XX_PMC5 (0x3B1) #define SPR_40x_PID (0x3B1) -#define SPR_PMC6 (0x3B2) +#define SPR_7XX_PMC6 (0x3B2) #define SPR_440_MMUCR (0x3B2) #define SPR_4xx_CCR0 (0x3B3) #define SPR_BOOKE_EPLC(0x3B3) @@ -1593,19 +1593,19 @@ static inline int cpu_mmu_index (CPUPPCState *env) #define SPR_405_DVC1 (0x3B6) #define SPR_405_DVC2 (0x3B7) #define SPR_BAMR (0x3B7) -#define SPR_MMCR0 (0x3B8) -#define SPR_PMC1 (0x3B9) +#define SPR_7XX_MMCR0 (0x3B8) +#define SPR_7XX_PMC1 (0x3B9) #define SPR_40x_SGR (0x3B9) -#define SPR_PMC2 (0x3BA) +#define SPR_7XX_PMC2 (0x3BA) #define SPR_40x_DCWR (0x3BA) -#define SPR_SIAR (0x3BB) +#define SPR_7XX_SIAR (0x3BB) #define SPR_405_SLER (0x3BB) -#define SPR_MMCR1 (0x3BC) +#define SPR_7XX_MMCR1 (0x3BC) #define SPR_405_SU0R (0x3BC) #define SPR_401_SKR (0x3BC) -#define SPR_PMC3 (0x3BD) +#define SPR_7XX_PMC3 (0x3BD) #define SPR_405_DBCR1 (0x3BD) -#define SPR_PMC4 (0x3BE) +#define SPR_7XX_PMC4 (0x3BE) #define SPR_SDA (0x3BF) #define SPR_403_VTBL (0x3CC) #define SPR_403_VTBU (0x3CD) diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index c13cbba..c1cec07 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -953,72 +953,72 @@ static void gen_spr_7xx (CPUPPCState *env) 0x); /* Performance monitors */ /* XXX : not implemented */ -spr_register(env, SPR_MMCR0, MMCR0, +spr_register(env, SPR_7XX_MMCR0, MMCR0, SPR_NOACCESS, SPR_NOACCESS, spr_read_generic, spr_write_generic, 0x); /* XXX : not implemented */ -spr_register(env, SPR_MMCR1, MMCR1, +spr_register(env, SPR_7XX_MMCR1, MMCR1, SPR_NOACCESS, SPR_NOACCESS, spr_read_generic, spr_write_generic, 0x); /* XXX : not implemented */ -spr_register(env, SPR_PMC1, PMC1, +spr_register(env, SPR_7XX_PMC1, PMC1, SPR_NOACCESS, SPR_NOACCESS, spr_read_generic, spr_write_generic, 0x); /* XXX : not implemented */ -spr_register(env, SPR_PMC2, PMC2, +spr_register(env, SPR_7XX_PMC2, PMC2, SPR_NOACCESS, SPR_NOACCESS, spr_read_generic, spr_write_generic, 0x); /* XXX : not implemented */ -spr_register(env, SPR_PMC3, PMC3, +spr_register(env, SPR_7XX_PMC3, PMC3, SPR_NOACCESS, SPR_NOACCESS, spr_read_generic, spr_write_generic, 0x); /* XXX : not implemented */ -spr_register(env, SPR_PMC4, PMC4, +spr_register(env, SPR_7XX_PMC4, PMC4, SPR_NOACCESS, SPR_NOACCESS,
[Qemu-devel] [PATCH v3 11/24] target-ppc: Remove check_pow_970FX
After merging 970s into one class, check_pow_970() is used for all of them. Since POWER5+ is no different in the matter of supported power modes, let's use the same check_pow() callback for POWER5+ too, Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- target-ppc/translate_init.c | 10 +- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 5556b02..703ad16 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -7582,14 +7582,6 @@ POWERPC_FAMILY(970)(ObjectClass *oc, void *data) pcc-l1_icache_size = 0x1; } -static int check_pow_970FX (CPUPPCState *env) -{ -if (env-spr[SPR_HID0] 0x0060) -return 1; - -return 0; -} - static void init_proc_power5plus(CPUPPCState *env) { init_proc_POWER(env, BOOK3S_CPU_POWER5PLUS); @@ -7603,7 +7595,7 @@ POWERPC_FAMILY(POWER5P)(ObjectClass *oc, void *data) dc-fw_name = PowerPC,POWER5; dc-desc = POWER5+; pcc-init_proc = init_proc_power5plus; -pcc-check_pow = check_pow_970FX; +pcc-check_pow = check_pow_970; pcc-insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | -- 1.8.4.rc4
[Qemu-devel] [PATCH v3 14/24] target-ppc: Move POWER7/8 SPR registration to helpers
This puts SPRs into groups and moves their registration to group helpers. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- target-ppc/translate_init.c | 161 +++- 1 file changed, 85 insertions(+), 76 deletions(-) diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 8e1b465..ca592ed 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -7498,6 +7498,82 @@ static void gen_spr_970_lpar(CPUPPCState *env) 0x); } +static void gen_spr_book3s_ids(CPUPPCState *env) +{ +/* Processor identification */ +spr_register(env, SPR_PIR, PIR, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, spr_write_pir, + 0x); +} + +static void gen_spr_book3s_purr(CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY) +/* PURR SPURR: Hack - treat these as aliases for the TB for now */ +spr_register_kvm(env, SPR_PURR, PURR, + spr_read_purr, SPR_NOACCESS, + spr_read_purr, SPR_NOACCESS, + KVM_REG_PPC_PURR, 0x); +spr_register_kvm(env, SPR_SPURR, SPURR, + spr_read_purr, SPR_NOACCESS, + spr_read_purr, SPR_NOACCESS, + KVM_REG_PPC_SPURR, 0x); +#endif +} + +static void gen_spr_power6_dbg(CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY) +spr_register(env, SPR_CFAR, SPR_CFAR, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_cfar, spr_write_cfar, + 0x); +#endif +} + +static void gen_spr_book3s_common(CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY) +spr_register_kvm(env, SPR_DSCR, SPR_DSCR, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, spr_write_generic, + KVM_REG_PPC_DSCR, 0x); +#endif +spr_register(env, SPR_CTRL, SPR_CTRLT, + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, spr_write_generic, + 0x8080); +spr_register(env, SPR_UCTRL, SPR_CTRLF, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, SPR_NOACCESS, + 0x8080); +spr_register(env, SPR_PPR, PPR, + spr_read_generic, spr_write_generic, + spr_read_generic, spr_write_generic, + 0x); +} + +static void gen_spr_book3s_pcr(CPUPPCState *env) +{ +/* + * Register PCR to report POWERPC_EXCP_PRIV_REG instead of + * POWERPC_EXCP_INVAL_SPR. + */ +spr_register(env, SPR_PCR, PCR, + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + 0x); +} + +static void gen_spr_power8_branch_control(CPUPPCState *env) +{ +spr_register(env, SPR_TAR, TAR, + spr_read_generic, spr_write_generic, + spr_read_generic, spr_write_generic, + 0x); +} + static void init_proc_POWER(CPUPPCState *env, int version) { gen_spr_ne_601(env); @@ -7709,67 +7785,16 @@ static void init_proc_POWER7 (CPUPPCState *env) { gen_spr_ne_601(env); gen_spr_7xx(env); -/* Time base */ +gen_spr_book3s_altivec(env); gen_tbl(env); -/* Processor identification */ -spr_register(env, SPR_PIR, PIR, - SPR_NOACCESS, SPR_NOACCESS, - spr_read_generic, spr_write_pir, - 0x); -#if !defined(CONFIG_USER_ONLY) -/* PURR SPURR: Hack - treat these as aliases for the TB for now */ -spr_register_kvm(env, SPR_PURR, PURR, - spr_read_purr, SPR_NOACCESS, - spr_read_purr, SPR_NOACCESS, - KVM_REG_PPC_PURR, 0x); -spr_register_kvm(env, SPR_SPURR, SPURR, - spr_read_purr, SPR_NOACCESS, - spr_read_purr, SPR_NOACCESS, - KVM_REG_PPC_SPURR, 0x); -spr_register(env, SPR_CFAR, SPR_CFAR, - SPR_NOACCESS, SPR_NOACCESS, - spr_read_cfar, spr_write_cfar, - 0x); -spr_register_kvm(env, SPR_DSCR, SPR_DSCR, - SPR_NOACCESS, SPR_NOACCESS, - spr_read_generic, spr_write_generic, - KVM_REG_PPC_DSCR, 0x); -spr_register_kvm(env, SPR_POWER_MMCRA, SPR_MMCRA, - SPR_NOACCESS, SPR_NOACCESS, - spr_read_generic, spr_write_generic, - KVM_REG_PPC_MMCRA, 0x); -spr_register_kvm(env, SPR_7XX_PMC5, SPR_7XX_PMC5, - SPR_NOACCESS, SPR_NOACCESS, - spr_read_generic, spr_write_generic, - KVM_REG_PPC_PMC5, 0x); -spr_register_kvm(env, SPR_7XX_PMC6, SPR_7XX_PMC6, - SPR_NOACCESS, SPR_NOACCESS, -
[Qemu-devel] [PATCH v3 19/24] target-ppc: Add POWER8's TM SPRs
This adds TM (Transactional Memory) SPRs. Since TEXASRU is an upper half of TEXASR, special handling is needed here. This adds two helpers: spr_read_prev_upper32()/spr_write_prev_upper32(). They read/write upper half of a previous 64bit SPR. Since TEXASR and TEXASRU have consequent numbers, that works. These will be used later for other SPRs as well. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- target-ppc/cpu.h| 4 target-ppc/translate_init.c | 45 + 2 files changed, 49 insertions(+) diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index c2a84fd..778b7d7 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -1260,6 +1260,10 @@ static inline int cpu_mmu_index (CPUPPCState *env) #define SPR_MPC_EIE (0x050) #define SPR_MPC_EID (0x051) #define SPR_MPC_NRI (0x052) +#define SPR_TFHAR (0x080) +#define SPR_TFIAR (0x081) +#define SPR_TEXASR(0x082) +#define SPR_TEXASRU (0x083) #define SPR_UCTRL (0x088) #define SPR_MPC_CMPA (0x090) #define SPR_MPC_CMPB (0x091) diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 0682739..9dda60e 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -117,6 +117,30 @@ static void spr_access_nop(void *opaque, int sprn, int gprn) #endif +static void spr_read_prev_upper32(void *opaque, int gprn, int sprn) +{ +TCGv_i32 spr32 = tcg_temp_new_i32(); +TCGv spr = tcg_temp_new(); + +gen_load_spr(spr, sprn - 1); +tcg_gen_trunc_shr_i64_i32(spr32, spr, 32); +tcg_gen_ext32u_tl(cpu_gpr[gprn], spr32); + +tcg_temp_free(spr); +tcg_temp_free(spr32); +} + +static void spr_write_prev_upper32(void *opaque, int sprn, int gprn) +{ +TCGv spr = tcg_temp_new(); + +gen_load_spr(spr, sprn - 1); +tcg_gen_deposit_i64(spr, spr, cpu_gpr[gprn], 32, 32); +gen_store_spr(sprn - 1, spr); + +tcg_temp_free(spr); +} + /* SPR common to all PowerPC */ /* XER */ static void spr_read_xer (void *opaque, int gprn, int sprn) @@ -7598,6 +7622,26 @@ static void gen_spr_power8_branch_control(CPUPPCState *env) 0x); } +static void gen_spr_power8_tm(CPUPPCState *env) +{ +spr_register_kvm(env, SPR_TFHAR, TFHAR, + spr_read_generic, spr_write_generic, + spr_read_generic, spr_write_generic, + KVM_REG_PPC_TFHAR, 0x); +spr_register_kvm(env, SPR_TFIAR, TFIAR, + spr_read_generic, spr_write_generic, + spr_read_generic, spr_write_generic, + KVM_REG_PPC_TFIAR, 0x); +spr_register_kvm(env, SPR_TEXASR, TEXASR, + spr_read_generic, spr_write_generic, + spr_read_generic, spr_write_generic, + KVM_REG_PPC_TEXASR, 0x); +spr_register(env, SPR_TEXASRU, TEXASRU, + spr_read_prev_upper32, spr_write_prev_upper32, + spr_read_prev_upper32, spr_write_prev_upper32, + 0x); +} + static void gen_spr_power8_common(CPUPPCState *env) { spr_register_kvm(env, SPR_FSCR, FSCR, @@ -7647,6 +7691,7 @@ static void init_proc_POWER(CPUPPCState *env, int version) } if (version = BOOK3S_CPU_POWER8) { gen_spr_power8_branch_control(env); +gen_spr_power8_tm(env); gen_spr_power8_pmu(env); gen_spr_power8_common(env); } -- 1.8.4.rc4
[Qemu-devel] [PATCH v3 12/24] target-ppc: Enable Hypervisor State bit in MSR for POWER5+
PowerISA 2.03 defines the HV bit. Since POWER5+ is 2.03-compliant, enable the bit in msr_mask. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- target-ppc/translate_init.c | 1 + 1 file changed, 1 insertion(+) diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 703ad16..21916dd 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -7606,6 +7606,7 @@ POWERPC_FAMILY(POWER5P)(ObjectClass *oc, void *data) PPC_64B | PPC_SEGMENT_64B | PPC_SLBI; pcc-msr_mask = (1ull MSR_SF) | +(1ull MSR_SHV) | (1ull MSR_VR) | (1ull MSR_POW) | (1ull MSR_EE) | -- 1.8.4.rc4
[Qemu-devel] [PATCH v3 22/24] KVM: target-ppc: Enable transactional state migration
This adds migration support for registers saved before transaction started. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- target-ppc/cpu.h | 19 +++ target-ppc/kvm.c | 38 ++ target-ppc/machine.c | 35 +++ 3 files changed, 92 insertions(+) diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 3e8b126..497de25 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -427,6 +427,9 @@ struct ppc_slb_t { #define MSR_TAG 62 /* Tag-active mode (POWERx ?)*/ #define MSR_ISF 61 /* Sixty-four-bit interrupt mode on 630 */ #define MSR_SHV 60 /* hypervisor state hflags */ +#define MSR_TS0 34 /* Transactional state, 2 bits (Book3s) */ +#define MSR_TS1 33 +#define MSR_TM 32 /* Transactional Memory Available (Book3s) */ #define MSR_CM 31 /* Computation mode for BookE hflags */ #define MSR_ICM 30 /* Interrupt computation mode for BookE */ #define MSR_THV 29 /* hypervisor state for 32 bits PowerPC hflags */ @@ -503,6 +506,8 @@ struct ppc_slb_t { #define msr_pmm ((env-msr MSR_PMM) 1) #define msr_ri ((env-msr MSR_RI)1) #define msr_le ((env-msr MSR_LE)1) +#define msr_ts ((env-msr MSR_TS1) 3) + /* Hypervisor bit is more specific */ #if defined(TARGET_PPC64) #define MSR_HVB (1ULL MSR_SHV) @@ -1086,6 +1091,20 @@ struct CPUPPCState { */ uint8_t fit_period[4]; uint8_t wdt_period[4]; + +/* Transactional memory state */ +target_ulong tm_gpr[32]; +ppc_avr_t tm_vsr[64]; +uint64_t tm_cr; +uint64_t tm_lr; +uint64_t tm_ctr; +uint64_t tm_fpscr; +uint64_t tm_amr; +uint64_t tm_ppr; +uint64_t tm_vrsave; +uint32_t tm_vscr; +uint64_t tm_dscr; +uint64_t tm_tar; }; #define SET_FIT_PERIOD(a_, b_, c_, d_) \ diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index 05952d0..efd88b1 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -861,6 +861,25 @@ int kvm_arch_put_registers(CPUState *cs, int level) } #ifdef TARGET_PPC64 +if (msr_ts) { +for (i = 0; i ARRAY_SIZE(env-tm_gpr); i++) { +kvm_set_one_reg(cs, KVM_REG_PPC_TM_GPR(i), env-tm_gpr[i]); +} +for (i = 0; i ARRAY_SIZE(env-tm_vsr); i++) { +kvm_set_one_reg(cs, KVM_REG_PPC_TM_VSR(i), env-tm_vsr[i]); +} +kvm_set_one_reg(cs, KVM_REG_PPC_TM_CR, env-tm_cr); +kvm_set_one_reg(cs, KVM_REG_PPC_TM_LR, env-tm_lr); +kvm_set_one_reg(cs, KVM_REG_PPC_TM_CTR, env-tm_ctr); +kvm_set_one_reg(cs, KVM_REG_PPC_TM_FPSCR, env-tm_fpscr); +kvm_set_one_reg(cs, KVM_REG_PPC_TM_AMR, env-tm_amr); +kvm_set_one_reg(cs, KVM_REG_PPC_TM_PPR, env-tm_ppr); +kvm_set_one_reg(cs, KVM_REG_PPC_TM_VRSAVE, env-tm_vrsave); +kvm_set_one_reg(cs, KVM_REG_PPC_TM_VSCR, env-tm_vscr); +kvm_set_one_reg(cs, KVM_REG_PPC_TM_DSCR, env-tm_dscr); +kvm_set_one_reg(cs, KVM_REG_PPC_TM_TAR, env-tm_tar); +} + if (cap_papr) { if (kvm_put_vpa(cs) 0) { DPRINTF(Warning: Unable to set VPA information to KVM\n); @@ -1087,6 +1106,25 @@ int kvm_arch_get_registers(CPUState *cs) } #ifdef TARGET_PPC64 +if (msr_ts) { +for (i = 0; i ARRAY_SIZE(env-tm_gpr); i++) { +kvm_get_one_reg(cs, KVM_REG_PPC_TM_GPR(i), env-tm_gpr[i]); +} +for (i = 0; i ARRAY_SIZE(env-tm_vsr); i++) { +kvm_get_one_reg(cs, KVM_REG_PPC_TM_VSR(i), env-tm_vsr[i]); +} +kvm_get_one_reg(cs, KVM_REG_PPC_TM_CR, env-tm_cr); +kvm_get_one_reg(cs, KVM_REG_PPC_TM_LR, env-tm_lr); +kvm_get_one_reg(cs, KVM_REG_PPC_TM_CTR, env-tm_ctr); +kvm_get_one_reg(cs, KVM_REG_PPC_TM_FPSCR, env-tm_fpscr); +kvm_get_one_reg(cs, KVM_REG_PPC_TM_AMR, env-tm_amr); +kvm_get_one_reg(cs, KVM_REG_PPC_TM_PPR, env-tm_ppr); +kvm_get_one_reg(cs, KVM_REG_PPC_TM_VRSAVE, env-tm_vrsave); +kvm_get_one_reg(cs, KVM_REG_PPC_TM_VSCR, env-tm_vscr); +kvm_get_one_reg(cs, KVM_REG_PPC_TM_DSCR, env-tm_dscr); +kvm_get_one_reg(cs, KVM_REG_PPC_TM_TAR, env-tm_tar); +} + if (cap_papr) { if (kvm_get_vpa(cs) 0) { DPRINTF(Warning: Unable to get VPA information from KVM\n); diff --git a/target-ppc/machine.c b/target-ppc/machine.c index df7cfc5..9c0e697 100644 --- a/target-ppc/machine.c +++ b/target-ppc/machine.c @@ -252,6 +252,38 @@ static const VMStateDescription vmstate_vsx = { }, }; +#ifdef TARGET_PPC64 +/* Transactional memory state */ +static bool tm_needed(void *opaque) +{ +PowerPCCPU *cpu = opaque; +CPUPPCState *env = cpu-env; +return
[Qemu-devel] [PATCH v3 24/24] spapr_hcall: Add address-translation-mode-on-interrupt resource in H_SET_MODE
This adds handling of the RESOURCE_ADDR_TRANS_MODE resource from the H_SET_MODE, for POWER8 (PowerISA 2.07) only. This defines AIL flags for LPCR special register. This changes @excp_prefix according to the mode, takes effect in TCG. This turns support of a new capability PPC2_ISA207S flag for TCG. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- hw/ppc/spapr_hcall.c | 47 +++ include/hw/ppc/spapr.h | 5 + target-ppc/cpu.h | 4 +++- target-ppc/excp_helper.c | 7 +-- 4 files changed, 60 insertions(+), 3 deletions(-) diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index cff3b0f..a2941f4 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -743,6 +743,49 @@ static target_ulong h_set_mode_resouce_le(PowerPCCPU *cpu, return H_UNSUPPORTED_FLAG; } +static target_ulong h_set_mode_resouce_addr_trans_mode(PowerPCCPU *cpu, + target_ulong mflags, + target_ulong value1, + target_ulong value2) +{ +CPUState *cs; +PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); +target_ulong prefix; + +if (!(pcc-insns_flags2 PPC2_ISA207S)) { +return H_P2; +} +if (value1) { +return H_P3; +} +if (value2) { +return H_P4; +} + +switch (mflags) { +case H_SET_MODE_ADDR_TRANS_NONE: +prefix = 0; +break; +case H_SET_MODE_ADDR_TRANS_0001_8000: +prefix = 0x18000; +break; +case H_SET_MODE_ADDR_TRANS_C000___4000: +prefix = 0xC0004000; +break; +default: +return H_UNSUPPORTED_FLAG; +} + +CPU_FOREACH(cs) { +CPUPPCState *env = POWERPC_CPU(cpu)-env; + +set_spr(cs, SPR_LPCR, mflags LPCR_AIL_SH, LPCR_AIL); +env-excp_prefix = prefix; +} + +return H_SUCCESS; +} + static target_ulong h_set_mode(PowerPCCPU *cpu, sPAPREnvironment *spapr, target_ulong opcode, target_ulong *args) { @@ -753,6 +796,10 @@ static target_ulong h_set_mode(PowerPCCPU *cpu, sPAPREnvironment *spapr, case H_SET_MODE_RESOURCE_LE: ret = h_set_mode_resouce_le(cpu, args[0], args[2], args[3]); break; +case H_SET_MODE_RESOURCE_ADDR_TRANS_MODE: +ret = h_set_mode_resouce_addr_trans_mode(cpu, args[0], + args[2], args[3]); +break; } return ret; diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index b8c2ba4..0d45954 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -164,6 +164,11 @@ typedef struct sPAPREnvironment { #define H_SET_MODE_ENDIAN_BIG0 #define H_SET_MODE_ENDIAN_LITTLE 1 +/* Flags for H_SET_MODE_RESOURCE_ADDR_TRANS_MODE */ +#define H_SET_MODE_ADDR_TRANS_NONE 0 +#define H_SET_MODE_ADDR_TRANS_0001_8000 2 +#define H_SET_MODE_ADDR_TRANS_C000___4000 3 + /* VASI States */ #define H_VASI_INVALID0 #define H_VASI_ENABLED1 diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 497de25..eeb82e9 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -467,6 +467,8 @@ struct ppc_slb_t { #define MSR_LE 0 /* Little-endian mode 1 hflags */ #define LPCR_ILE (1 (63-38)) +#define LPCR_AIL 0x0180 /* Alternate interrupt location */ +#define LPCR_AIL_SH (63-40) #define msr_sf ((env-msr MSR_SF)1) #define msr_isf ((env-msr MSR_ISF) 1) @@ -1998,7 +2000,7 @@ enum { PPC2_DIVE_ISA206 | PPC2_ATOMIC_ISA206 | \ PPC2_FP_CVT_ISA206 | PPC2_FP_TST_ISA206 | \ PPC2_BCTAR_ISA207 | PPC2_LSQ_ISA207 | \ -PPC2_ALTIVEC_207) +PPC2_ALTIVEC_207 | PPC2_ISA207S) }; /*/ diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c index fd89d99..b39bf1b 100644 --- a/target-ppc/excp_helper.c +++ b/target-ppc/excp_helper.c @@ -619,8 +619,11 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) if (asrr1 != -1) { env-spr[asrr1] = env-spr[srr1]; } -/* If we disactivated any translation, flush TLBs */ -if (msr ((1 MSR_IR) | (1 MSR_DR))) { + +if (env-spr[SPR_LPCR] LPCR_AIL) { +new_msr |= (1 MSR_IR) | (1 MSR_DR); +} else if (msr ((1 MSR_IR) | (1 MSR_DR))) { +/* If we disactivated any translation, flush TLBs */ tlb_flush(cs, 1); } -- 1.8.4.rc4
[Qemu-devel] [PATCH v3 00/24] book3s powerpc classes rework
Started as POWER7/8 SPRs patchset, this became a rework of book3s/970 CPU classes initialization. The aim is to boot little endian guests in TCG mode with -cpu POWER8 (ironically, POWER8 emulation still fails, debugging it now but most of the set is still valid). Please comment. Alexey Kardashevskiy (24): target-ppc: Rename 7XX/60x/74XX/e600 PMU SPRs target-ppc: Merge 970FX and 970MP into a single 970 class target-ppc: Refactor PPC970 target-ppc: Copy and split gen_spr_7xx() for 970 target-ppc: Add POWER prefix to MMCRA PMU registers target-ppc: Enable writes to user-privileged PMU registers target-ppc: Add PMC5/6, SDAR and MMCRA to 970 family target-ppc: Add PMC7/8 to 970 class target-ppc: Add HID4 SPR for PPC970 target-ppc: Introduce and reuse generalized init_proc_POWER() target-ppc: Remove check_pow_970FX target-ppc: Enable Hypervisor State bit in MSR for POWER5+ target-ppc: Enable PMU SPRs migration target-ppc: Move POWER7/8 SPR registration to helpers target-ppc: Refactor class init for POWER7/8 target-ppc: Add POWER7's TIR SPR target-ppc: Add POWER8's MMCR2/MMCRS SPRs target-ppc: Add POWER8's FSCR SPR target-ppc: Add POWER8's TM SPRs target-ppc: Add more POWER8's branch control SPRs target-ppc: Enable PPR and VRSAVE SPRs migration KVM: target-ppc: Enable transactional state migration spapr_hcall: Split h_set_mode() spapr_hcall: Add address-translation-mode-on-interrupt resource in H_SET_MODE hw/ppc/spapr_hcall.c| 114 +++-- include/hw/ppc/spapr.h | 5 + target-ppc/cpu-models.c | 14 +- target-ppc/cpu.h| 112 - target-ppc/excp_helper.c| 12 +- target-ppc/kvm.c| 38 ++ target-ppc/machine.c| 35 ++ target-ppc/translate_init.c | 997 +--- 8 files changed, 839 insertions(+), 488 deletions(-) -- 1.8.4.rc4
[Qemu-devel] [PATCH v3 16/24] target-ppc: Add POWER7's TIR SPR
This adds TIR (Thread Identification Register) SPR first defined in PowerISA 2.05. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- target-ppc/cpu.h| 1 + target-ppc/translate_init.c | 5 + 2 files changed, 6 insertions(+) diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 6f2baef..14cbf8e 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -1374,6 +1374,7 @@ static inline int cpu_mmu_index (CPUPPCState *env) #define SPR_BOOKE_GIVOR8 (0x1BB) #define SPR_BOOKE_GIVOR13 (0x1BC) #define SPR_BOOKE_GIVOR14 (0x1BD) +#define SPR_TIR (0x1BE) #define SPR_BOOKE_SPEFSCR (0x200) #define SPR_Exxx_BBEAR(0x201) #define SPR_Exxx_BBTAR(0x202) diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index e39a44d..83ef256 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -7508,6 +7508,11 @@ static void gen_spr_book3s_ids(CPUPPCState *env) SPR_NOACCESS, SPR_NOACCESS, spr_read_generic, spr_write_pir, 0x); + +spr_register(env, SPR_TIR, TIR, + spr_read_generic, SPR_NOACCESS, + spr_read_generic, SPR_NOACCESS, + 0x); } static void gen_spr_book3s_purr(CPUPPCState *env) -- 1.8.4.rc4
[Qemu-devel] [PATCH v3 23/24] spapr_hcall: Split h_set_mode()
This moves H_SET_MODE_RESOURCE_LE handler to a separate function as there are other resources coming and this is going to become ugly. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- Changes: v2: * s/becode/become/ in commit log --- hw/ppc/spapr_hcall.c | 67 +++- 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index a7460ab..cff3b0f 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -712,46 +712,49 @@ static target_ulong h_logical_dcbf(PowerPCCPU *cpu, sPAPREnvironment *spapr, return H_SUCCESS; } +static target_ulong h_set_mode_resouce_le(PowerPCCPU *cpu, + target_ulong mflags, + target_ulong value1, + target_ulong value2) +{ +CPUState *cs; + +if (value1) { +return H_P3; +} +if (value2) { +return H_P4; +} + +switch (mflags) { +case H_SET_MODE_ENDIAN_BIG: +CPU_FOREACH(cs) { +set_spr(cs, SPR_LPCR, 0, LPCR_ILE); +} +return H_SUCCESS; + +case H_SET_MODE_ENDIAN_LITTLE: +CPU_FOREACH(cs) { +set_spr(cs, SPR_LPCR, LPCR_ILE, LPCR_ILE); +} +return H_SUCCESS; +} + +return H_UNSUPPORTED_FLAG; +} + static target_ulong h_set_mode(PowerPCCPU *cpu, sPAPREnvironment *spapr, target_ulong opcode, target_ulong *args) { -CPUState *cs; -target_ulong mflags = args[0]; target_ulong resource = args[1]; -target_ulong value1 = args[2]; -target_ulong value2 = args[3]; target_ulong ret = H_P2; -if (resource == H_SET_MODE_RESOURCE_LE) { -if (value1) { -ret = H_P3; -goto out; -} -if (value2) { -ret = H_P4; -goto out; -} -switch (mflags) { -case H_SET_MODE_ENDIAN_BIG: -CPU_FOREACH(cs) { -set_spr(cs, SPR_LPCR, 0, LPCR_ILE); -} -ret = H_SUCCESS; -break; - -case H_SET_MODE_ENDIAN_LITTLE: -CPU_FOREACH(cs) { -set_spr(cs, SPR_LPCR, LPCR_ILE, LPCR_ILE); -} -ret = H_SUCCESS; -break; - -default: -ret = H_UNSUPPORTED_FLAG; -} +switch (resource) { +case H_SET_MODE_RESOURCE_LE: +ret = h_set_mode_resouce_le(cpu, args[0], args[2], args[3]); +break; } -out: return ret; } -- 1.8.4.rc4
[Qemu-devel] [PATCH v3 21/24] target-ppc: Enable PPR and VRSAVE SPRs migration
This hooks SPR with theit KVM set_one_reg counterparts which enables their migration. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- target-ppc/translate_init.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index f0be5b1..39cc930 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -7359,10 +7359,10 @@ static void gen_spr_book3s_altivec(CPUPPCState *env) return; } -spr_register(env, SPR_VRSAVE, SPR_VRSAVE, - spr_read_generic, spr_write_generic, - spr_read_generic, spr_write_generic, - 0x); +spr_register_kvm(env, SPR_VRSAVE, VRSAVE, + spr_read_generic, spr_write_generic, + spr_read_generic, spr_write_generic, + KVM_REG_PPC_VRSAVE, 0x); /* Can't find information on what this should be on reset. This * value is the one used by 74xx processors. */ @@ -7597,10 +7597,10 @@ static void gen_spr_book3s_common(CPUPPCState *env) SPR_NOACCESS, SPR_NOACCESS, spr_read_generic, SPR_NOACCESS, 0x8080); -spr_register(env, SPR_PPR, PPR, - spr_read_generic, spr_write_generic, - spr_read_generic, spr_write_generic, - 0x); +spr_register_kvm(env, SPR_PPR, PPR, + spr_read_generic, spr_write_generic, + spr_read_generic, spr_write_generic, + KVM_REG_PPC_PPR, 0x); } static void gen_spr_book3s_pcr(CPUPPCState *env) -- 1.8.4.rc4
[Qemu-devel] [PATCH v3 20/24] target-ppc: Add more POWER8's branch control SPRs
POWER8 supports Event-Based Branch Facility (EBB) and Target Address Register (TAR). They are controlled via set of SPRs access to which should generate an Facility Unavailable interrupt if the facilities are not enabled in FSCR for problem state. This adds EBB and TAR SPRs. This adds check_spr_bit() helper to read and test SPR, it is used for FSCR. This defines two bits in FSCR - per EEB and TAR facilities. This defines new exception type - POWERPC_EXCP_FU - facility unavailable. This registers the interrupt vector for it at 0xF60 as PowerISA defines. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- target-ppc/cpu.h| 12 +++ target-ppc/excp_helper.c| 5 +++ target-ppc/translate_init.c | 87 + 3 files changed, 104 insertions(+) diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 778b7d7..3e8b126 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -238,6 +238,7 @@ enum { POWERPC_EXCP_DTLBE= 93, /* Data TLB error*/ /* VSX Unavailable (Power ISA 2.06 and later)*/ POWERPC_EXCP_VSXU = 94, /* VSX Unavailable */ +POWERPC_EXCP_FU = 95, /* Facility Unavailable */ /* EOL */ POWERPC_EXCP_NB = 96, /* QEMU exceptions: used internally during code translation */ @@ -516,6 +517,10 @@ struct ppc_slb_t { #endif #endif +/* Facility Status and Control (FSCR) bits */ +#define FSCR_EBB(63 - 56) /* Event-Based Branch Facility */ +#define FSCR_TAR(63 - 55) /* Target Address Register */ + /* Exception state register bits definition */ #define ESR_PIL (1 (63 - 36)) /* Illegal Instruction*/ #define ESR_PPR (1 (63 - 37)) /* Privileged Instruction */ @@ -1547,11 +1552,18 @@ static inline int cpu_mmu_index (CPUPPCState *env) #define SPR_UPERFF(0x31F) #define SPR_RCPU_MI_RA0 (0x320) #define SPR_MPC_MI_DBCAM (0x320) +#define SPR_BESCRS(0x320) #define SPR_RCPU_MI_RA1 (0x321) #define SPR_MPC_MI_DBRAM0 (0x321) +#define SPR_BESCRSU (0x321) #define SPR_RCPU_MI_RA2 (0x322) #define SPR_MPC_MI_DBRAM1 (0x322) +#define SPR_BESCRR(0x322) #define SPR_RCPU_MI_RA3 (0x323) +#define SPR_BESCRRU (0x323) +#define SPR_EBBHR (0x324) +#define SPR_EBBRR (0x325) +#define SPR_BESCR (0x326) #define SPR_RCPU_L2U_RA0 (0x328) #define SPR_MPC_MD_DBCAM (0x328) #define SPR_RCPU_L2U_RA1 (0x329) diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c index 4fa297d..fd89d99 100644 --- a/target-ppc/excp_helper.c +++ b/target-ppc/excp_helper.c @@ -398,6 +398,11 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) new_msr |= (target_ulong)MSR_HVB; } goto store_current; +case POWERPC_EXCP_FU: /* Facility unavailable exception */ +if (lpes1 == 0) { +new_msr |= (target_ulong)MSR_HVB; +} +goto store_current; case POWERPC_EXCP_PIT: /* Programmable interval timer interrupt*/ LOG_EXCP(PIT exception\n); goto store_next; diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 9dda60e..f0be5b1 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -3104,6 +3104,7 @@ static void init_excp_POWER7 (CPUPPCState *env) env-excp_vectors[POWERPC_EXCP_PERFM]= 0x0F00; env-excp_vectors[POWERPC_EXCP_VPU] = 0x0F20; env-excp_vectors[POWERPC_EXCP_VSXU] = 0x0F40; +env-excp_vectors[POWERPC_EXCP_FU] = 0x0F60; env-excp_vectors[POWERPC_EXCP_IABR] = 0x1300; env-excp_vectors[POWERPC_EXCP_MAINT]= 0x1600; env-excp_vectors[POWERPC_EXCP_VPUA] = 0x1700; @@ -7614,12 +7615,98 @@ static void gen_spr_book3s_pcr(CPUPPCState *env) 0x); } +static bool check_spr_bit(void *ctx, int sprn, int bit) +{ +TCGv t = tcg_temp_new(); +bool ret = true; + +gen_load_spr(t, sprn); +if (!(GET_TCGV_I64(t) (1 bit))) { +gen_inval_exception(ctx, POWERPC_EXCP_FU); +ret = false; +} + +tcg_temp_free(t); + +return ret; +} + +static void spr_read_ebb_generic(void *opaque, int gprn, int sprn) +{ +if (check_spr_bit(opaque, SPR_FSCR, FSCR_EBB)) { +spr_read_generic(opaque, sprn, gprn); +} +} + +static void spr_write_ebb_generic(void *opaque, int sprn, int gprn) +{ +if (check_spr_bit(opaque, SPR_FSCR, FSCR_EBB)) { +spr_write_generic(opaque, sprn, gprn); +} +} + +static void spr_read_ebb_upper32(void *opaque, int gprn, int sprn) +{ +if (check_spr_bit(opaque, SPR_FSCR, FSCR_EBB)) { +
[Qemu-devel] [PATCH v3 17/24] target-ppc: Add POWER8's MMCR2/MMCRS SPRs
This adds POWER8 specific PMU MMCR2/MMCRS SPRs. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- target-ppc/cpu.h| 3 +++ target-ppc/translate_init.c | 17 + 2 files changed, 20 insertions(+) diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 14cbf8e..d0238e6 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -1464,6 +1464,7 @@ static inline int cpu_mmu_index (CPUPPCState *env) #define SPR_MPC_MI_CTR(0x300) #define SPR_PERF1 (0x301) #define SPR_RCPU_MI_RBA1 (0x301) +#define SPR_POWER_UMMCR2 (0x301) #define SPR_PERF2 (0x302) #define SPR_RCPU_MI_RBA2 (0x302) #define SPR_MPC_MI_AP (0x302) @@ -1511,6 +1512,7 @@ static inline int cpu_mmu_index (CPUPPCState *env) #define SPR_MPC_MD_TW (0x30F) #define SPR_UPERF0(0x310) #define SPR_UPERF1(0x311) +#define SPR_POWER_MMCR2 (0x311) #define SPR_UPERF2(0x312) #define SPR_POWER_MMCRA (0X312) #define SPR_UPERF3(0x313) @@ -1563,6 +1565,7 @@ static inline int cpu_mmu_index (CPUPPCState *env) #define SPR_440_ITV3 (0x377) #define SPR_440_CCR1 (0x378) #define SPR_DCRIPR(0x37B) +#define SPR_POWER_MMCRS (0x37E) #define SPR_PPR (0x380) #define SPR_750_GQR0 (0x390) #define SPR_440_DNV0 (0x390) diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 83ef256..6bcb41c 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -7540,6 +7540,22 @@ static void gen_spr_power6_dbg(CPUPPCState *env) #endif } +static void gen_spr_power8_pmu(CPUPPCState *env) +{ +spr_register_kvm(env, SPR_POWER_MMCR2, MMCR2, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, spr_write_generic, + KVM_REG_PPC_MMCR2, 0x); +spr_register(env, SPR_POWER_UMMCR2, UMMCR2, + spr_read_ureg, spr_write_ureg, + spr_read_ureg, spr_write_ureg, + 0x); +spr_register_kvm(env, SPR_POWER_MMCRS, MMCRS, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, spr_write_generic, + KVM_REG_PPC_MMCRS, 0x); +} + static void gen_spr_book3s_common(CPUPPCState *env) { #if !defined(CONFIG_USER_ONLY) @@ -7623,6 +7639,7 @@ static void init_proc_POWER(CPUPPCState *env, int version) } if (version = BOOK3S_CPU_POWER8) { gen_spr_power8_branch_control(env); +gen_spr_power8_pmu(env); } #if !defined(CONFIG_USER_ONLY) switch (version) { -- 1.8.4.rc4
[Qemu-devel] [PATCH v3 06/24] target-ppc: Enable writes to user-privileged PMU registers
This adds spr_write_ureg() helper and uses it for UPMCx and MMCR0 SPRs. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- target-ppc/translate_init.c | 25 +++-- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 88acf70..595fd3f 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -175,6 +175,11 @@ static void spr_read_ureg (void *opaque, int gprn, int sprn) gen_load_spr(cpu_gpr[gprn], sprn + 0x10); } +static void spr_write_ureg(void *opaque, int gprn, int sprn) +{ +gen_store_spr(sprn + 0x10, cpu_gpr[gprn]); +} + /* SPR common to all non-embedded PowerPC */ /* DECR */ #if !defined(CONFIG_USER_ONLY) @@ -7379,28 +7384,28 @@ static void gen_spr_book3s_pmu(CPUPPCState *env) spr_read_generic, SPR_NOACCESS, 0x); spr_register(env, SPR_POWER_UMMCR0, UMMCR0, - spr_read_ureg, SPR_NOACCESS, - spr_read_ureg, SPR_NOACCESS, + spr_read_ureg, spr_write_ureg, + spr_read_ureg, spr_write_ureg, 0x); spr_register(env, SPR_POWER_UMMCR1, UMMCR1, spr_read_ureg, SPR_NOACCESS, spr_read_ureg, SPR_NOACCESS, 0x); spr_register(env, SPR_POWER_UPMC1, UPMC1, - spr_read_ureg, SPR_NOACCESS, - spr_read_ureg, SPR_NOACCESS, + spr_read_ureg, spr_write_ureg, + spr_read_ureg, spr_write_ureg, 0x); spr_register(env, SPR_POWER_UPMC2, UPMC2, - spr_read_ureg, SPR_NOACCESS, - spr_read_ureg, SPR_NOACCESS, + spr_read_ureg, spr_write_ureg, + spr_read_ureg, spr_write_ureg, 0x); spr_register(env, SPR_POWER_UPMC3, UPMC3, - spr_read_ureg, SPR_NOACCESS, - spr_read_ureg, SPR_NOACCESS, + spr_read_ureg, spr_write_ureg, + spr_read_ureg, spr_write_ureg, 0x); spr_register(env, SPR_POWER_UPMC4, UPMC4, - spr_read_ureg, SPR_NOACCESS, - spr_read_ureg, SPR_NOACCESS, + spr_read_ureg, spr_write_ureg, + spr_read_ureg, spr_write_ureg, 0x); spr_register(env, SPR_POWER_USIAR, USIAR, spr_read_ureg, SPR_NOACCESS, -- 1.8.4.rc4
[Qemu-devel] [PATCH v3 02/24] target-ppc: Merge 970FX and 970MP into a single 970 class
The differences between classes were: 1. SLB size, was 32 for 970 and 64 for others, should be 64 for all; 2. check_pow() callback, HID0 format is the same so should be the same 0x01C0 which means deep nap, doze and nap bits set; 3. LPCR - 970 does not have it but 970MP had one (by mistake). This fixes wrong differences and makes one 970 class. This fixes wrong registration of LPCR which is not present on 970. This does not remove check_pow_970FX now as it is still used by POWER5+ class, this will be addressed later. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- target-ppc/cpu-models.c | 14 +-- target-ppc/translate_init.c | 221 2 files changed, 23 insertions(+), 212 deletions(-) diff --git a/target-ppc/cpu-models.c b/target-ppc/cpu-models.c index 9a66c03..97a81d8 100644 --- a/target-ppc/cpu-models.c +++ b/target-ppc/cpu-models.c @@ -1142,19 +1142,19 @@ POWER8 v1.0) POWERPC_DEF(970, CPU_POWERPC_970,970, PowerPC 970) -POWERPC_DEF(970fx_v1.0,CPU_POWERPC_970FX_v10, 970FX, +POWERPC_DEF(970fx_v1.0,CPU_POWERPC_970FX_v10, 970, PowerPC 970FX v1.0 (G5)) -POWERPC_DEF(970fx_v2.0,CPU_POWERPC_970FX_v20, 970FX, +POWERPC_DEF(970fx_v2.0,CPU_POWERPC_970FX_v20, 970, PowerPC 970FX v2.0 (G5)) -POWERPC_DEF(970fx_v2.1,CPU_POWERPC_970FX_v21, 970FX, +POWERPC_DEF(970fx_v2.1,CPU_POWERPC_970FX_v21, 970, PowerPC 970FX v2.1 (G5)) -POWERPC_DEF(970fx_v3.0,CPU_POWERPC_970FX_v30, 970FX, +POWERPC_DEF(970fx_v3.0,CPU_POWERPC_970FX_v30, 970, PowerPC 970FX v3.0 (G5)) -POWERPC_DEF(970fx_v3.1,CPU_POWERPC_970FX_v31, 970FX, +POWERPC_DEF(970fx_v3.1,CPU_POWERPC_970FX_v31, 970, PowerPC 970FX v3.1 (G5)) -POWERPC_DEF(970mp_v1.0,CPU_POWERPC_970MP_v10, 970MP, +POWERPC_DEF(970mp_v1.0,CPU_POWERPC_970MP_v10, 970, PowerPC 970MP v1.0) -POWERPC_DEF(970mp_v1.1,CPU_POWERPC_970MP_v11, 970MP, +POWERPC_DEF(970mp_v1.1,CPU_POWERPC_970MP_v11, 970, PowerPC 970MP v1.1) #if defined(TODO) POWERPC_DEF(Cell, CPU_POWERPC_CELL, 970, diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index c1cec07..6cd4cd9 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -7270,8 +7270,9 @@ POWERPC_FAMILY(e600)(ObjectClass *oc, void *data) static int check_pow_970 (CPUPPCState *env) { -if (env-spr[SPR_HID0] 0x0060) +if (env-spr[SPR_HID0] 0x01C0) { return 1; +} return 0; } @@ -7305,8 +7306,21 @@ static void init_proc_970 (CPUPPCState *env) SPR_NOACCESS, SPR_NOACCESS, spr_read_hior, spr_write_hior, 0x); + +spr_register(env, SPR_CTRL, SPR_CTRL, + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, spr_write_generic, + 0x); +spr_register(env, SPR_UCTRL, SPR_UCTRL, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, SPR_NOACCESS, + 0x); +spr_register(env, SPR_VRSAVE, SPR_VRSAVE, + spr_read_generic, spr_write_generic, + spr_read_generic, spr_write_generic, + 0x); #if !defined(CONFIG_USER_ONLY) -env-slb_nr = 32; +env-slb_nr = 64; #endif init_excp_970(env); env-dcache_line_size = 128; @@ -7373,209 +7387,6 @@ static int check_pow_970FX (CPUPPCState *env) return 0; } -static void init_proc_970FX (CPUPPCState *env) -{ -gen_spr_ne_601(env); -gen_spr_7xx(env); -/* Time base */ -gen_tbl(env); -/* Hardware implementation registers */ -/* XXX : not implemented */ -spr_register(env, SPR_HID0, HID0, - SPR_NOACCESS, SPR_NOACCESS, - spr_read_generic, spr_write_clear, - 0x6000); -/* XXX : not implemented */ -spr_register(env, SPR_HID1, HID1, - SPR_NOACCESS, SPR_NOACCESS, - spr_read_generic, spr_write_generic, - 0x); -/* XXX : not implemented */ -spr_register(env, SPR_970_HID5, HID5, - SPR_NOACCESS, SPR_NOACCESS, - spr_read_generic, spr_write_generic, - POWERPC970_HID5_INIT); -/* Memory management */ -/* XXX: not correct */ -gen_low_BATs(env); -spr_register(env, SPR_HIOR, SPR_HIOR, - SPR_NOACCESS, SPR_NOACCESS, - spr_read_hior, spr_write_hior, - 0x); -spr_register(env, SPR_CTRL, SPR_CTRL, - SPR_NOACCESS,
[Qemu-devel] [PATCH v3 07/24] target-ppc: Add PMC5/6, SDAR and MMCRA to 970 family
MMCR0, MMCR1, MMCRA, PMC1..6, SIAR, SDAR are defined for 970 and PowerISA CPUs. Since we are building common infrastructure for SPRs intialization to share it between 970 and POWER5+/7/..., let's add missing SPRs to the 970 family. Later rework of CPU class initialization will use those for all PowerISA CPUs. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- target-ppc/translate_init.c | 32 1 file changed, 32 insertions(+) diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 595fd3f..cdb647a 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -7363,6 +7363,10 @@ static void gen_spr_book3s_pmu(CPUPPCState *env) SPR_NOACCESS, SPR_NOACCESS, spr_read_generic, spr_write_generic, 0x); +spr_register(env, SPR_POWER_MMCRA, MMCRA, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, spr_write_generic, + 0x); spr_register(env, SPR_POWER_PMC1, PMC1, SPR_NOACCESS, SPR_NOACCESS, spr_read_generic, spr_write_generic, @@ -7379,10 +7383,22 @@ static void gen_spr_book3s_pmu(CPUPPCState *env) SPR_NOACCESS, SPR_NOACCESS, spr_read_generic, spr_write_generic, 0x); +spr_register(env, SPR_POWER_PMC5, PMC5, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, spr_write_generic, + 0x); +spr_register(env, SPR_POWER_PMC6, PMC6, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, spr_write_generic, + 0x); spr_register(env, SPR_POWER_SIAR, SIAR, SPR_NOACCESS, SPR_NOACCESS, spr_read_generic, SPR_NOACCESS, 0x); +spr_register(env, SPR_POWER_SDAR, SDAR, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, SPR_NOACCESS, + 0x); spr_register(env, SPR_POWER_UMMCR0, UMMCR0, spr_read_ureg, spr_write_ureg, spr_read_ureg, spr_write_ureg, @@ -7391,6 +7407,10 @@ static void gen_spr_book3s_pmu(CPUPPCState *env) spr_read_ureg, SPR_NOACCESS, spr_read_ureg, SPR_NOACCESS, 0x); +spr_register(env, SPR_POWER_UMMCRA, UMMCRA, + spr_read_ureg, SPR_NOACCESS, + spr_read_ureg, SPR_NOACCESS, + 0x); spr_register(env, SPR_POWER_UPMC1, UPMC1, spr_read_ureg, spr_write_ureg, spr_read_ureg, spr_write_ureg, @@ -7407,10 +7427,22 @@ static void gen_spr_book3s_pmu(CPUPPCState *env) spr_read_ureg, spr_write_ureg, spr_read_ureg, spr_write_ureg, 0x); +spr_register(env, SPR_POWER_UPMC5, UPMC5, + spr_read_ureg, spr_write_ureg, + spr_read_ureg, spr_write_ureg, + 0x); +spr_register(env, SPR_POWER_UPMC6, UPMC6, + spr_read_ureg, spr_write_ureg, + spr_read_ureg, spr_write_ureg, + 0x); spr_register(env, SPR_POWER_USIAR, USIAR, spr_read_ureg, SPR_NOACCESS, spr_read_ureg, SPR_NOACCESS, 0x); +spr_register(env, SPR_POWER_USDAR, USDAR, + spr_read_ureg, SPR_NOACCESS, + spr_read_ureg, SPR_NOACCESS, + 0x); } static void gen_spr_book3s_external_control(CPUPPCState *env) -- 1.8.4.rc4
Re: [Qemu-devel] [PATCH 01/18] migration: dump vmstate info as a json file for static analysis
On (Wed) 21 May 2014 [05:45:25], Eric Blake wrote: On 05/12/2014 10:12 PM, Amit Shah wrote: Hi, On (Mon) 12 May 2014 [06:51:54], Eric Blake wrote: On 05/12/2014 05:16 AM, Amit Shah wrote: This commit adds a new command, '-dump-vmstate', that takes a filename as a parameter. When executed, QEMU will dump the vmstate information for the machine type it's invoked with to the file, and quit. The JSON-format output can then be used to compare the vmstate info for different QEMU versions, specifically to test whether live migration would break due to changes in the vmstate data. Are we going to document that JSON format anywhere? I suppose we should, I thought I should wait for comments here on any extra fields that people want. I suppose documenting would just be coming up with a schema, though? ... Is it worth making it part of qapi-schema.json, but documenting the entire schema is difficult, as each device will have its own schema text (due to the differing fields). At least that's how I understand it; please correct me if I'm wrong. If field names form JSON keys, then yes, documenting each device will be its own schema. But if you write things generic enough, you can have a single schema that covers all devices, by ensuring that device-specific field names are supplied only as values, not keys. That is, 'device': { 'name': 'foo', 'fields': { 'field1': 'int32', 'field2': 'int64' } } requires a schema for each device, while 'device': { 'name': 'foo', 'fields': [ { 'name': 'field1', 'type': 'int32' }, { 'name': 'field2', 'type': 'int64' } ] } is generic. It is more verbose and requires more structure, but by isolating device details into values rather than keys, you get rid of the need for per-device schemas. Sure, that gives a nice schema, but complicates the python script.. at least more complex, from what I know of Python so far. Since no one should have the need to look at the json dumps, it's fair to say the simpler the script, the better for reviewers. Amit
Re: [Qemu-devel] [PATCH 01/18] migration: dump vmstate info as a json file for static analysis
On (Wed) 21 May 2014 [13:47:44], Markus Armbruster wrote: Amit Shah amit.s...@redhat.com writes: On (Wed) 21 May 2014 [11:03:04], Dr. David Alan Gilbert wrote: * Amit Shah (amit.s...@redhat.com) wrote: The idea is to be able to take a qemu binary and compare with another binary; if only fields that are instantiated are used, various invocations will have to be tried to find devices that may have broken. An alternative way of checking only devices which have been added to the running machine can be done via a monitor command (or a parameter to the existing cmdline option). But I'm not sure if that'll be more useful than the current one. Or perhaps a way to dump that info and mask your checker with it if wanted? A 'blacklist' file, which stores names of sections that you're not interested in? An error message format that lets me grep -v for sections I'm not interested in? Stupidest solution that could possibly work... The discusison had overfown onto IRC, and I think what David was looking for was to weed out certain sections altogether, like 'fdc', if the machines he's interested in do not have floppy drives at all. The error message format is quite consistent in that regard, I feel, but opinions on improving it are welcome. Currently, errors/warnings are reported like this: Section usb-kbd Description usb-kbd Field kbd.keycodes size mismatch: 4 , 2 Section PIIX3-xen Description PIIX3: minimum version error: 1 2 Section PIIX3-xen Description PIIX3: Entry Subsections missing ... and so on. Amit
[Qemu-devel] [PATCH] arm: Bugfix: Fix cpu_reset() / vcpu_init() order
This fix a bug introduced by commit 50a2c6e55fa2ce5a2916a2c206bad2c6b0e06df1, but I'm not sure it is a proper fix. Acked-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Christoffer Dall christoffer.d...@linaro.org --- target-arm/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 6c6f2b3..794dcb9 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -370,8 +370,8 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) init_cpreg_list(cpu); -cpu_reset(cs); qemu_init_vcpu(cs); +cpu_reset(cs); acc-parent_realize(dev, errp); } -- 1.8.5.2
Re: [Qemu-devel] [PATCH] PPC: Fix popcntb opcode id
On 5/23/2014 9:21 AM, Alexander Graf wrote: The popcntb opcode is at 31/122 according to the spec. In QEMU's internal opcode representation that sums up to 1f/1a/03. Fix the opcode definition to match on the correct ID. This fixes booting Linux with -cpu POWER7,compat=power6 in TCG mode for me. Signed-off-by: Alexander Graf ag...@suse.de --- target-ppc/translate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 0cf1417..02e006a 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -10124,7 +10124,7 @@ GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x, PPC_INTEGER), GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x, PPC_INTEGER), GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x, PPC_INTEGER), GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x, PPC_INTEGER), -GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0xF801, PPC_POPCNTB), +GEN_HANDLER(popcntb, 0x1F, 0x1A, 0x03, 0xF801, PPC_POPCNTB), GEN_HANDLER(popcntw, 0x1F, 0x1A, 0x0b, 0xF801, PPC_POPCNTWD), GEN_HANDLER_E(prtyw, 0x1F, 0x1A, 0x04, 0xF801, PPC_NONE, PPC2_ISA205), #if defined(TARGET_PPC64) Seems to the a duplicate of what I had done here: http://lists.nongnu.org/archive/html/qemu-devel/2014-05/msg02851.html So ... Reviewed-By: Tom Musta tommu...@gmail.com Tested-by: Tom Musta tommu...@gmail.com
Re: [Qemu-devel] How to enable more than 2047 MB RAM on 32 bit host systems for 32 bit guests?
On Di, 2014-05-27 at 09:33 +0200, Erik Rull wrote: Hi all, I would like to provide 3GB of RAM to my guest - I use kvm and don't see a real reason why this should not work. Currently, qemu-1.7.0 with kvm is in use. No way. Userspace has 3G address space on 32bit machines, and you can't assign all of that to the guest as qemu needs memory for itself too ... cheers, Gerd
[Qemu-devel] [PATCH v3 09/24] target-ppc: Add HID4 SPR for PPC970
Previously LPCR was registered for the 970 class which was wrong as it does not have LPCR. Instead, HID4 is used which this patch registers. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- target-ppc/cpu.h| 1 + target-ppc/translate_init.c | 11 +++ 2 files changed, 12 insertions(+) diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index f8a01ee..6f2baef 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -1683,6 +1683,7 @@ static inline int cpu_mmu_index (CPUPPCState *env) #define SPR_750_TDCL (0x3F4) #define SPR_40x_IAC1 (0x3F4) #define SPR_MMUCSR0 (0x3F4) +#define SPR_970_HID4 (0x3F4) #define SPR_DABR (0x3F5) #define DABR_MASK (~(target_ulong)0x7) #define SPR_Exxx_BUCSR(0x3F5) diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 6fc8671..7662730 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -7474,6 +7474,16 @@ static void gen_spr_book3s_external_control(CPUPPCState *env) 0x); } +static void gen_spr_970_lpar(CPUPPCState *env) +{ +/* Logical partitionning */ +/* PPC970: HID4 is effectively the LPCR */ +spr_register(env, SPR_970_HID4, HID4, + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, spr_write_generic, + 0x); +} + static void init_proc_970 (CPUPPCState *env) { gen_spr_ne_601(env); @@ -7487,6 +7497,7 @@ static void init_proc_970 (CPUPPCState *env) gen_low_BATs(env); gen_spr_970_ctrl(env); gen_spr_970_pmu(env); +gen_spr_970_lpar(env); gen_spr_book3s_external_control(env); -- 1.8.4.rc4
Re: [Qemu-devel] x86 emulation on ARM host (Samsung Chromebook)
On Wed, May 21, 2014 at 12:57:59PM +, Violaine V. wrote: Hi everyone, I’m trying to use QEMU (qemu-system-x86_64) to emulate an x86 virtual machine on an ARM host : a Samsung Chromebook with Cortex-A15 CPU. The Chromebook only has 2 GB of RAM and a relatively slow 32 bit processor, and you're using an SD card which means all I/O is going to be slow. Emulation of x86 is going to be very slow and painful. Anyway I think what you need to do is attach a debugger to find out what the guest is doing. http://wiki.qemu.org/Documentation/Debugging I've no idea if an ARM-compiled gdb will be able to debug an x86 guest however ... You may need to cross-compile it somehow. I'm kind of interested in making this work, but only on 64 bit ARM hardware where this is more feasible. People using libguestfs on aarch64 want to inspect and run commands in their x86 VMs. There was a request for this on the mailing list only a couple of weeks ago. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com Fedora Windows cross-compiler. Compile Windows programs, test, and build Windows installers. Over 100 libraries supported. http://fedoraproject.org/wiki/MinGW
Re: [Qemu-devel] [PATCH 5/8] qemu-bridge-helper: Fix fd leak in main()
On Tue, May 27, 2014 at 09:40:02AM +0800, arei.gong...@huawei.com wrote: From: Gonglei arei.gong...@huawei.com Signed-off-by: Gonglei arei.gong...@huawei.com --- qemu-bridge-helper.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/qemu-bridge-helper.c b/qemu-bridge-helper.c index 6a0974e..dce5abc 100644 --- a/qemu-bridge-helper.c +++ b/qemu-bridge-helper.c @@ -436,7 +436,12 @@ int main(int argc, char **argv) /* profit! */ cleanup: - +if (fd = 0) { +close(fd); +} +if (ctlfd = 0) { +close(ctlfd); +} fd and ctlfd are uninitialized: int fd, ctlfd, unixfd = -1; This patch introduces a read of uninitialized memory and could close a random file descriptor. There wasn't a real leak since this is the main() function and the kernel frees resources when the process terminates. Please either drop this patch or fix it carefully.
Re: [Qemu-devel] [PATCH 4/8] qcow2-cluster: Fix memory leak in copy_sectors
On Tue, May 27, 2014 at 09:40:01AM +0800, arei.gong...@huawei.com wrote: From: Gonglei arei.gong...@huawei.com Spotted by Coverity: (3) Event alloc_fn: Storage is returned from allocation function qemu_blockalign(BlockDriverState *, size_t). [details] (4) Event var_assign: Assigning: iov.iov_base = storage returned from qemu_blockalign(bs, iov.iov_len). Also see events: [leaked_storage] 375 iov.iov_base = qemu_blockalign(bs, iov.iov_len); 376 377 qemu_iovec_init_external(qiov, iov, 1); 378 379 BLKDBG_EVENT(bs-file, BLKDBG_COW_READ); 380 (5) Event cond_true: Condition !bs-drv, taking true branch 381 if (!bs-drv) { (6) Event leaked_storage: Variable iov going out of scope leaks the storage iov.iov_base points to. Also see events: [alloc_fn][var_assign] 382 return -ENOMEDIUM; 383 } Signed-off-by: Gonglei arei.gong...@huawei.com --- block/qcow2-cluster.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) Reviewed-by: Stefan Hajnoczi stefa...@redhat.com
Re: [Qemu-devel] Disk image fuzz testing (OPW)
On Mon, May 26, 2014 at 01:53:57PM +0400, M.Kustova wrote: About fuzzer effectiveness. 'qemu-img' was set as the fuzzer target, so its commands under interest are any that modify or/and read an image. As first step, a tested command will be selected randomly or specified by user. qemu-io would be better, wouldn't it? After investigation of code coverage on the final stage of the project additional constrains will be added to the algorithm selecting blocks to be fuzzed. Feedback-directed fuzz-testing? Good stuff. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com Fedora Windows cross-compiler. Compile Windows programs, test, and build Windows installers. Over 100 libraries supported. http://fedoraproject.org/wiki/MinGW