[RESEND PATCH v12 1/4] hw/arm/sysbus-fdt: helpers for platform bus nodes addition

2015-05-27 Thread Eric Auger
This new C module will be used by ARM machine files to generate
platform bus node and their dynamic sysbus device tree nodes.

Dynamic sysbus device node addition is done in a machine init
done notifier. arm_register_platform_bus_fdt_creator does the
registration of this latter and is supposed to be called by
ARM machine files that support platform bus and their dynamic
sysbus. Addition of dynamic sysbus nodes is done only if the
user did not provide any dtb.

Signed-off-by: Alexander Graf ag...@suse.de
Signed-off-by: Eric Auger eric.au...@linaro.org
Reviewed-by: Shannon Zhao zhaoshengl...@huawei.com
Reviewed-by: Alexander Graf ag...@suse.de
Reviewed-by: Alex Bennée alex.ben...@linaro.org

---
v11 - v12:
- resolve conflict introduced by netduino2.o addition in
  hw/arm/Makefile.objs
- Add Alex R-b

v9 - v10:
- add assert and exit in add_fdt_node

v8 - v9:
- s/Fdt/FDT in struct type names
- reorder fields in PlatformBusFdtNotifierParams and use DO_UPCAST
  instead of container_of
- use assert() when relevant (board model issue)
- g_free the ARMPlatformBusFDTParams and PlatformBusFDTNotifierParams
  pointers in platform_bus_fdt_notify

v7 - v8:
add Reviewed-by from Alex and Shannon

v6 - v7:
- revert indentation in add_fdt_node_functions

v5 - v6:
- add_all_platform_bus_fdt_nodes is not a modify_dtb function anymore
- it now takes a handle to an ARMPlatformBusFdtParams.
- fdt pointer is checked in case this notifier is executed after the
  one that executes the load_dtb (this latter deallocates the fdt pointer)
- check of fdt_filename moved in here.
- upgrade_dtb is removed
- copyright aligned between .h and .c

v4 - v5:
- change indentation in add_fdt_node_functions. Also becomes a
  static const.
- ARMPlatformBusFdtParams.system_params becomes a pointer to
  a const ARMPlatformBusSystemParams
- removes platform-bus.h second inclusion

v3 - v4:
- dyn_sysbus_devtree.c renamed into sysbus-fdt.c
- use new PlatformBusDevice object
- the dtb upgrade is done through modify_dtb. Before the fdt
  was recreated from scratch. When the user provided a dtb this
  latter was overwritten which was not correct.
- an array contains the association between device type names
  and their node creation function
- I must aknowledge I did not find any cleaner way to implement
  a FDT_BUILDER interface, as suggested by Paolo. The class method
  would need to be initialized somewhere and since it cannot
  happen in the device itself - according to Alex  Peter comments -,
  I don't see when I shall associate the device type and its
  interface implementation.

v2 - v3:
- add arm_ prefix
- arm_sysbus_device_create_devtree becomes static

v1 - v2:
- Code moved in an arch specific file to accomodate architecture
  dependent specificities.
- remove platform_bus_base from PlatformDevtreeData

v1: code originally written by Alex Graf in e500.c and reused for
ARM [Eric Auger]
---
 hw/arm/Makefile.objs|   1 +
 hw/arm/sysbus-fdt.c | 174 
 include/hw/arm/sysbus-fdt.h |  60 +++
 3 files changed, 235 insertions(+)
 create mode 100644 hw/arm/sysbus-fdt.c
 create mode 100644 include/hw/arm/sysbus-fdt.h

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index a75a182..72bb04d 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -4,6 +4,7 @@ obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o
 obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o
 obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o
 obj-y += netduino2.o
+obj-y += sysbus-fdt.o
 
 obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
 obj-$(CONFIG_DIGIC) += digic.o
diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c
new file mode 100644
index 000..3038b94
--- /dev/null
+++ b/hw/arm/sysbus-fdt.c
@@ -0,0 +1,174 @@
+/*
+ * ARM Platform Bus device tree generation helpers
+ *
+ * Copyright (c) 2014 Linaro Limited
+ *
+ * Authors:
+ *  Alex Graf ag...@suse.de
+ *  Eric Auger eric.au...@linaro.org
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see http://www.gnu.org/licenses/.
+ *
+ */
+
+#include hw/arm/sysbus-fdt.h
+#include qemu/error-report.h
+#include sysemu/device_tree.h
+#include hw/platform-bus.h
+#include sysemu/sysemu.h
+
+/*
+ * internal struct that contains the information to create dynamic
+ * sysbus device node
+ */
+typedef struct PlatformBusFDTData {
+void *fdt; /* device tree handle */
+int irq_start; 

[PATCH v16 3/9] hw/vfio/platform: calxeda xgmac device

2015-05-27 Thread Eric Auger
The platform device class has become abstract. This patch introduces
a calxeda xgmac device that derives from it.

Signed-off-by: Eric Auger eric.au...@linaro.org
Reviewed-by: Alex Bennée alex.ben...@linaro.org

---
v15 - v16:
- added Vikram's T-b

v10 - v11:
- add Alex Reviewed-by
- move virt modifications in a separate patch

v8 - v9:
- renamed calxeda_xgmac.c into calxeda-xgmac.c

v7 - v8:
- add a comment in the header about the MMIO regions and IRQ which
  are exposed by the device

v5 - v6
- back again following Alex Graf advises
- fix a bug related to compat override

v4 - v5:
removed since device tree was moved to hw/arm/dyn_sysbus_devtree.c

v4: creation for device tree specialization
---
 hw/vfio/Makefile.objs|  1 +
 hw/vfio/calxeda-xgmac.c  | 54 
 include/hw/vfio/vfio-calxeda-xgmac.h | 46 ++
 3 files changed, 101 insertions(+)
 create mode 100644 hw/vfio/calxeda-xgmac.c
 create mode 100644 include/hw/vfio/vfio-calxeda-xgmac.h

diff --git a/hw/vfio/Makefile.objs b/hw/vfio/Makefile.objs
index c5c76fe..d540c9d 100644
--- a/hw/vfio/Makefile.objs
+++ b/hw/vfio/Makefile.objs
@@ -2,4 +2,5 @@ ifeq ($(CONFIG_LINUX), y)
 obj-$(CONFIG_SOFTMMU) += common.o
 obj-$(CONFIG_PCI) += pci.o
 obj-$(CONFIG_SOFTMMU) += platform.o
+obj-$(CONFIG_SOFTMMU) += calxeda-xgmac.o
 endif
diff --git a/hw/vfio/calxeda-xgmac.c b/hw/vfio/calxeda-xgmac.c
new file mode 100644
index 000..c4b8fef
--- /dev/null
+++ b/hw/vfio/calxeda-xgmac.c
@@ -0,0 +1,54 @@
+/*
+ * calxeda xgmac VFIO device
+ *
+ * Copyright Linaro Limited, 2014
+ *
+ * Authors:
+ *  Eric Auger eric.au...@linaro.org
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include hw/vfio/vfio-calxeda-xgmac.h
+
+static void calxeda_xgmac_realize(DeviceState *dev, Error **errp)
+{
+VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(dev);
+VFIOCalxedaXgmacDeviceClass *k = VFIO_CALXEDA_XGMAC_DEVICE_GET_CLASS(dev);
+
+vdev-compat = g_strdup(calxeda,hb-xgmac);
+
+k-parent_realize(dev, errp);
+}
+
+static const VMStateDescription vfio_platform_vmstate = {
+.name = TYPE_VFIO_CALXEDA_XGMAC,
+.unmigratable = 1,
+};
+
+static void vfio_calxeda_xgmac_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+VFIOCalxedaXgmacDeviceClass *vcxc =
+VFIO_CALXEDA_XGMAC_DEVICE_CLASS(klass);
+vcxc-parent_realize = dc-realize;
+dc-realize = calxeda_xgmac_realize;
+dc-desc = VFIO Calxeda XGMAC;
+}
+
+static const TypeInfo vfio_calxeda_xgmac_dev_info = {
+.name = TYPE_VFIO_CALXEDA_XGMAC,
+.parent = TYPE_VFIO_PLATFORM,
+.instance_size = sizeof(VFIOCalxedaXgmacDevice),
+.class_init = vfio_calxeda_xgmac_class_init,
+.class_size = sizeof(VFIOCalxedaXgmacDeviceClass),
+};
+
+static void register_calxeda_xgmac_dev_type(void)
+{
+type_register_static(vfio_calxeda_xgmac_dev_info);
+}
+
+type_init(register_calxeda_xgmac_dev_type)
diff --git a/include/hw/vfio/vfio-calxeda-xgmac.h 
b/include/hw/vfio/vfio-calxeda-xgmac.h
new file mode 100644
index 000..f994775
--- /dev/null
+++ b/include/hw/vfio/vfio-calxeda-xgmac.h
@@ -0,0 +1,46 @@
+/*
+ * VFIO calxeda xgmac device
+ *
+ * Copyright Linaro Limited, 2014
+ *
+ * Authors:
+ *  Eric Auger eric.au...@linaro.org
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef HW_VFIO_VFIO_CALXEDA_XGMAC_H
+#define HW_VFIO_VFIO_CALXEDA_XGMAC_H
+
+#include hw/vfio/vfio-platform.h
+
+#define TYPE_VFIO_CALXEDA_XGMAC vfio-calxeda-xgmac
+
+/**
+ * This device exposes:
+ * - a single MMIO region corresponding to its register space
+ * - 3 IRQS (main and 2 power related IRQs)
+ */
+typedef struct VFIOCalxedaXgmacDevice {
+VFIOPlatformDevice vdev;
+} VFIOCalxedaXgmacDevice;
+
+typedef struct VFIOCalxedaXgmacDeviceClass {
+/* private */
+VFIOPlatformDeviceClass parent_class;
+/* public */
+DeviceRealize parent_realize;
+} VFIOCalxedaXgmacDeviceClass;
+
+#define VFIO_CALXEDA_XGMAC_DEVICE(obj) \
+ OBJECT_CHECK(VFIOCalxedaXgmacDevice, (obj), TYPE_VFIO_CALXEDA_XGMAC)
+#define VFIO_CALXEDA_XGMAC_DEVICE_CLASS(klass) \
+ OBJECT_CLASS_CHECK(VFIOCalxedaXgmacDeviceClass, (klass), \
+TYPE_VFIO_CALXEDA_XGMAC)
+#define VFIO_CALXEDA_XGMAC_DEVICE_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(VFIOCalxedaXgmacDeviceClass, (obj), \
+  TYPE_VFIO_CALXEDA_XGMAC)
+
+#endif
-- 
1.8.3.2

___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


[PATCH v16 2/9] hw/vfio/platform: add irq assignment

2015-05-27 Thread Eric Auger
This patch adds the code requested to assign interrupts to
a guest. The interrupts are mediated through user handled
eventfds only.

Signed-off-by: Eric Auger eric.au...@linaro.org
Tested-by: Vikram Sethi vikr...@codeaurora.org

---
v15 - v16:
- added Vikram's T-b

v13 - v14:
- remove virtualID field in header

v12 - v13:
- start user-side eventfd handling at realize time
- remove start_irq_fn

v10 - v11:
- use block declaration when possible
- change order of vfio_platform_eoi vs vfio_intp_interrupt
- introduce vfio_intp_inject_pending_lockheld following Alex Bennee
  comments
- remove unmasking/masked when setting up VFIO signaling
- remove unused kvm_accel member in VFIOINTp struct
- add flags member in VFIOINTp in order to properly discriminate
  edge/level-sensitive IRQs; unmask the physical IRQ only in case of
  level-sensitive IRQ
- some comment rewording

v8 - v9:
- free irq related resources in case of error in vfio_populate_device
---
 hw/vfio/platform.c  | 331 +++-
 include/hw/vfio/vfio-platform.h |  31 
 trace-events|   7 +
 3 files changed, 368 insertions(+), 1 deletion(-)

diff --git a/hw/vfio/platform.c b/hw/vfio/platform.c
index 569a675..35266a8 100644
--- a/hw/vfio/platform.c
+++ b/hw/vfio/platform.c
@@ -22,10 +22,299 @@
 #include qemu/range.h
 #include sysemu/sysemu.h
 #include exec/memory.h
+#include qemu/queue.h
 #include hw/sysbus.h
 #include trace.h
 #include hw/platform-bus.h
 
