[Qemu-devel] [Bug 498035] Re: qemu hangs on shutdown or reboot (XP guest)

2012-05-17 Thread Michael Tokarev
Confirming what?  0.14 version of qemu (there was no 14.0 version) is
very old.  Very frustrating that people just "confirm" bugs using old
versions without trying current version which has a lot of changes
within.  I can confirm that this prob - winXP (or win7 for that matter)
getting stuck on reboot/shutdown - which I faced too on a "semi-regular"
basis has now gone, either because of some change in qemu, in
configuration, or due to some patch on the windows side - I don't know,
and will unlikely to know.  I'm using 1.0.1 version currently.

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/498035

Title:
  qemu hangs on shutdown or reboot (XP guest)

Status in QEMU:
  Triaged

Bug description:
  When I shut down or reboot my Windows XP guest, about half the time,
  it hangs at the point where it says "Windows is shutting down...".  At
  that point qemu is using 100% of one host CPU, about 85% user, 15%
  system.  (Core 2 Quad 2.66GHz)

  This is the command line I use to start qemu:

  qemu-system-x86_64 -hda winxp.img -k en-us -m 2048 -smp 2 -vnc :3100
  -usbdevice tablet -boot c -enable-kvm &

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/498035/+subscriptions



Re: [Qemu-devel] [PATCH 04/13] pci: New pci_dma_quirk()

2012-05-17 Thread Anonymous
Alex,

On Sat, May 12, 2012 at 6:55 AM, Alex Williamson
 wrote:
> Integrating IOMMU groups more closely into the driver core allows
> us to more easily work around DMA quirks.  The Ricoh multifunction
> controller is a favorite example of devices that are currently
> incompatible with IOMMU isolation as all the functions use the
> requestor ID of function 0 for DMA.  Passing this device into
> pci_dma_quirk returns the PCI device to use for DMA.  The IOMMU
> driver can then construct an IOMMU group including both devices.
>

Please give some thought to the Marvell SATA controller quirk as well.

Instead of multiple visible functions using the same requester ID of
function 0, the Marvell device only makes function 0 visible, but uses
the requestor ID of function 1 as well during DMA.

See https://bugzilla.redhat.com/show_bug.cgi?id=757166

--
A.



Re: [Qemu-devel] [PATCH] Add event notification for guest balloon changes

2012-05-17 Thread Daniel P. Berrange
On Wed, May 16, 2012 at 01:58:34PM -0500, Anthony Liguori wrote:
> On 05/16/2012 01:42 PM, Luiz Capitulino wrote:
> >On Wed, 16 May 2012 11:10:47 +0100
> >"Daniel P. Berrange"  wrote:
> >
> >>From: "Daniel P. Berrange"
> >>
> >>After setting a balloon target value, applications have to
> >>continually poll 'query-balloon' to determine whether the
> >>guest has reacted to this request. The virtio-balloon backend
> >>knows exactly when the guest has reacted though, and thus it
> >>is possible to emit a JSON event to tell the mgmt application
> >>whenever the guest balloon changes.
> >>
> >>This introduces a new 'qemu_balloon_change()' API which is
> >>to be called by balloon driver backends, whenever they have
> >>a change in balloon value. This takes the 'actual' balloon
> >>value, as would be found in the BalloonInfo struct.
> >>
> >>The qemu_balloon_change API emits a JSON monitor event which
> >>looks like:
> >>
> >>   {"timestamp": {"seconds": 1337162462, "microseconds": 814521},
> >>"event": "BALLOON_CHANGE", "data": {"actual": 944766976}}
> >
> >It's missing an entry in QMP/qmp-events.txt and I have a comment below,
> >but in general looks good.
> >
> >Amit, would be good to get your ack.
> 
> I think it would be safer to limit this event to (1) only firing
> once target has been reached (2) firing if target is deviated from
> without a corresponding change in target.
> 
> Otherwise, a guest could just flood libvirt with events.  This would
> queue memory in QEMU indefinitely as the events got queued up to
> potentially serving as a DoS against other guests.

Hmm, that's a good point, but my concern was that if we only emit
the event when the target is reached, what happens if the guest
gets very close to the target but never actually reaches it for
some reason.

Should we perhaps just rate limit it to once per second ?

BTW, if we're considering guest initiated events to be a potential
DOS in this way, then I should point out the RTC_CHANGE event
will already suffer this way, if a malicious guest continually
adjusts its hardware close. So we might want to apply rate limiting
to that event too ?


Daniel
-- 
|: http://berrange.com  -o-http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org  -o- http://virt-manager.org :|
|: http://autobuild.org   -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org   -o-   http://live.gnome.org/gtk-vnc :|



[Qemu-devel] [PATCH 00/15] Qemu Openrisc support

2012-05-17 Thread Jia Liu
This is the Opencores Openrisc 1200 support for Qemu.
Full implementation of the system-model and linux-user-model support.

Openrisc 1200 is a Opencores Open Source CPU,
its Architecture Manual can be find at
http://opencores.org/svnget,or1k?file=/trunk/docs/openrisc_arch.pdf

Signed-off-by: Jia Liu 
---

Version History:

V1:
- add Qemu Openrisc support.
- well tested on x64 machine, and final tested x86 machine.

Jia Liu (15):
  Openrisc: add target stub
  Openrisc: add MMU support
  Openrisc: add instructions translation
  Openrisc: add interrupt support
  Openrisc: add exception support
  Openrisc: add int instruction helpers
  Openrisc: add float instruction helpers
  Openrisc: add programmable interrupt controller support
  Openrisc: add timer support
  Openrisc: add a simulation board
  Openrisc: add system instruction helpers
  Openrisc: add gdb stub support
  Openrisc: add linux syscall, signal and termbits
  Openrisc: add linux user support
  Openrisc: add testcases

 Makefile.target |7 +
 arch_init.c |2 +
 arch_init.h |1 +
 configure   |9 +-
 cpu-exec.c  |   19 +
 default-configs/or32-linux-user.mak |2 +
 default-configs/or32-softmmu.mak|6 +
 elf.h   |2 +
 gdbstub.c   |   64 ++
 hw/openrisc_cpudev.h|   30 +
 hw/openrisc_pic.c   |   79 ++
 hw/openrisc_sim.c   |  140 
 hw/openrisc_timer.c |  153 
 linux-user/elfload.c|   41 +
 linux-user/main.c   |  100 +++
 linux-user/openrisc/syscall.h   |   24 +
 linux-user/openrisc/syscall_nr.h|  506 
 linux-user/openrisc/target_signal.h |   26 +
 linux-user/openrisc/termbits.h  |  294 +++
 linux-user/signal.c |  229 ++
 linux-user/syscall.c|2 +-
 linux-user/syscall_defs.h   |   40 +-
 poison.h|1 +
 target-openrisc/cpu-qom.h   |   70 ++
 target-openrisc/cpu.c   |   74 ++
 target-openrisc/cpu.h   |  299 +++
 target-openrisc/excp.c  |   27 +
 target-openrisc/excp.h  |   28 +
 target-openrisc/excp_helper.c   |   28 +
 target-openrisc/fpu_helper.c|   93 +++
 target-openrisc/helper.c|  109 +++
 target-openrisc/helper.h|   46 ++
 target-openrisc/int_helper.c|  126 +++
 target-openrisc/intrp_helper.c  |   53 ++
 target-openrisc/machine.c   |   76 ++
 target-openrisc/mem.c   |  261 ++
 target-openrisc/mem_helper.c|   71 ++
 target-openrisc/sys_helper.c|  227 ++
 target-openrisc/translate.c | 1484 +++
 tests/tcg/openrisc/Makefile |   73 ++
 tests/tcg/openrisc/test_add.c   |   34 +
 tests/tcg/openrisc/test_addc.c  |   37 +
 tests/tcg/openrisc/test_addi.c  |   31 +
 tests/tcg/openrisc/test_addic.c |   32 +
 tests/tcg/openrisc/test_and_or.c|   61 ++
 tests/tcg/openrisc/test_bf.c|   46 ++
 tests/tcg/openrisc/test_bnf.c   |   50 ++
 tests/tcg/openrisc/test_div.c   |   32 +
 tests/tcg/openrisc/test_extx.c  |   71 ++
 tests/tcg/openrisc/test_fx.c|   53 ++
 tests/tcg/openrisc/test_j.c |   26 +
 tests/tcg/openrisc/test_jal.c   |   26 +
 tests/tcg/openrisc/test_lf_add.c|   32 +
 tests/tcg/openrisc/test_lf_div.c|   33 +
 tests/tcg/openrisc/test_lf_eqd.c|   44 ++
 tests/tcg/openrisc/test_lf_eqs.c|   43 +
 tests/tcg/openrisc/test_lf_ged.c|   45 ++
 tests/tcg/openrisc/test_lf_ges.c|   45 ++
 tests/tcg/openrisc/test_lf_gtd.c|   45 ++
 tests/tcg/openrisc/test_lf_gts.c|   45 ++
 tests/tcg/openrisc/test_lf_led.c|   43 +
 tests/tcg/openrisc/test_lf_les.c|   45 ++
 tests/tcg/openrisc/test_lf_ltd.c|   45 ++
 tests/tcg/openrisc/test_lf_lts.c|   45 ++
 tests/tcg/openrisc/test_lf_mul.c|   22 +
 tests/tcg/openrisc/test_lf_ned.c|   46 ++
 tests/tcg/openrisc/test_lf_nes.c|   46 ++
 tests/tcg/openrisc/test_lf_rem.c|   31 +
 tests/tcg/openrisc/test_lf_sub.c|   31 +
 tests/tcg/openrisc/test_logic.c |  100 +++
 tests/tcg/openrisc/test_lx.c|   78 ++
 tests/tcg/openrisc/test_movhi.c |   30 +
 tests/tcg/openrisc/test_mul.c   |   47 ++
 tests/tcg/openrisc/test_sfeq.c  |   43 +
 tests/tcg/openrisc/test_sfeqi.c |   39 +
 tests/tcg/openrisc/test_sfges.c |   44 ++
 tests/tcg/openrisc/test_sfgesi.c|   40 +
 tests/tcg/openrisc/test_sfgeu.c |   44 ++
 tests/tcg/openrisc/test_sfgeui.c|   41 +
 tests/tcg/openrisc/test_sfgts.c |   45 ++
 tests/tcg/openrisc/test_sfgtsi.c|   41 +
 tests/tcg/openrisc/test_sfgtu.c |   43 +
 tests/tcg/openrisc/test_sfgtui.c|   42 +
 tests/tcg/openrisc/test_sfles.c |   26 +
 tests/tcg/openrisc/te

[Qemu-devel] [PATCH 11/15] Openrisc: add system instruction helpers

2012-05-17 Thread Jia Liu
add the openrisc system instruction helpers.

Signed-off-by: Jia Liu 
---
 Makefile.target  |2 +-
 target-openrisc/helper.h |4 +
 target-openrisc/sys_helper.c |  227 ++
 target-openrisc/translate.c  |4 +-
 4 files changed, 234 insertions(+), 3 deletions(-)
 create mode 100644 target-openrisc/sys_helper.c

diff --git a/Makefile.target b/Makefile.target
index 433dd3c..ca1f45a 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -101,7 +101,7 @@ endif
 libobj-$(TARGET_SPARC) += int32_helper.o
 libobj-$(TARGET_SPARC64) += int64_helper.o
 libobj-$(TARGET_ALPHA) += int_helper.o fpu_helper.o sys_helper.o mem_helper.o
-libobj-$(TARGET_OPENRISC) += excp.o excp_helper.o fpu_helper.o int_helper.o 
intrp_helper.o mem.o mem_helper.o
+libobj-$(TARGET_OPENRISC) += excp.o excp_helper.o fpu_helper.o int_helper.o 
intrp_helper.o mem.o mem_helper.o sys_helper.o
 
 libobj-y += disas.o
 libobj-$(CONFIG_TCI_DIS) += tci-dis.o
diff --git a/target-openrisc/helper.h b/target-openrisc/helper.h
index b9b1d67..b515f92 100644
--- a/target-openrisc/helper.h
+++ b/target-openrisc/helper.h
@@ -39,4 +39,8 @@ DEF_HELPER_FLAGS_3(sub, 0, tl, env, tl, tl)
 /* interrupt */
 DEF_HELPER_FLAGS_1(rfe, 0, void, env)
 
+/* sys */
+DEF_HELPER_FLAGS_4(mtspr, 0, void, env, tl, tl, tl)
+DEF_HELPER_FLAGS_4(mfspr, 0, void, env, tl, tl, tl)
+
 #include "def-helper.h"
diff --git a/target-openrisc/sys_helper.c b/target-openrisc/sys_helper.c
new file mode 100644
index 000..59e9f20
--- /dev/null
+++ b/target-openrisc/sys_helper.c
@@ -0,0 +1,227 @@
+/*
+ * OpenRISC system-insns helper routines
+ *
+ *  Copyright (c) 2011-2012 Jia Liu 
+ *  Zhizhou Zhang 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
+ */
+
+#include "cpu.h"
+#include "helper.h"
+
+#define TO_SPR(group, number) (((group)<<11)+(number))
+void HELPER(mtspr)(CPUOPENRISCState * env,
+   target_ulong ra, target_ulong rb, uint32_t offset)
+{
+#if !defined(CONFIG_USER_ONLY)
+int spr = env->gpr[ra] | offset;
+int idx;
+
+switch (spr) {
+case TO_SPR(0, 16): /* NPC */
+env->npc = env->gpr[rb];
+break;
+
+case TO_SPR(0, 17): /* SR */
+if ((env->sr & (SR_IME | SR_DME | SR_SM)) ^
+(env->gpr[rb] & (SR_IME | SR_DME | SR_SM))) {
+tlb_flush(env, 1);
+}
+env->sr = env->gpr[rb];
+env->sr |= SR_FO;  /* FO is const equal to 1 */
+if (env->sr & SR_DME) {
+env->map_address_data = &get_phys_data;
+} else {
+env->map_address_data = &get_phys_nommu;
+}
+
+if (env->sr & SR_IME) {
+env->map_address_code = &get_phys_code;
+} else {
+env->map_address_code = &get_phys_nommu;
+}
+break;
+
+case TO_SPR(0, 18): /* PPC */
+env->ppc = env->gpr[rb];
+break;
+
+case TO_SPR(0, 32): /* EPCR */
+env->epcr = env->gpr[rb];
+break;
+
+case TO_SPR(0, 48): /* EEAR */
+env->eear = env->gpr[rb];
+break;
+
+case TO_SPR(0, 64): /* ESR */
+env->esr = env->gpr[rb];
+break;
+case TO_SPR(1, 512) ... TO_SPR(1, 639): /* DTLBW0MR 0-127 */
+idx = spr - TO_SPR(1, 512);
+if (!(env->gpr[rb] & 1)) {
+tlb_flush_page(env, env->dtlb[0][idx].mr & TARGET_PAGE_MASK);
+}
+env->dtlb[0][idx].mr = env->gpr[rb];
+break;
+
+case TO_SPR(1, 640) ... TO_SPR(1, 767): /* DTLBW0TR 0-127 */
+idx = spr - TO_SPR(1, 640);
+env->dtlb[0][idx].tr = env->gpr[rb];
+break;
+case TO_SPR(1, 768) ... TO_SPR(1, 895):   /* DTLBW1MR 0-127 */
+case TO_SPR(1, 896) ... TO_SPR(1, 1023):  /* DTLBW1TR 0-127 */
+case TO_SPR(1, 1024) ... TO_SPR(1, 1151): /* DTLBW2MR 0-127 */
+case TO_SPR(1, 1152) ... TO_SPR(1, 1279): /* DTLBW2TR 0-127 */
+case TO_SPR(1, 1280) ... TO_SPR(1, 1407): /* DTLBW3MR 0-127 */
+case TO_SPR(1, 1408) ... TO_SPR(1, 1535): /* DTLBW3TR 0-127 */
+break;
+case TO_SPR(2, 512) ... TO_SPR(2, 639):   /* ITLBW0MR 0-127 */
+idx = spr - TO_SPR(2, 512);
+if (!(env->gpr[rb] & 1)) {
+tlb_flush_page(env, env->itlb[0][idx].mr & TARGET_PAGE_MASK);
+}
+   

[Qemu-devel] [PATCH 12/15] Openrisc: add gdb stub support

2012-05-17 Thread Jia Liu
add the qemu gdb stub support for openrisc.

Signed-off-by: Jia Liu 
---
 gdbstub.c |   64 +
 1 file changed, 64 insertions(+)

diff --git a/gdbstub.c b/gdbstub.c
index 6a77a66..fb86f22 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1155,6 +1155,68 @@ static int cpu_gdb_write_register(CPUMIPSState *env, 
uint8_t *mem_buf, int n)
 
 return sizeof(target_ulong);
 }
+#elif defined(TARGET_OPENRISC)
+
+#define NUM_CORE_REGS (32 + 3)
+
+static int cpu_gdb_read_register(CPUOPENRISCState *env, uint8_t *mem_buf, int 
n)
+{
+if (n < 32) {
+GET_REG32(env->gpr[n]);
+} else {
+switch (n) {
+case 32:/* PPC */
+GET_REG32(env->ppc);
+break;
+
+case 33:/* NPC */
+GET_REG32(env->npc);
+break;
+
+case 34:/* SR */
+GET_REG32(env->sr);
+break;
+
+default:
+break;
+}
+}
+return 0;
+}
+
+static int cpu_gdb_write_register(CPUOPENRISCState *env,
+  uint8_t *mem_buf, int n)
+{
+uint32_t tmp;
+
+if (n > NUM_CORE_REGS) {
+return 0;
+}
+
+tmp = ldl_p(mem_buf);
+
+if (n < 32) {
+env->gpr[n] = tmp;
+} else {
+switch (n) {
+case 32: /* PPC */
+env->ppc = tmp;
+break;
+
+case 33: /* NPC */
+env->npc = tmp;
+break;
+
+case 34: /* SR */
+env->sr = tmp;
+break;
+
+default:
+break;
+}
+}
+return 4;
+}
 #elif defined (TARGET_SH4)
 
 /* Hint: Use "set architecture sh4" in GDB to see fpu registers */
@@ -1924,6 +1986,8 @@ static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
 }
 #elif defined (TARGET_MICROBLAZE)
 s->c_cpu->sregs[SR_PC] = pc;
+#elif defined(TARGET_OPENRISC)
+s->c_cpu->pc = pc;
 #elif defined (TARGET_CRIS)
 s->c_cpu->pc = pc;
 #elif defined (TARGET_ALPHA)
-- 
1.7.9.5




[Qemu-devel] [PATCH 13/15] Openrisc: add linux syscall, signal and termbits

2012-05-17 Thread Jia Liu
add the openrisc syscall, signal and termbits for linux-user.

Signed-off-by: Jia Liu 
---
 linux-user/openrisc/syscall.h   |   24 ++
 linux-user/openrisc/syscall_nr.h|  506 +++
 linux-user/openrisc/target_signal.h |   26 ++
 linux-user/openrisc/termbits.h  |  294 
 4 files changed, 850 insertions(+)
 create mode 100644 linux-user/openrisc/syscall.h
 create mode 100644 linux-user/openrisc/syscall_nr.h
 create mode 100644 linux-user/openrisc/target_signal.h
 create mode 100644 linux-user/openrisc/termbits.h

diff --git a/linux-user/openrisc/syscall.h b/linux-user/openrisc/syscall.h
new file mode 100644
index 000..9c51893
--- /dev/null
+++ b/linux-user/openrisc/syscall.h
@@ -0,0 +1,24 @@
+struct target_pt_regs {
+union {
+struct {
+/* Named registers */
+long  sr;   /* Stored in place of r0 */
+ long  sp;   /* r1 */
+ };
+ struct {
+ /* Old style */
+ long offset[2];
+ long gprs[30];
+ };
+ struct {
+ /* New style */
+ long gpr[32];
+ };
+ };
+long  pc;
+long  orig_gpr11;   /* For restarting system calls */
+long  syscallno;/* Syscall number (used by strace) */
+long dummy; /* Cheap alignment fix */
+};
+
+#define UNAME_MACHINE "openrisc"
diff --git a/linux-user/openrisc/syscall_nr.h b/linux-user/openrisc/syscall_nr.h
new file mode 100644
index 000..f4ac91e
--- /dev/null
+++ b/linux-user/openrisc/syscall_nr.h
@@ -0,0 +1,506 @@
+#define TARGET_NR_io_setup 0
+#define TARGET_NR_io_destroy 1
+#define TARGET_NR_io_submit 2
+#define TARGET_NR_io_cancel 3
+#define TARGET_NR_io_getevents 4
+
+/* fs/xattr.c */
+#define TARGET_NR_setxattr 5
+#define TARGET_NR_lsetxattr 6
+#define TARGET_NR_fsetxattr 7
+#define TARGET_NR_getxattr 8
+#define TARGET_NR_lgetxattr 9
+#define TARGET_NR_fgetxattr 10
+#define TARGET_NR_listxattr 11
+#define TARGET_NR_llistxattr 12
+#define TARGET_NR_flistxattr 13
+#define TARGET_NR_removexattr 14
+#define TARGET_NR_lremovexattr 15
+#define TARGET_NR_fremovexattr 16
+
+/* fs/dcache.c */
+#define TARGET_NR_getcwd 17
+
+/* fs/cookies.c */
+#define TARGET_NR_lookup_dcookie 18
+
+/* fs/eventfd.c */
+#define TARGET_NR_eventfd2 19
+
+/* fs/eventpoll.c */
+#define TARGET_NR_epoll_create1 20
+#define TARGET_NR_epoll_ctl 21
+#define TARGET_NR_epoll_pwait 22
+
+/* fs/fcntl.c */
+#define TARGET_NR_dup 23
+#define TARGET_NR_dup3 24
+#define TARGET_NR_3264_fcntl 25
+
+/* fs/inotify_user.c */
+#define TARGET_NR_inotify_init1 26
+#define TARGET_NR_inotify_add_watch 27
+#define TARGET_NR_inotify_rm_watch 28
+
+/* fs/ioctl.c */
+#define TARGET_NR_ioctl 29
+
+/* fs/ioprio.c */
+#define TARGET_NR_ioprio_set 30
+#define TARGET_NR_ioprio_get 31
+
+/* fs/locks.c */
+#define TARGET_NR_flock 32
+
+/* fs/namei.c */
+#define TARGET_NR_mknodat 33
+#define TARGET_NR_mkdirat 34
+#define TARGET_NR_unlinkat 35
+#define TARGET_NR_symlinkat 36
+#define TARGET_NR_linkat 37
+#define TARGET_NR_renameat 38
+
+/* fs/namespace.c */
+#define TARGET_NR_umount2 39
+#define TARGET_NR_mount 40
+#define TARGET_NR_pivot_root 41
+
+/* fs/nfsctl.c */
+#define TARGET_NR_nfsservctl 42
+
+/* fs/open.c */
+#define TARGET_NR_3264_statfs 43
+#define TARGET_NR_3264_fstatfs 44
+#define TARGET_NR_3264_truncate 45
+#define TARGET_NR_3264_ftruncate 46
+
+#define TARGET_NR_fallocate 47
+#define TARGET_NR_faccessat 48
+#define TARGET_NR_chdir 49
+#define TARGET_NR_fchdir 50
+#define TARGET_NR_chroot 51
+#define TARGET_NR_fchmod 52
+#define TARGET_NR_fchmodat 53
+#define TARGET_NR_fchownat 54
+#define TARGET_NR_fchown 55
+#define TARGET_NR_openat 56
+#define TARGET_NR_close 57
+#define TARGET_NR_vhangup 58
+
+/* fs/pipe.c */
+#define TARGET_NR_pipe2 59
+
+/* fs/quota.c */
+#define TARGET_NR_quotactl 60
+
+/* fs/readdir.c */
+#define TARGET_NR_getdents64 61
+
+/* fs/read_write.c */
+#define TARGET_NR_3264_lseek 62
+#define TARGET_NR_read 63
+#define TARGET_NR_write 64
+#define TARGET_NR_readv 65
+#define TARGET_NR_writev 66
+#define TARGET_NR_pread64 67
+#define TARGET_NR_pwrite64 68
+#define TARGET_NR_preadv 69
+#define TARGET_NR_pwritev 70
+
+/* fs/sendfile.c */
+#define TARGET_NR_3264_sendfile 71
+
+/* fs/select.c */
+#define TARGET_NR_pselect6 72
+#define TARGET_NR_ppoll 73
+
+/* fs/signalfd.c */
+#define TARGET_NR_signalfd4 74
+
+/* fs/splice.c */
+#define TARGET_NR_vmsplice 75
+#define TARGET_NR_splice 76
+#define TARGET_NR_tee 77
+
+/* fs/stat.c */
+#define TARGET_NR_readlinkat 78
+#define TARGET_NR_3264_fstatat 79
+#define TARGET_NR_3264_fstat 80
+
+/* fs/sync.c */
+#define TARGET_NR_sync 81
+#define TARGET_NR_fsync 82
+#define TARGET_NR_fdatasync 83
+
+#ifdef __ARCH_WANT_SYNC_FILE_RANGE2
+#define TARGET_NR_sync_file_range2 84
+#else
+#define TARGET_NR_sync_file_range 84
+#endif
+
+/* fs/timerfd.c */
+#define TARGET_NR_timerfd_create 85
+#define TARGET_NR_timerfd_settime 86
+#define TARGET_NR_timerfd_get

[Qemu-devel] [PATCH 14/15] Openrisc: add linux user support

2012-05-17 Thread Jia Liu
add the linux user support for openrisc.

Signed-off-by: Jia Liu 
---
 configure   |1 +
 default-configs/or32-linux-user.mak |2 +
 linux-user/elfload.c|   41 +++
 linux-user/main.c   |  100 +++
 linux-user/signal.c |  229 +++
 linux-user/syscall.c|2 +-
 linux-user/syscall_defs.h   |   40 +-
 7 files changed, 411 insertions(+), 4 deletions(-)
 create mode 100644 default-configs/or32-linux-user.mak

diff --git a/configure b/configure
index 63e2372..d0979d2 100755
--- a/configure
+++ b/configure
@@ -951,6 +951,7 @@ microblaze-linux-user \
 microblazeel-linux-user \
 mips-linux-user \
 mipsel-linux-user \
+or32-linux-user \
 ppc-linux-user \
 ppc64-linux-user \
 ppc64abi32-linux-user \
diff --git a/default-configs/or32-linux-user.mak 
b/default-configs/or32-linux-user.mak
new file mode 100644
index 000..d2fdf22
--- /dev/null
+++ b/default-configs/or32-linux-user.mak
@@ -0,0 +1,2 @@
+# Default configuration for or32-linux-user
+
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index f3b1552..5215ccd 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -787,6 +787,47 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, 
const CPUMBState *env
 
 #endif /* TARGET_MICROBLAZE */
 
+#ifdef TARGET_OPENRISC
+
+#define ELF_START_MMAP 0x0800
+
+#define elf_check_arch(x) ((x) == EM_OPENRISC)
+
+#define ELF_ARCH EM_OPENRISC
+#define ELF_CLASS ELFCLASS32
+#define ELF_DATA  ELFDATA2MSB
+
+static inline void init_thread(struct target_pt_regs *regs,
+   struct image_info *infop)
+{
+regs->pc = infop->entry;
+regs->gpr[1] = infop->start_stack;
+}
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE 8192
+
+/* See linux kernel arch/openrisc/include/asm/elf.h.  */
+#define ELF_NREG 34 /* gprs and pc, sr */
+typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
+
+static void elf_core_copy_regs(target_elf_gregset_t *regs,
+   const CPUOPENRISCState *env)
+{
+int i;
+
+for (i = 0; i < 32; i++) {
+(*regs)[i] = tswapl(env->gpr[i]);
+}
+
+(*regs)[32] = tswapl(env->pc);
+(*regs)[33] = tswapl(env->sr);
+}
+#define ELF_HWCAP 0
+#define ELF_PLATFORM NULL
+
+#endif /* TARGET_OPENRISC */
+
 #ifdef TARGET_SH4
 
 #define ELF_START_MMAP 0x8000
diff --git a/linux-user/main.c b/linux-user/main.c
index 191b750..68eee14 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -2305,6 +2305,93 @@ done_syscall:
 }
 #endif
 
