[PATCH 11/13] KVM: arm64: implement ITS command queue command handlers

2015-05-29 Thread Andre Przywara
The connection between a device, an event ID, the LPI number and the
allocated CPU is stored in in-memory tables in a GICv3, but their
format is not specified by the spec. Instead software uses a command
queue to let the ITS implementation use their own format.
Implement handlers for the various ITS commands and let them store
the requested relation into our own data structures.
Error handling is very basic at this point, as we don't have a good
way of communicating errors to the guest (usually a SError).

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 include/linux/irqchip/arm-gic-v3.h |   1 +
 virt/kvm/arm/its-emul.c| 422 -
 virt/kvm/arm/its-emul.h|  11 +
 3 files changed, 433 insertions(+), 1 deletion(-)

diff --git a/include/linux/irqchip/arm-gic-v3.h 
b/include/linux/irqchip/arm-gic-v3.h
index 0b450c7..651aacc 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -254,6 +254,7 @@
 #define GITS_CMD_MAPD  0x08
 #define GITS_CMD_MAPC  0x09
 #define GITS_CMD_MAPVI 0x0a
+#define GITS_CMD_MAPI  0x0b
 #define GITS_CMD_MOVI  0x01
 #define GITS_CMD_DISCARD   0x0f
 #define GITS_CMD_INV   0x0c
diff --git a/virt/kvm/arm/its-emul.c b/virt/kvm/arm/its-emul.c
index afd440e..574cf05 100644
--- a/virt/kvm/arm/its-emul.c
+++ b/virt/kvm/arm/its-emul.c
@@ -22,6 +22,7 @@
 #include linux/kvm_host.h
 #include linux/interrupt.h
 #include linux/list.h
+#include linux/slab.h
 
 #include linux/irqchip/arm-gic-v3.h
 #include kvm/arm_vgic.h
@@ -55,6 +56,34 @@ struct its_itte {
unsigned long *pending;
 };
 
+static struct its_device *find_its_device(struct kvm *kvm, u32 device_id)
+{
+   struct vgic_its *its = kvm-arch.vgic.its;
+   struct its_device *device;
+
+   list_for_each_entry(device, its-device_list, dev_list)
+   if (device_id == device-device_id)
+   return device;
+
+   return NULL;
+}
+
+static struct its_itte *find_itte(struct kvm *kvm, u32 device_id, u32 event_id)
+{
+   struct its_device *device;
+   struct its_itte *itte;
+
+   device = find_its_device(kvm, device_id);
+   if (device == NULL)
+   return NULL;
+
+   list_for_each_entry(itte, device-itt, itte_list)
+   if (itte-event_id == event_id)
+   return itte;
+
+   return NULL;
+}
+
 #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)
@@ -71,6 +100,19 @@ static struct its_itte *find_itte_by_lpi(struct kvm *kvm, 
int lpi)
return NULL;
 }
 
+static struct its_collection *find_collection(struct kvm *kvm, int coll_id)
+{
+   struct its_collection *collection;
+
+   list_for_each_entry(collection, kvm-arch.vgic.its.collection_list,
+   coll_list) {
+   if (coll_id == collection-collection_id)
+   return collection;
+   }
+
+   return NULL;
+}
+
 #define LPI_PROP_ENABLE_BIT(p) ((p)  LPI_PROP_ENABLED)
 #define LPI_PROP_PRIORITY(p)   ((p)  0xfc)
 
@@ -345,9 +387,386 @@ void vits_unqueue_lpi(struct kvm_vcpu *vcpu, int lpi)
spin_unlock(its-lock);
 }
 