+/*
+ * Functions used whatever the injection method
+ */
+
+/**
+ * vfio_init_intp - allocate, initialize the IRQ struct pointer
+ * and add it into the list of IRQs
+ * @vbasedev: the VFIO device handle
+ * @info: irq info struct retrieved from VFIO driver
+ */
+static VFIOINTp *vfio_init_intp(VFIODevice *vbasedev,
+struct vfio_irq_info info)
+{
+int ret;
+VFIOPlatformDevice *vdev =
+container_of(vbasedev, VFIOPlatformDevice, vbasedev);
+SysBusDevice *sbdev = SYS_BUS_DEVICE(vdev);
+VFIOINTp *intp;
+
+intp = g_malloc0(sizeof(*intp));
+intp-vdev = vdev;
+intp-pin = info.index;
+intp-flags = info.flags;
+intp-state = VFIO_IRQ_INACTIVE;
+
+sysbus_init_irq(sbdev, intp-qemuirq);
+
+/* Get an eventfd for trigger */
+ret = event_notifier_init(intp-interrupt, 0);
+if (ret) {
+g_free(intp);
+error_report(vfio: Error: trigger event_notifier_init failed );
+return NULL;
+}
+
+QLIST_INSERT_HEAD(vdev-intp_list, intp, next);
+return intp;
+}
+
+/**
+ * vfio_set_trigger_eventfd - set VFIO eventfd handling
+ *
+ * @intp: IRQ struct handle
+ * @handler: handler to be called on eventfd signaling
+ *
+ * Setup VFIO signaling and attach an optional user-side handler
+ * to the eventfd
+ */
+static int vfio_set_trigger_eventfd(VFIOINTp *intp,
+eventfd_user_side_handler_t handler)
+{
+VFIODevice *vbasedev = intp-vdev-vbasedev;
+struct vfio_irq_set *irq_set;
+int argsz, ret;
+int32_t *pfd;
+
+argsz = sizeof(*irq_set) + sizeof(*pfd);
+irq_set = g_malloc0(argsz);
+irq_set-argsz = argsz;
+irq_set-flags = VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER;
+irq_set-index = intp-pin;
+irq_set-start = 0;
+irq_set-count = 1;
+pfd = (int32_t *)irq_set-data;
+*pfd = event_notifier_get_fd(intp-interrupt);
+qemu_set_fd_handler(*pfd, (IOHandler *)handler, NULL, intp);
+ret = ioctl(vbasedev-fd, VFIO_DEVICE_SET_IRQS, irq_set);
+g_free(irq_set);
+if (ret  0) {
+error_report(vfio: Failed to set trigger eventfd: %m);
+qemu_set_fd_handler(*pfd, NULL, NULL, NULL);
+}
+return ret;
+}
+
+/*
+ * Functions only used when eventfds are handled on user-side
+ * ie. without irqfd
+ */
+
+/**
+ * vfio_mmap_set_enabled - enable/disable the fast path mode
+ * @vdev: the VFIO platform device
+ * @enabled: the target mmap state
+ *
+ * enabled = true ~ fast path = MMIO region is mmaped (no KVM TRAP);
+ * enabled = false ~ slow path = MMIO region is trapped and region callbacks
+ * are called; slow path enables to trap the device IRQ status register reset
+*/
+
+static void vfio_mmap_set_enabled(VFIOPlatformDevice *vdev, bool enabled)
+{
+int i;
+
+trace_vfio_platform_mmap_set_enabled(enabled);
+
+for (i = 0; i  vdev-vbasedev.num_regions; i++) {
+VFIORegion *region = vdev-regions[i];
+
+memory_region_set_enabled(region-mmap_mem, enabled);
+}
+}
+
+/**
+ * vfio_intp_mmap_enable - timer function, restores the fast path
+ * if there is no more active IRQ
+ * @opaque: actually points to the VFIO platform device
+ *
+ * Called on mmap timer timout, this function checks whether the
+ * IRQ is still active and if not, restores the fast path.
+ * by construction a single eventfd is handled at a time.
+ * if the IRQ is still active, the timer is re-programmed.
+ */
+static void vfio_intp_mmap_enable(void *opaque)

[PATCH v16 1/9] hw/vfio/platform: vfio-platform skeleton

2015-05-27 Thread Eric Auger
Minimal VFIO platform implementation supporting register space
user mapping but not IRQ assignment.

Signed-off-by: Kim Phillips kim.phill...@linaro.org
Signed-off-by: Eric Auger eric.au...@linaro.org
Tested-by: Vikram Sethi vikr...@codeaurora.org

---
v15 - v16:
- added Vikram's T-b

v14 - v15:
- vfio_platform_compute_needs_reset now returns true while
  vfio_platform_hot_reset_multi returns -1
- adjust g_malloc0_n usage

v13 - v14:
- fix ENAMETOOLONG error path sign

v12 - v13:
- check device name does not contain any /
- handle case where readlink fully fills the buffer
- in vfio_map_region declare size as uint64_t

v11 - v12:
- add x-mmap property definition, without which the default value of
  vbasedev.allow_mmap is false, hence preventing the reg space from
  being mapped.

v10 - v11:
x Take into account Alex Bennee's comments:
- use g_malloc0_n instead of g_malloc0
- use block declarations when possible
- rework readlink returned value treatment
- use g_strlcat in place of strncat
x use g_snprintf in place of snprintf
x correct error handling in vfio_populate_device,
  in case of flag not corresponding to platform device
x various cosmetic changes

v9 - v10:
- vfio_populate_device no more called in common vfio_get_device
  but in vfio_base_device_init

v8 - v9:
- irq management is moved into a separate patch to ease the review
- VFIO_DEVICE_FLAGS_PLATFORM is checked in vfio_populate_device
- g_free of regions added in vfio_populate_device error label
- virtualID becomes 32b

v7 - v8:
- change proto of vfio_platform_compute_needs_reset and sets
  vbasedev-needs_reset to false there
- vfio_[un]mask_irqindex renamed into vfio_[un]mask_single_irqindex
- vfio_register_irq_starter renamed into vfio_kick_irqs
  we now use a reset notifier instead of a machine init done notifier.
  Enables to get rid of the VfioIrqStarterNotifierParams dangling
  pointer. Previously we use pbus first_irq. This is no more possible
  since the reset notifier takes a void * and first_irq is a field of
  a const struct. So now we pass the DeviceState handle of the
  interrupt controller. I tried to keep the code generic, reason why
  I did not rely on an architecture specific accessor to retrieve
  the gsi number (gic accessor as proposed by Alex). I would like to
  avoid creating an ARM VFIO device model. I hope this model
  model can work on other archs than arm (no multiple intc?);
  wouldn't it be simpler to keep the previous first_irq parameter and
  relax the const constraint.

v6 - v7:
- compat is not exposed anymore as a user option. Rationale is
  the vfio device became abstract and a specialization is needed
  anyway. The derived device must set the compat string.
- in v6 vfio_start_irq_injection was exposed in vfio-platform.h.
  A new function dubbed vfio_register_irq_starter replaces it. It
  registers a machine init done notifier that programs  starts
  all dynamic VFIO device IRQs. This function is supposed to be
  called by the machine file. A set of static helper routines are
  added too. It must be called before the creation of the platform
  bus device.

v5 - v6:
- vfio_device property renamed into host property
- correct error handling of VFIO_DEVICE_GET_IRQ_INFO ioctl
  and remove PCI related comment
- remove declaration of vfio_setup_irqfd and irqfd_allowed
  property.Both belong to next patch (irqfd)