+#ifdef TARGET_OPENRISC
+
+void cpu_loop(CPUOPENRISCState *env)
+{
+int trapnr, gdbsig;
+
+for (;;) {
+trapnr = cpu_exec(env);
+gdbsig = 0;
+
+switch (trapnr) {
+case EXCP_RESET:
+fprintf(stderr, "\nReset request, exit, pc is %#x\n", env->pc);
+exit(1);
+break;
+case EXCP_BUSERR:
+fprintf(stderr, "\nBus error, exit, pc is %#x\n", env->pc);
+gdbsig = SIGBUS;
+break;
+case EXCP_DPF:
+case EXCP_IPF:
+cpu_dump_state(env, stderr, fprintf, 0);
+gdbsig = TARGET_SIGSEGV;
+break;
+case EXCP_TICK:
+fprintf(stderr, "\nTick time interrupt pc is %#x\n", env->pc);
+break;
+case EXCP_ALIGN:
+fprintf(stderr, "\nAlignment pc is %#x\n", env->pc);
+gdbsig = SIGBUS;
+break;
+case EXCP_ILLEGAL:
+fprintf(stderr, "\nIllegal instructionpc is %#x\n", env->pc);
+gdbsig = SIGILL;
+break;
+case EXCP_INT:
+fprintf(stderr, "\nExternal interruptpc is %#x\n", env->pc);
+break;
+case EXCP_DTLBMISS:
+case EXCP_ITLBMISS:
+printf("TLB miss\n");
+break;
+case EXCP_RANGE:
+fprintf(stderr, "\nRange\n");
+gdbsig = SIGSEGV;
+break;
+case EXCP_SYSCALL:
+env->pc += 4;   /* 0xc00; */
+env->gpr[11] = do_syscall(env,
+  env->gpr[11], /* return value   */
+  env->gpr[3],  /* r3 - r7 are params */
+  env->gpr[4],
+  env->gpr[5],
+  env->gpr[6],
+  env->gpr[7],
+  env->gpr[8], 0, 0);
+break;
+case EXCP_FPE:
+fprintf(stderr, "Floating point error\n");
+break;
+case EXCP_TRAP:
+fprintf(stderr, "Trap\n");
+gdbsig = SIGTRAP;
+break;
+case EXCP_NR:
+fprintf(stderr, "NR\n");
+break;
+default:
+fprintf(stderr, "qemu: unhandled CPU exception %#x - aborting\n", \
+

Re: [Qemu-devel] tracetool parse problem for parenthesis in format string

2012-05-17 Thread Stefan Hajnoczi
On Wed, May 02, 2012 at 10:52:07PM -0500, Bob Breuer wrote:
> The new tracetool has a problem with parsing parenthesis within the
> format string.  For example, add this line to trace-events:
> test_paren(int n) "(%d)"
> and you will get a failure when generating trace.h.

Thanks for reporting this bug.  I just got back from vacation but will
try to get a fix out if it hasn't been addressed already.

Stefan




[Qemu-devel] [PATCH 04/15] Openrisc: add interrupt support

2012-05-17 Thread Jia Liu
add the openrisc interrupt support.

Signed-off-by: Jia Liu 
---
 Makefile.target|2 +-
 target-openrisc/helper.c   |   42 +++
 target-openrisc/helper.h   |3 +++
 target-openrisc/intrp_helper.c |   53 
 target-openrisc/translate.c|2 +-
 5 files changed, 100 insertions(+), 2 deletions(-)
 create mode 100644 target-openrisc/intrp_helper.c

diff --git a/Makefile.target b/Makefile.target
index 79c75f6..975c9a8 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -101,7 +101,7 @@ endif
 libobj-$(TARGET_SPARC) += int32_helper.o
 libobj-$(TARGET_SPARC64) += int64_helper.o
 libobj-$(TARGET_ALPHA) += int_helper.o fpu_helper.o sys_helper.o mem_helper.o
-libobj-$(TARGET_OPENRISC) += mem.o mem_helper.o
+libobj-$(TARGET_OPENRISC) += intrp_helper.o mem.o mem_helper.o
 
 libobj-y += disas.o
 libobj-$(CONFIG_TCI_DIS) += tci-dis.o
diff --git a/target-openrisc/helper.c b/target-openrisc/helper.c
index dcb61c9..3aee996 100644
--- a/target-openrisc/helper.c
+++ b/target-openrisc/helper.c
@@ -64,4 +64,46 @@ CPUOPENRISCState *cpu_openrisc_init(const char *cpu_model)
 
 void do_interrupt(CPUOPENRISCState *env)
 {
+#if !defined(CONFIG_USER_ONLY)
+if (env->flags & D_FLAG) { /* Delay Slot insn */
+env->flags &= ~D_FLAG;
+env->sr |= SR_DSX;
+if (env->exception_index == EXCP_TICK||
+env->exception_index == EXCP_INT ||
+env->exception_index == EXCP_SYSCALL ||
+env->exception_index == EXCP_FPE) {
+env->epcr = env->jmp_pc;
+} else {
+env->epcr = env->pc - 4;
+}
+} else {
+if (env->exception_index == EXCP_TICK||
+env->exception_index == EXCP_INT ||
+env->exception_index == EXCP_SYSCALL ||
+env->exception_index == EXCP_FPE) {
+env->epcr = env->npc;
+} else {
+env->epcr = env->pc;
+}
+}
+
+tlb_flush(env, 1);
+
+env->esr = env->sr;
+env->sr &= ~SR_DME;
+env->sr &= ~SR_IME;
+env->sr |= SR_SM;
+env->sr &= ~SR_IEE;
+env->sr &= ~SR_TEE;
+env->map_address_data = &get_phys_nommu;
+env->map_address_code = &get_phys_nommu;
+
+if (env->exception_index > 0 && env->exception_index < EXCP_NR) {
+env->pc = env->exception_index * 0x100;
+} else {
+cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index);
+}
+#endif
+
+env->exception_index = -1;
 }
diff --git a/target-openrisc/helper.h b/target-openrisc/helper.h
index 103d9b4..bb394ad 100644
--- a/target-openrisc/helper.h
+++ b/target-openrisc/helper.h
@@ -20,4 +20,7 @@
 
 #include "def-helper.h"
 
+/* interrupt */
+DEF_HELPER_FLAGS_1(rfe, 0, void, env)
+
 #include "def-helper.h"
diff --git a/target-openrisc/intrp_helper.c b/target-openrisc/intrp_helper.c
new file mode 100644
index 000..c617068
--- /dev/null
+++ b/target-openrisc/intrp_helper.c
@@ -0,0 +1,53 @@
+/*
+ * OpenRISC interrupt helper routines
+ *
+ *  Copyright (c) 2011-2012 Jia Liu 
+ *  Feng Gao 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
+ */
+
+#include "cpu.h"
+#include "helper.h"
+
+void HELPER(rfe)(CPUOPENRISCState *env)
+{
+#if !defined(CONFIG_USER_ONLY)
+int need_flush_tlb = (env->sr & (SR_SM | SR_IME | SR_DME)) ^
+ (env->esr & (SR_SM | SR_IME | SR_DME));
+#endif
+env->pc = env->epcr;
+env->npc = env->epcr;
+env->sr = env->esr;
+
+#if !defined(CONFIG_USER_ONLY)
+if (env->sr & SR_DME) {
+env->map_address_data = &get_phys_data;
+} else {
+env->map_address_data = &get_phys_nommu;
+}
+
+if (env->sr & SR_IME) {
+env->map_address_code = &get_phys_code;
+} else {
+env->map_address_code = &get_phys_nommu;
+}
+
+if (need_flush_tlb) {
+tlb_flush(env, 1);
+}
+#endif
+env->interrupt_request |= CPU_INTERRUPT_EXITTB;
+}
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index 4828ae6..dd0240c 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -569,7 +569,7 @@ static void dec_misc(DisasContext *dc, CPUOPENRISCState 
*env, uint32_t insn)
 case 0x09:/*l.rfe*/
   

[Qemu-devel] [PATCH 15/15] Openrisc: add testcases

2012-05-17 Thread Jia Liu
add the testcases for openrisc.

Signed-off-by: Jia Liu 
---
 tests/tcg/openrisc/Makefile  |   73 
 tests/tcg/openrisc/test_add.c|   34 +
 tests/tcg/openrisc/test_addc.c   |   37 ++
 tests/tcg/openrisc/test_addi.c   |   31 
 tests/tcg/openrisc/test_addic.c  |   32 
 tests/tcg/openrisc/test_and_or.c |   61 +++
 tests/tcg/openrisc/test_bf.c |   46 ++
 tests/tcg/openrisc/test_bnf.c|   50 +++
 tests/tcg/openrisc/test_div.c|   32 
 tests/tcg/openrisc/test_extx.c   |   71 +++
 tests/tcg/openrisc/test_fx.c |   53 
 tests/tcg/openrisc/test_j.c  |   26 ++
 tests/tcg/openrisc/test_jal.c|   26 ++
 tests/tcg/openrisc/test_lf_add.c |   32 
 tests/tcg/openrisc/test_lf_div.c |   33 +
 tests/tcg/openrisc/test_lf_eqd.c |   44 +
 tests/tcg/openrisc/test_lf_eqs.c |   43 
 tests/tcg/openrisc/test_lf_ged.c |   45 +
 tests/tcg/openrisc/test_lf_ges.c |   45 +
 tests/tcg/openrisc/test_lf_gtd.c |   45 +
 tests/tcg/openrisc/test_lf_gts.c |   45 +
 tests/tcg/openrisc/test_lf_led.c |   43 
 tests/tcg/openrisc/test_lf_les.c |   45 +
 tests/tcg/openrisc/test_lf_ltd.c |   45 +
 tests/tcg/openrisc/test_lf_lts.c |   45 +
 tests/tcg/openrisc/test_lf_mul.c |   22 +
 tests/tcg/openrisc/test_lf_ned.c |   46 ++
 tests/tcg/openrisc/test_lf_nes.c |   46 ++
 tests/tcg/openrisc/test_lf_rem.c |   31 
 tests/tcg/openrisc/test_lf_sub.c |   31 
 tests/tcg/openrisc/test_logic.c  |  100 ++
 tests/tcg/openrisc/test_lx.c |   78 +
 tests/tcg/openrisc/test_movhi.c  |   30 
 tests/tcg/openrisc/test_mul.c|   47 ++
 tests/tcg/openrisc/test_sfeq.c   |   43 
 tests/tcg/openrisc/test_sfeqi.c  |   39 +++
 tests/tcg/openrisc/test_sfges.c  |   44 +
 tests/tcg/openrisc/test_sfgesi.c |   40 +++
 tests/tcg/openrisc/test_sfgeu.c  |   44 +
 tests/tcg/openrisc/test_sfgeui.c |   41 
 tests/tcg/openrisc/test_sfgts.c  |   45 +
 tests/tcg/openrisc/test_sfgtsi.c |   41 
 tests/tcg/openrisc/test_sfgtu.c  |   43 
 tests/tcg/openrisc/test_sfgtui.c |   42 
 tests/tcg/openrisc/test_sfles.c  |   26 ++
 tests/tcg/openrisc/test_sflesi.c |   39 +++
 tests/tcg/openrisc/test_sfleu.c  |   43 
 tests/tcg/openrisc/test_sfleui.c |   39 +++
 tests/tcg/openrisc/test_sflts.c  |   43 
 tests/tcg/openrisc/test_sfltsi.c |   38 +++
 tests/tcg/openrisc/test_sfltu.c  |   41 
 tests/tcg/openrisc/test_sfltui.c |   39 +++
 tests/tcg/openrisc/test_sfne.c   |   43 
 tests/tcg/openrisc/test_sfnei.c  |   38 +++
 54 files changed, 2324 insertions(+)
 create mode 100644 tests/tcg/openrisc/Makefile
 create mode 100644 tests/tcg/openrisc/test_add.c
 create mode 100644 tests/tcg/openrisc/test_addc.c
 create mode 100644 tests/tcg/openrisc/test_addi.c
 create mode 100644 tests/tcg/openrisc/test_addic.c
 create mode 100644 tests/tcg/openrisc/test_and_or.c
 create mode 100644 tests/tcg/openrisc/test_bf.c
 create mode 100644 tests/tcg/openrisc/test_bnf.c
 create mode 100644 tests/tcg/openrisc/test_div.c
 create mode 100644 tests/tcg/openrisc/test_extx.c
 create mode 100644 tests/tcg/openrisc/test_fx.c
 create mode 100644 tests/tcg/openrisc/test_j.c
 create mode 100644 tests/tcg/openrisc/test_jal.c
 create mode 100644 tests/tcg/openrisc/test_lf_add.c
 create mode 100644 tests/tcg/openrisc/test_lf_div.c
 create mode 100644 tests/tcg/openrisc/test_lf_eqd.c
 create mode 100644 tests/tcg/openrisc/test_lf_eqs.c
 create mode 100644 tests/tcg/openrisc/test_lf_ged.c
 create mode 100644 tests/tcg/openrisc/test_lf_ges.c
 create mode 100644 tests/tcg/openrisc/test_lf_gtd.c
 create mode 100644 tests/tcg/openrisc/test_lf_gts.c
 create mode 100644 tests/tcg/openrisc/test_lf_led.c
 create mode 100644 tests/tcg/openrisc/test_lf_les.c
 create mode 100644 tests/tcg/openrisc/test_lf_ltd.c
 create mode 100644 tests/tcg/openrisc/test_lf_lts.c
 create mode 100644 tests/tcg/openrisc/test_lf_mul.c
 create mode 100644 tests/tcg/openrisc/test_lf_ned.c
 create mode 100644 tests/tcg/openrisc/test_lf_nes.c
 create mode 100644 tests/tcg/openrisc/test_lf_rem.c
 create mode 100644 tests/tcg/openrisc/test_lf_sub.c
 create mode 100644 tests/tcg/openrisc/test_logic.c
 create mode 100644 tests/tcg/openrisc/test_lx.c
 create mode 100644 tests/tcg/openrisc/test_movhi.c
 create mode 100644 tests/tcg/openrisc/

Re: [Qemu-devel] Add support for new image type

2012-05-17 Thread Artyom Tarasenko
On Wed, May 16, 2012 at 9:20 PM, Kai Meyer  wrote:
> On 05/16/2012 11:48 AM, Paolo Bonzini wrote:
>>
>> Il 16/05/2012 19:06, Kai Meyer ha scritto:
>>>
>>> 1) It's been suggested to me that since we have the rights to distribute
>>> our closed source shared library, there is a precedence for being able
>>> to distributed a modified version of qemu that does run-time linking
>>> against our shared library. The absence or presence of our shared
>>> library simply enables or disables support for our file format. We are
>>> happy to make available all changes to the qemu source code, but we are
>>> not in a position to re-license our shared library's source code to a
>>> compatible GPL license. This seems to be in contradiction to Paolo's
>>> statement above, so while I can't resist asking if this is possible, I
>>> don't have any realistic expectation that this is acceptable.
>>
>> That's really getting into grey areas.  IANAL, so I cannot answer this
>> question.
>>
>> But as an aside, the GPL _does_ give you rights to distribute any
>> modification you make to QEMU.  The right questions to ask are:
>>
>> 1) a practical question: would the QEMU community accept that
>> contribution?  The answer here is "most likely not".
>>
>> 2) a legal question (i.e. the question that a court would answer): what
>> are the rights of the _recipients_ of your version (and especially of
>> the copyright holders of QEMU)?  Do they have rights to ask you for the
>> source code to the shared library, and to receive it under the GPL?
>> Again I cannot answer here (and I couldn't even if I were a lawyer).
>>
>> (Remember that however what we proposed was not just relicensing your
>> library source code, but alternatively to rewrite it from scratch with
>> no particular attention to performance.  That would be a completely
>> different story, probably also for your lawyers.  You could also share
>> any internal spec you have and hire someone to write the QEMU interface
>> for you, basically a form of clean-room reverse engineering).
>>
>>> 2) The GPL has provisions for you to create an exception where you have
>>> specified a controlled interface. Am I right that qemu has not added
>>> this controlled interface exception for file format access? What are
>>> your thoughts on adding this exception if it is not present? I would
>>> think that "struct BlockDriver" would make an excellent candidate for
>>> this.
>>
>> This would have to be applied to all files (not just block/*.c say) and
>> agreed upon by all QEMU copyright holders.  The second condition is
>> quite obvious, the first I'll spend a few more words on.
>>
>> The first condition is because the code overall can be distributed as
>> long as it fulfills all existing licenses.  QEMU right now has files
>> under BSD, GPLv2, GPLv2-or-later, LGPLv2.1-or-later and perhaps some
>> more licenses.  You can take code from individual files (or complete
>> files) and reuse it under the license indicated in the header of that
>> file.  However, you can only distribute QEMU as a whole under the
>> intersection of those licenses, which is GPLv2.  If you add another
>> license to the mix ("GPL+controlled interface") for block/*.c, QEMU as a
>> whole could still only be distributed under GPLv2.
>>
>>> On a personal note, I am an open source enthusiast, so the last thing I
>>> would want to do is to help alienate the relationship between qemu and
>>> storagecraft. I'm not asking these questions to look for a legal corner
>>> to worm my way into, but because I love open source software, and I want
>>> to learn how to play nicely. (Plus there's that virtualization
>>> "coolness" factor to this solution that I can't resist.)
>>
>> Sure, personally I appreciate your honesty even though I disagree with
>> your goal. :)
>>
>> Paolo
>
> I want to respect the lines that the GPL draws, and this helps clarify for
> me where some of those lines are. To help me better understand, what would
> be the terminology used for the explanation between what I would call
> "source code" licensing, and "project" licensing? Also, where in the code
> (or rather what file) can I see this distinction? It seems like something
> critical to be aware of, and I'd like to avoid missing something like this
> in the future as I give advice on what software we can use.
>
> Thanks for being patient with me.
>
> If you would help clarify a separate point, I would be grateful. As I
> understand it, I am able to modify qemu for my own purposes (like testing
> the filesystem integrity inside a backup image by using guestmount to mount
> it). How much of that work (source code, principles, explanations, ect) can
> I share, and with whom can I share it with?

With source code that's easy - if you  distribute qemu you have to
distribute its source code.

> For instance, would qemu be
> opposed to a StorageCraft wiki article on "How to add support for our Backup
> Images to qemu"? And would it make a difference if it was a publicly
> ac

[Qemu-devel] [PATCH 02/15] Openrisc: add MMU support

2012-05-17 Thread Jia Liu
add the openrisc MMU support.

Signed-off-by: Jia Liu 
---
 Makefile.target  |2 +
 hw/openrisc_cpudev.h |   30 ++
 hw/openrisc_pic.c|   31 ++
 target-openrisc/mem.c|  220 +-
 target-openrisc/mem_helper.c |   25 +
 5 files changed, 307 insertions(+), 1 deletion(-)
 create mode 100644 hw/openrisc_cpudev.h
 create mode 100644 hw/openrisc_pic.c

diff --git a/Makefile.target b/Makefile.target
index 0ffb29c..79c75f6 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -390,6 +390,8 @@ obj-xtensa-y += core-dc232b.o
 obj-xtensa-y += core-dc233c.o
 obj-xtensa-y += core-fsf.o
 
+obj-openrisc-y += openrisc_pic.o
+
 main.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
 
 monitor.o: hmp-commands.h qmp-commands-old.h
diff --git a/hw/openrisc_cpudev.h b/hw/openrisc_cpudev.h
new file mode 100644
index 000..ca7d064
--- /dev/null
+++ b/hw/openrisc_cpudev.h
@@ -0,0 +1,30 @@
+/*
+ * Qemu Openrisc CPU device support.
+ *
+ *  Copyright (c) 2011-2012 Jia Liu 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
+ */
+
+#ifndef HW_OPENRISC_CPUDEV_H
+#define HW_OPENRISC_CPUDEV_H
+
+/* openrisc_pic.c */
+void cpu_openrisc_pic_init(CPUOPENRISCState *env);
+
+/* openrisc_timer.c*/
+void cpu_openrisc_clock_init(CPUOPENRISCState *env);
+
+#endif
diff --git a/hw/openrisc_pic.c b/hw/openrisc_pic.c
new file mode 100644
index 000..0abdd50
--- /dev/null
+++ b/hw/openrisc_pic.c
@@ -0,0 +1,31 @@
+/*
+ * Generic  OPENRISC Programmable Interrupt Controller support.
+ *
+ *  Copyright (c) 2011-2012 Jia Liu 
+ *  Feng Gao 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
+ */
+
+#include "hw.h"
+#include "openrisc_cpudev.h"
+#include "cpu.h"
+
+/* Reset PIC */
+void cpu_openrisc_pic_reset(CPUOPENRISCState *env)
+{
+env->picmr = 0x;
+env->picsr = 0x;
+}
diff --git a/target-openrisc/mem.c b/target-openrisc/mem.c
index 57a0b1b..b26da38 100644
--- a/target-openrisc/mem.c
+++ b/target-openrisc/mem.c
@@ -28,10 +28,224 @@
 #endif
 
 #if !defined(CONFIG_USER_ONLY)
+enum {
+TLBRET_INVALID = -3,
+TLBRET_NOMATCH = -2,
+TLBRET_BADADDR = -1,
+TLBRET_MATCH = 0
+};
+
+tlb_entry itlb_table[ITLB_WAYS][ITLB_SIZE];
+tlb_entry dtlb_table[DTLB_WAYS][DTLB_SIZE];
+#endif
+
+#if !defined(CONFIG_USER_ONLY)
+/* no MMU emulation */
+int get_phys_nommu(CPUOPENRISCState *env, target_phys_addr_t *physical,
+   int *prot, target_ulong address, int rw)
+{
+*physical = address;
+*prot = PAGE_READ | PAGE_WRITE;
+return TLBRET_MATCH;
+}
+int get_phys_code(CPUOPENRISCState *env, target_phys_addr_t *physical,
+  int *prot, target_ulong address, int rw)
+{
+int vpn = address >> TARGET_PAGE_BITS;
+int idx = vpn & ITLB_MASK;
+int right = 0;
+
+if ((env->itlb[0][idx].mr >> TARGET_PAGE_BITS) != vpn) {
+return TLBRET_NOMATCH;
+}
+if (!(env->itlb[0][idx].mr & 1)) {
+return TLBRET_INVALID;
+}
+
+if (env->sr & SR_SM) { /* supervisor mode */
+if (env->itlb[0][idx].tr & SXE) {
+right |= PAGE_EXEC;
+}
+} else {
+if (env->itlb[0][idx].tr & UXE) {
+right |= PAGE_EXEC;
+}
+}
+
+if ((rw & 2) && ((right & PAGE_EXEC) == 0)) {
+return TLBRET_BADADDR;
+}
+
+*physical = (env->itlb[0][idx].tr & TARGET_PAGE_MASK) |
+(address & (TARGET_PAGE_SIZE-1));
+*prot = right;
+return TLBRET_MATCH;
+}
+
+int get_phys_data(CPUOPENRISCState *env, target_phys_addr_t *physical,
+  

Re: [Qemu-devel] [PATCH 26/27] blockdev: Collect block device code in new blockdev.c

2012-05-17 Thread Artyom Tarasenko
On Wed, Dec 15, 2010 at 4:31 PM, Kevin Wolf  wrote:
> Am 15.12.2010 16:04, schrieb Artyom Tarasenko:
>> On Fri, Jun 4, 2010 at 6:33 PM, Kevin Wolf  wrote:
>>> From: Markus Armbruster 
>>>
>>> Anything that moves hundreds of lines out of vl.c can't be all bad.
>>
>> I know I'm late for this train, but why does this patch change the
>> license of the former vl.c code from a BSD-like one to GPLv2?
>> It seems to be contradicting the vl.c paragraph:
>>
>>  * The above copyright notice and this permission notice shall be included in
>>  * all copies or substantial portions of the Software.
>
> Right, I think this needs to fixed. Markus, can you send a patch?

Ping?

-- 
Regards,
Artyom Tarasenko

solaris/sparc under qemu blog: http://tyom.blogspot.com/search/label/qemu



[Qemu-devel] [RFC:kvm] export host NUMA info to guest & make emulated device NUMA attr

2012-05-17 Thread Liu Ping Fan
Currently, the guest can not know the NUMA info of the vcpu, which will
result in performance drawback.

This is the discovered and experiment by
Shirley Ma 
Krishna Kumar 
Tom Lendacky 
Refer to - http://www.mail-archive.com/kvm@vger.kernel.org/msg69868.html
we can see the big perfermance gap between NUMA aware and unaware.

Enlightened by their discovery, I think, we can do more work -- that is to
export NUMA info of host to guest.

So here comes the idea:
1. export host numa info through guest's sched domain to its scheduler
  Export vcpu's NUMA info to guest scheduler(I think mem NUMA problem
  has been handled by host).  So the guest's lb will consider the cost.
  I am still working on this, and my original idea is to export these info
  through "static struct sched_domain_topology_level *sched_domain_topology"
  to guest.

2. Do a better emulation of virt mach exported to guest.
  In real world, the devices are limited by kinds of reasons to own the NUMA
  property. But as to Qemu, the device is emulated by thread, which inherit
  the NUMA attr in nature.  We can implement the device as components of many
  logic units, each of the unit is backed by a thread in different host node.
  Currently, I want to start the work on vhost. But I think, maybe in
  future, the iothread in Qemu can also has such attr.


Forgive me, for the limited time, I can not have more better understand of
vhost/virtio_net drivers. These patches are just draft, _FAR_, _FAR_ from work.
I will do more detail work for them in future.

To easy the review, the following is the sum up of the 2nd point of the idea.
As for the 1st point of the idea, it is not reflected in the patches.

--spread/shrink the vhost_workers over the host nodes as demanded from Qemu.
  And we can consider each vhost_worker as an independent net logic device
  embeded in physical device "vhost_net".  At the meanwhile, we spread vcpu
  threads over the host node. 
  The vrings on guest are allocated PAGE_SIZE align separately, so they can 
  will only be mapped into different host node, so vhost_worker in the same
  node can access it with the least cost. So does the vq on guest.

--virtio_net driver will changes and talk with the logic device. And which
  logic device it will talk to is determined by on which vcpu it is scheduled.

--the binding of vcpus and vhost_worker is implemented by: 
  for call direction, vq-a in the node-A will have a dedicated irq-a. And 
  we set the irq-a's affinity to vcpus in node-A.
  for kick direction, kick register-b trigger different eventfd-b which wake up
  vhost_worker-b.


Please give some comments and suggestion.

Thanks and regards,
pingfan




[Qemu-devel] [PATCH 2/2] [net/virtio_net]: make virtio_net support NUMA info

2012-05-17 Thread Liu Ping Fan
From: Liu Ping Fan 

Vhost net uses separate transfer logic unit in different node.
Virtio net must determine which logic unit it will talk with,
so we can improve the performance.

Signed-off-by: Liu Ping Fan 
---
 drivers/net/virtio_net.c |  425 ++
 1 files changed, 314 insertions(+), 111 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index af8acc8..31abafa 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -50,16 +50,32 @@ struct virtnet_stats {
u64 rx_packets;
 };
 
+struct napi_info {
+   struct napi_struct napi;
+   struct work_struct enable_napi;
+};
+
+struct vnet_virtio_node {
+   struct virtio_node vnode;
+   int demo_cpu;
+   struct napi_info info;
+   struct delayed_work refill;
+   struct virtnet_info *owner;
+};
+
 struct virtnet_info {
struct virtio_device *vdev;
-   struct virtqueue *rvq, *svq, *cvq;
+   /* we want to scatter in different host nodes */
+   struct virtqueue **vqs, **rvqs, **svqs;
+   struct virtqueue *cvq;
+   /* we want to scatter in different host nodes */
+   struct vnet_virtio_node **vnet_nodes;
struct net_device *dev;
-   struct napi_struct napi;
+
unsigned int status;
 
/* Number of input buffers, and max we've ever had. */
unsigned int num, max;
-
/* I like... big packets and I cannot lie! */
bool big_packets;
 
@@ -69,9 +85,6 @@ struct virtnet_info {
/* Active statistics */
struct virtnet_stats __percpu *stats;
 
-   /* Work struct for refilling if we run low on memory. */
-   struct delayed_work refill;
-
/* Chain pages by the private ptr. */
struct page *pages;
 
@@ -136,7 +149,6 @@ static void skb_xmit_done(struct virtqueue *svq)
 
/* Suppress further interrupts. */
virtqueue_disable_cb(svq);
-
/* We were probably waiting for more output buffers. */
netif_wake_queue(vi->dev);
 }
@@ -220,7 +232,8 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi,
return skb;
 }
 
-static int receive_mergeable(struct virtnet_info *vi, struct sk_buff *skb)
+static int receive_mergeable(struct virtnet_info *vi, struct sk_buff *skb,
+   struct virtqueue *rvq)
 {
struct skb_vnet_hdr *hdr = skb_vnet_hdr(skb);
struct page *page;
@@ -234,7 +247,7 @@ static int receive_mergeable(struct virtnet_info *vi, 
struct sk_buff *skb)
skb->dev->stats.rx_length_errors++;
return -EINVAL;
}
-   page = virtqueue_get_buf(vi->rvq, &len);
+   page = virtqueue_get_buf(rvq, &len);
if (!page) {
pr_debug("%s: rx error: %d buffers missing\n",
 skb->dev->name, hdr->mhdr.num_buffers);
@@ -252,7 +265,8 @@ static int receive_mergeable(struct virtnet_info *vi, 
struct sk_buff *skb)
return 0;
 }
 
-static void receive_buf(struct net_device *dev, void *buf, unsigned int len)
+static void receive_buf(struct net_device *dev, void *buf, unsigned int len,
+   struct virtqueue *rvq)
 {
struct virtnet_info *vi = netdev_priv(dev);
struct virtnet_stats *stats = this_cpu_ptr(vi->stats);
@@ -283,7 +297,7 @@ static void receive_buf(struct net_device *dev, void *buf, 
unsigned int len)
return;
}
if (vi->mergeable_rx_bufs)
-   if (receive_mergeable(vi, skb)) {
+   if (receive_mergeable(vi, skb, rvq)) {
dev_kfree_skb(skb);
return;
}
@@ -353,7 +367,67 @@ frame_err:
dev_kfree_skb(skb);
 }
 
-static int add_recvbuf_small(struct virtnet_info *vi, gfp_t gfp)
+/* todo, this will be redesign, and as a part of exporting host numa info to
+  * guest scheduler  */
+/* fix me, host numa node id directly exposed to guest? */
+
+/* fill in by host */
+static s16 __vapicid_to_vnode[MAX_LOCAL_APIC];
+/* fix me, HOST_NUMNODES is defined by host */
+#define  HOST_NUMNODES  128
+static struct cpumask vnode_to_vcpumask_map[HOST_NUMNODES];
+DECLARE_PER_CPU(int, vcpu_to_vnode_map);
+
+void init_vnode_map(void)
+{
+   int cpu, apicid, vnode;
+   for_each_possible_cpu(cpu) {
+   apicid = cpu_physical_id(cpu);
+   vnode = __vapicid_to_vnode[apicid];
+   per_cpu(vcpu_to_vnode_map, cpu) = vnode;
+   }
+}
+
+struct cpumask *vnode_to_vcpumask(int virtio_node)
+{
+   struct cpumask *msk = &vnode_to_vcpumask_map[virtio_node];
+   return msk;
+}
+
+static int first_vcpu_on_virtio_node(int virtio_node)
+{
+struct cpumask *msk = vnode_to_vcpumask(virtio_node);
+return cpumask_first(msk);
+}
+
+static int vcpu_to_virtio_node(void)
+{
+   int vnode = __get_cpu_var(vcpu_to_vnode_map);
+   retur

[Qemu-devel] [PATCH 1/2] [kvm/virtio]: make virtio support NUMA attr

2012-05-17 Thread Liu Ping Fan
From: Liu Ping Fan 

For each numa node reported by vhost, we alloc a pair of i/o vq,
and assign them msix IRQ, and set irq affinity to a set of vcpu
in the same node.
Also we alloc vqs on PAGE_SIZE align, so they will be allocated by
host when pg fault happen on different node.

Signed-off-by: Liu Ping Fan 
---
 drivers/virtio/virtio.c   |2 +-
 drivers/virtio/virtio_pci.c   |   35 +--
 drivers/virtio/virtio_ring.c  |9 ++---
 include/linux/virtio.h|9 +
 include/linux/virtio_config.h |1 +
 include/linux/virtio_pci.h|9 +
 6 files changed, 59 insertions(+), 6 deletions(-)

diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index 984c501..79e873f 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -136,7 +136,7 @@ static int virtio_dev_probe(struct device *_d)
set_bit(i, dev->features);
 
dev->config->finalize_features(dev);
-
+   dev->config->get_numa_map(dev);
err = drv->probe(dev);
if (err)
add_status(dev, VIRTIO_CONFIG_S_FAILED);
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c
index 2e03d41..5bb8a97 100644
--- a/drivers/virtio/virtio_pci.c
+++ b/drivers/virtio/virtio_pci.c
@@ -129,6 +129,24 @@ static void vp_finalize_features(struct virtio_device 
*vdev)
iowrite32(vdev->features[0], vp_dev->ioaddr+VIRTIO_PCI_GUEST_FEATURES);
 }
 
+static void vp_get_numa_map(struct virtio_device *vdev)
+{
+   int i, cnt,  sz = 32;
+   int cur, prev = 0;
+   struct virtio_pci_device *vp_dev = to_vp_device(vdev);
+
+   /* We only support 32 numa bits. */
+   vdev->allow_map = ioread32(vp_dev->ioaddr+VIRTIO_PCI_NUMA_MAP);
+   for (i = 0; i < sz; i++) {
+   cur = find_next_bit(&vdev->allow_map, sz, prev);
+   prev = cur;
+   if (cur >= sz)
+   break;
+   cnt++;
+   }
+   vdev->node_cnt = cnt;
+}
+
 /* virtio config->get() implementation */
 static void vp_get(struct virtio_device *vdev, unsigned offset,
   void *buf, unsigned len)
@@ -516,6 +534,8 @@ static int vp_try_to_find_vqs(struct virtio_device *vdev, 
unsigned nvqs,
struct virtio_pci_device *vp_dev = to_vp_device(vdev);
u16 msix_vec;
int i, err, nvectors, allocated_vectors;
+   int irq, next, prev = 0;
+   struct cpumask *mask;
 
if (!use_msix) {
/* Old style: one normal interrupt for change and all vqs. */
@@ -562,14 +582,24 @@ static int vp_try_to_find_vqs(struct virtio_device *vdev, 
unsigned nvqs,
 sizeof *vp_dev->msix_names,
 "%s-%s",
 dev_name(&vp_dev->vdev.dev), names[i]);
-   err = request_irq(vp_dev->msix_entries[msix_vec].vector,
- vring_interrupt, 0,
+   irq = vp_dev->msix_entries[msix_vec].vector;
+   err = request_irq(irq, vring_interrupt, 0,
  vp_dev->msix_names[msix_vec],
  vqs[i]);
if (err) {
vp_del_vq(vqs[i]);
goto error_find;
}
+   if (i == vdev->node_cnt)
+   prev = 0;
+   /* fix me the @size */
+   next = find_next_bit(vdev->allow_map, 64, prev);
+   prev = next;
+   if (next < 64) {
+   mask = vnode_to_vcpumask(next);
+   mask = cpumask_and(mask, cpu_online_mask, mask);
+   irq_set_affinity(irq, mask);
+   }
}
return 0;
 
@@ -619,6 +649,7 @@ static struct virtio_config_ops virtio_pci_config_ops = {
.del_vqs= vp_del_vqs,
.get_features   = vp_get_features,
.finalize_features = vp_finalize_features,
+   .get_numa_map = vp_get_numa_map,
.bus_name   = vp_bus_name,
 };
 
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 5aa43c3..5baa949 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -626,15 +626,18 @@ struct virtqueue *vring_new_virtqueue(unsigned int num,
  const char *name)
 {
struct vring_virtqueue *vq;
-   unsigned int i;
+   unsigned int i, size, max;
 
/* We assume num is a power of 2. */
if (num & (num - 1)) {
dev_warn(&vdev->dev, "Bad virtqueue length %u\n", num);
return NULL;
}
-
-   vq = kmalloc(sizeof(*vq) + sizeof(void *)*num, GFP_KERNEL);
+   size = PAGE_ALIGN (sizeof(*vq) + sizeof(void *)*num);
+   /* Allocate on PAGE boundary, so host can locate them at proper
+* node
+*/
+   vq = kmalloc(size, GFP_KERNEL);
if (!vq)
return NULL;
 
diff --git a/inc

[Qemu-devel] Signal management in qemu-user

2012-05-17 Thread Alex Barcelo
I'm working in a "big" (=complex, strange) project[1] and come across a bug
in signal management. I have been able to narrow it down to this program:

#include 
#include 
#include 
#include 
#include 
#include 

unsigned char *testfun;

int main ( void )
{
unsigned int ra;
testfun=memalign(getpagesize(),1024);
// We block the SIGSEGV signal, used by qemu-user
sigset_t set;
sigemptyset(&set);
sigaddset(&set, 11);
sigprocmask(SIG_BLOCK, &set, NULL);
mprotect(testfun, 1024, PROT_READ|PROT_EXEC|PROT_WRITE);

//400687: b8 0d 00 00 00  mov$0xd,%eax
//40068d: c3  retq
testfun[ 0]=0xb8;
testfun[ 1]=0x0d;
testfun[ 2]=0x00;
testfun[ 3]=0x00;
testfun[ 4]=0x00;
testfun[ 5]=0xc3;
printf ( "0x%02X\n",
 ((unsigned int (*)())testfun)() );

//400687: b8 20 00 00 00  mov$0x20,%eax
//40068d: c3  retq
// This self-modifying code will break because of the sigsegv signal
block
testfun[ 1]=0x20;
printf ( "0x%02X\n",
 ((unsigned int (*)())testfun)() );
}

Running it in a i386 machine works and gives an output of "0x0d\n0x20".
Running it in a qemu-i386 segfaults. Because the self-modifying code raises
a SIGSEGV in the qemu (I understand that it is the method used by qemu to
handle self-modifying code). But the sigprocmask disables the SIGSEGV and
the qemu-user... does nothing to avoid it. So the SIGSEGV is unmanaged and
breaks the program.

I will work in this bug (assuming that nobody is working on it). I suppose
that I have to make qemu aware of the signals on the guest and the signals
on himself. And do NOT allow the guest doing dangerous manipulations
(intercepting the syscall).

Is there something I have to take into acoount? Am I right in my
assumptions? Some guru to give me some advice ;) ?

[1] The project is puting a qemu-system-i386 crosscompiled in a qemu-ppc.
The "first guest" has LOTS of self-modifying code (qemu-system). I have
been bughunting to achieve this "qemu-tower". And correct signal management
is a must (as qemu uses lots of signal management, and an incomplete
implementation on qemu-user means segfault and things breaking).


[Qemu-devel] [PATCH 06/15] Openrisc: add int instruction helpers

2012-05-17 Thread Jia Liu
add the openrisc int instruction helpers.

Signed-off-by: Jia Liu 
---
 Makefile.target  |2 +-
 target-openrisc/helper.h |7 +++
 target-openrisc/int_helper.c |  126 ++
 target-openrisc/translate.c  |   14 ++---
 4 files changed, 141 insertions(+), 8 deletions(-)
 create mode 100644 target-openrisc/int_helper.c

diff --git a/Makefile.target b/Makefile.target
index ed5f0b0..9bebdb3 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -101,7 +101,7 @@ endif
 libobj-$(TARGET_SPARC) += int32_helper.o
 libobj-$(TARGET_SPARC64) += int64_helper.o
 libobj-$(TARGET_ALPHA) += int_helper.o fpu_helper.o sys_helper.o mem_helper.o
-libobj-$(TARGET_OPENRISC) += excp.o excp_helper.o intrp_helper.o mem.o 
mem_helper.o
+libobj-$(TARGET_OPENRISC) += excp.o excp_helper.o int_helper.o intrp_helper.o 
mem.o mem_helper.o
 
 libobj-y += disas.o
 libobj-$(CONFIG_TCI_DIS) += tci-dis.o
diff --git a/target-openrisc/helper.h b/target-openrisc/helper.h
index a0fb8c4..f5ed117 100644
--- a/target-openrisc/helper.h
+++ b/target-openrisc/helper.h
@@ -23,6 +23,13 @@
 /* exception */
 DEF_HELPER_FLAGS_2(exception, 0, void, env, i32)
 
+/* int */
+DEF_HELPER_FLAGS_1(ff1, 0, tl, tl)
+DEF_HELPER_FLAGS_1(fl1, 0, tl, tl)
+DEF_HELPER_FLAGS_3(add, 0, tl, env, tl, tl)
+DEF_HELPER_FLAGS_3(addc, 0, tl, env, tl, tl)
+DEF_HELPER_FLAGS_3(sub, 0, tl, env, tl, tl)
+
 /* interrupt */
 DEF_HELPER_FLAGS_1(rfe, 0, void, env)
 
diff --git a/target-openrisc/int_helper.c b/target-openrisc/int_helper.c
new file mode 100644
index 000..540b941
--- /dev/null
+++ b/target-openrisc/int_helper.c
@@ -0,0 +1,126 @@
+/*
+ * OpenRISC int helper routines
+ *
+ *  Copyright (c) 2011-2012 Jia Liu 
+ *  Feng Gao 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
+ */
+
+#include "cpu.h"
+#include "helper.h"
+#include "excp.h"
+
+target_ulong HELPER(ff1)(target_ulong x)
+{
+target_ulong n = 0;
+
+if (x == 0) {
+return 0;
+}
+
+for (n = 32; x; n--) {
+x <<= 1;
+}
+return n+1;
+}
+
+target_ulong HELPER(fl1)(target_ulong x)
+{
+target_ulong n = 0;
+
+if (x == 0) {
+return 0;
+}
+
+for (n = 0; x; n++) {
+x >>= 1;
+}
+return n;
+}
+
+/* l.add, l.addc, l.addi, l.addic, l.sub.  for overflow exception.  */
+target_ulong HELPER(add)(CPUOPENRISCState * env, target_ulong a, target_ulong 
b)
+{
+target_ulong result;
+result = a + b;
+
+if (result < a) {
+env->sr |= SR_CY;
+} else {
+env->sr &= ~SR_CY;
+}
+
+if ((a ^ b ^ -1) & (a ^ result)) {
+env->sr |= SR_OV;
+if (env->sr & SR_OVE) {
+raise_exception(env, EXCP_RANGE);
+}
+} else {
+env->sr &= ~SR_OV;
+}
+return result;
+}
+
+target_ulong HELPER(addc)(CPUOPENRISCState * env,
+  target_ulong a, target_ulong b)
+{
+target_ulong result;
+int cf = env->sr & SR_CY;
+
+if (!cf) {
+result = a + b;
+cf = result < a;
+} else {
+result = a + b + 1;
+cf = result <= a;
+}
+
+if (cf) {
+env->sr |= SR_CY;
+} else {
+env->sr &= ~SR_CY;
+}
+
+if ((a ^ b ^ -1) & (a ^ result)) {
+env->sr |= SR_OV;
+if (env->sr & SR_OVE) {
+raise_exception(env, EXCP_RANGE);
+}
+} else {
+env->sr &= ~SR_OV;
+}
+return result;
+}
+
+target_ulong HELPER(sub)(CPUOPENRISCState * env, target_ulong a, target_ulong 
b)
+{
+target_ulong result;
+result = a - b;
+if (a >= b) {
+env->sr |= SR_CY;
+} else {
+env->sr &= ~SR_CY;
+}
+
+if ((a ^ b) & (a ^ result)) {
+env->sr |= SR_OV;
+if (env->sr & SR_OVE) {
+raise_exception(env, EXCP_RANGE);
+}
+} else {
+env->sr &= ~SR_OV;
+}
+return result;
+}
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index a1264c9..dffc8a7 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -203,7 +203,7 @@ static void dec_calc(DisasContext *dc, CPUOPENRISCState 
*env, uint32_t insn)
 switch (op1) {
 case 0x00: /*l.add*/
 LOG_DIS("l.add r%d, r%d, r%d\n", rd, ra, rb);
- 

[Qemu-devel] [PATCH 05/15] Openrisc: add exception support

2012-05-17 Thread Jia Liu
add the openrisc exception support.

Signed-off-by: Jia Liu 
---
 Makefile.target   |2 +-
 target-openrisc/excp.c|   27 +++
 target-openrisc/excp.h|   28 
 target-openrisc/excp_helper.c |   28 
 target-openrisc/helper.h  |3 +++
 target-openrisc/translate.c   |   25 -
 6 files changed, 103 insertions(+), 10 deletions(-)
 create mode 100644 target-openrisc/excp.c
 create mode 100644 target-openrisc/excp.h
 create mode 100644 target-openrisc/excp_helper.c

diff --git a/Makefile.target b/Makefile.target
index 975c9a8..ed5f0b0 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -101,7 +101,7 @@ endif
 libobj-$(TARGET_SPARC) += int32_helper.o
 libobj-$(TARGET_SPARC64) += int64_helper.o
 libobj-$(TARGET_ALPHA) += int_helper.o fpu_helper.o sys_helper.o mem_helper.o
-libobj-$(TARGET_OPENRISC) += intrp_helper.o mem.o mem_helper.o
+libobj-$(TARGET_OPENRISC) += excp.o excp_helper.o intrp_helper.o mem.o 
mem_helper.o
 
 libobj-y += disas.o
 libobj-$(CONFIG_TCI_DIS) += tci-dis.o
diff --git a/target-openrisc/excp.c b/target-openrisc/excp.c
new file mode 100644
index 000..fc9391a
--- /dev/null
+++ b/target-openrisc/excp.c
@@ -0,0 +1,27 @@
+/*
+ *  Openrisc exception.
+ *
+ *  Copyright (c) 2011-2012 Jia Liu 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#include "cpu.h"
+#include "excp.h"
+
+void raise_exception(CPUOPENRISCState *env, uint32_t excp)
+{
+env->exception_index = excp;
+cpu_loop_exit(env);
+}
diff --git a/target-openrisc/excp.h b/target-openrisc/excp.h
new file mode 100644
index 000..4c32e46
--- /dev/null
+++ b/target-openrisc/excp.h
@@ -0,0 +1,28 @@
+/*
+ *  Openrisc exception header.
+ *
+ *  Copyright (c) 2011-2012 Jia Liu 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#ifndef QEMU_OPENRISC_EXCP_H
+#define QEMU_OPENRISC_EXCP_H
+
+#include "cpu.h"
+#include "qemu-common.h"
+
+void raise_exception(CPUOPENRISCState *env, uint32_t excp);
+
+#endif /* QEMU_OPENRISC_EXCP_H */
diff --git a/target-openrisc/excp_helper.c b/target-openrisc/excp_helper.c
new file mode 100644
index 000..0cad14b
--- /dev/null
+++ b/target-openrisc/excp_helper.c
@@ -0,0 +1,28 @@
+/*
+ * OpenRISC exception helper routines
+ *
+ *  Copyright (c) 2011-2012 Jia Liu 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
+ */
+
+#include "cpu.h"
+#include "helper.h"
+#include "excp.h"
+
+void HELPER(exception)(CPUOPENRISCState *env, uint32_t excp)
+{
+raise_exception(env, excp);
+}
diff --git a/target-openrisc/helper.h b/target-openrisc/helper.h
index bb394ad..a0fb8c4 100644
--- a/target-openrisc/helper.h
+++ b/target-openrisc/helper.h
@@ -20,6 +20,9 @@
 
 #include "def-helper.h"
 
+/* exception */
+DEF_HELPER_FLAGS_2(exception, 0, void, env, i32)
+
 /* interrupt */
 DEF_HELPER_FLAGS_1(rfe, 0, void, env)
 
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index dd0240c..a1264c9 100644
--- a/target-openr

[Qemu-devel] [PATCH 1/2] [kvm/vhost]: make vhost support NUMA model.

2012-05-17 Thread Liu Ping Fan
From: Liu Ping Fan 

Make vhost allocate vhost_virtqueue on different host nodes as required.

Signed-off-by: Liu Ping Fan 
---
 drivers/vhost/vhost.c |  380 +++--
 drivers/vhost/vhost.h |   41 --
 include/linux/vhost.h |2 +-
 3 files changed, 304 insertions(+), 119 deletions(-)

diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 51e4c1e..b0d2855 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -37,12 +38,11 @@ enum {
VHOST_MEMORY_F_LOG = 0x1,
 };
 
-static unsigned vhost_zcopy_mask __read_mostly;
 
 #define vhost_used_event(vq) ((u16 __user *)&vq->avail->ring[vq->num])
 #define vhost_avail_event(vq) ((u16 __user *)&vq->used->ring[vq->num])
 
-static void vhost_poll_func(struct file *file, wait_queue_head_t *wqh,
+void vhost_poll_func(struct file *file, wait_queue_head_t *wqh,
poll_table *pt)
 {
struct vhost_poll *poll;
@@ -75,12 +75,12 @@ static void vhost_work_init(struct vhost_work *work, 
vhost_work_fn_t fn)
 
 /* Init poll structure */
 void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t fn,
-unsigned long mask, struct vhost_dev *dev)
+unsigned long mask, struct vhost_sub_dev *dev)
 {
init_waitqueue_func_entry(&poll->wait, vhost_poll_wakeup);
init_poll_funcptr(&poll->table, vhost_poll_func);
poll->mask = mask;
-   poll->dev = dev;
+   poll->subdev = dev;
 
vhost_work_init(&poll->work, fn);
 }
@@ -103,7 +103,7 @@ void vhost_poll_stop(struct vhost_poll *poll)
remove_wait_queue(poll->wqh, &poll->wait);
 }
 
-static bool vhost_work_seq_done(struct vhost_dev *dev, struct vhost_work *work,
+static bool vhost_work_seq_done(struct vhost_sub_dev *dev, struct vhost_work 
*work,
unsigned seq)
 {
int left;
@@ -114,19 +114,19 @@ static bool vhost_work_seq_done(struct vhost_dev *dev, 
struct vhost_work *work,
return left <= 0;
 }
 
-static void vhost_work_flush(struct vhost_dev *dev, struct vhost_work *work)
+static void vhost_work_flush(struct vhost_sub_dev *sub, struct vhost_work 
*work)
 {
unsigned seq;
int flushing;
 
-   spin_lock_irq(&dev->work_lock);
+   spin_lock_irq(&sub->work_lock);
seq = work->queue_seq;
work->flushing++;
-   spin_unlock_irq(&dev->work_lock);
-   wait_event(work->done, vhost_work_seq_done(dev, work, seq));
-   spin_lock_irq(&dev->work_lock);
+   spin_unlock_irq(&sub->work_lock);
+   wait_event(work->done, vhost_work_seq_done(sub, work, seq));
+   spin_lock_irq(&sub->work_lock);
flushing = --work->flushing;
-   spin_unlock_irq(&dev->work_lock);
+   spin_unlock_irq(&sub->work_lock);
BUG_ON(flushing < 0);
 }
 
@@ -134,26 +134,26 @@ static void vhost_work_flush(struct vhost_dev *dev, 
struct vhost_work *work)
  * locks that are also used by the callback. */
 void vhost_poll_flush(struct vhost_poll *poll)
 {
-   vhost_work_flush(poll->dev, &poll->work);
+   vhost_work_flush(poll->subdev, &poll->work);
 }
 
-static inline void vhost_work_queue(struct vhost_dev *dev,
+static inline void vhost_work_queue(struct vhost_sub_dev *sub,
struct vhost_work *work)
 {
unsigned long flags;
 
-   spin_lock_irqsave(&dev->work_lock, flags);
+   spin_lock_irqsave(&sub->work_lock, flags);
if (list_empty(&work->node)) {
-   list_add_tail(&work->node, &dev->work_list);
+   list_add_tail(&work->node, &sub->work_list);
work->queue_seq++;
-   wake_up_process(dev->worker);
+   wake_up_process(sub->worker);
}
-   spin_unlock_irqrestore(&dev->work_lock, flags);
+   spin_unlock_irqrestore(&sub->work_lock, flags);
 }
 
 void vhost_poll_queue(struct vhost_poll *poll)
 {
-   vhost_work_queue(poll->dev, &poll->work);
+   vhost_work_queue(poll->subdev, &poll->work);
 }
 
 static void vhost_vq_reset(struct vhost_dev *dev,
@@ -188,7 +188,8 @@ static void vhost_vq_reset(struct vhost_dev *dev,
 
 static int vhost_worker(void *data)
 {
-   struct vhost_dev *dev = data;
+   struct vhost_sub_dev *sub = data;
+   struct vhost_dev *dev = sub->owner;
struct vhost_work *work = NULL;
unsigned uninitialized_var(seq);
 
@@ -198,7 +199,7 @@ static int vhost_worker(void *data)
/* mb paired w/ kthread_stop */
set_current_state(TASK_INTERRUPTIBLE);
 
-   spin_lock_irq(&dev->work_lock);
+   spin_lock_irq(&sub->work_lock);
if (work) {
work->done_seq = seq;
if (work->flushing)
@@ -206,18 +207,18 @@ static int vhost_worker(void *data)
}
 
if (kthread_should_stop()) {
-  

[Qemu-devel] [PATCH 08/15] Openrisc: add programmable interrupt controller support

2012-05-17 Thread Jia Liu
add the openrisc programmable interrupt controller support.

Signed-off-by: Jia Liu 
---
 cpu-exec.c|   17 +
 hw/openrisc_pic.c |   48 
 2 files changed, 65 insertions(+)

diff --git a/cpu-exec.c b/cpu-exec.c
index ba10db1..845b2ae 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -375,6 +375,23 @@ int cpu_exec(CPUArchState *env)
 do_interrupt(env);
 next_tb = 0;
 }
+#elif defined(TARGET_OPENRISC)
+{
+int idx = -1;
+if ((interrupt_request & CPU_INTERRUPT_HARD)
+&& (env->sr & SR_IEE)) {
+idx = EXCP_INT;
+}
+if ((interrupt_request & CPU_INTERRUPT_TIMER)
+&& (env->sr & SR_TEE)) {
+idx = EXCP_TICK;
+}
+if (idx >= 0) {
+env->exception_index = idx;
+do_interrupt(env);
+next_tb = 0;
+}
+}
 #elif defined(TARGET_SPARC)
 if (interrupt_request & CPU_INTERRUPT_HARD) {
 if (cpu_interrupts_enabled(env) &&
diff --git a/hw/openrisc_pic.c b/hw/openrisc_pic.c
index 0abdd50..52e48ec 100644
--- a/hw/openrisc_pic.c
+++ b/hw/openrisc_pic.c
@@ -29,3 +29,51 @@ void cpu_openrisc_pic_reset(CPUOPENRISCState *env)
 env->picmr = 0x;
 env->picsr = 0x;
 }
+
+/* openrisc pic handler */
+static void openrisc_pic_cpu_handler(void *opaque, int irq, int level)
+{
+CPUOPENRISCState *env = (CPUOPENRISCState *)opaque;
+int i;
+uint32_t irq_bit = 1 << irq;
+
+if (irq > 31 || irq < 0) {
+return;
+}
+
+if (level) {
+env->picsr |= irq_bit;
+} else {
+env->picsr &= ~irq_bit;
+}
+
+for (i = 0; i < 32; i++) {
+if ((env->picsr && (1 << i)) && (env->picmr && (1 << i))) {
+cpu_interrupt(env, CPU_INTERRUPT_HARD);
+} else {
+cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
+env->picsr &= ~(1 << i);
+}
+}
+}
+
+void cpu_openrisc_pic_init(CPUOPENRISCState *env)
+{
+int i;
+qemu_irq *qi;
+qi = qemu_allocate_irqs(openrisc_pic_cpu_handler, env, NR_IRQS);
+
+for (i = 0; i < NR_IRQS; i++) {
+env->irq[i] = qi[i];
+}
+}
+
+void cpu_openrisc_store_picmr(CPUOPENRISCState *env, uint32_t value)
+{
+env->picmr |= value;
+}
+
+void cpu_openrisc_store_picsr(CPUOPENRISCState *env, uint32_t value)
+{
+env->picsr &= ~value;
+}
-- 
1.7.9.5




[Qemu-devel] [PATCH 10/15] Openrisc: add a simulation board

2012-05-17 Thread Jia Liu
add a simulation board for openrisc.

Signed-off-by: Jia Liu 
---
 Makefile.target   |1 +
 hw/openrisc_sim.c |  140 +
 2 files changed, 141 insertions(+)
 create mode 100644 hw/openrisc_sim.c

diff --git a/Makefile.target b/Makefile.target
index 6b1d2d0..433dd3c 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -391,6 +391,7 @@ obj-xtensa-y += core-dc233c.o
 obj-xtensa-y += core-fsf.o
 
 obj-openrisc-y += openrisc_pic.o
+obj-openrisc-y += openrisc_sim.o
 obj-openrisc-y += openrisc_timer.o
 
 main.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
diff --git a/hw/openrisc_sim.c b/hw/openrisc_sim.c
new file mode 100644
index 000..869a02e
--- /dev/null
+++ b/hw/openrisc_sim.c
@@ -0,0 +1,140 @@
+/*
+ * Openrisc simulator for use as an ISS.
+ *
+ *  Copyright (c) 2011-2012 Jia Liu 
+ *  Feng Gao 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
+ */
+
+#include "hw.h"
+#include "fdc.h"
+#include "net.h"
+#include "openrisc_cpudev.h"
+#include "boards.h"
+#include "pci.h"
+#include "elf.h"
+#include "smbus.h"
+#include "memory.h"
+#include "pc.h"
+#include "pci.h"
+#include "sysbus.h"
+#include "flash.h"
+#include "loader.h"
+#include "exec-memory.h"
+#include "sysemu.h"
+#include "isa.h"
+#include "mc146818rtc.h"
+#include "blockdev.h"
+#include "qemu-log.h"
+
+#define KERNEL_LOAD_ADDR 0x100
+
+static uint64_t translate_phys_addr(void *env, uint64_t addr)
+{
+return cpu_get_phys_page_debug(env, addr);
+}
+
+static void main_cpu_reset(void *opaque)
+{
+CPUOPENRISCState *env = opaque;
+openrisc_reset(env);
+}
+
+static void openrisc_sim_init(ram_addr_t ram_size,
+  const char *boot_device,
+  const char *kernel_filename,
+  const char *kernel_cmdline,
+  const char *initrd_filename,
+  const char *cpu_model)
+{
+CPUOPENRISCState *env;
+MemoryRegion *ram = g_new(MemoryRegion, 1);
+int kernel_size;
+uint64_t elf_entry;
+target_phys_addr_t entry;
+qemu_irq *i8259;
+ISABus *isa_bus;
+
+if (!cpu_model) {
+cpu_model = "or1200";
+}
+env = cpu_init(cpu_model);
+if (!env) {
+fprintf(stderr, "Unable to find CPU definition!\n");
+exit(1);
+}
+
+qemu_register_reset(main_cpu_reset, env);
+main_cpu_reset(env);
+
+memory_region_init_ram(ram, "openrisc.ram", ram_size);
+memory_region_add_subregion(get_system_memory(), 0, ram);
+
+if (kernel_filename) {
+kernel_size = load_elf(kernel_filename, translate_phys_addr, env,
+   &elf_entry, NULL, NULL, 1, ELF_MACHINE, 1);
+entry = elf_entry;
+if (kernel_size < 0) {
+kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL);
+}
+if (kernel_size < 0) {
+kernel_size = load_image_targphys(kernel_filename,
+  KERNEL_LOAD_ADDR,
+  ram_size - KERNEL_LOAD_ADDR);
+entry = KERNEL_LOAD_ADDR;
+}
+if (kernel_size < 0) {
+fprintf(stderr, "qemu: could not load kernel '%s'\n",
+kernel_filename);
+exit(1);
+}
+
+if (kernel_size > 0) {
+env->pc = elf_entry;
+}
+} else {
+entry = 0;
+}
+
+cpu_openrisc_pic_init(env);
+cpu_openrisc_clock_init(env);
+
+isa_bus = isa_bus_new(NULL, get_system_io());
+i8259 = i8259_init(isa_bus, env->irq[3]);
+isa_bus_irqs(isa_bus, i8259);
+
+serial_mm_init(get_system_memory(), 0x9000, 0,
+   env->irq[2], 115200, serial_hds[0], DEVICE_NATIVE_ENDIAN);
+
+if (nd_table[0].vlan) {
+isa_ne2000_init(isa_bus, 0x9200, 4, &nd_table[0]);
+}
+}
+
+static QEMUMachine openrisc_sim_machine = {
+.name = "or32-sim",
+.desc = "or32 simulation",
+.init = openrisc_sim_init,
+.max_cpus = 1,
+.is_default = 1,
+};
+
+static void openrisc_sim_machine_init(void)
+{
+qemu_register_machine(&openrisc_sim_machine);
+}
+
+machine_init(openrisc_sim_machine_init);
-- 
1.7.9.5




Re: [Qemu-devel] [PATCH 01/15] Openrisc: add target stub

2012-05-17 Thread 陳韋任
> +CPUOPENRISCState *cpu_openrisc_init(const char *cpu_model)
> +{
> +CPUOPENRISCState *env;
> +static int tcg_inited;
> +
> +env = g_malloc0(sizeof(*env));
> +memset(env, 0, sizeof(*env));
   ^^
  No need to memset env to zero, since g_malloc0 already did it for you.

> diff --git a/target-openrisc/helper.h b/target-openrisc/helper.h
> new file mode 100644
> index 000..103d9b4
> --- /dev/null
> +++ b/target-openrisc/helper.h

  [snip]

> +#include "def-helper.h"
> +
> +#include "def-helper.h"

  I suppose you only need to #include "def-helper.h" once?

Regards,
chenwj

-- 
Wei-Ren Chen (陳韋任)
Computer Systems Lab, Institute of Information Science,
Academia Sinica, Taiwan (R.O.C.)
Tel:886-2-2788-3799 #1667
Homepage: http://people.cs.nctu.edu.tw/~chenwj



[Qemu-devel] [PATCH 01/15] Openrisc: add target stub

2012-05-17 Thread Jia Liu
add the openrisc target stub and basic implementation.

Signed-off-by: Jia Liu 
---
 Makefile.target  |3 +
 arch_init.c  |2 +
 arch_init.h  |1 +
 configure|8 +-
 cpu-exec.c   |2 +
 default-configs/or32-softmmu.mak |6 +
 elf.h|2 +
 poison.h |1 +
 target-openrisc/cpu-qom.h|   70 +
 target-openrisc/cpu.c|   74 ++
 target-openrisc/cpu.h|  299 ++
 target-openrisc/helper.c |   67 +
 target-openrisc/helper.h |   23 +++
 target-openrisc/machine.c|   76 ++
 target-openrisc/mem.c|   43 ++
 target-openrisc/mem_helper.c |   46 ++
 target-openrisc/translate.c  |   90 
 17 files changed, 812 insertions(+), 1 deletion(-)
 create mode 100644 default-configs/or32-softmmu.mak
 create mode 100644 target-openrisc/cpu-qom.h
 create mode 100644 target-openrisc/cpu.c
 create mode 100644 target-openrisc/cpu.h
 create mode 100644 target-openrisc/helper.c
 create mode 100644 target-openrisc/helper.h
 create mode 100644 target-openrisc/machine.c
 create mode 100644 target-openrisc/mem.c
 create mode 100644 target-openrisc/mem_helper.c
 create mode 100644 target-openrisc/translate.c

diff --git a/Makefile.target b/Makefile.target
index 1582904..0ffb29c 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -83,9 +83,11 @@ libobj-$(CONFIG_TCG_INTERPRETER) += tci.o
 libobj-y += fpu/softfloat.o
 ifneq ($(TARGET_BASE_ARCH), sparc)
 ifneq ($(TARGET_BASE_ARCH), alpha)
+ifneq ($(TARGET_BASE_ARCH), openrisc)
 libobj-y += op_helper.o
 endif
 endif
+endif
 libobj-y += helper.o
 ifneq ($(TARGET_BASE_ARCH), ppc)
 libobj-y += cpu.o
@@ -99,6 +101,7 @@ endif
 libobj-$(TARGET_SPARC) += int32_helper.o
 libobj-$(TARGET_SPARC64) += int64_helper.o
 libobj-$(TARGET_ALPHA) += int_helper.o fpu_helper.o sys_helper.o mem_helper.o
+libobj-$(TARGET_OPENRISC) += mem.o mem_helper.o
 
 libobj-y += disas.o
 libobj-$(CONFIG_TCI_DIS) += tci-dis.o
diff --git a/arch_init.c b/arch_init.c
index 988adca..55b608d 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -71,6 +71,8 @@ int graphic_depth = 15;
 #define QEMU_ARCH QEMU_ARCH_MICROBLAZE
 #elif defined(TARGET_MIPS)
 #define QEMU_ARCH QEMU_ARCH_MIPS
+#elif defined(TARGET_OPENRISC)
+#define QEMU_ARCH QEMU_ARCH_OPENRISC
 #elif defined(TARGET_PPC)
 #define QEMU_ARCH QEMU_ARCH_PPC
 #elif defined(TARGET_S390X)
diff --git a/arch_init.h b/arch_init.h
index c7cb94a..3dfea3b 100644
--- a/arch_init.h
+++ b/arch_init.h
@@ -16,6 +16,7 @@ enum {
 QEMU_ARCH_SH4 = 1024,
 QEMU_ARCH_SPARC = 2048,
 QEMU_ARCH_XTENSA = 4096,
+QEMU_ARCH_OPENRISC = 8192,
 };
 
 extern const uint32_t arch_type;
diff --git a/configure b/configure
index b55a792..63e2372 100755
--- a/configure
+++ b/configure
@@ -924,6 +924,7 @@ mips-softmmu \
 mipsel-softmmu \
 mips64-softmmu \
 mips64el-softmmu \
+or32-softmmu \
 ppc-softmmu \
 ppcemb-softmmu \
 ppc64-softmmu \
@@ -3460,7 +3461,7 @@ target_arch2=`echo $target | cut -d '-' -f 1`
 target_bigendian="no"
 
 case "$target_arch2" in
-  
armeb|lm32|m68k|microblaze|mips|mipsn32|mips64|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb)
+  
armeb|lm32|m68k|microblaze|mips|mipsn32|mips64|or32|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb)
   target_bigendian=yes
   ;;
 esac
@@ -3588,6 +3589,11 @@ case "$target_arch2" in
 target_phys_bits=64
 target_long_alignment=8
   ;;
+  or32)
+TARGET_ARCH=openrisc
+TARGET_BASE_ARCH=openrisc
+target_phys_bits=32
+  ;;
   ppc)
 gdb_xml_files="power-core.xml power-fpu.xml power-altivec.xml 
power-spe.xml"
 target_phys_bits=64
diff --git a/cpu-exec.c b/cpu-exec.c
index 0344cd5..ba10db1 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -222,6 +222,7 @@ int cpu_exec(CPUArchState *env)
 #elif defined(TARGET_LM32)
 #elif defined(TARGET_MICROBLAZE)
 #elif defined(TARGET_MIPS)
+#elif defined(TARGET_OPENRISC)
 #elif defined(TARGET_SH4)
 #elif defined(TARGET_CRIS)
 #elif defined(TARGET_S390X)
@@ -620,6 +621,7 @@ int cpu_exec(CPUArchState *env)
   | env->cc_dest | (env->cc_x << 4);
 #elif defined(TARGET_MICROBLAZE)
 #elif defined(TARGET_MIPS)
+#elif defined(TARGET_OPENRISC)
 #elif defined(TARGET_SH4)
 #elif defined(TARGET_ALPHA)
 #elif defined(TARGET_CRIS)
diff --git a/default-configs/or32-softmmu.mak b/default-configs/or32-softmmu.mak
new file mode 100644
index 000..7590eed
--- /dev/null
+++ b/default-configs/or32-softmmu.mak
@@ -0,0 +1,6 @@
+# Default configuration for or32-softmmu
+
+include pci.mak
+CONFIG_SERIAL=y
+CONFIG_NE2000_ISA=y
+CONFIG_I8259=y
diff --git a/elf.h b/elf.h
index e1422b8..e65f4b9 100644
--- a/elf.h
+++ b/elf.h
@@ -106,6 +106,8 @@ typedef int64_t  Elf64_Sxword;
 #define EM_H8S  48  /* Hitachi H8S */
 #define EM_LATT

Re: [Qemu-devel] Add support for new image type

2012-05-17 Thread Paolo Bonzini
Il 17/05/2012 11:10, Artyom Tarasenko ha scritto:
> To help me better understand, what would
>> be the terminology used for the explanation between what I would call
>> "source code" licensing, and "project" licensing? Also, where in the code
>> (or rather what file) can I see this distinction? It seems like something
>> critical to be aware of, and I'd like to avoid missing something like this
>> in the future as I give advice on what software we can use.

Roughly speaking, each file has its own license.  So you can take for
example vl.c or tcg/* and use it in a proprietary program, because those
are under a non-copyleft license.  You cannot do the same for
event_notifier.c, because it is released under GPLv2 or later.

For the project to be distributable at all, there has to be a license
that is compatible with all the others: such a license has to allow all
restrictions imposed by the other licenses used in the project, and all
other licenses have to allow all restrictions imposed by such a license.
 For QEMU this license is the GPLv2.

>> If you would help clarify a separate point, I would be grateful. As I
>> understand it, I am able to modify qemu for my own purposes (like testing
>> the filesystem integrity inside a backup image by using guestmount to mount
>> it). How much of that work (source code, principles, explanations, ect) can
>> I share, and with whom can I share it with?

Principles, explanations can be shared with whoever you want, however
you want.  Patches are more of a grey area and I suggest you consult a
(good) lawyer.

Remember that the GPL only becomes relevant once you start distributing
code.  As long as you share the changes within your company for example
you are safe.  Here is what the GPL FAQ says:

   Is making and using multiple copies within one organization or
   company “distribution”? (#InternalDistribution)

   No, in that case the organization is just making the copies for
   itself. As a consequence, a company or other organization can
   develop a modified version and install that version through its own
   facilities, without giving the staff permission to release that
   modified version to outsiders.

   However, when the organization transfers copies to other
   organizations or individuals, that is distribution. In particular,
   providing copies to contractors for use off-site is distribution.

What you suggested with run-time linking sounds like you are adding a
functionality that is totally useless to the general public.  Those
people who are able to combine it with the shared library could use it
as in the above answer without distributing the result.

Morally it's wrong, but a copyright holder cannot stop you on moral
grounds.  Legally, you should consult a lawyer.  Practically:

- if you go with iSCSI or something like that you would provide the same
functionality to your customers, keep clear from legal grey areas, and
the QEMU community probably could not care less.

- if you go with a clean reimplementation under the GPL you would
provide the same functionality to your customers, keep clear from legal
grey areas, contribute to QEMU positively, and perhaps get some
advertising for your product.

Paolo



[Qemu-devel] [PATCH 09/15] Openrisc: add timer support

2012-05-17 Thread Jia Liu
add the openrisc timer support.

Signed-off-by: Jia Liu 
---
 Makefile.target |1 +
 hw/openrisc_timer.c |  153 +++
 2 files changed, 154 insertions(+)
 create mode 100644 hw/openrisc_timer.c

diff --git a/Makefile.target b/Makefile.target
index 8a7b743..6b1d2d0 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -391,6 +391,7 @@ obj-xtensa-y += core-dc233c.o
 obj-xtensa-y += core-fsf.o
 
 obj-openrisc-y += openrisc_pic.o
+obj-openrisc-y += openrisc_timer.o
 
 main.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
 
diff --git a/hw/openrisc_timer.c b/hw/openrisc_timer.c
new file mode 100644
index 000..987149f
--- /dev/null
+++ b/hw/openrisc_timer.c
@@ -0,0 +1,153 @@
+/*
+ *  QEMU openrisc timer support
+ *
+ *  Copyright (c) 2011-2012 Jia Liu 
+ *  Zhizhou Zhang 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#include "hw.h"
+#include "openrisc_cpudev.h"
+#include "qemu-timer.h"
+
+#define TIMER_FREQ(20 * 1000 * 1000)/* 20MHz */
+
+/* The time when ttcr changes */
+static uint64_t last_clk;
+static int is_counting;
+
+/* Timer Mode */
+enum {
+TIMER_NONE = (0<<30),
+TIMER_INTR = (1<<30),
+TIMER_SHOT = (2<<30),
+TIMER_CONT = (3<<30),
+};
+
+static void count_update(CPUOPENRISCState *env)
+{
+uint64_t now, next;
+uint32_t wait;
+
+now = qemu_get_clock_ns(vm_clock);
+if (!is_counting) {
+qemu_del_timer(env->timer);
+last_clk = now;
+return;
+}
+
+env->ttcr += (uint32_t)muldiv64(now - last_clk, TIMER_FREQ,
+get_ticks_per_sec());
+last_clk = now;
+
+if ((env->ttmr & TTMR_TP) <= (env->ttcr & TTMR_TP)) {
+wait = TTMR_TP - (env->ttcr & TTMR_TP) + 1;
+wait += env->ttmr & TTMR_TP;
+} else {
+wait = (env->ttmr & TTMR_TP) - (env->ttcr & TTMR_TP);
+}
+
+next = now + muldiv64(wait, get_ticks_per_sec(), TIMER_FREQ);
+qemu_mod_timer(env->timer, next);
+}
+
+static void count_start(CPUOPENRISCState *env)
+{
+is_counting = 1;
+count_update(env);
+}
+
+static void count_stop(CPUOPENRISCState *env)
+{
+is_counting = 0;
+count_update(env);
+}
+
+uint32_t cpu_openrisc_get_count(CPUOPENRISCState *env)
+{
+count_update(env);
+return env->ttcr;
+}
+
+void cpu_openrisc_store_count(CPUOPENRISCState *env, uint32_t count)
+{
+/* Store new count register */
+env->ttcr = count;
+if (env->ttmr & TIMER_NONE) {
+return;
+}
+count_start(env);
+}
+
+void cpu_openrisc_store_compare(CPUOPENRISCState *env, uint32_t value)
+{
+int ip = env->ttmr & TTMR_IP;
+
+if (value & TTMR_IP) { /* Keep IP bit */
+env->ttmr = (value & ~TTMR_IP) + ip;
+} else {   /* Clear IP bit */
+env->ttmr = value & ~TTMR_IP;
+env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
+}
+count_update(env);
+
+switch (env->ttmr & TTMR_M) {
+case TIMER_NONE:
+count_stop(env);
+break;
+case TIMER_INTR:
+count_start(env);
+break;
+case TIMER_SHOT:
+count_start(env);
+break;
+case TIMER_CONT:
+count_start(env);
+break;
+}
+}
+
+static void openrisc_timer_cb(void *opaque)
+{
+CPUOPENRISCState *env = opaque;
+
+if ((env->ttmr & TTMR_IE) &&
+ qemu_timer_expired(env->timer, qemu_get_clock_ns(vm_clock))) {
+env->ttmr |= TTMR_IP;
+env->interrupt_request |= CPU_INTERRUPT_TIMER;
+}
+
+switch (env->ttmr & TTMR_M) {
+case TIMER_NONE:
+break;
+case TIMER_INTR:
+env->ttcr = 0;
+count_start(env);
+break;
+case TIMER_SHOT:
+count_stop(env);
+break;
+case TIMER_CONT:
+count_start(env);
+break;
+}
+}
+
+void cpu_openrisc_clock_init(CPUOPENRISCState *env)
+{
+env->timer = qemu_new_timer_ns(vm_clock, &openrisc_timer_cb, env);
+env->ttmr = 0;
+env->ttcr = 0;
+}
-- 
1.7.9.5




[Qemu-devel] [PATCH 03/15] Openrisc: add instructions translation

2012-05-17 Thread Jia Liu
add the openrisc instructions translation.

Signed-off-by: Jia Liu 
---
 target-openrisc/translate.c | 1387 +++
 1 file changed, 1387 insertions(+)

diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index aae483a..4828ae6 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -55,14 +55,1395 @@ typedef struct DisasContext {
 uint32_t delayed_branch;
 } DisasContext;
 
+static TCGv_ptr cpu_env;
+static TCGv cpu_sr;
+static TCGv cpu_R[32];
+static TCGv cpu_pc;
+static TCGv jmp_pc;/* l.jr/l.jalr temp pc */
+static TCGv cpu_npc;
+static TCGv cpu_ppc;
+static TCGv_i32 env_btaken;/* bf/bnf , F flag taken */
+static TCGv machi, maclo;
+static TCGv fpmaddhi, fpmaddlo;
+static TCGv_i32 env_flags;
+#include "gen-icount.h"
+
 void openrisc_translate_init(void)
 {
+static const char * const regnames[] = {
+"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+};
+int i;
+
+cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
+cpu_sr = tcg_global_mem_new(TCG_AREG0,
+offsetof(CPUOPENRISCState, sr), "sr");
+env_flags = tcg_global_mem_new_i32(TCG_AREG0,
+   offsetof(CPUOPENRISCState, flags),
+   "flags");
+cpu_pc = tcg_global_mem_new(TCG_AREG0,
+offsetof(CPUOPENRISCState, pc), "pc");
+cpu_npc = tcg_global_mem_new(TCG_AREG0,
+ offsetof(CPUOPENRISCState, npc), "npc");
+cpu_ppc = tcg_global_mem_new(TCG_AREG0,
+ offsetof(CPUOPENRISCState, ppc), "ppc");
+jmp_pc = tcg_global_mem_new(TCG_AREG0,
+offsetof(CPUOPENRISCState, jmp_pc), "jmp_pc");
+env_btaken = tcg_global_mem_new_i32(TCG_AREG0,
+offsetof(CPUOPENRISCState, btaken),
+"btaken");
+machi = tcg_global_mem_new(TCG_AREG0,
+   offsetof(CPUOPENRISCState, machi),
+   "machi");
+maclo = tcg_global_mem_new(TCG_AREG0,
+   offsetof(CPUOPENRISCState, maclo),
+   "maclo");
+fpmaddhi = tcg_global_mem_new(TCG_AREG0,
+  offsetof(CPUOPENRISCState, fpmaddhi),
+  "fpmaddhi");
+fpmaddlo = tcg_global_mem_new(TCG_AREG0,
+  offsetof(CPUOPENRISCState, fpmaddlo),
+  "fpmaddlo");
+for (i = 0; i < 32; i++) {
+cpu_R[i] = tcg_global_mem_new(TCG_AREG0,
+  offsetof(CPUOPENRISCState, gpr[i]),
+  regnames[i]);
+}
+#define GEN_HELPER 2
+#include "helper.h"
+}
+
+/* Writeback SR_F transaltion-space to execution-space.  */
+static inline void wb_SR_F(void)
+{
+int label;
+
+label = gen_new_label();
+tcg_gen_andi_tl(cpu_sr, cpu_sr, ~SR_F);
+tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, label);
+tcg_gen_ori_tl(cpu_sr, cpu_sr, SR_F);
+gen_set_label(label);
+}
+
+static inline int zero_extend(unsigned int val, int width)
+{
+return val & ((1 << width) - 1);
+}
+
+static inline int sign_extend(unsigned int val, int width)
+{
+int sval;
+
+/* LSL.  */
+val <<= 32 - width;
+sval = val;
+/* ASR.  */
+sval >>= 32 - width;
+return sval;
+}
+
+/* General purpose registers moves. */
+static inline void gen_load_gpr(TCGv t, unsigned int reg)
+{
+if (reg == 0) {
+tcg_gen_movi_tl(t, 0);
+} else {
+tcg_gen_mov_tl(t, cpu_R[reg]);
+}
+}
+
+static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
+{
+TranslationBlock *tb;
+tb = dc->tb;
+if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
+   likely(!dc->singlestep_enabled)) {
+tcg_gen_movi_tl(cpu_pc, dest);
+tcg_gen_goto_tb(n);
+tcg_gen_exit_tb((tcg_target_long)tb + n);
+} else {
+tcg_gen_movi_tl(cpu_pc, dest);
+if (dc->singlestep_enabled) {
+/* exception here */
+}
+tcg_gen_exit_tb(0);
+}
+}
+
+static inline uint32_t field(uint32_t val, int start, int length)
+{
+val >>= start;
+val &= ~(~0 << length);
+return val;
+}
+
+static void dec_calc(DisasContext *dc, CPUOPENRISCState *env, uint32_t insn)
+{
+uint32_t op0, op1, op2;
+uint32_t ra, rb, rd;
+op0 = field(insn, 0, 4);
+op1 = field(insn, 8, 2);
+op2 = field(insn, 6, 2);
+ra = field(insn, 16, 5);
+rb = field(insn, 11, 5);
+rd = field(insn, 21, 5);
+
+switch (op0) {
+cas

[Qemu-devel] [PATCH 07/15] Openrisc: add float instruction helpers

2012-05-17 Thread Jia Liu
add the openrisc float instruction helpers.

Signed-off-by: Jia Liu 
---
 Makefile.target  |2 +-
 target-openrisc/fpu_helper.c |   93 ++
 target-openrisc/helper.h |6 +++
 target-openrisc/translate.c  |8 ++--
 4 files changed, 104 insertions(+), 5 deletions(-)
 create mode 100644 target-openrisc/fpu_helper.c

diff --git a/Makefile.target b/Makefile.target
index 9bebdb3..8a7b743 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -101,7 +101,7 @@ endif
 libobj-$(TARGET_SPARC) += int32_helper.o
 libobj-$(TARGET_SPARC64) += int64_helper.o
 libobj-$(TARGET_ALPHA) += int_helper.o fpu_helper.o sys_helper.o mem_helper.o
-libobj-$(TARGET_OPENRISC) += excp.o excp_helper.o int_helper.o intrp_helper.o 
mem.o mem_helper.o
+libobj-$(TARGET_OPENRISC) += excp.o excp_helper.o fpu_helper.o int_helper.o 
intrp_helper.o mem.o mem_helper.o
 
 libobj-y += disas.o
 libobj-$(CONFIG_TCI_DIS) += tci-dis.o
diff --git a/target-openrisc/fpu_helper.c b/target-openrisc/fpu_helper.c
new file mode 100644
index 000..be2bfb5
--- /dev/null
+++ b/target-openrisc/fpu_helper.c
@@ -0,0 +1,93 @@
+/*
+ * OpenRISC float helper routines
+ *
+ *  Copyright (c) 2011-2012 Jia Liu 
+ *  Feng Gao 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
+ */
+
+#include "cpu.h"
+#include "helper.h"
+#include "excp.h"
+
+static inline int ieee_ex_to_openrisc(int xcpt)
+{
+int ret = 0;
+
+if (xcpt) {
+if (xcpt & float_flag_invalid) {
+ret &= FPCSR_FPEE;
+}
+if (xcpt & float_flag_overflow) {
+ret |= FPCSR_OVF;
+}
+if (xcpt & float_flag_underflow) {
+ret |= FPCSR_UNF;
+}
+if (xcpt & float_flag_divbyzero) {
+ret |= FPCSR_DZF;
+}
+}
+
+return ret;
+}
+
+static inline void update_fpcsr(CPUOPENRISCState *env)
+{
+int tmp = ieee_ex_to_openrisc(get_float_exception_flags(&env->fp_status));
+SET_FP_CAUSE(env->fpcsr, tmp);
+if (GET_FP_ENABLE(env->fpcsr) & tmp) {
+helper_exception(env, EXCP_FPE);
+} else {
+  UPDATE_FP_FLAGS(env->fpcsr, tmp);
+}
+}
+
+target_ulong HELPER(itofd)(CPUOPENRISCState *env, target_ulong val)
+{
+uint64_t itofd;
+set_float_exception_flags(0, &env->fp_status);
+itofd = int32_to_float64(val, &env->fp_status);
+update_fpcsr(env);
+return itofd;
+}
+
+target_ulong HELPER(itofs)(CPUOPENRISCState *env, target_ulong val)
+{
+target_ulong itofs;
+set_float_exception_flags(0, &env->fp_status);
+itofs = int32_to_float32(val, &env->fp_status);
+update_fpcsr(env);
+return itofs;
+}
+
+target_ulong HELPER(ftoid)(CPUOPENRISCState *env, target_ulong val)
+{
+target_ulong ftoid;
+set_float_exception_flags(0, &env->fp_status);
+ftoid = float32_to_int64(val, &env->fp_status);
+update_fpcsr(env);
+return ftoid;
+}
+
+target_ulong HELPER(ftois)(CPUOPENRISCState *env, target_ulong val)
+{
+target_ulong ftois;
+set_float_exception_flags(0, &env->fp_status);
+ftois = float32_to_int32(val, &env->fp_status);
+update_fpcsr(env);
+return ftois;
+}
diff --git a/target-openrisc/helper.h b/target-openrisc/helper.h
index f5ed117..b9b1d67 100644
--- a/target-openrisc/helper.h
+++ b/target-openrisc/helper.h
@@ -23,6 +23,12 @@
 /* exception */
 DEF_HELPER_FLAGS_2(exception, 0, void, env, i32)
 
+/* float */
+DEF_HELPER_FLAGS_2(itofd, 0, tl, env, tl)
+DEF_HELPER_FLAGS_2(itofs, 0, tl, env, tl)
+DEF_HELPER_FLAGS_2(ftoid, 0, tl, env, tl)
+DEF_HELPER_FLAGS_2(ftois, 0, tl, env, tl)
+
 /* int */
 DEF_HELPER_FLAGS_1(ff1, 0, tl, tl)
 DEF_HELPER_FLAGS_1(fl1, 0, tl, tl)
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index dffc8a7..7d942b5 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -1107,22 +1107,22 @@ static void dec_float(DisasContext *dc, 
CPUOPENRISCState *env, uint32_t insn)
 
 case 0x14:/*lf.itof.d*/
 LOG_DIS("lf.itof r%d, r%d\n", rd, ra);
-/* itof.d need a helper here */
+gen_helper_itofd(cpu_R[rd], cpu_env, cpu_R[ra]);
 break;
 
 case 0x04:/*lf.itof.s*/
 LOG_DIS("lf.itof r%d, r%d\n", rd, ra);
-/* itof.s need a helper here */
+gen_hel

Re: [Qemu-devel] [PATCH v10 8/9] Add set_cachesize command

2012-05-17 Thread Avi Kivity
On 05/16/2012 08:58 PM, Eric Blake wrote:
> On 05/16/2012 11:04 AM, Orit Wasserman wrote:
>
> >>> +- "value": cache size in bytes (json-int)
> >>
> >> Would it be any easier to take 'order' (log2 of the size) instead of the
> >> actual cache size?  That is, instead of calling "value":1048576, I would
> >> rather type "value":20.
> > Well the user is considering how much memory is going to be used and I 
> > though that it
> > is simpler to use 1G than 30.
>
> Libvirt can cope with either style, so maybe it's worth waiting for
> anyone else to chime in on which style is easier.

Let's be consistent.  It's best to use bytes everywhere (not kilobytes,
not megabytes, not pages, not order, or anything else we can come up with).

If you really want to specify order (not that I can think of a reason
why), we can use a suffix: 20ORD == 1M == 1048576.

btw, maybe it's better to handle a non-power-of-two cache size by
rounding down.  Less errors, less puzzlement, and less memory used.

-- 
error compiling committee.c: too many arguments to function




Re: [Qemu-devel] [QEMU] net: adapt dump to support the new syntax

2012-05-17 Thread Paolo Bonzini
Il 17/05/2012 07:59, Zhi Yong Wu ha scritto:
>> > However, then I noticed that qemu_can_send_packet is not called very much,
>> > and I do not understand why qemu_net_queue_send and qemu_net_queue_send_iov
>> > do not call qemu_can_send_packet before calling deliver/deliver_iov.
> This case has existed in current upstream code, not only vlan-hub
> code. Currently can_send function has been called by backend send
> function before deliver/deliver_iov, If we put can_send in queue send
> function, your idea will have a big challenge for slirp packet queue.

Exactly why?  For SLIRP's receive path, SLIRP doesn't implement
can_receive at all so it will never block.  For the send path, when flow
control kicks qemu_net_queue_append will copy the packet so it is not a
problem for SLIRP's stack-allocated packets.

> We can implement your idea below later, not in this patchset. What do
> you think?

Note that my idea above was only means to an end.  If you can remove the
TODOs in a convincing manner, that would be fine.

Paolo



[Qemu-devel] [PATCH 2/2] [kvm/vhost-net]: make vhost net own NUMA attribute

2012-05-17 Thread Liu Ping Fan
From: Liu Ping Fan 

Make vhost net support to spread on host node according the command.
And consider the whole vhost_net componsed of lots of logic net units.
for each node, there is a unit, which includes a vhost_worker thread,
rx/tx vhost_virtqueue.

Signed-off-by: Liu Ping Fan 
---
 drivers/vhost/net.c |  388 ++-
 1 files changed, 258 insertions(+), 130 deletions(-)

diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 1f21d2a..770933e 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -55,8 +55,19 @@ enum vhost_net_poll_state {
 
 struct vhost_net {
struct vhost_dev dev;
-   struct vhost_virtqueue vqs[VHOST_NET_VQ_MAX];
+   int numa_init;
+   int vqcnt;
+   struct vhost_virtqueue **vqs;
+   /* one for tx, one for rx */
struct vhost_poll poll[VHOST_NET_VQ_MAX];
+   int token[VHOST_NET_VQ_MAX];
+   /* fix me, Although tun.socket.sock can be parrell, but _maybe_, we 
need to record
+* wmem_alloc independly for each subdev.
+*/
+   struct mutex mutex;
+   struct socket __rcu *tx_sock;
+   struct socket __rcu *rx_sock;
+
/* Tells us whether we are polling a socket for TX.
 * We only do this when socket buffer fills up.
 * Protected by tx vq lock. */
@@ -112,7 +123,9 @@ static void tx_poll_stop(struct vhost_net *net)
 {
if (likely(net->tx_poll_state != VHOST_NET_POLL_STARTED))
return;
+
vhost_poll_stop(net->poll + VHOST_NET_VQ_TX);
+
net->tx_poll_state = VHOST_NET_POLL_STOPPED;
 }
 
@@ -121,15 +134,15 @@ static void tx_poll_start(struct vhost_net *net, struct 
socket *sock)
 {
if (unlikely(net->tx_poll_state != VHOST_NET_POLL_STOPPED))
return;
+
vhost_poll_start(net->poll + VHOST_NET_VQ_TX, sock->file);
net->tx_poll_state = VHOST_NET_POLL_STARTED;
 }
 
 /* Expects to be always run from workqueue - which acts as
  * read-size critical section for our kind of RCU. */
-static void handle_tx(struct vhost_net *net)
+static void handle_tx(struct vhost_net *net, struct vhost_virtqueue *vq)
 {
-   struct vhost_virtqueue *vq = &net->dev.vqs[VHOST_NET_VQ_TX];
unsigned out, in, s;
int head;
struct msghdr msg = {
@@ -148,15 +161,15 @@ static void handle_tx(struct vhost_net *net)
bool zcopy;
 
/* TODO: check that we are running from vhost_worker? */
-   sock = rcu_dereference_check(vq->private_data, 1);
+   sock = rcu_dereference_check(net->tx_sock, 1);
if (!sock)
return;
 
wmem = atomic_read(&sock->sk->sk_wmem_alloc);
if (wmem >= sock->sk->sk_sndbuf) {
-   mutex_lock(&vq->mutex);
+   mutex_lock(&net->mutex);
tx_poll_start(net, sock);
-   mutex_unlock(&vq->mutex);
+   mutex_unlock(&net->mutex);
return;
}
 
@@ -165,6 +178,7 @@ static void handle_tx(struct vhost_net *net)
 
if (wmem < sock->sk->sk_sndbuf / 2)
tx_poll_stop(net);
+
hdr_size = vq->vhost_hlen;
zcopy = vhost_sock_zcopy(sock);
 
@@ -186,8 +200,10 @@ static void handle_tx(struct vhost_net *net)
 
wmem = atomic_read(&sock->sk->sk_wmem_alloc);
if (wmem >= sock->sk->sk_sndbuf * 3 / 4) {
+   mutex_lock(&net->mutex);
tx_poll_start(net, sock);
set_bit(SOCK_ASYNC_NOSPACE, &sock->flags);
+   mutex_unlock(&net->mutex);
break;
}
/* If more outstanding DMAs, queue the work.
@@ -197,8 +213,10 @@ static void handle_tx(struct vhost_net *net)
(vq->upend_idx - vq->done_idx) :
(vq->upend_idx + UIO_MAXIOV - vq->done_idx);
if (unlikely(num_pends > VHOST_MAX_PEND)) {
+   mutex_lock(&net->mutex);
tx_poll_start(net, sock);
set_bit(SOCK_ASYNC_NOSPACE, &sock->flags);
+   mutex_unlock(&net->mutex);
break;
}
if (unlikely(vhost_enable_notify(&net->dev, vq))) {
@@ -353,9 +371,8 @@ err:
 
 /* Expects to be always run from workqueue - which acts as
  * read-size critical section for our kind of RCU. */
-static void handle_rx(struct vhost_net *net)
+static void handle_rx(struct vhost_net *net, struct vhost_virtqueue *vq)
 {
-   struct vhost_virtqueue *vq = &net->dev.vqs[VHOST_NET_VQ_RX];
unsigned uninitialized_var(in), log;
struct vhost_log *vq_log;
struct msghdr msg = {
@@ -375,11 +392,10 @@ static void handle_rx(struct vhost_net *net)
size_t vhost_hlen, sock_hlen;
  

Re: [Qemu-devel] [PATCH 2/2] Get system state configuration from QEMU and patcth DSDT with it.

2012-05-17 Thread Paolo Bonzini
Il 17/05/2012 02:24, Kevin O'Connor ha scritto:
>> > Can we build an SSDT that includes the contents of fw_cfg (e.g.
>> > FW_CFG_SIGNATURE at offset 0, FW_CFG_UUID at offset 4, FW_CFG_NOGRAPHIC
>> > at offset 16... the entry <-> offset mapping and the defaults would be
>> > part of SeaBIOS), and then read that data from normal DSDT methods?
>> > 
>> > That would be similar to Gerd's patch, but without letting the OSPM use
>> > the real fw_cfg device.
> I'm not sure I understand your proposal.  Are you suggesting reading
> every fw_cfg "port" into memory and then passing that memory into an
> SSDT?  If so, that wouldn't be easy (we don't necessarily know the
> size of each "port") and could potentially waste a lot of memory
> (think a vmlinuz stored in fw_cfg).

No, only entries and/or files that are needed by the DSDT (PCI region
and sleep data).

Paolo



Re: [Qemu-devel] [QEMU] net: adapt dump to support the new syntax

2012-05-17 Thread Zhi Yong Wu
On Thu, May 17, 2012 at 5:51 PM, Paolo Bonzini  wrote:
> Il 17/05/2012 07:59, Zhi Yong Wu ha scritto:
>>> > However, then I noticed that qemu_can_send_packet is not called very much,
>>> > and I do not understand why qemu_net_queue_send and 
>>> > qemu_net_queue_send_iov
>>> > do not call qemu_can_send_packet before calling deliver/deliver_iov.
>> This case has existed in current upstream code, not only vlan-hub
>> code. Currently can_send function has been called by backend send
>> function before deliver/deliver_iov, If we put can_send in queue send
>> function, your idea will have a big challenge for slirp packet queue.
>
> Exactly why?  For SLIRP's receive path, SLIRP doesn't implement
> can_receive at all so it will never block.  For the send path, when flow
> control kicks qemu_net_queue_append will copy the packet so it is not a
> problem for SLIRP's stack-allocated packets.
You know that qemu_send_packet is void type, and has return value, if
can_send fails, if_encap will not currently get expected return value,
so this will cause that we have to modify the definition of
qemu_send_packet to make it return one valid value. a lot of functions
have called it, so i would not like to modify its definition.

>
>> We can implement your idea below later, not in this patchset. What do
>> you think?
>
> Note that my idea above was only means to an end.  If you can remove the
> TODOs in a convincing manner, that would be fine.
You mean that we need adopt another handling way? or directly TODO comments?

>
> Paolo



-- 
Regards,

Zhi Yong Wu



Re: [Qemu-devel] [PATCH v6 4/7] RTC: Add divider reset support

2012-05-17 Thread Paolo Bonzini
Il 17/05/2012 04:28, Zhang, Yang Z ha scritto:
> 
> +static int32_t divider_reset;

This must be a variable inside RTCState.

The remark about inlining rtc_set_offset applies here as well.

Paolo

> +static inline bool rtc_running(RTCState *s)
> +{
> +return (!(s->cmos_data[RTC_REG_B] & REG_B_SET) &&
> +(s->cmos_data[RTC_REG_A] & 0x70) <= 0x20);
> +}
> +




Re: [Qemu-devel] [PATCH 1.1 V2] xen: Fix PV-on-HVM

2012-05-17 Thread Stefano Stabellini
On Wed, 16 May 2012, Anthony PERARD wrote:
> In the context of PV-on-HVM under Xen, the emulated nics are supposed to be
> unplug before the guest drivers are initialized, when the guest write to a
> specific IO port.
> 
> Without this patch, the guest end up with two nics with the same MAC, the
> emulated nic and the PV nic.
> 
> Signed-off-by: Anthony PERARD 
> ---

I think that the patch is correct and a good candidate for rc3. Any
comments?


>  hw/xen_platform.c |5 -
>  1 files changed, 4 insertions(+), 1 deletions(-)
> 
> diff --git a/hw/xen_platform.c b/hw/xen_platform.c
> index a9c52a6..0214f37 100644
> --- a/hw/xen_platform.c
> +++ b/hw/xen_platform.c
> @@ -87,7 +87,10 @@ static void unplug_nic(PCIBus *b, PCIDevice *d)
>  {
>  if (pci_get_word(d->config + PCI_CLASS_DEVICE) ==
>  PCI_CLASS_NETWORK_ETHERNET) {
> -qdev_unplug(&(d->qdev), NULL);
> +/* Until qdev_free includes a call to object_unparent, we call it 
> here
> + */
> +object_unparent(&d->qdev.parent_obj);
> +qdev_free(&d->qdev);
>  }
>  }
>  
> -- 
> Anthony PERARD
> 



Re: [Qemu-devel] [PATCH v6 2/7] RTC: Update the RTC clock only when reading it

2012-05-17 Thread Paolo Bonzini
Note: I haven't tested this series yet.  Thanks for finding the problem!

Il 17/05/2012 04:28, Zhang, Yang Z ha scritto:
> Use offset instead of timer to calculate guest rtc. Guest rtc is calculated 
> by (base_rtc + guest_time_now - guest_time_last_update_rtc + offset).
> Base_rtc means the rtc value of last update. 
> Guest_time_now means the guest time that access happens.
> Guest_time_last_update means the guest time of last update rtc.
> Offset is used when divider reset happened or set bit is changed.
> 
> +static void rtc_set_offset(RTCState *s, bool running, bool div_reset)
> +{
> +if (div_reset)
> +s->offset = 50;
> +else if (!running)
> +s->offset = s->old_guest_usec % USEC_PER_SEC;
> +}

This is probably clearer if you just inline it at the appropriate
places---especially because rtc_set_offset(s, 0, 0) is a no-op.

> -static void rtc_update_second(void *opaque)
> -{
> -RTCState *s = opaque;
> -int64_t delay;
> -
> -/* if the oscillator is not in normal operation, we do not update */
> -if ((s->cmos_data[RTC_REG_A] & 0x70) != 0x20) {
> -s->next_second_time += get_ticks_per_sec();
> -qemu_mod_timer(s->second_timer, s->next_second_time);
> -} else {
> -rtc_next_second(&s->current_tm);
> -
> -if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
> -/* update in progress bit */
> -s->cmos_data[RTC_REG_A] |= REG_A_UIP;
> -}
> -/* should be 244 us = 8 / 32768 seconds, but currently the
> -   timers do not have the necessary resolution. */
> -delay = (get_ticks_per_sec() * 1) / 100;
> -if (delay < 1)
> -delay = 1;
> -qemu_mod_timer(s->second_timer2,
> -   s->next_second_time + delay);
> -}
> -}

This patch breaks REG_A_UIP.  You can squash patches 2 and 3 together to
avoid this problem.

Paolo



Re: [Qemu-devel] [PATCH 1.1 V2] xen: Fix PV-on-HVM

2012-05-17 Thread Paolo Bonzini
Il 17/05/2012 12:35, Stefano Stabellini ha scritto:
> On Wed, 16 May 2012, Anthony PERARD wrote:
>> In the context of PV-on-HVM under Xen, the emulated nics are supposed to be
>> unplug before the guest drivers are initialized, when the guest write to a
>> specific IO port.
>>
>> Without this patch, the guest end up with two nics with the same MAC, the
>> emulated nic and the PV nic.
>>
>> Signed-off-by: Anthony PERARD 
>> ---
> 
> I think that the patch is correct and a good candidate for rc3. Any
> comments?

Yes, it's certainly nice when patches become as simple as this one. :)

Acked-by: Paolo Bonzini 

> 
>>  hw/xen_platform.c |5 -
>>  1 files changed, 4 insertions(+), 1 deletions(-)
>>
>> diff --git a/hw/xen_platform.c b/hw/xen_platform.c
>> index a9c52a6..0214f37 100644
>> --- a/hw/xen_platform.c
>> +++ b/hw/xen_platform.c
>> @@ -87,7 +87,10 @@ static void unplug_nic(PCIBus *b, PCIDevice *d)
>>  {
>>  if (pci_get_word(d->config + PCI_CLASS_DEVICE) ==
>>  PCI_CLASS_NETWORK_ETHERNET) {
>> -qdev_unplug(&(d->qdev), NULL);
>> +/* Until qdev_free includes a call to object_unparent, we call it 
>> here
>> + */
>> +object_unparent(&d->qdev.parent_obj);
>> +qdev_free(&d->qdev);
>>  }
>>  }
>>  
>> -- 
>> Anthony PERARD
>>




Re: [Qemu-devel] Add support for new image type

2012-05-17 Thread Artyom Tarasenko
On Thu, May 17, 2012 at 11:41 AM, Paolo Bonzini  wrote:
> To help me better understand, what would
>>> be the terminology used for the explanation between what I would call
>>> "source code" licensing, and "project" licensing? Also, where in the code
>>> (or rather what file) can I see this distinction? It seems like something
>>> critical to be aware of, and I'd like to avoid missing something like this
>>> in the future as I give advice on what software we can use.
>
> Roughly speaking, each file has its own license.  So you can take for
> example vl.c or tcg/* and use it in a proprietary program, because those
> are under a non-copyleft license.  You cannot do the same for
> event_notifier.c, because it is released under GPLv2 or later.
>
> For the project to be distributable at all, there has to be a license
> that is compatible with all the others: such a license has to allow all
> restrictions imposed by the other licenses used in the project, and all
> other licenses have to allow all restrictions imposed by such a license.
>  For QEMU this license is the GPLv2.

Strictly speaking it must be GPLv2 with exceptions/restrictions. The code
can not be moved freely between GPL and BSD licensed files.
Why the GPL->BSD move is illegal is obvious.
The BSD->GPL move is not allowed because of the :

" * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software."

clause of the BSD license.

So the result of GPL and BSD intersection must be GPL with some files
licensed under BSD.

>>> If you would help clarify a separate point, I would be grateful. As I
>>> understand it, I am able to modify qemu for my own purposes (like testing
>>> the filesystem integrity inside a backup image by using guestmount to mount
>>> it). How much of that work (source code, principles, explanations, ect) can
>>> I share, and with whom can I share it with?
>
> Principles, explanations can be shared with whoever you want, however
> you want.  Patches are more of a grey area and I suggest you consult a
> (good) lawyer.
>
> Remember that the GPL only becomes relevant once you start distributing
> code.  As long as you share the changes within your company for example
> you are safe.  Here is what the GPL FAQ says:
>
>   Is making and using multiple copies within one organization or
>   company “distribution”? (#InternalDistribution)
>
>   No, in that case the organization is just making the copies for
>   itself. As a consequence, a company or other organization can
>   develop a modified version and install that version through its own
>   facilities, without giving the staff permission to release that
>   modified version to outsiders.
>
>   However, when the organization transfers copies to other
>   organizations or individuals, that is distribution. In particular,
>   providing copies to contractors for use off-site is distribution.
>
> What you suggested with run-time linking sounds like you are adding a
> functionality that is totally useless to the general public.  Those
> people who are able to combine it with the shared library could use it
> as in the above answer without distributing the result.
>
> Morally it's wrong, but a copyright holder cannot stop you on moral
> grounds.  Legally, you should consult a lawyer.  Practically:
>
> - if you go with iSCSI or something like that you would provide the same
> functionality to your customers, keep clear from legal grey areas, and
> the QEMU community probably could not care less.
>
> - if you go with a clean reimplementation under the GPL you would
> provide the same functionality to your customers, keep clear from legal
> grey areas, contribute to QEMU positively, and perhaps get some
> advertising for your product.
>
> Paolo



-- 
Regards,
Artyom Tarasenko

solaris/sparc under qemu blog: http://tyom.blogspot.com/search/label/qemu



Re: [Qemu-devel] [PATCH 03/15] Openrisc: add instructions translation

2012-05-17 Thread Max Filippov
Hi.

I've got a couple of questions/suggestions regarding the code.

On Thu, May 17, 2012 at 12:35 PM, Jia Liu  wrote:
> add the openrisc instructions translation.
>
> Signed-off-by: Jia Liu 

[...]

> +    case 0x0009:
> +        switch (op1) {
> +        case 0x03:   /*l.div*/
> +            LOG_DIS("l.div r%d, r%d, r%d\n", rd, ra, rb);
> +            if (rb != 0) {
> +                tcg_gen_div_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);

You also need to take care of integer overflow/division by zero here,
otherwise it may crash QEMU.

> +            } else {
> +                /* exception here */
> +            }
> +            break;
> +        default:
> +            break;
> +        }
> +        break;
> +
> +    case 0x000a:
> +        switch (op1) {
> +        case 0x03:   /*l.divu*/
> +            LOG_DIS("l.divu r%d, r%d, r%d\n", rd, ra, rb);
> +            if (rb != 0) {
> +                tcg_gen_divu_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
> +            } else {
> +                /* exception here */
> +            }
> +            break;
> +        default:
> +            break;
> +        }
> +        break;
> +
> +    case 0x000b:
> +        switch (op1) {
> +        case 0x03:   /*l.mulu*/
> +            LOG_DIS("l.mulu r%d, r%d, r%d\n", rd, ra, rb);
> +            if (rb != 0 && ra != 0) {
> +                tcg_gen_ext32u_tl(cpu_R[ra], cpu_R[ra]);
> +                tcg_gen_ext32u_tl(cpu_R[rb], cpu_R[rb]);

This code would clobber high 32 bits of ra and rb if it was compiled
for 64 bit registers.
Are you going to support both 32 and 64 bit version of the ISA?
Could you please clarify *_tl usage here?

> +                tcg_gen_mul_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
> +            } else {
> +                tcg_gen_movi_tl(cpu_R[rd], 0);
> +            }
> +            break;
> +        default:
> +            break;
> +        }
> +        break;
> +
> +    case 0x000e:
> +        switch (op1) {
> +        case 0x00:   /*l.cmov*/
> +            LOG_DIS("l.cmov r%d, r%d, r%d\n", rd, ra, rb);
> +            {
> +                int lab = gen_new_label();
> +                TCGv sr_f = tcg_temp_new();
> +                tcg_gen_andi_tl(sr_f, cpu_sr, SR_F);
> +                tcg_gen_mov_tl(cpu_R[rd], cpu_R[rb]);
> +                tcg_gen_brcondi_tl(TCG_COND_NE, sr_f, SR_F, lab);

There may be an issue when rd == ra and the branch is not taken

> +                tcg_gen_mov_tl(cpu_R[rd], cpu_R[ra]);
> +                gen_set_label(lab);
> +                tcg_temp_free(sr_f);
> +            }
> +            break;
> +        default:
> +            break;
> +        }
> +        break;

[...]

> +    case 0x13:    /*l.maci*/
> +        {
> +            LOG_DIS("l.maci %d, r%d, %d\n", I5, ra, I11);
> +            TCGv_i64 tra = tcg_temp_new_i64();    /*  store cpu_R[ra]*/
> +            TCGv_i64 tmac = tcg_temp_new_i64();   /*  store machi maclo*/
> +            tcg_gen_movi_tl(t0, tmp);
> +            tcg_gen_ext32s_i64(tra, cpu_R[ra]);
> +            tcg_gen_ext32s_i64(tmac, t0);
> +            tcg_gen_mul_tl(tmac, tra, tmac);
> +            tcg_gen_trunc_i64_i32(cpu_R[ra], tmac);
> +            tcg_gen_add_i64(machi, machi, cpu_R[ra]);
> +            tcg_gen_add_i64(maclo, maclo, cpu_R[ra]);
> +            tcg_temp_free(tra);
> +            tcg_temp_free(tmac);
> +        }
> +        break;

[...]

> +static void dec_mac(DisasContext *dc, CPUOPENRISCState *env, uint32_t insn)
> +{
> +    uint32_t op0;
> +    uint32_t ra, rb;
> +    op0 = field(insn, 0, 4);
> +    ra = field(insn, 16, 5);
> +    rb = field(insn, 11, 5);
> +    TCGv_i64 t0 = tcg_temp_new();
> +    TCGv_i64 t1 = tcg_temp_new();
> +    switch (op0) {
> +    case 0x0001:   /*l.mac*/
> +        {
> +            LOG_DIS("l.mac r%d, r%d\n", ra, rb);
> +            tcg_gen_ext_i32_i64(t0, cpu_R[ra]);
> +            tcg_gen_ext_i32_i64(t1, cpu_R[rb]);
> +            tcg_gen_mul_i64(t0, t0, t1);
> +            tcg_gen_trunc_i64_i32(cpu_R[ra], t0);
> +            tcg_gen_add_tl(maclo, maclo, cpu_R[ra]);
> +            tcg_gen_add_tl(machi, machi, cpu_R[ra]);

>From the ISA I've got an impression that mac/maci should be
implemented like this (signedness left alone):

tcg_gen_mul_tl(t0, cpu_R[ra], cpu_R[rb]);
tcg_gen_ext_i32_i64(t1, t0);
tcg_gen_concat_i32_i64(t2, maclo, machi);
tcg_gen_add_i64(t2, t2, t1);
tcg_gen_trunc_i64(maclo, t2);
tcg_gen_shri_i64(t2, t2, 32);
tcg_gen_trunc_i64(machi, t2);

[...]

> +static void dec_float(DisasContext *dc, CPUOPENRISCState *env, uint32_t insn)
> +{
> +    uint32_t op0;
> +    uint32_t ra, rb, rd;
> +    op0 = field(insn, 0, 8);
> +    ra = field(insn, 16, 5);
> +    rb = field(insn, 11, 5);
> +    rd = field(insn, 21, 5);
> +
> +    switch (op0) {
> +    case 0x10:    /*lf.add.d*/
> +        LOG_DIS("lf.add.d r%d, r%d, r%d\n", rd, ra, rb);
> +        tcg_gen_add_i64(cpu_R[rd], cpu_R[ra], cpu_R[rb]);

Through t

Re: [Qemu-devel] [QEMU 1.1 PATCH] Expose CPUID leaf 7 only for -cpu host

2012-05-17 Thread Eduardo Habkost
On Wed, May 16, 2012 at 09:32:44PM -0500, Anthony Liguori wrote:
> On 05/16/2012 03:58 PM, Eduardo Habkost wrote:
> >Description of the bug:
> >
> >Since QEMU 0.15, the CPUID information on CPUID[EAX=7,ECX=0] is being
> >returned unfiltered to the guest, directly from the GET_SUPPORTED_CPUID
> >return value.
> >
> >The problem is that this makes the resulting CPU feature flags
> >unpredictable and dependent on the host CPU and kernel version.
> 
> But isn't this exactly what you get with -cpu host?  I mean, the
> whole point is that you're getting whatever the best set of flags
> that can be exposed by the hardware.

Exactly, this is the point of -cpu host, but not when _not_ using CPU
host. This happens unconditionally today, for all users.

> 
> >This
> >breaks live-migration badly if you try to migrate from a host CPU that
> >supports some features on that CPUID leaf (running a recent kenrel) to a
> >kernel or host CPU that doesn't support it.
> 
> This seems like expected behavior to me.

I am not sure I understand your point. This is expected behavior only
for -cpu host, and this is what this patch does: changes the code so
that this behavior is enabled only if using -cpu host.

> 
> Regards,
> 
> Anthony Liguori
> 
> >Migration also is incorrect (the virtual CPU changes under the guest's
> >feet) if you migrate in the opposite direction (from an old CPU/kernel
> >to a new CPU/kernel), but with less serious consequences (guests
> >normally query CPUID information only once on boot).
> >
> >Fortunately, the bug affects only users using cpudefs with level>= 7.
> >
> >The right behavior should be to explicitly enable those features on
> >[cpudef] config sections or on the "-cpu" command-line arguments. Right
> >now there is no predefined CPU model on QEMU that has those features:
> >the latest Intel model we have is Sandy Bridge.
> >
> >I would like to get this fixed on 1.1, so I am submitting this patch,
> >that enables those features only if "-cpu host" is being used (as we
> >don't have any pre-defined CPU model that actually have those features).
> >After 1.1 is released, we can make those features properly configurable
> >on [cpudef] and -cpu configuration.
> >
> >One problem is: with this patch, users with the following setup:
> >- Running QEMU 1.0;
> >- Using a cpudef having level>= 7; and
> >- Running a kernel that supports the features on CPUID leaf 7;
> >- Running on a CPU that supports some features on CPUID leaf 7.
> >won't be able to live-migrate to QEMU 1.1. But for these users
> >live-migration is already broken (they can't live-migrate to hosts with
> >older CPUs or older kernels, already), I don't see how to avoid this
> >problem.
> >
> >Signed-off-by: Eduardo Habkost
> >---
> >  target-i386/cpu.c |   24 +---
> >  target-i386/cpu.h |2 ++
> >  2 files changed, 19 insertions(+), 7 deletions(-)
> >
> >diff --git a/target-i386/cpu.c b/target-i386/cpu.c
> >index 89b4ac7..c75fa3d 100644
> >--- a/target-i386/cpu.c
> >+++ b/target-i386/cpu.c
> >@@ -238,6 +238,8 @@ typedef struct x86_def_t {
> >  /* Store the results of Centaur's CPUID instructions */
> >  uint32_t ext4_features;
> >  uint32_t xlevel2;
> >+/* The feature bits on CPUID[EAX=7,ECX=0].EBX */
> >+uint32_t cpuid_7_0_ebx_features;
> >  } x86_def_t;
> >
> >  #define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
> >@@ -521,6 +523,13 @@ static int cpu_x86_fill_host(x86_def_t *x86_cpu_def)
> >  x86_cpu_def->ext_features = ecx;
> >  x86_cpu_def->features = edx;
> >
> >+if (x86_cpu_def->level>= 7) {
> >+host_cpuid(0x7, 0,&eax,&ebx,&ecx,&edx);
> >+x86_cpu_def->cpuid_7_0_ebx_features = ebx;
> >+} else {
> >+x86_cpu_def->cpuid_7_0_ebx_features = 0;
> >+}
> >+
> >  host_cpuid(0x8000, 0,&eax,&ebx,&ecx,&edx);
> >  x86_cpu_def->xlevel = eax;
> >
> >@@ -1185,6 +1194,7 @@ int cpu_x86_register(X86CPU *cpu, const char 
> >*cpu_model)
> >  env->cpuid_kvm_features = def->kvm_features;
> >  env->cpuid_svm_features = def->svm_features;
> >  env->cpuid_ext4_features = def->ext4_features;
> >+env->cpuid_7_0_ebx = def->cpuid_7_0_ebx_features;
> >  env->cpuid_xlevel2 = def->xlevel2;
> >  object_property_set_int(OBJECT(cpu), (int64_t)def->tsc_khz * 1000,
> >  "tsc-frequency",&error);
> >@@ -1451,13 +1461,13 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
> >uint32_t count,
> >  *edx = 0;
> >  break;
> >  case 7:
> >-if (kvm_enabled()) {
> >-KVMState *s = env->kvm_state;
> >-
> >-*eax = kvm_arch_get_supported_cpuid(s, 0x7, count, R_EAX);
> >-*ebx = kvm_arch_get_supported_cpuid(s, 0x7, count, R_EBX);
> >-*ecx = kvm_arch_get_supported_cpuid(s, 0x7, count, R_ECX);
> >-*edx = kvm_arch_get_supported_cpuid(s, 0x7, count, R_EDX);
> >+/* Structured Extended Feature Flags Enumeration Leaf
> >+ */
> >+  

Re: [Qemu-devel] [PATCH v10 8/9] Add set_cachesize command

2012-05-17 Thread Orit Wasserman
On 05/17/2012 12:46 PM, Avi Kivity wrote:
> On 05/16/2012 08:58 PM, Eric Blake wrote:
>> On 05/16/2012 11:04 AM, Orit Wasserman wrote:
>>
> +- "value": cache size in bytes (json-int)

 Would it be any easier to take 'order' (log2 of the size) instead of the
 actual cache size?  That is, instead of calling "value":1048576, I would
 rather type "value":20.
>>> Well the user is considering how much memory is going to be used and I 
>>> though that it
>>> is simpler to use 1G than 30.
>>
>> Libvirt can cope with either style, so maybe it's worth waiting for
>> anyone else to chime in on which style is easier.
> 
> Let's be consistent.  It's best to use bytes everywhere (not kilobytes,
> not megabytes, not pages, not order, or anything else we can come up with).
> 
> If you really want to specify order (not that I can think of a reason
> why), we can use a suffix: 20ORD == 1M == 1048576.
That is what used at the moment.
> 
> btw, maybe it's better to handle a non-power-of-two cache size by
> rounding down.  Less errors, less puzzlement, and less memory used.
Sounds good to me.

Orit
> 




Re: [Qemu-devel] [QEMU 1.1 PATCH] Expose CPUID leaf 7 only for -cpu host

2012-05-17 Thread Eduardo Habkost
On Wed, May 16, 2012 at 05:58:05PM -0300, Eduardo Habkost wrote:
[...]
> @@ -521,6 +523,13 @@ static int cpu_x86_fill_host(x86_def_t *x86_cpu_def)
>  x86_cpu_def->ext_features = ecx;
>  x86_cpu_def->features = edx;
>  
> +if (x86_cpu_def->level >= 7) {
> +host_cpuid(0x7, 0, &eax, &ebx, &ecx, &edx);
> +x86_cpu_def->cpuid_7_0_ebx_features = ebx;
> +} else {
> +x86_cpu_def->cpuid_7_0_ebx_features = 0;
> +}
> +

Ouch: it looks like -cpu host isn't using GET_SUPPORTED_CPUID at all,
host_cpuid() is a raw cpuid instruction. I am surprised -cpu host works
at all (probably it breaks in interesting ways if running on a new CPU
and a not-very-new kernel).

I will send v2 of this patch, to use GET_SUPPORTED_CPUID at least for
cpuid_7_0_ebx_features.

It is still a bug to not filter the remaining CPUID leaves using
GET_SUPPORTED_CPUID, but I am not sure we would have enough time for
testing if we try to fix all that in 1.1.

-- 
Eduardo



Re: [Qemu-devel] [QEMU] net: adapt dump to support the new syntax

2012-05-17 Thread Paolo Bonzini
Il 17/05/2012 12:05, Zhi Yong Wu ha scritto:
> On Thu, May 17, 2012 at 5:51 PM, Paolo Bonzini  wrote:
>>> This case has existed in current upstream code, not only vlan-hub
>>> code. Currently can_send function has been called by backend send
>>> function before deliver/deliver_iov, If we put can_send in queue send
>>> function, your idea will have a big challenge for slirp packet queue.
>>
>> Exactly why?  For SLIRP's receive path, SLIRP doesn't implement
>> can_receive at all so it will never block.  For the send path, when flow
>> control kicks qemu_net_queue_append will copy the packet so it is not a
>> problem for SLIRP's stack-allocated packets.
>
> You know that qemu_send_packet is void type, and has return value, if
> can_send fails, if_encap will not currently get expected return value,
> so this will cause that we have to modify the definition of
> qemu_send_packet to make it return one valid value. a lot of functions
> have called it, so i would not like to modify its definition.

If qemu_can_send_packet returns false of course I would not drop the
packet.  I would append it to the queue (qemu_net_queue_append) for
later processing.

>>> We can implement your idea below later, not in this patchset. What do
>>> you think?
>>
>> Note that my idea above was only means to an end.  If you can remove the
>> TODOs in a convincing manner, that would be fine.
> You mean that we need adopt another handling way? or directly TODO comments?

You need to address the TODOs.  I proposed a way.  It may actually not
be correct, and there may of course be others.  But the TODOs are there,
and have to be solved.

Paolo



[Qemu-devel] [RFC][PATCH v2 02/11] msix: Invoke msix_handle_mask_update on msix_mask_all

2012-05-17 Thread Jan Kiszka
From: Jan Kiszka 

In preparation of firing vector notifiers on mask changes, call
msix_handle_mask_update also from msix_mask_all. So far, this will have
no real effect.

Signed-off-by: Jan Kiszka 
---
 hw/msix.c |4 
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/hw/msix.c b/hw/msix.c
index 3197465..e1a7d92 100644
--- a/hw/msix.c
+++ b/hw/msix.c
@@ -231,10 +231,14 @@ static void msix_mmio_setup(PCIDevice *d, MemoryRegion 
*bar)
 static void msix_mask_all(struct PCIDevice *dev, unsigned nentries)
 {
 int vector;
+
 for (vector = 0; vector < nentries; ++vector) {
 unsigned offset =
 vector * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_VECTOR_CTRL;
+bool was_masked = msix_is_masked(dev, vector);
+
 dev->msix_table_page[offset] |= PCI_MSIX_ENTRY_CTRL_MASKBIT;
+msix_handle_mask_update(dev, vector, was_masked);
 }
 }
 
-- 
1.7.3.4




[Qemu-devel] [RFC][PATCH v2 01/11] msix: Factor out msix_get_message

2012-05-17 Thread Jan Kiszka
From: Jan Kiszka 

This helper will also be used by the upcoming config notifier.

Signed-off-by: Jan Kiszka 
---
 hw/msix.c |   19 +--
 1 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/hw/msix.c b/hw/msix.c
index 3835eaa..3197465 100644
--- a/hw/msix.c
+++ b/hw/msix.c
@@ -35,6 +35,15 @@
 #define MSIX_PAGE_PENDING (MSIX_PAGE_SIZE / 2)
 #define MSIX_MAX_ENTRIES 32
 
+static MSIMessage msix_get_message(PCIDevice *dev, unsigned vector)
+{
+uint8_t *table_entry = dev->msix_table_page + vector * PCI_MSIX_ENTRY_SIZE;
+MSIMessage msg;
+
+msg.address = pci_get_quad(table_entry + PCI_MSIX_ENTRY_LOWER_ADDR);
+msg.data = pci_get_long(table_entry + PCI_MSIX_ENTRY_DATA);
+return msg;
+}
 
 /* Add MSI-X capability to the config space for the device. */
 /* Given a bar and its size, add MSI-X table on top of it
@@ -352,9 +361,7 @@ uint32_t msix_bar_size(PCIDevice *dev)
 /* Send an MSI-X message */
 void msix_notify(PCIDevice *dev, unsigned vector)
 {
-uint8_t *table_entry = dev->msix_table_page + vector * PCI_MSIX_ENTRY_SIZE;
-uint64_t address;
-uint32_t data;
+MSIMessage msg;
 
 if (vector >= dev->msix_entries_nr || !dev->msix_entry_used[vector])
 return;
@@ -363,9 +370,9 @@ void msix_notify(PCIDevice *dev, unsigned vector)
 return;
 }
 
-address = pci_get_quad(table_entry + PCI_MSIX_ENTRY_LOWER_ADDR);
-data = pci_get_long(table_entry + PCI_MSIX_ENTRY_DATA);
-stl_le_phys(address, data);
+msg = msix_get_message(dev, vector);
+
+stl_le_phys(msg.address, msg.data);
 }
 
 void msix_reset(PCIDevice *dev)
-- 
1.7.3.4




[Qemu-devel] [RFC][PATCH v2 09/11] kvm: Enable use of kvm_irqchip_in_kernel in hwlib code

2012-05-17 Thread Jan Kiszka
From: Jan Kiszka 

Provide a dummy kvm_kernel_irqchip so that kvm_irqchip_in_kernel can be
used by code that is not under CONFIG_KVM protection.

Signed-off-by: Jan Kiszka 
---
 kvm-stub.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/kvm-stub.c b/kvm-stub.c
index b4cf03f..ec9a364 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -18,6 +18,7 @@
 #include "kvm.h"
 
 KVMState *kvm_state;
+bool kvm_kernel_irqchip;
 
 int kvm_init_vcpu(CPUArchState *env)
 {
-- 
1.7.3.4




Re: [Qemu-devel] Signal management in qemu-user

2012-05-17 Thread Peter Maydell
On 17 May 2012 14:33, Andreas Färber  wrote:
> Am 17.05.2012 11:23, schrieb Alex Barcelo:
>> Running it in a i386 machine works and gives an output of "0x0d\n0x20".
>> Running it in a qemu-i386 segfaults. Because the self-modifying code
>> raises a SIGSEGV in the qemu (I understand that it is the method used by
>> qemu to handle self-modifying code). But the sigprocmask disables the
>> SIGSEGV and the qemu-user... does nothing to avoid it. So the SIGSEGV is
>> unmanaged and breaks the program.
>
> Alex has the following SIGSEGV workaround queued for our openSUSE package:
> http://repo.or.cz/w/qemu/agraf.git/commit/0760e24b52ff20a328f168ed23b52c9b9c0fd28f
>
> Don't know if it fixes your specific problem.

No, that's a different issue, see the analysis here:
 http://lists.gnu.org/archive/html/qemu-devel/2012-02/msg02868.html
In that case an internal-to-QEMU allocation fails (because the guest
imposes a severe rlimit), we don't handle it very well and die
horribly. The commit you link to above is a sticking plaster on
the problem and definitely not OK for master.

> Peter had some ideas how to refactor signal handling but iirc
> didn't have time to work on it himself.

That was mostly to do with solving the problem of signals occurring
during emulation of a system call and the consequent race conditions:
 http://lists.gnu.org/archive/html/qemu-devel/2011-12/msg00384.html

I think Alex Barcelo's problem here is unrelated. I'm not very
surprised by it, though -- linux-user is not very robust in
complex edge cases (and in particular is really poor for
threaded programs).

-- PMM



Re: [Qemu-devel] [libvirt] [RFC 0/5] block: File descriptor passing using -open-hook-fd

2012-05-17 Thread Stefan Hajnoczi
On Fri, May 04, 2012 at 11:28:47AM +0800, Zhi Yong Wu wrote:
> On Tue, May 1, 2012 at 11:31 PM, Stefan Hajnoczi
>  wrote:
> > Libvirt can take advantage of SELinux to restrict the QEMU process and 
> > prevent
> > it from opening files that it should not have access to.  This improves
> > security because it prevents the attacker from escaping the QEMU process if
> > they manage to gain control.
> >
> > NFS has been a pain point for SELinux because it does not support labels 
> > (which
> > I believe are stored in extended attributes).  In other words, it's not
> > possible to use SELinux goodness on QEMU when image files are located on 
> > NFS.
> > Today we have to allow QEMU access to any file on the NFS export rather than
> > restricting specifically to the image files that the guest requires.
> >
> > File descriptor passing is a solution to this problem and might also come in
> > handy elsewhere.  Libvirt or another external process chooses files which 
> > QEMU
> > is allowed to access and provides just those file descriptors - QEMU cannot
> > open the files itself.
> >
> > This series adds the -open-hook-fd command-line option.  Whenever QEMU 
> > needs to
> > open an image file it sends a request over the given UNIX domain socket.  
> > The
> > response includes the file descriptor or an errno on failure.  Please see 
> > the
> > patches for details on the protocol.
> >
> > The -open-hook-fd approach allows QEMU to support file descriptor passing
> > without changing -drive.  It also supports snapshot_blkdev and other 
> > commands
> By the way, How will it support them?

The problem with snapshot_blkdev is that closing a file and opening a
new file cannot be done by the QEMU process when an SELinux policy is in
place to prevent opening files.

The -open-hook-fd approach works even when the QEMU process is not
allowed to open files since file descriptor passing over a UNIX domain
socket is used to open files on behalf of QEMU.

Stefan




[Qemu-devel] [PATCH] qemu-img: Implement 'diff' operation.

2012-05-17 Thread Richard W.M. Jones
From: "Richard W.M. Jones" 

This produces a qcow2 file which is the different between
two disk images.  ie, if:

  original.img - is a disk image (in any format)
  modified.img - is a modified version of original.img

then:

  qemu-img diff -b original.img modified.img diff.qcow2

creates 'diff.qcow2' which contains just the differences.  Note that
'diff.qcow2' has 'original.img' set as the backing file.

Signed-off-by: Richard W.M. Jones 
Cc: Matthew Booth 
Cc: Pablo Iranzo Gómez 
Cc: Tomas Von Veschler 
---
 qemu-img-cmds.hx |6 +++
 qemu-img.c   |  150 ++
 qemu-img.texi|   17 +++
 3 files changed, 173 insertions(+)

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 49dce7c..01a9246 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -33,6 +33,12 @@ STEXI
 @item convert [-c] [-p] [-f @var{fmt}] [-t @var{cache}] [-O @var{output_fmt}] 
[-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] 
@var{filename} [@var{filename2} [...]] @var{output_filename}
 ETEXI
 
+DEF("diff", img_diff,
+"diff [-f fmt] [-F backing_fmt] [-O output_fmt] -b backing_file filename 
output_filename")
+STEXI
+@item rebase [-f @var{fmt}] [-F @var{backing_fmt}] [-O @var{output_fmt}] -b 
@var{backing_file} @var{filename} @var{output_filename}
+ETEXI
+
 DEF("info", img_info,
 "info [-f fmt] filename")
 STEXI
diff --git a/qemu-img.c b/qemu-img.c
index c8a70ff..6e3fe2a 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -1533,6 +1533,156 @@ out:
 return 0;
 }
 
+static int img_diff(int argc, char **argv)
+{
+/* qemu-img diff -b original modified out */
+BlockDriverState *bs_original, *bs_modified, *bs_out;
+const char *fmt_original, *original,
+*fmt_modified, *modified,
+*fmt_out, *out;
+int c, ret = 0;
+uint64_t num_sectors, modified_num_sectors;
+uint64_t sector;
+int n;
+uint8_t *buf_original;
+uint8_t *buf_modified;
+
+/* Parse commandline parameters */
+fmt_original = NULL;
+fmt_modified = NULL;
+fmt_out = NULL;
+original = NULL;
+for(;;) {
+c = getopt(argc, argv, "hf:F:b:O:");
+if (c == -1) {
+break;
+}
+switch(c) {
+case '?':
+case 'h':
+help();
+return 0;
+case 'f':
+fmt_modified = optarg;
+break;
+case 'F':
+fmt_original = optarg;
+break;
+case 'b':
+original = optarg;
+break;
+case 'O':
+fmt_out = optarg;
+break;
+}
+}
+
+if (original == NULL) {
+error_report("The -b (backing filename) option must be supplied");
+return 1;
+}
+
+if (argc - optind != 2) {
+error_report("The input and output filenames must be supplied");
+return 1;
+}
+modified = argv[optind++];
+out = argv[optind++];
+
+/* Open the input images. */
+bs_original = bdrv_new_open(original, fmt_original, BDRV_O_FLAGS);
+if (!bs_original) {
+return 1;
+}
+
+bs_modified = bdrv_new_open(modified, fmt_modified, BDRV_O_FLAGS);
+if (!bs_modified) {
+return 1;
+}
+
+bdrv_get_geometry(bs_original, &num_sectors);
+bdrv_get_geometry(bs_modified, &modified_num_sectors);
+if (num_sectors != modified_num_sectors) {
+error_report("Number of sectors in backing and source must be the 
same");
+goto out2;
+}
+
+/* Output image. */
+if (fmt_out == NULL || fmt_out[0] == '\0') {
+fmt_out = "qcow2";
+}
+ret = bdrv_img_create(out, fmt_out,
+  /* original file becomes the new backing file */
+  original, fmt_original,
+  NULL, num_sectors * BDRV_SECTOR_SIZE, BDRV_O_FLAGS);
+if (ret != 0) {
+goto out2;
+}
+bs_out = bdrv_new_open(out, fmt_out, BDRV_O_RDWR);
+
+buf_original = qemu_blockalign(bs_original, IO_BUF_SIZE);
+buf_modified = qemu_blockalign(bs_modified, IO_BUF_SIZE);
+
+for (sector = 0; sector < num_sectors; sector += n) {
+/* How many sectors can we handle with the next read? */
+if (sector + (IO_BUF_SIZE / BDRV_SECTOR_SIZE) <= num_sectors) {
+n = IO_BUF_SIZE / BDRV_SECTOR_SIZE;
+} else {
+n = num_sectors - sector;
+}
+
+/* Read input files and compare. */
+ret = bdrv_read(bs_original, sector, buf_original, n);
+if (ret < 0) {
+error_report("error while reading from backing file");
+goto out;
+}
+
+ret = bdrv_read(bs_modified, sector, buf_modified, n);
+if (ret < 0) {
+error_report("error while reading from input file");
+goto out;
+}
+
+/* If they differ, we need to write to the differences file. */
+uint64_t written = 0;
+
+while (written < n) {
+int

Re: [Qemu-devel] [PATCH] Add event notification for guest balloon changes

2012-05-17 Thread Luiz Capitulino
On Thu, 17 May 2012 08:49:44 +0100
"Daniel P. Berrange"  wrote:

> On Wed, May 16, 2012 at 01:58:34PM -0500, Anthony Liguori wrote:
> > On 05/16/2012 01:42 PM, Luiz Capitulino wrote:
> > >On Wed, 16 May 2012 11:10:47 +0100
> > >"Daniel P. Berrange"  wrote:
> > >
> > >>From: "Daniel P. Berrange"
> > >>
> > >>After setting a balloon target value, applications have to
> > >>continually poll 'query-balloon' to determine whether the
> > >>guest has reacted to this request. The virtio-balloon backend
> > >>knows exactly when the guest has reacted though, and thus it
> > >>is possible to emit a JSON event to tell the mgmt application
> > >>whenever the guest balloon changes.
> > >>
> > >>This introduces a new 'qemu_balloon_change()' API which is
> > >>to be called by balloon driver backends, whenever they have
> > >>a change in balloon value. This takes the 'actual' balloon
> > >>value, as would be found in the BalloonInfo struct.
> > >>
> > >>The qemu_balloon_change API emits a JSON monitor event which
> > >>looks like:
> > >>
> > >>   {"timestamp": {"seconds": 1337162462, "microseconds": 814521},
> > >>"event": "BALLOON_CHANGE", "data": {"actual": 944766976}}
> > >
> > >It's missing an entry in QMP/qmp-events.txt and I have a comment below,
> > >but in general looks good.
> > >
> > >Amit, would be good to get your ack.
> > 
> > I think it would be safer to limit this event to (1) only firing
> > once target has been reached (2) firing if target is deviated from
> > without a corresponding change in target.
> > 
> > Otherwise, a guest could just flood libvirt with events.  This would
> > queue memory in QEMU indefinitely as the events got queued up to
> > potentially serving as a DoS against other guests.
> 
> Hmm, that's a good point, but my concern was that if we only emit
> the event when the target is reached, what happens if the guest
> gets very close to the target but never actually reaches it for
> some reason.

Having a way to detect the last balloon change would be perfect.

> Should we perhaps just rate limit it to once per second ?
> 
> BTW, if we're considering guest initiated events to be a potential
> DOS in this way, then I should point out the RTC_CHANGE event
> will already suffer this way, if a malicious guest continually
> adjusts its hardware close. So we might want to apply rate limiting
> to that event too ?

I think several events can suffer from that. For example, a VNC
client could repeatedly connect & disconnect from QEMU. If we're going
to fix this, then we'd need a general solution for it.

But I think the balloon case is different, because we're not fighting
malicious guests/clients, it's really the balloon operation that can
cause the flood.



[Qemu-devel] [RFC][PATCH v2 11/11] virtio/vhost: Add support for KVM in-kernel MSI injection

2012-05-17 Thread Jan Kiszka
From: Jan Kiszka 

Make use of the new vector notifier to track changes of the MSI-X
configuration of virtio PCI devices. On enabling events, we establish
the required virtual IRQ to MSI-X message route and link the signaling
eventfd file descriptor to this vIRQ line. That way, vhost-generated
interrupts can be directly delivered to an in-kernel MSI-X consumer like
the x86 APIC.

Signed-off-by: Jan Kiszka 
---
 hw/virtio-pci.c |  126 +++
 hw/virtio-pci.h |6 +++
 2 files changed, 132 insertions(+), 0 deletions(-)

diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 4a4413d..01f5b92 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -24,6 +24,7 @@
 #include "virtio-scsi.h"
 #include "pci.h"
 #include "qemu-error.h"
+#include "msi.h"
 #include "msix.h"
 #include "net.h"
 #include "loader.h"
@@ -539,6 +540,107 @@ static void virtio_pci_guest_notifier_read(void *opaque)
 }
 }
 
+static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy,
+unsigned int queue_no,
+unsigned int vector,
+MSIMessage msg)
+{
+VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no);
+VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
+int fd, ret;
+
+fd = event_notifier_get_fd(virtio_queue_get_guest_notifier(vq));
+
+if (irqfd->users == 0) {
+ret = kvm_irqchip_add_msi_route(kvm_state, msg);
+if (ret < 0) {
+return ret;
+}
+irqfd->virq = ret;
+}
+irqfd->users++;
+
+ret = kvm_irqchip_add_irqfd(kvm_state, fd, irqfd->virq);
+if (ret < 0) {
+if (--irqfd->users == 0) {
+kvm_irqchip_release_virq(kvm_state, irqfd->virq);
+}
+return ret;
+}
+
+qemu_set_fd_handler(fd, NULL, NULL, NULL);
+
+return 0;
+}
+
+static void kvm_virtio_pci_vq_vector_release(VirtIOPCIProxy *proxy,
+ unsigned int queue_no,
+ unsigned int vector)
+{
+VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no);
+VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
+int fd, ret;
+
+fd = event_notifier_get_fd(virtio_queue_get_guest_notifier(vq));
+
+ret = kvm_irqchip_remove_irqfd(kvm_state, fd, irqfd->virq);
+assert(ret == 0);
+
+if (--irqfd->users == 0) {
+kvm_irqchip_release_virq(kvm_state, irqfd->virq);
+}
+
+qemu_set_fd_handler(fd, virtio_pci_guest_notifier_read, NULL, vq);
+}
+
+static int kvm_virtio_pci_vector_use(PCIDevice *dev, unsigned vector,
+ MSIMessage msg)
+{
+VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
+VirtIODevice *vdev = proxy->vdev;
+int ret, queue_no;
+
+for (queue_no = 0; queue_no < VIRTIO_PCI_QUEUE_MAX; queue_no++) {
+if (!virtio_queue_get_num(vdev, queue_no)) {
+break;
+}
+if (virtio_queue_vector(vdev, queue_no) != vector) {
+continue;
+}
+ret = kvm_virtio_pci_vq_vector_use(proxy, queue_no, vector, msg);
+if (ret < 0) {
+goto undo;
+}
+}
+return 0;
+
+undo:
+while (--queue_no >= 0) {
+if (virtio_queue_vector(vdev, queue_no) != vector) {
+continue;
+}
+kvm_virtio_pci_vq_vector_release(proxy, queue_no, vector);
+}
+return ret;
+}
+
+static void kvm_virtio_pci_vector_release(PCIDevice *dev, unsigned vector)
+{
+VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
+VirtIODevice *vdev = proxy->vdev;
+int queue_no;
+
+for (queue_no = 0; queue_no < VIRTIO_PCI_QUEUE_MAX; queue_no++) {
+if (!virtio_queue_get_num(vdev, queue_no)) {
+break;
+}
+if (virtio_queue_vector(vdev, queue_no) != vector) {
+continue;
+}
+kvm_virtio_pci_vq_vector_release(proxy, queue_no, vector);
+}
+}
+
 static int virtio_pci_set_guest_notifier(void *opaque, int n, bool assign)
 {
 VirtIOPCIProxy *proxy = opaque;
@@ -555,6 +657,9 @@ static int virtio_pci_set_guest_notifier(void *opaque, int 
n, bool assign)
 } else {
 qemu_set_fd_handler(event_notifier_get_fd(notifier),
 NULL, NULL, NULL);
+/* Test and clear notifier before closing it,
+ * in case poll callback didn't have time to run. */
+virtio_pci_guest_notifier_read(vq);
 event_notifier_cleanup(notifier);
 }
 
@@ -573,6 +678,13 @@ static int virtio_pci_set_guest_notifiers(void *opaque, 
bool assign)
 VirtIODevice *vdev = proxy->vdev;
 int r, n;
 
+/* Must unset vector notifier while guest notifier is still assigned */
+if (kvm_irqchip_in_kernel() && !assign) {
+msix_unset_vector_notifiers(&proxy->pci_dev);
+g_free(proxy->vector_irqfd);
+proxy->vector_irqfd = NULL;
+   

Re: [Qemu-devel] [PATCH] qemu-img: Implement 'diff' operation.

2012-05-17 Thread Peter Maydell
On 17 May 2012 14:44, Richard W.M. Jones  wrote:
> From: "Richard W.M. Jones" 
>
> This produces a qcow2 file which is the different between
> two disk images.  ie, if:
>
>  original.img - is a disk image (in any format)
>  modified.img - is a modified version of original.img
>
> then:
>
>  qemu-img diff -b original.img modified.img diff.qcow2
>
> creates 'diff.qcow2' which contains just the differences.  Note that
> 'diff.qcow2' has 'original.img' set as the backing file.

Any chance of some more detailed explanation in the docs patch
about what this actually means and why it's useful? I spent
several minutes going "huh, does it even mean anything to
calculate the difference between two binary disk images?"
before realising that it's the presence of the backing file
that makes it actually make sense...

(maybe I'm just dense :-))

-- PMM



Re: [Qemu-devel] [PATCH] qemu-img: Implement 'diff' operation.

2012-05-17 Thread Eric Blake
On 05/17/2012 07:44 AM, Richard W.M. Jones wrote:
> From: "Richard W.M. Jones" 
> 
> This produces a qcow2 file which is the different between
> two disk images.  ie, if:
> 
>   original.img - is a disk image (in any format)
>   modified.img - is a modified version of original.img
> 
> then:
> 
>   qemu-img diff -b original.img modified.img diff.qcow2
> 
> creates 'diff.qcow2' which contains just the differences.  Note that
> 'diff.qcow2' has 'original.img' set as the backing file.

Sounds useful!

>  
> +DEF("diff", img_diff,
> +"diff [-f fmt] [-F backing_fmt] [-O output_fmt] -b backing_file filename 
> output_filename")

Just so I'm clear: -f is for filename (the file with the modifications
being extracted), -F is for backing_file (the file that serves as the
base of the diff), and -O is for output_filename.

> +STEXI
> +@item rebase [-f @var{fmt}] [-F @var{backing_fmt}] [-O @var{output_fmt}] -b 
> @var{backing_file} @var{filename} @var{output_filename}

s/rebase/diff/

We also need to support -o options for the output_filename, so that we
can expose other qcow2 attributes while creating the diff.  For example,
encryption, cluster_size, and preacllocation all come to mind.


> +
> +bdrv_get_geometry(bs_original, &num_sectors);
> +bdrv_get_geometry(bs_modified, &modified_num_sectors);
> +if (num_sectors != modified_num_sectors) {
> +error_report("Number of sectors in backing and source must be the 
> same");
> +goto out2;
> +}

Why are you requiring equality?  I can see the usefulness of doing a
diff where the modified file is larger than the original (basically, the
diff was created by extending the original file to something larger).
Prohibiting a modified file smaller than the original makes sense, so I
think this should be >, not !=.

> +
> +/* Output image. */
> +if (fmt_out == NULL || fmt_out[0] == '\0') {
> +fmt_out = "qcow2";
> +}
> +ret = bdrv_img_create(out, fmt_out,
> +  /* original file becomes the new backing file */
> +  original, fmt_original,
> +  NULL, num_sectors * BDRV_SECTOR_SIZE, 
> BDRV_O_FLAGS);

If you allow a modified larger than backing, then this should be
modified_num_sectors, not num_sectors.


> +++ b/qemu-img.texi
> @@ -114,6 +114,23 @@ created as a copy on write image of the specified base 
> image; the
>  @var{backing_file} should have the same content as the input's base image,
>  however the path, image format, etc may differ.
>  
> +@item diff [-f @var{fmt}] [-F @var{backing_fmt}] [-O @var{output_fmt}] -b 
> @var{backing_file} @var{filename} @var{output_filename}
> +
> +Create a new file (@var{output_filename}) which contains the
> +differences between @var{backing_file} and @var{filename}.
> +
> +The @var{backing_file} and @var{filename} must have the same
> +virtual disk size, but may be in different formats.

Again, I think this is overly tight.

> +
> +@var{output_file} will have @var{backing_file} set as its backing
> +file.  The format of @var{output_file} must be one that supports
> +backing files (currently @code{qcow2} is the default and only
> +permitted output format).

Why doesn't qed just work out of the box?

-- 
Eric Blake   ebl...@redhat.com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [libvirt] [RFC 0/5] block: File descriptor passing using -open-hook-fd

2012-05-17 Thread Zhi Yong Wu
On Thu, May 17, 2012 at 9:42 PM, Stefan Hajnoczi
 wrote:
> On Fri, May 04, 2012 at 11:28:47AM +0800, Zhi Yong Wu wrote:
>> On Tue, May 1, 2012 at 11:31 PM, Stefan Hajnoczi
>>  wrote:
>> > Libvirt can take advantage of SELinux to restrict the QEMU process and 
>> > prevent
>> > it from opening files that it should not have access to.  This improves
>> > security because it prevents the attacker from escaping the QEMU process if
>> > they manage to gain control.
>> >
>> > NFS has been a pain point for SELinux because it does not support labels 
>> > (which
>> > I believe are stored in extended attributes).  In other words, it's not
>> > possible to use SELinux goodness on QEMU when image files are located on 
>> > NFS.
>> > Today we have to allow QEMU access to any file on the NFS export rather 
>> > than
>> > restricting specifically to the image files that the guest requires.
>> >
>> > File descriptor passing is a solution to this problem and might also come 
>> > in
>> > handy elsewhere.  Libvirt or another external process chooses files which 
>> > QEMU
>> > is allowed to access and provides just those file descriptors - QEMU cannot
>> > open the files itself.
>> >
>> > This series adds the -open-hook-fd command-line option.  Whenever QEMU 
>> > needs to
>> > open an image file it sends a request over the given UNIX domain socket.  
>> > The
>> > response includes the file descriptor or an errno on failure.  Please see 
>> > the
>> > patches for details on the protocol.
>> >
>> > The -open-hook-fd approach allows QEMU to support file descriptor passing
>> > without changing -drive.  It also supports snapshot_blkdev and other 
>> > commands
>> By the way, How will it support them?
>
> The problem with snapshot_blkdev is that closing a file and opening a
> new file cannot be done by the QEMU process when an SELinux policy is in
> place to prevent opening files.
>
> The -open-hook-fd approach works even when the QEMU process is not
> allowed to open files since file descriptor passing over a UNIX domain
> socket is used to open files on behalf of QEMU.
Do you mean that libvirt will provide QEMU with one service? When QEMU
need open or close one new file, it can send one request to libvirt?
>
> Stefan
>



-- 
Regards,

Zhi Yong Wu



Re: [Qemu-devel] [PATCH] qemu-img: Implement 'diff' operation.

2012-05-17 Thread Eric Blake
On 05/17/2012 07:52 AM, Peter Maydell wrote:
> On 17 May 2012 14:44, Richard W.M. Jones  wrote:
>> From: "Richard W.M. Jones" 
>>
>> This produces a qcow2 file which is the different between
>> two disk images.  ie, if:
>>
>>  original.img - is a disk image (in any format)
>>  modified.img - is a modified version of original.img
>>
>> then:
>>
>>  qemu-img diff -b original.img modified.img diff.qcow2
>>
>> creates 'diff.qcow2' which contains just the differences.  Note that
>> 'diff.qcow2' has 'original.img' set as the backing file.
> 
> Any chance of some more detailed explanation in the docs patch
> about what this actually means and why it's useful? I spent
> several minutes going "huh, does it even mean anything to
> calculate the difference between two binary disk images?"
> before realising that it's the presence of the backing file
> that makes it actually make sense...

Even something as simple as:

Useful for converting a monolithic image back into a thin image on top
of a common base.

-- 
Eric Blake   ebl...@redhat.com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH] qemu-img: Implement 'diff' operation.

2012-05-17 Thread Richard W.M. Jones
On Thu, May 17, 2012 at 02:52:56PM +0100, Peter Maydell wrote:
> On 17 May 2012 14:44, Richard W.M. Jones  wrote:
> > From: "Richard W.M. Jones" 
> >
> > This produces a qcow2 file which is the different between
> > two disk images.  ie, if:
> >
> >  original.img - is a disk image (in any format)
> >  modified.img - is a modified version of original.img
> >
> > then:
> >
> >  qemu-img diff -b original.img modified.img diff.qcow2
> >
> > creates 'diff.qcow2' which contains just the differences.  Note that
> > 'diff.qcow2' has 'original.img' set as the backing file.
> 
> Any chance of some more detailed explanation in the docs patch
> about what this actually means and why it's useful? I spent
> several minutes going "huh, does it even mean anything to
> calculate the difference between two binary disk images?"
> before realising that it's the presence of the backing file
> that makes it actually make sense...

Well I'll say first of all that I was asked to implement this by a
colleague.  Personally, I'm far more organized than this, and I always
use snapshots and backing files if I want to create an efficient COW
from a base template :-)

However my colleague has got himself into a situation where he has
copied (ie. "cp" or equivalent) a guest several times from a template,
and these guests have been running independently.  He now wants to
conserve disk space by turning this situation back into one where he
has one backing file + several COW copies.

To do this, he can (with this patch) do:

  qemu-img diff -b base.img the_copied_guest.img guest.qcow2
  rm the_copied_guest.img

'guest.qcow2' will (in theory at least) be much smaller than the
copied guests he has right now.

Does that make sense?

[BTW I'm still working on this.  There are a few spelling mistakes and
it needs a lot more testing.  This patch is just for comment at the
moment.]

Rich.

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
libguestfs lets you edit virtual machines.  Supports shell scripting,
bindings from many languages.  http://libguestfs.org



Re: [Qemu-devel] [libvirt] [RFC 0/5] block: File descriptor passing using -open-hook-fd

2012-05-17 Thread Zhi Yong Wu
On Thu, May 17, 2012 at 9:42 PM, Stefan Hajnoczi
 wrote:
> On Fri, May 04, 2012 at 11:28:47AM +0800, Zhi Yong Wu wrote:
>> On Tue, May 1, 2012 at 11:31 PM, Stefan Hajnoczi
>>  wrote:
>> > Libvirt can take advantage of SELinux to restrict the QEMU process and 
>> > prevent
>> > it from opening files that it should not have access to.  This improves
>> > security because it prevents the attacker from escaping the QEMU process if
>> > they manage to gain control.
>> >
>> > NFS has been a pain point for SELinux because it does not support labels 
>> > (which
>> > I believe are stored in extended attributes).  In other words, it's not
>> > possible to use SELinux goodness on QEMU when image files are located on 
>> > NFS.
>> > Today we have to allow QEMU access to any file on the NFS export rather 
>> > than
>> > restricting specifically to the image files that the guest requires.
>> >
>> > File descriptor passing is a solution to this problem and might also come 
>> > in
>> > handy elsewhere.  Libvirt or another external process chooses files which 
>> > QEMU
>> > is allowed to access and provides just those file descriptors - QEMU cannot
>> > open the files itself.
>> >
>> > This series adds the -open-hook-fd command-line option.  Whenever QEMU 
>> > needs to
>> > open an image file it sends a request over the given UNIX domain socket.  
>> > The
>> > response includes the file descriptor or an errno on failure.  Please see 
>> > the
>> > patches for details on the protocol.
>> >
>> > The -open-hook-fd approach allows QEMU to support file descriptor passing
>> > without changing -drive.  It also supports snapshot_blkdev and other 
>> > commands
>> By the way, How will it support them?
>
> The problem with snapshot_blkdev is that closing a file and opening a
> new file cannot be done by the QEMU process when an SELinux policy is in
> place to prevent opening files.
>
> The -open-hook-fd approach works even when the QEMU process is not
> allowed to open files since file descriptor passing over a UNIX domain
> socket is used to open files on behalf of QEMU.
I thought that the patchset can only let QEMU passively get passed fd
parameter from upper application.
>
> Stefan
>



-- 
Regards,

Zhi Yong Wu



[Qemu-devel] [RFC][PATCH v2 08/11] kvm: Introduce kvm_irqchip_add/remove_irqfd

2012-05-17 Thread Jan Kiszka
From: Jan Kiszka 

Add services to associate an eventfd file descriptor as input with an
IRQ line as output. Such a line can be an input pin of an in-kernel
irqchip or a virtual line returned by kvm_irqchip_add_route.

Signed-off-by: Jan Kiszka 
---
 kvm-all.c  |   30 ++
 kvm-stub.c |   10 ++
 kvm.h  |3 +++
 3 files changed, 43 insertions(+), 0 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index e96f092..489ee53 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1108,6 +1108,21 @@ int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage 
msg)
 return virq;
 }
 
+static int kvm_irqchip_assign_irqfd(KVMState *s, int fd, int virq, bool assign)
+{
+struct kvm_irqfd irqfd = {
+.fd = fd,
+.gsi = virq,
+.flags = assign ? 0 : KVM_IRQFD_FLAG_DEASSIGN,
+};
+
+if (!kvm_irqchip_in_kernel()) {
+return -ENOSYS;
+}
+
+return kvm_vm_ioctl(s, KVM_IRQFD, &irqfd);
+}
+
 #else /* !KVM_CAP_IRQ_ROUTING */
 
 static void kvm_init_irq_routing(KVMState *s)
@@ -1123,8 +1138,23 @@ int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage 
msg)
 {
 abort();
 }
+
+static int kvm_irqchip_assign_irqfd(KVMState *s, int fd, int virq, bool assign)
+{
+abort();
+}
 #endif /* !KVM_CAP_IRQ_ROUTING */
 
+int kvm_irqchip_add_irqfd(KVMState *s, int fd, int virq)
+{
+return kvm_irqchip_assign_irqfd(s, fd, virq, true);
+}
+
+int kvm_irqchip_remove_irqfd(KVMState *s, int fd, int virq)
+{
+return kvm_irqchip_assign_irqfd(s, fd, virq, false);
+}
+
 static int kvm_irqchip_create(KVMState *s)
 {
 QemuOptsList *list = qemu_find_opts("machine");
diff --git a/kvm-stub.c b/kvm-stub.c
index ec351d9..b4cf03f 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -140,3 +140,13 @@ int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg)
 void kvm_irqchip_release_virq(KVMState *s, int virq)
 {
 }
+
+int kvm_irqchip_add_irqfd(KVMState *s, int fd, int virq)
+{
+return -ENOSYS;
+}
+
+int kvm_irqchip_remove_irqfd(KVMState *s, int fd, int virq)
+{
+return -ENOSYS;
+}
diff --git a/kvm.h b/kvm.h
index f0d0c53..9c7b0ea 100644
--- a/kvm.h
+++ b/kvm.h
@@ -215,4 +215,7 @@ int kvm_set_ioeventfd_pio_word(int fd, uint16_t adr, 
uint16_t val, bool assign);
 
 int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg);
 void kvm_irqchip_release_virq(KVMState *s, int virq);
+
+int kvm_irqchip_add_irqfd(KVMState *s, int fd, int virq);
+int kvm_irqchip_remove_irqfd(KVMState *s, int fd, int virq);
 #endif
-- 
1.7.3.4




[Qemu-devel] [RFC][PATCH v2 05/11] kvm: Introduce kvm_irqchip_add_msi_route

2012-05-17 Thread Jan Kiszka
From: Jan Kiszka 

Add a service that establishes a static route from a virtual IRQ line to
an MSI message. Will be used for IRQFD and device assignment. As we will
use this service outside of CONFIG_KVM protected code, stub it properly.

Signed-off-by: Jan Kiszka 
---
 kvm-all.c  |   31 +++
 kvm-stub.c |8 
 kvm.h  |   10 ++
 3 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index 0117837..7f906ca 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1080,6 +1080,32 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg)
 return kvm_irqchip_set_irq(s, route->kroute.gsi, 1);
 }
 
+int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg)
+{
+struct kvm_irq_routing_entry kroute;
+int virq;
+
+if (!kvm_irqchip_in_kernel()) {
+return -ENOSYS;
+}
+
+virq = kvm_irqchip_get_virq(s);
+if (virq < 0) {
+return virq;
+}
+
+kroute.gsi = virq;
+kroute.type = KVM_IRQ_ROUTING_MSI;
+kroute.flags = 0;
+kroute.u.msi.address_lo = (uint32_t)msg.address;
+kroute.u.msi.address_hi = msg.address >> 32;
+kroute.u.msi.data = msg.data;
+
+kvm_add_routing_entry(s, &kroute);
+
+return virq;
+}
+
 #else /* !KVM_CAP_IRQ_ROUTING */
 
 static void kvm_init_irq_routing(KVMState *s)
@@ -1090,6 +1116,11 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg)
 {
 abort();
 }
+
+int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg)
+{
+abort();
+}
 #endif /* !KVM_CAP_IRQ_ROUTING */
 
 static int kvm_irqchip_create(KVMState *s)
diff --git a/kvm-stub.c b/kvm-stub.c
index 47c573d..db3a7dc 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -12,10 +12,13 @@
 
 #include "qemu-common.h"
 #include "hw/hw.h"
+#include "hw/msi.h"
 #include "cpu.h"
 #include "gdbstub.h"
 #include "kvm.h"
 
+KVMState *kvm_state;
+
 int kvm_init_vcpu(CPUArchState *env)
 {
 return -ENOSYS;
@@ -128,3 +131,8 @@ int kvm_on_sigbus(int code, void *addr)
 {
 return 1;
 }
+
+int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg)
+{
+return -ENOSYS;
+}
diff --git a/kvm.h b/kvm.h
index 8b061bd..67df1f1 100644
--- a/kvm.h
+++ b/kvm.h
@@ -44,6 +44,10 @@ typedef struct KVMCapabilityInfo {
 #define KVM_CAP_INFO(CAP) { "KVM_CAP_" stringify(CAP), KVM_CAP_##CAP }
 #define KVM_CAP_LAST_INFO { NULL, 0 }
 
+struct KVMState;
+typedef struct KVMState KVMState;
+extern KVMState *kvm_state;
+
 /* external API */
 
 int kvm_init(void);
@@ -88,10 +92,6 @@ int kvm_on_sigbus(int code, void *addr);
 
 /* internal API */
 
-struct KVMState;
-typedef struct KVMState KVMState;
-extern KVMState *kvm_state;
-
 int kvm_ioctl(KVMState *s, int type, ...);
 
 int kvm_vm_ioctl(KVMState *s, int type, ...);
@@ -213,4 +213,6 @@ int kvm_set_ioeventfd_mmio(int fd, uint32_t adr, uint32_t 
val, bool assign,
uint32_t size);
 
 int kvm_set_ioeventfd_pio_word(int fd, uint16_t adr, uint16_t val, bool 
assign);
+
+int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg);
 #endif
-- 
1.7.3.4




Re: [Qemu-devel] [PATCH 01/15] Openrisc: add target stub

2012-05-17 Thread Andreas Färber
Am 17.05.2012 10:35, schrieb Jia Liu:
> add the openrisc target stub and basic implementation.
> 
> Signed-off-by: Jia Liu 
> ---
> diff --git a/target-openrisc/cpu-qom.h b/target-openrisc/cpu-qom.h
> new file mode 100644
> index 000..8c936df
> --- /dev/null
> +++ b/target-openrisc/cpu-qom.h

First of all, if you design your new target cleanly, there's no strict
need for a cpu-qom.h header - it mainly served to separate new QOM code
from legacy code. If you want, you can put the code directly into cpu.h
just as well.

> @@ -0,0 +1,70 @@
> +/*
> + *  QEMU Openrisc CPU
> + *
> + *  Copyright (c) 2012 Jia Liu 

Minor nitpick: I guess this was copied from some other header? Uses a
two-space indentation here and one-space below.

> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, see 
> .
> + */
> +
> +#ifndef QEMU_OPENRISC_CPU_QOM_H
> +#define QEMU_OPENRISC_CPU_QOM_H
> +
> +#include "qemu/cpu.h"

> +#include "cpu.h"

Please don't. This was a big mistake of mine that I've been correcting
on the qom-next branch, onto which you should rebase a new target such
as this by the way. It leads to really ugly problems when someone
includes cpu-qom.h and the new struct below is not yet defined for
functions using it there.

> +
> +#define TYPE_OPENRISC_CPU "or32"
> +
> +#define OPENRISC_CPU_CLASS(klass) \
> +OBJECT_CLASS_CHECK(OPENRISCCPUClass, (klass), TYPE_OPENRISC_CPU)
> +#define OPENRISC_CPU(obj) \
> +OBJECT_CHECK(OPENRISCCPU, (obj), TYPE_OPENRISC_CPU)
> +#define OPENRISC_CPU_GET_CLASS(obj) \
> +OBJECT_GET_CLASS(OPENRISCCPUClass, (obj), TYPE_OPENRISC_CPU)
> +
> +/**
> + * OPENRISCCPUClass:
> + * @parent_reset: The parent class' reset handler.
> + *
> + * A Openrisc CPU model.
> + */
> +typedef struct OPENRISCCPUClass {
> +/*< private >*/
> +CPUClass parent_class;
> +/*< public >*/
> +
> +void (*parent_reset)(CPUState *cpu);
> +} OPENRISCCPUClass;

Pleave avoid unnecessary uppercase spelling: OpenRISCCPUClass? That
distinguishes it from the all-uppercase cast macros.

Or OpenriscCPUClass as you spell it elsewhere?

> +
> +/**
> + * OPENRISCCPU:
> + * @env: #CPUOPENRISCState
> + *
> + * A Openrisc CPU.
> + */
> +typedef struct OPENRISCCPU {
> +/*< private >*/
> +CPUState parent_obj;
> +/*< public >*/
> +
> +CPUOPENRISCState env;
> +} OPENRISCCPU;

OpenRISCCPU? OpenriscCPU?

> +
> +static inline OPENRISCCPU *openrisc_env_get_cpu(CPUOPENRISCState *env)
> +{
> +return OPENRISC_CPU(container_of(env, OPENRISCCPU, env));
> +}
> +
> +#define ENV_GET_CPU(e) CPU(openrisc_env_get_cpu(e))
> +
> +#endif /* QEMU_OPENRISC_CPU_QOM_H */
> diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c
> new file mode 100644
> index 000..01e65a2
> --- /dev/null
> +++ b/target-openrisc/cpu.c
> @@ -0,0 +1,74 @@
> +/*
> + *  QEMU Openrisc CPU
> + *
> + *  Copyright (c) 2012 Jia Liu 
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, see 
> .
> + */
> +
> +#include "cpu.h"
> +#include "cpu-qom.h"

cpu.h already does #include "cpu-qom.h", so no need to include it here
again.

> +#include "qemu-common.h"
> +
> +
> +/* CPUClass::reset() */
> +static void openrisc_cpu_reset(CPUState *s)
> +{
> +OPENRISCCPU *cpu = OPENRISC_CPU(s);
> +OPENRISCCPUClass *occ = OPENRISC_CPU_GET_CLASS(cpu);
> +CPUOPENRISCState *env = &cpu->env;
> +
> +occ->parent_reset(s);
> +
> +openrisc_reset(env);

Shouldn't this be inline here? And don't forget to reset the common
fields, too. The usual way I think is to let a helper signal an
interrupt_request and then from outside the thread call cpu_reset(),
which will call the above function.

Be warned that over time more and more fields will be moved from
CPU_COMMON into CPUSt

Re: [Qemu-devel] [libvirt] [RFC 0/5] block: File descriptor passing using -open-hook-fd

2012-05-17 Thread Eric Blake
On 05/17/2012 07:42 AM, Stefan Hajnoczi wrote:

>>>
>>> The -open-hook-fd approach allows QEMU to support file descriptor passing
>>> without changing -drive.  It also supports snapshot_blkdev and other 
>>> commands
>> By the way, How will it support them?
> 
> The problem with snapshot_blkdev is that closing a file and opening a
> new file cannot be done by the QEMU process when an SELinux policy is in
> place to prevent opening files.

snapshot_blkdev can take an fd:name instead of a /path/to/file for the
file to open, in which case libvirt can pass in the named fd _prior_ to
the snapshot_blkdev using the 'getfd' monitor command.

> 
> The -open-hook-fd approach works even when the QEMU process is not
> allowed to open files since file descriptor passing over a UNIX domain
> socket is used to open files on behalf of QEMU.

The -open-hook-fd approach would indeed allow snapshot_blokdev to ask
for the fd after the fact, but it's much more painful.  Consider a case
with a two-disk snapshot:

with the fd:name approach, the sequence is:

libvirt calls getfd:name1 over normal monitor
qemu responds
libvirt calls getfd:name2 over normal monitor
qemu responds
libvirt calls transaction around blockdev-snapshot-sync over normal
monitor, using fd:name1 and fd:name2
qemu responds

but with -open-hook-fd, the approach would be:

libvirt calls transaction
qemu calls open(file1) over hook
libvirt responds
qemu calls open(file2) over hook
libvirt responds
qemu responds to the original transaction

The 'transaction' operation is thus blocked by the time it takes to do
two intermediate opens over a second channel, which kind of defeats the
purpose of making the transaction take effect with minimal guest
downtime.  And libvirt code becomes a lot trickier to deal with the fact
that two channels are in use, and that the channel that issued the
'transaction' command must block while the other channel for handling
hooks must be responsive.

I'm really disliking the hook-fd approach, when a better solution is to
make use of 'getfd' in advance of any operation that will need to open
new fds.

-- 
Eric Blake   ebl...@redhat.com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] Signal management in qemu-user

2012-05-17 Thread Andreas Färber
Am 17.05.2012 15:42, schrieb Peter Maydell:
> On 17 May 2012 14:33, Andreas Färber  wrote:
>> Am 17.05.2012 11:23, schrieb Alex Barcelo:
>>> Running it in a i386 machine works and gives an output of "0x0d\n0x20".
>>> Running it in a qemu-i386 segfaults. Because the self-modifying code
>>> raises a SIGSEGV in the qemu (I understand that it is the method used by
>>> qemu to handle self-modifying code). But the sigprocmask disables the
>>> SIGSEGV and the qemu-user... does nothing to avoid it. So the SIGSEGV is
>>> unmanaged and breaks the program.
>>
>> Alex has the following SIGSEGV workaround queued for our openSUSE package:
>> http://repo.or.cz/w/qemu/agraf.git/commit/0760e24b52ff20a328f168ed23b52c9b9c0fd28f
>>
>> Don't know if it fixes your specific problem.
> 
> No, that's a different issue, see the analysis here:
>  http://lists.gnu.org/archive/html/qemu-devel/2012-02/msg02868.html
> In that case an internal-to-QEMU allocation fails (because the guest
> imposes a severe rlimit), we don't handle it very well and die
> horribly. The commit you link to above is a sticking plaster on
> the problem and definitely not OK for master.

Note the term "workaround". :-)

/-F

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg



[Qemu-devel] [RFC][PATCH v2 00/11] uq/master: irqfd-based interrupt injection for virtio/vhost

2012-05-17 Thread Jan Kiszka
[ changes in v2: rebase over uq/master ]

This series is another major milestone of merging qemu-kvm into
upstream. It implements the required interfaces and logic to directly
inject MSI-X interrupts generated by the vhost-net kernel module into
the KVM in-kernel irqchip. This involves
 - establishing MSI vector notifiers, so far triggered on relevant MSI-X
   configuration changes of subscribed PCI devices
 - support for static vIRQ-to-MSI routes
 - an API for linking an IRQFD with such a vIRQ
 - the usage of these services in virtio-pci to enable direct injection

The series also contains some smaller refactorings of the KVM IRQ
routing API such as automatic committing of route changes. It applies on
top of the KVM MSI support series [1] posted recently. The complete
stack is available at

git://git.kiszka.org/qemu-kvm.git queues/kvm-msi-irqfd

If the proposes API is acceptable, I will also provide some morphing
patches for qemu-kvm to make the merge of both trees smoother.

After this series, to only reasons to still use qemu-kvm for production
purposes will be PCI device assignment and potential dependencies on
legacy command line switches as well as vmstate formats (when requiring
backward migration support). However, the majority of users should be
able to switch to upstream QEMU seamlessly and finally receive the same
level of performance on x86.

[1] http://thread.gmane.org/gmane.comp.emulators.kvm.devel/90651

Jan Kiszka (11):
  msix: Factor out msix_get_message
  msix: Invoke msix_handle_mask_update on msix_mask_all
  msix: Introduce vector notifiers
  kvm: Rename kvm_irqchip_add_route to kvm_irqchip_add_irq_route
  kvm: Introduce kvm_irqchip_add_msi_route
  kvm: Publicize kvm_irqchip_release_virq
  kvm: Make kvm_irqchip_commit_routes an internal service
  kvm: Introduce kvm_irqchip_add/remove_irqfd
  kvm: Enable use of kvm_irqchip_in_kernel in hwlib code
  msix: Add msix_nr_vectors_allocated
  virtio/vhost: Add support for KVM in-kernel MSI injection

 hw/msix.c   |  121 ++---
 hw/msix.h   |6 +++
 hw/pc_piix.c|   14 ++
 hw/pci.h|8 
 hw/virtio-pci.c |  126 +++
 hw/virtio-pci.h |6 +++
 kvm-all.c   |   91 +--
 kvm-stub.c  |   23 ++
 kvm.h   |   17 +---
 9 files changed, 377 insertions(+), 35 deletions(-)

-- 
1.7.3.4




Re: [Qemu-devel] Signal management in qemu-user

2012-05-17 Thread Andreas Färber
Am 17.05.2012 11:23, schrieb Alex Barcelo:
> Running it in a i386 machine works and gives an output of "0x0d\n0x20".
> Running it in a qemu-i386 segfaults. Because the self-modifying code
> raises a SIGSEGV in the qemu (I understand that it is the method used by
> qemu to handle self-modifying code). But the sigprocmask disables the
> SIGSEGV and the qemu-user... does nothing to avoid it. So the SIGSEGV is
> unmanaged and breaks the program.

Alex has the following SIGSEGV workaround queued for our openSUSE package:
http://repo.or.cz/w/qemu/agraf.git/commit/0760e24b52ff20a328f168ed23b52c9b9c0fd28f

Don't know if it fixes your specific problem. Peter had some ideas how
to refactor signal handling but iirc didn't have time to work on it himself.

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg



[Qemu-devel] [RFC][PATCH v2 07/11] kvm: Make kvm_irqchip_commit_routes an internal service

2012-05-17 Thread Jan Kiszka
From: Jan Kiszka 

Automatically commit route changes after kvm_add_routing_entry and
kvm_irqchip_release_virq. There is no performance relevant use case for
which collecting multiple route changes is beneficial. This makes
kvm_irqchip_commit_routes an internal service which assert()s that the
corresponding IOCTL will always succeed.

Signed-off-by: Jan Kiszka 
---
 hw/pc_piix.c |6 +-
 kvm-all.c|   26 ++
 kvm.h|1 -
 3 files changed, 15 insertions(+), 18 deletions(-)

diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index c17f906..044dfcb 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -56,7 +56,7 @@ static void kvm_piix3_setup_irq_routing(bool pci_enabled)
 {
 #ifdef CONFIG_KVM
 KVMState *s = kvm_state;
-int ret, i;
+int i;
 
 if (kvm_check_extension(s, KVM_CAP_IRQ_ROUTING)) {
 for (i = 0; i < 8; ++i) {
@@ -77,10 +77,6 @@ static void kvm_piix3_setup_irq_routing(bool pci_enabled)
 }
 }
 }
-ret = kvm_irqchip_commit_routes(s);
-if (ret < 0) {
-hw_error("KVM IRQ routing setup failed");
-}
 }
 #endif /* CONFIG_KVM */
 }
diff --git a/kvm-all.c b/kvm-all.c
index ca6cec6..e96f092 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -908,6 +908,15 @@ static void kvm_init_irq_routing(KVMState *s)
 kvm_arch_init_irq_routing(s);
 }
 
+static void kvm_irqchip_commit_routes(KVMState *s)
+{
+int ret;
+
+s->irq_routes->flags = 0;
+ret = kvm_vm_ioctl(s, KVM_SET_GSI_ROUTING, s->irq_routes);
+assert(ret == 0);
+}
+
 static void kvm_add_routing_entry(KVMState *s,
   struct kvm_irq_routing_entry *entry)
 {
@@ -933,6 +942,8 @@ static void kvm_add_routing_entry(KVMState *s,
 new->u = entry->u;
 
 set_gsi(s, entry->gsi);
+
+kvm_irqchip_commit_routes(s);
 }
 
 void kvm_irqchip_add_irq_route(KVMState *s, int irq, int irqchip, int pin)
@@ -949,12 +960,6 @@ void kvm_irqchip_add_irq_route(KVMState *s, int irq, int 
irqchip, int pin)
 kvm_add_routing_entry(s, &e);
 }
 
-int kvm_irqchip_commit_routes(KVMState *s)
-{
-s->irq_routes->flags = 0;
-return kvm_vm_ioctl(s, KVM_SET_GSI_ROUTING, s->irq_routes);
-}
-
 void kvm_irqchip_release_virq(KVMState *s, int virq)
 {
 struct kvm_irq_routing_entry *e;
@@ -968,6 +973,8 @@ void kvm_irqchip_release_virq(KVMState *s, int virq)
 }
 }
 clear_gsi(s, virq);
+
+kvm_irqchip_commit_routes(s);
 }
 
 static unsigned int kvm_hash_msi(uint32_t data)
@@ -1049,7 +1056,7 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg)
 
 route = kvm_lookup_msi_route(s, msg);
 if (!route) {
-int virq, ret;
+int virq;
 
 virq = kvm_irqchip_get_virq(s);
 if (virq < 0) {
@@ -1068,11 +1075,6 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg)
 
 QTAILQ_INSERT_TAIL(&s->msi_hashtab[kvm_hash_msi(msg.data)], route,
entry);
-
-ret = kvm_irqchip_commit_routes(s);
-if (ret < 0) {
-return ret;
-}
 }
 
 assert(route->kroute.type == KVM_IRQ_ROUTING_MSI);