+static u64 its_cmd_mask_field(u64 *its_cmd, int word, int shift, int size)
+{
+   return (le64_to_cpu(its_cmd[word])  shift)  (BIT_ULL(size) - 1);
+}
+
+#define its_cmd_get_command(cmd)   its_cmd_mask_field(cmd, 0,  0,  8)
+#define its_cmd_get_deviceid(cmd)  its_cmd_mask_field(cmd, 0, 32, 32)
+#define its_cmd_get_id(cmd)its_cmd_mask_field(cmd, 1,  0, 32)
+#define its_cmd_get_physical_id(cmd)   its_cmd_mask_field(cmd, 1, 32, 32)
+#define its_cmd_get_collection(cmd)its_cmd_mask_field(cmd, 2,  0, 16)
+#define its_cmd_get_target_addr(cmd)   its_cmd_mask_field(cmd, 2, 16, 32)
+#define its_cmd_get_validbit(cmd)  its_cmd_mask_field(cmd, 2, 63,  1)
+
+/*
+ * Handles the DISCARD command, which frees an ITTE.
+ * Must be called with the ITS lock held.
+ */
+static int vits_cmd_handle_discard(struct kvm *kvm, u64 *its_cmd)
+{
+   u32 device_id;
+   u32 event_id;
+   struct its_itte *itte;
+
+   device_id = its_cmd_get_deviceid(its_cmd);
+   event_id = its_cmd_get_id(its_cmd);
+
+   itte = find_itte(kvm, device_id, event_id);
+   if (!itte || !itte-collection)
+   return E_ITS_DISCARD_UNMAPPED_INTERRUPT;
+
+   clear_bit(itte-collection-target_addr, itte-pending);
+
+   list_del(itte-itte_list);
+   kfree(itte);
+   return 0;
+}
+
+/*
+ * Handles the MOVI command, which moves an ITTE to a different collection.
+ * Must be called with the ITS lock held.
+ */
+static int vits_cmd_handle_movi(struct kvm *kvm, u64 *its_cmd)
+{
+   u32 device_id = its_cmd_get_deviceid(its_cmd);
+   u32 event_id = 

[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 

[PATCH v5 09/12] KVM: arm64: introduce vcpu-arch.debug_ptr

2015-05-29 Thread Alex Bennée
This introduces a level of indirection for the debug registers. Instead
of using the sys_regs[] directly we store registers in a structure in
the vcpu. As we are no longer tied to the layout of the sys_regs[] we
can make the copies size appropriate for control and value registers.

This also entails updating the sys_regs code to access this new
structure. Instead of passing a register index we now pass an offset
into the kvm_guest_debug_arch structure.

We also need to ensure the GET/SET_ONE_REG ioctl operations store the
registers in their correct location.

Signed-off-by: Alex Bennée alex.ben...@linaro.org
---
 arch/arm/kvm/arm.c|   3 +
 arch/arm64/include/asm/kvm_asm.h  |  24 +++-
 arch/arm64/include/asm/kvm_host.h |  12 +++-
 arch/arm64/kernel/asm-offsets.c   |   6 ++
 arch/arm64/kvm/hyp.S  | 107 +---
 arch/arm64/kvm/sys_regs.c | 126 +++---
 6 files changed, 188 insertions(+), 90 deletions(-)

diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 9b3ed6d..0d17c7b 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -279,6 +279,9 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
/* Set up the timer */
kvm_timer_vcpu_init(vcpu);
 
+   /* Set the debug registers to be the guests */
+   vcpu-arch.debug_ptr = vcpu-arch.vcpu_debug_state;
+
return 0;
 }
 
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index d6b507e..e997404 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -46,24 +46,16 @@
 #defineCNTKCTL_EL1 20  /* Timer Control Register (EL1) */
 #definePAR_EL1 21  /* Physical Address Register */
 #define MDSCR_EL1  22  /* Monitor Debug System Control Register */
-#define DBGBCR0_EL123  /* Debug Breakpoint Control Registers (0-15) */
-#define DBGBCR15_EL1   38
-#define DBGBVR0_EL139  /* Debug Breakpoint Value Registers (0-15) */
-#define DBGBVR15_EL1   54
-#define DBGWCR0_EL155  /* Debug Watchpoint Control Registers (0-15) */
-#define DBGWCR15_EL1   70
-#define DBGWVR0_EL171  /* Debug Watchpoint Value Registers (0-15) */
-#define DBGWVR15_EL1   86
-#define MDCCINT_EL187  /* Monitor Debug Comms Channel Interrupt Enable 
Reg */
+#define MDCCINT_EL123  /* Monitor Debug Comms Channel Interrupt Enable 
Reg */
 
 /* 32bit specific registers. Keep them at the end of the range */
-#defineDACR32_EL2  88  /* Domain Access Control Register */
-#defineIFSR32_EL2  89  /* Instruction Fault Status Register */
-#defineFPEXC32_EL2 90  /* Floating-Point Exception Control 
Register */
-#defineDBGVCR32_EL291  /* Debug Vector Catch Register */
-#defineTEECR32_EL1 92  /* ThumbEE Configuration Register */
-#defineTEEHBR32_EL193  /* ThumbEE Handler Base Register */
-#defineNR_SYS_REGS 94
+#defineDACR32_EL2  24  /* Domain Access Control Register */
+#defineIFSR32_EL2  25  /* Instruction Fault Status Register */
+#defineFPEXC32_EL2 26  /* Floating-Point Exception Control 
Register */
+#defineDBGVCR32_EL227  /* Debug Vector Catch Register */
+#defineTEECR32_EL1 28  /* ThumbEE Configuration Register */
+#defineTEEHBR32_EL129  /* ThumbEE Handler Base Register */
+#defineNR_SYS_REGS 30
 
 /* 32bit mapping */
 #define c0_MPIDR   (MPIDR_EL1 * 2) /* MultiProcessor ID Register */
diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h
index e2db6a6..e5040b6 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -108,11 +108,21 @@ struct kvm_vcpu_arch {
/* Exception Information */
struct kvm_vcpu_fault_info fault;
 
-   /* Debug state */
+   /* Guest debug state */
u64 debug_flags;
 
+   /*
+* For debugging the guest we need to keep a set of debug
+* registers which can override the guests own debug state
+* while being used. These are set via the KVM_SET_GUEST_DEBUG
+* ioctl.
+*/
+   struct kvm_guest_debug_arch *debug_ptr;
+   struct kvm_guest_debug_arch vcpu_debug_state;
+
/* Pointer to host CPU context */
kvm_cpu_context_t *host_cpu_context;
+   struct kvm_guest_debug_arch host_debug_state;
 
/* VGIC state */
struct vgic_cpu vgic_cpu;
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index dfb25a2..1a8e97c 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -116,10 +116,16 @@ int main(void)
   DEFINE(VCPU_FAR_EL2, offsetof(struct kvm_vcpu, arch.fault.far_el2));
   DEFINE(VCPU_HPFAR_EL2,   offsetof(struct kvm_vcpu, 
arch.fault.hpfar_el2));
   DEFINE(VCPU_DEBUG_FLAGS,   

[PATCH v5 01/12] KVM: add comments for kvm_debug_exit_arch struct

2015-05-29 Thread Alex Bennée
Bring into line with the comments for the other structures and their
KVM_EXIT_* cases. Also update api.txt to reflect use in kvm_run
documentation.

Signed-off-by: Alex Bennée alex.ben...@linaro.org
Reviewed-by: David Hildenbrand d...@linux.vnet.ibm.com
Reviewed-by: Andrew Jones drjo...@redhat.com
Acked-by: Christoffer Dall christoffer.d...@linaro.org

---

v2
  - add comments for other exit types
v3
  - s/commentary/comments/
  - add rb tags
  - update api.txt kvm_run to include KVM_EXIT_DEBUG desc
v4
  - sp fixes
  - add a-b
---
 Documentation/virtual/kvm/api.txt | 4 +++-
 include/uapi/linux/kvm.h  | 3 +++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index 9fa2bf8..c34c32d 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -3070,11 +3070,13 @@ data_offset describes where the data is located 
(KVM_EXIT_IO_OUT) or
 where kvm expects application code to place the data for the next
 KVM_RUN invocation (KVM_EXIT_IO_IN).  Data format is a packed array.
 
+   /* KVM_EXIT_DEBUG */
struct {
struct kvm_debug_exit_arch arch;
} debug;
 
-Unused.
+If the exit_reason is KVM_EXIT_DEBUG, then a vcpu is processing a debug event
+for which architecture specific information is returned.
 
/* KVM_EXIT_MMIO */
struct {
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 4b60056..70ac641 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -237,6 +237,7 @@ struct kvm_run {
__u32 count;
__u64 data_offset; /* relative to kvm_run start */
} io;
+   /* KVM_EXIT_DEBUG */
struct {
struct kvm_debug_exit_arch arch;
} debug;
@@ -285,6 +286,7 @@ struct kvm_run {
__u32 data;
__u8  is_write;
} dcr;
+   /* KVM_EXIT_INTERNAL_ERROR */
struct {
__u32 suberror;
/* Available with KVM_CAP_INTERNAL_ERROR_DATA: */
@@ -295,6 +297,7 @@ struct kvm_run {
struct {
__u64 gprs[32];
} osi;
+   /* KVM_EXIT_PAPR_HCALL */
struct {
__u64 nr;
__u64 ret;
-- 
2.4.1

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


[PATCH v5 05/12] KVM: arm: introduce kvm_arm_init/setup/clear_debug

2015-05-29 Thread Alex Bennée
This is a precursor for later patches which will need to do more to
setup debug state before entering the hyp.S switch code. The existing
functionality for setting mdcr_el2 has been moved out of hyp.S and now
uses the value kept in vcpu-arch.mdcr_el2.

As the assembler used to previously mask and preserve MDCR_EL2.HPMN I've
had to add a mechanism to save the value of mdcr_el2 as a per-cpu
variable during the initialisation code. The kernel never sets this
number so we are assuming the bootcode has set up the correct value
here.

This also moves the conditional setting of the TDA bit from the hyp code
into the C code which is currently used for the lazy debug register
context switch code.

Signed-off-by: Alex Bennée alex.ben...@linaro.org

---
v3
  - rename fns from arch-arm
  - preserve MDCR_EL2.HPMN setting
  - re-word some of the comments
  - fix some minor grammar nits
  - merge setting of mdcr_el2
  - introduce trap_debug flag
  - move setup/clear within the irq lock section
v4
  - fix TDOSA desc
  - rm un-needed else leg
  - s/arch/arm/
---
 arch/arm/include/asm/kvm_host.h   |  4 ++
 arch/arm/kvm/arm.c|  9 -
 arch/arm64/include/asm/kvm_asm.h  |  2 +
 arch/arm64/include/asm/kvm_host.h |  5 +++
 arch/arm64/kernel/asm-offsets.c   |  1 +
 arch/arm64/kvm/Makefile   |  2 +-
 arch/arm64/kvm/debug.c| 81 +++
 arch/arm64/kvm/hyp.S  | 19 -
 8 files changed, 110 insertions(+), 13 deletions(-)
 create mode 100644 arch/arm64/kvm/debug.c

diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index d71607c..746c0c69 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -236,4 +236,8 @@ static inline void kvm_arch_sync_events(struct kvm *kvm) {}
 static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
 
+static inline void kvm_arm_init_debug(void) {}
+static inline void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) {}
+static inline void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) {}
+
 #endif /* __ARM_KVM_HOST_H__ */
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 52a1d4d38..4a274e1 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -570,6 +570,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
continue;
}
 
+   kvm_arm_setup_debug(vcpu);
+
/**
 * Enter the guest
 */
@@ -582,7 +584,10 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
vcpu-mode = OUTSIDE_GUEST_MODE;
kvm_guest_exit();
trace_kvm_exit(kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu));
-   /*
+
+   kvm_arm_clear_debug(vcpu);
+
+/*
 * We may have taken a host interrupt in HYP mode (ie
 * while executing the guest). This interrupt is still
 * pending, as we haven't serviced it yet!
@@ -930,6 +935,8 @@ static void cpu_init_hyp_mode(void *dummy)
vector_ptr = (unsigned long)__kvm_hyp_vector;
 
__cpu_init_hyp_mode(boot_pgd_ptr, pgd_ptr, hyp_stack_ptr, vector_ptr);
+
+   kvm_arm_init_debug();
 }
 
 static int hyp_init_cpu_notify(struct notifier_block *self,
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 4f7310f..d6b507e 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -137,6 +137,8 @@ extern char __restore_vgic_v2_state[];
 extern char __save_vgic_v3_state[];
 extern char __restore_vgic_v3_state[];
 
+extern u32 __kvm_get_mdcr_el2(void);
+
 #endif
 
 #endif /* __ARM_KVM_ASM_H__ */
diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h
index f0f58c9..7cb99b5 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -103,6 +103,7 @@ struct kvm_vcpu_arch {
 
/* HYP configuration */
u64 hcr_el2;
+   u32 mdcr_el2;
 
/* Exception Information */
struct kvm_vcpu_fault_info fault;
@@ -250,4 +251,8 @@ static inline void kvm_arch_sync_events(struct kvm *kvm) {}
 static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
 
+void kvm_arm_init_debug(void);
+void kvm_arm_setup_debug(struct kvm_vcpu *vcpu);
+void kvm_arm_clear_debug(struct kvm_vcpu *vcpu);
+
 #endif /* __ARM64_KVM_HOST_H__ */
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index da675cc..dfb25a2 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -117,6 +117,7 @@ int main(void)
   DEFINE(VCPU_HPFAR_EL2,   offsetof(struct kvm_vcpu, 
arch.fault.hpfar_el2));
   DEFINE(VCPU_DEBUG_FLAGS,

[PATCH v5 10/12] KVM: arm64: guest debug, HW assisted debug support

2015-05-29 Thread Alex Bennée
This adds support for userspace to control the HW debug registers for
guest debug. In the debug ioctl we copy the IMPDEF defined number of
registers into a new register set called host_debug_state. There is now
a new vcpu parameter called debug_ptr which selects which register set
is to copied into the real registers when world switch occurs.

I've moved some helper functions into the hw_breakpoint.h header for
re-use.

As with single step we need to tweak the guest registers to enable the
exceptions so we need to save and restore those bits.

Two new capabilities have been added to the KVM_EXTENSION ioctl to allow
userspace to query the number of hardware break and watch points
available on the host hardware.

Signed-off-by: Alex Bennée alex.ben...@linaro.org

---
v2
   - switched to C setup
   - replace host debug registers directly into context
   - minor tweak to api docs
   - setup right register for debug
   - add FAR_EL2 to debug exit structure
   - add support for trapping debug register access
v3
   - remove stray trace statement
   - fix spacing around operators (various)
   - clean-up usage of trap_debug
   - introduce debug_ptr, replace excessive memcpy stuff
   - don't use memcpy in ioctl, just assign
   - update cap ioctl documentation
   - reword a number comments
   - rename host_debug_state-external_debug_state
v4
   - use the new u32/u64 split debug_ptr approach
   - fix some wording/comments
v5
   - don't set MDSCR_EL1.KDE (not needed)
---
 Documentation/virtual/kvm/api.txt  |  7 ++-
 arch/arm/kvm/arm.c |  7 +++
 arch/arm64/include/asm/hw_breakpoint.h | 12 +++
 arch/arm64/include/asm/kvm_host.h  |  3 ++-
 arch/arm64/include/uapi/asm/kvm.h  |  2 +-
 arch/arm64/kernel/hw_breakpoint.c  | 12 ---
 arch/arm64/kvm/debug.c | 37 +-
 arch/arm64/kvm/handle_exit.c   |  6 ++
 arch/arm64/kvm/reset.c | 12 +++
 include/uapi/linux/kvm.h   |  2 ++
 10 files changed, 80 insertions(+), 20 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index 33c8143..ada57df 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2668,7 +2668,7 @@ 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, arm64]
-  - KVM_GUESTDBG_USE_HW_BP: using hardware breakpoints [x86, s390]
+  - KVM_GUESTDBG_USE_HW_BP: using hardware breakpoints [x86, s390, arm64]
   - KVM_GUESTDBG_INJECT_DB: inject DB type exception [x86]
   - KVM_GUESTDBG_INJECT_BP: inject BP type exception [x86]
   - KVM_GUESTDBG_EXIT_PENDING:  trigger an immediate guest exit [s390]
@@ -2683,6 +2683,11 @@ updated to the correct (supplied) values.
 The second part of the structure is architecture specific and
 typically contains a set of debug registers.
 
+For arm64 the number of debug registers is implementation defined and
+can be determined by querying the KVM_CAP_GUEST_DEBUG_HW_BPS and
+KVM_CAP_GUEST_DEBUG_HW_WPS capabilities which return a positive number
+indicating the number of supported registers.
+
 When debug events exit the main run loop with the reason
 KVM_EXIT_DEBUG with the kvm_debug_exit_arch part of the kvm_run
 structure containing architecture specific debug information.
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 0d17c7b..6df47c1 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -307,6 +307,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
 
 #define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE |\
KVM_GUESTDBG_USE_SW_BP | \
+   KVM_GUESTDBG_USE_HW_BP | \
KVM_GUESTDBG_SINGLESTEP)
 
 /**
@@ -327,6 +328,12 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu 
*vcpu,
 
if (dbg-control  KVM_GUESTDBG_ENABLE) {
vcpu-guest_debug = dbg-control;
+
+   /* Hardware assisted Break and Watch points */
+   if (vcpu-guest_debug  KVM_GUESTDBG_USE_HW_BP) {
+   vcpu-arch.external_debug_state = dbg-arch;
+   }
+
} else {
/* If not enabled clear all flags */
vcpu-guest_debug = 0;
diff --git a/arch/arm64/include/asm/hw_breakpoint.h 
b/arch/arm64/include/asm/hw_breakpoint.h
index 52b484b..c450552 100644
--- a/arch/arm64/include/asm/hw_breakpoint.h
+++ b/arch/arm64/include/asm/hw_breakpoint.h
@@ -130,6 +130,18 @@ static inline void ptrace_hw_copy_thread(struct 
task_struct *task)
 }
 #endif
 
+/* Determine number of BRP registers available. */
+static inline int get_num_brps(void)
+{
+   return ((read_cpuid(ID_AA64DFR0_EL1)  12)  0xf) + 1;
+}
+
+/* Determine number of WRP registers available. */
+static inline int get_num_wrps(void)
+{
+   return 

[PATCH v4 0/4] Add support for for GICv2m and MSIs to arm-virt

2015-05-29 Thread Christoffer Dall
Now when we have a host generic PCIe controller in the virt board, it
would be nice to be able to use MSIs so that we can eventually enable
VHOST with KVM.

With these patches you can use MSIs with TCG and with KVM, but you still
need some fixes for the mapping of the IRQ index to the GSI number for
IRQFD to work.  A separate series that enables IRQFD and vhost
is available: ARM adaptations for vhost irqfd setup
https://lists.gnu.org/archive/html/qemu-devel/2015-04/msg01054.html)

Tested with KVM on XGene and with TCG by configuring a virtio-pci
network adapter for the guest and verifying MSIs going through as
expected.

Rebased on target-arm.next, see the individual patches for detailed
changelogs.

Christoffer Dall (4):
  target-arm: Add GIC phandle to VirtBoardInfo
  arm_gicv2m: Add GICv2m widget to support MSIs
  target-arm: Extend the gic node properties
  target-arm: Add the GICv2m to the virt board

 hw/arm/virt.c |  73 ++-
 hw/intc/Makefile.objs |   1 +
 hw/intc/arm_gicv2m.c  | 190 ++
 include/hw/arm/virt.h |   2 +
 4 files changed, 248 insertions(+), 18 deletions(-)
 create mode 100644 hw/intc/arm_gicv2m.c

-- 
2.1.2.330.g565301e.dirty

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


[PATCH v5 12/12] KVM: arm64: add trace points for guest_debug debug

2015-05-29 Thread Alex Bennée
This includes trace points for:
  kvm_arch_setup_guest_debug
  kvm_arch_clear_guest_debug

I've also added some generic register setting trace events and also a
trace point to dump the array of hardware registers.

Signed-off-by: Alex Bennée alex.ben...@linaro.org

---
v3
  - add trace event for debug access.
  - remove short trace #define, rename trace events
  - use __print_array with fixed array instead of own func
  - rationalise trace points (only one per register changed)
  - add vcpu ptr to the debug_setup trace
  - remove :: in prints
v4
  - u32/u64 split on debug registers
  - fix for renames
  - add tracing of traps/set_guest_debug
  - remove handle_guest_debug trace
v5
  - minor print fmt fix
  - rm pstate traces
---
 arch/arm/kvm/arm.c|   2 +
 arch/arm/kvm/trace.h  |  17 
 arch/arm64/kvm/debug.c|  35 +++-
 arch/arm64/kvm/sys_regs.c |  10 +
 arch/arm64/kvm/trace.h| 105 ++
 5 files changed, 168 insertions(+), 1 deletion(-)

diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 6df47c1..a939a4e 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -323,6 +323,8 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
 int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
struct kvm_guest_debug *dbg)
 {
+   trace_kvm_set_guest_debug(vcpu, dbg-control);
+
if (dbg-control  ~KVM_GUESTDBG_VALID_MASK)
return -EINVAL;
 
diff --git a/arch/arm/kvm/trace.h b/arch/arm/kvm/trace.h
index 0ec3539..3e346a6 100644
--- a/arch/arm/kvm/trace.h
+++ b/arch/arm/kvm/trace.h
@@ -317,6 +317,23 @@ TRACE_EVENT(kvm_toggle_cache,
  __entry-now ? on : off)
 );
 
+TRACE_EVENT(kvm_set_guest_debug,
+   TP_PROTO(struct kvm_vcpu *vcpu, __u32 guest_debug),
+   TP_ARGS(vcpu, guest_debug),
+
+   TP_STRUCT__entry(
+   __field(struct kvm_vcpu *, vcpu)
+   __field(__u32, guest_debug)
+   ),
+
+   TP_fast_assign(
+   __entry-vcpu = vcpu;
+   __entry-guest_debug = guest_debug;
+   ),
+
+   TP_printk(vcpu: %p, flags: 0x%08x, __entry-vcpu, 
__entry-guest_debug)
+);
+
 #endif /* _TRACE_KVM_H */
 
 #undef TRACE_INCLUDE_PATH
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index 3c0daae..97204b5 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -24,6 +24,8 @@
 #include asm/kvm_arm.h
 #include asm/kvm_emulate.h
 
+#include trace.h
+
 /* These are the bits of MDSCR_EL1 we may manipulate */
 #define MDSCR_EL1_DEBUG_MASK   (DBG_MDSCR_SS | \
DBG_MDSCR_KDE | \
@@ -46,11 +48,17 @@ static DEFINE_PER_CPU(u32, mdcr_el2);
 static void save_guest_debug_regs(struct kvm_vcpu *vcpu)
 {
vcpu-arch.guest_debug_preserved.mdscr_el1 = vcpu_sys_reg(vcpu, 
MDSCR_EL1);
+
+   trace_kvm_arm_set_dreg32(Saved MDSCR_EL1,
+   vcpu-arch.guest_debug_preserved.mdscr_el1);
 }
 
 static void restore_guest_debug_regs(struct kvm_vcpu *vcpu)
 {
vcpu_sys_reg(vcpu, MDSCR_EL1) = 
vcpu-arch.guest_debug_preserved.mdscr_el1;
+
+   trace_kvm_arm_set_dreg32(Restored MDSCR_EL1,
+   vcpu_sys_reg(vcpu, MDSCR_EL1));
 }
 
 /**
@@ -92,6 +100,8 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
 {
bool trap_debug = !(vcpu-arch.debug_flags  KVM_ARM64_DEBUG_DIRTY);
 
+   trace_kvm_arm_setup_debug(vcpu, vcpu-guest_debug);
+
vcpu-arch.mdcr_el2 = __this_cpu_read(mdcr_el2)  MDCR_EL2_HPMN_MASK;
vcpu-arch.mdcr_el2 |= (MDCR_EL2_TPM |
MDCR_EL2_TPMCR |
@@ -121,6 +131,8 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
vcpu_sys_reg(vcpu, MDSCR_EL1) = ~DBG_MDSCR_SS;
}
 
+   trace_kvm_arm_set_dreg32(SPSR_EL2, *vcpu_cpsr(vcpu));
+
/*
 * HW Break/Watch points
 *
@@ -137,16 +149,29 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
vcpu-arch.debug_ptr = vcpu-arch.external_debug_state;
vcpu-arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY;
trap_debug = true;
+
+   trace_kvm_arm_set_regset(BKPTS, get_num_brps(),
+   
vcpu-arch.debug_ptr-dbg_bcr[0],
+   
vcpu-arch.debug_ptr-dbg_bvr[0]);
+
+   trace_kvm_arm_set_regset(WAPTS, get_num_wrps(),
+   
vcpu-arch.debug_ptr-dbg_wcr[0],
+   
vcpu-arch.debug_ptr-dbg_wvr[0]);
}
}
 
/* Trap debug register access */
if (trap_debug)
vcpu-arch.mdcr_el2 |= MDCR_EL2_TDA;
+
+   trace_kvm_arm_set_dreg32(MDCR_EL2, vcpu-arch.mdcr_el2);
+   trace_kvm_arm_set_dreg32(MDSCR_EL1, vcpu_sys_reg(vcpu, 

[PATCH v5 11/12] KVM: arm64: enable KVM_CAP_SET_GUEST_DEBUG

2015-05-29 Thread Alex Bennée
Finally advertise the KVM capability for SET_GUEST_DEBUG. Once arm
support is added this check can be moved to the common
kvm_vm_ioctl_check_extension() code.

Signed-off-by: Alex Bennée alex.ben...@linaro.org
Acked-by: Christoffer Dall christoffer.d...@linaro.org

---

v3:
 - separated capability check from previous patches
 - moved into arm64 specific ioctl handler.
v4:
 - add a-b-tag
---
 arch/arm64/kvm/reset.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 21d5a62..88e5331 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -76,6 +76,9 @@ int kvm_arch_dev_ioctl_check_extension(long ext)
case KVM_CAP_GUEST_DEBUG_HW_WPS:
r  = get_num_wrps();
break;
+   case KVM_CAP_SET_GUEST_DEBUG:
+   r = 1;
+   break;
default:
r = 0;
}
-- 
2.4.1

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


[PATCH v5 00/12] KVM Guest Debug support for arm64

2015-05-29 Thread Alex Bennée
Here is V5 of the KVM Guest Debug support for arm64.

The changes are fairly minimal from the last round:

  - dropped KVM_GUESTDBG_USE_SW/HW_BP unifying patch (ABI break)
  - new comment patch to fix comments in hyp.S (also sent separately)
  - simplified singlestep code (no longer needs to preserve pstate)
  - don't set MDSCR_EL1.KDE (not needed)

For full details see the changelog on each of the patches.

GIT Repos:

The patches for this series are based off v4.1-rc5 and can be found
at:

https://git.linaro.org/people/alex.bennee/linux.git
branch: guest-debug/4.1-rc5-v5

While adding debug exception injection support into QEMU I ran into
problem with GDB in the guest which relies on working single step
support. So while guest SW BKPTs get delivered (and HW BKPTs if the
host is not using them) GDB tends to get confused as it tries to
single step. If the host isn't doing any debugging of the guest then
everything works as normal.

The actual solution would be to fully emulate single step in QEMU by
creating a new debug event when the guest sets MDSCR_EL1.SS. QEMU
would then need to ensure the correct position is reached while
honouring the guests setting of MDSCR_EL1.KDE. However this would be a
bunch of potentially hairy new code so I've left this as an exercise
for a future patch series.

https://github.com/stsquad/qemu
branch: kvm/guest-debug-v5

Alex Bennée (12):
  KVM: add comments for kvm_debug_exit_arch struct
  KVM: arm64: fix misleading comments in save/restore
  KVM: arm64: guest debug, define API headers
  KVM: arm: guest debug, add stub KVM_SET_GUEST_DEBUG ioctl
  KVM: arm: introduce kvm_arm_init/setup/clear_debug
  KVM: arm64: guest debug, add SW break point support
  KVM: arm64: guest debug, add support for single-step
  KVM: arm64: re-factor hyp.S debug register code
  KVM: arm64: introduce vcpu-arch.debug_ptr
  KVM: arm64: guest debug, HW assisted debug support
  KVM: arm64: enable KVM_CAP_SET_GUEST_DEBUG
  KVM: arm64: add trace points for guest_debug debug

 Documentation/virtual/kvm/api.txt  |  15 +-
 arch/arm/include/asm/kvm_host.h|   4 +
 arch/arm/kvm/arm.c |  46 ++-
 arch/arm/kvm/trace.h   |  17 +
 arch/arm64/include/asm/hw_breakpoint.h |  12 +
 arch/arm64/include/asm/kvm_asm.h   |  26 +-
 arch/arm64/include/asm/kvm_host.h  |  29 +-
 arch/arm64/include/uapi/asm/kvm.h  |  20 ++
 arch/arm64/kernel/asm-offsets.c|   7 +
 arch/arm64/kernel/hw_breakpoint.c  |  12 -
 arch/arm64/kvm/Makefile|   2 +-
 arch/arm64/kvm/debug.c | 194 
 arch/arm64/kvm/handle_exit.c   |  44 +++
 arch/arm64/kvm/hyp.S   | 551 ++---
 arch/arm64/kvm/reset.c |  15 +
 arch/arm64/kvm/sys_regs.c  | 136 ++--
 arch/arm64/kvm/trace.h | 105 +++
 include/uapi/linux/kvm.h   |   5 +
 18 files changed, 788 insertions(+), 452 deletions(-)
 create mode 100644 arch/arm64/kvm/debug.c

-- 
2.4.1

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


[PATCH v5 04/12] KVM: arm: guest debug, add stub KVM_SET_GUEST_DEBUG ioctl

2015-05-29 Thread Alex Bennée
This commit adds a stub function to support the KVM_SET_GUEST_DEBUG
ioctl. Any unsupported flag will return -EINVAL. For now, only
KVM_GUESTDBG_ENABLE is supported, although it won't have any effects.

Signed-off-by: Alex Bennée alex.ben...@linaro.org.
Reviewed-by: Christoffer Dall christoffer.d...@linaro.org

---
v2
  - simplified form of the ioctl (stuff will go into setup_debug)
v3
 - KVM_GUESTDBG_VALID-KVM_GUESTDBG_VALID_MASK
 - move mask check to the top of function
 - add ioctl doc header
 - split capability into separate patch
 - tweaked commit wording w.r.t return of -EINVAL
v4
 - add r-b-tag
---
 Documentation/virtual/kvm/api.txt |  2 +-
 arch/arm/kvm/arm.c| 23 ++-
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index c34c32d..ba635c7 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2645,7 +2645,7 @@ handled.
 4.87 KVM_SET_GUEST_DEBUG
 
 Capability: KVM_CAP_SET_GUEST_DEBUG
-Architectures: x86, s390, ppc
+Architectures: x86, s390, ppc, arm64
 Type: vcpu ioctl
 Parameters: struct kvm_guest_debug (in)
 Returns: 0 on success; -1 on error
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index d9631ec..52a1d4d38 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -302,10 +302,31 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
kvm_arm_set_running_vcpu(NULL);
 }
 
+#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE)
+
+/**
+ * kvm_arch_vcpu_ioctl_set_guest_debug - set up guest debugging
+ * @kvm:   pointer to the KVM struct
+ * @kvm_guest_debug: the ioctl data buffer
+ *
+ * This sets up and enables the VM for guest debugging. Userspace
+ * passes in a control flag to enable different debug types and
+ * potentially other architecture specific information in the rest of
+ * the structure.
+ */
 int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
struct kvm_guest_debug *dbg)
 {
-   return -EINVAL;
+   if (dbg-control  ~KVM_GUESTDBG_VALID_MASK)
+   return -EINVAL;
+
+   if (dbg-control  KVM_GUESTDBG_ENABLE) {
+   vcpu-guest_debug = dbg-control;
+   } else {
+   /* If not enabled clear all flags */
+   vcpu-guest_debug = 0;
+   }
+   return 0;
 }
 
 
-- 
2.4.1

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


[PATCH v5 07/12] KVM: arm64: guest debug, add support for single-step

2015-05-29 Thread Alex Bennée
This adds support for single-stepping the guest. To do this we need to
manipulate the guests PSTATE.SS and MDSCR_EL1.SS bits which we do in the
kvm_arm_setup/clear_debug() so we don't affect the apparent state of the
guest. Additionally while the host is debugging the guest we suppress
the ability of the guest to single-step itself.

Signed-off-by: Alex Bennée alex.ben...@linaro.org

---
v2
  - Move pstate/mdscr manipulation into C
  - don't export guest_debug to assembly
  - add accessor for saved_debug regs
  - tweak save/restore of mdscr_el1
v3
  - don't save PC in debug information struct
  - rename debug_saved_regs-guest_debug_state
  - save whole value, only use bits in restore
  - add save/restore_guest-debug_regs helper functions
  - simplify commit message for clarity
  - rm vcpu_debug_saved_reg access fn
v4
  - added more comments based on suggestions
  - guest_debug_state-guest_debug_preserved
  - no point masking restore, we will trap out
v5
  - more comments
  - don't bother preserving pstate.ss
---
 arch/arm/kvm/arm.c|  4 ++-
 arch/arm64/include/asm/kvm_host.h | 11 
 arch/arm64/kvm/debug.c| 58 ---
 arch/arm64/kvm/handle_exit.c  |  2 ++
 4 files changed, 70 insertions(+), 5 deletions(-)

diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 064c105..9b3ed6d 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -302,7 +302,9 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
kvm_arm_set_running_vcpu(NULL);
 }
 
