[Qemu-devel] Re: [PATCH 0/9] S390x KVM support

2009-10-21 Thread Alexander Graf


On 20.10.2009, at 18:40, Carsten Otte wrote:


Alexander Graf wrote:
This is the resulting code. Please comment on things you like and  
also on the

ones you don't :-).

I've reviewed and tested it, great work Alex :-)


Thanks :-).

Also to actually run this code you need a patch for an ugly bug in  
the kernel

module: http://alex.csgraf.de/psw.patch
Well, it was not exactly a bug. Kuli does'nt need the psw to be  
updated in kvm_run at all times. Your hotfix updates the psw in a  
union, even if the exit reason indicates that s390_sieic is not  
valid. The patch at the end of this mail moves the PSW out of the  
union. I think it makes most sense if Avi picks this patch and you  
adopt your series to it. This way the user interface of the kvm  
module works for both kuli and qemu.


Alright, expect v2 today!

On a sidenode, please post the patch to kvm-devel too, so Marcelo has  
the chance to pick it up.




This patch moves s390 processor status word into the base kvm_run
struct and keeps it up-to date on all userspace exits.

Signed-off-by: Carsten Otte 
---
arch/s390/kvm/kvm-s390.c |   14 --
include/linux/kvm.h  |8 ++--
2 files changed, 14 insertions(+), 8 deletions(-)

Index: kvm/include/linux/kvm.h
===
--- kvm.orig/include/linux/kvm.h2009-10-20 15:00:40.0 +0200
+++ kvm/include/linux/kvm.h 2009-10-20 16:51:48.0 +0200
@@ -7,6 +7,7 @@
* Note: you must update KVM_API_VERSION if you change this interface.
*/
+#include 
#include 
#include 
#include 
@@ -116,6 +117,11 @@
__u64 cr8;
__u64 apic_base;
+#ifdef CONFIG_S390
+   /* the processor status word for s390 */
+   __u64 psw_mask; /* psw upper half */
+   __u64 psw_addr; /* psw lower half */
+#endif
union {
/* KVM_EXIT_UNKNOWN */
struct {
@@ -167,8 +173,6 @@
/* KVM_EXIT_S390_SIEIC */
struct {
__u8 icptcode;
-   __u64 mask; /* psw upper half */
-   __u64 addr; /* psw lower half */
__u16 ipa;
__u32 ipb;
} s390_sieic;
Index: kvm/arch/s390/kvm/kvm-s390.c
===
--- kvm.orig/arch/s390/kvm/kvm-s390.c	2009-10-20 15:01:02.0  
+0200

+++ kvm/arch/s390/kvm/kvm-s390.c2009-10-20 18:13:45.0 +0200
@@ -421,7 +421,8 @@
if (atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_RUNNING)
rc = -EBUSY;
else
-   vcpu->arch.sie_block->gpsw = psw;
+   vcpu->run->psw_mask = psw.mask;
+   vcpu->run->psw_addr = psw.addr;
vcpu_put(vcpu);
return rc;
}
@@ -509,9 +510,6 @@
switch (kvm_run->exit_reason) {
case KVM_EXIT_S390_SIEIC:
-   vcpu->arch.sie_block->gpsw.mask = kvm_run->s390_sieic.mask;
-   vcpu->arch.sie_block->gpsw.addr = kvm_run->s390_sieic.addr;
-   break;
case KVM_EXIT_UNKNOWN:
case KVM_EXIT_INTR:
case KVM_EXIT_S390_RESET:
@@ -520,6 +518,9 @@
BUG();
}


Why leave the switch? Do you want the BUG() that badly?

Most of the time that's just wasted cycles, right?


+   vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask;
+   vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr;
+
might_fault();
do {
@@ -539,8 +540,6 @@
/* intercept cannot be handled in-kernel, prepare kvm-run */
kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
-   kvm_run->s390_sieic.mask = vcpu->arch.sie_block->gpsw.mask;
-   kvm_run->s390_sieic.addr = vcpu->arch.sie_block->gpsw.addr;
kvm_run->s390_sieic.ipa  = vcpu->arch.sie_block->ipa;
kvm_run->s390_sieic.ipb  = vcpu->arch.sie_block->ipb;
rc = 0;
@@ -552,6 +551,9 @@
rc = 0;
}
+   kvm_run->psw_mask = vcpu->arch.sie_block->gpsw.mask;
+   kvm_run->psw_addr = vcpu->arch.sie_block->gpsw.addr;
+


I think you should not indent the equal signs here. They're not  
aligned to the ones above anymore anyways.


Apart from that, great patch!
I'll put all the pieces together today, so expect to be running Qemu  
backed virtualization on your mainframe :-).


Alex




[Qemu-devel] Re: [PATCH 0/9] S390x KVM support

2009-10-21 Thread Alexander Graf


On 20.10.2009, at 18:40, Carsten Otte wrote:


Alexander Graf wrote:
This is the resulting code. Please comment on things you like and  
also on the

ones you don't :-).

I've reviewed and tested it, great work Alex :-)

Also to actually run this code you need a patch for an ugly bug in  
the kernel

module: http://alex.csgraf.de/psw.patch
Well, it was not exactly a bug. Kuli does'nt need the psw to be  
updated in kvm_run at all times. Your hotfix updates the psw in a  
union, even if the exit reason indicates that s390_sieic is not  
valid. The patch at the end of this mail moves the PSW out of the  
union. I think it makes most sense if Avi picks this patch and you  
adopt your series to it. This way the user interface of the kvm  
module works for both kuli and qemu.








This patch moves s390 processor status word into the base kvm_run
struct and keeps it up-to date on all userspace exits.

Signed-off-by: Carsten Otte 
---
arch/s390/kvm/kvm-s390.c |   14 --
include/linux/kvm.h  |8 ++--
2 files changed, 14 insertions(+), 8 deletions(-)

Index: kvm/include/linux/kvm.h
===
--- kvm.orig/include/linux/kvm.h2009-10-20 15:00:40.0 +0200
+++ kvm/include/linux/kvm.h 2009-10-20 16:51:48.0 +0200
@@ -7,6 +7,7 @@
* Note: you must update KVM_API_VERSION if you change this interface.
*/
+#include 
#include 
#include 
#include 
@@ -116,6 +117,11 @@
__u64 cr8;
__u64 apic_base;
+#ifdef CONFIG_S390
+   /* the processor status word for s390 */
+   __u64 psw_mask; /* psw upper half */
+   __u64 psw_addr; /* psw lower half */
+#endif


While at it, I think we should either go all or nothing here.

Either we take the psw in on x86 too or we #ifdef out the x86 specific  
stuff on s390.


Alex





[Qemu-devel] Re: [PATCH 0/9] S390x KVM support

2009-10-21 Thread Alexander Graf


On 20.10.2009, at 18:40, Carsten Otte wrote:


Alexander Graf wrote:
This is the resulting code. Please comment on things you like and  
also on the

ones you don't :-).

I've reviewed and tested it, great work Alex :-)

Also to actually run this code you need a patch for an ugly bug in  
the kernel

module: http://alex.csgraf.de/psw.patch
Well, it was not exactly a bug. Kuli does'nt need the psw to be  
updated in kvm_run at all times. Your hotfix updates the psw in a  
union, even if the exit reason indicates that s390_sieic is not  
valid. The patch at the end of this mail moves the PSW out of the  
union. I think it makes most sense if Avi picks this patch and you  
adopt your series to it. This way the user interface of the kvm  
module works for both kuli and qemu.








This patch moves s390 processor status word into the base kvm_run
struct and keeps it up-to date on all userspace exits.

Signed-off-by: Carsten Otte 
---
arch/s390/kvm/kvm-s390.c |   14 --
include/linux/kvm.h  |8 ++--
2 files changed, 14 insertions(+), 8 deletions(-)

Index: kvm/include/linux/kvm.h
===
--- kvm.orig/include/linux/kvm.h2009-10-20 15:00:40.0 +0200
+++ kvm/include/linux/kvm.h 2009-10-20 16:51:48.0 +0200
@@ -7,6 +7,7 @@
* Note: you must update KVM_API_VERSION if you change this interface.
*/
+#include 
#include 
#include 
#include 
@@ -116,6 +117,11 @@
__u64 cr8;
__u64 apic_base;
+#ifdef CONFIG_S390
+   /* the processor status word for s390 */
+   __u64 psw_mask; /* psw upper half */
+   __u64 psw_addr; /* psw lower half */
+#endif
union {
/* KVM_EXIT_UNKNOWN */
struct {
@@ -167,8 +173,6 @@
/* KVM_EXIT_S390_SIEIC */
struct {
__u8 icptcode;
-   __u64 mask; /* psw upper half */
-   __u64 addr; /* psw lower half */
__u16 ipa;
__u32 ipb;
} s390_sieic;
Index: kvm/arch/s390/kvm/kvm-s390.c
===
--- kvm.orig/arch/s390/kvm/kvm-s390.c	2009-10-20 15:01:02.0  
+0200

+++ kvm/arch/s390/kvm/kvm-s390.c2009-10-20 18:13:45.0 +0200
@@ -421,7 +421,8 @@
if (atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_RUNNING)
rc = -EBUSY;
else
-   vcpu->arch.sie_block->gpsw = psw;
+   vcpu->run->psw_mask = psw.mask;
+   vcpu->run->psw_addr = psw.addr;


Missing braces.

Alex




Re: [Qemu-devel] [PATCH] new SDL keyboard shortcuts to start and stop VM

2009-10-21 Thread Kevin Wolf
Am 20.10.2009 19:08, schrieb Daniel P. Berrange:
> On Tue, Oct 20, 2009 at 12:40:08PM +0200, Kevin Wolf wrote:
>> Am 20.10.2009 00:20, schrieb Anthony Liguori:
>>> Mulyadi Santosa wrote:
 IMO, it would be faster if we provide keyboard shortcuts that will
 stop and resume VM execution right from SDL guest interface, rather
 than switching to console monitor first and type "s" or "c"
 respectively.
   
>>>
>>> Is this really common of an operation that you would need an escape key 
>>> for it?
>>>
>>> Why are you so frequently stopping and continuing a guest?
>>
>> Why are you all trying to explain to him that actually he doesn't want
>> to have this feature? I could have used it, too, at times (stop the
>> guest to have enough time to attach gdb, for example). There are other
>> ways to do it (although they are not as simple) and I used them, but
>> that doesn't make this feature less useful.
>>
>> Does it take anything away for you? Or do you have plans to use those
>> keys otherwise? If not, why not add a feature that some might find
>> useful, even though others don't?
> 
> The problem with adding lots of magic key-sequences, is that the more
> you add, the more likely they are to clash with something that the 
> guest OS wants to use. You may make this use case work, but break
> someone else's use case. Thus, IMHO, magic key sequences should be kept
> to the bare minimum neccessary to access functionality for which there
> is no other viable access method.

Ok, you have a point there. But why do we have key sequences for
fullscreen and resizing the SDL window back to its original size then?
Both are things that could be accessed through monitor commands as well.
And you don't need the right timing for resizing the window - unlike
stopping the VM. So I would be really happy with swapping those for a
"stop VM" shortcut.

Kevin




[Qemu-devel] Re: [PATCH 0/9] S390x KVM support

2009-10-21 Thread Carsten Otte

Alexander Graf wrote:
Either we take the psw in on x86 too or we #ifdef out the x86 specific 
stuff on s390.

Good idea, I'll #ifndef CONFIG_S390 the x86 specifics while we're at it.




[Qemu-devel] Re: [PATCH 0/9] S390x KVM support

2009-10-21 Thread Alexander Graf


On 21.10.2009, at 10:18, Carsten Otte wrote:


Alexander Graf wrote:
Either we take the psw in on x86 too or we #ifdef out the x86  
specific stuff on s390.
Good idea, I'll #ifndef CONFIG_S390 the x86 specifics while we're at  
it.


Maybe better #if defined(TARGET_X86) || defined(TARGET_IA64). We don't  
really need them for ppc either :-).


Alex




[Qemu-devel] RE: [ANNOUNCE] Sheepdog: Distributed Storage System for KVM

2009-10-21 Thread Dietmar Maurer
Quite interesting. But would it be possible to use corosync for the cluster 
communication? The point is that we need corosync anyways for pacemaker, it is 
written in C (high performance) and seem to implement the feature you need?

> -Original Message-
> From: kvm-ow...@vger.kernel.org [mailto:kvm-ow...@vger.kernel.org] On
> Behalf Of MORITA Kazutaka
> Sent: Mittwoch, 21. Oktober 2009 07:14
> To: k...@vger.kernel.org; qemu-devel@nongnu.org; linux-
> fsde...@vger.kernel.org
> Subject: [ANNOUNCE] Sheepdog: Distributed Storage System for KVM
> 
> Hi everyone,
> 
> Sheepdog is a distributed storage system for KVM/QEMU. It provides
> highly available block level storage volumes to VMs like Amazon EBS.
> Sheepdog supports advanced volume management features such as snapshot,
> cloning, and thin provisioning. Sheepdog runs on several tens or
> hundreds
> of nodes, and the architecture is fully symmetric; there is no central
> node such as a meta-data server.





[Qemu-devel] [PATCH 5/9] Add S390x virtio machine description

2009-10-21 Thread Alexander Graf
In order to use the new S390x virtio bus we just introduced, we also
need a machine description that sets up the machine according to our
PV specification.

Let's add that machine description and be happy!

Signed-off-by: Alexander Graf 
---
 Makefile.target  |2 +-
 hw/s390-virtio.c |  244 ++
 2 files changed, 245 insertions(+), 1 deletions(-)
 create mode 100644 hw/s390-virtio.c

diff --git a/Makefile.target b/Makefile.target
index ef72867..524be43 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -294,7 +294,7 @@ obj-sh4-y += ide/core.o ide/mmio.o
 obj-m68k-y = an5206.o mcf5206.o mcf_uart.o mcf_intc.o mcf5208.o mcf_fec.o
 obj-m68k-y += m68k-semi.o dummy_m68k.o
 
-obj-s390x-y = s390-virtio-bus.o
+obj-s390x-y = s390-virtio-bus.o s390-virtio.o 
 
 main.o vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
 
diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
new file mode 100644
index 000..cd62e54
--- /dev/null
+++ b/hw/s390-virtio.c
@@ -0,0 +1,244 @@
+/*
+ * QEMU S390 virtio target
+ *
+ * Copyright (c) 2009 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 "hw.h"
+#include "block.h"
+#include "sysemu.h"
+#include "net.h"
+#include "boards.h"
+#include "monitor.h"
+#include "loader.h"
+#include "elf.h"
+#include "hw/virtio.h"
+#include "hw/virtio-console.h"
+#include "hw/sysbus.h"
+#include "kvm.h"
+
+#include "hw/s390-virtio-bus.h"
+
+//#define DEBUG_S390
+
+#ifdef DEBUG_S390
+#define dprintf(fmt, ...) \
+do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
+#else
+#define dprintf(fmt, ...) \
+do { } while (0)
+#endif
+
+#define KVM_S390_VIRTIO_NOTIFY  0
+#define KVM_S390_VIRTIO_RESET   1
+#define KVM_S390_VIRTIO_SET_STATUS  2
+
+#define KERN_IMAGE_START0x01UL
+#define KERN_PARM_AREA  0x010480UL
+#define INITRD_START0x80UL
+#define INITRD_PARM_START   0x010408UL
+#define INITRD_PARM_SIZE0x010410UL
+#define PARMFILE_START  0x001000UL
+
+#define MAX_BLK_DEVS10
+
+static VirtIOS390Bus *s390_bus;
+static CPUState **ipi_states;
+
+void irq_info(Monitor *mon);
+void pic_info(Monitor *mon);
+
+void irq_info(Monitor *mon)
+{
+}
+
+void pic_info(Monitor *mon)
+{
+}
+
+CPUState *s390_cpu_addr2state(uint16_t cpu_addr)
+{
+if (cpu_addr >= smp_cpus)
+return NULL;
+
+return ipi_states[cpu_addr];
+}
+
+int s390_virtio_hypercall(CPUState *env)
+{
+int r = 0, i;
+target_ulong mem = env->regs[2];
+
+dprintf("KVM hypercall: %ld\n", env->regs[1]);
+switch (env->regs[1]) {
+case KVM_S390_VIRTIO_NOTIFY:
+if (mem > ram_size) {
+VirtIOS390Device *dev = s390_virtio_bus_find_vring(s390_bus,
+   mem, &i);
+if (dev) {
+virtio_queue_notify(dev->vdev, i);
+} else {
+r = -EINVAL;
+}
+} else {
+/* Early printk */
+uint8_t *p = (uint8_t *)qemu_get_ram_ptr(mem);
+VirtIOS390Device *dev = s390_virtio_bus_console(s390_bus);
+virtio_console_print_early(dev->vdev, p);
+}
+break;
+case KVM_S390_VIRTIO_RESET:
+{
+/* Virtio_reset resets the internal addresses, so we'd have to sync
+   them up again. We don't want to reallicate a vring though, so let's
+   just not reset. */
+/* virtio_reset(dev->vdev); */
+break;
+}
+case KVM_S390_VIRTIO_SET_STATUS:
+{
+VirtIOS390Device *dev;
+
+dev = s390_virtio_bus_find_mem(s390_bus, mem);
+if (dev)
+s390_virtio_device_update_status(dev);
+else
+r = -EINVAL;
+break;
+}
+default:
+r = -EINVAL;
+break;
+}
+
+env->regs[2] = r;
+return 0;
+}
+
+/* PC hardware initialisation */
+static void s390_init(ram_addr_t _ram_size,
+  const char *boot_device,
+  const char *kernel_filename,
+  const char *kernel_cmdline,
+  const char *initrd_filename,
+  const char *cpu_model)
+{
+CPUState *env = NULL;
+ram_addr_t ram_addr, ram_size = _ram_size;
+ram_addr_t ker

[Qemu-devel] [PATCH 7/9] Implement early printk in virtio-console

2009-10-21 Thread Alexander Graf
On our S390x Virtio machine we don't have anywhere to display early printks
on, because we don't know about VGA or serial ports.

So instead we just forward everything to the virtio console that we created
anyways.

Signed-off-by: Alexander Graf 
---
 hw/virtio-console.c |7 +++
 hw/virtio-console.h |2 ++
 2 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/hw/virtio-console.c b/hw/virtio-console.c
index 57f8f89..cd6cf20 100644
--- a/hw/virtio-console.c
+++ b/hw/virtio-console.c
@@ -105,6 +105,13 @@ static void vcon_event(void *opaque, int event)
 /* we will ignore any event for the time being */
 }
 