diff --git a/kvm.h b/kvm.h
index 1779e73..f0d0c53 100644
--- a/kvm.h
+++ b/kvm.h
@@ -135,7 +135,6 @@ int kvm_irqchip_set_irq(KVMState *s, int irq, int level);
 int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg);
 
 void kvm_irqchip_add_irq_route(KVMState *s, int gsi, int irqchip, int pin);
-int kvm_irqchip_commit_routes(KVMState *s);
 
 void kvm_put_apic_state(DeviceState *d, struct kvm_lapic_state *kapic);
 void kvm_get_apic_state(DeviceState *d, struct kvm_lapic_state *kapic);
-- 
1.7.3.4




[Qemu-devel] [PATCH qmp-next v4 00/16]: qapi: convert netdev_add & netdev_del

2012-05-17 Thread Luiz Capitulino
v4

- Fix vde build [Laszlo]
- Rebase on top of qmp-next (which contains latest master) [Me]

 blockdev.c   |2 +-
 hmp-commands.hx  |6 +-
 hmp.c|   30 +
 hmp.h|2 +
 hw/pci-hotplug.c |8 ++-
 hw/qdev-monitor.c|7 +-
 hw/usb/dev-network.c |7 +-
 hw/usb/dev-storage.c |2 +-
 hw/watchdog.c|2 +-
 net.c|  104 +++--
 net.h|6 +-
 net/dump.c   |2 +-
 net/dump.h   |3 +-
 net/slirp.c  |5 +-
 net/slirp.h  |5 +-
 net/socket.c |8 +--
 net/socket.h |3 +-
 net/tap-win32.c  |2 +-
 net/tap.c|9 ++-
 net/tap.h|5 +-
 net/vde.c|2 +-
 net/vde.h|2 +-
 qapi-schema.json |   42 
 qemu-char.c  |8 ++-
 qemu-config.c|   43 +---
 qemu-config.h|3 +
 qemu-option.c|  176 ++
 qemu-option.h|   11 +++-
 qemu-sockets.c   |8 +--
 qerror.c |4 ++
 qerror.h |3 +
 qmp-commands.hx  |   10 +--
 vl.c |   22 ---
 33 files changed, 382 insertions(+), 170 deletions(-)



