Re: [Qemu-devel] OEM Windows in Qemu

2011-12-23 Thread Jernej Simončič
On Friday, December 23, 2011, 7:11:08, in...@expertcomputerrepair.com wrote:

> I think the key is those specific
> memory addresses I mentioned earlier.

That's the exact reason - the strings have to be present in the
correct memory region. You can use SLICToolkit (in SLP1.0 tab) to
verify if the strings are present at the right address.

-- 
< Jernej Simončič ><><><><>< http://eternallybored.org/ >

Nature will tell you a direct lie if she can.
   -- Darwin's Observation




Re: [Qemu-devel] [PATCH] iSCSI: add configuration variables for iSCSI

2011-12-23 Thread Paolo Bonzini

On 12/22/2011 09:51 PM, ronnie sahlberg wrote:

The difference between qcow2 and iscsi and the problem is that .open()
is called for all devices before the monitor is started, so .open() is
called before we would have a chance to even hand the password to
qemu.

For qcow2 this is not a problem since even if the file is password
protected the file header is not, so you can still open the file and
read the header (to discover it is password protected) without knowing
the password.
So qcow2 can still open the file and do all the sanity checks it needs
without yet knowing the password.


You're right.

I see that the libvirt driver for rbd simply passes it on the command 
line.  I hope I'll be able to review the patch further today.


Paolo



Re: [Qemu-devel] [PATCH] iSCSI: add configuration variables for iSCSI

2011-12-23 Thread ronnie sahlberg
I do recognize that there is real need to provide password to iscsi
(and rbd?) via the monitor.
I myself do not use libvirt (it is just too much pain to be worth it
to try to upgrade it out-of-step with your distribution)
but I recognize that likely vast majority of users would use libvirt.


Once consensus is reached on "how to handle devices that need
two-stage setup" and what it would look like
I can volunteer to implement it. It would however be way out of scope
of and bigger than a simple iscsi-local patch


What about the idea about splitting .open() into two stages:
.open()   /* stage one, called before -S monitor is invoked */
.open_stage_2() /* called after -S finishes and when it starts to boot
the guest CPU */

?



regards
ronnie sahlberg


On Fri, Dec 23, 2011 at 8:08 PM, Paolo Bonzini  wrote:
> On 12/22/2011 09:51 PM, ronnie sahlberg wrote:
>>
>> The difference between qcow2 and iscsi and the problem is that .open()
>> is called for all devices before the monitor is started, so .open() is
>> called before we would have a chance to even hand the password to
>> qemu.
>>
>> For qcow2 this is not a problem since even if the file is password
>> protected the file header is not, so you can still open the file and
>> read the header (to discover it is password protected) without knowing
>> the password.
>> So qcow2 can still open the file and do all the sanity checks it needs
>> without yet knowing the password.
>
>
> You're right.
>
> I see that the libvirt driver for rbd simply passes it on the command line.
>  I hope I'll be able to review the patch further today.
>
> Paolo



Re: [Qemu-devel] [PATCH RFC v3 0/2] Initial support for Microsoft Hyper-V.

2011-12-23 Thread Marcelo Tosatti
On Sun, Dec 18, 2011 at 10:48:12PM +0200, Vadim Rozenfeld wrote:
> With the following series of patches we are starting to implement
> some basic Microsoft Hyper-V Enlightenment functionality. This series
> is mostly about adding support for relaxed timing, spinlock,
> and virtual apic.
> 
> For more Hyper-V related information please see:
> "Hypervisor Functional Specification v2.0: For Windows Server 2008 R2" at
> http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=18673

Looks fine to me and others reviewers, will wait for Anthony to apply
last uq/master pull request before applying.




[Qemu-devel] [PATCH v5 03/11] hw/sysbus.h: Increase maximum number of device IRQs.

2011-12-23 Thread Evgeny Voevodin
Samsung exynos4210 Interrupt Combiner needs 512 IRQ sources.

Signed-off-by: Evgeny Voevodin 
---
 hw/sysbus.h |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/sysbus.h b/hw/sysbus.h
index 2f4025b..6b8f0e2 100644
--- a/hw/sysbus.h
+++ b/hw/sysbus.h
@@ -8,7 +8,7 @@
 
 #define QDEV_MAX_MMIO 32
 #define QDEV_MAX_PIO 32
-#define QDEV_MAX_IRQ 256
+#define QDEV_MAX_IRQ 512
 
 typedef struct SysBusDevice SysBusDevice;
 
-- 
1.7.4.1




[Qemu-devel] [PATCH v5 10/11] hw/exynos4210.c: Add LAN support for SMDKC210.

2011-12-23 Thread Evgeny Voevodin
SMDKC210 uses lan9215 chip, but lan9118 in 16-bit mode seems to
be enough.

Signed-off-by: Evgeny Voevodin 
---
 hw/exynos4_boards.c |   27 ++-
 1 files changed, 26 insertions(+), 1 deletions(-)

diff --git a/hw/exynos4_boards.c b/hw/exynos4_boards.c
index 5410a6f..a005e0a 100644
--- a/hw/exynos4_boards.c
+++ b/hw/exynos4_boards.c
@@ -22,6 +22,8 @@
  */
 
 #include "sysemu.h"
+#include "sysbus.h"
+#include "net.h"
 #include "arm-misc.h"
 #include "exec-memory.h"
 #include "exynos4210.h"
@@ -41,6 +43,8 @@
 #define  PRINT_DEBUG(fmt, args...)  do {} while (0)
 #endif
 
+#define SMDK_LAN9118_BASE_ADDR  0x0500
+
 typedef enum exynos4_board_type {
 EXYNOS4_BOARD_NURI,
 EXYNOS4_BOARD_SMDKC210,
@@ -67,6 +71,24 @@ static struct arm_boot_info exynos4_board_binfo = {
 .smp_loader_start = EXYNOS4210_SMP_BOOT_ADDR,
 };
 
+static void lan9215_init(uint32_t base, qemu_irq irq)
+{
+DeviceState *dev;
+SysBusDevice *s;
+
+/* This should be a 9215 but the 9118 is close enough */
+if (nd_table[0].vlan) {
+qemu_check_nic_model(&nd_table[0], "lan9118");
+dev = qdev_create(NULL, "lan9118");
+qdev_set_nic_properties(dev, &nd_table[0]);
+qdev_prop_set_uint32(dev, "mode_16bit", 1);
+qdev_init_nofail(dev);
+s = sysbus_from_qdev(dev);
+sysbus_mmio_map(s, 0, base);
+sysbus_connect_irq(s, 0, irq);
+}
+}
+
 static Exynos4210State *exynos4_boards_init_common(
 const char *kernel_filename,
 const char *kernel_cmdline,
@@ -113,9 +135,12 @@ static void smdkc210_init(ram_addr_t ram_size,
 const char *kernel_filename, const char *kernel_cmdline,
 const char *initrd_filename, const char *cpu_model)
 {
-exynos4_boards_init_common(kernel_filename,
+Exynos4210State *s = exynos4_boards_init_common(kernel_filename,
kernel_cmdline, initrd_filename, 
EXYNOS4_BOARD_SMDKC210);
 
+lan9215_init(SMDK_LAN9118_BASE_ADDR,
+qemu_irq_invert(s->irq_table[exynos4210_get_irq(37, 1)]));
+
 arm_load_kernel(first_cpu, &exynos4_board_binfo);
 }
 
-- 
1.7.4.1




[Qemu-devel] [PATCH v5 07/11] ARM: exynos4210: MCT support.

2011-12-23 Thread Evgeny Voevodin

Signed-off-by: Evgeny Voevodin 
---
 Makefile.target |2 +-
 hw/exynos4210.c |   19 +
 hw/exynos4210_mct.c | 1494 +++
 3 files changed, 1514 insertions(+), 1 deletions(-)
 create mode 100644 hw/exynos4210_mct.c

diff --git a/Makefile.target b/Makefile.target
index 70a2ef8..f11d4c4 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -337,7 +337,7 @@ obj-arm-y += arm_boot.o pl011.o pl031.o pl050.o pl080.o 
pl110.o pl181.o pl190.o
 obj-arm-y += versatile_pci.o
 obj-arm-y += realview_gic.o realview.o arm_sysctl.o arm11mpcore.o a9mpcore.o
 obj-arm-y += exynos4_boards.o exynos4210.o exynos4210_uart.o exynos4210_gic.o \
- exynos4210_combiner.o exynos4210_pwm.o
+ exynos4210_combiner.o exynos4210_pwm.o exynos4210_mct.o
 obj-arm-y += arm_mptimer.o
 obj-arm-y += armv7m.o armv7m_nvic.o stellaris.o pl022.o stellaris_enet.o
 obj-arm-y += pl061.o
diff --git a/hw/exynos4210.c b/hw/exynos4210.c
index a350199..f958980 100644
--- a/hw/exynos4210.c
+++ b/hw/exynos4210.c
@@ -33,6 +33,9 @@
 /* PWM */
 #define EXYNOS4210_PWM_BASE_ADDR   0x139D
 
+/* MCT */
+#define EXYNOS4210_MCT_BASE_ADDR   0x1005
+
 /* UART's definitions */
 #define EXYNOS4210_UART0_BASE_ADDR 0x1380
 #define EXYNOS4210_UART1_BASE_ADDR 0x1381
@@ -289,6 +292,22 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
 irq_table[exynos4210_get_irq(22, 4)],
 NULL);
 
+/* Multi Core Timer */
+dev = qdev_create(NULL, "exynos4210.mct");
+qdev_init_nofail(dev);
+busdev = sysbus_from_qdev(dev);
+for (n = 0; n < 4; n++) {
+/* Connect global timer interrupts to Combiner gpio_in */
+sysbus_connect_irq(busdev, n,
+irq_table[exynos4210_get_irq(1, 4 + n)]);
+}
+/* Connect local timer interrupts to Combiner gpio_in */
+sysbus_connect_irq(busdev, 4,
+irq_table[exynos4210_get_irq(51, 0)]);
+sysbus_connect_irq(busdev, 5,
+irq_table[exynos4210_get_irq(35, 3)]);
+sysbus_mmio_map(busdev, 0, EXYNOS4210_MCT_BASE_ADDR);
+
 /*** UARTs ***/
 exynos4210_uart_create(EXYNOS4210_UART0_BASE_ADDR,
EXYNOS4210_UART0_FIFO_SIZE, 0, NULL,
diff --git a/hw/exynos4210_mct.c b/hw/exynos4210_mct.c
new file mode 100644
index 000..0ef32b8
--- /dev/null
+++ b/hw/exynos4210_mct.c
@@ -0,0 +1,1494 @@
+/*
+ * Samsung exynos4210 Multi Core timer
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
+ * All rights reserved.
+ *
+ * Evgeny Voevodin 
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see .
+ */
+
+/*
+ * Global Timer:
+ *
+ * Consists of two timers. First represents Free Running Counter and second
+ * is used to measure interval from FRC to nearest comparator.
+ *
+ *0
0x...
+ *|  timer0 |
+ *| <-- |
+ *| frc---> |
+ *|__|__|
+ *CMP0  CMP1 CMP2|   CMP3
+ * __||_
+ * | timer1 |
+ * | -> |
+ *frc  CMPx
+ *
+ * Problem: when implementing global timer as is, overflow arises.
+ * next_time = cur_time + period*count;
+ * period and count are 64 bits width and count == 0xFF..FF 64its.
+ * Lets arm timer for 0x count and update internal G_CNT register
+ * during each event.
+ *
+ * Problem: both timers need to be implemented using MCT_XT_COUNTER_STEP 
because
+ * local timer contains two counters: TCNT and ICNT. TCNT == 0 -> ICNT--.
+ * IRQ is generated when ICNT riches zero. If make timer for every TCNT == 0
+ * possible too frequently events (yes, if ICNT == 0 both, we got no luck).
+ * So, better to have one uint64_t counter equal to TCNT*ICNT and arm ptimer.c
+ * for a minimum(TCNT*ICNT, MCT_GT_COUNTER_STEP);
+ */
+
+#include "sysbus.h"
+#include "qemu-timer.h"
+#include "qemu-commo

[Qemu-devel] [PATCH v5 00/11] ARM: Samsung Exynos4210-based boards support.

2011-12-23 Thread Evgeny Voevodin
This set of patches adds support for Samsung S5PC210-based boards NURI and 
SMDKC210.
Tested on Linux kernel v3.x series. Usage of "-smp 2" option is required for 
now.

Changelog:
 v4->v5
 - hw/exynos4210_gic.c: Use memory aliases for CPU interface and Distributer.
   Excessive RW functions are removed.
 - hw/exynos4210_pwm.c and hw/exynos4210_mct.c: Saving of timers added.
 - hw/exynos4210_uart.c: VMSTATE version_id fixed.
 v3->v4
 - Split Exynos SOC and boards.
 - Temporary removed SD and CMU support to post later.
 - Lan9118 remarks took into account.
 - Secondary CPU bootloader remarks took into account.
 - PWM remarks took into account.
 - UART remarks took into account.
 v2->v3
 - Reverted hw/arm_gic.c modification
 - Added IRQ Gate to Exynos4210 board.

Evgeny Voevodin (8):
  hw/sysbus.h: Increase maximum number of device IRQs.
  ARM: exynos4210: IRQ subsystem support.
  ARM: exynos4210: PWM support.
  hw/arm_boot.c: Extend secondary CPU bootloader.
  ARM: exynos4210: MCT support.
  hw/exynos4210.c: Boot secondary CPU.
  hw/lan9118: Add basic 16-bit mode support.
  hw/exynos4210.c: Add LAN support for SMDKC210.

Evgeny Voevodin (8):
  hw/sysbus.h: Increase maximum number of device IRQs.
  ARM: exynos4210: IRQ subsystem support.
  ARM: exynos4210: PWM support.
  hw/arm_boot.c: Extend secondary CPU bootloader.
  ARM: exynos4210: MCT support.
  hw/exynos4210.c: Boot secondary CPU.
  hw/lan9118: Add basic 16-bit mode support.
  hw/exynos4210.c: Add LAN support for SMDKC210.

Maksim Kozlov (2):
  ARM: Samsung exynos4210-based boards emulation
  ARM: exynos4210: UART support

Mitsyanko Igor (1):
  Exynos4210: added display controller implementation

 Makefile.target  |3 +
 hw/arm-misc.h|1 +
 hw/arm_boot.c|   23 +-
 hw/exynos4210.c  |  352 +
 hw/exynos4210.h  |  123 
 hw/exynos4210_combiner.c |  384 ++
 hw/exynos4210_fimd.c | 1783 ++
 hw/exynos4210_gic.c  |  437 
 hw/exynos4210_mct.c  | 1494 ++
 hw/exynos4210_pwm.c  |  416 +++
 hw/exynos4210_uart.c |  670 +
 hw/exynos4_boards.c  |  167 +
 hw/lan9118.c |  115 +++-
 hw/sysbus.h  |2 +-
 14 files changed, 5956 insertions(+), 14 deletions(-)
 create mode 100644 hw/exynos4210.c
 create mode 100644 hw/exynos4210.h
 create mode 100644 hw/exynos4210_combiner.c
 create mode 100644 hw/exynos4210_fimd.c
 create mode 100644 hw/exynos4210_gic.c
 create mode 100644 hw/exynos4210_mct.c
 create mode 100644 hw/exynos4210_pwm.c
 create mode 100644 hw/exynos4210_uart.c
 create mode 100644 hw/exynos4_boards.c

-- 
1.7.4.1




[Qemu-devel] [PATCH v5 01/11] ARM: Samsung exynos4210-based boards emulation

2011-12-23 Thread Evgeny Voevodin
From: Maksim Kozlov 

Add initial code for support of NURI and SMDKC210 boards

Signed-off-by: Evgeny Voevodin 
---
 Makefile.target |1 +
 hw/exynos4210.c |  103 +++
 hw/exynos4210.h |   63 
 hw/exynos4_boards.c |  133 +++
 4 files changed, 300 insertions(+), 0 deletions(-)
 create mode 100644 hw/exynos4210.c
 create mode 100644 hw/exynos4210.h
 create mode 100644 hw/exynos4_boards.c

diff --git a/Makefile.target b/Makefile.target
index 3261383..fc308bf 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -336,6 +336,7 @@ obj-arm-y = integratorcp.o versatilepb.o arm_pic.o 
arm_timer.o
 obj-arm-y += arm_boot.o pl011.o pl031.o pl050.o pl080.o pl110.o pl181.o pl190.o
 obj-arm-y += versatile_pci.o
 obj-arm-y += realview_gic.o realview.o arm_sysctl.o arm11mpcore.o a9mpcore.o
+obj-arm-y += exynos4_boards.o exynos4210.o
 obj-arm-y += arm_mptimer.o
 obj-arm-y += armv7m.o armv7m_nvic.o stellaris.o pl022.o stellaris_enet.o
 obj-arm-y += pl061.o
diff --git a/hw/exynos4210.c b/hw/exynos4210.c
new file mode 100644
index 000..62d0ad5
--- /dev/null
+++ b/hw/exynos4210.c
@@ -0,0 +1,103 @@
+/*
+ *  Samsung exynos4210 SoC emulation
+ *
+ *  Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *Maksim Kozlov 
+ *Evgeny Voevodin 
+ *Igor Mitsyanko  
+ *
+ *  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.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see .
+ *
+ */
+
+#include "boards.h"
+#include "sysemu.h"
+#include "arm-misc.h"
+#include "exynos4210.h"
+
+#define EXYNOS4210_CHIPID_ADDR 0x1000
+
+static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
+0x09, 0x00, 0x00, 0x00 };
+
+
+Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
+unsigned long ram_size)
+{
+qemu_irq cpu_irq[4];
+int n;
+Exynos4210State *s = g_new(Exynos4210State, 1);
+qemu_irq *irqp;
+unsigned long mem_size;
+
+for (n = 0; n < smp_cpus; n++) {
+s->env[n] = cpu_init("cortex-a9");
+if (!s->env[n]) {
+fprintf(stderr, "Unable to find CPU %d definition\n", n);
+exit(1);
+}
+/* Create PIC controller for each processor instance */
+irqp = arm_pic_init_cpu(s->env[n]);
+
+/*
+ * Get GICs gpio_in cpu_irq to connect a combiner to them later.
+ * Use only IRQ for a while.
+ */
+cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
+}
+
+/*** Memory ***/
+
+/* Chip-ID and OMR */
+memory_region_init_ram_ptr(&s->chipid_mem, NULL, "exynos4210.chipid",
+sizeof(chipid_and_omr), chipid_and_omr);
+memory_region_set_readonly(&s->chipid_mem, true);
+memory_region_add_subregion(system_mem, EXYNOS4210_CHIPID_ADDR,
+&s->chipid_mem);
+
+/* Internal ROM */
+memory_region_init_ram(&s->irom_mem, NULL, "exynos4210.irom",
+   EXYNOS4210_IROM_SIZE);
+memory_region_set_readonly(&s->irom_mem, true);
+memory_region_add_subregion(system_mem, EXYNOS4210_IROM_BASE_ADDR,
+&s->irom_mem);
+/* mirror of 0x0 – 0x1 */
+memory_region_init_alias(&s->irom_alias_mem, "exynos4210.irom_alias",
+&s->irom_mem, 0, EXYNOS4210_IROM_SIZE);
+memory_region_set_readonly(&s->irom_alias_mem, true);
+memory_region_add_subregion(system_mem, EXYNOS4210_IROM_MIRROR_BASE_ADDR,
+&s->irom_alias_mem);
+
+/* Internal RAM */
+memory_region_init_ram(&s->iram_mem, NULL, "exynos4210.iram",
+   EXYNOS4210_IRAM_SIZE);
+memory_region_set_readonly(&s->iram_mem, false);
+memory_region_add_subregion(system_mem, EXYNOS4210_IRAM_BASE_ADDR,
+&s->iram_mem);
+
+/* DRAM */
+mem_size = ram_size;
+if (mem_size > EXYNOS4210_DRAM_MAX_SIZE) {
+memory_region_init_ram(&s->dram1_mem, NULL, "exynos4210.dram1",
+mem_size - EXYNOS4210_DRAM_MAX_SIZE);
+memory_region_add_subregion(system_mem, EXYNOS4210_DRAM1_BASE_ADDR,
+&s->dram1_mem);
+mem_size = EXYNOS4210_DRAM_MAX_SIZE;
+}
+memory_region_init_ram(&s->dram0_mem, NULL, "exynos4210.dram0", mem_size);
+memory_region_add_subregion(system_mem, EXYNOS4210_DRAM0_BASE_ADDR,
+&s->dra

[Qemu-devel] [PATCH v5 02/11] ARM: exynos4210: UART support

2011-12-23 Thread Evgeny Voevodin
From: Maksim Kozlov 

Add basic support of exynos4210 UART

Signed-off-by: Evgeny Voevodin 
---
 Makefile.target  |2 +-
 hw/exynos4210.c  |   24 ++
 hw/exynos4210.h  |9 +
 hw/exynos4210_uart.c |  670 ++
 4 files changed, 704 insertions(+), 1 deletions(-)
 create mode 100644 hw/exynos4210_uart.c

diff --git a/Makefile.target b/Makefile.target
index fc308bf..0246947 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -336,7 +336,7 @@ obj-arm-y = integratorcp.o versatilepb.o arm_pic.o 
arm_timer.o
 obj-arm-y += arm_boot.o pl011.o pl031.o pl050.o pl080.o pl110.o pl181.o pl190.o
 obj-arm-y += versatile_pci.o
 obj-arm-y += realview_gic.o realview.o arm_sysctl.o arm11mpcore.o a9mpcore.o
-obj-arm-y += exynos4_boards.o exynos4210.o
+obj-arm-y += exynos4_boards.o exynos4210.o exynos4210_uart.o
 obj-arm-y += arm_mptimer.o
 obj-arm-y += armv7m.o armv7m_nvic.o stellaris.o pl022.o stellaris_enet.o
 obj-arm-y += pl061.o
diff --git a/hw/exynos4210.c b/hw/exynos4210.c
index 62d0ad5..afef4cb 100644
--- a/hw/exynos4210.c
+++ b/hw/exynos4210.c
@@ -26,8 +26,19 @@
 #include "arm-misc.h"
 #include "exynos4210.h"
 
+
 #define EXYNOS4210_CHIPID_ADDR 0x1000
 
+/* UART's definitions */
+#define EXYNOS4210_UART0_BASE_ADDR 0x1380
+#define EXYNOS4210_UART1_BASE_ADDR 0x1381
+#define EXYNOS4210_UART2_BASE_ADDR 0x1382
+#define EXYNOS4210_UART3_BASE_ADDR 0x1383
+#define EXYNOS4210_UART0_FIFO_SIZE 256
+#define EXYNOS4210_UART1_FIFO_SIZE 64
+#define EXYNOS4210_UART2_FIFO_SIZE 16
+#define EXYNOS4210_UART3_FIFO_SIZE 16
+
 static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
 0x09, 0x00, 0x00, 0x00 };
 
@@ -99,5 +110,18 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
 memory_region_add_subregion(system_mem, EXYNOS4210_DRAM0_BASE_ADDR,
 &s->dram0_mem);
 
+/*** UARTs ***/
+exynos4210_uart_create(EXYNOS4210_UART0_BASE_ADDR,
+   EXYNOS4210_UART0_FIFO_SIZE, 0, NULL, NULL);
+
+exynos4210_uart_create(EXYNOS4210_UART1_BASE_ADDR,
+   EXYNOS4210_UART1_FIFO_SIZE, 1, NULL, NULL);
+
+exynos4210_uart_create(EXYNOS4210_UART2_BASE_ADDR,
+   EXYNOS4210_UART2_FIFO_SIZE, 2, NULL, NULL);
+
+exynos4210_uart_create(EXYNOS4210_UART3_BASE_ADDR,
+   EXYNOS4210_UART3_FIFO_SIZE, 3, NULL, NULL);
+
 return s;
 }
diff --git a/hw/exynos4210.h b/hw/exynos4210.h
index 56b1438..4dc119a 100644
--- a/hw/exynos4210.h
+++ b/hw/exynos4210.h
@@ -60,4 +60,13 @@ typedef struct Exynos4210State {
 Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
 unsigned long ram_size);
 
+/*
+ * exynos4210 UART
+ */
+DeviceState *exynos4210_uart_create(target_phys_addr_t addr,
+int fifo_size,
+int channel,
+CharDriverState *chr,
+qemu_irq irq);
+
 #endif /* EXYNOS4210_H_ */
diff --git a/hw/exynos4210_uart.c b/hw/exynos4210_uart.c
new file mode 100644
index 000..99fedc9
--- /dev/null
+++ b/hw/exynos4210_uart.c
@@ -0,0 +1,670 @@
+/*
+ *  exynos4210 UART Emulation
+ *
+ *  Copyright (C) 2011 Samsung Electronics Co Ltd.
+ *Maksim Kozlov, 
+ *
+ *  Created on: 07.2011
+ *
+ *
+ *  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.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see .
+ *
+ */
+
+#include "sysbus.h"
+#include "sysemu.h"
+#include "qemu-char.h"
+
+#include "exynos4210.h"
+
+#undef DEBUG_UART
+#undef DEBUG_UART_EXTEND
+#undef DEBUG_IRQ
+#undef DEBUG_Rx_DATA
+#undef DEBUG_Tx_DATA
+
+
+//#define DEBUG_UART
+//#define DEBUG_UART_EXTEND
+//#define DEBUG_IRQ
+//#define DEBUG_Rx_DATA
+//#define DEBUG_Tx_DATA
+
+
+#define  PRINT_DEBUG(fmt, args...)  \
+do {} while (0)
+#define  PRINT_DEBUG_EXTEND(fmt, args...) \
+do {} while (0)
+#define  PRINT_ERROR(fmt, args...) \
+do { \
+fprintf(stderr, "  [%s:%d]   "fmt, __func__, __LINE__, ##args); \
+} while (0)
+
+#ifdef DEBUG_UART
+
+#undef PRINT_DEBUG
+#define  PRINT_DEBUG(fmt, args...)  \
+do { \
+fprintf(stderr, "  [%s:%d]   "fmt, __func__, __LINE__, ##args); \
+} while (0)
+
+#ifdef DEBUG_UART_EXTEND
+
+#undef PRINT_DEBUG_EXTEND
+#define  PRINT_DEBUG_EXTE

[Qemu-devel] Use Clang to compile Qemu?

2011-12-23 Thread 陳韋任
Hi all,

  I am trying to build QEMU by using clang, but get error message below.

---
In file included from /z/tmp/chenwj/qemu-1.0/user-exec.c:21:
/z/tmp/chenwj/qemu-1.0/dyngen-exec.h:64:20: error: global register variables 
are not supported
register CPUState *env asm(AREG0);
   ^
1 warning and 1 error generated.
---

  Any idea on how to work around this? Thanks! :)

Regards,
chenwj

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



[Qemu-devel] [PATCH v5 04/11] ARM: exynos4210: IRQ subsystem support.

2011-12-23 Thread Evgeny Voevodin

Signed-off-by: Evgeny Voevodin 
---
 Makefile.target  |3 +-
 hw/exynos4210.c  |  179 ++-
 hw/exynos4210.h  |   46 +
 hw/exynos4210_combiner.c |  384 
 hw/exynos4210_gic.c  |  437 ++
 5 files changed, 1044 insertions(+), 5 deletions(-)
 create mode 100644 hw/exynos4210_combiner.c
 create mode 100644 hw/exynos4210_gic.c

diff --git a/Makefile.target b/Makefile.target
index 0246947..ccd1f79 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -336,7 +336,8 @@ obj-arm-y = integratorcp.o versatilepb.o arm_pic.o 
arm_timer.o
 obj-arm-y += arm_boot.o pl011.o pl031.o pl050.o pl080.o pl110.o pl181.o pl190.o
 obj-arm-y += versatile_pci.o
 obj-arm-y += realview_gic.o realview.o arm_sysctl.o arm11mpcore.o a9mpcore.o
-obj-arm-y += exynos4_boards.o exynos4210.o exynos4210_uart.o
+obj-arm-y += exynos4_boards.o exynos4210.o exynos4210_uart.o exynos4210_gic.o \
+ exynos4210_combiner.o
 obj-arm-y += arm_mptimer.o
 obj-arm-y += armv7m.o armv7m_nvic.o stellaris.o pl022.o stellaris_enet.o
 obj-arm-y += pl061.o
diff --git a/hw/exynos4210.c b/hw/exynos4210.c
index afef4cb..a85eb5d 100644
--- a/hw/exynos4210.c
+++ b/hw/exynos4210.c
@@ -23,6 +23,7 @@
 
 #include "boards.h"
 #include "sysemu.h"
+#include "sysbus.h"
 #include "arm-misc.h"
 #include "exynos4210.h"
 
@@ -38,10 +39,101 @@
 #define EXYNOS4210_UART1_FIFO_SIZE 64
 #define EXYNOS4210_UART2_FIFO_SIZE 16
 #define EXYNOS4210_UART3_FIFO_SIZE 16
+/* Interrupt Group of External Interrupt Combiner for UART */
+#define EXYNOS4210_UART_INT_GRP26
+
+/* External GIC */
+#define EXYNOS4210_EXT_GIC_CPU_BASE_ADDR0x1048
+#define EXYNOS4210_EXT_GIC_DIST_BASE_ADDR   0x1049
+
+/* Combiner */
+#define EXYNOS4210_EXT_COMBINER_BASE_ADDR   0x1044
+#define EXYNOS4210_INT_COMBINER_BASE_ADDR   0x10448000
 
 static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
 0x09, 0x00, 0x00, 0x00 };
 
+static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
+DeviceState *dev,
+int ext)
+{
+int n;
+int bit;
+int max;
+qemu_irq *irq;
+
+max = ext ? EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ :
+EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
+irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
+
+/*
+ * Some IRQs of Int/External Combiner are going to two Combiners groups,
+ * so let split them.
+ */
+for (n = 0; n < max; n++) {
+
+bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
+
+switch (n) {
+/* MDNIE_LCD1 INTG1*/
+case EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 0) ...
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 3):
+irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
+irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(0, bit + 4)]);
+continue;
+break;
+
+/* TMU INTG3*/
+case EXYNOS4210_COMBINER_GET_IRQ_NUM(3, 4):
+irq[n] =
+qemu_irq_split(qdev_get_gpio_in(dev, n),
+irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(2, bit)]);
+continue;
+break;
+
+/* LCD1 INTG12*/
+case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 0) ...
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 3):
+irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(11, bit + 
4)]);
+continue;
+
+/* Multi-Core Timer INTG12*/
+case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4) ...
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 8):
+irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
+irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
+continue;
+break;
+
+/* Multi-Core Timer INTG35*/
+case EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 4) ...
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 8):
+irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
+irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
+continue;
+break;
+
+/* Multi-Core Timer INTG51*/
+case EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 4) ...
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 8):
+irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
+irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
+continue;
+break;
+
+/* Multi-Core Timer INTG53*/
+case EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 4) ...
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 8):
+irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
+irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
+continue;
+break;
+}
+
+irq[n] = qdev_get_gpio_in(dev, n);
+}
+}
 
 Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
 un

