[Qemu-devel] [PATCH 2/2] Don't zero out buffer in sched_getaffinity

2011-04-18 Thread Mike McCormack
The kernel doesn't fill the buffer provided to sched_getaffinity
with zero bytes, so neither should QEMU.

Signed-off-by: Mike McCormack 
Reviewed-by: Stefan Hajnoczi 
---
 linux-user/syscall.c |   13 +
 1 files changed, 1 insertions(+), 12 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 1cda10a..e53b7e5 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6384,20 +6384,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long 
arg1,
 ret = get_errno(sys_sched_getaffinity(arg1, mask_size, mask));
 
 if (!is_error(ret)) {
-if (arg2 > ret) {
-/* Zero out any extra space kernel didn't fill */
-unsigned long zero = arg2 - ret;
-p = alloca(zero);
-memset(p, 0, zero);
-if (copy_to_user(arg3 + ret, p, zero)) {
-goto efault;
-}
-arg2 = ret;
-}
-if (copy_to_user(arg3, mask, arg2)) {
+if (copy_to_user(arg3, mask, ret)) {
 goto efault;
 }
-ret = arg2;
 }
 }
 break;
-- 
1.7.0.4




[Qemu-devel] [PATCH 1/2] Fix buffer overrun in sched_getaffinity

2011-04-18 Thread Mike McCormack
Zeroing of the cpu array should start from &cpus[kernel_ret]
not &cpus[num_zeros_to_fill].

This fixes a crash in EFL's edje_cc running under qemu-arm.

Signed-off-by: Mike McCormack 
Reviewed-by: Stefan Hajnoczi 
Acked-by: Mike Frysinger 
---
 linux-user/syscall.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index bb0999d..1cda10a 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6389,7 +6389,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 unsigned long zero = arg2 - ret;
 p = alloca(zero);
 memset(p, 0, zero);
-if (copy_to_user(arg3 + zero, p, zero)) {
+if (copy_to_user(arg3 + ret, p, zero)) {
 goto efault;
 }
 arg2 = ret;
-- 
1.7.0.4





[Qemu-devel] [PATCH] virtio-serial: Fix endianness bug in the config space

2011-04-18 Thread David Gibson
From: Alexey Kardashevskiy 

The virtio serial specification requres that the values in the config
space are encoded in native endian of the guest.

The qemu virtio-serial code did not do conversion to the guest endian
format what caused problems when host and guest use different format.

This patch corrects the qemu side, correctly doing host-native <->
guest-native conversions when accessing the config space. This won't
break any setups that aren't already broken, and fixes the case
of different host and guest endianness.

Signed-off-by: Alexey Kardashevskiy 
---
 hw/virtio-serial-bus.c |   23 +--
 1 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 6227379..f10d48f 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -494,7 +494,7 @@ static void virtio_serial_save(QEMUFile *f, void *opaque)
 VirtIOSerial *s = opaque;
 VirtIOSerialPort *port;
 uint32_t nr_active_ports;
-unsigned int i;
+unsigned int i, max_nr_ports;
 
 /* The virtio device */
 virtio_save(&s->vdev, f);
@@ -506,8 +506,8 @@ static void virtio_serial_save(QEMUFile *f, void *opaque)
 qemu_put_be32s(f, &s->config.max_nr_ports);
 
 /* The ports map */
-
-for (i = 0; i < (s->config.max_nr_ports + 31) / 32; i++) {
+max_nr_ports = tswap32(s->config.max_nr_ports);
+for (i = 0; i < (max_nr_ports + 31) / 32; i++) {
 qemu_put_be32s(f, &s->ports_map[i]);
 }
 
@@ -568,7 +568,8 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, 
int version_id)
 qemu_get_be16s(f, &s->config.rows);
 
 qemu_get_be32s(f, &max_nr_ports);
-if (max_nr_ports > s->config.max_nr_ports) {
+tswap32s(&max_nr_ports);
+if (max_nr_ports > tswap32(s->config.max_nr_ports)) {
 /* Source could have had more ports than us. Fail migration. */
 return -EINVAL;
 }
@@ -670,9 +671,10 @@ static void virtser_bus_dev_print(Monitor *mon, 
DeviceState *qdev, int indent)
 /* This function is only used if a port id is not provided by the user */
 static uint32_t find_free_port_id(VirtIOSerial *vser)
 {
-unsigned int i;
+unsigned int i, max_nr_ports;
 
-for (i = 0; i < (vser->config.max_nr_ports + 31) / 32; i++) {
+max_nr_ports = tswap32(vser->config.max_nr_ports);
+for (i = 0; i < (max_nr_ports + 31) / 32; i++) {
 uint32_t map, bit;
 
 map = vser->ports_map[i];
@@ -720,7 +722,7 @@ static int virtser_port_qdev_init(DeviceState *qdev, 
DeviceInfo *base)
 VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, qdev);
 VirtIOSerialPortInfo *info = DO_UPCAST(VirtIOSerialPortInfo, qdev, base);
 VirtIOSerialBus *bus = DO_UPCAST(VirtIOSerialBus, qbus, qdev->parent_bus);
-int ret;
+int ret, max_nr_ports;
 bool plugging_port0;
 
 port->vser = bus->vser;
@@ -750,9 +752,10 @@ static int virtser_port_qdev_init(DeviceState *qdev, 
DeviceInfo *base)
 }
 }
 
-if (port->id >= port->vser->config.max_nr_ports) {
+max_nr_ports = tswap32(port->vser->config.max_nr_ports);
+if (port->id >= max_nr_ports) {
 error_report("virtio-serial-bus: Out-of-range port id specified, max. 
allowed: %u\n",
- port->vser->config.max_nr_ports - 1);
+ max_nr_ports - 1);
 return -1;
 }
 
@@ -863,7 +866,7 @@ VirtIODevice *virtio_serial_init(DeviceState *dev, 
virtio_serial_conf *conf)
 vser->ovqs[i] = virtio_add_queue(vdev, 128, handle_output);
 }
 
-vser->config.max_nr_ports = conf->max_virtserial_ports;
+vser->config.max_nr_ports = tswap32(conf->max_virtserial_ports);
 vser->ports_map = qemu_mallocz(((conf->max_virtserial_ports + 31) / 32)
 * sizeof(vser->ports_map[0]));
 /*
-- 
1.7.1




[Qemu-devel] [PATCH 1/3] pseries: Increase maximum CPUs to 256

2011-04-18 Thread David Gibson
From: Anton Blanchard 

The original pSeries machine was limited to 32 CPUs, more or less
arbitrarily.  Particularly when we get SMT KVM guests it will be
pretty easy to exceed this.  Therefore, raise the max number of CPUs
in a pseries machine guest to 256.

Signed-off-by: Anton Blanchard 
Signed-off-by: David Gibson 
---
 hw/spapr.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/spapr.c b/hw/spapr.c
index 1782cc0..67dd1e5 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -51,7 +51,7 @@
 
 #define TIMEBASE_FREQ   51200ULL
 
-#define MAX_CPUS32
+#define MAX_CPUS256
 #define XICS_IRQS  1024
 
 sPAPREnvironment *spapr;
-- 
1.7.1




[Qemu-devel] [PATCH 3/3] Place pseries vty devices at addresses more similar to existing machines

2011-04-18 Thread David Gibson
Currently the qemu pseries machine numbers its virtual serial devices
from 0.  However, existing pSeries machines running pHyp number them from
0x3000.

In theory these indices are arbitrary, since everything necessary for the
kernel to find them is advertised in the device tree.  However the debian
installer, at least, incorrectly looks for a device named vty@30... to
determine whether to use the hypervisor console.

Therefore this patch moves the numbers we use to match the existing pHyp
practice, in order to workaround broken userspace apps of this type.

Signed-off-by: David Gibson 
---
 hw/spapr.c  |5 +++--
 hw/spapr_rtas.c |3 ++-
 hw/spapr_vio.h  |2 ++
 3 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/hw/spapr.c b/hw/spapr.c
index 884c667..109b774 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -362,8 +362,9 @@ static void ppc_spapr_init(ram_addr_t ram_size,
 
 for (i = 0; i < MAX_SERIAL_PORTS; i++, irq++) {
 if (serial_hds[i]) {
-spapr_vty_create(spapr->vio_bus, i, serial_hds[i],
- xics_find_qirq(spapr->icp, irq), irq);
+spapr_vty_create(spapr->vio_bus, SPAPR_VTY_BASE_ADDRESS + i,
+ serial_hds[i], xics_find_qirq(spapr->icp, irq),
+ irq);
 }
 }
 
diff --git a/hw/spapr_rtas.c b/hw/spapr_rtas.c
index 16b6542..00c8ce5 100644
--- a/hw/spapr_rtas.c
+++ b/hw/spapr_rtas.c
@@ -44,7 +44,8 @@ static void rtas_display_character(sPAPREnvironment *spapr,
uint32_t nret, target_ulong rets)
 {
 uint8_t c = rtas_ld(args, 0);
-VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, 0);
+VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus,
+ SPAPR_VTY_BASE_ADDRESS);
 
 if (!sdev) {
 rtas_st(rets, 0, -1);
diff --git a/hw/spapr_vio.h b/hw/spapr_vio.h
index 841b043..603a8c4 100644
--- a/hw/spapr_vio.h
+++ b/hw/spapr_vio.h
@@ -32,6 +32,8 @@ enum VIOsPAPR_TCEAccess {
 SPAPR_TCE_RW = 3,
 };
 
+#define SPAPR_VTY_BASE_ADDRESS 0x3000
+
 struct VIOsPAPRDevice;
 
 typedef struct VIOsPAPR_RTCE {
-- 
1.7.1




[Qemu-devel] [PATCH 2/3] Make pSeries 'model' property more closely resemble real hardware

2011-04-18 Thread David Gibson
Currently, the qemu emulated pseries machine puts
"qemu,emulated-pSeries-LPAR" in the device tree's root level 'model'
property.  Unfortunately this confuses some installers and ybin, which
expect this to start with "IBM" on pSeries machines.  This patch addresses
this problem, making the property more closely resemble the pattern of
existing real hardware.

Signed-off-by: David Gibson 
---
 hw/spapr.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/spapr.c b/hw/spapr.c
index 67dd1e5..884c667 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -93,7 +93,7 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
 /* Root node */
 _FDT((fdt_begin_node(fdt, "")));
 _FDT((fdt_property_string(fdt, "device_type", "chrp")));
-_FDT((fdt_property_string(fdt, "model", "qemu,emulated-pSeries-LPAR")));
+_FDT((fdt_property_string(fdt, "model", "IBM pSeries (emulated by 
qemu)")));
 
 _FDT((fdt_property_cell(fdt, "#address-cells", 0x2)));
 _FDT((fdt_property_cell(fdt, "#size-cells", 0x2)));
-- 
1.7.1




[Qemu-devel] [0/3] More pSeries machine tweaks

2011-04-18 Thread David Gibson
Hi Alex,

Here are several more minor tweaks/improvements to the pseries machine 
emulation.




Re: [Qemu-devel] [PATCH 1/2] KVM: PPC: booke: save/restore VRSAVE (a.k.a. USPRG0)

2011-04-18 Thread Scott Wood
On Mon, Apr 18, 2011 at 05:25:48PM -0500, Scott Wood wrote:
> Linux doesn't use USPRG0 (now renamed VRSAVE in the architecture, even
> when Altivec isn't involved), but a guest might.
> 
> Signed-off-by: Scott Wood 
> ---
>  arch/powerpc/include/asm/kvm_host.h |1 +
>  arch/powerpc/kernel/asm-offsets.c   |1 +
>  arch/powerpc/kvm/booke_interrupts.S |5 -
>  3 files changed, 6 insertions(+), 1 deletions(-)

Please ignore this (and 2/2), accidentally sent to the wrong list.

-Scott




[Qemu-devel] [PATCH 2/2] KVM: PPC: booke: add sregs support

2011-04-18 Thread Scott Wood
Signed-off-by: Scott Wood 
---
 Documentation/kvm/api.txt   |6 +-
 arch/powerpc/include/asm/kvm.h  |  184 +++
 arch/powerpc/include/asm/kvm_44x.h  |1 -
 arch/powerpc/include/asm/kvm_e500.h |1 +
 arch/powerpc/include/asm/kvm_host.h |3 +
 arch/powerpc/include/asm/kvm_ppc.h  |9 ++
 arch/powerpc/kvm/44x.c  |   10 ++
 arch/powerpc/kvm/booke.c|  153 -
 arch/powerpc/kvm/e500.c |   75 ++
 arch/powerpc/kvm/e500_emulate.c |5 +-
 arch/powerpc/kvm/e500_tlb.c |8 ++
 arch/powerpc/kvm/emulate.c  |   13 ++-
 arch/powerpc/kvm/powerpc.c  |4 +
 include/linux/kvm.h |1 +
 14 files changed, 460 insertions(+), 13 deletions(-)

diff --git a/Documentation/kvm/api.txt b/Documentation/kvm/api.txt
index 1b9eaa7..f64c41f 100644
--- a/Documentation/kvm/api.txt
+++ b/Documentation/kvm/api.txt
@@ -261,7 +261,7 @@ See KVM_GET_REGS for the data structure.
 4.13 KVM_GET_SREGS
 
 Capability: basic
-Architectures: x86
+Architectures: x86, ppc
 Type: vcpu ioctl
 Parameters: struct kvm_sregs (out)
 Returns: 0 on success, -1 on error
@@ -279,6 +279,8 @@ struct kvm_sregs {
__u64 interrupt_bitmap[(KVM_NR_INTERRUPTS + 63) / 64];
 };
 
+/* ppc -- see arch/powerpc/include/asm/kvm.h */
+
 interrupt_bitmap is a bitmap of pending external interrupts.  At most
 one bit may be set.  This interrupt has been acknowledged by the APIC
 but not yet injected into the cpu core.
@@ -286,7 +288,7 @@ but not yet injected into the cpu core.
 4.14 KVM_SET_SREGS
 
 Capability: basic
-Architectures: x86
+Architectures: x86, ppc
 Type: vcpu ioctl
 Parameters: struct kvm_sregs (in)
 Returns: 0 on success, -1 on error
diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/asm/kvm.h
index 18ea696..d2ca5ed 100644
--- a/arch/powerpc/include/asm/kvm.h
+++ b/arch/powerpc/include/asm/kvm.h
@@ -45,6 +45,114 @@ struct kvm_regs {
__u64 gpr[32];
 };
 
+#define KVM_SREGS_E_IMPL_NONE  0
+#define KVM_SREGS_E_IMPL_FSL   1
+
+#define KVM_SREGS_E_FSL_PIDn   (1 << 0) /* PID1/PID2 */
+
+/*
+ * Feature bits indicate which sections of the sregs struct are valid,
+ * both in KVM_GET_SREGS and KVM_SET_SREGS.  On KVM_SET_SREGS, registers
+ * corresponding to unset feature bits will not be modified.  This allows
+ * restoring a checkpoint made without that feature, while keeping the
+ * default values of the new registers.
+ *
+ * KVM_SREGS_E_BASE contains:
+ * CSRR0/1 (refers to SRR2/3 on 40x)
+ * ESR
+ * DEAR
+ * MCSR
+ * TSR
+ * TCR
+ * DEC
+ * TB
+ * VRSAVE (USPRG0)
+ */
+#define KVM_SREGS_E_BASE   (1 << 0)
+
+/*
+ * KVM_SREGS_E_ARCH206 contains:
+ *
+ * PIR
+ * MCSRR0/1
+ * DECAR
+ * IVPR
+ */
+#define KVM_SREGS_E_ARCH206(1 << 1)
+
+/*
+ * Contains EPCR, plus the upper half of 64-bit registers
+ * that are 32-bit on 32-bit implementations.
+ */
+#define KVM_SREGS_E_64 (1 << 2)
+
+#define KVM_SREGS_E_SPRG8  (1 << 3)
+#define KVM_SREGS_E_MCIVPR (1 << 4)
+
+/*
+ * IVORs are used -- contains IVOR0-15, plus additional IVORs
+ * in combination with an appropriate feature bit.
+ */
+#define KVM_SREGS_E_IVOR   (1 << 5)
+
+/*
+ * Contains MAS0-4, MAS6-7, TLBnCFG, MMUCFG.
+ * Also TLBnPS if MMUCFG[MAVN] = 1.
+ */
+#define KVM_SREGS_E_ARCH206_MMU(1 << 6)
+
+/* DBSR, DBCR, IAC, DAC, DVC */
+#define KVM_SREGS_E_DEBUG  (1 << 7)
+
+/* Enhanced debug -- DSRR0/1, SPRG9 */
+#define KVM_SREGS_E_ED (1 << 8)
+
+/* Embedded Floating Point (SPE) -- IVOR32-34 if KVM_SREGS_E_IVOR */
+#define KVM_SREGS_E_SPE(1 << 9)
+
+/* External Proxy (EXP) -- EPR */
+#define KVM_SREGS_EXP  (1 << 10)
+
+/* External PID (E.PD) -- EPSC/EPLC */
+#define KVM_SREGS_E_PD (1 << 11)
+
+/* Processor Control (E.PC) -- IVOR36-37 if KVM_SREGS_E_IVOR */
+#define KVM_SREGS_E_PC (1 << 12)
+
+/* Page table (E.PT) -- EPTCFG */
+#define KVM_SREGS_E_PT (1 << 13)
+
+/* Embedded Performance Monitor (E.PM) -- IVOR35 if KVM_SREGS_E_IVOR */
+#define KVM_SREGS_E_PM (1 << 14)
+
+/*
+ * Special updates:
+ *
+ * Some registers may change even while a vcpu is not running.
+ * To avoid losing these changes, by default these registers are
+ * not updated by KVM_SET_SREGS.  To force an update, set the bit
+ * in u.e.update_special corresponding to the register to be updated.
+ *
+ * The update_special field is zero on return from KVM_GET_SREGS.
+ *
+ * When restoring a checkpoint, the caller can set update_special
+ * to 0x to ensure that everything is restored, even new features
+ * that the caller doesn't know about.
+ */
+#define KVM_SREGS_E_UPDATE_MCSR(1 << 0)
+#define KVM_SREGS_E_UPDATE_TSR (1 << 1)
+#define KVM_SREGS_E_UPDATE_DEC (1 << 2)
+#define KVM_SREGS_E_UPDATE_DBSR   

[Qemu-devel] [PATCH 1/2] KVM: PPC: booke: save/restore VRSAVE (a.k.a. USPRG0)

2011-04-18 Thread Scott Wood
Linux doesn't use USPRG0 (now renamed VRSAVE in the architecture, even
when Altivec isn't involved), but a guest might.

Signed-off-by: Scott Wood 
---
 arch/powerpc/include/asm/kvm_host.h |1 +
 arch/powerpc/kernel/asm-offsets.c   |1 +
 arch/powerpc/kvm/booke_interrupts.S |5 -
 3 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_host.h 
b/arch/powerpc/include/asm/kvm_host.h
index bfb0e0f..34b8732 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -228,6 +228,7 @@ struct kvm_vcpu_arch {
ulong hflags;
ulong guest_owned_ext;
 #endif
+   u32 vrsave; /* also USPRG0 */
u32 mmucr;
ulong shadow_msr;
ulong sprg4;
diff --git a/arch/powerpc/kernel/asm-offsets.c 
b/arch/powerpc/kernel/asm-offsets.c
index 2b223de..7b9e35e 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -395,6 +395,7 @@ int main(void)
DEFINE(VCPU_HOST_STACK, offsetof(struct kvm_vcpu, arch.host_stack));
DEFINE(VCPU_HOST_PID, offsetof(struct kvm_vcpu, arch.host_pid));
DEFINE(VCPU_GPRS, offsetof(struct kvm_vcpu, arch.gpr));
+   DEFINE(VCPU_VRSAVE, offsetof(struct kvm_vcpu, arch.vrsave));
DEFINE(VCPU_SPRG4, offsetof(struct kvm_vcpu, arch.sprg4));
DEFINE(VCPU_SPRG5, offsetof(struct kvm_vcpu, arch.sprg5));
DEFINE(VCPU_SPRG6, offsetof(struct kvm_vcpu, arch.sprg6));
diff --git a/arch/powerpc/kvm/booke_interrupts.S 
b/arch/powerpc/kvm/booke_interrupts.S
index 54c19d2..cde29c4 100644
--- a/arch/powerpc/kvm/booke_interrupts.S
+++ b/arch/powerpc/kvm/booke_interrupts.S
@@ -184,6 +184,8 @@ _GLOBAL(kvmppc_resume_host)
stw r3, VCPU_GPR(r4)(r4)
mfspr   r3, SPRN_SRR0
stw r3, VCPU_PC(r4)
+   mfspr   r3, SPRN_VRSAVE
+   stw r3, VCPU_VRSAVE(r4)
 
/* Restore host stack pointer and PID before IVPR, since the host
 * exception handlers use them. */
@@ -395,9 +397,10 @@ lightweight_exit:
 * because host interrupt handlers would get confused. */
lwz r1, VCPU_GPR(r1)(r4)
 
-   /* XXX handle USPRG0 */
/* Host interrupt handlers may have clobbered these guest-readable
 * SPRGs, so we need to reload them here with the guest's values. */
+   lwz r3, VCPU_VRSAVE(r4)
+   mtspr   SPRN_VRSAVE, r3
lwz r3, VCPU_SPRG4(r4)
mtspr   SPRN_SPRG4W, r3
lwz r3, VCPU_SPRG5(r4)
-- 
1.7.1





Re: [Qemu-devel] [PATCH] target-ppc: use softfloat min/max functions

2011-04-18 Thread Alexander Graf

On 18.04.2011, at 21:23, Aurelien Jarno wrote:

> Use the new softfloat float32_min() and float32_max() to implement the
> vminfp and vmaxfp instructions.
> 
> Cc: Alexander Graf 
> Signed-off-by: Aurelien Jarno 
> ---
> target-ppc/op_helper.c |   16 +---
> 1 files changed, 5 insertions(+), 11 deletions(-)
> 
> diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
> index 9aa108e..9058d78 100644
> --- a/target-ppc/op_helper.c
> +++ b/target-ppc/op_helper.c
> @@ -2369,22 +2369,16 @@ VMINMAX(uw, u32)
> #undef VMINMAX_DO
> #undef VMINMAX
> 
> -#define VMINMAXFP(suffix, rT, rF)   \
> -void helper_v##suffix (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)\
> +#define VMINMAXFP(suffix)   \
> +void helper_v##suffix##fp (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)\
> {   \
> int i;  \
> for (i = 0; i < ARRAY_SIZE(r->f); i++) {\
> -HANDLE_NAN2(r->f[i], a->f[i], b->f[i]) {\
> -if (float32_lt_quiet(a->f[i], b->f[i], &env->vec_status)) { \
> -r->f[i] = rT->f[i]; \
> -} else {\
> -r->f[i] = rF->f[i]; \
> -}   \
> -}   \
> +r->f[i] = float32_##suffix(a->f[i], b->f[i], &env->vec_status); \

Now that you've removed all the magic from the macro, it'd probably be easier 
to read if you open coded it, no? :)


Alex




Re: [Qemu-devel] [PATCH 03/17] linux-user: define a couple of syscalls for non-uid16 targets

2011-04-18 Thread Alexander Graf

On 18.04.2011, at 18:32, Riku Voipio wrote:

> On Fri, Apr 15, 2011 at 05:32:44PM +0200, Alexander Graf wrote:
>> From: Ulrich Hecht 
>> 
>> Quite a number of syscalls are only defined on systems with USE_UID16
>> defined; this patch defines them on other systems as well.
>> 
>> Fixes a large number of uid/gid-related testcases on the s390x target
>> (and most likely on other targets as well)
> 
> I'll provide cleaner patch for the same effect. This one makes the code
> more ifdeffed and harder to follow.

You're more than welcome to. I only included the patch because it was part of 
Uli's original series :)


Alex




[Qemu-devel] [PATCH] multiboot: Support commas in module parameters

2011-04-18 Thread Adam Lackorzynski
Support commas in the parameter list of modules, by using double commas
(via get_opt_value()).

Signed-off-by: Adam Lackorzynski 
---
 hw/multiboot.c |   18 +-
 1 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/hw/multiboot.c b/hw/multiboot.c
index 394ed01..7d5cb22 100644
--- a/hw/multiboot.c
+++ b/hw/multiboot.c
@@ -97,11 +97,11 @@ typedef struct {
 
 static uint32_t mb_add_cmdline(MultibootState *s, const char *cmdline)
 {
-int len = strlen(cmdline) + 1;
 target_phys_addr_t p = s->offset_cmdlines;
+char *b = (char *)s->mb_buf + p;
 
-pstrcpy((char *)s->mb_buf + p, len, cmdline);
-s->offset_cmdlines += len;
+get_opt_value(b, strlen(cmdline) + 1, cmdline);
+s->offset_cmdlines += strlen(b) + 1;
 return s->mb_buf_phys + p;
 }
 
@@ -238,7 +238,7 @@ int load_multiboot(void *fw_cfg,
 const char *r = initrd_filename;
 mbs.mb_buf_size += strlen(r) + 1;
 mbs.mb_mods_avail = 1;
-while ((r = strchr(r, ','))) {
+while (*(r = get_opt_value(NULL, 0, r))) {
mbs.mb_mods_avail++;
r++;
 }
@@ -252,7 +252,7 @@ int load_multiboot(void *fw_cfg,
 mbs.offset_cmdlines = mbs.offset_mbinfo + mbs.mb_mods_avail * MB_MOD_SIZE;
 
 if (initrd_filename) {
-char *next_initrd;
+char *next_initrd, not_last;
 
 mbs.offset_mods = mbs.mb_buf_size;
 
@@ -261,9 +261,9 @@ int load_multiboot(void *fw_cfg,
 int mb_mod_length;
 uint32_t offs = mbs.mb_buf_size;
 
-next_initrd = strchr(initrd_filename, ',');
-if (next_initrd)
-*next_initrd = '\0';
+next_initrd = (char *)get_opt_value(NULL, 0, initrd_filename);
+not_last = *next_initrd;
+*next_initrd = '\0';
 /* if a space comes after the module filename, treat everything
after that as parameters */
 target_phys_addr_t c = mb_add_cmdline(&mbs, initrd_filename);
@@ -287,7 +287,7 @@ int load_multiboot(void *fw_cfg,
  (char *)mbs.mb_buf + offs,
  (char *)mbs.mb_buf + offs + mb_mod_length, c);
 initrd_filename = next_initrd+1;
-} while (next_initrd);
+} while (not_last);
 }
 
 /* Commandline support */
-- 
1.7.4.1




[Qemu-devel] [PATCH 14/20] target-i386: fix helper_fsqrt() wrt softfloat

2011-04-18 Thread Aurelien Jarno
Signed-off-by: Aurelien Jarno 
---
 target-i386/exec.h  |4 
 target-i386/op_helper.c |7 ++-
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/target-i386/exec.h b/target-i386/exec.h
index b2af894..292e0de 100644
--- a/target-i386/exec.h
+++ b/target-i386/exec.h
@@ -114,6 +114,7 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_div floatx80_div
 #define floatx_mul floatx80_mul
 #define floatx_sub floatx80_sub
+#define floatx_sqrt floatx80_sqrt
 #define floatx_abs floatx80_abs
 #define floatx_chs floatx80_chs
 #define floatx_scalbn floatx80_scalbn
@@ -121,6 +122,7 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_compare floatx80_compare
 #define floatx_compare_quiet floatx80_compare_quiet
 #define floatx_is_any_nan floatx80_is_any_nan
+#define floatx_is_neg floatx80_is_neg
 #define floatx_is_zero floatx80_is_zero
 #else
 #define floatx_to_int32 float64_to_int32
@@ -137,6 +139,7 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_div float64_div
 #define floatx_mul float64_mul
 #define floatx_sub float64_sub
+#define floatx_sqrt float64_sqrt
 #define floatx_abs float64_abs
 #define floatx_chs float64_chs
 #define floatx_scalbn float64_scalbn
@@ -144,6 +147,7 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_compare float64_compare
 #define floatx_compare_quiet float64_compare_quiet
 #define floatx_is_any_nan float64_is_any_nan
+#define floatx_is_neg float64_is_neg
 #define floatx_is_zero float64_is_zero
 #endif
 
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index d0d639c..d935488 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -4152,14 +4152,11 @@ void helper_fyl2xp1(void)
 
 void helper_fsqrt(void)
 {
-CPU86_LDouble fptemp;
-
-fptemp = ST0;
-if (fptemp<0.0) {
+if (floatx_is_neg(ST0)) {
 env->fpus &= (~0x4700);  /* (C3,C2,C1,C0) <--  */
 env->fpus |= 0x400;
 }
-ST0 = sqrt(fptemp);
+ST0 = floatx_sqrt(ST0, &env->fp_status);
 }
 
 void helper_fsincos(void)
-- 
1.7.2.3




Re: [Qemu-devel] [PATCH 10/17] s390x: keep hint on virtio managing size

2011-04-18 Thread Alexander Graf

On 18.04.2011, at 21:06, Aurelien Jarno wrote:

> On Fri, Apr 15, 2011 at 05:32:51PM +0200, Alexander Graf wrote:
>> The s390x virtio bus keeps management information on virtio after the top
>> of the guest's RAM. We need to be able to tell the guest the size of its
>> RAM (without virtio stuff), but also be able to trap when the guest accesses
>> RAM outside of its scope (including virtio stuff).
>> 
>> So we need a variable telling us the size of the virtio stuff, so we can
>> calculate the highest available RAM address from that.
>> 
>> While at it, also increase the maximum number of virtio pages, so we play
>> along well with more recent kernels that spawn a ridiculous number of virtio
>> console adapters.
>> 
>> Signed-off-by: Alexander Graf 
>> ---
>> hw/s390-virtio-bus.c |3 +++
>> hw/s390-virtio-bus.h |2 +-
>> target-s390x/cpu.h   |3 +++
>> 3 files changed, 7 insertions(+), 1 deletions(-)
>> 
>> diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
>> index bb49e39..a90963b 100644
>> --- a/hw/s390-virtio-bus.c
>> +++ b/hw/s390-virtio-bus.c
>> @@ -60,6 +60,9 @@ static const VirtIOBindings virtio_s390_bindings;
>> 
>> static ram_addr_t s390_virtio_device_num_vq(VirtIOS390Device *dev);
>> 
>> +/* length of VirtIO device pages */
>> +target_phys_addr_t virtio_size = S390_DEVICE_PAGES * TARGET_PAGE_SIZE;
>> +
> 
> If this variable is never written, can it be declared const?

Does that improve anything for exported variables? Do they get put into a ro 
section then?


Alex




[Qemu-devel] [PATCH 19/20] target-i386: fix constants wrt softfloat

2011-04-18 Thread Aurelien Jarno
Signed-off-by: Aurelien Jarno 
---
 target-i386/exec.h  |8 
 target-i386/op_helper.c |   24 +---
 2 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/target-i386/exec.h b/target-i386/exec.h
index 292e0de..ee36a71 100644
--- a/target-i386/exec.h
+++ b/target-i386/exec.h
@@ -124,6 +124,10 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_is_any_nan floatx80_is_any_nan
 #define floatx_is_neg floatx80_is_neg
 #define floatx_is_zero floatx80_is_zero
+#define floatx_zero floatx80_zero
+#define floatx_one floatx80_one
+#define floatx_ln2 floatx80_ln2
+#define floatx_pi floatx80_pi
 #else
 #define floatx_to_int32 float64_to_int32
 #define floatx_to_int64 float64_to_int64
@@ -149,6 +153,10 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_is_any_nan float64_is_any_nan
 #define floatx_is_neg float64_is_neg
 #define floatx_is_zero float64_is_zero
+#define floatx_zero float64_zero
+#define floatx_one float64_one
+#define floatx_ln2 float64_ln2
+#define floatx_pi float64_pi
 #endif
 
 #define RC_MASK 0xc00
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index 0c4f0da..a9bb80d 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -95,15 +95,25 @@ static const uint8_t rclb_table[32] = {
 6, 7, 8, 0, 1, 2, 3, 4,
 };
 
+#if defined(CONFIG_SOFTFLOAT)
+# define floatx_lg2 make_floatx80( 0x3ffd, 0x9a209a84fbcff799LL )
+# define floatx_l2e make_floatx80( 0x3fff, 0xb8aa3b295c17f0bcLL )
+# define floatx_l2t make_floatx80( 0x4000, 0xd49a784bcd1b8afeLL )
+#else
+# define floatx_lg2 (0.30102999566398119523L)
+# define floatx_l2e (1.44269504088896340739L)
+# define floatx_l2t (3.32192809488736234781L)
+#endif
+
 static const CPU86_LDouble f15rk[7] =
 {
-0.L,
-1.L,
-3.14159265358979323851L,  /*pi*/
-0.30102999566398119523L,  /*lg2*/
-0.69314718055994530943L,  /*ln2*/
-1.44269504088896340739L,  /*l2e*/
-3.32192809488736234781L,  /*l2t*/
+floatx_zero,
+floatx_one,
+floatx_pi,
+floatx_lg2,
+floatx_ln2,
+floatx_l2e,
+floatx_l2t,
 };
 
 /* broken thread support */
-- 
1.7.2.3




[Qemu-devel] [PATCH 17/20] target-i386: fix logarithmic and trigonometric helpers wrt softfloat

2011-04-18 Thread Aurelien Jarno
Use the new CPU86_LDouble <-> double conversion functions to make logarithmic
and trigonometric helpers working with softfloat.

Signed-off-by: Aurelien Jarno 
---
 target-i386/op_helper.c |   52 +++---
 1 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index f69458d..4671a96 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -17,6 +17,7 @@
  * License along with this library; if not, see .
  */
 
+#include 
 #include "exec.h"
 #include "exec-all.h"
 #include "host-utils.h"
@@ -3981,17 +3982,19 @@ void helper_fbst_ST0(target_ulong ptr)
 
 void helper_f2xm1(void)
 {
-ST0 = pow(2.0,ST0) - 1.0;
+double val = CPU86_LDouble_to_double(ST0);
+val = pow(2.0, val) - 1.0;
+ST0 = double_to_CPU86_LDouble(val);
 }
 
 void helper_fyl2x(void)
 {
-CPU86_LDouble fptemp;
+double fptemp = CPU86_LDouble_to_double(ST0);
 
-fptemp = ST0;
 if (fptemp>0.0){
-fptemp = log(fptemp)/log(2.0);  /* log2(ST) */
-ST1 *= fptemp;
+fptemp = log(fptemp)/log(2.0);/* log2(ST) */
+fptemp *= CPU86_LDouble_to_double(ST1);
+ST1 = double_to_CPU86_LDouble(fptemp);
 fpop();
 } else {
 env->fpus &= (~0x4700);
@@ -4001,15 +4004,15 @@ void helper_fyl2x(void)
 
 void helper_fptan(void)
 {
-CPU86_LDouble fptemp;
+double fptemp = CPU86_LDouble_to_double(ST0);
 
-fptemp = ST0;
 if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
 env->fpus |= 0x400;
 } else {
-ST0 = tan(fptemp);
+fptemp = tan(fptemp);
+ST0 = double_to_CPU86_LDouble(fptemp);
 fpush();
-ST0 = 1.0;
+ST0 = double_to_CPU86_LDouble(1.0);
 env->fpus &= (~0x400);  /* C2 <-- 0 */
 /* the above code is for  |arg| < 2**52 only */
 }
@@ -4017,11 +4020,11 @@ void helper_fptan(void)
 
 void helper_fpatan(void)
 {
-CPU86_LDouble fptemp, fpsrcop;
+double fptemp, fpsrcop;
 
-fpsrcop = ST1;
-fptemp = ST0;
-ST1 = atan2(fpsrcop,fptemp);
+fpsrcop = CPU86_LDouble_to_double(ST1);
+fptemp = CPU86_LDouble_to_double(ST0);
+ST1 = double_to_CPU86_LDouble(atan2(fpsrcop, fptemp));
 fpop();
 }
 
@@ -4159,12 +4162,12 @@ void helper_fprem(void)
 
 void helper_fyl2xp1(void)
 {
-CPU86_LDouble fptemp;
+double fptemp = CPU86_LDouble_to_double(ST0);
 
-fptemp = ST0;
 if ((fptemp+1.0)>0.0) {
 fptemp = log(fptemp+1.0) / log(2.0); /* log2(ST+1.0) */
-ST1 *= fptemp;
+fptemp *= CPU86_LDouble_to_double(ST1);
+ST1 = double_to_CPU86_LDouble(fptemp);
 fpop();
 } else {
 env->fpus &= (~0x4700);
@@ -4183,15 +4186,14 @@ void helper_fsqrt(void)
 
 void helper_fsincos(void)
 {
-CPU86_LDouble fptemp;
+double fptemp = CPU86_LDouble_to_double(ST0);
 
-fptemp = ST0;
 if ((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
 env->fpus |= 0x400;
 } else {
-ST0 = sin(fptemp);
+ST0 = double_to_CPU86_LDouble(sin(fptemp));
 fpush();
-ST0 = cos(fptemp);
+ST0 = double_to_CPU86_LDouble(cos(fptemp));
 env->fpus &= (~0x400);  /* C2 <-- 0 */
 /* the above code is for  |arg| < 2**63 only */
 }
@@ -4214,13 +4216,12 @@ void helper_fscale(void)
 
 void helper_fsin(void)
 {
-CPU86_LDouble fptemp;
+double fptemp = CPU86_LDouble_to_double(ST0);
 
-fptemp = ST0;
 if ((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
 env->fpus |= 0x400;
 } else {
-ST0 = sin(fptemp);
+ST0 = double_to_CPU86_LDouble(sin(fptemp));
 env->fpus &= (~0x400);  /* C2 <-- 0 */
 /* the above code is for  |arg| < 2**53 only */
 }
@@ -4228,13 +4229,12 @@ void helper_fsin(void)
 
 void helper_fcos(void)
 {
-CPU86_LDouble fptemp;
+double fptemp = CPU86_LDouble_to_double(ST0);
 
-fptemp = ST0;
 if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
 env->fpus |= 0x400;
 } else {
-ST0 = cos(fptemp);
+ST0 = double_to_CPU86_LDouble(cos(fptemp));
 env->fpus &= (~0x400);  /* C2 <-- 0 */
 /* the above code is for  |arg5 < 2**63 only */
 }
-- 
1.7.2.3




[Qemu-devel] [PATCH 20/20] target-i386: switch to softfloat

2011-04-18 Thread Aurelien Jarno
This increase the correctness (precision, NaN values, corner cases) on
non-x86 machines, and add the possibility to handle the exception
correctly.

Signed-off-by: Aurelien Jarno 
---
 configure |3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/configure b/configure
index da2da04..6e445b4 100755
--- a/configure
+++ b/configure
@@ -3276,9 +3276,6 @@ if test ! -z "$gdb_xml_files" ; then
 fi
 
 case "$target_arch2" in
-  i386|x86_64)
-echo "CONFIG_NOSOFTFLOAT=y" >> $config_target_mak
-;;
   *)
 echo "CONFIG_SOFTFLOAT=y" >> $config_target_mak
 ;;
-- 
1.7.2.3




[Qemu-devel] [PATCH 18/20] target-i386: fix helper_fprem() and helper_fprem1() wrt softfloat

2011-04-18 Thread Aurelien Jarno
Signed-off-by: Aurelien Jarno 
---
 target-i386/op_helper.c |   48 +++---
 1 files changed, 28 insertions(+), 20 deletions(-)

diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index 4671a96..0c4f0da 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -4053,21 +4053,24 @@ void helper_fxtract(void)
 
 void helper_fprem1(void)
 {
-CPU86_LDouble dblq, fpsrcop, fptemp;
+double st0, st1, dblq, fpsrcop, fptemp;
 CPU86_LDoubleU fpsrcop1, fptemp1;
 int expdif;
 signed long long int q;
 
-if (isinf(ST0) || isnan(ST0) || isnan(ST1) || (ST1 == 0.0)) {
-ST0 = 0.0 / 0.0; /* NaN */
+st0 = CPU86_LDouble_to_double(ST0);
+st1 = CPU86_LDouble_to_double(ST1);
+
+if (isinf(st0) || isnan(st0) || isnan(st1) || (st1 == 0.0)) {
+ST0 = double_to_CPU86_LDouble(0.0 / 0.0); /* NaN */
 env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <--  */
 return;
 }
 
-fpsrcop = ST0;
-fptemp = ST1;
-fpsrcop1.d = fpsrcop;
-fptemp1.d = fptemp;
+fpsrcop = st0;
+fptemp = st1;
+fpsrcop1.d = ST0;
+fptemp1.d = ST1;
 expdif = EXPD(fpsrcop1) - EXPD(fptemp1);
 
 if (expdif < 0) {
@@ -4081,7 +4084,7 @@ void helper_fprem1(void)
 dblq = fpsrcop / fptemp;
 /* round dblq towards nearest integer */
 dblq = rint(dblq);
-ST0 = fpsrcop - fptemp * dblq;
+st0 = fpsrcop - fptemp * dblq;
 
 /* convert dblq to q by truncating towards zero */
 if (dblq < 0.0)
@@ -4097,31 +4100,35 @@ void helper_fprem1(void)
 } else {
 env->fpus |= 0x400;  /* C2 <-- 1 */
 fptemp = pow(2.0, expdif - 50);
-fpsrcop = (ST0 / ST1) / fptemp;
+fpsrcop = (st0 / st1) / fptemp;
 /* fpsrcop = integer obtained by chopping */
 fpsrcop = (fpsrcop < 0.0) ?
   -(floor(fabs(fpsrcop))) : floor(fpsrcop);
-ST0 -= (ST1 * fpsrcop * fptemp);
+st0 -= (st1 * fpsrcop * fptemp);
 }
+ST0 = double_to_CPU86_LDouble(st0);
 }
 
 void helper_fprem(void)
 {
-CPU86_LDouble dblq, fpsrcop, fptemp;
+double st0, st1, dblq, fpsrcop, fptemp;
 CPU86_LDoubleU fpsrcop1, fptemp1;
 int expdif;
 signed long long int q;
 
-if (isinf(ST0) || isnan(ST0) || isnan(ST1) || (ST1 == 0.0)) {
-   ST0 = 0.0 / 0.0; /* NaN */
+st0 = CPU86_LDouble_to_double(ST0);
+st1 = CPU86_LDouble_to_double(ST1);
+
+if (isinf(st0) || isnan(st0) || isnan(st1) || (st1 == 0.0)) {
+   ST0 = double_to_CPU86_LDouble(0.0 / 0.0); /* NaN */
env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <--  */
return;
 }
 
-fpsrcop = (CPU86_LDouble)ST0;
-fptemp = (CPU86_LDouble)ST1;
-fpsrcop1.d = fpsrcop;
-fptemp1.d = fptemp;
+fpsrcop = st0;
+fptemp = st1;
+fpsrcop1.d = ST0;
+fptemp1.d = ST1;
 expdif = EXPD(fpsrcop1) - EXPD(fptemp1);
 
 if (expdif < 0) {
@@ -4135,7 +4142,7 @@ void helper_fprem(void)
 dblq = fpsrcop/*ST0*/ / fptemp/*ST1*/;
 /* round dblq towards zero */
 dblq = (dblq < 0.0) ? ceil(dblq) : floor(dblq);
-ST0 = fpsrcop/*ST0*/ - fptemp * dblq;
+st0 = fpsrcop/*ST0*/ - fptemp * dblq;
 
 /* convert dblq to q by truncating towards zero */
 if (dblq < 0.0)
@@ -4152,12 +4159,13 @@ void helper_fprem(void)
 int N = 32 + (expdif % 32); /* as per AMD docs */
 env->fpus |= 0x400;  /* C2 <-- 1 */
 fptemp = pow(2.0, (double)(expdif - N));
-fpsrcop = (ST0 / ST1) / fptemp;
+fpsrcop = (st0 / st1) / fptemp;
 /* fpsrcop = integer obtained by chopping */
 fpsrcop = (fpsrcop < 0.0) ?
   -(floor(fabs(fpsrcop))) : floor(fpsrcop);
-ST0 -= (ST1 * fpsrcop * fptemp);
+st0 -= (st1 * fpsrcop * fptemp);
 }
+ST0 = double_to_CPU86_LDouble(st0);
 }
 
 void helper_fyl2xp1(void)
-- 
1.7.2.3




[Qemu-devel] [PATCH 15/20] target-i386: replace approx_rsqrt and approx_rcp by softfloat ops

2011-04-18 Thread Aurelien Jarno
Signed-off-by: Aurelien Jarno 
---
 target-i386/op_helper.c |   10 --
 target-i386/ops_sse.h   |   36 
 2 files changed, 24 insertions(+), 22 deletions(-)

diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index d935488..9628d27 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -4794,16 +4794,6 @@ void helper_boundl(target_ulong a0, int v)
 }
 }
 
-static float approx_rsqrt(float a)
-{
-return 1.0 / sqrt(a);
-}
-
-static float approx_rcp(float a)
-{
-return 1.0 / a;
-}
-
 #if !defined(CONFIG_USER_ONLY)
 
 #define MMUSUFFIX _mmu
diff --git a/target-i386/ops_sse.h b/target-i386/ops_sse.h
index ac0f150..703be99 100644
--- a/target-i386/ops_sse.h
+++ b/target-i386/ops_sse.h
@@ -778,28 +778,38 @@ int64_t helper_cvttsd2sq(XMMReg *s)
 
 void helper_rsqrtps(XMMReg *d, XMMReg *s)
 {
-d->XMM_S(0) = approx_rsqrt(s->XMM_S(0));
-d->XMM_S(1) = approx_rsqrt(s->XMM_S(1));
-d->XMM_S(2) = approx_rsqrt(s->XMM_S(2));
-d->XMM_S(3) = approx_rsqrt(s->XMM_S(3));
+d->XMM_S(0) = float32_div(float32_one,
+  float32_sqrt(s->XMM_S(0), &env->sse_status),
+  &env->sse_status);
+d->XMM_S(1) = float32_div(float32_one,
+  float32_sqrt(s->XMM_S(1), &env->sse_status),
+  &env->sse_status);
+d->XMM_S(2) = float32_div(float32_one,
+  float32_sqrt(s->XMM_S(2), &env->sse_status),
+  &env->sse_status);
+d->XMM_S(3) = float32_div(float32_one,
+  float32_sqrt(s->XMM_S(3), &env->sse_status),
+  &env->sse_status);
 }
 
 void helper_rsqrtss(XMMReg *d, XMMReg *s)
 {
-d->XMM_S(0) = approx_rsqrt(s->XMM_S(0));
+d->XMM_S(0) = float32_div(float32_one,
+  float32_sqrt(s->XMM_S(0), &env->sse_status),
+  &env->sse_status);
 }
 
 void helper_rcpps(XMMReg *d, XMMReg *s)
 {
-d->XMM_S(0) = approx_rcp(s->XMM_S(0));
-d->XMM_S(1) = approx_rcp(s->XMM_S(1));
-d->XMM_S(2) = approx_rcp(s->XMM_S(2));
-d->XMM_S(3) = approx_rcp(s->XMM_S(3));
+d->XMM_S(0) = float32_div(float32_one, s->XMM_S(0), &env->sse_status);
+d->XMM_S(1) = float32_div(float32_one, s->XMM_S(1), &env->sse_status);
+d->XMM_S(2) = float32_div(float32_one, s->XMM_S(2), &env->sse_status);
+d->XMM_S(3) = float32_div(float32_one, s->XMM_S(3), &env->sse_status);
 }
 
 void helper_rcpss(XMMReg *d, XMMReg *s)
 {
-d->XMM_S(0) = approx_rcp(s->XMM_S(0));
+d->XMM_S(0) = float32_div(float32_one, s->XMM_S(0), &env->sse_status);
 }
 
 static inline uint64_t helper_extrq(uint64_t src, int shift, int len)
@@ -1272,14 +1282,16 @@ void helper_pfpnacc(MMXReg *d, MMXReg *s)
 
 void helper_pfrcp(MMXReg *d, MMXReg *s)
 {
-d->MMX_S(0) = approx_rcp(s->MMX_S(0));
+d->MMX_S(0) = float32_div(float32_one, s->MMX_S(0), &env->mmx_status);
 d->MMX_S(1) = d->MMX_S(0);
 }
 
 void helper_pfrsqrt(MMXReg *d, MMXReg *s)
 {
 d->MMX_L(1) = s->MMX_L(0) & 0x7fff;
-d->MMX_S(1) = approx_rsqrt(d->MMX_S(1));
+d->MMX_S(1) = float32_div(float32_one,
+  float32_sqrt(d->MMX_S(1), &env->mmx_status),
+  &env->mmx_status);
 d->MMX_L(1) |= s->MMX_L(0) & 0x8000;
 d->MMX_L(0) = d->MMX_L(1);
 }
-- 
1.7.2.3




[Qemu-devel] [PATCH 06/20] softfloat: add floatx80_compare*() functions

2011-04-18 Thread Aurelien Jarno
Add floatx80_compare() and floatx80_compare_quiet() functions to match
the softfloat-native ones.

Signed-off-by: Aurelien Jarno 
---
 fpu/softfloat.c |   46 ++
 fpu/softfloat.h |2 ++
 2 files changed, 48 insertions(+), 0 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 6ce0b61..4368069 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -6190,6 +6190,52 @@ int float ## s ## _compare_quiet( float ## s a, float ## 
s b STATUS_PARAM )  \
 COMPARE(32, 0xff)
 COMPARE(64, 0x7ff)
 
+INLINE int floatx80_compare_internal( floatx80 a, floatx80 b,
+  int is_quiet STATUS_PARAM )
+{
+flag aSign, bSign;
+
+if (( ( extractFloatx80Exp( a ) == 0x7fff ) &&
+  ( extractFloatx80Frac( a )<<1 ) ) ||
+( ( extractFloatx80Exp( b ) == 0x7fff ) &&
+  ( extractFloatx80Frac( b )<<1 ) )) {
+if (!is_quiet ||
+floatx80_is_signaling_nan( a ) ||
+floatx80_is_signaling_nan( b ) ) {
+float_raise( float_flag_invalid STATUS_VAR);
+}
+return float_relation_unordered;
+}
+aSign = extractFloatx80Sign( a );
+bSign = extractFloatx80Sign( b );
+if ( aSign != bSign ) {
+
+if ( ( ( (uint16_t) ( ( a.high | b.high ) << 1 ) ) == 0) &&
+ ( ( a.low | b.low ) == 0 ) ) {
+/* zero case */
+return float_relation_equal;
+} else {
+return 1 - (2 * aSign);
+}
+} else {
+if (a.low == b.low && a.high == b.high) {
+return float_relation_equal;
+} else {
+return 1 - 2 * (aSign ^ ( lt128( a.high, a.low, b.high, b.low ) ));
+}
+}
+}
+
+int floatx80_compare( floatx80 a, floatx80 b STATUS_PARAM )
+{
+return floatx80_compare_internal(a, b, 0 STATUS_VAR);
+}
+
+int floatx80_compare_quiet( floatx80 a, floatx80 b STATUS_PARAM )
+{
+return floatx80_compare_internal(a, b, 1 STATUS_VAR);
+}
+
 INLINE int float128_compare_internal( float128 a, float128 b,
   int is_quiet STATUS_PARAM )
 {
diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index 52f49da..2055922 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -550,6 +550,8 @@ int floatx80_eq_quiet( floatx80, floatx80 STATUS_PARAM );
 int floatx80_le_quiet( floatx80, floatx80 STATUS_PARAM );
 int floatx80_lt_quiet( floatx80, floatx80 STATUS_PARAM );
 int floatx80_unordered_quiet( floatx80, floatx80 STATUS_PARAM );
+int floatx80_compare( floatx80, floatx80 STATUS_PARAM );
+int floatx80_compare_quiet( floatx80, floatx80 STATUS_PARAM );
 int floatx80_is_quiet_nan( floatx80 );
 int floatx80_is_signaling_nan( floatx80 );
 floatx80 floatx80_maybe_silence_nan( floatx80 );
-- 
1.7.2.3




[Qemu-devel] [PATCH 10/20] target-i386: fix helper_fscale() wrt softfloat

2011-04-18 Thread Aurelien Jarno
Use the scalbn softfloat function to implement helper_fscale(). This
fixes corner cases (e.g. NaN) and makes a few more GNU libc math tests
to pass.

Signed-off-by: Aurelien Jarno 
---
 target-i386/exec.h  |4 
 target-i386/op_helper.c |7 ++-
 2 files changed, 10 insertions(+), 1 deletions(-)

diff --git a/target-i386/exec.h b/target-i386/exec.h
index ae6b947..211cc8c 100644
--- a/target-i386/exec.h
+++ b/target-i386/exec.h
@@ -115,9 +115,11 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_sub floatx80_sub
 #define floatx_abs floatx80_abs
 #define floatx_chs floatx80_chs
+#define floatx_scalbn floatx80_scalbn
 #define floatx_round_to_int floatx80_round_to_int
 #define floatx_compare floatx80_compare
 #define floatx_compare_quiet floatx80_compare_quiet
+#define floatx_is_any_nan floatx80_is_any_nan
 #else
 #define floatx_to_int32 float64_to_int32
 #define floatx_to_int64 float64_to_int64
@@ -134,9 +136,11 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_sub float64_sub
 #define floatx_abs float64_abs
 #define floatx_chs float64_chs
+#define floatx_scalbn float64_scalbn
 #define floatx_round_to_int float64_round_to_int
 #define floatx_compare float64_compare
 #define floatx_compare_quiet float64_compare_quiet
+#define floatx_is_any_nan float64_is_any_nan
 #endif
 
 #define RC_MASK 0xc00
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index a73427f..f614893 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -4174,7 +4174,12 @@ void helper_frndint(void)
 
 void helper_fscale(void)
 {
-ST0 = ldexp (ST0, (int)(ST1));
+if (floatx_is_any_nan(ST1)) {
+ST0 = ST1;
+} else {
+int n = floatx_to_int32_round_to_zero(ST1, &env->fp_status);
+ST0 = floatx_scalbn(ST0, n, &env->fp_status);
+}
 }
 
 void helper_fsin(void)
-- 
1.7.2.3




[Qemu-devel] [PATCH 08/20] softfloat-native: fix float*_scalbn() functions

2011-04-18 Thread Aurelien Jarno
float*_scalbn() should be able to take a status parameter. Fix that.

Signed-off-by: Aurelien Jarno 
---
 fpu/softfloat-native.h |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/fpu/softfloat-native.h b/fpu/softfloat-native.h
index 97fb3c7..f497e64 100644
--- a/fpu/softfloat-native.h
+++ b/fpu/softfloat-native.h
@@ -283,7 +283,7 @@ INLINE float32 float32_is_zero(float32 a)
 return fpclassify(a) == FP_ZERO;
 }
 
-INLINE float32 float32_scalbn(float32 a, int n)
+INLINE float32 float32_scalbn(float32 a, int n STATUS_PARAM)
 {
 return scalbnf(a, n);
 }
@@ -404,7 +404,7 @@ INLINE float64 float64_is_zero(float64 a)
 return fpclassify(a) == FP_ZERO;
 }
 
-INLINE float64 float64_scalbn(float64 a, int n)
+INLINE float64 float64_scalbn(float64 a, int n STATUS_PARAM)
 {
 return scalbn(a, n);
 }
@@ -520,7 +520,7 @@ INLINE floatx80 floatx80_is_zero(floatx80 a)
 return fpclassify(a) == FP_ZERO;
 }
 
-INLINE floatx80 floatx80_scalbn(floatx80 a, int n)
+INLINE floatx80 floatx80_scalbn(floatx80 a, int n STATUS_PARAM)
 {
 return scalbnl(a, n);
 }
-- 
1.7.2.3




[Qemu-devel] [PATCH 04/20] softfloat: add pi constants

2011-04-18 Thread Aurelien Jarno
Add a pi constant for float32, float64, floatx80. It will be used by
target-i386 and later by the trigonometric functions.

Signed-off-by: Aurelien Jarno 
---
 fpu/softfloat.h |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index 90e0c41..52f49da 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -387,6 +387,7 @@ INLINE float32 float32_set_sign(float32 a, int sign)
 #define float32_zero make_float32(0)
 #define float32_one make_float32(0x3f80)
 #define float32_ln2 make_float32(0x3f317218)
+#define float32_pi make_float32(0x40490fdb)
 #define float32_half make_float32(0x3f00)
 #define float32_infinity make_float32(0x7f80)
 
@@ -499,6 +500,7 @@ INLINE float64 float64_set_sign(float64 a, int sign)
 #define float64_zero make_float64(0)
 #define float64_one make_float64(0x3ff0LL)
 #define float64_ln2 make_float64(0x3fe62e42fefa39efLL)
+#define float64_pi make_float32(0x400921fb54442d18LL)
 #define float64_half make_float64(0x3fe0LL)
 #define float64_infinity make_float64(0x7ff0LL)
 
@@ -588,6 +590,7 @@ INLINE int floatx80_is_any_nan(floatx80 a)
 #define floatx80_zero make_floatx80(0x, 0xLL)
 #define floatx80_one make_floatx80(0x3fff, 0x8000LL)
 #define floatx80_ln2 make_floatx80(0x3ffe, 0xb17217f7d1cf79acLL)
+#define floatx80_pi make_floatx80(0x4000, 0xc90fdaa22168c235LL)
 #define floatx80_half make_floatx80(0x3ffe, 0x8000LL)
 #define floatx80_infinity make_floatx80(0x7fff, 0x8000LL)
 
-- 
1.7.2.3




[Qemu-devel] [PATCH 16/20] target-i386: add CPU86_LDouble <-> double conversion functions

2011-04-18 Thread Aurelien Jarno
Add functions to convert CPU86_LDouble to double and vice versa. They
are going to be used to implement logarithmic and trigonometric function
until softfloat implement them.

Signed-off-by: Aurelien Jarno 
---
 target-i386/op_helper.c |   22 ++
 1 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index 9628d27..f69458d 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -3431,6 +3431,28 @@ void helper_verw(target_ulong selector1)
 
 /* x87 FPU helpers */
 
+static inline double CPU86_LDouble_to_double(CPU86_LDouble a)
+{
+union {
+float64 f64;
+double d;
+} u;
+
+u.f64 = floatx_to_float64(a, &env->fp_status);
+return u.d;
+}
+
+static inline CPU86_LDouble double_to_CPU86_LDouble(double a)
+{
+union {
+float64 f64;
+double d;
+} u;
+
+u.d = a;
+return float64_to_floatx(u.f64, &env->fp_status);
+}
+
 static void fpu_set_exception(int mask)
 {
 env->fpus |= mask;
-- 
1.7.2.3




[Qemu-devel] [PATCH 12/20] target-i386: fix helper_fxtract() wrt softfloat

2011-04-18 Thread Aurelien Jarno
With softfloat it's not possible to play with the overflow of an
unsigned value to get the 0 case partially correct. Use a special case
for that. Using a division to generate an infinity is the easiest way
that works for both softfloat and softfloat-native.

Signed-off-by: Aurelien Jarno 
---
 target-i386/op_helper.c |   23 ---
 1 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index 737..9e5ca72 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -4005,15 +4005,24 @@ void helper_fpatan(void)
 void helper_fxtract(void)
 {
 CPU86_LDoubleU temp;
-unsigned int expdif;
 
 temp.d = ST0;
-expdif = EXPD(temp) - EXPBIAS;
-/*DP exponent bias*/
-ST0 = expdif;
-fpush();
-BIASEXPONENT(temp);
-ST0 = temp.d;
+
+if (floatx_is_zero(ST0)) {
+/* Easy way to generate -inf and raising division by 0 exception */
+ST0 = floatx_div(floatx_chs(floatx_one), floatx_zero, &env->fp_status);
+fpush();
+ST0 = temp.d;
+} else {
+int expdif;
+
+expdif = EXPD(temp) - EXPBIAS;
+/*DP exponent bias*/
+ST0 = int32_to_floatx(expdif, &env->fp_status);
+fpush();
+BIASEXPONENT(temp);
+ST0 = temp.d;
+}
 }
 
 void helper_fprem1(void)
-- 
1.7.2.3




[Qemu-devel] [PATCH 07/20] softfloat: fix float*_scalnb() corner cases

2011-04-18 Thread Aurelien Jarno
float*_scalnb() were not taking into account all cases. This patch fixes
some corner cases:
- NaN values in input were not properly propagated and the invalid flag
  not correctly raised. Use propagateFloat*NaN() for that.
- NaN or infinite values in input of floatx80_scalnb() were not correctly
  detected due to a typo.
- The sum of exponent and n could overflow, leading to strange results.
  Additionally having int16 defined to int make that happening for a very
  small range of values. Fix that by saturating n to the maximum exponent
  range, and using an explicit wider type if needed.

Signed-off-by: Aurelien Jarno 
---
 fpu/softfloat.c |   47 ++-
 1 files changed, 42 insertions(+), 5 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 4368069..8f755c3 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -6333,7 +6333,7 @@ MINMAX(64, 0x7ff)
 float32 float32_scalbn( float32 a, int n STATUS_PARAM )
 {
 flag aSign;
-int16 aExp;
+int16_t aExp;
 uint32_t aSig;
 
 a = float32_squash_input_denormal(a STATUS_VAR);
@@ -6342,6 +6342,9 @@ float32 float32_scalbn( float32 a, int n STATUS_PARAM )
 aSign = extractFloat32Sign( a );
 
 if ( aExp == 0xFF ) {
+if ( aSig ) {
+return propagateFloat32NaN( a, a STATUS_VAR );
+}
 return a;
 }
 if ( aExp != 0 )
@@ -6349,6 +6352,12 @@ float32 float32_scalbn( float32 a, int n STATUS_PARAM )
 else if ( aSig == 0 )
 return a;
 
+if (n > 0x80) {
+n = 0x80;
+} else if (n < -0x80) {
+n = -0x80;
+}
+
 aExp += n - 1;
 aSig <<= 7;
 return normalizeRoundAndPackFloat32( aSign, aExp, aSig STATUS_VAR );
@@ -6357,7 +6366,7 @@ float32 float32_scalbn( float32 a, int n STATUS_PARAM )
 float64 float64_scalbn( float64 a, int n STATUS_PARAM )
 {
 flag aSign;
-int16 aExp;
+int16_t aExp;
 uint64_t aSig;
 
 a = float64_squash_input_denormal(a STATUS_VAR);
@@ -6366,6 +6375,9 @@ float64 float64_scalbn( float64 a, int n STATUS_PARAM )
 aSign = extractFloat64Sign( a );
 
 if ( aExp == 0x7FF ) {
+if ( aSig ) {
+return propagateFloat64NaN( a, a STATUS_VAR );
+}
 return a;
 }
 if ( aExp != 0 )
@@ -6373,6 +6385,12 @@ float64 float64_scalbn( float64 a, int n STATUS_PARAM )
 else if ( aSig == 0 )
 return a;
 
+if (n > 0x1000) {
+n = 0x1000;
+} else if (n < -0x1000) {
+n = -0x1000;
+}
+
 aExp += n - 1;
 aSig <<= 10;
 return normalizeRoundAndPackFloat64( aSign, aExp, aSig STATUS_VAR );
@@ -6382,19 +6400,29 @@ float64 float64_scalbn( float64 a, int n STATUS_PARAM )
 floatx80 floatx80_scalbn( floatx80 a, int n STATUS_PARAM )
 {
 flag aSign;
-int16 aExp;
+int32_t aExp;
 uint64_t aSig;
 
 aSig = extractFloatx80Frac( a );
 aExp = extractFloatx80Exp( a );
 aSign = extractFloatx80Sign( a );
 
-if ( aExp == 0x7FF ) {
+if ( aExp == 0x7FFF ) {
+if ( aSig<<1 ) {
+return propagateFloatx80NaN( a, a STATUS_VAR );
+}
 return a;
 }
+
 if (aExp == 0 && aSig == 0)
 return a;
 
+if (n > 0x1) {
+n = 0x1;
+} else if (n < -0x1) {
+n = -0x1;
+}
+
 aExp += n;
 return normalizeRoundAndPackFloatx80( STATUS(floatx80_rounding_precision),
   aSign, aExp, aSig, 0 STATUS_VAR );
@@ -6405,7 +6433,7 @@ floatx80 floatx80_scalbn( floatx80 a, int n STATUS_PARAM )
 float128 float128_scalbn( float128 a, int n STATUS_PARAM )
 {
 flag aSign;
-int32 aExp;
+int32_t aExp;
 uint64_t aSig0, aSig1;
 
 aSig1 = extractFloat128Frac1( a );
@@ -6413,6 +6441,9 @@ float128 float128_scalbn( float128 a, int n STATUS_PARAM )
 aExp = extractFloat128Exp( a );
 aSign = extractFloat128Sign( a );
 if ( aExp == 0x7FFF ) {
+if ( aSig0 | aSig1 ) {
+return propagateFloat128NaN( a, a STATUS_VAR );
+}
 return a;
 }
 if ( aExp != 0 )
@@ -6420,6 +6451,12 @@ float128 float128_scalbn( float128 a, int n STATUS_PARAM 
)
 else if ( aSig0 == 0 && aSig1 == 0 )
 return a;
 
+if (n > 0x1) {
+n = 0x1;
+} else if (n < -0x1) {
+n = -0x1;
+}
+
 aExp += n - 1;
 return normalizeRoundAndPackFloat128( aSign, aExp, aSig0, aSig1
   STATUS_VAR );
-- 
1.7.2.3




[Qemu-devel] [PATCH 09/20] softfloat-native: add float*_is_any_nan() functions

2011-04-18 Thread Aurelien Jarno
Add float*_is_any_nan() functions to match the softfloat API.

Signed-off-by: Aurelien Jarno 
---
 fpu/softfloat-native.c |   26 ++
 fpu/softfloat-native.h |3 +++
 2 files changed, 29 insertions(+), 0 deletions(-)

diff --git a/fpu/softfloat-native.c b/fpu/softfloat-native.c
index 50355a4..8848651 100644
--- a/fpu/softfloat-native.c
+++ b/fpu/softfloat-native.c
@@ -263,6 +263,15 @@ int float32_is_quiet_nan( float32 a1 )
 return ( 0xFF80 < ( a<<1 ) );
 }
 
+int float32_is_any_nan( float32 a1 )
+{
+float32u u;
+uint32_t a;
+u.f = a1;
+a = u.i;
+return (a & ~(1 << 31)) > 0x7f80U;
+}
+
 /*
 | Software IEC/IEEE double-precision conversion routines.
 **/
@@ -422,6 +431,16 @@ int float64_is_quiet_nan( float64 a1 )
 
 }
 
+int float64_is_any_nan( float64 a1 )
+{
+float64u u;
+uint64_t a;
+u.f = a1;
+a = u.i;
+
+return (a & ~(1ULL << 63)) > LIT64 (0x7FF0 );
+}
+
 #ifdef FLOATX80
 
 /*
@@ -511,4 +530,11 @@ int floatx80_is_quiet_nan( floatx80 a1 )
 return ( ( u.i.high & 0x7FFF ) == 0x7FFF ) && (uint64_t) ( u.i.low<<1 );
 }
 
+int floatx80_is_any_nan( floatx80 a1 )
+{
+floatx80u u;
+u.f = a1;
+return ((u.i.high & 0x7FFF) == 0x7FFF) && ( u.i.low<<1 );
+}
+
 #endif
diff --git a/fpu/softfloat-native.h b/fpu/softfloat-native.h
index f497e64..6afb74a 100644
--- a/fpu/softfloat-native.h
+++ b/fpu/softfloat-native.h
@@ -255,6 +255,7 @@ int float32_compare( float32, float32 STATUS_PARAM );
 int float32_compare_quiet( float32, float32 STATUS_PARAM );
 int float32_is_signaling_nan( float32 );
 int float32_is_quiet_nan( float32 );
+int float32_is_any_nan( float32 );
 
 INLINE float32 float32_abs(float32 a)
 {
@@ -375,6 +376,7 @@ INLINE int float64_unordered_quiet( float64 a, float64 b 
STATUS_PARAM)
 int float64_compare( float64, float64 STATUS_PARAM );
 int float64_compare_quiet( float64, float64 STATUS_PARAM );
 int float64_is_signaling_nan( float64 );
+int float64_is_any_nan( float64 );
 int float64_is_quiet_nan( float64 );
 
 INLINE float64 float64_abs(float64 a)
@@ -492,6 +494,7 @@ int floatx80_compare( floatx80, floatx80 STATUS_PARAM );
 int floatx80_compare_quiet( floatx80, floatx80 STATUS_PARAM );
 int floatx80_is_signaling_nan( floatx80 );
 int floatx80_is_quiet_nan( floatx80 );
+int floatx80_is_any_nan( floatx80 );
 
 INLINE floatx80 floatx80_abs(floatx80 a)
 {
-- 
1.7.2.3




[Qemu-devel] [PATCH 05/20] softfloat-native: add a few constant values

2011-04-18 Thread Aurelien Jarno
Signed-off-by: Aurelien Jarno 
---
 fpu/softfloat-native.h |   27 +++
 1 files changed, 27 insertions(+), 0 deletions(-)

diff --git a/fpu/softfloat-native.h b/fpu/softfloat-native.h
index ea7a15e..97fb3c7 100644
--- a/fpu/softfloat-native.h
+++ b/fpu/softfloat-native.h
@@ -172,6 +172,15 @@ float128 int64_to_float128( int64_t STATUS_PARAM);
 #endif
 
 /*
+| Software IEC/IEEE single-precision conversion constants.
+**/
+#define float32_zero (0.0)
+#define float32_one (1.0)
+#define float32_ln2 (0.6931471)
+#define float32_pi (3.1415926)
+#define float32_half (0.5)
+
+/*
 | Software IEC/IEEE single-precision conversion routines.
 **/
 int float32_to_int32( float32  STATUS_PARAM);
@@ -280,6 +289,15 @@ INLINE float32 float32_scalbn(float32 a, int n)
 }
 
 /*
+| Software IEC/IEEE double-precision conversion constants.
+**/
+#define float64_zero (0.0)
+#define float64_one (1.0)
+#define float64_ln2 (0.693147180559945)
+#define float64_pi (3.141592653589793)
+#define float64_half (0.5)
+
+/*
 | Software IEC/IEEE double-precision conversion routines.
 **/
 int float64_to_int32( float64 STATUS_PARAM );
@@ -394,6 +412,15 @@ INLINE float64 float64_scalbn(float64 a, int n)
 #ifdef FLOATX80
 
 /*
+| Software IEC/IEEE extended double-precision conversion constants.
+**/
+#define floatx80_zero (0.0L)
+#define floatx80_one (1.0L)
+#define floatx80_ln2 (0.69314718055994530943L)
+#define floatx80_pi (3.14159265358979323851L)
+#define floatx80_half (0.5L)
+
+/*
 | Software IEC/IEEE extended double-precision conversion routines.
 **/
 int floatx80_to_int32( floatx80 STATUS_PARAM );
-- 
1.7.2.3




[Qemu-devel] [PATCH 01/20] softfloat: fix floatx80 handling of NaN

2011-04-18 Thread Aurelien Jarno
The floatx80 format uses an explicit bit that should be taken into account
when converting to and from commonNaN format.

When converting to commonNaN, the explicit bit should be removed if it is
a 1, and a default NaN should be used if it is 0.

When converting from commonNan, the explicit bit should be added.

Signed-off-by: Aurelien Jarno 
---
 fpu/softfloat-specialize.h |   19 +--
 1 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
index b110187..fb2b5b4 100644
--- a/fpu/softfloat-specialize.h
+++ b/fpu/softfloat-specialize.h
@@ -603,9 +603,15 @@ static commonNaNT floatx80ToCommonNaN( floatx80 a 
STATUS_PARAM)
 commonNaNT z;
 
 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid 
STATUS_VAR);
-z.sign = a.high>>15;
-z.low = 0;
-z.high = a.low;
+if ( a.low >> 63 ) {
+z.sign = a.high >> 15;
+z.low = 0;
+z.high = a.low << 1;
+} else {
+z.sign = floatx80_default_nan_high >> 15;
+z.low = 0;
+z.high = floatx80_default_nan_low << 1;
+}
 return z;
 }
 
@@ -624,10 +630,11 @@ static floatx80 commonNaNToFloatx80( commonNaNT a 
STATUS_PARAM)
 return z;
 }
 
-if (a.high)
-z.low = a.high;
-else
+if (a.high) {
+z.low = LIT64( 0x8000 ) | a.high >> 1;
+} else {
 z.low = floatx80_default_nan_low;
+}
 z.high = ( ( (uint16_t) a.sign )<<15 ) | 0x7FFF;
 return z;
 }
-- 
1.7.2.3




[Qemu-devel] [PATCH 00/20] target-i386 conversion to softfloat

2011-04-18 Thread Aurelien Jarno
The i386 target is the last one still using softfloat-native. Compared 
to softfloat, it is faster but lacks exception handling, float80 
(except on x86 hosts) and float128, as well as correctness (use NaN 
propagation from the host, different corner cases, etc.). It's API has
also diverged from softfloat, meaning it's not easily possible to select
softfloat or softfloat-native at build-time.

This patch series adjust softfloat, softfloat-native, and target-i386,
so that it's possible to build this target with either implementation.
It's only a transient state until softfloat-native is definitely 
removed. This also mean that some code changes in target-i386 are not
the best possible, as writing code that work on both is sometimes 
difficult. This will have to be fixed after the softfloat removal.

For the trigonometic and logarithmic functions, which are not (yet)
available in softfloat (neither in softfloat-native actually), I have
chosen to convert the floatx80 value to double and use the host 
function. This limits the precision to float64, but anyway the current
code was already using the double version of these functions (instead
of the long double version for floatx80 precision).

I have tested these patches by using the GNU libc testsuite, and 
comparing the results before and after. This patch series already 
globally improve the testsuite results, though on some trigonometric 
functions some tests are now failing and some tests are now passing,
due to precision issues. In any case, these precision issues are limited
to the last two bits of the 80-bit value, so it's safe to ignore this
issue for now.

I already have another patch series in preparation, which does the 
actual softfloat removal, clean the generic and target-i386 codes, add 
exception support, and add a softfloat log2() function. However it's
the following step, and I prefer first to get this patch series 
discussed and hopefully accepted before.


Aurelien Jarno (20):
  softfloat: fix floatx80 handling of NaN
  softfloat: fix floatx80_is_infinity()
  softfloat: add floatx80 constants
  softfloat: add pi constants
  softfloat-native: add a few constant values
  softfloat: add floatx80_compare*() functions
  softfloat: fix float*_scalnb() corner cases
  softfloat-native: fix float*_scalbn() functions
  softfloat-native: add float*_is_any_nan() functions
  target-i386: fix helper_fscale() wrt softfloat
  target-i386: fix helper_flbd_ST0() wrt softfloat
  target-i386: fix helper_fxtract() wrt softfloat
  target-i386: fix helper_fdiv() wrt softfloat
  target-i386: fix helper_fsqrt() wrt softfloat
  target-i386: replace approx_rsqrt and approx_rcp by softfloat ops
  target-i386: add CPU86_LDouble <-> double conversion functions
  target-i386: fix logarithmic and trigonometric helpers wrt softfloat
  target-i386: fix helper_fprem() and helper_fprem1() wrt softfloat
  target-i386: fix constants wrt softfloat
  target-i386: switch to softfloat

 configure  |3 -
 fpu/softfloat-native.c |   26 ++
 fpu/softfloat-native.h |   36 +++-
 fpu/softfloat-specialize.h |   19 +++--
 fpu/softfloat.c|   93 +++-
 fpu/softfloat.h|   14 +++-
 target-i386/exec.h |   20 +
 target-i386/op_helper.c|  205 ++-
 target-i386/ops_sse.h  |   36 +---
 9 files changed, 341 insertions(+), 111 deletions(-)

-- 
1.7.2.3




[Qemu-devel] [PATCH 13/20] target-i386: fix helper_fdiv() wrt softfloat

2011-04-18 Thread Aurelien Jarno
Signed-off-by: Aurelien Jarno 
---
 target-i386/exec.h  |4 
 target-i386/op_helper.c |5 +++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/target-i386/exec.h b/target-i386/exec.h
index 211cc8c..b2af894 100644
--- a/target-i386/exec.h
+++ b/target-i386/exec.h
@@ -111,6 +111,7 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_to_float32 floatx80_to_float32
 #define floatx_to_float64 floatx80_to_float64
 #define floatx_add floatx80_add
+#define floatx_div floatx80_div
 #define floatx_mul floatx80_mul
 #define floatx_sub floatx80_sub
 #define floatx_abs floatx80_abs
@@ -120,6 +121,7 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_compare floatx80_compare
 #define floatx_compare_quiet floatx80_compare_quiet
 #define floatx_is_any_nan floatx80_is_any_nan
+#define floatx_is_zero floatx80_is_zero
 #else
 #define floatx_to_int32 float64_to_int32
 #define floatx_to_int64 float64_to_int64
@@ -132,6 +134,7 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_to_float32 float64_to_float32
 #define floatx_to_float64(x, e) (x)
 #define floatx_add float64_add
+#define floatx_div float64_div
 #define floatx_mul float64_mul
 #define floatx_sub float64_sub
 #define floatx_abs float64_abs
@@ -141,6 +144,7 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_compare float64_compare
 #define floatx_compare_quiet float64_compare_quiet
 #define floatx_is_any_nan float64_is_any_nan
+#define floatx_is_zero float64_is_zero
 #endif
 
 #define RC_MASK 0xc00
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index 9e5ca72..d0d639c 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -3440,9 +3440,10 @@ static void fpu_set_exception(int mask)
 
 static inline CPU86_LDouble helper_fdiv(CPU86_LDouble a, CPU86_LDouble b)
 {
-if (b == 0.0)
+if (floatx_is_zero(b)) {
 fpu_set_exception(FPUS_ZE);
-return a / b;
+}
+return floatx_div(a, b, &env->fp_status);
 }
 
 static void fpu_raise_exception(void)
-- 
1.7.2.3




[Qemu-devel] [PATCH 03/20] softfloat: add floatx80 constants

2011-04-18 Thread Aurelien Jarno
Add floatx80 constants similarly to float32 or float64.

Signed-off-by: Aurelien Jarno 
---
 fpu/softfloat.h |7 +++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index 3363128..90e0c41 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -154,6 +154,7 @@ typedef struct {
 uint64_t low;
 uint16_t high;
 } floatx80;
+#define make_floatx80(exp, mant) ((floatx80) { mant, exp })
 #endif
 #ifdef FLOAT128
 typedef struct {
@@ -584,6 +585,12 @@ INLINE int floatx80_is_any_nan(floatx80 a)
 return ((a.high & 0x7fff) == 0x7fff) && (a.low<<1);
 }
 
+#define floatx80_zero make_floatx80(0x, 0xLL)
+#define floatx80_one make_floatx80(0x3fff, 0x8000LL)
+#define floatx80_ln2 make_floatx80(0x3ffe, 0xb17217f7d1cf79acLL)
+#define floatx80_half make_floatx80(0x3ffe, 0x8000LL)
+#define floatx80_infinity make_floatx80(0x7fff, 0x8000LL)
+
 /*
 | The pattern for a default generated extended double-precision NaN.  The
 | `high' and `low' values hold the most- and least-significant bits,
-- 
1.7.2.3




[Qemu-devel] [PATCH 11/20] target-i386: fix helper_flbd_ST0() wrt softfloat

2011-04-18 Thread Aurelien Jarno
Signed-off-by: Aurelien Jarno 
---
 target-i386/op_helper.c |7 ---
 1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index f614893..737 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -3920,9 +3920,10 @@ void helper_fbld_ST0(target_ulong ptr)
 v = ldub(ptr + i);
 val = (val * 100) + ((v >> 4) * 10) + (v & 0xf);
 }
-tmp = val;
-if (ldub(ptr + 9) & 0x80)
-tmp = -tmp;
+if (ldub(ptr + 9) & 0x80) {
+val = -val;
+}
+tmp = int64_to_floatx(val, &env->fp_status);
 fpush();
 ST0 = tmp;
 }
-- 
1.7.2.3




[Qemu-devel] [PATCH 02/20] softfloat: fix floatx80_is_infinity()

2011-04-18 Thread Aurelien Jarno
With floatx80, the explicit bit is set for infinity.

Signed-off-by: Aurelien Jarno 
---
 fpu/softfloat.h |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index 340f0a9..3363128 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -566,7 +566,7 @@ INLINE floatx80 floatx80_chs(floatx80 a)
 
 INLINE int floatx80_is_infinity(floatx80 a)
 {
-return (a.high & 0x7fff) == 0x7fff && a.low == 0;
+return (a.high & 0x7fff) == 0x7fff && a.low == 0x8000LL;
 }
 
 INLINE int floatx80_is_neg(floatx80 a)
-- 
1.7.2.3




Re: [Qemu-devel] [PATCH v2 0/3] pc-bios: Use iPXE ROMs

2011-04-18 Thread Stefan Weil

Am 18.04.2011 19:34, schrieb Anthony Liguori:

On 04/18/2011 12:25 PM, Alex Williamson wrote:

On Mon, 2011-04-11 at 13:57 -0600, Alex Williamson wrote:

On Mon, 2011-04-11 at 14:48 -0500, Anthony Liguori wrote:

On 04/11/2011 02:35 PM, Alex Williamson wrote:

This series replaces our current gPXE based PXE ROMs with iPXE
versions from the iPXE project (http://ipxe.org). This version
adds ipxe to our submodules so it can be easily included in
releases. I'm still including a script for updating these,
perhaps someone better with Makefiles can eventually adopt this
to a build target.

This email series is mainly for reference, there's too much
renaming and replacing binary files to send out to the mailing
list. I'll strip out the binaries here so the rest can be
reviewed. For the real code, please pull:

git://github.com/awilliam/qemu.git (ipxe branch)

Thanks to Anthony for already setting up an ipxe mirror.
Thanks,


Looks good to me. How different is this from what we've been shipping?
Have you tested PXE boot from the builtin TFTP server and from an
external one (like dnsmasq)?


We were shipping v0.9.9, which was tagged 10/2009. There's been a gpxe
v1.0.0 release since then, plus the split between ipxe and gpxe. I
think Michael is hoping to have a release soon, but the code feels
pretty stable to me as is.

I've tested external booting from dhcp/tftp server for all the NICs.
I'll make a pass through testing with the builtin server and report
back. Thanks,


Ping, any reason this isn't going in? Testing passed, I updated the
script to use bash and alphabetized the Makefile per Stefan Weil's
suggestions. These are updated in the above github tree. Let me know.
Thanks,


I actually was just testing the github tree. Unfortunately, it looks
like there's something broken.

You renamed all of the pxe roms to end with .bin but Makefile still
refers to everything as .rom.

This makes make install break along with building from a separate build
directory.

Regards,

Anthony Liguori


Acked-by: Stefan Weil 

The patch renames .bin to .rom, so the Makefile should be ok.

Regards,

Stefan Weil




Re: [Qemu-devel] [PATCH] target-ppc: use softfloat min/max functions

2011-04-18 Thread Peter Maydell
On 18 April 2011 20:23, Aurelien Jarno  wrote:
> diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
> index 9aa108e..9058d78 100644
> --- a/target-ppc/op_helper.c
> +++ b/target-ppc/op_helper.c
> @@ -2369,22 +2369,16 @@ VMINMAX(uw, u32)
>  #undef VMINMAX_DO
>  #undef VMINMAX
>
> -#define VMINMAXFP(suffix, rT, rF)                                       \
> -    void helper_v##suffix (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)    \
> +#define VMINMAXFP(suffix)                                               \
> +    void helper_v##suffix##fp (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)\
>     {                                                                   \
>         int i;                                                          \
>         for (i = 0; i < ARRAY_SIZE(r->f); i++) {                        \
> -            HANDLE_NAN2(r->f[i], a->f[i], b->f[i]) {                    \
> -                if (float32_lt_quiet(a->f[i], b->f[i], &env->vec_status)) { \
> -                    r->f[i] = rT->f[i];                                 \
> -                } else {                                                \
> -                    r->f[i] = rF->f[i];                                 \
> -                }                                                       \
> -            }                                                           \
> +            r->f[i] = float32_##suffix(a->f[i], b->f[i], &env->vec_status); \
>         }                                                               \
>     }
> -VMINMAXFP(minfp, a, b)
> -VMINMAXFP(maxfp, b, a)
> +VMINMAXFP(min)
> +VMINMAXFP(max)
>  #undef VMINMAXFP
>
>  void helper_vmladduhm (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t 
> *c)

I think you should be able to remove the HANDLE_NAN2 line from the
VARITHFP macro (used for vaddfp, vsubfp) and then you can just say
 VARITHFP(minfp, float32_min)
 VARITHFP(maxfp, float32_max)
rather than needing a separate macro for them, right?

-- PMM


[Qemu-devel] [PATCH] target-ppc: use softfloat min/max functions

2011-04-18 Thread Aurelien Jarno
Use the new softfloat float32_min() and float32_max() to implement the
vminfp and vmaxfp instructions.

Cc: Alexander Graf 
Signed-off-by: Aurelien Jarno 
---
 target-ppc/op_helper.c |   16 +---
 1 files changed, 5 insertions(+), 11 deletions(-)

diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
index 9aa108e..9058d78 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/op_helper.c
@@ -2369,22 +2369,16 @@ VMINMAX(uw, u32)
 #undef VMINMAX_DO
 #undef VMINMAX
 
-#define VMINMAXFP(suffix, rT, rF)   \
-void helper_v##suffix (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)\
+#define VMINMAXFP(suffix)   \
+void helper_v##suffix##fp (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)\
 {   \
 int i;  \
 for (i = 0; i < ARRAY_SIZE(r->f); i++) {\
-HANDLE_NAN2(r->f[i], a->f[i], b->f[i]) {\
-if (float32_lt_quiet(a->f[i], b->f[i], &env->vec_status)) { \
-r->f[i] = rT->f[i]; \
-} else {\
-r->f[i] = rF->f[i]; \
-}   \
-}   \
+r->f[i] = float32_##suffix(a->f[i], b->f[i], &env->vec_status); \
 }   \
 }
-VMINMAXFP(minfp, a, b)
-VMINMAXFP(maxfp, b, a)
+VMINMAXFP(min)
+VMINMAXFP(max)
 #undef VMINMAXFP
 
 void helper_vmladduhm (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c)
-- 
1.7.2.3




Re: [Qemu-devel] [PATCH 2/4] [arm] move helpers.h to helper.h

2011-04-18 Thread Aurelien Jarno
On Wed, Apr 13, 2011 at 06:38:24PM +0200, Lluís wrote:
> This provides a consistent naming scheme across all targets.
> 
> Signed-off-by: Lluís Vilanova 
> ---
>  target-arm/helper.c|2 
>  target-arm/helper.h|  475 
> 
>  target-arm/helpers.h   |  475 
> 
>  target-arm/iwmmxt_helper.c |2 
>  target-arm/neon_helper.c   |2 
>  target-arm/op_helper.c |2 
>  target-arm/translate.c |6 -
>  7 files changed, 482 insertions(+), 482 deletions(-)
>  create mode 100644 target-arm/helper.h
>  delete mode 100644 target-arm/helpers.h

Thanks, applied.

> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index d2e0bf4..2adf3ca 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -5,7 +5,7 @@
>  #include "cpu.h"
>  #include "exec-all.h"
>  #include "gdbstub.h"
> -#include "helpers.h"
> +#include "helper.h"
>  #include "qemu-common.h"
>  #include "host-utils.h"
>  #if !defined(CONFIG_USER_ONLY)
> diff --git a/target-arm/helper.h b/target-arm/helper.h
> new file mode 100644
> index 000..ae701e8
> --- /dev/null
> +++ b/target-arm/helper.h
> @@ -0,0 +1,475 @@
> +#include "def-helper.h"
> +
> +DEF_HELPER_1(clz, i32, i32)
> +DEF_HELPER_1(sxtb16, i32, i32)
> +DEF_HELPER_1(uxtb16, i32, i32)
> +
> +DEF_HELPER_2(add_setq, i32, i32, i32)
> +DEF_HELPER_2(add_saturate, i32, i32, i32)
> +DEF_HELPER_2(sub_saturate, i32, i32, i32)
> +DEF_HELPER_2(add_usaturate, i32, i32, i32)
> +DEF_HELPER_2(sub_usaturate, i32, i32, i32)
> +DEF_HELPER_1(double_saturate, i32, s32)
> +DEF_HELPER_2(sdiv, s32, s32, s32)
> +DEF_HELPER_2(udiv, i32, i32, i32)
> +DEF_HELPER_1(rbit, i32, i32)
> +DEF_HELPER_1(abs, i32, i32)
> +
> +#define PAS_OP(pfx)  \
> +DEF_HELPER_3(pfx ## add8, i32, i32, i32, ptr) \
> +DEF_HELPER_3(pfx ## sub8, i32, i32, i32, ptr) \
> +DEF_HELPER_3(pfx ## sub16, i32, i32, i32, ptr) \
> +DEF_HELPER_3(pfx ## add16, i32, i32, i32, ptr) \
> +DEF_HELPER_3(pfx ## addsubx, i32, i32, i32, ptr) \
> +DEF_HELPER_3(pfx ## subaddx, i32, i32, i32, ptr)
> +
> +PAS_OP(s)
> +PAS_OP(u)
> +#undef PAS_OP
> +
> +#define PAS_OP(pfx)  \
> +DEF_HELPER_2(pfx ## add8, i32, i32, i32) \
> +DEF_HELPER_2(pfx ## sub8, i32, i32, i32) \
> +DEF_HELPER_2(pfx ## sub16, i32, i32, i32) \
> +DEF_HELPER_2(pfx ## add16, i32, i32, i32) \
> +DEF_HELPER_2(pfx ## addsubx, i32, i32, i32) \
> +DEF_HELPER_2(pfx ## subaddx, i32, i32, i32)
> +PAS_OP(q)
> +PAS_OP(sh)
> +PAS_OP(uq)
> +PAS_OP(uh)
> +#undef PAS_OP
> +
> +DEF_HELPER_2(ssat, i32, i32, i32)
> +DEF_HELPER_2(usat, i32, i32, i32)
> +DEF_HELPER_2(ssat16, i32, i32, i32)
> +DEF_HELPER_2(usat16, i32, i32, i32)
> +
> +DEF_HELPER_2(usad8, i32, i32, i32)
> +
> +DEF_HELPER_1(logicq_cc, i32, i64)
> +
> +DEF_HELPER_3(sel_flags, i32, i32, i32, i32)
> +DEF_HELPER_1(exception, void, i32)
> +DEF_HELPER_0(wfi, void)
> +
> +DEF_HELPER_2(cpsr_write, void, i32, i32)
> +DEF_HELPER_0(cpsr_read, i32)
> +
> +DEF_HELPER_3(v7m_msr, void, env, i32, i32)
> +DEF_HELPER_2(v7m_mrs, i32, env, i32)
> +
> +DEF_HELPER_3(set_cp15, void, env, i32, i32)
> +DEF_HELPER_2(get_cp15, i32, env, i32)
> +
> +DEF_HELPER_3(set_cp, void, env, i32, i32)
> +DEF_HELPER_2(get_cp, i32, env, i32)
> +
> +DEF_HELPER_2(get_r13_banked, i32, env, i32)
> +DEF_HELPER_3(set_r13_banked, void, env, i32, i32)
> +
> +DEF_HELPER_1(get_user_reg, i32, i32)
> +DEF_HELPER_2(set_user_reg, void, i32, i32)
> +
> +DEF_HELPER_1(vfp_get_fpscr, i32, env)
> +DEF_HELPER_2(vfp_set_fpscr, void, env, i32)
> +
> +DEF_HELPER_3(vfp_adds, f32, f32, f32, env)
> +DEF_HELPER_3(vfp_addd, f64, f64, f64, env)
> +DEF_HELPER_3(vfp_subs, f32, f32, f32, env)
> +DEF_HELPER_3(vfp_subd, f64, f64, f64, env)
> +DEF_HELPER_3(vfp_muls, f32, f32, f32, env)
> +DEF_HELPER_3(vfp_muld, f64, f64, f64, env)
> +DEF_HELPER_3(vfp_divs, f32, f32, f32, env)
> +DEF_HELPER_3(vfp_divd, f64, f64, f64, env)
> +DEF_HELPER_1(vfp_negs, f32, f32)
> +DEF_HELPER_1(vfp_negd, f64, f64)
> +DEF_HELPER_1(vfp_abss, f32, f32)
> +DEF_HELPER_1(vfp_absd, f64, f64)
> +DEF_HELPER_2(vfp_sqrts, f32, f32, env)
> +DEF_HELPER_2(vfp_sqrtd, f64, f64, env)
> +DEF_HELPER_3(vfp_cmps, void, f32, f32, env)
> +DEF_HELPER_3(vfp_cmpd, void, f64, f64, env)
> +DEF_HELPER_3(vfp_cmpes, void, f32, f32, env)
> +DEF_HELPER_3(vfp_cmped, void, f64, f64, env)
> +
> +DEF_HELPER_2(vfp_fcvtds, f64, f32, env)
> +DEF_HELPER_2(vfp_fcvtsd, f32, f64, env)
> +
> +DEF_HELPER_2(vfp_uitos, f32, i32, env)
> +DEF_HELPER_2(vfp_uitod, f64, i32, env)
> +DEF_HELPER_2(vfp_sitos, f32, i32, env)
> +DEF_HELPER_2(vfp_sitod, f64, i32, env)
> +
> +DEF_HELPER_2(vfp_touis, i32, f32, env)
> +DEF_HELPER_2(vfp_touid, i32, f64, env)
> +DEF_HELPER_2(vfp_touizs, i32, f32, env)
> +DEF_HELPER_2(vfp_touizd, i32, f64, env)
> +DEF_HELPER_2(vfp_tosis, i32, f32, env)
> +DEF_HELPER_2(vfp_tosid, i32, f64, env)
> +DEF_HELPER_2(vfp_tosizs, i32, f32, env)
> +DEF_HELPER_2(vfp_tosizd, i32, f64, env)
> +
> +DEF_HELPER_3(vfp_toshs, i32, 

Re: [Qemu-devel] [PATCH] libcacard: fix opposite usage of isspace

2011-04-18 Thread Aurelien Jarno
On Wed, Apr 13, 2011 at 02:42:00PM +0300, Alon Levy wrote:
> Signed-off-by: Alon Levy 
> ---
>  libcacard/vcard_emul_nss.c |4 ++--
>  1 files changed, 2 insertions(+), 2 deletions(-)

Thanks, applied.

> diff --git a/libcacard/vcard_emul_nss.c b/libcacard/vcard_emul_nss.c
> index 71f2ba3..baada52 100644
> --- a/libcacard/vcard_emul_nss.c
> +++ b/libcacard/vcard_emul_nss.c
> @@ -955,7 +955,7 @@ count_tokens(const char *str, char token, char token_end)
>  static const char *
>  strip(const char *str)
>  {
> -for (; *str && !isspace(*str); str++) {
> +for (; *str && isspace(*str); str++) {
>  }
>  return str;
>  }
> @@ -963,7 +963,7 @@ strip(const char *str)
>  static const char *
>  find_blank(const char *str)
>  {
> -for (; *str && isspace(*str); str++) {
> +for (; *str && !isspace(*str); str++) {
>  }
>  return str;
>  }
> -- 
> 1.7.4.2
> 
> 
> 

-- 
Aurelien Jarno  GPG: 1024D/F1BCDB73
aurel...@aurel32.net http://www.aurel32.net



Re: [Qemu-devel] [PATCH 10/17] s390x: keep hint on virtio managing size

2011-04-18 Thread Aurelien Jarno
On Fri, Apr 15, 2011 at 05:32:51PM +0200, Alexander Graf wrote:
> The s390x virtio bus keeps management information on virtio after the top
> of the guest's RAM. We need to be able to tell the guest the size of its
> RAM (without virtio stuff), but also be able to trap when the guest accesses
> RAM outside of its scope (including virtio stuff).
> 
> So we need a variable telling us the size of the virtio stuff, so we can
> calculate the highest available RAM address from that.
> 
> While at it, also increase the maximum number of virtio pages, so we play
> along well with more recent kernels that spawn a ridiculous number of virtio
> console adapters.
> 
> Signed-off-by: Alexander Graf 
> ---
>  hw/s390-virtio-bus.c |3 +++
>  hw/s390-virtio-bus.h |2 +-
>  target-s390x/cpu.h   |3 +++
>  3 files changed, 7 insertions(+), 1 deletions(-)
> 
> diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
> index bb49e39..a90963b 100644
> --- a/hw/s390-virtio-bus.c
> +++ b/hw/s390-virtio-bus.c
> @@ -60,6 +60,9 @@ static const VirtIOBindings virtio_s390_bindings;
>  
>  static ram_addr_t s390_virtio_device_num_vq(VirtIOS390Device *dev);
>  
> +/* length of VirtIO device pages */
> +target_phys_addr_t virtio_size = S390_DEVICE_PAGES * TARGET_PAGE_SIZE;
> +

If this variable is never written, can it be declared const?

>  VirtIOS390Bus *s390_virtio_bus_init(ram_addr_t *ram_size)
>  {
>  VirtIOS390Bus *bus;
> diff --git a/hw/s390-virtio-bus.h b/hw/s390-virtio-bus.h
> index edf6d04..0c412d0 100644
> --- a/hw/s390-virtio-bus.h
> +++ b/hw/s390-virtio-bus.h
> @@ -33,7 +33,7 @@
>  #define VIRTIO_VQCONFIG_LEN  24
>  
>  #define VIRTIO_RING_LEN  (TARGET_PAGE_SIZE * 3)
> -#define S390_DEVICE_PAGES256
> +#define S390_DEVICE_PAGES512
>  
>  typedef struct VirtIOS390Device {
>  DeviceState qdev;
> diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
> index a84b3ee..6ba303d 100644
> --- a/target-s390x/cpu.h
> +++ b/target-s390x/cpu.h
> @@ -293,6 +293,9 @@ void kvm_s390_interrupt_internal(CPUState *env, int type, 
> uint32_t parm,
>   uint64_t parm64, int vm);
>  CPUState *s390_cpu_addr2state(uint16_t cpu_addr);
>  
> +/* from s390-virtio-bus */
> +extern target_phys_addr_t virtio_size;
> +
>  #ifndef KVM_S390_SIGP_STOP
>  #define KVM_S390_SIGP_STOP  0
>  #define KVM_S390_PROGRAM_INT0


-- 
Aurelien Jarno  GPG: 1024D/F1BCDB73
aurel...@aurel32.net http://www.aurel32.net



Re: [Qemu-devel] [PATCH 09/17] s390x: virtio machine storage keys

2011-04-18 Thread Aurelien Jarno
On Fri, Apr 15, 2011 at 05:32:50PM +0200, Alexander Graf wrote:
> For emulation (and migration) we need to know about the guest's storage keys.
> These are separate from actual RAM contents, so we need to allocate them in
> parallel to RAM.
> 
> While touching the file, this patch also adjusts the hypercall function
> to a new syntax that aligns better with tcg emulated code.
> 
> Signed-off-by: Alexander Graf 
> ---
>  hw/s390-virtio.c |   21 +
>  1 files changed, 9 insertions(+), 12 deletions(-)

Thanks, applied.

> diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
> index 48fb0d0..698ff6f 100644
> --- a/hw/s390-virtio.c
> +++ b/hw/s390-virtio.c
> @@ -82,13 +82,12 @@ CPUState *s390_cpu_addr2state(uint16_t cpu_addr)
>  return ipi_states[cpu_addr];
>  }
>  
> -int s390_virtio_hypercall(CPUState *env, uint64_t mem_, uint64_t hypercall)
> +int s390_virtio_hypercall(CPUState *env, uint64_t mem, uint64_t hypercall)
>  {
>  int r = 0, i;
> -target_ulong mem = env->regs[2];
>  
> -dprintf("KVM hypercall: %ld\n", env->regs[1]);
> -switch (env->regs[1]) {
> +dprintf("KVM hypercall: %ld\n", hypercall);
> +switch (hypercall) {
>  case KVM_S390_VIRTIO_NOTIFY:
>  if (mem > ram_size) {
>  VirtIOS390Device *dev = s390_virtio_bus_find_vring(s390_bus,
> @@ -128,8 +127,7 @@ int s390_virtio_hypercall(CPUState *env, uint64_t mem_, 
> uint64_t hypercall)
>  break;
>  }
>  
> -env->regs[2] = r;
> -return 0;
> +return r;
>  }
>  
>  /* PC hardware initialisation */
> @@ -145,14 +143,9 @@ static void s390_init(ram_addr_t ram_size,
>  ram_addr_t kernel_size = 0;
>  ram_addr_t initrd_offset;
>  ram_addr_t initrd_size = 0;
> +uint8_t *storage_keys;
>  int i;
>  
> -/* XXX we only work on KVM for now */
> -
> -if (!kvm_enabled()) {
> -fprintf(stderr, "The S390 target only works with KVM enabled\n");
> -exit(1);
> -}
>  
>  /* get a BUS */
>  s390_bus = s390_virtio_bus_init(&ram_size);
> @@ -161,6 +154,9 @@ static void s390_init(ram_addr_t ram_size,
>  ram_addr = qemu_ram_alloc(NULL, "s390.ram", ram_size);
>  cpu_register_physical_memory(0, ram_size, ram_addr);
>  
> +/* allocate storage keys */
> +storage_keys = qemu_mallocz(ram_size / TARGET_PAGE_SIZE);
> +
>  /* init CPUs */
>  if (cpu_model == NULL) {
>  cpu_model = "host";
> @@ -178,6 +174,7 @@ static void s390_init(ram_addr_t ram_size,
>  ipi_states[i] = tmp_env;
>  tmp_env->halted = 1;
>  tmp_env->exception_index = EXCP_HLT;
> +tmp_env->storage_keys = storage_keys;
>  }
>  
>  env->halted = 0;
> -- 
> 1.6.0.2
> 
> 
> 

-- 
Aurelien Jarno  GPG: 1024D/F1BCDB73
aurel...@aurel32.net http://www.aurel32.net



Re: [Qemu-devel] [PATCH 08/17] s390x: Dispatch interrupts to KVM or the real CPU

2011-04-18 Thread Aurelien Jarno
On Fri, Apr 15, 2011 at 05:32:49PM +0200, Alexander Graf wrote:
> The KVM interrupt injection path is non-generic for now. So we need to push
> knowledge of how to inject a device interrupt using KVM into the actual device
> code.
> 
> Signed-off-by: Alexander Graf 
> ---
>  hw/s390-virtio-bus.c |   10 --
>  1 files changed, 8 insertions(+), 2 deletions(-)

Thanks, applied.

> diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
> index 175e5cb..bb49e39 100644
> --- a/hw/s390-virtio-bus.c
> +++ b/hw/s390-virtio-bus.c
> @@ -43,6 +43,8 @@
>  do { } while (0)
>  #endif
>  
> +#define VIRTIO_EXT_CODE   0x2603
> +
>  struct BusInfo s390_virtio_bus_info = {
>  .name   = "s390-virtio",
>  .size   = sizeof(VirtIOS390Bus),
> @@ -305,9 +307,13 @@ static void virtio_s390_notify(void *opaque, uint16_t 
> vector)
>  {
>  VirtIOS390Device *dev = (VirtIOS390Device*)opaque;
>  uint64_t token = s390_virtio_device_vq_token(dev, vector);
> +CPUState *env = s390_cpu_addr2state(0);
>  
> -/* XXX kvm dependency! */
> -kvm_s390_virtio_irq(s390_cpu_addr2state(0), 0, token);
> +if (kvm_enabled()) {
> +kvm_s390_virtio_irq(env, 0, token);
> +} else {
> +cpu_inject_ext(env, VIRTIO_EXT_CODE, 0, token);
> +}
>  }
>  
>  static unsigned virtio_s390_get_features(void *opaque)
> -- 
> 1.6.0.2
> 
> 
> 

-- 
Aurelien Jarno  GPG: 1024D/F1BCDB73
aurel...@aurel32.net http://www.aurel32.net



Re: [Qemu-devel] [PATCH 07/17] s390x: Enable s390x-softmmu target

2011-04-18 Thread Aurelien Jarno
On Fri, Apr 15, 2011 at 05:32:48PM +0200, Alexander Graf wrote:
> This patch adds some code paths for running s390x guest OSs without the
> need for KVM.
> 
> Signed-off-by: Alexander Graf 
> 
> ---
> 
> v3 -> v4:
> 
>   - declare non-working when EXT is masked
>   - remove obsolete cpu_halted
> ---
>  cpu-exec.c|8 
>  target-s390x/exec.h   |   11 ++-
>  target-s390x/helper.c |4 
>  3 files changed, 22 insertions(+), 1 deletions(-)

Thanks for the fixes. This patch hasn't really changed since the last
review, so I have just applied it. This way we can concentrate on the
remaining patches.

> diff --git a/cpu-exec.c b/cpu-exec.c
> index 5d6c9a8..d57afef 100644
> --- a/cpu-exec.c
> +++ b/cpu-exec.c
> @@ -346,6 +346,8 @@ int cpu_exec(CPUState *env1)
>  do_interrupt(env);
>  #elif defined(TARGET_M68K)
>  do_interrupt(0);
> +#elif defined(TARGET_S390X)
> +do_interrupt(env);
>  #endif
>  env->exception_index = -1;
>  #endif
> @@ -560,6 +562,12 @@ int cpu_exec(CPUState *env1)
>  do_interrupt(1);
>  next_tb = 0;
>  }
> +#elif defined(TARGET_S390X) && !defined(CONFIG_USER_ONLY)
> +if ((interrupt_request & CPU_INTERRUPT_HARD) &&
> +(env->psw.mask & PSW_MASK_EXT)) {
> +do_interrupt(env);
> +next_tb = 0;
> +}
>  #endif
> /* Don't use the cached interupt_request value,
>do_interrupt may have updated the EXITTB flag. */
> diff --git a/target-s390x/exec.h b/target-s390x/exec.h
> index f7893f3..7a87fff 100644
> --- a/target-s390x/exec.h
> +++ b/target-s390x/exec.h
> @@ -31,7 +31,16 @@ register struct CPUS390XState *env asm(AREG0);
>  
>  static inline int cpu_has_work(CPUState *env)
>  {
> -return env->interrupt_request & CPU_INTERRUPT_HARD; // guess
> +return ((env->interrupt_request & CPU_INTERRUPT_HARD) &&
> +(env->psw.mask & PSW_MASK_EXT));
> +}
> +
> +static inline void regs_to_env(void)
> +{
> +}
> +
> +static inline void env_to_regs(void)
> +{
>  }
>  
>  static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock* tb)
> diff --git a/target-s390x/helper.c b/target-s390x/helper.c
> index 4a5297b..629dfd9 100644
> --- a/target-s390x/helper.c
> +++ b/target-s390x/helper.c
> @@ -82,3 +82,7 @@ int cpu_s390x_handle_mmu_fault (CPUState *env, target_ulong 
> address, int rw,
>  return 0;
>  }
>  #endif /* CONFIG_USER_ONLY */
> +
> +void do_interrupt (CPUState *env)
> +{
> +}
> -- 
> 1.6.0.2
> 
> 
> 
> 

-- 
Aurelien Jarno  GPG: 1024D/F1BCDB73
aurel...@aurel32.net http://www.aurel32.net



Re: [Qemu-devel] [PATCH 06/17] s390x: Prepare cpu.h for emulation

2011-04-18 Thread Aurelien Jarno
On Fri, Apr 15, 2011 at 05:32:47PM +0200, Alexander Graf wrote:
> We need to add some more logic to the CPU description to leverage emulation
> of an s390x CPU. This patch adds all the required helpers, fields in CPUState
> and constant definitions required for user and system emulation.
> 
> Signed-off-by: Alexander Graf 
> 
> ---
>
> v1 -> v2:
> 
>   - remove FPReg definition
>   - remove EXCP_EXECUTE_SVC in non user-mode
>   - add descriptions to more cc_ops
>   - add comment on time2tod
>   - remove redundant EXECUTE_SVC
>   - describe EXCP_EXT
> 
> v3 -> v4:
> 
>   - add slag cc type
>   - add cc field for bisectability
>   - bisectability
> ---
>  hw/s390-virtio.c |2 +-
>  target-s390x/cpu.h   |  774 
> +++---
>  target-s390x/kvm.c   |   17 +-
>  target-s390x/translate.c |2 +-
>  4 files changed, 740 insertions(+), 55 deletions(-)

Thanks for the fixes. This patch hasn't really changed since the last
review, so I have just applied it. This way we can concentrate on the
remaining patches.

> diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
> index d429f10..48fb0d0 100644
> --- a/hw/s390-virtio.c
> +++ b/hw/s390-virtio.c
> @@ -82,7 +82,7 @@ CPUState *s390_cpu_addr2state(uint16_t cpu_addr)
>  return ipi_states[cpu_addr];
>  }
>  
> -int s390_virtio_hypercall(CPUState *env)
> +int s390_virtio_hypercall(CPUState *env, uint64_t mem_, uint64_t hypercall)
>  {
>  int r = 0, i;
>  target_ulong mem = env->regs[2];
> diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
> index e47c372..a84b3ee 100644
> --- a/target-s390x/cpu.h
> +++ b/target-s390x/cpu.h
> @@ -26,24 +26,35 @@
>  #define CPUState struct CPUS390XState
>  
>  #include "cpu-defs.h"
> +#define TARGET_PAGE_BITS 12
> +
> +#define TARGET_PHYS_ADDR_SPACE_BITS 64
> +#define TARGET_VIRT_ADDR_SPACE_BITS 64
> +
> +#include "cpu-all.h"
>  
>  #include "softfloat.h"
>  
> -#define NB_MMU_MODES 2
> +#define NB_MMU_MODES 3
>  
> -typedef union FPReg {
> -struct {
> -#ifdef WORDS_BIGENDIAN
> -float32 e;
> -int32_t __pad;
> -#else
> -int32_t __pad;
> -float32 e;
> -#endif
> -};
> -float64 d;
> -uint64_t i;
> -} FPReg;
> +#define MMU_MODE0_SUFFIX _primary
> +#define MMU_MODE1_SUFFIX _secondary
> +#define MMU_MODE2_SUFFIX _home
> +
> +#define MMU_USER_IDX 1
> +
> +#define MAX_EXT_QUEUE 16
> +
> +typedef struct PSW {
> +uint64_t mask;
> +uint64_t addr;
> +} PSW;
> +
> +typedef struct ExtQueue {
> +uint32_t code;
> +uint32_t param;
> +uint32_t param64;
> +} ExtQueue;
>  
>  typedef struct CPUS390XState {
>  uint64_t regs[16];   /* GP registers */
> @@ -51,17 +62,42 @@ typedef struct CPUS390XState {
>  uint32_t aregs[16];  /* access registers */
>  
>  uint32_t fpc;/* floating-point control register */
> -FPReg fregs[16]; /* FP registers */
> +CPU_DoubleU fregs[16]; /* FP registers */
>  float_status fpu_status; /* passed to softfloat lib */
>  
> -struct {
> -uint64_t mask;
> -uint64_t addr;
> -} psw;
> +PSW psw;
>  
> -int cc; /* condition code (0-3) */
> +uint32_t cc;
> +uint32_t cc_op;
> +uint64_t cc_src;
> +uint64_t cc_dst;
> +uint64_t cc_vr;
>  
>  uint64_t __excp_addr;
> +uint64_t psa;
> +
> +uint32_t int_pgm_code;
> +uint32_t int_pgm_ilc;
> +
> +uint32_t int_svc_code;
> +uint32_t int_svc_ilc;
> +
> +uint64_t cregs[16]; /* control registers */
> +
> +int pending_int;
> +ExtQueue ext_queue[MAX_EXT_QUEUE];
> +
> +/* reset does memset(0) up to here */
> +
> +int ext_index;
> +int cpu_num;
> +uint8_t *storage_keys;
> +
> +uint64_t tod_offset;
> +uint64_t tod_basetime;
> +QEMUTimer *tod_timer;
> +
> +QEMUTimer *cpu_timer;
>  
>  CPU_COMMON
>  } CPUS390XState;
> @@ -69,24 +105,174 @@ typedef struct CPUS390XState {
>  #if defined(CONFIG_USER_ONLY)
>  static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
>  {
> -if (newsp)
> +if (newsp) {
>  env->regs[15] = newsp;
> +}
>  env->regs[0] = 0;
>  }
>  #endif
>  
> -#define MMU_MODE0_SUFFIX _kernel
> -#define MMU_MODE1_SUFFIX _user
> -#define MMU_USER_IDX 1
> +/* Interrupt Codes */
> +/* Program Interrupts */
> +#define PGM_OPERATION   0x0001
> +#define PGM_PRIVILEGED  0x0002
> +#define PGM_EXECUTE 0x0003
> +#define PGM_PROTECTION  0x0004
> +#define PGM_ADDRESSING  0x0005
> +#define PGM_SPECIFICATION   0x0006
> +#define PGM_DATA0x0007
> +#define PGM_FIXPT_OVERFLOW  0x0008
> +#define PGM_FIXPT_DIVIDE0x0009
> +#define PGM_DEC_OVERFLOW0x000a
> +#define PGM_DEC_DIVIDE  0x000b
> +#define PGM_HFP_EXP_OVERFLOW0x000c
> +#define PGM_HFP_EXP_UNDERFLOW   0x000d
> +#define PGM_HFP_SIGNIFICANCE   

Re: [Qemu-devel] [PATCH 01/17] tcg: extend max tcg opcodes on 32bit

2011-04-18 Thread Aurelien Jarno
On Fri, Apr 15, 2011 at 05:32:42PM +0200, Alexander Graf wrote:
> When running on a 32 bit host, we tend to use more TCG ops than on
> a 64 bit host. Reflect that in the reserved opcode amount constant.
> 
> Signed-off-by: Alexander Graf 
> ---
>  exec-all.h |4 
>  1 files changed, 4 insertions(+), 0 deletions(-)

I really like this solution as it is actually better than incrementing
this value for both 32- and 64-bit hosts. That said, I think it should
only be done for 64-bit guests on 32-bit hosts. 32-bit guests on 32-bit
hosts should not use more ops than 32-bit guests on 64-bit hosts.

I think we should do the same for TCG_MAX_OP_SIZE, as it tends the be 
the same issue, ie emulating 64-bit load/store on a 32-bit hosts use a
lot of host instructions. That said in that case we should probably
rollback to the previous value on 64-bit hosts. You can do it in the
next version of the patch, but it's nothing mandatory for s390x.

> diff --git a/exec-all.h b/exec-all.h
> index 496c001..d23a36d 100644
> --- a/exec-all.h
> +++ b/exec-all.h
> @@ -43,7 +43,11 @@ typedef ram_addr_t tb_page_addr_t;
>  typedef struct TranslationBlock TranslationBlock;
>  
>  /* XXX: make safe guess about sizes */
> +#if HOST_LONG_BITS == 32
> +#define MAX_OP_PER_INSTR 128
> +#else
>  #define MAX_OP_PER_INSTR 96
> +#endif
>  
>  #if HOST_LONG_BITS == 32
>  #define MAX_OPC_PARAM_PER_ARG 2
> -- 
> 1.6.0.2
> 
> 
> 

-- 
Aurelien Jarno  GPG: 1024D/F1BCDB73
aurel...@aurel32.net http://www.aurel32.net



Re: [Qemu-devel] [PATCH 05/17] kvm: add kvm stub for arch specific stuff

2011-04-18 Thread Aurelien Jarno
On Fri, Apr 15, 2011 at 05:32:46PM +0200, Alexander Graf wrote:
> We have a generic stub architecture for kvm calls, but some architectures
> are different from others. So we do want to be able to have stubs for
> architecture specific functionality as well.
> 
> This patch adds kvm stubs for all architectures.
> 
> Signed-off-by: Alexander Graf 
> ---
>  Makefile.target   |2 +-
>  target-alpha/kvm-arch-stub.c  |   26 +
>  target-arm/kvm-arch-stub.c|   26 +
>  target-cris/kvm-arch-stub.c   |   26 +
>  target-i386/kvm-arch-stub.c   |   26 +
>  target-lm32/kvm-arch-stub.c   |   26 +
>  target-m68k/kvm-arch-stub.c   |   26 +
>  target-microblaze/kvm-arch-stub.c |   26 +
>  target-mips/kvm-arch-stub.c   |   26 +
>  target-ppc/kvm-arch-stub.c|   26 +
>  target-s390x/kvm-arch-stub.c  |   38 
> +
>  target-sh4/kvm-arch-stub.c|   26 +
>  target-sparc/kvm-arch-stub.c  |   26 +
>  target-unicore32/kvm-arch-stub.c  |   26 +
>  14 files changed, 351 insertions(+), 1 deletions(-)
>  create mode 100644 target-alpha/kvm-arch-stub.c
>  create mode 100644 target-arm/kvm-arch-stub.c
>  create mode 100644 target-cris/kvm-arch-stub.c
>  create mode 100644 target-i386/kvm-arch-stub.c
>  create mode 100644 target-lm32/kvm-arch-stub.c
>  create mode 100644 target-m68k/kvm-arch-stub.c
>  create mode 100644 target-microblaze/kvm-arch-stub.c
>  create mode 100644 target-mips/kvm-arch-stub.c
>  create mode 100644 target-ppc/kvm-arch-stub.c
>  create mode 100644 target-s390x/kvm-arch-stub.c
>  create mode 100644 target-sh4/kvm-arch-stub.c
>  create mode 100644 target-sparc/kvm-arch-stub.c
>  create mode 100644 target-unicore32/kvm-arch-stub.c

Do we really want to create so much files on architectures we will never
see KVM support? Actually I know very few things about KVM, so it would
be better to have this patch reviewed by someone else. Avi or Anthony
maybe?

> diff --git a/Makefile.target b/Makefile.target
> index d5761b7..69ea140 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -197,7 +197,7 @@ obj-$(CONFIG_VHOST_NET) += vhost.o
>  obj-$(CONFIG_REALLY_VIRTFS) += virtio-9p.o
>  obj-y += rwhandler.o
>  obj-$(CONFIG_KVM) += kvm.o kvm-all.o
> -obj-$(CONFIG_NO_KVM) += kvm-stub.o
> +obj-$(CONFIG_NO_KVM) += kvm-stub.o kvm-arch-stub.o
>  LIBS+=-lz
>  
>  QEMU_CFLAGS += $(VNC_TLS_CFLAGS)
> diff --git a/target-alpha/kvm-arch-stub.c b/target-alpha/kvm-arch-stub.c
> new file mode 100644
> index 000..b338995
> --- /dev/null
> +++ b/target-alpha/kvm-arch-stub.c
> @@ -0,0 +1,26 @@
> +/*
> + * QEMU non-KVM stub implementation
> + *
> + * Copyright (c) 2011 Alexander Graf 
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, see 
> .
> + */
> +
> +#include "qemu-common.h"
> +#include "sysemu.h"
> +#include "hw/hw.h"
> +#include "exec-all.h"
> +#include "gdbstub.h"
> +#include "kvm.h"
> +
> diff --git a/target-arm/kvm-arch-stub.c b/target-arm/kvm-arch-stub.c
> new file mode 100644
> index 000..b338995
> --- /dev/null
> +++ b/target-arm/kvm-arch-stub.c
> @@ -0,0 +1,26 @@
> +/*
> + * QEMU non-KVM stub implementation
> + *
> + * Copyright (c) 2011 Alexander Graf 
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, see 
> .
> + */
> +
> +#include "qemu-common.h"
> +#include "sysemu.h"
> +#include "hw/hw.h"
> +#include "exec-all.h"
> +#include "gdbstub.h"
> +#include

[Qemu-devel] [PATCH 0/2] target-arm: Handle UNDEF cases for Neon load/stores

2011-04-18 Thread Peter Maydell
These two simple patches make qemu correctly UNDEF where required in the
Neon load/store space. We also catch and UNDEF on an UNPREDICTABLE rather
than indexing off the end of the register file.

Tested in the usual way with random instruction sequences.

Peter Maydell (2):
  target-arm: Handle UNDEFs for Neon single element load/stores
  target-arm: Handle UNDEF cases for Neon VLD/VST multiple-structures

 target-arm/translate.c |   49 
 1 files changed, 49 insertions(+), 0 deletions(-)




[Qemu-devel] [PATCH 2/2] target-arm: Handle UNDEF cases for Neon VLD/VST multiple-structures

2011-04-18 Thread Peter Maydell
Correctly UNDEF for Neon VLD/VST "multiple structures" forms where the
align field is not valid.

Signed-off-by: Peter Maydell 
---
 target-arm/translate.c |   15 +++
 1 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 5820add..30ca7df 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -3830,6 +3830,21 @@ static int disas_neon_ls_insn(CPUState * env, 
DisasContext *s, uint32_t insn)
 size = (insn >> 6) & 3;
 if (op > 10)
 return 1;
+/* Catch UNDEF cases for bad values of align field */
+switch (op & 0xc) {
+case 4:
+if (((insn >> 5) & 1) == 1) {
+return 1;
+}
+break;
+case 8:
+if (((insn >> 4) & 3) == 3) {
+return 1;
+}
+break;
+default:
+break;
+}
 nregs = neon_ls_element_type[op].nregs;
 interleave = neon_ls_element_type[op].interleave;
 spacing = neon_ls_element_type[op].spacing;
-- 
1.7.1




[Qemu-devel] [PATCH 1/2] target-arm: Handle UNDEFs for Neon single element load/stores

2011-04-18 Thread Peter Maydell
Handle the UNDEF and UNPREDICTABLE cases for Neon "single element to
one lane" VLD and "single element from one lane" VST.

Signed-off-by: Peter Maydell 
---
 target-arm/translate.c |   34 ++
 1 files changed, 34 insertions(+), 0 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 6190028..5820add 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -3975,6 +3975,7 @@ static int disas_neon_ls_insn(CPUState * env, 
DisasContext *s, uint32_t insn)
 stride = (1 << size) * nregs;
 } else {
 /* Single element.  */
+int idx = (insn >> 4) & 0xf;
 pass = (insn >> 7) & 1;
 switch (size) {
 case 0:
@@ -3993,6 +3994,39 @@ static int disas_neon_ls_insn(CPUState * env, 
DisasContext *s, uint32_t insn)
 abort();
 }
 nregs = ((insn >> 8) & 3) + 1;
+/* Catch the UNDEF cases. This is unavoidably a bit messy. */
+switch (nregs) {
+case 1:
+if (((idx & (1 << size)) != 0) ||
+(size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
+return 1;
+}
+break;
+case 3:
+if ((idx & 1) != 0) {
+return 1;
+}
+/* fall through */
+case 2:
+if (size == 2 && (idx & 2) != 0) {
+return 1;
+}
+break;
+case 4:
+if ((size == 2) && ((idx & 3) == 3)) {
+return 1;
+}
+break;
+default:
+abort();
+}
+if ((rd + stride * (nregs - 1)) > 31) {
+/* Attempts to write off the end of the register file
+ * are UNPREDICTABLE; we choose to UNDEF because otherwise
+ * the neon_load_reg() would write off the end of the array.
+ */
+return 1;
+}
 addr = tcg_temp_new_i32();
 load_reg_var(s, addr, rn);
 for (reg = 0; reg < nregs; reg++) {
-- 
1.7.1




Re: [Qemu-devel] [PATCH 1/2] Implement basic part of SA-1110/SA-1100

2011-04-18 Thread Aurelien Jarno
On Thu, Apr 14, 2011 at 10:18:02AM +0400, Dmitry Eremin-Solenikov wrote:
> Basic implementation of DEC/Intel SA-1100/SA-1110 chips emulation.
> Implemented:
>  - IRQs
>  - GPIO
>  - PPC
>  - RTC
>  - UARTs (no IrDA/etc.)
>  - OST reused from pxa25x
> 
> Everything else is TODO (esp. PM/idle/sleep!) - see the todo in the
> hw/strongarm.c
> 
> V5:
>   * syntax fixup
> 
> V4:
>   * use bitnames to access RTC and UART registers
>   * drop unused casts
>   * disable debug printfs in GPIO code
> 
> V3:
>   * fix the name of UART VMSD
>   * fix RTSR reg offset
>   * add SSP support
> 
> V2:
>   * removed all strongarm variants except latest
>   * dropped unused casts
>   * fixed PIC vmstate
>   * fixed new devices created with version_id = 1
> 
> Signed-off-by: Dmitry Eremin-Solenikov 
> ---
>  Makefile.target |1 +
>  hw/strongarm.c  | 1587 
> +++
>  hw/strongarm.h  |   64 ++
>  target-arm/cpu.h|3 +
>  target-arm/helper.c |9 +
>  5 files changed, 1664 insertions(+), 0 deletions(-)
>  create mode 100644 hw/strongarm.c
>  create mode 100644 hw/strongarm.h

It seems we are slowly converging, and this is almost ready. See my
comments below.

> diff --git a/Makefile.target b/Makefile.target
> index d5761b7..9e4cfc0 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -352,6 +352,7 @@ obj-arm-y += syborg.o syborg_fb.o syborg_interrupt.o 
> syborg_keyboard.o
>  obj-arm-y += syborg_serial.o syborg_timer.o syborg_pointer.o syborg_rtc.o
>  obj-arm-y += syborg_virtio.o
>  obj-arm-y += vexpress.o
> +obj-arm-y += strongarm.o
>  
>  obj-sh4-y = shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o
>  obj-sh4-y += sh_timer.o sh_serial.o sh_intc.o sh_pci.o sm501.o
> diff --git a/hw/strongarm.c b/hw/strongarm.c
> new file mode 100644
> index 000..3e0fefe
> --- /dev/null
> +++ b/hw/strongarm.c
> @@ -0,0 +1,1587 @@
> +/*
> + * StrongARM SA-1100/SA-1110 emulation
> + *
> + * Copyright (C) 2011 Dmitry Eremin-Solenikov
> + *
> + * Largely based on StrongARM emulation:
> + * Copyright (c) 2006 Openedhand Ltd.
> + * Written by Andrzej Zaborowski 
> + *
> + * UART code based on QEMU 16550A UART emulation
> + * Copyright (c) 2003-2004 Fabrice Bellard
> + * Copyright (c) 2008 Citrix Systems, Inc.
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2.  See
> + * the COPYING file in the top-level directory.
> + */

You may want to add a bit longer license text, see for example
hw/vexpress.c.

> +#include "sysbus.h"
> +#include "strongarm.h"
> +#include "qemu-error.h"
> +#include "arm-misc.h"
> +#include "sysemu.h"
> +#include "ssi.h"
> +
> +/*
> + TODO
> + - Implement cp15, c14 ?
> + - Implement cp15, c15 !!! (idle used in L)
> + - Implement idle mode handling/DIM
> + - Implement sleep mode/Wake sources
> + - Implement reset control
> + - Implement memory control regs
> + - PCMCIA handling
> + - Maybe support MBGNT/MBREQ
> + - DMA channels
> + - GPCLK
> + - IrDA
> + - MCP
> + - Enhance UART with modem signals
> + */
> +
> +static struct {
> +target_phys_addr_t io_base;
> +int irq;
> +} sa_serial[] = {
> +{ 0x8001, SA_PIC_UART1 },
> +{ 0x8003, SA_PIC_UART2 },
> +{ 0x8005, SA_PIC_UART3 },
> +{ 0, 0 }
> +};
> +
> +/* Interrupt Controller */
> +typedef struct {
> +SysBusDevice busdev;
> +qemu_irqirq;
> +qemu_irqfiq;
> +
> +uint32_t pending;
> +uint32_t enabled;
> +uint32_t is_fiq;
> +uint32_t int_idle;
> +} StrongARMPICState;
> +
> +#define ICIP0x00
> +#define ICMR0x04
> +#define ICLR0x08
> +#define ICFP0x10
> +#define ICPR0x20
> +#define ICCR0x0c
> +
> +#define SA_PIC_SRCS 32
> +
> +
> +static void strongarm_pic_update(void *opaque)
> +{
> +StrongARMPICState *s = opaque;
> +
> +/* FIXME: reflect DIM */
> +qemu_set_irq(s->fiq, s->pending & s->enabled &  s->is_fiq);
> +qemu_set_irq(s->irq, s->pending & s->enabled & ~s->is_fiq);
> +}
> +
> +static void strongarm_pic_set_irq(void *opaque, int irq, int level)
> +{
> +StrongARMPICState *s = opaque;
> +
> +if (level) {
> +s->pending |= 1 << irq;
> +} else {
> +s->pending &= ~(1 << irq);
> +}
> +
> +strongarm_pic_update(s);
> +}
> +
> +static uint32_t strongarm_pic_mem_read(void *opaque, target_phys_addr_t 
> offset)
> +{
> +StrongARMPICState *s = opaque;
> +
> +switch (offset) {
> +case ICIP:
> +return s->pending & ~s->is_fiq & s->enabled;
> +case ICMR:
> +return s->enabled;
> +case ICLR:
> +return s->is_fiq;
> +case ICCR:
> +return s->int_idle == 0;
> +case ICFP:
> +return s->pending & s->is_fiq & s->enabled;
> +case ICPR:
> +return s->pending;
> +default:
> +printf("%s: Bad register offset 0x" TARGET_FMT_plx "\n",
> +__func__, offset);
> +return 0;
> +}
> +}
> +
> +static void strongarm_pic_mem_write(void *opaque, target_

Re: [Qemu-devel] [PATCH v2 0/3] pc-bios: Use iPXE ROMs

2011-04-18 Thread Anthony Liguori
On 04/18/2011 12:25 PM, Alex Williamson wrote:
> On Mon, 2011-04-11 at 13:57 -0600, Alex Williamson wrote:
>> On Mon, 2011-04-11 at 14:48 -0500, Anthony Liguori wrote:
>>> On 04/11/2011 02:35 PM, Alex Williamson wrote:
 This series replaces our current gPXE based PXE ROMs with iPXE
 versions from the iPXE project (http://ipxe.org).  This version
 adds ipxe to our submodules so it can be easily included in
 releases.  I'm still including a script for updating these,
 perhaps someone better with Makefiles can eventually adopt this
 to a build target.

 This email series is mainly for reference, there's too much
 renaming and replacing binary files to send out to the mailing
 list.  I'll strip out the binaries here so the rest can be
 reviewed.  For the real code, please pull:

 git://github.com/awilliam/qemu.git (ipxe branch)

 Thanks to Anthony for already setting up an ipxe mirror.
 Thanks,
>>>
>>> Looks good to me.  How different is this from what we've been shipping?  
>>> Have you tested PXE boot from the builtin TFTP server and from an 
>>> external one (like dnsmasq)?
>>
>> We were shipping v0.9.9, which was tagged 10/2009.  There's been a gpxe
>> v1.0.0 release since then, plus the split between ipxe and gpxe.  I
>> think Michael is hoping to have a release soon, but the code feels
>> pretty stable to me as is.
>>
>> I've tested external booting from dhcp/tftp server for all the NICs.
>> I'll make a pass through testing with the builtin server and report
>> back.  Thanks,
> 
> Ping, any reason this isn't going in?  Testing passed, I updated the
> script to use bash and alphabetized the Makefile per Stefan Weil's
> suggestions.  These are updated in the above github tree.  Let me know.
> Thanks,

I actually was just testing the github tree.  Unfortunately, it looks
like there's something broken.

You renamed all of the pxe roms to end with .bin but Makefile still
refers to everything as .rom.

This makes make install break along with building from a separate build
directory.

Regards,

Anthony Liguori

> 
> Alex
> 




[Qemu-devel] [PATCH 6/6] linux-user: untie syscalls from UID16

2011-04-18 Thread Riku Voipio
Quite a number of uid/gid related syscalls are only defined on systems
with USE_UID16 defined. This is apperently based on the idea that these
system calls would never be called on non-UID16 systems. Make these
syscalls available for all architectures that define them.

drop alpha hack to support selected UID16 syscalls. MIPS and PowerPC
were also defined as UID16, to get uid/gid syscalls available, drop
this error as well.

Change QEMU to reflect this.

Cc: Ulrich Hecht 
Cc: Richard Henderson 
Cc: Alexander Graf 
Signed-off-by: Riku Voipio 
---
 linux-user/alpha/syscall_nr.h |7 --
 linux-user/syscall.c  |   48 +---
 linux-user/syscall_defs.h |5 +++-
 3 files changed, 43 insertions(+), 17 deletions(-)

diff --git a/linux-user/alpha/syscall_nr.h b/linux-user/alpha/syscall_nr.h
index 7182223..e3127df 100644
--- a/linux-user/alpha/syscall_nr.h
+++ b/linux-user/alpha/syscall_nr.h
@@ -412,10 +412,3 @@
 #define TARGET_NR_timerfd  477
 #define TARGET_NR_eventfd  478
 
-/* The following aliases are defined in order to match up with the
-   standard i386 syscalls implemented in syscalls.c.  */
-#define TARGET_NR_chown32  TARGET_NR_chown
-#define TARGET_NR_setuid32 TARGET_NR_setuid
-#define TARGET_NR_setgid32 TARGET_NR_setgid
-#define TARGET_NR_setfsuid32   TARGET_NR_setfsuid
-#define TARGET_NR_setfsgid32   TARGET_NR_setfsgid
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index e7af2ea..e969d1b 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -328,7 +328,7 @@ static int sys_fchmodat(int dirfd, const char *pathname, 
mode_t mode)
   return (fchmodat(dirfd, pathname, mode, 0));
 }
 #endif
-#if defined(TARGET_NR_fchownat) && defined(USE_UID16)
+#if defined(TARGET_NR_fchownat)
 static int sys_fchownat(int dirfd, const char *pathname, uid_t owner,
 gid_t group, int flags)
 {
@@ -437,7 +437,7 @@ _syscall3(int,sys_faccessat,int,dirfd,const char 
*,pathname,int,mode)
 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
 _syscall3(int,sys_fchmodat,int,dirfd,const char *,pathname, mode_t,mode)
 #endif
-#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) && defined(USE_UID16)
+#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
 _syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
   uid_t,owner,gid_t,group,int,flags)
 #endif
@@ -4164,7 +4164,31 @@ static inline int low2highgid(int gid)
 else
 return gid;
 }
-
+static inline int tswapid(int id)
+{
+return tswap16(id);
+}
+#else /* !USE_UID16 */
+static inline int high2lowuid(int uid)
+{
+return uid;
+}
+static inline int high2lowgid(int gid)
+{
+return gid;
+}
+static inline int low2highuid(int uid)
+{
+return uid;
+}
+static inline int low2highgid(int gid)
+{
+return gid;
+}
+static inline int tswapid(int id)
+{
+return tswap32(id);
+}
 #endif /* USE_UID16 */
 
 void syscall_init(void)
@@ -6765,25 +6789,32 @@ abi_long do_syscall(void *cpu_env, int num, abi_long 
arg1,
 ret = host_to_target_stat64(cpu_env, arg3, &st);
 break;
 #endif
-#ifdef USE_UID16
 case TARGET_NR_lchown:
 if (!(p = lock_user_string(arg1)))
 goto efault;
 ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
 unlock_user(p, arg1, 0);
 break;
+#ifdef TARGET_NR_getuid
 case TARGET_NR_getuid:
 ret = get_errno(high2lowuid(getuid()));
 break;
+#endif
+#ifdef TARGET_NR_getgid
 case TARGET_NR_getgid:
 ret = get_errno(high2lowgid(getgid()));
 break;
+#endif
+#ifdef TARGET_NR_geteuid
 case TARGET_NR_geteuid:
 ret = get_errno(high2lowuid(geteuid()));
 break;
+#endif
+#ifdef TARGET_NR_getegid
 case TARGET_NR_getegid:
 ret = get_errno(high2lowgid(getegid()));
 break;
+#endif
 case TARGET_NR_setreuid:
 ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
 break;
@@ -6793,7 +6824,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 case TARGET_NR_getgroups:
 {
 int gidsetsize = arg1;
-uint16_t *target_grouplist;
+target_id *target_grouplist;
 gid_t *grouplist;
 int i;
 
@@ -6806,7 +6837,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 if (!target_grouplist)
 goto efault;
 for(i = 0;i < ret; i++)
-target_grouplist[i] = tswap16(grouplist[i]);
+target_grouplist[i] = tswapid(high2lowgid(grouplist[i]));
 unlock_user(target_grouplist, arg2, gidsetsize * 2);
 }
 }
@@ -6814,7 +6845,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 case TARGET_NR_setgroups:
 {
 int gidsetsize = arg1;
-uint16_t *target_grouplist;
+target_id *target_grouplist;

[Qemu-devel] [PATCH 3/6] linux-user: convert ioctl(SIOCGIFCONF, ...) result.

2011-04-18 Thread Riku Voipio
From: Laurent Vivier 

The result needs to be converted as it is stored in an array of struct
ifreq and sizeof(struct ifreq) differs according to target and host
alignment rules.

This patch allows to execute correctly the following program on arm
and m68k:

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

int main(void)
{
int s, ret;
struct ifconf ifc;
int i;

memset( &ifc, 0, sizeof( struct ifconf ) );
ifc.ifc_len = 8 * sizeof(struct ifreq);
ifc.ifc_buf = alloca(ifc.ifc_len);

s = socket( AF_INET, SOCK_DGRAM, 0 );
if (s < 0) {
perror("Cannot open socket");
return 1;
}
ret = ioctl( s, SIOCGIFCONF, &ifc );
if (s < 0) {
perror("ioctl() failed");
return 1;
}

for (i = 0; i < ifc.ifc_len / sizeof(struct ifreq) ; i ++) {
struct sockaddr_in *s;
s = (struct sockaddr_in*)&ifc.ifc_req[i].ifr_addr;
printf("%s\n", ifc.ifc_req[i].ifr_name);
printf("%s\n", inet_ntoa(s->sin_addr));
}
}

Signed-off-by: Laurent Vivier 
Signed-off-by: Riku Voipio 
---
 linux-user/ioctls.h  |3 +-
 linux-user/syscall.c |   96 +-
 2 files changed, 97 insertions(+), 2 deletions(-)

diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index 526aaa2..ab15b86 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -112,7 +112,8 @@
   IOCTL(SIOCADDMULTI, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
   IOCTL(SIOCDELMULTI, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
   IOCTL(SIOCSIFLINK, 0, TYPE_NULL)
-  IOCTL(SIOCGIFCONF, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_ifconf)))
+  IOCTL_SPECIAL(SIOCGIFCONF, IOC_W | IOC_R, do_ioctl_ifconf,
+MK_PTR(MK_STRUCT(STRUCT_ifconf)))
   IOCTL(SIOCGIFENCAP, IOC_RW, MK_PTR(TYPE_INT))
   IOCTL(SIOCSIFENCAP, IOC_W, MK_PTR(TYPE_INT))
   IOCTL(SIOCDARP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_arpreq)))
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 732f71a..123909f 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -59,6 +59,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
 //#include 
 #include 
 #include 
+#include 
 #include 
 #ifdef TARGET_GPROF
 #include 
@@ -2970,7 +2971,6 @@ static abi_long do_ipc(unsigned int call, int first,
 #endif
 
 /* kernel structure types definitions */
-#define IFNAMSIZ16
 
 #define STRUCT(name, ...) STRUCT_ ## name,
 #define STRUCT_SPECIAL(name) STRUCT_ ## name,
@@ -3095,6 +3095,100 @@ static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry 
*ie, uint8_t *buf_temp,
 }
 #endif
 
+static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp,
+int fd, abi_long cmd, abi_long arg)
+{
+const argtype *arg_type = ie->arg_type;
+int target_size;
+void *argptr;
+int ret;
+struct ifconf *host_ifconf;
+uint32_t outbufsz;
+const argtype ifreq_arg_type[] = { MK_STRUCT(STRUCT_sockaddr_ifreq) };
+int target_ifreq_size;
+int nb_ifreq;
+int free_buf = 0;
+int i;
+int target_ifc_len;
+abi_long target_ifc_buf;
+int host_ifc_len;
+char *host_ifc_buf;
+
+assert(arg_type[0] == TYPE_PTR);
+assert(ie->access == IOC_RW);
+
+arg_type++;
+target_size = thunk_type_size(arg_type, 0);
+
+argptr = lock_user(VERIFY_READ, arg, target_size, 1);
+if (!argptr)
+return -TARGET_EFAULT;
+thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
+unlock_user(argptr, arg, 0);
+
+host_ifconf = (struct ifconf *)(unsigned long)buf_temp;
+target_ifc_len = host_ifconf->ifc_len;
+target_ifc_buf = (abi_long)(unsigned long)host_ifconf->ifc_buf;
+
+target_ifreq_size = thunk_type_size(ifreq_arg_type, 0);
+nb_ifreq = target_ifc_len / target_ifreq_size;
+host_ifc_len = nb_ifreq * sizeof(struct ifreq);
+
+outbufsz = sizeof(*host_ifconf) + host_ifc_len;
+if (outbufsz > MAX_STRUCT_SIZE) {
+/* We can't fit all the extents into the fixed size buffer.
+ * Allocate one that is large enough and use it instead.
+ */
+host_ifconf = malloc(outbufsz);
+if (!host_ifconf) {
+return -TARGET_ENOMEM;
+}
+memcpy(host_ifconf, buf_temp, sizeof(*host_ifconf));
+free_buf = 1;
+}
+host_ifc_buf = (char*)host_ifconf + sizeof(*host_ifconf);
+
+host_ifconf->ifc_len = host_ifc_len;
+host_ifconf->ifc_buf = host_ifc_buf;
+
+ret = get_errno(ioctl(fd, ie->host_cmd, host_ifconf));
+if (!is_error(ret)) {
+   /* convert host ifc_len to target ifc_len */
+
+nb_ifreq = host_ifconf->ifc_len / sizeof(struct ifreq);
+target_ifc_len = nb_ifreq * target_ifreq_size;
+host_ifconf->ifc_len = target_ifc_len;
+
+   /* restore target ifc_buf */
+
+host_ifconf->ifc_buf = (char *)(unsigned long)target_ifc_buf;
+
+   /* copy struct ifconf to target user */
+
+argptr = lock_user(VERIFY_WRITE, ar

[Qemu-devel] [PATCH 5/6] linux-user: add s390x to llseek list

2011-04-18 Thread Riku Voipio
From: Alexander Graf 

We keep a list of host architectures that do llseek with the same
syscall as lseek. S390x is one of them, so let's add it to the list.

Original-patch-by: Ulrich Hecht 
Signed-off-by: Alexander Graf 
Signed-off-by: Riku Voipio 
---
 linux-user/syscall.c |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 5f9061d..e7af2ea 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -197,7 +197,8 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 
arg4,type5 arg5,   \
 #define __NR_sys_inotify_add_watch __NR_inotify_add_watch
 #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
 
-#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
+#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) || \
+defined(__s390x__)
 #define __NR__llseek __NR_lseek
 #endif
 
-- 
1.7.1




[Qemu-devel] [PATCH 4/6] linux-user: add ioctl(SIOCGIWNAME, ...) support.

2011-04-18 Thread Riku Voipio
From: Laurent Vivier 

Allow to run properly following program from linux-user:

/* cc -o wifi wifi.c */

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

int main(int argc, char **argv)
{
int ret;
struct ifreq req;
struct sockaddr_in *addr;
int s;

if (argc != 2) {
fprintf(stderr, "Need an interface name (like wlan0)\n");
return 1;
}

s = socket( AF_INET, SOCK_DGRAM, 0 );
if (s < 0) {
perror("Cannot open socket");
return 1;
}
strncpy(req.ifr_name, argv[1], sizeof(req.ifr_name));
ret = ioctl( s, SIOCGIWNAME, &req );
if (ret < 0) {
fprintf(stderr, "No wireless extension\n");
return 1;
}

printf("%s\n", req.ifr_name);
printf("%s\n", req.ifr_newname);
return 0;
}

$ ./wifi eth0
No wireless extension

$ ./wifi wlan0
wlan0
IEEE 802.11bg

Signed-off-by: Laurent Vivier 
Signed-off-by: Riku Voipio 
---
 linux-user/ioctls.h   |1 +
 linux-user/syscall.c  |2 +-
 linux-user/syscall_defs.h |3 +++
 3 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index ab15b86..42b3ae3 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -122,6 +122,7 @@
   IOCTL(SIOCDRARP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_arpreq)))
   IOCTL(SIOCSRARP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_arpreq)))
   IOCTL(SIOCGRARP, IOC_R, MK_PTR(MK_STRUCT(STRUCT_arpreq)))
+  IOCTL(SIOCGIWNAME, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_char_ifreq)))
 
   IOCTL(CDROMPAUSE, 0, TYPE_NULL)
   IOCTL(CDROMSTART, 0, TYPE_NULL)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 123909f..5f9061d 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -59,7 +59,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
 //#include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #ifdef TARGET_GPROF
 #include 
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index bde8921..527f31d 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -765,6 +765,9 @@ struct target_pollfd {
 #define TARGET_SIOCADDDLCI 0x8980  /* Create new DLCI device   
*/
 #define TARGET_SIOCDELDLCI 0x8981  /* Delete DLCI device   
*/
 
+/* From  */
+
+#define TARGET_SIOCGIWNAME 0x8B01  /* get name == wireless 
protocol */
 
 /* From  */
 
-- 
1.7.1




[Qemu-devel] [PATCH 2/6] linux-user: improve traces

2011-04-18 Thread Riku Voipio
From: Laurent Vivier 

Add trace details for getpid(), kill(), _llseek(), rt_sigaction(),
rt_sigprocmask(), clone().

Signed-off-by: Laurent Vivier 
Signed-off-by: Riku Voipio 
---
 linux-user/strace.c|  161 
 linux-user/strace.list |   12 ++--
 2 files changed, 167 insertions(+), 6 deletions(-)

diff --git a/linux-user/strace.c b/linux-user/strace.c
index 8dd398b..5d9bb08 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -9,6 +9,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "qemu.h"
 
 int do_strace=0;
@@ -63,6 +64,7 @@ UNUSED static void print_string(abi_long, int);
 UNUSED static void print_raw_param(const char *, abi_long, int);
 UNUSED static void print_timeval(abi_ulong, int);
 UNUSED static void print_number(abi_long, int);
+UNUSED static void print_signal(abi_ulong, int);
 
 /*
  * Utility functions
@@ -117,6 +119,37 @@ if( cmd == val ) { \
 gemu_log("%d",cmd);
 }
 
+static void
+print_signal(abi_ulong arg, int last)
+{
+const char *signal_name = NULL;
+switch(arg) {
+case TARGET_SIGHUP: signal_name = "SIGHUP"; break;
+case TARGET_SIGINT: signal_name = "SIGINT"; break;
+case TARGET_SIGQUIT: signal_name = "SIGQUIT"; break;
+case TARGET_SIGILL: signal_name = "SIGILL"; break;
+case TARGET_SIGABRT: signal_name = "SIGABRT"; break;
+case TARGET_SIGFPE: signal_name = "SIGFPE"; break;
+case TARGET_SIGKILL: signal_name = "SIGKILL"; break;
+case TARGET_SIGSEGV: signal_name = "SIGSEGV"; break;
+case TARGET_SIGPIPE: signal_name = "SIGPIPE"; break;
+case TARGET_SIGALRM: signal_name = "SIGALRM"; break;
+case TARGET_SIGTERM: signal_name = "SIGTERM"; break;
+case TARGET_SIGUSR1: signal_name = "SIGUSR1"; break;
+case TARGET_SIGUSR2: signal_name = "SIGUSR2"; break;
+case TARGET_SIGCHLD: signal_name = "SIGCHLD"; break;
+case TARGET_SIGCONT: signal_name = "SIGCONT"; break;
+case TARGET_SIGSTOP: signal_name = "SIGSTOP"; break;
+case TARGET_SIGTTIN: signal_name = "SIGTTIN"; break;
+case TARGET_SIGTTOU: signal_name = "SIGTTOU"; break;
+}
+if (signal_name == NULL) {
+print_raw_param("%ld", arg, 1);
+return;
+}
+gemu_log("%s%s", signal_name, get_comma(last));
+}
+
 #ifdef TARGET_NR__newselect
 static void
 print_fdset(int n, abi_ulong target_fds_addr)
@@ -427,6 +460,32 @@ UNUSED static struct flags fcntl_flags[] = {
 FLAG_END,
 };
 
+UNUSED static struct flags clone_flags[] = {
+FLAG_GENERIC(CLONE_VM),
+FLAG_GENERIC(CLONE_FS),
+FLAG_GENERIC(CLONE_FILES),
+FLAG_GENERIC(CLONE_SIGHAND),
+FLAG_GENERIC(CLONE_PTRACE),
+FLAG_GENERIC(CLONE_VFORK),
+FLAG_GENERIC(CLONE_PARENT),
+FLAG_GENERIC(CLONE_THREAD),
+FLAG_GENERIC(CLONE_NEWNS),
+FLAG_GENERIC(CLONE_SYSVSEM),
+FLAG_GENERIC(CLONE_SETTLS),
+FLAG_GENERIC(CLONE_PARENT_SETTID),
+FLAG_GENERIC(CLONE_CHILD_CLEARTID),
+FLAG_GENERIC(CLONE_DETACHED),
+FLAG_GENERIC(CLONE_UNTRACED),
+FLAG_GENERIC(CLONE_CHILD_SETTID),
+FLAG_GENERIC(CLONE_NEWUTS),
+FLAG_GENERIC(CLONE_NEWIPC),
+FLAG_GENERIC(CLONE_NEWUSER),
+FLAG_GENERIC(CLONE_NEWPID),
+FLAG_GENERIC(CLONE_NEWNET),
+FLAG_GENERIC(CLONE_IO),
+FLAG_END,
+};
+
 /*
  * print_xxx utility functions.  These are used to print syscall
  * parameters in certain format.  All of these have parameter
@@ -669,6 +728,39 @@ print_chmod(const struct syscallname *name,
 }
 #endif
 
+#ifdef TARGET_NR_clone
+static void
+print_clone(const struct syscallname *name,
+abi_long arg0, abi_long arg1, abi_long arg2,
+abi_long arg3, abi_long arg4, abi_long arg5)
+{
+print_syscall_prologue(name);
+#if defined(TARGET_M68K)
+print_flags(clone_flags, arg0, 0);
+print_raw_param("newsp=0x" TARGET_ABI_FMT_lx, arg1, 1);
+#elif defined(TARGET_SH4) || defined(TARGET_ALPHA)
+print_flags(clone_flags, arg0, 0);
+print_raw_param("child_stack=0x" TARGET_ABI_FMT_lx, arg1, 0);
+print_raw_param("parent_tidptr=0x" TARGET_ABI_FMT_lx, arg2, 0);
+print_raw_param("child_tidptr=0x" TARGET_ABI_FMT_lx, arg3, 0);
+print_raw_param("tls=0x" TARGET_ABI_FMT_lx, arg4, 1);
+#elif defined(TARGET_CRIS)
+print_raw_param("child_stack=0x" TARGET_ABI_FMT_lx, arg0, 0);
+print_flags(clone_flags, arg1, 0);
+print_raw_param("parent_tidptr=0x" TARGET_ABI_FMT_lx, arg2, 0);
+print_raw_param("tls=0x" TARGET_ABI_FMT_lx, arg3, 0);
+print_raw_param("child_tidptr=0x" TARGET_ABI_FMT_lx, arg4, 1);
+#else
+print_flags(clone_flags, arg0, 0);
+print_raw_param("child_stack=0x" TARGET_ABI_FMT_lx, arg1, 0);
+print_raw_param("parent_tidptr=0x" TARGET_ABI_FMT_lx, arg2, 0);
+print_raw_param("tls=0x" TARGET_ABI_FMT_lx, arg3, 0);
+print_raw_param("child_tidptr=0x" TARGET_ABI_FMT_lx, arg4, 1);
+#endif
+print_syscall_epilogue(name);
+}
+#endif
+
 #ifdef TARGET_NR_creat
 static void
 print_creat(const struct syscallname *name,
@@ -805,6 +897,28 @@ print_linkat(const struct s

[Qemu-devel] [PATCH 1/6] [v2] linux-user: bigger default stack

2011-04-18 Thread Riku Voipio
From: Riku Voipio 

PTHREAD_STACK_MIN (16KB) is somewhat inadequate for a new stack for new
QEMU threads. Set new limit to 256K which should be enough, yet doesn't
increase memory pressure significantly.

Signed-off-by: Riku Voipio 
Reviewed-by: Nathan Froyd 
---
 linux-user/syscall.c |7 ++-
 1 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index bb0999d..732f71a 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -3690,9 +3690,9 @@ static abi_long do_arch_prctl(CPUX86State *env, int code, 
abi_ulong addr)
 
 #endif /* defined(TARGET_I386) */
 
-#if defined(CONFIG_USE_NPTL)
+#define NEW_STACK_SIZE 0x4
 
-#define NEW_STACK_SIZE PTHREAD_STACK_MIN
+#if defined(CONFIG_USE_NPTL)
 
 static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
 typedef struct {
@@ -3736,9 +3736,6 @@ static void *clone_func(void *arg)
 return NULL;
 }
 #else
-/* this stack is the equivalent of the kernel stack associated with a
-   thread/process */
-#define NEW_STACK_SIZE 8192
 
 static int clone_func(void *arg)
 {
-- 
1.7.1




[Qemu-devel] [PATCH 0/6] linux-user: pending patches

2011-04-18 Thread Riku Voipio

Apart from the last patch, all patches have been
seen on the list. If no problems are found in reviews, I'll
send these as the next pull request.

Changes can also be pulled by git from:

  git://gitorious.org/qemu-maemo/qemu.git linux-user-for-upstream

notice that linux-user git will move soon to some other location.

Alexander Graf (1):
  linux-user: add s390x to llseek list

Laurent Vivier (3):
  linux-user: improve traces
  linux-user: convert ioctl(SIOCGIFCONF, ...) result.
  linux-user: add ioctl(SIOCGIWNAME, ...) support.

Riku Voipio (2):
  [v2] linux-user: bigger default stack
  linux-user: untie syscalls from UID16

 linux-user/alpha/syscall_nr.h |7 --
 linux-user/ioctls.h   |4 +-
 linux-user/strace.c   |  161 +
 linux-user/strace.list|   12 ++--
 linux-user/syscall.c  |  154 +++
 linux-user/syscall_defs.h |8 ++-
 6 files changed, 315 insertions(+), 31 deletions(-)




Re: [Qemu-devel] [PATCH 2/2] Remove unused function parameter from cpu_restore_state

2011-04-18 Thread Peter Maydell
On 18 April 2011 17:39, Stefan Weil  wrote:
> The previous patch removed the need for parameter puc.
> Is is now unused, so remove it.

Reviewed-by: Peter Maydell 

-- PMM



Re: [Qemu-devel] [PATCH v2 0/3] pc-bios: Use iPXE ROMs

2011-04-18 Thread Alex Williamson
On Mon, 2011-04-11 at 13:57 -0600, Alex Williamson wrote:
> On Mon, 2011-04-11 at 14:48 -0500, Anthony Liguori wrote:
> > On 04/11/2011 02:35 PM, Alex Williamson wrote:
> > > This series replaces our current gPXE based PXE ROMs with iPXE
> > > versions from the iPXE project (http://ipxe.org).  This version
> > > adds ipxe to our submodules so it can be easily included in
> > > releases.  I'm still including a script for updating these,
> > > perhaps someone better with Makefiles can eventually adopt this
> > > to a build target.
> > >
> > > This email series is mainly for reference, there's too much
> > > renaming and replacing binary files to send out to the mailing
> > > list.  I'll strip out the binaries here so the rest can be
> > > reviewed.  For the real code, please pull:
> > >
> > > git://github.com/awilliam/qemu.git (ipxe branch)
> > >
> > > Thanks to Anthony for already setting up an ipxe mirror.
> > > Thanks,
> > 
> > Looks good to me.  How different is this from what we've been shipping?  
> > Have you tested PXE boot from the builtin TFTP server and from an 
> > external one (like dnsmasq)?
> 
> We were shipping v0.9.9, which was tagged 10/2009.  There's been a gpxe
> v1.0.0 release since then, plus the split between ipxe and gpxe.  I
> think Michael is hoping to have a release soon, but the code feels
> pretty stable to me as is.
> 
> I've tested external booting from dhcp/tftp server for all the NICs.
> I'll make a pass through testing with the builtin server and report
> back.  Thanks,

Ping, any reason this isn't going in?  Testing passed, I updated the
script to use bash and alphabetized the Makefile per Stefan Weil's
suggestions.  These are updated in the above github tree.  Let me know.
Thanks,

Alex




Re: [Qemu-devel] [PATCH 1/2] Remove unused function parameters from gen_pc_load and rename the function

2011-04-18 Thread Peter Maydell
On 18 April 2011 17:39, Stefan Weil  wrote:
> Function gen_pc_load was introduced in commit
> d2856f1ad4c259e5766847c49acbb4e390731bd4.
> The only reason for parameter searched_pc was
> a debug statement in target-i386/translate.c.
>
> Parameter puc was needed by target-sparc until
> commit d2856f1ad4c259e5766847c49acbb4e390731bd4.

Don't you mean d7da2a10402f1644128b66414ca8f86bdea9ae7c ?

> diff --git a/target-arm/translate.c b/target-arm/translate.c
> index 6190028..7e7652e 100644
> --- a/target-arm/translate.c
> +++ b/target-arm/translate.c
> @@ -9551,8 +9551,8 @@ static inline void 
> gen_intermediate_code_internal(CPUState *env,
>      * This is handled in the same way as restoration of the
>      * PC in these situations: we will be called again with search_pc=1
>      * and generate a mapping of the condexec bits for each PC in
> -     * gen_opc_condexec_bits[]. gen_pc_load[] then uses this to restore
> -     * the condexec bits.
> +     * gen_opc_condexec_bits[]. restore_state_to_opc[] then uses
> +     * this to restore the condexec bits.

If you have to do another round of this patch then you could make
that say "restore_state_to_opc()" (round brackets rather than square),
but it's not worth doing a fresh round just to fix an existing typo.

Reviewed-by: Peter Maydell 

-- PMM



Re: [Qemu-devel] [PULL] Migration of misc devices

2011-04-18 Thread Juan Quintela
Anthony Liguori  wrote:
> On 04/17/2011 03:08 PM, Juan Quintela wrote:
>> 
>> 
>> The following changes since commit a0102082de4026833afbd2525e8a6320d1f92885:
>> 
>>   usb: fix spelling errors in usb-linux.c (2011-04-16 12:24:28 +0100)
>> 
>> are available in the git repository at:
>>   git://repo.or.cz/qemu/quintela.git vmstate-misc-devices-v2
>
> Migration appears to be broken for me.  It's not caused by this series
> but I'm surprised you didn't encounter it.  Maybe it's my kernel version?
>
> My suspicion is that the cause of this is:
>
> commit 0ec329dab938e2d97d12a91f8ed15fec27b325e0
> Author: Jan Kiszka 
> Date:   Mon Feb 7 12:19:26 2011 +0100
>
> kvm: x86: Introduce kvmclock device to save/restore its state

GPE is broken.  see Isazu & Avi comments.  It worked for me with Sunday
tree, will retry now.

Later, Juan.



[Qemu-devel] [PATCH 2/2] Remove unused function parameter from cpu_restore_state

2011-04-18 Thread Stefan Weil
The previous patch removed the need for parameter puc.
Is is now unused, so remove it.

Cc: Aurelien Jarno 
Signed-off-by: Stefan Weil 
---
 cpu-exec.c|2 +-
 exec-all.h|3 +--
 exec.c|9 -
 target-alpha/op_helper.c  |2 +-
 target-arm/op_helper.c|2 +-
 target-cris/op_helper.c   |2 +-
 target-i386/op_helper.c   |2 +-
 target-lm32/op_helper.c   |2 +-
 target-m68k/op_helper.c   |2 +-
 target-microblaze/op_helper.c |2 +-
 target-mips/op_helper.c   |4 ++--
 target-ppc/op_helper.c|2 +-
 target-s390x/op_helper.c  |2 +-
 target-sh4/op_helper.c|2 +-
 target-sparc/op_helper.c  |2 +-
 translate-all.c   |3 +--
 16 files changed, 20 insertions(+), 23 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 5d6c9a8..293ae10 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -800,7 +800,7 @@ static inline int handle_cpu_signal(unsigned long pc, 
unsigned long address,
 if (tb) {
 /* the PC is inside the translated code. It means that we have
a virtual CPU fault */
-cpu_restore_state(tb, env, pc, puc);
+cpu_restore_state(tb, env, pc);
 }
 
 /* we restore the process signal mask as the sigreturn should
diff --git a/exec-all.h b/exec-all.h
index 29fd322..7c2d29f 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -84,8 +84,7 @@ void cpu_gen_init(void);
 int cpu_gen_code(CPUState *env, struct TranslationBlock *tb,
  int *gen_code_size_ptr);
 int cpu_restore_state(struct TranslationBlock *tb,
-  CPUState *env, unsigned long searched_pc,
-  void *puc);
+  CPUState *env, unsigned long searched_pc);
 void cpu_resume_from_signal(CPUState *env1, void *puc);
 void cpu_io_recompile(CPUState *env, void *retaddr);
 TranslationBlock *tb_gen_code(CPUState *env, 
diff --git a/exec.c b/exec.c
index b1ee52a..c3dc68a 100644
--- a/exec.c
+++ b/exec.c
@@ -1070,8 +1070,7 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, 
tb_page_addr_t end,
 restore the CPU state */
 
 current_tb_modified = 1;
-cpu_restore_state(current_tb, env,
-  env->mem_io_pc, NULL);
+cpu_restore_state(current_tb, env, env->mem_io_pc);
 cpu_get_tb_cpu_state(env, ¤t_pc, ¤t_cs_base,
  ¤t_flags);
 }
@@ -1179,7 +1178,7 @@ static void tb_invalidate_phys_page(tb_page_addr_t addr,
restore the CPU state */
 
 current_tb_modified = 1;
-cpu_restore_state(current_tb, env, pc, puc);
+cpu_restore_state(current_tb, env, pc);
 cpu_get_tb_cpu_state(env, ¤t_pc, ¤t_cs_base,
  ¤t_flags);
 }
@@ -3266,7 +3265,7 @@ static void check_watchpoint(int offset, int len_mask, 
int flags)
 cpu_abort(env, "check_watchpoint: could not find TB for "
   "pc=%p", (void *)env->mem_io_pc);
 }
-cpu_restore_state(tb, env, env->mem_io_pc, NULL);
+cpu_restore_state(tb, env, env->mem_io_pc);
 tb_phys_invalidate(tb, -1);
 if (wp->flags & BP_STOP_BEFORE_ACCESS) {
 env->exception_index = EXCP_DEBUG;
@@ -4301,7 +4300,7 @@ void cpu_io_recompile(CPUState *env, void *retaddr)
   retaddr);
 }
 n = env->icount_decr.u16.low + tb->icount;
-cpu_restore_state(tb, env, (unsigned long)retaddr, NULL);
+cpu_restore_state(tb, env, (unsigned long)retaddr);
 /* Calculate how many instructions had been executed before the fault
occurred.  */
 n = n - env->icount_decr.u16.low;
diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index 6c2ae20..afa3afb 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -1373,7 +1373,7 @@ void tlb_fill (target_ulong addr, int is_write, int 
mmu_idx, void *retaddr)
 if (likely(tb)) {
 /* the PC is inside the translated code. It means that we have
a virtual CPU fault */
-cpu_restore_state(tb, env, pc, NULL);
+cpu_restore_state(tb, env, pc);
 }
 }
 /* Exception index and error code are already set */
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index 3de2610..ee7997b 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -90,7 +90,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, 
void *retaddr)
 if (tb) {
 /* the PC is inside the translated code. It means that we have
a virtual CPU fault */
-cpu_restore_state(tb, env, pc, NULL);
+cpu_restore_state(tb, env, pc);
 }

[Qemu-devel] [PATCH 1/2] Remove unused function parameters from gen_pc_load and rename the function

2011-04-18 Thread Stefan Weil
Function gen_pc_load was introduced in commit
d2856f1ad4c259e5766847c49acbb4e390731bd4.
The only reason for parameter searched_pc was
a debug statement in target-i386/translate.c.

Parameter puc was needed by target-sparc until
commit d2856f1ad4c259e5766847c49acbb4e390731bd4.

Remove searched_pc from the debug statement and remove both
parameters from the parameter list of gen_pc_load.

As the function name gen_pc_load was also misleading,
it is now called restore_state_to_opc. This new name
was suggested by Peter Maydell, thanks.

v2: Remove last parameter, too, and rename the function.

Signed-off-by: Stefan Weil 
---
 exec-all.h|4 ++--
 target-alpha/translate.c  |3 +--
 target-arm/translate.c|7 +++
 target-cris/translate.c   |3 +--
 target-i386/translate.c   |7 +++
 target-lm32/translate.c   |3 +--
 target-m68k/translate.c   |3 +--
 target-microblaze/translate.c |3 +--
 target-mips/translate.c   |3 +--
 target-ppc/translate.c|3 +--
 target-s390x/translate.c  |3 +--
 target-sh4/translate.c|3 +--
 target-sparc/translate.c  |3 +--
 target-unicore32/translate.c  |3 +--
 translate-all.c   |2 +-
 15 files changed, 20 insertions(+), 33 deletions(-)

diff --git a/exec-all.h b/exec-all.h
index 496c001..29fd322 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -77,8 +77,8 @@ extern uint16_t gen_opc_icount[OPC_BUF_SIZE];
 
 void gen_intermediate_code(CPUState *env, struct TranslationBlock *tb);
 void gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb);
-void gen_pc_load(CPUState *env, struct TranslationBlock *tb,
- unsigned long searched_pc, int pc_pos, void *puc);
+void restore_state_to_opc(CPUState *env, struct TranslationBlock *tb,
+  int pc_pos);
 
 void cpu_gen_init(void);
 int cpu_gen_code(CPUState *env, struct TranslationBlock *tb,
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 96e922b..456ba51 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -3367,8 +3367,7 @@ CPUAlphaState * cpu_alpha_init (const char *cpu_model)
 return env;
 }
 
-void gen_pc_load(CPUState *env, TranslationBlock *tb,
-unsigned long searched_pc, int pc_pos, void *puc)
+void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
 {
 env->pc = gen_opc_pc[pc_pos];
 }
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 6190028..7e7652e 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -9551,8 +9551,8 @@ static inline void 
gen_intermediate_code_internal(CPUState *env,
  * This is handled in the same way as restoration of the
  * PC in these situations: we will be called again with search_pc=1
  * and generate a mapping of the condexec bits for each PC in
- * gen_opc_condexec_bits[]. gen_pc_load[] then uses this to restore
- * the condexec bits.
+ * gen_opc_condexec_bits[]. restore_state_to_opc[] then uses
+ * this to restore the condexec bits.
  *
  * Note that there are no instructions which can read the condexec
  * bits, and none which can write non-static values to them, so
@@ -9817,8 +9817,7 @@ void cpu_dump_state(CPUState *env, FILE *f, 
fprintf_function cpu_fprintf,
 #endif
 }
 
-void gen_pc_load(CPUState *env, TranslationBlock *tb,
-unsigned long searched_pc, int pc_pos, void *puc)
+void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
 {
 env->regs[15] = gen_opc_pc[pc_pos];
 env->condexec_bits = gen_opc_condexec_bits[pc_pos];
diff --git a/target-cris/translate.c b/target-cris/translate.c
index 1c03fa5..e2607d6 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -3604,8 +3604,7 @@ void cpu_reset (CPUCRISState *env)
 #endif
 }
 
-void gen_pc_load(CPUState *env, struct TranslationBlock *tb,
- unsigned long searched_pc, int pc_pos, void *puc)
+void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
 {
env->pc = gen_opc_pc[pc_pos];
 }
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 7d1340e..199302e 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -7890,8 +7890,7 @@ void gen_intermediate_code_pc(CPUState *env, 
TranslationBlock *tb)
 gen_intermediate_code_internal(env, tb, 1);
 }
 
-void gen_pc_load(CPUState *env, TranslationBlock *tb,
-unsigned long searched_pc, int pc_pos, void *puc)
+void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
 {
 int cc_op;
 #ifdef DEBUG_DISAS
@@ -7903,8 +7902,8 @@ void gen_pc_load(CPUState *env, TranslationBlock *tb,
 qemu_log("0x%04x: " TARGET_FMT_lx "\n", i, gen_opc_pc[i]);
 }
 }
-qemu_log("spc=0x%08lx pc_pos=0x%x eip=" TARGET_FMT_lx " cs_base=%x\n",
-searched_pc, pc_pos, gen_opc_pc[pc_pos] - tb->cs

Re: [Qemu-devel] [PATCH] Remove unneeded function parameter from gen_pc_load

2011-04-18 Thread Stefan Weil

Am 17.04.2011 23:43, schrieb Aurelien Jarno:

On Sun, Apr 17, 2011 at 10:34:47PM +0100, Peter Maydell wrote:

On 17 April 2011 22:07, Stefan Weil  wrote:

Am 17.04.2011 20:27, schrieb Aurelien Jarno:


On Thu, Apr 14, 2011 at 08:50:00PM +0200, Stefan Weil wrote:


Am 13.04.2011 23:05, schrieb Peter Maydell:


On 13 April 2011 21:38, Stefan Weil  wrote:


gen_pc_load was introduced in commit
d2856f1ad4c259e5766847c49acbb4e390731bd4.
The only reason for parameter searched_pc was
a debug statement in target-i386/translate.c.

Remove searched_pc from the debug statement
and from the parameter list of gen_pc_load.


No issues with the meat of the patch, but if we're going to
change all the callers and implementations of this anyway,
is there any appetite for giving it a more appropriate name?
It doesn't generate any code, it affects more than just the
pc, and it doesn't do a load...

restore_state_to_opc() ? set_env_for_opc() ?

-- PMM



What about cpu_restore_pc()? That's not always the whole truth,
but it's always the main action done in function n.n. which currently
is called gen_pc_load.

Or cpu_restore_helper()? Helper is very generic - it always fits.

Aurelien, please feel free to choose a name which suits bests.
I don't mind if you simply patch my patch, create a new one
or tell me which name should go into a new version of the patch
so I can send it.



As Peter said, the function is doing more than simply restoring the
pc. I am fine with the name he proposed, I think restore_state_to_opc()
is a bit better.


Ok, so I'll send a new patch which also replaces gen_pc_load
by restore_state_to_op.


That's _to_opc, not _to_op : I was trying to be consistent with
the naming of the gen_opc_* arrays.



Oops, sorry, just a cut & paste mistake.


I agree, but it was my mistake.

The first of the following patches is an improved version of my previous 
patch.
It uses the correct name restore_state_to_opc and also removes a second 
parameter.


The second patch is based on the first and removes a parameter
from another function.

[PATCH 1/2] Remove unused function parameters from gen_pc_load and 
rename the function

[PATCH 2/2] Remove unused function parameter from cpu_restore_state

Cheers,
Stefan W.




Re: [Qemu-devel] [PATCH 03/17] linux-user: define a couple of syscalls for non-uid16 targets

2011-04-18 Thread Riku Voipio
On Fri, Apr 15, 2011 at 05:32:44PM +0200, Alexander Graf wrote:
> From: Ulrich Hecht 
> 
> Quite a number of syscalls are only defined on systems with USE_UID16
> defined; this patch defines them on other systems as well.
> 
> Fixes a large number of uid/gid-related testcases on the s390x target
> (and most likely on other targets as well)

I'll provide cleaner patch for the same effect. This one makes the code
more ifdeffed and harder to follow.
 
> Signed-off-by: Ulrich Hecht 
> 
> ---
> 
> v3 -> v4:
> 
>   - remove linux-user host bits
> ---
>  linux-user/syscall.c |  125 
> ++
>  1 files changed, 105 insertions(+), 20 deletions(-)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 504b26c..99f5935 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -326,7 +326,7 @@ static int sys_fchmodat(int dirfd, const char *pathname, 
> mode_t mode)
>return (fchmodat(dirfd, pathname, mode, 0));
>  }
>  #endif
> -#if defined(TARGET_NR_fchownat) && defined(USE_UID16)
> +#if defined(TARGET_NR_fchownat)
>  static int sys_fchownat(int dirfd, const char *pathname, uid_t owner,
>  gid_t group, int flags)
>  {
> @@ -435,7 +435,7 @@ _syscall3(int,sys_faccessat,int,dirfd,const char 
> *,pathname,int,mode)
>  #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
>  _syscall3(int,sys_fchmodat,int,dirfd,const char *,pathname, mode_t,mode)
>  #endif
> -#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) && 
> defined(USE_UID16)
> +#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
>  _syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
>uid_t,owner,gid_t,group,int,flags)
>  #endif
> @@ -6817,18 +6817,35 @@ abi_long do_syscall(void *cpu_env, int num, abi_long 
> arg1,
>  case TARGET_NR_setfsgid:
>  ret = get_errno(setfsgid(arg1));
>  break;
> +#else /* USE_UID16 */
> +#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
> +case TARGET_NR_fchownat:
> +if (!(p = lock_user_string(arg2)))
> +goto efault;
> +ret = get_errno(sys_fchownat(arg1, p, arg3, arg4, arg5));
> +unlock_user(p, arg2, 0);
> +break;
> +#endif
>  #endif /* USE_UID16 */
>  
> -#ifdef TARGET_NR_lchown32
> +#if defined(TARGET_NR_lchown32) || !defined(USE_UID16)
> +#if defined(TARGET_NR_lchown32)
>  case TARGET_NR_lchown32:
> +#else
> +case TARGET_NR_lchown:
> +#endif
>  if (!(p = lock_user_string(arg1)))
>  goto efault;
>  ret = get_errno(lchown(p, arg2, arg3));
>  unlock_user(p, arg1, 0);
>  break;
>  #endif
> -#ifdef TARGET_NR_getuid32
> +#if defined(TARGET_NR_getuid32) || (defined(TARGET_NR_getuid) && 
> !defined(USE_UID16))
> +#if defined(TARGET_NR_getuid32)
>  case TARGET_NR_getuid32:
> +#else
> +case TARGET_NR_getuid:
> +#endif
>  ret = get_errno(getuid());
>  break;
>  #endif
> @@ -6973,33 +6990,57 @@ abi_long do_syscall(void *cpu_env, int num, abi_long 
> arg1,
>  break;
>  #endif
>  
> -#ifdef TARGET_NR_getgid32
> +#if defined(TARGET_NR_getgid32) || (defined(TARGET_NR_getgid) && 
> !defined(USE_UID16))
> +#if defined(TARGET_NR_getgid32)
>  case TARGET_NR_getgid32:
> +#else
> +case TARGET_NR_getgid:
> +#endif
>  ret = get_errno(getgid());
>  break;
>  #endif
> -#ifdef TARGET_NR_geteuid32
> +#if defined(TARGET_NR_geteuid32) || (defined(TARGET_NR_geteuid) && 
> !defined(USE_UID16))
> +#if defined(TARGET_NR_geteuid32)
>  case TARGET_NR_geteuid32:
> +#else
> +case TARGET_NR_geteuid:
> +#endif
>  ret = get_errno(geteuid());
>  break;
>  #endif
> -#ifdef TARGET_NR_getegid32
> +#if defined(TARGET_NR_getegid32) || (defined(TARGET_NR_getegid) && 
> !defined(USE_UID16))
> +#if defined(TARGET_NR_getegid32)
>  case TARGET_NR_getegid32:
> +#else
> +case TARGET_NR_getegid:
> +#endif
>  ret = get_errno(getegid());
>  break;
>  #endif
> -#ifdef TARGET_NR_setreuid32
> +#if defined(TARGET_NR_setreuid32) || !defined(USE_UID16)
> +#if defined(TARGET_NR_setreuid32)
>  case TARGET_NR_setreuid32:
> +#else
> +case TARGET_NR_setreuid:
> +#endif
>  ret = get_errno(setreuid(arg1, arg2));
>  break;
>  #endif
> -#ifdef TARGET_NR_setregid32
> +#if defined(TARGET_NR_setregid32) || !defined(USE_UID16)
> +#if defined(TARGET_NR_setregid32)
>  case TARGET_NR_setregid32:
> +#else
> +case TARGET_NR_setregid:
> +#endif
>  ret = get_errno(setregid(arg1, arg2));
>  break;
>  #endif
> -#ifdef TARGET_NR_getgroups32
> +#if defined(TARGET_NR_getgroups32) || !defined(USE_UID16)
> +#if defined(TARGET_NR_getgroups32)
>  case TARGET_NR_getgroups32:
> +#else
> +case TARGET_NR_getgroups:
> +#endif
>  {
>  int gidsetsize = arg1;
>  uint32_t *target_grouplist;
> @@ -7023,8 +7064,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long 
> arg1,
>  }
>  break

Re: [Qemu-devel] [PATCH] acpi_piix4: fix save/load of PIIX4PMState

2011-04-18 Thread Juan Quintela
Isaku Yamahata  wrote:
> It's vmstate parameter was wrong. This patch fixes it.
>
> Reported-by: Avi Kivity 
> Signed-off-by: Isaku Yamahata 
> ---
>  hw/acpi_piix4.c |3 +--
>  1 files changed, 1 insertions(+), 2 deletions(-)
>
> diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
> index 96f5222..3a8fece 100644
> --- a/hw/acpi_piix4.c
> +++ b/hw/acpi_piix4.c
> @@ -214,10 +214,9 @@ static int vmstate_acpi_post_load(void *opaque, int 
> version_id)
>   {   \
>   .name   = (stringify(_field)),  \
>   .version_id = 0,\
> - .num= GPE_LEN,  \
>   .info   = &vmstate_info_uint16, \
>   .size   = sizeof(uint16_t), \
> - .flags  = VMS_ARRAY | VMS_POINTER,  \
> + .flags  = VMS_SINGLE | VMS_POINTER, \
>   .offset = vmstate_offset_pointer(_state, _field, uint8_t),
> \


shouldn't last one still be uint16_t?

I guess that on ich9, GPE becomes one array, do you have that code handy
somewhere, just to see what you want to do?

I think that best thing to do at this point is just to revert this whole
patch.  We are creating a new type for uint8_t, that becomes a pointer.
We are not sending the length of that array, so we need to add a new
version/subsection when we add ICH9 anyways.

Seeing what you want to do would help me trying to figure out the best
vmstate aproach.

Thanks, Juan.



Re: [Qemu-devel] iPXE/Etherboot prompts twice for booting?

2011-04-18 Thread Alex Williamson
On Mon, 2011-04-18 at 10:45 +0100, Stefan Hajnoczi wrote:
> On Sat, Apr 16, 2011 at 8:41 PM, Michael Tokarev  wrote:
> > I'm playing with iPXE ROM images again, and see
> > iPXE prompts two times during bootup.  Once like
> > this: "Press Ctrl-B to configure", at early stage,
> > even if -boot n is not selected.  And second time
> > when it actually tries to boot, like "Press Ctrl-B
> > for the command line".
> >
> > The same behavor happens with old Etherboot, with
> > the exception that during init stage it tries to
> > boot too but fails.
> >
> > Any idea how to get rid of that?
> 
> IIRC you need to #define BANNER_TIMEOUT 0 in src/config/general.h.

I think src/local/config/general.h is the preferred location, which is
what the script in my tree does and includes pre-built ipxe images:

https://github.com/awilliam/qemu/tree/ipxe

Alex




Re: [Qemu-devel] [RFC PATCH] implement vmware pvscsi device

2011-04-18 Thread Paolo Bonzini

On 04/18/2011 04:05 PM, Hannes Reinecke wrote:

My proposal would be to implement a full virtio-scsi _host_, and extend
the proposal to be able to handle the transport layer too.


Yes, I have added this independently from Friday to today, and it is why 
I haven't sent the proposal yet.



At the lastest we would need to include a LUN address before the CDB,
and define TMF command values for proper error recovery.


I haven't yet worked out TMF, but I did add a LUN.


That way we could handle hotplug / -unplug via a simple host rescan


It's a bit more complicated because you also want guest-initiated 
unplug, and SAM transport reset events include more than hotplug/unplug.



I couldn't find that in either SPC or SAM indeed. It seems like a
pretty widespread assumption though. Perhaps Nicholas or Hannes know
where it comes from.


96 bytes is a carry-over from scsi parallel. We shouldn't rely
on a fixed length here but rather use an additional pointer/iovec and
length field.

Check SG_IO header on how it's done.


Will do.

Paolo



[Qemu-devel] [Bug 656285] Re: arm-semi mishandling SYS_HEAPINFO

2011-04-18 Thread Peter Maydell
I've just submitted a patchset which I think fixes this bug (among
others):

http://patchwork.ozlabs.org/patch/91789/ [1/3] linux-user: Don't use MAP_FIXED 
in do_brk()
http://patchwork.ozlabs.org/patch/91790/ [2/3] arm-semi.c: Use correct check 
for failure of do_brk()
http://patchwork.ozlabs.org/patch/91793/ [3/3] m68k-semi.c: Use correct check 
for failure of do_brk()

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

Title:
  arm-semi mishandling SYS_HEAPINFO

Status in QEMU:
  New

Bug description:
  I am running qemu-arm on a 32-bit fedora-7 i386 machine:

  $ /home/bri0633/users/clarkes/qemu/build/arm-linux-user/qemu-arm --version
  qemu-arm version 0.12.3, Copyright (c) 2003-2008 Fabrice Bellard

  When I try to run an arm semi-hosted executable, I sometimes get
  unexpected segv and sometimes not, depending on the executable.  The
  symptom is:

  $ /home/bri0633/users/clarkes/qemu/build/arm-linux-user/qemu-arm -cpu 
cortex-a9 -- a.out
  qemu: uncaught target signal 11 (Segmentation fault) - core dumped
  Segmentation fault

  
  It appear to be because of the handling of the SYS_HEAPINFO syscall in 
arm-semi.c.  There it tries to allocate 128M for the heap by calling do_brk() 
which calls target_mmap().  This is the DEBUG_MMAP diagnostic:

  mmap: start=0x9000 len=0x08001000 prot=rw- flags=MAP_FIXED
  MAP_ANON MAP_PRIVATE fd=0 offset=

  but this mmap is failing because there are shared libraries (and the
  gate page) mapped there:

  $ ldd /home/bri0633/users/clarkes/qemu/build/arm-linux-user/qemu-arm
  linux-gate.so.1 =>  (0x0088)
  librt.so.1 => /lib/librt.so.1 (0x03409000)
  libpthread.so.0 => /lib/libpthread.so.0 (0x00d7d000)
  libm.so.6 => /lib/libm.so.6 (0x00d4b000)
  libc.so.6 => /lib/libc.so.6 (0x00bf5000)
  /lib/ld-linux.so.2 (0x00bd6000)

  However, it seems that the code in arm-semi.c does not interpret the result 
of do_brk() correctly, and thinks that the mapping succeeded.
  The following patch appears to fix the problem:

  $ diff -u arm-semi.c.orig arm-semi.c
  --- arm-semi.c.orig 2010-09-21 13:19:15.0 +0100
  +++ arm-semi.c  2010-10-07 13:23:13.0 +0100
  @@ -475,7 +475,7 @@
   /* Try a big heap, and reduce the size if that fails.  */
   for (;;) {
   ret = do_brk(limit);
  -if (ret != -1)
  +if (ret == limit)
   break;
   limit = (ts->heap_base >> 1) + (limit >> 1);
   }

  Do you think this is a genuine bug?
  Steve.



Re: [Qemu-devel] [PULL] Migration of misc devices

2011-04-18 Thread Jan Kiszka
On 2011-04-18 17:44, Anthony Liguori wrote:
> On 04/18/2011 10:36 AM, Jan Kiszka wrote:
>> On 2011-04-18 17:12, Anthony Liguori wrote:
>>> On 04/17/2011 03:08 PM, Juan Quintela wrote:


 The following changes since commit 
 a0102082de4026833afbd2525e8a6320d1f92885:

   usb: fix spelling errors in usb-linux.c (2011-04-16 12:24:28 +0100)

 are available in the git repository at:
   git://repo.or.cz/qemu/quintela.git vmstate-misc-devices-v2
>>>
>>> Migration appears to be broken for me.  It's not caused by this series
>>> but I'm surprised you didn't encounter it.  Maybe it's my kernel version?
>>>
>>> My suspicion is that the cause of this is:
>>>
>>> commit 0ec329dab938e2d97d12a91f8ed15fec27b325e0
>>> Author: Jan Kiszka 
>>> Date:   Mon Feb 7 12:19:26 2011 +0100
>>>
>>> kvm: x86: Introduce kvmclock device to save/restore its state
>>
>> Can you prove your suspicion a bit by retrying with -cpu ...,-kvmclock?
>> Is your guest using kvmclock? Are you migrating from old to new or
>> between new versions?
> 
> Heh, it turns out I was migrating from KVM to TCG :-)
> 
> This changeset "breaks" that but I don't think I'd count this as a
> supported use-case so I don't count it as a regression.

I would say it now breaks earlier and less subtly. :)

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux



[Qemu-devel] [PATCH 3/3] m68k-semi.c: Use correct check for failure of do_brk()

2011-04-18 Thread Peter Maydell
In the m68k semihosting implementation of HOSTED_INIT_SIM, use the correct
check for whether do_brk() has failed -- it does not return -1 but the
previous value of the break limit.

Signed-off-by: Peter Maydell 
---
 m68k-semi.c |5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/m68k-semi.c b/m68k-semi.c
index 0371089..7fde10e 100644
--- a/m68k-semi.c
+++ b/m68k-semi.c
@@ -370,7 +370,7 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
 TaskState *ts = env->opaque;
 /* Allocate the heap using sbrk.  */
 if (!ts->heap_limit) {
-long ret;
+abi_ulong ret;
 uint32_t size;
 uint32_t base;
 
@@ -379,8 +379,9 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
 /* Try a big heap, and reduce the size if that fails.  */
 for (;;) {
 ret = do_brk(base + size);
-if (ret != -1)
+if (ret >= (base + size)) {
 break;
+}
 size >>= 1;
 }
 ts->heap_limit = base + size;
-- 
1.7.1




Re: [Qemu-devel] [PULL] Migration of misc devices

2011-04-18 Thread Anthony Liguori
On 04/18/2011 10:36 AM, Jan Kiszka wrote:
> On 2011-04-18 17:12, Anthony Liguori wrote:
>> On 04/17/2011 03:08 PM, Juan Quintela wrote:
>>>
>>>
>>> The following changes since commit a0102082de4026833afbd2525e8a6320d1f92885:
>>>
>>>   usb: fix spelling errors in usb-linux.c (2011-04-16 12:24:28 +0100)
>>>
>>> are available in the git repository at:
>>>   git://repo.or.cz/qemu/quintela.git vmstate-misc-devices-v2
>>
>> Migration appears to be broken for me.  It's not caused by this series
>> but I'm surprised you didn't encounter it.  Maybe it's my kernel version?
>>
>> My suspicion is that the cause of this is:
>>
>> commit 0ec329dab938e2d97d12a91f8ed15fec27b325e0
>> Author: Jan Kiszka 
>> Date:   Mon Feb 7 12:19:26 2011 +0100
>>
>> kvm: x86: Introduce kvmclock device to save/restore its state
> 
> Can you prove your suspicion a bit by retrying with -cpu ...,-kvmclock?
> Is your guest using kvmclock? Are you migrating from old to new or
> between new versions?

Heh, it turns out I was migrating from KVM to TCG :-)

This changeset "breaks" that but I don't think I'd count this as a
supported use-case so I don't count it as a regression.

So ignore the noise here.

Regards,

Anthony Liguori

> Jan
> 




Re: [Qemu-devel] [PATCH] set VIRTIO_BALLOON_F_MUST_TELL_HOST unconditionally

2011-04-18 Thread Dave Hansen
On Fri, 2011-04-15 at 14:20 -0500, Anthony Liguori wrote: 
> On 04/15/2011 02:15 PM, Dave Hansen wrote:
> > On Fri, 2011-04-15 at 12:17 -0500, Anthony Liguori wrote:
> >> If you're in OOM and you need memory, you can't ask the host for more
> >> and wait for a response.  You have to reclaim it immediately.
> > Why not?  The call in to the notifier chain the s390 case is
> > synchronous.  The OOM only affects one task at a time and won't proceed
> > elsewhere while this is going on.
> 
> Because if we tell the host, we have to wait for the host to ack which 
> means we'd sleep waiting for an interrupt.  Can you do this in the OOM path?

Sure.  One of the s390 handlers sleeps today.

> > Why do we even _tell_ qemu, though?  The MADV_WILLNEED is nice, but far
> > from being necessary.  We could just skip the entire notification in OOM
> > situations.
> 
> There's really no particular reason to other than symmetry.

When we get there, it sounds like we can simply _skip_ the notification
in the qemu case.  

-- Dave






Re: [Qemu-devel] [PULL] Migration of misc devices

2011-04-18 Thread Jan Kiszka
On 2011-04-18 17:12, Anthony Liguori wrote:
> On 04/17/2011 03:08 PM, Juan Quintela wrote:
>>
>>
>> The following changes since commit a0102082de4026833afbd2525e8a6320d1f92885:
>>
>>   usb: fix spelling errors in usb-linux.c (2011-04-16 12:24:28 +0100)
>>
>> are available in the git repository at:
>>   git://repo.or.cz/qemu/quintela.git vmstate-misc-devices-v2
> 
> Migration appears to be broken for me.  It's not caused by this series
> but I'm surprised you didn't encounter it.  Maybe it's my kernel version?
> 
> My suspicion is that the cause of this is:
> 
> commit 0ec329dab938e2d97d12a91f8ed15fec27b325e0
> Author: Jan Kiszka 
> Date:   Mon Feb 7 12:19:26 2011 +0100
> 
> kvm: x86: Introduce kvmclock device to save/restore its state

Can you prove your suspicion a bit by retrying with -cpu ...,-kvmclock?
Is your guest using kvmclock? Are you migrating from old to new or
between new versions?

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux



Re: [Qemu-devel] KVM call agenda for April 19th

2011-04-18 Thread Antonio Galindo Castro
Tools for resource accounting the virtual machines.

Fingerprint 35C0 49D6 E879 1F30 2FC3  0313 58C0 8857 4681 A236
Luis Antonio Galindo Castro (FunkyM0nk3y) 

On Mon, Apr 18, 2011 at 04:46, Juan Quintela  wrote:

>
> Please, send in any agenda items you are interested in covering.
>
> Later, Juan.
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


[Qemu-devel] [PATCH 0/3] Fix ARM semihosting SYS_HEAPINFO issues

2011-04-18 Thread Peter Maydell
This patchset is intended to fix some problems with the ARM
semihosting SYS_HEAPINFO call. Patch 1 fixes a bug in do_brk()
which meant that using SYS_HEAPINFO tended to result in our
accidentally unmapping the host libc. Patch 2 fixes the
bug https://bugs.launchpad.net/qemu/+bug/656285
by correcting the check for failure of do_brk(). Patch 3
does the same for the equivalent code in m68k-semi.c, but
note that I have only tested that it compiles.

(linux-user/m68k-sim.c also has a suspicious error check
on do_brk(), but since I don't have any specs of what the
simcalls there are supposed to do on error I haven't
attempted to fix this one.)

Peter Maydell (3):
  linux-user: Don't use MAP_FIXED in do_brk()
  arm-semi.c: Use correct check for failure of do_brk()
  m68k-semi.c: Use correct check for failure of do_brk()

 arm-semi.c   |5 +++--
 linux-user/syscall.c |   29 -
 m68k-semi.c  |5 +++--
 3 files changed, 26 insertions(+), 13 deletions(-)




[Qemu-devel] [PATCH 2/3] arm-semi.c: Use correct check for failure of do_brk()

2011-04-18 Thread Peter Maydell
In the ARM semihosting implementation of SYS_HEAPINFO, use the correct
check for whether do_brk() has failed -- it does not return -1 but the
previous value of the break limit.

Signed-off-by: Peter Maydell 
---
 arm-semi.c |5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/arm-semi.c b/arm-semi.c
index e9e6f89..5a62d03 100644
--- a/arm-semi.c
+++ b/arm-semi.c
@@ -440,15 +440,16 @@ uint32_t do_arm_semihosting(CPUState *env)
 /* Some C libraries assume the heap immediately follows .bss, so
allocate it using sbrk.  */
 if (!ts->heap_limit) {
-long ret;
+abi_ulong ret;
 
 ts->heap_base = do_brk(0);
 limit = ts->heap_base + ARM_ANGEL_HEAP_SIZE;
 /* Try a big heap, and reduce the size if that fails.  */
 for (;;) {
 ret = do_brk(limit);
-if (ret != -1)
+if (ret >= limit) {
 break;
+}
 limit = (ts->heap_base >> 1) + (limit >> 1);
 }
 ts->heap_limit = limit;
-- 
1.7.1




[Qemu-devel] [PATCH 1/3] linux-user: Don't use MAP_FIXED in do_brk()

2011-04-18 Thread Peter Maydell
Since mmap() with MAP_FIXED will map over the top of existing mappings,
it's a bad idea to use it to implement brk(), because brk() with a
large size is likely to overwrite important things like qemu itself
or the host libc. So we drop MAP_FIXED and handle "mapped but at
different address" as an error case instead.

Signed-off-by: Peter Maydell 
---
 linux-user/syscall.c |   29 -
 1 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index bb0999d..e68c5e0 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -733,23 +733,34 @@ abi_long do_brk(abi_ulong new_brk)
return target_brk;
 }
 
-/* We need to allocate more memory after the brk... */
+/* We need to allocate more memory after the brk... Note that
+ * we don't use MAP_FIXED because that will map over the top of
+ * any existing mapping (like the one with the host libc or qemu
+ * itself); instead we treat "mapped but at wrong address" as
+ * a failure and unmap again.
+ */
 new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
 mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
 PROT_READ|PROT_WRITE,
-MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
+MAP_ANON|MAP_PRIVATE, 0, 0));
+
+if (mapped_addr == brk_page) {
+target_brk = new_brk;
+return target_brk;
+} else if (mapped_addr != -1) {
+/* Mapped but at wrong address, meaning there wasn't actually
+ * enough space for this brk.
+ */
+target_munmap(mapped_addr, new_alloc_size);
+mapped_addr = -1;
+}
 
 #if defined(TARGET_ALPHA)
 /* We (partially) emulate OSF/1 on Alpha, which requires we
return a proper errno, not an unchanged brk value.  */
-if (is_error(mapped_addr)) {
-return -TARGET_ENOMEM;
-}
+return -TARGET_ENOMEM;
 #endif
-
-if (!is_error(mapped_addr)) {
-   target_brk = new_brk;
-}
+/* For everything else, return the previous break. */
 return target_brk;
 }
 
-- 
1.7.1




Re: [Qemu-devel] [RFC PATCH] implement vmware pvscsi device

2011-04-18 Thread Stefan Hajnoczi
On Mon, Apr 18, 2011 at 3:05 PM, Hannes Reinecke  wrote:
> On 04/15/2011 10:56 PM, Paolo Bonzini wrote:
>>
>> On 04/15/2011 05:04 PM, Stefan Hajnoczi wrote:
>>>
>>> The way I approached virtio-scsi was to look at the SCSI Architecture
>>> Model document and some of the Linux SCSI code. I'm not sure if
>>> letting virtio-blk SCSI pass-through or scsi-generic guide us is a
>>> good approach.
>>>
>>> How do your ioprio and barrier relate to SCSI?
>>
>> Both are part of the transport protocol, which can provide
>> additional features with respect to SAM. For example SCSI doesn't
>> provide the full details of hotplug/hotunplug, or doesn't have a way
>> for the guest to trigger a drive unplug on the host, but these are
>> all desirable features for virtio-scsi (and they are supported by
>> vmw_pvscsi by the way).
>>
> And this is something I really miss in the current proposals, namely
> a working transport layer.
>
> The SCSI spec (SPC etc) itself just handles command delivery between
> initiator and target. Anything else (like hotplug, error recovery, target
> addressing etc) is out of the scope of the spec and needs to be implemented
> on another layer (that's the ominous
> transport layer).
>
> Hence any protocol implemented to the above spec would be missing those
> parts, and they would need to be implemented additionally.
> Which also explains why these features are missing when just using SCSI CDBs
> as the main command container.
>
> My proposal would be to implement a full virtio-scsi _host_, and extend the
> proposal to be able to handle the transport layer too.
> At the lastest we would need to include a LUN address before the CDB, and
> define TMF command values for proper error recovery.
>
> That way we could handle hotplug / -unplug via a simple host rescan, and
> would even be able to pass-in NPIV hosts.

In my prototype there is a header and a footer for the request and
response, respectively:
http://git.kernel.org/?p=linux/kernel/git/nab/lio-core-2.6.git;a=blob;f=include/linux/virtio_scsi.h;hb=refs/heads/tcm_vhost

We definitely need more than plain CDB pass-through.

Stefan



Re: [Qemu-devel] [PULL] Migration of misc devices

2011-04-18 Thread Anthony Liguori
On 04/17/2011 03:08 PM, Juan Quintela wrote:
> 
> 
> The following changes since commit a0102082de4026833afbd2525e8a6320d1f92885:
> 
>   usb: fix spelling errors in usb-linux.c (2011-04-16 12:24:28 +0100)
> 
> are available in the git repository at:
>   git://repo.or.cz/qemu/quintela.git vmstate-misc-devices-v2

Migration appears to be broken for me.  It's not caused by this series
but I'm surprised you didn't encounter it.  Maybe it's my kernel version?

My suspicion is that the cause of this is:

commit 0ec329dab938e2d97d12a91f8ed15fec27b325e0
Author: Jan Kiszka 
Date:   Mon Feb 7 12:19:26 2011 +0100

kvm: x86: Introduce kvmclock device to save/restore its state

Regards,

Anthony Liguori

> Juan Quintela (45):
>   vmstate: port adb_kbd
>   vmstate: port adb_mouse
>   vmstate: port ads7846
>   vmstate: port m48t59
>   vmstate: port mipsnet
>   vmstate: port arm sp804
>   vmstate: port arm_timer
>   vmstate: port sysborg_timer
>   vmstate: port pmtimer
>   vmstate: port syborg_rtc
>   vmstate: port pxa2xx_keypad
>   vmstate: port pl011
>   vmstate: port armv7m nvic
>   vmstate: port stellaris i2c
>   vmstate: port stellaris ssi bus
>   vmstate: port stellaris sys
>   vmstate: port pl022 ssp
>   vmstate: port heathrow_pic
>   vmstate: port cuda
>   vmstate: port stellaris gptm
>   vmstate: port pxa2xx_i2s
>   vmstate: port pxa2xx_cm
>   vmstate: port pxa2xx_mm
>   vmstate: port pxa2xx_pm
>   vmstate: port ppce500_pci
>   vmstate: port ppc4xx_pci
>   vmstate: port syborg_pointer
>   vmstate: port stellaris_adc
>   vmstate: port syborg_serial
>   vmstate: port syborg_keyboard
>   vmstate: port stellaris gamepad
>   vmstate: stellaris use unused for placeholder entries
>   pxa2xx_lcd: name anonymous struct
>   pxa2xx_lcd: up field is used as a bool and migrated as an uint8_t
>   vmstate: port pxa2xx_lcd
>   max111x: input field is only used as uint8_t
>   vmstate: port max111x
>   nand: pin values are uint8_t
>   vmstate: port nand
>   mac_nvram: size is a size, no need to be a target dependent type
>   vmstate: port mac_nvram
>   piix4: create PIIX4State
>   vmstate: port piix4
>   mac_dbdma: create DBDMAState instead of passing one array around
>   vmstate: port mac_dbdma
> 
>  hw/adb.c |   83 +-
>  hw/ads7846.c |   41 +++
>  hw/arm_timer.c   |   66 ---
>  hw/armv7m_nvic.c |   39 ++
>  hw/cuda.c|  116 +++---
>  hw/flash.h   |4 +-
>  hw/heathrow_pic.c|   62 --
>  hw/hw.h  |   17 ++-
>  hw/m48t59.c  |   36 ++
>  hw/mac_dbdma.c   |   83 +++--
>  hw/mac_nvram.c   |   32 ++---
>  hw/max111x.c |   51 +++-
>  hw/mipsnet.c |   53 +++--
>  hw/nand.c|   79 +++--
>  hw/piix4.c   |   44 
>  hw/pl011.c   |   76 
>  hw/pl022.c   |   84 ++
>  hw/ppc4xx_pci.c  |   80 ++---
>  hw/ppce500_pci.c |   87 ++
>  hw/ptimer.c  |   59 +++---
>  hw/pxa2xx.c  |  158 +
>  hw/pxa2xx_keypad.c   |   53 +++--
>  hw/pxa2xx_lcd.c  |  138 +-
>  hw/stellaris.c   |  323 
> +-
>  hw/stellaris_input.c |   50 
>  hw/syborg_keyboard.c |   57 +++--
>  hw/syborg_pointer.c  |   73 +---
>  hw/syborg_rtc.c  |   34 ++
>  hw/syborg_serial.c   |   60 +++---
>  hw/syborg_timer.c|   46 +++-
>  qemu-timer.h |2 -
>  31 files changed, 854 insertions(+), 1332 deletions(-)
> 
> 




[Qemu-devel] [RFC][PATCH v2 11/17] qmp proxy: build QEMU with qmp proxy

2011-04-18 Thread Michael Roth

Signed-off-by: Michael Roth 
---
 Makefile.objs |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/Makefile.objs b/Makefile.objs
index df7e670..f143bd8 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -103,6 +103,7 @@ common-obj-y += block-migration.o
 common-obj-y += pflib.o
 common-obj-y += qmp-marshal.o qmp-marshal-types.o
 common-obj-y += qmp-marshal-types-core.o qmp-core.o
+common-obj-y += qmp-proxy.o
 common-obj-y += hmp.o
 
 common-obj-$(CONFIG_BRLAPI) += baum.o
-- 
1.7.0.4




[Qemu-devel] [RFC][PATCH v2 17/17] guest agent: build qemu-ga, add QEMU-wide gio dep

2011-04-18 Thread Michael Roth
This allows us to build qemu-ga with "make qemu-ga". It pulls in the
qemu-tools deps, but does not currently build by default. This may
change to avoid bitrot and help with host-side-only unit tests.

This also pulls in gio dependences for all of qemu, currently we only
pull in gthread. In general this brings in gio, gmodule, and
gobject.

Can limit this to only the guest agent, but it's expected that all of
these will be needed as we start relying more on glib throughout qemu,
so leaving for now.

Signed-off-by: Michael Roth 
---
 Makefile  |   15 +--
 configure |6 +++---
 2 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/Makefile b/Makefile
index d510779..a7c1503 100644
--- a/Makefile
+++ b/Makefile
@@ -173,10 +173,10 @@ libqmp.h: $(SRC_PATH)/qapi-schema.json 
$(SRC_PATH)/qmp-gen.py
 libqmp.c: $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qmp-gen.py
$(call quiet-command,python $(SRC_PATH)/qmp-gen.py --lib-body $@ < $<, 
"  GEN   $@")
 
-guest-agent.h: $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qmp-gen.py
+qga/guest-agent.h: $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qmp-gen.py
$(call quiet-command,python $(SRC_PATH)/qmp-gen.py --guest-header $@ < 
$<, "  GEN   $@")
 
-guest-agent.c: $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qmp-gen.py
+qga/guest-agent.c: $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qmp-gen.py
$(call quiet-command,python $(SRC_PATH)/qmp-gen.py --guest-body $@ < 
$<, "  GEN   $@")
 
 qdev-marshal.h: $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qmp-gen.py
@@ -206,6 +206,7 @@ libqmp.o: libqmp.c libqmp.h qapi-types.h
 qdev-marshal.o: qdev-marshal.c qdev-marshal.h qapi-types.h
 qcfg-marshal.o: qcfg-marshal.c qcfg-marshal.h qapi-types.h
 qcfg-opts.o: qcfg-opts.c qcfg-opts.h qcfg-marshal.h qapi-types.h
+qemu-ga.o: qga/guest-agent.c qga/guest-agent.h qmp-marshal-types.c 
qmp-marshal-types.h
 
 version.o: $(SRC_PATH)/version.rc config-host.mak
$(call quiet-command,$(WINDRES) -I. -o $@ $<,"  RC$(TARGET_DIR)$@")
@@ -214,7 +215,9 @@ version-obj-$(CONFIG_WIN32) += version.o
 ##
 
 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-ga$(EXESUF): qemu-ga.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 qemu-sockets.o qmp-marshal-types-core.o qmp-marshal-types.o 
qga/guest-agent.o qga/guest-agent-core.o qga/guest-agent-commands.o 
qga/guest-agent-command-state.o qga/guest-agent-worker.o
 
 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
 
@@ -276,8 +279,8 @@ 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 $(TOOLS) TAGS cscope.* *.pod *~ */*~
-   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 *.o *.d *.a $(TOOLS) qemu-ga TAGS cscope.* *.pod *~ */*~
+   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 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
@@ -463,4 +466,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/configure b/configure
index d99deb2..bfea356 100755
--- a/configure
+++ b/configure
@@ -1659,9 +1659,9 @@ fi
 
 ##
 # glib support probe
-if $pkg_config --modversion gthread-2.0 > /dev/null 2>&1 ; then
-glib_cflags=`$pkg_config --cflags gthread-2.0 2>/dev/null`
-glib_libs=`$pkg_config --libs gthread-2.0 2>/dev/null`
+if $pkg_config --modversion gthread-2.0 gio-2.0 > /dev/null 2>&1 ; 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
-- 
1.7.0.4




[Qemu-devel] [RFC][PATCH v2 14/17] guest agent: core marshal/dispatch interfaces

2011-04-18 Thread Michael Roth
These are basically a stripped-down, guest-side analogue to what's in
qmp_core.c: definitions used by qmp-gen.py-generated marshalling code to
handle dispatch and a registration of command->function mappings (minus
all the bits related to Qmp sessions/server/events).

As a result of that, there is a little bit of code duplication here.
It wouldn't be difficult to make the common bits shareable, but there
isn't much.

The guest agent will use these interfaces to handle dispatch/execution
of requests it gets from the proxy.

Signed-off-by: Michael Roth 
---
 qga/guest-agent-core.c |  139 
 qga/guest-agent-core.h |   40 ++
 2 files changed, 179 insertions(+), 0 deletions(-)
 create mode 100644 qga/guest-agent-core.c
 create mode 100644 qga/guest-agent-core.h

diff --git a/qga/guest-agent-core.c b/qga/guest-agent-core.c
new file mode 100644
index 000..55498b1
--- /dev/null
+++ b/qga/guest-agent-core.c
@@ -0,0 +1,139 @@
+/*
+ * QEMU Guest Agent core functions
+ *
+ * Copyright IBM Corp. 2011
+ *
+ * Authors:
+ *  Adam Litke
+ *  Michael Roth  
+ *
+ * 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 "guest-agent-core.h"
+
+typedef enum QmpCommandType {
+QCT_NORMAL,
+QCT_ASYNC,
+} QmpCommandType;
+
+typedef struct QmpCommand {
+const char *name;
+QmpCommandType type;
+QmpCommandFunc *fn;
+QmpAsyncCommandFunc *afn;
+QTAILQ_ENTRY(QmpCommand) node;
+} QmpCommand;
+
+static QTAILQ_HEAD(, QmpCommand) qmp_commands =
+QTAILQ_HEAD_INITIALIZER(qmp_commands);
+
+QmpMarshalState *qmp_state_get_mstate(QmpState *sess)
+{
+return NULL;
+}
+
+void qga_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);
+}
+
+static 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;
+}
+
+static QObject *qga_dispatch_err(QObject *request, Error **errp)
+{
+const char *command;
+QDict *args, *dict;
+QmpCommand *cmd;
+QObject *ret = NULL;
+
+if (qobject_type(request) != QTYPE_QDICT) {
+error_set(errp, QERR_JSON_PARSE_ERROR, "request is not a dictionary");
+goto out;
+}
+
+dict = qobject_to_qdict(request);
+if (!qdict_haskey(dict, "execute")) {
+error_set(errp, QERR_JSON_PARSE_ERROR, "no execute key");
+goto out;
+}
+
+command = qdict_get_str(dict, "execute");
+cmd = qmp_find_command(command);
+if (cmd == NULL) {
+error_set(errp, QERR_COMMAND_NOT_FOUND, command);
+goto out;
+}
+
+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(NULL, args, &ret, errp);
+if (ret == NULL) {
+ret = QOBJECT(qdict_new());
+}
+break;
+case QCT_ASYNC: {
+QmpCommandState *s = qemu_mallocz(sizeof(*s));
+/* FIXME save async commands and do something
+ * smart if disconnect occurs before completion
+ */
+s->tag = NULL;
+if (qdict_haskey(dict, "tag")) {
+s->tag = qdict_get(dict, "tag");
+qobject_incref(s->tag);
+}
+cmd->afn(args, errp, s);
+ret = NULL;
+}
+break;
+}
+
+QDECREF(args);
+
+out:
+return ret;
+}
+
+QObject *qga_dispatch(QObject *request, Error **errp)
+{
+Error *err = NULL;
+QObject *ret;
+QDict *rsp;
+
+ret = qga_dispatch_err(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);
+}
diff --git a/qga/guest-agent-core.h b/qga/guest-agent-core.h
new file mode 100644
index 000..51ae798
--- /dev/null
+++ b/qga/guest-agent-core.h
@@ -0,0 +1,40 @@
+/*
+ * QEMU Guest Agent core declarations
+ *
+ * Copyright IBM Corp. 2011
+ *
+ * Authors:
+ *  Adam Litke
+ *  Michael Roth  
+ *
+ * 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 "qmp-core.h"
+#include "qapi-types-core.h"
+#include "qmp-marshal-types-core.h"
+#include "qemu-common.h"
+#include "qdict.h"
+
+#define QGA_VERSION "1.0"
+
+typedef struct GAState GAState;
+typedef struct GACommandState GACommandState;
+typedef struct GAWorker GAWorker;
+typedef void (*ga_w

[Qemu-devel] [RFC][PATCH v2 15/17] guest agent: qemu-ga daemon

2011-04-18 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 
---
 qemu-ga.c |  711 +
 1 files changed, 711 insertions(+), 0 deletions(-)
 create mode 100644 qemu-ga.c

diff --git a/qemu-ga.c b/qemu-ga.c
new file mode 100644
index 000..800d16b
--- /dev/null
+++ b/qemu-ga.c
@@ -0,0 +1,711 @@
+/*
+ * QEMU Guest Agent
+ *
+ * Copyright IBM Corp. 2011
+ *
+ * Authors:
+ *  Adam Litke
+ *  Michael Roth  
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "qemu_socket.h"
+#include "json-streamer.h"
+#include "json-parser.h"
+#include "qga/guest-agent.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 {
+bool active;
+int session_id;
+const char *proxy_path;
+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;
+GAWorker *worker;
+int timeout_ms;
+GLogLevelFlags log_level;
+FILE *log_file;
+};
+
+static void usage(const char *cmd)
+{
+printf(
+"Usage: %s -c \n"
+"QEMU Guest Agent %s\n"
+"\n"
+"  -c, --channel channel method: one of unix-connect, virtio-serial, or\n"
+"isa-serial (virtio-serial is the default)\n"
+"  -p, --pathchannel path (%s is the default for virtio-serial)\n"
+"  -l, --logfile set logfile path, logs to stderr by default\n"
+"  -f, --pidfile specify pidfile (default is %s)\n"
+"  -v, --verbose log extra debugging information\n"
+"  -V, --version print version information and exit\n"
+"  -d, --daemonize   become a daemon\n"
+"  -h, --helpdisplay this help and exit\n"
+"\n"
+"Report bugs to \n"
+, cmd, QGA_VERSION, QGA_VIRTIO_PATH_DEFAULT, QGA_PIDFILE_DEFAULT);
+}
+
+static void conn_channel_close(GAState *s);
+
+static const char *ga_log_level_str(GLogLevelFlags level)
+{
+switch (level & G_LOG_LEVEL_MASK) {
+case G_LOG_LEVEL_ERROR: return "error";
+case G_LOG_LEVEL_CRITICAL:  return "critical";
+case G_LOG_LEVEL_WARNING:   return "warning";
+case G_LOG_LEVEL_MESSAGE:   return "message";
+case G_LOG_LEVEL_INFO:  return "info";
+case G_LOG_LEVEL_DEBUG: return "debug";
+default:return "user";
+}
+}
+
+static void ga_log(const gchar *domain, GLogLevelFlags level,
+   const gchar *msg, gpointer opaque)
+{
+GAState *s = opaque;
+GTimeVal time;
+const char *level_str = ga_log_level_str(level);
+
+level &= G_LOG_LEVEL_MASK;
+if (g_strcmp0(domain, "syslog") == 0) {
+syslog(LOG_INFO, "%s: %s", level_str, msg);
+} else if (level & s->log_level) {
+g_get_current_time(&time);
+fprintf(s->log_file,
+"%lu.%lu: %s: %s\n", time.tv_sec, time.tv_usec, level_str, 
msg);
+fflush(s->log_file);
+}
+}
+
+int ga_get_timeout(GAState *s)
+{
+return s->timeout_ms;
+}
+
+static void become_daemon(const char *pidfile)
+{
+pid_t pid, sid;
+int pidfd;
+char *pidstr = NULL;
+
+pid = fork();
+if (pid < 0) {
+exit(EXIT_FAILURE);
+}
+if (pid > 0) {
+exit(EXIT_SUCCESS);
+}
+
+pidfd = open(pidfile, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR);
+if (!pidfd || lockf(pidfd, F_TLOCK, 0)) {
+g_error("Cannot lock pid file");
+}
+
+if (ftruncate(pidfd, 0) || lseek(pidfd, 0, SEEK_SET)) {
+g_critical("Cannot truncate pid file");
+goto fail;
+}
+if (asprintf(&pidstr, "%d", getpid()) == -1) {
+g_critical("Cannot allocate memory");
+goto fail;
+}
+if (write(pidfd, pidstr, strlen(pidstr)) != strlen(pidstr)) {
+g_critical("Failed to write pid file");
+goto fail;
+}
+
+umask(0);
+sid = setsid();
+if (sid < 0) {
+goto fail;
+}
+if ((chdir("/")) < 0) {
+goto fail;
+}
+
+close(STDIN_FILENO);
+close(STDOUT_FILENO);
+close(STDERR_FILENO);
+retur

[Qemu-devel] [RFC][PATCH v2 03/17] json-parser: add handling for NULL token list

2011-04-18 Thread Michael Roth
Currently a NULL token list will crash the parser, instead we have it
pass back a NULL QObject.

Signed-off-by: Michael Roth 
---
 json-parser.c |6 +-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/json-parser.c b/json-parser.c
index 58e973b..849e215 100644
--- a/json-parser.c
+++ b/json-parser.c
@@ -633,9 +633,13 @@ QObject *json_parser_parse(QList *tokens, va_list *ap)
 QObject *json_parser_parse_err(QList *tokens, va_list *ap, Error **errp)
 {
 JSONParserContext ctxt = {};
-QList *working = qlist_copy(tokens);
+QList *working;
 QObject *result;
 
+if (!tokens) {
+return NULL;
+}
+working = qlist_copy(tokens);
 result = parse_value(&ctxt, &working, ap);
 
 QDECREF(working);
-- 
1.7.0.4




[Qemu-devel] [RFC][PATCH v2 05/17] qapi: fix handling for null-return async callbacks

2011-04-18 Thread Michael Roth
Async commands like 'guest-ping' have NULL retvals. Handle these by
inserting an empty dictionary in the response's "return" field.

Signed-off-by: Michael Roth 
---
 qmp-core.c |5 -
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/qmp-core.c b/qmp-core.c
index e33f7a4..9f3d182 100644
--- a/qmp-core.c
+++ b/qmp-core.c
@@ -922,9 +922,12 @@ void qmp_async_complete_command(QmpCommandState *cmd, 
QObject *retval, Error *er
 rsp = qdict_new();
 if (err) {
 qdict_put_obj(rsp, "error", error_get_qobject(err));
-} else {
+} else if (retval) {
 qobject_incref(retval);
 qdict_put_obj(rsp, "return", retval);
+} else {
+/* add empty "return" dict, this is the standard for NULL returns */
+qdict_put_obj(rsp, "return", QOBJECT(qdict_new()));
 }
 if (cmd->tag) {
 qdict_put_obj(rsp, "tag", cmd->tag);
-- 
1.7.0.4




[Qemu-devel] [RFC][PATCH v2 01/17] json-lexer: make lexer error-recovery more deterministic

2011-04-18 Thread Michael Roth
Currently when we reach an error state we effectively flush everything
fed to the lexer, which can put us in a state where we keep feeding
tokens into the parser at arbitrary offsets in the stream. This makes it
difficult for the lexer/tokenizer/parser to get back in sync when bad
input is made by the client.

With these changes we emit an error state/token up to the tokenizer as
soon as we reach an error state, and continue processing any data passed
in rather than bailing out. The reset token will be used to reset the
tokenizer and parser, such that they'll recover state as soon as the
lexer begins generating valid token sequences again.

We also map chr(192,193,245-255) to an error state here, since they are
invalid UTF-8 characters. QMP guest proxy/agent will use chr(255) to
force a flush/reset of previous input for reliable delivery of certain
events, so also we document that thoroughly here.

Signed-off-by: Michael Roth 
---
 json-lexer.c |   33 -
 json-lexer.h |1 +
 2 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/json-lexer.c b/json-lexer.c
index 3462c89..bede557 100644
--- a/json-lexer.c
+++ b/json-lexer.c
@@ -105,7 +105,8 @@ static const uint8_t json_lexer[][256] =  {
 ['u'] = IN_DQ_UCODE0,
 },
 [IN_DQ_STRING] = {
-[1 ... 0xFF] = IN_DQ_STRING,
+[1 ... 0xBF] = IN_DQ_STRING,
+[0xC2 ... 0xF4] = IN_DQ_STRING,
 ['\\'] = IN_DQ_STRING_ESCAPE,
 ['"'] = JSON_STRING,
 },
@@ -144,7 +145,8 @@ static const uint8_t json_lexer[][256] =  {
 ['u'] = IN_SQ_UCODE0,
 },
 [IN_SQ_STRING] = {
-[1 ... 0xFF] = IN_SQ_STRING,
+[1 ... 0xBF] = IN_SQ_STRING,
+[0xC2 ... 0xF4] = IN_SQ_STRING,
 ['\\'] = IN_SQ_STRING_ESCAPE,
 ['\''] = JSON_STRING,
 },
@@ -305,10 +307,25 @@ static int json_lexer_feed_char(JSONLexer *lexer, char ch)
 new_state = IN_START;
 break;
 case ERROR:
+/* XXX: To avoid having previous bad input leaving the parser in an
+ * unresponsive state where we consume unpredictable amounts of
+ * subsequent "good" input, percolate this error state up to the
+ * tokenizer/parser by forcing a NULL object to be emitted, then
+ * reset state.
+ *
+ * Also note that this handling is required for reliable channel
+ * negotiation between QMP and the guest agent, since chr(0xFF)
+ * is placed at the beginning of certain events to ensure proper
+ * delivery when the channel is in an unknown state. chr(0xFF) is
+ * never a valid ASCII/UTF-8 sequence, so this should reliably
+ * induce an error/flush state.
+ */
+lexer->emit(lexer, lexer->token, JSON_ERROR, lexer->x, lexer->y);
 QDECREF(lexer->token);
 lexer->token = qstring_new();
 new_state = IN_START;
-return -EINVAL;
+lexer->state = new_state;
+return 0;
 default:
 break;
 }
@@ -334,7 +351,6 @@ int json_lexer_feed(JSONLexer *lexer, const char *buffer, 
size_t size)
 
 for (i = 0; i < size; i++) {
 int err;
-
 err = json_lexer_feed_char(lexer, buffer[i]);
 if (err < 0) {
 return err;
@@ -346,7 +362,14 @@ int json_lexer_feed(JSONLexer *lexer, const char *buffer, 
size_t size)
 
 int json_lexer_flush(JSONLexer *lexer)
 {
-return lexer->state == IN_START ? 0 : json_lexer_feed_char(lexer, 0);
+if (lexer->state != IN_START) {
+lexer->state = IN_START;
+QDECREF(lexer->token);
+lexer->token = qstring_new();
+return -EINVAL;
+}
+
+return 0;
 }
 
 void json_lexer_destroy(JSONLexer *lexer)
diff --git a/json-lexer.h b/json-lexer.h
index 3b50c46..10bc0a7 100644
--- a/json-lexer.h
+++ b/json-lexer.h
@@ -25,6 +25,7 @@ typedef enum json_token_type {
 JSON_STRING,
 JSON_ESCAPE,
 JSON_SKIP,
+JSON_ERROR,
 } JSONTokenType;
 
 typedef struct JSONLexer JSONLexer;
-- 
1.7.0.4




[Qemu-devel] [RFC][PATCH v2 13/17] guest agent: command state class

2011-04-18 Thread Michael Roth

Signed-off-by: Michael Roth 
---
 qga/guest-agent-command-state.c |   73 +++
 1 files changed, 73 insertions(+), 0 deletions(-)
 create mode 100644 qga/guest-agent-command-state.c

diff --git a/qga/guest-agent-command-state.c b/qga/guest-agent-command-state.c
new file mode 100644
index 000..997355e
--- /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  
+ *
+ * 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 
+#include "guest-agent.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 = g_malloc0(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 = g_malloc0(sizeof(GACommandState));
+cs->groups = NULL;
+return cs;
+}
-- 
1.7.0.4




[Qemu-devel] [RFC][PATCH v2 02/17] json-streamer: add handling for JSON_ERROR token/state

2011-04-18 Thread Michael Roth
This allows a JSON_ERROR state to be passed to the streamer to force a
flush of the current tokens and pass a NULL token list to the parser
rather that have it churn on bad data. (Alternatively we could just not
pass it to the parser at all, but it may be useful to push there errors
up the stack. NULL token lists are not currently handled by the parser,
the next patch will address that)

Signed-off-by: Michael Roth 
---
 json-streamer.c |   35 +++
 1 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/json-streamer.c b/json-streamer.c
index a6cb28f..c255c78 100644
--- a/json-streamer.c
+++ b/json-streamer.c
@@ -56,29 +56,40 @@ static void json_message_process_token(JSONLexer *lexer, 
QString *token, JSONTok
 
 qlist_append(parser->tokens, dict);
 
-if (parser->brace_count < 0 ||
+if (type == JSON_ERROR) {
+goto out_emit_bad;
+} else if (parser->brace_count < 0 ||
 parser->bracket_count < 0 ||
 (parser->brace_count == 0 &&
  parser->bracket_count == 0)) {
-parser->brace_count = 0;
-parser->bracket_count = 0;
-parser->emit(parser, parser->tokens);
-QDECREF(parser->tokens);
-parser->tokens = qlist_new();
-parser->token_size = 0;
+goto out_emit;
 } else if (parser->token_size > MAX_TOKEN_SIZE ||
parser->bracket_count > MAX_NESTING ||
parser->brace_count > MAX_NESTING) {
 /* Security consideration, we limit total memory allocated per object
  * and the maximum recursion depth that a message can force.
  */
-parser->brace_count = 0;
-parser->bracket_count = 0;
-parser->emit(parser, parser->tokens);
+goto out_emit;
+}
+
+return;
+
+out_emit_bad:
+/* clear out token list and tell the parser to emit and error
+ * indication by passing it a NULL list
+ */
+QDECREF(parser->tokens);
+parser->tokens = NULL;
+out_emit:
+/* send current list of tokens to parser and reset tokenizer */
+parser->brace_count = 0;
+parser->bracket_count = 0;
+parser->emit(parser, parser->tokens);
+if (parser->tokens) {
 QDECREF(parser->tokens);
-parser->tokens = qlist_new();
-parser->token_size = 0;
 }
+parser->tokens = qlist_new();
+parser->token_size = 0;
 }
 
 void json_message_parser_init(JSONMessageParser *parser,
-- 
1.7.0.4




[Qemu-devel] [RFC][PATCH v2 10/17] qmp proxy: add qmp_proxy chardev

2011-04-18 Thread Michael Roth
This allows qemu to be started with guest agent support via:

qemu -chardev qmp_proxy,id=qmp_proxy -device ...,chardev=qmp_proxy

Writes to the guest agent are buffered, with deferred work handled by a
timer. Writes from the guest agent to host/proxy are passed directly
into a JSON streamer object/buffer.

The chardev is intended for use with virtio-serial or isa-serial
channels. Other uses may be possible with appropriate changes to guest
agent.

Signed-off-by: Michael Roth 
---
 qemu-char.c |   55 +++
 1 files changed, 55 insertions(+), 0 deletions(-)

diff --git a/qemu-char.c b/qemu-char.c
index d301925..27b1252 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2276,6 +2276,60 @@ static CharDriverState *qemu_chr_open_socket(QemuOpts 
*opts)
 }
 
 /***/
+/* QMP host->guest proxy chardev */
+#include "qmp-proxy-core.h"
+#include "json-streamer.h"
+
+extern QmpProxy *qmp_proxy_default;
+
+static int qmp_proxy_chr_write(CharDriverState *chr, const uint8_t *buf, int 
len)
+{
+QmpProxy *p = chr->opaque;
+
+qmp_proxy_read(p, buf, len);
+
+return len;
+}
+
+static void qmp_proxy_chr_close(CharDriverState *chr)
+{
+QmpProxy *p = chr->opaque;
+
+qmp_proxy_default = NULL;
+qmp_proxy_close(p);
+qemu_chr_event(chr, CHR_EVENT_CLOSED);
+}
+
+static CharDriverState *qemu_chr_open_qmp_proxy(QemuOpts *opts)
+{
+CharDriverState *chr = qemu_mallocz(sizeof(CharDriverState));
+QmpProxy *p;
+
+/* initialize the qmp guest proxy */
+if (qmp_proxy_default) {
+fprintf(stderr, "error, multiple qmp guest proxies are not allowed\n");
+goto err;
+}
+p = qmp_proxy_default = qmp_proxy_new(chr);
+if (p == NULL) {
+fprintf(stderr, "error initializing qmp guest proxy\n");
+goto err;
+}
+
+chr->opaque = p;
+chr->chr_write = qmp_proxy_chr_write;
+chr->chr_close = qmp_proxy_chr_close;
+qemu_chr_generic_open(chr);
+
+return chr;
+err:
+if (chr) {
+qemu_free(chr);
+}
+return NULL;
+}
+
+/***/
 /* Memory chardev */
 typedef struct {
 size_t outbuf_size;
@@ -2495,6 +2549,7 @@ static const struct {
 || defined(__FreeBSD_kernel__)
 { .name = "parport",   .open = qemu_chr_open_pp },
 #endif
+{ .name = "qmp_proxy", .open = qemu_chr_open_qmp_proxy },
 };
 
 CharDriverState *qemu_chr_open_opts(QemuOpts *opts,
-- 
1.7.0.4




[Qemu-devel] [RFC][PATCH v2 12/17] guest agent: worker thread class

2011-04-18 Thread Michael Roth

Signed-off-by: Michael Roth 
---
 qga/guest-agent-worker.c |  173 ++
 1 files changed, 173 insertions(+), 0 deletions(-)
 create mode 100644 qga/guest-agent-worker.c

diff --git a/qga/guest-agent-worker.c b/qga/guest-agent-worker.c
new file mode 100644
index 000..e3295da
--- /dev/null
+++ b/qga/guest-agent-worker.c
@@ -0,0 +1,173 @@
+/*
+ * QEMU Guest Agent worker thread interfaces
+ *
+ * Copyright IBM Corp. 2011
+ *
+ * Authors:
+ *  Michael Roth  
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "guest-agent.h"
+#include "../error.h"
+
+struct GAWorker {
+pthread_t thread;
+ga_worker_func execute;
+pthread_mutex_t input_mutex;
+pthread_cond_t input_avail_cond;
+void *input;
+bool input_avail;
+pthread_mutex_t output_mutex;
+pthread_cond_t output_avail_cond;
+void *output;
+Error *output_error;
+bool output_avail;
+};
+
+static void *worker_run(void *worker_p)
+{
+GAWorker *worker = worker_p;
+Error *err;
+void *input, *output;
+
+while (1) {
+/* wait for input */
+pthread_mutex_lock(&worker->input_mutex);
+while (!worker->input_avail) {
+pthread_cond_wait(&worker->input_avail_cond, &worker->input_mutex);
+}
+input = worker->input;
+worker->input_avail = false;
+pthread_mutex_unlock(&worker->input_mutex);
+
+/* process input. input points to shared data, so if we ever add
+ * asynchronous dispatch, we'll need to copy the input instead
+ */
+worker->execute(input, &output, &err);
+
+/* signal waiters */
+pthread_mutex_lock(&worker->output_mutex);
+worker->output = output;
+worker->output_error = err;
+worker->output_avail = true;
+pthread_cond_signal(&worker->output_avail_cond);
+pthread_mutex_unlock(&worker->output_mutex);
+}
+
+return NULL;
+}
+
+static void ga_worker_set_input(GAWorker *worker, void *input)
+{
+pthread_mutex_lock(&worker->input_mutex);
+
+/* provide input for thread, and signal it */
+worker->input = input;
+worker->input_avail = true;
+pthread_cond_signal(&worker->input_avail_cond);
+
+pthread_mutex_unlock(&worker->input_mutex);
+}
+
+static bool ga_worker_get_output(GAWorker *worker, void **output, int timeout)
+{
+struct timespec ts;
+GTimeVal tv;
+bool timed_out = false;
+int ret;
+
+pthread_mutex_lock(&worker->output_mutex);
+
+while (!worker->output_avail) {
+if (timeout > 0) {
+g_get_current_time(&tv);
+g_time_val_add(&tv, timeout * 1000);
+ts.tv_sec = tv.tv_sec;
+ts.tv_nsec = tv.tv_usec * 1000;
+ret = pthread_cond_timedwait(&worker->output_avail_cond,
+ &worker->output_mutex, &ts);
+if (ret == ETIMEDOUT) {
+timed_out = true;
+goto out;
+}
+} else {
+ret = pthread_cond_wait(&worker->output_avail_cond,
+&worker->output_mutex);
+}
+}
+
+/* handle output from thread */
+worker->output_avail = false;
+*output = worker->output;
+
+out:
+pthread_mutex_unlock(&worker->output_mutex);
+return timed_out;
+}
+
+bool ga_worker_dispatch(GAWorker *worker, void *input, void *output,
+int timeout, Error **errp)
+{
+ga_worker_set_input(worker, input);
+return ga_worker_get_output(worker, output, timeout);
+}
+
+static void ga_worker_start(GAWorker *worker)
+{
+int ret;
+
+pthread_cond_init(&worker->input_avail_cond, NULL);
+pthread_cond_init(&worker->output_avail_cond, NULL);
+pthread_mutex_init(&worker->input_mutex, NULL);
+pthread_mutex_init(&worker->output_mutex, NULL);
+worker->output_avail = false;
+worker->input_avail = false;
+
+ret = pthread_create(&worker->thread, NULL, worker_run, worker);
+if (ret == -1) {
+g_error("error: %s", strerror(errno));
+}
+}
+
+static void ga_worker_stop(GAWorker *worker)
+{
+int ret;
+void *status;
+
+ret = pthread_cancel(worker->thread);
+if (ret == -1) { 
+g_error("pthread_cancel() failed: %s", strerror(errno));
+}
+
+ret = pthread_join(worker->thread, &status);
+if (ret == -1) { 
+g_error("pthread_join() failed: %s", strerror(errno));
+}
+/* TODO: should *_destroy pthread data structures here */
+}
+
+GAWorker *ga_worker_new(ga_worker_func func)
+{
+GAWorker *worker = g_malloc0(sizeof(GAWorker));
+
+g_assert(func);
+worker->execute = func;
+ga_worker_start(worker);
+
+return worker;
+}
+
+void ga_worker_cleanup(GAWorker *worker)
+{
+ga_worker_stop(worker);
+   

[Qemu-devel] [RFC][PATCH v2 16/17] guest agent: add guest agent RPCs/commands

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

guest-ping
guest-file-open
guest-file-read
guest-file-write
guest-file-seek
guest-file-close

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

Signed-off-by: Michael Roth 
---
 qapi-schema.json   |  133 -
 qga/guest-agent-commands.c |  284 
 2 files changed, 415 insertions(+), 2 deletions(-)
 create mode 100644 qga/guest-agent-commands.c

diff --git a/qapi-schema.json b/qapi-schema.json
index 5292938..e2f209d 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1387,10 +1387,139 @@
 { 'enum': 'VirtioNetTxStrategy', 'data': ['bh', 'timer'] }
 { 'type': 'GuestInfo', 'data': {'*name': 'str', '*pid': 'int'} }
 
+##
+# @guest-ping:
+#
+# Ping the guest agent, a non-error return implies success
+#
+# Since: 0.15.0
+##
 { 'command': 'guest-ping' }
-{ 'command': 'guest-view-file', 'data': { 'filename': 'str' },
-  'returns': 'str' }
 
+##
+# @guest-info:
+#
+# Get some information about the guest agent.
+#
+# Since: 0.15.0
+##
+{ 'type': 'GuestAgentInfo', 'data': {'version': 'str', 'timeout_ms': 'int'} }
+{ 'command': 'guest-info',
+  'returns': 'GuestAgentInfo' }
+
+##
+# @guest-shutdown:
+#
+# Initiate guest-activated shutdown
+#
+# @shutdown_mode: "halt", "powerdown", or "reboot"
+#
+# Returns: Nothing on success
+#
+# Since: 0.15.0
+##
+{ 'command': 'guest-shutdown', 'data': { 'shutdown_mode': 'str' } }
+
+##
+# @guest-file-open:
+#
+# Open a file in the guest and retrieve a file handle for it
+#
+# @filename: 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 @filename cannot be opened, OpenFileFailed
+#
+# Since: 0.15.0
+##
+{ 'command': 'guest-file-open',
+  'data':{ 'filename': '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 cannot be found, 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 cannot be found, 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 @filename cannot be 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 @filename cannot be opened, OpenFileFailed
+#
+# Since: 0.15.0
+##
+{ 'command': 'guest-file-close',
+  'data': { 'filehandle': 'int' } }
 
 { 'type': 'ProbeProtocol', 'data': { 'unsafe': 'bool', 'filename': 'str' } }
 
diff --git a/qga/guest-agent-commands.c b/qga/guest-agent-commands.c
new file mode 100644
index 000..843ef36
--- /dev/null
+++ b/qga/guest-agent-commands.c
@@ -0,0 +1,284 @@
+/*
+ * QEMU Guest Agent commands
+ *
+ * Copyright IBM Corp. 2011
+ *
+ * Authors:
+ *  Michael Roth  
+ *
+ * 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 
+#include "guest-agent.h"
+
+static bool enable_syslog = true;
+static GAState *ga_state;
+
+#define SLOG(msg, ...) do { \
+if (enable_syslog) { \
+g_log("syslog", G_LOG_LEVEL_INFO, msg, ## __VA_ARGS__); \
+} \
+} while(0)
+
+void qga_guest_ping(Error **err)
+{
+SLOG("guest-ping called");
+}
+
+struct GuestAgentInfo *qga_guest_info(Error **

[Qemu-devel] [RFC][PATCH v2 06/17] qapi: fix memory leak for async marshalling code

2011-04-18 Thread Michael Roth
When generating the callback function for an async command, if we expect
a QString we copy it into a native char* type, then call the completion
function. We should free it after calling the completion function, since
the completion function will later copy it into a new QString before
adding it to the response object and then passing it on to the wire.

Signed-off-by: Michael Roth 
---
 qmp-gen.py |4 
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/qmp-gen.py b/qmp-gen.py
index 4164692..3667ec5 100644
--- a/qmp-gen.py
+++ b/qmp-gen.py
@@ -349,6 +349,10 @@ static void qmp_%(c_name)s_cb(void *qmp__opaque, QObject 
*qmp__retval, Error *qm
 ret += cgen('qmp__cb->cb(qmp__cb->opaque, qmp__err);')
 else:
 ret += cgen('qmp__cb->cb(qmp__cb->opaque, qmp__native_retval, 
qmp__err);')
+if retval != 'none' and qmp_type_should_free(retval):
+ret += cgen('%(free)s(qmp__native_retval);',
+free=qapi_free_func(retval))
+
 ret += cgen('}')
 
 return ret
-- 
1.7.0.4




[Qemu-devel] [RFC][PATCH v2 04/17] qapi: fix function name typo in qmp-gen.py

2011-04-18 Thread Michael Roth

Signed-off-by: Michael Roth 
---
 qmp-gen.py |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/qmp-gen.py b/qmp-gen.py
index 90069ca..4164692 100644
--- a/qmp-gen.py
+++ b/qmp-gen.py
@@ -2328,7 +2328,7 @@ void qga_init_marshal(void)
 if not s.has_key('command'):
 continue
 name = s['command']
-if qmp_is_proxy_command(name):
+if qmp_is_proxy_cmd(name):
 ret += mcgen('''
 qga_register_command("%(name)s", &qmp_marshal_%(c_name)s);
 ''',
-- 
1.7.0.4




[Qemu-devel] [RFC][PATCH v2 08/17] qapi: fix Error usage in qemu-sockets.c

2011-04-18 Thread Michael Roth
Fix spurious errors due to not initializing Error pointer to NULL before
checking for errors.

Signed-off-by: Michael Roth 
---
 qemu-sockets.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/qemu-sockets.c b/qemu-sockets.c
index dc8beeb..e709e5f 100644
--- a/qemu-sockets.c
+++ b/qemu-sockets.c
@@ -630,7 +630,7 @@ int unix_connect(const char *path)
 {
 QemuOpts *opts;
 int sock;
-Error *err;
+Error *err = NULL;
 
 opts = qemu_opts_create(&dummy_opts, NULL, 0, &err);
 if (err) {
-- 
1.7.0.4




[Qemu-devel] [RFC][PATCH v2 07/17] qapi: qmp-gen.py, use basename of path for guard/core prefix

2011-04-18 Thread Michael Roth
To avoid errors when generating output to a seperate subdirectory, use
only the filename, minus any leading directories, when passing it into
functions to be used as a prefix for header guards, includes, etc.

Also, trim file extensions based on "." seperator instead of assuming a
single-char extension and trimming the last 2 chars

Signed-off-by: Michael Roth 
---
 qmp-gen.py |9 +
 1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/qmp-gen.py b/qmp-gen.py
index 3667ec5..eeef58c 100644
--- a/qmp-gen.py
+++ b/qmp-gen.py
@@ -2047,10 +2047,11 @@ def generate(kind, output):
 enum_types = []
 event_types = {}
 indent_level = 0
+prefix = output.split("/")[-1].split(".")[0]
 
-guard = '%s_H' % c_var(output[:-2]).upper()
-core = '%s-core.h' % output[:-2]
-header = '%s.h' % output[:-2]
+guard = '%s_H' % c_var(prefix).upper()
+core = '%s-core.h' % prefix
+header = '%s.h' % prefix
 
 if kind.endswith('body') or kind.endswith('header'):
 ret = mcgen('''
@@ -2387,7 +2388,7 @@ void qcfg_options_init(void)
 return ret
 
 def main(args):
-if len(args) != 2:
+if len(args) < 2:
 return 1
 if not args[0].startswith('--'):
 return 1
-- 
1.7.0.4




[Qemu-devel] [RFC][PATCH v2 09/17] qmp proxy: core code for proxying qmp requests to guest

2011-04-18 Thread Michael Roth
This provides a QmpProxy class, 1 instance of which is shared by all QMP
servers/sessions to send/receive QMP requests/responses between QEMU and
the QEMU guest agent.

A single qmp_proxy_send_request() is the only interface currently needed
by a QMP session, QAPI/QMP's existing async support handles all the work
of doing callbacks and routing responses to the proper session.

Signed-off-by: Michael Roth 
---
 qapi-schema.json |7 ++
 qmp-core.c   |8 ++
 qmp-core.h   |7 +-
 qmp-proxy-core.h |   21 
 qmp-proxy.c  |  294 ++
 vl.c |1 +
 6 files changed, 332 insertions(+), 6 deletions(-)
 create mode 100644 qmp-proxy-core.h
 create mode 100644 qmp-proxy.c

diff --git a/qapi-schema.json b/qapi-schema.json
index de6c9a3..5292938 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1498,3 +1498,10 @@
 # Since: 0.14.0
 ##
 { 'option': 'vnc', 'data': 'VncConfig', 'implicit': 'address' }
+
+## 0.15.0 Events ##
+{ 'event': 'GUEST_AGENT_UP' }
+{ 'command': 'get-guest-agent-up-event', 'returns': 'GUEST_AGENT_UP' }
+
+{ 'event': 'GUEST_AGENT_RESET' }
+{ 'command': 'get-guest-agent-reset-event', 'returns': 'GUEST_AGENT_RESET' }
diff --git a/qmp-core.c b/qmp-core.c
index 9f3d182..dab50a1 100644
--- a/qmp-core.c
+++ b/qmp-core.c
@@ -937,7 +937,15 @@ void qmp_async_complete_command(QmpCommandState *cmd, 
QObject *retval, Error *er
 qemu_free(cmd);
 }
 
+extern QmpProxy *qmp_proxy_default;
+
 void qmp_guest_dispatch(const char *name, const QDict *args, Error **errp,
 QmpGuestCompletionFunc *cb, void *opaque)
 {
+if (!qmp_proxy_default) {
+/* TODO: should set errp here */
+fprintf(stderr, "qmp proxy: no guest proxy found\n");
+return;
+}
+qmp_proxy_send_request(qmp_proxy_default, name, args, errp, cb, opaque);
 }
diff --git a/qmp-core.h b/qmp-core.h
index b676020..114d290 100644
--- a/qmp-core.h
+++ b/qmp-core.h
@@ -4,6 +4,7 @@
 #include "monitor.h"
 #include "qmp-marshal-types.h"
 #include "error_int.h"
+#include "qmp-proxy-core.h"
 
 struct QmpCommandState
 {
@@ -85,11 +86,5 @@ int qmp_state_get_fd(QmpState *sess);
 }\
 } while(0)
 
-typedef void (QmpGuestCompletionFunc)(void *opaque, QObject *ret_data, Error 
*err);
-
-void qmp_guest_dispatch(const char *name, const QDict *args, Error **errp,
-QmpGuestCompletionFunc *cb, void *opaque);
-
-
 #endif
 
diff --git a/qmp-proxy-core.h b/qmp-proxy-core.h
new file mode 100644
index 000..6afdc23
--- /dev/null
+++ b/qmp-proxy-core.h
@@ -0,0 +1,21 @@
+#ifndef QMP_PROXY_CORE_H
+#define QMP_PROXY_CORE_H
+
+#define QMP_PROXY_PATH_DEFAULT "/tmp/qmp-proxy.sock"
+
+typedef void (QmpGuestCompletionFunc)(void *opaque, QObject *ret_data,
+  Error *err);
+
+void qmp_guest_dispatch(const char *name, const QDict *args, Error **errp,
+QmpGuestCompletionFunc *cb, void *opaque);
+
+typedef struct QmpProxy QmpProxy;
+
+void qmp_proxy_send_request(QmpProxy *p, const char *name,
+const QDict *args, Error **errp,
+QmpGuestCompletionFunc *cb, void *opaque);
+QmpProxy *qmp_proxy_new(CharDriverState *chr);
+void qmp_proxy_close(QmpProxy *p);
+int qmp_proxy_read(QmpProxy *p, const uint8_t *buf, int len);
+
+#endif
diff --git a/qmp-proxy.c b/qmp-proxy.c
new file mode 100644
index 000..a4c7eea
--- /dev/null
+++ b/qmp-proxy.c
@@ -0,0 +1,294 @@
+/*
+ * QMP definitions for communicating with guest agent
+ *
+ * Copyright IBM Corp. 2011
+ *
+ * Authors:
+ *  Michael Roth  
+ *
+ * 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 
+#include "qmp.h"
+#include "qmp-core.h"
+#include "qemu-queue.h"
+#include "json-parser.h"
+#include "json-streamer.h"
+#include "qemu_socket.h"
+
+#define QMP_SENTINEL 0xFF
+
+typedef struct QmpProxyRequest {
+const char *name;
+const QDict *args;
+QmpGuestCompletionFunc *cb;
+void *opaque;
+QString *json;
+QTAILQ_ENTRY(QmpProxyRequest) entry;
+} QmpProxyRequest;
+
+struct QmpProxy {
+int session_id;
+JSONMessageParser parser;
+GString *tx;
+QEMUTimer *tx_timer;
+int tx_timer_interval;
+QTAILQ_HEAD(, QmpProxyRequest) requests;
+CharDriverState *chr;
+};
+
+static GuestAgentUpEvent guest_agent_up_event;
+static GuestAgentResetEvent guest_agent_reset_event;
+static void qmp_proxy_write(QmpProxy *p);
+
+GuestAgentUpEvent *qmp_get_guest_agent_up_event(Error **errp)
+{
+return &guest_agent_up_event;
+}
+
+GuestAgentResetEvent *qmp_get_guest_agent_reset_event(Error **errp)
+{
+return &guest_agent_reset_event;
+}
+
+static int qmp_proxy_cancel_request(QmpProxy *p, QmpProxyRequest *r)
+{
+if (r && r->cb) {
+r->cb(r->opaque, NULL, NULL);
+}
+
+return

[Qemu-devel] [RFC][PATCH v2 00/11] QEMU Guest Agent: QMP-based host/guest communication (virtagent)

2011-04-18 Thread Michael Roth
These apply on top of Anthony's glib tree, commit 
03d5927deb5e6baebaade1b4c8ff2428a85e125c currently, and can also be obtained 
from:
git://repo.or.cz/qemu/mdroth.git qga_v2

Patches 1-8 are general json/QAPI-related fixes. Anthony, please consider 
pulling these into your glib tree. The json fix-ups may need further 
evaluation, but I'm confident they're at least an improvement. The QAPI ones 
are mostly trivial fix-ups.

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:

- Fix QMP proxy handling of error responses sent by guest agent, currently 
ignored
- Add unit tests for guest agent wire protocol
- Add unit tests for QMP interfaces
- Add host-side timeout mechanism for async QMP commands
- Return error for guest commands if guest up event has not yet been recieved
- Make QMP param names more consistent between related commands
- Clean up logging

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 --enable-kvm \
  -chardev socket,path=/tmp/mon-qmp.sock,server,nowait,id=mon-qmp \
  -qmp mon-qmp \
  -chardev qmp_proxy,id=qmp_proxy \ 
  -device virtio-serial \
  -device virtserialport,chardev=qmp_proxy,name=qcg"

use guest agent:
  ./qemu-ga -h
  ./qemu-ga -c virtio-serial -p /dev/virtio-ports/qcg

start/use qmp:
  mdroth@illuin:~$ sudo socat unix-connect:/tmp/mon-qmp.sock readline
  {"QMP": {"version": {"qemu": {"micro": 50, "minor": 13, "major": 0}, 
"package": ""}, "capabilities": []}}

  {"execute":"guest-info"}
  {"return": {}}

  {"execute": "guest-info"}
  {"return": {"version": "1.0", "timeout_ms": 3}}

  {"execute":"guest-file-open", 
"arguments":{"filename":"/tmp/testqga","mode":"w+"}}
  {"return": 0}
  {"execute":"guest-file-write", 
"arguments":{"filehandle":0,"data_b64":"aGVsbG8gd29ybGQhCg==","count":13}} // 
writes "hello world!\n"
  {"return": {"count": 13, "eof": false}}

  {"execute":"guest-file-open", 
"arguments":{"filename":"/tmp/testqga","mode":"r"}}
  {"return": 1}
  {"execute":"guest-file-read", "arguments":{"filehandle":1,"count":1024}}
  {"return": {"buf": "aGVsbG8gd29ybGQhCg==", "count": 13, "eof": true}}
  {"execute":"guest-file-close","arguments":{"filehandle":1}}
  {"return": {}}

 Makefile|   15 +-
 Makefile.objs   |1 +
 configure   |6 +-
 json-lexer.c|   33 ++-
 json-lexer.h|1 +
 json-parser.c   |6 +-
 json-streamer.c |   35 ++-
 qapi-schema.json|  140 -
 qemu-char.c |   55 +++
 qemu-ga.c   |  711 +++
 qemu-sockets.c  |2 +-
 qga/guest-agent-command-state.c |   73 
 qga/guest-agent-commands.c  |  284 
 qga/guest-agent-core.c  |  139 
 qga/guest-agent-core.h  |   40 +++
 qga/guest-agent-worker.c|  173 ++
 qmp-core.c  |   13 +-
 qmp-core.h  |7 +-
 qmp-gen.py  |   15 +-
 qmp-proxy-core.h|   21 ++
 qmp-proxy.c |  294 
 vl.c|1 +
 22 files changed, 2023 insertions(+), 42 deletions(-)




  1   2   >