[Qemu-devel] [PATCH 02/16] qemu-option: parse_option_number(): use error_set()

2012-05-17 Thread Luiz Capitulino
Note that qemu_opt_parse() callers still expect automatic error reporting
with QError, so qemu_opts_parse() calls qerror_report_err() to keep the
same semantics.

Signed-off-by: Luiz Capitulino 
---
 qemu-option.c |   26 +++---
 1 file changed, 19 insertions(+), 7 deletions(-)

diff --git a/qemu-option.c b/qemu-option.c
index 9f531c8..72dcb56 100644
--- a/qemu-option.c
+++ b/qemu-option.c
@@ -186,7 +186,8 @@ static int parse_option_bool(const char *name, const char 
*value, bool *ret)
 return 0;
 }
 
-static int parse_option_number(const char *name, const char *value, uint64_t 
*ret)
+static void parse_option_number(const char *name, const char *value,
+uint64_t *ret, Error **errp)
 {
 char *postfix;
 uint64_t number;
@@ -194,15 +195,13 @@ static int parse_option_number(const char *name, const 
char *value, uint64_t *re
 if (value != NULL) {
 number = strtoull(value, &postfix, 0);
 if (*postfix != '\0') {
-qerror_report(QERR_INVALID_PARAMETER_VALUE, name, "a number");
-return -1;
+error_set(errp, QERR_INVALID_PARAMETER_VALUE, name, "a number");
+return;
 }
 *ret = number;
 } else {
-qerror_report(QERR_INVALID_PARAMETER_VALUE, name, "a number");
-return -1;
+error_set(errp, QERR_INVALID_PARAMETER_VALUE, name, "a number");
 }
-return 0;
 }
 
 static int parse_option_size(const char *name, const char *value, uint64_t 
*ret)
@@ -579,8 +578,11 @@ uint64_t qemu_opt_get_size(QemuOpts *opts, const char 
*name, uint64_t defval)
 
 static int qemu_opt_parse(QemuOpt *opt)
 {
+Error *local_err = NULL;
+
 if (opt->desc == NULL)
 return 0;
+
 switch (opt->desc->type) {
 case QEMU_OPT_STRING:
 /* nothing */
@@ -588,12 +590,22 @@ static int qemu_opt_parse(QemuOpt *opt)
 case QEMU_OPT_BOOL:
 return parse_option_bool(opt->name, opt->str, &opt->value.boolean);
 case QEMU_OPT_NUMBER:
-return parse_option_number(opt->name, opt->str, &opt->value.uint);
+parse_option_number(opt->name, opt->str, &opt->value.uint,
+&local_err);
+break;
 case QEMU_OPT_SIZE:
 return parse_option_size(opt->name, opt->str, &opt->value.uint);
 default:
 abort();
 }
+
+if (error_is_set(&local_err)) {
+qerror_report_err(local_err);
+error_free(local_err);
+return -1;
+}
+
+return 0;
 }
 
 static void qemu_opt_del(QemuOpt *opt)
-- 
1.7.9.2.384.g4a92a




[Qemu-devel] [PATCH 01/16] qemu-option: qemu_opts_create(): use error_set()

2012-05-17 Thread Luiz Capitulino
This commit converts qemu_opts_create() from qerror_report() to
error_set().

Currently, most calls to qemu_opts_create() can't fail, so most
callers don't need any changes.

The two cases where code checks for qemu_opts_create() erros are:

 1. Initialization code in vl.c. All of them print their own
error messages directly to stderr, no need to pass the Error
object

 2. The functions opts_parse(), qemu_opts_from_qdict() and
qemu_chr_parse_compat() make use of the error information and
they can be called from HMP or QMP. In this case, to allow for
incremental conversion, we propagate the error up using
qerror_report_err(), which keeps the QError semantics

Signed-off-by: Luiz Capitulino 
---
 blockdev.c   |2 +-
 hw/usb/dev-storage.c |2 +-
 hw/watchdog.c|2 +-
 qemu-char.c  |8 ++--
 qemu-config.c|6 +++---
 qemu-option.c|   37 +++--
 qemu-option.h|4 +++-
 qemu-sockets.c   |8 
 vl.c |   22 +-
 9 files changed, 59 insertions(+), 32 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 67895b2..622ecba 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -569,7 +569,7 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
 break;
 case IF_VIRTIO:
 /* add virtio block device */
-opts = qemu_opts_create(qemu_find_opts("device"), NULL, 0);
+opts = qemu_opts_create(qemu_find_opts("device"), NULL, 0, NULL);
 if (arch_type == QEMU_ARCH_S390X) {
 qemu_opt_set(opts, "driver", "virtio-blk-s390");
 } else {
diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
index ae22fb1..a96c0b9 100644
--- a/hw/usb/dev-storage.c
+++ b/hw/usb/dev-storage.c
@@ -584,7 +584,7 @@ static USBDevice *usb_msd_init(USBBus *bus, const char 
*filename)
 
 /* parse -usbdevice disk: syntax into drive opts */
 snprintf(id, sizeof(id), "usb%d", nr++);
-opts = qemu_opts_create(qemu_find_opts("drive"), id, 0);
+opts = qemu_opts_create(qemu_find_opts("drive"), id, 0, NULL);
 
 p1 = strchr(filename, ':');
 if (p1++) {
diff --git a/hw/watchdog.c b/hw/watchdog.c
index 4c18965..a42124d 100644
--- a/hw/watchdog.c
+++ b/hw/watchdog.c
@@ -66,7 +66,7 @@ int select_watchdog(const char *p)
 QLIST_FOREACH(model, &watchdog_list, entry) {
 if (strcasecmp(model->wdt_name, p) == 0) {
 /* add the device */
-opts = qemu_opts_create(qemu_find_opts("device"), NULL, 0);
+opts = qemu_opts_create(qemu_find_opts("device"), NULL, 0, NULL);
 qemu_opt_set(opts, "driver", p);
 return 0;
 }
diff --git a/qemu-char.c b/qemu-char.c
index fe1126f..0bd903f 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2584,10 +2584,14 @@ QemuOpts *qemu_chr_parse_compat(const char *label, 
const char *filename)
 int pos;
 const char *p;
 QemuOpts *opts;
+Error *local_err = NULL;
 
-opts = qemu_opts_create(qemu_find_opts("chardev"), label, 1);
-if (NULL == opts)
+opts = qemu_opts_create(qemu_find_opts("chardev"), label, 1, &local_err);
+if (error_is_set(&local_err)) {
+qerror_report_err(local_err);
+error_free(local_err);
 return NULL;
+}
 
 if (strstart(filename, "mon:", &p)) {
 filename = p;
diff --git a/qemu-config.c b/qemu-config.c
index be84a03..f876646 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -709,7 +709,7 @@ int qemu_global_option(const char *str)
 return -1;
 }
 
-opts = qemu_opts_create(&qemu_global_opts, NULL, 0);
+opts = qemu_opts_create(&qemu_global_opts, NULL, 0, NULL);
 qemu_opt_set(opts, "driver", driver);
 qemu_opt_set(opts, "property", property);
 qemu_opt_set(opts, "value", str+offset+1);
@@ -781,7 +781,7 @@ int qemu_config_parse(FILE *fp, QemuOptsList **lists, const 
char *fname)
 list = find_list(lists, group);
 if (list == NULL)
 goto out;
-opts = qemu_opts_create(list, id, 1);
+opts = qemu_opts_create(list, id, 1, NULL);
 continue;
 }
 if (sscanf(line, "[%63[^]]]", group) == 1) {
@@ -789,7 +789,7 @@ int qemu_config_parse(FILE *fp, QemuOptsList **lists, const 
char *fname)
 list = find_list(lists, group);
 if (list == NULL)
 goto out;
-opts = qemu_opts_create(list, NULL, 0);
+opts = qemu_opts_create(list, NULL, 0, NULL);
 continue;
 }
 if (sscanf(line, " %63s = \"%1023[^\"]\"", arg, value) == 2) {
diff --git a/qemu-option.c b/qemu-option.c
index 35cd609..9f531c8 100644
--- a/qemu-option.c
+++ b/qemu-option.c
@@ -30,6 +30,7 @@
 #include "qemu-error.h"
 #include "qemu-objects.h"
 #include "qemu-option.h"
+#include "error.h"
 #include "qerror.h"
 
 /*
@@ -729,20 +730,21 @@ static int id_wellformed(const char *id)
 return 1;
 }
 
-QemuOpts 

[Qemu-devel] [PATCH 06/16] qemu-option: qemu_opts_validate(): use error_set()

2012-05-17 Thread Luiz Capitulino
net_client_init() propagates the error up by calling qerror_report_err(),
because its users expect QError semantics.

Signed-off-by: Luiz Capitulino 
---
 net.c |6 +-
 qemu-option.c |   13 +
 qemu-option.h |2 +-
 3 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/net.c b/net.c
index 1922d8a..f5d9cc7 100644
--- a/net.c
+++ b/net.c
@@ -1136,10 +1136,14 @@ int net_client_init(Monitor *mon, QemuOpts *opts, int 
is_netdev)
 for (i = 0; i < NET_CLIENT_TYPE_MAX; i++) {
 if (net_client_types[i].type != NULL &&
 !strcmp(net_client_types[i].type, type)) {
+Error *local_err = NULL;
 VLANState *vlan = NULL;
 int ret;
 
-if (qemu_opts_validate(opts, &net_client_types[i].desc[0]) == -1) {
+qemu_opts_validate(opts, &net_client_types[i].desc[0], &local_err);
+if (error_is_set(&local_err)) {
+qerror_report_err(local_err);
+error_free(local_err);
 return -1;
 }
 
diff --git a/qemu-option.c b/qemu-option.c
index d79acbd..3a9a5f8 100644
--- a/qemu-option.c
+++ b/qemu-option.c
@@ -1044,7 +1044,7 @@ QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict)
 /* Validate parsed opts against descriptions where no
  * descriptions were provided in the QemuOptsList.
  */
-int qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc)
+void qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc, Error **errp)
 {
 QemuOpt *opt;
 Error *local_err = NULL;
@@ -1060,21 +1060,18 @@ int qemu_opts_validate(QemuOpts *opts, const 
QemuOptDesc *desc)
 }
 }
 if (desc[i].name == NULL) {
-qerror_report(QERR_INVALID_PARAMETER, opt->name);
-return -1;
+error_set(errp, QERR_INVALID_PARAMETER, opt->name);
+return;
 }
 
 opt->desc = &desc[i];
 
 qemu_opt_parse(opt, &local_err);
 if (error_is_set(&local_err)) {
-qerror_report_err(local_err);
-error_free(local_err);
-return -1;
+error_propagate(errp, local_err);
+return;
 }
 }
