[Qemu-devel] [PATCH qemu v2 REPOST] pci: Initialize pci_dev->name before use

2017-10-14 Thread Alexey Kardashevskiy
This moves pci_dev->name initialization earlier so
pci_dev->bus_master_as could get a name instead of an empty string.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Alexey Kardashevskiy 
---

Changes:
v2:
* fixed mistype in the commit log
* added "rb"
---
 hw/pci/pci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 1e6fb88eba..05c5f75ef0 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -1020,6 +1020,7 @@ static PCIDevice *do_pci_register_device(PCIDevice 
*pci_dev, PCIBus *bus,
 
 pci_dev->devfn = devfn;
 pci_dev->requester_id_cache = pci_req_id_cache_get(pci_dev);
+pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
 
 memory_region_init(_dev->bus_master_container_region, OBJECT(pci_dev),
"bus master container", UINT64_MAX);
@@ -1029,7 +1030,6 @@ static PCIDevice *do_pci_register_device(PCIDevice 
*pci_dev, PCIBus *bus,
 if (qdev_hotplug) {
 pci_init_bus_master(pci_dev);
 }
-pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
 pci_dev->irq_state = 0;
 pci_config_alloc(pci_dev);
 
-- 
2.11.0




Re: [Qemu-devel] host physical address width issues/questions for x86_64

2017-10-14 Thread Peter Xu
On Fri, Oct 13, 2017 at 11:14:03AM -0600, Alex Williamson wrote:
> On Fri, 13 Oct 2017 18:01:44 +0100
> "Dr. David Alan Gilbert"  wrote:
> 
> > * Prasad Singamsetty (prasad.singamse...@oracle.com) wrote:
> > > Hi,
> > > 
> > > I am new to the alias. I have some questions on this subject
> > > and seek some clarifications from the experts in the team.
> > > I ran into a couple of issues when I tried with large configuration
> > > ( >= 1TB memory, > 255 CPUs) for x86_64 guest machine.
> > > 
> > > 1. QEMU uses the default value of 40 (TCG_PHYS_ADDR_BITS) for address
> > >width if user has not specified phys-bits or host-phys-bits=true
> > >property. The default value is obviously not sufficient and
> > >causing guest kernel to crash if configured with >= 1TB
> > >memory. Depending on the linux kernel version in the guest the
> > >panic was in different code paths. The workaround is for the
> > >user to specify the phys-bits property or set the property
> > >host-phys-bits=true.
> > > 
> > >QUESTIONS:
> ...
> > > 2. host_address_width in DMAR table structure
> > > 
> > >In this case, the default value is set to 39
> > >(VTD_HOST_ADDRESS_WIDTH - 1). With interrupt remapping
> > >enabled for the intel iommu and the guest is configured
> > >with > 255 cpus and >= 1TB memory, the guest kernel hangs
> > >during boot up. This need to be fixed.
> > > 
> > >QUESTION:
> > >The question here again is can we fix this to use the
> > >real address width from the host as the default?  
> > 
> > I don't know DMAR stuff; chatting to Alex (cc'd) it does sound
> > like that's an ommission that should be fixed.
> 
> [CC +Peter]
> 
> On physical hardware VT-d supports either 39 or 48 bit address widths
> and generally you'd expect a sufficiently capable IOMMU to be matched
> with the CPU.  Seems QEMU has only implemented a lower bit width and
> it should probably be forcing phys bits of the VM to 39 to match until
> the extended width can be implemented.  Thanks,
> 
> Alex

There were patches that tried to enable 48 bits GAW but it was
not accepted somehow:

  https://lists.gnu.org/archive/html/qemu-devel/2016-12/msg01886.html

Would this help in any way?

Thanks,

-- 
Peter Xu



Re: [Qemu-devel] [PATCH qemu v2] pci: Initialize pci_dev->name before use

2017-10-14 Thread Michael S. Tsirkin
On Sun, Oct 15, 2017 at 02:24:17PM +1100, Alexey Kardashevskiy wrote:
> On 03/10/17 13:10, Alexey Kardashevskiy wrote:
> > On 15/09/17 16:35, Alexey Kardashevskiy wrote:
> >> This moves pci_dev->name initialization earlier so
> >> pci_dev->bus_master_as could get a name instead of an empty string.
> >>
> >> Signed-off-by: Alexey Kardashevskiy 
> >> Reviewed-by: Philippe Mathieu-Daudé 
> > 
> > Ping?
> 
> Ping?

Pls repost while you CC me. Thanks!

> 
> > 
> > 
> >> ---
> >> Changes:
> >> v2:
> >> * fixed mistype in the commit log
> >> * added "rb"
> >> ---
> >>  hw/pci/pci.c | 2 +-
> >>  1 file changed, 1 insertion(+), 1 deletion(-)
> >>
> >> diff --git a/hw/pci/pci.c b/hw/pci/pci.c
> >> index 21e203b056..353195d154 100644
> >> --- a/hw/pci/pci.c
> >> +++ b/hw/pci/pci.c
> >> @@ -1020,6 +1020,7 @@ static PCIDevice *do_pci_register_device(PCIDevice 
> >> *pci_dev, PCIBus *bus,
> >>  
> >>  pci_dev->devfn = devfn;
> >>  pci_dev->requester_id_cache = pci_req_id_cache_get(pci_dev);
> >> +pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
> >>  
> >>  memory_region_init(_dev->bus_master_container_region, 
> >> OBJECT(pci_dev),
> >> "bus master container", UINT64_MAX);
> >> @@ -1029,7 +1030,6 @@ static PCIDevice *do_pci_register_device(PCIDevice 
> >> *pci_dev, PCIBus *bus,
> >>  if (qdev_hotplug) {
> >>  pci_init_bus_master(pci_dev);
> >>  }
> >> -pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
> >>  pci_dev->irq_state = 0;
> >>  pci_config_alloc(pci_dev);
> >>  
> >>
> > 
> > 
> 
> 
> -- 
> Alexey



[Qemu-devel] [PULL 25/26] pc: remove useless hot_add_cpu initialisation

2017-10-14 Thread Michael S. Tsirkin
From: Laurent Vivier 

Since 4458fb3a79 (pc: Eliminate pc_default_machine_options()),
hot_add_cpu is set in pc_machine_class_init(), so we don't
need to set it in pc_q35_machine_options(), pc_i440fx_machine_options()
and xenfv_machine_options(), except to clear it in
pc_i440fx_1_4_machine_opt().

Signed-off-by: Laurent Vivier 
Reviewed-by: Igor Mammedov 
Reviewed-by: Eduardo Habkost 
Acked-by: Anthony PERARD 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/i386/pc_piix.c | 2 --
 hw/i386/pc_q35.c  | 1 -
 2 files changed, 3 deletions(-)

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 9dbcbcd..f79d5cb 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -426,7 +426,6 @@ static void pc_i440fx_machine_options(MachineClass *m)
 {
 m->family = "pc_piix";
 m->desc = "Standard PC (i440FX + PIIX, 1996)";
-m->hot_add_cpu = pc_hot_add_cpu;
 m->default_machine_opts = "firmware=bios-256k.bin";
 m->default_display = "std";
 }
@@ -1125,7 +1124,6 @@ static void xenfv_machine_options(MachineClass *m)
 m->desc = "Xen Fully-virtualized PC";
 m->max_cpus = HVM_MAX_VCPUS;
 m->default_machine_opts = "accel=xen";
-m->hot_add_cpu = pc_hot_add_cpu;
 }
 
 DEFINE_PC_MACHINE(xenfv, "xenfv", pc_xen_hvm_init,
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 6c4ec4b..da3ea60 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -295,7 +295,6 @@ static void pc_q35_machine_options(MachineClass *m)
 {
 m->family = "pc_q35";
 m->desc = "Standard PC (Q35 + ICH9, 2009)";
-m->hot_add_cpu = pc_hot_add_cpu;
 m->units_per_default_bus = 1;
 m->default_machine_opts = "firmware=bios-256k.bin";
 m->default_display = "std";
-- 
MST




[Qemu-devel] [PULL 24/26] isapc: Remove unnecessary migration compatibility code

2017-10-14 Thread Michael S. Tsirkin
From: Eduardo Habkost 

We don't touch isapc when we change guest ABI and add new entries
to PC_COMPAT_* or new PCMachineClass compat flags.  This means
isapc never guaranteed guest ABI and cross-QEMU-version live
migration compatibility.  There's no point in keeping code for
kvm-pv-eoi and APIC ID compatibility in pc_init_isa().

Signed-off-by: Eduardo Habkost 
Reviewed-by: Igor Mammedov 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/i386/pc_piix.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 1a56465..9dbcbcd 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -378,8 +378,6 @@ static void pc_compat_0_13(MachineState *machine)
 
 static void pc_init_isa(MachineState *machine)
 {
-x86_cpu_change_kvm_default("kvm-pv-eoi", NULL);
-enable_compat_apic_id_mode();
 pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, TYPE_I440FX_PCI_DEVICE);
 }
 
-- 
MST




Re: [Qemu-devel] [PATCH qemu v2] pci: Initialize pci_dev->name before use

2017-10-14 Thread Alexey Kardashevskiy
On 15/10/17 14:31, Michael S. Tsirkin wrote:
> On Sun, Oct 15, 2017 at 02:24:17PM +1100, Alexey Kardashevskiy wrote:
>> On 03/10/17 13:10, Alexey Kardashevskiy wrote:
>>> On 15/09/17 16:35, Alexey Kardashevskiy wrote:
 This moves pci_dev->name initialization earlier so
 pci_dev->bus_master_as could get a name instead of an empty string.

 Signed-off-by: Alexey Kardashevskiy 
 Reviewed-by: Philippe Mathieu-Daudé 
>>>
>>> Ping?
>>
>> Ping?
> 
> I can't find v2 in either qemu or my personal mailbox.


Few weeks ago qemu-devel@ list admins were playing with list-id, may be
that's why it missed your inbox.

It hit patchwork though: https://patchwork.ozlabs.org/patch/814085/


> 
>>
>>>
>>>
 ---
 Changes:
 v2:
 * fixed mistype in the commit log
 * added "rb"
 ---
  hw/pci/pci.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

 diff --git a/hw/pci/pci.c b/hw/pci/pci.c
 index 21e203b056..353195d154 100644
 --- a/hw/pci/pci.c
 +++ b/hw/pci/pci.c
 @@ -1020,6 +1020,7 @@ static PCIDevice *do_pci_register_device(PCIDevice 
 *pci_dev, PCIBus *bus,
  
  pci_dev->devfn = devfn;
  pci_dev->requester_id_cache = pci_req_id_cache_get(pci_dev);
 +pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
  
  memory_region_init(_dev->bus_master_container_region, 
 OBJECT(pci_dev),
 "bus master container", UINT64_MAX);
 @@ -1029,7 +1030,6 @@ static PCIDevice *do_pci_register_device(PCIDevice 
 *pci_dev, PCIBus *bus,
  if (qdev_hotplug) {
  pci_init_bus_master(pci_dev);
  }
 -pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
  pci_dev->irq_state = 0;
  pci_config_alloc(pci_dev);
  

>>>
>>>
>>
>>
>> -- 
>> Alexey


-- 
Alexey



Re: [Qemu-devel] [PATCH qemu v2] pci: Initialize pci_dev->name before use

2017-10-14 Thread Michael S. Tsirkin
On Sun, Oct 15, 2017 at 02:24:17PM +1100, Alexey Kardashevskiy wrote:
> On 03/10/17 13:10, Alexey Kardashevskiy wrote:
> > On 15/09/17 16:35, Alexey Kardashevskiy wrote:
> >> This moves pci_dev->name initialization earlier so
> >> pci_dev->bus_master_as could get a name instead of an empty string.
> >>
> >> Signed-off-by: Alexey Kardashevskiy 
> >> Reviewed-by: Philippe Mathieu-Daudé 
> > 
> > Ping?
> 
> Ping?

I can't find v2 in either qemu or my personal mailbox.

> 
> > 
> > 
> >> ---
> >> Changes:
> >> v2:
> >> * fixed mistype in the commit log
> >> * added "rb"
> >> ---
> >>  hw/pci/pci.c | 2 +-
> >>  1 file changed, 1 insertion(+), 1 deletion(-)
> >>
> >> diff --git a/hw/pci/pci.c b/hw/pci/pci.c
> >> index 21e203b056..353195d154 100644
> >> --- a/hw/pci/pci.c
> >> +++ b/hw/pci/pci.c
> >> @@ -1020,6 +1020,7 @@ static PCIDevice *do_pci_register_device(PCIDevice 
> >> *pci_dev, PCIBus *bus,
> >>  
> >>  pci_dev->devfn = devfn;
> >>  pci_dev->requester_id_cache = pci_req_id_cache_get(pci_dev);
> >> +pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
> >>  
> >>  memory_region_init(_dev->bus_master_container_region, 
> >> OBJECT(pci_dev),
> >> "bus master container", UINT64_MAX);
> >> @@ -1029,7 +1030,6 @@ static PCIDevice *do_pci_register_device(PCIDevice 
> >> *pci_dev, PCIBus *bus,
> >>  if (qdev_hotplug) {
> >>  pci_init_bus_master(pci_dev);
> >>  }
> >> -pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
> >>  pci_dev->irq_state = 0;
> >>  pci_config_alloc(pci_dev);
> >>  
> >>
> > 
> > 
> 
> 
> -- 
> Alexey



[Qemu-devel] [PULL 19/26] xen/pt: Mark TYPE_XEN_PT_DEVICE as hybrid

2017-10-14 Thread Michael S. Tsirkin
From: Eduardo Habkost 

xen-pt doesn't set the is_express field, but is supposed to be
able to handle PCI Express devices too.  Mark it as hybrid.

Suggested-by: Jan Beulich 
Signed-off-by: Eduardo Habkost 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/xen/xen_pt.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c
index 01df341..9bba717 100644
--- a/hw/xen/xen_pt.c
+++ b/hw/xen/xen_pt.c
@@ -966,6 +966,7 @@ static const TypeInfo xen_pci_passthrough_info = {
 .class_init = xen_pci_passthrough_class_init,
 .interfaces = (InterfaceInfo[]) {
 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
+{ INTERFACE_PCIE_DEVICE },
 { },
 },
 };
-- 
MST




[Qemu-devel] [PULL 18/26] pci: Add INTERFACE_CONVENTIONAL_PCI_DEVICE to Conventional PCI devices

2017-10-14 Thread Michael S. Tsirkin
From: Eduardo Habkost 

Add INTERFACE_CONVENTIONAL_PCI_DEVICE to all direct subtypes of
TYPE_PCI_DEVICE, except:

1) The ones that already have INTERFACE_PCIE_DEVICE set:

* base-xhci
* e1000e
* nvme
* pvscsi
* vfio-pci
* virtio-pci
* vmxnet3

2) base-pci-bridge

Not all PCI bridges are Conventional PCI devices, so
INTERFACE_CONVENTIONAL_PCI_DEVICE is added only to the subtypes
that are actually Conventional PCI:

* dec-21154-p2p-bridge
* i82801b11-bridge
* pbm-bridge
* pci-bridge

The direct subtypes of base-pci-bridge not touched by this patch
are:

* xilinx-pcie-root: Already marked as PCIe-only.
* pcie-pci-bridge: Already marked as PCIe-only.
* pcie-port: all non-abstract subtypes of pcie-port are already
  marked as PCIe-only devices.

3) megasas-base

Not all megasas devices are Conventional PCI devices, so the
interface names are added to the subclasses registered by
megasas_register_types(), according to information in the
megasas_devices[] array.

"megasas-gen2" already implements INTERFACE_PCIE_DEVICE, so add
INTERFACE_CONVENTIONAL_PCI_DEVICE only to "megasas".

Acked-by: Alberto Garcia 
Acked-by: John Snow 
Acked-by: Anthony PERARD 
Signed-off-by: Eduardo Habkost 
Reviewed-by: David Gibson 
Acked-by: David Gibson 
Reviewed-by: Marcel Apfelbaum 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/acpi/piix4.c |  1 +
 hw/audio/ac97.c |  4 
 hw/audio/es1370.c   |  4 
 hw/audio/intel-hda.c|  4 
 hw/char/serial-pci.c| 12 
 hw/display/cirrus_vga.c |  4 
 hw/display/qxl.c|  4 
 hw/display/sm501.c  |  4 
 hw/display/vga-pci.c|  4 
 hw/display/vmware_vga.c |  4 
 hw/i2c/smbus_ich9.c |  4 
 hw/i386/amd_iommu.c |  4 
 hw/i386/kvm/pci-assign.c|  4 
 hw/i386/pc_piix.c   |  4 
 hw/i386/xen/xen_platform.c  |  4 
 hw/i386/xen/xen_pvdevice.c  |  4 
 hw/ide/ich.c|  4 
 hw/ide/pci.c|  4 
 hw/ipack/tpci200.c  |  4 
 hw/isa/i82378.c |  4 
 hw/isa/lpc_ich9.c   |  1 +
 hw/isa/piix4.c  |  4 
 hw/isa/vt82c686.c   | 16 
 hw/mips/gt64xxx_pci.c   |  4 
 hw/misc/edu.c   |  5 +
 hw/misc/ivshmem.c   |  4 
 hw/misc/macio/macio.c   |  4 
 hw/misc/pci-testdev.c   |  4 
 hw/net/e1000.c  |  4 
 hw/net/eepro100.c   |  4 
 hw/net/ne2000.c |  4 
 hw/net/pcnet-pci.c  |  4 
 hw/net/rocker/rocker.c  |  4 
 hw/net/rtl8139.c|  4 
 hw/net/sungem.c |  4 
 hw/net/sunhme.c |  4 
 hw/pci-bridge/dec.c |  8 
 hw/pci-bridge/i82801b11.c   |  4 
 hw/pci-bridge/pci_bridge_dev.c  |  1 +
 hw/pci-bridge/pci_expander_bridge.c |  8 
 hw/pci-host/apb.c   |  8 
 hw/pci-host/bonito.c|  4 
 hw/pci-host/gpex.c  |  4 
 hw/pci-host/grackle.c   |  4 
 hw/pci-host/piix.c  |  8 
 hw/pci-host/ppce500.c   |  4 
 hw/pci-host/prep.c  |  4 
 hw/pci-host/q35.c   |  4 
 hw/pci-host/uninorth.c  | 16 
 hw/pci-host/versatile.c |  4 
 hw/ppc/ppc4xx_pci.c |  4 
 hw/scsi/esp-pci.c   |  4 
 hw/scsi/lsi53c895a.c|  4 
 hw/scsi/megasas.c   |  4 
 hw/scsi/mptsas.c|  4 
 hw/sd/sdhci.c   |  4 
 hw/sh4/sh_pci.c |  4 
 hw/sparc64/sun4u.c  |  4 
 hw/usb/hcd-ehci-pci.c   |  4 
 hw/usb/hcd-ohci.c   |  4 
 hw/usb/hcd-uhci.c   |  4 
 hw/vfio/pci-quirks.c|  4 
 hw/watchdog/wdt_i6300esb.c  |  4 
 hw/xen/xen_pt.c |  4 
 64 files changed, 296 insertions(+)

diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index f4fd590..a0fb1ce 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -718,6 +718,7 @@ static const TypeInfo piix4_pm_info = {
 .interfaces = (InterfaceInfo[]) {
 { TYPE_HOTPLUG_HANDLER },
 { TYPE_ACPI_DEVICE_IF },
+{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
 { 

[Qemu-devel] [PULL 22/26] virtio: fix descriptor counting in virtqueue_pop

2017-10-14 Thread Michael S. Tsirkin
From: Wolfgang Bumiller 

While changing the s/g list allocation, commit 3b3b0628
also changed the descriptor counting to count iovec entries
as split by cpu_physical_memory_map(). Previously only the
actual descriptor entries were counted and the split into
the iovec happened afterwards in virtqueue_map().
Count the entries again instead to avoid erroneous
"Looped descriptor" errors.

Reported-by: Hans Middelhoek 
Link: https://forum.proxmox.com/threads/vm-crash-with-memory-hotplug.35904/
Fixes: 3b3b0628217e ("virtio: slim down allocation of VirtQueueElements")
Signed-off-by: Wolfgang Bumiller 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/virtio/virtio.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 311929e..5884ce3 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -834,7 +834,7 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz)
 int64_t len;
 VirtIODevice *vdev = vq->vdev;
 VirtQueueElement *elem = NULL;
-unsigned out_num, in_num;
+unsigned out_num, in_num, elem_entries;
 hwaddr addr[VIRTQUEUE_MAX_SIZE];
 struct iovec iov[VIRTQUEUE_MAX_SIZE];
 VRingDesc desc;
@@ -852,7 +852,7 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz)
 smp_rmb();
 
 /* When we start there are none of either input nor output. */
-out_num = in_num = 0;
+out_num = in_num = elem_entries = 0;
 
 max = vq->vring.num;
 
@@ -922,7 +922,7 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz)
 }
 
 /* If we've got too many, that implies a descriptor loop. */
-if ((in_num + out_num) > max) {
+if (++elem_entries > max) {
 virtio_error(vdev, "Looped descriptor");
 goto err_undo_map;
 }
-- 
MST




[Qemu-devel] [PULL 23/26] virtio-pci: Replace modern_as with direct access to modern_bar

2017-10-14 Thread Michael S. Tsirkin
From: Alexey Kardashevskiy 

The modern bar is accessed now via yet another address space created just
for that purpose and it does not really need FlatView and dispatch tree
as it has a single memory region so it is just a waste of memory. Things
get even worse when there are dozens or hundreds of virtio-pci devices -
since these address spaces are global, changing any of them triggers
rebuilding all address spaces.

This replaces indirect accesses to the modern BAR with a simple lookup
and direct calls to memory_region_dispatch_read/write.

This is expected to save lots of memory at boot time after applying:
[Qemu-devel] [PULL 00/32] Misc changes for 2017-09-22

Signed-off-by: Alexey Kardashevskiy 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/virtio/virtio-pci.h | 17 +++-
 hw/virtio/virtio-pci.c | 75 +-
 2 files changed, 54 insertions(+), 38 deletions(-)

diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h
index 69f5959..12d3a90 100644
--- a/hw/virtio/virtio-pci.h
+++ b/hw/virtio/virtio-pci.h
@@ -155,15 +155,18 @@ typedef struct VirtIOPCIQueue {
 struct VirtIOPCIProxy {
 PCIDevice pci_dev;
 MemoryRegion bar;
-VirtIOPCIRegion common;
-VirtIOPCIRegion isr;
-VirtIOPCIRegion device;
-VirtIOPCIRegion notify;
-VirtIOPCIRegion notify_pio;
+union {
+struct {
+VirtIOPCIRegion common;
+VirtIOPCIRegion isr;
+VirtIOPCIRegion device;
+VirtIOPCIRegion notify;
+VirtIOPCIRegion notify_pio;
+};
+VirtIOPCIRegion regs[5];
+};
 MemoryRegion modern_bar;
 MemoryRegion io_bar;
-MemoryRegion modern_cfg;
-AddressSpace modern_as;
 uint32_t legacy_io_bar_idx;
 uint32_t msix_bar_idx;
 uint32_t modern_io_bar_idx;
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 6c60aa0..e92837c 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -491,6 +491,24 @@ static const MemoryRegionOps virtio_pci_config_ops = {
 .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
+static MemoryRegion *virtio_address_space_lookup(VirtIOPCIProxy *proxy,
+ hwaddr *off, int len)
+{
+int i;
+VirtIOPCIRegion *reg;
+
+for (i = 0; i < ARRAY_SIZE(proxy->regs); ++i) {
+reg = >regs[i];
+if (*off >= reg->offset &&
+*off + len <= reg->offset + reg->size) {
+*off -= reg->offset;
+return >mr;
+}
+}
+
+return NULL;
+}
+
 /* Below are generic functions to do memcpy from/to an address space,
  * without byteswaps, with input validation.
  *
@@ -504,63 +522,72 @@ static const MemoryRegionOps virtio_pci_config_ops = {
  * Note: host pointer must be aligned.
  */
 static
-void virtio_address_space_write(AddressSpace *as, hwaddr addr,
+void virtio_address_space_write(VirtIOPCIProxy *proxy, hwaddr addr,
 const uint8_t *buf, int len)
 {
-uint32_t val;
+uint64_t val;
+MemoryRegion *mr;
 
 /* address_space_* APIs assume an aligned address.
  * As address is under guest control, handle illegal values.
  */
 addr &= ~(len - 1);
 
+mr = virtio_address_space_lookup(proxy, , len);
+if (!mr) {
+return;
+}
+
 /* Make sure caller aligned buf properly */
 assert(!(((uintptr_t)buf) & (len - 1)));
 
 switch (len) {
 case 1:
 val = pci_get_byte(buf);
-address_space_stb(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL);
 break;
 case 2:
-val = pci_get_word(buf);
-address_space_stw_le(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL);
+val = cpu_to_le16(pci_get_word(buf));
 break;
 case 4:
-val = pci_get_long(buf);
-address_space_stl_le(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL);
+val = cpu_to_le32(pci_get_long(buf));
 break;
 default:
 /* As length is under guest control, handle illegal values. */
-break;
+return;
 }
+memory_region_dispatch_write(mr, addr, val, len, MEMTXATTRS_UNSPECIFIED);
 }
 
 static void
-virtio_address_space_read(AddressSpace *as, hwaddr addr, uint8_t *buf, int len)
+virtio_address_space_read(VirtIOPCIProxy *proxy, hwaddr addr,
+  uint8_t *buf, int len)
 {
-uint32_t val;
+uint64_t val;
+MemoryRegion *mr;
 
 /* address_space_* APIs assume an aligned address.
  * As address is under guest control, handle illegal values.
  */
 addr &= ~(len - 1);
 
+mr = virtio_address_space_lookup(proxy, , len);
+if (!mr) {
+return;
+}
+
 /* Make sure caller aligned buf properly */
 assert(!(((uintptr_t)buf) & (len - 1)));
 
+memory_region_dispatch_read(mr, addr, , len, MEMTXATTRS_UNSPECIFIED);
 switch (len) {
 case 1:
-val 

[Qemu-devel] [PULL 16/26] pci: Add interface names to hybrid PCI devices

2017-10-14 Thread Michael S. Tsirkin
From: Eduardo Habkost 

The following devices support both PCI Express and Conventional
PCI, by including special code to handle the QEMU_PCI_CAP_EXPRESS
flag and/or conditional pcie_endpoint_cap_init() calls:

* vfio-pci (is_express=1, but legacy PCI handled by
  vfio_populate_device())
* vmxnet3 (is_express=0, but PCIe handled by vmxnet3_realize())
* pvscsi (is_express=0, but PCIe handled by pvscsi_realize())
* virtio-pci (is_express=0, but PCIe handled by
  virtio_pci_dc_realize(), and additional legacy PCI code at
  virtio_pci_realize())
* base-xhci (is_express=1, but pcie_endpoint_cap_init() call
  is conditional on pci_bus_is_express(dev->bus)
  * Note that xhci does not clear QEMU_PCI_CAP_EXPRESS like the
other hybrid devices

Cc: Dmitry Fleytman 
Cc: Jason Wang 
Cc: Paolo Bonzini 
Cc: Gerd Hoffmann 
Cc: Alex Williamson 
Cc: "Michael S. Tsirkin" 
Signed-off-by: Eduardo Habkost 
Reviewed-by: David Gibson 
Reviewed-by: Marcel Apfelbaum 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/net/vmxnet3.c   | 5 +
 hw/scsi/vmw_pvscsi.c   | 2 ++
 hw/usb/hcd-xhci.c  | 5 +
 hw/vfio/pci.c  | 5 +
 hw/virtio/virtio-pci.c | 5 +
 5 files changed, 22 insertions(+)

diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
index b43b58b..8c4bae5 100644
--- a/hw/net/vmxnet3.c
+++ b/hw/net/vmxnet3.c
@@ -2653,6 +2653,11 @@ static const TypeInfo vmxnet3_info = {
 .instance_size = sizeof(VMXNET3State),
 .class_init= vmxnet3_class_init,
 .instance_init = vmxnet3_instance_init,
+.interfaces = (InterfaceInfo[]) {
+{ INTERFACE_PCIE_DEVICE },
+{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
+{ }
+},
 };
 
 static void vmxnet3_register_types(void)
diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
index d807915..d564e5c 100644
--- a/hw/scsi/vmw_pvscsi.c
+++ b/hw/scsi/vmw_pvscsi.c
@@ -1302,6 +1302,8 @@ static const TypeInfo pvscsi_info = {
 .class_init= pvscsi_class_init,
 .interfaces = (InterfaceInfo[]) {
 { TYPE_HOTPLUG_HANDLER },
+{ INTERFACE_PCIE_DEVICE },
+{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
 { }
 }
 };
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index d75c085..af3a9d8 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -3670,6 +3670,11 @@ static const TypeInfo xhci_info = {
 .instance_size = sizeof(XHCIState),
 .class_init= xhci_class_init,
 .abstract  = true,
+.interfaces = (InterfaceInfo[]) {
+{ INTERFACE_PCIE_DEVICE },
+{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
+{ }
+},
 };
 
 static void qemu_xhci_class_init(ObjectClass *klass, void *data)
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 9e86db7..c977ee3 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -3036,6 +3036,11 @@ static const TypeInfo vfio_pci_dev_info = {
 .class_init = vfio_pci_dev_class_init,
 .instance_init = vfio_instance_init,
 .instance_finalize = vfio_instance_finalize,
+.interfaces = (InterfaceInfo[]) {
+{ INTERFACE_PCIE_DEVICE },
+{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
+{ }
+},
 };
 
 static void register_vfio_pci_dev_type(void)
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index f825a68..6c60aa0 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1904,6 +1904,11 @@ static const TypeInfo virtio_pci_info = {
 .class_init= virtio_pci_class_init,
 .class_size= sizeof(VirtioPCIClass),
 .abstract  = true,
+.interfaces = (InterfaceInfo[]) {
+{ INTERFACE_PCIE_DEVICE },
+{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
+{ }
+},
 };
 
 /* virtio-blk-pci */
-- 
MST




[Qemu-devel] [PULL 20/26] pci: Validate interfaces on base_class_init

2017-10-14 Thread Michael S. Tsirkin
From: Eduardo Habkost 

Make sure we don't forget to add the Conventional PCI or PCI
Express interface names on PCI device classes in the future.

Signed-off-by: Eduardo Habkost 
Revieed-by: David Gibson 
Reviewed-by: Marcel Apfelbaum 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/pci/pci.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 1b08e18..5ed3c8d 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -2547,6 +2547,17 @@ static void pci_device_class_init(ObjectClass *klass, 
void *data)
 pc->realize = pci_default_realize;
 }
 
+static void pci_device_class_base_init(ObjectClass *klass, void *data)
+{
+if (!object_class_is_abstract(klass)) {
+ObjectClass *conventional =
+object_class_dynamic_cast(klass, 
INTERFACE_CONVENTIONAL_PCI_DEVICE);
+ObjectClass *pcie =
+object_class_dynamic_cast(klass, INTERFACE_PCIE_DEVICE);
+assert(conventional || pcie);
+}
+}
+
 AddressSpace *pci_device_iommu_address_space(PCIDevice *dev)
 {
 PCIBus *bus = PCI_BUS(dev->bus);
@@ -2671,6 +2682,7 @@ static const TypeInfo pci_device_type_info = {
 .abstract = true,
 .class_size = sizeof(PCIDeviceClass),
 .class_init = pci_device_class_init,
+.class_base_init = pci_device_class_base_init,
 };
 
 static void pci_register_types(void)
-- 
MST




[Qemu-devel] [PULL 14/26] PCI: PCIe access should always be little endian

2017-10-14 Thread Michael S. Tsirkin
From: Matt Redfearn 

PCIe busses are always little endian, so set the endianness of the
memory region to little endian rather than native such that operations
work as expected on big endian targets.

Signed-off-by: Matt Redfearn 
Reviewed-by: Marcel Apfelbaum 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/pci/pcie_host.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/pci/pcie_host.c b/hw/pci/pcie_host.c
index dcebf57..553db56 100644
--- a/hw/pci/pcie_host.c
+++ b/hw/pci/pcie_host.c
@@ -81,7 +81,7 @@ static uint64_t pcie_mmcfg_data_read(void *opaque,
 static const MemoryRegionOps pcie_mmcfg_ops = {
 .read = pcie_mmcfg_data_read,
 .write = pcie_mmcfg_data_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static void pcie_host_init(Object *obj)
-- 
MST




[Qemu-devel] [PULL 21/26] hw/gen_pcie_root_port: make IO RO 0 on IO disabled

2017-10-14 Thread Michael S. Tsirkin
From: Marcel Apfelbaum 

IO_LIMIT and IO_BASE registers should not be writable if
gen_pcie_root_port's io-reserve property is set to 0.
The COMMAND register should have the IO flag read only.

Signed-off-by: Marcel Apfelbaum 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/pci-bridge/gen_pcie_root_port.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/hw/pci-bridge/gen_pcie_root_port.c 
b/hw/pci-bridge/gen_pcie_root_port.c
index ed03ffc..ad4e6aa 100644
--- a/hw/pci-bridge/gen_pcie_root_port.c
+++ b/hw/pci-bridge/gen_pcie_root_port.c
@@ -85,6 +85,13 @@ static void gen_rp_realize(DeviceState *dev, Error **errp)
 rpc->parent_class.exit(d);
 return;
 }
+
+if (!grp->io_reserve) {
+pci_word_test_and_clear_mask(d->wmask + PCI_COMMAND,
+ PCI_COMMAND_IO);
+d->wmask[PCI_IO_BASE] = 0;
+d->wmask[PCI_IO_LIMIT] = 0;
+}
 }
 
 static const VMStateDescription vmstate_rp_dev = {
-- 
MST




[Qemu-devel] [PULL 11/26] pci: allow 32-bit PCI IO accesses to pass through the PCI bridge

2017-10-14 Thread Michael S. Tsirkin
From: Mark Cave-Ayland 

Whilst the underlying PCI bridge implementation supports 32-bit PCI IO
accesses, unfortunately they are truncated at the legacy 64K limit.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Richard Henderson 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/pci/pci_bridge.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c
index 17feae5..a47d257 100644
--- a/hw/pci/pci_bridge.c
+++ b/hw/pci/pci_bridge.c
@@ -379,7 +379,8 @@ void pci_bridge_initfn(PCIDevice *dev, const char *typename)
 sec_bus->address_space_mem = >address_space_mem;
 memory_region_init(>address_space_mem, OBJECT(br), "pci_bridge_pci", 
UINT64_MAX);
 sec_bus->address_space_io = >address_space_io;
-memory_region_init(>address_space_io, OBJECT(br), "pci_bridge_io", 
65536);
+memory_region_init(>address_space_io, OBJECT(br), "pci_bridge_io",
+   UINT32_MAX);
 br->windows = pci_bridge_region_init(br);
 QLIST_INIT(_bus->child);
 QLIST_INSERT_HEAD(>child, sec_bus, sibling);
-- 
MST




[Qemu-devel] [PULL 15/26] pci: conventional-pci-device and pci-express-device interfaces

2017-10-14 Thread Michael S. Tsirkin
From: Eduardo Habkost 

Those two interfaces will be used to indicate which device types
support Conventional PCI or PCI Express buses.  Management
software will be able to use the qom-list-types QMP command to
query that information.

Signed-off-by: Eduardo Habkost 
Reviewed-by: David Gibson 
Reviewed-by: Marcel Apfelbaum 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 include/hw/pci/pci.h |  6 ++
 hw/pci/pci.c | 12 
 2 files changed, 18 insertions(+)

diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index aa7ef9c..8d02a0a 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -198,6 +198,12 @@ enum {
 #define PCI_DEVICE_GET_CLASS(obj) \
  OBJECT_GET_CLASS(PCIDeviceClass, (obj), TYPE_PCI_DEVICE)
 
+/* Implemented by devices that can be plugged on PCI Express buses */
+#define INTERFACE_PCIE_DEVICE "pci-express-device"
+
+/* Implemented by devices that can be plugged on Conventional PCI buses */
+#define INTERFACE_CONVENTIONAL_PCI_DEVICE "conventional-pci-device"
+
 typedef struct PCIINTxRoute {
 enum {
 PCI_INTX_ENABLED,
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 1e6fb88..1b08e18 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -170,6 +170,16 @@ static const TypeInfo pci_bus_info = {
 .class_init = pci_bus_class_init,
 };
 
+static const TypeInfo pcie_interface_info = {
+.name  = INTERFACE_PCIE_DEVICE,
+.parent= TYPE_INTERFACE,
+};
+
+static const TypeInfo conventional_pci_interface_info = {
+.name  = INTERFACE_CONVENTIONAL_PCI_DEVICE,
+.parent= TYPE_INTERFACE,
+};
+
 static const TypeInfo pcie_bus_info = {
 .name = TYPE_PCIE_BUS,
 .parent = TYPE_PCI_BUS,
@@ -2667,6 +2677,8 @@ static void pci_register_types(void)
 {
 type_register_static(_bus_info);
 type_register_static(_bus_info);
+type_register_static(_pci_interface_info);
+type_register_static(_interface_info);
 type_register_static(_device_type_info);
 }
 
-- 
MST




[Qemu-devel] [PULL 17/26] pci: Add INTERFACE_PCIE_DEVICE to all PCIe devices

2017-10-14 Thread Michael S. Tsirkin
From: Eduardo Habkost 

Change all devices that set is_express=1 to implement
INTERFACE_PCIE_DEVICE.

Cc: Keith Busch 
Cc: Kevin Wolf 
Cc: Max Reitz 
Cc: Dmitry Fleytman 
Cc: Jason Wang 
Cc: "Michael S. Tsirkin" 
Cc: Marcel Apfelbaum 
Cc: Paul Burton 
Cc: Paolo Bonzini 
Cc: Hannes Reinecke 
Cc: qemu-bl...@nongnu.org
Reviewed-by: Alistair Francis 
Signed-off-by: Eduardo Habkost 
Reviewed-by: David Gibson 
Reviewed-by: Marcel Apfelbaum 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/block/nvme.c| 4 
 hw/net/e1000e.c| 4 
 hw/pci-bridge/pcie_pci_bridge.c| 1 +
 hw/pci-bridge/pcie_root_port.c | 4 
 hw/pci-bridge/xio3130_downstream.c | 4 
 hw/pci-bridge/xio3130_upstream.c   | 4 
 hw/pci-host/xilinx-pcie.c  | 4 
 hw/scsi/megasas.c  | 6 ++
 8 files changed, 31 insertions(+)

diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 9aa3269..441e21e 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -1110,6 +1110,10 @@ static const TypeInfo nvme_info = {
 .instance_size = sizeof(NvmeCtrl),
 .class_init= nvme_class_init,
 .instance_init = nvme_instance_init,
+.interfaces = (InterfaceInfo[]) {
+{ INTERFACE_PCIE_DEVICE },
+{ }
+},
 };
 
 static void nvme_register_types(void)
diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c
index 744f0f3..f1af279 100644
--- a/hw/net/e1000e.c
+++ b/hw/net/e1000e.c
@@ -710,6 +710,10 @@ static const TypeInfo e1000e_info = {
 .instance_size = sizeof(E1000EState),
 .class_init = e1000e_class_init,
 .instance_init = e1000e_instance_init,
+.interfaces = (InterfaceInfo[]) {
+{ INTERFACE_PCIE_DEVICE },
+{ }
+},
 };
 
 static void e1000e_register_types(void)
diff --git a/hw/pci-bridge/pcie_pci_bridge.c b/hw/pci-bridge/pcie_pci_bridge.c
index da562fe..a4d827c 100644
--- a/hw/pci-bridge/pcie_pci_bridge.c
+++ b/hw/pci-bridge/pcie_pci_bridge.c
@@ -192,6 +192,7 @@ static const TypeInfo pcie_pci_bridge_info = {
 .class_init = pcie_pci_bridge_class_init,
 .interfaces = (InterfaceInfo[]) {
 { TYPE_HOTPLUG_HANDLER },
+{ INTERFACE_PCIE_DEVICE },
 { },
 }
 };
diff --git a/hw/pci-bridge/pcie_root_port.c b/hw/pci-bridge/pcie_root_port.c
index 4d588cb..9b6e4ce 100644
--- a/hw/pci-bridge/pcie_root_port.c
+++ b/hw/pci-bridge/pcie_root_port.c
@@ -161,6 +161,10 @@ static const TypeInfo rp_info = {
 .class_init= rp_class_init,
 .abstract  = true,
 .class_size = sizeof(PCIERootPortClass),
+.interfaces = (InterfaceInfo[]) {
+{ INTERFACE_PCIE_DEVICE },
+{ }
+},
 };
 
 static void rp_register_types(void)
diff --git a/hw/pci-bridge/xio3130_downstream.c 
b/hw/pci-bridge/xio3130_downstream.c
index 5a882b0..1e09d2a 100644
--- a/hw/pci-bridge/xio3130_downstream.c
+++ b/hw/pci-bridge/xio3130_downstream.c
@@ -196,6 +196,10 @@ static const TypeInfo xio3130_downstream_info = {
 .name  = "xio3130-downstream",
 .parent= TYPE_PCIE_SLOT,
 .class_init= xio3130_downstream_class_init,
+.interfaces = (InterfaceInfo[]) {
+{ INTERFACE_PCIE_DEVICE },
+{ }
+},
 };
 
 static void xio3130_downstream_register_types(void)
diff --git a/hw/pci-bridge/xio3130_upstream.c b/hw/pci-bridge/xio3130_upstream.c
index a052224..227997c 100644
--- a/hw/pci-bridge/xio3130_upstream.c
+++ b/hw/pci-bridge/xio3130_upstream.c
@@ -166,6 +166,10 @@ static const TypeInfo xio3130_upstream_info = {
 .name  = "x3130-upstream",
 .parent= TYPE_PCIE_PORT,
 .class_init= xio3130_upstream_class_init,
+.interfaces = (InterfaceInfo[]) {
+{ INTERFACE_PCIE_DEVICE },
+{ }
+},
 };
 
 static void xio3130_upstream_register_types(void)
diff --git a/hw/pci-host/xilinx-pcie.c b/hw/pci-host/xilinx-pcie.c
index 4613dda..7659253 100644
--- a/hw/pci-host/xilinx-pcie.c
+++ b/hw/pci-host/xilinx-pcie.c
@@ -317,6 +317,10 @@ static const TypeInfo xilinx_pcie_root_info = {
 .parent = TYPE_PCI_BRIDGE,
 .instance_size = sizeof(XilinxPCIERoot),
 .class_init = xilinx_pcie_root_class_init,
+.interfaces = (InterfaceInfo[]) {
+{ INTERFACE_PCIE_DEVICE },
+{ }
+},
 };
 
 static void xilinx_pcie_register(void)
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index 0db68aa..535ee26 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -2451,6 +2451,7 @@ typedef struct MegasasInfo {
 int osts;
 const VMStateDescription *vmsd;
 Property *props;
+InterfaceInfo *interfaces;
 } MegasasInfo;
 
 static 

[Qemu-devel] [PULL 09/26] MAINTAINERS: add Dump maintainers

2017-10-14 Thread Michael S. Tsirkin
From: Marc-André Lureau 

Proposing myself, since I have some familiarity with the code now.

Signed-off-by: Marc-André Lureau 
Acked-by: Laszlo Ersek 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 MAINTAINERS | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 772ac20..9cff973 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1317,6 +1317,17 @@ S: Maintained
 F: device_tree.c
 F: include/sysemu/device_tree.h
 
+Dump
+S: Supported
+M: Marc-André Lureau 
+F: dump.c
+F: hw/misc/vmcoreinfo.c
+F: include/hw/misc/vmcoreinfo.h
+F: include/sysemu/dump-arch.h
+F: include/sysemu/dump.h
+F: scripts/dump-guest-memory.py
+F: stubs/dump.c
+
 Error reporting
 M: Markus Armbruster 
 S: Supported
-- 
MST




[Qemu-devel] [PULL 12/26] hw/pci-bridge/pcie_pci_bridge: properly handle MSI unavailability case

2017-10-14 Thread Michael S. Tsirkin
From: Aleksandr Bezzubikov 

QEMU with the pcie-pci-bridge device crashes if the guest board doesn't support 
MSI,
e.g. 'qemu-system-ppc64 -M prep -device pcie-pci-bridge'.
This is caused by wrong pcie-pci-bridge instantiation error handling. This 
patch fixes this issue
by falling back to legacy INTx if MSI is not available.
Also set the bridge's 'msi' property default value to 'auto' in order to 
trigger errors
only when user explicitly set msi=on.

Reported-by: Eduardo Habkost 
Signed-off-by: Aleksandr Bezzubikov 
Reviewed-by: Marcel Apfelbaum 
Tested-by: Thomas Huth 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/pci-bridge/pcie_pci_bridge.c | 24 ++--
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/hw/pci-bridge/pcie_pci_bridge.c b/hw/pci-bridge/pcie_pci_bridge.c
index 9aa5cc3..da562fe 100644
--- a/hw/pci-bridge/pcie_pci_bridge.c
+++ b/hw/pci-bridge/pcie_pci_bridge.c
@@ -65,10 +65,18 @@ static void pcie_pci_bridge_realize(PCIDevice *d, Error 
**errp)
 goto aer_error;
 }
 
+Error *local_err = NULL;
 if (pcie_br->msi != ON_OFF_AUTO_OFF) {
-rc = msi_init(d, 0, 1, true, true, errp);
+rc = msi_init(d, 0, 1, true, true, _err);
 if (rc < 0) {
-goto msi_error;
+assert(rc == -ENOTSUP);
+if (pcie_br->msi != ON_OFF_AUTO_ON) {
+error_free(local_err);
+} else {
+/* failed to satisfy user's explicit request for MSI */
+error_propagate(errp, local_err);
+goto msi_error;
+}
 }
 }
 pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY |
@@ -81,7 +89,7 @@ aer_error:
 pm_error:
 pcie_cap_exit(d);
 cap_error:
-shpc_free(d);
+shpc_cleanup(d, _br->shpc_bar);
 error:
 pci_bridge_exitfn(d);
 }
@@ -98,7 +106,9 @@ static void pcie_pci_bridge_reset(DeviceState *qdev)
 {
 PCIDevice *d = PCI_DEVICE(qdev);
 pci_bridge_reset(qdev);
-msi_reset(d);
+if (msi_present(d)) {
+msi_reset(d);
+}
 shpc_reset(d);
 }
 
@@ -106,12 +116,14 @@ static void pcie_pci_bridge_write_config(PCIDevice *d,
 uint32_t address, uint32_t val, int len)
 {
 pci_bridge_write_config(d, address, val, len);
-msi_write_config(d, address, val, len);
+if (msi_present(d)) {
+msi_write_config(d, address, val, len);
+}
 shpc_cap_write_config(d, address, val, len);
 }
 
 static Property pcie_pci_bridge_dev_properties[] = {
-DEFINE_PROP_ON_OFF_AUTO("msi", PCIEPCIBridge, msi, ON_OFF_AUTO_ON),
+DEFINE_PROP_ON_OFF_AUTO("msi", PCIEPCIBridge, msi, ON_OFF_AUTO_AUTO),
 DEFINE_PROP_END_OF_LIST(),
 };
 
-- 
MST




[Qemu-devel] [PULL 13/26] virtio/pci/migration: Convert to VMState

2017-10-14 Thread Michael S. Tsirkin
From: "Dr. David Alan Gilbert" 

Convert the 'modern_state' part of virtio-pci to modern migration
macros.

Signed-off-by: Dr. David Alan Gilbert 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/virtio/virtio-pci.c | 108 +
 1 file changed, 27 insertions(+), 81 deletions(-)

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 8b0d6b6..f825a68 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -88,77 +88,19 @@ static void virtio_pci_save_config(DeviceState *d, QEMUFile 
*f)
 qemu_put_be16(f, vdev->config_vector);
 }
 
-static void virtio_pci_load_modern_queue_state(VirtIOPCIQueue *vq,
-   QEMUFile *f)
-{
-vq->num = qemu_get_be16(f);
-vq->enabled = qemu_get_be16(f);
-vq->desc[0] = qemu_get_be32(f);
-vq->desc[1] = qemu_get_be32(f);
-vq->avail[0] = qemu_get_be32(f);
-vq->avail[1] = qemu_get_be32(f);
-vq->used[0] = qemu_get_be32(f);
-vq->used[1] = qemu_get_be32(f);
-}
-
-static bool virtio_pci_has_extra_state(DeviceState *d)
-{
-VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
-
-return proxy->flags & VIRTIO_PCI_FLAG_MIGRATE_EXTRA;
-}
-
-static int get_virtio_pci_modern_state(QEMUFile *f, void *pv, size_t size,
-   VMStateField *field)
-{
-VirtIOPCIProxy *proxy = pv;
-int i;
-
-proxy->dfselect = qemu_get_be32(f);
-proxy->gfselect = qemu_get_be32(f);
-proxy->guest_features[0] = qemu_get_be32(f);
-proxy->guest_features[1] = qemu_get_be32(f);
-for (i = 0; i < VIRTIO_QUEUE_MAX; i++) {
-virtio_pci_load_modern_queue_state(>vqs[i], f);
-}
-
-return 0;
-}
-
-static void virtio_pci_save_modern_queue_state(VirtIOPCIQueue *vq,
-   QEMUFile *f)
-{
-qemu_put_be16(f, vq->num);
-qemu_put_be16(f, vq->enabled);
-qemu_put_be32(f, vq->desc[0]);
-qemu_put_be32(f, vq->desc[1]);
-qemu_put_be32(f, vq->avail[0]);
-qemu_put_be32(f, vq->avail[1]);
-qemu_put_be32(f, vq->used[0]);
-qemu_put_be32(f, vq->used[1]);
-}
-
-static int put_virtio_pci_modern_state(QEMUFile *f, void *pv, size_t size,
-   VMStateField *field, QJSON *vmdesc)
-{
-VirtIOPCIProxy *proxy = pv;
-int i;
-
-qemu_put_be32(f, proxy->dfselect);
-qemu_put_be32(f, proxy->gfselect);
-qemu_put_be32(f, proxy->guest_features[0]);
-qemu_put_be32(f, proxy->guest_features[1]);
-for (i = 0; i < VIRTIO_QUEUE_MAX; i++) {
-virtio_pci_save_modern_queue_state(>vqs[i], f);
+static const VMStateDescription vmstate_virtio_pci_modern_queue_state = {
+.name = "virtio_pci/modern_queue_state",
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT16(num, VirtIOPCIQueue),
+VMSTATE_UNUSED(1), /* enabled was stored as be16 */
+VMSTATE_BOOL(enabled, VirtIOPCIQueue),
+VMSTATE_UINT32_ARRAY(desc, VirtIOPCIQueue, 2),
+VMSTATE_UINT32_ARRAY(avail, VirtIOPCIQueue, 2),
+VMSTATE_UINT32_ARRAY(used, VirtIOPCIQueue, 2),
+VMSTATE_END_OF_LIST()
 }
-
-return 0;
-}
-
-static const VMStateInfo vmstate_info_virtio_pci_modern_state = {
-.name = "virtqueue_state",
-.get = get_virtio_pci_modern_state,
-.put = put_virtio_pci_modern_state,
 };
 
 static bool virtio_pci_modern_state_needed(void *opaque)
@@ -168,21 +110,18 @@ static bool virtio_pci_modern_state_needed(void *opaque)
 return virtio_pci_modern(proxy);
 }
 
-static const VMStateDescription vmstate_virtio_pci_modern_state = {
+static const VMStateDescription vmstate_virtio_pci_modern_state_sub = {
 .name = "virtio_pci/modern_state",
 .version_id = 1,
 .minimum_version_id = 1,
 .needed = _pci_modern_state_needed,
 .fields = (VMStateField[]) {
-{
-.name = "modern_state",
-.version_id   = 0,
-.field_exists = NULL,
-.size = 0,
-.info = _info_virtio_pci_modern_state,
-.flags= VMS_SINGLE,
-.offset   = 0,
-},
+VMSTATE_UINT32(dfselect, VirtIOPCIProxy),
+VMSTATE_UINT32(gfselect, VirtIOPCIProxy),
+VMSTATE_UINT32_ARRAY(guest_features, VirtIOPCIProxy, 2),
+VMSTATE_STRUCT_ARRAY(vqs, VirtIOPCIProxy, VIRTIO_QUEUE_MAX, 0,
+ vmstate_virtio_pci_modern_queue_state,
+ VirtIOPCIQueue),
 VMSTATE_END_OF_LIST()
 }
 };
@@ -196,11 +135,18 @@ static const VMStateDescription vmstate_virtio_pci = {
 VMSTATE_END_OF_LIST()
 },
 .subsections = (const VMStateDescription*[]) {
-_virtio_pci_modern_state,
+_virtio_pci_modern_state_sub,
 NULL
 }
 };
 
+static bool 

Re: [Qemu-devel] [PATCH qemu v2] pci: Initialize pci_dev->name before use

2017-10-14 Thread Alexey Kardashevskiy
On 03/10/17 13:10, Alexey Kardashevskiy wrote:
> On 15/09/17 16:35, Alexey Kardashevskiy wrote:
>> This moves pci_dev->name initialization earlier so
>> pci_dev->bus_master_as could get a name instead of an empty string.
>>
>> Signed-off-by: Alexey Kardashevskiy 
>> Reviewed-by: Philippe Mathieu-Daudé 
> 
> Ping?

Ping?


> 
> 
>> ---
>> Changes:
>> v2:
>> * fixed mistype in the commit log
>> * added "rb"
>> ---
>>  hw/pci/pci.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/hw/pci/pci.c b/hw/pci/pci.c
>> index 21e203b056..353195d154 100644
>> --- a/hw/pci/pci.c
>> +++ b/hw/pci/pci.c
>> @@ -1020,6 +1020,7 @@ static PCIDevice *do_pci_register_device(PCIDevice 
>> *pci_dev, PCIBus *bus,
>>  
>>  pci_dev->devfn = devfn;
>>  pci_dev->requester_id_cache = pci_req_id_cache_get(pci_dev);
>> +pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
>>  
>>  memory_region_init(_dev->bus_master_container_region, 
>> OBJECT(pci_dev),
>> "bus master container", UINT64_MAX);
>> @@ -1029,7 +1030,6 @@ static PCIDevice *do_pci_register_device(PCIDevice 
>> *pci_dev, PCIBus *bus,
>>  if (qdev_hotplug) {
>>  pci_init_bus_master(pci_dev);
>>  }
>> -pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
>>  pci_dev->irq_state = 0;
>>  pci_config_alloc(pci_dev);
>>  
>>
> 
> 


-- 
Alexey



[Qemu-devel] [PULL 03/26] fw_cfg: add write callback

2017-10-14 Thread Michael S. Tsirkin
From: Marc-André Lureau 

Reintroduce the write callback that was removed when write support was
removed in commit 023e3148567ac898c7258138f8e86c3c2bb40d07.

Contrary to the previous callback implementation, the write_cb
callback is called whenever a write happened, so handlers must be
ready to handle partial write as necessary.

Signed-off-by: Marc-André Lureau 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 include/hw/nvram/fw_cfg.h |  3 +++
 hw/acpi/vmgenid.c |  2 +-
 hw/core/loader.c  |  2 +-
 hw/i386/acpi-build.c  |  2 +-
 hw/isa/lpc_ich9.c |  4 ++--
 hw/nvram/fw_cfg.c | 14 ++
 6 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h
index f50d068..7ccbae5 100644
--- a/include/hw/nvram/fw_cfg.h
+++ b/include/hw/nvram/fw_cfg.h
@@ -45,6 +45,7 @@ typedef struct FWCfgDmaAccess {
 } QEMU_PACKED FWCfgDmaAccess;
 
 typedef void (*FWCfgCallback)(void *opaque);
+typedef void (*FWCfgWriteCallback)(void *opaque, off_t start, size_t len);
 
 struct FWCfgState {
 /*< private >*/
@@ -183,6 +184,7 @@ void fw_cfg_add_file(FWCfgState *s, const char *filename, 
void *data,
  * @s: fw_cfg device being modified
  * @filename: name of new fw_cfg file item
  * @select_cb: callback function when selecting
+ * @write_cb: callback function after a write
  * @callback_opaque: argument to be passed into callback function
  * @data: pointer to start of item data
  * @len: size of item data
@@ -202,6 +204,7 @@ void fw_cfg_add_file(FWCfgState *s, const char *filename, 
void *data,
  */
 void fw_cfg_add_file_callback(FWCfgState *s, const char *filename,
   FWCfgCallback select_cb,
+  FWCfgWriteCallback write_cb,
   void *callback_opaque,
   void *data, size_t len, bool read_only);
 
diff --git a/hw/acpi/vmgenid.c b/hw/acpi/vmgenid.c
index 2876d8a..105044f 100644
--- a/hw/acpi/vmgenid.c
+++ b/hw/acpi/vmgenid.c
@@ -124,7 +124,7 @@ void vmgenid_add_fw_cfg(VmGenIdState *vms, FWCfgState *s, 
GArray *guid)
 fw_cfg_add_file(s, VMGENID_GUID_FW_CFG_FILE, guid->data,
 VMGENID_FW_CFG_SIZE);
 /* Create a read-write fw_cfg file for Address */
-fw_cfg_add_file_callback(s, VMGENID_ADDR_FW_CFG_FILE, NULL, NULL,
+fw_cfg_add_file_callback(s, VMGENID_ADDR_FW_CFG_FILE, NULL, NULL, NULL,
  vms->vmgenid_addr_le,
  ARRAY_SIZE(vms->vmgenid_addr_le), false);
 }
diff --git a/hw/core/loader.c b/hw/core/loader.c
index 4593061..91669d6 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -1023,7 +1023,7 @@ MemoryRegion *rom_add_blob(const char *name, const void 
*blob, size_t len,
 }
 
 fw_cfg_add_file_callback(fw_cfg, fw_file_name,
- fw_callback, callback_opaque,
+ fw_callback, NULL, callback_opaque,
  data, rom->datasize, read_only);
 }
 return mr;
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 2af37a9..73519ab 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -2911,7 +2911,7 @@ void acpi_setup(void)
 
 build_state->rsdp = g_memdup(tables.rsdp->data, rsdp_size);
 fw_cfg_add_file_callback(pcms->fw_cfg, ACPI_BUILD_RSDP_FILE,
- acpi_build_update, build_state,
+ acpi_build_update, NULL, build_state,
  build_state->rsdp, rsdp_size, true);
 build_state->rsdp_mr = NULL;
 } else {
diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index ac8416d..de8fbb7 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -402,12 +402,12 @@ void ich9_lpc_pm_init(PCIDevice *lpc_pci, bool 
smm_enabled)
  * just link them into fw_cfg here.
  */
 fw_cfg_add_file_callback(fw_cfg, "etc/smi/requested-features",
- NULL, NULL,
+ NULL, NULL, NULL,
  lpc->smi_guest_features_le,
  sizeof lpc->smi_guest_features_le,
  false);
 fw_cfg_add_file_callback(fw_cfg, "etc/smi/features-ok",
- smi_features_ok_callback, lpc,
+ smi_features_ok_callback, NULL, lpc,
  >smi_features_ok,
  sizeof lpc->smi_features_ok,
  true);
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index e3bd626..753ac0e 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -56,6 +56,7 @@ struct FWCfgEntry {
 uint8_t *data;
 void *callback_opaque;
 FWCfgCallback 

[Qemu-devel] [PULL 07/26] kdump: set vmcoreinfo location

2017-10-14 Thread Michael S. Tsirkin
From: Marc-André Lureau 

kdump header provides offset and size of the vmcoreinfo content,
append it if available (skip the ELF note header).

crash-7.1.9 was the first version that started looking in the
vmcoreinfo data for phys_base instead of in the kdump_sub_header.

Signed-off-by: Marc-André Lureau 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 dump.c | 24 
 1 file changed, 24 insertions(+)

diff --git a/dump.c b/dump.c
index 5674512..d4a8c94 100644
--- a/dump.c
+++ b/dump.c
@@ -857,6 +857,18 @@ static void create_header32(DumpState *s, Error **errp)
 kh->dump_level = cpu_to_dump32(s, DUMP_LEVEL);
 
 offset_note = DISKDUMP_HEADER_BLOCKS * block_size + size;
+if (s->guest_note &&
+note_name_equal(s, s->guest_note, "VMCOREINFO")) {
+uint64_t hsize, name_size, size_vmcoreinfo_desc, offset_vmcoreinfo;
+
+get_note_sizes(s, s->guest_note,
+   , _size, _vmcoreinfo_desc);
+offset_vmcoreinfo = offset_note + s->note_size - s->guest_note_size +
+(DIV_ROUND_UP(hsize, 4) + DIV_ROUND_UP(name_size, 4)) * 4;
+kh->offset_vmcoreinfo = cpu_to_dump64(s, offset_vmcoreinfo);
+kh->size_vmcoreinfo = cpu_to_dump32(s, size_vmcoreinfo_desc);
+}
+
 kh->offset_note = cpu_to_dump64(s, offset_note);
 kh->note_size = cpu_to_dump32(s, s->note_size);
 
@@ -957,6 +969,18 @@ static void create_header64(DumpState *s, Error **errp)
 kh->dump_level = cpu_to_dump32(s, DUMP_LEVEL);
 
 offset_note = DISKDUMP_HEADER_BLOCKS * block_size + size;
+if (s->guest_note &&
+note_name_equal(s, s->guest_note, "VMCOREINFO")) {
+uint64_t hsize, name_size, size_vmcoreinfo_desc, offset_vmcoreinfo;
+
+get_note_sizes(s, s->guest_note,
+   , _size, _vmcoreinfo_desc);
+offset_vmcoreinfo = offset_note + s->note_size - s->guest_note_size +
+(DIV_ROUND_UP(hsize, 4) + DIV_ROUND_UP(name_size, 4)) * 4;
+kh->offset_vmcoreinfo = cpu_to_dump64(s, offset_vmcoreinfo);
+kh->size_vmcoreinfo = cpu_to_dump64(s, size_vmcoreinfo_desc);
+}
+
 kh->offset_note = cpu_to_dump64(s, offset_note);
 kh->note_size = cpu_to_dump64(s, s->note_size);
 
-- 
MST




[Qemu-devel] [PULL 08/26] scripts/dump-guest-memory.py: add vmcoreinfo

2017-10-14 Thread Michael S. Tsirkin
From: Marc-André Lureau 

Add a vmcoreinfo ELF note in the dump if vmcoreinfo device has the
memory location details.

Signed-off-by: Marc-André Lureau 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 scripts/dump-guest-memory.py | 61 
 1 file changed, 61 insertions(+)

diff --git a/scripts/dump-guest-memory.py b/scripts/dump-guest-memory.py
index f7c6635..69dd5ef 100644
--- a/scripts/dump-guest-memory.py
+++ b/scripts/dump-guest-memory.py
@@ -14,6 +14,7 @@ the COPYING file in the top-level directory.
 """
 
 import ctypes
+import struct
 
 UINTPTR_T = gdb.lookup_type("uintptr_t")
 
@@ -45,6 +46,17 @@ EM_S390 = 22
 EM_AARCH = 183
 EM_X86_64 = 62
 
+VMCOREINFO_FORMAT_ELF = 1
+
+def le16_to_cpu(val):
+return struct.unpack(" 1 << 20:
+print('warning: invalid vmcoreinfo size')
+return
+# now get the full note
+note = get_arch_note(self.endianness,
+ header.n_namesz - 1, header.n_descsz)
+ctypes.memmove(ctypes.pointer(note), vmcoreinfo, ctypes.sizeof(note))
+
+self.notes.append(note)
+self.segments[0].p_filesz += ctypes.sizeof(note)
+self.segments[0].p_memsz += ctypes.sizeof(note)
+
 def add_segment(self, p_type, p_paddr, p_size):
 """Adds a segment to the elf."""
 
@@ -505,6 +536,35 @@ shape and this command should mostly work."""
 cur += chunk_size
 left -= chunk_size
 
+def phys_memory_read(self, addr, size):
+qemu_core = gdb.inferiors()[0]
+for block in self.guest_phys_blocks:
+if block["target_start"] <= addr \
+   and addr + size <= block["target_end"]:
+haddr = block["host_addr"] + (addr - block["target_start"])
+return qemu_core.read_memory(haddr, size)
+return None
+
+def add_vmcoreinfo(self):
+if not gdb.parse_and_eval("vmcoreinfo_find()") \
+   or not gdb.parse_and_eval("vmcoreinfo_find()->has_vmcoreinfo"):
+return
+
+fmt = gdb.parse_and_eval("vmcoreinfo_find()->vmcoreinfo.guest_format")
+addr = gdb.parse_and_eval("vmcoreinfo_find()->vmcoreinfo.paddr")
+size = gdb.parse_and_eval("vmcoreinfo_find()->vmcoreinfo.size")
+
+fmt = le16_to_cpu(fmt)
+addr = le64_to_cpu(addr)
+size = le32_to_cpu(size)
+
+if fmt != VMCOREINFO_FORMAT_ELF:
+return
+
+vmcoreinfo = self.phys_memory_read(addr, size)
+if vmcoreinfo:
+self.elf.add_vmcoreinfo_note(vmcoreinfo.tobytes())
+
 def invoke(self, args, from_tty):
 """Handles command invocation from gdb."""
 
@@ -518,6 +578,7 @@ shape and this command should mostly work."""
 
 self.elf = ELF(argv[1])
 self.guest_phys_blocks = get_guest_phys_blocks()
+self.add_vmcoreinfo()
 
 with open(argv[0], "wb") as vmcore:
 self.dump_init(vmcore)
-- 
MST




[Qemu-devel] [PULL 26/26] tests/pxe: Test more NICs when running in SPEED=slow mode

2017-10-14 Thread Michael S. Tsirkin
From: Thomas Huth 

The pxe-test is a very good test to excercise NICs, thus we should use
it to test all NICs that can be used by the BIOS for booting via network.
However, to avoid that the default testing time increases too much, the
additional NICs are only tested in the "make check SPEED=slow" mode.

The virtio-net NIC on ppc64 is now also only tested in slow mode, since
the test on ppc64 is really quite slow and we've got test coverage for
virtio-net in big endian mode now on s390x, too.

Signed-off-by: Thomas Huth 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 tests/pxe-test.c | 31 +--
 1 file changed, 21 insertions(+), 10 deletions(-)

diff --git a/tests/pxe-test.c b/tests/pxe-test.c
index 0d70afc..937f29e 100644
--- a/tests/pxe-test.c
+++ b/tests/pxe-test.c
@@ -1,11 +1,12 @@
 /*
  * PXE test cases.
  *
- * Copyright (c) 2016 Red Hat Inc.
+ * Copyright (c) 2016, 2017 Red Hat Inc.
  *
  * Authors:
  *  Michael S. Tsirkin ,
  *  Victor Kaplansky 
+ *  Thomas Huth 
  *
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
@@ -36,14 +37,14 @@ static void test_pxe_one(const char *params, bool ipv6)
 g_free(args);
 }
 
-static void test_pxe_e1000(void)
+static void test_pxe_ipv4(gconstpointer data)
 {
-test_pxe_one("-device e1000,netdev=" NETNAME, false);
-}
+const char *model = data;
+char *dev_arg;
 
-static void test_pxe_virtio_pci(void)
-{
-test_pxe_one("-device virtio-net-pci,netdev=" NETNAME, false);
+dev_arg = g_strdup_printf("-device %s,netdev=" NETNAME, model);
+test_pxe_one(dev_arg, false);
+g_free(dev_arg);
 }
 
 static void test_pxe_spapr_vlan(void)
@@ -68,11 +69,21 @@ int main(int argc, char *argv[])
 g_test_init(, , NULL);
 
 if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
-qtest_add_func("pxe/e1000", test_pxe_e1000);
-qtest_add_func("pxe/virtio", test_pxe_virtio_pci);
+qtest_add_data_func("pxe/e1000", "e1000", test_pxe_ipv4);
+qtest_add_data_func("pxe/virtio", "virtio-net-pci", test_pxe_ipv4);
+if (g_test_slow()) {
+qtest_add_data_func("pxe/ne2000", "ne2k_pci", test_pxe_ipv4);
+qtest_add_data_func("pxe/eepro100", "i82550", test_pxe_ipv4);
+qtest_add_data_func("pxe/pcnet", "pcnet", test_pxe_ipv4);
+qtest_add_data_func("pxe/rtl8139", "rtl8139", test_pxe_ipv4);
+qtest_add_data_func("pxe/vmxnet3", "vmxnet3", test_pxe_ipv4);
+}
 } else if (strcmp(arch, "ppc64") == 0) {
-qtest_add_func("pxe/virtio", test_pxe_virtio_pci);
 qtest_add_func("pxe/spapr-vlan", test_pxe_spapr_vlan);
+if (g_test_slow()) {
+qtest_add_data_func("pxe/virtio", "virtio-net-pci", test_pxe_ipv4);
+qtest_add_data_func("pxe/e1000", "e1000", test_pxe_ipv4);
+}
 } else if (g_str_equal(arch, "s390x")) {
 qtest_add_func("pxe/virtio-ccw", test_pxe_virtio_ccw);
 }
-- 
MST




[Qemu-devel] [PULL 06/26] dump: update phys_base header field based on VMCOREINFO content

2017-10-14 Thread Michael S. Tsirkin
From: Marc-André Lureau 

If the guest note is VMCOREINFO, try to get phys_base from it.

Signed-off-by: Marc-André Lureau 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 docs/specs/vmcoreinfo.txt |  8 +++
 dump.c| 56 +--
 2 files changed, 62 insertions(+), 2 deletions(-)

diff --git a/docs/specs/vmcoreinfo.txt b/docs/specs/vmcoreinfo.txt
index 2868a77..8212610 100644
--- a/docs/specs/vmcoreinfo.txt
+++ b/docs/specs/vmcoreinfo.txt
@@ -39,3 +39,11 @@ qemu dumps.
 
 The note format/class must be of the target bitness and the size must
 be less than 1Mb.
+
+If the ELF note name is "VMCOREINFO", it is expected to be the Linux
+vmcoreinfo note (see Documentation/ABI/testing/sysfs-kernel-vmcoreinfo
+in Linux source). In this case, qemu dump code will read the content
+as a key=value text file, looking for "NUMBER(phys_base)" key
+value. The value is expected to be more accurate than architecture
+guess of the value. This is useful for KASLR-enabled guest with
+ancient tools not handling the VMCOREINFO note.
diff --git a/dump.c b/dump.c
index 1479f1f..5674512 100644
--- a/dump.c
+++ b/dump.c
@@ -779,6 +779,23 @@ static void get_note_sizes(DumpState *s, const void *note,
 }
 }
 
+static bool note_name_equal(DumpState *s,
+const uint8_t *note, const char *name)
+{
+int len = strlen(name) + 1;
+uint64_t head_size, name_size;
+
+get_note_sizes(s, note, _size, _size, NULL);
+head_size = ROUND_UP(head_size, 4);
+
+if (name_size != len ||
+memcmp(note + head_size, "VMCOREINFO", len)) {
+return false;
+}
+
+return true;
+}
+
 /* write common header, sub header and elf note to vmcore */
 static void create_header32(DumpState *s, Error **errp)
 {
@@ -1553,6 +1570,39 @@ static int64_t dump_calculate_size(DumpState *s)
 return total;
 }
 
+static void vmcoreinfo_update_phys_base(DumpState *s)
+{
+uint64_t size, note_head_size, name_size, phys_base;
+char **lines;
+uint8_t *vmci;
+size_t i;
+
+if (!note_name_equal(s, s->guest_note, "VMCOREINFO")) {
+return;
+}
+
+get_note_sizes(s, s->guest_note, _head_size, _size, );
+note_head_size = ROUND_UP(note_head_size, 4);
+
+vmci = s->guest_note + note_head_size + ROUND_UP(name_size, 4);
+*(vmci + size) = '\0';
+
+lines = g_strsplit((char *)vmci, "\n", -1);
+for (i = 0; lines[i]; i++) {
+if (g_str_has_prefix(lines[i], "NUMBER(phys_base)=")) {
+if (qemu_strtou64(lines[i] + 18, NULL, 16,
+  _base) < 0) {
+warn_report("Failed to read NUMBER(phys_base)=");
+} else {
+s->dump_info.phys_base = phys_base;
+}
+break;
+}
+}
+
+g_strfreev(lines);
+}
+
 static void dump_init(DumpState *s, int fd, bool has_format,
   DumpGuestMemoryFormat format, bool paging, bool 
has_filter,
   int64_t begin, int64_t length, Error **errp)
@@ -1636,8 +1686,9 @@ static void dump_init(DumpState *s, int fd, bool 
has_format,
 }
 
 /*
- * The goal of this block is to copy the guest note out of
- * the guest.  Failure to do so is not fatal for dumping.
+ * The goal of this block is to (a) update the previously guessed
+ * phys_base, (b) copy the guest note out of the guest.
+ * Failure to do so is not fatal for dumping.
  */
 if (vmci) {
 uint64_t addr, note_head_size, name_size, desc_size;
@@ -1670,6 +1721,7 @@ static void dump_init(DumpState *s, int fd, bool 
has_format,
 g_free(s->guest_note);
 s->guest_note = NULL;
 } else {
+vmcoreinfo_update_phys_base(s);
 s->note_size += s->guest_note_size;
 }
 }
-- 
MST




[Qemu-devel] [PULL 05/26] dump: add guest ELF note

2017-10-14 Thread Michael S. Tsirkin
From: Marc-André Lureau 

Read the guest ELF PT_NOTE from guest memory when fw_cfg
etc/vmcoreinfo entry provides the location, and write it as an
additional note in the dump.

Signed-off-by: Marc-André Lureau 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 include/sysemu/dump.h |   2 +
 dump.c| 107 ++
 2 files changed, 109 insertions(+)

diff --git a/include/sysemu/dump.h b/include/sysemu/dump.h
index 2672a15..df43bd0 100644
--- a/include/sysemu/dump.h
+++ b/include/sysemu/dump.h
@@ -192,6 +192,8 @@ typedef struct DumpState {
   * this could be used to calculate
   * how much work we have
   * finished. */
+uint8_t *guest_note; /* ELF note content */
+size_t guest_note_size;
 } DumpState;
 
 uint16_t cpu_to_dump16(DumpState *s, uint16_t val);
diff --git a/dump.c b/dump.c
index 7ebcf55..1479f1f 100644
--- a/dump.c
+++ b/dump.c
@@ -25,6 +25,8 @@
 #include "qapi/qmp/qerror.h"
 #include "qmp-commands.h"
 #include "qapi-event.h"
+#include "qemu/error-report.h"
+#include "hw/misc/vmcoreinfo.h"
 
 #include 
 #ifdef CONFIG_LZO
@@ -37,6 +39,13 @@
 #define ELF_MACHINE_UNAME "Unknown"
 #endif
 
+#define MAX_GUEST_NOTE_SIZE (1 << 20) /* 1MB should be enough */
+
+#define ELF_NOTE_SIZE(hdr_size, name_size, desc_size)   \
+((DIV_ROUND_UP((hdr_size), 4) + \
+  DIV_ROUND_UP((name_size), 4) +\
+  DIV_ROUND_UP((desc_size), 4)) * 4)
+
 uint16_t cpu_to_dump16(DumpState *s, uint16_t val)
 {
 if (s->dump_info.d_endian == ELFDATA2LSB) {
@@ -75,6 +84,8 @@ static int dump_cleanup(DumpState *s)
 guest_phys_blocks_free(>guest_phys_blocks);
 memory_mapping_list_free(>list);
 close(s->fd);
+g_free(s->guest_note);
+s->guest_note = NULL;
 if (s->resume) {
 if (s->detached) {
 qemu_mutex_lock_iothread();
@@ -234,6 +245,19 @@ static inline int cpu_index(CPUState *cpu)
 return cpu->cpu_index + 1;
 }
 
+static void write_guest_note(WriteCoreDumpFunction f, DumpState *s,
+ Error **errp)
+{
+int ret;
+
+if (s->guest_note) {
+ret = f(s->guest_note, s->guest_note_size, s);
+if (ret < 0) {
+error_setg(errp, "dump: failed to write guest note");
+}
+}
+}
+
 static void write_elf64_notes(WriteCoreDumpFunction f, DumpState *s,
   Error **errp)
 {
@@ -257,6 +281,8 @@ static void write_elf64_notes(WriteCoreDumpFunction f, 
DumpState *s,
 return;
 }
 }
+
+write_guest_note(f, s, errp);
 }
 
 static void write_elf32_note(DumpState *s, Error **errp)
@@ -302,6 +328,8 @@ static void write_elf32_notes(WriteCoreDumpFunction f, 
DumpState *s,
 return;
 }
 }
+
+write_guest_note(f, s, errp);
 }
 
 static void write_elf_section(DumpState *s, int type, Error **errp)
@@ -713,6 +741,44 @@ static int buf_write_note(const void *buf, size_t size, 
void *opaque)
 return 0;
 }
 
+/*
+ * This function retrieves various sizes from an elf header.
+ *
+ * @note has to be a valid ELF note. The return sizes are unmodified
+ * (not padded or rounded up to be multiple of 4).
+ */
+static void get_note_sizes(DumpState *s, const void *note,
+   uint64_t *note_head_size,
+   uint64_t *name_size,
+   uint64_t *desc_size)
+{
+uint64_t note_head_sz;
+uint64_t name_sz;
+uint64_t desc_sz;
+
+if (s->dump_info.d_class == ELFCLASS64) {
+const Elf64_Nhdr *hdr = note;
+note_head_sz = sizeof(Elf64_Nhdr);
+name_sz = tswap64(hdr->n_namesz);
+desc_sz = tswap64(hdr->n_descsz);
+} else {
+const Elf32_Nhdr *hdr = note;
+note_head_sz = sizeof(Elf32_Nhdr);
+name_sz = tswap32(hdr->n_namesz);
+desc_sz = tswap32(hdr->n_descsz);
+}
+
+if (note_head_size) {
+*note_head_size = note_head_sz;
+}
+if (name_size) {
+*name_size = name_sz;
+}
+if (desc_size) {
+*desc_size = desc_sz;
+}
+}
+
 /* write common header, sub header and elf note to vmcore */
 static void create_header32(DumpState *s, Error **errp)
 {
@@ -1491,6 +1557,7 @@ static void dump_init(DumpState *s, int fd, bool 
has_format,
   DumpGuestMemoryFormat format, bool paging, bool 
has_filter,
   int64_t begin, int64_t length, Error **errp)
 {
+VMCoreInfoState *vmci = vmcoreinfo_find();
 CPUState *cpu;
 int nr_cpus;
 Error *err = NULL;
@@ -1568,6 +1635,46 @@ static void dump_init(DumpState *s, int fd, bool 
has_format,
 goto cleanup;
 }
 
+/*
+ * The goal of this block is to copy the guest note out of
+ * the guest. 

[Qemu-devel] [PULL 01/26] xio3130_downstream: Report error if pcie_chassis_add_slot() failed

2017-10-14 Thread Michael S. Tsirkin
From: Eduardo Habkost 

On commit f8cd1b02 ("pci: Convert to realize"), no error_set*()
call was added for the pcie_chassis_add_slot() error case.
pcie_chassis_add_slot() errors get ignored, making QEMU crash
later.  e.g.:

  $ qemu-system-x86_64 -device ioh3420 -device xio3130-downstream
  qemu-system-x86_64: memory.c:2166: memory_region_del_subregion: Assertion 
`subregion->container == mr' failed.
  Aborted (core dumped)

Fix it by reporting the error using error_setg().

Fixes: f8cd1b0201c41d88bb97dcafb80348a0e88d8805
Signed-off-by: Eduardo Habkost 
Reviewed-by: Marcel Apfelbaum 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/pci-bridge/xio3130_downstream.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/pci-bridge/xio3130_downstream.c 
b/hw/pci-bridge/xio3130_downstream.c
index e706f36..5a882b0 100644
--- a/hw/pci-bridge/xio3130_downstream.c
+++ b/hw/pci-bridge/xio3130_downstream.c
@@ -94,6 +94,7 @@ static void xio3130_downstream_realize(PCIDevice *d, Error 
**errp)
 pcie_chassis_create(s->chassis);
 rc = pcie_chassis_add_slot(s);
 if (rc < 0) {
+error_setg(errp, "Can't add chassis slot, error %d", rc);
 goto err_pcie_cap;
 }
 
-- 
MST




[Qemu-devel] [PULL 10/26] virtio/vhost: reset dev->log after syncing

2017-10-14 Thread Michael S. Tsirkin
From: Felipe Franciosi 

vhost_log_put() is called to decomission the dirty log between qemu and
a vhost device when stopping the device. Such a call can happen from
migration_completion().

Present code sets dev->log_size to zero too early in vhost_log_put(),
causing the sync check to always return false. As a consequence, the
last pass on the dirty bitmap never happens at the end of migration.

If a vhost device was busy (writing to guest memory) until the last
moments before vhost_virtqueue_stop(), this error will result in guest
memory corruption (at least) following migrations.

Signed-off-by: Felipe Franciosi 
Acked-by: Jason Wang 
Reviewed-by: Marc-André Lureau 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/virtio/vhost.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 5fd69f0..ddc42f0 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -375,8 +375,6 @@ static void vhost_log_put(struct vhost_dev *dev, bool sync)
 if (!log) {
 return;
 }
-dev->log = NULL;
-dev->log_size = 0;
 
 --log->refcnt;
 if (log->refcnt == 0) {
@@ -396,6 +394,9 @@ static void vhost_log_put(struct vhost_dev *dev, bool sync)
 
 g_free(log);
 }
+
+dev->log = NULL;
+dev->log_size = 0;
 }
 
 static bool vhost_dev_log_is_shared(struct vhost_dev *dev)
-- 
MST




[Qemu-devel] [PULL 02/26] pci: Set err to errp directly rather than through error_propagate()

2017-10-14 Thread Michael S. Tsirkin
From: Mao Zhongyi 

ioh3420_interrupts_init() pass error message to local_err, then
propagate it to errp by error_propagate(), which is not necessary.
So eliminate it and pass errp directly instead of local_err.

Cc: "Michael S. Tsirkin" 
Cc: Marcel Apfelbaum 
Signed-off-by: Mao Zhongyi 
Reviewed-by: Eric Blake 
Reviewed-by: Marcel Apfelbaum 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Stefan Hajnoczi 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/pci-bridge/ioh3420.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/hw/pci-bridge/ioh3420.c b/hw/pci-bridge/ioh3420.c
index da4e5bd..5f56a2f 100644
--- a/hw/pci-bridge/ioh3420.c
+++ b/hw/pci-bridge/ioh3420.c
@@ -64,15 +64,13 @@ static uint8_t ioh3420_aer_vector(const PCIDevice *d)
 static int ioh3420_interrupts_init(PCIDevice *d, Error **errp)
 {
 int rc;
-Error *local_err = NULL;
 
 rc = msi_init(d, IOH_EP_MSI_OFFSET, IOH_EP_MSI_NR_VECTOR,
   IOH_EP_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_64BIT,
   IOH_EP_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_MASKBIT,
-  _err);
+  errp);
 if (rc < 0) {
 assert(rc == -ENOTSUP);
-error_propagate(errp, local_err);
 }
 
 return rc;
-- 
MST




[Qemu-devel] [PULL 04/26] hw/misc: add vmcoreinfo device

2017-10-14 Thread Michael S. Tsirkin
From: Marc-André Lureau 

See docs/specs/vmcoreinfo.txt for details.

"etc/vmcoreinfo" fw_cfg entry is added when using "-device vmcoreinfo".

Signed-off-by: Marc-André Lureau 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 docs/specs/vmcoreinfo.txt| 41 +++
 include/hw/misc/vmcoreinfo.h | 46 +
 hw/misc/vmcoreinfo.c | 96 
 hw/misc/Makefile.objs|  1 +
 4 files changed, 184 insertions(+)
 create mode 100644 docs/specs/vmcoreinfo.txt
 create mode 100644 include/hw/misc/vmcoreinfo.h
 create mode 100644 hw/misc/vmcoreinfo.c

diff --git a/docs/specs/vmcoreinfo.txt b/docs/specs/vmcoreinfo.txt
new file mode 100644
index 000..2868a77
--- /dev/null
+++ b/docs/specs/vmcoreinfo.txt
@@ -0,0 +1,41 @@
+=
+VMCoreInfo device
+=
+
+The `-device vmcoreinfo` will create a fw_cfg entry for a guest to
+store dump details.
+
+etc/vmcoreinfo
+**
+
+A guest may use this fw_cfg entry to add information details to qemu
+dumps.
+
+The entry of 16 bytes has the following layout, in little-endian::
+
+#define VMCOREINFO_FORMAT_NONE 0x0
+#define VMCOREINFO_FORMAT_ELF 0x1
+
+struct FWCfgVMCoreInfo {
+uint16_t host_format;  /* formats host supports */
+uint16_t guest_format; /* format guest supplies */
+uint32_t size; /* size of vmcoreinfo region */
+uint64_t paddr;/* physical address of vmcoreinfo region */
+};
+
+Only full write (of 16 bytes) are considered valid for further
+processing of entry values.
+
+A write of 0 in guest_format will disable further processing of
+vmcoreinfo entry values & content.
+
+Format & content
+
+
+As of qemu 2.11, only VMCOREINFO_FORMAT_ELF is supported.
+
+The entry gives location and size of an ELF note that is appended in
+qemu dumps.
+
+The note format/class must be of the target bitness and the size must
+be less than 1Mb.
diff --git a/include/hw/misc/vmcoreinfo.h b/include/hw/misc/vmcoreinfo.h
new file mode 100644
index 000..c3aa856
--- /dev/null
+++ b/include/hw/misc/vmcoreinfo.h
@@ -0,0 +1,46 @@
+/*
+ * Virtual Machine coreinfo device
+ *
+ * Copyright (C) 2017 Red Hat, Inc.
+ *
+ * Authors: Marc-André Lureau 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+#ifndef VMCOREINFO_H
+#define VMCOREINFO_H
+
+#include "hw/qdev.h"
+
+#define VMCOREINFO_DEVICE "vmcoreinfo"
+#define VMCOREINFO(obj) OBJECT_CHECK(VMCoreInfoState, (obj), VMCOREINFO_DEVICE)
+
+#define VMCOREINFO_FORMAT_NONE 0x0
+#define VMCOREINFO_FORMAT_ELF 0x1
+
+/* all fields are little-endian */
+typedef struct FWCfgVMCoreInfo {
+uint16_t host_format; /* set on reset */
+uint16_t guest_format;
+uint32_t size;
+uint64_t paddr;
+} QEMU_PACKED FWCfgVMCoreInfo;
+
+typedef struct VMCoreInfoState {
+DeviceClass parent_obj;
+
+bool has_vmcoreinfo;
+FWCfgVMCoreInfo vmcoreinfo;
+} VMCoreInfoState;
+
+/* returns NULL unless there is exactly one device */
+static inline VMCoreInfoState *vmcoreinfo_find(void)
+{
+Object *o = object_resolve_path_type("", VMCOREINFO_DEVICE, NULL);
+
+return o ? VMCOREINFO(o) : NULL;
+}
+
+#endif
diff --git a/hw/misc/vmcoreinfo.c b/hw/misc/vmcoreinfo.c
new file mode 100644
index 000..a618e12
--- /dev/null
+++ b/hw/misc/vmcoreinfo.c
@@ -0,0 +1,96 @@
+/*
+ * Virtual Machine coreinfo device
+ *
+ * Copyright (C) 2017 Red Hat, Inc.
+ *
+ * Authors: Marc-André Lureau 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/nvram/fw_cfg.h"
+#include "hw/misc/vmcoreinfo.h"
+
+static void fw_cfg_vmci_write(void *dev, off_t offset, size_t len)
+{
+VMCoreInfoState *s = VMCOREINFO(dev);
+
+s->has_vmcoreinfo = offset == 0 && len == sizeof(s->vmcoreinfo)
+&& s->vmcoreinfo.guest_format != VMCOREINFO_FORMAT_NONE;
+}
+
+static void vmcoreinfo_reset(void *dev)
+{
+VMCoreInfoState *s = VMCOREINFO(dev);
+
+s->has_vmcoreinfo = false;
+memset(>vmcoreinfo, 0, sizeof(s->vmcoreinfo));
+s->vmcoreinfo.host_format = cpu_to_le16(VMCOREINFO_FORMAT_ELF);
+}
+
+static void vmcoreinfo_realize(DeviceState *dev, Error **errp)
+{
+VMCoreInfoState *s = VMCOREINFO(dev);
+FWCfgState *fw_cfg = fw_cfg_find();
+
+/* Given that this function is executing, there is at least one VMCOREINFO
+ * device. Check if there are several.
+ */
+if (!vmcoreinfo_find()) {
+error_setg(errp, "at most one %s device is permitted",
+   VMCOREINFO_DEVICE);
+return;
+}
+
+if (!fw_cfg || !fw_cfg->dma_enabled) {
+   

[Qemu-devel] [PULL 00/26] pc, pci, virtio: fixes, features

2017-10-14 Thread Michael S. Tsirkin
The following changes since commit f90ea7ba7c5ae7010ee0ce062207ae42530f57d6:

  Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20171012' 
into staging (2017-10-12 17:06:50 +0100)

are available in the git repository at:

  git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_upstream

for you to fetch changes up to ab06ec43577177a442e8e5ca28d0154efe4ff60f:

  tests/pxe: Test more NICs when running in SPEED=slow mode (2017-10-15 
05:54:44 +0300)


pc, pci, virtio: fixes, features

A bunch of fixes all over the place.
A new vmcore device - the user interface around it is still somewhat
controversial, but I feel most of the code is fine, suggestions can be
addressed by adding patches on top.

Signed-off-by: Michael S. Tsirkin 


Aleksandr Bezzubikov (1):
  hw/pci-bridge/pcie_pci_bridge: properly handle MSI unavailability case

Alexey Kardashevskiy (1):
  virtio-pci: Replace modern_as with direct access to modern_bar

Dr. David Alan Gilbert (1):
  virtio/pci/migration: Convert to VMState

Eduardo Habkost (8):
  xio3130_downstream: Report error if pcie_chassis_add_slot() failed
  pci: conventional-pci-device and pci-express-device interfaces
  pci: Add interface names to hybrid PCI devices
  pci: Add INTERFACE_PCIE_DEVICE to all PCIe devices
  pci: Add INTERFACE_CONVENTIONAL_PCI_DEVICE to Conventional PCI devices
  xen/pt: Mark TYPE_XEN_PT_DEVICE as hybrid
  pci: Validate interfaces on base_class_init
  isapc: Remove unnecessary migration compatibility code

Felipe Franciosi (1):
  virtio/vhost: reset dev->log after syncing

Laurent Vivier (1):
  pc: remove useless hot_add_cpu initialisation

Mao Zhongyi (1):
  pci: Set err to errp directly rather than through error_propagate()

Marc-André Lureau (7):
  fw_cfg: add write callback
  hw/misc: add vmcoreinfo device
  dump: add guest ELF note
  dump: update phys_base header field based on VMCOREINFO content
  kdump: set vmcoreinfo location
  scripts/dump-guest-memory.py: add vmcoreinfo
  MAINTAINERS: add Dump maintainers

Marcel Apfelbaum (1):
  hw/gen_pcie_root_port: make IO RO 0 on IO disabled

Mark Cave-Ayland (1):
  pci: allow 32-bit PCI IO accesses to pass through the PCI bridge

Matt Redfearn (1):
  PCI: PCIe access should always be little endian

Thomas Huth (1):
  tests/pxe: Test more NICs when running in SPEED=slow mode

Wolfgang Bumiller (1):
  virtio: fix descriptor counting in virtqueue_pop

 docs/specs/vmcoreinfo.txt   |  49 ++
 hw/virtio/virtio-pci.h  |  17 ++--
 include/hw/misc/vmcoreinfo.h|  46 +
 include/hw/nvram/fw_cfg.h   |   3 +
 include/hw/pci/pci.h|   6 ++
 include/sysemu/dump.h   |   2 +
 dump.c  | 183 +++
 hw/acpi/piix4.c |   1 +
 hw/acpi/vmgenid.c   |   2 +-
 hw/audio/ac97.c |   4 +
 hw/audio/es1370.c   |   4 +
 hw/audio/intel-hda.c|   4 +
 hw/block/nvme.c |   4 +
 hw/char/serial-pci.c|  12 +++
 hw/core/loader.c|   2 +-
 hw/display/cirrus_vga.c |   4 +
 hw/display/qxl.c|   4 +
 hw/display/sm501.c  |   4 +
 hw/display/vga-pci.c|   4 +
 hw/display/vmware_vga.c |   4 +
 hw/i2c/smbus_ich9.c |   4 +
 hw/i386/acpi-build.c|   2 +-
 hw/i386/amd_iommu.c |   4 +
 hw/i386/kvm/pci-assign.c|   4 +
 hw/i386/pc_piix.c   |   8 +-
 hw/i386/pc_q35.c|   1 -
 hw/i386/xen/xen_platform.c  |   4 +
 hw/i386/xen/xen_pvdevice.c  |   4 +
 hw/ide/ich.c|   4 +
 hw/ide/pci.c|   4 +
 hw/ipack/tpci200.c  |   4 +
 hw/isa/i82378.c |   4 +
 hw/isa/lpc_ich9.c   |   5 +-
 hw/isa/piix4.c  |   4 +
 hw/isa/vt82c686.c   |  16 +++
 hw/mips/gt64xxx_pci.c   |   4 +
 hw/misc/edu.c   |   5 +
 hw/misc/ivshmem.c   |   4 +
 hw/misc/macio/macio.c   |   4 +
 hw/misc/pci-testdev.c   |   4 +
 hw/misc/vmcoreinfo.c|  96 ++
 hw/net/e1000.c  |   4 +
 hw/net/e1000e.c |   4 +
 hw/net/eepro100.c   |   4 +
 hw/net/ne2000.c |   4 +
 hw/net/pcnet-pci.c  |   4 +
 hw/net/rocker/rocker.c  |   4 +
 hw/net/rtl8139.c|   4 +
 hw/net/sungem.c |   4 +
 hw/net/sunhme.c |   4 +
 

Re: [Qemu-devel] [PATCHv2 00/13] sun4m: sparc32_dma tidy-ups

2017-10-14 Thread no-reply
Hi,

This series failed build test on s390x host. Please find the details below.

Type: series
Message-id: 1508004545-28578-1-git-send-email-mark.cave-ayl...@ilande.co.uk
Subject: [Qemu-devel] [PATCHv2 00/13] sun4m: sparc32_dma tidy-ups

=== TEST SCRIPT BEGIN ===
#!/bin/bash
# Testing script will be invoked under the git checkout with
# HEAD pointing to a commit that has the patches applied on top of "base"
# branch
set -e
echo "=== ENV ==="
env
echo "=== PACKAGES ==="
rpm -qa
echo "=== TEST BEGIN ==="
CC=$HOME/bin/cc
INSTALL=$PWD/install
BUILD=$PWD/build
echo -n "Using CC: "
realpath $CC
mkdir -p $BUILD $INSTALL
SRC=$PWD
cd $BUILD
$SRC/configure --cc=$CC --prefix=$INSTALL
make -j4
# XXX: we need reliable clean up
# make check -j4 V=1
make install
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 - [tag update]  
patchew/1507816448-86665-1-git-send-email-pbonz...@redhat.com -> 
patchew/1507816448-86665-1-git-send-email-pbonz...@redhat.com
 - [tag update]  patchew/1507930220-17461-1-git-send-email-c...@braap.org 
-> patchew/1507930220-17461-1-git-send-email-c...@braap.org
 * [new tag] 
patchew/1508004545-28578-1-git-send-email-mark.cave-ayl...@ilande.co.uk -> 
patchew/1508004545-28578-1-git-send-email-mark.cave-ayl...@ilande.co.uk
 - [tag update]  patchew/20171013054842.32120-1...@weilnetz.de -> 
patchew/20171013054842.32120-1...@weilnetz.de
 - [tag update]  patchew/20171013162438.32458-1-alex.ben...@linaro.org -> 
patchew/20171013162438.32458-1-alex.ben...@linaro.org
Switched to a new branch 'test'
750844c sparc32_dma: add len to esp/le DMA memory tracing
ba7ab63 sparc32_dma: remove is_ledma hack and replace with memory region alias
cf74bfb sparc32_dma: introduce new SPARC32_DMA type container object
1a9feba sparc32_dma: make lance device child of ledma device
86b3305 lance: move TYPE_LANCE and SysBusPCNetState from lance.c to sun4m.h
c5ae1c6 sparc32_dma: make esp device child of espdma device
420993a esp: move TYPE_ESP and SysBusESPState from esp.c to esp.h
236dbd4 sparc32_dma: use object link instead of qdev property to pass IOMMU 
reference
5165f56 sun4m_iommu: move TYPE_SUN4M_IOMMU declaration to sun4m.h
850a150 sun4m: move DMA device wiring from sparc32_dma_init() to sun4m_hw_init()
4ba0c4c sparc32_dma: move type declarations from sparc32_dma.c to sparc32_dma.h
553bbce sparc32_dma: split esp and le into separate DMA devices
dd74a83 sparc32_dma: rename SPARC32_DMA type to SPARC32_DMA_DEVICE

=== OUTPUT BEGIN ===
=== ENV ===
XDG_SESSION_ID=45931
SHELL=/bin/sh
USER=fam
PATCHEW=/home/fam/patchew/patchew-cli -s http://patchew.org --nodebug
PATH=/usr/bin:/bin
PWD=/var/tmp/patchew-tester-tmp-0zvctjo5/src
LANG=en_US.UTF-8
HOME=/home/fam
SHLVL=2
LOGNAME=fam
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1012/bus
XDG_RUNTIME_DIR=/run/user/1012
_=/usr/bin/env
=== PACKAGES ===
gpg-pubkey-873529b8-54e386ff
xz-libs-5.2.2-2.fc24.s390x
libxshmfence-1.2-3.fc24.s390x
giflib-4.1.6-15.fc24.s390x
trousers-lib-0.3.13-6.fc24.s390x
ncurses-base-6.0-6.20160709.fc25.noarch
gmp-6.1.1-1.fc25.s390x
libidn-1.33-1.fc25.s390x
slang-2.3.0-7.fc25.s390x
pkgconfig-0.29.1-1.fc25.s390x
alsa-lib-1.1.1-2.fc25.s390x
yum-metadata-parser-1.1.4-17.fc25.s390x
python3-slip-dbus-0.6.4-4.fc25.noarch
python2-cssselect-0.9.2-1.fc25.noarch
createrepo_c-libs-0.10.0-6.fc25.s390x
initscripts-9.69-1.fc25.s390x
parted-3.2-21.fc25.s390x
flex-2.6.0-3.fc25.s390x
colord-libs-1.3.4-1.fc25.s390x
python-osbs-client-0.33-3.fc25.noarch
perl-Pod-Simple-3.35-1.fc25.noarch
python2-simplejson-3.10.0-1.fc25.s390x
brltty-5.4-2.fc25.s390x
librados2-10.2.4-2.fc25.s390x
tcp_wrappers-7.6-83.fc25.s390x
libcephfs_jni1-10.2.4-2.fc25.s390x
nettle-devel-3.3-1.fc25.s390x
bzip2-devel-1.0.6-21.fc25.s390x
libuuid-2.28.2-2.fc25.s390x
python3-dnf-1.1.10-6.fc25.noarch
texlive-kpathsea-doc-svn41139-33.fc25.1.noarch
openssh-7.4p1-4.fc25.s390x
texlive-kpathsea-bin-svn40473-33.20160520.fc25.1.s390x
texlive-graphics-svn41015-33.fc25.1.noarch
texlive-dvipdfmx-def-svn40328-33.fc25.1.noarch
texlive-mfware-svn40768-33.fc25.1.noarch
texlive-texlive-scripts-svn41433-33.fc25.1.noarch
texlive-euro-svn22191.1.1-33.fc25.1.noarch
texlive-etex-svn37057.0-33.fc25.1.noarch
texlive-iftex-svn29654.0.2-33.fc25.1.noarch
texlive-palatino-svn31835.0-33.fc25.1.noarch
texlive-texlive-docindex-svn41430-33.fc25.1.noarch
texlive-xunicode-svn30466.0.981-33.fc25.1.noarch
texlive-koma-script-svn41508-33.fc25.1.noarch
texlive-pst-grad-svn15878.1.06-33.fc25.1.noarch
texlive-pst-blur-svn15878.2.0-33.fc25.1.noarch
texlive-jknapltx-svn19440.0-33.fc25.1.noarch
texinfo-6.1-4.fc25.s390x
openssl-devel-1.0.2k-1.fc25.s390x
jansson-2.10-2.fc25.s390x
fedora-repos-25-4.noarch
perl-Errno-1.25-387.fc25.s390x
acl-2.2.52-13.fc25.s390x
systemd-pam-231-17.fc25.s390x
NetworkManager-libnm-1.4.4-5.fc25.s390x
poppler-0.45.0-5.fc25.s390x
ccache-3.3.4-1.fc25.s390x
valgrind-3.12.0-9.fc25.s390x
perl-open-1.10-387.fc25.noarch
libgcc-6.4.1-1.fc25.s390x

Re: [Qemu-devel] [PATCH v6 2/7] hw/misc: add vmcoreinfo device

2017-10-14 Thread Michael S. Tsirkin
On Tue, Oct 10, 2017 at 03:01:10PM -0300, Eduardo Habkost wrote:
> On Tue, Oct 10, 2017 at 04:06:28PM +0100, Daniel P. Berrange wrote:
> > On Tue, Oct 10, 2017 at 05:00:18PM +0200, Marc-André Lureau wrote:
> > > Hi
> > > 
> > > On Tue, Oct 10, 2017 at 10:31 AM, Daniel P. Berrange
> > >  wrote:
> > > > On Tue, Oct 10, 2017 at 12:44:26AM +0300, Michael S. Tsirkin wrote:
> > > >> On Mon, Oct 09, 2017 at 02:02:18PM +0100, Daniel P. Berrange wrote:
> > > >> > On Mon, Oct 09, 2017 at 02:43:44PM +0200, Igor Mammedov wrote:
> > > >> > > On Mon, 9 Oct 2017 12:03:36 +0100
> > > >> > > "Daniel P. Berrange"  wrote:
> > > >> > >
> > > >> > > > On Mon, Sep 11, 2017 at 06:59:24PM +0200, Marc-André Lureau 
> > > >> > > > wrote:
> > > >> > > > > See docs/specs/vmcoreinfo.txt for details.
> > > >> > > > >
> > > >> > > > > "etc/vmcoreinfo" fw_cfg entry is added when using "-device 
> > > >> > > > > vmcoreinfo".
> > > >> > > >
> > > >> > > > I'm wondering if you considered just adding the entry to fw_cfg 
> > > >> > > > by
> > > >> > > > default, without requiring any -device arg ? Unless I'm 
> > > >> > > > misunderstanding,
> > > >> > > > this doesn't feel like a device to me - its just a well known 
> > > >> > > > bucket
> > > >> > > > in fw_cfg IIUC ?  Obviously its existance would need to be tied 
> > > >> > > > to
> > > >> > > > the latest machine type for ABI reasons though. The benefit of 
> > > >> > > > this
> > > >> > > > is that it would "just work" without us having to plumb it 
> > > >> > > > through to
> > > >> > > > all the downstream applications that use QEMU for mgmt guest 
> > > >> > > > (OpenStack,
> > > >> > > > oVirt, GNOME Boxes, virt-manager, and countless other mgmt apps).
> > > >> > > it follows model set by pvpanic device, it's easier to manage from 
> > > >> > > migration
> > > >> > > POV, one could use it even for old machine types with new qemu 
> > > >> > > (just by adding
> > > >> > > device, it makes instance not backwards migratable to old qemu but 
> > > >> > > should work
> > > >> > > for forward migration) and if user doesn't need it, device could 
> > > >> > > be just omitted
> > > >> > > from CLI.
> > > >> >
> > > >> > Sure but it means that in effect no one will have this functionality 
> > > >> > enabled
> > > >> > for several years. pvpanic has been around a long time and I rarely 
> > > >> > see it
> > > >> > present in configured guests :-(
> > > >> >
> > > >> >
> > > >> > Regards,
> > > >> > Daniel
> > > >>
> > > >> libvirt runs with -nodefaults, right? I'd argue pretty strongly 
> > > >> -nodefaults
> > > >> shouldn't add optional devices anyway.
> > > >
> > > > This isn't really adding a device though is it - it is just a well known
> > > > location in fw_cfg to receive data.
> > > 
> > > Enabling the device on some configurations by default can be done as a
> > > follow-up patch. Can we get this series reviewed & merged?
> > 
> > The problem with the -device approach + turning it on by default is that 
> > there
> > is no way to turn it off again if you don't want it. eg there's way to undo
> > an implicit '-device foo' except via -nodefaults, but since libvirt uses 
> > that
> > already it would negate the effect of enabling it by default 
> > unconditionally.
> 
> It's still possible to add a -machine option that can
> enable/disable automatic creation of the device.
>
>
> But I also don't see why it needs to be implemented using -device
> if it's not really a device.  A boolean machine or fw_cfg
> property is good enough for that.

Device imho is a combination of guest/host interface and state.


> > 
> > Your previous approach of "-global fw_cfg.vmcoreinfo=on" is nicer in this
> > respect, as you can trivially turn it on/off, overriding the default state
> > in both directions.
> 
> Both "-global fw_cfg.vmcoreinfo=on|off" and
> "-machine vmcoreinfo=on|off" sound good enough to me.

I can live with the second option if people really want it.
I'd like to see some way to add these things without
adding to the mess that is the pc initialization
but oh well.

> -- 
> Eduardo



Re: [Qemu-devel] [PATCH v6 2/7] hw/misc: add vmcoreinfo device

2017-10-14 Thread Michael S. Tsirkin
On Tue, Oct 10, 2017 at 03:01:10PM -0300, Eduardo Habkost wrote:
> On Tue, Oct 10, 2017 at 04:06:28PM +0100, Daniel P. Berrange wrote:
> > On Tue, Oct 10, 2017 at 05:00:18PM +0200, Marc-André Lureau wrote:
> > > Hi
> > > 
> > > On Tue, Oct 10, 2017 at 10:31 AM, Daniel P. Berrange
> > >  wrote:
> > > > On Tue, Oct 10, 2017 at 12:44:26AM +0300, Michael S. Tsirkin wrote:
> > > >> On Mon, Oct 09, 2017 at 02:02:18PM +0100, Daniel P. Berrange wrote:
> > > >> > On Mon, Oct 09, 2017 at 02:43:44PM +0200, Igor Mammedov wrote:
> > > >> > > On Mon, 9 Oct 2017 12:03:36 +0100
> > > >> > > "Daniel P. Berrange"  wrote:
> > > >> > >
> > > >> > > > On Mon, Sep 11, 2017 at 06:59:24PM +0200, Marc-André Lureau 
> > > >> > > > wrote:
> > > >> > > > > See docs/specs/vmcoreinfo.txt for details.
> > > >> > > > >
> > > >> > > > > "etc/vmcoreinfo" fw_cfg entry is added when using "-device 
> > > >> > > > > vmcoreinfo".
> > > >> > > >
> > > >> > > > I'm wondering if you considered just adding the entry to fw_cfg 
> > > >> > > > by
> > > >> > > > default, without requiring any -device arg ? Unless I'm 
> > > >> > > > misunderstanding,
> > > >> > > > this doesn't feel like a device to me - its just a well known 
> > > >> > > > bucket
> > > >> > > > in fw_cfg IIUC ?  Obviously its existance would need to be tied 
> > > >> > > > to
> > > >> > > > the latest machine type for ABI reasons though. The benefit of 
> > > >> > > > this
> > > >> > > > is that it would "just work" without us having to plumb it 
> > > >> > > > through to
> > > >> > > > all the downstream applications that use QEMU for mgmt guest 
> > > >> > > > (OpenStack,
> > > >> > > > oVirt, GNOME Boxes, virt-manager, and countless other mgmt apps).
> > > >> > > it follows model set by pvpanic device, it's easier to manage from 
> > > >> > > migration
> > > >> > > POV, one could use it even for old machine types with new qemu 
> > > >> > > (just by adding
> > > >> > > device, it makes instance not backwards migratable to old qemu but 
> > > >> > > should work
> > > >> > > for forward migration) and if user doesn't need it, device could 
> > > >> > > be just omitted
> > > >> > > from CLI.
> > > >> >
> > > >> > Sure but it means that in effect no one will have this functionality 
> > > >> > enabled
> > > >> > for several years. pvpanic has been around a long time and I rarely 
> > > >> > see it
> > > >> > present in configured guests :-(
> > > >> >
> > > >> >
> > > >> > Regards,
> > > >> > Daniel
> > > >>
> > > >> libvirt runs with -nodefaults, right? I'd argue pretty strongly 
> > > >> -nodefaults
> > > >> shouldn't add optional devices anyway.
> > > >
> > > > This isn't really adding a device though is it - it is just a well known
> > > > location in fw_cfg to receive data.
> > > 
> > > Enabling the device on some configurations by default can be done as a
> > > follow-up patch. Can we get this series reviewed & merged?
> > 
> > The problem with the -device approach + turning it on by default is that 
> > there
> > is no way to turn it off again if you don't want it. eg there's way to undo
> > an implicit '-device foo' except via -nodefaults, but since libvirt uses 
> > that
> > already it would negate the effect of enabling it by default 
> > unconditionally.
> 
> It's still possible to add a -machine option that can
> enable/disable automatic creation of the device.
> 
> But I also don't see why it needs to be implemented using -device
> if it's not really a device.  A boolean machine or fw_cfg
> property is good enough for that.

It certainly feels like a device. It has state
(that needs to be migrated), it has a host/guest interface.


> > 
> > Your previous approach of "-global fw_cfg.vmcoreinfo=on" is nicer in this
> > respect, as you can trivially turn it on/off, overriding the default state
> > in both directions.
> 
> Both "-global fw_cfg.vmcoreinfo=on|off" and
> "-machine vmcoreinfo=on|off" sound good enough to me.


Certainly not a fw cfg flag. Can be a machine flag I guess
but then we'd have to open-code each such device.
And don't forget auto - this is what Daniel asks for.

I don't necessarily see this device as so special and think a generic
interface to control what goes into the machine would be better (e.g.
look how you use hacky -global to control fw cfg options, it only works
if there's a single one), but if everyone thinks otherwise and agrees we
should have it in there by default, and a property to disable, fine.

Can be a patch on top though.


> -- 
> Eduardo



Re: [Qemu-devel] [PATCH] spapr_cpu_core: instantiate CPUs separately

2017-10-14 Thread David Gibson
On Fri, Oct 13, 2017 at 01:31:44PM +0200, Greg Kurz wrote:
> The current code assumes that only the CPU core object holds a
> reference on each individual CPU object, and happily frees their
> allocated memory when the core is unrealized. This is dangerous
> as some other code can legitimely keep a pointer to a CPU if it
> calls object_ref(), but it would end up with a dangling pointer.
> 
> Let's allocate all CPUs with object_new() and let QOM frees them
> when their reference count reaches zero. This greatly simplify the
> code as we don't have to fiddle with the instance size anymore.
> 
> Signed-off-by: Greg Kurz 

So, I'm pretty sure my first drafts of the core stuff did things this
waym and it got nacked, for QOM lifetime reasons that I never really
understood.

> ---
> v2: - mention code simplification in changelog
> - use PowerPCCPU * and Object * instead of void *
> ---
>  hw/ppc/spapr.c  |   11 +++
>  hw/ppc/spapr_cpu_core.c |   19 +++
>  include/hw/ppc/spapr_cpu_core.h |2 +-
>  3 files changed, 11 insertions(+), 21 deletions(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index fd9813bde82f..d9555a3677be 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -3153,12 +3153,10 @@ void spapr_core_release(DeviceState *dev)
>  
>  if (smc->pre_2_10_has_unused_icps) {
>  sPAPRCPUCore *sc = SPAPR_CPU_CORE(OBJECT(dev));
> -sPAPRCPUCoreClass *scc = SPAPR_CPU_CORE_GET_CLASS(OBJECT(cc));
> -size_t size = object_type_get_instance_size(scc->cpu_type);
>  int i;
>  
>  for (i = 0; i < cc->nr_threads; i++) {
> -CPUState *cs = CPU(sc->threads + i * size);
> +CPUState *cs = CPU(sc->threads[i]);
>  
>  pre_2_10_vmstate_register_dummy_icp(cs->cpu_index);
>  }
> @@ -3204,7 +3202,7 @@ static void spapr_core_plug(HotplugHandler 
> *hotplug_dev, DeviceState *dev,
>  sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
>  sPAPRCPUCore *core = SPAPR_CPU_CORE(OBJECT(dev));
>  CPUCore *cc = CPU_CORE(dev);
> -CPUState *cs = CPU(core->threads);
> +CPUState *cs = CPU(core->threads[0]);
>  sPAPRDRConnector *drc;
>  Error *local_err = NULL;
>  int smt = kvmppc_smt_threads();
> @@ -3249,15 +3247,12 @@ static void spapr_core_plug(HotplugHandler 
> *hotplug_dev, DeviceState *dev,
>  core_slot->cpu = OBJECT(dev);
>  
>  if (smc->pre_2_10_has_unused_icps) {
> -sPAPRCPUCoreClass *scc = SPAPR_CPU_CORE_GET_CLASS(OBJECT(cc));
> -size_t size = object_type_get_instance_size(scc->cpu_type);
>  int i;
>  
>  for (i = 0; i < cc->nr_threads; i++) {
>  sPAPRCPUCore *sc = SPAPR_CPU_CORE(dev);
> -void *obj = sc->threads + i * size;
>  
> -cs = CPU(obj);
> +cs = CPU(sc->threads[i]);
>  pre_2_10_vmstate_unregister_dummy_icp(cs->cpu_index);
>  }
>  }
> diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
> index 3a4c17401226..588f9b45714a 100644
> --- a/hw/ppc/spapr_cpu_core.c
> +++ b/hw/ppc/spapr_cpu_core.c
> @@ -79,13 +79,11 @@ const char *spapr_get_cpu_core_type(const char *cpu_type)
>  static void spapr_cpu_core_unrealizefn(DeviceState *dev, Error **errp)
>  {
>  sPAPRCPUCore *sc = SPAPR_CPU_CORE(OBJECT(dev));
> -sPAPRCPUCoreClass *scc = SPAPR_CPU_CORE_GET_CLASS(OBJECT(dev));
> -size_t size = object_type_get_instance_size(scc->cpu_type);
>  CPUCore *cc = CPU_CORE(dev);
>  int i;
>  
>  for (i = 0; i < cc->nr_threads; i++) {
> -void *obj = sc->threads + i * size;
> +Object *obj = OBJECT(sc->threads[i]);
>  DeviceState *dev = DEVICE(obj);
>  CPUState *cs = CPU(dev);
>  PowerPCCPU *cpu = POWERPC_CPU(cs);
> @@ -146,9 +144,8 @@ static void spapr_cpu_core_realize(DeviceState *dev, 
> Error **errp)
>  sPAPRCPUCore *sc = SPAPR_CPU_CORE(OBJECT(dev));
>  sPAPRCPUCoreClass *scc = SPAPR_CPU_CORE_GET_CLASS(OBJECT(dev));
>  CPUCore *cc = CPU_CORE(OBJECT(dev));
> -size_t size;
>  Error *local_err = NULL;
> -void *obj;
> +Object *obj;
>  int i, j;
>  
>  if (!spapr) {
> @@ -156,18 +153,16 @@ static void spapr_cpu_core_realize(DeviceState *dev, 
> Error **errp)
>  return;
>  }
>  
> -size = object_type_get_instance_size(scc->cpu_type);
> -sc->threads = g_malloc0(size * cc->nr_threads);
> +sc->threads = g_new(PowerPCCPU *, cc->nr_threads);
>  for (i = 0; i < cc->nr_threads; i++) {
>  char id[32];
>  CPUState *cs;
>  PowerPCCPU *cpu;
>  
> -obj = sc->threads + i * size;
> +obj = object_new(scc->cpu_type);
>  
> -object_initialize(obj, size, scc->cpu_type);
>  cs = CPU(obj);
> -cpu = POWERPC_CPU(cs);
> +cpu = sc->threads[i] = POWERPC_CPU(obj);
>  cs->cpu_index = cc->core_id + i;
>  cpu->vcpu_id = (cc->core_id * spapr->vsmt / 

[Qemu-devel] [PATCH v4 7/8] nbd/client: prepare nbd_receive_reply for structured reply

2017-10-14 Thread Eric Blake
From: Vladimir Sementsov-Ogievskiy 

In following patch nbd_receive_reply will be used both for simple
and structured reply header receiving.
NBDReply is altered into union of simple reply header and structured
reply chunk header, simple error translation moved to block/nbd-client
to be consistent with further structured reply error translation.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Signed-off-by: Eric Blake 
---
 include/block/nbd.h |  30 ---
 block/nbd-client.c  |   8 ++--
 nbd/client.c| 104 +---
 nbd/trace-events|   3 +-
 4 files changed, 113 insertions(+), 32 deletions(-)

diff --git a/include/block/nbd.h b/include/block/nbd.h
index 225e9575e4..2ee1578420 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -57,12 +57,6 @@ struct NBDRequest {
 };
 typedef struct NBDRequest NBDRequest;

-struct NBDReply {
-uint64_t handle;
-uint32_t error;
-};
-typedef struct NBDReply NBDReply;
-
 typedef struct NBDSimpleReply {
 uint32_t magic;  /* NBD_SIMPLE_REPLY_MAGIC */
 uint32_t error;
@@ -78,6 +72,20 @@ typedef struct NBDStructuredReplyChunk {
 uint32_t length; /* length of payload */
 } QEMU_PACKED NBDStructuredReplyChunk;

+typedef union NBDReply {
+NBDSimpleReply simple;
+NBDStructuredReplyChunk structured;
+struct {
+/* @magic and @handle fields have the same offset and size both in
+ * simple reply and structured reply chunk, so let them be accessible
+ * without ".simple." or ".structured." specification
+ */
+uint32_t magic;
+uint32_t _skip;
+uint64_t handle;
+} QEMU_PACKED;
+} NBDReply;
+
 /* Header of NBD_REPLY_TYPE_OFFSET_DATA, complete NBD_REPLY_TYPE_OFFSET_HOLE */
 typedef struct NBDStructuredRead {
 NBDStructuredReplyChunk h;
@@ -256,4 +264,14 @@ void nbd_client_put(NBDClient *client);
 void nbd_server_start(SocketAddress *addr, const char *tls_creds,
   Error **errp);

+static inline bool nbd_reply_is_simple(NBDReply *reply)
+{
+return reply->magic == NBD_SIMPLE_REPLY_MAGIC;
+}
+
+static inline bool nbd_reply_is_structured(NBDReply *reply)
+{
+return reply->magic == NBD_STRUCTURED_REPLY_MAGIC;
+}
+
 #endif
diff --git a/block/nbd-client.c b/block/nbd-client.c
index c0683c3c83..58493b7ac4 100644
--- a/block/nbd-client.c
+++ b/block/nbd-client.c
@@ -92,7 +92,9 @@ static coroutine_fn void nbd_read_reply_entry(void *opaque)
 i = HANDLE_TO_INDEX(s, s->reply.handle);
 if (i >= MAX_NBD_REQUESTS ||
 !s->requests[i].coroutine ||
-!s->requests[i].receiving) {
+!s->requests[i].receiving ||
+nbd_reply_is_structured(>reply))
+{
 break;
 }

@@ -194,8 +196,8 @@ static int nbd_co_receive_reply(NBDClientSession *s,
 ret = -EIO;
 } else {
 assert(s->reply.handle == handle);
-ret = -s->reply.error;
-if (qiov && s->reply.error == 0) {
+ret = -nbd_errno_to_system_errno(s->reply.simple.error);
+if (qiov && ret == 0) {
 if (qio_channel_readv_all(s->ioc, qiov->iov, qiov->niov,
   NULL) < 0) {
 ret = -EIO;
diff --git a/nbd/client.c b/nbd/client.c
index 9d335fcaba..eeb23ae934 100644
--- a/nbd/client.c
+++ b/nbd/client.c
@@ -907,6 +907,57 @@ int nbd_send_request(QIOChannel *ioc, NBDRequest *request)
 return nbd_write(ioc, buf, sizeof(buf), NULL);
 }

+/* nbd_receive_simple_reply
+ * Read simple reply except magic field (which should be already read).
+ * Payload is not read (payload is possible for CMD_READ, but here we even
+ * don't know whether it take place or not).
+ */
+static int nbd_receive_simple_reply(QIOChannel *ioc, NBDSimpleReply *reply,
+Error **errp)
+{
+int ret;
+
+assert(reply->magic == NBD_SIMPLE_REPLY_MAGIC);
+
+ret = nbd_read(ioc, (uint8_t *)reply + sizeof(reply->magic),
+   sizeof(*reply) - sizeof(reply->magic), errp);
+if (ret < 0) {
+return ret;
+}
+
+be32_to_cpus(>error);
+be64_to_cpus(>handle);
+
+return 0;
+}
+
+/* nbd_receive_structured_reply_chunk
+ * Read structured reply chunk except magic field (which should be already
+ * read).
+ * Payload is not read.
+ */
+static int nbd_receive_structured_reply_chunk(QIOChannel *ioc,
+  NBDStructuredReplyChunk *chunk,
+  Error **errp)
+{
+int ret;
+
+assert(chunk->magic == NBD_STRUCTURED_REPLY_MAGIC);
+
+ret = nbd_read(ioc, (uint8_t *)chunk + sizeof(chunk->magic),
+   sizeof(*chunk) - sizeof(chunk->magic), errp);
+if (ret < 0) {
+return ret;
+}
+
+be16_to_cpus(>flags);
+be16_to_cpus(>type);
+be64_to_cpus(>handle);
+

[Qemu-devel] [PATCH v4 6/8] nbd/client: refactor nbd_receive_starttls

2017-10-14 Thread Eric Blake
From: Vladimir Sementsov-Ogievskiy 

Split out nbd_request_simple_option to be reused for structured reply
option.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Signed-off-by: Eric Blake 

---
v4: reduce redundant traces, typo fix in commit message
---
 nbd/client.c | 69 ++--
 nbd/trace-events |  4 +---
 2 files changed, 48 insertions(+), 25 deletions(-)

diff --git a/nbd/client.c b/nbd/client.c
index 50f36b511e..9d335fcaba 100644
--- a/nbd/client.c
+++ b/nbd/client.c
@@ -508,35 +508,60 @@ static int nbd_receive_query_exports(QIOChannel *ioc,
 }
 }

+/* nbd_request_simple_option: Send an option request, and parse the reply
+ * return 1 for successful negotiation,
+ *0 if operation is unsupported,
+ *-1 with errp set for any other error
+ */
+static int nbd_request_simple_option(QIOChannel *ioc, int opt, Error **errp)
+{
+nbd_opt_reply reply;
+
+if (nbd_send_option_request(ioc, opt, 0, NULL, errp) < 0) {
+return -1;
+}
+
+if (nbd_receive_option_reply(ioc, opt, , errp) < 0) {
+return -1;
+}
+
+if (reply.length != 0) {
+error_setg(errp, "Option %d ('%s') response length is %" PRIu32
+   " (it should be zero)", opt, nbd_opt_lookup(opt),
+   reply.length);
+nbd_send_opt_abort(ioc);
+return -1;
+}
+
+if (reply.type == NBD_REP_ERR_UNSUP) {
+return 0;
+}
+
+if (reply.type != NBD_REP_ACK) {
+error_setg(errp, "Server rejected request for option %d (%s) "
+   "with reply %" PRIx32 " (%s)", opt, nbd_opt_lookup(opt),
+   reply.type, nbd_rep_lookup(reply.type));
+nbd_send_opt_abort(ioc);
+return -1;
+}
+
+return 1;
+}
+
 static QIOChannel *nbd_receive_starttls(QIOChannel *ioc,
 QCryptoTLSCreds *tlscreds,
 const char *hostname, Error **errp)
 {
-nbd_opt_reply reply;
+int ret;
 QIOChannelTLS *tioc;
 struct NBDTLSHandshakeData data = { 0 };

-trace_nbd_receive_starttls_request();
-if (nbd_send_option_request(ioc, NBD_OPT_STARTTLS, 0, NULL, errp) < 0) {
-return NULL;
-}
-
-trace_nbd_receive_starttls_reply();
-if (nbd_receive_option_reply(ioc, NBD_OPT_STARTTLS, , errp) < 0) {
-return NULL;
-}
-
-if (reply.type != NBD_REP_ACK) {
-error_setg(errp, "Server rejected request to start TLS %" PRIx32,
-   reply.type);
-nbd_send_opt_abort(ioc);
-return NULL;
-}
-
-if (reply.length != 0) {
-error_setg(errp, "Start TLS response was not zero %" PRIu32,
-   reply.length);
-nbd_send_opt_abort(ioc);
+ret = nbd_request_simple_option(ioc, NBD_OPT_STARTTLS, errp);
+if (ret <= 0) {
+if (ret == 0) {
+error_setg(errp, "Server don't support STARTTLS option");
+nbd_send_opt_abort(ioc);
+}
 return NULL;
 }

diff --git a/nbd/trace-events b/nbd/trace-events
index 880f211c07..39b723d1d8 100644
--- a/nbd/trace-events
+++ b/nbd/trace-events
@@ -8,9 +8,7 @@ nbd_opt_go_info_unknown(int info, const char *name) "Ignoring 
unknown info %d (%
 nbd_opt_go_info_block_size(uint32_t minimum, uint32_t preferred, uint32_t 
maximum) "Block sizes are 0x%" PRIx32 ", 0x%" PRIx32 ", 0x%" PRIx32
 nbd_receive_query_exports_start(const char *wantname) "Querying export list 
for '%s'"
 nbd_receive_query_exports_success(const char *wantname) "Found desired export 
name '%s'"
-nbd_receive_starttls_request(void) "Requesting TLS from server"
-nbd_receive_starttls_reply(void) "Getting TLS reply from server"
-nbd_receive_starttls_new_client(void) "TLS request approved, setting up TLS"
+nbd_receive_starttls_new_client(void) "Setting up TLS"
 nbd_receive_starttls_tls_handshake(void) "Starting TLS handshake"
 nbd_receive_negotiate(void *tlscreds, const char *hostname) "Receiving 
negotiation tlscreds=%p hostname=%s"
 nbd_receive_negotiate_magic(uint64_t magic) "Magic is 0x%" PRIx64
-- 
2.13.6




[Qemu-devel] [PATCH v4 4/8] nbd: Minimal structured read for server

2017-10-14 Thread Eric Blake
From: Vladimir Sementsov-Ogievskiy 

Minimal implementation of structured read: one structured reply chunk,
no segmentation.
Minimal structured error implementation: no text message.
Support DF flag, but just ignore it, as there is no segmentation any
way.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Signed-off-by: Eric Blake 

---
v4: better _DF flag handling, convert errno to wire format, add
comments and tracing, rework structured error for less churn when adding
text message later, don't kill connection on redundant client option
---
 nbd/server.c | 106 +--
 nbd/trace-events |   2 ++
 2 files changed, 98 insertions(+), 10 deletions(-)

diff --git a/nbd/server.c b/nbd/server.c
index efb6003364..23dc6be708 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -100,6 +100,8 @@ struct NBDClient {
 QTAILQ_ENTRY(NBDClient) next;
 int nb_requests;
 bool closing;
+
+bool structured_reply;
 };

 /* That's all folks */
@@ -762,6 +764,23 @@ static int nbd_negotiate_options(NBDClient *client, 
uint16_t myflags,
 return ret;
 }
 break;
+
+case NBD_OPT_STRUCTURED_REPLY:
+if (client->structured_reply) {
+ret = nbd_negotiate_send_rep_err(
+client->ioc, NBD_REP_ERR_INVALID, option, errp,
+"structured reply already negotiated");
+} else {
+ret = nbd_negotiate_send_rep(client->ioc, NBD_REP_ACK,
+ option, errp);
+}
+if (ret < 0) {
+return ret;
+}
+client->structured_reply = true;
+myflags |= NBD_CMD_FLAG_DF;
+break;
+
 default:
 if (nbd_drop(client->ioc, length, errp) < 0) {
 return -EIO;
@@ -1236,6 +1255,59 @@ static int nbd_co_send_simple_reply(NBDClient *client,
 return nbd_co_send_iov(client, iov, len ? 2 : 1, errp);
 }

+static inline void set_be_chunk(NBDStructuredReplyChunk *chunk, uint16_t flags,
+uint16_t type, uint64_t handle, uint32_t 
length)
+{
+stl_be_p(>magic, NBD_STRUCTURED_REPLY_MAGIC);
+stw_be_p(>flags, flags);
+stw_be_p(>type, type);
+stq_be_p(>handle, handle);
+stl_be_p(>length, length);
+}
+
+static int coroutine_fn nbd_co_send_structured_read(NBDClient *client,
+uint64_t handle,
+uint64_t offset,
+void *data,
+size_t size,
+Error **errp)
+{
+NBDStructuredRead chunk;
+struct iovec iov[] = {
+{.iov_base = , .iov_len = sizeof(chunk)},
+{.iov_base = data, .iov_len = size}
+};
+
+trace_nbd_co_send_structured_read(handle, offset, data, size);
+set_be_chunk(, NBD_REPLY_FLAG_DONE, NBD_REPLY_TYPE_OFFSET_DATA,
+ handle, sizeof(chunk) - sizeof(chunk.h) + size);
+stq_be_p(, offset);
+
+return nbd_co_send_iov(client, iov, 2, errp);
+}
+
+static int coroutine_fn nbd_co_send_structured_error(NBDClient *client,
+ uint64_t handle,
+ uint32_t error,
+ Error **errp)
+{
+NBDStructuredError chunk;
+int nbd_err = system_errno_to_nbd_errno(error);
+struct iovec iov[] = {
+{.iov_base = , .iov_len = sizeof(chunk)},
+/* FIXME: Support human-readable error message */
+};
+
+assert(nbd_err);
+trace_nbd_co_send_structured_error(handle, nbd_err);
+set_be_chunk(, NBD_REPLY_FLAG_DONE, NBD_REPLY_TYPE_ERROR, handle,
+ sizeof(chunk) - sizeof(chunk.h));
+stl_be_p(, nbd_err);
+stw_be_p(_length, 0);
+
+return nbd_co_send_iov(client, iov, 1, errp);
+}
+
 /* nbd_co_receive_request
  * Collect a client request. Return 0 if request looks valid, -EIO to drop
  * connection right away, and any other negative value to report an error to
@@ -1246,6 +1318,7 @@ static int nbd_co_receive_request(NBDRequestData *req, 
NBDRequest *request,
   Error **errp)
 {
 NBDClient *client = req->client;
+int valid_flags;

 g_assert(qemu_in_coroutine());
 assert(client->recv_coroutine == qemu_coroutine_self());
@@ -1307,13 +1380,15 @@ static int nbd_co_receive_request(NBDRequestData *req, 
NBDRequest *request,
(uint64_t)client->exp->size);
 return request->type == NBD_CMD_WRITE ? -ENOSPC : -EINVAL;
 }
-if (request->flags & ~(NBD_CMD_FLAG_FUA | 

[Qemu-devel] [PATCH v4 3/8] nbd: Expose constants and structs for structured read

2017-10-14 Thread Eric Blake
Upcoming patches will implement the NBD structured reply
extension [1] for both client and server roles.  Declare the
constants, structs, and lookup routines that will be valuable
whether the server or client code is backported in isolation.

This includes moving one constant from an internal header to
the public header, as part of the structured read processing
will be done in block/nbd-client.c rather than nbd/client.c.

[1]https://github.com/NetworkBlockDevice/nbd/blob/extension-structured-reply/doc/proto.md

Based on patches from Vladimir Sementsov-Ogievskiy.

Signed-off-by: Eric Blake 
---
 include/block/nbd.h | 41 +
 nbd/nbd-internal.h  |  2 +-
 nbd/common.c| 27 +++
 nbd/server.c|  2 ++
 4 files changed, 71 insertions(+), 1 deletion(-)

diff --git a/include/block/nbd.h b/include/block/nbd.h
index dc62b5cd19..225e9575e4 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -69,6 +69,28 @@ typedef struct NBDSimpleReply {
 uint64_t handle;
 } QEMU_PACKED NBDSimpleReply;

+/* Header of all structured replies */
+typedef struct NBDStructuredReplyChunk {
+uint32_t magic;  /* NBD_STRUCTURED_REPLY_MAGIC */
+uint16_t flags;  /* combination of NBD_REPLY_FLAG_* */
+uint16_t type;   /* NBD_REPLY_TYPE_* */
+uint64_t handle; /* request handle */
+uint32_t length; /* length of payload */
+} QEMU_PACKED NBDStructuredReplyChunk;
+
+/* Header of NBD_REPLY_TYPE_OFFSET_DATA, complete NBD_REPLY_TYPE_OFFSET_HOLE */
+typedef struct NBDStructuredRead {
+NBDStructuredReplyChunk h;
+uint64_t offset;
+} QEMU_PACKED NBDStructuredRead;
+
+/* Header of all NBD_REPLY_TYPE_ERROR* errors */
+typedef struct NBDStructuredError {
+NBDStructuredReplyChunk h;
+uint32_t error;
+uint16_t message_length;
+} QEMU_PACKED NBDStructuredError;
+
 /* Transmission (export) flags: sent from server to client during handshake,
but describe what will happen during transmission */
 #define NBD_FLAG_HAS_FLAGS (1 << 0) /* Flags are there */
@@ -79,6 +101,7 @@ typedef struct NBDSimpleReply {
rotational media */
 #define NBD_FLAG_SEND_TRIM (1 << 5) /* Send TRIM (discard) */
 #define NBD_FLAG_SEND_WRITE_ZEROES (1 << 6) /* Send WRITE_ZEROES */
+#define NBD_FLAG_SEND_DF   (1 << 7) /* Send DF (Do not Fragment) */

 /* New-style handshake (global) flags, sent from server to client, and
control what will happen during handshake phase. */
@@ -125,6 +148,7 @@ typedef struct NBDSimpleReply {
 /* Request flags, sent from client to server during transmission phase */
 #define NBD_CMD_FLAG_FUA(1 << 0) /* 'force unit access' during write */
 #define NBD_CMD_FLAG_NO_HOLE(1 << 1) /* don't punch hole on zero run */
+#define NBD_CMD_FLAG_DF (1 << 2) /* don't fragment structured read */

 /* Supported request types */
 enum {
@@ -149,6 +173,22 @@ enum {
  * aren't overflowing some other buffer. */
 #define NBD_MAX_NAME_SIZE 256

+/* Two types of reply structures */
+#define NBD_SIMPLE_REPLY_MAGIC  0x67446698
+#define NBD_STRUCTURED_REPLY_MAGIC  0x668e33ef
+
+/* Structured reply flags */
+#define NBD_REPLY_FLAG_DONE  (1 << 0) /* This reply-chunk is last */
+
+/* Structured reply types */
+#define NBD_REPLY_ERR(value) ((1 << 15) | (value))
+
+#define NBD_REPLY_TYPE_NONE  0
+#define NBD_REPLY_TYPE_OFFSET_DATA   1
+#define NBD_REPLY_TYPE_OFFSET_HOLE   2
+#define NBD_REPLY_TYPE_ERROR NBD_REPLY_ERR(1)
+#define NBD_REPLY_TYPE_ERROR_OFFSET  NBD_REPLY_ERR(2)
+
 /* NBD errors are based on errno numbers, so there is a 1:1 mapping,
  * but only a limited set of errno values is specified in the protocol.
  * Everything else is squashed to EINVAL.
@@ -159,6 +199,7 @@ enum {
 #define NBD_ENOMEM 12
 #define NBD_EINVAL 22
 #define NBD_ENOSPC 28
+#define NBD_EOVERFLOW  75
 #define NBD_ESHUTDOWN  108

 /* Details collected by NBD_OPT_EXPORT_NAME and NBD_OPT_GO */
diff --git a/nbd/nbd-internal.h b/nbd/nbd-internal.h
index df6c8b2f24..4f24d6e57d 100644
--- a/nbd/nbd-internal.h
+++ b/nbd/nbd-internal.h
@@ -47,7 +47,6 @@
 #define NBD_OLDSTYLE_NEGOTIATE_SIZE (8 + 8 + 8 + 4 + 124)

 #define NBD_REQUEST_MAGIC   0x25609513
-#define NBD_SIMPLE_REPLY_MAGIC  0x67446698
 #define NBD_OPTS_MAGIC  0x49484156454F5054LL
 #define NBD_CLIENT_MAGIC0x420281861253LL
 #define NBD_REP_MAGIC   0x0003e889045565a9LL
@@ -114,6 +113,7 @@ const char *nbd_opt_lookup(uint32_t opt);
 const char *nbd_rep_lookup(uint32_t rep);
 const char *nbd_info_lookup(uint16_t info);
 const char *nbd_cmd_lookup(uint16_t info);
+const char *nbd_reply_type_lookup(uint16_t type);
 const char *nbd_err_lookup(int err);

 int nbd_drop(QIOChannel *ioc, size_t size, Error **errp);
diff --git a/nbd/common.c b/nbd/common.c
index 593904f148..6047d71748 100644
--- a/nbd/common.c
+++ b/nbd/common.c
@@ 

[Qemu-devel] [PATCH v4 8/8] nbd: Move nbd_read() to common header

2017-10-14 Thread Eric Blake
An upcoming change to block/nbd-client.c will want to read the
tail of a structured reply chunk directly from the wire.  Move
this function to make it easier.

Based on a patch from Vladimir Sementsov-Ogievskiy.

Signed-off-by: Eric Blake 
---
 include/block/nbd.h | 10 ++
 nbd/nbd-internal.h  |  9 -
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/include/block/nbd.h b/include/block/nbd.h
index 2ee1578420..da6e305dd5 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -264,6 +264,16 @@ void nbd_client_put(NBDClient *client);
 void nbd_server_start(SocketAddress *addr, const char *tls_creds,
   Error **errp);

+
+/* nbd_read
+ * Reads @size bytes from @ioc. Returns 0 on success.
+ */
+static inline int nbd_read(QIOChannel *ioc, void *buffer, size_t size,
+   Error **errp)
+{
+return qio_channel_read_all(ioc, buffer, size, errp) < 0 ? -EIO : 0;
+}
+
 static inline bool nbd_reply_is_simple(NBDReply *reply)
 {
 return reply->magic == NBD_SIMPLE_REPLY_MAGIC;
diff --git a/nbd/nbd-internal.h b/nbd/nbd-internal.h
index 4f24d6e57d..b64eb1cc9b 100644
--- a/nbd/nbd-internal.h
+++ b/nbd/nbd-internal.h
@@ -82,15 +82,6 @@ static inline int nbd_read_eof(QIOChannel *ioc, void 
*buffer, size_t size,
 return ret;
 }

-/* nbd_read
- * Reads @size bytes from @ioc. Returns 0 on success.
- */
-static inline int nbd_read(QIOChannel *ioc, void *buffer, size_t size,
-   Error **errp)
-{
-return qio_channel_read_all(ioc, buffer, size, errp) < 0 ? -EIO : 0;
-}
-
 /* nbd_write
  * Writes @size bytes to @ioc. Returns 0 on success.
  */
-- 
2.13.6




[Qemu-devel] [PATCH v4 2/8] nbd: Move nbd_errno_to_system_errno() to public header

2017-10-14 Thread Eric Blake
This is needed in preparation for structured reply handling,
as we will be performing the translation from NBD error to
system errno value higher in the stack at block/nbd-client.c.
---
 include/block/nbd.h | 13 +
 nbd/nbd-internal.h  | 12 
 nbd/client.c| 32 
 nbd/common.c| 34 ++
 nbd/trace-events|  4 +++-
 5 files changed, 50 insertions(+), 45 deletions(-)

diff --git a/include/block/nbd.h b/include/block/nbd.h
index a6df5ce8b5..dc62b5cd19 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -149,6 +149,18 @@ enum {
  * aren't overflowing some other buffer. */
 #define NBD_MAX_NAME_SIZE 256

+/* NBD errors are based on errno numbers, so there is a 1:1 mapping,
+ * but only a limited set of errno values is specified in the protocol.
+ * Everything else is squashed to EINVAL.
+ */
+#define NBD_SUCCESS0
+#define NBD_EPERM  1
+#define NBD_EIO5
+#define NBD_ENOMEM 12
+#define NBD_EINVAL 22
+#define NBD_ENOSPC 28
+#define NBD_ESHUTDOWN  108
+
 /* Details collected by NBD_OPT_EXPORT_NAME and NBD_OPT_GO */
 struct NBDExportInfo {
 /* Set by client before nbd_receive_negotiate() */
@@ -172,6 +184,7 @@ int nbd_send_request(QIOChannel *ioc, NBDRequest *request);
 int nbd_receive_reply(QIOChannel *ioc, NBDReply *reply, Error **errp);
 int nbd_client(int fd);
 int nbd_disconnect(int fd);
+int nbd_errno_to_system_errno(int err);

 typedef struct NBDExport NBDExport;
 typedef struct NBDClient NBDClient;
diff --git a/nbd/nbd-internal.h b/nbd/nbd-internal.h
index 4bfe5be884..df6c8b2f24 100644
--- a/nbd/nbd-internal.h
+++ b/nbd/nbd-internal.h
@@ -64,18 +64,6 @@
 #define NBD_SET_TIMEOUT _IO(0xab, 9)
 #define NBD_SET_FLAGS   _IO(0xab, 10)

-/* NBD errors are based on errno numbers, so there is a 1:1 mapping,
- * but only a limited set of errno values is specified in the protocol.
- * Everything else is squashed to EINVAL.
- */
-#define NBD_SUCCESS0
-#define NBD_EPERM  1
-#define NBD_EIO5
-#define NBD_ENOMEM 12
-#define NBD_EINVAL 22
-#define NBD_ENOSPC 28
-#define NBD_ESHUTDOWN  108
-
 /* nbd_read_eof
  * Tries to read @size bytes from @ioc.
  * Returns 1 on success
diff --git a/nbd/client.c b/nbd/client.c
index 59d7c9d49f..50f36b511e 100644
--- a/nbd/client.c
+++ b/nbd/client.c
@@ -22,38 +22,6 @@
 #include "trace.h"
 #include "nbd-internal.h"

-static int nbd_errno_to_system_errno(int err)
-{
-int ret;
-switch (err) {
-case NBD_SUCCESS:
-ret = 0;
-break;
-case NBD_EPERM:
-ret = EPERM;
-break;
-case NBD_EIO:
-ret = EIO;
-break;
-case NBD_ENOMEM:
-ret = ENOMEM;
-break;
-case NBD_ENOSPC:
-ret = ENOSPC;
-break;
-case NBD_ESHUTDOWN:
-ret = ESHUTDOWN;
-break;
-default:
-trace_nbd_unknown_error(err);
-/* fallthrough */
-case NBD_EINVAL:
-ret = EINVAL;
-break;
-}
-return ret;
-}
-
 /* Definitions for opaque data types */

 static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports);
diff --git a/nbd/common.c b/nbd/common.c
index 7456021f7e..593904f148 100644
--- a/nbd/common.c
+++ b/nbd/common.c
@@ -18,6 +18,7 @@

 #include "qemu/osdep.h"
 #include "qapi/error.h"
+#include "trace.h"
 #include "nbd-internal.h"

 /* Discard length bytes from channel.  Return -errno on failure and 0 on
@@ -171,3 +172,36 @@ const char *nbd_err_lookup(int err)
 return "";
 }
 }
+
+
+int nbd_errno_to_system_errno(int err)
+{
+int ret;
+switch (err) {
+case NBD_SUCCESS:
+ret = 0;
+break;
+case NBD_EPERM:
+ret = EPERM;
+break;
+case NBD_EIO:
+ret = EIO;
+break;
+case NBD_ENOMEM:
+ret = ENOMEM;
+break;
+case NBD_ENOSPC:
+ret = ENOSPC;
+break;
+case NBD_ESHUTDOWN:
+ret = ESHUTDOWN;
+break;
+default:
+trace_nbd_unknown_error(err);
+/* fallthrough */
+case NBD_EINVAL:
+ret = EINVAL;
+break;
+}
+return ret;
+}
diff --git a/nbd/trace-events b/nbd/trace-events
index 9a72f458b2..d3b702dd9a 100644
--- a/nbd/trace-events
+++ b/nbd/trace-events
@@ -1,5 +1,4 @@
 # nbd/client.c
-nbd_unknown_error(int err) "Squashing unexpected error %d to EINVAL"
 nbd_send_option_request(uint32_t opt, const char *name, uint32_t len) "Sending 
option request %" PRIu32" (%s), len %" PRIu32
 nbd_receive_option_reply(uint32_t option, const char *optname, uint32_t type, 
const char *typename, uint32_t length) "Received option reply 0x%" PRIx32" 
(%s), type 0x%" PRIx32" (%s), len %" PRIu32
 nbd_reply_err_unsup(uint32_t option, const char *name) "server doesn't 
understand request 0x%" PRIx32 " (%s), attempting fallback"
@@ -31,6 +30,9 @@ nbd_client_clear_socket(void) "Clearing NBD socket"
 nbd_send_request(uint64_t from, 

[Qemu-devel] [PATCH v4 5/8] nbd/server: Include human-readable message in structured errors

2017-10-14 Thread Eric Blake
The NBD spec permits including a human-readable error string if
structured replies are in force, so we might as well send the
client the message that we logged on any error.

Signed-off-by: Eric Blake 
---
 nbd/server.c | 22 --
 nbd/trace-events |  2 +-
 2 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/nbd/server.c b/nbd/server.c
index 23dc6be708..8085d79076 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -1289,23 +1289,25 @@ static int coroutine_fn 
nbd_co_send_structured_read(NBDClient *client,
 static int coroutine_fn nbd_co_send_structured_error(NBDClient *client,
  uint64_t handle,
  uint32_t error,
+ char *msg,
  Error **errp)
 {
 NBDStructuredError chunk;
 int nbd_err = system_errno_to_nbd_errno(error);
 struct iovec iov[] = {
 {.iov_base = , .iov_len = sizeof(chunk)},
-/* FIXME: Support human-readable error message */
+{.iov_base = msg, .iov_len = strlen(msg)},
 };

 assert(nbd_err);
-trace_nbd_co_send_structured_error(handle, nbd_err);
+trace_nbd_co_send_structured_error(handle, nbd_err,
+   nbd_err_lookup(nbd_err), msg);
 set_be_chunk(, NBD_REPLY_FLAG_DONE, NBD_REPLY_TYPE_ERROR, handle,
  sizeof(chunk) - sizeof(chunk.h));
 stl_be_p(, nbd_err);
-stw_be_p(_length, 0);
+stw_be_p(_length, iov[1].iov_len);

-return nbd_co_send_iov(client, iov, 1, errp);
+return nbd_co_send_iov(client, iov, 1 + !!iov[1].iov_len, errp);
 }

 /* nbd_co_receive_request
@@ -1406,6 +1408,7 @@ static coroutine_fn void nbd_trip(void *opaque)
 int flags;
 int reply_data_len = 0;
 Error *local_err = NULL;
+char *msg = NULL;

 trace_nbd_trip();
 if (client->closing) {
@@ -1521,14 +1524,20 @@ reply:
 if (local_err) {
 /* If we get here, local_err was not a fatal error, and should be sent
  * to the client. */
+assert(ret < 0);
+msg = g_strdup(error_get_pretty(local_err));
 error_report_err(local_err);
 local_err = NULL;
 }

-if (client->structured_reply && request.type == NBD_CMD_READ) {
+if (client->structured_reply &&
+(ret < 0 || request.type == NBD_CMD_READ)) {
 if (ret < 0) {
+if (!msg) {
+msg = g_strdup("");
+}
 ret = nbd_co_send_structured_error(req->client, request.handle,
-   -ret, _err);
+   -ret, msg, _err);
 } else {
 ret = nbd_co_send_structured_read(req->client, request.handle,
   request.from, req->data,
@@ -1539,6 +1548,7 @@ reply:
ret < 0 ? -ret : 0,
req->data, reply_data_len, _err);
 }
+g_free(msg);
 if (ret < 0) {
 error_prepend(_err, "Failed to send reply: ");
 goto disconnect;
diff --git a/nbd/trace-events b/nbd/trace-events
index 15a9294445..880f211c07 100644
--- a/nbd/trace-events
+++ b/nbd/trace-events
@@ -57,7 +57,7 @@ nbd_blk_aio_attached(const char *name, void *ctx) "Export %s: 
Attaching clients
 nbd_blk_aio_detach(const char *name, void *ctx) "Export %s: Detaching clients 
from AIO context %p\n"
 nbd_co_send_simple_reply(uint64_t handle, uint32_t error, const char *errname, 
int len) "Send simple reply: handle = %" PRIu64 ", error = %" PRIu32 " (%s), 
len = %d"
 nbd_co_send_structured_read(uint64_t handle, uint64_t offset, void *data, 
size_t size) "Send structured read data reply: handle = %" PRIu64 ", offset = 
%" PRIu64 ", data = %p, len = %zu"
-nbd_co_send_structured_error(uint64_t handle, int err) "Send structured error 
reply: handle = %" PRIu64 ", error = %d"
+nbd_co_send_structured_error(uint64_t handle, int err, const char *errname, 
const char *msg) "Send structured error reply: handle = %" PRIu64 ", error = %d 
(%s), msg = '%s'"
 nbd_co_receive_request_decode_type(uint64_t handle, uint16_t type, const char 
*name) "Decoding type: handle = %" PRIu64 ", type = %" PRIu16 " (%s)"
 nbd_co_receive_request_payload_received(uint64_t handle, uint32_t len) 
"Payload received: handle = %" PRIu64 ", len = %" PRIu32
 nbd_co_receive_request_cmd_write(uint32_t len) "Reading %" PRIu32 " byte(s)"
-- 
2.13.6




[Qemu-devel] [PATCH v4 0/8] nbd mimimal structured read

2017-10-14 Thread Eric Blake
As mentioned in my review of Vladimir's v3 of this series [1],
I had enough tweaks during my review that it's easier to repost
things for another round of discussion, adding some of my patches
in between his.  I did not include his 13/13 "nbd: Minimal structured
read for client", where I had a lot of comments, and suggest that
Vladimir is in the best position to rebase that patch on top of
this v4 series (post it as a 9/8, if desired).

[1] https://lists.gnu.org/archive/html/qemu-devel/2017-10/msg02755.html

Based-on: <20171015004033.3248-1-ebl...@redhat.com>
([PULL 0/9] NBD patches through 14 Oct)

Eric Blake (5):
  nbd: Include error names in trace messages
  nbd: Move nbd_errno_to_system_errno() to public header
  nbd: Expose constants and structs for structured read
  nbd/server: Include human-readable message in structured errors
  nbd: Move nbd_read() to common header

Vladimir Sementsov-Ogievskiy (3):
  nbd: Minimal structured read for server
  nbd/client: refactor nbd_receive_starttls
  nbd/client: prepare nbd_receive_reply for structured reply

 include/block/nbd.h |  94 ++--
 nbd/nbd-internal.h  |  24 +--
 block/nbd-client.c  |   8 ++-
 nbd/client.c| 204 +---
 nbd/common.c|  84 ++
 nbd/server.c| 121 ---
 nbd/trace-events|  15 ++--
 7 files changed, 427 insertions(+), 123 deletions(-)

-- 
2.13.6




[Qemu-devel] [PATCH v4 1/8] nbd: Include error names in trace messages

2017-10-14 Thread Eric Blake
NBD errors were originally sent over the wire based on Linux errno
values; but not all the world is Linux, and not all platforms share
the same values.  Since a number isn't very easy to decipher on all
platforms, update the trace messages to include the name of NBD
errors being sent/received over the wire.  Tweak the trace messages
to be at the point where we are using the NBD error, not the
translation to the host errno values.

Signed-off-by: Eric Blake 
---
 nbd/nbd-internal.h |  1 +
 nbd/client.c   |  3 ++-
 nbd/common.c   | 23 +++
 nbd/server.c   |  3 ++-
 nbd/trace-events   |  4 ++--
 5 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/nbd/nbd-internal.h b/nbd/nbd-internal.h
index 11a130d050..4bfe5be884 100644
--- a/nbd/nbd-internal.h
+++ b/nbd/nbd-internal.h
@@ -126,6 +126,7 @@ const char *nbd_opt_lookup(uint32_t opt);
 const char *nbd_rep_lookup(uint32_t rep);
 const char *nbd_info_lookup(uint16_t info);
 const char *nbd_cmd_lookup(uint16_t info);
+const char *nbd_err_lookup(int err);

 int nbd_drop(QIOChannel *ioc, size_t size, Error **errp);

diff --git a/nbd/client.c b/nbd/client.c
index cd5a2c80ac..59d7c9d49f 100644
--- a/nbd/client.c
+++ b/nbd/client.c
@@ -940,6 +940,8 @@ int nbd_receive_reply(QIOChannel *ioc, NBDReply *reply, 
Error **errp)
 reply->error  = ldl_be_p(buf + 4);
 reply->handle = ldq_be_p(buf + 8);

+trace_nbd_receive_reply(magic, reply->error, nbd_err_lookup(reply->error),
+reply->handle);
 reply->error = nbd_errno_to_system_errno(reply->error);

 if (reply->error == ESHUTDOWN) {
@@ -947,7 +949,6 @@ int nbd_receive_reply(QIOChannel *ioc, NBDReply *reply, 
Error **errp)
 error_setg(errp, "server shutting down");
 return -EINVAL;
 }
-trace_nbd_receive_reply(magic, reply->error, reply->handle);

 if (magic != NBD_SIMPLE_REPLY_MAGIC) {
 error_setg(errp, "invalid magic (got 0x%" PRIx32 ")", magic);
diff --git a/nbd/common.c b/nbd/common.c
index 59a5316be9..7456021f7e 100644
--- a/nbd/common.c
+++ b/nbd/common.c
@@ -148,3 +148,26 @@ const char *nbd_cmd_lookup(uint16_t cmd)
 return "";
 }
 }
+
+
+const char *nbd_err_lookup(int err)
+{
+switch (err) {
+case NBD_SUCCESS:
+return "success";
+case NBD_EPERM:
+return "EPERM";
+case NBD_EIO:
+return "EIO";
+case NBD_ENOMEM:
+return "ENOMEM";
+case NBD_EINVAL:
+return "EINVAL";
+case NBD_ENOSPC:
+return "ENOSPC";
+case NBD_ESHUTDOWN:
+return "ESHUTDOWN";
+default:
+return "";
+}
+}
diff --git a/nbd/server.c b/nbd/server.c
index 3df3548d6d..459e00c553 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -1227,7 +1227,8 @@ static int nbd_co_send_simple_reply(NBDClient *client,
 {.iov_base = data, .iov_len = len}
 };

-trace_nbd_co_send_simple_reply(handle, nbd_err, len);
+trace_nbd_co_send_simple_reply(handle, nbd_err, nbd_err_lookup(nbd_err),
+   len);
 set_be_simple_reply(, nbd_err, handle);

 return nbd_co_send_iov(client, iov, len ? 2 : 1, errp);
diff --git a/nbd/trace-events b/nbd/trace-events
index e27614f050..9a72f458b2 100644
--- a/nbd/trace-events
+++ b/nbd/trace-events
@@ -29,7 +29,7 @@ nbd_client_loop_ret(int ret, const char *error) "NBD loop 
returned %d: %s"
 nbd_client_clear_queue(void) "Clearing NBD queue"
 nbd_client_clear_socket(void) "Clearing NBD socket"
 nbd_send_request(uint64_t from, uint32_t len, uint64_t handle, uint16_t flags, 
uint16_t type, const char *name) "Sending request to server: { .from = %" 
PRIu64", .len = %" PRIu32 ", .handle = %" PRIu64 ", .flags = 0x%" PRIx16 ", 
.type = %" PRIu16 " (%s) }"
-nbd_receive_reply(uint32_t magic, int32_t error, uint64_t handle) "Got reply: 
{ magic = 0x%" PRIx32 ", .error = % " PRId32 ", handle = %" PRIu64" }"
+nbd_receive_reply(uint32_t magic, int32_t error, const char *errname, uint64_t 
handle) "Got reply: { magic = 0x%" PRIx32 ", .error = % " PRId32 " (%s), handle 
= %" PRIu64" }"

 # nbd/server.c
 nbd_negotiate_send_rep_len(uint32_t opt, const char *optname, uint32_t type, 
const char *typename, uint32_t len) "Reply opt=0x%" PRIx32 " (%s), type=0x%" 
PRIx32 " (%s), len=%" PRIu32
@@ -53,7 +53,7 @@ nbd_negotiate_success(void) "Negotiation succeeded"
 nbd_receive_request(uint32_t magic, uint16_t flags, uint16_t type, uint64_t 
from, uint32_t len) "Got request: { magic = 0x%" PRIx32 ", .flags = 0x%" PRIx16 
", .type = 0x%" PRIx16 ", from = %" PRIu64 ", len = %" PRIu32 " }"
 nbd_blk_aio_attached(const char *name, void *ctx) "Export %s: Attaching 
clients to AIO context %p\n"
 nbd_blk_aio_detach(const char *name, void *ctx) "Export %s: Detaching clients 
from AIO context %p\n"
-nbd_co_send_simple_reply(uint64_t handle, uint32_t error, int len) "Send 
simple reply: handle = %" PRIu64 ", error = %" PRIu32 ", len = %d"
+nbd_co_send_simple_reply(uint64_t handle, 

[Qemu-devel] [PULL 8/9] nbd/server: simplify reply transmission

2017-10-14 Thread Eric Blake
From: Vladimir Sementsov-Ogievskiy 

Send qiov via qio_channel_writev_all instead of calling nbd_write twice
with a cork.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Message-Id: <20171012095319.136610-8-vsement...@virtuozzo.com>
[eblake: rebase to tweaks earlier in series]
Signed-off-by: Eric Blake 
---
 nbd/server.c | 49 -
 1 file changed, 24 insertions(+), 25 deletions(-)

diff --git a/nbd/server.c b/nbd/server.c
index 3fcc3d3c7c..3df3548d6d 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -1188,6 +1188,23 @@ void nbd_export_close_all(void)
 }
 }

+static int coroutine_fn nbd_co_send_iov(NBDClient *client, struct iovec *iov,
+unsigned niov, Error **errp)
+{
+int ret;
+
+g_assert(qemu_in_coroutine());
+qemu_co_mutex_lock(>send_lock);
+client->send_coroutine = qemu_coroutine_self();
+
+ret = qio_channel_writev_all(client->ioc, iov, niov, errp) < 0 ? -EIO : 0;
+
+client->send_coroutine = NULL;
+qemu_co_mutex_unlock(>send_lock);
+
+return ret;
+}
+
 static inline void set_be_simple_reply(NBDSimpleReply *reply, uint64_t error,
uint64_t handle)
 {
@@ -1203,35 +1220,17 @@ static int nbd_co_send_simple_reply(NBDClient *client,
 size_t len,
 Error **errp)
 {
-NBDSimpleReply simple_reply;
+NBDSimpleReply reply;
 int nbd_err = system_errno_to_nbd_errno(error);
-int ret;
-
-g_assert(qemu_in_coroutine());
+struct iovec iov[] = {
+{.iov_base = , .iov_len = sizeof(reply)},
+{.iov_base = data, .iov_len = len}
+};

 trace_nbd_co_send_simple_reply(handle, nbd_err, len);
-set_be_simple_reply(_reply, nbd_err, handle);
+set_be_simple_reply(, nbd_err, handle);

-qemu_co_mutex_lock(>send_lock);
-client->send_coroutine = qemu_coroutine_self();
-
-if (!len) {
-ret = nbd_write(client->ioc, _reply, sizeof(simple_reply), 
errp);
-} else {
-qio_channel_set_cork(client->ioc, true);
-ret = nbd_write(client->ioc, _reply, sizeof(simple_reply), 
errp);
-if (ret == 0) {
-ret = nbd_write(client->ioc, data, len, errp);
-if (ret < 0) {
-ret = -EIO;
-}
-}
-qio_channel_set_cork(client->ioc, false);
-}
-
-client->send_coroutine = NULL;
-qemu_co_mutex_unlock(>send_lock);
-return ret;
+return nbd_co_send_iov(client, iov, len ? 2 : 1, errp);
 }

 /* nbd_co_receive_request
-- 
2.13.6




[Qemu-devel] [PULL 9/9] nbd: header constants indenting

2017-10-14 Thread Eric Blake
From: Vladimir Sementsov-Ogievskiy 

Prepare indenting for the following commit.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Eric Blake 
Message-Id: <20171012095319.136610-9-vsement...@virtuozzo.com>
Signed-off-by: Eric Blake 
---
 include/block/nbd.h | 15 ---
 nbd/nbd-internal.h  | 32 
 2 files changed, 24 insertions(+), 23 deletions(-)

diff --git a/include/block/nbd.h b/include/block/nbd.h
index 49008980f4..a6df5ce8b5 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -71,13 +71,14 @@ typedef struct NBDSimpleReply {

 /* Transmission (export) flags: sent from server to client during handshake,
but describe what will happen during transmission */
-#define NBD_FLAG_HAS_FLAGS  (1 << 0)/* Flags are there */
-#define NBD_FLAG_READ_ONLY  (1 << 1)/* Device is read-only */
-#define NBD_FLAG_SEND_FLUSH (1 << 2)/* Send FLUSH */
-#define NBD_FLAG_SEND_FUA   (1 << 3)/* Send FUA (Force Unit 
Access) */
-#define NBD_FLAG_ROTATIONAL (1 << 4)/* Use elevator algorithm - 
rotational media */
-#define NBD_FLAG_SEND_TRIM  (1 << 5)/* Send TRIM (discard) */
-#define NBD_FLAG_SEND_WRITE_ZEROES (1 << 6) /* Send WRITE_ZEROES */
+#define NBD_FLAG_HAS_FLAGS (1 << 0) /* Flags are there */
+#define NBD_FLAG_READ_ONLY (1 << 1) /* Device is read-only */
+#define NBD_FLAG_SEND_FLUSH(1 << 2) /* Send FLUSH */
+#define NBD_FLAG_SEND_FUA  (1 << 3) /* Send FUA (Force Unit Access) */
+#define NBD_FLAG_ROTATIONAL(1 << 4) /* Use elevator algorithm -
+   rotational media */
+#define NBD_FLAG_SEND_TRIM (1 << 5) /* Send TRIM (discard) */
+#define NBD_FLAG_SEND_WRITE_ZEROES (1 << 6) /* Send WRITE_ZEROES */

 /* New-style handshake (global) flags, sent from server to client, and
control what will happen during handshake phase. */
diff --git a/nbd/nbd-internal.h b/nbd/nbd-internal.h
index 2d6663de23..11a130d050 100644
--- a/nbd/nbd-internal.h
+++ b/nbd/nbd-internal.h
@@ -46,23 +46,23 @@
 /* Size of oldstyle negotiation */
 #define NBD_OLDSTYLE_NEGOTIATE_SIZE (8 + 8 + 8 + 4 + 124)

-#define NBD_REQUEST_MAGIC   0x25609513
-#define NBD_SIMPLE_REPLY_MAGIC  0x67446698
-#define NBD_OPTS_MAGIC  0x49484156454F5054LL
-#define NBD_CLIENT_MAGIC0x420281861253LL
-#define NBD_REP_MAGIC   0x0003e889045565a9LL
+#define NBD_REQUEST_MAGIC   0x25609513
+#define NBD_SIMPLE_REPLY_MAGIC  0x67446698
+#define NBD_OPTS_MAGIC  0x49484156454F5054LL
+#define NBD_CLIENT_MAGIC0x420281861253LL
+#define NBD_REP_MAGIC   0x0003e889045565a9LL

-#define NBD_SET_SOCK_IO(0xab, 0)
-#define NBD_SET_BLKSIZE _IO(0xab, 1)
-#define NBD_SET_SIZE_IO(0xab, 2)
-#define NBD_DO_IT   _IO(0xab, 3)
-#define NBD_CLEAR_SOCK  _IO(0xab, 4)
-#define NBD_CLEAR_QUE   _IO(0xab, 5)
-#define NBD_PRINT_DEBUG _IO(0xab, 6)
-#define NBD_SET_SIZE_BLOCKS _IO(0xab, 7)
-#define NBD_DISCONNECT  _IO(0xab, 8)
-#define NBD_SET_TIMEOUT _IO(0xab, 9)
-#define NBD_SET_FLAGS   _IO(0xab, 10)
+#define NBD_SET_SOCK_IO(0xab, 0)
+#define NBD_SET_BLKSIZE _IO(0xab, 1)
+#define NBD_SET_SIZE_IO(0xab, 2)
+#define NBD_DO_IT   _IO(0xab, 3)
+#define NBD_CLEAR_SOCK  _IO(0xab, 4)
+#define NBD_CLEAR_QUE   _IO(0xab, 5)
+#define NBD_PRINT_DEBUG _IO(0xab, 6)
+#define NBD_SET_SIZE_BLOCKS _IO(0xab, 7)
+#define NBD_DISCONNECT  _IO(0xab, 8)
+#define NBD_SET_TIMEOUT _IO(0xab, 9)
+#define NBD_SET_FLAGS   _IO(0xab, 10)

 /* NBD errors are based on errno numbers, so there is a 1:1 mapping,
  * but only a limited set of errno values is specified in the protocol.
-- 
2.13.6




[Qemu-devel] [PULL 6/9] nbd/server: do not use NBDReply structure

2017-10-14 Thread Eric Blake
From: Vladimir Sementsov-Ogievskiy 

NBDReply structure will be upgraded in future patches to handle both
simple and structured replies and will be used only in the client

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Message-Id: <20171012095319.136610-6-vsement...@virtuozzo.com>
[eblake: rebase to tweaks earlier in series]
Signed-off-by: Eric Blake 
---
 nbd/server.c | 36 +++-
 1 file changed, 15 insertions(+), 21 deletions(-)

diff --git a/nbd/server.c b/nbd/server.c
index 4f765ba992..06aeadcfbb 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -1196,18 +1196,20 @@ static inline void set_be_simple_reply(NBDSimpleReply 
*reply, uint64_t error,
 stq_be_p(>handle, handle);
 }

-static int nbd_co_send_simple_reply(NBDRequestData *req, NBDReply *reply,
+static int nbd_co_send_simple_reply(NBDRequestData *req,
+uint64_t handle,
+uint32_t error,
 int len, Error **errp)
 {
 NBDClient *client = req->client;
 NBDSimpleReply simple_reply;
-int nbd_err = system_errno_to_nbd_errno(reply->error);
+int nbd_err = system_errno_to_nbd_errno(error);
 int ret;

 g_assert(qemu_in_coroutine());

-trace_nbd_co_send_simple_reply(reply->handle, nbd_err, len);
-set_be_simple_reply(_reply, nbd_err, reply->handle);
+trace_nbd_co_send_simple_reply(handle, nbd_err, len);
+set_be_simple_reply(_reply, nbd_err, handle);

 qemu_co_mutex_lock(>send_lock);
 client->send_coroutine = qemu_coroutine_self();
@@ -1322,7 +1324,6 @@ static coroutine_fn void nbd_trip(void *opaque)
 NBDExport *exp = client->exp;
 NBDRequestData *req;
 NBDRequest request = { 0 };/* GCC thinks it can be used uninitialized 
*/
-NBDReply reply;
 int ret;
 int flags;
 int reply_data_len = 0;
@@ -1342,11 +1343,7 @@ static coroutine_fn void nbd_trip(void *opaque)
 goto disconnect;
 }

-reply.handle = request.handle;
-reply.error = 0;
-
 if (ret < 0) {
-reply.error = -ret;
 goto reply;
 }

@@ -1365,7 +1362,6 @@ static coroutine_fn void nbd_trip(void *opaque)
 ret = blk_co_flush(exp->blk);
 if (ret < 0) {
 error_setg_errno(_err, -ret, "flush failed");
-reply.error = -ret;
 break;
 }
 }
@@ -1374,7 +1370,6 @@ static coroutine_fn void nbd_trip(void *opaque)
 req->data, request.len);
 if (ret < 0) {
 error_setg_errno(_err, -ret, "reading from file failed");
-reply.error = -ret;
 break;
 }

@@ -1383,7 +1378,7 @@ static coroutine_fn void nbd_trip(void *opaque)
 break;
 case NBD_CMD_WRITE:
 if (exp->nbdflags & NBD_FLAG_READ_ONLY) {
-reply.error = EROFS;
+ret = -EROFS;
 break;
 }

@@ -1395,14 +1390,13 @@ static coroutine_fn void nbd_trip(void *opaque)
  req->data, request.len, flags);
 if (ret < 0) {
 error_setg_errno(_err, -ret, "writing to file failed");
-reply.error = -ret;
 }

 break;
 case NBD_CMD_WRITE_ZEROES:
 if (exp->nbdflags & NBD_FLAG_READ_ONLY) {
 error_setg(_err, "Server is read-only, return error");
-reply.error = EROFS;
+ret = -EROFS;
 break;
 }

@@ -1417,7 +1411,6 @@ static coroutine_fn void nbd_trip(void *opaque)
 request.len, flags);
 if (ret < 0) {
 error_setg_errno(_err, -ret, "writing to file failed");
-reply.error = -ret;
 }

 break;
@@ -1429,7 +1422,6 @@ static coroutine_fn void nbd_trip(void *opaque)
 ret = blk_co_flush(exp->blk);
 if (ret < 0) {
 error_setg_errno(_err, -ret, "flush failed");
-reply.error = -ret;
 }

 break;
@@ -1438,25 +1430,27 @@ static coroutine_fn void nbd_trip(void *opaque)
   request.len);
 if (ret < 0) {
 error_setg_errno(_err, -ret, "discard failed");
-reply.error = -ret;
 }

 break;
 default:
 error_setg(_err, "invalid request type (%" PRIu32 ") received",
request.type);
-reply.error = EINVAL;
+ret = -EINVAL;
 }

 reply:
 if (local_err) {
-/* If we are here local_err is not fatal error, already stored in
- * reply.error */
+/* If we get here, local_err was not a fatal error, and should be sent
+ * to the client. */
 error_report_err(local_err);
 local_err = NULL;
 }

-if (nbd_co_send_simple_reply(req, , reply_data_len, _err) < 0) 
{
+if (nbd_co_send_simple_reply(req, request.handle,
+

[Qemu-devel] [PULL 7/9] nbd/server: refactor nbd_co_send_simple_reply parameters

2017-10-14 Thread Eric Blake
From: Vladimir Sementsov-Ogievskiy 

Pass client and buffer (*data) parameters directly, to make the function
consistent with further structured reply sending functions.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Message-Id: <20171012095319.136610-7-vsement...@virtuozzo.com>
Signed-off-by: Eric Blake 
---
 nbd/server.c | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/nbd/server.c b/nbd/server.c
index 06aeadcfbb..3fcc3d3c7c 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -1196,12 +1196,13 @@ static inline void set_be_simple_reply(NBDSimpleReply 
*reply, uint64_t error,
 stq_be_p(>handle, handle);
 }

-static int nbd_co_send_simple_reply(NBDRequestData *req,
+static int nbd_co_send_simple_reply(NBDClient *client,
 uint64_t handle,
 uint32_t error,
-int len, Error **errp)
+void *data,
+size_t len,
+Error **errp)
 {
-NBDClient *client = req->client;
 NBDSimpleReply simple_reply;
 int nbd_err = system_errno_to_nbd_errno(error);
 int ret;
@@ -1220,7 +1221,7 @@ static int nbd_co_send_simple_reply(NBDRequestData *req,
 qio_channel_set_cork(client->ioc, true);
 ret = nbd_write(client->ioc, _reply, sizeof(simple_reply), 
errp);
 if (ret == 0) {
-ret = nbd_write(client->ioc, req->data, len, errp);
+ret = nbd_write(client->ioc, data, len, errp);
 if (ret < 0) {
 ret = -EIO;
 }
@@ -1447,9 +1448,9 @@ reply:
 local_err = NULL;
 }

-if (nbd_co_send_simple_reply(req, request.handle,
+if (nbd_co_send_simple_reply(req->client, request.handle,
  ret < 0 ? -ret : 0,
- reply_data_len, _err) < 0)
+ req->data, reply_data_len, _err) < 0)
 {
 error_prepend(_err, "Failed to send reply: ");
 goto disconnect;
-- 
2.13.6




[Qemu-devel] [PULL 4/9] nbd: rename some simple-request related objects to be _simple_

2017-10-14 Thread Eric Blake
From: Vladimir Sementsov-Ogievskiy 

To be consistent when their _structured_ analogs will be introduced.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Eric Blake 
Message-Id: <20171012095319.136610-4-vsement...@virtuozzo.com>
[eblake: also tweak trace message contents]
Signed-off-by: Eric Blake 
---
 nbd/nbd-internal.h   |  2 +-
 nbd/client.c |  4 ++--
 nbd/server.c | 12 ++--
 nbd/trace-events |  2 +-
 tests/qemu-iotests/nbd-fault-injector.py |  4 ++--
 5 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/nbd/nbd-internal.h b/nbd/nbd-internal.h
index 8a609a227f..2d6663de23 100644
--- a/nbd/nbd-internal.h
+++ b/nbd/nbd-internal.h
@@ -47,7 +47,7 @@
 #define NBD_OLDSTYLE_NEGOTIATE_SIZE (8 + 8 + 8 + 4 + 124)

 #define NBD_REQUEST_MAGIC   0x25609513
-#define NBD_REPLY_MAGIC 0x67446698
+#define NBD_SIMPLE_REPLY_MAGIC  0x67446698
 #define NBD_OPTS_MAGIC  0x49484156454F5054LL
 #define NBD_CLIENT_MAGIC0x420281861253LL
 #define NBD_REP_MAGIC   0x0003e889045565a9LL
diff --git a/nbd/client.c b/nbd/client.c
index 68a0bc1ffc..cd5a2c80ac 100644
--- a/nbd/client.c
+++ b/nbd/client.c
@@ -931,7 +931,7 @@ int nbd_receive_reply(QIOChannel *ioc, NBDReply *reply, 
Error **errp)
 }

 /* Reply
-   [ 0 ..  3]magic   (NBD_REPLY_MAGIC)
+   [ 0 ..  3]magic   (NBD_SIMPLE_REPLY_MAGIC)
[ 4 ..  7]error   (0 == no error)
[ 7 .. 15]handle
  */
@@ -949,7 +949,7 @@ int nbd_receive_reply(QIOChannel *ioc, NBDReply *reply, 
Error **errp)
 }
 trace_nbd_receive_reply(magic, reply->error, reply->handle);

-if (magic != NBD_REPLY_MAGIC) {
+if (magic != NBD_SIMPLE_REPLY_MAGIC) {
 error_setg(errp, "invalid magic (got 0x%" PRIx32 ")", magic);
 return -EINVAL;
 }
diff --git a/nbd/server.c b/nbd/server.c
index b74cc6ab7e..ea2f0fa476 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -911,11 +911,11 @@ static int nbd_send_reply(QIOChannel *ioc, NBDReply 
*reply, Error **errp)
 trace_nbd_send_reply(reply->error, reply->handle);

 /* Reply
-   [ 0 ..  3]magic   (NBD_REPLY_MAGIC)
+   [ 0 ..  3]magic   (NBD_SIMPLE_REPLY_MAGIC)
[ 4 ..  7]error   (0 == no error)
[ 7 .. 15]handle
  */
-stl_be_p(buf, NBD_REPLY_MAGIC);
+stl_be_p(buf, NBD_SIMPLE_REPLY_MAGIC);
 stl_be_p(buf + 4, reply->error);
 stq_be_p(buf + 8, reply->handle);

@@ -1208,15 +1208,15 @@ void nbd_export_close_all(void)
 }
 }

-static int nbd_co_send_reply(NBDRequestData *req, NBDReply *reply, int len,
- Error **errp)
+static int nbd_co_send_simple_reply(NBDRequestData *req, NBDReply *reply,
+int len, Error **errp)
 {
 NBDClient *client = req->client;
 int ret;

 g_assert(qemu_in_coroutine());

-trace_nbd_co_send_reply(reply->handle, reply->error, len);
+trace_nbd_co_send_simple_reply(reply->handle, reply->error, len);

 qemu_co_mutex_lock(>send_lock);
 client->send_coroutine = qemu_coroutine_self();
@@ -1465,7 +1465,7 @@ reply:
 local_err = NULL;
 }

-if (nbd_co_send_reply(req, , reply_data_len, _err) < 0) {
+if (nbd_co_send_simple_reply(req, , reply_data_len, _err) < 0) 
{
 error_prepend(_err, "Failed to send reply: ");
 goto disconnect;
 }
diff --git a/nbd/trace-events b/nbd/trace-events
index 48a4f27682..4d6f86c2d4 100644
--- a/nbd/trace-events
+++ b/nbd/trace-events
@@ -54,7 +54,7 @@ nbd_receive_request(uint32_t magic, uint16_t flags, uint16_t 
type, uint64_t from
 nbd_send_reply(int32_t error, uint64_t handle) "Sending response to client: { 
.error = %" PRId32 ", handle = %" PRIu64 " }"
 nbd_blk_aio_attached(const char *name, void *ctx) "Export %s: Attaching 
clients to AIO context %p\n"
 nbd_blk_aio_detach(const char *name, void *ctx) "Export %s: Detaching clients 
from AIO context %p\n"
-nbd_co_send_reply(uint64_t handle, uint32_t error, int len) "Send reply: 
handle = %" PRIu64 ", error = %" PRIu32 ", len = %d"
+nbd_co_send_simple_reply(uint64_t handle, uint32_t error, int len) "Send 
simple reply: handle = %" PRIu64 ", error = %" PRIu32 ", len = %d"
 nbd_co_receive_request_decode_type(uint64_t handle, uint16_t type, const char 
*name) "Decoding type: handle = %" PRIu64 ", type = %" PRIu16 " (%s)"
 nbd_co_receive_request_payload_received(uint64_t handle, uint32_t len) 
"Payload received: handle = %" PRIu64 ", len = %" PRIu32
 nbd_co_receive_request_cmd_write(uint32_t len) "Reading %" PRIu32 " byte(s)"
diff --git a/tests/qemu-iotests/nbd-fault-injector.py 
b/tests/qemu-iotests/nbd-fault-injector.py
index 1c10dcb51c..8a04d979aa 100755
--- a/tests/qemu-iotests/nbd-fault-injector.py
+++ b/tests/qemu-iotests/nbd-fault-injector.py
@@ -56,7 +56,7 @@ 

[Qemu-devel] [PULL 2/9] block/nbd-client: assert qiov len once in nbd_co_request

2017-10-14 Thread Eric Blake
From: Vladimir Sementsov-Ogievskiy 

Also improve the assertion: check that qiov is NULL for other commands
than CMD_READ and CMD_WRITE.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Eric Blake 
Message-Id: <20171012095319.136610-2-vsement...@virtuozzo.com>
Signed-off-by: Eric Blake 
---
 block/nbd-client.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/block/nbd-client.c b/block/nbd-client.c
index 72651dcdb1..ddf273a6a4 100644
--- a/block/nbd-client.c
+++ b/block/nbd-client.c
@@ -156,7 +156,6 @@ static int nbd_co_send_request(BlockDriverState *bs,
 qio_channel_set_cork(s->ioc, true);
 rc = nbd_send_request(s->ioc, request);
 if (rc >= 0 && !s->quit) {
-assert(request->len == iov_size(qiov->iov, qiov->niov));
 if (qio_channel_writev_all(s->ioc, qiov->iov, qiov->niov,
NULL) < 0) {
 rc = -EIO;
@@ -197,7 +196,6 @@ static int nbd_co_receive_reply(NBDClientSession *s,
 assert(s->reply.handle == request->handle);
 ret = -s->reply.error;
 if (qiov && s->reply.error == 0) {
-assert(request->len == iov_size(qiov->iov, qiov->niov));
 if (qio_channel_readv_all(s->ioc, qiov->iov, qiov->niov,
   NULL) < 0) {
 ret = -EIO;
@@ -231,8 +229,12 @@ static int nbd_co_request(BlockDriverState *bs,
 NBDClientSession *client = nbd_get_client_session(bs);
 int ret;

-assert(!qiov || request->type == NBD_CMD_WRITE ||
-   request->type == NBD_CMD_READ);
+if (qiov) {
+assert(request->type == NBD_CMD_WRITE || request->type == 
NBD_CMD_READ);
+assert(request->len == iov_size(qiov->iov, qiov->niov));
+} else {
+assert(request->type != NBD_CMD_WRITE && request->type != 
NBD_CMD_READ);
+}
 ret = nbd_co_send_request(bs, request,
   request->type == NBD_CMD_WRITE ? qiov : NULL);
 if (ret < 0) {
-- 
2.13.6




[Qemu-devel] [PULL 5/9] nbd/server: structurize simple reply header sending

2017-10-14 Thread Eric Blake
From: Vladimir Sementsov-Ogievskiy 

Use packed structure instead of pointer arithmetics.

Also, merge two redundant traces into one.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Message-Id: <20171012095319.136610-5-vsement...@virtuozzo.com>
[eblake: tweak and mention impact on traces, fix errp usage]
Signed-off-by: Eric Blake 
---
 include/block/nbd.h |  6 ++
 nbd/server.c| 37 ++---
 nbd/trace-events|  1 -
 3 files changed, 20 insertions(+), 24 deletions(-)

diff --git a/include/block/nbd.h b/include/block/nbd.h
index 707fd37575..49008980f4 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -63,6 +63,12 @@ struct NBDReply {
 };
 typedef struct NBDReply NBDReply;

+typedef struct NBDSimpleReply {
+uint32_t magic;  /* NBD_SIMPLE_REPLY_MAGIC */
+uint32_t error;
+uint64_t handle;
+} QEMU_PACKED NBDSimpleReply;
+
 /* Transmission (export) flags: sent from server to client during handshake,
but describe what will happen during transmission */
 #define NBD_FLAG_HAS_FLAGS  (1 << 0)/* Flags are there */
diff --git a/nbd/server.c b/nbd/server.c
index ea2f0fa476..4f765ba992 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -902,26 +902,6 @@ static int nbd_receive_request(QIOChannel *ioc, NBDRequest 
*request,
 return 0;
 }

-static int nbd_send_reply(QIOChannel *ioc, NBDReply *reply, Error **errp)
-{
-uint8_t buf[NBD_REPLY_SIZE];
-
-reply->error = system_errno_to_nbd_errno(reply->error);
-
-trace_nbd_send_reply(reply->error, reply->handle);
-
-/* Reply
-   [ 0 ..  3]magic   (NBD_SIMPLE_REPLY_MAGIC)
-   [ 4 ..  7]error   (0 == no error)
-   [ 7 .. 15]handle
- */
-stl_be_p(buf, NBD_SIMPLE_REPLY_MAGIC);
-stl_be_p(buf + 4, reply->error);
-stq_be_p(buf + 8, reply->handle);
-
-return nbd_write(ioc, buf, sizeof(buf), errp);
-}
-
 #define MAX_NBD_REQUESTS 16

 void nbd_client_get(NBDClient *client)
@@ -1208,24 +1188,35 @@ void nbd_export_close_all(void)
 }
 }

+static inline void set_be_simple_reply(NBDSimpleReply *reply, uint64_t error,
+   uint64_t handle)
+{
+stl_be_p(>magic, NBD_SIMPLE_REPLY_MAGIC);
+stl_be_p(>error, error);
+stq_be_p(>handle, handle);
+}
+
 static int nbd_co_send_simple_reply(NBDRequestData *req, NBDReply *reply,
 int len, Error **errp)
 {
 NBDClient *client = req->client;
+NBDSimpleReply simple_reply;
+int nbd_err = system_errno_to_nbd_errno(reply->error);
 int ret;

 g_assert(qemu_in_coroutine());

-trace_nbd_co_send_simple_reply(reply->handle, reply->error, len);
+trace_nbd_co_send_simple_reply(reply->handle, nbd_err, len);
+set_be_simple_reply(_reply, nbd_err, reply->handle);

 qemu_co_mutex_lock(>send_lock);
 client->send_coroutine = qemu_coroutine_self();

 if (!len) {
-ret = nbd_send_reply(client->ioc, reply, errp);
+ret = nbd_write(client->ioc, _reply, sizeof(simple_reply), 
errp);
 } else {
 qio_channel_set_cork(client->ioc, true);
-ret = nbd_send_reply(client->ioc, reply, errp);
+ret = nbd_write(client->ioc, _reply, sizeof(simple_reply), 
errp);
 if (ret == 0) {
 ret = nbd_write(client->ioc, req->data, len, errp);
 if (ret < 0) {
diff --git a/nbd/trace-events b/nbd/trace-events
index 4d6f86c2d4..e27614f050 100644
--- a/nbd/trace-events
+++ b/nbd/trace-events
@@ -51,7 +51,6 @@ nbd_negotiate_old_style(uint64_t size, unsigned flags) 
"advertising size %" PRIu
 nbd_negotiate_new_style_size_flags(uint64_t size, unsigned flags) "advertising 
size %" PRIu64 " and flags 0x%x"
 nbd_negotiate_success(void) "Negotiation succeeded"
 nbd_receive_request(uint32_t magic, uint16_t flags, uint16_t type, uint64_t 
from, uint32_t len) "Got request: { magic = 0x%" PRIx32 ", .flags = 0x%" PRIx16 
", .type = 0x%" PRIx16 ", from = %" PRIu64 ", len = %" PRIu32 " }"
-nbd_send_reply(int32_t error, uint64_t handle) "Sending response to client: { 
.error = %" PRId32 ", handle = %" PRIu64 " }"
 nbd_blk_aio_attached(const char *name, void *ctx) "Export %s: Attaching 
clients to AIO context %p\n"
 nbd_blk_aio_detach(const char *name, void *ctx) "Export %s: Detaching clients 
from AIO context %p\n"
 nbd_co_send_simple_reply(uint64_t handle, uint32_t error, int len) "Send 
simple reply: handle = %" PRIu64 ", error = %" PRIu32 ", len = %d"
-- 
2.13.6




[Qemu-devel] [PULL 3/9] block/nbd-client: refactor nbd_co_receive_reply

2017-10-14 Thread Eric Blake
From: Vladimir Sementsov-Ogievskiy 

Pass handle parameter directly, as the whole request isn't needed.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Eric Blake 
Message-Id: <20171012095319.136610-3-vsement...@virtuozzo.com>
Signed-off-by: Eric Blake 
---
 block/nbd-client.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/block/nbd-client.c b/block/nbd-client.c
index ddf273a6a4..c0683c3c83 100644
--- a/block/nbd-client.c
+++ b/block/nbd-client.c
@@ -180,11 +180,11 @@ err:
 }

 static int nbd_co_receive_reply(NBDClientSession *s,
-NBDRequest *request,
+uint64_t handle,
 QEMUIOVector *qiov)
 {
 int ret;
-int i = HANDLE_TO_INDEX(s, request->handle);
+int i = HANDLE_TO_INDEX(s, handle);

 /* Wait until we're woken up by nbd_read_reply_entry.  */
 s->requests[i].receiving = true;
@@ -193,7 +193,7 @@ static int nbd_co_receive_reply(NBDClientSession *s,
 if (!s->ioc || s->quit) {
 ret = -EIO;
 } else {
-assert(s->reply.handle == request->handle);
+assert(s->reply.handle == handle);
 ret = -s->reply.error;
 if (qiov && s->reply.error == 0) {
 if (qio_channel_readv_all(s->ioc, qiov->iov, qiov->niov,
@@ -241,7 +241,7 @@ static int nbd_co_request(BlockDriverState *bs,
 return ret;
 }

-return nbd_co_receive_reply(client, request,
+return nbd_co_receive_reply(client, request->handle,
 request->type == NBD_CMD_READ ? qiov : NULL);
 }

-- 
2.13.6




[Qemu-devel] [PULL 0/9] NBD patches through 14 Oct

2017-10-14 Thread Eric Blake
The following changes since commit f90ea7ba7c5ae7010ee0ce062207ae42530f57d6:

  Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20171012' 
into staging (2017-10-12 17:06:50 +0100)

are available in the git repository at:

  git://repo.or.cz/qemu/ericb.git tags/pull-nbd-2017-10-14

for you to fetch changes up to 92652b124336f5c08c7eb4616af202ea910dd3ea:

  nbd: header constants indenting (2017-10-13 09:27:38 -0500)


nbd patches for 2017-10-14

- Marc-André Lureau - NBD: use g_new() family of functions
- Vladimir Sementsov-Ogievskiy - first half of 00/13 nbd minimal structured read


Marc-André Lureau (1):
  NBD: use g_new() family of functions

Vladimir Sementsov-Ogievskiy (8):
  block/nbd-client: assert qiov len once in nbd_co_request
  block/nbd-client: refactor nbd_co_receive_reply
  nbd: rename some simple-request related objects to be _simple_
  nbd/server: structurize simple reply header sending
  nbd/server: do not use NBDReply structure
  nbd/server: refactor nbd_co_send_simple_reply parameters
  nbd/server: simplify reply transmission
  nbd: header constants indenting

 include/block/nbd.h  |  21 ---
 nbd/nbd-internal.h   |  32 +-
 block/nbd-client.c   |  18 +++---
 nbd/client.c |   4 +-
 nbd/server.c | 101 +--
 nbd/trace-events |   3 +-
 tests/qemu-iotests/nbd-fault-injector.py |   4 +-
 7 files changed, 88 insertions(+), 95 deletions(-)

-- 
2.13.6




[Qemu-devel] [PULL 1/9] NBD: use g_new() family of functions

2017-10-14 Thread Eric Blake
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Message-Id: <20171006235023.11952-22-f4...@amsat.org>
Signed-off-by: Eric Blake 
---
 nbd/server.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/nbd/server.c b/nbd/server.c
index 993ade30bb..b74cc6ab7e 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -1047,7 +1047,7 @@ NBDExport *nbd_export_new(BlockDriverState *bs, off_t 
dev_offset, off_t size,
 {
 AioContext *ctx;
 BlockBackend *blk;
-NBDExport *exp = g_malloc0(sizeof(NBDExport));
+NBDExport *exp = g_new0(NBDExport, 1);
 uint64_t perm;
 int ret;

@@ -1539,7 +1539,7 @@ void nbd_client_new(NBDExport *exp,
 NBDClient *client;
 Coroutine *co;

-client = g_malloc0(sizeof(NBDClient));
+client = g_new0(NBDClient, 1);
 client->refcount = 1;
 client->exp = exp;
 client->tlscreds = tlscreds;
-- 
2.13.6




Re: [Qemu-devel] [RFC QEMU PATCH v3 00/10] Implement vNVDIMM for Xen HVM guest

2017-10-14 Thread Michael S. Tsirkin
On Fri, Oct 13, 2017 at 03:53:26PM +0800, Haozhong Zhang wrote:
> On 10/12/17 17:45 +0200, Paolo Bonzini wrote:
> > On 12/10/2017 14:45, Haozhong Zhang wrote:
> > > Basically, QEMU builds two ROMs for guest, /rom@etc/acpi/tables and
> > > /rom@etc/table-loader. The former is unstructured to guest, and
> > > contains all data of guest ACPI. The latter is a BIOSLinkerLoader
> > > organized as a set of commands, which direct the guest (e.g., SeaBIOS
> > > on KVM/QEMU) to relocate data in the former file, recalculate checksum
> > > of specified area, and fill guest address in specified ACPI field.
> > > 
> > > One part of my patches is to implement a mechanism to tell Xen which
> > > part of ACPI data is a table (NFIT), and which part defines a
> > > namespace device and what the device name is. I can add two new loader
> > > commands for them respectively.
> > > 
> > > Because they just provide information and SeaBIOS in non-xen
> > > environment ignores unrecognized commands, they will not break SeaBIOS
> > > in non-xen environment.
> > > 
> > > On QEMU side, most Xen-specific hacks in ACPI builder could be
> > > dropped, and replaced by adding the new loader commands (though they
> > > may be used only by Xen).
> > > 
> > > On Xen side, a fw_cfg driver and a BIOSLinkerLoader command executor
> > > are needed in, perhaps, hvmloader.
> > 
> > If Xen has to parse BIOSLinkerLoader, it can use the existing commands
> > to process a reduced set of ACPI tables.  In other words,
> > etc/acpi/tables would only include the NFIT, the SSDT with namespace
> > devices, and the XSDT.  etc/acpi/rsdp would include the RSDP table as usual.
> >
> > hvmloader can then:
> > 
> > 1) allocate some memory for where the XSDT will go
> > 
> > 2) process the BIOSLinkerLoader like SeaBIOS would do
> > 
> > 3) find the RSDP in low memory, since the loader script must have placed
> > it there.  If it cannot find it, allocate some low memory, fill it with
> > the RSDP header and revision, and and jump to step 6
> > 
> > 4) If it found QEMU's RSDP, use it to find QEMU's XSDT
> > 
> > 5) Copy ACPI table pointers from QEMU to hvmloader's RSDT and/or XSDT.
> > 
> > 6) build hvmloader tables and link them into the RSDT and/or XSDT as usual.
> > 
> > 7) overwrite the RSDP in low memory with a pointer to hvmloader's own
> > RSDT and/or XSDT, and updated the checksums
> > 
> > QEMU's XSDT remains there somewhere in memory, unused but harmless.
> > 
> 
> It can work for plan tables which do not contain AML.
> 
> However, for a namespace device, Xen needs to know its name in order
> to detect the potential name conflict with those used in Xen built
> ACPI. Xen does not (and is not going to) introduce an AML parser, so
> it cannot get those device names from QEMU built ACPI by its own.
> 
> The idea of either this patch series or the new BIOSLinkerLoader
> command is to let QEMU tell Xen where the definition body of a
> namespace device (i.e. that part within the outmost "Device(NAME)") is
> and what the device name is. Xen, after the name conflict check, can
> re-package the definition body in a namespace device (w/ minimal AML
> builder code added in Xen) and then in SSDT.
> 
> 
> Haozhong

You most likely can do this without a new command.
You can use something similiar to build_append_named_dword
in combination with BIOS_LINKER_LOADER_COMMAND_ADD_POINTER
like vm gen id does.

-- 
MST



Re: [Qemu-devel] [RFC QEMU PATCH v3 00/10] Implement vNVDIMM for Xen HVM guest

2017-10-14 Thread Michael S. Tsirkin
On Fri, Oct 13, 2017 at 03:46:39PM -0700, Stefano Stabellini wrote:
> On Fri, 13 Oct 2017, Jan Beulich wrote:
> > >>> On 13.10.17 at 13:13,  wrote:
> > > To Jan, Andrew, Stefano and Anthony,
> > > 
> > > what do you think about allowing QEMU to build the entire guest ACPI
> > > and letting SeaBIOS to load it? ACPI builder code in hvmloader is
> > > still there and just bypassed in this case.
> > 
> > Well, if that can be made work in a non-quirky way and without
> > loss of functionality, I'd probably be fine. I do think, however,
> > that there's a reason this is being handled in hvmloader right now.
> 
> And not to discourage you, just as a clarification, you'll also need to
> consider backward compatibility: unless the tables are identical, I
> imagine we'll have to keep using the old tables for already installed
> virtual machines.

Maybe you can handle this using machine type versioning.
Installed guests would use the old type.

-- 
MST



Re: [Qemu-devel] [PATCHv3 00/13] sun4m: sparc32_dma tidy-ups

2017-10-14 Thread no-reply
Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 1508006342-5304-1-git-send-email-mark.cave-ayl...@ilande.co.uk
Subject: [Qemu-devel] [PATCHv3 00/13] sun4m: sparc32_dma tidy-ups

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

git config --local diff.renamelimit 0
git config --local diff.renames True

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
failed=1
echo
fi
n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
49376f2097 sparc32_dma: add len to esp/le DMA memory tracing
d1747b9946 sparc32_dma: remove is_ledma hack and replace with memory region 
alias
aff708b794 sparc32_dma: introduce new SPARC32_DMA type container object
c1d8e324e2 sparc32_dma: make lance device child of ledma device
89f91116dd lance: move TYPE_LANCE and SysBusPCNetState from lance.c to sun4m.h
dead665d1d sparc32_dma: make esp device child of espdma device
1afaa63bbd esp: move TYPE_ESP and SysBusESPState from esp.c to esp.h
9e05523632 sparc32_dma: use object link instead of qdev property to pass IOMMU 
reference
80b9835896 sun4m_iommu: move TYPE_SUN4M_IOMMU declaration to sun4m.h
66a36aaa11 sun4m: move DMA device wiring from sparc32_dma_init() to 
sun4m_hw_init()
d2fd9ca3eb sparc32_dma: move type declarations from sparc32_dma.c to 
sparc32_dma.h
74c5135edf sparc32_dma: split esp and le into separate DMA devices
cc07b7035d sparc32_dma: rename SPARC32_DMA type to SPARC32_DMA_DEVICE

=== OUTPUT BEGIN ===
Checking PATCH 1/13: sparc32_dma: rename SPARC32_DMA type to 
SPARC32_DMA_DEVICE...
Checking PATCH 2/13: sparc32_dma: split esp and le into separate DMA devices...
Checking PATCH 3/13: sparc32_dma: move type declarations from sparc32_dma.c to 
sparc32_dma.h...
Checking PATCH 4/13: sun4m: move DMA device wiring from sparc32_dma_init() to 
sun4m_hw_init()...
ERROR: spaces required around that '*' (ctx:WxV)
#51: FILE: hw/sparc/sun4m.c:824:
+qemu_irq *cpu_irqs[MAX_CPUS], slavio_irq[32], slavio_cpu_irq[MAX_CPUS];
  ^

total: 1 errors, 0 warnings, 66 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 5/13: sun4m_iommu: move TYPE_SUN4M_IOMMU declaration to 
sun4m.h...
Checking PATCH 6/13: sparc32_dma: use object link instead of qdev property to 
pass IOMMU reference...
Checking PATCH 7/13: esp: move TYPE_ESP and SysBusESPState from esp.c to 
esp.h...
Checking PATCH 8/13: sparc32_dma: make esp device child of espdma device...
Checking PATCH 9/13: lance: move TYPE_LANCE and SysBusPCNetState from lance.c 
to sun4m.h...
Checking PATCH 10/13: sparc32_dma: make lance device child of ledma device...
Checking PATCH 11/13: sparc32_dma: introduce new SPARC32_DMA type container 
object...
Checking PATCH 12/13: sparc32_dma: remove is_ledma hack and replace with memory 
region alias...
Checking PATCH 13/13: sparc32_dma: add len to esp/le DMA memory tracing...
=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-de...@freelists.org

[Qemu-devel] [PATCHv3 08/13] sparc32_dma: make esp device child of espdma device

2017-10-14 Thread Mark Cave-Ayland
This makes it possible to reference the esp device from the espdma device as
required, and by wiring up the device ourselves in sun4m.c we can drop use
of the esp_init() function.

Signed-off-by: Mark Cave-Ayland 
---
 hw/dma/sparc32_dma.c   |   26 ++
 hw/sparc/sun4m.c   |   19 ---
 include/hw/sparc/sparc32_dma.h |3 +++
 3 files changed, 37 insertions(+), 11 deletions(-)

diff --git a/hw/dma/sparc32_dma.c b/hw/dma/sparc32_dma.c
index c56a2ba..6009b94 100644
--- a/hw/dma/sparc32_dma.c
+++ b/hw/dma/sparc32_dma.c
@@ -298,11 +298,37 @@ static void sparc32_espdma_device_init(Object *obj)
 s->is_ledma = 0;
 }
 
+static void sparc32_espdma_device_realize(DeviceState *dev, Error **errp)
+{
+DeviceState *d;
+SysBusESPState *sysbus;
+ESPState *esp;
+
+d = qdev_create(NULL, TYPE_ESP);
+object_property_add_child(OBJECT(dev), "esp", OBJECT(d), errp);
+sysbus = ESP_STATE(d);
+esp = >esp;
+esp->dma_memory_read = espdma_memory_read;
+esp->dma_memory_write = espdma_memory_write;
+esp->dma_opaque = SPARC32_DMA_DEVICE(dev);
+sysbus->it_shift = 2;
+esp->dma_enabled = 1;
+qdev_init_nofail(d);
+}
+
+static void sparc32_espdma_device_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->realize = sparc32_espdma_device_realize;
+}
+
 static const TypeInfo sparc32_espdma_device_info = {
 .name  = TYPE_SPARC32_ESPDMA_DEVICE,
 .parent= TYPE_SPARC32_DMA_DEVICE,
 .instance_size = sizeof(ESPDMADeviceState),
 .instance_init = sparc32_espdma_device_init,
+.class_init= sparc32_espdma_device_class_init,
 };
 
 static void sparc32_ledma_device_init(Object *obj)
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 12d36b5..4626c85 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -819,10 +819,9 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
 const char *cpu_model = machine->cpu_model;
 unsigned int i;
 void *iommu, *nvram;
-DeviceState *espdma, *ledma;
+DeviceState *espdma, *esp, *ledma;
 SysBusDevice *sbd;
 qemu_irq *cpu_irqs[MAX_CPUS], slavio_irq[32], slavio_cpu_irq[MAX_CPUS];
-qemu_irq esp_reset, dma_enable;
 qemu_irq fdc_tc;
 unsigned long kernel_size;
 DriveInfo *fd[MAX_FD];
@@ -884,6 +883,13 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
 sbd = SYS_BUS_DEVICE(espdma);
 sysbus_connect_irq(sbd, 0, slavio_irq[18]);
 
+esp = DEVICE(object_resolve_path_component(OBJECT(espdma), "esp"));
+sbd = SYS_BUS_DEVICE(esp);
+sysbus_mmio_map(sbd, 0, hwdef->esp_base);
+sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(espdma, 0));
+qdev_connect_gpio_out(espdma, 0, qdev_get_gpio_in(esp, 0));
+qdev_connect_gpio_out(espdma, 1, qdev_get_gpio_in(esp, 1));
+
 ledma = sparc32_dma_init(hwdef->dma_base + 16ULL, iommu, 1);
 sbd = SYS_BUS_DEVICE(ledma);
 sysbus_connect_irq(sbd, 0, slavio_irq[16]);
@@ -970,15 +976,6 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
 slavio_misc_init(hwdef->slavio_base, hwdef->aux1_base, hwdef->aux2_base,
  slavio_irq[30], fdc_tc);
 
-esp_init(hwdef->esp_base, 2,
- espdma_memory_read, espdma_memory_write,
- espdma,
- qdev_get_gpio_in(espdma, 0),
- _reset, _enable);
-
-qdev_connect_gpio_out(espdma, 0, esp_reset);
-qdev_connect_gpio_out(espdma, 1, dma_enable);
-
 if (hwdef->cs_base) {
 sysbus_create_simple("SUNW,CS4231", hwdef->cs_base,
  slavio_irq[5]);
diff --git a/include/hw/sparc/sparc32_dma.h b/include/hw/sparc/sparc32_dma.h
index df7491d..365160f 100644
--- a/include/hw/sparc/sparc32_dma.h
+++ b/include/hw/sparc/sparc32_dma.h
@@ -2,6 +2,7 @@
 #define SPARC32_DMA_H
 
 #include "hw/sysbus.h"
+#include "hw/scsi/esp.h"
 
 #define DMA_REGS 4
 
@@ -28,6 +29,8 @@ struct DMADeviceState {
 
 typedef struct ESPDMADeviceState {
 DMADeviceState parent_obj;
+
+SysBusESPState *esp;
 } ESPDMADeviceState;
 
 #define TYPE_SPARC32_LEDMA_DEVICE "sparc32-ledma"
-- 
1.7.10.4




[Qemu-devel] [PATCHv3 11/13] sparc32_dma: introduce new SPARC32_DMA type container object

2017-10-14 Thread Mark Cave-Ayland
Create a new SPARC32_DMA container object (including an appropriate container
memory region) and add instances of the SPARC32_ESPDMA_DEVICE and
SPARC32_LEDMA_DEVICE as child objects. The benefit is that most of the gpio
wiring complexity between esp/espdma and lance/ledma is now hidden within the
SPARC32_DMA realize function.

Since the sun4m IOMMU is already QOMified we can find a reference to
it using object_resolve_path_type() allowing us to completely remove all 
external
references to the iommu pointer.

Finally we rework sun4m's sparc32_dma_init() to invoke the new SPARC32_DMA 
object
and wire up the remaining board memory regions/IRQs.

Signed-off-by: Mark Cave-Ayland 
---
 hw/dma/sparc32_dma.c   |   70 
 hw/sparc/sun4m.c   |   66 ++---
 include/hw/sparc/sparc32_dma.h |   12 +++
 3 files changed, 114 insertions(+), 34 deletions(-)

diff --git a/hw/dma/sparc32_dma.c b/hw/dma/sparc32_dma.c
index d507ca3..ba62927 100644
--- a/hw/dma/sparc32_dma.c
+++ b/hw/dma/sparc32_dma.c
@@ -29,6 +29,7 @@
 #include "hw/hw.h"
 #include "hw/sparc/sparc32_dma.h"
 #include "hw/sysbus.h"
+#include "qapi/error.h"
 #include "trace.h"
 
 /*
@@ -368,11 +369,80 @@ static const TypeInfo sparc32_ledma_device_info = {
 .class_init= sparc32_ledma_device_class_init,
 };
 
+static void sparc32_dma_realize(DeviceState *dev, Error **errp)
+{
+SPARC32DMAState *s = SPARC32_DMA(dev);
+DeviceState *espdma, *esp, *ledma, *lance;
+SysBusDevice *sbd;
+Object *iommu;
+
+iommu = object_resolve_path_type("", TYPE_SUN4M_IOMMU, NULL);
+if (!iommu) {
+error_setg(errp, "unable to locate sun4m IOMMU device");
+return;
+}
+
+espdma = qdev_create(NULL, TYPE_SPARC32_ESPDMA_DEVICE);
+object_property_set_link(OBJECT(espdma), iommu, "iommu", errp);
+object_property_add_child(OBJECT(s), "espdma", OBJECT(espdma), errp);
+qdev_init_nofail(espdma);
+
+esp = DEVICE(object_resolve_path_component(OBJECT(espdma), "esp"));
+sbd = SYS_BUS_DEVICE(esp);
+sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(espdma, 0));
+qdev_connect_gpio_out(espdma, 0, qdev_get_gpio_in(esp, 0));
+qdev_connect_gpio_out(espdma, 1, qdev_get_gpio_in(esp, 1));
+
+sbd = SYS_BUS_DEVICE(espdma);
+memory_region_add_subregion(>dmamem, 0x0,
+sysbus_mmio_get_region(sbd, 0));
+
+ledma = qdev_create(NULL, TYPE_SPARC32_LEDMA_DEVICE);
+object_property_set_link(OBJECT(ledma), iommu, "iommu", errp);
+object_property_add_child(OBJECT(s), "ledma", OBJECT(ledma), errp);
+qdev_init_nofail(ledma);
+
+lance = DEVICE(object_resolve_path_component(OBJECT(ledma), "lance"));
+sbd = SYS_BUS_DEVICE(lance);
+sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(ledma, 0));
+qdev_connect_gpio_out(ledma, 0, qdev_get_gpio_in(lance, 0));
+
+sbd = SYS_BUS_DEVICE(ledma);
+memory_region_add_subregion(>dmamem, 0x10,
+sysbus_mmio_get_region(sbd, 0));
+}
+
+static void sparc32_dma_init(Object *obj)
+{
+SPARC32DMAState *s = SPARC32_DMA(obj);
+SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+
+memory_region_init(>dmamem, OBJECT(s), "dma", DMA_SIZE + DMA_ETH_SIZE);
+sysbus_init_mmio(sbd, >dmamem);
+}
+
+static void sparc32_dma_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->realize = sparc32_dma_realize;
+}
+
+static const TypeInfo sparc32_dma_info = {
+.name  = TYPE_SPARC32_DMA,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(SPARC32DMAState),
+.instance_init = sparc32_dma_init,
+.class_init= sparc32_dma_class_init,
+};
+
+
 static void sparc32_dma_register_types(void)
 {
 type_register_static(_dma_device_info);
 type_register_static(_espdma_device_info);
 type_register_static(_ledma_device_info);
+type_register_static(_dma_info);
 }
 
 type_init(sparc32_dma_register_types)
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index ae486a4..5017ae5 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -307,18 +307,36 @@ static void *iommu_init(hwaddr addr, uint32_t version, 
qemu_irq irq)
 return s;
 }
 
-static void *sparc32_dma_init(hwaddr daddr, void *iommu, int is_ledma)
+static void *sparc32_dma_init(hwaddr dma_base,
+  hwaddr esp_base, qemu_irq espdma_irq,
+  hwaddr le_base, qemu_irq ledma_irq)
 {
-DeviceState *dev;
-SysBusDevice *s;
+DeviceState *dma;
+ESPDMADeviceState *espdma;
+LEDMADeviceState *ledma;
+SysBusESPState *esp;
+SysBusPCNetState *lance;
 
-dev = qdev_create(NULL, is_ledma ? "sparc32-ledma" : "sparc32-espdma");
-object_property_set_link(OBJECT(dev), OBJECT(iommu), "iommu", 
_abort);
-qdev_init_nofail(dev);
-s = SYS_BUS_DEVICE(dev);
-sysbus_mmio_map(s, 0, daddr);
+dma = 

[Qemu-devel] [PATCHv3 13/13] sparc32_dma: add len to esp/le DMA memory tracing

2017-10-14 Thread Mark Cave-Ayland
This is surprisingly useful when trying to debug DMA issues.

Signed-off-by: Mark Cave-Ayland 
---
 hw/dma/sparc32_dma.c |8 
 hw/dma/trace-events  |8 
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/hw/dma/sparc32_dma.c b/hw/dma/sparc32_dma.c
index bb7d70a..fbb072a 100644
--- a/hw/dma/sparc32_dma.c
+++ b/hw/dma/sparc32_dma.c
@@ -73,7 +73,7 @@ void ledma_memory_read(void *opaque, hwaddr addr,
 int i;
 
 addr |= s->dmaregs[3];
-trace_ledma_memory_read(addr);
+trace_ledma_memory_read(addr, len);
 if (do_bswap) {
 sparc_iommu_memory_read(s->iommu, addr, buf, len);
 } else {
@@ -94,7 +94,7 @@ void ledma_memory_write(void *opaque, hwaddr addr,
 uint16_t tmp_buf[32];
 
 addr |= s->dmaregs[3];
-trace_ledma_memory_write(addr);
+trace_ledma_memory_write(addr, len);
 if (do_bswap) {
 sparc_iommu_memory_write(s->iommu, addr, buf, len);
 } else {
@@ -139,7 +139,7 @@ void espdma_memory_read(void *opaque, uint8_t *buf, int len)
 {
 DMADeviceState *s = opaque;
 
-trace_espdma_memory_read(s->dmaregs[1]);
+trace_espdma_memory_read(s->dmaregs[1], len);
 sparc_iommu_memory_read(s->iommu, s->dmaregs[1], buf, len);
 s->dmaregs[1] += len;
 }
@@ -148,7 +148,7 @@ void espdma_memory_write(void *opaque, uint8_t *buf, int 
len)
 {
 DMADeviceState *s = opaque;
 
-trace_espdma_memory_write(s->dmaregs[1]);
+trace_espdma_memory_write(s->dmaregs[1], len);
 sparc_iommu_memory_write(s->iommu, s->dmaregs[1], buf, len);
 s->dmaregs[1] += len;
 }
diff --git a/hw/dma/trace-events b/hw/dma/trace-events
index 428469a..6b367f0 100644
--- a/hw/dma/trace-events
+++ b/hw/dma/trace-events
@@ -7,12 +7,12 @@ rc4030_read(uint64_t addr, uint32_t ret) "read 
reg[0x%"PRIx64"] = 0x%x"
 rc4030_write(uint64_t addr, uint32_t val) "write reg[0x%"PRIx64"] = 0x%x"
 
 # hw/dma/sparc32_dma.c
-ledma_memory_read(uint64_t addr) "DMA read addr 0x%"PRIx64
-ledma_memory_write(uint64_t addr) "DMA write addr 0x%"PRIx64
+ledma_memory_read(uint64_t addr, int len) "DMA read addr 0x%"PRIx64 " len %d"
+ledma_memory_write(uint64_t addr, int len) "DMA write addr 0x%"PRIx64 " len %d"
 sparc32_dma_set_irq_raise(void) "Raise IRQ"
 sparc32_dma_set_irq_lower(void) "Lower IRQ"
-espdma_memory_read(uint32_t addr) "DMA read addr 0x%08x"
-espdma_memory_write(uint32_t addr) "DMA write addr 0x%08x"
+espdma_memory_read(uint32_t addr, int len) "DMA read addr 0x%08x len %d"
+espdma_memory_write(uint32_t addr, int len) "DMA write addr 0x%08x len %d"
 sparc32_dma_mem_readl(uint64_t addr, uint32_t ret) "read dmareg 0x%"PRIx64": 
0x%08x"
 sparc32_dma_mem_writel(uint64_t addr, uint32_t old, uint32_t val) "write 
dmareg 0x%"PRIx64": 0x%08x -> 0x%08x"
 sparc32_dma_enable_raise(void) "Raise DMA enable"
-- 
1.7.10.4




[Qemu-devel] [PATCHv3 09/13] lance: move TYPE_LANCE and SysBusPCNetState from lance.c to sun4m.h

2017-10-14 Thread Mark Cave-Ayland
This enables them to be used outside of lance.c.

Signed-off-by: Mark Cave-Ayland 
CC: Jason Wang 
---
 hw/net/lance.c   |9 -
 include/hw/sparc/sun4m.h |   13 +
 2 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/hw/net/lance.c b/hw/net/lance.c
index 92b0c68..ef7747d 100644
--- a/hw/net/lance.c
+++ b/hw/net/lance.c
@@ -45,15 +45,6 @@
 #include "trace.h"
 #include "sysemu/sysemu.h"
 
-#define TYPE_LANCE "lance"
-#define SYSBUS_PCNET(obj) \
-OBJECT_CHECK(SysBusPCNetState, (obj), TYPE_LANCE)
-
-typedef struct {
-SysBusDevice parent_obj;
-
-PCNetState state;
-} SysBusPCNetState;
 
 static void parent_lance_reset(void *opaque, int irq, int level)
 {
diff --git a/include/hw/sparc/sun4m.h b/include/hw/sparc/sun4m.h
index 1f1cf91..a4f5f09 100644
--- a/include/hw/sparc/sun4m.h
+++ b/include/hw/sparc/sun4m.h
@@ -5,6 +5,8 @@
 #include "exec/hwaddr.h"
 #include "qapi/qmp/types.h"
 #include "hw/sysbus.h"
+#include "net/net.h"
+#include "hw/net/pcnet.h"
 
 /* Devices used by sparc32 system.  */
 
@@ -40,6 +42,17 @@ static inline void sparc_iommu_memory_write(void *opaque,
 sparc_iommu_memory_rw(opaque, addr, buf, len, 1);
 }
 
+/* lance.c */
+#define TYPE_LANCE "lance"
+#define SYSBUS_PCNET(obj) \
+OBJECT_CHECK(SysBusPCNetState, (obj), TYPE_LANCE)
+
+typedef struct {
+SysBusDevice parent_obj;
+
+PCNetState state;
+} SysBusPCNetState;
+
 /* sparc32_dma.c */
 #include "hw/sparc/sparc32_dma.h"
 
-- 
1.7.10.4




[Qemu-devel] [PATCHv3 10/13] sparc32_dma: make lance device child of ledma device

2017-10-14 Thread Mark Cave-Ayland
This makes it possible to reference the lance device from the ledma device as
required.

Signed-off-by: Mark Cave-Ayland 
---
 hw/dma/sparc32_dma.c   |   23 ++-
 hw/sparc/sun4m.c   |   31 +++
 include/hw/sparc/sparc32_dma.h |3 +++
 3 files changed, 32 insertions(+), 25 deletions(-)

diff --git a/hw/dma/sparc32_dma.c b/hw/dma/sparc32_dma.c
index 6009b94..d507ca3 100644
--- a/hw/dma/sparc32_dma.c
+++ b/hw/dma/sparc32_dma.c
@@ -28,7 +28,6 @@
 #include "qemu/osdep.h"
 #include "hw/hw.h"
 #include "hw/sparc/sparc32_dma.h"
-#include "hw/sparc/sun4m.h"
 #include "hw/sysbus.h"
 #include "trace.h"
 
@@ -340,11 +339,33 @@ static void sparc32_ledma_device_init(Object *obj)
 s->is_ledma = 1;
 }
 
+static void sparc32_ledma_device_realize(DeviceState *dev, Error **errp)
+{
+DeviceState *d;
+NICInfo *nd = _table[0];
+
+qemu_check_nic_model(nd, "lance");
+
+d = qdev_create(NULL, "lance");
+object_property_add_child(OBJECT(dev), "lance", OBJECT(d), errp);
+qdev_set_nic_properties(d, nd);
+qdev_prop_set_ptr(d, "dma", dev);
+qdev_init_nofail(d);
+}
+
+static void sparc32_ledma_device_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->realize = sparc32_ledma_device_realize;
+}
+
 static const TypeInfo sparc32_ledma_device_info = {
 .name  = TYPE_SPARC32_LEDMA_DEVICE,
 .parent= TYPE_SPARC32_DMA_DEVICE,
 .instance_size = sizeof(LEDMADeviceState),
 .instance_init = sparc32_ledma_device_init,
+.class_init= sparc32_ledma_device_class_init,
 };
 
 static void sparc32_dma_register_types(void)
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 4626c85..ae486a4 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -321,26 +321,6 @@ static void *sparc32_dma_init(hwaddr daddr, void *iommu, 
int is_ledma)
 return s;
 }
 
-static void lance_init(NICInfo *nd, hwaddr leaddr,
-   void *dma_opaque, qemu_irq irq)
-{
-DeviceState *dev;
-SysBusDevice *s;
-qemu_irq reset;
-
-qemu_check_nic_model(_table[0], "lance");
-
-dev = qdev_create(NULL, "lance");
-qdev_set_nic_properties(dev, nd);
-qdev_prop_set_ptr(dev, "dma", dma_opaque);
-qdev_init_nofail(dev);
-s = SYS_BUS_DEVICE(dev);
-sysbus_mmio_map(s, 0, leaddr);
-sysbus_connect_irq(s, 0, irq);
-reset = qdev_get_gpio_in(dev, 0);
-qdev_connect_gpio_out(dma_opaque, 0, reset);
-}
-
 static DeviceState *slavio_intctl_init(hwaddr addr,
hwaddr addrg,
qemu_irq **parent_irq)
@@ -819,7 +799,7 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
 const char *cpu_model = machine->cpu_model;
 unsigned int i;
 void *iommu, *nvram;
-DeviceState *espdma, *esp, *ledma;
+DeviceState *espdma, *esp, *ledma, *lance;
 SysBusDevice *sbd;
 qemu_irq *cpu_irqs[MAX_CPUS], slavio_irq[32], slavio_cpu_irq[MAX_CPUS];
 qemu_irq fdc_tc;
@@ -894,6 +874,12 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
 sbd = SYS_BUS_DEVICE(ledma);
 sysbus_connect_irq(sbd, 0, slavio_irq[16]);
 
+lance = DEVICE(object_resolve_path_component(OBJECT(ledma), "lance"));
+sbd = SYS_BUS_DEVICE(lance);
+sysbus_mmio_map(sbd, 0, hwdef->le_base);
+sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(ledma, 0));
+qdev_connect_gpio_out(ledma, 0, qdev_get_gpio_in(lance, 0));
+
 if (graphic_depth != 8 && graphic_depth != 24) {
 error_report("Unsupported depth: %d", graphic_depth);
 exit (1);
@@ -945,9 +931,6 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
 empty_slot_init(hwdef->sx_base, 0x2000);
 }
 
-lance_init(_table[0], hwdef->le_base, ledma,
-   qdev_get_gpio_in(ledma, 0));
-
 nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0, 0x2000, 1968, 8);
 
 slavio_timer_init_all(hwdef->counter_base, slavio_irq[19], slavio_cpu_irq, 
smp_cpus);
diff --git a/include/hw/sparc/sparc32_dma.h b/include/hw/sparc/sparc32_dma.h
index 365160f..5f39c28 100644
--- a/include/hw/sparc/sparc32_dma.h
+++ b/include/hw/sparc/sparc32_dma.h
@@ -3,6 +3,7 @@
 
 #include "hw/sysbus.h"
 #include "hw/scsi/esp.h"
+#include "hw/sparc/sun4m.h"
 
 #define DMA_REGS 4
 
@@ -39,6 +40,8 @@ typedef struct ESPDMADeviceState {
 
 typedef struct LEDMADeviceState {
 DMADeviceState parent_obj;
+
+SysBusPCNetState *lance;
 } LEDMADeviceState;
 
 /* sparc32_dma.c */
-- 
1.7.10.4




[Qemu-devel] [PATCHv3 12/13] sparc32_dma: remove is_ledma hack and replace with memory region alias

2017-10-14 Thread Mark Cave-Ayland
This hack originated from before the memory region API was introduced, and
increased the size of the ledma DMA device to capture incorrect accesses
beyond the end of the ledma device. A full analysis can be found on Artyom's
blog at 
http://tyom.blogspot.co.uk/2010/10/bug-in-all-solaris-versions-after-57.html.

With the memory API we can now simply alias the incorrect access onto its
intended destination allowing us to remove the hack.

Signed-off-by: Mark Cave-Ayland 
---
 hw/dma/sparc32_dma.c   |   20 ++--
 include/hw/sparc/sparc32_dma.h |2 +-
 2 files changed, 7 insertions(+), 15 deletions(-)

diff --git a/hw/dma/sparc32_dma.c b/hw/dma/sparc32_dma.c
index ba62927..bb7d70a 100644
--- a/hw/dma/sparc32_dma.c
+++ b/hw/dma/sparc32_dma.c
@@ -159,12 +159,6 @@ static uint64_t dma_mem_read(void *opaque, hwaddr addr,
 DMADeviceState *s = opaque;
 uint32_t saddr;
 
-if (s->is_ledma && (addr > DMA_MAX_REG_OFFSET)) {
-/* aliased to espdma, but we can't get there from here */
-/* buggy driver if using undocumented behavior, just return 0 */
-trace_sparc32_dma_mem_readl(addr, 0);
-return 0;
-}
 saddr = (addr & DMA_MASK) >> 2;
 trace_sparc32_dma_mem_readl(addr, s->dmaregs[saddr]);
 return s->dmaregs[saddr];
@@ -176,11 +170,6 @@ static void dma_mem_write(void *opaque, hwaddr addr,
 DMADeviceState *s = opaque;
 uint32_t saddr;
 
-if (s->is_ledma && (addr > DMA_MAX_REG_OFFSET)) {
-/* aliased to espdma, but we can't get there from here */
-trace_sparc32_dma_mem_writel(addr, 0, val);
-return;
-}
 saddr = (addr & DMA_MASK) >> 2;
 trace_sparc32_dma_mem_writel(addr, s->dmaregs[saddr], val);
 switch (saddr) {
@@ -295,7 +284,6 @@ static void sparc32_espdma_device_init(Object *obj)
 
 memory_region_init_io(>iomem, OBJECT(s), _mem_ops, s,
   "espdma-mmio", DMA_SIZE);
-s->is_ledma = 0;
 }
 
 static void sparc32_espdma_device_realize(DeviceState *dev, Error **errp)
@@ -336,8 +324,7 @@ static void sparc32_ledma_device_init(Object *obj)
 DMADeviceState *s = SPARC32_DMA_DEVICE(obj);
 
 memory_region_init_io(>iomem, OBJECT(s), _mem_ops, s,
-  "ledma-mmio", DMA_ETH_SIZE);
-s->is_ledma = 1;
+  "ledma-mmio", DMA_SIZE);
 }
 
 static void sparc32_ledma_device_realize(DeviceState *dev, Error **errp)
@@ -410,6 +397,11 @@ static void sparc32_dma_realize(DeviceState *dev, Error 
**errp)
 sbd = SYS_BUS_DEVICE(ledma);
 memory_region_add_subregion(>dmamem, 0x10,
 sysbus_mmio_get_region(sbd, 0));
+
+/* Add ledma alias to handle SunOS 5.7 - Solaris 9 invalid access bug */
+memory_region_init_alias(>ledma_alias, OBJECT(dev), "ledma-alias",
+ sysbus_mmio_get_region(sbd, 0), 0x4, 0x4);
+memory_region_add_subregion(>dmamem, 0x20, >ledma_alias);
 }
 
 static void sparc32_dma_init(Object *obj)
diff --git a/include/hw/sparc/sparc32_dma.h b/include/hw/sparc/sparc32_dma.h
index e52cd1d..f78180f 100644
--- a/include/hw/sparc/sparc32_dma.h
+++ b/include/hw/sparc/sparc32_dma.h
@@ -21,7 +21,6 @@ struct DMADeviceState {
 qemu_irq irq;
 void *iommu;
 qemu_irq gpio[2];
-uint32_t is_ledma;
 };
 
 #define TYPE_SPARC32_ESPDMA_DEVICE "sparc32-espdma"
@@ -52,6 +51,7 @@ typedef struct SPARC32DMAState {
 SysBusDevice parent_obj;
 
 MemoryRegion dmamem;
+MemoryRegion ledma_alias;
 ESPDMADeviceState *espdma;
 LEDMADeviceState *ledma;
 } SPARC32DMAState;
-- 
1.7.10.4




[Qemu-devel] [PATCHv3 01/13] sparc32_dma: rename SPARC32_DMA type to SPARC32_DMA_DEVICE

2017-10-14 Thread Mark Cave-Ayland
Also update the function names to match as appropriate. While we're
here rename the type from sparc32_dma to sparc32-dma in order to
match the current QOM convention.

Signed-off-by: Mark Cave-Ayland 
---
 hw/dma/sparc32_dma.c |   67 +-
 hw/sparc/sun4m.c |2 +-
 2 files changed, 35 insertions(+), 34 deletions(-)

diff --git a/hw/dma/sparc32_dma.c b/hw/dma/sparc32_dma.c
index eb491b5..a8d31c1 100644
--- a/hw/dma/sparc32_dma.c
+++ b/hw/dma/sparc32_dma.c
@@ -61,12 +61,13 @@
 /* XXX SCSI and ethernet should have different read-only bit masks */
 #define DMA_CSR_RO_MASK 0xfe07
 
-#define TYPE_SPARC32_DMA "sparc32_dma"
-#define SPARC32_DMA(obj) OBJECT_CHECK(DMAState, (obj), TYPE_SPARC32_DMA)
+#define TYPE_SPARC32_DMA_DEVICE "sparc32-dma-device"
+#define SPARC32_DMA_DEVICE(obj) OBJECT_CHECK(DMADeviceState, (obj), \
+ TYPE_SPARC32_DMA_DEVICE)
 
-typedef struct DMAState DMAState;
+typedef struct DMADeviceState DMADeviceState;
 
-struct DMAState {
+struct DMADeviceState {
 SysBusDevice parent_obj;
 
 MemoryRegion iomem;
@@ -86,7 +87,7 @@ enum {
 void ledma_memory_read(void *opaque, hwaddr addr,
uint8_t *buf, int len, int do_bswap)
 {
-DMAState *s = opaque;
+DMADeviceState *s = opaque;
 int i;
 
 addr |= s->dmaregs[3];
@@ -106,7 +107,7 @@ void ledma_memory_read(void *opaque, hwaddr addr,
 void ledma_memory_write(void *opaque, hwaddr addr,
 uint8_t *buf, int len, int do_bswap)
 {
-DMAState *s = opaque;
+DMADeviceState *s = opaque;
 int l, i;
 uint16_t tmp_buf[32];
 
@@ -134,7 +135,7 @@ void ledma_memory_write(void *opaque, hwaddr addr,
 
 static void dma_set_irq(void *opaque, int irq, int level)
 {
-DMAState *s = opaque;
+DMADeviceState *s = opaque;
 if (level) {
 s->dmaregs[0] |= DMA_INTR;
 if (s->dmaregs[0] & DMA_INTREN) {
@@ -154,7 +155,7 @@ static void dma_set_irq(void *opaque, int irq, int level)
 
 void espdma_memory_read(void *opaque, uint8_t *buf, int len)
 {
-DMAState *s = opaque;
+DMADeviceState *s = opaque;
 
 trace_espdma_memory_read(s->dmaregs[1]);
 sparc_iommu_memory_read(s->iommu, s->dmaregs[1], buf, len);
@@ -163,7 +164,7 @@ void espdma_memory_read(void *opaque, uint8_t *buf, int len)
 
 void espdma_memory_write(void *opaque, uint8_t *buf, int len)
 {
-DMAState *s = opaque;
+DMADeviceState *s = opaque;
 
 trace_espdma_memory_write(s->dmaregs[1]);
 sparc_iommu_memory_write(s->iommu, s->dmaregs[1], buf, len);
@@ -173,7 +174,7 @@ void espdma_memory_write(void *opaque, uint8_t *buf, int 
len)
 static uint64_t dma_mem_read(void *opaque, hwaddr addr,
  unsigned size)
 {
-DMAState *s = opaque;
+DMADeviceState *s = opaque;
 uint32_t saddr;
 
 if (s->is_ledma && (addr > DMA_MAX_REG_OFFSET)) {
@@ -190,7 +191,7 @@ static uint64_t dma_mem_read(void *opaque, hwaddr addr,
 static void dma_mem_write(void *opaque, hwaddr addr,
   uint64_t val, unsigned size)
 {
-DMAState *s = opaque;
+DMADeviceState *s = opaque;
 uint32_t saddr;
 
 if (s->is_ledma && (addr > DMA_MAX_REG_OFFSET)) {
@@ -252,28 +253,28 @@ static const MemoryRegionOps dma_mem_ops = {
 },
 };
 
-static void dma_reset(DeviceState *d)
+static void sparc32_dma_device_reset(DeviceState *d)
 {
-DMAState *s = SPARC32_DMA(d);
+DMADeviceState *s = SPARC32_DMA_DEVICE(d);
 
 memset(s->dmaregs, 0, DMA_SIZE);
 s->dmaregs[0] = DMA_VER;
 }
 
-static const VMStateDescription vmstate_dma = {
+static const VMStateDescription vmstate_sparc32_dma_device = {
 .name ="sparc32_dma",
 .version_id = 2,
 .minimum_version_id = 2,
 .fields = (VMStateField[]) {
-VMSTATE_UINT32_ARRAY(dmaregs, DMAState, DMA_REGS),
+VMSTATE_UINT32_ARRAY(dmaregs, DMADeviceState, DMA_REGS),
 VMSTATE_END_OF_LIST()
 }
 };
 
-static void sparc32_dma_init(Object *obj)
+static void sparc32_dma_device_init(Object *obj)
 {
 DeviceState *dev = DEVICE(obj);
-DMAState *s = SPARC32_DMA(obj);
+DMADeviceState *s = SPARC32_DMA_DEVICE(obj);
 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
 
 sysbus_init_irq(sbd, >irq);
@@ -284,9 +285,9 @@ static void sparc32_dma_init(Object *obj)
 qdev_init_gpio_out(dev, s->gpio, 2);
 }
 
-static void sparc32_dma_realize(DeviceState *dev, Error **errp)
+static void sparc32_dma_device_realize(DeviceState *dev, Error **errp)
 {
-DMAState *s = SPARC32_DMA(dev);
+DMADeviceState *s = SPARC32_DMA_DEVICE(dev);
 int reg_size;
 
 reg_size = s->is_ledma ? DMA_ETH_SIZE : DMA_SIZE;
@@ -294,35 +295,35 @@ static void sparc32_dma_realize(DeviceState *dev, Error 
**errp)
   "dma", reg_size);
 }
 
-static Property sparc32_dma_properties[] = {
-DEFINE_PROP_PTR("iommu_opaque", DMAState, iommu),
-

[Qemu-devel] [PATCHv3 07/13] esp: move TYPE_ESP and SysBusESPState from esp.c to esp.h

2017-10-14 Thread Mark Cave-Ayland
This enables them to be used outside of esp.c.

Signed-off-by: Mark Cave-Ayland 
CC: Paolo Bonzini 
---
 hw/scsi/esp.c |   13 -
 include/hw/scsi/esp.h |   14 ++
 2 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 22c2d91..ee586e7 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -592,19 +592,6 @@ const VMStateDescription vmstate_esp = {
 }
 };
 
-#define TYPE_ESP "esp"
-#define ESP_STATE(obj) OBJECT_CHECK(SysBusESPState, (obj), TYPE_ESP)
-
-typedef struct {
-/*< private >*/
-SysBusDevice parent_obj;
-/*< public >*/
-
-MemoryRegion iomem;
-uint32_t it_shift;
-ESPState esp;
-} SysBusESPState;
-
 static void sysbus_esp_mem_write(void *opaque, hwaddr addr,
  uint64_t val, unsigned int size)
 {
diff --git a/include/hw/scsi/esp.h b/include/hw/scsi/esp.h
index d2c4886..3b160f8 100644
--- a/include/hw/scsi/esp.h
+++ b/include/hw/scsi/esp.h
@@ -2,6 +2,7 @@
 #define QEMU_HW_ESP_H
 
 #include "hw/scsi/scsi.h"
+#include "hw/sysbus.h"
 
 /* esp.c */
 #define ESP_MAX_DEVS 7
@@ -52,6 +53,19 @@ struct ESPState {
 void (*dma_cb)(ESPState *s);
 };
 
+#define TYPE_ESP "esp"
+#define ESP_STATE(obj) OBJECT_CHECK(SysBusESPState, (obj), TYPE_ESP)
+
+typedef struct {
+/*< private >*/
+SysBusDevice parent_obj;
+/*< public >*/
+
+MemoryRegion iomem;
+uint32_t it_shift;
+ESPState esp;
+} SysBusESPState;
+
 #define ESP_TCLO   0x0
 #define ESP_TCMID  0x1
 #define ESP_FIFO   0x2
-- 
1.7.10.4




[Qemu-devel] [PATCHv3 05/13] sun4m_iommu: move TYPE_SUN4M_IOMMU declaration to sun4m.h

2017-10-14 Thread Mark Cave-Ayland
This is in preparation to allow the type to be used elsewhere.

Signed-off-by: Mark Cave-Ayland 
---
 hw/dma/sun4m_iommu.c |   14 --
 include/hw/sparc/sun4m.h |   16 
 2 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/hw/dma/sun4m_iommu.c b/hw/dma/sun4m_iommu.c
index 335ef63..840064b 100644
--- a/hw/dma/sun4m_iommu.c
+++ b/hw/dma/sun4m_iommu.c
@@ -36,7 +36,6 @@
  * 
http://mediacast.sun.com/users/Barton808/media/Sun4M_SystemArchitecture_edited2.pdf
  */
 
-#define IOMMU_NREGS (4*4096/4)
 #define IOMMU_CTRL  (0x >> 2)
 #define IOMMU_CTRL_IMPL 0xf000 /* Implementation */
 #define IOMMU_CTRL_VERS 0x0f00 /* Version */
@@ -128,19 +127,6 @@
 #define IOMMU_PAGE_SIZE (1 << IOMMU_PAGE_SHIFT)
 #define IOMMU_PAGE_MASK ~(IOMMU_PAGE_SIZE - 1)
 
-#define TYPE_SUN4M_IOMMU "iommu"
-#define SUN4M_IOMMU(obj) OBJECT_CHECK(IOMMUState, (obj), TYPE_SUN4M_IOMMU)
-
-typedef struct IOMMUState {
-SysBusDevice parent_obj;
-
-MemoryRegion iomem;
-uint32_t regs[IOMMU_NREGS];
-hwaddr iostart;
-qemu_irq irq;
-uint32_t version;
-} IOMMUState;
-
 static uint64_t iommu_mem_read(void *opaque, hwaddr addr,
unsigned size)
 {
diff --git a/include/hw/sparc/sun4m.h b/include/hw/sparc/sun4m.h
index 580d87b..1f1cf91 100644
--- a/include/hw/sparc/sun4m.h
+++ b/include/hw/sparc/sun4m.h
@@ -4,10 +4,26 @@
 #include "qemu-common.h"
 #include "exec/hwaddr.h"
 #include "qapi/qmp/types.h"
+#include "hw/sysbus.h"
 
 /* Devices used by sparc32 system.  */
 
 /* iommu.c */
+#define TYPE_SUN4M_IOMMU "iommu"
+#define SUN4M_IOMMU(obj) OBJECT_CHECK(IOMMUState, (obj), TYPE_SUN4M_IOMMU)
+
+#define IOMMU_NREGS (4 * 4096 / 4)
+
+typedef struct IOMMUState {
+SysBusDevice parent_obj;
+
+MemoryRegion iomem;
+uint32_t regs[IOMMU_NREGS];
+hwaddr iostart;
+qemu_irq irq;
+uint32_t version;
+} IOMMUState;
+
 void sparc_iommu_memory_rw(void *opaque, hwaddr addr,
  uint8_t *buf, int len, int is_write);
 static inline void sparc_iommu_memory_read(void *opaque,
-- 
1.7.10.4




[Qemu-devel] [PATCHv3 02/13] sparc32_dma: split esp and le into separate DMA devices

2017-10-14 Thread Mark Cave-Ayland
Due to slight differences in behaviour accessing the registers for the
esp and le devices, create two separate SPARC32_DMA_DEVICE types and
update the sun4m machine to use.

Note that by using different device types we already know the size of
the register block and the value of is_ledma at init time, allowing us to
drop the SPARC32_DMA_DEVICE realize function and the is_ledma device
property.

Signed-off-by: Mark Cave-Ayland 
---
 hw/dma/sparc32_dma.c |   63 --
 hw/sparc/sun4m.c |3 +--
 2 files changed, 52 insertions(+), 14 deletions(-)

diff --git a/hw/dma/sparc32_dma.c b/hw/dma/sparc32_dma.c
index a8d31c1..e4ff4a8 100644
--- a/hw/dma/sparc32_dma.c
+++ b/hw/dma/sparc32_dma.c
@@ -78,6 +78,22 @@ struct DMADeviceState {
 uint32_t is_ledma;
 };
 
+#define TYPE_SPARC32_ESPDMA_DEVICE "sparc32-espdma"
+#define SPARC32_ESPDMA_DEVICE(obj) OBJECT_CHECK(ESPDMADeviceState, (obj), \
+TYPE_SPARC32_ESPDMA_DEVICE)
+
+typedef struct ESPDMADeviceState {
+DMADeviceState parent_obj;
+} ESPDMADeviceState;
+
+#define TYPE_SPARC32_LEDMA_DEVICE "sparc32-ledma"
+#define SPARC32_LEDMA_DEVICE(obj) OBJECT_CHECK(LEDMADeviceState, (obj), \
+   TYPE_SPARC32_LEDMA_DEVICE)
+
+typedef struct LEDMADeviceState {
+DMADeviceState parent_obj;
+} LEDMADeviceState;
+
 enum {
 GPIO_RESET = 0,
 GPIO_DMA,
@@ -285,19 +301,8 @@ static void sparc32_dma_device_init(Object *obj)
 qdev_init_gpio_out(dev, s->gpio, 2);
 }
 
-static void sparc32_dma_device_realize(DeviceState *dev, Error **errp)
-{
-DMADeviceState *s = SPARC32_DMA_DEVICE(dev);
-int reg_size;
-
-reg_size = s->is_ledma ? DMA_ETH_SIZE : DMA_SIZE;
-memory_region_init_io(>iomem, OBJECT(dev), _mem_ops, s,
-  "dma", reg_size);
-}
-
 static Property sparc32_dma_device_properties[] = {
 DEFINE_PROP_PTR("iommu_opaque", DMADeviceState, iommu),
-DEFINE_PROP_UINT32("is_ledma", DMADeviceState, is_ledma, 0),
 DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -308,7 +313,6 @@ static void sparc32_dma_device_class_init(ObjectClass 
*klass, void *data)
 dc->reset = sparc32_dma_device_reset;
 dc->vmsd = _sparc32_dma_device;
 dc->props = sparc32_dma_device_properties;
-dc->realize = sparc32_dma_device_realize;
 /* Reason: pointer property "iommu_opaque" */
 dc->user_creatable = false;
 }
@@ -316,14 +320,49 @@ static void sparc32_dma_device_class_init(ObjectClass 
*klass, void *data)
 static const TypeInfo sparc32_dma_device_info = {
 .name  = TYPE_SPARC32_DMA_DEVICE,
 .parent= TYPE_SYS_BUS_DEVICE,
+.abstract  = true,
 .instance_size = sizeof(DMADeviceState),
 .instance_init = sparc32_dma_device_init,
 .class_init= sparc32_dma_device_class_init,
 };
 
+static void sparc32_espdma_device_init(Object *obj)
+{
+DMADeviceState *s = SPARC32_DMA_DEVICE(obj);
+
+memory_region_init_io(>iomem, OBJECT(s), _mem_ops, s,
+  "espdma-mmio", DMA_SIZE);
+s->is_ledma = 0;
+}
+
+static const TypeInfo sparc32_espdma_device_info = {
+.name  = TYPE_SPARC32_ESPDMA_DEVICE,
+.parent= TYPE_SPARC32_DMA_DEVICE,
+.instance_size = sizeof(ESPDMADeviceState),
+.instance_init = sparc32_espdma_device_init,
+};
+
+static void sparc32_ledma_device_init(Object *obj)
+{
+DMADeviceState *s = SPARC32_DMA_DEVICE(obj);
+
+memory_region_init_io(>iomem, OBJECT(s), _mem_ops, s,
+  "ledma-mmio", DMA_ETH_SIZE);
+s->is_ledma = 1;
+}
+
+static const TypeInfo sparc32_ledma_device_info = {
+.name  = TYPE_SPARC32_LEDMA_DEVICE,
+.parent= TYPE_SPARC32_DMA_DEVICE,
+.instance_size = sizeof(LEDMADeviceState),
+.instance_init = sparc32_ledma_device_init,
+};
+
 static void sparc32_dma_register_types(void)
 {
 type_register_static(_dma_device_info);
+type_register_static(_espdma_device_info);
+type_register_static(_ledma_device_info);
 }
 
 type_init(sparc32_dma_register_types)
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 82c553c..88a9752 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -313,9 +313,8 @@ static void *sparc32_dma_init(hwaddr daddr, qemu_irq 
parent_irq,
 DeviceState *dev;
 SysBusDevice *s;
 
-dev = qdev_create(NULL, "sparc32-dma-device");
+dev = qdev_create(NULL, is_ledma ? "sparc32-ledma" : "sparc32-espdma");
 qdev_prop_set_ptr(dev, "iommu_opaque", iommu);
-qdev_prop_set_uint32(dev, "is_ledma", is_ledma);
 qdev_init_nofail(dev);
 s = SYS_BUS_DEVICE(dev);
 sysbus_connect_irq(s, 0, parent_irq);
-- 
1.7.10.4




[Qemu-devel] [PATCHv3 06/13] sparc32_dma: use object link instead of qdev property to pass IOMMU reference

2017-10-14 Thread Mark Cave-Ayland
This enables us to remove the last remaining (opaque) qdev property. Whilst we
are here, also update iommu_init() to use TYPE_SUN4M_IOMMU instead of a
hardcoded string.

Signed-off-by: Mark Cave-Ayland 
---
 hw/dma/sparc32_dma.c |   13 +
 hw/sparc/sun4m.c |4 ++--
 2 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/hw/dma/sparc32_dma.c b/hw/dma/sparc32_dma.c
index ae8fa06..c56a2ba 100644
--- a/hw/dma/sparc32_dma.c
+++ b/hw/dma/sparc32_dma.c
@@ -263,24 +263,21 @@ static void sparc32_dma_device_init(Object *obj)
 
 sysbus_init_mmio(sbd, >iomem);
 
+object_property_add_link(OBJECT(dev), "iommu", TYPE_SUN4M_IOMMU,
+ (Object **) >iommu,
+ qdev_prop_allow_set_link_before_realize,
+ 0, NULL);
+
 qdev_init_gpio_in(dev, dma_set_irq, 1);
 qdev_init_gpio_out(dev, s->gpio, 2);
 }
 
-static Property sparc32_dma_device_properties[] = {
-DEFINE_PROP_PTR("iommu_opaque", DMADeviceState, iommu),
-DEFINE_PROP_END_OF_LIST(),
-};
-
 static void sparc32_dma_device_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
 
 dc->reset = sparc32_dma_device_reset;
 dc->vmsd = _sparc32_dma_device;
-dc->props = sparc32_dma_device_properties;
-/* Reason: pointer property "iommu_opaque" */
-dc->user_creatable = false;
 }
 
 static const TypeInfo sparc32_dma_device_info = {
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 4f2ed4b..12d36b5 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -297,7 +297,7 @@ static void *iommu_init(hwaddr addr, uint32_t version, 
qemu_irq irq)
 DeviceState *dev;
 SysBusDevice *s;
 
-dev = qdev_create(NULL, "iommu");
+dev = qdev_create(NULL, TYPE_SUN4M_IOMMU);
 qdev_prop_set_uint32(dev, "version", version);
 qdev_init_nofail(dev);
 s = SYS_BUS_DEVICE(dev);
@@ -313,7 +313,7 @@ static void *sparc32_dma_init(hwaddr daddr, void *iommu, 
int is_ledma)
 SysBusDevice *s;
 
 dev = qdev_create(NULL, is_ledma ? "sparc32-ledma" : "sparc32-espdma");
-qdev_prop_set_ptr(dev, "iommu_opaque", iommu);
+object_property_set_link(OBJECT(dev), OBJECT(iommu), "iommu", 
_abort);
 qdev_init_nofail(dev);
 s = SYS_BUS_DEVICE(dev);
 sysbus_mmio_map(s, 0, daddr);
-- 
1.7.10.4




[Qemu-devel] [PATCHv3 00/13] sun4m: sparc32_dma tidy-ups

2017-10-14 Thread Mark Cave-Ayland
This patchset aims to tidy-up the sparc32_dma code by improving the
modelling of the espdma/ledma devices using both QOM and the memory
API which didn't exist when the code was first written.

The result is that it is now possible to remove both the iommu_opaque
and is_ledma workarounds from the code, and the code for wiring up
the espdma/ledma and respective devices is also a lot more readable.

Signed-off-by: Mark Cave-Ayland 

v3:
- Add missing sysbus.h include to esp.h in patch 7

v2:
- Make esp/lance devices children of espdma/ledma devices respectively
- Add len parameter to ledma/espdma tracepoints

Mark Cave-Ayland (13):
  sparc32_dma: rename SPARC32_DMA type to SPARC32_DMA_DEVICE
  sparc32_dma: split esp and le into separate DMA devices
  sparc32_dma: move type declarations from sparc32_dma.c to
sparc32_dma.h
  sun4m: move DMA device wiring from sparc32_dma_init() to
sun4m_hw_init()
  sun4m_iommu: move TYPE_SUN4M_IOMMU declaration to sun4m.h
  sparc32_dma: use object link instead of qdev property to pass IOMMU
reference
  esp: move TYPE_ESP and SysBusESPState from esp.c to esp.h
  sparc32_dma: make esp device child of espdma device
  lance: move TYPE_LANCE and SysBusPCNetState from lance.c to sun4m.h
  sparc32_dma: make lance device child of ledma device
  sparc32_dma: introduce new SPARC32_DMA type container object
  sparc32_dma: remove is_ledma hack and replace with memory region
alias
  sparc32_dma: add len to esp/le DMA memory tracing

 hw/dma/sparc32_dma.c   |  236 +---
 hw/dma/sun4m_iommu.c   |   14 ---
 hw/dma/trace-events|8 +-
 hw/net/lance.c |9 --
 hw/scsi/esp.c  |   13 ---
 hw/sparc/sun4m.c   |   82 ++
 include/hw/scsi/esp.h  |   14 +++
 include/hw/sparc/sparc32_dma.h |   55 ++
 include/hw/sparc/sun4m.h   |   29 +
 9 files changed, 307 insertions(+), 153 deletions(-)

-- 
1.7.10.4




[Qemu-devel] [PATCHv3 04/13] sun4m: move DMA device wiring from sparc32_dma_init() to sun4m_hw_init()

2017-10-14 Thread Mark Cave-Ayland
By using the sysbus interface it is possible to wire up the esp/le devices
to the sun4m DMA controller directly during sun4m_hw_init() instead of
passing qemu_irqs into the sparc32_dma_init() function.

This is an intermediate step to allow further reorganisation as more logic
is moved into the relevant SPARC32 DMA devices; there will be a final
refactoring of sparc32_dma_init() once this work is complete.

Signed-off-by: Mark Cave-Ayland 
---
 hw/sparc/sun4m.c |   29 -
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 88a9752..4f2ed4b 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -307,8 +307,7 @@ static void *iommu_init(hwaddr addr, uint32_t version, 
qemu_irq irq)
 return s;
 }
 
-static void *sparc32_dma_init(hwaddr daddr, qemu_irq parent_irq,
-  void *iommu, qemu_irq *dev_irq, int is_ledma)
+static void *sparc32_dma_init(hwaddr daddr, void *iommu, int is_ledma)
 {
 DeviceState *dev;
 SysBusDevice *s;
@@ -317,8 +316,6 @@ static void *sparc32_dma_init(hwaddr daddr, qemu_irq 
parent_irq,
 qdev_prop_set_ptr(dev, "iommu_opaque", iommu);
 qdev_init_nofail(dev);
 s = SYS_BUS_DEVICE(dev);
-sysbus_connect_irq(s, 0, parent_irq);
-*dev_irq = qdev_get_gpio_in(dev, 0);
 sysbus_mmio_map(s, 0, daddr);
 
 return s;
@@ -821,9 +818,10 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
 DeviceState *slavio_intctl;
 const char *cpu_model = machine->cpu_model;
 unsigned int i;
-void *iommu, *espdma, *ledma, *nvram;
-qemu_irq *cpu_irqs[MAX_CPUS], slavio_irq[32], slavio_cpu_irq[MAX_CPUS],
-espdma_irq, ledma_irq;
+void *iommu, *nvram;
+DeviceState *espdma, *ledma;
+SysBusDevice *sbd;
+qemu_irq *cpu_irqs[MAX_CPUS], slavio_irq[32], slavio_cpu_irq[MAX_CPUS];
 qemu_irq esp_reset, dma_enable;
 qemu_irq fdc_tc;
 unsigned long kernel_size;
@@ -882,11 +880,13 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
 empty_slot_init(hwdef->iommu_pad_base,hwdef->iommu_pad_len);
 }
 
-espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[18],
-  iommu, _irq, 0);
+espdma = sparc32_dma_init(hwdef->dma_base, iommu, 0);
+sbd = SYS_BUS_DEVICE(espdma);
+sysbus_connect_irq(sbd, 0, slavio_irq[18]);
 
-ledma = sparc32_dma_init(hwdef->dma_base + 16ULL,
- slavio_irq[16], iommu, _irq, 1);
+ledma = sparc32_dma_init(hwdef->dma_base + 16ULL, iommu, 1);
+sbd = SYS_BUS_DEVICE(ledma);
+sysbus_connect_irq(sbd, 0, slavio_irq[16]);
 
 if (graphic_depth != 8 && graphic_depth != 24) {
 error_report("Unsupported depth: %d", graphic_depth);
@@ -939,7 +939,8 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
 empty_slot_init(hwdef->sx_base, 0x2000);
 }
 
-lance_init(_table[0], hwdef->le_base, ledma, ledma_irq);
+lance_init(_table[0], hwdef->le_base, ledma,
+   qdev_get_gpio_in(ledma, 0));
 
 nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0, 0x2000, 1968, 8);
 
@@ -971,7 +972,9 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
 
 esp_init(hwdef->esp_base, 2,
  espdma_memory_read, espdma_memory_write,
- espdma, espdma_irq, _reset, _enable);
+ espdma,
+ qdev_get_gpio_in(espdma, 0),
+ _reset, _enable);
 
 qdev_connect_gpio_out(espdma, 0, esp_reset);
 qdev_connect_gpio_out(espdma, 1, dma_enable);
-- 
1.7.10.4




[Qemu-devel] [PATCHv3 03/13] sparc32_dma: move type declarations from sparc32_dma.c to sparc32_dma.h

2017-10-14 Thread Mark Cave-Ayland
Signed-off-by: Mark Cave-Ayland 
---
 hw/dma/sparc32_dma.c   |   34 --
 include/hw/sparc/sparc32_dma.h |   37 +
 2 files changed, 37 insertions(+), 34 deletions(-)

diff --git a/hw/dma/sparc32_dma.c b/hw/dma/sparc32_dma.c
index e4ff4a8..ae8fa06 100644
--- a/hw/dma/sparc32_dma.c
+++ b/hw/dma/sparc32_dma.c
@@ -40,7 +40,6 @@
  * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/DMA2.txt
  */
 
-#define DMA_REGS 4
 #define DMA_SIZE (4 * sizeof(uint32_t))
 /* We need the mask, because one instance of the device is not page
aligned (ledma, start address 0x0010) */
@@ -61,39 +60,6 @@
 /* XXX SCSI and ethernet should have different read-only bit masks */
 #define DMA_CSR_RO_MASK 0xfe07
 
-#define TYPE_SPARC32_DMA_DEVICE "sparc32-dma-device"
-#define SPARC32_DMA_DEVICE(obj) OBJECT_CHECK(DMADeviceState, (obj), \
- TYPE_SPARC32_DMA_DEVICE)
-
-typedef struct DMADeviceState DMADeviceState;
-
-struct DMADeviceState {
-SysBusDevice parent_obj;
-
-MemoryRegion iomem;
-uint32_t dmaregs[DMA_REGS];
-qemu_irq irq;
-void *iommu;
-qemu_irq gpio[2];
-uint32_t is_ledma;
-};
-
-#define TYPE_SPARC32_ESPDMA_DEVICE "sparc32-espdma"
-#define SPARC32_ESPDMA_DEVICE(obj) OBJECT_CHECK(ESPDMADeviceState, (obj), \
-TYPE_SPARC32_ESPDMA_DEVICE)
-
-typedef struct ESPDMADeviceState {
-DMADeviceState parent_obj;
-} ESPDMADeviceState;
-
-#define TYPE_SPARC32_LEDMA_DEVICE "sparc32-ledma"
-#define SPARC32_LEDMA_DEVICE(obj) OBJECT_CHECK(LEDMADeviceState, (obj), \
-   TYPE_SPARC32_LEDMA_DEVICE)
-
-typedef struct LEDMADeviceState {
-DMADeviceState parent_obj;
-} LEDMADeviceState;
-
 enum {
 GPIO_RESET = 0,
 GPIO_DMA,
diff --git a/include/hw/sparc/sparc32_dma.h b/include/hw/sparc/sparc32_dma.h
index 9497b13..df7491d 100644
--- a/include/hw/sparc/sparc32_dma.h
+++ b/include/hw/sparc/sparc32_dma.h
@@ -1,6 +1,43 @@
 #ifndef SPARC32_DMA_H
 #define SPARC32_DMA_H
 
+#include "hw/sysbus.h"
+
+#define DMA_REGS 4
+
+#define TYPE_SPARC32_DMA_DEVICE "sparc32-dma-device"
+#define SPARC32_DMA_DEVICE(obj) OBJECT_CHECK(DMADeviceState, (obj), \
+ TYPE_SPARC32_DMA_DEVICE)
+
+typedef struct DMADeviceState DMADeviceState;
+
+struct DMADeviceState {
+SysBusDevice parent_obj;
+
+MemoryRegion iomem;
+uint32_t dmaregs[DMA_REGS];
+qemu_irq irq;
+void *iommu;
+qemu_irq gpio[2];
+uint32_t is_ledma;
+};
+
+#define TYPE_SPARC32_ESPDMA_DEVICE "sparc32-espdma"
+#define SPARC32_ESPDMA_DEVICE(obj) OBJECT_CHECK(ESPDMADeviceState, (obj), \
+TYPE_SPARC32_ESPDMA_DEVICE)
+
+typedef struct ESPDMADeviceState {
+DMADeviceState parent_obj;
+} ESPDMADeviceState;
+
+#define TYPE_SPARC32_LEDMA_DEVICE "sparc32-ledma"
+#define SPARC32_LEDMA_DEVICE(obj) OBJECT_CHECK(LEDMADeviceState, (obj), \
+   TYPE_SPARC32_LEDMA_DEVICE)
+
+typedef struct LEDMADeviceState {
+DMADeviceState parent_obj;
+} LEDMADeviceState;
+
 /* sparc32_dma.c */
 void ledma_memory_read(void *opaque, hwaddr addr,
uint8_t *buf, int len, int do_bswap);
-- 
1.7.10.4




Re: [Qemu-devel] [PATCHv2 00/13] sun4m: sparc32_dma tidy-ups

2017-10-14 Thread no-reply
Hi,

This series failed automatic build test. Please find the testing commands and
their output below. If you have docker installed, you can probably reproduce it
locally.

Type: series
Message-id: 1508004545-28578-1-git-send-email-mark.cave-ayl...@ilande.co.uk
Subject: [Qemu-devel] [PATCHv2 00/13] sun4m: sparc32_dma tidy-ups

=== TEST SCRIPT BEGIN ===
#!/bin/bash
set -e
git submodule update --init dtc
# Let docker tests dump environment info
export SHOW_ENV=1
export J=8
time make docker-test-quick@centos6
time make docker-test-build@min-glib
time make docker-test-mingw@fedora
time make docker-test-block@fedora
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 t [tag update]
patchew/1507816448-86665-1-git-send-email-pbonz...@redhat.com -> 
patchew/1507816448-86665-1-git-send-email-pbonz...@redhat.com
 t [tag update]
patchew/1507930220-17461-1-git-send-email-c...@braap.org -> 
patchew/1507930220-17461-1-git-send-email-c...@braap.org
 * [new tag]   
patchew/1508004545-28578-1-git-send-email-mark.cave-ayl...@ilande.co.uk -> 
patchew/1508004545-28578-1-git-send-email-mark.cave-ayl...@ilande.co.uk
 t [tag update]patchew/20171013054842.32120-1...@weilnetz.de -> 
patchew/20171013054842.32120-1...@weilnetz.de
 t [tag update]
patchew/20171013162438.32458-1-alex.ben...@linaro.org -> 
patchew/20171013162438.32458-1-alex.ben...@linaro.org
Switched to a new branch 'test'
750844c42d sparc32_dma: add len to esp/le DMA memory tracing
ba7ab63f8e sparc32_dma: remove is_ledma hack and replace with memory region 
alias
cf74bfb2aa sparc32_dma: introduce new SPARC32_DMA type container object
1a9feba778 sparc32_dma: make lance device child of ledma device
86b3305848 lance: move TYPE_LANCE and SysBusPCNetState from lance.c to sun4m.h
c5ae1c6011 sparc32_dma: make esp device child of espdma device
420993a6ce esp: move TYPE_ESP and SysBusESPState from esp.c to esp.h
236dbd4516 sparc32_dma: use object link instead of qdev property to pass IOMMU 
reference
5165f5669a sun4m_iommu: move TYPE_SUN4M_IOMMU declaration to sun4m.h
850a150983 sun4m: move DMA device wiring from sparc32_dma_init() to 
sun4m_hw_init()
4ba0c4c9f1 sparc32_dma: move type declarations from sparc32_dma.c to 
sparc32_dma.h
553bbcee17 sparc32_dma: split esp and le into separate DMA devices
dd74a83295 sparc32_dma: rename SPARC32_DMA type to SPARC32_DMA_DEVICE

=== OUTPUT BEGIN ===
Submodule 'dtc' (git://git.qemu-project.org/dtc.git) registered for path 'dtc'
Cloning into '/var/tmp/patchew-tester-tmp-4z0wtpem/src/dtc'...
Submodule path 'dtc': checked out '558cd81bdd432769b59bff01240c44f82cfb1a9d'
  BUILD   centos6
make[1]: Entering directory '/var/tmp/patchew-tester-tmp-4z0wtpem/src'
  GEN docker-src.2017-10-14-14.23.58.20533/qemu.tar
  COPYRUNNER
RUN test-quick in qemu:centos6 
Packages installed:
SDL-devel-1.2.14-7.el6_7.1.x86_64
bison-2.4.1-5.el6.x86_64
bzip2-devel-1.0.5-7.el6_0.x86_64
ccache-3.1.6-2.el6.x86_64
csnappy-devel-0-6.20150729gitd7bc683.el6.x86_64
flex-2.5.35-9.el6.x86_64
gcc-4.4.7-18.el6.x86_64
gettext-0.17-18.el6.x86_64
git-1.7.1-9.el6_9.x86_64
glib2-devel-2.28.8-9.el6.x86_64
libepoxy-devel-1.2-3.el6.x86_64
libfdt-devel-1.4.0-1.el6.x86_64
librdmacm-devel-1.0.21-0.el6.x86_64
lzo-devel-2.03-3.1.el6_5.1.x86_64
make-3.81-23.el6.x86_64
mesa-libEGL-devel-11.0.7-4.el6.x86_64
mesa-libgbm-devel-11.0.7-4.el6.x86_64
package g++ is not installed
pixman-devel-0.32.8-1.el6.x86_64
spice-glib-devel-0.26-8.el6.x86_64
spice-server-devel-0.12.4-16.el6.x86_64
tar-1.23-15.el6_8.x86_64
vte-devel-0.25.1-9.el6.x86_64
xen-devel-4.6.6-2.el6.x86_64
zlib-devel-1.2.3-29.el6.x86_64

Environment variables:
PACKAGES=bison bzip2-devel ccache csnappy-devel flex g++
 gcc gettext git glib2-devel libepoxy-devel libfdt-devel
 librdmacm-devel lzo-devel make mesa-libEGL-devel 
mesa-libgbm-devel pixman-devel SDL-devel spice-glib-devel 
spice-server-devel tar vte-devel xen-devel zlib-devel
HOSTNAME=2430be8c8daf
TERM=xterm
MAKEFLAGS= -j8
J=8
CCACHE_DIR=/var/tmp/ccache
EXTRA_CONFIGURE_OPTS=
V=
SHOW_ENV=1
PATH=/usr/lib/ccache:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
TARGET_LIST=
SHLVL=1
HOME=/root
TEST_DIR=/tmp/qemu-test
FEATURES= dtc
DEBUG=
_=/usr/bin/env

Configure options:
--enable-werror --target-list=x86_64-softmmu,aarch64-softmmu 
--prefix=/tmp/qemu-test/install
No C++ compiler available; disabling C++ specific optional code
Install prefix/tmp/qemu-test/install
BIOS directory/tmp/qemu-test/install/share/qemu
firmware path /tmp/qemu-test/install/share/qemu-firmware
binary directory  /tmp/qemu-test/install/bin
library directory /tmp/qemu-test/install/lib
module directory  /tmp/qemu-test/install/lib/qemu
libexec directory /tmp/qemu-test/install/libexec
include directory /tmp/qemu-test/install/include
config directory  

Re: [Qemu-devel] [PATCHv2 00/13] sun4m: sparc32_dma tidy-ups

2017-10-14 Thread no-reply
Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 1508004545-28578-1-git-send-email-mark.cave-ayl...@ilande.co.uk
Subject: [Qemu-devel] [PATCHv2 00/13] sun4m: sparc32_dma tidy-ups

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

git config --local diff.renamelimit 0
git config --local diff.renames True

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
failed=1
echo
fi
n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
750844c42d sparc32_dma: add len to esp/le DMA memory tracing
ba7ab63f8e sparc32_dma: remove is_ledma hack and replace with memory region 
alias
cf74bfb2aa sparc32_dma: introduce new SPARC32_DMA type container object
1a9feba778 sparc32_dma: make lance device child of ledma device
86b3305848 lance: move TYPE_LANCE and SysBusPCNetState from lance.c to sun4m.h
c5ae1c6011 sparc32_dma: make esp device child of espdma device
420993a6ce esp: move TYPE_ESP and SysBusESPState from esp.c to esp.h
236dbd4516 sparc32_dma: use object link instead of qdev property to pass IOMMU 
reference
5165f5669a sun4m_iommu: move TYPE_SUN4M_IOMMU declaration to sun4m.h
850a150983 sun4m: move DMA device wiring from sparc32_dma_init() to 
sun4m_hw_init()
4ba0c4c9f1 sparc32_dma: move type declarations from sparc32_dma.c to 
sparc32_dma.h
553bbcee17 sparc32_dma: split esp and le into separate DMA devices
dd74a83295 sparc32_dma: rename SPARC32_DMA type to SPARC32_DMA_DEVICE

=== OUTPUT BEGIN ===
Checking PATCH 1/13: sparc32_dma: rename SPARC32_DMA type to 
SPARC32_DMA_DEVICE...
Checking PATCH 2/13: sparc32_dma: split esp and le into separate DMA devices...
Checking PATCH 3/13: sparc32_dma: move type declarations from sparc32_dma.c to 
sparc32_dma.h...
Checking PATCH 4/13: sun4m: move DMA device wiring from sparc32_dma_init() to 
sun4m_hw_init()...
ERROR: spaces required around that '*' (ctx:WxV)
#51: FILE: hw/sparc/sun4m.c:824:
+qemu_irq *cpu_irqs[MAX_CPUS], slavio_irq[32], slavio_cpu_irq[MAX_CPUS];
  ^

total: 1 errors, 0 warnings, 66 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 5/13: sun4m_iommu: move TYPE_SUN4M_IOMMU declaration to 
sun4m.h...
Checking PATCH 6/13: sparc32_dma: use object link instead of qdev property to 
pass IOMMU reference...
Checking PATCH 7/13: esp: move TYPE_ESP and SysBusESPState from esp.c to 
esp.h...
Checking PATCH 8/13: sparc32_dma: make esp device child of espdma device...
Checking PATCH 9/13: lance: move TYPE_LANCE and SysBusPCNetState from lance.c 
to sun4m.h...
Checking PATCH 10/13: sparc32_dma: make lance device child of ledma device...
Checking PATCH 11/13: sparc32_dma: introduce new SPARC32_DMA type container 
object...
Checking PATCH 12/13: sparc32_dma: remove is_ledma hack and replace with memory 
region alias...
Checking PATCH 13/13: sparc32_dma: add len to esp/le DMA memory tracing...
=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-de...@freelists.org

[Qemu-devel] [PATCH 1/3] sun4m: implement IOMMU translation using IOMMU memory region

2017-10-14 Thread Mark Cave-Ayland
Signed-off-by: Mark Cave-Ayland 
---
 hw/dma/sun4m_iommu.c |   62 ++
 include/hw/sparc/sun4m.h |5 
 2 files changed, 67 insertions(+)

diff --git a/hw/dma/sun4m_iommu.c b/hw/dma/sun4m_iommu.c
index 840064b..ce21a22 100644
--- a/hw/dma/sun4m_iommu.c
+++ b/hw/dma/sun4m_iommu.c
@@ -278,6 +278,49 @@ static void iommu_bad_addr(IOMMUState *s, hwaddr addr,
 qemu_irq_raise(s->irq);
 }
 
+/* Called from RCU critical section */
+static IOMMUTLBEntry sun4m_translate_iommu(IOMMUMemoryRegion *iommu,
+   hwaddr addr,
+   IOMMUAccessFlags flags)
+{
+IOMMUState *is = container_of(iommu, IOMMUState, iommu);
+hwaddr page, pa;
+int is_write = (flags & IOMMU_WO) ? 1 : 0;
+uint32_t pte;
+IOMMUTLBEntry ret = {
+.target_as = _space_memory,
+.iova = 0,
+.translated_addr = 0,
+.addr_mask = ~(hwaddr)0,
+.perm = IOMMU_NONE,
+};
+
+page = addr & IOMMU_PAGE_MASK;
+pte = iommu_page_get_flags(is, page);
+if (!(pte & IOPTE_VALID)) {
+iommu_bad_addr(is, page, is_write);
+return ret;
+}
+
+pa = iommu_translate_pa(addr, pte);
+if (is_write && !(pte & IOPTE_WRITE)) {
+iommu_bad_addr(is, page, is_write);
+return ret;
+}
+
+if (pte & IOPTE_WRITE) {
+ret.perm = IOMMU_RW;
+} else {
+ret.perm = IOMMU_RO;
+}
+
+ret.iova = page;
+ret.translated_addr = pa;
+ret.addr_mask = ~IOMMU_PAGE_MASK;
+
+return ret;
+}
+
 void sparc_iommu_memory_rw(void *opaque, hwaddr addr,
uint8_t *buf, int len, int is_write)
 {
@@ -340,6 +383,11 @@ static void iommu_init(Object *obj)
 IOMMUState *s = SUN4M_IOMMU(obj);
 SysBusDevice *dev = SYS_BUS_DEVICE(obj);
 
+memory_region_init_iommu(>iommu, sizeof(s->iommu),
+ TYPE_SUN4M_IOMMU_MEMORY_REGION, OBJECT(dev),
+ "iommu-sun4m", UINT64_MAX);
+address_space_init(>iommu_as, MEMORY_REGION(>iommu), "iommu-as");
+
 sysbus_init_irq(dev, >irq);
 
 memory_region_init_io(>iomem, obj, _mem_ops, s, "iommu",
@@ -369,9 +417,23 @@ static const TypeInfo iommu_info = {
 .class_init= iommu_class_init,
 };
 
+static void sun4m_iommu_memory_region_class_init(ObjectClass *klass, void 
*data)
+{
+IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass);
+
+imrc->translate = sun4m_translate_iommu;
+}
+
+static const TypeInfo sun4m_iommu_memory_region_info = {
+.parent = TYPE_IOMMU_MEMORY_REGION,
+.name = TYPE_SUN4M_IOMMU_MEMORY_REGION,
+.class_init = sun4m_iommu_memory_region_class_init,
+};
+
 static void iommu_register_types(void)
 {
 type_register_static(_info);
+type_register_static(_iommu_memory_region_info);
 }
 
 type_init(iommu_register_types)
diff --git a/include/hw/sparc/sun4m.h b/include/hw/sparc/sun4m.h
index a4f5f09..0548bac 100644
--- a/include/hw/sparc/sun4m.h
+++ b/include/hw/sparc/sun4m.h
@@ -14,11 +14,16 @@
 #define TYPE_SUN4M_IOMMU "iommu"
 #define SUN4M_IOMMU(obj) OBJECT_CHECK(IOMMUState, (obj), TYPE_SUN4M_IOMMU)
 
+#define TYPE_SUN4M_IOMMU_MEMORY_REGION "sun4m-iommu-memory-region"
+
 #define IOMMU_NREGS (4 * 4096 / 4)
 
 typedef struct IOMMUState {
 SysBusDevice parent_obj;
 
+AddressSpace iommu_as;
+IOMMUMemoryRegion iommu;
+
 MemoryRegion iomem;
 uint32_t regs[IOMMU_NREGS];
 hwaddr iostart;
-- 
1.7.10.4




[Qemu-devel] [PATCH 2/3] sparc32_dma: switch over to using IOMMU memory region and DMA API

2017-10-14 Thread Mark Cave-Ayland
Signed-off-by: Mark Cave-Ayland 
---
 hw/dma/sparc32_dma.c |   17 +++--
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/hw/dma/sparc32_dma.c b/hw/dma/sparc32_dma.c
index fbb072a..5438831 100644
--- a/hw/dma/sparc32_dma.c
+++ b/hw/dma/sparc32_dma.c
@@ -29,6 +29,7 @@
 #include "hw/hw.h"
 #include "hw/sparc/sparc32_dma.h"
 #include "hw/sysbus.h"
+#include "sysemu/dma.h"
 #include "qapi/error.h"
 #include "trace.h"
 
@@ -70,16 +71,17 @@ void ledma_memory_read(void *opaque, hwaddr addr,
uint8_t *buf, int len, int do_bswap)
 {
 DMADeviceState *s = opaque;
+IOMMUState *is = (IOMMUState *)s->iommu;
 int i;
 
 addr |= s->dmaregs[3];
 trace_ledma_memory_read(addr, len);
 if (do_bswap) {
-sparc_iommu_memory_read(s->iommu, addr, buf, len);
+dma_memory_read(>iommu_as, addr, buf, len);
 } else {
 addr &= ~1;
 len &= ~1;
-sparc_iommu_memory_read(s->iommu, addr, buf, len);
+dma_memory_read(>iommu_as, addr, buf, len);
 for(i = 0; i < len; i += 2) {
 bswap16s((uint16_t *)(buf + i));
 }
@@ -90,13 +92,14 @@ void ledma_memory_write(void *opaque, hwaddr addr,
 uint8_t *buf, int len, int do_bswap)
 {
 DMADeviceState *s = opaque;
+IOMMUState *is = (IOMMUState *)s->iommu;
 int l, i;
 uint16_t tmp_buf[32];
 
 addr |= s->dmaregs[3];
 trace_ledma_memory_write(addr, len);
 if (do_bswap) {
-sparc_iommu_memory_write(s->iommu, addr, buf, len);
+dma_memory_write(>iommu_as, addr, buf, len);
 } else {
 addr &= ~1;
 len &= ~1;
@@ -107,7 +110,7 @@ void ledma_memory_write(void *opaque, hwaddr addr,
 for(i = 0; i < l; i += 2) {
 tmp_buf[i >> 1] = bswap16(*(uint16_t *)(buf + i));
 }
-sparc_iommu_memory_write(s->iommu, addr, (uint8_t *)tmp_buf, l);
+dma_memory_write(>iommu_as, addr, tmp_buf, l);
 len -= l;
 buf += l;
 addr += l;
@@ -138,18 +141,20 @@ static void dma_set_irq(void *opaque, int irq, int level)
 void espdma_memory_read(void *opaque, uint8_t *buf, int len)
 {
 DMADeviceState *s = opaque;
+IOMMUState *is = (IOMMUState *)s->iommu;
 
 trace_espdma_memory_read(s->dmaregs[1], len);
-sparc_iommu_memory_read(s->iommu, s->dmaregs[1], buf, len);
+dma_memory_read(>iommu_as, s->dmaregs[1], buf, len);
 s->dmaregs[1] += len;
 }
 
 void espdma_memory_write(void *opaque, uint8_t *buf, int len)
 {
 DMADeviceState *s = opaque;
+IOMMUState *is = (IOMMUState *)s->iommu;
 
 trace_espdma_memory_write(s->dmaregs[1], len);
-sparc_iommu_memory_write(s->iommu, s->dmaregs[1], buf, len);
+dma_memory_write(>iommu_as, s->dmaregs[1], buf, len);
 s->dmaregs[1] += len;
 }
 
-- 
1.7.10.4




[Qemu-devel] [PATCH 3/3] sun4m_iommu: remove legacy sparc_iommu_memory_rw() function

2017-10-14 Thread Mark Cave-Ayland
With the switch to the IOMMU memory region and DMA API, this is no longer
required.

Signed-off-by: Mark Cave-Ayland 
---
 hw/dma/sun4m_iommu.c |   33 -
 include/hw/sparc/sun4m.h |   16 
 2 files changed, 49 deletions(-)

diff --git a/hw/dma/sun4m_iommu.c b/hw/dma/sun4m_iommu.c
index ce21a22..30a05e8 100644
--- a/hw/dma/sun4m_iommu.c
+++ b/hw/dma/sun4m_iommu.c
@@ -321,39 +321,6 @@ static IOMMUTLBEntry 
sun4m_translate_iommu(IOMMUMemoryRegion *iommu,
 return ret;
 }
 
-void sparc_iommu_memory_rw(void *opaque, hwaddr addr,
-   uint8_t *buf, int len, int is_write)
-{
-int l;
-uint32_t flags;
-hwaddr page, phys_addr;
-
-while (len > 0) {
-page = addr & IOMMU_PAGE_MASK;
-l = (page + IOMMU_PAGE_SIZE) - addr;
-if (l > len)
-l = len;
-flags = iommu_page_get_flags(opaque, page);
-if (!(flags & IOPTE_VALID)) {
-iommu_bad_addr(opaque, page, is_write);
-return;
-}
-phys_addr = iommu_translate_pa(addr, flags);
-if (is_write) {
-if (!(flags & IOPTE_WRITE)) {
-iommu_bad_addr(opaque, page, is_write);
-return;
-}
-cpu_physical_memory_write(phys_addr, buf, l);
-} else {
-cpu_physical_memory_read(phys_addr, buf, l);
-}
-len -= l;
-buf += l;
-addr += l;
-}
-}
-
 static const VMStateDescription vmstate_iommu = {
 .name ="iommu",
 .version_id = 2,
diff --git a/include/hw/sparc/sun4m.h b/include/hw/sparc/sun4m.h
index 0548bac..662f86e 100644
--- a/include/hw/sparc/sun4m.h
+++ b/include/hw/sparc/sun4m.h
@@ -31,22 +31,6 @@ typedef struct IOMMUState {
 uint32_t version;
 } IOMMUState;
 
-void sparc_iommu_memory_rw(void *opaque, hwaddr addr,
- uint8_t *buf, int len, int is_write);
-static inline void sparc_iommu_memory_read(void *opaque,
-   hwaddr addr,
-   uint8_t *buf, int len)
-{
-sparc_iommu_memory_rw(opaque, addr, buf, len, 0);
-}
-
-static inline void sparc_iommu_memory_write(void *opaque,
-hwaddr addr,
-uint8_t *buf, int len)
-{
-sparc_iommu_memory_rw(opaque, addr, buf, len, 1);
-}
-
 /* lance.c */
 #define TYPE_LANCE "lance"
 #define SYSBUS_PCNET(obj) \
-- 
1.7.10.4




[Qemu-devel] [PATCH 0/3] sun4m: implement memory region IOMMU translation and DMA API

2017-10-14 Thread Mark Cave-Ayland
The original sun4m IOMMU/DMA code dates from before the introduction of the QEMU
memory region API (in particular IOMMU memory regions) and the DMA API.

This patchset removes these sun4m-specific implementations and replaces them 
with
the more up-to-date QEMU APIs instead.

Signed-off-by: Mark Cave-Ayland 
Based-on: 1508004545-28578-1-git-send-email-mark.cave-ayl...@ilande.co.uk 
([PATCHv2 00/13] sun4m: sparc32_dma tidy-ups)

Mark Cave-Ayland (3):
  sun4m: implement IOMMU translation using IOMMU memory region
  sparc32_dma: switch over to using IOMMU memory region and DMA API
  sun4m_iommu: remove legacy sparc_iommu_memory_rw() function

 hw/dma/sparc32_dma.c |   17 +
 hw/dma/sun4m_iommu.c |   87 ++
 include/hw/sparc/sun4m.h |   21 +++
 3 files changed, 74 insertions(+), 51 deletions(-)

-- 
1.7.10.4




[Qemu-devel] [PATCHv2 12/13] sparc32_dma: remove is_ledma hack and replace with memory region alias

2017-10-14 Thread Mark Cave-Ayland
This hack originated from before the memory region API was introduced, and
increased the size of the ledma DMA device to capture incorrect accesses
beyond the end of the ledma device. A full analysis can be found on Artyom's
blog at 
http://tyom.blogspot.co.uk/2010/10/bug-in-all-solaris-versions-after-57.html.

With the memory API we can now simply alias the incorrect access onto its
intended destination allowing us to remove the hack.

Signed-off-by: Mark Cave-Ayland 
---
 hw/dma/sparc32_dma.c   |   20 ++--
 include/hw/sparc/sparc32_dma.h |2 +-
 2 files changed, 7 insertions(+), 15 deletions(-)

diff --git a/hw/dma/sparc32_dma.c b/hw/dma/sparc32_dma.c
index ba62927..bb7d70a 100644
--- a/hw/dma/sparc32_dma.c
+++ b/hw/dma/sparc32_dma.c
@@ -159,12 +159,6 @@ static uint64_t dma_mem_read(void *opaque, hwaddr addr,
 DMADeviceState *s = opaque;
 uint32_t saddr;
 
-if (s->is_ledma && (addr > DMA_MAX_REG_OFFSET)) {
-/* aliased to espdma, but we can't get there from here */
-/* buggy driver if using undocumented behavior, just return 0 */
-trace_sparc32_dma_mem_readl(addr, 0);
-return 0;
-}
 saddr = (addr & DMA_MASK) >> 2;
 trace_sparc32_dma_mem_readl(addr, s->dmaregs[saddr]);
 return s->dmaregs[saddr];
@@ -176,11 +170,6 @@ static void dma_mem_write(void *opaque, hwaddr addr,
 DMADeviceState *s = opaque;
 uint32_t saddr;
 
-if (s->is_ledma && (addr > DMA_MAX_REG_OFFSET)) {
-/* aliased to espdma, but we can't get there from here */
-trace_sparc32_dma_mem_writel(addr, 0, val);
-return;
-}
 saddr = (addr & DMA_MASK) >> 2;
 trace_sparc32_dma_mem_writel(addr, s->dmaregs[saddr], val);
 switch (saddr) {
@@ -295,7 +284,6 @@ static void sparc32_espdma_device_init(Object *obj)
 
 memory_region_init_io(>iomem, OBJECT(s), _mem_ops, s,
   "espdma-mmio", DMA_SIZE);
-s->is_ledma = 0;
 }
 
 static void sparc32_espdma_device_realize(DeviceState *dev, Error **errp)
@@ -336,8 +324,7 @@ static void sparc32_ledma_device_init(Object *obj)
 DMADeviceState *s = SPARC32_DMA_DEVICE(obj);
 
 memory_region_init_io(>iomem, OBJECT(s), _mem_ops, s,
-  "ledma-mmio", DMA_ETH_SIZE);
-s->is_ledma = 1;
+  "ledma-mmio", DMA_SIZE);
 }
 
 static void sparc32_ledma_device_realize(DeviceState *dev, Error **errp)
@@ -410,6 +397,11 @@ static void sparc32_dma_realize(DeviceState *dev, Error 
**errp)
 sbd = SYS_BUS_DEVICE(ledma);
 memory_region_add_subregion(>dmamem, 0x10,
 sysbus_mmio_get_region(sbd, 0));
+
+/* Add ledma alias to handle SunOS 5.7 - Solaris 9 invalid access bug */
+memory_region_init_alias(>ledma_alias, OBJECT(dev), "ledma-alias",
+ sysbus_mmio_get_region(sbd, 0), 0x4, 0x4);
+memory_region_add_subregion(>dmamem, 0x20, >ledma_alias);
 }
 
 static void sparc32_dma_init(Object *obj)
diff --git a/include/hw/sparc/sparc32_dma.h b/include/hw/sparc/sparc32_dma.h
index e52cd1d..f78180f 100644
--- a/include/hw/sparc/sparc32_dma.h
+++ b/include/hw/sparc/sparc32_dma.h
@@ -21,7 +21,6 @@ struct DMADeviceState {
 qemu_irq irq;
 void *iommu;
 qemu_irq gpio[2];
-uint32_t is_ledma;
 };
 
 #define TYPE_SPARC32_ESPDMA_DEVICE "sparc32-espdma"
@@ -52,6 +51,7 @@ typedef struct SPARC32DMAState {
 SysBusDevice parent_obj;
 
 MemoryRegion dmamem;
+MemoryRegion ledma_alias;
 ESPDMADeviceState *espdma;
 LEDMADeviceState *ledma;
 } SPARC32DMAState;
-- 
1.7.10.4




[Qemu-devel] [PATCHv2 10/13] sparc32_dma: make lance device child of ledma device

2017-10-14 Thread Mark Cave-Ayland
This makes it possible to reference the lance device from the ledma device as
required.

Signed-off-by: Mark Cave-Ayland 
---
 hw/dma/sparc32_dma.c   |   23 ++-
 hw/sparc/sun4m.c   |   31 +++
 include/hw/sparc/sparc32_dma.h |3 +++
 3 files changed, 32 insertions(+), 25 deletions(-)

diff --git a/hw/dma/sparc32_dma.c b/hw/dma/sparc32_dma.c
index 6009b94..d507ca3 100644
--- a/hw/dma/sparc32_dma.c
+++ b/hw/dma/sparc32_dma.c
@@ -28,7 +28,6 @@
 #include "qemu/osdep.h"
 #include "hw/hw.h"
 #include "hw/sparc/sparc32_dma.h"
-#include "hw/sparc/sun4m.h"
 #include "hw/sysbus.h"
 #include "trace.h"
 
@@ -340,11 +339,33 @@ static void sparc32_ledma_device_init(Object *obj)
 s->is_ledma = 1;
 }
 
+static void sparc32_ledma_device_realize(DeviceState *dev, Error **errp)
+{
+DeviceState *d;
+NICInfo *nd = _table[0];
+
+qemu_check_nic_model(nd, "lance");
+
+d = qdev_create(NULL, "lance");
+object_property_add_child(OBJECT(dev), "lance", OBJECT(d), errp);
+qdev_set_nic_properties(d, nd);
+qdev_prop_set_ptr(d, "dma", dev);
+qdev_init_nofail(d);
+}
+
+static void sparc32_ledma_device_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->realize = sparc32_ledma_device_realize;
+}
+
 static const TypeInfo sparc32_ledma_device_info = {
 .name  = TYPE_SPARC32_LEDMA_DEVICE,
 .parent= TYPE_SPARC32_DMA_DEVICE,
 .instance_size = sizeof(LEDMADeviceState),
 .instance_init = sparc32_ledma_device_init,
+.class_init= sparc32_ledma_device_class_init,
 };
 
 static void sparc32_dma_register_types(void)
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 4626c85..ae486a4 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -321,26 +321,6 @@ static void *sparc32_dma_init(hwaddr daddr, void *iommu, 
int is_ledma)
 return s;
 }
 
-static void lance_init(NICInfo *nd, hwaddr leaddr,
-   void *dma_opaque, qemu_irq irq)
-{
-DeviceState *dev;
-SysBusDevice *s;
-qemu_irq reset;
-
-qemu_check_nic_model(_table[0], "lance");
-
-dev = qdev_create(NULL, "lance");
-qdev_set_nic_properties(dev, nd);
-qdev_prop_set_ptr(dev, "dma", dma_opaque);
-qdev_init_nofail(dev);
-s = SYS_BUS_DEVICE(dev);
-sysbus_mmio_map(s, 0, leaddr);
-sysbus_connect_irq(s, 0, irq);
-reset = qdev_get_gpio_in(dev, 0);
-qdev_connect_gpio_out(dma_opaque, 0, reset);
-}
-
 static DeviceState *slavio_intctl_init(hwaddr addr,
hwaddr addrg,
qemu_irq **parent_irq)
@@ -819,7 +799,7 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
 const char *cpu_model = machine->cpu_model;
 unsigned int i;
 void *iommu, *nvram;
-DeviceState *espdma, *esp, *ledma;
+DeviceState *espdma, *esp, *ledma, *lance;
 SysBusDevice *sbd;
 qemu_irq *cpu_irqs[MAX_CPUS], slavio_irq[32], slavio_cpu_irq[MAX_CPUS];
 qemu_irq fdc_tc;
@@ -894,6 +874,12 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
 sbd = SYS_BUS_DEVICE(ledma);
 sysbus_connect_irq(sbd, 0, slavio_irq[16]);
 
+lance = DEVICE(object_resolve_path_component(OBJECT(ledma), "lance"));
+sbd = SYS_BUS_DEVICE(lance);
+sysbus_mmio_map(sbd, 0, hwdef->le_base);
+sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(ledma, 0));
+qdev_connect_gpio_out(ledma, 0, qdev_get_gpio_in(lance, 0));
+
 if (graphic_depth != 8 && graphic_depth != 24) {
 error_report("Unsupported depth: %d", graphic_depth);
 exit (1);
@@ -945,9 +931,6 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
 empty_slot_init(hwdef->sx_base, 0x2000);
 }
 
-lance_init(_table[0], hwdef->le_base, ledma,
-   qdev_get_gpio_in(ledma, 0));
-
 nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0, 0x2000, 1968, 8);
 
 slavio_timer_init_all(hwdef->counter_base, slavio_irq[19], slavio_cpu_irq, 
smp_cpus);
diff --git a/include/hw/sparc/sparc32_dma.h b/include/hw/sparc/sparc32_dma.h
index 365160f..5f39c28 100644
--- a/include/hw/sparc/sparc32_dma.h
+++ b/include/hw/sparc/sparc32_dma.h
@@ -3,6 +3,7 @@
 
 #include "hw/sysbus.h"
 #include "hw/scsi/esp.h"
+#include "hw/sparc/sun4m.h"
 
 #define DMA_REGS 4
 
@@ -39,6 +40,8 @@ typedef struct ESPDMADeviceState {
 
 typedef struct LEDMADeviceState {
 DMADeviceState parent_obj;
+
+SysBusPCNetState *lance;
 } LEDMADeviceState;
 
 /* sparc32_dma.c */
-- 
1.7.10.4




[Qemu-devel] [PATCHv2 09/13] lance: move TYPE_LANCE and SysBusPCNetState from lance.c to sun4m.h

2017-10-14 Thread Mark Cave-Ayland
This enables them to be used outside of lance.c.

Signed-off-by: Mark Cave-Ayland 
CC: Jason Wang 
---
 hw/net/lance.c   |9 -
 include/hw/sparc/sun4m.h |   13 +
 2 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/hw/net/lance.c b/hw/net/lance.c
index 92b0c68..ef7747d 100644
--- a/hw/net/lance.c
+++ b/hw/net/lance.c
@@ -45,15 +45,6 @@
 #include "trace.h"
 #include "sysemu/sysemu.h"
 
-#define TYPE_LANCE "lance"
-#define SYSBUS_PCNET(obj) \
-OBJECT_CHECK(SysBusPCNetState, (obj), TYPE_LANCE)
-
-typedef struct {
-SysBusDevice parent_obj;
-
-PCNetState state;
-} SysBusPCNetState;
 
 static void parent_lance_reset(void *opaque, int irq, int level)
 {
diff --git a/include/hw/sparc/sun4m.h b/include/hw/sparc/sun4m.h
index 1f1cf91..a4f5f09 100644
--- a/include/hw/sparc/sun4m.h
+++ b/include/hw/sparc/sun4m.h
@@ -5,6 +5,8 @@
 #include "exec/hwaddr.h"
 #include "qapi/qmp/types.h"
 #include "hw/sysbus.h"
+#include "net/net.h"
+#include "hw/net/pcnet.h"
 
 /* Devices used by sparc32 system.  */
 
@@ -40,6 +42,17 @@ static inline void sparc_iommu_memory_write(void *opaque,
 sparc_iommu_memory_rw(opaque, addr, buf, len, 1);
 }
 
+/* lance.c */
+#define TYPE_LANCE "lance"
+#define SYSBUS_PCNET(obj) \
+OBJECT_CHECK(SysBusPCNetState, (obj), TYPE_LANCE)
+
+typedef struct {
+SysBusDevice parent_obj;
+
+PCNetState state;
+} SysBusPCNetState;
+
 /* sparc32_dma.c */
 #include "hw/sparc/sparc32_dma.h"
 
-- 
1.7.10.4




[Qemu-devel] [PATCHv2 08/13] sparc32_dma: make esp device child of espdma device

2017-10-14 Thread Mark Cave-Ayland
This makes it possible to reference the esp device from the espdma device as
required, and by wiring up the device ourselves in sun4m.c we can drop use
of the esp_init() function.

Signed-off-by: Mark Cave-Ayland 
---
 hw/dma/sparc32_dma.c   |   26 ++
 hw/sparc/sun4m.c   |   19 ---
 include/hw/sparc/sparc32_dma.h |3 +++
 3 files changed, 37 insertions(+), 11 deletions(-)

diff --git a/hw/dma/sparc32_dma.c b/hw/dma/sparc32_dma.c
index c56a2ba..6009b94 100644
--- a/hw/dma/sparc32_dma.c
+++ b/hw/dma/sparc32_dma.c
@@ -298,11 +298,37 @@ static void sparc32_espdma_device_init(Object *obj)
 s->is_ledma = 0;
 }
 
+static void sparc32_espdma_device_realize(DeviceState *dev, Error **errp)
+{
+DeviceState *d;
+SysBusESPState *sysbus;
+ESPState *esp;
+
+d = qdev_create(NULL, TYPE_ESP);
+object_property_add_child(OBJECT(dev), "esp", OBJECT(d), errp);
+sysbus = ESP_STATE(d);
+esp = >esp;
+esp->dma_memory_read = espdma_memory_read;
+esp->dma_memory_write = espdma_memory_write;
+esp->dma_opaque = SPARC32_DMA_DEVICE(dev);
+sysbus->it_shift = 2;
+esp->dma_enabled = 1;
+qdev_init_nofail(d);
+}
+
+static void sparc32_espdma_device_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->realize = sparc32_espdma_device_realize;
+}
+
 static const TypeInfo sparc32_espdma_device_info = {
 .name  = TYPE_SPARC32_ESPDMA_DEVICE,
 .parent= TYPE_SPARC32_DMA_DEVICE,
 .instance_size = sizeof(ESPDMADeviceState),
 .instance_init = sparc32_espdma_device_init,
+.class_init= sparc32_espdma_device_class_init,
 };
 
 static void sparc32_ledma_device_init(Object *obj)
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 12d36b5..4626c85 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -819,10 +819,9 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
 const char *cpu_model = machine->cpu_model;
 unsigned int i;
 void *iommu, *nvram;
-DeviceState *espdma, *ledma;
+DeviceState *espdma, *esp, *ledma;
 SysBusDevice *sbd;
 qemu_irq *cpu_irqs[MAX_CPUS], slavio_irq[32], slavio_cpu_irq[MAX_CPUS];
-qemu_irq esp_reset, dma_enable;
 qemu_irq fdc_tc;
 unsigned long kernel_size;
 DriveInfo *fd[MAX_FD];
@@ -884,6 +883,13 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
 sbd = SYS_BUS_DEVICE(espdma);
 sysbus_connect_irq(sbd, 0, slavio_irq[18]);
 
+esp = DEVICE(object_resolve_path_component(OBJECT(espdma), "esp"));
+sbd = SYS_BUS_DEVICE(esp);
+sysbus_mmio_map(sbd, 0, hwdef->esp_base);
+sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(espdma, 0));
+qdev_connect_gpio_out(espdma, 0, qdev_get_gpio_in(esp, 0));
+qdev_connect_gpio_out(espdma, 1, qdev_get_gpio_in(esp, 1));
+
 ledma = sparc32_dma_init(hwdef->dma_base + 16ULL, iommu, 1);
 sbd = SYS_BUS_DEVICE(ledma);
 sysbus_connect_irq(sbd, 0, slavio_irq[16]);
@@ -970,15 +976,6 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
 slavio_misc_init(hwdef->slavio_base, hwdef->aux1_base, hwdef->aux2_base,
  slavio_irq[30], fdc_tc);
 
-esp_init(hwdef->esp_base, 2,
- espdma_memory_read, espdma_memory_write,
- espdma,
- qdev_get_gpio_in(espdma, 0),
- _reset, _enable);
-
-qdev_connect_gpio_out(espdma, 0, esp_reset);
-qdev_connect_gpio_out(espdma, 1, dma_enable);
-
 if (hwdef->cs_base) {
 sysbus_create_simple("SUNW,CS4231", hwdef->cs_base,
  slavio_irq[5]);
diff --git a/include/hw/sparc/sparc32_dma.h b/include/hw/sparc/sparc32_dma.h
index df7491d..365160f 100644
--- a/include/hw/sparc/sparc32_dma.h
+++ b/include/hw/sparc/sparc32_dma.h
@@ -2,6 +2,7 @@
 #define SPARC32_DMA_H
 
 #include "hw/sysbus.h"
+#include "hw/scsi/esp.h"
 
 #define DMA_REGS 4
 
@@ -28,6 +29,8 @@ struct DMADeviceState {
 
 typedef struct ESPDMADeviceState {
 DMADeviceState parent_obj;
+
+SysBusESPState *esp;
 } ESPDMADeviceState;
 
 #define TYPE_SPARC32_LEDMA_DEVICE "sparc32-ledma"
-- 
1.7.10.4




[Qemu-devel] [PATCHv2 05/13] sun4m_iommu: move TYPE_SUN4M_IOMMU declaration to sun4m.h

2017-10-14 Thread Mark Cave-Ayland
This is in preparation to allow the type to be used elsewhere.

Signed-off-by: Mark Cave-Ayland 
---
 hw/dma/sun4m_iommu.c |   14 --
 include/hw/sparc/sun4m.h |   16 
 2 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/hw/dma/sun4m_iommu.c b/hw/dma/sun4m_iommu.c
index 335ef63..840064b 100644
--- a/hw/dma/sun4m_iommu.c
+++ b/hw/dma/sun4m_iommu.c
@@ -36,7 +36,6 @@
  * 
http://mediacast.sun.com/users/Barton808/media/Sun4M_SystemArchitecture_edited2.pdf
  */
 
-#define IOMMU_NREGS (4*4096/4)
 #define IOMMU_CTRL  (0x >> 2)
 #define IOMMU_CTRL_IMPL 0xf000 /* Implementation */
 #define IOMMU_CTRL_VERS 0x0f00 /* Version */
@@ -128,19 +127,6 @@
 #define IOMMU_PAGE_SIZE (1 << IOMMU_PAGE_SHIFT)
 #define IOMMU_PAGE_MASK ~(IOMMU_PAGE_SIZE - 1)
 
-#define TYPE_SUN4M_IOMMU "iommu"
-#define SUN4M_IOMMU(obj) OBJECT_CHECK(IOMMUState, (obj), TYPE_SUN4M_IOMMU)
-
-typedef struct IOMMUState {
-SysBusDevice parent_obj;
-
-MemoryRegion iomem;
-uint32_t regs[IOMMU_NREGS];
-hwaddr iostart;
-qemu_irq irq;
-uint32_t version;
-} IOMMUState;
-
 static uint64_t iommu_mem_read(void *opaque, hwaddr addr,
unsigned size)
 {
diff --git a/include/hw/sparc/sun4m.h b/include/hw/sparc/sun4m.h
index 580d87b..1f1cf91 100644
--- a/include/hw/sparc/sun4m.h
+++ b/include/hw/sparc/sun4m.h
@@ -4,10 +4,26 @@
 #include "qemu-common.h"
 #include "exec/hwaddr.h"
 #include "qapi/qmp/types.h"
+#include "hw/sysbus.h"
 
 /* Devices used by sparc32 system.  */
 
 /* iommu.c */
+#define TYPE_SUN4M_IOMMU "iommu"
+#define SUN4M_IOMMU(obj) OBJECT_CHECK(IOMMUState, (obj), TYPE_SUN4M_IOMMU)
+
+#define IOMMU_NREGS (4 * 4096 / 4)
+
+typedef struct IOMMUState {
+SysBusDevice parent_obj;
+
+MemoryRegion iomem;
+uint32_t regs[IOMMU_NREGS];
+hwaddr iostart;
+qemu_irq irq;
+uint32_t version;
+} IOMMUState;
+
 void sparc_iommu_memory_rw(void *opaque, hwaddr addr,
  uint8_t *buf, int len, int is_write);
 static inline void sparc_iommu_memory_read(void *opaque,
-- 
1.7.10.4




[Qemu-devel] [PATCHv2 13/13] sparc32_dma: add len to esp/le DMA memory tracing

2017-10-14 Thread Mark Cave-Ayland
This is surprisingly useful when trying to debug DMA issues.

Signed-off-by: Mark Cave-Ayland 
---
 hw/dma/sparc32_dma.c |8 
 hw/dma/trace-events  |8 
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/hw/dma/sparc32_dma.c b/hw/dma/sparc32_dma.c
index bb7d70a..fbb072a 100644
--- a/hw/dma/sparc32_dma.c
+++ b/hw/dma/sparc32_dma.c
@@ -73,7 +73,7 @@ void ledma_memory_read(void *opaque, hwaddr addr,
 int i;
 
 addr |= s->dmaregs[3];
-trace_ledma_memory_read(addr);
+trace_ledma_memory_read(addr, len);
 if (do_bswap) {
 sparc_iommu_memory_read(s->iommu, addr, buf, len);
 } else {
@@ -94,7 +94,7 @@ void ledma_memory_write(void *opaque, hwaddr addr,
 uint16_t tmp_buf[32];
 
 addr |= s->dmaregs[3];
-trace_ledma_memory_write(addr);
+trace_ledma_memory_write(addr, len);
 if (do_bswap) {
 sparc_iommu_memory_write(s->iommu, addr, buf, len);
 } else {
@@ -139,7 +139,7 @@ void espdma_memory_read(void *opaque, uint8_t *buf, int len)
 {
 DMADeviceState *s = opaque;
 
-trace_espdma_memory_read(s->dmaregs[1]);
+trace_espdma_memory_read(s->dmaregs[1], len);
 sparc_iommu_memory_read(s->iommu, s->dmaregs[1], buf, len);
 s->dmaregs[1] += len;
 }
@@ -148,7 +148,7 @@ void espdma_memory_write(void *opaque, uint8_t *buf, int 
len)
 {
 DMADeviceState *s = opaque;
 
-trace_espdma_memory_write(s->dmaregs[1]);
+trace_espdma_memory_write(s->dmaregs[1], len);
 sparc_iommu_memory_write(s->iommu, s->dmaregs[1], buf, len);
 s->dmaregs[1] += len;
 }
diff --git a/hw/dma/trace-events b/hw/dma/trace-events
index 428469a..6b367f0 100644
--- a/hw/dma/trace-events
+++ b/hw/dma/trace-events
@@ -7,12 +7,12 @@ rc4030_read(uint64_t addr, uint32_t ret) "read 
reg[0x%"PRIx64"] = 0x%x"
 rc4030_write(uint64_t addr, uint32_t val) "write reg[0x%"PRIx64"] = 0x%x"
 
 # hw/dma/sparc32_dma.c
-ledma_memory_read(uint64_t addr) "DMA read addr 0x%"PRIx64
-ledma_memory_write(uint64_t addr) "DMA write addr 0x%"PRIx64
+ledma_memory_read(uint64_t addr, int len) "DMA read addr 0x%"PRIx64 " len %d"
+ledma_memory_write(uint64_t addr, int len) "DMA write addr 0x%"PRIx64 " len %d"
 sparc32_dma_set_irq_raise(void) "Raise IRQ"
 sparc32_dma_set_irq_lower(void) "Lower IRQ"
-espdma_memory_read(uint32_t addr) "DMA read addr 0x%08x"
-espdma_memory_write(uint32_t addr) "DMA write addr 0x%08x"
+espdma_memory_read(uint32_t addr, int len) "DMA read addr 0x%08x len %d"
+espdma_memory_write(uint32_t addr, int len) "DMA write addr 0x%08x len %d"
 sparc32_dma_mem_readl(uint64_t addr, uint32_t ret) "read dmareg 0x%"PRIx64": 
0x%08x"
 sparc32_dma_mem_writel(uint64_t addr, uint32_t old, uint32_t val) "write 
dmareg 0x%"PRIx64": 0x%08x -> 0x%08x"
 sparc32_dma_enable_raise(void) "Raise DMA enable"
-- 
1.7.10.4




[Qemu-devel] [PATCHv2 11/13] sparc32_dma: introduce new SPARC32_DMA type container object

2017-10-14 Thread Mark Cave-Ayland
Create a new SPARC32_DMA container object (including an appropriate container
memory region) and add instances of the SPARC32_ESPDMA_DEVICE and
SPARC32_LEDMA_DEVICE as child objects. The benefit is that most of the gpio
wiring complexity between esp/espdma and lance/ledma is now hidden within the
SPARC32_DMA realize function.

Since the sun4m IOMMU is already QOMified we can find a reference to
it using object_resolve_path_type() allowing us to completely remove all 
external
references to the iommu pointer.

Finally we rework sun4m's sparc32_dma_init() to invoke the new SPARC32_DMA 
object
and wire up the remaining board memory regions/IRQs.

Signed-off-by: Mark Cave-Ayland 
---
 hw/dma/sparc32_dma.c   |   70 
 hw/sparc/sun4m.c   |   66 ++---
 include/hw/sparc/sparc32_dma.h |   12 +++
 3 files changed, 114 insertions(+), 34 deletions(-)

diff --git a/hw/dma/sparc32_dma.c b/hw/dma/sparc32_dma.c
index d507ca3..ba62927 100644
--- a/hw/dma/sparc32_dma.c
+++ b/hw/dma/sparc32_dma.c
@@ -29,6 +29,7 @@
 #include "hw/hw.h"
 #include "hw/sparc/sparc32_dma.h"
 #include "hw/sysbus.h"
+#include "qapi/error.h"
 #include "trace.h"
 
 /*
@@ -368,11 +369,80 @@ static const TypeInfo sparc32_ledma_device_info = {
 .class_init= sparc32_ledma_device_class_init,
 };
 
+static void sparc32_dma_realize(DeviceState *dev, Error **errp)
+{
+SPARC32DMAState *s = SPARC32_DMA(dev);
+DeviceState *espdma, *esp, *ledma, *lance;
+SysBusDevice *sbd;
+Object *iommu;
+
+iommu = object_resolve_path_type("", TYPE_SUN4M_IOMMU, NULL);
+if (!iommu) {
+error_setg(errp, "unable to locate sun4m IOMMU device");
+return;
+}
+
+espdma = qdev_create(NULL, TYPE_SPARC32_ESPDMA_DEVICE);
+object_property_set_link(OBJECT(espdma), iommu, "iommu", errp);
+object_property_add_child(OBJECT(s), "espdma", OBJECT(espdma), errp);
+qdev_init_nofail(espdma);
+
+esp = DEVICE(object_resolve_path_component(OBJECT(espdma), "esp"));
+sbd = SYS_BUS_DEVICE(esp);
+sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(espdma, 0));
+qdev_connect_gpio_out(espdma, 0, qdev_get_gpio_in(esp, 0));
+qdev_connect_gpio_out(espdma, 1, qdev_get_gpio_in(esp, 1));
+
+sbd = SYS_BUS_DEVICE(espdma);
+memory_region_add_subregion(>dmamem, 0x0,
+sysbus_mmio_get_region(sbd, 0));
+
+ledma = qdev_create(NULL, TYPE_SPARC32_LEDMA_DEVICE);
+object_property_set_link(OBJECT(ledma), iommu, "iommu", errp);
+object_property_add_child(OBJECT(s), "ledma", OBJECT(ledma), errp);
+qdev_init_nofail(ledma);
+
+lance = DEVICE(object_resolve_path_component(OBJECT(ledma), "lance"));
+sbd = SYS_BUS_DEVICE(lance);
+sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(ledma, 0));
+qdev_connect_gpio_out(ledma, 0, qdev_get_gpio_in(lance, 0));
+
+sbd = SYS_BUS_DEVICE(ledma);
+memory_region_add_subregion(>dmamem, 0x10,
+sysbus_mmio_get_region(sbd, 0));
+}
+
+static void sparc32_dma_init(Object *obj)
+{
+SPARC32DMAState *s = SPARC32_DMA(obj);
+SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+
+memory_region_init(>dmamem, OBJECT(s), "dma", DMA_SIZE + DMA_ETH_SIZE);
+sysbus_init_mmio(sbd, >dmamem);
+}
+
+static void sparc32_dma_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->realize = sparc32_dma_realize;
+}
+
+static const TypeInfo sparc32_dma_info = {
+.name  = TYPE_SPARC32_DMA,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(SPARC32DMAState),
+.instance_init = sparc32_dma_init,
+.class_init= sparc32_dma_class_init,
+};
+
+
 static void sparc32_dma_register_types(void)
 {
 type_register_static(_dma_device_info);
 type_register_static(_espdma_device_info);
 type_register_static(_ledma_device_info);
+type_register_static(_dma_info);
 }
 
 type_init(sparc32_dma_register_types)
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index ae486a4..5017ae5 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -307,18 +307,36 @@ static void *iommu_init(hwaddr addr, uint32_t version, 
qemu_irq irq)
 return s;
 }
 
-static void *sparc32_dma_init(hwaddr daddr, void *iommu, int is_ledma)
+static void *sparc32_dma_init(hwaddr dma_base,
+  hwaddr esp_base, qemu_irq espdma_irq,
+  hwaddr le_base, qemu_irq ledma_irq)
 {
-DeviceState *dev;
-SysBusDevice *s;
+DeviceState *dma;
+ESPDMADeviceState *espdma;
+LEDMADeviceState *ledma;
+SysBusESPState *esp;
+SysBusPCNetState *lance;
 
-dev = qdev_create(NULL, is_ledma ? "sparc32-ledma" : "sparc32-espdma");
-object_property_set_link(OBJECT(dev), OBJECT(iommu), "iommu", 
_abort);
-qdev_init_nofail(dev);
-s = SYS_BUS_DEVICE(dev);
-sysbus_mmio_map(s, 0, daddr);
+dma = 

[Qemu-devel] [PATCHv2 03/13] sparc32_dma: move type declarations from sparc32_dma.c to sparc32_dma.h

2017-10-14 Thread Mark Cave-Ayland
Signed-off-by: Mark Cave-Ayland 
---
 hw/dma/sparc32_dma.c   |   34 --
 include/hw/sparc/sparc32_dma.h |   37 +
 2 files changed, 37 insertions(+), 34 deletions(-)

diff --git a/hw/dma/sparc32_dma.c b/hw/dma/sparc32_dma.c
index e4ff4a8..ae8fa06 100644
--- a/hw/dma/sparc32_dma.c
+++ b/hw/dma/sparc32_dma.c
@@ -40,7 +40,6 @@
  * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/DMA2.txt
  */
 
-#define DMA_REGS 4
 #define DMA_SIZE (4 * sizeof(uint32_t))
 /* We need the mask, because one instance of the device is not page
aligned (ledma, start address 0x0010) */
@@ -61,39 +60,6 @@
 /* XXX SCSI and ethernet should have different read-only bit masks */
 #define DMA_CSR_RO_MASK 0xfe07
 
-#define TYPE_SPARC32_DMA_DEVICE "sparc32-dma-device"
-#define SPARC32_DMA_DEVICE(obj) OBJECT_CHECK(DMADeviceState, (obj), \
- TYPE_SPARC32_DMA_DEVICE)
-
-typedef struct DMADeviceState DMADeviceState;
-
-struct DMADeviceState {
-SysBusDevice parent_obj;
-
-MemoryRegion iomem;
-uint32_t dmaregs[DMA_REGS];
-qemu_irq irq;
-void *iommu;
-qemu_irq gpio[2];
-uint32_t is_ledma;
-};
-
-#define TYPE_SPARC32_ESPDMA_DEVICE "sparc32-espdma"
-#define SPARC32_ESPDMA_DEVICE(obj) OBJECT_CHECK(ESPDMADeviceState, (obj), \
-TYPE_SPARC32_ESPDMA_DEVICE)
-
-typedef struct ESPDMADeviceState {
-DMADeviceState parent_obj;
-} ESPDMADeviceState;
-
-#define TYPE_SPARC32_LEDMA_DEVICE "sparc32-ledma"
-#define SPARC32_LEDMA_DEVICE(obj) OBJECT_CHECK(LEDMADeviceState, (obj), \
-   TYPE_SPARC32_LEDMA_DEVICE)
-
-typedef struct LEDMADeviceState {
-DMADeviceState parent_obj;
-} LEDMADeviceState;
-
 enum {
 GPIO_RESET = 0,
 GPIO_DMA,
diff --git a/include/hw/sparc/sparc32_dma.h b/include/hw/sparc/sparc32_dma.h
index 9497b13..df7491d 100644
--- a/include/hw/sparc/sparc32_dma.h
+++ b/include/hw/sparc/sparc32_dma.h
@@ -1,6 +1,43 @@
 #ifndef SPARC32_DMA_H
 #define SPARC32_DMA_H
 
+#include "hw/sysbus.h"
+
+#define DMA_REGS 4
+
+#define TYPE_SPARC32_DMA_DEVICE "sparc32-dma-device"
+#define SPARC32_DMA_DEVICE(obj) OBJECT_CHECK(DMADeviceState, (obj), \
+ TYPE_SPARC32_DMA_DEVICE)
+
+typedef struct DMADeviceState DMADeviceState;
+
+struct DMADeviceState {
+SysBusDevice parent_obj;
+
+MemoryRegion iomem;
+uint32_t dmaregs[DMA_REGS];
+qemu_irq irq;
+void *iommu;
+qemu_irq gpio[2];
+uint32_t is_ledma;
+};
+
+#define TYPE_SPARC32_ESPDMA_DEVICE "sparc32-espdma"
+#define SPARC32_ESPDMA_DEVICE(obj) OBJECT_CHECK(ESPDMADeviceState, (obj), \
+TYPE_SPARC32_ESPDMA_DEVICE)
+
+typedef struct ESPDMADeviceState {
+DMADeviceState parent_obj;
+} ESPDMADeviceState;
+
+#define TYPE_SPARC32_LEDMA_DEVICE "sparc32-ledma"
+#define SPARC32_LEDMA_DEVICE(obj) OBJECT_CHECK(LEDMADeviceState, (obj), \
+   TYPE_SPARC32_LEDMA_DEVICE)
+
+typedef struct LEDMADeviceState {
+DMADeviceState parent_obj;
+} LEDMADeviceState;
+
 /* sparc32_dma.c */
 void ledma_memory_read(void *opaque, hwaddr addr,
uint8_t *buf, int len, int do_bswap);
-- 
1.7.10.4




[Qemu-devel] [PATCHv2 01/13] sparc32_dma: rename SPARC32_DMA type to SPARC32_DMA_DEVICE

2017-10-14 Thread Mark Cave-Ayland
Also update the function names to match as appropriate. While we're
here rename the type from sparc32_dma to sparc32-dma in order to
match the current QOM convention.

Signed-off-by: Mark Cave-Ayland 
---
 hw/dma/sparc32_dma.c |   67 +-
 hw/sparc/sun4m.c |2 +-
 2 files changed, 35 insertions(+), 34 deletions(-)

diff --git a/hw/dma/sparc32_dma.c b/hw/dma/sparc32_dma.c
index eb491b5..a8d31c1 100644
--- a/hw/dma/sparc32_dma.c
+++ b/hw/dma/sparc32_dma.c
@@ -61,12 +61,13 @@
 /* XXX SCSI and ethernet should have different read-only bit masks */
 #define DMA_CSR_RO_MASK 0xfe07
 
-#define TYPE_SPARC32_DMA "sparc32_dma"
-#define SPARC32_DMA(obj) OBJECT_CHECK(DMAState, (obj), TYPE_SPARC32_DMA)
+#define TYPE_SPARC32_DMA_DEVICE "sparc32-dma-device"
+#define SPARC32_DMA_DEVICE(obj) OBJECT_CHECK(DMADeviceState, (obj), \
+ TYPE_SPARC32_DMA_DEVICE)
 
-typedef struct DMAState DMAState;
+typedef struct DMADeviceState DMADeviceState;
 
-struct DMAState {
+struct DMADeviceState {
 SysBusDevice parent_obj;
 
 MemoryRegion iomem;
@@ -86,7 +87,7 @@ enum {
 void ledma_memory_read(void *opaque, hwaddr addr,
uint8_t *buf, int len, int do_bswap)
 {
-DMAState *s = opaque;
+DMADeviceState *s = opaque;
 int i;
 
 addr |= s->dmaregs[3];
@@ -106,7 +107,7 @@ void ledma_memory_read(void *opaque, hwaddr addr,
 void ledma_memory_write(void *opaque, hwaddr addr,
 uint8_t *buf, int len, int do_bswap)
 {
-DMAState *s = opaque;
+DMADeviceState *s = opaque;
 int l, i;
 uint16_t tmp_buf[32];
 
@@ -134,7 +135,7 @@ void ledma_memory_write(void *opaque, hwaddr addr,
 
 static void dma_set_irq(void *opaque, int irq, int level)
 {
-DMAState *s = opaque;
+DMADeviceState *s = opaque;
 if (level) {
 s->dmaregs[0] |= DMA_INTR;
 if (s->dmaregs[0] & DMA_INTREN) {
@@ -154,7 +155,7 @@ static void dma_set_irq(void *opaque, int irq, int level)
 
 void espdma_memory_read(void *opaque, uint8_t *buf, int len)
 {
-DMAState *s = opaque;
+DMADeviceState *s = opaque;
 
 trace_espdma_memory_read(s->dmaregs[1]);
 sparc_iommu_memory_read(s->iommu, s->dmaregs[1], buf, len);
@@ -163,7 +164,7 @@ void espdma_memory_read(void *opaque, uint8_t *buf, int len)
 
 void espdma_memory_write(void *opaque, uint8_t *buf, int len)
 {
-DMAState *s = opaque;
+DMADeviceState *s = opaque;
 
 trace_espdma_memory_write(s->dmaregs[1]);
 sparc_iommu_memory_write(s->iommu, s->dmaregs[1], buf, len);
@@ -173,7 +174,7 @@ void espdma_memory_write(void *opaque, uint8_t *buf, int 
len)
 static uint64_t dma_mem_read(void *opaque, hwaddr addr,
  unsigned size)
 {
-DMAState *s = opaque;
+DMADeviceState *s = opaque;
 uint32_t saddr;
 
 if (s->is_ledma && (addr > DMA_MAX_REG_OFFSET)) {
@@ -190,7 +191,7 @@ static uint64_t dma_mem_read(void *opaque, hwaddr addr,
 static void dma_mem_write(void *opaque, hwaddr addr,
   uint64_t val, unsigned size)
 {
-DMAState *s = opaque;
+DMADeviceState *s = opaque;
 uint32_t saddr;
 
 if (s->is_ledma && (addr > DMA_MAX_REG_OFFSET)) {
@@ -252,28 +253,28 @@ static const MemoryRegionOps dma_mem_ops = {
 },
 };
 
-static void dma_reset(DeviceState *d)
+static void sparc32_dma_device_reset(DeviceState *d)
 {
-DMAState *s = SPARC32_DMA(d);
+DMADeviceState *s = SPARC32_DMA_DEVICE(d);
 
 memset(s->dmaregs, 0, DMA_SIZE);
 s->dmaregs[0] = DMA_VER;
 }
 
-static const VMStateDescription vmstate_dma = {
+static const VMStateDescription vmstate_sparc32_dma_device = {
 .name ="sparc32_dma",
 .version_id = 2,
 .minimum_version_id = 2,
 .fields = (VMStateField[]) {
-VMSTATE_UINT32_ARRAY(dmaregs, DMAState, DMA_REGS),
+VMSTATE_UINT32_ARRAY(dmaregs, DMADeviceState, DMA_REGS),
 VMSTATE_END_OF_LIST()
 }
 };
 
-static void sparc32_dma_init(Object *obj)
+static void sparc32_dma_device_init(Object *obj)
 {
 DeviceState *dev = DEVICE(obj);
-DMAState *s = SPARC32_DMA(obj);
+DMADeviceState *s = SPARC32_DMA_DEVICE(obj);
 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
 
 sysbus_init_irq(sbd, >irq);
@@ -284,9 +285,9 @@ static void sparc32_dma_init(Object *obj)
 qdev_init_gpio_out(dev, s->gpio, 2);
 }
 
-static void sparc32_dma_realize(DeviceState *dev, Error **errp)
+static void sparc32_dma_device_realize(DeviceState *dev, Error **errp)
 {
-DMAState *s = SPARC32_DMA(dev);
+DMADeviceState *s = SPARC32_DMA_DEVICE(dev);
 int reg_size;
 
 reg_size = s->is_ledma ? DMA_ETH_SIZE : DMA_SIZE;
@@ -294,35 +295,35 @@ static void sparc32_dma_realize(DeviceState *dev, Error 
**errp)
   "dma", reg_size);
 }
 
-static Property sparc32_dma_properties[] = {
-DEFINE_PROP_PTR("iommu_opaque", DMAState, iommu),
-

[Qemu-devel] [PATCHv2 07/13] esp: move TYPE_ESP and SysBusESPState from esp.c to esp.h

2017-10-14 Thread Mark Cave-Ayland
This enables them to be used outside of esp.c.

Signed-off-by: Mark Cave-Ayland 
CC: Paolo Bonzini 
---
 hw/scsi/esp.c |   13 -
 include/hw/scsi/esp.h |   13 +
 2 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 22c2d91..ee586e7 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -592,19 +592,6 @@ const VMStateDescription vmstate_esp = {
 }
 };
 
-#define TYPE_ESP "esp"
-#define ESP_STATE(obj) OBJECT_CHECK(SysBusESPState, (obj), TYPE_ESP)
-
-typedef struct {
-/*< private >*/
-SysBusDevice parent_obj;
-/*< public >*/
-
-MemoryRegion iomem;
-uint32_t it_shift;
-ESPState esp;
-} SysBusESPState;
-
 static void sysbus_esp_mem_write(void *opaque, hwaddr addr,
  uint64_t val, unsigned int size)
 {
diff --git a/include/hw/scsi/esp.h b/include/hw/scsi/esp.h
index d2c4886..a79d3f2 100644
--- a/include/hw/scsi/esp.h
+++ b/include/hw/scsi/esp.h
@@ -52,6 +52,19 @@ struct ESPState {
 void (*dma_cb)(ESPState *s);
 };
 
+#define TYPE_ESP "esp"
+#define ESP_STATE(obj) OBJECT_CHECK(SysBusESPState, (obj), TYPE_ESP)
+
+typedef struct {
+/*< private >*/
+SysBusDevice parent_obj;
+/*< public >*/
+
+MemoryRegion iomem;
+uint32_t it_shift;
+ESPState esp;
+} SysBusESPState;
+
 #define ESP_TCLO   0x0
 #define ESP_TCMID  0x1
 #define ESP_FIFO   0x2
-- 
1.7.10.4




[Qemu-devel] [PATCHv2 06/13] sparc32_dma: use object link instead of qdev property to pass IOMMU reference

2017-10-14 Thread Mark Cave-Ayland
This enables us to remove the last remaining (opaque) qdev property. Whilst we
are here, also update iommu_init() to use TYPE_SUN4M_IOMMU instead of a
hardcoded string.

Signed-off-by: Mark Cave-Ayland 
---
 hw/dma/sparc32_dma.c |   13 +
 hw/sparc/sun4m.c |4 ++--
 2 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/hw/dma/sparc32_dma.c b/hw/dma/sparc32_dma.c
index ae8fa06..c56a2ba 100644
--- a/hw/dma/sparc32_dma.c
+++ b/hw/dma/sparc32_dma.c
@@ -263,24 +263,21 @@ static void sparc32_dma_device_init(Object *obj)
 
 sysbus_init_mmio(sbd, >iomem);
 
+object_property_add_link(OBJECT(dev), "iommu", TYPE_SUN4M_IOMMU,
+ (Object **) >iommu,
+ qdev_prop_allow_set_link_before_realize,
+ 0, NULL);
+
 qdev_init_gpio_in(dev, dma_set_irq, 1);
 qdev_init_gpio_out(dev, s->gpio, 2);
 }
 
-static Property sparc32_dma_device_properties[] = {
-DEFINE_PROP_PTR("iommu_opaque", DMADeviceState, iommu),
-DEFINE_PROP_END_OF_LIST(),
-};
-
 static void sparc32_dma_device_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
 
 dc->reset = sparc32_dma_device_reset;
 dc->vmsd = _sparc32_dma_device;
-dc->props = sparc32_dma_device_properties;
-/* Reason: pointer property "iommu_opaque" */
-dc->user_creatable = false;
 }
 
 static const TypeInfo sparc32_dma_device_info = {
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 4f2ed4b..12d36b5 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -297,7 +297,7 @@ static void *iommu_init(hwaddr addr, uint32_t version, 
qemu_irq irq)
 DeviceState *dev;
 SysBusDevice *s;
 
-dev = qdev_create(NULL, "iommu");
+dev = qdev_create(NULL, TYPE_SUN4M_IOMMU);
 qdev_prop_set_uint32(dev, "version", version);
 qdev_init_nofail(dev);
 s = SYS_BUS_DEVICE(dev);
@@ -313,7 +313,7 @@ static void *sparc32_dma_init(hwaddr daddr, void *iommu, 
int is_ledma)
 SysBusDevice *s;
 
 dev = qdev_create(NULL, is_ledma ? "sparc32-ledma" : "sparc32-espdma");
-qdev_prop_set_ptr(dev, "iommu_opaque", iommu);
+object_property_set_link(OBJECT(dev), OBJECT(iommu), "iommu", 
_abort);
 qdev_init_nofail(dev);
 s = SYS_BUS_DEVICE(dev);
 sysbus_mmio_map(s, 0, daddr);
-- 
1.7.10.4




[Qemu-devel] [PATCHv2 02/13] sparc32_dma: split esp and le into separate DMA devices

2017-10-14 Thread Mark Cave-Ayland
Due to slight differences in behaviour accessing the registers for the
esp and le devices, create two separate SPARC32_DMA_DEVICE types and
update the sun4m machine to use.

Note that by using different device types we already know the size of
the register block and the value of is_ledma at init time, allowing us to
drop the SPARC32_DMA_DEVICE realize function and the is_ledma device
property.

Signed-off-by: Mark Cave-Ayland 
---
 hw/dma/sparc32_dma.c |   63 --
 hw/sparc/sun4m.c |3 +--
 2 files changed, 52 insertions(+), 14 deletions(-)

diff --git a/hw/dma/sparc32_dma.c b/hw/dma/sparc32_dma.c
index a8d31c1..e4ff4a8 100644
--- a/hw/dma/sparc32_dma.c
+++ b/hw/dma/sparc32_dma.c
@@ -78,6 +78,22 @@ struct DMADeviceState {
 uint32_t is_ledma;
 };
 
+#define TYPE_SPARC32_ESPDMA_DEVICE "sparc32-espdma"
+#define SPARC32_ESPDMA_DEVICE(obj) OBJECT_CHECK(ESPDMADeviceState, (obj), \
+TYPE_SPARC32_ESPDMA_DEVICE)
+
+typedef struct ESPDMADeviceState {
+DMADeviceState parent_obj;
+} ESPDMADeviceState;
+
+#define TYPE_SPARC32_LEDMA_DEVICE "sparc32-ledma"
+#define SPARC32_LEDMA_DEVICE(obj) OBJECT_CHECK(LEDMADeviceState, (obj), \
+   TYPE_SPARC32_LEDMA_DEVICE)
+
+typedef struct LEDMADeviceState {
+DMADeviceState parent_obj;
+} LEDMADeviceState;
+
 enum {
 GPIO_RESET = 0,
 GPIO_DMA,
@@ -285,19 +301,8 @@ static void sparc32_dma_device_init(Object *obj)
 qdev_init_gpio_out(dev, s->gpio, 2);
 }
 
-static void sparc32_dma_device_realize(DeviceState *dev, Error **errp)
-{
-DMADeviceState *s = SPARC32_DMA_DEVICE(dev);
-int reg_size;
-
-reg_size = s->is_ledma ? DMA_ETH_SIZE : DMA_SIZE;
-memory_region_init_io(>iomem, OBJECT(dev), _mem_ops, s,
-  "dma", reg_size);
-}
-
 static Property sparc32_dma_device_properties[] = {
 DEFINE_PROP_PTR("iommu_opaque", DMADeviceState, iommu),
-DEFINE_PROP_UINT32("is_ledma", DMADeviceState, is_ledma, 0),
 DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -308,7 +313,6 @@ static void sparc32_dma_device_class_init(ObjectClass 
*klass, void *data)
 dc->reset = sparc32_dma_device_reset;
 dc->vmsd = _sparc32_dma_device;
 dc->props = sparc32_dma_device_properties;
-dc->realize = sparc32_dma_device_realize;
 /* Reason: pointer property "iommu_opaque" */
 dc->user_creatable = false;
 }
@@ -316,14 +320,49 @@ static void sparc32_dma_device_class_init(ObjectClass 
*klass, void *data)
 static const TypeInfo sparc32_dma_device_info = {
 .name  = TYPE_SPARC32_DMA_DEVICE,
 .parent= TYPE_SYS_BUS_DEVICE,
+.abstract  = true,
 .instance_size = sizeof(DMADeviceState),
 .instance_init = sparc32_dma_device_init,
 .class_init= sparc32_dma_device_class_init,
 };
 
+static void sparc32_espdma_device_init(Object *obj)
+{
+DMADeviceState *s = SPARC32_DMA_DEVICE(obj);
+
+memory_region_init_io(>iomem, OBJECT(s), _mem_ops, s,
+  "espdma-mmio", DMA_SIZE);
+s->is_ledma = 0;
+}
+
+static const TypeInfo sparc32_espdma_device_info = {
+.name  = TYPE_SPARC32_ESPDMA_DEVICE,
+.parent= TYPE_SPARC32_DMA_DEVICE,
+.instance_size = sizeof(ESPDMADeviceState),
+.instance_init = sparc32_espdma_device_init,
+};
+
+static void sparc32_ledma_device_init(Object *obj)
+{
+DMADeviceState *s = SPARC32_DMA_DEVICE(obj);
+
+memory_region_init_io(>iomem, OBJECT(s), _mem_ops, s,
+  "ledma-mmio", DMA_ETH_SIZE);
+s->is_ledma = 1;
+}
+
+static const TypeInfo sparc32_ledma_device_info = {
+.name  = TYPE_SPARC32_LEDMA_DEVICE,
+.parent= TYPE_SPARC32_DMA_DEVICE,
+.instance_size = sizeof(LEDMADeviceState),
+.instance_init = sparc32_ledma_device_init,
+};
+
 static void sparc32_dma_register_types(void)
 {
 type_register_static(_dma_device_info);
+type_register_static(_espdma_device_info);
+type_register_static(_ledma_device_info);
 }
 
 type_init(sparc32_dma_register_types)
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 82c553c..88a9752 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -313,9 +313,8 @@ static void *sparc32_dma_init(hwaddr daddr, qemu_irq 
parent_irq,
 DeviceState *dev;
 SysBusDevice *s;
 
-dev = qdev_create(NULL, "sparc32-dma-device");
+dev = qdev_create(NULL, is_ledma ? "sparc32-ledma" : "sparc32-espdma");
 qdev_prop_set_ptr(dev, "iommu_opaque", iommu);
-qdev_prop_set_uint32(dev, "is_ledma", is_ledma);
 qdev_init_nofail(dev);
 s = SYS_BUS_DEVICE(dev);
 sysbus_connect_irq(s, 0, parent_irq);
-- 
1.7.10.4




[Qemu-devel] [PATCHv2 00/13] sun4m: sparc32_dma tidy-ups

2017-10-14 Thread Mark Cave-Ayland
This patchset aims to tidy-up the sparc32_dma code by improving the
modelling of the espdma/ledma devices using both QOM and the memory
API which didn't exist when the code was first written.

The result is that it is now possible to remove both the iommu_opaque
and is_ledma workarounds from the code, and the code for wiring up
the espdma/ledma and respective devices is also a lot more readable.

Signed-off-by: Mark Cave-Ayland 

v2:
- Make esp/lance devices children of espdma/ledma devices respectively
- Add len parameter to ledma/espdma tracepoints


Mark Cave-Ayland (13):
  sparc32_dma: rename SPARC32_DMA type to SPARC32_DMA_DEVICE
  sparc32_dma: split esp and le into separate DMA devices
  sparc32_dma: move type declarations from sparc32_dma.c to
sparc32_dma.h
  sun4m: move DMA device wiring from sparc32_dma_init() to
sun4m_hw_init()
  sun4m_iommu: move TYPE_SUN4M_IOMMU declaration to sun4m.h
  sparc32_dma: use object link instead of qdev property to pass IOMMU
reference
  esp: move TYPE_ESP and SysBusESPState from esp.c to esp.h
  sparc32_dma: make esp device child of espdma device
  lance: move TYPE_LANCE and SysBusPCNetState from lance.c to sun4m.h
  sparc32_dma: make lance device child of ledma device
  sparc32_dma: introduce new SPARC32_DMA type container object
  sparc32_dma: remove is_ledma hack and replace with memory region
alias
  sparc32_dma: add len to esp/le DMA memory tracing

 hw/dma/sparc32_dma.c   |  236 +---
 hw/dma/sun4m_iommu.c   |   14 ---
 hw/dma/trace-events|8 +-
 hw/net/lance.c |9 --
 hw/scsi/esp.c  |   13 ---
 hw/sparc/sun4m.c   |   82 ++
 include/hw/scsi/esp.h  |   13 +++
 include/hw/sparc/sparc32_dma.h |   55 ++
 include/hw/sparc/sun4m.h   |   29 +
 9 files changed, 306 insertions(+), 153 deletions(-)

-- 
1.7.10.4




[Qemu-devel] [PATCHv2 04/13] sun4m: move DMA device wiring from sparc32_dma_init() to sun4m_hw_init()

2017-10-14 Thread Mark Cave-Ayland
By using the sysbus interface it is possible to wire up the esp/le devices
to the sun4m DMA controller directly during sun4m_hw_init() instead of
passing qemu_irqs into the sparc32_dma_init() function.

This is an intermediate step to allow further reorganisation as more logic
is moved into the relevant SPARC32 DMA devices; there will be a final
refactoring of sparc32_dma_init() once this work is complete.

Signed-off-by: Mark Cave-Ayland 
---
 hw/sparc/sun4m.c |   29 -
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 88a9752..4f2ed4b 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -307,8 +307,7 @@ static void *iommu_init(hwaddr addr, uint32_t version, 
qemu_irq irq)
 return s;
 }
 
-static void *sparc32_dma_init(hwaddr daddr, qemu_irq parent_irq,
-  void *iommu, qemu_irq *dev_irq, int is_ledma)
+static void *sparc32_dma_init(hwaddr daddr, void *iommu, int is_ledma)
 {
 DeviceState *dev;
 SysBusDevice *s;
@@ -317,8 +316,6 @@ static void *sparc32_dma_init(hwaddr daddr, qemu_irq 
parent_irq,
 qdev_prop_set_ptr(dev, "iommu_opaque", iommu);
 qdev_init_nofail(dev);
 s = SYS_BUS_DEVICE(dev);
-sysbus_connect_irq(s, 0, parent_irq);
-*dev_irq = qdev_get_gpio_in(dev, 0);
 sysbus_mmio_map(s, 0, daddr);
 
 return s;
@@ -821,9 +818,10 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
 DeviceState *slavio_intctl;
 const char *cpu_model = machine->cpu_model;
 unsigned int i;
-void *iommu, *espdma, *ledma, *nvram;
-qemu_irq *cpu_irqs[MAX_CPUS], slavio_irq[32], slavio_cpu_irq[MAX_CPUS],
-espdma_irq, ledma_irq;
+void *iommu, *nvram;
+DeviceState *espdma, *ledma;
+SysBusDevice *sbd;
+qemu_irq *cpu_irqs[MAX_CPUS], slavio_irq[32], slavio_cpu_irq[MAX_CPUS];
 qemu_irq esp_reset, dma_enable;
 qemu_irq fdc_tc;
 unsigned long kernel_size;
@@ -882,11 +880,13 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
 empty_slot_init(hwdef->iommu_pad_base,hwdef->iommu_pad_len);
 }
 
-espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[18],
-  iommu, _irq, 0);
+espdma = sparc32_dma_init(hwdef->dma_base, iommu, 0);
+sbd = SYS_BUS_DEVICE(espdma);
+sysbus_connect_irq(sbd, 0, slavio_irq[18]);
 
-ledma = sparc32_dma_init(hwdef->dma_base + 16ULL,
- slavio_irq[16], iommu, _irq, 1);
+ledma = sparc32_dma_init(hwdef->dma_base + 16ULL, iommu, 1);
+sbd = SYS_BUS_DEVICE(ledma);
+sysbus_connect_irq(sbd, 0, slavio_irq[16]);
 
 if (graphic_depth != 8 && graphic_depth != 24) {
 error_report("Unsupported depth: %d", graphic_depth);
@@ -939,7 +939,8 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
 empty_slot_init(hwdef->sx_base, 0x2000);
 }
 
-lance_init(_table[0], hwdef->le_base, ledma, ledma_irq);
+lance_init(_table[0], hwdef->le_base, ledma,
+   qdev_get_gpio_in(ledma, 0));
 
 nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0, 0x2000, 1968, 8);
 
@@ -971,7 +972,9 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
 
 esp_init(hwdef->esp_base, 2,
  espdma_memory_read, espdma_memory_write,
- espdma, espdma_irq, _reset, _enable);
+ espdma,
+ qdev_get_gpio_in(espdma, 0),
+ _reset, _enable);
 
 qdev_connect_gpio_out(espdma, 0, esp_reset);
 qdev_connect_gpio_out(espdma, 1, dma_enable);
-- 
1.7.10.4




Re: [Qemu-devel] [PATCH 0/8] sun4m : sparc32_dma tidy-ups

2017-10-14 Thread Mark Cave-Ayland
On 10/10/17 09:21, Artyom Tarasenko wrote:

> On Mon, Oct 9, 2017 at 11:06 PM, Mark Cave-Ayland
>  wrote:
>> This patchset aims to tidy-up the sparc32_dma code by improving the
>> modelling of the espdma/ledma devices using both QOM and the memory
>> API which didn't exist when the code was first written.
>>
>> The result is that it is now possible to remove both the iommu_opaque
>> and is_ledma workarounds from the code.
>>
>> Signed-off-by: Mark Cave-Ayland 
> 
> Reviewed-by: Artyom Tarasenko 

With some further experimentation I've found that making the esp/le
devices children of their respective espdma/ledma devices makes things a
lot cleaner.

I've also got another related patch to update the espdma/ledma
tracepoints to log the DMA transaction length, so I'll submit a v2 of
this with the additional changes shortly.


ATB,

Mark.



Re: [Qemu-devel] QEMU without X11 support

2017-10-14 Thread Peter Maydell
On 14 October 2017 at 17:38, Philippe Mathieu-Daudé  wrote:
>>> Hello, is it possible to run (or rebuild modifying build flags) QEMU
>>> without support for X11 window system integration?
>>
>> ./configure --disable-gtk --disable-sdl --disable-opengl
>
> Is there some interest in adding a simpler --disable-x11 option?

We don't directly link to X11, so it wouldn't fit with
our other options.
The --disable-foo options aren't very often necessary --
only if your build environment has support for linking
against foo but for some reason you don't want it
linked in.

thanks
-- PMM



Re: [Qemu-devel] [PATCH] tco: add trace events

2017-10-14 Thread Philippe Mathieu-Daudé
Hi Paolo,

On 10/12/2017 10:54 AM, Paolo Bonzini wrote:
> Add trace events to the PCH watchdog timer, it can be useful to see how
> the guest is using it.
> 
> Signed-off-by: Paolo Bonzini 
> ---
>  hw/acpi/tco.c| 11 +--
>  hw/acpi/trace-events |  4 
>  2 files changed, 13 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/acpi/tco.c b/hw/acpi/tco.c
> index 05b9d7b..0032db4 100644
> --- a/hw/acpi/tco.c
> +++ b/hw/acpi/tco.c
> @@ -12,6 +12,7 @@
>  #include "hw/i386/ich9.h"
>  
>  #include "hw/acpi/tco.h"
> +#include "trace.h"
>  
>  //#define DEBUG
>  
> @@ -41,8 +42,11 @@ enum {
>  
>  static inline void tco_timer_reload(TCOIORegs *tr)
>  {
> -tr->expire_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
> -((int64_t)(tr->tco.tmr & TCO_TMR_MASK) * TCO_TICK_NSEC);
> +int ticks = tr->tco.tmr & TCO_TMR_MASK;
> +int64_t nsec = (int64_t)ticks * TCO_TICK_NSEC;
> +
> +trace_tco_timer_reload(ticks, nsec / 100);

I'd use SCALE_MS here.

> +tr->expire_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + nsec;
>  timer_mod(tr->tco_timer, tr->expire_time);
>  }
>  
> @@ -59,6 +63,9 @@ static void tco_timer_expired(void *opaque)
>  ICH9LPCState *lpc = container_of(pm, ICH9LPCState, pm);
>  uint32_t gcs = pci_get_long(lpc->chip_config + ICH9_CC_GCS);
>  
> +trace_tco_timer_expired(tr->timeouts_no,
> + lpc->pin_strap.spkr_hi,
> + !!(gcs & ICH9_CC_GCS_NO_REBOOT));
>  tr->tco.rld = 0;
>  tr->tco.sts1 |= TCO_TIMEOUT;
>  if (++tr->timeouts_no == 2) {
> diff --git a/hw/acpi/trace-events b/hw/acpi/trace-events
> index e3b41e9..df0024f 100644
> --- a/hw/acpi/trace-events
> +++ b/hw/acpi/trace-events
> @@ -30,3 +30,7 @@ cpuhp_acpi_ejecting_invalid_cpu(uint32_t idx) "0x%"PRIx32
>  cpuhp_acpi_ejecting_cpu(uint32_t idx) "0x%"PRIx32
>  cpuhp_acpi_write_ost_ev(uint32_t slot, uint32_t ev) "idx[0x%"PRIx32"] OST 
> EVENT: 0x%"PRIx32
>  cpuhp_acpi_write_ost_status(uint32_t slot, uint32_t st) "idx[0x%"PRIx32"] 
> OST STATUS: 0x%"PRIx32
> +
> +# hw/acpi/tco.c
> +tco_timer_reload(int ticks, int msec) "ticks=%d (%d ms)"
> +tco_timer_expired(int timeouts_no, bool strap, bool no_reboot) 
> "timeouts_no=%d no_reboot=%d/%d"

Changing tabs by spaces to satisfy checkpatch:
Reviewed-by: Philippe Mathieu-Daudé 



Re: [Qemu-devel] [PATCH v2] oslib-posix: Fix compiler warning and some data types

2017-10-14 Thread Philippe Mathieu-Daudé
Hi Stefan,

On 10/13/2017 02:48 AM, Stefan Weil wrote:
> diff --git a/util/oslib-posix.c b/util/oslib-posix.c
> index 80086c549f..beef148c96 100644
> --- a/util/oslib-posix.c
> +++ b/util/oslib-posix.c
> @@ -59,8 +59,8 @@
>  
>  struct MemsetThread {
>  char *addr;
> -uint64_t numpages;
> -uint64_t hpagesize;
> +size_t numpages;
> +size_t hpagesize;
>  QemuThread pgthread;
>  sigjmp_buf env;
>  };
> @@ -301,11 +301,7 @@ static void sigbus_handler(int signal)
>  static void *do_touch_pages(void *arg)
>  {
>  MemsetThread *memset_args = (MemsetThread *)arg;
> -char *addr = memset_args->addr;
> -uint64_t numpages = memset_args->numpages;
> -uint64_t hpagesize = memset_args->hpagesize;
>  sigset_t set, oldset;
> -int i = 0;
>  
>  /* unblock SIGBUS */
>  sigemptyset();
> @@ -315,6 +311,10 @@ static void *do_touch_pages(void *arg)
>  if (sigsetjmp(memset_args->env, 1)) {
>  memset_thread_failed = true;
>  } else {
> +volatile char *addr = memset_args->addr;
> +size_t numpages = memset_args->numpages;
> +size_t hpagesize = memset_args->hpagesize;
> +size_t i;
>  for (i = 0; i < numpages; i++) {
>  /*
>   * Read & write back the same value, so we don't
> @@ -328,7 +328,7 @@ static void *do_touch_pages(void *arg)
>   * don't need to write at all so we don't cause
>   * wear on the storage backing the region...
>   */
> -*(volatile char *)addr = *addr;
> +*addr = *addr;

I personally prefer the other form which is mostly self-explicit when
reviewing this code.

Declaring addr non volatile and using volatile cast here:
Reviewed-by: Philippe Mathieu-Daudé 

>  addr += hpagesize;
>  }
>  }
> @@ -351,7 +351,8 @@ static inline int get_memset_num_threads(int smp_cpus)
>  static bool touch_all_pages(char *area, size_t hpagesize, size_t numpages,
>  int smp_cpus)
>  {
> -uint64_t numpages_per_thread, size_per_thread;
> +size_t numpages_per_thread;
> +size_t size_per_thread;
>  char *addr = area;
>  int i = 0;
>  
> 



Re: [Qemu-devel] QEMU without X11 support

2017-10-14 Thread Philippe Mathieu-Daudé
>> Hello, is it possible to run (or rebuild modifying build flags) QEMU
>> without support for X11 window system integration?
> 
> ./configure --disable-gtk --disable-sdl --disable-opengl

Is there some interest in adding a simpler --disable-x11 option?



Re: [Qemu-devel] [PATCH] futex: add missing header guards

2017-10-14 Thread Philippe Mathieu-Daudé
Cc: trivial

On 10/13/2017 06:30 PM, Emilio G. Cota wrote:
> The header file was introduced by fbcc3e5 ("qemu-thread: optimize QemuLockCnt
> with futexes on Linux", 2017-01-16) without header guards. Add them.
> 
> Signed-off-by: Emilio G. Cota 

Reviewed-by: Philippe Mathieu-Daudé 

> ---
>  include/qemu/futex.h | 5 +
>  1 file changed, 5 insertions(+)
> 
> diff --git a/include/qemu/futex.h b/include/qemu/futex.h
> index bb7dc9e..91ae889 100644
> --- a/include/qemu/futex.h
> +++ b/include/qemu/futex.h
> @@ -11,6 +11,9 @@
>   *
>   */
>  
> +#ifndef QEMU_FUTEX_H
> +#define QEMU_FUTEX_H
> +
>  #include 
>  #include 
>  
> @@ -34,3 +37,5 @@ static inline void qemu_futex_wait(void *f, unsigned val)
>  }
>  }
>  }
> +
> +#endif /* QEMU_FUTEX_H */
> 



Re: [Qemu-devel] [PATCH 2/4] multiboot: load any machine type of ELF

2017-10-14 Thread Peter Maydell
On 14 October 2017 at 00:21, Eduardo Habkost  wrote:
> I don't believe the spec restricts that, but I don't see why it
> would be useful to load an ELF file that doesn't match the target
> architecture (e.g. loading non-x86 ELF files on a x86 machine
> like PC).

Agreed. If we have non i386 boards that want to use multiboot
we should probably move the common code out of hw/i386...

thanks
-- PMM



  1   2   >