-#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP)
+#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE |\
+   KVM_GUESTDBG_USE_SW_BP | \
+   KVM_GUESTDBG_SINGLESTEP)
 
 /**
  * kvm_arch_vcpu_ioctl_set_guest_debug - set up guest debugging
diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h
index 7cb99b5..e2db6a6 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -123,6 +123,17 @@ struct kvm_vcpu_arch {
 * here.
 */
 
+   /*
+* Guest registers we preserve during guest debugging.
+*
+* These shadow registers are updated by the kvm_handle_sys_reg
+* trap handler if the guest accesses or updates them while we
+* are using guest debug.
+*/
+   struct {
+   u32 mdscr_el1;
+   } guest_debug_preserved;
+
/* Don't run the guest */
bool pause;
 
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index 8d1bfa4..10a6baa 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -19,11 +19,41 @@
 
 #include linux/kvm_host.h
 
+#include asm/debug-monitors.h
+#include asm/kvm_asm.h
 #include asm/kvm_arm.h
+#include asm/kvm_emulate.h
+
+/* These are the bits of MDSCR_EL1 we may manipulate */
+#define MDSCR_EL1_DEBUG_MASK   (DBG_MDSCR_SS | \
+   DBG_MDSCR_KDE | \
+   DBG_MDSCR_MDE)
 
 static DEFINE_PER_CPU(u32, mdcr_el2);
 
 /**
+ * save/restore_guest_debug_regs
+ *
+ * For some debug operations we need to tweak some guest registers. As
+ * a result we need to save the state of those registers before we
+ * make those modifications. This does get confused if the guest
+ * attempts to control single step while being debugged. It will start
+ * working again once it is no longer being debugged by the host.
+ *
+ * Guest access to MDSCR_EL1 is trapped by the hypervisor and handled
+ * after we have restored the preserved value to the main context.
+ */
+static void save_guest_debug_regs(struct kvm_vcpu *vcpu)
+{
+   vcpu-arch.guest_debug_preserved.mdscr_el1 = vcpu_sys_reg(vcpu, 
MDSCR_EL1);
+}
+
+static void restore_guest_debug_regs(struct kvm_vcpu *vcpu)
+{
+   vcpu_sys_reg(vcpu, MDSCR_EL1) = 
vcpu-arch.guest_debug_preserved.mdscr_el1;
+}
+
+/**
  * kvm_arm_init_debug - grab what we need for debug
  *
  * Currently the sole task of this function is to retrieve the initial
@@ -38,7 +68,6 @@ void kvm_arm_init_debug(void)
__this_cpu_write(mdcr_el2, kvm_call_hyp(__kvm_get_mdcr_el2));
 }
 
-
 /**
  * kvm_arm_setup_debug - set up debug related stuff
  *
@@ -73,12 +102,33 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
if (trap_debug)
vcpu-arch.mdcr_el2 |= MDCR_EL2_TDA;
 
-   /* Trap breakpoints? */
-   if (vcpu-guest_debug  KVM_GUESTDBG_USE_SW_BP)
+   /* Is Guest debugging in effect? */
+   if (vcpu-guest_debug) {
vcpu-arch.mdcr_el2 |= MDCR_EL2_TDE;
+
+   /* Save guest debug state */
+   save_guest_debug_regs(vcpu);
+
+   /*
+* Single Step (ARM ARM D2.12.3 The software step state
+* machine)
+*
+* If we are doing Single Step we need to manipulate
+* MDSCR_EL1.SS and PSTATE.SS. If not we need to
+

[PATCH v5 02/12] KVM: arm64: fix misleading comments in save/restore

2015-05-29 Thread Alex Bennée
The elr_el2 and spsr_el2 registers in fact contain the processor state
before entry into the hypervisor code. In the case of guest state it
could be in either el0 or el1.

Signed-off-by: Alex Bennée alex.ben...@linaro.org
---
 arch/arm64/kvm/hyp.S | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
index 5befd01..cb9bdd8 100644
--- a/arch/arm64/kvm/hyp.S
+++ b/arch/arm64/kvm/hyp.S
@@ -50,8 +50,8 @@
stp x29, lr, [x3, #80]
 
mrs x19, sp_el0
-   mrs x20, elr_el2// EL1 PC
-   mrs x21, spsr_el2   // EL1 pstate
+   mrs x20, elr_el2// PC before hyp entry
+   mrs x21, spsr_el2   // pstate before hyp entry
 
stp x19, x20, [x3, #96]
str x21, [x3, #112]
@@ -82,8 +82,8 @@
ldr x21, [x3, #16]
 
msr sp_el0, x19
-   msr elr_el2, x20// EL1 PC
-   msr spsr_el2, x21   // EL1 pstate
+   msr elr_el2, x20// PC to restore
+   msr spsr_el2, x21   // pstate to restore
 
add x3, x2, #CPU_XREG_OFFSET(19)
ldp x19, x20, [x3]
-- 
2.4.1

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


[PATCH v5 06/12] KVM: arm64: guest debug, add SW break point support

2015-05-29 Thread Alex Bennée
This adds support for SW breakpoints inserted by userspace.

We do this by trapping all guest software debug exceptions to the
hypervisor (MDCR_EL2.TDE). The exit handler sets an exit reason of
KVM_EXIT_DEBUG with the kvm_debug_exit_arch structure holding the
exception syndrome information.

It will be up to userspace to extract the PC (via GET_ONE_REG) and
determine if the debug event was for a breakpoint it inserted. If not
userspace will need to re-inject the correct exception restart the
hypervisor to deliver the debug exception to the guest.

Any other guest software debug exception (e.g. single step or HW
assisted breakpoints) will cause an error and the VM to be killed. This
is addressed by later patches which add support for the other debug
types.

Signed-off-by: Alex Bennée alex.ben...@linaro.org
Reviewed-by: Christoffer Dall christoffer.d...@linaro.org

---
v2
  - update to use new exit struct
  - tweak for C setup
  - do our setup in debug_setup/clear code
  - fixed up comments
v3:
  - fix spacing in KVM_GUESTDBG_VALID_MASK
  - fix and clarify wording on kvm_handle_guest_debug
  - handle error case in kvm_handle_guest_debug
  - re-word the commit message
v4
  - rm else leg
  - add r-b-tag
---
 Documentation/virtual/kvm/api.txt |  2 +-
 arch/arm/kvm/arm.c|  2 +-
 arch/arm64/kvm/debug.c|  3 +++
 arch/arm64/kvm/handle_exit.c  | 36 
 4 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index ba635c7..33c8143 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2667,7 +2667,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 4a274e1..064c105 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -302,7 +302,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
kvm_arm_set_running_vcpu(NULL);
 }
 
-#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE)
+#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP)
 
 /**
  * kvm_arch_vcpu_ioctl_set_guest_debug - set up guest debugging
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index faf0e1f..8d1bfa4 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -73,6 +73,9 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
if (trap_debug)
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;
 }
 
 void kvm_arm_clear_debug(struct kvm_vcpu *vcpu)
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 524fa25..27f38a9 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -82,6 +82,40 @@ static int kvm_handle_wfx(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
return 1;
 }
 
+/**
+ * kvm_handle_guest_debug - handle a debug exception instruction
+ *
+ * @vcpu:  the vcpu pointer
+ * @run:   access to the kvm_run structure for results
+ *
+ * We route all debug exceptions through the same handler. If both the
+ * guest and host are using the same debug facilities it will be up to
+ * userspace to re-inject the correct exception for guest delivery.
+ *
+ * @return: 0 (while setting run-exit_reason), -1 for error
+ */
+static int kvm_handle_guest_debug(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+   u32 hsr = kvm_vcpu_get_hsr(vcpu);
+   int ret = 0;
+
+   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:
+   break;
+   default:
+   kvm_err(%s: un-handled case hsr: %#08x\n,
+   __func__, (unsigned int) hsr);
+   ret = -1;
+   break;
+   }
+
+   return ret;
+}
+
 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 +130,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,
 };
 
 static exit_handle_fn kvm_get_exit_handler(struct 

[PATCH v4 4/4] target-arm: Add the GICv2m to the virt board

2015-05-29 Thread Christoffer Dall
Add a GICv2m device to the virt board to enable MSIs on the generic PCI
host controller.  We allocate 64 SPIs in the IRQ space for now (this can
be increased/decreased later) and map the GICv2m right after the GIC in
the memory map.

Reviewed-by: Eric Auger eric.au...@linaro.org
Signed-off-by: Christoffer Dall christoffer.d...@linaro.org
---
Changes since v3:
 - Rebased on target-arm.next, so moved some definitions to virt.h
 - Added reviewed-by tag
Changes since v2:
 - Factored out changes to GIC DT node to previous patch.
 - Renamed QOM type name to arm-gicv2m
Changes since v1:
 - Remove stray merge conflict line
 - Reworded commmit message.

 hw/arm/virt.c | 40 +++-
 include/hw/arm/virt.h |  2 ++
 2 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 387dac8..4bb7175 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -70,6 +70,7 @@ typedef struct VirtBoardInfo {
 int fdt_size;
 uint32_t clock_phandle;
 uint32_t gic_phandle;
+uint32_t v2m_phandle;
 } VirtBoardInfo;
 
 typedef struct {
@@ -109,6 +110,7 @@ static const MemMapEntry a15memmap[] = {
 /* GIC distributor and CPU interfaces sit inside the CPU peripheral space 
*/
 [VIRT_GIC_DIST] =   { 0x0800, 0x0001 },
 [VIRT_GIC_CPU] ={ 0x0801, 0x0001 },
+[VIRT_GIC_V2M] ={ 0x0802, 0x1000 },
 [VIRT_UART] =   { 0x0900, 0x1000 },
 [VIRT_RTC] ={ 0x0901, 0x1000 },
 [VIRT_FW_CFG] = { 0x0902, 0x000a },
@@ -125,6 +127,7 @@ static const int a15irqmap[] = {
 [VIRT_RTC] = 2,
 [VIRT_PCIE] = 3, /* ... to 6 */
 [VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */
+[VIRT_GIC_V2M] = 48, /* ...to 48 + NUM_GICV2M_SPIS - 1 */
 };
 
 static VirtBoardInfo machines[] = {
@@ -300,9 +303,21 @@ static void fdt_add_cpu_nodes(const VirtBoardInfo *vbi)
 }
 }
 
-static void fdt_add_gic_node(VirtBoardInfo *vbi)
+static void fdt_add_v2m_gic_node(VirtBoardInfo *vbi)
 {
+vbi-v2m_phandle = qemu_fdt_alloc_phandle(vbi-fdt);
+qemu_fdt_add_subnode(vbi-fdt, /intc/v2m);
+qemu_fdt_setprop_string(vbi-fdt, /intc/v2m, compatible,
+arm,gic-v2m-frame);
+qemu_fdt_setprop(vbi-fdt, /intc/v2m, msi-controller, NULL, 0);
+qemu_fdt_setprop_sized_cells(vbi-fdt, /intc/v2m, reg,
+ 2, vbi-memmap[VIRT_GIC_V2M].base,
+ 2, vbi-memmap[VIRT_GIC_V2M].size);
+qemu_fdt_setprop_cell(vbi-fdt, /intc/v2m, phandle, vbi-v2m_phandle);
+}
 
+static void fdt_add_gic_node(VirtBoardInfo *vbi)
+{
 vbi-gic_phandle = qemu_fdt_alloc_phandle(vbi-fdt);
 qemu_fdt_setprop_cell(vbi-fdt, /, interrupt-parent, vbi-gic_phandle);
 
@@ -323,6 +338,25 @@ static void fdt_add_gic_node(VirtBoardInfo *vbi)
 qemu_fdt_setprop_cell(vbi-fdt, /intc, phandle, vbi-gic_phandle);
 }
 
+static void create_v2m(VirtBoardInfo *vbi, qemu_irq *pic)
+{
+int i;
+int irq = vbi-irqmap[VIRT_GIC_V2M];
+DeviceState *dev;
+
+dev = qdev_create(NULL, arm-gicv2m);
+sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vbi-memmap[VIRT_GIC_V2M].base);
+qdev_prop_set_uint32(dev, base-spi, irq);
+qdev_prop_set_uint32(dev, num-spi, NUM_GICV2M_SPIS);
+qdev_init_nofail(dev);
+
+for (i = 0; i  NUM_GICV2M_SPIS; i++) {
+sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
+}
+
+fdt_add_v2m_gic_node(vbi);
+}
+
 static void create_gic(VirtBoardInfo *vbi, qemu_irq *pic)
 {
 /* We create a standalone GIC v2 */
@@ -373,6 +407,8 @@ static void create_gic(VirtBoardInfo *vbi, qemu_irq *pic)
 }
 
 fdt_add_gic_node(vbi);
+
+create_v2m(vbi, pic);
 }
 
 static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic)