-
-return 0;
 }
 
 int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void 
*opaque,
diff --git a/qemu-option.h b/qemu-option.h
index 4d5b3d3..e9fbbb5 100644
--- a/qemu-option.h
+++ b/qemu-option.h
@@ -125,7 +125,7 @@ int qemu_opts_set(QemuOptsList *list, const char *id,
   const char *name, const char *value);
 const char *qemu_opts_id(QemuOpts *opts);
 void qemu_opts_del(QemuOpts *opts);
-int qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc);
+void qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc, Error **errp);
 int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char 
*firstname);
 QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, int 
permit_abbrev);
 void qemu_opts_set_defaults(QemuOptsList *list, const char *params,
-- 
1.7.9.2.384.g4a92a




[Qemu-devel] [PATCH 15/16] qapi: convert netdev_add

2012-05-17 Thread Luiz Capitulino
This is not a full QAPI conversion, but an intermediate step.

In essence, do_netdev_add() is split into three functions:

 1. netdev_add(): performs the actual work. This function is fully
converted to Error (thus, it's "qapi-friendly")

 2. qmp_netdev_add(): the QMP front-end for netdev_add(). This is
coded by hand and not auto-generated (gen=no in the schema). The
reason for this it's a lot easier and simpler to with QemuOpts
this way

 3. hmp_netdev_add(): HMP front-end.

This design was suggested by Paolo Bonzini.

Signed-off-by: Luiz Capitulino 
---
 hmp-commands.hx  |3 +--
 hmp.c|   21 +
 hmp.h|1 +
 net.c|   41 +++--
 net.h|3 ++-
 qapi-schema.json |   28 
 qmp-commands.hx  |5 +
 7 files changed, 81 insertions(+), 21 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 81723c8..d0ce6a5 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1037,8 +1037,7 @@ ETEXI
 .args_type  = "netdev:O",
 .params = "[user|tap|socket],id=str[,prop=value][,...]",
 .help   = "add host network device",
-.user_print = monitor_user_noop,
-.mhandler.cmd_new = do_netdev_add,
+.mhandler.cmd = hmp_netdev_add,
 },
 
 STEXI
diff --git a/hmp.c b/hmp.c
index 42ced2a..7a4e25f 100644
--- a/hmp.c
+++ b/hmp.c
@@ -14,6 +14,8 @@
  */
 
 #include "hmp.h"
+#include "net.h"
+#include "qemu-option.h"
 #include "qemu-timer.h"
 #include "qmp-commands.h"
 
@@ -969,3 +971,22 @@ void hmp_dump_guest_memory(Monitor *mon, const QDict 
*qdict)
   &errp);
 hmp_handle_error(mon, &errp);
 }