- remove declaration of vfio_intp_interrupt in vfio-platform.h
- functions that can be static get this characteristic
- remove declarations of vfio_region_ops, vfio_memory_listener,
  group_list, vfio_address_spaces. All are moved to vfio-common.h
- remove vfio_put_device declaration and definition
- print_regions removed. code moved into vfio_populate_regions
- replace DPRINTF by trace events
- new helper routine to set the trigger eventfd
- dissociate intp init from the injection enablement:
  vfio_enable_intp renamed into vfio_init_intp and new function
  named vfio_start_eventfd_injection
- injection start moved to vfio_start_irq_injection (not anymore
  in vfio_populate_interrupt)
- new start_irq_fn field in VFIOPlatformDevice corresponding to
  the function that will be used for starting injection
- user handled eventfd:
  x add mutex to protect IRQ state  list manipulation,
  x correct misleading comment in vfio_intp_interrupt.
  x Fix bugs thanks to fake interrupt modality
- VFIOPlatformDeviceClass becomes abstract
- add error_setg in vfio_platform_realize

v4 - v5:
- vfio-plaform.h included first
- cleanup error handling in *populate*, vfio_get_device,
  vfio_enable_intp
- vfio_put_device not called anymore
- add some includes to follow vfio policy

v3 - v4:
[Eric Auger]
- merge of vfio: Add initial IRQ support in platform device
  to get a full functional patch although perfs are limited.
- removal of unrealize function since I currently understand
  it is only used with device hot-plug feature.

v2 - v3:
[Eric Auger]
- further factorization between PCI and platform (VFIORegion,
  VFIODevice). same 

[PATCH v16 8/9] sysbus: add irq_routing_notifier

2015-05-27 Thread Eric Auger
Add a new connect_irq_notifier notifier in the SysBusDeviceClass. This
notifier, if populated, is called after sysbus_connect_irq.

This mechanism is used to setup VFIO signaling once VFIO platform
devices get attached to their platform bus, on a machine init done
notifier.

Signed-off-by: Eric Auger eric.au...@linaro.org
Reviewed-by: Peter Crosthwaite peter.crosthwa...@xilinx.com
Tested-by: Vikram Sethi vikr...@codeaurora.org

---
v15 - v16:
- add Vikram's T-b

v14 - v15:
- add Peter R-b

v2 - v3 (integrated into this series v14):
- rename irq_routing_notifier into connect_irq_notifier

v1 - v2:
- duly put the notifier in the class and not in the device
---
 hw/core/sysbus.c| 6 ++
 include/hw/sysbus.h | 1 +
 2 files changed, 7 insertions(+)

diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c
index b53c351..2d22aec 100644
--- a/hw/core/sysbus.c
+++ b/hw/core/sysbus.c
@@ -109,7 +109,13 @@ qemu_irq sysbus_get_connected_irq(SysBusDevice *dev, int n)
 
 void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq)
 {
+SysBusDeviceClass *sbd = SYS_BUS_DEVICE_GET_CLASS(dev);
+
 qdev_connect_gpio_out_named(DEVICE(dev), SYSBUS_DEVICE_GPIO_IRQ, n, irq);
+
+if (sbd-connect_irq_notifier) {
+sbd-connect_irq_notifier(dev, irq);
+}
 }
 
 /* Check whether an MMIO region exists */
diff --git a/include/hw/sysbus.h b/include/hw/sysbus.h
index d1f3f00..e80b26d 100644
--- a/include/hw/sysbus.h
+++ b/include/hw/sysbus.h
@@ -41,6 +41,7 @@ typedef struct SysBusDeviceClass {
 /* public */
 
 int (*init)(SysBusDevice *dev);
+void (*connect_irq_notifier)(SysBusDevice *dev, qemu_irq irq);
 } SysBusDeviceClass;
 
 struct SysBusDevice {
-- 
1.8.3.2

___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


[PATCH v16 5/9] kvm: rename kvm_irqchip_[add, remove]_irqfd_notifier with gsi suffix

2015-05-27 Thread Eric Auger
Anticipating for the introduction of new add/remove functions taking
a qemu_irq parameter, let's rename existing ones with a gsi suffix.

Signed-off-by: Eric Auger eric.au...@linaro.org
Tested-by: Vikram Sethi vikr...@codeaurora.org

---

v15 - v16:
- added Vikram's T-b
- resolve rebase conflict in kvm.h
---
 hw/s390x/virtio-ccw.c  | 8 
 hw/vfio/pci.c  | 6 +++---
 hw/virtio/virtio-pci.c | 4 ++--
 include/sysemu/kvm.h   | 7 ---
 kvm-all.c  | 7 ---
 kvm-stub.c | 7 ---
 6 files changed, 21 insertions(+), 18 deletions(-)

diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index c96101a..17707c7 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -1216,8 +1216,8 @@ static int virtio_ccw_add_irqfd(VirtioCcwDevice *dev, int 
n)
 VirtQueue *vq = virtio_get_queue(vdev, n);
 EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);
 
-return kvm_irqchip_add_irqfd_notifier(kvm_state, notifier, NULL,
-  dev-routes.gsi[n]);
+return kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, notifier, NULL,
+  dev-routes.gsi[n]);
 }
 
 static void virtio_ccw_remove_irqfd(VirtioCcwDevice *dev, int n)
@@ -1227,8 +1227,8 @@ static void virtio_ccw_remove_irqfd(VirtioCcwDevice *dev, 
int n)
 EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);
 int ret;
 
-ret = kvm_irqchip_remove_irqfd_notifier(kvm_state, notifier,
-dev-routes.gsi[n]);
+ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, notifier,
+dev-routes.gsi[n]);
 assert(ret == 0);
 }
 
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index e0e339a..ac85624 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -597,7 +597,7 @@ static void vfio_add_kvm_msi_virq(VFIOMSIVector *vector, 
MSIMessage *msg,
 return;
 }
 
