Re: [PATCH] KVM: arm64: add gic-400 compatible

2015-04-02 Thread AKASHI Takahiro

Ping.
This patch was acked but has never been merged?

-Takahiro AKASHI

On 09/09/2014 07:21 AM, Joel Schopp wrote:

Add a one liner to identify the gic-400.  It's gicv2 with optional MSI 
extensions.

Cc: Christoffer Dall christoffer.d...@linaro.org
Signed-off-by: Joel Schopp joel.sch...@amd.com
---
  virt/kvm/arm/vgic.c |1 +
  1 file changed, 1 insertion(+)

diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 73eba79..e81444e 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -1550,6 +1550,7 @@ static struct notifier_block vgic_cpu_nb = {

  static const struct of_device_id vgic_ids[] = {
{ .compatible = arm,cortex-a15-gic, .data = vgic_v2_probe, },
+   { .compatible = arm,gic-400, .data = vgic_v2_probe, },
{ .compatible = arm,gic-v3, .data = vgic_v3_probe, },
{},
  };


___
linux-arm-kernel mailing list
linux-arm-ker...@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


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


[PATCH 14/27] arm/arm64: KVM: support for un-queuing active IRQs

2015-04-02 Thread Marc Zyngier
From: Christoffer Dall christoffer.d...@linaro.org

Migrating active interrupts causes the active state to be lost
completely. This implements some additional bitmaps to track the active
state on the distributor and export this to user space.

Signed-off-by: Christoffer Dall christoffer.d...@linaro.org
Signed-off-by: Alex Bennée alex.ben...@linaro.org
Signed-off-by: Christoffer Dall christoffer.d...@linaro.org
---
 include/kvm/arm_vgic.h  |  15 +++-
 virt/kvm/arm/vgic-v2-emul.c |  20 -
 virt/kvm/arm/vgic.c | 207 
 virt/kvm/arm/vgic.h |   8 ++
 4 files changed, 212 insertions(+), 38 deletions(-)

diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index b81630b..9092fad 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -195,6 +195,9 @@ struct vgic_dist {
/* Level-triggered interrupt queued on VCPU interface */
struct vgic_bitmap  irq_queued;
 
+   /* Interrupt was active when unqueue from VCPU interface */
+   struct vgic_bitmap  irq_active;
+
/* Interrupt priority. Not used yet. */
struct vgic_bytemap irq_priority;
 
@@ -235,6 +238,9 @@ struct vgic_dist {
/* Bitmap indicating which CPU has something pending */
unsigned long   *irq_pending_on_cpu;
 
+   /* Bitmap indicating which CPU has active IRQs */
+   unsigned long   *irq_active_on_cpu;
+
struct vgic_vm_ops  vm_ops;
 };
 
@@ -266,9 +272,15 @@ struct vgic_cpu {
/* per IRQ to LR mapping */
u8  *vgic_irq_lr_map;
 
-   /* Pending interrupts on this VCPU */
+   /* Pending/active/both interrupts on this VCPU */
DECLARE_BITMAP( pending_percpu, VGIC_NR_PRIVATE_IRQS);
+   DECLARE_BITMAP( active_percpu, VGIC_NR_PRIVATE_IRQS);
+   DECLARE_BITMAP( pend_act_percpu, VGIC_NR_PRIVATE_IRQS);
+
+   /* Pending/active/both shared interrupts, dynamically sized */
unsigned long   *pending_shared;
+   unsigned long   *active_shared;
+   unsigned long   *pend_act_shared;
 
/* Bitmap of used/free list registers */
DECLARE_BITMAP( lr_used, VGIC_V2_MAX_LRS);
@@ -306,6 +318,7 @@ int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, 
unsigned int irq_num,
bool level);
 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);
 bool vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run,
  struct kvm_exit_mmio *mmio);
 
diff --git a/virt/kvm/arm/vgic-v2-emul.c b/virt/kvm/arm/vgic-v2-emul.c
index 19c6210..c818662 100644
--- a/virt/kvm/arm/vgic-v2-emul.c
+++ b/virt/kvm/arm/vgic-v2-emul.c
@@ -107,6 +107,22 @@ static bool handle_mmio_clear_pending_reg(struct kvm_vcpu 
*vcpu,
 vcpu-vcpu_id);
 }
 
+static bool handle_mmio_set_active_reg(struct kvm_vcpu *vcpu,
+  struct kvm_exit_mmio *mmio,
+  phys_addr_t offset)
+{
+   return vgic_handle_set_active_reg(vcpu-kvm, mmio, offset,
+ vcpu-vcpu_id);
+}
+
+static bool handle_mmio_clear_active_reg(struct kvm_vcpu *vcpu,
+struct kvm_exit_mmio *mmio,
+phys_addr_t offset)
+{
+   return vgic_handle_clear_active_reg(vcpu-kvm, mmio, offset,
+   vcpu-vcpu_id);
+}
+
 static bool handle_mmio_priority_reg(struct kvm_vcpu *vcpu,
 struct kvm_exit_mmio *mmio,
 phys_addr_t offset)
@@ -344,13 +360,13 @@ static const struct kvm_mmio_range vgic_dist_ranges[] = {
.base   = GIC_DIST_ACTIVE_SET,
.len= VGIC_MAX_IRQS / 8,
.bits_per_irq   = 1,
-   .handle_mmio= handle_mmio_raz_wi,
+   .handle_mmio= handle_mmio_set_active_reg,
},
{
.base   = GIC_DIST_ACTIVE_CLEAR,
.len= VGIC_MAX_IRQS / 8,
.bits_per_irq   = 1,
-   .handle_mmio= handle_mmio_raz_wi,
+   .handle_mmio= handle_mmio_clear_active_reg,
},
{
.base   = GIC_DIST_PRI,
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 697ce17..ffd937c 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -264,6 +264,13 @@ static int vgic_irq_is_queued(struct kvm_vcpu *vcpu, int 
irq)
return vgic_bitmap_get_irq_val(dist-irq_queued, vcpu-vcpu_id, irq);
 }
 
+static int vgic_irq_is_active(struct kvm_vcpu *vcpu, int irq)
+{
+   struct vgic_dist *dist = vcpu-kvm-arch.vgic;
+
+   return vgic_bitmap_get_irq_val(dist-irq_active, vcpu-vcpu_id, irq);
+}
+
 static void 

[PATCH 21/27] KVM: arm/arm64: simplify vgic_find_range() and callers

2015-04-02 Thread Marc Zyngier
From: Andre Przywara andre.przyw...@arm.com

The vgic_find_range() function in vgic.c takes a struct kvm_exit_mmio
argument, but actually only used the length field in there. Since we
need to get rid of that structure in that part of the code anyway,
let's rework the function (and it's callers) to pass the length
argument to the function directly.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
Reviewed-by: Christoffer Dall christoffer.d...@linaro.org
Reviewed-by: Marc Zyngier marc.zyng...@arm.com
Signed-off-by: Marc Zyngier marc.zyng...@arm.com
---
 virt/kvm/arm/vgic-v2-emul.c |  2 +-
 virt/kvm/arm/vgic.c | 22 --
 virt/kvm/arm/vgic.h |  3 +--
 3 files changed, 10 insertions(+), 17 deletions(-)

diff --git a/virt/kvm/arm/vgic-v2-emul.c b/virt/kvm/arm/vgic-v2-emul.c
index ddb3135..1dd183e 100644
--- a/virt/kvm/arm/vgic-v2-emul.c
+++ b/virt/kvm/arm/vgic-v2-emul.c
@@ -715,7 +715,7 @@ static int vgic_attr_regs_access(struct kvm_device *dev,
default:
BUG();
}
-   r = vgic_find_range(ranges, mmio, offset);
+   r = vgic_find_range(ranges, 4, offset);
 
if (unlikely(!r || !r-handle_mmio)) {
ret = -ENXIO;
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 21a3550..8802ad7 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -713,16 +713,13 @@ void vgic_unqueue_irqs(struct kvm_vcpu *vcpu)
 
 const
 struct vgic_io_range *vgic_find_range(const struct vgic_io_range *ranges,
- struct kvm_exit_mmio *mmio,
- phys_addr_t offset)
+ int len, gpa_t offset)
 {
-   const struct vgic_io_range *r = ranges;
-
-   while (r-len) {
-   if (offset = r-base 
-   (offset + mmio-len) = (r-base + r-len))
-   return r;
-   r++;
+   while (ranges-len) {
+   if (offset = ranges-base 
+   (offset + len) = (ranges-base + ranges-len))
+   return ranges;
+   ranges++;
}
 
return NULL;
@@ -813,7 +810,7 @@ bool vgic_handle_mmio_range(struct kvm_vcpu *vcpu, struct 
kvm_run *run,
unsigned long offset;
 
offset = mmio-phys_addr - mmio_base;
-   range = vgic_find_range(ranges, mmio, offset);
+   range = vgic_find_range(ranges, mmio-len, offset);
if (unlikely(!range || !range-handle_mmio)) {
pr_warn(Unhandled access %d %08llx %d\n,
mmio-is_write, mmio-phys_addr, mmio-len);
@@ -1986,10 +1983,7 @@ int vgic_get_common_attr(struct kvm_device *dev, struct 
kvm_device_attr *attr)
 
 int vgic_has_attr_regs(const struct vgic_io_range *ranges, phys_addr_t offset)
 {
-   struct kvm_exit_mmio dev_attr_mmio;
-
-   dev_attr_mmio.len = 4;
-   if (vgic_find_range(ranges, dev_attr_mmio, offset))
+   if (vgic_find_range(ranges, 4, offset))
return 0;
else
return -ENXIO;
diff --git a/virt/kvm/arm/vgic.h b/virt/kvm/arm/vgic.h
index 6fccb96..01aa622 100644
--- a/virt/kvm/arm/vgic.h
+++ b/virt/kvm/arm/vgic.h
@@ -90,8 +90,7 @@ static inline bool is_in_range(phys_addr_t addr, unsigned 
long len,
 
 const
 struct vgic_io_range *vgic_find_range(const struct vgic_io_range *ranges,
- struct kvm_exit_mmio *mmio,
- phys_addr_t offset);
+ int len, gpa_t offset);
 
 bool vgic_handle_mmio_range(struct kvm_vcpu *vcpu, struct kvm_run *run,
struct kvm_exit_mmio *mmio,
-- 
2.1.4

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


[PATCH 15/27] arm/arm64: KVM: Fix migration race in the arch timer

2015-04-02 Thread Marc Zyngier
From: Christoffer Dall christoffer.d...@linaro.org

When a VCPU is no longer running, we currently check to see if it has a
timer scheduled in the future, and if it does, we schedule a host
hrtimer to notify is in case the timer expires while the VCPU is still
not running.  When the hrtimer fires, we mask the guest's timer and
inject the timer IRQ (still relying on the guest unmasking the time when
it receives the IRQ).

This is all good and fine, but when migration a VM (checkpoint/restore)
this introduces a race.  It is unlikely, but possible, for the following
sequence of events to happen:

 1. Userspace stops the VM
 2. Hrtimer for VCPU is scheduled
 3. Userspace checkpoints the VGIC state (no pending timer interrupts)
 4. The hrtimer fires, schedules work in a workqueue
 5. Workqueue function runs, masks the timer and injects timer interrupt
 6. Userspace checkpoints the timer state (timer masked)

At restore time, you end up with a masked timer without any timer
interrupts and your guest halts never receiving timer interrupts.

Fix this by only kicking the VCPU in the workqueue function, and sample
the expired state of the timer when entering the guest again and inject
the interrupt and mask the timer only then.

Signed-off-by: Christoffer Dall christoffer.d...@linaro.org
Signed-off-by: Alex Bennée alex.ben...@linaro.org
Signed-off-by: Christoffer Dall christoffer.d...@linaro.org
---
 arch/arm/kvm/arm.c   |  2 +-
 include/kvm/arm_arch_timer.h |  2 ++
 virt/kvm/arm/arch_timer.c| 45 +++-
 3 files changed, 39 insertions(+), 10 deletions(-)

diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 9a5f057..e98370c 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -266,7 +266,7 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
 
 int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
 {
-   return 0;
+   return kvm_timer_should_fire(vcpu);
 }
 
 int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
index a74e4c2..e596675 100644
--- a/include/kvm/arm_arch_timer.h
+++ b/include/kvm/arm_arch_timer.h
@@ -67,4 +67,6 @@ void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu);
 u64 kvm_arm_timer_get_reg(struct kvm_vcpu *, u64 regid);
 int kvm_arm_timer_set_reg(struct kvm_vcpu *, u64 regid, u64 value);
 
+bool kvm_timer_should_fire(struct kvm_vcpu *vcpu);
+
 #endif
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index 6e54f35..98c95f2 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -85,13 +85,22 @@ static irqreturn_t kvm_arch_timer_handler(int irq, void 
*dev_id)
return IRQ_HANDLED;
 }
 
+/*
+ * Work function for handling the backup timer that we schedule when a vcpu is
+ * no longer running, but had a timer programmed to fire in the future.
+ */
 static void kvm_timer_inject_irq_work(struct work_struct *work)
 {
struct kvm_vcpu *vcpu;
 
vcpu = container_of(work, struct kvm_vcpu, arch.timer_cpu.expired);
vcpu-arch.timer_cpu.armed = false;
-   kvm_timer_inject_irq(vcpu);
+
+   /*
+* If the vcpu is blocked we want to wake it up so that it will see
+* the timer has expired when entering the guest.
+*/
+   kvm_vcpu_kick(vcpu);
 }
 
 static enum hrtimer_restart kvm_timer_expire(struct hrtimer *hrt)
@@ -102,6 +111,21 @@ static enum hrtimer_restart kvm_timer_expire(struct 
hrtimer *hrt)
return HRTIMER_NORESTART;
 }
 
+bool kvm_timer_should_fire(struct kvm_vcpu *vcpu)
+{
+   struct arch_timer_cpu *timer = vcpu-arch.timer_cpu;
+   cycle_t cval, now;
+
+   if ((timer-cntv_ctl  ARCH_TIMER_CTRL_IT_MASK) ||
+   !(timer-cntv_ctl  ARCH_TIMER_CTRL_ENABLE))
+   return false;
+
+   cval = timer-cntv_cval;
+   now = kvm_phys_timer_read() - vcpu-kvm-arch.timer.cntvoff;
+
+   return cval = now;
+}
+
 /**
  * kvm_timer_flush_hwstate - prepare to move the virt timer to the cpu
  * @vcpu: The vcpu pointer
@@ -119,6 +143,13 @@ void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu)
 * populate the CPU timer again.
 */
timer_disarm(timer);
+
+   /*
+* If the timer expired while we were not scheduled, now is the time
+* to inject it.
+*/
+   if (kvm_timer_should_fire(vcpu))
+   kvm_timer_inject_irq(vcpu);
 }
 
 /**
@@ -134,16 +165,9 @@ void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu)
cycle_t cval, now;
u64 ns;
 
-   if ((timer-cntv_ctl  ARCH_TIMER_CTRL_IT_MASK) ||
-   !(timer-cntv_ctl  ARCH_TIMER_CTRL_ENABLE))
-   return;
-
-   cval = timer-cntv_cval;
-   now = kvm_phys_timer_read() - vcpu-kvm-arch.timer.cntvoff;
-
BUG_ON(timer_is_armed(timer));
 
-   if (cval = now) {
+   if (kvm_timer_should_fire(vcpu)) {
/*
 * Timer has already expired while we were not
 * 

[PATCH 22/27] KVM: arm/arm64: implement kvm_io_bus MMIO handling for the VGIC

2015-04-02 Thread Marc Zyngier
From: Andre Przywara andre.przyw...@arm.com

Currently we use a lot of VGIC specific code to do the MMIO
dispatching.
Use the previous reworks to add kvm_io_bus style MMIO handlers.

Those are not yet called by the MMIO abort handler, also the actual
VGIC emulator function do not make use of it yet, but will be enabled
with the following patches.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
Reviewed-by: Marc Zyngier marc.zyng...@arm.com
Signed-off-by: Marc Zyngier marc.zyng...@arm.com
---
 include/kvm/arm_vgic.h |   9 
 virt/kvm/arm/vgic.c| 129 +
 virt/kvm/arm/vgic.h|   7 +++
 3 files changed, 145 insertions(+)

diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 9092fad..f90140c 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -24,6 +24,7 @@
 #include linux/irqreturn.h
 #include linux/spinlock.h
 #include linux/types.h
+#include kvm/iodev.h
 
 #define VGIC_NR_IRQS_LEGACY256
 #define VGIC_NR_SGIS   16
@@ -147,6 +148,14 @@ struct vgic_vm_ops {
int (*map_resources)(struct kvm *, const struct vgic_params *);
 };
 
+struct vgic_io_device {
+   gpa_t addr;
+   int len;
+   const struct vgic_io_range *reg_ranges;
+   struct kvm_vcpu *redist_vcpu;
+   struct kvm_io_device dev;
+};
+
 struct vgic_dist {
spinlock_t  lock;
boolin_kernel;
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 8802ad7..e968179 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -32,6 +32,8 @@
 #include asm/kvm_arm.h
 #include asm/kvm_mmu.h
 #include trace/events/kvm.h
+#include asm/kvm.h
+#include kvm/iodev.h
 
 /*
  * How the whole thing works (courtesy of Christoffer Dall):
@@ -837,6 +839,66 @@ bool vgic_handle_mmio_range(struct kvm_vcpu *vcpu, struct 
kvm_run *run,
 }
 
 /**
+ * vgic_handle_mmio_access - handle an in-kernel MMIO access
+ * This is called by the read/write KVM IO device wrappers below.
+ * @vcpu:  pointer to the vcpu performing the access
+ * @this:  pointer to the KVM IO device in charge
+ * @addr:  guest physical address of the access
+ * @len:   size of the access
+ * @val:   pointer to the data region
+ * @is_write:  read or write access
+ *
+ * returns true if the MMIO access could be performed
+ */
+static int vgic_handle_mmio_access(struct kvm_vcpu *vcpu,
+  struct kvm_io_device *this, gpa_t addr,
+  int len, void *val, bool is_write)
+{
+   struct vgic_dist *dist = vcpu-kvm-arch.vgic;
+   struct vgic_io_device *iodev = container_of(this,
+   struct vgic_io_device, dev);
+   struct kvm_run *run = vcpu-run;
+   const struct vgic_io_range *range;
+   struct kvm_exit_mmio mmio;
+   bool updated_state;
+   gpa_t offset;
+
+   offset = addr - iodev-addr;
+   range = vgic_find_range(iodev-reg_ranges, len, offset);
+   if (unlikely(!range || !range-handle_mmio)) {
+   pr_warn(Unhandled access %d %08llx %d\n, is_write, addr, len);
+   return -ENXIO;
+   }
+
+   mmio.phys_addr = addr;
+   mmio.len = len;
+   mmio.is_write = is_write;
+   if (is_write)
+   memcpy(mmio.data, val, len);
+   mmio.private = iodev-redist_vcpu;
+
+   spin_lock(dist-lock);
+   offset -= range-base;
+   if (vgic_validate_access(dist, range, offset)) {
+   updated_state = call_range_handler(vcpu, mmio, offset, range);
+   if (!is_write)
+   memcpy(val, mmio.data, len);
+   } else {
+   if (!is_write)
+   memset(val, 0, len);
+   updated_state = false;
+   }
+   spin_unlock(dist-lock);
+   kvm_prepare_mmio(run, mmio);
+   kvm_handle_mmio_return(vcpu, run);
+
+   if (updated_state)
+   vgic_kick_vcpus(vcpu-kvm);
+
+   return 0;
+}
+
+/**
  * vgic_handle_mmio - handle an in-kernel MMIO access for the GIC emulation
  * @vcpu:  pointer to the vcpu performing the access
  * @run:   pointer to the kvm_run structure
@@ -860,6 +922,73 @@ bool vgic_handle_mmio(struct kvm_vcpu *vcpu, struct 
kvm_run *run,
return vcpu-kvm-arch.vgic.vm_ops.handle_mmio(vcpu, run, mmio);
 }
 
+static int vgic_handle_mmio_read(struct kvm_vcpu *vcpu,
+struct kvm_io_device *this,
+gpa_t addr, int len, void *val)
+{
+   return vgic_handle_mmio_access(vcpu, this, addr, len, val, false);
+}
+
+static int vgic_handle_mmio_write(struct kvm_vcpu *vcpu,
+ struct kvm_io_device *this,
+ gpa_t addr, int len, const void *val)
+{
+   return vgic_handle_mmio_access(vcpu, this, addr, len, (void *)val,
+  true);
+}
+
+struct 

[PATCH 26/27] KVM: arm/arm64: rework MMIO abort handling to use KVM MMIO bus

2015-04-02 Thread Marc Zyngier
From: Andre Przywara andre.przyw...@arm.com

Currently we have struct kvm_exit_mmio for encapsulating MMIO abort
data to be passed on from syndrome decoding all the way down to the
VGIC register handlers. Now as we switch the MMIO handling to be
routed through the KVM MMIO bus, it does not make sense anymore to
use that structure already from the beginning. So we keep the data in
local variables until we put them into the kvm_io_bus framework.
Then we fill kvm_exit_mmio in the VGIC only, making it a VGIC private
structure. On that way we replace the data buffer in that structure
with a pointer pointing to a single location in a local variable, so
we get rid of some copying on the way.
With all of the virtual GIC emulation code now being registered with
the kvm_io_bus, we can remove all of the old MMIO handling code and
its dispatching functionality.

I didn't bother to rename kvm_exit_mmio (to vgic_mmio or something),
because that touches a lot of code lines without any good reason.

This is based on an original patch by Nikolay.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
Cc: Nikolay Nikolaev n.nikol...@virtualopensystems.com
Reviewed-by: Marc Zyngier marc.zyng...@arm.com
Signed-off-by: Marc Zyngier marc.zyng...@arm.com
---
 arch/arm/include/asm/kvm_mmio.h   | 22 -
 arch/arm/kvm/mmio.c   | 64 +++
 arch/arm64/include/asm/kvm_mmio.h | 22 -
 include/kvm/arm_vgic.h|  6 ---
 virt/kvm/arm/vgic-v2-emul.c   | 21 +
 virt/kvm/arm/vgic-v3-emul.c   | 35 ---
 virt/kvm/arm/vgic.c   | 93 ---
 virt/kvm/arm/vgic.h   | 13 +++---
 8 files changed, 55 insertions(+), 221 deletions(-)

diff --git a/arch/arm/include/asm/kvm_mmio.h b/arch/arm/include/asm/kvm_mmio.h
index 3f83db2..d8e90c8 100644
--- a/arch/arm/include/asm/kvm_mmio.h
+++ b/arch/arm/include/asm/kvm_mmio.h
@@ -28,28 +28,6 @@ struct kvm_decode {
bool sign_extend;
 };
 
-/*
- * The in-kernel MMIO emulation code wants to use a copy of run-mmio,
- * which is an anonymous type. Use our own type instead.
- */
-struct kvm_exit_mmio {
-   phys_addr_t phys_addr;
-   u8  data[8];
-   u32 len;
-   boolis_write;
-   void*private;
-};
-
-static inline void kvm_prepare_mmio(struct kvm_run *run,
-   struct kvm_exit_mmio *mmio)
-{
-   run-mmio.phys_addr = mmio-phys_addr;
-   run-mmio.len   = mmio-len;
-   run-mmio.is_write  = mmio-is_write;
-   memcpy(run-mmio.data, mmio-data, mmio-len);
-   run-exit_reason= KVM_EXIT_MMIO;
-}
-
 int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run);
 int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run,
 phys_addr_t fault_ipa);