+
+void hmp_netdev_add(Monitor *mon, const QDict *qdict)
+{
+Error *err = NULL;
+QemuOpts *opts;
+
+opts = qemu_opts_from_qdict(qemu_find_opts("netdev"), qdict, &err);
+if (error_is_set(&err)) {
+goto out;
+}
+
+netdev_add(opts, &err);
+if (error_is_set(&err)) {
+qemu_opts_del(opts);
+}
+
+out:
+hmp_handle_error(mon, &err);
+}
diff --git a/hmp.h b/hmp.h
index 5cf3241..017df87 100644
--- a/hmp.h
+++ b/hmp.h
@@ -62,5 +62,6 @@ void hmp_block_job_cancel(Monitor *mon, const QDict *qdict);
 void hmp_migrate(Monitor *mon, const QDict *qdict);
 void hmp_device_del(Monitor *mon, const QDict *qdict);
 void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict);
+void hmp_netdev_add(Monitor *mon, const QDict *qdict);
 
 #endif
diff --git a/net.c b/net.c
index 7e9d0c5..5f0c53c 100644
--- a/net.c
+++ b/net.c
@@ -1234,27 +1234,39 @@ void net_host_device_remove(Monitor *mon, const QDict 
*qdict)
 qemu_del_vlan_client(vc);
 }
 
-int do_netdev_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
+void netdev_add(QemuOpts *opts, Error **errp)
+{
+net_client_init(opts, 1, errp);
+}
+
+int qmp_netdev_add(Monitor *mon, const QDict *qdict, QObject **ret)
 {
 Error *local_err = NULL;
+QemuOptsList *opts_list;
 QemuOpts *opts;
-int res;
 
-opts = qemu_opts_from_qdict(qemu_find_opts("netdev"), qdict, &local_err);
-if (!opts) {
-qerror_report_err(local_err);
-error_free(local_err);
-return -1;
+opts_list = qemu_find_opts_err("netdev", &local_err);
+if (error_is_set(&local_err)) {
+goto exit_err;
 }
 
-res = net_client_init(opts, 1, &local_err);
-if (res < 0) {
-qerror_report_err(local_err);
-error_free(local_err);
+opts = qemu_opts_from_qdict(opts_list, qdict, &local_err);
+if (error_is_set(&local_err)) {
+goto exit_err;
+}
+
+netdev_add(opts, &local_err);
+if (error_is_set(&local_err)) {
 qemu_opts_del(opts);
+goto exit_err;
 }
 
-return res;
+return 0;
+
+exit_err:
+qerror_report_err(local_err);
+error_free(local_err);
+return -1;
 }
 
 int do_netdev_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
@@ -1447,15 +1459,16 @@ static int net_init_client(QemuOpts *opts, void *dummy)
 static int net_init_netdev(QemuOpts *opts, void *dummy)
 {
 Error *local_err = NULL;
+int ret;
 
-net_client_init(opts, 1, &local_err);
+ret = net_client_init(opts, 1, &local_err);
 if (error_is_set(&local_err)) {
 qerror_report_err(local_err);
 error_free(local_err);
 return -1;
 }
 
-return 0;
+return ret;
 }
 
 int net_init_clients(void)
diff --git a/net.h b/net.h
index 7ee97e9..1eb9280 100644
--- a/net.h
+++ b/net.h
@@ -170,7 +170,8 @@ void net_check_clients(void);
 void net_cleanup(void);
 void net_host_device_add(Monitor *mon, const QDict *qdict);
 void net_host_device_remove(Monitor *mon, const QDict *qdict);
-int do_netdev_add(Monitor *mon, const QDict *qdict, QObject **ret_data);
+void netdev_add(QemuOpts *opts, Error **errp);
+int qmp_netdev_add(Monitor *mon, const QDict *qdict, QObject **ret);
 int do_netdev_del(Monitor *mon, const QDict *qdict, QObject

[Qemu-devel] [PATCH 03/16] qemu-option: parse_option_bool(): use error_set()

2012-05-17 Thread Luiz Capitulino
Note that set_option_parameter() callers still expect automatic error
reporting with QError, so set_option_parameter() calls
qerror_report_err() to keep the same semantics.

Signed-off-by: Luiz Capitulino 
---
 qemu-option.c |   22 +++---
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/qemu-option.c b/qemu-option.c
index 72dcb56..a8b50af 100644
--- a/qemu-option.c
+++ b/qemu-option.c
@@ -169,7 +169,8 @@ QEMUOptionParameter 
*get_option_parameter(QEMUOptionParameter *list,
 return NULL;
 }
 
-static int parse_option_bool(const char *name, const char *value, bool *ret)
+static void parse_option_bool(const char *name, const char *value, bool *ret,
+  Error **errp)
 {
 if (value != NULL) {
 if (!strcmp(value, "on")) {
@@ -177,13 +178,11 @@ static int parse_option_bool(const char *name, const char 
*value, bool *ret)
 } else if (!strcmp(value, "off")) {
 *ret = 0;
 } else {
-qerror_report(QERR_INVALID_PARAMETER_VALUE, name, "'on' or 'off'");
-return -1;
+error_set(errp,QERR_INVALID_PARAMETER_VALUE, name, "'on' or 
'off'");
 }
 } else {
 *ret = 1;
 }
-return 0;
 }
 
 static void parse_option_number(const char *name, const char *value,
@@ -263,6 +262,7 @@ int set_option_parameter(QEMUOptionParameter *list, const 
char *name,
 const char *value)
 {
 bool flag;
+Error *local_err = NULL;
 
 // Find a matching parameter
 list = get_option_parameter(list, name);
@@ -274,8 +274,10 @@ int set_option_parameter(QEMUOptionParameter *list, const 
char *name,
 // Process parameter
 switch (list->type) {
 case OPT_FLAG:
-if (parse_option_bool(name, value, &flag) == -1)
-return -1;
+parse_option_bool(name, value, &flag, &local_err);
+if (error_is_set(&local_err)) {
+goto exit_err;
+}
 list->value.n = flag;
 break;
 
@@ -299,6 +301,11 @@ int set_option_parameter(QEMUOptionParameter *list, const 
char *name,
 }
 
 return 0;
+
+exit_err:
+qerror_report_err(local_err);
+error_free(local_err);
+return -1;
 }
 
 /*
@@ -588,7 +595,8 @@ static int qemu_opt_parse(QemuOpt *opt)
 /* nothing */
 return 0;
 case QEMU_OPT_BOOL:
-return parse_option_bool(opt->name, opt->str, &opt->value.boolean);
+parse_option_bool(opt->name, opt->str, &opt->value.boolean, 
&local_err);
+break;
 case QEMU_OPT_NUMBER:
 parse_option_number(opt->name, opt->str, &opt->value.uint,
 &local_err);
-- 
1.7.9.2.384.g4a92a




[Qemu-devel] [RFC][PATCH v2 03/11] msix: Introduce vector notifiers

2012-05-17 Thread Jan Kiszka
From: Jan Kiszka 

Vector notifiers shall be triggered by the MSI/MSI-X core whenever a
relevant configuration change is programmed by the guest. In case of
MSI-X, changes are reported when the effective mask (global &&
per-vector) alters its state. On unmask, the current vector
configuration is included in the event report. This allows users - e.g.
virtio-pci layer - to transfer this information to external MSI-X
routing subsystems - like vhost + KVM in-kernel irqchip.

This implementation only provides MSI-X support, but extension to MSI is
feasible and will be provided later on when adding support for KVM PCI
device assignment.

Signed-off-by: Jan Kiszka 
---
 hw/msix.c |   93 +
 hw/msix.h |4 ++
 hw/pci.h  |8 +
 3 files changed, 105 insertions(+), 0 deletions(-)

diff --git a/hw/msix.c b/hw/msix.c
index e1a7d92..1622e16 100644
--- a/hw/msix.c
+++ b/hw/msix.c
@@ -139,13 +139,34 @@ static bool msix_is_masked(PCIDevice *dev, int vector)
 return msix_vector_masked(dev, vector, dev->msix_function_masked);
 }
 
+static void msix_fire_vector_notifier(PCIDevice *dev,
+  unsigned int vector, bool is_masked)
+{
+MSIMessage msg;
+int ret;
+
+if (!dev->msix_vector_use_notifier) {
+return;
+}
+if (is_masked) {
+dev->msix_vector_release_notifier(dev, vector);
+} else {
+msg = msix_get_message(dev, vector);
+ret = dev->msix_vector_use_notifier(dev, vector, msg);
+assert(ret >= 0);
+}
+}
+
 static void msix_handle_mask_update(PCIDevice *dev, int vector, bool 
was_masked)
 {
 bool is_masked = msix_is_masked(dev, vector);
+
 if (is_masked == was_masked) {
 return;
 }
 
+msix_fire_vector_notifier(dev, vector, is_masked);
+
 if (!is_masked && msix_is_pending(dev, vector)) {
 msix_clr_pending(dev, vector);
 msix_notify(dev, vector);
@@ -330,6 +351,7 @@ void msix_save(PCIDevice *dev, QEMUFile *f)
 void msix_load(PCIDevice *dev, QEMUFile *f)
 {
 unsigned n = dev->msix_entries_nr;
+unsigned int vector;
 
 if (!(dev->cap_present & QEMU_PCI_CAP_MSIX)) {
 return;
@@ -339,6 +361,10 @@ void msix_load(PCIDevice *dev, QEMUFile *f)
 qemu_get_buffer(f, dev->msix_table_page, n * PCI_MSIX_ENTRY_SIZE);
 qemu_get_buffer(f, dev->msix_table_page + MSIX_PAGE_PENDING, (n + 7) / 8);
 msix_update_function_masked(dev);
+
+for (vector = 0; vector < n; vector++) {
+msix_handle_mask_update(dev, vector, true);
+}
 }
 
 /* Does device support MSI-X? */
@@ -425,3 +451,70 @@ void msix_unuse_all_vectors(PCIDevice *dev)
 return;
 msix_free_irq_entries(dev);
 }
+
+static int msix_set_notifier_for_vector(PCIDevice *dev, unsigned int vector)
+{
+MSIMessage msg;
+
+if (msix_is_masked(dev, vector)) {
+return 0;
+}
+msg = msix_get_message(dev, vector);
+return dev->msix_vector_use_notifier(dev, vector, msg);
+}
+
+static void msix_unset_notifier_for_vector(PCIDevice *dev, unsigned int vector)
+{
+if (msix_is_masked(dev, vector)) {
+return;
+}
+dev->msix_vector_release_notifier(dev, vector);
+}
+
+int msix_set_vector_notifiers(PCIDevice *dev,
+  MSIVectorUseNotifier use_notifier,
+  MSIVectorReleaseNotifier release_notifier)
+{
+int vector, ret;
+
+assert(use_notifier && release_notifier);
+
+dev->msix_vector_use_notifier = use_notifier;
+dev->msix_vector_release_notifier = release_notifier;
+
+if ((dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] &
+(MSIX_ENABLE_MASK | MSIX_MASKALL_MASK)) == MSIX_ENABLE_MASK) {
+for (vector = 0; vector < dev->msix_entries_nr; vector++) {
+ret = msix_set_notifier_for_vector(dev, vector);
+if (ret < 0) {
+goto undo;
+}
+}
+}
+return 0;
+
+undo:
+while (--vector >= 0) {
+msix_unset_notifier_for_vector(dev, vector);
+}
+dev->msix_vector_use_notifier = NULL;
+dev->msix_vector_release_notifier = NULL;
+return ret;
+}
+
+void msix_unset_vector_notifiers(PCIDevice *dev)
+{
+int vector;
+
+assert(dev->msix_vector_use_notifier &&
+   dev->msix_vector_release_notifier);
+
+if ((dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] &
+(MSIX_ENABLE_MASK | MSIX_MASKALL_MASK)) == MSIX_ENABLE_MASK) {
+for (vector = 0; vector < dev->msix_entries_nr; vector++) {
+msix_unset_notifier_for_vector(dev, vector);
+}
+}
+dev->msix_vector_use_notifier = NULL;
+dev->msix_vector_release_notifier = NULL;
+}
diff --git a/hw/msix.h b/hw/msix.h
index 5aba22b..f33f18b 100644
--- a/hw/msix.h
+++ b/hw/msix.h
@@ -29,4 +29,8 @@ void msix_notify(PCIDevice *dev, unsigned vector);
 
 void msix_reset(PCIDevice *dev);
 
+int msix_set_vector_notifiers(PCIDevice *dev,
+  

[Qemu-devel] [PATCH 12/16] qemu-config: introduce qemu_find_opts_err()

2012-05-17 Thread Luiz Capitulino
This is like qemu_find_opts(), except that it takes an Error argument.

This new function allows for a incremental conversion of code using
qemu_find_opts().

Signed-off-by: Luiz Capitulino 
---
 qemu-config.c |5 +
 qemu-config.h |3 +++
 2 files changed, 8 insertions(+)

diff --git a/qemu-config.c b/qemu-config.c
index bdb381d..bb3bff4 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -661,6 +661,11 @@ QemuOptsList *qemu_find_opts(const char *group)
 return ret;
 }
 
+QemuOptsList *qemu_find_opts_err(const char *group, Error **errp)
+{
+return find_list(vm_config_groups, group, errp);
+}
+
 void qemu_add_opts(QemuOptsList *list)
 {
 int entries, i;
diff --git a/qemu-config.h b/qemu-config.h
index 6d7365d..e9f2ef4 100644
--- a/qemu-config.h
+++ b/qemu-config.h
@@ -1,11 +1,14 @@
 #ifndef QEMU_CONFIG_H
 #define QEMU_CONFIG_H
 
+#include "error.h"
+
 extern QemuOptsList qemu_fsdev_opts;
 extern QemuOptsList qemu_virtfs_opts;
 extern QemuOptsList qemu_spice_opts;
 
 QemuOptsList *qemu_find_opts(const char *group);
+QemuOptsList *qemu_find_opts_err(const char *group, Error **errp);
 void qemu_add_opts(QemuOptsList *list);
 int qemu_set_option(const char *str);
 int qemu_global_option(const char *str);
-- 
1.7.9.2.384.g4a92a




[Qemu-devel] [RFC][PATCH v2 04/11] kvm: Rename kvm_irqchip_add_route to kvm_irqchip_add_irq_route

2012-05-17 Thread Jan Kiszka
From: Jan Kiszka 

We will add kvm_irqchip_add_msi_route, so let's make the difference
clearer.

Signed-off-by: Jan Kiszka 
---
 hw/pc_piix.c |8 
 kvm-all.c|2 +-
 kvm.h|2 +-
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 6a75718..c17f906 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -63,17 +63,17 @@ static void kvm_piix3_setup_irq_routing(bool pci_enabled)
 if (i == 2) {
 continue;
 }
-kvm_irqchip_add_route(s, i, KVM_IRQCHIP_PIC_MASTER, i);
+kvm_irqchip_add_irq_route(s, i, KVM_IRQCHIP_PIC_MASTER, i);
 }
 for (i = 8; i < 16; ++i) {
-kvm_irqchip_add_route(s, i, KVM_IRQCHIP_PIC_SLAVE, i - 8);
+kvm_irqchip_add_irq_route(s, i, KVM_IRQCHIP_PIC_SLAVE, i - 8);
 }
 if (pci_enabled) {
 for (i = 0; i < 24; ++i) {
 if (i == 0) {
-kvm_irqchip_add_route(s, i, KVM_IRQCHIP_IOAPIC, 2);
+kvm_irqchip_add_irq_route(s, i, KVM_IRQCHIP_IOAPIC, 2);
 } else if (i != 2) {
-kvm_irqchip_add_route(s, i, KVM_IRQCHIP_IOAPIC, i);
+kvm_irqchip_add_irq_route(s, i, KVM_IRQCHIP_IOAPIC, i);
 }
 }
 }
diff --git a/kvm-all.c b/kvm-all.c
index 1913d6a..0117837 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -935,7 +935,7 @@ static void kvm_add_routing_entry(KVMState *s,
 set_gsi(s, entry->gsi);
 }
 
-void kvm_irqchip_add_route(KVMState *s, int irq, int irqchip, int pin)
+void kvm_irqchip_add_irq_route(KVMState *s, int irq, int irqchip, int pin)
 {
 struct kvm_irq_routing_entry e;
 
diff --git a/kvm.h b/kvm.h
index 7857dbf..8b061bd 100644
--- a/kvm.h
+++ b/kvm.h
@@ -134,7 +134,7 @@ void kvm_arch_init_irq_routing(KVMState *s);
 int kvm_irqchip_set_irq(KVMState *s, int irq, int level);
 int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg);
 
-void kvm_irqchip_add_route(KVMState *s, int gsi, int irqchip, int pin);
+void kvm_irqchip_add_irq_route(KVMState *s, int gsi, int irqchip, int pin);
 int kvm_irqchip_commit_routes(KVMState *s);
 
 void kvm_put_apic_state(DeviceState *d, struct kvm_lapic_state *kapic);
-- 
1.7.3.4




[Qemu-devel] [RFC][PATCH v2 06/11] kvm: Publicize kvm_irqchip_release_virq

2012-05-17 Thread Jan Kiszka
From: Jan Kiszka 

This allows to drop routes created by kvm_irqchip_add_irq/msi_route
again.

Signed-off-by: Jan Kiszka 
---
 kvm-all.c  |2 +-
 kvm-stub.c |4 
 kvm.h  |1 +
 3 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index 7f906ca..ca6cec6 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -955,7 +955,7 @@ int kvm_irqchip_commit_routes(KVMState *s)
 return kvm_vm_ioctl(s, KVM_SET_GSI_ROUTING, s->irq_routes);
 }
 
-static void kvm_irqchip_release_virq(KVMState *s, int virq)
+void kvm_irqchip_release_virq(KVMState *s, int virq)
 {
 struct kvm_irq_routing_entry *e;
 int i;
diff --git a/kvm-stub.c b/kvm-stub.c
index db3a7dc..ec351d9 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -136,3 +136,7 @@ int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg)
 {
 return -ENOSYS;
 }
+
+void kvm_irqchip_release_virq(KVMState *s, int virq)
+{
+}
diff --git a/kvm.h b/kvm.h
index 67df1f1..1779e73 100644
--- a/kvm.h
+++ b/kvm.h
@@ -215,4 +215,5 @@ int kvm_set_ioeventfd_mmio(int fd, uint32_t adr, uint32_t 
val, bool assign,
 int kvm_set_ioeventfd_pio_word(int fd, uint16_t adr, uint16_t val, bool 
assign);
 
 int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg);
+void kvm_irqchip_release_virq(KVMState *s, int virq);
 #endif
-- 
1.7.3.4




[Qemu-devel] [PATCH 05/16] qemu-option: qemu_opt_parse(): use error_set()

2012-05-17 Thread Luiz Capitulino
The functions opt_set() and qemu_opts_validate() both call qemu_opt_parse(),
but their callers expect QError semantics. Thus, both functions call
qerro_report_err() to keep the expected semantics.

Signed-off-by: Luiz Capitulino 
---
 qemu-option.c |   36 +---
 1 file changed, 17 insertions(+), 19 deletions(-)

diff --git a/qemu-option.c b/qemu-option.c
index 61354af..d79acbd 100644
--- a/qemu-option.c
+++ b/qemu-option.c
@@ -584,38 +584,27 @@ uint64_t qemu_opt_get_size(QemuOpts *opts, const char 
*name, uint64_t defval)
 return opt->value.uint;
 }
 
-static int qemu_opt_parse(QemuOpt *opt)
+static void qemu_opt_parse(QemuOpt *opt, Error **errp)
 {
-Error *local_err = NULL;
-
 if (opt->desc == NULL)
-return 0;
+return;
 
 switch (opt->desc->type) {
 case QEMU_OPT_STRING:
 /* nothing */
-return 0;
+return;
 case QEMU_OPT_BOOL:
-parse_option_bool(opt->name, opt->str, &opt->value.boolean, 
&local_err);
+parse_option_bool(opt->name, opt->str, &opt->value.boolean, errp);
 break;
 case QEMU_OPT_NUMBER:
-parse_option_number(opt->name, opt->str, &opt->value.uint,
-&local_err);
+parse_option_number(opt->name, opt->str, &opt->value.uint, errp);
 break;
 case QEMU_OPT_SIZE:
-parse_option_size(opt->name, opt->str, &opt->value.uint, &local_err);
+parse_option_size(opt->name, opt->str, &opt->value.uint, errp);
 break;
 default:
 abort();
 }
-
-if (error_is_set(&local_err)) {
-qerror_report_err(local_err);
-error_free(local_err);
-return -1;
-}
-
-return 0;
 }
 
 static void qemu_opt_del(QemuOpt *opt)
@@ -631,6 +620,7 @@ static int opt_set(QemuOpts *opts, const char *name, const 
char *value,
 {
 QemuOpt *opt;
 const QemuOptDesc *desc = opts->list->desc;
+Error *local_err = NULL;
 int i;
 
 for (i = 0; desc[i].name != NULL; i++) {
@@ -661,10 +651,14 @@ static int opt_set(QemuOpts *opts, const char *name, 
const char *value,
 if (value) {
 opt->str = g_strdup(value);
 }
-if (qemu_opt_parse(opt) < 0) {
+qemu_opt_parse(opt, &local_err);
+if (error_is_set(&local_err)) {
+qerror_report_err(local_err);
+error_free(local_err);
 qemu_opt_del(opt);
 return -1;
 }
+
 return 0;
 }
 
@@ -1053,6 +1047,7 @@ QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict)
 int qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc)
 {
 QemuOpt *opt;
+Error *local_err = NULL;
 
 assert(opts->list->desc[0].name == NULL);
 
@@ -1071,7 +1066,10 @@ int qemu_opts_validate(QemuOpts *opts, const QemuOptDesc 
*desc)
 
 opt->desc = &desc[i];
 
-if (qemu_opt_parse(opt) < 0) {
+qemu_opt_parse(opt, &local_err);
+if (error_is_set(&local_err)) {
+qerror_report_err(local_err);
+error_free(local_err);
 return -1;
 }
 }
-- 
1.7.9.2.384.g4a92a




[Qemu-devel] [PATCH 11/16] qemu-config: find_list(): use error_set()

2012-05-17 Thread Luiz Capitulino
Note that qemu_find_opts() and qemu_config_parse() need to call
error_report() to maintain their semantics on error.

Signed-off-by: Luiz Capitulino 
---
 qemu-config.c |   32 +---
 1 file changed, 25 insertions(+), 7 deletions(-)

diff --git a/qemu-config.c b/qemu-config.c
index f876646..bdb381d 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -3,6 +3,7 @@
 #include "qemu-option.h"
 #include "qemu-config.h"
 #include "hw/qdev.h"
+#include "error.h"
 
 static QemuOptsList qemu_drive_opts = {
 .name = "drive",
@@ -631,7 +632,8 @@ static QemuOptsList *vm_config_groups[32] = {
 NULL,
 };
 
-static QemuOptsList *find_list(QemuOptsList **lists, const char *group)
+static QemuOptsList *find_list(QemuOptsList **lists, const char *group,
+   Error **errp)
 {
 int i;
 
@@ -640,14 +642,23 @@ static QemuOptsList *find_list(QemuOptsList **lists, 
const char *group)
 break;
 }
 if (lists[i] == NULL) {
-error_report("there is no option group \"%s\"", group);
+error_set(errp, QERR_INVALID_OPTION_GROUP, group);
 }
 return lists[i];
 }
 
 QemuOptsList *qemu_find_opts(const char *group)
 {
-return find_list(vm_config_groups, group);
+QemuOptsList *ret;
+Error *local_err = NULL;
+
+ret = find_list(vm_config_groups, group, &local_err);
+if (error_is_set(&local_err)) {
+error_report("%s\n", error_get_pretty(local_err));
+error_free(local_err);
+}
+
+return ret;
 }
 
 void qemu_add_opts(QemuOptsList *list)
@@ -762,6 +773,7 @@ int qemu_config_parse(FILE *fp, QemuOptsList **lists, const 
char *fname)
 char line[1024], group[64], id[64], arg[64], value[1024];
 Location loc;
 QemuOptsList *list = NULL;
+Error *local_err = NULL;
 QemuOpts *opts = NULL;
 int res = -1, lno = 0;
 
@@ -778,17 +790,23 @@ int qemu_config_parse(FILE *fp, QemuOptsList **lists, 
const char *fname)
 }
 if (sscanf(line, "[%63s \"%63[^\"]\"]", group, id) == 2) {
 /* group with id */
-list = find_list(lists, group);
-if (list == NULL)
+list = find_list(lists, group, &local_err);
+if (error_is_set(&local_err)) {
+error_report("%s\n", error_get_pretty(local_err));
+error_free(local_err);
 goto out;
+}
 opts = qemu_opts_create(list, id, 1, NULL);
 continue;
 }
 if (sscanf(line, "[%63[^]]]", group) == 1) {
 /* group without id */
-list = find_list(lists, group);
-if (list == NULL)
+list = find_list(lists, group, &local_err);
+if (error_is_set(&local_err)) {
+error_report("%s\n", error_get_pretty(local_err));
+error_free(local_err);
 goto out;
+}
 opts = qemu_opts_create(list, NULL, 0, NULL);
 continue;
 }
-- 
1.7.9.2.384.g4a92a




[Qemu-devel] [RFC][PATCH v2 10/11] msix: Add msix_nr_vectors_allocated

2012-05-17 Thread Jan Kiszka
From: Jan Kiszka 

Analogously to msi_nr_vectors_allocated, add a service for MSI-X. Will
be used by the virtio-pci layer.

Signed-off-by: Jan Kiszka 
---
 hw/msix.c |5 +
 hw/msix.h |2 ++
 2 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/hw/msix.c b/hw/msix.c
index 1622e16..59c7a83 100644
--- a/hw/msix.c
+++ b/hw/msix.c
@@ -452,6 +452,11 @@ void msix_unuse_all_vectors(PCIDevice *dev)
 msix_free_irq_entries(dev);
 }
 
+unsigned int msix_nr_vectors_allocated(const PCIDevice *dev)
+{
+return dev->msix_entries_nr;
+}
+
 static int msix_set_notifier_for_vector(PCIDevice *dev, unsigned int vector)
 {
 MSIMessage msg;
diff --git a/hw/msix.h b/hw/msix.h
index f33f18b..50aee82 100644
--- a/hw/msix.h
+++ b/hw/msix.h
@@ -13,6 +13,8 @@ void msix_write_config(PCIDevice *pci_dev, uint32_t address,
 
 int msix_uninit(PCIDevice *d, MemoryRegion *bar);
 
+unsigned int msix_nr_vectors_allocated(const PCIDevice *dev);
+
 void msix_save(PCIDevice *dev, QEMUFile *f);
 void msix_load(PCIDevice *dev, QEMUFile *f);
 
-- 
1.7.3.4




[Qemu-devel] [PATCH v2] qemu-img: Implement 'diff' operation.

2012-05-17 Thread Richard W.M. Jones
From: "Richard W.M. Jones" 

This produces a qcow2 file which is the difference between
two disk images.  ie, if:

  base.img - is a disk image (in any format)
  modified.img - is base.img, copied and modified

then:

  qemu-img diff -b base.img modified.img diff.qcow2

creates 'diff.qcow2' which contains the differences between 'base.img'
and 'modified.img'.  Note that 'diff.qcow2' has 'base.img' as its
backing file.

Signed-off-by: Richard W.M. Jones 
Cc: Matthew Booth 
Cc: Pablo Iranzo Gómez 
Cc: Tomas Von Veschler 
---
 qemu-img-cmds.hx |6 ++
 qemu-img.c   |  162 ++
 qemu-img.texi|   22 
 3 files changed, 190 insertions(+)

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 49dce7c..00eef96 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -33,6 +33,12 @@ STEXI
 @item convert [-c] [-p] [-f @var{fmt}] [-t @var{cache}] [-O @var{output_fmt}] 
[-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] 
@var{filename} [@var{filename2} [...]] @var{output_filename}
 ETEXI
 
+DEF("diff", img_diff,
+"diff [-F backing_fmt] -b backing_file [-f fmt] [-O output_fmt] [-o 
options] filename output_filename")
+STEXI
+@item diff [-F @var{backing_fmt}] -b @var{backing_file} [-f @var{fmt}] [-O 
@var{output_fmt}] [-o @var{options}] @var{filename} @var{output_filename}
+ETEXI
+
 DEF("info", img_info,
 "info [-f fmt] filename")
 STEXI
diff --git a/qemu-img.c b/qemu-img.c
index c8a70ff..ccf7541 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -1533,6 +1533,168 @@ out:
 return 0;
 }
 
+static int img_diff(int argc, char **argv)
+{
+/* qemu-img diff -b base modified out */
+BlockDriverState *bs_base, *bs_modified, *bs_out;
+const char *fmt_base, *base,
+*fmt_modified, *modified,
+*fmt_out, *out;
+char *options;
+int c, ret = 0;
+uint64_t num_sectors, modified_num_sectors;
+uint64_t sector;
+int n;
+uint8_t *buf_base;
+uint8_t *buf_modified;
+
+/* Parse commandline parameters */
+fmt_base = NULL;
+fmt_modified = NULL;
+fmt_out = NULL;
+base = NULL;
+options = NULL;
+for(;;) {
+c = getopt(argc, argv, "b:hf:F:O:o:");
+if (c == -1) {
+break;
+}
+switch(c) {
+case '?':
+case 'h':
+help();
+return 0;
+case 'f':
+fmt_modified = optarg;
+break;
+case 'F':
+fmt_base = optarg;
+break;
+case 'b':
+base = optarg;
+break;
+case 'O':
+fmt_out = optarg;
+break;
+case 'o':
+options = optarg;
+break;
+}
+}
+
+if (base == NULL) {
+error_report("The -b (backing filename) option must be supplied");
+return 1;
+}
+
+if (argc - optind != 2) {
+error_report("The input and output filenames must be supplied");
+return 1;
+}
+modified = argv[optind++];
+out = argv[optind++];
+
+if (fmt_out == NULL || fmt_out[0] == '\0') {
+fmt_out = "qcow2";
+}
+
+if (options && !strcmp(options, "?")) {
+ret = print_block_option_help(out, fmt_out);
+return 1;
+}
+
+/* Open the input images. */
+bs_base = bdrv_new_open(base, fmt_base, BDRV_O_FLAGS);
+if (!bs_base) {
+return 1;
+}
+
+bs_modified = bdrv_new_open(modified, fmt_modified, BDRV_O_FLAGS);
+if (!bs_modified) {
+return 1;
+}
+
+bdrv_get_geometry(bs_base, &num_sectors);
+bdrv_get_geometry(bs_modified, &modified_num_sectors);
+if (num_sectors != modified_num_sectors) {
+error_report("Number of sectors in backing and source must be the 
same");
+goto out2;
+}
+
+/* Output image. */
+ret = bdrv_img_create(out, fmt_out,
+  /* base file becomes the new backing file */
+  base, fmt_base,
+  options,
+  num_sectors * BDRV_SECTOR_SIZE, BDRV_O_FLAGS);
+if (ret != 0) {
+goto out2;
+}
+bs_out = bdrv_new_open(out, fmt_out, BDRV_O_RDWR);
+
+buf_base = qemu_blockalign(bs_base, IO_BUF_SIZE);
+buf_modified = qemu_blockalign(bs_modified, IO_BUF_SIZE);
+
+for (sector = 0; sector < num_sectors; sector += n) {
+/* How many sectors can we handle with the next read? */
+if (sector + (IO_BUF_SIZE / BDRV_SECTOR_SIZE) <= num_sectors) {
+n = IO_BUF_SIZE / BDRV_SECTOR_SIZE;
+} else {
+n = num_sectors - sector;
+}
+
+/* Read input files and compare. */
+ret = bdrv_read(bs_base, sector, buf_base, n);
+if (ret < 0) {
+error_report("error while reading from backing file");
+goto out;
+}
+
+ret = bdrv_read(bs_modified, sector, buf_modified, n);
+if (ret < 0) {
+error_repor

[Qemu-devel] [PATCH 09/16] qemu-option: qemu_opts_from_qdict(): use error_set()

2012-05-17 Thread Luiz Capitulino
do_device_add() and do_netdev_add() call qerror_report_err() to maintain
their QError semantics.

Signed-off-by: Luiz Capitulino 
---
 hw/qdev-monitor.c |7 +--
 net.c |5 -
 qemu-option.c |   31 ---
 qemu-option.h |3 ++-
 4 files changed, 35 insertions(+), 11 deletions(-)

diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
index eed781d..b01ef06 100644
--- a/hw/qdev-monitor.c
+++ b/hw/qdev-monitor.c
@@ -554,10 +554,13 @@ void do_info_qdm(Monitor *mon)
 
 int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
 {
+Error *local_err = NULL;
 QemuOpts *opts;
 
-opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict);
-if (!opts) {
+opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict, &local_err);
+if (error_is_set(&local_err)) {
+qerror_report_err(local_err);
+error_free(local_err);
 return -1;
 }
 if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
diff --git a/net.c b/net.c
index f5d9cc7..246209f 100644
--- a/net.c
+++ b/net.c
@@ -1237,11 +1237,14 @@ void net_host_device_remove(Monitor *mon, const QDict 
*qdict)
 
 int do_netdev_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
 {
+Error *local_err = NULL;
 QemuOpts *opts;
 int res;
 
-opts = qemu_opts_from_qdict(qemu_find_opts("netdev"), qdict);
+opts = qemu_opts_from_qdict(qemu_find_opts("netdev"), qdict, &local_err);
 if (!opts) {
+qerror_report_err(local_err);
+error_free(local_err);
 return -1;
 }
 
diff --git a/qemu-option.c b/qemu-option.c
index afee3fb..a26c40a 100644
--- a/qemu-option.c
+++ b/qemu-option.c
@@ -971,13 +971,19 @@ void qemu_opts_set_defaults(QemuOptsList *list, const 
char *params,
 assert(opts);
 }
 
+typedef struct OptsFromQDictState {
+QemuOpts *opts;
+Error **errp;
+} OptsFromQDictState;
+
 static void qemu_opts_from_qdict_1(const char *key, QObject *obj, void *opaque)
 {
+OptsFromQDictState *state = opaque;
 char buf[32];
 const char *value;
 int n;
 
-if (!strcmp(key, "id")) {
+if (!strcmp(key, "id") || error_is_set(state->errp)) {
 return;
 }
 
@@ -1005,7 +1011,8 @@ static void qemu_opts_from_qdict_1(const char *key, 
QObject *obj, void *opaque)
 default:
 return;
 }
-qemu_opt_set(opaque, key, value);
+
+qemu_opt_set_err(state->opts, key, value, state->errp);
 }
 
 /*
@@ -1014,21 +1021,31 @@ static void qemu_opts_from_qdict_1(const char *key, 
QObject *obj, void *opaque)
  * Only QStrings, QInts, QFloats and QBools are copied.  Entries with
  * other types are silently ignored.
  */
-QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict)
+QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict,
+   Error **errp)
 {
-QemuOpts *opts;
+OptsFromQDictState state;
 Error *local_err = NULL;
+QemuOpts *opts;
 
 opts = qemu_opts_create(list, qdict_get_try_str(qdict, "id"), 1,
 &local_err);
 if (error_is_set(&local_err)) {
-qerror_report_err(local_err);
-error_free(local_err);
+error_propagate(errp, local_err);
 return NULL;
 }
 
 assert(opts != NULL);
-qdict_iter(qdict, qemu_opts_from_qdict_1, opts);
+
+state.errp = &local_err;
+state.opts = opts;
+qdict_iter(qdict, qemu_opts_from_qdict_1, &state);
+if (error_is_set(&local_err)) {
+error_propagate(errp, local_err);
+qemu_opts_del(opts);
+return NULL;
+}
+
 return opts;
 }
 
diff --git a/qemu-option.h b/qemu-option.h
index c0e022b..951dec3 100644
--- a/qemu-option.h
+++ b/qemu-option.h
@@ -132,7 +132,8 @@ int qemu_opts_do_parse(QemuOpts *opts, const char *params, 
const char *firstname
 QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, int 
permit_abbrev);
 void qemu_opts_set_defaults(QemuOptsList *list, const char *params,
 int permit_abbrev);
-QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict);
+QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict,
+   Error **errp);
 QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict);
 
 typedef int (*qemu_opts_loopfunc)(QemuOpts *opts, void *opaque);
-- 
1.7.9.2.384.g4a92a




[Qemu-devel] [PATCH 04/16] qemu-option: parse_option_size(): use error_set()

2012-05-17 Thread Luiz Capitulino
Signed-off-by: Luiz Capitulino 
---
 qemu-option.c |   20 +++-
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/qemu-option.c b/qemu-option.c
index a8b50af..61354af 100644
--- a/qemu-option.c
+++ b/qemu-option.c
@@ -203,7 +203,8 @@ static void parse_option_number(const char *name, const 
char *value,
 }
 }
 
-static int parse_option_size(const char *name, const char *value, uint64_t 
*ret)
+static void parse_option_size(const char *name, const char *value,
+  uint64_t *ret, Error **errp)
 {
 char *postfix;
 double sizef;
@@ -229,16 +230,14 @@ static int parse_option_size(const char *name, const char 
*value, uint64_t *ret)
 *ret = (uint64_t) sizef;
 break;
 default:
-qerror_report(QERR_INVALID_PARAMETER_VALUE, name, "a size");
+error_set(errp, QERR_INVALID_PARAMETER_VALUE, name, "a size");
 error_printf_unless_qmp("You may use k, M, G or T suffixes for "
 "kilobytes, megabytes, gigabytes and terabytes.\n");
-return -1;
+return;
 }
 } else {
-qerror_report(QERR_INVALID_PARAMETER_VALUE, name, "a size");
-return -1;
+error_set(errp, QERR_INVALID_PARAMETER_VALUE, name, "a size");
 }
-return 0;
 }
 
 /*
@@ -291,8 +290,10 @@ int set_option_parameter(QEMUOptionParameter *list, const 
char *name,
 break;
 
 case OPT_SIZE:
-if (parse_option_size(name, value, &list->value.n) == -1)
-return -1;
+parse_option_size(name, value, &list->value.n, &local_err);
+if (error_is_set(&local_err)) {
+goto exit_err;
+}
 break;
 
 default:
@@ -602,7 +603,8 @@ static int qemu_opt_parse(QemuOpt *opt)
 &local_err);
 break;
 case QEMU_OPT_SIZE:
-return parse_option_size(opt->name, opt->str, &opt->value.uint);
+parse_option_size(opt->name, opt->str, &opt->value.uint, &local_err);
+break;
 default:
 abort();
 }
-- 
1.7.9.2.384.g4a92a




Re: [Qemu-devel] [PATCH] qemu-img: Implement 'diff' operation.

2012-05-17 Thread Richard W.M. Jones
On Thu, May 17, 2012 at 07:57:31AM -0600, Eric Blake wrote:
[...]

I just posted a v2 patch which fixes everything you mentioned except
the case of resizing the disk, which I need to think about a bit more.

Rich.

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
virt-p2v converts physical machines to virtual machines.  Boot with a
live CD or over the network (PXE) and turn machines into Xen guests.
http://et.redhat.com/~rjones/virt-p2v



[Qemu-devel] [PATCH 08/16] qemu-option: introduce qemu_opt_set_err()

2012-05-17 Thread Luiz Capitulino
This is like qemu_opt_set(), except that it takes an Error argument.

This new function allows for a incremental conversion of code using
qemu_opt_set().

Signed-off-by: Luiz Capitulino 
---
 qemu-option.c |6 ++
 qemu-option.h |2 ++
 2 files changed, 8 insertions(+)

diff --git a/qemu-option.c b/qemu-option.c
index c54bb21..afee3fb 100644
--- a/qemu-option.c
+++ b/qemu-option.c
@@ -672,6 +672,12 @@ int qemu_opt_set(QemuOpts *opts, const char *name, const 
char *value)
 return 0;
 }
 
+void qemu_opt_set_err(QemuOpts *opts, const char *name, const char *value,
+  Error **errp)
+{
+opt_set(opts, name, value, false, errp);
+}
+
 int qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val)
 {
 QemuOpt *opt;
diff --git a/qemu-option.h b/qemu-option.h
index e9fbbb5..c0e022b 100644
--- a/qemu-option.h
+++ b/qemu-option.h
@@ -111,6 +111,8 @@ bool qemu_opt_get_bool(QemuOpts *opts, const char *name, 
bool defval);
 uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t 
defval);
 uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval);
 int qemu_opt_set(QemuOpts *opts, const char *name, const char *value);
+void qemu_opt_set_err(QemuOpts *opts, const char *name, const char *value,
+  Error **errp);
 int qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val);
 typedef int (*qemu_opt_loopfunc)(const char *name, const char *value, void 
*opaque);
 int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque,
-- 
1.7.9.2.384.g4a92a




[Qemu-devel] [PATCH 13/16] net: purge the monitor object from all init functions

2012-05-17 Thread Luiz Capitulino
The only backend that really uses it is the socket one, which calls
monitor_get_fd(). But it can use 'cur_mon' instead.

Signed-off-by: Luiz Capitulino 
---
 hw/pci-hotplug.c |2 +-
 hw/usb/dev-network.c |2 +-
 net.c|   18 +++---
 net.h|2 +-
 net/dump.c   |2 +-
 net/dump.h   |3 +--
 net/slirp.c  |5 +
 net/slirp.h  |5 +
 net/socket.c |8 +++-
 net/socket.h |3 +--
 net/tap-win32.c  |2 +-
 net/tap.c|9 -
 net/tap.h|5 ++---
 net/vde.c|2 +-
 net/vde.h|2 +-
 15 files changed, 27 insertions(+), 43 deletions(-)

diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c
index c55d8b9..785eb3d 100644
--- a/hw/pci-hotplug.c
+++ b/hw/pci-hotplug.c
@@ -60,7 +60,7 @@ static PCIDevice *qemu_pci_hot_add_nic(Monitor *mon,
 
 qemu_opt_set(opts, "type", "nic");
 
-ret = net_client_init(mon, opts, 0);
+ret = net_client_init(opts, 0);
 if (ret < 0)
 return NULL;
 if (nd_table[ret].devaddr) {
diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c
index b238a09..4e26e64 100644
--- a/hw/usb/dev-network.c
+++ b/hw/usb/dev-network.c
@@ -1367,7 +1367,7 @@ static USBDevice *usb_net_init(USBBus *bus, const char 
*cmdline)
 qemu_opt_set(opts, "type", "nic");
 qemu_opt_set(opts, "model", "usb");
 
-idx = net_client_init(NULL, opts, 0);
+idx = net_client_init(opts, 0);
 if (idx == -1) {
 return NULL;
 }
diff --git a/net.c b/net.c
index 246209f..adb7e20 100644
--- a/net.c
+++ b/net.c
@@ -745,10 +745,7 @@ int net_handle_fd_param(Monitor *mon, const char *param)
 return fd;
 }
 
-static int net_init_nic(QemuOpts *opts,
-Monitor *mon,
-const char *name,
-VLANState *vlan)
+static int net_init_nic(QemuOpts *opts, const char *name, VLANState *vlan)
 {
 int idx;
 NICInfo *nd;
@@ -821,7 +818,6 @@ static int net_init_nic(QemuOpts *opts,
  }
 
 typedef int (*net_client_init_func)(QemuOpts *opts,
-Monitor *mon,
 const char *name,
 VLANState *vlan);
 
@@ -1085,7 +1081,7 @@ static const struct {
 #endif /* CONFIG_NET_BRIDGE */
 };
 
-int net_client_init(Monitor *mon, QemuOpts *opts, int is_netdev)
+int net_client_init(QemuOpts *opts, int is_netdev)
 {
 const char *name;
 const char *type;
@@ -1156,7 +1152,7 @@ int net_client_init(Monitor *mon, QemuOpts *opts, int 
is_netdev)
 
 ret = 0;
 if (net_client_types[i].init) {
-ret = net_client_types[i].init(opts, mon, name, vlan);
+ret = net_client_types[i].init(opts, name, vlan);
 if (ret < 0) {
 /* TODO push error reporting into init() methods */
 qerror_report(QERR_DEVICE_INIT_FAILED, type);
@@ -1213,7 +1209,7 @@ void net_host_device_add(Monitor *mon, const QDict *qdict)
 
 qemu_opt_set(opts, "type", device);
 
-if (net_client_init(mon, opts, 0) < 0) {
+if (net_client_init(opts, 0) < 0) {
 monitor_printf(mon, "adding host network device %s failed\n", device);
 }
 }
@@ -1248,7 +1244,7 @@ int do_netdev_add(Monitor *mon, const QDict *qdict, 
QObject **ret_data)
 return -1;
 }
 
-res = net_client_init(mon, opts, 1);
+res = net_client_init(opts, 1);
 if (res < 0) {
 qemu_opts_del(opts);
 }
@@ -1431,14 +1427,14 @@ void net_check_clients(void)
 
 static int net_init_client(QemuOpts *opts, void *dummy)
 {
-if (net_client_init(NULL, opts, 0) < 0)
+if (net_client_init(opts, 0) < 0)
 return -1;
 return 0;
 }
 
 static int net_init_netdev(QemuOpts *opts, void *dummy)
 {
-return net_client_init(NULL, opts, 1);
+return net_client_init(opts, 1);
 }
 
 int net_init_clients(void)
diff --git a/net.h b/net.h
index 64993b4..9d1ed93 100644
--- a/net.h
+++ b/net.h
@@ -163,7 +163,7 @@ struct HCIInfo *qemu_next_hci(void);
 extern const char *legacy_tftp_prefix;
 extern const char *legacy_bootp_filename;
 
-int net_client_init(Monitor *mon, QemuOpts *opts, int is_netdev);
+int net_client_init(QemuOpts *opts, int is_netdev);
 int net_client_parse(QemuOptsList *opts_list, const char *str);
 int net_init_clients(void);
 void net_check_clients(void);
diff --git a/net/dump.c b/net/dump.c
index 4b48d48..f835c51 100644
--- a/net/dump.c
+++ b/net/dump.c
@@ -144,7 +144,7 @@ static int net_dump_init(VLANState *vlan, const char 
*device,
 return 0;
 }
 
-int net_init_dump(QemuOpts *opts, Monitor *mon, const char *name, VLANState 
*vlan)
+int net_init_dump(QemuOpts *opts, const char *name, VLANState *vlan)
 {
 int len;
 const char *file;
diff --git a/net/dump.h b/net/dump.h
index fdc91ad..2b5d9ba 100644
--- a/net/dump.h
+++ b/net/dump.h
@@ -27,7 +27,6 @@
 #include 

[Qemu-devel] [PATCH 14/16] net: net_client_init(): use error_set()

2012-05-17 Thread Luiz Capitulino
Callers are changed to use qerror_report_err() to keep their QError
semantics.

Signed-off-by: Luiz Capitulino 
---
 hw/pci-hotplug.c |8 ++--
 hw/usb/dev-network.c |7 +--
 net.c|   53 +++---
 net.h|2 +-
 4 files changed, 49 insertions(+), 21 deletions(-)

diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c
index 785eb3d..61257f4 100644
--- a/hw/pci-hotplug.c
+++ b/hw/pci-hotplug.c
@@ -39,6 +39,7 @@ static PCIDevice *qemu_pci_hot_add_nic(Monitor *mon,
const char *devaddr,
const char *opts_str)
 {
+Error *local_err = NULL;
 QemuOpts *opts;
 PCIBus *bus;
 int ret, devfn;
@@ -60,9 +61,12 @@ static PCIDevice *qemu_pci_hot_add_nic(Monitor *mon,
 
 qemu_opt_set(opts, "type", "nic");
 
-ret = net_client_init(opts, 0);
-if (ret < 0)
+ret = net_client_init(opts, 0, &local_err);
+if (error_is_set(&local_err)) {
+qerror_report_err(local_err);
+error_free(local_err);
 return NULL;
+}
 if (nd_table[ret].devaddr) {
 monitor_printf(mon, "Parameter addr not supported\n");
 return NULL;
diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c
index 4e26e64..5d2f098 100644
--- a/hw/usb/dev-network.c
+++ b/hw/usb/dev-network.c
@@ -1356,6 +1356,7 @@ static int usb_net_initfn(USBDevice *dev)
 
 static USBDevice *usb_net_init(USBBus *bus, const char *cmdline)
 {
+Error *local_err = NULL;
 USBDevice *dev;
 QemuOpts *opts;
 int idx;
@@ -1367,8 +1368,10 @@ static USBDevice *usb_net_init(USBBus *bus, const char 
*cmdline)
 qemu_opt_set(opts, "type", "nic");
 qemu_opt_set(opts, "model", "usb");
 
-idx = net_client_init(opts, 0);
-if (idx == -1) {
+idx = net_client_init(opts, 0, &local_err);
+if (error_is_set(&local_err)) {
+qerror_report_err(local_err);
+error_free(local_err);
 return NULL;
 }
 
diff --git a/net.c b/net.c
index adb7e20..7e9d0c5 100644
--- a/net.c
+++ b/net.c
@@ -1081,7 +1081,7 @@ static const struct {
 #endif /* CONFIG_NET_BRIDGE */
 };
 
-int net_client_init(QemuOpts *opts, int is_netdev)
+int net_client_init(QemuOpts *opts, int is_netdev, Error **errp)
 {
 const char *name;
 const char *type;
@@ -1089,7 +1089,7 @@ int net_client_init(QemuOpts *opts, int is_netdev)
 
 type = qemu_opt_get(opts, "type");
 if (!type) {
-qerror_report(QERR_MISSING_PARAMETER, "type");
+error_set(errp, QERR_MISSING_PARAMETER, "type");
 return -1;
 }
 
@@ -1105,21 +1105,21 @@ int net_client_init(QemuOpts *opts, int is_netdev)
 strcmp(type, "vde") != 0 &&
 #endif
 strcmp(type, "socket") != 0) {
-qerror_report(QERR_INVALID_PARAMETER_VALUE, "type",
-  "a netdev backend type");
+error_set(errp, QERR_INVALID_PARAMETER_VALUE, "type",
+  "a netdev backend type");
 return -1;
 }
 
 if (qemu_opt_get(opts, "vlan")) {
-qerror_report(QERR_INVALID_PARAMETER, "vlan");
+error_set(errp, QERR_INVALID_PARAMETER, "vlan");
 return -1;
 }
 if (qemu_opt_get(opts, "name")) {
-qerror_report(QERR_INVALID_PARAMETER, "name");
+error_set(errp, QERR_INVALID_PARAMETER, "name");
 return -1;
 }
 if (!qemu_opts_id(opts)) {
-qerror_report(QERR_MISSING_PARAMETER, "id");
+error_set(errp, QERR_MISSING_PARAMETER, "id");
 return -1;
 }
 }
@@ -1138,8 +1138,7 @@ int net_client_init(QemuOpts *opts, int is_netdev)
 
 qemu_opts_validate(opts, &net_client_types[i].desc[0], &local_err);
 if (error_is_set(&local_err)) {
-qerror_report_err(local_err);
-error_free(local_err);
+error_propagate(errp, local_err);
 return -1;
 }
 
@@ -1155,7 +1154,7 @@ int net_client_init(QemuOpts *opts, int is_netdev)
 ret = net_client_types[i].init(opts, name, vlan);
 if (ret < 0) {
 /* TODO push error reporting into init() methods */
-qerror_report(QERR_DEVICE_INIT_FAILED, type);
+error_set(errp, QERR_DEVICE_INIT_FAILED, type);
 return -1;
 }
 }
@@ -1163,8 +1162,8 @@ int net_client_init(QemuOpts *opts, int is_netdev)
 }
 }
 
-qerror_report(QERR_INVALID_PARAMETER_VALUE, "type",
-  "a network client type");
+error_set(errp, QERR_INVALID_PARAMETER_VALUE, "type",
+  "a network client type");
 return -1;
 }
 
@@ -1195,6 +1194,7 @@ void net_host_device_add(Monitor *mon, const QDict *qdict)
 {
 const char *device = qdict_get_str(qdict, "device");
 const char *opts_str = qdict_get_try_s

[Qemu-devel] [PATCH 07/16] qemu-option: opt_set(): use error_set()

2012-05-17 Thread Luiz Capitulino
The functions qemu_opt_set() and opts_do_parse() both call opt_set(),
but their callers expect QError semantics. Thus, both functions call
qerro_report_err() to keep the expected semantics.

Signed-off-by: Luiz Capitulino 
---
 qemu-option.c |   31 ---
 1 file changed, 20 insertions(+), 11 deletions(-)

diff --git a/qemu-option.c b/qemu-option.c
index 3a9a5f8..c54bb21 100644
--- a/qemu-option.c
+++ b/qemu-option.c
@@ -615,8 +615,8 @@ static void qemu_opt_del(QemuOpt *opt)
 g_free(opt);
 }
 
-static int opt_set(QemuOpts *opts, const char *name, const char *value,
-   bool prepend)
+static void opt_set(QemuOpts *opts, const char *name, const char *value,
+bool prepend, Error **errp)
 {
 QemuOpt *opt;
 const QemuOptDesc *desc = opts->list->desc;
@@ -632,8 +632,8 @@ static int opt_set(QemuOpts *opts, const char *name, const 
char *value,
 if (i == 0) {
 /* empty list -> allow any */;
 } else {
-qerror_report(QERR_INVALID_PARAMETER, name);
-return -1;
+error_set(errp, QERR_INVALID_PARAMETER, name);
+return;
 }
 }
 
@@ -653,18 +653,23 @@ static int opt_set(QemuOpts *opts, const char *name, 
const char *value,
 }
 qemu_opt_parse(opt, &local_err);
 if (error_is_set(&local_err)) {
-qerror_report_err(local_err);
-error_free(local_err);
+error_propagate(errp, local_err);
 qemu_opt_del(opt);
-return -1;
 }
-
-return 0;
 }
 
 int qemu_opt_set(QemuOpts *opts, const char *name, const char *value)
 {
-return opt_set(opts, name, value, false);
+Error *local_err = NULL;
+
+opt_set(opts, name, value, false, &local_err);
+if (error_is_set(&local_err)) {
+qerror_report_err(local_err);
+error_free(local_err);
+return -1;
+}
+
+return 0;
 }
 
 int qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val)
@@ -850,6 +855,7 @@ static int opts_do_parse(QemuOpts *opts, const char *params,
 {
 char option[128], value[1024];
 const char *p,*pe,*pc;
+Error *local_err = NULL;
 
 for (p = params; *p != '\0'; p++) {
 pe = strchr(p, '=');
@@ -881,7 +887,10 @@ static int opts_do_parse(QemuOpts *opts, const char 
*params,
 }
 if (strcmp(option, "id") != 0) {
 /* store and parse */
-if (opt_set(opts, option, value, prepend) == -1) {
+opt_set(opts, option, value, prepend, &local_err);
+if (error_is_set(&local_err)) {
+qerror_report_err(local_err);
+error_free(local_err);
 return -1;
 }
 }
-- 
1.7.9.2.384.g4a92a




Re: [Qemu-devel] [PATCH v2] qemu-img: Implement 'diff' operation.

2012-05-17 Thread Eric Blake
On 05/17/2012 08:57 AM, Richard W.M. Jones wrote:
> From: "Richard W.M. Jones" 
> 
> This produces a qcow2 file which is the difference between
> two disk images.  ie, if:
> 
>   base.img - is a disk image (in any format)
>   modified.img - is base.img, copied and modified
> 
> then:
> 
>   qemu-img diff -b base.img modified.img diff.qcow2
> 
> creates 'diff.qcow2' which contains the differences between 'base.img'
> and 'modified.img'.  Note that 'diff.qcow2' has 'base.img' as its
> backing file.
> 

> +++ b/qemu-img-cmds.hx
> @@ -33,6 +33,12 @@ STEXI
>  @item convert [-c] [-p] [-f @var{fmt}] [-t @var{cache}] [-O 
> @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S 
> @var{sparse_size}] @var{filename} [@var{filename2} [...]] 
> @var{output_filename}
>  ETEXI
>  
> +DEF("diff", img_diff,
> +"diff [-F backing_fmt] -b backing_file [-f fmt] [-O output_fmt] [-o 
> options] filename output_filename")
> +STEXI
> +@item diff [-F @var{backing_fmt}] -b @var{backing_file} [-f @var{fmt}] [-O 
> @var{output_fmt}] [-o @var{options}] @var{filename} @var{output_filename}

Why the difference in ordering between -o and -O?


> +
> +if (argc - optind != 2) {
> +error_report("The input and output filenames must be supplied");
> +return 1;

Error is misleading if argc > optind+2.


> +
> +if (fmt_out == NULL || fmt_out[0] == '\0') {
> +fmt_out = "qcow2";
> +}

So output defaults to qcow2, and input (both base and modified) default
to probing.  Works for me.

> +
> +bdrv_get_geometry(bs_base, &num_sectors);
> +bdrv_get_geometry(bs_modified, &modified_num_sectors);
> +if (num_sectors != modified_num_sectors) {
> +error_report("Number of sectors in backing and source must be the 
> same");
> +goto out2;
> +}

I can live with an initial implementation that is strict, where a later
patch relaxes things to allow a modified image that has been enlarged.

> +
> +/* Output image. */
> +ret = bdrv_img_create(out, fmt_out,
> +  /* base file becomes the new backing file */
> +  base, fmt_base,
> +  options,
> +  num_sectors * BDRV_SECTOR_SIZE, BDRV_O_FLAGS);

I still think this should be modified_num_sectors - for now, the two
values are equal, but if we relax the error check up above, then you
really do want to go with the output file the same size as the modified
file.

It looks like you did indeed address most of my comments on v1.

-- 
Eric Blake   ebl...@redhat.com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PATCH 10/16] qerror: introduce QERR_INVALID_OPTION_GROUP

2012-05-17 Thread Luiz Capitulino
Signed-off-by: Luiz Capitulino 
---
 qerror.c |4 
 qerror.h |3 +++
 2 files changed, 7 insertions(+)

diff --git a/qerror.c b/qerror.c
index 5092fe7..92c4eff 100644
--- a/qerror.c
+++ b/qerror.c
@@ -156,6 +156,10 @@ static const QErrorStringTable qerror_table[] = {
 .desc  = "Invalid block format '%(name)'",
 },
 {
+.error_fmt = QERR_INVALID_OPTION_GROUP,
+.desc  = "There is no option group '%(group)'",
+},
+{
 .error_fmt = QERR_INVALID_PARAMETER,
 .desc  = "Invalid parameter '%(name)'",
 },
diff --git a/qerror.h b/qerror.h
index 4cbba48..b4c8758 100644
--- a/qerror.h
+++ b/qerror.h
@@ -139,6 +139,9 @@ QError *qobject_to_qerror(const QObject *obj);
 #define QERR_INVALID_BLOCK_FORMAT \
 "{ 'class': 'InvalidBlockFormat', 'data': { 'name': %s } }"
 
+#define QERR_INVALID_OPTION_GROUP \
+"{ 'class': 'InvalidOptionGroup', 'data': { 'group': %s } }"
+
 #define QERR_INVALID_PARAMETER \
 "{ 'class': 'InvalidParameter', 'data': { 'name': %s } }"
 
-- 
1.7.9.2.384.g4a92a




[Qemu-devel] [PATCH 16/16] qapi: convert netdev_del

2012-05-17 Thread Luiz Capitulino
Signed-off-by: Anthony Liguori 
Signed-off-by: Luiz Capitulino 
---
 hmp-commands.hx  |3 +--
 hmp.c|9 +
 hmp.h|1 +
 net.c|   11 +--
 net.h|1 -
 qapi-schema.json |   14 ++
 qmp-commands.hx  |5 +
 7 files changed, 31 insertions(+), 13 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index d0ce6a5..f5d9d91 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1051,8 +1051,7 @@ ETEXI
 .args_type  = "id:s",
 .params = "id",
 .help   = "remove host network device",
-.user_print = monitor_user_noop,
-.mhandler.cmd_new = do_netdev_del,
+.mhandler.cmd = hmp_netdev_del,
 },
 
 STEXI
diff --git a/hmp.c b/hmp.c
index 7a4e25f..2ce8cb9 100644
--- a/hmp.c
+++ b/hmp.c
@@ -990,3 +990,12 @@ void hmp_netdev_add(Monitor *mon, const QDict *qdict)
 out:
 hmp_handle_error(mon, &err);
 }
+
+void hmp_netdev_del(Monitor *mon, const QDict *qdict)
+{
+const char *id = qdict_get_str(qdict, "id");
+Error *err = NULL;
+
+qmp_netdev_del(id, &err);
+hmp_handle_error(mon, &err);
+}
diff --git a/hmp.h b/hmp.h
index 017df87..79d138d 100644
--- a/hmp.h
+++ b/hmp.h
@@ -63,5 +63,6 @@ void hmp_migrate(Monitor *mon, const QDict *qdict);
 void hmp_device_del(Monitor *mon, const QDict *qdict);
 void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict);
 void hmp_netdev_add(Monitor *mon, const QDict *qdict);
+void hmp_netdev_del(Monitor *mon, const QDict *qdict);
 
 #endif
diff --git a/net.c b/net.c
index 5f0c53c..4aa416c 100644
--- a/net.c
+++ b/net.c
@@ -1269,19 +1269,18 @@ exit_err:
 return -1;
 }
 
-int do_netdev_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
+void qmp_netdev_del(const char *id, Error **errp)
 {
-const char *id = qdict_get_str(qdict, "id");
 VLANClientState *vc;
 
 vc = qemu_find_netdev(id);
 if (!vc) {
-qerror_report(QERR_DEVICE_NOT_FOUND, id);
-return -1;
+error_set(errp, QERR_DEVICE_NOT_FOUND, id);
+return;
 }
+
 qemu_del_vlan_client(vc);
-qemu_opts_del(qemu_opts_find(qemu_find_opts("netdev"), id));
-return 0;
+qemu_opts_del(qemu_opts_find(qemu_find_opts_err("netdev", errp), id));
 }
 
 static void print_net_client(Monitor *mon, VLANClientState *vc)
diff --git a/net.h b/net.h
index 1eb9280..bdc2a06 100644
--- a/net.h
+++ b/net.h
@@ -172,7 +172,6 @@ void net_host_device_add(Monitor *mon, const QDict *qdict);
 void net_host_device_remove(Monitor *mon, const QDict *qdict);
 void netdev_add(QemuOpts *opts, Error **errp);
 int qmp_netdev_add(Monitor *mon, const QDict *qdict, QObject **ret);
-int do_netdev_del(Monitor *mon, const QDict *qdict, QObject **ret_data);
 
 #define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
 #define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
diff --git a/qapi-schema.json b/qapi-schema.json
index 69fcd8e..bb1f806 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1826,3 +1826,17 @@
 { 'command': 'netdev_add',
   'data': {'type': 'str', 'id': 'str', '*props': '**'},
   'gen': 'no' }
+
+##
+# @netdev_del:
+#
+# Remove a network backend.
+#
+# @id: the name of the network backend to remove
+#
+# Returns: Nothing on success
+#  If @id is not a valid network backend, DeviceNotFound
+#
+# Since: 0.14.0
+##
+{ 'command': 'netdev_del', 'data': {'id': 'str'} }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index f6550cb..57ea803 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -671,10 +671,7 @@ EQMP
 {
 .name   = "netdev_del",
 .args_type  = "id:s",
-.params = "id",
-.help   = "remove host network device",
-.user_print = monitor_user_noop,
-.mhandler.cmd_new = do_netdev_del,
+.mhandler.cmd_new = qmp_marshal_input_netdev_del,
 },
 
 SQMP
-- 
1.7.9.2.384.g4a92a




Re: [Qemu-devel] [PATCH v6 0/7] RTC: New logic to emulate RTC

2012-05-17 Thread Paolo Bonzini
Il 17/05/2012 04:28, Zhang, Yang Z ha scritto:
> Changes in v6:
> Rebase to latest QEMU
> Fix a bug that fail to pass tests/rtc-test:
>   In previous version, it uses host time as the base point to calculate 
> guest RTC. It works when guest uses host based clock. But for vm and rt based 
> clock, it's wrong. Because guest's clock may not synchronous with host. In 
> current patch, it use rtc_clock as the reference point and successes to pass 
> the testing.
> Adapt paolo's suggestion to use more reasonable code for migration.

Nice work!

I've made my testcase even nastier and done the following changes:

* simplified the code to remove the double update timer.  The idea is
that if you can latch the update-in-progress flag 244us before the timer
expires in update_in_progress, instead of using a separate timer.

* improved bisectability by squashing some patches and separating others.

* changed the code to do all computation in nanoseconds

* simplified the handling of the offset (and I think also made it more
precise)

* added another corner case: the SET bit does not stop interrupts, while
divider reset does

The result is at git://github.com/bonzini/qemu.git in branch rtc-intel.
 You're welcome to give it a further shake, but IMO it's good to go for 1.2!

Paolo



Re: [Qemu-devel] [PATCH 04/13] pci: New pci_dma_quirk()

2012-05-17 Thread Alex Williamson
On Thu, 2012-05-17 at 15:19 +0800, Anonymous wrote:
> Alex,
> 
> On Sat, May 12, 2012 at 6:55 AM, Alex Williamson
>  wrote:
> > Integrating IOMMU groups more closely into the driver core allows
> > us to more easily work around DMA quirks.  The Ricoh multifunction
> > controller is a favorite example of devices that are currently
> > incompatible with IOMMU isolation as all the functions use the
> > requestor ID of function 0 for DMA.  Passing this device into
> > pci_dma_quirk returns the PCI device to use for DMA.  The IOMMU
> > driver can then construct an IOMMU group including both devices.
> >
> 
> Please give some thought to the Marvell SATA controller quirk as well.
> 
> Instead of multiple visible functions using the same requester ID of
> function 0, the Marvell device only makes function 0 visible, but uses
> the requestor ID of function 1 as well during DMA.
> 
> See https://bugzilla.redhat.com/show_bug.cgi?id=757166

Wow.  That one isn't quite as easy to deal with since there's no
existing device in the kernel to point to.  This comment might be on the
right track:

https://bugzilla.kernel.org/show_bug.cgi?id=42679#c11

Perhaps David Woodhouse can comment on support for phantom functions.
If we had infrastructure for that it might be easy for the quirk to
update the pci_dev struct, inserting a new phantom function.  Otherwise
we'd need to create a new device in the kernel for it.  Thanks,

Alex





Re: [Qemu-devel] [PATCH v2] qemu-img: Implement 'diff' operation.

2012-05-17 Thread Richard W.M. Jones
On Thu, May 17, 2012 at 09:15:08AM -0600, Eric Blake wrote:
> On 05/17/2012 08:57 AM, Richard W.M. Jones wrote:
> > +DEF("diff", img_diff,
> > +"diff [-F backing_fmt] -b backing_file [-f fmt] [-O output_fmt] [-o 
> > options] filename output_filename")
> > +STEXI
> > +@item diff [-F @var{backing_fmt}] -b @var{backing_file} [-f @var{fmt}] [-O 
> > @var{output_fmt}] [-o @var{options}] @var{filename} @var{output_filename}
> 
> Why the difference in ordering between -o and -O?

I though it looked more logical, but I can swap them around too if you
think it's better.

> > +
> > +if (argc - optind != 2) {
> > +error_report("The input and output filenames must be supplied");
> > +return 1;
> 
> Error is misleading if argc > optind+2.

OK will fix.

I'll rework the num_sectors thing in v3.

Rich.

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
virt-p2v converts physical machines to virtual machines.  Boot with a
live CD or over the network (PXE) and turn machines into Xen guests.
http://et.redhat.com/~rjones/virt-p2v



[Qemu-devel] [PATCH v3] qemu-img: Implement 'diff' operation.

2012-05-17 Thread Richard W.M. Jones
From: "Richard W.M. Jones" 

This produces a qcow2 file which is the difference between
two disk images.  ie, if:

  base.img - is a disk image (in any format)
  modified.img - is base.img, copied and modified

then:

  qemu-img diff -b base.img modified.img diff.qcow2

creates 'diff.qcow2' which contains the differences between 'base.img'
and 'modified.img'.  Note that 'diff.qcow2' has 'base.img' as its
backing file.

Signed-off-by: Richard W.M. Jones 
Cc: Matthew Booth 
Cc: Pablo Iranzo Gómez 
Cc: Tomas Von Veschler 
---
 qemu-img-cmds.hx |6 ++
 qemu-img.c   |  166 ++
 qemu-img.texi|   22 
 3 files changed, 194 insertions(+)

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 49dce7c..00eef96 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -33,6 +33,12 @@ STEXI
 @item convert [-c] [-p] [-f @var{fmt}] [-t @var{cache}] [-O @var{output_fmt}] 
[-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] 
@var{filename} [@var{filename2} [...]] @var{output_filename}
 ETEXI
 
+DEF("diff", img_diff,
+"diff [-F backing_fmt] -b backing_file [-f fmt] [-O output_fmt] [-o 
options] filename output_filename")
+STEXI
+@item diff [-F @var{backing_fmt}] -b @var{backing_file} [-f @var{fmt}] [-O 
@var{output_fmt}] [-o @var{options}] @var{filename} @var{output_filename}
+ETEXI
+
 DEF("info", img_info,
 "info [-f fmt] filename")
 STEXI
diff --git a/qemu-img.c b/qemu-img.c
index c8a70ff..af12c29 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -1533,6 +1533,172 @@ out:
 return 0;
 }
 
+static int img_diff(int argc, char **argv)
+{
+/* qemu-img diff -b base modified out */
+BlockDriverState *bs_base, *bs_modified, *bs_out;
+const char *fmt_base, *base,
+*fmt_modified, *modified,
+*fmt_out, *out;
+char *options;
+int c, ret = 0;
+uint64_t num_sectors_base, num_sectors_modified;
+uint64_t sector;
+int n;
+uint8_t *buf_base;
+uint8_t *buf_modified;
+
+/* Parse commandline parameters */
+fmt_base = NULL;
+fmt_modified = NULL;
+fmt_out = NULL;
+base = NULL;
+options = NULL;
+for(;;) {
+c = getopt(argc, argv, "b:hf:F:O:o:");
+if (c == -1) {
+break;
+}
+switch(c) {
+case '?':
+case 'h':
+help();
+return 0;
+case 'f':
+fmt_modified = optarg;
+break;
+case 'F':
+fmt_base = optarg;
+break;
+case 'b':
+base = optarg;
+break;
+case 'O':
+fmt_out = optarg;
+break;
+case 'o':
+options = optarg;
+break;
+}
+}
+
+if (base == NULL) {
+error_report("The -b (backing filename) option must be supplied");
+return 1;
+}
+
+if (argc - optind != 2) {
+error_report("Exactly two filenames (source and destination) must be 
supplied");
+return 1;
+}
+modified = argv[optind++];
+out = argv[optind++];
+
+if (fmt_out == NULL || fmt_out[0] == '\0') {
+fmt_out = "qcow2";
+}
+
+if (options && !strcmp(options, "?")) {
+ret = print_block_option_help(out, fmt_out);
+return 1;
+}
+
+/* Open the input images. */
+bs_base = bdrv_new_open(base, fmt_base, BDRV_O_FLAGS);
+if (!bs_base) {
+return 1;
+}
+
+bs_modified = bdrv_new_open(modified, fmt_modified, BDRV_O_FLAGS);
+if (!bs_modified) {
+return 1;
+}
+
+bdrv_get_geometry(bs_base, &num_sectors_base);
+bdrv_get_geometry(bs_modified, &num_sectors_modified);
+/* NB: It is possible to relax this constraint so that
+ * num_sectors_base <= num_sectors_modified, ie. the modified disk
+ * has been expanded.  That requires changes to the loop below.
+ */
+if (num_sectors_base != num_sectors_modified) {
+error_report("Number of sectors in backing and source must be the 
same");
+goto out2;
+}
+
+/* Output image. */
+ret = bdrv_img_create(out, fmt_out,
+  /* base file becomes the new backing file */
+  base, fmt_base,
+  options, num_sectors_modified * BDRV_SECTOR_SIZE,
+  BDRV_O_FLAGS);
+if (ret != 0) {
+goto out2;
+}
+bs_out = bdrv_new_open(out, fmt_out, BDRV_O_RDWR);
+
+buf_base = qemu_blockalign(bs_base, IO_BUF_SIZE);
+buf_modified = qemu_blockalign(bs_modified, IO_BUF_SIZE);
+
+for (sector = 0; sector < num_sectors_modified; sector += n) {
+/* How many sectors can we handle with the next read? */
+if (sector + (IO_BUF_SIZE / BDRV_SECTOR_SIZE) <= num_sectors_modified) 
{
+n = IO_BUF_SIZE / BDRV_SECTOR_SIZE;
+} else {
+n = num_sectors_modified - sector;
+}
+
+/* Read input files and compare. */
+ret = bd

[Qemu-devel] qxl performance problems and spice issues

2012-05-17 Thread heliman
Hello,

I am testing Xen 4.2 (unstable) with Qemu 1.1rc2 and spice.
I have severe video performance problems on Windows 7 guest and X fails to run 
on
Debian wheezy and Ubuntu Precise guest.
The problem may be related to Xen and I'm asking there too, but I want to make
sure my invocation is correct as far as Qemu is concerned.

If someone is experimenting with spice and has qxl video, vdagent, audio and usb
redirection working, can you post your Qemu and SeaBIOS version and exact Qemu
invocation, so that I can try to replicate your results.

Are qxl and other spice features dependent on kvm in some way?
Should I use -vga qxl or -device qxl-vga?

Thanks,
LG

Here is Qemu invocation by xl:
--
libxl: debug: libxl_dm.c:1001:libxl__spawn_local_dm: Spawning device-model /usr/
lib/xen/bin/qemu-system-i386 with arguments:
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:  
/usr/lib/xen/bin/qemu-system-i386
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:   -xen-domid
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:   8
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:   -chardev
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:  
socket,id=libxl-cmd,path=/var/run/xen/qmp-libxl-8,server,nowait
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:   -mon
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:   
chardev=libxl-cmd,mode=control
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:   -name
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:   W7
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:   -spice
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:  
port=6000,tls-port=0,addr=0.0.0.0,disable-ticketing,agent-mouse=on
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:   -boot
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:   order=cd
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:   -smp
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:   2,maxcpus=3
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:   -device
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:  
rtl8139,id=nic0,netdev=net0,mac=00:16:3e:6b:1f:d9
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:   -netdev
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:  
type=tap,id=net0,ifname=vif8.0-emu,script=no,downscript=no
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:   -device
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:   qxl-vga
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:   -global
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:   
qxl-vga.vram_size=33554432
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:   -global
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:   qxl-vga.ram_size=33554432
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:   -device
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:  
virtio-serial-pci,id=virtio-serial0,max_ports=16
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:   -chardev
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:  
spicevmc,name=vdagent,id=vdagent
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:   -device
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:  
virtserialport,nr=1,bus=virtio-serial0.0,chardev=vdagent,name=com.redhat.spice.0
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:   -M
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:   xenfv
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:   -m
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:   1792
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:   -drive
libxl: debug: libxl_dm.c:1003:libxl__spawn_local_dm:  
file=/mnt/vm/disks/W7.disk1.xm,if=ide,index=0,media=disk,format=raw

-- 

 Nuova grafica e nuove funzionalità! Crea subito Gratis la tua nuova 
Casella di Posta  Katamail



Re: [Qemu-devel] [PATCH v3] qemu-img: Implement 'diff' operation.

2012-05-17 Thread Eric Blake
On 05/17/2012 09:34 AM, Richard W.M. Jones wrote:
> From: "Richard W.M. Jones" 
> 
> This produces a qcow2 file which is the difference between
> two disk images.  ie, if:
> 
>   base.img - is a disk image (in any format)
>   modified.img - is base.img, copied and modified
> 
> then:
> 
>   qemu-img diff -b base.img modified.img diff.qcow2
> 
> creates 'diff.qcow2' which contains the differences between 'base.img'
> and 'modified.img'.  Note that 'diff.qcow2' has 'base.img' as its
> backing file.
> 
> Signed-off-by: Richard W.M. Jones 
> Cc: Matthew Booth 
> Cc: Pablo Iranzo Gómez 
> Cc: Tomas Von Veschler 

Regarding the documentation and command overview:

Reviewed-by: Eric Blake 

Regarding the actual logic used in computing the diff, I did not closely
look at that, and you would be wise to get a review from someone more
familiar with block dev operations.

-- 
Eric Blake   ebl...@redhat.com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [QEMU 1.1 PATCH v2] Expose CPUID leaf 7 only for -cpu host

2012-05-17 Thread Eduardo Habkost
Changes v1 -> v2:
  - Use kvm_arch_get_supported_cpuid() instead of host_cpuid() on
cpu_x86_fill_host().

  We should use GET_SUPPORTED_CPUID for all bits on "-cpu host"
  eventually, but I am not changing all the other CPUID leaves because
  we may not be able to test such an intrusive change in time for 1.1.

Description of the bug:

Since QEMU 0.15, the CPUID information on CPUID[EAX=7,ECX=0] is being
returned unfiltered to the guest, directly from the GET_SUPPORTED_CPUID
return value.

The problem is that this makes the resulting CPU feature flags
unpredictable and dependent on the host CPU and kernel version. This
breaks live-migration badly if migrating from a host CPU that supports
some features on that CPUID leaf (running a recent kenrel) to a kernel
or host CPU that doesn't support it.

Migration also is incorrect (the virtual CPU changes under the guest's
feet) if you migrate in the opposite direction (from an old CPU/kernel
to a new CPU/kernel), but with less serious consequences (guests
normally query CPUID information only once on boot).

Fortunately, the bug affects only users using cpudefs with level >= 7.

The right behavior should be to explicitly enable those features on
[cpudef] config sections or on the "-cpu" command-line arguments. Right
now there is no predefined CPU model on QEMU that has those features:
the latest Intel model we have is Sandy Bridge.

I would like to get this fixed on 1.1, so I am submitting this patch,
that enables those features only if "-cpu host" is being used (as we
don't have any pre-defined CPU model that actually have those features).
After 1.1 is released, we can make those features properly configurable
on [cpudef] and -cpu configuration.

One problem is: with this patch, users with the following setup:
- Running QEMU 1.0;
- Using a cpudef having level >= 7;
- Running a kernel that supports the features on CPUID leaf 7; and
- Running on a CPU that supports some features on CPUID leaf 7
won't be able to live-migrate to QEMU 1.1. But for these users
live-migration is already broken (they can't live-migrate to hosts with
older CPUs or older kernels, already), I don't see how to avoid this
problem.

Signed-off-by: Eduardo Habkost 
---
 target-i386/cpu.c |   22 +++---
 target-i386/cpu.h |2 ++
 2 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 89b4ac7..957173b 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -238,6 +238,8 @@ typedef struct x86_def_t {
 /* Store the results of Centaur's CPUID instructions */
 uint32_t ext4_features;
 uint32_t xlevel2;
+/* The feature bits on CPUID[EAX=7,ECX=0].EBX */
+uint32_t cpuid_7_0_ebx_features;
 } x86_def_t;
 
 #define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
@@ -521,6 +523,12 @@ static int cpu_x86_fill_host(x86_def_t *x86_cpu_def)
 x86_cpu_def->ext_features = ecx;
 x86_cpu_def->features = edx;
 
+if (x86_cpu_def->level >= 7) {
+x86_cpu_def->cpuid_7_0_ebx_features = 
kvm_arch_get_supported_cpuid(kvm_state, 0x7, 0, R_EBX);
+} else {
+x86_cpu_def->cpuid_7_0_ebx_features = 0;
+}
+
 host_cpuid(0x8000, 0, &eax, &ebx, &ecx, &edx);
 x86_cpu_def->xlevel = eax;
 
@@ -1185,6 +1193,7 @@ int cpu_x86_register(X86CPU *cpu, const char *cpu_model)
 env->cpuid_kvm_features = def->kvm_features;
 env->cpuid_svm_features = def->svm_features;
 env->cpuid_ext4_features = def->ext4_features;
+env->cpuid_7_0_ebx = def->cpuid_7_0_ebx_features;
 env->cpuid_xlevel2 = def->xlevel2;
 object_property_set_int(OBJECT(cpu), (int64_t)def->tsc_khz * 1000,
 "tsc-frequency", &error);
@@ -1451,13 +1460,12 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
uint32_t count,
 *edx = 0;
 break;
 case 7:
-if (kvm_enabled()) {
-KVMState *s = env->kvm_state;
-
-*eax = kvm_arch_get_supported_cpuid(s, 0x7, count, R_EAX);
-*ebx = kvm_arch_get_supported_cpuid(s, 0x7, count, R_EBX);
-*ecx = kvm_arch_get_supported_cpuid(s, 0x7, count, R_ECX);
-*edx = kvm_arch_get_supported_cpuid(s, 0x7, count, R_EDX);
+/* Structured Extended Feature Flags Enumeration Leaf */
+if (count == 0) {
+*eax = 0; /* Maximum ECX value for sub-leaves */
+*ebx = env->cpuid_7_0_ebx; /* Feature flags */
+*ecx = 0; /* Reserved */
+*edx = 0; /* Reserved */
 } else {
 *eax = 0;
 *ebx = 0;
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index b5b9a50..2460f63 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -741,6 +741,8 @@ typedef struct CPUX86State {
 /* Store the results of Centaur's CPUID instructions */
 uint32_t cpuid_xlevel2;
 uint32_t cpuid_ext4_features;
+/* Flags from CPUID[EAX=7,ECX=0].EBX */
+uint32_t cpuid_7_0_ebx;
 
 /* MTRRs */
 uint64_t mtrr_fixed[11

Re: [Qemu-devel] [PULL 1.1] Xen fixes for 1.1

2012-05-17 Thread Stefano Stabellini
On Tue, 15 May 2012, Stefano Stabellini wrote:
> Hi Anthony,
> please pull:
> 
> git://xenbits.xen.org/people/sstabellini/qemu-dm.git for_1.1
> 
> 
> it contains 3 fixes to xen_disk and 2 patches to disable rtc_clock,
> the PIT and PCSPK on Xen:
> 
> 
> Jan Beulich (1):
>   xen_disk: properly update stats in ioreq_release()
> 
> Stefano Stabellini (4):
>   xen: do not initialize the interval timer and PCSPK emulator
>   xen: disable rtc_clock
>   xen_disk: remove syncwrite option
>   xen_disk: use bdrv_aio_flush instead of bdrv_flush
> 
>  hw/pc.c   |   23 +--
>  hw/xen_disk.c |   42 +++---
>  xen-all.c |4 
>  3 files changed, 44 insertions(+), 25 deletions(-)

I am about to send another PULL request that contains these changes plus
two other fixes, so you can skip this one.



[Qemu-devel] [PULL 1.1] Xen fixes for 1.1-rc3

2012-05-17 Thread Stefano Stabellini
Hi Anthony,
please pull:

git://xenbits.xen.org/people/sstabellini/qemu-dm.git for_1.1_rc3



Anthony PERARD (1):
  xen: Fix PV-on-HVM

Jan Beulich (1):
  xen_disk: properly update stats in ioreq_release()

John V. Baboval (1):
  Call xc_domain_shutdown with the reboot flag when the guest requests a 
reboot.

Stefano Stabellini (4):
  xen: do not initialize the interval timer and PCSPK emulator
  xen: disable rtc_clock
  xen_disk: remove syncwrite option
  xen_disk: use bdrv_aio_flush instead of bdrv_flush

 hw/pc.c   |   23 +--
 hw/xen_common.h   |2 +-
 hw/xen_disk.c |   42 +++---
 hw/xen_platform.c |5 -
 xen-all.c |   22 +++---
 5 files changed, 60 insertions(+), 34 deletions(-)


Cheers,

Stefano



Re: [Qemu-devel] [QEMU 1.1 PATCH v2] Expose CPUID leaf 7 only for -cpu host

2012-05-17 Thread Eric Blake
On 05/17/2012 10:26 AM, Eduardo Habkost wrote:

> The problem is that this makes the resulting CPU feature flags
> unpredictable and dependent on the host CPU and kernel version. This
> breaks live-migration badly if migrating from a host CPU that supports
> some features on that CPUID leaf (running a recent kenrel) to a kernel

s/kenrel/kernel/

-- 
Eric Blake   ebl...@redhat.com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


  1   2   >