-if (kvm_irqchip_add_irqfd_notifier(kvm_state, vector-kvm_interrupt,
+if (kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, vector-kvm_interrupt,
NULL, virq)  0) {
 kvm_irqchip_release_virq(kvm_state, virq);
 event_notifier_cleanup(vector-kvm_interrupt);
@@ -609,8 +609,8 @@ static void vfio_add_kvm_msi_virq(VFIOMSIVector *vector, 
MSIMessage *msg,
 
 static void vfio_remove_kvm_msi_virq(VFIOMSIVector *vector)
 {
-kvm_irqchip_remove_irqfd_notifier(kvm_state, vector-kvm_interrupt,
-  vector-virq);
+kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, vector-kvm_interrupt,
+  vector-virq);
 kvm_irqchip_release_virq(kvm_state, vector-virq);
 vector-virq = -1;
 event_notifier_cleanup(vector-kvm_interrupt);
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 867c9d1..21871e6 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -477,7 +477,7 @@ static int kvm_virtio_pci_irqfd_use(VirtIOPCIProxy *proxy,
 VirtQueue *vq = virtio_get_queue(vdev, queue_no);
 EventNotifier *n = virtio_queue_get_guest_notifier(vq);
 int ret;
-ret = kvm_irqchip_add_irqfd_notifier(kvm_state, n, NULL, irqfd-virq);
+ret = kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, irqfd-virq);
 return ret;
 }
 
@@ -491,7 +491,7 @@ static void kvm_virtio_pci_irqfd_release(VirtIOPCIProxy 
*proxy,
 VirtIOIRQFD *irqfd = proxy-vector_irqfd[vector];
 int ret;
 
-ret = kvm_irqchip_remove_irqfd_notifier(kvm_state, n, irqfd-virq);
+ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n, irqfd-virq);
 assert(ret == 0);
 }
 
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 4878959..d0aa224 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -414,9 +414,10 @@ void kvm_irqchip_release_virq(KVMState *s, int virq);
 
 int kvm_irqchip_add_adapter_route(KVMState *s, AdapterInfo *adapter);
 
-int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n,
-   EventNotifier *rn, int virq);
-int kvm_irqchip_remove_irqfd_notifier(KVMState *s, EventNotifier *n, int virq);
+int kvm_irqchip_add_irqfd_notifier_gsi(KVMState *s, EventNotifier *n,
+   EventNotifier *rn, int virq);
+int kvm_irqchip_remove_irqfd_notifier_gsi(KVMState *s, EventNotifier *n,
+  int virq);
 void kvm_pc_gsi_handler(void *opaque, int n, int level);
 void kvm_pc_setup_irq_routing(bool pci_enabled);
 void kvm_init_irq_routing(KVMState *s);
diff --git a/kvm-all.c b/kvm-all.c
index 17a3771..2d58eb8 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1368,14 +1368,15 @@ int kvm_irqchip_update_msi_route(KVMState *s, int virq, 
MSIMessage msg)
 }
 #endif /* !KVM_CAP_IRQ_ROUTING */
 
-int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n,
-   EventNotifier *rn, int virq)
+int 

[PATCH v16 7/9] intc: arm_gic_kvm: set the qemu_irq/gsi mapping

2015-05-27 Thread Eric Auger
The arm_gic_kvm now calls kvm_irqchip_set_qemuirq_gsi to build
the hash table storing qemu_irq/gsi mappings. From that point on
irqfd can be setup directly from the qemu_irq using
kvm_irqchip_add_irqfd_notifier.

Signed-off-by: Eric Auger eric.au...@linaro.org
Tested-by: Vikram Sethi vikr...@codeaurora.org

---
v15 - v16:
- added Vikram's T-b
- Resolve rebase conflict

v2 - v3:
- kvm_irqchip_add_qemuirq_irqfd_notifier renamed into
  kvm_irqchip_add_irqfd_notifier
---
 hw/intc/arm_gic_kvm.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/hw/intc/arm_gic_kvm.c b/hw/intc/arm_gic_kvm.c
index 2cb7d25..f56bff1 100644
--- a/hw/intc/arm_gic_kvm.c
+++ b/hw/intc/arm_gic_kvm.c
@@ -570,6 +570,12 @@ static void kvm_arm_gic_realize(DeviceState *dev, Error 
**errp)
  */
 i += (GIC_INTERNAL * s-num_cpu);
 qdev_init_gpio_in(dev, kvm_arm_gic_set_irq, i);
+
+for (i = 0; i  s-num_irq - GIC_INTERNAL; i++) {
+qemu_irq irq = qdev_get_gpio_in(dev, i);
+kvm_irqchip_set_qemuirq_gsi(kvm_state, irq, i);
+}
+
 /* We never use our outbound IRQ/FIQ lines but provide them so that
  * we maintain the same interface as the non-KVM GIC.
  */
-- 
1.8.3.2

___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [Qemu-devel] [RESEND PATCH v12 4/4] hw/arm/virt: change indentation in a15memmap

2015-05-27 Thread Shannon Zhao



On 2015年05月27日 16:47, Eric Auger wrote:

Re-indent in a15memmap after VIRT_PLATFORM_BUS introduction

Signed-off-by: Eric Auger eric.au...@linaro.org
Reviewed-by: Alex Bennée alex.ben...@linaro.org

---

