[PATCH v5 09/10] arm: add support for supplying GICv3 redistributor addresses

2015-07-03 Thread Andre Przywara
Instead of the GIC virtual CPU interface an emulated GICv3 needs to
have accesses to its emulated redistributors trapped in the guest.
Add code to tell the kernel about the mapping if a GICv3 emulation was
requested by the user.

This contains some defines which are not (yet) in the (32 bit) header
files to allow compilation for ARM.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
Reviewed-by: Marc Zyngier marc.zyng...@arm.com
---
 arm/gic.c | 36 +++-
 arm/include/arm-common/gic.h  |  1 +
 arm/include/arm-common/kvm-arch.h |  7 +++
 3 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/arm/gic.c b/arm/gic.c
index b6c5868..efe4b42 100644
--- a/arm/gic.c
+++ b/arm/gic.c
@@ -9,7 +9,18 @@
 #include linux/kernel.h
 #include linux/kvm.h
 
+/* Those names are not defined for ARM (yet) */
+#ifndef KVM_VGIC_V3_ADDR_TYPE_DIST
+#define KVM_VGIC_V3_ADDR_TYPE_DIST 2
+#endif
+
+#ifndef KVM_VGIC_V3_ADDR_TYPE_REDIST
+#define KVM_VGIC_V3_ADDR_TYPE_REDIST 3
+#endif
+
 static int gic_fd = -1;
+static u64 gic_redists_base;
+static u64 gic_redists_size;
 
 static int gic__create_device(struct kvm *kvm, enum irqchip_type type)
 {
@@ -28,12 +39,21 @@ static int gic__create_device(struct kvm *kvm, enum 
irqchip_type type)
.group  = KVM_DEV_ARM_VGIC_GRP_ADDR,
.addr   = (u64)(unsigned long)dist_addr,
};
+   struct kvm_device_attr redist_attr = {
+   .group  = KVM_DEV_ARM_VGIC_GRP_ADDR,
+   .attr   = KVM_VGIC_V3_ADDR_TYPE_REDIST,
+   .addr   = (u64)(unsigned long)gic_redists_base,
+   };
 
switch (type) {
case IRQCHIP_GICV2:
gic_device.type = KVM_DEV_TYPE_ARM_VGIC_V2;
dist_attr.attr  = KVM_VGIC_V2_ADDR_TYPE_DIST;
break;
+   case IRQCHIP_GICV3:
+   gic_device.type = KVM_DEV_TYPE_ARM_VGIC_V3;
+   dist_attr.attr  = KVM_VGIC_V3_ADDR_TYPE_DIST;
+   break;
}
 
err = ioctl(kvm-vm_fd, KVM_CREATE_DEVICE, gic_device);
@@ -46,6 +66,9 @@ static int gic__create_device(struct kvm *kvm, enum 
irqchip_type type)
case IRQCHIP_GICV2:
err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, cpu_if_attr);
break;
+   case IRQCHIP_GICV3:
+   err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, redist_attr);
+   break;
}
if (err)
goto out_err;
@@ -97,6 +120,10 @@ int gic__create(struct kvm *kvm, enum irqchip_type type)
switch (type) {
case IRQCHIP_GICV2:
break;
+   case IRQCHIP_GICV3:
+   gic_redists_size = kvm-cfg.nrcpus * ARM_GIC_REDIST_SIZE;
+   gic_redists_base = ARM_GIC_DIST_BASE - gic_redists_size;
+   break;
default:
return -ENODEV;
}
@@ -156,12 +183,19 @@ void gic__generate_fdt_nodes(void *fdt, u32 phandle, enum 
irqchip_type type)
const char *compatible;
u64 reg_prop[] = {
cpu_to_fdt64(ARM_GIC_DIST_BASE), 
cpu_to_fdt64(ARM_GIC_DIST_SIZE),
-   cpu_to_fdt64(ARM_GIC_CPUI_BASE), 
cpu_to_fdt64(ARM_GIC_CPUI_SIZE),
+   0, 0,   /* to be filled */
};
 
switch (type) {
case IRQCHIP_GICV2:
compatible = arm,cortex-a15-gic;
+   reg_prop[2] = cpu_to_fdt64(ARM_GIC_CPUI_BASE);
+   reg_prop[3] = cpu_to_fdt64(ARM_GIC_CPUI_SIZE);
+   break;
+   case IRQCHIP_GICV3:
+   compatible = arm,gic-v3;
+   reg_prop[2] = cpu_to_fdt64(gic_redists_base);
+   reg_prop[3] = cpu_to_fdt64(gic_redists_size);
break;
default:
return;
diff --git a/arm/include/arm-common/gic.h b/arm/include/arm-common/gic.h
index d524f55..4fde5ac 100644
--- a/arm/include/arm-common/gic.h
+++ b/arm/include/arm-common/gic.h
@@ -23,6 +23,7 @@
 
 enum irqchip_type {
IRQCHIP_GICV2,
+   IRQCHIP_GICV3,
 };
 
 struct kvm;
diff --git a/arm/include/arm-common/kvm-arch.h 
b/arm/include/arm-common/kvm-arch.h
index 90d6733..0f5fb7f 100644
--- a/arm/include/arm-common/kvm-arch.h
+++ b/arm/include/arm-common/kvm-arch.h
@@ -30,6 +30,13 @@
 #define KVM_PCI_MMIO_AREA  (KVM_PCI_CFG_AREA + ARM_PCI_CFG_SIZE)
 #define KVM_VIRTIO_MMIO_AREA   ARM_MMIO_AREA
 
+/*
+ * On a GICv3 there must be one redistributor per vCPU.
+ * The value here is the size for one, we multiply this at runtime with
+ * the number of requested vCPUs to get the actual size.
+ */
+#define ARM_GIC_REDIST_SIZE0x2
+
 #define KVM_IRQ_OFFSET GIC_SPI_IRQ_BASE
 
 #define KVM_VM_TYPE0
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 04/10] AArch{32,64}: dynamically configure the number of GIC interrupts

2015-07-03 Thread Andre Przywara
From: Marc Zyngier marc.zyng...@arm.com

In order to reduce the memory usage of large guests (as well
as improve performance), tell KVM about the number of interrupts
we require.

To avoid synchronization with the various device creation,
use a late_init callback to compute the GIC configuration.
[Andre: rename to gic__init_gic() to ease future expansion]

Signed-off-by: Marc Zyngier marc.zyng...@arm.com
Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 arm/gic.c | 25 +
 1 file changed, 25 insertions(+)

diff --git a/arm/gic.c b/arm/gic.c
index 1ff3663..8560c9b 100644
--- a/arm/gic.c
+++ b/arm/gic.c
@@ -1,10 +1,12 @@
 #include kvm/fdt.h
+#include kvm/irq.h
 #include kvm/kvm.h
 #include kvm/virtio.h
 
 #include arm-common/gic.h
 
 #include linux/byteorder.h
+#include linux/kernel.h
 #include linux/kvm.h
 
 static int gic_fd = -1;
@@ -96,6 +98,29 @@ int gic__create(struct kvm *kvm)
return err;
 }
 
+static int gic__init_gic(struct kvm *kvm)
+{
+   int lines = irq__get_nr_allocated_lines();
+   u32 nr_irqs = ALIGN(lines, 32) + GIC_SPI_IRQ_BASE;
+   struct kvm_device_attr nr_irqs_attr = {
+   .group  = KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
+   .addr   = (u64)(unsigned long)nr_irqs,
+   };
+
+   /*
+* If we didn't use the KVM_CREATE_DEVICE method, KVM will
+* give us some default number of interrupts.
+*/
+   if (gic_fd  0)
+   return 0;
+
+   if (!ioctl(gic_fd, KVM_HAS_DEVICE_ATTR, nr_irqs_attr))
+   return ioctl(gic_fd, KVM_SET_DEVICE_ATTR, nr_irqs_attr);
+
+   return 0;
+}
+late_init(gic__init_gic)
+
 void gic__generate_fdt_nodes(void *fdt, u32 phandle)
 {
u64 reg_prop[] = {
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 06/10] arm: simplify MMIO dispatching

2015-07-03 Thread Andre Przywara
Currently we separate any incoming MMIO request into one of the ARM
memory map regions and take care to spare the GIC.
It turns out that this is unnecessary, as we only have one special
region (the IO port area in the first 64 KByte). The MMIO rbtree
takes care about unhandled MMIO ranges, so we can simply drop all the
special range checking (except that for the IO range) in
kvm_cpu__emulate_mmio().
As the GIC is handled in the kernel, a GIC MMIO access should never
reach userland (and we don't know what to do with it anyway).
This lets us delete some more code and simplifies future extensions
(like expanding the GIC regions).
To be in line with the other architectures, move the now simpler
code into a header file.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
Reviewed-by: Marc Zyngier marc.zyng...@arm.com
---
 arm/include/arm-common/kvm-arch.h | 12 
 arm/include/arm-common/kvm-cpu-arch.h | 14 --
 arm/kvm-cpu.c | 16 
 3 files changed, 12 insertions(+), 30 deletions(-)

diff --git a/arm/include/arm-common/kvm-arch.h 
b/arm/include/arm-common/kvm-arch.h
index 082131d..90d6733 100644
--- a/arm/include/arm-common/kvm-arch.h
+++ b/arm/include/arm-common/kvm-arch.h
@@ -45,18 +45,6 @@ static inline bool arm_addr_in_ioport_region(u64 phys_addr)
return phys_addr = KVM_IOPORT_AREA  phys_addr  limit;
 }
 
-static inline bool arm_addr_in_virtio_mmio_region(u64 phys_addr)
-{
-   u64 limit = KVM_VIRTIO_MMIO_AREA + ARM_VIRTIO_MMIO_SIZE;
-   return phys_addr = KVM_VIRTIO_MMIO_AREA  phys_addr  limit;
-}
-
-static inline bool arm_addr_in_pci_region(u64 phys_addr)
-{
-   u64 limit = KVM_PCI_CFG_AREA + ARM_PCI_CFG_SIZE + ARM_PCI_MMIO_SIZE;
-   return phys_addr = KVM_PCI_CFG_AREA  phys_addr  limit;
-}
-
 struct kvm_arch {
/*
 * We may have to align the guest memory for virtio, so keep the
diff --git a/arm/include/arm-common/kvm-cpu-arch.h 
b/arm/include/arm-common/kvm-cpu-arch.h
index 36c7872..329979a 100644
--- a/arm/include/arm-common/kvm-cpu-arch.h
+++ b/arm/include/arm-common/kvm-cpu-arch.h
@@ -44,8 +44,18 @@ static inline bool kvm_cpu__emulate_io(struct kvm_cpu *vcpu, 
u16 port, void *dat
return false;
 }
 
-bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data,
-  u32 len, u8 is_write);
+static inline bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr,
+u8 *data, u32 len, u8 is_write)
+{
+   if (arm_addr_in_ioport_region(phys_addr)) {
+   int direction = is_write ? KVM_EXIT_IO_OUT : KVM_EXIT_IO_IN;
+   u16 port = (phys_addr - KVM_IOPORT_AREA)  USHRT_MAX;
+
+   return kvm__emulate_io(vcpu, port, data, direction, len, 1);
+   }
+
+   return kvm__emulate_mmio(vcpu, phys_addr, data, len, is_write);
+}
 
 unsigned long kvm_cpu__get_vcpu_mpidr(struct kvm_cpu *vcpu);
 
diff --git a/arm/kvm-cpu.c b/arm/kvm-cpu.c
index ab08815..7780251 100644
--- a/arm/kvm-cpu.c
+++ b/arm/kvm-cpu.c
@@ -139,22 +139,6 @@ bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu)
return false;
 }
 
-bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data,
-  u32 len, u8 is_write)
-{
-   if (arm_addr_in_virtio_mmio_region(phys_addr)) {
-   return kvm__emulate_mmio(vcpu, phys_addr, data, len, is_write);
-   } else if (arm_addr_in_ioport_region(phys_addr)) {
-   int direction = is_write ? KVM_EXIT_IO_OUT : KVM_EXIT_IO_IN;
-   u16 port = (phys_addr - KVM_IOPORT_AREA)  USHRT_MAX;
-   return kvm__emulate_io(vcpu, port, data, direction, len, 1);
-   } else if (arm_addr_in_pci_region(phys_addr)) {
-   return kvm__emulate_mmio(vcpu, phys_addr, data, len, is_write);
-   }
-
-   return false;
-}
-
 void kvm_cpu__show_page_tables(struct kvm_cpu *vcpu)
 {
 }
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 10/10] arm: use new irqchip parameter to create different vGIC types

2015-07-03 Thread Andre Przywara
Currently we unconditionally create a virtual GICv2 in the guest.
Add a --irqchip= parameter to let the user specify a different GIC
type for the guest, when omitting this parameter it still defaults to
--irqchip=gicv2.
For now the only other supported type is --irqchip=gicv3

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 arm/aarch64/arm-cpu.c|  2 +-
 arm/gic.c| 16 
 arm/include/arm-common/kvm-config-arch.h |  9 -
 arm/kvm.c|  2 +-
 4 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/arm/aarch64/arm-cpu.c b/arm/aarch64/arm-cpu.c
index f702b9e..3dc8ea3 100644
--- a/arm/aarch64/arm-cpu.c
+++ b/arm/aarch64/arm-cpu.c
@@ -12,7 +12,7 @@
 static void generate_fdt_nodes(void *fdt, struct kvm *kvm, u32 gic_phandle)
 {
int timer_interrupts[4] = {13, 14, 11, 10};
-   gic__generate_fdt_nodes(fdt, gic_phandle, IRQCHIP_GICV2);
+   gic__generate_fdt_nodes(fdt, gic_phandle, kvm-cfg.arch.irqchip);
timer__generate_fdt_nodes(fdt, kvm, timer_interrupts);
 }
 
diff --git a/arm/gic.c b/arm/gic.c
index efe4b42..1b63074 100644
--- a/arm/gic.c
+++ b/arm/gic.c
@@ -22,6 +22,22 @@ static int gic_fd = -1;
 static u64 gic_redists_base;
 static u64 gic_redists_size;
 
+int irqchip_parser(const struct option *opt, const char *arg, int unset)
+{
+   enum irqchip_type *type = opt-value;
+
+   if (!strcmp(arg, gicv2)) {
+   *type = IRQCHIP_GICV2;
+   } else if (!strcmp(arg, gicv3)) {
+   *type = IRQCHIP_GICV3;
+   } else {
+   fprintf(stderr, irqchip: unknown type \%s\\n, arg);
+   return -1;
+   }
+
+   return 0;
+}
+
 static int gic__create_device(struct kvm *kvm, enum irqchip_type type)
 {
int err;
diff --git a/arm/include/arm-common/kvm-config-arch.h 
b/arm/include/arm-common/kvm-config-arch.h
index a8ebd94..9529881 100644
--- a/arm/include/arm-common/kvm-config-arch.h
+++ b/arm/include/arm-common/kvm-config-arch.h
@@ -8,8 +8,11 @@ struct kvm_config_arch {
unsigned intforce_cntfrq;
boolvirtio_trans_pci;
boolaarch32_guest;
+   enum irqchip_type irqchip;
 };
 
+int irqchip_parser(const struct option *opt, const char *arg, int unset);
+
 #define OPT_ARCH_RUN(pfx, cfg) 
\
pfx,
\
ARM_OPT_ARCH_RUN(cfg)   
\
@@ -21,6 +24,10 @@ struct kvm_config_arch {
 updated to program CNTFRQ correctly*),   
\
OPT_BOOLEAN('\0', force-pci, (cfg)-virtio_trans_pci,
\
Force virtio devices to use PCI as their default  
\
-   transport),
+   transport),   
\
+OPT_CALLBACK('\0', irqchip, (cfg)-irqchip, 
\
+[gicv2|gicv3],   \
+type of interrupt controller to emulate in the guest,
\
+irqchip_parser, NULL),
 
 #endif /* ARM_COMMON__KVM_CONFIG_ARCH_H */
diff --git a/arm/kvm.c b/arm/kvm.c
index f9685c2..d0e4a20 100644
--- a/arm/kvm.c
+++ b/arm/kvm.c
@@ -82,6 +82,6 @@ void kvm__arch_init(struct kvm *kvm, const char 
*hugetlbfs_path, u64 ram_size)
MADV_MERGEABLE | MADV_HUGEPAGE);
 
/* Create the virtual GIC. */
-   if (gic__create(kvm, IRQCHIP_GICV2))
+   if (gic__create(kvm, kvm-cfg.arch.irqchip))
die(Failed to create virtual GIC);
 }
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 07/10] limit number of VCPUs on demand

2015-07-03 Thread Andre Przywara
Currently the ARM GIC checks the number of VCPUs against a fixed
limit, which is GICv2 specific. Don't pretend we know better than the
kernel and let's get rid of that explicit check.
We now fail if the number of requested VCPUs could not be
instantiated instead of limiting the number of VCPUs.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 arm/gic.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/arm/gic.c b/arm/gic.c
index 99f0d2b..05f85a2 100644
--- a/arm/gic.c
+++ b/arm/gic.c
@@ -84,12 +84,6 @@ int gic__create(struct kvm *kvm)
 {
int err;
 
-   if (kvm-nrcpus  GIC_MAX_CPUS) {
-   pr_warning(%d CPUS greater than maximum of %d -- truncating\n,
-   kvm-nrcpus, GIC_MAX_CPUS);
-   kvm-nrcpus = GIC_MAX_CPUS;
-   }
-
/* Try the new way first, and fallback on legacy method otherwise */
err = gic__create_device(kvm);
if (err)
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 08/10] arm: prepare for instantiating different IRQ chip devices

2015-07-03 Thread Andre Przywara
Extend the vGIC handling code to potentially deal with different IRQ
chip devices instead of hard-coding the GICv2 in.
We extend most vGIC functions to take a type parameter, but still put
GICv2 in at the top for the time being.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
Reviewed-by: Marc Zyngier marc.zyng...@arm.com
---
 arm/aarch32/arm-cpu.c|  2 +-
 arm/aarch64/arm-cpu.c|  2 +-
 arm/gic.c| 44 +++-
 arm/include/arm-common/gic.h |  8 ++--
 arm/kvm.c|  2 +-
 5 files changed, 44 insertions(+), 14 deletions(-)

diff --git a/arm/aarch32/arm-cpu.c b/arm/aarch32/arm-cpu.c
index 946e443..d8d6293 100644
--- a/arm/aarch32/arm-cpu.c
+++ b/arm/aarch32/arm-cpu.c
@@ -12,7 +12,7 @@ static void generate_fdt_nodes(void *fdt, struct kvm *kvm, 
u32 gic_phandle)
 {
int timer_interrupts[4] = {13, 14, 11, 10};
 
-   gic__generate_fdt_nodes(fdt, gic_phandle);
+   gic__generate_fdt_nodes(fdt, gic_phandle, IRQCHIP_GICV2);
timer__generate_fdt_nodes(fdt, kvm, timer_interrupts);
 }
 
diff --git a/arm/aarch64/arm-cpu.c b/arm/aarch64/arm-cpu.c
index 8efe877..f702b9e 100644
--- a/arm/aarch64/arm-cpu.c
+++ b/arm/aarch64/arm-cpu.c
@@ -12,7 +12,7 @@
 static void generate_fdt_nodes(void *fdt, struct kvm *kvm, u32 gic_phandle)
 {
int timer_interrupts[4] = {13, 14, 11, 10};
-   gic__generate_fdt_nodes(fdt, gic_phandle);
+   gic__generate_fdt_nodes(fdt, gic_phandle, IRQCHIP_GICV2);
timer__generate_fdt_nodes(fdt, kvm, timer_interrupts);
 }
 
diff --git a/arm/gic.c b/arm/gic.c
index 05f85a2..b6c5868 100644
--- a/arm/gic.c
+++ b/arm/gic.c
@@ -11,13 +11,13 @@
 
 static int gic_fd = -1;
 
-static int gic__create_device(struct kvm *kvm)
+static int gic__create_device(struct kvm *kvm, enum irqchip_type type)
 {
int err;
u64 cpu_if_addr = ARM_GIC_CPUI_BASE;
u64 dist_addr = ARM_GIC_DIST_BASE;
struct kvm_create_device gic_device = {
-   .type   = KVM_DEV_TYPE_ARM_VGIC_V2,
+   .flags  = 0,
};
struct kvm_device_attr cpu_if_attr = {
.group  = KVM_DEV_ARM_VGIC_GRP_ADDR,
@@ -26,17 +26,27 @@ static int gic__create_device(struct kvm *kvm)
};
struct kvm_device_attr dist_attr = {
.group  = KVM_DEV_ARM_VGIC_GRP_ADDR,
-   .attr   = KVM_VGIC_V2_ADDR_TYPE_DIST,
.addr   = (u64)(unsigned long)dist_addr,
};
 
+   switch (type) {
+   case IRQCHIP_GICV2:
+   gic_device.type = KVM_DEV_TYPE_ARM_VGIC_V2;
+   dist_attr.attr  = KVM_VGIC_V2_ADDR_TYPE_DIST;
+   break;
+   }
+
err = ioctl(kvm-vm_fd, KVM_CREATE_DEVICE, gic_device);
if (err)
return err;
 
gic_fd = gic_device.fd;
 
-   err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, cpu_if_attr);
+   switch (type) {
+   case IRQCHIP_GICV2:
+   err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, cpu_if_attr);
+   break;
+   }
if (err)
goto out_err;
 
@@ -80,13 +90,20 @@ static int gic__create_irqchip(struct kvm *kvm)
return err;
 }
 
-int gic__create(struct kvm *kvm)
+int gic__create(struct kvm *kvm, enum irqchip_type type)
 {
int err;
 
+   switch (type) {
+   case IRQCHIP_GICV2:
+   break;
+   default:
+   return -ENODEV;
+   }
+
/* Try the new way first, and fallback on legacy method otherwise */
-   err = gic__create_device(kvm);
-   if (err)
+   err = gic__create_device(kvm, type);
+   if (err  type == IRQCHIP_GICV2)
err = gic__create_irqchip(kvm);
 
return err;
@@ -134,15 +151,24 @@ static int gic__init_gic(struct kvm *kvm)
 }
 late_init(gic__init_gic)
 
-void gic__generate_fdt_nodes(void *fdt, u32 phandle)
+void gic__generate_fdt_nodes(void *fdt, u32 phandle, enum irqchip_type type)
 {
+   const char *compatible;
u64 reg_prop[] = {
cpu_to_fdt64(ARM_GIC_DIST_BASE), 
cpu_to_fdt64(ARM_GIC_DIST_SIZE),
cpu_to_fdt64(ARM_GIC_CPUI_BASE), 
cpu_to_fdt64(ARM_GIC_CPUI_SIZE),
};
 
+   switch (type) {
+   case IRQCHIP_GICV2:
+   compatible = arm,cortex-a15-gic;
+   break;
+   default:
+   return;
+   }
+
_FDT(fdt_begin_node(fdt, intc));
-   _FDT(fdt_property_string(fdt, compatible, arm,cortex-a15-gic));
+   _FDT(fdt_property_string(fdt, compatible, compatible));
_FDT(fdt_property_cell(fdt, #interrupt-cells, GIC_FDT_IRQ_NUM_CELLS));
_FDT(fdt_property(fdt, interrupt-controller, NULL, 0));
_FDT(fdt_property(fdt, reg, reg_prop, sizeof(reg_prop)));
diff --git a/arm/include/arm-common/gic.h b/arm/include/arm-common/gic.h
index 44859f7..d524f55 100644
--- a/arm/include/arm-common/gic.h
+++ b/arm/include/arm-common/gic.h
@@ -21,10 +21,14 @@
 #define GIC_MAX_CPUS

[PATCH v5 05/10] arm: finish VGIC initialisation explicitly

2015-07-03 Thread Andre Przywara
Since Linux 3.19-rc1 there is a new API to explicitly initialise
the in-kernel GIC emulation by a userland KVM device call.
Use that to tell the kernel we are finished with the GIC
initialisation, since the automatic GIC init will only be provided
as a legacy functionality in the future.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
Reviewed-by: Marc Zyngier marc.zyng...@arm.com
---
 arm/gic.c | 25 ++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/arm/gic.c b/arm/gic.c
index 8560c9b..99f0d2b 100644
--- a/arm/gic.c
+++ b/arm/gic.c
@@ -98,24 +98,43 @@ int gic__create(struct kvm *kvm)
return err;
 }
 
+/*
+ * Sets the number of used interrupts and finalizes the GIC init explicitly.
+ */
 static int gic__init_gic(struct kvm *kvm)
 {
+   int ret;
+
int lines = irq__get_nr_allocated_lines();
u32 nr_irqs = ALIGN(lines, 32) + GIC_SPI_IRQ_BASE;
struct kvm_device_attr nr_irqs_attr = {
.group  = KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
.addr   = (u64)(unsigned long)nr_irqs,
};
+   struct kvm_device_attr vgic_init_attr = {
+   .group  = KVM_DEV_ARM_VGIC_GRP_CTRL,
+   .attr   = KVM_DEV_ARM_VGIC_CTRL_INIT,
+   };
 
/*
 * If we didn't use the KVM_CREATE_DEVICE method, KVM will
-* give us some default number of interrupts.
+* give us some default number of interrupts. The GIC initialization
+* will be done automatically in this case.
 */
if (gic_fd  0)
return 0;
 
-   if (!ioctl(gic_fd, KVM_HAS_DEVICE_ATTR, nr_irqs_attr))
-   return ioctl(gic_fd, KVM_SET_DEVICE_ATTR, nr_irqs_attr);
+   if (!ioctl(gic_fd, KVM_HAS_DEVICE_ATTR, nr_irqs_attr)) {
+   ret = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, nr_irqs_attr);
+   if (ret)
+   return ret;
+   }
+
+   if (!ioctl(gic_fd, KVM_HAS_DEVICE_ATTR, vgic_init_attr)) {
+   ret = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, vgic_init_attr);
+   if (ret)
+   return ret;
+   }
 
return 0;
 }
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/7] KVM: api: add kvm_irq_routing_extended_msi

2015-07-02 Thread Andre Przywara
Hi Eric,

On 02/07/15 15:49, Eric Auger wrote:
 Hi Pavel,
 On 07/02/2015 09:26 AM, Pavel Fedin wrote:
  Hello!

 -Original Message-
 From: kvm-ow...@vger.kernel.org [mailto:kvm-ow...@vger.kernel.org] On 
 Behalf Of Eric Auger
 Sent: Monday, June 29, 2015 6:37 PM
 To: eric.au...@st.com; eric.au...@linaro.org; 
 linux-arm-ker...@lists.infradead.org;
 marc.zyng...@arm.com; christoffer.d...@linaro.org; andre.przyw...@arm.com;
 kvm...@lists.cs.columbia.edu; kvm@vger.kernel.org
 Cc: linux-ker...@vger.kernel.org; patc...@linaro.org; p.fe...@samsung.com; 
 pbonz...@redhat.com
 Subject: [PATCH 1/7] KVM: api: add kvm_irq_routing_extended_msi

 On ARM, the MSI msg (address and data) comes along with
 out-of-band device ID information. The device ID encodes the device
 that composes the MSI msg. Let's create a new routing entry type,
 dubbed KVM_IRQ_ROUTING_EXTENDED_MSI and use the __u32 pad space
 to convey the device ID.

 Signed-off-by: Eric Auger eric.au...@linaro.org

 ---

 RFC - PATCH
 - remove kvm_irq_routing_extended_msi and use union instead
 ---
  Documentation/virtual/kvm/api.txt | 9 -
  include/uapi/linux/kvm.h  | 6 +-
  2 files changed, 13 insertions(+), 2 deletions(-)

 diff --git a/Documentation/virtual/kvm/api.txt 
 b/Documentation/virtual/kvm/api.txt
 index d20fd94..6426ae9 100644
 --- a/Documentation/virtual/kvm/api.txt
 +++ b/Documentation/virtual/kvm/api.txt
 @@ -1414,7 +1414,10 @@ struct kvm_irq_routing_entry {
 __u32 gsi;
 __u32 type;
 __u32 flags;
 -   __u32 pad;
 +   union {
 +   __u32 pad;
 +   __u32 devid;
 +   };
 union {
 struct kvm_irq_routing_irqchip irqchip;
 struct kvm_irq_routing_msi msi;

  devid is actually a part of MSI bunch. Shouldn't it be a part of struct 
 kvm_irq_routing_msi then?
 It also has reserved pad.
 Well this makes sense to me to associate the devid to the msi and put
 devid in the pad field of struct kvm_irq_routing_msi.
 
 André, Christoffer, would you agree on this change? - I would like to
 avoid doing/undoing things ;-) -

Yes, that makes sense to me. TBH I haven't had a closer look at the
patches yet, but clearly devid belongs into struct kvm_irq_routing_msi.


 @@ -1427,6 +1430,10 @@ struct kvm_irq_routing_entry {
  #define KVM_IRQ_ROUTING_IRQCHIP 1
  #define KVM_IRQ_ROUTING_MSI 2
  #define KVM_IRQ_ROUTING_S390_ADAPTER 3
 +#define KVM_IRQ_ROUTING_EXTENDED_MSI 4
 +
 +In case of KVM_IRQ_ROUTING_EXTENDED_MSI routing type, devid is used to 
 convey
 +the device ID.

  No flags are specified so far, the corresponding field must be set to zero.

 What if we use KVM_MSI_VALID_DEVID flag instead of new 
 KVM_IRQ_ROUTING_EXTENDED_MSI definition? I
 believe this would make an API more consistent and introduce less new 
 definitions.
 do you mean using type == KVM_IRQ_ROUTING_MSI and flag ==
 KVM_MSI_VALID_DEVID? Not sure this is simpler/clearer. s390 paved the
 way for new routing entry types. I add a new one here.

I tend to agree with Pavel's solution. When hacking IRQ routing support
into kvmtool I saw that it's nasty being forced to differentiate between
the two MSI routing types. Actually userland should be able to query the
kernel about what kind of routing it requires. Also there is the issue
that we must _not_ set the flag on x86, since that breaks older kernels
(due to that check that Eric removes in 3/7).
So from my point of view the cleanest solution would be to always use
KVM_IRQ_ROUTING_MSI, and add the device ID if the kernel needs it (true
for ITS guests, false for GICv2M, x86, ...)
I am looking for a clever solution for this now.

Cheers,
Andre.

 
 Another solution may be to use new KVM_IRQ_ROUTING_EXTENDED_MSI type and
 add struct kvm_msi ext_msi in kvm_irq_routing_entry union. It is 8 words
 as well. But most probably this is even uglier.

 
 Let's see if this thread is heading to a consensus...
 
 Best Regards
 
 Eric


 diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
 index 2a23705..8484681 100644
 --- a/include/uapi/linux/kvm.h
 +++ b/include/uapi/linux/kvm.h
 @@ -841,12 +841,16 @@ struct kvm_irq_routing_s390_adapter {
  #define KVM_IRQ_ROUTING_IRQCHIP 1
  #define KVM_IRQ_ROUTING_MSI 2
  #define KVM_IRQ_ROUTING_S390_ADAPTER 3
 +#define KVM_IRQ_ROUTING_EXTENDED_MSI 4

  struct kvm_irq_routing_entry {
 __u32 gsi;
 __u32 type;
 __u32 flags;
 -   __u32 pad;
 +   union {
 +   __u32 pad;
 +   __u32 devid;
 +   };
 union {
 struct kvm_irq_routing_irqchip irqchip;
 struct kvm_irq_routing_msi msi;
 --
 1.9.1

 --
 To unsubscribe from this list: send the line unsubscribe kvm in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html

 Kind regards,
 Pavel Fedin
 Expert Engineer
 Samsung Electronics Research center Russia

 
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org

Re: [PATCH 7/7] KVM: arm: implement kvm_set_msi by gsi direct mapping

2015-07-02 Thread Andre Przywara
Hi Eric,

On 29/06/15 16:37, Eric Auger wrote:
 If the ITS modality is not available, let's simply support MSI
 injection by transforming the MSI.data into an SPI ID.
 
 This becomes possible to use KVM_SIGNAL_MSI ioctl for arm too.
 
 Signed-off-by: Eric Auger eric.au...@linaro.org
 ---
  arch/arm/kvm/Kconfig | 1 +
  virt/kvm/arm/vgic.c  | 5 +
  2 files changed, 6 insertions(+)
 
 diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig
 index 151e710..0f58baf 100644
 --- a/arch/arm/kvm/Kconfig
 +++ b/arch/arm/kvm/Kconfig
 @@ -31,6 +31,7 @@ config KVM
   select KVM_VFIO
   select HAVE_KVM_EVENTFD
   select HAVE_KVM_IRQFD
 + select HAVE_KVM_MSI
   select HAVE_KVM_IRQCHIP
   select HAVE_KVM_IRQ_ROUTING
   depends on ARM_VIRT_EXT  ARM_LPAE  ARM_ARCH_TIMER
 diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
 index 0b4c48c..b3c10dc 100644
 --- a/virt/kvm/arm/vgic.c
 +++ b/virt/kvm/arm/vgic.c
 @@ -2314,6 +2314,11 @@ int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
   return kvm-arch.vgic.vm_ops.inject_msi(kvm, msi);
   else
   return -ENODEV;
 + case KVM_IRQ_ROUTING_MSI:
 + if (kvm-arch.vgic.vm_ops.inject_msi)
 + return -EINVAL;
 + else
 + return kvm_vgic_inject_irq(kvm, 0, e-msi.data, level);

If you add:

static int vgic_v2m_inject_msi(struct kvm *kvm, struct kvm_msi *msi)
{
return kvm_vgic_inject_irq(kvm, 0, msi-data, 1);
}

to vgic-v2-emul.c and wire it up accordingly, you can simplify the above
kvm_set_msi, getting rid of all those extra case handling.
This also helps merging KVM_IRQ_ROUTING_MSI and the extended case.

I have hacked this up and it seems to work for me.

Cheers,
Andre.
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/7] KVM: kvm_host: add kvm_extended_msi

2015-07-02 Thread Andre Przywara
Hi Eric,

just played a bit with the code and I could make things easier by the
following change:

On 29/06/15 16:37, Eric Auger wrote:
 Add a new kvm_extended_msi struct to store the additional device ID
 specific to ARM. kvm_kernel_irq_routing_entry union now encompasses
 this new struct.
 
 Signed-off-by: Eric Auger eric.au...@linaro.org
 
 ---
 
 RFC - PATCH:
 - reword the commit message after change in first patch (uapi)
 ---
  include/linux/kvm_host.h | 8 
  1 file changed, 8 insertions(+)
 
 diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
 index ad45054..e1c1c0d 100644
 --- a/include/linux/kvm_host.h
 +++ b/include/linux/kvm_host.h
 @@ -304,6 +304,13 @@ struct kvm_s390_adapter_int {
   u32 adapter_id;
  };
  
 +struct kvm_extended_msi {
 + u32 address_lo; /* low 32 bits of msi message address */
 + u32 address_hi; /* high 32 bits of msi message address */
 + u32 data;   /* 16 bits of msi message data */
 + u32 devid;  /* out-of-band device ID */
 +};
 +

I got rid of this structure at all, instead using:

 @@ -317,6 +324,7 @@ struct kvm_kernel_irq_routing_entry {
} irqchip;
-   struct msi_msg msi;
+   struct {
+   struct msi_msg msi;
+   u32 devid;
+   };
struct kvm_s390_adapter_int adapter;
};
struct hlist_node link;
  };

This re-uses the existing MSI fields in struct msi_msg, so all the extra
code you added in the next patches to set address and data could be
skipped. If needed we can add a flags field here as well to avoid that
extra type.
That simplified a lot for me.

Cheers,
André
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 4/7] KVM: arm/arm64: enable irqchip routing

2015-06-30 Thread Andre Przywara
Hi Eric,

On 29/06/15 16:37, Eric Auger wrote:
 This patch adds compilation and link against irqchip.
 
 On ARM, irqchip routing is not really useful since there is
 a single irqchip. However main motivation behind using irqchip
 code is to enable MSI routing code. With the support of in-kernel
 GICv3 ITS emulation, it now seems to be a MUST HAVE requirement.
 
 Functions previously implemented in vgic.c and substitute
 to more complex irqchip implementation are removed:
 
 - kvm_send_userspace_msi
 - kvm_irq_map_chip_pin
 - kvm_set_irq
 - kvm_irq_map_gsi.
 
 They implemented a kernel default identity GSI routing. This is now
 replaced by user-side provided routing.
 
 Routing standard hooks are now implemented in vgic:
 - kvm_set_routing_entry
 - kvm_set_irq
 - kvm_set_msi
 
 Both HAVE_KVM_IRQCHIP and HAVE_KVM_IRQ_ROUTING are defined.
 KVM_CAP_IRQ_ROUTING is advertised and KVM_SET_GSI_ROUTING is allowed.
 
 MSI routing is not yet allowed.
 
 Signed-off-by: Eric Auger eric.au...@linaro.org
 
...

 diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
 index 09b1f46..212a5ff 100644
 --- a/virt/kvm/arm/vgic.c
 +++ b/virt/kvm/arm/vgic.c
 @@ -2220,47 +2220,67 @@ out_free_irq:
   return ret;
  }
  
 -int kvm_irq_map_gsi(struct kvm *kvm,
 - struct kvm_kernel_irq_routing_entry *entries,
 - int gsi)
 +int vgic_irqfd_set_irq(struct kvm_kernel_irq_routing_entry *e,
 + struct kvm *kvm, int irq_source_id,
 + int level, bool line_status)
  {
 - return 0;
 -}
 -
 -int kvm_irq_map_chip_pin(struct kvm *kvm, unsigned irqchip, unsigned pin)
 -{
 - return pin;
 -}
 -
 -int kvm_set_irq(struct kvm *kvm, int irq_source_id,
 - u32 irq, int level, bool line_status)
 -{
 - unsigned int spi = irq + VGIC_NR_PRIVATE_IRQS;
 + unsigned int spi_id = e-irqchip.pin + VGIC_NR_PRIVATE_IRQS;
  
 - trace_kvm_set_irq(irq, level, irq_source_id);
 + trace_kvm_set_irq(spi_id, level, irq_source_id);
  
   BUG_ON(!vgic_initialized(kvm));
  
 - if (spi  kvm-arch.vgic.nr_irqs)
 + if (spi_id  kvm-arch.vgic.nr_irqs)
   return -EINVAL;
 - return kvm_vgic_inject_irq(kvm, 0, spi, level);
 + return kvm_vgic_inject_irq(kvm, 0, spi_id, level);
  
  }
  
 -/* MSI not implemented yet */
 +/**
 + * Populates a kvm routing entry from a user routing entry
 + * @e: kvm internal formatted entry
 + * @ue: user api formatted entry
 + * return 0 on success, -EINVAL on errors.
 + */
 +int kvm_set_routing_entry(struct kvm_kernel_irq_routing_entry *e,
 +   const struct kvm_irq_routing_entry *ue)
 +{
 + int r = -EINVAL;
 +
 + switch (ue-type) {
 + case KVM_IRQ_ROUTING_IRQCHIP:
 + e-set = vgic_irqfd_set_irq;
 + e-irqchip.irqchip = ue-u.irqchip.irqchip;
 + e-irqchip.pin = ue-u.irqchip.pin;
 + if ((e-irqchip.pin = KVM_IRQCHIP_NUM_PINS) ||
 + (e-irqchip.irqchip = KVM_NR_IRQCHIPS))
 + goto out;
 + break;
 + default:
 + goto out;
 + }
 + r = 0;
 +out:
 + return r;
 +}
 +
  int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
   struct kvm *kvm, int irq_source_id,
   int level, bool line_status)
  {
 - return 0;
 -}
 + struct kvm_msi msi;
  
 -#ifdef CONFIG_HAVE_KVM_MSI
 -int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi)
 -{
 - if (kvm-arch.vgic.vm_ops.inject_msi)
 - return kvm-arch.vgic.vm_ops.inject_msi(kvm, msi);
 - else
 - return -ENODEV;
 + switch (e-type) {
 + case KVM_IRQ_ROUTING_EXTENDED_MSI:
 + msi.address_lo = e-ext_msi.address_lo;
 + msi.address_hi = e-ext_msi.address_hi;
 + msi.data = e-ext_msi.data;
 + msi.flags = e-ext_msi.devid;

You probably meant to write:
+   msi.flags = KVM_MSI_VALID_DEVID;
+   msi.devid = e-ext_msi.devid;

With this change I could get it (your patches on top of my v1.5) to work
with my hacked kvmtool - at least with vhost=0. On to fixing irqfd now ...

Cheers,
Andre.

 + if (kvm-arch.vgic.vm_ops.inject_msi)
 + return kvm-arch.vgic.vm_ops.inject_msi(kvm, msi);
 + else
 + return -ENODEV;
 + default:
 + return -EINVAL;
 + }
  }
 -#endif
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 10/10] arm: use new irqchip parameter to create different vGIC types

2015-06-30 Thread Andre Przywara
On 30/06/15 17:13, Will Deacon wrote:
 On Fri, Jun 26, 2015 at 02:16:18PM +0100, Andre Przywara wrote:
 Currently we unconditionally create a virtual GICv2 in the guest.
 Add a --irqchip= parameter to let the user specify a different GIC
 type for the guest, when omitting this parameter it still defaults to
 --irqchip=gicv2.
 For now the only other supported type is --irqchip=gicv3

 Signed-off-by: Andre Przywara andre.przyw...@arm.com
 ---
  arm/aarch64/arm-cpu.c|  2 +-
  arm/gic.c| 17 +
  arm/include/arm-common/kvm-config-arch.h |  9 -
  arm/kvm.c|  2 +-
  4 files changed, 27 insertions(+), 3 deletions(-)

 diff --git a/arm/aarch64/arm-cpu.c b/arm/aarch64/arm-cpu.c
 index f702b9e..3dc8ea3 100644
 --- a/arm/aarch64/arm-cpu.c
 +++ b/arm/aarch64/arm-cpu.c
 @@ -12,7 +12,7 @@
  static void generate_fdt_nodes(void *fdt, struct kvm *kvm, u32 gic_phandle)
  {
  int timer_interrupts[4] = {13, 14, 11, 10};
 -gic__generate_fdt_nodes(fdt, gic_phandle, IRQCHIP_GICV2);
 +gic__generate_fdt_nodes(fdt, gic_phandle, kvm-cfg.arch.irqchip);
  timer__generate_fdt_nodes(fdt, kvm, timer_interrupts);
  }
  
 diff --git a/arm/gic.c b/arm/gic.c
 index efe4b42..ff56de7 100644
 --- a/arm/gic.c
 +++ b/arm/gic.c
 @@ -22,6 +22,23 @@ static int gic_fd = -1;
  static u64 gic_redists_base;
  static u64 gic_redists_size;
  
 +int irqchip_parser(const struct option *opt, const char *arg, int unset)
 +{
 +enum irqchip_type *type = opt-value;
 +
 +*type = IRQCHIP_GICV2;
 
 Pointless assignment?

Yeah, that's a leftover from some refactoring.

 
 +if (!strcmp(arg, gicv2)) {
 +*type = IRQCHIP_GICV2;
 +} else if (!strcmp(arg, gicv3)) {
 +*type = IRQCHIP_GICV3;
 +} else {
 +fprintf(stderr, irqchip: unknown type \%s\\n, arg);
 +return -1;
 +}
 +
 +return 0;
 +}
 +
  static int gic__create_device(struct kvm *kvm, enum irqchip_type type)
  {
  int err;
 diff --git a/arm/include/arm-common/kvm-config-arch.h 
 b/arm/include/arm-common/kvm-config-arch.h
 index a8ebd94..9529881 100644
 --- a/arm/include/arm-common/kvm-config-arch.h
 +++ b/arm/include/arm-common/kvm-config-arch.h
 @@ -8,8 +8,11 @@ struct kvm_config_arch {
  unsigned intforce_cntfrq;
  boolvirtio_trans_pci;
  boolaarch32_guest;
 +enum irqchip_type irqchip;
  };
  
 +int irqchip_parser(const struct option *opt, const char *arg, int unset);
 +
  #define OPT_ARCH_RUN(pfx, cfg)  
 \
  pfx,
 \
  ARM_OPT_ARCH_RUN(cfg)   
 \
 @@ -21,6 +24,10 @@ struct kvm_config_arch {
   updated to program CNTFRQ correctly*),   
 \
  OPT_BOOLEAN('\0', force-pci, (cfg)-virtio_trans_pci,
 \
  Force virtio devices to use PCI as their default  
 \
 -transport),
 +transport),   
 \
 +OPT_CALLBACK('\0', irqchip, (cfg)-irqchip,  
 \
 + [gicv2|gicv3],   \
 + type of interrupt controller to emulate in the guest,
 \
 + irqchip_parser, NULL),
 
 What happens if I don't pass this option at all?

Then (cfg)-irqchip will be 0 as all the other configuration parameters
because they are part of struct kvm, which is calloc()ed.
So it will be IRQCHIP_GICV2, as that is the first entry in the enum.
Admittedly a bit convoluted, do you want a comment or an explicit
enum { IRQCHIP_GICV2 = 0, ...}?

Cheers,
Andre.
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 07/10] limit number of VCPUs on demand

2015-06-30 Thread Andre Przywara
Hi,

On 30/06/15 17:09, Will Deacon wrote:
 On Fri, Jun 26, 2015 at 02:16:15PM +0100, Andre Przywara wrote:
 Currently the ARM GIC checks the number of VCPUs against a fixed
 limit, which is GICv2 specific. Don't pretend we know better than the
 kernel and let's get rid of that explicit check.
 Instead be more relaxed about KVM_CREATE_VCPU failing with EINVAL,
 which is the way the kernel communicates having reached a VCPU limit.
 If we see this and have at least brought up one VCPU already
 successfully, then don't panic, but limit the number of VCPUs instead.

 Signed-off-by: Andre Przywara andre.przyw...@arm.com
 ---
  arm/gic.c | 6 --
  arm/kvm-cpu.c | 7 ++-
  kvm-cpu.c | 7 +++
  3 files changed, 13 insertions(+), 7 deletions(-)

 diff --git a/arm/gic.c b/arm/gic.c
 index 99f0d2b..05f85a2 100644
 --- a/arm/gic.c
 +++ b/arm/gic.c
 @@ -84,12 +84,6 @@ int gic__create(struct kvm *kvm)
  {
  int err;
  
 -if (kvm-nrcpus  GIC_MAX_CPUS) {
 -pr_warning(%d CPUS greater than maximum of %d -- truncating\n,
 -kvm-nrcpus, GIC_MAX_CPUS);
 -kvm-nrcpus = GIC_MAX_CPUS;
 -}
 -
  /* Try the new way first, and fallback on legacy method otherwise */
  err = gic__create_device(kvm);
  if (err)
 diff --git a/arm/kvm-cpu.c b/arm/kvm-cpu.c
 index 7780251..b2fd6ed 100644
 --- a/arm/kvm-cpu.c
 +++ b/arm/kvm-cpu.c
 @@ -51,8 +51,13 @@ struct kvm_cpu *kvm_cpu__arch_init(struct kvm *kvm, 
 unsigned long cpu_id)
  return NULL;
  
  vcpu-vcpu_fd = ioctl(kvm-vm_fd, KVM_CREATE_VCPU, cpu_id);
 -if (vcpu-vcpu_fd  0)
 +if (vcpu-vcpu_fd  0) {
 +if (errno == EINVAL) {
 +free(vcpu);
 +return NULL;
 +}
 
 Hmm, but EINVAL can mean all sorts of other failures too, surely?

Not for ARM, at least not at the moment. I went through all the cases -
I think up to 8 levels deep - and exceeding the number of VCPUs is the
only case where we return EINVAL for KVM_CREATE_VCPU.

 I'm
 not against removing the nrcpus check, but I think we should die if ioctls
 start failing rather than silently ignore them.

I see your point, but at least we don't fail silently: if we exit the
loop prematurely, we print the warning about limiting the number of VCPUs.
I agree that the proper solution would be to just explicitly ask the
kernel about the number of VCPUs, but on ARM this is not reliable at the
moment due to kernel behaviour, and any fix there would still not affect
older kernels.

Cheers,
Andre.
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] kvmtool: don't use PCI config space IRQ line field

2015-06-29 Thread Andre Przywara
Hi Will,

On 29/06/15 11:10, Will Deacon wrote:
 Hi Andre,
 
 On Thu, Jun 18, 2015 at 06:19:53PM +0100, Andre Przywara wrote:
 I am tempted to remove shmem, since it's broken:
 a) there is no upstream driver, only some out-of-tree uio driver module
 in some Github repo
 
 Right, but that's the same for qemu and we've already made the jump of
 merging the driver, so I don't think that's a good argument for throwing
 it out of the tree.

If this driver has some future in the Linux tree, I agree it's worth to
keep it in, though I didn't see any effort to merge it lately.

 b) the PCI device BARs do not match what QEMU implements and what the
 uio driver expects (IO BAR vs. MMIO BAR)
 
 In what way? A quick look suggests that kvmtool is at least aligned with
 said github repo.

The first BAR holds the control registers, QEMU and the UIO driver
require an MMIO region, kvmtool uses PIO :-(

 c) there is (at least one) bug in kvmtool (easily fixed, though)

The size of the control register region in BAR0 is set to the size of
the shared memory region, where it should be some constant size (at
least 16 Bytes, QEMU uses 256, the spec says 1K, pick one ;-)
As PIO on x86 is at most 64K, this BAR gets ignored by the kernel with
any shmem size above that (it defaults to 4M).
As said the fix is easy, but ...

Those two bugs alone make we wonder if that ever worked on kvmtool,
obviously not with that UIO driver (which seems to work on QEMU).
I have fixes for both issues, but I haven't had a chance of testing this
in real action (just the driver loaded and lspci looking sensible). I
may send the patches later, but this doesn't have high priority for me
(unless someone bugs me ;-)

Cheers,
Andre.
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 0/3] KVM: arm: Implement software vGICv2 emulation

2015-06-29 Thread Andre Przywara
Hi,

On 29/06/15 13:52, Christoffer Dall wrote:
 Hi Pavel,
 
 [Please cc the kvm/arm list for such patches according to the
 MAINTAINERS file in the future]
 
 On Mon, Jun 29, 2015 at 12:53:46PM +0300, Pavel Fedin wrote:
 Some hardware (like Raspberry Pi 2) is capable of running KVM, however lacks
 functional vGIC registers. This series introduces software vGIC emulation for
 such machines, allowing to fully use virtualization capabilities
 
 Is this rather esoteric use case really worth the extra code in the
 kernel? 

I wonder if these patches would pave the way to support running GICv2
guests on GICv3s without compat support? Admittedly not a really
compelling use case either, but at least worth discussing, I think.

Also if this will make the hack needed to enable KVM on RPi2 smaller,
I'd rather embrace this one than letting any random hacks appear on that
RPi kernel tree (patches which I have seen already on some other repo).
If I get this correctly, there are some efforts currently to get closer
to mainline with the RPi tree.

Pavel, is this broken GIC you are talking about going to appear in a
publicly available SoC? If yes, you could either state this right now or
send it later once you can talk publicly.

Marc, Christoffer:
So is this GICv2 CPU interface emulation totally out of question for us
or is it worth at least commenting on the patches?

Cheers,
Andre.

 I really feel that pure emulation should happen in userspace
 unless there's a very good reason for doing it in the kernel, such as a
 clearly measureable difference in performance, etc.
 
 I would much rather see a version of this where a userspace provided GIC
 works with the in-kernel arch timers support.
 
 -Christoffer
 
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 02/13] KVM: extend struct kvm_msi to hold a 32-bit device ID

2015-06-29 Thread Andre Przywara
Hi Christoffer,

thanks for your time to reviewing this! Was probably no pleasure ;-)

On 28/06/15 20:12, Christoffer Dall wrote:
 On Fri, May 29, 2015 at 10:53:18AM +0100, Andre Przywara wrote:
 The ARM GICv3 ITS MSI controller requires a device ID to be able to
 assign the proper interrupt vector. On real hardware, this ID is
 sampled from the bus. To be able to emulate an ITS controller, extend
 the KVM MSI interface to let userspace provide such a device ID. For
 PCI devices, the device ID is simply the 16-bit bus-device-function
 triplet, which should be easily available to the userland tool.

 Signed-off-by: Andre Przywara andre.przyw...@arm.com
 ---
  Documentation/virtual/kvm/api.txt | 8 ++--
  include/uapi/linux/kvm.h  | 4 +++-
  2 files changed, 9 insertions(+), 3 deletions(-)

 diff --git a/Documentation/virtual/kvm/api.txt 
 b/Documentation/virtual/kvm/api.txt
 index 9fa2bf8..891d64a 100644
 --- a/Documentation/virtual/kvm/api.txt
 +++ b/Documentation/virtual/kvm/api.txt
 @@ -2121,10 +2121,14 @@ struct kvm_msi {
  __u32 address_hi;
  __u32 data;
  __u32 flags;
 -__u8  pad[16];
 +__u32 devid;
 +__u8  pad[12];
  };
  
 -No flags are defined so far. The corresponding field must be 0.
 +flags: KVM_MSI_VALID_DEVID: devid is valid, otherwise ignored.
 
 I don't see what the 'otherwise ignored' part of the sentence here is
 meant to say, that the flags field is otherwise ignored for other value?

No, that the devid field is ignored if this bit isn't set. I can
rephrase this to be more explicit.

 That's not what the current API doc specifies, it specifies that the
 remainder of the field must be 0.
 
 +devid: If KVM_MSI_VALID_DEVID is set, contains a value to identify the 
 device
 +   that wrote the MSI message. For PCI, this is usually a BFD
 +   identifier in the lower 16 bits.
 
 I assume plus something else that uniquely identifies the PCI
 controller?

Well yes, the device ID is a unique device identifier within a system,
the BFD use case was just to illustrate this and give a hint to
userspace what to fill in there. I will explain this better in v2.

So are you OK with that extension of the API in general? Just asking
because there is a lot that depends on it.

Cheers,
Andre.
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] kvmtool: vhost-net: fix ioeventfd registration

2015-06-26 Thread Andre Przywara
On registering the ioeventfds for the virtio-pci device we cover both
the I/O ports and the MMIO BAR.
But as the current code advertises both as PIO, the host kernel gets
the wrong bus number for the MMIO region.
Fix the issue by marking only the actual PIO area as PIO.
This fixes vhost-net on x86.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 virtio/pci.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/virtio/pci.c b/virtio/pci.c
index 2dff13b..90fcd64 100644
--- a/virtio/pci.c
+++ b/virtio/pci.c
@@ -25,7 +25,7 @@ static int virtio_pci__init_ioeventfd(struct kvm *kvm, struct 
virtio_device *vde
 {
struct ioevent ioevent;
struct virtio_pci *vpci = vdev-virtio;
-   int i, r, flags = IOEVENTFD_FLAG_PIO;
+   int i, r, flags = 0;
int fds[2];
 
vpci-ioeventfds[vq] = (struct virtio_pci_ioevent_param) {
@@ -51,7 +51,7 @@ static int virtio_pci__init_ioeventfd(struct kvm *kvm, struct 
virtio_device *vde
ioevent.io_addr = vpci-port_addr + VIRTIO_PCI_QUEUE_NOTIFY;
ioevent.io_len  = sizeof(u16);
ioevent.fd  = fds[0] = eventfd(0, 0);
-   r = ioeventfd__add_event(ioevent, flags);
+   r = ioeventfd__add_event(ioevent, flags | IOEVENTFD_FLAG_PIO);
if (r)
return r;
 
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 01/10] AArch64: Reserve two 64k pages for GIC CPU interface

2015-06-26 Thread Andre Przywara
From: Marc Zyngier marc.zyng...@arm.com

On AArch64 system with a GICv2, the GICC range can be aligned
to the last 4k block of a 64k page, ending up straddling two
64k pages. In order not to conflict with the distributor mapping,
allocate two 64k pages to the CPU interface.

Signed-off-by: Marc Zyngier marc.zyng...@arm.com
Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 arm/aarch64/include/kvm/kvm-arch.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arm/aarch64/include/kvm/kvm-arch.h 
b/arm/aarch64/include/kvm/kvm-arch.h
index 2f08a26..4925736 100644
--- a/arm/aarch64/include/kvm/kvm-arch.h
+++ b/arm/aarch64/include/kvm/kvm-arch.h
@@ -2,7 +2,7 @@
 #define KVM__KVM_ARCH_H
 
 #define ARM_GIC_DIST_SIZE  0x1
-#define ARM_GIC_CPUI_SIZE  0x1
+#define ARM_GIC_CPUI_SIZE  0x2
 
 #define ARM_KERN_OFFSET(kvm)   ((kvm)-cfg.arch.aarch32_guest  ?   \
0x8000  :   \
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 08/10] arm: prepare for instantiating different IRQ chip devices

2015-06-26 Thread Andre Przywara
Extend the vGIC handling code to potentially deal with different IRQ
chip devices instead of hard-coding the GICv2 in.
We extend most vGIC functions to take a type parameter, but still put
GICv2 in at the top for the time being.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
Reviewed-by: Marc Zyngier marc.zyng...@arm.com
---
 arm/aarch32/arm-cpu.c|  2 +-
 arm/aarch64/arm-cpu.c|  2 +-
 arm/gic.c| 44 +++-
 arm/include/arm-common/gic.h |  8 ++--
 arm/kvm.c|  2 +-
 5 files changed, 44 insertions(+), 14 deletions(-)

diff --git a/arm/aarch32/arm-cpu.c b/arm/aarch32/arm-cpu.c
index 946e443..d8d6293 100644
--- a/arm/aarch32/arm-cpu.c
+++ b/arm/aarch32/arm-cpu.c
@@ -12,7 +12,7 @@ static void generate_fdt_nodes(void *fdt, struct kvm *kvm, 
u32 gic_phandle)
 {
int timer_interrupts[4] = {13, 14, 11, 10};
 
-   gic__generate_fdt_nodes(fdt, gic_phandle);
+   gic__generate_fdt_nodes(fdt, gic_phandle, IRQCHIP_GICV2);
timer__generate_fdt_nodes(fdt, kvm, timer_interrupts);
 }
 
diff --git a/arm/aarch64/arm-cpu.c b/arm/aarch64/arm-cpu.c
index 8efe877..f702b9e 100644
--- a/arm/aarch64/arm-cpu.c
+++ b/arm/aarch64/arm-cpu.c
@@ -12,7 +12,7 @@
 static void generate_fdt_nodes(void *fdt, struct kvm *kvm, u32 gic_phandle)
 {
int timer_interrupts[4] = {13, 14, 11, 10};
-   gic__generate_fdt_nodes(fdt, gic_phandle);
+   gic__generate_fdt_nodes(fdt, gic_phandle, IRQCHIP_GICV2);
timer__generate_fdt_nodes(fdt, kvm, timer_interrupts);
 }
 
diff --git a/arm/gic.c b/arm/gic.c
index 05f85a2..b6c5868 100644
--- a/arm/gic.c
+++ b/arm/gic.c
@@ -11,13 +11,13 @@
 
 static int gic_fd = -1;
 
-static int gic__create_device(struct kvm *kvm)
+static int gic__create_device(struct kvm *kvm, enum irqchip_type type)
 {
int err;
u64 cpu_if_addr = ARM_GIC_CPUI_BASE;
u64 dist_addr = ARM_GIC_DIST_BASE;
struct kvm_create_device gic_device = {
-   .type   = KVM_DEV_TYPE_ARM_VGIC_V2,
+   .flags  = 0,
};
struct kvm_device_attr cpu_if_attr = {
.group  = KVM_DEV_ARM_VGIC_GRP_ADDR,
@@ -26,17 +26,27 @@ static int gic__create_device(struct kvm *kvm)
};
struct kvm_device_attr dist_attr = {
.group  = KVM_DEV_ARM_VGIC_GRP_ADDR,
-   .attr   = KVM_VGIC_V2_ADDR_TYPE_DIST,
.addr   = (u64)(unsigned long)dist_addr,
};
 
+   switch (type) {
+   case IRQCHIP_GICV2:
+   gic_device.type = KVM_DEV_TYPE_ARM_VGIC_V2;
+   dist_attr.attr  = KVM_VGIC_V2_ADDR_TYPE_DIST;
+   break;
+   }
+
err = ioctl(kvm-vm_fd, KVM_CREATE_DEVICE, gic_device);
if (err)
return err;
 
gic_fd = gic_device.fd;
 
-   err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, cpu_if_attr);
+   switch (type) {
+   case IRQCHIP_GICV2:
+   err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, cpu_if_attr);
+   break;
+   }
if (err)
goto out_err;
 
@@ -80,13 +90,20 @@ static int gic__create_irqchip(struct kvm *kvm)
return err;
 }
 
-int gic__create(struct kvm *kvm)
+int gic__create(struct kvm *kvm, enum irqchip_type type)
 {
int err;
 
+   switch (type) {
+   case IRQCHIP_GICV2:
+   break;
+   default:
+   return -ENODEV;
+   }
+
/* Try the new way first, and fallback on legacy method otherwise */
-   err = gic__create_device(kvm);
-   if (err)
+   err = gic__create_device(kvm, type);
+   if (err  type == IRQCHIP_GICV2)
err = gic__create_irqchip(kvm);
 
return err;
@@ -134,15 +151,24 @@ static int gic__init_gic(struct kvm *kvm)
 }
 late_init(gic__init_gic)
 
-void gic__generate_fdt_nodes(void *fdt, u32 phandle)
+void gic__generate_fdt_nodes(void *fdt, u32 phandle, enum irqchip_type type)
 {
+   const char *compatible;
u64 reg_prop[] = {
cpu_to_fdt64(ARM_GIC_DIST_BASE), 
cpu_to_fdt64(ARM_GIC_DIST_SIZE),
cpu_to_fdt64(ARM_GIC_CPUI_BASE), 
cpu_to_fdt64(ARM_GIC_CPUI_SIZE),
};
 
+   switch (type) {
+   case IRQCHIP_GICV2:
+   compatible = arm,cortex-a15-gic;
+   break;
+   default:
+   return;
+   }
+
_FDT(fdt_begin_node(fdt, intc));
-   _FDT(fdt_property_string(fdt, compatible, arm,cortex-a15-gic));
+   _FDT(fdt_property_string(fdt, compatible, compatible));
_FDT(fdt_property_cell(fdt, #interrupt-cells, GIC_FDT_IRQ_NUM_CELLS));
_FDT(fdt_property(fdt, interrupt-controller, NULL, 0));
_FDT(fdt_property(fdt, reg, reg_prop, sizeof(reg_prop)));
diff --git a/arm/include/arm-common/gic.h b/arm/include/arm-common/gic.h
index 44859f7..d524f55 100644
--- a/arm/include/arm-common/gic.h
+++ b/arm/include/arm-common/gic.h
@@ -21,10 +21,14 @@
 #define GIC_MAX_CPUS

[PATCH v4 00/10] kvmtool: arm64: GICv3 guest support

2015-06-26 Thread Andre Przywara
Hi,

hopefully the final version of the GICv3 support series for kvmtool.
I addressed the remaining comments Marc had on the last four patches
(the first six were left untouched).
The undocumented --irqchip=default is now gone.

Cheers,
Andre.

-
Since Linux 3.19 the kernel can emulate a GICv3 for KVM guests.
This allows more than 8 VCPUs in a guest and enables in-kernel irqchip
for non-backwards-compatible GICv3 implementations.

This series updates kvmtool to support this feature.
The first half of the series is mostly from Marc and supports some
newer features of the virtual GIC which we later depend on. The second
part enables support for a guest GICv3 by adding a new command line
parameter (--irqchip=).

We now use the KVM_CREATE_DEVICE interface to create a virtual GIC
and only fall back to the now legacy KVM_CREATE_IRQCHIP call if the
former is not supported by the kernel.
Also we use two new features the KVM_CREATE_DEVICE interface
introduces:
* We now set the number of actually used interrupts to avoid
  allocating too many of them without ever using them.
* We tell the kernel explicitly that we are finished with the GIC
  initialisation. This is a requirement for future VGIC versions.

The final three patches introduce virtual GICv3 support, so on
supported hardware (and given kernel support) the user can ask KVM to
emulate a GICv3, lifting the 8 VCPU limit of KVM. This is done by
specifying --irqchip=gicv3 on the command line.
For the time being the kernel only supports a virtual GICv3 on ARM64,
but as the GIC is shared in kvmtool, I had to add the macro
definitions to not break the build on ARM.

This series goes on top of the new official stand-alone repo hosted
on Will's kernel.org git [1].
Find a branch with those patches included at my repo [2].

[1] git://git.kernel.org/pub/scm/linux/kernel/git/will/kvmtool.git
[2] git://linux-arm.org/kvmtool.git (branch gicv3/v4)
http://www.linux-arm.org/git?p=kvmtool.git;a=log;h=refs/heads/gicv3/v4

Andre Przywara (6):
  arm: finish VGIC initialisation explicitly
  arm: simplify MMIO dispatching
  limit number of VCPUs on demand
  arm: prepare for instantiating different IRQ chip devices
  arm: add support for supplying GICv3 redistributor addresses
  arm: use new irqchip parameter to create different vGIC types

Marc Zyngier (4):
  AArch64: Reserve two 64k pages for GIC CPU interface
  AArch{32,64}: use KVM_CREATE_DEVICE  co to instanciate the GIC
  irq: add irq__get_nr_allocated_lines
  AArch{32,64}: dynamically configure the number of GIC interrupts

 arm/aarch32/arm-cpu.c|   2 +-
 arm/aarch64/arm-cpu.c|   2 +-
 arm/aarch64/include/kvm/kvm-arch.h   |   2 +-
 arm/gic.c| 190 +--
 arm/include/arm-common/gic.h |   9 +-
 arm/include/arm-common/kvm-arch.h|  19 ++--
 arm/include/arm-common/kvm-config-arch.h |   9 +-
 arm/include/arm-common/kvm-cpu-arch.h|  14 ++-
 arm/kvm-cpu.c|  23 +---
 arm/kvm.c|   6 +-
 include/kvm/irq.h|   1 +
 irq.c|   5 +
 kvm-cpu.c|   7 ++
 13 files changed, 239 insertions(+), 50 deletions(-)

-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 09/10] arm: add support for supplying GICv3 redistributor addresses

2015-06-26 Thread Andre Przywara
Instead of the GIC virtual CPU interface an emulated GICv3 needs to
have accesses to its emulated redistributors trapped in the guest.
Add code to tell the kernel about the mapping if a GICv3 emulation was
requested by the user.

This contains some defines which are not (yet) in the (32 bit) header
files to allow compilation for ARM.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
Reviewed-by: Marc Zyngier marc.zyng...@arm.com
---
 arm/gic.c | 36 +++-
 arm/include/arm-common/gic.h  |  1 +
 arm/include/arm-common/kvm-arch.h |  7 +++
 3 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/arm/gic.c b/arm/gic.c
index b6c5868..efe4b42 100644
--- a/arm/gic.c
+++ b/arm/gic.c
@@ -9,7 +9,18 @@
 #include linux/kernel.h
 #include linux/kvm.h
 
+/* Those names are not defined for ARM (yet) */
+#ifndef KVM_VGIC_V3_ADDR_TYPE_DIST
+#define KVM_VGIC_V3_ADDR_TYPE_DIST 2
+#endif
+
+#ifndef KVM_VGIC_V3_ADDR_TYPE_REDIST
+#define KVM_VGIC_V3_ADDR_TYPE_REDIST 3
+#endif
+
 static int gic_fd = -1;
+static u64 gic_redists_base;
+static u64 gic_redists_size;
 
 static int gic__create_device(struct kvm *kvm, enum irqchip_type type)
 {
@@ -28,12 +39,21 @@ static int gic__create_device(struct kvm *kvm, enum 
irqchip_type type)
.group  = KVM_DEV_ARM_VGIC_GRP_ADDR,
.addr   = (u64)(unsigned long)dist_addr,
};
+   struct kvm_device_attr redist_attr = {
+   .group  = KVM_DEV_ARM_VGIC_GRP_ADDR,
+   .attr   = KVM_VGIC_V3_ADDR_TYPE_REDIST,
+   .addr   = (u64)(unsigned long)gic_redists_base,
+   };
 
switch (type) {
case IRQCHIP_GICV2:
gic_device.type = KVM_DEV_TYPE_ARM_VGIC_V2;
dist_attr.attr  = KVM_VGIC_V2_ADDR_TYPE_DIST;
break;
+   case IRQCHIP_GICV3:
+   gic_device.type = KVM_DEV_TYPE_ARM_VGIC_V3;
+   dist_attr.attr  = KVM_VGIC_V3_ADDR_TYPE_DIST;
+   break;
}
 
err = ioctl(kvm-vm_fd, KVM_CREATE_DEVICE, gic_device);
@@ -46,6 +66,9 @@ static int gic__create_device(struct kvm *kvm, enum 
irqchip_type type)
case IRQCHIP_GICV2:
err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, cpu_if_attr);
break;
+   case IRQCHIP_GICV3:
+   err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, redist_attr);
+   break;
}
if (err)
goto out_err;
@@ -97,6 +120,10 @@ int gic__create(struct kvm *kvm, enum irqchip_type type)
switch (type) {
case IRQCHIP_GICV2:
break;
+   case IRQCHIP_GICV3:
+   gic_redists_size = kvm-cfg.nrcpus * ARM_GIC_REDIST_SIZE;
+   gic_redists_base = ARM_GIC_DIST_BASE - gic_redists_size;
+   break;
default:
return -ENODEV;
}
@@ -156,12 +183,19 @@ void gic__generate_fdt_nodes(void *fdt, u32 phandle, enum 
irqchip_type type)
const char *compatible;
u64 reg_prop[] = {
cpu_to_fdt64(ARM_GIC_DIST_BASE), 
cpu_to_fdt64(ARM_GIC_DIST_SIZE),
-   cpu_to_fdt64(ARM_GIC_CPUI_BASE), 
cpu_to_fdt64(ARM_GIC_CPUI_SIZE),
+   0, 0,   /* to be filled */
};
 
switch (type) {
case IRQCHIP_GICV2:
compatible = arm,cortex-a15-gic;
+   reg_prop[2] = cpu_to_fdt64(ARM_GIC_CPUI_BASE);
+   reg_prop[3] = cpu_to_fdt64(ARM_GIC_CPUI_SIZE);
+   break;
+   case IRQCHIP_GICV3:
+   compatible = arm,gic-v3;
+   reg_prop[2] = cpu_to_fdt64(gic_redists_base);
+   reg_prop[3] = cpu_to_fdt64(gic_redists_size);
break;
default:
return;
diff --git a/arm/include/arm-common/gic.h b/arm/include/arm-common/gic.h
index d524f55..4fde5ac 100644
--- a/arm/include/arm-common/gic.h
+++ b/arm/include/arm-common/gic.h
@@ -23,6 +23,7 @@
 
 enum irqchip_type {
IRQCHIP_GICV2,
+   IRQCHIP_GICV3,
 };
 
 struct kvm;
diff --git a/arm/include/arm-common/kvm-arch.h 
b/arm/include/arm-common/kvm-arch.h
index 90d6733..0f5fb7f 100644
--- a/arm/include/arm-common/kvm-arch.h
+++ b/arm/include/arm-common/kvm-arch.h
@@ -30,6 +30,13 @@
 #define KVM_PCI_MMIO_AREA  (KVM_PCI_CFG_AREA + ARM_PCI_CFG_SIZE)
 #define KVM_VIRTIO_MMIO_AREA   ARM_MMIO_AREA
 
+/*
+ * On a GICv3 there must be one redistributor per vCPU.
+ * The value here is the size for one, we multiply this at runtime with
+ * the number of requested vCPUs to get the actual size.
+ */
+#define ARM_GIC_REDIST_SIZE0x2
+
 #define KVM_IRQ_OFFSET GIC_SPI_IRQ_BASE
 
 #define KVM_VM_TYPE0
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 06/10] arm: simplify MMIO dispatching

2015-06-26 Thread Andre Przywara
Currently we separate any incoming MMIO request into one of the ARM
memory map regions and take care to spare the GIC.
It turns out that this is unnecessary, as we only have one special
region (the IO port area in the first 64 KByte). The MMIO rbtree
takes care about unhandled MMIO ranges, so we can simply drop all the
special range checking (except that for the IO range) in
kvm_cpu__emulate_mmio().
As the GIC is handled in the kernel, a GIC MMIO access should never
reach userland (and we don't know what to do with it anyway).
This lets us delete some more code and simplifies future extensions
(like expanding the GIC regions).
To be in line with the other architectures, move the now simpler
code into a header file.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
Reviewed-by: Marc Zyngier marc.zyng...@arm.com
---
 arm/include/arm-common/kvm-arch.h | 12 
 arm/include/arm-common/kvm-cpu-arch.h | 14 --
 arm/kvm-cpu.c | 16 
 3 files changed, 12 insertions(+), 30 deletions(-)

diff --git a/arm/include/arm-common/kvm-arch.h 
b/arm/include/arm-common/kvm-arch.h
index 082131d..90d6733 100644
--- a/arm/include/arm-common/kvm-arch.h
+++ b/arm/include/arm-common/kvm-arch.h
@@ -45,18 +45,6 @@ static inline bool arm_addr_in_ioport_region(u64 phys_addr)
return phys_addr = KVM_IOPORT_AREA  phys_addr  limit;
 }
 
-static inline bool arm_addr_in_virtio_mmio_region(u64 phys_addr)
-{
-   u64 limit = KVM_VIRTIO_MMIO_AREA + ARM_VIRTIO_MMIO_SIZE;
-   return phys_addr = KVM_VIRTIO_MMIO_AREA  phys_addr  limit;
-}
-
-static inline bool arm_addr_in_pci_region(u64 phys_addr)
-{
-   u64 limit = KVM_PCI_CFG_AREA + ARM_PCI_CFG_SIZE + ARM_PCI_MMIO_SIZE;
-   return phys_addr = KVM_PCI_CFG_AREA  phys_addr  limit;
-}
-
 struct kvm_arch {
/*
 * We may have to align the guest memory for virtio, so keep the
diff --git a/arm/include/arm-common/kvm-cpu-arch.h 
b/arm/include/arm-common/kvm-cpu-arch.h
index 36c7872..329979a 100644
--- a/arm/include/arm-common/kvm-cpu-arch.h
+++ b/arm/include/arm-common/kvm-cpu-arch.h
@@ -44,8 +44,18 @@ static inline bool kvm_cpu__emulate_io(struct kvm_cpu *vcpu, 
u16 port, void *dat
return false;
 }
 
-bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data,
-  u32 len, u8 is_write);
+static inline bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr,
+u8 *data, u32 len, u8 is_write)
+{
+   if (arm_addr_in_ioport_region(phys_addr)) {
+   int direction = is_write ? KVM_EXIT_IO_OUT : KVM_EXIT_IO_IN;
+   u16 port = (phys_addr - KVM_IOPORT_AREA)  USHRT_MAX;
+
+   return kvm__emulate_io(vcpu, port, data, direction, len, 1);
+   }
+
+   return kvm__emulate_mmio(vcpu, phys_addr, data, len, is_write);
+}
 
 unsigned long kvm_cpu__get_vcpu_mpidr(struct kvm_cpu *vcpu);
 
diff --git a/arm/kvm-cpu.c b/arm/kvm-cpu.c
index ab08815..7780251 100644
--- a/arm/kvm-cpu.c
+++ b/arm/kvm-cpu.c
@@ -139,22 +139,6 @@ bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu)
return false;
 }
 
-bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data,
-  u32 len, u8 is_write)
-{
-   if (arm_addr_in_virtio_mmio_region(phys_addr)) {
-   return kvm__emulate_mmio(vcpu, phys_addr, data, len, is_write);
-   } else if (arm_addr_in_ioport_region(phys_addr)) {
-   int direction = is_write ? KVM_EXIT_IO_OUT : KVM_EXIT_IO_IN;
-   u16 port = (phys_addr - KVM_IOPORT_AREA)  USHRT_MAX;
-   return kvm__emulate_io(vcpu, port, data, direction, len, 1);
-   } else if (arm_addr_in_pci_region(phys_addr)) {
-   return kvm__emulate_mmio(vcpu, phys_addr, data, len, is_write);
-   }
-
-   return false;
-}
-
 void kvm_cpu__show_page_tables(struct kvm_cpu *vcpu)
 {
 }
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 02/10] AArch{32,64}: use KVM_CREATE_DEVICE co to instanciate the GIC

2015-06-26 Thread Andre Przywara
From: Marc Zyngier marc.zyng...@arm.com

As of 3.14, KVM/arm supports the creation/configuration of the GIC through
a more generic device API, which is now the preferred way to do so.

Plumb the new API in, and allow the old code to be used as a fallback.

[Andre: Rename some functions on the way to differentiate between
creation and initialisation more clearly and fix error path.]

Signed-off-by: Marc Zyngier marc.zyng...@arm.com
Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 arm/gic.c| 69 +++-
 arm/include/arm-common/gic.h |  2 +-
 arm/kvm.c|  6 ++--
 3 files changed, 66 insertions(+), 11 deletions(-)

diff --git a/arm/gic.c b/arm/gic.c
index 5d8cbe6..1ff3663 100644
--- a/arm/gic.c
+++ b/arm/gic.c
@@ -7,7 +7,50 @@
 #include linux/byteorder.h
 #include linux/kvm.h
 
-int gic__init_irqchip(struct kvm *kvm)
+static int gic_fd = -1;
+
+static int gic__create_device(struct kvm *kvm)
+{
+   int err;
+   u64 cpu_if_addr = ARM_GIC_CPUI_BASE;
+   u64 dist_addr = ARM_GIC_DIST_BASE;
+   struct kvm_create_device gic_device = {
+   .type   = KVM_DEV_TYPE_ARM_VGIC_V2,
+   };
+   struct kvm_device_attr cpu_if_attr = {
+   .group  = KVM_DEV_ARM_VGIC_GRP_ADDR,
+   .attr   = KVM_VGIC_V2_ADDR_TYPE_CPU,
+   .addr   = (u64)(unsigned long)cpu_if_addr,
+   };
+   struct kvm_device_attr dist_attr = {
+   .group  = KVM_DEV_ARM_VGIC_GRP_ADDR,
+   .attr   = KVM_VGIC_V2_ADDR_TYPE_DIST,
+   .addr   = (u64)(unsigned long)dist_addr,
+   };
+
+   err = ioctl(kvm-vm_fd, KVM_CREATE_DEVICE, gic_device);
+   if (err)
+   return err;
+
+   gic_fd = gic_device.fd;
+
+   err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, cpu_if_attr);
+   if (err)
+   goto out_err;
+
+   err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, dist_attr);
+   if (err)
+   goto out_err;
+
+   return 0;
+
+out_err:
+   close(gic_fd);
+   gic_fd = -1;
+   return err;
+}
+
+static int gic__create_irqchip(struct kvm *kvm)
 {
int err;
struct kvm_arm_device_addr gic_addr[] = {
@@ -23,12 +66,6 @@ int gic__init_irqchip(struct kvm *kvm)
}
};
 
-   if (kvm-nrcpus  GIC_MAX_CPUS) {
-   pr_warning(%d CPUS greater than maximum of %d -- truncating\n,
-   kvm-nrcpus, GIC_MAX_CPUS);
-   kvm-nrcpus = GIC_MAX_CPUS;
-   }
-
err = ioctl(kvm-vm_fd, KVM_CREATE_IRQCHIP);
if (err)
return err;
@@ -41,6 +78,24 @@ int gic__init_irqchip(struct kvm *kvm)
return err;
 }
 
+int gic__create(struct kvm *kvm)
+{
+   int err;
+
+   if (kvm-nrcpus  GIC_MAX_CPUS) {
+   pr_warning(%d CPUS greater than maximum of %d -- truncating\n,
+   kvm-nrcpus, GIC_MAX_CPUS);
+   kvm-nrcpus = GIC_MAX_CPUS;
+   }
+
+   /* Try the new way first, and fallback on legacy method otherwise */
+   err = gic__create_device(kvm);
+   if (err)
+   err = gic__create_irqchip(kvm);
+
+   return err;
+}
+
 void gic__generate_fdt_nodes(void *fdt, u32 phandle)
 {
u64 reg_prop[] = {
diff --git a/arm/include/arm-common/gic.h b/arm/include/arm-common/gic.h
index 5a36f2c..44859f7 100644
--- a/arm/include/arm-common/gic.h
+++ b/arm/include/arm-common/gic.h
@@ -24,7 +24,7 @@
 struct kvm;
 
 int gic__alloc_irqnum(void);
-int gic__init_irqchip(struct kvm *kvm);
+int gic__create(struct kvm *kvm);
 void gic__generate_fdt_nodes(void *fdt, u32 phandle);
 
 #endif /* ARM_COMMON__GIC_H */
diff --git a/arm/kvm.c b/arm/kvm.c
index 58ad9fa..bcd2533 100644
--- a/arm/kvm.c
+++ b/arm/kvm.c
@@ -81,7 +81,7 @@ void kvm__arch_init(struct kvm *kvm, const char 
*hugetlbfs_path, u64 ram_size)
madvise(kvm-arch.ram_alloc_start, kvm-arch.ram_alloc_size,
MADV_MERGEABLE | MADV_HUGEPAGE);
 
-   /* Initialise the virtual GIC. */
-   if (gic__init_irqchip(kvm))
-   die(Failed to initialise virtual GIC);
+   /* Create the virtual GIC. */
+   if (gic__create(kvm))
+   die(Failed to create virtual GIC);
 }
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 03/10] irq: add irq__get_nr_allocated_lines

2015-06-26 Thread Andre Przywara
From: Marc Zyngier marc.zyng...@arm.com

The ARM GIC emulation needs to be told the number of interrupts
it has to support. As commit 1c262fa1dc7bc (kvm tools: irq: make
irq__alloc_line generic) made the interrupt counter private,
add a new accessor returning the number of interrupt lines we've
allocated so far.

Signed-off-by: Marc Zyngier marc.zyng...@arm.com
Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 include/kvm/irq.h | 1 +
 irq.c | 5 +
 2 files changed, 6 insertions(+)

diff --git a/include/kvm/irq.h b/include/kvm/irq.h
index 4cec6f0..8a78e43 100644
--- a/include/kvm/irq.h
+++ b/include/kvm/irq.h
@@ -11,6 +11,7 @@
 struct kvm;
 
 int irq__alloc_line(void);
+int irq__get_nr_allocated_lines(void);
 
 int irq__init(struct kvm *kvm);
 int irq__exit(struct kvm *kvm);
diff --git a/irq.c b/irq.c
index 33ea8d2..71eaa05 100644
--- a/irq.c
+++ b/irq.c
@@ -7,3 +7,8 @@ int irq__alloc_line(void)
 {
return next_line++;
 }
+
+int irq__get_nr_allocated_lines(void)
+{
+   return next_line - KVM_IRQ_OFFSET;
+}
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 07/10] limit number of VCPUs on demand

2015-06-26 Thread Andre Przywara
Currently the ARM GIC checks the number of VCPUs against a fixed
limit, which is GICv2 specific. Don't pretend we know better than the
kernel and let's get rid of that explicit check.
Instead be more relaxed about KVM_CREATE_VCPU failing with EINVAL,
which is the way the kernel communicates having reached a VCPU limit.
If we see this and have at least brought up one VCPU already
successfully, then don't panic, but limit the number of VCPUs instead.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 arm/gic.c | 6 --
 arm/kvm-cpu.c | 7 ++-
 kvm-cpu.c | 7 +++
 3 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/arm/gic.c b/arm/gic.c
index 99f0d2b..05f85a2 100644
--- a/arm/gic.c
+++ b/arm/gic.c
@@ -84,12 +84,6 @@ int gic__create(struct kvm *kvm)
 {
int err;
 
-   if (kvm-nrcpus  GIC_MAX_CPUS) {
-   pr_warning(%d CPUS greater than maximum of %d -- truncating\n,
-   kvm-nrcpus, GIC_MAX_CPUS);
-   kvm-nrcpus = GIC_MAX_CPUS;
-   }
-
/* Try the new way first, and fallback on legacy method otherwise */
err = gic__create_device(kvm);
if (err)
diff --git a/arm/kvm-cpu.c b/arm/kvm-cpu.c
index 7780251..b2fd6ed 100644
--- a/arm/kvm-cpu.c
+++ b/arm/kvm-cpu.c
@@ -51,8 +51,13 @@ struct kvm_cpu *kvm_cpu__arch_init(struct kvm *kvm, unsigned 
long cpu_id)
return NULL;
 
vcpu-vcpu_fd = ioctl(kvm-vm_fd, KVM_CREATE_VCPU, cpu_id);
-   if (vcpu-vcpu_fd  0)
+   if (vcpu-vcpu_fd  0) {
+   if (errno == EINVAL) {
+   free(vcpu);
+   return NULL;
+   }
die_perror(KVM_CREATE_VCPU ioctl);
+   }
 
mmap_size = ioctl(kvm-sys_fd, KVM_GET_VCPU_MMAP_SIZE, 0);
if (mmap_size  0)
diff --git a/kvm-cpu.c b/kvm-cpu.c
index 5d90664..7a9d689 100644
--- a/kvm-cpu.c
+++ b/kvm-cpu.c
@@ -222,11 +222,18 @@ int kvm_cpu__init(struct kvm *kvm)
for (i = 0; i  kvm-nrcpus; i++) {
kvm-cpus[i] = kvm_cpu__arch_init(kvm, i);
if (!kvm-cpus[i]) {
+   if (i  0  errno == EINVAL)
+   break;
pr_warning(unable to initialize KVM VCPU);
goto fail_alloc;
}
}
 
+   if (i  kvm-nrcpus) {
+   kvm-nrcpus = i;
+   printf(  # The kernel limits the number of CPUs to %d\n, i);
+   }
+
return 0;
 
 fail_alloc:
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 05/10] arm: finish VGIC initialisation explicitly

2015-06-26 Thread Andre Przywara
Since Linux 3.19-rc1 there is a new API to explicitly initialise
the in-kernel GIC emulation by a userland KVM device call.
Use that to tell the kernel we are finished with the GIC
initialisation, since the automatic GIC init will only be provided
as a legacy functionality in the future.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
Reviewed-by: Marc Zyngier marc.zyng...@arm.com
---
 arm/gic.c | 25 ++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/arm/gic.c b/arm/gic.c
index 8560c9b..99f0d2b 100644
--- a/arm/gic.c
+++ b/arm/gic.c
@@ -98,24 +98,43 @@ int gic__create(struct kvm *kvm)
return err;
 }
 
+/*
+ * Sets the number of used interrupts and finalizes the GIC init explicitly.
+ */
 static int gic__init_gic(struct kvm *kvm)
 {
+   int ret;
+
int lines = irq__get_nr_allocated_lines();
u32 nr_irqs = ALIGN(lines, 32) + GIC_SPI_IRQ_BASE;
struct kvm_device_attr nr_irqs_attr = {
.group  = KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
.addr   = (u64)(unsigned long)nr_irqs,
};
+   struct kvm_device_attr vgic_init_attr = {
+   .group  = KVM_DEV_ARM_VGIC_GRP_CTRL,
+   .attr   = KVM_DEV_ARM_VGIC_CTRL_INIT,
+   };
 
/*
 * If we didn't use the KVM_CREATE_DEVICE method, KVM will
-* give us some default number of interrupts.
+* give us some default number of interrupts. The GIC initialization
+* will be done automatically in this case.
 */
if (gic_fd  0)
return 0;
 
-   if (!ioctl(gic_fd, KVM_HAS_DEVICE_ATTR, nr_irqs_attr))
-   return ioctl(gic_fd, KVM_SET_DEVICE_ATTR, nr_irqs_attr);
+   if (!ioctl(gic_fd, KVM_HAS_DEVICE_ATTR, nr_irqs_attr)) {
+   ret = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, nr_irqs_attr);
+   if (ret)
+   return ret;
+   }
+
+   if (!ioctl(gic_fd, KVM_HAS_DEVICE_ATTR, vgic_init_attr)) {
+   ret = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, vgic_init_attr);
+   if (ret)
+   return ret;
+   }
 
return 0;
 }
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 04/10] AArch{32,64}: dynamically configure the number of GIC interrupts

2015-06-26 Thread Andre Przywara
From: Marc Zyngier marc.zyng...@arm.com

In order to reduce the memory usage of large guests (as well
as improve performance), tell KVM about the number of interrupts
we require.

To avoid synchronization with the various device creation,
use a late_init callback to compute the GIC configuration.
[Andre: rename to gic__init_gic() to ease future expansion]

Signed-off-by: Marc Zyngier marc.zyng...@arm.com
Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 arm/gic.c | 25 +
 1 file changed, 25 insertions(+)

diff --git a/arm/gic.c b/arm/gic.c
index 1ff3663..8560c9b 100644
--- a/arm/gic.c
+++ b/arm/gic.c
@@ -1,10 +1,12 @@
 #include kvm/fdt.h
+#include kvm/irq.h
 #include kvm/kvm.h
 #include kvm/virtio.h
 
 #include arm-common/gic.h
 
 #include linux/byteorder.h
+#include linux/kernel.h
 #include linux/kvm.h
 
 static int gic_fd = -1;
@@ -96,6 +98,29 @@ int gic__create(struct kvm *kvm)
return err;
 }
 
+static int gic__init_gic(struct kvm *kvm)
+{
+   int lines = irq__get_nr_allocated_lines();
+   u32 nr_irqs = ALIGN(lines, 32) + GIC_SPI_IRQ_BASE;
+   struct kvm_device_attr nr_irqs_attr = {
+   .group  = KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
+   .addr   = (u64)(unsigned long)nr_irqs,
+   };
+
+   /*
+* If we didn't use the KVM_CREATE_DEVICE method, KVM will
+* give us some default number of interrupts.
+*/
+   if (gic_fd  0)
+   return 0;
+
+   if (!ioctl(gic_fd, KVM_HAS_DEVICE_ATTR, nr_irqs_attr))
+   return ioctl(gic_fd, KVM_SET_DEVICE_ATTR, nr_irqs_attr);
+
+   return 0;
+}
+late_init(gic__init_gic)
+
 void gic__generate_fdt_nodes(void *fdt, u32 phandle)
 {
u64 reg_prop[] = {
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 10/10] arm: use new irqchip parameter to create different vGIC types

2015-06-26 Thread Andre Przywara
Currently we unconditionally create a virtual GICv2 in the guest.
Add a --irqchip= parameter to let the user specify a different GIC
type for the guest, when omitting this parameter it still defaults to
--irqchip=gicv2.
For now the only other supported type is --irqchip=gicv3

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 arm/aarch64/arm-cpu.c|  2 +-
 arm/gic.c| 17 +
 arm/include/arm-common/kvm-config-arch.h |  9 -
 arm/kvm.c|  2 +-
 4 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/arm/aarch64/arm-cpu.c b/arm/aarch64/arm-cpu.c
index f702b9e..3dc8ea3 100644
--- a/arm/aarch64/arm-cpu.c
+++ b/arm/aarch64/arm-cpu.c
@@ -12,7 +12,7 @@
 static void generate_fdt_nodes(void *fdt, struct kvm *kvm, u32 gic_phandle)
 {
int timer_interrupts[4] = {13, 14, 11, 10};
-   gic__generate_fdt_nodes(fdt, gic_phandle, IRQCHIP_GICV2);
+   gic__generate_fdt_nodes(fdt, gic_phandle, kvm-cfg.arch.irqchip);
timer__generate_fdt_nodes(fdt, kvm, timer_interrupts);
 }
 
diff --git a/arm/gic.c b/arm/gic.c
index efe4b42..ff56de7 100644
--- a/arm/gic.c
+++ b/arm/gic.c
@@ -22,6 +22,23 @@ static int gic_fd = -1;
 static u64 gic_redists_base;
 static u64 gic_redists_size;
 
+int irqchip_parser(const struct option *opt, const char *arg, int unset)
+{
+   enum irqchip_type *type = opt-value;
+
+   *type = IRQCHIP_GICV2;
+   if (!strcmp(arg, gicv2)) {
+   *type = IRQCHIP_GICV2;
+   } else if (!strcmp(arg, gicv3)) {
+   *type = IRQCHIP_GICV3;
+   } else {
+   fprintf(stderr, irqchip: unknown type \%s\\n, arg);
+   return -1;
+   }
+
+   return 0;
+}
+
 static int gic__create_device(struct kvm *kvm, enum irqchip_type type)
 {
int err;
diff --git a/arm/include/arm-common/kvm-config-arch.h 
b/arm/include/arm-common/kvm-config-arch.h
index a8ebd94..9529881 100644
--- a/arm/include/arm-common/kvm-config-arch.h
+++ b/arm/include/arm-common/kvm-config-arch.h
@@ -8,8 +8,11 @@ struct kvm_config_arch {
unsigned intforce_cntfrq;
boolvirtio_trans_pci;
boolaarch32_guest;
+   enum irqchip_type irqchip;
 };
 
+int irqchip_parser(const struct option *opt, const char *arg, int unset);
+
 #define OPT_ARCH_RUN(pfx, cfg) 
\
pfx,
\
ARM_OPT_ARCH_RUN(cfg)   
\
@@ -21,6 +24,10 @@ struct kvm_config_arch {
 updated to program CNTFRQ correctly*),   
\
OPT_BOOLEAN('\0', force-pci, (cfg)-virtio_trans_pci,
\
Force virtio devices to use PCI as their default  
\
-   transport),
+   transport),   
\
+OPT_CALLBACK('\0', irqchip, (cfg)-irqchip, 
\
+[gicv2|gicv3],   \
+type of interrupt controller to emulate in the guest,
\
+irqchip_parser, NULL),
 
 #endif /* ARM_COMMON__KVM_CONFIG_ARCH_H */
diff --git a/arm/kvm.c b/arm/kvm.c
index f9685c2..d0e4a20 100644
--- a/arm/kvm.c
+++ b/arm/kvm.c
@@ -82,6 +82,6 @@ void kvm__arch_init(struct kvm *kvm, const char 
*hugetlbfs_path, u64 ram_size)
MADV_MERGEABLE | MADV_HUGEPAGE);
 
/* Create the virtual GIC. */
-   if (gic__create(kvm, IRQCHIP_GICV2))
+   if (gic__create(kvm, kvm-cfg.arch.irqchip))
die(Failed to create virtual GIC);
 }
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 06/10] arm: simplify MMIO dispatching

2015-06-24 Thread Andre Przywara
Hi Will,

do you want me to respin the whole series to address the remaining minor
comments in the last four patches or do you want to take patch 01-06
already (which I think Marc has already agreed upon)?
Then I would just send an updated version of the remaining patches.

Cheers,
Andre.




 No, that's fine.
 
 I just wondered what was the rational behind having the
 arm_addr_in_pci_region() call there. It might have guarded something,
 but if you're absolutely positive that this doesn't cause a regression,
 that's OK with me.
 
 Reviewed-by: Marc Zyngier marc.zyng...@arm.com
 
   M.
 
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH 1/2] Makefile: cleanup guest/init generation

2015-06-23 Thread Andre Przywara
The dependencies and targets for the guest userland binary are
currently not correct, some are redundant.
Fix them by splitting up guest/guest_init.o creation into its two
steps and describe the dependencies properly.
On the way use automatic variables in some rules.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 Makefile | 21 -
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/Makefile b/Makefile
index 151fa9d..b9480ff 100644
--- a/Makefile
+++ b/Makefile
@@ -337,7 +337,7 @@ ifneq ($(WERROR),0)
CFLAGS += -Werror
 endif
 
-all: $(PROGRAM) $(PROGRAM_ALIAS) $(GUEST_INIT)
+all: $(PROGRAM) $(PROGRAM_ALIAS)
 
 # CFLAGS used when building objects
 # This is intentionally not assigned using :=
@@ -352,22 +352,25 @@ c_flags   = -Wp,-MD,$(depfile) $(CFLAGS)
 STATIC_OBJS = $(patsubst %.o,%.static.o,$(OBJS) $(OBJS_STATOPT))
 GUEST_OBJS = guest/guest_init.o
 
-$(PROGRAM)-static:  $(STATIC_OBJS) $(OTHEROBJS) $(GUEST_INIT)
+$(PROGRAM)-static:  $(STATIC_OBJS) $(OTHEROBJS) $(GUEST_OBJS)
$(E)   LINK $@
-   $(Q) $(CC) -static $(CFLAGS) $(STATIC_OBJS) $(OTHEROBJS) $(GUEST_OBJS) 
$(LIBS) $(LIBS_STATOPT) -o $@
+   $(Q) $(CC) -static $(CFLAGS) $^ $(LIBS) $(LIBS_STATOPT) -o $@
 
-$(PROGRAM): $(OBJS) $(OBJS_DYNOPT) $(OTHEROBJS) $(GUEST_INIT)
+$(PROGRAM): $(OBJS) $(OBJS_DYNOPT) $(OTHEROBJS) $(GUEST_OBJS)
$(E)   LINK $@
-   $(Q) $(CC) $(CFLAGS) $(OBJS) $(OBJS_DYNOPT) $(OTHEROBJS) $(GUEST_OBJS) 
$(LIBS) $(LIBS_DYNOPT) -o $@
+   $(Q) $(CC) $(CFLAGS) $^ $(LIBS) $(LIBS_DYNOPT) -o $@
 
 $(PROGRAM_ALIAS): $(PROGRAM)
$(E)   LN   $@
-   $(Q) ln -f $(PROGRAM) $@
+   $(Q) ln -f $ $@
 
-$(GUEST_INIT): guest/init.c
+$(GUEST_OBJS): $(GUEST_INIT)
$(E)   LINK $@
-   $(Q) $(CC) -static guest/init.c -o $@
-   $(Q) $(LD) $(LDFLAGS) -r -b binary -o guest/guest_init.o $(GUEST_INIT)
+   $(Q) $(LD) $(LDFLAGS) -r -b binary -o $@ $
+
+$(GUEST_INIT): guest/init.c
+   $(E)   CC   $@
+   $(Q) $(CC) -static $^ -o $@
 
 %.s: %.c
$(Q) $(CC) -o $@ -S $(CFLAGS) -fverbose-asm $
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH 2/2] Makefile: use xxd for converting guest/init

2015-06-23 Thread Andre Przywara
Currently we use ld to convert the static guest/init binary back
into an object file, which we can embed as a binary blob into our
lkvm binary. This works fine as long as compiler and linker use the
same ELF target format, which seems to be not true for most of the
MIPS toolchains.
Use a different approach instead, which converts the guest/init
binary into a C array, from which the compiler generates an .o
representation. As the compiler is now the same, this naturally links
together fine on all architectures.
We use the xxd tool for generating a C array representation out of
the binary file. If this turns out to be not widely installed (it
seems to be part of the vim package in most distributions), we could
think about switching to a scripted implementation using od or some
printf trickery.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 Makefile| 4 ++--
 builtin-run.c   | 8 
 builtin-setup.c | 8 
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/Makefile b/Makefile
index b9480ff..7f2a0ea 100644
--- a/Makefile
+++ b/Makefile
@@ -365,8 +365,8 @@ $(PROGRAM_ALIAS): $(PROGRAM)
$(Q) ln -f $ $@
 
 $(GUEST_OBJS): $(GUEST_INIT)
-   $(E)   LINK $@
-   $(Q) $(LD) $(LDFLAGS) -r -b binary -o $@ $
+   $(E)   CONVERT  $@
+   $(Q) xxd -i $ | $(CC) -c -x c - -o $@
 
 $(GUEST_INIT): guest/init.c
$(E)   CC   $@
diff --git a/builtin-run.c b/builtin-run.c
index 1ee75ad..0a48663 100644
--- a/builtin-run.c
+++ b/builtin-run.c
@@ -59,8 +59,8 @@ static int  kvm_run_wrapper;
 
 bool do_debug_print = false;
 
-extern char _binary_guest_init_start;
-extern char _binary_guest_init_size;
+extern char guest_init;
+extern char guest_init_len;
 
 static const char * const run_usage[] = {
lkvm run [options] [kernel image],
@@ -354,8 +354,8 @@ static int kvm_setup_guest_init(struct kvm *kvm)
char *data;
 
/* Setup /virt/init */
-   size = (size_t)_binary_guest_init_size;
-   data = (char *)_binary_guest_init_start;
+   size = (size_t)guest_init_len;
+   data = (char *)guest_init;
snprintf(tmp, PATH_MAX, %s%s/virt/init, kvm__get_dir(), rootfs);
remove(tmp);
fd = open(tmp, O_CREAT | O_WRONLY, 0755);
diff --git a/builtin-setup.c b/builtin-setup.c
index 8b45c56..fd7ca54 100644
--- a/builtin-setup.c
+++ b/builtin-setup.c
@@ -16,8 +16,8 @@
 #include sys/mman.h
 #include fcntl.h
 
-extern char _binary_guest_init_start;
-extern char _binary_guest_init_size;
+extern char guest_init;
+extern char guest_init_len;
 
 static const char *instance_name;
 
@@ -131,8 +131,8 @@ static int copy_init(const char *guestfs_name)
int fd, ret;
char *data;
 
-   size = (size_t)_binary_guest_init_size;
-   data = (char *)_binary_guest_init_start;
+   size = (size_t)guest_init;
+   data = (char *)guest_init_len;
snprintf(path, PATH_MAX, %s%s/virt/init, kvm__get_dir(), 
guestfs_name);
remove(path);
fd = open(path, O_CREAT | O_WRONLY, 0755);
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH 0/2] kvmtool: Rework guest/init integration

2015-06-23 Thread Andre Przywara
Hi,

this mini series aims at solving long standing issues with compiling
and linking the guest/init binary for MIPS.
It seems that many MIPS toolchains use different default ELF targets
for the compiler and the linker, rendering the approach of linking
the guest/init executable into the lkvm binary moot.
One could work around this by specifying some magic ELF target
options to the linker so it matches the compiler ones, but I couldn't
find a way of automatically determining those, so this approach is
only valid on a particular toolchain.
Another approach would be to fixup the ELF header, but that sounds
dodgy and fragile to me.

Instead of using ld this series transforms the generated guest
binary into a C file, which gets compiled (with CC) and thus
automatically links fine with the other object files.
Patch 2/2 implements this, patch 1/2 cleans up the rules for the
guest binary generation in the Makefile.

This uses the xxd tool, which has a special command line option
to generate a C array out of a binary blob. On the distributions
I checked, this comes with the vim package, not sure if that is a
restriction.

I compile tested this on on PowerPC64, MIPS64, ARM, ARM64, i386 and
x86_64.

Please test whether this works with your toolchain / system!

Cheers,
Andre.

Andre Przywara (2):
  Makefile: cleanup guest/init generation
  Makefile: use xxd for converting guest/init

 Makefile| 21 -
 builtin-run.c   |  8 
 builtin-setup.c |  8 
 3 files changed, 20 insertions(+), 17 deletions(-)

-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC 0/6] KVM: arm/arm64: gsi routing support

2015-06-23 Thread Andre Przywara
Hi Eric,

I went back reading the code and looked at how the x86 APIC works more
closely to understand the GSI routing better.
See below for more ...

On 22/06/15 10:21, Eric Auger wrote:
 On 06/22/2015 10:40 AM, Andre Przywara wrote:
 Hi Eric,

 I briefly looked over the series, the patches itself look good overall.
 I have one or two comments on the actual code, but want to discuss the
 general approach first (more a dump of some first thoughts):

 On 18/06/15 18:40, Eric Auger wrote:
 With the advent of GICv3 ITS in-kernel emulation, KVM GSI routing
 appears to be requested. More specifically MSI routing is needed.
 irqchip routing does not sound to be really useful on arm but usage of
 MSI routing also mandates to integrate irqchip routing. The initial
 implementation of irqfd on arm must be upgraded with the integration
 of kvm irqchip.c code and the implementation of its standard hooks
 in the architecture specific part.

 The series therefore allows and mandates the usage of KVM_SET_GSI_ROUTING
 ioctl along with KVM_IRQFD. If the userspace does not define any routing
 table, no irqfd injection can happen. The user-space can use
 KVM_CAP_IRQ_ROUTING to detect whether a routing table is needed.

 for irqchip routing, the convention is, only SPI can be injected and the
 SPI ID corresponds to irqchip.pin + 32. For MSI routing the interrupt ID
 matches the MSI msg data. API evolve to support associating a device ID
 to a routine entry.

 So if I get this right, in a guest ITS case we have now three different
 IRQ name spaces:
 a) the LPI number, which is guest internal. The ITS driver in the guest
 maintains it. We can track assignments and changes when handling the
 MAPVI command in the host kernel, but this would stay in the kernel, as
 I don't see an efficient way of propagating this to userland.
 b) the GSI number, which is used in communication between userland and
 the host kernel. The guest kernel does not know about this at all. Also
 the ioctl requires us to set the routing for _all_ GSIs, and I read it
 that it assumes starting at GSI 0.
 all injected GSI must effectively have a routing entry in KVM. Starting
 at 0 that's not requested. At qemu level there's just the constaint gsi
 fits between [0, max route number].

Yeah, you are right, I somehow missed that each routing entry has a gsi
field in it. So we have to allocate all of them at once with one ioctl,
but they can be sparse.

  So we cannot even pretend to have
 LPIs here, because we would need at least 8192 empty entries then, not
 to speak of the possibly sparse allocation above. So we have a
 completely distinct name space here.
 What is done currently at qemu level for other archs -  if I understand
 it correctly -  is there is static GSI routing for standard IRQ. For MSI
 irqfd setup they use spare gsi number not yet used for GSI routing  max
 route number. So this is sparse for MSI but not for standard IRQs.
 Effectively we do not plan to have GSI routing for LPIs but only MSI
 routing.

That seems to make sense to me. Since we already limit the number of
SPIs to something sensible with our KVM_DEV_ARM_VGIC_GRP_NR_IRQS, we
could infer an implicit direct routing for those SPIs. KVM could check
the IRQ number against vgic.nr_irqs to see whether an IRQ is routed or not.
Any GSI beyond that number would be an MSI with your enhanced DevID:EvID
pair in it, which gets injected via the ITS emulation code (or the
respective GICv2m code).

That would be the idea, but if it turns out that not routing SPIs but
only MSIs requires too many changes to the (core) KVM code (haven't
looked yet), we could require routing entries for SPIs as well.
After all that's what for instance kvmtool sets up for x86, creating
default 1:1 mappings for ISA and low APIC IRQs and allocating MSIs on
demand after that.

 c) The DevID:EvID pair, which actually identifies an IRQ in all the
 three regimes and is the only authoritative ID.

 So that means we need to maintain the connection between all the three,
 somehow duplicating the whole ITS mapping again to map GSIs to DevID:EvID.
 Currently the KVM routing table indeed stores GSI/DevID:EvID mapping.

 So I wonder if we could use DevID:EvID directly.
 The KVM_IRQFD ioctl struct has some space, so we could put the DevID
 into the pad area.
 Also (more forward-looking) KVM_CAP_ASSIGN_DEV_IRQ identifies guest IRQs
 by an u32, but again there is quite some padding area available.

 ASSIGN_DEV_IRQ is a deprecated feature. We should not use that API I think.

OK, so do we have other users of the GSI routing beside IRQFD then?

I will go ahead and try to implement some code matching Eric's patches
in kvmtool to test the GSI routing.

Eric, how did you test the irqchip routing on the Midway?

Cheers,
Andre.

 Eric

 In general I am a bit reluctant to introduce just another level of
 complexity to the already quite convoluted way of doing IRQs and MSIs on
 ARM(64), that's why I will investigate if we can use DevID:EvID

Re: [PATCH 1/2] powerpc: Define the hcall opcodes return values we need

2015-06-23 Thread Andre Przywara
Hi,

On 23/06/15 11:05, Michael Ellerman wrote:
 On Tue, 2015-06-23 at 11:33 +0200, Paolo Bonzini wrote:
 On 19/06/2015 09:21, Michael Ellerman wrote:
 diff --git a/powerpc/spapr.h b/powerpc/spapr.h
 index 0537f881c0e4..7a377d093ef4 100644
 --- a/powerpc/spapr.h
 +++ b/powerpc/spapr.h
 @@ -16,17 +16,32 @@
  
  #include inttypes.h
  
 -/* We need some of the H_ hcall defs, but they're __KERNEL__ only. */
 -#define __KERNEL__
 -#include asm/hvcall.h
 -#undef __KERNEL__
 -

 This thing is exactly why I think kvmtool's life in the kernel tree was
 harmful.
 
 Harmful is a bit of an overstatement. Though I agree that was a bit of a hack.
 
 Why wasn't instead H_* just moved to a uapi/ header?!?!?  Can you do
 that now?
 
 Because it's not part of the kernel API, never was, still isn't.

Technically it may not - if I get this correctly it is more a platform
API defined by the architecture, like ACPI or PSCI on ARM.
But if I get this correctly Linux re-uses those definitions in the KVM
API, by piggy-backing on the existing hypercalls. Please correct me if I
am wrong here, I am looking at arch/powerpc/kvm/book3s_hv.c, where it
seems to trap those hypercalls.

So I think that - though not originally invented or defined by Linux -
it should export those definitions that KVM (re-)uses.
QEMU also has a header file duplicating those definitions, so I support
the idea of an uapi header.

 It *is* part of the hypervisor API, but it's not Linux's job to export that 
 and
 deal with the fallout if it was ever changed.

Regardless of what happens if that phyp API changes, KVM would still
need to support those hypercalls, so I think it should export them as well.

Cheers,
Andre.
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC 1/6] KVM: api: add kvm_irq_routing_extended_msi

2015-06-22 Thread Andre Przywara
Hi Eric,

On 18/06/15 18:40, Eric Auger wrote:
 On ARM, the MSI msg (address and data) comes along with
 out-of-band device ID information. The device ID encodes the device
 that composes the MSI msg. Let's create a new routing entry structure
 that enables to encode that information on top of standard MSI
 message
 
 Signed-off-by: Eric Auger eric.au...@linaro.org
 ---
  Documentation/virtual/kvm/api.txt | 9 +
  include/uapi/linux/kvm.h  | 9 +
  2 files changed, 18 insertions(+)
 
 diff --git a/Documentation/virtual/kvm/api.txt 
 b/Documentation/virtual/kvm/api.txt
 index d20fd94..bcec91e 100644
 --- a/Documentation/virtual/kvm/api.txt
 +++ b/Documentation/virtual/kvm/api.txt
 @@ -1419,6 +1419,7 @@ struct kvm_irq_routing_entry {
   struct kvm_irq_routing_irqchip irqchip;
   struct kvm_irq_routing_msi msi;
   struct kvm_irq_routing_s390_adapter adapter;
 + struct kvm_irq_routing_extended_msi ext_msi;
   __u32 pad[8];
   } u;
  };
 @@ -1427,6 +1428,7 @@ struct kvm_irq_routing_entry {
  #define KVM_IRQ_ROUTING_IRQCHIP 1
  #define KVM_IRQ_ROUTING_MSI 2
  #define KVM_IRQ_ROUTING_S390_ADAPTER 3
 +#define KVM_IRQ_ROUTING_EXTENDED_MSI 4
  
  No flags are specified so far, the corresponding field must be set to zero.
  
 @@ -1442,6 +1444,13 @@ struct kvm_irq_routing_msi {
   __u32 pad;
  };
  
 +struct kvm_irq_routing_extended_msi {
 + __u32 address_lo;
 + __u32 address_hi;
 + __u32 data;
 + __u32 devid;
 +};
 +

I wonder if we could re-use the existing struct kvm_irq_routing_msi,
which has an u32 pad field already. Since we use a different type
number, this should not break. Admittedly not the nicest thing, but
reduces interface bloat:

struct kvm_irq_routing_msi {
__u32 address_lo;
__u32 address_hi;
__u32 data;
union {
__u32 pad;
__u32 devid;
};
};

to maintain backward compatibility on the userland source level.

Cheers,
Andre.

  struct kvm_irq_routing_s390_adapter {
   __u64 ind_addr;
   __u64 summary_addr;
 diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
 index 2a23705..e3f65a0 100644
 --- a/include/uapi/linux/kvm.h
 +++ b/include/uapi/linux/kvm.h
 @@ -829,6 +829,13 @@ struct kvm_irq_routing_msi {
   __u32 pad;
  };
  
 +struct kvm_irq_routing_extended_msi {
 + __u32 address_lo;
 + __u32 address_hi;
 + __u32 data;
 + __u32 devid;
 +};
 +
  struct kvm_irq_routing_s390_adapter {
   __u64 ind_addr;
   __u64 summary_addr;
 @@ -841,6 +848,7 @@ struct kvm_irq_routing_s390_adapter {
  #define KVM_IRQ_ROUTING_IRQCHIP 1
  #define KVM_IRQ_ROUTING_MSI 2
  #define KVM_IRQ_ROUTING_S390_ADAPTER 3
 +#define KVM_IRQ_ROUTING_EXTENDED_MSI 4
  
  struct kvm_irq_routing_entry {
   __u32 gsi;
 @@ -851,6 +859,7 @@ struct kvm_irq_routing_entry {
   struct kvm_irq_routing_irqchip irqchip;
   struct kvm_irq_routing_msi msi;
   struct kvm_irq_routing_s390_adapter adapter;
 + struct kvm_irq_routing_extended_msi ext_msi;
   __u32 pad[8];
   } u;
  };
 
--
To unsubscribe from this list: send the line unsubscribe kvm in


Re: [RFC 0/6] KVM: arm/arm64: gsi routing support

2015-06-22 Thread Andre Przywara
Hi Eric,

I briefly looked over the series, the patches itself look good overall.
I have one or two comments on the actual code, but want to discuss the
general approach first (more a dump of some first thoughts):

On 18/06/15 18:40, Eric Auger wrote:
 With the advent of GICv3 ITS in-kernel emulation, KVM GSI routing
 appears to be requested. More specifically MSI routing is needed.
 irqchip routing does not sound to be really useful on arm but usage of
 MSI routing also mandates to integrate irqchip routing. The initial
 implementation of irqfd on arm must be upgraded with the integration
 of kvm irqchip.c code and the implementation of its standard hooks
 in the architecture specific part.
 
 The series therefore allows and mandates the usage of KVM_SET_GSI_ROUTING
 ioctl along with KVM_IRQFD. If the userspace does not define any routing
 table, no irqfd injection can happen. The user-space can use
 KVM_CAP_IRQ_ROUTING to detect whether a routing table is needed.
 
 for irqchip routing, the convention is, only SPI can be injected and the
 SPI ID corresponds to irqchip.pin + 32. For MSI routing the interrupt ID
 matches the MSI msg data. API evolve to support associating a device ID
 to a routine entry.

So if I get this right, in a guest ITS case we have now three different
IRQ name spaces:
a) the LPI number, which is guest internal. The ITS driver in the guest
maintains it. We can track assignments and changes when handling the
MAPVI command in the host kernel, but this would stay in the kernel, as
I don't see an efficient way of propagating this to userland.
b) the GSI number, which is used in communication between userland and
the host kernel. The guest kernel does not know about this at all. Also
the ioctl requires us to set the routing for _all_ GSIs, and I read it
that it assumes starting at GSI 0. So we cannot even pretend to have
LPIs here, because we would need at least 8192 empty entries then, not
to speak of the possibly sparse allocation above. So we have a
completely distinct name space here.
c) The DevID:EvID pair, which actually identifies an IRQ in all the
three regimes and is the only authoritative ID.

So that means we need to maintain the connection between all the three,
somehow duplicating the whole ITS mapping again to map GSIs to DevID:EvID.

So I wonder if we could use DevID:EvID directly.
The KVM_IRQFD ioctl struct has some space, so we could put the DevID
into the pad area.
Also (more forward-looking) KVM_CAP_ASSIGN_DEV_IRQ identifies guest IRQs
by an u32, but again there is quite some padding area available.

In general I am a bit reluctant to introduce just another level of
complexity to the already quite convoluted way of doing IRQs and MSIs on
ARM(64), that's why I will investigate if we can use DevID:EvID to refer
to an interrupt.

So far,
Andre.

 
 Known Issues of this RFC:
 
 - One of the biggest is the API inconsistencies on ARM. Blame me.
   Routing should apply to KVM_IRQ_LINE ioctl which is not the case yet
   in this series. It only applies to irqfd.
   on x86 typically this KVM_IRQ_LINE is plugged onto irqchip.c kvm_set_irq
   whereas on ARM we inject directly through kvm_vgic_inject_irq
   x on arm/arm64 gsi has a specific structure:
 bits:  | 31 ... 24 | 23  ... 16 | 15...0 |
 field: | irq_type  | vcpu_index | irq_id |
 where irq_id matches the Interrupt ID
 - for KVM_IRQFD without routing (current implementation) the gsi field
   corresponds to an SPI index = irq_id (above) -32.
 - as far as understand qemu integration, gsi is supposed to be within
   [0, KVM_MAX_IRQ_ROUTES]. Difficult to use KVM_IRQ_LINE gsi.
 - to be defined what we choose as a convention with irqchip routing is
   applied: gsi - irqchip input pin.
 - Or shouldn't we simply rule out any userspace irqchip routing and stick
   to MSI routing? we could define a fixed identity in-kernel irqchip mapping
   and only offer MSI routing.
 - static allocation of chip[KVM_NR_IRQCHIPS][KVM_IRQCHIP_NUM_PINS];
   arbitrary put KVM_IRQCHIP_NUM_PINS = 1020 - 32 (SPI count). On s390
   this is even bigger.
 
 Currently tested on irqchip routing only (Calxeda midway only),
 ie NOT TESTED on MSI routing yet.
 
 This is a very preliminary RFC to ease the discussion.
 
 Code can be found at 
 https://git.linaro.org/people/eric.auger/linux.git/shortlog/refs/heads/v4.1-rc8-gsi-routing-rfc
 
 It applies on Andre's [PATCH 00/13] arm64: KVM: GICv3 ITS emulation
 (http://www.spinics.net/lists/kvm/msg117402.html)
 
 Eric Auger (6):
   KVM: api: add kvm_irq_routing_extended_msi
   KVM: kvm_host: add kvm_extended_msi
   KVM: irqchip: convey devid to kvm_set_msi
   KVM: arm/arm64: enable irqchip routing
   KVM: arm/arm64: enable MSI routing
   KVM: arm: implement kvm_set_msi by gsi direct mapping
 
  Documentation/virtual/kvm/api.txt | 20 ++--
  arch/arm/include/asm/kvm_host.h   |  2 +
  arch/arm/kvm/Kconfig  |  3 ++
  arch/arm/kvm/Makefile |  2 +-
  

[PATCH] kvmtool: avoid casts when initializing structures

2015-06-19 Thread Andre Przywara
Due to our kernel heritage we have code in kvmtool that relies on
the (still) implicit -std=gnu89 compiler switch.
It turns out that this just affects some structure initialization,
where we currently provide a cast to the type, which upsets GCC for
anything beyond -std=gnu89 (for instance gnu99 or gnu11).
We do need the casts when initializing structures that are not
assigned to the same type, so we put it there explicitly.

This allows us to compile with all the three standards GCC currently
supports: gnu89/90, gnu99 and gnu11.
GCC threatens people with moving to gnu11 as the new default standard,
so lets fix this better sooner than later.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
Hi,

TBH I don't know why we had those casts there in the first place,
but it works without them, even for -std=gnu89.
If people agree with this, we can think about dropping the forced
CFLAGS and LDFLAGS reset in the Makefile again, since this patch
should fix compilation on Dave Jones' machine as well ;-)

Cheers,
Andre.
 disk/qcow.c| 6 +++---
 include/kvm/mutex.h| 2 +-
 include/linux/rbtree.h | 2 +-
 virtio/9p.c| 2 +-
 virtio/balloon.c   | 2 +-
 virtio/blk.c   | 2 +-
 virtio/console.c   | 2 +-
 virtio/net.c   | 2 +-
 virtio/rng.c   | 2 +-
 virtio/scsi.c  | 2 +-
 10 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/disk/qcow.c b/disk/qcow.c
index 64a2550..e26c419 100644
--- a/disk/qcow.c
+++ b/disk/qcow.c
@@ -1203,7 +1203,7 @@ static int qcow_read_refcount_table(struct qcow *q)
if (!rft-rf_table)
return -1;
 
-   rft-root = RB_ROOT;
+   rft-root = (struct rb_root) RB_ROOT;
INIT_LIST_HEAD(rft-lru_list);
 
return pread_in_full(q-fd, rft-rf_table, sizeof(u64) * rft-rf_size, 
header-refcount_table_offset);
@@ -1289,7 +1289,7 @@ static struct disk_image *qcow2_probe(int fd, bool 
readonly)
 
l1t = q-table;
 
-   l1t-root = RB_ROOT;
+   l1t-root = (struct rb_root) RB_ROOT;
INIT_LIST_HEAD(l1t-lru_list);
 
h = q-header = qcow2_read_header(fd);
@@ -1435,7 +1435,7 @@ static struct disk_image *qcow1_probe(int fd, bool 
readonly)
 
l1t = q-table;
 
-   l1t-root = RB_ROOT;
+   l1t-root = (struct rb_root)RB_ROOT;
INIT_LIST_HEAD(l1t-lru_list);
 
h = q-header = qcow1_read_header(fd);
diff --git a/include/kvm/mutex.h b/include/kvm/mutex.h
index a90584b..1f7d0f6 100644
--- a/include/kvm/mutex.h
+++ b/include/kvm/mutex.h
@@ -13,7 +13,7 @@
 struct mutex {
pthread_mutex_t mutex;
 };
-#define MUTEX_INITIALIZER (struct mutex) { .mutex = PTHREAD_MUTEX_INITIALIZER }
+#define MUTEX_INITIALIZER { .mutex = PTHREAD_MUTEX_INITIALIZER }
 
 #define DEFINE_MUTEX(mtx) struct mutex mtx = MUTEX_INITIALIZER
 
diff --git a/include/linux/rbtree.h b/include/linux/rbtree.h
index fb31765..33adf78 100644
--- a/include/linux/rbtree.h
+++ b/include/linux/rbtree.h
@@ -46,7 +46,7 @@ struct rb_root {
 
 #define rb_parent(r)   ((struct rb_node *)((r)-__rb_parent_color  ~3))
 
-#define RB_ROOT(struct rb_root) { NULL, }
+#define RB_ROOT{ NULL, }
 #definerb_entry(ptr, type, member) container_of(ptr, type, member)
 
 #define RB_EMPTY_ROOT(root)  ((root)-rb_node == NULL)
diff --git a/virtio/9p.c b/virtio/9p.c
index 66dcc26..49e7c5c 100644
--- a/virtio/9p.c
+++ b/virtio/9p.c
@@ -1320,7 +1320,7 @@ static int set_size_vq(struct kvm *kvm, void *dev, u32 
vq, int size)
return size;
 }
 
-struct virtio_ops p9_dev_virtio_ops = (struct virtio_ops) {
+struct virtio_ops p9_dev_virtio_ops = {
.get_config = get_config,
.get_host_features  = get_host_features,
.set_guest_features = set_guest_features,
diff --git a/virtio/balloon.c b/virtio/balloon.c
index 84c4bb0..9564aa3 100644
--- a/virtio/balloon.c
+++ b/virtio/balloon.c
@@ -239,7 +239,7 @@ static int set_size_vq(struct kvm *kvm, void *dev, u32 vq, 
int size)
return size;
 }
 
-struct virtio_ops bln_dev_virtio_ops = (struct virtio_ops) {
+struct virtio_ops bln_dev_virtio_ops = {
.get_config = get_config,
.get_host_features  = get_host_features,
.set_guest_features = set_guest_features,
diff --git a/virtio/blk.c b/virtio/blk.c
index edfa8e6..c485e4f 100644
--- a/virtio/blk.c
+++ b/virtio/blk.c
@@ -244,7 +244,7 @@ static int set_size_vq(struct kvm *kvm, void *dev, u32 vq, 
int size)
return size;
 }
 
-static struct virtio_ops blk_dev_virtio_ops = (struct virtio_ops) {
+static struct virtio_ops blk_dev_virtio_ops = {
.get_config = get_config,
.get_host_features  = get_host_features,
.set_guest_features = set_guest_features,
diff --git a/virtio/console.c b/virtio/console.c
index 384eac1..f1c0a19 100644
--- a/virtio/console.c
+++ b/virtio/console.c
@@ -197,7 +197,7 @@ static int set_size_vq(struct kvm *kvm, void *dev, u32 vq, 
int size)
return

Re: [PATCH] kvmtool: Makefile: allow overriding CC and LD

2015-06-19 Thread Andre Przywara
Hi Paolo,

On 19/06/15 10:59, Paolo Bonzini wrote:
 
 
 On 18/06/2015 17:50, Andre Przywara wrote:
 Currently we set CC unconditionally to ${CROSS_COMPILE}gcc, the same
 for LD.
 Allow people to override the compiler name by specifying it explicitly
 on the command line or via the environment.
 Beside calling a certain compiler binary this allows to pass in
 options to the compiler, which lets us get rid of the PowerPC
 overrides in the Makefile. Possible uses:
 $ make CC=gcc -m64 LD=ld -melf64ppc
 (build kvmtool on a PowerPC toolchain defaulting to 32-bit)
 $ make CC=gcc -m32 LD=ld -melf_i386
 (build a 32-bit binary on a multilib-enabled x86-64 compiler)

 Signed-off-by: Andre Przywara andre.przyw...@arm.com
 ---
  Makefile | 10 ++
  1 file changed, 6 insertions(+), 4 deletions(-)

 diff --git a/Makefile b/Makefile
 index 6110b8e..888bee5 100644
 --- a/Makefile
 +++ b/Makefile
 @@ -14,9 +14,13 @@ export E Q
  include config/utilities.mak
  include config/feature-tests.mak
  
 -CC  := $(CROSS_COMPILE)gcc
 +ifeq ($(origin CC), default)
 +CC  := $(CROSS_COMPILE)gcc
 +endif
  CFLAGS  :=
 -LD  := $(CROSS_COMPILE)ld
 +ifeq ($(origin LD), default)
 +LD  := $(CROSS_COMPILE)ld
 +endif
 
 I know zero about the kvmtool build system, 

Well, it inherits a lot from the kernel ;-)

 but that ought not to be
 necessary.  The make manual says:
 
 If a variable has been set with a command argument (*note Overriding
 Variables: Overriding.), then ordinary assignments in the makefile are
 ignored.

Right, there was this nasty difference between CC=gcc make and
make CC=gcc. So I agree that the latter works even without that patch.

Guess I was only looking at the environment here.
Paolo, thanks for pointing out!

Will, please ignore this patch then.

Cheers,
Andre.

 
 Paolo
 
  LDFLAGS :=
  
  FIND:= find
 @@ -148,8 +152,6 @@ ifeq ($(ARCH), powerpc)
  OBJS+= powerpc/spapr_pci.o
  OBJS+= powerpc/xics.o
  ARCH_INCLUDE := powerpc/include
 -CFLAGS  += -m64
 -LDFLAGS += -m elf64ppc
  
  ARCH_WANT_LIBFDT := y
  endif

 
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] kvmtool: Makefile: allow overriding CC and LD

2015-06-19 Thread Andre Przywara
Hi Michael,

On 19/06/15 02:14, Michael Ellerman wrote:
 On Thu, 2015-06-18 at 16:50 +0100, Andre Przywara wrote:
 Currently we set CC unconditionally to ${CROSS_COMPILE}gcc, the same
 for LD.
 Allow people to override the compiler name by specifying it explicitly
 on the command line or via the environment.
 Beside calling a certain compiler binary this allows to pass in
 options to the compiler, which lets us get rid of the PowerPC
 overrides in the Makefile. Possible uses:
 $ make CC=gcc -m64 LD=ld -melf64ppc
 (build kvmtool on a PowerPC toolchain defaulting to 32-bit)
 $ make CC=gcc -m32 LD=ld -melf_i386
 (build a 32-bit binary on a multilib-enabled x86-64 compiler)
 
 
 I'm not a big fan of that.
 
 Your examples are all about overriding CFLAGS and LDFLAGS, not CC and LD. So
 if anything you should be allowing that. Adding flags to CC and LD is asking
 for trouble.

Will just disabled overriding CFLAGS and LDFLAGS, I think because
kvmtool inherited some C nastiness from the kernel, which does not
compile with random flags set (CFLAGS=-std=gnu99 was the one the broke it).
Maybe we should revisit that, either fix the code to be more robust to
comply with various standards or document that you should not have
CFLAGS set. Then allow overriding CFLAGS again.

But I thought that overriding CC is common practise - if you want to
select a different compiler, that is. Using a different bitness seems a
lot like a different compiler to me, same with different endianness.
I think I saw quite some examples on the web about using CC=gcc -m32.

I agree that abusing CC to pass optimization options to the compiler is
not good, but for kvmtool's Makefile I don't see how adding flags to CC
would hurt.

Cheers,
Andre.
--
To unsubscribe from this list: send the line unsubscribe kvm-ppc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] kvmtool: Makefile: allow overriding CC and LD

2015-06-19 Thread Andre Przywara
Hi Michael,

On 19/06/15 02:14, Michael Ellerman wrote:
 On Thu, 2015-06-18 at 16:50 +0100, Andre Przywara wrote:
 Currently we set CC unconditionally to ${CROSS_COMPILE}gcc, the same
 for LD.
 Allow people to override the compiler name by specifying it explicitly
 on the command line or via the environment.
 Beside calling a certain compiler binary this allows to pass in
 options to the compiler, which lets us get rid of the PowerPC
 overrides in the Makefile. Possible uses:
 $ make CC=gcc -m64 LD=ld -melf64ppc
 (build kvmtool on a PowerPC toolchain defaulting to 32-bit)
 $ make CC=gcc -m32 LD=ld -melf_i386
 (build a 32-bit binary on a multilib-enabled x86-64 compiler)
 
 
 I'm not a big fan of that.
 
 Your examples are all about overriding CFLAGS and LDFLAGS, not CC and LD. So
 if anything you should be allowing that. Adding flags to CC and LD is asking
 for trouble.

Will just disabled overriding CFLAGS and LDFLAGS, I think because
kvmtool inherited some C nastiness from the kernel, which does not
compile with random flags set (CFLAGS=-std=gnu99 was the one the broke it).
Maybe we should revisit that, either fix the code to be more robust to
comply with various standards or document that you should not have
CFLAGS set. Then allow overriding CFLAGS again.

But I thought that overriding CC is common practise - if you want to
select a different compiler, that is. Using a different bitness seems a
lot like a different compiler to me, same with different endianness.
I think I saw quite some examples on the web about using CC=gcc -m32.

I agree that abusing CC to pass optimization options to the compiler is
not good, but for kvmtool's Makefile I don't see how adding flags to CC
would hurt.

Cheers,
Andre.
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/3] powerpc: use default endianness for converting guest/init

2015-06-19 Thread Andre Przywara
Hi Michael,

On 19/06/15 02:08, Michael Ellerman wrote:
 On Thu, 2015-06-18 at 15:52 +0100, Andre Przywara wrote:
 Hi,

 On 06/17/2015 10:43 AM, Andre Przywara wrote:
 For converting the guest/init binary into an object file, we call
 the linker binary, setting the endianness to big endian explicitly
 when compiling kvmtool for powerpc.
 This breaks if the compiler is actually targetting little endian
 (which is true for the Debian port, for instance).
 Remove the explicit big endianness switch from the linker call to
 allow linking on little endian PowerPC builds again.

 Signed-off-by: Andre Przywara andre.przyw...@arm.com
 ---
 Hi,

 this fixed the powerpc64le build for me, while still compiling fine
 for big endian. Admittedly this whole init-guest_init.o conversion
 has its issues (with MIPS, for instance), which deserve proper fixing,
 but lets just fix that build for now.

 Will was concerned about breaking toolchains where the linker does not
 default to 64-bit. Is that an issue we care about?
 
 Yeah, that would be Debian  Ubuntu BE at least, and maybe Fedora too? I'm not
 sure how you compiled it big endian?

I have my own cross-compiler built from scratch. This is
powerpc64-linux-gnu, which is big endian. I don't have any distribution
behind it, it's just a cross-compiler with glibc.

 AFAICT LDFLAGS is only used in this dodgy binary-to-object-file
 conversion of guest/init. For this we rely on the resulting .o file to
 have the same ELF target as the other object files to be finally linked
 into the lkvm binary. As we don't compile guest/init with CFLAGS, there
 is a possible mismatch.

 I am looking into a proper fix for this now (compiling guest/init with
 CFLAGS, calling $CC with linker options instead of $LD and allowing CC
 and LD override). Still struggling with MIPS, though :-(
 
 Yeah that's obviously a better solution medium term.
 
 Can you do something like this? Sorry untested:
 
 diff --git a/Makefile b/Makefile
 index 6110b8e..8663d67 100644
 --- a/Makefile
 +++ b/Makefile
 @@ -149,7 +149,11 @@ ifeq ($(ARCH), powerpc)
 OBJS+= powerpc/xics.o
 ARCH_INCLUDE := powerpc/include
 CFLAGS  += -m64
 -   LDFLAGS += -m elf64ppc
 +   ifeq ($(call try-build,$(SOURCE_HELLO),$(CFLAGS),-m elf64ppc),y)
 +   LDFLAGS += -m elf64ppc
 +   else
 +   LDFLAGS += -m elf64leppc
 +   endif
  
 ARCH_WANT_LIBFDT := y
  endif

Nah, actually I want to get rid of those LDFLAGS at all. For some
reasons using ld to convert a random binary file into a C object is
causing trouble on MIPS, because ld uses a slightly different ELF target
than CC there.
I think this conversion should be more a job for objcopy than for ld,
but that does not fix the problem in a generic way (though I was able to
hack it with some magic objcopy options).

What works though is using xxd to convert the binary guest/init into a C
array:
$ xxd -i guest/init | $(CC) -x c -c - -o guest/guest_init.o
This has the nice property of using the same compiler that generates the
other object files and thus automatically matches them (which is a
problem under MIPS atm, as ld seems to default to some different ELF type).
The only issue is that xxd is part of the vim package, which would annoy
Emacs users. Not sure we are in a position to mandate vim for compiling
kvmtool ;-)

Cheers,
Andre.
--
To unsubscribe from this list: send the line unsubscribe kvm-ppc in


Re: [PATCH 2/3] powerpc: use default endianness for converting guest/init

2015-06-19 Thread Andre Przywara
Hi Michael,

On 19/06/15 02:08, Michael Ellerman wrote:
 On Thu, 2015-06-18 at 15:52 +0100, Andre Przywara wrote:
 Hi,

 On 06/17/2015 10:43 AM, Andre Przywara wrote:
 For converting the guest/init binary into an object file, we call
 the linker binary, setting the endianness to big endian explicitly
 when compiling kvmtool for powerpc.
 This breaks if the compiler is actually targetting little endian
 (which is true for the Debian port, for instance).
 Remove the explicit big endianness switch from the linker call to
 allow linking on little endian PowerPC builds again.

 Signed-off-by: Andre Przywara andre.przyw...@arm.com
 ---
 Hi,

 this fixed the powerpc64le build for me, while still compiling fine
 for big endian. Admittedly this whole init-guest_init.o conversion
 has its issues (with MIPS, for instance), which deserve proper fixing,
 but lets just fix that build for now.

 Will was concerned about breaking toolchains where the linker does not
 default to 64-bit. Is that an issue we care about?
 
 Yeah, that would be Debian  Ubuntu BE at least, and maybe Fedora too? I'm not
 sure how you compiled it big endian?

I have my own cross-compiler built from scratch. This is
powerpc64-linux-gnu, which is big endian. I don't have any distribution
behind it, it's just a cross-compiler with glibc.

 AFAICT LDFLAGS is only used in this dodgy binary-to-object-file
 conversion of guest/init. For this we rely on the resulting .o file to
 have the same ELF target as the other object files to be finally linked
 into the lkvm binary. As we don't compile guest/init with CFLAGS, there
 is a possible mismatch.

 I am looking into a proper fix for this now (compiling guest/init with
 CFLAGS, calling $CC with linker options instead of $LD and allowing CC
 and LD override). Still struggling with MIPS, though :-(
 
 Yeah that's obviously a better solution medium term.
 
 Can you do something like this? Sorry untested:
 
 diff --git a/Makefile b/Makefile
 index 6110b8e..8663d67 100644
 --- a/Makefile
 +++ b/Makefile
 @@ -149,7 +149,11 @@ ifeq ($(ARCH), powerpc)
 OBJS+= powerpc/xics.o
 ARCH_INCLUDE := powerpc/include
 CFLAGS  += -m64
 -   LDFLAGS += -m elf64ppc
 +   ifeq ($(call try-build,$(SOURCE_HELLO),$(CFLAGS),-m elf64ppc),y)
 +   LDFLAGS += -m elf64ppc
 +   else
 +   LDFLAGS += -m elf64leppc
 +   endif
  
 ARCH_WANT_LIBFDT := y
  endif

Nah, actually I want to get rid of those LDFLAGS at all. For some
reasons using ld to convert a random binary file into a C object is
causing trouble on MIPS, because ld uses a slightly different ELF target
than CC there.
I think this conversion should be more a job for objcopy than for ld,
but that does not fix the problem in a generic way (though I was able to
hack it with some magic objcopy options).

What works though is using xxd to convert the binary guest/init into a C
array:
$ xxd -i guest/init | $(CC) -x c -c - -o guest/guest_init.o
This has the nice property of using the same compiler that generates the
other object files and thus automatically matches them (which is a
problem under MIPS atm, as ld seems to default to some different ELF type).
The only issue is that xxd is part of the vim package, which would annoy
Emacs users. Not sure we are in a position to mandate vim for compiling
kvmtool ;-)

Cheers,
Andre.
--
To unsubscribe from this list: send the line unsubscribe kvm in


Re: [PATCH 13/13] KVM: arm64: enable ITS emulation as a virtual MSI controller

2015-06-18 Thread Andre Przywara
Hi Eric,

On 06/18/2015 09:43 AM, Eric Auger wrote:
 On 05/29/2015 11:53 AM, Andre Przywara wrote:
 If userspace has provided a base address for the ITS register frame,
 we enable the bits that advertise LPIs in the GICv3.
 When the guest has enabled LPIs and the ITS, we enable the emulation
 part by initializing the ITS data structures and trapping on ITS
 register frame accesses by the guest.
 Also we enable the KVM_SIGNAL_MSI feature to allow userland to inject
 MSIs into the guest. Not having enabled the ITS emulation will lead
 to a -ENODEV when trying to inject a MSI.




 Signed-off-by: Andre Przywara andre.przyw...@arm.com
 diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
 index 9f7b05f..09b1f46 100644
 --- a/virt/kvm/arm/vgic.c
 +++ b/virt/kvm/arm/vgic.c
 @@ -2254,3 +2254,13 @@ int kvm_set_msi(struct kvm_kernel_irq_routing_entry 
 *e,
  {
  return 0;
  }
 +
 +#ifdef CONFIG_HAVE_KVM_MSI
 I don't think the if#def is requested since the entry is already
 prevented in kvm_main.c in, case KVM_SIGNAL_MSI.

But that fails compilation on ARM (which uses this file as well),
because we have a dummy fail function in the header if
CONFIG_HAVE_KVM_MSI is not defined.
So you get: error: redefinition of 'kvm_send_userspace_msi'

Cheers,
Andre.

 +int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi)
 +{
 +if (kvm-arch.vgic.vm_ops.inject_msi)
 +return kvm-arch.vgic.vm_ops.inject_msi(kvm, msi);
 +else
 +return -ENODEV;
 +}
 +#endif

 
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/3] powerpc: use default endianness for converting guest/init

2015-06-18 Thread Andre Przywara
Hi,

On 06/17/2015 10:43 AM, Andre Przywara wrote:
 For converting the guest/init binary into an object file, we call
 the linker binary, setting the endianness to big endian explicitly
 when compiling kvmtool for powerpc.
 This breaks if the compiler is actually targetting little endian
 (which is true for the Debian port, for instance).
 Remove the explicit big endianness switch from the linker call to
 allow linking on little endian PowerPC builds again.
 
 Signed-off-by: Andre Przywara andre.przyw...@arm.com
 ---
 Hi,
 
 this fixed the powerpc64le build for me, while still compiling fine
 for big endian. Admittedly this whole init-guest_init.o conversion
 has its issues (with MIPS, for instance), which deserve proper fixing,
 but lets just fix that build for now.
 

Will was concerned about breaking toolchains where the linker does not
default to 64-bit. Is that an issue we care about?
AFAICT LDFLAGS is only used in this dodgy binary-to-object-file
conversion of guest/init. For this we rely on the resulting .o file to
have the same ELF target as the other object files to be finally linked
into the lkvm binary. As we don't compile guest/init with CFLAGS, there
is a possible mismatch.

I am looking into a proper fix for this now (compiling guest/init with
CFLAGS, calling $CC with linker options instead of $LD and allowing CC
and LD override). Still struggling with MIPS, though :-(

If someone is eager to fix compilation on PowerPC meanwhile, feel free
to use this fix for the time being.

Cheers,
Andre.

 
  Makefile | 1 -
  1 file changed, 1 deletion(-)
 
 diff --git a/Makefile b/Makefile
 index 6110b8e..c118e1a 100644
 --- a/Makefile
 +++ b/Makefile
 @@ -149,7 +149,6 @@ ifeq ($(ARCH), powerpc)
   OBJS+= powerpc/xics.o
   ARCH_INCLUDE := powerpc/include
   CFLAGS  += -m64
 - LDFLAGS += -m elf64ppc
  
   ARCH_WANT_LIBFDT := y
  endif
 
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/3] powerpc: use default endianness for converting guest/init

2015-06-18 Thread Andre Przywara
Hi,

On 06/17/2015 10:43 AM, Andre Przywara wrote:
 For converting the guest/init binary into an object file, we call
 the linker binary, setting the endianness to big endian explicitly
 when compiling kvmtool for powerpc.
 This breaks if the compiler is actually targetting little endian
 (which is true for the Debian port, for instance).
 Remove the explicit big endianness switch from the linker call to
 allow linking on little endian PowerPC builds again.
 
 Signed-off-by: Andre Przywara andre.przyw...@arm.com
 ---
 Hi,
 
 this fixed the powerpc64le build for me, while still compiling fine
 for big endian. Admittedly this whole init-guest_init.o conversion
 has its issues (with MIPS, for instance), which deserve proper fixing,
 but lets just fix that build for now.
 

Will was concerned about breaking toolchains where the linker does not
default to 64-bit. Is that an issue we care about?
AFAICT LDFLAGS is only used in this dodgy binary-to-object-file
conversion of guest/init. For this we rely on the resulting .o file to
have the same ELF target as the other object files to be finally linked
into the lkvm binary. As we don't compile guest/init with CFLAGS, there
is a possible mismatch.

I am looking into a proper fix for this now (compiling guest/init with
CFLAGS, calling $CC with linker options instead of $LD and allowing CC
and LD override). Still struggling with MIPS, though :-(

If someone is eager to fix compilation on PowerPC meanwhile, feel free
to use this fix for the time being.

Cheers,
Andre.

 
  Makefile | 1 -
  1 file changed, 1 deletion(-)
 
 diff --git a/Makefile b/Makefile
 index 6110b8e..c118e1a 100644
 --- a/Makefile
 +++ b/Makefile
 @@ -149,7 +149,6 @@ ifeq ($(ARCH), powerpc)
   OBJS+= powerpc/xics.o
   ARCH_INCLUDE := powerpc/include
   CFLAGS  += -m64
 - LDFLAGS += -m elf64ppc
  
   ARCH_WANT_LIBFDT := y
  endif
 
--
To unsubscribe from this list: send the line unsubscribe kvm-ppc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] kvmtool: Makefile: allow overriding CC and LD

2015-06-18 Thread Andre Przywara
Currently we set CC unconditionally to ${CROSS_COMPILE}gcc, the same
for LD.
Allow people to override the compiler name by specifying it explicitly
on the command line or via the environment.
Beside calling a certain compiler binary this allows to pass in
options to the compiler, which lets us get rid of the PowerPC
overrides in the Makefile. Possible uses:
$ make CC=gcc -m64 LD=ld -melf64ppc
(build kvmtool on a PowerPC toolchain defaulting to 32-bit)
$ make CC=gcc -m32 LD=ld -melf_i386
(build a 32-bit binary on a multilib-enabled x86-64 compiler)

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 Makefile | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/Makefile b/Makefile
index 6110b8e..888bee5 100644
--- a/Makefile
+++ b/Makefile
@@ -14,9 +14,13 @@ export E Q
 include config/utilities.mak
 include config/feature-tests.mak
 
-CC := $(CROSS_COMPILE)gcc
+ifeq ($(origin CC), default)
+   CC  := $(CROSS_COMPILE)gcc
+endif
 CFLAGS :=
-LD := $(CROSS_COMPILE)ld
+ifeq ($(origin LD), default)
+   LD  := $(CROSS_COMPILE)ld
+endif
 LDFLAGS:=
 
 FIND   := find
@@ -148,8 +152,6 @@ ifeq ($(ARCH), powerpc)
OBJS+= powerpc/spapr_pci.o
OBJS+= powerpc/xics.o
ARCH_INCLUDE := powerpc/include
-   CFLAGS  += -m64
-   LDFLAGS += -m elf64ppc
 
ARCH_WANT_LIBFDT := y
 endif
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] kvmtool: Makefile: allow overriding CC and LD

2015-06-18 Thread Andre Przywara
Currently we set CC unconditionally to ${CROSS_COMPILE}gcc, the same
for LD.
Allow people to override the compiler name by specifying it explicitly
on the command line or via the environment.
Beside calling a certain compiler binary this allows to pass in
options to the compiler, which lets us get rid of the PowerPC
overrides in the Makefile. Possible uses:
$ make CC=gcc -m64 LD=ld -melf64ppc
(build kvmtool on a PowerPC toolchain defaulting to 32-bit)
$ make CC=gcc -m32 LD=ld -melf_i386
(build a 32-bit binary on a multilib-enabled x86-64 compiler)

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 Makefile | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/Makefile b/Makefile
index 6110b8e..888bee5 100644
--- a/Makefile
+++ b/Makefile
@@ -14,9 +14,13 @@ export E Q
 include config/utilities.mak
 include config/feature-tests.mak
 
-CC := $(CROSS_COMPILE)gcc
+ifeq ($(origin CC), default)
+   CC  := $(CROSS_COMPILE)gcc
+endif
 CFLAGS :=
-LD := $(CROSS_COMPILE)ld
+ifeq ($(origin LD), default)
+   LD  := $(CROSS_COMPILE)ld
+endif
 LDFLAGS:=
 
 FIND   := find
@@ -148,8 +152,6 @@ ifeq ($(ARCH), powerpc)
OBJS+= powerpc/spapr_pci.o
OBJS+= powerpc/xics.o
ARCH_INCLUDE := powerpc/include
-   CFLAGS  += -m64
-   LDFLAGS += -m elf64ppc
 
ARCH_WANT_LIBFDT := y
 endif
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm-ppc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] kvmtool: don't use PCI config space IRQ line field

2015-06-18 Thread Andre Przywara
Hi Will,

On 06/16/2015 06:06 PM, Will Deacon wrote:
 On Mon, Jun 15, 2015 at 11:45:38AM +0100, Andre Przywara wrote:
 On 06/05/2015 05:41 PM, Will Deacon wrote:
 On Thu, Jun 04, 2015 at 04:20:45PM +0100, Andre Przywara wrote:
 In PCI config space there is an interrupt line field (offset 0x3f),
 which is used to initially communicate the IRQ line number from
 firmware to the OS. _Hardware_ should never use this information,
 as the OS is free to write any information in there.
 But kvmtool uses this number when it triggers IRQs in the guest,
 which fails starting with Linux 3.19-rc1, where the PCI layer starts
 writing the virtual IRQ number in there.

 Fix that by storing the IRQ number in a separate field in
 struct virtio_pci, which is independent from the PCI config space
 and cannot be influenced by the guest.
 This fixes ARM/ARM64 guests using PCI with newer kernels.

 Signed-off-by: Andre Przywara andre.przyw...@arm.com
 ---
  include/kvm/virtio-pci.h | 8 
  virtio/pci.c | 9 ++---
  2 files changed, 14 insertions(+), 3 deletions(-)

 diff --git a/include/kvm/virtio-pci.h b/include/kvm/virtio-pci.h
 index c795ce7..b70cadd 100644
 --- a/include/kvm/virtio-pci.h
 +++ b/include/kvm/virtio-pci.h
 @@ -30,6 +30,14 @@ struct virtio_pci {
u8  isr;
u32 features;
  
 +  /*
 +   * We cannot rely on the INTERRUPT_LINE byte in the config space once
 +   * we have run guest code, as the OS is allowed to use that field
 +   * as a scratch pad to communicate between driver and PCI layer.
 +   * So store our legacy interrupt line number in here for internal use.
 +   */
 +  u8  legacy_irq_line;
 +
/* MSI-X */
u16 config_vector;
u32 config_gsi;
 diff --git a/virtio/pci.c b/virtio/pci.c
 index 7556239..e17e5a9 100644
 --- a/virtio/pci.c
 +++ b/virtio/pci.c
 @@ -141,7 +141,7 @@ static bool virtio_pci__io_in(struct ioport *ioport, 
 struct kvm_cpu *vcpu, u16 p
break;
case VIRTIO_PCI_ISR:
ioport__write8(data, vpci-isr);
 -  kvm__irq_line(kvm, vpci-pci_hdr.irq_line, VIRTIO_IRQ_LOW);
 +  kvm__irq_line(kvm, vpci-legacy_irq_line, VIRTIO_IRQ_LOW);
vpci-isr = VIRTIO_IRQ_LOW;
break;
default:
 @@ -299,7 +299,7 @@ int virtio_pci__signal_vq(struct kvm *kvm, struct 
 virtio_device *vdev, u32 vq)
kvm__irq_trigger(kvm, vpci-gsis[vq]);
} else {
vpci-isr = VIRTIO_IRQ_HIGH;
 -  kvm__irq_trigger(kvm, vpci-pci_hdr.irq_line);
 +  kvm__irq_trigger(kvm, vpci-legacy_irq_line);
}
return 0;
  }
 @@ -323,7 +323,7 @@ int virtio_pci__signal_config(struct kvm *kvm, struct 
 virtio_device *vdev)
kvm__irq_trigger(kvm, vpci-config_gsi);
} else {
vpci-isr = VIRTIO_PCI_ISR_CONFIG;
 -  kvm__irq_trigger(kvm, vpci-pci_hdr.irq_line);
 +  kvm__irq_trigger(kvm, vpci-legacy_irq_line);
}
  
return 0;
 @@ -422,6 +422,9 @@ int virtio_pci__init(struct kvm *kvm, void *dev, 
 struct virtio_device *vdev,
if (r  0)
goto free_msix_mmio;
  
 +  /* save the IRQ that device__register() has allocated */
 +  vpci-legacy_irq_line = vpci-pci_hdr.irq_line;

 I'd rather we used the container_of trick that we do for virtio-mmio
 devices when assigning the irq in device__register. Then we can avoid
 this line completely.

 Not completely sure I get what you mean, I take it you want to assign
 legacy_irq_line in pci__assign_irq() directly (where the IRQ number is
 allocated).
 But this function is PCI generic code and is used by the VESA
 framebuffer and the shmem device on x86 as well. For those devices
 dev_hdr is not part of a struct virtio_pci, so we can't do container_of
 to assign the legacy_irq_line here directly.
 Admittedly this fix should apply to the other two users as well, but
 VESA does not use interrupts and pci-shmem is completely broken anyway,
 so I didn't bother to fix it in this regard.
 Would it be justified to provide an IRQ number field in struct
 device_header to address all users?

 Or what am I missing here?
 
 If VESA and shmem are broken, they should either be fixed or removed.

I am tempted to remove shmem, since it's broken:
a) there is no upstream driver, only some out-of-tree uio driver module
in some Github repo
b) the PCI device BARs do not match what QEMU implements and what the
uio driver expects (IO BAR vs. MMIO BAR)
c) there is (at least one) bug in kvmtool (easily fixed, though)
I haven't completely given up yet fixing it, but that's for another
series ;-)

However ...

 
 If you fix them, then we could have separate virtual buses for virtio-pci
 and emulated-pci (or whatever you want to call it). We could also have
 a separate bus for passthrough-devices too.
 
 However, that's quite a lot of work for a bug-fix, so I guess the easiest
 thing is to extend your current hack to cover VESA and shmem

Re: [PATCH 13/13] KVM: arm64: enable ITS emulation as a virtual MSI controller

2015-06-18 Thread Andre Przywara
On 06/18/2015 04:03 PM, Pavel Fedin wrote:
  Hello!
 
 But that fails compilation on ARM (which uses this file as well),
 because we have a dummy fail function in the header if
 CONFIG_HAVE_KVM_MSI is not defined.
 
  May be then remove that fail function too? Too many #ifdef's are not good...

Yes, that seems to work - now. I think I had more code in there before
that prevented exposure without #ifdef guarding.

Cheers,
Andre.

 
 Kind regards,
 Pavel Fedin
 Expert Engineer
 Samsung Electronics Research center Russia
 
 
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] powerpc: add hvcall.h header from Linux

2015-06-18 Thread Andre Przywara
The powerpc code uses some PAPR hypercalls, of which we need the
hypercall number. Copy just the needed macro definitions from the
kernel's (private) hvcall.h file and remove the extra tricks formerly
used to be able to include this header file directly.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
Hi,

this version of the header file just contains the definitions we
need, while still being easily diff-able against the original file.
Please consider applying this one.

Cheers,
Andre.

 powerpc/include/asm/hvcall.h | 33 +
 powerpc/spapr.h  |  3 ---
 2 files changed, 33 insertions(+), 3 deletions(-)
 create mode 100644 powerpc/include/asm/hvcall.h

diff --git a/powerpc/include/asm/hvcall.h b/powerpc/include/asm/hvcall.h
new file mode 100644
index 000..9d58f9b
--- /dev/null
+++ b/powerpc/include/asm/hvcall.h
@@ -0,0 +1,33 @@
+#ifndef _ASM_POWERPC_HVCALL_H
+#define _ASM_POWERPC_HVCALL_H
+
+/* This file is a trimmed-down version of arch/powerpc/include/asm/hvcall.h. */
+
+#define H_SUCCESS  0
+
+#define H_HARDWARE -1  /* Hardware error */
+#define H_FUNCTION -2  /* Function not supported */
+#define H_PRIVILEGE-3  /* Caller not privileged */
+#define H_PARAMETER-4  /* Parameter invalid, out-of-range or 
conflicting */
+
+#define H_SET_DABR 0x28
+#define H_LOGICAL_CI_LOAD  0x3c
+#define H_LOGICAL_CI_STORE 0x40
+#define H_LOGICAL_CACHE_LOAD   0x44
+#define H_LOGICAL_CACHE_STORE  0x48
+#define H_LOGICAL_ICBI 0x4c
+#define H_LOGICAL_DCBF 0x50
+
+#define H_GET_TERM_CHAR0x54
+#define H_PUT_TERM_CHAR0x58
+
+#define H_EOI  0x64
+#define H_CPPR 0x68
+#define H_IPI  0x6c
+#define H_IPOLL0x70
+#define H_XIRR 0x74
+
+#define H_SET_MODE 0x31C
+#define MAX_HCALL_OPCODE   H_SET_MODE
+
+#endif /* _ASM_POWERPC_HVCALL_H */
diff --git a/powerpc/spapr.h b/powerpc/spapr.h
index 0537f88..4c6e349 100644
--- a/powerpc/spapr.h
+++ b/powerpc/spapr.h
@@ -16,10 +16,7 @@
 
 #include inttypes.h
 
-/* We need some of the H_ hcall defs, but they're __KERNEL__ only. */
-#define __KERNEL__
 #include asm/hvcall.h
-#undef __KERNEL__
 
 #include kvm/kvm.h
 #include kvm/kvm-cpu.h
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] powerpc: add hvcall.h header from Linux

2015-06-18 Thread Andre Przywara
The powerpc code uses some PAPR hypercalls, of which we need the
hypercall number. Copy just the needed macro definitions from the
kernel's (private) hvcall.h file and remove the extra tricks formerly
used to be able to include this header file directly.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
Hi,

this version of the header file just contains the definitions we
need, while still being easily diff-able against the original file.
Please consider applying this one.

Cheers,
Andre.

 powerpc/include/asm/hvcall.h | 33 +
 powerpc/spapr.h  |  3 ---
 2 files changed, 33 insertions(+), 3 deletions(-)
 create mode 100644 powerpc/include/asm/hvcall.h

diff --git a/powerpc/include/asm/hvcall.h b/powerpc/include/asm/hvcall.h
new file mode 100644
index 000..9d58f9b
--- /dev/null
+++ b/powerpc/include/asm/hvcall.h
@@ -0,0 +1,33 @@
+#ifndef _ASM_POWERPC_HVCALL_H
+#define _ASM_POWERPC_HVCALL_H
+
+/* This file is a trimmed-down version of arch/powerpc/include/asm/hvcall.h. */
+
+#define H_SUCCESS  0
+
+#define H_HARDWARE -1  /* Hardware error */
+#define H_FUNCTION -2  /* Function not supported */
+#define H_PRIVILEGE-3  /* Caller not privileged */
+#define H_PARAMETER-4  /* Parameter invalid, out-of-range or 
conflicting */
+
+#define H_SET_DABR 0x28
+#define H_LOGICAL_CI_LOAD  0x3c
+#define H_LOGICAL_CI_STORE 0x40
+#define H_LOGICAL_CACHE_LOAD   0x44
+#define H_LOGICAL_CACHE_STORE  0x48
+#define H_LOGICAL_ICBI 0x4c
+#define H_LOGICAL_DCBF 0x50
+
+#define H_GET_TERM_CHAR0x54
+#define H_PUT_TERM_CHAR0x58
+
+#define H_EOI  0x64
+#define H_CPPR 0x68
+#define H_IPI  0x6c
+#define H_IPOLL0x70
+#define H_XIRR 0x74
+
+#define H_SET_MODE 0x31C
+#define MAX_HCALL_OPCODE   H_SET_MODE
+
+#endif /* _ASM_POWERPC_HVCALL_H */
diff --git a/powerpc/spapr.h b/powerpc/spapr.h
index 0537f88..4c6e349 100644
--- a/powerpc/spapr.h
+++ b/powerpc/spapr.h
@@ -16,10 +16,7 @@
 
 #include inttypes.h
 
-/* We need some of the H_ hcall defs, but they're __KERNEL__ only. */
-#define __KERNEL__
 #include asm/hvcall.h
-#undef __KERNEL__
 
 #include kvm/kvm.h
 #include kvm/kvm-cpu.h
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm-ppc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 09/10] arm: add support for supplying GICv3 redistributor addresses

2015-06-17 Thread Andre Przywara
Instead of the GIC virtual CPU interface an emulated GICv3 needs to
have accesses to its emulated redistributors trapped in the guest.
Add code to tell the kernel about the mapping if a GICv3 emulation was
requested by the user.

This contains some defines which are not (yet) in the (32 bit) header
files to allow compilation for ARM.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 arm/gic.c | 36 +++-
 arm/include/arm-common/gic.h  |  3 ++-
 arm/include/arm-common/kvm-arch.h |  7 +++
 3 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/arm/gic.c b/arm/gic.c
index b6c5868..efe4b42 100644
--- a/arm/gic.c
+++ b/arm/gic.c
@@ -9,7 +9,18 @@
 #include linux/kernel.h
 #include linux/kvm.h
 
+/* Those names are not defined for ARM (yet) */
+#ifndef KVM_VGIC_V3_ADDR_TYPE_DIST
+#define KVM_VGIC_V3_ADDR_TYPE_DIST 2
+#endif
+
+#ifndef KVM_VGIC_V3_ADDR_TYPE_REDIST
+#define KVM_VGIC_V3_ADDR_TYPE_REDIST 3
+#endif
+
 static int gic_fd = -1;
+static u64 gic_redists_base;
+static u64 gic_redists_size;
 
 static int gic__create_device(struct kvm *kvm, enum irqchip_type type)
 {
@@ -28,12 +39,21 @@ static int gic__create_device(struct kvm *kvm, enum 
irqchip_type type)
.group  = KVM_DEV_ARM_VGIC_GRP_ADDR,
.addr   = (u64)(unsigned long)dist_addr,
};
+   struct kvm_device_attr redist_attr = {
+   .group  = KVM_DEV_ARM_VGIC_GRP_ADDR,
+   .attr   = KVM_VGIC_V3_ADDR_TYPE_REDIST,
+   .addr   = (u64)(unsigned long)gic_redists_base,
+   };
 
switch (type) {
case IRQCHIP_GICV2:
gic_device.type = KVM_DEV_TYPE_ARM_VGIC_V2;
dist_attr.attr  = KVM_VGIC_V2_ADDR_TYPE_DIST;
break;
+   case IRQCHIP_GICV3:
+   gic_device.type = KVM_DEV_TYPE_ARM_VGIC_V3;
+   dist_attr.attr  = KVM_VGIC_V3_ADDR_TYPE_DIST;
+   break;
}
 
err = ioctl(kvm-vm_fd, KVM_CREATE_DEVICE, gic_device);
@@ -46,6 +66,9 @@ static int gic__create_device(struct kvm *kvm, enum 
irqchip_type type)
case IRQCHIP_GICV2:
err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, cpu_if_attr);
break;
+   case IRQCHIP_GICV3:
+   err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, redist_attr);
+   break;
}
if (err)
goto out_err;
@@ -97,6 +120,10 @@ int gic__create(struct kvm *kvm, enum irqchip_type type)
switch (type) {
case IRQCHIP_GICV2:
break;
+   case IRQCHIP_GICV3:
+   gic_redists_size = kvm-cfg.nrcpus * ARM_GIC_REDIST_SIZE;
+   gic_redists_base = ARM_GIC_DIST_BASE - gic_redists_size;
+   break;
default:
return -ENODEV;
}
@@ -156,12 +183,19 @@ void gic__generate_fdt_nodes(void *fdt, u32 phandle, enum 
irqchip_type type)
const char *compatible;
u64 reg_prop[] = {
cpu_to_fdt64(ARM_GIC_DIST_BASE), 
cpu_to_fdt64(ARM_GIC_DIST_SIZE),
-   cpu_to_fdt64(ARM_GIC_CPUI_BASE), 
cpu_to_fdt64(ARM_GIC_CPUI_SIZE),
+   0, 0,   /* to be filled */
};
 
switch (type) {
case IRQCHIP_GICV2:
compatible = arm,cortex-a15-gic;
+   reg_prop[2] = cpu_to_fdt64(ARM_GIC_CPUI_BASE);
+   reg_prop[3] = cpu_to_fdt64(ARM_GIC_CPUI_SIZE);
+   break;
+   case IRQCHIP_GICV3:
+   compatible = arm,gic-v3;
+   reg_prop[2] = cpu_to_fdt64(gic_redists_base);
+   reg_prop[3] = cpu_to_fdt64(gic_redists_size);
break;
default:
return;
diff --git a/arm/include/arm-common/gic.h b/arm/include/arm-common/gic.h
index 2ed76fa..403d93b 100644
--- a/arm/include/arm-common/gic.h
+++ b/arm/include/arm-common/gic.h
@@ -22,7 +22,8 @@
 #define GIC_MAX_IRQ255
 
 enum irqchip_type {
-   IRQCHIP_GICV2
+   IRQCHIP_GICV2,
+   IRQCHIP_GICV3
 };
 
 struct kvm;
diff --git a/arm/include/arm-common/kvm-arch.h 
b/arm/include/arm-common/kvm-arch.h
index 90d6733..0f5fb7f 100644
--- a/arm/include/arm-common/kvm-arch.h
+++ b/arm/include/arm-common/kvm-arch.h
@@ -30,6 +30,13 @@
 #define KVM_PCI_MMIO_AREA  (KVM_PCI_CFG_AREA + ARM_PCI_CFG_SIZE)
 #define KVM_VIRTIO_MMIO_AREA   ARM_MMIO_AREA
 
+/*
+ * On a GICv3 there must be one redistributor per vCPU.
+ * The value here is the size for one, we multiply this at runtime with
+ * the number of requested vCPUs to get the actual size.
+ */
+#define ARM_GIC_REDIST_SIZE0x2
+
 #define KVM_IRQ_OFFSET GIC_SPI_IRQ_BASE
 
 #define KVM_VM_TYPE0
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 05/10] arm: finish VGIC initialisation explicitly

2015-06-17 Thread Andre Przywara
Since Linux 3.19-rc1 there is a new API to explicitly initialise
the in-kernel GIC emulation by a userland KVM device call.
Use that to tell the kernel we are finished with the GIC
initialisation, since the automatic GIC init will only be provided
as a legacy functionality in the future.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
Reviewed-by: Marc Zyngier marc.zyng...@arm.com
---
 arm/gic.c | 25 ++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/arm/gic.c b/arm/gic.c
index 8560c9b..99f0d2b 100644
--- a/arm/gic.c
+++ b/arm/gic.c
@@ -98,24 +98,43 @@ int gic__create(struct kvm *kvm)
return err;
 }
 
+/*
+ * Sets the number of used interrupts and finalizes the GIC init explicitly.
+ */
 static int gic__init_gic(struct kvm *kvm)
 {
+   int ret;
+
int lines = irq__get_nr_allocated_lines();
u32 nr_irqs = ALIGN(lines, 32) + GIC_SPI_IRQ_BASE;
struct kvm_device_attr nr_irqs_attr = {
.group  = KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
.addr   = (u64)(unsigned long)nr_irqs,
};
+   struct kvm_device_attr vgic_init_attr = {
+   .group  = KVM_DEV_ARM_VGIC_GRP_CTRL,
+   .attr   = KVM_DEV_ARM_VGIC_CTRL_INIT,
+   };
 
/*
 * If we didn't use the KVM_CREATE_DEVICE method, KVM will
-* give us some default number of interrupts.
+* give us some default number of interrupts. The GIC initialization
+* will be done automatically in this case.
 */
if (gic_fd  0)
return 0;
 
-   if (!ioctl(gic_fd, KVM_HAS_DEVICE_ATTR, nr_irqs_attr))
-   return ioctl(gic_fd, KVM_SET_DEVICE_ATTR, nr_irqs_attr);
+   if (!ioctl(gic_fd, KVM_HAS_DEVICE_ATTR, nr_irqs_attr)) {
+   ret = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, nr_irqs_attr);
+   if (ret)
+   return ret;
+   }
+
+   if (!ioctl(gic_fd, KVM_HAS_DEVICE_ATTR, vgic_init_attr)) {
+   ret = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, vgic_init_attr);
+   if (ret)
+   return ret;
+   }
 
return 0;
 }
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 01/10] AArch64: Reserve two 64k pages for GIC CPU interface

2015-06-17 Thread Andre Przywara
From: Marc Zyngier marc.zyng...@arm.com

On AArch64 system with a GICv2, the GICC range can be aligned
to the last 4k block of a 64k page, ending up straddling two
64k pages. In order not to conflict with the distributor mapping,
allocate two 64k pages to the CPU interface.

Signed-off-by: Marc Zyngier marc.zyng...@arm.com
Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 arm/aarch64/include/kvm/kvm-arch.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arm/aarch64/include/kvm/kvm-arch.h 
b/arm/aarch64/include/kvm/kvm-arch.h
index 2f08a26..4925736 100644
--- a/arm/aarch64/include/kvm/kvm-arch.h
+++ b/arm/aarch64/include/kvm/kvm-arch.h
@@ -2,7 +2,7 @@
 #define KVM__KVM_ARCH_H
 
 #define ARM_GIC_DIST_SIZE  0x1
-#define ARM_GIC_CPUI_SIZE  0x1
+#define ARM_GIC_CPUI_SIZE  0x2
 
 #define ARM_KERN_OFFSET(kvm)   ((kvm)-cfg.arch.aarch32_guest  ?   \
0x8000  :   \
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 02/10] AArch{32,64}: use KVM_CREATE_DEVICE co to instanciate the GIC

2015-06-17 Thread Andre Przywara
From: Marc Zyngier marc.zyng...@arm.com

As of 3.14, KVM/arm supports the creation/configuration of the GIC through
a more generic device API, which is now the preferred way to do so.

Plumb the new API in, and allow the old code to be used as a fallback.

[Andre: Rename some functions on the way to differentiate between
creation and initialisation more clearly and fix error path.]

Signed-off-by: Marc Zyngier marc.zyng...@arm.com
Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 arm/gic.c| 69 +++-
 arm/include/arm-common/gic.h |  2 +-
 arm/kvm.c|  6 ++--
 3 files changed, 66 insertions(+), 11 deletions(-)

diff --git a/arm/gic.c b/arm/gic.c
index 5d8cbe6..1ff3663 100644
--- a/arm/gic.c
+++ b/arm/gic.c
@@ -7,7 +7,50 @@
 #include linux/byteorder.h
 #include linux/kvm.h
 
-int gic__init_irqchip(struct kvm *kvm)
+static int gic_fd = -1;
+
+static int gic__create_device(struct kvm *kvm)
+{
+   int err;
+   u64 cpu_if_addr = ARM_GIC_CPUI_BASE;
+   u64 dist_addr = ARM_GIC_DIST_BASE;
+   struct kvm_create_device gic_device = {
+   .type   = KVM_DEV_TYPE_ARM_VGIC_V2,
+   };
+   struct kvm_device_attr cpu_if_attr = {
+   .group  = KVM_DEV_ARM_VGIC_GRP_ADDR,
+   .attr   = KVM_VGIC_V2_ADDR_TYPE_CPU,
+   .addr   = (u64)(unsigned long)cpu_if_addr,
+   };
+   struct kvm_device_attr dist_attr = {
+   .group  = KVM_DEV_ARM_VGIC_GRP_ADDR,
+   .attr   = KVM_VGIC_V2_ADDR_TYPE_DIST,
+   .addr   = (u64)(unsigned long)dist_addr,
+   };
+
+   err = ioctl(kvm-vm_fd, KVM_CREATE_DEVICE, gic_device);
+   if (err)
+   return err;
+
+   gic_fd = gic_device.fd;
+
+   err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, cpu_if_attr);
+   if (err)
+   goto out_err;
+
+   err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, dist_attr);
+   if (err)
+   goto out_err;
+
+   return 0;
+
+out_err:
+   close(gic_fd);
+   gic_fd = -1;
+   return err;
+}
+
+static int gic__create_irqchip(struct kvm *kvm)
 {
int err;
struct kvm_arm_device_addr gic_addr[] = {
@@ -23,12 +66,6 @@ int gic__init_irqchip(struct kvm *kvm)
}
};
 
-   if (kvm-nrcpus  GIC_MAX_CPUS) {
-   pr_warning(%d CPUS greater than maximum of %d -- truncating\n,
-   kvm-nrcpus, GIC_MAX_CPUS);
-   kvm-nrcpus = GIC_MAX_CPUS;
-   }
-
err = ioctl(kvm-vm_fd, KVM_CREATE_IRQCHIP);
if (err)
return err;
@@ -41,6 +78,24 @@ int gic__init_irqchip(struct kvm *kvm)
return err;
 }
 
+int gic__create(struct kvm *kvm)
+{
+   int err;
+
+   if (kvm-nrcpus  GIC_MAX_CPUS) {
+   pr_warning(%d CPUS greater than maximum of %d -- truncating\n,
+   kvm-nrcpus, GIC_MAX_CPUS);
+   kvm-nrcpus = GIC_MAX_CPUS;
+   }
+
+   /* Try the new way first, and fallback on legacy method otherwise */
+   err = gic__create_device(kvm);
+   if (err)
+   err = gic__create_irqchip(kvm);
+
+   return err;
+}
+
 void gic__generate_fdt_nodes(void *fdt, u32 phandle)
 {
u64 reg_prop[] = {
diff --git a/arm/include/arm-common/gic.h b/arm/include/arm-common/gic.h
index 5a36f2c..44859f7 100644
--- a/arm/include/arm-common/gic.h
+++ b/arm/include/arm-common/gic.h
@@ -24,7 +24,7 @@
 struct kvm;
 
 int gic__alloc_irqnum(void);
-int gic__init_irqchip(struct kvm *kvm);
+int gic__create(struct kvm *kvm);
 void gic__generate_fdt_nodes(void *fdt, u32 phandle);
 
 #endif /* ARM_COMMON__GIC_H */
diff --git a/arm/kvm.c b/arm/kvm.c
index 58ad9fa..bcd2533 100644
--- a/arm/kvm.c
+++ b/arm/kvm.c
@@ -81,7 +81,7 @@ void kvm__arch_init(struct kvm *kvm, const char 
*hugetlbfs_path, u64 ram_size)
madvise(kvm-arch.ram_alloc_start, kvm-arch.ram_alloc_size,
MADV_MERGEABLE | MADV_HUGEPAGE);
 
-   /* Initialise the virtual GIC. */
-   if (gic__init_irqchip(kvm))
-   die(Failed to initialise virtual GIC);
+   /* Create the virtual GIC. */
+   if (gic__create(kvm))
+   die(Failed to create virtual GIC);
 }
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 06/10] arm: simplify MMIO dispatching

2015-06-17 Thread Andre Przywara
Currently we separate any incoming MMIO request into one of the ARM
memory map regions and take care to spare the GIC.
It turns out that this is unnecessary, as we only have one special
region (the IO port area in the first 64 KByte). The MMIO rbtree
takes care about unhandled MMIO ranges, so we can simply drop all the
special range checking (except that for the IO range) in
kvm_cpu__emulate_mmio().
As the GIC is handled in the kernel, a GIC MMIO access should never
reach userland (and we don't know what to do with it anyway).
This lets us delete some more code and simplifies future extensions
(like expanding the GIC regions).
To be in line with the other architectures, move the now simpler
code into a header file.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 arm/include/arm-common/kvm-arch.h | 12 
 arm/include/arm-common/kvm-cpu-arch.h | 14 --
 arm/kvm-cpu.c | 16 
 3 files changed, 12 insertions(+), 30 deletions(-)

diff --git a/arm/include/arm-common/kvm-arch.h 
b/arm/include/arm-common/kvm-arch.h
index 082131d..90d6733 100644
--- a/arm/include/arm-common/kvm-arch.h
+++ b/arm/include/arm-common/kvm-arch.h
@@ -45,18 +45,6 @@ static inline bool arm_addr_in_ioport_region(u64 phys_addr)
return phys_addr = KVM_IOPORT_AREA  phys_addr  limit;
 }
 
-static inline bool arm_addr_in_virtio_mmio_region(u64 phys_addr)
-{
-   u64 limit = KVM_VIRTIO_MMIO_AREA + ARM_VIRTIO_MMIO_SIZE;
-   return phys_addr = KVM_VIRTIO_MMIO_AREA  phys_addr  limit;
-}
-
-static inline bool arm_addr_in_pci_region(u64 phys_addr)
-{
-   u64 limit = KVM_PCI_CFG_AREA + ARM_PCI_CFG_SIZE + ARM_PCI_MMIO_SIZE;
-   return phys_addr = KVM_PCI_CFG_AREA  phys_addr  limit;
-}
-
 struct kvm_arch {
/*
 * We may have to align the guest memory for virtio, so keep the
diff --git a/arm/include/arm-common/kvm-cpu-arch.h 
b/arm/include/arm-common/kvm-cpu-arch.h
index 36c7872..329979a 100644
--- a/arm/include/arm-common/kvm-cpu-arch.h
+++ b/arm/include/arm-common/kvm-cpu-arch.h
@@ -44,8 +44,18 @@ static inline bool kvm_cpu__emulate_io(struct kvm_cpu *vcpu, 
u16 port, void *dat
return false;
 }
 
-bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data,
-  u32 len, u8 is_write);
+static inline bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr,
+u8 *data, u32 len, u8 is_write)
+{
+   if (arm_addr_in_ioport_region(phys_addr)) {
+   int direction = is_write ? KVM_EXIT_IO_OUT : KVM_EXIT_IO_IN;
+   u16 port = (phys_addr - KVM_IOPORT_AREA)  USHRT_MAX;
+
+   return kvm__emulate_io(vcpu, port, data, direction, len, 1);
+   }
+
+   return kvm__emulate_mmio(vcpu, phys_addr, data, len, is_write);
+}
 
 unsigned long kvm_cpu__get_vcpu_mpidr(struct kvm_cpu *vcpu);
 
diff --git a/arm/kvm-cpu.c b/arm/kvm-cpu.c
index ab08815..7780251 100644
--- a/arm/kvm-cpu.c
+++ b/arm/kvm-cpu.c
@@ -139,22 +139,6 @@ bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu)
return false;
 }
 
-bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data,
-  u32 len, u8 is_write)
-{
-   if (arm_addr_in_virtio_mmio_region(phys_addr)) {
-   return kvm__emulate_mmio(vcpu, phys_addr, data, len, is_write);
-   } else if (arm_addr_in_ioport_region(phys_addr)) {
-   int direction = is_write ? KVM_EXIT_IO_OUT : KVM_EXIT_IO_IN;
-   u16 port = (phys_addr - KVM_IOPORT_AREA)  USHRT_MAX;
-   return kvm__emulate_io(vcpu, port, data, direction, len, 1);
-   } else if (arm_addr_in_pci_region(phys_addr)) {
-   return kvm__emulate_mmio(vcpu, phys_addr, data, len, is_write);
-   }
-
-   return false;
-}
-
 void kvm_cpu__show_page_tables(struct kvm_cpu *vcpu)
 {
 }
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 03/10] irq: add irq__get_nr_allocated_lines

2015-06-17 Thread Andre Przywara
From: Marc Zyngier marc.zyng...@arm.com

The ARM GIC emulation needs to be told the number of interrupts
it has to support. As commit 1c262fa1dc7bc (kvm tools: irq: make
irq__alloc_line generic) made the interrupt counter private,
add a new accessor returning the number of interrupt lines we've
allocated so far.

Signed-off-by: Marc Zyngier marc.zyng...@arm.com
Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 include/kvm/irq.h | 1 +
 irq.c | 5 +
 2 files changed, 6 insertions(+)

diff --git a/include/kvm/irq.h b/include/kvm/irq.h
index 4cec6f0..8a78e43 100644
--- a/include/kvm/irq.h
+++ b/include/kvm/irq.h
@@ -11,6 +11,7 @@
 struct kvm;
 
 int irq__alloc_line(void);
+int irq__get_nr_allocated_lines(void);
 
 int irq__init(struct kvm *kvm);
 int irq__exit(struct kvm *kvm);
diff --git a/irq.c b/irq.c
index 33ea8d2..71eaa05 100644
--- a/irq.c
+++ b/irq.c
@@ -7,3 +7,8 @@ int irq__alloc_line(void)
 {
return next_line++;
 }
+
+int irq__get_nr_allocated_lines(void)
+{
+   return next_line - KVM_IRQ_OFFSET;
+}
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 10/10] arm: use new irqchip parameter to create different vGIC types

2015-06-17 Thread Andre Przywara
Currently we unconditionally create a virtual GICv2 in the guest.
Add a --irqchip= parameter to let the user specify a different GIC
type for the guest.
For now we the only other supported type is GICv3.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 arm/aarch64/arm-cpu.c|  2 +-
 arm/gic.c| 17 +
 arm/include/arm-common/kvm-config-arch.h |  9 -
 arm/kvm.c|  2 +-
 4 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/arm/aarch64/arm-cpu.c b/arm/aarch64/arm-cpu.c
index f702b9e..3dc8ea3 100644
--- a/arm/aarch64/arm-cpu.c
+++ b/arm/aarch64/arm-cpu.c
@@ -12,7 +12,7 @@
 static void generate_fdt_nodes(void *fdt, struct kvm *kvm, u32 gic_phandle)
 {
int timer_interrupts[4] = {13, 14, 11, 10};
-   gic__generate_fdt_nodes(fdt, gic_phandle, IRQCHIP_GICV2);
+   gic__generate_fdt_nodes(fdt, gic_phandle, kvm-cfg.arch.irqchip);
timer__generate_fdt_nodes(fdt, kvm, timer_interrupts);
 }
 
diff --git a/arm/gic.c b/arm/gic.c
index efe4b42..5b49416 100644
--- a/arm/gic.c
+++ b/arm/gic.c
@@ -22,6 +22,23 @@ static int gic_fd = -1;
 static u64 gic_redists_base;
 static u64 gic_redists_size;
 
+int irqchip_parser(const struct option *opt, const char *arg, int unset)
+{
+   enum irqchip_type *type = opt-value;
+
+   *type = IRQCHIP_GICV2;
+   if (!strcmp(arg, gicv2)) {
+   *type = IRQCHIP_GICV2;
+   } else if (!strcmp(arg, gicv3)) {
+   *type = IRQCHIP_GICV3;
+   } else if (strcmp(arg, default)) {
+   fprintf(stderr, irqchip: unknown type \%s\\n, arg);
+   return -1;
+   }
+
+   return 0;
+}
+
 static int gic__create_device(struct kvm *kvm, enum irqchip_type type)
 {
int err;
diff --git a/arm/include/arm-common/kvm-config-arch.h 
b/arm/include/arm-common/kvm-config-arch.h
index a8ebd94..9529881 100644
--- a/arm/include/arm-common/kvm-config-arch.h
+++ b/arm/include/arm-common/kvm-config-arch.h
@@ -8,8 +8,11 @@ struct kvm_config_arch {
unsigned intforce_cntfrq;
boolvirtio_trans_pci;
boolaarch32_guest;
+   enum irqchip_type irqchip;
 };
 
+int irqchip_parser(const struct option *opt, const char *arg, int unset);
+
 #define OPT_ARCH_RUN(pfx, cfg) 
\
pfx,
\
ARM_OPT_ARCH_RUN(cfg)   
\
@@ -21,6 +24,10 @@ struct kvm_config_arch {
 updated to program CNTFRQ correctly*),   
\
OPT_BOOLEAN('\0', force-pci, (cfg)-virtio_trans_pci,
\
Force virtio devices to use PCI as their default  
\
-   transport),
+   transport),   
\
+OPT_CALLBACK('\0', irqchip, (cfg)-irqchip, 
\
+[gicv2|gicv3],   \
+type of interrupt controller to emulate in the guest,
\
+irqchip_parser, NULL),
 
 #endif /* ARM_COMMON__KVM_CONFIG_ARCH_H */
diff --git a/arm/kvm.c b/arm/kvm.c
index f9685c2..d0e4a20 100644
--- a/arm/kvm.c
+++ b/arm/kvm.c
@@ -82,6 +82,6 @@ void kvm__arch_init(struct kvm *kvm, const char 
*hugetlbfs_path, u64 ram_size)
MADV_MERGEABLE | MADV_HUGEPAGE);
 
/* Create the virtual GIC. */
-   if (gic__create(kvm, IRQCHIP_GICV2))
+   if (gic__create(kvm, kvm-cfg.arch.irqchip))
die(Failed to create virtual GIC);
 }
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 07/10] limit number of VCPUs on demand

2015-06-17 Thread Andre Przywara
Currently the ARM GIC checks the number of VCPUs against a fixed
limit, which is GICv2 specific. Don't pretend we know better than the
kernel and let's get rid of that explicit check.
Instead be more relaxed about KVM_CREATE_VCPU failing with EINVAL,
which is the way the kernel communicates having reached a VCPU limit.
If we see this and have at least brought up one VCPU already
successfully, then don't panic, but limit the number of VCPUs instead.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 arm/gic.c |  6 --
 arm/kvm-cpu.c | 11 +--
 kvm-cpu.c |  7 +++
 3 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/arm/gic.c b/arm/gic.c
index 99f0d2b..05f85a2 100644
--- a/arm/gic.c
+++ b/arm/gic.c
@@ -84,12 +84,6 @@ int gic__create(struct kvm *kvm)
 {
int err;
 
-   if (kvm-nrcpus  GIC_MAX_CPUS) {
-   pr_warning(%d CPUS greater than maximum of %d -- truncating\n,
-   kvm-nrcpus, GIC_MAX_CPUS);
-   kvm-nrcpus = GIC_MAX_CPUS;
-   }
-
/* Try the new way first, and fallback on legacy method otherwise */
err = gic__create_device(kvm);
if (err)
diff --git a/arm/kvm-cpu.c b/arm/kvm-cpu.c
index 7780251..c1cf51d 100644
--- a/arm/kvm-cpu.c
+++ b/arm/kvm-cpu.c
@@ -47,12 +47,19 @@ struct kvm_cpu *kvm_cpu__arch_init(struct kvm *kvm, 
unsigned long cpu_id)
};
 
vcpu = calloc(1, sizeof(struct kvm_cpu));
-   if (!vcpu)
+   if (!vcpu) {
+   errno = ENOMEM;
return NULL;
+   }
 
vcpu-vcpu_fd = ioctl(kvm-vm_fd, KVM_CREATE_VCPU, cpu_id);
-   if (vcpu-vcpu_fd  0)
+   if (vcpu-vcpu_fd  0) {
+   if (errno == EINVAL) {
+   free(vcpu);
+   return NULL;
+   }
die_perror(KVM_CREATE_VCPU ioctl);
+   }
 
mmap_size = ioctl(kvm-sys_fd, KVM_GET_VCPU_MMAP_SIZE, 0);
if (mmap_size  0)
diff --git a/kvm-cpu.c b/kvm-cpu.c
index 5d90664..7a9d689 100644
--- a/kvm-cpu.c
+++ b/kvm-cpu.c
@@ -222,11 +222,18 @@ int kvm_cpu__init(struct kvm *kvm)
for (i = 0; i  kvm-nrcpus; i++) {
kvm-cpus[i] = kvm_cpu__arch_init(kvm, i);
if (!kvm-cpus[i]) {
+   if (i  0  errno == EINVAL)
+   break;
pr_warning(unable to initialize KVM VCPU);
goto fail_alloc;
}
}
 
+   if (i  kvm-nrcpus) {
+   kvm-nrcpus = i;
+   printf(  # The kernel limits the number of CPUs to %d\n, i);
+   }
+
return 0;
 
 fail_alloc:
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 00/10] kvmtool: arm64: GICv3 guest support

2015-06-17 Thread Andre Przywara
Hi,

a new version of the GICv3 support series for kvmtool.

I got rid of passing the number of redistributors around kvmtool.
The new patch 06/10 simplifies ARM's MMIO dispatching, so that we no
longer need to know the GIC size at this point. The FDT code uses
base and size values now directly and these values are private to
arm/gic.c.

The new 07/10 patch aims to solve the number-of-VCPUs problem Marc
mentioned. Instead of letting kvmtool have knowledge about particular
limits, let the kernel decide on this matter. Since KVM_CAP_MAX_VCPUS
is not really reliable on ARM, let's be a bit more relaxed about
KVM_CREATE_VCPU failing and stop with creating more VCPUs if we get
an EINVAL in return.

I also addressed the other comments Marcs gave, but I had to leave
some of the default switch-cases in due to the compiler complaining
otherwise.

Cheers,
Andre.
-

Since Linux 3.19 the kernel can emulate a GICv3 for KVM guests.
This allows more than 8 VCPUs in a guest and enables in-kernel irqchip
for non-backwards-compatible GICv3 implementations.

This series updates kvmtool to support this feature.
The first half of the series is mostly from Marc and supports some
newer features of the virtual GIC which we later depend on. The second
part enables support for a guest GICv3 by adding a new command line
parameter (--irqchip=).

We now use the KVM_CREATE_DEVICE interface to create a virtual GIC
and only fall back to the now legacy KVM_CREATE_IRQCHIP call if the
former is not supported by the kernel.
Also we use two new features the KVM_CREATE_DEVICE interface
introduces:
* We now set the number of actually used interrupts to avoid
  allocating too many of them without ever using them.
* We tell the kernel explicitly that we are finished with the GIC
  initialisation. This is a requirement for future VGIC versions.

The final three patches introduce virtual GICv3 support, so on
supported hardware (and given kernel support) the user can ask KVM to
emulate a GICv3, lifting the 8 VCPU limit of KVM. This is done by
specifying --irqchip=gicv3 on the command line.
For the time being the kernel only supports a virtual GICv3 on ARM64,
but as the GIC is shared in kvmtool, I had to add the macro
definitions to not break the build on ARM.

This series goes on top of the new official stand-alone repo hosted
on Will's kernel.org git [1].
Find a branch with those patches included at my repo [2].

[1] git://git.kernel.org/pub/scm/linux/kernel/git/will/kvmtool.git
[2] git://linux-arm.org/kvmtool.git (branch gicv3/v3)
http://www.linux-arm.org/git?p=kvmtool.git;a=log;h=refs/heads/gicv3/v3

Andre Przywara (6):
  arm: finish VGIC initialisation explicitly
  arm: simplify MMIO dispatching
  limit number of VCPUs on demand
  arm: prepare for instantiating different IRQ chip devices
  arm: add support for supplying GICv3 redistributor addresses
  arm: use new irqchip parameter to create different vGIC types

Marc Zyngier (4):
  AArch64: Reserve two 64k pages for GIC CPU interface
  AArch{32,64}: use KVM_CREATE_DEVICE  co to instanciate the GIC
  irq: add irq__get_nr_allocated_lines
  AArch{32,64}: dynamically configure the number of GIC interrupts

 arm/aarch32/arm-cpu.c|   2 +-
 arm/aarch64/arm-cpu.c|   2 +-
 arm/aarch64/include/kvm/kvm-arch.h   |   2 +-
 arm/gic.c| 190 +--
 arm/include/arm-common/gic.h |   9 +-
 arm/include/arm-common/kvm-arch.h|  19 ++--
 arm/include/arm-common/kvm-config-arch.h |   9 +-
 arm/include/arm-common/kvm-cpu-arch.h|  14 ++-
 arm/kvm-cpu.c|  27 ++---
 arm/kvm.c|   6 +-
 include/kvm/irq.h|   1 +
 irq.c|   5 +
 kvm-cpu.c|   7 ++
 13 files changed, 242 insertions(+), 51 deletions(-)

-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 08/10] arm: prepare for instantiating different IRQ chip devices

2015-06-17 Thread Andre Przywara
Extend the vGIC handling code to potentially deal with different IRQ
chip devices instead of hard-coding the GICv2 in.
We extend most vGIC functions to take a type parameter, but still put
GICv2 in at the top for the time being.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 arm/aarch32/arm-cpu.c|  2 +-
 arm/aarch64/arm-cpu.c|  2 +-
 arm/gic.c| 44 +++-
 arm/include/arm-common/gic.h |  8 ++--
 arm/kvm.c|  2 +-
 5 files changed, 44 insertions(+), 14 deletions(-)

diff --git a/arm/aarch32/arm-cpu.c b/arm/aarch32/arm-cpu.c
index 946e443..d8d6293 100644
--- a/arm/aarch32/arm-cpu.c
+++ b/arm/aarch32/arm-cpu.c
@@ -12,7 +12,7 @@ static void generate_fdt_nodes(void *fdt, struct kvm *kvm, 
u32 gic_phandle)
 {
int timer_interrupts[4] = {13, 14, 11, 10};
 
-   gic__generate_fdt_nodes(fdt, gic_phandle);
+   gic__generate_fdt_nodes(fdt, gic_phandle, IRQCHIP_GICV2);
timer__generate_fdt_nodes(fdt, kvm, timer_interrupts);
 }
 
diff --git a/arm/aarch64/arm-cpu.c b/arm/aarch64/arm-cpu.c
index 8efe877..f702b9e 100644
--- a/arm/aarch64/arm-cpu.c
+++ b/arm/aarch64/arm-cpu.c
@@ -12,7 +12,7 @@
 static void generate_fdt_nodes(void *fdt, struct kvm *kvm, u32 gic_phandle)
 {
int timer_interrupts[4] = {13, 14, 11, 10};
-   gic__generate_fdt_nodes(fdt, gic_phandle);
+   gic__generate_fdt_nodes(fdt, gic_phandle, IRQCHIP_GICV2);
timer__generate_fdt_nodes(fdt, kvm, timer_interrupts);
 }
 
diff --git a/arm/gic.c b/arm/gic.c
index 05f85a2..b6c5868 100644
--- a/arm/gic.c
+++ b/arm/gic.c
@@ -11,13 +11,13 @@
 
 static int gic_fd = -1;
 
-static int gic__create_device(struct kvm *kvm)
+static int gic__create_device(struct kvm *kvm, enum irqchip_type type)
 {
int err;
u64 cpu_if_addr = ARM_GIC_CPUI_BASE;
u64 dist_addr = ARM_GIC_DIST_BASE;
struct kvm_create_device gic_device = {
-   .type   = KVM_DEV_TYPE_ARM_VGIC_V2,
+   .flags  = 0,
};
struct kvm_device_attr cpu_if_attr = {
.group  = KVM_DEV_ARM_VGIC_GRP_ADDR,
@@ -26,17 +26,27 @@ static int gic__create_device(struct kvm *kvm)
};
struct kvm_device_attr dist_attr = {
.group  = KVM_DEV_ARM_VGIC_GRP_ADDR,
-   .attr   = KVM_VGIC_V2_ADDR_TYPE_DIST,
.addr   = (u64)(unsigned long)dist_addr,
};
 
+   switch (type) {
+   case IRQCHIP_GICV2:
+   gic_device.type = KVM_DEV_TYPE_ARM_VGIC_V2;
+   dist_attr.attr  = KVM_VGIC_V2_ADDR_TYPE_DIST;
+   break;
+   }
+
err = ioctl(kvm-vm_fd, KVM_CREATE_DEVICE, gic_device);
if (err)
return err;
 
gic_fd = gic_device.fd;
 
-   err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, cpu_if_attr);
+   switch (type) {
+   case IRQCHIP_GICV2:
+   err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, cpu_if_attr);
+   break;
+   }
if (err)
goto out_err;
 
@@ -80,13 +90,20 @@ static int gic__create_irqchip(struct kvm *kvm)
return err;
 }
 
-int gic__create(struct kvm *kvm)
+int gic__create(struct kvm *kvm, enum irqchip_type type)
 {
int err;
 
+   switch (type) {
+   case IRQCHIP_GICV2:
+   break;
+   default:
+   return -ENODEV;
+   }
+
/* Try the new way first, and fallback on legacy method otherwise */
-   err = gic__create_device(kvm);
-   if (err)
+   err = gic__create_device(kvm, type);
+   if (err  type == IRQCHIP_GICV2)
err = gic__create_irqchip(kvm);
 
return err;
@@ -134,15 +151,24 @@ static int gic__init_gic(struct kvm *kvm)
 }
 late_init(gic__init_gic)
 
-void gic__generate_fdt_nodes(void *fdt, u32 phandle)
+void gic__generate_fdt_nodes(void *fdt, u32 phandle, enum irqchip_type type)
 {
+   const char *compatible;
u64 reg_prop[] = {
cpu_to_fdt64(ARM_GIC_DIST_BASE), 
cpu_to_fdt64(ARM_GIC_DIST_SIZE),
cpu_to_fdt64(ARM_GIC_CPUI_BASE), 
cpu_to_fdt64(ARM_GIC_CPUI_SIZE),
};
 
+   switch (type) {
+   case IRQCHIP_GICV2:
+   compatible = arm,cortex-a15-gic;
+   break;
+   default:
+   return;
+   }
+
_FDT(fdt_begin_node(fdt, intc));
-   _FDT(fdt_property_string(fdt, compatible, arm,cortex-a15-gic));
+   _FDT(fdt_property_string(fdt, compatible, compatible));
_FDT(fdt_property_cell(fdt, #interrupt-cells, GIC_FDT_IRQ_NUM_CELLS));
_FDT(fdt_property(fdt, interrupt-controller, NULL, 0));
_FDT(fdt_property(fdt, reg, reg_prop, sizeof(reg_prop)));
diff --git a/arm/include/arm-common/gic.h b/arm/include/arm-common/gic.h
index 44859f7..2ed76fa 100644
--- a/arm/include/arm-common/gic.h
+++ b/arm/include/arm-common/gic.h
@@ -21,10 +21,14 @@
 #define GIC_MAX_CPUS   8
 #define GIC_MAX_IRQ

[PATCH v3 04/10] AArch{32,64}: dynamically configure the number of GIC interrupts

2015-06-17 Thread Andre Przywara
From: Marc Zyngier marc.zyng...@arm.com

In order to reduce the memory usage of large guests (as well
as improve performance), tell KVM about the number of interrupts
we require.

To avoid synchronization with the various device creation,
use a late_init callback to compute the GIC configuration.
[Andre: rename to gic__init_gic() to ease future expansion]

Signed-off-by: Marc Zyngier marc.zyng...@arm.com
Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 arm/gic.c | 25 +
 1 file changed, 25 insertions(+)

diff --git a/arm/gic.c b/arm/gic.c
index 1ff3663..8560c9b 100644
--- a/arm/gic.c
+++ b/arm/gic.c
@@ -1,10 +1,12 @@
 #include kvm/fdt.h
+#include kvm/irq.h
 #include kvm/kvm.h
 #include kvm/virtio.h
 
 #include arm-common/gic.h
 
 #include linux/byteorder.h
+#include linux/kernel.h
 #include linux/kvm.h
 
 static int gic_fd = -1;
@@ -96,6 +98,29 @@ int gic__create(struct kvm *kvm)
return err;
 }
 
+static int gic__init_gic(struct kvm *kvm)
+{
+   int lines = irq__get_nr_allocated_lines();
+   u32 nr_irqs = ALIGN(lines, 32) + GIC_SPI_IRQ_BASE;
+   struct kvm_device_attr nr_irqs_attr = {
+   .group  = KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
+   .addr   = (u64)(unsigned long)nr_irqs,
+   };
+
+   /*
+* If we didn't use the KVM_CREATE_DEVICE method, KVM will
+* give us some default number of interrupts.
+*/
+   if (gic_fd  0)
+   return 0;
+
+   if (!ioctl(gic_fd, KVM_HAS_DEVICE_ATTR, nr_irqs_attr))
+   return ioctl(gic_fd, KVM_SET_DEVICE_ATTR, nr_irqs_attr);
+
+   return 0;
+}
+late_init(gic__init_gic)
+
 void gic__generate_fdt_nodes(void *fdt, u32 phandle)
 {
u64 reg_prop[] = {
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/3] kvmtool: fixes for PowerPC

2015-06-17 Thread Andre Przywara
Hello,

some patches to fix at least the build of the new kvmtool for
PowerPC. I could only compile test it so far, so I'd be grateful
if people more familiar with that architecture can have a look
and maybe even test it on actual machines.

Cheers,
Andre.

Andre Przywara (3):
  powerpc: implement barrier primitives
  powerpc: use default endianness for converting guest/init
  powerpc: add hvcall.h header from Linux

 Makefile  |   1 -
 powerpc/include/asm/hvcall.h  | 287 ++
 powerpc/include/kvm/barrier.h |   4 +-
 powerpc/spapr.h   |   3 -
 4 files changed, 290 insertions(+), 5 deletions(-)
 create mode 100644 powerpc/include/asm/hvcall.h

-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm-ppc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/3] powerpc: use default endianness for converting guest/init

2015-06-17 Thread Andre Przywara
For converting the guest/init binary into an object file, we call
the linker binary, setting the endianness to big endian explicitly
when compiling kvmtool for powerpc.
This breaks if the compiler is actually targetting little endian
(which is true for the Debian port, for instance).
Remove the explicit big endianness switch from the linker call to
allow linking on little endian PowerPC builds again.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
Hi,

this fixed the powerpc64le build for me, while still compiling fine
for big endian. Admittedly this whole init-guest_init.o conversion
has its issues (with MIPS, for instance), which deserve proper fixing,
but lets just fix that build for now.

Andre.

 Makefile | 1 -
 1 file changed, 1 deletion(-)

diff --git a/Makefile b/Makefile
index 6110b8e..c118e1a 100644
--- a/Makefile
+++ b/Makefile
@@ -149,7 +149,6 @@ ifeq ($(ARCH), powerpc)
OBJS+= powerpc/xics.o
ARCH_INCLUDE := powerpc/include
CFLAGS  += -m64
-   LDFLAGS += -m elf64ppc
 
ARCH_WANT_LIBFDT := y
 endif
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm-ppc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/3] powerpc: add hvcall.h header from Linux

2015-06-17 Thread Andre Przywara
The powerpc code uses some PAPR hypercalls, of which we need the
hypercall number. Copy the macro definition parts from the kernel's
(private) hvcall.h file and remove the extra tricks formerly used
to be able to include this header file directly.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
Hi,

I copied most of the Linux header, without removing
definitions that kvmtool doesn't use. That should make updates
easier. If people would prefer a bespoke header, let me know.

Andre.

 powerpc/include/asm/hvcall.h | 287 +++
 powerpc/spapr.h  |   3 -
 2 files changed, 287 insertions(+), 3 deletions(-)
 create mode 100644 powerpc/include/asm/hvcall.h

diff --git a/powerpc/include/asm/hvcall.h b/powerpc/include/asm/hvcall.h
new file mode 100644
index 000..b6dc250
--- /dev/null
+++ b/powerpc/include/asm/hvcall.h
@@ -0,0 +1,287 @@
+#ifndef _ASM_POWERPC_HVCALL_H
+#define _ASM_POWERPC_HVCALL_H
+
+#define HVSC   .long 0x4422
+
+#define H_SUCCESS  0
+#define H_BUSY 1   /* Hardware busy -- retry later */
+#define H_CLOSED   2   /* Resource closed */
+#define H_NOT_AVAILABLE 3
+#define H_CONSTRAINED  4   /* Resource request constrained to max allowed 
*/
+#define H_PARTIAL   5
+#define H_IN_PROGRESS  14  /* Kind of like busy */
+#define H_PAGE_REGISTERED 15
+#define H_PARTIAL_STORE   16
+#define H_PENDING  17  /* returned from H_POLL_PENDING */
+#define H_CONTINUE 18  /* Returned from H_Join on success */
+#define H_LONG_BUSY_START_RANGE9900  /* Start of long busy 
range */
+#define H_LONG_BUSY_ORDER_1_MSEC   9900  /* Long busy, hint that 1msec \
+is a good time to retry */
+#define H_LONG_BUSY_ORDER_10_MSEC  9901  /* Long busy, hint that 10msec \
+is a good time to retry */
+#define H_LONG_BUSY_ORDER_100_MSEC 9902  /* Long busy, hint that 100msec \
+is a good time to retry */
+#define H_LONG_BUSY_ORDER_1_SEC9903  /* Long busy, hint that 
1sec \
+is a good time to retry */
+#define H_LONG_BUSY_ORDER_10_SEC   9904  /* Long busy, hint that 10sec \
+is a good time to retry */
+#define H_LONG_BUSY_ORDER_100_SEC  9905  /* Long busy, hint that 100sec \
+is a good time to retry */
+#define H_LONG_BUSY_END_RANGE  9905  /* End of long busy range */
+
+/* Internal value used in book3s_hv kvm support; not returned to guests */
+#define H_TOO_HARD 
+
+#define H_HARDWARE -1  /* Hardware error */
+#define H_FUNCTION -2  /* Function not supported */
+#define H_PRIVILEGE-3  /* Caller not privileged */
+#define H_PARAMETER-4  /* Parameter invalid, out-of-range or 
conflicting */
+#define H_BAD_MODE -5  /* Illegal msr value */
+#define H_PTEG_FULL-6  /* PTEG is full */
+#define H_NOT_FOUND-7  /* PTE was not found */
+#define H_RESERVED_DABR-8  /* DABR address is reserved by the 
hypervisor on this processor */
+#define H_NO_MEM   -9
+#define H_AUTHORITY-10
+#define H_PERMISSION   -11
+#define H_DROPPED  -12
+#define H_SOURCE_PARM  -13
+#define H_DEST_PARM-14
+#define H_REMOTE_PARM  -15
+#define H_RESOURCE -16
+#define H_ADAPTER_PARM  -17
+#define H_RH_PARM   -18
+#define H_RCQ_PARM  -19
+#define H_SCQ_PARM  -20
+#define H_EQ_PARM   -21
+#define H_RT_PARM   -22
+#define H_ST_PARM   -23
+#define H_SIGT_PARM -24
+#define H_TOKEN_PARM-25
+#define H_MLENGTH_PARM  -27
+#define H_MEM_PARM  -28
+#define H_MEM_ACCESS_PARM -29
+#define H_ATTR_PARM -30
+#define H_PORT_PARM -31
+#define H_MCG_PARM  -32
+#define H_VL_PARM   -33
+#define H_TSIZE_PARM-34
+#define H_TRACE_PARM-35
+
+#define H_MASK_PARM -37
+#define H_MCG_FULL  -38
+#define H_ALIAS_EXIST   -39
+#define H_P_COUNTER -40
+#define H_TABLE_FULL-41
+#define H_ALT_TABLE -42
+#define H_MR_CONDITION  -43
+#define H_NOT_ENOUGH_RESOURCES -44
+#define H_R_STATE   -45
+#define H_RESCINDED -46
+#define H_P2   -55
+#define H_P3   -56
+#define H_P4   -57
+#define H_P5   -58
+#define H_P6   -59
+#define H_P7   -60
+#define H_P8   -61
+#define H_P9   -62
+#define H_TOO_BIG  -64
+#define H_OVERLAP  -68
+#define H_INTERRUPT-69
+#define H_BAD_DATA -70
+#define H_NOT_ACTIVE   -71
+#define H_SG_LIST  -72
+#define H_OP_MODE  -73
+#define H_COP_HW   -74
+#define H_UNSUPPORTED_FLAG_START   -256
+#define H_UNSUPPORTED_FLAG_END -511
+#define H_MULTI_THREADS_ACTIVE -9005
+#define H_OUTSTANDING_COP_OPS  -9006
+
+
+/* Long Busy is a condition that can

[PATCH 2/3] powerpc: use default endianness for converting guest/init

2015-06-17 Thread Andre Przywara
For converting the guest/init binary into an object file, we call
the linker binary, setting the endianness to big endian explicitly
when compiling kvmtool for powerpc.
This breaks if the compiler is actually targetting little endian
(which is true for the Debian port, for instance).
Remove the explicit big endianness switch from the linker call to
allow linking on little endian PowerPC builds again.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
Hi,

this fixed the powerpc64le build for me, while still compiling fine
for big endian. Admittedly this whole init-guest_init.o conversion
has its issues (with MIPS, for instance), which deserve proper fixing,
but lets just fix that build for now.

Andre.

 Makefile | 1 -
 1 file changed, 1 deletion(-)

diff --git a/Makefile b/Makefile
index 6110b8e..c118e1a 100644
--- a/Makefile
+++ b/Makefile
@@ -149,7 +149,6 @@ ifeq ($(ARCH), powerpc)
OBJS+= powerpc/xics.o
ARCH_INCLUDE := powerpc/include
CFLAGS  += -m64
-   LDFLAGS += -m elf64ppc
 
ARCH_WANT_LIBFDT := y
 endif
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/3] powerpc: add hvcall.h header from Linux

2015-06-17 Thread Andre Przywara
The powerpc code uses some PAPR hypercalls, of which we need the
hypercall number. Copy the macro definition parts from the kernel's
(private) hvcall.h file and remove the extra tricks formerly used
to be able to include this header file directly.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
Hi,

I copied most of the Linux header, without removing
definitions that kvmtool doesn't use. That should make updates
easier. If people would prefer a bespoke header, let me know.

Andre.

 powerpc/include/asm/hvcall.h | 287 +++
 powerpc/spapr.h  |   3 -
 2 files changed, 287 insertions(+), 3 deletions(-)
 create mode 100644 powerpc/include/asm/hvcall.h

diff --git a/powerpc/include/asm/hvcall.h b/powerpc/include/asm/hvcall.h
new file mode 100644
index 000..b6dc250
--- /dev/null
+++ b/powerpc/include/asm/hvcall.h
@@ -0,0 +1,287 @@
+#ifndef _ASM_POWERPC_HVCALL_H
+#define _ASM_POWERPC_HVCALL_H
+
+#define HVSC   .long 0x4422
+
+#define H_SUCCESS  0
+#define H_BUSY 1   /* Hardware busy -- retry later */
+#define H_CLOSED   2   /* Resource closed */
+#define H_NOT_AVAILABLE 3
+#define H_CONSTRAINED  4   /* Resource request constrained to max allowed 
*/
+#define H_PARTIAL   5
+#define H_IN_PROGRESS  14  /* Kind of like busy */
+#define H_PAGE_REGISTERED 15
+#define H_PARTIAL_STORE   16
+#define H_PENDING  17  /* returned from H_POLL_PENDING */
+#define H_CONTINUE 18  /* Returned from H_Join on success */
+#define H_LONG_BUSY_START_RANGE9900  /* Start of long busy 
range */
+#define H_LONG_BUSY_ORDER_1_MSEC   9900  /* Long busy, hint that 1msec \
+is a good time to retry */
+#define H_LONG_BUSY_ORDER_10_MSEC  9901  /* Long busy, hint that 10msec \
+is a good time to retry */
+#define H_LONG_BUSY_ORDER_100_MSEC 9902  /* Long busy, hint that 100msec \
+is a good time to retry */
+#define H_LONG_BUSY_ORDER_1_SEC9903  /* Long busy, hint that 
1sec \
+is a good time to retry */
+#define H_LONG_BUSY_ORDER_10_SEC   9904  /* Long busy, hint that 10sec \
+is a good time to retry */
+#define H_LONG_BUSY_ORDER_100_SEC  9905  /* Long busy, hint that 100sec \
+is a good time to retry */
+#define H_LONG_BUSY_END_RANGE  9905  /* End of long busy range */
+
+/* Internal value used in book3s_hv kvm support; not returned to guests */
+#define H_TOO_HARD 
+
+#define H_HARDWARE -1  /* Hardware error */
+#define H_FUNCTION -2  /* Function not supported */
+#define H_PRIVILEGE-3  /* Caller not privileged */
+#define H_PARAMETER-4  /* Parameter invalid, out-of-range or 
conflicting */
+#define H_BAD_MODE -5  /* Illegal msr value */
+#define H_PTEG_FULL-6  /* PTEG is full */
+#define H_NOT_FOUND-7  /* PTE was not found */
+#define H_RESERVED_DABR-8  /* DABR address is reserved by the 
hypervisor on this processor */
+#define H_NO_MEM   -9
+#define H_AUTHORITY-10
+#define H_PERMISSION   -11
+#define H_DROPPED  -12
+#define H_SOURCE_PARM  -13
+#define H_DEST_PARM-14
+#define H_REMOTE_PARM  -15
+#define H_RESOURCE -16
+#define H_ADAPTER_PARM  -17
+#define H_RH_PARM   -18
+#define H_RCQ_PARM  -19
+#define H_SCQ_PARM  -20
+#define H_EQ_PARM   -21
+#define H_RT_PARM   -22
+#define H_ST_PARM   -23
+#define H_SIGT_PARM -24
+#define H_TOKEN_PARM-25
+#define H_MLENGTH_PARM  -27
+#define H_MEM_PARM  -28
+#define H_MEM_ACCESS_PARM -29
+#define H_ATTR_PARM -30
+#define H_PORT_PARM -31
+#define H_MCG_PARM  -32
+#define H_VL_PARM   -33
+#define H_TSIZE_PARM-34
+#define H_TRACE_PARM-35
+
+#define H_MASK_PARM -37
+#define H_MCG_FULL  -38
+#define H_ALIAS_EXIST   -39
+#define H_P_COUNTER -40
+#define H_TABLE_FULL-41
+#define H_ALT_TABLE -42
+#define H_MR_CONDITION  -43
+#define H_NOT_ENOUGH_RESOURCES -44
+#define H_R_STATE   -45
+#define H_RESCINDED -46
+#define H_P2   -55
+#define H_P3   -56
+#define H_P4   -57
+#define H_P5   -58
+#define H_P6   -59
+#define H_P7   -60
+#define H_P8   -61
+#define H_P9   -62
+#define H_TOO_BIG  -64
+#define H_OVERLAP  -68
+#define H_INTERRUPT-69
+#define H_BAD_DATA -70
+#define H_NOT_ACTIVE   -71
+#define H_SG_LIST  -72
+#define H_OP_MODE  -73
+#define H_COP_HW   -74
+#define H_UNSUPPORTED_FLAG_START   -256
+#define H_UNSUPPORTED_FLAG_END -511
+#define H_MULTI_THREADS_ACTIVE -9005
+#define H_OUTSTANDING_COP_OPS  -9006
+
+
+/* Long Busy is a condition that can

[PATCH 0/3] kvmtool: fixes for PowerPC

2015-06-17 Thread Andre Przywara
Hello,

some patches to fix at least the build of the new kvmtool for
PowerPC. I could only compile test it so far, so I'd be grateful
if people more familiar with that architecture can have a look
and maybe even test it on actual machines.

Cheers,
Andre.

Andre Przywara (3):
  powerpc: implement barrier primitives
  powerpc: use default endianness for converting guest/init
  powerpc: add hvcall.h header from Linux

 Makefile  |   1 -
 powerpc/include/asm/hvcall.h  | 287 ++
 powerpc/include/kvm/barrier.h |   4 +-
 powerpc/spapr.h   |   3 -
 4 files changed, 290 insertions(+), 5 deletions(-)
 create mode 100644 powerpc/include/asm/hvcall.h

-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/3] powerpc: implement barrier primitives

2015-06-17 Thread Andre Przywara
Instead of referring to the Linux header including the barrier
macros, copy over the rather simple implementation for the PowerPC
barrier instructions kvmtool uses. This fixes build for powerpc.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
Hi,

I just took what kvmtool seems to have used before, I actually have
no idea if sync is the right instruction or lwsync would do.
Would be nice if some people with PowerPC knowledge could comment.

Cheers,
Andre.

 powerpc/include/kvm/barrier.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/powerpc/include/kvm/barrier.h b/powerpc/include/kvm/barrier.h
index dd5115a..4b708ae 100644
--- a/powerpc/include/kvm/barrier.h
+++ b/powerpc/include/kvm/barrier.h
@@ -1,6 +1,8 @@
 #ifndef _KVM_BARRIER_H_
 #define _KVM_BARRIER_H_
 
-#include asm/barrier.h
+#define mb()   asm volatile (sync : : : memory)
+#define rmb()  asm volatile (sync : : : memory)
+#define wmb()  asm volatile (sync : : : memory)
 
 #endif /* _KVM_BARRIER_H_ */
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: IRQFD support with GICv3 ITS (WAS: RE: [PATCH 00/13] arm64: KVM: GICv3 ITS emulation)

2015-06-17 Thread Andre Przywara
Здравствуй Pavel,

On 06/17/2015 10:21 AM, Pavel Fedin wrote:
  PING!
  The discussion has suddenly stopped... What is our status? Is ITS v2 patch 
 being
 developed, or what?

Yes, I am about to get a v2 ready, but mostly with some fixes. If you
want to work on top of it, I can push a WIP branch to my repo.

As Marc mentioned before, this whole irqfd story does not go together
well with KVM and the ITS architecture, so that needs some more
investigation (which I am planning to do in the next days).

Cheers,
Andre.

And do we have some conclusion on irqfd ?
 
 Kind regards,
 Pavel Fedin
 Expert Engineer
 Samsung Electronics Research center Russia
 
 
 -Original Message-
 From: kvm-ow...@vger.kernel.org [mailto:kvm-ow...@vger.kernel.org] On Behalf 
 Of Pavel
 Fedin
 Sent: Wednesday, June 10, 2015 6:30 PM
 To: 'Eric Auger'; 'Marc Zyngier'; 'Andre Przywara'; 
 christoffer.d...@linaro.org
 Cc: kvm...@lists.cs.columbia.edu; linux-arm-ker...@lists.infradead.org;
 kvm@vger.kernel.org
 Subject: RE: IRQFD support with GICv3 ITS (WAS: RE: [PATCH 00/13] arm64: 
 KVM: GICv3 ITS
 emulation)

  Hi!

 indeed in newly added qemu kvm-all.c kvm_arch_msi_data_to_gsi we could
 call a new ioctl that translates the data + deviceid? into an LPI and
 program irqfd with that LPI. This is done once when setting irqfd up.
 This also means extending irqfd support to lpi injection, gsi being the
 LPI index if gsi = 8192. in that case we continue using
 kvm_gsi_direct_mapping and gsi still is an IRQ index.

  This is exactly what i have done in my kernel + qemu. I have added a new 
 KVM capability
 and then in qemu i do this:
 --- cut ---
 if (kvm_gsi_kernel_mapping()) {
 struct kvm_msi msi;

 msi.address_lo = (uint32_t)msg.address;
 msi.address_hi = msg.address  32;
 msi.data = le32_to_cpu(msg.data);
 memset(msi.pad, 0, sizeof(msi.pad));

 if (dev) {
 msi.devid = (pci_bus_num(dev-bus)  8) | dev-devfn;
 msi.flags = KVM_MSI_VALID_DEVID;
 } else {
 msi.devid = 0;
 msi.flags = 0;
 }

 return kvm_vm_ioctl(s, KVM_TRANSLATE_MSI, msi);
 }
 --- cut ---
  KVM_TRANSLATE_MSI returns an LPI number. This seemed to be the simplest and 
 fastest
 thing
 to do.
  If someone is interested, i could prepare an RFC patch series for this, 
 which would
 apply
 on top of Andre's ITS implementation.

 Kind regards,
 Pavel Fedin
 Expert Engineer
 Samsung Electronics Research center Russia


 --
 To unsubscribe from this list: send the line unsubscribe kvm in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html
 
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 06/10] arm: simplify MMIO dispatching

2015-06-17 Thread Andre Przywara
Hi Marc,

On 06/17/2015 01:48 PM, Marc Zyngier wrote:
 On 17/06/15 12:21, Andre Przywara wrote:
 Currently we separate any incoming MMIO request into one of the ARM
 memory map regions and take care to spare the GIC.
 It turns out that this is unnecessary, as we only have one special
 region (the IO port area in the first 64 KByte). The MMIO rbtree
 takes care about unhandled MMIO ranges, so we can simply drop all the
 special range checking (except that for the IO range) in
 kvm_cpu__emulate_mmio().
 As the GIC is handled in the kernel, a GIC MMIO access should never
 reach userland (and we don't know what to do with it anyway).
 This lets us delete some more code and simplifies future extensions
 (like expanding the GIC regions).
 To be in line with the other architectures, move the now simpler
 code into a header file.

 Signed-off-by: Andre Przywara andre.przyw...@arm.com
 ---
  arm/include/arm-common/kvm-arch.h | 12 
  arm/include/arm-common/kvm-cpu-arch.h | 14 --
  arm/kvm-cpu.c | 16 
  3 files changed, 12 insertions(+), 30 deletions(-)

 diff --git a/arm/include/arm-common/kvm-arch.h 
 b/arm/include/arm-common/kvm-arch.h
 index 082131d..90d6733 100644
 --- a/arm/include/arm-common/kvm-arch.h
 +++ b/arm/include/arm-common/kvm-arch.h
 @@ -45,18 +45,6 @@ static inline bool arm_addr_in_ioport_region(u64 
 phys_addr)
  return phys_addr = KVM_IOPORT_AREA  phys_addr  limit;
  }
  
 -static inline bool arm_addr_in_virtio_mmio_region(u64 phys_addr)
 -{
 -u64 limit = KVM_VIRTIO_MMIO_AREA + ARM_VIRTIO_MMIO_SIZE;
 -return phys_addr = KVM_VIRTIO_MMIO_AREA  phys_addr  limit;
 -}
 -
 -static inline bool arm_addr_in_pci_region(u64 phys_addr)
 -{
 -u64 limit = KVM_PCI_CFG_AREA + ARM_PCI_CFG_SIZE + ARM_PCI_MMIO_SIZE;
 -return phys_addr = KVM_PCI_CFG_AREA  phys_addr  limit;
 -}
 -
  struct kvm_arch {
  /*
   * We may have to align the guest memory for virtio, so keep the
 diff --git a/arm/include/arm-common/kvm-cpu-arch.h 
 b/arm/include/arm-common/kvm-cpu-arch.h
 index 36c7872..329979a 100644
 --- a/arm/include/arm-common/kvm-cpu-arch.h
 +++ b/arm/include/arm-common/kvm-cpu-arch.h
 @@ -44,8 +44,18 @@ static inline bool kvm_cpu__emulate_io(struct kvm_cpu 
 *vcpu, u16 port, void *dat
  return false;
  }
  
 -bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data,
 -   u32 len, u8 is_write);
 +static inline bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 
 phys_addr,
 + u8 *data, u32 len, u8 is_write)
 +{
 +if (arm_addr_in_ioport_region(phys_addr)) {
 +int direction = is_write ? KVM_EXIT_IO_OUT : KVM_EXIT_IO_IN;
 +u16 port = (phys_addr - KVM_IOPORT_AREA)  USHRT_MAX;
 +
 +return kvm__emulate_io(vcpu, port, data, direction, len, 1);
 +}
 +
 +return kvm__emulate_mmio(vcpu, phys_addr, data, len, is_write);
 +}
  
  unsigned long kvm_cpu__get_vcpu_mpidr(struct kvm_cpu *vcpu);
  
 diff --git a/arm/kvm-cpu.c b/arm/kvm-cpu.c
 index ab08815..7780251 100644
 --- a/arm/kvm-cpu.c
 +++ b/arm/kvm-cpu.c
 @@ -139,22 +139,6 @@ bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu)
  return false;
  }
  
 -bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data,
 -   u32 len, u8 is_write)
 -{
 -if (arm_addr_in_virtio_mmio_region(phys_addr)) {
 -return kvm__emulate_mmio(vcpu, phys_addr, data, len, is_write);
 -} else if (arm_addr_in_ioport_region(phys_addr)) {
 -int direction = is_write ? KVM_EXIT_IO_OUT : KVM_EXIT_IO_IN;
 -u16 port = (phys_addr - KVM_IOPORT_AREA)  USHRT_MAX;
 -return kvm__emulate_io(vcpu, port, data, direction, len, 1);
 -} else if (arm_addr_in_pci_region(phys_addr)) {
 -return kvm__emulate_mmio(vcpu, phys_addr, data, len, is_write);
 -}
 
 Can you explain why this arm_addr_in_pci_region(phys_addr) check has
 disappeared in your updated version on this function? It may be a non
 issue, but I'd very much like to understand.

If you look above the calls to kvm__emulate_mmio() are exactly the same
for the PCI and the virtio_mmio region, also as the areas are
non-overlapping the if branches can be reordered.
arm_addr_in_virtio_mmio_region() is true between 64k and (1GB - GIC),
while arm_addr_in_pci_region() gives true between 1GB and 2GB.

So this translates into: do kvm__emulate_io() for anything below 64K and
kvm__emulate_mmio() for everything else except for the GIC area,
admittedly in a quite convoluted way.

So my patch just removes the check for the GIC region and rewrites it to
match that description in the last sentence, with the rationale given in
the commit message.
Does that make sense?
If you desperately want some extra barfing for misguided GIC requests,
I'd rather introduce that to the no match code path in
kvm__emulate_mmio or register some dummy MMIO regions for the GIC

Re: [PATCH v3 07/10] limit number of VCPUs on demand

2015-06-17 Thread Andre Przywara
On 06/17/2015 01:53 PM, Marc Zyngier wrote:
 On 17/06/15 12:21, Andre Przywara wrote:
 Currently the ARM GIC checks the number of VCPUs against a fixed
 limit, which is GICv2 specific. Don't pretend we know better than the
 kernel and let's get rid of that explicit check.
 Instead be more relaxed about KVM_CREATE_VCPU failing with EINVAL,
 which is the way the kernel communicates having reached a VCPU limit.
 If we see this and have at least brought up one VCPU already
 successfully, then don't panic, but limit the number of VCPUs instead.

 Signed-off-by: Andre Przywara andre.przyw...@arm.com

...

 diff --git a/arm/kvm-cpu.c b/arm/kvm-cpu.c
 index 7780251..c1cf51d 100644
 --- a/arm/kvm-cpu.c
 +++ b/arm/kvm-cpu.c
 @@ -47,12 +47,19 @@ struct kvm_cpu *kvm_cpu__arch_init(struct kvm *kvm, 
 unsigned long cpu_id)
  };
  
  vcpu = calloc(1, sizeof(struct kvm_cpu));
 -if (!vcpu)
 +if (!vcpu) {
 +errno = ENOMEM;
  return NULL;
 +}
 
 Isn't errno already set when calloc fails?

Ah yes, that seems to be true at least for glibc or UNIX 98, according
to the manpage. I was misguided by the fact that calloc is not a
syscall. So I can drop this hunk.

Thanks,
Andre.
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] kvmtool: don't use PCI config space IRQ line field

2015-06-15 Thread Andre Przywara
On 06/05/2015 05:41 PM, Will Deacon wrote:
 On Thu, Jun 04, 2015 at 04:20:45PM +0100, Andre Przywara wrote:

Hi Will,

sorry, almost forgot about this email...

 In PCI config space there is an interrupt line field (offset 0x3f),
 which is used to initially communicate the IRQ line number from
 firmware to the OS. _Hardware_ should never use this information,
 as the OS is free to write any information in there.
 But kvmtool uses this number when it triggers IRQs in the guest,
 which fails starting with Linux 3.19-rc1, where the PCI layer starts
 writing the virtual IRQ number in there.

 Fix that by storing the IRQ number in a separate field in
 struct virtio_pci, which is independent from the PCI config space
 and cannot be influenced by the guest.
 This fixes ARM/ARM64 guests using PCI with newer kernels.

 Signed-off-by: Andre Przywara andre.przyw...@arm.com
 ---
  include/kvm/virtio-pci.h | 8 
  virtio/pci.c | 9 ++---
  2 files changed, 14 insertions(+), 3 deletions(-)

 diff --git a/include/kvm/virtio-pci.h b/include/kvm/virtio-pci.h
 index c795ce7..b70cadd 100644
 --- a/include/kvm/virtio-pci.h
 +++ b/include/kvm/virtio-pci.h
 @@ -30,6 +30,14 @@ struct virtio_pci {
  u8  isr;
  u32 features;
  
 +/*
 + * We cannot rely on the INTERRUPT_LINE byte in the config space once
 + * we have run guest code, as the OS is allowed to use that field
 + * as a scratch pad to communicate between driver and PCI layer.
 + * So store our legacy interrupt line number in here for internal use.
 + */
 +u8  legacy_irq_line;
 +
  /* MSI-X */
  u16 config_vector;
  u32 config_gsi;
 diff --git a/virtio/pci.c b/virtio/pci.c
 index 7556239..e17e5a9 100644
 --- a/virtio/pci.c
 +++ b/virtio/pci.c
 @@ -141,7 +141,7 @@ static bool virtio_pci__io_in(struct ioport *ioport, 
 struct kvm_cpu *vcpu, u16 p
  break;
  case VIRTIO_PCI_ISR:
  ioport__write8(data, vpci-isr);
 -kvm__irq_line(kvm, vpci-pci_hdr.irq_line, VIRTIO_IRQ_LOW);
 +kvm__irq_line(kvm, vpci-legacy_irq_line, VIRTIO_IRQ_LOW);
  vpci-isr = VIRTIO_IRQ_LOW;
  break;
  default:
 @@ -299,7 +299,7 @@ int virtio_pci__signal_vq(struct kvm *kvm, struct 
 virtio_device *vdev, u32 vq)
  kvm__irq_trigger(kvm, vpci-gsis[vq]);
  } else {
  vpci-isr = VIRTIO_IRQ_HIGH;
 -kvm__irq_trigger(kvm, vpci-pci_hdr.irq_line);
 +kvm__irq_trigger(kvm, vpci-legacy_irq_line);
  }
  return 0;
  }
 @@ -323,7 +323,7 @@ int virtio_pci__signal_config(struct kvm *kvm, struct 
 virtio_device *vdev)
  kvm__irq_trigger(kvm, vpci-config_gsi);
  } else {
  vpci-isr = VIRTIO_PCI_ISR_CONFIG;
 -kvm__irq_trigger(kvm, vpci-pci_hdr.irq_line);
 +kvm__irq_trigger(kvm, vpci-legacy_irq_line);
  }
  
  return 0;
 @@ -422,6 +422,9 @@ int virtio_pci__init(struct kvm *kvm, void *dev, struct 
 virtio_device *vdev,
  if (r  0)
  goto free_msix_mmio;
  
 +/* save the IRQ that device__register() has allocated */
 +vpci-legacy_irq_line = vpci-pci_hdr.irq_line;
 
 I'd rather we used the container_of trick that we do for virtio-mmio
 devices when assigning the irq in device__register. Then we can avoid
 this line completely.

Not completely sure I get what you mean, I take it you want to assign
legacy_irq_line in pci__assign_irq() directly (where the IRQ number is
allocated).
But this function is PCI generic code and is used by the VESA
framebuffer and the shmem device on x86 as well. For those devices
dev_hdr is not part of a struct virtio_pci, so we can't do container_of
to assign the legacy_irq_line here directly.
Admittedly this fix should apply to the other two users as well, but
VESA does not use interrupts and pci-shmem is completely broken anyway,
so I didn't bother to fix it in this regard.
Would it be justified to provide an IRQ number field in struct
device_header to address all users?

Or what am I missing here?

Cheers,
Andre
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 6/8] arm: prepare for instantiating different IRQ chip devices

2015-06-15 Thread Andre Przywara
Hi Marc,

On 06/10/2015 06:21 PM, Marc Zyngier wrote:
 On 05/06/15 09:37, Andre Przywara wrote:
 Extend the vGIC handling code to potentially deal with different IRQ
 chip devices instead of hard-coding the GICv2 in.
 We extend most vGIC functions to take a type parameter, but still put
 GICv2 in at the top for the time being.

 Signed-off-by: Andre Przywara andre.przyw...@arm.com
...
 @@ -26,21 +26,37 @@ static int gic__create_device(struct kvm *kvm)
  };
  struct kvm_device_attr dist_attr = {
  .group  = KVM_DEV_ARM_VGIC_GRP_ADDR,
 -.attr   = KVM_VGIC_V2_ADDR_TYPE_DIST,
  .addr   = (u64)(unsigned long)dist_addr,
  };
  
 +switch (type) {
 +case IRQCHIP_GICV2:
 +gic_device.type = KVM_DEV_TYPE_ARM_VGIC_V2;
 +break;
 +default:
 +return -ENODEV;
 +}
 +
  err = ioctl(kvm-vm_fd, KVM_CREATE_DEVICE, gic_device);
  if (err)
  return err;
  
  gic_fd = gic_device.fd;
  
 -err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, cpu_if_attr);
 +switch (type) {
 +case IRQCHIP_GICV2:
 +dist_attr.attr = KVM_VGIC_V2_ADDR_TYPE_DIST;
 
 You could move the structure patching in the first switch statement.
 
 +err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, cpu_if_attr);
 +break;
 +default:
 +return -ENODEV;
 
 This default cannot be reached, as you've already caught the weird stuff
 above.

Tell that the compiler, not me ;-)
Will check if dropping IRQCHIP_DEFAULT will appease the compiler.



 @@ -131,15 +156,26 @@ static int gic__init_gic(struct kvm *kvm)
  }
  late_init(gic__init_gic)
  
 -void gic__generate_fdt_nodes(void *fdt, u32 phandle)
 +void gic__generate_fdt_nodes(void *fdt, u32 phandle, enum irqchip_type type)
  {
 +const char *compatible;
  u64 reg_prop[] = {
 -cpu_to_fdt64(ARM_GIC_DIST_BASE), 
 cpu_to_fdt64(ARM_GIC_DIST_SIZE),
 -cpu_to_fdt64(ARM_GIC_CPUI_BASE), 
 cpu_to_fdt64(ARM_GIC_CPUI_SIZE),
 +cpu_to_fdt64(ARM_GIC_DIST_BASE),
 +cpu_to_fdt64(ARM_GIC_DIST_SIZE),
 +cpu_to_fdt64(ARM_GIC_CPUI_BASE),
 +cpu_to_fdt64(ARM_GIC_CPUI_SIZE),
  };
 
 Any particular reason for this change? I found the original more readable...

80 characters. I will revert this.

Fixed the rest.

Thanks!
Andre.
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 7/8] arm: add support for supplying GICv3 redistributor addresses

2015-06-15 Thread Andre Przywara
On 06/10/2015 06:40 PM, Marc Zyngier wrote:
 On 05/06/15 09:37, Andre Przywara wrote:
 The code currently is assuming fixed sized memory regions for the
 distributor and CPU interface. GICv3 needs a dynamic allocation of
 its redistributor region, since its size depends on the number of
 vCPUs.
 Also add the necessary code to create a GICv3 IRQ chip instance.
 This contains some defines which are not (yet) in the (32 bit) header
 files to allow compilation for ARM.

 Signed-off-by: Andre Przywara andre.przyw...@arm.com
 ---
  arm/gic.c | 37 +++--
  arm/include/arm-common/gic.h  |  2 +-
  arm/include/arm-common/kvm-arch.h | 18 ++
  arm/kvm-cpu.c |  4 +++-
  4 files changed, 53 insertions(+), 8 deletions(-)

 diff --git a/arm/gic.c b/arm/gic.c
 index 0ce40e4..c50d662 100644
 --- a/arm/gic.c
 +++ b/arm/gic.c
 @@ -9,13 +9,24 @@
  #include linux/kernel.h
  #include linux/kvm.h
  
 +/* Those names are not defined for ARM (yet) */
 +#ifndef KVM_VGIC_V3_ADDR_TYPE_DIST
 +#define KVM_VGIC_V3_ADDR_TYPE_DIST 2
 +#endif
 +
 +#ifndef KVM_VGIC_V3_ADDR_TYPE_REDIST
 +#define KVM_VGIC_V3_ADDR_TYPE_REDIST 3
 +#endif
 +
  static int gic_fd = -1;
 +static int nr_redists;
 
 Who sets this variable?
  
  static int gic__create_device(struct kvm *kvm, enum irqchip_type type)
  {
  int err;
  u64 cpu_if_addr = ARM_GIC_CPUI_BASE;
  u64 dist_addr = ARM_GIC_DIST_BASE;
 +u64 redist_addr = dist_addr - nr_redists * ARM_GIC_REDIST_SIZE;
 
 You are doing a similar offsetting further down. Consider having a macro
 that computes the redist base from the dist base.
 
  struct kvm_create_device gic_device = {
  .flags  = 0,
  };
 @@ -28,11 +39,19 @@ static int gic__create_device(struct kvm *kvm, enum 
 irqchip_type type)
  .group  = KVM_DEV_ARM_VGIC_GRP_ADDR,
  .addr   = (u64)(unsigned long)dist_addr,
  };
 +struct kvm_device_attr redist_attr = {
 +.group  = KVM_DEV_ARM_VGIC_GRP_ADDR,
 +.attr   = KVM_VGIC_V3_ADDR_TYPE_REDIST,
 +.addr   = (u64)(unsigned long)redist_addr,
 +};
  
  switch (type) {
  case IRQCHIP_GICV2:
  gic_device.type = KVM_DEV_TYPE_ARM_VGIC_V2;
  break;
 +case IRQCHIP_GICV3:
 +gic_device.type = KVM_DEV_TYPE_ARM_VGIC_V3;
 +break;
  default:
  return -ENODEV;
  }
 @@ -48,6 +67,10 @@ static int gic__create_device(struct kvm *kvm, enum 
 irqchip_type type)
  dist_attr.attr = KVM_VGIC_V2_ADDR_TYPE_DIST;
  err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, cpu_if_attr);
  break;
 +case IRQCHIP_GICV3:
 +dist_attr.attr = KVM_VGIC_V3_ADDR_TYPE_DIST;
 +err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, redist_attr);
 +break;
  default:
  return -ENODEV;
  }
 @@ -55,6 +78,8 @@ static int gic__create_device(struct kvm *kvm, enum 
 irqchip_type type)
  return err;
  
  err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, dist_attr);
 +if (err)
 +return err;
 
 Looks like a fairly useless statement...

Sorry, rebasing artefact, this gets amended in the next patch. I have
fixed it now in here.

  
  return err;
  }
 @@ -162,17 +187,25 @@ void gic__generate_fdt_nodes(void *fdt, u32 phandle, 
 enum irqchip_type type)
  u64 reg_prop[] = {
  cpu_to_fdt64(ARM_GIC_DIST_BASE),
  cpu_to_fdt64(ARM_GIC_DIST_SIZE),
 -cpu_to_fdt64(ARM_GIC_CPUI_BASE),
 -cpu_to_fdt64(ARM_GIC_CPUI_SIZE),
 +0, 0,   /* to be filled */
  };
  
  switch (type) {
  case IRQCHIP_GICV2:
  compatible = arm,cortex-a15-gic;
 +reg_prop[2] = ARM_GIC_CPUI_BASE;
 +reg_prop[3] = ARM_GIC_CPUI_SIZE;
 +break;
 +case IRQCHIP_GICV3:
 +compatible = arm,gic-v3;
 +reg_prop[2] = ARM_GIC_DIST_BASE - nr_redists * 
 ARM_GIC_REDIST_SIZE;
 +reg_prop[3] = ARM_GIC_REDIST_SIZE * nr_redists;
  break;
  default:
  return;
  }
 +reg_prop[2] = cpu_to_fdt64(reg_prop[2]);
 +reg_prop[3] = cpu_to_fdt64(reg_prop[3]);
 
 I'd find it more readable if you did the cpu_to_fdt64() as part of the
 initial assignment.

Agreed, that looks much nicer now that I use a separate variable for the
GIC redist base address (instead of nr_redist).

  
  _FDT(fdt_begin_node(fdt, intc));
  _FDT(fdt_property_string(fdt, compatible, compatible));
 diff --git a/arm/include/arm-common/gic.h b/arm/include/arm-common/gic.h
 index f5f6707..8d6ab01 100644
 --- a/arm/include/arm-common/gic.h
 +++ b/arm/include/arm-common/gic.h
 @@ -21,7 +21,7 @@
  #define GIC_MAX_CPUS8
  #define GIC_MAX_IRQ 255
  
 -enum irqchip_type {IRQCHIP_DEFAULT, IRQCHIP_GICV2};
 +enum irqchip_type {IRQCHIP_DEFAULT

Re: [PATCH 05/13] KVM: arm64: handle ITS related GICv3 redistributor registers

2015-06-12 Thread Andre Przywara
Hi Eric,

On 06/09/2015 09:52 AM, Eric Auger wrote:
 On 05/29/2015 11:53 AM, Andre Przywara wrote:
 In the GICv3 redistributor there are the PENDBASER and PROPBASER
 registers which we did not emulate so far, as they only make sense
 when having an ITS. In preparation for that emulate those MMIO
 accesses by storing the 64-bit data written into it into a variable
 which we later read in the ITS emulation.

 Signed-off-by: Andre Przywara andre.przyw...@arm.com
 ---
  include/kvm/arm_vgic.h  |  4 
  virt/kvm/arm/vgic-v3-emul.c | 43 +++
  virt/kvm/arm/vgic.c | 35 +++
  virt/kvm/arm/vgic.h |  4 
  4 files changed, 86 insertions(+)

 diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
 index 37725bb..9ea0b3b 100644
 --- a/include/kvm/arm_vgic.h
 +++ b/include/kvm/arm_vgic.h
 @@ -256,6 +256,10 @@ struct vgic_dist {
  struct vgic_vm_ops  vm_ops;
  struct vgic_io_device   dist_iodev;
  struct vgic_io_device   *redist_iodevs;
 +
 add some comments?
 /* LPI config table shared by all distributors */
 +u64 propbaser;
 /* LPI pending table per distributors */
 +u64 *pendbaser;
 +boollpis_enabled;
  };
  
  struct vgic_v2_cpu_if {
 diff --git a/virt/kvm/arm/vgic-v3-emul.c b/virt/kvm/arm/vgic-v3-emul.c
 index 16c6d8a..04f3aed 100644
 --- a/virt/kvm/arm/vgic-v3-emul.c
 +++ b/virt/kvm/arm/vgic-v3-emul.c
 @@ -607,6 +607,37 @@ static bool handle_mmio_cfg_reg_redist(struct kvm_vcpu 
 *vcpu,
  return vgic_handle_cfg_reg(reg, mmio, offset);
  }
  
 +/* We don't trigger any actions here, just store the register value */
 +static bool handle_mmio_propbaser_redist(struct kvm_vcpu *vcpu,
 + struct kvm_exit_mmio *mmio,
 + phys_addr_t offset)
 +{
 +struct vgic_dist *dist = vcpu-kvm-arch.vgic;
 +int mode = ACCESS_READ_VALUE;
 +
 you may add the same comment as below?
 +mode |= dist-lpis_enabled ? ACCESS_WRITE_IGNORED : ACCESS_WRITE_VALUE;
 +vgic_handle_base_register(vcpu, mmio, offset, dist-propbaser, mode);
 having the PROPBASER programmed to different values on different redist
 with EnableLPIs==1 also is unpredictable. Do we plan to check that
 somewhere? Allow a single write?

Well, we are safe if the spec says it's unpredictable, aren't we?
I refrained from checking too many corner cases (same for the ITS
commands, btw), since we lack a good way of communicating errors.
SErrors into a guest do not work AFAIK, and spamming dmesg with
guest-triggerable messages is also bad.
After all this is an emulator, not a validator. So as long as this
doesn't affect the host and violates the spec, I think we get away with
ignoring stupid requests from the guest.
I am happy to revisit this shall the need arise.

 +
 +return false;
 +}
 +
 +/* We don't trigger any actions here, just store the register value */
 +static bool handle_mmio_pendbaser_redist(struct kvm_vcpu *vcpu,
 + struct kvm_exit_mmio *mmio,
 + phys_addr_t offset)
 +{
 +struct kvm_vcpu *rdvcpu = mmio-private;
 +struct vgic_dist *dist = vcpu-kvm-arch.vgic;
 +int mode = ACCESS_READ_VALUE;
 +
 +/* Storing a value with LPIs already enabled is undefined */
 +mode |= dist-lpis_enabled ? ACCESS_WRITE_IGNORED : ACCESS_WRITE_VALUE;
 +vgic_handle_base_register(vcpu, mmio, offset,
 +  dist-pendbaser[rdvcpu-vcpu_id], mode);
 pendbaser is not yet allocated. Wouldn't it make sense to introduce that
 patch later on?

I am quite glad having found a patch order which compiles ;-)
But well, I guess we have to address this as this strictly isn't safe if
pendbaser is NULL (though it works with how GCC compiles this).

Thanks for looking!

Cheers,
Andre.

 Eric
 +
 +return false;
 +}
 +
  #define SGI_base(x) ((x) + SZ_64K)
  
  static const struct vgic_io_range vgic_redist_ranges[] = {
 @@ -635,6 +666,18 @@ static const struct vgic_io_range vgic_redist_ranges[] 
 = {
  .handle_mmio= handle_mmio_raz_wi,
  },
  {
 +.base   = GICR_PENDBASER,
 +.len= 0x08,
 +.bits_per_irq   = 0,
 +.handle_mmio= handle_mmio_pendbaser_redist,
 +},
 +{
 +.base   = GICR_PROPBASER,
 +.len= 0x08,
 +.bits_per_irq   = 0,
 +.handle_mmio= handle_mmio_propbaser_redist,
 +},
 +{
  .base   = GICR_IDREGS,
  .len= 0x30,
  .bits_per_irq   = 0,
 diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
 index 2e9723aa..0a9236d 100644
 --- a/virt/kvm/arm/vgic.c
 +++ b/virt/kvm/arm/vgic.c
 @@ -448,6 +448,41 @@ void vgic_reg_access(struct kvm_exit_mmio *mmio, u32 
 *reg

Re: [PATCH 07/10] KVM: arm/arm64: vgic: Allow HW interrupts to be queued to a guest

2015-06-11 Thread Andre Przywara
On 06/11/2015 10:15 AM, Marc Zyngier wrote:
 On 11/06/15 09:44, Andre Przywara wrote:
 On 06/08/2015 06:04 PM, Marc Zyngier wrote:
...
 @@ -1344,6 +1364,35 @@ static bool vgic_process_maintenance(struct kvm_vcpu 
 *vcpu)
 return level_pending;
  }
  
 +/* Return 1 if HW interrupt went from active to inactive, and 0 otherwise 
 */
 +static int vgic_sync_hwirq(struct kvm_vcpu *vcpu, struct vgic_lr vlr)
 +{
 +   struct irq_phys_map *map;
 +   int ret;
 +
 +   if (!(vlr.state  LR_HW))
 +   return 0;
 +
 +   map = vgic_irq_map_search(vcpu, vlr.irq);

 I wonder if it's safe to rely on that mapping here. Are we sure that
 this hasn't changed while the VCPU was running? If I got this correctly,
 currently only vcpu_reset will actually add a map entry, but I guess in
 the future there will be more users.
 
 How can the guest interrupt change? This is HW, as far as the guest is
 concerned. An actual interrupt line. We don't reconfigure the HW live.

I was thinking about the rbtree mapping we introduced. There we map a
guest interrupt to a hardware interrupt. Are we sure that no one tears
down that mapping while we have an LR populated with this pair?
I am not talking about the timer here, but more about future users.

 Also we rely on the irqdomain mapping to be still the same, but that is
 probably a safe assumption.
 
 Like I said before, this *cannot* change.

OK, got it.

 
 But I'd still find it more natural to use the hwirq number from the LR
 at this point. Can't we use irq_find_mapping() here to learn Linux'
 (current) irq number from that?
 
 I think you're confused.
 
 - The guest irq (vlr.irq) is entirely made up, and has no connection
 with reality. it is stable, and cannot change during the lifetime of the
 guest (think of it as a HW irq line).
 
 - The host hwirq (vlr.hwirq) is stable as well, for the same reason.
 
 - The Linux IRQ cannot change because we've been given it by the kernel,
 and that's what we use for *everything* as far as the kernel is
 concerned. Its mapping to hwirq is stable as well because this is how we
 talk to the HW.

Not disputing any of them, but:

 - irq_find_mapping gives you the *reverse* mapping (from hwirq to Linux
 irq), and for that to work, you need the domain on which you want to
 apply the translation. This is only useful when actually taking the
 interrupt (i.e. in an interrupt controller driver). I can't see how that
 could make sense here.

So if the guest has acked/EOIed it's IRQ, the GIC at the same time
acked/EOIed the hardware IRQ it found in the LR. Now we assume that this
is the very same as the HW IRQ we found doing our rbtree traversal.
I just wanted to be sure that this is always true and that this mapping
didn't change while the VCPU was running.
If you are sure of this, fine, I was just concerned that someone breaks
this assumption in the future by more dynamically mapping/unmapping
entries (say some irq forwarding user) and we will not notice.

Cheers,
Andre.

 
 The purpose of this mapping is to, given the guest irq (because that's
 what we inject), what the other values are:
 - hwirq: to provide GICH with the interrupt to deactivate
 - Linux irq: to control the active state through the irqchip state API.
 
 Or am I too paranoid here?
 
 Hope it makes more sense to you now.
 
 Thanks,
 
   M.
 
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 06/10] KVM: arm/arm64: vgic: Allow dynamic mapping of physical/virtual interrupts

2015-06-11 Thread Andre Przywara
Hi,

On 06/08/2015 06:04 PM, Marc Zyngier wrote:
 In order to be able to feed physical interrupts to a guest, we need
 to be able to establish the virtual-physical mapping between the two
 worlds.

 The mapping is kept in a rbtree, indexed by virtual interrupts.

 Signed-off-by: Marc Zyngier marc.zyng...@arm.com
 ---
  include/kvm/arm_vgic.h |  18 
  virt/kvm/arm/vgic.c| 110 
 +
  2 files changed, 128 insertions(+)

 diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
 index 4f9fa1d..33d121a 100644
 --- a/include/kvm/arm_vgic.h
 +++ b/include/kvm/arm_vgic.h
 @@ -159,6 +159,14 @@ struct vgic_io_device {
   struct kvm_io_device dev;
  };

 +struct irq_phys_map {
 + struct rb_node  node;
 + u32 virt_irq;
 + u32 phys_irq;
 + u32 irq;

Can you add comments explaining the different IRQ types here?
So I take it that phys_irq is the actual SPI number (hwirq in irqchip
lingo), virt_irq is the guest's virtual IRQ number and irq is Linux'
notion of the IRQ number (the first column in /proc/interrupts)?
Would renaming help? (phys_irq to hwirq? virt_irq to guest_irq?)

 + boolactive;
 +};
 +
  struct vgic_dist {
   spinlock_t  lock;
   boolin_kernel;
 @@ -256,6 +264,10 @@ struct vgic_dist {
   struct vgic_vm_ops  vm_ops;
   struct vgic_io_device   dist_iodev;
   struct vgic_io_device   *redist_iodevs;
 +
 + /* Virtual irq to hwirq mapping */
 + spinlock_t  irq_phys_map_lock;
 + struct rb_root  irq_phys_map;
  };

  struct vgic_v2_cpu_if {
 @@ -307,6 +319,9 @@ struct vgic_cpu {
   struct vgic_v2_cpu_if   vgic_v2;
   struct vgic_v3_cpu_if   vgic_v3;
   };
 +
 + /* Protected by the distributor's irq_phys_map_lock */
 + struct rb_root  irq_phys_map;
  };

  #define LR_EMPTY 0xff
 @@ -331,6 +346,9 @@ int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, 
 unsigned int irq_num,
  void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
  int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
  int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
 +struct irq_phys_map *vgic_map_phys_irq(struct kvm_vcpu *vcpu,
 +int virt_irq, int irq);
 +int vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, struct irq_phys_map *map);

  #define irqchip_in_kernel(k) (!!((k)-arch.vgic.in_kernel))
  #define vgic_initialized(k)  (!!((k)-arch.vgic.nr_cpus))
 diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
 index 59ed7a3..c6604f2 100644
 --- a/virt/kvm/arm/vgic.c
 +++ b/virt/kvm/arm/vgic.c
 @@ -24,6 +24,7 @@
  #include linux/of.h
  #include linux/of_address.h
  #include linux/of_irq.h
 +#include linux/rbtree.h
  #include linux/uaccess.h

  #include linux/irqchip/arm-gic.h
 @@ -84,6 +85,8 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu 
 *vcpu);
  static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu);
  static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr);
  static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr, struct vgic_lr 
 lr_desc);
 +static struct irq_phys_map *vgic_irq_map_search(struct kvm_vcpu *vcpu,
 + int virt_irq);

  static const struct vgic_ops *vgic_ops;
  static const struct vgic_params *vgic;
 @@ -1585,6 +1588,112 @@ static irqreturn_t vgic_maintenance_handler(int irq, 
 void *data)
   return IRQ_HANDLED;
  }

 +static struct rb_root *vgic_get_irq_phys_map(struct kvm_vcpu *vcpu,
 +  int virt_irq)
 +{
 + if (virt_irq  VGIC_NR_PRIVATE_IRQS)
 + return vcpu-arch.vgic_cpu.irq_phys_map;
 + else
 + return vcpu-kvm-arch.vgic.irq_phys_map;
 +}
 +
 +struct irq_phys_map *vgic_map_phys_irq(struct kvm_vcpu *vcpu,
 +int virt_irq, int irq)
 +{
 + struct vgic_dist *dist = vcpu-kvm-arch.vgic;
 + struct rb_root *root = vgic_get_irq_phys_map(vcpu, virt_irq);
 + struct rb_node **new = root-rb_node, *parent = NULL;
 + struct irq_phys_map *new_map;
 + struct irq_desc *desc;
 + struct irq_data *data;
 + int phys_irq;
 +
 + desc = irq_to_desc(irq);
 + if (!desc) {
 + kvm_err(kvm_arch_timer: can't obtain interrupt descriptor\n);

I guess kvm_arch_timer: is a left-over of the original user?

 + return NULL;
 + }
 +
 + data = irq_desc_get_irq_data(desc);
 + while (data-parent_data)
 + data = data-parent_data;
 +
 + phys_irq = data-hwirq;

So if I get this correctly we cache hwirq/phys_irq in this map to get
a cheaper access to it, but actually it is redundant since we have
Linux' irq number, isn't it?
Are we sure that the irqdomain mapping of irq and phys_irq never will
change while this map entry is valid? This is probably true for the

Re: [PATCH 07/10] KVM: arm/arm64: vgic: Allow HW interrupts to be queued to a guest

2015-06-11 Thread Andre Przywara
Hi Marc,

On 06/08/2015 06:04 PM, Marc Zyngier wrote:
 To allow a HW interrupt to be injected into a guest, we lookup the
 guest virtual interrupt in the irq_phys_map rbtree, and if we have
 a match, encode both interrupts in the LR.
 
 We also mark the interrupt as active at the host distributor level.
 
 On guest EOI on the virtual interrupt, the host interrupt will be
 deactivated.
 
 Signed-off-by: Marc Zyngier marc.zyng...@arm.com
 ---
  virt/kvm/arm/vgic.c | 71 
 ++---
  1 file changed, 68 insertions(+), 3 deletions(-)
 
 diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
 index c6604f2..495ac7d 100644
 --- a/virt/kvm/arm/vgic.c
 +++ b/virt/kvm/arm/vgic.c
 @@ -1120,6 +1120,26 @@ static void vgic_queue_irq_to_lr(struct kvm_vcpu 
 *vcpu, int irq,
   if (!vgic_irq_is_edge(vcpu, irq))
   vlr.state |= LR_EOI_INT;
  
 + if (vlr.irq = VGIC_NR_SGIS) {
 + struct irq_phys_map *map;
 + map = vgic_irq_map_search(vcpu, irq);
 +
 + if (map) {
 + int ret;
 +
 + BUG_ON(!map-active);
 + vlr.hwirq = map-phys_irq;
 + vlr.state |= LR_HW;
 + vlr.state = ~LR_EOI_INT;
 +
 + ret = irq_set_irqchip_state(map-irq,
 + IRQCHIP_STATE_ACTIVE,
 + true);
 + vgic_irq_set_queued(vcpu, irq);
 + WARN_ON(ret);
 + }
 + }
 +
   vgic_set_lr(vcpu, lr_nr, vlr);
   vgic_sync_lr_elrsr(vcpu, lr_nr, vlr);
  }
 @@ -1344,6 +1364,35 @@ static bool vgic_process_maintenance(struct kvm_vcpu 
 *vcpu)
   return level_pending;
  }
  
 +/* Return 1 if HW interrupt went from active to inactive, and 0 otherwise */
 +static int vgic_sync_hwirq(struct kvm_vcpu *vcpu, struct vgic_lr vlr)
 +{
 + struct irq_phys_map *map;
 + int ret;
 +
 + if (!(vlr.state  LR_HW))
 + return 0;
 +
 + map = vgic_irq_map_search(vcpu, vlr.irq);

I wonder if it's safe to rely on that mapping here. Are we sure that
this hasn't changed while the VCPU was running? If I got this correctly,
currently only vcpu_reset will actually add a map entry, but I guess in
the future there will be more users.
Also we rely on the irqdomain mapping to be still the same, but that is
probably a safe assumption.

But I'd still find it more natural to use the hwirq number from the LR
at this point. Can't we use irq_find_mapping() here to learn Linux'
(current) irq number from that?

Or am I too paranoid here?

Cheers,
Andre.

 + BUG_ON(!map || !map-active);
 +
 + ret = irq_get_irqchip_state(map-irq,
 + IRQCHIP_STATE_ACTIVE,
 + map-active);
 +
 + WARN_ON(ret);
 +
 + if (map-active) {
 + ret = irq_set_irqchip_state(map-irq,
 + IRQCHIP_STATE_ACTIVE,
 + false);
 + WARN_ON(ret);
 + return 0;
 + }
 +
 + return 1;
 +}
 +
  /* Sync back the VGIC state after a guest run */
  static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
  {
 @@ -1358,14 +1407,30 @@ static void __kvm_vgic_sync_hwstate(struct kvm_vcpu 
 *vcpu)
   elrsr = vgic_get_elrsr(vcpu);
   elrsr_ptr = u64_to_bitmask(elrsr);
  
 - /* Clear mappings for empty LRs */
 - for_each_set_bit(lr, elrsr_ptr, vgic-nr_lr) {
 + /* Deal with HW interrupts, and clear mappings for empty LRs */
 + for (lr = 0; lr  vgic-nr_lr; lr++) {
   struct vgic_lr vlr;
  
 - if (!test_and_clear_bit(lr, vgic_cpu-lr_used))
 + if (!test_bit(lr, vgic_cpu-lr_used))
   continue;
  
   vlr = vgic_get_lr(vcpu, lr);
 + if (vgic_sync_hwirq(vcpu, vlr)) {
 + /*
 +  * So this is a HW interrupt that the guest
 +  * EOI-ed. Clean the LR state and allow the
 +  * interrupt to be queued again.
 +  */
 + vlr.state = ~LR_HW;
 + vlr.hwirq = 0;
 + vgic_set_lr(vcpu, lr, vlr);
 + vgic_irq_clear_queued(vcpu, vlr.irq);
 + }
 +
 + if (!test_bit(lr, elrsr_ptr))
 + continue;
 +
 + clear_bit(lr, vgic_cpu-lr_used);
  
   BUG_ON(vlr.irq = dist-nr_irqs);
   vgic_cpu-vgic_irq_lr_map[vlr.irq] = LR_EMPTY;
 
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 04/13] KVM: arm64: Introduce new MMIO region for the ITS base address

2015-06-11 Thread Andre Przywara
Hi Eric,

thanks for the review!

On 06/09/2015 09:52 AM, Eric Auger wrote:
 On 05/29/2015 11:53 AM, Andre Przywara wrote:
 The ARM GICv3 ITS controller requires a separate register frame to
 cover ITS specific registers. Add a new VGIC address type and store
 the address in a field in the vgic_dist structure.
 Provide a function to check whether userland has provided the address,
 so ITS functionality can be guarded by that check.

 Signed-off-by: Andre Przywara andre.przyw...@arm.com
 ---
  Documentation/virtual/kvm/devices/arm-vgic.txt |  7 +++
  arch/arm64/include/uapi/asm/kvm.h  |  3 +++
  include/kvm/arm_vgic.h |  3 +++
  virt/kvm/arm/vgic-v3-emul.c|  1 +
  virt/kvm/arm/vgic.c| 17 +
  virt/kvm/arm/vgic.h|  1 +
  6 files changed, 32 insertions(+)

 diff --git a/Documentation/virtual/kvm/devices/arm-vgic.txt 
 b/Documentation/virtual/kvm/devices/arm-vgic.txt
 index 3fb9054..1f89001 100644
 --- a/Documentation/virtual/kvm/devices/arm-vgic.txt
 +++ b/Documentation/virtual/kvm/devices/arm-vgic.txt
 @@ -39,6 +39,13 @@ Groups:
Only valid for KVM_DEV_TYPE_ARM_VGIC_V3.
This address needs to be 64K aligned.
  
 +KVM_VGIC_V3_ADDR_TYPE_ITS (rw, 64-bit)
 +  Base address in the guest physical address space of the GICv3 ITS
 +  register frame. The ITS allows MSI(-X) interrupts to be injected
 +  into guests. This extension is optional, if the kernel does not
 +  support the ITS, the call returns -ENODEV.
 +  Only valid for KVM_DEV_TYPE_ARM_VGIC_V3.
 +  This address needs to be 64K aligned and the region covers 64 KByte.
 I would emphasize this is the control registers (ITS_Base) hence a
 single page, not comprising the ITS translation register page.

Good point, will do.

  
KVM_DEV_ARM_VGIC_GRP_DIST_REGS
Attributes:
 diff --git a/arch/arm64/include/uapi/asm/kvm.h 
 b/arch/arm64/include/uapi/asm/kvm.h
 index d268320..e42435c 100644
 --- a/arch/arm64/include/uapi/asm/kvm.h
 +++ b/arch/arm64/include/uapi/asm/kvm.h
 @@ -82,8 +82,11 @@ struct kvm_regs {
  #define KVM_VGIC_V3_ADDR_TYPE_DIST  2
  #define KVM_VGIC_V3_ADDR_TYPE_REDIST3
  
 extra white line?
 +#define KVM_VGIC_V3_ADDR_TYPE_ITS   4
 +
  #define KVM_VGIC_V3_DIST_SIZE   SZ_64K
  #define KVM_VGIC_V3_REDIST_SIZE (2 * SZ_64K)
 +#define KVM_VGIC_V3_ITS_SIZESZ_64K
  
  #define KVM_ARM_VCPU_POWER_OFF  0 /* CPU is started in OFF 
 state */
  #define KVM_ARM_VCPU_EL1_32BIT  1 /* CPU running a 32bit VM */
 diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
 index b18e2c5..37725bb 100644
 --- a/include/kvm/arm_vgic.h
 +++ b/include/kvm/arm_vgic.h
 @@ -178,6 +178,9 @@ struct vgic_dist {
  phys_addr_t vgic_redist_base;
  };
  
 +/* The base address for the MSI control block (V2M/ITS) */
 why V2M here? It's it the GITS_TRANSLATER page that has a fellow page in
 case of V2M?

Ah yes, this was a leftover from a previous version of the series. I had
V2M in-kernel emulation implemented at some time, but later dropped that.
Thanks for spotting.

 +phys_addr_t vgic_its_base;
 +
  /* Distributor enabled */
  u32 enabled;
  
 diff --git a/virt/kvm/arm/vgic-v3-emul.c b/virt/kvm/arm/vgic-v3-emul.c
 index fbfdd6f..16c6d8a 100644
 --- a/virt/kvm/arm/vgic-v3-emul.c
 +++ b/virt/kvm/arm/vgic-v3-emul.c
 @@ -1012,6 +1012,7 @@ static int vgic_v3_has_attr(struct kvm_device *dev,
  return -ENXIO;
  case KVM_VGIC_V3_ADDR_TYPE_DIST:
  case KVM_VGIC_V3_ADDR_TYPE_REDIST:
 +case KVM_VGIC_V3_ADDR_TYPE_ITS:
  return 0;
  }
  break;
 diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
 index 6ea30e0..2e9723aa 100644
 --- a/virt/kvm/arm/vgic.c
 +++ b/virt/kvm/arm/vgic.c
 @@ -932,6 +932,16 @@ int vgic_register_kvm_io_dev(struct kvm *kvm, gpa_t 
 base, int len,
  return ret;
  }
  
 +bool vgic_has_its(struct kvm *kvm)
 +{
 +struct vgic_dist *dist = kvm-arch.vgic;
 +
 +if (dist-vgic_model != KVM_DEV_TYPE_ARM_VGIC_V3)
 +return false;
 +
 +return !IS_VGIC_ADDR_UNDEF(dist-vgic_its_base);
 +}
 +
  static int vgic_nr_shared_irqs(struct vgic_dist *dist)
  {
  return dist-nr_irqs - VGIC_NR_PRIVATE_IRQS;
 @@ -1835,6 +1845,7 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
  kvm-arch.vgic.vgic_dist_base = VGIC_ADDR_UNDEF;
  kvm-arch.vgic.vgic_cpu_base = VGIC_ADDR_UNDEF;
  kvm-arch.vgic.vgic_redist_base = VGIC_ADDR_UNDEF;
 +kvm-arch.vgic.vgic_its_base = VGIC_ADDR_UNDEF;
 minor: given the fact we have specialized
 init_vgic_model/vgic_vx_init_emulation wouldn't it make sense to move
 those VGIC v3 specific assignment there? also CPU base is specific to v2?

Yes, that seems to make some sense. The original idea was to make sure

Re: [PATCH 09/13] KVM: arm64: handle pending bit for LPIs in ITS emulation

2015-06-11 Thread Andre Przywara
Salut Eric,

On 06/09/2015 04:59 PM, Eric Auger wrote:
 On 05/29/2015 11:53 AM, Andre Przywara wrote:
 As the actual LPI number in a guest can be quite high, but is mostly
 assigned using a very sparse allocation scheme, bitmaps and arrays
 for storing the virtual interrupt status are a waste of memory.
 We use our equivalent of the Interrupt Translation Table Entry
 (ITTE) to hold this extra status information for a virtual LPI.
 As the normal VGIC code cannot use it's fancy bitmaps to manage
 pending interrupts, we provide a hook in the VGIC code to let the
 ITS emulation handle the list register queueing itself.
 LPIs are located in a separate number range (=8192), so
 distinguishing them is easy. With LPIs being only edge-triggered, we
 get away with a less complex IRQ handling.

 Signed-off-by: Andre Przywara andre.przyw...@arm.com
 ---
  include/kvm/arm_vgic.h  |  2 ++
  virt/kvm/arm/its-emul.c | 66 +++
  virt/kvm/arm/its-emul.h |  3 ++
  virt/kvm/arm/vgic-v3-emul.c |  2 ++
  virt/kvm/arm/vgic.c | 68 
 +
  5 files changed, 124 insertions(+), 17 deletions(-)

 diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
 index fa17df6..de19c34 100644
 --- a/include/kvm/arm_vgic.h
 +++ b/include/kvm/arm_vgic.h
 @@ -147,6 +147,8 @@ struct vgic_vm_ops {
  int (*init_model)(struct kvm *);
  void(*destroy_model)(struct kvm *);
  int (*map_resources)(struct kvm *, const struct vgic_params *);
 +bool(*queue_lpis)(struct kvm_vcpu *);
 +void(*unqueue_lpi)(struct kvm_vcpu *, int irq);
  };
  
  struct vgic_io_device {
 diff --git a/virt/kvm/arm/its-emul.c b/virt/kvm/arm/its-emul.c
 index f0f4a9c..f75fb9e 100644
 --- a/virt/kvm/arm/its-emul.c
 +++ b/virt/kvm/arm/its-emul.c
 @@ -50,8 +50,26 @@ struct its_itte {
  struct its_collection *collection;
  u32 lpi;
  u32 event_id;
 +bool enabled;
 +unsigned long *pending;
 allocated in later patch. does not ease the review of the life cycle but
 I guess it is accepted/acceptable.

I tried to move some bits around a bit and ran into several issues, so I
guess we have to live with that.

 Isn't it somehow redundant to have a bitmap here where the collection
 already indicates the target cpu id on which the LPI is pending?

Unfortunately only somewhat, as Marc taught me the other day ;-)
First, the spec shows that the pending bitmap is allocated _per CPU_, so
we have to model this here appropriately.
Second, you could have an LPI pending on one distributor, then change
the associated collection to another distributor and trigger that
interrupt again. This would make it pending on two VCPUs.
Admittedly not the most prominent use case, but possible.

Cheers,
Andre.
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 03/10] KVM: arm/arm64: vgic: Convert struct vgic_lr to use bitfields

2015-06-10 Thread Andre Przywara
Hi Marc,

On 06/08/2015 06:03 PM, Marc Zyngier wrote:
 As we're about to cram more information in the vgic_lr structure
 (HW interrupt number and additional state information), we switch
 to a layout similar to the HW's:
 
 - use bitfields to save space (we don't need more than 10 bits
   to represent the irq numbers)

But that will not be true for LPIs later, right? Before that I was lucky
with the irq field being 16 bits wide ;-)
So can we increase that to be at least 14 bits (8192 LPI offset + 8192
LPIs) here? The structure would still fit in 32 bits, then.
I guess guests should get away with only supporting 8K of LPIs, but if
we map hardware LPIs to guest IRQs I guess we may exceed 14 bits here.
Not sure if we could extend this further for ARM64 only, as we have more
room there and also need it only here.

Cheers,
Andre.

 - source CPU and HW interrupt can share the same field, as
   a SGI doesn't have a physical line.
 
 Signed-off-by: Marc Zyngier marc.zyng...@arm.com
 ---
  include/kvm/arm_vgic.h | 10 +++---
  1 file changed, 7 insertions(+), 3 deletions(-)
 
 diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
 index 133ea00..4f9fa1d 100644
 --- a/include/kvm/arm_vgic.h
 +++ b/include/kvm/arm_vgic.h
 @@ -95,11 +95,15 @@ enum vgic_type {
  #define LR_STATE_ACTIVE  (1  1)
  #define LR_STATE_MASK(3  0)
  #define LR_EOI_INT   (1  2)
 +#define LR_HW(1  3)
  
  struct vgic_lr {
 - u16 irq;
 - u8  source;
 - u8  state;
 + unsigned irq:10;
 + union {
 + unsigned hwirq:10;
 + unsigned source:8;
 + };
 + unsigned state:4;
  };
  
  struct vgic_vmcr {
 
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 6/8] arm: prepare for instantiating different IRQ chip devices

2015-06-09 Thread Andre Przywara
Hi, contrary to my boasting in the cover letter I managed to
accidentially drop the fix for the GIC device initialization error
handling Will requested from this series.
If we fail the GIC initialization sequence at some point, we should
make sure to not let the gic_fd initialized, so that subsequent
accesses to the GIC device fail appropriately.
So the fix below should be merged in, actually a part of it already
in patch 2/8.
If there are no further comments, I will re-spin this series with
those fixes contained in the proper patches later this week.

Cheers,
Andre.

---
diff --git a/arm/gic.c b/arm/gic.c
index ab0f594..5fb94c1 100644
--- a/arm/gic.c
+++ b/arm/gic.c
@@ -89,15 +89,21 @@ static int gic__create_device(struct kvm *kvm, enum 
irqchip_type type)
err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, redist_attr);
break;
default:
-   return -ENODEV;
+   err = -ENODEV;
+   break;
}
if (err)
-   return err;
+   goto out_err;
 
err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, dist_attr);
if (err)
-   return err;
+   goto out_err;
+
+   return err;
 
+out_err:
+   close(gic_fd);
+   gic_fd = -1;
return err;
 }
 
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 4/8] AArch{32,64}: dynamically configure the number of GIC interrupts

2015-06-05 Thread Andre Przywara
From: Marc Zyngier marc.zyng...@arm.com

In order to reduce the memory usage of large guests (as well
as improve performance), tell KVM about the number of interrupts
we require.

To avoid synchronization with the various device creation,
use a late_init callback to compute the GIC configuration.
[Andre: rename to gic__init_gic() to ease future expansion]

Signed-off-by: Marc Zyngier marc.zyng...@arm.com
Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 arm/gic.c | 25 +
 1 file changed, 25 insertions(+)

diff --git a/arm/gic.c b/arm/gic.c
index ce5f7fa..6277af8 100644
--- a/arm/gic.c
+++ b/arm/gic.c
@@ -1,10 +1,12 @@
 #include kvm/fdt.h
+#include kvm/irq.h
 #include kvm/kvm.h
 #include kvm/virtio.h
 
 #include arm-common/gic.h
 
 #include linux/byteorder.h
+#include linux/kernel.h
 #include linux/kvm.h
 
 static int gic_fd = -1;
@@ -87,6 +89,29 @@ int gic__create(struct kvm *kvm)
return err;
 }
 
+static int gic__init_gic(struct kvm *kvm)
+{
+   int lines = irq__get_nr_allocated_lines();
+   u32 nr_irqs = ALIGN(lines, 32) + GIC_SPI_IRQ_BASE;
+   struct kvm_device_attr nr_irqs_attr = {
+   .group  = KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
+   .addr   = (u64)(unsigned long)nr_irqs,
+   };
+
+   /*
+* If we didn't use the KVM_CREATE_DEVICE method, KVM will
+* give us some default number of interrupts.
+*/
+   if (gic_fd  0)
+   return 0;
+
+   if (!ioctl(gic_fd, KVM_HAS_DEVICE_ATTR, nr_irqs_attr))
+   return ioctl(gic_fd, KVM_SET_DEVICE_ATTR, nr_irqs_attr);
+
+   return 0;
+}
+late_init(gic__init_gic)
+
 void gic__generate_fdt_nodes(void *fdt, u32 phandle)
 {
u64 reg_prop[] = {
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 5/8] arm: finish VGIC initialisation explicitly

2015-06-05 Thread Andre Przywara
Since Linux 3.19-rc1 there is a new API to explicitly initialise
the in-kernel GIC emulation by a userland KVM device call.
Use that to tell the kernel we are finished with the GIC
initialisation, since the automatic GIC init will only be provided
as a legacy functionality in the future.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 arm/gic.c | 25 ++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/arm/gic.c b/arm/gic.c
index 6277af8..8d47562 100644
--- a/arm/gic.c
+++ b/arm/gic.c
@@ -89,24 +89,43 @@ int gic__create(struct kvm *kvm)
return err;
 }
 
+/*
+ * Sets the number of used interrupts and finalizes the GIC init explicitly.
+ */
 static int gic__init_gic(struct kvm *kvm)
 {
+   int ret;
+
int lines = irq__get_nr_allocated_lines();
u32 nr_irqs = ALIGN(lines, 32) + GIC_SPI_IRQ_BASE;
struct kvm_device_attr nr_irqs_attr = {
.group  = KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
.addr   = (u64)(unsigned long)nr_irqs,
};
+   struct kvm_device_attr vgic_init_attr = {
+   .group  = KVM_DEV_ARM_VGIC_GRP_CTRL,
+   .attr   = KVM_DEV_ARM_VGIC_CTRL_INIT,
+   };
 
/*
 * If we didn't use the KVM_CREATE_DEVICE method, KVM will
-* give us some default number of interrupts.
+* give us some default number of interrupts. The GIC initialization
+* will be done automatically in this case.
 */
if (gic_fd  0)
return 0;
 
-   if (!ioctl(gic_fd, KVM_HAS_DEVICE_ATTR, nr_irqs_attr))
-   return ioctl(gic_fd, KVM_SET_DEVICE_ATTR, nr_irqs_attr);
+   if (!ioctl(gic_fd, KVM_HAS_DEVICE_ATTR, nr_irqs_attr)) {
+   ret = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, nr_irqs_attr);
+   if (ret)
+   return ret;
+   }
+
+   if (!ioctl(gic_fd, KVM_HAS_DEVICE_ATTR, vgic_init_attr)) {
+   ret = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, vgic_init_attr);
+   if (ret)
+   return ret;
+   }
 
return 0;
 }
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 3/8] irq: add irq__get_nr_allocated_lines

2015-06-05 Thread Andre Przywara
From: Marc Zyngier marc.zyng...@arm.com

The ARM GIC emulation needs to be told the number of interrupts
it has to support. As commit 1c262fa1dc7bc (kvm tools: irq: make
irq__alloc_line generic) made the interrupt counter private,
add a new accessor returning the number of interrupt lines we've
allocated so far.

Signed-off-by: Marc Zyngier marc.zyng...@arm.com
Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 include/kvm/irq.h | 1 +
 irq.c | 5 +
 2 files changed, 6 insertions(+)

diff --git a/include/kvm/irq.h b/include/kvm/irq.h
index 4cec6f0..8a78e43 100644
--- a/include/kvm/irq.h
+++ b/include/kvm/irq.h
@@ -11,6 +11,7 @@
 struct kvm;
 
 int irq__alloc_line(void);
+int irq__get_nr_allocated_lines(void);
 
 int irq__init(struct kvm *kvm);
 int irq__exit(struct kvm *kvm);
diff --git a/irq.c b/irq.c
index 33ea8d2..71eaa05 100644
--- a/irq.c
+++ b/irq.c
@@ -7,3 +7,8 @@ int irq__alloc_line(void)
 {
return next_line++;
 }
+
+int irq__get_nr_allocated_lines(void)
+{
+   return next_line - KVM_IRQ_OFFSET;
+}
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 2/8] AArch{32,64}: use KVM_CREATE_DEVICE co to instanciate the GIC

2015-06-05 Thread Andre Przywara
From: Marc Zyngier marc.zyng...@arm.com

As of 3.14, KVM/arm supports the creation/configuration of the GIC through
a more generic device API, which is now the preferred way to do so.

Plumb the new API in, and allow the old code to be used as a fallback.

[Andre: Rename some functions on the way to differentiate between
creation and initialisation more clearly.]

Signed-off-by: Marc Zyngier marc.zyng...@arm.com
Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 arm/gic.c| 60 ++--
 arm/include/arm-common/gic.h |  2 +-
 arm/kvm.c|  6 ++---
 3 files changed, 57 insertions(+), 11 deletions(-)

diff --git a/arm/gic.c b/arm/gic.c
index 5d8cbe6..ce5f7fa 100644
--- a/arm/gic.c
+++ b/arm/gic.c
@@ -7,7 +7,41 @@
 #include linux/byteorder.h
 #include linux/kvm.h
 
-int gic__init_irqchip(struct kvm *kvm)
+static int gic_fd = -1;
+
+static int gic__create_device(struct kvm *kvm)
+{
+   int err;
+   u64 cpu_if_addr = ARM_GIC_CPUI_BASE;
+   u64 dist_addr = ARM_GIC_DIST_BASE;
+   struct kvm_create_device gic_device = {
+   .type   = KVM_DEV_TYPE_ARM_VGIC_V2,
+   };
+   struct kvm_device_attr cpu_if_attr = {
+   .group  = KVM_DEV_ARM_VGIC_GRP_ADDR,
+   .attr   = KVM_VGIC_V2_ADDR_TYPE_CPU,
+   .addr   = (u64)(unsigned long)cpu_if_addr,
+   };
+   struct kvm_device_attr dist_attr = {
+   .group  = KVM_DEV_ARM_VGIC_GRP_ADDR,
+   .attr   = KVM_VGIC_V2_ADDR_TYPE_DIST,
+   .addr   = (u64)(unsigned long)dist_addr,
+   };
+
+   err = ioctl(kvm-vm_fd, KVM_CREATE_DEVICE, gic_device);
+   if (err)
+   return err;
+
+   gic_fd = gic_device.fd;
+
+   err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, cpu_if_attr);
+   if (err)
+   return err;
+
+   return ioctl(gic_fd, KVM_SET_DEVICE_ATTR, dist_attr);
+}
+
+static int gic__create_irqchip(struct kvm *kvm)
 {
int err;
struct kvm_arm_device_addr gic_addr[] = {
@@ -23,12 +57,6 @@ int gic__init_irqchip(struct kvm *kvm)
}
};
 
-   if (kvm-nrcpus  GIC_MAX_CPUS) {
-   pr_warning(%d CPUS greater than maximum of %d -- truncating\n,
-   kvm-nrcpus, GIC_MAX_CPUS);
-   kvm-nrcpus = GIC_MAX_CPUS;
-   }
-
err = ioctl(kvm-vm_fd, KVM_CREATE_IRQCHIP);
if (err)
return err;
@@ -41,6 +69,24 @@ int gic__init_irqchip(struct kvm *kvm)
return err;
 }
 
+int gic__create(struct kvm *kvm)
+{
+   int err;
+
+   if (kvm-nrcpus  GIC_MAX_CPUS) {
+   pr_warning(%d CPUS greater than maximum of %d -- truncating\n,
+   kvm-nrcpus, GIC_MAX_CPUS);
+   kvm-nrcpus = GIC_MAX_CPUS;
+   }
+
+   /* Try the new way first, and fallback on legacy method otherwise */
+   err = gic__create_device(kvm);
+   if (err)
+   err = gic__create_irqchip(kvm);
+
+   return err;
+}
+
 void gic__generate_fdt_nodes(void *fdt, u32 phandle)
 {
u64 reg_prop[] = {
diff --git a/arm/include/arm-common/gic.h b/arm/include/arm-common/gic.h
index 5a36f2c..44859f7 100644
--- a/arm/include/arm-common/gic.h
+++ b/arm/include/arm-common/gic.h
@@ -24,7 +24,7 @@
 struct kvm;
 
 int gic__alloc_irqnum(void);
-int gic__init_irqchip(struct kvm *kvm);
+int gic__create(struct kvm *kvm);
 void gic__generate_fdt_nodes(void *fdt, u32 phandle);
 
 #endif /* ARM_COMMON__GIC_H */
diff --git a/arm/kvm.c b/arm/kvm.c
index 58ad9fa..bcd2533 100644
--- a/arm/kvm.c
+++ b/arm/kvm.c
@@ -81,7 +81,7 @@ void kvm__arch_init(struct kvm *kvm, const char 
*hugetlbfs_path, u64 ram_size)
madvise(kvm-arch.ram_alloc_start, kvm-arch.ram_alloc_size,
MADV_MERGEABLE | MADV_HUGEPAGE);
 
-   /* Initialise the virtual GIC. */
-   if (gic__init_irqchip(kvm))
-   die(Failed to initialise virtual GIC);
+   /* Create the virtual GIC. */
+   if (gic__create(kvm))
+   die(Failed to create virtual GIC);
 }
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 7/8] arm: add support for supplying GICv3 redistributor addresses

2015-06-05 Thread Andre Przywara
The code currently is assuming fixed sized memory regions for the
distributor and CPU interface. GICv3 needs a dynamic allocation of
its redistributor region, since its size depends on the number of
vCPUs.
Also add the necessary code to create a GICv3 IRQ chip instance.
This contains some defines which are not (yet) in the (32 bit) header
files to allow compilation for ARM.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 arm/gic.c | 37 +++--
 arm/include/arm-common/gic.h  |  2 +-
 arm/include/arm-common/kvm-arch.h | 18 ++
 arm/kvm-cpu.c |  4 +++-
 4 files changed, 53 insertions(+), 8 deletions(-)

diff --git a/arm/gic.c b/arm/gic.c
index 0ce40e4..c50d662 100644
--- a/arm/gic.c
+++ b/arm/gic.c
@@ -9,13 +9,24 @@
 #include linux/kernel.h
 #include linux/kvm.h
 
+/* Those names are not defined for ARM (yet) */
+#ifndef KVM_VGIC_V3_ADDR_TYPE_DIST
+#define KVM_VGIC_V3_ADDR_TYPE_DIST 2
+#endif
+
+#ifndef KVM_VGIC_V3_ADDR_TYPE_REDIST
+#define KVM_VGIC_V3_ADDR_TYPE_REDIST 3
+#endif
+
 static int gic_fd = -1;
+static int nr_redists;
 
 static int gic__create_device(struct kvm *kvm, enum irqchip_type type)
 {
int err;
u64 cpu_if_addr = ARM_GIC_CPUI_BASE;
u64 dist_addr = ARM_GIC_DIST_BASE;
+   u64 redist_addr = dist_addr - nr_redists * ARM_GIC_REDIST_SIZE;
struct kvm_create_device gic_device = {
.flags  = 0,
};
@@ -28,11 +39,19 @@ static int gic__create_device(struct kvm *kvm, enum 
irqchip_type type)
.group  = KVM_DEV_ARM_VGIC_GRP_ADDR,
.addr   = (u64)(unsigned long)dist_addr,
};
+   struct kvm_device_attr redist_attr = {
+   .group  = KVM_DEV_ARM_VGIC_GRP_ADDR,
+   .attr   = KVM_VGIC_V3_ADDR_TYPE_REDIST,
+   .addr   = (u64)(unsigned long)redist_addr,
+   };
 
switch (type) {
case IRQCHIP_GICV2:
gic_device.type = KVM_DEV_TYPE_ARM_VGIC_V2;
break;
+   case IRQCHIP_GICV3:
+   gic_device.type = KVM_DEV_TYPE_ARM_VGIC_V3;
+   break;
default:
return -ENODEV;
}
@@ -48,6 +67,10 @@ static int gic__create_device(struct kvm *kvm, enum 
irqchip_type type)
dist_attr.attr = KVM_VGIC_V2_ADDR_TYPE_DIST;
err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, cpu_if_attr);
break;
+   case IRQCHIP_GICV3:
+   dist_attr.attr = KVM_VGIC_V3_ADDR_TYPE_DIST;
+   err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, redist_attr);
+   break;
default:
return -ENODEV;
}
@@ -55,6 +78,8 @@ static int gic__create_device(struct kvm *kvm, enum 
irqchip_type type)
return err;
 
err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, dist_attr);
+   if (err)
+   return err;
 
return err;
 }
@@ -162,17 +187,25 @@ void gic__generate_fdt_nodes(void *fdt, u32 phandle, enum 
irqchip_type type)
u64 reg_prop[] = {
cpu_to_fdt64(ARM_GIC_DIST_BASE),
cpu_to_fdt64(ARM_GIC_DIST_SIZE),
-   cpu_to_fdt64(ARM_GIC_CPUI_BASE),
-   cpu_to_fdt64(ARM_GIC_CPUI_SIZE),
+   0, 0,   /* to be filled */
};
 
switch (type) {
case IRQCHIP_GICV2:
compatible = arm,cortex-a15-gic;
+   reg_prop[2] = ARM_GIC_CPUI_BASE;
+   reg_prop[3] = ARM_GIC_CPUI_SIZE;
+   break;
+   case IRQCHIP_GICV3:
+   compatible = arm,gic-v3;
+   reg_prop[2] = ARM_GIC_DIST_BASE - nr_redists * 
ARM_GIC_REDIST_SIZE;
+   reg_prop[3] = ARM_GIC_REDIST_SIZE * nr_redists;
break;
default:
return;
}
+   reg_prop[2] = cpu_to_fdt64(reg_prop[2]);
+   reg_prop[3] = cpu_to_fdt64(reg_prop[3]);
 
_FDT(fdt_begin_node(fdt, intc));
_FDT(fdt_property_string(fdt, compatible, compatible));
diff --git a/arm/include/arm-common/gic.h b/arm/include/arm-common/gic.h
index f5f6707..8d6ab01 100644
--- a/arm/include/arm-common/gic.h
+++ b/arm/include/arm-common/gic.h
@@ -21,7 +21,7 @@
 #define GIC_MAX_CPUS   8
 #define GIC_MAX_IRQ255
 
-enum irqchip_type {IRQCHIP_DEFAULT, IRQCHIP_GICV2};
+enum irqchip_type {IRQCHIP_DEFAULT, IRQCHIP_GICV2, IRQCHIP_GICV3};
 
 struct kvm;
 
diff --git a/arm/include/arm-common/kvm-arch.h 
b/arm/include/arm-common/kvm-arch.h
index 082131d..be66a76 100644
--- a/arm/include/arm-common/kvm-arch.h
+++ b/arm/include/arm-common/kvm-arch.h
@@ -17,10 +17,8 @@
 
 #define ARM_GIC_DIST_BASE  (ARM_AXI_AREA - ARM_GIC_DIST_SIZE)
 #define ARM_GIC_CPUI_BASE  (ARM_GIC_DIST_BASE - ARM_GIC_CPUI_SIZE)
-#define ARM_GIC_SIZE   (ARM_GIC_DIST_SIZE + ARM_GIC_CPUI_SIZE)
 
 #define ARM_IOPORT_SIZE(ARM_MMIO_AREA

[PATCH v2 0/8] kvmtool: arm64: GICv3 guest support

2015-06-05 Thread Andre Przywara
Hi,

a rework of the GICv3 support series for kvmtool.
I addressed Will's comments on the broken fallback in VGIC creation,
also changed the command line parameter to --irqchip=[gicv2,gicv3].
The default is still GICv2 emulation for the sake of reproducibility,
not sure we want to have an automatic switch-over in case GICv2
emulation is not supported by the hardware.
This is also the base for ITS support, which I will send later as
a follow-up series.

Cheers,
Andre.
-

Since Linux 3.19 the kernel can emulate a GICv3 for KVM guests.
This allows more than 8 VCPUs in a guest and enables in-kernel irqchip
for non-backwards-compatible GICv3 implementations.

This series updates kvmtool to support this feature.
The first half of the series is mostly from Marc and supports some
newer features of the virtual GIC which we later depend on. The second
part enables support for a guest GICv3 by adding a new command line
parameter (--irqchip=).

We now use the KVM_CREATE_DEVICE interface to create a virtual GIC
and only fall back to the now legacy KVM_CREATE_IRQCHIP call if the
former is not supported by the kernel.
Also we use two new features the KVM_CREATE_DEVICE interface
introduces:
* We now set the number of actually used interrupts to avoid
  allocating too many of them without ever using them.
* We tell the kernel explicitly that we are finished with the GIC
  initialisation. This is a requirement for future VGIC versions.

The final three patches introduce virtual GICv3 support, so on
supported hardware (and given kernel support) the user can ask KVM to
emulate a GICv3, lifting the 8 VCPU limit of KVM. This is done by
specifying --irqchip=gicv3 on the command line.
As the kernel currently only supports this on ARM64, this parameter
is valid for the arm64 kvmtool build. But as the GIC is shared in
kvmtool, I had to add the macro definitions to not break the build
on ARM.

This series goes on top of the new official stand-alone repo hosted
on Will's kernel.org git [1].
Find a branch with those patches included at my repo [2].

[1] git://git.kernel.org/pub/scm/linux/kernel/git/will/kvmtool.git
[2] git://linux-arm.org/kvmtool.git (branch gicv3/v2)
http://www.linux-arm.org/git?p=kvmtool.git;a=log;h=refs/heads/gicv3/v2

Andre Przywara (4):
  arm: finish VGIC initialisation explicitly
  arm: prepare for instantiating different IRQ chip devices
  arm: add support for supplying GICv3 redistributor addresses
  arm: use new irqchip parameter to create different vGIC types

Marc Zyngier (4):
  AArch64: Reserve two 64k pages for GIC CPU interface
  AArch{32,64}: use KVM_CREATE_DEVICE  co to instanciate the GIC
  irq: add irq__get_nr_allocated_lines
  AArch{32,64}: dynamically configure the number of GIC interrupts

 arm/aarch32/arm-cpu.c|   2 +-
 arm/aarch64/arm-cpu.c|   2 +-
 arm/aarch64/include/kvm/kvm-arch.h   |   2 +-
 arm/gic.c| 202 +--
 arm/include/arm-common/gic.h |   6 +-
 arm/include/arm-common/kvm-arch.h|  18 ++-
 arm/include/arm-common/kvm-config-arch.h |   9 +-
 arm/kvm-cpu.c|  10 +-
 arm/kvm.c|   8 +-
 include/kvm/irq.h|   1 +
 irq.c|   5 +
 11 files changed, 240 insertions(+), 25 deletions(-)

-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 8/8] arm: use new irqchip parameter to create different vGIC types

2015-06-05 Thread Andre Przywara
Currently we unconditionally create a virtual GICv2 in the guest.
Add a --irqchip= parameter to let the user specify a different GIC
type for the guest.
For now we the only other supported type is GICv3.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 arm/aarch64/arm-cpu.c|  2 +-
 arm/gic.c| 21 +
 arm/include/arm-common/kvm-config-arch.h |  9 -
 arm/kvm-cpu.c|  6 ++
 arm/kvm.c|  4 +++-
 5 files changed, 39 insertions(+), 3 deletions(-)

diff --git a/arm/aarch64/arm-cpu.c b/arm/aarch64/arm-cpu.c
index f702b9e..3dc8ea3 100644
--- a/arm/aarch64/arm-cpu.c
+++ b/arm/aarch64/arm-cpu.c
@@ -12,7 +12,7 @@
 static void generate_fdt_nodes(void *fdt, struct kvm *kvm, u32 gic_phandle)
 {
int timer_interrupts[4] = {13, 14, 11, 10};
-   gic__generate_fdt_nodes(fdt, gic_phandle, IRQCHIP_GICV2);
+   gic__generate_fdt_nodes(fdt, gic_phandle, kvm-cfg.arch.irqchip);
timer__generate_fdt_nodes(fdt, kvm, timer_interrupts);
 }
 
diff --git a/arm/gic.c b/arm/gic.c
index c50d662..ab0f594 100644
--- a/arm/gic.c
+++ b/arm/gic.c
@@ -21,6 +21,23 @@
 static int gic_fd = -1;
 static int nr_redists;
 
+int irqchip_parser(const struct option *opt, const char *arg, int unset)
+{
+   enum irqchip_type *type = opt-value;
+
+   *type = IRQCHIP_DEFAULT;
+   if (!strcmp(arg, gicv2)) {
+   *type = IRQCHIP_GICV2;
+   } else if (!strcmp(arg, gicv3)) {
+   *type = IRQCHIP_GICV3;
+   } else if (strcmp(arg, default)) {
+   fprintf(stderr, irqchip: unknown type \%s\\n, arg);
+   return -1;
+   }
+
+   return 0;
+}
+
 static int gic__create_device(struct kvm *kvm, enum irqchip_type type)
 {
int err;
@@ -121,6 +138,10 @@ int gic__create(struct kvm *kvm, enum irqchip_type type)
case IRQCHIP_GICV2:
max_cpus = GIC_MAX_CPUS;
break;
+   case IRQCHIP_GICV3:
+   nr_redists = kvm-cfg.nrcpus;
+   max_cpus = 255;
+   break;
default:
return -ENODEV;
}
diff --git a/arm/include/arm-common/kvm-config-arch.h 
b/arm/include/arm-common/kvm-config-arch.h
index a8ebd94..ae4e89b 100644
--- a/arm/include/arm-common/kvm-config-arch.h
+++ b/arm/include/arm-common/kvm-config-arch.h
@@ -8,8 +8,11 @@ struct kvm_config_arch {
unsigned intforce_cntfrq;
boolvirtio_trans_pci;
boolaarch32_guest;
+   int irqchip;
 };
 
+int irqchip_parser(const struct option *opt, const char *arg, int unset);
+
 #define OPT_ARCH_RUN(pfx, cfg) 
\
pfx,
\
ARM_OPT_ARCH_RUN(cfg)   
\
@@ -21,6 +24,10 @@ struct kvm_config_arch {
 updated to program CNTFRQ correctly*),   
\
OPT_BOOLEAN('\0', force-pci, (cfg)-virtio_trans_pci,
\
Force virtio devices to use PCI as their default  
\
-   transport),
+   transport),   
\
+OPT_CALLBACK('\0', irqchip, (cfg)-irqchip, 
\
+[gicv2|gicv3],   \
+type of interrupt controller to emulate in the guest,
\
+irqchip_parser, NULL),
 
 #endif /* ARM_COMMON__KVM_CONFIG_ARCH_H */
diff --git a/arm/kvm-cpu.c b/arm/kvm-cpu.c
index a3344fa..aacc172 100644
--- a/arm/kvm-cpu.c
+++ b/arm/kvm-cpu.c
@@ -144,6 +144,12 @@ bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 
phys_addr, u8 *data,
 {
int nr_redists = 0;
 
+   switch (vcpu-kvm-cfg.arch.irqchip) {
+   case IRQCHIP_GICV3:
+   nr_redists = vcpu-kvm-nrcpus;
+   break;
+   }
+
if (arm_addr_in_virtio_mmio_region(nr_redists, phys_addr)) {
return kvm__emulate_mmio(vcpu, phys_addr, data, len, is_write);
} else if (arm_addr_in_ioport_region(phys_addr)) {
diff --git a/arm/kvm.c b/arm/kvm.c
index f9685c2..2628d31 100644
--- a/arm/kvm.c
+++ b/arm/kvm.c
@@ -82,6 +82,8 @@ void kvm__arch_init(struct kvm *kvm, const char 
*hugetlbfs_path, u64 ram_size)
MADV_MERGEABLE | MADV_HUGEPAGE);
 
/* Create the virtual GIC. */
-   if (gic__create(kvm, IRQCHIP_GICV2))
+   if (kvm-cfg.arch.irqchip == IRQCHIP_DEFAULT)
+   kvm-cfg.arch.irqchip = IRQCHIP_GICV2;
+   if (gic__create(kvm, kvm-cfg.arch.irqchip))
die(Failed to create virtual GIC);
 }
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo

[PATCH v2 6/8] arm: prepare for instantiating different IRQ chip devices

2015-06-05 Thread Andre Przywara
Extend the vGIC handling code to potentially deal with different IRQ
chip devices instead of hard-coding the GICv2 in.
We extend most vGIC functions to take a type parameter, but still put
GICv2 in at the top for the time being.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 arm/aarch32/arm-cpu.c|  2 +-
 arm/aarch64/arm-cpu.c|  2 +-
 arm/gic.c| 66 ++--
 arm/include/arm-common/gic.h |  6 ++--
 arm/kvm.c|  2 +-
 5 files changed, 58 insertions(+), 20 deletions(-)

diff --git a/arm/aarch32/arm-cpu.c b/arm/aarch32/arm-cpu.c
index 946e443..d8d6293 100644
--- a/arm/aarch32/arm-cpu.c
+++ b/arm/aarch32/arm-cpu.c
@@ -12,7 +12,7 @@ static void generate_fdt_nodes(void *fdt, struct kvm *kvm, 
u32 gic_phandle)
 {
int timer_interrupts[4] = {13, 14, 11, 10};
 
-   gic__generate_fdt_nodes(fdt, gic_phandle);
+   gic__generate_fdt_nodes(fdt, gic_phandle, IRQCHIP_GICV2);
timer__generate_fdt_nodes(fdt, kvm, timer_interrupts);
 }
 
diff --git a/arm/aarch64/arm-cpu.c b/arm/aarch64/arm-cpu.c
index 8efe877..f702b9e 100644
--- a/arm/aarch64/arm-cpu.c
+++ b/arm/aarch64/arm-cpu.c
@@ -12,7 +12,7 @@
 static void generate_fdt_nodes(void *fdt, struct kvm *kvm, u32 gic_phandle)
 {
int timer_interrupts[4] = {13, 14, 11, 10};
-   gic__generate_fdt_nodes(fdt, gic_phandle);
+   gic__generate_fdt_nodes(fdt, gic_phandle, IRQCHIP_GICV2);
timer__generate_fdt_nodes(fdt, kvm, timer_interrupts);
 }
 
diff --git a/arm/gic.c b/arm/gic.c
index 8d47562..0ce40e4 100644
--- a/arm/gic.c
+++ b/arm/gic.c
@@ -11,13 +11,13 @@
 
 static int gic_fd = -1;
 
-static int gic__create_device(struct kvm *kvm)
+static int gic__create_device(struct kvm *kvm, enum irqchip_type type)
 {
int err;
u64 cpu_if_addr = ARM_GIC_CPUI_BASE;
u64 dist_addr = ARM_GIC_DIST_BASE;
struct kvm_create_device gic_device = {
-   .type   = KVM_DEV_TYPE_ARM_VGIC_V2,
+   .flags  = 0,
};
struct kvm_device_attr cpu_if_attr = {
.group  = KVM_DEV_ARM_VGIC_GRP_ADDR,
@@ -26,21 +26,37 @@ static int gic__create_device(struct kvm *kvm)
};
struct kvm_device_attr dist_attr = {
.group  = KVM_DEV_ARM_VGIC_GRP_ADDR,
-   .attr   = KVM_VGIC_V2_ADDR_TYPE_DIST,
.addr   = (u64)(unsigned long)dist_addr,
};
 
+   switch (type) {
+   case IRQCHIP_GICV2:
+   gic_device.type = KVM_DEV_TYPE_ARM_VGIC_V2;
+   break;
+   default:
+   return -ENODEV;
+   }
+
err = ioctl(kvm-vm_fd, KVM_CREATE_DEVICE, gic_device);
if (err)
return err;
 
gic_fd = gic_device.fd;
 
-   err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, cpu_if_attr);
+   switch (type) {
+   case IRQCHIP_GICV2:
+   dist_attr.attr = KVM_VGIC_V2_ADDR_TYPE_DIST;
+   err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, cpu_if_attr);
+   break;
+   default:
+   return -ENODEV;
+   }
if (err)
return err;
 
-   return ioctl(gic_fd, KVM_SET_DEVICE_ATTR, dist_attr);
+   err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, dist_attr);
+
+   return err;
 }
 
 static int gic__create_irqchip(struct kvm *kvm)
@@ -71,19 +87,28 @@ static int gic__create_irqchip(struct kvm *kvm)
return err;
 }
 
-int gic__create(struct kvm *kvm)
+int gic__create(struct kvm *kvm, enum irqchip_type type)
 {
+   int max_cpus;
int err;
 
-   if (kvm-nrcpus  GIC_MAX_CPUS) {
+   switch (type) {
+   case IRQCHIP_GICV2:
+   max_cpus = GIC_MAX_CPUS;
+   break;
+   default:
+   return -ENODEV;
+   }
+
+   if (kvm-nrcpus  max_cpus) {
pr_warning(%d CPUS greater than maximum of %d -- truncating\n,
-   kvm-nrcpus, GIC_MAX_CPUS);
-   kvm-nrcpus = GIC_MAX_CPUS;
+   kvm-nrcpus, max_cpus);
+   kvm-nrcpus = max_cpus;
}
 
/* Try the new way first, and fallback on legacy method otherwise */
-   err = gic__create_device(kvm);
-   if (err)
+   err = gic__create_device(kvm, type);
+   if (err  type == IRQCHIP_GICV2)
err = gic__create_irqchip(kvm);
 
return err;
@@ -131,15 +156,26 @@ static int gic__init_gic(struct kvm *kvm)
 }
 late_init(gic__init_gic)
 
-void gic__generate_fdt_nodes(void *fdt, u32 phandle)
+void gic__generate_fdt_nodes(void *fdt, u32 phandle, enum irqchip_type type)
 {
+   const char *compatible;
u64 reg_prop[] = {
-   cpu_to_fdt64(ARM_GIC_DIST_BASE), 
cpu_to_fdt64(ARM_GIC_DIST_SIZE),
-   cpu_to_fdt64(ARM_GIC_CPUI_BASE), 
cpu_to_fdt64(ARM_GIC_CPUI_SIZE),
+   cpu_to_fdt64(ARM_GIC_DIST_BASE),
+   cpu_to_fdt64(ARM_GIC_DIST_SIZE

[PATCH v2 1/8] AArch64: Reserve two 64k pages for GIC CPU interface

2015-06-05 Thread Andre Przywara
From: Marc Zyngier marc.zyng...@arm.com

On AArch64 system with a GICv2, the GICC range can be aligned
to the last 4k block of a 64k page, ending up straddling two
64k pages. In order not to conflict with the distributor mapping,
allocate two 64k pages to the CPU interface.

Signed-off-by: Marc Zyngier marc.zyng...@arm.com
Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 arm/aarch64/include/kvm/kvm-arch.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arm/aarch64/include/kvm/kvm-arch.h 
b/arm/aarch64/include/kvm/kvm-arch.h
index 2f08a26..4925736 100644
--- a/arm/aarch64/include/kvm/kvm-arch.h
+++ b/arm/aarch64/include/kvm/kvm-arch.h
@@ -2,7 +2,7 @@
 #define KVM__KVM_ARCH_H
 
 #define ARM_GIC_DIST_SIZE  0x1
-#define ARM_GIC_CPUI_SIZE  0x1
+#define ARM_GIC_CPUI_SIZE  0x2
 
 #define ARM_KERN_OFFSET(kvm)   ((kvm)-cfg.arch.aarch32_guest  ?   \
0x8000  :   \
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] kvmtool: don't use PCI config space IRQ line field

2015-06-04 Thread Andre Przywara
In PCI config space there is an interrupt line field (offset 0x3f),
which is used to initially communicate the IRQ line number from
firmware to the OS. _Hardware_ should never use this information,
as the OS is free to write any information in there.
But kvmtool uses this number when it triggers IRQs in the guest,
which fails starting with Linux 3.19-rc1, where the PCI layer starts
writing the virtual IRQ number in there.

Fix that by storing the IRQ number in a separate field in
struct virtio_pci, which is independent from the PCI config space
and cannot be influenced by the guest.
This fixes ARM/ARM64 guests using PCI with newer kernels.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 include/kvm/virtio-pci.h | 8 
 virtio/pci.c | 9 ++---
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/include/kvm/virtio-pci.h b/include/kvm/virtio-pci.h
index c795ce7..b70cadd 100644
--- a/include/kvm/virtio-pci.h
+++ b/include/kvm/virtio-pci.h
@@ -30,6 +30,14 @@ struct virtio_pci {
u8  isr;
u32 features;
 
+   /*
+* We cannot rely on the INTERRUPT_LINE byte in the config space once
+* we have run guest code, as the OS is allowed to use that field
+* as a scratch pad to communicate between driver and PCI layer.
+* So store our legacy interrupt line number in here for internal use.
+*/
+   u8  legacy_irq_line;
+
/* MSI-X */
u16 config_vector;
u32 config_gsi;
diff --git a/virtio/pci.c b/virtio/pci.c
index 7556239..e17e5a9 100644
--- a/virtio/pci.c
+++ b/virtio/pci.c
@@ -141,7 +141,7 @@ static bool virtio_pci__io_in(struct ioport *ioport, struct 
kvm_cpu *vcpu, u16 p
break;
case VIRTIO_PCI_ISR:
ioport__write8(data, vpci-isr);
-   kvm__irq_line(kvm, vpci-pci_hdr.irq_line, VIRTIO_IRQ_LOW);
+   kvm__irq_line(kvm, vpci-legacy_irq_line, VIRTIO_IRQ_LOW);
vpci-isr = VIRTIO_IRQ_LOW;
break;
default:
@@ -299,7 +299,7 @@ int virtio_pci__signal_vq(struct kvm *kvm, struct 
virtio_device *vdev, u32 vq)
kvm__irq_trigger(kvm, vpci-gsis[vq]);
} else {
vpci-isr = VIRTIO_IRQ_HIGH;
-   kvm__irq_trigger(kvm, vpci-pci_hdr.irq_line);
+   kvm__irq_trigger(kvm, vpci-legacy_irq_line);
}
return 0;
 }
@@ -323,7 +323,7 @@ int virtio_pci__signal_config(struct kvm *kvm, struct 
virtio_device *vdev)
kvm__irq_trigger(kvm, vpci-config_gsi);
} else {
vpci-isr = VIRTIO_PCI_ISR_CONFIG;
-   kvm__irq_trigger(kvm, vpci-pci_hdr.irq_line);
+   kvm__irq_trigger(kvm, vpci-legacy_irq_line);
}
 
return 0;
@@ -422,6 +422,9 @@ int virtio_pci__init(struct kvm *kvm, void *dev, struct 
virtio_device *vdev,
if (r  0)
goto free_msix_mmio;
 
+   /* save the IRQ that device__register() has allocated */
+   vpci-legacy_irq_line = vpci-pci_hdr.irq_line;
+
return 0;
 
 free_msix_mmio:
-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 00/13] arm64: KVM: GICv3 ITS emulation

2015-05-29 Thread Andre Przywara
The GICv3 ITS (Interrupt Translation Service) is a part of the
ARM GICv3 interrupt controller used for implementing MSIs.
It specifies a new kind of interrupts (LPIs), which are mapped to
establish a connection between a device, its MSI payload value and
the target processor the IRQ is eventually delivered to.
In order to allow using MSIs in an ARM64 KVM guest, we emulate this
ITS widget in the kernel.
The ITS works by reading commands written by software (from the guest
in our case) into a (guest allocated) memory region and establishing
the mapping between a device, the MSI payload and the target CPU.
We parse these commands and update our internal data structures to
reflect those changes. On an MSI injection we iterate those
structures to learn the LPI number we have to inject.
For the time being we use simple lists to hold the data, this is
good enough for the small number of entries each of the components
currently have. Should this become a performance bottleneck in the
future, those can be extended to arrays or trees if needed.

Most of the code lives in a separate source file (its-emul.c), though
there are some changes necessary both in vgic.c and gic-v3-emul.c.
Patch 01/13 gets rid of the internal tracking of the used LR for
an injected IRQ.
Patch 02/13 extends the KVM MSI ioctl to hold a device ID.
Patch 03/13 introduces an emulation model specific destroy function
to let the ITS be teared down correctly later.
The rest of the patches implement the ITS functionality step by step.
For more details see the respective commit messages.

For the time being this series gives us the ability to use emulated
PCI devices that can use MSIs in the guest. Those have to be
triggered by letting the userland device emulation simulate the MSI
write with the KVM_SIGNAL_MSI ioctl. This will be translated into
the proper LPI by the ITS emulation and injected into the guest in
the usual way (just with a higher IRQ number).

This series is based on 4.1-rc5 and can be found at the its-emul/v1
branch of this repository [1].
For this to be used you need a GICv3 host machine, though it does not
rely on any host ITS bits (neither hardware or software).

To test this you can use the kvmtool patches available in the its
branch here [2].
Start a guest with: $ lkvm run --irqchip=gicv3-its --force-pci
and see the ITS being used for instance by the virtio devices.

[1]: git://linux-arm.org/linux-ap.git
 http://www.linux-arm.org/git?p=linux-ap.git;a=log;h=refs/heads/its-emul/v1
[2]: git://linux-arm.org/kvmtool.git
 http://www.linux-arm.org/git?p=kvmtool.git;a=log;h=refs/heads/its

Andre Przywara (13):
  KVM: arm/arm64: VGIC: don't track used LRs in the distributor
  KVM: extend struct kvm_msi to hold a 32-bit device ID
  KVM: arm/arm64: add emulation model specific destroy function
  KVM: arm64: Introduce new MMIO region for the ITS base address
  KVM: arm64: handle ITS related GICv3 redistributor registers
  KVM: arm64: introduce ITS emulation file with stub functions
  KVM: arm64: implement basic ITS register handlers
  KVM: arm64: add data structures to model ITS interrupt translation
  KVM: arm64: handle pending bit for LPIs in ITS emulation
  KVM: arm64: sync LPI properties and status between guest and KVM
  KVM: arm64: implement ITS command queue command handlers
  KVM: arm64: implement MSI injection in ITS emulation
  KVM: arm64: enable ITS emulation as a virtual MSI controller

 Documentation/virtual/kvm/api.txt  |   10 +-
 Documentation/virtual/kvm/devices/arm-vgic.txt |7 +
 arch/arm64/include/uapi/asm/kvm.h  |3 +
 arch/arm64/kvm/Kconfig |1 +
 arch/arm64/kvm/Makefile|1 +
 include/kvm/arm_vgic.h |   39 +-
 include/linux/irqchip/arm-gic-v3.h |   10 +
 include/uapi/linux/kvm.h   |4 +-
 virt/kvm/arm/its-emul.c| 1026 
 virt/kvm/arm/its-emul.h|   52 ++
 virt/kvm/arm/vgic-v2.c |1 +
 virt/kvm/arm/vgic-v3-emul.c|   98 ++-
 virt/kvm/arm/vgic-v3.c |1 +
 virt/kvm/arm/vgic.c|  280 ---
 virt/kvm/arm/vgic.h|5 +
 15 files changed, 1426 insertions(+), 112 deletions(-)
 create mode 100644 virt/kvm/arm/its-emul.c
 create mode 100644 virt/kvm/arm/its-emul.h

-- 
2.3.5

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 01/13] KVM: arm/arm64: VGIC: don't track used LRs in the distributor

2015-05-29 Thread Andre Przywara
Currently we track which IRQ has been mapped to which VGIC list
register and also have to synchronize both. We used to do this
to hold some extra state (for instance the active bit).
It turns out that this extra state in the LRs is no longer needed and
this extra tracking causes some pain later.
Remove the tracking feature (lr_map and lr_used) and get rid of
quite some code on the way.
On a guest exit we pick up all still pending IRQs from the LRs and put
them back in the distributor. We don't care about active-only IRQs,
so we keep them in the LRs. They will be retired either by our
vgic_process_maintenance() routine or by the GIC hardware in case of
edge triggered interrupts.
In places where we scan LRs we now use our shadow copy of the ELRSR
register directly.
This code change means we lose the piggy-back optimization, which
would re-use an active-only LR to inject the pending state on top of
it. Tracing with various workloads shows that this actually occurred
very rarely, the ballpark figure is about once every 10,000 exits
in a disk I/O heavy workload. Also the list registers don't seem to
as scarce as assumed, with all 4 LRs on the popular implementations
used less than once every 100,000 exits.

This has been briefly tested on Midway, Juno and the model (the latter
both with GICv2 and GICv3 guests).

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 include/kvm/arm_vgic.h |   6 ---
 virt/kvm/arm/vgic-v2.c |   1 +
 virt/kvm/arm/vgic-v3.c |   1 +
 virt/kvm/arm/vgic.c| 143 ++---
 4 files changed, 66 insertions(+), 85 deletions(-)

diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 133ea00..2ccfa9a 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -279,9 +279,6 @@ struct vgic_v3_cpu_if {
 };
 
 struct vgic_cpu {
-   /* per IRQ to LR mapping */
-   u8  *vgic_irq_lr_map;
-
/* Pending/active/both interrupts on this VCPU */
DECLARE_BITMAP( pending_percpu, VGIC_NR_PRIVATE_IRQS);
DECLARE_BITMAP( active_percpu, VGIC_NR_PRIVATE_IRQS);
@@ -292,9 +289,6 @@ struct vgic_cpu {
unsigned long   *active_shared;
unsigned long   *pend_act_shared;
 
-   /* Bitmap of used/free list registers */
-   DECLARE_BITMAP( lr_used, VGIC_V2_MAX_LRS);
-
/* Number of list registers on this CPU */
int nr_lr;
 
diff --git a/virt/kvm/arm/vgic-v2.c b/virt/kvm/arm/vgic-v2.c
index f9b9c7c..f723710 100644
--- a/virt/kvm/arm/vgic-v2.c
+++ b/virt/kvm/arm/vgic-v2.c
@@ -144,6 +144,7 @@ static void vgic_v2_enable(struct kvm_vcpu *vcpu)
 * anyway.
 */
vcpu-arch.vgic_cpu.vgic_v2.vgic_vmcr = 0;
+   vcpu-arch.vgic_cpu.vgic_v2.vgic_elrsr = ~0;
 
/* Get the show on the road... */
vcpu-arch.vgic_cpu.vgic_v2.vgic_hcr = GICH_HCR_EN;
diff --git a/virt/kvm/arm/vgic-v3.c b/virt/kvm/arm/vgic-v3.c
index dff0602..21e5d28 100644
--- a/virt/kvm/arm/vgic-v3.c
+++ b/virt/kvm/arm/vgic-v3.c
@@ -178,6 +178,7 @@ static void vgic_v3_enable(struct kvm_vcpu *vcpu)
 * anyway.
 */
vgic_v3-vgic_vmcr = 0;
+   vgic_v3-vgic_elrsr = ~0;
 
/*
 * If we are emulating a GICv3, we do it in an non-GICv2-compatible
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 78fb820..037b723 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -81,7 +81,6 @@
 #include vgic.h
 
 static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu);
-static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu);
 static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr);
 static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr, struct vgic_lr lr_desc);
 
@@ -649,6 +648,17 @@ bool vgic_handle_cfg_reg(u32 *reg, struct kvm_exit_mmio 
*mmio,
return false;
 }
 
+static void vgic_sync_lr_elrsr(struct kvm_vcpu *vcpu, int lr,
+  struct vgic_lr vlr)
+{
+   vgic_ops-sync_lr_elrsr(vcpu, lr, vlr);
+}
+
+static inline u64 vgic_get_elrsr(struct kvm_vcpu *vcpu)
+{
+   return vgic_ops-get_elrsr(vcpu);
+}
+
 /**
  * vgic_unqueue_irqs - move pending/active IRQs from LRs to the distributor
  * @vgic_cpu: Pointer to the vgic_cpu struct holding the LRs
@@ -660,9 +670,11 @@ bool vgic_handle_cfg_reg(u32 *reg, struct kvm_exit_mmio 
*mmio,
 void vgic_unqueue_irqs(struct kvm_vcpu *vcpu)
 {
struct vgic_cpu *vgic_cpu = vcpu-arch.vgic_cpu;
+   u64 elrsr = vgic_get_elrsr(vcpu);
+   unsigned long *elrsr_ptr = u64_to_bitmask(elrsr);
int i;
 
-   for_each_set_bit(i, vgic_cpu-lr_used, vgic_cpu-nr_lr) {
+   for_each_clear_bit(i, elrsr_ptr, vgic_cpu-nr_lr) {
struct vgic_lr lr = vgic_get_lr(vcpu, i);
 
/*
@@ -705,7 +717,7 @@ void vgic_unqueue_irqs(struct kvm_vcpu *vcpu)
 * Mark the LR as free for other use.
 */
BUG_ON(lr.state  LR_STATE_MASK);
-   vgic_retire_lr(i

[PATCH 13/13] KVM: arm64: enable ITS emulation as a virtual MSI controller

2015-05-29 Thread Andre Przywara
If userspace has provided a base address for the ITS register frame,
we enable the bits that advertise LPIs in the GICv3.
When the guest has enabled LPIs and the ITS, we enable the emulation
part by initializing the ITS data structures and trapping on ITS
register frame accesses by the guest.
Also we enable the KVM_SIGNAL_MSI feature to allow userland to inject
MSIs into the guest. Not having enabled the ITS emulation will lead
to a -ENODEV when trying to inject a MSI.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 Documentation/virtual/kvm/api.txt |  2 +-
 arch/arm64/kvm/Kconfig|  1 +
 include/kvm/arm_vgic.h| 10 ++
 virt/kvm/arm/its-emul.c   |  9 -
 virt/kvm/arm/vgic-v3-emul.c   | 20 +++-
 virt/kvm/arm/vgic.c   | 10 ++
 6 files changed, 45 insertions(+), 7 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index 891d64a..d20fd94 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2108,7 +2108,7 @@ after pausing the vcpu, but before it is resumed.
 4.71 KVM_SIGNAL_MSI
 
 Capability: KVM_CAP_SIGNAL_MSI
-Architectures: x86
+Architectures: x86 arm64
 Type: vm ioctl
 Parameters: struct kvm_msi (in)
 Returns: 0 on delivery, 0 if guest blocked the MSI, and -1 on error
diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index 5105e29..6c432c0 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -30,6 +30,7 @@ config KVM
select SRCU
select HAVE_KVM_EVENTFD
select HAVE_KVM_IRQFD
+   select HAVE_KVM_MSI
---help---
  Support hosting virtualized guest machines.
 
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 6bb138d..8f1be6a 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -162,6 +162,7 @@ struct vgic_io_device {
 
 struct vgic_its {
boolenabled;
+   struct vgic_io_device   iodev;
spinlock_t  lock;
u64 cbaser;
int creadr;
@@ -365,4 +366,13 @@ static inline int vgic_v3_probe(struct device_node 
*vgic_node,
 }
 #endif
 
+#ifdef CONFIG_HAVE_KVM_MSI
+int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi);
+#else
+static inline int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi)
+{
+   return -ENODEV;
+}
+#endif
+
 #endif
diff --git a/virt/kvm/arm/its-emul.c b/virt/kvm/arm/its-emul.c
index 35e886c..864de19 100644
--- a/virt/kvm/arm/its-emul.c
+++ b/virt/kvm/arm/its-emul.c
@@ -964,6 +964,7 @@ int vits_init(struct kvm *kvm)
 {
struct vgic_dist *dist = kvm-arch.vgic;
struct vgic_its *its = dist-its;
+   int ret;
 
if (IS_VGIC_ADDR_UNDEF(dist-vgic_its_base))
return -ENXIO;
@@ -977,9 +978,15 @@ int vits_init(struct kvm *kvm)
INIT_LIST_HEAD(its-device_list);
INIT_LIST_HEAD(its-collection_list);
 
+   ret = vgic_register_kvm_io_dev(kvm, dist-vgic_its_base,
+  KVM_VGIC_V3_ITS_SIZE, vgicv3_its_ranges,
+  -1, its-iodev);
+   if (ret)
+   return ret;
+
its-enabled = false;
 
-   return -ENXIO;
+   return 0;
 }
 
 void vits_destroy(struct kvm *kvm)
diff --git a/virt/kvm/arm/vgic-v3-emul.c b/virt/kvm/arm/vgic-v3-emul.c
index 4513551..71d0bcf 100644
--- a/virt/kvm/arm/vgic-v3-emul.c
+++ b/virt/kvm/arm/vgic-v3-emul.c
@@ -89,10 +89,11 @@ static bool handle_mmio_ctlr(struct kvm_vcpu *vcpu,
 /*
  * As this implementation does not provide compatibility
  * with GICv2 (ARE==1), we report zero CPUs in bits [5..7].
- * Also LPIs and MBIs are not supported, so we set the respective bits to 0.
- * Also we report at most 2**10=1024 interrupt IDs (to match 1024 SPIs).
+ * Also we report at most 2**10=1024 interrupt IDs (to match 1024 SPIs)
+ * and provide 16 bits worth of LPI number space (to give 8192 LPIs).
  */
-#define INTERRUPT_ID_BITS 10
+#define INTERRUPT_ID_BITS_SPIS 10
+#define INTERRUPT_ID_BITS_ITS 16
 static bool handle_mmio_typer(struct kvm_vcpu *vcpu,
  struct kvm_exit_mmio *mmio, phys_addr_t offset)
 {
@@ -100,7 +101,12 @@ static bool handle_mmio_typer(struct kvm_vcpu *vcpu,
 
reg = (min(vcpu-kvm-arch.vgic.nr_irqs, 1024)  5) - 1;
 
-   reg |= (INTERRUPT_ID_BITS - 1)  19;
+   if (vgic_has_its(vcpu-kvm)) {
+   reg |= GICD_TYPER_LPIS;
+   reg |= (INTERRUPT_ID_BITS_ITS - 1)  19;
+   } else {
+   reg |= (INTERRUPT_ID_BITS_SPIS - 1)  19;
+   }
 
vgic_reg_access(mmio, reg, offset,
ACCESS_READ_VALUE | ACCESS_WRITE_IGNORED);
@@ -519,7 +525,9 @@ static bool handle_mmio_ctlr_redist(struct kvm_vcpu *vcpu,
vgic_reg_access(mmio, reg, offset,
ACCESS_READ_VALUE | ACCESS_WRITE_VALUE);
if (!dist-lpis_enabled

[PATCH 10/13] KVM: arm64: sync LPI properties and status between guest and KVM

2015-05-29 Thread Andre Przywara
The properties and status of the GICv3 LPIs are hold in tables in
(guest) memory. To achieve reasonable performance, we cache this
data in our own data structures, so we need to sync those two views
from time to time. This behaviour is well described in the GICv3 spec
and is also exercised by hardware, so the sync points are well known.

Provide functions that read the guest memory and store the
information from the property and status table in the kernel.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 virt/kvm/arm/its-emul.c | 140 
 1 file changed, 140 insertions(+)

diff --git a/virt/kvm/arm/its-emul.c b/virt/kvm/arm/its-emul.c
index f75fb9e..afd440e 100644
--- a/virt/kvm/arm/its-emul.c
+++ b/virt/kvm/arm/its-emul.c
@@ -50,6 +50,7 @@ struct its_itte {
struct its_collection *collection;
u32 lpi;
u32 event_id;
+   u8 priority;
bool enabled;
unsigned long *pending;
 };
@@ -70,7 +71,140 @@ static struct its_itte *find_itte_by_lpi(struct kvm *kvm, 
int lpi)
return NULL;
 }
 
+#define LPI_PROP_ENABLE_BIT(p) ((p)  LPI_PROP_ENABLED)
+#define LPI_PROP_PRIORITY(p)   ((p)  0xfc)
+
+/* stores the priority and enable bit for a given LPI */
+static void update_lpi_property(struct kvm *kvm, struct its_itte *itte, u8 
prop)
+{
+   itte-priority = LPI_PROP_PRIORITY(prop);
+   itte-enabled  = LPI_PROP_ENABLE_BIT(prop);
+}
+
+#define GIC_LPI_OFFSET 8192
+
+/* We scan the table in chunks the size of the smallest page size */
+#define CHUNK_SIZE 4096U
+
 #define BASER_BASE_ADDRESS(x) ((x)  0xf000ULL)
+#define PROPBASE_TSIZE(x) (1U  (x  0x1f))
+
+/*
+ * Scan the whole LPI property table and put the LPI configuration
+ * data in our own data structures. This relies on the LPI being
+ * mapped before.
+ * We scan from two sides:
+ * 1) for each byte in the table we care for the ones being enabled
+ * 2) for each mapped LPI we look into the table to spot LPIs being disabled
+ * Must be called with the ITS lock held.
+ */
+static bool its_update_lpi_properties(struct kvm *kvm)
+{
+   struct vgic_dist *dist = kvm-arch.vgic;
+   u8 *prop;
+   u32 tsize;
+   gpa_t propbase;
+   int lpi = GIC_LPI_OFFSET;
+   struct its_itte *itte;
+   struct its_device *device;
+   int ret;
+
+   propbase = BASER_BASE_ADDRESS(dist-propbaser);
+   tsize = PROPBASE_TSIZE(dist-propbaser);
+
+   prop = kmalloc(CHUNK_SIZE, GFP_KERNEL);
+   if (!prop)
+   return false;
+
+   while (tsize  0) {
+   int chunksize = min(tsize, CHUNK_SIZE);
+
+   ret = kvm_read_guest(kvm, propbase, prop, chunksize);
+   if (ret) {
+   kfree(prop);
+   break;
+   }
+
+   /*
+* Updating the status for all allocated LPIs. We catch
+* those LPIs that get disabled. We really don't care
+* about unmapped LPIs, as they need to be updated
+* later manually anyway once they get mapped.
+*/
+   for_each_lpi(device, itte, kvm) {
+   /*
+* Is the LPI covered by that part of the table we
+* are currently looking at?
+*/
+   if (itte-lpi  lpi)
+   continue;
+   if (itte-lpi = lpi + chunksize)
+   continue;
+
+   update_lpi_property(kvm, itte,
+   prop[itte-lpi - lpi]);
+   }
+   tsize -= chunksize;
+   lpi += chunksize;
+   propbase += chunksize;
+   }
+
+   kfree(prop);
+   return true;
+}
+
+/*
+ * Scan the whole LPI pending table and sync the pending bit in there
+ * with our own data structures. This relies on the LPI being
+ * mapped before.
+ * Must be called with the ITS lock held.
+ */
+static bool its_sync_lpi_pending_table(struct kvm_vcpu *vcpu)
+{
+   struct vgic_dist *dist = vcpu-kvm-arch.vgic;
+   unsigned long *pendmask;
+   u32 nr_lpis;
+   gpa_t pendbase;
+   int lpi = GIC_LPI_OFFSET;
+   struct its_itte *itte;
+   struct its_device *device;
+   int ret;
+   int lpi_bit, nr_bits;
+
+   pendbase = BASER_BASE_ADDRESS(dist-pendbaser[vcpu-vcpu_id]);
+   nr_lpis = GIC_LPI_OFFSET;
+
+   pendmask = kmalloc(CHUNK_SIZE, GFP_KERNEL);
+   if (!pendmask)
+   return false;
+
+   while (nr_lpis  0) {
+   nr_bits = min(nr_lpis, CHUNK_SIZE * 8);
+
+   ret = kvm_read_guest(vcpu-kvm, pendbase, pendmask,
+nr_bits / 8);
+   if (ret)
+   break;
+
+   for_each_lpi(device, itte, vcpu-kvm) {
+   lpi_bit = itte-lpi - lpi

[PATCH 06/13] KVM: arm64: introduce ITS emulation file with stub functions

2015-05-29 Thread Andre Przywara
The ARM GICv3 ITS emulation code goes into a separate file, but
needs to be connected to the GICv3 emulation, of which it is an
option.
Introduce the skeletton with function stubs to be filled later.
Introduce the basic ITS data structure and initialize it, but don't
return any success yet, as we are not yet ready for the show.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 arch/arm64/kvm/Makefile|   1 +
 include/kvm/arm_vgic.h |   6 ++
 include/linux/irqchip/arm-gic-v3.h |   1 +
 virt/kvm/arm/its-emul.c| 127 +
 virt/kvm/arm/its-emul.h|  35 ++
 virt/kvm/arm/vgic-v3-emul.c|  22 ++-
 6 files changed, 189 insertions(+), 3 deletions(-)
 create mode 100644 virt/kvm/arm/its-emul.c
 create mode 100644 virt/kvm/arm/its-emul.h

diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index d5904f8..0d09189 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -25,5 +25,6 @@ kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic-v2-emul.o
 kvm-$(CONFIG_KVM_ARM_HOST) += vgic-v2-switch.o
 kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic-v3.o
 kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic-v3-emul.o
+kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/its-emul.o
 kvm-$(CONFIG_KVM_ARM_HOST) += vgic-v3-switch.o
 kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/arch_timer.o
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 9ea0b3b..d76c2d9 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -156,6 +156,11 @@ struct vgic_io_device {
struct kvm_io_device dev;
 };
 
+struct vgic_its {
+   boolenabled;
+   spinlock_t  lock;
+};
+
 struct vgic_dist {
spinlock_t  lock;
boolin_kernel;
@@ -260,6 +265,7 @@ struct vgic_dist {
u64 propbaser;
u64 *pendbaser;
boollpis_enabled;
+   struct vgic_its its;
 };
 
 struct vgic_v2_cpu_if {
diff --git a/include/linux/irqchip/arm-gic-v3.h 
b/include/linux/irqchip/arm-gic-v3.h
index ffbc034..df4e527 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -177,6 +177,7 @@
 #define GITS_CWRITER   0x0088
 #define GITS_CREADR0x0090
 #define GITS_BASER 0x0100
+#define GITS_IDREGS_BASE   0xffd0
 #define GITS_PIDR2 GICR_PIDR2
 
 #define GITS_TRANSLATER0x10040
diff --git a/virt/kvm/arm/its-emul.c b/virt/kvm/arm/its-emul.c
new file mode 100644
index 000..7b283ce
--- /dev/null
+++ b/virt/kvm/arm/its-emul.c
@@ -0,0 +1,127 @@
+/*
+ * GICv3 ITS emulation
+ *
+ * Copyright (C) 2015 ARM Ltd.
+ * Author: Andre Przywara andre.przyw...@arm.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see http://www.gnu.org/licenses/.
+ */
+
+#include linux/cpu.h
+#include linux/kvm.h
+#include linux/kvm_host.h
+#include linux/interrupt.h
+
+#include linux/irqchip/arm-gic-v3.h
+#include kvm/arm_vgic.h
+
+#include asm/kvm_emulate.h
+#include asm/kvm_arm.h
+#include asm/kvm_mmu.h
+
+#include vgic.h
+#include its-emul.h
+
+static bool handle_mmio_misc_gits(struct kvm_vcpu *vcpu,
+ struct kvm_exit_mmio *mmio,
+ phys_addr_t offset)
+{
+   return false;
+}
+
+static bool handle_mmio_gits_idregs(struct kvm_vcpu *vcpu,
+   struct kvm_exit_mmio *mmio,
+   phys_addr_t offset)
+{
+   return false;
+}
+
+static bool handle_mmio_gits_cbaser(struct kvm_vcpu *vcpu,
+   struct kvm_exit_mmio *mmio,
+   phys_addr_t offset)
+{
+   return false;
+}
+
+static bool handle_mmio_gits_cwriter(struct kvm_vcpu *vcpu,
+struct kvm_exit_mmio *mmio,
+phys_addr_t offset)
+{
+   return false;
+}
+
+static bool handle_mmio_gits_creadr(struct kvm_vcpu *vcpu,
+   struct kvm_exit_mmio *mmio,
+   phys_addr_t offset)
+{
+   return false;
+}
+
+static const struct vgic_io_range vgicv3_its_ranges[] = {
+   {
+   .base   = GITS_CTLR,
+   .len= 0x10,
+   .bits_per_irq   = 0

[PATCH 09/13] KVM: arm64: handle pending bit for LPIs in ITS emulation

2015-05-29 Thread Andre Przywara
As the actual LPI number in a guest can be quite high, but is mostly
assigned using a very sparse allocation scheme, bitmaps and arrays
for storing the virtual interrupt status are a waste of memory.
We use our equivalent of the Interrupt Translation Table Entry
(ITTE) to hold this extra status information for a virtual LPI.
As the normal VGIC code cannot use it's fancy bitmaps to manage
pending interrupts, we provide a hook in the VGIC code to let the
ITS emulation handle the list register queueing itself.
LPIs are located in a separate number range (=8192), so
distinguishing them is easy. With LPIs being only edge-triggered, we
get away with a less complex IRQ handling.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 include/kvm/arm_vgic.h  |  2 ++
 virt/kvm/arm/its-emul.c | 66 +++
 virt/kvm/arm/its-emul.h |  3 ++
 virt/kvm/arm/vgic-v3-emul.c |  2 ++
 virt/kvm/arm/vgic.c | 68 +
 5 files changed, 124 insertions(+), 17 deletions(-)

diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index fa17df6..de19c34 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -147,6 +147,8 @@ struct vgic_vm_ops {
int (*init_model)(struct kvm *);
void(*destroy_model)(struct kvm *);
int (*map_resources)(struct kvm *, const struct vgic_params *);
+   bool(*queue_lpis)(struct kvm_vcpu *);
+   void(*unqueue_lpi)(struct kvm_vcpu *, int irq);
 };
 
 struct vgic_io_device {
diff --git a/virt/kvm/arm/its-emul.c b/virt/kvm/arm/its-emul.c
index f0f4a9c..f75fb9e 100644
--- a/virt/kvm/arm/its-emul.c
+++ b/virt/kvm/arm/its-emul.c
@@ -50,8 +50,26 @@ struct its_itte {
struct its_collection *collection;
u32 lpi;
u32 event_id;
+   bool enabled;
+   unsigned long *pending;
 };
 
+#define for_each_lpi(dev, itte, kvm) \
+   list_for_each_entry(dev, (kvm)-arch.vgic.its.device_list, dev_list) \
+   list_for_each_entry(itte, (dev)-itt, itte_list)
+
+static struct its_itte *find_itte_by_lpi(struct kvm *kvm, int lpi)
+{
+   struct its_device *device;
+   struct its_itte *itte;
+
+   for_each_lpi(device, itte, kvm) {
+   if (itte-lpi == lpi)
+   return itte;
+   }
+   return NULL;
+}
+
 #define BASER_BASE_ADDRESS(x) ((x)  0xf000ULL)
 
 /* distributor lock is hold by the VGIC MMIO handler */
@@ -145,6 +163,54 @@ static bool handle_mmio_gits_idregs(struct kvm_vcpu *vcpu,
return false;
 }
 
+/*
+ * Find all enabled and pending LPIs and queue them into the list
+ * registers.
+ * The dist lock is held by the caller.
+ */
+bool vits_queue_lpis(struct kvm_vcpu *vcpu)
+{
+   struct vgic_its *its = vcpu-kvm-arch.vgic.its;
+   struct its_device *device;
+   struct its_itte *itte;
+   bool ret = true;
+
+   spin_lock(its-lock);
+   for_each_lpi(device, itte, vcpu-kvm) {
+   if (!itte-enabled || !test_bit(vcpu-vcpu_id, itte-pending))
+   continue;
+
+   if (!itte-collection)
+   continue;
+
+   if (itte-collection-target_addr != vcpu-vcpu_id)
+   continue;
+
+   clear_bit(vcpu-vcpu_id, itte-pending);
+
+   ret = vgic_queue_irq(vcpu, 0, itte-lpi);
+   }
+
+   spin_unlock(its-lock);
+   return ret;
+}
+
+/* is called with the distributor lock held by the caller */
+void vits_unqueue_lpi(struct kvm_vcpu *vcpu, int lpi)
+{
+   struct vgic_its *its = vcpu-kvm-arch.vgic.its;
+   struct its_itte *itte;
+
+   spin_lock(its-lock);
+
+   /* Find the right ITTE and put the pending state back in there */
+   itte = find_itte_by_lpi(vcpu-kvm, lpi);
+   if (itte)
+   set_bit(vcpu-vcpu_id, itte-pending);
+
+   spin_unlock(its-lock);
+}
+
 static int vits_handle_command(struct kvm_vcpu *vcpu, u64 *its_cmd)
 {
return -ENODEV;
diff --git a/virt/kvm/arm/its-emul.h b/virt/kvm/arm/its-emul.h
index 472a6d0..cc5d5ff 100644
--- a/virt/kvm/arm/its-emul.h
+++ b/virt/kvm/arm/its-emul.h
@@ -33,4 +33,7 @@ void vgic_enable_lpis(struct kvm_vcpu *vcpu);
 int vits_init(struct kvm *kvm);
 void vits_destroy(struct kvm *kvm);
 
+bool vits_queue_lpis(struct kvm_vcpu *vcpu);
+void vits_unqueue_lpi(struct kvm_vcpu *vcpu, int irq);
+
 #endif
diff --git a/virt/kvm/arm/vgic-v3-emul.c b/virt/kvm/arm/vgic-v3-emul.c
index fa81c4b..66640c2fa 100644
--- a/virt/kvm/arm/vgic-v3-emul.c
+++ b/virt/kvm/arm/vgic-v3-emul.c
@@ -901,6 +901,8 @@ void vgic_v3_init_emulation(struct kvm *kvm)
dist-vm_ops.init_model = vgic_v3_init_model;
dist-vm_ops.destroy_model = vgic_v3_destroy_model;
dist-vm_ops.map_resources = vgic_v3_map_resources;
+   dist-vm_ops.queue_lpis = vits_queue_lpis;
+   dist-vm_ops.unqueue_lpi = vits_unqueue_lpi;
 
kvm-arch.max_vcpus = KVM_MAX_VCPUS;
 }
diff

[PATCH 05/13] KVM: arm64: handle ITS related GICv3 redistributor registers

2015-05-29 Thread Andre Przywara
In the GICv3 redistributor there are the PENDBASER and PROPBASER
registers which we did not emulate so far, as they only make sense
when having an ITS. In preparation for that emulate those MMIO
accesses by storing the 64-bit data written into it into a variable
which we later read in the ITS emulation.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 include/kvm/arm_vgic.h  |  4 
 virt/kvm/arm/vgic-v3-emul.c | 43 +++
 virt/kvm/arm/vgic.c | 35 +++
 virt/kvm/arm/vgic.h |  4 
 4 files changed, 86 insertions(+)

diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 37725bb..9ea0b3b 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -256,6 +256,10 @@ struct vgic_dist {
struct vgic_vm_ops  vm_ops;
struct vgic_io_device   dist_iodev;
struct vgic_io_device   *redist_iodevs;
+
+   u64 propbaser;
+   u64 *pendbaser;
+   boollpis_enabled;
 };
 
 struct vgic_v2_cpu_if {
diff --git a/virt/kvm/arm/vgic-v3-emul.c b/virt/kvm/arm/vgic-v3-emul.c
index 16c6d8a..04f3aed 100644
--- a/virt/kvm/arm/vgic-v3-emul.c
+++ b/virt/kvm/arm/vgic-v3-emul.c
@@ -607,6 +607,37 @@ static bool handle_mmio_cfg_reg_redist(struct kvm_vcpu 
*vcpu,
return vgic_handle_cfg_reg(reg, mmio, offset);
 }
 
+/* We don't trigger any actions here, just store the register value */
+static bool handle_mmio_propbaser_redist(struct kvm_vcpu *vcpu,
+struct kvm_exit_mmio *mmio,
+phys_addr_t offset)
+{
+   struct vgic_dist *dist = vcpu-kvm-arch.vgic;
+   int mode = ACCESS_READ_VALUE;
+
+   mode |= dist-lpis_enabled ? ACCESS_WRITE_IGNORED : ACCESS_WRITE_VALUE;
+   vgic_handle_base_register(vcpu, mmio, offset, dist-propbaser, mode);
+
+   return false;
+}
+
+/* We don't trigger any actions here, just store the register value */
+static bool handle_mmio_pendbaser_redist(struct kvm_vcpu *vcpu,
+struct kvm_exit_mmio *mmio,
+phys_addr_t offset)
+{
+   struct kvm_vcpu *rdvcpu = mmio-private;
+   struct vgic_dist *dist = vcpu-kvm-arch.vgic;
+   int mode = ACCESS_READ_VALUE;
+
+   /* Storing a value with LPIs already enabled is undefined */
+   mode |= dist-lpis_enabled ? ACCESS_WRITE_IGNORED : ACCESS_WRITE_VALUE;
+   vgic_handle_base_register(vcpu, mmio, offset,
+ dist-pendbaser[rdvcpu-vcpu_id], mode);
+
+   return false;
+}
+
 #define SGI_base(x) ((x) + SZ_64K)
 
 static const struct vgic_io_range vgic_redist_ranges[] = {
@@ -635,6 +666,18 @@ static const struct vgic_io_range vgic_redist_ranges[] = {
.handle_mmio= handle_mmio_raz_wi,
},
{
+   .base   = GICR_PENDBASER,
+   .len= 0x08,
+   .bits_per_irq   = 0,
+   .handle_mmio= handle_mmio_pendbaser_redist,
+   },
+   {
+   .base   = GICR_PROPBASER,
+   .len= 0x08,
+   .bits_per_irq   = 0,
+   .handle_mmio= handle_mmio_propbaser_redist,
+   },
+   {
.base   = GICR_IDREGS,
.len= 0x30,
.bits_per_irq   = 0,
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 2e9723aa..0a9236d 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -448,6 +448,41 @@ void vgic_reg_access(struct kvm_exit_mmio *mmio, u32 *reg,
}
 }
 
+/* handle a 64-bit register access */
+void vgic_handle_base_register(struct kvm_vcpu *vcpu,
+  struct kvm_exit_mmio *mmio,
+  phys_addr_t offset, u64 *basereg,
+  int mode)
+{
+   u32 reg;
+   u64 breg;
+
+   switch (offset  ~3) {
+   case 0x00:
+   breg = *basereg;
+   reg = lower_32_bits(breg);
+   vgic_reg_access(mmio, reg, offset  3, mode);
+   if (mmio-is_write  (mode  ACCESS_WRITE_VALUE)) {
+   breg = GENMASK_ULL(63, 32);
+   breg |= reg;
+   *basereg = breg;
+   }
+   break;
+   case 0x04:
+   breg = *basereg;
+   reg = upper_32_bits(breg);
+   vgic_reg_access(mmio, reg, offset  3, mode);
+   if (mmio-is_write  (mode  ACCESS_WRITE_VALUE)) {
+   breg  = lower_32_bits(breg);
+   breg |= (u64)reg  32;
+   *basereg = breg;
+   }
+   break;
+   }
+}
+
+
+
 bool handle_mmio_raz_wi(struct kvm_vcpu *vcpu, struct kvm_exit_mmio *mmio,
phys_addr_t offset)
 {
diff --git

<    1   2   3   4   5   6   7   >