+void virtio_console_print_early(VirtIODevice *vdev, uint8_t *buf)
+{
+VirtIOConsole *s = to_virtio_console(vdev);
+
+qemu_chr_write(s->chr, buf, strlen((char*)buf));
+}
+
 static void virtio_console_save(QEMUFile *f, void *opaque)
 {
 VirtIOConsole *s = opaque;
diff --git a/hw/virtio-console.h b/hw/virtio-console.h
index 84d0717..f3ccc3c 100644
--- a/hw/virtio-console.h
+++ b/hw/virtio-console.h
@@ -16,4 +16,6 @@
 /* The ID for virtio console */
 #define VIRTIO_ID_CONSOLE 3
 
+void virtio_console_print_early(VirtIODevice *vdev, uint8_t *buf);
+
 #endif
-- 
1.6.0.2





[Qemu-devel] [PATCH 9/9] Move mp_state to CPU_COMMON

2009-10-21 Thread Alexander Graf
MP State is implemented in the generic code, so let's move the variable
it accesses to generic code as well.

Still unbreaks PPC and now even S390x w/ KVM.

Signed-off-by: Alexander Graf 
---
 cpu-defs.h|1 +
 target-i386/cpu.h |1 -
 2 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/cpu-defs.h b/cpu-defs.h
index 95068b5..ad804e6 100644
--- a/cpu-defs.h
+++ b/cpu-defs.h
@@ -197,6 +197,7 @@ typedef struct CPUWatchpoint {
 const char *cpu_model_str;  \
 struct KVMState *kvm_state; \
 struct kvm_run *kvm_run;\
+uint32_t mp_state;  \
 int kvm_fd;
 
 #endif
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 5929d28..8d0c2a9 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -692,7 +692,6 @@ typedef struct CPUX86State {
 
 /* For KVM */
 uint64_t interrupt_bitmap[256 / 64];
-uint32_t mp_state;
 
 /* in order to simplify APIC support, we leave this pointer to the
user */
-- 
1.6.0.2





[Qemu-devel] [PATCH 1/9] Export function for VA defined ram allocation

2009-10-21 Thread Alexander Graf
S390 requires vmas for guests to be < 256 GB. So we need to directly export
mmaps "try to use this vma as start address" feature to not accidently get
over that limit.

Signed-off-by: Alexander Graf 
---
 cpu-common.h |1 +
 exec.c   |   15 +--
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/cpu-common.h b/cpu-common.h
index 6302372..ecaf9e3 100644
--- a/cpu-common.h
+++ b/cpu-common.h
@@ -30,6 +30,7 @@ static inline void 
cpu_register_physical_memory(target_phys_addr_t start_addr,
 
 ram_addr_t cpu_get_physical_page_desc(target_phys_addr_t addr);
 ram_addr_t qemu_ram_alloc(ram_addr_t);
+ram_addr_t _qemu_ram_alloc(ram_addr_t size, void *map_at);
 void qemu_ram_free(ram_addr_t addr);
 /* This should only be used for ram local to a device.  */
 void *qemu_get_ram_ptr(ram_addr_t addr);
diff --git a/exec.c b/exec.c
index 076d26b..36c26cd 100644
--- a/exec.c
+++ b/exec.c
@@ -2404,14 +2404,20 @@ void qemu_unregister_coalesced_mmio(target_phys_addr_t 
addr, ram_addr_t size)
 kvm_uncoalesce_mmio_region(addr, size);
 }
 
-ram_addr_t qemu_ram_alloc(ram_addr_t size)
+ram_addr_t _qemu_ram_alloc(ram_addr_t size, void *map_at)
 {
 RAMBlock *new_block;
 
 size = TARGET_PAGE_ALIGN(size);
 new_block = qemu_malloc(sizeof(*new_block));
 
-new_block->host = qemu_vmalloc(size);
+if (map_at) {
+new_block->host = mmap(map_at, size, PROT_EXEC|PROT_READ|PROT_WRITE,
+   MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+
+} else {
+new_block->host = qemu_vmalloc(size);
+}
 #ifdef MADV_MERGEABLE
 madvise(new_block->host, size, MADV_MERGEABLE);
 #endif
@@ -2434,6 +2440,11 @@ ram_addr_t qemu_ram_alloc(ram_addr_t size)
 return new_block->offset;
 }
 
+ram_addr_t qemu_ram_alloc(ram_addr_t size)
+{
+return _qemu_ram_alloc(size, NULL);
+}
+
 void qemu_ram_free(ram_addr_t addr)
 {
 /* TODO: implement this.  */
-- 
1.6.0.2





[Qemu-devel] [PATCH 3/9] Add support for S390x system emulation

2009-10-21 Thread Alexander Graf
Right now only S390x Linux userspace emulation is supported. Let's enable
the basics for system emulation so we can run virtual machines with KVM!

Signed-off-by: Alexander Graf 
---
 target-s390x/cpu.h   |   86 -
 target-s390x/exec.h  |5 +++
 target-s390x/helper.c|   26 +-
 target-s390x/machine.c   |   30 
 target-s390x/op_helper.c |   53 
 5 files changed, 196 insertions(+), 4 deletions(-)
 create mode 100644 target-s390x/machine.c

diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index 93b09cd..c5ba7c3 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -30,8 +30,7 @@
 
 #include "softfloat.h"
 
-#define NB_MMU_MODES 2 // guess
-#define MMU_USER_IDX 0 // guess
+#define NB_MMU_MODES 2
 
 typedef union FPReg {
 struct {
@@ -77,12 +76,28 @@ static inline void cpu_clone_regs(CPUState *env, 
target_ulong newsp)
 }
 #endif
 
+#define MMU_MODE0_SUFFIX _kernel
+#define MMU_MODE1_SUFFIX _user
+#define MMU_USER_IDX 1
+static inline int cpu_mmu_index (CPUState *env)
+{
+/* XXX: Currently we don't implement virtual memory */
+return 0;
+}
+
+
 CPUS390XState *cpu_s390x_init(const char *cpu_model);
 void s390x_translate_init(void);
 int cpu_s390x_exec(CPUS390XState *s);
 void cpu_s390x_close(CPUS390XState *s);
 void do_interrupt (CPUState *env);
 
+#ifndef CONFIG_USER_ONLY
+extern int s390_virtio_hypercall(CPUState *env);
+extern void kvm_s390_virtio_irq(CPUState *env, int config_change, uint64_t 
token);
+extern CPUState *s390_cpu_addr2state(uint16_t cpu_addr);
+#endif
+
 /* you can call this signal handler from your SIGBUS and SIGSEGV
signal handlers to inform the virtual CPU of exceptions. non zero
is returned if the signal was handled by the virtual CPU.  */
@@ -129,4 +144,71 @@ static inline void cpu_get_tb_cpu_state(CPUState* env, 
target_ulong *pc,
 *cs_base = 0;
 *flags = env->psw.mask; // guess
 }
+
+/* Program Status Word.  */
+#define S390_PSWM_REGNUM 0
+#define S390_PSWA_REGNUM 1
+/* General Purpose Registers.  */
+#define S390_R0_REGNUM 2
+#define S390_R1_REGNUM 3
+#define S390_R2_REGNUM 4
+#define S390_R3_REGNUM 5
+#define S390_R4_REGNUM 6
+#define S390_R5_REGNUM 7
+#define S390_R6_REGNUM 8
+#define S390_R7_REGNUM 9
+#define S390_R8_REGNUM 10
+#define S390_R9_REGNUM 11
+#define S390_R10_REGNUM 12
+#define S390_R11_REGNUM 13
+#define S390_R12_REGNUM 14
+#define S390_R13_REGNUM 15
+#define S390_R14_REGNUM 16
+#define S390_R15_REGNUM 17
+/* Access Registers.  */
+#define S390_A0_REGNUM 18
+#define S390_A1_REGNUM 19
+#define S390_A2_REGNUM 20
+#define S390_A3_REGNUM 21
+#define S390_A4_REGNUM 22
+#define S390_A5_REGNUM 23
+#define S390_A6_REGNUM 24
+#define S390_A7_REGNUM 25
+#define S390_A8_REGNUM 26
+#define S390_A9_REGNUM 27
+#define S390_A10_REGNUM 28
+#define S390_A11_REGNUM 29
+#define S390_A12_REGNUM 30
+#define S390_A13_REGNUM 31
+#define S390_A14_REGNUM 32
+#define S390_A15_REGNUM 33
+/* Floating Point Control Word.  */
+#define S390_FPC_REGNUM 34
+/* Floating Point Registers.  */
+#define S390_F0_REGNUM 35
+#define S390_F1_REGNUM 36
+#define S390_F2_REGNUM 37
+#define S390_F3_REGNUM 38
+#define S390_F4_REGNUM 39
+#define S390_F5_REGNUM 40
+#define S390_F6_REGNUM 41
+#define S390_F7_REGNUM 42
+#define S390_F8_REGNUM 43
+#define S390_F9_REGNUM 44
+#define S390_F10_REGNUM 45
+#define S390_F11_REGNUM 46
+#define S390_F12_REGNUM 47
+#define S390_F13_REGNUM 48
+#define S390_F14_REGNUM 49
+#define S390_F15_REGNUM 50
+/* Total.  */
+#define S390_NUM_REGS 51
+
+/* Pseudo registers -- PC and condition code.  */
+#define S390_PC_REGNUM S390_NUM_REGS
+#define S390_CC_REGNUM (S390_NUM_REGS+1)
+#define S390_NUM_PSEUDO_REGS 2
+#define S390_NUM_TOTAL_REGS (S390_NUM_REGS+2)
+
+
 #endif
diff --git a/target-s390x/exec.h b/target-s390x/exec.h
index 5198359..13dc7dd 100644
--- a/target-s390x/exec.h
+++ b/target-s390x/exec.h
@@ -22,9 +22,14 @@
 
 register struct CPUS390XState *env asm(AREG0);
 
+#include "config.h"
 #include "cpu.h"
 #include "exec-all.h"
 
+#if !defined(CONFIG_USER_ONLY)
+#include "softmmu_exec.h"
+#endif /* !defined(CONFIG_USER_ONLY) */
+
 static inline int cpu_has_work(CPUState *env)
 {
 return env->interrupt_request & CPU_INTERRUPT_HARD; // guess
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index 5407c62..d98d603 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -27,6 +27,9 @@
 #include "gdbstub.h"
 #include "qemu-common.h"
 
+#include 
+#include "kvm.h"
+
 CPUS390XState *cpu_s390x_init(const char *cpu_model)
 {
 CPUS390XState *env;
@@ -61,13 +64,13 @@ int cpu_s390x_handle_mmu_fault (CPUState *env, target_ulong 
address, int rw,
 return 1;
 }
 
+#endif /* CONFIG_USER_ONLY */
+
 target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
 {
 return addr;
 }
 
-#endif /* CONFIG_USER_ONLY */
-
 void cpu_reset(CPUS390XState *env)
 {
 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
@@ -79,3 

[Qemu-devel] [PATCH 6/9] S390 GDB stub

2009-10-21 Thread Alexander Graf
In order to debug funny kernel breakages it's always good to have a working
gdb stub around.

While Uli's patches don't include one one, I needed one that's at least good
enough for 'bt' and some variable examinations during early bootup.

So here it is - the absolute basics to get the qemu gdb stub running with s390x
targets.

Sgined-off-by: Alexander Graf 
---
 gdbstub.c |   52 
 1 files changed, 52 insertions(+), 0 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index 315f606..49f6fe3 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1348,6 +1348,55 @@ static int cpu_gdb_write_register(CPUState *env, uint8_t 
*mem_buf, int n)
 
 return 8;
 }
+#elif defined (TARGET_S390X)
+
+#define NUM_CORE_REGS S390_NUM_TOTAL_REGS
+
+static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
+{
+switch (n) {
+case S390_PSWM_REGNUM: GET_REGL(env->psw.mask); break;
+case S390_PSWA_REGNUM: GET_REGL(env->psw.addr); break;
+case S390_R0_REGNUM ... S390_R15_REGNUM:
+GET_REGL(env->regs[n-S390_R0_REGNUM]); break;
+case S390_A0_REGNUM ... S390_A15_REGNUM:
+GET_REG32(env->aregs[n-S390_A0_REGNUM]); break;
+case S390_FPC_REGNUM: GET_REG32(env->fpc); break;
+case S390_F0_REGNUM ... S390_F15_REGNUM:
+/* XXX */
+break;
+case S390_PC_REGNUM: GET_REGL(env->psw.addr); break;
+case S390_CC_REGNUM: GET_REG32(env->cc); break;
+}
+
+return 0;
+}
+
+static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
+{
+target_ulong tmpl;
+uint32_t tmp32;
+int r = 8;
+tmpl = ldtul_p(mem_buf);
+tmp32 = ldl_p(mem_buf);
+
+switch (n) {
+case S390_PSWM_REGNUM: env->psw.mask = tmpl; break;
+case S390_PSWA_REGNUM: env->psw.addr = tmpl; break;
+case S390_R0_REGNUM ... S390_R15_REGNUM:
+env->regs[n-S390_R0_REGNUM] = tmpl; break;
+case S390_A0_REGNUM ... S390_A15_REGNUM:
+env->aregs[n-S390_A0_REGNUM] = tmp32; r=4; break;
+case S390_FPC_REGNUM: env->fpc = tmp32; r=4; break;
+case S390_F0_REGNUM ... S390_F15_REGNUM:
+/* XXX */
+break;
+case S390_PC_REGNUM: env->psw.addr = tmpl; break;
+case S390_CC_REGNUM: env->cc = tmp32; r=4; break;
+}
+
+return r;
+}
 #else
 
 #define NUM_CORE_REGS 0
@@ -1616,6 +1665,9 @@ static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
 s->c_cpu->pc = pc;
 #elif defined (TARGET_ALPHA)
 s->c_cpu->pc = pc;
+#elif defined (TARGET_S390X)
+cpu_synchronize_state(s->c_cpu);
+s->c_cpu->psw.addr = pc;
 #endif
 }
 
-- 
1.6.0.2





[Qemu-devel] [PATCH 2/9] Add KVM support for S390x

2009-10-21 Thread Alexander Graf
S390x was one of the first platforms that received support for KVM back in the
day. Unfortunately until now there hasn't been a qemu implementation that would
enable users to actually run guests.

So let's include support for KVM S390x in qemu!

Signed-off-by: Alexander Graf 

---

v1 -> v2:

 - use new generic psw fields in kvm_run
---
 configure  |4 +-
 target-s390x/kvm.c |  457 
 2 files changed, 460 insertions(+), 1 deletions(-)
 create mode 100644 target-s390x/kvm.c

diff --git a/configure b/configure
index b93fc34..e81492a 100755
--- a/configure
+++ b/configure
@@ -1342,6 +1342,8 @@ EOF
 kvm_cflags="$kvm_cflags -I$kerneldir/arch/x86/include"
elif test "$cpu" = "ppc" -a -d "$kerneldir/arch/powerpc/include" ; then
kvm_cflags="$kvm_cflags -I$kerneldir/arch/powerpc/include"
+   elif test "$cpu" = "s390x" -a -d "$kerneldir/arch/s390/include" ; then
+   kvm_cflags="$kvm_cflags -I$kerneldir/arch/s390/include"
 elif test -d "$kerneldir/arch/$cpu/include" ; then
 kvm_cflags="$kvm_cflags -I$kerneldir/arch/$cpu/include"
   fi
@@ -2306,7 +2308,7 @@ case "$target_arch2" in
 fi
 esac
 case "$target_arch2" in
-  i386|x86_64|ppcemb|ppc|ppc64)
+  i386|x86_64|ppcemb|ppc|ppc64|s390x)
 # Make sure the target and host cpus are compatible
 if test "$kvm" = "yes" -a "$target_softmmu" = "yes" -a \
   \( "$target_arch2" = "$cpu" -o \
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
new file mode 100644
index 000..f50155e
--- /dev/null
+++ b/target-s390x/kvm.c
@@ -0,0 +1,457 @@
+/*
+ * QEMU S390x KVM implementation
+ *
+ * Copyright (c) 2009 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 
+#include 
+#include 
+
+#include 
+#include 
+
+#include "qemu-common.h"
+#include "qemu-timer.h"
+#include "sysemu.h"
+#include "kvm.h"
+#include "cpu.h"
+#include "device_tree.h"
+
+/* #define DEBUG_KVM */
+
+#ifdef DEBUG_KVM
+#define dprintf(fmt, ...) \
+do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
+#else
+#define dprintf(fmt, ...) \
+do { } while (0)
+#endif
+
+#define IPA0_DIAG   0x8300
+#define IPA0_SIGP   0xae00
+#define IPA0_PRIV   0xb200
+
+#define PRIV_SCLP_CALL  0x20
+#define DIAG_KVM_HYPERCALL  0x500
+#define DIAG_KVM_BREAKPOINT 0x501
+
+#define SCP_LENGTH  0x00
+#define SCP_FUNCTION_CODE   0x02
+#define SCP_CONTROL_MASK0x03
+#define SCP_RESPONSE_CODE   0x06
+#define SCP_MEM_CODE0x08
+#define SCP_INCREMENT   0x0a
+
+#define ICPT_INSTRUCTION0x04
+#define ICPT_WAITPSW0x1c
+#define ICPT_SOFT_INTERCEPT 0x24
+#define ICPT_CPU_STOP   0x28
+#define ICPT_IO 0x40
+
+#define SIGP_RESTART0x06
+#define SIGP_INITIAL_CPU_RESET  0x0b
+#define SIGP_STORE_STATUS_ADDR  0x0e
+#define SIGP_SET_ARCH   0x12
+
+
+int kvm_arch_init(KVMState *s, int smp_cpus)
+{
+return 0;
+}
+
+int kvm_arch_init_vcpu(CPUState *env)
+{
+int ret = 0;
+
+if (kvm_vcpu_ioctl(env, KVM_S390_INITIAL_RESET, NULL) < 0)
+perror("cannot init reset vcpu");
+
+return ret;
+}
+
+int kvm_arch_put_registers(CPUState *env)
+{
+struct kvm_regs regs;
+int ret;
+int i;
+
+ret = kvm_vcpu_ioctl(env, KVM_GET_REGS, ®s);
+if (ret < 0)
+return ret;
+
+for (i = 0; i < 16; i++)
+regs.gprs[i] = env->regs[i];
+
+ret = kvm_vcpu_ioctl(env, KVM_SET_REGS, ®s);
+if (ret < 0)
+return ret;
+
+env->kvm_run->psw_addr = env->psw.addr;
+env->kvm_run->psw_mask = env->psw.mask;
+
+return ret;
+}
+
+int kvm_arch_get_registers(CPUState *env)
+{
+uint32_t ret;
+struct kvm_regs regs;
+int i;
+
+ret = kvm_vcpu_ioctl(env, KVM_GET_REGS, ®s);
+if (ret < 0)
+return ret;
+
+for (i = 0; i < 16; i++)
+env->regs[i] = regs.gprs[i];
+
+env->psw.addr = env->kvm_run->psw_addr;
+env->psw.mask = env->kvm_run->psw_mask;
+
+return 0;
+}
+
+int kvm_arch_insert_sw_breakpoint(CPUState *env, struct kvm_sw_breakpoint *bp)
+{
+static const uint8_t diag_501[] = {0x83, 0x24, 0x05, 0x01};
+
+if (cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&bp->saved_insn, 4, 0) ||
+cpu_memory_rw_debug(env, bp->

[Qemu-devel] [PATCH 0/9] S390x KVM support v2

2009-10-21 Thread Alexander Graf
While S390x was one of the first targets that were supported by KVM it always
lacked qemu system emulation support.

In order to change that sad fact, I figured I'd just take on the task myself,
taking kuli (http://www.ibm.com/developerworks/linux/linux390/kuli.html),
Documentation/s390/kvm.txt and lguest as starting points to write a clean,
qemu'ish S390x Virtio machine emulation.

So now you can run Linux VMs on Linux on z/VM on LPAR on zSeries!

This is the resulting code. Please comment on things you like and also on the
ones you don't :-).

The patchset is based on Uli's S390x userspace emulation patches. There's not
really that much shared functionality, but I didn't want to reimplement the
configure wheels. So make sure to have his patches applied first.

Please only run S390x system virtualization using io threads. S390x has very
few intercepts and even less that actually reach userspace. So you'll end up
with a non-responsive VM without a dedicated IO thread.

Use: $ ./configure --target-list=s390x-softmmu --enable-io-thread

Currently only -kernel, -initrd and friends work. Booting from a real dasd
device is not supported.

Also to actually run this code you need a patch for an ugly bug in the kernel
module that Carsten sent a patch to on the ML.

I verified that the userspace actually works on a 2.6.27 (SLES11) kernel, so
if it doesn't work on current git, please tell me! I'm too afraid that I might
end up in a 3270 terminal to update the kernel on my z/VM instance :-).

v1 -> v2:

  - use new kvm_run variables
  - use DO_UPCAST
  - add bridge device for "info qtree"

Alexander Graf (9):
  Export function for VA defined ram allocation
  Add KVM support for S390x
  Add support for S390x system emulation
  Add S390x virtio machine bus
  Add S390x virtio machine description
  S390 GDB stub
  Implement early printk in virtio-console
  Set default console to virtio on S390x
  Move mp_state to CPU_COMMON

 Makefile.target  |2 +
 configure|4 +-
 cpu-common.h |1 +
 cpu-defs.h   |1 +
 exec.c   |   15 ++-
 gdbstub.c|   52 ++
 hw/s390-virtio-bus.c |  384 ++
 hw/s390-virtio-bus.h |   64 +++
 hw/s390-virtio.c |  244 
 hw/virtio-console.c  |7 +
 hw/virtio-console.h  |2 +
 target-i386/cpu.h|1 -
 target-s390x/cpu.h   |   86 +-
 target-s390x/exec.h  |5 +
 target-s390x/helper.c|   26 +++-
 target-s390x/kvm.c   |  457 ++
 target-s390x/machine.c   |   30 +++
 target-s390x/op_helper.c |   53 ++
 vl.c |   26 +++
 19 files changed, 1452 insertions(+), 8 deletions(-)
 create mode 100644 hw/s390-virtio-bus.c
 create mode 100644 hw/s390-virtio-bus.h
 create mode 100644 hw/s390-virtio.c
 create mode 100644 target-s390x/kvm.c
 create mode 100644 target-s390x/machine.c





[Qemu-devel] [PATCH 4/9] Add S390x virtio machine bus

2009-10-21 Thread Alexander Graf
On S390x we don't want to go through the hassle of emulating real existing
hardware, because we don't need to for running Linux.

So let's instead implement a machine that is 100% based on VirtIO which we
fortunately implement already.

This patch implements the bus that is the groundwork for such an S390x
virtio machine.

Signed-off-by: Alexander Graf 

---

v1 -> v2:

  - use DO_UPCAST
  - add bridge device for "info qtree"
---
 Makefile.target  |2 +
 hw/s390-virtio-bus.c |  384 ++
 hw/s390-virtio-bus.h |   64 +
 3 files changed, 450 insertions(+), 0 deletions(-)
 create mode 100644 hw/s390-virtio-bus.c
 create mode 100644 hw/s390-virtio-bus.h

diff --git a/Makefile.target b/Makefile.target
index 8d146c5..ef72867 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -294,6 +294,8 @@ obj-sh4-y += ide/core.o ide/mmio.o
 obj-m68k-y = an5206.o mcf5206.o mcf_uart.o mcf_intc.o mcf5208.o mcf_fec.o
 obj-m68k-y += m68k-semi.o dummy_m68k.o
 
+obj-s390x-y = s390-virtio-bus.o
+
 main.o vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
 
 vl.o: QEMU_CFLAGS+=$(SDL_CFLAGS)
diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
new file mode 100644
index 000..84a004f
--- /dev/null
+++ b/hw/s390-virtio-bus.c
@@ -0,0 +1,384 @@
+/*
+ * QEMU S390 virtio target
+ *
+ * Copyright (c) 2009 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 "hw.h"
+#include "block.h"
+#include "sysemu.h"
+#include "net.h"
+#include "boards.h"
+#include "monitor.h"
+#include "loader.h"
+#include "elf.h"
+#include "hw/virtio.h"
+#include "hw/virtio-console.h"
+#include "hw/sysbus.h"
+#include "kvm.h"
+
+#include "hw/s390-virtio-bus.h"
+
+//#define DEBUG_S390
+
+#ifdef DEBUG_S390
+#define dprintf(fmt, ...) \
+do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
+#else
+#define dprintf(fmt, ...) \
+do { } while (0)
+#endif
+
+struct BusInfo s390_virtio_bus_info = {
+.name   = "s390-virtio",
+.size   = sizeof(VirtIOS390Bus),
+};
+
+typedef struct {
+DeviceInfo qdev;
+int (*init)(VirtIOS390Device *dev);
+} VirtIOS390DeviceInfo;
+
+
+static const VirtIOBindings virtio_s390_bindings;
+
+static ram_addr_t s390_virtio_device_num_vq(VirtIOS390Device *dev);
+static void s390_virtio_device_sync(VirtIOS390Device *dev);
+
+VirtIOS390Bus *s390_virtio_bus_init(ram_addr_t *ram_size)
+{
+VirtIOS390Bus *bus;
+BusState *_bus;
+DeviceState *dev;
+
+/* Create bridge device */
+dev = qdev_create(NULL, "s390-virtio-bridge");
+qdev_init_nofail(dev);
+
+/* Create bus on bridge device */
+
+_bus = qbus_create(&s390_virtio_bus_info, dev, "s390-virtio");
+bus = DO_UPCAST(VirtIOS390Bus, bus, _bus);
+
+bus->dev_page = *ram_size;
+bus->dev_offs = bus->dev_page;
+bus->next_ring = bus->dev_page + TARGET_PAGE_SIZE;
+
+/* Allocate RAM for VirtIO device pages (descriptors, queues, rings) */
+*ram_size += S390_DEVICE_PAGES * TARGET_PAGE_SIZE;
+
+return bus;
+}
+
+static int s390_virtio_device_init(VirtIOS390Device *dev, VirtIODevice *vdev)
+{
+VirtIOS390Bus *bus;
+int dev_len;
+
+bus = DO_UPCAST(VirtIOS390Bus, bus, dev->qdev.parent_bus);
+dev->vdev = vdev;
+dev->dev_offs = bus->dev_offs;
+dev->feat_len = sizeof(uint32_t); /* always keep 32 bits features */
+
+dev_len = VIRTIO_DEV_OFFS_CONFIG;
+dev_len += s390_virtio_device_num_vq(dev) * VIRTIO_VQCONFIG_LEN;
+dev_len += dev->feat_len * 2;
+dev_len += vdev->config_len;
+
+bus->dev_offs += dev_len;
+
+virtio_bind_device(vdev, &virtio_s390_bindings, dev);
+s390_virtio_device_sync(dev);
+
+return 0;
+}
+
+static int s390_virtio_net_init(VirtIOS390Device *dev)
+{
+VirtIODevice *vdev;
+
+vdev = virtio_net_init((DeviceState *)dev);
+if (!vdev)
+return -1;
+
+return s390_virtio_device_init(dev, vdev);
+}
+
+static int s390_virtio_blk_init(VirtIOS390Device *dev)
+{
+VirtIODevice *vdev;
+
+vdev = virtio_blk_init((DeviceState *)dev, dev->dinfo);
+if (!vdev)
+return -1;
+
+return s390_virtio_device_init(dev, vdev);
+}
+
+static int s390_virtio_console_init(VirtIOS390Device *dev)
+{
+VirtIOS390Bus *bus;
+VirtIODevice *vdev;
+int r;
+
+bus = DO_UPCAST(VirtIOS390Bus, bus, dev->qdev.parent_bus);
+
+vdev = virtio_console_init((

[Qemu-devel] [PATCH 8/9] Set default console to virtio on S390x

2009-10-21 Thread Alexander Graf
All "normal" system emulation targets in qemu I'm aware of display output
on either VGA or serial output.

Our S390x virtio machine doesn't have such kind of legacy hardware. So
instead we need to default to a virtio console.

I'm not particularly proud of this patch. It would be a lot better to
have something in the machine description that tells us about the default
terminal.

Signed-off-by: Alexander Graf 
---
 vl.c |   26 ++
 1 files changed, 26 insertions(+), 0 deletions(-)

diff --git a/vl.c b/vl.c
index eb2744e..e7f1504 100644
--- a/vl.c
+++ b/vl.c
@@ -4818,6 +4818,20 @@ int main(int argc, char **argv, char **envp)
 cyls = heads = secs = 0;
 translation = BIOS_ATA_TRANSLATION_AUTO;
 
+#ifdef TARGET_S390X
+for(i = 0; i < MAX_SERIAL_PORTS; i++)
+serial_devices[i] = NULL;
+serial_device_index = 0;
+
+for(i = 0; i < MAX_PARALLEL_PORTS; i++)
+parallel_devices[i] = NULL;
+parallel_device_index = 0;
+
+virtio_consoles[0] = "mon:stdio";
+for(i = 1; i < MAX_VIRTIO_CONSOLES; i++)
+virtio_consoles[i] = NULL;
+virtio_console_index = 0;
+#else
 serial_devices[0] = "vc:80Cx24C";
 for(i = 1; i < MAX_SERIAL_PORTS; i++)
 serial_devices[i] = NULL;
@@ -4831,6 +4845,7 @@ int main(int argc, char **argv, char **envp)
 for(i = 0; i < MAX_VIRTIO_CONSOLES; i++)
 virtio_consoles[i] = NULL;
 virtio_console_index = 0;
+#endif
 
 monitor_devices[0] = "vc:80Cx24C";
 for (i = 1; i < MAX_MONITOR_DEVICES; i++) {
@@ -5709,6 +5724,17 @@ int main(int argc, char **argv, char **envp)
 break;
 }
 }
+for (i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
+const char *devname = virtio_consoles[i];
+if (devname && !strcmp(devname,"mon:stdio")) {
+monitor_devices[0] = NULL;
+break;
+} else if (devname && !strcmp(devname,"stdio")) {
+monitor_devices[0] = NULL;
+virtio_consoles[i] = "mon:stdio";
+break;
+}
+}
 }
 
 if (nb_numa_nodes > 0) {
-- 
1.6.0.2





[Qemu-devel] Re: [PATCH 2/2] multiboot: Limit number of multiboot modules

2009-10-21 Thread Kevin Wolf
Am 21.10.2009 01:05, schrieb Juan Quintela:
> Adam Lackorzynski  wrote:
> 
> Hi
> 
>> +enum {
>> +/* Multiboot info */
>> +MBI_FLAGS   = 0,
>> +MBI_MEM_LOWER   = 4,
>> +MBI_MEM_UPPER   = 8,
>> +MBI_BOOT_DEVICE = 12,
>> +MBI_CMDLINE = 16,
>> +MBI_MODS_COUNT  = 20,
>> +MBI_MODS_ADDR   = 24,
>> +MBI_MMAP_ADDR   = 48,
>> +
>> +MBI_SIZE= 88,
>> +
>> +/* Multiboot modules */
>> +MB_MOD_START= 0,
>> +MB_MOD_END  = 4,
>> +MB_MOD_CMDLINE  = 8,
>> +
>> +MB_MOD_SIZE = 16,
>> +
>> +/* Region offsets */
>> +ADDR_E820_MAP = MULTIBOOT_STRUCT_ADDR + 0,
>> +ADDR_MBI  = ADDR_E820_MAP + 0x500,
>> +
>> +/* Multiboot flags */
>> +MULTIBOOT_FLAGS_MEMORY  = 1 << 0,
>> +MULTIBOOT_FLAGS_BOOT_DEVICE = 1 << 1,
>> +MULTIBOOT_FLAGS_CMDLINE = 1 << 2,
>> +MULTIBOOT_FLAGS_MODULES = 1 << 3,
>> +MULTIBOOT_FLAGS_MMAP= 1 << 6,
>> +};
> 
> Why do you use a single enum, without name, and repeating the values?
> I think that using more than one enum is better here.

Right, this looks a bit strange even though it's correct. Otherwise the
new patch looks okay and I'd suggest to submit it for inclusion.

Kevin




[Qemu-devel] PCI address question

2009-10-21 Thread Màrius Montón
Hello,

For my PCI device to QEMU, I need the real address the PCI bus is using
to access my device. For a IO BAR (PCI_ADDRESS_SPACE_IO), I receive the
real address (like 0xc200 or similar), but when registering a
PCI_ADDRESS_SPACE_MEM I only receive the offset to the BAR.

How I can receive or obtaint the real address on each access to my device?

Cjeers,

Màrius
<>

[Qemu-devel] [PATCH 00/12] target-arm: miscellaneous fixes

2009-10-21 Thread Juha.Riihimaki
Hi,

This patch series includes a number of smaller fixes and improvements  
to the ARM translator. The series should be applied in sequence as the  
modifications are all but one related to the same file, target-arm/ 
translate.c. The whole series should apply cleanly against latest git  
AFTER applying the resource leak patch which I sent on this list  
couple of days ago.


Cheers,
Juha




[Qemu-devel] [PATCH 03/12] target-arm: add support for neon vld1.64 instruction

2009-10-21 Thread Juha.Riihimaki
Add support for neon vld1.64 instruction.

From: Riku Voipio 
Signed-off-by: Juha Riihimäki 
---
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 3ea9d51..d027572 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -795,6 +795,12 @@ static inline TCGv gen_ld32(TCGv addr, int index)
  tcg_gen_qemu_ld32u(tmp, addr, index);
  return tmp;
  }
+static inline TCGv_i64 gen_ld64(TCGv addr, int index)
+{
+TCGv_i64 tmp = tcg_temp_new_i64();
+tcg_gen_qemu_ld64(tmp, addr, index);
+return tmp;
+}
  static inline void gen_st8(TCGv val, TCGv addr, int index)
  {
  tcg_gen_qemu_st8(val, addr, index);
@@ -810,6 +816,11 @@ static inline void gen_st32(TCGv val, TCGv addr,  
int index)
  tcg_gen_qemu_st32(val, addr, index);
  dead_tmp(val);
  }
+static inline void gen_st64(TCGv_i64 val, TCGv addr, int index)
+{
+tcg_gen_qemu_st64(val, addr, index);
+tcg_temp_free_i64(val);
+}

  static inline void gen_set_pc_im(uint32_t val)
  {
@@ -3690,6 +3701,7 @@ static int disas_neon_ls_insn(CPUState * env,  
DisasContext *s, uint32_t insn)
  TCGv addr;
  TCGv tmp;
  TCGv tmp2;
+TCGv_i64 tmp64;

  if (!vfp_enabled(env))
return 1;
@@ -3702,7 +3714,7 @@ static int disas_neon_ls_insn(CPUState * env,  
DisasContext *s, uint32_t insn)
  /* Load store all elements.  */
  op = (insn >> 8) & 0xf;
  size = (insn >> 6) & 3;
-if (op > 10 || size == 3)
+if (op > 10)
  return 1;
  nregs = neon_ls_element_type[op].nregs;
  interleave = neon_ls_element_type[op].interleave;
@@ -3716,61 +3728,74 @@ static int disas_neon_ls_insn(CPUState * env,  
DisasContext *s, uint32_t insn)
  load_reg_var(s, addr, rn);
  tcg_gen_addi_i32(addr, addr, 1 << size);
  }
-for (pass = 0; pass < 2; pass++) {
-if (size == 2) {
-if (load) {
-tmp = gen_ld32(addr, IS_USER(s));
-neon_store_reg(rd, pass, tmp);
-} else {
-tmp = neon_load_reg(rd, pass);
-gen_st32(tmp, addr, IS_USER(s));
-}
-tcg_gen_addi_i32(addr, addr, stride);
-} else if (size == 1) {
-if (load) {
-tmp = gen_ld16u(addr, IS_USER(s));
-tcg_gen_addi_i32(addr, addr, stride);
-tmp2 = gen_ld16u(addr, IS_USER(s));
-tcg_gen_addi_i32(addr, addr, stride);
-gen_bfi(tmp, tmp, tmp2, 16, 0x);
-dead_tmp(tmp2);
-neon_store_reg(rd, pass, tmp);
-} else {
-tmp = neon_load_reg(rd, pass);
-tmp2 = new_tmp();
-tcg_gen_shri_i32(tmp2, tmp, 16);
-gen_st16(tmp, addr, IS_USER(s));
-tcg_gen_addi_i32(addr, addr, stride);
-gen_st16(tmp2, addr, IS_USER(s));
+if (size == 3) {
+if (load) {
+tmp64 = gen_ld64(addr, IS_USER(s));
+neon_store_reg64(tmp64, rd);
+tcg_temp_free_i64(tmp64);
+} else {
+tmp64 = tcg_temp_new_i64();
+neon_load_reg64(tmp64, rd);
+gen_st64(tmp64, addr, IS_USER(s));
+}
+tcg_gen_addi_i32(addr, addr, stride);
+} else {
+for (pass = 0; pass < 2; pass++) {
+if (size == 2) {
+if (load) {
+tmp = gen_ld32(addr, IS_USER(s));
+neon_store_reg(rd, pass, tmp);
+} else {
+tmp = neon_load_reg(rd, pass);
+gen_st32(tmp, addr, IS_USER(s));
+}
  tcg_gen_addi_i32(addr, addr, stride);
-}
-} else /* size == 0 */ {
-if (load) {
-TCGV_UNUSED(tmp2);
-for (n = 0; n < 4; n++) {
-tmp = gen_ld8u(addr, IS_USER(s));
+} else if (size == 1) {
+if (load) {
+tmp = gen_ld16u(addr, IS_USER(s));
+tcg_gen_addi_i32(addr, addr, stride);
+tmp2 = gen_ld16u(addr, IS_USER(s));
+tcg_gen_addi_i32(addr, addr, stride);
+gen_bfi(tmp, tmp, tmp2, 16, 0x);
+dead_tmp(tmp2);
+neon_store_reg(rd, pass, tmp);
+} else {
+tmp = neon_load_reg(rd, pass);

[Qemu-devel] [PATCH 02/12] target-arm: optimize thumb 32bit multiply

2009-10-21 Thread Juha.Riihimaki
Current implementation of thumb mul instruction is implemented as a  
32x32->64 multiply which then uses only 32 least significant bits of  
the result. Replace that with a simple 32x32->32 multiply.

Signed-off-by: Juha Riihimäki 
---
diff --git a/target-arm/translate.c b/target-arm/translate.c
index bda105e..3ea9d51 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -310,22 +310,6 @@ static TCGv_i64 gen_muls_i64_i32(TCGv a, TCGv b)
  return tmp1;
  }

-/* Unsigned 32x32->64 multiply.  */
-static void gen_mull(TCGv a, TCGv b)
-{
-TCGv_i64 tmp1 = tcg_temp_new_i64();
-TCGv_i64 tmp2 = tcg_temp_new_i64();
-
-tcg_gen_extu_i32_i64(tmp1, a);
-tcg_gen_extu_i32_i64(tmp2, b);
-tcg_gen_mul_i64(tmp1, tmp1, tmp2);
-tcg_temp_free_i64(tmp2);
-tcg_gen_trunc_i64_i32(a, tmp1);
-tcg_gen_shri_i64(tmp1, tmp1, 32);
-tcg_gen_trunc_i64_i32(b, tmp1);
-tcg_temp_free_i64(tmp1);
-}
-
  /* Signed 32x32->64 multiply.  */
  static void gen_imull(TCGv a, TCGv b)
  {
@@ -8358,7 +8342,7 @@ static void disas_thumb_insn(CPUState *env,  
DisasContext *s)
  gen_logic_CC(tmp);
  break;
  case 0xd: /* mul */
-gen_mull(tmp, tmp2);
+tcg_gen_mul_i32(tmp, tmp, tmp2);
  if (!s->condexec_mask)
  gen_logic_CC(tmp);
  break;


translate.c.genmull.diff
Description: translate.c.genmull.diff


[Qemu-devel] [PATCH 07/12] target-arm: fix neon vsri, vshl and vsli ops

2009-10-21 Thread Juha.Riihimaki
Shift immediate value is incorrectly overwritten by a temporary  
variable in the processing of NEON vsri, vshl and vsli instructions.

Signed-off-by: Juha Riihimäki 
---
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 59bf7bc..c92ecc6 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -4094,7 +4094,7 @@ static int disas_neon_data_insn(CPUState * env,  
DisasContext *s, uint32_t insn)
  int pairwise;
  int u;
  int n;
-uint32_t imm;
+uint32_t imm, imm2;
  TCGv tmp;
  TCGv tmp2;
  TCGv tmp3;
@@ -4624,31 +4624,31 @@ static int disas_neon_data_insn(CPUState *  
env, DisasContext *s, uint32_t insn)
  switch (size) {
  case 0:
  if (op == 4)
-imm = 0xff >> -shift;
+imm2 = 0xff >> -shift;
  else
-imm = (uint8_t)(0xff << shift);
-imm |= imm << 8;
-imm |= imm << 16;
+imm2 = (uint8_t)(0xff << shift);
+imm2 |= imm2 << 8;
+imm2 |= imm2 << 16;
  break;
  case 1:
  if (op == 4)
-imm = 0x >> -shift;
+imm2 = 0x >> -shift;
  else
-imm = (uint16_t)(0x << shift);
-imm |= imm << 16;
+imm2 = (uint16_t)(0x << shift);
+imm2 |= imm2 << 16;
  break;
  case 2:
  if (op == 4)
-imm = 0xu >> -shift;
+imm2 = 0xu >> -shift;
  else
-imm = 0xu << shift;
+imm2 = 0xu << shift;
  break;
  default:
  abort();
  }
  tmp2 = neon_load_reg(rd, pass);
-tcg_gen_andi_i32(tmp, tmp, imm);
-tcg_gen_andi_i32(tmp2, tmp2, ~imm);
+tcg_gen_andi_i32(tmp, tmp, imm2);
+tcg_gen_andi_i32(tmp2, tmp2, ~imm2);
  tcg_gen_or_i32(tmp, tmp, tmp2);
  dead_tmp(tmp2);
  }


translate.c.neonimm.diff
Description: translate.c.neonimm.diff


[Qemu-devel] [PATCH 06/12] target-arm: optimize arm load/store multiple ops

2009-10-21 Thread Juha.Riihimaki
ARM load/store multiple instructions can be slightly optimized by  
loading the register offset constant into a variable outside the  
register loop and using the preloaded variable inside the loop instead  
of reloading the offset value to a temporary variable on each loop  
iteration. This causes less TCG ops to be generated for a ARM load/ 
store multiple instruction.

Signed-off-by: Juha Riihimäki 
---
diff --git a/target-arm/translate.c b/target-arm/translate.c
index e5a2881..bae1122 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6852,6 +6852,7 @@ static void disas_arm_insn(CPUState * env,  
DisasContext *s)
  }
  rn = (insn >> 16) & 0xf;
  addr = load_reg(s, rn);
+tmp2 = tcg_const_i32(4);

  /* compute total size */
  loaded_base = 0;
@@ -6865,7 +6866,7 @@ static void disas_arm_insn(CPUState * env,  
DisasContext *s)
  if (insn & (1 << 23)) {
  if (insn & (1 << 24)) {
  /* pre increment */
-tcg_gen_addi_i32(addr, addr, 4);
+tcg_gen_add_i32(addr, addr, tmp2);
  } else {
  /* post increment */
  }
@@ -6918,7 +6919,7 @@ static void disas_arm_insn(CPUState * env,  
DisasContext *s)
  j++;
  /* no need to add after the last transfer */
  if (j != n)
-tcg_gen_addi_i32(addr, addr, 4);
+tcg_gen_add_i32(addr, addr, tmp2);
  }
  }
  if (insn & (1 << 21)) {
@@ -6928,7 +6929,7 @@ static void disas_arm_insn(CPUState * env,  
DisasContext *s)
  /* pre increment */
  } else {
  /* post increment */
-tcg_gen_addi_i32(addr, addr, 4);
+tcg_gen_add_i32(addr, addr, tmp2);
  }
  } else {
  if (insn & (1 << 24)) {
@@ -6944,6 +6945,7 @@ static void disas_arm_insn(CPUState * env,  
DisasContext *s)
  } else {
  dead_tmp(addr);
  }
+tcg_temp_free_i32(tmp2);
  if (loaded_base) {
  store_reg(s, rn, loaded_var);
  }


translate.c.ldmstm.diff
Description: translate.c.ldmstm.diff


[Qemu-devel] [PATCH 10/12] target-arm: replace tcg_gen_rori_i32 by tcg_gen_rotri_i32

2009-10-21 Thread Juha.Riihimaki
Use native rotation if possible instead of a simulated one.

From: Filip Navara 
Signed-off-by: Juha Riihimäki 
---
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 99a9ffd..1734fae 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -418,21 +418,6 @@ static inline void tcg_gen_bic_i32(TCGv dest,  
TCGv t0, TCGv t1)
  /* FIXME:  Implement this natively.  */
  #define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1)

-/* FIXME:  Implement this natively.  */
-static void tcg_gen_rori_i32(TCGv t0, TCGv t1, int i)
-{
-TCGv tmp;
-
-if (i == 0)
-return;
-
-tmp = new_tmp();
-tcg_gen_shri_i32(tmp, t1, i);
-tcg_gen_shli_i32(t1, t1, 32 - i);
-tcg_gen_or_i32(t0, t1, tmp);
-dead_tmp(tmp);
-}
-
  static void shifter_out_im(TCGv var, int shift)
  {
  TCGv tmp = new_tmp();
@@ -484,7 +469,7 @@ static inline void gen_arm_shift_im(TCGv var, int  
shiftop, int shift, int flags)
  if (shift != 0) {
  if (flags)
  shifter_out_im(var, shift - 1);
-tcg_gen_rori_i32(var, var, shift); break;
+tcg_gen_rotri_i32(var, var, shift); break;
  } else {
  TCGv tmp = load_cpu_field(CF);
  if (flags)
@@ -6634,7 +6619,7 @@ static void disas_arm_insn(CPUState * env,  
DisasContext *s)
  /* ??? In many cases it's not neccessary to  
do a
 rotate, a shift is sufficient.  */
  if (shift != 0)
-tcg_gen_rori_i32(tmp, tmp, shift * 8);
+tcg_gen_rotri_i32(tmp, tmp, shift * 8);
  op1 = (insn >> 20) & 7;
  switch (op1) {
  case 0: gen_sxtb16(tmp);  break;
@@ -7451,7 +7436,7 @@ static int disas_thumb2_insn(CPUState *env,  
DisasContext *s, uint16_t insn_hw1)
  /* ??? In many cases it's not neccessary to do a
 rotate, a shift is sufficient.  */
  if (shift != 0)
-tcg_gen_rori_i32(tmp, tmp, shift * 8);
+tcg_gen_rotri_i32(tmp, tmp, shift * 8);
  op = (insn >> 20) & 7;
  switch (op) {
  case 0: gen_sxth(tmp);   break;


translate.c.rori.diff
Description: translate.c.rori.diff


[Qemu-devel] [PATCH 01/12] target-arm: fix resource leak in gen_set_cpsr macro

2009-10-21 Thread Juha.Riihimaki
Current implementation of the gen_set_cpsr macro creates a new  
temporary tcg variable through the tcg_const_i32 call but never marks  
it dead.

Signed-off-by: Juha Riihimäki 
---
diff --git a/target-arm/translate.c b/target-arm/translate.c
index bc51bcb..bda105e 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -184,7 +184,12 @@ static void store_reg(DisasContext *s, int reg,  
TCGv var)
  #define gen_uxtb16(var) gen_helper_uxtb16(var, var)


-#define gen_set_cpsr(var, mask) gen_helper_cpsr_write(var,  
tcg_const_i32(mask))
+#define gen_set_cpsr(var, mask) \
+{ \
+TCGv tmp_mask = tcg_const_i32(mask); \
+gen_helper_cpsr_write(var, tmp_mask); \
+tcg_temp_free_i32(tmp_mask); \
+}
  /* Set NZCV flags from the high 4 bits of var.  */
  #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)


translate.c.gensetcpsr.diff
Description: translate.c.gensetcpsr.diff


[Qemu-devel] [PATCH 11/12] target-arm: optimize neon vld/vst ops

2009-10-21 Thread Juha.Riihimaki
Reduce the amount of tcg ops generated from NEON vld/vst instructions  
by simplifying the code generation.

Signed-off-by: Juha Riihimäki 
---
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 1734fae..fa03df8 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -3692,6 +3692,7 @@ static int disas_neon_ls_insn(CPUState * env,  
DisasContext *s, uint32_t insn)
  TCGv tmp;
  TCGv tmp2;
  TCGv_i64 tmp64;
+TCGv stride_v;

  if (!vfp_enabled(env))
return 1;
@@ -3710,6 +3711,7 @@ static int disas_neon_ls_insn(CPUState * env,  
DisasContext *s, uint32_t insn)
  interleave = neon_ls_element_type[op].interleave;
  load_reg_var(s, addr, rn);
  stride = (1 << size) * interleave;
+stride_v = tcg_const_i32(stride);
  for (reg = 0; reg < nregs; reg++) {
  if (interleave > 2 || (interleave == 2 && nregs == 2)) {
  load_reg_var(s, addr, rn);
@@ -3728,7 +3730,7 @@ static int disas_neon_ls_insn(CPUState * env,  
DisasContext *s, uint32_t insn)
  neon_load_reg64(tmp64, rd);
  gen_st64(tmp64, addr, IS_USER(s));
  }
-tcg_gen_addi_i32(addr, addr, stride);
+tcg_gen_add_i32(addr, addr, stride_v);
  } else {
  for (pass = 0; pass < 2; pass++) {
  if (size == 2) {
@@ -3739,58 +3741,57 @@ static int disas_neon_ls_insn(CPUState * env,  
DisasContext *s, uint32_t insn)
  tmp = neon_load_reg(rd, pass);
  gen_st32(tmp, addr, IS_USER(s));
  }
-tcg_gen_addi_i32(addr, addr, stride);
+tcg_gen_add_i32(addr, addr, stride_v);
  } else if (size == 1) {
  if (load) {
  tmp = gen_ld16u(addr, IS_USER(s));
  tcg_gen_addi_i32(addr, addr, stride);
  tmp2 = gen_ld16u(addr, IS_USER(s));
-tcg_gen_addi_i32(addr, addr, stride);
-gen_bfi(tmp, tmp, tmp2, 16, 0x);
+tcg_gen_add_i32(addr, addr, stride_v);
+tcg_gen_shli_i32(tmp2, tmp2, 16);
+tcg_gen_or_i32(tmp, tmp, tmp2);
  dead_tmp(tmp2);
  neon_store_reg(rd, pass, tmp);
  } else {
  tmp = neon_load_reg(rd, pass);
-tmp2 = new_tmp();
-tcg_gen_shri_i32(tmp2, tmp, 16);
-gen_st16(tmp, addr, IS_USER(s));
-tcg_gen_addi_i32(addr, addr, stride);
-gen_st16(tmp2, addr, IS_USER(s));
-tcg_gen_addi_i32(addr, addr, stride);
+tcg_gen_qemu_st16(tmp, addr, IS_USER(s));
+tcg_gen_add_i32(addr, addr, stride_v);
+tcg_gen_shri_i32(tmp, tmp, 16);
+tcg_gen_qemu_st16(tmp, addr, IS_USER(s));
+tcg_gen_add_i32(addr, addr, stride_v);
+dead_tmp(tmp);
  }
  } else /* size == 0 */ {
  if (load) {
-TCGV_UNUSED(tmp2);
-for (n = 0; n < 4; n++) {
-tmp = gen_ld8u(addr, IS_USER(s));
-tcg_gen_addi_i32(addr, addr, stride);
-if (n == 0) {
-tmp2 = tmp;
-} else {
-gen_bfi(tmp2, tmp2, tmp, n * 8,  
0xff);
-dead_tmp(tmp);
-}
+tmp = gen_ld8u(addr, IS_USER(s));
+tcg_gen_add_i32(addr, addr, stride_v);
+for (n = 1; n < 4; n++) {
+tmp2 = gen_ld8u(addr, IS_USER(s));
+tcg_gen_add_i32(addr, addr, stride_v);
+tcg_gen_shli_i32(tmp2, tmp2, n * 8);
+tcg_gen_or_i32(tmp, tmp, tmp2);
+dead_tmp(tmp2);
  }
-neon_store_reg(rd, pass, tmp2);
+neon_store_reg(rd, pass, tmp);
  } else {
-tmp2 = neon_load_reg(rd, pass);
-for (n = 0; n < 4; n++) {
-tmp = new_tmp();
-if (n == 0) {
-tcg_gen_mov_i32(tmp, tmp2);

[Qemu-devel] [PATCH 04/12] target-arm: allow modifying vfp fpexc en bit only

2009-10-21 Thread Juha.Riihimaki
All other bits except for the EN in the VFP FPEXC register are defined  
as subarchitecture specific and real functionality for any of the  
other bits has not been implemented in QEMU. However, current code  
allows modifying all bits in the VFP FPEXC register leading to  
problems when guest code is writing 1's to the subarchitecture  
specific bits and checking whether the bits stay up to verify the  
existence of functionality which in fact does not exist in QEMU.

Signed-off-by: Juha Riihimäki 
---
diff --git a/target-arm/translate.c b/target-arm/translate.c
index d027572..07ee638 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -2788,6 +2788,9 @@ static int disas_vfp_insn(CPUState * env,  
DisasContext *s, uint32_t insn)
  case ARM_VFP_FPEXC:
  if (IS_USER(s))
  return 1;
+/* TODO: VFP subarchitecture support.
+ * For now, keep the EN bit only */
+tcg_gen_andi_i32(tmp, tmp, 1 << 30);
  store_cpu_field(tmp, vfp.xregs[rn]);
  gen_lookup_tb(s);
  break;


translate.c.vfpfpexc.diff
Description: translate.c.vfpfpexc.diff


[Qemu-devel] [PATCH 12/12] target-arm: fix neon shift helper functions

2009-10-21 Thread Juha.Riihimaki
Current code is broken at least on gcc 4.2, the result of a comparison  
"-1 >= sizeof(type) * 8" results true and causes wrong code path to be  
taken. The fix utilizes abs() function where applicable and otherwise  
adds a test to ensure both arguments are positive before making the  
aforementioned comparison.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Signed-off-by: Juha Riihimäki 
---
diff --git a/target-arm/neon_helper.c b/target-arm/neon_helper.c
index f32ecd6..0c95035 100644
--- a/target-arm/neon_helper.c
+++ b/target-arm/neon_helper.c
@@ -392,7 +392,7 @@ NEON_VOP(abd_u32, neon_u32, 1)
  #define NEON_FN(dest, src1, src2) do { \
  int8_t tmp; \
  tmp = (int8_t)src2; \
-if (tmp >= sizeof(src1) * 8 || tmp <= -sizeof(src1) * 8) { \
+if (abs(tmp) >= sizeof(src1) * 8) { \
  dest = 0; \
  } else if (tmp < 0) { \
  dest = src1 >> -tmp; \
@@ -420,7 +420,7 @@ uint64_t HELPER(neon_shl_u64)(uint64_t val,  
uint64_t shiftop)
  #define NEON_FN(dest, src1, src2) do { \
  int8_t tmp; \
  tmp = (int8_t)src2; \
-if (tmp >= sizeof(src1) * 8) { \
+if (tmp >= 0 && tmp >= sizeof(src1) * 8) { \
  dest = 0; \
  } else if (tmp <= -sizeof(src1) * 8) { \
  dest = src1 >> (sizeof(src1) * 8 - 1); \
@@ -453,7 +453,7 @@ uint64_t HELPER(neon_shl_s64)(uint64_t valop,  
uint64_t shiftop)
  #define NEON_FN(dest, src1, src2) do { \
  int8_t tmp; \
  tmp = (int8_t)src2; \
-if (tmp >= sizeof(src1) * 8) { \
+if (tmp >= 0 && tmp >= sizeof(src1) * 8) { \
  dest = 0; \
  } else if (tmp < -sizeof(src1) * 8) { \
  dest = src1 >> (sizeof(src1) * 8 - 1); \
@@ -494,7 +494,7 @@ uint64_t HELPER(neon_rshl_s64)(uint64_t valop,  
uint64_t shiftop)
  #define NEON_FN(dest, src1, src2) do { \
  int8_t tmp; \
  tmp = (int8_t)src2; \
-if (tmp >= sizeof(src1) * 8 || tmp < -sizeof(src1) * 8) { \
+if (abs(tmp) >= sizeof(src1) * 8) { \
  dest = 0; \
  } else if (tmp == -sizeof(src1) * 8) { \
  dest = src1 >> (tmp - 1); \
@@ -528,7 +528,7 @@ uint64_t HELPER(neon_rshl_u64)(uint64_t val,  
uint64_t shiftop)
  #define NEON_FN(dest, src1, src2) do { \
  int8_t tmp; \
  tmp = (int8_t)src2; \
-if (tmp >= sizeof(src1) * 8) { \
+if (tmp >= 0 && tmp >= sizeof(src1) * 8) { \
  if (src1) { \
  SET_QC(); \
  dest = ~0; \
@@ -579,7 +579,7 @@ uint64_t HELPER(neon_qshl_u64)(CPUState *env,  
uint64_t val, uint64_t shiftop)
  #define NEON_FN(dest, src1, src2) do { \
  int8_t tmp; \
  tmp = (int8_t)src2; \
-if (tmp >= sizeof(src1) * 8) { \
+if (tmp >= 0 && tmp >= sizeof(src1) * 8) { \
  if (src1) \
  SET_QC(); \
  dest = src1 >> 31; \


neon_helper.c.diff
Description: neon_helper.c.diff


[Qemu-devel] [PATCH 09/12] target-arm: optimize thumb push/pop ops

2009-10-21 Thread Juha.Riihimaki
Thumb push/pop instructions can be slightly optimized by loading the  
register offset constant into a variable outside the register loop and  
using the preloaded variable inside the loop instead of reloading the  
offset value to a temporary variable on each loop iteration. This  
causes less TCG ops to be generated for a Thumb push/pop instruction.

Signed-off-by: Juha Riihimäki 
---
diff --git a/target-arm/translate.c b/target-arm/translate.c
index abb3105..99a9ffd 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -8589,6 +8589,7 @@ static void disas_thumb_insn(CPUState *env,  
DisasContext *s)
  if ((insn & (1 << 11)) == 0) {
  tcg_gen_addi_i32(addr, addr, -offset);
  }
+tmp2 = tcg_const_i32(4);
  for (i = 0; i < 8; i++) {
  if (insn & (1 << i)) {
  if (insn & (1 << 11)) {
@@ -8601,7 +8602,7 @@ static void disas_thumb_insn(CPUState *env,  
DisasContext *s)
  gen_st32(tmp, addr, IS_USER(s));
  }
  /* advance to the next address.  */
-tcg_gen_addi_i32(addr, addr, 4);
+tcg_gen_add_i32(addr, addr, tmp2);
  }
  }
  TCGV_UNUSED(tmp);
@@ -8616,8 +8617,9 @@ static void disas_thumb_insn(CPUState *env,  
DisasContext *s)
  tmp = load_reg(s, 14);
  gen_st32(tmp, addr, IS_USER(s));
  }
-tcg_gen_addi_i32(addr, addr, 4);
+tcg_gen_add_i32(addr, addr, tmp2);
  }
+tcg_temp_free_i32(tmp2);
  if ((insn & (1 << 11)) == 0) {
  tcg_gen_addi_i32(addr, addr, -offset);
  }


translate.c.tpushpop.diff
Description: translate.c.tpushpop.diff


[Qemu-devel] [PATCH 08/12] target-arm: optimize thumb2 load/store multiple ops

2009-10-21 Thread Juha.Riihimaki
Thumb2 load/store multiple instructions can be slightly optimized by  
loading the register offset constant into a variable outside the  
register loop and using the preloaded variable inside the loop instead  
of reloading the offset value to a temporary variable on each loop  
iteration. This causes less TCG ops to be generated for a Thumb2 load/ 
store multiple instruction.

Signed-off-by: Juha Riihimäki 
---
diff --git a/target-arm/translate.c b/target-arm/translate.c
index c92ecc6..abb3105 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -7370,6 +7370,7 @@ static int disas_thumb2_insn(CPUState *env,  
DisasContext *s, uint16_t insn_hw1)
  tcg_gen_addi_i32(addr, addr, -offset);
  }

+tmp2 = tcg_const_i32(4);
  for (i = 0; i < 16; i++) {
  if ((insn & (1 << i)) == 0)
  continue;
@@ -7386,8 +7387,9 @@ static int disas_thumb2_insn(CPUState *env,  
DisasContext *s, uint16_t insn_hw1)
  tmp = load_reg(s, i);
  gen_st32(tmp, addr, IS_USER(s));
  }
-tcg_gen_addi_i32(addr, addr, 4);
+tcg_gen_add_i32(addr, addr, tmp2);
  }
+tcg_temp_free_i32(tmp2);
  if (insn & (1 << 21)) {
  /* Base register writeback.  */
  if (insn & (1 << 24)) {


translate.c.t2ldmstm.diff
Description: translate.c.t2ldmstm.diff


[Qemu-devel] [PATCH 05/12] target-arm: optimize vfp load/store multiple ops

2009-10-21 Thread Juha.Riihimaki
VFP load/store multiple instructions can be slightly optimized by  
loading the register offset constant into a variable outside the  
register loop and using the preloaded variable inside the loop instead  
of reloading the offset value to a temporary variable on each loop  
iteration. This causes less TCG ops to be generated for a VFP load/ 
store multiple instruction.

Signed-off-by: Juha Riihimäki 
---
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 07ee638..e5a2881 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -3222,6 +3222,7 @@ static int disas_vfp_insn(CPUState * env,  
DisasContext *s, uint32_t insn)
  offset = 8;
  else
  offset = 4;
+tmp = tcg_const_i32(offset);
  for (i = 0; i < n; i++) {
  if (insn & ARM_CP_RW_BIT) {
  /* load */
@@ -3232,8 +3233,9 @@ static int disas_vfp_insn(CPUState * env,  
DisasContext *s, uint32_t insn)
  gen_mov_F0_vreg(dp, rd + i);
  gen_vfp_st(s, dp, addr);
  }
-tcg_gen_addi_i32(addr, addr, offset);
+tcg_gen_add_i32(addr, addr, tmp);
  }
+tcg_temp_free_i32(tmp);
  if (insn & (1 << 21)) {
  /* writeback */
  if (insn & (1 << 24))


translate.c.vfpldmstm.diff
Description: translate.c.vfpldmstm.diff


Re: [Qemu-devel] [PATCH 02/12] target-arm: optimize thumb 32bit multiply

2009-10-21 Thread Laurent Desnogues
On Wed, Oct 21, 2009 at 12:17 PM,   wrote:
> Current implementation of thumb mul instruction is implemented as a
> 32x32->64 multiply which then uses only 32 least significant bits of
> the result. Replace that with a simple 32x32->32 multiply.
>
> Signed-off-by: Juha Riihimäki 

Acked-by: Laurent Desnogues 

> ---
> diff --git a/target-arm/translate.c b/target-arm/translate.c
> index bda105e..3ea9d51 100644
> --- a/target-arm/translate.c
> +++ b/target-arm/translate.c
> @@ -310,22 +310,6 @@ static TCGv_i64 gen_muls_i64_i32(TCGv a, TCGv b)
>      return tmp1;
>  }
>
> -/* Unsigned 32x32->64 multiply.  */
> -static void gen_mull(TCGv a, TCGv b)
> -{
> -    TCGv_i64 tmp1 = tcg_temp_new_i64();
> -    TCGv_i64 tmp2 = tcg_temp_new_i64();
> -
> -    tcg_gen_extu_i32_i64(tmp1, a);
> -    tcg_gen_extu_i32_i64(tmp2, b);
> -    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
> -    tcg_temp_free_i64(tmp2);
> -    tcg_gen_trunc_i64_i32(a, tmp1);
> -    tcg_gen_shri_i64(tmp1, tmp1, 32);
> -    tcg_gen_trunc_i64_i32(b, tmp1);
> -    tcg_temp_free_i64(tmp1);
> -}
> -
>  /* Signed 32x32->64 multiply.  */
>  static void gen_imull(TCGv a, TCGv b)
>  {
> @@ -8358,7 +8342,7 @@ static void disas_thumb_insn(CPUState *env,
> DisasContext *s)
>                  gen_logic_CC(tmp);
>              break;
>          case 0xd: /* mul */
> -            gen_mull(tmp, tmp2);
> +            tcg_gen_mul_i32(tmp, tmp, tmp2);
>              if (!s->condexec_mask)
>                  gen_logic_CC(tmp);
>              break;
>




Re: [Qemu-devel] [PATCH 07/12] target-arm: fix neon vsri, vshl and vsli ops

2009-10-21 Thread Laurent Desnogues
On Wed, Oct 21, 2009 at 12:17 PM,   wrote:
> Shift immediate value is incorrectly overwritten by a temporary
> variable in the processing of NEON vsri, vshl and vsli instructions.
>
> Signed-off-by: Juha Riihimäki 
> ---
> diff --git a/target-arm/translate.c b/target-arm/translate.c
> index 59bf7bc..c92ecc6 100644
> --- a/target-arm/translate.c
> +++ b/target-arm/translate.c
> @@ -4094,7 +4094,7 @@ static int disas_neon_data_insn(CPUState * env,
> DisasContext *s, uint32_t insn)
>      int pairwise;
>      int u;
>      int n;
> -    uint32_t imm;
> +    uint32_t imm, imm2;

I would prefer mask to imm2, but that's personal taste :-)

>      TCGv tmp;
>      TCGv tmp2;
>      TCGv tmp3;
> @@ -4624,31 +4624,31 @@ static int disas_neon_data_insn(CPUState *
> env, DisasContext *s, uint32_t insn)
>                              switch (size) {
>                              case 0:
>                                  if (op == 4)
> -                                    imm = 0xff >> -shift;
> +                                    imm2 = 0xff >> -shift;
>                                  else
> -                                    imm = (uint8_t)(0xff << shift);
> -                                imm |= imm << 8;
> -                                imm |= imm << 16;
> +                                    imm2 = (uint8_t)(0xff << shift);
> +                                imm2 |= imm2 << 8;
> +                                imm2 |= imm2 << 16;
>                                  break;
>                              case 1:
>                                  if (op == 4)
> -                                    imm = 0x >> -shift;
> +                                    imm2 = 0x >> -shift;
>                                  else
> -                                    imm = (uint16_t)(0x << shift);
> -                                imm |= imm << 16;
> +                                    imm2 = (uint16_t)(0x << shift);
> +                                imm2 |= imm2 << 16;
>                                  break;
>                              case 2:
>                                  if (op == 4)
> -                                    imm = 0xu >> -shift;
> +                                    imm2 = 0xu >> -shift;
>                                  else
> -                                    imm = 0xu << shift;
> +                                    imm2 = 0xu << shift;
>                                  break;
>                              default:
>                                  abort();
>                              }
>                              tmp2 = neon_load_reg(rd, pass);
> -                            tcg_gen_andi_i32(tmp, tmp, imm);
> -                            tcg_gen_andi_i32(tmp2, tmp2, ~imm);
> +                            tcg_gen_andi_i32(tmp, tmp, imm2);
> +                            tcg_gen_andi_i32(tmp2, tmp2, ~imm2);
>                              tcg_gen_or_i32(tmp, tmp, tmp2);
>                              dead_tmp(tmp2);
>                          }

I mostly agree with this, except there's a mistake already
present in the original code:  for a size of 2 the shift amount
can be 32 (look at VSRI in the ARM Architecture Reference
Manual).  Note in this case, shift will be -32.


Laurent


Re: [Qemu-devel] [PATCH 01/12] target-arm: fix resource leak in gen_set_cpsr macro

2009-10-21 Thread Laurent Desnogues
On Wed, Oct 21, 2009 at 12:17 PM,   wrote:
> Current implementation of the gen_set_cpsr macro creates a new
> temporary tcg variable through the tcg_const_i32 call but never marks
> it dead.
>
> Signed-off-by: Juha Riihimäki 
> ---
> diff --git a/target-arm/translate.c b/target-arm/translate.c
> index bc51bcb..bda105e 100644
> --- a/target-arm/translate.c
> +++ b/target-arm/translate.c
> @@ -184,7 +184,12 @@ static void store_reg(DisasContext *s, int reg,
> TCGv var)
>  #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
>
>
> -#define gen_set_cpsr(var, mask) gen_helper_cpsr_write(var,
> tcg_const_i32(mask))
> +#define gen_set_cpsr(var, mask) \
> +{ \
> +    TCGv tmp_mask = tcg_const_i32(mask); \
> +    gen_helper_cpsr_write(var, tmp_mask); \
> +    tcg_temp_free_i32(tmp_mask); \
> +}
>  /* Set NZCV flags from the high 4 bits of var.  */
>  #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)

Again personal taste:  why not make gen_set_cpsr a static
inline function.

Apart from that, it's OK.


Laurent




Re: [Qemu-devel] [PATCH 10/12] target-arm: replace tcg_gen_rori_i32 by tcg_gen_rotri_i32

2009-10-21 Thread Laurent Desnogues
On Wed, Oct 21, 2009 at 12:18 PM,   wrote:
> Use native rotation if possible instead of a simulated one.
>
> From: Filip Navara 
> Signed-off-by: Juha Riihimäki 

Acked-by: Laurent Desnogues 

> ---
> diff --git a/target-arm/translate.c b/target-arm/translate.c
> index 99a9ffd..1734fae 100644
> --- a/target-arm/translate.c
> +++ b/target-arm/translate.c
> @@ -418,21 +418,6 @@ static inline void tcg_gen_bic_i32(TCGv dest,
> TCGv t0, TCGv t1)
>  /* FIXME:  Implement this natively.  */
>  #define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1)
>
> -/* FIXME:  Implement this natively.  */
> -static void tcg_gen_rori_i32(TCGv t0, TCGv t1, int i)
> -{
> -    TCGv tmp;
> -
> -    if (i == 0)
> -        return;
> -
> -    tmp = new_tmp();
> -    tcg_gen_shri_i32(tmp, t1, i);
> -    tcg_gen_shli_i32(t1, t1, 32 - i);
> -    tcg_gen_or_i32(t0, t1, tmp);
> -    dead_tmp(tmp);
> -}
> -
>  static void shifter_out_im(TCGv var, int shift)
>  {
>      TCGv tmp = new_tmp();
> @@ -484,7 +469,7 @@ static inline void gen_arm_shift_im(TCGv var, int
> shiftop, int shift, int flags)
>          if (shift != 0) {
>              if (flags)
>                  shifter_out_im(var, shift - 1);
> -            tcg_gen_rori_i32(var, var, shift); break;
> +            tcg_gen_rotri_i32(var, var, shift); break;
>          } else {
>              TCGv tmp = load_cpu_field(CF);
>              if (flags)
> @@ -6634,7 +6619,7 @@ static void disas_arm_insn(CPUState * env,
> DisasContext *s)
>                          /* ??? In many cases it's not neccessary to
> do a
>                             rotate, a shift is sufficient.  */
>                          if (shift != 0)
> -                            tcg_gen_rori_i32(tmp, tmp, shift * 8);
> +                            tcg_gen_rotri_i32(tmp, tmp, shift * 8);
>                          op1 = (insn >> 20) & 7;
>                          switch (op1) {
>                          case 0: gen_sxtb16(tmp);  break;
> @@ -7451,7 +7436,7 @@ static int disas_thumb2_insn(CPUState *env,
> DisasContext *s, uint16_t insn_hw1)
>              /* ??? In many cases it's not neccessary to do a
>                 rotate, a shift is sufficient.  */
>              if (shift != 0)
> -                tcg_gen_rori_i32(tmp, tmp, shift * 8);
> +                tcg_gen_rotri_i32(tmp, tmp, shift * 8);
>              op = (insn >> 20) & 7;
>              switch (op) {
>              case 0: gen_sxth(tmp);   break;
>




[Qemu-devel] [PATCH 12/12] [RESEND] target-arm: fix neon shift helper functions

2009-10-21 Thread Juha.Riihimaki
Current code is broken at least on gcc 4.2, the result of a comparison
"-1 >= sizeof(type) * 8" results true and causes wrong code path to be
taken. The fix utilizes abs() function where applicable and otherwise
adds a test to ensure both arguments are positive before making the
aforementioned comparison.

Signed-off-by: Juha Riihimäki 
---
diff --git a/target-arm/neon_helper.c b/target-arm/neon_helper.c
index f32ecd6..0c95035 100644
--- a/target-arm/neon_helper.c
+++ b/target-arm/neon_helper.c
@@ -392,7 +392,7 @@ NEON_VOP(abd_u32, neon_u32, 1)
  #define NEON_FN(dest, src1, src2) do { \
  int8_t tmp; \
  tmp = (int8_t)src2; \
-if (tmp >= sizeof(src1) * 8 || tmp <= -sizeof(src1) * 8) { \
+if (abs(tmp) >= sizeof(src1) * 8) { \
  dest = 0; \
  } else if (tmp < 0) { \
  dest = src1 >> -tmp; \
@@ -420,7 +420,7 @@ uint64_t HELPER(neon_shl_u64)(uint64_t val,  
uint64_t shiftop)
  #define NEON_FN(dest, src1, src2) do { \
  int8_t tmp; \
  tmp = (int8_t)src2; \
-if (tmp >= sizeof(src1) * 8) { \
+if (tmp >= 0 && tmp >= sizeof(src1) * 8) { \
  dest = 0; \
  } else if (tmp <= -sizeof(src1) * 8) { \
  dest = src1 >> (sizeof(src1) * 8 - 1); \
@@ -453,7 +453,7 @@ uint64_t HELPER(neon_shl_s64)(uint64_t valop,  
uint64_t shiftop)
  #define NEON_FN(dest, src1, src2) do { \
  int8_t tmp; \
  tmp = (int8_t)src2; \
-if (tmp >= sizeof(src1) * 8) { \
+if (tmp >= 0 && tmp >= sizeof(src1) * 8) { \
  dest = 0; \
  } else if (tmp < -sizeof(src1) * 8) { \
  dest = src1 >> (sizeof(src1) * 8 - 1); \
@@ -494,7 +494,7 @@ uint64_t HELPER(neon_rshl_s64)(uint64_t valop,  
uint64_t shiftop)
  #define NEON_FN(dest, src1, src2) do { \
  int8_t tmp; \
  tmp = (int8_t)src2; \
-if (tmp >= sizeof(src1) * 8 || tmp < -sizeof(src1) * 8) { \
+if (abs(tmp) >= sizeof(src1) * 8) { \
  dest = 0; \
  } else if (tmp == -sizeof(src1) * 8) { \
  dest = src1 >> (tmp - 1); \
@@ -528,7 +528,7 @@ uint64_t HELPER(neon_rshl_u64)(uint64_t val,  
uint64_t shiftop)
  #define NEON_FN(dest, src1, src2) do { \
  int8_t tmp; \
  tmp = (int8_t)src2; \
-if (tmp >= sizeof(src1) * 8) { \
+if (tmp >= 0 && tmp >= sizeof(src1) * 8) { \
  if (src1) { \
  SET_QC(); \
  dest = ~0; \
@@ -579,7 +579,7 @@ uint64_t HELPER(neon_qshl_u64)(CPUState *env,  
uint64_t val, uint64_t shiftop)
  #define NEON_FN(dest, src1, src2) do { \
  int8_t tmp; \
  tmp = (int8_t)src2; \
-if (tmp >= sizeof(src1) * 8) { \
+if (tmp >= 0 && tmp >= sizeof(src1) * 8) { \
  if (src1) \
  SET_QC(); \
  dest = src1 >> 31; \


neon_helper.c.diff
Description: neon_helper.c.diff


[Qemu-devel] Re: [PATCH 0/9] S390x KVM support v2

2009-10-21 Thread Carsten Otte

Alexander Graf wrote:

This is the resulting code. Please comment on things you like and also on the
ones you don't :-).

Looks fantastic now. Whole series:
Acked-by: Carsten Otte 




[Qemu-devel] [PATCH 03/19] net: make tap_receive() re-use tap_receive_iov() code

2009-10-21 Thread Mark McLoughlin
In future we will want to prepend a virtio_net header if the NIC didn't
supply one but IFF_VNET_HDR is enabled on the interface. This is most
easily achived by using writev() in all cases.

Signed-off-by: Mark McLoughlin 
---
 net.c |   23 +++
 1 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/net.c b/net.c
index 0e3388b..728941a 100644
--- a/net.c
+++ b/net.c
@@ -1291,10 +1291,8 @@ static void tap_writable(void *opaque)
 qemu_flush_queued_packets(s->vc);
 }
 
-static ssize_t tap_receive_iov(VLANClientState *vc, const struct iovec *iov,
-   int iovcnt)
+static ssize_t tap_write_packet(TAPState *s, const struct iovec *iov, int 
iovcnt)
 {
-TAPState *s = vc->opaque;
 ssize_t len;
 
 do {
@@ -1309,16 +1307,25 @@ static ssize_t tap_receive_iov(VLANClientState *vc, 
const struct iovec *iov,
 return len;
 }
 
+static ssize_t tap_receive_iov(VLANClientState *vc, const struct iovec *iov,
+   int iovcnt)
+{
+TAPState *s = vc->opaque;
+
+return tap_write_packet(s, iov, iovcnt);
+}
+
 static ssize_t tap_receive(VLANClientState *vc, const uint8_t *buf, size_t 
size)
 {
 TAPState *s = vc->opaque;
-ssize_t len;
+struct iovec iov[1];
+int iovcnt = 0;
 
-do {
-len = write(s->fd, buf, size);
-} while (len == -1 && (errno == EINTR || errno == EAGAIN));
+iov[iovcnt].iov_base = (char *)buf;
+iov[iovcnt].iov_len  = size;
+iovcnt++;
 
-return len;
+return tap_write_packet(s, iov, iovcnt);
 }
 
 static int tap_can_send(void *opaque)
-- 
1.6.2.5





[Qemu-devel] [PATCH 00/19]

2009-10-21 Thread Mark McLoughlin

Hey,
Over a year ago we added some code to qemu-kvm.git which takes
advantage of the recent tun/tap IFF_VNET_HDR feature in order to allow
virtio-net to send and receive packets with partial checksums and
segmentation offloaded:

  http://article.gmane.org/gmane.comp.emulators.kvm.devel/20440

  "This allows us to pass larger packets and packets with
  partial checkums between the guest and the host, greatly
  increasing the achievable bandwidth."

Unfortunately, that implementation was quite hacky as it
made some assumptions that would break if e.g. you added another
network client to a vlan where the feature had enabled.

Now that we have the -netdev parameter, we can more safely
pair the NIC and backend, allowing us to negatiate features like
this.

What follows is a somewhat cleaned up version of the code
from qemu-kvm.git. Further cleanups are probably possible, but I
think this much is mergeable. Some points of discussion:

  - If you start a guest on a host which supports IFF_VNET_HDR and
migrate to a host which doesn't support it, we can't just tell
the guest to stop using GSO.

We need prevent this by rejecting the migration on the destination
if IFF_VNET_HDR is required but not available. However, in my
testing if a load() function returns an error, the migration is
seen to have completed on the source but failed on the destination.
Clearly that's wrong, but I haven't investigated further yet.

Also, we provide a vnet_hdr= arg so that people can prevent the
feature being used on the source or require that is available on
the destination.

  - I've slightly abused QemuOpts in 05/19. Comments welcome.

  - The whole mess around adding a 'raw' packet flag for the gratuitous
ARP packet is gratuitously messy.

  - I'm always enabling IFF_VNET_HDR if it's available. I don't think
that's a problem, especially compared to what would be required to
only selectively enable it.

Cheers,
Mark.




[Qemu-devel] [PATCH 01/19] net: remove unused includes of if_tun.h and if_tap.h

2009-10-21 Thread Mark McLoughlin
Looks like these are just artifacts of vl.c being split up.

Signed-off-by: Mark McLoughlin 
---
 qemu-char.c |6 --
 savevm.c|6 --
 vl.c|6 --
 3 files changed, 0 insertions(+), 18 deletions(-)

diff --git a/qemu-char.c b/qemu-char.c
index 8084a67..7b39ace 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -51,12 +51,6 @@
 #include 
 #include 
 #include 
-#ifdef __NetBSD__
-#include 
-#endif
-#ifdef __linux__
-#include 
-#endif
 #include 
 #include 
 #include 
diff --git a/savevm.c b/savevm.c
index 27a7686..99aa15a 100644
--- a/savevm.c
+++ b/savevm.c
@@ -42,12 +42,6 @@
 #include 
 #include 
 #include 
-#if defined(__NetBSD__)
-#include 
-#endif
-#ifdef __linux__
-#include 
-#endif
 #include 
 #include 
 #include 
diff --git a/vl.c b/vl.c
index eb2744e..7fa7bdc 100644
--- a/vl.c
+++ b/vl.c
@@ -44,12 +44,6 @@
 #include 
 #include 
 #include 
-#if defined(__NetBSD__)
-#include 
-#endif
-#ifdef __linux__
-#include 
-#endif
 #include 
 #include 
 #include 
-- 
1.6.2.5





[Qemu-devel] [PATCH 08/19] net: add tap_has_vnet_hdr() and tap_using_vnet_hdr() APIs

2009-10-21 Thread Mark McLoughlin
These lamely named functions allow virtio-net to query whether
IFF_VNET_HDR is enabled on a tap interface and inform the tap code
that virtio-net will supply packets with a vnet header.

Signed-off-by: Mark McLoughlin 
---
 net.c |   39 +++
 net.h |3 +++
 2 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/net.c b/net.c
index 638ba36..56d979b 100644
--- a/net.c
+++ b/net.c
@@ -1246,7 +1246,15 @@ void do_info_usernet(Monitor *mon)
 
 #endif /* CONFIG_SLIRP */
 
-#if !defined(_WIN32)
+#if defined(_WIN32)
+int tap_has_vnet_hdr(VLANClientState *vc)
+{
+return 0;
+}
+void tap_using_vnet_hdr(VLANClientState *vc, int using_vnet_hdr)
+{
+}
+#else /* !defined(_WIN32) */
 
 /* Maximum GSO packet size (64k) plus plenty of room for
  * the ethernet and virtio_net headers
@@ -1262,6 +1270,7 @@ typedef struct TAPState {
 unsigned int read_poll : 1;
 unsigned int write_poll : 1;
 unsigned int has_vnet_hdr : 1;
+unsigned int using_vnet_hdr : 1;
 } TAPState;
 
 static int launch_script(const char *setup_script, const char *ifname, int fd);
@@ -1324,7 +1333,7 @@ static ssize_t tap_receive_iov(VLANClientState *vc, const 
struct iovec *iov,
 struct iovec iov_copy[iovcnt + 1];
 struct virtio_net_hdr hdr = { 0, };
 
-if (s->has_vnet_hdr) {
+if (s->has_vnet_hdr && !s->using_vnet_hdr) {
 iov_copy[0].iov_base = &hdr;
 iov_copy[0].iov_len =  sizeof(hdr);
 memcpy(&iov_copy[1], iov, iovcnt * sizeof(*iov));
@@ -1342,7 +1351,7 @@ static ssize_t tap_receive(VLANClientState *vc, const 
uint8_t *buf, size_t size)
 int iovcnt = 0;
 struct virtio_net_hdr hdr = { 0, };
 
-if (s->has_vnet_hdr) {
+if (s->has_vnet_hdr && !s->using_vnet_hdr) {
 iov[iovcnt].iov_base = &hdr;
 iov[iovcnt].iov_len  = sizeof(hdr);
 iovcnt++;
@@ -1399,7 +1408,7 @@ static void tap_send(void *opaque)
 break;
 }
 
-if (s->has_vnet_hdr) {
+if (s->has_vnet_hdr && !s->using_vnet_hdr) {
 buf  += sizeof(struct virtio_net_hdr);
 size -= sizeof(struct virtio_net_hdr);
 }
@@ -1434,6 +1443,27 @@ static int tap_set_sndbuf(TAPState *s, QemuOpts *opts)
 return 0;
 }
 
+int tap_has_vnet_hdr(VLANClientState *vc)
+{
+TAPState *s = vc->opaque;
+
+assert(vc->type == NET_CLIENT_TYPE_TAP);
+
+return s->has_vnet_hdr;
+}
+
+void tap_using_vnet_hdr(VLANClientState *vc, int using_vnet_hdr)
+{
+TAPState *s = vc->opaque;
+
+using_vnet_hdr = using_vnet_hdr != 0;
+
+assert(vc->type == NET_CLIENT_TYPE_TAP);
+assert(s->has_vnet_hdr == using_vnet_hdr);
+
+s->using_vnet_hdr = using_vnet_hdr;
+}
+
 static int tap_probe_vnet_hdr(int fd)
 {
 struct ifreq ifr;
@@ -1474,6 +1504,7 @@ static TAPState *net_tap_fd_init(VLANState *vlan,
 s = qemu_mallocz(sizeof(TAPState));
 s->fd = fd;
 s->has_vnet_hdr = vnet_hdr != 0;
+s->using_vnet_hdr = 0;
 s->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_TAP,
  vlan, NULL, model, name, NULL,
  tap_receive, tap_receive_iov,
diff --git a/net.h b/net.h
index aefeef4..5f28860 100644
--- a/net.h
+++ b/net.h
@@ -165,4 +165,7 @@ VLANClientState *qdev_get_vlan_client(DeviceState *dev,
   NetCleanup *cleanup,
   void *opaque);
 
+int tap_has_vnet_hdr(VLANClientState *vc);
+void tap_using_vnet_hdr(VLANClientState *vc, int using_vnet_hdr);
+
 #endif
-- 
1.6.2.5





[Qemu-devel] [PATCH 04/19] net: enable IFF_VNET_HDR on tap fds if available

2009-10-21 Thread Mark McLoughlin
For now, we just add an empty header before writing and strip the header
after reading.

We really only want IFF_VNET_HDR when virtio_net is using it, but it
would significantly complicate matters to try and do that. There should
be little or no performance impact with always adding headers.

Signed-off-by: Mark McLoughlin 
---
 net.c   |   83 +-
 tap-linux.h |   14 ++
 2 files changed, 84 insertions(+), 13 deletions(-)

diff --git a/net.c b/net.c
index 728941a..356a280 100644
--- a/net.c
+++ b/net.c
@@ -1245,14 +1245,20 @@ void do_info_usernet(Monitor *mon)
 
 #if !defined(_WIN32)
 
+/* Maximum GSO packet size (64k) plus plenty of room for
+ * the ethernet and virtio_net headers
+ */
+#define TAP_BUFSIZE (4096 + 65536)
+
 typedef struct TAPState {
 VLANClientState *vc;
 int fd;
 char down_script[1024];
 char down_script_arg[128];
-uint8_t buf[4096];
+uint8_t buf[TAP_BUFSIZE];
 unsigned int read_poll : 1;
 unsigned int write_poll : 1;
+unsigned int has_vnet_hdr : 1;
 } TAPState;
 
 static int launch_script(const char *setup_script, const char *ifname, int fd);
@@ -1311,15 +1317,33 @@ static ssize_t tap_receive_iov(VLANClientState *vc, 
const struct iovec *iov,
int iovcnt)
 {
 TAPState *s = vc->opaque;
+const struct iovec *iovp = iov;
+struct iovec iov_copy[iovcnt + 1];
+struct virtio_net_hdr hdr = { 0, };
 
-return tap_write_packet(s, iov, iovcnt);
+if (s->has_vnet_hdr) {
+iov_copy[0].iov_base = &hdr;
+iov_copy[0].iov_len =  sizeof(hdr);
+memcpy(&iov_copy[1], iov, iovcnt * sizeof(*iov));
+iovp = iov_copy;
+iovcnt++;
+}
+
+return tap_write_packet(s, iovp, iovcnt);
 }
 
 static ssize_t tap_receive(VLANClientState *vc, const uint8_t *buf, size_t 
size)
 {
 TAPState *s = vc->opaque;
-struct iovec iov[1];
+struct iovec iov[2];
 int iovcnt = 0;
+struct virtio_net_hdr hdr = { 0, };
+
+if (s->has_vnet_hdr) {
+iov[iovcnt].iov_base = &hdr;
+iov[iovcnt].iov_len  = sizeof(hdr);
+iovcnt++;
+}
 
 iov[iovcnt].iov_base = (char *)buf;
 iov[iovcnt].iov_len  = size;
@@ -1365,12 +1389,19 @@ static void tap_send(void *opaque)
 int size;
 
 do {
+uint8_t *buf = s->buf;
+
 size = tap_read_packet(s->fd, s->buf, sizeof(s->buf));
 if (size <= 0) {
 break;
 }
 
-size = qemu_send_packet_async(s->vc, s->buf, size, tap_send_completed);
+if (s->has_vnet_hdr) {
+buf  += sizeof(struct virtio_net_hdr);
+size -= sizeof(struct virtio_net_hdr);
+}
+
+size = qemu_send_packet_async(s->vc, buf, size, tap_send_completed);
 if (size == 0) {
 tap_read_poll(s, 0);
 }
@@ -1400,6 +1431,18 @@ static int tap_set_sndbuf(TAPState *s, QemuOpts *opts)
 return 0;
 }
 
+static int tap_probe_vnet_hdr(int fd)
+{
+struct ifreq ifr;
+
+if (ioctl(fd, TUNGETIFF, &ifr) != 0) {
+qemu_error("TUNGETIFF ioctl() failed: %s\n", strerror(errno));
+return 0;
+}
+
+return ifr.ifr_flags & IFF_VNET_HDR;
+}
+
 static void tap_cleanup(VLANClientState *vc)
 {
 TAPState *s = vc->opaque;
@@ -1420,12 +1463,14 @@ static void tap_cleanup(VLANClientState *vc)
 static TAPState *net_tap_fd_init(VLANState *vlan,
  const char *model,
  const char *name,
- int fd)
+ int fd,
+ int vnet_hdr)
 {
 TAPState *s;
 
 s = qemu_mallocz(sizeof(TAPState));
 s->fd = fd;
+s->has_vnet_hdr = vnet_hdr != 0;
 s->vc = qemu_new_vlan_client(vlan, NULL, model, name, NULL,
  tap_receive, tap_receive_iov,
  tap_cleanup, s);
@@ -1435,7 +1480,7 @@ static TAPState *net_tap_fd_init(VLANState *vlan,
 }
 
 #if defined (CONFIG_BSD) || defined (__FreeBSD_kernel__)
-static int tap_open(char *ifname, int ifname_size)
+static int tap_open(char *ifname, int ifname_size, int *vnet_hdr)
 {
 int fd;
 char *dev;
@@ -1577,7 +1622,7 @@ static int tap_alloc(char *dev, size_t dev_size)
 return tap_fd;
 }
 
-static int tap_open(char *ifname, int ifname_size)
+static int tap_open(char *ifname, int ifname_size, int *vnet_hdr)
 {
 char  dev[10]="";
 int fd;
@@ -1590,13 +1635,13 @@ static int tap_open(char *ifname, int ifname_size)
 return fd;
 }
 #elif defined (_AIX)
-static int tap_open(char *ifname, int ifname_size)
+static int tap_open(char *ifname, int ifname_size, int *vnet_hdr)
 {
 fprintf (stderr, "no tap on AIX\n");
 return -1;
 }
 #else
-static int tap_open(char *ifname, int ifname_size)
+static int tap_open(char *ifname, int ifname_size, int *vnet_hdr)
 {
 struct ifreq ifr;
 int fd, ret;
@@ -1608,6 +1653,17 @@ sta

[Qemu-devel] [PATCH 02/19] net: import linux tap ioctl definitions

2009-10-21 Thread Mark McLoughlin
Making features dependent on the availability of newer versions if_tun.h
is going to get seriously clumsy, so let's just import the definitions
we need. It's only a small handful.

If and when we're comfortable depending on 2.6.30 headers, we can remove
this again.

Signed-off-by: Mark McLoughlin 
---
 net.c   |   11 +--
 qemu-options.hx |8 +---
 tap-linux.h |   29 +
 3 files changed, 31 insertions(+), 17 deletions(-)
 create mode 100644 tap-linux.h

diff --git a/net.c b/net.c
index 4708080..0e3388b 100644
--- a/net.c
+++ b/net.c
@@ -46,7 +46,7 @@
 #include 
 #endif
 #ifdef __linux__
-#include 
+#include "tap-linux.h"
 #endif
 #include 
 #include 
@@ -1370,7 +1370,6 @@ static void tap_send(void *opaque)
 } while (size > 0);
 }
 
-#ifdef TUNSETSNDBUF
 /* sndbuf should be set to a value lower than the tx queue
  * capacity of any destination network interface.
  * Ethernet NICs generally have txqueuelen=1000, so 1Mb is
@@ -1393,12 +1392,6 @@ static int tap_set_sndbuf(TAPState *s, QemuOpts *opts)
 }
 return 0;
 }
-#else
-static int tap_set_sndbuf(TAPState *s, QemuOpts *opts)
-{
-return 0;
-}
-#endif /* TUNSETSNDBUF */
 
 static void tap_cleanup(VLANClientState *vc)
 {
@@ -2972,12 +2965,10 @@ static struct {
 .name = "downscript",
 .type = QEMU_OPT_STRING,
 .help = "script to shut down the interface",
-#ifdef TUNSETSNDBUF
 }, {
 .name = "sndbuf",
 .type = QEMU_OPT_SIZE,
 .help = "send buffer limit"
-#endif
 },
 { /* end of list */ }
 },
diff --git a/qemu-options.hx b/qemu-options.hx
index 20aa242..c745e0c 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -810,21 +810,15 @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
 "-net tap[,vlan=n][,name=str],ifname=name\n"
 "connect the host TAP network interface to VLAN 'n'\n"
 #else
-"-net 
tap[,vlan=n][,name=str][,fd=h][,ifname=name][,script=file][,downscript=dfile]"
-#ifdef TUNSETSNDBUF
-"[,sndbuf=nbytes]"
-#endif
-"\n"
+"-net 
tap[,vlan=n][,name=str][,fd=h][,ifname=name][,script=file][,downscript=dfile][,sndbuf=nbytes]\n"
 "connect the host TAP network interface to VLAN 'n' and 
use the\n"
 "network scripts 'file' (default=%s)\n"
 "and 'dfile' (default=%s);\n"
 "use '[down]script=no' to disable script execution;\n"
 "use 'fd=h' to connect to an already opened TAP 
interface\n"
-#ifdef TUNSETSNDBUF
 "use 'sndbuf=nbytes' to limit the size of the send buffer; 
the\n"
 "default of 'sndbuf=1048576' can be disabled using 
'sndbuf=0'\n"
 #endif
-#endif
 "-net 
socket[,vlan=n][,name=str][,fd=h][,listen=[host]:port][,connect=host:port]\n"
 "connect the vlan 'n' to another VLAN using a socket 
connection\n"
 "-net socket[,vlan=n][,name=str][,fd=h][,mcast=maddr:port]\n"
diff --git a/tap-linux.h b/tap-linux.h
new file mode 100644
index 000..cd07ea8
--- /dev/null
+++ b/tap-linux.h
@@ -0,0 +1,29 @@
+/*
+ *  Universal TUN/TAP device driver.
+ *  Copyright (C) 1999-2000 Maxim Krasnyansky 
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ */
+
+#ifndef QEMU_TAP_H
+#define QEMU_TAP_H
+
+#include 
+
+/* Ioctl defines */
+#define TUNSETIFF _IOW('T', 202, int)
+#define TUNSETSNDBUF   _IOW('T', 212, int)
+
+/* TUNSETIFF ifr flags */
+#define IFF_TAP0x0002
+#define IFF_NO_PI  0x1000
+
+#endif /* QEMU_TAP_H */
-- 
1.6.2.5





[Qemu-devel] [PATCH 06/19] net: add a vnet_hdr=on|off parameter

2009-10-21 Thread Mark McLoughlin
This allows people to disable the IFF_VNET_HDR flag, e.g. for debugging
purposes or if they know they may migrate the guest to a machine without
IFF_VNET_HDR support.

It also allows making the lack of IFF_VNET_HDR support an error
condition, e.g. in the case where a guest is being migrated from a host
which does support it.

Signed-off-by: Mark McLoughlin 
---
 net.c   |   42 --
 qemu-options.hx |4 +++-
 2 files changed, 35 insertions(+), 11 deletions(-)

diff --git a/net.c b/net.c
index fccabdb..d62ab7b 100644
--- a/net.c
+++ b/net.c
@@ -1479,7 +1479,8 @@ static TAPState *net_tap_fd_init(VLANState *vlan,
 }
 
 #if defined (CONFIG_BSD) || defined (__FreeBSD_kernel__)
-static int tap_open(char *ifname, int ifname_size, int *vnet_hdr)
+static int tap_open(char *ifname, int ifname_size,
+int *vnet_hdr, int vnet_hdr_required)
 {
 int fd;
 char *dev;
@@ -1621,7 +1622,8 @@ static int tap_alloc(char *dev, size_t dev_size)
 return tap_fd;
 }
 
-static int tap_open(char *ifname, int ifname_size, int *vnet_hdr)
+static int tap_open(char *ifname, int ifname_size,
+int *vnet_hdr, int vnet_hdr_required)
 {
 char  dev[10]="";
 int fd;
@@ -1634,13 +1636,15 @@ static int tap_open(char *ifname, int ifname_size, int 
*vnet_hdr)
 return fd;
 }
 #elif defined (_AIX)
-static int tap_open(char *ifname, int ifname_size, int *vnet_hdr)
+static int tap_open(char *ifname, int ifname_size,
+int *vnet_hdr, int vnet_hdr_required)
 {
 fprintf (stderr, "no tap on AIX\n");
 return -1;
 }
 #else
-static int tap_open(char *ifname, int ifname_size, int *vnet_hdr)
+static int tap_open(char *ifname, int ifname_size,
+int *vnet_hdr, int vnet_hdr_required)
 {
 struct ifreq ifr;
 int fd, ret;
@@ -1653,7 +1657,7 @@ static int tap_open(char *ifname, int ifname_size, int 
*vnet_hdr)
 memset(&ifr, 0, sizeof(ifr));
 ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
 
-{
+if (*vnet_hdr) {
 unsigned int features;
 
 if (ioctl(fd, TUNGETFEATURES, &features) == 0 &&
@@ -1661,6 +1665,13 @@ static int tap_open(char *ifname, int ifname_size, int 
*vnet_hdr)
 *vnet_hdr = 1;
 ifr.ifr_flags |= IFF_VNET_HDR;
 }
+
+if (vnet_hdr_required && !*vnet_hdr) {
+qemu_error("vnet_hdr=1 requested, but no kernel "
+   "support for IFF_VNET_HDR available");
+close(fd);
+return -1;
+}
 }
 
 if (ifname[0] != '\0')
@@ -1725,7 +1736,7 @@ static int launch_script(const char *setup_script, const 
char *ifname, int fd)
 
 static int net_tap_init(QemuOpts *opts, int *vnet_hdr)
 {
-int fd;
+int fd, vnet_hdr_required;
 char ifname[128] = {0,};
 const char *setup_script;
 
@@ -1733,8 +1744,14 @@ static int net_tap_init(QemuOpts *opts, int *vnet_hdr)
 pstrcpy(ifname, sizeof(ifname), qemu_opt_get(opts, "ifname"));
 }
 
-*vnet_hdr = 0;
-TFR(fd = tap_open(ifname, sizeof(ifname), vnet_hdr));
+*vnet_hdr = qemu_opt_get_bool(opts, "vnet_hdr", 1);
+if (qemu_opt_get(opts, "vnet_hdr")) {
+vnet_hdr_required = *vnet_hdr;
+} else {
+vnet_hdr_required = 0;
+}
+
+TFR(fd = tap_open(ifname, sizeof(ifname), vnet_hdr, vnet_hdr_required));
 if (fd < 0) {
 return -1;
 }
@@ -2683,8 +2700,9 @@ static int net_init_tap(QemuOpts *opts,
 if (qemu_opt_get(opts, "fd")) {
 if (qemu_opt_get(opts, "ifname") ||
 qemu_opt_get(opts, "script") ||
-qemu_opt_get(opts, "downscript")) {
-qemu_error("ifname=, script= and downscript= is invalid with 
fd=\n");
+qemu_opt_get(opts, "downscript") ||
+qemu_opt_get(opts, "vnet_hdr")) {
+qemu_error("ifname=, script=, downscript= and vnet_hdr= is invalid 
with fd=\n");
 return -1;
 }
 
@@ -3040,6 +3058,10 @@ static struct {
 .name = "sndbuf",
 .type = QEMU_OPT_SIZE,
 .help = "send buffer limit"
+}, {
+.name = "vnet_hdr",
+.type = QEMU_OPT_BOOL,
+.help = "enable the IFF_VNET_HDR flag on the tap interface"
 },
 { /* end of list */ }
 },
diff --git a/qemu-options.hx b/qemu-options.hx
index c745e0c..d78b738 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -810,7 +810,7 @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
 "-net tap[,vlan=n][,name=str],ifname=name\n"
 "connect the host TAP network interface to VLAN 'n'\n"
 #else
-"-net 
tap[,vlan=n][,name=str][,fd=h][,ifname=name][,script=file][,downscript=dfile][,sndbuf=nbytes]\n"
+"-net 
tap[,vlan=n][,name=str][,fd=h][,ifname=name][,script=file][,downscript=dfile][,sndbuf=nbytes][,vnet_hdr=on|off]\n"
 "connect the host TAP network interface to VLAN 'n' and 
use the\n"
  

[Qemu-devel] [PATCH 07/19] net: add a client type code

2009-10-21 Thread Mark McLoughlin
This is so as to allow APIs which operate on specific client types
without having to add a function table entry which is only implemented
by a single client type.

Signed-off-by: Mark McLoughlin 
---
 hw/dp8393x.c |3 ++-
 hw/etraxfs_eth.c |3 ++-
 hw/mcf_fec.c |3 ++-
 hw/mipsnet.c |3 ++-
 hw/qdev.c|3 ++-
 hw/usb-net.c |3 ++-
 hw/xen_nic.c |3 ++-
 net.c|   22 +++---
 net.h|   14 +-
 tap-win32.c  |3 ++-
 10 files changed, 44 insertions(+), 16 deletions(-)

diff --git a/hw/dp8393x.c b/hw/dp8393x.c
index e4caab0..5622170 100644
--- a/hw/dp8393x.c
+++ b/hw/dp8393x.c
@@ -889,7 +889,8 @@ void dp83932_init(NICInfo *nd, target_phys_addr_t base, int 
it_shift,
 s->watchdog = qemu_new_timer(vm_clock, dp8393x_watchdog, s);
 s->regs[SONIC_SR] = 0x0004; /* only revision recognized by Linux */
 
-s->vc = nd->vc = qemu_new_vlan_client(nd->vlan, nd->netdev,
+s->vc = nd->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
+  nd->vlan, nd->netdev,
   nd->model, nd->name,
   nic_can_receive, nic_receive, NULL,
   nic_cleanup, s);
diff --git a/hw/etraxfs_eth.c b/hw/etraxfs_eth.c
index a411dab..2a583a3 100644
--- a/hw/etraxfs_eth.c
+++ b/hw/etraxfs_eth.c
@@ -590,7 +590,8 @@ void *etraxfs_eth_init(NICInfo *nd, target_phys_addr_t 
base, int phyaddr)
eth->ethregs = cpu_register_io_memory(eth_read, eth_write, eth);
cpu_register_physical_memory (base, 0x5c, eth->ethregs);
 
-   eth->vc = nd->vc = qemu_new_vlan_client(nd->vlan, nd->netdev,
+   eth->vc = nd->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
+nd->vlan, nd->netdev,
 nd->model, nd->name,
 eth_can_receive, eth_receive,
 NULL, eth_cleanup, eth);
diff --git a/hw/mcf_fec.c b/hw/mcf_fec.c
index f9f437a..0567bcd 100644
--- a/hw/mcf_fec.c
+++ b/hw/mcf_fec.c
@@ -462,7 +462,8 @@ void mcf_fec_init(NICInfo *nd, target_phys_addr_t base, 
qemu_irq *irq)
mcf_fec_writefn, s);
 cpu_register_physical_memory(base, 0x400, s->mmio_index);
 
-s->vc = nd->vc = qemu_new_vlan_client(nd->vlan, nd->netdev,
+s->vc = nd->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
+  nd->vlan, nd->netdev,
   nd->model, nd->name,
   mcf_fec_can_receive, mcf_fec_receive,
   NULL, mcf_fec_cleanup, s);
diff --git a/hw/mipsnet.c b/hw/mipsnet.c
index ea8b570..d32099f 100644
--- a/hw/mipsnet.c
+++ b/hw/mipsnet.c
@@ -263,7 +263,8 @@ void mipsnet_init (int base, qemu_irq irq, NICInfo *nd)
 s->io_base = base;
 s->irq = irq;
 if (nd) {
-s->vc = nd->vc = qemu_new_vlan_client(nd->vlan, nd->netdev,
+s->vc = nd->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
+  nd->vlan, nd->netdev,
   nd->model, nd->name,
   mipsnet_can_receive, 
mipsnet_receive,
   NULL, mipsnet_cleanup, s);
diff --git a/hw/qdev.c b/hw/qdev.c
index 20f931c..bc3a0d5 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -370,7 +370,8 @@ VLANClientState *qdev_get_vlan_client(DeviceState *dev,
 {
 NICInfo *nd = dev->nd;
 assert(nd);
-nd->vc = qemu_new_vlan_client(nd->vlan, nd->netdev,
+nd->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
+  nd->vlan, nd->netdev,
   nd->model, nd->name,
   can_receive, receive, receive_iov,
   cleanup, opaque);
diff --git a/hw/usb-net.c b/hw/usb-net.c
index 5c753e0..2393812 100644
--- a/hw/usb-net.c
+++ b/hw/usb-net.c
@@ -1460,7 +1460,8 @@ USBDevice *usb_net_init(NICInfo *nd)
 
 memcpy(s->mac, nd->macaddr, 6);
 
-s->vc = nd->vc = qemu_new_vlan_client(nd->vlan, nd->netdev,
+s->vc = nd->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
+  nd->vlan, nd->netdev,
   nd->model, nd->name,
   usbnet_can_receive,
   usbnet_receive,
diff --git a/hw/xen_nic.c b/hw/xen_nic.c
index b09b48a..2a179f0 100644
--- a/hw/xen_nic.c
+++ b/hw/xen_nic.c
@@ -301,7 +301,8 @@ static int net_init(struct XenDevice *xendev)
return -1;
 
 vlan = qemu_find_vlan(netdev->xendev.dev, 1);
-netdev->vs = qemu_new_vlan_client(vlan, NULL, "xen", NULL,
+ne

[Qemu-devel] [PATCH 13/19] net: implement tap support for receive_raw()

2009-10-21 Thread Mark McLoughlin
tap_receive_raw() always prepends a vnet header if IFF_VNET_HDR is
enabled.

tap_receive() only prepends when the a header is required but the NIC
doesn't supply one.

Signed-off-by: Mark McLoughlin 
---
 net.c |   23 +++
 1 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/net.c b/net.c
index 56d9de7..b44495d 100644
--- a/net.c
+++ b/net.c
@@ -1377,14 +1377,14 @@ static ssize_t tap_receive_iov(VLANClientState *vc, 
const struct iovec *iov,
 return tap_write_packet(s, iovp, iovcnt);
 }
 
-static ssize_t tap_receive(VLANClientState *vc, const uint8_t *buf, size_t 
size)
+static ssize_t tap_receive_raw(VLANClientState *vc, const uint8_t *buf, size_t 
size)
 {
 TAPState *s = vc->opaque;
 struct iovec iov[2];
 int iovcnt = 0;
 struct virtio_net_hdr hdr = { 0, };
 
-if (s->has_vnet_hdr && !s->using_vnet_hdr) {
+if (s->has_vnet_hdr) {
 iov[iovcnt].iov_base = &hdr;
 iov[iovcnt].iov_len  = sizeof(hdr);
 iovcnt++;
@@ -1397,6 +1397,21 @@ static ssize_t tap_receive(VLANClientState *vc, const 
uint8_t *buf, size_t size)
 return tap_write_packet(s, iov, iovcnt);
 }
 
+static ssize_t tap_receive(VLANClientState *vc, const uint8_t *buf, size_t 
size)
+{
+TAPState *s = vc->opaque;
+struct iovec iov[1];
+
+if (s->has_vnet_hdr && !s->using_vnet_hdr) {
+return tap_receive_raw(vc, buf, size);
+}
+
+iov[0].iov_base = (char *)buf;
+iov[0].iov_len  = size;
+
+return tap_write_packet(s, iov, 1);
+}
+
 static int tap_can_send(void *opaque)
 {
 TAPState *s = opaque;
@@ -1540,8 +1555,8 @@ static TAPState *net_tap_fd_init(VLANState *vlan,
 s->using_vnet_hdr = 0;
 s->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_TAP,
  vlan, NULL, model, name, NULL,
- tap_receive, NULL, tap_receive_iov,
- tap_cleanup, s);
+ tap_receive, tap_receive_raw,
+ tap_receive_iov, tap_cleanup, s);
 tap_read_poll(s, 1);
 return s;
 }
-- 
1.6.2.5





[Qemu-devel] [PATCH 05/19] net: refactor tap initialization

2009-10-21 Thread Mark McLoughlin
Re-factor things so that there is only one call site for
net_tap_fd_init().

Two concerns about the QemuOpts usage here - firstly, we set the script
arguments to their default value and, secondly, we set the ifname value
to the name allocated by the kernel if none is supplied. Are we okay
with such things ending up in writeconfig output?

Signed-off-by: Mark McLoughlin 
---
 net.c |   97 +++--
 1 files changed, 52 insertions(+), 45 deletions(-)

diff --git a/net.c b/net.c
index 356a280..fccabdb 100644
--- a/net.c
+++ b/net.c
@@ -1475,7 +1475,6 @@ static TAPState *net_tap_fd_init(VLANState *vlan,
  tap_receive, tap_receive_iov,
  tap_cleanup, s);
 tap_read_poll(s, 1);
-snprintf(s->vc->info_str, sizeof(s->vc->info_str), "fd=%d", fd);
 return s;
 }
 
@@ -1724,38 +1723,34 @@ static int launch_script(const char *setup_script, 
const char *ifname, int fd)
 return -1;
 }
 
-static TAPState *net_tap_init(VLANState *vlan, const char *model,
-  const char *name, const char *ifname1,
-  const char *setup_script, const char 
*down_script)
+static int net_tap_init(QemuOpts *opts, int *vnet_hdr)
 {
-TAPState *s;
-int fd, vnet_hdr;
-char ifname[128];
+int fd;
+char ifname[128] = {0,};
+const char *setup_script;
 
-if (ifname1 != NULL)
-pstrcpy(ifname, sizeof(ifname), ifname1);
-else
-ifname[0] = '\0';
-vnet_hdr = 0;
-TFR(fd = tap_open(ifname, sizeof(ifname), &vnet_hdr));
-if (fd < 0)
-return NULL;
+if (qemu_opt_get(opts, "ifname")) {
+pstrcpy(ifname, sizeof(ifname), qemu_opt_get(opts, "ifname"));
+}
 
-if (!setup_script || !strcmp(setup_script, "no"))
-setup_script = "";
-if (setup_script[0] != '\0' &&
-launch_script(setup_script, ifname, fd)) {
-return NULL;
+*vnet_hdr = 0;
+TFR(fd = tap_open(ifname, sizeof(ifname), vnet_hdr));
+if (fd < 0) {
+return -1;
 }
-s = net_tap_fd_init(vlan, model, name, fd, vnet_hdr);
-snprintf(s->vc->info_str, sizeof(s->vc->info_str),
- "ifname=%s,script=%s,downscript=%s",
- ifname, setup_script, down_script);
-if (down_script && strcmp(down_script, "no")) {
-snprintf(s->down_script, sizeof(s->down_script), "%s", down_script);
-snprintf(s->down_script_arg, sizeof(s->down_script_arg), "%s", ifname);
+
+setup_script = qemu_opt_get(opts, "script");
+if (setup_script &&
+setup_script[0] != '\0' &&
+strcmp(setup_script, "no") != 0 &&
+launch_script(setup_script, ifname, fd)) {
+close(fd);
+return -1;
 }
-return s;
+
+qemu_opt_set(opts, "ifname", ifname);
+
+return fd;
 }
 
 #endif /* !_WIN32 */
@@ -2683,10 +2678,9 @@ static int net_init_tap(QemuOpts *opts,
 VLANState *vlan)
 {
 TAPState *s;
+int fd, vnet_hdr;
 
 if (qemu_opt_get(opts, "fd")) {
-int fd;
-
 if (qemu_opt_get(opts, "ifname") ||
 qemu_opt_get(opts, "script") ||
 qemu_opt_get(opts, "downscript")) {
@@ -2701,28 +2695,22 @@ static int net_init_tap(QemuOpts *opts,
 
 fcntl(fd, F_SETFL, O_NONBLOCK);
 
-s = net_tap_fd_init(vlan, "tap", name, fd, tap_probe_vnet_hdr(fd));
-if (!s) {
-close(fd);
-}
+vnet_hdr = tap_probe_vnet_hdr(fd);
 } else {
-const char *ifname, *script, *downscript;
-
-ifname = qemu_opt_get(opts, "ifname");
-script = qemu_opt_get(opts, "script");
-downscript = qemu_opt_get(opts, "downscript");
-
-if (!script) {
-script = DEFAULT_NETWORK_SCRIPT;
+if (!qemu_opt_get(opts, "script")) {
+qemu_opt_set(opts, "script", DEFAULT_NETWORK_SCRIPT);
 }
-if (!downscript) {
-downscript = DEFAULT_NETWORK_DOWN_SCRIPT;
+
+if (!qemu_opt_get(opts, "downscript")) {
+qemu_opt_set(opts, "downscript", DEFAULT_NETWORK_DOWN_SCRIPT);
 }
 
-s = net_tap_init(vlan, "tap", name, ifname, script, downscript);
+fd = net_tap_init(opts, &vnet_hdr);
 }
 
+s = net_tap_fd_init(vlan, "tap", name, fd, vnet_hdr);
 if (!s) {
+close(fd);
 return -1;
 }
 
@@ -2730,6 +2718,25 @@ static int net_init_tap(QemuOpts *opts,
 return -1;
 }
 
+if (qemu_opt_get(opts, "fd")) {
+snprintf(s->vc->info_str, sizeof(s->vc->info_str), "fd=%d", fd);
+} else {
+const char *ifname, *script, *downscript;
+
+ifname = qemu_opt_get(opts, "ifname");
+script = qemu_opt_get(opts, "script");
+downscript = qemu_opt_get(opts, "downscript");
+
+snprintf(s->vc->info_str, sizeof(s->vc->info_str),
+ "ifname=%s,script=%s,downscript=%s",
+ ifname,

[Qemu-devel] [PATCH 15/19] net: add tap_set_offload()

2009-10-21 Thread Mark McLoughlin
This API allows virtio-net to enable various offload features on a
tap interface - e.g. to tell the host kernel it can pass up partial
checksums to userspace.

Signed-off-by: Mark McLoughlin 
---
 net.c   |   24 
 net.h   |1 +
 tap-linux.h |7 +++
 3 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/net.c b/net.c
index b44495d..746a3d6 100644
--- a/net.c
+++ b/net.c
@@ -1287,6 +1287,9 @@ int tap_has_vnet_hdr(VLANClientState *vc)
 void tap_using_vnet_hdr(VLANClientState *vc, int using_vnet_hdr)
 {
 }
+void tap_set_offload(VLANClientState *vc, int csum, int tso4, int tso6, int 
ecn)
+{
+}
 #else /* !defined(_WIN32) */
 
 /* Maximum GSO packet size (64k) plus plenty of room for
@@ -1524,6 +1527,27 @@ static int tap_probe_vnet_hdr(int fd)
 return ifr.ifr_flags & IFF_VNET_HDR;
 }
 
+void tap_set_offload(VLANClientState *vc, int csum, int tso4, int tso6, int 
ecn)
+{
+TAPState *s = vc->opaque;
+unsigned int offload = 0;
+
+if (csum) {
+offload |= TUN_F_CSUM;
+if (tso4)
+offload |= TUN_F_TSO4;
+if (tso6)
+offload |= TUN_F_TSO6;
+if ((tso4 || tso6) && ecn)
+offload |= TUN_F_TSO_ECN;
+}
+
+if (ioctl(s->fd, TUNSETOFFLOAD, offload) != 0) {
+fprintf(stderr, "TUNSETOFFLOAD ioctl() failed: %s\n",
+strerror(errno));
+}
+}
+
 static void tap_cleanup(VLANClientState *vc)
 {
 TAPState *s = vc->opaque;
diff --git a/net.h b/net.h
index 6255e2b..a0f0359 100644
--- a/net.h
+++ b/net.h
@@ -170,5 +170,6 @@ VLANClientState *qdev_get_vlan_client(DeviceState *dev,
 
 int tap_has_vnet_hdr(VLANClientState *vc);
 void tap_using_vnet_hdr(VLANClientState *vc, int using_vnet_hdr);
+void tap_set_offload(VLANClientState *vc, int csum, int tso4, int tso6, int 
ecn);
 
 #endif
diff --git a/tap-linux.h b/tap-linux.h
index 8e75348..241cf83 100644
--- a/tap-linux.h
+++ b/tap-linux.h
@@ -22,6 +22,7 @@
 /* Ioctl defines */
 #define TUNSETIFF _IOW('T', 202, int)
 #define TUNGETFEATURES _IOR('T', 207, unsigned int)
+#define TUNSETOFFLOAD  _IOW('T', 208, unsigned int)
 #define TUNGETIFF  _IOR('T', 210, unsigned int)
 #define TUNSETSNDBUF   _IOW('T', 212, int)
 
@@ -30,6 +31,12 @@
 #define IFF_NO_PI  0x1000
 #define IFF_VNET_HDR   0x4000
 
+/* Features for GSO (TUNSETOFFLOAD). */
+#define TUN_F_CSUM 0x01/* You can hand me unchecksummed packets. */
+#define TUN_F_TSO4 0x02/* I can handle TSO for IPv4 packets */
+#define TUN_F_TSO6 0x04/* I can handle TSO for IPv6 packets */
+#define TUN_F_TSO_ECN  0x08/* I can handle TSO with ECN bits. */
+
 struct virtio_net_hdr
 {
 uint8_t flags;
-- 
1.6.2.5





[Qemu-devel] [PATCH 14/19] virtio-net: add vnet_hdr support

2009-10-21 Thread Mark McLoughlin
With '-netdev tap,id=foo -nic model=virtio,netdev=foo' virtio-net can
detect that its peer (i.e. the tap backend) supports vnet headers
and advertise to the guest that it can send packets with partial
checksums and/or TSO packets.

One complication is that if we're migrating and the source host
supports IFF_VNET_HDR but the destination host doesn't, we can't then
stop the guest from using those features. In this scenario, we just
fail the migration.

Signed-off-by: Mark McLoughlin 
---
 hw/virtio-net.c |   49 ++---
 1 files changed, 42 insertions(+), 7 deletions(-)

diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 218f985..5ce4b42 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -120,8 +120,20 @@ static void virtio_net_reset(VirtIODevice *vdev)
 memset(n->vlans, 0, MAX_VLAN >> 3);
 }
 
+static int peer_has_vnet_hdr(VirtIONet *n)
+{
+if (!n->vc->peer)
+return 0;
+
+if (n->vc->peer->type != NET_CLIENT_TYPE_TAP)
+return 0;
+
+return tap_has_vnet_hdr(n->vc->peer);
+}
+
 static uint32_t virtio_net_get_features(VirtIODevice *vdev)
 {
+VirtIONet *n = to_virtio_net(vdev);
 uint32_t features = (1 << VIRTIO_NET_F_MAC) |
 (1 << VIRTIO_NET_F_MRG_RXBUF) |
 (1 << VIRTIO_NET_F_STATUS) |
@@ -130,6 +142,15 @@ static uint32_t virtio_net_get_features(VirtIODevice *vdev)
 (1 << VIRTIO_NET_F_CTRL_VLAN) |
 (1 << VIRTIO_NET_F_CTRL_RX_EXTRA);
 
+if (peer_has_vnet_hdr(n)) {
+tap_using_vnet_hdr(n->vc->peer, 1);
+
+features |= (1 << VIRTIO_NET_F_CSUM);
+features |= (1 << VIRTIO_NET_F_HOST_TSO4);
+features |= (1 << VIRTIO_NET_F_HOST_TSO6);
+features |= (1 << VIRTIO_NET_F_HOST_ECN);
+}
+
 return features;
 }
 
@@ -359,6 +380,11 @@ static int receive_header(VirtIONet *n, struct iovec *iov, 
int iovcnt,
 hdr->flags = 0;
 hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE;
 
+if (peer_has_vnet_hdr(n)) {
+memcpy(hdr, buf, sizeof(*hdr));
+offset = sizeof(*hdr);
+}
+
 /* We only ever receive a struct virtio_net_hdr from the tapfd,
  * but we may be passing along a larger header to the guest.
  */
@@ -378,6 +404,10 @@ static int receive_filter(VirtIONet *n, const uint8_t 
*buf, int size)
 if (n->promisc)
 return 1;
 
+if (peer_has_vnet_hdr(n)) {
+ptr += sizeof(struct virtio_net_hdr);
+}
+
 if (!memcmp(&ptr[12], vlan, sizeof(vlan))) {
 int vid = be16_to_cpup((uint16_t *)(ptr + 14)) & 0xfff;
 if (!(n->vlans[vid >> 5] & (1U << (vid & 0x1f
@@ -510,7 +540,6 @@ static void virtio_net_tx_complete(VLANClientState *vc, 
ssize_t len)
 static void virtio_net_flush_tx(VirtIONet *n, VirtQueue *vq)
 {
 VirtQueueElement elem;
-int has_vnet_hdr = 0;
 
 if (!(n->vdev.status & VIRTIO_CONFIG_S_DRIVER_OK))
 return;
@@ -537,7 +566,7 @@ static void virtio_net_flush_tx(VirtIONet *n, VirtQueue *vq)
 }
 
 /* ignore the header if GSO is not supported */
-if (!has_vnet_hdr) {
+if (!peer_has_vnet_hdr(n)) {
 out_num--;
 out_sg++;
 len += hdr_len;
@@ -610,7 +639,7 @@ static void virtio_net_save(QEMUFile *f, void *opaque)
 qemu_put_be32(f, n->mac_table.in_use);
 qemu_put_buffer(f, n->mac_table.macs, n->mac_table.in_use * ETH_ALEN);
 qemu_put_buffer(f, (uint8_t *)n->vlans, MAX_VLAN >> 3);
-qemu_put_be32(f, 0); /* vnet-hdr placeholder */
+qemu_put_be32(f, peer_has_vnet_hdr(n));
 qemu_put_byte(f, n->mac_table.multi_overflow);
 qemu_put_byte(f, n->mac_table.uni_overflow);
 qemu_put_byte(f, n->alluni);
@@ -662,10 +691,16 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int 
version_id)
 if (version_id >= 6)
 qemu_get_buffer(f, (uint8_t *)n->vlans, MAX_VLAN >> 3);
 
-if (version_id >= 7 && qemu_get_be32(f)) {
-fprintf(stderr,
-"virtio-net: saved image requires vnet header support\n");
-exit(1);
+if (version_id >= 7) {
+if (qemu_get_be32(f) && !peer_has_vnet_hdr(n)) {
+fprintf(stderr,
+"virtio-net: saved image requires vnet_hdr=on\n");
+return -1;
+}
+
+if (peer_has_vnet_hdr(n)) {
+tap_using_vnet_hdr(n->vc->peer, 1);
+}
 }
 
 if (version_id >= 9) {
-- 
1.6.2.5





[Qemu-devel] [PATCH 19/19] virtio-net: add tap_has_ufo flag to saved state

2009-10-21 Thread Mark McLoughlin
If we tell the guest we support UFO and then migrate to host which
doesn't support it, we will find ourselves in grave difficulties.

Prevent this scenario by adding a flag to virtio-net's savevm format
which indicates whether the device requires host UFO support.

Signed-off-by: Mark McLoughlin 
---
 hw/virtio-net.c |   12 +++-
 1 files changed, 11 insertions(+), 1 deletions(-)

diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 3349800..f919952 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -16,7 +16,7 @@
 #include "qemu-timer.h"
 #include "virtio-net.h"
 
-#define VIRTIO_NET_VM_VERSION10
+#define VIRTIO_NET_VM_VERSION11
 
 #define MAC_TABLE_ENTRIES64
 #define MAX_VLAN(1 << 12)   /* Per 802.1Q definition */
@@ -694,6 +694,7 @@ static void virtio_net_save(QEMUFile *f, void *opaque)
 qemu_put_byte(f, n->nomulti);
 qemu_put_byte(f, n->nouni);
 qemu_put_byte(f, n->nobcast);
+qemu_put_byte(f, peer_has_vnet_hdr(n) && tap_has_ufo(n->vc->peer));
 }
 
 static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
@@ -769,6 +770,15 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int 
version_id)
 n->nobcast = qemu_get_byte(f);
 }
 
+if (version_id >= 11) {
+if (qemu_get_byte(f) &&
+(!peer_has_vnet_hdr(n) || !tap_has_ufo(n->vc->peer))) {
+fprintf(stderr,
+"virtio-net: saved image requires TUN_F_UFO support\n");
+return -1;
+}
+}
+
 /* Find the first multicast entry in the saved MAC filter */
 for (i = 0; i < n->mac_table.in_use; i++) {
 if (n->mac_table.macs[i * ETH_ALEN] & 1) {
-- 
1.6.2.5





[Qemu-devel] [PATCH 10/19] net: add an API for 'raw' packets

2009-10-21 Thread Mark McLoughlin
In the case where a NIC and backend agree on a packet header format,
this API allows injecting packets which lack the agreed upon header.

We need this for sending our gratuitous ARP.

Signed-off-by: Mark McLoughlin 
---
 net-queue.h |1 +
 net.c   |   37 +
 net.h   |2 ++
 3 files changed, 32 insertions(+), 8 deletions(-)

diff --git a/net-queue.h b/net-queue.h
index 343760e..a31958e 100644
--- a/net-queue.h
+++ b/net-queue.h
@@ -44,6 +44,7 @@ typedef ssize_t (NetPacketDeliverIOV) (VLANClientState 
*sender,
void *opaque);
 
 #define QEMU_NET_PACKET_FLAG_NONE  0
+#define QEMU_NET_PACKET_FLAG_RAW  (1<<0)
 
 NetQueue *qemu_new_net_queue(NetPacketDeliver *deliver,
  NetPacketDeliverIOV *deliver_iov,
diff --git a/net.c b/net.c
index 30dc402..50d2f83 100644
--- a/net.c
+++ b/net.c
@@ -463,7 +463,10 @@ static ssize_t qemu_deliver_packet(VLANClientState *sender,
 return size;
 }
 
-return vc->receive(vc, data, size);
+if (flags & QEMU_NET_PACKET_FLAG_RAW && vc->receive_raw)
+return vc->receive_raw(vc, data, size);
+else
+return vc->receive(vc, data, size);
 }
 
 static ssize_t qemu_vlan_deliver_packet(VLANClientState *sender,
@@ -488,7 +491,10 @@ static ssize_t qemu_vlan_deliver_packet(VLANClientState 
*sender,
 continue;
 }
 
-len = vc->receive(vc, buf, size);
+if (flags & QEMU_NET_PACKET_FLAG_RAW && vc->receive_raw)
+len = vc->receive_raw(vc, buf, size);
+else
+len = vc->receive(vc, buf, size);
 
 ret = (ret >= 0) ? ret : len;
 }
@@ -526,9 +532,10 @@ void qemu_flush_queued_packets(VLANClientState *vc)
 qemu_net_queue_flush(queue);
 }
 
-ssize_t qemu_send_packet_async(VLANClientState *sender,
-   const uint8_t *buf, int size,
-   NetPacketSent *sent_cb)
+static ssize_t qemu_send_packet_async_with_flags(VLANClientState *sender,
+ unsigned flags,
+ const uint8_t *buf, int size,
+ NetPacketSent *sent_cb)
 {
 NetQueue *queue;
 
@@ -547,9 +554,15 @@ ssize_t qemu_send_packet_async(VLANClientState *sender,
 queue = sender->vlan->send_queue;
 }
 
-return qemu_net_queue_send(queue, sender,
-   QEMU_NET_PACKET_FLAG_NONE,
-   buf, size, sent_cb);
+return qemu_net_queue_send(queue, sender, flags, buf, size, sent_cb);
+}
+
+ssize_t qemu_send_packet_async(VLANClientState *sender,
+   const uint8_t *buf, int size,
+   NetPacketSent *sent_cb)
+{
+return qemu_send_packet_async_with_flags(sender, QEMU_NET_PACKET_FLAG_NONE,
+ buf, size, sent_cb);
 }
 
 void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size)
@@ -557,6 +570,12 @@ void qemu_send_packet(VLANClientState *vc, const uint8_t 
*buf, int size)
 qemu_send_packet_async(vc, buf, size, NULL);
 }
 
+ssize_t qemu_send_packet_raw(VLANClientState *vc, const uint8_t *buf, int size)
+{
+return qemu_send_packet_async_with_flags(vc, QEMU_NET_PACKET_FLAG_RAW,
+ buf, size, NULL);
+}
+
 static ssize_t vc_sendv_compat(VLANClientState *vc, const struct iovec *iov,
int iovcnt)
 {
@@ -626,6 +645,8 @@ static ssize_t qemu_vlan_deliver_packet_iov(VLANClientState 
*sender,
 continue;
 }
 
+assert(!(flags & QEMU_NET_PACKET_FLAG_RAW));
+
 if (vc->receive_iov) {
 len = vc->receive_iov(vc, iov, iovcnt);
 } else {
diff --git a/net.h b/net.h
index 5f28860..53d813c 100644
--- a/net.h
+++ b/net.h
@@ -28,6 +28,7 @@ typedef void (LinkStatusChanged)(VLANClientState *);
 struct VLANClientState {
 net_client_type type;
 NetReceive *receive;
+NetReceive *receive_raw;
 NetReceiveIOV *receive_iov;
 /* Packets may still be sent if this returns zero.  It's used to
rate-limit the slirp code.  */
@@ -72,6 +73,7 @@ ssize_t qemu_sendv_packet(VLANClientState *vc, const struct 
iovec *iov,
 ssize_t qemu_sendv_packet_async(VLANClientState *vc, const struct iovec *iov,
 int iovcnt, NetPacketSent *sent_cb);
 void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size);
+ssize_t qemu_send_packet_raw(VLANClientState *vc, const uint8_t *buf, int 
size);
 ssize_t qemu_send_packet_async(VLANClientState *vc, const uint8_t *buf,
int size, NetPacketSent *sent_cb);
 void qemu_purge_queued_packets(VLANClientState *vc);
-- 
1.6.2.5





[Qemu-devel] [PATCH 12/19] net: use qemu_send_packet_raw() in qemu_announce_self()

2009-10-21 Thread Mark McLoughlin
From: Gleb Natapov 

Use qemu_send_packet_raw to send gratuitous arp. This will ensure that
vnet header is handled properly.

Also, avoid sending the gratuitous packet to the guest. There doesn't
appear to be any reason for doing that and the code will currently just
crash if the NIC is not associated with a vlan.

Signed-off-by: Gleb Natapov 
Signed-off-by: Mark McLoughlin 
---
 savevm.c |7 +--
 1 files changed, 1 insertions(+), 6 deletions(-)

diff --git a/savevm.c b/savevm.c
index 99aa15a..ac1ef42 100644
--- a/savevm.c
+++ b/savevm.c
@@ -114,8 +114,6 @@ static int announce_self_create(uint8_t *buf,
 static void qemu_announce_self_once(void *opaque)
 {
 int i, len;
-VLANState *vlan;
-VLANClientState *vc;
 uint8_t buf[256];
 static int count = SELF_ANNOUNCE_ROUNDS;
 QEMUTimer *timer = *(QEMUTimer **)opaque;
@@ -124,10 +122,7 @@ static void qemu_announce_self_once(void *opaque)
 if (!nd_table[i].used)
 continue;
 len = announce_self_create(buf, nd_table[i].macaddr);
-vlan = nd_table[i].vlan;
-QTAILQ_FOREACH(vc, &vlan->clients, next) {
-vc->receive(vc, buf, len);
-}
+qemu_send_packet_raw(nd_table[i].vc, buf, len);
 }
 if (count--) {
qemu_mod_timer(timer, qemu_get_clock(rt_clock) + 100);
-- 
1.6.2.5





[Qemu-devel] [PATCH 09/19] net: add flags parameter to packet queue interface

2009-10-21 Thread Mark McLoughlin
This allows for the addition of a raw flag, and leaves the way open
for other flags too.

Signed-off-by: Mark McLoughlin 
---
 net-queue.c |   26 ++
 net-queue.h |6 ++
 net.c   |   14 --
 3 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/net-queue.c b/net-queue.c
index 75457f0..f6b01e9 100644
--- a/net-queue.c
+++ b/net-queue.c
@@ -41,6 +41,7 @@
 struct NetPacket {
 QTAILQ_ENTRY(NetPacket) entry;
 VLANClientState *sender;
+unsigned flags;
 int size;
 NetPacketSent *sent_cb;
 uint8_t data[0];
@@ -89,6 +90,7 @@ void qemu_del_net_queue(NetQueue *queue)
 
 static ssize_t qemu_net_queue_append(NetQueue *queue,
  VLANClientState *sender,
+ unsigned flags,
  const uint8_t *buf,
  size_t size,
  NetPacketSent *sent_cb)
@@ -97,6 +99,7 @@ static ssize_t qemu_net_queue_append(NetQueue *queue,
 
 packet = qemu_malloc(sizeof(NetPacket) + size);
 packet->sender = sender;
+packet->flags = flags;
 packet->size = size;
 packet->sent_cb = sent_cb;
 memcpy(packet->data, buf, size);
@@ -108,6 +111,7 @@ static ssize_t qemu_net_queue_append(NetQueue *queue,
 
 static ssize_t qemu_net_queue_append_iov(NetQueue *queue,
  VLANClientState *sender,
+ unsigned flags,
  const struct iovec *iov,
  int iovcnt,
  NetPacketSent *sent_cb)
@@ -123,6 +127,7 @@ static ssize_t qemu_net_queue_append_iov(NetQueue *queue,
 packet = qemu_malloc(sizeof(NetPacket) + max_len);
 packet->sender = sender;
 packet->sent_cb = sent_cb;
+packet->flags = flags;
 packet->size = 0;
 
 for (i = 0; i < iovcnt; i++) {
@@ -139,13 +144,14 @@ static ssize_t qemu_net_queue_append_iov(NetQueue *queue,
 
 static ssize_t qemu_net_queue_deliver(NetQueue *queue,
   VLANClientState *sender,
+  unsigned flags,
   const uint8_t *data,
   size_t size)
 {
 ssize_t ret = -1;
 
 queue->delivering = 1;
-ret = queue->deliver(sender, data, size, queue->opaque);
+ret = queue->deliver(sender, flags, data, size, queue->opaque);
 queue->delivering = 0;
 
 return ret;
@@ -153,13 +159,14 @@ static ssize_t qemu_net_queue_deliver(NetQueue *queue,
 
 static ssize_t qemu_net_queue_deliver_iov(NetQueue *queue,
   VLANClientState *sender,
+  unsigned flags,
   const struct iovec *iov,
   int iovcnt)
 {
 ssize_t ret = -1;
 
 queue->delivering = 1;
-ret = queue->deliver_iov(sender, iov, iovcnt, queue->opaque);
+ret = queue->deliver_iov(sender, flags, iov, iovcnt, queue->opaque);
 queue->delivering = 0;
 
 return ret;
@@ -167,6 +174,7 @@ static ssize_t qemu_net_queue_deliver_iov(NetQueue *queue,
 
 ssize_t qemu_net_queue_send(NetQueue *queue,
 VLANClientState *sender,
+unsigned flags,
 const uint8_t *data,
 size_t size,
 NetPacketSent *sent_cb)
@@ -174,12 +182,12 @@ ssize_t qemu_net_queue_send(NetQueue *queue,
 ssize_t ret;
 
 if (queue->delivering) {
-return qemu_net_queue_append(queue, sender, data, size, NULL);
+return qemu_net_queue_append(queue, sender, flags, data, size, NULL);
 }
 
-ret = qemu_net_queue_deliver(queue, sender, data, size);
+ret = qemu_net_queue_deliver(queue, sender, flags, data, size);
 if (ret == 0 && sent_cb != NULL) {
-qemu_net_queue_append(queue, sender, data, size, sent_cb);
+qemu_net_queue_append(queue, sender, flags, data, size, sent_cb);
 return 0;
 }
 
@@ -190,6 +198,7 @@ ssize_t qemu_net_queue_send(NetQueue *queue,
 
 ssize_t qemu_net_queue_send_iov(NetQueue *queue,
 VLANClientState *sender,
+unsigned flags,
 const struct iovec *iov,
 int iovcnt,
 NetPacketSent *sent_cb)
@@ -197,12 +206,12 @@ ssize_t qemu_net_queue_send_iov(NetQueue *queue,
 ssize_t ret;
 
 if (queue->delivering) {
-return qemu_net_queue_append_iov(queue, sender, iov, iovcnt, NULL);
+return qemu_net_queue_append_iov(queue, sender, flags, iov, iovcnt, 
NULL);
 }
 
-ret = qemu_net_queue_deliver_iov(queue, sender, iov, iovcnt);
+ret = qemu_net_queue_del

[Qemu-devel] [PATCH 16/19] virtio-net: enable tap offload if guest supports it

2009-10-21 Thread Mark McLoughlin
We query the guest's feature set to see if it supports offload and,
if so, we enable those features on the tap interface.

Signed-off-by: Mark McLoughlin 
---
 hw/virtio-net.c |   18 ++
 1 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 5ce4b42..19d00a6 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -149,6 +149,11 @@ static uint32_t virtio_net_get_features(VirtIODevice *vdev)
 features |= (1 << VIRTIO_NET_F_HOST_TSO4);
 features |= (1 << VIRTIO_NET_F_HOST_TSO6);
 features |= (1 << VIRTIO_NET_F_HOST_ECN);
+
+features |= (1 << VIRTIO_NET_F_GUEST_CSUM);
+features |= (1 << VIRTIO_NET_F_GUEST_TSO4);
+features |= (1 << VIRTIO_NET_F_GUEST_TSO6);
+features |= (1 << VIRTIO_NET_F_GUEST_ECN);
 }
 
 return features;
@@ -174,6 +179,14 @@ static void virtio_net_set_features(VirtIODevice *vdev, 
uint32_t features)
 VirtIONet *n = to_virtio_net(vdev);
 
 n->mergeable_rx_bufs = !!(features & (1 << VIRTIO_NET_F_MRG_RXBUF));
+
+if (peer_has_vnet_hdr(n)) {
+tap_set_offload(n->vc->peer,
+(features >> VIRTIO_NET_F_GUEST_CSUM) & 1,
+(features >> VIRTIO_NET_F_GUEST_TSO4) & 1,
+(features >> VIRTIO_NET_F_GUEST_TSO6) & 1,
+(features >> VIRTIO_NET_F_GUEST_ECN)  & 1);
+}
 }
 
 static int virtio_net_handle_rx_mode(VirtIONet *n, uint8_t cmd,
@@ -700,6 +713,11 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int 
version_id)
 
 if (peer_has_vnet_hdr(n)) {
 tap_using_vnet_hdr(n->vc->peer, 1);
+tap_set_offload(n->vc->peer,
+(n->vdev.features >> VIRTIO_NET_F_GUEST_CSUM) & 1,
+(n->vdev.features >> VIRTIO_NET_F_GUEST_TSO4) & 1,
+(n->vdev.features >> VIRTIO_NET_F_GUEST_TSO6) & 1,
+(n->vdev.features >> VIRTIO_NET_F_GUEST_ECN)  & 1);
 }
 }
 
-- 
1.6.2.5





[Qemu-devel] [PATCH 17/19] Work around dhclient brokenness

2009-10-21 Thread Mark McLoughlin
From: Anthony Liguori 

With the latest GSO/csum offload patches, any guest using an unpatched version
of dhclient (any Ubuntu guest, for instance), will no longer be able to get
a DHCP address.

dhclient is actually at fault here.  It uses AF_PACKET to receive DHCP responses
but does not check auxdata to see if the packet has a valid csum.  This causes
it to throw out the DHCP responses it gets from the virtio interface as there
is not a valid checksum.

Fedora has carried a patch to fix their dhclient (it's needed for Xen too) but
this patch has not made it into a release of dhclient.  AFAIK, the patch is in
the dhclient CVS but I cannot confirm since their CVS is not public.

This patch, suggested by Rusty, looks for UDP packets (of a normal MTU) and
explicitly adds a checksum to them if they are missing one.

This allows unpatched dhclients to continue to work without needing to update
the guest kernels.

Signed-off-by: Anthony Liguori 
Signed-off-by: Mark McLoughlin 
---
 hw/virtio-net.c |   29 +
 1 files changed, 29 insertions(+), 0 deletions(-)

diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 19d00a6..4590594 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -369,6 +369,34 @@ static int virtio_net_can_receive(VLANClientState *vc)
 return do_virtio_net_can_receive(n, VIRTIO_NET_MAX_BUFSIZE);
 }
 
+/* dhclient uses AF_PACKET but doesn't pass auxdata to the kernel so
+ * it never finds out that the packets don't have valid checksums.  This
+ * causes dhclient to get upset.  Fedora's carried a patch for ages to
+ * fix this with Xen but it hasn't appeared in an upstream release of
+ * dhclient yet.
+ *
+ * To avoid breaking existing guests, we catch udp packets and add
+ * checksums.  This is terrible but it's better than hacking the guest
+ * kernels.
+ *
+ * N.B. if we introduce a zero-copy API, this operation is no longer free so
+ * we should provide a mechanism to disable it to avoid polluting the host
+ * cache.
+ */
+static void work_around_broken_dhclient(struct virtio_net_hdr *hdr,
+const uint8_t *buf, size_t size)
+{
+if ((hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && /* missing csum */
+(size > 27 && size < 1500) && /* normal sized MTU */
+(buf[12] == 0x08 && buf[13] == 0x00) && /* ethertype == IPv4 */
+(buf[23] == 17) && /* ip.protocol == UDP */
+(buf[34] == 0 && buf[35] == 67)) { /* udp.srcport == bootps */
+/* FIXME this cast is evil */
+net_checksum_calculate((uint8_t *)buf, size);
+hdr->flags &= ~VIRTIO_NET_HDR_F_NEEDS_CSUM;
+}
+}
+
 static int iov_fill(struct iovec *iov, int iovcnt, const void *buf, int count)
 {
 int offset, i;
@@ -396,6 +424,7 @@ static int receive_header(VirtIONet *n, struct iovec *iov, 
int iovcnt,
 if (peer_has_vnet_hdr(n)) {
 memcpy(hdr, buf, sizeof(*hdr));
 offset = sizeof(*hdr);
+work_around_broken_dhclient(hdr, buf + offset, size - offset);
 }
 
 /* We only ever receive a struct virtio_net_hdr from the tapfd,
-- 
1.6.2.5





[Qemu-devel] [PATCH 18/19] Enable UFO on virtio-net and tap devices

2009-10-21 Thread Mark McLoughlin
From: Sridhar Samudrala 

Enable UFO on the host tap device if supported and allow setting UFO
on virtio-net in the guest.

Signed-off-by: Sridhar Samudrala 
Signed-off-by: Mark McLoughlin 
---
 hw/virtio-net.c |   11 +--
 net.c   |   36 
 net.h   |3 ++-
 tap-linux.h |1 +
 4 files changed, 44 insertions(+), 7 deletions(-)

diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 4590594..3349800 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -154,6 +154,11 @@ static uint32_t virtio_net_get_features(VirtIODevice *vdev)
 features |= (1 << VIRTIO_NET_F_GUEST_TSO4);
 features |= (1 << VIRTIO_NET_F_GUEST_TSO6);
 features |= (1 << VIRTIO_NET_F_GUEST_ECN);
+
+if (tap_has_ufo(n->vc->peer)) {
+features |= (1 << VIRTIO_NET_F_GUEST_UFO);
+features |= (1 << VIRTIO_NET_F_HOST_UFO);
+}
 }
 
 return features;
@@ -185,7 +190,8 @@ static void virtio_net_set_features(VirtIODevice *vdev, 
uint32_t features)
 (features >> VIRTIO_NET_F_GUEST_CSUM) & 1,
 (features >> VIRTIO_NET_F_GUEST_TSO4) & 1,
 (features >> VIRTIO_NET_F_GUEST_TSO6) & 1,
-(features >> VIRTIO_NET_F_GUEST_ECN)  & 1);
+(features >> VIRTIO_NET_F_GUEST_ECN)  & 1,
+(features >> VIRTIO_NET_F_GUEST_UFO)  & 1);
 }
 }
 
@@ -746,7 +752,8 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int 
version_id)
 (n->vdev.features >> VIRTIO_NET_F_GUEST_CSUM) & 1,
 (n->vdev.features >> VIRTIO_NET_F_GUEST_TSO4) & 1,
 (n->vdev.features >> VIRTIO_NET_F_GUEST_TSO6) & 1,
-(n->vdev.features >> VIRTIO_NET_F_GUEST_ECN)  & 1);
+(n->vdev.features >> VIRTIO_NET_F_GUEST_ECN)  & 1,
+(n->vdev.features >> VIRTIO_NET_F_GUEST_UFO)  & 1);
 }
 }
 
diff --git a/net.c b/net.c
index 746a3d6..3e54c53 100644
--- a/net.c
+++ b/net.c
@@ -1280,6 +1280,10 @@ void do_info_usernet(Monitor *mon)
 #endif /* CONFIG_SLIRP */
 
 #if defined(_WIN32)
+int tap_has_ufo(VLANClientState *vc)
+{
+return 0;
+}
 int tap_has_vnet_hdr(VLANClientState *vc)
 {
 return 0;
@@ -1287,7 +1291,8 @@ int tap_has_vnet_hdr(VLANClientState *vc)
 void tap_using_vnet_hdr(VLANClientState *vc, int using_vnet_hdr)
 {
 }
-void tap_set_offload(VLANClientState *vc, int csum, int tso4, int tso6, int 
ecn)
+void tap_set_offload(VLANClientState *vc, int csum, int tso4,
+ int tso6, int ecn, int ufo)
 {
 }
 #else /* !defined(_WIN32) */
@@ -1307,6 +1312,7 @@ typedef struct TAPState {
 unsigned int write_poll : 1;
 unsigned int has_vnet_hdr : 1;
 unsigned int using_vnet_hdr : 1;
+unsigned int has_ufo: 1;
 } TAPState;
 
 static int launch_script(const char *setup_script, const char *ifname, int fd);
@@ -1494,6 +1500,15 @@ static int tap_set_sndbuf(TAPState *s, QemuOpts *opts)
 return 0;
 }
 
+int tap_has_ufo(VLANClientState *vc)
+{
+TAPState *s = vc->opaque;
+
+assert(vc->type == NET_CLIENT_TYPE_TAP);
+
+return s->has_ufo;
+}
+
 int tap_has_vnet_hdr(VLANClientState *vc)
 {
 TAPState *s = vc->opaque;
@@ -1527,7 +1542,8 @@ static int tap_probe_vnet_hdr(int fd)
 return ifr.ifr_flags & IFF_VNET_HDR;
 }
 
-void tap_set_offload(VLANClientState *vc, int csum, int tso4, int tso6, int 
ecn)
+void tap_set_offload(VLANClientState *vc, int csum, int tso4,
+ int tso6, int ecn, int ufo)
 {
 TAPState *s = vc->opaque;
 unsigned int offload = 0;
@@ -1540,11 +1556,16 @@ void tap_set_offload(VLANClientState *vc, int csum, int 
tso4, int tso6, int ecn)
 offload |= TUN_F_TSO6;
 if ((tso4 || tso6) && ecn)
 offload |= TUN_F_TSO_ECN;
+if (ufo)
+offload |= TUN_F_UFO;
 }
 
 if (ioctl(s->fd, TUNSETOFFLOAD, offload) != 0) {
-fprintf(stderr, "TUNSETOFFLOAD ioctl() failed: %s\n",
-strerror(errno));
+offload &= ~TUN_F_UFO;
+if (ioctl(s->fd, TUNSETOFFLOAD, offload) != 0) {
+fprintf(stderr, "TUNSETOFFLOAD ioctl() failed: %s\n",
+strerror(errno));
+}
 }
 }
 
@@ -1572,6 +1593,7 @@ static TAPState *net_tap_fd_init(VLANState *vlan,
  int vnet_hdr)
 {
 TAPState *s;
+unsigned int offload;
 
 s = qemu_mallocz(sizeof(TAPState));
 s->fd = fd;
@@ -1581,6 +1603,12 @@ static TAPState *net_tap_fd_init(VLANState *vlan,
  vlan, NULL, model, name, NULL,
  tap_receive, tap_receive_raw,
  tap_receive_iov, tap_cleanup, s);
+s->has_ufo = 0;
+/* Check if tap supports UFO */
+offload = TUN_F_CSUM | TUN_F_UFO;
+if (ioctl(s->fd, TUNSETOFFLOAD, 

[Qemu-devel] [PATCH 11/19] net: add receive_raw parameter to qemu_new_vlan_client()

2009-10-21 Thread Mark McLoughlin
Trivial patch to allow supplying a receive_raw function.

A future cleanup should combine this function pointer parameters into a
table.

Signed-off-by: Mark McLoughlin 
---
 hw/dp8393x.c |2 +-
 hw/etraxfs_eth.c |2 +-
 hw/mcf_fec.c |2 +-
 hw/mipsnet.c |2 +-
 hw/qdev.c|3 ++-
 hw/usb-net.c |2 +-
 hw/xen_nic.c |2 +-
 net.c|   14 --
 net.h|1 +
 tap-win32.c  |2 +-
 10 files changed, 18 insertions(+), 14 deletions(-)

diff --git a/hw/dp8393x.c b/hw/dp8393x.c
index 5622170..ae8b16e 100644
--- a/hw/dp8393x.c
+++ b/hw/dp8393x.c
@@ -892,7 +892,7 @@ void dp83932_init(NICInfo *nd, target_phys_addr_t base, int 
it_shift,
 s->vc = nd->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
   nd->vlan, nd->netdev,
   nd->model, nd->name,
-  nic_can_receive, nic_receive, NULL,
+  nic_can_receive, nic_receive, NULL, 
NULL,
   nic_cleanup, s);
 
 qemu_format_nic_info_str(s->vc, nd->macaddr);
diff --git a/hw/etraxfs_eth.c b/hw/etraxfs_eth.c
index 2a583a3..ffe7082 100644
--- a/hw/etraxfs_eth.c
+++ b/hw/etraxfs_eth.c
@@ -594,7 +594,7 @@ void *etraxfs_eth_init(NICInfo *nd, target_phys_addr_t 
base, int phyaddr)
 nd->vlan, nd->netdev,
 nd->model, nd->name,
 eth_can_receive, eth_receive,
-NULL, eth_cleanup, eth);
+NULL, NULL, eth_cleanup, eth);
eth->vc->opaque = eth;
eth->vc->link_status_changed = eth_set_link;
 
diff --git a/hw/mcf_fec.c b/hw/mcf_fec.c
index 0567bcd..9f0d0f4 100644
--- a/hw/mcf_fec.c
+++ b/hw/mcf_fec.c
@@ -466,7 +466,7 @@ void mcf_fec_init(NICInfo *nd, target_phys_addr_t base, 
qemu_irq *irq)
   nd->vlan, nd->netdev,
   nd->model, nd->name,
   mcf_fec_can_receive, mcf_fec_receive,
-  NULL, mcf_fec_cleanup, s);
+  NULL, NULL, mcf_fec_cleanup, s);
 memcpy(s->macaddr, nd->macaddr, 6);
 qemu_format_nic_info_str(s->vc, s->macaddr);
 }
diff --git a/hw/mipsnet.c b/hw/mipsnet.c
index d32099f..65e1d59 100644
--- a/hw/mipsnet.c
+++ b/hw/mipsnet.c
@@ -267,7 +267,7 @@ void mipsnet_init (int base, qemu_irq irq, NICInfo *nd)
   nd->vlan, nd->netdev,
   nd->model, nd->name,
   mipsnet_can_receive, 
mipsnet_receive,
-  NULL, mipsnet_cleanup, s);
+  NULL, NULL, mipsnet_cleanup, s);
 } else {
 s->vc = NULL;
 }
diff --git a/hw/qdev.c b/hw/qdev.c
index bc3a0d5..38ac037 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -373,7 +373,8 @@ VLANClientState *qdev_get_vlan_client(DeviceState *dev,
 nd->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
   nd->vlan, nd->netdev,
   nd->model, nd->name,
-  can_receive, receive, receive_iov,
+  can_receive, receive,
+  NULL, receive_iov,
   cleanup, opaque);
 return nd->vc;
 }
diff --git a/hw/usb-net.c b/hw/usb-net.c
index 2393812..9c6549c 100644
--- a/hw/usb-net.c
+++ b/hw/usb-net.c
@@ -1465,7 +1465,7 @@ USBDevice *usb_net_init(NICInfo *nd)
   nd->model, nd->name,
   usbnet_can_receive,
   usbnet_receive,
-  NULL,
+  NULL, NULL,
   usbnet_cleanup, s);
 
 qemu_format_nic_info_str(s->vc, s->mac);
diff --git a/hw/xen_nic.c b/hw/xen_nic.c
index 2a179f0..75599d6 100644
--- a/hw/xen_nic.c
+++ b/hw/xen_nic.c
@@ -303,7 +303,7 @@ static int net_init(struct XenDevice *xendev)
 vlan = qemu_find_vlan(netdev->xendev.dev, 1);
 netdev->vs = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
   vlan, NULL, "xen", NULL,
-  net_rx_ok, net_rx_packet, NULL,
+  net_rx_ok, net_rx_packet, NULL, NULL,
   NULL, netdev);
 snprintf(netdev->vs->info_str, sizeof(netdev->vs->info_str),
  "nic: xenbus vif macaddr=%s", netdev->mac);
diff --git a/net.c b/net.c

[Qemu-devel] New machine type

2009-10-21 Thread Johnny Giacomoni
Hi !

I need to create a new machine type with QEMU (QEMUMachine).
Is it something I can find to do that ? What do I need exactly ?

Thanks for help.

Have a nice day !

-- 
Johnny Giacomoni
Alternant en Electronique Informatique et Systèmes
1ère année du cycle ingénieur ESISAR Valence


[Qemu-devel] [PATCH 04/22] qdev: add vlan property

2009-10-21 Thread Gerd Hoffmann

Signed-off-by: Gerd Hoffmann 
---
 hw/qdev-properties.c |   39 +++
 hw/qdev.h|6 ++
 2 files changed, 45 insertions(+), 0 deletions(-)

diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 76925c8..c9843a2 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -282,6 +282,40 @@ PropertyInfo qdev_prop_netdev = {
 .print = print_netdev,
 };
 
+/* --- vlan --- */
+
+static int parse_vlan(DeviceState *dev, Property *prop, const char *str)
+{
+VLANState **ptr = qdev_get_prop_ptr(dev, prop);
+int id;
+
+if (sscanf(str, "%d", &id) != 1)
+return -1;
+*ptr = qemu_find_vlan(id, 1);
+if (*ptr == NULL)
+return -1;
+return 0;
+}
+
+static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len)
+{
+VLANState **ptr = qdev_get_prop_ptr(dev, prop);
+
+if (*ptr) {
+return snprintf(dest, len, "%d", (*ptr)->id);
+} else {
+return snprintf(dest, len, "");
+}
+}
+
+PropertyInfo qdev_prop_vlan = {
+.name  = "vlan",
+.type  = PROP_TYPE_VLAN,
+.size  = sizeof(VLANClientState*),
+.parse = parse_vlan,
+.print = print_vlan,
+};
+
 /* --- pointer --- */
 
 static int print_ptr(DeviceState *dev, Property *prop, char *dest, size_t len)
@@ -496,6 +530,11 @@ void qdev_prop_set_netdev(DeviceState *dev, const char 
*name, VLANClientState *v
 qdev_prop_set(dev, name, &value, PROP_TYPE_NETDEV);
 }
 
+void qdev_prop_set_vlan(DeviceState *dev, const char *name, VLANState *value)
+{
+qdev_prop_set(dev, name, &value, PROP_TYPE_VLAN);
+}
+
 void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
 {
 qdev_prop_set(dev, name, value, PROP_TYPE_MACADDR);
diff --git a/hw/qdev.h b/hw/qdev.h
index c0d59bc..c678ab2 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -80,6 +80,7 @@ enum PropertyType {
 PROP_TYPE_DRIVE,
 PROP_TYPE_CHR,
 PROP_TYPE_NETDEV,
+PROP_TYPE_VLAN,
 PROP_TYPE_PTR,
 };
 
@@ -191,6 +192,8 @@ extern PropertyInfo qdev_prop_chr;
 extern PropertyInfo qdev_prop_ptr;
 extern PropertyInfo qdev_prop_macaddr;
 extern PropertyInfo qdev_prop_drive;
+extern PropertyInfo qdev_prop_netdev;
+extern PropertyInfo qdev_prop_vlan;
 extern PropertyInfo qdev_prop_pci_devfn;
 
 #define DEFINE_PROP(_name, _state, _field, _prop, _type) { \
@@ -230,6 +233,8 @@ extern PropertyInfo qdev_prop_pci_devfn;
 DEFINE_PROP(_n, _s, _f, qdev_prop_chr, CharDriverState*)
 #define DEFINE_PROP_NETDEV(_n, _s, _f) \
 DEFINE_PROP(_n, _s, _f, qdev_prop_netdev, VLANClientState*)
+#define DEFINE_PROP_VLAN(_n, _s, _f) \
+DEFINE_PROP(_n, _s, _f, qdev_prop_vlan, VLANState*)
 #define DEFINE_PROP_DRIVE(_n, _s, _f) \
 DEFINE_PROP(_n, _s, _f, qdev_prop_drive, DriveInfo*)
 #define DEFINE_PROP_MACADDR(_n, _s, _f) \
@@ -249,6 +254,7 @@ void qdev_prop_set_int32(DeviceState *dev, const char 
*name, int32_t value);
 void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value);
 void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState 
*value);
 void qdev_prop_set_netdev(DeviceState *dev, const char *name, VLANClientState 
*value);
+void qdev_prop_set_vlan(DeviceState *dev, const char *name, VLANState *value);
 void qdev_prop_set_drive(DeviceState *dev, const char *name, DriveInfo *value);
 void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value);
 /* FIXME: Remove opaque pointer properties.  */
-- 
1.6.2.5





[Qemu-devel] [PATCH 01/22] net: add macaddr type.

2009-10-21 Thread Gerd Hoffmann
Add new type for mac addresses.

Add function which sets the qemu default mac address if it finds the mac
address uninitialized (i.e. all zeros).

Signed-off-by: Gerd Hoffmann 
---
 net.c |   15 +++
 net.h |5 +
 qemu-common.h |1 +
 3 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/net.c b/net.c
index 4708080..3b69d3b 100644
--- a/net.c
+++ b/net.c
@@ -280,6 +280,21 @@ void qemu_format_nic_info_str(VLANClientState *vc, uint8_t 
macaddr[6])
  macaddr[3], macaddr[4], macaddr[5]);
 }
 
+void qemu_macaddr_default_if_unset(MACAddr *macaddr)
+{
+static int index = 0;
+static const MACAddr zero = { .a = { 0,0,0,0,0,0 } };
+
+if (memcmp(macaddr, &zero, sizeof(zero)) != 0)
+return;
+macaddr->a[0] = 0x52;
+macaddr->a[1] = 0x54;
+macaddr->a[2] = 0x00;
+macaddr->a[3] = 0x12;
+macaddr->a[4] = 0x34;
+macaddr->a[5] = 0x56 + index++;
+}
+
 static char *assign_name(VLANClientState *vc1, const char *model)
 {
 VLANState *vlan;
diff --git a/net.h b/net.h
index 439de2a..605092a 100644
--- a/net.h
+++ b/net.h
@@ -7,6 +7,10 @@
 #include "qemu-option.h"
 #include "net-queue.h"
 
+struct MACAddr {
+uint8_t a[6];
+};
+
 /* VLANs support */
 
 typedef int (NetCanReceive)(VLANClientState *);
@@ -65,6 +69,7 @@ ssize_t qemu_send_packet_async(VLANClientState *vc, const 
uint8_t *buf,
 void qemu_purge_queued_packets(VLANClientState *vc);
 void qemu_flush_queued_packets(VLANClientState *vc);
 void qemu_format_nic_info_str(VLANClientState *vc, uint8_t macaddr[6]);
+void qemu_macaddr_default_if_unset(MACAddr *macaddr);
 int qemu_show_nic_models(const char *arg, const char *const *models);
 void qemu_check_nic_model(NICInfo *nd, const char *model);
 int qemu_find_nic_model(NICInfo *nd, const char * const *models,
diff --git a/qemu-common.h b/qemu-common.h
index 8551862..980f362 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -180,6 +180,7 @@ typedef struct PixelFormat PixelFormat;
 typedef struct TextConsole TextConsole;
 typedef TextConsole QEMUConsole;
 typedef struct CharDriverState CharDriverState;
+typedef struct MACAddr MACAddr;
 typedef struct VLANState VLANState;
 typedef struct VLANClientState VLANClientState;
 typedef struct QEMUFile QEMUFile;
-- 
1.6.2.5





[Qemu-devel] [PATCH 01/22] qdev-ify network cards

2009-10-21 Thread Gerd Hoffmann
  Hi,

Now the first non-RfC version of this series.  Changes compared to
last RfC patch:

  * Added some common helper code so we have less code duplication
and the actual driver changes are smaller.
  * All network drivers are converted now.
  * Some final cleanups which zap dead code.

With the patches applied network cards can now be created using ...

  -device ne2k_isa,mac=00:11:22:33:44:55,vlan=1,irq=3,id=foo

'info qtree' shows ...

[ ... ]
bus: isa.0
  type ISA
  dev: ne2k_isa, id "foo"
dev-prop: iobase = 0x300
dev-prop: irq = 3
dev-prop: mac = 00:11:22:33:44:55
dev-prop: vlan = 1
dev-prop: netdev = 
[ ... ]

'info network' shows:

[ ... ]
VLAN 1 devices:
  foo: model=ne2k_isa,macaddr=00:11:22:33:44:55

The nic initialization code calls qemu_new_vlan_client() with the
vlan/netdev specified using the properties.  Likewise the device
cleanup code should call qemu_del_vlan_client (which only makes sense
for hot-pluggable devices).

struct NICInfo is only involved when creating nics using the legacy
path (via -net nic,...).

This patch series is also available here:
  http://repo.or.cz/w/qemu/kraxel.git?a=shortlog;h=refs/heads/nic.v4

cheers,
  Gerd





[Qemu-devel] [PATCH 03/22] qdev: add netdev property

2009-10-21 Thread Gerd Hoffmann

Signed-off-by: Gerd Hoffmann 
---
 hw/qdev-properties.c |   36 
 hw/qdev.h|4 
 net.c|2 +-
 net.h|1 +
 4 files changed, 42 insertions(+), 1 deletions(-)

diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 1d68125..76925c8 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -251,6 +251,37 @@ PropertyInfo qdev_prop_chr = {
 .print = print_chr,
 };
 
+/* --- netdev device --- */
+
+static int parse_netdev(DeviceState *dev, Property *prop, const char *str)
+{
+VLANClientState **ptr = qdev_get_prop_ptr(dev, prop);
+
+*ptr = qemu_find_netdev(str);
+if (*ptr == NULL)
+return -1;
+return 0;
+}
+
+static int print_netdev(DeviceState *dev, Property *prop, char *dest, size_t 
len)
+{
+VLANClientState **ptr = qdev_get_prop_ptr(dev, prop);
+
+if (*ptr && (*ptr)->name) {
+return snprintf(dest, len, "%s", (*ptr)->name);
+} else {
+return snprintf(dest, len, "");
+}
+}
+
+PropertyInfo qdev_prop_netdev = {
+.name  = "netdev",
+.type  = PROP_TYPE_NETDEV,
+.size  = sizeof(VLANClientState*),
+.parse = parse_netdev,
+.print = print_netdev,
+};
+
 /* --- pointer --- */
 
 static int print_ptr(DeviceState *dev, Property *prop, char *dest, size_t len)
@@ -460,6 +491,11 @@ void qdev_prop_set_chr(DeviceState *dev, const char *name, 
CharDriverState *valu
 qdev_prop_set(dev, name, &value, PROP_TYPE_CHR);
 }
 
+void qdev_prop_set_netdev(DeviceState *dev, const char *name, VLANClientState 
*value)
+{
+qdev_prop_set(dev, name, &value, PROP_TYPE_NETDEV);
+}
+
 void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
 {
 qdev_prop_set(dev, name, value, PROP_TYPE_MACADDR);
diff --git a/hw/qdev.h b/hw/qdev.h
index 118e886..c0d59bc 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -79,6 +79,7 @@ enum PropertyType {
 PROP_TYPE_MACADDR,
 PROP_TYPE_DRIVE,
 PROP_TYPE_CHR,
+PROP_TYPE_NETDEV,
 PROP_TYPE_PTR,
 };
 
@@ -227,6 +228,8 @@ extern PropertyInfo qdev_prop_pci_devfn;
 DEFINE_PROP(_n, _s, _f, qdev_prop_ptr, void*)
 #define DEFINE_PROP_CHR(_n, _s, _f) \
 DEFINE_PROP(_n, _s, _f, qdev_prop_chr, CharDriverState*)
+#define DEFINE_PROP_NETDEV(_n, _s, _f) \
+DEFINE_PROP(_n, _s, _f, qdev_prop_netdev, VLANClientState*)
 #define DEFINE_PROP_DRIVE(_n, _s, _f) \
 DEFINE_PROP(_n, _s, _f, qdev_prop_drive, DriveInfo*)
 #define DEFINE_PROP_MACADDR(_n, _s, _f) \
@@ -245,6 +248,7 @@ void qdev_prop_set_uint32(DeviceState *dev, const char 
*name, uint32_t value);
 void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value);
 void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value);
 void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState 
*value);
+void qdev_prop_set_netdev(DeviceState *dev, const char *name, VLANClientState 
*value);
 void qdev_prop_set_drive(DeviceState *dev, const char *name, DriveInfo *value);
 void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value);
 /* FIXME: Remove opaque pointer properties.  */
diff --git a/net.c b/net.c
index 3b69d3b..75a01d2 100644
--- a/net.c
+++ b/net.c
@@ -2363,7 +2363,7 @@ VLANState *qemu_find_vlan(int id, int allocate)
 return vlan;
 }
 
-static VLANClientState *qemu_find_netdev(const char *id)
+VLANClientState *qemu_find_netdev(const char *id)
 {
 VLANClientState *vc;
 
diff --git a/net.h b/net.h
index 605092a..6a24f55 100644
--- a/net.h
+++ b/net.h
@@ -47,6 +47,7 @@ struct VLANState {
 };
 
 VLANState *qemu_find_vlan(int id, int allocate);
+VLANClientState *qemu_find_netdev(const char *id);
 VLANClientState *qemu_new_vlan_client(VLANState *vlan,
   VLANClientState *peer,
   const char *model,
-- 
1.6.2.5





[Qemu-devel] [PATCH 02/22] qdev: mac addr property fixups

2009-10-21 Thread Gerd Hoffmann
Make the mac property use the newly added type for the mac address.

Signed-off-by: Gerd Hoffmann 
---
 hw/qdev-properties.c |   31 +--
 hw/qdev.h|3 ++-
 2 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 5c627fa..1d68125 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -1,4 +1,5 @@
 #include "sysemu.h"
+#include "net.h"
 #include "qdev.h"
 
 void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
@@ -274,7 +275,7 @@ PropertyInfo qdev_prop_ptr = {
  */
 static int parse_mac(DeviceState *dev, Property *prop, const char *str)
 {
-uint8_t *mac = qdev_get_prop_ptr(dev, prop);
+MACAddr *mac = qdev_get_prop_ptr(dev, prop);
 int i, pos;
 char *p;
 
@@ -283,26 +284,31 @@ static int parse_mac(DeviceState *dev, Property *prop, 
const char *str)
 return -1;
 if (!qemu_isxdigit(str[pos+1]))
 return -1;
-if (i == 5 && str[pos+2] != '\0')
-return -1;
-if (str[pos+2] != ':' && str[pos+2] != '-')
-return -1;
-mac[i] = strtol(str+pos, &p, 16);
+if (i == 5) {
+if (str[pos+2] != '\0')
+return -1;
+} else {
+if (str[pos+2] != ':' && str[pos+2] != '-')
+return -1;
+}
+mac->a[i] = strtol(str+pos, &p, 16);
 }
 return 0;
 }
 
 static int print_mac(DeviceState *dev, Property *prop, char *dest, size_t len)
 {
-uint8_t *mac = qdev_get_prop_ptr(dev, prop);
+MACAddr *mac = qdev_get_prop_ptr(dev, prop);
+
 return snprintf(dest, len, "%02x:%02x:%02x:%02x:%02x:%02x",
-mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+mac->a[0], mac->a[1], mac->a[2],
+mac->a[3], mac->a[4], mac->a[5]);
 }
 
 PropertyInfo qdev_prop_macaddr = {
-.name  = "mac-addr",
+.name  = "macaddr",
 .type  = PROP_TYPE_MACADDR,
-.size  = 6,
+.size  = sizeof(MACAddr),
 .parse = parse_mac,
 .print = print_mac,
 };
@@ -454,6 +460,11 @@ void qdev_prop_set_chr(DeviceState *dev, const char *name, 
CharDriverState *valu
 qdev_prop_set(dev, name, &value, PROP_TYPE_CHR);
 }
 
+void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
+{
+qdev_prop_set(dev, name, value, PROP_TYPE_MACADDR);
+}
+
 void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
 {
 qdev_prop_set(dev, name, &value, PROP_TYPE_PTR);
diff --git a/hw/qdev.h b/hw/qdev.h
index 8cd843e..118e886 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -230,7 +230,7 @@ extern PropertyInfo qdev_prop_pci_devfn;
 #define DEFINE_PROP_DRIVE(_n, _s, _f) \
 DEFINE_PROP(_n, _s, _f, qdev_prop_drive, DriveInfo*)
 #define DEFINE_PROP_MACADDR(_n, _s, _f) \
-DEFINE_PROP(_n, _s, _f, qdev_prop_macaddr, uint8_t[6])
+DEFINE_PROP(_n, _s, _f, qdev_prop_macaddr, MACAddr)
 
 #define DEFINE_PROP_END_OF_LIST()   \
 {}
@@ -246,6 +246,7 @@ void qdev_prop_set_int32(DeviceState *dev, const char 
*name, int32_t value);
 void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value);
 void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState 
*value);
 void qdev_prop_set_drive(DeviceState *dev, const char *name, DriveInfo *value);
+void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value);
 /* FIXME: Remove opaque pointer properties.  */
 void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value);
 void qdev_prop_set_defaults(DeviceState *dev, Property *props);
-- 
1.6.2.5





[Qemu-devel] [PATCH 07/22] qdev: add qdev_prop_exists()

2009-10-21 Thread Gerd Hoffmann
Function test whenever a driver has a specific property.

Signed-off-by: Gerd Hoffmann 
---
 hw/qdev-properties.c |5 +
 hw/qdev.h|1 +
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index c9843a2..370f356 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -452,6 +452,11 @@ static Property *qdev_prop_find(DeviceState *dev, const 
char *name)
 return NULL;
 }
 
+int qdev_prop_exists(DeviceState *dev, const char *name)
+{
+return qdev_prop_find(dev, name) ? true : false;
+}
+
 int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
 {
 Property *prop;
diff --git a/hw/qdev.h b/hw/qdev.h
index c678ab2..5271a3c 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -245,6 +245,7 @@ extern PropertyInfo qdev_prop_pci_devfn;
 
 /* Set properties between creation and init.  */
 void *qdev_get_prop_ptr(DeviceState *dev, Property *prop);
+int qdev_prop_exists(DeviceState *dev, const char *name);
 int qdev_prop_parse(DeviceState *dev, const char *name, const char *value);
 void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum 
PropertyType type);
 void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value);
-- 
1.6.2.5





[Qemu-devel] [PATCH 08/22] prepare pci nic init path for qdev property configuration.

2009-10-21 Thread Gerd Hoffmann
Initialization path will work with both converted and not-converted
drivers, so we can convert drivers one by one.

Signed-off-by: Gerd Hoffmann 
---
 hw/pci.c |   10 --
 1 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index abf07ca..fe2c4bd 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -859,10 +859,16 @@ PCIDevice *pci_nic_init(NICInfo *nd, const char 
*default_model,
 dev = &pci_dev->qdev;
 if (nd->name)
 dev->id = qemu_strdup(nd->name);
-dev->nd = nd;
+if (qdev_prop_exists(dev, "mac")) {
+/* qdev-ified */
+qdev_set_nic_properties(dev, nd);
+} else {
+/* legacy */
+dev->nd = nd;
+nd->private = dev;
+}
 if (qdev_init(dev) < 0)
 return NULL;
-nd->private = dev;
 return pci_dev;
 }
 
-- 
1.6.2.5





[Qemu-devel] [PATCH 05/22] qdev/net: common nic property bits

2009-10-21 Thread Gerd Hoffmann
Add a new type for properties common to all nics.
Add helper functions and macros to deal with it.

Signed-off-by: Gerd Hoffmann 
---
 hw/qdev.c |9 +
 net.h |   14 ++
 2 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index 20f931c..b32dbfc 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -383,6 +383,15 @@ void qdev_get_macaddr(DeviceState *dev, uint8_t *macaddr)
 memcpy(macaddr, dev->nd->macaddr, 6);
 }
 
+void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
+{
+qdev_prop_set_macaddr(dev, "mac", nd->macaddr);
+if (nd->vlan)
+qdev_prop_set_vlan(dev, "vlan", nd->vlan);
+if (nd->netdev)
+qdev_prop_set_netdev(dev, "netdev", nd->netdev);
+}
+
 static int next_block_unit[IF_COUNT];
 
 /* Get a block device.  This should only be used for single-drive devices
diff --git a/net.h b/net.h
index 6a24f55..f2d10f0 100644
--- a/net.h
+++ b/net.h
@@ -11,6 +11,19 @@ struct MACAddr {
 uint8_t a[6];
 };
 
+/* qdev nic properties */
+
+typedef struct NICConf {
+MACAddr macaddr;
+VLANState *vlan;
+VLANClientState *peer;
+} NICConf;
+
+#define DEFINE_NIC_PROPERTIES(_state, _conf)\
+DEFINE_PROP_MACADDR("mac",   _state, _conf.macaddr),\
+DEFINE_PROP_VLAN("vlan", _state, _conf.vlan),   \
+DEFINE_PROP_NETDEV("netdev", _state, _conf.peer)
+
 /* VLANs support */
 
 typedef int (NetCanReceive)(VLANClientState *);
@@ -158,5 +171,6 @@ VLANClientState *qdev_get_vlan_client(DeviceState *dev,
   NetReceiveIOV *receive_iov,
   NetCleanup *cleanup,
   void *opaque);
+void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd);
 
 #endif
-- 
1.6.2.5





[Qemu-devel] [PATCH 09/22] ne2k_pci: use qdev properties for configuration.

2009-10-21 Thread Gerd Hoffmann

Signed-off-by: Gerd Hoffmann 
---
 hw/ne2000.c |   39 ---
 1 files changed, 32 insertions(+), 7 deletions(-)

diff --git a/hw/ne2000.c b/hw/ne2000.c
index 7ce56ff..41893b3 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -25,6 +25,7 @@
 #include "pci.h"
 #include "net.h"
 #include "ne2000.h"
+#include "loader.h"
 
 /* debug NE2000 card */
 //#define DEBUG_NE2000
@@ -738,7 +739,7 @@ static void ne2000_cleanup(VLANClientState *vc)
 {
 NE2000State *s = vc->opaque;
 
-unregister_savevm("ne2000", s);
+s->vc = NULL;
 }
 
 static int pci_ne2000_init(PCIDevice *pci_dev)
@@ -758,22 +759,46 @@ static int pci_ne2000_init(PCIDevice *pci_dev)
PCI_ADDRESS_SPACE_IO, ne2000_map);
 s = &d->ne2000;
 s->irq = d->dev.irq[0];
-qdev_get_macaddr(&d->dev.qdev, s->c.macaddr.a);
+
+qemu_macaddr_default_if_unset(&s->c.macaddr);
 ne2000_reset(s);
-s->vc = qdev_get_vlan_client(&d->dev.qdev,
+s->vc = qemu_new_vlan_client(s->c.vlan, s->c.peer,
+ pci_dev->qdev.info->name, pci_dev->qdev.id,
  ne2000_can_receive, ne2000_receive, NULL,
  ne2000_cleanup, s);
-
 qemu_format_nic_info_str(s->vc, s->c.macaddr.a);
 
+if (!pci_dev->qdev.hotplugged) {
+static int loaded = 0;
+if (!loaded) {
+rom_add_option("pxe-ne2k_pci.bin");
+loaded = 1;
+}
+}
+
 register_savevm("ne2000", -1, 3, pci_ne2000_save, pci_ne2000_load, d);
 return 0;
 }
 
+static int pci_ne2000_exit(PCIDevice *pci_dev)
+{
+PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev);
+NE2000State *s = &d->ne2000;
+
+unregister_savevm("ne2000", s);
+qemu_del_vlan_client(s->vc);
+return 0;
+}
+
 static PCIDeviceInfo ne2000_info = {
-.qdev.name = "ne2k_pci",
-.qdev.size = sizeof(PCINE2000State),
-.init  = pci_ne2000_init,
+.qdev.name  = "ne2k_pci",
+.qdev.size  = sizeof(PCINE2000State),
+.init   = pci_ne2000_init,
+.exit   = pci_ne2000_exit,
+.qdev.props = (Property[]) {
+DEFINE_NIC_PROPERTIES(PCINE2000State, ne2000.c),
+DEFINE_PROP_END_OF_LIST(),
+}
 };
 
 static void ne2000_register_devices(void)
-- 
1.6.2.5





[Qemu-devel] [PATCH 06/22] ne2k_isa: use qdev properties for configuration.

2009-10-21 Thread Gerd Hoffmann

Signed-off-by: Gerd Hoffmann 
---
 hw/ne2000-isa.c |   17 +++--
 hw/ne2000.c |6 +++---
 hw/ne2000.h |2 +-
 3 files changed, 11 insertions(+), 14 deletions(-)

diff --git a/hw/ne2000-isa.c b/hw/ne2000-isa.c
index e346731..1da0d54 100644
--- a/hw/ne2000-isa.c
+++ b/hw/ne2000-isa.c
@@ -38,13 +38,8 @@ typedef struct ISANE2000State {
 static void isa_ne2000_cleanup(VLANClientState *vc)
 {
 NE2000State *s = vc->opaque;
-ISANE2000State *isa = container_of(s, ISANE2000State, ne2000);
 
-unregister_savevm("ne2000", s);
-
-isa_unassign_ioport(isa->iobase, 16);
-isa_unassign_ioport(isa->iobase + 0x10, 2);
-isa_unassign_ioport(isa->iobase + 0x1f, 1);
+s->vc = NULL;
 }
 
 static int isa_ne2000_initfn(ISADevice *dev)
@@ -65,13 +60,14 @@ static int isa_ne2000_initfn(ISADevice *dev)
 
 isa_init_irq(dev, &s->irq, isa->isairq);
 
-qdev_get_macaddr(&dev->qdev, s->macaddr);
+qemu_macaddr_default_if_unset(&s->c.macaddr);
 ne2000_reset(s);
 
-s->vc = qdev_get_vlan_client(&dev->qdev,
+s->vc = qemu_new_vlan_client(s->c.vlan, s->c.peer,
+ dev->qdev.info->name, dev->qdev.id,
  ne2000_can_receive, ne2000_receive, NULL,
  isa_ne2000_cleanup, s);
-qemu_format_nic_info_str(s->vc, s->macaddr);
+qemu_format_nic_info_str(s->vc, s->c.macaddr.a);
 
 register_savevm("ne2000", -1, 2, ne2000_save, ne2000_load, s);
 return 0;
@@ -84,9 +80,9 @@ void isa_ne2000_init(int base, int irq, NICInfo *nd)
 qemu_check_nic_model(nd, "ne2k_isa");
 
 dev = isa_create("ne2k_isa");
-dev->qdev.nd = nd; /* hack alert */
 qdev_prop_set_uint32(&dev->qdev, "iobase", base);
 qdev_prop_set_uint32(&dev->qdev, "irq",irq);
+qdev_set_nic_properties(&dev->qdev, nd);
 qdev_init_nofail(&dev->qdev);
 }
 
@@ -97,6 +93,7 @@ static ISADeviceInfo ne2000_isa_info = {
 .qdev.props = (Property[]) {
 DEFINE_PROP_HEX32("iobase", ISANE2000State, iobase, 0x300),
 DEFINE_PROP_UINT32("irq",   ISANE2000State, isairq, 9),
+DEFINE_NIC_PROPERTIES(ISANE2000State, ne2000.c),
 DEFINE_PROP_END_OF_LIST(),
 },
 };
diff --git a/hw/ne2000.c b/hw/ne2000.c
index 87f1e59..7ce56ff 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -126,7 +126,7 @@ void ne2000_reset(NE2000State *s)
 int i;
 
 s->isr = ENISR_RESET;
-memcpy(s->mem, s->macaddr, 6);
+memcpy(s->mem, &s->c.macaddr, 6);
 s->mem[14] = 0x57;
 s->mem[15] = 0x57;
 
@@ -758,13 +758,13 @@ static int pci_ne2000_init(PCIDevice *pci_dev)
PCI_ADDRESS_SPACE_IO, ne2000_map);
 s = &d->ne2000;
 s->irq = d->dev.irq[0];
-qdev_get_macaddr(&d->dev.qdev, s->macaddr);
+qdev_get_macaddr(&d->dev.qdev, s->c.macaddr.a);
 ne2000_reset(s);
 s->vc = qdev_get_vlan_client(&d->dev.qdev,
  ne2000_can_receive, ne2000_receive, NULL,
  ne2000_cleanup, s);
 
-qemu_format_nic_info_str(s->vc, s->macaddr);
+qemu_format_nic_info_str(s->vc, s->c.macaddr.a);
 
 register_savevm("ne2000", -1, 3, pci_ne2000_save, pci_ne2000_load, d);
 return 0;
diff --git a/hw/ne2000.h b/hw/ne2000.h
index 92a2ddb..7842246 100644
--- a/hw/ne2000.h
+++ b/hw/ne2000.h
@@ -23,7 +23,7 @@ typedef struct NE2000State {
 uint8_t mult[8]; /* multicast mask array */
 qemu_irq irq;
 VLANClientState *vc;
-uint8_t macaddr[6];
+NICConf c;
 uint8_t mem[NE2000_MEM_SIZE];
 } NE2000State;
 
-- 
1.6.2.5





[Qemu-devel] [PATCH 11/22] pcnet: use qdev properties for configuration.

2009-10-21 Thread Gerd Hoffmann

Signed-off-by: Gerd Hoffmann 
---
 hw/pcnet.c |   64 +---
 hw/sun4m.c |2 +-
 2 files changed, 49 insertions(+), 17 deletions(-)

diff --git a/hw/pcnet.c b/hw/pcnet.c
index fecbff7..45ca6f3 100644
--- a/hw/pcnet.c
+++ b/hw/pcnet.c
@@ -38,6 +38,7 @@
 #include "sysbus.h"
 #include "pci.h"
 #include "net.h"
+#include "loader.h"
 #include "qemu-timer.h"
 #include "qemu_socket.h"
 
@@ -61,7 +62,7 @@ typedef struct PCNetState_st PCNetState;
 
 struct PCNetState_st {
 VLANClientState *vc;
-uint8_t macaddr[6];
+NICConf conf;
 QEMUTimer *poll_timer;
 int rap, isr, lnkst;
 uint32_t rdra, tdra;
@@ -1601,7 +1602,7 @@ static void pcnet_h_reset(void *opaque)
 
 /* Initialize the PROM */
 
-memcpy(s->prom, s->macaddr, 6);
+memcpy(s->prom, s->conf.macaddr.a, 6);
 s->prom[12] = s->prom[13] = 0x00;
 s->prom[14] = s->prom[15] = 0x57;
 
@@ -1953,22 +1954,20 @@ static int pci_pcnet_load(QEMUFile *f, void *opaque, 
int version_id)
 
 static void pcnet_common_cleanup(PCNetState *d)
 {
-unregister_savevm("pcnet", d);
-
-qemu_del_timer(d->poll_timer);
-qemu_free_timer(d->poll_timer);
+d->vc = NULL;
 }
 
 static int pcnet_common_init(DeviceState *dev, PCNetState *s,
-  NetCleanup *cleanup)
+ NetCleanup *cleanup)
 {
 s->poll_timer = qemu_new_timer(vm_clock, pcnet_poll_timer, s);
 
-qdev_get_macaddr(dev, s->macaddr);
-s->vc = qdev_get_vlan_client(dev,
+qemu_macaddr_default_if_unset(&s->conf.macaddr);
+s->vc = qemu_new_vlan_client(s->conf.vlan, s->conf.peer,
+ dev->info->name, dev->id,
  pcnet_can_receive, pcnet_receive, NULL,
  cleanup, s);
-qemu_register_reset(pcnet_h_reset, s);
+qemu_format_nic_info_str(s->vc, s->conf.macaddr.a);
 pcnet_h_reset(s);
 return 0;
 }
@@ -2023,7 +2022,10 @@ static int pci_pcnet_uninit(PCIDevice *dev)
 PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, dev);
 
 cpu_unregister_io_memory(d->state.mmio_index);
-
+unregister_savevm("pcnet", d);
+qemu_del_timer(d->state.poll_timer);
+qemu_free_timer(d->state.poll_timer);
+qemu_del_vlan_client(d->state.vc);
 return 0;
 }
 
@@ -2071,9 +2073,25 @@ static int pci_pcnet_init(PCIDevice *pci_dev)
 s->phys_mem_write = pci_physical_memory_write;
 
 register_savevm("pcnet", -1, 3, pci_pcnet_save, pci_pcnet_load, d);
+
+if (!pci_dev->qdev.hotplugged) {
+static int loaded = 0;
+if (!loaded) {
+rom_add_option("pxe-pcnet.bin");
+loaded = 1;
+}
+}
+
 return pcnet_common_init(&pci_dev->qdev, s, pci_pcnet_cleanup);
 }
 
+static void pci_reset(DeviceState *dev)
+{
+PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev.qdev, dev);
+
+pcnet_h_reset(&d->state);
+}
+
 /* SPARC32 interface */
 
 #if defined (TARGET_SPARC) && !defined(TARGET_SPARC64) // Avoid compile failure
@@ -2151,12 +2169,21 @@ static int lance_init(SysBusDevice *dev)
 return pcnet_common_init(&dev->qdev, s, lance_cleanup);
 }
 
+static void lance_reset(DeviceState *dev)
+{
+SysBusPCNetState *d = DO_UPCAST(SysBusPCNetState, busdev.qdev, dev);
+
+pcnet_h_reset(&d->state);
+}
+
 static SysBusDeviceInfo lance_info = {
-.init = lance_init,
+.init   = lance_init,
 .qdev.name  = "lance",
 .qdev.size  = sizeof(SysBusPCNetState),
+.qdev.reset = lance_reset,
 .qdev.props = (Property[]) {
 DEFINE_PROP_PTR("dma", SysBusPCNetState, state.dma_opaque),
+DEFINE_NIC_PROPERTIES(SysBusPCNetState, state.conf),
 DEFINE_PROP_END_OF_LIST(),
 }
 };
@@ -2164,10 +2191,15 @@ static SysBusDeviceInfo lance_info = {
 #endif /* TARGET_SPARC */
 
 static PCIDeviceInfo pcnet_info = {
-.qdev.name = "pcnet",
-.qdev.size = sizeof(PCIPCNetState),
-.init  = pci_pcnet_init,
-.exit  = pci_pcnet_uninit,
+.qdev.name  = "pcnet",
+.qdev.size  = sizeof(PCIPCNetState),
+.qdev.reset = pci_reset,
+.init   = pci_pcnet_init,
+.exit   = pci_pcnet_uninit,
+.qdev.props = (Property[]) {
+DEFINE_NIC_PROPERTIES(PCIPCNetState, state.conf),
+DEFINE_PROP_END_OF_LIST(),
+}
 };
 
 static void pcnet_register_devices(void)
diff --git a/hw/sun4m.c b/hw/sun4m.c
index 21f609c..424cf6d 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -396,7 +396,7 @@ static void lance_init(NICInfo *nd, target_phys_addr_t 
leaddr,
 qemu_check_nic_model(&nd_table[0], "lance");
 
 dev = qdev_create(NULL, "lance");
-dev->nd = nd;
+qdev_set_nic_properties(dev, nd);
 qdev_prop_set_ptr(dev, "dma", dma_opaque);
 qdev_init_nofail(dev);
 s = sysbus_from_qdev(dev);
-- 
1.6.2.5





[Qemu-devel] [PATCH 10/22] e1000: use qdev properties for configuration.

2009-10-21 Thread Gerd Hoffmann

Signed-off-by: Gerd Hoffmann 
---
 hw/e1000.c |   46 --
 1 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/hw/e1000.c b/hw/e1000.c
index f123bda..301997b 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -25,6 +25,7 @@
 #include "hw.h"
 #include "pci.h"
 #include "net.h"
+#include "loader.h"
 
 #include "e1000_hw.h"
 
@@ -74,6 +75,7 @@ enum {
 typedef struct E1000State_st {
 PCIDevice dev;
 VLANClientState *vc;
+NICConf conf;
 int mmio_index;
 
 uint32_t mac_reg[0x8000];
@@ -1056,7 +1058,7 @@ e1000_cleanup(VLANClientState *vc)
 {
 E1000State *d = vc->opaque;
 
-unregister_savevm("e1000", d);
+d->vc = NULL;
 }
 
 static int
@@ -1065,7 +1067,8 @@ pci_e1000_uninit(PCIDevice *dev)
 E1000State *d = DO_UPCAST(E1000State, dev, dev);
 
 cpu_unregister_io_memory(d->mmio_index);
-
+qemu_del_vlan_client(d->vc);
+unregister_savevm("e1000", d);
 return 0;
 }
 
@@ -1088,7 +1091,7 @@ static int pci_e1000_init(PCIDevice *pci_dev)
 uint16_t checksum = 0;
 static const char info_str[] = "e1000";
 int i;
-uint8_t macaddr[6];
+uint8_t *macaddr;
 
 pci_conf = d->dev.config;
 
@@ -1113,7 +1116,8 @@ static int pci_e1000_init(PCIDevice *pci_dev)
 
 memmove(d->eeprom_data, e1000_eeprom_template,
 sizeof e1000_eeprom_template);
-qdev_get_macaddr(&d->dev.qdev, macaddr);
+qemu_macaddr_default_if_unset(&d->conf.macaddr);
+macaddr = d->conf.macaddr.a;
 for (i = 0; i < 3; i++)
 d->eeprom_data[i] = (macaddr[2*i+1]<<8) | macaddr[2*i];
 for (i = 0; i < EEPROM_CHECKSUM_REG; i++)
@@ -1121,7 +1125,8 @@ static int pci_e1000_init(PCIDevice *pci_dev)
 checksum = (uint16_t) EEPROM_SUM - checksum;
 d->eeprom_data[EEPROM_CHECKSUM_REG] = checksum;
 
-d->vc = qdev_get_vlan_client(&d->dev.qdev,
+d->vc = qemu_new_vlan_client(d->conf.vlan, d->conf.peer,
+ d->dev.qdev.info->name, d->dev.qdev.id,
  e1000_can_receive, e1000_receive,
  NULL, e1000_cleanup, d);
 d->vc->link_status_changed = e1000_set_link_status;
@@ -1129,16 +1134,37 @@ static int pci_e1000_init(PCIDevice *pci_dev)
 qemu_format_nic_info_str(d->vc, macaddr);
 
 register_savevm(info_str, -1, 2, nic_save, nic_load, d);
-qemu_register_reset(e1000_reset, d);
 e1000_reset(d);
+
+#if 0 /* rom bev support is broken -> can't load unconditionally */
+if (!pci_dev->qdev.hotplugged) {
+static int loaded = 0;
+if (!loaded) {
+rom_add_option("pxe-e1000.bin");
+loaded = 1;
+}
+}
+#endif
 return 0;
 }
 
+static void qdev_e1000_reset(DeviceState *dev)
+{
+E1000State *d = DO_UPCAST(E1000State, dev.qdev, dev);
+e1000_reset(d);
+}
+
 static PCIDeviceInfo e1000_info = {
-.qdev.name = "e1000",
-.qdev.size = sizeof(E1000State),
-.init  = pci_e1000_init,
-.exit  = pci_e1000_uninit,
+.qdev.name  = "e1000",
+.qdev.desc  = "Intel Gigabit Ethernet",
+.qdev.size  = sizeof(E1000State),
+.qdev.reset = qdev_e1000_reset,
+.init   = pci_e1000_init,
+.exit   = pci_e1000_uninit,
+.qdev.props = (Property[]) {
+DEFINE_NIC_PROPERTIES(E1000State, conf),
+DEFINE_PROP_END_OF_LIST(),
+}
 };
 
 static void e1000_register_devices(void)
-- 
1.6.2.5





[Qemu-devel] [PATCH 13/22] rtl8139: use qdev properties for configuration.

2009-10-21 Thread Gerd Hoffmann

Signed-off-by: Gerd Hoffmann 
---
 hw/rtl8139.c |   54 +-
 1 files changed, 33 insertions(+), 21 deletions(-)

diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index 10daeb2..de60246 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -47,6 +47,7 @@
 #include "pci.h"
 #include "qemu-timer.h"
 #include "net.h"
+#include "loader.h"
 
 /* debug RTL8139 card */
 //#define DEBUG_RTL8139 1
@@ -465,7 +466,7 @@ typedef struct RTL8139State {
 uint8_t  TxThresh;
 
 VLANClientState *vc;
-uint8_t macaddr[6];
+NICConf conf;
 int rtl8139_mmio_io_addr;
 
 /* C ring mode */
@@ -1179,7 +1180,7 @@ static void rtl8139_reset(DeviceState *d)
 int i;
 
 /* restore MAC address */
-memcpy(s->phys, s->macaddr, 6);
+memcpy(s->phys, s->conf.macaddr.a, 6);
 
 /* reset interrupt mask */
 s->IntrStatus = 0;
@@ -1195,9 +1196,9 @@ static void rtl8139_reset(DeviceState *d)
 s->eeprom.contents[2] = PCI_DEVICE_ID_REALTEK_8139;
 #endif
 
-s->eeprom.contents[7] = s->macaddr[0] | s->macaddr[1] << 8;
-s->eeprom.contents[8] = s->macaddr[2] | s->macaddr[3] << 8;
-s->eeprom.contents[9] = s->macaddr[4] | s->macaddr[5] << 8;
+s->eeprom.contents[7] = s->conf.macaddr.a[0] | s->conf.macaddr.a[1] << 8;
+s->eeprom.contents[8] = s->conf.macaddr.a[2] | s->conf.macaddr.a[3] << 8;
+s->eeprom.contents[9] = s->conf.macaddr.a[4] | s->conf.macaddr.a[5] << 8;
 
 /* mark all status registers as owned by host */
 for (i = 0; i < 4; ++i)
@@ -3171,7 +3172,7 @@ static void rtl8139_save(QEMUFile* f,void* opaque)
 
 i = 0;
 qemu_put_be32s(f, &i); /* unused.  */
-qemu_put_buffer(f, s->macaddr, 6);
+qemu_put_buffer(f, s->conf.macaddr.a, 6);
 qemu_put_be32(f, s->rtl8139_mmio_io_addr);
 
 qemu_put_be32s(f, &s->currTxDesc);
@@ -3268,7 +3269,7 @@ static int rtl8139_load(QEMUFile* f,void* opaque,int 
version_id)
 qemu_get_8s(f, &s->TxThresh);
 
 qemu_get_be32s(f, &i); /* unused.  */
-qemu_get_buffer(f, s->macaddr, 6);
+qemu_get_buffer(f, s->conf.macaddr.a, 6);
 s->rtl8139_mmio_io_addr=qemu_get_be32(f);
 
 qemu_get_be32s(f, &s->currTxDesc);
@@ -3416,25 +3417,24 @@ static void rtl8139_cleanup(VLANClientState *vc)
 {
 RTL8139State *s = vc->opaque;
 
+s->vc = NULL;
+}
+
+static int pci_rtl8139_uninit(PCIDevice *dev)
+{
+RTL8139State *s = DO_UPCAST(RTL8139State, dev, dev);
+
+cpu_unregister_io_memory(s->rtl8139_mmio_io_addr);
 if (s->cplus_txbuffer) {
 qemu_free(s->cplus_txbuffer);
 s->cplus_txbuffer = NULL;
 }
-
 #ifdef RTL8139_ONBOARD_TIMER
 qemu_del_timer(s->timer);
 qemu_free_timer(s->timer);
 #endif
-
 unregister_savevm("rtl8139", s);
-}
-
-static int pci_rtl8139_uninit(PCIDevice *dev)
-{
-RTL8139State *s = DO_UPCAST(RTL8139State, dev, dev);
-
-cpu_unregister_io_memory(s->rtl8139_mmio_io_addr);
-
+qemu_del_vlan_client(s->vc);
 return 0;
 }
 
@@ -3463,13 +3463,13 @@ static int pci_rtl8139_init(PCIDevice *dev)
 pci_register_bar(&s->dev, 1, 0x100,
PCI_ADDRESS_SPACE_MEM, rtl8139_mmio_map);
 
-qdev_get_macaddr(&dev->qdev, s->macaddr);
+qemu_macaddr_default_if_unset(&s->conf.macaddr);
 rtl8139_reset(&s->dev.qdev);
-s->vc = qdev_get_vlan_client(&dev->qdev,
+s->vc = qemu_new_vlan_client(s->conf.vlan, s->conf.peer,
+ dev->qdev.info->name, dev->qdev.id,
  rtl8139_can_receive, rtl8139_receive, NULL,
  rtl8139_cleanup, s);
-
-qemu_format_nic_info_str(s->vc, s->macaddr);
+qemu_format_nic_info_str(s->vc, s->conf.macaddr.a);
 
 s->cplus_txbuffer = NULL;
 s->cplus_txbuffer_len = 0;
@@ -3483,6 +3483,14 @@ static int pci_rtl8139_init(PCIDevice *dev)
 qemu_mod_timer(s->timer,
 rtl8139_get_next_tctr_time(s,qemu_get_clock(vm_clock)));
 #endif /* RTL8139_ONBOARD_TIMER */
+
+if (!dev->qdev.hotplugged) {
+static int loaded = 0;
+if (!loaded) {
+rom_add_option("pxe-rtl8139.bin");
+loaded = 1;
+}
+}
 return 0;
 }
 
@@ -3492,6 +3500,10 @@ static PCIDeviceInfo rtl8139_info = {
 .qdev.reset = rtl8139_reset,
 .init   = pci_rtl8139_init,
 .exit   = pci_rtl8139_uninit,
+.qdev.props = (Property[]) {
+DEFINE_NIC_PROPERTIES(RTL8139State, conf),
+DEFINE_PROP_END_OF_LIST(),
+}
 };
 
 static void rtl8139_register_devices(void)
-- 
1.6.2.5





[Qemu-devel] [PATCH 14/22] virtio: use qdev properties for configuration.

2009-10-21 Thread Gerd Hoffmann

Signed-off-by: Gerd Hoffmann 
---
 hw/qdev.c  |4 
 hw/syborg.c|4 ++--
 hw/syborg_virtio.c |   16 +---
 hw/virtio-net.c|   43 ---
 hw/virtio-pci.c|   33 +++--
 hw/virtio.h|5 -
 6 files changed, 70 insertions(+), 35 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index b32dbfc..e81d662 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -390,6 +390,10 @@ void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
 qdev_prop_set_vlan(dev, "vlan", nd->vlan);
 if (nd->netdev)
 qdev_prop_set_netdev(dev, "netdev", nd->netdev);
+if (nd->nvectors != NIC_NVECTORS_UNSPECIFIED &&
+qdev_prop_exists(dev, "vectors")) {
+qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
+}
 }
 
 static int next_block_unit[IF_COUNT];
diff --git a/hw/syborg.c b/hw/syborg.c
index 2aec769..2d08cb2 100644
--- a/hw/syborg.c
+++ b/hw/syborg.c
@@ -77,13 +77,13 @@ static void syborg_init(ram_addr_t ram_size,
 sysbus_create_simple("syborg,serial", 0xC0008000, pic[7]);
 sysbus_create_simple("syborg,serial", 0xC0009000, pic[8]);
 
-if (nd_table[0].vlan) {
+if (nd_table[0].vlan || nd_table[0].netdev) {
 DeviceState *dev;
 SysBusDevice *s;
 
 qemu_check_nic_model(&nd_table[0], "virtio");
 dev = qdev_create(NULL, "syborg,virtio-net");
-dev->nd = &nd_table[0];
+qdev_set_nic_properties(dev, &nd_table[0]);
 qdev_init_nofail(dev);
 s = sysbus_from_qdev(dev);
 sysbus_mmio_map(s, 0, 0xc000c000);
diff --git a/hw/syborg_virtio.c b/hw/syborg_virtio.c
index c1faf3d..6cf5a15 100644
--- a/hw/syborg_virtio.c
+++ b/hw/syborg_virtio.c
@@ -65,6 +65,7 @@ typedef struct {
 qemu_irq irq;
 uint32_t int_enable;
 uint32_t id;
+NICConf nic;
 } SyborgVirtIOProxy;
 
 static uint32_t syborg_virtio_readl(void *opaque, target_phys_addr_t offset)
@@ -273,14 +274,23 @@ static int syborg_virtio_net_init(SysBusDevice *dev)
 VirtIODevice *vdev;
 SyborgVirtIOProxy *proxy = FROM_SYSBUS(SyborgVirtIOProxy, dev);
 
-vdev = virtio_net_init(&dev->qdev);
+vdev = virtio_net_init(&dev->qdev, &proxy->nic);
 return syborg_virtio_init(proxy, vdev);
 }
 
+static SysBusDeviceInfo syborg_virtio_net_info = {
+.init = syborg_virtio_net_init,
+.qdev.name  = "syborg,virtio-net",
+.qdev.size  = sizeof(SyborgVirtIOProxy),
+.qdev.props = (Property[]) {
+DEFINE_NIC_PROPERTIES(SyborgVirtIOProxy, nic),
+DEFINE_PROP_END_OF_LIST(),
+}
+};
+
 static void syborg_virtio_register_devices(void)
 {
-sysbus_register_dev("syborg,virtio-net", sizeof(SyborgVirtIOProxy),
-syborg_virtio_net_init);
+sysbus_register_withprop(&syborg_virtio_net_info);
 }
 
 device_init(syborg_virtio_register_devices)
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 218f985..f187461 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -700,20 +700,10 @@ static void virtio_net_cleanup(VLANClientState *vc)
 {
 VirtIONet *n = vc->opaque;
 
-qemu_purge_queued_packets(vc);
-
-unregister_savevm("virtio-net", n);
-
-qemu_free(n->mac_table.macs);
-qemu_free(n->vlans);
-
-qemu_del_timer(n->tx_timer);
-qemu_free_timer(n->tx_timer);
-
-virtio_cleanup(&n->vdev);
+n->vc = NULL;
 }
 
-VirtIODevice *virtio_net_init(DeviceState *dev)
+VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf)
 {
 VirtIONet *n;
 static int virtio_net_id;
@@ -731,15 +721,16 @@ VirtIODevice *virtio_net_init(DeviceState *dev)
 n->rx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_rx);
 n->tx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_tx);
 n->ctrl_vq = virtio_add_queue(&n->vdev, 64, virtio_net_handle_ctrl);
-qdev_get_macaddr(dev, n->mac);
+qemu_macaddr_default_if_unset(&conf->macaddr);
 n->status = VIRTIO_NET_S_LINK_UP;
-n->vc = qdev_get_vlan_client(dev,
+n->vc = qemu_new_vlan_client(conf->vlan, conf->peer,
+ dev->info->name, dev->id,
  virtio_net_can_receive,
  virtio_net_receive, NULL,
  virtio_net_cleanup, n);
 n->vc->link_status_changed = virtio_net_set_link_status;
 
-qemu_format_nic_info_str(n->vc, n->mac);
+qemu_format_nic_info_str(n->vc, conf->macaddr.a);
 
 n->tx_timer = qemu_new_timer(vm_clock, virtio_net_tx_timer, n);
 n->tx_timer_active = 0;
@@ -749,13 +740,27 @@ VirtIODevice *virtio_net_init(DeviceState *dev)
 n->mac_table.macs = qemu_mallocz(MAC_TABLE_ENTRIES * ETH_ALEN);
 
 n->vlans = qemu_mallocz(MAX_VLAN >> 3);
-if (dev->nd->nvectors == NIC_NVECTORS_UNSPECIFIED)
-n->vdev.nvectors = 3;
-else
-n->vdev.nvectors = dev->nd->nvectors;
 
 register_savevm("virtio-net", virtio_net_id++, VIRTIO_NET_VM_VERSION,
 virtio

[Qemu-devel] [PATCH 12/22] pcnet: split away lance.c (sparc32 code).

2009-10-21 Thread Gerd Hoffmann

Signed-off-by: Gerd Hoffmann 
---
 Makefile.target |2 +-
 hw/lance.c  |  146 
 hw/pcnet.c  |  154 +++---
 hw/pcnet.h  |   39 ++
 4 files changed, 195 insertions(+), 146 deletions(-)
 create mode 100644 hw/lance.c
 create mode 100644 hw/pcnet.h

diff --git a/Makefile.target b/Makefile.target
index 8d146c5..1d6bad8 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -260,7 +260,7 @@ obj-sparc-y += vga.o vga-pci.o
 obj-sparc-y += fdc.o mc146818rtc.o serial.o
 obj-sparc-y += cirrus_vga.o parallel.o
 else
-obj-sparc-y = sun4m.o tcx.o iommu.o slavio_intctl.o
+obj-sparc-y = sun4m.o lance.o tcx.o iommu.o slavio_intctl.o
 obj-sparc-y += slavio_timer.o slavio_misc.o fdc.o sparc32_dma.o
 obj-sparc-y += cs4231.o eccmemctl.o sbi.o sun4c_intctl.o
 endif
diff --git a/hw/lance.c b/hw/lance.c
new file mode 100644
index 000..99c25a8
--- /dev/null
+++ b/hw/lance.c
@@ -0,0 +1,146 @@
+/*
+ * QEMU AMD PC-Net II (Am79C970A) emulation
+ *
+ * Copyright (c) 2004 Antony T Curtis
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* This software was written to be compatible with the specification:
+ * AMD Am79C970A PCnet-PCI II Ethernet Controller Data-Sheet
+ * AMD Publication# 19436  Rev:E  Amendment/0  Issue Date: June 2000
+ */
+
+/*
+ * On Sparc32, this is the Lance (Am7990) part of chip STP2000 (Master I/O), 
also
+ * produced as NCR89C100. See
+ * 
http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C100.txt
+ * and
+ * 
http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR92C990.txt
+ */
+
+#include "sysbus.h"
+#include "net.h"
+#include "qemu-timer.h"
+#include "qemu_socket.h"
+#include "sun4m.h"
+
+#include "pcnet.h"
+
+typedef struct {
+SysBusDevice busdev;
+PCNetState state;
+} SysBusPCNetState;
+
+static void parent_lance_reset(void *opaque, int irq, int level)
+{
+SysBusPCNetState *d = opaque;
+if (level)
+pcnet_h_reset(&d->state);
+}
+
+static void lance_mem_writew(void *opaque, target_phys_addr_t addr,
+ uint32_t val)
+{
+SysBusPCNetState *d = opaque;
+#ifdef PCNET_DEBUG_IO
+printf("lance_mem_writew addr=" TARGET_FMT_plx " val=0x%04x\n", addr,
+   val & 0x);
+#endif
+pcnet_ioport_writew(&d->state, addr, val & 0x);
+}
+
+static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr)
+{
+SysBusPCNetState *d = opaque;
+uint32_t val;
+
+val = pcnet_ioport_readw(&d->state, addr);
+#ifdef PCNET_DEBUG_IO
+printf("lance_mem_readw addr=" TARGET_FMT_plx " val = 0x%04x\n", addr,
+   val & 0x);
+#endif
+
+return val & 0x;
+}
+
+static CPUReadMemoryFunc * const lance_mem_read[3] = {
+NULL,
+lance_mem_readw,
+NULL,
+};
+
+static CPUWriteMemoryFunc * const lance_mem_write[3] = {
+NULL,
+lance_mem_writew,
+NULL,
+};
+
+static void lance_cleanup(VLANClientState *vc)
+{
+PCNetState *d = vc->opaque;
+
+pcnet_common_cleanup(d);
+}
+
+static int lance_init(SysBusDevice *dev)
+{
+SysBusPCNetState *d = FROM_SYSBUS(SysBusPCNetState, dev);
+PCNetState *s = &d->state;
+
+s->mmio_index =
+cpu_register_io_memory(lance_mem_read, lance_mem_write, d);
+
+qdev_init_gpio_in(&dev->qdev, parent_lance_reset, 1);
+
+sysbus_init_mmio(dev, 4, s->mmio_index);
+
+sysbus_init_irq(dev, &s->irq);
+
+s->phys_mem_read = ledma_memory_read;
+s->phys_mem_write = ledma_memory_write;
+
+register_savevm("pcnet", -1, 3, pcnet_save, pcnet_load, s);
+return pcnet_common_init(&dev->qdev, s, lance_cleanup);
+}
+
+static void lance_reset(DeviceState *dev)
+{
+SysBusPCNetState *d = DO_UPCAST(SysBusPCNetState, busdev.qdev, dev);
+
+pcnet_h_reset(&d->state);
+}
+
+static SysBusDeviceInfo lance_info = {
+.init   = lance_init,
+.qdev.name  = "lance",
+.qdev.si

[Qemu-devel] [PATCH 19/22] musicpal: use qdev properties for configuration.

2009-10-21 Thread Gerd Hoffmann

Signed-off-by: Gerd Hoffmann 
---
 hw/musicpal.c |   14 +-
 1 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/hw/musicpal.c b/hw/musicpal.c
index 02d4c70..cb1ac6d 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -152,6 +152,7 @@ typedef struct mv88w8618_eth_state {
 uint32_t frx_queue[4];
 uint32_t cur_rx[4];
 VLANClientState *vc;
+NICConf conf;
 } mv88w8618_eth_state;
 
 static void eth_rx_desc_put(uint32_t addr, mv88w8618_rx_desc *desc)
@@ -368,9 +369,7 @@ static void eth_cleanup(VLANClientState *vc)
 {
 mv88w8618_eth_state *s = vc->opaque;
 
-cpu_unregister_io_memory(s->mmio_index);
-
-qemu_free(s);
+s->vc = NULL;
 }
 
 static int mv88w8618_eth_init(SysBusDevice *dev)
@@ -378,7 +377,8 @@ static int mv88w8618_eth_init(SysBusDevice *dev)
 mv88w8618_eth_state *s = FROM_SYSBUS(mv88w8618_eth_state, dev);
 
 sysbus_init_irq(dev, &s->irq);
-s->vc = qdev_get_vlan_client(&dev->qdev,
+s->vc = qemu_new_vlan_client(s->conf.vlan, s->conf.peer,
+ dev->qdev.info->name, dev->qdev.id,
  eth_can_receive, eth_receive, NULL,
  eth_cleanup, s);
 s->mmio_index = cpu_register_io_memory(mv88w8618_eth_readfn,
@@ -410,6 +410,10 @@ static SysBusDeviceInfo mv88w8618_eth_info = {
 .qdev.name = "mv88w8618_eth",
 .qdev.size = sizeof(mv88w8618_eth_state),
 .qdev.vmsd = &mv88w8618_eth_vmsd,
+.qdev.props = (Property[]) {
+DEFINE_NIC_PROPERTIES(mv88w8618_eth_state, conf),
+DEFINE_PROP_END_OF_LIST(),
+},
 };
 
 /* LCD register offsets */
@@ -1550,7 +1554,7 @@ static void musicpal_init(ram_addr_t ram_size,
 
 qemu_check_nic_model(&nd_table[0], "mv88w8618");
 dev = qdev_create(NULL, "mv88w8618_eth");
-dev->nd = &nd_table[0];
+qdev_set_nic_properties(dev, &nd_table[0]);
 qdev_init_nofail(dev);
 sysbus_mmio_map(sysbus_from_qdev(dev), 0, MP_ETH_BASE);
 sysbus_connect_irq(sysbus_from_qdev(dev), 0, pic[MP_ETH_IRQ]);
-- 
1.6.2.5





[Qemu-devel] [PATCH 21/22] kill dead nic unplug code.

2009-10-21 Thread Gerd Hoffmann
Cleanup on unplug happens via qdev->exit() callback now.

Signed-off-by: Gerd Hoffmann 
---
 hw/acpi.c   |3 ---
 hw/device-hotplug.c |   16 
 hw/pci-hotplug.c|   25 -
 sysemu.h|4 
 4 files changed, 0 insertions(+), 48 deletions(-)

diff --git a/hw/acpi.c b/hw/acpi.c
index d73aee9..dcc2c86 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -702,9 +702,6 @@ static void pciej_write(void *opaque, uint32_t addr, 
uint32_t val)
 QLIST_FOREACH_SAFE(qdev, &bus->children, sibling, next) {
 dev = DO_UPCAST(PCIDevice, qdev, qdev);
 if (PCI_SLOT(dev->devfn) == slot) {
-#if defined (TARGET_I386)
-pci_device_hot_remove_success(dev);
-#endif
 qdev_free(qdev);
 }
 }
diff --git a/hw/device-hotplug.c b/hw/device-hotplug.c
index c0cfd31..9cc8376 100644
--- a/hw/device-hotplug.c
+++ b/hw/device-hotplug.c
@@ -46,19 +46,3 @@ DriveInfo *add_init_drive(const char *optstr)
 
 return dinfo;
 }
-
-void destroy_nic(dev_match_fn *match_fn, void *arg)
-{
-int i;
-NICInfo *nic;
-
-for (i = 0; i < MAX_NICS; i++) {
-nic = &nd_table[i];
-if (nic->used) {
-if (nic->private && match_fn(nic->private, arg)) {
-qemu_del_vlan_client(nic->vc);
-net_client_uninit(nic);
-}
-}
-}
-}
diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c
index 35fa290..4673b89 100644
--- a/hw/pci-hotplug.c
+++ b/hw/pci-hotplug.c
@@ -234,28 +234,3 @@ void do_pci_device_hot_remove(Monitor *mon, const QDict 
*qdict)
 {
 pci_device_hot_remove(mon, qdict_get_str(qdict, "pci_addr"));
 }
-
-static int pci_match_fn(void *dev_private, void *arg)
-{
-PCIDevice *dev = dev_private;
-PCIDevice *match = arg;
-
-return (dev == match);
-}
-
-/*
- * OS has executed _EJ0 method, we now can remove the device
- */
-void pci_device_hot_remove_success(PCIDevice *d)
-{
-int class_code;
-
-class_code = d->config_read(d, PCI_CLASS_DEVICE+1, 1);
-
-switch(class_code) {
-case PCI_BASE_CLASS_NETWORK:
-destroy_nic(pci_match_fn, d);
-break;
-}
-}
-
diff --git a/sysemu.h b/sysemu.h
index 763861d..cda5848 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -202,17 +202,13 @@ extern DriveInfo *drive_init(QemuOpts *arg, void 
*machine, int *fatal_error);
 
 /* device-hotplug */
 
-typedef int (dev_match_fn)(void *dev_private, void *arg);
-
 DriveInfo *add_init_drive(const char *opts);
-void destroy_nic(dev_match_fn *match_fn, void *arg);
 
 /* pci-hotplug */
 void pci_device_hot_add(Monitor *mon, const QDict *qdict);
 void drive_hot_add(Monitor *mon, const QDict *qdict);
 void pci_device_hot_remove(Monitor *mon, const char *pci_addr);
 void do_pci_device_hot_remove(Monitor *mon, const QDict *qdict);
-void pci_device_hot_remove_success(PCIDevice *dev);
 
 /* serial ports */
 
-- 
1.6.2.5





[Qemu-devel] [PATCH 17/22] xilinx_ethlite: use qdev properties for configuration.

2009-10-21 Thread Gerd Hoffmann

Signed-off-by: Gerd Hoffmann 
---
 hw/xilinx.h |2 +-
 hw/xilinx_ethlite.c |   16 ++--
 2 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/hw/xilinx.h b/hw/xilinx.h
index 5e6aeea..705ff5b 100644
--- a/hw/xilinx.h
+++ b/hw/xilinx.h
@@ -40,7 +40,7 @@ xilinx_ethlite_create(NICInfo *nd, target_phys_addr_t base, 
qemu_irq irq,
 qemu_check_nic_model(nd, "xilinx-ethlite");
 
 dev = qdev_create(NULL, "xilinx,ethlite");
-dev->nd = nd;
+qdev_set_nic_properties(dev, nd);
 qdev_prop_set_uint32(dev, "txpingpong", txpingpong);
 qdev_prop_set_uint32(dev, "rxpingpong", rxpingpong);
 qdev_init_nofail(dev);
diff --git a/hw/xilinx_ethlite.c b/hw/xilinx_ethlite.c
index 9b0074c..994e0e2 100644
--- a/hw/xilinx_ethlite.c
+++ b/hw/xilinx_ethlite.c
@@ -52,13 +52,13 @@ struct xlx_ethlite
 SysBusDevice busdev;
 qemu_irq irq;
 VLANClientState *vc;
+NICConf conf;
 
 uint32_t c_tx_pingpong;
 uint32_t c_rx_pingpong;
 unsigned int txbuf;
 unsigned int rxbuf;
 
-uint8_t macaddr[6];
 uint32_t regs[R_MAX];
 };
 
@@ -125,7 +125,7 @@ eth_writel (void *opaque, target_phys_addr_t addr, uint32_t 
value)
 if (s->regs[base + R_TX_CTRL0] & CTRL_I)
 eth_pulse_irq(s);
 } else if ((value & (CTRL_P | CTRL_S)) == (CTRL_P | CTRL_S)) {
-memcpy(&s->macaddr[0], &s->regs[base], 6);
+memcpy(&s->conf.macaddr.a[0], &s->regs[base], 6);
 if (s->regs[base + R_TX_CTRL0] & CTRL_I)
 eth_pulse_irq(s);
 }
@@ -175,7 +175,7 @@ static ssize_t eth_rx(VLANClientState *vc, const uint8_t 
*buf, size_t size)
 int i;
 
 /* DA filter.  */
-if (!(buf[0] & 0x80) && memcmp(&s->macaddr[0], buf, 6))
+if (!(buf[0] & 0x80) && memcmp(&s->conf.macaddr.a[0], buf, 6))
 return size;
 
 if (s->regs[rxbase + R_RX_CTRL0] & CTRL_S) {
@@ -204,7 +204,8 @@ static ssize_t eth_rx(VLANClientState *vc, const uint8_t 
*buf, size_t size)
 static void eth_cleanup(VLANClientState *vc)
 {
 struct xlx_ethlite *s = vc->opaque;
-qemu_free(s);
+
+s->vc = NULL;
 }
 
 static int xilinx_ethlite_init(SysBusDevice *dev)
@@ -218,9 +219,11 @@ static int xilinx_ethlite_init(SysBusDevice *dev)
 regs = cpu_register_io_memory(eth_read, eth_write, s);
 sysbus_init_mmio(dev, R_MAX * 4, regs);
 
-qdev_get_macaddr(&dev->qdev, s->macaddr);
-s->vc = qdev_get_vlan_client(&dev->qdev,
+qemu_macaddr_default_if_unset(&s->conf.macaddr);
+s->vc = qemu_new_vlan_client(s->conf.vlan, s->conf.peer,
+ dev->qdev.info->name, dev->qdev.id,
  eth_can_rx, eth_rx, NULL, eth_cleanup, s);
+qemu_format_nic_info_str(s->vc, s->conf.macaddr.a);
 return 0;
 }
 
@@ -231,6 +234,7 @@ static SysBusDeviceInfo xilinx_ethlite_info = {
 .qdev.props = (Property[]) {
 DEFINE_PROP_UINT32("txpingpong", struct xlx_ethlite, c_tx_pingpong, 1),
 DEFINE_PROP_UINT32("rxpingpong", struct xlx_ethlite, c_rx_pingpong, 1),
+DEFINE_NIC_PROPERTIES(struct xlx_ethlite, conf),
 DEFINE_PROP_END_OF_LIST(),
 }
 };
-- 
1.6.2.5





[Qemu-devel] [PATCH 22/22] pc.c: only load e1000 rom.

2009-10-21 Thread Gerd Hoffmann
The other pxe roms are loaded by the drivers individual drivers now.

Signed-off-by: Gerd Hoffmann 
---
 hw/pc.c |9 -
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/hw/pc.c b/hw/pc.c
index 408d6d6..4cd8ec6 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -1163,6 +1163,11 @@ static void pc_init1(ram_addr_t ram_size,
 rom_add_option(option_rom[i]);
 }
 
+#if 1
+/*
+ * Needed for the e1000 rom only.  The rom doesn't do proper BEV
+ * and thus we can't load it unconditionally.
+ */
 for (i = 0; i < nb_nics; i++) {
 char nic_oprom[1024];
 const char *model = nd_table[i].model;
@@ -1172,10 +1177,12 @@ static void pc_init1(ram_addr_t ram_size,
 
 if (model == NULL)
 model = "e1000";
+if (strcmp(model,"e1000") != 0)
+continue;
 snprintf(nic_oprom, sizeof(nic_oprom), "pxe-%s.bin", model);
-
 rom_add_option(nic_oprom);
 }
+#endif
 
 cpu_irq = qemu_allocate_irqs(pic_irq_request, NULL, 1);
 i8259 = i8259_init(cpu_irq[0]);
-- 
1.6.2.5





[Qemu-devel] [PATCH 15/22] eepro100: use qdev properties for configuration.

2009-10-21 Thread Gerd Hoffmann

Signed-off-by: Gerd Hoffmann 
---
 hw/eepro100.c |   75 +++--
 1 files changed, 62 insertions(+), 13 deletions(-)

diff --git a/hw/eepro100.c b/hw/eepro100.c
index 62207da..277759f 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -194,11 +194,11 @@ typedef struct {
 uint8_t mult[8];/* multicast mask array */
 int mmio_index;
 VLANClientState *vc;
+NICConf conf;
 uint8_t scb_stat;   /* SCB stat/ack byte */
 uint8_t int_stat;   /* PCI interrupt status */
 /* region must not be saved by nic_save. */
 uint32_t region[3]; /* PCI region addresses */
-uint8_t macaddr[6];
 uint16_t mdimem[32];
 eeprom_t *eeprom;
 uint32_t device;/* device variant */
@@ -482,7 +482,7 @@ static void nic_selective_reset(EEPRO100State * s)
 size_t i;
 uint16_t *eeprom_contents = eeprom93xx_data(s->eeprom);
 //~ eeprom93xx_reset(s->eeprom);
-memcpy(eeprom_contents, s->macaddr, 6);
+memcpy(eeprom_contents, s->conf.macaddr.a, 6);
 eeprom_contents[0xa] = 0x4000;
 if (s->device == i82557B || s->device == i82557C)
 eeprom_contents[5] = 0x0100;
@@ -665,7 +665,7 @@ static void eepro100_cu_command(EEPRO100State * s, uint8_t 
val)
 /* Do nothing. */
 break;
 case CmdIASetup:
-cpu_physical_memory_read(cb_address + 8, &s->macaddr[0], 6);
+cpu_physical_memory_read(cb_address + 8, &s->conf.macaddr.a[0], 6);
 TRACE(OTHER, logout("macaddr: %s\n", nic_dump(&s->macaddr[0], 6)));
 break;
 case CmdConfigure:
@@ -1507,7 +1507,7 @@ static ssize_t nic_receive(VLANClientState *vc, const 
uint8_t * buf, size_t size
  * Long frames are discarded. */
 logout("%p received long frame (%zu byte), ignored\n", s, size);
 return -1;
-} else if (memcmp(buf, s->macaddr, 6) == 0) {   // !!!
+} else if (memcmp(buf, s->conf.macaddr.a, 6) == 0) {   // !!!
 /* Frame matches individual address. */
 /* TODO: check configuration byte 15/4 (ignore U/L). */
 TRACE(RXTX, logout("%p received frame for me, len=%zu\n", s, size));
@@ -1616,7 +1616,7 @@ static int nic_load(QEMUFile * f, void *opaque, int 
version_id)
 qemu_get_8s(f, &s->int_stat);
 /* Skip unused entries. */
 qemu_fseek(f, 3 * 4, SEEK_CUR);
-qemu_get_buffer(f, s->macaddr, 6);
+qemu_get_buffer(f, s->conf.macaddr.a, 6);
 /* Skip unused entries. */
 qemu_fseek(f, 19 * 4, SEEK_CUR);
 for (i = 0; i < 32; i++) {
@@ -1682,7 +1682,7 @@ static void nic_save(QEMUFile * f, void *opaque)
 qemu_put_8s(f, &s->int_stat);
 /* Skip unused entries. */
 qemu_fseek(f, 3 * 4, SEEK_CUR);
-qemu_put_buffer(f, s->macaddr, 6);
+qemu_put_buffer(f, s->conf.macaddr.a, 6);
 /* Skip unused entries. */
 qemu_fseek(f, 19 * 4, SEEK_CUR);
 for (i = 0; i < 32; i++) {
@@ -1731,9 +1731,7 @@ static void nic_cleanup(VLANClientState *vc)
 {
 EEPRO100State *s = vc->opaque;
 
-unregister_savevm(vc->model, s);
-
-eeprom93xx_free(s->eeprom);
+s->vc = NULL;
 }
 
 static int pci_nic_uninit(PCIDevice *pci_dev)
@@ -1741,7 +1739,9 @@ static int pci_nic_uninit(PCIDevice *pci_dev)
 EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);
 
 cpu_unregister_io_memory(s->mmio_index);
-
+unregister_savevm(s->vc->model, s);
+eeprom93xx_free(s->eeprom);
+qemu_del_vlan_client(s->vc);
 return 0;
 }
 
@@ -1771,17 +1771,18 @@ static int nic_init(PCIDevice *pci_dev, uint32_t device)
 pci_register_bar(&s->dev, 2, PCI_FLASH_SIZE, PCI_ADDRESS_SPACE_MEM,
pci_mmio_map);
 
-qdev_get_macaddr(&s->dev.qdev, s->macaddr);
+qemu_macaddr_default_if_unset(&s->conf.macaddr);
 logout("macaddr: %s\n", nic_dump(&s->macaddr[0], 6));
 assert(s->region[1] == 0);
 
 nic_reset(s);
 
-s->vc = qdev_get_vlan_client(&s->dev.qdev,
+s->vc = qemu_new_vlan_client(s->conf.vlan, s->conf.peer,
+ pci_dev->qdev.info->name, pci_dev->qdev.id,
  nic_can_receive, nic_receive, NULL,
  nic_cleanup, s);
 
-qemu_format_nic_info_str(s->vc, s->macaddr);
+qemu_format_nic_info_str(s->vc, s->conf.macaddr.a);
 TRACE(OTHER, logout("%s\n", s->vc->info_str));
 
 qemu_register_reset(nic_reset, s);
@@ -1855,53 +1856,101 @@ static PCIDeviceInfo eepro100_info[] = {
 .qdev.name = "i82550",
 .qdev.size = sizeof(EEPRO100State),
 .init  = pci_i82550_init,
+.qdev.props = (Property[]) {
+DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
+DEFINE_PROP_END_OF_LIST(),
+},
 },{
 .qdev.name = "i82551",
 .qdev.size = sizeof(EEPRO100State),
 .init  = pci_i82551_init,
 .exit  = pci_nic_uninit,
+.qdev.props = (Property[]) {
+  

[Qemu-devel] [PATCH 16/22] smc91c111: use qdev properties for configuration.

2009-10-21 Thread Gerd Hoffmann

Signed-off-by: Gerd Hoffmann 
---
 hw/smc91c111.c |   28 +++-
 1 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/hw/smc91c111.c b/hw/smc91c111.c
index d58821a..4006035 100644
--- a/hw/smc91c111.c
+++ b/hw/smc91c111.c
@@ -19,6 +19,7 @@
 typedef struct {
 SysBusDevice busdev;
 VLANClientState *vc;
+NICConf conf;
 uint16_t tcr;
 uint16_t rcr;
 uint16_t cr;
@@ -42,7 +43,6 @@ typedef struct {
 uint8_t data[NUM_PACKETS][2048];
 uint8_t int_level;
 uint8_t int_mask;
-uint8_t macaddr[6];
 int mmio_index;
 } smc91c111_state;
 
@@ -474,7 +474,7 @@ static uint32_t smc91c111_readb(void *opaque, 
target_phys_addr_t offset)
 /* Not implemented.  */
 return 0;
 case 4: case 5: case 6: case 7: case 8: case 9: /* IA */
-return s->macaddr[offset - 4];
+return s->conf.macaddr.a[offset - 4];
 case 10: /* General Purpose */
 return s->gpr & 0xff;
 case 11:
@@ -696,8 +696,7 @@ static void smc91c111_cleanup(VLANClientState *vc)
 {
 smc91c111_state *s = vc->opaque;
 
-cpu_unregister_io_memory(s->mmio_index);
-qemu_free(s);
+s->vc = NULL;
 }
 
 static int smc91c111_init1(SysBusDevice *dev)
@@ -708,21 +707,32 @@ static int smc91c111_init1(SysBusDevice *dev)
smc91c111_writefn, s);
 sysbus_init_mmio(dev, 16, s->mmio_index);
 sysbus_init_irq(dev, &s->irq);
-qdev_get_macaddr(&dev->qdev, s->macaddr);
+qemu_macaddr_default_if_unset(&s->conf.macaddr);
 
 smc91c111_reset(s);
 
-s->vc = qdev_get_vlan_client(&dev->qdev,
+s->vc = qemu_new_vlan_client(s->conf.vlan, s->conf.peer,
+ dev->qdev.info->name, dev->qdev.id,
  smc91c111_can_receive, smc91c111_receive, 
NULL,
  smc91c111_cleanup, s);
-qemu_format_nic_info_str(s->vc, s->macaddr);
+qemu_format_nic_info_str(s->vc, s->conf.macaddr.a);
 /* ??? Save/restore.  */
 return 0;
 }
 
+static SysBusDeviceInfo smc91c111_info = {
+.init = smc91c111_init1,
+.qdev.name  = "smc91c111",
+.qdev.size  = sizeof(smc91c111_state),
+.qdev.props = (Property[]) {
+DEFINE_NIC_PROPERTIES(smc91c111_state, conf),
+DEFINE_PROP_END_OF_LIST(),
+}
+};
+
 static void smc91c111_register_devices(void)
 {
-sysbus_register_dev("smc91c111", sizeof(smc91c111_state), smc91c111_init1);
+sysbus_register_withprop(&smc91c111_info);
 }
 
 /* Legacy helper function.  Should go away when machine config files are
@@ -734,7 +744,7 @@ void smc91c111_init(NICInfo *nd, uint32_t base, qemu_irq 
irq)
 
 qemu_check_nic_model(nd, "smc91c111");
 dev = qdev_create(NULL, "smc91c111");
-dev->nd = nd;
+qdev_set_nic_properties(dev, nd);
 qdev_init_nofail(dev);
 s = sysbus_from_qdev(dev);
 sysbus_mmio_map(s, 0, base);
-- 
1.6.2.5





[Qemu-devel] [PATCH 18/22] stellaris_enet: use qdev properties for configuration.

2009-10-21 Thread Gerd Hoffmann

Signed-off-by: Gerd Hoffmann 
---
 hw/stellaris.c  |2 +-
 hw/stellaris_enet.c |   40 +---
 2 files changed, 26 insertions(+), 16 deletions(-)

diff --git a/hw/stellaris.c b/hw/stellaris.c
index 1628914..44c9eee 100644
--- a/hw/stellaris.c
+++ b/hw/stellaris.c
@@ -1383,7 +1383,7 @@ static void stellaris_init(const char *kernel_filename, 
const char *cpu_model,
 qemu_check_nic_model(&nd_table[0], "stellaris");
 
 enet = qdev_create(NULL, "stellaris_enet");
-enet->nd = &nd_table[0];
+qdev_set_nic_properties(enet, &nd_table[0]);
 qdev_init_nofail(enet);
 sysbus_mmio_map(sysbus_from_qdev(enet), 0, 0x40048000);
 sysbus_connect_irq(sysbus_from_qdev(enet), 0, pic[42]);
diff --git a/hw/stellaris_enet.c b/hw/stellaris_enet.c
index 4596a69..fe2cffe 100644
--- a/hw/stellaris_enet.c
+++ b/hw/stellaris_enet.c
@@ -67,8 +67,8 @@ typedef struct {
 int rx_fifo_len;
 int next_packet;
 VLANClientState *vc;
+NICConf conf;
 qemu_irq irq;
-uint8_t macaddr[6];
 int mmio_index;
 } stellaris_enet_state;
 
@@ -169,10 +169,10 @@ static uint32_t stellaris_enet_read(void *opaque, 
target_phys_addr_t offset)
 }
 return val;
 case 0x14: /* IA0 */
-return s->macaddr[0] | (s->macaddr[1] << 8)
-   | (s->macaddr[2] << 16) | (s->macaddr[3] << 24);
+return s->conf.macaddr.a[0] | (s->conf.macaddr.a[1] << 8)
+   | (s->conf.macaddr.a[2] << 16) | (s->conf.macaddr.a[3] << 24);
 case 0x18: /* IA1 */
-return s->macaddr[4] | (s->macaddr[5] << 8);
+return s->conf.macaddr.a[4] | (s->conf.macaddr.a[5] << 8);
 case 0x1c: /* THR */
 return s->thr;
 case 0x20: /* MCTL */
@@ -267,14 +267,14 @@ static void stellaris_enet_write(void *opaque, 
target_phys_addr_t offset,
 }
 break;
 case 0x14: /* IA0 */
-s->macaddr[0] = value;
-s->macaddr[1] = value >> 8;
-s->macaddr[2] = value >> 16;
-s->macaddr[3] = value >> 24;
+s->conf.macaddr.a[0] = value;
+s->conf.macaddr.a[1] = value >> 8;
+s->conf.macaddr.a[2] = value >> 16;
+s->conf.macaddr.a[3] = value >> 24;
 break;
 case 0x18: /* IA1 */
-s->macaddr[4] = value;
-s->macaddr[5] = value >> 8;
+s->conf.macaddr.a[4] = value;
+s->conf.macaddr.a[5] = value >> 8;
 break;
 case 0x1c: /* THR */
 s->thr = value;
@@ -404,13 +404,14 @@ static int stellaris_enet_init(SysBusDevice *dev)
stellaris_enet_writefn, s);
 sysbus_init_mmio(dev, 0x1000, s->mmio_index);
 sysbus_init_irq(dev, &s->irq);
-qdev_get_macaddr(&dev->qdev, s->macaddr);
+qemu_macaddr_default_if_unset(&s->conf.macaddr);
 
-s->vc = qdev_get_vlan_client(&dev->qdev,
+s->vc = qemu_new_vlan_client(s->conf.vlan, s->conf.peer,
+ dev->qdev.info->name, dev->qdev.id,
  stellaris_enet_can_receive,
  stellaris_enet_receive, NULL,
  stellaris_enet_cleanup, s);
-qemu_format_nic_info_str(s->vc, s->macaddr);
+qemu_format_nic_info_str(s->vc, s->conf.macaddr.a);
 
 stellaris_enet_reset(s);
 register_savevm("stellaris_enet", -1, 1,
@@ -418,10 +419,19 @@ static int stellaris_enet_init(SysBusDevice *dev)
 return 0;
 }
 
+static SysBusDeviceInfo stellaris_enet_info = {
+.init = stellaris_enet_init,
+.qdev.name  = "stellaris_enet",
+.qdev.size  = sizeof(stellaris_enet_state),
+.qdev.props = (Property[]) {
+DEFINE_NIC_PROPERTIES(stellaris_enet_state, conf),
+DEFINE_PROP_END_OF_LIST(),
+}
+};
+
 static void stellaris_enet_register_devices(void)
 {
-sysbus_register_dev("stellaris_enet", sizeof(stellaris_enet_state),
-stellaris_enet_init);
+sysbus_register_withprop(&stellaris_enet_info);
 }
 
 device_init(stellaris_enet_register_devices)
-- 
1.6.2.5





[Qemu-devel] [PATCH 20/22] zap DeviceState->nd

2009-10-21 Thread Gerd Hoffmann
No users left.
Also cleanup obsolete helper functions.

Signed-off-by: Gerd Hoffmann 
---
 hw/pci.c  |9 +
 hw/qdev.c |   22 --
 hw/qdev.h |1 -
 net.h |7 ---
 4 files changed, 1 insertions(+), 38 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index fe2c4bd..553febb 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -859,14 +859,7 @@ PCIDevice *pci_nic_init(NICInfo *nd, const char 
*default_model,
 dev = &pci_dev->qdev;
 if (nd->name)
 dev->id = qemu_strdup(nd->name);
-if (qdev_prop_exists(dev, "mac")) {
-/* qdev-ified */
-qdev_set_nic_properties(dev, nd);
-} else {
-/* legacy */
-dev->nd = nd;
-nd->private = dev;
-}
+qdev_set_nic_properties(dev, nd);
 if (qdev_init(dev) < 0)
 return NULL;
 return pci_dev;
diff --git a/hw/qdev.c b/hw/qdev.c
index e81d662..373ddfc 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -361,28 +361,6 @@ void qdev_connect_gpio_out(DeviceState * dev, int n, 
qemu_irq pin)
 dev->gpio_out[n] = pin;
 }
 
-VLANClientState *qdev_get_vlan_client(DeviceState *dev,
-  NetCanReceive *can_receive,
-  NetReceive *receive,
-  NetReceiveIOV *receive_iov,
-  NetCleanup *cleanup,
-  void *opaque)
-{
-NICInfo *nd = dev->nd;
-assert(nd);
-nd->vc = qemu_new_vlan_client(nd->vlan, nd->netdev,
-  nd->model, nd->name,
-  can_receive, receive, receive_iov,
-  cleanup, opaque);
-return nd->vc;
-}
-
-
-void qdev_get_macaddr(DeviceState *dev, uint8_t *macaddr)
-{
-memcpy(macaddr, dev->nd->macaddr, 6);
-}
-
 void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
 {
 qdev_prop_set_macaddr(dev, "mac", nd->macaddr);
diff --git a/hw/qdev.h b/hw/qdev.h
index 5271a3c..d28978f 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -39,7 +39,6 @@ struct DeviceState {
 qemu_irq *gpio_in;
 QLIST_HEAD(, BusState) child_bus;
 int num_child_bus;
-NICInfo *nd;
 QLIST_ENTRY(DeviceState) sibling;
 };
 
diff --git a/net.h b/net.h
index f2d10f0..c96f291 100644
--- a/net.h
+++ b/net.h
@@ -164,13 +164,6 @@ void net_host_device_remove(Monitor *mon, const QDict 
*qdict);
 #define SMBD_COMMAND "/usr/sbin/smbd"
 #endif
 
-void qdev_get_macaddr(DeviceState *dev, uint8_t *macaddr);
-VLANClientState *qdev_get_vlan_client(DeviceState *dev,
-  NetCanReceive *can_receive,
-  NetReceive *receive,
-  NetReceiveIOV *receive_iov,
-  NetCleanup *cleanup,
-  void *opaque);
 void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd);
 
 #endif
-- 
1.6.2.5





Re: [Qemu-devel] [PATCH] properly save kvm system time msr registers

2009-10-21 Thread Gerd Hoffmann

On 10/20/09 16:04, Glauber Costa wrote:

Currently, the msrs involved in setting up pvclock are not saved over
migration and/or save/restore. This patch puts their value in special
fields in our CPUState, and deal with them using vmstate.

kvm also has to account for it, by including them in the msr list
for the ioctls.


Fails to build.  Fedora 11 machine with distro kernel.

http://repo.or.cz/w/qemu/pdb.git?a=blob;f=build.log;h=5b8a2e83116dc6a74e5045e30c3efe71fa7397ef;hb=0b4f913c89b89b45d3844dc1cf321e3d94871ecb

cheers,
  Gerd





[Qemu-devel] [PATCH 00/12] S/390 support

2009-10-21 Thread Ulrich Hecht
Here's the patches again, split and fixed as suggested by Aurelien.
It should now be possible to apply host and target support separately.
See the individual patches for details on what has changed.

CU
Uli

Ulrich Hecht (12):
  TCG "sync" op
  S/390 disassembler fixes
  S/390 CPU emulation
  S/390 host build system support
  S/390 target build system support
  S/390 host support for TCG
  linux-user: S/390 64-bit (s390x) support
  linux-user: don't do locking in single-threaded processes
  linux-user: dup3, fallocate syscalls
  linux-user: define a couple of syscalls for non-uid16 targets
  linux-user: getpriority errno fix
  enable CPU_QuadU for s390x

 configure|   58 +-
 cpu-all.h|2 +-
 cpu-defs.h   |8 +
 cpu-exec.c   |   16 +-
 disas.c  |3 +
 dyngen-exec.h|2 +-
 linux-user/elfload.c |   18 +
 linux-user/main.c|   89 ++
 linux-user/s390x/syscall.h   |   25 +
 linux-user/s390x/syscall_nr.h|  348 +
 linux-user/s390x/target_signal.h |   26 +
 linux-user/s390x/termbits.h  |  283 
 linux-user/signal.c  |  314 +
 linux-user/syscall.c |  156 ++-
 linux-user/syscall_defs.h|   56 +-
 qemu-binfmt-conf.sh  |5 +-
 s390-dis.c   |4 +-
 s390x.ld |  194 +++
 target-s390x/cpu.h   |  118 ++
 target-s390x/exec.h  |   51 +
 target-s390x/helper.c|   63 +
 target-s390x/helpers.h   |  128 ++
 target-s390x/op_helper.c | 1639 ++
 target-s390x/translate.c | 2834 ++
 tcg/s390/tcg-target.c| 1145 +++
 tcg/s390/tcg-target.h|   76 +
 tcg/tcg-op.h |   12 +
 tcg/tcg-opc.h|2 +
 tcg/tcg.c|6 +
 29 files changed, 7640 insertions(+), 41 deletions(-)
 create mode 100644 linux-user/s390x/syscall.h
 create mode 100644 linux-user/s390x/syscall_nr.h
 create mode 100644 linux-user/s390x/target_signal.h
 create mode 100644 linux-user/s390x/termbits.h
 create mode 100644 s390x.ld
 create mode 100644 target-s390x/cpu.h
 create mode 100644 target-s390x/exec.h
 create mode 100644 target-s390x/helper.c
 create mode 100644 target-s390x/helpers.h
 create mode 100644 target-s390x/op_helper.c
 create mode 100644 target-s390x/translate.c
 create mode 100644 tcg/s390/tcg-target.c
 create mode 100644 tcg/s390/tcg-target.h





[Qemu-devel] [PATCH 06/12] S/390 host support for TCG

2009-10-21 Thread Ulrich Hecht
S/390 TCG code generator as posted before

improvements since last time:
- don't use R0 (often means "zero", not "register zero")
- optimized add_i32 immediate
- formatted for better compliance with the QEMU coding style

Signed-off-by: Ulrich Hecht 
---
 dyngen-exec.h |2 +-
 linux-user/syscall.c  |2 +-
 s390x.ld  |  194 +
 tcg/s390/tcg-target.c | 1145 +
 tcg/s390/tcg-target.h |   76 
 5 files changed, 1417 insertions(+), 2 deletions(-)
 create mode 100644 s390x.ld
 create mode 100644 tcg/s390/tcg-target.c
 create mode 100644 tcg/s390/tcg-target.h

diff --git a/dyngen-exec.h b/dyngen-exec.h
index 86e61c3..0353f36 100644
--- a/dyngen-exec.h
+++ b/dyngen-exec.h
@@ -117,7 +117,7 @@ extern int printf(const char *, ...);
 
 /* The return address may point to the start of the next instruction.
Subtracting one gets us the call instruction itself.  */
-#if defined(__s390__)
+#if defined(__s390__) && !defined(__s390x__)
 # define GETPC() ((void*)(((unsigned long)__builtin_return_address(0) & 
0x7fffUL) - 1))
 #elif defined(__arm__)
 /* Thumb return addresses have the low bit set, so we need to subtract two.
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index bf06d14..45ccef9 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -183,7 +183,7 @@ 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
 
diff --git a/s390x.ld b/s390x.ld
new file mode 100644
index 000..7d1f2b7
--- /dev/null
+++ b/s390x.ld
@@ -0,0 +1,194 @@
+/* Default linker script, for normal executables */
+OUTPUT_FORMAT("elf64-s390", "elf64-s390",
+ "elf64-s390")
+OUTPUT_ARCH(s390:64-bit)
+ENTRY(_start)
+SEARCH_DIR("/usr/s390x-suse-linux/lib64"); SEARCH_DIR("/usr/local/lib64"); 
SEARCH_DIR("/lib64"); SEARCH_DIR("/usr/lib64"); 
SEARCH_DIR("/usr/s390x-suse-linux/lib"); SEARCH_DIR("/usr/lib64"); 
SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  PROVIDE (__executable_start = 0x6000); . = 0x6000 + SIZEOF_HEADERS;
+  .interp : { *(.interp) }
+  .note.gnu.build-id : { *(.note.gnu.build-id) }
+  .hash   : { *(.hash) }
+  .gnu.hash   : { *(.gnu.hash) }
+  .dynsym : { *(.dynsym) }
+  .dynstr : { *(.dynstr) }
+  .gnu.version: { *(.gnu.version) }
+  .gnu.version_d  : { *(.gnu.version_d) }
+  .gnu.version_r  : { *(.gnu.version_r) }
+  .rel.init   : { *(.rel.init) }
+  .rela.init  : { *(.rela.init) }
+  .rel.text   : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }
+  .rela.text  : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
+  .rel.fini   : { *(.rel.fini) }
+  .rela.fini  : { *(.rela.fini) }
+  .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }
+  .rela.rodata: { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
+  .rel.data.rel.ro   : { *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*) }
+  .rela.data.rel.ro   : { *(.rela.data.rel.ro* .rela.gnu.linkonce.d.rel.ro.*) }
+  .rel.data   : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
+  .rela.data  : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
+  .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }
+  .rela.tdata: { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
+  .rel.tbss  : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }
+  .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
+  .rel.ctors  : { *(.rel.ctors) }
+  .rela.ctors : { *(.rela.ctors) }
+  .rel.dtors  : { *(.rel.dtors) }
+  .rela.dtors : { *(.rela.dtors) }
+  .rel.got: { *(.rel.got) }
+  .rela.got   : { *(.rela.got) }
+  .rel.bss: { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
+  .rela.bss   : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
+  .rel.plt: { *(.rel.plt) }
+  .rela.plt   : { *(.rela.plt) }
+  .init   :
+  {
+KEEP (*(.init))
+  } =0x07070707
+  .plt: { *(.plt) }
+  .text   :
+  {
+*(.text .stub .text.* .gnu.linkonce.t.*)
+/* .gnu.warning sections are handled specially by elf32.em.  */
+*(.gnu.warning)
+  } =0x07070707
+  .fini   :
+  {
+KEEP (*(.fini))
+  } =0x07070707
+  PROVIDE (__etext = .);
+  PROVIDE (_etext = .);
+  PROVIDE (etext = .);
+  .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
+  .rodata1: { *(.rodata1) }
+  .eh_frame_hdr : { *(.eh_frame_hdr) }
+  .eh_frame   : ONLY_IF_RO { KEEP (*(.eh_frame)) }
+  .gcc_except_table   : ONLY_IF_RO { *(.

[Qemu-devel] [PATCH 05/12] S/390 target build system support

2009-10-21 Thread Ulrich Hecht
changes to configure and makefiles for S/390 target support
---
 configure |9 +++--
 1 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/configure b/configure
index df984a3..64be51f 100755
--- a/configure
+++ b/configure
@@ -793,6 +793,7 @@ sh4eb-linux-user \
 sparc-linux-user \
 sparc64-linux-user \
 sparc32plus-linux-user \
+s390x-linux-user \
 "
 fi
 # the following are Darwin specific
@@ -2093,7 +2094,7 @@ target_arch2=`echo $target | cut -d '-' -f 1`
 target_bigendian="no"
 
 case "$target_arch2" in
-  
armeb|m68k|microblaze|mips|mipsn32|mips64|ppc|ppcemb|ppc64|ppc64abi32|sh4eb|sparc|sparc64|sparc32plus)
+  
armeb|m68k|microblaze|mips|mipsn32|mips64|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus)
   target_bigendian=yes
   ;;
 esac
@@ -2253,6 +2254,10 @@ case "$target_arch2" in
 echo "TARGET_ABI32=y" >> $config_target_mak
 target_phys_bits=64
   ;;
+  s390x)
+target_nptl="yes"
+target_phys_bits=64
+  ;;
   *)
 echo "Unsupported target CPU"
 exit 1
@@ -2321,7 +2326,7 @@ if test ! -z "$gdb_xml_files" ; then
 fi
 
 case "$target_arch2" in
-  
arm|armeb|m68k|microblaze|mips|mipsel|mipsn32|mipsn32el|mips64|mips64el|ppc|ppc64|ppc64abi32|ppcemb|sparc|sparc64|sparc32plus)
+  
arm|armeb|m68k|microblaze|mips|mipsel|mipsn32|mipsn32el|mips64|mips64el|ppc|ppc64|ppc64abi32|ppcemb|s390x|sparc|sparc64|sparc32plus)
 echo "CONFIG_SOFTFLOAT=y" >> $config_target_mak
 ;;
   *)
-- 
1.6.2.1





[Qemu-devel] [PATCH 02/12] S/390 disassembler fixes

2009-10-21 Thread Ulrich Hecht
enable zArch (64-bit) instructions
enable disassembler for both s390 and s390x

Signed-off-by: Ulrich Hecht 
---
 configure  |2 +-
 disas.c|3 +++
 s390-dis.c |4 ++--
 3 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/configure b/configure
index ca6d45c..350c742 100755
--- a/configure
+++ b/configure
@@ -2386,7 +2386,7 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
   ppc*)
 echo "CONFIG_PPC_DIS=y"  >> $config_target_mak
   ;;
-  s390)
+  s390*)
 echo "CONFIG_S390_DIS=y"  >> $config_target_mak
   ;;
   sh4)
diff --git a/disas.c b/disas.c
index ce342bc..14c8901 100644
--- a/disas.c
+++ b/disas.c
@@ -195,6 +195,9 @@ void target_disas(FILE *out, target_ulong code, 
target_ulong size, int flags)
 #elif defined(TARGET_CRIS)
 disasm_info.mach = bfd_mach_cris_v32;
 print_insn = print_insn_crisv32;
+#elif defined(TARGET_S390X)
+disasm_info.mach = bfd_mach_s390_64;
+print_insn = print_insn_s390;
 #elif defined(TARGET_MICROBLAZE)
 disasm_info.mach = bfd_arch_microblaze;
 print_insn = print_insn_microblaze;
diff --git a/s390-dis.c b/s390-dis.c
index 86dd84f..9a73a57 100644
--- a/s390-dis.c
+++ b/s390-dis.c
@@ -191,10 +191,10 @@ init_disasm (struct disassemble_info *info)
 //  switch (info->mach)
 //{
 //case bfd_mach_s390_31:
-  current_arch_mask = 1 << S390_OPCODE_ESA;
+//  current_arch_mask = 1 << S390_OPCODE_ESA;
 //  break;
 //case bfd_mach_s390_64:
-//  current_arch_mask = 1 << S390_OPCODE_ZARCH;
+  current_arch_mask = 1 << S390_OPCODE_ZARCH;
 //  break;
 //default:
 //  abort ();
-- 
1.6.2.1





[Qemu-devel] [PATCH 01/12] TCG "sync" op

2009-10-21 Thread Ulrich Hecht
sync allows concurrent accesses to locations in memory through different TCG
variables. This comes in handy when you are emulating CPU registers that can
be used as either 32 or 64 bit, as TCG doesn't know anything about aliases.
See the s390x target for an example.

Fixed sync_i64 build failure on 32-bit targets.

Signed-off-by: Ulrich Hecht 
---
 tcg/tcg-op.h  |   12 
 tcg/tcg-opc.h |2 ++
 tcg/tcg.c |6 ++
 3 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index faf2e8b..c1b4710 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -316,6 +316,18 @@ static inline void tcg_gen_br(int label)
 tcg_gen_op1i(INDEX_op_br, label);
 }
 
+static inline void tcg_gen_sync_i32(TCGv_i32 arg)
+{
+tcg_gen_op1_i32(INDEX_op_sync_i32, arg);
+}
+
+#if TCG_TARGET_REG_BITS == 64
+static inline void tcg_gen_sync_i64(TCGv_i64 arg)
+{
+tcg_gen_op1_i64(INDEX_op_sync_i64, arg);
+}
+#endif
+
 static inline void tcg_gen_mov_i32(TCGv_i32 ret, TCGv_i32 arg)
 {
 if (!TCGV_EQUAL_I32(ret, arg))
diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h
index b7f3fd7..5dcdeba 100644
--- a/tcg/tcg-opc.h
+++ b/tcg/tcg-opc.h
@@ -40,6 +40,7 @@ DEF2(call, 0, 1, 2, TCG_OPF_SIDE_EFFECTS) /* variable number 
of parameters */
 DEF2(jmp, 0, 1, 0, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
 DEF2(br, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
 
+DEF2(sync_i32, 0, 1, 0, 0)
 DEF2(mov_i32, 1, 1, 0, 0)
 DEF2(movi_i32, 1, 0, 1, 0)
 /* load/store */
@@ -109,6 +110,7 @@ DEF2(neg_i32, 1, 1, 0, 0)
 #endif
 
 #if TCG_TARGET_REG_BITS == 64
+DEF2(sync_i64, 0, 1, 0, 0)
 DEF2(mov_i64, 1, 1, 0, 0)
 DEF2(movi_i64, 1, 0, 1, 0)
 /* load/store */
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 3c0e296..8eb60f8 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1930,6 +1930,12 @@ static inline int tcg_gen_code_common(TCGContext *s, 
uint8_t *gen_code_buf,
 //dump_regs(s);
 #endif
 switch(opc) {
+case INDEX_op_sync_i32:
+#if TCG_TARGET_REG_BITS == 64
+case INDEX_op_sync_i64:
+#endif
+temp_save(s, args[0], s->reserved_regs);
+break;
 case INDEX_op_mov_i32:
 #if TCG_TARGET_REG_BITS == 64
 case INDEX_op_mov_i64:
-- 
1.6.2.1





[Qemu-devel] [PATCH 11/12] linux-user: getpriority errno fix

2009-10-21 Thread Ulrich Hecht
getpriority returned wrong errno; fixes LTP test getpriority02.

Signed-off-by: Ulrich Hecht 
---
 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 da6f2e1..455c3fd 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5314,7 +5314,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 /* libc does special remapping of the return value of
  * sys_getpriority() so it's just easiest to call
  * sys_getpriority() directly rather than through libc. */
-ret = sys_getpriority(arg1, arg2);
+ret = get_errno(sys_getpriority(arg1, arg2));
 break;
 case TARGET_NR_setpriority:
 ret = get_errno(setpriority(arg1, arg2, arg3));
-- 
1.6.2.1





[Qemu-devel] [PATCH 04/12] S/390 host build system support

2009-10-21 Thread Ulrich Hecht
changes to configure and makefiles for S/390 host support
---
 configure |   11 ---
 1 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/configure b/configure
index 350c742..df984a3 100755
--- a/configure
+++ b/configure
@@ -157,9 +157,12 @@ case "$cpu" in
   parisc|parisc64)
 cpu="hppa"
   ;;
-  s390*)
+  s390)
 cpu="s390"
   ;;
+  s390x)
+cpu="s390x"
+  ;;
   sparc|sun4[cdmuv])
 cpu="sparc"
   ;;
@@ -855,7 +858,7 @@ fi
 # host long bits test
 hostlongbits="32"
 case "$cpu" in
-  x86_64|alpha|ia64|sparc64|ppc64)
+  x86_64|alpha|ia64|sparc64|ppc64|s390x)
 hostlongbits=64
   ;;
 esac
@@ -1819,7 +1822,7 @@ echo >> $config_host_mak
 echo "CONFIG_QEMU_SHAREDIR=\"$prefix$datasuffix\"" >> $config_host_mak
 
 case "$cpu" in
-  
i386|x86_64|alpha|cris|hppa|ia64|m68k|microblaze|mips|mips64|ppc|ppc64|s390|sparc|sparc64)
+  
i386|x86_64|alpha|cris|hppa|ia64|m68k|microblaze|mips|mips64|ppc|ppc64|s390|s390x|sparc|sparc64)
 ARCH=$cpu
   ;;
   armv4b|armv4l)
@@ -2351,6 +2354,8 @@ ldflags=""
 
 if test "$ARCH" = "sparc64" ; then
   cflags="-I\$(SRC_PATH)/tcg/sparc $cflags"
+elif test "$ARCH" = "s390x" ; then
+  cflags="-I\$(SRC_PATH)/tcg/s390 $cflags"
 else
   cflags="-I\$(SRC_PATH)/tcg/\$(ARCH) $cflags"
 fi
-- 
1.6.2.1





[Qemu-devel] [PATCH 12/12] enable CPU_QuadU for s390x

2009-10-21 Thread Ulrich Hecht
Signed-off-by: Ulrich Hecht 
---
 cpu-all.h |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/cpu-all.h b/cpu-all.h
index ebe8bfb..d245dd2 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -138,7 +138,7 @@ typedef union {
 uint64_t ll;
 } CPU_DoubleU;
 
-#ifdef TARGET_SPARC
+#if defined(TARGET_SPARC) || defined(TARGET_S390X)
 typedef union {
 float128 q;
 #if defined(HOST_WORDS_BIGENDIAN) \
-- 
1.6.2.1





[Qemu-devel] [PATCH 09/12] linux-user: dup3, fallocate syscalls

2009-10-21 Thread Ulrich Hecht
implementations of dup3 and fallocate that are good enough to fool LTP

dup3 check, fallocate check fixed
use compile_prog

Signed-off-by: Ulrich Hecht 
---
 configure|   36 
 linux-user/syscall.c |   10 ++
 2 files changed, 46 insertions(+), 0 deletions(-)

diff --git a/configure b/configure
index 64be51f..30ecd8f 100755
--- a/configure
+++ b/configure
@@ -1573,6 +1573,36 @@ if compile_prog "" "" ; then
   eventfd=yes
 fi
 
+# check for fallocate
+fallocate=no
+cat > $TMPC << EOF
+#include 
+
+int main(void)
+{
+fallocate(0, 0, 0, 0);
+return 0;
+}
+EOF
+if compile_prog "" "" ; then
+  fallocate=yes
+fi
+
+# check for dup3
+dup3=no
+cat > $TMPC << EOF
+#include 
+
+int main(void)
+{
+dup3(0, 0, 0);
+return 0;
+}
+EOF
+if compile_prog "" "" ; then
+  dup3=yes
+fi
+
 # Check if tools are available to build documentation.
 if test "$docs" != "no" ; then
   if test -x "`which texi2html 2>/dev/null`" -a \
@@ -1954,6 +1984,12 @@ fi
 if test "$eventfd" = "yes" ; then
   echo "CONFIG_EVENTFD=y" >> $config_host_mak
 fi
+if test "$fallocate" = "yes" ; then
+  echo "CONFIG_FALLOCATE=y" >> $config_host_mak
+fi
+if test "$dup3" = "yes" ; then
+  echo "CONFIG_DUP3=y" >> $config_host_mak
+fi
 if test "$inotify" = "yes" ; then
   echo "CONFIG_INOTIFY=y" >> $config_host_mak
 fi
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index f2a53d5..4991154 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4747,6 +4747,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long 
arg1,
 case TARGET_NR_dup2:
 ret = get_errno(dup2(arg1, arg2));
 break;
+#if defined(TARGET_NR_dup3) && defined(CONFIG_DUP3)
+case TARGET_NR_dup3:
+ret = get_errno(dup3(arg1, arg2, arg3));
+break;
+#endif
 #ifdef TARGET_NR_getppid /* not on alpha */
 case TARGET_NR_getppid:
 ret = get_errno(getppid());
@@ -7022,6 +7027,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long 
arg1,
 break;
 #endif
 #endif /* CONFIG_EVENTFD  */
+#if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
+case TARGET_NR_fallocate:
+ret = get_errno(fallocate(arg1, arg2, arg3, arg4));
+break;
+#endif
 default:
 unimplemented:
 gemu_log("qemu: Unsupported syscall: %d\n", num);
-- 
1.6.2.1





[Qemu-devel] [PATCH 08/12] linux-user: don't do locking in single-threaded processes

2009-10-21 Thread Ulrich Hecht
Skips setting the tb_lock if a process doesn't have more than one thread,
which is usually the case. Results in about 20% performance gain (measured
with the s390x target, but the effect should be similar with other targets).

Signed-off-by: Ulrich Hecht 
---
 cpu-defs.h   |8 
 cpu-exec.c   |   14 --
 linux-user/syscall.c |1 +
 3 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/cpu-defs.h b/cpu-defs.h
index 95068b5..c50c59e 100644
--- a/cpu-defs.h
+++ b/cpu-defs.h
@@ -135,6 +135,13 @@ typedef struct CPUWatchpoint {
 } CPUWatchpoint;
 
 #define CPU_TEMP_BUF_NLONGS 128
+
+#ifdef CONFIG_USER_ONLY
+#define MULTITHREAD uint32_t multithreaded;
+#else
+#define MULTITHREAD
+#endif
+
 #define CPU_COMMON  \
 struct TranslationBlock *current_tb; /* currently executing TB  */  \
 /* soft mmu support */  \
@@ -149,6 +156,7 @@ typedef struct CPUWatchpoint {
 uint32_t stop;   /* Stop request */ \
 uint32_t stopped; /* Artificially stopped */\
 uint32_t interrupt_request; \
+MULTITHREAD /* needs locking when accessing TBs */  \
 volatile sig_atomic_t exit_request; \
 /* The meaning of the MMU modes is defined in the target code. */   \
 CPUTLBEntry tlb_table[NB_MMU_MODES][CPU_TLB_SIZE];  \
diff --git a/cpu-exec.c b/cpu-exec.c
index 6b3391c..3fe2725 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -219,6 +219,9 @@ int cpu_exec(CPUState *env1)
 TranslationBlock *tb;
 uint8_t *tc_ptr;
 unsigned long next_tb;
+#ifdef CONFIG_USER_ONLY
+uint32_t multithreaded;
+#endif
 
 if (cpu_halted(env1) == EXCP_HALTED)
 return EXCP_HALTED;
@@ -576,7 +579,11 @@ int cpu_exec(CPUState *env1)
 #endif
 }
 #endif
-spin_lock(&tb_lock);
+#ifdef CONFIG_USER_ONLY
+multithreaded = env->multithreaded;
+if (multithreaded)
+#endif
+spin_lock(&tb_lock);
 tb = tb_find_fast();
 /* Note: we do it here to avoid a gcc bug on Mac OS X when
doing it in tb_find_slow */
@@ -600,7 +607,10 @@ int cpu_exec(CPUState *env1)
 tb_add_jump((TranslationBlock *)(next_tb & ~3), next_tb & 
3, tb);
 }
 }
-spin_unlock(&tb_lock);
+#ifdef CONFIG_USER_ONLY
+if (multithreaded)
+#endif
+spin_unlock(&tb_lock);
 env->current_tb = tb;
 
 /* cpu_interrupt might be called while translating the
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 617e031..f2a53d5 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -3549,6 +3549,7 @@ static int do_fork(CPUState *env, unsigned int flags, 
abi_ulong newsp,
 ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
 init_task_state(ts);
 new_stack = ts->stack;
+env->multithreaded = 1;
 /* we create a new CPU instance. */
 new_env = cpu_copy(env);
 /* Init regs that differ from the parent.  */
-- 
1.6.2.1





[Qemu-devel] [PATCH 07/12] linux-user: S/390 64-bit (s390x) support

2009-10-21 Thread Ulrich Hecht
code for running 64-bit S/390 Linux binaries

use CPU_DoubleU for FP regs
proper specification exception (SIGILL) handling

Signed-off-by: Ulrich Hecht 
---
 linux-user/elfload.c |   18 ++
 linux-user/main.c|   89 ++
 linux-user/s390x/syscall.h   |   25 +++
 linux-user/s390x/syscall_nr.h|  348 ++
 linux-user/s390x/target_signal.h |   26 +++
 linux-user/s390x/termbits.h  |  283 +++
 linux-user/signal.c  |  314 ++
 linux-user/syscall.c |   16 ++-
 linux-user/syscall_defs.h|   56 ++-
 qemu-binfmt-conf.sh  |5 +-
 10 files changed, 1173 insertions(+), 7 deletions(-)
 create mode 100644 linux-user/s390x/syscall.h
 create mode 100644 linux-user/s390x/syscall_nr.h
 create mode 100644 linux-user/s390x/target_signal.h
 create mode 100644 linux-user/s390x/termbits.h

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 62a3f2a..90e9268 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -679,6 +679,24 @@ static inline void init_thread(struct target_pt_regs 
*regs, struct image_info *i
 
 #endif /* TARGET_ALPHA */
 
+#ifdef TARGET_S390X
+
+#define ELF_START_MMAP (0x200ULL)
+
+#define elf_check_arch(x) ( (x) == ELF_ARCH )
+
+#define ELF_CLASS  ELFCLASS64
+#define ELF_DATA   ELFDATA2MSB
+#define ELF_ARCH   EM_S390
+
+static inline void init_thread(struct target_pt_regs *regs, struct image_info 
*infop)
+{
+regs->psw.addr = infop->entry;
+regs->gprs[15] = infop->start_stack;
+}
+
+#endif /* TARGET_S390X */
+
 #ifndef ELF_PLATFORM
 #define ELF_PLATFORM (NULL)
 #endif
diff --git a/linux-user/main.c b/linux-user/main.c
index 81a1ada..798b2d5 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -2351,6 +2351,86 @@ void cpu_loop (CPUState *env)
 }
 #endif /* TARGET_ALPHA */
 
+#ifdef TARGET_S390X
+void cpu_loop(CPUS390XState *env)
+{
+int trapnr;
+target_siginfo_t info;
+
+while (1) {
+trapnr = cpu_s390x_exec (env);
+
+if ((trapnr & 0x) == EXCP_EXECUTE_SVC) {
+int n = trapnr & 0x;
+env->regs[2] = do_syscall(env, n,
+   env->regs[2],
+   env->regs[3],
+   env->regs[4],
+   env->regs[5],
+   env->regs[6],
+   env->regs[7]);
+}
+else switch (trapnr) {
+case EXCP_INTERRUPT:
+/* just indicate that signals should be handled asap */
+break;
+case EXCP_DEBUG:
+{
+int sig;
+
+sig = gdb_handlesig (env, TARGET_SIGTRAP);
+if (sig) {
+info.si_signo = sig;
+info.si_errno = 0;
+info.si_code = TARGET_TRAP_BRKPT;
+queue_signal(env, info.si_signo, &info);
+}
+}
+break;
+case EXCP_SVC:
+{
+int n = ldub(env->psw.addr - 1);
+if (!n) n = env->regs[1];  /* syscalls > 255 */
+env->regs[2] = do_syscall(env, n,
+   env->regs[2],
+   env->regs[3],
+   env->regs[4],
+   env->regs[5],
+   env->regs[6],
+   env->regs[7]);
+}
+break;
+case EXCP_ADDR:
+{
+info.si_signo = SIGSEGV;
+info.si_errno = 0;
+/* XXX: check env->error_code */
+info.si_code = TARGET_SEGV_MAPERR;
+info._sifields._sigfault._addr = env->__excp_addr;
+queue_signal(env, info.si_signo, &info);
+}
+break;
+case EXCP_SPEC:
+{
+fprintf(stderr,"specification exception insn 0x%08x%04x\n", 
ldl(env->psw.addr), lduw(env->psw.addr + 4));
+info.si_signo = SIGILL;
+info.si_errno = 0;
+info.si_code = TARGET_ILL_ILLOPC;
+info._sifields._sigfault._addr = env->__excp_addr;
+queue_signal(env, info.si_signo, &info);
+}
+break;
+default:
+printf ("Unhandled trap: 0x%x\n", trapnr);
+cpu_dump_state(env, stderr, fprintf, 0);
+exit (1);
+}
+process_pending_signals (env);
+}
+}
+
+#endif /* TARGET_S390X */
+
 static void usage(void)
 {
 printf("qemu-" TARGET_ARCH " version " QEMU_VERSION QEMU_PKGVERSION ", 
Copyright (c) 2003-2008 Fabrice Bellard\n"
@@ -2987,6 +3067,15 @@ int main(int argc, char **argv, char **envp)
env->regs[15] = regs->acr;  
env->pc = regs->erp;
 }
+#elif defined(TARGET_S390X)
+{
+int i;
+fo

[Qemu-devel] [PATCH 10/12] linux-user: define a couple of syscalls for non-uid16 targets

2009-10-21 Thread 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)

Signed-off-by: Ulrich Hecht 
---
 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 4991154..da6f2e1 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -307,7 +307,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)
 {
@@ -416,7 +416,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
@@ -6371,18 +6371,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
@@ -6410,33 +6427,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;
@@ -6460,8 +6501,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long 
arg1,
 }
 break;
 #endif
-#ifdef TARGET_NR_setgroups32
+#if defined(TARGET_NR_setgroups32) || !defined(USE_UID16)
+#if defined(TARGET_NR_setgroups32)
 case TARGET_NR_setgroups32:
+#else
+case TARGET_NR_setgroups:
+#endif
 {
 int gidsetsize = arg1;
 uint32_t *target_grouplist;
@@ -6481,18 +6526,30 @@ abi_long do_syscall(void *cpu_env, int num, abi_long 
arg1,
 }
 break;
 #endif
-#ifdef TARGET_NR_fchown32
+#if defined(TARGET_NR_fchown32) || !defined(USE_UID16)
+#if defined(TARGET_NR_fchown32)
 case TARGET_NR_

Re: [Qemu-devel] [PATCH] new SDL keyboard shortcuts to start and stop VM

2009-10-21 Thread Glauber Costa
On Wed, Oct 21, 2009 at 5:27 AM, Kevin Wolf  wrote:
> Am 20.10.2009 19:08, schrieb Daniel P. Berrange:
>> On Tue, Oct 20, 2009 at 12:40:08PM +0200, Kevin Wolf wrote:
>>> Am 20.10.2009 00:20, schrieb Anthony Liguori:
 Mulyadi Santosa wrote:
> IMO, it would be faster if we provide keyboard shortcuts that will
> stop and resume VM execution right from SDL guest interface, rather
> than switching to console monitor first and type "s" or "c"
> respectively.
>

 Is this really common of an operation that you would need an escape key
 for it?

 Why are you so frequently stopping and continuing a guest?
>>>
>>> Why are you all trying to explain to him that actually he doesn't want
>>> to have this feature? I could have used it, too, at times (stop the
>>> guest to have enough time to attach gdb, for example). There are other
>>> ways to do it (although they are not as simple) and I used them, but
>>> that doesn't make this feature less useful.
>>>
>>> Does it take anything away for you? Or do you have plans to use those
>>> keys otherwise? If not, why not add a feature that some might find
>>> useful, even though others don't?
>>
>> The problem with adding lots of magic key-sequences, is that the more
>> you add, the more likely they are to clash with something that the
>> guest OS wants to use. You may make this use case work, but break
>> someone else's use case. Thus, IMHO, magic key sequences should be kept
>> to the bare minimum neccessary to access functionality for which there
>> is no other viable access method.
>
> Ok, you have a point there. But why do we have key sequences for
> fullscreen and resizing the SDL window back to its original size then?
> Both are things that could be accessed through monitor commands as well.
> And you don't need the right timing for resizing the window - unlike
> stopping the VM. So I would be really happy with swapping those for a
> "stop VM" shortcut.

Why don't we provide a mechanism to make a macro out of a sequence of
monitor commands, and let the user assign whatever he wants out of that?


-- 
Glauber  Costa.
"Free as in Freedom"
http://glommer.net

"The less confident you are, the more serious you have to act."




[Qemu-devel] [GIT PULL] linux-user updates

2009-10-21 Thread Riku Voipio
Hi,

Added to the previous list of patches is Uli's KD/VT/FB ioctl adding patch,
which was sent to the list earlier.

The following changes since commit 544f4f0b5aa659f858f384677d4767d8fcecb27d:
  Blue Swirl (1):
bsd-user: fix breakage by 78cfb07fe0dc556cae662a0fab5fe1bd33daabdb

are available in the git repository at:

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

Jan-Simon Möller (1):
  Re: linux-user/syscall.c - don't add GUEST_BASE to NULL pointer

Max Filippov (1):
  linux-user: fix ppc target_stat64 st_blocks layout

Paul Bolle (1):
  linux-user: don't zero a buffer twice

Riku Voipio (1):
  linux-user: Update ARM hwcaps

Ulrich Hecht (3):
  implementations of dup3 and fallocate that are good enough to fool LTP
  linux-user: getpriority errno fix
  linux-user: KD/VT/FB ioctls

 configure  |   36 +++
 linux-user/elfload.c   |9 +++-
 linux-user/ioctls.h|   14 
 linux-user/linuxload.c |1 -
 linux-user/syscall.c   |   22 --
 linux-user/syscall_defs.h  |   18 ++-
 linux-user/syscall_types.h |   51 



signature.asc
Description: Digital signature


Re: [Qemu-devel] [PATCH 1/9] Export function for VA defined ram allocation

2009-10-21 Thread Anthony Liguori

Alexander Graf wrote:

S390 requires vmas for guests to be < 256 GB. So we need to directly export
mmaps "try to use this vma as start address" feature to not accidently get
over that limit.

Signed-off-by: Alexander Graf 
---
 cpu-common.h |1 +
 exec.c   |   15 +--
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/cpu-common.h b/cpu-common.h
index 6302372..ecaf9e3 100644
--- a/cpu-common.h
+++ b/cpu-common.h
@@ -30,6 +30,7 @@ static inline void 
cpu_register_physical_memory(target_phys_addr_t start_addr,
 
 ram_addr_t cpu_get_physical_page_desc(target_phys_addr_t addr);

 ram_addr_t qemu_ram_alloc(ram_addr_t);
+ram_addr_t _qemu_ram_alloc(ram_addr_t size, void *map_at);
  


I don't like this interface very much.  Couldn't the fact that we need a 
va starting at 0 for s390 kvm be hidden behind the existing qemu_ram_alloc?


Regards,

Anthony Liguori




Re: [Qemu-devel] [PATCH] properly save kvm system time msr registers

2009-10-21 Thread Glauber Costa
On Wed, Oct 21, 2009 at 03:38:31PM +0200, Gerd Hoffmann wrote:
> On 10/20/09 16:04, Glauber Costa wrote:
>> Currently, the msrs involved in setting up pvclock are not saved over
>> migration and/or save/restore. This patch puts their value in special
>> fields in our CPUState, and deal with them using vmstate.
>>
>> kvm also has to account for it, by including them in the msr list
>> for the ioctls.
>
> Fails to build.  Fedora 11 machine with distro kernel.
>
> http://repo.or.cz/w/qemu/pdb.git?a=blob;f=build.log;h=5b8a2e83116dc6a74e5045e30c3efe71fa7397ef;hb=0b4f913c89b89b45d3844dc1cf321e3d94871ecb
strange message. Do we need --kerneldir for that? kvm_para.h should be 
available...




Re: [Qemu-devel] [PATCH] properly save kvm system time msr registers

2009-10-21 Thread Glauber Costa
On Wed, Oct 21, 2009 at 04:52:00PM +0200, Gerd Hoffmann wrote:
> On 10/21/09 16:32, Glauber Costa wrote:
>> On Wed, Oct 21, 2009 at 03:38:31PM +0200, Gerd Hoffmann wrote:
>>> On 10/20/09 16:04, Glauber Costa wrote:
 Currently, the msrs involved in setting up pvclock are not saved over
 migration and/or save/restore. This patch puts their value in special
 fields in our CPUState, and deal with them using vmstate.

 kvm also has to account for it, by including them in the msr list
 for the ioctls.
>>>
>>> Fails to build.  Fedora 11 machine with distro kernel.
>>>
>>> http://repo.or.cz/w/qemu/pdb.git?a=blob;f=build.log;h=5b8a2e83116dc6a74e5045e30c3efe71fa7397ef;hb=0b4f913c89b89b45d3844dc1cf321e3d94871ecb
>> strange message. Do we need --kerneldir for that?
>
> Requiring --kerneldir for a successful build isn't going to fly.
>
>> kvm_para.h should be available...
>
> Nope:
>
>$ rpm -ql kernel-headers | grep kvm
>/usr/include/asm/kvm.h
>/usr/include/linux/kvm.h
>
> Did you ever build this?
> You should improve your patch qa ...
built and tested. I was using --kerneldir all along, however.

One option I see is to redefine the values of msrs in this file.
It seems it already happens for tsc anyway.






  1   2   >