@@ -676,6 +712,8 @@ static void create_pcie(const VirtBoardInfo *vbi, qemu_irq 
*pic)
 qemu_fdt_setprop_cells(vbi-fdt, nodename, bus-range, 0,
nr_pcie_buses - 1);
 
+qemu_fdt_setprop_cells(vbi-fdt, nodename, msi-parent, vbi-v2m_phandle);
+
 qemu_fdt_setprop_sized_cells(vbi-fdt, nodename, reg,
  2, base_ecam, 2, size_ecam);
 qemu_fdt_setprop_sized_cells(vbi-fdt, nodename, ranges,
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index ceec8b3..003ef29 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -32,6 +32,7 @@
 
 #include qemu-common.h
 
+#define NUM_GICV2M_SPIS   64
 #define NUM_VIRTIO_TRANSPORTS 32
 
 #define ARCH_TIMER_VIRT_IRQ   11
@@ -53,6 +54,7 @@ enum {
 VIRT_PCIE_MMIO,
 VIRT_PCIE_PIO,
 VIRT_PCIE_ECAM,
+VIRT_GIC_V2M,
 };
 
 typedef struct MemMapEntry {
-- 
2.1.2.330.g565301e.dirty

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


[PATCH v4 3/4] target-arm: Extend the gic node properties

2015-05-29 Thread Christoffer Dall
In preparation for adding the GICv2m which requires address specifiers
and is a subnode of the gic, we extend the gic DT definition to specify
the #address-cells and #size-cells properties and add an empty ranges
property properties of the DT node, since this is required to add the
v2m node as a child of the gic node.

Note that we must also expand the irq-map to reference the gic with the
right address-cells as a consequence of this change.

Reviewed-by: Eric Auger eric.au...@linaro.org
Suggested-by: Shanker Donthineni shank...@codeaurora.org
Signed-off-by: Christoffer Dall christoffer.d...@linaro.org
---
Changes since v3:
 - Rewrote patch and changed authorship and tags accordingly
 - Fixed spelling in commit message
Changes since v2:
 - New separate patch factoring out changes to existing code for eased
   bisectability in case we broke something
 - The above fixes the issue with non-MSI compatible guests.

 hw/arm/virt.c | 11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index e5235ef..387dac8 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -317,6 +317,9 @@ static void fdt_add_gic_node(VirtBoardInfo *vbi)
  2, vbi-memmap[VIRT_GIC_DIST].size,
  2, vbi-memmap[VIRT_GIC_CPU].base,
  2, vbi-memmap[VIRT_GIC_CPU].size);
+qemu_fdt_setprop_cell(vbi-fdt, /intc, #address-cells, 0x2);
+qemu_fdt_setprop_cell(vbi-fdt, /intc, #size-cells, 0x2);
+qemu_fdt_setprop(vbi-fdt, /intc, ranges, NULL, 0);
 qemu_fdt_setprop_cell(vbi-fdt, /intc, phandle, vbi-gic_phandle);
 }
 
@@ -585,7 +588,7 @@ static void create_pcie_irq_map(const VirtBoardInfo *vbi, 
uint32_t gic_phandle,
 int first_irq, const char *nodename)
 {
 int devfn, pin;
-uint32_t full_irq_map[4 * 4 * 8] = { 0 };
+uint32_t full_irq_map[4 * 4 * 10] = { 0 };
 uint32_t *irq_map = full_irq_map;
 
 for (devfn = 0; devfn = 0x18; devfn += 0x8) {
@@ -598,13 +601,13 @@ static void create_pcie_irq_map(const VirtBoardInfo *vbi, 
uint32_t gic_phandle,
 uint32_t map[] = {
 devfn  8, 0, 0,   /* devfn */
 pin + 1,/* PCI pin */
-gic_phandle, irq_type, irq_nr, irq_level }; /* GIC irq */
+gic_phandle, 0, 0, irq_type, irq_nr, irq_level }; /* GIC irq */
 
 /* Convert map to big endian */
-for (i = 0; i  8; i++) {
+for (i = 0; i  10; i++) {
 irq_map[i] = cpu_to_be32(map[i]);
 }
-irq_map += 8;
+irq_map += 10;
 }
 }
 
-- 
2.1.2.330.g565301e.dirty

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


[PATCH v4 2/4] arm_gicv2m: Add GICv2m widget to support MSIs

2015-05-29 Thread Christoffer Dall
The ARM GICv2m widget is a little device that handles MSI interrupt
writes to a trigger register and ties them to a range of interrupt lines
wires to the GIC.  It has a few status/id registers and the interrupt wires,
and that's about it.

A board instantiates the device by setting the base SPI number and
number SPIs for the frame.  The base-spi parameter is indexed in the SPI
number space only, so base-spi == 0, means IRQ number 32.  When a device
(the PCI host controller) writes to the trigger register, the payload is
the GIC IRQ number, so we have to subtract 32 from that and then index
into our frame of SPIs.

When instantiating a GICv2m device, tell PCI that we have instantiated
something that can deal with MSIs.  We rely on the board actually wiring
up the GICv2m to the PCI host controller.

Reviewed-by: Eric Auger eric.au...@linaro.org
Signed-off-by: Christoffer Dall christoffer.d...@linaro.org
---
Changes since v3:
 - Added reviewed-by tag
Changes since v2:
 - Renamed QOM type to arm-gicv2m
Changes since v1:
 - Check that writes to MSI_SETSPI are within the lower boundary as well
 - Move gicv2m to common-obj in Makefile
 - Separate switch case and comment for impdef regs
 - Clearly document what is emulated
 - Allow 16 bit lower accesses to MSI_SETSPI regs
 - Fix commit grammar error
 - Remove stray pixman commit

 hw/intc/Makefile.objs |   1 +
 hw/intc/arm_gicv2m.c  | 190 ++
 2 files changed, 191 insertions(+)
 create mode 100644 hw/intc/arm_gicv2m.c

diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
index 843864a..092d8a8 100644
--- a/hw/intc/Makefile.objs
+++ b/hw/intc/Makefile.objs
@@ -11,6 +11,7 @@ common-obj-$(CONFIG_SLAVIO) += slavio_intctl.o
 common-obj-$(CONFIG_IOAPIC) += ioapic_common.o
 common-obj-$(CONFIG_ARM_GIC) += arm_gic_common.o
 common-obj-$(CONFIG_ARM_GIC) += arm_gic.o
+common-obj-$(CONFIG_ARM_GIC) += arm_gicv2m.o
 common-obj-$(CONFIG_OPENPIC) += openpic.o
 
 obj-$(CONFIG_APIC) += apic.o apic_common.o
diff --git a/hw/intc/arm_gicv2m.c b/hw/intc/arm_gicv2m.c
new file mode 100644
index 000..9f84f72
--- /dev/null
+++ b/hw/intc/arm_gicv2m.c
@@ -0,0 +1,190 @@
+/*
+ *  GICv2m extension for MSI/MSI-x support with a GICv2-based system
+ *
+ * Copyright (C) 2015 Linaro, All rights reserved.
+ *
+ * Author: Christoffer Dall christoffer.d...@linaro.org
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see http://www.gnu.org/licenses/.
+ */
+
+/* This file implements an emulated GICv2m widget as described in the ARM
+ * Server Base System Architecture (SBSA) specification Version 2.2
+ * (ARM-DEN-0029 v2.2) pages 35-39 without any optional implementation defined
+ * identification registers and with a single non-secure MSI register frame.
+ */
+
+#include hw/sysbus.h
+#include hw/pci/msi.h
+
+#define TYPE_ARM_GICV2M arm-gicv2m
+#define ARM_GICV2M(obj) OBJECT_CHECK(ARMGICv2mState, (obj), TYPE_ARM_GICV2M)
+
+#define GICV2M_NUM_SPI_MAX 128
+
+#define V2M_MSI_TYPER   0x008
+#define V2M_MSI_SETSPI_NS   0x040
+#define V2M_MSI_IIDR0xFCC
+#define V2M_IIDR0   0xFD0
+#define V2M_IIDR11  0xFFC
+
+#define PRODUCT_ID_QEMU 0x51 /* ASCII code Q */
+
+typedef struct ARMGICv2mState {
+SysBusDevice parent_obj;
+
+MemoryRegion iomem;
+qemu_irq spi[GICV2M_NUM_SPI_MAX];
+
+uint32_t base_spi;
+uint32_t num_spi;
+} ARMGICv2mState;
+
+static void gicv2m_set_irq(void *opaque, int irq)
+{
+ARMGICv2mState *s = (ARMGICv2mState *)opaque;
+
+qemu_irq_pulse(s-spi[irq]);
+}
+
+static uint64_t gicv2m_read(void *opaque, hwaddr offset,
+unsigned size)
+{
+ARMGICv2mState *s = (ARMGICv2mState *)opaque;
+uint32_t val;
+
+if (size != 4) {
+qemu_log_mask(LOG_GUEST_ERROR, gicv2m_read: bad size %u\n, size);
+return 0;
+}
+
+switch (offset) {
+case V2M_MSI_TYPER:
+val = (s-base_spi + 32)  16;
+val |= s-num_spi;
+return val;
+case V2M_MSI_IIDR:
+/* We don't have any valid implementor so we leave that field as zero
+ * and we return 0 in the arch revision as per the spec.
+ */
+return (PRODUCT_ID_QEMU  20);
+case V2M_IIDR0 ... V2M_IIDR11:
+/* We do not implement any optional identification registers and the
+ * mandatory MSI_PIDR2 register reads as 0x0, so we 

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

2015-05-29 Thread Andrew Jones
On Thu, May 28, 2015 at 01:34:33AM -0400, Wei Huang wrote:
 This patches enables ACPI support for KVM virtual GICv2. KVM parses
 ACPI table for virt GIC related information and initializes resources.
 
 Signed-off-by: Alexander Spyridaki a.spyrida...@virtualopensystems.com
 Signed-off-by: Wei Huang w...@redhat.com
 ---
  virt/kvm/arm/vgic-v2.c | 49 -
  1 file changed, 48 insertions(+), 1 deletion(-)
 
 diff --git a/virt/kvm/arm/vgic-v2.c b/virt/kvm/arm/vgic-v2.c
 index 711de82..01ce8a3 100644
 --- a/virt/kvm/arm/vgic-v2.c
 +++ b/virt/kvm/arm/vgic-v2.c
 @@ -264,6 +264,53 @@ int vgic_v2_acpi_probe(struct 
 acpi_madt_generic_interrupt *vgic_acpi,
  const struct vgic_ops **ops,
  const struct vgic_params **params)
  {
 - return -EINVAL;
 + struct vgic_params *vgic = vgic_v2_params;
 + int irq_mode, ret;
 +
 + /* IRQ trigger mode */
 + irq_mode = (vgic_acpi-flags  ACPI_MADT_VGIC_IRQ_MODE) ?
 + ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE;
 + vgic-maint_irq = acpi_register_gsi(NULL, vgic_acpi-vgic_interrupt,
 + irq_mode, ACPI_ACTIVE_HIGH);
 + if (!vgic-maint_irq) {
 + kvm_err(Cannot register VGIC ACPI maintenance irq\n);
 + ret = -ENXIO;
 + goto out;
 + }
 +
 + /* GICH resource */
 + vgic-vctrl_base = ioremap(vgic_acpi-gich_base_address, SZ_8K);
 + if (!vgic-vctrl_base) {
 + kvm_err(cannot ioremap GICH memory\n);
 + ret = -ENOMEM;
 + goto out;
 + }
 +
 + vgic-nr_lr = readl_relaxed(vgic-vctrl_base + GICH_VTR);
 + vgic-nr_lr = (vgic-nr_lr  0x3f) + 1;
 +
 + ret = create_hyp_io_mappings(vgic-vctrl_base,
 +  vgic-vctrl_base + SZ_8K,
 +  vgic_acpi-gich_base_address);
 + if (ret) {
 + kvm_err(Cannot map GICH into hyp\n);
 + goto out;
 + }
 +
 + vgic-vcpu_base = vgic_acpi-gicv_base_address;
 + vgic-can_emulate_gicv2 = true;
 + kvm_register_device_ops(kvm_arm_vgic_v2_ops, KVM_DEV_TYPE_ARM_VGIC_V2);
 +
 + kvm_info(GICH base=0x%llx, GICV base=0x%llx, IRQ=%d\n,
 +  (unsigned long long)vgic_acpi-gich_base_address,
 +  (unsigned long long)vgic_acpi-gicv_base_address,
 +  vgic-maint_irq);
 +
 + vgic-type = VGIC_V2;

we're missing max_gic_vcpus here

vgic-max_gic_vcpus = VGIC_V2_MAX_CPUS;

 + *ops = vgic_v2_ops;
 + *params = vgic;
 +
 +out:
 + return ret;
  }
  #endif /* CONFIG_ACPI */
 -- 
 1.8.3.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
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


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

2015-05-29 Thread Wei Huang


On 05/29/2015 09:06 AM, Andrew Jones wrote:
 On Thu, May 28, 2015 at 01:34:33AM -0400, Wei Huang wrote:
 This patches enables ACPI support for KVM virtual GICv2. KVM parses
 ACPI table for virt GIC related information and initializes resources.

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

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

Yes. Will fix in the next spin.

-Wei

 
 +*ops = vgic_v2_ops;
 +*params = vgic;
 +
 +out:
 +return ret;
  }
  #endif /* CONFIG_ACPI */
 -- 
 1.8.3.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
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


[PATCH v5 3/6] target-arm: kvm - implement software breakpoints

2015-05-29 Thread Alex Bennée
These don't involve messing around with debug registers, just setting
the breakpoint instruction in memory. GDB will not use this mechanism if
it can't access the memory to write the breakpoint.

All the kernel has to do is ensure the hypervisor traps the breakpoint
exceptions and returns to userspace.

Signed-off-by: Alex Bennée alex.ben...@linaro.org

--
v2
  - handle debug exit with new hsr exception info
  - add verbosity to UNIMP message
v3
  - sync with kvm_cpu_synchronize_state() before checking PC.
  - use internals.h defines
  - use env-pc
  - use proper format types
---
 target-arm/kvm.c | 88 
 1 file changed, 76 insertions(+), 12 deletions(-)

diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index fdd9ba3..c3bad6f 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -510,9 +510,60 @@ void kvm_arch_post_run(CPUState *cs, struct kvm_run *run)
 {
 }
 
+/* See v8 ARM ARM D7.2.27 ESR_ELx, Exception Syndrome Register
+ *
+ * To minimise translating between kernel and user-space the kernel
+ * ABI just provides user-space with the full exception syndrome
+ * register value to be decoded in QEMU.
+ */
+
+static int kvm_handle_debug(CPUState *cs, struct kvm_run *run)
+{
+struct kvm_debug_exit_arch *arch_info = run-debug.arch;
+int hsr_ec = arch_info-hsr  ARM_EL_EC_SHIFT;
+ARMCPU *cpu = ARM_CPU(cs);
+CPUARMState *env = cpu-env;
+
+/* Ensure PC is synchronised */
+kvm_cpu_synchronize_state(cs);
+
+switch (hsr_ec) {
+case EC_AA64_BKPT:
+if (kvm_find_sw_breakpoint(cs, env-pc)) {
+return true;
+}
+break;
+default:
+error_report(%s: unhandled debug exit (%PRIx32, %PRIx64)\n,
+ __func__, arch_info-hsr, env-pc);
+}
+
+/* If we don't handle this it could be it really is for the
+   guest to handle */
+qemu_log_mask(LOG_UNIMP,
+  %s: re-injecting exception not yet implemented
+   (0x%PRIx32, %PRIx64)\n,
+  __func__, hsr_ec, env-pc);
+
+return false;
+}
+
 int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
 {
-return 0;
+int ret = 0;
+
+switch (run-exit_reason) {
+case KVM_EXIT_DEBUG:
+if (kvm_handle_debug(cs, run)) {
+ret = EXCP_DEBUG;
+} /* otherwise return to guest */
+break;
+default:
+qemu_log_mask(LOG_UNIMP, %s: un-handled exit reason %d\n,
+  __func__, run-exit_reason);
+break;
+}
+return ret;
 }
 
 bool kvm_arch_stop_on_emulation_error(CPUState *cs)
@@ -537,14 +588,33 @@ int kvm_arch_on_sigbus(int code, void *addr)
 
 void kvm_arch_update_guest_debug(CPUState *cs, struct kvm_guest_debug *dbg)
 {
-qemu_log_mask(LOG_UNIMP, %s: not implemented\n, __func__);
+if (kvm_sw_breakpoints_active(cs)) {
+dbg-control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP;
+}
 }
 
-int kvm_arch_insert_sw_breakpoint(CPUState *cs,
-  struct kvm_sw_breakpoint *bp)
+/* C6.6.29 BRK instruction */
+int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
 {
-qemu_log_mask(LOG_UNIMP, %s: not implemented\n, __func__);
-return -EINVAL;
+static const uint32_t brk = 0xd420;
+
+if (cpu_memory_rw_debug(cs, bp-pc, (uint8_t *)bp-saved_insn, 4, 0) ||
+cpu_memory_rw_debug(cs, bp-pc, (uint8_t *)brk, 4, 1)) {
+return -EINVAL;
+}
+return 0;
+}
+
+int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
+{
+static uint32_t brk;
+
+if (cpu_memory_rw_debug(cs, bp-pc, (uint8_t *)brk, 4, 0) ||
+brk != 0xd420 ||
+cpu_memory_rw_debug(cs, bp-pc, (uint8_t *)bp-saved_insn, 4, 1)) {
+return -EINVAL;
+}
+return 0;
 }
 
 int kvm_arch_insert_hw_breakpoint(target_ulong addr,
@@ -561,12 +631,6 @@ int kvm_arch_remove_hw_breakpoint(target_ulong addr,
 return -EINVAL;
 }
 
-int kvm_arch_remove_sw_breakpoint(CPUState *cs,
-  struct kvm_sw_breakpoint *bp)
-{
-qemu_log_mask(LOG_UNIMP, %s: not implemented\n, __func__);
-return -EINVAL;
-}
 
 void kvm_arch_remove_all_hw_breakpoints(void)
 {
-- 
2.4.1

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


[PATCH v5 1/6] linux-headers: sync from my kernel tree (DEV)

2015-05-29 Thread Alex Bennée
I assume I'll properly merge the KVM Headers direct from Linux when
the kernel side is upstream. These headers came from:

https://git.linaro.org/people/alex.bennee/linux.git/shortlog/refs/heads/guest-debug/4.1-rc5-v5

Signed-off-by: Alex Bennée alex.ben...@linaro.org

---
v2
  - update ABI to include -far
v3
  - update with latest 4.1-rc1 headers
v4
  - update to v4 headers
v5
  - update to v5 headers
---
 include/standard-headers/linux/virtio_balloon.h |  28 +++-
 include/standard-headers/linux/virtio_blk.h |   8 +-
 include/standard-headers/linux/virtio_ids.h |   1 +
 include/standard-headers/linux/virtio_input.h   |  76 +++
 include/standard-headers/linux/virtio_ring.h|   2 +-
 linux-headers/asm-arm/kvm.h |   9 +-
 linux-headers/asm-arm64/kvm.h   |  29 -
 linux-headers/asm-mips/kvm.h| 164 +++-
 linux-headers/asm-s390/kvm.h|   4 +
 linux-headers/asm-x86/hyperv.h  |   2 +
 linux-headers/linux/kvm.h   |  71 +-
 linux-headers/linux/vfio.h  |   2 +
 12 files changed, 325 insertions(+), 71 deletions(-)
 create mode 100644 include/standard-headers/linux/virtio_input.h

diff --git a/include/standard-headers/linux/virtio_balloon.h 
b/include/standard-headers/linux/virtio_balloon.h
index 799376d..88ada1d 100644
--- a/include/standard-headers/linux/virtio_balloon.h
+++ b/include/standard-headers/linux/virtio_balloon.h
@@ -25,6 +25,7 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE. */
+#include standard-headers/linux/types.h
 #include standard-headers/linux/virtio_ids.h
 #include standard-headers/linux/virtio_config.h
 
@@ -51,9 +52,32 @@ struct virtio_balloon_config {
 #define VIRTIO_BALLOON_S_MEMTOT   5   /* Total amount of memory */
 #define VIRTIO_BALLOON_S_NR   6
 
+/*
+ * Memory statistics structure.
+ * Driver fills an array of these structures and passes to device.
+ *
+ * NOTE: fields are laid out in a way that would make compiler add padding
+ * between and after fields, so we have to use compiler-specific attributes to
+ * pack it, to disable this padding. This also often causes compiler to
+ * generate suboptimal code.
+ *
+ * We maintain this statistics structure format for backwards compatibility,
+ * but don't follow this example.
+ *
+ * If implementing a similar structure, do something like the below instead:
+ * struct virtio_balloon_stat {
+ * __virtio16 tag;
+ * uint8_t reserved[6];
+ * __virtio64 val;
+ * };
+ *
+ * In other words, add explicit reserved fields to align field and
+ * structure boundaries at field size, avoiding compiler padding
+ * without the packed attribute.
+ */
 struct virtio_balloon_stat {
-   uint16_t tag;
-   uint64_t val;
+   __virtio16 tag;
+   __virtio64 val;
 } QEMU_PACKED;
 
 #endif /* _LINUX_VIRTIO_BALLOON_H */
diff --git a/include/standard-headers/linux/virtio_blk.h 
b/include/standard-headers/linux/virtio_blk.h
index 12016b4..cd601f4 100644
--- a/include/standard-headers/linux/virtio_blk.h
+++ b/include/standard-headers/linux/virtio_blk.h
@@ -58,7 +58,7 @@ struct virtio_blk_config {
uint32_t size_max;
/* The maximum number of segments (if VIRTIO_BLK_F_SEG_MAX) */
uint32_t seg_max;
-   /* geometry the device (if VIRTIO_BLK_F_GEOMETRY) */
+   /* geometry of the device (if VIRTIO_BLK_F_GEOMETRY) */
struct virtio_blk_geometry {
uint16_t cylinders;
uint8_t heads;
@@ -117,7 +117,11 @@ struct virtio_blk_config {
 #define VIRTIO_BLK_T_BARRIER   0x8000
 #endif /* !VIRTIO_BLK_NO_LEGACY */
 
-/* This is the first element of the read scatter-gather list. */
+/*
+ * This comes first in the read scatter-gather list.
+ * For legacy virtio, if VIRTIO_F_ANY_LAYOUT is not negotiated,
+ * this is the first element of the read scatter-gather list.
+ */
 struct virtio_blk_outhdr {
/* VIRTIO_BLK_T* */
__virtio32 type;
diff --git a/include/standard-headers/linux/virtio_ids.h 
b/include/standard-headers/linux/virtio_ids.h
index 284fc3a..5f60aa4 100644
--- a/include/standard-headers/linux/virtio_ids.h
+++ b/include/standard-headers/linux/virtio_ids.h
@@ -39,5 +39,6 @@
 #define VIRTIO_ID_9P   9 /* 9p virtio console */
 #define VIRTIO_ID_RPROC_SERIAL 11 /* virtio remoteproc serial link */
 #define VIRTIO_ID_CAIF12 /* Virtio caif */
+#define VIRTIO_ID_INPUT18 /* virtio input */
 
 #endif /* _LINUX_VIRTIO_IDS_H */
diff --git a/include/standard-headers/linux/virtio_input.h 
b/include/standard-headers/linux/virtio_input.h
new file mode 100644
index 000..a98a797
--- /dev/null
+++ b/include/standard-headers/linux/virtio_input.h
@@ -0,0 +1,76 @@
+#ifndef _LINUX_VIRTIO_INPUT_H
+#define _LINUX_VIRTIO_INPUT_H
+/* This header 

[PATCH v5 2/6] target-arm: kvm64: introduce kvm_arm_init_debug()

2015-05-29 Thread Alex Bennée
As we haven't always had guest debug support we need to probe for it.
Additionally we don't do this in the start-up capability code so we
don't fall over on old kernels.

Signed-off-by: Alex Bennée alex.ben...@linaro.org
---
 target-arm/kvm64.c | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/target-arm/kvm64.c b/target-arm/kvm64.c
index 93c1ca8..61592d2 100644
--- a/target-arm/kvm64.c
+++ b/target-arm/kvm64.c
@@ -25,6 +25,22 @@
 #include internals.h
 #include hw/arm/arm.h
 
+static bool have_guest_debug;
+
+/**
+ * kvm_arm_init_debug()
+ * @cs: CPUState
+ *
+ * Check for guest debug capabilities.
+ *
+ */
+static void kvm_arm_init_debug(CPUState *cs)
+{
+have_guest_debug = kvm_check_extension(cs-kvm_state,
+   KVM_CAP_SET_GUEST_DEBUG);
+return;
+}
+
 static inline void set_feature(uint64_t *features, int feature)
 {
 *features |= 1ULL  feature;
@@ -107,6 +123,8 @@ int kvm_arch_init_vcpu(CPUState *cs)
 return ret;
 }
 
+kvm_arm_init_debug(cs);
+
 return kvm_arm_init_cpreg_list(cpu);
 }
 
-- 
2.4.1

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


[PATCH v5 0/6] QEMU support for KVM Guest Debug on arm64

2015-05-29 Thread Alex Bennée
Hi,

You may be wondering what happened to v3 and v4. They do exist but
they didn't change much from the the original patches as I've been
mostly looking the kernel side of the equation. So in summary the
changes are:

  - updates to the kernel ABI
  - don't fall over on kernels without debug support
  - better logging, syncing and use of internals.h
  - debug exception re-injection for guest events*

More detailed changelogs are attached to each patch.

* see
  https://lists.cs.columbia.edu/pipermail/kvmarm/2015-May/014807.html

GIT Repos:

The patch series is based off a recent master and can be found at:

https://github.com/stsquad/qemu
branch: kvm/guest-debug-v5

The kernel patches for this series are based off a v4.1-rc5-v5 and can be
found at:

https://git.linaro.org/people/alex.bennee/linux.git
branch: guest-debug/4.1-rc5-v5

Alex Bennée (6):
  linux-headers: sync from my kernel tree (DEV)
  target-arm: kvm64: introduce kvm_arm_init_debug()
  target-arm: kvm - implement software breakpoints
  target-arm: kvm - support for single step
  target-arm: kvm - add support for HW assisted debug
  target-arm: kvm - re-inject guest debug exceptions

 include/standard-headers/linux/virtio_balloon.h |  28 ++-
 include/standard-headers/linux/virtio_blk.h |   8 +-
 include/standard-headers/linux/virtio_ids.h |   1 +
 include/standard-headers/linux/virtio_input.h   |  76 ++
 include/standard-headers/linux/virtio_ring.h|   2 +-
 linux-headers/asm-arm/kvm.h |   9 +-
 linux-headers/asm-arm64/kvm.h   |  29 ++-
 linux-headers/asm-mips/kvm.h| 164 +++-
 linux-headers/asm-s390/kvm.h|   4 +
 linux-headers/asm-x86/hyperv.h  |   2 +
 linux-headers/linux/kvm.h   |  71 +-
 linux-headers/linux/vfio.h  |   2 +
 target-arm/cpu.h|   1 +
 target-arm/helper-a64.c |  17 +-
 target-arm/internals.h  |   1 +
 target-arm/kvm.c| 137 --
 target-arm/kvm64.c  | 318 
 target-arm/kvm_arm.h|  21 ++
 18 files changed, 790 insertions(+), 101 deletions(-)
 create mode 100644 include/standard-headers/linux/virtio_input.h

-- 
2.4.1

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


Re: [PATCH v2] arm/arm64: KVM: Properly account for guest CPU time

2015-05-29 Thread Mario Smarduch
On 05/28/2015 11:49 AM, Christoffer Dall wrote:
 Until now we have been calling kvm_guest_exit after re-enabling
 interrupts when we come back from the guest, but this has the
 unfortunate effect that CPU time accounting done in the context of timer
 interrupts occurring while the guest is running doesn't properly notice
 that the time since the last tick was spent in the guest.
 
 Inspired by the comment in the x86 code, move the kvm_guest_exit() call
 below the local_irq_enable() call and change __kvm_guest_exit() to
 kvm_guest_exit(), because we are now calling this function with
 interrupts enabled.  We have to now explicitly disable preemption and
 not enable preemption before we've called kvm_guest_exit(), since
 otherwise we could be preempted and everything happening before we
 eventually get scheduled again would be accounted for as guest time.
 
 At the same time, move the trace_kvm_exit() call outside of the atomic
 section, since there is no reason for us to do that with interrupts
 disabled.
 
 Signed-off-by: Christoffer Dall christoffer.d...@linaro.org
 ---
 This patch is based on kvm/queue, because it has the kvm_guest_enter/exit
 rework recently posted by Christian Borntraeger.  I hope I got the logic
 of this right, there were 2 slightly worrying facts about this:
 
 First, we now enable and disable and enable interrupts on each exit
 path, but I couldn't see any performance overhead on hackbench - yes the
 only benchmark we care about.
 
 Second, looking at the ppc and mips code, they seem to also call
 kvm_guest_exit() before enabling interrupts, so I don't understand how
 guest CPU time accounting works on those architectures.
 
 Changes since v1:
  - Tweak comment and commit text based on Marc's feedback.
  - Explicitly disable preemption and enable it only after kvm_guest_exit().
 
  arch/arm/kvm/arm.c | 21 +
  1 file changed, 17 insertions(+), 4 deletions(-)
 
 diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
 index e41cb11..fe8028d 100644
 --- a/arch/arm/kvm/arm.c
 +++ b/arch/arm/kvm/arm.c
 @@ -532,6 +532,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct 
 kvm_run *run)
   kvm_vgic_flush_hwstate(vcpu);
   kvm_timer_flush_hwstate(vcpu);
  
 + preempt_disable();
   local_irq_disable();
  
   /*
 @@ -544,6 +545,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct 
 kvm_run *run)
  
   if (ret = 0 || need_new_vmid_gen(vcpu-kvm)) {
   local_irq_enable();
 + preempt_enable();
   kvm_timer_sync_hwstate(vcpu);
   kvm_vgic_sync_hwstate(vcpu);
   continue;
 @@ -559,8 +561,10 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, 
 struct kvm_run *run)
   ret = kvm_call_hyp(__kvm_vcpu_run, vcpu);
  
   vcpu-mode = OUTSIDE_GUEST_MODE;
 - __kvm_guest_exit();
 - trace_kvm_exit(kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu));
 + /*
 +  * Back from guest
 +  */
 +
   /*
* We may have taken a host interrupt in HYP mode (ie
* while executing the guest). This interrupt is still
 @@ -574,8 +578,17 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, 
 struct kvm_run *run)
   local_irq_enable();
  
   /*
 -  * Back from guest
 -  */
 +  * We do local_irq_enable() before calling kvm_guest_exit() so
 +  * that if a timer interrupt hits while running the guest we
 +  * account that tick as being spent in the guest.  We enable
 +  * preemption after calling kvm_guest_exit() so that if we get
 +  * preempted we make sure ticks after that is not counted as
 +  * guest time.
 +  */
 + kvm_guest_exit();
 + trace_kvm_exit(kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu));
 + preempt_enable();
 +
  
   kvm_timer_sync_hwstate(vcpu);
   kvm_vgic_sync_hwstate(vcpu);
 

Hi Christoffer,
 so currently we take a snap shot when we enter the guest
(tsk-vtime_snap) and upon exit add the time we spent in
the guest and update accrued time, which appears correct.

With this patch it appears that interrupts running
in host mode are accrued to Guest time, and additional preemption
latency is added.

Thanks,
- Mario

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