diff --git a/arch/arm/kvm/mmio.c b/arch/arm/kvm/mmio.c
index 5d3bfc0..974b1c6 100644
--- a/arch/arm/kvm/mmio.c
+++ b/arch/arm/kvm/mmio.c
@@ -121,12 +121,11 @@ int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
return 0;
 }
 
-static int decode_hsr(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
- struct kvm_exit_mmio *mmio)
+static int decode_hsr(struct kvm_vcpu *vcpu, bool *is_write, int *len)
 {
unsigned long rt;
-   int len;
-   bool is_write, sign_extend;
+   int access_size;
+   bool sign_extend;
 
if (kvm_vcpu_dabt_isextabt(vcpu)) {
/* cache operation on I/O addr, tell guest unsupported */
@@ -140,17 +139,15 @@ static int decode_hsr(struct kvm_vcpu *vcpu, phys_addr_t 
fault_ipa,
return 1;
}
 
-   len = kvm_vcpu_dabt_get_as(vcpu);
-   if (unlikely(len  0))
-   return len;
+   access_size = kvm_vcpu_dabt_get_as(vcpu);
+   if (unlikely(access_size  0))
+   return access_size;
 
-   is_write = kvm_vcpu_dabt_iswrite(vcpu);
+   *is_write = kvm_vcpu_dabt_iswrite(vcpu);
sign_extend = kvm_vcpu_dabt_issext(vcpu);
rt = kvm_vcpu_dabt_get_rd(vcpu);
 
-   mmio-is_write = is_write;
-   mmio-phys_addr = fault_ipa;
-   mmio-len = len;
+   *len = access_size;
vcpu-arch.mmio_decode.sign_extend = sign_extend;
vcpu-arch.mmio_decode.rt = rt;
 
@@ -165,20 +162,20 @@ static int decode_hsr(struct kvm_vcpu *vcpu, phys_addr_t 
fault_ipa,
 int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run,
 phys_addr_t fault_ipa)
 {
-   struct kvm_exit_mmio mmio;
unsigned long data;
unsigned long rt;
int ret;
+   bool is_write;
+   int len;
+   u8 data_buf[8];
 
/*
-* Prepare MMIO operation. First stash it in a private
-* structure that we can use for in-kernel emulation. If the
-* kernel can't handle it, copy it into run-mmio and let user
-* space do its magic.
+* Prepare MMIO operation. 

[PATCH 27/27] KVM: arm/arm64: enable KVM_CAP_IOEVENTFD

2015-04-02 Thread Marc Zyngier
From: Nikolay Nikolaev n.nikol...@virtualopensystems.com

As the infrastructure for eventfd has now been merged, report the
ioeventfd capability as being supported.

Signed-off-by: Nikolay Nikolaev n.nikol...@virtualopensystems.com
[maz: grouped the case entry with the others, fixed commit log]
Signed-off-by: Marc Zyngier marc.zyng...@arm.com
---
 arch/arm/kvm/arm.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index e98370c..6f53645 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -172,6 +172,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
switch (ext) {
case KVM_CAP_IRQCHIP:
case KVM_CAP_IRQFD:
+   case KVM_CAP_IOEVENTFD:
case KVM_CAP_DEVICE_CTRL:
case KVM_CAP_USER_MEMORY:
case KVM_CAP_SYNC_MMU:
-- 
2.1.4

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


[PATCH 11/27] arm/arm64: KVM: Optimize handling of Access Flag faults

2015-04-02 Thread Marc Zyngier
Now that we have page aging in Stage-2, it becomes obvious that
we're doing way too much work handling the fault.

The page is not going anywhere (it is still mapped), the page
tables are already allocated, and all we want is to flip a bit
in the PMD or PTE. Also, we can avoid any form of TLB invalidation,
since a page with the AF bit off is not allowed to be cached.

An obvious solution is to have a separate handler for FSC_ACCESS,
where we pride ourselves to only do the very minimum amount of
work.

Signed-off-by: Marc Zyngier marc.zyng...@arm.com
Acked-by: Christoffer Dall christoffer.d...@linaro.org
Signed-off-by: Christoffer Dall christoffer.d...@linaro.org
---
 arch/arm/kvm/mmu.c   | 46 ++
 arch/arm/kvm/trace.h | 15 +++
 2 files changed, 61 insertions(+)

diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index 1831aa2..56c8b03 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -1304,6 +1304,46 @@ out_unlock:
return ret;
 }
 
+/*
+ * Resolve the access fault by making the page young again.
+ * Note that because the faulting entry is guaranteed not to be
+ * cached in the TLB, we don't need to invalidate anything.
+ */
+static void handle_access_fault(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
+{
+   pmd_t *pmd;
+   pte_t *pte;
+   pfn_t pfn;
+   bool pfn_valid = false;
+
+   trace_kvm_access_fault(fault_ipa);
+
+   spin_lock(vcpu-kvm-mmu_lock);
+
+   pmd = stage2_get_pmd(vcpu-kvm, NULL, fault_ipa);
+   if (!pmd || pmd_none(*pmd)) /* Nothing there */
+   goto out;
+
+   if (kvm_pmd_huge(*pmd)) {   /* THP, HugeTLB */
+   *pmd = pmd_mkyoung(*pmd);
+   pfn = pmd_pfn(*pmd);
+   pfn_valid = true;
+   goto out;
+   }
+
+   pte = pte_offset_kernel(pmd, fault_ipa);
+   if (pte_none(*pte)) /* Nothing there either */
+   goto out;
+
+   *pte = pte_mkyoung(*pte);   /* Just a page... */
+   pfn = pte_pfn(*pte);
+   pfn_valid = true;
+out:
+   spin_unlock(vcpu-kvm-mmu_lock);
+   if (pfn_valid)
+   kvm_set_pfn_accessed(pfn);
+}
+
 /**
  * kvm_handle_guest_abort - handles all 2nd stage aborts
  * @vcpu:  the VCPU pointer
@@ -1371,6 +1411,12 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
/* Userspace should not be able to register out-of-bounds IPAs */
VM_BUG_ON(fault_ipa = KVM_PHYS_SIZE);
 
+   if (fault_status == FSC_ACCESS) {
+   handle_access_fault(vcpu, fault_ipa);
+   ret = 1;
+   goto out_unlock;
+   }
+
ret = user_mem_abort(vcpu, fault_ipa, memslot, hva, fault_status);
if (ret == 0)
ret = 1;
diff --git a/arch/arm/kvm/trace.h b/arch/arm/kvm/trace.h
index c09f37f..0ec3539 100644
--- a/arch/arm/kvm/trace.h
+++ b/arch/arm/kvm/trace.h
@@ -68,6 +68,21 @@ TRACE_EVENT(kvm_guest_fault,
  __entry-hxfar, __entry-vcpu_pc)
 );
 
+TRACE_EVENT(kvm_access_fault,
+   TP_PROTO(unsigned long ipa),
+   TP_ARGS(ipa),
+
+   TP_STRUCT__entry(
+   __field(unsigned long,  ipa )
+   ),
+
+   TP_fast_assign(
+   __entry-ipa= ipa;
+   ),
+
+   TP_printk(IPA: %lx, __entry-ipa)
+);
+
 TRACE_EVENT(kvm_irq_line,
TP_PROTO(unsigned int type, int vcpu_idx, int irq_num, int level),
TP_ARGS(type, vcpu_idx, irq_num, level),
-- 
2.1.4

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


[PATCH 20/27] KVM: arm/arm64: rename struct kvm_mmio_range to vgic_io_range

2015-04-02 Thread Marc Zyngier
From: Andre Przywara andre.przyw...@arm.com

The name kvm_mmio_range is a bit bold, given that it only covers
the VGIC's MMIO ranges. To avoid confusion with kvm_io_range, rename
it to vgic_io_range.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
Acked-by: Christoffer Dall christoffer.d...@linaro.org
Reviewed-by: Marc Zyngier marc.zyng...@arm.com
Signed-off-by: Marc Zyngier marc.zyng...@arm.com
---
 virt/kvm/arm/vgic-v2-emul.c |  6 +++---
 virt/kvm/arm/vgic-v3-emul.c |  8 
 virt/kvm/arm/vgic.c | 18 +-
 virt/kvm/arm/vgic.h | 12 ++--
 4 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/virt/kvm/arm/vgic-v2-emul.c b/virt/kvm/arm/vgic-v2-emul.c
index c818662..ddb3135 100644
--- a/virt/kvm/arm/vgic-v2-emul.c
+++ b/virt/kvm/arm/vgic-v2-emul.c
@@ -319,7 +319,7 @@ static bool handle_mmio_sgi_clear(struct kvm_vcpu *vcpu,
return write_set_clear_sgi_pend_reg(vcpu, mmio, offset, false);
 }
 
-static const struct kvm_mmio_range vgic_dist_ranges[] = {
+static const struct vgic_io_range vgic_dist_ranges[] = {
{
.base   = GIC_DIST_CTRL,
.len= 12,
@@ -647,7 +647,7 @@ static bool handle_cpu_mmio_ident(struct kvm_vcpu *vcpu,
  * CPU Interface Register accesses - these are not accessed by the VM, but by
  * user space for saving and restoring VGIC state.
  */
-static const struct kvm_mmio_range vgic_cpu_ranges[] = {
+static const struct vgic_io_range vgic_cpu_ranges[] = {
{
.base   = GIC_CPU_CTRL,
.len= 12,
@@ -674,7 +674,7 @@ static int vgic_attr_regs_access(struct kvm_device *dev,
 struct kvm_device_attr *attr,
 u32 *reg, bool is_write)
 {
-   const struct kvm_mmio_range *r = NULL, *ranges;
+   const struct vgic_io_range *r = NULL, *ranges;
phys_addr_t offset;
int ret, cpuid, c;
struct kvm_vcpu *vcpu, *tmp_vcpu;
diff --git a/virt/kvm/arm/vgic-v3-emul.c b/virt/kvm/arm/vgic-v3-emul.c
index b3f1546..14943e3 100644
--- a/virt/kvm/arm/vgic-v3-emul.c
+++ b/virt/kvm/arm/vgic-v3-emul.c
@@ -340,7 +340,7 @@ static bool handle_mmio_idregs(struct kvm_vcpu *vcpu,
return false;
 }
 
-static const struct kvm_mmio_range vgic_v3_dist_ranges[] = {
+static const struct vgic_io_range vgic_v3_dist_ranges[] = {
{
.base   = GICD_CTLR,
.len= 0x04,
@@ -570,7 +570,7 @@ static bool handle_mmio_cfg_reg_redist(struct kvm_vcpu 
*vcpu,
return vgic_handle_cfg_reg(reg, mmio, offset);
 }
 
-static const struct kvm_mmio_range vgic_redist_sgi_ranges[] = {
+static const struct vgic_io_range vgic_redist_sgi_ranges[] = {
{
.base   = GICR_IGROUPR0,
.len= 0x04,
@@ -676,7 +676,7 @@ static bool handle_mmio_typer_redist(struct kvm_vcpu *vcpu,
return false;
 }
 
-static const struct kvm_mmio_range vgic_redist_ranges[] = {
+static const struct vgic_io_range vgic_redist_ranges[] = {
{
.base   = GICR_CTLR,
.len= 0x04,
@@ -726,7 +726,7 @@ static bool vgic_v3_handle_mmio(struct kvm_vcpu *vcpu, 
struct kvm_run *run,
unsigned long rdbase = dist-vgic_redist_base;
int nrcpus = atomic_read(vcpu-kvm-online_vcpus);
int vcpu_id;
-   const struct kvm_mmio_range *mmio_range;
+   const struct vgic_io_range *mmio_range;
 
if (is_in_range(mmio-phys_addr, mmio-len, dbase, GIC_V3_DIST_SIZE)) {
return vgic_handle_mmio_range(vcpu, run, mmio,
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index ffd937c..21a3550 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -712,11 +712,11 @@ void vgic_unqueue_irqs(struct kvm_vcpu *vcpu)
 }
 
 const
-struct kvm_mmio_range *vgic_find_range(const struct kvm_mmio_range *ranges,
-  struct kvm_exit_mmio *mmio,
-  phys_addr_t offset)
+struct vgic_io_range *vgic_find_range(const struct vgic_io_range *ranges,
+ struct kvm_exit_mmio *mmio,
+ phys_addr_t offset)
 {
-   const struct kvm_mmio_range *r = ranges;
+   const struct vgic_io_range *r = ranges;
 
while (r-len) {
if (offset = r-base 
@@ -729,7 +729,7 @@ struct kvm_mmio_range *vgic_find_range(const struct 
kvm_mmio_range *ranges,
 }
 
 static bool vgic_validate_access(const struct vgic_dist *dist,
-const struct kvm_mmio_range *range,
+const struct vgic_io_range *range,
 unsigned long offset)
 {
int irq;
@@ -757,7 +757,7 @@ static bool vgic_validate_access(const struct vgic_dist 
*dist,
 static bool call_range_handler(struct kvm_vcpu *vcpu,
 

[PATCH 17/27] KVM: move iodev.h from virt/kvm/ to include/kvm

2015-04-02 Thread Marc Zyngier
From: Andre Przywara andre.przyw...@arm.com

iodev.h contains definitions for the kvm_io_bus framework. This is
needed both by the generic KVM code in virt/kvm as well as by
architecture specific code under arch/. Putting the header file in
virt/kvm and using local includes in the architecture part seems at
least dodgy to me, so let's move the file into include/kvm, so that a
more natural #include kvm/iodev.h can be used by all of the code.
This also solves a problem later when using struct kvm_io_device
in arm_vgic.h.
Fixing up the FSF address in the GPL header and a wrong include path
on the way.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
Acked-by: Christoffer Dall christoffer.d...@linaro.org
Reviewed-by: Marc Zyngier marc.zyng...@arm.com
Reviewed-by: Marcelo Tosatti mtosa...@redhat.com
Signed-off-by: Marc Zyngier marc.zyng...@arm.com
---
 arch/powerpc/kvm/mpic.c   |  2 +-
 arch/x86/kvm/i8254.h  |  2 +-
 arch/x86/kvm/ioapic.h |  2 +-
 arch/x86/kvm/irq.h|  2 +-
 arch/x86/kvm/lapic.h  |  2 +-
 include/kvm/iodev.h   | 76 ++
 virt/kvm/coalesced_mmio.c |  2 +-
 virt/kvm/eventfd.c|  2 +-
 virt/kvm/iodev.h  | 77 ---
 virt/kvm/kvm_main.c   |  2 +-
 10 files changed, 84 insertions(+), 85 deletions(-)
 create mode 100644 include/kvm/iodev.h
 delete mode 100644 virt/kvm/iodev.h

diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c
index 8542f07..4703fad 100644
--- a/arch/powerpc/kvm/mpic.c
+++ b/arch/powerpc/kvm/mpic.c
@@ -34,7 +34,7 @@
 #include asm/kvm_para.h
 #include asm/kvm_host.h
 #include asm/kvm_ppc.h
-#include iodev.h
+#include kvm/iodev.h
 
 #define MAX_CPU 32
 #define MAX_SRC 256
diff --git a/arch/x86/kvm/i8254.h b/arch/x86/kvm/i8254.h
index dd1b16b..c84990b 100644
--- a/arch/x86/kvm/i8254.h
+++ b/arch/x86/kvm/i8254.h
@@ -3,7 +3,7 @@
 
 #include linux/kthread.h
 
-#include iodev.h
+#include kvm/iodev.h
 
 struct kvm_kpit_channel_state {
u32 count; /* can be 65536 */
diff --git a/arch/x86/kvm/ioapic.h b/arch/x86/kvm/ioapic.h
index c2e36d9..d9e02ca 100644
--- a/arch/x86/kvm/ioapic.h
+++ b/arch/x86/kvm/ioapic.h
@@ -3,7 +3,7 @@
 
 #include linux/kvm_host.h
 
-#include iodev.h
+#include kvm/iodev.h
 
 struct kvm;
 struct kvm_vcpu;
diff --git a/arch/x86/kvm/irq.h b/arch/x86/kvm/irq.h
index 2d03568..ad68c73 100644
--- a/arch/x86/kvm/irq.h
+++ b/arch/x86/kvm/irq.h
@@ -27,7 +27,7 @@
 #include linux/kvm_host.h
 #include linux/spinlock.h
 
-#include iodev.h
+#include kvm/iodev.h
 #include ioapic.h
 #include lapic.h
 
diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
index 0bc6c65..e284c28 100644
--- a/arch/x86/kvm/lapic.h
+++ b/arch/x86/kvm/lapic.h
@@ -1,7 +1,7 @@
 #ifndef __KVM_X86_LAPIC_H
 #define __KVM_X86_LAPIC_H
 
-#include iodev.h
+#include kvm/iodev.h
 
 #include linux/kvm_host.h
 
diff --git a/include/kvm/iodev.h b/include/kvm/iodev.h
new file mode 100644
index 000..a6d208b
--- /dev/null
+++ b/include/kvm/iodev.h
@@ -0,0 +1,76 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ *
+ * 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/.
+ */
+
+#ifndef __KVM_IODEV_H__
+#define __KVM_IODEV_H__
+
+#include linux/kvm_types.h
+#include linux/errno.h
+
+struct kvm_io_device;
+struct kvm_vcpu;
+
+/**
+ * kvm_io_device_ops are called under kvm slots_lock.
+ * read and write handlers return 0 if the transaction has been handled,
+ * or non-zero to have it passed to the next device.
+ **/
+struct kvm_io_device_ops {
+   int (*read)(struct kvm_vcpu *vcpu,
+   struct kvm_io_device *this,
+   gpa_t addr,
+   int len,
+   void *val);
+   int (*write)(struct kvm_vcpu *vcpu,
+struct kvm_io_device *this,
+gpa_t addr,
+int len,
+const void *val);
+   void (*destructor)(struct kvm_io_device *this);
+};
+
+
+struct kvm_io_device {
+   const struct kvm_io_device_ops *ops;
+};
+
+static inline void kvm_iodevice_init(struct kvm_io_device *dev,
+const struct kvm_io_device_ops *ops)
+{
+   dev-ops = ops;
+}
+
+static inline int kvm_iodevice_read(struct kvm_vcpu *vcpu,
+   struct kvm_io_device *dev, gpa_t addr,
+   int l, void *v)
+{
+   return dev-ops-read ? dev-ops-read(vcpu, dev, addr, l, 

[PATCH 03/27] arm/arm64: KVM: Kill CONFIG_KVM_ARM_{VGIC,TIMER}

2015-04-02 Thread Marc Zyngier
From: Christoffer Dall christoffer.d...@linaro.org

We can definitely decide at run-time whether to use the GIC and timers
or not, and the extra code and data structures that we allocate space
for is really negligable with this config option, so I don't think it's
worth the extra complexity of always having to define stub static
inlines.  The !CONFIG_KVM_ARM_VGIC/TIMER case is pretty much an untested
code path anyway, so we're better off just getting rid of it.

Signed-off-by: Christoffer Dall christoffer.d...@linaro.org
Acked-by: Marc Zyngier marc.zyng...@arm.com
---
 arch/arm/kernel/asm-offsets.c  |  4 --
 arch/arm/kvm/Kconfig   | 29 +++---
 arch/arm/kvm/Makefile  |  8 ++--
 arch/arm/kvm/arm.c |  6 ---
 arch/arm/kvm/guest.c   | 18 -
 arch/arm/kvm/interrupts_head.S |  8 
 arch/arm64/kvm/Kconfig | 17 +
 arch/arm64/kvm/Makefile| 16 
 include/kvm/arm_arch_timer.h   | 31 ---
 include/kvm/arm_vgic.h | 85 --
 10 files changed, 20 insertions(+), 202 deletions(-)

diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 2d2d608..488eaac 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -190,7 +190,6 @@ int main(void)
   DEFINE(VCPU_HxFAR,   offsetof(struct kvm_vcpu, arch.fault.hxfar));
   DEFINE(VCPU_HPFAR,   offsetof(struct kvm_vcpu, arch.fault.hpfar));
   DEFINE(VCPU_HYP_PC,  offsetof(struct kvm_vcpu, arch.fault.hyp_pc));
-#ifdef CONFIG_KVM_ARM_VGIC
   DEFINE(VCPU_VGIC_CPU,offsetof(struct kvm_vcpu, 
arch.vgic_cpu));
   DEFINE(VGIC_V2_CPU_HCR,  offsetof(struct vgic_cpu, vgic_v2.vgic_hcr));
   DEFINE(VGIC_V2_CPU_VMCR, offsetof(struct vgic_cpu, vgic_v2.vgic_vmcr));
@@ -200,14 +199,11 @@ int main(void)
   DEFINE(VGIC_V2_CPU_APR,  offsetof(struct vgic_cpu, vgic_v2.vgic_apr));
   DEFINE(VGIC_V2_CPU_LR,   offsetof(struct vgic_cpu, vgic_v2.vgic_lr));
   DEFINE(VGIC_CPU_NR_LR,   offsetof(struct vgic_cpu, nr_lr));
-#ifdef CONFIG_KVM_ARM_TIMER
   DEFINE(VCPU_TIMER_CNTV_CTL,  offsetof(struct kvm_vcpu, 
arch.timer_cpu.cntv_ctl));
   DEFINE(VCPU_TIMER_CNTV_CVAL, offsetof(struct kvm_vcpu, 
arch.timer_cpu.cntv_cval));
   DEFINE(KVM_TIMER_CNTVOFF,offsetof(struct kvm, arch.timer.cntvoff));
   DEFINE(KVM_TIMER_ENABLED,offsetof(struct kvm, arch.timer.enabled));
-#endif
   DEFINE(KVM_VGIC_VCTRL,   offsetof(struct kvm, arch.vgic.vctrl_base));
-#endif
   DEFINE(KVM_VTTBR,offsetof(struct kvm, arch.vttbr));
 #endif
   return 0; 
diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig
index 338ace7..7b6347b 100644
--- a/arch/arm/kvm/Kconfig
+++ b/arch/arm/kvm/Kconfig
@@ -18,6 +18,7 @@ if VIRTUALIZATION
 
 config KVM
bool Kernel-based Virtual Machine (KVM) support
+   depends on MMU  OF
select PREEMPT_NOTIFIERS
select ANON_INODES
select HAVE_KVM_CPU_RELAX_INTERCEPT
@@ -26,10 +27,11 @@ config KVM
select KVM_ARM_HOST
select KVM_GENERIC_DIRTYLOG_READ_PROTECT
select SRCU
-   depends on ARM_VIRT_EXT  ARM_LPAE
+   select MMU_NOTIFIER
+   select HAVE_KVM_IRQCHIP
+   depends on ARM_VIRT_EXT  ARM_LPAE  ARM_ARCH_TIMER
---help---
- Support hosting virtualized guest machines. You will also
- need to select one or more of the processor modules below.
+ Support hosting virtualized guest machines.
 
  This module provides access to the hardware capabilities through
  a character device node named /dev/kvm.
@@ -37,10 +39,7 @@ config KVM
  If unsure, say N.
 
 config KVM_ARM_HOST
-   bool KVM host support for ARM cpus.
-   depends on KVM
-   depends on MMU
-   select  MMU_NOTIFIER
+   bool
---help---
  Provides host support for ARM processors.
 
@@ -55,20 +54,4 @@ config KVM_ARM_MAX_VCPUS
  large, so only choose a reasonable number that you expect to
  actually use.
 
-config KVM_ARM_VGIC
-   bool KVM support for Virtual GIC
-   depends on KVM_ARM_HOST  OF
-   select HAVE_KVM_IRQCHIP
-   default y
-   ---help---
- Adds support for a hardware assisted, in-kernel GIC emulation.
-
-config KVM_ARM_TIMER
-   bool KVM support for Architected Timers
-   depends on KVM_ARM_VGIC  ARM_ARCH_TIMER
-   select HAVE_KVM_IRQCHIP
-   default y
-   ---help---
- Adds support for the Architected Timers in virtual machines
-
 endif # VIRTUALIZATION
diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile
index 443b8be..60be7be 100644
--- a/arch/arm/kvm/Makefile
+++ b/arch/arm/kvm/Makefile
@@ -20,7 +20,7 @@ kvm-arm-y = $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o
 obj-y += kvm-arm.o init.o interrupts.o
 obj-y += arm.o handle_exit.o guest.o mmu.o emulate.o reset.o
 obj-y += coproc.o coproc_a15.o coproc_a7.o mmio.o psci.o perf.o
-obj-$(CONFIG_KVM_ARM_VGIC) += 

[GIT PULL] KVM/ARM updates for v4.1

2015-04-02 Thread Marc Zyngier
Paolo, Marcelo,

This is the pull request for the KVM/ARM updates targeting v4.1. It
contains a number of important updates bringing the port much closer
to feature completeness.

Note that merging this will generate a small conflict in
virt/kvm/arm/vgic.c, which should be resolved as per linux-next.

Thanks,

M.

The following changes since commit 4ff6f8e61eb7f96d3ca535c6d240f863ccd6fb7d:

  KVM: emulate: fix CMPXCHG8B on 32-bit hosts (2015-02-23 22:28:48 +0100)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git 
tags/kvm-arm-for-4.1

for you to fetch changes up to d44758c0dfc5993a4b9952935a7eae4c91ebb6b4:

  KVM: arm/arm64: enable KVM_CAP_IOEVENTFD (2015-03-30 17:07:24 +0100)


KVM/ARM changes for v4.1:

- fixes for live migration
- irqfd support
- kvm-io-bus  vgic rework to enable ioeventfd
- page ageing for stage-2 translation
- various cleanups


Alex Bennée (2):
  arm/arm64: KVM: export VCPU power state via MP_STATE ioctl
  arm/arm64: KVM: add a common vgic_queue_irq_to_lr fn

Andre Przywara (10):
  KVM: move iodev.h from virt/kvm/ to include/kvm
  KVM: arm/arm64: remove now unneeded include directory from Makefile
  KVM: x86: remove now unneeded include directory from Makefile
  KVM: arm/arm64: rename struct kvm_mmio_range to vgic_io_range
  KVM: arm/arm64: simplify vgic_find_range() and callers
  KVM: arm/arm64: implement kvm_io_bus MMIO handling for the VGIC
  KVM: arm/arm64: prepare GICv2 emulation to be handled by kvm_io_bus
  KVM: arm/arm64: merge GICv3 RD_base and SGI_base register frames
  KVM: arm/arm64: prepare GICv3 emulation to use kvm_io_bus MMIO handling
  KVM: arm/arm64: rework MMIO abort handling to use KVM MMIO bus

Christoffer Dall (3):
  arm/arm64: KVM: Kill CONFIG_KVM_ARM_{VGIC,TIMER}
  arm/arm64: KVM: support for un-queuing active IRQs
  arm/arm64: KVM: Fix migration race in the arch timer

Eric Auger (5):
  KVM: arm/arm64: unset CONFIG_HAVE_KVM_IRQCHIP
  KVM: introduce kvm_arch_intc_initialized and use it in irqfd
  KVM: arm/arm64: implement kvm_arch_intc_initialized
  KVM: arm/arm64: remove coarse grain dist locking at kvm_vgic_sync_hwstate
  KVM: arm/arm64: add irqfd support

Marc Zyngier (3):
  arm/arm64: KVM: Allow handle_hva_to_gpa to return a value
  arm/arm64: KVM: Implement Stage-2 page aging
  arm/arm64: KVM: Optimize handling of Access Flag faults

Mark Rutland (1):
  KVM: vgic: add virt-capable compatible strings

Nikolay Nikolaev (2):
  KVM: Redesign kvm_io_bus_ API to pass VCPU structure to the callbacks.
  KVM: arm/arm64: enable KVM_CAP_IOEVENTFD

Paolo Bonzini (1):
  KVM: arm/arm64: prefer IS_ENABLED to a static variable

 Documentation/virtual/kvm/api.txt |  22 +-
 arch/arm/include/asm/kvm_arm.h|   1 +
 arch/arm/include/asm/kvm_host.h   |  15 +-
 arch/arm/include/asm/kvm_mmio.h   |  22 --
 arch/arm/include/uapi/asm/kvm.h   |   3 +
 arch/arm/kernel/asm-offsets.c |   4 -
 arch/arm/kvm/Kconfig  |  30 +--
 arch/arm/kvm/Makefile |  12 +-
 arch/arm/kvm/arm.c|  45 ++--
 arch/arm/kvm/guest.c  |  18 --
 arch/arm/kvm/interrupts_head.S|   8 -
 arch/arm/kvm/mmio.c   |  64 ++---
 arch/arm/kvm/mmu.c| 134 ++-
 arch/arm/kvm/trace.h  |  48 
 arch/arm64/include/asm/esr.h  |   1 +
 arch/arm64/include/asm/kvm_arm.h  |   1 +
 arch/arm64/include/asm/kvm_host.h |  15 +-
 arch/arm64/include/asm/kvm_mmio.h |  22 --
 arch/arm64/include/uapi/asm/kvm.h |   3 +
 arch/arm64/kvm/Kconfig|  18 +-
 arch/arm64/kvm/Makefile   |  20 +-
 arch/powerpc/kvm/mpic.c   |  12 +-
 arch/powerpc/kvm/powerpc.c|   4 +-
 arch/s390/kvm/diag.c  |   2 +-
 arch/x86/kvm/Makefile |   2 +-
 arch/x86/kvm/i8254.c  |  14 +-
 arch/x86/kvm/i8254.h  |   2 +-
 arch/x86/kvm/i8259.c  |  12 +-
 arch/x86/kvm/ioapic.c |   8 +-
 arch/x86/kvm/ioapic.h |   2 +-
 arch/x86/kvm/irq.h|   2 +-
 arch/x86/kvm/lapic.c  |   4 +-
 arch/x86/kvm/lapic.h  |   2 +-
 arch/x86/kvm/vmx.c|   2 +-
 arch/x86/kvm/x86.c|  13 +-
 include/kvm/arm_arch_timer.h  |  31 +--
 include/kvm/arm_vgic.h| 117 ++
 {virt = include}/kvm/iodev.h |  28 ++-
 include/linux/kvm_host.h  |  24 +-
 virt/kvm/arm/arch_timer.c |  45 +++-
 virt/kvm/arm/vgic-v2-emul.c   |  71 +++---
 virt/kvm/arm/vgic-v3-emul.c   | 246 ++--
 virt/kvm/arm/vgic.c   | 476 --
 virt/kvm/arm/vgic.h   |  37 ++-
 virt/kvm/coalesced_mmio.c |   7 +-
 virt/kvm/eventfd.c

[PATCH 04/27] KVM: arm/arm64: unset CONFIG_HAVE_KVM_IRQCHIP

2015-04-02 Thread Marc Zyngier
From: Eric Auger eric.au...@linaro.org

CONFIG_HAVE_KVM_IRQCHIP is needed to support IRQ routing (along
with irq_comm.c and irqchip.c usage). This is not the case for
arm/arm64 currently.

This patch unsets the flag for both arm and arm64.

Signed-off-by: Eric Auger eric.au...@linaro.org
Reviewed-by: Andre Przywara andre.przyw...@arm.com
Acked-by: Christoffer Dall christoffer.d...@linaro.org
Acked-by: Will Deacon will.dea...@arm.com
Acked-by: Marc Zyngier marc.zyng...@arm.com
Signed-off-by: Christoffer Dall christoffer.d...@linaro.org
---
 arch/arm/kvm/Kconfig   | 1 -
 arch/arm64/kvm/Kconfig | 1 -
 2 files changed, 2 deletions(-)

diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig
index 7b6347b..83a448e 100644
--- a/arch/arm/kvm/Kconfig
+++ b/arch/arm/kvm/Kconfig
@@ -28,7 +28,6 @@ config KVM
select KVM_GENERIC_DIRTYLOG_READ_PROTECT
select SRCU
select MMU_NOTIFIER
-   select HAVE_KVM_IRQCHIP
depends on ARM_VIRT_EXT  ARM_LPAE  ARM_ARCH_TIMER
---help---
  Support hosting virtualized guest machines.
diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index ee43750..05f56ce 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -26,7 +26,6 @@ config KVM
select HAVE_KVM_ARCH_TLB_FLUSH_ALL
select KVM_MMIO
select KVM_ARM_HOST
-   select HAVE_KVM_IRQCHIP
select KVM_GENERIC_DIRTYLOG_READ_PROTECT
select SRCU
---help---
-- 
2.1.4

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


[PATCH 09/27] arm/arm64: KVM: Allow handle_hva_to_gpa to return a value

2015-04-02 Thread Marc Zyngier
So far, handle_hva_to_gpa was never required to return a value.
As we prepare to age pages at Stage-2, we need to be able to
return a value from the iterator (kvm_test_age_hva).

Adapt the code to handle this situation. No semantic change.

Acked-by: Christoffer Dall christoffer.d...@linaro.org
Signed-off-by: Marc Zyngier marc.zyng...@arm.com
Signed-off-by: Christoffer Dall christoffer.d...@linaro.org
---
 arch/arm/kvm/mmu.c | 23 ++-
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index 3e6859b..ffa06e0 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -1377,15 +1377,16 @@ out_unlock:
return ret;
 }
 
-static void handle_hva_to_gpa(struct kvm *kvm,
- unsigned long start,
- unsigned long end,
- void (*handler)(struct kvm *kvm,
- gpa_t gpa, void *data),
- void *data)
+static int handle_hva_to_gpa(struct kvm *kvm,
+unsigned long start,
+unsigned long end,
+int (*handler)(struct kvm *kvm,
+   gpa_t gpa, void *data),
+void *data)
 {
struct kvm_memslots *slots;
struct kvm_memory_slot *memslot;
+   int ret = 0;
 
slots = kvm_memslots(kvm);
 
@@ -1409,14 +1410,17 @@ static void handle_hva_to_gpa(struct kvm *kvm,
 
for (; gfn  gfn_end; ++gfn) {
gpa_t gpa = gfn  PAGE_SHIFT;
-   handler(kvm, gpa, data);
+   ret |= handler(kvm, gpa, data);
}
}
+
+   return ret;
 }
 
-static void kvm_unmap_hva_handler(struct kvm *kvm, gpa_t gpa, void *data)
+static int kvm_unmap_hva_handler(struct kvm *kvm, gpa_t gpa, void *data)
 {
unmap_stage2_range(kvm, gpa, PAGE_SIZE);
+   return 0;
 }
 
 int kvm_unmap_hva(struct kvm *kvm, unsigned long hva)
@@ -1442,7 +1446,7 @@ int kvm_unmap_hva_range(struct kvm *kvm,
return 0;
 }
 
-static void kvm_set_spte_handler(struct kvm *kvm, gpa_t gpa, void *data)
+static int kvm_set_spte_handler(struct kvm *kvm, gpa_t gpa, void *data)
 {
pte_t *pte = (pte_t *)data;
 
@@ -1454,6 +1458,7 @@ static void kvm_set_spte_handler(struct kvm *kvm, gpa_t 
gpa, void *data)
 * through this calling path.
 */
stage2_set_pte(kvm, NULL, gpa, pte, 0);
+   return 0;
 }
 
 
-- 
2.1.4

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


[PATCH 07/27] KVM: arm/arm64: remove coarse grain dist locking at kvm_vgic_sync_hwstate

2015-04-02 Thread Marc Zyngier
From: Eric Auger eric.au...@linaro.org

To prepare for irqfd addition, coarse grain locking is removed at
kvm_vgic_sync_hwstate level and finer grain locking is introduced in
vgic_process_maintenance only.

Signed-off-by: Eric Auger eric.au...@linaro.org
Acked-by: Christoffer Dall christoffer.d...@linaro.org
Acked-by: Marc Zyngier marc.zyng...@arm.com
Signed-off-by: Christoffer Dall christoffer.d...@linaro.org
---
 virt/kvm/arm/vgic.c | 13 +
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 86cec79..897c849 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -1081,6 +1081,7 @@ epilog:
 static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)
 {
u32 status = vgic_get_interrupt_status(vcpu);
+   struct vgic_dist *dist = vcpu-kvm-arch.vgic;
bool level_pending = false;
 
kvm_debug(STATUS = %08x\n, status);
@@ -1098,6 +1099,7 @@ static bool vgic_process_maintenance(struct kvm_vcpu 
*vcpu)
struct vgic_lr vlr = vgic_get_lr(vcpu, lr);
WARN_ON(vgic_irq_is_edge(vcpu, vlr.irq));
 
+   spin_lock(dist-lock);
vgic_irq_clear_queued(vcpu, vlr.irq);
WARN_ON(vlr.state  LR_STATE_MASK);
vlr.state = 0;
@@ -1125,6 +1127,8 @@ static bool vgic_process_maintenance(struct kvm_vcpu 
*vcpu)
vgic_cpu_irq_clear(vcpu, vlr.irq);
}
 
+   spin_unlock(dist-lock);
+
/*
 * Despite being EOIed, the LR may not have
 * been marked as empty.
@@ -1139,10 +1143,7 @@ static bool vgic_process_maintenance(struct kvm_vcpu 
*vcpu)
return level_pending;
 }
 
-/*
- * Sync back the VGIC state after a guest run. The distributor lock is
- * needed so we don't get preempted in the middle of the state processing.
- */
+/* Sync back the VGIC state after a guest run */
 static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
 {
struct vgic_cpu *vgic_cpu = vcpu-arch.vgic_cpu;
@@ -1189,14 +1190,10 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
 
 void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
 {
-   struct vgic_dist *dist = vcpu-kvm-arch.vgic;
-
if (!irqchip_in_kernel(vcpu-kvm))
return;
 
-   spin_lock(dist-lock);
__kvm_vgic_sync_hwstate(vcpu);
-   spin_unlock(dist-lock);
 }
 
 int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu)
-- 
2.1.4

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


[PATCH 06/27] KVM: arm/arm64: implement kvm_arch_intc_initialized

2015-04-02 Thread Marc Zyngier
From: Eric Auger eric.au...@linaro.org

On arm/arm64 the VGIC is dynamically instantiated and it is useful
to expose its state, especially for irqfd setup.

This patch defines __KVM_HAVE_ARCH_INTC_INITIALIZED and
implements kvm_arch_intc_initialized.

Signed-off-by: Eric Auger eric.au...@linaro.org
Acked-by: Christoffer Dall christoffer.d...@linaro.org
Reviewed-by: Andre Przywara andre.przyw...@arm.com
Acked-by: Marc Zyngier marc.zyng...@arm.com
Signed-off-by: Christoffer Dall christoffer.d...@linaro.org
---
 arch/arm/include/asm/kvm_host.h   | 2 ++
 arch/arm/kvm/arm.c| 5 +
 arch/arm64/include/asm/kvm_host.h | 2 ++
 3 files changed, 9 insertions(+)

diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 41008cd..902a7d1 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -27,6 +27,8 @@
 #include asm/fpstate.h
 #include kvm/arm_arch_timer.h
 
+#define __KVM_HAVE_ARCH_INTC_INITIALIZED
+
 #if defined(CONFIG_KVM_ARM_MAX_VCPUS)
 #define KVM_MAX_VCPUS CONFIG_KVM_ARM_MAX_VCPUS
 #else
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 37b46c5..5e893eb 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -448,6 +448,11 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
return 0;
 }
 
+bool kvm_arch_intc_initialized(struct kvm *kvm)
+{
+   return vgic_initialized(kvm);
+}
+
 static void vcpu_pause(struct kvm_vcpu *vcpu)
 {
wait_queue_head_t *wq = kvm_arch_vcpu_wq(vcpu);
diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h
index 8ac3c70..967fb1c 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -28,6 +28,8 @@
 #include asm/kvm_asm.h
 #include asm/kvm_mmio.h
 
+#define __KVM_HAVE_ARCH_INTC_INITIALIZED
+
 #if defined(CONFIG_KVM_ARM_MAX_VCPUS)
 #define KVM_MAX_VCPUS CONFIG_KVM_ARM_MAX_VCPUS
 #else
-- 
2.1.4

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


[PATCH 10/27] arm/arm64: KVM: Implement Stage-2 page aging

2015-04-02 Thread Marc Zyngier
Until now, KVM/arm didn't care much for page aging (who was swapping
anyway?), and simply provided empty hooks to the core KVM code. With
server-type systems now being available, things are quite different.

This patch implements very simple support for page aging, by clearing
the Access flag in the Stage-2 page tables. On access fault, the current
fault handling will write the PTE or PMD again, putting the Access flag
back on.

It should be possible to implement a much faster handling for Access
faults, but that's left for a later patch.

With this in place, performance in VMs is degraded much more gracefully.

Signed-off-by: Marc Zyngier marc.zyng...@arm.com
Acked-by: Christoffer Dall christoffer.d...@linaro.org
Signed-off-by: Christoffer Dall christoffer.d...@linaro.org
---
 arch/arm/include/asm/kvm_arm.h|  1 +
 arch/arm/include/asm/kvm_host.h   | 13 ++--
 arch/arm/kvm/mmu.c| 65 ++-
 arch/arm/kvm/trace.h  | 33 
 arch/arm64/include/asm/esr.h  |  1 +
 arch/arm64/include/asm/kvm_arm.h  |  1 +
 arch/arm64/include/asm/kvm_host.h | 13 ++--
 7 files changed, 104 insertions(+), 23 deletions(-)

diff --git a/arch/arm/include/asm/kvm_arm.h b/arch/arm/include/asm/kvm_arm.h
index 816db0b..d995821 100644
--- a/arch/arm/include/asm/kvm_arm.h
+++ b/arch/arm/include/asm/kvm_arm.h
@@ -185,6 +185,7 @@
 #define HSR_COND   (0xfU  HSR_COND_SHIFT)
 
 #define FSC_FAULT  (0x04)
+#define FSC_ACCESS (0x08)
 #define FSC_PERM   (0x0c)
 
 /* Hyp Prefetch Fault Address Register (HPFAR/HDFAR) */
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 902a7d1..d71607c 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -167,19 +167,10 @@ void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, 
pte_t pte);
 
 unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu);
 int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices);
+int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end);
+int kvm_test_age_hva(struct kvm *kvm, unsigned long hva);
 
 /* We do not have shadow page tables, hence the empty hooks */
-static inline int kvm_age_hva(struct kvm *kvm, unsigned long start,
- unsigned long end)
-{
-   return 0;
-}
-
-static inline int kvm_test_age_hva(struct kvm *kvm, unsigned long hva)
-{
-   return 0;
-}
-
 static inline void kvm_arch_mmu_notifier_invalidate_page(struct kvm *kvm,
 unsigned long address)
 {
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index ffa06e0..1831aa2 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -1299,6 +1299,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, 
phys_addr_t fault_ipa,
 
 out_unlock:
spin_unlock(kvm-mmu_lock);
+   kvm_set_pfn_accessed(pfn);
kvm_release_pfn_clean(pfn);
return ret;
 }
@@ -1333,7 +1334,8 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
 
/* Check the stage-2 fault is trans. fault or write fault */
fault_status = kvm_vcpu_trap_get_fault_type(vcpu);
-   if (fault_status != FSC_FAULT  fault_status != FSC_PERM) {
+   if (fault_status != FSC_FAULT  fault_status != FSC_PERM 
+   fault_status != FSC_ACCESS) {
kvm_err(Unsupported FSC: EC=%#x xFSC=%#lx ESR_EL2=%#lx\n,
kvm_vcpu_trap_get_class(vcpu),
(unsigned long)kvm_vcpu_trap_get_fault(vcpu),
@@ -1475,6 +1477,67 @@ void kvm_set_spte_hva(struct kvm *kvm, unsigned long 
hva, pte_t pte)
handle_hva_to_gpa(kvm, hva, end, kvm_set_spte_handler, stage2_pte);
 }
 
+static int kvm_age_hva_handler(struct kvm *kvm, gpa_t gpa, void *data)
+{
+   pmd_t *pmd;
+   pte_t *pte;
+
+   pmd = stage2_get_pmd(kvm, NULL, gpa);
+   if (!pmd || pmd_none(*pmd)) /* Nothing there */
+   return 0;
+
+   if (kvm_pmd_huge(*pmd)) {   /* THP, HugeTLB */
+   if (pmd_young(*pmd)) {
+   *pmd = pmd_mkold(*pmd);
+   return 1;
+   }
+
+   return 0;
+   }
+
+   pte = pte_offset_kernel(pmd, gpa);
+   if (pte_none(*pte))
+   return 0;
+
+   if (pte_young(*pte)) {
+   *pte = pte_mkold(*pte); /* Just a page... */
+   return 1;
+   }
+
+   return 0;
+}
+
+static int kvm_test_age_hva_handler(struct kvm *kvm, gpa_t gpa, void *data)
+{
+   pmd_t *pmd;
+   pte_t *pte;
+
+   pmd = stage2_get_pmd(kvm, NULL, gpa);
+   if (!pmd || pmd_none(*pmd)) /* Nothing there */
+   return 0;
+
+   if (kvm_pmd_huge(*pmd)) /* THP, HugeTLB */
+   return pmd_young(*pmd);
+
+   pte = pte_offset_kernel(pmd, gpa);
+   if (!pte_none(*pte))/* Just a page... */
+   return 

[PATCH 13/27] arm/arm64: KVM: add a common vgic_queue_irq_to_lr fn

2015-04-02 Thread Marc Zyngier
From: Alex Bennée alex.ben...@linaro.org

This helps re-factor away some of the repetitive code and makes the code
flow more nicely.

Signed-off-by: Alex Bennée alex.ben...@linaro.org
Signed-off-by: Christoffer Dall christoffer.d...@linaro.org
---
 virt/kvm/arm/vgic.c | 24 +---
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index c000e97..697ce17 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -950,6 +950,20 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu 
*vcpu)
}
 }
 
+static void vgic_queue_irq_to_lr(struct kvm_vcpu *vcpu, int irq,
+int lr_nr, struct vgic_lr vlr)
+{
+   if (vgic_dist_irq_is_pending(vcpu, irq)) {
+   vlr.state |= LR_STATE_PENDING;
+   kvm_debug(Set pending: 0x%x\n, vlr.state);
+   }
+
+   if (!vgic_irq_is_edge(vcpu, irq))
+   vlr.state |= LR_EOI_INT;
+
+   vgic_set_lr(vcpu, lr_nr, vlr);
+}
+
 /*
  * Queue an interrupt to a CPU virtual interface. Return true on success,
  * or false if it wasn't possible to queue it.
@@ -977,8 +991,7 @@ bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 
sgi_source_id, int irq)
if (vlr.source == sgi_source_id) {
kvm_debug(LR%d piggyback for IRQ%d\n, lr, vlr.irq);
BUG_ON(!test_bit(lr, vgic_cpu-lr_used));
-   vlr.state |= LR_STATE_PENDING;
-   vgic_set_lr(vcpu, lr, vlr);
+   vgic_queue_irq_to_lr(vcpu, irq, lr, vlr);
return true;
}
}
@@ -995,11 +1008,8 @@ bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 
sgi_source_id, int irq)
 
vlr.irq = irq;
vlr.source = sgi_source_id;
-   vlr.state = LR_STATE_PENDING;
-   if (!vgic_irq_is_edge(vcpu, irq))
-   vlr.state |= LR_EOI_INT;
-
-   vgic_set_lr(vcpu, lr, vlr);
+   vlr.state = 0;
+   vgic_queue_irq_to_lr(vcpu, irq, lr, vlr);
 
return true;
 }
-- 
2.1.4

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


Re: [GIT PULL] KVM/ARM updates for v4.1

2015-04-02 Thread Paolo Bonzini


On 02/04/2015 12:05, Marc Zyngier wrote:
 Paolo, Marcelo,
 
 This is the pull request for the KVM/ARM updates targeting v4.1. It
 contains a number of important updates bringing the port much closer
 to feature completeness.
 
 Note that merging this will generate a small conflict in
 virt/kvm/arm/vgic.c, which should be resolved as per linux-next.
 
 Thanks,
 
   M.
 
 The following changes since commit 4ff6f8e61eb7f96d3ca535c6d240f863ccd6fb7d:
 
   KVM: emulate: fix CMPXCHG8B on 32-bit hosts (2015-02-23 22:28:48 +0100)
 
 are available in the git repository at:
 
   git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git 
 tags/kvm-arm-for-4.1
 
 for you to fetch changes up to d44758c0dfc5993a4b9952935a7eae4c91ebb6b4:
 
   KVM: arm/arm64: enable KVM_CAP_IOEVENTFD (2015-03-30 17:07:24 +0100)
 
 
 KVM/ARM changes for v4.1:
 
 - fixes for live migration
 - irqfd support
 - kvm-io-bus  vgic rework to enable ioeventfd
 - page ageing for stage-2 translation
 - various cleanups
 
 
 Alex Bennée (2):
   arm/arm64: KVM: export VCPU power state via MP_STATE ioctl
   arm/arm64: KVM: add a common vgic_queue_irq_to_lr fn
 
 Andre Przywara (10):
   KVM: move iodev.h from virt/kvm/ to include/kvm
   KVM: arm/arm64: remove now unneeded include directory from Makefile
   KVM: x86: remove now unneeded include directory from Makefile
   KVM: arm/arm64: rename struct kvm_mmio_range to vgic_io_range
   KVM: arm/arm64: simplify vgic_find_range() and callers
   KVM: arm/arm64: implement kvm_io_bus MMIO handling for the VGIC
   KVM: arm/arm64: prepare GICv2 emulation to be handled by kvm_io_bus
   KVM: arm/arm64: merge GICv3 RD_base and SGI_base register frames
   KVM: arm/arm64: prepare GICv3 emulation to use kvm_io_bus MMIO handling
   KVM: arm/arm64: rework MMIO abort handling to use KVM MMIO bus
 
 Christoffer Dall (3):
   arm/arm64: KVM: Kill CONFIG_KVM_ARM_{VGIC,TIMER}
   arm/arm64: KVM: support for un-queuing active IRQs
   arm/arm64: KVM: Fix migration race in the arch timer
 
 Eric Auger (5):
   KVM: arm/arm64: unset CONFIG_HAVE_KVM_IRQCHIP
   KVM: introduce kvm_arch_intc_initialized and use it in irqfd
   KVM: arm/arm64: implement kvm_arch_intc_initialized
   KVM: arm/arm64: remove coarse grain dist locking at 
 kvm_vgic_sync_hwstate
   KVM: arm/arm64: add irqfd support
 
 Marc Zyngier (3):
   arm/arm64: KVM: Allow handle_hva_to_gpa to return a value
   arm/arm64: KVM: Implement Stage-2 page aging
   arm/arm64: KVM: Optimize handling of Access Flag faults
 
 Mark Rutland (1):
   KVM: vgic: add virt-capable compatible strings
 
 Nikolay Nikolaev (2):
   KVM: Redesign kvm_io_bus_ API to pass VCPU structure to the callbacks.
   KVM: arm/arm64: enable KVM_CAP_IOEVENTFD
 
 Paolo Bonzini (1):
   KVM: arm/arm64: prefer IS_ENABLED to a static variable
 
  Documentation/virtual/kvm/api.txt |  22 +-
  arch/arm/include/asm/kvm_arm.h|   1 +
  arch/arm/include/asm/kvm_host.h   |  15 +-
  arch/arm/include/asm/kvm_mmio.h   |  22 --
  arch/arm/include/uapi/asm/kvm.h   |   3 +
  arch/arm/kernel/asm-offsets.c |   4 -
  arch/arm/kvm/Kconfig  |  30 +--
  arch/arm/kvm/Makefile |  12 +-
  arch/arm/kvm/arm.c|  45 ++--
  arch/arm/kvm/guest.c  |  18 --
  arch/arm/kvm/interrupts_head.S|   8 -
  arch/arm/kvm/mmio.c   |  64 ++---
  arch/arm/kvm/mmu.c| 134 ++-
  arch/arm/kvm/trace.h  |  48 
  arch/arm64/include/asm/esr.h  |   1 +
  arch/arm64/include/asm/kvm_arm.h  |   1 +
  arch/arm64/include/asm/kvm_host.h |  15 +-
  arch/arm64/include/asm/kvm_mmio.h |  22 --
  arch/arm64/include/uapi/asm/kvm.h |   3 +
  arch/arm64/kvm/Kconfig|  18 +-
  arch/arm64/kvm/Makefile   |  20 +-
  arch/powerpc/kvm/mpic.c   |  12 +-
  arch/powerpc/kvm/powerpc.c|   4 +-
  arch/s390/kvm/diag.c  |   2 +-
  arch/x86/kvm/Makefile |   2 +-
  arch/x86/kvm/i8254.c  |  14 +-
  arch/x86/kvm/i8254.h  |   2 +-
  arch/x86/kvm/i8259.c  |  12 +-
  arch/x86/kvm/ioapic.c |   8 +-
  arch/x86/kvm/ioapic.h |   2 +-
  arch/x86/kvm/irq.h|   2 +-
  arch/x86/kvm/lapic.c  |   4 +-
  arch/x86/kvm/lapic.h  |   2 +-
  arch/x86/kvm/vmx.c|   2 +-
  arch/x86/kvm/x86.c|  13 +-
  include/kvm/arm_arch_timer.h  |  31 +--
  include/kvm/arm_vgic.h| 117 ++
  {virt = include}/kvm/iodev.h |  28 ++-
  include/linux/kvm_host.h  |  24 +-
  virt/kvm/arm/arch_timer.c |  45 +++-
  virt/kvm/arm/vgic-v2-emul.c   |  71 +++---
  virt/kvm/arm/vgic-v3-emul.c   | 246 ++--
  virt/kvm/arm/vgic.c   

Re: [PATCH v2 06/10] KVM: arm64: guest debug, add SW break point support

2015-04-02 Thread Alex Bennée

David Hildenbrand d...@linux.vnet.ibm.com writes:

 This adds support for SW breakpoints inserted by userspace.
 
 We do this by trapping all BKPT exceptions in the
 hypervisor (MDCR_EL2_TDE). The kvm_debug_exit_arch carries the address
 of the exception. If user-space doesn't know of the breakpoint then we
 have a guest inserted breakpoint and the hypervisor needs to start again
 and deliver the exception to guest.
 
 Signed-off-by: Alex Bennée alex.ben...@linaro.org
 
 ---
 v2
   - update to use new exit struct
   - tweak for C setup
   - do our setup in debug_setup/clear code
   - fixed up comments
 
 diff --git a/Documentation/virtual/kvm/api.txt 
 b/Documentation/virtual/kvm/api.txt
 index 06c5064..17d4f9c 100644
 --- a/Documentation/virtual/kvm/api.txt
 +++ b/Documentation/virtual/kvm/api.txt
 @@ -2626,7 +2626,7 @@ when running. Common control bits are:
  The top 16 bits of the control field are architecture specific control
  flags which can include the following:
 
 -  - KVM_GUESTDBG_USE_SW_BP: using software breakpoints [x86]
 +  - KVM_GUESTDBG_USE_SW_BP: using software breakpoints [x86, arm64]
- KVM_GUESTDBG_USE_HW_BP: using hardware breakpoints [x86, s390]
- KVM_GUESTDBG_INJECT_DB: inject DB type exception [x86]
- KVM_GUESTDBG_INJECT_BP: inject BP type exception [x86]
 diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
 index 7ea8b0e..d3bc8dc 100644
 --- a/arch/arm/kvm/arm.c
 +++ b/arch/arm/kvm/arm.c
 @@ -304,7 +304,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
  kvm_arm_set_running_vcpu(NULL);
  }
 
 -#define KVM_GUESTDBG_VALID (KVM_GUESTDBG_ENABLE)
 +#define KVM_GUESTDBG_VALID (KVM_GUESTDBG_ENABLE|KVM_GUESTDBG_USE_SW_BP)
 
  int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
  struct kvm_guest_debug *dbg)
 diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
 index 8a29d0b..cff0475 100644
 --- a/arch/arm64/kvm/debug.c
 +++ b/arch/arm64/kvm/debug.c
 @@ -45,11 +45,18 @@ void kvm_arch_setup_debug(struct kvm_vcpu *vcpu)
  vcpu-arch.mdcr_el2 |= (MDCR_EL2_TPM | MDCR_EL2_TPMCR);
  vcpu-arch.mdcr_el2 |= (MDCR_EL2_TDRA | MDCR_EL2_TDOSA);
 
 +/* Trap debug register access? */

 This should probably go to the earlier patch.

Agreed.


  if (!vcpu-arch.debug_flags  KVM_ARM64_DEBUG_DIRTY)
  vcpu-arch.mdcr_el2 |= MDCR_EL2_TDA;
  else
  vcpu-arch.mdcr_el2 = ~MDCR_EL2_TDA;
 
 +/* Trap breakpoints? */
 +if (vcpu-guest_debug  KVM_GUESTDBG_USE_SW_BP)
 +vcpu-arch.mdcr_el2 |= MDCR_EL2_TDE;
 +else
 +vcpu-arch.mdcr_el2 = ~MDCR_EL2_TDE;

 Again, a candidate for clear_debug?

I don't follow. Changes to mdcr_el2 will only get applied as we jump in
through the hyp.S code. We need to ensure the guest can use SW BKPTs if
we are not.


 +
  }
 
  void kvm_arch_clear_debug(struct kvm_vcpu *vcpu)
 diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
 index 524fa25..ed1bbb4 100644
 --- a/arch/arm64/kvm/handle_exit.c
 +++ b/arch/arm64/kvm/handle_exit.c
 @@ -82,6 +82,37 @@ static int kvm_handle_wfx(struct kvm_vcpu *vcpu, struct 
 kvm_run *run)
  return 1;
  }
 
 +/**
 + * kvm_handle_debug_exception - handle a debug exception instruction

 kvm_handle_guest_debug

Sure.


 + *
 + * @vcpu:   the vcpu pointer
 + * @run:access to the kvm_run structure for results
 + *
 + * We route all debug exceptions through the same handler as we
 + * just need to report the PC and the HSR values to userspace.
 + * Userspace may decide to re-inject the exception and deliver it to
 + * the guest if it wasn't for the host to deal with.
 + */
 +static int kvm_handle_guest_debug(struct kvm_vcpu *vcpu, struct kvm_run 
 *run)
 +{
 +u32 hsr = kvm_vcpu_get_hsr(vcpu);
 +
 +run-exit_reason = KVM_EXIT_DEBUG;
 +run-debug.arch.hsr = hsr;
 +
 +switch (hsr  ESR_ELx_EC_SHIFT) {
 +case ESR_ELx_EC_BKPT32:
 +case ESR_ELx_EC_BRK64:
 +run-debug.arch.pc = *vcpu_pc(vcpu);
 +break;
 +default:
 +kvm_err(%s: un-handled case hsr: %#08x\n,
 +__func__, (unsigned int) hsr);

 Don't you want to fail hard in this case? This might result in many messages.
 returning 0 feels wrong.

You mean a BUG_ON()? Although it would be a cock up on the hosts part to
have an un-handled exception enabled allowing the guest to trigger a
host panic seems excessive.


 +break;
 +}
 +return 0;
 +}
 +
  static exit_handle_fn arm_exit_handlers[] = {
  [ESR_ELx_EC_WFx]= kvm_handle_wfx,
  [ESR_ELx_EC_CP15_32]= kvm_handle_cp15_32,
 @@ -96,6 +127,8 @@ static exit_handle_fn arm_exit_handlers[] = {
  [ESR_ELx_EC_SYS64]  = kvm_handle_sys_reg,
  [ESR_ELx_EC_IABT_LOW]   = kvm_handle_guest_abort,
  [ESR_ELx_EC_DABT_LOW]   = kvm_handle_guest_abort,
 +[ESR_ELx_EC_BKPT32] = kvm_handle_guest_debug,
 +[ESR_ELx_EC_BRK64]  = kvm_handle_guest_debug,
  };
 
  

Re: [PATCH] KVM: arm64: add gic-400 compatible

2015-04-02 Thread Mark Rutland
Hi,

On Thu, Apr 02, 2015 at 08:47:21AM +0100, AKASHI Takahiro wrote:
 Ping.
 This patch was acked but has never been merged?

There's a more complete patch in the kvmarm tree, queued for 4.1 [1]. It
adds both arm,gic-400 and arm,cortex-a7-gic.

Mark.

[1] 
https://git.kernel.org/cgit/linux/kernel/git/kvmarm/kvmarm.git/commit/?h=queueid=0f37247574b3ef5b130116bbf7c0f9eb8a4c78c2

 
 -Takahiro AKASHI
 
 On 09/09/2014 07:21 AM, Joel Schopp wrote:
  Add a one liner to identify the gic-400.  It's gicv2 with optional MSI 
  extensions.
 
  Cc: Christoffer Dall christoffer.d...@linaro.org
  Signed-off-by: Joel Schopp joel.sch...@amd.com
  ---
virt/kvm/arm/vgic.c |1 +
1 file changed, 1 insertion(+)
 
  diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
  index 73eba79..e81444e 100644
  --- a/virt/kvm/arm/vgic.c
  +++ b/virt/kvm/arm/vgic.c
  @@ -1550,6 +1550,7 @@ static struct notifier_block vgic_cpu_nb = {
 
static const struct of_device_id vgic_ids[] = {
  { .compatible = arm,cortex-a15-gic, .data = vgic_v2_probe, },
  +   { .compatible = arm,gic-400, .data = vgic_v2_probe, },
  { .compatible = arm,gic-v3, .data = vgic_v3_probe, },
  {},
};
 
 
  ___
  linux-arm-kernel mailing list
  linux-arm-ker...@lists.infradead.org
  http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
 
 ___
 kvmarm mailing list
 kvmarm@lists.cs.columbia.edu
 https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
 
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm