Re: [Qemu-devel] buildbot failure in qemu on pci_x86_64_debian_5_0

2011-07-05 Thread Stefan Hajnoczi
On Tue, Jul 5, 2011 at 3:04 AM,  q...@buildbot.b1-systems.de wrote:
 The Buildbot has detected a new failure on builder pci_x86_64_debian_5_0 
 while building qemu.
 Full details are available at:
  http://buildbot.b1-systems.de/qemu/builders/pci_x86_64_debian_5_0/builds/24

 Buildbot URL: http://buildbot.b1-systems.de/qemu/

 Buildslave for this Build: b1_qemu_1

I haven't investigated but perhaps this is because b1_qemu_1 is
running Debian lenny:
http://buildbot.b1-systems.de/qemu/builders/pci_x86_64_debian_5_0/builds/24/steps/compile/logs/stdio

I vaguely remember that eventfd EFD_NONBLOCK and EFD_CLOEXEC were
added to eventfd later.  Originally you had to use the regular
fcntl(2) calls (which means there was a window of time where
close-on-exec was missing).

Stefan



Re: [Qemu-devel] [PATCH 3/3] Avoid Wunsed-but-set warnings (or errors in case of Werror)

2011-07-05 Thread Markus Armbruster
Typo in subject: unsed.  The warning is spelled
unused-but-set-variable, the option -Wunused-but-set-variable.

Raghavendra D Prabhu raghu.prabh...@gmail.com writes:

 In a few cases, variable attributed 'unused' has been added, in other cases
 unused variable has been either removed or commented out.

 Signed-off-by: Raghavendra D Prabhu rpra...@wnohang.net
 ---
  hw/device-assignment.c |6 +++---
  simpletrace.c  |2 +-
  xen-mapcache.c |7 ++-
  3 files changed, 6 insertions(+), 9 deletions(-)

 diff --git a/hw/device-assignment.c b/hw/device-assignment.c
 index 36ad6b0..19a59b4 100644
 --- a/hw/device-assignment.c
 +++ b/hw/device-assignment.c
 @@ -1654,7 +1654,7 @@ static void reset_assigned_device(DeviceState *dev)
  AssignedDevice *adev = DO_UPCAST(AssignedDevice, dev, pci_dev);
  char reset_file[64];
  const char reset[] = 1;
 -int fd, ret;
 +int fd, __attribute__((unused)) ret;
  
  snprintf(reset_file, sizeof(reset_file),
   /sys/bus/pci/devices/%04x:%02x:%02x.%01x/reset,

What about (void)write() and do away with ret?

 @@ -1682,7 +1682,7 @@ static void reset_assigned_device(DeviceState *dev)
  static int assigned_initfn(struct PCIDevice *pci_dev)
  {
  AssignedDevice *dev = DO_UPCAST(AssignedDevice, dev, pci_dev);
 -uint8_t e_device, e_intx;
 +uint8_t e_intx;
  int r;
  
  if (!kvm_enabled()) {
 @@ -1709,7 +1709,7 @@ static int assigned_initfn(struct PCIDevice *pci_dev)
  goto out;
  
  /* handle interrupt routing */
 -e_device = (dev-dev.devfn  3)  0x1f;
 +/*e_device = (dev-dev.devfn  3)  0x1f;*/
  e_intx = dev-dev.config[0x3d] - 1;
  dev-intpin = e_intx;
  dev-run = 0;
 diff --git a/simpletrace.c b/simpletrace.c
 index f1dbb5e..2ce9cff 100644
 --- a/simpletrace.c
 +++ b/simpletrace.c
 @@ -119,7 +119,7 @@ static void *writeout_thread(void *opaque)
  TraceRecord record;
  unsigned int writeout_idx = 0;
  unsigned int num_available, idx;
 -size_t unused;
 +size_t __attribute__((unused)) unused;
  
  for (;;) {
  wait_for_trace_records_available();

Same here.

[...]



Re: [Qemu-devel] [PATCH 3/3] Avoid Wunsed-but-set warnings (or errors in case of Werror)

2011-07-05 Thread Peter Maydell
On 5 July 2011 07:15, Markus Armbruster arm...@redhat.com wrote:
 +    int fd, __attribute__((unused)) ret;

      snprintf(reset_file, sizeof(reset_file),
               /sys/bus/pci/devices/%04x:%02x:%02x.%01x/reset,

 What about (void)write() and do away with ret?

If 'ret' has been used to silence compiler warnings about functions
which have been declared with attribute __warn_unused_result__
(eg write() and various other libc functions) then (void)write()
is insufficient -- gcc requires the variable.

-- PMM



Re: [Qemu-devel] [PATCH 1/2] ide: Ignore reads during PIO in and writes during PIO out

2011-07-05 Thread Markus Armbruster
I got confused by PIO out until it dawned on me that it's from the
device's point of view, i.e. out means device - cpu, not the CPU's out
instruction.

Both patches

Reviewed-by: Markus Armbruster arm...@redhat.com



Re: [Qemu-devel] PCI: how handle multifunction / compound devices best?

2011-07-05 Thread Gerd Hoffmann

  Hi,


Device macros destroy the 1:1 relationship between -device and device
tree nodes.  Or rather what's left of it: we already have a device that
expands into multiple devices, namely usb-storage.  But it's an ad hoc
hack, which has caused us some grief.


Exactly thats why I don't feel like adding more ad hoc hacks ...

cheers,
  Gerd



Re: [Qemu-devel] [PATCH 3/3] Avoid Wunsed-but-set warnings (or errors in case of Werror)

2011-07-05 Thread Markus Armbruster
Peter Maydell peter.mayd...@linaro.org writes:

 On 5 July 2011 07:15, Markus Armbruster arm...@redhat.com wrote:
 +    int fd, __attribute__((unused)) ret;

      snprintf(reset_file, sizeof(reset_file),
               /sys/bus/pci/devices/%04x:%02x:%02x.%01x/reset,

 What about (void)write() and do away with ret?

 If 'ret' has been used to silence compiler warnings about functions
 which have been declared with attribute __warn_unused_result__
 (eg write() and various other libc functions) then (void)write()
 is insufficient -- gcc requires the variable.

gcc being silly.  Oh well.



Re: [Qemu-devel] KVM call agenda for June 28

2011-07-05 Thread Dor Laor
I tried to re-arrange all of the requirements and use cases using this 
wiki page: http://wiki.qemu.org/Features/LiveBlockMigration


It would be the best to agree upon the most interesting use cases (while 
we make sure we cover future ones) and agree to them.
The next step is to set the interface for all the various verbs since 
the implementation seems to be converging.


Cheers,
Dor

On 06/30/2011 09:38 PM, Marcelo Tosatti wrote:

On Thu, Jun 30, 2011 at 04:52:00PM +0200, Kevin Wolf wrote:

Am 30.06.2011 16:36, schrieb Marcelo Tosatti:

4. Live block copy API and high-level control - the main code that
adds the live block copy feature.  Existing patches by Marcelo, can be
restructured to use common core by Marcelo.


Can use your proposed block_stream interface, with a block_switch
command on top, so:

1) management creates copy.img with backing file current.img, allows
access
2) management issues block_switch dev copy.img
3) management issues block_stream dev base


Isn't this block_switch command the same as the existing snapshot_blkdev?


Yep.


Thought of implementing block_stream command by reopening device with

blkstream:imagename.img

Then:

AIO_READ:
- for each cluster in request:
 - if allocated-or-in-final-base, read.
 - check write queue, if present wait on it, if not, add copy
   entry to write queue.
 - issue cluster sized read from source.
 - on completion:
 - copy data to original read buffer, complete it.
 - if not cancelled, write cluster to destination.

AIO_WRITE
for each cluster in request:
 - check write queue, cancel/wait for copy entry.
 - add guest entry to write queue.
 - issue write to destination.
 - on completion:
 - remove write queue entry.


With the 0...END background read, once it completes write final base
file for image.

So block_stream/block_stream_cancel/block_stream_status commands, the
background read and the rebase -u update can be separate from the block
driver.


The way how it works looks good to me, I'm just not entirely sure about
the right place to implement it. I think request queueing and copy on
read could be useful outside blkstream, too.


They could be lifted later, when there are other users.

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html





Re: [Qemu-devel] [PATCH 3/3] Avoid Wunsed-but-set warnings (or errors in case of Werror)

2011-07-05 Thread Paolo Bonzini

On 07/05/2011 09:49 AM, Markus Armbruster wrote:

  If 'ret' has been used to silence compiler warnings about functions
  which have been declared with attribute __warn_unused_result__
  (eg write() and various other libc functions) then (void)write()
  is insufficient -- gcc requires the variable.

gcc being silly.  Oh well.


In this particular case I think that the return value should be checked. 
 It's good if something is printed in the log saying that the reset 
wasn't done for some reason---even if it is just defensive.


The really silly thing is in glibc, not gcc.  __warn_unused_result__ was 
added to fwrite, where you have no certainty that the write has been 
done, but not to either fclose or fflush.  Oh well...


Paolo



[Qemu-devel] [PATCH 1/3] linux-user:Support for MIPS64 user mode emulation in QEMU

2011-07-05 Thread khansa
From: Khansa Butt kha...@kics.edu.pk


Signed-off-by: Khansa Butt kha...@kics.edu.pk
---
 configure |1 +
 default-configs/mips64-linux-user.mak |1 +
 linux-user/main.c |   21 +++--
 linux-user/mips64/syscall.h   |2 ++
 linux-user/signal.c   |4 ++--
 linux-user/syscall.c  |5 +
 6 files changed, 30 insertions(+), 4 deletions(-)
 create mode 100644 default-configs/mips64-linux-user.mak

diff --git a/configure b/configure
index 88159ac..ad4c321 100755
--- a/configure
+++ b/configure
@@ -866,6 +866,7 @@ m68k-linux-user \
 microblaze-linux-user \
 microblazeel-linux-user \
 mips-linux-user \
+mips64-linux-user \
 mipsel-linux-user \
 ppc-linux-user \
 ppc64-linux-user \
diff --git a/default-configs/mips64-linux-user.mak 
b/default-configs/mips64-linux-user.mak
new file mode 100644
index 000..1598bfc
--- /dev/null
+++ b/default-configs/mips64-linux-user.mak
@@ -0,0 +1 @@
+# Default configuration for mips64-linux-user
diff --git a/linux-user/main.c b/linux-user/main.c
index 289054b..a3ed752 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -2041,7 +2041,8 @@ static int do_store_exclusive(CPUMIPSState *env)
 void cpu_loop(CPUMIPSState *env)
 {
 target_siginfo_t info;
-int trapnr, ret;
+int trapnr;
+abi_long ret;
 unsigned int syscall_num;
 
 for(;;) {
@@ -2050,8 +2051,23 @@ void cpu_loop(CPUMIPSState *env)
 cpu_exec_end(env);
 switch(trapnr) {
 case EXCP_SYSCALL:
-syscall_num = env-active_tc.gpr[2] - 4000;
 env-active_tc.PC += 4;
+#if defined(TARGET_MIPS64)
+syscall_num = env-active_tc.gpr[2] - 5000;
+/* MIPS64 has eight argument registers so there is
+ * no need to get arguments from stack
+ */
+ret = do_syscall(env, env-active_tc.gpr[2],
+ env-active_tc.gpr[4],
+ env-active_tc.gpr[5],
+ env-active_tc.gpr[6],
+ env-active_tc.gpr[7],
+ env-active_tc.gpr[8],
+ env-active_tc.gpr[9],
+ env-active_tc.gpr[10],
+ env-active_tc.gpr[11]);
+#else
+syscall_num = env-active_tc.gpr[2] - 4000;
 if (syscall_num = sizeof(mips_syscall_args)) {
 ret = -ENOSYS;
 } else {
@@ -2078,6 +2094,7 @@ void cpu_loop(CPUMIPSState *env)
  env-active_tc.gpr[7],
  arg5, arg6, arg7, arg8);
 }
+#endif
 if (ret == -TARGET_QEMU_ESIGRETURN) {
 /* Returning from a successful sigreturn syscall.
Avoid clobbering register state.  */
diff --git a/linux-user/mips64/syscall.h b/linux-user/mips64/syscall.h
index 668a2b9..96f03da 100644
--- a/linux-user/mips64/syscall.h
+++ b/linux-user/mips64/syscall.h
@@ -218,4 +218,6 @@ struct target_pt_regs {
 
 
 
+#define TARGET_QEMU_ESIGRETURN 255
+
 #define UNAME_MACHINE mips64
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 7d168e1..48a22e0 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -2414,8 +2414,8 @@ void sparc64_get_context(CPUSPARCState *env)
 }
 #endif
 #elif defined(TARGET_ABI_MIPSN64)
-
-# warning signal handling not implemented
+/* Signal handling will be Implemented soon
+# warning signal handling not implemented */
 
 static void setup_frame(int sig, struct target_sigaction *ka,
target_sigset_t *set, CPUState *env)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index fed7a8f..339dede 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -7584,6 +7584,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long 
arg1,
 case TARGET_NR_set_thread_area:
 #if defined(TARGET_MIPS)
   ((CPUMIPSState *) cpu_env)-tls_value = arg1;
+  if (((CPUMIPSState *) cpu_env)-insn_flags  CPU_OCTEON) {
+  /* tls entry is moved to k0 so that this can be used later
+ currently this thing is tested only for Octeon */
+  ((CPUMIPSState *) cpu_env)-active_tc.gpr[26] = arg1;
+  }
   ret = 0;
   break;
 #elif defined(TARGET_CRIS)
-- 
1.7.3.4




[Qemu-devel] [PATCH 0/3] MIPS64 user mode emulation in QEMU with Cavium specific instruction support

2011-07-05 Thread khansa
From: Khansa Butt kha...@kics.edu.pk

This is the team work of Ehsan-ul-Haq, Abdul Qadeer, Abdul Waheed, Khansa Butt 
from HPCN Lab KICS UET Lahore. 
 
Cavium Networks's Octeon processors are based on MIPS64r2 
We have Implemented 27 user mode Cavium specific instructions. 
Richard Henderson told me that QEMU does not support 64-bit 
address spaces in user mode from a 32-bit host. so this code will work 
only on  64 bit host. Although we did some workaround to run MIPS64 on 32 x86
and it can be generlized for other architectures. We will submit that after 
this 
submission. This development work is tested for 64 bit X86 and working fine 
all Cavium specific instructions are also tested. teast cases can be provided 
if required.
Octeon binaries (ELF) can be downloaded from below links
1)http://dl.dropbox.com/u/19530066/hw_mips
2)http://dl.dropbox.com/u/19530066/matmul   
If you have any objection regarding the Implementation of 
Cavium instructions please read following notes. 

Notes 
* 

The detail of some instructions are as follows 
1)seq rd,rs,rt 
seq--rd = 1 if rs = rt 
is equivalent to 
xor rd,rs,rt 
sltiu rd,rd,1 
2)exts rt,rs,p,lenm1 
rt = sign-extend(rsp+lenm1:p,lenm1) 
From reference manual of Cavium Networks 
Bit locations p + lenm1 to p are extracted from rs and the result is written 
into the 
lowest bits of destination register rt. The remaining bits in rt are a 
sign-extension of 
the most-significant bit of the bit field (i.e. rt63:lenm1 are all duplicates 
of the 
source-register bit rsp+lenm1). so we can't use any of 8,16 or 32 bit 
sign extention tcg function. To sign extend according to msb of bit field 
we have our own implementation
3)dmul rd,rs,rt 
This instruction is included in gen_arith() because it is three operand 
double word multiply instruction.

-- 
1.7.3.4




[Qemu-devel] [PATCH 2/3] target-mips:Adding Octeon cpu definitions

2011-07-05 Thread khansa
From: Khansa Butt kha...@kics.edu.pk


Signed-off-by: Khansa Butt kha...@kics.edu.pk
---
 target-mips/mips-defs.h  |2 ++
 target-mips/translate.c  |1 +
 target-mips/translate_init.c |   24 
 3 files changed, 27 insertions(+), 0 deletions(-)

diff --git a/target-mips/mips-defs.h b/target-mips/mips-defs.h
index bf094a3..6fec935 100644
--- a/target-mips/mips-defs.h
+++ b/target-mips/mips-defs.h
@@ -44,6 +44,7 @@
 #defineINSN_LOONGSON2E  0x2000
 #defineINSN_LOONGSON2F  0x4000
 #defineINSN_VR54XX 0x8000
+#define INSN_OCTEON 0x1000
 
 /* MIPS CPU defines. */
 #defineCPU_MIPS1   (ISA_MIPS1)
@@ -53,6 +54,7 @@
 #defineCPU_VR54XX  (CPU_MIPS4 | INSN_VR54XX)
 #defineCPU_LOONGSON2E  (CPU_MIPS3 | INSN_LOONGSON2E)
 #defineCPU_LOONGSON2F  (CPU_MIPS3 | INSN_LOONGSON2F)
+#define CPU_OCTEON  (CPU_MIPS64R2 | INSN_OCTEON)
 
 #defineCPU_MIPS5   (CPU_MIPS4 | ISA_MIPS5)
 
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 2848c6a..eb108bc 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -12693,6 +12693,7 @@ void cpu_reset (CPUMIPSState *env)
 env-hflags |= MIPS_HFLAG_FPU;
 }
 #ifdef TARGET_MIPS64
+env-hflags |=  MIPS_HFLAG_UX;
 if (env-active_fpu.fcr0  (1  FCR0_F64)) {
 env-hflags |= MIPS_HFLAG_F64;
 }
diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c
index d55c522..7d7e1e9 100644
--- a/target-mips/translate_init.c
+++ b/target-mips/translate_init.c
@@ -451,6 +451,30 @@ static const mips_def_t mips_defs[] =
 .mmu_type = MMU_TYPE_R4000,
 },
 {
+.name = octeon,
+.CP0_PRid = 0x0d30,
+.CP0_Config0 = MIPS_CONFIG0 | (0x1  CP0C0_AR) | (0x2  CP0C0_AT) |
+   (MMU_TYPE_R4000  CP0C0_MT),
+.CP0_Config1 = MIPS_CONFIG1 | (63  CP0C1_MMU) |
+   (2  CP0C1_IS) | (4  CP0C1_IL) | (3  CP0C1_IA) |
+   (2  CP0C1_DS) | (4  CP0C1_DL) | (3  CP0C1_DA) |
+   (1  CP0C1_PC) | (1  CP0C1_WR) | (1  CP0C1_EP),
+.CP0_Config2 = MIPS_CONFIG2,
+.CP0_Config3 = MIPS_CONFIG3 | (1  CP0C3_LPA),
+.CP0_LLAddr_rw_bitmask = 0,
+.CP0_LLAddr_shift = 0,
+.SYNCI_Step = 32,
+.CCRes = 2,
+.CP0_Status_rw_bitmask = 0x36FB,
+.CP1_fcr0 = (1  FCR0_F64) | (1  FCR0_3D) | (1  FCR0_PS) |
+(1  FCR0_L) | (1  FCR0_W) | (1  FCR0_D) |
+(1  FCR0_S) | (0x00  FCR0_PRID) | (0x0  FCR0_REV),
+.SEGBITS = 49,
+.PABITS = 49,
+.insn_flags = CPU_OCTEON | ASE_MIPS3D,
+.mmu_type = MMU_TYPE_R4000,
+},
+{
 .name = Loongson-2E,
 .CP0_PRid = 0x6302,
 /*64KB I-cache and d-cache. 4 way with 32 bit cache line size*/
-- 
1.7.3.4




[Qemu-devel] [PATCH 3/3] target-mips:Support for Cavium specific instructions

2011-07-05 Thread khansa
From: Ehsan-ul-Haq, Abdul Qadeer, Abdul Waheed, Khansa Butt kha...@kics.edu.pk


Signed-off-by: Khansa Butt kha...@kics.edu.pk
---
 host-utils.c|1 +
 target-mips/cpu.h   |7 +
 target-mips/helper.h|5 +
 target-mips/op_helper.c |   67 +++
 target-mips/translate.c |  443 ++-
 5 files changed, 514 insertions(+), 9 deletions(-)

diff --git a/host-utils.c b/host-utils.c
index dc96123..1128698 100644
--- a/host-utils.c
+++ b/host-utils.c
@@ -102,4 +102,5 @@ void muls64 (uint64_t *plow, uint64_t *phigh, int64_t a, 
int64_t b)
a, b, *phigh, *plow);
 #endif
 }
+
 #endif /* !defined(__x86_64__) */
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index b0ac4da..8e75e9b 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -171,6 +171,13 @@ struct TCState {
 target_ulong CP0_TCSchedule;
 target_ulong CP0_TCScheFBack;
 int32_t CP0_Debug_tcstatus;
+/* Multiplier registers for Octeon */
+target_ulong MPL0;
+target_ulong MPL1;
+target_ulong MPL2;
+target_ulong P0;
+target_ulong P1;
+target_ulong P2;
 };
 
 typedef struct CPUMIPSState CPUMIPSState;
diff --git a/target-mips/helper.h b/target-mips/helper.h
index 297ab64..e892d39 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -8,7 +8,12 @@ DEF_HELPER_3(ldl, tl, tl, tl, int)
 DEF_HELPER_3(ldr, tl, tl, tl, int)
 DEF_HELPER_3(sdl, void, tl, tl, int)
 DEF_HELPER_3(sdr, void, tl, tl, int)
+DEF_HELPER_2(v3mulu, tl, tl, tl)
+DEF_HELPER_2(vmulu, tl, tl, tl)
+DEF_HELPER_1(dpop, tl, tl)
 #endif
+DEF_HELPER_1(pop, tl, tl);
+
 DEF_HELPER_3(lwl, tl, tl, tl, int)
 DEF_HELPER_3(lwr, tl, tl, tl, int)
 DEF_HELPER_3(swl, void, tl, tl, int)
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 6b966b1..a1893d1 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -266,7 +266,74 @@ void helper_dmultu (target_ulong arg1, target_ulong arg2)
 {
 mulu64((env-active_tc.LO[0]), (env-active_tc.HI[0]), arg1, arg2);
 }
+static void addc(uint64_t res[], uint64_t a, int i)
+{
+uint64_t c = res[i];
+for (; i  4; i++) {
+res[i] = c + a;
+if (res[i]  a) {
+c = 1;
+a = res[i+1];
+} else
+  break;
+}
+}
+target_ulong helper_v3mulu(target_ulong arg1, target_ulong arg2)
+{
+uint64_t hi, lo, res[4];
+int i;
+for (i = 0; i  4; i++) {
+res[i] = 0;
+}
+mulu64(res[0], res[1], env-active_tc.MPL0, arg1);
+mulu64(lo, hi, env-active_tc.MPL1, arg1);
+res[1] = res[1] + lo;
+if (res[1]  lo) {
+res[2]++;
+}
+res[2] = res[2] + hi;
+if (res[2]  hi) {
+res[3]++;
+}
+mulu64(lo, hi, env-active_tc.MPL2, arg1);
+res[2] = res[2] + lo;
+if (res[2]  lo) {
+res[3]++;
+}
+res[3] = res[3] + hi;
+addc(res, arg2, 0);
+addc(res, env-active_tc.P0, 0);
+addc(res, env-active_tc.P1, 1);
+addc(res, env-active_tc.P2, 2);
+env-active_tc.P0 = res[1];
+env-active_tc.P1 = res[2];
+env-active_tc.P2 = res[3];
+return res[0];
+}
+target_ulong helper_vmulu(target_ulong arg1, target_ulong arg2)
+{
+uint64_t hi, lo;
+mulu64(lo, hi, env-active_tc.MPL0, arg1);
+lo = lo + arg2;
+if (lo  arg2) {
+hi++;
+}
+lo = lo + env-active_tc.P0;
+if (lo  env-active_tc.P0) {
+hi++;
+}
+env-active_tc.P0 = hi;
+return lo;
+}
+target_ulong helper_dpop(target_ulong arg)
+{
+return ctpop64(arg);
+}
 #endif
+target_ulong helper_pop(target_ulong arg)
+{
+return ctpop32((uint32_t)arg);
+}
 
 #ifndef CONFIG_USER_ONLY
 
diff --git a/target-mips/translate.c b/target-mips/translate.c
index eb108bc..b480665 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -69,6 +69,11 @@ enum {
 OPC_JAL  = (0x03  26),
 OPC_JALS = OPC_JAL | 0x5,
 OPC_BEQ  = (0x04  26),  /* Unconditional if rs = rt = 0 (B) */
+/* Cavium Specific */
+OPC_BBIT1= (0x3a  26),  /* jump on bit set, cavium specific */
+OPC_BBIT132  = (0x3e  26),  /* jump on bit set(for upper 32 bits) */
+OPC_BBIT0= (0x32  26),  /* jump on bit clear, cavium specific */
+OPC_BBIT032  = (0x36  26),  /* jump on bit clear(for upper 32 bits) */
 OPC_BEQL = (0x14  26),
 OPC_BNE  = (0x05  26),
 OPC_BNEL = (0x15  26),
@@ -264,6 +269,31 @@ enum {
 OPC_MADD = 0x00 | OPC_SPECIAL2,
 OPC_MADDU= 0x01 | OPC_SPECIAL2,
 OPC_MUL  = 0x02 | OPC_SPECIAL2,
+/* Cavium Specific Instructions */
+OPC_BADDU= 0x28 | OPC_SPECIAL2,
+OPC_DMUL = 0x03 | OPC_SPECIAL2,
+OPC_EXTS = 0x3a | OPC_SPECIAL2,
+OPC_EXTS32   = 0x3b | OPC_SPECIAL2,
+OPC_CINS = 0x32 | OPC_SPECIAL2,
+OPC_CINS32   = 0x33 | OPC_SPECIAL2,
+OPC_SEQI = 0x2e | OPC_SPECIAL2,
+OPC_SNEI = 0x2f | OPC_SPECIAL2,
+OPC_MTM0 = 0x08 | OPC_SPECIAL2,
+OPC_MTM1 = 0x0c | OPC_SPECIAL2,
+  

Re: [Qemu-devel] [PATCH 2/3] Add fno-strict-overflow

2011-07-05 Thread Stefan Hajnoczi
On Tue, Jul 5, 2011 at 6:41 AM, Stefan Hajnoczi stefa...@gmail.com wrote:
 On Mon, Jul 4, 2011 at 11:38 PM, Peter Maydell peter.mayd...@linaro.org 
 wrote:
 On 4 July 2011 23:00, Raghavendra D Prabhu raghu.prabh...@gmail.com wrote:
 This is to avoid gcc optimizating out the comparison in assert,
 due to assumption of signed overflow being undefined by default 
 (-Werror=strict-overflow).

--- a/Makefile.hw
+++ b/Makefile.hw
@@ -9,7 +9,7 @@ include $(SRC_PATH)/rules.mak

 $(call set-vpath, $(SRC_PATH):$(SRC_PATH)/hw)

 -QEMU_CFLAGS+=-I.. -I$(SRC_PATH)/fpu
 +QEMU_CFLAGS+=-I.. -I$(SRC_PATH)/fpu -fno-strict-overflow

 Can you give a more detailed description of the problem this is trying
 to solve? I think it would be nicer if we could remove the assumptions
 about signed overflows instead, if that's practical.

 (Also, if we do want to add this compiler flag then it ought to be
 done in configure I think, as we do for -fno-strict-aliasing.)

 a correct C/C++ program must never generate signed overflow when
 computing an expression. It also means that a compiler may assume that
 a program will never generated signed overflow.

 http://www.airs.com/blog/archives/120

You can check out the warnings that gcc raises with ./configure
--extra-cflags=-Wstrict-overflow -fstrict-overflow --disable-werror.

Either we'd have to fix the warnings or we could use
-fno-strict-overflow/-fwrapv.

This patch seems reasonable to me.  We're telling gcc not to take
advantage of the undefined behavior of signed overflow.  It also means
QEMU code is assuming two's complement representation and wrapping on
overflow, but that is a common assumption (what QEMU-capable hardware
doesn't?).

Reviewed-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com



[Qemu-devel] PATCH: fix qemu-mips[el]-static to work with debian squeeze/sid chroot

2011-07-05 Thread Wesley W. Terpstra
I also recently tried to get a mipsel debian/sid chroot running under my
amd64/squeeze system. As posted by Lisandro earlier this month, it didn't
work. ;-) There are several problems, the most glaring of which the attached
patch fixes. I'll break down the changes:

1. Return -TARGET_ENOSYS instead of -ENOSYS from linux-user/main.c
   * Caused the strange 'Level 2 synchronization messages' instead of
correctly reporting the syscall was missing.
   * Made glibc simply fail instead of using older syscalls (one important
example is the new setrlimit syscall which qemu lacks and gnupg/apt needs)

2. The mips syscall table wasn't kept in-sync with syscall.c
   * utimensat was missing (and the cause of the ENOSYS error Lisandro was
seeing)
   * Although I didn't run into problems with any other syscalls, I updated
the table to match syscall.c as well I could anyway

3. Dereferencing a null pointer causes an exception 0xC (EXCP_AdEL) instead
of EXCP_TLBL. This should also trigger a segfault.

4. The codes for get/setrlimit do not stay constant between linux target
platforms. I added a conversion method. This is important else programs
(rsyslog, python, ...) can go into a near infinite loop trying to close all
the file descriptors from 0 to -1.

5. 64-bit file system calls were failing on mipsel (ftruncate 888 created
files 888*4GB large). arm had already work-around code for EABI which also
worked for mipsel, so I just added the same code path for mips everywhere
arm eabi has it. Works for both little and big endian.

These changes were enough to get a mostly working debian chroot for me. I
did have to install squeeze first and then dist-upgrade to sid, however, as
debootstrap seems to have problems with the new multilib glibc (dist-upgrade
will install it fine, though).

To setup a mipsel chroot in /media with the patch applied:
apt-get install qemu-user-static binfmt-support debootstrap
debootstrap --foreign --arch=mipsel squeeze /media/mipsel-sid
compile qemu with patch
cp qemu-srcdir/mipsel-user-static /media/mipsel-sid/usr/bin
chroot /media/mipsel-sid
/debootstrap/debootstrap --second-stage
echo deb http://ftp.de.debian.org/debian sid main  /etc/apt/sources.list
apt-get update
apt-get install locales
mount devpts /dev/pts -t devpts
mount proc /proc -t proc
mount sys /sys -t sysfs
dpkg-reconfigure locales
apt-get dist-upgrade
... install whatever else you need ...

There is still some problem where gcc 4.6.1 in the chroot can ICE when
handling floating point code. I'm looking into it.

I would appreciate it if these fixes could be merged upstream. Thanks.
*
*


qemu-mipsel-debian-rootfs.patch.gz
Description: GNU Zip compressed data


Re: [Qemu-devel] [V4 Patch 1/4 -Updated]Qemu: Enhance info block to display host cache setting

2011-07-05 Thread Supriya Kannery


Updated patch to display hostcache = 1/0 instead of true/false
in monitor.

---
Enhance info block to display hostcache setting for each
block device.

Example:
(qemu) info block
ide0-hd0: type=hd removable=0 file=../rhel6-32.qcow2 ro=0 drv=qcow2
encrypted=0

Enhanced to display hostcache setting:
(qemu) info block
ide0-hd0: type=hd removable=0 hostcache=true file=../rhel6-32.qcow2
ro=0 drv=qcow2 encrypted=0

Signed-off-by: Supriya Kannery supri...@in.ibm.com

---
 block.c |   21 +
 qmp-commands.hx |2 ++
 2 files changed, 19 insertions(+), 4 deletions(-)

Index: qemu/block.c
===
--- qemu.orig/block.c
+++ qemu/block.c
@@ -1694,6 +1694,14 @@ static void bdrv_print_dict(QObject *obj
 monitor_printf(mon,  locked=%d, qdict_get_bool(bs_dict, 
locked));

 }

+if (qdict_haskey(bs_dict, open_flags)) {
+int open_flags = qdict_get_int(bs_dict, open_flags);
+if (open_flags  BDRV_O_NOCACHE)
+monitor_printf(mon,  hostcache=0);
+else
+monitor_printf(mon,  hostcache=1);
+}
+
 if (qdict_haskey(bs_dict, inserted)) {
 QDict *qdict = qobject_to_qdict(qdict_get(bs_dict, inserted));

@@ -1730,13 +1738,18 @@ void bdrv_info(Monitor *mon, QObject **r
 QObject *bs_obj;

 bs_obj = qobject_from_jsonf({ 'device': %s, 'type': 'unknown', 
-'removable': %i, 'locked': %i },
-bs-device_name, bs-removable,
-bs-locked);
+ 'removable': %i, 'locked': %i, 
+ 'hostcache': %s },
+ bs-device_name, bs-removable,
+ bs-locked,
+ (bs-open_flags  BDRV_O_NOCACHE) ?
+ false : true);
+
+QDict *bs_dict = qobject_to_qdict(bs_obj);
+qdict_put(bs_dict, open_flags, qint_from_int(bs-open_flags));

 if (bs-drv) {
 QObject *obj;
-QDict *bs_dict = qobject_to_qdict(bs_obj);

 obj = qobject_from_jsonf({ 'file': %s, 'ro': %i, 'drv': %s, 
  'encrypted': %i },
Index: qemu/qmp-commands.hx
===
--- qemu.orig/qmp-commands.hx
+++ qemu/qmp-commands.hx
@@ -1070,6 +1070,7 @@ Each json-object contain the following:
  - Possible values: unknown
 - removable: true if the device is removable, false otherwise 
(json-bool)

 - locked: true if the device is locked, false otherwise (json-bool)
+- hostcache: true if hostcache enabled, false otherwise (json-bool)
 - inserted: only present if the device is inserted, it is a json-object
containing the following:
  - file: device file name (json-string)
@@ -1091,6 +1092,7 @@ Example:
  {
 device:ide0-hd0,
 locked:false,
+hostcache:false,
 removable:false,
 inserted:{
ro:false,



Re: [Qemu-devel] [V4 Patch 3/4]Qemu: Command block_set for dynamic block params change

2011-07-05 Thread Supriya Kannery

On 07/04/2011 05:59 PM, Stefan Hajnoczi wrote:

On Mon, Jul 4, 2011 at 11:43 AM, Supriya Kannery
supri...@linux.vnet.ibm.com  wrote:


 {
+.name   = block_set,
+.args_type  = device:B,name:s,enable:b,
+.params = device name enable,


Perhaps:

.args_type  = device:B,name:s,enable:b?,
.params = device name [enable],

But I am not sure what the best way to express this is.


+.help   = Enable/Disable block device params like hostcache,


Arguments (like enable) should depend on the block parameter that is
being set:

.help = Set block device parameter

If there is no good way to support different optional arguments and
types then a json-string value argument would be best.



device_add is defined and implemented to handle multiple types of
optional arguments. Will work on to see whether that approach
can be adopted for block_set
{
.name   = device_add,
.args_type  = device:O,
.params = driver[,prop=value][,...],
.help   = add device, like -device on the command line,
.user_print = monitor_user_noop,
.mhandler.cmd_new = do_device_add,
},





Stefan





Re: [Qemu-devel] [V4 Patch 4/4 - Updated]Qemu: Add commandline -drive option 'hostcache'

2011-07-05 Thread Supriya Kannery

Updated patch to use qemu_opt_get_bool() instead of qemu_opt_get()
to read 'hostcache'

---
qemu command option 'hostcache' added to -drive for block devices.
While starting a VM from qemu commandline, this option can be used
for setting host cache usage for block data access. It is not
allowed to specify both 'hostcache' and 'cache' options in the same
commandline. User has to specify only one among these.

Signed-off-by: Supriya Kannery supri...@in.ibm.com

---
 blockdev.c  |   13 +
 qemu-config.c   |4 
 qemu-options.hx |2 +-
 3 files changed, 18 insertions(+), 1 deletion(-)

Index: qemu/blockdev.c
===
--- qemu.orig/blockdev.c
+++ qemu/blockdev.c
@@ -238,6 +238,7 @@ DriveInfo *drive_init(QemuOpts *opts, in
 DriveInfo *dinfo;
 int snapshot = 0;
 int ret;
+int hostcache = 0;

 translation = BIOS_ATA_TRANSLATION_AUTO;

@@ -324,7 +325,19 @@ DriveInfo *drive_init(QemuOpts *opts, in
}
 }

+if ((hostcache = qemu_opt_get_bool(opts, hostcache, -1)) != -1) {
+if (!hostcache) {
+bdrv_flags |= BDRV_O_NOCACHE;
+} else {
+bdrv_flags = ~BDRV_O_NOCACHE;
+}
+}
+
 if ((buf = qemu_opt_get(opts, cache)) != NULL) {
+if (hostcache != -1) {
+error_report('hostcache' and 'cache' cannot co-exist);
+return NULL;
+}
 if (!strcmp(buf, off) || !strcmp(buf, none)) {
 bdrv_flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB;
 } else if (!strcmp(buf, writeback)) {
Index: qemu/qemu-options.hx
===
--- qemu.orig/qemu-options.hx
+++ qemu/qemu-options.hx
@@ -120,7 +120,7 @@ DEF(drive, HAS_ARG, QEMU_OPTION_drive,
[,cyls=c,heads=h,secs=s[,trans=t]][,snapshot=on|off]\n
[,cache=writethrough|writeback|none|unsafe][,format=f]\n
[,serial=s][,addr=A][,id=name][,aio=threads|native]\n
-   [,readonly=on|off]\n
+   [,readonly=on|off][,hostcache=on|off]\n
 use 'file' as a drive image\n, QEMU_ARCH_ALL)
 STEXI
 @item -drive @var{option}[,@var{option}[,@var{option}[,...]]]
Index: qemu/qemu-config.c
===
--- qemu.orig/qemu-config.c
+++ qemu/qemu-config.c
@@ -78,6 +78,10 @@ static QemuOptsList qemu_drive_opts = {
 },{
 .name = readonly,
 .type = QEMU_OPT_BOOL,
+},{
+.name = hostcache,
+.type = QEMU_OPT_BOOL,
+.help = set or reset hostcache (on/off)
 },
 { /* end of list */ }
 },



[Qemu-devel] [PATCH 2/5] scsi: Add 'hba_private' to SCSIRequest

2011-07-05 Thread Hannes Reinecke
'tag' is just an abstraction to identify the command
from the driver. So we should make that explicit by
replacing 'tag' with a driver-defined pointer 'hba_private'.
This saves the lookup for driver handling several commands
in parallel.
'tag' is still being kept for tracing purposes.

Signed-off-by: Hannes Reinecke h...@suse.de
Acked-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/esp.c  |2 +-
 hw/lsi53c895a.c   |   22 --
 hw/scsi-bus.c |9 ++---
 hw/scsi-disk.c|4 ++--
 hw/scsi-generic.c |5 +++--
 hw/scsi.h |   10 +++---
 hw/spapr_vscsi.c  |   29 +
 hw/usb-msd.c  |9 +
 8 files changed, 37 insertions(+), 53 deletions(-)

diff --git a/hw/esp.c b/hw/esp.c
index 8e95672..69209bd 100644
--- a/hw/esp.c
+++ b/hw/esp.c
@@ -244,7 +244,7 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t 
busid)
 
 DPRINTF(do_busid_cmd: busid 0x%x\n, busid);
 lun = busid  7;
-s-current_req = scsi_req_new(s-current_dev, 0, lun);
+s-current_req = scsi_req_new(s-current_dev, 0, lun, NULL);
 datalen = scsi_req_enqueue(s-current_req, buf);
 s-ti_size = datalen;
 if (datalen != 0) {
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 940b43a..69eec1d 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -661,7 +661,7 @@ static lsi_request *lsi_find_by_tag(LSIState *s, uint32_t 
tag)
 static void lsi_request_cancelled(SCSIRequest *req)
 {
 LSIState *s = DO_UPCAST(LSIState, dev.qdev, req-bus-qbus.parent);
-lsi_request *p;
+lsi_request *p = req-hba_private;
 
 if (s-current  req == s-current-req) {
 scsi_req_unref(req);
@@ -670,7 +670,6 @@ static void lsi_request_cancelled(SCSIRequest *req)
 return;
 }
 
-p = lsi_find_by_tag(s, req-tag);
 if (p) {
 QTAILQ_REMOVE(s-queue, p, next);
 scsi_req_unref(req);
@@ -680,18 +679,12 @@ static void lsi_request_cancelled(SCSIRequest *req)
 
 /* Record that data is available for a queued command.  Returns zero if
the device was reselected, nonzero if the IO is deferred.  */
-static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t len)
+static int lsi_queue_req(LSIState *s, SCSIRequest *req, uint32_t len)
 {
-lsi_request *p;
-
-p = lsi_find_by_tag(s, tag);
-if (!p) {
-BADF(IO with unknown tag %d\n, tag);
-return 1;
-}
+lsi_request *p = req-hba_private;
 
 if (p-pending) {
-BADF(Multiple IO pending for tag %d\n, tag);
+BADF(Multiple IO pending for request %p\n, p);
 }
 p-pending = len;
 /* Reselect if waiting for it, or if reselection triggers an IRQ
@@ -743,9 +736,9 @@ static void lsi_transfer_data(SCSIRequest *req, uint32_t 
len)
 LSIState *s = DO_UPCAST(LSIState, dev.qdev, req-bus-qbus.parent);
 int out;
 
-if (s-waiting == 1 || !s-current || req-tag != s-current-tag ||
+if (s-waiting == 1 || !s-current || req-hba_private != s-current ||
 (lsi_irq_on_rsl(s)  !(s-scntl1  LSI_SCNTL1_CON))) {
-if (lsi_queue_tag(s, req-tag, len)) {
+if (lsi_queue_req(s, req, len)) {
 return;
 }
 }
@@ -789,7 +782,8 @@ static void lsi_do_command(LSIState *s)
 assert(s-current == NULL);
 s-current = qemu_mallocz(sizeof(lsi_request));
 s-current-tag = s-select_tag;
-s-current-req = scsi_req_new(dev, s-current-tag, s-current_lun);
+s-current-req = scsi_req_new(dev, s-current-tag, s-current_lun,
+   s-current);
 
 n = scsi_req_enqueue(s-current-req, buf);
 if (n) {
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index ad6a730..8b1a412 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -131,7 +131,8 @@ int scsi_bus_legacy_handle_cmdline(SCSIBus *bus)
 return res;
 }
 
-SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t 
lun)
+SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag,
+uint32_t lun, void *hba_private)
 {
 SCSIRequest *req;
 
@@ -141,14 +142,16 @@ SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, 
uint32_t tag, uint32_t l
 req-dev = d;
 req-tag = tag;
 req-lun = lun;
+req-hba_private = hba_private;
 req-status = -1;
 trace_scsi_req_alloc(req-dev-id, req-lun, req-tag);
 return req;
 }
 
-SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun)
+SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
+  void *hba_private)
 {
-return d-info-alloc_req(d, tag, lun);
+return d-info-alloc_req(d, tag, lun, hba_private);
 }
 
 uint8_t *scsi_req_get_buf(SCSIRequest *req)
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index a8c7372..c2a99fe 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -81,13 +81,13 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, 
int type);
 static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf);
 
 static 

[Qemu-devel] [PATCH 3/5] scsi-disk: Fixup debugging statement

2011-07-05 Thread Hannes Reinecke
A debugging statement wasn't converted to the new interface.

Signed-off-by: Hannes Reinecke h...@suse.de
---
 hw/scsi-disk.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index c2a99fe..5804662 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -1007,7 +1007,7 @@ static int32_t scsi_send_command(SCSIRequest *req, 
uint8_t *buf)
 
 command = buf[0];
 outbuf = (uint8_t *)r-iov.iov_base;
-DPRINTF(Command: lun=%d tag=0x%x data=0x%02x, lun, tag, buf[0]);
+DPRINTF(Command: lun=%d tag=0x%x data=0x%02x, req-lun, req-tag, 
buf[0]);
 
 if (scsi_req_parse(r-req, buf) != 0) {
 BADF(Unsupported command length, command %x\n, command);
-- 
1.7.3.4




[Qemu-devel] [PATCH 4/5] scsi-disk: Mask out serial number EVPD

2011-07-05 Thread Hannes Reinecke
If the serial number is not set we should mask it out in the
list of supported VPD pages and mark it as not supported.

Signed-off-by: Hannes Reinecke h...@suse.de
---
 hw/scsi-disk.c |   15 ---
 1 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 5804662..05d14ab 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -398,7 +398,8 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, 
uint8_t *outbuf)
 buffer size %zd\n, req-cmd.xfer);
 pages = buflen++;
 outbuf[buflen++] = 0x00; // list of supported pages (this page)
-outbuf[buflen++] = 0x80; // unit serial number
+if (s-serial)
+outbuf[buflen++] = 0x80; // unit serial number
 outbuf[buflen++] = 0x83; // device identification
 if (s-drive_kind == SCSI_HD) {
 outbuf[buflen++] = 0xb0; // block limits
@@ -409,8 +410,14 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, 
uint8_t *outbuf)
 }
 case 0x80: /* Device serial number, optional */
 {
-int l = strlen(s-serial);
+int l;
 
+if (!s-serial) {
+DPRINTF(Inquiry (EVPD[Serial number] not supported\n);
+return -1;
+}
+
+l = strlen(s-serial);
 if (l  req-cmd.xfer)
 l = req-cmd.xfer;
 if (l  20)
@@ -1203,7 +1210,9 @@ static int scsi_initfn(SCSIDevice *dev, SCSIDriveKind 
kind)
 if (!s-serial) {
 /* try to fall back to value set with legacy -drive serial=... */
 dinfo = drive_get_by_blockdev(s-bs);
-s-serial = qemu_strdup(*dinfo-serial ? dinfo-serial : 0);
+if (*dinfo-serial) {
+s-serial = qemu_strdup(dinfo-serial);
+}
 }
 
 if (!s-version) {
-- 
1.7.3.4




[Qemu-devel] [PATCH 0/5][v6] Megasas HBA emulation

2011-07-05 Thread Hannes Reinecke
Hi all,

as Alex Graf reminded me the driver needed some more bugfixing
to be done. I've found some issues and also moved the megasas
emulation over to the new trace infrastructure.
Driver works for me now and a full installation of
openSUSE-12.1 works perfectly.
I've also included the fixes suggested by Stefan Hajnoczi.
And during debugging I've found two minor issues in scsi_disk.c

Changes since v5:
- scsi-disk: Fixup debugging statement
  A debugging statement wasn't converted. Do so now.
- scsi-disk: Mask out serial number EVPD
  The 'serial' parameter to scsi-disk is optional. So if it's
  not set we should mask it out in the list of supported EVPD
  pages and not return '0' here.
- megasas: Use tracing infrastructure instead of DPRINTF
- megasas: Use new PCI infrastructure
- megasas: Check for iovec mapping failure
  cpu_map_physical_memory() might fail, so we need to check for
  it when mapping iovecs.
- megasas: Trace scsi buffer overflow
  The transfer length as specified in the SCSI command might
  disagree with the length of the iovec. We should be tracing
  these issues.
- megasas: Reset frames after init firmware
  When receiving an INIT FIRMWARE command we need reset all
  frames, otherwise some frames might point to invalid memory.

Chances since v4:
- iov: Update parameter usage in iov_(to|from)_buf()
  Updated description for the first patch and clarified the usage
  Renamed arguments for io_XXX for clarification
- scsi: Add 'hba_private' to SCSIRequest
  Kept 'tag' for tracing and just add 'hba_private' as an
  additional field as per request from Paolo
- megasas: checkpatch.pl fixes and update to work with the
  changed interface in scsi_req_new(). Also included the
  suggested fixes from Alex.


Hannes Reinecke (5):
  iov: Update parameter usage in iov_(to|from)_buf()
  scsi: Add 'hba_private' to SCSIRequest
  scsi-disk: Fixup debugging statement
  scsi-disk: Mask out serial number EVPD
  megasas: LSI Megaraid SAS emulation

 Makefile.objs   |1 +
 default-configs/pci.mak |1 +
 hw/esp.c|2 +-
 hw/lsi53c895a.c |   22 +-
 hw/megasas.c| 1950 +++
 hw/mfi.h| 1197 +
 hw/pci_ids.h|3 +-
 hw/scsi-bus.c   |9 +-
 hw/scsi-disk.c  |   21 +-
 hw/scsi-generic.c   |5 +-
 hw/scsi.h   |   10 +-
 hw/spapr_vscsi.c|   29 +-
 hw/usb-msd.c|9 +-
 hw/virtio-net.c |2 +-
 hw/virtio-serial-bus.c  |2 +-
 iov.c   |   49 +-
 iov.h   |   10 +-
 trace-events|   71 ++
 18 files changed, 3306 insertions(+), 87 deletions(-)
 create mode 100644 hw/megasas.c
 create mode 100644 hw/mfi.h

-- 
1.7.3.4




Re: [Qemu-devel] [PATCH 4/5] scsi-disk: Mask out serial number EVPD

2011-07-05 Thread Paolo Bonzini

On 07/05/2011 01:03 PM, Hannes Reinecke wrote:

If the serial number is not set we should mask it out in the
list of supported VPD pages and mark it as not supported.

Signed-off-by: Hannes Reineckeh...@suse.de
---
  hw/scsi-disk.c |   15 ---
  1 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 5804662..05d14ab 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -398,7 +398,8 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, 
uint8_t *outbuf)
  buffer size %zd\n, req-cmd.xfer);
  pages = buflen++;
  outbuf[buflen++] = 0x00; // list of supported pages (this page)
-outbuf[buflen++] = 0x80; // unit serial number
+if (s-serial)
+outbuf[buflen++] = 0x80; // unit serial number
  outbuf[buflen++] = 0x83; // device identification
  if (s-drive_kind == SCSI_HD) {
  outbuf[buflen++] = 0xb0; // block limits
@@ -409,8 +410,14 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, 
uint8_t *outbuf)
  }
  case 0x80: /* Device serial number, optional */
  {
-int l = strlen(s-serial);
+int l;

+if (!s-serial) {
+DPRINTF(Inquiry (EVPD[Serial number] not supported\n);
+return -1;
+}
+
+l = strlen(s-serial);
  if (l  req-cmd.xfer)
  l = req-cmd.xfer;
  if (l  20)
@@ -1203,7 +1210,9 @@ static int scsi_initfn(SCSIDevice *dev, SCSIDriveKind 
kind)
  if (!s-serial) {
  /* try to fall back to value set with legacy -drive serial=... */
  dinfo = drive_get_by_blockdev(s-bs);
-s-serial = qemu_strdup(*dinfo-serial ? dinfo-serial : 0);
+if (*dinfo-serial) {
+s-serial = qemu_strdup(dinfo-serial);
+}
  }

  if (!s-version) {


Acked-by: Paolo Bonzini pbonz...@redhat.com

Paolo



[Qemu-devel] [PATCH 1/5] iov: Update parameter usage in iov_(to|from)_buf()

2011-07-05 Thread Hannes Reinecke
iov_to_buf() has an 'offset' parameter, iov_from_buf() hasn't.
This patch adds the missing parameter to iov_from_buf().
It also renames the 'offset' parameter to 'iov_off' to
emphasize it's the offset into the iovec and not the buffer.

Signed-off-by: Hannes Reinecke h...@suse.de
Acked-by: Alexander Graf ag...@suse.de
---
 hw/virtio-net.c|2 +-
 hw/virtio-serial-bus.c |2 +-
 iov.c  |   49 ++-
 iov.h  |   10 
 4 files changed, 34 insertions(+), 29 deletions(-)

diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 6997e02..a32cc01 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -657,7 +657,7 @@ static ssize_t virtio_net_receive(VLANClientState *nc, 
const uint8_t *buf, size_
 
 /* copy in packet.  ugh */
 len = iov_from_buf(sg, elem.in_num,
-   buf + offset, size - offset);
+   buf + offset, 0, size - offset);
 total += len;
 offset += len;
 /* If buffers can't be merged, at this point we
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 7f6db7b..53c58d0 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -103,7 +103,7 @@ static size_t write_to_port(VirtIOSerialPort *port,
 }
 
 len = iov_from_buf(elem.in_sg, elem.in_num,
-   buf + offset, size - offset);
+   buf + offset, 0, size - offset);
 offset += len;
 
 virtqueue_push(vq, elem, len);
diff --git a/iov.c b/iov.c
index 588cd04..1e02791 100644
--- a/iov.c
+++ b/iov.c
@@ -14,56 +14,61 @@
 
 #include iov.h
 
-size_t iov_from_buf(struct iovec *iov, unsigned int iovcnt,
-const void *buf, size_t size)
+size_t iov_from_buf(struct iovec *iov, unsigned int iov_cnt,
+const void *buf, size_t iov_off, size_t size)
 {
-size_t offset;
+size_t iovec_off, buf_off;
 unsigned int i;
 
-offset = 0;
-for (i = 0; offset  size  i  iovcnt; i++) {
-size_t len;
+iovec_off = 0;
+buf_off = 0;
+for (i = 0; i  iov_cnt  size; i++) {
+if (iov_off  (iovec_off + iov[i].iov_len)) {
+size_t len = MIN((iovec_off + iov[i].iov_len) - iov_off, size);
 
-len = MIN(iov[i].iov_len, size - offset);
+memcpy(iov[i].iov_base + (iov_off - iovec_off), buf + buf_off, 
len);
 
-memcpy(iov[i].iov_base, buf + offset, len);
-offset += len;
+buf_off += len;
+iov_off += len;
+size -= len;
+}
+iovec_off += iov[i].iov_len;
 }
-return offset;
+return buf_off;
 }
 
-size_t iov_to_buf(const struct iovec *iov, const unsigned int iovcnt,
-  void *buf, size_t offset, size_t size)
+size_t iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt,
+  void *buf, size_t iov_off, size_t size)
 {
 uint8_t *ptr;
-size_t iov_off, buf_off;
+size_t iovec_off, buf_off;
 unsigned int i;
 
 ptr = buf;
-iov_off = 0;
+iovec_off = 0;
 buf_off = 0;
-for (i = 0; i  iovcnt  size; i++) {
-if (offset  (iov_off + iov[i].iov_len)) {
-size_t len = MIN((iov_off + iov[i].iov_len) - offset , size);
+for (i = 0; i  iov_cnt  size; i++) {
+if (iov_off  (iovec_off + iov[i].iov_len)) {
+size_t len = MIN((iovec_off + iov[i].iov_len) - iov_off , size);
 
-memcpy(ptr + buf_off, iov[i].iov_base + (offset - iov_off), len);
+memcpy(ptr + buf_off, iov[i].iov_base + (iov_off - iovec_off), 
len);
 
 buf_off += len;
-offset += len;
+iov_off += len;
 size -= len;
 }
-iov_off += iov[i].iov_len;
+iovec_off += iov[i].iov_len;
 }
 return buf_off;
 }
 
-size_t iov_size(const struct iovec *iov, const unsigned int iovcnt)
+size_t iov_size(const struct iovec *iov, const unsigned int iov_cnt)
 {
 size_t len;
 unsigned int i;
 
 len = 0;
-for (i = 0; i  iovcnt; i++) {
+for (i = 0; i  iov_cnt; i++) {
 len += iov[i].iov_len;
 }
 return len;
diff --git a/iov.h b/iov.h
index 60a8547..110f67a 100644
--- a/iov.h
+++ b/iov.h
@@ -12,8 +12,8 @@
 
 #include qemu-common.h
 
-size_t iov_from_buf(struct iovec *iov, unsigned int iovcnt,
-const void *buf, size_t size);
-size_t iov_to_buf(const struct iovec *iov, const unsigned int iovcnt,
-  void *buf, size_t offset, size_t size);
-size_t iov_size(const struct iovec *iov, const unsigned int iovcnt);
+size_t iov_from_buf(struct iovec *iov, unsigned int iov_cnt,
+const void *buf, size_t iov_off, size_t size);
+size_t iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt,
+  void *buf, size_t iov_off, size_t size);
+size_t iov_size(const struct iovec *iov, const unsigned int iov_cnt);
-- 
1.7.3.4




Re: [Qemu-devel] [PATCH 3/5] scsi-disk: Fixup debugging statement

2011-07-05 Thread Paolo Bonzini

On 07/05/2011 01:03 PM, Hannes Reinecke wrote:

A debugging statement wasn't converted to the new interface.

Signed-off-by: Hannes Reineckeh...@suse.de
---
  hw/scsi-disk.c |2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index c2a99fe..5804662 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -1007,7 +1007,7 @@ static int32_t scsi_send_command(SCSIRequest *req, 
uint8_t *buf)

  command = buf[0];
  outbuf = (uint8_t *)r-iov.iov_base;
-DPRINTF(Command: lun=%d tag=0x%x data=0x%02x, lun, tag, buf[0]);
+DPRINTF(Command: lun=%d tag=0x%x data=0x%02x, req-lun, req-tag, 
buf[0]);

  if (scsi_req_parse(r-req, buf) != 0) {
  BADF(Unsupported command length, command %x\n, command);


Acked-by: Paolo Bonzini pbonz...@redhat.com



[Qemu-devel] [PATCH 2/2] virtio-console: Add some trace events

2011-07-05 Thread Amit Shah
Add some trace events for messages passed between the char layer and the
virtio-serial bus.

Signed-off-by: Amit Shah amit.s...@redhat.com
---
 hw/virtio-console.c |9 -
 trace-events|5 +
 2 files changed, 13 insertions(+), 1 deletions(-)

diff --git a/hw/virtio-console.c b/hw/virtio-console.c
index b076331..713a761 100644
--- a/hw/virtio-console.c
+++ b/hw/virtio-console.c
@@ -12,6 +12,7 @@
 
 #include qemu-char.h
 #include qemu-error.h
+#include trace.h
 #include virtio-serial.h
 
 typedef struct VirtConsole {
@@ -24,8 +25,12 @@ typedef struct VirtConsole {
 static ssize_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t 
len)
 {
 VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
+ssize_t ret;
 
-return qemu_chr_write(vcon-chr, buf, len);
+ret = qemu_chr_write(vcon-chr, buf, len);
+
+trace_virtio_console_flush_buf(port-id, len, ret);
+return ret;
 }
 
 /* Callback function that's called when the guest opens the port */
@@ -57,6 +62,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int 
size)
 {
 VirtConsole *vcon = opaque;
 
+trace_virtio_console_chr_read(vcon-port.id, size);
 virtio_serial_write(vcon-port, buf, size);
 }
 
@@ -64,6 +70,7 @@ static void chr_event(void *opaque, int event)
 {
 VirtConsole *vcon = opaque;
 
+trace_virtio_console_chr_event(vcon-port.id, event);
 switch (event) {
 case CHR_EVENT_OPENED:
 virtio_serial_open(vcon-port);
diff --git a/trace-events b/trace-events
index 59420e8..765a15e 100644
--- a/trace-events
+++ b/trace-events
@@ -52,6 +52,11 @@ disable virtio_serial_throttle_port(unsigned int port, bool 
throttle) port %u,
 disable virtio_serial_handle_control_message(uint16_t event, uint16_t value) 
event %u, value %u
 disable virtio_serial_handle_control_message_port(unsigned int port) port %u
 
+# hw/virtio-console.c
+disable virtio_console_flush_buf(unsigned int port, size_t len, ssize_t ret) 
port %u, in_len %zu, out_len %zd
+disable virtio_console_chr_read(unsigned int port, int size) port %u, size %d
+disable virtio_console_chr_event(unsigned int port, int event) port %u, event 
%d
+
 # block.c
 disable multiwrite_cb(void *mcb, int ret) mcb %p ret %d
 disable bdrv_aio_multiwrite(void *mcb, int num_callbacks, int num_reqs) mcb 
%p num_callbacks %d num_reqs %d
-- 
1.7.5.4




[Qemu-devel] [PATCH v8 05/12] VMDK: add field BDRVVmdkState.desc_offset

2011-07-05 Thread Fam Zheng
There are several occurrence of magic number 0x200 as the descriptor
offset within mono sparse image file. This is not the case for images
with separate descriptor file. So a field is added to BDRVVmdkState to
hold the correct value.

Signed-off-by: Fam Zheng famc...@gmail.com
---
 block/vmdk.c |   27 ++-
 1 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index 6d7b497..529ae90 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -81,6 +81,7 @@ typedef struct VmdkExtent {
 } VmdkExtent;
 
 typedef struct BDRVVmdkState {
+int desc_offset;
 uint32_t parent_cid;
 int num_extents;
 /* Extent array with num_extents entries, ascend ordered by address */
@@ -175,10 +176,11 @@ static uint32_t vmdk_read_cid(BlockDriverState *bs, int 
parent)
 uint32_t cid;
 const char *p_name, *cid_str;
 size_t cid_str_size;
+BDRVVmdkState *s = bs-opaque;
 
-/* the descriptor offset = 0x200 */
-if (bdrv_pread(bs-file, 0x200, desc, DESC_SIZE) != DESC_SIZE)
+if (bdrv_pread(bs-file, s-desc_offset, desc, DESC_SIZE) != DESC_SIZE) {
 return 0;
+}
 
 if (parent) {
 cid_str = parentCID;
@@ -200,10 +202,12 @@ static int vmdk_write_cid(BlockDriverState *bs, uint32_t 
cid)
 {
 char desc[DESC_SIZE], tmp_desc[DESC_SIZE];
 char *p_name, *tmp_str;
+BDRVVmdkState *s = bs-opaque;
 
-/* the descriptor offset = 0x200 */
-if (bdrv_pread(bs-file, 0x200, desc, DESC_SIZE) != DESC_SIZE)
-return -1;
+memset(desc, 0, sizeof(desc));
+if (bdrv_pread(bs-file, s-desc_offset, desc, DESC_SIZE) != DESC_SIZE) {
+return -EIO;
+}
 
 tmp_str = strstr(desc,parentCID);
 pstrcpy(tmp_desc, sizeof(tmp_desc), tmp_str);
@@ -213,8 +217,9 @@ static int vmdk_write_cid(BlockDriverState *bs, uint32_t 
cid)
 pstrcat(desc, sizeof(desc), tmp_desc);
 }
 
-if (bdrv_pwrite_sync(bs-file, 0x200, desc, DESC_SIZE)  0)
-return -1;
+if (bdrv_pwrite_sync(bs-file, s-desc_offset, desc, DESC_SIZE)  0) {
+return -EIO;
+}
 return 0;
 }
 
@@ -402,10 +407,11 @@ static int vmdk_parent_open(BlockDriverState *bs)
 {
 char *p_name;
 char desc[DESC_SIZE];
+BDRVVmdkState *s = bs-opaque;
 
-/* the descriptor offset = 0x200 */
-if (bdrv_pread(bs-file, 0x200, desc, DESC_SIZE) != DESC_SIZE)
+if (bdrv_pread(bs-file, s-desc_offset, desc, DESC_SIZE) != DESC_SIZE) {
 return -1;
+}
 
 if ((p_name = strstr(desc,parentFileNameHint)) != NULL) {
 char *end_name;
@@ -506,8 +512,10 @@ static int vmdk_open_vmdk3(BlockDriverState *bs, int flags)
 int ret;
 uint32_t magic;
 VMDK3Header header;
+BDRVVmdkState *s = bs-opaque;
 VmdkExtent *extent;
 
+s-desc_offset = 0x200;
 ret = bdrv_pread(bs-file, sizeof(magic), header, sizeof(header));
 if (ret  0) {
 goto fail;
@@ -539,6 +547,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs, int flags)
 BDRVVmdkState *s = bs-opaque;
 VmdkExtent *extent;
 
+s-desc_offset = 0x200;
 ret = bdrv_pread(bs-file, sizeof(magic), header, sizeof(header));
 if (ret  0) {
 goto fail;



[Qemu-devel] [PATCH 1/2] virtio-serial-bus: Add trace events

2011-07-05 Thread Amit Shah
Add some trace events for messages passed between the guest and host.

Signed-off-by: Amit Shah amit.s...@redhat.com
---
 hw/virtio-serial-bus.c |7 +++
 trace-events   |6 ++
 2 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 7f6db7b..9859f9f 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -19,6 +19,7 @@
 #include monitor.h
 #include qemu-queue.h
 #include sysbus.h
+#include trace.h
 #include virtio-serial.h
 
 /* The virtio-serial bus on top of which the ports will ride as devices */
@@ -221,6 +222,7 @@ static size_t send_control_event(VirtIOSerialPort *port, 
uint16_t event,
 stw_p(cpkt.event, event);
 stw_p(cpkt.value, value);
 
+trace_virtio_serial_send_control_event(port-id, event, value);
 return send_control_msg(port, cpkt, sizeof(cpkt));
 }
 
@@ -302,6 +304,7 @@ void virtio_serial_throttle_port(VirtIOSerialPort *port, 
bool throttle)
 return;
 }
 
+trace_virtio_serial_throttle_port(port-id, throttle);
 port-throttled = throttle;
 if (throttle) {
 return;
@@ -328,6 +331,8 @@ static void handle_control_message(VirtIOSerial *vser, void 
*buf, size_t len)
 cpkt.event = lduw_p(gcpkt-event);
 cpkt.value = lduw_p(gcpkt-value);
 
+trace_virtio_serial_handle_control_message(cpkt.event, cpkt.value);
+
 if (cpkt.event == VIRTIO_CONSOLE_DEVICE_READY) {
 if (!cpkt.value) {
 error_report(virtio-serial-bus: Guest failure in adding device 
%s,
@@ -351,6 +356,8 @@ static void handle_control_message(VirtIOSerial *vser, void 
*buf, size_t len)
 return;
 }
 
+trace_virtio_serial_handle_control_message_port(port-id);
+
 info = DO_UPCAST(VirtIOSerialPortInfo, qdev, port-dev.info);
 
 switch(cpkt.event) {
diff --git a/trace-events b/trace-events
index bebf612..59420e8 100644
--- a/trace-events
+++ b/trace-events
@@ -46,6 +46,12 @@ disable virtio_queue_notify(void *vdev, int n, void *vq) 
vdev %p n %d vq %p
 disable virtio_irq(void *vq) vq %p
 disable virtio_notify(void *vdev, void *vq) vdev %p vq %p
 
+# hw/virtio-serial-bus.c
+disable virtio_serial_send_control_event(unsigned int port, uint16_t event, 
uint16_t value) port %u, event %u, value %u
+disable virtio_serial_throttle_port(unsigned int port, bool throttle) port 
%u, throttle %d
+disable virtio_serial_handle_control_message(uint16_t event, uint16_t value) 
event %u, value %u
+disable virtio_serial_handle_control_message_port(unsigned int port) port %u
+
 # block.c
 disable multiwrite_cb(void *mcb, int ret) mcb %p ret %d
 disable bdrv_aio_multiwrite(void *mcb, int num_callbacks, int num_reqs) mcb 
%p num_callbacks %d num_reqs %d
-- 
1.7.5.4




[Qemu-devel] [PATCH v8 07/12] VMDK: move 'static' cid_update flag to bs field

2011-07-05 Thread Fam Zheng
Cid_update is the flag for updating CID on first write after opening the
image. This should be per image open rather than per program life cycle,
so change it from static var of vmdk_write to a field in BDRVVmdkState.

Signed-off-by: Fam Zheng famc...@gmail.com
---
 block/vmdk.c |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index f6d2986..8dc58a8 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -82,6 +82,7 @@ typedef struct VmdkExtent {
 
 typedef struct BDRVVmdkState {
 int desc_offset;
+bool cid_updated;
 uint32_t parent_cid;
 int num_extents;
 /* Extent array with num_extents entries, ascend ordered by address */
@@ -853,7 +854,6 @@ static int vmdk_write(BlockDriverState *bs, int64_t 
sector_num,
 int n;
 int64_t index_in_cluster;
 uint64_t cluster_offset;
-static int cid_update = 0;
 VmdkMetaData m_data;
 
 if (sector_num  bs-total_sectors) {
@@ -900,9 +900,9 @@ static int vmdk_write(BlockDriverState *bs, int64_t 
sector_num,
 buf += n * 512;
 
 // update CID on the first write every time the virtual disk is opened
-if (!cid_update) {
+if (!s-cid_updated) {
 vmdk_write_cid(bs, time(NULL));
-cid_update++;
+s-cid_updated = true;
 }
 }
 return 0;



[Qemu-devel] [PATCH v8 00/12] Adding VMDK monolithic flat support

2011-07-05 Thread Fam Zheng
Chnages from v7:
03/12: remove deadloop in probing descriptor file.

Fam Zheng (12):
  VMDK: introduce VmdkExtent
  VMDK: bugfix, align offset to cluster in get_whole_cluster
  VMDK: probe for monolithicFlat images
  VMDK: separate vmdk_open by format version
  VMDK: add field BDRVVmdkState.desc_offset
  VMDK: flush multiple extents
  VMDK: move 'static' cid_update flag to bs field
  VMDK: change get_cluster_offset return type
  VMDK: open/read/write for monolithicFlat image
  VMDK: create different subformats
  VMDK: fix coding style
  block: add bdrv_get_allocated_file_size() operation

 block.c   |   19 +
 block.h   |1 +
 block/raw-posix.c |   21 +
 block/raw-win32.c |   29 ++
 block/vmdk.c  | 1361 +
 block_int.h   |2 +
 qemu-img.c|   31 +--
 7 files changed, 1024 insertions(+), 440 deletions(-)




[Qemu-devel] [PATCH v8 01/12] VMDK: introduce VmdkExtent

2011-07-05 Thread Fam Zheng
Introduced VmdkExtent array into BDRVVmdkState, enable holding multiple
image extents for multiple file image support.

Signed-off-by: Fam Zheng famc...@gmail.com
---
 block/vmdk.c |  348 +-
 1 files changed, 246 insertions(+), 102 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index 922b23d..3b78583 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -60,7 +60,11 @@ typedef struct {
 
 #define L2_CACHE_SIZE 16
 
-typedef struct BDRVVmdkState {
+typedef struct VmdkExtent {
+BlockDriverState *file;
+bool flat;
+int64_t sectors;
+int64_t end_sector;
 int64_t l1_table_offset;
 int64_t l1_backup_table_offset;
 uint32_t *l1_table;
@@ -74,7 +78,13 @@ typedef struct BDRVVmdkState {
 uint32_t l2_cache_counts[L2_CACHE_SIZE];
 
 unsigned int cluster_sectors;
+} VmdkExtent;
+
+typedef struct BDRVVmdkState {
 uint32_t parent_cid;
+int num_extents;
+/* Extent array with num_extents entries, ascend ordered by address */
+VmdkExtent *extents;
 } BDRVVmdkState;
 
 typedef struct VmdkMetaData {
@@ -105,6 +115,19 @@ static int vmdk_probe(const uint8_t *buf, int buf_size, 
const char *filename)
 #define DESC_SIZE 20*SECTOR_SIZE   // 20 sectors of 512 bytes each
 #define HEADER_SIZE 512// first sector of 512 bytes
 
+static void vmdk_free_extents(BlockDriverState *bs)
+{
+int i;
+BDRVVmdkState *s = bs-opaque;
+
+for (i = 0; i  s-num_extents; i++) {
+qemu_free(s-extents[i].l1_table);
+qemu_free(s-extents[i].l2_cache);
+qemu_free(s-extents[i].l1_backup_table);
+}
+qemu_free(s-extents);
+}
+
 static uint32_t vmdk_read_cid(BlockDriverState *bs, int parent)
 {
 char desc[DESC_SIZE];
@@ -358,11 +381,50 @@ static int vmdk_parent_open(BlockDriverState *bs)
 return 0;
 }
 
+/* Create and append extent to the extent array. Return the added VmdkExtent
+ * address. return NULL if allocation failed. */
+static VmdkExtent *vmdk_add_extent(BlockDriverState *bs,
+   BlockDriverState *file, bool flat, int64_t sectors,
+   int64_t l1_offset, int64_t l1_backup_offset,
+   uint32_t l1_size,
+   int l2_size, unsigned int cluster_sectors)
+{
+VmdkExtent *extent;
+BDRVVmdkState *s = bs-opaque;
+
+s-extents = qemu_realloc(s-extents,
+  (s-num_extents + 1) * sizeof(VmdkExtent));
+extent = s-extents[s-num_extents];
+s-num_extents++;
+
+memset(extent, 0, sizeof(VmdkExtent));
+extent-file = file;
+extent-flat = flat;
+extent-sectors = sectors;
+extent-l1_table_offset = l1_offset;
+extent-l1_backup_table_offset = l1_backup_offset;
+extent-l1_size = l1_size;
+extent-l1_entry_sectors = l2_size * cluster_sectors;
+extent-l2_size = l2_size;
+extent-cluster_sectors = cluster_sectors;
+
+if (s-num_extents  1) {
+extent-end_sector = (*(extent - 1)).end_sector + extent-sectors;
+} else {
+extent-end_sector = extent-sectors;
+}
+bs-total_sectors = extent-end_sector;
+return extent;
+}
+
+
 static int vmdk_open(BlockDriverState *bs, int flags)
 {
 BDRVVmdkState *s = bs-opaque;
 uint32_t magic;
-int l1_size, i;
+int i;
+uint32_t l1_size, l1_entry_sectors;
+VmdkExtent *extent = NULL;
 
 if (bdrv_pread(bs-file, 0, magic, sizeof(magic)) != sizeof(magic))
 goto fail;
@@ -370,32 +432,34 @@ static int vmdk_open(BlockDriverState *bs, int flags)
 magic = be32_to_cpu(magic);
 if (magic == VMDK3_MAGIC) {
 VMDK3Header header;
-
-if (bdrv_pread(bs-file, sizeof(magic), header, sizeof(header)) != 
sizeof(header))
+if (bdrv_pread(bs-file, sizeof(magic), header, sizeof(header))
+!= sizeof(header)) {
 goto fail;
-s-cluster_sectors = le32_to_cpu(header.granularity);
-s-l2_size = 1  9;
-s-l1_size = 1  6;
-bs-total_sectors = le32_to_cpu(header.disk_sectors);
-s-l1_table_offset = le32_to_cpu(header.l1dir_offset)  9;
-s-l1_backup_table_offset = 0;
-s-l1_entry_sectors = s-l2_size * s-cluster_sectors;
+}
+extent = vmdk_add_extent(bs, bs-file, false,
+  le32_to_cpu(header.disk_sectors),
+  le32_to_cpu(header.l1dir_offset)  9, 0,
+  1  6, 1  9, le32_to_cpu(header.granularity));
 } else if (magic == VMDK4_MAGIC) {
 VMDK4Header header;
-
-if (bdrv_pread(bs-file, sizeof(magic), header, sizeof(header)) != 
sizeof(header))
+if (bdrv_pread(bs-file, sizeof(magic), header, sizeof(header))
+!= sizeof(header)) {
 goto fail;
-bs-total_sectors = le64_to_cpu(header.capacity);
-s-cluster_sectors = le64_to_cpu(header.granularity);
-s-l2_size = 

[Qemu-devel] [PATCH v8 10/12] VMDK: create different subformats

2011-07-05 Thread Fam Zheng
Add create option 'format', with enums:
monolithicSparse
monolithicFlat
twoGbMaxExtentSparse
twoGbMaxExtentFlat
Each creates a subformat image file. The default is monolithiSparse.

Signed-off-by: Fam Zheng famc...@gmail.com
---
 block/vmdk.c |  561 ++
 block_int.h  |1 +
 2 files changed, 330 insertions(+), 232 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index 2183ace..0f51332 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -156,8 +156,8 @@ static int vmdk_probe(const uint8_t *buf, int buf_size, 
const char *filename)
 #define CHECK_CID 1
 
 #define SECTOR_SIZE 512
-#define DESC_SIZE 20*SECTOR_SIZE   // 20 sectors of 512 bytes each
-#define HEADER_SIZE 512// first sector of 512 bytes
+#define DESC_SIZE (20 * SECTOR_SIZE)/* 20 sectors of 512 bytes each */
+#define HEADER_SIZE 512 /* first sector of 512 bytes */
 
 static void vmdk_free_extents(BlockDriverState *bs)
 {
@@ -243,168 +243,6 @@ static int vmdk_is_cid_valid(BlockDriverState *bs)
 return 1;
 }
 
-static int vmdk_snapshot_create(const char *filename, const char *backing_file)
-{
-int snp_fd, p_fd;
-int ret;
-uint32_t p_cid;
-char *p_name, *gd_buf, *rgd_buf;
-const char *real_filename, *temp_str;
-VMDK4Header header;
-uint32_t gde_entries, gd_size;
-int64_t gd_offset, rgd_offset, capacity, gt_size;
-char p_desc[DESC_SIZE], s_desc[DESC_SIZE], hdr[HEADER_SIZE];
-static const char desc_template[] =
-# Disk DescriptorFile\n
-version=1\n
-CID=%x\n
-parentCID=%x\n
-createType=\monolithicSparse\\n
-parentFileNameHint=\%s\\n
-\n
-# Extent description\n
-RW %u SPARSE \%s\\n
-\n
-# The Disk Data Base \n
-#DDB\n
-\n;
-
-snp_fd = open(filename, O_RDWR | O_CREAT | O_TRUNC | O_BINARY | 
O_LARGEFILE, 0644);
-if (snp_fd  0)
-return -errno;
-p_fd = open(backing_file, O_RDONLY | O_BINARY | O_LARGEFILE);
-if (p_fd  0) {
-close(snp_fd);
-return -errno;
-}
-
-/* read the header */
-if (lseek(p_fd, 0x0, SEEK_SET) == -1) {
-ret = -errno;
-goto fail;
-}
-if (read(p_fd, hdr, HEADER_SIZE) != HEADER_SIZE) {
-ret = -errno;
-goto fail;
-}
-
-/* write the header */
-if (lseek(snp_fd, 0x0, SEEK_SET) == -1) {
-ret = -errno;
-goto fail;
-}
-if (write(snp_fd, hdr, HEADER_SIZE) == -1) {
-ret = -errno;
-goto fail;
-}
-
-memset(header, 0, sizeof(header));
-memcpy(header,hdr[4], sizeof(header)); // skip the VMDK4_MAGIC
-
-if (ftruncate(snp_fd, header.grain_offset  9)) {
-ret = -errno;
-goto fail;
-}
-/* the descriptor offset = 0x200 */
-if (lseek(p_fd, 0x200, SEEK_SET) == -1) {
-ret = -errno;
-goto fail;
-}
-if (read(p_fd, p_desc, DESC_SIZE) != DESC_SIZE) {
-ret = -errno;
-goto fail;
-}
-
-if ((p_name = strstr(p_desc,CID)) != NULL) {
-p_name += sizeof(CID);
-sscanf(p_name,%x,p_cid);
-}
-
-real_filename = filename;
-if ((temp_str = strrchr(real_filename, '\\')) != NULL)
-real_filename = temp_str + 1;
-if ((temp_str = strrchr(real_filename, '/')) != NULL)
-real_filename = temp_str + 1;
-if ((temp_str = strrchr(real_filename, ':')) != NULL)
-real_filename = temp_str + 1;
-
-snprintf(s_desc, sizeof(s_desc), desc_template, p_cid, p_cid, backing_file,
- (uint32_t)header.capacity, real_filename);
-
-/* write the descriptor */
-if (lseek(snp_fd, 0x200, SEEK_SET) == -1) {
-ret = -errno;
-goto fail;
-}
-if (write(snp_fd, s_desc, strlen(s_desc)) == -1) {
-ret = -errno;
-goto fail;
-}
-
-gd_offset = header.gd_offset * SECTOR_SIZE; // offset of GD table
-rgd_offset = header.rgd_offset * SECTOR_SIZE;   // offset of RGD table
-capacity = header.capacity * SECTOR_SIZE;   // Extent size
-/*
- * Each GDE span 32M disk, means:
- * 512 GTE per GT, each GTE points to grain
- */
-gt_size = (int64_t)header.num_gtes_per_gte * header.granularity * 
SECTOR_SIZE;
-if (!gt_size) {
-ret = -EINVAL;
-goto fail;
-}
-gde_entries = (uint32_t)(capacity / gt_size);  // number of gde/rgde
-gd_size = gde_entries * sizeof(uint32_t);
-
-/* write RGD */
-rgd_buf = qemu_malloc(gd_size);
-if (lseek(p_fd, rgd_offset, SEEK_SET) == -1) {
-ret = -errno;
-goto fail_rgd;
-}
-if (read(p_fd, rgd_buf, gd_size) != gd_size) {
-ret = -errno;
-goto fail_rgd;
-}
-if (lseek(snp_fd, rgd_offset, SEEK_SET) == -1) {
-ret = -errno;
-goto fail_rgd;
-}
-if (write(snp_fd, rgd_buf, gd_size) == -1) {
-ret = -errno;
-goto fail_rgd;
-}
-
-/* write GD */
-gd_buf = qemu_malloc(gd_size);
-

[Qemu-devel] [PATCH v8 09/12] VMDK: open/read/write for monolithicFlat image

2011-07-05 Thread Fam Zheng
Parse vmdk decriptor file and open mono flat image.
Read/write the flat extent.

Signed-off-by: Fam Zheng famc...@gmail.com
---
 block/vmdk.c |  172 +-
 1 files changed, 159 insertions(+), 13 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index f637d98..2183ace 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -65,6 +65,7 @@ typedef struct VmdkExtent {
 bool flat;
 int64_t sectors;
 int64_t end_sector;
+int64_t flat_start_offset;
 int64_t l1_table_offset;
 int64_t l1_backup_table_offset;
 uint32_t *l1_table;
@@ -407,9 +408,10 @@ fail:
 static int vmdk_parent_open(BlockDriverState *bs)
 {
 char *p_name;
-char desc[DESC_SIZE];
+char desc[DESC_SIZE + 1];
 BDRVVmdkState *s = bs-opaque;
 
+desc[DESC_SIZE] = '\0';
 if (bdrv_pread(bs-file, s-desc_offset, desc, DESC_SIZE) != DESC_SIZE) {
 return -1;
 }
@@ -584,6 +586,145 @@ static int vmdk_open_vmdk4(BlockDriverState *bs, int 
flags)
 return ret;
 }
 
+/* find an option value out of descriptor file */
+static int vmdk_parse_description(const char *desc, const char *opt_name,
+char *buf, int buf_size)
+{
+char *opt_pos, *opt_end;
+const char *end = desc + strlen(desc);
+
+opt_pos = strstr(desc, opt_name);
+if (!opt_pos) {
+return -1;
+}
+/* Skip =\ following opt_name */
+opt_pos += strlen(opt_name) + 2;
+if (opt_pos = end) {
+return -1;
+}
+opt_end = opt_pos;
+while (opt_end  end  *opt_end != '') {
+opt_end++;
+}
+if (opt_end == end || buf_size  opt_end - opt_pos + 1) {
+return -1;
+}
+pstrcpy(buf, opt_end - opt_pos + 1, opt_pos);
+return 0;
+}
+
+static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
+const char *desc_file_path)
+{
+int ret;
+char access[11];
+char type[11];
+char fname[512];
+const char *p = desc;
+int64_t sectors = 0;
+int64_t flat_offset;
+
+while (*p) {
+/* parse extent line:
+ * RW [size in sectors] FLAT file-name.vmdk OFFSET
+ * or
+ * RW [size in sectors] SPARSE file-name.vmdk
+ */
+flat_offset = -1;
+ret = sscanf(p, %10s %lld %10s %512s,
+access, sectors, type, fname);
+if (ret != 4) {
+goto next_line;
+}
+if (!strcmp(type, FLAT)) {
+ret = sscanf(p, %10s %lld %10s %511s %lld,
+access, sectors, type, fname, flat_offset);
+if (ret != 5 || flat_offset  0) {
+return -EINVAL;
+}
+}
+
+/* trim the quotation marks around */
+if (fname[0] == '') {
+memmove(fname, fname + 1, strlen(fname));
+if (strlen(fname) = 1 || fname[strlen(fname) - 1] != '') {
+return -EINVAL;
+}
+fname[strlen(fname) - 1] = '\0';
+}
+if (sectors = 0 ||
+(strcmp(type, FLAT)  strcmp(type, SPARSE)) ||
+(strcmp(access, RW))) {
+goto next_line;
+}
+
+/* save to extents array */
+if (!strcmp(type, FLAT)) {
+/* FLAT extent */
+char extent_path[PATH_MAX];
+BlockDriverState *extent_file;
+VmdkExtent *extent;
+
+path_combine(extent_path, sizeof(extent_path),
+desc_file_path, fname);
+ret = bdrv_file_open(extent_file, extent_path, bs-open_flags);
+if (ret) {
+return ret;
+}
+extent = vmdk_add_extent(bs, extent_file, true, sectors,
+0, 0, 0, 0, sectors);
+extent-flat_start_offset = flat_offset;
+} else {
+/* SPARSE extent, not supported for now */
+fprintf(stderr,
+VMDK: Not supported extent type \%s\.\n, type);
+return -ENOTSUP;
+}
+next_line:
+/* move to next line */
+while (*p  *p != '\n') {
+p++;
+}
+p++;
+}
+return 0;
+}
+
+static int vmdk_open_desc_file(BlockDriverState *bs, int flags)
+{
+int ret;
+char buf[2048];
+char ct[128];
+BDRVVmdkState *s = bs-opaque;
+
+ret = bdrv_pread(bs-file, 0, buf, sizeof(buf));
+if (ret  0) {
+return ret;
+}
+buf[2047] = '\0';
+if (vmdk_parse_description(buf, createType, ct, sizeof(ct))) {
+return -EINVAL;
+}
+if (strcmp(ct, monolithicFlat)) {
+fprintf(stderr,
+VMDK: Not supported image type \%s\.\n, ct);
+return -ENOTSUP;
+}
+s-desc_offset = 0;
+ret = vmdk_parse_extents(buf, bs, bs-file-filename);
+if (ret) {
+return ret;
+}
+
+/* try to open parent images, if exist */
+if (vmdk_parent_open(bs)) {
+qemu_free(s-extents);
+return -EINVAL;
+}
+s-parent_cid = vmdk_read_cid(bs, 1);
+

[Qemu-devel] [PATCH v8 02/12] VMDK: bugfix, align offset to cluster in get_whole_cluster

2011-07-05 Thread Fam Zheng
In get_whole_cluster, the offset is not aligned to cluster when reading
from backing_hd. When the first write to child is not at the cluster
boundary, wrong address data from parent is copied to child.

Signed-off-by: Fam Zheng famc...@gmail.com
---
 block/vmdk.c |8 +---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index 3b78583..03a4619 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -514,21 +514,23 @@ static int get_whole_cluster(BlockDriverState *bs,
 /* 128 sectors * 512 bytes each = grain size 64KB */
 uint8_t  whole_grain[extent-cluster_sectors * 512];
 
-// we will be here if it's first write on non-exist grain(cluster).
-// try to read from parent image, if exist
+/* we will be here if it's first write on non-exist grain(cluster).
+ * try to read from parent image, if exist */
 if (bs-backing_hd) {
 int ret;
 
 if (!vmdk_is_cid_valid(bs))
 return -1;
 
+/* floor offset to cluster */
+offset -= offset % (extent-cluster_sectors * 512);
 ret = bdrv_read(bs-backing_hd, offset  9, whole_grain,
 extent-cluster_sectors);
 if (ret  0) {
 return -1;
 }
 
-//Write grain only into the active image
+/* Write grain only into the active image */
 ret = bdrv_write(extent-file, cluster_offset, whole_grain,
 extent-cluster_sectors);
 if (ret  0) {



[Qemu-devel] [PATCH v8 11/12] VMDK: fix coding style

2011-07-05 Thread Fam Zheng
Conform coding style in vmdk.c to pass scripts/checkpatch.pl checks.

Signed-off-by: Fam Zheng famc...@gmail.com
---
 block/vmdk.c |   79 +++--
 1 files changed, 48 insertions(+), 31 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index 0f51332..1084db8 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -102,8 +102,9 @@ static int vmdk_probe(const uint8_t *buf, int buf_size, 
const char *filename)
 {
 uint32_t magic;
 
-if (buf_size  4)
+if (buf_size  4) {
 return 0;
+}
 magic = be32_to_cpu(*(uint32_t *)buf);
 if (magic == VMDK3_MAGIC ||
 magic == VMDK4_MAGIC) {
@@ -192,9 +193,10 @@ static uint32_t vmdk_read_cid(BlockDriverState *bs, int 
parent)
 cid_str_size = sizeof(CID);
 }
 
-if ((p_name = strstr(desc,cid_str)) != NULL) {
+p_name = strstr(desc, cid_str);
+if (p_name != NULL) {
 p_name += cid_str_size;
-sscanf(p_name,%x,cid);
+sscanf(p_name, %x, cid);
 }
 
 return cid;
@@ -211,9 +213,10 @@ static int vmdk_write_cid(BlockDriverState *bs, uint32_t 
cid)
 return -EIO;
 }
 
-tmp_str = strstr(desc,parentCID);
+tmp_str = strstr(desc, parentCID);
 pstrcpy(tmp_desc, sizeof(tmp_desc), tmp_str);
-if ((p_name = strstr(desc,CID)) != NULL) {
+p_name = strstr(desc, CID);
+if (p_name != NULL) {
 p_name += sizeof(CID);
 snprintf(p_name, sizeof(desc) - (p_name - desc), %x\n, cid);
 pstrcat(desc, sizeof(desc), tmp_desc);
@@ -233,13 +236,14 @@ static int vmdk_is_cid_valid(BlockDriverState *bs)
 uint32_t cur_pcid;
 
 if (p_bs) {
-cur_pcid = vmdk_read_cid(p_bs,0);
-if (s-parent_cid != cur_pcid)
-// CID not valid
+cur_pcid = vmdk_read_cid(p_bs, 0);
+if (s-parent_cid != cur_pcid) {
+/* CID not valid */
 return 0;
+}
 }
 #endif
-// CID valid
+/* CID valid */
 return 1;
 }
 
@@ -254,14 +258,18 @@ static int vmdk_parent_open(BlockDriverState *bs)
 return -1;
 }
 
-if ((p_name = strstr(desc,parentFileNameHint)) != NULL) {
+p_name = strstr(desc, parentFileNameHint);
+if (p_name != NULL) {
 char *end_name;
 
 p_name += sizeof(parentFileNameHint) + 1;
-if ((end_name = strchr(p_name,'\')) == NULL)
+end_name = strchr(p_name, '\');
+if (end_name == NULL) {
 return -1;
-if ((end_name - p_name)  sizeof (bs-backing_file) - 1)
+}
+if ((end_name - p_name)  sizeof(bs-backing_file) - 1) {
 return -1;
+}
 
 pstrcpy(bs-backing_file, end_name - p_name + 1, p_name);
 }
@@ -595,8 +603,9 @@ static int get_whole_cluster(BlockDriverState *bs,
 if (bs-backing_hd) {
 int ret;
 
-if (!vmdk_is_cid_valid(bs))
+if (!vmdk_is_cid_valid(bs)) {
 return -1;
+}
 
 /* floor offset to cluster */
 offset -= offset % (extent-cluster_sectors * 512);
@@ -655,8 +664,9 @@ static int get_cluster_offset(BlockDriverState *bs,
 int min_index, i, j;
 uint32_t min_count, *l2_table, tmp = 0;
 
-if (m_data)
+if (m_data) {
 m_data-valid = 0;
+}
 if (extent-flat) {
 *cluster_offset = extent-flat_start_offset;
 return 0;
@@ -712,7 +722,7 @@ static int get_cluster_offset(BlockDriverState *bs,
 return -1;
 }
 
-// Avoid the L2 tables update for the images that have snapshots.
+/* Avoid the L2 tables update for the images that have snapshots. */
 *cluster_offset = bdrv_getlength(extent-file);
 bdrv_truncate(
 extent-file,
@@ -729,8 +739,9 @@ static int get_cluster_offset(BlockDriverState *bs,
  * or inappropriate VM shutdown.
  */
 if (get_whole_cluster(
-bs, extent, *cluster_offset, offset, allocate) == -1)
+bs, extent, *cluster_offset, offset, allocate) == -1) {
 return -1;
+}
 
 if (m_data) {
 m_data-offset = tmp;
@@ -780,8 +791,9 @@ static int vmdk_is_allocated(BlockDriverState *bs, int64_t 
sector_num,
 
 index_in_cluster = sector_num % extent-cluster_sectors;
 n = extent-cluster_sectors - index_in_cluster;
-if (n  nb_sectors)
+if (n  nb_sectors) {
 n = nb_sectors;
+}
 *pnum = n;
 return ret;
 }
@@ -805,16 +817,19 @@ static int vmdk_read(BlockDriverState *bs, int64_t 
sector_num,
 sector_num  9, 0, cluster_offset);
 index_in_cluster = sector_num % extent-cluster_sectors;
 n = extent-cluster_sectors - index_in_cluster;
-if (n  nb_sectors)
+if (n  nb_sectors) {
 n = nb_sectors;
+}
 if (ret) {
 /* if not allocated, try to read from parent image, if exist */
 if (bs-backing_hd) {
-if (!vmdk_is_cid_valid(bs))
+ 

[Qemu-devel] [PATCH v8 03/12] VMDK: probe for monolithicFlat images

2011-07-05 Thread Fam Zheng
Probe as the same behavior as VMware does.
Recognize image as monolithicFlat descriptor file when the file is text
and the first effective line (not '#' leaded comment or space line) is
either 'version=1' or 'version=2'. No space or upper case charactors
accepted.

Signed-off-by: Fam Zheng famc...@gmail.com
---
 block/vmdk.c |   45 +++--
 1 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index 03a4619..f8a815c 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -103,10 +103,51 @@ static int vmdk_probe(const uint8_t *buf, int buf_size, 
const char *filename)
 return 0;
 magic = be32_to_cpu(*(uint32_t *)buf);
 if (magic == VMDK3_MAGIC ||
-magic == VMDK4_MAGIC)
+magic == VMDK4_MAGIC) {
 return 100;
-else
+} else {
+const char *p = (const char *)buf;
+const char *end = p + buf_size;
+while (p  end) {
+if (*p == '#') {
+/* skip comment line */
+while (p  end  *p != '\n') {
+p++;
+}
+p++;
+continue;
+}
+if (*p == ' ') {
+while (p  end  *p == ' ') {
+p++;
+}
+/* skip '\r' if windows line endings used. */
+if (p  end  *p == '\r') {
+p++;
+}
+/* only accept blank lines before 'version=' line */
+if (p == end || *p != '\n') {
+return 0;
+}
+p++;
+continue;
+}
+if (end - p = strlen(version=X\n)) {
+if (strncmp(version=1\n, p, strlen(version=1\n)) == 0 ||
+strncmp(version=2\n, p, strlen(version=2\n)) == 0) {
+return 100;
+}
+}
+if (end - p = strlen(version=X\r\n)) {
+if (strncmp(version=1\r\n, p, strlen(version=1\r\n)) == 0 
||
+strncmp(version=2\r\n, p, strlen(version=2\r\n)) == 0) 
{
+return 100;
+}
+}
+return 0;
+}
 return 0;
+}
 }
 
 #define CHECK_CID 1



[Qemu-devel] [PATCH v8 04/12] VMDK: separate vmdk_open by format version

2011-07-05 Thread Fam Zheng
Separate vmdk_open by subformats to:
* vmdk_open_vmdk3
* vmdk_open_vmdk4

Signed-off-by: Fam Zheng famc...@gmail.com
---
 block/vmdk.c |  178 -
 1 files changed, 112 insertions(+), 66 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index f8a815c..6d7b497 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -458,67 +458,20 @@ static VmdkExtent *vmdk_add_extent(BlockDriverState *bs,
 return extent;
 }
 
-
-static int vmdk_open(BlockDriverState *bs, int flags)
+static int vmdk_init_tables(BlockDriverState *bs, VmdkExtent *extent)
 {
-BDRVVmdkState *s = bs-opaque;
-uint32_t magic;
-int i;
-uint32_t l1_size, l1_entry_sectors;
-VmdkExtent *extent = NULL;
-
-if (bdrv_pread(bs-file, 0, magic, sizeof(magic)) != sizeof(magic))
-goto fail;
-
-magic = be32_to_cpu(magic);
-if (magic == VMDK3_MAGIC) {
-VMDK3Header header;
-if (bdrv_pread(bs-file, sizeof(magic), header, sizeof(header))
-!= sizeof(header)) {
-goto fail;
-}
-extent = vmdk_add_extent(bs, bs-file, false,
-  le32_to_cpu(header.disk_sectors),
-  le32_to_cpu(header.l1dir_offset)  9, 0,
-  1  6, 1  9, le32_to_cpu(header.granularity));
-} else if (magic == VMDK4_MAGIC) {
-VMDK4Header header;
-if (bdrv_pread(bs-file, sizeof(magic), header, sizeof(header))
-!= sizeof(header)) {
-goto fail;
-}
-l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gte)
-* le64_to_cpu(header.granularity);
-l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1)
-/ l1_entry_sectors;
-extent = vmdk_add_extent(bs, bs-file, false,
-  le64_to_cpu(header.capacity),
-  le64_to_cpu(header.gd_offset)  9,
-  le64_to_cpu(header.rgd_offset)  9,
-  l1_size,
-  le32_to_cpu(header.num_gtes_per_gte),
-  le64_to_cpu(header.granularity));
-if (extent-l1_entry_sectors = 0) {
-goto fail;
-}
-// try to open parent images, if exist
-if (vmdk_parent_open(bs) != 0)
-goto fail;
-// write the CID once after the image creation
-s-parent_cid = vmdk_read_cid(bs,1);
-} else {
-goto fail;
-}
+int ret;
+int l1_size, i;
 
 /* read the L1 table */
 l1_size = extent-l1_size * sizeof(uint32_t);
 extent-l1_table = qemu_malloc(l1_size);
-if (bdrv_pread(bs-file,
-extent-l1_table_offset,
-extent-l1_table,
-l1_size)
-!= l1_size) {
-goto fail;
+ret = bdrv_pread(extent-file,
+extent-l1_table_offset,
+extent-l1_table,
+l1_size);
+if (ret  0) {
+goto fail_l1;
 }
 for (i = 0; i  extent-l1_size; i++) {
 le32_to_cpus(extent-l1_table[i]);
@@ -526,12 +479,12 @@ static int vmdk_open(BlockDriverState *bs, int flags)
 
 if (extent-l1_backup_table_offset) {
 extent-l1_backup_table = qemu_malloc(l1_size);
-if (bdrv_pread(bs-file,
-extent-l1_backup_table_offset,
-extent-l1_backup_table,
-l1_size)
-!= l1_size) {
-goto fail;
+ret = bdrv_pread(extent-file,
+extent-l1_backup_table_offset,
+extent-l1_backup_table,
+l1_size);
+if (ret  0) {
+goto fail_l1b;
 }
 for (i = 0; i  extent-l1_size; i++) {
 le32_to_cpus(extent-l1_backup_table[i]);
@@ -541,9 +494,102 @@ static int vmdk_open(BlockDriverState *bs, int flags)
 extent-l2_cache =
 qemu_malloc(extent-l2_size * L2_CACHE_SIZE * sizeof(uint32_t));
 return 0;
+ fail_l1b:
+qemu_free(extent-l1_backup_table);
+ fail_l1:
+qemu_free(extent-l1_table);
+return ret;
+}
+
+static int vmdk_open_vmdk3(BlockDriverState *bs, int flags)
+{
+int ret;
+uint32_t magic;
+VMDK3Header header;
+VmdkExtent *extent;
+
+ret = bdrv_pread(bs-file, sizeof(magic), header, sizeof(header));
+if (ret  0) {
+goto fail;
+}
+extent = vmdk_add_extent(bs,
+ bs-file, false,
+ le32_to_cpu(header.disk_sectors),
+ le32_to_cpu(header.l1dir_offset)  9,
+ 0, 1  6, 1  9,
+ le32_to_cpu(header.granularity));
+ret = vmdk_init_tables(bs, extent);
+if (ret) {
+/* vmdk_init_tables cleans up on fail, so only free allocation of
+ * vmdk_add_extent here. */
+goto fail;
+}
+return 0;
  

[Qemu-devel] [PATCH v8 06/12] VMDK: flush multiple extents

2011-07-05 Thread Fam Zheng
Flush all the file that referenced by the image.

Signed-off-by: Fam Zheng famc...@gmail.com
---
 block/vmdk.c |   12 +++-
 1 files changed, 11 insertions(+), 1 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index 529ae90..f6d2986 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1072,7 +1072,17 @@ static void vmdk_close(BlockDriverState *bs)
 
 static int vmdk_flush(BlockDriverState *bs)
 {
-return bdrv_flush(bs-file);
+int i, ret, err;
+BDRVVmdkState *s = bs-opaque;
+
+ret = bdrv_flush(bs-file);
+for (i = 0; i  s-num_extents; i++) {
+err = bdrv_flush(s-extents[i].file);
+if (err  0) {
+ret = err;
+}
+}
+return ret;
 }
 
 



[Qemu-devel] [PATCH v8 08/12] VMDK: change get_cluster_offset return type

2011-07-05 Thread Fam Zheng
The return type of get_cluster_offset was an offset that use 0 to denote
'not allocated', this will be no longer true for flat extents, as we see
flat extent file as a single huge cluster whose offset is 0 and length
is the whole file length.
So now we use int return value, 0 means success and otherwise offset
invalid.

Signed-off-by: Fam Zheng famc...@gmail.com
---
 block/vmdk.c |   79 ++---
 1 files changed, 42 insertions(+), 37 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index 8dc58a8..f637d98 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -665,26 +665,31 @@ static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData 
*m_data)
 return 0;
 }
 
-static uint64_t get_cluster_offset(BlockDriverState *bs,
+static int get_cluster_offset(BlockDriverState *bs,
 VmdkExtent *extent,
 VmdkMetaData *m_data,
-uint64_t offset, int allocate)
+uint64_t offset,
+int allocate,
+uint64_t *cluster_offset)
 {
 unsigned int l1_index, l2_offset, l2_index;
 int min_index, i, j;
 uint32_t min_count, *l2_table, tmp = 0;
-uint64_t cluster_offset;
 
 if (m_data)
 m_data-valid = 0;
+if (extent-flat) {
+*cluster_offset = 0;
+return 0;
+}
 
 l1_index = (offset  9) / extent-l1_entry_sectors;
 if (l1_index = extent-l1_size) {
-return 0;
+return -1;
 }
 l2_offset = extent-l1_table[l1_index];
 if (!l2_offset) {
-return 0;
+return -1;
 }
 for (i = 0; i  L2_CACHE_SIZE; i++) {
 if (l2_offset == extent-l2_cache_offsets[i]) {
@@ -714,28 +719,29 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
 l2_table,
 extent-l2_size * sizeof(uint32_t)
 ) != extent-l2_size * sizeof(uint32_t)) {
-return 0;
+return -1;
 }
 
 extent-l2_cache_offsets[min_index] = l2_offset;
 extent-l2_cache_counts[min_index] = 1;
  found:
 l2_index = ((offset  9) / extent-cluster_sectors) % extent-l2_size;
-cluster_offset = le32_to_cpu(l2_table[l2_index]);
+*cluster_offset = le32_to_cpu(l2_table[l2_index]);
 
-if (!cluster_offset) {
-if (!allocate)
-return 0;
+if (!*cluster_offset) {
+if (!allocate) {
+return -1;
+}
 
 // Avoid the L2 tables update for the images that have snapshots.
-cluster_offset = bdrv_getlength(extent-file);
+*cluster_offset = bdrv_getlength(extent-file);
 bdrv_truncate(
 extent-file,
-cluster_offset + (extent-cluster_sectors  9)
+*cluster_offset + (extent-cluster_sectors  9)
 );
 
-cluster_offset = 9;
-tmp = cpu_to_le32(cluster_offset);
+*cluster_offset = 9;
+tmp = cpu_to_le32(*cluster_offset);
 l2_table[l2_index] = tmp;
 
 /* First of all we write grain itself, to avoid race condition
@@ -744,8 +750,8 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
  * or inappropriate VM shutdown.
  */
 if (get_whole_cluster(
-bs, extent, cluster_offset, offset, allocate) == -1)
-return 0;
+bs, extent, *cluster_offset, offset, allocate) == -1)
+return -1;
 
 if (m_data) {
 m_data-offset = tmp;
@@ -755,8 +761,8 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
 m_data-valid = 1;
 }
 }
-cluster_offset = 9;
-return cluster_offset;
+*cluster_offset = 9;
+return 0;
 }
 
 static VmdkExtent *find_extent(BDRVVmdkState *s,
@@ -780,7 +786,6 @@ static int vmdk_is_allocated(BlockDriverState *bs, int64_t 
sector_num,
  int nb_sectors, int *pnum)
 {
 BDRVVmdkState *s = bs-opaque;
-
 int64_t index_in_cluster, n, ret;
 uint64_t offset;
 VmdkExtent *extent;
@@ -789,15 +794,13 @@ static int vmdk_is_allocated(BlockDriverState *bs, 
int64_t sector_num,
 if (!extent) {
 return 0;
 }
-if (extent-flat) {
-n = extent-end_sector - sector_num;
-ret = 1;
-} else {
-offset = get_cluster_offset(bs, extent, NULL, sector_num * 512, 0);
-index_in_cluster = sector_num % extent-cluster_sectors;
-n = extent-cluster_sectors - index_in_cluster;
-ret = offset ? 1 : 0;
-}
+ret = get_cluster_offset(bs, extent, NULL,
+sector_num * 512, 0, offset);
+/* get_cluster_offset returning 0 means success */
+ret = !ret;
+
+index_in_cluster = sector_num % extent-cluster_sectors;
+n = extent-cluster_sectors - index_in_cluster;
 if (n  nb_sectors)
 n = nb_sectors;
 *pnum = n;
@@ -818,14 +821,15 @@ static int 

Re: [Qemu-devel] KVM call agenda for June 28

2011-07-05 Thread Stefan Hajnoczi
On Tue, Jul 5, 2011 at 9:01 AM, Dor Laor dl...@redhat.com wrote:
 I tried to re-arrange all of the requirements and use cases using this wiki
 page: http://wiki.qemu.org/Features/LiveBlockMigration

 It would be the best to agree upon the most interesting use cases (while we
 make sure we cover future ones) and agree to them.
 The next step is to set the interface for all the various verbs since the
 implementation seems to be converging.

Live block copy was supposed to support snapshot merge.  I think the
current favored approach is to make the source image a backing file to
the destination image and essentially do image streaming.

Using this mechanism for snapshot merge is tricky.  The COW file
already uses the read-only snapshot base image.  So now we cannot
trivally copy the COW file contents back into the snapshot base image
using live block copy.

It seems like snapshot merge will require dedicated code that reads
the allocated clusters from the COW file and writes them back into the
base image.

A very inefficient alternative would be to create a third image, the
merge image file, which has the COW file as its backing file:
snapshot (base) - cow - merge

All data from snapshot and cow is copied into merge and then snapshot
and cow can be deleted.  But this approach is results in full data
copying and uses potentially 3x space if cow is close to the size of
snapshot.

Any other ideas that reuse live block copy for snapshot merge?

Stefan



[Qemu-devel] [PATCH v8 12/12] block: add bdrv_get_allocated_file_size() operation

2011-07-05 Thread Fam Zheng
qemu-img.c wants to count allocated file size of image. Previously it
counts a single bs-file by 'stat' or Window API. As VMDK introduces
multiple file support, the operation becomes format specific with
platform specific meanwhile.

The functions are moved to block/raw-{posix,win32}.c and qemu-img.c calls
bdrv_get_allocated_file_size to count the bs. And also added VMDK code
to count his own extents.

Signed-off-by: Fam Zheng famc...@gmail.com
---
 block.c   |   19 +++
 block.h   |1 +
 block/raw-posix.c |   21 +
 block/raw-win32.c |   29 +
 block/vmdk.c  |   24 
 block_int.h   |1 +
 qemu-img.c|   31 +--
 7 files changed, 96 insertions(+), 30 deletions(-)

diff --git a/block.c b/block.c
index 24a25d5..9549b9e 100644
--- a/block.c
+++ b/block.c
@@ -1147,6 +1147,25 @@ int bdrv_truncate(BlockDriverState *bs, int64_t offset)
 }
 
 /**
+ * Length of a allocated file in bytes. Sparse files are counted by actual
+ * allocated space. Return  0 if error or unknown.
+ */
+int64_t bdrv_get_allocated_file_size(BlockDriverState *bs)
+{
+BlockDriver *drv = bs-drv;
+if (!drv) {
+return -ENOMEDIUM;
+}
+if (drv-bdrv_get_allocated_file_size) {
+return drv-bdrv_get_allocated_file_size(bs);
+}
+if (bs-file) {
+return bdrv_get_allocated_file_size(bs-file);
+}
+return -ENOTSUP;
+}
+
+/**
  * Length of a file in bytes. Return  0 if error or unknown.
  */
 int64_t bdrv_getlength(BlockDriverState *bs)
diff --git a/block.h b/block.h
index 859d1d9..59cc410 100644
--- a/block.h
+++ b/block.h
@@ -89,6 +89,7 @@ int bdrv_write_sync(BlockDriverState *bs, int64_t sector_num,
 const uint8_t *buf, int nb_sectors);
 int bdrv_truncate(BlockDriverState *bs, int64_t offset);
 int64_t bdrv_getlength(BlockDriverState *bs);
+int64_t bdrv_get_allocated_file_size(BlockDriverState *bs);
 void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
 void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int 
*psecs);
 int bdrv_commit(BlockDriverState *bs);
diff --git a/block/raw-posix.c b/block/raw-posix.c
index 4cd7d7a..911cc0d 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -791,6 +791,17 @@ static int64_t raw_getlength(BlockDriverState *bs)
 }
 #endif
 
+static int64_t raw_get_allocated_file_size(BlockDriverState *bs)
+{
+struct stat st;
+BDRVRawState *s = bs-opaque;
+
+if (fstat(s-fd, st)  0) {
+return -errno;
+}
+return (int64_t)st.st_blocks * 512;
+}
+
 static int raw_create(const char *filename, QEMUOptionParameter *options)
 {
 int fd;
@@ -886,6 +897,8 @@ static BlockDriver bdrv_file = {
 
 .bdrv_truncate = raw_truncate,
 .bdrv_getlength = raw_getlength,
+.bdrv_get_allocated_file_size
+= raw_get_allocated_file_size,
 
 .create_options = raw_create_options,
 };
@@ -1154,6 +1167,8 @@ static BlockDriver bdrv_host_device = {
 .bdrv_read  = raw_read,
 .bdrv_write = raw_write,
 .bdrv_getlength= raw_getlength,
+.bdrv_get_allocated_file_size
+= raw_get_allocated_file_size,
 
 /* generic scsi device */
 #ifdef __linux__
@@ -1269,6 +1284,8 @@ static BlockDriver bdrv_host_floppy = {
 .bdrv_read  = raw_read,
 .bdrv_write = raw_write,
 .bdrv_getlength= raw_getlength,
+.bdrv_get_allocated_file_size
+= raw_get_allocated_file_size,
 
 /* removable device support */
 .bdrv_is_inserted   = floppy_is_inserted,
@@ -1366,6 +1383,8 @@ static BlockDriver bdrv_host_cdrom = {
 .bdrv_read  = raw_read,
 .bdrv_write = raw_write,
 .bdrv_getlength = raw_getlength,
+.bdrv_get_allocated_file_size
+= raw_get_allocated_file_size,
 
 /* removable device support */
 .bdrv_is_inserted   = cdrom_is_inserted,
@@ -1489,6 +1508,8 @@ static BlockDriver bdrv_host_cdrom = {
 .bdrv_read  = raw_read,
 .bdrv_write = raw_write,
 .bdrv_getlength = raw_getlength,
+.bdrv_get_allocated_file_size
+= raw_get_allocated_file_size,
 
 /* removable device support */
 .bdrv_is_inserted   = cdrom_is_inserted,
diff --git a/block/raw-win32.c b/block/raw-win32.c
index 56bd719..91067e7 100644
--- a/block/raw-win32.c
+++ b/block/raw-win32.c
@@ -213,6 +213,31 @@ static int64_t raw_getlength(BlockDriverState *bs)
 return l.QuadPart;
 }
 
+static int64_t raw_get_allocated_file_size(BlockDriverState *bs)
+{
+typedef DWORD (WINAPI * get_compressed_t)(const char *filename,
+  DWORD * high);
+get_compressed_t get_compressed;
+struct _stati64 st;
+const char *filename = bs-filename;
+/* WinNT support GetCompressedFileSize to determine allocate size */
+

[Qemu-devel] [QAPI+QGA 2/3] QAPI code generation infrastructure v5

2011-07-05 Thread Michael Roth
This is Set 2/3 of the QAPI+QGA patchsets.

These patches apply on top of master (set1 merged), and can also be obtained
from:
git://repo.or.cz/qemu/mdroth.git qapi-backport-set2-v5

(Set1+2 are a backport of some of the QAPI-related work from Anthony's
glib tree. The main goal is to get the basic code generation infrastructure in
place so that it can be used by the guest agent to implement a QMP-like guest
interface, and so that future work regarding the QMP conversion to QAPI can be
decoupled from the infrastructure bits. Set3 is the Qemu Guest Agent
(virtagent), rebased on the new code QAPI code generation infrastructure. This
is the first user of QAPI, QMP will follow.)
___

This patchset introduces the following:

 - Hard dependency on GLib. This has been floating around the list for a while.
   Currently the only users are the unit tests for this patchset and the guest
   agent. We can make both of these a configure option, but based on previous
   discussions a hard dependency will likely be introduced with subsequent
   QAPI patches.

 - A couple additional qlist utility functions used by QAPI.

 - QAPI schema-based code generation for synchronous QMP/QGA commands
   and types, and Visitor/dispatch infrastructure to handle
   marshaling/unmarshaling/dispatch between QAPI and the QMP/QGA wire protocols.

 - Documentation and unit tests for visitor functions and synchronous
   command/type generation.

CHANGES SINCE V4:
 - Fix segfault in output visitor when dealing with QAPI-defined C structs
   with NULL pointers

CHANGES SINCE V3:
 - Added copyright headers for generated code and remaining files
 - Added checking for required/extra parameters in top-level of QMP QObject
 - Made QDict arg to input visitor constructor a const
 - Renamed qmp_dispatch_err() - do_qmp_dispatch()
 - Changed QERR_QAPI_STACK_OVERRUN to QERR_BUFFER_OVERRUN
 - Moved configure changes to create QAPI directory when using a different build
   root to first patch which uses it.
 - Squashed Makefile changes for test-visitor/test-qmp-commands into single
   commits
 - Removed redundant NULL checks for qemu_free() in dealloc visitor

CHANGES SINCE V2:
 - Added cleanup functions for input/output visitor types and fixed a leak in
   dispatch path.
 - Corrected spelling from visiter-visitor and updated filenames accordingly.
 - Re-organized patches so that each new C file can be built as part of the
   introducting commit (for instances where there were no users of the
   qapi-obj-y target yet a test build was done by adding the target as a
   superficial dependency on other tools), and moved code generator patches
   after the required dependencies.
 - Made qlist_first/qlist_next accept/return const types.
 - Moved Visitor interface inline wrapper functions to real ones.
 - Fixed error-reporting for invalid parameters when parameter name is null.
 - Removed hard-coded size for QAPI-type allocations done by the input visitor,
   using generated code to pass in a sizeof() now.
 - Replaced assert()'s on visitor stack overruns, replaced with an error
   indication.
 - Fixed build issue when using a separate build directory.
 - Added missing copyright headers for scripts, moved external code in
   ordereddict.py to a seperate patch.
 - Many thanks to Luiz, Anthony, and everyone else for the excellent
   review/testing.

CHANGES SINCE V1:
 - Fixed build issue that was missed due to deprecated files being present in
   source tree. Thanks to Matsuda Daiki for sending fixes.
 - Fixed grammatical errors in documentation pointed out by Luiz.
 - Added generated code to the make clean target.

CHANGES SINCE V0 (QAPI Infrastructure Round 1):
 - Fixed known memory leaks in generated code
 - Stricter error-handling in generated code
 - Removed currently unused code (generators for events and async/proxied
   QMP/QGA commands and definition used by the not-yet-introduced QMP server
   replacement)
 - Added documentation for code generation scripts/schemas/usage
 - Addressed review comments from Luiz and Stefan

 Makefile|   24 +++-
 Makefile.objs   |9 +
 Makefile.target |1 +
 configure   |   14 ++
 docs/qapi-code-gen.txt  |  316 +++
 module.h|2 +
 qapi-schema-test.json   |   22 +++
 qapi/qapi-dealloc-visitor.c |  138 
 qapi/qapi-dealloc-visitor.h |   26 +++
 qapi/qapi-types-core.h  |   21 +++
 qapi/qapi-visit-core.c  |  114 +
 qapi/qapi-visit-core.h  |   68 
 qapi/qmp-core.h |   41 +
 qapi/qmp-dispatch.c |  124 ++
 qapi/qmp-input-visitor.c|  264 ++
 qapi/qmp-input-visitor.h|   27 +++
 qapi/qmp-output-visitor.c   |  216 
 qapi/qmp-output-visitor.h   |   28 +++
 qapi/qmp-registry.c |   40 +
 qerror.h|3 +
 qlist.h |   11 ++
 

Re: [Qemu-devel] [PATCH 0/5][v6] Megasas HBA emulation

2011-07-05 Thread Alexander Graf

On 07/05/2011 01:03 PM, Hannes Reinecke wrote:

Hi all,

as Alex Graf reminded me the driver needed some more bugfixing
to be done. I've found some issues and also moved the megasas
emulation over to the new trace infrastructure.
Driver works for me now and a full installation of
openSUSE-12.1 works perfectly.
I've also included the fixes suggested by Stefan Hajnoczi.
And during debugging I've found two minor issues in scsi_disk.c

Changes since v5:
- scsi-disk: Fixup debugging statement
   A debugging statement wasn't converted. Do so now.
- scsi-disk: Mask out serial number EVPD
   The 'serial' parameter to scsi-disk is optional. So if it's
   not set we should mask it out in the list of supported EVPD
   pages and not return '0' here.
- megasas: Use tracing infrastructure instead of DPRINTF
- megasas: Use new PCI infrastructure
- megasas: Check for iovec mapping failure
   cpu_map_physical_memory() might fail, so we need to check for
   it when mapping iovecs.
- megasas: Trace scsi buffer overflow
   The transfer length as specified in the SCSI command might
   disagree with the length of the iovec. We should be tracing
   these issues.
- megasas: Reset frames after init firmware
   When receiving an INIT FIRMWARE command we need reset all
   frames, otherwise some frames might point to invalid memory.

Chances since v4:
- iov: Update parameter usage in iov_(to|from)_buf()
   Updated description for the first patch and clarified the usage
   Renamed arguments for io_XXX for clarification
- scsi: Add 'hba_private' to SCSIRequest
   Kept 'tag' for tracing and just add 'hba_private' as an
   additional field as per request from Paolo
- megasas: checkpatch.pl fixes and update to work with the
   changed interface in scsi_req_new(). Also included the
   suggested fixes from Alex.


agraf@busu:~/patch-rest/hannes1 ~/git/qemu/scripts/checkpatch.pl *
total: 0 errors, 0 warnings, 112 lines checked

[PATCH 1_5] iov: Update parameter usage in iov_(to|from)_buf().eml has 
no obvious style problems and is ready for submission.

total: 0 errors, 0 warnings, 257 lines checked

[PATCH 2_5] scsi: Add 'hba_private' to SCSIRequest.eml has no obvious 
style problems and is ready for submission.

total: 0 errors, 0 warnings, 8 lines checked

[PATCH 3_5] scsi-disk: Fixup debugging statement.eml has no obvious 
style problems and is ready for submission.

WARNING: braces {} are necessary for all arms of this statement
#56: FILE: hw/scsi-disk.c:401:
+if (s-serial)
[...]

ERROR: do not use C99 // comments
#57: FILE: hw/scsi-disk.c:402:
+outbuf[buflen++] = 0x80; // unit serial number

total: 1 errors, 1 warnings, 34 lines checked

[PATCH 4_5] scsi-disk: Mask out serial number EVPD.eml has style 
problems, please review.  If any of these errors

are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
ERROR: space required after that ',' (ctx:VxV)
#482: FILE: hw/megasas.c:399:
+trace_megasas_frame_map_failed(cmd-index,(unsigned 
long)frame);

  ^

ERROR: space required after that ',' (ctx:VxV)
#673: FILE: hw/megasas.c:590:
+trace_megasas_dcmd_enter(cmd-index,MFI DCMD get controller info);
^

ERROR: space required after that ',' (ctx:VxV)
#748: FILE: hw/megasas.c:665:
+trace_megasas_dcmd_invalid_xfer_len(cmd-index,MFC Get defaults,
   ^

ERROR: space required after that ',' (ctx:VxV)
#774: FILE: hw/megasas.c:691:
+trace_megasas_dcmd_invalid_xfer_len(cmd-index,Get BIOS info,
   ^

ERROR: space required after that ',' (ctx:VxV)
#827: FILE: hw/megasas.c:744:
+trace_megasas_dcmd_invalid_xfer_len(cmd-index,PD get list,
   ^

ERROR: trailing whitespace
#3284: FILE: trace-events:339:
+disable megasas_handle_scsi(const char *frame, const char *desc, int 
dev, int lun, void *sdev, unsigned long size) %s %s dev %x/%x sdev %p 
xfer %lu $


ERROR: trailing whitespace
#3294: FILE: trace-events:349:
+disable megasas_handle_io(int cmd, const char *frame, int dev, int lun, 
unsigned long lba, unsigned long count) scmd %d: %s dev %x/%x lba %lx 
count %lu $


total: 7 errors, 0 warnings, 3255 lines checked

[PATCH 5_5] megasas: LSI Megaraid SAS emulation.eml has style problems, 
please review.  If any of these errors

are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.




Re: [Qemu-devel] KVM call agenda for June 28

2011-07-05 Thread Marcelo Tosatti
On Tue, Jul 05, 2011 at 01:40:08PM +0100, Stefan Hajnoczi wrote:
 On Tue, Jul 5, 2011 at 9:01 AM, Dor Laor dl...@redhat.com wrote:
  I tried to re-arrange all of the requirements and use cases using this wiki
  page: http://wiki.qemu.org/Features/LiveBlockMigration
 
  It would be the best to agree upon the most interesting use cases (while we
  make sure we cover future ones) and agree to them.
  The next step is to set the interface for all the various verbs since the
  implementation seems to be converging.
 
 Live block copy was supposed to support snapshot merge.  I think the
 current favored approach is to make the source image a backing file to
 the destination image and essentially do image streaming.
 
 Using this mechanism for snapshot merge is tricky.  The COW file
 already uses the read-only snapshot base image.  So now we cannot
 trivally copy the COW file contents back into the snapshot base image
 using live block copy.

It never did. Live copy creates a new image were both snapshot and
current are copied to.

This is similar with image streaming.

 It seems like snapshot merge will require dedicated code that reads
 the allocated clusters from the COW file and writes them back into the
 base image.
 
 A very inefficient alternative would be to create a third image, the
 merge image file, which has the COW file as its backing file:
 snapshot (base) - cow - merge
 
 All data from snapshot and cow is copied into merge and then snapshot
 and cow can be deleted.  But this approach is results in full data
 copying and uses potentially 3x space if cow is close to the size of
 snapshot.

Management can set a higher limit on the size of data that is merged,
and create a new base once exceeded. This avoids copying excessive
amounts of data.

 Any other ideas that reuse live block copy for snapshot merge?
 
 Stefan



[Qemu-devel] [PATCH v5 02/18] qlist: add qlist_first()/qlist_next()

2011-07-05 Thread Michael Roth

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 qlist.h |   11 +++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/qlist.h b/qlist.h
index dbe7b92..d426bd4 100644
--- a/qlist.h
+++ b/qlist.h
@@ -16,6 +16,7 @@
 #include qobject.h
 #include qemu-queue.h
 #include qemu-common.h
+#include qemu-queue.h
 
 typedef struct QListEntry {
 QObject *value;
@@ -50,4 +51,14 @@ QObject *qlist_peek(QList *qlist);
 int qlist_empty(const QList *qlist);
 QList *qobject_to_qlist(const QObject *obj);
 
+static inline const QListEntry *qlist_first(const QList *qlist)
+{
+return QTAILQ_FIRST(qlist-head);
+}
+
+static inline const QListEntry *qlist_next(const QListEntry *entry)
+{
+return QTAILQ_NEXT(entry, next);
+}
+
 #endif /* QLIST_H */
-- 
1.7.0.4




[Qemu-devel] [PATCH v5 01/18] Add hard build dependency on glib

2011-07-05 Thread Michael Roth
From: Anthony Liguori aligu...@us.ibm.com

GLib is an extremely common library that has a portable thread implementation
along with tons of other goodies.

GLib and GObject have a fantastic amount of infrastructure we can leverage in
QEMU including an object oriented programming infrastructure.

Short term, it has a very nice thread pool implementation that we could leverage
in something like virtio-9p.  It also has a test harness implementation that
this series will use.

Signed-off-by: Anthony Liguori aligu...@us.ibm.com
Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 Makefile|2 ++
 Makefile.objs   |2 ++
 Makefile.target |1 +
 configure   |   13 +
 4 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/Makefile b/Makefile
index b3ffbe2..42ae4e5 100644
--- a/Makefile
+++ b/Makefile
@@ -106,6 +106,8 @@ audio/audio.o audio/fmodaudio.o: QEMU_CFLAGS += 
$(FMOD_CFLAGS)
 
 QEMU_CFLAGS+=$(CURL_CFLAGS)
 
+QEMU_CFLAGS+=$(GLIB_CFLAGS)
+
 ui/cocoa.o: ui/cocoa.m
 
 ui/sdl.o audio/sdlaudio.o ui/sdl_zoom.o baum.o: QEMU_CFLAGS += $(SDL_CFLAGS)
diff --git a/Makefile.objs b/Makefile.objs
index cea15e4..493c988 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -376,3 +376,5 @@ vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
 
 vl.o: QEMU_CFLAGS+=$(SDL_CFLAGS)
 
+vl.o: QEMU_CFLAGS+=$(GLIB_CFLAGS)
+
diff --git a/Makefile.target b/Makefile.target
index a53a2ff..b8256ae 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -203,6 +203,7 @@ QEMU_CFLAGS += $(VNC_TLS_CFLAGS)
 QEMU_CFLAGS += $(VNC_SASL_CFLAGS)
 QEMU_CFLAGS += $(VNC_JPEG_CFLAGS)
 QEMU_CFLAGS += $(VNC_PNG_CFLAGS)
+QEMU_CFLAGS += $(GLIB_CFLAGS)
 
 # xen backend driver support
 obj-i386-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o
diff --git a/configure b/configure
index 88159ac..63156a2 100755
--- a/configure
+++ b/configure
@@ -1803,6 +1803,18 @@ EOF
 fi
 
 ##
+# glib support probe
+if $pkg_config --modversion gthread-2.0 gio-2.0  /dev/null 21 ; then
+glib_cflags=`$pkg_config --cflags gthread-2.0 gio-2.0 2/dev/null`
+glib_libs=`$pkg_config --libs gthread-2.0 gio-2.0 2/dev/null`
+libs_softmmu=$glib_libs $libs_softmmu
+libs_tools=$glib_libs $libs_tools
+else
+echo glib-2.0 required to compile QEMU
+exit 1
+fi
+
+##
 # pthread probe
 PTHREADLIBS_LIST=-lpthread -lpthreadGC2
 
@@ -2849,6 +2861,7 @@ if test $bluez = yes ; then
   echo CONFIG_BLUEZ=y  $config_host_mak
   echo BLUEZ_CFLAGS=$bluez_cflags  $config_host_mak
 fi
+echo GLIB_CFLAGS=$glib_cflags  $config_host_mak
 if test $xen = yes ; then
   echo CONFIG_XEN=y  $config_host_mak
   echo CONFIG_XEN_CTRL_INTERFACE_VERSION=$xen_ctrl_version  
$config_host_mak
-- 
1.7.0.4




[Qemu-devel] utimensat trouble on mips

2011-07-05 Thread Johannes Schauer
Hi,

I am following up on threads started here [1] and here [2]. I'm not
subscribed to qemu-devel so please dont forget to CC me.

About a year ago, Kenneth Johansson reported [1], that trying to do a
debian debootstrap using qemu user emulation will fail due to the
following error:

/bin/tar: ./postinst: Cannot utime: Level 2 not synchronized

Lisandro had a very similar issue [2]:

/usr/bin/touch: setting times of `tito': Level 2 not synchronized

Since I was also interested in bootstrapping debian using qemu user mode
emulation at some point I tracked down the error to the usage of
utimensat which results in a ENOSYS error (being translated to
EL2NSYNC).

Here is a quick and dirty C snippet that allows to reproduce the issue:

-%-
#include stdio.h
#include sys/stat.h
#include fcntl.h

int main()
{
int ret, fd, dir;

dir = open(., O_RDONLY);
fd = open(./foobar, O_WRONLY|O_CREAT, 0666);
ret = utimensat(dir, ./foobar, NULL, 0);
perror(utimensat);

return 0;
}
-%-

To see how different architectures behave when executing this, I
compiled it natively and crosscompiled it for arm and mips. I statically
compiled it to avoid shared library troubles. Because of binfmt support
I do not prepend qemu-mips or qemu-arm in the following.

$ gcc -Wall -static utimensat.c
$ file a.out
a.out: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically 
linked, for GNU/Linux 2.6.18, not stripped
$ ./a.out
utimensat: Success
$ arm-linux-gnueabi-gcc -Wall -static utimensat.c
$ file a.out
a.out: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, for 
GNU/Linux 2.6.18, not stripped
$ ./a.out
utimensat: Success
$ mips-linux-gnu-gcc -Wall -static utimensat.c
$ file a.out
a.out: ELF 32-bit MSB executable, MIPS, MIPS-I version 1 (SYSV), statically 
linked, for GNU/Linux 2.6.18, with unknown capability 0x4100 = 0xf676e75, 
with unknown capability 0x1 = 0x70401, not stripped
$ ./a.out
utimensat: Level 2 not synchronized
$ mipsel-linux-gnu-gcc -Wall -static utimensat.c
$ file a.out
a.out: ELF 32-bit LSB executable, MIPS, MIPS-I version 1 (SYSV), statically 
linked, for GNU/Linux 2.6.18, with unknown capability 0xf41 = 0x756e6700, with 
unknown capability 0x70100 = 0x104, not stripped
$ ./a.out
utimensat: Level 2 not synchronized

As one can see the error only shows on mips. It also occurs when
natively compiling above snippet on mips and it also occurs when using a
natively compiled `touch` binary for mips from the debian coreutils
package.

Now my questions are:

* why is this happening with mips?
* Whose fault is it?
* is it a qemu bug?
* should I open a bugreport about this issue?
* why was nobody else complaining about it, given that this is an issue
  for over a year now?

thank you

cheers, josch

[1] http://lists.gnu.org/archive/html/qemu-devel/2010-05/msg00116.html
[2] http://lists.gnu.org/archive/html/qemu-devel/2011-07/msg00102.html



[Qemu-devel] [PATCH v5 03/18] qapi: add module init types for qapi

2011-07-05 Thread Michael Roth

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 module.h |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/module.h b/module.h
index 9263f1c..ef66730 100644
--- a/module.h
+++ b/module.h
@@ -24,12 +24,14 @@ typedef enum {
 MODULE_INIT_BLOCK,
 MODULE_INIT_DEVICE,
 MODULE_INIT_MACHINE,
+MODULE_INIT_QAPI,
 MODULE_INIT_MAX
 } module_init_type;
 
 #define block_init(function) module_init(function, MODULE_INIT_BLOCK)
 #define device_init(function) module_init(function, MODULE_INIT_DEVICE)
 #define machine_init(function) module_init(function, MODULE_INIT_MACHINE)
+#define qapi_init(function) module_init(function, MODULE_INIT_QAPI)
 
 void register_module_init(void (*fn)(void), module_init_type type);
 
-- 
1.7.0.4




[Qemu-devel] [PATCH v5 04/18] qapi: add QAPI visitor core

2011-07-05 Thread Michael Roth
Base definitions/includes for Visiter interface used by generated
visiter/marshalling code.

Includes a GenericList type. Our lists require an embedded element.
Since these types are generated, if you want to use them in a different
type of data structure, there's no easy way to add another embedded
element. The solution is to have non-embedded lists and that what this is.

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 Makefile.objs  |6 +++
 configure  |1 +
 qapi/qapi-types-core.h |   21 +
 qapi/qapi-visit-core.c |  114 
 qapi/qapi-visit-core.h |   68 
 5 files changed, 210 insertions(+), 0 deletions(-)
 create mode 100644 qapi/qapi-types-core.h
 create mode 100644 qapi/qapi-visit-core.c
 create mode 100644 qapi/qapi-visit-core.h

diff --git a/Makefile.objs b/Makefile.objs
index 493c988..0077014 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -372,6 +372,12 @@ endif
 
 libcacard-y = cac.o event.o vcard.o vreader.o vcard_emul_nss.o 
vcard_emul_type.o card_7816.o
 
+##
+# qapi
+
+qapi-nested-y = qapi-visit-core.o
+qapi-obj-y = $(addprefix qapi/, $(qapi-nested-y))
+
 vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
 
 vl.o: QEMU_CFLAGS+=$(SDL_CFLAGS)
diff --git a/configure b/configure
index 63156a2..02c552e 100755
--- a/configure
+++ b/configure
@@ -3486,6 +3486,7 @@ DIRS=tests tests/cris slirp audio block net 
pc-bios/optionrom
 DIRS=$DIRS pc-bios/spapr-rtas
 DIRS=$DIRS roms/seabios roms/vgabios
 DIRS=$DIRS fsdev ui
+DIRS=$DIRS qapi
 FILES=Makefile tests/Makefile
 FILES=$FILES tests/cris/Makefile tests/cris/.gdbinit
 FILES=$FILES pc-bios/optionrom/Makefile pc-bios/keymaps
diff --git a/qapi/qapi-types-core.h b/qapi/qapi-types-core.h
new file mode 100644
index 000..de733ab
--- /dev/null
+++ b/qapi/qapi-types-core.h
@@ -0,0 +1,21 @@
+/*
+ * Core Definitions for QAPI-generated Types
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   aligu...@us.ibm.com
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef QAPI_TYPES_CORE_H
+#define QAPI_TYPES_CORE_H
+
+#include stdbool.h
+#include stdint.h
+#include error.h
+
+#endif
diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
new file mode 100644
index 000..c8a7805
--- /dev/null
+++ b/qapi/qapi-visit-core.c
@@ -0,0 +1,114 @@
+/*
+ * Core Definitions for QAPI Visitor Classes
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   aligu...@us.ibm.com
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#include qapi/qapi-visit-core.h
+
+void visit_start_handle(Visitor *v, void **obj, const char *kind, const char 
*name, Error **errp)
+{
+if (!error_is_set(errp)  v-start_handle) {
+v-start_handle(v, obj, kind, name, errp);
+}
+}
+
+void visit_end_handle(Visitor *v, Error **errp)
+{
+if (!error_is_set(errp)  v-end_handle) {
+v-end_handle(v, errp);
+}
+}
+
+void visit_start_struct(Visitor *v, void **obj, const char *kind, const char 
*name, size_t size, Error **errp)
+{
+if (!error_is_set(errp)) {
+v-start_struct(v, obj, kind, name, size, errp);
+}
+}
+
+void visit_end_struct(Visitor *v, Error **errp)
+{
+if (!error_is_set(errp)) {
+v-end_struct(v, errp);
+}
+}
+
+void visit_start_list(Visitor *v, const char *name, Error **errp)
+{
+if (!error_is_set(errp)) {
+v-start_list(v, name, errp);
+}
+}
+
+GenericList *visit_next_list(Visitor *v, GenericList **list, Error **errp)
+{
+if (!error_is_set(errp)) {
+return v-next_list(v, list, errp);
+}
+
+return 0;
+}
+
+void visit_end_list(Visitor *v, Error **errp)
+{
+if (!error_is_set(errp)) {
+v-end_list(v, errp);
+}
+}
+
+void visit_start_optional(Visitor *v, bool *present, const char *name, Error 
**errp)
+{
+if (!error_is_set(errp)  v-start_optional) {
+v-start_optional(v, present, name, errp);
+}
+}
+
+void visit_end_optional(Visitor *v, Error **errp)
+{
+if (!error_is_set(errp)  v-end_optional) {
+v-end_optional(v, errp);
+}
+}
+
+void visit_type_enum(Visitor *v, int *obj, const char *kind, const char *name, 
Error **errp)
+{
+if (!error_is_set(errp)) {
+v-type_enum(v, obj, kind, name, errp);
+}
+}
+
+void visit_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp)
+{
+if (!error_is_set(errp)) {
+v-type_int(v, obj, name, errp);
+}
+}
+
+void visit_type_bool(Visitor *v, bool *obj, const char *name, Error **errp)
+{
+if (!error_is_set(errp)) {
+v-type_bool(v, obj, name, errp);
+}
+}
+
+void visit_type_str(Visitor *v, char **obj, const char *name, Error **errp)
+{
+if 

[Qemu-devel] [PATCH v5 12/18] qapi: add qapi-types.py code generator

2011-07-05 Thread Michael Roth
This is the code generator for qapi types. It will generation the
following files:

  $(prefix)qapi-types.h - C types corresponding to types defined in
  the schema you pass in
  $(prefix)qapi-types.c - Cleanup functions for the above C types

The $(prefix) is used to as a namespace to keep the generated code from
one schema/code-generation separated from others so code and be
generated from multiple schemas with clobbering previously created code.

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 scripts/qapi-types.py |  258 +
 1 files changed, 258 insertions(+), 0 deletions(-)
 create mode 100644 scripts/qapi-types.py

diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
new file mode 100644
index 000..be0fecf
--- /dev/null
+++ b/scripts/qapi-types.py
@@ -0,0 +1,258 @@
+#
+# QAPI types generator
+#
+# Copyright IBM, Corp. 2011
+#
+# Authors:
+#  Anthony Liguori aligu...@us.ibm.com
+#
+# This work is licensed under the terms of the GNU GPLv2.
+# See the COPYING.LIB file in the top-level directory.
+
+from ordereddict import OrderedDict
+from qapi import *
+import sys
+import os
+import getopt
+
+def generate_fwd_struct(name, members):
+return mcgen('''
+typedef struct %(name)s %(name)s;
+
+typedef struct %(name)sList
+{
+%(name)s *value;
+struct %(name)sList *next;
+} %(name)sList;
+''',
+ name=name)
+
+def generate_struct(structname, fieldname, members):
+ret = mcgen('''
+struct %(name)s
+{
+''',
+  name=structname)
+
+for argname, argentry, optional, structured in parse_args(members):
+if optional:
+ret += mcgen('''
+bool has_%(c_name)s;
+''',
+ c_name=c_var(argname))
+if structured:
+push_indent()
+ret += generate_struct(, argname, argentry)
+pop_indent()
+else:
+ret += mcgen('''
+%(c_type)s %(c_name)s;
+''',
+ c_type=c_type(argentry), c_name=c_var(argname))
+
+if len(fieldname):
+fieldname =   + fieldname
+ret += mcgen('''
+}%(field)s;
+''',
+field=fieldname)
+
+return ret
+
+def generate_handle(name, typeinfo):
+return mcgen('''
+typedef struct %(name)s
+{
+%(c_type)s handle;
+} %(name)s;
+
+typedef struct %(name)sList
+{
+%(name)s *value;
+struct %(name)sList *next;
+} %(name)sList;
+''',
+ name=name, c_type=c_type(typeinfo))
+
+def generate_enum(name, values):
+ret = mcgen('''
+typedef enum %(name)s
+{
+''',
+name=name)
+
+i = 1
+for value in values:
+ret += mcgen('''
+%(abbrev)s_%(value)s = %(i)d,
+''',
+ abbrev=de_camel_case(name).upper(),
+ value=c_var(value).upper(),
+ i=i)
+i += 1
+
+ret += mcgen('''
+} %(name)s;
+''',
+ name=name)
+
+return ret
+
+def generate_union(name, typeinfo):
+ret = mcgen('''
+struct %(name)s
+{
+%(name)sKind kind;
+union {
+''',
+name=name)
+
+for key in typeinfo:
+ret += mcgen('''
+%(c_type)s %(c_name)s;
+''',
+ c_type=c_type(typeinfo[key]),
+ c_name=c_var(key))
+
+ret += mcgen('''
+};
+};
+''')
+
+return ret
+
+def generate_type_cleanup_decl(name):
+ret = mcgen('''
+void qapi_free_%(type)s(%(c_type)s obj);
+''',
+c_type=c_type(name),type=name)
+return ret
+
+def generate_type_cleanup(name):
+ret = mcgen('''
+void qapi_free_%(type)s(%(c_type)s obj)
+{
+QapiDeallocVisitor *md;
+Visitor *v;
+
+if (!obj) {
+return;
+}
+
+md = qapi_dealloc_visitor_new();
+v = qapi_dealloc_get_visitor(md);
+visit_type_%(type)s(v, obj, NULL, NULL);
+qapi_dealloc_visitor_cleanup(md);
+}
+''',
+c_type=c_type(name),type=name)
+return ret
+
+
+try:
+opts, args = getopt.gnu_getopt(sys.argv[1:], p:o:, [prefix=, 
output-dir=])
+except getopt.GetoptError, err:
+print str(err)
+sys.exit(1)
+
+output_dir = 
+prefix = 
+c_file = 'qapi-types.c'
+h_file = 'qapi-types.h'
+
+for o, a in opts:
+if o in (-p, --prefix):
+prefix = a
+elif o in (-o, --output-dir):
+output_dir = a + /
+
+c_file = output_dir + prefix + c_file
+h_file = output_dir + prefix + h_file
+
+if os.path.isdir(output_dir) == False:
+os.makedirs(output_dir)
+
+fdef = open(c_file, 'w')
+fdecl = open(h_file, 'w')
+
+fdef.write(mcgen('''
+/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
+
+/*
+ * deallocation functions for schema-defined QAPI types
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   aligu...@us.ibm.com
+ *  Michael Roth  aligu...@us.ibm.com
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#include 

[Qemu-devel] [PATCH v5 06/18] qapi: add QMP output visitor

2011-07-05 Thread Michael Roth
Type of Visiter class that serves as the inverse of the input visitor:
it takes a series of native C types and uses their values to construct a
corresponding QObject. The command marshaling/dispatcher functions will
use this to convert the output of QMP functions into a QObject that can
be sent over the wire.

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 Makefile.objs |2 +-
 qapi/qmp-output-visitor.c |  216 +
 qapi/qmp-output-visitor.h |   28 ++
 3 files changed, 245 insertions(+), 1 deletions(-)
 create mode 100644 qapi/qmp-output-visitor.c
 create mode 100644 qapi/qmp-output-visitor.h

diff --git a/Makefile.objs b/Makefile.objs
index 997ecef..7f9cba5 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -375,7 +375,7 @@ libcacard-y = cac.o event.o vcard.o vreader.o 
vcard_emul_nss.o vcard_emul_type.o
 ##
 # qapi
 
-qapi-nested-y = qapi-visit-core.o qmp-input-visitor.o
+qapi-nested-y = qapi-visit-core.o qmp-input-visitor.o qmp-output-visitor.o
 qapi-obj-y = $(addprefix qapi/, $(qapi-nested-y))
 
 vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
diff --git a/qapi/qmp-output-visitor.c b/qapi/qmp-output-visitor.c
new file mode 100644
index 000..03a481c
--- /dev/null
+++ b/qapi/qmp-output-visitor.c
@@ -0,0 +1,216 @@
+/*
+ * Core Definitions for QAPI/QMP Command Registry
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   aligu...@us.ibm.com
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#include qmp-output-visitor.h
+#include qemu-queue.h
+#include qemu-common.h
+#include qemu-objects.h
+
+typedef struct QStackEntry
+{
+QObject *value;
+QTAILQ_ENTRY(QStackEntry) node;
+} QStackEntry;
+
+typedef QTAILQ_HEAD(QStack, QStackEntry) QStack;
+
+struct QmpOutputVisitor
+{
+Visitor visitor;
+QStack stack;
+};
+
+#define qmp_output_add(qov, name, value) qmp_output_add_obj(qov, name, 
QOBJECT(value))
+#define qmp_output_push(qov, value) qmp_output_push_obj(qov, QOBJECT(value))
+
+static QmpOutputVisitor *to_qov(Visitor *v)
+{
+return container_of(v, QmpOutputVisitor, visitor);
+}
+
+static void qmp_output_push_obj(QmpOutputVisitor *qov, QObject *value)
+{
+QStackEntry *e = qemu_mallocz(sizeof(*e));
+
+e-value = value;
+QTAILQ_INSERT_HEAD(qov-stack, e, node);
+}
+
+static QObject *qmp_output_pop(QmpOutputVisitor *qov)
+{
+QStackEntry *e = QTAILQ_FIRST(qov-stack);
+QObject *value;
+QTAILQ_REMOVE(qov-stack, e, node);
+value = e-value;
+qemu_free(e);
+return value;
+}
+
+static QObject *qmp_output_first(QmpOutputVisitor *qov)
+{
+QStackEntry *e = QTAILQ_LAST(qov-stack, QStack);
+return e-value;
+}
+
+static QObject *qmp_output_last(QmpOutputVisitor *qov)
+{
+QStackEntry *e = QTAILQ_FIRST(qov-stack);
+return e-value;
+}
+
+static void qmp_output_add_obj(QmpOutputVisitor *qov, const char *name, 
QObject *value)
+{
+QObject *cur;
+
+if (QTAILQ_EMPTY(qov-stack)) {
+qmp_output_push_obj(qov, value);
+return;
+}
+
+cur = qmp_output_last(qov);
+
+switch (qobject_type(cur)) {
+case QTYPE_QDICT:
+qdict_put_obj(qobject_to_qdict(cur), name, value);
+break;
+case QTYPE_QLIST:
+qlist_append_obj(qobject_to_qlist(cur), value);
+break;
+default:
+qobject_decref(qmp_output_pop(qov));
+qmp_output_push_obj(qov, value);
+break;
+}
+}
+
+static void qmp_output_start_struct(Visitor *v, void **obj, const char *kind, 
const char *name, size_t unused, Error **errp)
+{
+QmpOutputVisitor *qov = to_qov(v);
+QDict *dict = qdict_new();
+
+qmp_output_add(qov, name, dict);
+qmp_output_push(qov, dict);
+}
+
+static void qmp_output_end_struct(Visitor *v, Error **errp)
+{
+QmpOutputVisitor *qov = to_qov(v);
+qmp_output_pop(qov);
+}
+
+static void qmp_output_start_list(Visitor *v, const char *name, Error **errp)
+{
+QmpOutputVisitor *qov = to_qov(v);
+QList *list = qlist_new();
+
+qmp_output_add(qov, name, list);
+qmp_output_push(qov, list);
+}
+
+static GenericList *qmp_output_next_list(Visitor *v, GenericList **list, Error 
**errp)
+{
+GenericList *retval = *list;
+*list = retval-next;
+return retval;
+}
+
+static void qmp_output_end_list(Visitor *v, Error **errp)
+{
+QmpOutputVisitor *qov = to_qov(v);
+qmp_output_pop(qov);
+}
+
+static void qmp_output_type_int(Visitor *v, int64_t *obj, const char *name, 
Error **errp)
+{
+QmpOutputVisitor *qov = to_qov(v);
+qmp_output_add(qov, name, qint_from_int(*obj));
+}
+
+static void qmp_output_type_bool(Visitor *v, bool *obj, const char *name, 
Error **errp)
+{
+QmpOutputVisitor *qov = to_qov(v);
+qmp_output_add(qov, name, qbool_from_int(*obj));
+}
+
+static void qmp_output_type_str(Visitor *v, char **obj, 

[Qemu-devel] [PATCH v5 05/18] qapi: add QMP input visitor

2011-07-05 Thread Michael Roth
A type of Visiter class that is used to walk a qobject's
structure and assign each entry to the corresponding native C type.
Command marshaling function will use this to pull out QMP command
parameters recieved over the wire and pass them as native arguments
to the corresponding C functions.

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 Makefile.objs|2 +-
 qapi/qmp-input-visitor.c |  264 ++
 qapi/qmp-input-visitor.h |   27 +
 qerror.h |3 +
 4 files changed, 295 insertions(+), 1 deletions(-)
 create mode 100644 qapi/qmp-input-visitor.c
 create mode 100644 qapi/qmp-input-visitor.h

diff --git a/Makefile.objs b/Makefile.objs
index 0077014..997ecef 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -375,7 +375,7 @@ libcacard-y = cac.o event.o vcard.o vreader.o 
vcard_emul_nss.o vcard_emul_type.o
 ##
 # qapi
 
-qapi-nested-y = qapi-visit-core.o
+qapi-nested-y = qapi-visit-core.o qmp-input-visitor.o
 qapi-obj-y = $(addprefix qapi/, $(qapi-nested-y))
 
 vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c
new file mode 100644
index 000..80912bb
--- /dev/null
+++ b/qapi/qmp-input-visitor.c
@@ -0,0 +1,264 @@
+/*
+ * Input Visitor
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   aligu...@us.ibm.com
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#include qmp-input-visitor.h
+#include qemu-queue.h
+#include qemu-common.h
+#include qemu-objects.h
+#include qerror.h
+
+#define QIV_STACK_SIZE 1024
+
+typedef struct StackObject
+{
+const QObject *obj;
+const  QListEntry *entry;
+} StackObject;
+
+struct QmpInputVisitor
+{
+Visitor visitor;
+const QObject *obj;
+StackObject stack[QIV_STACK_SIZE];
+int nb_stack;
+};
+
+static QmpInputVisitor *to_qiv(Visitor *v)
+{
+return container_of(v, QmpInputVisitor, visitor);
+}
+
+static const QObject *qmp_input_get_object(QmpInputVisitor *qiv, const char 
*name)
+{
+const QObject *qobj;
+
+if (qiv-nb_stack == 0) {
+qobj = qiv-obj;
+} else {
+qobj = qiv-stack[qiv-nb_stack - 1].obj;
+}
+
+if (name  qobject_type(qobj) == QTYPE_QDICT) {
+return qdict_get(qobject_to_qdict(qobj), name);
+} else if (qiv-nb_stack  0  qobject_type(qobj) == QTYPE_QLIST) {
+return qlist_entry_obj(qiv-stack[qiv-nb_stack - 1].entry);
+}
+
+return qobj;
+}
+
+static void qmp_input_push(QmpInputVisitor *qiv, const QObject *obj, Error 
**errp)
+{
+qiv-stack[qiv-nb_stack].obj = obj;
+if (qobject_type(obj) == QTYPE_QLIST) {
+qiv-stack[qiv-nb_stack].entry = qlist_first(qobject_to_qlist(obj));
+}
+qiv-nb_stack++;
+
+if (qiv-nb_stack = QIV_STACK_SIZE) {
+error_set(errp, QERR_BUFFER_OVERRUN);
+return;
+}
+}
+
+static void qmp_input_pop(QmpInputVisitor *qiv, Error **errp)
+{
+qiv-nb_stack--;
+if (qiv-nb_stack  0) {
+error_set(errp, QERR_BUFFER_OVERRUN);
+return;
+}
+}
+
+static void qmp_input_start_struct(Visitor *v, void **obj, const char *kind, 
const char *name, size_t size, Error **errp)
+{
+QmpInputVisitor *qiv = to_qiv(v);
+const QObject *qobj = qmp_input_get_object(qiv, name);
+
+if (!qobj || qobject_type(qobj) != QTYPE_QDICT) {
+error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : null, 
QDict);
+return;
+}
+
+qmp_input_push(qiv, qobj, errp);
+if (error_is_set(errp)) {
+return;
+}
+
+if (obj) {
+*obj = qemu_mallocz(size);
+}
+}
+
+static void qmp_input_end_struct(Visitor *v, Error **errp)
+{
+QmpInputVisitor *qiv = to_qiv(v);
+
+qmp_input_pop(qiv, errp);
+}
+
+static void qmp_input_start_list(Visitor *v, const char *name, Error **errp)
+{
+QmpInputVisitor *qiv = to_qiv(v);
+const QObject *qobj = qmp_input_get_object(qiv, name);
+
+if (!qobj || qobject_type(qobj) != QTYPE_QLIST) {
+error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : null, 
list);
+return;
+}
+
+qmp_input_push(qiv, qobj, errp);
+}
+
+static GenericList *qmp_input_next_list(Visitor *v, GenericList **list, Error 
**errp)
+{
+QmpInputVisitor *qiv = to_qiv(v);
+GenericList *entry;
+StackObject *so = qiv-stack[qiv-nb_stack - 1];
+
+if (so-entry == NULL) {
+return NULL;
+}
+
+entry = qemu_mallocz(sizeof(*entry));
+if (*list) {
+so-entry = qlist_next(so-entry);
+if (so-entry == NULL) {
+qemu_free(entry);
+return NULL;
+}
+(*list)-next = entry;
+}
+*list = entry;
+
+
+return entry;
+}
+
+static void qmp_input_end_list(Visitor *v, Error **errp)
+{
+QmpInputVisitor *qiv = to_qiv(v);
+
+qmp_input_pop(qiv, errp);
+}
+

[Qemu-devel] [PATCH v5 15/18] qapi: test schema used for unit tests

2011-07-05 Thread Michael Roth
This is how QMP commands/parameters/types would be defined. We use a
subset of that functionality here to implement functions/types for unit
testing.

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 qapi-schema-test.json |   22 ++
 1 files changed, 22 insertions(+), 0 deletions(-)
 create mode 100644 qapi-schema-test.json

diff --git a/qapi-schema-test.json b/qapi-schema-test.json
new file mode 100644
index 000..3acedad
--- /dev/null
+++ b/qapi-schema-test.json
@@ -0,0 +1,22 @@
+# *-*- Mode: Python -*-*
+
+# for testing enums
+{ 'enum': 'EnumOne',
+  'data': [ 'value1', 'value2', 'value3' ] }
+{ 'type': 'NestedEnumsOne',
+  'data': { 'enum1': 'EnumOne', '*enum2': 'EnumOne', 'enum3': 'EnumOne', 
'*enum4': 'EnumOne' } }
+
+# for testing nested structs
+{ 'type': 'UserDefOne',
+  'data': { 'integer': 'int', 'string': 'str' } }
+
+{ 'type': 'UserDefTwo',
+  'data': { 'string': 'str',
+'dict': { 'string': 'str',
+  'dict': { 'userdef': 'UserDefOne', 'string': 'str' },
+  '*dict2': { 'userdef': 'UserDefOne', 'string': 'str' } } 
} }
+
+# testing commands
+{ 'command': 'user_def_cmd', 'data': {} }
+{ 'command': 'user_def_cmd1', 'data': {'ud1a': 'UserDefOne'} }
+{ 'command': 'user_def_cmd2', 'data': {'ud1a': 'UserDefOne', 'ud1b': 
'UserDefOne'}, 'returns': 'UserDefTwo' }
-- 
1.7.0.4




[Qemu-devel] [PATCH v5 08/18] qapi: add QMP command registration/lookup functions

2011-07-05 Thread Michael Roth
Registration/lookup functions for that provide a lookup table for
dispatching QMP commands.

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 Makefile.objs   |1 +
 qapi/qmp-core.h |   40 
 qapi/qmp-registry.c |   40 
 3 files changed, 81 insertions(+), 0 deletions(-)
 create mode 100644 qapi/qmp-core.h
 create mode 100644 qapi/qmp-registry.c

diff --git a/Makefile.objs b/Makefile.objs
index 08f69e5..55a94e4 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -376,6 +376,7 @@ libcacard-y = cac.o event.o vcard.o vreader.o 
vcard_emul_nss.o vcard_emul_type.o
 # qapi
 
 qapi-nested-y = qapi-visit-core.o qmp-input-visitor.o qmp-output-visitor.o 
qapi-dealloc-visitor.o
+qapi-nested-y += qmp-registry.o
 qapi-obj-y = $(addprefix qapi/, $(qapi-nested-y))
 
 vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
diff --git a/qapi/qmp-core.h b/qapi/qmp-core.h
new file mode 100644
index 000..99e929f
--- /dev/null
+++ b/qapi/qmp-core.h
@@ -0,0 +1,40 @@
+/*
+ * Core Definitions for QAPI/QMP Dispatch
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   aligu...@us.ibm.com
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef QMP_CORE_H
+#define QMP_CORE_H
+
+#include qobject.h
+#include qdict.h
+#include error.h
+
+typedef void (QmpCommandFunc)(QDict *, QObject **, Error **);
+
+typedef enum QmpCommandType
+{
+QCT_NORMAL,
+} QmpCommandType;
+
+typedef struct QmpCommand
+{
+const char *name;
+QmpCommandType type;
+QmpCommandFunc *fn;
+QTAILQ_ENTRY(QmpCommand) node;
+} QmpCommand;
+
+void qmp_register_command(const char *name, QmpCommandFunc *fn);
+QmpCommand *qmp_find_command(const char *name);
+
+#endif
+
diff --git a/qapi/qmp-registry.c b/qapi/qmp-registry.c
new file mode 100644
index 000..3fe8866
--- /dev/null
+++ b/qapi/qmp-registry.c
@@ -0,0 +1,40 @@
+/*
+ * Core Definitions for QAPI/QMP Dispatch
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   aligu...@us.ibm.com
+ *  Michael Roth  mdr...@us.ibm.com
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#include qapi/qmp-core.h
+
+static QTAILQ_HEAD(, QmpCommand) qmp_commands =
+QTAILQ_HEAD_INITIALIZER(qmp_commands);
+
+void qmp_register_command(const char *name, QmpCommandFunc *fn)
+{
+QmpCommand *cmd = qemu_mallocz(sizeof(*cmd));
+
+cmd-name = name;
+cmd-type = QCT_NORMAL;
+cmd-fn = fn;
+QTAILQ_INSERT_TAIL(qmp_commands, cmd, node);
+}
+
+QmpCommand *qmp_find_command(const char *name)
+{
+QmpCommand *i;
+
+QTAILQ_FOREACH(i, qmp_commands, node) {
+if (strcmp(i-name, name) == 0) {
+return i;
+}
+}
+return NULL;
+}
-- 
1.7.0.4




[Qemu-devel] [PATCH v5 07/18] qapi: add QAPI dealloc visitor

2011-07-05 Thread Michael Roth
Type of Visitor class that can be passed into a qapi-generated C
type's visitor function to free() any heap-allocated data types.

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 Makefile.objs   |2 +-
 qapi/qapi-dealloc-visitor.c |  138 +++
 qapi/qapi-dealloc-visitor.h |   26 
 3 files changed, 165 insertions(+), 1 deletions(-)
 create mode 100644 qapi/qapi-dealloc-visitor.c
 create mode 100644 qapi/qapi-dealloc-visitor.h

diff --git a/Makefile.objs b/Makefile.objs
index 7f9cba5..08f69e5 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -375,7 +375,7 @@ libcacard-y = cac.o event.o vcard.o vreader.o 
vcard_emul_nss.o vcard_emul_type.o
 ##
 # qapi
 
-qapi-nested-y = qapi-visit-core.o qmp-input-visitor.o qmp-output-visitor.o
+qapi-nested-y = qapi-visit-core.o qmp-input-visitor.o qmp-output-visitor.o 
qapi-dealloc-visitor.o
 qapi-obj-y = $(addprefix qapi/, $(qapi-nested-y))
 
 vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
diff --git a/qapi/qapi-dealloc-visitor.c b/qapi/qapi-dealloc-visitor.c
new file mode 100644
index 000..7525df3
--- /dev/null
+++ b/qapi/qapi-dealloc-visitor.c
@@ -0,0 +1,138 @@
+/*
+ * Dealloc Visitor
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Michael Roth   mdr...@linux.vnet.ibm.com
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#include qapi-dealloc-visitor.h
+#include qemu-queue.h
+#include qemu-common.h
+#include qemu-objects.h
+
+typedef struct StackEntry
+{
+void *value;
+QTAILQ_ENTRY(StackEntry) node;
+} StackEntry;
+
+struct QapiDeallocVisitor
+{
+Visitor visitor;
+QTAILQ_HEAD(, StackEntry) stack;
+};
+
+static QapiDeallocVisitor *to_qov(Visitor *v)
+{
+return container_of(v, QapiDeallocVisitor, visitor);
+}
+
+static void qapi_dealloc_push(QapiDeallocVisitor *qov, void *value)
+{
+StackEntry *e = qemu_mallocz(sizeof(*e));
+
+e-value = value;
+QTAILQ_INSERT_HEAD(qov-stack, e, node);
+}
+
+static void *qapi_dealloc_pop(QapiDeallocVisitor *qov)
+{
+StackEntry *e = QTAILQ_FIRST(qov-stack);
+QObject *value;
+QTAILQ_REMOVE(qov-stack, e, node);
+value = e-value;
+qemu_free(e);
+return value;
+}
+
+static void qapi_dealloc_start_struct(Visitor *v, void **obj, const char 
*kind, const char *name, size_t unused, Error **errp)
+{
+QapiDeallocVisitor *qov = to_qov(v);
+qapi_dealloc_push(qov, obj);
+}
+
+static void qapi_dealloc_end_struct(Visitor *v, Error **errp)
+{
+QapiDeallocVisitor *qov = to_qov(v);
+void **obj = qapi_dealloc_pop(qov);
+if (obj) {
+qemu_free(*obj);
+}
+}
+
+static void qapi_dealloc_start_list(Visitor *v, const char *name, Error **errp)
+{
+}
+
+static GenericList *qapi_dealloc_next_list(Visitor *v, GenericList **list, 
Error **errp)
+{
+GenericList *retval = *list;
+qemu_free(retval-value);
+*list = retval-next;
+return retval;
+}
+
+static void qapi_dealloc_end_list(Visitor *v, Error **errp)
+{
+}
+
+static void qapi_dealloc_type_str(Visitor *v, char **obj, const char *name, 
Error **errp)
+{
+if (obj) {
+qemu_free(*obj);
+}
+}
+
+static void qapi_dealloc_type_int(Visitor *v, int64_t *obj, const char *name, 
Error **errp)
+{
+}
+
+static void qapi_dealloc_type_bool(Visitor *v, bool *obj, const char *name, 
Error **errp)
+{
+}
+
+static void qapi_dealloc_type_number(Visitor *v, double *obj, const char 
*name, Error **errp)
+{
+}
+
+static void qapi_dealloc_type_enum(Visitor *v, int *obj, const char *kind, 
const char *name, Error **errp)
+{
+}
+
+Visitor *qapi_dealloc_get_visitor(QapiDeallocVisitor *v)
+{
+return v-visitor;
+}
+
+void qapi_dealloc_visitor_cleanup(QapiDeallocVisitor *v)
+{
+qemu_free(v);
+}
+
+QapiDeallocVisitor *qapi_dealloc_visitor_new(void)
+{
+QapiDeallocVisitor *v;
+
+v = qemu_mallocz(sizeof(*v));
+
+v-visitor.start_struct = qapi_dealloc_start_struct;
+v-visitor.end_struct = qapi_dealloc_end_struct;
+v-visitor.start_list = qapi_dealloc_start_list;
+v-visitor.next_list = qapi_dealloc_next_list;
+v-visitor.end_list = qapi_dealloc_end_list;
+v-visitor.type_enum = qapi_dealloc_type_enum;
+v-visitor.type_int = qapi_dealloc_type_int;
+v-visitor.type_bool = qapi_dealloc_type_bool;
+v-visitor.type_str = qapi_dealloc_type_str;
+v-visitor.type_number = qapi_dealloc_type_number;
+
+QTAILQ_INIT(v-stack);
+
+return v;
+}
diff --git a/qapi/qapi-dealloc-visitor.h b/qapi/qapi-dealloc-visitor.h
new file mode 100644
index 000..5842bc7
--- /dev/null
+++ b/qapi/qapi-dealloc-visitor.h
@@ -0,0 +1,26 @@
+/*
+ * Dealloc Visitor
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Michael Roth   mdr...@linux.vnet.ibm.com
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in 

Re: [Qemu-devel] [PATCH 5/5] megasas: LSI Megaraid SAS emulation

2011-07-05 Thread Alexander Graf

On 07/05/2011 01:03 PM, Hannes Reinecke wrote:

This patch adds an emulation for the LSI Megaraid SAS 8708EM2 HBA.


Nice, so it does work for me this time :).

Tested-by: Alexander Graf ag...@suse.de


Alex




[Qemu-devel] [PATCH v5 09/18] qapi: add QMP dispatch functions

2011-07-05 Thread Michael Roth
Given an object recieved via QMP, this code uses the dispatch table
provided by qmp_registry.c to call the corresponding marshalling/dispatch
function and format return values/errors for delivery to the QMP.
Currently only synchronous QMP functions are supported, but this will
also be used for async QMP functions and QMP guest proxy dispatch as
well.

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 Makefile.objs   |2 +-
 qapi/qmp-core.h |1 +
 qapi/qmp-dispatch.c |  124 +++
 3 files changed, 126 insertions(+), 1 deletions(-)
 create mode 100644 qapi/qmp-dispatch.c

diff --git a/Makefile.objs b/Makefile.objs
index 55a94e4..d7c4cec 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -376,7 +376,7 @@ libcacard-y = cac.o event.o vcard.o vreader.o 
vcard_emul_nss.o vcard_emul_type.o
 # qapi
 
 qapi-nested-y = qapi-visit-core.o qmp-input-visitor.o qmp-output-visitor.o 
qapi-dealloc-visitor.o
-qapi-nested-y += qmp-registry.o
+qapi-nested-y += qmp-registry.o qmp-dispatch.o
 qapi-obj-y = $(addprefix qapi/, $(qapi-nested-y))
 
 vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
diff --git a/qapi/qmp-core.h b/qapi/qmp-core.h
index 99e929f..f1c26e4 100644
--- a/qapi/qmp-core.h
+++ b/qapi/qmp-core.h
@@ -35,6 +35,7 @@ typedef struct QmpCommand
 
 void qmp_register_command(const char *name, QmpCommandFunc *fn);
 QmpCommand *qmp_find_command(const char *name);
+QObject *qmp_dispatch(QObject *request);
 
 #endif
 
diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
new file mode 100644
index 000..5584693
--- /dev/null
+++ b/qapi/qmp-dispatch.c
@@ -0,0 +1,124 @@
+/*
+ * Core Definitions for QAPI/QMP Dispatch
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   aligu...@us.ibm.com
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#include qemu-objects.h
+#include qapi/qmp-core.h
+#include json-parser.h
+#include error.h
+#include error_int.h
+#include qerror.h
+
+static QDict *qmp_dispatch_check_obj(const QObject *request, Error **errp)
+{
+const QDictEntry *ent;
+const char *arg_name;
+const QObject *arg_obj;
+bool has_exec_key = false;
+QDict *dict = NULL;
+
+if (qobject_type(request) != QTYPE_QDICT) {
+error_set(errp, QERR_QMP_BAD_INPUT_OBJECT,
+  request is not a dictionary);
+return NULL;
+}
+
+dict = qobject_to_qdict(request);
+
+for (ent = qdict_first(dict); ent;
+ ent = qdict_next(dict, ent)) {
+arg_name = qdict_entry_key(ent);
+arg_obj = qdict_entry_value(ent);
+
+if (!strcmp(arg_name, execute)) {
+if (qobject_type(arg_obj) != QTYPE_QSTRING) {
+error_set(errp, QERR_QMP_BAD_INPUT_OBJECT_MEMBER, execute,
+  string);
+return NULL;
+}
+has_exec_key = true;
+} else if (strcmp(arg_name, arguments)) {
+error_set(errp, QERR_QMP_EXTRA_MEMBER, arg_name);
+return NULL;
+}
+}
+
+if (!has_exec_key) {
+error_set(errp, QERR_QMP_BAD_INPUT_OBJECT, execute);
+return NULL;
+}
+
+return dict;
+}
+
+static QObject *do_qmp_dispatch(QObject *request, Error **errp)
+{
+const char *command;
+QDict *args, *dict;
+QmpCommand *cmd;
+QObject *ret = NULL;
+
+
+dict = qmp_dispatch_check_obj(request, errp);
+if (!dict || error_is_set(errp)) {
+return NULL;
+}
+
+command = qdict_get_str(dict, execute);
+cmd = qmp_find_command(command);
+if (cmd == NULL) {
+error_set(errp, QERR_COMMAND_NOT_FOUND, command);
+return NULL;
+}
+
+if (!qdict_haskey(dict, arguments)) {
+args = qdict_new();
+} else {
+args = qdict_get_qdict(dict, arguments);
+QINCREF(args);
+}
+
+switch (cmd-type) {
+case QCT_NORMAL:
+cmd-fn(args, ret, errp);
+if (!error_is_set(errp)  ret == NULL) {
+ret = QOBJECT(qdict_new());
+}
+break;
+}
+
+QDECREF(args);
+
+return ret;
+}
+
+QObject *qmp_dispatch(QObject *request)
+{
+Error *err = NULL;
+QObject *ret;
+QDict *rsp;
+
+ret = do_qmp_dispatch(request, err);
+
+rsp = qdict_new();
+if (err) {
+qdict_put_obj(rsp, error, error_get_qobject(err));
+error_free(err);
+} else if (ret) {
+qdict_put_obj(rsp, return, ret);
+} else {
+QDECREF(rsp);
+return NULL;
+}
+
+return QOBJECT(rsp);
+}
-- 
1.7.0.4




[Qemu-devel] [PATCH v5 18/18] qapi: add QAPI code generation documentation

2011-07-05 Thread Michael Roth

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 docs/qapi-code-gen.txt |  316 
 1 files changed, 316 insertions(+), 0 deletions(-)
 create mode 100644 docs/qapi-code-gen.txt

diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
new file mode 100644
index 000..b7befb5
--- /dev/null
+++ b/docs/qapi-code-gen.txt
@@ -0,0 +1,316 @@
+= How to use the QAPI code generator =
+
+* Note: as of this writing, QMP does not use QAPI. Eventually QMP
+commands will be converted to use QAPI internally. The following
+information describes QMP/QAPI as it will exist after the
+conversion.
+
+QAPI is a native C API within QEMU which provides management-level
+functionality to internal/external users. For external
+users/processes, this interface is made available by a JSON-based
+QEMU Monitor protocol that is provided by the QMP server.
+
+To map QMP-defined interfaces to the native C QAPI implementations,
+a JSON-based schema is used to define types and function
+signatures, and a set of scripts is used to generate types/signatures,
+and marshaling/dispatch code. The QEMU Guest Agent also uses these
+scripts, paired with a seperate schema, to generate
+marshaling/dispatch code for the guest agent server running in the
+guest.
+
+This document will describe how the schemas, scripts, and resulting
+code is used.
+
+
+== QMP/Guest agent schema ==
+
+This file defines the types, commands, and events used by QMP.  It should
+fully describe the interface used by QMP.
+
+This file is designed to be loosely based on JSON although it's technically
+executable Python.  While dictionaries are used, they are parsed as
+OrderedDicts so that ordering is preserved.
+
+There are two basic syntaxes used, type definitions and command definitions.
+
+The first syntax defines a type and is represented by a dictionary.  There are
+two kinds of types that are supported: complex user-defined types, and enums.
+
+A complex type is a dictionary containing a single key who's value is a
+dictionary.  This corresponds to a struct in C or an Object in JSON.  An
+example of a complex type is:
+
+ { 'type': 'MyType',
+   'data' { 'member1': 'str', 'member2': 'int', '*member3': 'str } }
+
+The use of '*' as a prefix to the name means the member is optional.  Optional
+members should always be added to the end of the dictionary to preserve
+backwards compatibility.
+
+An enumeration type is a dictionary containing a single key who's value is a
+list of strings.  An example enumeration is:
+
+ { 'enum': 'MyEnum', 'data': [ 'value1', 'value2', 'value3' ] }
+
+Generally speaking, complex types and enums should always use CamelCase for
+the type names.
+
+Commands are defined by using a list containing three members.  The first
+member is the command name, the second member is a dictionary containing
+arguments, and the third member is the return type.
+
+An example command is:
+
+ { 'command': 'my-command',
+   'data': { 'arg1': 'str', '*arg2': 'str' },
+   'returns': 'str' ]
+
+Command names should be all lower case with words separated by a hyphen.
+
+
+== Code generation ==
+
+Schemas are fed into 3 scripts to generate all the code/files that, paired
+with the core QAPI libraries, comprise everything required to take JSON
+commands read in by a QMP/guest agent server, unmarshal the arguments into
+the underlying C types, call into the corresponding C function, and map the
+response back to a QMP/guest agent response to be returned to the user.
+
+As an example, we'll use the following schema, which describes a single
+complex user-defined type (which will produce a C struct, along with a list
+node structure that can be used to chain together a list of such types in
+case we want to accept/return a list of this type with a command), and a
+command which takes that type as a parameter and returns the same type:
+
+mdroth@illuin:~/w/qemu2.git$ cat example-schema.json
+{ 'type': 'UserDefOne',
+  'data': { 'integer': 'int', 'string': 'str' } }
+
+{ 'command': 'my-command',
+  'data':{'arg1': 'UserDefOne'},
+  'returns': 'UserDefOne' }
+mdroth@illuin:~/w/qemu2.git$
+
+=== scripts/qapi-types.py ===
+
+Used to generate the C types defined by a schema. The following files are
+created:
+
+$(prefix)qapi-types.h - C types corresponding to types defined in
+the schema you pass in
+$(prefix)qapi-types.c - Cleanup functions for the above C types
+
+The $(prefix) is an optional parameter used as a namespace to keep the
+generated code from one schema/code-generation separated from others so code
+can be generated/used from multiple schemas without clobbering previously
+created code.
+
+Example:
+
+mdroth@illuin:~/w/qemu2.git$ python scripts/qapi-types.py \
+  --output-dir=qapi-generated --prefix=example-  example-schema.json
+mdroth@illuin:~/w/qemu2.git$ cat qapi-generated/example-qapi-types.c
+/* AUTOMATICALLY GENERATED, DO NOT 

Re: [Qemu-devel] Setting up PPC440 Virtex Image for Qemu

2011-07-05 Thread Suzuki Poulose

On 06/30/11 18:40, Edgar E. Iglesias wrote:

On Thu, Jun 30, 2011 at 06:30:04PM +0530, Suzuki Poulose wrote:

On 06/30/11 18:02, Edgar E. Iglesias wrote:

On Thu, Jun 30, 2011 at 05:45:23PM +0530, Suzuki Poulose wrote:

Hi,

I am working on enabling the KEXEC on PPC440 chipsets. To debug my patches,
I would like to use the Qemu. The only available PPC440 support in Qemu is
for the ppc-virtex. (Thanks for adding the support).

I was trying to use the default image provided at

http://wiki.qemu.org/download/ppc-virtexml507-linux-2_6_34.tgz

However I cannot get the network up for the board to use the nfs root file
system.


Hi,

The problem is that there is no model of the LL-TEMAC in qemu, the one in
the refdesign beeing emulated. An easy way out is probably to connect
a xilinx,ethlite instead. You'll need to modify both QEMU and the dtb.

IIRC, the dtb published with the image has the lltemac removed.

I've got a working LL-temac model here, will try to post it this weekend.
Or if you're interested in hacking on it, I could probably code dump it as
is.


Edgar,

Thanks a lot for the quick reply.


Is there something I can do to get the networking up ? I think this may need to
be fixed in the dtb.

Or is there any other mechanism to use a different file system ?
( I have the tool chain to build the kernel etc)



Another way is to create ramdisks with all the stuff you need and just
not use networking. Thats how the image from the wiki does it.


I think I can try this option. By the way, could you pass on the steps to
attach the ramdisks to the image ?


Hi,

If I dont remember wrong, the image on the wiki contains a kernelconfig file.
The config file sets the CONFIG_INITRAMFS_SOURCE option to ./romfs.
In my case I created a romfs subdir right in my linux-2.6 kernel tree,
e.g linux-2.6/romfs/.

You'll then have to populate the romfs directory with all the things
you need. romfs/dev/xxx, romfs/lib/xxx etc etc.

Then, once you build the kernel, an image of the romfs/ will be baked
into the kernel image. You then need to choose your init cmd by
passing an rdinit option in ther kernel cmd line.

With qemu:
-append rdinit=/bin/sh

The qemu-run.sh script from the wiki does that aswell.

There are probably other better ways to do it that I am not aware
of at the moment. But I hope it helps as example.


Thanks a lot for the pointers. Somehow, the INITRAMFS_SOURCE was not working
 for me even with the kernelconfig that is attached in the tar.gz. Btw, the
kernelconfig enabled additional image types, simpleImage.virtex507 etc, which
 had no rules to build. I tried with the xilinix-2.6 git tree with no luck.

However, I have got it working using an initrd.img (7M) which I pass using 
-initrd option.

I have also hacked qemu to display the tlb entries (which is very much needed 
for my
work) with info registers and gdb works like a charm.  Nothing more, I could 
ask for.


Cheers
Suzuki



[Qemu-devel] [PATCH v5 10/18] qapi: add ordereddict.py helper library

2011-07-05 Thread Michael Roth
We need this to parse dictionaries with schema ordering intact so that C
prototypes can be generated deterministically.

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 scripts/ordereddict.py |  128 
 1 files changed, 128 insertions(+), 0 deletions(-)
 create mode 100644 scripts/ordereddict.py

diff --git a/scripts/ordereddict.py b/scripts/ordereddict.py
new file mode 100644
index 000..e17269f
--- /dev/null
+++ b/scripts/ordereddict.py
@@ -0,0 +1,128 @@
+# Copyright (c) 2009 Raymond Hettinger
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation files
+# (the Software), to deal in the Software without restriction,
+# including without limitation the rights to use, copy, modify, merge,
+# publish, distribute, sublicense, and/or sell copies of the Software,
+# and to permit persons to whom the Software is furnished to do so,
+# subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+
+from UserDict import DictMixin
+
+class OrderedDict(dict, DictMixin):
+
+def __init__(self, *args, **kwds):
+if len(args)  1:
+raise TypeError('expected at most 1 arguments, got %d' % len(args))
+try:
+self.__end
+except AttributeError:
+self.clear()
+self.update(*args, **kwds)
+
+def clear(self):
+self.__end = end = []
+end += [None, end, end] # sentinel node for doubly linked list
+self.__map = {} # key -- [key, prev, next]
+dict.clear(self)
+
+def __setitem__(self, key, value):
+if key not in self:
+end = self.__end
+curr = end[1]
+curr[2] = end[1] = self.__map[key] = [key, curr, end]
+dict.__setitem__(self, key, value)
+
+def __delitem__(self, key):
+dict.__delitem__(self, key)
+key, prev, next = self.__map.pop(key)
+prev[2] = next
+next[1] = prev
+
+def __iter__(self):
+end = self.__end
+curr = end[2]
+while curr is not end:
+yield curr[0]
+curr = curr[2]
+
+def __reversed__(self):
+end = self.__end
+curr = end[1]
+while curr is not end:
+yield curr[0]
+curr = curr[1]
+
+def popitem(self, last=True):
+if not self:
+raise KeyError('dictionary is empty')
+if last:
+key = reversed(self).next()
+else:
+key = iter(self).next()
+value = self.pop(key)
+return key, value
+
+def __reduce__(self):
+items = [[k, self[k]] for k in self]
+tmp = self.__map, self.__end
+del self.__map, self.__end
+inst_dict = vars(self).copy()
+self.__map, self.__end = tmp
+if inst_dict:
+return (self.__class__, (items,), inst_dict)
+return self.__class__, (items,)
+
+def keys(self):
+return list(self)
+
+setdefault = DictMixin.setdefault
+update = DictMixin.update
+pop = DictMixin.pop
+values = DictMixin.values
+items = DictMixin.items
+iterkeys = DictMixin.iterkeys
+itervalues = DictMixin.itervalues
+iteritems = DictMixin.iteritems
+
+def __repr__(self):
+if not self:
+return '%s()' % (self.__class__.__name__,)
+return '%s(%r)' % (self.__class__.__name__, self.items())
+
+def copy(self):
+return self.__class__(self)
+
+@classmethod
+def fromkeys(cls, iterable, value=None):
+d = cls()
+for key in iterable:
+d[key] = value
+return d
+
+def __eq__(self, other):
+if isinstance(other, OrderedDict):
+if len(self) != len(other):
+return False
+for p, q in  zip(self.items(), other.items()):
+if p != q:
+return False
+return True
+return dict.__eq__(self, other)
+
+def __ne__(self, other):
+return not self == other
+
-- 
1.7.0.4




Re: [Qemu-devel] [PATCH 3/3] hw/omap_gpio.c: Convert to qdev

2011-07-05 Thread Peter Maydell
On 4 July 2011 23:39, andrzej zaborowski balr...@gmail.com wrote:
 Patch looks good overall, but for consistency we should rename
 functions which start with omap2_gpio_module_ to omap2_gpio_ if the
 state pointer passed is no longer the module pointer but instead the
 whole thing pointer.  But maybe it would make more sense for each
 module to be a device?  It looks like vmsaving/vmloading the union
 structure may be problematic and we can also save some cycles.

Yes, I think you're right and we should just have two separate
devices rather than one with a union.

 Similarly omap_l4_base would be better named omap_l4_region_base or
 similar.

Happy to change this, I'm not very attached to the name.

 I'd also prefer that omap2_gpio_init remains a function that
 does all the qdev magic in omap_gpio.c and with the current signature

I'm not convinced about this. Implementing the GPIO module as
a sysbus device seems like the right thing, and it's the job
of omap2.c to know how to map and wire the resources the sysbus
device provides. Hiding that in a helper function in omap_gpio.c
doesn't seem quite right.

 (so for example clocks usage can be kept track of).

You're right, we probably should do something with the clocks (even
though omap_gpio doesn't use them). We'd probably wind up with a
'wire up clocks' function per device type though, unless we want to
try to make all omap devices inherit from a common thing that knows
about clocks (so we could have an omap_connect_clk() function like
sysbus_connect_irq()). [This is about the only thing inclining
me in favour of an _init routine. I guess you touch on the idea
of an omap-specific bus below.]

PS: on the subject of clocks, this is how a later qdevification patch
in my stack does the wiring up of the uart:

s-uart[0] = qdev_create(NULL, omap_uart);
s-uart[0]-id = uart1;
qdev_prop_set_uint32(s-uart[0], mmio_size, 0x1000);
qdev_prop_set_uint32(s-uart[0], baudrate,
 omap_clk_getrate(omap_findclk(s, uart1_fclk)) / 16);
qdev_prop_set_chr(s-uart[0], chardev, serial_hds[0]);
qdev_init_nofail(s-uart[0]);
busdev = sysbus_from_qdev(s-uart[0]);
sysbus_connect_irq(busdev, 0, s-irq[0][OMAP_INT_24XX_UART1_IRQ]);
sysbus_connect_irq(busdev, 1, s-drq[OMAP24XX_DMA_UART1_TX]);
sysbus_connect_irq(busdev, 2, s-drq[OMAP24XX_DMA_UART1_RX]);
sysbus_mmio_map(busdev, 0, omap_l4_base(omap_l4ta(s-l4, 19), 0));

...it would be useful to know if you're going to object to how it's
dealing with the clock there so I can fix it in advance and avoid
a round of review.

 Would it make more sense to pass the ta structures instead of base
 adresses to the qdev? Have you considered how difficult l4 would be
 to convert to a QBus?

Hmm. I hadn't thought about that. Does it buy us anything useful?
I'm not sure how it would interact with wanting to be able to
put plain-old-sysbus devices onto the bus (eg the OHCI USB).

Thanks for the review.

-- PMM



[Qemu-devel] [PATCH v5 11/18] qapi: add qapi.py helper libraries

2011-07-05 Thread Michael Roth

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 scripts/qapi.py |  203 +++
 1 files changed, 203 insertions(+), 0 deletions(-)
 create mode 100644 scripts/qapi.py

diff --git a/scripts/qapi.py b/scripts/qapi.py
new file mode 100644
index 000..56af232
--- /dev/null
+++ b/scripts/qapi.py
@@ -0,0 +1,203 @@
+#
+# QAPI helper library
+#
+# Copyright IBM, Corp. 2011
+#
+# Authors:
+#  Anthony Liguori aligu...@us.ibm.com
+#
+# This work is licensed under the terms of the GNU GPLv2.
+# See the COPYING.LIB file in the top-level directory.
+
+from ordereddict import OrderedDict
+
+def tokenize(data):
+while len(data):
+if data[0] in ['{', '}', ':', ',', '[', ']']:
+yield data[0]
+data = data[1:]
+elif data[0] in ' \n':
+data = data[1:]
+elif data[0] == ':
+data = data[1:]
+string = ''
+while data[0] != ':
+string += data[0]
+data = data[1:]
+data = data[1:]
+yield string
+
+def parse(tokens):
+if tokens[0] == '{':
+ret = OrderedDict()
+tokens = tokens[1:]
+while tokens[0] != '}':
+key = tokens[0]
+tokens = tokens[1:]
+
+tokens = tokens[1:] # :
+
+value, tokens = parse(tokens)
+
+if tokens[0] == ',':
+tokens = tokens[1:]
+
+ret[key] = value
+tokens = tokens[1:]
+return ret, tokens
+elif tokens[0] == '[':
+ret = []
+tokens = tokens[1:]
+while tokens[0] != ']':
+value, tokens = parse(tokens)
+if tokens[0] == ',':
+tokens = tokens[1:]
+ret.append(value)
+tokens = tokens[1:]
+return ret, tokens
+else:
+return tokens[0], tokens[1:]
+
+def evaluate(string):
+return parse(map(lambda x: x, tokenize(string)))[0]
+
+def parse_schema(fp):
+exprs = []
+expr = ''
+expr_eval = None
+
+for line in fp:
+if line.startswith('#') or line == '\n':
+continue
+
+if line.startswith(' '):
+expr += line
+elif expr:
+expr_eval = evaluate(expr)
+if expr_eval.has_key('enum'):
+add_enum(expr_eval['enum'])
+elif expr_eval.has_key('union'):
+add_enum('%sKind' % expr_eval['union'])
+exprs.append(expr_eval)
+expr = line
+else:
+expr += line
+
+if expr:
+expr_eval = evaluate(expr)
+if expr_eval.has_key('enum'):
+add_enum(expr_eval['enum'])
+elif expr_eval.has_key('union'):
+add_enum('%sKind' % expr_eval['union'])
+exprs.append(expr_eval)
+
+return exprs
+
+def parse_args(typeinfo):
+for member in typeinfo:
+argname = member
+argentry = typeinfo[member]
+optional = False
+structured = False
+if member.startswith('*'):
+argname = member[1:]
+optional = True
+if isinstance(argentry, OrderedDict):
+structured = True
+yield (argname, argentry, optional, structured)
+
+def de_camel_case(name):
+new_name = ''
+for ch in name:
+if ch.isupper() and new_name:
+new_name += '_'
+if ch == '-':
+new_name += '_'
+else:
+new_name += ch.lower()
+return new_name
+
+def camel_case(name):
+new_name = ''
+first = True
+for ch in name:
+if ch in ['_', '-']:
+first = True
+elif first:
+new_name += ch.upper()
+first = False
+else:
+new_name += ch.lower()
+return new_name
+
+def c_var(name):
+return '_'.join(name.split('-')).lstrip(*)
+
+def c_list_type(name):
+return '%sList' % name
+
+def type_name(name):
+if type(name) == list:
+return c_list_type(name[0])
+return name
+
+enum_types = []
+
+def add_enum(name):
+global enum_types
+enum_types.append(name)
+
+def is_enum(name):
+global enum_types
+return (name in enum_types)
+
+def c_type(name):
+if name == 'str':
+return 'char *'
+elif name == 'int':
+return 'int64_t'
+elif name == 'bool':
+return 'bool'
+elif name == 'number':
+return 'double'
+elif type(name) == list:
+return '%s *' % c_list_type(name[0])
+elif is_enum(name):
+return name
+elif name == None or len(name) == 0:
+return 'void'
+elif name == name.upper():
+return '%sEvent *' % camel_case(name)
+else:
+return '%s *' % name
+
+def genindent(count):
+ret = 
+for i in range(count):
+ret +=  
+return ret
+
+indent_level = 0
+
+def push_indent(indent_amount=4):
+global indent_level
+indent_level += indent_amount
+
+def 

[Qemu-devel] [PATCH v6 1/4] guest agent: command state class

2011-07-05 Thread Michael Roth

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 Makefile|4 ++-
 configure   |1 +
 qga/guest-agent-command-state.c |   73 +++
 qga/guest-agent-core.h  |   25 +
 4 files changed, 102 insertions(+), 1 deletions(-)
 create mode 100644 qga/guest-agent-command-state.c
 create mode 100644 qga/guest-agent-core.h

diff --git a/Makefile b/Makefile
index cbd2d77..6c3ba71 100644
--- a/Makefile
+++ b/Makefile
@@ -181,6 +181,8 @@ test-visitor: test-visitor.o qfloat.o qint.o qdict.o 
qstring.o qlist.o qbool.o $
 test-qmp-commands.o: $(addprefix $(qapi-dir)/, test-qapi-types.c 
test-qapi-types.h test-qapi-visit.c test-qapi-visit.h test-qmp-marshal.c 
test-qmp-commands.h)
 test-qmp-commands: test-qmp-commands.o qfloat.o qint.o qdict.o qstring.o 
qlist.o qbool.o $(qapi-obj-y) error.o osdep.o qemu-malloc.o $(oslib-obj-y) 
qjson.o json-streamer.o json-lexer.o json-parser.o qerror.o qemu-error.o 
qemu-tool.o $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o 
$(qapi-dir)/test-qmp-marshal.o module.o
 
+QGALIB=qga/guest-agent-command-state.o
+
 QEMULIBS=libhw32 libhw64 libuser libdis libdis-user
 
 clean:
@@ -189,7 +191,7 @@ clean:
rm -f qemu-options.def
rm -f *.o *.d *.a *.lo $(TOOLS) TAGS cscope.* *.pod *~ */*~
rm -Rf .libs
-   rm -f slirp/*.o slirp/*.d audio/*.o audio/*.d block/*.o block/*.d 
net/*.o net/*.d fsdev/*.o fsdev/*.d ui/*.o ui/*.d qapi/*.o qapi/*.d
+   rm -f slirp/*.o slirp/*.d audio/*.o audio/*.d block/*.o block/*.d 
net/*.o net/*.d fsdev/*.o fsdev/*.d ui/*.o ui/*.d qapi/*.o qapi/*.d qga/*.o 
qga/*.d
rm -f qemu-img-cmds.h
rm -f trace.c trace.h trace.c-timestamp trace.h-timestamp
rm -f trace-dtrace.dtrace trace-dtrace.dtrace-timestamp
diff --git a/configure b/configure
index 02c552e..6a03002 100755
--- a/configure
+++ b/configure
@@ -3487,6 +3487,7 @@ DIRS=$DIRS pc-bios/spapr-rtas
 DIRS=$DIRS roms/seabios roms/vgabios
 DIRS=$DIRS fsdev ui
 DIRS=$DIRS qapi
+DIRS=$DIRS qga
 FILES=Makefile tests/Makefile
 FILES=$FILES tests/cris/Makefile tests/cris/.gdbinit
 FILES=$FILES pc-bios/optionrom/Makefile pc-bios/keymaps
diff --git a/qga/guest-agent-command-state.c b/qga/guest-agent-command-state.c
new file mode 100644
index 000..bc6e0bd
--- /dev/null
+++ b/qga/guest-agent-command-state.c
@@ -0,0 +1,73 @@
+/*
+ * QEMU Guest Agent command state interfaces
+ *
+ * Copyright IBM Corp. 2011
+ *
+ * Authors:
+ *  Michael Roth  mdr...@linux.vnet.ibm.com
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include glib.h
+#include qga/guest-agent-core.h
+
+struct GACommandState {
+GSList *groups;
+};
+
+typedef struct GACommandGroup {
+void (*init)(void);
+void (*cleanup)(void);
+} GACommandGroup;
+
+/* handle init/cleanup for stateful guest commands */
+
+void ga_command_state_add(GACommandState *cs,
+  void (*init)(void),
+  void (*cleanup)(void))
+{
+GACommandGroup *cg = qemu_mallocz(sizeof(GACommandGroup));
+cg-init = init;
+cg-cleanup = cleanup;
+cs-groups = g_slist_append(cs-groups, cg);
+}
+
+static void ga_command_group_init(gpointer opaque, gpointer unused)
+{
+GACommandGroup *cg = opaque;
+
+g_assert(cg);
+if (cg-init) {
+cg-init();
+}
+}
+
+void ga_command_state_init_all(GACommandState *cs)
+{
+g_assert(cs);
+g_slist_foreach(cs-groups, ga_command_group_init, NULL);
+}
+
+static void ga_command_group_cleanup(gpointer opaque, gpointer unused)
+{
+GACommandGroup *cg = opaque;
+
+g_assert(cg);
+if (cg-cleanup) {
+cg-cleanup();
+}
+}
+
+void ga_command_state_cleanup_all(GACommandState *cs)
+{
+g_assert(cs);
+g_slist_foreach(cs-groups, ga_command_group_cleanup, NULL);
+}
+
+GACommandState *ga_command_state_new(void)
+{
+GACommandState *cs = qemu_mallocz(sizeof(GACommandState));
+cs-groups = NULL;
+return cs;
+}
diff --git a/qga/guest-agent-core.h b/qga/guest-agent-core.h
new file mode 100644
index 000..688f120
--- /dev/null
+++ b/qga/guest-agent-core.h
@@ -0,0 +1,25 @@
+/*
+ * QEMU Guest Agent core declarations
+ *
+ * Copyright IBM Corp. 2011
+ *
+ * Authors:
+ *  Adam Litkeagli...@linux.vnet.ibm.com
+ *  Michael Roth  mdr...@linux.vnet.ibm.com
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include qapi/qmp-core.h
+#include qemu-common.h
+
+#define QGA_VERSION 1.0
+
+typedef struct GACommandState GACommandState;
+
+void ga_command_state_add(GACommandState *cs,
+  void (*init)(void),
+  void (*cleanup)(void));
+void ga_command_state_init_all(GACommandState *cs);
+void ga_command_state_cleanup_all(GACommandState *cs);
+GACommandState 

[Qemu-devel] [PATCH v6 3/4] guest agent: add guest agent commands schema file

2011-07-05 Thread Michael Roth

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 qapi-schema-guest.json |  204 
 1 files changed, 204 insertions(+), 0 deletions(-)
 create mode 100644 qapi-schema-guest.json

diff --git a/qapi-schema-guest.json b/qapi-schema-guest.json
new file mode 100644
index 000..367b42d
--- /dev/null
+++ b/qapi-schema-guest.json
@@ -0,0 +1,204 @@
+# *-*- Mode: Python -*-*
+
+##
+# @guest-sync:
+#
+# Echo back a unique integer value
+#
+# This is used by clients talking to the guest agent over the
+# wire to ensure the stream is in sync and doesn't contain stale
+# data from previous client. All guest agent responses should be
+# ignored until the provided unique integer value is returned,
+# and it is up to the client to handle stale whole or
+# partially-delivered JSON text in such a way that this response
+# can be obtained.
+#
+# Such clients should also preceed this command
+# with a 0xFF byte to make such the guest agent flushes any
+# partially read JSON data from a previous session.
+#
+# @id: randomly generated 64-bit integer
+#
+# Returns: The unique integer id passed in by the client
+#
+# Since: 0.15.0
+##
+{ 'command': 'guest-sync'
+  'data':{ 'id': 'int' },
+  'returns': 'int' }
+
+##
+# @guest-ping:
+#
+# Ping the guest agent, a non-error return implies success
+#
+# Since: 0.15.0
+##
+{ 'command': 'guest-ping' }
+
+##
+# @guest-info:
+#
+# Get some information about the guest agent.
+#
+# Since: 0.15.0
+##
+{ 'type': 'GuestAgentInfo', 'data': {'version': 'str'} }
+{ 'command': 'guest-info',
+  'returns': 'GuestAgentInfo' }
+
+##
+# @guest-shutdown:
+#
+# Initiate guest-activated shutdown. Note: this is an asynchronous
+# shutdown request, with no guaruntee of successful shutdown. Errors
+# will be logged to guest's syslog.
+#
+# @mode: halt, powerdown, or reboot
+#
+# Returns: Nothing on success
+#
+# Since: 0.15.0
+##
+{ 'command': 'guest-shutdown', 'data': { 'mode': 'str' } }
+
+##
+# @guest-file-open:
+#
+# Open a file in the guest and retrieve a file handle for it
+#
+# @filepath: Full path to the file in the guest to open.
+#
+# @mode: #optional open mode, as per fopen(), r is the default.
+#
+# Returns: Guest file handle on success.
+#  If @filepath cannot be opened, OpenFileFailed
+#
+# Since: 0.15.0
+##
+{ 'command': 'guest-file-open',
+  'data':{ 'filepath': 'str', '*mode': 'str' },
+  'returns': 'int' }
+
+##
+# @guest-file-read:
+#
+# Read from an open file in the guest
+#
+# @filehandle: filehandle returned by guest-file-open
+#
+# @count: maximum number of bytes to read
+#
+# Returns: GuestFileRead on success.
+#  If @filehandle is not open, OpenFileFailed
+#
+# Since: 0.15.0
+##
+{ 'type': 'GuestFileRead',
+  'data': { 'count': 'int', 'buf': 'str', 'eof': 'bool' } }
+
+{ 'command': 'guest-file-read',
+  'data':{ 'filehandle': 'int', 'count': 'int' },
+  'returns': 'GuestFileRead' }
+
+##
+# @guest-file-write:
+#
+# Write to an open file in the guest
+#
+# @filehandle: filehandle returned by guest-file-open
+#
+# @data_b64: base64-encoded string representing data to be written
+#
+# @count: bytes to write (actual bytes, after b64-decode)
+#
+# Returns: GuestFileWrite on success.
+#  If @filehandle is not opened, OpenFileFailed
+#
+# Since: 0.15.0
+##
+{ 'type': 'GuestFileWrite',
+  'data': { 'count': 'int', 'eof': 'bool' } }
+{ 'command': 'guest-file-write',
+  'data':{ 'filehandle': 'int', 'data_b64': 'str', 'count': 'int' },
+  'returns': 'GuestFileWrite' }
+
+##
+# @guest-file-seek:
+#
+# Seek to a position in the file, as with fseek(), and return the
+# current file position afterward. Also encapsulates ftell()'s
+# functionality, just Set offset=0, whence=SEEK_CUR.
+#
+# @filehandle: filehandle returned by guest-file-open
+#
+# @offset: bytes to skip over in the file stream
+#
+# @whence: SEEK_SET, SEEK_CUR, or SEEK_END, as with fseek()
+#
+# Returns: GuestFileSeek on success.
+#  If @filehandle is not opened, OpenFileFailed
+#
+# Since: 0.15.0
+##
+{ 'type': 'GuestFileSeek',
+  'data': { 'position': 'int', 'eof': 'bool' } }
+
+{ 'command': 'guest-file-seek',
+  'data':{ 'filehandle': 'int', 'offset': 'int', 'whence': 'int' },
+  'returns': 'GuestFileSeek' }
+
+##
+# @guest-file-close:
+#
+# Close an open file in the guest
+#
+# @filehandle: filehandle returned by guest-file-open
+#
+# Returns: Nothing on success.
+#  If @filehandle is not opened, OpenFileFailed
+#
+# Since: 0.15.0
+##
+{ 'command': 'guest-file-close',
+  'data': { 'filehandle': 'int' } }
+
+##
+# @guest-fsfreeze-status:
+#
+# get guest fsfreeze state
+#
+# Returns: GuestFsfreezeStatus (enumeration starts at 1)
+#
+# Since: 0.15.0
+##
+{ 'enum': 'GuestFsfreezeStatus',
+  'data': [ 'thawed', 'inprogress', 'frozen', 'error' ] }
+{ 'command': 'guest-fsfreeze-status',
+  'returns': 'GuestFsfreezeStatus' }
+
+##
+# @guest-fsfreeze-freeze:
+#
+# Sync and freeze all non-network guest filesystems
+#
+# 

[Qemu-devel] [PATCH v6 2/4] guest agent: qemu-ga daemon

2011-07-05 Thread Michael Roth
This is the actual guest daemon, it listens for requests over a
virtio-serial/isa-serial/unix socket channel and routes them through
to dispatch routines, and writes the results back to the channel in
a manner similar to QMP.

A shorthand invocation:

  qemu-ga -d

Is equivalent to:

  qemu-ga -c virtio-serial -p /dev/virtio-ports/org.qemu.guest_agent \
  -p /var/run/qemu-guest-agent.pid -d

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 Makefile   |   10 +-
 qemu-ga.c  |  651 
 qga/guest-agent-core.h |4 +
 3 files changed, 661 insertions(+), 4 deletions(-)
 create mode 100644 qemu-ga.c

diff --git a/Makefile b/Makefile
index 6c3ba71..b2e8593 100644
--- a/Makefile
+++ b/Makefile
@@ -140,7 +140,7 @@ endif
 ##
 
 qemu-img.o: qemu-img-cmds.h
-qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o cmd.o: $(GENERATED_HEADERS)
+qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o cmd.o qemu-ga.o: 
$(GENERATED_HEADERS)
 
 qemu-img$(EXESUF): qemu-img.o qemu-tool.o qemu-error.o $(oslib-obj-y) 
$(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) 
qemu-timer-common.o
 
@@ -163,7 +163,7 @@ check-qfloat: check-qfloat.o qfloat.o $(CHECK_PROG_DEPS)
 check-qjson: check-qjson.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o 
qjson.o json-streamer.o json-lexer.o json-parser.o error.o qerror.o 
qemu-error.o $(CHECK_PROG_DEPS)
 
 qapi-dir := qapi-generated
-$(qapi-obj-y) test-visitor.o test-qmp-commands.o: QEMU_CFLAGS += -I $(qapi-dir)
+$(qapi-obj-y) test-visitor.o test-qmp-commands.o qemu-ga$(EXESUF): QEMU_CFLAGS 
+= -I $(qapi-dir)
 
 $(qapi-dir)/test-qapi-types.c: $(qapi-dir)/test-qapi-types.h
 $(qapi-dir)/test-qapi-types.h: $(SRC_PATH)/qapi-schema-test.json 
$(SRC_PATH)/scripts/qapi-types.py
@@ -183,13 +183,15 @@ test-qmp-commands: test-qmp-commands.o qfloat.o qint.o 
qdict.o qstring.o qlist.o
 
 QGALIB=qga/guest-agent-command-state.o
 
+qemu-ga$(EXESUF): qemu-ga.o $(QGALIB) qemu-tool.o qemu-error.o error.o 
$(oslib-obj-y) $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) 
$(qapi-obj-y) qemu-timer-common.o qemu-sockets.o module.o qapi/qmp-dispatch.o 
qapi/qmp-registry.o
+
 QEMULIBS=libhw32 libhw64 libuser libdis libdis-user
 
 clean:
 # avoid old build problems by removing potentially incorrect old files
rm -f config.mak op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h 
gen-op-arm.h
rm -f qemu-options.def
-   rm -f *.o *.d *.a *.lo $(TOOLS) TAGS cscope.* *.pod *~ */*~
+   rm -f *.o *.d *.a *.lo $(TOOLS) qemu-ga TAGS cscope.* *.pod *~ */*~
rm -Rf .libs
rm -f slirp/*.o slirp/*.d audio/*.o audio/*.d block/*.o block/*.d 
net/*.o net/*.d fsdev/*.o fsdev/*.d ui/*.o ui/*.d qapi/*.o qapi/*.d qga/*.o 
qga/*.d
rm -f qemu-img-cmds.h
@@ -385,4 +387,4 @@ tarbin:
$(mandir)/man8/qemu-nbd.8
 
 # Include automatically generated dependency files
--include $(wildcard *.d audio/*.d slirp/*.d block/*.d net/*.d ui/*.d qapi/*.d)
+-include $(wildcard *.d audio/*.d slirp/*.d block/*.d net/*.d ui/*.d qapi/*.d 
qga/*.d)
diff --git a/qemu-ga.c b/qemu-ga.c
new file mode 100644
index 000..649c16a
--- /dev/null
+++ b/qemu-ga.c
@@ -0,0 +1,651 @@
+/*
+ * QEMU Guest Agent
+ *
+ * Copyright IBM Corp. 2011
+ *
+ * Authors:
+ *  Adam Litkeagli...@linux.vnet.ibm.com
+ *  Michael Roth  mdr...@linux.vnet.ibm.com
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include stdlib.h
+#include stdio.h
+#include stdbool.h
+#include glib.h
+#include gio/gio.h
+#include getopt.h
+#include termios.h
+#include syslog.h
+#include qemu_socket.h
+#include json-streamer.h
+#include json-parser.h
+#include qint.h
+#include qjson.h
+#include qga/guest-agent-core.h
+#include module.h
+#include signal.h
+
+#define QGA_VIRTIO_PATH_DEFAULT /dev/virtio-ports/org.qemu.guest_agent
+#define QGA_PIDFILE_DEFAULT /var/run/qemu-va.pid
+#define QGA_BAUDRATE_DEFAULT B38400 /* for isa-serial channels */
+#define QGA_TIMEOUT_DEFAULT 30*1000 /* ms */
+
+struct GAState {
+JSONMessageParser parser;
+GMainLoop *main_loop;
+guint conn_id;
+GSocket *conn_sock;
+GIOChannel *conn_channel;
+guint listen_id;
+GSocket *listen_sock;
+GIOChannel *listen_channel;
+const char *path;
+const char *method;
+bool virtio; /* fastpath to check for virtio to deal with poll() quirks */
+GACommandState *command_state;
+GLogLevelFlags log_level;
+FILE *log_file;
+bool logging_enabled;
+};
+
+static struct GAState *ga_state;
+
+static void quit_handler(int sig)
+{
+g_debug(recieved signal num %d, quitting);
+
+if (g_main_loop_is_running(ga_state-main_loop)) {
+g_main_loop_quit(ga_state-main_loop);
+}
+}
+
+static void register_signal_handlers(void)
+{
+struct sigaction sigact;
+int ret;
+
+

[Qemu-devel] [PATCH v5 13/18] qapi: add qapi-visit.py code generator

2011-07-05 Thread Michael Roth
This is the code generator for qapi visiter functions used to
marshal/unmarshal/dealloc qapi types. It generates the following 2
files:

  $(prefix)qapi-visit.c: visiter function for a particular c type, used
 to automagically convert qobjects into the
 corresponding C type and vice-versa, and well
 as for deallocation memory for an existing C
 type

  $(prefix)qapi-visit.h: declarations for previously mentioned visiter
 functions

$(prefix) is used as decribed for qapi-types.py

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 scripts/qapi-visit.py |  261 +
 1 files changed, 261 insertions(+), 0 deletions(-)
 create mode 100644 scripts/qapi-visit.py

diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
new file mode 100644
index 000..a1a2d33
--- /dev/null
+++ b/scripts/qapi-visit.py
@@ -0,0 +1,261 @@
+#
+# QAPI visitor generator
+#
+# Copyright IBM, Corp. 2011
+#
+# Authors:
+#  Anthony Liguori aligu...@us.ibm.com
+#  Michael Rothmdr...@linux.vnet.ibm.com
+#
+# This work is licensed under the terms of the GNU GPLv2.
+# See the COPYING.LIB file in the top-level directory.
+
+from ordereddict import OrderedDict
+from qapi import *
+import sys
+import os
+import getopt
+
+def generate_visit_struct_body(field_prefix, members):
+ret = 
+if len(field_prefix):
+field_prefix = field_prefix + .
+for argname, argentry, optional, structured in parse_args(members):
+if optional:
+ret += mcgen('''
+visit_start_optional(m, (obj  *obj) ? (*obj)-%(c_prefix)shas_%(c_name)s : 
NULL, %(name)s, errp);
+if ((*obj)-%(prefix)shas_%(c_name)s) {
+''',
+ c_prefix=c_var(field_prefix), prefix=field_prefix,
+ c_name=c_var(argname), name=argname)
+push_indent()
+
+if structured:
+ret += mcgen('''
+visit_start_struct(m, NULL, , %(name)s, 0, errp);
+''',
+ name=argname)
+ret += generate_visit_struct_body(field_prefix + argname, argentry)
+ret += mcgen('''
+visit_end_struct(m, errp);
+''')
+else:
+ret += mcgen('''
+visit_type_%(type)s(m, (obj  *obj) ? (*obj)-%(c_prefix)s%(c_name)s : NULL, 
%(name)s, errp);
+''',
+ c_prefix=c_var(field_prefix), prefix=field_prefix,
+ type=type_name(argentry), c_name=c_var(argname),
+ name=argname)
+
+if optional:
+pop_indent()
+ret += mcgen('''
+}
+visit_end_optional(m, errp);
+''')
+return ret
+
+def generate_visit_struct(name, members):
+ret = mcgen('''
+
+void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error 
**errp)
+{
+visit_start_struct(m, (void **)obj, %(name)s, name, sizeof(%(name)s), 
errp);
+''',
+name=name)
+push_indent()
+ret += generate_visit_struct_body(, members)
+pop_indent()
+
+ret += mcgen('''
+visit_end_struct(m, errp);
+}
+''')
+return ret
+
+def generate_visit_list(name, members):
+return mcgen('''
+
+void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char 
*name, Error **errp)
+{
+GenericList *i;
+
+visit_start_list(m, name, errp);
+
+for (i = visit_next_list(m, (GenericList **)obj, errp); i; i = 
visit_next_list(m, i, errp)) {
+%(name)sList *native_i = (%(name)sList *)i;
+visit_type_%(name)s(m, native_i-value, NULL, errp);
+}
+
+visit_end_list(m, errp);
+}
+''',
+name=name)
+
+def generate_visit_handle(name, typeinfo):
+return mcgen('''
+
+void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error 
**errp)
+{
+visit_start_handle(m, (void **)obj, %(name)s, name, errp);
+visit_type_%(type_name)s(m, (*obj)-handle, handle, errp);
+visit_end_handle(m, errp);
+}
+''',
+name=name, type_name=type_name(typeinfo))
+
+def generate_visit_enum(name, members):
+return mcgen('''
+
+void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error 
**errp)
+{
+visit_type_enum(m, (int *)obj, %(name)s, name, errp);
+}
+''',
+ name=name)
+
+def generate_visit_union(name, members):
+ret = generate_visit_enum('%sKind' % name, members.keys())
+
+ret += mcgen('''
+
+void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error 
**errp)
+{
+}
+''',
+ name=name)
+
+return ret
+
+def generate_declaration(name, members, genlist=True):
+ret = mcgen('''
+
+void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error 
**errp);
+''',
+name=name)
+
+if genlist:
+ret += mcgen('''
+void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char 
*name, Error **errp);
+''',
+ name=name)
+
+

[Qemu-devel] [PATCH v5 14/18] qapi: add qapi-commands.py code generator

2011-07-05 Thread Michael Roth
This is the code generator for qapi command marshaling/dispatch.
Currently only generators for synchronous qapi/qmp functions are
supported. This script generates the following files:

  $(prefix)qmp-marshal.c: command marshal/dispatch functions for each
  QMP command defined in the schema. Functions
  generated by qapi-visit.py are used to
  convert qobjects recieved from the wire into
  function parameters, and uses the same
  visiter functions to convert native C return
  values to qobjects from transmission back
  over the wire.

  $(prefix)qmp-commands.h: Function prototypes for the QMP commands
   specified in the schema.

$(prefix) is used in the same manner as with qapi-types.py

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 scripts/qapi-commands.py |  381 ++
 1 files changed, 381 insertions(+), 0 deletions(-)
 create mode 100644 scripts/qapi-commands.py

diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
new file mode 100644
index 000..5c06bfa
--- /dev/null
+++ b/scripts/qapi-commands.py
@@ -0,0 +1,381 @@
+#
+# QAPI command marshaller generator
+#
+# Copyright IBM, Corp. 2011
+#
+# Authors:
+#  Anthony Liguori aligu...@us.ibm.com
+#  Michael Rothmdr...@linux.vnet.ibm.com
+#
+# This work is licensed under the terms of the GNU GPLv2.
+# See the COPYING.LIB file in the top-level directory.
+
+from ordereddict import OrderedDict
+from qapi import *
+import sys
+import os
+import getopt
+
+def generate_decl_enum(name, members, genlist=True):
+return mcgen('''
+
+void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error 
**errp);
+''',
+name=name)
+
+def generate_command_decl(name, args, ret_type):
+arglist=
+for argname, argtype, optional, structured in parse_args(args):
+argtype = c_type(argtype)
+if argtype == char *:
+argtype = const char *
+if optional:
+arglist += bool has_%s,  % c_var(argname)
+arglist += %s %s,  % (argtype, c_var(argname))
+return mcgen('''
+%(ret_type)s qmp_%(name)s(%(args)sError **errp);
+''',
+ ret_type=c_type(ret_type), name=c_var(name), 
args=arglist).strip()
+
+def gen_sync_call(name, args, ret_type, indent=0):
+ret = 
+arglist=
+retval=
+if ret_type:
+retval = retval = 
+for argname, argtype, optional, structured in parse_args(args):
+if optional:
+arglist += has_%s,  % c_var(argname)
+arglist += %s,  % (c_var(argname))
+push_indent(indent)
+ret = mcgen('''
+%(retval)sqmp_%(name)s(%(args)serrp);
+
+''',
+name=c_var(name), args=arglist, retval=retval).rstrip()
+if ret_type:
+ret += \n + mcgen(
+%(marshal_output_call)s
+''',
+marshal_output_call=gen_marshal_output_call(name, 
ret_type)).rstrip()
+pop_indent(indent)
+return ret.rstrip()
+
+
+def gen_marshal_output_call(name, ret_type):
+if not ret_type:
+return 
+return qmp_marshal_output_%s(retval, ret, errp); % c_var(name)
+
+def gen_visitor_output_containers_decl(ret_type):
+ret = 
+push_indent()
+if ret_type:
+ret += mcgen('''
+QmpOutputVisitor *mo;
+QapiDeallocVisitor *md;
+Visitor *v;
+''')
+pop_indent()
+
+return ret
+
+def gen_visitor_input_containers_decl(args):
+ret = 
+
+push_indent()
+if len(args)  0:
+ret += mcgen('''
+QmpInputVisitor *mi;
+QapiDeallocVisitor *md;
+Visitor *v;
+''')
+pop_indent()
+
+return ret.rstrip()
+
+def gen_visitor_input_vars_decl(args):
+ret = 
+push_indent()
+for argname, argtype, optional, structured in parse_args(args):
+if optional:
+ret += mcgen('''
+bool has_%(argname)s = false;
+''',
+ argname=c_var(argname))
+if c_type(argtype).endswith(*):
+ret += mcgen('''
+%(argtype)s %(argname)s = NULL;
+''',
+ argname=c_var(argname), argtype=c_type(argtype))
+else:
+ret += mcgen('''
+%(argtype)s %(argname)s;
+''',
+ argname=c_var(argname), argtype=c_type(argtype))
+
+pop_indent()
+return ret.rstrip()
+
+def gen_visitor_input_block(args, obj, dealloc=False):
+ret = 
+if len(args) == 0:
+return ret
+
+push_indent()
+
+if dealloc:
+ret += mcgen('''
+md = qapi_dealloc_visitor_new();
+v = qapi_dealloc_get_visitor(md);
+''')
+else:
+ret += mcgen('''
+mi = qmp_input_visitor_new(%(obj)s);
+v = qmp_input_get_visitor(mi);
+''',
+ obj=obj)
+
+for argname, argtype, optional, structured in parse_args(args):
+if optional:
+ret += mcgen('''
+visit_start_optional(v, has_%(c_name)s, 

Re: [Qemu-devel] [PATCH] pci: add standard bridge device

2011-07-05 Thread Isaku Yamahata
On Mon, Jul 04, 2011 at 12:43:59PM +0300, Michael S. Tsirkin wrote:
 +/* Mapping mandated by PCI-to-PCI Bridge architecture specification,
 + * revision 1.2 */
 +/* Table 9-1: Interrupt Binding for Devices Behind a Bridge */
 +static int pci_bridge_dev_map_irq_fn(PCIDevice *dev, int irq_num)
 +{
 +return (irq_num + PCI_SLOT(dev-devfn) + irq_num) % PCI_NUM_PINS;
   ^^^  ^^^
Typo. There are 2 irq_num.

-- 
yamahata



Re: [Qemu-devel] [PATCH 5/5] megasas: LSI Megaraid SAS emulation

2011-07-05 Thread Alexander Graf

On 07/05/2011 01:03 PM, Hannes Reinecke wrote:

This patch adds an emulation for the LSI Megaraid SAS 8708EM2 HBA.

Signed-off-by: Hannes Reineckeh...@suse.de
---
  Makefile.objs   |1 +
  default-configs/pci.mak |1 +
  hw/megasas.c| 1950 +++
  hw/mfi.h| 1197 +
  hw/pci_ids.h|3 +-
  trace-events|   71 ++
  6 files changed, 3222 insertions(+), 1 deletions(-)
  create mode 100644 hw/megasas.c
  create mode 100644 hw/mfi.h

diff --git a/Makefile.objs b/Makefile.objs
index cea15e4..6f5d113 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -258,6 +258,7 @@ hw-obj-$(CONFIG_AHCI) += ide/ich.o

  # SCSI layer
  hw-obj-$(CONFIG_LSI_SCSI_PCI) += lsi53c895a.o
+hw-obj-$(CONFIG_MEGASAS_SCSI_PCI) += megasas.o
  hw-obj-$(CONFIG_ESP) += esp.o

  hw-obj-y += dma-helpers.o sysbus.o isa-bus.o
diff --git a/default-configs/pci.mak b/default-configs/pci.mak
index 22bd350..fabb56c 100644
--- a/default-configs/pci.mak
+++ b/default-configs/pci.mak
@@ -9,6 +9,7 @@ CONFIG_EEPRO100_PCI=y
  CONFIG_PCNET_PCI=y
  CONFIG_PCNET_COMMON=y
  CONFIG_LSI_SCSI_PCI=y
+CONFIG_MEGASAS_SCSI_PCI=y
  CONFIG_RTL8139_PCI=y
  CONFIG_E1000_PCI=y
  CONFIG_IDE_CORE=y
diff --git a/hw/megasas.c b/hw/megasas.c
new file mode 100644
index 000..613bb0a
--- /dev/null
+++ b/hw/megasas.c
@@ -0,0 +1,1950 @@
+/*
+ * QEMU MegaRAID SAS 8708EM2 Host Bus Adapter emulation
+ *
+ * Copyright (c) 2009-2011 Hannes Reinecke, SUSE Labs
+ *
+ * This code is licensed under the LGPL.
+ */
+
+#include hw.h
+#include pci.h
+#include dma.h
+#include iov.h
+#include scsi.h
+#include scsi-defs.h
+#include block_int.h
+#include trace.h
+
+#include mfi.h
+
+#ifdef DEBUG_MEGASAS
+#define DPRINTF(fmt, ...) \
+do {\
+printf(megasas:  fmt , ## __VA_ARGS__);   \
+} while (0)
+#else
+#define DPRINTF(fmt, ...) do {} while (0)
+#endif
+
+/* Static definitions */
+#define MEGASAS_VERSION 1.30
+#define MEGASAS_MAX_FRAMES 2048 /* Firmware limit at 65535 */
+#define MEGASAS_DEFAULT_FRAMES 1000 /* Windows requires this */
+#define MEGASAS_MAX_SGE 256 /* Firmware limit */
+#define MEGASAS_DEFAULT_SGE 80
+#define MEGASAS_MAX_SECTORS 0x  /* No real limit */
+#define MEGASAS_MAX_ARRAYS 128
+
+const char *mfi_frame_desc[] = {
+MFI init, LD Read, LD Write, LD SCSI, PD SCSI,
+MFI Doorbell, MFI Abort, MFI SMP, MFI Stop};
+
+struct megasas_cmd_t {
+int index;
+int context;
+int count;
+
+target_phys_addr_t pa;
+target_phys_addr_t pa_size;
+union mfi_frame *frame;
+SCSIRequest *req;
+struct iovec *iov;
+void *iov_buf;
+size_t iov_cnt;
+size_t iov_size;
+size_t iov_offset;
+SCSIDevice *sdev;
+struct megasas_state_t *state;
+};
+
+typedef struct megasas_state_t {
+PCIDevice dev;
+int mmio_io_addr;
+int io_addr;
+int queue_addr;
+uint32_t frame_hi;
+
+int fw_state;
+uint32_t fw_sge;
+uint32_t fw_cmds;
+int fw_luns;
+int intr_mask;
+int doorbell;
+int busy;
+char *raid_mode_str;
+int is_jbod;
+
+int event_count;
+int shutdown_event;
+int boot_event;
+
+uint64_t reply_queue_pa;
+void *reply_queue;
+int reply_queue_len;
+int reply_queue_index;
+uint64_t consumer_pa;
+uint64_t producer_pa;
+
+struct megasas_cmd_t frames[MEGASAS_MAX_FRAMES];
+
+SCSIBus bus;
+} MPTState;
+
+#define MEGASAS_INTR_DISABLED_MASK 0x
+
+#define MEGASAS_INTR_ENABLED(s) \
+(((s)-intr_mask  MEGASAS_INTR_DISABLED_MASK) !=   \
+ MEGASAS_INTR_DISABLED_MASK)


Please make this a static function


+
+#define megasas_frame_set_cmd_status(f, v)   \
+stb_phys((f) + offsetof(struct mfi_frame_header, cmd_status), v);
+
+#define megasas_frame_set_scsi_status(f, v)  \
+stb_phys((f) + offsetof(struct mfi_frame_header, scsi_status), v);
+
+#define megasas_frame_get_cmd(f)\
+ldub_phys((f) + offsetof(struct mfi_frame_header, frame_cmd))
+
+#define megasas_frame_get_context(f)\
+ldl_phys(frame_addr + offsetof(struct mfi_frame_header, context));


... these too :).


+
+static void megasas_soft_reset(MPTState *s);
+
+static int megasas_map_sgl(struct megasas_cmd_t *cmd, int pa_offset)
+{
+int i;
+uint16_t flags = le16_to_cpu(cmd-frame-header.flags);
+int is_sgl64 = (flags  MFI_FRAME_SGL64) ? 1 : 0;
+int is_write = (flags  MFI_FRAME_DIR_WRITE) ? 1 : 0;
+int sgl_addr_size = is_sgl64 ? sizeof(uint64_t) : sizeof(uint32_t);
+size_t iov_count = 0;
+
+cmd-iov = qemu_malloc(sizeof(struct iovec) *
+   (cmd-frame-header.sge_count + 1));


Is there a maximum number of sg elements? 

[Qemu-devel] [QAPI+QGA 3/3] QEMU Guest Agent (virtagent) v6

2011-07-05 Thread Michael Roth
This is Set 3/3 of the QAPI+QGA patchsets.

These patches apply on top of qapi-backport-set2-v5, and can also be obtained 
from:
git://repo.or.cz/qemu/mdroth.git qapi-backport-set3-v6

(Set1+2 are a backport of some of the QAPI-related work from Anthony's
glib tree. The main goal is to get the basic code generation infrastructure in
place so that it can be used by the guest agent to implement a QMP-like guest
interface, and so that future work regarding the QMP conversion to QAPI can be
decoupled from the infrastructure bits. Set3 is the Qemu Guest Agent
(virtagent), rebased on the new code QAPI code generation infrastructure. This
is the first user of QAPI, QMP will follow.)
___

CHANGES SINCE V5:
 - switched to using qemu malloc/list functions where possible
 - removed unused proxy_path field in struct GAState
 - pid file now opened write-only, removed lockf() in favor of O_EXCL, added 
SIGINT/SIGTERM signal handlers to handle cleanup
 - cleaned up error-handling, switched to asserts where appropriate, removed 
unecessary gotos and NULL checks for qemu_free()/qobject_decref()
 - refactored send_payload() using helper functions
 - fixed improper handling of pidfile fd==0
 - changed guest-shutdown's shutdown_mode param to mode
 - switched to using kernel-generated FDs for guest-file-open rather than an 
autoincrement value
 - add maximum chunk size of guest-file-read/guest-file-write
 - added checks to avoid guest-file-write from writing data beyond the provided 
data buffer
 - made logging best-effort, removed handling of failures to log as errors
 - guest-shutdown exec errors now logged to guest syslog, clarified shutdown's 
asynchronous, no gauruntee nature in schema.

CHANGES SINCE V4:
 - Removed timeout mechanism via worker thread/pthread_cancel due to potential 
memory leak. Will re-introduce guest-side timeout support in future version.
 - Fixed up fsfreeze code to use enums specified within the guest agent's qapi 
schema.
 - Fixed memory leak due to a log statement, and added missing cleanup 
functions for heap-allocated g_error objects.
 - Made mode param to guest-file-open optional, defaults to r (read-only)

CHANGES SINCE V3:
 - Fixed error-handling issues in fsfreeze commands leading to certain mounted 
directories causing freeze/thaw operations to fail
 - Added cleanup hook to thaw filesystems on graceful guest agent exit
 - Removed unused enum values and added additional details to schema 
documentation
 - Fixed build issue that was missed due to deprecated files in source tree, 
removed unused includes

CHANGES SINCE V2:
 - Rebased on new QAPI code generation framework
 - Dropped ability for QMP to act as a proxy for the guest agent, will be added 
when new QMP server is backported from Anthony's glib tree
 - Replaced negotiation/control events with a simple 2-way handshake 
implemented by a standard RPC (guest-sync)
 - Removed enforcement of pristine sessions, state is now global/persistant 
across multiple clients/connections
 - Fixed segfault in logging code
 - Added Jes' filesystem freeze patches 
 - General cleanups

CHANGES SINCE V1:
 - Added guest agent worker thread to execute RPCs in the guest. With this in 
place we have a reliable timeout mechanism for hung commands, currently set at 
30 seconds.
 - Add framework for registering init/cleanup routines for stateful RPCs to 
clean up after themselves after a timeout.
 - Added the following RPCs: guest-file-{open,close,read,write,seek}, 
guest-shutdown, guest-info, and removed stubs for guest-view-file (now 
deprecated)
 - Added GUEST_AGENT_UP/GUEST_AGENT_DOWN QMP events
 - Switched to a TCP-style host-initiated 3-way handshake for channel 
negotiation, this simplifies client negotiation/interaction over the wire
 - Added configurable log level/log file/pid file options for guest agent
 - Various fixes for bugs/memory leaks and checkpatch.pl fixups

ISSUES/TODOS:
 - Add unit tests for guest agent wire protocol

OVERVIEW

For a better overview of what these patches are meant to accomplish, please 
reference the RFC for virtagent:

http://comments.gmane.org/gmane.comp.emulators.qemu/96096

These patches integrate the previous virtagent guest agent work directly in 
QAPI/QMP to leverage it's auto-generated marshalling code. This has numerous 
benefits:

 - addresses previous concerns over relying on external libraries to handle 
data encapsulation
 - reduces the need for manual unmarshalling of requests/responses, which makes 
adding new RPCs much safer/less error-prone, as well as cutting down on 
redundant code
 - QAPI documentation aligns completely with guest-side RPC implementation
 - is Just Better (TM)

BUILD/USAGE

build:
  ./configure --target-list=x86_64-softmmu
  make
  make qemu-ga #should be built on|for target guest

start guest:
  qemu \
  -drive file=/home/mdroth/vm/rhel6_64_base.raw,snapshot=off,if=virtio \
  -net nic,model=virtio,macaddr=52:54:00:12:34:00 \
  -net tap,script=/etc/qemu-ifup \
  -vnc :1 -m 1024 

[Qemu-devel] [PATCH v5 16/18] qapi: add test-visitor, tests for gen. visitor code

2011-07-05 Thread Michael Roth

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 Makefile   |   18 +++-
 test-visitor.c |  305 
 2 files changed, 321 insertions(+), 2 deletions(-)
 create mode 100644 test-visitor.c

diff --git a/Makefile b/Makefile
index 42ae4e5..a243c24 100644
--- a/Makefile
+++ b/Makefile
@@ -162,6 +162,19 @@ check-qlist: check-qlist.o qlist.o qint.o 
$(CHECK_PROG_DEPS)
 check-qfloat: check-qfloat.o qfloat.o $(CHECK_PROG_DEPS)
 check-qjson: check-qjson.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o 
qjson.o json-streamer.o json-lexer.o json-parser.o error.o qerror.o 
qemu-error.o $(CHECK_PROG_DEPS)
 
+qapi-dir := qapi-generated
+$(qapi-obj-y) test-visitor.o: QEMU_CFLAGS += -I $(qapi-dir)
+
+$(qapi-dir)/test-qapi-types.c: $(qapi-dir)/test-qapi-types.h
+$(qapi-dir)/test-qapi-types.h: $(SRC_PATH)/qapi-schema-test.json 
$(SRC_PATH)/scripts/qapi-types.py
+   $(call quiet-command,python $(SRC_PATH)/scripts/qapi-types.py -o 
$(qapi-dir) -p test-  $,   GEN   $@)
+$(qapi-dir)/test-qapi-visit.c: $(qapi-dir)/test-qapi-visit.h
+$(qapi-dir)/test-qapi-visit.h: $(SRC_PATH)/qapi-schema-test.json 
$(SRC_PATH)/scripts/qapi-visit.py
+   $(call quiet-command,python $(SRC_PATH)/scripts/qapi-visit.py -o 
$(qapi-dir) -p test-  $,   GEN   $@)
+
+test-visitor.o: $(addprefix $(qapi-dir)/, test-qapi-types.c test-qapi-types.h 
test-qapi-visit.c test-qapi-visit.h)
+test-visitor: test-visitor.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o 
$(qapi-obj-y) error.o osdep.o qemu-malloc.o $(oslib-obj-y) qjson.o 
json-streamer.o json-lexer.o json-parser.o qerror.o qemu-error.o qemu-tool.o 
$(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o
+
 QEMULIBS=libhw32 libhw64 libuser libdis libdis-user
 
 clean:
@@ -170,11 +183,12 @@ clean:
rm -f qemu-options.def
rm -f *.o *.d *.a *.lo $(TOOLS) TAGS cscope.* *.pod *~ */*~
rm -Rf .libs
-   rm -f slirp/*.o slirp/*.d audio/*.o audio/*.d block/*.o block/*.d 
net/*.o net/*.d fsdev/*.o fsdev/*.d ui/*.o ui/*.d
+   rm -f slirp/*.o slirp/*.d audio/*.o audio/*.d block/*.o block/*.d 
net/*.o net/*.d fsdev/*.o fsdev/*.d ui/*.o ui/*.d qapi/*.o qapi/*.d
rm -f qemu-img-cmds.h
rm -f trace.c trace.h trace.c-timestamp trace.h-timestamp
rm -f trace-dtrace.dtrace trace-dtrace.dtrace-timestamp
rm -f trace-dtrace.h trace-dtrace.h-timestamp
+   rm -rf $(qapi-dir)
$(MAKE) -C tests clean
for d in $(ALL_SUBDIRS) $(QEMULIBS) libcacard; do \
if test -d $$d; then $(MAKE) -C $$d $@ || exit 1; fi; \
@@ -363,4 +377,4 @@ tarbin:
$(mandir)/man8/qemu-nbd.8
 
 # Include automatically generated dependency files
--include $(wildcard *.d audio/*.d slirp/*.d block/*.d net/*.d ui/*.d)
+-include $(wildcard *.d audio/*.d slirp/*.d block/*.d net/*.d ui/*.d qapi/*.d)
diff --git a/test-visitor.c b/test-visitor.c
new file mode 100644
index 000..5b2f138
--- /dev/null
+++ b/test-visitor.c
@@ -0,0 +1,305 @@
+#include glib.h
+#include qapi/qmp-output-visitor.h
+#include qapi/qmp-input-visitor.h
+#include test-qapi-types.h
+#include test-qapi-visit.h
+#include qemu-objects.h
+
+typedef struct TestStruct
+{
+int64_t x;
+int64_t y;
+} TestStruct;
+
+typedef struct TestStructList
+{
+TestStruct *value;
+struct TestStructList *next;
+} TestStructList;
+
+static void visit_type_TestStruct(Visitor *v, TestStruct **obj, const char 
*name, Error **errp)
+{
+visit_start_struct(v, (void **)obj, TestStruct, name, 
sizeof(TestStruct), errp);
+visit_type_int(v, (*obj)-x, x, errp);
+visit_type_int(v, (*obj)-y, y, errp);
+visit_end_struct(v, errp);
+}
+
+static void visit_type_TestStructList(Visitor *m, TestStructList ** obj, const 
char *name, Error **errp)
+{
+GenericList *i;
+
+visit_start_list(m, name, errp);
+
+for (i = visit_next_list(m, (GenericList **)obj, errp); i; i = 
visit_next_list(m, i, errp)) {
+TestStructList *native_i = (TestStructList *)i;
+visit_type_TestStruct(m, native_i-value, NULL, errp);
+}
+
+visit_end_list(m, errp);
+}
+
+/* test core visitor methods */
+static void test_visitor_core(void)
+{
+QmpOutputVisitor *mo;
+QmpInputVisitor *mi;
+Visitor *v;
+TestStruct ts = { 42, 82 };
+TestStruct *pts = ts;
+TestStructList *lts = NULL;
+Error *err = NULL;
+QObject *obj;
+QString *str;
+int64_t value = 0;
+
+mo = qmp_output_visitor_new();
+v = qmp_output_get_visitor(mo);
+
+visit_type_TestStruct(v, pts, NULL, err);
+
+obj = qmp_output_get_qobject(mo);
+
+str = qobject_to_json(obj);
+
+printf(%s\n, qstring_get_str(str));
+
+QDECREF(str);
+
+obj = QOBJECT(qint_from_int(0x42));
+
+mi = qmp_input_visitor_new(obj);
+v = qmp_input_get_visitor(mi);
+
+visit_type_int(v, value, NULL, err);
+if (err) {
+g_error(%s, error_get_pretty(err));
+}
+
+g_assert(value == 0x42);
+
+qobject_decref(obj);
+
+

Re: [Qemu-devel] KVM call agenda for June 28

2011-07-05 Thread Dor Laor

On 07/05/2011 03:58 PM, Marcelo Tosatti wrote:

On Tue, Jul 05, 2011 at 01:40:08PM +0100, Stefan Hajnoczi wrote:

On Tue, Jul 5, 2011 at 9:01 AM, Dor Laordl...@redhat.com  wrote:

I tried to re-arrange all of the requirements and use cases using this wiki
page: http://wiki.qemu.org/Features/LiveBlockMigration

It would be the best to agree upon the most interesting use cases (while we
make sure we cover future ones) and agree to them.
The next step is to set the interface for all the various verbs since the
implementation seems to be converging.


Live block copy was supposed to support snapshot merge.  I think the
current favored approach is to make the source image a backing file to
the destination image and essentially do image streaming.

Using this mechanism for snapshot merge is tricky.  The COW file
already uses the read-only snapshot base image.  So now we cannot
trivally copy the COW file contents back into the snapshot base image
using live block copy.


It never did. Live copy creates a new image were both snapshot and
current are copied to.

This is similar with image streaming.


Not sure I realize what's bad to do in-place merge:

Let's suppose we have this COW chain:

  base -- s1 -- s2

Now a live snapshot is created over s2, s2 becomes RO and s3 is RW:

  base -- s1 -- s2 -- s3

Now we've done with s2 (post backup) and like to merge s3 into s2.

With your approach we use live copy of s3 into newSnap:

  base -- s1 -- s2 -- s3
  base -- s1 -- newSnap

When it is over s2 and s3 can be erased.
The down side is the IOs for copying s2 data and the temporary storage. 
I guess temp storage is cheap but excessive IO are expensive.


My approach was to collapse s3 into s2 and erase s3 eventually:

before: base -- s1 -- s2 -- s3
after:  base -- s1 -- s2

If we use live block copy using mirror driver it should be safe as long 
as we keep the ordering of new writes into s3 during the execution.
Even a failure in the the middle won't cause harm since the management 
will keep using s3 until it gets success event.





It seems like snapshot merge will require dedicated code that reads
the allocated clusters from the COW file and writes them back into the
base image.

A very inefficient alternative would be to create a third image, the
merge image file, which has the COW file as its backing file:
snapshot (base) -  cow -  merge

All data from snapshot and cow is copied into merge and then snapshot
and cow can be deleted.  But this approach is results in full data
copying and uses potentially 3x space if cow is close to the size of
snapshot.


Management can set a higher limit on the size of data that is merged,
and create a new base once exceeded. This avoids copying excessive
amounts of data.


Any other ideas that reuse live block copy for snapshot merge?

Stefan








Re: [Qemu-devel] PATCH: fix qemu-mips[el]-static to work with debian squeeze/sid chroot

2011-07-05 Thread Peter Maydell
On 5 July 2011 11:08, Wesley W. Terpstra terps...@debian.org wrote:
 I also recently tried to get a mipsel debian/sid chroot running under my
 amd64/squeeze system. As posted by Lisandro earlier this month, it didn't
 work. ;-) There are several problems, the most glaring of which the attached
 patch fixes.

Thanks for this patch. To get it merged upstream it would be helpful
if you could resubmit it in line with the guidelines at
http://wiki.qemu.org/Contribute/SubmitAPatch
(in particular it needs a Signed-off-by: line, it should be one patch
per bug fix, and it needs to be against current head of qemu git).

In the meantime, some minor initial review comments:

 @@ -1985,6 +1985,20 @@
   MIPS_SYS(sys_epoll_pwait, 6)
   MIPS_SYS(sys_ioprio_set, 3)
   MIPS_SYS(sys_ioprio_get, 2)
 + MIPS_SYS(sys_utimensat, 4)
 + MIPS_SYS(sys_ni_syscall, 0) /* signalfd */
 + MIPS_SYS(sys_ni_syscall, 0) /* timerfd */
 + MIPS_SYS(sys_eventfd, 1)
 + MIPS_SYS(sys_fallocate, 4)
 + MIPS_SYS(sys_ni_syscall, 0) /* timerfd_create */
 + MIPS_SYS(sys_ni_syscall, 0) /* timerfd_gettime */
 + MIPS_SYS(sys_ni_syscall, 0) /* timerfd_settime */
 + MIPS_SYS(sys_ni_syscall, 0) /* signalfd4 */
 + MIPS_SYS(sys_eventfd2, 2)
 + MIPS_SYS(sys_epoll_create1, 1)
 + MIPS_SYS(sys_dup3, 3)
 + MIPS_SYS(sys_pipe2, 2)
 + MIPS_SYS(sys_inotify_init1, 1)
  };

You can drop this bit as there's already a patch in the works
which adds the new syscall numbers:
http://patchwork.ozlabs.org/patch/102241/

(the earlier fix for sigaltstack is still needed).

There are also some bits of your patch which use hardcoded tabs;
these should be spaces. (Yes, existing code is sometimes not
consistent; we tend to convert gradually as we touch code.)

Otherwise I think it looks good.

Thanks again
-- PMM



[Qemu-devel] [PATCH v5 17/18] qapi: add test-qmp-commands, tests for gen. marshalling/dispatch code

2011-07-05 Thread Michael Roth

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 Makefile|8 +++-
 test-qmp-commands.c |  113 +++
 2 files changed, 120 insertions(+), 1 deletions(-)
 create mode 100644 test-qmp-commands.c

diff --git a/Makefile b/Makefile
index a243c24..cbd2d77 100644
--- a/Makefile
+++ b/Makefile
@@ -163,7 +163,7 @@ check-qfloat: check-qfloat.o qfloat.o $(CHECK_PROG_DEPS)
 check-qjson: check-qjson.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o 
qjson.o json-streamer.o json-lexer.o json-parser.o error.o qerror.o 
qemu-error.o $(CHECK_PROG_DEPS)
 
 qapi-dir := qapi-generated
-$(qapi-obj-y) test-visitor.o: QEMU_CFLAGS += -I $(qapi-dir)
+$(qapi-obj-y) test-visitor.o test-qmp-commands.o: QEMU_CFLAGS += -I $(qapi-dir)
 
 $(qapi-dir)/test-qapi-types.c: $(qapi-dir)/test-qapi-types.h
 $(qapi-dir)/test-qapi-types.h: $(SRC_PATH)/qapi-schema-test.json 
$(SRC_PATH)/scripts/qapi-types.py
@@ -171,10 +171,16 @@ $(qapi-dir)/test-qapi-types.h: 
$(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scr
 $(qapi-dir)/test-qapi-visit.c: $(qapi-dir)/test-qapi-visit.h
 $(qapi-dir)/test-qapi-visit.h: $(SRC_PATH)/qapi-schema-test.json 
$(SRC_PATH)/scripts/qapi-visit.py
$(call quiet-command,python $(SRC_PATH)/scripts/qapi-visit.py -o 
$(qapi-dir) -p test-  $,   GEN   $@)
+$(qapi-dir)/test-qmp-commands.h: $(qapi-dir)/test-qmp-marshal.c
+$(qapi-dir)/test-qmp-marshal.c: $(SRC_PATH)/qapi-schema-test.json 
$(SRC_PATH)/scripts/qapi-commands.py
+   $(call quiet-command,python $(SRC_PATH)/scripts/qapi-commands.py -o 
$(qapi-dir) -p test-  $,   GEN   $@)
 
 test-visitor.o: $(addprefix $(qapi-dir)/, test-qapi-types.c test-qapi-types.h 
test-qapi-visit.c test-qapi-visit.h)
 test-visitor: test-visitor.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o 
$(qapi-obj-y) error.o osdep.o qemu-malloc.o $(oslib-obj-y) qjson.o 
json-streamer.o json-lexer.o json-parser.o qerror.o qemu-error.o qemu-tool.o 
$(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o
 
+test-qmp-commands.o: $(addprefix $(qapi-dir)/, test-qapi-types.c 
test-qapi-types.h test-qapi-visit.c test-qapi-visit.h test-qmp-marshal.c 
test-qmp-commands.h)
+test-qmp-commands: test-qmp-commands.o qfloat.o qint.o qdict.o qstring.o 
qlist.o qbool.o $(qapi-obj-y) error.o osdep.o qemu-malloc.o $(oslib-obj-y) 
qjson.o json-streamer.o json-lexer.o json-parser.o qerror.o qemu-error.o 
qemu-tool.o $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o 
$(qapi-dir)/test-qmp-marshal.o module.o
+
 QEMULIBS=libhw32 libhw64 libuser libdis libdis-user
 
 clean:
diff --git a/test-qmp-commands.c b/test-qmp-commands.c
new file mode 100644
index 000..7752904
--- /dev/null
+++ b/test-qmp-commands.c
@@ -0,0 +1,113 @@
+#include glib.h
+#include qemu-objects.h
+#include test-qmp-commands.h
+#include qapi/qmp-core.h
+#include module.h
+
+void qmp_user_def_cmd(Error **errp)
+{
+}
+
+void qmp_user_def_cmd1(UserDefOne * ud1, Error **errp)
+{
+}
+
+UserDefTwo * qmp_user_def_cmd2(UserDefOne * ud1a, UserDefOne * ud1b, Error 
**errp)
+{
+UserDefTwo *ret;
+UserDefOne *ud1c = qemu_mallocz(sizeof(UserDefOne));
+UserDefOne *ud1d = qemu_mallocz(sizeof(UserDefOne));
+
+ud1c-string = strdup(ud1a-string);
+ud1c-integer = ud1a-integer;
+ud1d-string = strdup(ud1b-string);
+ud1d-integer = ud1b-integer;
+
+ret = qemu_mallocz(sizeof(UserDefTwo));
+ret-string = strdup(blah1);
+ret-dict.string = strdup(blah2);
+ret-dict.dict.userdef = ud1c;
+ret-dict.dict.string = strdup(blah3);
+ret-dict.has_dict2 = true;
+ret-dict.dict2.userdef = ud1d;
+ret-dict.dict2.string = strdup(blah4);
+
+return ret;
+}
+
+/* test commands with no input and no return value */
+static void test_dispatch_cmd(void)
+{
+QDict *req = qdict_new();
+QObject *resp;
+
+qdict_put_obj(req, execute, QOBJECT(qstring_from_str(user_def_cmd)));
+
+resp = qmp_dispatch(QOBJECT(req));
+assert(resp != NULL);
+assert(!qdict_haskey(qobject_to_qdict(resp), error));
+g_print(\nresp: %s\n, qstring_get_str(qobject_to_json(resp)));
+
+qobject_decref(resp);
+QDECREF(req);
+}
+
+/* test commands that return an error due to invalid parameters */
+static void test_dispatch_cmd_error(void)
+{
+QDict *req = qdict_new();
+QObject *resp;
+
+qdict_put_obj(req, execute, QOBJECT(qstring_from_str(user_def_cmd2)));
+
+resp = qmp_dispatch(QOBJECT(req));
+assert(resp != NULL);
+assert(qdict_haskey(qobject_to_qdict(resp), error));
+g_print(\nresp: %s\n, qstring_get_str(qobject_to_json_pretty(resp)));
+
+qobject_decref(resp);
+QDECREF(req);
+}
+
+/* test commands that involve both input parameters and return values */
+static void test_dispatch_cmd_io(void)
+{
+QDict *req = qdict_new();
+QDict *args = qdict_new();
+QDict *ud1a = qdict_new();
+QDict *ud1b = qdict_new();
+QObject *resp;
+
+qdict_put_obj(ud1a, integer, QOBJECT(qint_from_int(42)));
+

[Qemu-devel] live block copy/stream/snapshot discussion

2011-07-05 Thread Dor Laor
Anthony advised to clone 
http://wiki.qemu.org/index.php?title=Features/LiveBlockMigrationFuture 
to the list in order to encourage discussion, so here it is:


 qemu is expected to support these features (some already implemented):

= Live features =

== Live block copy ==

   Ability to copy 1+ virtual disk from the source backing file/block
   device to a new target that is accessible by the host. The copy
   supposed to be executed while the VM runs in a transparent way.

== Live snapshots and live snapshot merge ==

   Live snapshot is already incorporated (by Jes) in qemu (still need
   virt-agent work to freeze the guest FS).
   Live snapshot merge is required in order of reducing the overhead
   caused by the additional snapshots (sometimes over raw device).
   We'll use live copy to do the live merge

== Image streaming (Copy on read) ==
   Ability to start guest execution while the parent image reside
   remotely and each block access is replicated to a local copy (image
   format snapshot)
   Such functionality can be hooked together with live block migration
   instead of the 'post copy' method.

== Live block migration (pre/post) ==

   Beyond live block copy we'll sometimes need to move both the storage
   and the guest. There are two main approached here:
   - pre copy
 First live copy the image and only then live migration the VM.
 It is simple and safer approach in terms of management app, but if
 the purpose of the whole live block migration was to balance the
 cpu load, it won't be practical to use since copying an image of
 100GB will take too long.
   - post copy (streaming / copy on read)
 First live migrate the VM, then on line stream its blocks.
 It's better approach for HA/load balancing but it might make
 management complex (need to keep the source VM alive, handling
 failures)

   In addition there are two cases for the storage access:

   1. Shared storage
  Live block copy enable this capability, its seems like a rare
  case for live block migration.
   2. There are some cases where the is no NFS/SAN storage and live
  migration is needed. It should be similar to VMW's storage VM
  motion.
  http://www.vmware.com/files/pdf/VMware-Storage-VMotion-DS-EN.pdf
  http://www.vmware.com/products/storage-vmotion/features.html

== Using external dirty block bitmap ==

   FVD has an option to use external dirty block bitmap file in
   addition to the regular mapping/data files.
   We can consider using it for live block migration and live merge too.
   It can also allow additional usages of 3rd party tools to calculate
   diffs between the snapshots.
   There is a big down side thought since it will make management
   complicated and there is the risky of the image and its bitmap file
   get out of sync. It's much better choice to have qemu-img tool to be
   the single interface to the dirty block bitmap data.

= Solutions =

== Non shared storage ==

   Either use iscsi (target and initiator) or NBD or proprietary qemu
   solution. iScsi in theory is the best but there is a problem of
   dealing with COW images - iScsi cannot report the COW level and
   detect un-allocated blocks. This might force us to use
   proprietary solution.
   An interesting option (by Orit Wasserman) was to use iScsi for
   exporting the images externally to qemu level and qemu will access
   as if they were a local device. This can work well w/o almost any
   effort. What do we do with chains of COW files? We create up to N
   such iscsi connections for every COW file in the chain.

== Live block migration ==

   Use the streaming approach + regular live migration + iscsi:
   Execute regular live migration and at the end of it, start streaming.
   If there is no shared storage, use the external iscsi and behave as
   if the image is local. At the end of the streaming operation there
   will be a new local base image.

== Block mirror layer ==

   Was invented in order to duplicate write IOs for the source and
   destination images. It prevents the potential race when both qemu
   and the management crash at the end of the block copy stage and it
   is unknown whether management should pick the source or the
   destination

== Streaming ==

   No need for mirror since only the destination changes and is
   writable.

== Block copy background task ==

   Can be shared between block copy and streaming

== Live snapshot ==

   It can be seen as a (local) stream that preserve the current COW
   chain

= Use cases =

 1. Basic streaming, single base master image on source storage, need
to be instantiated on destination storage

 The base image is a single level COW format (file or lvm).
 The base is RO and only new destination is RW. base' is empty at
 the beginning. The base image content is being copied in the
 background to base'. At the end of the operation, 

[Qemu-devel] [PATCH v6 4/4] guest agent: add guest agent RPCs/commands

2011-07-05 Thread Michael Roth
This adds the initial set of QMP/QAPI commands provided by the guest
agent:

guest-sync
guest-ping
guest-info
guest-shutdown
guest-file-open
guest-file-read
guest-file-write
guest-file-seek
guest-file-close
guest-fsfreeze-freeze
guest-fsfreeze-thaw
guest-fsfreeze-status

The input/output specification for these commands are documented in the
schema.

Example usage:

  host:
qemu -device virtio-serial \
 -chardev socket,path=/tmp/vs0.sock,server,nowait,id=qga0 \
 -device virtserialport,chardev=qga0,name=qga0
 ...

echo {'execute':'guest-info'} | socat stdio \
 unix-connect:/tmp/qga0.sock

  guest:
qemu-ga -c virtio-serial -p /dev/virtio-ports/qga0 \
-p /var/run/qemu-guest-agent.pid -d

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 Makefile   |   15 ++-
 qemu-ga.c  |4 +
 qerror.h   |3 +
 qga/guest-agent-commands.c |  501 
 qga/guest-agent-core.h |2 +
 5 files changed, 523 insertions(+), 2 deletions(-)
 create mode 100644 qga/guest-agent-commands.c

diff --git a/Makefile b/Makefile
index b2e8593..7e4f722 100644
--- a/Makefile
+++ b/Makefile
@@ -175,15 +175,26 @@ $(qapi-dir)/test-qmp-commands.h: 
$(qapi-dir)/test-qmp-marshal.c
 $(qapi-dir)/test-qmp-marshal.c: $(SRC_PATH)/qapi-schema-test.json 
$(SRC_PATH)/scripts/qapi-commands.py
$(call quiet-command,python $(SRC_PATH)/scripts/qapi-commands.py -o 
$(qapi-dir) -p test-  $,   GEN   $@)
 
+$(qapi-dir)/qga-qapi-types.c: $(qapi-dir)/qga-qapi-types.h
+$(qapi-dir)/qga-qapi-types.h: $(SRC_PATH)/qapi-schema-guest.json 
$(SRC_PATH)/scripts/qapi-types.py
+   $(call quiet-command,python $(SRC_PATH)/scripts/qapi-types.py -o 
$(qapi-dir) -p qga-  $,   GEN   $@)
+$(qapi-dir)/qga-qapi-visit.c: $(qapi-dir)/qga-qapi-visit.h
+$(qapi-dir)/qga-qapi-visit.h: $(SRC_PATH)/qapi-schema-guest.json 
$(SRC_PATH)/scripts/qapi-visit.py
+   $(call quiet-command,python $(SRC_PATH)/scripts/qapi-visit.py -o 
$(qapi-dir) -p qga-  $,   GEN   $@)
+$(qapi-dir)/qga-qmp-marshal.c: $(SRC_PATH)/qapi-schema-guest.json 
$(SRC_PATH)/scripts/qapi-commands.py
+   $(call quiet-command,python $(SRC_PATH)/scripts/qapi-commands.py -o 
$(qapi-dir) -p qga-  $,   GEN   $@)
+
 test-visitor.o: $(addprefix $(qapi-dir)/, test-qapi-types.c test-qapi-types.h 
test-qapi-visit.c test-qapi-visit.h)
 test-visitor: test-visitor.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o 
$(qapi-obj-y) error.o osdep.o qemu-malloc.o $(oslib-obj-y) qjson.o 
json-streamer.o json-lexer.o json-parser.o qerror.o qemu-error.o qemu-tool.o 
$(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o
 
 test-qmp-commands.o: $(addprefix $(qapi-dir)/, test-qapi-types.c 
test-qapi-types.h test-qapi-visit.c test-qapi-visit.h test-qmp-marshal.c 
test-qmp-commands.h)
 test-qmp-commands: test-qmp-commands.o qfloat.o qint.o qdict.o qstring.o 
qlist.o qbool.o $(qapi-obj-y) error.o osdep.o qemu-malloc.o $(oslib-obj-y) 
qjson.o json-streamer.o json-lexer.o json-parser.o qerror.o qemu-error.o 
qemu-tool.o $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o 
$(qapi-dir)/test-qmp-marshal.o module.o
 
-QGALIB=qga/guest-agent-command-state.o
+QGALIB=qga/guest-agent-command-state.o qga/guest-agent-commands.o
+
+qemu-ga.o: $(qapi-dir)/qga-qapi-types.c $(qapi-dir)/qga-qapi-types.h 
$(qapi-dir)/qga-qapi-visit.c $(qapi-dir)/qga-qmp-marshal.c
 
-qemu-ga$(EXESUF): qemu-ga.o $(QGALIB) qemu-tool.o qemu-error.o error.o 
$(oslib-obj-y) $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) 
$(qapi-obj-y) qemu-timer-common.o qemu-sockets.o module.o qapi/qmp-dispatch.o 
qapi/qmp-registry.o
+qemu-ga$(EXESUF): qemu-ga.o $(QGALIB) qemu-tool.o qemu-error.o error.o 
$(oslib-obj-y) $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) 
$(qapi-obj-y) qemu-timer-common.o qemu-sockets.o module.o qapi/qmp-dispatch.o 
qapi/qmp-registry.o $(qapi-dir)/qga-qapi-visit.o $(qapi-dir)/qga-qmp-marshal.o
 
 QEMULIBS=libhw32 libhw64 libuser libdis libdis-user
 
diff --git a/qemu-ga.c b/qemu-ga.c
index 649c16a..04ead22 100644
--- a/qemu-ga.c
+++ b/qemu-ga.c
@@ -637,6 +637,9 @@ int main(int argc, char **argv)
 g_log_set_default_handler(ga_log, s);
 g_log_set_fatal_mask(NULL, G_LOG_LEVEL_ERROR);
 s-logging_enabled = true;
+s-command_state = ga_command_state_new();
+ga_command_state_init(s, s-command_state);
+ga_command_state_init_all(s-command_state);
 ga_state = s;
 
 module_call_init(MODULE_INIT_QAPI);
@@ -645,6 +648,7 @@ int main(int argc, char **argv)
 
 g_main_loop_run(ga_state-main_loop);
 
+ga_command_state_cleanup_all(ga_state-command_state);
 unlink(pidfile);
 
 return 0;
diff --git a/qerror.h b/qerror.h
index 9a9fa5b..0f618ac 100644
--- a/qerror.h
+++ b/qerror.h
@@ -184,4 +184,7 @@ QError *qobject_to_qerror(const QObject *obj);
 #define QERR_FEATURE_DISABLED \
 { 'class': 'FeatureDisabled', 'data': { 'name': 

Re: [Qemu-devel] utimensat trouble on mips

2011-07-05 Thread Peter Maydell
On 5 July 2011 13:07, Johannes Schauer j.scha...@email.de wrote:
 About a year ago, Kenneth Johansson reported [1], that trying to do a
 debian debootstrap using qemu user emulation will fail due to the
 following error:

 /bin/tar: ./postinst: Cannot utime: Level 2 not synchronized

This is the result of issues 1. and 2. listed by Wesley in this
email:
 http://lists.nongnu.org/archive/html/qemu-devel/2011-07/msg00313.html

 Now my questions are:

 * why is this happening with mips?

Because the particular bit of QEMU code which was wrongly returning
the host ENOSYS rather than the guest ENOSYS happened to be
MIPS-specific.

 * is it a qemu bug?

Yes.

 * why was nobody else complaining about it, given that this is an issue
  for over a year now?

I imagine because not very many people use QEMU for MIPS in
linux-user mode. Often with QEMU things work OK at the point
they were last tested, but new guest features (like this new
syscall) can cause breakage.

-- PMM



Re: [Qemu-devel] [PATCH 5/5] megasas: LSI Megaraid SAS emulation

2011-07-05 Thread Paolo Bonzini
On 07/05/2011 03:38 PM, Alexander Graf wrote:

 +if (is_sgl64) {
 +iov_pa = ldq_phys(pa);
 +} else {
 +iov_pa = ldl_phys(pa);
 
 These load data from memory in target endianness. Are you sure that's 
 what you want? I'd expect this to be defined as little endian 
 (especially given that ldq and ldl on the same address work).

Seems to be target endianness from the corresponding Linux code:

if (sge_count) {
scsi_for_each_sg(scp, os_sgl, sge_count, i) {
mfi_sgl-sge32[i].length = sg_dma_len(os_sgl);
mfi_sgl-sge32[i].phys_addr = sg_dma_address(os_sgl);
}
}

...

if (sge_count) {
scsi_for_each_sg(scp, os_sgl, sge_count, i) {
mfi_sgl-sge64[i].length = sg_dma_len(os_sgl);
mfi_sgl-sge64[i].phys_addr = sg_dma_address(os_sgl);
}
}

Note that this is _either_ a ldq or a ldl depending on what the driver told
the device.  It is not accessing a 64-bit value as 32-bit.

Paolo



Re: [Qemu-devel] [PATCH] pci: add standard bridge device

2011-07-05 Thread Michael S. Tsirkin
On Tue, Jul 05, 2011 at 10:29:36PM +0900, Isaku Yamahata wrote:
 On Mon, Jul 04, 2011 at 12:43:59PM +0300, Michael S. Tsirkin wrote:
  +/* Mapping mandated by PCI-to-PCI Bridge architecture specification,
  + * revision 1.2 */
  +/* Table 9-1: Interrupt Binding for Devices Behind a Bridge */
  +static int pci_bridge_dev_map_irq_fn(PCIDevice *dev, int irq_num)
  +{
  +return (irq_num + PCI_SLOT(dev-devfn) + irq_num) % PCI_NUM_PINS;
^^^  ^^^
 Typo. There are 2 irq_num.

Good catch, thanks.

 -- 
 yamahata



Re: [Qemu-devel] KVM call agenda for June 28

2011-07-05 Thread Marcelo Tosatti
On Tue, Jul 05, 2011 at 04:39:06PM +0300, Dor Laor wrote:
 On 07/05/2011 03:58 PM, Marcelo Tosatti wrote:
 On Tue, Jul 05, 2011 at 01:40:08PM +0100, Stefan Hajnoczi wrote:
 On Tue, Jul 5, 2011 at 9:01 AM, Dor Laordl...@redhat.com  wrote:
 I tried to re-arrange all of the requirements and use cases using this wiki
 page: http://wiki.qemu.org/Features/LiveBlockMigration
 
 It would be the best to agree upon the most interesting use cases (while we
 make sure we cover future ones) and agree to them.
 The next step is to set the interface for all the various verbs since the
 implementation seems to be converging.
 
 Live block copy was supposed to support snapshot merge.  I think the
 current favored approach is to make the source image a backing file to
 the destination image and essentially do image streaming.
 
 Using this mechanism for snapshot merge is tricky.  The COW file
 already uses the read-only snapshot base image.  So now we cannot
 trivally copy the COW file contents back into the snapshot base image
 using live block copy.
 
 It never did. Live copy creates a new image were both snapshot and
 current are copied to.
 
 This is similar with image streaming.
 
 Not sure I realize what's bad to do in-place merge:
 
 Let's suppose we have this COW chain:
 
   base -- s1 -- s2
 
 Now a live snapshot is created over s2, s2 becomes RO and s3 is RW:
 
   base -- s1 -- s2 -- s3
 
 Now we've done with s2 (post backup) and like to merge s3 into s2.
 
 With your approach we use live copy of s3 into newSnap:
 
   base -- s1 -- s2 -- s3
   base -- s1 -- newSnap
 
 When it is over s2 and s3 can be erased.
 The down side is the IOs for copying s2 data and the temporary
 storage. I guess temp storage is cheap but excessive IO are
 expensive.
 
 My approach was to collapse s3 into s2 and erase s3 eventually:
 
 before: base -- s1 -- s2 -- s3
 after:  base -- s1 -- s2
 
 If we use live block copy using mirror driver it should be safe as
 long as we keep the ordering of new writes into s3 during the
 execution.
 Even a failure in the the middle won't cause harm since the
 management will keep using s3 until it gets success event.

Well, it is more complicated than simply streaming into a new
image. I'm not entirely sure it is necessary. The common case is:

base - sn-1 - sn-2 - ... - sn-n

When n reaches a limit, you do:

base - merge-1

You're potentially copying similar amount of data when merging back into
a single image (and you can't easily merge multiple snapshots).

If the amount of data thats not in 'base' is large, you create
leave a new external file around:

base - merge-1 - sn-1 - sn-2 ... - sn-n
to
base - merge-1 - merge-2

 
 It seems like snapshot merge will require dedicated code that reads
 the allocated clusters from the COW file and writes them back into the
 base image.
 
 A very inefficient alternative would be to create a third image, the
 merge image file, which has the COW file as its backing file:
 snapshot (base) -  cow -  merge

Remember there is a 'base' before snapshot, you don't copy the entire
image.

 
 All data from snapshot and cow is copied into merge and then snapshot
 and cow can be deleted.  But this approach is results in full data
 copying and uses potentially 3x space if cow is close to the size of
 snapshot.
 
 Management can set a higher limit on the size of data that is merged,
 and create a new base once exceeded. This avoids copying excessive
 amounts of data.
 
 Any other ideas that reuse live block copy for snapshot merge?
 
 Stefan
 
 



Re: [Qemu-devel] KVM call agenda for June 28

2011-07-05 Thread Kevin Wolf
Am 05.07.2011 16:32, schrieb Marcelo Tosatti:
 On Tue, Jul 05, 2011 at 04:39:06PM +0300, Dor Laor wrote:
 On 07/05/2011 03:58 PM, Marcelo Tosatti wrote:
 On Tue, Jul 05, 2011 at 01:40:08PM +0100, Stefan Hajnoczi wrote:
 On Tue, Jul 5, 2011 at 9:01 AM, Dor Laordl...@redhat.com  wrote:
 I tried to re-arrange all of the requirements and use cases using this 
 wiki
 page: http://wiki.qemu.org/Features/LiveBlockMigration

 It would be the best to agree upon the most interesting use cases (while 
 we
 make sure we cover future ones) and agree to them.
 The next step is to set the interface for all the various verbs since the
 implementation seems to be converging.

 Live block copy was supposed to support snapshot merge.  I think the
 current favored approach is to make the source image a backing file to
 the destination image and essentially do image streaming.

 Using this mechanism for snapshot merge is tricky.  The COW file
 already uses the read-only snapshot base image.  So now we cannot
 trivally copy the COW file contents back into the snapshot base image
 using live block copy.

 It never did. Live copy creates a new image were both snapshot and
 current are copied to.

 This is similar with image streaming.

 Not sure I realize what's bad to do in-place merge:

 Let's suppose we have this COW chain:

   base -- s1 -- s2

 Now a live snapshot is created over s2, s2 becomes RO and s3 is RW:

   base -- s1 -- s2 -- s3

 Now we've done with s2 (post backup) and like to merge s3 into s2.

 With your approach we use live copy of s3 into newSnap:

   base -- s1 -- s2 -- s3
   base -- s1 -- newSnap

 When it is over s2 and s3 can be erased.
 The down side is the IOs for copying s2 data and the temporary
 storage. I guess temp storage is cheap but excessive IO are
 expensive.

 My approach was to collapse s3 into s2 and erase s3 eventually:

 before: base -- s1 -- s2 -- s3
 after:  base -- s1 -- s2

 If we use live block copy using mirror driver it should be safe as
 long as we keep the ordering of new writes into s3 during the
 execution.
 Even a failure in the the middle won't cause harm since the
 management will keep using s3 until it gets success event.
 
 Well, it is more complicated than simply streaming into a new
 image. I'm not entirely sure it is necessary. The common case is:
 
 base - sn-1 - sn-2 - ... - sn-n
 
 When n reaches a limit, you do:
 
 base - merge-1

Hm, I would expect that a case like this is important, too:

base - sn-1 - ... - sn-n-1 - sn-n - ... - sn-m

Which should be merged so that we get the following (i.e. deleting older
snapshots but retaining more recent ones):

base - sn-merged - sn-n - ... - sn-m

Kevin



Re: [Qemu-devel] [PATCH 5/5] megasas: LSI Megaraid SAS emulation

2011-07-05 Thread Alexander Graf

On 07/05/2011 03:59 PM, Paolo Bonzini wrote:

On 07/05/2011 03:38 PM, Alexander Graf wrote:

+if (is_sgl64) {
+iov_pa = ldq_phys(pa);
+} else {
+iov_pa = ldl_phys(pa);

These load data from memory in target endianness. Are you sure that's
what you want? I'd expect this to be defined as little endian
(especially given that ldq and ldl on the same address work).

Seems to be target endianness from the corresponding Linux code:

 if (sge_count) {
 scsi_for_each_sg(scp, os_sgl, sge_count, i) {
 mfi_sgl-sge32[i].length = sg_dma_len(os_sgl);
 mfi_sgl-sge32[i].phys_addr = sg_dma_address(os_sgl);
 }
 }

...

 if (sge_count) {
 scsi_for_each_sg(scp, os_sgl, sge_count, i) {
 mfi_sgl-sge64[i].length = sg_dma_len(os_sgl);
 mfi_sgl-sge64[i].phys_addr = sg_dma_address(os_sgl);
 }
 }

Note that this is _either_ a ldq or a ldl depending on what the driver told
the device.  It is not accessing a 64-bit value as 32-bit.


So how would the device know which endianness the target is then? This 
looks like broken Linux code to me then. Christoph, is the above correct 
for big endian systems?


Btw, reading through the Qemu sources, there is ldl_le_p() to read 
little endian values from memory. I haven't quite found one for _phys 
though. We can just add that however.



Alex




Re: [Qemu-devel] [PATCH] Make SLIRP Ethernet packets size to 64 bytes minimuma

2011-07-05 Thread Fabien Chouteau
On 30/06/2011 10:38, Fabien Chouteau wrote:
 On 28/06/2011 15:15, Stefan Hajnoczi wrote:
 On Tue, Jun 28, 2011 at 10:08 AM, Fabien Chouteau chout...@adacore.com 
 wrote:
 On 28/06/2011 10:34, Stefan Hajnoczi wrote:
 This patch doesn't hurt but we'd be just as well off without it.

 Did you do this to fix a bug?  If so, then something else in QEMU
 needs to be fixed, not slirp.

 When Qemu generates bad Ethernet frames, I think it's a bug.

 And again, this is the extension of a previous patch. If this patch is not
 valid then we should revert the first, it's also a question of consistency.

 IMO the previous patch is not necessary either.

 Since there is no net subsystem maintainer who can help decide which
 way to go, I'm going to back off from this issue.  Please go ahead.

 
 OK thanks.
 
 Any other comments?
 

This patch got no further comments, can it be applied please?

thanks,

-- 
Fabien Chouteau



[Qemu-devel] [PATCH 0/9] Don't use ld./st._phys in hw/

2011-07-05 Thread Alexander Graf
We have quite some code in hw/ that uses ld./st._phys functions
in device emulation code. This is just pure wrong, as devices
don't know about the CPU endianness (except for virtio), so they
should instead use something endian specific.

Unfortunately, there is no endian specific call to easily receive
an integer from memory, so this patch set introduces some and then
converts all the obvious users to them.

I tested the targets I could, but please double-check if your
architecture behaves differently or I accidently put in a _be
instead of _le :)


Alex

Alexander Graf (9):
  exec: add endian specific phys ld/st functions
  hpet: use specific endian ld/st_phys
  intel-hda: use specific endian ld/st_phys
  msi: use specific endian ld/st_phys
  msix: use specific endian ld/st_phys
  pl080: use specific endian ld/st_phys
  ppc405_uc: use specific endian ld/st_phys
  s390-virtio: use specific endian ld/st_phys
  spapr: use specific endian ld/st_phys

 cpu-common.h |   12 ++
 exec.c   |  102 ++
 hw/hpet.c|2 +-
 hw/intel-hda.c   |   21 ++
 hw/msi.c |2 +-
 hw/msix.c|2 +-
 hw/pl080.c   |8 ++--
 hw/ppc405_uc.c   |   43 +++--
 hw/s390-virtio-bus.c |   10 ++--
 hw/s390-virtio.c |6 +-
 hw/spapr.h   |4 +-
 hw/spapr_hcall.c |   12 +++---
 12 files changed, 164 insertions(+), 60 deletions(-)

-- 
1.7.3.4




Re: [Qemu-devel] KVM call agenda for June 28

2011-07-05 Thread Dor Laor

On 07/05/2011 05:32 PM, Marcelo Tosatti wrote:

On Tue, Jul 05, 2011 at 04:39:06PM +0300, Dor Laor wrote:

On 07/05/2011 03:58 PM, Marcelo Tosatti wrote:

On Tue, Jul 05, 2011 at 01:40:08PM +0100, Stefan Hajnoczi wrote:

On Tue, Jul 5, 2011 at 9:01 AM, Dor Laordl...@redhat.com   wrote:

I tried to re-arrange all of the requirements and use cases using this wiki
page: http://wiki.qemu.org/Features/LiveBlockMigration

It would be the best to agree upon the most interesting use cases (while we
make sure we cover future ones) and agree to them.
The next step is to set the interface for all the various verbs since the
implementation seems to be converging.


Live block copy was supposed to support snapshot merge.  I think the
current favored approach is to make the source image a backing file to
the destination image and essentially do image streaming.

Using this mechanism for snapshot merge is tricky.  The COW file
already uses the read-only snapshot base image.  So now we cannot
trivally copy the COW file contents back into the snapshot base image
using live block copy.


It never did. Live copy creates a new image were both snapshot and
current are copied to.

This is similar with image streaming.


Not sure I realize what's bad to do in-place merge:

Let's suppose we have this COW chain:

   base-- s1-- s2

Now a live snapshot is created over s2, s2 becomes RO and s3 is RW:

   base-- s1-- s2-- s3

Now we've done with s2 (post backup) and like to merge s3 into s2.

With your approach we use live copy of s3 into newSnap:

   base-- s1-- s2-- s3
   base-- s1-- newSnap

When it is over s2 and s3 can be erased.
The down side is the IOs for copying s2 data and the temporary
storage. I guess temp storage is cheap but excessive IO are
expensive.

My approach was to collapse s3 into s2 and erase s3 eventually:

before: base-- s1-- s2-- s3
after:  base-- s1-- s2

If we use live block copy using mirror driver it should be safe as
long as we keep the ordering of new writes into s3 during the
execution.
Even a failure in the the middle won't cause harm since the
management will keep using s3 until it gets success event.


Well, it is more complicated than simply streaming into a new
image. I'm not entirely sure it is necessary. The common case is:

base -  sn-1 -  sn-2 -  ... -  sn-n

When n reaches a limit, you do:

base -  merge-1

You're potentially copying similar amount of data when merging back into
a single image (and you can't easily merge multiple snapshots).

If the amount of data thats not in 'base' is large, you create
leave a new external file around:

base -  merge-1 -  sn-1 -  sn-2 ... -  sn-n
to
base -  merge-1 -  merge-2


Sometimes one will want to merge the snapshot immediately post the base 
was backed-up







It seems like snapshot merge will require dedicated code that reads
the allocated clusters from the COW file and writes them back into the
base image.

A very inefficient alternative would be to create a third image, the
merge image file, which has the COW file as its backing file:
snapshot (base) -   cow -   merge


Remember there is a 'base' before snapshot, you don't copy the entire
image.


Not always, the image might be raw file/device -

1. raw image
2. live snapshot it and use COW above it
   raw - s1
3. backup the raw image using 3rd party mechanism
4. live merge (copy) s1 into raw





All data from snapshot and cow is copied into merge and then snapshot
and cow can be deleted.  But this approach is results in full data
copying and uses potentially 3x space if cow is close to the size of
snapshot.


Management can set a higher limit on the size of data that is merged,
and create a new base once exceeded. This avoids copying excessive
amounts of data.


Any other ideas that reuse live block copy for snapshot merge?

Stefan








[Qemu-devel] [PATCH 7/9] ppc405_uc: use specific endian ld/st_phys

2011-07-05 Thread Alexander Graf
Signed-off-by: Alexander Graf ag...@suse.de
---
 hw/ppc405_uc.c |   43 +++
 1 files changed, 23 insertions(+), 20 deletions(-)

diff --git a/hw/ppc405_uc.c b/hw/ppc405_uc.c
index 2ce79ee..06a053b 100644
--- a/hw/ppc405_uc.c
+++ b/hw/ppc405_uc.c
@@ -51,39 +51,42 @@ ram_addr_t ppc405_set_bootinfo (CPUState *env, 
ppc4xx_bd_info_t *bd,
 bdloc = 0x0100UL - sizeof(struct ppc4xx_bd_info_t);
 else
 bdloc = bd-bi_memsize - sizeof(struct ppc4xx_bd_info_t);
-stl_phys(bdloc + 0x00, bd-bi_memstart);
-stl_phys(bdloc + 0x04, bd-bi_memsize);
-stl_phys(bdloc + 0x08, bd-bi_flashstart);
-stl_phys(bdloc + 0x0C, bd-bi_flashsize);
-stl_phys(bdloc + 0x10, bd-bi_flashoffset);
-stl_phys(bdloc + 0x14, bd-bi_sramstart);
-stl_phys(bdloc + 0x18, bd-bi_sramsize);
-stl_phys(bdloc + 0x1C, bd-bi_bootflags);
-stl_phys(bdloc + 0x20, bd-bi_ipaddr);
-for (i = 0; i  6; i++)
+stl_be_phys(bdloc + 0x00, bd-bi_memstart);
+stl_be_phys(bdloc + 0x04, bd-bi_memsize);
+stl_be_phys(bdloc + 0x08, bd-bi_flashstart);
+stl_be_phys(bdloc + 0x0C, bd-bi_flashsize);
+stl_be_phys(bdloc + 0x10, bd-bi_flashoffset);
+stl_be_phys(bdloc + 0x14, bd-bi_sramstart);
+stl_be_phys(bdloc + 0x18, bd-bi_sramsize);
+stl_be_phys(bdloc + 0x1C, bd-bi_bootflags);
+stl_be_phys(bdloc + 0x20, bd-bi_ipaddr);
+for (i = 0; i  6; i++) {
 stb_phys(bdloc + 0x24 + i, bd-bi_enetaddr[i]);
-stw_phys(bdloc + 0x2A, bd-bi_ethspeed);
-stl_phys(bdloc + 0x2C, bd-bi_intfreq);
-stl_phys(bdloc + 0x30, bd-bi_busfreq);
-stl_phys(bdloc + 0x34, bd-bi_baudrate);
-for (i = 0; i  4; i++)
+}
+stw_be_phys(bdloc + 0x2A, bd-bi_ethspeed);
+stl_be_phys(bdloc + 0x2C, bd-bi_intfreq);
+stl_be_phys(bdloc + 0x30, bd-bi_busfreq);
+stl_be_phys(bdloc + 0x34, bd-bi_baudrate);
+for (i = 0; i  4; i++) {
 stb_phys(bdloc + 0x38 + i, bd-bi_s_version[i]);
+}
 for (i = 0; i  32; i++) {
 stb_phys(bdloc + 0x3C + i, bd-bi_r_version[i]);
 }
-stl_phys(bdloc + 0x5C, bd-bi_plb_busfreq);
-stl_phys(bdloc + 0x60, bd-bi_pci_busfreq);
-for (i = 0; i  6; i++)
+stl_be_phys(bdloc + 0x5C, bd-bi_plb_busfreq);
+stl_be_phys(bdloc + 0x60, bd-bi_pci_busfreq);
+for (i = 0; i  6; i++) {
 stb_phys(bdloc + 0x64 + i, bd-bi_pci_enetaddr[i]);
+}
 n = 0x6A;
 if (flags  0x0001) {
 for (i = 0; i  6; i++)
 stb_phys(bdloc + n++, bd-bi_pci_enetaddr2[i]);
 }
-stl_phys(bdloc + n, bd-bi_opbfreq);
+stl_be_phys(bdloc + n, bd-bi_opbfreq);
 n += 4;
 for (i = 0; i  2; i++) {
-stl_phys(bdloc + n, bd-bi_iic_fast[i]);
+stl_be_phys(bdloc + n, bd-bi_iic_fast[i]);
 n += 4;
 }
 
-- 
1.7.3.4




Re: [Qemu-devel] [PATCH 5/5] megasas: LSI Megaraid SAS emulation

2011-07-05 Thread Stefan Hajnoczi
On Tue, Jul 5, 2011 at 12:03 PM, Hannes Reinecke h...@suse.de wrote:
 +static void megasas_unmap_sgl(struct megasas_cmd_t *cmd)
 +{
 +    uint16_t flags = le16_to_cpu(cmd-frame-header.flags);
 +    int i, is_write = (flags  MFI_FRAME_DIR_WRITE) ? 1 : 0;
 +
 +    for (i = 0; i  cmd-frame-header.sge_count; i++) {
 +        cpu_physical_memory_unmap(cmd-iov[i].iov_base, cmd-iov[i].iov_len,
 +                                  is_write, cmd-iov[i].iov_len);
 +    }

We cannot map control structures from guest memory and treating them
as valid request state later on.

A malicious guest can issue the request, then change the fields the
control structure while QEMU is processing the I/O, and then this
function will execute with is_write/sge_count no longer the same as
when the request started.

Good practice would be to copy in any request state needed instead of
reaching into guest memory at later points of the request lifecycle.
This way a malicious guest can never cause QEMU to crash or do
something due to inconsistent state.

The particular problem I see here is starting the request with
sge_count=1 and then setting it to sge_count=255.  We will perform
invalid iov[] accesses.

Stefan



[Qemu-devel] [PATCH 2/9] hpet: use specific endian ld/st_phys

2011-07-05 Thread Alexander Graf
Signed-off-by: Alexander Graf ag...@suse.de
---
 hw/hpet.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/hpet.c b/hw/hpet.c
index ef9a2a0..4eda33d 100644
--- a/hw/hpet.c
+++ b/hw/hpet.c
@@ -192,7 +192,7 @@ static void update_irq(struct HPETTimer *timer, int set)
 qemu_irq_lower(s-irqs[route]);
 }
 } else if (timer_fsb_route(timer)) {
-stl_phys(timer-fsb  32, timer-fsb  0x);
+stl_le_phys(timer-fsb  32, timer-fsb  0x);
 } else if (timer-config  HPET_TN_TYPE_LEVEL) {
 s-isr |= mask;
 qemu_irq_raise(s-irqs[route]);
-- 
1.7.3.4




Re: [Qemu-devel] [PATCH V2] [PowerPC][RFC] booke timers

2011-07-05 Thread Scott Wood
On Mon, 4 Jul 2011 17:06:54 +0200
Fabien Chouteau chout...@adacore.com wrote:

 On 01/07/2011 22:22, Scott Wood wrote:
  On Fri, 1 Jul 2011 16:13:41 +0200
  Fabien Chouteau chout...@adacore.com wrote:
  +static void booke_update_fixed_timer(CPUState *env,
  + uint8_t   target_bit,
  + uint64_t  *next,
  + struct QEMUTimer *timer)
  +{
  +ppc_tb_t *tb_env = env-tb_env;
  +uint64_t lapse;
  +uint64_t tb;
  +uint64_t period = 1  (target_bit + 1);
  +uint64_t now;
  +
  +now = qemu_get_clock_ns(vm_clock);
  +tb  = cpu_ppc_get_tb(tb_env, now, tb_env-tb_offset);
  +
  +if (tb = (1  target_bit)) {
  +lapse = (1  target_bit) - tb;
  +} else {
  +lapse = period - ((tb - (1  target_bit)) % period);
  
  We know period is a power of two, so just do  (period - 1).
  
  That should let you get rid of the special case for
  tb = (1  target_bit) as well.
  
 
 Do you mean lapse = period - ((tb - (1  target_bit))  (period - 1)); ?

Yes.

Or more simply:

lapse = period - ((tb - period)  (period - 1));

 I don't see how this solves the tb = (1  target_bit) case.

Actually, since everything is unsigned the special case shouldn't be needed
regardless.

-Scott




Re: [Qemu-devel] KVM call agenda for June 28

2011-07-05 Thread Marcelo Tosatti
On Tue, Jul 05, 2011 at 06:04:34PM +0300, Dor Laor wrote:
 On 07/05/2011 05:32 PM, Marcelo Tosatti wrote:
 On Tue, Jul 05, 2011 at 04:39:06PM +0300, Dor Laor wrote:
 On 07/05/2011 03:58 PM, Marcelo Tosatti wrote:
 On Tue, Jul 05, 2011 at 01:40:08PM +0100, Stefan Hajnoczi wrote:
 On Tue, Jul 5, 2011 at 9:01 AM, Dor Laordl...@redhat.com   wrote:
 I tried to re-arrange all of the requirements and use cases using this 
 wiki
 page: http://wiki.qemu.org/Features/LiveBlockMigration
 
 It would be the best to agree upon the most interesting use cases (while 
 we
 make sure we cover future ones) and agree to them.
 The next step is to set the interface for all the various verbs since the
 implementation seems to be converging.
 
 Live block copy was supposed to support snapshot merge.  I think the
 current favored approach is to make the source image a backing file to
 the destination image and essentially do image streaming.
 
 Using this mechanism for snapshot merge is tricky.  The COW file
 already uses the read-only snapshot base image.  So now we cannot
 trivally copy the COW file contents back into the snapshot base image
 using live block copy.
 
 It never did. Live copy creates a new image were both snapshot and
 current are copied to.
 
 This is similar with image streaming.
 
 Not sure I realize what's bad to do in-place merge:
 
 Let's suppose we have this COW chain:
 
base-- s1-- s2
 
 Now a live snapshot is created over s2, s2 becomes RO and s3 is RW:
 
base-- s1-- s2-- s3
 
 Now we've done with s2 (post backup) and like to merge s3 into s2.
 
 With your approach we use live copy of s3 into newSnap:
 
base-- s1-- s2-- s3
base-- s1-- newSnap
 
 When it is over s2 and s3 can be erased.
 The down side is the IOs for copying s2 data and the temporary
 storage. I guess temp storage is cheap but excessive IO are
 expensive.
 
 My approach was to collapse s3 into s2 and erase s3 eventually:
 
 before: base-- s1-- s2-- s3
 after:  base-- s1-- s2
 
 If we use live block copy using mirror driver it should be safe as
 long as we keep the ordering of new writes into s3 during the
 execution.
 Even a failure in the the middle won't cause harm since the
 management will keep using s3 until it gets success event.
 
 Well, it is more complicated than simply streaming into a new
 image. I'm not entirely sure it is necessary. The common case is:
 
 base -  sn-1 -  sn-2 -  ... -  sn-n
 
 When n reaches a limit, you do:
 
 base -  merge-1
 
 You're potentially copying similar amount of data when merging back into
 a single image (and you can't easily merge multiple snapshots).
 
 If the amount of data thats not in 'base' is large, you create
 leave a new external file around:
 
 base -  merge-1 -  sn-1 -  sn-2 ... -  sn-n
 to
 base -  merge-1 -  merge-2
 
 Sometimes one will want to merge the snapshot immediately post the
 base was backed-up

Well, ok, this needs a separate interface for management, needs write
mirroring, and must mind crash handling.

 It seems like snapshot merge will require dedicated code that reads
 the allocated clusters from the COW file and writes them back into the
 base image.
 
 A very inefficient alternative would be to create a third image, the
 merge image file, which has the COW file as its backing file:
 snapshot (base) -   cow -   merge
 
 Remember there is a 'base' before snapshot, you don't copy the entire
 image.
 
 Not always, the image might be raw file/device -
 
 1. raw image
 2. live snapshot it and use COW above it
raw - s1
 3. backup the raw image using 3rd party mechanism
 4. live merge (copy) s1 into raw
 
 
 
 All data from snapshot and cow is copied into merge and then snapshot
 and cow can be deleted.  But this approach is results in full data
 copying and uses potentially 3x space if cow is close to the size of
 snapshot.
 
 Management can set a higher limit on the size of data that is merged,
 and create a new base once exceeded. This avoids copying excessive
 amounts of data.
 
 Any other ideas that reuse live block copy for snapshot merge?
 
 Stefan
 
 



[Qemu-devel] [PATCH 1/9] exec: add endian specific phys ld/st functions

2011-07-05 Thread Alexander Graf
Device code some times needs to access physical memory and does that
through the ld./st._phys functions. However, these are the exact same
functions that the CPU uses to access memory, which means they will
be endianness swapped depending on the target CPU.

However, devices don't know about the CPU's endianness, but instead
access memory directly using their own interface to the memory bus,
so they need some way to read data with their native endianness.

This patch adds _le and _be functions to ld./st._phys.

Signed-off-by: Alexander Graf ag...@suse.de
---
 cpu-common.h |   12 +++
 exec.c   |  102 ++
 2 files changed, 114 insertions(+), 0 deletions(-)

diff --git a/cpu-common.h b/cpu-common.h
index b027e43..c6a2b5f 100644
--- a/cpu-common.h
+++ b/cpu-common.h
@@ -135,14 +135,26 @@ void qemu_flush_coalesced_mmio_buffer(void);
 
 uint32_t ldub_phys(target_phys_addr_t addr);
 uint32_t lduw_phys(target_phys_addr_t addr);
+uint32_t lduw_le_phys(target_phys_addr_t addr);
+uint32_t lduw_be_phys(target_phys_addr_t addr);
 uint32_t ldl_phys(target_phys_addr_t addr);
+uint32_t ldl_le_phys(target_phys_addr_t addr);
+uint32_t ldl_be_phys(target_phys_addr_t addr);
 uint64_t ldq_phys(target_phys_addr_t addr);
+uint64_t ldq_le_phys(target_phys_addr_t addr);
+uint64_t ldq_be_phys(target_phys_addr_t addr);
 void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val);
 void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val);
 void stb_phys(target_phys_addr_t addr, uint32_t val);
 void stw_phys(target_phys_addr_t addr, uint32_t val);
+void stw_le_phys(target_phys_addr_t addr, uint32_t val);
+void stw_be_phys(target_phys_addr_t addr, uint32_t val);
 void stl_phys(target_phys_addr_t addr, uint32_t val);
+void stl_le_phys(target_phys_addr_t addr, uint32_t val);
+void stl_be_phys(target_phys_addr_t addr, uint32_t val);
 void stq_phys(target_phys_addr_t addr, uint64_t val);
+void stq_le_phys(target_phys_addr_t addr, uint64_t val);
+void stq_be_phys(target_phys_addr_t addr, uint64_t val);
 
 void cpu_physical_memory_write_rom(target_phys_addr_t addr,
const uint8_t *buf, int len);
diff --git a/exec.c b/exec.c
index 4c45299..5f2f87e 100644
--- a/exec.c
+++ b/exec.c
@@ -4158,6 +4158,24 @@ uint32_t ldl_phys(target_phys_addr_t addr)
 return val;
 }
 
+uint32_t ldl_le_phys(target_phys_addr_t addr)
+{
+#if defined(TARGET_WORDS_BIGENDIAN)
+return bswap32(ldl_phys(addr));
+#else
+return ldl_phys(addr);
+#endif
+}
+
+uint32_t ldl_be_phys(target_phys_addr_t addr)
+{
+#if defined(TARGET_WORDS_BIGENDIAN)
+return ldl_phys(addr);
+#else
+return bswap32(ldl_phys(addr));
+#endif
+}
+
 /* warning: addr must be aligned */
 uint64_t ldq_phys(target_phys_addr_t addr)
 {
@@ -4196,6 +4214,24 @@ uint64_t ldq_phys(target_phys_addr_t addr)
 return val;
 }
 
+uint64_t ldq_le_phys(target_phys_addr_t addr)
+{
+#if defined(TARGET_WORDS_BIGENDIAN)
+return bswap64(ldq_phys(addr));
+#else
+return ldq_phys(addr);
+#endif
+}
+
+uint64_t ldq_be_phys(target_phys_addr_t addr)
+{
+#if defined(TARGET_WORDS_BIGENDIAN)
+return ldq_phys(addr);
+#else
+return bswap64(ldq_phys(addr));
+#endif
+}
+
 /* XXX: optimize */
 uint32_t ldub_phys(target_phys_addr_t addr)
 {
@@ -4236,6 +4272,24 @@ uint32_t lduw_phys(target_phys_addr_t addr)
 return val;
 }
 
+uint32_t lduw_le_phys(target_phys_addr_t addr)
+{
+#if defined(TARGET_WORDS_BIGENDIAN)
+return bswap16(lduw_phys(addr));
+#else
+return lduw_phys(addr);
+#endif
+}
+
+uint32_t lduw_be_phys(target_phys_addr_t addr)
+{
+#if defined(TARGET_WORDS_BIGENDIAN)
+return lduw_phys(addr);
+#else
+return bswap16(lduw_phys(addr));
+#endif
+}
+
 /* warning: addr must be aligned. The ram page is not masked as dirty
and the code inside is not invalidated. It is useful if the dirty
bits are used to track modified PTEs */
@@ -4343,6 +4397,24 @@ void stl_phys(target_phys_addr_t addr, uint32_t val)
 }
 }
 
+void stl_le_phys(target_phys_addr_t addr, uint32_t val)
+{
+#if defined(TARGET_WORDS_BIGENDIAN)
+return stl_phys(addr, bswap32(val));
+#else
+return stl_phys(addr, val);
+#endif
+}
+
+void stl_be_phys(target_phys_addr_t addr, uint32_t val)
+{
+#if defined(TARGET_WORDS_BIGENDIAN)
+return stl_phys(addr, val);
+#else
+return stl_phys(addr, bswap32(val));
+#endif
+}
+
 /* XXX: optimize */
 void stb_phys(target_phys_addr_t addr, uint32_t val)
 {
@@ -4386,6 +4458,24 @@ void stw_phys(target_phys_addr_t addr, uint32_t val)
 }
 }
 
+void stw_le_phys(target_phys_addr_t addr, uint32_t val)
+{
+#if defined(TARGET_WORDS_BIGENDIAN)
+return stw_phys(addr, bswap16(val));
+#else
+return stw_phys(addr, val);
+#endif
+}
+
+void stw_be_phys(target_phys_addr_t addr, uint32_t val)
+{
+#if defined(TARGET_WORDS_BIGENDIAN)
+return stw_phys(addr, val);
+#else
+return stw_phys(addr, bswap16(val));
+#endif
+}
+
 /* XXX: optimize */
 void 

Re: [Qemu-devel] [PATCH 2/3] Add fno-strict-overflow

2011-07-05 Thread Raghavendra D Prabhu

* On Mon, Jul 04, 2011 at 11:38:30PM +0100, Peter Maydell 
peter.mayd...@linaro.org wrote:

On 4 July 2011 23:00, Raghavendra D Prabhu raghu.prabh...@gmail.com wrote:

This is to avoid gcc optimizating out the comparison in assert,
due to assumption of signed overflow being undefined by default 
(-Werror=strict-overflow).



--- a/Makefile.hw
+++ b/Makefile.hw
@@ -9,7 +9,7 @@ include $(SRC_PATH)/rules.mak



$(call set-vpath, $(SRC_PATH):$(SRC_PATH)/hw)



-QEMU_CFLAGS+=-I.. -I$(SRC_PATH)/fpu
+QEMU_CFLAGS+=-I.. -I$(SRC_PATH)/fpu -fno-strict-overflow


Can you give a more detailed description of the problem this is trying
to solve? I think it would be nicer if we could remove the assumptions
about signed overflows instead, if that's practical.

Following line in pcie.c:pcie_add_capability:505

assert(offset  offset + size);

is what the compiler was warning about. The compiler optimizes out that
comparison without fno-strict-overflow flag. More information about it
is here -  http://www.airs.com/blog/archives/120 -- as already mentioned by 
Stefan.


(Also, if we do want to add this compiler flag then it ought to be
done in configure I think, as we do for -fno-strict-aliasing.)


Globally adding that flag can limits the optimizations of gcc since in
other places (loops) the undefined behavior can be advantageous, hence
added only to Makefile.hw.

-- PMM



--
Raghavendra Prabhu
GPG Id : 0xD72BE977
Fingerprint: B93F EBCB 8E05 7039 CD3C A4B8 A616 DCA1 D72B E977
www: wnohang.net



[Qemu-devel] [PATCH 5/9] msix: use specific endian ld/st_phys

2011-07-05 Thread Alexander Graf
Signed-off-by: Alexander Graf ag...@suse.de
---
 hw/msix.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/msix.c b/hw/msix.c
index 03d7bec..e67e700 100644
--- a/hw/msix.c
+++ b/hw/msix.c
@@ -359,7 +359,7 @@ void msix_notify(PCIDevice *dev, unsigned vector)
 
 address = pci_get_quad(table_entry + PCI_MSIX_ENTRY_LOWER_ADDR);
 data = pci_get_long(table_entry + PCI_MSIX_ENTRY_DATA);
-stl_phys(address, data);
+stl_le_phys(address, data);
 }
 
 void msix_reset(PCIDevice *dev)
-- 
1.7.3.4




Re: [Qemu-devel] KVM call agenda for June 28

2011-07-05 Thread Stefan Hajnoczi
On Tue, Jul 5, 2011 at 3:32 PM, Marcelo Tosatti mtosa...@redhat.com wrote:
 On Tue, Jul 05, 2011 at 04:39:06PM +0300, Dor Laor wrote:
 On 07/05/2011 03:58 PM, Marcelo Tosatti wrote:
 On Tue, Jul 05, 2011 at 01:40:08PM +0100, Stefan Hajnoczi wrote:
 On Tue, Jul 5, 2011 at 9:01 AM, Dor Laordl...@redhat.com  wrote:
 I tried to re-arrange all of the requirements and use cases using this 
 wiki
 page: http://wiki.qemu.org/Features/LiveBlockMigration
 
 It would be the best to agree upon the most interesting use cases (while 
 we
 make sure we cover future ones) and agree to them.
 The next step is to set the interface for all the various verbs since the
 implementation seems to be converging.
 
 Live block copy was supposed to support snapshot merge.  I think the
 current favored approach is to make the source image a backing file to
 the destination image and essentially do image streaming.
 
 Using this mechanism for snapshot merge is tricky.  The COW file
 already uses the read-only snapshot base image.  So now we cannot
 trivally copy the COW file contents back into the snapshot base image
 using live block copy.
 
 It never did. Live copy creates a new image were both snapshot and
 current are copied to.
 
 This is similar with image streaming.

 Not sure I realize what's bad to do in-place merge:

 Let's suppose we have this COW chain:

   base -- s1 -- s2

 Now a live snapshot is created over s2, s2 becomes RO and s3 is RW:

   base -- s1 -- s2 -- s3

 Now we've done with s2 (post backup) and like to merge s3 into s2.

 With your approach we use live copy of s3 into newSnap:

   base -- s1 -- s2 -- s3
   base -- s1 -- newSnap

 When it is over s2 and s3 can be erased.
 The down side is the IOs for copying s2 data and the temporary
 storage. I guess temp storage is cheap but excessive IO are
 expensive.

 My approach was to collapse s3 into s2 and erase s3 eventually:

 before: base -- s1 -- s2 -- s3
 after:  base -- s1 -- s2

 If we use live block copy using mirror driver it should be safe as
 long as we keep the ordering of new writes into s3 during the
 execution.
 Even a failure in the the middle won't cause harm since the
 management will keep using s3 until it gets success event.

 Well, it is more complicated than simply streaming into a new
 image. I'm not entirely sure it is necessary. The common case is:

 base - sn-1 - sn-2 - ... - sn-n

 When n reaches a limit, you do:

 base - merge-1

 You're potentially copying similar amount of data when merging back into
 a single image (and you can't easily merge multiple snapshots).

 If the amount of data thats not in 'base' is large, you create
 leave a new external file around:

 base - merge-1 - sn-1 - sn-2 ... - sn-n
 to
 base - merge-1 - merge-2

 
 It seems like snapshot merge will require dedicated code that reads
 the allocated clusters from the COW file and writes them back into the
 base image.
 
 A very inefficient alternative would be to create a third image, the
 merge image file, which has the COW file as its backing file:
 snapshot (base) -  cow -  merge

 Remember there is a 'base' before snapshot, you don't copy the entire
 image.

One use case I have in mind is the Live Backup approach that Jagane
has been developing.  Here the backup solution only creates a snapshot
for the period of time needed to read out the dirty blocks.  Then the
snapshot is deleted again and probably contains very little new data
relative to the base image.  The backup solution does this operation
every day.

This is the pathalogical case for any approach that copies the entire
base into a new file.  We could have avoided a lot of I/O by doing an
in-place update.

I want to make sure this works well.

Stefan



[Qemu-devel] [PATCH 8/9] s390-virtio: use specific endian ld/st_phys

2011-07-05 Thread Alexander Graf
Signed-off-by: Alexander Graf ag...@suse.de
---
 hw/s390-virtio-bus.c |   10 +-
 hw/s390-virtio.c |6 +++---
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
index d4a12f7..dde6ba5 100644
--- a/hw/s390-virtio-bus.c
+++ b/hw/s390-virtio-bus.c
@@ -165,7 +165,7 @@ static uint64_t 
s390_virtio_device_vq_token(VirtIOS390Device *dev, int vq)
 (vq * VIRTIO_VQCONFIG_LEN) +
 VIRTIO_VQCONFIG_OFFS_TOKEN;
 
-return ldq_phys(token_off);
+return ldq_be_phys(token_off);
 }
 
 static ram_addr_t s390_virtio_device_num_vq(VirtIOS390Device *dev)
@@ -219,8 +219,8 @@ void s390_virtio_device_sync(VirtIOS390Device *dev)
 vring = s390_virtio_next_ring(bus);
 virtio_queue_set_addr(dev-vdev, i, vring);
 virtio_queue_set_vector(dev-vdev, i, i);
-stq_phys(vq + VIRTIO_VQCONFIG_OFFS_ADDRESS, vring);
-stw_phys(vq + VIRTIO_VQCONFIG_OFFS_NUM, 
virtio_queue_get_num(dev-vdev, i));
+stq_be_phys(vq + VIRTIO_VQCONFIG_OFFS_ADDRESS, vring);
+stw_be_phys(vq + VIRTIO_VQCONFIG_OFFS_NUM, 
virtio_queue_get_num(dev-vdev, i));
 }
 
 cur_offs = dev-dev_offs;
@@ -228,7 +228,7 @@ void s390_virtio_device_sync(VirtIOS390Device *dev)
 cur_offs += num_vq * VIRTIO_VQCONFIG_LEN;
 
 /* Sync feature bitmap */
-stl_phys(cur_offs, bswap32(dev-host_features));
+stl_le_phys(cur_offs, dev-host_features);
 
 dev-feat_offs = cur_offs + dev-feat_len;
 cur_offs += dev-feat_len * 2;
@@ -252,7 +252,7 @@ void s390_virtio_device_update_status(VirtIOS390Device *dev)
 
 /* Update guest supported feature bitmap */
 
-features = bswap32(ldl_phys(dev-feat_offs));
+features = bswap32(ldl_be_phys(dev-feat_offs));
 if (vdev-set_features) {
 vdev-set_features(vdev, features);
 }
diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
index 3eba7ea..abe954d 100644
--- a/hw/s390-virtio.c
+++ b/hw/s390-virtio.c
@@ -193,7 +193,7 @@ static void s390_init(ram_addr_t my_ram_size,
 if (kernel_filename) {
 kernel_size = load_image(kernel_filename, qemu_get_ram_ptr(0));
 
-if (lduw_phys(KERN_IMAGE_START) != 0x0dd0) {
+if (lduw_be_phys(KERN_IMAGE_START) != 0x0dd0) {
 fprintf(stderr, Specified image is not an s390 boot image\n);
 exit(1);
 }
@@ -232,8 +232,8 @@ static void s390_init(ram_addr_t my_ram_size,
 }
 initrd_size = load_image(initrd_filename, 
qemu_get_ram_ptr(initrd_offset));
 
-stq_phys(INITRD_PARM_START, initrd_offset);
-stq_phys(INITRD_PARM_SIZE, initrd_size);
+stq_be_phys(INITRD_PARM_START, initrd_offset);
+stq_be_phys(INITRD_PARM_SIZE, initrd_size);
 }
 
 if (kernel_cmdline) {
-- 
1.7.3.4




Re: [Qemu-devel] [PATCH V2] [PowerPC][RFC] booke timers

2011-07-05 Thread Fabien Chouteau
On 05/07/2011 18:02, Scott Wood wrote:
 On Mon, 4 Jul 2011 17:06:54 +0200
 Fabien Chouteau chout...@adacore.com wrote:
 
 On 01/07/2011 22:22, Scott Wood wrote:
 On Fri, 1 Jul 2011 16:13:41 +0200
 Fabien Chouteau chout...@adacore.com wrote:
 +static void booke_update_fixed_timer(CPUState *env,
 + uint8_t   target_bit,
 + uint64_t  *next,
 + struct QEMUTimer *timer)
 +{
 +ppc_tb_t *tb_env = env-tb_env;
 +uint64_t lapse;
 +uint64_t tb;
 +uint64_t period = 1  (target_bit + 1);
 +uint64_t now;
 +
 +now = qemu_get_clock_ns(vm_clock);
 +tb  = cpu_ppc_get_tb(tb_env, now, tb_env-tb_offset);
 +
 +if (tb = (1  target_bit)) {
 +lapse = (1  target_bit) - tb;
 +} else {
 +lapse = period - ((tb - (1  target_bit)) % period);

 We know period is a power of two, so just do  (period - 1).

 That should let you get rid of the special case for
 tb = (1  target_bit) as well.


 Do you mean lapse = period - ((tb - (1  target_bit))  (period - 1)); ?
 
 Yes.
 
 Or more simply:
 
 lapse = period - ((tb - period)  (period - 1));
 

Are you sure? Note that period != (1  target_bit).

 I don't see how this solves the tb = (1  target_bit) case.
 
 Actually, since everything is unsigned the special case shouldn't be needed
 regardless.

You're right about this one, it's tricky though :)

-- 
Fabien Chouteau



[Qemu-devel] [PATCH 09/12] xen_disk: treat aio as raw

2011-07-05 Thread Alexander Graf
From: Stefano Stabellini stefano.stabell...@eu.citrix.com

Sometimes the toolstack uses aio without an additional format
identifier, in such cases use raw.

Updated in v2:

- fix code style.

Signed-off-by: Stefano Stabellini stefano.stabell...@eu.citrix.com
Signed-off-by: Alexander Graf ag...@suse.de
---
 hw/xen_disk.c |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/hw/xen_disk.c b/hw/xen_disk.c
index f14e5a6..add815f 100644
--- a/hw/xen_disk.c
+++ b/hw/xen_disk.c
@@ -633,6 +633,9 @@ static int blk_init(struct XenDevice *xendev)
 blkdev-filename  = blkdev-params;
 }
 }
+if (!strcmp(aio, blkdev-fileproto)) {
+blkdev-fileproto = raw;
+}
 if (blkdev-mode == NULL) {
 blkdev-mode = xenstore_read_be_str(blkdev-xendev, mode);
 }
-- 
1.6.0.2




[Qemu-devel] [PATCH 4/9] msi: use specific endian ld/st_phys

2011-07-05 Thread Alexander Graf
Signed-off-by: Alexander Graf ag...@suse.de
---
 hw/msi.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/msi.c b/hw/msi.c
index e8c5607..f214fcf 100644
--- a/hw/msi.c
+++ b/hw/msi.c
@@ -249,7 +249,7 @@ void msi_notify(PCIDevice *dev, unsigned int vector)
notify vector 0x%x
 address: 0x%PRIx64 data: 0x%PRIx32\n,
vector, address, data);
-stl_phys(address, data);
+stl_le_phys(address, data);
 }
 
 /* call this function after updating configs by pci_default_write_config(). */
-- 
1.7.3.4




[Qemu-devel] [PATCH 08/12] qemu_ram_ptr_length: take ram_addr_t as arguments

2011-07-05 Thread Alexander Graf
From: Stefano Stabellini stefano.stabell...@eu.citrix.com

qemu_ram_ptr_length should take ram_addr_t as argument rather than
target_phys_addr_t because is doing comparisons with RAMBlock addresses.

cpu_physical_memory_map should create a ram_addr_t address to pass to
qemu_ram_ptr_length from PhysPageDesc phys_offset.

Remove code after abort() in qemu_ram_ptr_length.

Changes in v2:

- handle 0 size in qemu_ram_ptr_length;

- rename addr1 to raddr;

- initialize raddr to ULONG_MAX.

Signed-off-by: Stefano Stabellini stefano.stabell...@eu.citrix.com
Reviewed-by: Peter Maydell peter.mayd...@linaro.org
Signed-off-by: Alexander Graf ag...@suse.de
---
 cpu-common.h |2 +-
 exec.c   |   21 ++---
 2 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/cpu-common.h b/cpu-common.h
index b027e43..e4fcded 100644
--- a/cpu-common.h
+++ b/cpu-common.h
@@ -65,7 +65,7 @@ void qemu_ram_free_from_ptr(ram_addr_t addr);
 void qemu_ram_remap(ram_addr_t addr, ram_addr_t length);
 /* This should only be used for ram local to a device.  */
 void *qemu_get_ram_ptr(ram_addr_t addr);
-void *qemu_ram_ptr_length(target_phys_addr_t addr, target_phys_addr_t *size);
+void *qemu_ram_ptr_length(ram_addr_t addr, ram_addr_t *size);
 /* Same but slower, to use for migration, where the order of
  * RAMBlocks must not change. */
 void *qemu_safe_ram_ptr(ram_addr_t addr);
diff --git a/exec.c b/exec.c
index 5604946..c0673c2 100644
--- a/exec.c
+++ b/exec.c
@@ -3167,8 +3167,11 @@ void *qemu_safe_ram_ptr(ram_addr_t addr)
 
 /* Return a host pointer to guest's ram. Similar to qemu_get_ram_ptr
  * but takes a size argument */
-void *qemu_ram_ptr_length(target_phys_addr_t addr, target_phys_addr_t *size)
+void *qemu_ram_ptr_length(ram_addr_t addr, ram_addr_t *size)
 {
+if (*size == 0) {
+return NULL;
+}
 if (xen_enabled()) {
 return xen_map_cache(addr, *size, 1);
 } else {
@@ -3184,9 +3187,6 @@ void *qemu_ram_ptr_length(target_phys_addr_t addr, 
target_phys_addr_t *size)
 
 fprintf(stderr, Bad ram offset % PRIx64 \n, (uint64_t)addr);
 abort();
-
-*size = 0;
-return NULL;
 }
 }
 
@@ -4052,7 +4052,9 @@ void *cpu_physical_memory_map(target_phys_addr_t addr,
 target_phys_addr_t page;
 unsigned long pd;
 PhysPageDesc *p;
-target_phys_addr_t addr1 = addr;
+ram_addr_t raddr = ULONG_MAX;
+ram_addr_t rlen;
+void *ret;
 
 while (len  0) {
 page = addr  TARGET_PAGE_MASK;
@@ -4080,13 +4082,18 @@ void *cpu_physical_memory_map(target_phys_addr_t addr,
 *plen = l;
 return bounce.buffer;
 }
+if (!todo) {
+raddr = (pd  TARGET_PAGE_MASK) + (addr  ~TARGET_PAGE_MASK);
+}
 
 len -= l;
 addr += l;
 todo += l;
 }
-*plen = todo;
-return qemu_ram_ptr_length(addr1, plen);
+rlen = todo;
+ret = qemu_ram_ptr_length(raddr, rlen);
+*plen = rlen;
+return ret;
 }
 
 /* Unmaps a memory region previously mapped by cpu_physical_memory_map().
-- 
1.6.0.2




[Qemu-devel] [PATCH 06/12] xen: add vkbd support for PV on HVM guests

2011-07-05 Thread Alexander Graf
From: Stefano Stabellini stefano.stabell...@eu.citrix.com

Register the vkbd backend even when running as device emulator for HVM
guests: it is useful because it doesn't need a frequent timer like usb.

Check whether the XenInput DisplayState has been set in the initialise
state, rather than the input state.
In case the DisplayState hasn't been set and there is no vfb for this
domain, then set the XenInput DisplayState to the default one.

Changed in v2:

- use qemu_free instead of free;

Signed-off-by: Stefano Stabellini stefano.stabell...@eu.citrix.com
Signed-off-by: Alexander Graf ag...@suse.de
---
 hw/xenfb.c |   19 ---
 xen-all.c  |1 +
 2 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/hw/xenfb.c b/hw/xenfb.c
index 1db75fb..0a01ae3 100644
--- a/hw/xenfb.c
+++ b/hw/xenfb.c
@@ -347,13 +347,6 @@ static void xenfb_mouse_event(void *opaque,
 
 static int input_init(struct XenDevice *xendev)
 {
-struct XenInput *in = container_of(xendev, struct XenInput, c.xendev);
-
-if (!in-c.ds) {
-xen_be_printf(xendev, 1, ds not set (yet)\n);
-   return -1;
-}
-
 xenstore_write_be_int(xendev, feature-abs-pointer, 1);
 return 0;
 }
@@ -367,6 +360,18 @@ static int input_connect(struct XenDevice *xendev)
  in-abs_pointer_wanted) == -1)
in-abs_pointer_wanted = 0;
 
+if (!in-c.ds) {
+char *vfb = xenstore_read_str(NULL, device/vfb);
+if (vfb == NULL) {
+/* there is no vfb, run vkbd on its own */
+in-c.ds = get_displaystate();
+} else {
+qemu_free(vfb);
+xen_be_printf(xendev, 1, ds not set (yet)\n);
+return -1;
+}
+}
+
 rc = common_bind(in-c);
 if (rc != 0)
return rc;
diff --git a/xen-all.c b/xen-all.c
index 3d40ab0..fb9bcc8 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -868,6 +868,7 @@ int xen_hvm_init(void)
 exit(1);
 }
 xen_be_register(console, xen_console_ops);
+xen_be_register(vkbd, xen_kbdmouse_ops);
 xen_be_register(qdisk, xen_blkdev_ops);
 
 return 0;
-- 
1.6.0.2




[Qemu-devel] [PATCH 04/12] xen: enable console and disk backend in HVM mode

2011-07-05 Thread Alexander Graf
From: Stefano Stabellini stefano.stabell...@eu.citrix.com

Initialize the Xen console backend and the Xen disk backend even when
running in HVM mode so that PV on HVM drivers can connect to them.

Signed-off-by: Stefano Stabellini stefano.stabell...@eu.citrix.com
Signed-off-by: Alexander Graf ag...@suse.de
---
 xen-all.c |8 
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/xen-all.c b/xen-all.c
index 4827d6a..3d40ab0 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -862,6 +862,14 @@ int xen_hvm_init(void)
 cpu_register_phys_memory_client(state-client);
 state-log_for_dirtybit = NULL;
 
+/* Initialize backend core  drivers */
+if (xen_be_init() != 0) {
+fprintf(stderr, %s: xen backend core setup failed\n, __FUNCTION__);
+exit(1);
+}
+xen_be_register(console, xen_console_ops);
+xen_be_register(qdisk, xen_blkdev_ops);
+
 return 0;
 }
 
-- 
1.6.0.2




  1   2   >