v11 - v12:
- Add Alex R-b
---
  hw/arm/virt.c | 26 +-
  1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 199d031..6c1ec58 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -128,26 +128,26 @@ typedef struct {
   */
  static const MemMapEntry a15memmap[] = {
  /* Space up to 0x800 is reserved for a boot ROM */
-[VIRT_FLASH] =  {  0, 0x0800 },
-[VIRT_CPUPERIPHS] = { 0x0800, 0x0002 },
+[VIRT_FLASH] =  {  0, 0x0800 },
+[VIRT_CPUPERIPHS] = { 0x0800, 0x0002 },
  /* GIC distributor and CPU interfaces sit inside the CPU peripheral space 
*/
-[VIRT_GIC_DIST] =   { 0x0800, 0x0001 },
-[VIRT_GIC_CPU] ={ 0x0801, 0x0001 },
-[VIRT_UART] =   { 0x0900, 0x1000 },
-[VIRT_RTC] ={ 0x0901, 0x1000 },
-[VIRT_FW_CFG] = { 0x0902, 0x000a },
-[VIRT_MMIO] =   { 0x0a00, 0x0200 },
+[VIRT_GIC_DIST] =   { 0x0800, 0x0001 },
+[VIRT_GIC_CPU] ={ 0x0801, 0x0001 },
+[VIRT_UART] =   { 0x0900, 0x1000 },
+[VIRT_RTC] ={ 0x0901, 0x1000 },
+[VIRT_FW_CFG] = { 0x0902, 0x000a },
+[VIRT_MMIO] =   { 0x0a00, 0x0200 },
  /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
  [VIRT_PLATFORM_BUS] =   { 0x0c00, 0x0200 },
  /*
   * PCIE verbose map:
   *
- * MMIO window  { 0x1000, 0x2eff },
- * PIO window   { 0x3eff, 0x0001 },
- * ECAM { 0x3f00, 0x0100 },
+ * MMIO window  { 0x1000, 0x2eff },
+ * PIO window   { 0x3eff, 0x0001 },
+ * ECAM { 0x3f00, 0x0100 },
   */
-[VIRT_PCIE] =   { 0x1000, 0x3000 },
-[VIRT_MEM] ={ 0x4000, 30ULL * 1024 * 1024 * 1024 },
+[VIRT_PCIE] =   { 0x1000, 0x3000 },
+[VIRT_MEM] ={ 0x4000, 30ULL * 1024 * 1024 * 1024 },
  };

  static const int a15irqmap[] = {



Could we reserve more blanks in case of long name in the future? Then we 
won't deal the indentation again I guess.


--
Shannon
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


[PATCH V1 2/5] kvm: arm64: Dispatch virt GIC probing to device tree and ACPI

2015-05-27 Thread Wei Huang
This patch creates a dispatch function to support virt GIC probing
in both device tree (DT) and ACPI environment. kvm_vgic_hyp_init()
will probe DT first. If failed, it will try ACPI.

Signed-off-by: Wei Huang w...@redhat.com
---
 include/kvm/arm_vgic.h | 18 +-
 virt/kvm/arm/vgic-v2.c |  8 
 virt/kvm/arm/vgic-v3.c |  8 
 virt/kvm/arm/vgic.c| 42 +++---
 4 files changed, 48 insertions(+), 28 deletions(-)

diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 133ea00..3ee732a 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -332,17 +332,17 @@ int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
 #define vgic_initialized(k)(!!((k)-arch.vgic.nr_cpus))
 #define vgic_ready(k)  ((k)-arch.vgic.ready)
 
-int vgic_v2_probe(struct device_node *vgic_node,
- const struct vgic_ops **ops,
- const struct vgic_params **params);
+int vgic_v2_dt_probe(struct device_node *vgic_node,
+const struct vgic_ops **ops,
+const struct vgic_params **params);
 #ifdef CONFIG_ARM_GIC_V3
-int vgic_v3_probe(struct device_node *vgic_node,
- const struct vgic_ops **ops,
- const struct vgic_params **params);
+int vgic_v3_dt_probe(struct device_node *vgic_node,
+const struct vgic_ops **ops,
+const struct vgic_params **params);
 #else
-static inline int vgic_v3_probe(struct device_node *vgic_node,
-   const struct vgic_ops **ops,
-   const struct vgic_params **params)
+static inline int vgic_v3_dt_probe(struct device_node *vgic_node,
+  const struct vgic_ops **ops,
+  const struct vgic_params **params)
 {
return -ENODEV;
 }
diff --git a/virt/kvm/arm/vgic-v2.c b/virt/kvm/arm/vgic-v2.c
index f9b9c7c..295996f 100644
--- a/virt/kvm/arm/vgic-v2.c
+++ b/virt/kvm/arm/vgic-v2.c
@@ -167,7 +167,7 @@ static const struct vgic_ops vgic_v2_ops = {
 static struct vgic_params vgic_v2_params;
 
 /**
- * vgic_v2_probe - probe for a GICv2 compatible interrupt controller in DT
+ * vgic_v2_dt_probe - probe for a GICv2 compatible interrupt controller in DT
  * @node:  pointer to the DT node
  * @ops:   address of a pointer to the GICv2 operations
  * @params:address of a pointer to HW-specific parameters
@@ -176,9 +176,9 @@ static struct vgic_params vgic_v2_params;
  * in *ops and the HW parameters in *params. Returns an error code
  * otherwise.
  */
-int vgic_v2_probe(struct device_node *vgic_node,
- const struct vgic_ops **ops,
- const struct vgic_params **params)
+int vgic_v2_dt_probe(struct device_node *vgic_node,
+const struct vgic_ops **ops,
+const struct vgic_params **params)
 {
int ret;
struct resource vctrl_res;
diff --git a/virt/kvm/arm/vgic-v3.c b/virt/kvm/arm/vgic-v3.c
index dff0602..91814e2 100644
--- a/virt/kvm/arm/vgic-v3.c
+++ b/virt/kvm/arm/vgic-v3.c
@@ -211,7 +211,7 @@ static const struct vgic_ops vgic_v3_ops = {
 static struct vgic_params vgic_v3_params;
 
 /**
- * vgic_v3_probe - probe for a GICv3 compatible interrupt controller in DT
+ * vgic_v3_dt_probe - probe for a GICv3 compatible interrupt controller in DT
  * @node:  pointer to the DT node
  * @ops:   address of a pointer to the GICv3 operations
  * @params:address of a pointer to HW-specific parameters
@@ -220,9 +220,9 @@ static struct vgic_params vgic_v3_params;
  * in *ops and the HW parameters in *params. Returns an error code
  * otherwise.
  */
-int vgic_v3_probe(struct device_node *vgic_node,
- const struct vgic_ops **ops,
- const struct vgic_params **params)
+int vgic_v3_dt_probe(struct device_node *vgic_node,
+const struct vgic_ops **ops,
+const struct vgic_params **params)
 {
int ret = 0;
u32 gicv_idx;
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 78fb820..b4010f0 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -25,6 +25,7 @@
 #include linux/of_address.h
 #include linux/of_irq.h
 #include linux/uaccess.h
+#include linux/acpi.h
 
 #include linux/irqchip/arm-gic.h
 
@@ -2088,32 +2089,51 @@ static struct notifier_block vgic_cpu_nb = {
 };
 
 static const struct of_device_id vgic_ids[] = {
-   { .compatible = arm,cortex-a15-gic,   .data = vgic_v2_probe, },
-   { .compatible = arm,cortex-a7-gic,.data = vgic_v2_probe, },
-   { .compatible = arm,gic-400,  .data = vgic_v2_probe, },
-   { .compatible = arm,gic-v3,   .data = vgic_v3_probe, },
+   { .compatible = arm,cortex-a15-gic,   .data = vgic_v2_dt_probe, },
+   { .compatible = arm,cortex-a7-gic,.data = vgic_v2_dt_probe, },
+   { .compatible = arm,gic-400,  .data = 

[PATCH V1 0/5] Enable ACPI support for KVM ARM

2015-05-27 Thread Wei Huang
Initial ACPI support for ARM64 has been accepted into Linux kernel recently.
Now it is a good time to re-visit ACPI support for KVM. This patchset
enables ACPI for both arch_timer and vGIC by probing related ACPI tables
and does necessary initialization.

Note that Alexander Spyridaki submitted similar patches before. Some of
his ideas were borrowed in this patchset, but with substancial changes.
In addition we extend support for both GICv2 and GICv3.

This patchset would work better on top of recent GIC/IRQCHIP patches by
Hanjun Guo, who added support for gic_version in ACPI struct of GIC
distributor (search ACPICA: Introduce GIC version for arm based system).

This patchset can be applied cleanly on top of Linx 4.1-rc1.

Wei Huang (5):
  kvm: arm64: Enable ACPI support for virt arch timer
  kvm: arm64: Dispatch virt GIC probing to device tree and ACPI
  kvm: arm64: Detect GIC version for proper ACPI vGIC probing
  kvm: arm64: Implement ACPI probing code for GICv2
  kvm: arm64: Implement ACPI probing code for GICv3

 include/kvm/arm_vgic.h|  36 +---
 virt/kvm/arm/arch_timer.c |  64 -
 virt/kvm/arm/vgic-v2.c|  65 +++--
 virt/kvm/arm/vgic-v3.c|  56 +--
 virt/kvm/arm/vgic.c   | 140 ++
 5 files changed, 320 insertions(+), 41 deletions(-)

-- 
1.8.3.1

___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


[PATCH V1 4/5] kvm: arm64: Implement ACPI probing code for GICv2

2015-05-27 Thread Wei Huang
This patches enables ACPI support for KVM virtual GICv2. KVM parses
ACPI table for virt GIC related information and initializes resources.

Signed-off-by: Alexander Spyridaki a.spyrida...@virtualopensystems.com
Signed-off-by: Wei Huang w...@redhat.com
---
 virt/kvm/arm/vgic-v2.c | 49 -
 1 file changed, 48 insertions(+), 1 deletion(-)

diff --git a/virt/kvm/arm/vgic-v2.c b/virt/kvm/arm/vgic-v2.c
index 711de82..01ce8a3 100644
--- a/virt/kvm/arm/vgic-v2.c
+++ b/virt/kvm/arm/vgic-v2.c
@@ -264,6 +264,53 @@ int vgic_v2_acpi_probe(struct acpi_madt_generic_interrupt 
*vgic_acpi,
   const struct vgic_ops **ops,
   const struct vgic_params **params)
 {
-   return -EINVAL;
+   struct vgic_params *vgic = vgic_v2_params;
+   int irq_mode, ret;
+
+   /* IRQ trigger mode */
+   irq_mode = (vgic_acpi-flags  ACPI_MADT_VGIC_IRQ_MODE) ?
+   ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE;
+   vgic-maint_irq = acpi_register_gsi(NULL, vgic_acpi-vgic_interrupt,
+   irq_mode, ACPI_ACTIVE_HIGH);
+   if (!vgic-maint_irq) {
+   kvm_err(Cannot register VGIC ACPI maintenance irq\n);
+   ret = -ENXIO;
+   goto out;
+   }
+
+   /* GICH resource */
+   vgic-vctrl_base = ioremap(vgic_acpi-gich_base_address, SZ_8K);
+   if (!vgic-vctrl_base) {
+   kvm_err(cannot ioremap GICH memory\n);
+   ret = -ENOMEM;
+   goto out;
+   }
+
+   vgic-nr_lr = readl_relaxed(vgic-vctrl_base + GICH_VTR);
+   vgic-nr_lr = (vgic-nr_lr  0x3f) + 1;
+
+   ret = create_hyp_io_mappings(vgic-vctrl_base,
+vgic-vctrl_base + SZ_8K,
+vgic_acpi-gich_base_address);
+   if (ret) {
+   kvm_err(Cannot map GICH into hyp\n);
+   goto out;
+   }
+
+   vgic-vcpu_base = vgic_acpi-gicv_base_address;
+   vgic-can_emulate_gicv2 = true;
+   kvm_register_device_ops(kvm_arm_vgic_v2_ops, KVM_DEV_TYPE_ARM_VGIC_V2);
+
+   kvm_info(GICH base=0x%llx, GICV base=0x%llx, IRQ=%d\n,
+(unsigned long long)vgic_acpi-gich_base_address,
+(unsigned long long)vgic_acpi-gicv_base_address,
+vgic-maint_irq);
+
+   vgic-type = VGIC_V2;
+   *ops = vgic_v2_ops;
+   *params = vgic;
+
+out:
+   return ret;
 }
 #endif /* CONFIG_ACPI */
-- 
1.8.3.1

___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


[PATCH V1 3/5] kvm: arm64: Detect GIC version for proper ACPI vGIC probing

2015-05-27 Thread Wei Huang
There are two GICs (GICv2 and GICv3) supported by KVM. So it is necessary
to find out GIC version before calling ACPI probing functions defined
in vgic-v2.c and vgic-v3.c.

This patch detects GIC version by checking gic_version field of GIC
distributor, which was defined  since ACPI 6.0. In case of ACPI 5.1,
we use manual hardware discovery to find out GIC version.

NOTE: This patch is based on a recent patch by Hanjun Guo.

Signed-off-by: Hanjun Guo hanjun@linaro.org
Signed-off-by: Wei Huang w...@redhat.com
---
 include/kvm/arm_vgic.h |  18 +
 virt/kvm/arm/vgic-v2.c |  10 +
 virt/kvm/arm/vgic-v3.c |  10 +
 virt/kvm/arm/vgic.c| 100 -
 4 files changed, 137 insertions(+), 1 deletion(-)

diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 3ee732a..7a44b08 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -24,6 +24,7 @@
 #include linux/irqreturn.h
 #include linux/spinlock.h
 #include linux/types.h
+#include linux/acpi.h
 #include kvm/iodev.h
 
 #define VGIC_NR_IRQS_LEGACY256
@@ -335,10 +336,18 @@ int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
 int vgic_v2_dt_probe(struct device_node *vgic_node,
 const struct vgic_ops **ops,
 const struct vgic_params **params);
+#ifdef CONFIG_ACPI
+int vgic_v2_acpi_probe(struct acpi_madt_generic_interrupt *,
+  const struct vgic_ops **ops,
+  const struct vgic_params **params);
+#endif /* CONFIG_ACPI */
 #ifdef CONFIG_ARM_GIC_V3
 int vgic_v3_dt_probe(struct device_node *vgic_node,
 const struct vgic_ops **ops,
 const struct vgic_params **params);
+int vgic_v3_acpi_probe(struct acpi_madt_generic_interrupt *,
+  const struct vgic_ops **ops,
+  const struct vgic_params **params);
 #else
 static inline int vgic_v3_dt_probe(struct device_node *vgic_node,
   const struct vgic_ops **ops,
@@ -346,6 +355,15 @@ static inline int vgic_v3_dt_probe(struct device_node 
*vgic_node,
 {
return -ENODEV;
 }
+
+#ifdef CONFIG_ACPI
+int vgic_v3_acpi_probe(struct acpi_madt_generic_interrupt *,
+  const struct vgic_ops **ops,
+  const struct vgic_params **params)
+{
+   return -ENODEV;
+}
+#endif /* CONFIG_ACPI */
 #endif
 
 #endif
diff --git a/virt/kvm/arm/vgic-v2.c b/virt/kvm/arm/vgic-v2.c
index 295996f..711de82 100644
--- a/virt/kvm/arm/vgic-v2.c
+++ b/virt/kvm/arm/vgic-v2.c
@@ -23,6 +23,7 @@
 #include linux/of.h
 #include linux/of_address.h
 #include linux/of_irq.h
+#include linux/acpi.h
 
 #include linux/irqchip/arm-gic.h
 
@@ -257,3 +258,12 @@ out:
of_node_put(vgic_node);
return ret;
 }
+
+#ifdef CONFIG_ACPI
+int vgic_v2_acpi_probe(struct acpi_madt_generic_interrupt *vgic_acpi,
+  const struct vgic_ops **ops,
+  const struct vgic_params **params)
+{
+   return -EINVAL;
+}
+#endif /* CONFIG_ACPI */
diff --git a/virt/kvm/arm/vgic-v3.c b/virt/kvm/arm/vgic-v3.c
index 91814e2..99d0f9f 100644
--- a/virt/kvm/arm/vgic-v3.c
+++ b/virt/kvm/arm/vgic-v3.c
@@ -23,6 +23,7 @@
 #include linux/of.h
 #include linux/of_address.h
 #include linux/of_irq.h
+#include linux/acpi.h
 
 #include linux/irqchip/arm-gic-v3.h
 
@@ -285,3 +286,12 @@ out:
of_node_put(vgic_node);
return ret;
 }
+
+#ifdef CONFIG_ACPI
+int vgic_v3_acpi_probe(struct acpi_madt_generic_interrupt *vgic_acpi,
+  const struct vgic_ops **ops,
+  const struct vgic_params **params)
+{
+   return -EINVAL;
+}
+#endif /* CONFIG_ACPI */
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index b4010f0..cd09877 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -28,6 +28,7 @@
 #include linux/acpi.h
 
 #include linux/irqchip/arm-gic.h
+#include linux/irqchip/arm-gic-v3.h
 
 #include asm/kvm_emulate.h
 #include asm/kvm_arm.h
@@ -2114,9 +2115,106 @@ static int kvm_vgic_dt_probe(void)
 }
 
 #ifdef CONFIG_ACPI
+u8 gic_version = ACPI_MADT_GIC_VER_UNKNOWN;
+phys_addr_t dist_phy_base;
+static struct acpi_madt_generic_interrupt *vgic_acpi;
+
+static void gic_get_acpi_header(struct acpi_subtable_header *header)
+{
+   vgic_acpi = (struct acpi_madt_generic_interrupt *)header;
+}
+
+static int gic_parse_distributor(struct acpi_subtable_header *header,
+const unsigned long end)
+{
+   struct acpi_madt_generic_distributor *dist;
+
+   dist = (struct acpi_madt_generic_distributor *)header;
+
+   if (BAD_MADT_ENTRY(dist, end))
+   return -EINVAL;
+
+   gic_version = dist-gic_version;
+   dist_phy_base = dist-base_address;
+
+   return 0;
+}
+
+static int gic_match_redist(struct acpi_subtable_header *header,
+   const unsigned long end)
+{
+   return 0;
+}
+
+static bool 

[PATCH V1 1/5] kvm: arm64: Enable ACPI support for virt arch timer

2015-05-27 Thread Wei Huang
This patches enables ACPI support for KVM virtual arch timer. It allows
KVM to parse ACPI table for arch timer PPI when DT table is not present.

Signed-off-by: Alexander Spyridaki a.spyrida...@virtualopensystems.com
Signed-off-by: Wei Huang w...@redhat.com
---
 virt/kvm/arm/arch_timer.c | 64 +--
 1 file changed, 51 insertions(+), 13 deletions(-)

diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index 98c95f2..7da9eb3 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -21,6 +21,7 @@
 #include linux/kvm.h
 #include linux/kvm_host.h
 #include linux/interrupt.h
+#include linux/acpi.h
 
 #include clocksource/arm_arch_timer.h
 #include asm/arch_timer.h
@@ -274,9 +275,46 @@ static const struct of_device_id arch_timer_of_match[] = {
{},
 };
 
-int kvm_timer_hyp_init(void)
+static int kvm_timer_ppi_dt_parse(unsigned int *ppi)
 {
struct device_node *np;
+
+   np = of_find_matching_node(NULL, arch_timer_of_match);
+   if (!np)
+   return -ENODEV;
+
+   *ppi = irq_of_parse_and_map(np, 2);
+   if (*ppi == 0) {
+   of_node_put(np);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+#ifdef CONFIG_ACPI
+struct acpi_table_gtdt *gtdt_acpi;
+static void arch_timer_acpi_parse(struct acpi_table_header *table)
+{
+   gtdt_acpi = container_of(table, struct acpi_table_gtdt, header);
+}
+
+static int kvm_timer_ppi_acpi_parse(unsigned int *ppi)
+{
+   /* Get the interrupt number from the GTDT table */
+   acpi_table_parse(ACPI_SIG_GTDT,
+(acpi_tbl_table_handler)arch_timer_acpi_parse);
+
+   if (!gtdt_acpi-virtual_timer_interrupt)
+   return -EINVAL;
+
+   *ppi = gtdt_acpi-virtual_timer_interrupt;
+   return 0;
+}
+#endif
+
+int kvm_timer_hyp_init(void)
+{
unsigned int ppi;
int err;
 
@@ -284,19 +322,20 @@ int kvm_timer_hyp_init(void)
if (!timecounter)
return -ENODEV;
 
-   np = of_find_matching_node(NULL, arch_timer_of_match);
-   if (!np) {
-   kvm_err(kvm_arch_timer: can't find DT node\n);
-   return -ENODEV;
-   }
+   /* PPI parsing: try DT first, then ACPI */
+   err = kvm_timer_ppi_dt_parse(ppi);
+#ifdef CONFIG_ACPI
+   if (err  !acpi_disabled)
+   err = kvm_timer_ppi_acpi_parse(ppi);
+#endif
 
-   ppi = irq_of_parse_and_map(np, 2);
-   if (!ppi) {
-   kvm_err(kvm_arch_timer: no virtual timer interrupt\n);
-   err = -EINVAL;
-   goto out;
+   if (err) {
+   kvm_err(kvm_arch_timer: can't find virtual timer info or 
+   config virtual timer interrupt\n);
+   return err;
}
 
+   /* configure IRQ handler */
err = request_percpu_irq(ppi, kvm_arch_timer_handler,
 kvm guest timer, kvm_get_running_vcpus());
if (err) {
@@ -319,14 +358,13 @@ int kvm_timer_hyp_init(void)
goto out_free;
}
 
-   kvm_info(%s IRQ%d\n, np-name, ppi);
+   kvm_info(timer IRQ%d\n, ppi);
on_each_cpu(kvm_timer_init_interrupt, NULL, 1);
 
goto out;
 out_free:
free_percpu_irq(ppi, kvm_get_running_vcpus());
 out:
-   of_node_put(np);
return err;
 }
 
-- 
1.8.3.1

___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm