Re: [Qemu-devel] [RFC QEMU PATCH v4 03/10] hostmem-xen: add a host memory backend for Xen

2018-03-04 Thread Haozhong Zhang
On 03/02/18 11:50 +, Anthony PERARD wrote:
> On Wed, Feb 28, 2018 at 03:56:54PM +0800, Haozhong Zhang wrote:
> > On 02/27/18 16:41 +, Anthony PERARD wrote:
> > > On Thu, Dec 07, 2017 at 06:18:05PM +0800, Haozhong Zhang wrote:
> > > > @@ -108,7 +109,10 @@ void pc_dimm_memory_plug(DeviceState *dev, 
> > > > MemoryHotplugState *hpms,
> > > >  }
> > > >  
> > > >  memory_region_add_subregion(>mr, addr - hpms->base, mr);
> > > > -vmstate_register_ram(vmstate_mr, dev);
> > > > +/* memory-backend-xen is not backed by RAM. */
> > > > +if (!xen_enabled()) {
> > > 
> > > Is it possible to have the same condition as the one used in
> > > host_memory_backend_memory_complete? i.e. base on whether the memory
> > > region is mapped or not (backend->mr.ram_block).
> > 
> > Like "if (!xen_enabled() || backend->mr.ram_block))"? No, it will mute
> > the abortion (vmstate_register_ram --> qemu_ram_set_idstr ) caused by
> > the case that !backend->mr.ram_block in the non-xen environment.
> 
> In non-xen environment, vmstate_register_ram() will be called, because
> !xen_enabled() is true, it would not matter if there is a ram_block or
> not.

Sorry, I really meant 'if (backend->mr.ram_block)', which may mute the
abortion in non-xen environment. 'if (!xen_enabled())' keeps the
original semantics in non-xen environment, so it's unlikely to break
the non-xen usage.

Haozhong

> 
> But if there is a memory-backend that can run in a xen environment that
> have a ram_block, vmstate_register_ram would not be called in the
> origial patch, but if we use (!xen_enabled() || vmstate_mr->ram_block)
> as condition then vmstate_register_ram will be called.
> 
> Is this make sense?
> 
> > > > +vmstate_register_ram(vmstate_mr, dev);
> > > > +}
> > > >  numa_set_mem_node_id(addr, memory_region_size(mr), dimm->node);
> > > >  
> > > >  out:
> 
> -- 
> Anthony PERARD
> 



Re: [Qemu-devel] [PATCH] Allow to specify a display ID whith the screendump command

2018-03-04 Thread Gerd Hoffmann
> -void qmp_screendump(const char *filename, Error **errp)
> +void qmp_screendump(const char *filename, bool has_id, const char *id,
> +Error **errp)
>  {
>  QemuConsole *con = qemu_console_lookup_by_index(0);
>  DisplaySurface *surface;
> +DeviceState *dev;
> +
> +if (has_id) {
> +dev = qdev_find_recursive(sysbus_get_default(), id);
> +if (!dev) {
> +error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
> +  "Device '%s' not found", id);
> +return;
> +}
> +con = qemu_console_lookup_by_device(dev, 0);

I'd suggest to name this 'device', because this is what it actually is.
While being at it you should also add a 'head' parameter (second arg of
qemu_console_lookup_by_device()), for devices like virtio-vga which can
support multiple heads.

>  if (con == NULL) {
>  error_setg(errp, "There is no QemuConsole I can screendump from.");

This might also be refined to say something like 'device $name is not a
display device' in case qemu_console_lookup_by_device() failed.

> -- 
> 1.8.3.1
> 



Re: [Qemu-devel] [PATCH v3 04/12] vfio/pci: add notify framework based on IOMMUSVAContext

2018-03-04 Thread Peter Xu
On Thu, Mar 01, 2018 at 06:33:27PM +0800, Liu, Yi L wrote:
> This patch introduces a notify framework for IOMMUSVAContext.sva_notifiers.
> 
> Signed-off-by: Liu, Yi L 
> ---
>  hw/vfio/common.c  | 1 +
>  include/hw/vfio/vfio-common.h | 9 +
>  2 files changed, 10 insertions(+)
> 
> diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> index 06277d2..1cc96df 100644
> --- a/hw/vfio/common.c
> +++ b/hw/vfio/common.c
> @@ -1019,6 +1019,7 @@ static int vfio_connect_container(VFIOGroup *group, 
> AddressSpace *as,
>  container->fd = fd;
>  QLIST_INIT(>giommu_mr_list);
>  QLIST_INIT(>hostwin_list);
> +QLIST_INIT(>gsva_ctx_list);
>  if (ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1_IOMMU) ||
>  ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1v2_IOMMU)) {
>  bool v2 = !!ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1v2_IOMMU);
> diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
> index 702a085..4c16b4c 100644
> --- a/include/hw/vfio/vfio-common.h
> +++ b/include/hw/vfio/vfio-common.h
> @@ -29,6 +29,7 @@
>  #ifdef CONFIG_LINUX
>  #include 
>  #endif
> +#include "hw/core/pasid.h"
>  
>  #define ERR_PREFIX "vfio error: %s: "
>  #define WARN_PREFIX "vfio warning: %s: "
> @@ -88,6 +89,7 @@ typedef struct VFIOContainer {
>   * future
>   */
>  QLIST_HEAD(, VFIOGuestIOMMUMR) giommu_mr_list;
> +QLIST_HEAD(, VFIOGuestIOMMUSVAContext) gsva_ctx_list;

IIUC vfio container is per-domain, so here we have a per-domain
context.  Does that mean that all the devices in the same IOMMU group
(or say, share the 2nd level page table) must share the same PASID
table (or say, the 1st level page table)?  Thanks,

>  QLIST_HEAD(, VFIOHostDMAWindow) hostwin_list;
>  QLIST_HEAD(, VFIOGroup) group_list;
>  QLIST_ENTRY(VFIOContainer) next;
> @@ -101,6 +103,13 @@ typedef struct VFIOGuestIOMMUMR {
>  QLIST_ENTRY(VFIOGuestIOMMUMR) giommu_next;
>  } VFIOGuestIOMMUMR;
>  
> +typedef struct VFIOGuestIOMMUSVAContext {
> +VFIOContainer *container;
> +IOMMUSVAContext *sva_ctx;
> +IOMMUSVANotifier n;
> +QLIST_ENTRY(VFIOGuestIOMMUSVAContext) gsva_ctx_next;
> +} VFIOGuestIOMMUSVAContext;
> +
>  typedef struct VFIOHostDMAWindow {
>  hwaddr min_iova;
>  hwaddr max_iova;
> -- 
> 1.9.1
> 

-- 
Peter Xu



Re: [Qemu-devel] [PATCH 0/9] chardev: qio related non-default context support

2018-03-04 Thread no-reply
Hi,

This series failed docker-quick@centos6 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: 20180305065040.10353-1-pet...@redhat.com
Subject: [Qemu-devel] [PATCH 0/9] chardev: qio related non-default context 
support

=== 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
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
22ac8d2012 chardev: tcp: postpone TLS work until machine done
ed4c32e237 chardev: tcp: let TLS run on chardev context
5647bf6b38 chardev: tcp: postpone async connection setup
8ae81a810e chardev: use chardev's gcontext for async connect
01d4991034 chardev: introduce chr_machine_done hook
eb241a606e chardev: allow telnet gsource to switch gcontext
661b79ad6c chardev: update net listener gcontext
0c7927dc54 chardev: fix leak in tcp_chr_telnet_init_io()
f3898e28be vl: export machine_init_done

=== OUTPUT BEGIN ===
Submodule 'dtc' (git://git.qemu-project.org/dtc.git) registered for path 'dtc'
Cloning into '/var/tmp/patchew-tester-tmp-9957yvff/src/dtc'...
Submodule path 'dtc': checked out 'e54388015af1fb4bf04d0bca99caba1074d9cc42'
  BUILD   centos6
make[1]: Entering directory '/var/tmp/patchew-tester-tmp-9957yvff/src'
  GEN 
/var/tmp/patchew-tester-tmp-9957yvff/src/docker-src.2018-03-05-02.41.16.6330/qemu.tar
Cloning into 
'/var/tmp/patchew-tester-tmp-9957yvff/src/docker-src.2018-03-05-02.41.16.6330/qemu.tar.vroot'...
done.
Checking out files:  45% (2678/5923)   
Checking out files:  46% (2725/5923)   
Checking out files:  47% (2784/5923)   
Checking out files:  48% (2844/5923)   
Checking out files:  49% (2903/5923)   
Checking out files:  50% (2962/5923)   
Checking out files:  51% (3021/5923)   
Checking out files:  52% (3080/5923)   
Checking out files:  53% (3140/5923)   
Checking out files:  54% (3199/5923)   
Checking out files:  55% (3258/5923)   
Checking out files:  56% (3317/5923)   
Checking out files:  57% (3377/5923)   
Checking out files:  58% (3436/5923)   
Checking out files:  59% (3495/5923)   
Checking out files:  60% (3554/5923)   
Checking out files:  61% (3614/5923)   
Checking out files:  62% (3673/5923)   
Checking out files:  63% (3732/5923)   
Checking out files:  64% (3791/5923)   
Checking out files:  65% (3850/5923)   
Checking out files:  66% (3910/5923)   
Checking out files:  67% (3969/5923)   
Checking out files:  68% (4028/5923)   
Checking out files:  69% (4087/5923)   
Checking out files:  70% (4147/5923)   
Checking out files:  71% (4206/5923)   
Checking out files:  72% (4265/5923)   
Checking out files:  73% (4324/5923)   
Checking out files:  74% (4384/5923)   
Checking out files:  75% (4443/5923)   
Checking out files:  76% (4502/5923)   
Checking out files:  77% (4561/5923)   
Checking out files:  78% (4620/5923)   
Checking out files:  79% (4680/5923)   
Checking out files:  80% (4739/5923)   
Checking out files:  81% (4798/5923)   
Checking out files:  82% (4857/5923)   
Checking out files:  83% (4917/5923)   
Checking out files:  84% (4976/5923)   
Checking out files:  84% (4978/5923)   
Checking out files:  85% (5035/5923)   
Checking out files:  86% (5094/5923)   
Checking out files:  87% (5154/5923)   
Checking out files:  88% (5213/5923)   
Checking out files:  89% (5272/5923)   
Checking out files:  90% (5331/5923)   
Checking out files:  91% (5390/5923)   
Checking out files:  92% (5450/5923)   
Checking out files:  93% (5509/5923)   
Checking out files:  94% (5568/5923)   
Checking out files:  95% (5627/5923)   
Checking out files:  96% (5687/5923)   
Checking out files:  97% (5746/5923)   
Checking out files:  98% (5805/5923)   
Checking out files:  99% (5864/5923)   
Checking out files: 100% (5923/5923)   
Checking out files: 100% (5923/5923), done.
Your branch is up-to-date with 'origin/test'.
Submodule 'dtc' (git://git.qemu-project.org/dtc.git) registered for path 'dtc'
Cloning into 
'/var/tmp/patchew-tester-tmp-9957yvff/src/docker-src.2018-03-05-02.41.16.6330/qemu.tar.vroot/dtc'...
Submodule path 'dtc': checked out 'e54388015af1fb4bf04d0bca99caba1074d9cc42'
Submodule 'ui/keycodemapdb' (git://git.qemu.org/keycodemapdb.git) registered 
for path 'ui/keycodemapdb'
Cloning into 
'/var/tmp/patchew-tester-tmp-9957yvff/src/docker-src.2018-03-05-02.41.16.6330/qemu.tar.vroot/ui/keycodemapdb'...
Submodule path 'ui/keycodemapdb': checked out 
'6b3d716e2b6472eb7189d3220552280ef3d832ce'
  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

[Qemu-devel] [PATCH] Allow to specify a display ID whith the screendump command

2018-03-04 Thread Thomas Huth
QEMU's screendump command can only take dumps from the primary display.
When using multiple VGA cards, there is no way to get a dump from a
secondary card yet. So let's add an 'id' parameter to the HMP and QMP
commands to be able to specify alternative devices with the screendump
command, too.

Signed-off-by: Thomas Huth 
---
 hmp-commands.hx |  6 +++---
 hmp.c   |  3 ++-
 qapi/ui.json|  4 +++-
 ui/console.c| 16 +++-
 4 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index d26eb41..045ffb0 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -253,9 +253,9 @@ ETEXI
 
 {
 .name   = "screendump",
-.args_type  = "filename:F",
-.params = "filename",
-.help   = "save screen into PPM image 'filename'",
+.args_type  = "filename:F,id:s?",
+.params = "filename [id]",
+.help   = "save screen from device 'id' into PPM image 'filename'",
 .cmd= hmp_screendump,
 },
 
diff --git a/hmp.c b/hmp.c
index ae86bfb..e2f46f1 100644
--- a/hmp.c
+++ b/hmp.c
@@ -2132,9 +2132,10 @@ err_out:
 void hmp_screendump(Monitor *mon, const QDict *qdict)
 {
 const char *filename = qdict_get_str(qdict, "filename");
+const char *id = qdict_get_try_str(qdict, "id");
 Error *err = NULL;
 
-qmp_screendump(filename, );
+qmp_screendump(filename, id != NULL, id, );
 hmp_handle_error(mon, );
 }
 
diff --git a/qapi/ui.json b/qapi/ui.json
index 3e82f25..977212a 100644
--- a/qapi/ui.json
+++ b/qapi/ui.json
@@ -77,6 +77,8 @@
 #
 # @filename: the path of a new PPM file to store the image
 #
+# @id: ID of the display device that should be used (since 2.12)
+#
 # Returns: Nothing on success
 #
 # Since: 0.14.0
@@ -88,7 +90,7 @@
 # <- { "return": {} }
 #
 ##
-{ 'command': 'screendump', 'data': {'filename': 'str'} }
+{ 'command': 'screendump', 'data': {'filename': 'str', '*id': 'str'} }
 
 ##
 # == Spice
diff --git a/ui/console.c b/ui/console.c
index e22931a..a0db0c5 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -344,10 +344,24 @@ write_err:
 goto out;
 }
 
-void qmp_screendump(const char *filename, Error **errp)
+void qmp_screendump(const char *filename, bool has_id, const char *id,
+Error **errp)
 {
 QemuConsole *con = qemu_console_lookup_by_index(0);
 DisplaySurface *surface;
+DeviceState *dev;
+
+if (has_id) {
+dev = qdev_find_recursive(sysbus_get_default(), id);
+if (!dev) {
+error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+  "Device '%s' not found", id);
+return;
+}
+con = qemu_console_lookup_by_device(dev, 0);
+} else {
+con = qemu_console_lookup_by_index(0);
+}
 
 if (con == NULL) {
 error_setg(errp, "There is no QemuConsole I can screendump from.");
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 1/5] pc-dimm: refactor qmp_pc_dimm_device_list

2018-03-04 Thread Haozhong Zhang
Use pc_dimm_built_list to hide recursive callbacks from callers.

Signed-off-by: Haozhong Zhang 
---
 hw/mem/pc-dimm.c | 83 +---
 hw/ppc/spapr.c   |  3 +-
 include/hw/mem/pc-dimm.h |  2 +-
 numa.c   |  4 +--
 qmp.c|  7 +---
 stubs/qmp_pc_dimm.c  |  4 +--
 6 files changed, 50 insertions(+), 53 deletions(-)

diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c
index 6e74b61cb6..4d050fe2cd 100644
--- a/hw/mem/pc-dimm.c
+++ b/hw/mem/pc-dimm.c
@@ -162,45 +162,6 @@ uint64_t get_plugged_memory_size(void)
 return pc_existing_dimms_capacity(_abort);
 }
 
-int qmp_pc_dimm_device_list(Object *obj, void *opaque)
-{
-MemoryDeviceInfoList ***prev = opaque;
-
-if (object_dynamic_cast(obj, TYPE_PC_DIMM)) {
-DeviceState *dev = DEVICE(obj);
-
-if (dev->realized) {
-MemoryDeviceInfoList *elem = g_new0(MemoryDeviceInfoList, 1);
-MemoryDeviceInfo *info = g_new0(MemoryDeviceInfo, 1);
-PCDIMMDeviceInfo *di = g_new0(PCDIMMDeviceInfo, 1);
-DeviceClass *dc = DEVICE_GET_CLASS(obj);
-PCDIMMDevice *dimm = PC_DIMM(obj);
-
-if (dev->id) {
-di->has_id = true;
-di->id = g_strdup(dev->id);
-}
-di->hotplugged = dev->hotplugged;
-di->hotpluggable = dc->hotpluggable;
-di->addr = dimm->addr;
-di->slot = dimm->slot;
-di->node = dimm->node;
-di->size = object_property_get_uint(OBJECT(dimm), 
PC_DIMM_SIZE_PROP,
-NULL);
-di->memdev = object_get_canonical_path(OBJECT(dimm->hostmem));
-
-info->u.dimm.data = di;
-elem->value = info;
-elem->next = NULL;
-**prev = elem;
-*prev = >next;
-}
-}
-
-object_child_foreach(obj, qmp_pc_dimm_device_list, opaque);
-return 0;
-}
-
 static int pc_dimm_slot2bitmap(Object *obj, void *opaque)
 {
 unsigned long *bitmap = opaque;
@@ -276,6 +237,50 @@ static int pc_dimm_built_list(Object *obj, void *opaque)
 return 0;
 }
 
+MemoryDeviceInfoList *qmp_pc_dimm_device_list(void)
+{
+GSList *dimms = NULL, *item;
+MemoryDeviceInfoList *list = NULL, *prev = NULL;
+
+object_child_foreach(qdev_get_machine(), pc_dimm_built_list, );
+
+for (item = dimms; item; item = g_slist_next(item)) {
+PCDIMMDevice *dimm = PC_DIMM(item->data);
+Object *obj = OBJECT(dimm);
+MemoryDeviceInfoList *elem = g_new0(MemoryDeviceInfoList, 1);
+MemoryDeviceInfo *info = g_new0(MemoryDeviceInfo, 1);
+PCDIMMDeviceInfo *di = g_new0(PCDIMMDeviceInfo, 1);
+DeviceClass *dc = DEVICE_GET_CLASS(obj);
+DeviceState *dev = DEVICE(obj);
+
+if (dev->id) {
+di->has_id = true;
+di->id = g_strdup(dev->id);
+}
+di->hotplugged = dev->hotplugged;
+di->hotpluggable = dc->hotpluggable;
+di->addr = dimm->addr;
+di->slot = dimm->slot;
+di->node = dimm->node;
+di->size = object_property_get_uint(obj, PC_DIMM_SIZE_PROP, NULL);
+di->memdev = object_get_canonical_path(OBJECT(dimm->hostmem));
+
+info->u.dimm.data = di;
+elem->value = info;
+elem->next = NULL;
+if (prev) {
+prev->next = elem;
+} else {
+list = elem;
+}
+prev = elem;
+}
+
+g_slist_free(dimms);
+
+return list;
+}
+
 uint64_t pc_dimm_get_free_addr(uint64_t address_space_start,
uint64_t address_space_size,
uint64_t *hint, uint64_t align, uint64_t size,
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 83c9d66dd5..68a81e47d2 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -731,8 +731,7 @@ static int spapr_populate_drconf_memory(sPAPRMachineState 
*spapr, void *fdt)
 }
 
 if (hotplug_lmb_start) {
-MemoryDeviceInfoList **prev = 
-qmp_pc_dimm_device_list(qdev_get_machine(), );
+dimms = qmp_pc_dimm_device_list();
 }
 
 /* ibm,dynamic-memory */
diff --git a/include/hw/mem/pc-dimm.h b/include/hw/mem/pc-dimm.h
index d83b957829..1fc479281c 100644
--- a/include/hw/mem/pc-dimm.h
+++ b/include/hw/mem/pc-dimm.h
@@ -93,7 +93,7 @@ uint64_t pc_dimm_get_free_addr(uint64_t address_space_start,
 
 int pc_dimm_get_free_slot(const int *hint, int max_slots, Error **errp);
 
-int qmp_pc_dimm_device_list(Object *obj, void *opaque);
+MemoryDeviceInfoList *qmp_pc_dimm_device_list(void);
 uint64_t pc_existing_dimms_capacity(Error **errp);
 uint64_t get_plugged_memory_size(void);
 void pc_dimm_memory_plug(DeviceState *dev, MemoryHotplugState *hpms,
diff --git a/numa.c b/numa.c
index 7e0e789b02..c6734ceb8c 100644
--- a/numa.c
+++ b/numa.c
@@ -520,12 +520,10 @@ void 

[Qemu-devel] [PATCH v3 5/5] tests/bios-tables-test: add test cases for DIMM proximity

2018-03-04 Thread Haozhong Zhang
QEMU now builds one SRAT memory affinity structure for each
static-plugged PC-DIMM and NVDIMM device with the proximity domain
specified in the device option 'node', rather than only one SRAT
memory affinity structure covering the entire hotpluggable address
space with the proximity domain of the last node.

Add test cases on PC and Q35 machines with 3 proximity domains, and
one PC-DIMM and one NVDIMM attached to the second proximity domain.
Check whether the QEMU-built SRAT tables match with the expected ones.

Signed-off-by: Haozhong Zhang 
Suggested-by: Igor Mammedov 
---
 tests/acpi-test-data/pc/APIC.dimmpxm  | Bin 0 -> 136 bytes
 tests/acpi-test-data/pc/DSDT.dimmpxm  | Bin 0 -> 6710 bytes
 tests/acpi-test-data/pc/NFIT.dimmpxm  | Bin 0 -> 224 bytes
 tests/acpi-test-data/pc/SRAT.dimmpxm  | Bin 0 -> 416 bytes
 tests/acpi-test-data/pc/SSDT.dimmpxm  | Bin 0 -> 685 bytes
 tests/acpi-test-data/q35/APIC.dimmpxm | Bin 0 -> 136 bytes
 tests/acpi-test-data/q35/DSDT.dimmpxm | Bin 0 -> 9394 bytes
 tests/acpi-test-data/q35/NFIT.dimmpxm | Bin 0 -> 224 bytes
 tests/acpi-test-data/q35/SRAT.dimmpxm | Bin 0 -> 416 bytes
 tests/acpi-test-data/q35/SSDT.dimmpxm | Bin 0 -> 685 bytes
 tests/bios-tables-test.c  |  33 +
 11 files changed, 33 insertions(+)
 create mode 100644 tests/acpi-test-data/pc/APIC.dimmpxm
 create mode 100644 tests/acpi-test-data/pc/DSDT.dimmpxm
 create mode 100644 tests/acpi-test-data/pc/NFIT.dimmpxm
 create mode 100644 tests/acpi-test-data/pc/SRAT.dimmpxm
 create mode 100644 tests/acpi-test-data/pc/SSDT.dimmpxm
 create mode 100644 tests/acpi-test-data/q35/APIC.dimmpxm
 create mode 100644 tests/acpi-test-data/q35/DSDT.dimmpxm
 create mode 100644 tests/acpi-test-data/q35/NFIT.dimmpxm
 create mode 100644 tests/acpi-test-data/q35/SRAT.dimmpxm
 create mode 100644 tests/acpi-test-data/q35/SSDT.dimmpxm

diff --git a/tests/acpi-test-data/pc/APIC.dimmpxm 
b/tests/acpi-test-data/pc/APIC.dimmpxm
new file mode 100644
index 
..658d7e748e37540ff85a02f4391efc7eaae3c8b4
GIT binary patch
literal 136
zcmZ<^@O18AU|?W8>g4b25v<@85#a0y6k`O6f!H9Lf#JbFFwFr}2jX%tGD2u3CJ@cY
q0}?#&4@5F?0WpXHVzIIUXMv!Q`St
z2satx2E`NwaMQjOT80hSgA(XD{s`Mg=tt~aB0UQo6nV}n;q}*6L*s!=>De17$ErAXf5Fu1dD*Ge^>q0g
zCdy7(ZxPwqsOwZQos1~+PE+aPH|zWFglB>Rzq^4yJTQ_q<#-N~s-
zj@2#`4|`k>yE>n_OmTchclv|4EFPz3-`BKAD7a!4N}52}fwG(!gK1LTDmwuV1{QIb^P0e1
z2JXK7yNk$zZxT|wL{2o!YLk+yMAXXI5VZ>YQM7ZHL~a<_?EVL>wg#lZkfmU-(BFCX
z+A8*X^&{euac8D;wOYHuYwTd3WMNv)qqY?$`zvvQ|Pc2@Li_7qbw4aa{12zLM14YM8jDiL))
zn0g#icQ^}xFaR_O!rfhfz1J>Q?Iq^%nTKBx)(35lb5DZUhmyr}pz
zD@aqEpkYG912Y=SBfJ!VM+P3HCLbnI&(y3oO_3K?CZgB;w*!9*#>RmZJOu
zGb)9GR>@bdfuhnhS~R5u3KX

[Qemu-devel] [PATCH 8/9] chardev: tcp: let TLS run on chardev context

2018-03-04 Thread Peter Xu
Now qio_channel_tls_handshake() is ready to receive the context.  Let
socket chardev use it, then the TLS handshake of chardev will always be
with the chardev's context.

Signed-off-by: Peter Xu 
---
 chardev/char-socket.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 165612845a..bd40864f87 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -750,7 +750,7 @@ static void tcp_chr_tls_init(Chardev *chr)
   tcp_chr_tls_handshake,
   chr,
   NULL,
-  NULL);
+  chr->gcontext);
 }
 
 
-- 
2.14.3




[Qemu-devel] [PATCH v3 3/5] hw/acpi-build: build SRAT memory affinity structures for DIMM devices

2018-03-04 Thread Haozhong Zhang
ACPI 6.2A Table 5-129 "SPA Range Structure" requires the proximity
domain of a NVDIMM SPA range must match with corresponding entry in
SRAT table.

The address ranges of vNVDIMM in QEMU are allocated from the
hot-pluggable address space, which is entirely covered by one SRAT
memory affinity structure. However, users can set the vNVDIMM
proximity domain in NFIT SPA range structure by the 'node' property of
'-device nvdimm' to a value different than the one in the above SRAT
memory affinity structure.

In order to solve such proximity domain mismatch, this patch builds
one SRAT memory affinity structure for each DIMM device present at
boot time, including both PC-DIMM and NVDIMM, with the proximity
domain specified in '-device pc-dimm' or '-device nvdimm'.

The remaining hot-pluggable address space is covered by one or multiple
SRAT memory affinity structures with the proximity domain of the last
node as before.

Signed-off-by: Haozhong Zhang 
---
 hw/i386/acpi-build.c | 60 
 1 file changed, 56 insertions(+), 4 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index deb440f286..2ca0317386 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -2323,6 +2323,59 @@ build_tpm2(GArray *table_data, BIOSLinker *linker, 
GArray *tcpalog)
 #define HOLE_640K_START  (640 * 1024)
 #define HOLE_640K_END   (1024 * 1024)
 
+static void build_srat_hotpluggable_memory(GArray *table_data, uint64_t base,
+   uint64_t len, int default_node)
+{
+MemoryDeviceInfoList *info_list = qmp_pc_dimm_device_list();
+MemoryDeviceInfoList *info;
+MemoryDeviceInfo *mi;
+PCDIMMDeviceInfo *di;
+uint64_t end = base + len, cur, addr, size;
+int node;
+bool is_nvdimm;
+AcpiSratMemoryAffinity *numamem;
+MemoryAffinityFlags flags;
+
+for (cur = base, info = info_list;
+ cur < end;
+ cur += size, info = info->next) {
+numamem = acpi_data_push(table_data, sizeof *numamem);
+
+if (!info) {
+build_srat_memory(numamem, cur, end - cur, default_node,
+  MEM_AFFINITY_HOTPLUGGABLE | 
MEM_AFFINITY_ENABLED);
+break;
+}
+
+mi = info->value;
+is_nvdimm = (mi->type == MEMORY_DEVICE_INFO_KIND_NVDIMM);
+di = !is_nvdimm ? mi->u.dimm.data :
+  qapi_NVDIMMDeviceInfo_base(mi->u.nvdimm.data);
+
+addr = di->addr;
+if (cur < addr) {
+build_srat_memory(numamem, cur, addr - cur, default_node,
+  MEM_AFFINITY_HOTPLUGGABLE | 
MEM_AFFINITY_ENABLED);
+numamem = acpi_data_push(table_data, sizeof *numamem);
+}
+
+size = di->size;
+node = di->node;
+
+flags = MEM_AFFINITY_ENABLED;
+if (di->hotpluggable) {
+flags |= MEM_AFFINITY_HOTPLUGGABLE;
+}
+if (is_nvdimm) {
+flags |= MEM_AFFINITY_NON_VOLATILE;
+}
+
+build_srat_memory(numamem, addr, size, node, flags);
+}
+
+qapi_free_MemoryDeviceInfoList(info_list);
+}
+
 static void
 build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
 {
@@ -2434,10 +2487,9 @@ build_srat(GArray *table_data, BIOSLinker *linker, 
MachineState *machine)
  * providing _PXM method if necessary.
  */
 if (hotplugabble_address_space_size) {
-numamem = acpi_data_push(table_data, sizeof *numamem);
-build_srat_memory(numamem, pcms->hotplug_memory.base,
-  hotplugabble_address_space_size, pcms->numa_nodes - 
1,
-  MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED);
+build_srat_hotpluggable_memory(table_data, pcms->hotplug_memory.base,
+   hotplugabble_address_space_size,
+   pcms->numa_nodes - 1);
 }
 
 build_header(linker, table_data,
-- 
2.14.1




[Qemu-devel] [PATCH 4/9] chardev: allow telnet gsource to switch gcontext

2018-03-04 Thread Peter Xu
It was originally created by qio_channel_add_watch() so it's always
assigning the task to main context.  Now we use the new API called
qio_channel_add_watch_source() so that we get the GSource handle rather
than the tag ID.

Meanwhile, caching the gsource and TCPChardevTelnetInit (which holds the
handshake data) in SocketChardev.telnet_source so that we can also do
dynamic context switch when update read handlers.

Signed-off-by: Peter Xu 
---
 chardev/char-socket.c | 67 +++
 1 file changed, 51 insertions(+), 16 deletions(-)

diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 5aa01e15ff..c22b3f330c 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -39,6 +39,11 @@
 
 #define TCP_MAX_FDS 16
 
+typedef struct {
+char buf[21];
+size_t buflen;
+} TCPChardevTelnetInit;
+
 typedef struct {
 Chardev parent;
 QIOChannel *ioc; /* Client I/O channel */
@@ -59,6 +64,8 @@ typedef struct {
 bool is_listen;
 bool is_telnet;
 bool is_tn3270;
+GSource *telnet_source;
+TCPChardevTelnetInit *telnet_init;
 
 GSource *reconnect_timer;
 int64_t reconnect_time;
@@ -69,6 +76,7 @@ typedef struct {
 OBJECT_CHECK(SocketChardev, (obj), TYPE_CHARDEV_SOCKET)
 
 static gboolean socket_reconnect_timeout(gpointer opaque);
+static void tcp_chr_telnet_init(Chardev *chr);
 
 static void tcp_chr_reconn_timer_cancel(SocketChardev *s)
 {
@@ -555,6 +563,15 @@ static void tcp_chr_connect(void *opaque)
 qemu_chr_be_event(chr, CHR_EVENT_OPENED);
 }
 
+static void tcp_chr_telnet_destroy(SocketChardev *s)
+{
+if (s->telnet_source) {
+g_source_destroy(s->telnet_source);
+g_source_unref(s->telnet_source);
+s->telnet_source = NULL;
+}
+}
+
 static void tcp_chr_update_read_handler(Chardev *chr)
 {
 SocketChardev *s = SOCKET_CHARDEV(chr);
@@ -569,6 +586,10 @@ static void tcp_chr_update_read_handler(Chardev *chr)
   chr, NULL, chr->gcontext);
 }
 
+if (s->telnet_source) {
+tcp_chr_telnet_init(CHARDEV(s));
+}
+
 if (!s->connected) {
 return;
 }
@@ -582,32 +603,30 @@ static void tcp_chr_update_read_handler(Chardev *chr)
 }
 }
 
-typedef struct {
-Chardev *chr;
-char buf[21];
-size_t buflen;
-} TCPChardevTelnetInit;
-
 static gboolean tcp_chr_telnet_init_io(QIOChannel *ioc,
GIOCondition cond G_GNUC_UNUSED,
gpointer user_data)
 {
-TCPChardevTelnetInit *init = user_data;
+SocketChardev *s = user_data;
+Chardev *chr = CHARDEV(s);
+TCPChardevTelnetInit *init = s->telnet_init;
 ssize_t ret;
 
+assert(init);
+
 ret = qio_channel_write(ioc, init->buf, init->buflen, NULL);
 if (ret < 0) {
 if (ret == QIO_CHANNEL_ERR_BLOCK) {
 ret = 0;
 } else {
-tcp_chr_disconnect(init->chr);
+tcp_chr_disconnect(chr);
 goto end;
 }
 }
 init->buflen -= ret;
 
 if (init->buflen == 0) {
-tcp_chr_connect(init->chr);
+tcp_chr_connect(chr);
 goto end;
 }
 
@@ -616,16 +635,30 @@ static gboolean tcp_chr_telnet_init_io(QIOChannel *ioc,
 return G_SOURCE_CONTINUE;
 
 end:
-g_free(init);
+g_free(s->telnet_init);
+s->telnet_init = NULL;
+g_source_unref(s->telnet_source);
+s->telnet_source = NULL;
 return G_SOURCE_REMOVE;
 }
 
 static void tcp_chr_telnet_init(Chardev *chr)
 {
 SocketChardev *s = SOCKET_CHARDEV(chr);
-TCPChardevTelnetInit *init = g_new0(TCPChardevTelnetInit, 1);
+TCPChardevTelnetInit *init;
 size_t n = 0;
 
+/* Destroy existing task */
+tcp_chr_telnet_destroy(s);
+
+if (s->telnet_init) {
+/* We are possibly during a handshake already */
+goto cont;
+}
+
+s->telnet_init = g_new0(TCPChardevTelnetInit, 1);
+init = s->telnet_init;
+
 #define IACSET(x, a, b, c)  \
 do {\
 x[n++] = a; \
@@ -633,7 +666,6 @@ static void tcp_chr_telnet_init(Chardev *chr)
 x[n++] = c; \
 } while (0)
 
-init->chr = chr;
 if (!s->is_tn3270) {
 init->buflen = 12;
 /* Prep the telnet negotion to put telnet in binary,
@@ -656,10 +688,11 @@ static void tcp_chr_telnet_init(Chardev *chr)
 
 #undef IACSET
 
-qio_channel_add_watch(
-s->ioc, G_IO_OUT,
-tcp_chr_telnet_init_io,
-init, NULL);
+cont:
+s->telnet_source = qio_channel_add_watch_source(s->ioc, G_IO_OUT,
+tcp_chr_telnet_init_io,
+s, NULL,
+chr->gcontext);
 }
 
 
@@ -834,6 +867,8 @@ static void char_socket_finalize(Object *obj)
 

[Qemu-devel] [PATCH v3 0/5] hw/acpi-build: build SRAT memory affinity structures for DIMM devices

2018-03-04 Thread Haozhong Zhang
ACPI 6.2A Table 5-129 "SPA Range Structure" requires the proximity
domain of a NVDIMM SPA range must match with corresponding entry in
SRAT table.

The address ranges of vNVDIMM in QEMU are allocated from the
hot-pluggable address space, which is entirely covered by one SRAT
memory affinity structure. However, users can set the vNVDIMM
proximity domain in NFIT SPA range structure by the 'node' property of
'-device nvdimm' to a value different than the one in the above SRAT
memory affinity structure.

In order to solve such proximity domain mismatch, this patch builds
one SRAT memory affinity structure for each DIMM device present at
boot time, including both PC-DIMM and NVDIMM, with the proximity
domain specified in '-device pc-dimm' or '-device nvdimm'.

The remaining hot-pluggable address space is covered by one or multiple
SRAT memory affinity structures with the proximity domain of the last
node as before.


Changes in v3:
 * (Patch 1&2) Use qmp_pc_dimm_device_list to get information of DIMM
   devices and move it to separate patches.
 * (Patch 3) Replace while loop by a more readable for loop.
 * (Patch 3) Refactor the flag setting code.
 * (Patch 3) s/'static-plugged'/'present at boot time' in commit message.

Changes in v2:
 * Build SRAT memory affinity structures of PC-DIMM devices as well.
 * Add test cases.


Haozhong Zhang (5):
  pc-dimm: refactor qmp_pc_dimm_device_list
  qmp: distinguish PC-DIMM and NVDIMM in MemoryDeviceInfoList
  hw/acpi-build: build SRAT memory affinity structures for DIMM devices
  tests/bios-tables-test: allow setting extra machine options
  tests/bios-tables-test: add test cases for DIMM proximity

 hmp.c |  14 +++--
 hw/i386/acpi-build.c  |  60 +++--
 hw/mem/pc-dimm.c  |  99 --
 hw/ppc/spapr.c|   3 +-
 include/hw/mem/pc-dimm.h  |   2 +-
 numa.c|  23 
 qapi-schema.json  |  18 ++-
 qmp.c |   7 +--
 stubs/qmp_pc_dimm.c   |   4 +-
 tests/acpi-test-data/pc/APIC.dimmpxm  | Bin 0 -> 136 bytes
 tests/acpi-test-data/pc/DSDT.dimmpxm  | Bin 0 -> 6710 bytes
 tests/acpi-test-data/pc/NFIT.dimmpxm  | Bin 0 -> 224 bytes
 tests/acpi-test-data/pc/SRAT.dimmpxm  | Bin 0 -> 416 bytes
 tests/acpi-test-data/pc/SSDT.dimmpxm  | Bin 0 -> 685 bytes
 tests/acpi-test-data/q35/APIC.dimmpxm | Bin 0 -> 136 bytes
 tests/acpi-test-data/q35/DSDT.dimmpxm | Bin 0 -> 9394 bytes
 tests/acpi-test-data/q35/NFIT.dimmpxm | Bin 0 -> 224 bytes
 tests/acpi-test-data/q35/SRAT.dimmpxm | Bin 0 -> 416 bytes
 tests/acpi-test-data/q35/SSDT.dimmpxm | Bin 0 -> 685 bytes
 tests/bios-tables-test.c  |  78 +--
 20 files changed, 225 insertions(+), 83 deletions(-)
 create mode 100644 tests/acpi-test-data/pc/APIC.dimmpxm
 create mode 100644 tests/acpi-test-data/pc/DSDT.dimmpxm
 create mode 100644 tests/acpi-test-data/pc/NFIT.dimmpxm
 create mode 100644 tests/acpi-test-data/pc/SRAT.dimmpxm
 create mode 100644 tests/acpi-test-data/pc/SSDT.dimmpxm
 create mode 100644 tests/acpi-test-data/q35/APIC.dimmpxm
 create mode 100644 tests/acpi-test-data/q35/DSDT.dimmpxm
 create mode 100644 tests/acpi-test-data/q35/NFIT.dimmpxm
 create mode 100644 tests/acpi-test-data/q35/SRAT.dimmpxm
 create mode 100644 tests/acpi-test-data/q35/SSDT.dimmpxm

-- 
2.14.1




[Qemu-devel] [PATCH v3 4/5] tests/bios-tables-test: allow setting extra machine options

2018-03-04 Thread Haozhong Zhang
Some test cases may require extra machine options than those used in
the current test_acpi_ones(), e.g., nvdimm test cases require the
machine option 'nvdimm=on'.

Signed-off-by: Haozhong Zhang 
---
 tests/bios-tables-test.c | 45 +
 1 file changed, 29 insertions(+), 16 deletions(-)

diff --git a/tests/bios-tables-test.c b/tests/bios-tables-test.c
index 65b271a173..d45181aa51 100644
--- a/tests/bios-tables-test.c
+++ b/tests/bios-tables-test.c
@@ -654,17 +654,22 @@ static void test_smbios_structs(test_data *data)
 }
 }
 
-static void test_acpi_one(const char *params, test_data *data)
+static void test_acpi_one(const char *extra_machine_opts,
+  const char *params, test_data *data)
 {
 char *args;
 
 /* Disable kernel irqchip to be able to override apic irq0. */
-args = g_strdup_printf("-machine %s,accel=%s,kernel-irqchip=off "
+args = g_strdup_printf("-machine %s,accel=%s,kernel-irqchip=off",
+   data->machine, "kvm:tcg");
+if (extra_machine_opts) {
+args = g_strdup_printf("%s,%s", args, extra_machine_opts);
+}
+args = g_strdup_printf("%s "
"-net none -display none %s "
"-drive id=hd0,if=none,file=%s,format=raw "
"-device ide-hd,drive=hd0 ",
-   data->machine, "kvm:tcg",
-   params ? params : "", disk);
+   args, params ? params : "", disk);
 
 qtest_start(args);
 
@@ -711,7 +716,7 @@ static void test_acpi_piix4_tcg(void)
 data.machine = MACHINE_PC;
 data.required_struct_types = base_required_struct_types;
 data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types);
-test_acpi_one(NULL, );
+test_acpi_one(NULL, NULL, );
 free_test_data();
 }
 
@@ -724,7 +729,7 @@ static void test_acpi_piix4_tcg_bridge(void)
 data.variant = ".bridge";
 data.required_struct_types = base_required_struct_types;
 data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types);
-test_acpi_one("-device pci-bridge,chassis_nr=1", );
+test_acpi_one(NULL, "-device pci-bridge,chassis_nr=1", );
 free_test_data();
 }
 
@@ -736,7 +741,7 @@ static void test_acpi_q35_tcg(void)
 data.machine = MACHINE_Q35;
 data.required_struct_types = base_required_struct_types;
 data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types);
-test_acpi_one(NULL, );
+test_acpi_one(NULL, NULL, );
 free_test_data();
 }
 
@@ -749,7 +754,7 @@ static void test_acpi_q35_tcg_bridge(void)
 data.variant = ".bridge";
 data.required_struct_types = base_required_struct_types;
 data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types);
-test_acpi_one("-device pci-bridge,chassis_nr=1",
+test_acpi_one(NULL, "-device pci-bridge,chassis_nr=1",
   );
 free_test_data();
 }
@@ -761,7 +766,8 @@ static void test_acpi_piix4_tcg_cphp(void)
 memset(, 0, sizeof(data));
 data.machine = MACHINE_PC;
 data.variant = ".cphp";
-test_acpi_one("-smp 2,cores=3,sockets=2,maxcpus=6"
+test_acpi_one(NULL,
+  "-smp 2,cores=3,sockets=2,maxcpus=6"
   " -numa node -numa node"
   " -numa dist,src=0,dst=1,val=21",
   );
@@ -775,7 +781,8 @@ static void test_acpi_q35_tcg_cphp(void)
 memset(, 0, sizeof(data));
 data.machine = MACHINE_Q35;
 data.variant = ".cphp";
-test_acpi_one(" -smp 2,cores=3,sockets=2,maxcpus=6"
+test_acpi_one(NULL,
+  " -smp 2,cores=3,sockets=2,maxcpus=6"
   " -numa node -numa node"
   " -numa dist,src=0,dst=1,val=21",
   );
@@ -795,7 +802,8 @@ static void test_acpi_q35_tcg_ipmi(void)
 data.variant = ".ipmibt";
 data.required_struct_types = ipmi_required_struct_types;
 data.required_struct_types_len = ARRAY_SIZE(ipmi_required_struct_types);
-test_acpi_one("-device ipmi-bmc-sim,id=bmc0"
+test_acpi_one(NULL,
+  "-device ipmi-bmc-sim,id=bmc0"
   " -device isa-ipmi-bt,bmc=bmc0",
   );
 free_test_data();
@@ -813,7 +821,8 @@ static void test_acpi_piix4_tcg_ipmi(void)
 data.variant = ".ipmikcs";
 data.required_struct_types = ipmi_required_struct_types;
 data.required_struct_types_len = ARRAY_SIZE(ipmi_required_struct_types);
-test_acpi_one("-device ipmi-bmc-sim,id=bmc0"
+test_acpi_one(NULL,
+  "-device ipmi-bmc-sim,id=bmc0"
   " -device isa-ipmi-kcs,irq=0,bmc=bmc0",
   );
 free_test_data();
@@ -826,7 +835,8 @@ static void test_acpi_q35_tcg_memhp(void)
 memset(, 0, sizeof(data));
 data.machine = MACHINE_Q35;
 data.variant = ".memhp";
-test_acpi_one(" -m 128,slots=3,maxmem=1G"
+test_acpi_one(NULL,
+

[Qemu-devel] [PATCH v3 2/5] qmp: distinguish PC-DIMM and NVDIMM in MemoryDeviceInfoList

2018-03-04 Thread Haozhong Zhang
It may need to treat PC-DIMM and NVDIMM differently, e.g., when
deciding the necessity of non-volatile flag bit in SRAT memory
affinity structures.

NVDIMMDeviceInfo, which inherits from PCDIMMDeviceInfo, is added to
union type MemoryDeviceInfo to record information of NVDIMM devices.
The NVDIMM-specific data is currently left empty and will be filled
when necessary in the future.

Signed-off-by: Haozhong Zhang 
---
 hmp.c| 14 +++---
 hw/mem/pc-dimm.c | 20 ++--
 numa.c   | 19 +--
 qapi-schema.json | 18 +-
 4 files changed, 59 insertions(+), 12 deletions(-)

diff --git a/hmp.c b/hmp.c
index ae86bfbade..3f06407c5e 100644
--- a/hmp.c
+++ b/hmp.c
@@ -2413,7 +2413,18 @@ void hmp_info_memory_devices(Monitor *mon, const QDict 
*qdict)
 switch (value->type) {
 case MEMORY_DEVICE_INFO_KIND_DIMM:
 di = value->u.dimm.data;
+break;
+
+case MEMORY_DEVICE_INFO_KIND_NVDIMM:
+di = qapi_NVDIMMDeviceInfo_base(value->u.nvdimm.data);
+break;
+
+default:
+di = NULL;
+break;
+}
 
+if (di) {
 monitor_printf(mon, "Memory device [%s]: \"%s\"\n",
MemoryDeviceInfoKind_str(value->type),
di->id ? di->id : "");
@@ -2426,9 +2437,6 @@ void hmp_info_memory_devices(Monitor *mon, const QDict 
*qdict)
di->hotplugged ? "true" : "false");
 monitor_printf(mon, "  hotpluggable: %s\n",
di->hotpluggable ? "true" : "false");
-break;
-default:
-break;
 }
 }
 }
diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c
index 4d050fe2cd..866ecc699a 100644
--- a/hw/mem/pc-dimm.c
+++ b/hw/mem/pc-dimm.c
@@ -20,6 +20,7 @@
 
 #include "qemu/osdep.h"
 #include "hw/mem/pc-dimm.h"
+#include "hw/mem/nvdimm.h"
 #include "qapi/error.h"
 #include "qemu/config-file.h"
 #include "qapi/visitor.h"
@@ -249,10 +250,19 @@ MemoryDeviceInfoList *qmp_pc_dimm_device_list(void)
 Object *obj = OBJECT(dimm);
 MemoryDeviceInfoList *elem = g_new0(MemoryDeviceInfoList, 1);
 MemoryDeviceInfo *info = g_new0(MemoryDeviceInfo, 1);
-PCDIMMDeviceInfo *di = g_new0(PCDIMMDeviceInfo, 1);
+PCDIMMDeviceInfo *di;
+NVDIMMDeviceInfo *ndi;
+bool is_nvdimm = object_dynamic_cast(obj, TYPE_NVDIMM);
 DeviceClass *dc = DEVICE_GET_CLASS(obj);
 DeviceState *dev = DEVICE(obj);
 
+if (!is_nvdimm) {
+di = g_new0(PCDIMMDeviceInfo, 1);
+} else {
+ndi = g_new0(NVDIMMDeviceInfo, 1);
+di = qapi_NVDIMMDeviceInfo_base(ndi);
+}
+
 if (dev->id) {
 di->has_id = true;
 di->id = g_strdup(dev->id);
@@ -265,7 +275,13 @@ MemoryDeviceInfoList *qmp_pc_dimm_device_list(void)
 di->size = object_property_get_uint(obj, PC_DIMM_SIZE_PROP, NULL);
 di->memdev = object_get_canonical_path(OBJECT(dimm->hostmem));
 
-info->u.dimm.data = di;
+if (!is_nvdimm) {
+info->u.dimm.data = di;
+info->type = MEMORY_DEVICE_INFO_KIND_DIMM;
+} else {
+info->u.nvdimm.data = ndi;
+info->type = MEMORY_DEVICE_INFO_KIND_NVDIMM;
+}
 elem->value = info;
 elem->next = NULL;
 if (prev) {
diff --git a/numa.c b/numa.c
index c6734ceb8c..23c4371e51 100644
--- a/numa.c
+++ b/numa.c
@@ -529,18 +529,25 @@ static void numa_stat_memory_devices(NumaNodeMem 
node_mem[])
 
 if (value) {
 switch (value->type) {
-case MEMORY_DEVICE_INFO_KIND_DIMM: {
+case MEMORY_DEVICE_INFO_KIND_DIMM:
 pcdimm_info = value->u.dimm.data;
+break;
+
+case MEMORY_DEVICE_INFO_KIND_NVDIMM:
+pcdimm_info = qapi_NVDIMMDeviceInfo_base(value->u.nvdimm.data);
+break;
+
+default:
+pcdimm_info = NULL;
+break;
+}
+
+if (pcdimm_info) {
 node_mem[pcdimm_info->node].node_mem += pcdimm_info->size;
 if (pcdimm_info->hotpluggable && pcdimm_info->hotplugged) {
 node_mem[pcdimm_info->node].node_plugged_mem +=
 pcdimm_info->size;
 }
-break;
-}
-
-default:
-break;
 }
 }
 }
diff --git a/qapi-schema.json b/qapi-schema.json
index cd98a94388..1c2d281749 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2920,6 +2920,18 @@
   }
 }
 
+##
+# @NVDIMMDeviceInfo:
+#
+# NVDIMMDevice state information
+#
+# Since: 2.12
+##
+{ 'struct': 'NVDIMMDeviceInfo',
+  'base': 'PCDIMMDeviceInfo',
+  'data': 

[Qemu-devel] [PATCH 0/9] chardev: qio related non-default context support

2018-03-04 Thread Peter Xu
Based-on: <20180305064324.9238-1-pet...@redhat.com>

This series is based on the QIO part:
  [PATCH v3 0/6] qio: general non-default GMainContext support

And it is splitted out from version 2 of the QIO series V2:

  http://lists.gnu.org/archive/html/qemu-devel/2018-03/msg00016.html

Please review, thanks.

Peter Xu (9):
  vl: export machine_init_done
  chardev: fix leak in tcp_chr_telnet_init_io()
  chardev: update net listener gcontext
  chardev: allow telnet gsource to switch gcontext
  chardev: introduce chr_machine_done hook
  chardev: use chardev's gcontext for async connect
  chardev: tcp: postpone async connection setup
  chardev: tcp: let TLS run on chardev context
  chardev: tcp: postpone TLS work until machine done

 chardev/char-mux.c|  33 --
 chardev/char-socket.c | 153 ++
 chardev/char.c|  43 ++---
 include/chardev/char.h|   2 +
 include/sysemu/sysemu.h   |   2 +
 stubs/machine-init-done.c |   2 +
 vl.c  |   4 +-
 7 files changed, 169 insertions(+), 70 deletions(-)

-- 
2.14.3




[Qemu-devel] [PATCH 7/9] chardev: tcp: postpone async connection setup

2018-03-04 Thread Peter Xu
This patch allows the socket chardev async connection be setup with
non-default gcontext.  We do it by postponing the setup to machine done,
since until then we can know which context we should run the async
operation on.

Reviewed-by: Paolo Bonzini 
Signed-off-by: Peter Xu 
---
 chardev/char-socket.c | 17 ++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 1ce5adad9a..165612845a 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -1004,9 +1004,8 @@ static void qmp_chardev_open_socket(Chardev *chr,
 s->reconnect_time = reconnect;
 }
 
-if (s->reconnect_time) {
-tcp_chr_connect_async(chr);
-} else {
+/* If reconnect_time is set, will do that in chr_machine_done. */
+if (!s->reconnect_time) {
 if (s->is_listen) {
 char *name;
 s->listener = qio_net_listener_new();
@@ -1138,6 +1137,17 @@ char_socket_get_connected(Object *obj, Error **errp)
 return s->connected;
 }
 
+static int tcp_chr_machine_done_hook(Chardev *chr)
+{
+SocketChardev *s = SOCKET_CHARDEV(chr);
+
+if (s->reconnect_time) {
+tcp_chr_connect_async(chr);
+}
+
+return 0;
+}
+
 static void char_socket_class_init(ObjectClass *oc, void *data)
 {
 ChardevClass *cc = CHARDEV_CLASS(oc);
@@ -1153,6 +1163,7 @@ static void char_socket_class_init(ObjectClass *oc, void 
*data)
 cc->chr_add_client = tcp_chr_add_client;
 cc->chr_add_watch = tcp_chr_add_watch;
 cc->chr_update_read_handler = tcp_chr_update_read_handler;
+cc->chr_machine_done = tcp_chr_machine_done_hook;
 
 object_class_property_add(oc, "addr", "SocketAddress",
   char_socket_get_addr, NULL,
-- 
2.14.3




[Qemu-devel] [PATCH 3/9] chardev: update net listener gcontext

2018-03-04 Thread Peter Xu
TCP chardevs can be using QIO network listeners working in the
background when in listening mode.  However the network listeners are
always running in main context.  This can race with chardevs that are
running in non-main contexts.

To solve this, we need to re-setup the net listeners in
tcp_chr_update_read_handler() with the newly cached gcontext.

Signed-off-by: Peter Xu 
---
 chardev/char-socket.c | 26 --
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 205ee377a4..5aa01e15ff 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -422,8 +422,8 @@ static void tcp_chr_disconnect(Chardev *chr)
 tcp_chr_free_connection(chr);
 
 if (s->listener) {
-qio_net_listener_set_client_func(s->listener, tcp_chr_accept,
- chr, NULL);
+qio_net_listener_set_client_func_full(s->listener, tcp_chr_accept,
+  chr, NULL, chr->gcontext);
 }
 update_disconnected_filename(s);
 if (emit_close) {
@@ -559,6 +559,16 @@ static void tcp_chr_update_read_handler(Chardev *chr)
 {
 SocketChardev *s = SOCKET_CHARDEV(chr);
 
+if (s->listener) {
+/*
+ * It's possible that chardev context is changed in
+ * qemu_chr_be_update_read_handlers().  Reset it for QIO net
+ * listener if there is.
+ */
+qio_net_listener_set_client_func_full(s->listener, tcp_chr_accept,
+  chr, NULL, chr->gcontext);
+}
+
 if (!s->connected) {
 return;
 }
@@ -743,7 +753,8 @@ static int tcp_chr_new_client(Chardev *chr, 
QIOChannelSocket *sioc)
 qio_channel_set_delay(s->ioc, false);
 }
 if (s->listener) {
-qio_net_listener_set_client_func(s->listener, NULL, NULL, NULL);
+qio_net_listener_set_client_func_full(s->listener, NULL, NULL,
+  NULL, chr->gcontext);
 }
 
 if (s->tls_creds) {
@@ -824,7 +835,8 @@ static void char_socket_finalize(Object *obj)
 tcp_chr_reconn_timer_cancel(s);
 qapi_free_SocketAddress(s->addr);
 if (s->listener) {
-qio_net_listener_set_client_func(s->listener, NULL, NULL, NULL);
+qio_net_listener_set_client_func_full(s->listener, NULL, NULL,
+  NULL, chr->gcontext);
 object_unref(OBJECT(s->listener));
 }
 if (s->tls_creds) {
@@ -980,8 +992,10 @@ static void qmp_chardev_open_socket(Chardev *chr,
 return;
 }
 if (!s->ioc) {
-qio_net_listener_set_client_func(s->listener, tcp_chr_accept,
- chr, NULL);
+qio_net_listener_set_client_func_full(s->listener,
+  tcp_chr_accept,
+  chr, NULL,
+  chr->gcontext);
 }
 } else if (qemu_chr_wait_connected(chr, errp) < 0) {
 goto error;
-- 
2.14.3




[Qemu-devel] [PATCH 5/9] chardev: introduce chr_machine_done hook

2018-03-04 Thread Peter Xu
Introduce ChardevClass.chr_machine_done() hook so that chardevs can run
customized procedures after machine init.

There was an existing mux user already that did similar thing but used a
raw machine done notifier.  Generalize it into a framework, and let the
mux chardevs provide such a class-specific hook to achieve the same
thing.  Then we can move the mux related code to the char-mux.c file.

Since at it, replace the mux_realized variable with the global
machine_init_done varible.

This notifier framework will be further leverged by other type of
chardevs soon.

Reviewed-by: Paolo Bonzini 
Signed-off-by: Peter Xu 
---
 chardev/char-mux.c | 33 +
 chardev/char.c | 43 +--
 include/chardev/char.h |  2 ++
 3 files changed, 48 insertions(+), 30 deletions(-)

diff --git a/chardev/char-mux.c b/chardev/char-mux.c
index d48e78103a..1b925c8dec 100644
--- a/chardev/char-mux.c
+++ b/chardev/char-mux.c
@@ -27,6 +27,7 @@
 #include "qemu/option.h"
 #include "chardev/char.h"
 #include "sysemu/block-backend.h"
+#include "sysemu/sysemu.h"
 #include "chardev/char-mux.h"
 
 /* MUX driver for serial I/O splitting */
@@ -230,14 +231,12 @@ static void mux_chr_read(void *opaque, const uint8_t 
*buf, int size)
 }
 }
 
-bool muxes_realized;
-
 void mux_chr_send_all_event(Chardev *chr, int event)
 {
 MuxChardev *d = MUX_CHARDEV(chr);
 int i;
 
-if (!muxes_realized) {
+if (!machine_init_done) {
 return;
 }
 
@@ -327,7 +326,7 @@ static void qemu_chr_open_mux(Chardev *chr,
 /* only default to opened state if we've realized the initial
  * set of muxes
  */
-*be_opened = muxes_realized;
+*be_opened = machine_init_done;
 qemu_chr_fe_init(>chr, drv, errp);
 }
 
@@ -347,6 +346,31 @@ static void qemu_chr_parse_mux(QemuOpts *opts, 
ChardevBackend *backend,
 mux->chardev = g_strdup(chardev);
 }
 
+/**
+ * Called after processing of default and command-line-specified
+ * chardevs to deliver CHR_EVENT_OPENED events to any FEs attached
+ * to a mux chardev. This is done here to ensure that
+ * output/prompts/banners are only displayed for the FE that has
+ * focus when initial command-line processing/machine init is
+ * completed.
+ *
+ * After this point, any new FE attached to any new or existing
+ * mux will receive CHR_EVENT_OPENED notifications for the BE
+ * immediately.
+ */
+static int open_muxes(Chardev *chr)
+{
+/* send OPENED to all already-attached FEs */
+mux_chr_send_all_event(chr, CHR_EVENT_OPENED);
+/*
+ * mark mux as OPENED so any new FEs will immediately receive
+ * OPENED event
+ */
+qemu_chr_be_event(chr, CHR_EVENT_OPENED);
+
+return 0;
+}
+
 static void char_mux_class_init(ObjectClass *oc, void *data)
 {
 ChardevClass *cc = CHARDEV_CLASS(oc);
@@ -357,6 +381,7 @@ static void char_mux_class_init(ObjectClass *oc, void *data)
 cc->chr_accept_input = mux_chr_accept_input;
 cc->chr_add_watch = mux_chr_add_watch;
 cc->chr_be_event = mux_chr_be_event;
+cc->chr_machine_done = open_muxes;
 }
 
 static const TypeInfo char_mux_type_info = {
diff --git a/chardev/char.c b/chardev/char.c
index 01d979a1da..fda820863c 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -281,40 +281,31 @@ static const TypeInfo char_type_info = {
 .class_init = char_class_init,
 };
 
-/**
- * Called after processing of default and command-line-specified
- * chardevs to deliver CHR_EVENT_OPENED events to any FEs attached
- * to a mux chardev. This is done here to ensure that
- * output/prompts/banners are only displayed for the FE that has
- * focus when initial command-line processing/machine init is
- * completed.
- *
- * After this point, any new FE attached to any new or existing
- * mux will receive CHR_EVENT_OPENED notifications for the BE
- * immediately.
- */
-static int open_muxes(Object *child, void *opaque)
+static int chardev_machine_done_notify_one(Object *child, void *opaque)
 {
-if (CHARDEV_IS_MUX(child)) {
-/* send OPENED to all already-attached FEs */
-mux_chr_send_all_event(CHARDEV(child), CHR_EVENT_OPENED);
-/* mark mux as OPENED so any new FEs will immediately receive
- * OPENED event
- */
-qemu_chr_be_event(CHARDEV(child), CHR_EVENT_OPENED);
+Chardev *chr = (Chardev *)child;
+ChardevClass *class = CHARDEV_GET_CLASS(chr);
+
+if (class->chr_machine_done) {
+return class->chr_machine_done(chr);
 }
 
 return 0;
 }
 
-static void muxes_realize_done(Notifier *notifier, void *unused)
+static void chardev_machine_done_hook(Notifier *notifier, void *unused)
 {
-muxes_realized = true;
-object_child_foreach(get_chardevs_root(), open_muxes, NULL);
+int ret = object_child_foreach(get_chardevs_root(),
+   chardev_machine_done_notify_one, NULL);
+
+if (ret) {
+

[Qemu-devel] [PATCH 2/9] chardev: fix leak in tcp_chr_telnet_init_io()

2018-03-04 Thread Peter Xu
Need to free TCPChardevTelnetInit when session established.

Since at it, switch to use G_SOURCE_* macros.

Reviewed-by: Daniel P. Berrange 
Reviewed-by: Paolo Bonzini 
Signed-off-by: Peter Xu 
---
 chardev/char-socket.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 113feaf948..205ee377a4 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -591,19 +591,23 @@ static gboolean tcp_chr_telnet_init_io(QIOChannel *ioc,
 ret = 0;
 } else {
 tcp_chr_disconnect(init->chr);
-return FALSE;
+goto end;
 }
 }
 init->buflen -= ret;
 
 if (init->buflen == 0) {
 tcp_chr_connect(init->chr);
-return FALSE;
+goto end;
 }
 
 memmove(init->buf, init->buf + ret, init->buflen);
 
-return TRUE;
+return G_SOURCE_CONTINUE;
+
+end:
+g_free(init);
+return G_SOURCE_REMOVE;
 }
 
 static void tcp_chr_telnet_init(Chardev *chr)
-- 
2.14.3




[Qemu-devel] [PATCH 6/9] chardev: use chardev's gcontext for async connect

2018-03-04 Thread Peter Xu
Generalize the function to create the async QIO task connection.  Also,
fix the context pointer to use the chardev's gcontext.

Reviewed-by: Paolo Bonzini 
Signed-off-by: Peter Xu 
---
 chardev/char-socket.c | 25 ++---
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index c22b3f330c..1ce5adad9a 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -901,11 +901,22 @@ cleanup:
 object_unref(OBJECT(sioc));
 }
 
+static void tcp_chr_connect_async(Chardev *chr)
+{
+SocketChardev *s = SOCKET_CHARDEV(chr);
+QIOChannelSocket *sioc;
+
+sioc = qio_channel_socket_new();
+tcp_chr_set_client_ioc_name(chr, sioc);
+qio_channel_socket_connect_async(sioc, s->addr,
+ qemu_chr_socket_connected,
+ chr, NULL, chr->gcontext);
+}
+
 static gboolean socket_reconnect_timeout(gpointer opaque)
 {
 Chardev *chr = CHARDEV(opaque);
 SocketChardev *s = SOCKET_CHARDEV(opaque);
-QIOChannelSocket *sioc;
 
 g_source_unref(s->reconnect_timer);
 s->reconnect_timer = NULL;
@@ -914,11 +925,7 @@ static gboolean socket_reconnect_timeout(gpointer opaque)
 return false;
 }
 
-sioc = qio_channel_socket_new();
-tcp_chr_set_client_ioc_name(chr, sioc);
-qio_channel_socket_connect_async(sioc, s->addr,
- qemu_chr_socket_connected,
- chr, NULL, NULL);
+tcp_chr_connect_async(chr);
 
 return false;
 }
@@ -998,11 +1005,7 @@ static void qmp_chardev_open_socket(Chardev *chr,
 }
 
 if (s->reconnect_time) {
-sioc = qio_channel_socket_new();
-tcp_chr_set_client_ioc_name(chr, sioc);
-qio_channel_socket_connect_async(sioc, s->addr,
- qemu_chr_socket_connected,
- chr, NULL, NULL);
+tcp_chr_connect_async(chr);
 } else {
 if (s->is_listen) {
 char *name;
-- 
2.14.3




[Qemu-devel] [PATCH 1/9] vl: export machine_init_done

2018-03-04 Thread Peter Xu
We have that variable but not exported.  Export that so modules can have
a way to poke on whether machine init has finished.

Meanwhile, set that up even before calling the notifiers, so that
notifiers who may depend on this field will get a correct answer.

Suggested-by: Paolo Bonzini 
Signed-off-by: Peter Xu 
---
 include/sysemu/sysemu.h   | 2 ++
 stubs/machine-init-done.c | 2 ++
 vl.c  | 4 ++--
 3 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 77bb3da582..3f0f35610b 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -86,6 +86,8 @@ void qemu_system_guest_panicked(GuestPanicInformation *info);
 void qemu_add_exit_notifier(Notifier *notify);
 void qemu_remove_exit_notifier(Notifier *notify);
 
+extern bool machine_init_done;
+
 void qemu_add_machine_init_done_notifier(Notifier *notify);
 void qemu_remove_machine_init_done_notifier(Notifier *notify);
 
diff --git a/stubs/machine-init-done.c b/stubs/machine-init-done.c
index 9a0d62514f..4121f1709b 100644
--- a/stubs/machine-init-done.c
+++ b/stubs/machine-init-done.c
@@ -2,6 +2,8 @@
 #include "qemu-common.h"
 #include "sysemu/sysemu.h"
 
+bool machine_init_done = true;
+
 void qemu_add_machine_init_done_notifier(Notifier *notify)
 {
 }
diff --git a/vl.c b/vl.c
index a33ac008fb..5e8d47 100644
--- a/vl.c
+++ b/vl.c
@@ -2712,7 +2712,7 @@ static void qemu_run_exit_notifiers(void)
 notifier_list_notify(_notifiers, NULL);
 }
 
-static bool machine_init_done;
+bool machine_init_done;
 
 void qemu_add_machine_init_done_notifier(Notifier *notify)
 {
@@ -2729,8 +2729,8 @@ void qemu_remove_machine_init_done_notifier(Notifier 
*notify)
 
 static void qemu_run_machine_init_done_notifiers(void)
 {
-notifier_list_notify(_init_done_notifiers, NULL);
 machine_init_done = true;
+notifier_list_notify(_init_done_notifiers, NULL);
 }
 
 static const QEMUOption *lookup_opt(int argc, char **argv,
-- 
2.14.3




[Qemu-devel] [PATCH 9/9] chardev: tcp: postpone TLS work until machine done

2018-03-04 Thread Peter Xu
TLS handshake may create background GSource tasks, while we won't know
the correct GMainContext until the whole chardev (including frontend)
inited.  Let's postpone the initial TLS handshake until machine done.

For dynamically created tcp chardev, we don't postpone that by checking
the init_machine_done variable.

Signed-off-by: Peter Xu 
---
 chardev/char-socket.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index bd40864f87..997c70dd7d 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -31,6 +31,7 @@
 #include "qemu/option.h"
 #include "qapi/error.h"
 #include "qapi/clone-visitor.h"
+#include "sysemu/sysemu.h"
 
 #include "chardev/char-io.h"
 
@@ -722,6 +723,11 @@ static void tcp_chr_tls_init(Chardev *chr)
 Error *err = NULL;
 gchar *name;
 
+if (!machine_init_done) {
+/* This will be postponed to machine_done notifier */
+return;
+}
+
 if (s->is_listen) {
 tioc = qio_channel_tls_new_server(
 s->ioc, s->tls_creds,
@@ -1145,6 +1151,10 @@ static int tcp_chr_machine_done_hook(Chardev *chr)
 tcp_chr_connect_async(chr);
 }
 
+if (s->tls_creds) {
+tcp_chr_tls_init(chr);
+}
+
 return 0;
 }
 
-- 
2.14.3




[Qemu-devel] [PATCH v3 5/6] qio: non-default context for async conn

2018-03-04 Thread Peter Xu
We have worked on qio_task_run_in_thread() already.  Further, let
all the qio channel APIs use that context.

Signed-off-by: Peter Xu 
---
 chardev/char-socket.c  |  4 ++--
 include/io/channel-socket.h| 15 ---
 io/channel-socket.c| 15 +--
 migration/socket.c |  3 ++-
 tests/test-io-channel-socket.c |  4 ++--
 5 files changed, 27 insertions(+), 14 deletions(-)

diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index bdd6cff5f6..754d82679a 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -866,7 +866,7 @@ static gboolean socket_reconnect_timeout(gpointer opaque)
 tcp_chr_set_client_ioc_name(chr, sioc);
 qio_channel_socket_connect_async(sioc, s->addr,
  qemu_chr_socket_connected,
- chr, NULL);
+ chr, NULL, NULL);
 
 return false;
 }
@@ -950,7 +950,7 @@ static void qmp_chardev_open_socket(Chardev *chr,
 tcp_chr_set_client_ioc_name(chr, sioc);
 qio_channel_socket_connect_async(sioc, s->addr,
  qemu_chr_socket_connected,
- chr, NULL);
+ chr, NULL, NULL);
 } else {
 if (s->is_listen) {
 char *name;
diff --git a/include/io/channel-socket.h b/include/io/channel-socket.h
index 53801f6042..d7134d2cd6 100644
--- a/include/io/channel-socket.h
+++ b/include/io/channel-socket.h
@@ -101,6 +101,8 @@ int qio_channel_socket_connect_sync(QIOChannelSocket *ioc,
  * @callback: the function to invoke on completion
  * @opaque: user data to pass to @callback
  * @destroy: the function to free @opaque
+ * @context: the context to run the async task. If %NULL, the default
+ *   context will be used.
  *
  * Attempt to connect to the address @addr. This method
  * will run in the background so the caller will regain
@@ -113,7 +115,8 @@ void qio_channel_socket_connect_async(QIOChannelSocket *ioc,
   SocketAddress *addr,
   QIOTaskFunc callback,
   gpointer opaque,
-  GDestroyNotify destroy);
+  GDestroyNotify destroy,
+  GMainContext *context);
 
 
 /**
@@ -138,6 +141,8 @@ int qio_channel_socket_listen_sync(QIOChannelSocket *ioc,
  * @callback: the function to invoke on completion
  * @opaque: user data to pass to @callback
  * @destroy: the function to free @opaque
+ * @context: the context to run the async task. If %NULL, the default
+ *   context will be used.
  *
  * Attempt to listen to the address @addr. This method
  * will run in the background so the caller will regain
@@ -150,7 +155,8 @@ void qio_channel_socket_listen_async(QIOChannelSocket *ioc,
  SocketAddress *addr,
  QIOTaskFunc callback,
  gpointer opaque,
- GDestroyNotify destroy);
+ GDestroyNotify destroy,
+ GMainContext *context);
 
 
 /**
@@ -179,6 +185,8 @@ int qio_channel_socket_dgram_sync(QIOChannelSocket *ioc,
  * @callback: the function to invoke on completion
  * @opaque: user data to pass to @callback
  * @destroy: the function to free @opaque
+ * @context: the context to run the async task. If %NULL, the default
+ *   context will be used.
  *
  * Attempt to initialize a datagram socket bound to
  * @localAddr and communicating with peer @remoteAddr.
@@ -194,7 +202,8 @@ void qio_channel_socket_dgram_async(QIOChannelSocket *ioc,
 SocketAddress *remoteAddr,
 QIOTaskFunc callback,
 gpointer opaque,
-GDestroyNotify destroy);
+GDestroyNotify destroy,
+GMainContext *context);
 
 
 /**
diff --git a/io/channel-socket.c b/io/channel-socket.c
index 4224ce323a..18c139c365 100644
--- a/io/channel-socket.c
+++ b/io/channel-socket.c
@@ -173,7 +173,8 @@ void qio_channel_socket_connect_async(QIOChannelSocket *ioc,
   SocketAddress *addr,
   QIOTaskFunc callback,
   gpointer opaque,
-  GDestroyNotify destroy)
+  GDestroyNotify destroy,
+  GMainContext *context)
 {
 QIOTask *task = qio_task_new(
 OBJECT(ioc), callback, opaque, destroy);
@@ -188,7 +189,7 @@ void qio_channel_socket_connect_async(QIOChannelSocket 

[Qemu-devel] [PATCH v3 4/6] qio: non-default context for threaded qtask

2018-03-04 Thread Peter Xu
qio_task_run_in_thread() allows main thread to run blocking operations
in the background. However it has an assumption on that it's always
working with the default context. This patch tries to allow the threaded
QIO task framework to run with non-default gcontext.

Currently no functional change so far, so the QIOTasks are still always
running on main context.

Reviewed-by: Daniel P. Berrange 
Signed-off-by: Peter Xu 
---
 include/io/task.h|  7 +--
 io/channel-socket.c  |  9 ++---
 io/dns-resolver.c|  3 ++-
 io/task.c| 20 ++--
 tests/test-io-task.c |  2 ++
 5 files changed, 33 insertions(+), 8 deletions(-)

diff --git a/include/io/task.h b/include/io/task.h
index 6021f51336..9e09b95b2e 100644
--- a/include/io/task.h
+++ b/include/io/task.h
@@ -227,15 +227,18 @@ QIOTask *qio_task_new(Object *source,
  * @worker: the function to invoke in a thread
  * @opaque: opaque data to pass to @worker
  * @destroy: function to free @opaque
+ * @context: the context to run the complete hook. If %NULL, the
+ *   default context will be used.
  *
  * Run a task in a background thread. When @worker
  * returns it will call qio_task_complete() in
- * the main event thread context.
+ * the event thread context that provided.
  */
 void qio_task_run_in_thread(QIOTask *task,
 QIOTaskWorker worker,
 gpointer opaque,
-GDestroyNotify destroy);
+GDestroyNotify destroy,
+GMainContext *context);
 
 /**
  * qio_task_complete:
diff --git a/io/channel-socket.c b/io/channel-socket.c
index 563e297357..4224ce323a 100644
--- a/io/channel-socket.c
+++ b/io/channel-socket.c
@@ -187,7 +187,8 @@ void qio_channel_socket_connect_async(QIOChannelSocket *ioc,
 qio_task_run_in_thread(task,
qio_channel_socket_connect_worker,
addrCopy,
-   (GDestroyNotify)qapi_free_SocketAddress);
+   (GDestroyNotify)qapi_free_SocketAddress,
+   NULL);
 }
 
 
@@ -245,7 +246,8 @@ void qio_channel_socket_listen_async(QIOChannelSocket *ioc,
 qio_task_run_in_thread(task,
qio_channel_socket_listen_worker,
addrCopy,
-   (GDestroyNotify)qapi_free_SocketAddress);
+   (GDestroyNotify)qapi_free_SocketAddress,
+   NULL);
 }
 
 
@@ -321,7 +323,8 @@ void qio_channel_socket_dgram_async(QIOChannelSocket *ioc,
 qio_task_run_in_thread(task,
qio_channel_socket_dgram_worker,
data,
-   qio_channel_socket_dgram_worker_free);
+   qio_channel_socket_dgram_worker_free,
+   NULL);
 }
 
 
diff --git a/io/dns-resolver.c b/io/dns-resolver.c
index c072d121c3..75c2ca9c4a 100644
--- a/io/dns-resolver.c
+++ b/io/dns-resolver.c
@@ -233,7 +233,8 @@ void qio_dns_resolver_lookup_async(QIODNSResolver *resolver,
 qio_task_run_in_thread(task,
qio_dns_resolver_lookup_worker,
data,
-   qio_dns_resolver_lookup_data_free);
+   qio_dns_resolver_lookup_data_free,
+   NULL);
 }
 
 
diff --git a/io/task.c b/io/task.c
index 1a0a1c7185..2886a2c1bc 100644
--- a/io/task.c
+++ b/io/task.c
@@ -77,6 +77,7 @@ struct QIOTaskThreadData {
 QIOTaskWorker worker;
 gpointer opaque;
 GDestroyNotify destroy;
+GMainContext *context;
 };
 
 
@@ -91,6 +92,10 @@ static gboolean qio_task_thread_result(gpointer opaque)
 data->destroy(data->opaque);
 }
 
+if (data->context) {
+g_main_context_unref(data->context);
+}
+
 g_free(data);
 
 return FALSE;
@@ -100,6 +105,7 @@ static gboolean qio_task_thread_result(gpointer opaque)
 static gpointer qio_task_thread_worker(gpointer opaque)
 {
 struct QIOTaskThreadData *data = opaque;
+GSource *idle;
 
 trace_qio_task_thread_run(data->task);
 data->worker(data->task, data->opaque);
@@ -110,7 +116,11 @@ static gpointer qio_task_thread_worker(gpointer opaque)
  * the worker results
  */
 trace_qio_task_thread_exit(data->task);
-g_idle_add(qio_task_thread_result, data);
+
+idle = g_idle_source_new();
+g_source_set_callback(idle, qio_task_thread_result, data, NULL);
+g_source_attach(idle, data->context);
+
 return NULL;
 }
 
@@ -118,15 +128,21 @@ static gpointer qio_task_thread_worker(gpointer opaque)
 void qio_task_run_in_thread(QIOTask *task,
 QIOTaskWorker worker,
 gpointer opaque,
-GDestroyNotify destroy)
+GDestroyNotify destroy,
+

[Qemu-devel] [PATCH v3 6/6] qio: non-default context for TLS handshake

2018-03-04 Thread Peter Xu
A new parameter "context" is added to qio_channel_tls_handshake() is to
allow the TLS to be run on a non-default context.  Still, no functional
change.

Signed-off-by: Peter Xu 
---
 chardev/char-socket.c   |  1 +
 include/io/channel-tls.h|  5 -
 io/channel-tls.c| 45 ++---
 migration/tls.c |  2 ++
 nbd/client.c|  1 +
 nbd/server.c|  1 +
 tests/test-io-channel-tls.c |  2 ++
 ui/vnc-auth-vencrypt.c  |  1 +
 ui/vnc-ws.c |  1 +
 9 files changed, 47 insertions(+), 12 deletions(-)

diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 754d82679a..113feaf948 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -702,6 +702,7 @@ static void tcp_chr_tls_init(Chardev *chr)
 qio_channel_tls_handshake(tioc,
   tcp_chr_tls_handshake,
   chr,
+  NULL,
   NULL);
 }
 
diff --git a/include/io/channel-tls.h b/include/io/channel-tls.h
index d157eb10e8..87fcaf9146 100644
--- a/include/io/channel-tls.h
+++ b/include/io/channel-tls.h
@@ -116,6 +116,8 @@ qio_channel_tls_new_client(QIOChannel *master,
  * @func: the callback to invoke when completed
  * @opaque: opaque data to pass to @func
  * @destroy: optional callback to free @opaque
+ * @context: the context that TLS handshake will run with. If %NULL,
+ *   the default context will be used
  *
  * Perform the TLS session handshake. This method
  * will return immediately and the handshake will
@@ -126,7 +128,8 @@ qio_channel_tls_new_client(QIOChannel *master,
 void qio_channel_tls_handshake(QIOChannelTLS *ioc,
QIOTaskFunc func,
gpointer opaque,
-   GDestroyNotify destroy);
+   GDestroyNotify destroy,
+   GMainContext *context);
 
 /**
  * qio_channel_tls_get_session:
diff --git a/io/channel-tls.c b/io/channel-tls.c
index 6182702dab..9628e6fa47 100644
--- a/io/channel-tls.c
+++ b/io/channel-tls.c
@@ -140,13 +140,19 @@ qio_channel_tls_new_client(QIOChannel *master,
 return NULL;
 }
 
+struct QIOChannelTLSData {
+QIOTask *task;
+GMainContext *context;
+};
+typedef struct QIOChannelTLSData QIOChannelTLSData;
 
 static gboolean qio_channel_tls_handshake_io(QIOChannel *ioc,
  GIOCondition condition,
  gpointer user_data);
 
 static void qio_channel_tls_handshake_task(QIOChannelTLS *ioc,
-   QIOTask *task)
+   QIOTask *task,
+   GMainContext *context)
 {
 Error *err = NULL;
 QCryptoTLSSessionHandshakeStatus status;
@@ -171,6 +177,15 @@ static void qio_channel_tls_handshake_task(QIOChannelTLS 
*ioc,
 qio_task_complete(task);
 } else {
 GIOCondition condition;
+QIOChannelTLSData *data = g_new0(typeof(*data), 1);
+
+data->task = task;
+data->context = context;
+
+if (context) {
+g_main_context_ref(context);
+}
+
 if (status == QCRYPTO_TLS_HANDSHAKE_SENDING) {
 condition = G_IO_OUT;
 } else {
@@ -178,11 +193,12 @@ static void qio_channel_tls_handshake_task(QIOChannelTLS 
*ioc,
 }
 
 trace_qio_channel_tls_handshake_pending(ioc, status);
-qio_channel_add_watch(ioc->master,
-  condition,
-  qio_channel_tls_handshake_io,
-  task,
-  NULL);
+qio_channel_add_watch_full(ioc->master,
+   condition,
+   qio_channel_tls_handshake_io,
+   data,
+   NULL,
+   context);
 }
 }
 
@@ -191,12 +207,18 @@ static gboolean qio_channel_tls_handshake_io(QIOChannel 
*ioc,
  GIOCondition condition,
  gpointer user_data)
 {
-QIOTask *task = user_data;
+QIOChannelTLSData *data = user_data;
+QIOTask *task = data->task;
+GMainContext *context = data->context;
 QIOChannelTLS *tioc = QIO_CHANNEL_TLS(
 qio_task_get_source(task));
 
-qio_channel_tls_handshake_task(
-   tioc, task);
+g_free(data);
+qio_channel_tls_handshake_task(tioc, task, context);
+
+if (context) {
+g_main_context_unref(context);
+}
 
 return FALSE;
 }
@@ -204,7 +226,8 @@ static gboolean qio_channel_tls_handshake_io(QIOChannel 
*ioc,
 void qio_channel_tls_handshake(QIOChannelTLS *ioc,
QIOTaskFunc func,
 

[Qemu-devel] [PATCH v3 3/6] qio: store gsources for net listeners

2018-03-04 Thread Peter Xu
Originally we were storing the GSources tag IDs.  That'll be not enough
if we are going to support non-default gcontext for QIO code.  Switch to
GSources without changing anything real.  Now we still always pass in
NULL, which means the default gcontext.

Signed-off-by: Peter Xu 
---
 include/io/net-listener.h | 22 --
 io/net-listener.c | 58 +--
 2 files changed, 56 insertions(+), 24 deletions(-)

diff --git a/include/io/net-listener.h b/include/io/net-listener.h
index 56d6da7a76..8081ac58a2 100644
--- a/include/io/net-listener.h
+++ b/include/io/net-listener.h
@@ -53,7 +53,7 @@ struct QIONetListener {
 
 char *name;
 QIOChannelSocket **sioc;
-gulong *io_tag;
+GSource **io_source;
 size_t nsioc;
 
 bool connected;
@@ -120,17 +120,35 @@ void qio_net_listener_add(QIONetListener *listener,
   QIOChannelSocket *sioc);
 
 /**
- * qio_net_listener_set_client_func:
+ * qio_net_listener_set_client_func_full:
  * @listener: the network listener object
  * @func: the callback function
  * @data: opaque data to pass to @func
  * @notify: callback to free @data
+ * @context: the context that the sources will be bound to.  If %NULL,
+ *   the default context will be used.
  *
  * Register @func to be invoked whenever a new client
  * connects to the listener. @func will be invoked
  * passing in the QIOChannelSocket instance for the
  * client.
  */
+void qio_net_listener_set_client_func_full(QIONetListener *listener,
+   QIONetListenerClientFunc func,
+   gpointer data,
+   GDestroyNotify notify,
+   GMainContext *context);
+
+/**
+ * qio_net_listener_set_client_func:
+ * @listener: the network listener object
+ * @func: the callback function
+ * @data: opaque data to pass to @func
+ * @notify: callback to free @data
+ *
+ * Wrapper of qio_net_listener_set_client_func_full(), only that the
+ * sources will always be bound to default main context.
+ */
 void qio_net_listener_set_client_func(QIONetListener *listener,
   QIONetListenerClientFunc func,
   gpointer data,
diff --git a/io/net-listener.c b/io/net-listener.c
index de38dfae99..555e8acaa4 100644
--- a/io/net-listener.c
+++ b/io/net-listener.c
@@ -118,29 +118,32 @@ void qio_net_listener_add(QIONetListener *listener,
 
 listener->sioc = g_renew(QIOChannelSocket *, listener->sioc,
  listener->nsioc + 1);
-listener->io_tag = g_renew(gulong, listener->io_tag, listener->nsioc + 1);
+listener->io_source = g_renew(typeof(listener->io_source[0]),
+  listener->io_source,
+  listener->nsioc + 1);
 listener->sioc[listener->nsioc] = sioc;
-listener->io_tag[listener->nsioc] = 0;
+listener->io_source[listener->nsioc] = NULL;
 
 object_ref(OBJECT(sioc));
 listener->connected = true;
 
 if (listener->io_func != NULL) {
 object_ref(OBJECT(listener));
-listener->io_tag[listener->nsioc] = qio_channel_add_watch(
+listener->io_source[listener->nsioc] = qio_channel_add_watch_source(
 QIO_CHANNEL(listener->sioc[listener->nsioc]), G_IO_IN,
 qio_net_listener_channel_func,
-listener, (GDestroyNotify)object_unref);
+listener, (GDestroyNotify)object_unref, NULL);
 }
 
 listener->nsioc++;
 }
 
 
-void qio_net_listener_set_client_func(QIONetListener *listener,
-  QIONetListenerClientFunc func,
-  gpointer data,
-  GDestroyNotify notify)
+void qio_net_listener_set_client_func_full(QIONetListener *listener,
+   QIONetListenerClientFunc func,
+   gpointer data,
+   GDestroyNotify notify,
+   GMainContext *context)
 {
 size_t i;
 
@@ -152,23 +155,32 @@ void qio_net_listener_set_client_func(QIONetListener 
*listener,
 listener->io_notify = notify;
 
 for (i = 0; i < listener->nsioc; i++) {
-if (listener->io_tag[i]) {
-g_source_remove(listener->io_tag[i]);
-listener->io_tag[i] = 0;
+if (listener->io_source[i]) {
+g_source_destroy(listener->io_source[i]);
+g_source_unref(listener->io_source[i]);
+listener->io_source[i] = NULL;
 }
 }
 
 if (listener->io_func != NULL) {
 for (i = 0; i < listener->nsioc; i++) {
 object_ref(OBJECT(listener));
-listener->io_tag[i] = qio_channel_add_watch(
+listener->io_source[i] = 

[Qemu-devel] [PATCH v3 0/6] qio: general non-default GMainContext support

2018-03-04 Thread Peter Xu
V1: http://lists.nongnu.org/archive/html/qemu-devel/2018-02/msg06972.html
V2: http://lists.gnu.org/archive/html/qemu-devel/2018-03/msg00016.html

>From this version, I'll split the old series into two: one QIO series
and one CHARDEV series.  This is the QIO part.

Hopefully I have addressed every comments in v2.  Please shoot if I
missed any of them.  Thanks,

v3:
- add r-bs
- move the migration patch out of the series [Dan]
- in comments, mention "%NULL" case for contexts [Paolo]
- do similar thing to listen_async and dgram_async to allow context
  parameter [Dan]
- cache TCPChardevTelnetInit properly in telnet patch, and fixes
  around that new change in the patch [Paolo]
- drop patch 5 [Dan]
- drop the helper tcp_chr_net_listener_setup() [Dan]

v2:
- collect r-bs
- qio_channel_add_watch_full() should still return the same thing as
  the old one, and introduced qio_channel_add_watch_full() to return a
  GSource pointer. [Dan]
- Fix commit message on RDMA. It's using QIO, but still, I am not
  touching it.  [Dan]
- use qio_net_listener_set_client_func_full() directly, and avoid
  introducing new API. [Dan]

Please review.  Thanks.

Peter Xu (6):
  qio: rename qio_task_thread_result
  qio: introduce qio_channel_add_watch_{full|source}
  qio: store gsources for net listeners
  qio: non-default context for threaded qtask
  qio: non-default context for async conn
  qio: non-default context for TLS handshake

 chardev/char-socket.c  |  5 ++--
 include/io/channel-socket.h| 15 ---
 include/io/channel-tls.h   |  5 +++-
 include/io/channel.h   | 44 
 include/io/net-listener.h  | 22 ++--
 include/io/task.h  |  7 +++--
 io/channel-socket.c| 18 -
 io/channel-tls.c   | 45 
 io/channel.c   | 40 -
 io/dns-resolver.c  |  3 ++-
 io/net-listener.c  | 58 ++
 io/task.c  | 22 +---
 migration/socket.c |  3 ++-
 migration/tls.c|  2 ++
 nbd/client.c   |  1 +
 nbd/server.c   |  1 +
 tests/test-io-channel-socket.c |  4 +--
 tests/test-io-channel-tls.c|  2 ++
 tests/test-io-task.c   |  2 ++
 ui/vnc-auth-vencrypt.c |  1 +
 ui/vnc-ws.c|  1 +
 21 files changed, 239 insertions(+), 62 deletions(-)

-- 
2.14.3




[Qemu-devel] [PATCH v3 1/6] qio: rename qio_task_thread_result

2018-03-04 Thread Peter Xu
It is strange that it was called gio_task_thread_result.  Rename it to
follow the naming rule of the file.

Reviewed-by: Daniel P. Berrange 
Signed-off-by: Peter Xu 
---
 io/task.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/io/task.c b/io/task.c
index 3ce556017c..1a0a1c7185 100644
--- a/io/task.c
+++ b/io/task.c
@@ -80,7 +80,7 @@ struct QIOTaskThreadData {
 };
 
 
-static gboolean gio_task_thread_result(gpointer opaque)
+static gboolean qio_task_thread_result(gpointer opaque)
 {
 struct QIOTaskThreadData *data = opaque;
 
@@ -110,7 +110,7 @@ static gpointer qio_task_thread_worker(gpointer opaque)
  * the worker results
  */
 trace_qio_task_thread_exit(data->task);
-g_idle_add(gio_task_thread_result, data);
+g_idle_add(qio_task_thread_result, data);
 return NULL;
 }
 
-- 
2.14.3




[Qemu-devel] [PATCH v3 2/6] qio: introduce qio_channel_add_watch_{full|source}

2018-03-04 Thread Peter Xu
Firstly, introduce an internal qio_channel_add_watch_full(), which
enhances qio_channel_add_watch() that context can be specified.

Then add a new API wrapper qio_channel_add_watch_source() to return a
GSource pointer rather than a tag ID.

Note that the _source() call will keep a reference of GSource so that
callers need to unref them explicitly when finished using the GSource.

Signed-off-by: Peter Xu 
---
 include/io/channel.h | 44 
 io/channel.c | 40 ++--
 2 files changed, 78 insertions(+), 6 deletions(-)

diff --git a/include/io/channel.h b/include/io/channel.h
index 3995e243a3..e8cdadb0b0 100644
--- a/include/io/channel.h
+++ b/include/io/channel.h
@@ -648,6 +648,50 @@ guint qio_channel_add_watch(QIOChannel *ioc,
 gpointer user_data,
 GDestroyNotify notify);
 
+/**
+ * qio_channel_add_watch_full:
+ * @ioc: the channel object
+ * @condition: the I/O condition to monitor
+ * @func: callback to invoke when the source becomes ready
+ * @user_data: opaque data to pass to @func
+ * @notify: callback to free @user_data
+ * @context: the context to run the watch source
+ *
+ * Similar as qio_channel_add_watch(), but allows to specify context
+ * to run the watch source.
+ *
+ * Returns: the source ID
+ */
+guint qio_channel_add_watch_full(QIOChannel *ioc,
+ GIOCondition condition,
+ QIOChannelFunc func,
+ gpointer user_data,
+ GDestroyNotify notify,
+ GMainContext *context);
+
+/**
+ * qio_channel_add_watch_source:
+ * @ioc: the channel object
+ * @condition: the I/O condition to monitor
+ * @func: callback to invoke when the source becomes ready
+ * @user_data: opaque data to pass to @func
+ * @notify: callback to free @user_data
+ * @context: gcontext to bind the source to
+ *
+ * Similar as qio_channel_add_watch(), but allows to specify context
+ * to run the watch source, meanwhile return the GSource object
+ * instead of tag ID, with the GSource referenced already.
+ *
+ * Note: callers is responsible to unref the source when not needed.
+ *
+ * Returns: the source pointer
+ */
+GSource *qio_channel_add_watch_source(QIOChannel *ioc,
+  GIOCondition condition,
+  QIOChannelFunc func,
+  gpointer user_data,
+  GDestroyNotify notify,
+  GMainContext *context);
 
 /**
  * qio_channel_attach_aio_context:
diff --git a/io/channel.c b/io/channel.c
index ec4b86de7c..8dd0684f5d 100644
--- a/io/channel.c
+++ b/io/channel.c
@@ -299,11 +299,12 @@ void qio_channel_set_aio_fd_handler(QIOChannel *ioc,
 klass->io_set_aio_fd_handler(ioc, ctx, io_read, io_write, opaque);
 }
 
-guint qio_channel_add_watch(QIOChannel *ioc,
-GIOCondition condition,
-QIOChannelFunc func,
-gpointer user_data,
-GDestroyNotify notify)
+guint qio_channel_add_watch_full(QIOChannel *ioc,
+ GIOCondition condition,
+ QIOChannelFunc func,
+ gpointer user_data,
+ GDestroyNotify notify,
+ GMainContext *context)
 {
 GSource *source;
 guint id;
@@ -312,12 +313,39 @@ guint qio_channel_add_watch(QIOChannel *ioc,
 
 g_source_set_callback(source, (GSourceFunc)func, user_data, notify);
 
-id = g_source_attach(source, NULL);
+id = g_source_attach(source, context);
 g_source_unref(source);
 
 return id;
 }
 
+guint qio_channel_add_watch(QIOChannel *ioc,
+GIOCondition condition,
+QIOChannelFunc func,
+gpointer user_data,
+GDestroyNotify notify)
+{
+return qio_channel_add_watch_full(ioc, condition, func,
+  user_data, notify, NULL);
+}
+
+GSource *qio_channel_add_watch_source(QIOChannel *ioc,
+  GIOCondition condition,
+  QIOChannelFunc func,
+  gpointer user_data,
+  GDestroyNotify notify,
+  GMainContext *context)
+{
+GSource *source;
+guint id;
+
+id = qio_channel_add_watch_full(ioc, condition, func,
+user_data, notify, context);
+source = g_main_context_find_source_by_id(context, id);
+g_source_ref(source);
+return source;
+}
+
 
 int qio_channel_shutdown(QIOChannel *ioc,

[Qemu-devel] [PATCH v4 1/2] i386: Add Intel Processor Trace feature support

2018-03-04 Thread Luwei Kang
From: Chao Peng 

Expose Intel Processor Trace feature to guest.

To make Intel PT live migration safe and get same CPUID information
with same CPU model on diffrent host. CPUID[14] is constant in this
patch. Intel PT use EPT is first supported in IceLake, the CPUID[14]
get on this machine as default value. Intel PT would be disabled
if any machine don't support this minial feature list.

Signed-off-by: Chao Peng 
Signed-off-by: Luwei Kang 
---
>From V3:
 - fix some typo;
 - add some comments and safty check.

---
 target/i386/cpu.c | 78 +--
 target/i386/cpu.h |  1 +
 target/i386/kvm.c | 23 
 3 files changed, 100 insertions(+), 2 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index b5e431e..24e1693 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -173,7 +173,32 @@
 #define L2_ITLB_4K_ASSOC   4
 #define L2_ITLB_4K_ENTRIES   512
 
-
+/* CPUID Leaf 0x14 constants: */
+#define INTEL_PT_MAX_SUBLEAF 0x1
+/*
+ * bit[00]: IA32_RTIT_CTL.CR3 filter can be set to 1 and IA32_RTIT_CR3_MATCH
+ *  MSR can be accessed;
+ * bit[01]: Support Configurable PSB and Cycle-Accurate Mode;
+ * bit[02]: Support IP Filtering, TraceStop filtering, and preservation
+ *  of Intel PT MSRs across warm reset;
+ * bit[03]: Support MTC timing packet and suppression of COFI-based packets;
+ */
+#define INTEL_PT_MINIMAL_EBX 0xf
+/*
+ * bit[00]: Tracing can be enabled with IA32_RTIT_CTL.ToPA = 1 and
+ *  IA32_RTIT_OUTPUT_BASE and IA32_RTIT_OUTPUT_MASK_PTRS MSRs can be
+ *  accessed;
+ * bit[01]: ToPA tables can hold any number of output entries, up to the
+ *  maximum allowed by the MaskOrTableOffset field of
+ *  IA32_RTIT_OUTPUT_MASK_PTRS;
+ * bit[02]: Support Single-Range Output scheme;
+ */
+#define INTEL_PT_MINIMAL_ECX 0x7
+#define INTEL_PT_ADDR_RANGES_NUM 0x2 /* Number of configurable address ranges 
*/
+#define INTEL_PT_ADDR_RANGES_NUM_MASK 0x3
+#define INTEL_PT_MTC_BITMAP  (0x0249 << 16) /* Support ART(0,3,6,9) */
+#define INTEL_PT_CYCLE_BITMAP0x1fff /* Support 0,2^(0~11) */
+#define INTEL_PT_PSB_BITMAP  (0x003f << 16) /* Support 
2K,4K,8K,16K,32K,64K */
 
 static void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
  uint32_t vendor2, uint32_t vendor3)
@@ -428,7 +453,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 NULL, NULL, "mpx", NULL,
 "avx512f", "avx512dq", "rdseed", "adx",
 "smap", "avx512ifma", "pcommit", "clflushopt",
-"clwb", NULL, "avx512pf", "avx512er",
+"clwb", "intel-pt", "avx512pf", "avx512er",
 "avx512cd", "sha-ni", "avx512bw", "avx512vl",
 },
 .cpuid_eax = 7,
@@ -3453,6 +3478,27 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
uint32_t count,
 }
 break;
 }
+case 0x14: {
+/* Intel Processor Trace Enumeration */
+*eax = 0;
+*ebx = 0;
+*ecx = 0;
+*edx = 0;
+if (!(env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_INTEL_PT) ||
+!kvm_enabled()) {
+break;
+}
+
+if (count == 0) {
+*eax = INTEL_PT_MAX_SUBLEAF;
+*ebx = INTEL_PT_MINIMAL_EBX;
+*ecx = INTEL_PT_MINIMAL_ECX;
+} else if (count == 1) {
+*eax = INTEL_PT_MTC_BITMAP | INTEL_PT_ADDR_RANGES_NUM;
+*ebx = INTEL_PT_PSB_BITMAP | INTEL_PT_CYCLE_BITMAP;
+}
+break;
+}
 case 0x4000:
 /*
  * CPUID code in kvm_arch_init_vcpu() ignores stuff
@@ -4083,6 +4129,34 @@ static int x86_cpu_filter_features(X86CPU *cpu)
 }
 }
 
+if ((env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_INTEL_PT) &&
+kvm_enabled()) {
+KVMState *s = CPU(cpu)->kvm_state;
+uint32_t eax_0 = kvm_arch_get_supported_cpuid(s, 0x14, 0, R_EAX);
+uint32_t ebx_0 = kvm_arch_get_supported_cpuid(s, 0x14, 0, R_EBX);
+uint32_t ecx_0 = kvm_arch_get_supported_cpuid(s, 0x14, 0, R_ECX);
+uint32_t eax_1 = kvm_arch_get_supported_cpuid(s, 0x14, 1, R_EAX);
+uint32_t ebx_1 = kvm_arch_get_supported_cpuid(s, 0x14, 1, R_EBX);
+
+if (!eax_0 ||
+   ((ebx_0 & INTEL_PT_MINIMAL_EBX) != INTEL_PT_MINIMAL_EBX) ||
+   ((ecx_0 & INTEL_PT_MINIMAL_ECX) != INTEL_PT_MINIMAL_ECX) ||
+   ((eax_1 & INTEL_PT_MTC_BITMAP) != INTEL_PT_MTC_BITMAP) ||
+   ((eax_1 & INTEL_PT_ADDR_RANGES_NUM_MASK) <
+   INTEL_PT_ADDR_RANGES_NUM) ||
+   ((ebx_1 & (INTEL_PT_PSB_BITMAP | INTEL_PT_CYCLE_BITMAP)) !=
+(INTEL_PT_PSB_BITMAP | INTEL_PT_CYCLE_BITMAP))) {
+/*
+ * Processor Trace capabilities aren't configurable, so if the
+ * host can't emulate the 

[Qemu-devel] [PATCH v4 2/2] i386: Add support to get/set/migrate Intel Processor Trace feature

2018-03-04 Thread Luwei Kang
From: Chao Peng 

Add Intel Processor Trace related definition. It also add
corresponding part to kvm_get/set_msr and vmstate.

Signed-off-by: Chao Peng 
Signed-off-by: Luwei Kang 
---
 target/i386/cpu.h | 22 ++
 target/i386/kvm.c | 51 +++
 target/i386/machine.c | 38 ++
 3 files changed, 111 insertions(+)

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index f5b9ecb..5457d3b 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -415,6 +415,21 @@ typedef enum X86Seg {
 #define MSR_MC0_ADDR0x402
 #define MSR_MC0_MISC0x403
 
+#define MSR_IA32_RTIT_OUTPUT_BASE   0x560
+#define MSR_IA32_RTIT_OUTPUT_MASK   0x561
+#define MSR_IA32_RTIT_CTL   0x570
+#define MSR_IA32_RTIT_STATUS0x571
+#define MSR_IA32_RTIT_CR3_MATCH 0x572
+#define MSR_IA32_RTIT_ADDR0_A   0x580
+#define MSR_IA32_RTIT_ADDR0_B   0x581
+#define MSR_IA32_RTIT_ADDR1_A   0x582
+#define MSR_IA32_RTIT_ADDR1_B   0x583
+#define MSR_IA32_RTIT_ADDR2_A   0x584
+#define MSR_IA32_RTIT_ADDR2_B   0x585
+#define MSR_IA32_RTIT_ADDR3_A   0x586
+#define MSR_IA32_RTIT_ADDR3_B   0x587
+#define MAX_RTIT_ADDRS  8
+
 #define MSR_EFER0xc080
 
 #define MSR_EFER_SCE   (1 << 0)
@@ -1154,6 +1169,13 @@ typedef struct CPUX86State {
 uint64_t msr_hv_stimer_config[HV_STIMER_COUNT];
 uint64_t msr_hv_stimer_count[HV_STIMER_COUNT];
 
+uint64_t msr_rtit_ctrl;
+uint64_t msr_rtit_status;
+uint64_t msr_rtit_output_base;
+uint64_t msr_rtit_output_mask;
+uint64_t msr_rtit_cr3_match;
+uint64_t msr_rtit_addrs[MAX_RTIT_ADDRS];
+
 /* exception/interrupt handling */
 int error_code;
 int exception_is_int;
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index f9f4cd1..097c953 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -1811,6 +1811,25 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
 kvm_msr_entry_add(cpu, MSR_MTRRphysMask(i), mask);
 }
 }
+if (env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_INTEL_PT) {
+int addr_num = kvm_arch_get_supported_cpuid(kvm_state,
+0x14, 1, R_EAX) & 0x7;
+
+kvm_msr_entry_add(cpu, MSR_IA32_RTIT_CTL,
+env->msr_rtit_ctrl);
+kvm_msr_entry_add(cpu, MSR_IA32_RTIT_STATUS,
+env->msr_rtit_status);
+kvm_msr_entry_add(cpu, MSR_IA32_RTIT_OUTPUT_BASE,
+env->msr_rtit_output_base);
+kvm_msr_entry_add(cpu, MSR_IA32_RTIT_OUTPUT_MASK,
+env->msr_rtit_output_mask);
+kvm_msr_entry_add(cpu, MSR_IA32_RTIT_CR3_MATCH,
+env->msr_rtit_cr3_match);
+for (i = 0; i < addr_num; i++) {
+kvm_msr_entry_add(cpu, MSR_IA32_RTIT_ADDR0_A + i,
+env->msr_rtit_addrs[i]);
+}
+}
 
 /* Note: MSR_IA32_FEATURE_CONTROL is written separately, see
  *   kvm_put_msr_feature_control. */
@@ -2124,6 +2143,20 @@ static int kvm_get_msrs(X86CPU *cpu)
 }
 }
 
+if (env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_INTEL_PT) {
+int addr_num =
+kvm_arch_get_supported_cpuid(kvm_state, 0x14, 1, R_EAX) & 0x7;
+
+kvm_msr_entry_add(cpu, MSR_IA32_RTIT_CTL, 0);
+kvm_msr_entry_add(cpu, MSR_IA32_RTIT_STATUS, 0);
+kvm_msr_entry_add(cpu, MSR_IA32_RTIT_OUTPUT_BASE, 0);
+kvm_msr_entry_add(cpu, MSR_IA32_RTIT_OUTPUT_MASK, 0);
+kvm_msr_entry_add(cpu, MSR_IA32_RTIT_CR3_MATCH, 0);
+for (i = 0; i < addr_num; i++) {
+kvm_msr_entry_add(cpu, MSR_IA32_RTIT_ADDR0_A + i, 0);
+}
+}
+
 ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_MSRS, cpu->kvm_msr_buf);
 if (ret < 0) {
 return ret;
@@ -2364,6 +2397,24 @@ static int kvm_get_msrs(X86CPU *cpu)
 case MSR_IA32_SPEC_CTRL:
 env->spec_ctrl = msrs[i].data;
 break;
+case MSR_IA32_RTIT_CTL:
+env->msr_rtit_ctrl = msrs[i].data;
+break;
+case MSR_IA32_RTIT_STATUS:
+env->msr_rtit_status = msrs[i].data;
+break;
+case MSR_IA32_RTIT_OUTPUT_BASE:
+env->msr_rtit_output_base = msrs[i].data;
+break;
+case MSR_IA32_RTIT_OUTPUT_MASK:
+env->msr_rtit_output_mask = msrs[i].data;
+break;
+case MSR_IA32_RTIT_CR3_MATCH:
+env->msr_rtit_cr3_match = msrs[i].data;
+break;
+case MSR_IA32_RTIT_ADDR0_A ... MSR_IA32_RTIT_ADDR3_B:
+env->msr_rtit_addrs[index - MSR_IA32_RTIT_ADDR0_A] = 

Re: [Qemu-devel] [PATCH] PowerPC: Add TM bits into msr_mask

2018-03-04 Thread David Gibson
On Wed, Feb 28, 2018 at 09:51:37AM +0800, wei.guo.si...@gmail.com wrote:
> From: Simon Guo 
> 
> During migration, cpu_post_load() will use msr_mask to determine which
> PPC MSR bits will be sync to the target side. Hardware Transaction
> Memory(HTM) has been supported since Power8. This patch adds TM/TS bits
> into msr_mask for Power8, so that transactional application can be
> migrated across qemu.
> 
> Signed-off-by: Simon Guo 

Sorry I've taken a while to respond to this.

This addresses a real bug, but doesn't get the details quite right.

First, the MSR_TM bit is *already* included in the msr_mask for POWER8
(it's a little above the context for this patch), though TS0 and TS1
were not.

Second, all MSR bits are sent to the far side, it's just that without
them in the MSR mask they'll be dropped instead of re-inserted into
KVM.  That's the only reason the msr_mask is relevant to KVM (and TCG
doesn't support HTM anyway).  The commit message needs to make that clearer.

> ---
>  target/ppc/translate_init.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
> index 55c99c9..a438721 100644
> --- a/target/ppc/translate_init.c
> +++ b/target/ppc/translate_init.c
> @@ -8689,6 +8689,9 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
>  (1ull << MSR_DR) |
>  (1ull << MSR_PMM) |
>  (1ull << MSR_RI) |
> +(1ull << MSR_TM) |
> +(1ull << MSR_TS0) |
> +(1ull << MSR_TS1) |
>  (1ull << MSR_LE);
>  pcc->mmu_model = POWERPC_MMU_2_07;
>  #if defined(CONFIG_SOFTMMU)

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


[Qemu-devel] [RESEND PATCH v7 1/3] pci: Add support for Designware IP block

2018-03-04 Thread Andrey Smirnov
Add code needed to get a functional PCI subsytem when using in
conjunction with upstream Linux guest (4.13+). Tested to work against
"e1000e" (network adapter, using MSI interrupts) as well as
"usb-ehci" (USB controller, using legacy PCI interrupts).

Based on "i.MX6 Applications Processor Reference Manual" (Document
Number: IMX6DQRM Rev. 4) as well as corresponding dirver in Linux
kernel (circa 4.13 - 4.16 found in drivers/pci/dwc/*)

Cc: Peter Maydell 
Cc: Jason Wang 
Cc: Philippe Mathieu-Daudé 
Cc: Marcel Apfelbaum 
Cc: Michael S. Tsirkin 
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Signed-off-by: Andrey Smirnov 
---
 default-configs/arm-softmmu.mak  |   2 +
 include/hw/pci-host/designware.h | 102 ++
 include/hw/pci/pci_ids.h |   2 +
 hw/pci-host/designware.c | 754 +++
 hw/pci-host/Makefile.objs|   2 +
 5 files changed, 862 insertions(+)
 create mode 100644 include/hw/pci-host/designware.h
 create mode 100644 hw/pci-host/designware.c

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index d724106bd3..5540ea5e7e 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -140,3 +140,5 @@ CONFIG_GPIO_KEY=y
 CONFIG_MSF2=y
 CONFIG_FW_CFG_DMA=y
 CONFIG_XILINX_AXI=y
+CONFIG_PCI_DESIGNWARE=y
+
diff --git a/include/hw/pci-host/designware.h b/include/hw/pci-host/designware.h
new file mode 100644
index 00..a4f2c0695b
--- /dev/null
+++ b/include/hw/pci-host/designware.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2017, Impinj, Inc.
+ *
+ * Designware PCIe IP block emulation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * .
+ */
+
+#ifndef DESIGNWARE_H
+#define DESIGNWARE_H
+
+#include "hw/hw.h"
+#include "hw/sysbus.h"
+#include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
+#include "hw/pci/pcie_host.h"
+#include "hw/pci/pci_bridge.h"
+
+#define TYPE_DESIGNWARE_PCIE_HOST "designware-pcie-host"
+#define DESIGNWARE_PCIE_HOST(obj) \
+ OBJECT_CHECK(DesignwarePCIEHost, (obj), TYPE_DESIGNWARE_PCIE_HOST)
+
+#define TYPE_DESIGNWARE_PCIE_ROOT "designware-pcie-root"
+#define DESIGNWARE_PCIE_ROOT(obj) \
+ OBJECT_CHECK(DesignwarePCIERoot, (obj), TYPE_DESIGNWARE_PCIE_ROOT)
+
+struct DesignwarePCIERoot;
+typedef struct DesignwarePCIERoot DesignwarePCIERoot;
+
+typedef struct DesignwarePCIEViewport {
+DesignwarePCIERoot *root;
+
+MemoryRegion cfg;
+MemoryRegion mem;
+
+uint64_t base;
+uint64_t target;
+uint32_t limit;
+uint32_t cr[2];
+
+bool inbound;
+} DesignwarePCIEViewport;
+
+typedef struct DesignwarePCIEMSIBank {
+uint32_t enable;
+uint32_t mask;
+uint32_t status;
+} DesignwarePCIEMSIBank;
+
+typedef struct DesignwarePCIEMSI {
+uint64_t base;
+MemoryRegion iomem;
+
+#define DESIGNWARE_PCIE_NUM_MSI_BANKS1
+
+DesignwarePCIEMSIBank intr[DESIGNWARE_PCIE_NUM_MSI_BANKS];
+} DesignwarePCIEMSI;
+
+struct DesignwarePCIERoot {
+PCIBridge parent_obj;
+
+uint32_t atu_viewport;
+
+#define DESIGNWARE_PCIE_VIEWPORT_OUTBOUND0
+#define DESIGNWARE_PCIE_VIEWPORT_INBOUND 1
+#define DESIGNWARE_PCIE_NUM_VIEWPORTS4
+
+DesignwarePCIEViewport viewports[2][DESIGNWARE_PCIE_NUM_VIEWPORTS];
+DesignwarePCIEMSI msi;
+};
+
+typedef struct DesignwarePCIEHost {
+PCIHostState parent_obj;
+
+DesignwarePCIERoot root;
+
+struct {
+AddressSpace address_space;
+MemoryRegion address_space_root;
+
+MemoryRegion memory;
+MemoryRegion io;
+
+qemu_irq irqs[4];
+} pci;
+
+MemoryRegion mmio;
+} DesignwarePCIEHost;
+
+#endif  /* DESIGNWARE_H */
diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h
index 1dbf53627c..63acc722a9 100644
--- a/include/hw/pci/pci_ids.h
+++ b/include/hw/pci/pci_ids.h
@@ -269,4 +269,6 @@
 #define PCI_VENDOR_ID_VMWARE 0x15ad
 #define PCI_DEVICE_ID_VMWARE_PVRDMA  0x0820
 
+#define PCI_VENDOR_ID_SYNOPSYS   0x16C3
+
 #endif
diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c
new file mode 100644
index 00..29ea313798
--- /dev/null
+++ b/hw/pci-host/designware.c
@@ -0,0 +1,754 @@
+/*
+ * Copyright (c) 2018, Impinj, Inc.
+ 

[Qemu-devel] [RESEND PATCH v7 0/3] Initial i.MX7 support

2018-03-04 Thread Andrey Smirnov
RESEND due to botched original v7 submission (patch 1/3 broken)

Hi everyone,

This v7 of the patch series containing the work that I've done in
order to enable support for i.MX7 emulation in QEMU.

As the one before last commit in the series states the supported i.MX7
features are:

* up to 2 Cortex A9 cores (SMP works with PSCI)
* A7 MPCORE (identical to A15 MPCORE)
* 4 GPTs modules
* 7 GPIO controllers
* 2 IOMUXC controllers
* 1 CCM module
* 1 SVNS module
* 1 SRC module
* 1 GPCv2 controller
* 4 eCSPI controllers
* 4 I2C controllers
* 7 i.MX UART controllers
* 2 FlexCAN controllers
* 2 Ethernet controllers (FEC)
* 3 SD controllers (USDHC)
* 4 WDT modules
* 1 SDMA module
* 1 GPR module
* 2 USBMISC modules
* 2 ADC modules
* 1 PCIe controller
* 3 USB controllers
* 1 LCD controller
* 1 ARMv7 DAP IP block

Feedback is welcome!

Changes since [v6]:

- Removed reference to "is_express"

- All endiannes in Designware PCI implementation is now specified
  as little-endian

- Patchset rebase on latest master
  (136c67e07869227b21b3f627316e03679ce7b738)


Changes since [v5]:

- Rebase patchest on top of latest QEMU master, so now the
  patchset is down to three patches

- Reverted the change to use pci_data_* functions becuase the
  patch supporting this change was causing trouble

- Fixed endiannes of MSI and configuration space accessors to be
  LITTLE_ENDIAN

Changes since [v4]:

- Rebase patchest on top of latest QEMU master

- Reworked PCIE emulation code to create MemoryRegions
  only once

- Fixed incorrect usages of PCI instead of PCIE

- Fixed device class reported by PCIE bridge

- Added patch to make pci_data_read() and pci_data_write() usable
  for PCIE devices as well

- Converted PCIE code to use pci_data_read() and pci_data_write()

- Added VMStateDescription code for PCIE

- Collected Reviewed-by tag from Philippe

Changes since [v3]:

- Changes to FEC were split into a separate set and merged to master

- Patchest is rebased on latest master

- Converted to use PSCI DT fixup code that is shared with virt
  platform (now relocated to live in arm/boot.c)

- Large number of dummy block were converted to use
  create_unimplemented_device() as opposed to its own dedicated
  type

- Incorporated varios small feedback items

- Collected Reviewed-by tags from Peter

Changes since [v2]:

- Added stubs for more blocks that were causing memory
  transactions when booting Linux guest as were revealed by
  additional testing of the patchest

- Added proper USB emulation code, so now it should be possible to
  emulated guest's USB bus

Changes since [v1]:

- Patchset no longer relies on "ignore_memory_transaction_failures = false"
  for its functionality

- As a consequnce of implementing the above a number of patches
  implementing dummy IP block emulation as well as PCIe emulation
  patches that I alluded to in [v1] are now included in this patch
  series

- "has_el3" property is no longer being set to "false" as a part
  of intialization of A7 CPU. I couldn't reproduce the issues that
  I thought I was having, so I just dropped that code.

- A number of smaller feedback items from Peter and other has been
  incorporated into the patches.


Thanks,
Andrey Smirnov

[v6] https://lists.gnu.org/archive/html/qemu-devel/2018-02/msg03587.html
[v5] https://lists.gnu.org/archive/html/qemu-devel/2018-02/msg01558.html
[v4] https://lists.gnu.org/archive/html/qemu-devel/2018-01/msg03264.html
[v3] https://lists.gnu.org/archive/html/qemu-devel/2017-11/msg04236.html
[v2] https://lists.gnu.org/archive/html/qemu-devel/2017-10/msg05516.html
[v1] https://lists.gnu.org/archive/html/qemu-devel/2017-09/msg04770.html

Andrey Smirnov (3):
  pci: Add support for Designware IP block
  i.MX: Add i.MX7 SOC implementation.
  Implement support for i.MX7 Sabre board

 default-configs/arm-softmmu.mak  |   3 +
 include/hw/arm/fsl-imx7.h| 222 
 include/hw/pci-host/designware.h | 102 ++
 include/hw/pci/pci_ids.h |   2 +
 hw/arm/fsl-imx7.c| 580 ++
 hw/arm/mcimx7d-sabre.c   |  90 +
 hw/pci-host/designware.c | 754 +++
 hw/arm/Makefile.objs |   3 +
 hw/pci-host/Makefile.objs|   2 +
 9 files changed, 1758 insertions(+)
 create mode 100644 include/hw/arm/fsl-imx7.h
 create mode 100644 include/hw/pci-host/designware.h
 create mode 100644 hw/arm/fsl-imx7.c
 create mode 100644 hw/arm/mcimx7d-sabre.c
 create mode 100644 hw/pci-host/designware.c

-- 
2.14.3




[Qemu-devel] [RESEND PATCH v7 2/3] i.MX: Add i.MX7 SOC implementation.

2018-03-04 Thread Andrey Smirnov
The following interfaces are partially or fully emulated:

* up to 2 Cortex A9 cores (SMP works with PSCI)
* A7 MPCORE (identical to A15 MPCORE)
* 4 GPTs modules
* 7 GPIO controllers
* 2 IOMUXC controllers
* 1 CCM module
* 1 SVNS module
* 1 SRC module
* 1 GPCv2 controller
* 4 eCSPI controllers
* 4 I2C controllers
* 7 i.MX UART controllers
* 2 FlexCAN controllers
* 2 Ethernet controllers (FEC)
* 3 SD controllers (USDHC)
* 4 WDT modules
* 1 SDMA module
* 1 GPR module
* 2 USBMISC modules
* 2 ADC modules
* 1 PCIe controller

Tested to boot and work with upstream Linux (4.13+) guest.

Cc: Peter Maydell 
Cc: Jason Wang 
Cc: Philippe Mathieu-Daudé 
Cc: Marcel Apfelbaum 
Cc: Michael S. Tsirkin 
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Peter Maydell 
Signed-off-by: Andrey Smirnov 
---
 default-configs/arm-softmmu.mak |   1 +
 include/hw/arm/fsl-imx7.h   | 222 +++
 hw/arm/fsl-imx7.c   | 580 
 hw/arm/Makefile.objs|   2 +
 4 files changed, 805 insertions(+)
 create mode 100644 include/hw/arm/fsl-imx7.h
 create mode 100644 hw/arm/fsl-imx7.c

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 5540ea5e7e..7665a02fb2 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -126,6 +126,7 @@ CONFIG_ALLWINNER_A10=y
 CONFIG_FSL_IMX6=y
 CONFIG_FSL_IMX31=y
 CONFIG_FSL_IMX25=y
+CONFIG_FSL_IMX7=y
 
 CONFIG_IMX_I2C=y
 
diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
new file mode 100644
index 00..d848262bfd
--- /dev/null
+++ b/include/hw/arm/fsl-imx7.h
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2018, Impinj, Inc.
+ *
+ * i.MX7 SoC definitions
+ *
+ * Author: Andrey Smirnov 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef FSL_IMX7_H
+#define FSL_IMX7_H
+
+#include "hw/arm/arm.h"
+#include "hw/cpu/a15mpcore.h"
+#include "hw/intc/imx_gpcv2.h"
+#include "hw/misc/imx7_ccm.h"
+#include "hw/misc/imx7_snvs.h"
+#include "hw/misc/imx7_gpr.h"
+#include "hw/misc/imx6_src.h"
+#include "hw/misc/imx2_wdt.h"
+#include "hw/gpio/imx_gpio.h"
+#include "hw/char/imx_serial.h"
+#include "hw/timer/imx_gpt.h"
+#include "hw/timer/imx_epit.h"
+#include "hw/i2c/imx_i2c.h"
+#include "hw/gpio/imx_gpio.h"
+#include "hw/sd/sdhci.h"
+#include "hw/ssi/imx_spi.h"
+#include "hw/net/imx_fec.h"
+#include "hw/pci-host/designware.h"
+#include "hw/usb/chipidea.h"
+#include "exec/memory.h"
+#include "cpu.h"
+
+#define TYPE_FSL_IMX7 "fsl,imx7"
+#define FSL_IMX7(obj) OBJECT_CHECK(FslIMX7State, (obj), TYPE_FSL_IMX7)
+
+enum FslIMX7Configuration {
+FSL_IMX7_NUM_CPUS = 2,
+FSL_IMX7_NUM_UARTS= 7,
+FSL_IMX7_NUM_ETHS = 2,
+FSL_IMX7_ETH_NUM_TX_RINGS = 3,
+FSL_IMX7_NUM_USDHCS   = 3,
+FSL_IMX7_NUM_WDTS = 4,
+FSL_IMX7_NUM_GPTS = 4,
+FSL_IMX7_NUM_IOMUXCS  = 2,
+FSL_IMX7_NUM_GPIOS= 7,
+FSL_IMX7_NUM_I2CS = 4,
+FSL_IMX7_NUM_ECSPIS   = 4,
+FSL_IMX7_NUM_USBS = 3,
+FSL_IMX7_NUM_ADCS = 2,
+};
+
+typedef struct FslIMX7State {
+/*< private >*/
+DeviceStateparent_obj;
+
+/*< public >*/
+ARMCPU cpu[FSL_IMX7_NUM_CPUS];
+A15MPPrivState a7mpcore;
+IMXGPTStategpt[FSL_IMX7_NUM_GPTS];
+IMXGPIOState   gpio[FSL_IMX7_NUM_GPIOS];
+IMX7CCMState   ccm;
+IMX7AnalogStateanalog;
+IMX7SNVSState  snvs;
+IMXGPCv2State  gpcv2;
+IMXSPIStatespi[FSL_IMX7_NUM_ECSPIS];
+IMXI2CStatei2c[FSL_IMX7_NUM_I2CS];
+IMXSerialState uart[FSL_IMX7_NUM_UARTS];
+IMXFECStateeth[FSL_IMX7_NUM_ETHS];
+SDHCIState usdhc[FSL_IMX7_NUM_USDHCS];
+IMX2WdtState   wdt[FSL_IMX7_NUM_WDTS];
+IMX7GPRState   gpr;
+ChipideaState  usb[FSL_IMX7_NUM_USBS];
+DesignwarePCIEHost pcie;
+} FslIMX7State;
+
+enum FslIMX7MemoryMap {
+FSL_IMX7_MMDC_ADDR= 0x8000,
+FSL_IMX7_MMDC_SIZE= 2 * 1024 * 1024 * 1024UL,
+
+FSL_IMX7_GPIO1_ADDR   = 0x3020,
+FSL_IMX7_GPIO2_ADDR   = 0x3021,
+FSL_IMX7_GPIO3_ADDR   = 0x3022,
+

Re: [Qemu-devel] [PATCH v7 0/3] Initial i.MX7 support

2018-03-04 Thread Andrey Smirnov
On Sun, Mar 4, 2018 at 9:16 PM, Andrey Smirnov  wrote:
> Hi everyone,
>

Ugh, just realized that I was too hasty to call git "send-email" and
patch 1/3 in this submission is broken since I forgot to remove
"is_express" field. Please disregard this version of v7 and I'll
resend corrected one shortly.

Very sorry for the noise.

Thanks,
Andrey Smirnov



Re: [Qemu-devel] [PATCH V3 0/4] vfio: Introduce Live migration capability to vfio_mdev device

2018-03-04 Thread no-reply
Hi,

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

Type: series
Message-id: 1520229653-10658-1-git-send-email-yulei.zh...@intel.com
Subject: [Qemu-devel] [PATCH V3 0/4] vfio: Introduce Live migration capability 
to vfio_mdev device

=== 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
git config --local diff.algorithm histogram

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
From https://github.com/patchew-project/qemu
 * [new tag]   
patchew/1520229653-10658-1-git-send-email-yulei.zh...@intel.com -> 
patchew/1520229653-10658-1-git-send-email-yulei.zh...@intel.com
Switched to a new branch 'test'
c4092ae00e vifo: introduce new VFIO ioctl VFIO_IOMMU_GET_DIRTY_BITMAP
a6090fffc5 vfio: Add struct vfio_vmstate_info to introduce put/get callback 
funtion for vfio device status save/restore
74f1f045a9 vfio: Add vm status change callback to stop/restart the mdev device
b32825279c vfio: introduce a new VFIO subregion for mdev device migration 
support

=== OUTPUT BEGIN ===
Checking PATCH 1/4: vfio: introduce a new VFIO subregion for mdev device 
migration support...
ERROR: initializer for struct VMStateDescription should normally be const
#49: FILE: hw/vfio/pci.c:3172:
+static VMStateDescription vfio_pci_vmstate = {

total: 1 errors, 0 warnings, 54 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 2/4: vfio: Add vm status change callback to stop/restart the 
mdev device...
Checking PATCH 3/4: vfio: Add struct vfio_vmstate_info to introduce put/get 
callback funtion for vfio device status save/restore...
Checking PATCH 4/4: vifo: introduce new VFIO ioctl 
VFIO_IOMMU_GET_DIRTY_BITMAP...
=== 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 V3 3/4] vfio: Add struct vfio_vmstate_info to introduce put/get callback funtion for vfio device status save/restore

2018-03-04 Thread Yulei Zhang
Introduce vfio_device_put/vfio_device_get funtion for vfio device state
save/restore usage.

For VFIO pci device status migrate, on the source side with
funtion vfio_device_put to save the following states
1. pci configuration space addr0~addr5
2. pci configuration space msi_addr msi_data
3. pci device status fetch from device driver

And on the target side with funtion vfio_device_get to restore
the same states
1. re-setup the pci bar configuration
2. re-setup the pci device msi configuration
3. restore the pci device status

Signed-off-by: Yulei Zhang 
---
 hw/vfio/pci.c  | 137 +
 linux-headers/linux/vfio.h |   3 +
 2 files changed, 140 insertions(+)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 3e2289c..c1676cf 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -2982,6 +2982,123 @@ static void vfio_vm_change_state_handler(void *pv, int 
running, RunState state)
 vbasedev->device_state = dev_state;
 }
 
+static int vfio_device_put(QEMUFile *f, void *pv, size_t size,
+   VMStateField *field, QJSON *vmdesc)
+{
+VFIOPCIDevice *vdev = pv;
+PCIDevice *pdev = >pdev;
+int sz = vdev->device_state.size - VFIO_DEVICE_STATE_OFFSET;
+uint8_t *buf = NULL;
+uint32_t msi_cfg, msi_lo, msi_hi, msi_data, bar_cfg, i;
+bool msi_64bit;
+
+for (i = 0; i < PCI_ROM_SLOT; i++) {
+bar_cfg = pci_default_read_config(pdev, PCI_BASE_ADDRESS_0 + i * 4, 4);
+qemu_put_be32(f, bar_cfg);
+}
+
+msi_cfg = pci_default_read_config(pdev, pdev->msi_cap + PCI_MSI_FLAGS, 2);
+msi_64bit = !!(msi_cfg & PCI_MSI_FLAGS_64BIT);
+
+msi_lo = pci_default_read_config(pdev,
+ pdev->msi_cap + PCI_MSI_ADDRESS_LO, 4);
+qemu_put_be32(f, msi_lo);
+
+if (msi_64bit) {
+msi_hi = pci_default_read_config(pdev,
+ pdev->msi_cap + PCI_MSI_ADDRESS_HI,
+ 4);
+qemu_put_be32(f, msi_hi);
+}
+
+msi_data = pci_default_read_config(pdev,
+   pdev->msi_cap + (msi_64bit ? PCI_MSI_DATA_64 : PCI_MSI_DATA_32),
+   2);
+qemu_put_be32(f, msi_data);
+
+buf = g_malloc(sz);
+if (buf == NULL) {
+error_report("vfio: Failed to allocate memory for migrate");
+goto exit;
+}
+
+if (pread(vdev->vbasedev.fd, buf, sz,
+  vdev->device_state.offset + VFIO_DEVICE_STATE_OFFSET) != sz) {
+error_report("vfio: Failed to read Device State Region");
+goto exit;
+}
+
+qemu_put_buffer(f, buf, sz);
+
+exit:
+g_free(buf);
+
+return 0;
+}
+
+static int vfio_device_get(QEMUFile *f, void *pv,
+   size_t size, VMStateField *field)
+{
+VFIOPCIDevice *vdev = pv;
+PCIDevice *pdev = >pdev;
+int sz = vdev->device_state.size - VFIO_DEVICE_STATE_OFFSET;
+uint8_t *buf = NULL;
+uint32_t ctl, msi_lo, msi_hi, msi_data, bar_cfg, i;
+bool msi_64bit;
+
+/* retore pci bar configuration */
+ctl = pci_default_read_config(pdev, PCI_COMMAND, 2);
+vfio_pci_write_config(pdev, PCI_COMMAND,
+  ctl & (!(PCI_COMMAND_IO | PCI_COMMAND_MEMORY)), 2);
+for (i = 0; i < PCI_ROM_SLOT; i++) {
+bar_cfg = qemu_get_be32(f);
+vfio_pci_write_config(pdev, PCI_BASE_ADDRESS_0 + i * 4, bar_cfg, 4);
+}
+vfio_pci_write_config(pdev, PCI_COMMAND,
+  ctl | PCI_COMMAND_IO | PCI_COMMAND_MEMORY, 2);
+
+/* restore msi configuration */
+ctl = pci_default_read_config(pdev, pdev->msi_cap + PCI_MSI_FLAGS, 2);
+msi_64bit = !!(ctl & PCI_MSI_FLAGS_64BIT);
+
+vfio_pci_write_config(>pdev,
+  pdev->msi_cap + PCI_MSI_FLAGS,
+  ctl & (!PCI_MSI_FLAGS_ENABLE), 2);
+
+msi_lo = qemu_get_be32(f);
+vfio_pci_write_config(pdev, pdev->msi_cap + PCI_MSI_ADDRESS_LO, msi_lo, 4);
+
+if (msi_64bit) {
+msi_hi = qemu_get_be32(f);
+vfio_pci_write_config(pdev, pdev->msi_cap + PCI_MSI_ADDRESS_HI,
+  msi_hi, 4);
+}
+msi_data = qemu_get_be32(f);
+vfio_pci_write_config(pdev,
+  pdev->msi_cap + (msi_64bit ? PCI_MSI_DATA_64 : PCI_MSI_DATA_32),
+  msi_data, 2);
+
+vfio_pci_write_config(>pdev, pdev->msi_cap + PCI_MSI_FLAGS,
+  ctl | PCI_MSI_FLAGS_ENABLE, 2);
+
+buf = g_malloc(sz);
+if (buf == NULL) {
+error_report("vfio: Failed to allocate memory for migrate");
+return -1;
+}
+
+qemu_get_buffer(f, buf, sz);
+if (pwrite(vdev->vbasedev.fd, buf, sz,
+   vdev->device_state.offset + VFIO_DEVICE_STATE_OFFSET) != sz) {
+error_report("vfio: Failed to write Device State Region");
+return -1;
+}
+
+g_free(buf);
+
+return 0;
+}
+
 static void vfio_instance_init(Object *obj)
 {
 PCIDevice *pci_dev = 

[Qemu-devel] [PATCH V3 4/4] vifo: introduce new VFIO ioctl VFIO_IOMMU_GET_DIRTY_BITMAP

2018-03-04 Thread Yulei Zhang
New VFIO ioctl VFIO_IOMMU_GET_DIRTY_BITMAP is used to fetch the
bitmap of pinned memory in iommu container, we need copy those
memory to the target during the migration as they are dirtied by
mdev devices.

Signed-off-by: Yulei Zhang 
---
 hw/vfio/common.c   | 34 ++
 linux-headers/linux/vfio.h | 14 ++
 2 files changed, 48 insertions(+)

diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 7b2924c..a952554 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -35,6 +35,7 @@
 #include "sysemu/kvm.h"
 #include "trace.h"
 #include "qapi/error.h"
+#include "exec/ram_addr.h"
 
 struct vfio_group_head vfio_group_list =
 QLIST_HEAD_INITIALIZER(vfio_group_list);
@@ -624,9 +625,42 @@ static void vfio_listener_region_del(MemoryListener 
*listener,
 }
 }
 
+static void vfio_log_sync(MemoryListener *listener,
+  MemoryRegionSection *section)
+{
+VFIOContainer *container = container_of(listener, VFIOContainer, listener);
+VFIOGroup *group = QLIST_FIRST(>group_list);
+VFIODevice *vbasedev;
+QLIST_FOREACH(vbasedev, >device_list, next) {
+if (vbasedev->device_state == VFIO_DEVICE_START) {
+return;
+}
+}
+
+struct vfio_iommu_get_dirty_bitmap *d;
+ram_addr_t size = int128_get64(section->size);
+unsigned long page_nr = size >> TARGET_PAGE_BITS;
+unsigned long bitmap_size =
+(BITS_TO_LONGS(page_nr) + 1) * sizeof(unsigned long);
+d = g_malloc0(sizeof(*d) + bitmap_size);
+d->start_addr = section->offset_within_address_space;
+d->page_nr = page_nr;
+
+if (ioctl(container->fd, VFIO_IOMMU_GET_DIRTY_BITMAP, d)) {
+error_report("vfio: Failed to fetch dirty pages for migration");
+goto exit;
+}
+
+cpu_physical_memory_set_dirty_lebitmap((unsigned long *)>dirty_bitmap,
+   d->start_addr, d->page_nr);
+exit:
+g_free(d);
+}
+
 static const MemoryListener vfio_memory_listener = {
 .region_add = vfio_listener_region_add,
 .region_del = vfio_listener_region_del,
+.log_sync = vfio_log_sync,
 };
 
 static void vfio_listener_release(VFIOContainer *container)
diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h
index 4451a8f..a41f73b 100644
--- a/linux-headers/linux/vfio.h
+++ b/linux-headers/linux/vfio.h
@@ -574,6 +574,20 @@ struct vfio_iommu_type1_dma_unmap {
 #define VFIO_IOMMU_ENABLE  _IO(VFIO_TYPE, VFIO_BASE + 15)
 #define VFIO_IOMMU_DISABLE _IO(VFIO_TYPE, VFIO_BASE + 16)
 
+/**
+ * VFIO_IOMMU_GET_DIRTY_BITMAP - _IOW(VFIO_TYPE, VFIO_BASE + 17,
+ * struct vfio_iommu_get_dirty_bitmap)
+ *
+ * Return: 0 on success, -errno on failure.
+ */
+struct vfio_iommu_get_dirty_bitmap {
+   __u64  start_addr;
+   __u64  page_nr;
+   __u8   dirty_bitmap[];
+};
+
+#define VFIO_IOMMU_GET_DIRTY_BITMAP _IO(VFIO_TYPE, VFIO_BASE + 17)
+
 /*  Additional API for SPAPR TCE (Server POWERPC) IOMMU  */
 
 /*
-- 
2.7.4




[Qemu-devel] [PATCH V3 2/4] vfio: Add vm status change callback to stop/restart the mdev device

2018-03-04 Thread Yulei Zhang
VM status change handler is added to change the vfio pci device
status during the migration, write the demanded device status
to the DEVICE STATUS subregion to stop the device on the source side
before fetch its status and start the deivce on the target side
after restore its status.

Signed-off-by: Yulei Zhang 
---
 hw/vfio/pci.c | 20 
 include/hw/vfio/vfio-common.h |  1 +
 linux-headers/linux/vfio.h|  3 +++
 3 files changed, 24 insertions(+)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 2fe20e4..3e2289c 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -38,6 +38,7 @@
 static void vfio_disable_interrupts(VFIOPCIDevice *vdev);
 static void vfio_mmap_set_enabled(VFIOPCIDevice *vdev, bool enabled);
 static VMStateDescription vfio_pci_vmstate;
+static void vfio_vm_change_state_handler(void *pv, int running, RunState 
state);
 
 /*
  * Disabling BAR mmaping can be slow, but toggling it around INTx can
@@ -2880,6 +2881,7 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
 vfio_register_err_notifier(vdev);
 vfio_register_req_notifier(vdev);
 vfio_setup_resetfn_quirk(vdev);
+qemu_add_vm_change_state_handler(vfio_vm_change_state_handler, vdev);
 
 return;
 
@@ -2962,6 +2964,24 @@ post_reset:
 vfio_pci_post_reset(vdev);
 }
 
+static void vfio_vm_change_state_handler(void *pv, int running, RunState state)
+{
+VFIOPCIDevice *vdev = pv;
+VFIODevice *vbasedev = >vbasedev;
+uint8_t dev_state;
+uint8_t sz = 1;
+
+dev_state = running ? VFIO_DEVICE_START : VFIO_DEVICE_STOP;
+
+if (pwrite(vdev->vbasedev.fd, _state,
+   sz, vdev->device_state.offset) != sz) {
+error_report("vfio: Failed to %s device", running ? "start" : "stop");
+return;
+}
+
+vbasedev->device_state = dev_state;
+}
+
 static void vfio_instance_init(Object *obj)
 {
 PCIDevice *pci_dev = PCI_DEVICE(obj);
diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index f3a2ac9..9c14a8f 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -125,6 +125,7 @@ typedef struct VFIODevice {
 unsigned int num_irqs;
 unsigned int num_regions;
 unsigned int flags;
+bool device_state;
 } VFIODevice;
 
 struct VFIODeviceOps {
diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h
index c3b8e4a..4ddeebc 100644
--- a/linux-headers/linux/vfio.h
+++ b/linux-headers/linux/vfio.h
@@ -303,6 +303,9 @@ struct vfio_region_info_cap_type {
 /* Mdev sub-type for device state save and restore */
 #define VFIO_REGION_SUBTYPE_DEVICE_STATE   (4)
 
+#define VFIO_DEVICE_START  0
+#define VFIO_DEVICE_STOP   1
+
 /**
  * VFIO_DEVICE_GET_IRQ_INFO - _IOWR(VFIO_TYPE, VFIO_BASE + 9,
  * struct vfio_irq_info)
-- 
2.7.4




[Qemu-devel] [PATCH V3 1/4] vfio: introduce a new VFIO subregion for mdev device migration support

2018-03-04 Thread Yulei Zhang
New VFIO sub region VFIO_REGION_SUBTYPE_DEVICE_STATE is added
to fetch and restore the status of mdev device vGPU during the
live migration.

Signed-off-by: Yulei Zhang 
---
 hw/vfio/pci.c  | 14 +-
 hw/vfio/pci.h  |  1 +
 linux-headers/linux/vfio.h |  9 ++---
 3 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 31e1edf..2fe20e4 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -37,6 +37,7 @@
 
 static void vfio_disable_interrupts(VFIOPCIDevice *vdev);
 static void vfio_mmap_set_enabled(VFIOPCIDevice *vdev, bool enabled);
+static VMStateDescription vfio_pci_vmstate;
 
 /*
  * Disabling BAR mmaping can be slow, but toggling it around INTx can
@@ -2813,6 +2814,17 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
 vfio_vga_quirk_setup(vdev);
 }
 
+struct vfio_region_info *device_state;
+/* device state region setup */
+if (!vfio_get_dev_region_info(>vbasedev,
+VFIO_REGION_TYPE_PCI_VENDOR_TYPE | PCI_VENDOR_ID_INTEL,
+VFIO_REGION_SUBTYPE_DEVICE_STATE, _state)) {
+memcpy(>device_state, device_state,
+   sizeof(struct vfio_region_info));
+g_free(device_state);
+vfio_pci_vmstate.unmigratable = 0;
+}
+
 for (i = 0; i < PCI_ROM_SLOT; i++) {
 vfio_bar_quirk_setup(vdev, i);
 }
@@ -2994,7 +3006,7 @@ static Property vfio_pci_dev_properties[] = {
 DEFINE_PROP_END_OF_LIST(),
 };
 
-static const VMStateDescription vfio_pci_vmstate = {
+static VMStateDescription vfio_pci_vmstate = {
 .name = "vfio-pci",
 .unmigratable = 1,
 };
diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
index a8366bb..6a1d26e 100644
--- a/hw/vfio/pci.h
+++ b/hw/vfio/pci.h
@@ -116,6 +116,7 @@ typedef struct VFIOPCIDevice {
 VFIOBAR bars[PCI_NUM_REGIONS - 1]; /* No ROM */
 VFIOVGA *vga; /* 0xa, 0x3b0, 0x3c0 */
 void *igd_opregion;
+struct vfio_region_info device_state;
 PCIHostDeviceAddress host;
 EventNotifier err_notifier;
 EventNotifier req_notifier;
diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h
index 4e7ab4c..c3b8e4a 100644
--- a/linux-headers/linux/vfio.h
+++ b/linux-headers/linux/vfio.h
@@ -296,9 +296,12 @@ struct vfio_region_info_cap_type {
 #define VFIO_REGION_TYPE_PCI_VENDOR_MASK   (0x)
 
 /* 8086 Vendor sub-types */
-#define VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION (1)
-#define VFIO_REGION_SUBTYPE_INTEL_IGD_HOST_CFG (2)
-#define VFIO_REGION_SUBTYPE_INTEL_IGD_LPC_CFG  (3)
+#define VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION (1)
+#define VFIO_REGION_SUBTYPE_INTEL_IGD_HOST_CFG (2)
+#define VFIO_REGION_SUBTYPE_INTEL_IGD_LPC_CFG  (3)
+
+/* Mdev sub-type for device state save and restore */
+#define VFIO_REGION_SUBTYPE_DEVICE_STATE   (4)
 
 /**
  * VFIO_DEVICE_GET_IRQ_INFO - _IOWR(VFIO_TYPE, VFIO_BASE + 9,
-- 
2.7.4




[Qemu-devel] [PATCH V3 0/4] vfio: Introduce Live migration capability to vfio_mdev device

2018-03-04 Thread Yulei Zhang
Summary

This series RFC would like to resume the discussion about how to
introduce the live migration capability to vfio mdev device. 

By adding a new vfio subtype region VFIO_REGION_SUBTYPE_DEVICE_STATE,
the mdev device will be set to migratable if the new region exist
during the initialization.  

The intention to add the new region is using it for mdev device status
save and restore during the migration. The access to this region
will be trapped and forward to the mdev device driver, it also uses 
the first byte in the new region to control the running state of mdev
device, so during the migration after stop the mdev driver, qemu could
retrieve the specific device status from this region and transfer to 
the target VM side for the mdev device restore.

In addition,  we add one new ioctl VFIO_IOMMU_GET_DIRTY_BITMAP to help do 
the mdev device dirty page synchronization during the migration, currently
it is just for static copy, in the future we would like to add new interface
for the pre-copy.

Below is the vfio_mdev device migration sequence
Source VM side:
start migration
|
V
 get the cpu state change callback, write to the
 subregion's first byte to stop the mdev device
|
V
 quary the dirty page bitmap from iommu container 
 and add into qemu dirty list for synchronization
|
V
 save the deivce status into Qemufile which is 
 read from the vfio device subregion

Target VM side:
   restore the mdev device after get the
 saved status context from Qemufile
|
V
 get the cpu state change callback
 write to subregion's first byte to 
  start the mdev device to put it in 
  running status
|
V
finish migration

V3->V2:
1. rebase the patch to Qemu stable 2.10 branch.
2. use a common name for the subregion instead of specific for 
   intel IGD.

V1->V2:
Per Alex's suggestion:
1. use device subtype region instead of VFIO PCI fixed region.
2. remove unnecessary ioctl, use the first byte of subregion to 
   control the running state of mdev device.  
3. for dirty page synchronization, implement the interface with
   VFIOContainer instead of vfio pci device.

Yulei Zhang (4):
  vfio: introduce a new VFIO subregion for mdev device migration support
  vfio: Add vm status change callback to stop/restart the mdev device
  vfio: Add struct vfio_vmstate_info to introduce put/get callback
funtion for vfio device status save/restore
  vifo: introduce new VFIO ioctl VFIO_IOMMU_GET_DIRTY_BITMAP

 hw/vfio/common.c  |  34 +
 hw/vfio/pci.c | 171 +-
 hw/vfio/pci.h |   1 +
 include/hw/vfio/vfio-common.h |   1 +
 linux-headers/linux/vfio.h|  29 ++-
 5 files changed, 232 insertions(+), 4 deletions(-)

-- 
2.7.4



Re: [Qemu-devel] [PATCH v2 07/15] qio/chardev: update net listener gcontext

2018-03-04 Thread Peter Xu
On Fri, Mar 02, 2018 at 12:17:30PM +0100, Paolo Bonzini wrote:
> On 02/03/2018 05:26, Peter Xu wrote:
> > Frankly speaking I was a bit confused when I started to read
> > chardev/qio codes with so many hooks, e.g., when I saw:
> > 
> >  qio_net_listener_set_client_func(s->listener, tcp_chr_accept,
> >   chr, NULL);
> > 
> > I totally have no idea on what happened.  I need to go deeper into the
> > net listener code to know that, hmm, it's setting up something to
> > accept connections!
> > 
> > If I can have something like:
> > 
> > tcp_chr_net_listener_setup(s, true);
> > 
> > It may be easier for me to understand that there's something either
> > registered for the listening ports, and I don't need to care about
> > which function will be called when accept happened.  Basically it
> > "hides" some logic inside, that's IMHO where functions/macros help.
> 
> I tend to agree with Daniel, but I probably would be convinced if you
> had a pair of functions tcp_chr_{start,stop}_listen instead of a bool
> argument.

Thanks Paolo for your suggestion.

Let me just keep the code untouched so that we can be more focused on
the topic of the series.  I'll try to avoid unecessary clean ups
there.  Thanks,

-- 
Peter Xu



Re: [Qemu-devel] [PATCH v2 05/15] qio: refactor net listener source operations

2018-03-04 Thread Peter Xu
On Fri, Mar 02, 2018 at 10:51:01AM +, Daniel P. Berrangé wrote:
> On Fri, Mar 02, 2018 at 11:58:52AM +0800, Peter Xu wrote:
> > On Thu, Mar 01, 2018 at 10:47:17AM +, Daniel P. Berrangé wrote:
> > > On Thu, Mar 01, 2018 at 04:44:28PM +0800, Peter Xu wrote:
> > > > Three functions are abstracted from the old code:
> > > > 
> > > > - qio_net_listener_source_add(): create one source for listener
> > > > - qio_net_listener_sources_clear(): unset existing net lister sources
> > > > - qio_net_listener_sources_update(): setup all sources for listener
> > > > 
> > > > Use them where possible.
> > > > 
> > > > Signed-off-by: Peter Xu 
> > > > ---
> > > >  io/net-listener.c | 82 
> > > > +++
> > > >  1 file changed, 41 insertions(+), 41 deletions(-)
> > > 
> > > This patch can be dropped since nothing else in the series now
> > > depends on it.
> > 
> > Do you think it's still acceptable even as a cleanup?  Thanks,
> 
> I don't think it really adds value over what's there already.

I'll drop it.  Thanks.

-- 
Peter Xu



[Qemu-devel] [PATCH v7 1/3] pci: Add support for Designware IP block

2018-03-04 Thread Andrey Smirnov
Add code needed to get a functional PCI subsytem when using in
conjunction with upstream Linux guest (4.13+). Tested to work against
"e1000e" (network adapter, using MSI interrupts) as well as
"usb-ehci" (USB controller, using legacy PCI interrupts).

Based on "i.MX6 Applications Processor Reference Manual" (Document
Number: IMX6DQRM Rev. 4) as well as corresponding dirver in Linux
kernel (circa 4.13 - 4.16 found in drivers/pci/dwc/*)

Cc: Peter Maydell 
Cc: Jason Wang 
Cc: Philippe Mathieu-Daudé 
Cc: Marcel Apfelbaum 
Cc: Michael S. Tsirkin 
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Signed-off-by: Andrey Smirnov 
---
 default-configs/arm-softmmu.mak  |   2 +
 include/hw/pci-host/designware.h | 102 ++
 include/hw/pci/pci_ids.h |   2 +
 hw/pci-host/designware.c | 755 +++
 hw/pci-host/Makefile.objs|   2 +
 5 files changed, 863 insertions(+)
 create mode 100644 include/hw/pci-host/designware.h
 create mode 100644 hw/pci-host/designware.c

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index d724106bd3..5540ea5e7e 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -140,3 +140,5 @@ CONFIG_GPIO_KEY=y
 CONFIG_MSF2=y
 CONFIG_FW_CFG_DMA=y
 CONFIG_XILINX_AXI=y
+CONFIG_PCI_DESIGNWARE=y
+
diff --git a/include/hw/pci-host/designware.h b/include/hw/pci-host/designware.h
new file mode 100644
index 00..a4f2c0695b
--- /dev/null
+++ b/include/hw/pci-host/designware.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2017, Impinj, Inc.
+ *
+ * Designware PCIe IP block emulation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * .
+ */
+
+#ifndef DESIGNWARE_H
+#define DESIGNWARE_H
+
+#include "hw/hw.h"
+#include "hw/sysbus.h"
+#include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
+#include "hw/pci/pcie_host.h"
+#include "hw/pci/pci_bridge.h"
+
+#define TYPE_DESIGNWARE_PCIE_HOST "designware-pcie-host"
+#define DESIGNWARE_PCIE_HOST(obj) \
+ OBJECT_CHECK(DesignwarePCIEHost, (obj), TYPE_DESIGNWARE_PCIE_HOST)
+
+#define TYPE_DESIGNWARE_PCIE_ROOT "designware-pcie-root"
+#define DESIGNWARE_PCIE_ROOT(obj) \
+ OBJECT_CHECK(DesignwarePCIERoot, (obj), TYPE_DESIGNWARE_PCIE_ROOT)
+
+struct DesignwarePCIERoot;
+typedef struct DesignwarePCIERoot DesignwarePCIERoot;
+
+typedef struct DesignwarePCIEViewport {
+DesignwarePCIERoot *root;
+
+MemoryRegion cfg;
+MemoryRegion mem;
+
+uint64_t base;
+uint64_t target;
+uint32_t limit;
+uint32_t cr[2];
+
+bool inbound;
+} DesignwarePCIEViewport;
+
+typedef struct DesignwarePCIEMSIBank {
+uint32_t enable;
+uint32_t mask;
+uint32_t status;
+} DesignwarePCIEMSIBank;
+
+typedef struct DesignwarePCIEMSI {
+uint64_t base;
+MemoryRegion iomem;
+
+#define DESIGNWARE_PCIE_NUM_MSI_BANKS1
+
+DesignwarePCIEMSIBank intr[DESIGNWARE_PCIE_NUM_MSI_BANKS];
+} DesignwarePCIEMSI;
+
+struct DesignwarePCIERoot {
+PCIBridge parent_obj;
+
+uint32_t atu_viewport;
+
+#define DESIGNWARE_PCIE_VIEWPORT_OUTBOUND0
+#define DESIGNWARE_PCIE_VIEWPORT_INBOUND 1
+#define DESIGNWARE_PCIE_NUM_VIEWPORTS4
+
+DesignwarePCIEViewport viewports[2][DESIGNWARE_PCIE_NUM_VIEWPORTS];
+DesignwarePCIEMSI msi;
+};
+
+typedef struct DesignwarePCIEHost {
+PCIHostState parent_obj;
+
+DesignwarePCIERoot root;
+
+struct {
+AddressSpace address_space;
+MemoryRegion address_space_root;
+
+MemoryRegion memory;
+MemoryRegion io;
+
+qemu_irq irqs[4];
+} pci;
+
+MemoryRegion mmio;
+} DesignwarePCIEHost;
+
+#endif  /* DESIGNWARE_H */
diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h
index 1dbf53627c..63acc722a9 100644
--- a/include/hw/pci/pci_ids.h
+++ b/include/hw/pci/pci_ids.h
@@ -269,4 +269,6 @@
 #define PCI_VENDOR_ID_VMWARE 0x15ad
 #define PCI_DEVICE_ID_VMWARE_PVRDMA  0x0820
 
+#define PCI_VENDOR_ID_SYNOPSYS   0x16C3
+
 #endif
diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c
new file mode 100644
index 00..7b9add3da1
--- /dev/null
+++ b/hw/pci-host/designware.c
@@ -0,0 +1,755 @@
+/*
+ * Copyright (c) 2018, Impinj, Inc.
+ 

[Qemu-devel] [PATCH v7 2/3] i.MX: Add i.MX7 SOC implementation.

2018-03-04 Thread Andrey Smirnov
The following interfaces are partially or fully emulated:

* up to 2 Cortex A9 cores (SMP works with PSCI)
* A7 MPCORE (identical to A15 MPCORE)
* 4 GPTs modules
* 7 GPIO controllers
* 2 IOMUXC controllers
* 1 CCM module
* 1 SVNS module
* 1 SRC module
* 1 GPCv2 controller
* 4 eCSPI controllers
* 4 I2C controllers
* 7 i.MX UART controllers
* 2 FlexCAN controllers
* 2 Ethernet controllers (FEC)
* 3 SD controllers (USDHC)
* 4 WDT modules
* 1 SDMA module
* 1 GPR module
* 2 USBMISC modules
* 2 ADC modules
* 1 PCIe controller

Tested to boot and work with upstream Linux (4.13+) guest.

Cc: Peter Maydell 
Cc: Jason Wang 
Cc: Philippe Mathieu-Daudé 
Cc: Marcel Apfelbaum 
Cc: Michael S. Tsirkin 
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Peter Maydell 
Signed-off-by: Andrey Smirnov 
---
 default-configs/arm-softmmu.mak |   1 +
 include/hw/arm/fsl-imx7.h   | 222 +++
 hw/arm/fsl-imx7.c   | 580 
 hw/arm/Makefile.objs|   2 +
 4 files changed, 805 insertions(+)
 create mode 100644 include/hw/arm/fsl-imx7.h
 create mode 100644 hw/arm/fsl-imx7.c

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 5540ea5e7e..7665a02fb2 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -126,6 +126,7 @@ CONFIG_ALLWINNER_A10=y
 CONFIG_FSL_IMX6=y
 CONFIG_FSL_IMX31=y
 CONFIG_FSL_IMX25=y
+CONFIG_FSL_IMX7=y
 
 CONFIG_IMX_I2C=y
 
diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
new file mode 100644
index 00..d848262bfd
--- /dev/null
+++ b/include/hw/arm/fsl-imx7.h
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2018, Impinj, Inc.
+ *
+ * i.MX7 SoC definitions
+ *
+ * Author: Andrey Smirnov 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef FSL_IMX7_H
+#define FSL_IMX7_H
+
+#include "hw/arm/arm.h"
+#include "hw/cpu/a15mpcore.h"
+#include "hw/intc/imx_gpcv2.h"
+#include "hw/misc/imx7_ccm.h"
+#include "hw/misc/imx7_snvs.h"
+#include "hw/misc/imx7_gpr.h"
+#include "hw/misc/imx6_src.h"
+#include "hw/misc/imx2_wdt.h"
+#include "hw/gpio/imx_gpio.h"
+#include "hw/char/imx_serial.h"
+#include "hw/timer/imx_gpt.h"
+#include "hw/timer/imx_epit.h"
+#include "hw/i2c/imx_i2c.h"
+#include "hw/gpio/imx_gpio.h"
+#include "hw/sd/sdhci.h"
+#include "hw/ssi/imx_spi.h"
+#include "hw/net/imx_fec.h"
+#include "hw/pci-host/designware.h"
+#include "hw/usb/chipidea.h"
+#include "exec/memory.h"
+#include "cpu.h"
+
+#define TYPE_FSL_IMX7 "fsl,imx7"
+#define FSL_IMX7(obj) OBJECT_CHECK(FslIMX7State, (obj), TYPE_FSL_IMX7)
+
+enum FslIMX7Configuration {
+FSL_IMX7_NUM_CPUS = 2,
+FSL_IMX7_NUM_UARTS= 7,
+FSL_IMX7_NUM_ETHS = 2,
+FSL_IMX7_ETH_NUM_TX_RINGS = 3,
+FSL_IMX7_NUM_USDHCS   = 3,
+FSL_IMX7_NUM_WDTS = 4,
+FSL_IMX7_NUM_GPTS = 4,
+FSL_IMX7_NUM_IOMUXCS  = 2,
+FSL_IMX7_NUM_GPIOS= 7,
+FSL_IMX7_NUM_I2CS = 4,
+FSL_IMX7_NUM_ECSPIS   = 4,
+FSL_IMX7_NUM_USBS = 3,
+FSL_IMX7_NUM_ADCS = 2,
+};
+
+typedef struct FslIMX7State {
+/*< private >*/
+DeviceStateparent_obj;
+
+/*< public >*/
+ARMCPU cpu[FSL_IMX7_NUM_CPUS];
+A15MPPrivState a7mpcore;
+IMXGPTStategpt[FSL_IMX7_NUM_GPTS];
+IMXGPIOState   gpio[FSL_IMX7_NUM_GPIOS];
+IMX7CCMState   ccm;
+IMX7AnalogStateanalog;
+IMX7SNVSState  snvs;
+IMXGPCv2State  gpcv2;
+IMXSPIStatespi[FSL_IMX7_NUM_ECSPIS];
+IMXI2CStatei2c[FSL_IMX7_NUM_I2CS];
+IMXSerialState uart[FSL_IMX7_NUM_UARTS];
+IMXFECStateeth[FSL_IMX7_NUM_ETHS];
+SDHCIState usdhc[FSL_IMX7_NUM_USDHCS];
+IMX2WdtState   wdt[FSL_IMX7_NUM_WDTS];
+IMX7GPRState   gpr;
+ChipideaState  usb[FSL_IMX7_NUM_USBS];
+DesignwarePCIEHost pcie;
+} FslIMX7State;
+
+enum FslIMX7MemoryMap {
+FSL_IMX7_MMDC_ADDR= 0x8000,
+FSL_IMX7_MMDC_SIZE= 2 * 1024 * 1024 * 1024UL,
+
+FSL_IMX7_GPIO1_ADDR   = 0x3020,
+FSL_IMX7_GPIO2_ADDR   = 0x3021,
+FSL_IMX7_GPIO3_ADDR   = 0x3022,
+

[Qemu-devel] [PATCH] target/s390x: Remove leading underscores from #defines

2018-03-04 Thread Thomas Huth
We should not use leading underscores followed by a capital letter
in #defines since such identifiers are reserved by the C standard.

For ASCE_ORIGIN, REGION_ENTRY_ORIGIN and SEGMENT_ENTRY_ORIGIN I also
added parentheses around the value to silence an error message from
checkpatch.pl.

Signed-off-by: Thomas Huth 
---
 target/s390x/cpu.h| 66 +++
 target/s390x/mem_helper.c | 20 +++---
 target/s390x/mmu_helper.c | 54 +++---
 3 files changed, 70 insertions(+), 70 deletions(-)

diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index c5ef930..5f357a4e 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -538,39 +538,39 @@ typedef union SysIB {
 QEMU_BUILD_BUG_ON(sizeof(SysIB) != 4096);
 
 /* MMU defines */
-#define _ASCE_ORIGIN~0xfffULL /* segment table origin 
*/
-#define _ASCE_SUBSPACE  0x200 /* subspace group control   
*/
-#define _ASCE_PRIVATE_SPACE 0x100 /* private space control
*/
-#define _ASCE_ALT_EVENT 0x80  /* storage alteration event control 
*/
-#define _ASCE_SPACE_SWITCH  0x40  /* space switch event   
*/
-#define _ASCE_REAL_SPACE0x20  /* real space control   
*/
-#define _ASCE_TYPE_MASK 0x0c  /* asce table type mask 
*/
-#define _ASCE_TYPE_REGION1  0x0c  /* region first table type  
*/
-#define _ASCE_TYPE_REGION2  0x08  /* region second table type 
*/
-#define _ASCE_TYPE_REGION3  0x04  /* region third table type  
*/
-#define _ASCE_TYPE_SEGMENT  0x00  /* segment table type   
*/
-#define _ASCE_TABLE_LENGTH  0x03  /* region table length  
*/
-
-#define _REGION_ENTRY_ORIGIN~0xfffULL /* region/segment table origin  
*/
-#define _REGION_ENTRY_RO0x200 /* region/segment protection bit
*/
-#define _REGION_ENTRY_TF0xc0  /* region/segment table offset  
*/
-#define _REGION_ENTRY_INV   0x20  /* invalid region table entry   
*/
-#define _REGION_ENTRY_TYPE_MASK 0x0c  /* region/segment table type mask   
*/
-#define _REGION_ENTRY_TYPE_R1   0x0c  /* region first table type  
*/
-#define _REGION_ENTRY_TYPE_R2   0x08  /* region second table type 
*/
-#define _REGION_ENTRY_TYPE_R3   0x04  /* region third table type  
*/
-#define _REGION_ENTRY_LENGTH0x03  /* region third length  
*/
-
-#define _SEGMENT_ENTRY_ORIGIN   ~0x7ffULL /* segment table origin 
*/
-#define _SEGMENT_ENTRY_FC   0x400 /* format control   
*/
-#define _SEGMENT_ENTRY_RO   0x200 /* page protection bit  
*/
-#define _SEGMENT_ENTRY_INV  0x20  /* invalid segment table entry  
*/
-
-#define VADDR_PX0xff000   /* page index bits  
*/
-
-#define _PAGE_RO0x200/* HW read-only bit  */
-#define _PAGE_INVALID   0x400/* HW invalid bit*/
-#define _PAGE_RES0  0x800/* bit must be zero  */
+#define ASCE_ORIGIN   (~0xfffULL) /* segment table origin 
*/
+#define ASCE_SUBSPACE 0x200   /* subspace group control   
*/
+#define ASCE_PRIVATE_SPACE0x100   /* private space control
*/
+#define ASCE_ALT_EVENT0x80/* storage alteration event control 
*/
+#define ASCE_SPACE_SWITCH 0x40/* space switch event   
*/
+#define ASCE_REAL_SPACE   0x20/* real space control   
*/
+#define ASCE_TYPE_MASK0x0c/* asce table type mask 
*/
+#define ASCE_TYPE_REGION1 0x0c/* region first table type  
*/
+#define ASCE_TYPE_REGION2 0x08/* region second table type 
*/
+#define ASCE_TYPE_REGION3 0x04/* region third table type  
*/
+#define ASCE_TYPE_SEGMENT 0x00/* segment table type   
*/
+#define ASCE_TABLE_LENGTH 0x03/* region table length  
*/
+
+#define REGION_ENTRY_ORIGIN   (~0xfffULL) /* region/segment table origin*/
+#define REGION_ENTRY_RO   0x200   /* region/segment protection bit  */
+#define REGION_ENTRY_TF   0xc0/* region/segment table offset*/
+#define REGION_ENTRY_INV  0x20/* invalid region table entry */
+#define REGION_ENTRY_TYPE_MASK 0x0c   /* region/segment table type mask */
+#define REGION_ENTRY_TYPE_R1  0x0c/* region first table type*/
+#define REGION_ENTRY_TYPE_R2  0x08/* region second table type   */
+#define REGION_ENTRY_TYPE_R3  0x04/* region third table type*/
+#define REGION_ENTRY_LENGTH   0x03/* region third length*/
+
+#define SEGMENT_ENTRY_ORIGIN  (~0x7ffULL) /* segment table origin*/

[Qemu-devel] [PATCH v7 0/3] Initial i.MX7 support

2018-03-04 Thread Andrey Smirnov
Hi everyone,

This v7 of the patch series containing the work that I've done in
order to enable support for i.MX7 emulation in QEMU.

As the one before last commit in the series states the supported i.MX7
features are:

* up to 2 Cortex A9 cores (SMP works with PSCI)
* A7 MPCORE (identical to A15 MPCORE)
* 4 GPTs modules
* 7 GPIO controllers
* 2 IOMUXC controllers
* 1 CCM module
* 1 SVNS module
* 1 SRC module
* 1 GPCv2 controller
* 4 eCSPI controllers
* 4 I2C controllers
* 7 i.MX UART controllers
* 2 FlexCAN controllers
* 2 Ethernet controllers (FEC)
* 3 SD controllers (USDHC)
* 4 WDT modules
* 1 SDMA module
* 1 GPR module
* 2 USBMISC modules
* 2 ADC modules
* 1 PCIe controller
* 3 USB controllers
* 1 LCD controller
* 1 ARMv7 DAP IP block

Feedback is welcome!

Changes since [v6]:

- All endiannes in Designware PCI implementation is now specified
  as little-endian

Changes since [v5]:

- Rebase patchest on top of latest QEMU master, so now the
  patchset is down to three patches

- Reverted the change to use pci_data_* functions becuase the
  patch supporting this change was causing trouble

- Fixed endiannes of MSI and configuration space accessors to be
  LITTLE_ENDIAN

Changes since [v4]:

- Rebase patchest on top of latest QEMU master

- Reworked PCIE emulation code to create MemoryRegions
  only once

- Fixed incorrect usages of PCI instead of PCIE

- Fixed device class reported by PCIE bridge

- Added patch to make pci_data_read() and pci_data_write() usable
  for PCIE devices as well

- Converted PCIE code to use pci_data_read() and pci_data_write()

- Added VMStateDescription code for PCIE

- Collected Reviewed-by tag from Philippe

Changes since [v3]:

- Changes to FEC were split into a separate set and merged to master

- Patchest is rebased on latest master

- Converted to use PSCI DT fixup code that is shared with virt
  platform (now relocated to live in arm/boot.c)

- Large number of dummy block were converted to use
  create_unimplemented_device() as opposed to its own dedicated
  type

- Incorporated varios small feedback items

- Collected Reviewed-by tags from Peter

Changes since [v2]:

- Added stubs for more blocks that were causing memory
  transactions when booting Linux guest as were revealed by
  additional testing of the patchest

- Added proper USB emulation code, so now it should be possible to
  emulated guest's USB bus

Changes since [v1]:

- Patchset no longer relies on "ignore_memory_transaction_failures = false"
  for its functionality

- As a consequnce of implementing the above a number of patches
  implementing dummy IP block emulation as well as PCIe emulation
  patches that I alluded to in [v1] are now included in this patch
  series

- "has_el3" property is no longer being set to "false" as a part
  of intialization of A7 CPU. I couldn't reproduce the issues that
  I thought I was having, so I just dropped that code.

- A number of smaller feedback items from Peter and other has been
  incorporated into the patches.


Thanks,
Andrey Smirnov

[v6] https://lists.gnu.org/archive/html/qemu-devel/2018-02/msg03587.html
[v5] https://lists.gnu.org/archive/html/qemu-devel/2018-02/msg01558.html
[v4] https://lists.gnu.org/archive/html/qemu-devel/2018-01/msg03264.html
[v3] https://lists.gnu.org/archive/html/qemu-devel/2017-11/msg04236.html
[v2] https://lists.gnu.org/archive/html/qemu-devel/2017-10/msg05516.html
[v1] https://lists.gnu.org/archive/html/qemu-devel/2017-09/msg04770.html

Andrey Smirnov (3):
  pci: Add support for Designware IP block
  i.MX: Add i.MX7 SOC implementation.
  Implement support for i.MX7 Sabre board

 default-configs/arm-softmmu.mak  |   3 +
 include/hw/arm/fsl-imx7.h| 222 
 include/hw/pci-host/designware.h | 102 ++
 include/hw/pci/pci_ids.h |   2 +
 hw/arm/fsl-imx7.c| 580 ++
 hw/arm/mcimx7d-sabre.c   |  90 +
 hw/pci-host/designware.c | 755 +++
 hw/arm/Makefile.objs |   3 +
 hw/pci-host/Makefile.objs|   2 +
 9 files changed, 1759 insertions(+)
 create mode 100644 include/hw/arm/fsl-imx7.h
 create mode 100644 include/hw/pci-host/designware.h
 create mode 100644 hw/arm/fsl-imx7.c
 create mode 100644 hw/arm/mcimx7d-sabre.c
 create mode 100644 hw/pci-host/designware.c

-- 
2.14.3




Re: [Qemu-devel] [PATCH v3 05/12] hw/pci: introduce PCISVAOps to PCIDevice

2018-03-04 Thread David Gibson
On Thu, Mar 01, 2018 at 06:31:55PM +0800, Liu, Yi L wrote:
> This patch intoduces PCISVAOps for virt-SVA.
> 
> So far, to setup virt-SVA for assigned SVA capable device, needs to
> config host translation structures. e.g. for VT-d, needs to set the
> guest pasid table to host and enable nested translation. Besides,
> vIOMMU emulator needs to forward guest's cache invalidation to host.
> On VT-d, it is guest's invalidation to 1st level translation related
> cache, such invalidation should be forwarded to host.
> 
> Proposed PCISVAOps are:
> * sva_bind_guest_pasid_table: set the guest pasid table to host, and
>   enable nested translation in host
> * sva_register_notifier: register sva_notifier to forward guest's
>  cache invalidation to host
> * sva_unregister_notifier: unregister sva_notifier
> 
> The PCISVAOps should be provided by vfio or modules alike. Mainly for
> assigned SVA capable devices.
> 
> Take virt-SVA on VT-d as an exmaple:
> If a guest wants to setup virt-SVA for an assigned SVA capable device,
> it programs its context entry. vIOMMU emulator captures guest's context
> entry programming, and figure out the target device. vIOMMU emulator
> use the pci_device_sva_bind_pasid_table() API to bind the guest pasid
> table to host.
> 
> Guest would also program its pasid table. vIOMMU emulator captures
> guest's pasid entry programming. In Qemu, needs to allocate an
> AddressSpace to stand for the pasid tagged address space and Qemu also
> needs to register sva_notifier to forward future cache invalidation
> request to host.
> 
> Allocating AddressSpace to stand for the pasid tagged address space is
> for the emulation of emulated SVA capable devices. Emulated SVA capable
> devices may issue SVA aware DMAs, Qemu needs to emulate read/write to a
> pasid tagged AddressSpace. Thus needs an abstraction for such address
> space in Qemu.
> 
> Signed-off-by: Liu, Yi L 

So PCISVAOps is roughly equivalent to the cluster-of-PASIDs context I
was suggesting in my earlier comments, however it's only an ops
structure.  That means you can't easily share a context between
multiple PCI devices which is unfortunate because:
* The simplest use case for SVA I can see would just put the
  same set of PASIDs into place for every SVA capable device
* Sometimes the IOMMU can't determine exactly what device a DMA
  came from.  Now the bridge cases where this applies are probably
  unlikely with SVA devices, but I wouldn't want to bet on it.  In
  addition, the chances some manufacturer will eventually put out
  a buggy multifunction SVA capable device that use the wrong RIDs
  for the secondary functions is pretty darn high.

So I think instead you want a cluster-of-PASIDs object which has an
ops table including both these and the per-PASID calls from the
earlier patches (but the per-PASID calls would now take an explicit
PASID value).

> ---
>  hw/pci/pci.c | 60 
> 
>  include/hw/pci/pci.h | 21 ++
>  2 files changed, 81 insertions(+)
> 
> diff --git a/hw/pci/pci.c b/hw/pci/pci.c
> index e006b6a..157fe21 100644
> --- a/hw/pci/pci.c
> +++ b/hw/pci/pci.c
> @@ -2573,6 +2573,66 @@ void pci_setup_iommu(PCIBus *bus, PCIIOMMUFunc fn, 
> void *opaque)
>  bus->iommu_opaque = opaque;
>  }
>  
> +void pci_setup_sva_ops(PCIDevice *dev, PCISVAOps *ops)
> +{
> +if (dev) {
> +dev->sva_ops = ops;
> +}
> +return;
> +}
> +
> +void pci_device_sva_bind_pasid_table(PCIBus *bus,
> + int32_t devfn, uint64_t addr, uint32_t size)
> +{
> +PCIDevice *dev;
> +
> +if (!bus) {
> +return;
> +}
> +
> +dev = bus->devices[devfn];
> +if (dev && dev->sva_ops) {
> +dev->sva_ops->sva_bind_pasid_table(bus, devfn, addr, size);
> +}
> +return;
> +}
> +
> +void pci_device_sva_register_notifier(PCIBus *bus, int32_t devfn,
> +  IOMMUSVAContext *sva_ctx)
> +{
> +PCIDevice *dev;
> +
> +if (!bus) {
> +return;
> +}
> +
> +dev = bus->devices[devfn];
> +if (dev && dev->sva_ops) {
> +dev->sva_ops->sva_register_notifier(bus,
> +devfn,
> +sva_ctx);
> +}
> +return;
> +}
> +
> +void pci_device_sva_unregister_notifier(PCIBus *bus, int32_t devfn,
> +IOMMUSVAContext *sva_ctx)
> +{
> +PCIDevice *dev;
> +
> +if (!bus) {
> +return;
> +}
> +
> +dev = bus->devices[devfn];
> +if (dev && dev->sva_ops) {
> +dev->sva_ops->sva_unregister_notifier(bus,
> +  devfn,
> +  sva_ctx);
> +}
> +return;
> +}
> +
>  static void pci_dev_get_w64(PCIBus *b, PCIDevice *dev, void *opaque)
>  {
>  

Re: [Qemu-devel] [PATCH v3 03/12] hw/core: introduce IOMMUSVAContext for virt-SVA

2018-03-04 Thread David Gibson
On Thu, Mar 01, 2018 at 06:31:53PM +0800, Liu, Yi L wrote:
> From: Peter Xu 
> 
> This patch adds IOMMUSVAContext as an abstract for virt-SVA in
> Qemu.
> 
> IOMMUSVAContext is per-PASID(Process Address Space Identity).
> A PASID Tagged AddressSpace should have an IOMMUSVAContext
> created for it. virt-SVA emulation for emulated SVA capable
> devices would use IOMMUSVAContext. And for assigned devices,
> Qemu also needs to propagate guest tlb flush to host through
> the sva_notifer based on IOMMUSVAContext.
> 
> This patch proposes to include a sva_notifier list and
> an IOMMUSVAContextOps in IOMMUSVAContext.
> 
> * The sva_notifier list would include tlb invalidate nofitifer
>   to propagate guest's iotlb flush to host.
> * The first callback in IOMMUSVAContextOps would be an address
>   translation callback. For the SVA aware DMAs issued by emulated
>   SVA capable devices, it requires Qemu to emulate data read/write
>   to guest process address space. Qemu needs to do address translation
>   with guest process page table. So the IOMMUSVAContextOps.translate()
>   callback would be helpful for emulating SVA capable devices.
> 
> Note: to fulfill the IOMMUSVAContext based address translation
> framework, may duplicate quite a few existing MemoryRegion based
> translation code in Qemu. As this patchset is mainly to support
> assigned SVA capable devices. So this patchset hasn't done the
> duplication. In future, if any requirement for emulating SVA
> capable device, it would require a separate patchset to fulfill
> the translation framework.
> 
> Signed-off-by: Peter Xu 
> Signed-off-by: Liu, Yi L 
> ---
>  hw/core/Makefile.objs   |   1 +
>  hw/core/pasid.c |  64 
>  include/hw/core/pasid.h | 110 
> 
>  3 files changed, 175 insertions(+)
>  create mode 100644 hw/core/pasid.c
>  create mode 100644 include/hw/core/pasid.h

[snip]
> +
> +#ifndef HW_PCI_PASID_H
> +#define HW_PCI_PASID_H
> +
> +#include "qemu/queue.h"
> +#ifndef CONFIG_USER_ONLY
> +#include "exec/hwaddr.h"
> +#endif
> +
> +typedef struct IOMMUSVAContext IOMMUSVAContext;
> +
> +enum IOMMUSVAEvent {
> +IOMMU_SVA_EVENT_TLB_INV,
> +};
> +typedef enum IOMMUSVAEvent IOMMUSVAEvent;
> +
> +struct IOMMUSVAEventData {
> +IOMMUSVAEvent event;
> +uint64_t length;
> +void *data;
> +};
> +typedef struct IOMMUSVAEventData IOMMUSVAEventData;
> +
> +typedef struct IOMMUSVANotifier IOMMUSVANotifier;
> +
> +typedef void (*IOMMUSVANotifyFn)(IOMMUSVANotifier *notifier,
> + IOMMUSVAEventData *event_data);
> +
> +typedef struct IOMMUSVATLBEntry IOMMUSVATLBEntry;
> +
> +/* See address_space_translate: bit 0 is read, bit 1 is write.  */
> +typedef enum {
> +IOMMU_SVA_NONE = 0,
> +IOMMU_SVA_RO   = 1,
> +IOMMU_SVA_WO   = 2,
> +IOMMU_SVA_RW   = 3,
> +} IOMMUSVAAccessFlags;
> +
> +#define IOMMU_SVA_ACCESS_FLAG(r, w) (((r) ? IOMMU_SVA_RO : 0) | \
> + ((w) ? IOMMU_SVA_WO : 0))
> +
> +struct IOMMUSVATLBEntry {
> +AddressSpace*target_as;
> +hwaddr   va;
> +hwaddr   translated_addr;
> +hwaddr   addr_mask;  /* 0xfff = 4k translation */
> +IOMMUSVAAccessFlags perm;
> +};
> +
> +typedef struct IOMMUSVAContextOps IOMMUSVAContextOps;
> +struct IOMMUSVAContextOps {
> +/* Return a TLB entry that contains a given address. */
> +IOMMUSVATLBEntry (*translate)(IOMMUSVAContext *sva_ctx,
> +  hwaddr addr, bool is_write);
> +};

A lot of the above seems to just duplicate stuff from IOMMU MRs and
it's not clear why we need both.

> +struct IOMMUSVANotifier {
> +IOMMUSVANotifyFn sva_notify;
> +/*
> + * What events we are listening to. Let's allow multiple event
> + * registrations from beginning.
> + */
> +IOMMUSVAEvent event;
> +QLIST_ENTRY(IOMMUSVANotifier) node;
> +};
> +
> +/*
> + * This stands for an IOMMU unit. Any translation device should have
> + * this struct inside its own structure to make sure it can leverage
> + * common IOMMU functionalities.
> + */
> +struct IOMMUSVAContext {
> +uint32_t pasid;
> +QLIST_HEAD(, IOMMUSVANotifier) sva_notifiers;
> +const IOMMUSVAContextOps *sva_ctx_ops;
> +};

I think the problem is here.  The SVAContext represents a *single*
PASID, and once you have a single PASID the resulting object *is*
functionally equivalent to an AddressSpace (though effectively
required to have nothing but a single IOMMUMR within it).

It also seems to me unlikely that different PASIDs for the same device
/ IOMMU domain will have truly different sva_ctx_ops.

It really seems to me the object you actually want is a level up from
that, representing the whole cluster of address spaces indexed by
PASID.  They would have the same operations for all PASIDs in the
cluster, but those would take the pasid 

Re: [Qemu-devel] [PATCH v3 2/3] virtio-balloon: VIRTIO_BALLOON_F_FREE_PAGE_HINT

2018-03-04 Thread Wei Wang

On 03/03/2018 02:37 AM, Michael S. Tsirkin wrote:

On Fri, Mar 02, 2018 at 04:47:29PM +0800, Wei Wang wrote:

diff --git a/include/sysemu/balloon.h b/include/sysemu/balloon.h
index af49e19..16a2aae 100644
--- a/include/sysemu/balloon.h
+++ b/include/sysemu/balloon.h

...


+typedef void (QEMUBalloonFreePageStart)(void *opaque);
+typedef void (QEMUBalloonFreePageStop)(void *opaque);

So I think the rule is that no bitmap sync must happen
between these two, otherwise a hint might arrive and
override the sync output.

Should be documented I think.



Yes, agree. How about adding the following new balloon API explanation 
to this patch's commit:


- balloon_free_page_start: Callers call this API to obtain guest free
  page hints, and clear the related bits from the migration dirty 
bitmap.

  The whole process is implemented in a new thread independent of the
  migration thread. Free page hints imply the part of guest memory is
  likely to be free without a guarantee. That is, the reported free 
pages

  may not be free any more when QEMU receives them, so callers are
  responsible for detecting those pages that are not free pages 
after the

  bits are cleared from the dirty bitmap. To ensure the above, this API
  should be used when the migration dirty logging mechanism (e.g.
  guest memory write-protection) has started.

- balloon_free_page_stop: Callers call this API to stop the guest from
  reporting free page hints. Bits from the dirty bitmap are safe to
  be cleared on condition that the dirty logging mechanism is recording
  pages that the guest has written to. To avoid the case that clearing
  bits of free page hints overrides the dirty bits offered by the dirty
  logging mechanism, this API is suggested to be called before QEMU
  synchronizes the dirty logging bitmap.

- balloon_free_page_support: This API is called to check whether the
  balloon device supports the guest free page reporting feature. The
  balloon_free_page_start and balloon_free_page_stop APIs should be 
used

  only when this API returns true.


Best,
Wei



[Qemu-devel] [PULL 8/9] hw/net: Remove unnecessary header includes

2018-03-04 Thread Jason Wang
From: Thomas Huth 

Headers like "hw/loader.h" and "qemu/sockets.h" are not needed in
the hw/net/*.c files. And Some other headers are included via other
headers already, so we can drop them, too.

Signed-off-by: Thomas Huth 
Signed-off-by: Jason Wang 
---
 hw/net/e1000.c | 1 -
 hw/net/lance.c | 3 ---
 hw/net/ne2000.c| 2 --
 hw/net/pcnet-pci.c | 1 -
 hw/net/pcnet.c | 1 -
 hw/net/rtl8139.c   | 2 --
 hw/net/xgmac.c | 1 -
 7 files changed, 11 deletions(-)

diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index 804ec08..c7f1695 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -30,7 +30,6 @@
 #include "hw/pci/pci.h"
 #include "net/net.h"
 #include "net/checksum.h"
-#include "hw/loader.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/dma.h"
 #include "qemu/iov.h"
diff --git a/hw/net/lance.c b/hw/net/lance.c
index 0028bc5..a08d5ac 100644
--- a/hw/net/lance.c
+++ b/hw/net/lance.c
@@ -36,10 +36,7 @@
  */
 
 #include "qemu/osdep.h"
-#include "hw/sysbus.h"
-#include "net/net.h"
 #include "qemu/timer.h"
-#include "qemu/sockets.h"
 #include "hw/sparc/sparc32_dma.h"
 #include "hw/net/lance.h"
 #include "trace.h"
diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c
index 687ef84..3a9fc89 100644
--- a/hw/net/ne2000.c
+++ b/hw/net/ne2000.c
@@ -23,10 +23,8 @@
  */
 #include "qemu/osdep.h"
 #include "hw/pci/pci.h"
-#include "net/net.h"
 #include "net/eth.h"
 #include "ne2000.h"
-#include "hw/loader.h"
 #include "sysemu/sysemu.h"
 
 /* debug NE2000 card */
diff --git a/hw/net/pcnet-pci.c b/hw/net/pcnet-pci.c
index 0ae5ca4..70dc8b3 100644
--- a/hw/net/pcnet-pci.c
+++ b/hw/net/pcnet-pci.c
@@ -30,7 +30,6 @@
 #include "qemu/osdep.h"
 #include "hw/pci/pci.h"
 #include "net/net.h"
-#include "hw/loader.h"
 #include "qemu/timer.h"
 #include "sysemu/dma.h"
 #include "sysemu/sysemu.h"
diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c
index 606b05c..0c44554 100644
--- a/hw/net/pcnet.c
+++ b/hw/net/pcnet.c
@@ -40,7 +40,6 @@
 #include "net/net.h"
 #include "net/eth.h"
 #include "qemu/timer.h"
-#include "qemu/sockets.h"
 #include "sysemu/sysemu.h"
 #include "trace.h"
 
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
index 1cc95b8..46daa16 100644
--- a/hw/net/rtl8139.c
+++ b/hw/net/rtl8139.c
@@ -58,9 +58,7 @@
 #include "qemu/timer.h"
 #include "net/net.h"
 #include "net/eth.h"
-#include "hw/loader.h"
 #include "sysemu/sysemu.h"
-#include "qemu/iov.h"
 
 /* debug RTL8139 card */
 //#define DEBUG_RTL8139 1
diff --git a/hw/net/xgmac.c b/hw/net/xgmac.c
index 0843bf1..fa00156 100644
--- a/hw/net/xgmac.c
+++ b/hw/net/xgmac.c
@@ -28,7 +28,6 @@
 #include "hw/sysbus.h"
 #include "qemu/log.h"
 #include "net/net.h"
-#include "net/checksum.h"
 
 #ifdef DEBUG_XGMAC
 #define DEBUGF_BRK(message, args...) do { \
-- 
2.7.4




[Qemu-devel] [PULL 9/9] tap: setting error appropriately when calling net_init_tap_one()

2018-03-04 Thread Jason Wang
From: Jay Zhou 

If netdev_add tap,id=net0,...,vhost=on failed in net_init_tap_one(),
the followed up device_add virtio-net-pci,netdev=net0 will fail
too, prints:

   TUNSETOFFLOAD ioctl() failed: Bad file descriptor TUNSETOFFLOAD
   ioctl() failed: Bad file descriptor

The reason is that the fd of tap is closed when error occured after
calling net_init_tap_one().

The fd should be closed when calling net_init_tap_one failed:
   - if tap_set_sndbuf() failed
   - if tap_set_sndbuf() succeeded but vhost failed to open or
 initialize with vhostforce flag on
   - with wrong vhost command line parameter
The fd should not be closed just because vhost failed to open or
initialize but without vhostforce flag. So the followed up
device_add can fall back to userspace virtio successfully.

Suggested-by: Michael S. Tsirkin 
Suggested-by: Igor Mammedov 
Suggested-by: Jason Wang 
Signed-off-by: Jay Zhou 
Signed-off-by: Jason Wang 
---
 include/net/vhost_net.h |  3 +++
 net/tap.c   | 22 +-
 2 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h
index afc1499..77e4739 100644
--- a/include/net/vhost_net.h
+++ b/include/net/vhost_net.h
@@ -4,6 +4,9 @@
 #include "net/net.h"
 #include "hw/virtio/vhost-backend.h"
 
+#define VHOST_NET_INIT_FAILED \
+"vhost-net requested but could not be initialized"
+
 struct vhost_net;
 typedef struct vhost_net VHostNetState;
 
diff --git a/net/tap.c b/net/tap.c
index 979e622..2b3a36f 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -686,14 +686,23 @@ static void net_init_tap_one(const NetdevTapOptions *tap, 
NetClientState *peer,
 if (vhostfdname) {
 vhostfd = monitor_fd_param(cur_mon, vhostfdname, );
 if (vhostfd == -1) {
-error_propagate(errp, err);
+if (tap->has_vhostforce && tap->vhostforce) {
+error_propagate(errp, err);
+} else {
+warn_report_err(err);
+}
 return;
 }
 } else {
 vhostfd = open("/dev/vhost-net", O_RDWR);
 if (vhostfd < 0) {
-error_setg_errno(errp, errno,
- "tap: open vhost char device failed");
+if (tap->has_vhostforce && tap->vhostforce) {
+error_setg_errno(errp, errno,
+ "tap: open vhost char device failed");
+} else {
+warn_report("tap: open vhost char device failed: %s",
+strerror(errno));
+}
 return;
 }
 fcntl(vhostfd, F_SETFL, O_NONBLOCK);
@@ -702,8 +711,11 @@ static void net_init_tap_one(const NetdevTapOptions *tap, 
NetClientState *peer,
 
 s->vhost_net = vhost_net_init();
 if (!s->vhost_net) {
-error_setg(errp,
-   "vhost-net requested but could not be initialized");
+if (tap->has_vhostforce && tap->vhostforce) {
+error_setg(errp, VHOST_NET_INIT_FAILED);
+} else {
+warn_report(VHOST_NET_INIT_FAILED);
+}
 return;
 }
 } else if (vhostfdname) {
-- 
2.7.4




[Qemu-devel] [PULL 6/9] net: Remove the deprecated 'host_net_add' and 'host_net_remove' HMP commands

2018-03-04 Thread Jason Wang
From: Thomas Huth 

They are deprecated since QEMU v2.10, and so far nobody complained that
these commands are still necessary for any reason - and since you can use
'netdev_add' and 'netdev_remove' instead, there also should not be any
real reason. Since they are also standing in the way for the upcoming
'vlan' clean-up, it's now time to remove them.

Reviewed-by: Paolo Bonzini 
Signed-off-by: Thomas Huth 
Signed-off-by: Jason Wang 
---
 hmp-commands.hx  | 30 --
 hmp.h|  3 --
 monitor.c| 61 
 net/net.c| 94 
 qemu-doc.texi| 10 --
 tests/test-hmp.c |  2 --
 6 files changed, 200 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index d26eb41..964eb51 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1291,36 +1291,6 @@ Inject PCIe AER error
 ETEXI
 
 {
-.name   = "host_net_add",
-.args_type  = "device:s,opts:s?",
-.params = "tap|user|socket|vde|netmap|bridge|vhost-user|dump 
[options]",
-.help   = "add host VLAN client (deprecated, use netdev_add 
instead)",
-.cmd= hmp_host_net_add,
-.command_completion = host_net_add_completion,
-},
-
-STEXI
-@item host_net_add
-@findex host_net_add
-Add host VLAN client. Deprecated, please use @code{netdev_add} instead.
-ETEXI
-
-{
-.name   = "host_net_remove",
-.args_type  = "vlan_id:i,device:s",
-.params = "vlan_id name",
-.help   = "remove host VLAN client (deprecated, use netdev_del 
instead)",
-.cmd= hmp_host_net_remove,
-.command_completion = host_net_remove_completion,
-},
-
-STEXI
-@item host_net_remove
-@findex host_net_remove
-Remove host VLAN client. Deprecated, please use @code{netdev_del} instead.
-ETEXI
-
-{
 .name   = "netdev_add",
 .args_type  = "netdev:O",
 .params = 
"[user|tap|socket|vde|bridge|hubport|netmap|vhost-user],id=str[,prop=value][,...]",
diff --git a/hmp.h b/hmp.h
index 1143db4..b897338 100644
--- a/hmp.h
+++ b/hmp.h
@@ -132,9 +132,6 @@ void migrate_set_capability_completion(ReadLineState *rs, 
int nb_args,
const char *str);
 void migrate_set_parameter_completion(ReadLineState *rs, int nb_args,
   const char *str);
-void host_net_add_completion(ReadLineState *rs, int nb_args, const char *str);
-void host_net_remove_completion(ReadLineState *rs, int nb_args,
-const char *str);
 void delvm_completion(ReadLineState *rs, int nb_args, const char *str);
 void loadvm_completion(ReadLineState *rs, int nb_args, const char *str);
 void hmp_rocker(Monitor *mon, const QDict *qdict);
diff --git a/monitor.c b/monitor.c
index 308a3d9..70eb1b9 100644
--- a/monitor.c
+++ b/monitor.c
@@ -3581,67 +3581,6 @@ void migrate_set_parameter_completion(ReadLineState *rs, 
int nb_args,
 }
 }
 
-void host_net_add_completion(ReadLineState *rs, int nb_args, const char *str)
-{
-int i;
-size_t len;
-if (nb_args != 2) {
-return;
-}
-len = strlen(str);
-readline_set_completion_index(rs, len);
-for (i = 0; host_net_devices[i]; i++) {
-if (!strncmp(host_net_devices[i], str, len)) {
-readline_add_completion(rs, host_net_devices[i]);
-}
-}
-}
-
-void host_net_remove_completion(ReadLineState *rs, int nb_args, const char 
*str)
-{
-NetClientState *ncs[MAX_QUEUE_NUM];
-int count, i, len;
-
-len = strlen(str);
-readline_set_completion_index(rs, len);
-if (nb_args == 2) {
-count = qemu_find_net_clients_except(NULL, ncs,
- NET_CLIENT_DRIVER_NONE,
- MAX_QUEUE_NUM);
-for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) {
-int id;
-char name[16];
-
-if (net_hub_id_for_client(ncs[i], )) {
-continue;
-}
-snprintf(name, sizeof(name), "%d", id);
-if (!strncmp(str, name, len)) {
-readline_add_completion(rs, name);
-}
-}
-return;
-} else if (nb_args == 3) {
-count = qemu_find_net_clients_except(NULL, ncs,
- NET_CLIENT_DRIVER_NIC,
- MAX_QUEUE_NUM);
-for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) {
-int id;
-const char *name;
-
-if (ncs[i]->info->type == NET_CLIENT_DRIVER_HUBPORT ||
-net_hub_id_for_client(ncs[i], )) {
-continue;
-}
-name = ncs[i]->name;
-if (!strncmp(str, name, len)) {
-readline_add_completion(rs, name);
-   

[Qemu-devel] [PULL 7/9] net: Add a new convenience option "--nic" to configure default/on-board NICs

2018-03-04 Thread Jason Wang
From: Thomas Huth 

The legacy "-net" option can be quite confusing for the users since most
people do not expect to get a "vlan" hub between their emulated guest
hardware and the host backend. But so far, we are also not able to get
rid of "-net" completely, since it is the only way to configure on-board
NICs that can not be instantiated via "-device" yet. It's also a little
bit shorter to type "-net nic -net tap" instead of "-device xyz,netdev=n1
-netdev tap,id=n1".

So what we need is a new convenience option that is shorter to type than
the full -device + -netdev stuff, and which can be used to configure the
on-board NICs that can not be handled via -device yet. Thus this patch now
provides such a new option "--nic": It adds an entry in the nd_table to
configure a on-board / default NIC, creates a host backend and connects
the two directly, without a confusing "vlan" hub inbetween.

Reviewed-by: Paolo Bonzini 
Signed-off-by: Thomas Huth 
Signed-off-by: Jason Wang 
---
 include/sysemu/sysemu.h |  1 +
 net/net.c   | 78 +
 qemu-options.hx | 40 +
 vl.c|  7 +
 4 files changed, 120 insertions(+), 6 deletions(-)

diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 77bb3da..66f0761 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -197,6 +197,7 @@ extern QemuOptsList bdrv_runtime_opts;
 extern QemuOptsList qemu_chardev_opts;
 extern QemuOptsList qemu_device_opts;
 extern QemuOptsList qemu_netdev_opts;
+extern QemuOptsList qemu_nic_opts;
 extern QemuOptsList qemu_net_opts;
 extern QemuOptsList qemu_global_opts;
 extern QemuOptsList qemu_mon_opts;
diff --git a/net/net.c b/net/net.c
index 2d05808..0bab269 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1462,6 +1462,67 @@ static int net_init_netdev(void *dummy, QemuOpts *opts, 
Error **errp)
 return net_client_init(opts, true, errp);
 }
 
+/* For the convenience "--nic" parameter */
+static int net_param_nic(void *dummy, QemuOpts *opts, Error **errp)
+{
+char *mac, *nd_id;
+int idx, ret;
+NICInfo *ni;
+const char *type;
+
+type = qemu_opt_get(opts, "type");
+if (type && g_str_equal(type, "none")) {
+return 0;/* Nothing to do, default_net is cleared in vl.c */
+}
+
+idx = nic_get_free_idx();
+if (idx == -1 || nb_nics >= MAX_NICS) {
+error_setg(errp, "no more on-board/default NIC slots available");
+return -1;
+}
+
+if (!type) {
+qemu_opt_set(opts, "type", "user", _abort);
+}
+
+ni = _table[idx];
+memset(ni, 0, sizeof(*ni));
+ni->model = qemu_opt_get_del(opts, "model");
+
+/* Create an ID if the user did not specify one */
+nd_id = g_strdup(qemu_opts_id(opts));
+if (!nd_id) {
+nd_id = g_strdup_printf("__org.qemu.nic%i\n", idx);
+qemu_opts_set_id(opts, nd_id);
+}
+
+/* Handle MAC address */
+mac = qemu_opt_get_del(opts, "mac");
+if (mac) {
+ret = net_parse_macaddr(ni->macaddr.a, mac);
+g_free(mac);
+if (ret) {
+error_setg(errp, "invalid syntax for ethernet address");
+return -1;
+}
+if (is_multicast_ether_addr(ni->macaddr.a)) {
+error_setg(errp, "NIC cannot have multicast MAC address");
+return -1;
+}
+}
+qemu_macaddr_default_if_unset(>macaddr);
+
+ret = net_client_init(opts, true, errp);
+if (ret == 0) {
+ni->netdev = qemu_find_netdev(nd_id);
+ni->used = true;
+nb_nics++;
+}
+
+g_free(nd_id);
+return ret;
+}
+
 int net_init_clients(Error **errp)
 {
 net_change_state_entry =
@@ -1474,6 +1535,10 @@ int net_init_clients(Error **errp)
 return -1;
 }
 
+if (qemu_opts_foreach(qemu_find_opts("nic"), net_param_nic, NULL, errp)) {
+return -1;
+}
+
 if (qemu_opts_foreach(qemu_find_opts("net"), net_init_client, NULL, errp)) 
{
 return -1;
 }
@@ -1549,6 +1614,19 @@ QemuOptsList qemu_netdev_opts = {
 },
 };
 
+QemuOptsList qemu_nic_opts = {
+.name = "nic",
+.implied_opt_name = "type",
+.head = QTAILQ_HEAD_INITIALIZER(qemu_nic_opts.head),
+.desc = {
+/*
+ * no elements => accept any params
+ * validation will happen later
+ */
+{ /* end of list */ }
+},
+};
+
 QemuOptsList qemu_net_opts = {
 .name = "net",
 .implied_opt_name = "type",
diff --git a/qemu-options.hx b/qemu-options.hx
index 9ce0cfe..2a22a62 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2004,13 +2004,34 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
 #endif
 "-netdev hubport,id=str,hubid=n[,netdev=nd]\n"
 "configure a hub port on QEMU VLAN 'n'\n", QEMU_ARCH_ALL)
+DEF("nic", HAS_ARG, QEMU_OPTION_nic,
+"--nic [tap|bridge|"
+#ifdef CONFIG_SLIRP
+"user|"

[Qemu-devel] [PULL 5/9] net: Remove the deprecated way of dumping network packets

2018-03-04 Thread Jason Wang
From: Thomas Huth 

"-net dump" has been marked as deprecated since QEMU v2.10, since it
only works with the deprecated 'vlan' parameter (or hubs). Network
dumping should be done with "-object filter-dump" nowadays instead.
Since nobody complained so far about the deprecation message, let's
finally get rid of "-net dump" now.

Signed-off-by: Thomas Huth 
Signed-off-by: Jason Wang 
---
 net/dump.c  | 102 ++--
 net/net.c   |   9 +
 qapi/net.json   |  29 
 qemu-doc.texi   |   6 
 qemu-options.hx |   8 -
 5 files changed, 9 insertions(+), 145 deletions(-)

diff --git a/net/dump.c b/net/dump.c
index 15df9a4..f16c354 100644
--- a/net/dump.c
+++ b/net/dump.c
@@ -109,7 +109,7 @@ static int net_dump_state_init(DumpState *s, const char 
*filename,
 
 fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, 0644);
 if (fd < 0) {
-error_setg_errno(errp, errno, "-net dump: can't open %s", filename);
+error_setg_errno(errp, errno, "net dump: can't open %s", filename);
 return -1;
 }
 
@@ -122,7 +122,7 @@ static int net_dump_state_init(DumpState *s, const char 
*filename,
 hdr.linktype = 1;
 
 if (write(fd, , sizeof(hdr)) < sizeof(hdr)) {
-error_setg_errno(errp, errno, "-net dump write error");
+error_setg_errno(errp, errno, "net dump write error");
 close(fd);
 return -1;
 }
@@ -136,104 +136,6 @@ static int net_dump_state_init(DumpState *s, const char 
*filename,
 return 0;
 }
 
-/* Dumping via VLAN netclient */
-
-struct DumpNetClient {
-NetClientState nc;
-DumpState ds;
-};
-typedef struct DumpNetClient DumpNetClient;
-
-static ssize_t dumpclient_receive(NetClientState *nc, const uint8_t *buf,
-  size_t size)
-{
-DumpNetClient *dc = DO_UPCAST(DumpNetClient, nc, nc);
-struct iovec iov = {
-.iov_base = (void *)buf,
-.iov_len = size
-};
-
-return dump_receive_iov(>ds, , 1);
-}
-
-static ssize_t dumpclient_receive_iov(NetClientState *nc,
-  const struct iovec *iov, int cnt)
-{
-DumpNetClient *dc = DO_UPCAST(DumpNetClient, nc, nc);
-
-return dump_receive_iov(>ds, iov, cnt);
-}
-
-static void dumpclient_cleanup(NetClientState *nc)
-{
-DumpNetClient *dc = DO_UPCAST(DumpNetClient, nc, nc);
-
-dump_cleanup(>ds);
-}
-
-static NetClientInfo net_dump_info = {
-.type = NET_CLIENT_DRIVER_DUMP,
-.size = sizeof(DumpNetClient),
-.receive = dumpclient_receive,
-.receive_iov = dumpclient_receive_iov,
-.cleanup = dumpclient_cleanup,
-};
-
-int net_init_dump(const Netdev *netdev, const char *name,
-  NetClientState *peer, Error **errp)
-{
-int len, rc;
-const char *file;
-char def_file[128];
-const NetdevDumpOptions *dump;
-NetClientState *nc;
-DumpNetClient *dnc;
-
-assert(netdev->type == NET_CLIENT_DRIVER_DUMP);
-dump = >u.dump;
-
-assert(peer);
-
-error_report("'-net dump' is deprecated. "
- "Please use '-object filter-dump' instead.");
-
-if (dump->has_file) {
-file = dump->file;
-} else {
-int id;
-int ret;
-
-ret = net_hub_id_for_client(peer, );
-assert(ret == 0); /* peer must be on a hub */
-
-snprintf(def_file, sizeof(def_file), "qemu-vlan%d.pcap", id);
-file = def_file;
-}
-
-if (dump->has_len) {
-if (dump->len > INT_MAX) {
-error_setg(errp, "invalid length: %"PRIu64, dump->len);
-return -1;
-}
-len = dump->len;
-} else {
-len = 65536;
-}
-
-nc = qemu_new_net_client(_dump_info, peer, "dump", name);
-snprintf(nc->info_str, sizeof(nc->info_str),
- "dump to %s (len=%d)", file, len);
-
-dnc = DO_UPCAST(DumpNetClient, nc, nc);
-rc = net_dump_state_init(>ds, file, len, errp);
-if (rc) {
-qemu_del_net_client(nc);
-}
-return rc;
-}
-
-/* Dumping via filter */
-
 #define TYPE_FILTER_DUMP "filter-dump"
 
 #define FILTER_DUMP(obj) \
diff --git a/net/net.c b/net/net.c
index dd80f1b..cbd553d 100644
--- a/net/net.c
+++ b/net/net.c
@@ -63,7 +63,6 @@ static QTAILQ_HEAD(, NetClientState) net_clients;
 const char *host_net_devices[] = {
 "tap",
 "socket",
-"dump",
 #ifdef CONFIG_NET_BRIDGE
 "bridge",
 #endif
@@ -967,7 +966,6 @@ static int (* const 
net_client_init_fun[NET_CLIENT_DRIVER__MAX])(
 #ifdef CONFIG_NETMAP
 [NET_CLIENT_DRIVER_NETMAP]= net_init_netmap,
 #endif
-[NET_CLIENT_DRIVER_DUMP]  = net_init_dump,
 #ifdef CONFIG_NET_BRIDGE
 [NET_CLIENT_DRIVER_BRIDGE]= net_init_bridge,
 #endif
@@ -993,8 +991,7 @@ static int net_client_init1(const void *object, bool 
is_netdev, Error **errp)
 netdev = object;
 name = netdev->id;
 
-if (netdev->type == 

[Qemu-devel] [PULL 4/9] net: Make net_client_init() static

2018-03-04 Thread Jason Wang
From: Thomas Huth 

The function is only used within net.c, so there's no need that
this is a global function.

While we're at it, also remove the unused prototype compute_mcast_idx()
(the function has been removed in commit d9caeb09b107e91122d10ba4a08a).

Reviewed-by: Paolo Bonzini 
Signed-off-by: Thomas Huth 
Signed-off-by: Jason Wang 
---
 include/net/net.h | 2 --
 net/net.c | 2 +-
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/include/net/net.h b/include/net/net.h
index bdd4d9f..cd1708c 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -204,7 +204,6 @@ extern const char *host_net_devices[];
 extern const char *legacy_tftp_prefix;
 extern const char *legacy_bootp_filename;
 
-int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp);
 int net_client_parse(QemuOptsList *opts_list, const char *str);
 int net_init_clients(Error **errp);
 void net_check_clients(void);
@@ -228,7 +227,6 @@ void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd);
 #define POLYNOMIAL_LE 0xedb88320
 uint32_t net_crc32(const uint8_t *p, int len);
 uint32_t net_crc32_le(const uint8_t *p, int len);
-unsigned compute_mcast_idx(const uint8_t *ep);
 
 #define vmstate_offset_macaddr(_state, _field)   \
 vmstate_offset_array(_state, _field.a, uint8_t,\
diff --git a/net/net.c b/net/net.c
index cf07e15..dd80f1b 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1119,7 +1119,7 @@ static void show_netdevs(void)
 }
 }
 
-int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp)
+static int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp)
 {
 void *object = NULL;
 Error *err = NULL;
-- 
2.7.4




[Qemu-devel] [PULL 2/9] net: List available netdevs with "-netdev help"

2018-03-04 Thread Jason Wang
From: Thomas Huth 

Other options like "-chardev" or "-device" feature a nice help text
with the available devices when being called with "help" or "?".
Since it is quite useful, especially if you want to see which network
backends have been compiled into the QEMU binary, let's provide such
a help text for "-netdev", too.

Reviewed-by: Paolo Bonzini 
Reviewed-by: Eric Blake 
Signed-off-by: Thomas Huth 
Signed-off-by: Jason Wang 
---
 net/net.c | 37 -
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/net/net.c b/net/net.c
index e213a61..cf07e15 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1086,6 +1086,38 @@ static int net_client_init1(const void *object, bool 
is_netdev, Error **errp)
 return 0;
 }
 
+static void show_netdevs(void)
+{
+int idx;
+const char *available_netdevs[] = {
+"socket",
+"hubport",
+"tap",
+#ifdef CONFIG_SLIRP
+"user",
+#endif
+#ifdef CONFIG_L2TPV3
+"l2tpv3",
+#endif
+#ifdef CONFIG_VDE
+"vde",
+#endif
+#ifdef CONFIG_NET_BRIDGE
+"bridge",
+#endif
+#ifdef CONFIG_NETMAP
+"netmap",
+#endif
+#ifdef CONFIG_POSIX
+"vhost-user",
+#endif
+};
+
+printf("Available netdev backend types:\n");
+for (idx = 0; idx < ARRAY_SIZE(available_netdevs); idx++) {
+puts(available_netdevs[idx]);
+}
+}
 
 int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp)
 {
@@ -1094,7 +1126,10 @@ int net_client_init(QemuOpts *opts, bool is_netdev, 
Error **errp)
 int ret = -1;
 Visitor *v = opts_visitor_new(opts);
 
-{
+if (is_netdev && is_help_option(qemu_opt_get(opts, "type"))) {
+show_netdevs();
+exit(0);
+} else {
 /* Parse convenience option format ip6-net=fec0::0[/64] */
 const char *ip6_net = qemu_opt_get(opts, "ipv6-net");
 
-- 
2.7.4




[Qemu-devel] [PULL 3/9] net: Only show vhost-user in the help text if CONFIG_POSIX is defined

2018-03-04 Thread Jason Wang
From: Thomas Huth 

According to net/Makefile.objs we only link in the vhost-user code
if CONFIG_POSIX has been set. So the help screen should also only
show this information if CONFIG_POSIX has been defined.

Reviewed-by: Paolo Bonzini 
Signed-off-by: Thomas Huth 
Signed-off-by: Jason Wang 
---
 qemu-options.hx | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/qemu-options.hx b/qemu-options.hx
index fea949d..5781599 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1998,8 +1998,10 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
 "VALE port (created on the fly) called 'name' ('nmname' is 
name of the \n"
 "netmap device, defaults to '/dev/netmap')\n"
 #endif
+#ifdef CONFIG_POSIX
 "-netdev vhost-user,id=str,chardev=dev[,vhostforce=on|off]\n"
 "configure a vhost-user network, backed by a chardev 
'dev'\n"
+#endif
 "-netdev hubport,id=str,hubid=n[,netdev=nd]\n"
 "configure a hub port on QEMU VLAN 'n'\n", QEMU_ARCH_ALL)
 DEF("net", HAS_ARG, QEMU_OPTION_net,
-- 
2.7.4




[Qemu-devel] [PULL 1/9] net: Move error reporting from net_init_client/netdev to the calling site

2018-03-04 Thread Jason Wang
From: Thomas Huth 

It looks strange that net_init_client() and net_init_netdev() both
take an "Error **errp" parameter, but then do the error reporting
with "error_report_err(local_err)" on their own. Let's move the
error reporting to the calling site instead to simplify this code
a little bit.

Reviewed-by: Eric Blake 
Reviewed-by: Paolo Bonzini 
Signed-off-by: Thomas Huth 
Signed-off-by: Jason Wang 
---
 include/net/net.h |  2 +-
 net/net.c | 29 +
 vl.c  |  3 ++-
 3 files changed, 8 insertions(+), 26 deletions(-)

diff --git a/include/net/net.h b/include/net/net.h
index 3fc48e4..bdd4d9f 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -206,7 +206,7 @@ extern const char *legacy_bootp_filename;
 
 int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp);
 int net_client_parse(QemuOptsList *opts_list, const char *str);
-int net_init_clients(void);
+int net_init_clients(Error **errp);
 void net_check_clients(void);
 void net_cleanup(void);
 void hmp_host_net_add(Monitor *mon, const QDict *qdict);
diff --git a/net/net.c b/net/net.c
index 7d42925..e213a61 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1520,46 +1520,27 @@ void net_check_clients(void)
 
 static int net_init_client(void *dummy, QemuOpts *opts, Error **errp)
 {
-Error *local_err = NULL;
-
-net_client_init(opts, false, _err);
-if (local_err) {
-error_report_err(local_err);
-return -1;
-}
-
-return 0;
+return net_client_init(opts, false, errp);
 }
 
 static int net_init_netdev(void *dummy, QemuOpts *opts, Error **errp)
 {
-Error *local_err = NULL;
-int ret;
-
-ret = net_client_init(opts, true, _err);
-if (local_err) {
-error_report_err(local_err);
-return -1;
-}
-
-return ret;
+return net_client_init(opts, true, errp);
 }
 
-int net_init_clients(void)
+int net_init_clients(Error **errp)
 {
-QemuOptsList *net = qemu_find_opts("net");
-
 net_change_state_entry =
 qemu_add_vm_change_state_handler(net_vm_change_state_handler, NULL);
 
 QTAILQ_INIT(_clients);
 
 if (qemu_opts_foreach(qemu_find_opts("netdev"),
-  net_init_netdev, NULL, NULL)) {
+  net_init_netdev, NULL, errp)) {
 return -1;
 }
 
-if (qemu_opts_foreach(net, net_init_client, NULL, NULL)) {
+if (qemu_opts_foreach(qemu_find_opts("net"), net_init_client, NULL, errp)) 
{
 return -1;
 }
 
diff --git a/vl.c b/vl.c
index a33ac00..1931621 100644
--- a/vl.c
+++ b/vl.c
@@ -4489,7 +4489,8 @@ int main(int argc, char **argv, char **envp)
 
 colo_info_init();
 
-if (net_init_clients() < 0) {
+if (net_init_clients() < 0) {
+error_report_err(err);
 exit(1);
 }
 
-- 
2.7.4




[Qemu-devel] [PULL 0/9] Net patches

2018-03-04 Thread Jason Wang
The following changes since commit 136c67e07869227b21b3f627316e03679ce7b738:

  Merge remote-tracking branch 
'remotes/bkoppelmann/tags/pull-tricore-2018-03-02' into staging (2018-03-02 
16:56:20 +)

are available in the git repository at:

  https://github.com/jasowang/qemu.git tags/net-pull-request

for you to fetch changes up to 46d4d36d0bf2b24b205f2f604f0905db80264eef:

  tap: setting error appropriately when calling net_init_tap_one() (2018-03-05 
10:30:16 +0800)




Jay Zhou (1):
  tap: setting error appropriately when calling net_init_tap_one()

Thomas Huth (8):
  net: Move error reporting from net_init_client/netdev to the calling site
  net: List available netdevs with "-netdev help"
  net: Only show vhost-user in the help text if CONFIG_POSIX is defined
  net: Make net_client_init() static
  net: Remove the deprecated way of dumping network packets
  net: Remove the deprecated 'host_net_add' and 'host_net_remove' HMP 
commands
  net: Add a new convenience option "--nic" to configure default/on-board 
NICs
  hw/net: Remove unnecessary header includes

 hmp-commands.hx |  30 --
 hmp.h   |   3 -
 hw/net/e1000.c  |   1 -
 hw/net/lance.c  |   3 -
 hw/net/ne2000.c |   2 -
 hw/net/pcnet-pci.c  |   1 -
 hw/net/pcnet.c  |   1 -
 hw/net/rtl8139.c|   2 -
 hw/net/xgmac.c  |   1 -
 include/net/net.h   |   4 +-
 include/net/vhost_net.h |   3 +
 include/sysemu/sysemu.h |   1 +
 monitor.c   |  61 
 net/dump.c  | 102 +
 net/net.c   | 239 +++-
 net/tap.c   |  22 -
 qapi/net.json   |  29 ++
 qemu-doc.texi   |  16 
 qemu-options.hx |  48 +++---
 tests/test-hmp.c|   2 -
 vl.c|  10 +-
 21 files changed, 190 insertions(+), 391 deletions(-)




Re: [Qemu-devel] [PATCH v4] PPC: e500: Fix duplicate kernel load and device tree overlap

2018-03-04 Thread David Gibson
On Fri, Mar 02, 2018 at 12:20:13PM +0100, David Engraf wrote:
> This patch fixes an incorrect behavior when the -kernel argument has been
> specified without -bios. In this case the kernel was loaded twice. At address
> 32M as a raw image and afterwards by load_elf/load_uimage at the
> corresponding load address. In this case the region for the device tree and
> the raw kernel image may overlap.
> 
> The patch fixes the behavior by loading the kernel image once with
> load_elf/load_uimage and skips loading the raw image.
> 
> When here do not use bios_name/size for the kernel and use a more generic
> name called payload_name/size.
> 
> New in v3: dtb must be stored between kernel and initrd because Linux can
>handle the dtb only within the first 64MB. Add a comment to
>clarify the behavior.
> 
> Signed-off-by: David Engraf 
> Reviewed-by: David Gibson 

Applied, thanks.

> ---
>  hw/ppc/e500.c | 116 
> +++---
>  1 file changed, 70 insertions(+), 46 deletions(-)
> 
> diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
> index ef541a00be..43c15d18c4 100644
> --- a/hw/ppc/e500.c
> +++ b/hw/ppc/e500.c
> @@ -792,8 +792,10 @@ void ppce500_init(MachineState *machine, PPCE500Params 
> *params)
>  int initrd_size = 0;
>  hwaddr cur_base = 0;
>  char *filename;
> +const char *payload_name;
> +bool kernel_as_payload;
>  hwaddr bios_entry = 0;
> -target_long bios_size;
> +target_long payload_size;
>  struct boot_info *boot_info;
>  int dt_size;
>  int i;
> @@ -921,11 +923,6 @@ void ppce500_init(MachineState *machine, PPCE500Params 
> *params)
>  /* Register spinning region */
>  sysbus_create_simple("e500-spin", params->spin_base, NULL);
>  
> -if (cur_base < (32 * 1024 * 1024)) {
> -/* u-boot occupies memory up to 32MB, so load blobs above */
> -cur_base = (32 * 1024 * 1024);
> -}
> -
>  if (params->has_mpc8xxx_gpio) {
>  qemu_irq poweroff_irq;
>  
> @@ -960,8 +957,61 @@ void ppce500_init(MachineState *machine, PPCE500Params 
> *params)
>  sysbus_mmio_get_region(s, 0));
>  }
>  
> -/* Load kernel. */
> -if (machine->kernel_filename) {
> +/*
> + * Smart firmware defaults ahead!
> + *
> + * We follow the following table to select which payload we execute.
> + *
> + *  -kernel | -bios | payload
> + * -+---+-
> + * N|   Y   | u-boot
> + * N|   N   | u-boot
> + * Y|   Y   | u-boot
> + * Y|   N   | kernel
> + *
> + * This ensures backwards compatibility with how we used to expose
> + * -kernel to users but allows them to run through u-boot as well.
> + */
> +kernel_as_payload = false;
> +if (bios_name == NULL) {
> +if (machine->kernel_filename) {
> +payload_name = machine->kernel_filename;
> +kernel_as_payload = true;
> +} else {
> +payload_name = "u-boot.e500";
> +}
> +} else {
> +payload_name = bios_name;
> +}
> +
> +filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, payload_name);
> +
> +payload_size = load_elf(filename, NULL, NULL, _entry, , 
> NULL,
> +1, PPC_ELF_MACHINE, 0, 0);
> +if (payload_size < 0) {
> +/*
> + * Hrm. No ELF image? Try a uImage, maybe someone is giving us an
> + * ePAPR compliant kernel
> + */
> +payload_size = load_uimage(filename, _entry, , NULL,
> +   NULL, NULL);
> +if (payload_size < 0) {
> +error_report("qemu: could not load firmware '%s'", filename);
> +exit(1);
> +}
> +}
> +
> +g_free(filename);
> +
> +if (kernel_as_payload) {
> +kernel_base = loadaddr;
> +kernel_size = payload_size;
> +}
> +
> +cur_base = loadaddr + payload_size;
> +
> +/* Load bare kernel only if no bios/u-boot has been provided */
> +if (machine->kernel_filename && !kernel_as_payload) {
>  kernel_base = cur_base;
>  kernel_size = load_image_targphys(machine->kernel_filename,
>cur_base,
> @@ -975,6 +1025,11 @@ void ppce500_init(MachineState *machine, PPCE500Params 
> *params)
>  cur_base += kernel_size;
>  }
>  
> +if (cur_base < (32 * 1024 * 1024)) {
> +/* u-boot occupies memory up to 32MB, so load blobs above */
> +cur_base = (32 * 1024 * 1024);
> +}
> +
>  /* Load initrd. */
>  if (machine->initrd_filename) {
>  initrd_base = (cur_base + INITRD_LOAD_PAD) & ~INITRD_PAD_MASK;
> @@ -991,47 +1046,16 @@ void ppce500_init(MachineState *machine, PPCE500Params 
> *params)
>  }
>  
>  /*
> - * Smart firmware defaults ahead!
> - *
> - * We follow the following table 

Re: [Qemu-devel] [PATCH v2 0/2] Firmware blob and git submodule for Sam460ex

2018-03-04 Thread David Gibson
On Fri, Mar 02, 2018 at 12:50:14PM +0100, BALATON Zoltan wrote:
> This is v2 of the firmware image for the ppc sam460ex machine type in
> case you choose to add it with external git repo first. In case you
> decide not to add it either as external git nor as a mirrored or
> copied to QEMU repo then probably some wiki page should be updated to
> point to a binary image for the machine to be usable but I'm not sure
> how to do that. Please advise which of the above options should be
> followed.

Applied, and moved before the same460ex board to avoid bisection breakage.

> 
> Thank you,
> BALATON Zoltan
> 
> BALATON Zoltan (2):
>   roms: Added git submodule for u-boot-sam460 (firmware for sam460ex)
>   pc-bios: Added u-boot-sam460 firmware binary
> 
>  .gitmodules|   3 +++
>  Makefile   |   2 +-
>  pc-bios/u-boot-sam460-20100605.bin | Bin 0 -> 524288 bytes
>  roms/Makefile  |   7 +++
>  roms/u-boot-sam460ex   |   1 +
>  5 files changed, 12 insertions(+), 1 deletion(-)
>  create mode 100755 pc-bios/u-boot-sam460-20100605.bin
>  create mode 16 roms/u-boot-sam460ex
> 

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH] PPC: e500: Add check for NULL return value from qemu_find_file.

2018-03-04 Thread David Gibson
On Mon, Mar 05, 2018 at 10:51:52AM +1100, David Gibson wrote:
> On Sat, Mar 03, 2018 at 01:02:26PM +, Nia Alarie wrote:
> > This prints a message and exits if the e500 BIOS firmware can't
> > be found, to avoid dereferencing a null pointer.
> > 
> > Signed-off-by: Nia Alarie 
> 
> Applied to ppc-for-2.12, thanks.

Sorry, I take that back.  This has been obsoleted by other changes to
the e500 image load path.
> 
> > ---
> >  hw/ppc/e500.c | 4 
> >  1 file changed, 4 insertions(+)
> > 
> > diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
> > index a40d3ec3e3..6ce03d6ff4 100644
> > --- a/hw/ppc/e500.c
> > +++ b/hw/ppc/e500.c
> > @@ -1005,6 +1005,10 @@ void ppce500_init(MachineState *machine, 
> > PPCE500Params *params)
> >  }
> >  }
> >  filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
> > +if (!filename) {
> > +error_report("Could not find firmware '%s'", bios_name);
> > +exit(1);
> > +}
> >  
> >  bios_size = load_elf(filename, NULL, NULL, _entry, , 
> > NULL,
> >   1, PPC_ELF_MACHINE, 0, 0);
> 



-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH] ppc440_uc: Fix unintialized variable warning with older gcc

2018-03-04 Thread David Gibson
On Fri, Mar 02, 2018 at 10:43:23PM +0100, BALATON Zoltan wrote:
> Signed-off-by: BALATON Zoltan 

Applied, and rebased so we don't get bisection breakage.

> ---
>  hw/ppc/ppc440_uc.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
> index 4e2523a..976ab2b 100644
> --- a/hw/ppc/ppc440_uc.c
> +++ b/hw/ppc/ppc440_uc.c
> @@ -1050,6 +1050,9 @@ static void ppc460ex_pcie_realize(DeviceState *dev, 
> Error **errp)
>  case DCRN_PCIE1_BASE:
>  id = 1;
>  break;
> +default:
> +error_setg(errp, "invalid PCIe DCRN base");
> +return;
>  }
>  snprintf(buf, sizeof(buf), "pcie%d-io", id);
>  memory_region_init(>iomem, OBJECT(s), buf, UINT64_MAX);

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH 4/5] tpm: convert tpm_emulator.c to use trace-events

2018-03-04 Thread Philippe Mathieu-Daudé
On 03/04/2018 06:56 PM, Stefan Berger wrote:
> Signed-off-by: Stefan Berger 

Reviewed-by: Philippe Mathieu-Daudé 

> ---
>  hw/tpm/tpm_emulator.c | 45 +++--
>  hw/tpm/trace-events   | 14 ++
>  2 files changed, 37 insertions(+), 22 deletions(-)
> 
> diff --git a/hw/tpm/tpm_emulator.c b/hw/tpm/tpm_emulator.c
> index b787aee..d0da10a 100644
> --- a/hw/tpm/tpm_emulator.c
> +++ b/hw/tpm/tpm_emulator.c
> @@ -39,14 +39,7 @@
>  #include "qapi/error.h"
>  #include "qapi/clone-visitor.h"
>  #include "chardev/char-fe.h"
> -
> -#define DEBUG_TPM 0
> -
> -#define DPRINTF(fmt, ...) do { \
> -if (DEBUG_TPM) { \
> -fprintf(stderr, "tpm-emulator:"fmt"\n", ## __VA_ARGS__); \
> -} \
> -} while (0)
> +#include "trace.h"
>  
>  #define TYPE_TPM_EMULATOR "tpm-emulator"
>  #define TPM_EMULATOR(obj) \
> @@ -151,13 +144,12 @@ static int tpm_emulator_set_locality(TPMEmulator 
> *tpm_emu, uint8_t locty_number,
>  {
>  ptm_loc loc;
>  
> -DPRINTF("%s : locality: 0x%x", __func__, locty_number);
> -
>  if (tpm_emu->cur_locty_number == locty_number) {
>  return 0;
>  }
>  
> -DPRINTF("setting locality : 0x%x", locty_number);
> +trace_tpm_emulator_set_locality(locty_number);
> +
>  loc.u.req.loc = locty_number;
>  if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_LOCALITY, ,
>   sizeof(loc), sizeof(loc)) < 0) {
> @@ -183,7 +175,7 @@ static void tpm_emulator_handle_request(TPMBackend *tb, 
> TPMBackendCmd *cmd,
>  {
>  TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
>  
> -DPRINTF("processing TPM command");
> +trace_tpm_emulator_handle_request();
>  
>  if (tpm_emulator_set_locality(tpm_emu, cmd->locty, errp) < 0 ||
>  tpm_emulator_unix_tx_bufs(tpm_emu, cmd->in, cmd->in_len,
> @@ -195,7 +187,6 @@ static void tpm_emulator_handle_request(TPMBackend *tb, 
> TPMBackendCmd *cmd,
>  
>  static int tpm_emulator_probe_caps(TPMEmulator *tpm_emu)
>  {
> -DPRINTF("%s", __func__);
>  if (tpm_emulator_ctrlcmd(tpm_emu, CMD_GET_CAPABILITY,
>   _emu->caps, 0, sizeof(tpm_emu->caps)) < 0) {
>  error_report("tpm-emulator: probing failed : %s", strerror(errno));
> @@ -204,7 +195,7 @@ static int tpm_emulator_probe_caps(TPMEmulator *tpm_emu)
>  
>  tpm_emu->caps = be64_to_cpu(tpm_emu->caps);
>  
> -DPRINTF("capabilities : 0x%"PRIx64, tpm_emu->caps);
> +trace_tpm_emulator_probe_caps(tpm_emu->caps);
>  
>  return 0;
>  }
> @@ -293,7 +284,7 @@ static int tpm_emulator_set_buffer_size(TPMBackend *tb,
>  *actual_size = be32_to_cpu(psbs.u.resp.buffersize);
>  }
>  
> -DPRINTF("buffer size: %u, min: %u, max: %u\n",
> +trace_tpm_emulator_set_buffer_size(
>  be32_to_cpu(psbs.u.resp.buffersize),
>  be32_to_cpu(psbs.u.resp.minsize),
>  be32_to_cpu(psbs.u.resp.maxsize));
> @@ -314,7 +305,7 @@ static int tpm_emulator_startup_tpm(TPMBackend *tb, 
> size_t buffersize)
>  goto err_exit;
>  }
>  
> -DPRINTF("%s", __func__);
> +trace_tpm_emulator_startup_tpm();
>  if (tpm_emulator_ctrlcmd(tpm_emu, CMD_INIT, , sizeof(init),
>   sizeof(init)) < 0) {
>  error_report("tpm-emulator: could not send INIT: %s",
> @@ -348,7 +339,7 @@ static bool 
> tpm_emulator_get_tpm_established_flag(TPMBackend *tb)
>   strerror(errno));
>  return false;
>  }
> -DPRINTF("got established flag: %0x", est.u.resp.bit);
> +trace_tpm_emulator_get_tpm_established_flag(est.u.resp.bit);
>  
>  tpm_emu->established_flag_cached = 1;
>  tpm_emu->established_flag = (est.u.resp.bit != 0);
> @@ -395,7 +386,7 @@ static void tpm_emulator_cancel_cmd(TPMBackend *tb)
>  ptm_res res;
>  
>  if (!TPM_EMULATOR_IMPLEMENTS_ALL_CAPS(tpm_emu, PTM_CAP_CANCEL_TPM_CMD)) {
> -DPRINTF("Backend does not support CANCEL_TPM_CMD");
> +trace_tpm_emulator_cancel_cmd_not_supt();
>  return;
>  }
>  
> @@ -521,8 +512,16 @@ static int tpm_emulator_handle_device_opts(TPMEmulator 
> *tpm_emu, QemuOpts *opts)
>  goto err;
>  }
>  
> -DPRINTF("TPM Version %s", tpm_emu->tpm_version == TPM_VERSION_1_2 ? 
> "1.2" :
> -(tpm_emu->tpm_version == TPM_VERSION_2_0 ?  "2.0" : 
> "Unspecified"));
> +switch (tpm_emu->tpm_version) {
> +case TPM_VERSION_1_2:
> +trace_tpm_emulator_handle_device_opts_tpm12();
> +break;
> +case TPM_VERSION_2_0:
> +trace_tpm_emulator_handle_device_opts_tpm2();
> +break;
> +default:
> +trace_tpm_emulator_handle_device_opts_unspec();
> +}
>  
>  if (tpm_emulator_probe_caps(tpm_emu) ||
>  tpm_emulator_check_caps(tpm_emu)) {
> @@ -532,7 +531,8 @@ static int tpm_emulator_handle_device_opts(TPMEmulator 
> *tpm_emu, QemuOpts *opts)
>  return tpm_emulator_block_migration(tpm_emu);
>  
>  err:
> 

Re: [Qemu-devel] [PATCH 3/5] tpm: convert tpm_util.c to use trace-events

2018-03-04 Thread Philippe Mathieu-Daudé
On 03/04/2018 06:56 PM, Stefan Berger wrote:
> Signed-off-by: Stefan Berger 

Reviewed-by: Philippe Mathieu-Daudé 

> ---
>  hw/tpm/tpm_util.c   | 29 -
>  hw/tpm/trace-events |  7 +++
>  2 files changed, 19 insertions(+), 17 deletions(-)
> 
> diff --git a/hw/tpm/tpm_util.c b/hw/tpm/tpm_util.c
> index 2de52a0..ee41757 100644
> --- a/hw/tpm/tpm_util.c
> +++ b/hw/tpm/tpm_util.c
> @@ -28,14 +28,7 @@
>  #include "exec/memory.h"
>  #include "sysemu/tpm_backend.h"
>  #include "hw/qdev.h"
> -
> -#define DEBUG_TPM 0
> -
> -#define DPRINTF(fmt, ...) do { \
> -if (DEBUG_TPM) { \
> -fprintf(stderr, "tpm-util:"fmt"\n", ## __VA_ARGS__); \
> -} \
> -} while (0)
> +#include "trace.h"
>  
>  /* tpm backend property */
>  
> @@ -279,10 +272,11 @@ int tpm_util_get_buffer_size(int tpm_fd, TPMVersion 
> tpm_version,
>  
>  if (be32_to_cpu(tpm_resp.hdr.len) != sizeof(tpm_resp) ||
>  be32_to_cpu(tpm_resp.len) != sizeof(uint32_t)) {
> -DPRINTF("tpm_resp->hdr.len = %u, expected = %zu\n",
> -be32_to_cpu(tpm_resp.hdr.len), sizeof(tpm_resp));
> -DPRINTF("tpm_resp->len = %u, expected = %zu\n",
> -be32_to_cpu(tpm_resp.len), sizeof(uint32_t));
> +trace_tpm_util_get_buffer_size_hdr_len(
> +be32_to_cpu(tpm_resp.hdr.len),
> +sizeof(tpm_resp));
> +trace_tpm_util_get_buffer_size_len(be32_to_cpu(tpm_resp.len),
> +   sizeof(uint32_t));
>  error_report("tpm_util: Got unexpected response to "
>   "TPM_GetCapability; errcode: 0x%x",
>   be32_to_cpu(tpm_resp.hdr.errcode));
> @@ -327,10 +321,11 @@ int tpm_util_get_buffer_size(int tpm_fd, TPMVersion 
> tpm_version,
>  
>  if (be32_to_cpu(tpm2_resp.hdr.len) != sizeof(tpm2_resp) ||
>  be32_to_cpu(tpm2_resp.count) != 2) {
> -DPRINTF("tpm2_resp->hdr.len = %u, expected = %zu\n",
> -be32_to_cpu(tpm2_resp.hdr.len), sizeof(tpm2_resp));
> -DPRINTF("tpm2_resp->len = %u, expected = %u\n",
> -be32_to_cpu(tpm2_resp.count), 2);
> +trace_tpm_util_get_buffer_size_hdr_len2(
> +be32_to_cpu(tpm2_resp.hdr.len),
> +sizeof(tpm2_resp));
> +trace_tpm_util_get_buffer_size_len2(
> +be32_to_cpu(tpm2_resp.count), 2);
>  error_report("tpm_util: Got unexpected response to "
>   "TPM2_GetCapability; errcode: 0x%x",
>   be32_to_cpu(tpm2_resp.hdr.errcode));
> @@ -344,7 +339,7 @@ int tpm_util_get_buffer_size(int tpm_fd, TPMVersion 
> tpm_version,
>  return -EFAULT;
>  }
>  
> -DPRINTF("buffersize of device: %zu\n", *buffersize);
> +trace_tpm_util_get_buffer_size(*buffersize);
>  
>  return 0;
>  }
> diff --git a/hw/tpm/trace-events b/hw/tpm/trace-events
> index 8557dd9..66b2b91 100644
> --- a/hw/tpm/trace-events
> +++ b/hw/tpm/trace-events
> @@ -7,3 +7,10 @@ tpm_crb_mmio_write(uint64_t addr, unsigned size, uint32_t 
> val) "CRB write 0x" TA
>  # hw/tpm/tpm_passthrough.c
>  tpm_passthrough_handle_request(void *cmd) "processing command %p"
>  tpm_passthrough_reset(void) "reset"
> +
> +# hw/tpm/tpm_util.c
> +tpm_util_get_buffer_size_hdr_len(uint32_t len, size_t expected) 
> "tpm_resp->hdr.len = %u, expected = %zu"
> +tpm_util_get_buffer_size_len(uint32_t len, size_t expected) "tpm_resp->len = 
> %u, expected = %zu"
> +tpm_util_get_buffer_size_hdr_len2(uint32_t len, size_t expected) 
> "tpm2_resp->hdr.len = %u, expected = %zu"
> +tpm_util_get_buffer_size_len2(uint32_t len, size_t expected) "tpm2_resp->len 
> = %u, expected = %zu"
> +tpm_util_get_buffer_size(size_t len) "buffersize of device: %zu"
> 



Re: [Qemu-devel] [PATCH 2/5] tpm: convert tpm_passthrough.c to use trace-events

2018-03-04 Thread Philippe Mathieu-Daudé
On 03/04/2018 06:56 PM, Stefan Berger wrote:
> Signed-off-by: Stefan Berger 

Reviewed-by: Philippe Mathieu-Daudé 

> ---
>  hw/tpm/tpm_passthrough.c | 13 +++--
>  hw/tpm/trace-events  |  4 
>  2 files changed, 7 insertions(+), 10 deletions(-)
> 
> diff --git a/hw/tpm/tpm_passthrough.c b/hw/tpm/tpm_passthrough.c
> index a495fe0..2589c4d 100644
> --- a/hw/tpm/tpm_passthrough.c
> +++ b/hw/tpm/tpm_passthrough.c
> @@ -31,14 +31,7 @@
>  #include "hw/hw.h"
>  #include "qapi/clone-visitor.h"
>  #include "tpm_util.h"
> -
> -#define DEBUG_TPM 0
> -
> -#define DPRINTF(fmt, ...) do { \
> -if (DEBUG_TPM) { \
> -fprintf(stderr, fmt, ## __VA_ARGS__); \
> -} \
> -} while (0)
> +#include "trace.h"
>  
>  #define TYPE_TPM_PASSTHROUGH "tpm-passthrough"
>  #define TPM_PASSTHROUGH(obj) \
> @@ -137,7 +130,7 @@ static void tpm_passthrough_handle_request(TPMBackend 
> *tb, TPMBackendCmd *cmd,
>  {
>  TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
>  
> -DPRINTF("tpm_passthrough: processing command %p\n", cmd);
> +trace_tpm_passthrough_handle_request(cmd);
>  
>  tpm_passthrough_unix_tx_bufs(tpm_pt, cmd->in, cmd->in_len,
>   cmd->out, cmd->out_len, >selftest_done,
> @@ -146,7 +139,7 @@ static void tpm_passthrough_handle_request(TPMBackend 
> *tb, TPMBackendCmd *cmd,
>  
>  static void tpm_passthrough_reset(TPMBackend *tb)
>  {
> -DPRINTF("tpm_passthrough: CALL TO TPM_RESET!\n");
> +trace_tpm_passthrough_reset();
>  
>  tpm_passthrough_cancel_cmd(tb);
>  }
> diff --git a/hw/tpm/trace-events b/hw/tpm/trace-events
> index 336b06d..8557dd9 100644
> --- a/hw/tpm/trace-events
> +++ b/hw/tpm/trace-events
> @@ -3,3 +3,7 @@
>  # hw/tpm/tpm_crb.c
>  tpm_crb_mmio_read(uint64_t addr, unsigned size, uint32_t val) "CRB read 0x" 
> TARGET_FMT_plx " len:%u val: 0x%" PRIx32
>  tpm_crb_mmio_write(uint64_t addr, unsigned size, uint32_t val) "CRB write 
> 0x" TARGET_FMT_plx " len:%u val: 0x%" PRIx32
> +
> +# hw/tpm/tpm_passthrough.c
> +tpm_passthrough_handle_request(void *cmd) "processing command %p"
> +tpm_passthrough_reset(void) "reset"
> 



Re: [Qemu-devel] [PATCH 1/5] tpm: convert tpm_crb.c to use trace-events

2018-03-04 Thread Philippe Mathieu-Daudé
On 03/04/2018 06:56 PM, Stefan Berger wrote:
> Signed-off-by: Stefan Berger 

Reviewed-by: Philippe Mathieu-Daudé 

> ---
>  Makefile.objs   |  1 +
>  hw/tpm/tpm_crb.c| 17 +
>  hw/tpm/trace-events |  5 +
>  3 files changed, 11 insertions(+), 12 deletions(-)
>  create mode 100644 hw/tpm/trace-events
> 
> diff --git a/Makefile.objs b/Makefile.objs
> index 5dc1348..72c3d8c 100644
> --- a/Makefile.objs
> +++ b/Makefile.objs
> @@ -162,6 +162,7 @@ trace-events-subdirs += hw/alpha
>  trace-events-subdirs += hw/hppa
>  trace-events-subdirs += hw/xen
>  trace-events-subdirs += hw/ide
> +trace-events-subdirs += hw/tpm
>  trace-events-subdirs += ui
>  trace-events-subdirs += audio
>  trace-events-subdirs += net
> diff --git a/hw/tpm/tpm_crb.c b/hw/tpm/tpm_crb.c
> index b5b8256..d8917cb 100644
> --- a/hw/tpm/tpm_crb.c
> +++ b/hw/tpm/tpm_crb.c
> @@ -29,6 +29,7 @@
>  #include "sysemu/reset.h"
>  #include "tpm_int.h"
>  #include "tpm_util.h"
> +#include "trace.h"
>  
>  typedef struct CRBState {
>  DeviceState parent_obj;
> @@ -44,14 +45,6 @@ typedef struct CRBState {
>  
>  #define CRB(obj) OBJECT_CHECK(CRBState, (obj), TYPE_TPM_CRB)
>  
> -#define DEBUG_CRB 0
> -
> -#define DPRINTF(fmt, ...) do {  \
> -if (DEBUG_CRB) {\
> -printf(fmt, ## __VA_ARGS__);\
> -}   \
> -} while (0)
> -
>  #define CRB_INTF_TYPE_CRB_ACTIVE 0b1
>  #define CRB_INTF_VERSION_CRB 0b1
>  #define CRB_INTF_CAP_LOCALITY_0_ONLY 0b0
> @@ -91,8 +84,8 @@ static uint64_t tpm_crb_mmio_read(void *opaque, hwaddr addr,
>  unsigned offset = addr & 3;
>  uint32_t val = *(uint32_t *)regs >> (8 * offset);
>  
> -DPRINTF("CRB read 0x" TARGET_FMT_plx " len:%u val: 0x%" PRIx32 "\n",
> -addr, size, val);
> +trace_tpm_crb_mmio_read(addr, size, val);
> +
>  return val;
>  }
>  
> @@ -100,8 +93,8 @@ static void tpm_crb_mmio_write(void *opaque, hwaddr addr,
> uint64_t val, unsigned size)
>  {
>  CRBState *s = CRB(opaque);
> -DPRINTF("CRB write 0x" TARGET_FMT_plx " len:%u val: 0x%" PRIx64 "\n",
> -addr, size, val);
> +
> +trace_tpm_crb_mmio_write(addr, size, val);
>  
>  switch (addr) {
>  case A_CRB_CTRL_REQ:
> diff --git a/hw/tpm/trace-events b/hw/tpm/trace-events
> new file mode 100644
> index 000..336b06d
> --- /dev/null
> +++ b/hw/tpm/trace-events
> @@ -0,0 +1,5 @@
> +# See docs/devel/tracing.txt for syntax documentation.
> +
> +# hw/tpm/tpm_crb.c
> +tpm_crb_mmio_read(uint64_t addr, unsigned size, uint32_t val) "CRB read 0x" 
> TARGET_FMT_plx " len:%u val: 0x%" PRIx32
> +tpm_crb_mmio_write(uint64_t addr, unsigned size, uint32_t val) "CRB write 
> 0x" TARGET_FMT_plx " len:%u val: 0x%" PRIx32
> 



Re: [Qemu-devel] [PATCH] PPC: e500: Add check for NULL return value from qemu_find_file.

2018-03-04 Thread David Gibson
On Sat, Mar 03, 2018 at 01:02:26PM +, Nia Alarie wrote:
> This prints a message and exits if the e500 BIOS firmware can't
> be found, to avoid dereferencing a null pointer.
> 
> Signed-off-by: Nia Alarie 

Applied to ppc-for-2.12, thanks.

> ---
>  hw/ppc/e500.c | 4 
>  1 file changed, 4 insertions(+)
> 
> diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
> index a40d3ec3e3..6ce03d6ff4 100644
> --- a/hw/ppc/e500.c
> +++ b/hw/ppc/e500.c
> @@ -1005,6 +1005,10 @@ void ppce500_init(MachineState *machine, PPCE500Params 
> *params)
>  }
>  }
>  filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
> +if (!filename) {
> +error_report("Could not find firmware '%s'", bios_name);
> +exit(1);
> +}
>  
>  bios_size = load_elf(filename, NULL, NULL, _entry, , NULL,
>   1, PPC_ELF_MACHINE, 0, 0);

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PULL 00/24] ppc-for-2.12 queue 20180302

2018-03-04 Thread David Gibson
On Fri, Mar 02, 2018 at 02:26:49PM +, Peter Maydell wrote:
> On 2 March 2018 at 06:03, David Gibson  wrote:
> > The following changes since commit 0dc8ae5e8e693737dfe65ba02d0c6eccb58a9c67:
> >
> >   Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20180301-v2' into 
> > staging (2018-03-01 17:08:16 +)
> >
> > are available in the Git repository at:
> >
> >   git://github.com/dgibson/qemu.git tags/ppc-for-2.12-20180302
> >
> > for you to fetch changes up to 57ae75b2e401f1d04f37a8cd26212eb3134c51a6:
> >
> >   hw/ppc/spapr,e500: Use new property "stdout-path" for boot console 
> > (2018-03-02 12:24:44 +1100)
> >
> > 
> > ppc patch queue 2018-03-02
> >
> > Here's the next batch of accumulated spapr and ppc patches.
> > Highlights are:
> > * New Sam460ex machine type
> > * Yet more fixes related to vcpu id allocation for spapr
> > * Numerous macio cleanupsr
> > * Some enhancements to the Spectre/Meltdown fixes for pseries,
> >   allowing use of a better mitigation for indirect branch based
> >   exploits
> > * New pseries machine types with Spectre/Meltdown mitigations
> >   enabled (stop gap until libvirt and management understands the
> >   machine options)
> > * A handful of other fixes
> >
> 
> Hi. This generates a compile error from some compilers in my test set
> (I think just the older gccs):
> 
> /home/petmay01/linaro/qemu-for-merges/hw/ppc/ppc440_uc.c: In function
> ‘ppc460ex_pcie_realize’:
> /home/petmay01/linaro/qemu-for-merges/hw/ppc/ppc440_uc.c:1054:5:
> error: ‘id’ may be used uninitialized in this function
> [-Werror=maybe-uninitialized]
>  snprintf(buf, sizeof(buf), "pcie%d-io", id);
>  ^
> cc1: all warnings being treated as errors
> 
> Looks like a valid complaint to me -- the realize function
> should check that dcrn_base was set to a valid value, fail
> realize if it wasn't, and have a 'default:' case in the
> switch with g_assert_not_reached().

Bother.  I wonder why my compiler didn't catch that.

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


[Qemu-devel] [PATCH 3/5] tpm: convert tpm_util.c to use trace-events

2018-03-04 Thread Stefan Berger
Signed-off-by: Stefan Berger 
---
 hw/tpm/tpm_util.c   | 29 -
 hw/tpm/trace-events |  7 +++
 2 files changed, 19 insertions(+), 17 deletions(-)

diff --git a/hw/tpm/tpm_util.c b/hw/tpm/tpm_util.c
index 2de52a0..ee41757 100644
--- a/hw/tpm/tpm_util.c
+++ b/hw/tpm/tpm_util.c
@@ -28,14 +28,7 @@
 #include "exec/memory.h"
 #include "sysemu/tpm_backend.h"
 #include "hw/qdev.h"
-
-#define DEBUG_TPM 0
-
-#define DPRINTF(fmt, ...) do { \
-if (DEBUG_TPM) { \
-fprintf(stderr, "tpm-util:"fmt"\n", ## __VA_ARGS__); \
-} \
-} while (0)
+#include "trace.h"
 
 /* tpm backend property */
 
@@ -279,10 +272,11 @@ int tpm_util_get_buffer_size(int tpm_fd, TPMVersion 
tpm_version,
 
 if (be32_to_cpu(tpm_resp.hdr.len) != sizeof(tpm_resp) ||
 be32_to_cpu(tpm_resp.len) != sizeof(uint32_t)) {
-DPRINTF("tpm_resp->hdr.len = %u, expected = %zu\n",
-be32_to_cpu(tpm_resp.hdr.len), sizeof(tpm_resp));
-DPRINTF("tpm_resp->len = %u, expected = %zu\n",
-be32_to_cpu(tpm_resp.len), sizeof(uint32_t));
+trace_tpm_util_get_buffer_size_hdr_len(
+be32_to_cpu(tpm_resp.hdr.len),
+sizeof(tpm_resp));
+trace_tpm_util_get_buffer_size_len(be32_to_cpu(tpm_resp.len),
+   sizeof(uint32_t));
 error_report("tpm_util: Got unexpected response to "
  "TPM_GetCapability; errcode: 0x%x",
  be32_to_cpu(tpm_resp.hdr.errcode));
@@ -327,10 +321,11 @@ int tpm_util_get_buffer_size(int tpm_fd, TPMVersion 
tpm_version,
 
 if (be32_to_cpu(tpm2_resp.hdr.len) != sizeof(tpm2_resp) ||
 be32_to_cpu(tpm2_resp.count) != 2) {
-DPRINTF("tpm2_resp->hdr.len = %u, expected = %zu\n",
-be32_to_cpu(tpm2_resp.hdr.len), sizeof(tpm2_resp));
-DPRINTF("tpm2_resp->len = %u, expected = %u\n",
-be32_to_cpu(tpm2_resp.count), 2);
+trace_tpm_util_get_buffer_size_hdr_len2(
+be32_to_cpu(tpm2_resp.hdr.len),
+sizeof(tpm2_resp));
+trace_tpm_util_get_buffer_size_len2(
+be32_to_cpu(tpm2_resp.count), 2);
 error_report("tpm_util: Got unexpected response to "
  "TPM2_GetCapability; errcode: 0x%x",
  be32_to_cpu(tpm2_resp.hdr.errcode));
@@ -344,7 +339,7 @@ int tpm_util_get_buffer_size(int tpm_fd, TPMVersion 
tpm_version,
 return -EFAULT;
 }
 
-DPRINTF("buffersize of device: %zu\n", *buffersize);
+trace_tpm_util_get_buffer_size(*buffersize);
 
 return 0;
 }
diff --git a/hw/tpm/trace-events b/hw/tpm/trace-events
index 8557dd9..66b2b91 100644
--- a/hw/tpm/trace-events
+++ b/hw/tpm/trace-events
@@ -7,3 +7,10 @@ tpm_crb_mmio_write(uint64_t addr, unsigned size, uint32_t val) 
"CRB write 0x" TA
 # hw/tpm/tpm_passthrough.c
 tpm_passthrough_handle_request(void *cmd) "processing command %p"
 tpm_passthrough_reset(void) "reset"
+
+# hw/tpm/tpm_util.c
+tpm_util_get_buffer_size_hdr_len(uint32_t len, size_t expected) 
"tpm_resp->hdr.len = %u, expected = %zu"
+tpm_util_get_buffer_size_len(uint32_t len, size_t expected) "tpm_resp->len = 
%u, expected = %zu"
+tpm_util_get_buffer_size_hdr_len2(uint32_t len, size_t expected) 
"tpm2_resp->hdr.len = %u, expected = %zu"
+tpm_util_get_buffer_size_len2(uint32_t len, size_t expected) "tpm2_resp->len = 
%u, expected = %zu"
+tpm_util_get_buffer_size(size_t len) "buffersize of device: %zu"
-- 
2.5.5




[Qemu-devel] [PATCH 5/5] tpm: convert tpm_tis.c to use trace-events

2018-03-04 Thread Stefan Berger
Leave the DEBUG_TIS for more debugging and convert to use if (DEBUG_TIS)
rather than #if DEBUG_TIS where it is being used.

Signed-off-by: Stefan Berger 
---
 hw/tpm/tpm_tis.c| 98 -
 hw/tpm/trace-events | 16 +
 2 files changed, 61 insertions(+), 53 deletions(-)

diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index 834eef7..2ac7e74 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis.c
@@ -31,6 +31,7 @@
 #include "sysemu/tpm_backend.h"
 #include "tpm_int.h"
 #include "tpm_util.h"
+#include "trace.h"
 
 #define TPM_TIS_NUM_LOCALITIES  5 /* per spec */
 #define TPM_TIS_LOCALITY_SHIFT  12
@@ -86,12 +87,6 @@ typedef struct TPMState {
 
 #define DEBUG_TIS 0
 
-#define DPRINTF(fmt, ...) do { \
-if (DEBUG_TIS) { \
-printf(fmt, ## __VA_ARGS__); \
-} \
-} while (0)
-
 /* local prototypes */
 
 static uint64_t tpm_tis_mmio_read(void *opaque, hwaddr addr,
@@ -107,19 +102,17 @@ static uint8_t tpm_tis_locality_from_addr(hwaddr addr)
 static void tpm_tis_show_buffer(const unsigned char *buffer,
 size_t buffer_size, const char *string)
 {
-#ifdef DEBUG_TIS
 uint32_t len, i;
 
 len = MIN(tpm_cmd_get_size(buffer), buffer_size);
-DPRINTF("tpm_tis: %s length = %d\n", string, len);
+printf("tpm_tis: %s length = %d\n", string, len);
 for (i = 0; i < len; i++) {
 if (i && !(i % 16)) {
-DPRINTF("\n");
+printf("\n");
 }
-DPRINTF("%.2X ", buffer[i]);
+printf("%.2X ", buffer[i]);
 }
-DPRINTF("\n");
-#endif
+printf("\n");
 }
 
 /*
@@ -146,8 +139,10 @@ static void tpm_tis_sts_set(TPMLocality *l, uint32_t flags)
  */
 static void tpm_tis_tpm_send(TPMState *s, uint8_t locty)
 {
-tpm_tis_show_buffer(s->buffer, s->be_buffer_size,
-"tpm_tis: To TPM");
+if (DEBUG_TIS) {
+tpm_tis_show_buffer(s->buffer, s->be_buffer_size,
+"tpm_tis: To TPM");
+}
 
 /*
  * rw_offset serves as length indicator for length of data;
@@ -175,7 +170,7 @@ static void tpm_tis_raise_irq(TPMState *s, uint8_t locty, 
uint32_t irqmask)
 
 if ((s->loc[locty].inte & TPM_TIS_INT_ENABLED) &&
 (s->loc[locty].inte & irqmask)) {
-DPRINTF("tpm_tis: Raising IRQ for flag %08x\n", irqmask);
+trace_tpm_tis_raise_irq(irqmask);
 qemu_irq_raise(s->irq);
 s->loc[locty].ints |= irqmask;
 }
@@ -223,7 +218,7 @@ static void tpm_tis_new_active_locality(TPMState *s, 
uint8_t new_active_locty)
 
 s->active_locty = new_active_locty;
 
-DPRINTF("tpm_tis: Active locality is now %d\n", s->active_locty);
+trace_tpm_tis_new_active_locality(s->active_locty);
 
 if (TPM_TIS_IS_VALID_LOCTY(new_active_locty)) {
 /* set flags on the new active locality */
@@ -242,7 +237,7 @@ static void tpm_tis_abort(TPMState *s, uint8_t locty)
 {
 s->rw_offset = 0;
 
-DPRINTF("tpm_tis: tis_abort: new active locality is %d\n", s->next_locty);
+trace_tpm_tis_abort(s->next_locty);
 
 /*
  * Need to react differently depending on who's aborting now and
@@ -310,8 +305,10 @@ static void tpm_tis_request_completed(TPMIf *ti, int ret)
 s->loc[locty].state = TPM_TIS_STATE_COMPLETION;
 s->rw_offset = 0;
 
-tpm_tis_show_buffer(s->buffer, s->be_buffer_size,
-"tpm_tis: From TPM");
+if (DEBUG_TIS) {
+tpm_tis_show_buffer(s->buffer, s->be_buffer_size,
+"tpm_tis: From TPM");
+}
 
 if (TPM_TIS_IS_VALID_LOCTY(s->next_locty)) {
 tpm_tis_abort(s, locty);
@@ -339,8 +336,7 @@ static uint32_t tpm_tis_data_read(TPMState *s, uint8_t 
locty)
 tpm_tis_sts_set(>loc[locty], TPM_TIS_STS_VALID);
 tpm_tis_raise_irq(s, locty, TPM_TIS_INT_STS_VALID);
 }
-DPRINTF("tpm_tis: tpm_tis_data_read byte 0x%02x   [%d]\n",
-ret, s->rw_offset - 1);
+trace_tpm_tis_data_read(ret, s->rw_offset - 1);
 }
 
 return ret;
@@ -364,29 +360,29 @@ static void tpm_tis_dump_state(void *opaque, hwaddr addr)
 hwaddr base = addr & ~0xfff;
 TPMState *s = opaque;
 
-DPRINTF("tpm_tis: active locality  : %d\n"
-"tpm_tis: state of locality %d : %d\n"
-"tpm_tis: register dump:\n",
-s->active_locty,
-locty, s->loc[locty].state);
+printf("tpm_tis: active locality  : %d\n"
+   "tpm_tis: state of locality %d : %d\n"
+   "tpm_tis: register dump:\n",
+   s->active_locty,
+   locty, s->loc[locty].state);
 
 for (idx = 0; regs[idx] != 0xfff; idx++) {
-DPRINTF("tpm_tis: 0x%04x : 0x%08x\n", regs[idx],
-(int)tpm_tis_mmio_read(opaque, base + regs[idx], 4));
+printf("tpm_tis: 0x%04x : 0x%08x\n", regs[idx],
+   (int)tpm_tis_mmio_read(opaque, base + regs[idx], 4));
 }
 
-

[Qemu-devel] [PATCH 1/5] tpm: convert tpm_crb.c to use trace-events

2018-03-04 Thread Stefan Berger
Signed-off-by: Stefan Berger 
---
 Makefile.objs   |  1 +
 hw/tpm/tpm_crb.c| 17 +
 hw/tpm/trace-events |  5 +
 3 files changed, 11 insertions(+), 12 deletions(-)
 create mode 100644 hw/tpm/trace-events

diff --git a/Makefile.objs b/Makefile.objs
index 5dc1348..72c3d8c 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -162,6 +162,7 @@ trace-events-subdirs += hw/alpha
 trace-events-subdirs += hw/hppa
 trace-events-subdirs += hw/xen
 trace-events-subdirs += hw/ide
+trace-events-subdirs += hw/tpm
 trace-events-subdirs += ui
 trace-events-subdirs += audio
 trace-events-subdirs += net
diff --git a/hw/tpm/tpm_crb.c b/hw/tpm/tpm_crb.c
index b5b8256..d8917cb 100644
--- a/hw/tpm/tpm_crb.c
+++ b/hw/tpm/tpm_crb.c
@@ -29,6 +29,7 @@
 #include "sysemu/reset.h"
 #include "tpm_int.h"
 #include "tpm_util.h"
+#include "trace.h"
 
 typedef struct CRBState {
 DeviceState parent_obj;
@@ -44,14 +45,6 @@ typedef struct CRBState {
 
 #define CRB(obj) OBJECT_CHECK(CRBState, (obj), TYPE_TPM_CRB)
 
-#define DEBUG_CRB 0
-
-#define DPRINTF(fmt, ...) do {  \
-if (DEBUG_CRB) {\
-printf(fmt, ## __VA_ARGS__);\
-}   \
-} while (0)
-
 #define CRB_INTF_TYPE_CRB_ACTIVE 0b1
 #define CRB_INTF_VERSION_CRB 0b1
 #define CRB_INTF_CAP_LOCALITY_0_ONLY 0b0
@@ -91,8 +84,8 @@ static uint64_t tpm_crb_mmio_read(void *opaque, hwaddr addr,
 unsigned offset = addr & 3;
 uint32_t val = *(uint32_t *)regs >> (8 * offset);
 
-DPRINTF("CRB read 0x" TARGET_FMT_plx " len:%u val: 0x%" PRIx32 "\n",
-addr, size, val);
+trace_tpm_crb_mmio_read(addr, size, val);
+
 return val;
 }
 
@@ -100,8 +93,8 @@ static void tpm_crb_mmio_write(void *opaque, hwaddr addr,
uint64_t val, unsigned size)
 {
 CRBState *s = CRB(opaque);
-DPRINTF("CRB write 0x" TARGET_FMT_plx " len:%u val: 0x%" PRIx64 "\n",
-addr, size, val);
+
+trace_tpm_crb_mmio_write(addr, size, val);
 
 switch (addr) {
 case A_CRB_CTRL_REQ:
diff --git a/hw/tpm/trace-events b/hw/tpm/trace-events
new file mode 100644
index 000..336b06d
--- /dev/null
+++ b/hw/tpm/trace-events
@@ -0,0 +1,5 @@
+# See docs/devel/tracing.txt for syntax documentation.
+
+# hw/tpm/tpm_crb.c
+tpm_crb_mmio_read(uint64_t addr, unsigned size, uint32_t val) "CRB read 0x" 
TARGET_FMT_plx " len:%u val: 0x%" PRIx32
+tpm_crb_mmio_write(uint64_t addr, unsigned size, uint32_t val) "CRB write 0x" 
TARGET_FMT_plx " len:%u val: 0x%" PRIx32
-- 
2.5.5




[Qemu-devel] [PATCH 0/5] Convert the TPM code to use tracing

2018-03-04 Thread Stefan Berger
This series of patches converts the TPM code to use tracing rather
than the #define DEBUG_XYZ type of debugging.

Regards,
   Stefan

Stefan Berger (5):
  tpm: convert tpm_crb.c to use trace-events
  tpm: convert tpm_passthrough.c to use trace-events
  tpm: convert tpm_util.c to use trace-events
  tpm: convert tpm_emulator.c to use trace-events
  tpm: convert tpm_tis.c to use trace-events

 Makefile.objs|  1 +
 hw/tpm/tpm_crb.c | 17 +++--
 hw/tpm/tpm_emulator.c| 45 +++---
 hw/tpm/tpm_passthrough.c | 13 ++-
 hw/tpm/tpm_tis.c | 98 ++--
 hw/tpm/tpm_util.c| 29 ++
 hw/tpm/trace-events  | 46 +++
 7 files changed, 135 insertions(+), 114 deletions(-)
 create mode 100644 hw/tpm/trace-events

-- 
2.5.5




[Qemu-devel] [PATCH 4/5] tpm: convert tpm_emulator.c to use trace-events

2018-03-04 Thread Stefan Berger
Signed-off-by: Stefan Berger 
---
 hw/tpm/tpm_emulator.c | 45 +++--
 hw/tpm/trace-events   | 14 ++
 2 files changed, 37 insertions(+), 22 deletions(-)

diff --git a/hw/tpm/tpm_emulator.c b/hw/tpm/tpm_emulator.c
index b787aee..d0da10a 100644
--- a/hw/tpm/tpm_emulator.c
+++ b/hw/tpm/tpm_emulator.c
@@ -39,14 +39,7 @@
 #include "qapi/error.h"
 #include "qapi/clone-visitor.h"
 #include "chardev/char-fe.h"
-
-#define DEBUG_TPM 0
-
-#define DPRINTF(fmt, ...) do { \
-if (DEBUG_TPM) { \
-fprintf(stderr, "tpm-emulator:"fmt"\n", ## __VA_ARGS__); \
-} \
-} while (0)
+#include "trace.h"
 
 #define TYPE_TPM_EMULATOR "tpm-emulator"
 #define TPM_EMULATOR(obj) \
@@ -151,13 +144,12 @@ static int tpm_emulator_set_locality(TPMEmulator 
*tpm_emu, uint8_t locty_number,
 {
 ptm_loc loc;
 
-DPRINTF("%s : locality: 0x%x", __func__, locty_number);
-
 if (tpm_emu->cur_locty_number == locty_number) {
 return 0;
 }
 
-DPRINTF("setting locality : 0x%x", locty_number);
+trace_tpm_emulator_set_locality(locty_number);
+
 loc.u.req.loc = locty_number;
 if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_LOCALITY, ,
  sizeof(loc), sizeof(loc)) < 0) {
@@ -183,7 +175,7 @@ static void tpm_emulator_handle_request(TPMBackend *tb, 
TPMBackendCmd *cmd,
 {
 TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
 
-DPRINTF("processing TPM command");
+trace_tpm_emulator_handle_request();
 
 if (tpm_emulator_set_locality(tpm_emu, cmd->locty, errp) < 0 ||
 tpm_emulator_unix_tx_bufs(tpm_emu, cmd->in, cmd->in_len,
@@ -195,7 +187,6 @@ static void tpm_emulator_handle_request(TPMBackend *tb, 
TPMBackendCmd *cmd,
 
 static int tpm_emulator_probe_caps(TPMEmulator *tpm_emu)
 {
-DPRINTF("%s", __func__);
 if (tpm_emulator_ctrlcmd(tpm_emu, CMD_GET_CAPABILITY,
  _emu->caps, 0, sizeof(tpm_emu->caps)) < 0) {
 error_report("tpm-emulator: probing failed : %s", strerror(errno));
@@ -204,7 +195,7 @@ static int tpm_emulator_probe_caps(TPMEmulator *tpm_emu)
 
 tpm_emu->caps = be64_to_cpu(tpm_emu->caps);
 
-DPRINTF("capabilities : 0x%"PRIx64, tpm_emu->caps);
+trace_tpm_emulator_probe_caps(tpm_emu->caps);
 
 return 0;
 }
@@ -293,7 +284,7 @@ static int tpm_emulator_set_buffer_size(TPMBackend *tb,
 *actual_size = be32_to_cpu(psbs.u.resp.buffersize);
 }
 
-DPRINTF("buffer size: %u, min: %u, max: %u\n",
+trace_tpm_emulator_set_buffer_size(
 be32_to_cpu(psbs.u.resp.buffersize),
 be32_to_cpu(psbs.u.resp.minsize),
 be32_to_cpu(psbs.u.resp.maxsize));
@@ -314,7 +305,7 @@ static int tpm_emulator_startup_tpm(TPMBackend *tb, size_t 
buffersize)
 goto err_exit;
 }
 
-DPRINTF("%s", __func__);
+trace_tpm_emulator_startup_tpm();
 if (tpm_emulator_ctrlcmd(tpm_emu, CMD_INIT, , sizeof(init),
  sizeof(init)) < 0) {
 error_report("tpm-emulator: could not send INIT: %s",
@@ -348,7 +339,7 @@ static bool 
tpm_emulator_get_tpm_established_flag(TPMBackend *tb)
  strerror(errno));
 return false;
 }
-DPRINTF("got established flag: %0x", est.u.resp.bit);
+trace_tpm_emulator_get_tpm_established_flag(est.u.resp.bit);
 
 tpm_emu->established_flag_cached = 1;
 tpm_emu->established_flag = (est.u.resp.bit != 0);
@@ -395,7 +386,7 @@ static void tpm_emulator_cancel_cmd(TPMBackend *tb)
 ptm_res res;
 
 if (!TPM_EMULATOR_IMPLEMENTS_ALL_CAPS(tpm_emu, PTM_CAP_CANCEL_TPM_CMD)) {
-DPRINTF("Backend does not support CANCEL_TPM_CMD");
+trace_tpm_emulator_cancel_cmd_not_supt();
 return;
 }
 
@@ -521,8 +512,16 @@ static int tpm_emulator_handle_device_opts(TPMEmulator 
*tpm_emu, QemuOpts *opts)
 goto err;
 }
 
-DPRINTF("TPM Version %s", tpm_emu->tpm_version == TPM_VERSION_1_2 ? "1.2" :
-(tpm_emu->tpm_version == TPM_VERSION_2_0 ?  "2.0" : 
"Unspecified"));
+switch (tpm_emu->tpm_version) {
+case TPM_VERSION_1_2:
+trace_tpm_emulator_handle_device_opts_tpm12();
+break;
+case TPM_VERSION_2_0:
+trace_tpm_emulator_handle_device_opts_tpm2();
+break;
+default:
+trace_tpm_emulator_handle_device_opts_unspec();
+}
 
 if (tpm_emulator_probe_caps(tpm_emu) ||
 tpm_emulator_check_caps(tpm_emu)) {
@@ -532,7 +531,8 @@ static int tpm_emulator_handle_device_opts(TPMEmulator 
*tpm_emu, QemuOpts *opts)
 return tpm_emulator_block_migration(tpm_emu);
 
 err:
-DPRINTF("Startup error");
+trace_tpm_emulator_handle_device_opts_startup_error();
+
 return -1;
 }
 
@@ -573,7 +573,8 @@ static void tpm_emulator_inst_init(Object *obj)
 {
 TPMEmulator *tpm_emu = TPM_EMULATOR(obj);
 
-DPRINTF("%s", __func__);
+trace_tpm_emulator_inst_init();
+
 tpm_emu->options = g_new0(TPMEmulatorOptions, 1);
 

[Qemu-devel] [PATCH 2/5] tpm: convert tpm_passthrough.c to use trace-events

2018-03-04 Thread Stefan Berger
Signed-off-by: Stefan Berger 
---
 hw/tpm/tpm_passthrough.c | 13 +++--
 hw/tpm/trace-events  |  4 
 2 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/hw/tpm/tpm_passthrough.c b/hw/tpm/tpm_passthrough.c
index a495fe0..2589c4d 100644
--- a/hw/tpm/tpm_passthrough.c
+++ b/hw/tpm/tpm_passthrough.c
@@ -31,14 +31,7 @@
 #include "hw/hw.h"
 #include "qapi/clone-visitor.h"
 #include "tpm_util.h"
-
-#define DEBUG_TPM 0
-
-#define DPRINTF(fmt, ...) do { \
-if (DEBUG_TPM) { \
-fprintf(stderr, fmt, ## __VA_ARGS__); \
-} \
-} while (0)
+#include "trace.h"
 
 #define TYPE_TPM_PASSTHROUGH "tpm-passthrough"
 #define TPM_PASSTHROUGH(obj) \
@@ -137,7 +130,7 @@ static void tpm_passthrough_handle_request(TPMBackend *tb, 
TPMBackendCmd *cmd,
 {
 TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
 
-DPRINTF("tpm_passthrough: processing command %p\n", cmd);
+trace_tpm_passthrough_handle_request(cmd);
 
 tpm_passthrough_unix_tx_bufs(tpm_pt, cmd->in, cmd->in_len,
  cmd->out, cmd->out_len, >selftest_done,
@@ -146,7 +139,7 @@ static void tpm_passthrough_handle_request(TPMBackend *tb, 
TPMBackendCmd *cmd,
 
 static void tpm_passthrough_reset(TPMBackend *tb)
 {
-DPRINTF("tpm_passthrough: CALL TO TPM_RESET!\n");
+trace_tpm_passthrough_reset();
 
 tpm_passthrough_cancel_cmd(tb);
 }
diff --git a/hw/tpm/trace-events b/hw/tpm/trace-events
index 336b06d..8557dd9 100644
--- a/hw/tpm/trace-events
+++ b/hw/tpm/trace-events
@@ -3,3 +3,7 @@
 # hw/tpm/tpm_crb.c
 tpm_crb_mmio_read(uint64_t addr, unsigned size, uint32_t val) "CRB read 0x" 
TARGET_FMT_plx " len:%u val: 0x%" PRIx32
 tpm_crb_mmio_write(uint64_t addr, unsigned size, uint32_t val) "CRB write 0x" 
TARGET_FMT_plx " len:%u val: 0x%" PRIx32
+
+# hw/tpm/tpm_passthrough.c
+tpm_passthrough_handle_request(void *cmd) "processing command %p"
+tpm_passthrough_reset(void) "reset"
-- 
2.5.5




Re: [Qemu-devel] [PATCH 2/2] slirp: Add classless static routes support to DHCP server

2018-03-04 Thread Samuel Thibault
Benjamin Drung, on mar. 27 févr. 2018 17:06:02 +0100, wrote:
> +int i = 0;

Rather unsigned?
>  char *end;
> +unsigned int route_count = 0;
>  struct slirp_config_str *config;
> +struct StaticRoute *routes = NULL;
> +const StringList *iter;
>  
>  if (!ipv4 && (vnetwork || vhost || vnameserver)) {
>  error_setg(errp, "IPv4 disabled but netmask/host/dns provided");
> @@ -365,6 +369,58 @@ static int net_slirp_init(NetClientState *peer, const 
> char *model,
>  return -1;
>  }
>  
> +iter = vroutes;

Rather initialize route_count to 0 here.
> +while (iter) {
> +route_count++;
> +iter = iter->next;
> +}



> +iter = vroutes;

Rather initialize i to 0 here.

> +while(iter != NULL) {

> +// Split "subnet/mask:gateway" into its components
> +if (get_str_sep(buf2, sizeof(buf2), , ':') < 0) {
[etc.]

You should make the gateway host.s_addr by default, so the gateway or
even :gateway part can be optional.

> -" [,tftp=dir][,bootfile=f][,hostfwd=rule][,guestfwd=rule]"
> +" 
> [,route=addr/mask:gateway][,tftp=dir][,bootfile=f][,hostfwd=rule][,guestfwd=rule]"

And document optionality in the help, of course.

> +if (slirp->route_count > 0) {
> +uint8_t option_length = 0;
> +uint8_t significant_octets;
> +
> +for (int i = 0; i < slirp->route_count; i++) {
> +significant_octets = slirp->routes[i].mask_width / 8
> + + (slirp->routes[i].mask_width % 8 > 0);

Rather use (slirp->routes[i].mask_width + 7) / 8 (and ditto below)

> +option_length += significant_octets + 5;
> +}
> +
> +*q++ = RFC3442_CLASSLESS_STATIC_ROUTE;

I'd say instead of computing the option_length twice, create a variable
uint8_t *size which you make point at the size byte here, and you can
fill it after the loop.

Apart from that it looks good.

Samuel



Re: [Qemu-devel] [PATCH 1/2 v4] slirp: Add domainname option to slirp's DHCP server

2018-03-04 Thread Samuel Thibault
Benjamin Drung, on mar. 27 févr. 2018 17:06:01 +0100, wrote:
> This patch will allow the user to include the domainname option in
> replies from the built-in DHCP server.
> 
> Signed-off-by: Benjamin Drung 

Reviewed-by: Samuel Thibault 

and applied to my tree.

Samuel

> ---
>  net/slirp.c  | 12 +---
>  qapi/net.json|  4 
>  qemu-options.hx  |  7 +--
>  slirp/bootp.c|  8 
>  slirp/libslirp.h |  2 +-
>  slirp/slirp.c|  4 +++-
>  slirp/slirp.h|  1 +
>  7 files changed, 31 insertions(+), 7 deletions(-)
> 
> diff --git a/net/slirp.c b/net/slirp.c
> index 8991816bbf..8c08e5644f 100644
> --- a/net/slirp.c
> +++ b/net/slirp.c
> @@ -157,7 +157,8 @@ static int net_slirp_init(NetClientState *peer, const 
> char *model,
>const char *bootfile, const char *vdhcp_start,
>const char *vnameserver, const char *vnameserver6,
>const char *smb_export, const char *vsmbserver,
> -  const char **dnssearch, Error **errp)
> +  const char **dnssearch, const char *vdomainname,
> +  Error **errp)
>  {
>  /* default settings according to historic slirp */
>  struct in_addr net  = { .s_addr = htonl(0x0a000200) }; /* 10.0.2.0 */
> @@ -359,6 +360,11 @@ static int net_slirp_init(NetClientState *peer, const 
> char *model,
>  ip6_dns.s6_addr[15] |= 3;
>  }
>  
> +if (vdomainname && !*vdomainname) {
> +error_setg(errp, "'domainname' parameter cannot be empty");
> +return -1;
> +}
> +
>  
>  nc = qemu_new_net_client(_slirp_info, peer, model, name);
>  
> @@ -371,7 +377,7 @@ static int net_slirp_init(NetClientState *peer, const 
> char *model,
>  s->slirp = slirp_init(restricted, ipv4, net, mask, host,
>ipv6, ip6_prefix, vprefix6_len, ip6_host,
>vhostname, tftp_export, bootfile, dhcp,
> -  dns, ip6_dns, dnssearch, s);
> +  dns, ip6_dns, dnssearch, vdomainname, s);
>  QTAILQ_INSERT_TAIL(_stacks, s, entry);
>  
>  for (config = slirp_configs; config; config = config->next) {
> @@ -958,7 +964,7 @@ int net_init_slirp(const Netdev *netdev, const char *name,
>   user->ipv6_host, user->hostname, user->tftp,
>   user->bootfile, user->dhcpstart,
>   user->dns, user->ipv6_dns, user->smb,
> - user->smbserver, dnssearch, errp);
> + user->smbserver, dnssearch, user->domainname, errp);
>  
>  while (slirp_configs) {
>  config = slirp_configs;
> diff --git a/qapi/net.json b/qapi/net.json
> index 1238ba5de1..9dfd34cafa 100644
> --- a/qapi/net.json
> +++ b/qapi/net.json
> @@ -160,6 +160,9 @@
>  # @dnssearch: list of DNS suffixes to search, passed as DHCP option
>  # to the guest
>  #
> +# @domainname: guest-visible domain name of the virtual nameserver
> +#  (since 2.12)
> +#
>  # @ipv6-prefix: IPv6 network prefix (default is fec0::) (since
>  #   2.6). The network prefix is given in the usual
>  #   hexadecimal IPv6 address notation.
> @@ -197,6 +200,7 @@
>  '*dhcpstart': 'str',
>  '*dns':   'str',
>  '*dnssearch': ['String'],
> +'*domainname': 'str',
>  '*ipv6-prefix':  'str',
>  '*ipv6-prefixlen':   'int',
>  '*ipv6-host':'str',
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 8ccd5dcaa6..c000ef454e 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -1906,8 +1906,8 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
>  "-netdev user,id=str[,ipv4[=on|off]][,net=addr[/mask]][,host=addr]\n"
>  " [,ipv6[=on|off]][,ipv6-net=addr[/int]][,ipv6-host=addr]\n"
>  " [,restrict=on|off][,hostname=host][,dhcpstart=addr]\n"
> -" [,dns=addr][,ipv6-dns=addr][,dnssearch=domain][,tftp=dir]\n"
> -" [,bootfile=f][,hostfwd=rule][,guestfwd=rule]"
> +" 
> [,dns=addr][,ipv6-dns=addr][,dnssearch=domain][,domainname=domain]\n"
> +" [,tftp=dir][,bootfile=f][,hostfwd=rule][,guestfwd=rule]"
>  #ifndef _WIN32
>   "[,smb=dir[,smbserver=addr]]\n"
>  #endif
> @@ -2116,6 +2116,9 @@ Example:
>  qemu -net user,dnssearch=mgmt.example.org,dnssearch=example.org [...]
>  @end example
>  
> +@item domainname=@var{domain}
> +Specifies the client domain name reported by the built-in DHCP server.
> +
>  @item tftp=@var{dir}
>  When using the user mode network stack, activate a built-in TFTP
>  server. The files in @var{dir} will be exposed as the root of a TFTP server.
> diff --git a/slirp/bootp.c b/slirp/bootp.c
> index 5dd1a415b5..9e7b53ba94 100644
> --- a/slirp/bootp.c
> +++ b/slirp/bootp.c
> @@ -298,6 +298,14 @@ static void 

[Qemu-devel] [Bug 1753314] [NEW] UART in sabrelite machine simulation doesn't work with VxWorks 7

2018-03-04 Thread Bill Paul
Public bug reported:

The imx_serial.c driver currently implements only partial support for
the i.MX6 UART hardware. (I understand it's a work in progress and
that's fine.) dIn particular, it does not implement support for the
Transmit Complete Interrupt Enable bit in the UCR4 register. The VxWorks
7 i.MX6 serial driver depends on the behavior of this bit in actual
hardware in order to send characters through the UART correctly. The
result is that with the current machine model, VxWorks will boot and run
in QEMU but it's unable to print any characters to the console serial
port.

I have produced a small patch for the imx_serial.c module to make it
nominally functional with VxWorks 7. It works well enough to allow the
boot banner to appear and for the user to interact with the target
shell.

I'm not submitting this as a patch to the development list as I'm not
fully certain it complies with the hardware spec and doesn't break any
other functionality. I would prefer if the maintainer (or someone)
reviewed it for any issues/refinements first.

I'm attaching the patch to this bug report. A copy can also be obtained
from:

http://people.freebsd.org/~wpaul/qemu/imx_serial.zip

This patch was generated against QEMU 2.11.0 but also works with QEMU
2.11.1.

My host environment is FreeBSD/amd64 11.1-RELEASE with QEMU
2.11.0/2.11.11 built from source.

** Affects: qemu
 Importance: Undecided
 Status: New


** Tags: arm sabrelite uart

** Patch added: "Patch for imx_serial.c/h to make it work with VxWorks"
   
https://bugs.launchpad.net/bugs/1753314/+attachment/5069246/+files/imx_serial.zip

** Summary changed:

- UART in sabrelite machine simulation doesn't work wth VxWorks
+ UART in sabrelite machine simulation doesn't work with VxWorks 7

** Description changed:

  The imx_serial.c driver currently implements only partial support for
- the i.MX6 UART hardware. In particular, it does not implement support
- for the Transmit Complete Interrupt Enable bit in the UCR4 register. The
- VxWorks 7 i.MX6 serial driver depends on the behavior of this bit in
- actual hardware in order to send characters through the UART correctly.
- The result is that with the current machine model, VxWorks will boot and
- run in QEMU but it's unable to print any characters to the console
- serial port.
+ the i.MX6 UART hardware. (I understand it's a work in progress and
+ that's fine.) In particular, it does not implement support for the
+ Transmit Complete Interrupt Enable bit in the UCR4 register. The VxWorks
+ 7 i.MX6 serial driver depends on the behavior of this bit in actual
+ hardware in order to send characters through the UART correctly. The
+ result is that with the current machine model, VxWorks will boot and run
+ in QEMU but it's unable to print any characters to the console serial
+ port.
  
  I have produced a small patch for the imx_serial.c module to make it
  nominally functional with VxWorks 7. It works well enough to allow the
  boot banner to appear and for the user to interact with the target
  shell.
  
  I'm not submitting this as a patch to the development list as I'm not
  fully certain it complies with the hardware spec and doesn't break any
  other functionality. I would prefer if the maintainer (or someone)
  reviewed it for any issues/refinements first.
  
  I'm attaching the patch to this bug report. A copy can also be obtained
  from:
  
  http://people.freebsd.org/~wpaul/qemu/imx_serial.zip
  
  This patch was generated against QEMU 2.11.0 but also works with QEMU
  2.11.1.

** Description changed:

  The imx_serial.c driver currently implements only partial support for
  the i.MX6 UART hardware. (I understand it's a work in progress and
- that's fine.) In particular, it does not implement support for the
+ that's fine.) dIn particular, it does not implement support for the
  Transmit Complete Interrupt Enable bit in the UCR4 register. The VxWorks
  7 i.MX6 serial driver depends on the behavior of this bit in actual
  hardware in order to send characters through the UART correctly. The
  result is that with the current machine model, VxWorks will boot and run
  in QEMU but it's unable to print any characters to the console serial
  port.
  
  I have produced a small patch for the imx_serial.c module to make it
  nominally functional with VxWorks 7. It works well enough to allow the
  boot banner to appear and for the user to interact with the target
  shell.
  
  I'm not submitting this as a patch to the development list as I'm not
  fully certain it complies with the hardware spec and doesn't break any
  other functionality. I would prefer if the maintainer (or someone)
  reviewed it for any issues/refinements first.
  
  I'm attaching the patch to this bug report. A copy can also be obtained
  from:
  
  http://people.freebsd.org/~wpaul/qemu/imx_serial.zip
  
  This patch was generated against QEMU 2.11.0 but also works with QEMU
  2.11.1.
+ 
+ My host environment is FreeBSD/amd64 11.1-RELEASE 

[Qemu-devel] [Bug 1753309] [NEW] Ethernet interrupt vectors for sabrelite machine are defined backwards

2018-03-04 Thread Bill Paul
Public bug reported:

The sabrelite machine model used by qemu-system-arm is based on the
Freescale/NXP i.MX6Q processor. This SoC has an on-board ethernet
controller which is supported in QEMU using the imx_fec.c module
(actually called imx.enet for this model.)

The include/hw/arm/fsm-imx6.h file defines the interrupt vectors for the
imx.enet device like this:

#define FSL_IMX6_ENET_MAC_1588_IRQ 118
#define FSL_IMX6_ENET_MAC_IRQ 119

However, this is backwards. The reference manual for the i.MX6D/Q
devices can be found here:

https://www.nxp.com/docs/en/reference-manual/IMX6DQRM.pdf

On page 225, in Table 3-1. ARM Cortex A9 domain interrupt summary, it
shows the following:

150 ENET
MAC 0 IRQ, Logical OR of:
MAC 0 Periodic Timer Overflow
MAC 0 Time Stamp Available
MAC 0 Time Stamp Available
MAC 0 Time Stamp Available
MAC 0 Payload Receive Error
MAC 0 Transmit FIFO Underrun
MAC 0 Collision Retry Limit
MAC 0 Late Collision
MAC 0 Ethernet Bus Error
MAC 0 MII Data Transfer Done
MAC 0 Receive Buffer Done
MAC 0 Receive Frame Done
MAC 0 Transmit Buffer Done
MAC 0 Transmit Frame Done
MAC 0 Graceful Stop
MAC 0 Babbling Transmit Error
MAC 0 Babbling Receive Error
MAC 0 Wakeup Request [synchronous]

151 ENET
MAC 0 1588 Timer interrupt [synchronous] request

Note:
150 - 32 == 118
151 - 32 == 119

In other words, the vector definitions in the fsl-imx6.h file are
reversed. The correct definition is:

#define FSL_IMX6_ENET_MAC_IRQ 118
#define FSL_IMX6_ENET_MAC_1588_IRQ 119

I tested the sabrelite simulation using VxWorks 7 (which supports the
SabreLite board) and found that while I was able to send and receive
packet data via the simulated ethernet interface, the VxWorks i.MX6
ethernet driver failed to receive any interrupts. When I corrected the
interrupt vector definitions as shown above and recompiled QEMU,
everything worked as expected. I was able to exchange ICMP packets with
the simulated target and telnet to/from the VxWorks instance running in
the virtual machine. I used the tap interface for this.

As a workaround I was also able to make the ethernet work by modifying
the VxWorks imx6q-sabrelite.dts file to change the ethernet interrupt
property from 150 to 151.

This problem was observed with the following environment:

Host: FreeBSD/amd64 11.1-RELEASE
QEMU version: 2.11.0 and 2.11.1 built from source code

** Affects: qemu
 Importance: Undecided
 Status: New


** Tags: arm imx.enet sabrelite

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

Title:
  Ethernet interrupt vectors for sabrelite machine are defined backwards

Status in QEMU:
  New

Bug description:
  The sabrelite machine model used by qemu-system-arm is based on the
  Freescale/NXP i.MX6Q processor. This SoC has an on-board ethernet
  controller which is supported in QEMU using the imx_fec.c module
  (actually called imx.enet for this model.)

  The include/hw/arm/fsm-imx6.h file defines the interrupt vectors for
  the imx.enet device like this:

  #define FSL_IMX6_ENET_MAC_1588_IRQ 118
  #define FSL_IMX6_ENET_MAC_IRQ 119

  However, this is backwards. The reference manual for the i.MX6D/Q
  devices can be found here:

  https://www.nxp.com/docs/en/reference-manual/IMX6DQRM.pdf

  On page 225, in Table 3-1. ARM Cortex A9 domain interrupt summary, it
  shows the following:

  150 ENET
  MAC 0 IRQ, Logical OR of:
  MAC 0 Periodic Timer Overflow
  MAC 0 Time Stamp Available
  MAC 0 Time Stamp Available
  MAC 0 Time Stamp Available
  MAC 0 Payload Receive Error
  MAC 0 Transmit FIFO Underrun
  MAC 0 Collision Retry Limit
  MAC 0 Late Collision
  MAC 0 Ethernet Bus Error
  MAC 0 MII Data Transfer Done
  MAC 0 Receive Buffer Done
  MAC 0 Receive Frame Done
  MAC 0 Transmit Buffer Done
  MAC 0 Transmit Frame Done
  MAC 0 Graceful Stop
  MAC 0 Babbling Transmit Error
  MAC 0 Babbling Receive Error
  MAC 0 Wakeup Request [synchronous]

  151 ENET
  MAC 0 1588 Timer interrupt [synchronous] request

  Note:
  150 - 32 == 118
  151 - 32 == 119

  In other words, the vector definitions in the fsl-imx6.h file are
  reversed. The correct definition is:

  #define FSL_IMX6_ENET_MAC_IRQ 118
  #define FSL_IMX6_ENET_MAC_1588_IRQ 119

  I tested the sabrelite simulation using VxWorks 7 (which supports the
  SabreLite board) and found that while I was able to send and receive
  packet data via the simulated ethernet interface, the VxWorks i.MX6
  ethernet driver failed to receive any interrupts. When I corrected the
  interrupt vector definitions as shown above and recompiled QEMU,
  everything worked as expected. I was able to exchange ICMP packets
  with the simulated target and telnet to/from the VxWorks instance
  running in the virtual machine. I used the tap interface for this.

  As a workaround I was also able to make the ethernet work by modifying
  the VxWorks imx6q-sabrelite.dts file to change the ethernet interrupt
  property from 150 to 

Re: [Qemu-devel] Problem compiling qemu-2.1.1

2018-03-04 Thread Peter Maydell
On 4 March 2018 at 11:15, Frans de Boer  wrote:
> LS,
>
> I try to compile qemu and get the next error message:
>
> mnt/rhome/frans-tw/data/projects/linux/kernel/qemu/qemu-2.11.1/util/memfd.c:40:12:
> error: static declaration of ‘memfd_create’ follows non-static declaration
>  static int memfd_create(const char *name, unsigned int flags)
> ^~~~
> In file included from /usr/include/bits/mman-linux.h:115:0,
>  from /usr/include/bits/mman.h:45,
>  from /usr/include/sys/mman.h:41,
>  from
> /mnt/rhome/frans-tw/data/projects/linux/kernel/qemu/qemu-2.11.1/include/sysemu/os-posix.h:29,
>  from
> /mnt/rhome/frans-tw/data/projects/linux/kernel/qemu/qemu-2.11.1/include/qemu/osdep.h:104,
>  from
> /mnt/rhome/frans-tw/data/projects/linux/kernel/qemu/qemu-2.11.1/util/memfd.c:28:
> /usr/include/bits/mman-shared.h:46:5: note: previous declaration of
> ‘memfd_create’ was here
>  int memfd_create (const char *__name, unsigned int __flags) __THROW;
>
> I use the newest Tumbleweed of openSuse with the gcc 7.3.0 compiler suite.

Hi -- this looks like a QEMU incompatibility with newer glibc that
we fixed in QEMU commit 75e5b70e6b5dcc4. That didn't quite make
the 2.11.0 release, but will be in 2.12.0.

thanks
-- PMM



Re: [Qemu-devel] Problem compiling qemu-2.11.1

2018-03-04 Thread Thomas Huth
On 04.03.2018 12:15, Frans de Boer wrote:
> LS,
> 
> I try to compile qemu and get the next error message:
> 
> mnt/rhome/frans-tw/data/projects/linux/kernel/qemu/qemu-2.11.1/util/memfd.c:40:12:
> error: static declaration of ‘memfd_create’ follows non-static declaration
>  static int memfd_create(const char *name, unsigned int flags)
>     ^~~~
> In file included from /usr/include/bits/mman-linux.h:115:0,
>  from /usr/include/bits/mman.h:45,
>  from /usr/include/sys/mman.h:41,
>  from
> /mnt/rhome/frans-tw/data/projects/linux/kernel/qemu/qemu-2.11.1/include/sysemu/os-posix.h:29,
> 
>  from
> /mnt/rhome/frans-tw/data/projects/linux/kernel/qemu/qemu-2.11.1/include/qemu/osdep.h:104,
> 
>  from
> /mnt/rhome/frans-tw/data/projects/linux/kernel/qemu/qemu-2.11.1/util/memfd.c:28:
> 
> /usr/include/bits/mman-shared.h:46:5: note: previous declaration of
> ‘memfd_create’ was here
>  int memfd_create (const char *__name, unsigned int __flags) __THROW;
> 
> I use the newest Tumbleweed of openSuse with the gcc 7.3.0 compiler suite.
> 
> Suggestions?

Not sure, but it sounds like you need this patch on top:

https://git.qemu.org/?p=qemu.git;a=commitdiff;h=75e5b70e6b5dcc4f2219992

 HTH,
  Thomas



[Qemu-devel] [PULL 4/5] softfloat: use floatx80_infinity in softfloat

2018-03-04 Thread Laurent Vivier
Since f3218a8 ("softfloat: add floatx80 constants")
floatx80_infinity is defined but never used.

This patch updates floatx80 functions to use
this definition.

This allows to define a different default Infinity
value on m68k: the m68k FPU defines infinity with
all bits set to zero in the mantissa.

Signed-off-by: Laurent Vivier 
Reviewed-by: Richard Henderson 
Message-Id: <20180224201802.911-4-laur...@vivier.eu>
---
 fpu/softfloat-specialize.h | 14 ++
 fpu/softfloat.c| 39 +--
 include/fpu/softfloat.h| 13 +++--
 3 files changed, 50 insertions(+), 16 deletions(-)

diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
index 46126e9e0a..9ccb59422c 100644
--- a/fpu/softfloat-specialize.h
+++ b/fpu/softfloat-specialize.h
@@ -177,6 +177,20 @@ floatx80 floatx80_default_nan(float_status *status)
 return r;
 }
 
+/*
+| The pattern for a default generated extended double-precision inf.
+**/
+
+#define floatx80_infinity_high 0x7FFF
+#if defined(TARGET_M68K)
+#define floatx80_infinity_low  LIT64(0x)
+#else
+#define floatx80_infinity_low  LIT64(0x8000)
+#endif
+
+const floatx80 floatx80_infinity
+= make_floatx80_init(floatx80_infinity_high, floatx80_infinity_low);
+
 /*
 | The pattern for a default generated quadruple-precision NaN.
 **/
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index fb4853682e..e124df9f7e 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -2636,7 +2636,9 @@ floatx80 roundAndPackFloatx80(int8_t roundingPrecision, 
flag zSign,
) {
 return packFloatx80( zSign, 0x7FFE, ~ roundMask );
 }
-return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000 ) );
+return packFloatx80(zSign,
+floatx80_infinity_high,
+floatx80_infinity_low);
 }
 if ( zExp <= 0 ) {
 isTiny =
@@ -3182,7 +3184,9 @@ floatx80 float32_to_floatx80(float32 a, float_status 
*status)
 if (aSig) {
 return commonNaNToFloatx80(float32ToCommonNaN(a, status), status);
 }
-return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000 ) );
+return packFloatx80(aSign,
+floatx80_infinity_high,
+floatx80_infinity_low);
 }
 if ( aExp == 0 ) {
 if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
@@ -4037,7 +4041,9 @@ floatx80 float64_to_floatx80(float64 a, float_status 
*status)
 if (aSig) {
 return commonNaNToFloatx80(float64ToCommonNaN(a, status), status);
 }
-return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000 ) );
+return packFloatx80(aSign,
+floatx80_infinity_high,
+floatx80_infinity_low);
 }
 if ( aExp == 0 ) {
 if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
@@ -4549,10 +4555,7 @@ int64_t floatx80_to_int64(floatx80 a, float_status 
*status)
 if ( shiftCount <= 0 ) {
 if ( shiftCount ) {
 float_raise(float_flag_invalid, status);
-if (! aSign
- || (( aExp == 0x7FFF )
-  && ( aSig != LIT64( 0x8000 ) ) )
-   ) {
+if (!aSign || floatx80_is_any_nan(a)) {
 return LIT64( 0x7FFF );
 }
 return (int64_t) LIT64( 0x8000 );
@@ -4858,7 +4861,9 @@ static floatx80 addFloatx80Sigs(floatx80 a, floatx80 b, 
flag zSign,
 if ((uint64_t)(bSig << 1)) {
 return propagateFloatx80NaN(a, b, status);
 }
-return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000 ) );
+return packFloatx80(zSign,
+floatx80_infinity_high,
+floatx80_infinity_low);
 }
 if ( aExp == 0 ) ++expDiff;
 shift64ExtraRightJamming( aSig, 0, - expDiff, ,  );
@@ -4933,7 +4938,8 @@ static floatx80 subFloatx80Sigs(floatx80 a, floatx80 b, 
flag zSign,
 if ((uint64_t)(bSig << 1)) {
 return propagateFloatx80NaN(a, b, status);
 }
-return packFloatx80( zSign ^ 1, 0x7FFF, LIT64( 0x8000 ) );
+return packFloatx80(zSign ^ 1, floatx80_infinity_high,
+floatx80_infinity_low);
 }
 if ( aExp == 0 ) ++expDiff;
 shift128RightJamming( aSig, 0, - expDiff, ,  );
@@ -5038,7 +5044,8 @@ floatx80 floatx80_mul(floatx80 a, floatx80 b, 

[Qemu-devel] [PULL 5/5] target/m68k: add fscale, fgetman and fgetexp

2018-03-04 Thread Laurent Vivier
Using local m68k floatx80_getman(), floatx80_getexp(), floatx80_scale()
[copied from previous:
Written by Andreas Grabher for Previous, NeXT Computer Emulator.]

Signed-off-by: Laurent Vivier 
Reviewed-by: Richard Henderson 
Message-Id: <20180224201802.911-5-laur...@vivier.eu>
---
 target/m68k/fpu_helper.c |  15 +
 target/m68k/helper.h |   3 +
 target/m68k/softfloat.c  | 144 +++
 target/m68k/softfloat.h  |   3 +
 target/m68k/translate.c  |   9 +++
 5 files changed, 174 insertions(+)

diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
index 8286228b81..cdb9b50462 100644
--- a/target/m68k/fpu_helper.c
+++ b/target/m68k/fpu_helper.c
@@ -542,3 +542,18 @@ void HELPER(frem)(CPUM68KState *env, FPReg *res, FPReg 
*val0, FPReg *val1)
 
 make_quotient(env, res->d);
 }
+
+void HELPER(fgetexp)(CPUM68KState *env, FPReg *res, FPReg *val)
+{
+res->d = floatx80_getexp(val->d, >fp_status);
+}
+
+void HELPER(fgetman)(CPUM68KState *env, FPReg *res, FPReg *val)
+{
+res->d = floatx80_getman(val->d, >fp_status);
+}
+
+void HELPER(fscale)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
+{
+res->d = floatx80_scale(val1->d, val0->d, >fp_status);
+}
diff --git a/target/m68k/helper.h b/target/m68k/helper.h
index 76a0590c9c..c348dced3a 100644
--- a/target/m68k/helper.h
+++ b/target/m68k/helper.h
@@ -65,6 +65,9 @@ DEF_HELPER_3(fmovemd_st_postinc, i32, env, i32, i32)
 DEF_HELPER_3(fmovemd_ld_postinc, i32, env, i32, i32)
 DEF_HELPER_4(fmod, void, env, fp, fp, fp)
 DEF_HELPER_4(frem, void, env, fp, fp, fp)
+DEF_HELPER_3(fgetexp, void, env, fp, fp)
+DEF_HELPER_3(fgetman, void, env, fp, fp)
+DEF_HELPER_4(fscale, void, env, fp, fp, fp)
 
 DEF_HELPER_3(mac_move, void, env, i32, i32)
 DEF_HELPER_3(macmulf, i64, env, i32, i32)
diff --git a/target/m68k/softfloat.c b/target/m68k/softfloat.c
index 8c77757b4e..9cb141900c 100644
--- a/target/m68k/softfloat.c
+++ b/target/m68k/softfloat.c
@@ -22,6 +22,19 @@
 #include "softfloat.h"
 #include "fpu/softfloat-macros.h"
 
+static floatx80 propagateFloatx80NaNOneArg(floatx80 a, float_status *status)
+{
+if (floatx80_is_signaling_nan(a, status)) {
+float_raise(float_flag_invalid, status);
+}
+
+if (status->default_nan_mode) {
+return floatx80_default_nan(status);
+}
+
+return floatx80_maybe_silence_nan(a, status);
+}
+
 /*
  | Returns the modulo remainder of the extended double-precision floating-point
  | value `a' with respect to the corresponding value `b'.
@@ -103,3 +116,134 @@ floatx80 floatx80_mod(floatx80 a, floatx80 b, 
float_status *status)
 normalizeRoundAndPackFloatx80(
 80, zSign, bExp + expDiff, aSig0, aSig1, status);
 }
+
+/*
+ | Returns the mantissa of the extended double-precision floating-point
+ | value `a'.
+ 
**/
+
+floatx80 floatx80_getman(floatx80 a, float_status *status)
+{
+flag aSign;
+int32_t aExp;
+uint64_t aSig;
+
+aSig = extractFloatx80Frac(a);
+aExp = extractFloatx80Exp(a);
+aSign = extractFloatx80Sign(a);
+
+if (aExp == 0x7FFF) {
+if ((uint64_t) (aSig << 1)) {
+return propagateFloatx80NaNOneArg(a , status);
+}
+float_raise(float_flag_invalid , status);
+return floatx80_default_nan(status);
+}
+
+if (aExp == 0) {
+if (aSig == 0) {
+return packFloatx80(aSign, 0, 0);
+}
+normalizeFloatx80Subnormal(aSig, , );
+}
+
+return roundAndPackFloatx80(status->floatx80_rounding_precision, aSign,
+0x3FFF, aSig, 0, status);
+}
+
+/*
+ | Returns the exponent of the extended double-precision floating-point
+ | value `a' as an extended double-precision value.
+ 
**/
+
+floatx80 floatx80_getexp(floatx80 a, float_status *status)
+{
+flag aSign;
+int32_t aExp;
+uint64_t aSig;
+
+aSig = extractFloatx80Frac(a);
+aExp = extractFloatx80Exp(a);
+aSign = extractFloatx80Sign(a);
+
+if (aExp == 0x7FFF) {
+if ((uint64_t) (aSig << 1)) {
+return propagateFloatx80NaNOneArg(a , status);
+}
+float_raise(float_flag_invalid , status);
+return floatx80_default_nan(status);
+}
+
+if (aExp == 0) {
+if (aSig == 0) {
+return packFloatx80(aSign, 0, 0);
+}
+normalizeFloatx80Subnormal(aSig, , );
+}
+
+return int32_to_floatx80(aExp - 0x3FFF, status);
+}
+
+/*
+ | Scales extended double-precision 

[Qemu-devel] [PULL 2/5] softfloat: export some functions

2018-03-04 Thread Laurent Vivier
Move fpu/softfloat-macros.h to include/fpu/

Export floatx80 functions to be used by target floatx80
specific implementations.

Exports:
  propagateFloatx80NaN(), extractFloatx80Frac(),
  extractFloatx80Exp(), extractFloatx80Sign(),
  normalizeFloatx80Subnormal(), packFloatx80(),
  roundAndPackFloatx80(), normalizeRoundAndPackFloatx80()

Also exports packFloat32() that will be used to implement
m68k fsinh, fcos, fsin, ftan operations.

Signed-off-by: Laurent Vivier 
Reviewed-by: Richard Henderson 
Message-Id: <20180224201802.911-2-laur...@vivier.eu>
---
 fpu/softfloat-specialize.h  |   3 +-
 fpu/softfloat.c |  91 +++-
 {fpu => include/fpu}/softfloat-macros.h |  10 +--
 include/fpu/softfloat.h | 121 
 4 files changed, 137 insertions(+), 88 deletions(-)
 rename {fpu => include/fpu}/softfloat-macros.h (98%)

diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
index e81ca001e1..46126e9e0a 100644
--- a/fpu/softfloat-specialize.h
+++ b/fpu/softfloat-specialize.h
@@ -1011,8 +1011,7 @@ static floatx80 commonNaNToFloatx80(commonNaNT a, 
float_status *status)
 | `b' is a signaling NaN, the invalid exception is raised.
 **/
 
-static floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b,
- float_status *status)
+floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
 {
 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
 flag aIsLargerSignificand;
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index e7fb0d357a..fb4853682e 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -93,7 +93,7 @@ this code that are retained.
 | division and square root approximations.  (Can be specialized to target if
 | desired.)
 **/
-#include "softfloat-macros.h"
+#include "fpu/softfloat-macros.h"
 
 /*
 | Functions and definitions to determine:  (1) whether tininess for underflow
@@ -2192,25 +2192,6 @@ static void
 
 }
 
-/*
-| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
-| single-precision floating-point value, returning the result.  After being
-| shifted into the proper positions, the three fields are simply added
-| together to form the result.  This means that any integer portion of `zSig'
-| will be added into the exponent.  Since a properly normalized significand
-| will have an integer portion equal to 1, the `zExp' input should be 1 less
-| than the desired result exponent whenever `zSig' is a complete, normalized
-| significand.
-**/
-
-static inline float32 packFloat32(flag zSign, int zExp, uint32_t zSig)
-{
-
-return make_float32(
-  ( ( (uint32_t) zSign )<<31 ) + ( ( (uint32_t) zExp )<<23 ) + zSig);
-
-}
-
 /*
 | Takes an abstract floating-point value having sign `zSign', exponent `zExp',
 | and significand `zSig', and returns the proper single-precision floating-
@@ -2490,42 +2471,6 @@ static float64
 
 }
 
-/*
-| Returns the fraction bits of the extended double-precision floating-point
-| value `a'.
-**/
-
-static inline uint64_t extractFloatx80Frac( floatx80 a )
-{
-
-return a.low;
-
-}
-
-/*
-| Returns the exponent bits of the extended double-precision floating-point
-| value `a'.
-**/
-
-static inline int32_t extractFloatx80Exp( floatx80 a )
-{
-
-return a.high & 0x7FFF;
-
-}
-
-/*
-| Returns the sign bit of the extended double-precision floating-point value
-| `a'.
-**/
-
-static inline flag extractFloatx80Sign( floatx80 a )
-{
-
-return a.high>>15;
-
-}
-
 /*
 | Normalizes the subnormal extended double-precision floating-point value
 | represented by the denormalized significand `aSig'.  The normalized exponent
@@ -2533,30 +2478,14 @@ static inline flag extractFloatx80Sign( floatx80 a )
 | `zSigPtr', respectively.
 **/
 
-static void
- normalizeFloatx80Subnormal( uint64_t aSig, 

[Qemu-devel] [PULL 1/5] target/m68k: TCGv returned by gen_load() must be freed

2018-03-04 Thread Laurent Vivier
Signed-off-by: Laurent Vivier 
Message-Id: <20180217235920.2254-1-laur...@vivier.eu>
---
 target/m68k/translate.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index 93cd38950e..a22993c7ce 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -2871,6 +2871,7 @@ DISAS_INSN(unlk)
 tcg_gen_mov_i32(reg, tmp);
 tcg_gen_addi_i32(QREG_SP, src, 4);
 tcg_temp_free(src);
+tcg_temp_free(tmp);
 }
 
 #if defined(CONFIG_SOFTMMU)
@@ -3148,6 +3149,9 @@ DISAS_INSN(subx_mem)
 gen_subx(s, src, dest, opsize);
 
 gen_store(s, opsize, addr_dest, QREG_CC_N, IS_USER(s));
+
+tcg_temp_free(dest);
+tcg_temp_free(src);
 }
 
 DISAS_INSN(mov3q)
@@ -3354,6 +3358,9 @@ DISAS_INSN(addx_mem)
 gen_addx(s, src, dest, opsize);
 
 gen_store(s, opsize, addr_dest, QREG_CC_N, IS_USER(s));
+
+tcg_temp_free(dest);
+tcg_temp_free(src);
 }
 
 static inline void shift_im(DisasContext *s, uint16_t insn, int opsize)
@@ -4398,6 +4405,8 @@ DISAS_INSN(chk2)
 gen_flush_flags(s);
 gen_helper_chk2(cpu_env, reg, bound1, bound2);
 tcg_temp_free(reg);
+tcg_temp_free(bound1);
+tcg_temp_free(bound2);
 }
 
 static void m68k_copy_line(TCGv dst, TCGv src, int index)
@@ -4547,6 +4556,7 @@ DISAS_INSN(moves)
 } else {
 gen_partset_reg(opsize, reg, tmp);
 }
+tcg_temp_free(tmp);
 }
 switch (extract32(insn, 3, 3)) {
 case 3: /* Indirect postincrement.  */
@@ -5537,6 +5547,7 @@ DISAS_INSN(mac)
 case 4: /* Pre-decrement.  */
 tcg_gen_mov_i32(AREG(insn, 0), addr);
 }
+tcg_temp_free(loadval);
 }
 }
 
-- 
2.14.3




[Qemu-devel] [PULL 3/5] target/m68k: add fmod/frem

2018-03-04 Thread Laurent Vivier
Using a local m68k floatx80_mod()
[copied from previous:
Written by Andreas Grabher for Previous, NeXT Computer Emulator.]

The quotient byte of the FPSR is updated with
the result of the operation.

Signed-off-by: Laurent Vivier 
Reviewed-by: Richard Henderson 
Message-Id: <20180224201802.911-3-laur...@vivier.eu>
---
 target/m68k/Makefile.objs |   3 +-
 target/m68k/cpu.h |   1 +
 target/m68k/fpu_helper.c  |  35 +++-
 target/m68k/helper.h  |   2 +
 target/m68k/softfloat.c   | 105 ++
 target/m68k/softfloat.h   |  26 
 target/m68k/translate.c   |   6 +++
 7 files changed, 176 insertions(+), 2 deletions(-)
 create mode 100644 target/m68k/softfloat.c
 create mode 100644 target/m68k/softfloat.h

diff --git a/target/m68k/Makefile.objs b/target/m68k/Makefile.objs
index d143f20270..ac61948676 100644
--- a/target/m68k/Makefile.objs
+++ b/target/m68k/Makefile.objs
@@ -1,4 +1,5 @@
 obj-y += m68k-semi.o
-obj-y += translate.o op_helper.o helper.o cpu.o fpu_helper.o
+obj-y += translate.o op_helper.o helper.o cpu.o
+obj-y += fpu_helper.o softfloat.o
 obj-y += gdbstub.o
 obj-$(CONFIG_SOFTMMU) += monitor.o
diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h
index 65f4fb95cb..2259bf22dc 100644
--- a/target/m68k/cpu.h
+++ b/target/m68k/cpu.h
@@ -427,6 +427,7 @@ typedef enum {
 /* Quotient */
 
 #define FPSR_QT_MASK  0x00ff
+#define FPSR_QT_SHIFT 16
 
 /* Floating-Point Control Register */
 /* Rounding mode */
diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
index 3c5a82aaa0..8286228b81 100644
--- a/target/m68k/fpu_helper.c
+++ b/target/m68k/fpu_helper.c
@@ -23,7 +23,7 @@
 #include "exec/helper-proto.h"
 #include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
-#include "fpu/softfloat.h"
+#include "softfloat.h"
 
 /* Undefined offsets may be different on various FPU.
  * On 68040 they return 0.0 (floatx80_zero)
@@ -509,3 +509,36 @@ uint32_t HELPER(fmovemd_ld_postinc)(CPUM68KState *env, 
uint32_t addr,
 {
 return fmovem_postinc(env, addr, mask, cpu_ld_float64_ra);
 }
+
+static void make_quotient(CPUM68KState *env, floatx80 val)
+{
+int32_t quotient;
+int sign;
+
+if (floatx80_is_any_nan(val)) {
+return;
+}
+
+quotient = floatx80_to_int32(val, >fp_status);
+sign = quotient < 0;
+if (sign) {
+quotient = -quotient;
+}
+
+quotient = (sign << 7) | (quotient & 0x7f);
+env->fpsr = (env->fpsr & ~FPSR_QT_MASK) | (quotient << FPSR_QT_SHIFT);
+}
+
+void HELPER(fmod)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
+{
+res->d = floatx80_mod(val1->d, val0->d, >fp_status);
+
+make_quotient(env, res->d);
+}
+
+void HELPER(frem)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
+{
+res->d = floatx80_rem(val1->d, val0->d, >fp_status);
+
+make_quotient(env, res->d);
+}
diff --git a/target/m68k/helper.h b/target/m68k/helper.h
index 7f400f0def..76a0590c9c 100644
--- a/target/m68k/helper.h
+++ b/target/m68k/helper.h
@@ -63,6 +63,8 @@ DEF_HELPER_3(fmovemx_ld_postinc, i32, env, i32, i32)
 DEF_HELPER_3(fmovemd_st_predec, i32, env, i32, i32)
 DEF_HELPER_3(fmovemd_st_postinc, i32, env, i32, i32)
 DEF_HELPER_3(fmovemd_ld_postinc, i32, env, i32, i32)
+DEF_HELPER_4(fmod, void, env, fp, fp, fp)
+DEF_HELPER_4(frem, void, env, fp, fp, fp)
 
 DEF_HELPER_3(mac_move, void, env, i32, i32)
 DEF_HELPER_3(macmulf, i64, env, i32, i32)
diff --git a/target/m68k/softfloat.c b/target/m68k/softfloat.c
new file mode 100644
index 00..8c77757b4e
--- /dev/null
+++ b/target/m68k/softfloat.c
@@ -0,0 +1,105 @@
+/*
+ * Ported from a work by Andreas Grabher for Previous, NeXT Computer Emulator,
+ * derived from NetBSD M68040 FPSP functions,
+ * derived from release 2a of the SoftFloat IEC/IEEE Floating-point Arithmetic
+ * Package. Those parts of the code (and some later contributions) are
+ * provided under that license, as detailed below.
+ * It has subsequently been modified by contributors to the QEMU Project,
+ * so some portions are provided under:
+ *  the SoftFloat-2a license
+ *  the BSD license
+ *  GPL-v2-or-later
+ *
+ * Any future contributions to this file will be taken to be licensed under
+ * the Softfloat-2a license unless specifically indicated otherwise.
+ */
+
+/* Portions of this work are 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 "softfloat.h"
+#include "fpu/softfloat-macros.h"
+
+/*
+ | Returns the modulo remainder of the extended double-precision floating-point
+ | value `a' with respect to the corresponding value `b'.
+ 
**/
+
+floatx80 floatx80_mod(floatx80 a, floatx80 b, float_status *status)
+{
+flag aSign, zSign;
+int32_t aExp, bExp, expDiff;

[Qemu-devel] [PULL 0/5] M68k for 2.12 patches

2018-03-04 Thread Laurent Vivier
The following changes since commit 136c67e07869227b21b3f627316e03679ce7b738:

  Merge remote-tracking branch 
'remotes/bkoppelmann/tags/pull-tricore-2018-03-02' into staging (2018-03-02 
16:56:20 +)

are available in the Git repository at:

  git://github.com/vivier/qemu-m68k.git tags/m68k-for-2.12-pull-request

for you to fetch changes up to 0d379c1709aa6b2d09dd3b493bfdf3a5fe6debcd:

  target/m68k: add fscale, fgetman and fgetexp (2018-03-04 17:27:59 +0100)





Laurent Vivier (5):
  target/m68k: TCGv returned by gen_load() must be freed
  softfloat: export some functions
  target/m68k: add fmod/frem
  softfloat: use floatx80_infinity in softfloat
  target/m68k: add fscale, fgetman and fgetexp

 fpu/softfloat-specialize.h  |  17 ++-
 fpu/softfloat.c | 130 +
 {fpu => include/fpu}/softfloat-macros.h |  10 +-
 include/fpu/softfloat.h | 134 -
 target/m68k/Makefile.objs   |   3 +-
 target/m68k/cpu.h   |   1 +
 target/m68k/fpu_helper.c|  50 ++-
 target/m68k/helper.h|   5 +
 target/m68k/softfloat.c | 249 
 target/m68k/softfloat.h |  29 
 target/m68k/translate.c |  26 
 11 files changed, 548 insertions(+), 106 deletions(-)
 rename {fpu => include/fpu}/softfloat-macros.h (98%)
 create mode 100644 target/m68k/softfloat.c
 create mode 100644 target/m68k/softfloat.h

-- 
2.14.3




[Qemu-devel] [PATCH] s390x/sclpconsole: Remove dead code - make _error functions void

2018-03-04 Thread Nia Alarie
These functions always return 0. By changing their return type to
void, some dead code can be removed.

Signed-off-by: Nia Alarie 
---
 hw/char/sclpconsole-lm.c  | 3 +--
 hw/char/sclpconsole.c | 3 +--
 hw/s390x/event-facility.c | 6 +-
 hw/s390x/virtio-ccw.c | 6 +++---
 hw/s390x/virtio-ccw.h | 2 +-
 include/hw/s390x/event-facility.h | 2 +-
 6 files changed, 8 insertions(+), 14 deletions(-)

diff --git a/hw/char/sclpconsole-lm.c b/hw/char/sclpconsole-lm.c
index c500bdaf29..7a02db54b8 100644
--- a/hw/char/sclpconsole-lm.c
+++ b/hw/char/sclpconsole-lm.c
@@ -318,9 +318,8 @@ static int console_init(SCLPEvent *event)
 return 0;
 }
 
-static int console_exit(SCLPEvent *event)
+static void console_exit(SCLPEvent *event)
 {
-return 0;
 }
 
 static void console_reset(DeviceState *dev)
diff --git a/hw/char/sclpconsole.c b/hw/char/sclpconsole.c
index d0265dfa7a..e2a80dd2dd 100644
--- a/hw/char/sclpconsole.c
+++ b/hw/char/sclpconsole.c
@@ -246,9 +246,8 @@ static void console_reset(DeviceState *dev)
scon->notify = false;
 }
 
-static int console_exit(SCLPEvent *event)
+static void console_exit(SCLPEvent *event)
 {
-return 0;
 }
 
 static Property console_properties[] = {
diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c
index 155a69467b..4263d28012 100644
--- a/hw/s390x/event-facility.c
+++ b/hw/s390x/event-facility.c
@@ -436,11 +436,7 @@ static void event_unrealize(DeviceState *qdev, Error 
**errp)
 SCLPEvent *event = SCLP_EVENT(qdev);
 SCLPEventClass *child = SCLP_EVENT_GET_CLASS(event);
 if (child->exit) {
-int rc = child->exit(event);
-if (rc < 0) {
-error_setg(errp, "SCLP event exit failed.");
-return;
-}
+child->exit(event);
 }
 }
 
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index 8f7fbc2ab7..0773818a82 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -752,7 +752,7 @@ out_err:
 g_free(sch);
 }
 
-static int virtio_ccw_exit(VirtioCcwDevice *dev)
+static void virtio_ccw_exit(VirtioCcwDevice *dev)
 {
 CcwDevice *ccw_dev = CCW_DEVICE(dev);
 SubchDev *sch = ccw_dev->sch;
@@ -765,7 +765,6 @@ static int virtio_ccw_exit(VirtioCcwDevice *dev)
 release_indicator(>routes.adapter, dev->indicators);
 dev->indicators = NULL;
 }
-return 0;
 }
 
 static void virtio_ccw_net_realize(VirtioCcwDevice *ccw_dev, Error **errp)
@@ -1710,7 +1709,8 @@ static int virtio_ccw_busdev_exit(DeviceState *dev)
 VirtioCcwDevice *_dev = (VirtioCcwDevice *)dev;
 VirtIOCCWDeviceClass *_info = VIRTIO_CCW_DEVICE_GET_CLASS(dev);
 
-return _info->exit(_dev);
+_info->exit(_dev);
+return 0;
 }
 
 static void virtio_ccw_busdev_unplug(HotplugHandler *hotplug_dev,
diff --git a/hw/s390x/virtio-ccw.h b/hw/s390x/virtio-ccw.h
index 3905f3a3d6..8ffe7fe095 100644
--- a/hw/s390x/virtio-ccw.h
+++ b/hw/s390x/virtio-ccw.h
@@ -76,7 +76,7 @@ typedef struct VirtioCcwDevice VirtioCcwDevice;
 typedef struct VirtIOCCWDeviceClass {
 CCWDeviceClass parent_class;
 void (*realize)(VirtioCcwDevice *dev, Error **errp);
-int (*exit)(VirtioCcwDevice *dev);
+void (*exit)(VirtioCcwDevice *dev);
 } VirtIOCCWDeviceClass;
 
 /* Performance improves when virtqueue kick processing is decoupled from the
diff --git a/include/hw/s390x/event-facility.h 
b/include/hw/s390x/event-facility.h
index 5119b9b7f0..833f12a5e7 100644
--- a/include/hw/s390x/event-facility.h
+++ b/include/hw/s390x/event-facility.h
@@ -174,7 +174,7 @@ typedef struct SCLPEvent {
 typedef struct SCLPEventClass {
 DeviceClass parent_class;
 int (*init)(SCLPEvent *event);
-int (*exit)(SCLPEvent *event);
+void (*exit)(SCLPEvent *event);
 
 /* get SCLP's send mask */
 unsigned int (*get_send_mask)(void);
-- 
2.16.2




Re: [Qemu-devel] [virtio-dev] [PATCH 4/4] virtio-net: add linkspeed and duplex settings to virtio-net

2018-03-04 Thread Yan Vugenfirer


> On 2 Mar 2018, at 22:19, Michael S. Tsirkin  wrote:
> 
> On Fri, Mar 02, 2018 at 03:14:01PM +0800, Jason Wang wrote:
>> 
>> 
>> On 2018年03月02日 11:46, Jason Baron wrote:
>>> Although linkspeed and duplex can be set in a linux guest via 'ethtool -s',
>>> this requires custom ethtool commands for virtio-net by default.
>>> 
>>> Introduce a new feature flag, VIRTIO_NET_F_SPEED_DUPLEX, which allows
>>> the hypervisor to export a linkspeed and duplex setting. The user can
>>> subsequently overwrite it later if desired via: 'ethtool -s'.
>>> 
>>> Linkspeed and duplex settings can be set as:
>>> '-device virtio-net,speed=1,duplex=full'
>> 
>> I was thinking whether or not it's better to decide the duplex by the type
>> of backends.
>> 
>> E.g userspace and vhost-kernel implement a in fact half duplex. But dpdk
>> implement a full duplex.
>> 
>> Thanks
> 
> OTOH it's a priority for some people to be able to support migration
> between different backend types. Breaking that won't be nice.

I think that in this case we need a way to update the settings of link speed 
and link duplex (maybe add QMP command). Migration between different backend 
types should cause link down\link up events. And this is a time for a driver to 
re-read the settings and update the OS.

Best regards,
Yan.

> 
>>> 
>>> where speed is [0...INT_MAX], and duplex is ["half"|"full"].
>>> 
>>> Signed-off-by: Jason Baron
>>> Cc: "Michael S. Tsirkin"
>>> Cc: Jason Wang
>>> Cc:virtio-...@lists.oasis-open.org
>>> ---
> 
> -
> To unsubscribe, e-mail: virtio-dev-unsubscr...@lists.oasis-open.org
> For additional commands, e-mail: virtio-dev-h...@lists.oasis-open.org



[Qemu-devel] Problem compiling qemu-2.1.1

2018-03-04 Thread Frans de Boer

LS,

I try to compile qemu and get the next error message:

mnt/rhome/frans-tw/data/projects/linux/kernel/qemu/qemu-2.11.1/util/memfd.c:40:12: 
error: static declaration of ‘memfd_create’ follows non-static declaration

 static int memfd_create(const char *name, unsigned int flags)
^~~~
In file included from /usr/include/bits/mman-linux.h:115:0,
 from /usr/include/bits/mman.h:45,
 from /usr/include/sys/mman.h:41,
 from 
/mnt/rhome/frans-tw/data/projects/linux/kernel/qemu/qemu-2.11.1/include/sysemu/os-posix.h:29,
 from 
/mnt/rhome/frans-tw/data/projects/linux/kernel/qemu/qemu-2.11.1/include/qemu/osdep.h:104,
 from 
/mnt/rhome/frans-tw/data/projects/linux/kernel/qemu/qemu-2.11.1/util/memfd.c:28:
/usr/include/bits/mman-shared.h:46:5: note: previous declaration of 
‘memfd_create’ was here

 int memfd_create (const char *__name, unsigned int __flags) __THROW;

I use the newest Tumbleweed of openSuse with the gcc 7.3.0 compiler suite.

Suggestions?

Regards,
Frans.