[Qemu-devel] [PATCH v5 09/11] hw/lan9118: Add basic 16-bit mode support.

2011-12-23 Thread Evgeny Voevodin

Signed-off-by: Evgeny Voevodin 
---
 hw/lan9118.c |  115 +++---
 1 files changed, 110 insertions(+), 5 deletions(-)

diff --git a/hw/lan9118.c b/hw/lan9118.c
index 7e64c5d..21b7b23 100644
--- a/hw/lan9118.c
+++ b/hw/lan9118.c
@@ -212,6 +212,17 @@ typedef struct {
 int rxp_offset;
 int rxp_size;
 int rxp_pad;
+
+uint32_t write_word_prev_offset;
+uint32_t write_word_n;
+uint16_t write_word_l;
+uint16_t write_word_h;
+uint32_t read_word_prev_offset;
+uint32_t read_word_n;
+uint32_t read_long;
+
+uint32_t mode_16bit;
+
 } lan9118_state;
 
 static void lan9118_update(lan9118_state *s)
@@ -306,7 +317,7 @@ static void lan9118_reset(DeviceState *d)
 s->fifo_int = 0x4800;
 s->rx_cfg = 0;
 s->tx_cfg = 0;
-s->hw_cfg = 0x0005;
+s->hw_cfg = s->mode_16bit ? 0x0005 : 0x00050004;
 s->pmt_ctrl &= 0x45;
 s->gpio_cfg = 0;
 s->txp->fifo_used = 0;
@@ -345,6 +356,9 @@ static void lan9118_reset(DeviceState *d)
 s->mac_mii_data = 0;
 s->mac_flow = 0;
 
+s->read_word_n = 0;
+s->write_word_n = 0;
+
 phy_reset(s);
 
 s->eeprom_writable = 0;
@@ -900,7 +914,7 @@ static void lan9118_writel(void *opaque, target_phys_addr_t 
offset,
 {
 lan9118_state *s = (lan9118_state *)opaque;
 offset &= 0xff;
-
+
 //DPRINTF("Write reg 0x%02x = 0x%08x\n", (int)offset, val);
 if (offset >= 0x20 && offset < 0x40) {
 /* TX FIFO */
@@ -950,7 +964,7 @@ static void lan9118_writel(void *opaque, target_phys_addr_t 
offset,
 /* SRST */
 lan9118_reset(&s->busdev.qdev);
 } else {
-s->hw_cfg = val & 0x003f300;
+s->hw_cfg = (val & 0x003f300) | (s->hw_cfg & 0x4);
 }
 break;
 case CSR_RX_DP_CTRL:
@@ -1029,6 +1043,46 @@ static void lan9118_writel(void *opaque, 
target_phys_addr_t offset,
 lan9118_update(s);
 }
 
+static void lan9118_writew(void *opaque, target_phys_addr_t offset,
+   uint32_t val)
+{
+lan9118_state *s = (lan9118_state *)opaque;
+offset &= 0xff;
+
+if (s->write_word_prev_offset != (offset & ~0x3)) {
+/* New offset, reset word counter */
+s->write_word_n = 0;
+s->write_word_prev_offset = offset & ~0x3;
+}
+
+if (offset & 0x2) {
+s->write_word_h = val;
+} else {
+s->write_word_l = val;
+}
+
+//DPRINTF("Writew reg 0x%02x = 0x%08x\n", (int)offset, val);
+s->write_word_n++;
+if (s->write_word_n == 2) {
+s->write_word_n = 0;
+lan9118_writel(s, offset & ~3, s->write_word_l +
+(s->write_word_h << 16), 4);
+}
+}
+
+static void lan9118_16bit_mode_write(void *opaque, target_phys_addr_t offset,
+ uint64_t val, unsigned size)
+{
+switch (size) {
+case 2:
+return lan9118_writew(opaque, offset, (uint32_t)val);
+case 4:
+return lan9118_writel(opaque, offset, val, size);
+}
+
+hw_error("lan9118_write: Bad size 0x%x\n", size);
+}
+
 static uint64_t lan9118_readl(void *opaque, target_phys_addr_t offset,
   unsigned size)
 {
@@ -1065,7 +1119,7 @@ static uint64_t lan9118_readl(void *opaque, 
target_phys_addr_t offset,
 case CSR_TX_CFG:
 return s->tx_cfg;
 case CSR_HW_CFG:
-return s->hw_cfg | 0x4;
+return s->hw_cfg;
 case CSR_RX_DP_CTRL:
 return 0;
 case CSR_RX_FIFO_INF:
@@ -1103,12 +1157,60 @@ static uint64_t lan9118_readl(void *opaque, 
target_phys_addr_t offset,
 return 0;
 }
 
+static uint32_t lan9118_readw(void *opaque, target_phys_addr_t offset)
+{
+lan9118_state *s = (lan9118_state *)opaque;
+uint32_t val;
+
+if (s->read_word_prev_offset != (offset & ~0x3)) {
+/* New offset, reset word counter */
+s->read_word_n = 0;
+s->read_word_prev_offset = offset & ~0x3;
+}
+
+s->read_word_n++;
+if (s->read_word_n == 1) {
+s->read_long = lan9118_readl(s, offset & ~3, 4);
+} else {
+s->read_word_n = 0;
+}
+
+if (offset & 2) {
+val = s->read_long >> 16;
+} else {
+val = s->read_long & 0x;
+}
+
+//DPRINTF("Readw reg 0x%02x, val 0x%x\n", (int)offset, val);
+return val;
+}
+
+static uint64_t lan9118_16bit_mode_read(void *opaque, target_phys_addr_t 
offset,
+unsigned size)
+{
+switch (size) {
+case 2:
+return lan9118_readw(opaque, offset);
+case 4:
+return lan9118_readl(opaque, offset, size);
+}
+
+hw_error("lan9118_read: Bad size 0x%x\n", size);
+return 0;
+}
+
 static const MemoryRegionOps lan9118_mem_ops = {
 .read = lan9118_readl,
 .write = lan9118_writel,
 .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
+static const MemoryRegionOps lan9118_16bit_mem_ops = {
+.read = lan9118_16bit_mode_read,
+.write = lan9118_16bit_mode_wr

[Qemu-devel] [PATCH v5 06/11] hw/arm_boot.c: Extend secondary CPU bootloader.

2011-12-23 Thread Evgeny Voevodin
Secondary CPU bootloader enables interrupt and issues wfi until start address
is written to system controller. The position where to find this start
address is hardcoded to 0x1030. This commit extends bootloader for
secondary CPU to allow a target board to cpecify a position where
to find start address. If target board doesn't specify start address then
default 0x1030 is used.

Signed-off-by: Evgeny Voevodin 
---
 hw/arm-misc.h |1 +
 hw/arm_boot.c |   23 +++
 2 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/hw/arm-misc.h b/hw/arm-misc.h
index af403a1..6e8ae6b 100644
--- a/hw/arm-misc.h
+++ b/hw/arm-misc.h
@@ -31,6 +31,7 @@ struct arm_boot_info {
 const char *initrd_filename;
 target_phys_addr_t loader_start;
 target_phys_addr_t smp_loader_start;
+target_phys_addr_t smp_bootreg_addr;
 target_phys_addr_t smp_priv_base;
 int nb_cpus;
 int board_id;
diff --git a/hw/arm_boot.c b/hw/arm_boot.c
index 215d5de..700a89d 100644
--- a/hw/arm_boot.c
+++ b/hw/arm_boot.c
@@ -31,17 +31,17 @@ static uint32_t bootloader[] = {
 /* Entry point for secondary CPUs.  Enable interrupt controller and
Issue WFI until start address is written to system controller.  */
 static uint32_t smpboot[] = {
-  0xe59f0020, /* ldr r0, privbase */
-  0xe3a01001, /* mov r1, #1 */
-  0xe5801100, /* str r1, [r0, #0x100] */
-  0xe3a00201, /* mov r0, #0x1000 */
-  0xe3800030, /* orr r0, #0x30 */
+  0xe59f201c, /* ldr r2, privbase */
+  0xe59f001c, /* ldr r0, startaddr */
+  0xe3a01001, /* mov r1, #1 */
+  0xe5821100, /* str r1, [r2, #256] */
   0xe320f003, /* wfi */
   0xe5901000, /* ldr r1, [r0] */
   0xe1110001, /* tst r1, r1 */
   0x0afb, /* beq  */
   0xe12fff11, /* bx  r1 */
-  0 /* privbase: Private memory region base address.  */
+  0,  /* privbase: Private memory region base address.  */
+  0   /* bootreg: Boot register address is held here */
 };
 
 #define WRITE_WORD(p, value) do { \
@@ -179,6 +179,8 @@ static void do_cpu_reset(void *opaque)
 {
 CPUState *env = opaque;
 const struct arm_boot_info *info = env->boot_info;
+uint32_t smp_bootreg_addr = 0;
+target_phys_addr_t p = info->smp_bootreg_addr;
 
 cpu_reset(env);
 if (info) {
@@ -197,6 +199,7 @@ static void do_cpu_reset(void *opaque)
 info->loader_start);
 }
 } else {
+WRITE_WORD(p, smp_bootreg_addr);
 env->regs[15] = info->smp_loader_start;
 }
 }
@@ -272,8 +275,12 @@ void arm_load_kernel(CPUState *env, struct arm_boot_info 
*info)
 rom_add_blob_fixed("bootloader", bootloader, sizeof(bootloader),
info->loader_start);
 if (info->nb_cpus > 1) {
-smpboot[10] = info->smp_priv_base;
-for (n = 0; n < sizeof(smpboot) / 4; n++) {
+if (!info->smp_bootreg_addr) {
+info->smp_bootreg_addr = 0x1030;
+}
+smpboot[ARRAY_SIZE(smpboot) - 1] = info->smp_bootreg_addr;
+smpboot[ARRAY_SIZE(smpboot) - 2] = info->smp_priv_base;
+for (n = 0; n < ARRAY_SIZE(smpboot); n++) {
 smpboot[n] = tswap32(smpboot[n]);
 }
 rom_add_blob_fixed("smpboot", smpboot, sizeof(smpboot),
-- 
1.7.4.1




[Qemu-devel] [PATCH v5 05/11] ARM: exynos4210: PWM support.

2011-12-23 Thread Evgeny Voevodin

Signed-off-by: Evgeny Voevodin 
---
 Makefile.target |2 +-
 hw/exynos4210.c |   12 ++
 hw/exynos4210_pwm.c |  416 +++
 3 files changed, 429 insertions(+), 1 deletions(-)
 create mode 100644 hw/exynos4210_pwm.c

diff --git a/Makefile.target b/Makefile.target
index ccd1f79..70a2ef8 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -337,7 +337,7 @@ obj-arm-y += arm_boot.o pl011.o pl031.o pl050.o pl080.o 
pl110.o pl181.o pl190.o
 obj-arm-y += versatile_pci.o
 obj-arm-y += realview_gic.o realview.o arm_sysctl.o arm11mpcore.o a9mpcore.o
 obj-arm-y += exynos4_boards.o exynos4210.o exynos4210_uart.o exynos4210_gic.o \
- exynos4210_combiner.o
+ exynos4210_combiner.o exynos4210_pwm.o
 obj-arm-y += arm_mptimer.o
 obj-arm-y += armv7m.o armv7m_nvic.o stellaris.o pl022.o stellaris_enet.o
 obj-arm-y += pl061.o
diff --git a/hw/exynos4210.c b/hw/exynos4210.c
index a85eb5d..a350199 100644
--- a/hw/exynos4210.c
+++ b/hw/exynos4210.c
@@ -30,6 +30,9 @@
 
 #define EXYNOS4210_CHIPID_ADDR 0x1000
 
+/* PWM */
+#define EXYNOS4210_PWM_BASE_ADDR   0x139D
+
 /* UART's definitions */
 #define EXYNOS4210_UART0_BASE_ADDR 0x1380
 #define EXYNOS4210_UART1_BASE_ADDR 0x1381
@@ -277,6 +280,15 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
 memory_region_add_subregion(system_mem, EXYNOS4210_DRAM0_BASE_ADDR,
 &s->dram0_mem);
 
+/* PWM */
+sysbus_create_varargs("exynos4210.pwm", EXYNOS4210_PWM_BASE_ADDR,
+irq_table[exynos4210_get_irq(22, 0)],
+irq_table[exynos4210_get_irq(22, 1)],
+irq_table[exynos4210_get_irq(22, 2)],
+irq_table[exynos4210_get_irq(22, 3)],
+irq_table[exynos4210_get_irq(22, 4)],
+NULL);
+
 /*** UARTs ***/
 exynos4210_uart_create(EXYNOS4210_UART0_BASE_ADDR,
EXYNOS4210_UART0_FIFO_SIZE, 0, NULL,
diff --git a/hw/exynos4210_pwm.c b/hw/exynos4210_pwm.c
new file mode 100644
index 000..3253bfa
--- /dev/null
+++ b/hw/exynos4210_pwm.c
@@ -0,0 +1,416 @@
+/*
+ * Samsung exynos4210 Pulse Width Modulation Timer
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
+ * All rights reserved.
+ *
+ * Evgeny Voevodin 
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see .
+ */
+
+#include "sysbus.h"
+#include "qemu-timer.h"
+#include "qemu-common.h"
+#include "hw.h"
+
+#include "exynos4210.h"
+
+//#define DEBUG_PWM
+
+#ifdef DEBUG_PWM
+#define DPRINTF(fmt, ...) \
+do { fprintf(stdout, "PWM: [%24s:%5d] " fmt, __func__, __LINE__, \
+## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) do {} while (0)
+#endif
+
+#define EXYNOS4210_PWM_TIMERS_NUM  5
+#define EXYNOS4210_PWM_REG_MEM_SIZE0x50
+
+#define TCFG00x
+#define TCFG10x0004
+#define TCON 0x0008
+#define TCNTB0   0x000C
+#define TCMPB0   0x0010
+#define TCNTO0   0x0014
+#define TCNTB1   0x0018
+#define TCMPB1   0x001C
+#define TCNTO1   0x0020
+#define TCNTB2   0x0024
+#define TCMPB2   0x0028
+#define TCNTO2   0x002C
+#define TCNTB3   0x0030
+#define TCMPB3   0x0034
+#define TCNTO3   0x0038
+#define TCNTB4   0x003C
+#define TCNTO4   0x0040
+#define TINT_CSTAT   0x0044
+
+#define TCNTB(x)(0xC*x)
+#define TCMPB(x)(0xC*x+1)
+#define TCNTO(x)(0xC*x+2)
+
+#define GET_PRESCALER(reg, x)  ((reg&(0xFF<<(8*x)))>>8*x)
+#define GET_DIVIDER(reg, x)(1<<((0xF<<(4*x))>>(4*x)))
+
+/*
+ * Attention! Timer4 doesn't have OUTPUT_INVERTER,
+ * so Auto Reload bit is not accessible by macros!
+ */
+#define TCON_TIMER_BASE(x)  ((x ? 1 : 0)*4 + 4*x)
+#define TCON_TIMER_START(x) (1<<(TCON_TIMER_BASE(x) + 0))
+#define TCON_TIMER_MANUAL_UPD(x)(1<<(TCON_TIMER_BASE(x) + 1))
+#define TCON_TIMER_OUTPUT_INV(x)(1<<(TCON_TIMER_BASE(x) + 2))
+#define TCON_TIMER_AUTO_RELOAD(x)   (1<<(TCON_TIMER_BASE(x) + 3))
+#define TCON_TIMER4_AUTO_RELOAD (1<<22)
+
+#define TINT_CSTAT_STATUS(x)(1<<(5+x))
+#define TINT_CSTAT_ENABLE(x)(1 1) {
+s->timer[id].freq = 2400 /
+((GET_PRESCALER(s->

[Qemu-devel] [PATCH v5 08/11] hw/exynos4210.c: Boot secondary CPU.

2011-12-23 Thread Evgeny Voevodin

Signed-off-by: Evgeny Voevodin 
---
 hw/exynos4210.c |   14 ++
 hw/exynos4210.h |7 ++-
 hw/exynos4_boards.c |9 +
 3 files changed, 29 insertions(+), 1 deletions(-)

diff --git a/hw/exynos4210.c b/hw/exynos4210.c
index f958980..badeacf 100644
--- a/hw/exynos4210.c
+++ b/hw/exynos4210.c
@@ -283,6 +283,20 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
 memory_region_add_subregion(system_mem, EXYNOS4210_DRAM0_BASE_ADDR,
 &s->dram0_mem);
 
+/*
+ * Secondary CPU startup code will be placed here.
+ */
+memory_region_init_ram(&s->hack_mem, NULL, "exynos4210.hack", 0x1000);
+memory_region_add_subregion(system_mem, EXYNOS4210_SMP_BOOT_ADDR,
+&s->hack_mem);
+
+/*
+ * Hack: Map SECOND_CPU_BOOTREG, because it is in PMU USER5 register.
+ */
+memory_region_init_ram(&s->bootreg_mem, NULL, "exynos4210.bootreg", 0x4);
+memory_region_add_subregion(system_mem, EXYNOS4210_SECOND_CPU_BOOTREG,
+&s->bootreg_mem);
+
 /* PWM */
 sysbus_create_varargs("exynos4210.pwm", EXYNOS4210_PWM_BASE_ADDR,
 irq_table[exynos4210_get_irq(22, 0)],
diff --git a/hw/exynos4210.h b/hw/exynos4210.h
index b55d159..974d4c3 100644
--- a/hw/exynos4210.h
+++ b/hw/exynos4210.h
@@ -43,7 +43,11 @@
 #define EXYNOS4210_IRAM_BASE_ADDR   0x0202
 #define EXYNOS4210_IRAM_SIZE0x0002  /* 128 KB */
 
+/* Secondary CPU startup code is in IROM memory */
+#define EXYNOS4210_SMP_BOOT_ADDREXYNOS4210_IROM_BASE_ADDR
 #define EXYNOS4210_BASE_BOOT_ADDR   EXYNOS4210_DRAM0_BASE_ADDR
+/* Secondary CPU polling address to get loader start from */
+#define EXYNOS4210_SECOND_CPU_BOOTREG   0x10020814
 
 #define EXYNOS4210_SMP_PRIVATE_BASE_ADDR0x1050
 
@@ -87,7 +91,8 @@ typedef struct Exynos4210State {
 MemoryRegion irom_alias_mem;
 MemoryRegion dram0_mem;
 MemoryRegion dram1_mem;
-
+MemoryRegion hack_mem;
+MemoryRegion bootreg_mem;
 } Exynos4210State;
 
 Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
diff --git a/hw/exynos4_boards.c b/hw/exynos4_boards.c
index b710b06..5410a6f 100644
--- a/hw/exynos4_boards.c
+++ b/hw/exynos4_boards.c
@@ -52,6 +52,11 @@ static int exynos4_board_id[EXYNOS4_NUM_OF_BOARDS] = {
 [EXYNOS4_BOARD_SMDKC210] = 0xB16,
 };
 
+static int exynos4_board_smp_bootreg_addr[EXYNOS4_NUM_OF_BOARDS] = {
+[EXYNOS4_BOARD_NURI] = EXYNOS4210_SECOND_CPU_BOOTREG,
+[EXYNOS4_BOARD_SMDKC210] = EXYNOS4210_SECOND_CPU_BOOTREG,
+};
+
 static unsigned long exynos4_board_ram_size[EXYNOS4_NUM_OF_BOARDS] = {
 [EXYNOS4_BOARD_NURI] = 0x4000,
 [EXYNOS4_BOARD_SMDKC210] = 0x4000,
@@ -59,6 +64,7 @@ static unsigned long 
exynos4_board_ram_size[EXYNOS4_NUM_OF_BOARDS] = {
 
 static struct arm_boot_info exynos4_board_binfo = {
 .loader_start = EXYNOS4210_BASE_BOOT_ADDR,
+.smp_loader_start = EXYNOS4210_SMP_BOOT_ADDR,
 };
 
 static Exynos4210State *exynos4_boards_init_common(
@@ -69,10 +75,13 @@ static Exynos4210State *exynos4_boards_init_common(
 {
 exynos4_board_binfo.ram_size = exynos4_board_ram_size[board_type];
 exynos4_board_binfo.board_id = exynos4_board_id[board_type];
+exynos4_board_binfo.smp_bootreg_addr =
+exynos4_board_smp_bootreg_addr[board_type];
 exynos4_board_binfo.nb_cpus = smp_cpus;
 exynos4_board_binfo.kernel_filename = kernel_filename;
 exynos4_board_binfo.initrd_filename = initrd_filename;
 exynos4_board_binfo.kernel_cmdline = kernel_cmdline;
+exynos4_board_binfo.smp_priv_base = EXYNOS4210_SMP_PRIVATE_BASE_ADDR;
 
 PRINT_DEBUG("\n ram_size: %luMiB [0x%08lx]\n"
 " kernel_filename: %s\n"
-- 
1.7.4.1




[Qemu-devel] qemu on centos

2011-12-23 Thread Reed Kotler
We have been seeing various problems running qemu for MIPS target on 
Centos 5.

We are running linux user mode programs.

Qemu segfaults.

We recently tried upgrading to Centos 6 and the problem there is much 
worse, making it basically unusable.


The same programs have no problem when running on Ubuntu.

Is this a known problem?

Any ideas?

TIA.

Reed





Re: [Qemu-devel] Use Clang to compile Qemu?

2011-12-23 Thread David Turner
Some parts of QEMU (the JIT) require the use of a global register variable
to point to the "env" CPU state variable.

This feature is not supported by Clang (which is not very surprising given
that it uses LLVM as its backend, and LLVM explicitely doesn't support this)

Until the JIT is modified to not require this anymore, it is very unlikely
that Clang will be able to build QEMU.

There were previous discussions about such a change on this mailing list,
but I believe nobody started working on that change because many feared it
was a lot of work that would have a negative impact on performance (though
I think it was all conjecture, i.e. no one really tried it and got any real
data).

Please correct me if I'm wrong.

On Fri, Dec 23, 2011 at 1:00 PM, 陳韋任  wrote:

> Hi all,
>
>  I am trying to build QEMU by using clang, but get error message below.
>
> ---
> In file included from /z/tmp/chenwj/qemu-1.0/user-exec.c:21:
> /z/tmp/chenwj/qemu-1.0/dyngen-exec.h:64:20: error: global register
> variables are not supported
> register CPUState *env asm(AREG0);
>   ^
> 1 warning and 1 error generated.
> ---
>
>  Any idea on how to work around this? Thanks! :)
>
> Regards,
> chenwj
>
> --
> Wei-Ren Chen (陳韋任)
> Computer Systems Lab, Institute of Information Science,
> Academia Sinica, Taiwan (R.O.C.)
> Tel:886-2-2788-3799 #1667
> Homepage: http://people.cs.nctu.edu.tw/~chenwj
>
>


Re: [Qemu-devel] [target-mips] qemu on centos

2011-12-23 Thread Andreas Färber
Hi,

Am 23.12.2011 13:44, schrieb Reed Kotler:
> We have been seeing various problems running qemu for MIPS target on
> Centos 5.
> We are running linux user mode programs.
> 
> Qemu segfaults.
> 
> We recently tried upgrading to Centos 6 and the problem there is much
> worse, making it basically unusable.
> 
> The same programs have no problem when running on Ubuntu.

They likely are using different QEMU versions, and distros may have
different patches applied on top.
Please provide some more info on what version, what ABI (which
executable), what -cpu parameter (if any), etc. you are using. Does a
gdb backtrace indicate any QEMU function or is it from translated code?

For n64 there were some patches in need of testing, review and fixing.
[cc'ing Khansa]

For n32 there's signal handling missing. (openSUSE for one ignores the
build warning and provides it non the less.)

No known issues specific to o32 that I'm aware of, but the two Richards
had patches for some instructions. Shouldn't lead to segfaults though.

Regards,
Andreas

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



Re: [Qemu-devel] [PATCH] sheepdog: use coroutines

2011-12-23 Thread Christoph Hellwig
FYI, this causes segfaults when doing large streaming writes when
running against a sheepdog cluster which:

  a) has relatively fast SSDs

and

  b) uses buffered I/O.

Unfortunately I can't get a useful backtrace out of gdb.  When running just
this commit I at least get some debugging messages:

qemu-system-x86_64: failed to recv a rsp, Socket operation on non-socket
qemu-system-x86_64: failed to get the header, Socket operation on non-socket

but on least qemu these don't show up either.



Re: [Qemu-devel] [PATCH v2] w32: Build windows and console executables

2011-12-23 Thread Stefan Weil

Am 23.12.2011 03:31, schrieb TeLeMan:

On Thu, Dec 22, 2011 at 18:20, Stefan Weil  wrote:

System emulation executables with SDL are typically windows
executables. Sometimes console executables are more useful,
so create both variants if linker option -mwindows was detected.

v2:
This version uses QEMU_PROGW / QEMU_PROG instead of QEMU_PROG / 
QEMU_PROGC.


Signed-off-by: Stefan Weil 
---
 Makefile.target |   16 +++-
 1 files changed, 15 insertions(+), 1 deletions(-)

diff --git a/Makefile.target b/Makefile.target
index 3261383..0182e41 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -27,10 +27,17 @@ ifdef CONFIG_USER_ONLY
 QEMU_PROG=qemu-$(TARGET_ARCH2)
 else
 # system emulator name
+ifneq (,$(findstring -mwindows,$(LIBS)))
+# Terminate program name with a 'w' because the linker builds a 
windows executable.

+QEMU_PROGW=qemu-system-$(TARGET_ARCH2)w$(EXESUF)
+endif # windows executable
 QEMU_PROG=qemu-system-$(TARGET_ARCH2)$(EXESUF)
 endif

 PROGS=$(QEMU_PROG)
+ifdef QEMU_PROGW
+PROGS+=$(QEMU_PROGW)
+endif
 STPFILES=

 ifndef CONFIG_HAIKU
@@ -403,9 +410,16 @@ endif # CONFIG_LINUX_USER

 obj-$(CONFIG_GDBSTUB_XML) += gdbstub-xml.o

+ifdef QEMU_PROGW
+# The linker builds a windows executable. Make also a console 
executable.

+$(QEMU_PROGW): $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y)
+   $(call LINK,$^)
+$(QEMU_PROG): $(QEMU_PROGW)
+   $(call quiet-command,$(OBJCOPY) --subsystem console 
$(QEMU_PROGW) $(QEMU_PROG),"  GEN   $(TARGET_DIR)$(QEMU_PROG)")

+else
 $(QEMU_PROG): $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y)
   $(call LINK,$^)
-
+endif

 gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/scripts/feature_to_c.sh
   $(call quiet-command,rm -f $@ && $(SHELL) 
$(SRC_PATH)/scripts/feature_to_c.sh $@ $(TARGET_XML_FILES),"  GEN   
$(TARGET_DIR)$@")

--
1.7.2.5


Failed to make:
Makefile:416: *** multiple target patterns. Stop.


It works here (native and cross compilations) with MinGW,
so I have to guess and need your help.

This is the relevant code from Makefile.target when my patch was applied:

$(QEMU_PROGW): $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y)
$(call LINK,$^)
$(QEMU_PROG): $(QEMU_PROGW)
$(call quiet-command,$(OBJCOPY) --subsystem console 
$(QEMU_PROGW) $(QEMU_PROG),"  GEN   $(TARGET_DIR)$(QEMU_PROG)")


Line 416 is the 2nd line which was not changed by my patch.
It contains no target pattern at all.

Or do you have a different line counting caused by local
modifications or an older version of the QEMU sources?

Does an empty line between 2nd and 3rd line help?

Do you run a native or a cross compilation?

If native: which line endings do you use (CRLF or LF,
depends on git settings and MinGW mount options)?
Do you use Cygwin, MinGW or MinGW-w64?
Which make do you use?

Try to run make in verbose mode (make V=1).

This page describes the error which you got:
http://www.gnu.org/savannah-checkouts/gnu/make/manual/html_node/Error-Messages.html

Cheers,
Stefan Weil




Re: [Qemu-devel] [PATCH] Fix KVM dirty logging with 32-bit qemu & >32-bit physical addresses

2011-12-23 Thread Alexander Graf

On 23.12.2011, at 01:15, Benjamin Herrenschmidt wrote:

> We were using the wrong types in kvm_get_dirty_pages_log_range().
> 
> This would break dirty logging if the region to log resides at a
> physical address above 32-bit, which can happen with 64-bit guest
> but also with 32-bit guests that support >32-bit physical addresses
> such as ppc BookE.
> 
> Signed-off-by: Benjamin Herrenschmidt 

Acked-by: Alexander Graf 


Alex




Re: [Qemu-devel] [PATCH] PPC: Add description for the Freescale e500mc core.

2011-12-23 Thread Alexander Graf

On 22.12.2011, at 23:26, Scott Wood wrote:

> From: Varun Sethi 
> 
> This core is found on chips such as p4080, p3041, p2040, and p5020.
> 
> More needs to be done to make this viable for TCG (such as missing SPRs
> and instructions), but this suffices to get KVM running with appropriate
> kernel support.
> 
> Signed-off-by: Varun Sethi 
> [scottw...@freescale.com: tweak some flags]
> Signed-off-by: Scott Wood 

Thanks, applied to ppc-next.


Alex




[Qemu-devel] [Bug 907994] Re: converting VDI to IMG

2011-12-23 Thread Stefan Weil
Which version of QEMU do you use?
You can run QEMU with the original (=vdi) image (and use -snapshot, then QEMU 
won't write to the image), too.

A Windows blue screen or a start menu is a clear indication that the image 
conversion was successful.
Therefore I assume that this is not a QEMU related problem but a Windows 
problem.

Windows does not like when you move installation images from one machine to 
another
one with different hardware. That's what you do when you move from VirtualBox 
to QEMU.


** Changed in: qemu
   Status: New => Incomplete

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

Title:
  converting VDI to IMG

Status in QEMU:
  Incomplete

Bug description:
  I'm so close to moving away from VrtualBox to using Qemu.  However
  I've run into some issues converting my  existing virtual machine from
  VirtualBox to Qemu. I'm running Qemu on Fedora 16. I took my
  windows_xp.vdi and tried to convert it to qemu. The conversion goes
  well without any errors but then when I import the converted file to
  Qemu, it won't start. Here is the info on the file that I'm trying to
  convert:

  
  INFO
  =
  $ qemu-img info windows_xp.vdi 
  image: windows_xp.vdi
  file format: vdi
  virtual size: 21G (22020096000 bytes)
  disk size: 9.4G
  cluster_size: 1048576

  
  CONVERT COMMAND
  ==
  qemu-img convert windows_xp.vdi  windows_xp.img

  
  I created a new virtual machine  and used the converted machine created (from 
the above step).

  When I try to start the newly created virtual machine, it keeps
  failing. There is a blue screen of death that goes away too soon. and
  I'm stuck with the windows start menu "safe mode,  start normally "
  etc.. but no matter what I do I can't seem to start the vm.

  Any help much appreciated.

  Thanks

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



[Qemu-devel] [PATCH] virtio-blk: refuse SG_IO requests with scsi=off

2011-12-23 Thread Paolo Bonzini
QEMU does have a "scsi" option (to be used like -device
virtio-blk-pci,drive=foo,scsi=off).  However, it only
masks the feature bit, and does not reject the command
if a malicious guest disregards the feature bits and
issues a request.

Without this patch, using scsi=off does not protect you
from CVE-2011-4127.

Signed-off-by: Paolo Bonzini 
---
 hw/virtio-blk.c |6 ++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index b70d116..6cd3164 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -153,6 +153,12 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
 int status;
 int i;
 
+if ((req->dev->vdev.guest_features & (1 << VIRTIO_BLK_F_SCSI)) == 0) {
+virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP);
+g_free(req);
+return;
+}
+
 /*
  * We require at least one output segment each for the virtio_blk_outhdr
  * and the SCSI command block.
-- 
1.7.7.1




[Qemu-devel] [RFC 2/2] ahci: Add migration support for ICH9

2011-12-23 Thread Andreas Färber
Introduce generic vmstate_ahci and VMSTATE_AHCI macro.
Resolve name conflict and hook it up for ich9-ahci.

Signed-off-by: Andreas Färber 
Cc: Kevin Wolf 
Cc: Alexander Graf 
---
 hw/ide/ahci.c |   41 +
 hw/ide/ahci.h |   10 ++
 hw/ide/ich.c  |   11 ---
 3 files changed, 59 insertions(+), 3 deletions(-)

diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 51cb48b..7d1415b 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -1213,3 +1213,44 @@ void ahci_reset(void *opaque)
 ahci_reset_port(&d->ahci, i);
 }
 }
+
+const VMStateDescription vmstate_ahci_device = {
+.name = "ahci port",
+.version_id = 1,
+.fields = (VMStateField []) {
+VMSTATE_IDE_BUS(port, AHCIDevice),
+VMSTATE_UINT32(port_state, AHCIDevice),
+VMSTATE_UINT32(finished, AHCIDevice),
+VMSTATE_UINT32(port_regs.lst_addr, AHCIDevice),
+VMSTATE_UINT32(port_regs.lst_addr_hi, AHCIDevice),
+VMSTATE_UINT32(port_regs.fis_addr, AHCIDevice),
+VMSTATE_UINT32(port_regs.fis_addr_hi, AHCIDevice),
+VMSTATE_UINT32(port_regs.irq_stat, AHCIDevice),
+VMSTATE_UINT32(port_regs.irq_mask, AHCIDevice),
+VMSTATE_UINT32(port_regs.cmd, AHCIDevice),
+VMSTATE_UINT32(port_regs.tfdata, AHCIDevice),
+VMSTATE_UINT32(port_regs.sig, AHCIDevice),
+VMSTATE_UINT32(port_regs.scr_stat, AHCIDevice),
+VMSTATE_UINT32(port_regs.scr_ctl, AHCIDevice),
+VMSTATE_UINT32(port_regs.scr_err, AHCIDevice),
+VMSTATE_UINT32(port_regs.scr_act, AHCIDevice),
+VMSTATE_UINT32(port_regs.cmd_issue, AHCIDevice),
+VMSTATE_END_OF_LIST()
+},
+};
+
+const VMStateDescription vmstate_ahci = {
+.name = "ahci",
+.version_id = 1,
+.fields = (VMStateField []) {
+VMSTATE_STRUCT_ARRAY(dev, AHCIState, AHCI_MAX_PORTS, 0,
+ vmstate_ahci_device, AHCIDevice),
+VMSTATE_UINT32(control_regs.cap, AHCIState),
+VMSTATE_UINT32(control_regs.ghc, AHCIState),
+VMSTATE_UINT32(control_regs.irqstatus, AHCIState),
+VMSTATE_UINT32(control_regs.impl, AHCIState),
+VMSTATE_UINT32(control_regs.version, AHCIState),
+VMSTATE_UINT32(idp_index, AHCIState),
+VMSTATE_END_OF_LIST()
+},
+};
diff --git a/hw/ide/ahci.h b/hw/ide/ahci.h
index 4df7c2b..56ee621 100644
--- a/hw/ide/ahci.h
+++ b/hw/ide/ahci.h
@@ -306,6 +306,16 @@ typedef struct AHCIPCIState {
 AHCIState ahci;
 } AHCIPCIState;
 
+extern const VMStateDescription vmstate_ahci;
+
+#define VMSTATE_AHCI(_field, _state) {   \
+.name   = (stringify(_field)),   \
+.size   = sizeof(AHCIState), \
+.vmsd   = &vmstate_ahci, \
+.flags  = VMS_STRUCT,\
+.offset = vmstate_offset_value(_state, _field, AHCIState),   \
+}
+
 typedef struct NCQFrame {
 uint8_t fis_type;
 uint8_t c;
diff --git a/hw/ide/ich.c b/hw/ide/ich.c
index 3f7510f..851b6a9 100644
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@ -79,9 +79,14 @@
 #define ICH9_IDP_INDEX  0x10
 #define ICH9_IDP_INDEX_LOG2 0x04
 
-static const VMStateDescription vmstate_ahci = {
+static const VMStateDescription vmstate_ich9_ahci = {
 .name = "ahci",
-.unmigratable = 1,
+.version_id = 1,
+.fields = (VMStateField []) {
+VMSTATE_PCI_DEVICE(card, AHCIPCIState),
+VMSTATE_AHCI(ahci, AHCIPCIState),
+VMSTATE_END_OF_LIST()
+},
 };
 
 static int pci_ich9_ahci_init(PCIDevice *dev)
@@ -151,7 +156,7 @@ static PCIDeviceInfo ich_ahci_info[] = {
 .qdev.name= "ich9-ahci",
 .qdev.alias   = "ahci",
 .qdev.size= sizeof(AHCIPCIState),
-.qdev.vmsd= &vmstate_ahci,
+.qdev.vmsd= &vmstate_ich9_ahci,
 .init = pci_ich9_ahci_init,
 .exit = pci_ich9_uninit,
 .config_write = pci_ich9_write_config,
-- 
1.7.7




[Qemu-devel] [RFC 0/2] ahci: Make ich9-ahci migratable

2011-12-23 Thread Andreas Färber
Hello,

Since mjt asked about it, I'm posting a first draft of AHCI migration support
I recently pieced together. Some more pressing issues came up, including
ide-cd being broken with AHCI, so that I have hardly tested this yet.

The initial issue was that the ports were dynamically allocated in ich.c
and I did not find prior art dealing with that in VMState. I therefore
took the easy path of converting it to a statically-sized array, which is
a bit wasteful of course. Better suggestions welcome.

The second part then is a mostly mechanical addition of fields and structs
to VMState, possibly still incomplete.

Happy Holidays,

Andreas

Cc: Kevin Wolf 
Cc: Juan Quintela 

Cc: Alexander Graf 
Cc: Michael Tokarev 
Cc: Mark Langsdorf 

Andreas Färber (2):
  ahci: Refactor ports as a fixed-size array for VMState
  ahci: Add migration support for ICH9

 hw/ide/ahci.c |   44 ++--
 hw/ide/ahci.h |   12 +++-
 hw/ide/ich.c  |   11 ---
 3 files changed, 61 insertions(+), 6 deletions(-)

-- 
1.7.7




[Qemu-devel] [RFC 1/2] ahci: Refactor ports as a fixed-size array for VMState

2011-12-23 Thread Andreas Färber
It seems, VMState cannot handle a dynamically allocated array of
structs at this time.

Change AHCIState to use an AHCIDevice array of size AHCI_MAX_PORTS.
Of those 32, only 6 are being used for ich9.

Signed-off-by: Andreas Färber 
Cc: Juan Quintela 
Cc: Kevin Wolf 
Cc: Alexander Graf 
---
 hw/ide/ahci.c |3 +--
 hw/ide/ahci.h |2 +-
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 0af201d..51cb48b 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -1168,7 +1168,7 @@ void ahci_init(AHCIState *s, DeviceState *qdev, int ports)
 int i;
 
 s->ports = ports;
-s->dev = g_malloc0(sizeof(AHCIDevice) * ports);
+memset(s->dev, 0, sizeof(AHCIDevice) * ports);
 ahci_reg_init(s);
 /* XXX BAR size should be 1k, but that breaks, so bump it to 4k for now */
 memory_region_init_io(&s->mem, &ahci_mem_ops, s, "ahci", 
AHCI_MEM_BAR_SIZE);
@@ -1194,7 +1194,6 @@ void ahci_uninit(AHCIState *s)
 {
 memory_region_destroy(&s->mem);
 memory_region_destroy(&s->idp);
-g_free(s->dev);
 }
 
 void ahci_reset(void *opaque)
diff --git a/hw/ide/ahci.h b/hw/ide/ahci.h
index b223d2c..4df7c2b 100644
--- a/hw/ide/ahci.h
+++ b/hw/ide/ahci.h
@@ -291,7 +291,7 @@ struct AHCIDevice {
 };
 
 typedef struct AHCIState {
-AHCIDevice *dev;
+AHCIDevice dev[AHCI_MAX_PORTS];
 AHCIControlRegs control_regs;
 MemoryRegion mem;
 MemoryRegion idp;   /* Index-Data Pair I/O port space */
-- 
1.7.7




[Qemu-devel] [PATCH v2] vectorize is_dup_page

2011-12-23 Thread Paolo Bonzini
is_dup_page is already proceeding in 32-bit chunks.  Changing it
to 16 bytes using Altivec or SSE is easy.

Signed-off-by: Paolo Bonzini 
---
 arch_init.c |   28 ++--
 1 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/arch_init.c b/arch_init.c
index d4c92b0..8466ffb 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -94,14 +94,30 @@ const uint32_t arch_type = QEMU_ARCH;
 #define RAM_SAVE_FLAG_EOS  0x10
 #define RAM_SAVE_FLAG_CONTINUE 0x20
 
-static int is_dup_page(uint8_t *page, uint8_t ch)
+#ifdef __ALTIVEC__
+#include 
+#define VECTYPEvector unsigned char
+#define SPLAT(p)   vec_splat(vec_ld(0, p), 0)
+#define ALL_EQ(v1, v2) vec_all_eq(v1, v2)
+#elif defined __SSE2__
+#include 
+#define VECTYPE__m128i
+#define SPLAT(p)   _mm_set1_epi8(*(p))
+#define ALL_EQ(v1, v2) (_mm_movemask_epi8(_mm_cmpeq_epi8(v1, v2)) == 0x)
+#else
+#define VECTYPEunsigned long
+#define SPLAT(p)   (*(p) * (~0UL / 255))
+#define ALL_EQ(v1, v2) ((v1) == (v2))
+#endif
+
+static int is_dup_page(uint8_t *page)
 {
-uint32_t val = ch << 24 | ch << 16 | ch << 8 | ch;
-uint32_t *array = (uint32_t *)page;
+VECTYPE *p = (VECTYPE *)page;
+VECTYPE val = SPLAT(page);
 int i;
 
-for (i = 0; i < (TARGET_PAGE_SIZE / 4); i++) {
-if (array[i] != val) {
+for (i = 0; i < TARGET_PAGE_SIZE / sizeof(VECTYPE); i++) {
+if (!ALL_EQ(val, p[i])) {
 return 0;
 }
 }
@@ -135,7 +151,7 @@ static int ram_save_block(QEMUFile *f)
 
 p = block->host + offset;
 
-if (is_dup_page(p, *p)) {
+if (is_dup_page(p)) {
 qemu_put_be64(f, offset | cont | RAM_SAVE_FLAG_COMPRESS);
 if (!cont) {
 qemu_put_byte(f, strlen(block->idstr));
-- 
1.7.7.1




[Qemu-devel] [PATCH v2] prepare for future GPLv2+ relicensing

2011-12-23 Thread Paolo Bonzini
All files under GPLv2 will get GPLv2+ changes starting next Christmas.
Files that were only ever touched by Red Hat employees can be relicensed
now.

Signed-off-by: Paolo Bonzini 
---
 aio.c  |2 ++
 block-migration.c  |2 ++
 block/raw-posix-aio.h  |2 ++
 block/rbd.c|2 ++
 block/sheepdog.c   |3 +++
 buffered_file.c|2 ++
 compatfd.c |2 ++
 event_notifier.c   |4 ++--
 event_notifier.h   |   12 
 exec-obsolete.h|4 ++--
 hmp.c  |2 ++
 hw/ac97.c  |3 +++
 hw/acpi.c  |3 +++
 hw/acpi_piix4.c|3 +++
 hw/ads7846.c   |3 +++
 hw/apm.c   |3 +++
 hw/bitbang_i2c.c   |3 +++
 hw/bonito.c|3 +++
 hw/collie.c|3 +++
 hw/ds1338.c|3 +++
 hw/ecc.c   |3 +++
 hw/framebuffer.c   |3 +++
 hw/gumstix.c   |3 +++
 hw/ivshmem.c   |3 +++
 hw/kvmclock.c  |2 ++
 hw/lan9118.c   |3 +++
 hw/mainstone.c |3 +++
 hw/marvell_88w8618_audio.c |3 +++
 hw/max111x.c   |3 +++
 hw/mips_fulong2e.c |3 +++
 hw/msix.c  |3 +++
 hw/mst_fpga.c  |3 +++
 hw/musicpal.c  |3 +++
 hw/nand.c  |3 +++
 hw/pl031.c |2 ++
 hw/pxa2xx_keypad.c |3 +++
 hw/pxa2xx_lcd.c|3 +++
 hw/pxa2xx_mmci.c   |3 +++
 hw/pxa2xx_pcmcia.c |3 +++
 hw/smbios.c|2 ++
 hw/spitz.c |3 +++
 hw/ssi-sd.c|3 +++
 hw/ssi.c   |3 +++
 hw/strongarm.c |3 +++
 hw/tc6393xb.c  |3 +++
 hw/tosa.c  |3 +++
 hw/vexpress.c  |3 +++
 hw/vhost.c |3 +++
 hw/vhost_net.c |3 +++
 hw/virtio-pci.c|2 ++
 hw/virtio-serial-bus.c |3 +++
 hw/vt82c686.c  |3 +++
 hw/xen_backend.c   |3 +++
 hw/xen_disk.c  |3 +++
 hw/xen_nic.c   |3 +++
 hw/z2.c|3 +++
 iov.c  |3 +++
 memory.c   |2 ++
 migration-exec.c   |2 ++
 migration-fd.c |2 ++
 migration-tcp.c|2 ++
 migration-unix.c   |2 ++
 migration.c|2 ++
 module.c   |2 ++
 net/checksum.c |3 +++
 notify.c   |2 ++
 pflib.c|2 ++
 posix-aio-compat.c |2 ++
 qemu-tool.c|2 ++
 qmp.c  |2 ++
 xen-all.c  |2 ++
 xen-mapcache.c |2 ++
 xen-stub.c |2 ++
 73 files changed, 200 insertions(+), 4 deletions(-)

diff --git a/aio.c b/aio.c
index 1239ca7..93e3b8c 100644
--- a/aio.c
+++ b/aio.c
@@ -9,6 +9,8 @@
  * This work is licensed under the terms of the GNU GPL, version 2.  See
  * the COPYING file in the top-level directory.
  *
+ * Contributions after 2011-12-25 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
  */
 
 #include "qemu-common.h"
diff --git a/block-migration.c b/block-migration.c
index 2b7edbc..67276bf 100644
--- a/block-migration.c
+++ b/block-migration.c
@@ -9,6 +9,8 @@
  * This work is licensed under the terms of the GNU GPL, version 2.  See
  * the COPYING file in the top-level directory.
  *
+ * Contributions after 2011-12-25 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
  */
 
 #include "qemu-common.h"
diff --git a/block/raw-posix-aio.h b/block/raw-posix-aio.h
index dfc63b8..4151ae2 100644
--- a/block/raw-posix-aio.h
+++ b/block/raw-posix-aio.h
@@ -9,6 +9,8 @@
  * This work is licensed under the terms of the GNU GPL, version 2.  See
  * the COPYING file in the top-level directory.
  *
+ * Contributions after 2011-12-25 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
  */
 #ifndef QEMU_RAW_POSIX_AIO_H
 #define QEMU_RAW_POSIX_AIO_H
diff --git a/block/rbd.c b/block/rbd.c
index 7a2384c..3f5e50c 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -7,6 +7,8 @@
  * This work is licensed under the terms of the GNU GPL, version 2.  See
  * the COPYING file in the top-level directory.
  *
+ * Contributions after 2011-12-25 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
  */
 
 #include 
diff --git a/block/sheepdog.c b/block/sheepdog.c
index aa9707f..a9c714e 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -7,6 +7,9 @@
  *
  * You should have received a copy of the GNU General Public License
 

[Qemu-devel] [PULL 00/26] nbd refactoring, fully asynchronous operation, flushing, fixes

2011-12-23 Thread Paolo Bonzini
Anthony,

the following changes since commit 3799ce4ab64f578eb818689a276e4f0c73d01fb5:

  sd: Remember to reset .expecting_acmd on reset. (2011-12-21 05:04:21 +0100)

are available in the git repository at:
  git://github.com/bonzini/qemu.git nbd-for-anthony

Thanks,

Paolo

Chunyan Liu (1):
  Update ioctl order in nbd_init() to detect EBUSY

Paolo Bonzini (25):
  add qemu_send_full and qemu_recv_full
  sheepdog: move coroutine send/recv function to generic code
  nbd: switch to asynchronous operation
  nbd: split requests
  nbd: allow multiple in-flight requests
  nbd: fix error handling in the server
  nbd: add support for NBD_CMD_FLAG_FUA
  nbd: add support for NBD_CMD_FLUSH
  nbd: add support for NBD_CMD_TRIM
  qemu-nbd: remove offset argument to nbd_trip
  qemu-nbd: remove data_size argument to nbd_trip
  move corking functions to osdep.c
  qemu-nbd: simplify nbd_trip
  qemu-nbd: introduce nbd_do_send_reply
  qemu-nbd: more robust handling of invalid requests
  qemu-nbd: introduce nbd_do_receive_request
  qemu-nbd: introduce NBDExport
  qemu-nbd: introduce NBDRequest
  link the main loop and its dependencies into the tools
  qemu-nbd: use common main loop
  qemu-nbd: move client handling to nbd.c
  qemu-nbd: add client pointer to NBDRequest
  qemu-nbd: asynchronous operation
  qemu-nbd: throttle requests
  nbd: add myself as maintainer

 MAINTAINERS |7 +
 Makefile|5 +-
 Makefile.objs   |2 +-
 block/nbd.c |  319 ++---
 block/sheepdog.c|  250 +++--
 cutils.c|  111 +
 main-loop.h |6 +
 nbd.c   |  439 ---
 nbd.h   |   14 ++-
 os-posix.c  |   42 -
 os-win32.c  |5 -
 osdep.c |   76 +
 oslib-posix.c   |   43 +
 oslib-win32.c   |5 +
 qemu-common.h   |   34 
 qemu-coroutine-io.c |   96 +++
 qemu-nbd.c  |  120 +-
 qemu-tool.c |   42 +++---
 qemu_socket.h   |1 +
 19 files changed, 1087 insertions(+), 530 deletions(-)
 create mode 100644 qemu-coroutine-io.c

-- 
1.7.7.1




[Qemu-devel] [PATCH 01/26] add qemu_send_full and qemu_recv_full

2011-12-23 Thread Paolo Bonzini
Signed-off-by: Paolo Bonzini 
---
 osdep.c   |   67 +
 qemu-common.h |4 +++
 2 files changed, 71 insertions(+), 0 deletions(-)

diff --git a/osdep.c b/osdep.c
index 56e6963..70bad27 100644
--- a/osdep.c
+++ b/osdep.c
@@ -166,3 +166,70 @@ int qemu_accept(int s, struct sockaddr *addr, socklen_t 
*addrlen)
 
 return ret;
 }
+
+/*
+ * A variant of send(2) which handles partial write.
+ *
+ * Return the number of bytes transferred, which is only
+ * smaller than `count' if there is an error.
+ *
+ * This function won't work with non-blocking fd's.
+ * Any of the possibilities with non-bloking fd's is bad:
+ *   - return a short write (then name is wrong)
+ *   - busy wait adding (errno == EAGAIN) to the loop
+ */
+ssize_t qemu_send_full(int fd, const void *buf, size_t count, int flags)
+{
+ssize_t ret = 0;
+ssize_t total = 0;
+
+while (count) {
+ret = send(fd, buf, count, flags);
+if (ret < 0) {
+if (errno == EINTR) {
+continue;
+}
+break;
+}
+
+count -= ret;
+buf += ret;
+total += ret;
+}
+
+return total;
+}
+
+/*
+ * A variant of recv(2) which handles partial write.
+ *
+ * Return the number of bytes transferred, which is only
+ * smaller than `count' if there is an error.
+ *
+ * This function won't work with non-blocking fd's.
+ * Any of the possibilities with non-bloking fd's is bad:
+ *   - return a short write (then name is wrong)
+ *   - busy wait adding (errno == EAGAIN) to the loop
+ */
+ssize_t qemu_recv_full(int fd, void *buf, size_t count, int flags)
+{
+ssize_t ret = 0;
+ssize_t total = 0;
+
+while (count) {
+ret = qemu_recv(fd, buf, count, flags);
+if (ret <= 0) {
+if (ret < 0 && errno == EINTR) {
+continue;
+}
+break;
+}
+
+count -= ret;
+buf += ret;
+total += ret;
+}
+
+return total;
+}
+
diff --git a/qemu-common.h b/qemu-common.h
index b2de015..5c3f3af 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -173,6 +173,10 @@ void *qemu_oom_check(void *ptr);
 int qemu_open(const char *name, int flags, ...);
 ssize_t qemu_write_full(int fd, const void *buf, size_t count)
 QEMU_WARN_UNUSED_RESULT;
+ssize_t qemu_send_full(int fd, const void *buf, size_t count, int flags)
+QEMU_WARN_UNUSED_RESULT;
+ssize_t qemu_recv_full(int fd, const void *buf, size_t count, int flags)
+QEMU_WARN_UNUSED_RESULT;
 void qemu_set_cloexec(int fd);
 
 #ifndef _WIN32
-- 
1.7.7.1





[Qemu-devel] [PATCH 02/26] sheepdog: move coroutine send/recv function to generic code

2011-12-23 Thread Paolo Bonzini
Outside coroutines, avoid busy waiting on EAGAIN by temporarily
making the socket blocking.

The API of qemu_recvv/qemu_sendv is slightly different from
do_readv/do_writev because they do not handle coroutines.  It
returns the number of bytes written before encountering an
EAGAIN.  The specificity of yielding on EAGAIN is entirely in
qemu-coroutine.c.

Reviewed-by: MORITA Kazutaka 
Signed-off-by: Paolo Bonzini 
---
 Makefile.objs   |2 +-
 block/sheepdog.c|  230 +--
 cutils.c|  111 +
 qemu-common.h   |   32 +++-
 qemu-coroutine-io.c |   96 +
 5 files changed, 260 insertions(+), 211 deletions(-)
 create mode 100644 qemu-coroutine-io.c

diff --git a/Makefile.objs b/Makefile.objs
index f753d83..8813673 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -12,7 +12,7 @@ oslib-obj-$(CONFIG_POSIX) += oslib-posix.o qemu-thread-posix.o
 
 ###
 # coroutines
-coroutine-obj-y = qemu-coroutine.o qemu-coroutine-lock.o
+coroutine-obj-y = qemu-coroutine.o qemu-coroutine-lock.o qemu-coroutine-io.o
 ifeq ($(CONFIG_UCONTEXT_COROUTINE),y)
 coroutine-obj-$(CONFIG_POSIX) += coroutine-ucontext.o
 else
diff --git a/block/sheepdog.c b/block/sheepdog.c
index aa9707f..00ea5a0 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -443,129 +443,6 @@ static SheepdogAIOCB *sd_aio_setup(BlockDriverState *bs, 
QEMUIOVector *qiov,
 return acb;
 }
 
-#ifdef _WIN32
-
-struct msghdr {
-struct iovec *msg_iov;
-size_tmsg_iovlen;
-};
-
-static ssize_t sendmsg(int s, const struct msghdr *msg, int flags)
-{
-size_t size = 0;
-char *buf, *p;
-int i, ret;
-
-/* count the msg size */
-for (i = 0; i < msg->msg_iovlen; i++) {
-size += msg->msg_iov[i].iov_len;
-}
-buf = g_malloc(size);
-
-p = buf;
-for (i = 0; i < msg->msg_iovlen; i++) {
-memcpy(p, msg->msg_iov[i].iov_base, msg->msg_iov[i].iov_len);
-p += msg->msg_iov[i].iov_len;
-}
-
-ret = send(s, buf, size, flags);
-
-g_free(buf);
-return ret;
-}
-
-static ssize_t recvmsg(int s, struct msghdr *msg, int flags)
-{
-size_t size = 0;
-char *buf, *p;
-int i, ret;
-
-/* count the msg size */
-for (i = 0; i < msg->msg_iovlen; i++) {
-size += msg->msg_iov[i].iov_len;
-}
-buf = g_malloc(size);
-
-ret = qemu_recv(s, buf, size, flags);
-if (ret < 0) {
-goto out;
-}
-
-p = buf;
-for (i = 0; i < msg->msg_iovlen; i++) {
-memcpy(msg->msg_iov[i].iov_base, p, msg->msg_iov[i].iov_len);
-p += msg->msg_iov[i].iov_len;
-}
-out:
-g_free(buf);
-return ret;
-}
-
-#endif
-
-/*
- * Send/recv data with iovec buffers
- *
- * This function send/recv data from/to the iovec buffer directly.
- * The first `offset' bytes in the iovec buffer are skipped and next
- * `len' bytes are used.
- *
- * For example,
- *
- *   do_send_recv(sockfd, iov, len, offset, 1);
- *
- * is equals to
- *
- *   char *buf = malloc(size);
- *   iov_to_buf(iov, iovcnt, buf, offset, size);
- *   send(sockfd, buf, size, 0);
- *   free(buf);
- */
-static int do_send_recv(int sockfd, struct iovec *iov, int len, int offset,
-int write)
-{
-struct msghdr msg;
-int ret, diff;
-
-memset(&msg, 0, sizeof(msg));
-msg.msg_iov = iov;
-msg.msg_iovlen = 1;
-
-len += offset;
-
-while (iov->iov_len < len) {
-len -= iov->iov_len;
-
-iov++;
-msg.msg_iovlen++;
-}
-
-diff = iov->iov_len - len;
-iov->iov_len -= diff;
-
-while (msg.msg_iov->iov_len <= offset) {
-offset -= msg.msg_iov->iov_len;
-
-msg.msg_iov++;
-msg.msg_iovlen--;
-}
-
-msg.msg_iov->iov_base = (char *) msg.msg_iov->iov_base + offset;
-msg.msg_iov->iov_len -= offset;
-
-if (write) {
-ret = sendmsg(sockfd, &msg, 0);
-} else {
-ret = recvmsg(sockfd, &msg, 0);
-}
-
-msg.msg_iov->iov_base = (char *) msg.msg_iov->iov_base - offset;
-msg.msg_iov->iov_len += offset;
-
-iov->iov_len += diff;
-return ret;
-}
-
 static int connect_to_sdog(const char *addr, const char *port)
 {
 char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
@@ -618,83 +495,19 @@ success:
 return fd;
 }
 
-static int do_readv_writev(int sockfd, struct iovec *iov, int len,
-   int iov_offset, int write)
-{
-int ret;
-again:
-ret = do_send_recv(sockfd, iov, len, iov_offset, write);
-if (ret < 0) {
-if (errno == EINTR) {
-goto again;
-}
-if (errno == EAGAIN) {
-if (qemu_in_coroutine()) {
-qemu_coroutine_yield();
-}
-goto again;
-}
-error_report("failed to recv a rsp, %s", strerror(errno));
-return 1;
-}
-
-iov_offset += ret;
-len -= ret;
-if (len) {
-

[Qemu-devel] [PATCH 03/26] nbd: switch to asynchronous operation

2011-12-23 Thread Paolo Bonzini
Signed-off-by: Paolo Bonzini 
---
 block/nbd.c |  188 ++
 nbd.c   |8 +++
 2 files changed, 131 insertions(+), 65 deletions(-)

diff --git a/block/nbd.c b/block/nbd.c
index 95212da..bea7acd 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -47,13 +47,17 @@
 #endif
 
 typedef struct BDRVNBDState {
-CoMutex lock;
 int sock;
 uint32_t nbdflags;
 off_t size;
 size_t blocksize;
 char *export_name; /* An NBD server may export several devices */
 
+CoMutex mutex;
+Coroutine *coroutine;
+
+struct nbd_reply reply;
+
 /* If it begins with  '/', this is a UNIX domain socket. Otherwise,
  * it's a string of the form :port
  */
@@ -106,6 +110,95 @@ out:
 return err;
 }
 
+static void nbd_coroutine_start(BDRVNBDState *s, struct nbd_request *request)
+{
+qemu_co_mutex_lock(&s->mutex);
+s->coroutine = qemu_coroutine_self();
+request->handle = (uint64_t)(intptr_t)s;
+}
+
+static int nbd_have_request(void *opaque)
+{
+BDRVNBDState *s = opaque;
+
+return !!s->coroutine;
+}
+
+static void nbd_reply_ready(void *opaque)
+{
+BDRVNBDState *s = opaque;
+
+if (s->reply.handle == 0) {
+/* No reply already in flight.  Fetch a header.  */
+if (nbd_receive_reply(s->sock, &s->reply) < 0) {
+s->reply.handle = 0;
+}
+}
+
+/* There's no need for a mutex on the receive side, because the
+ * handler acts as a synchronization point and ensures that only
+ * one coroutine is called until the reply finishes.  */
+if (s->coroutine) {
+qemu_coroutine_enter(s->coroutine, NULL);
+}
+}
+
+static void nbd_restart_write(void *opaque)
+{
+BDRVNBDState *s = opaque;
+qemu_coroutine_enter(s->coroutine, NULL);
+}
+
+static int nbd_co_send_request(BDRVNBDState *s, struct nbd_request *request,
+   struct iovec *iov, int offset)
+{
+int rc, ret;
+
+qemu_aio_set_fd_handler(s->sock, nbd_reply_ready, nbd_restart_write,
+nbd_have_request, NULL, s);
+rc = nbd_send_request(s->sock, request);
+if (rc != -1 && iov) {
+ret = qemu_co_sendv(s->sock, iov, request->len, offset);
+if (ret != request->len) {
+errno = -EIO;
+rc = -1;
+}
+}
+qemu_aio_set_fd_handler(s->sock, nbd_reply_ready, NULL,
+nbd_have_request, NULL, s);
+return rc;
+}
+
+static void nbd_co_receive_reply(BDRVNBDState *s, struct nbd_request *request,
+ struct nbd_reply *reply,
+ struct iovec *iov, int offset)
+{
+int ret;
+
+/* Wait until we're woken up by the read handler.  */
+qemu_coroutine_yield();
+*reply = s->reply;
+if (reply->handle != request->handle) {
+reply->error = EIO;
+} else {
+if (iov && reply->error == 0) {
+ret = qemu_co_recvv(s->sock, iov, request->len, offset);
+if (ret != request->len) {
+reply->error = EIO;
+}
+}
+
+/* Tell the read handler to read another header.  */
+s->reply.handle = 0;
+}
+}
+
+static void nbd_coroutine_end(BDRVNBDState *s, struct nbd_request *request)
+{
+s->coroutine = NULL;
+qemu_co_mutex_unlock(&s->mutex);
+}
+
 static int nbd_establish_connection(BlockDriverState *bs)
 {
 BDRVNBDState *s = bs->opaque;
@@ -135,8 +228,11 @@ static int nbd_establish_connection(BlockDriverState *bs)
 return -errno;
 }
 
-/* Now that we're connected, set the socket to be non-blocking */
+/* Now that we're connected, set the socket to be non-blocking and
+ * kick the reply mechanism.  */
 socket_set_nonblock(sock);
+qemu_aio_set_fd_handler(s->sock, nbd_reply_ready, NULL,
+nbd_have_request, NULL, s);
 
 s->sock = sock;
 s->size = size;
@@ -152,11 +248,11 @@ static void nbd_teardown_connection(BlockDriverState *bs)
 struct nbd_request request;
 
 request.type = NBD_CMD_DISC;
-request.handle = (uint64_t)(intptr_t)bs;
 request.from = 0;
 request.len = 0;
 nbd_send_request(s->sock, &request);
 
+qemu_aio_set_fd_handler(s->sock, NULL, NULL, NULL, NULL, NULL);
 closesocket(s->sock);
 }
 
@@ -165,6 +261,8 @@ static int nbd_open(BlockDriverState *bs, const char* 
filename, int flags)
 BDRVNBDState *s = bs->opaque;
 int result;
 
+qemu_co_mutex_init(&s->mutex);
+
 /* Pop the config into our state object. Exit if invalid. */
 result = nbd_config(s, filename, flags);
 if (result != 0) {
@@ -176,90 +274,50 @@ static int nbd_open(BlockDriverState *bs, const char* 
filename, int flags)
  */
 result = nbd_establish_connection(bs);
 
-qemu_co_mutex_init(&s->lock);
 return result;
 }
 
-static int nbd_read(BlockDriverState *bs, int64_t sector_num,
-uint8_t *buf, int nb_sectors)
+st

[Qemu-devel] [PATCH 04/26] nbd: split requests

2011-12-23 Thread Paolo Bonzini
qemu-nbd has a limit of slightly less than 1M per request.  Work
around this in the nbd block driver.

Signed-off-by: Paolo Bonzini 
---
 block/nbd.c |   52 ++--
 1 files changed, 46 insertions(+), 6 deletions(-)

diff --git a/block/nbd.c b/block/nbd.c
index bea7acd..9d661c1 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -277,8 +277,9 @@ static int nbd_open(BlockDriverState *bs, const char* 
filename, int flags)
 return result;
 }
 
-static int nbd_co_readv(BlockDriverState *bs, int64_t sector_num,
-int nb_sectors, QEMUIOVector *qiov)
+static int nbd_co_readv_1(BlockDriverState *bs, int64_t sector_num,
+  int nb_sectors, QEMUIOVector *qiov,
+  int offset)
 {
 BDRVNBDState *s = bs->opaque;
 struct nbd_request request;
@@ -292,15 +293,16 @@ static int nbd_co_readv(BlockDriverState *bs, int64_t 
sector_num,
 if (nbd_co_send_request(s, &request, NULL, 0) == -1) {
 reply.error = errno;
 } else {
-nbd_co_receive_reply(s, &request, &reply, qiov->iov, 0);
+nbd_co_receive_reply(s, &request, &reply, qiov->iov, offset);
 }
 nbd_coroutine_end(s, &request);
 return -reply.error;
 
 }
 
-static int nbd_co_writev(BlockDriverState *bs, int64_t sector_num,
- int nb_sectors, QEMUIOVector *qiov)
+static int nbd_co_writev_1(BlockDriverState *bs, int64_t sector_num,
+   int nb_sectors, QEMUIOVector *qiov,
+   int offset)
 {
 BDRVNBDState *s = bs->opaque;
 struct nbd_request request;
@@ -311,7 +313,7 @@ static int nbd_co_writev(BlockDriverState *bs, int64_t 
sector_num,
 request.len = nb_sectors * 512;
 
 nbd_coroutine_start(s, &request);
-if (nbd_co_send_request(s, &request, qiov->iov, 0) == -1) {
+if (nbd_co_send_request(s, &request, qiov->iov, offset) == -1) {
 reply.error = errno;
 } else {
 nbd_co_receive_reply(s, &request, &reply, NULL, 0);
@@ -320,6 +322,44 @@ static int nbd_co_writev(BlockDriverState *bs, int64_t 
sector_num,
 return -reply.error;
 }
 
+/* qemu-nbd has a limit of slightly less than 1M per request.  Try to
+ * remain aligned to 4K. */
+#define NBD_MAX_SECTORS 2040
+
+static int nbd_co_readv(BlockDriverState *bs, int64_t sector_num,
+int nb_sectors, QEMUIOVector *qiov)
+{
+int offset = 0;
+int ret;
+while (nb_sectors > NBD_MAX_SECTORS) {
+ret = nbd_co_readv_1(bs, sector_num, NBD_MAX_SECTORS, qiov, offset);
+if (ret < 0) {
+return ret;
+}
+offset += NBD_MAX_SECTORS * 512;
+sector_num += NBD_MAX_SECTORS;
+nb_sectors -= NBD_MAX_SECTORS;
+}
+return nbd_co_readv_1(bs, sector_num, nb_sectors, qiov, offset);
+}
+
+static int nbd_co_writev(BlockDriverState *bs, int64_t sector_num,
+ int nb_sectors, QEMUIOVector *qiov)
+{
+int offset = 0;
+int ret;
+while (nb_sectors > NBD_MAX_SECTORS) {
+ret = nbd_co_writev_1(bs, sector_num, NBD_MAX_SECTORS, qiov, offset);
+if (ret < 0) {
+return ret;
+}
+offset += NBD_MAX_SECTORS * 512;
+sector_num += NBD_MAX_SECTORS;
+nb_sectors -= NBD_MAX_SECTORS;
+}
+return nbd_co_writev_1(bs, sector_num, nb_sectors, qiov, offset);
+}
+
 static void nbd_close(BlockDriverState *bs)
 {
 BDRVNBDState *s = bs->opaque;
-- 
1.7.7.1





[Qemu-devel] [PATCH 12/26] qemu-nbd: remove data_size argument to nbd_trip

2011-12-23 Thread Paolo Bonzini
The size of the buffer is in practice part of the protocol.

Signed-off-by: Paolo Bonzini 
---
 nbd.c  |6 +++---
 nbd.h  |4 +++-
 qemu-nbd.c |4 +---
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/nbd.c b/nbd.c
index 1df2b91..d8cc331 100644
--- a/nbd.c
+++ b/nbd.c
@@ -585,7 +585,7 @@ static int nbd_send_reply(int csock, struct nbd_reply 
*reply)
 
 int nbd_trip(BlockDriverState *bs, int csock, off_t size,
  uint64_t dev_offset, uint32_t nbdflags,
- uint8_t *data, int data_size)
+ uint8_t *data)
 {
 struct nbd_request request;
 struct nbd_reply reply;
@@ -596,9 +596,9 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size,
 if (nbd_receive_request(csock, &request) == -1)
 return -1;
 
-if (request.len + NBD_REPLY_SIZE > data_size) {
+if (request.len + NBD_REPLY_SIZE > NBD_BUFFER_SIZE) {
 LOG("len (%u) is larger than max len (%u)",
-request.len + NBD_REPLY_SIZE, data_size);
+request.len + NBD_REPLY_SIZE, NBD_BUFFER_SIZE);
 errno = EINVAL;
 return -1;
 }
diff --git a/nbd.h b/nbd.h
index ebdb2db..dbc4c0d 100644
--- a/nbd.h
+++ b/nbd.h
@@ -57,6 +57,8 @@ enum {
 
 #define NBD_DEFAULT_PORT   10809
 
+#define NBD_BUFFER_SIZE (1024*1024)
+
 size_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read);
 int tcp_socket_outgoing(const char *address, uint16_t port);
 int tcp_socket_incoming(const char *address, uint16_t port);
@@ -72,7 +74,7 @@ int nbd_init(int fd, int csock, uint32_t flags, off_t size, 
size_t blocksize);
 int nbd_send_request(int csock, struct nbd_request *request);
 int nbd_receive_reply(int csock, struct nbd_reply *reply);
 int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset,
- uint32_t nbdflags, uint8_t *data, int data_size);
+ uint32_t nbdflags, uint8_t *data);
 int nbd_client(int fd);
 int nbd_disconnect(int fd);
 
diff --git a/qemu-nbd.c b/qemu-nbd.c
index f9ee9c5..d662268 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -35,8 +35,6 @@
 
 #define SOCKET_PATH"/var/lock/qemu-nbd-%s"
 
-#define NBD_BUFFER_SIZE (1024*1024)
-
 static int sigterm_wfd;
 static int verbose;
 static char *device;
@@ -541,7 +539,7 @@ int main(int argc, char **argv)
 for (i = 1; i < nb_fds && ret; i++) {
 if (FD_ISSET(sharing_fds[i], &fds)) {
 if (nbd_trip(bs, sharing_fds[i], fd_size, dev_offset,
-nbdflags, data, NBD_BUFFER_SIZE) != 0) {
+ nbdflags, data) != 0) {
 close(sharing_fds[i]);
 nb_fds--;
 sharing_fds[i] = sharing_fds[nb_fds];
-- 
1.7.7.1





[Qemu-devel] [PATCH 19/26] qemu-nbd: introduce NBDRequest

2011-12-23 Thread Paolo Bonzini
Move the buffer from NBDExport to a new structure, so that it will be
possible to have multiple in-flight requests for the same export
(and for the same client too---we get that for free).

Signed-off-by: Paolo Bonzini 
---
 nbd.c |   65 +++--
 1 files changed, 51 insertions(+), 14 deletions(-)

diff --git a/nbd.c b/nbd.c
index 8d2a3bc..82eb98d 100644
--- a/nbd.c
+++ b/nbd.c
@@ -36,6 +36,7 @@
 #endif
 
 #include "qemu_socket.h"
+#include "qemu-queue.h"
 
 //#define DEBUG_NBD
 
@@ -584,29 +585,60 @@ static int nbd_send_reply(int csock, struct nbd_reply 
*reply)
 return 0;
 }
 
+typedef struct NBDRequest NBDRequest;
+
+struct NBDRequest {
+QSIMPLEQ_ENTRY(NBDRequest) entry;
+uint8_t *data;
+};
+
 struct NBDExport {
 BlockDriverState *bs;
 off_t dev_offset;
 off_t size;
-uint8_t *data;
 uint32_t nbdflags;
+QSIMPLEQ_HEAD(, NBDRequest) requests;
 };
 
+static NBDRequest *nbd_request_get(NBDExport *exp)
+{
+NBDRequest *req;
+if (QSIMPLEQ_EMPTY(&exp->requests)) {
+req = g_malloc0(sizeof(NBDRequest));
+req->data = qemu_blockalign(exp->bs, NBD_BUFFER_SIZE);
+} else {
+req = QSIMPLEQ_FIRST(&exp->requests);
+QSIMPLEQ_REMOVE_HEAD(&exp->requests, entry);
+}
+return req;
+}
+
+static void nbd_request_put(NBDExport *exp, NBDRequest *req)
+{
+QSIMPLEQ_INSERT_HEAD(&exp->requests, req, entry);
+}
+
 NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset,
   off_t size, uint32_t nbdflags)
 {
 NBDExport *exp = g_malloc0(sizeof(NBDExport));
+QSIMPLEQ_INIT(&exp->requests);
 exp->bs = bs;
 exp->dev_offset = dev_offset;
 exp->nbdflags = nbdflags;
 exp->size = size == -1 ? exp->bs->total_sectors * 512 : size;
-exp->data = qemu_blockalign(exp->bs, NBD_BUFFER_SIZE);
 return exp;
 }
 
 void nbd_export_close(NBDExport *exp)
 {
-qemu_vfree(exp->data);
+while (!QSIMPLEQ_EMPTY(&exp->requests)) {
+NBDRequest *first = QSIMPLEQ_FIRST(&exp->requests);
+QSIMPLEQ_REMOVE_HEAD(&exp->requests, entry);
+qemu_vfree(first->data);
+g_free(first);
+}
+
 bdrv_close(exp->bs);
 g_free(exp);
 }
@@ -682,15 +714,17 @@ out:
 
 int nbd_trip(NBDExport *exp, int csock)
 {
+NBDRequest *req = nbd_request_get(exp);
 struct nbd_request request;
 struct nbd_reply reply;
+int rc = -1;
 int ret;
 
 TRACE("Reading request.");
 
-ret = nbd_do_receive_request(csock, &request, exp->data);
+ret = nbd_do_receive_request(csock, &request, req->data);
 if (ret == -EIO) {
-return -1;
+goto out;
 }
 
 reply.handle = request.handle;
@@ -715,7 +749,7 @@ int nbd_trip(NBDExport *exp, int csock)
 TRACE("Request type is READ");
 
 ret = bdrv_read(exp->bs, (request.from + exp->dev_offset) / 512,
-exp->data, request.len / 512);
+req->data, request.len / 512);
 if (ret < 0) {
 LOG("reading from file failed");
 reply.error = -ret;
@@ -723,8 +757,8 @@ int nbd_trip(NBDExport *exp, int csock)
 }
 
 TRACE("Read %u byte(s)", request.len);
-if (nbd_do_send_reply(csock, &reply, exp->data, request.len) < 0)
-return -1;
+if (nbd_do_send_reply(csock, &reply, req->data, request.len) < 0)
+goto out;
 break;
 case NBD_CMD_WRITE:
 TRACE("Request type is WRITE");
@@ -738,7 +772,7 @@ int nbd_trip(NBDExport *exp, int csock)
 TRACE("Writing to device");
 
 ret = bdrv_write(exp->bs, (request.from + exp->dev_offset) / 512,
- exp->data, request.len / 512);
+ req->data, request.len / 512);
 if (ret < 0) {
 LOG("writing to file failed");
 reply.error = -ret;
@@ -755,7 +789,7 @@ int nbd_trip(NBDExport *exp, int csock)
 }
 
 if (nbd_do_send_reply(csock, &reply, NULL, 0) < 0)
-return -1;
+goto out;
 break;
 case NBD_CMD_DISC:
 TRACE("Request type is DISCONNECT");
@@ -771,7 +805,7 @@ int nbd_trip(NBDExport *exp, int csock)
 }
 
 if (nbd_do_send_reply(csock, &reply, NULL, 0) < 0)
-return -1;
+goto out;
 break;
 case NBD_CMD_TRIM:
 TRACE("Request type is TRIM");
@@ -782,7 +816,7 @@ int nbd_trip(NBDExport *exp, int csock)
 reply.error = -ret;
 }
 if (nbd_do_send_reply(csock, &reply, NULL, 0) < 0)
-return -1;
+goto out;
 break;
 default:
 LOG("invalid request type (%u) received", request.type);
@@ -790,13 +824,16 @@ int nbd_trip(NBDExport *exp, int csock)
 reply.error = -EINVAL;
 error_reply:
 if (nbd_do_send_reply(csock, &reply, NULL, 0) == -1)
-return -1;
+goto out;
 break;
 }
 
 TRAC

[Qemu-devel] [PATCH 25/26] qemu-nbd: throttle requests

2011-12-23 Thread Paolo Bonzini
Limiting the number of in-flight requests is implemented very simply
with a can_read callback.  It does not require a semaphore, unlike the
client side in block/nbd.c, because we can throttle directly the creation
of coroutines.  The client side can have a coroutine created at any time
when an I/O request is made.

Signed-off-by: Paolo Bonzini 
---
 nbd.c |   25 ++---
 1 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/nbd.c b/nbd.c
index 6d7d1f8..567e94e 100644
--- a/nbd.c
+++ b/nbd.c
@@ -587,6 +587,8 @@ static int nbd_send_reply(int csock, struct nbd_reply 
*reply)
 return 0;
 }
 
+#define MAX_NBD_REQUESTS 16
+
 typedef struct NBDRequest NBDRequest;
 
 struct NBDRequest {
@@ -614,6 +616,8 @@ struct NBDClient {
 
 CoMutex send_lock;
 Coroutine *send_coroutine;
+
+int nb_requests;
 };
 
 static void nbd_client_get(NBDClient *client)
@@ -644,6 +648,9 @@ static NBDRequest *nbd_request_get(NBDClient *client)
 NBDRequest *req;
 NBDExport *exp = client->exp;
 
+assert(client->nb_requests <= MAX_NBD_REQUESTS - 1);
+client->nb_requests++;
+
 if (QSIMPLEQ_EMPTY(&exp->requests)) {
 req = g_malloc0(sizeof(NBDRequest));
 req->data = qemu_blockalign(exp->bs, NBD_BUFFER_SIZE);
@@ -660,6 +667,9 @@ static void nbd_request_put(NBDRequest *req)
 {
 NBDClient *client = req->client;
 QSIMPLEQ_INSERT_HEAD(&client->exp->requests, req, entry);
+if (client->nb_requests-- == MAX_NBD_REQUESTS) {
+qemu_notify_event();
+}
 nbd_client_put(client);
 }
 
@@ -688,6 +698,7 @@ void nbd_export_close(NBDExport *exp)
 g_free(exp);
 }
 
+static int nbd_can_read(void *opaque);
 static void nbd_read(void *opaque);
 static void nbd_restart_write(void *opaque);
 
@@ -699,7 +710,8 @@ static int nbd_co_send_reply(NBDRequest *req, struct 
nbd_reply *reply,
 int rc, ret;
 
 qemu_co_mutex_lock(&client->send_lock);
-qemu_set_fd_handler2(csock, NULL, nbd_read, nbd_restart_write, client);
+qemu_set_fd_handler2(csock, nbd_can_read, nbd_read,
+ nbd_restart_write, client);
 client->send_coroutine = qemu_coroutine_self();
 
 if (!len) {
@@ -724,7 +736,7 @@ static int nbd_co_send_reply(NBDRequest *req, struct 
nbd_reply *reply,
 }
 
 client->send_coroutine = NULL;
-qemu_set_fd_handler2(csock, NULL, nbd_read, NULL, client);
+qemu_set_fd_handler2(csock, nbd_can_read, nbd_read, NULL, client);
 qemu_co_mutex_unlock(&client->send_lock);
 return rc;
 }
@@ -900,6 +912,13 @@ out:
 nbd_client_close(client);
 }
 
+static int nbd_can_read(void *opaque)
+{
+NBDClient *client = opaque;
+
+return client->recv_coroutine || client->nb_requests < MAX_NBD_REQUESTS;
+}
+
 static void nbd_read(void *opaque)
 {
 NBDClient *client = opaque;
@@ -931,6 +950,6 @@ NBDClient *nbd_client_new(NBDExport *exp, int csock,
 client->sock = csock;
 client->close = close;
 qemu_co_mutex_init(&client->send_lock);
-qemu_set_fd_handler2(csock, NULL, nbd_read, NULL, client);
+qemu_set_fd_handler2(csock, nbd_can_read, nbd_read, NULL, client);
 return client;
 }
-- 
1.7.7.1





[Qemu-devel] [PATCH 26/26] nbd: add myself as maintainer

2011-12-23 Thread Paolo Bonzini
Not planning to do much else, hence listing it as "Odd Fixes".

Signed-off-by: Paolo Bonzini 
---
 MAINTAINERS |7 +++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index e22bfa1..764c92d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -473,6 +473,13 @@ M: Mark McLoughlin 
 S: Maintained
 F: net/
 
+Network Block Device (NBD)
+M: Paolo Bonzini 
+S: Odd Fixes
+F: block/nbd.c
+F: nbd.*
+F: qemu-nbd.c
+
 SLIRP
 M: Jan Kiszka 
 S: Maintained
-- 
1.7.7.1




[Qemu-devel] [PATCH 07/26] nbd: add support for NBD_CMD_FLAG_FUA

2011-12-23 Thread Paolo Bonzini
Signed-off-by: Paolo Bonzini 
---
 block/nbd.c |4 
 nbd.c   |   13 +++--
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/block/nbd.c b/block/nbd.c
index 3f693e3..2f483cd 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -352,6 +352,10 @@ static int nbd_co_writev_1(BlockDriverState *bs, int64_t 
sector_num,
 struct nbd_reply reply;
 
 request.type = NBD_CMD_WRITE;
+if (!bdrv_enable_write_cache(bs) && (s->nbdflags & NBD_FLAG_SEND_FUA)) {
+request.type |= NBD_CMD_FLAG_FUA;
+}
+
 request.from = sector_num * 512;
 request.len = nb_sectors * 512;
 
diff --git a/nbd.c b/nbd.c
index 5b718b5..c597d47 100644
--- a/nbd.c
+++ b/nbd.c
@@ -202,7 +202,8 @@ int nbd_negotiate(int csock, off_t size, uint32_t flags)
 memcpy(buf, "NBDMAGIC", 8);
 cpu_to_be64w((uint64_t*)(buf + 8), 0x00420281861253LL);
 cpu_to_be64w((uint64_t*)(buf + 16), size);
-cpu_to_be32w((uint32_t*)(buf + 24), flags | NBD_FLAG_HAS_FLAGS);
+cpu_to_be32w((uint32_t*)(buf + 24),
+ flags | NBD_FLAG_HAS_FLAGS | NBD_FLAG_SEND_FUA);
 memset(buf + 28, 0, 124);
 
 if (write_sync(csock, buf, sizeof(buf)) != sizeof(buf)) {
@@ -630,7 +631,7 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size, 
uint64_t dev_offset,
 reply.handle = request.handle;
 reply.error = 0;
 
-switch (request.type) {
+switch (request.type & NBD_CMD_MASK_COMMAND) {
 case NBD_CMD_READ:
 TRACE("Request type is READ");
 
@@ -692,6 +693,14 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size, 
uint64_t dev_offset,
 }
 
 *offset += request.len;
+
+if (request.type & NBD_CMD_FLAG_FUA) {
+ret = bdrv_flush(bs);
+if (ret < 0) {
+LOG("flush failed");
+reply.error = -ret;
+}
+}
 }
 
 if (nbd_send_reply(csock, &reply) == -1)
-- 
1.7.7.1





[Qemu-devel] [PATCH v5 1/2] ptimer: move declarations to ptimer.h

2011-12-23 Thread Paolo Bonzini
Signed-off-by: Paolo Bonzini 
---
 hw/arm_timer.c|1 +
 hw/etraxfs_timer.c|1 +
 hw/grlib_apbuart.c|1 +
 hw/grlib_gptimer.c|1 +
 hw/lan9118.c  |1 +
 hw/leon3.c|1 +
 hw/lm32_timer.c   |1 +
 hw/mcf5206.c  |1 +
 hw/mcf5208.c  |1 +
 hw/milkymist-sysctl.c |1 +
 hw/musicpal.c |1 +
 hw/ptimer.c   |1 +
 hw/ptimer.h   |   27 +++
 hw/sh_timer.c |1 +
 hw/slavio_timer.c |1 +
 hw/xilinx_axidma.c|1 +
 hw/xilinx_timer.c |1 +
 qemu-timer.h  |   13 -
 18 files changed, 43 insertions(+), 13 deletions(-)
 create mode 100644 hw/ptimer.h

diff --git a/hw/arm_timer.c b/hw/arm_timer.c
index 0a5b9d2..fc9dbc6 100644
--- a/hw/arm_timer.c
+++ b/hw/arm_timer.c
@@ -9,6 +9,7 @@
 
 #include "sysbus.h"
 #include "qemu-timer.h"
+#include "ptimer.h"
 
 /* Common timer implementation.  */
 
diff --git a/hw/etraxfs_timer.c b/hw/etraxfs_timer.c
index 319cee1..2dfdb30 100644
--- a/hw/etraxfs_timer.c
+++ b/hw/etraxfs_timer.c
@@ -24,6 +24,7 @@
 #include "sysbus.h"
 #include "sysemu.h"
 #include "qemu-timer.h"
+#include "ptimer.h"
 
 #define D(x)
 
diff --git a/hw/grlib_apbuart.c b/hw/grlib_apbuart.c
index 62bdb03..f8a64e1 100644
--- a/hw/grlib_apbuart.c
+++ b/hw/grlib_apbuart.c
@@ -24,6 +24,7 @@
 
 #include "sysbus.h"
 #include "qemu-char.h"
+#include "ptimer.h"
 
 #include "trace.h"
 
diff --git a/hw/grlib_gptimer.c b/hw/grlib_gptimer.c
index 5645054..9c98a83 100644
--- a/hw/grlib_gptimer.c
+++ b/hw/grlib_gptimer.c
@@ -24,6 +24,7 @@
 
 #include "sysbus.h"
 #include "qemu-timer.h"
+#include "ptimer.h"
 
 #include "trace.h"
 
diff --git a/hw/lan9118.c b/hw/lan9118.c
index 7e64c5d..341a521 100644
--- a/hw/lan9118.c
+++ b/hw/lan9118.c
@@ -11,6 +11,7 @@
 #include "net.h"
 #include "devices.h"
 #include "sysemu.h"
+#include "ptimer.h"
 /* For crc32 */
 #include 
 
diff --git a/hw/leon3.c b/hw/leon3.c
index 607ec85..97a68f6 100644
--- a/hw/leon3.c
+++ b/hw/leon3.c
@@ -23,6 +23,7 @@
  */
 #include "hw.h"
 #include "qemu-timer.h"
+#include "ptimer.h"
 #include "qemu-char.h"
 #include "sysemu.h"
 #include "boards.h"
diff --git a/hw/lm32_timer.c b/hw/lm32_timer.c
index 445847f..115e1e9 100644
--- a/hw/lm32_timer.c
+++ b/hw/lm32_timer.c
@@ -25,6 +25,7 @@
 #include "sysbus.h"
 #include "trace.h"
 #include "qemu-timer.h"
+#include "ptimer.h"
 #include "qemu-error.h"
 
 #define DEFAULT_FREQUENCY (50*100)
diff --git a/hw/mcf5206.c b/hw/mcf5206.c
index 7b6d501..5110d83 100644
--- a/hw/mcf5206.c
+++ b/hw/mcf5206.c
@@ -8,6 +8,7 @@
 #include "hw.h"
 #include "mcf.h"
 #include "qemu-timer.h"
+#include "ptimer.h"
 #include "sysemu.h"
 #include "exec-memory.h"
 
diff --git a/hw/mcf5208.c b/hw/mcf5208.c
index ec608a1..4d5874f 100644
--- a/hw/mcf5208.c
+++ b/hw/mcf5208.c
@@ -8,6 +8,7 @@
 #include "hw.h"
 #include "mcf.h"
 #include "qemu-timer.h"
+#include "ptimer.h"
 #include "sysemu.h"
 #include "net.h"
 #include "boards.h"
diff --git a/hw/milkymist-sysctl.c b/hw/milkymist-sysctl.c
index 6326b70..bd2a298 100644
--- a/hw/milkymist-sysctl.c
+++ b/hw/milkymist-sysctl.c
@@ -26,6 +26,7 @@
 #include "sysemu.h"
 #include "trace.h"
 #include "qemu-timer.h"
+#include "ptimer.h"
 #include "qemu-error.h"
 
 enum {
diff --git a/hw/musicpal.c b/hw/musicpal.c
index 3c6cefe..ddab817 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -14,6 +14,7 @@
 #include "boards.h"
 #include "pc.h"
 #include "qemu-timer.h"
+#include "ptimer.h"
 #include "block.h"
 #include "flash.h"
 #include "console.h"
diff --git a/hw/ptimer.c b/hw/ptimer.c
index b6cabd5..de7d664 100644
--- a/hw/ptimer.c
+++ b/hw/ptimer.c
@@ -7,6 +7,7 @@
  */
 #include "hw.h"
 #include "qemu-timer.h"
+#include "ptimer.h"
 #include "host-utils.h"
 
 struct ptimer_state
diff --git a/hw/ptimer.h b/hw/ptimer.h
new file mode 100644
index 000..69cdddc
--- /dev/null
+++ b/hw/ptimer.h
@@ -0,0 +1,27 @@
+/*
+ * General purpose implementation of a simple periodic countdown timer.
+ *
+ * Copyright (c) 2007 CodeSourcery.
+ *
+ * This code is licensed under the GNU LGPL.
+ */
+#ifndef PTIMER_H
+#define PTIMER_H
+
+#include "qemu-common.h"
+#include "qemu-timer.h"
+
+/* ptimer.c */
+typedef struct ptimer_state ptimer_state;
+typedef void (*ptimer_cb)(void *opaque);
+
+ptimer_state *ptimer_init(QEMUBH *bh);
+void ptimer_set_period(ptimer_state *s, int64_t period);
+void ptimer_set_freq(ptimer_state *s, uint32_t freq);
+void ptimer_set_limit(ptimer_state *s, uint64_t limit, int reload);
+uint64_t ptimer_get_count(ptimer_state *s);
+void ptimer_set_count(ptimer_state *s, uint64_t count);
+void ptimer_run(ptimer_state *s, int oneshot);
+void ptimer_stop(ptimer_state *s);
+
+#endif
diff --git a/hw/sh_timer.c b/hw/sh_timer.c
index d2c0cec..64bf604 100644
--- a/hw/sh_timer.c
+++ b/hw/sh_timer.c
@@ -12,6 +12,7 @@
 #include "sh.h"
 #include "qemu-timer.h"
 #include "exec-memory.h"
+#include "ptimer.h"
 
 //#define DEBUG_TIMER
 
diff --gi

[Qemu-devel] [PATCH 09/26] nbd: add support for NBD_CMD_TRIM

2011-12-23 Thread Paolo Bonzini
Signed-off-by: Paolo Bonzini 
---
 block/nbd.c |   25 +
 nbd.c   |   15 +--
 2 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/block/nbd.c b/block/nbd.c
index 097b418..161b299 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -435,6 +435,30 @@ static int nbd_co_flush(BlockDriverState *bs)
 return -reply.error;
 }
 
+static int nbd_co_discard(BlockDriverState *bs, int64_t sector_num,
+  int nb_sectors)
+{
+BDRVNBDState *s = bs->opaque;
+struct nbd_request request;
+struct nbd_reply reply;
+
+if (!(s->nbdflags & NBD_FLAG_SEND_TRIM)) {
+return 0;
+}
+request.type = NBD_CMD_TRIM;
+request.from = sector_num * 512;;
+request.len = nb_sectors * 512;
+
+nbd_coroutine_start(s, &request);
+if (nbd_co_send_request(s, &request, NULL, 0) == -1) {
+reply.error = errno;
+} else {
+nbd_co_receive_reply(s, &request, &reply, NULL, 0);
+}
+nbd_coroutine_end(s, &request);
+return -reply.error;
+}
+
 static void nbd_close(BlockDriverState *bs)
 {
 BDRVNBDState *s = bs->opaque;
@@ -459,6 +483,7 @@ static BlockDriver bdrv_nbd = {
 .bdrv_co_writev  = nbd_co_writev,
 .bdrv_close  = nbd_close,
 .bdrv_co_flush_to_os = nbd_co_flush,
+.bdrv_co_discard = nbd_co_discard,
 .bdrv_getlength  = nbd_getlength,
 .protocol_name   = "nbd",
 };
diff --git a/nbd.c b/nbd.c
index 4fd0f4e..7ab1b1f 100644
--- a/nbd.c
+++ b/nbd.c
@@ -203,8 +203,8 @@ int nbd_negotiate(int csock, off_t size, uint32_t flags)
 cpu_to_be64w((uint64_t*)(buf + 8), 0x00420281861253LL);
 cpu_to_be64w((uint64_t*)(buf + 16), size);
 cpu_to_be32w((uint32_t*)(buf + 24),
- flags | NBD_FLAG_HAS_FLAGS | NBD_FLAG_SEND_FLUSH |
- NBD_FLAG_SEND_FUA);
+ flags | NBD_FLAG_HAS_FLAGS | NBD_FLAG_SEND_TRIM |
+ NBD_FLAG_SEND_FLUSH | NBD_FLAG_SEND_FUA);
 memset(buf + 28, 0, 124);
 
 if (write_sync(csock, buf, sizeof(buf)) != sizeof(buf)) {
@@ -723,6 +723,17 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size, 
uint64_t dev_offset,
 if (nbd_send_reply(csock, &reply) == -1)
 return -1;
 break;
+case NBD_CMD_TRIM:
+TRACE("Request type is TRIM");
+ret = bdrv_discard(bs, (request.from + dev_offset) / 512,
+   request.len / 512);
+if (ret < 0) {
+LOG("discard failed");
+reply.error = -ret;
+}
+if (nbd_send_reply(csock, &reply) == -1)
+return -1;
+break;
 default:
 LOG("invalid request type (%u) received", request.type);
 errno = EINVAL;
-- 
1.7.7.1





[Qemu-devel] [PATCH 24/26] qemu-nbd: asynchronous operation

2011-12-23 Thread Paolo Bonzini
Using coroutines enable asynchronous operation on both the network and
the block side.  Network can be owned by two coroutines at the same time,
one writing and one reading.  On the send side, mutual exclusion is
guaranteed by a CoMutex.  On the receive side, mutual exclusion is
guaranteed because new coroutines immediately start receiving data,
and no new coroutines are created as long as the previous one is receiving.

Between receive and send, qemu-nbd can have an arbitrary number of
in-flight block transfers.  Throttling is implemented by the next
patch.

Signed-off-by: Paolo Bonzini 
---
 nbd.c |   74 ++--
 1 files changed, 53 insertions(+), 21 deletions(-)

diff --git a/nbd.c b/nbd.c
index ca18c10..6d7d1f8 100644
--- a/nbd.c
+++ b/nbd.c
@@ -20,6 +20,8 @@
 #include "block.h"
 #include "block_int.h"
 
+#include "qemu-coroutine.h"
+
 #include 
 #include 
 #ifndef _WIN32
@@ -607,6 +609,11 @@ struct NBDClient {
 
 NBDExport *exp;
 int sock;
+
+Coroutine *recv_coroutine;
+
+CoMutex send_lock;
+Coroutine *send_coroutine;
 };
 
 static void nbd_client_get(NBDClient *client)
@@ -681,13 +688,20 @@ void nbd_export_close(NBDExport *exp)
 g_free(exp);
 }
 
-static int nbd_do_send_reply(NBDRequest *req, struct nbd_reply *reply,
+static void nbd_read(void *opaque);
+static void nbd_restart_write(void *opaque);
+
+static int nbd_co_send_reply(NBDRequest *req, struct nbd_reply *reply,
  int len)
 {
 NBDClient *client = req->client;
 int csock = client->sock;
 int rc, ret;
 
+qemu_co_mutex_lock(&client->send_lock);
+qemu_set_fd_handler2(csock, NULL, nbd_read, nbd_restart_write, client);
+client->send_coroutine = qemu_coroutine_self();
+
 if (!len) {
 rc = nbd_send_reply(csock, reply);
 if (rc == -1) {
@@ -697,7 +711,7 @@ static int nbd_do_send_reply(NBDRequest *req, struct 
nbd_reply *reply,
 socket_set_cork(csock, 1);
 rc = nbd_send_reply(csock, reply);
 if (rc != -1) {
-ret = write_sync(csock, req->data, len);
+ret = qemu_co_send(csock, req->data, len);
 if (ret != len) {
 errno = EIO;
 rc = -1;
@@ -708,15 +722,20 @@ static int nbd_do_send_reply(NBDRequest *req, struct 
nbd_reply *reply,
 }
 socket_set_cork(csock, 0);
 }
+
+client->send_coroutine = NULL;
+qemu_set_fd_handler2(csock, NULL, nbd_read, NULL, client);
+qemu_co_mutex_unlock(&client->send_lock);
 return rc;
 }
 
-static int nbd_do_receive_request(NBDRequest *req, struct nbd_request *request)
+static int nbd_co_receive_request(NBDRequest *req, struct nbd_request *request)
 {
 NBDClient *client = req->client;
 int csock = client->sock;
 int rc;
 
+client->recv_coroutine = qemu_coroutine_self();
 if (nbd_receive_request(csock, request) == -1) {
 rc = -EIO;
 goto out;
@@ -741,7 +760,7 @@ static int nbd_do_receive_request(NBDRequest *req, struct 
nbd_request *request)
 if ((request->type & NBD_CMD_MASK_COMMAND) == NBD_CMD_WRITE) {
 TRACE("Reading %u byte(s)", request->len);
 
-if (read_sync(csock, req->data, request->len) != request->len) {
+if (qemu_co_recv(csock, req->data, request->len) != request->len) {
 LOG("reading from socket failed");
 rc = -EIO;
 goto out;
@@ -750,21 +769,22 @@ static int nbd_do_receive_request(NBDRequest *req, struct 
nbd_request *request)
 rc = 0;
 
 out:
+client->recv_coroutine = NULL;
 return rc;
 }
 
-static int nbd_trip(NBDClient *client)
+static void nbd_trip(void *opaque)
 {
+NBDClient *client = opaque;
 NBDRequest *req = nbd_request_get(client);
 NBDExport *exp = client->exp;
 struct nbd_request request;
 struct nbd_reply reply;
-int rc = -1;
 int ret;
 
 TRACE("Reading request.");
 
-ret = nbd_do_receive_request(req, &request);
+ret = nbd_co_receive_request(req, &request);
 if (ret == -EIO) {
 goto out;
 }
@@ -799,7 +819,7 @@ static int nbd_trip(NBDClient *client)
 }
 
 TRACE("Read %u byte(s)", request.len);
-if (nbd_do_send_reply(req, &reply, request.len) < 0)
+if (nbd_co_send_reply(req, &reply, request.len) < 0)
 goto out;
 break;
 case NBD_CMD_WRITE:
@@ -822,7 +842,7 @@ static int nbd_trip(NBDClient *client)
 }
 
 if (request.type & NBD_CMD_FLAG_FUA) {
-ret = bdrv_flush(exp->bs);
+ret = bdrv_co_flush(exp->bs);
 if (ret < 0) {
 LOG("flush failed");
 reply.error = -ret;
@@ -830,34 +850,34 @@ static int nbd_trip(NBDClient *client)
 }
 }
 
-if (nbd_do_send_reply(req, &reply, 0) < 0)
+if (nbd_co_send_reply(req, &reply, 0) < 0)
 goto out;
 break;
 case NBD_CMD_DISC:
 TRACE("Reques

[Qemu-devel] [PATCH 11/26] qemu-nbd: remove offset argument to nbd_trip

2011-12-23 Thread Paolo Bonzini
The argument is write-only.

Signed-off-by: Paolo Bonzini 
---
 nbd.c  |8 +++-
 nbd.h  |2 +-
 qemu-nbd.c |3 +--
 3 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/nbd.c b/nbd.c
index 73fedeb..1df2b91 100644
--- a/nbd.c
+++ b/nbd.c
@@ -583,8 +583,9 @@ static int nbd_send_reply(int csock, struct nbd_reply 
*reply)
 return 0;
 }
 
-int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset,
- off_t *offset, uint32_t nbdflags, uint8_t *data, int data_size)
+int nbd_trip(BlockDriverState *bs, int csock, off_t size,
+ uint64_t dev_offset, uint32_t nbdflags,
+ uint8_t *data, int data_size)
 {
 struct nbd_request request;
 struct nbd_reply reply;
@@ -635,7 +636,6 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size, 
uint64_t dev_offset,
 reply.error = -ret;
 request.len = 0;
 }
-*offset += request.len;
 
 TRACE("Read %u byte(s)", request.len);
 
@@ -684,8 +684,6 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size, 
uint64_t dev_offset,
 request.len = 0;
 }
 
-*offset += request.len;
-
 if (request.type & NBD_CMD_FLAG_FUA) {
 ret = bdrv_flush(bs);
 if (ret < 0) {
diff --git a/nbd.h b/nbd.h
index 61553f4..ebdb2db 100644
--- a/nbd.h
+++ b/nbd.h
@@ -72,7 +72,7 @@ int nbd_init(int fd, int csock, uint32_t flags, off_t size, 
size_t blocksize);
 int nbd_send_request(int csock, struct nbd_request *request);
 int nbd_receive_reply(int csock, struct nbd_reply *reply);
 int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset,
- off_t *offset, uint32_t nbdflags, uint8_t *data, int data_size);
+ uint32_t nbdflags, uint8_t *data, int data_size);
 int nbd_client(int fd);
 int nbd_disconnect(int fd);
 
diff --git a/qemu-nbd.c b/qemu-nbd.c
index 291cba2..f9ee9c5 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -248,7 +248,6 @@ int main(int argc, char **argv)
 {
 BlockDriverState *bs;
 off_t dev_offset = 0;
-off_t offset = 0;
 uint32_t nbdflags = 0;
 bool disconnect = false;
 const char *bindto = "0.0.0.0";
@@ -542,7 +541,7 @@ int main(int argc, char **argv)
 for (i = 1; i < nb_fds && ret; i++) {
 if (FD_ISSET(sharing_fds[i], &fds)) {
 if (nbd_trip(bs, sharing_fds[i], fd_size, dev_offset,
-&offset, nbdflags, data, NBD_BUFFER_SIZE) != 0) {
+nbdflags, data, NBD_BUFFER_SIZE) != 0) {
 close(sharing_fds[i]);
 nb_fds--;
 sharing_fds[i] = sharing_fds[nb_fds];
-- 
1.7.7.1





[Qemu-devel] [PATCH 06/26] nbd: fix error handling in the server

2011-12-23 Thread Paolo Bonzini
bdrv_read and bdrv_write return negative errno values, not -1.

Signed-off-by: Paolo Bonzini 
---
 nbd.c |   21 -
 1 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/nbd.c b/nbd.c
index ff701d3..5b718b5 100644
--- a/nbd.c
+++ b/nbd.c
@@ -595,6 +595,7 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size, 
uint64_t dev_offset,
 {
 struct nbd_request request;
 struct nbd_reply reply;
+int ret;
 
 TRACE("Reading request.");
 
@@ -633,12 +634,13 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size, 
uint64_t dev_offset,
 case NBD_CMD_READ:
 TRACE("Request type is READ");
 
-if (bdrv_read(bs, (request.from + dev_offset) / 512,
-  data + NBD_REPLY_SIZE,
-  request.len / 512) == -1) {
+ret = bdrv_read(bs, (request.from + dev_offset) / 512,
+data + NBD_REPLY_SIZE,
+request.len / 512);
+if (ret < 0) {
 LOG("reading from file failed");
-errno = EINVAL;
-return -1;
+reply.error = -ret;
+request.len = 0;
 }
 *offset += request.len;
 
@@ -681,11 +683,12 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size, 
uint64_t dev_offset,
 } else {
 TRACE("Writing to device");
 
-if (bdrv_write(bs, (request.from + dev_offset) / 512,
-   data, request.len / 512) == -1) {
+ret = bdrv_write(bs, (request.from + dev_offset) / 512,
+ data, request.len / 512);
+if (ret < 0) {
 LOG("writing to file failed");
-errno = EINVAL;
-return -1;
+reply.error = -ret;
+request.len = 0;
 }
 
 *offset += request.len;
-- 
1.7.7.1





[Qemu-devel] [PATCH 05/26] nbd: allow multiple in-flight requests

2011-12-23 Thread Paolo Bonzini
Allow sending up to 16 requests, and drive the replies to the coroutine
that did the request.  The code is written to be exactly the same as
before this patch when MAX_NBD_REQUESTS == 1 (modulo the extra mutex
and state).

Signed-off-by: Paolo Bonzini 
---
 block/nbd.c |   69 +++---
 1 files changed, 56 insertions(+), 13 deletions(-)

diff --git a/block/nbd.c b/block/nbd.c
index 9d661c1..3f693e3 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -46,6 +46,10 @@
 #define logout(fmt, ...) ((void)0)
 #endif
 
+#define MAX_NBD_REQUESTS   16
+#define HANDLE_TO_INDEX(bs, handle) ((handle) ^ ((uint64_t)(intptr_t)bs))
+#define INDEX_TO_HANDLE(bs, index)  ((index)  ^ ((uint64_t)(intptr_t)bs))
+
 typedef struct BDRVNBDState {
 int sock;
 uint32_t nbdflags;
@@ -53,9 +57,12 @@ typedef struct BDRVNBDState {
 size_t blocksize;
 char *export_name; /* An NBD server may export several devices */
 
-CoMutex mutex;
-Coroutine *coroutine;
+CoMutex send_mutex;
+CoMutex free_sema;
+Coroutine *send_coroutine;
+int in_flight;
 
+Coroutine *recv_coroutine[MAX_NBD_REQUESTS];
 struct nbd_reply reply;
 
 /* If it begins with  '/', this is a UNIX domain socket. Otherwise,
@@ -112,41 +119,68 @@ out:
 
 static void nbd_coroutine_start(BDRVNBDState *s, struct nbd_request *request)
 {
-qemu_co_mutex_lock(&s->mutex);
-s->coroutine = qemu_coroutine_self();
-request->handle = (uint64_t)(intptr_t)s;
+int i;
+
+/* Poor man semaphore.  The free_sema is locked when no other request
+ * can be accepted, and unlocked after receiving one reply.  */
+if (s->in_flight >= MAX_NBD_REQUESTS - 1) {
+qemu_co_mutex_lock(&s->free_sema);
+assert(s->in_flight < MAX_NBD_REQUESTS);
+}
+s->in_flight++;
+
+for (i = 0; i < MAX_NBD_REQUESTS; i++) {
+if (s->recv_coroutine[i] == NULL) {
+s->recv_coroutine[i] = qemu_coroutine_self();
+break;
+}
+}
+
+assert(i < MAX_NBD_REQUESTS);
+request->handle = INDEX_TO_HANDLE(s, i);
 }
 
 static int nbd_have_request(void *opaque)
 {
 BDRVNBDState *s = opaque;
 
-return !!s->coroutine;
+return s->in_flight > 0;
 }
 
 static void nbd_reply_ready(void *opaque)
 {
 BDRVNBDState *s = opaque;
+int i;
 
 if (s->reply.handle == 0) {
 /* No reply already in flight.  Fetch a header.  */
 if (nbd_receive_reply(s->sock, &s->reply) < 0) {
 s->reply.handle = 0;
+goto fail;
 }
 }
 
 /* There's no need for a mutex on the receive side, because the
  * handler acts as a synchronization point and ensures that only
  * one coroutine is called until the reply finishes.  */
-if (s->coroutine) {
-qemu_coroutine_enter(s->coroutine, NULL);
+i = HANDLE_TO_INDEX(s, s->reply.handle);
+if (s->recv_coroutine[i]) {
+qemu_coroutine_enter(s->recv_coroutine[i], NULL);
+return;
+}
+
+fail:
+for (i = 0; i < MAX_NBD_REQUESTS; i++) {
+if (s->recv_coroutine[i]) {
+qemu_coroutine_enter(s->recv_coroutine[i], NULL);
+}
 }
 }
 
 static void nbd_restart_write(void *opaque)
 {
 BDRVNBDState *s = opaque;
-qemu_coroutine_enter(s->coroutine, NULL);
+qemu_coroutine_enter(s->send_coroutine, NULL);
 }
 
 static int nbd_co_send_request(BDRVNBDState *s, struct nbd_request *request,
@@ -154,6 +188,8 @@ static int nbd_co_send_request(BDRVNBDState *s, struct 
nbd_request *request,
 {
 int rc, ret;
 
+qemu_co_mutex_lock(&s->send_mutex);
+s->send_coroutine = qemu_coroutine_self();
 qemu_aio_set_fd_handler(s->sock, nbd_reply_ready, nbd_restart_write,
 nbd_have_request, NULL, s);
 rc = nbd_send_request(s->sock, request);
@@ -166,6 +202,8 @@ static int nbd_co_send_request(BDRVNBDState *s, struct 
nbd_request *request,
 }
 qemu_aio_set_fd_handler(s->sock, nbd_reply_ready, NULL,
 nbd_have_request, NULL, s);
+s->send_coroutine = NULL;
+qemu_co_mutex_unlock(&s->send_mutex);
 return rc;
 }
 
@@ -175,7 +213,8 @@ static void nbd_co_receive_reply(BDRVNBDState *s, struct 
nbd_request *request,
 {
 int ret;
 
-/* Wait until we're woken up by the read handler.  */
+/* Wait until we're woken up by the read handler.  TODO: perhaps
+ * peek at the next reply and avoid yielding if it's ours?  */
 qemu_coroutine_yield();
 *reply = s->reply;
 if (reply->handle != request->handle) {
@@ -195,8 +234,11 @@ static void nbd_co_receive_reply(BDRVNBDState *s, struct 
nbd_request *request,
 
 static void nbd_coroutine_end(BDRVNBDState *s, struct nbd_request *request)
 {
-s->coroutine = NULL;
-qemu_co_mutex_unlock(&s->mutex);
+int i = HANDLE_TO_INDEX(s, request->handle);
+s->recv_coroutine[i] = NULL;
+if (s->in_flight-- == MAX_NBD_REQUESTS) {
+qemu_co_mutex_unlock(&s->free_sema);
+}

[Qemu-devel] [PATCH 15/26] qemu-nbd: introduce nbd_do_send_reply

2011-12-23 Thread Paolo Bonzini
Group the sending of a reply and the associated data into a new function.
Without corking, the caller would be forced to leave 12 free bytes at the
beginning of the data pointer.  Not too ugly, but still ugly. :)

Using nbd_do_send_reply everywhere will help when the routine will set up
the write handler that re-enters the send coroutine.

Signed-off-by: Paolo Bonzini 
---
 nbd.c |   46 --
 1 files changed, 32 insertions(+), 14 deletions(-)

diff --git a/nbd.c b/nbd.c
index d383d85..025c5b0 100644
--- a/nbd.c
+++ b/nbd.c
@@ -583,6 +583,34 @@ static int nbd_send_reply(int csock, struct nbd_reply 
*reply)
 return 0;
 }
 
+static int nbd_do_send_reply(int csock, struct nbd_reply *reply,
+ uint8_t *data, int len)
+{
+int rc, ret;
+
+if (!len) {
+rc = nbd_send_reply(csock, reply);
+if (rc == -1) {
+rc = -errno;
+}
+} else {
+socket_set_cork(csock, 1);
+rc = nbd_send_reply(csock, reply);
+if (rc != -1) {
+ret = write_sync(csock, data, len);
+if (ret != len) {
+errno = EIO;
+rc = -1;
+}
+}
+if (rc == -1) {
+rc = -errno;
+}
+socket_set_cork(csock, 0);
+}
+return rc;
+}
+
 int nbd_trip(BlockDriverState *bs, int csock, off_t size,
  uint64_t dev_offset, uint32_t nbdflags,
  uint8_t *data)
@@ -637,18 +665,8 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size,
 }
 
 TRACE("Read %u byte(s)", request.len);
-socket_set_cork(csock, 1);
-if (nbd_send_reply(csock, &reply) == -1)
+if (nbd_do_send_reply(csock, &reply, data, request.len) < 0)
 return -1;
-
-TRACE("Sending data to client");
-
-if (write_sync(csock, data, request.len) != request.len) {
-LOG("writing to socket failed");
-errno = EINVAL;
-return -1;
-}
-socket_set_cork(csock, 0);
 break;
 case NBD_CMD_WRITE:
 TRACE("Request type is WRITE");
@@ -684,7 +702,7 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size,
 }
 }
 
-if (nbd_send_reply(csock, &reply) == -1)
+if (nbd_do_send_reply(csock, &reply, NULL, 0) < 0)
 return -1;
 break;
 case NBD_CMD_DISC:
@@ -700,7 +718,7 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size,
 reply.error = -ret;
 }
 
-if (nbd_send_reply(csock, &reply) == -1)
+if (nbd_do_send_reply(csock, &reply, NULL, 0) < 0)
 return -1;
 break;
 case NBD_CMD_TRIM:
@@ -711,7 +729,7 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size,
 LOG("discard failed");
 reply.error = -ret;
 }
-if (nbd_send_reply(csock, &reply) == -1)
+if (nbd_do_send_reply(csock, &reply, NULL, 0) < 0)
 return -1;
 break;
 default:
-- 
1.7.7.1





[Qemu-devel] [PATCH 17/26] qemu-nbd: introduce nbd_do_receive_request

2011-12-23 Thread Paolo Bonzini
Group the receiving of a response and the associated data into a new function.

Signed-off-by: Paolo Bonzini 
---
 nbd.c |   68 
 1 files changed, 47 insertions(+), 21 deletions(-)

diff --git a/nbd.c b/nbd.c
index 053ad8d..964a732 100644
--- a/nbd.c
+++ b/nbd.c
@@ -611,6 +611,47 @@ static int nbd_do_send_reply(int csock, struct nbd_reply 
*reply,
 return rc;
 }
 
+static int nbd_do_receive_request(int csock, struct nbd_request *request,
+  uint8_t *data)
+{
+int rc;
+
+if (nbd_receive_request(csock, request) == -1) {
+rc = -EIO;
+goto out;
+}
+
+if (request->len > NBD_BUFFER_SIZE) {
+LOG("len (%u) is larger than max len (%u)",
+request->len, NBD_BUFFER_SIZE);
+rc = -EINVAL;
+goto out;
+}
+
+if ((request->from + request->len) < request->from) {
+LOG("integer overflow detected! "
+"you're probably being attacked");
+rc = -EINVAL;
+goto out;
+}
+
+TRACE("Decoding type");
+
+if ((request->type & NBD_CMD_MASK_COMMAND) == NBD_CMD_WRITE) {
+TRACE("Reading %u byte(s)", request->len);
+
+if (read_sync(csock, data, request->len) != request->len) {
+LOG("reading from socket failed");
+rc = -EIO;
+goto out;
+}
+}
+rc = 0;
+
+out:
+return rc;
+}
+
 int nbd_trip(BlockDriverState *bs, int csock, off_t size,
  uint64_t dev_offset, uint32_t nbdflags,
  uint8_t *data)
@@ -621,22 +662,17 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size,
 
 TRACE("Reading request.");
 
-if (nbd_receive_request(csock, &request) == -1)
+ret = nbd_do_receive_request(csock, &request, data);
+if (ret == -EIO) {
 return -1;
+}
 
 reply.handle = request.handle;
 reply.error = 0;
 
-if (request.len > NBD_BUFFER_SIZE) {
-LOG("len (%u) is larger than max len (%u)",
-request.len, NBD_BUFFER_SIZE);
-goto invalid_request;
-}
-
-if ((request.from + request.len) < request.from) {
-LOG("integer overflow detected! "
-"you're probably being attacked");
-goto invalid_request;
+if (ret < 0) {
+reply.error = -ret;
+goto error_reply;
 }
 
 if ((request.from + request.len) > size) {
@@ -647,8 +683,6 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size,
 goto invalid_request;
 }
 
-TRACE("Decoding type");
-
 switch (request.type & NBD_CMD_MASK_COMMAND) {
 case NBD_CMD_READ:
 TRACE("Request type is READ");
@@ -668,14 +702,6 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size,
 case NBD_CMD_WRITE:
 TRACE("Request type is WRITE");
 
-TRACE("Reading %u byte(s)", request.len);
-
-if (read_sync(csock, data, request.len) != request.len) {
-LOG("reading from socket failed");
-errno = EINVAL;
-return -1;
-}
-
 if (nbdflags & NBD_FLAG_READ_ONLY) {
 TRACE("Server is read-only, return error");
 reply.error = EROFS;
-- 
1.7.7.1





[Qemu-devel] [PATCH 22/26] qemu-nbd: move client handling to nbd.c

2011-12-23 Thread Paolo Bonzini
This patch sets up the fd handler in nbd.c instead of qemu-nbd.c.  It
introduces NBDClient, which wraps the arguments to nbd_trip in a single
structure, so that we can add a notifier to it.  This way, qemu-nbd can
know about disconnections.

Signed-off-by: Paolo Bonzini 
---
 nbd.c  |   62 +--
 nbd.h  |5 ++-
 qemu-nbd.c |   14 +++-
 3 files changed, 66 insertions(+), 15 deletions(-)

diff --git a/nbd.c b/nbd.c
index 82eb98d..4822843 100644
--- a/nbd.c
+++ b/nbd.c
@@ -600,6 +600,37 @@ struct NBDExport {
 QSIMPLEQ_HEAD(, NBDRequest) requests;
 };
 
+struct NBDClient {
+int refcount;
+void (*close)(NBDClient *client);
+
+NBDExport *exp;
+int sock;
+};
+
+static void nbd_client_get(NBDClient *client)
+{
+client->refcount++;
+}
+
+static void nbd_client_put(NBDClient *client)
+{
+if (--client->refcount == 0) {
+g_free(client);
+}
+}
+
+static void nbd_client_close(NBDClient *client)
+{
+qemu_set_fd_handler2(client->sock, NULL, NULL, NULL, NULL);
+close(client->sock);
+client->sock = -1;
+if (client->close) {
+client->close(client);
+}
+nbd_client_put(client);
+}
+
 static NBDRequest *nbd_request_get(NBDExport *exp)
 {
 NBDRequest *req;
@@ -712,9 +743,11 @@ out:
 return rc;
 }
 
-int nbd_trip(NBDExport *exp, int csock)
+static int nbd_trip(NBDClient *client)
 {
+NBDExport *exp = client->exp;
 NBDRequest *req = nbd_request_get(exp);
+int csock = client->sock;
 struct nbd_request request;
 struct nbd_reply reply;
 int rc = -1;
@@ -836,7 +869,30 @@ out:
 return rc;
 }
 
-int nbd_negotiate(NBDExport *exp, int csock)
+static void nbd_read(void *opaque)
+{
+NBDClient *client = opaque;
+
+nbd_client_get(client);
+if (nbd_trip(client) != 0) {
+nbd_client_close(client);
+}
+
+nbd_client_put(client);
+}
+
+NBDClient *nbd_client_new(NBDExport *exp, int csock,
+  void (*close)(NBDClient *))
 {
-return nbd_send_negotiate(csock, exp->size, exp->nbdflags);
+NBDClient *client;
+if (nbd_send_negotiate(csock, exp->size, exp->nbdflags) == -1) {
+return NULL;
+}
+client = g_malloc0(sizeof(NBDClient));
+client->refcount = 1;
+client->exp = exp;
+client->sock = csock;
+client->close = close;
+qemu_set_fd_handler2(csock, NULL, nbd_read, NULL, client);
+return client;
 }
diff --git a/nbd.h b/nbd.h
index c77c2fd..a8382f0 100644
--- a/nbd.h
+++ b/nbd.h
@@ -76,11 +76,12 @@ int nbd_client(int fd);
 int nbd_disconnect(int fd);
 
 typedef struct NBDExport NBDExport;
+typedef struct NBDClient NBDClient;
 
 NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset,
   off_t size, uint32_t nbdflags);
 void nbd_export_close(NBDExport *exp);
-int nbd_negotiate(NBDExport *exp, int csock);
-int nbd_trip(NBDExport *exp, int csock);
+NBDClient *nbd_client_new(NBDExport *exp, int csock,
+  void (*close)(NBDClient *));
 
 #endif
diff --git a/qemu-nbd.c b/qemu-nbd.c
index 347c776..155b058 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -249,15 +249,10 @@ static int nbd_can_accept(void *opaque)
 return nb_fds < shared;
 }
 
-static void nbd_read(void *opaque)
+static void nbd_client_closed(NBDClient *client)
 {
-int fd = (uintptr_t) opaque;
-
-if (nbd_trip(exp, fd) != 0) {
-qemu_set_fd_handler2(fd, NULL, NULL, NULL, NULL);
-close(fd);
-nb_fds--;
-}
+nb_fds--;
+qemu_notify_event();
 }
 
 static void nbd_accept(void *opaque)
@@ -268,8 +263,7 @@ static void nbd_accept(void *opaque)
 
 int fd = accept(server_fd, (struct sockaddr *)&addr, &addr_len);
 nbd_started = true;
-if (fd != -1 && nbd_negotiate(exp, fd) != -1) {
-qemu_set_fd_handler2(fd, NULL, nbd_read, NULL, (void *) (intptr_t) fd);
+if (fd != -1 && nbd_client_new(exp, fd, nbd_client_closed)) {
 nb_fds++;
 }
 }
-- 
1.7.7.1





[Qemu-devel] [PATCH 13/26] move corking functions to osdep.c

2011-12-23 Thread Paolo Bonzini
Signed-off-by: Paolo Bonzini 
---
 block/sheepdog.c |   20 ++--
 osdep.c  |9 +
 qemu_socket.h|1 +
 3 files changed, 12 insertions(+), 18 deletions(-)

diff --git a/block/sheepdog.c b/block/sheepdog.c
index 00ea5a0..17a79be 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -702,22 +702,6 @@ static int aio_flush_request(void *opaque)
 return !QLIST_EMPTY(&s->outstanding_aio_head);
 }
 
-#if !defined(SOL_TCP) || !defined(TCP_CORK)
-
-static int set_cork(int fd, int v)
-{
-return 0;
-}
-
-#else
-
-static int set_cork(int fd, int v)
-{
-return setsockopt(fd, SOL_TCP, TCP_CORK, &v, sizeof(v));
-}
-
-#endif
-
 static int set_nodelay(int fd)
 {
 int ret, opt;
@@ -923,7 +907,7 @@ static int coroutine_fn add_aio_request(BDRVSheepdogState 
*s, AIOReq *aio_req,
 s->co_send = qemu_coroutine_self();
 qemu_aio_set_fd_handler(s->fd, co_read_response, co_write_request,
 aio_flush_request, NULL, s);
-set_cork(s->fd, 1);
+socket_set_cork(s->fd, 1);
 
 /* send a header */
 ret = qemu_co_send(s->fd, &hdr, sizeof(hdr));
@@ -942,7 +926,7 @@ static int coroutine_fn add_aio_request(BDRVSheepdogState 
*s, AIOReq *aio_req,
 }
 }
 
-set_cork(s->fd, 0);
+socket_set_cork(s->fd, 0);
 qemu_aio_set_fd_handler(s->fd, co_read_response, NULL,
 aio_flush_request, NULL, s);
 qemu_co_mutex_unlock(&s->lock);
diff --git a/osdep.c b/osdep.c
index 70bad27..3e6bada 100644
--- a/osdep.c
+++ b/osdep.c
@@ -48,6 +48,15 @@ extern int madvise(caddr_t, size_t, int);
 #include "trace.h"
 #include "qemu_socket.h"
 
+int socket_set_cork(int fd, int v)
+{
+#if defined(SOL_TCP) && defined(TCP_CORK)
+return setsockopt(fd, SOL_TCP, TCP_CORK, &v, sizeof(v));
+#else
+return 0;
+#endif
+}
+
 int qemu_madvise(void *addr, size_t len, int advice)
 {
 if (advice == QEMU_MADV_INVALID) {
diff --git a/qemu_socket.h b/qemu_socket.h
index 9e32fac..fe4cf6c 100644
--- a/qemu_socket.h
+++ b/qemu_socket.h
@@ -35,6 +35,7 @@ int inet_aton(const char *cp, struct in_addr *ia);
 /* misc helpers */
 int qemu_socket(int domain, int type, int protocol);
 int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
+int socket_set_cork(int fd, int v);
 void socket_set_block(int fd);
 void socket_set_nonblock(int fd);
 int send_all(int fd, const void *buf, int len1);
-- 
1.7.7.1





[Qemu-devel] [PATCH 20/26] link the main loop and its dependencies into the tools

2011-12-23 Thread Paolo Bonzini
Using the main loop code from QEMU enables tools to operate fully
asynchronously.  Advantages include better Windows portability (for some
definition of portability) over glib's.

Signed-off-by: Paolo Bonzini 
---
 Makefile  |5 +++--
 main-loop.h   |6 ++
 os-posix.c|   42 --
 os-win32.c|5 -
 oslib-posix.c |   43 +++
 oslib-win32.c |5 +
 qemu-tool.c   |   42 +++---
 7 files changed, 80 insertions(+), 68 deletions(-)

diff --git a/Makefile b/Makefile
index 2c03055..368eeae 100644
--- a/Makefile
+++ b/Makefile
@@ -147,8 +147,9 @@ endif
 qemu-img.o: qemu-img-cmds.h
 qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o cmd.o qemu-ga.o: 
$(GENERATED_HEADERS)
 
-tools-obj-y = qemu-tool.o $(oslib-obj-y) $(trace-obj-y) \
-   qemu-timer-common.o cutils.o
+tools-obj-y = $(oslib-obj-y) $(trace-obj-y) qemu-tool.o qemu-timer.o \
+   qemu-timer-common.o main-loop.o notify.o iohandler.o cutils.o async.o
+tools-obj-$(CONFIG_POSIX) += compatfd.o
 
 qemu-img$(EXESUF): qemu-img.o $(tools-obj-y) $(block-obj-y)
 qemu-nbd$(EXESUF): qemu-nbd.o $(tools-obj-y) $(block-obj-y)
diff --git a/main-loop.h b/main-loop.h
index 876092d..f971013 100644
--- a/main-loop.h
+++ b/main-loop.h
@@ -324,6 +324,9 @@ int qemu_add_child_watch(pid_t pid);
  * by threads other than the main loop thread when calling
  * qemu_bh_new(), qemu_set_fd_handler() and basically all other
  * functions documented in this file.
+ *
+ * NOTE: tools currently are single-threaded and qemu_mutex_lock_iothread
+ * is a no-op there.
  */
 void qemu_mutex_lock_iothread(void);
 
@@ -336,6 +339,9 @@ void qemu_mutex_lock_iothread(void);
  * as soon as possible by threads other than the main loop thread,
  * because it prevents the main loop from processing callbacks,
  * including timers and bottom halves.
+ *
+ * NOTE: tools currently are single-threaded and qemu_mutex_unlock_iothread
+ * is a no-op there.
  */
 void qemu_mutex_unlock_iothread(void);
 
diff --git a/os-posix.c b/os-posix.c
index dc4a6bb..5c437ca 100644
--- a/os-posix.c
+++ b/os-posix.c
@@ -42,11 +42,6 @@
 
 #ifdef CONFIG_LINUX
 #include 
-#include 
-#endif
-
-#ifdef CONFIG_EVENTFD
-#include 
 #endif
 
 static struct passwd *user_pwd;
@@ -333,34 +328,6 @@ void os_set_line_buffering(void)
 setvbuf(stdout, NULL, _IOLBF, 0);
 }
 
-/*
- * Creates an eventfd that looks like a pipe and has EFD_CLOEXEC set.
- */
-int qemu_eventfd(int fds[2])
-{
-#ifdef CONFIG_EVENTFD
-int ret;
-
-ret = eventfd(0, 0);
-if (ret >= 0) {
-fds[0] = ret;
-qemu_set_cloexec(ret);
-if ((fds[1] = dup(ret)) == -1) {
-close(ret);
-return -1;
-}
-qemu_set_cloexec(fds[1]);
-return 0;
-}
-
-if (errno != ENOSYS) {
-return -1;
-}
-#endif
-
-return qemu_pipe(fds);
-}
-
 int qemu_create_pidfile(const char *filename)
 {
 char buffer[128];
@@ -384,12 +351,3 @@ int qemu_create_pidfile(const char *filename)
 close(fd);
 return 0;
 }
-
-int qemu_get_thread_id(void)
-{
-#if defined (__linux__)
-return syscall(SYS_gettid);
-#else
-return getpid();
-#endif
-}
diff --git a/os-win32.c b/os-win32.c
index 8523d8d..ad76370 100644
--- a/os-win32.c
+++ b/os-win32.c
@@ -151,8 +151,3 @@ int qemu_create_pidfile(const char *filename)
 }
 return 0;
 }
-
-int qemu_get_thread_id(void)
-{
-return GetCurrentThreadId();
-}
diff --git a/oslib-posix.c b/oslib-posix.c
index ce75549..b6a3c7f 100644
--- a/oslib-posix.c
+++ b/oslib-posix.c
@@ -55,6 +55,21 @@ static int running_on_valgrind = -1;
 #else
 #  define running_on_valgrind 0
 #endif
+#ifdef CONFIG_LINUX
+#include 
+#endif
+#ifdef CONFIG_EVENTFD
+#include 
+#endif
+
+int qemu_get_thread_id(void)
+{
+#if defined(__linux__)
+return syscall(SYS_gettid);
+#else
+return getpid();
+#endif
+}
 
 int qemu_daemon(int nochdir, int noclose)
 {
@@ -162,6 +177,34 @@ int qemu_pipe(int pipefd[2])
 return ret;
 }
 
+/*
+ * Creates an eventfd that looks like a pipe and has EFD_CLOEXEC set.
+ */
+int qemu_eventfd(int fds[2])
+{
+#ifdef CONFIG_EVENTFD
+int ret;
+
+ret = eventfd(0, 0);
+if (ret >= 0) {
+fds[0] = ret;
+fds[1] = dup(ret);
+if (fds[1] == -1) {
+close(ret);
+return -1;
+}
+qemu_set_cloexec(ret);
+qemu_set_cloexec(fds[1]);
+return 0;
+}
+if (errno != ENOSYS) {
+return -1;
+}
+#endif
+
+return qemu_pipe(fds);
+}
+
 int qemu_utimens(const char *path, const struct timespec *times)
 {
 struct timeval tv[2], tv_now;
diff --git a/oslib-win32.c b/oslib-win32.c
index 5e3de7d..ce3021e 100644
--- a/oslib-win32.c
+++ b/oslib-win32.c
@@ -118,3 +118,8 @@ int qemu_gettimeofday(qemu_timeval *tp)
  Do not set errno on error.  */
   return 0;
 }
+
+int qemu_get_thread_id(void)
+{
+return GetCurrentThreadId();
+}
diff 

[Qemu-devel] [PATCH 23/26] qemu-nbd: add client pointer to NBDRequest

2011-12-23 Thread Paolo Bonzini
By attaching a client to an NBDRequest, we can avoid passing around the
socket descriptor and data buffer.

Also, we can now manage the reference count for the client in
nbd_request_get/put request instead of having to do it ourselved in
nbd_read.  This simplifies things when coroutines are used.

Signed-off-by: Paolo Bonzini 
---
 nbd.c |   48 +++-
 1 files changed, 27 insertions(+), 21 deletions(-)

diff --git a/nbd.c b/nbd.c
index 4822843..ca18c10 100644
--- a/nbd.c
+++ b/nbd.c
@@ -589,6 +589,7 @@ typedef struct NBDRequest NBDRequest;
 
 struct NBDRequest {
 QSIMPLEQ_ENTRY(NBDRequest) entry;
+NBDClient *client;
 uint8_t *data;
 };
 
@@ -631,9 +632,11 @@ static void nbd_client_close(NBDClient *client)
 nbd_client_put(client);
 }
 
-static NBDRequest *nbd_request_get(NBDExport *exp)
+static NBDRequest *nbd_request_get(NBDClient *client)
 {
 NBDRequest *req;
+NBDExport *exp = client->exp;
+
 if (QSIMPLEQ_EMPTY(&exp->requests)) {
 req = g_malloc0(sizeof(NBDRequest));
 req->data = qemu_blockalign(exp->bs, NBD_BUFFER_SIZE);
@@ -641,12 +644,16 @@ static NBDRequest *nbd_request_get(NBDExport *exp)
 req = QSIMPLEQ_FIRST(&exp->requests);
 QSIMPLEQ_REMOVE_HEAD(&exp->requests, entry);
 }
+nbd_client_get(client);
+req->client = client;
 return req;
 }
 
-static void nbd_request_put(NBDExport *exp, NBDRequest *req)
+static void nbd_request_put(NBDRequest *req)
 {
-QSIMPLEQ_INSERT_HEAD(&exp->requests, req, entry);
+NBDClient *client = req->client;
+QSIMPLEQ_INSERT_HEAD(&client->exp->requests, req, entry);
+nbd_client_put(client);
 }
 
 NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset,
@@ -674,9 +681,11 @@ void nbd_export_close(NBDExport *exp)
 g_free(exp);
 }
 
-static int nbd_do_send_reply(int csock, struct nbd_reply *reply,
- uint8_t *data, int len)
+static int nbd_do_send_reply(NBDRequest *req, struct nbd_reply *reply,
+ int len)
 {
+NBDClient *client = req->client;
+int csock = client->sock;
 int rc, ret;
 
 if (!len) {
@@ -688,7 +697,7 @@ static int nbd_do_send_reply(int csock, struct nbd_reply 
*reply,
 socket_set_cork(csock, 1);
 rc = nbd_send_reply(csock, reply);
 if (rc != -1) {
-ret = write_sync(csock, data, len);
+ret = write_sync(csock, req->data, len);
 if (ret != len) {
 errno = EIO;
 rc = -1;
@@ -702,9 +711,10 @@ static int nbd_do_send_reply(int csock, struct nbd_reply 
*reply,
 return rc;
 }
 
-static int nbd_do_receive_request(int csock, struct nbd_request *request,
-  uint8_t *data)
+static int nbd_do_receive_request(NBDRequest *req, struct nbd_request *request)
 {
+NBDClient *client = req->client;
+int csock = client->sock;
 int rc;
 
 if (nbd_receive_request(csock, request) == -1) {
@@ -731,7 +741,7 @@ static int nbd_do_receive_request(int csock, struct 
nbd_request *request,
 if ((request->type & NBD_CMD_MASK_COMMAND) == NBD_CMD_WRITE) {
 TRACE("Reading %u byte(s)", request->len);
 
-if (read_sync(csock, data, request->len) != request->len) {
+if (read_sync(csock, req->data, request->len) != request->len) {
 LOG("reading from socket failed");
 rc = -EIO;
 goto out;
@@ -745,9 +755,8 @@ out:
 
 static int nbd_trip(NBDClient *client)
 {
+NBDRequest *req = nbd_request_get(client);
 NBDExport *exp = client->exp;
-NBDRequest *req = nbd_request_get(exp);
-int csock = client->sock;
 struct nbd_request request;
 struct nbd_reply reply;
 int rc = -1;
@@ -755,7 +764,7 @@ static int nbd_trip(NBDClient *client)
 
 TRACE("Reading request.");
 
-ret = nbd_do_receive_request(csock, &request, req->data);
+ret = nbd_do_receive_request(req, &request);
 if (ret == -EIO) {
 goto out;
 }
@@ -790,7 +799,7 @@ static int nbd_trip(NBDClient *client)
 }
 
 TRACE("Read %u byte(s)", request.len);
-if (nbd_do_send_reply(csock, &reply, req->data, request.len) < 0)
+if (nbd_do_send_reply(req, &reply, request.len) < 0)
 goto out;
 break;
 case NBD_CMD_WRITE:
@@ -821,7 +830,7 @@ static int nbd_trip(NBDClient *client)
 }
 }
 
-if (nbd_do_send_reply(csock, &reply, NULL, 0) < 0)
+if (nbd_do_send_reply(req, &reply, 0) < 0)
 goto out;
 break;
 case NBD_CMD_DISC:
@@ -837,7 +846,7 @@ static int nbd_trip(NBDClient *client)
 reply.error = -ret;
 }
 
-if (nbd_do_send_reply(csock, &reply, NULL, 0) < 0)
+if (nbd_do_send_reply(req, &reply, 0) < 0)
 goto out;
 break;
 case NBD_CMD_TRIM:
@@ -848,7 +857,7 @@ static int nbd_trip(NBDClient *client)
 LOG("discard failed");
 

[Qemu-devel] [PATCH 14/26] qemu-nbd: simplify nbd_trip

2011-12-23 Thread Paolo Bonzini
Use TCP_CORK to remove a violation of encapsulation, that would later
require nbd_trip to know too much about an NBD reply.

We could also switch to sendmsg (qemu_co_sendv) later, it is even
easier once coroutines are in.

Signed-off-by: Paolo Bonzini 
---
 nbd.c |   25 -
 1 files changed, 8 insertions(+), 17 deletions(-)

diff --git a/nbd.c b/nbd.c
index d8cc331..d383d85 100644
--- a/nbd.c
+++ b/nbd.c
@@ -596,9 +596,9 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size,
 if (nbd_receive_request(csock, &request) == -1)
 return -1;
 
-if (request.len + NBD_REPLY_SIZE > NBD_BUFFER_SIZE) {
+if (request.len > NBD_BUFFER_SIZE) {
 LOG("len (%u) is larger than max len (%u)",
-request.len + NBD_REPLY_SIZE, NBD_BUFFER_SIZE);
+request.len, NBD_BUFFER_SIZE);
 errno = EINVAL;
 return -1;
 }
@@ -629,8 +629,7 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size,
 TRACE("Request type is READ");
 
 ret = bdrv_read(bs, (request.from + dev_offset) / 512,
-data + NBD_REPLY_SIZE,
-request.len / 512);
+data, request.len / 512);
 if (ret < 0) {
 LOG("reading from file failed");
 reply.error = -ret;
@@ -638,26 +637,18 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size,
 }
 
 TRACE("Read %u byte(s)", request.len);
-
-/* Reply
-   [ 0 ..  3]magic   (NBD_REPLY_MAGIC)
-   [ 4 ..  7]error   (0 == no error)
-   [ 7 .. 15]handle
- */
-
-cpu_to_be32w((uint32_t*)data, NBD_REPLY_MAGIC);
-cpu_to_be32w((uint32_t*)(data + 4), reply.error);
-cpu_to_be64w((uint64_t*)(data + 8), reply.handle);
+socket_set_cork(csock, 1);
+if (nbd_send_reply(csock, &reply) == -1)
+return -1;
 
 TRACE("Sending data to client");
 
-if (write_sync(csock, data,
-   request.len + NBD_REPLY_SIZE) !=
-   request.len + NBD_REPLY_SIZE) {
+if (write_sync(csock, data, request.len) != request.len) {
 LOG("writing to socket failed");
 errno = EINVAL;
 return -1;
 }
+socket_set_cork(csock, 0);
 break;
 case NBD_CMD_WRITE:
 TRACE("Request type is WRITE");
-- 
1.7.7.1





[Qemu-devel] [PATCH 16/26] qemu-nbd: more robust handling of invalid requests

2011-12-23 Thread Paolo Bonzini
Fail invalid requests with EINVAL instead of dropping them into
the void.

Signed-off-by: Paolo Bonzini 
---
 nbd.c |   57 ++---
 1 files changed, 30 insertions(+), 27 deletions(-)

diff --git a/nbd.c b/nbd.c
index 025c5b0..053ad8d 100644
--- a/nbd.c
+++ b/nbd.c
@@ -624,18 +624,19 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size,
 if (nbd_receive_request(csock, &request) == -1)
 return -1;
 
+reply.handle = request.handle;
+reply.error = 0;
+
 if (request.len > NBD_BUFFER_SIZE) {
 LOG("len (%u) is larger than max len (%u)",
 request.len, NBD_BUFFER_SIZE);
-errno = EINVAL;
-return -1;
+goto invalid_request;
 }
 
 if ((request.from + request.len) < request.from) {
 LOG("integer overflow detected! "
 "you're probably being attacked");
-errno = EINVAL;
-return -1;
+goto invalid_request;
 }
 
 if ((request.from + request.len) > size) {
@@ -643,15 +644,11 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size,
 ", Offset: %" PRIu64 "\n",
 request.from, request.len, (uint64_t)size, dev_offset);
 LOG("requested operation past EOF--bad client?");
-errno = EINVAL;
-return -1;
+goto invalid_request;
 }
 
 TRACE("Decoding type");
 
-reply.handle = request.handle;
-reply.error = 0;
-
 switch (request.type & NBD_CMD_MASK_COMMAND) {
 case NBD_CMD_READ:
 TRACE("Request type is READ");
@@ -661,7 +658,7 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size,
 if (ret < 0) {
 LOG("reading from file failed");
 reply.error = -ret;
-request.len = 0;
+goto error_reply;
 }
 
 TRACE("Read %u byte(s)", request.len);
@@ -681,24 +678,26 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size,
 
 if (nbdflags & NBD_FLAG_READ_ONLY) {
 TRACE("Server is read-only, return error");
-reply.error = 1;
-} else {
-TRACE("Writing to device");
+reply.error = EROFS;
+goto error_reply;
+}
+
+TRACE("Writing to device");
+
+ret = bdrv_write(bs, (request.from + dev_offset) / 512,
+ data, request.len / 512);
+if (ret < 0) {
+LOG("writing to file failed");
+reply.error = -ret;
+goto error_reply;
+}
 
-ret = bdrv_write(bs, (request.from + dev_offset) / 512,
- data, request.len / 512);
+if (request.type & NBD_CMD_FLAG_FUA) {
+ret = bdrv_flush(bs);
 if (ret < 0) {
-LOG("writing to file failed");
+LOG("flush failed");
 reply.error = -ret;
-request.len = 0;
-}
-
-if (request.type & NBD_CMD_FLAG_FUA) {
-ret = bdrv_flush(bs);
-if (ret < 0) {
-LOG("flush failed");
-reply.error = -ret;
-}
+goto error_reply;
 }
 }
 
@@ -734,8 +733,12 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size,
 break;
 default:
 LOG("invalid request type (%u) received", request.type);
-errno = EINVAL;
-return -1;
+invalid_request:
+reply.error = -EINVAL;
+error_reply:
+if (nbd_do_send_reply(csock, &reply, NULL, 0) == -1)
+return -1;
+break;
 }
 
 TRACE("Request/Reply complete");
-- 
1.7.7.1





[Qemu-devel] [PATCH 18/26] qemu-nbd: introduce NBDExport

2011-12-23 Thread Paolo Bonzini
Wrap the common parameters of nbd_trip and nbd_negotiate in a
single opaque struct.

Signed-off-by: Paolo Bonzini 
---
 nbd.c  |   64 +---
 nbd.h  |   11 +++--
 qemu-nbd.c |   15 -
 3 files changed, 61 insertions(+), 29 deletions(-)

diff --git a/nbd.c b/nbd.c
index 964a732..8d2a3bc 100644
--- a/nbd.c
+++ b/nbd.c
@@ -18,6 +18,7 @@
 
 #include "nbd.h"
 #include "block.h"
+#include "block_int.h"
 
 #include 
 #include 
@@ -186,7 +187,7 @@ int unix_socket_outgoing(const char *path)
   Request (type == 2)
 */
 
-int nbd_negotiate(int csock, off_t size, uint32_t flags)
+static int nbd_send_negotiate(int csock, off_t size, uint32_t flags)
 {
 char buf[8 + 8 + 8 + 128];
 
@@ -583,6 +584,33 @@ static int nbd_send_reply(int csock, struct nbd_reply 
*reply)
 return 0;
 }
 
+struct NBDExport {
+BlockDriverState *bs;
+off_t dev_offset;
+off_t size;
+uint8_t *data;
+uint32_t nbdflags;
+};
+
+NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset,
+  off_t size, uint32_t nbdflags)
+{
+NBDExport *exp = g_malloc0(sizeof(NBDExport));
+exp->bs = bs;
+exp->dev_offset = dev_offset;
+exp->nbdflags = nbdflags;
+exp->size = size == -1 ? exp->bs->total_sectors * 512 : size;
+exp->data = qemu_blockalign(exp->bs, NBD_BUFFER_SIZE);
+return exp;
+}
+
+void nbd_export_close(NBDExport *exp)
+{
+qemu_vfree(exp->data);
+bdrv_close(exp->bs);
+g_free(exp);
+}
+
 static int nbd_do_send_reply(int csock, struct nbd_reply *reply,
  uint8_t *data, int len)
 {
@@ -652,9 +680,7 @@ out:
 return rc;
 }
 
-int nbd_trip(BlockDriverState *bs, int csock, off_t size,
- uint64_t dev_offset, uint32_t nbdflags,
- uint8_t *data)
+int nbd_trip(NBDExport *exp, int csock)
 {
 struct nbd_request request;
 struct nbd_reply reply;
@@ -662,7 +688,7 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size,
 
 TRACE("Reading request.");
 
-ret = nbd_do_receive_request(csock, &request, data);
+ret = nbd_do_receive_request(csock, &request, exp->data);
 if (ret == -EIO) {
 return -1;
 }
@@ -675,10 +701,11 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size,
 goto error_reply;
 }
 
-if ((request.from + request.len) > size) {
+if ((request.from + request.len) > exp->size) {
 LOG("From: %" PRIu64 ", Len: %u, Size: %" PRIu64
 ", Offset: %" PRIu64 "\n",
-request.from, request.len, (uint64_t)size, dev_offset);
+request.from, request.len,
+(uint64_t)exp->size, exp->dev_offset);
 LOG("requested operation past EOF--bad client?");
 goto invalid_request;
 }
@@ -687,8 +714,8 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size,
 case NBD_CMD_READ:
 TRACE("Request type is READ");
 
-ret = bdrv_read(bs, (request.from + dev_offset) / 512,
-data, request.len / 512);
+ret = bdrv_read(exp->bs, (request.from + exp->dev_offset) / 512,
+exp->data, request.len / 512);
 if (ret < 0) {
 LOG("reading from file failed");
 reply.error = -ret;
@@ -696,13 +723,13 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size,
 }
 
 TRACE("Read %u byte(s)", request.len);
-if (nbd_do_send_reply(csock, &reply, data, request.len) < 0)
+if (nbd_do_send_reply(csock, &reply, exp->data, request.len) < 0)
 return -1;
 break;
 case NBD_CMD_WRITE:
 TRACE("Request type is WRITE");
 
-if (nbdflags & NBD_FLAG_READ_ONLY) {
+if (exp->nbdflags & NBD_FLAG_READ_ONLY) {
 TRACE("Server is read-only, return error");
 reply.error = EROFS;
 goto error_reply;
@@ -710,8 +737,8 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size,
 
 TRACE("Writing to device");
 
-ret = bdrv_write(bs, (request.from + dev_offset) / 512,
- data, request.len / 512);
+ret = bdrv_write(exp->bs, (request.from + exp->dev_offset) / 512,
+ exp->data, request.len / 512);
 if (ret < 0) {
 LOG("writing to file failed");
 reply.error = -ret;
@@ -719,7 +746,7 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size,
 }
 
 if (request.type & NBD_CMD_FLAG_FUA) {
-ret = bdrv_flush(bs);
+ret = bdrv_flush(exp->bs);
 if (ret < 0) {
 LOG("flush failed");
 reply.error = -ret;
@@ -737,7 +764,7 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size,
 case NBD_CMD_FLUSH:
 TRACE("Request type is FLUSH");
 
-ret = bdrv_flush(bs);
+ret = bdrv_flush(exp->bs);
 if (ret < 0) {
 LOG("f

[Qemu-devel] [PATCH 21/26] qemu-nbd: use common main loop

2011-12-23 Thread Paolo Bonzini
Using a single main loop for sockets will help yielding from the socket
coroutine back to the main loop, and later reentering it.

Signed-off-by: Paolo Bonzini 
---
 qemu-nbd.c |  112 
 1 files changed, 45 insertions(+), 67 deletions(-)

diff --git a/qemu-nbd.c b/qemu-nbd.c
index d5ac75e..347c776 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -35,12 +35,15 @@
 
 #define SOCKET_PATH"/var/lock/qemu-nbd-%s"
 
-static int sigterm_wfd;
 static NBDExport *exp;
 static int verbose;
 static char *device;
 static char *srcpath;
 static char *sockpath;
+static bool sigterm_reported;
+static bool nbd_started;
+static int shared = 1;
+static int nb_fds;
 
 static void usage(const char *name)
 {
@@ -169,10 +172,8 @@ static int find_partition(BlockDriverState *bs, int 
partition,
 
 static void termsig_handler(int signum)
 {
-static int sigterm_reported;
-if (!sigterm_reported) {
-sigterm_reported = (write(sigterm_wfd, "", 1) == 1);
-}
+sigterm_reported = true;
+qemu_notify_event();
 }
 
 static void *show_parts(void *arg)
@@ -243,6 +244,36 @@ out:
 return (void *) EXIT_FAILURE;
 }
 
+static int nbd_can_accept(void *opaque)
+{
+return nb_fds < shared;
+}
+
+static void nbd_read(void *opaque)
+{
+int fd = (uintptr_t) opaque;
+
+if (nbd_trip(exp, fd) != 0) {
+qemu_set_fd_handler2(fd, NULL, NULL, NULL, NULL);
+close(fd);
+nb_fds--;
+}
+}
+
+static void nbd_accept(void *opaque)
+{
+int server_fd = (uintptr_t) opaque;
+struct sockaddr_in addr;
+socklen_t addr_len = sizeof(addr);
+
+int fd = accept(server_fd, (struct sockaddr *)&addr, &addr_len);
+nbd_started = true;
+if (fd != -1 && nbd_negotiate(exp, fd) != -1) {
+qemu_set_fd_handler2(fd, NULL, nbd_read, NULL, (void *) (intptr_t) fd);
+nb_fds++;
+}
+}
+
 int main(int argc, char **argv)
 {
 BlockDriverState *bs;
@@ -251,8 +282,6 @@ int main(int argc, char **argv)
 bool disconnect = false;
 const char *bindto = "0.0.0.0";
 int port = NBD_DEFAULT_PORT;
-struct sockaddr_in addr;
-socklen_t addr_len = sizeof(addr);
 off_t fd_size;
 const char *sopt = "hVb:o:p:rsnP:c:dvk:e:t";
 struct option lopt[] = {
@@ -280,13 +309,7 @@ int main(int argc, char **argv)
 int flags = BDRV_O_RDWR;
 int partition = -1;
 int ret;
-int shared = 1;
-fd_set fds;
-int *sharing_fds;
 int fd;
-int i;
-int nb_fds = 0;
-int max_fd;
 int persistent = 0;
 pthread_t client_thread;
 
@@ -294,12 +317,6 @@ int main(int argc, char **argv)
  * handler ensures that "qemu-nbd -v -c" exits with a nice status code.
  */
 struct sigaction sa_sigterm;
-int sigterm_fd[2];
-if (qemu_pipe(sigterm_fd) == -1) {
-err(EXIT_FAILURE, "Error setting up communication pipe");
-}
-
-sigterm_wfd = sigterm_fd[1];
 memset(&sa_sigterm, 0, sizeof(sa_sigterm));
 sa_sigterm.sa_handler = termsig_handler;
 sigaction(SIGTERM, &sa_sigterm, NULL);
@@ -490,16 +507,16 @@ int main(int argc, char **argv)
 }
 
 exp = nbd_export_new(bs, dev_offset, fd_size, nbdflags);
-sharing_fds = g_malloc((shared + 1) * sizeof(int));
 
 if (sockpath) {
-sharing_fds[0] = unix_socket_incoming(sockpath);
+fd = unix_socket_incoming(sockpath);
 } else {
-sharing_fds[0] = tcp_socket_incoming(bindto, port);
+fd = tcp_socket_incoming(bindto, port);
 }
 
-if (sharing_fds[0] == -1)
+if (fd == -1) {
 return 1;
+}
 
 if (device) {
 int ret;
@@ -514,54 +531,15 @@ int main(int argc, char **argv)
 memset(&client_thread, 0, sizeof(client_thread));
 }
 
-max_fd = sharing_fds[0];
-nb_fds++;
+qemu_init_main_loop();
+qemu_set_fd_handler2(fd, nbd_can_accept, nbd_accept, NULL,
+ (void *)(uintptr_t)fd);
 
 do {
-FD_ZERO(&fds);
-FD_SET(sigterm_fd[0], &fds);
-for (i = 0; i < nb_fds; i++)
-FD_SET(sharing_fds[i], &fds);
-
-do {
-ret = select(max_fd + 1, &fds, NULL, NULL, NULL);
-} while (ret == -1 && errno == EINTR);
-if (ret == -1 || FD_ISSET(sigterm_fd[0], &fds)) {
-break;
-}
-
-if (FD_ISSET(sharing_fds[0], &fds))
-ret--;
-for (i = 1; i < nb_fds && ret; i++) {
-if (FD_ISSET(sharing_fds[i], &fds)) {
-if (nbd_trip(exp, sharing_fds[i]) != 0) {
-close(sharing_fds[i]);
-nb_fds--;
-sharing_fds[i] = sharing_fds[nb_fds];
-i--;
-}
-ret--;
-}
-}
-/* new connection ? */
-if (FD_ISSET(sharing_fds[0], &fds)) {
-if (nb_fds < shared + 1) {
-sharing_fds[nb_fds] = accept(sharing_fds[0],
- (struct sock

[Qemu-devel] [PATCH 10/26] Update ioctl order in nbd_init() to detect EBUSY

2011-12-23 Thread Paolo Bonzini
From: Chunyan Liu 

Update ioctl(s) in nbd_init() to detect device busy early.

Current nbd_init() issues NBD_CLEAR_SOCKET before NBD_SET_SOCKET, if issuing
"qemu-nbd -c /dev/nbd0 disk.img" twice, the second time won't detect EBUSY in
nbd_init(), but in nbd_client will report EBUSY and do clear socket (the 1st
time command will be affacted too because of no socket any more.)

No change to previous version.

Signed-off-by: Chunyan Liu 

Signed-off-by: Paolo Bonzini 
---
 nbd.c |   27 +--
 1 files changed, 9 insertions(+), 18 deletions(-)

diff --git a/nbd.c b/nbd.c
index 7ab1b1f..73fedeb 100644
--- a/nbd.c
+++ b/nbd.c
@@ -358,6 +358,15 @@ int nbd_receive_negotiate(int csock, const char *name, 
uint32_t *flags,
 #ifdef __linux__
 int nbd_init(int fd, int csock, uint32_t flags, off_t size, size_t blocksize)
 {
+TRACE("Setting NBD socket");
+
+if (ioctl(fd, NBD_SET_SOCK, csock) == -1) {
+int serrno = errno;
+LOG("Failed to set NBD socket");
+errno = serrno;
+return -1;
+}
+
 TRACE("Setting block size to %lu", (unsigned long)blocksize);
 
 if (ioctl(fd, NBD_SET_BLKSIZE, blocksize) == -1) {
@@ -396,24 +405,6 @@ int nbd_init(int fd, int csock, uint32_t flags, off_t 
size, size_t blocksize)
 return -1;
 }
 
-TRACE("Clearing NBD socket");
-
-if (ioctl(fd, NBD_CLEAR_SOCK) == -1) {
-int serrno = errno;
-LOG("Failed clearing NBD socket");
-errno = serrno;
-return -1;
-}
-
-TRACE("Setting NBD socket");
-
-if (ioctl(fd, NBD_SET_SOCK, csock) == -1) {
-int serrno = errno;
-LOG("Failed to set NBD socket");
-errno = serrno;
-return -1;
-}
-
 TRACE("Negotiation ended");
 
 return 0;
-- 
1.7.7.1





[Qemu-devel] [PATCH 08/26] nbd: add support for NBD_CMD_FLUSH

2011-12-23 Thread Paolo Bonzini
Signed-off-by: Paolo Bonzini 
---
 block/nbd.c |   45 +
 nbd.c   |   15 ++-
 2 files changed, 51 insertions(+), 9 deletions(-)

diff --git a/block/nbd.c b/block/nbd.c
index 2f483cd..097b418 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -407,6 +407,34 @@ static int nbd_co_writev(BlockDriverState *bs, int64_t 
sector_num,
 return nbd_co_writev_1(bs, sector_num, nb_sectors, qiov, offset);
 }
 
+static int nbd_co_flush(BlockDriverState *bs)
+{
+BDRVNBDState *s = bs->opaque;
+struct nbd_request request;
+struct nbd_reply reply;
+
+if (!(s->nbdflags & NBD_FLAG_SEND_FLUSH)) {
+return 0;
+}
+
+request.type = NBD_CMD_FLUSH;
+if (s->nbdflags & NBD_FLAG_SEND_FUA) {
+request.type |= NBD_CMD_FLAG_FUA;
+}
+
+request.from = 0;
+request.len = 0;
+
+nbd_coroutine_start(s, &request);
+if (nbd_co_send_request(s, &request, NULL, 0) == -1) {
+reply.error = errno;
+} else {
+nbd_co_receive_reply(s, &request, &reply, NULL, 0);
+}
+nbd_coroutine_end(s, &request);
+return -reply.error;
+}
+
 static void nbd_close(BlockDriverState *bs)
 {
 BDRVNBDState *s = bs->opaque;
@@ -424,14 +452,15 @@ static int64_t nbd_getlength(BlockDriverState *bs)
 }
 
 static BlockDriver bdrv_nbd = {
-.format_name   = "nbd",
-.instance_size = sizeof(BDRVNBDState),
-.bdrv_file_open= nbd_open,
-.bdrv_co_readv = nbd_co_readv,
-.bdrv_co_writev= nbd_co_writev,
-.bdrv_close= nbd_close,
-.bdrv_getlength= nbd_getlength,
-.protocol_name = "nbd",
+.format_name = "nbd",
+.instance_size   = sizeof(BDRVNBDState),
+.bdrv_file_open  = nbd_open,
+.bdrv_co_readv   = nbd_co_readv,
+.bdrv_co_writev  = nbd_co_writev,
+.bdrv_close  = nbd_close,
+.bdrv_co_flush_to_os = nbd_co_flush,
+.bdrv_getlength  = nbd_getlength,
+.protocol_name   = "nbd",
 };
 
 static void bdrv_nbd_init(void)
diff --git a/nbd.c b/nbd.c
index c597d47..4fd0f4e 100644
--- a/nbd.c
+++ b/nbd.c
@@ -203,7 +203,8 @@ int nbd_negotiate(int csock, off_t size, uint32_t flags)
 cpu_to_be64w((uint64_t*)(buf + 8), 0x00420281861253LL);
 cpu_to_be64w((uint64_t*)(buf + 16), size);
 cpu_to_be32w((uint32_t*)(buf + 24),
- flags | NBD_FLAG_HAS_FLAGS | NBD_FLAG_SEND_FUA);
+ flags | NBD_FLAG_HAS_FLAGS | NBD_FLAG_SEND_FLUSH |
+ NBD_FLAG_SEND_FUA);
 memset(buf + 28, 0, 124);
 
 if (write_sync(csock, buf, sizeof(buf)) != sizeof(buf)) {
@@ -710,6 +711,18 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size, 
uint64_t dev_offset,
 TRACE("Request type is DISCONNECT");
 errno = 0;
 return 1;
+case NBD_CMD_FLUSH:
+TRACE("Request type is FLUSH");
+
+ret = bdrv_flush(bs);
+if (ret < 0) {
+LOG("flush failed");
+reply.error = -ret;
+}
+
+if (nbd_send_reply(csock, &reply) == -1)
+return -1;
+break;
 default:
 LOG("invalid request type (%u) received", request.type);
 errno = EINVAL;
-- 
1.7.7.1





Re: [Qemu-devel] [PATCH v2] prepare for future GPLv2+ relicensing

2011-12-23 Thread Andreas Färber
Am 23.12.2011 16:19, schrieb Paolo Bonzini:
> All files under GPLv2 will get GPLv2+ changes starting next Christmas.

> Files that were only ever touched by Red Hat employees can be relicensed
> now.

Quoting from IRC: "it's just event_notifier.c and exec-obsolete.h"

Would be nice if the committer could add that, e.g.:

Files that were only ever touched by Red Hat employees can be relicensed
now: event_notifier.[ch] and exec-obsolete.h

Otherwise

Reviewed-by: Andreas Färber 

Andreas

> 
> Signed-off-by: Paolo Bonzini 
> ---
>  aio.c  |2 ++
>  block-migration.c  |2 ++
>  block/raw-posix-aio.h  |2 ++
>  block/rbd.c|2 ++
>  block/sheepdog.c   |3 +++
>  buffered_file.c|2 ++
>  compatfd.c |2 ++
>  event_notifier.c   |4 ++--
>  event_notifier.h   |   12 
>  exec-obsolete.h|4 ++--
>  hmp.c  |2 ++
>  hw/ac97.c  |3 +++
>  hw/acpi.c  |3 +++
>  hw/acpi_piix4.c|3 +++
>  hw/ads7846.c   |3 +++
>  hw/apm.c   |3 +++
>  hw/bitbang_i2c.c   |3 +++
>  hw/bonito.c|3 +++
>  hw/collie.c|3 +++
>  hw/ds1338.c|3 +++
>  hw/ecc.c   |3 +++
>  hw/framebuffer.c   |3 +++
>  hw/gumstix.c   |3 +++
>  hw/ivshmem.c   |3 +++
>  hw/kvmclock.c  |2 ++
>  hw/lan9118.c   |3 +++
>  hw/mainstone.c |3 +++
>  hw/marvell_88w8618_audio.c |3 +++
>  hw/max111x.c   |3 +++
>  hw/mips_fulong2e.c |3 +++
>  hw/msix.c  |3 +++
>  hw/mst_fpga.c  |3 +++
>  hw/musicpal.c  |3 +++
>  hw/nand.c  |3 +++
>  hw/pl031.c |2 ++
>  hw/pxa2xx_keypad.c |3 +++
>  hw/pxa2xx_lcd.c|3 +++
>  hw/pxa2xx_mmci.c   |3 +++
>  hw/pxa2xx_pcmcia.c |3 +++
>  hw/smbios.c|2 ++
>  hw/spitz.c |3 +++
>  hw/ssi-sd.c|3 +++
>  hw/ssi.c   |3 +++
>  hw/strongarm.c |3 +++
>  hw/tc6393xb.c  |3 +++
>  hw/tosa.c  |3 +++
>  hw/vexpress.c  |3 +++
>  hw/vhost.c |3 +++
>  hw/vhost_net.c |3 +++
>  hw/virtio-pci.c|2 ++
>  hw/virtio-serial-bus.c |3 +++
>  hw/vt82c686.c  |3 +++
>  hw/xen_backend.c   |3 +++
>  hw/xen_disk.c  |3 +++
>  hw/xen_nic.c   |3 +++
>  hw/z2.c|3 +++
>  iov.c  |3 +++
>  memory.c   |2 ++
>  migration-exec.c   |2 ++
>  migration-fd.c |2 ++
>  migration-tcp.c|2 ++
>  migration-unix.c   |2 ++
>  migration.c|2 ++
>  module.c   |2 ++
>  net/checksum.c |3 +++
>  notify.c   |2 ++
>  pflib.c|2 ++
>  posix-aio-compat.c |2 ++
>  qemu-tool.c|2 ++
>  qmp.c  |2 ++
>  xen-all.c  |2 ++
>  xen-mapcache.c |2 ++
>  xen-stub.c |2 ++
>  73 files changed, 200 insertions(+), 4 deletions(-)

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



[Qemu-devel] [Bug 883136] Re: qemu on ARM hosts aborts on startup because makecontext() always fails

2011-12-23 Thread Dr. David Alan Gilbert
OK, here is a eglibc patch that adds the context routines; seems to pass
Stefan's magic coroutine test, pass all the context specific tests in
eglibc and boots a debian image on qemu.  (Not run a full eglibc test
run yet).

Dave

** Attachment added: "eglibc patch for ARM context routines"
   
https://bugs.launchpad.net/qemu-linaro/+bug/883136/+attachment/2644972/+files/context-diff-v0.3

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

Title:
  qemu on ARM hosts aborts on startup because makecontext() always fails

Status in QEMU:
  New
Status in Linaro QEMU:
  New

Bug description:
  qemu has recently grown a coroutines implementation. There are two
  versions, one using the makecontext/setcontext/swapcontext functions
  from ucontext.h, and one falling back to implementing coroutines as
  separate glib threads. configure chooses the former if the platform
  has a makecontext().

  Unfortunately ARM eglibc provides a makecontext() which always fails
  ENOSYS, which means the configure check passes but when qemu starts it
  abort()s.

  The best fix for this is probably going to involve making the
  coroutine implementation runtime-selectable.

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



Re: [Qemu-devel] [Spice-devel] Seem thread Competition

2011-12-23 Thread Ademar de Souza Reis Jr.
On Thu, Dec 22, 2011 at 07:07:14PM +0800, ZhouPeng wrote:
> On Thu, Dec 22, 2011 at 6:00 PM, Alon Levy  wrote:
> > On Thu, Dec 22, 2011 at 05:42:29PM +0800, ZhouPeng wrote:
> >> On Thu, Dec 22, 2011 at 4:42 PM, Alon Levy  wrote:
> >> > On Thu, Dec 22, 2011 at 10:13:50AM +0800, ZhouPeng wrote:
> >> >> Hi,
> >> >>
> >> >> I meet the err:
> >> >>
> >> >> # virsh dumpxml 63
> >> >> error: internal error cannot parse json {"timestamp": {"seconds":
> >> >> 1323332828, "microseco{"timest35p":39}, "econds":PICE_D 1CO3233TE828,
> >> >> Dmicrosec "ds"data"52}, : {"ser: "SPrCE_DIS"ONNEC{ED", "port": {"serve
> >> >> ": {6299": "62, "famiamily": "ipv:", "hist": pv4"1 "hos6":
> >> >> "182.168.12.231"}, "2lient.: {"p2rt": 3350196, "fa"ily": "}, "cl,
> >> >> "ho{sport":t"35020", ": "19y": "i2.4", "168.1.": "19}: lexical error:
> >> >> invalid string in json text.
> >> >>           ds": 1323332828, "microseco{"timest35p":39}, "econds":PICE_D
> >> >>
> >> >> This similar bug seems has been reported by:
> >> >> https://bugzilla.redhat.com/show_bug.cgi?id=744105
> >> >>
> >> >> The patch(http://cgit.freedesktop.org/spice/qemu/commit/?h=spice.v42)
> >> >> seems be related with the competition.
> >> >> But I searched the upstream qemu, it has not been merged in.
> >> >>
> >> >> My qemu is qemu-kvm-0.15.1 on 3.1.2-1.fc16.x86_64
> >> >>
> >> >> Is there any plan about this bug, it seems be some serious.
> >> >>
> >> >
> >> > The patch Daniel Berrange mentioned wotrked around it in qemu and is in
> >> > qemu 1.0-rc0 and onward, still checking qemu-kvm. There is another patch
> >>
> >> Yea, I searched  in spice-core.c again and the patch is in qemu unstable
> >> Sorry, I carelessly search by " me " but not " me;" before.
> >
> > It is in qemu-kvm-1.0 as well. But like you said fedora carries 0.15.1
> > that doesn't have it.
> >
> >> > in spice-0.10 and in 0.8, still need to check if it's in fedora. Which
> >> > version of spice are you using?
> >>
> >> spice-server.x86_64  version 0.9.1
> >
> > which doesn't have the spice side fix. but 0.10.0 has it, and it is
> > closest to 0.9.1. I assume this is from the fedora package as well since
> > you mentioned qemu-kvm is from a fedora package? seems the latest is
> > indeed 0.9.1-1, can you test
> > http://koji.fedoraproject.org/koji/buildinfo?buildID=273917
> > (spice-server-0.10.0-1)?
> [root@localhost ~]# rpm -i spice-server-0.10.0-1.fc16.x86_64.rpm
> file /usr/lib64/libspice-server.so.1.0.2 from install of
> spice-server-0.10.0-1.fc16.x86_64 conflicts with file from package
> spice-server-0.9.1-1.fc16.x86_64
> 
> So I force install
> rpm -i --force spice-server-0.10.0-1.fc16.x86_64.rpm

You should use rpm -U (upgrade), not -i (install). Or better
yet, yum install 

> 
> yum list installed:
> spice-server.x86_64 0.9.1-1.fc16 
> @anaconda-0
> spice-server.x86_64 0.10.0-1.fc16installed
> 
> 0.9.1-1.fc16 seems not be overrided.
> 
> So  first, I am not sure qemu-kvm will use 0.10.0-1.fc16  or 0.9.1-1.fc16

That's because you now have the two versions installed. Remove
them using rpm -e spice-server-0.10.0-1 spice-server-0.9.1-1 and
then reinstall the version you want.

As a general rule, never use --force unless you're absolutely
sure of what you're doing, and prefer to use yum as much as
possible.

Cheers,
   - Ademar

> 
> Second, this is a random bug, I am not sure when it will  appear again.
> -- 
> Zhou Peng
> ___
> Spice-devel mailing list
> spice-de...@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel

-- 
Ademar de Souza Reis Jr.
Red Hat



[Qemu-devel] [PATCH] qmp: Add missing gcc format attribute and fix format string

2011-12-23 Thread Stefan Weil
Signed-off-by: Stefan Weil 
---
 test-qmp-input-visitor.c |7 ---
 1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/test-qmp-input-visitor.c b/test-qmp-input-visitor.c
index 1f3ab03..bc410c6 100644
--- a/test-qmp-input-visitor.c
+++ b/test-qmp-input-visitor.c
@@ -38,8 +38,9 @@ static void visitor_input_teardown(TestInputVisitorData *data,
 /* This is provided instead of a test setup function so that the JSON
string used by the tests are kept in the test functions (and not
int main()) */
-static Visitor *visitor_input_test_init(TestInputVisitorData *data,
-const char *json_string, ...)
+static GCC_FMT_ATTR(2, 3)
+Visitor *visitor_input_test_init(TestInputVisitorData *data,
+ const char *json_string, ...)
 {
 Visitor *v;
 va_list ap;
@@ -66,7 +67,7 @@ static void test_visitor_in_int(TestInputVisitorData *data,
 Error *errp = NULL;
 Visitor *v;
 
-v = visitor_input_test_init(data, "%d", value);
+v = visitor_input_test_init(data, "%" PRId64, value);
 
 visit_type_int(v, &res, NULL, &errp);
 g_assert(!error_is_set(&errp));
-- 
1.7.2.5




Re: [Qemu-devel] Fwd: Re: [target-mips] qemu on centos

2011-12-23 Thread Stefan Weil

Am 23.12.2011 19:05, schrieb Brendan Kirby:

Attached are three MIPS binaries that I have seen segfault
intermittently on CentOS 6 machines. Just run them with no arguments
several times.

Brendan

On Fri, 2011-12-23 at 09:00 -0800, Reed Kotler wrote:


Please work with this guy.

If possible, submit some test cases to them of some code that causes
segfaults on Centos 6, even if intermittent.

Reed

 Original Message 
Subject:
Re: [Qemu-devel] [target-mips] qemu
on centos
Date:
Fri, 23 Dec 2011 14:25:57 +0100
From:
Andreas Färber 
Organization:
SUSE LINUX Products GmbH
To:
Reed Kotler 
CC:
, Khansa
Butt , Richard
Henderson ,
Richard Sandiford



Hi,

Am 23.12.2011 13:44, schrieb Reed Kotler:

We have been seeing various problems running qemu for MIPS target on
Centos 5.
We are running linux user mode programs.

Qemu segfaults.

We recently tried upgrading to Centos 6 and the problem there is much
worse, making it basically unusable.

The same programs have no problem when running on Ubuntu.


They likely are using different QEMU versions, and distros may have
different patches applied on top.
Please provide some more info on what version, what ABI (which
executable), what -cpu parameter (if any), etc. you are using. Does a
gdb backtrace indicate any QEMU function or is it from translated code?

For n64 there were some patches in need of testing, review and fixing.
[cc'ing Khansa]

For n32 there's signal handling missing. (openSUSE for one ignores the
build warning and provides it non the less.)

No known issues specific to o32 that I'm aware of, but the two Richards
had patches for some instructions. Shouldn't lead to segfaults though.

Regards,
Andreas

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




Please add your message at the bottom of the mail, not at the top.

I tried your binaries with latest QEMU. All three fail here each time
with SIGSEGV. This is caused by a jump to address 0 (pc = 0).
Up to now I don't know the reason for this jump.

Call stack:
#0  0x555f62d2 in ldl_le_p (ptr=0x0) at 
/home/stefan/src/qemu/qemu.org/qemu/bswap.h:477
#1  0x5561333e in gen_intermediate_code_internal 
(env=0x57ca0b10, tb=0x73982108, search_pc=0) at 
/home/stefan/src/qemu/qemu.org/qemu/target-mips/translate.c:12442
#2  0x55613709 in gen_intermediate_code (env=0x57ca0b10, 
tb=0x73982108) at 
/home/stefan/src/qemu/qemu.org/qemu/target-mips/translate.c:12528
#3  0x555f5f8d in cpu_mips_gen_code (env=0x57ca0b10, 
tb=0x73982108, gen_code_size_ptr=0x7fffd748) at 
/home/stefan/src/qemu/qemu.org/qemu/translate-all.c:66
#4  0x555a33b3 in tb_gen_code (env=0x57ca0b10, pc=0, 
cs_base=0, flags=34, cflags=0) at 
/home/stefan/src/qemu/qemu.org/qemu/exec.c:1003
#5  0x5559c5b2 in tb_find_slow (env=0x57ca0b10, pc=0, 
cs_base=0, flags=34) at /home/stefan/src/qemu/qemu.org/qemu/cpu-exec.c:126
#6  0x5559c73c in tb_find_fast (env=0x57ca0b10) at 
/home/stefan/src/qemu/qemu.org/qemu/cpu-exec.c:153
#7  0x5559cb2a in cpu_mips_exec (env=0x57ca0b10) at 
/home/stefan/src/qemu/qemu.org/qemu/cpu-exec.c:536
#8  0x555bf780 in cpu_loop (env=0x57ca0b10) at 
/home/stefan/src/qemu/qemu.org/qemu/linux-user/main.c:2160
#9  0x555c16ac in main (argc=7, argv=0x7fffe1c8, 
envp=0x7fffe208) at 
/home/stefan/src/qemu/qemu.org/qemu/linux-user/main.c:3812


Try running a working version and the bad version with
mipsel-linux-user/qemu-mipsel -d in_asm,cpu -singlestep ...
and compare the resulting output file /tmp/qemu.log.
For programs without external events (timers and other
interrupt sources), the program flow should be identical
(same instructions, same register values).

This should identify the mips code which is handled differently
by the two versions.

Here is an extract of my qemu.log which shows the jump to
address 0.

pc=0x004027d8 HI=0x018a LO=0xf816 ds 0022 004027c0 0
GPR00: r0  at fff8 v0 4081190c v1 0814
GPR04: a0 0040248c a1 0001 a2 4080042c a3 00402650
GPR08: t0 004026f4 t1 0ffe t2 0063 t3 0002
GPR12: t4 40800180 t5 40800228 t6  t7 00400538
GPR16: s0 4083a010 s1 004004f0 s2  s3 
GPR20: s4  s5  s6  s7 
GPR24: t8 0002 t9  k0  k1 
GPR28: gp 00412804 sp 40800408 s8  ra 00400538
CP0 Status  0x Cause   0x EPC0x
Config0 0x8482 Config1 0x9e190c8f LLAddr 0x
CP1 FCR0 0x  FCR31 0x  SR.FR 0  fp_status 0x00
 f0: w:3f80 d:40003f80 fd:  4.61169e+18 fs:  1.06535e+09 
psu:  1.07374e+09
 f2: w: d: fd:0 fs:0 
psu:0
 f4: w: d: fd:0 fs:0 
psu:0
 f6: w: d: fd:0 fs:  

Re: [Qemu-devel] Fwd: Re: [target-mips] qemu on centos

2011-12-23 Thread Brendan Kirby
On Fri, 2011-12-23 at 23:57 +0100, Stefan Weil wrote:
> Am 23.12.2011 19:05, schrieb Brendan Kirby:
> > Attached are three MIPS binaries that I have seen segfault
> > intermittently on CentOS 6 machines. Just run them with no arguments
> > several times.
> >
> > Brendan
> >
> > On Fri, 2011-12-23 at 09:00 -0800, Reed Kotler wrote:
> >>
> >> Please work with this guy.
> >>
> >> If possible, submit some test cases to them of some code that causes
> >> segfaults on Centos 6, even if intermittent.
> >>
> >> Reed
> >>
> >>  Original Message 
> >> Subject:
> >> Re: [Qemu-devel] [target-mips] qemu
> >> on centos
> >> Date:
> >> Fri, 23 Dec 2011 14:25:57 +0100
> >> From:
> >> Andreas Färber 
> >> Organization:
> >> SUSE LINUX Products GmbH
> >> To:
> >> Reed Kotler 
> >> CC:
> >> , Khansa
> >> Butt , Richard
> >> Henderson ,
> >> Richard Sandiford
> >> 
> >>
> >>
> >> Hi,
> >>
> >> Am 23.12.2011 13:44, schrieb Reed Kotler:
> >>> We have been seeing various problems running qemu for MIPS target on
> >>> Centos 5.
> >>> We are running linux user mode programs.
> >>>
> >>> Qemu segfaults.
> >>>
> >>> We recently tried upgrading to Centos 6 and the problem there is much
> >>> worse, making it basically unusable.
> >>>
> >>> The same programs have no problem when running on Ubuntu.
> >>
> >> They likely are using different QEMU versions, and distros may have
> >> different patches applied on top.
> >> Please provide some more info on what version, what ABI (which
> >> executable), what -cpu parameter (if any), etc. you are using. Does a
> >> gdb backtrace indicate any QEMU function or is it from translated code?
> >>
> >> For n64 there were some patches in need of testing, review and fixing.
> >> [cc'ing Khansa]
> >>
> >> For n32 there's signal handling missing. (openSUSE for one ignores the
> >> build warning and provides it non the less.)
> >>
> >> No known issues specific to o32 that I'm aware of, but the two Richards
> >> had patches for some instructions. Shouldn't lead to segfaults though.
> >>
> >> Regards,
> >> Andreas
> >>
> >> -- 
> >> SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
> >> GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
> >
> 
> Please add your message at the bottom of the mail, not at the top.

> I tried your binaries with latest QEMU. All three fail here each time
> with SIGSEGV. This is caused by a jump to address 0 (pc = 0).
> Up to now I don't know the reason for this jump.

The binaries should be the same on both the CentOS 5 and CentOS 6
machines.  (They're compiled with the same compiler, at least)  But,
I'll verify that.  I neglected to mention the version of QEMU I'm
running.  Here is the version string:
qemu-mips version 0.14.50 (Sourcery CodeBench 2011.03-95), Copyright (c)
2003-2008 Fabrice Bellard, 2008-2011 Mentor Graphics

And, the version string for GCC that the two mipsgcc binaries were
compiled with is:
mips-linux-gnu-gcc (Sourcery CodeBench 2011.03-95) 4.5.2
Copyright (C) 2010 Free Software Foundation, Inc.

> Call stack:
> #0  0x555f62d2 in ldl_le_p (ptr=0x0) at 
> /home/stefan/src/qemu/qemu.org/qemu/bswap.h:477
> #1  0x5561333e in gen_intermediate_code_internal 
> (env=0x57ca0b10, tb=0x73982108, search_pc=0) at 
> /home/stefan/src/qemu/qemu.org/qemu/target-mips/translate.c:12442
> #2  0x55613709 in gen_intermediate_code (env=0x57ca0b10, 
> tb=0x73982108) at 
> /home/stefan/src/qemu/qemu.org/qemu/target-mips/translate.c:12528
> #3  0x555f5f8d in cpu_mips_gen_code (env=0x57ca0b10, 
> tb=0x73982108, gen_code_size_ptr=0x7fffd748) at 
> /home/stefan/src/qemu/qemu.org/qemu/translate-all.c:66
> #4  0x555a33b3 in tb_gen_code (env=0x57ca0b10, pc=0, 
> cs_base=0, flags=34, cflags=0) at 
> /home/stefan/src/qemu/qemu.org/qemu/exec.c:1003
> #5  0x5559c5b2 in tb_find_slow (env=0x57ca0b10, pc=0, 
> cs_base=0, flags=34) at /home/stefan/src/qemu/qemu.org/qemu/cpu-exec.c:126
> #6  0x5559c73c in tb_find_fast (env=0x57ca0b10) at 
> /home/stefan/src/qemu/qemu.org/qemu/cpu-exec.c:153
> #7  0x5559cb2a in cpu_mips_exec (env=0x57ca0b10) at 
> /home/stefan/src/qemu/qemu.org/qemu/cpu-exec.c:536
> #8  0x555bf780 in cpu_loop (env=0x57ca0b10) at 
> /home/stefan/src/qemu/qemu.org/qemu/linux-user/main.c:2160
> #9  0x555c16ac in main (argc=7, argv=0x7fffe1c8, 
> envp=0x7fffe208) at 
> /home/stefan/src/qemu/qemu.org/qemu/linux-user/main.c:3812
> 
> Try running a working version and the bad version with
> mipsel-linux-user/qemu-mipsel -d in_asm,cpu -singlestep ...
> and compare the resulting output file /tmp/qemu.log.
> For programs without external events (timers and other
> interrupt sources), the program flow should be identical
> (same instructions, same register values).
> 
> This should identify the mips code which is handled differently
> by the two versions.
> 
> Here is an extract of my qemu.log which shows t

Re: [Qemu-devel] [target-mips] qemu on centos

2011-12-23 Thread Stefan Weil

Am 23.12.2011 23:57, schrieb Stefan Weil:

Am 23.12.2011 19:05, schrieb Brendan Kirby:

Attached are three MIPS binaries that I have seen segfault
intermittently on CentOS 6 machines. Just run them with no arguments
several times.

Brendan


I tried your binaries with latest QEMU. All three fail here each time
with SIGSEGV. This is caused by a jump to address 0 (pc = 0).
Up to now I don't know the reason for this jump.


[snip]


An older qemu-mipsel from August fails, too.

Regards,
Stefan Weil


A version from May is better: it also has a jump to address 0,
but handles it correctly:

qemu-mipsel -L /media/vm/tftpboot/mips/malta-le mipsbin/bisort.llc.mips32r2
qemu: unhandled CPU exception 0xc - aborting
pc=0x HI=0x018a LO=0xf816 ds 0022  0
GPR00: r0  at fff8 v0 4081190c v1 0814
GPR04: a0 0040107c a1 0001 a2 4080043c a3 004012a0
GPR08: t0 00401344 t1 0ffe t2 0063 t3 0002
GPR12: t4 40800190 t5 40800238 t6  t7 004006a8
GPR16: s0 4083a010 s1 00400660 s2  s3 
GPR20: s4  s5  s6  s7 
GPR24: t8  t9  k0  k1 
GPR28: gp 00411544 sp 40800418 s8  ra 00401520
CP0 Status  0x Cause   0x EPC0x
Config0 0x8482 Config1 0x9e190c8f LLAddr 0x
CP1 FCR0 0x  FCR31 0x  SR.FR 0  fp_status 0x00
 f0: w:3f80 d:40003f80 fd:  4.61169e+18 fs:  1.06535e+09 
psu:  1.07374e+09
 f2: w: d: fd:0 fs:0 
psu:0
 f4: w: d: fd:0 fs:0 
psu:0
 f6: w: d: fd:0 fs:0 
psu:0
 f8: w: d: fd:0 fs:0 
psu:0
f10: w: d: fd:0 fs:0 
psu:0
f12: w: d: fd:0 fs:0 
psu:0
f14: w: d: fd:0 fs:0 
psu:0
f16: w: d: fd:0 fs:0 
psu:0
f18: w: d: fd:0 fs:0 
psu:0
f20: w: d: fd:0 fs:0 
psu:0
f22: w: d: fd:0 fs:0 
psu:0
f24: w: d: fd:0 fs:0 
psu:0
f26: w: d: fd:0 fs:0 
psu:0
f28: w: d: fd:0 fs:0 
psu:0
f30: w: d: fd:0 fs:0 
psu:0

qemu: uncaught target signal 6 (Aborted) - core dumped

Obviously signal handling for SIGSEGV in user code changed.
It now raises a SIGSEGV on the host...

Merry Christmas

Stefan Weil




Re: [Qemu-devel] [PATCH v2 1/9] arm: add missing scu registers

2011-12-23 Thread Peter Maydell
On 22 December 2011 18:20, Mark Langsdorf  wrote:
> From: Rob Herring 
>
> Add power control and non-secure access ctrl registers

Commit message says it's adding the non-secure
access control register, but the patch is only
doing power control.

>
> Signed-off-by: Rob Herring 
> Signed-off-by: Mark Langsdorf 
> ---
> Changes from v1:
>        Added VMState support
>        Checked alignment of writes to the power control register
>
>  hw/a9mpcore.c |   34 --
>  1 files changed, 32 insertions(+), 2 deletions(-)
>
> diff --git a/hw/a9mpcore.c b/hw/a9mpcore.c
> index cd2985f..875ae98 100644
> --- a/hw/a9mpcore.c
> +++ b/hw/a9mpcore.c
> @@ -29,6 +29,7 @@ gic_get_current_cpu(void)
>  typedef struct a9mp_priv_state {
>     gic_state gic;
>     uint32_t scu_control;
> +    uint32_t scu_status;
>     uint32_t old_timer_status[8];
>     uint32_t num_cpu;
>     qemu_irq *timer_irq;
> @@ -48,7 +49,13 @@ static uint64_t a9_scu_read(void *opaque, 
> target_phys_addr_t offset,
>     case 0x04: /* Configuration */
>         return (((1 << s->num_cpu) - 1) << 4) | (s->num_cpu - 1);
>     case 0x08: /* CPU Power Status */
> -        return 0;
> +        return s->scu_status;
> +    case 0x09: /* CPU status.  */
> +        return s->scu_status >> 8;
> +    case 0x0a: /* CPU status.  */
> +        return s->scu_status >> 16;
> +    case 0x0b: /* CPU status.  */
> +        return s->scu_status >> 24;
>     case 0x0c: /* Invalidate All Registers In Secure State */
>         return 0;
>     case 0x40: /* Filtering Start Address Register */
> @@ -73,6 +80,29 @@ static void a9_scu_write(void *opaque, target_phys_addr_t 
> offset,
>         break;
>     case 0x4: /* Configuration: RO */
>         break;
> +    case 0x08: /* Power Control  */
> +        s->scu_status = value;
> +        break;

This does the wrong thing for a byte or halfword
write to 0x8. (Byte writes in particular are going to be the
common case for this register for obvious reasons.)

> +    case 0x09: /* Power Control  */
> +        s->scu_status &= ~(0xff << 8);
> +        s->scu_status |= (value & 0xff) << 8;
> +        break;
> +    case 0x0A: /* Power Control  */
> +        if (size == 1) {
> +            s->scu_status &= ~(0xff << 16);
> +            s->scu_status |= (value & 0xff) << 16;
> +        } else if (size == 2) {
> +            s->scu_status &= ~(0x << 16);
> +            s->scu_status |= (value & 0x) << 16;
> +        } else {
> +            /* illegal number of bytes */
> +            break;
> +        }
> +        break;
> +    case 0x0B: /* Power Control  */
> +        s->scu_status &= ~(0xff << 24);
> +        s->scu_status |= (value & 0xff) << 24;
> +        break;

How about:
 switch (size) {
 case 1:
mask = 0xff;
break;
 case 2:
mask = 0x;
break;
 case 4:
mask = 0x;
break;
 }

Then the register write code simplifies to:
   case 0x08: case 0x09: case 0xa: case 0xb:
  shift = (offset - 0x8) * 8;
  s->scu_status &= ~(mask << shift);
  s->scu_status |= ((value & mask) << shift);
  break;

(written on the hoof and untested!)

>     case 0x0c: /* Invalidate All Registers In Secure State */
>         /* no-op as we do not implement caches */
>         break;
> @@ -80,7 +110,6 @@ static void a9_scu_write(void *opaque, target_phys_addr_t 
> offset,
>     case 0x44: /* Filtering End Address Register */
>         /* RAZ/WI, like an implementation with only one AXI master */
>         break;
> -    case 0x8: /* CPU Power Status */
>     case 0x50: /* SCU Access Control Register */
>     case 0x54: /* SCU Non-secure Access Control Register */
>         /* unimplemented, fall through */
> @@ -173,6 +202,7 @@ static const VMStateDescription vmstate_a9mp_priv = {
>     .minimum_version_id = 1,
>     .fields = (VMStateField[]) {
>         VMSTATE_UINT32(scu_control, a9mp_priv_state),
> +        VMSTATE_UINT32(scu_status, a9mp_priv_state),
>         VMSTATE_UINT32_ARRAY(old_timer_status, a9mp_priv_state, 8),
>         VMSTATE_END_OF_LIST()
>     }

This breaks migration compatibility. You want:
 * set .version_id to 2
 * leave .minimum_version_id as 1
 * the new field should go at the end of the list and be:
 VMSTATE_UINT32_V(scu_status, a9mp_priv_state, 2),
(which says it only exists in version 2).

-- PMM



Re: [Qemu-devel] [PATCH v2 2/9] arm: Set frequencies for arm_timer

2011-12-23 Thread Peter Maydell
On 22 December 2011 18:20, Mark Langsdorf  wrote:
> Use qdev properties to allow board modelers to set the frequencies
> for the sp804 timer. Each of the sp804's timers can have an
> individual frequency. The timers default to 1MHz.
>
> +    /* The timers are configurable between 32kHz and 1MHz
> +     * defaulting to 1MHz but overrideable as a property
> +     * They can be configured individually as a property
> +     * but default is shared frequency */

You've forgotten to update this comment when you dropped the
shared-frequency property. Patch looks good otherwise.

-- PMM



Re: [Qemu-devel] [PATCH v2 3/9] arm: add dummy v7 cp15 config_base_register

2011-12-23 Thread Peter Maydell
On 22 December 2011 18:20, Mark Langsdorf  wrote:
> +        if (ARM_CPUID(env) == ARM_CPUID_CORTEXA9) {
> +            switch (crm) {
> +            case 0:
> +                /* The config_base_address should hold the value of
> +                 * the peripheral base. ARM should get this from a CPU
> +                 * object property, but that support isn't available in
> +                 * December 2011. Default to 0 for now and board models
> +                 * that care can set it by a private hook */
> +                if (op1 == 4) {
> +                    return env->cp15.c15_config_base_address;
> +                }

Still underdecoded -- op2 must be 0 as well.
Otherwise OK.

-- PMM


Re: [Qemu-devel] [PATCH v2 4/9] arm: add dummy gic security registers

2011-12-23 Thread Peter Maydell
On 22 December 2011 18:20, Mark Langsdorf  wrote:
> From: Rob Herring 
>
> Implement handling for the RAZ/WI gic security registers.
>
> Signed-off-by: Rob Herring 
> Signed-off-by: Mark Langsdorf 

Reviewed-by: Peter Maydell 

-- PMM



Re: [Qemu-devel] [PATCH 5/9] ahci: convert ahci_reset to use AHCIState

2011-12-23 Thread Peter Maydell
On 22 December 2011 18:20, Mark Langsdorf  wrote:
> From: Rob Herring 
>
> Use AHCIState instead of AHCIPCIState so the function can be used for
> non-PCI based AHCI controllers.

Just a note that I'm assuming Kevin will review the IDE
related patches.

-- PMM



Re: [Qemu-devel] [PATCH 6/9] ahci: add support for non-PCI based controllers

2011-12-23 Thread Peter Maydell
On 22 December 2011 18:20, Mark Langsdorf  wrote:
> From: Rob Herring 
>
> Add support for ahci on sysbus.

Again, IDE isn't my domain, but some minor points:
> +typedef struct PlatAHCIState {
> +        SysBusDevice busdev;
> +        AHCIState ahci;
> +} PlatAHCIState;

Indentation is wrong here.

> +static SysBusDeviceInfo plat_ahci_info[] = {
> +    {
> +        .qdev.name    = "plat-ahci",
> +        .qdev.size    = sizeof(PlatAHCIState),
> +        .init         = plat_ahci_init,
> +    },{
> +        /* end of list */
> +    }
> +};
> +
> +static void plat_ahci_register(void)
> +{
> +    sysbus_register_withprop(plat_ahci_info);
> +}

sysbus_register_withprop() takes a single SysBusDeviceInfo,
not a list.

-- PMM



Re: [Qemu-devel] [PATCH v2 7/9] add L2x0/PL310 cache controller device

2011-12-23 Thread Peter Maydell
On 22 December 2011 18:20, Mark Langsdorf  wrote:
> From: Rob Herring 
>
> This is just a dummy device for ARM L2 cache controllers, based on the
> pl310. The cache type parameter can be defined by a property value
> and has a meaningful default.
>
> Signed-off-by: Rob Herring 
> Signed-off-by: Mark Langsdorf 

scripts/checkpatch.pl complains about a couple of overlong lines;
please fix.

> ---
> Changes from v1
>        Corrected formatting
>        Clarified the copyrights
>        Clarified GPL revision
>        Clarified model version
>        Removed hw_error() calls
>        Added a reset function
>        Restructed everything as switch/case statements
>        Added a type cache property
>
>  Makefile.target |    1 +
>  hw/arm_l2x0.c   |  173 
> +++
>  2 files changed, 174 insertions(+), 0 deletions(-)
>  create mode 100644 hw/arm_l2x0.c
>
> diff --git a/Makefile.target b/Makefile.target
> index 3261383..db5e44c 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -336,6 +336,7 @@ obj-arm-y = integratorcp.o versatilepb.o arm_pic.o 
> arm_timer.o
>  obj-arm-y += arm_boot.o pl011.o pl031.o pl050.o pl080.o pl110.o pl181.o 
> pl190.o
>  obj-arm-y += versatile_pci.o
>  obj-arm-y += realview_gic.o realview.o arm_sysctl.o arm11mpcore.o a9mpcore.o
> +obj-arm-y += arm_l2x0.o
>  obj-arm-y += arm_mptimer.o
>  obj-arm-y += armv7m.o armv7m_nvic.o stellaris.o pl022.o stellaris_enet.o
>  obj-arm-y += pl061.o
> diff --git a/hw/arm_l2x0.c b/hw/arm_l2x0.c
> new file mode 100644
> index 000..84f6c5a
> --- /dev/null
> +++ b/hw/arm_l2x0.c
> @@ -0,0 +1,173 @@
> +/*
> + * ARM dummy L210, L220, PL310 cache controller.
> + *
> + * Copyright (c) 2010-2012 Calxeda
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.

"Or any later version". We're trying to avoid new v2-only code, please.

> + *
> + * This program is distributed in the hope 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.
> + *
> + * You should have received a copy of the GNU General Public License along 
> with
> + * this program.  If not, see .
> + *
> + */
> +
> +#include "sysbus.h"
> +
> +/* L2C-310 r3p1 */
> +#define CACHE_ID 0x41c6

Why not r3p2 ?

> +#define DEFAULT_CACHE_TYPE 0x19080800
> +
> +typedef struct l2x0_state {
> +    SysBusDevice busdev;
> +    MemoryRegion iomem;
> +    uint32_t cache_type;
> +    uint32_t ctrl;
> +    uint32_t aux_ctrl;
> +    uint32_t data_ctrl;
> +    uint32_t tag_ctrl;
> +    uint32_t filter_start;
> +    uint32_t filter_end;
> +} l2x0_state;
> +
> +static const VMStateDescription vmstate_l2x0 = {
> +    .name = "l2x0",
> +    .version_id = 1,
> +    .minimum_version_id = 1,
> +    .fields = (VMStateField[]) {
> +        VMSTATE_UINT32(ctrl, l2x0_state),
> +        VMSTATE_UINT32(aux_ctrl, l2x0_state),
> +        VMSTATE_UINT32(data_ctrl, l2x0_state),
> +        VMSTATE_UINT32(tag_ctrl, l2x0_state),
> +        VMSTATE_UINT32(filter_start, l2x0_state),
> +        VMSTATE_UINT32(filter_end, l2x0_state),
> +        VMSTATE_END_OF_LIST()
> +    }
> +};
> +
> +
> +static uint64_t l2x0_priv_read(void *opaque, target_phys_addr_t offset, 
> unsigned size)
> +{
> +    l2x0_state *s = (l2x0_state *)opaque;
> +    offset &= 0xfff;
> +    if (offset >= 0x730 && offset < 0x800) {
> +        return 0; /* cache ops complete */
> +    }
> +    switch (offset) {
> +    case 0:
> +        return CACHE_ID;
> +    case 0x4:
> +        return s->cache_type;
> +    case 0x100:
> +        return s->ctrl;
> +    case 0x104:
> +        return s->aux_ctrl;
> +    case 0x108:
> +        return s->tag_ctrl;
> +    case 0x10C:
> +        return s->data_ctrl;
> +    case 0xC00:
> +        return s->filter_start;
> +    case 0xC04:
> +        return s->filter_end;
> +    case 0xF40:
> +        return 0;
> +    case 0xF60:
> +        return 0;
> +    case 0xF80:
> +        return 0;
> +    default:
> +        fprintf(stderr, "l2x0_priv_read: Bad offset %x\n", (int)offset);
> +        break;
> +    }
> +    return 0;
> +}
> +
> +static void l2x0_priv_write(void *opaque, target_phys_addr_t offset, 
> uint64_t value, unsigned size)
> +{
> +    l2x0_state *s = (l2x0_state *)opaque;
> +    offset &= 0xfff;
> +    if (offset >= 0x730 && offset < 0x800) {
> +        /* ignore */
> +        return;
> +    }
> +    switch (offset) {
> +    case 0x100:
> +        s->ctrl = value & 1;
> +        break;
> +    case 0x104:
> +        s->aux_ctrl = value;
> +        break;
> +    case 0x108:
> +        s->tag_ctrl = value;
> +        break;
> +    case 0x10C:
> +        s->data_ctrl = value;
> +        break;
> +    case 0xC00:
> +        s->filter_st

Re: [Qemu-devel] [PATCH 9/9] arm: increase a9mp interrupts to 160

2011-12-23 Thread Rob Herring
Mark,

On 12/22/2011 12:20 PM, Mark Langsdorf wrote:
> From: Rob Herring 
> 
> Signed-off-by: Rob Herring 
> Signed-off-by: Mark Langsdorf 
> ---
>  hw/a9mpcore.c |2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/hw/a9mpcore.c b/hw/a9mpcore.c
> index 875ae98..93b0498 100644
> --- a/hw/a9mpcore.c
> +++ b/hw/a9mpcore.c
> @@ -13,7 +13,7 @@
>  /* Configuration for arm_gic.c:
>   * number of external IRQ lines, max number of CPUs, how to ID current CPU
>   */
> -#define GIC_NIRQ 96
> +#define GIC_NIRQ 160
>  #define NCPU 4

This needs to be run-time. The value gets put in a register and read by
the OS. It breaks platforms expecting 96 irqs.

Rob



Re: [Qemu-devel] [PATCH 9/9] arm: increase a9mp interrupts to 160

2011-12-23 Thread Peter Maydell
On 24 December 2011 00:54, Rob Herring  wrote:
> Mark,
>
> On 12/22/2011 12:20 PM, Mark Langsdorf wrote:
>> From: Rob Herring 
>>
>> Signed-off-by: Rob Herring 
>> Signed-off-by: Mark Langsdorf 
>> ---
>>  hw/a9mpcore.c |    2 +-
>>  1 files changed, 1 insertions(+), 1 deletions(-)
>>
>> diff --git a/hw/a9mpcore.c b/hw/a9mpcore.c
>> index 875ae98..93b0498 100644
>> --- a/hw/a9mpcore.c
>> +++ b/hw/a9mpcore.c
>> @@ -13,7 +13,7 @@
>>  /* Configuration for arm_gic.c:
>>   * number of external IRQ lines, max number of CPUs, how to ID current CPU
>>   */
>> -#define GIC_NIRQ 96
>> +#define GIC_NIRQ 160
>>  #define NCPU 4
>
> This needs to be run-time. The value gets put in a register and read by
> the OS. It breaks platforms expecting 96 irqs.

Also the hardware maximum for the A9 is 256, so bumping the compile
time maximum to only 160 wouldn't make sense. (The GIC architectural
limit is 1020 interrupts.)

FYI: In the long term the place I would like to get to is to have
the GIC be a properly separated out qdev device, rather than a bit
of code which is #included by various different source files which
do this kind of compile-time configuration for it. Having the
private peripheral qdev devices be subclasses of the GIC is also
a bit of a workaround for limitations of our current device object
model which I hope QOM will let us rearrange.

-- PMM



Re: [Qemu-devel] Use Clang to compile Qemu?

2011-12-23 Thread 陳韋任
On Fri, Dec 23, 2011 at 02:07:53PM +0100, David Turner wrote:
> Some parts of QEMU (the JIT) require the use of a global register variable
> to point to the "env" CPU state variable.
> 
> This feature is not supported by Clang (which is not very surprising given
> that it uses LLVM as its backend, and LLVM explicitely doesn't support this)
> 
> Until the JIT is modified to not require this anymore, it is very unlikely
> that Clang will be able to build QEMU.
> 
> There were previous discussions about such a change on this mailing list,
> but I believe nobody started working on that change because many feared it
> was a lot of work that would have a negative impact on performance (though
> I think it was all conjecture, i.e. no one really tried it and got any real
> data).

  You're right. Here is the discussion,
  http://lists.gnu.org/archive/html/qemu-devel/2011-05/msg01116.html

  Since TCI (Tiny Code Interpreter) doesn't need AREG0, I configure QEMU to use
TCI and try it out. Here's my flow.

---
# apply patches under /usr/ports/emulators/qemu-devel/files/ first
$ ../configure --prefix=$INSTALL --target-list=i386-bsd-user \
  --enable-tcg-interpreter \
  --cc=clang
$ gmake install
---

  So far so good (perhaps freebsd guys should upstream those patches?). But I am
stuck at the error below,

---
$ qemu-i386 -bsd freebsd hello
Unable to load interpreter
---

  Any thoughts? Thanks! :)

Regards,
chenwj

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



[Qemu-devel] metal mesh

2011-12-23 Thread andy
Dear Sir or Madam   



It is glad to write to you with keen hope to open a business relationship with 
you. I obtained your company name and email address from the Internet.


Boli hardware industrial limited is a factory specialized in wire and wire mesh 
production. Our products mainly include expanded wire metal mesh,window 
screen,welded wire mesh, square wire mesh, stainless steel wire mesh, hexagonal 
wire mesh fence, stainless steel wire, black annealed wire, galvanized wire, 
PVC-coated wire, barbed wire, hot galvanized patented wire, hot dipped 
galvanized chain etc!

For more information, we would like to let you know our company web site as 
below:http://www.boliwiremesh.com.



Hope to hear good news from you.
Sincerely Yours,
Andy


Sales manager

Boli hardware industrial limited

Tel: 86-0311-87789982

Fax: 86-0311-87769982





Re: [Qemu-devel] OEM Windows in Qemu

2011-12-23 Thread inbox

Jernej Simon?i?  wrote:
>That's the exact reason - the strings have to be present in the
>correct memory region. You can use SLICToolkit (in SLP1.0 tab) to
>verify if the strings are present at the right address.

Alright then, do you know how to modify those values in qemu?  


Brian