Re: [PATCH 07/18] KVM: ARM64: PMU: Add perf event map and introduce perf event creating function

2015-07-17 Thread Christoffer Dall
On Mon, Jul 06, 2015 at 10:17:37AM +0800, shannon.z...@linaro.org wrote:
 From: Shannon Zhao shannon.z...@linaro.org
 
 When we use tools like perf on host, perf passes the event type and the
 id in this type category to kernel, then kernel will map them to event
 number and write this number to PMU PMEVTYPERn_EL0 register. While
 we're trapping and emulating guest accesses to PMU registers, we get the
 event number and map it to the event type and the id reversely.

There's something with the nomenclature that makes this really hard to
read.

you mention here: event type, the id, and event number.  The
former two I think are perf identifiers, and the latter is the hardware
event number, is this right?

 
 Check whether the event type is same with the one to be set.

when?

 If not,
 stop counter to monitor current event and find the event type map id.
 According to the bits of data to configure this perf_event attr and
 set exclude_host to 1 for guest. Then call perf_event API to create the
 corresponding event and save the event pointer.
 
 Signed-off-by: Shannon Zhao shannon.z...@linaro.org
 ---
  include/kvm/arm_pmu.h |   4 ++
  virt/kvm/arm/pmu.c| 173 
 ++
  2 files changed, 177 insertions(+)
 
 diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
 index 27d14ca..1050b24 100644
 --- a/include/kvm/arm_pmu.h
 +++ b/include/kvm/arm_pmu.h
 @@ -45,9 +45,13 @@ struct kvm_pmu {
  
  #ifdef CONFIG_KVM_ARM_PMU
  void kvm_pmu_vcpu_reset(struct kvm_vcpu *vcpu);
 +void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, unsigned long 
 data,
 + unsigned long select_idx);
  void kvm_pmu_init(struct kvm_vcpu *vcpu);
  #else
  static inline void kvm_pmu_vcpu_reset(struct kvm_vcpu *vcpu) {}
 +void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, unsigned long 
 data,
 + unsigned long select_idx) {}
  static inline void kvm_pmu_init(struct kvm_vcpu *vcpu) {}
  #endif
  
 diff --git a/virt/kvm/arm/pmu.c b/virt/kvm/arm/pmu.c
 index dc252d0..50a3c82 100644
 --- a/virt/kvm/arm/pmu.c
 +++ b/virt/kvm/arm/pmu.c
 @@ -18,8 +18,68 @@
  #include linux/cpu.h
  #include linux/kvm.h
  #include linux/kvm_host.h
 +#include linux/perf_event.h
  #include kvm/arm_pmu.h
  
 +/* PMU HW events mapping. */
 +static struct kvm_pmu_hw_event_map {
 + unsigned eventsel;
 + unsigned event_type;
 +} kvm_pmu_hw_events[] = {
 + [0] = { 0x11, PERF_COUNT_HW_CPU_CYCLES },
 + [1] = { 0x08, PERF_COUNT_HW_INSTRUCTIONS },
 + [2] = { 0x04, PERF_COUNT_HW_CACHE_REFERENCES },
 + [3] = { 0x03, PERF_COUNT_HW_CACHE_MISSES },
 + [4] = { 0x10, PERF_COUNT_HW_BRANCH_MISSES },
 +};
 +
 +/* PMU HW cache events mapping. */
 +static struct kvm_pmu_hw_cache_event_map {
 + unsigned eventsel;
 + unsigned cache_type;
 + unsigned cache_op;
 + unsigned cache_result;
 +} kvm_pmu_hw_cache_events[] = {
 + [0] = { 0x04, PERF_COUNT_HW_CACHE_L1D, PERF_COUNT_HW_CACHE_OP_READ,
 +   PERF_COUNT_HW_CACHE_RESULT_ACCESS },
 + [1] = { 0x03, PERF_COUNT_HW_CACHE_L1D, PERF_COUNT_HW_CACHE_OP_READ,
 +   PERF_COUNT_HW_CACHE_RESULT_MISS },
 + [2] = { 0x04, PERF_COUNT_HW_CACHE_L1D, PERF_COUNT_HW_CACHE_OP_WRITE,
 +   PERF_COUNT_HW_CACHE_RESULT_ACCESS },
 + [3] = { 0x03, PERF_COUNT_HW_CACHE_L1D, PERF_COUNT_HW_CACHE_OP_WRITE,
 +   PERF_COUNT_HW_CACHE_RESULT_MISS },

seems to me that the four entries above will never be used, because
you'll always match them in kvm_pmu_hw_events above?

Is this because perf map multiple generic perf events to the same
hardware event?  Does it matter if we register this with perf as one or
the other then?

 + [4] = { 0x12, PERF_COUNT_HW_CACHE_BPU, PERF_COUNT_HW_CACHE_OP_READ,
 +   PERF_COUNT_HW_CACHE_RESULT_ACCESS },
 + [5] = { 0x10, PERF_COUNT_HW_CACHE_BPU, PERF_COUNT_HW_CACHE_OP_READ,
 +   PERF_COUNT_HW_CACHE_RESULT_MISS },
 + [6] = { 0x12, PERF_COUNT_HW_CACHE_BPU, PERF_COUNT_HW_CACHE_OP_WRITE,
 +   PERF_COUNT_HW_CACHE_RESULT_ACCESS },
 + [7] = { 0x10, PERF_COUNT_HW_CACHE_BPU, PERF_COUNT_HW_CACHE_OP_WRITE,
 +   PERF_COUNT_HW_CACHE_RESULT_MISS },
 +};
 +
 +/**
 + * kvm_pmu_stop_counter - stop PMU counter for the selected counter
 + * @vcpu: The vcpu pointer
 + * @select_idx: The counter index
 + *
 + * If this counter has been configured to monitor some event, disable and
 + * release it.
 + */
 +static void kvm_pmu_stop_counter(struct kvm_vcpu *vcpu,
 +  unsigned long select_idx)
 +{
 + struct kvm_pmu *pmu = vcpu-arch.pmu;
 + struct kvm_pmc *pmc = pmu-pmc[select_idx];
 +
 + if (pmc-perf_event) {
 + perf_event_disable(pmc-perf_event);
 + perf_event_release_kernel(pmc-perf_event);
 + }
 + pmc-perf_event = NULL;
 + pmc-eventsel = 0xff;

why is 0xff 'unused' or 

Re: [PATCH 09/18] KVM: ARM64: Add reset and access handlers for PMXEVCNTR_EL0 register

2015-07-17 Thread Christoffer Dall
On Mon, Jul 06, 2015 at 10:17:39AM +0800, shannon.z...@linaro.org wrote:
 From: Shannon Zhao shannon.z...@linaro.org
 
 Since the reset value of PMXEVTYPER_EL0 is UNKNOWN, use reset_unknown
 for its reset handler. Add access handler which emulates writing and
 reading PMXEVTYPER_EL0 register. When reading PMXEVCNTR_EL0, call
 perf_event_read_value to get the count value of the perf event.
 
 Signed-off-by: Shannon Zhao shannon.z...@linaro.org
 ---
  arch/arm64/kvm/sys_regs.c | 21 -
  include/kvm/arm_pmu.h | 11 +++
  virt/kvm/arm/pmu.c| 37 +
  3 files changed, 68 insertions(+), 1 deletion(-)
 
 diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
 index b4f8dd9..2bcf1a0 100644
 --- a/arch/arm64/kvm/sys_regs.c
 +++ b/arch/arm64/kvm/sys_regs.c
 @@ -356,6 +356,25 @@ static bool access_pmxevtyper(struct kvm_vcpu *vcpu,
   return true;
  }
  
 +static bool access_pmxevcntr(struct kvm_vcpu *vcpu,
 +  const struct sys_reg_params *p,
 +  const struct sys_reg_desc *r)
 +{
 + unsigned long val;
 +
 + if (p-is_write) {
 + val = *vcpu_reg(vcpu, p-Rt);
 + kvm_pmu_set_counter_value(vcpu, vcpu_sys_reg(vcpu, PMSELR_EL0),
 +   val  0xUL);
 + } else {
 + val = kvm_pmu_get_counter_value(vcpu,
 + vcpu_sys_reg(vcpu, PMSELR_EL0));
 + *vcpu_reg(vcpu, p-Rt) = val;
 + }
 +
 + return true;
 +}
 +
  /* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */
  #define DBG_BCR_BVR_WCR_WVR_EL1(n)   \
   /* DBGBVRn_EL1 */   \
 @@ -577,7 +596,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 access_pmxevtyper, reset_unknown, PMXEVTYPER_EL0 },
   /* PMXEVCNTR_EL0 */
   { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1101), Op2(0b010),
 -   trap_raz_wi },
 +   access_pmxevcntr, reset_unknown, PMXEVCNTR_EL0 },
   /* PMUSERENR_EL0 */
   { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1110), Op2(0b000),
 trap_raz_wi },
 diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
 index 1050b24..40ab4a0 100644
 --- a/include/kvm/arm_pmu.h
 +++ b/include/kvm/arm_pmu.h
 @@ -45,11 +45,22 @@ struct kvm_pmu {
  
  #ifdef CONFIG_KVM_ARM_PMU
  void kvm_pmu_vcpu_reset(struct kvm_vcpu *vcpu);
 +void kvm_pmu_set_counter_value(struct kvm_vcpu *vcpu, unsigned long 
 select_idx,
 +unsigned long val);
 +unsigned long kvm_pmu_get_counter_value(struct kvm_vcpu *vcpu,
 + unsigned long select_idx);
  void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, unsigned long 
 data,
   unsigned long select_idx);
  void kvm_pmu_init(struct kvm_vcpu *vcpu);
  #else
  static inline void kvm_pmu_vcpu_reset(struct kvm_vcpu *vcpu) {}
 +void kvm_pmu_set_counter_value(struct kvm_vcpu *vcpu, unsigned long 
 select_idx,
 +unsigned long val) {}
 +unsigned long kvm_pmu_get_counter_value(struct kvm_vcpu *vcpu,
 + unsigned long select_idx)
 +{
 + return 0;
 +}
  void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, unsigned long 
 data,
   unsigned long select_idx) {}
  static inline void kvm_pmu_init(struct kvm_vcpu *vcpu) {}
 diff --git a/virt/kvm/arm/pmu.c b/virt/kvm/arm/pmu.c
 index 50a3c82..361fa51 100644
 --- a/virt/kvm/arm/pmu.c
 +++ b/virt/kvm/arm/pmu.c
 @@ -97,6 +97,43 @@ void kvm_pmu_vcpu_reset(struct kvm_vcpu *vcpu)
  }
  
  /**
 + * kvm_pmu_set_counter_value - set PMU counter value
 + * @vcpu: The vcpu pointer
 + * @select_idx: The counter index
 + * @val: the value to be set
 + */
 +void kvm_pmu_set_counter_value(struct kvm_vcpu *vcpu, unsigned long 
 select_idx,
 +unsigned long val)
 +{
 + struct kvm_pmu *pmu = vcpu-arch.pmu;
 + struct kvm_pmc *pmc = pmu-pmc[select_idx];
 +
 + pmc-counter = val;

how does this help generate an overflow event when expected?

 +}
 +
 +/**
 + * kvm_pmu_set_counter_value - set PMU counter value

s/set/get/

 + * @vcpu: The vcpu pointer
 + * @select_idx: The counter index
 + *
 + * Call perf_event API to get the event count
 + */
 +unsigned long kvm_pmu_get_counter_value(struct kvm_vcpu *vcpu,
 + unsigned long select_idx)
 +{
 + u64 enabled, running;
 + struct kvm_pmu *pmu = vcpu-arch.pmu;
 + struct kvm_pmc *pmc = pmu-pmc[select_idx];
 + unsigned long counter = pmc-counter;
 +
 + if (pmc-perf_event) {
 + counter += perf_event_read_value(pmc-perf_event,
 + enabled, running);

I don't quite understand the summation here or feel convinced that
enabled and running 

Re: [PATCH 10/18] KVM: ARM64: Add reset and access handlers for PMCCNTR_EL0 register

2015-07-17 Thread Christoffer Dall
On Mon, Jul 06, 2015 at 10:17:40AM +0800, shannon.z...@linaro.org wrote:
 From: Shannon Zhao shannon.z...@linaro.org
 
 Since the reset value of PMCCNTR_EL0 is UNKNOWN, use reset_unknown for
 its reset handler. Add access handler which emulates writing and reading
 PMCCNTR_EL0 register.
 
 Signed-off-by: Shannon Zhao shannon.z...@linaro.org
 ---
  arch/arm64/kvm/sys_regs.c | 19 ++-
  1 file changed, 18 insertions(+), 1 deletion(-)
 
 diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
 index 2bcf1a0..29883df 100644
 --- a/arch/arm64/kvm/sys_regs.c
 +++ b/arch/arm64/kvm/sys_regs.c
 @@ -375,6 +375,23 @@ static bool access_pmxevcntr(struct kvm_vcpu *vcpu,
   return true;
  }
  
 +static bool access_pmccntr(struct kvm_vcpu *vcpu,
 +const struct sys_reg_params *p,
 +const struct sys_reg_desc *r)
 +{
 + unsigned long val;
 +
 + if (p-is_write) {
 + val = *vcpu_reg(vcpu, p-Rt);
 + kvm_pmu_set_counter_value(vcpu, 31, val);

magic number?  do we have some existing define we can use or can we add
one?

 + } else {
 + val = kvm_pmu_get_counter_value(vcpu, 31);
 + *vcpu_reg(vcpu, p-Rt) = val;
 + }
 +
 + return true;
 +}
 +
  /* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */
  #define DBG_BCR_BVR_WCR_WVR_EL1(n)   \
   /* DBGBVRn_EL1 */   \
 @@ -590,7 +607,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 access_pmceid, reset_pmceid, PMCEID1_EL0, },
   /* PMCCNTR_EL0 */
   { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1101), Op2(0b000),
 -   trap_raz_wi },
 +   access_pmccntr, reset_unknown, PMCCNTR_EL0 },
   /* PMXEVTYPER_EL0 */
   { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1101), Op2(0b001),
 access_pmxevtyper, reset_unknown, PMXEVTYPER_EL0 },
 -- 
 2.1.0
 
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 11/18] KVM: ARM64: Add reset and access handlers for PMCNTENSET_EL0 and PMCNTENCLR_EL0 register

2015-07-17 Thread Christoffer Dall
On Mon, Jul 06, 2015 at 10:17:41AM +0800, shannon.z...@linaro.org wrote:
 From: Shannon Zhao shannon.z...@linaro.org
 
 Since the reset value of PMCNTENSET_EL0 and PMCNTENCLR_EL0 is UNKNOWN,
 use reset_unknown for its reset handler. Add access handler which
 emulates writing and reading PMCNTENSET_EL0 or PMCNTENCLR_EL0 register.
 When writing to PMCNTENSET_EL0, call perf_event_enable to enable the
 perf event. When writing to PMCNTENCLR_EL0, call perf_event_disable to
 disable the perf event.
 
 Signed-off-by: Shannon Zhao shannon.z...@linaro.org
 ---
  arch/arm64/kvm/sys_regs.c | 56 
 +--
  include/kvm/arm_pmu.h |  4 
  virt/kvm/arm/pmu.c| 41 ++
  3 files changed, 99 insertions(+), 2 deletions(-)
 
 diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
 index 29883df..c14ec8d 100644
 --- a/arch/arm64/kvm/sys_regs.c
 +++ b/arch/arm64/kvm/sys_regs.c
 @@ -392,6 +392,58 @@ static bool access_pmccntr(struct kvm_vcpu *vcpu,
   return true;
  }
  
 +/* PMCNTENSET_EL0 accessor. */
 +static bool access_pmcntenset(struct kvm_vcpu *vcpu,
 +   const struct sys_reg_params *p,
 +   const struct sys_reg_desc *r)
 +{
 + unsigned long val;
 +
 + if (p-is_write) {
 + val = *vcpu_reg(vcpu, p-Rt);
 + if (!p-is_aarch32)
 + vcpu_sys_reg(vcpu, r-reg) |= val;
 + else
 + vcpu_cp15(vcpu, r-reg) |= val  0xUL;
 +
 + kvm_pmu_enable_counter(vcpu, val);
 + } else {
 + if (!p-is_aarch32)
 + val = vcpu_sys_reg(vcpu, r-reg);
 + else
 + val = vcpu_cp15(vcpu, r-reg);
 + *vcpu_reg(vcpu, p-Rt) = val;
 + }
 +
 + return true;
 +}
 +
 +/* PMCNTENCLR_EL0 accessor. */
 +static bool access_pmcntenclr(struct kvm_vcpu *vcpu,
 +   const struct sys_reg_params *p,
 +   const struct sys_reg_desc *r)
 +{
 + unsigned long val;
 +
 + if (p-is_write) {
 + val = *vcpu_reg(vcpu, p-Rt);
 + if (!p-is_aarch32)
 + vcpu_sys_reg(vcpu, r-reg) |= val;

huh, this is the clear register, don't you need to = ~val ?

also, there's a lot of code duplication between these two functions, it
must be worthwhile having a single static function that they both call
if a bool differentiating between set/clear.


 + else
 + vcpu_cp15(vcpu, r-reg) |= val  0xUL;
 +
 + kvm_pmu_disable_counter(vcpu, val);
 + } else {
 + if (!p-is_aarch32)
 + val = vcpu_sys_reg(vcpu, r-reg);
 + else
 + val = vcpu_cp15(vcpu, r-reg);
 + *vcpu_reg(vcpu, p-Rt) = val;
 + }
 +
 + return true;
 +}
 +
  /* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */
  #define DBG_BCR_BVR_WCR_WVR_EL1(n)   \
   /* DBGBVRn_EL1 */   \
 @@ -586,10 +638,10 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 access_pmcr, reset_pmcr_el0, PMCR_EL0, },
   /* PMCNTENSET_EL0 */
   { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b001),
 -   trap_raz_wi },
 +   access_pmcntenset, reset_unknown, PMCNTENSET_EL0 },
   /* PMCNTENCLR_EL0 */
   { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b010),
 -   trap_raz_wi },
 +   access_pmcntenclr, reset_unknown, PMCNTENCLR_EL0 },
   /* PMOVSCLR_EL0 */
   { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b011),
 trap_raz_wi },
 diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
 index 40ab4a0..2cfd9be 100644
 --- a/include/kvm/arm_pmu.h
 +++ b/include/kvm/arm_pmu.h
 @@ -49,6 +49,8 @@ void kvm_pmu_set_counter_value(struct kvm_vcpu *vcpu, 
 unsigned long select_idx,
  unsigned long val);
  unsigned long kvm_pmu_get_counter_value(struct kvm_vcpu *vcpu,
   unsigned long select_idx);
 +void kvm_pmu_disable_counter(struct kvm_vcpu *vcpu, unsigned long val);
 +void kvm_pmu_enable_counter(struct kvm_vcpu *vcpu, unsigned long val);
  void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, unsigned long 
 data,
   unsigned long select_idx);
  void kvm_pmu_init(struct kvm_vcpu *vcpu);
 @@ -61,6 +63,8 @@ unsigned long kvm_pmu_get_counter_value(struct kvm_vcpu 
 *vcpu,
  {
   return 0;
  }
 +void kvm_pmu_disable_counter(struct kvm_vcpu *vcpu, unsigned long val) {}
 +void kvm_pmu_enable_counter(struct kvm_vcpu *vcpu, unsigned long val) {}
  void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, unsigned long 
 data,
   unsigned long select_idx) {}
  static inline void kvm_pmu_init(struct kvm_vcpu *vcpu) {}

Re: [PATCH 03/18] KVM: ARM64: Add offset defines for PMU registers

2015-07-17 Thread Shannon Zhao



On 2015/7/17 18:17, Christoffer Dall wrote:

On Fri, Jul 17, 2015 at 04:25:06PM +0800, Shannon Zhao wrote:



On 2015/7/17 2:45, Christoffer Dall wrote:

On Mon, Jul 06, 2015 at 10:17:33AM +0800, shannon.z...@linaro.org wrote:

From: Shannon Zhao shannon.z...@linaro.org

We are about to trap and emulate acccesses to each PMU register
individually. This adds the context offsets for the AArch64 PMU
registers and their AArch32 counterparts.

Signed-off-by: Shannon Zhao shannon.z...@linaro.org
---
  arch/arm64/include/asm/kvm_asm.h | 59 +++-
  1 file changed, 52 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 3c5fe68..21b5d3b 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -56,14 +56,36 @@
  #define DBGWVR15_EL1  86
  #define MDCCINT_EL1   87  /* Monitor Debug Comms Channel Interrupt Enable 
Reg */

+/* Performance Monitors Registers */
+#define PMCR_EL0   88  /* Control Register */
+#define PMOVSSET_EL0   89  /* Overflow Flag Status Set Register */
+#define PMOVSCLR_EL0   90  /* Overflow Flag Status Clear Register */
+#define PMCCNTR_EL091  /* Cycle Counter Register */
+#define PMSELR_EL0 92  /* Event Counter Selection Register */
+#define PMCEID0_EL093  /* Common Event Identification Register 0 */
+#define PMCEID1_EL094  /* Common Event Identification Register 1 */
+#define PMEVCNTR0_EL0  95  /* Event Counter Register (0-30) */


why do we need these when we trap-and-emulate and we have the kvm_pmc
structs?

This just makes the guest work when accessing these registers.


Is that because the kvm_pmc structs are only used when we
actually have an active counter running and registered with perf?



Right, the kvm_pmc structs are used to store the status of perf evnets,
like the event type, count number of this perf event.

On the other hand, the kernel perf codes will not directly access to the
PMEVCNTRx_EL0 and PMEVTYPERx_EL0 registers. It will firstly write the
index of select counter to PMSELR_EL0 and access to PMXEVCNTR_EL0 or
PMXEVTYPER_EL0. Then this is architecturally mapped to PMEVCNTRx_EL0 and
PMEVTYPERx_EL0.



I'm just wondering if it makes sense to keep virtual state around for
all these registers, since we don't emulate the counter values, so why
do we need to preserve any virtual cpu state for all of them?



Good point. Will remove this :)

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


Re: [PATCH 02/18] KVM: ARM64: Add initial support for PMU

2015-07-17 Thread Shannon Zhao



On 2015/7/17 17:58, Christoffer Dall wrote:

On Fri, Jul 17, 2015 at 04:13:35PM +0800, Shannon Zhao wrote:



On 2015/7/17 2:25, Christoffer Dall wrote:

On Mon, Jul 06, 2015 at 10:17:32AM +0800, shannon.z...@linaro.org wrote:

From: Shannon Zhao shannon.z...@linaro.org

Here we plan to support virtual PMU for guest by full software
emulation, so define some basic structs and functions preparing for
futher steps. Define struct kvm_pmc for performance monitor counter and
struct kvm_pmu for performance monitor unit for each vcpu. According to
ARMv8 spec, the PMU contains at most 32(ARMV8_MAX_COUNTERS) counters.
Initialize PMU for each vcpu when kvm initialize vcpus, while reset PMU
when kvm reset vcpus.
Since this only supports ARM64 (or PMUv3), add a separate config symbol
for it.

Signed-off-by: Shannon Zhao shannon.z...@linaro.org
---
  arch/arm/kvm/arm.c|  4 +++
  arch/arm64/include/asm/kvm_host.h |  2 ++
  arch/arm64/include/asm/pmu.h  |  2 ++
  arch/arm64/kvm/Kconfig|  7 +
  arch/arm64/kvm/Makefile   |  1 +
  arch/arm64/kvm/reset.c|  3 +++
  include/kvm/arm_pmu.h | 54 ++
  virt/kvm/arm/pmu.c| 55 +++
  8 files changed, 128 insertions(+)
  create mode 100644 include/kvm/arm_pmu.h
  create mode 100644 virt/kvm/arm/pmu.c

diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index bc738d2..4e82625 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -28,6 +28,7 @@
  #include linux/sched.h
  #include linux/kvm.h
  #include trace/events/kvm.h
+#include kvm/arm_pmu.h

  #define CREATE_TRACE_POINTS
  #include trace.h
@@ -278,6 +279,9 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
/* Set up the timer */
kvm_timer_vcpu_init(vcpu);

+   /* Set up the PMU */
+   kvm_pmu_init(vcpu);
+
return 0;
  }

diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h
index 2709db2..3c88873 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -42,6 +42,7 @@

  #include kvm/arm_vgic.h
  #include kvm/arm_arch_timer.h
+#include kvm/arm_pmu.h

  #define KVM_VCPU_MAX_FEATURES 3

@@ -116,6 +117,7 @@ struct kvm_vcpu_arch {
/* VGIC state */
struct vgic_cpu vgic_cpu;
struct arch_timer_cpu timer_cpu;
+   struct kvm_pmu pmu;

/*
 * Anything that is not used directly from assembly code goes
diff --git a/arch/arm64/include/asm/pmu.h b/arch/arm64/include/asm/pmu.h
index b9f394a..95681e6 100644
--- a/arch/arm64/include/asm/pmu.h
+++ b/arch/arm64/include/asm/pmu.h
@@ -19,6 +19,8 @@
  #ifndef __ASM_PMU_H
  #define __ASM_PMU_H

+#include linux/perf_event.h
+
  #define ARMV8_MAX_COUNTERS  32
  #define ARMV8_COUNTER_MASK  (ARMV8_MAX_COUNTERS - 1)

diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index bfffe8f..eae3a1b 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -31,6 +31,7 @@ config KVM
select KVM_VFIO
select HAVE_KVM_EVENTFD
select HAVE_KVM_IRQFD
+   select KVM_ARM_PMU
---help---
  Support hosting virtualized guest machines.

@@ -52,4 +53,10 @@ config KVM_ARM_MAX_VCPUS
  large, so only choose a reasonable number that you expect to
  actually use.

+config KVM_ARM_PMU
+   bool
+   depends on KVM_ARM_HOST
+   ---help---
+ Adds support for the Performance Monitoring in virtual machines.


Adds support for a virtual Performance Monitoring Unit (PMU) in virtual
machines.


+
  endif # VIRTUALIZATION
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index f90f4aa..78db4ee 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -27,3 +27,4 @@ kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic-v3.o
  kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic-v3-emul.o
  kvm-$(CONFIG_KVM_ARM_HOST) += vgic-v3-switch.o
  kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/arch_timer.o
+kvm-$(CONFIG_KVM_ARM_PMU) += $(KVM)/arm/pmu.o
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 0b43265..ee2c2e9 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -107,5 +107,8 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
/* Reset timer */
kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);

+   /* Reset PMU */
+   kvm_pmu_vcpu_reset(vcpu);
+
return 0;
  }
diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
new file mode 100644
index 000..27d14ca
--- /dev/null
+++ b/include/kvm/arm_pmu.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2015 Linaro Ltd.
+ * Author: Shannon Zhao shannon.z...@linaro.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; 

Re: [PATCH 02/18] KVM: ARM64: Add initial support for PMU

2015-07-17 Thread Christoffer Dall
On Fri, Jul 17, 2015 at 07:34:58PM +0800, Shannon Zhao wrote:
 
 
 On 2015/7/17 17:58, Christoffer Dall wrote:
 On Fri, Jul 17, 2015 at 04:13:35PM +0800, Shannon Zhao wrote:
 
 
 On 2015/7/17 2:25, Christoffer Dall wrote:
 On Mon, Jul 06, 2015 at 10:17:32AM +0800, shannon.z...@linaro.org wrote:
 From: Shannon Zhao shannon.z...@linaro.org
 
 Here we plan to support virtual PMU for guest by full software
 emulation, so define some basic structs and functions preparing for
 futher steps. Define struct kvm_pmc for performance monitor counter and
 struct kvm_pmu for performance monitor unit for each vcpu. According to
 ARMv8 spec, the PMU contains at most 32(ARMV8_MAX_COUNTERS) counters.
 Initialize PMU for each vcpu when kvm initialize vcpus, while reset PMU
 when kvm reset vcpus.
 Since this only supports ARM64 (or PMUv3), add a separate config symbol
 for it.
 
 Signed-off-by: Shannon Zhao shannon.z...@linaro.org
 ---
   arch/arm/kvm/arm.c|  4 +++
   arch/arm64/include/asm/kvm_host.h |  2 ++
   arch/arm64/include/asm/pmu.h  |  2 ++
   arch/arm64/kvm/Kconfig|  7 +
   arch/arm64/kvm/Makefile   |  1 +
   arch/arm64/kvm/reset.c|  3 +++
   include/kvm/arm_pmu.h | 54 
  ++
   virt/kvm/arm/pmu.c| 55 
  +++
   8 files changed, 128 insertions(+)
   create mode 100644 include/kvm/arm_pmu.h
   create mode 100644 virt/kvm/arm/pmu.c
 
 diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
 index bc738d2..4e82625 100644
 --- a/arch/arm/kvm/arm.c
 +++ b/arch/arm/kvm/arm.c
 @@ -28,6 +28,7 @@
   #include linux/sched.h
   #include linux/kvm.h
   #include trace/events/kvm.h
 +#include kvm/arm_pmu.h
 
   #define CREATE_TRACE_POINTS
   #include trace.h
 @@ -278,6 +279,9 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
   /* Set up the timer */
   kvm_timer_vcpu_init(vcpu);
 
 + /* Set up the PMU */
 + kvm_pmu_init(vcpu);
 +
   return 0;
   }
 
 diff --git a/arch/arm64/include/asm/kvm_host.h 
 b/arch/arm64/include/asm/kvm_host.h
 index 2709db2..3c88873 100644
 --- a/arch/arm64/include/asm/kvm_host.h
 +++ b/arch/arm64/include/asm/kvm_host.h
 @@ -42,6 +42,7 @@
 
   #include kvm/arm_vgic.h
   #include kvm/arm_arch_timer.h
 +#include kvm/arm_pmu.h
 
   #define KVM_VCPU_MAX_FEATURES 3
 
 @@ -116,6 +117,7 @@ struct kvm_vcpu_arch {
   /* VGIC state */
   struct vgic_cpu vgic_cpu;
   struct arch_timer_cpu timer_cpu;
 + struct kvm_pmu pmu;
 
   /*
* Anything that is not used directly from assembly code goes
 diff --git a/arch/arm64/include/asm/pmu.h b/arch/arm64/include/asm/pmu.h
 index b9f394a..95681e6 100644
 --- a/arch/arm64/include/asm/pmu.h
 +++ b/arch/arm64/include/asm/pmu.h
 @@ -19,6 +19,8 @@
   #ifndef __ASM_PMU_H
   #define __ASM_PMU_H
 
 +#include linux/perf_event.h
 +
   #define ARMV8_MAX_COUNTERS  32
   #define ARMV8_COUNTER_MASK  (ARMV8_MAX_COUNTERS - 1)
 
 diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
 index bfffe8f..eae3a1b 100644
 --- a/arch/arm64/kvm/Kconfig
 +++ b/arch/arm64/kvm/Kconfig
 @@ -31,6 +31,7 @@ config KVM
   select KVM_VFIO
   select HAVE_KVM_EVENTFD
   select HAVE_KVM_IRQFD
 + select KVM_ARM_PMU
   ---help---
 Support hosting virtualized guest machines.
 
 @@ -52,4 +53,10 @@ config KVM_ARM_MAX_VCPUS
 large, so only choose a reasonable number that you expect to
 actually use.
 
 +config KVM_ARM_PMU
 + bool
 + depends on KVM_ARM_HOST
 + ---help---
 +   Adds support for the Performance Monitoring in virtual machines.
 
 Adds support for a virtual Performance Monitoring Unit (PMU) in virtual
 machines.
 
 +
   endif # VIRTUALIZATION
 diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
 index f90f4aa..78db4ee 100644
 --- a/arch/arm64/kvm/Makefile
 +++ b/arch/arm64/kvm/Makefile
 @@ -27,3 +27,4 @@ kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic-v3.o
   kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic-v3-emul.o
   kvm-$(CONFIG_KVM_ARM_HOST) += vgic-v3-switch.o
   kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/arch_timer.o
 +kvm-$(CONFIG_KVM_ARM_PMU) += $(KVM)/arm/pmu.o
 diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
 index 0b43265..ee2c2e9 100644
 --- a/arch/arm64/kvm/reset.c
 +++ b/arch/arm64/kvm/reset.c
 @@ -107,5 +107,8 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
   /* Reset timer */
   kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);
 
 + /* Reset PMU */
 + kvm_pmu_vcpu_reset(vcpu);
 +
   return 0;
   }
 diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
 new file mode 100644
 index 000..27d14ca
 --- /dev/null
 +++ b/include/kvm/arm_pmu.h
 @@ -0,0 +1,54 @@
 +/*
 + * Copyright (C) 2015 Linaro Ltd.
 + * Author: Shannon Zhao shannon.z...@linaro.org
 + *
 + * This program is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU 

Re: [PATCH 06/18] KVM: ARM64: Add reset and access handlers for PMCEID0_EL0 and PMCEID1_EL0 register

2015-07-17 Thread Christoffer Dall
On Mon, Jul 06, 2015 at 10:17:36AM +0800, shannon.z...@linaro.org wrote:
 From: Shannon Zhao shannon.z...@linaro.org
 
 Add reset handler which gets host value of PMCEID0_EL0 or PMCEID1_EL0.
 Add access handler which emulates writing and reading PMCEID0_EL0 or
 PMCEID1_EL0 register.
 
 Signed-off-by: Shannon Zhao shannon.z...@linaro.org
 ---
  arch/arm64/kvm/sys_regs.c | 36 ++--
  1 file changed, 34 insertions(+), 2 deletions(-)
 
 diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
 index 69c8c48..1df9ef3 100644
 --- a/arch/arm64/kvm/sys_regs.c
 +++ b/arch/arm64/kvm/sys_regs.c
 @@ -246,6 +246,19 @@ static void reset_pmcr_el0(struct kvm_vcpu *vcpu, const 
 struct sys_reg_desc *r)
  | (ARMV8_PMCR_MASK  0xdecafbad);
  }
  
 +static void reset_pmceid(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
 +{
 + u32 pmceid;
 +
 + if (r-reg == PMCEID0_EL0) {
 + asm volatile(mrs %0, pmceid0_el0\n : =r (pmceid));
 + vcpu_sys_reg(vcpu, r-reg) = pmceid;
 + } else {

add /* PMCEID1_EL1 */
 + asm volatile(mrs %0, pmceid1_el0\n : =r (pmceid));
 + vcpu_sys_reg(vcpu, r-reg) = pmceid;
 + }
 +}
 +
  /* PMCR_EL0 accessor. Only called as long as MDCR_EL2.TPMCR is set. */
  static bool access_pmcr(struct kvm_vcpu *vcpu,
   const struct sys_reg_params *p,
 @@ -299,6 +312,25 @@ static bool access_pmselr(struct kvm_vcpu *vcpu,
   return true;
  }
  
 +/* PMCEID0_EL0 and PMCEID1_EL0 accessor. */
 +static bool access_pmceid(struct kvm_vcpu *vcpu,
 +   const struct sys_reg_params *p,
 +   const struct sys_reg_desc *r)
 +{
 + unsigned long val;
 +
 + if (p-is_write) {
 + return ignore_write(vcpu, p);
 + } else {
 + if (!p-is_aarch32)
 + val = vcpu_sys_reg(vcpu, r-reg);
 + else
 + val = vcpu_cp15(vcpu, r-reg);
 + *vcpu_reg(vcpu, p-Rt) = val;
 + return true;
 + }
 +}
 +
  /* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */
  #define DBG_BCR_BVR_WCR_WVR_EL1(n)   \
   /* DBGBVRn_EL1 */   \
 @@ -508,10 +540,10 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 access_pmselr, reset_unknown, PMSELR_EL0 },
   /* PMCEID0_EL0 */
   { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b110),
 -   trap_raz_wi },
 +   access_pmceid, reset_pmceid, PMCEID0_EL0, },
   /* PMCEID1_EL0 */
   { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b111),
 -   trap_raz_wi },
 +   access_pmceid, reset_pmceid, PMCEID1_EL0, },
   /* PMCCNTR_EL0 */
   { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1101), Op2(0b000),
 trap_raz_wi },
 -- 
 2.1.0
 
same comment wrt. 32-bit table.

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


[PATCH] RFC: vhost: actually track log eventfd file

2015-07-17 Thread Marc-André Lureau
While reviewing vhost log code, I found out that log_file is never
set. Note: I haven't tested the change (QEMU doesn't use LOG_FD yet).

Signed-off-by: Marc-André Lureau marcandre.lur...@redhat.com
---
 drivers/vhost/vhost.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 2ee2826..fa49d329 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -886,6 +886,7 @@ long vhost_dev_ioctl(struct vhost_dev *d, unsigned int 
ioctl, void __user *argp)
}
if (eventfp != d-log_file) {
filep = d-log_file;
+   d-log_file = eventfp;
ctx = d-log_ctx;
d-log_ctx = eventfp ?
eventfd_ctx_fileget(eventfp) : NULL;
-- 
2.4.3

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


Re: [PATCH 12/18] KVM: ARM64: Add reset and access handlers for PMINTENSET_EL1 and PMINTENCLR_EL1 register

2015-07-17 Thread Christoffer Dall
On Mon, Jul 06, 2015 at 10:17:42AM +0800, shannon.z...@linaro.org wrote:
 From: Shannon Zhao shannon.z...@linaro.org
 
 Since the reset value of PMINTENSET_EL1 and PMINTENCLR_EL1 is UNKNOWN,
 use reset_unknown for its reset handler. Add access handler which
 emulates writing and reading PMINTENSET_EL1 or PMINTENCLR_EL1 register.
 When writing to PMINTENSET_EL1, set the interrupt flag true. While
 writing to PMINTENCLR_EL1, set the interrupt flag false. This flag will
 be useful for counter overflow interrupt.
 
 Signed-off-by: Shannon Zhao shannon.z...@linaro.org
 ---
  arch/arm64/kvm/sys_regs.c | 56 
 +--
  include/kvm/arm_pmu.h |  4 
  virt/kvm/arm/pmu.c| 28 
  3 files changed, 86 insertions(+), 2 deletions(-)
 
 diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
 index c14ec8d..cbc07b8 100644
 --- a/arch/arm64/kvm/sys_regs.c
 +++ b/arch/arm64/kvm/sys_regs.c
 @@ -444,6 +444,58 @@ static bool access_pmcntenclr(struct kvm_vcpu *vcpu,
   return true;
  }
  
 +/* PMINTENSET_EL1 accessor. */
 +static bool access_pmintenset(struct kvm_vcpu *vcpu,
 +   const struct sys_reg_params *p,
 +   const struct sys_reg_desc *r)
 +{
 + unsigned long val;
 +
 + if (p-is_write) {
 + val = *vcpu_reg(vcpu, p-Rt);
 + if (!p-is_aarch32)
 + vcpu_sys_reg(vcpu, r-reg) |= val;
 + else
 + vcpu_cp15(vcpu, r-reg) |= val  0xUL;
 +
 + kvm_pmu_enable_interrupt(vcpu, val);
 + } else {
 + if (!p-is_aarch32)
 + val = vcpu_sys_reg(vcpu, r-reg);
 + else
 + val = vcpu_cp15(vcpu, r-reg);
 + *vcpu_reg(vcpu, p-Rt) = val;
 + }
 +
 + return true;
 +}
 +
 +/* PMINTENCLR_EL1 accessor. */
 +static bool access_pmintenclr(struct kvm_vcpu *vcpu,
 +   const struct sys_reg_params *p,
 +   const struct sys_reg_desc *r)
 +{
 + unsigned long val;
 +
 + if (p-is_write) {
 + val = *vcpu_reg(vcpu, p-Rt);
 + if (!p-is_aarch32)
 + vcpu_sys_reg(vcpu, r-reg) |= val;
 + else
 + vcpu_cp15(vcpu, r-reg) |= val  0xUL;
 +
 + kvm_pmu_disable_interrupt(vcpu, val);
 + } else {
 + if (!p-is_aarch32)
 + val = vcpu_sys_reg(vcpu, r-reg);
 + else
 + val = vcpu_cp15(vcpu, r-reg);
 + *vcpu_reg(vcpu, p-Rt) = val;
 + }

Same comments as in the previous patch, but now I realize what you're
doing with the set/clear registers.  These are not separate pieces of
state, but a single register, which are just accessed with two
interfaces, for set/clear patterns.

 +
 + return true;
 +}
 +
  /* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */
  #define DBG_BCR_BVR_WCR_WVR_EL1(n)   \
   /* DBGBVRn_EL1 */   \
 @@ -595,10 +647,10 @@ static const struct sys_reg_desc sys_reg_descs[] = {
  
   /* PMINTENSET_EL1 */
   { Op0(0b11), Op1(0b000), CRn(0b1001), CRm(0b1110), Op2(0b001),
 -   trap_raz_wi },
 +   access_pmintenset, reset_unknown, PMINTENSET_EL1 },
   /* PMINTENCLR_EL1 */
   { Op0(0b11), Op1(0b000), CRn(0b1001), CRm(0b1110), Op2(0b010),
 -   trap_raz_wi },
 +   access_pmintenclr, reset_unknown, PMINTENCLR_EL1 },
  
   /* MAIR_EL1 */
   { Op0(0b11), Op1(0b000), CRn(0b1010), CRm(0b0010), Op2(0b000),
 diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
 index 2cfd9be..dee8356 100644
 --- a/include/kvm/arm_pmu.h
 +++ b/include/kvm/arm_pmu.h
 @@ -51,6 +51,8 @@ unsigned long kvm_pmu_get_counter_value(struct kvm_vcpu 
 *vcpu,
   unsigned long select_idx);
  void kvm_pmu_disable_counter(struct kvm_vcpu *vcpu, unsigned long val);
  void kvm_pmu_enable_counter(struct kvm_vcpu *vcpu, unsigned long val);
 +void kvm_pmu_disable_interrupt(struct kvm_vcpu *vcpu, unsigned long val);
 +void kvm_pmu_enable_interrupt(struct kvm_vcpu *vcpu, unsigned long val);
  void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, unsigned long 
 data,
   unsigned long select_idx);
  void kvm_pmu_init(struct kvm_vcpu *vcpu);
 @@ -65,6 +67,8 @@ unsigned long kvm_pmu_get_counter_value(struct kvm_vcpu 
 *vcpu,
  }
  void kvm_pmu_disable_counter(struct kvm_vcpu *vcpu, unsigned long val) {}
  void kvm_pmu_enable_counter(struct kvm_vcpu *vcpu, unsigned long val) {}
 +void kvm_pmu_disable_interrupt(struct kvm_vcpu *vcpu, unsigned long val) {}
 +void kvm_pmu_enable_interrupt(struct kvm_vcpu *vcpu, unsigned long val) {}
  void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, unsigned long 
 data,
   

Re: [PATCH 13/18] KVM: ARM64: Add reset and access handlers for PMOVSSET_EL0 and PMOVSCLR_EL0 register

2015-07-17 Thread Christoffer Dall
On Mon, Jul 06, 2015 at 10:17:43AM +0800, shannon.z...@linaro.org wrote:
 From: Shannon Zhao shannon.z...@linaro.org
 
 Since the reset value of PMOVSSET_EL0 and PMOVSCLR_EL0 is UNKNOWN, use
 reset_unknown for its reset handler. Add access handler which emulates
 writing and reading PMOVSSET_EL0 or PMOVSCLR_EL0 register.
 
 Signed-off-by: Shannon Zhao shannon.z...@linaro.org
 ---
  arch/arm64/kvm/sys_regs.c | 30 --
  1 file changed, 28 insertions(+), 2 deletions(-)
 
 diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
 index cbc07b8..ec80937 100644
 --- a/arch/arm64/kvm/sys_regs.c
 +++ b/arch/arm64/kvm/sys_regs.c
 @@ -496,6 +496,32 @@ static bool access_pmintenclr(struct kvm_vcpu *vcpu,
   return true;
  }
  
 +/* PMOVSSET_EL0 accessor. */
 +static bool access_pmovsset(struct kvm_vcpu *vcpu,
 + const struct sys_reg_params *p,
 + const struct sys_reg_desc *r)
 +{
 + if (p-is_write)
 + vcpu-arch.pmu.overflow_status |= *vcpu_reg(vcpu, p-Rt);
 + else
 + *vcpu_reg(vcpu, p-Rt) = vcpu-arch.pmu.overflow_status;
 +
 + return true;
 +}
 +
 +/* PMOVSCLR_EL0 accessor. */
 +static bool access_pmovsclr(struct kvm_vcpu *vcpu,
 + const struct sys_reg_params *p,
 + const struct sys_reg_desc *r)
 +{
 + if (p-is_write)
 + vcpu-arch.pmu.overflow_status = (~*vcpu_reg(vcpu, p-Rt));

why the extra parenthesis here?  If anything, I would think the bitwise
not should be on the outside of the parenthesis.

-Christoffer


 + else
 + *vcpu_reg(vcpu, p-Rt) = vcpu-arch.pmu.overflow_status;
 +
 + return true;
 +}
 +
  /* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */
  #define DBG_BCR_BVR_WCR_WVR_EL1(n)   \
   /* DBGBVRn_EL1 */   \
 @@ -696,7 +722,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 access_pmcntenclr, reset_unknown, PMCNTENCLR_EL0 },
   /* PMOVSCLR_EL0 */
   { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b011),
 -   trap_raz_wi },
 +   access_pmovsclr, reset_unknown, PMOVSCLR_EL0 },
   /* PMSWINC_EL0 */
   { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b100),
 trap_raz_wi },
 @@ -723,7 +749,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 trap_raz_wi },
   /* PMOVSSET_EL0 */
   { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1110), Op2(0b011),
 -   trap_raz_wi },
 +   access_pmovsset, reset_unknown, PMOVSSET_EL0 },
  
   /* TPIDR_EL0 */
   { Op0(0b11), Op1(0b011), CRn(0b1101), CRm(0b), Op2(0b010),
 -- 
 2.1.0
 
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 14/18] KVM: ARM64: Add reset and access handlers for PMUSERENR_EL0 register

2015-07-17 Thread Christoffer Dall
On Mon, Jul 06, 2015 at 10:17:44AM +0800, shannon.z...@linaro.org wrote:
 From: Shannon Zhao shannon.z...@linaro.org
 
 Since the reset value of PMUSERENR_EL0 is UNKNOWN, use reset_unknown for
 its reset handler. Add access handler which emulates writing and reading
 PMUSERENR_EL0 register.
 
 Signed-off-by: Shannon Zhao shannon.z...@linaro.org
 ---
  arch/arm64/kvm/sys_regs.c | 15 ++-
  include/kvm/arm_pmu.h |  1 +
  2 files changed, 15 insertions(+), 1 deletion(-)
 
 diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
 index ec80937..d5984d0 100644
 --- a/arch/arm64/kvm/sys_regs.c
 +++ b/arch/arm64/kvm/sys_regs.c
 @@ -522,6 +522,19 @@ static bool access_pmovsclr(struct kvm_vcpu *vcpu,
   return true;
  }
  
 +/* PMUSERENR_EL0 accessor. */
 +static bool access_pmuserenr(struct kvm_vcpu *vcpu,
 +  const struct sys_reg_params *p,
 +  const struct sys_reg_desc *r)
 +{
 + if (p-is_write)
 + vcpu-arch.pmu.user_enable |= *vcpu_reg(vcpu, p-Rt);
 + else
 + *vcpu_reg(vcpu, p-Rt) = vcpu-arch.pmu.user_enable;
 +
 + return true;
 +}
 +
  /* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */
  #define DBG_BCR_BVR_WCR_WVR_EL1(n)   \
   /* DBGBVRn_EL1 */   \
 @@ -746,7 +759,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 access_pmxevcntr, reset_unknown, PMXEVCNTR_EL0 },
   /* PMUSERENR_EL0 */
   { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1110), Op2(0b000),
 -   trap_raz_wi },
 +   access_pmuserenr, reset_unknown, PMUSERENR_EL0 },
   /* PMOVSSET_EL0 */
   { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1110), Op2(0b011),
 access_pmovsset, reset_unknown, PMOVSSET_EL0 },
 diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
 index dee8356..4f3d8a6 100644
 --- a/include/kvm/arm_pmu.h
 +++ b/include/kvm/arm_pmu.h
 @@ -39,6 +39,7 @@ struct kvm_pmu {
   /* IRQ pending flag */
   bool irq_pending;
   struct irq_work irq_work;
 + u32 user_enable;

why not store this in PMUSERENR_EL0 and get VM migration of this state
included for free?

Also, I assume the functionality to respect these flags are implemented
in a later patch or simply not supported?  It would have been good to
note this in the cover letter.

-Christoffer

   struct kvm_pmc pmc[ARMV8_MAX_COUNTERS];
  #endif
  };
 -- 
 2.1.0
 
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 13/18] KVM: ARM64: Add reset and access handlers for PMOVSSET_EL0 and PMOVSCLR_EL0 register

2015-07-17 Thread Christoffer Dall
On Mon, Jul 06, 2015 at 10:17:43AM +0800, shannon.z...@linaro.org wrote:
 From: Shannon Zhao shannon.z...@linaro.org
 
 Since the reset value of PMOVSSET_EL0 and PMOVSCLR_EL0 is UNKNOWN, use
 reset_unknown for its reset handler. Add access handler which emulates
 writing and reading PMOVSSET_EL0 or PMOVSCLR_EL0 register.
 
 Signed-off-by: Shannon Zhao shannon.z...@linaro.org
 ---
  arch/arm64/kvm/sys_regs.c | 30 --
  1 file changed, 28 insertions(+), 2 deletions(-)
 
 diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
 index cbc07b8..ec80937 100644
 --- a/arch/arm64/kvm/sys_regs.c
 +++ b/arch/arm64/kvm/sys_regs.c
 @@ -496,6 +496,32 @@ static bool access_pmintenclr(struct kvm_vcpu *vcpu,
   return true;
  }
  
 +/* PMOVSSET_EL0 accessor. */
 +static bool access_pmovsset(struct kvm_vcpu *vcpu,
 + const struct sys_reg_params *p,
 + const struct sys_reg_desc *r)
 +{
 + if (p-is_write)
 + vcpu-arch.pmu.overflow_status |= *vcpu_reg(vcpu, p-Rt);
 + else
 + *vcpu_reg(vcpu, p-Rt) = vcpu-arch.pmu.overflow_status;

if you store this state in PMOVSSET_EL0 you get VM migration
save/restore support for (almost) free.

-Christoffer

 +
 + return true;
 +}
 +
 +/* PMOVSCLR_EL0 accessor. */
 +static bool access_pmovsclr(struct kvm_vcpu *vcpu,
 + const struct sys_reg_params *p,
 + const struct sys_reg_desc *r)
 +{
 + if (p-is_write)
 + vcpu-arch.pmu.overflow_status = (~*vcpu_reg(vcpu, p-Rt));
 + else
 + *vcpu_reg(vcpu, p-Rt) = vcpu-arch.pmu.overflow_status;
 +
 + return true;
 +}
 +
  /* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */
  #define DBG_BCR_BVR_WCR_WVR_EL1(n)   \
   /* DBGBVRn_EL1 */   \
 @@ -696,7 +722,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 access_pmcntenclr, reset_unknown, PMCNTENCLR_EL0 },
   /* PMOVSCLR_EL0 */
   { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b011),
 -   trap_raz_wi },
 +   access_pmovsclr, reset_unknown, PMOVSCLR_EL0 },
   /* PMSWINC_EL0 */
   { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b100),
 trap_raz_wi },
 @@ -723,7 +749,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 trap_raz_wi },
   /* PMOVSSET_EL0 */
   { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1110), Op2(0b011),
 -   trap_raz_wi },
 +   access_pmovsset, reset_unknown, PMOVSSET_EL0 },
  
   /* TPIDR_EL0 */
   { Op0(0b11), Op1(0b011), CRn(0b1101), CRm(0b), Op2(0b010),
 -- 
 2.1.0
 
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 15/18] KVM: ARM64: Add reset and access handlers for PMSWINC_EL0 register

2015-07-17 Thread Christoffer Dall
On Mon, Jul 06, 2015 at 10:17:45AM +0800, shannon.z...@linaro.org wrote:
 From: Shannon Zhao shannon.z...@linaro.org
 
 Add access handler which emulates writing and reading PMSWINC_EL0
 register and add support for creating software increment event.
 
 Signed-off-by: Shannon Zhao shannon.z...@linaro.org
 ---
  arch/arm64/kvm/sys_regs.c | 15 ++-
  include/kvm/arm_pmu.h |  2 ++
  virt/kvm/arm/pmu.c| 20 
  3 files changed, 36 insertions(+), 1 deletion(-)
 
 diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
 index d5984d0..70afcba 100644
 --- a/arch/arm64/kvm/sys_regs.c
 +++ b/arch/arm64/kvm/sys_regs.c
 @@ -535,6 +535,19 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu,
   return true;
  }
  
 +/* PMSWINC_EL0 accessor. */
 +static bool access_pmswinc(struct kvm_vcpu *vcpu,
 +const struct sys_reg_params *p,
 +const struct sys_reg_desc *r)
 +{
 + if (p-is_write)
 + kvm_pmu_software_increment(vcpu, *vcpu_reg(vcpu, p-Rt));
 + else
 + return read_zero(vcpu, p);
 +
 + return true;
 +}
 +
  /* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */
  #define DBG_BCR_BVR_WCR_WVR_EL1(n)   \
   /* DBGBVRn_EL1 */   \
 @@ -738,7 +751,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 access_pmovsclr, reset_unknown, PMOVSCLR_EL0 },
   /* PMSWINC_EL0 */
   { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b100),
 -   trap_raz_wi },
 +   access_pmswinc, reset_unknown, PMSWINC_EL0 },
   /* PMSELR_EL0 */
   { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b101),
 access_pmselr, reset_unknown, PMSELR_EL0 },
 diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
 index 4f3d8a6..6985809 100644
 --- a/include/kvm/arm_pmu.h
 +++ b/include/kvm/arm_pmu.h
 @@ -54,6 +54,7 @@ void kvm_pmu_disable_counter(struct kvm_vcpu *vcpu, 
 unsigned long val);
  void kvm_pmu_enable_counter(struct kvm_vcpu *vcpu, unsigned long val);
  void kvm_pmu_disable_interrupt(struct kvm_vcpu *vcpu, unsigned long val);
  void kvm_pmu_enable_interrupt(struct kvm_vcpu *vcpu, unsigned long val);
 +void kvm_pmu_software_increment(struct kvm_vcpu *vcpu, unsigned long val);
  void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, unsigned long 
 data,
   unsigned long select_idx);
  void kvm_pmu_init(struct kvm_vcpu *vcpu);
 @@ -70,6 +71,7 @@ void kvm_pmu_disable_counter(struct kvm_vcpu *vcpu, 
 unsigned long val) {}
  void kvm_pmu_enable_counter(struct kvm_vcpu *vcpu, unsigned long val) {}
  void kvm_pmu_disable_interrupt(struct kvm_vcpu *vcpu, unsigned long val) {}
  void kvm_pmu_enable_interrupt(struct kvm_vcpu *vcpu, unsigned long val) {}
 +void kvm_pmu_software_increment(struct kvm_vcpu *vcpu, unsigned long val) {}
  void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, unsigned long 
 data,
   unsigned long select_idx) {}
  static inline void kvm_pmu_init(struct kvm_vcpu *vcpu) {}
 diff --git a/virt/kvm/arm/pmu.c b/virt/kvm/arm/pmu.c
 index 7023ad5..e655426 100644
 --- a/virt/kvm/arm/pmu.c
 +++ b/virt/kvm/arm/pmu.c
 @@ -203,6 +203,22 @@ void kvm_pmu_disable_interrupt(struct kvm_vcpu *vcpu, 
 unsigned long val)
  }
  
  /**
 + * kvm_pmu_software_increment - do software increment
 + * @vcpu: The vcpu pointer
 + * @val: the value guest writes to PMSWINC_EL0 register
 + */
 +void kvm_pmu_software_increment(struct kvm_vcpu *vcpu, unsigned long val)
 +{
 + int select_idx = find_first_bit(val, 31);

can you not also increment multiple counters with a single write here?

or is it an error to configure multiple counters to the same event?  And
if it is, do we enforce that somehow?  If not, should they not reflect
the same underlying value instead of a separate pmc-counter value?


 + struct kvm_pmu *pmu = vcpu-arch.pmu;
 + struct kvm_pmc *pmc = pmu-pmc[select_idx];
 +
 + if (pmu-user_enable  0x3)

shouldn't this be:
if (vcpu_mode_priv(vcpu) || pmu-user_enable  0x3 == 0x3)

?


 + if ((pmc-eventsel == 0)  (pmc-enable == true))
 + pmc-counter++;

how do we migrate this state?  do we care?

-Christoffer

 +}
 +
 +/**
   * kvm_pmu_find_hw_event - find hardware event
   * @pmu: The pmu pointer
   * @event_select: The number of selected event type
 @@ -280,6 +296,10 @@ void kvm_pmu_set_counter_event_type(struct kvm_vcpu 
 *vcpu, unsigned long data,
   kvm_pmu_stop_counter(vcpu, select_idx);
   pmc-eventsel = data  ARMV8_EVTYPE_EVENT;
  
 + /* For software increment event we don't need to create perf event */
 + if (pmc-eventsel == 0)
 + return;
 +
   config = kvm_pmu_find_hw_event(pmu, pmc-eventsel);
   if (config != PERF_COUNT_HW_MAX) {
   type = PERF_TYPE_HARDWARE;
 -- 
 2.1.0
 
--
To 

Re: [PATCH 16/18] KVM: ARM64: Add access handlers for PMEVCNTRn_EL0 and PMEVTYPERn_EL0 register

2015-07-17 Thread Christoffer Dall
On Mon, Jul 06, 2015 at 10:17:46AM +0800, shannon.z...@linaro.org wrote:
 From: Shannon Zhao shannon.z...@linaro.org
 
 Add access handler which emulates writing and reading PMEVCNTRn_EL0 and
 PMEVTYPERn_EL0.
 
 Signed-off-by: Shannon Zhao shannon.z...@linaro.org
 ---
  arch/arm64/kvm/sys_regs.c | 106 
 ++
  1 file changed, 106 insertions(+)
 
 diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
 index 70afcba..5663d83 100644
 --- a/arch/arm64/kvm/sys_regs.c
 +++ b/arch/arm64/kvm/sys_regs.c
 @@ -548,6 +548,30 @@ static bool access_pmswinc(struct kvm_vcpu *vcpu,
   return true;
  }
  
 +/* PMU reg accessor. */
 +static bool access_pmu_reg(struct kvm_vcpu *vcpu,
 +const struct sys_reg_params *p,
 +const struct sys_reg_desc *r)
 +{
 + unsigned long val;
 +
 + if (p-is_write) {
 + val = *vcpu_reg(vcpu, p-Rt);
 + if (!p-is_aarch32)
 + vcpu_sys_reg(vcpu, r-reg) = val;
 + else
 + vcpu_cp15(vcpu, r-reg) = val  0xUL;
 + } else {
 + if (!p-is_aarch32)
 + val = vcpu_sys_reg(vcpu, r-reg);
 + else
 + val = vcpu_cp15(vcpu, r-reg);
 + *vcpu_reg(vcpu, p-Rt) = val;
 + }

shouldn't these functions act completely analogously to access_pmxevcntr
(introduced in patch 09/18), only instead of using the valur of
PMSELR_EL0 for the index, this should be some offset calculation or
r-reg?

I think you also need a 32-bit mapping with the right offset for the
p-is_aarch32 check to make sense here (I may have forgotten this in a
few patches, please check all of them for this).

 +
 + return true;
 +}
 +
  /* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */
  #define DBG_BCR_BVR_WCR_WVR_EL1(n)   \
   /* DBGBVRn_EL1 */   \
 @@ -563,6 +587,20 @@ static bool access_pmswinc(struct kvm_vcpu *vcpu,
   { Op0(0b10), Op1(0b000), CRn(0b), CRm((n)), Op2(0b111), \
 trap_debug_regs, reset_val, (DBGWCR0_EL1 + (n)), 0 }
  
 +/* Macro to expand the PMEVCNTRn_EL0 register */
 +#define PMU_PMEVCNTR_EL0(n)  \
 + /* PMEVCNTRn_EL0 */ \
 + { Op0(0b11), Op1(0b011), CRn(0b1110),   \
 +   CRm((0b1000 | (((n)  3)  0x3))), Op2(((n)  0x7)), \
 +   access_pmu_reg, reset_val, (PMEVCNTR0_EL0 + (n)*2), 0 }
 +
 +/* Macro to expand the PMEVTYPERn_EL0 register */
 +#define PMU_PMEVTYPER_EL0(n) \
 + /* PMEVTYPERn_EL0 */\
 + { Op0(0b11), Op1(0b011), CRn(0b1110),   \
 +   CRm((0b1100 | (((n)  3)  0x3))), Op2(((n)  0x7)), \
 +   access_pmu_reg, reset_val, (PMEVTYPER0_EL0 + (n)*2), 0 }
 +
  /*
   * Architected system registers.
   * Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2
 @@ -784,6 +822,74 @@ static const struct sys_reg_desc sys_reg_descs[] = {
   { Op0(0b11), Op1(0b011), CRn(0b1101), CRm(0b), Op2(0b011),
 NULL, reset_unknown, TPIDRRO_EL0 },
  
 + /* PMEVCNTRn_EL0 */
 + PMU_PMEVCNTR_EL0(0),
 + PMU_PMEVCNTR_EL0(1),
 + PMU_PMEVCNTR_EL0(2),
 + PMU_PMEVCNTR_EL0(3),
 + PMU_PMEVCNTR_EL0(4),
 + PMU_PMEVCNTR_EL0(5),
 + PMU_PMEVCNTR_EL0(6),
 + PMU_PMEVCNTR_EL0(7),
 + PMU_PMEVCNTR_EL0(8),
 + PMU_PMEVCNTR_EL0(9),
 + PMU_PMEVCNTR_EL0(10),
 + PMU_PMEVCNTR_EL0(11),
 + PMU_PMEVCNTR_EL0(12),
 + PMU_PMEVCNTR_EL0(13),
 + PMU_PMEVCNTR_EL0(14),
 + PMU_PMEVCNTR_EL0(15),
 + PMU_PMEVCNTR_EL0(16),
 + PMU_PMEVCNTR_EL0(17),
 + PMU_PMEVCNTR_EL0(18),
 + PMU_PMEVCNTR_EL0(19),
 + PMU_PMEVCNTR_EL0(20),
 + PMU_PMEVCNTR_EL0(21),
 + PMU_PMEVCNTR_EL0(22),
 + PMU_PMEVCNTR_EL0(23),
 + PMU_PMEVCNTR_EL0(24),
 + PMU_PMEVCNTR_EL0(25),
 + PMU_PMEVCNTR_EL0(26),
 + PMU_PMEVCNTR_EL0(27),
 + PMU_PMEVCNTR_EL0(28),
 + PMU_PMEVCNTR_EL0(29),
 + PMU_PMEVCNTR_EL0(30),
 + /* PMEVTYPERn_EL0 */
 + PMU_PMEVTYPER_EL0(0),
 + PMU_PMEVTYPER_EL0(1),
 + PMU_PMEVTYPER_EL0(2),
 + PMU_PMEVTYPER_EL0(3),
 + PMU_PMEVTYPER_EL0(4),
 + PMU_PMEVTYPER_EL0(5),
 + PMU_PMEVTYPER_EL0(6),
 + PMU_PMEVTYPER_EL0(7),
 + PMU_PMEVTYPER_EL0(8),
 + PMU_PMEVTYPER_EL0(9),
 + PMU_PMEVTYPER_EL0(10),
 + PMU_PMEVTYPER_EL0(11),
 + PMU_PMEVTYPER_EL0(12),
 + PMU_PMEVTYPER_EL0(13),
 + PMU_PMEVTYPER_EL0(14),
 + PMU_PMEVTYPER_EL0(15),
 + PMU_PMEVTYPER_EL0(16),
 + PMU_PMEVTYPER_EL0(17),
 + PMU_PMEVTYPER_EL0(18),
 + PMU_PMEVTYPER_EL0(19),
 + PMU_PMEVTYPER_EL0(20),
 + PMU_PMEVTYPER_EL0(21),
 + PMU_PMEVTYPER_EL0(22),
 + PMU_PMEVTYPER_EL0(23),
 

Re: [PATCH 17/18] KVM: ARM64: Add PMU overflow interrupt routing

2015-07-17 Thread Christoffer Dall
On Mon, Jul 06, 2015 at 10:17:47AM +0800, shannon.z...@linaro.org wrote:
 From: Shannon Zhao shannon.z...@linaro.org
 
 When calling perf_event_create_kernel_counter to create perf_event,
 assign a overflow handler. Then when perf event overflows, if vcpu
 doesn't run, call irq_work_queue to wake up vcpu. Otherwise call
 kvm_vgic_inject_irq to inject the interrupt.
 
 Signed-off-by: Shannon Zhao shannon.z...@linaro.org
 ---
  arch/arm/kvm/arm.c|  2 ++
  include/kvm/arm_pmu.h |  2 ++
  virt/kvm/arm/pmu.c| 53 
 ++-
  3 files changed, 56 insertions(+), 1 deletion(-)
 
 diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
 index 4e82625..41eb063 100644
 --- a/arch/arm/kvm/arm.c
 +++ b/arch/arm/kvm/arm.c
 @@ -551,6 +551,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct 
 kvm_run *run)
   preempt_enable();
   kvm_timer_sync_hwstate(vcpu);
   kvm_vgic_sync_hwstate(vcpu);
 + kvm_pmu_sync_hwstate(vcpu);
   continue;
   }
  
 @@ -595,6 +596,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct 
 kvm_run *run)
  
   kvm_timer_sync_hwstate(vcpu);
   kvm_vgic_sync_hwstate(vcpu);
 + kvm_pmu_sync_hwstate(vcpu);
  
   ret = handle_exit(vcpu, run, ret);
   }
 diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
 index 6985809..5bcf27b 100644
 --- a/include/kvm/arm_pmu.h
 +++ b/include/kvm/arm_pmu.h
 @@ -45,6 +45,7 @@ struct kvm_pmu {
  };
  
  #ifdef CONFIG_KVM_ARM_PMU
 +void kvm_pmu_sync_hwstate(struct kvm_vcpu *vcpu);
  void kvm_pmu_vcpu_reset(struct kvm_vcpu *vcpu);
  void kvm_pmu_set_counter_value(struct kvm_vcpu *vcpu, unsigned long 
 select_idx,
  unsigned long val);
 @@ -59,6 +60,7 @@ void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, 
 unsigned long data,
   unsigned long select_idx);
  void kvm_pmu_init(struct kvm_vcpu *vcpu);
  #else
 +void kvm_pmu_sync_hwstate(struct kvm_vcpu *vcpu) {}
  static inline void kvm_pmu_vcpu_reset(struct kvm_vcpu *vcpu) {}
  void kvm_pmu_set_counter_value(struct kvm_vcpu *vcpu, unsigned long 
 select_idx,
  unsigned long val) {}
 diff --git a/virt/kvm/arm/pmu.c b/virt/kvm/arm/pmu.c
 index e655426..f957b85 100644
 --- a/virt/kvm/arm/pmu.c
 +++ b/virt/kvm/arm/pmu.c
 @@ -20,6 +20,7 @@
  #include linux/kvm_host.h
  #include linux/perf_event.h
  #include kvm/arm_pmu.h
 +#include kvm/arm_vgic.h
  
  /* PMU HW events mapping. */
  static struct kvm_pmu_hw_event_map {
 @@ -81,6 +82,23 @@ static void kvm_pmu_stop_counter(struct kvm_vcpu *vcpu,
  }
  
  /**
 + * kvm_pmu_sync_hwstate - sync pmu state for cpu
 + * @vcpu: The vcpu pointer
 + *
 + * Inject virtual PMU IRQ if IRQ is pending for this cpu.
 + */
 +void kvm_pmu_sync_hwstate(struct kvm_vcpu *vcpu)
 +{
 + struct kvm_pmu *pmu = vcpu-arch.pmu;
 +
 + if (pmu-irq_pending) {
 + kvm_vgic_inject_irq(vcpu-kvm, vcpu-vcpu_id, pmu-irq_num, 1);

don't you need to check if irq_num is set all these places where you use
it, somehow?

 + pmu-irq_pending = 0;
 + return;
 + }
 +}

I'm not sure I understand why this function is needed at this point in
the first place.  Why don't we just inject the interrupt when the
overflow happens?

I'm also not completely clear on the relationship between when the
physical counter overflows and when the virtual one does - do we always
keep that in sync somehow?  (this may relate to one of my questions
in one of the previous patches).


 +
 +/**
   * kvm_pmu_vcpu_reset - reset pmu state for cpu
   * @vcpu: The vcpu pointer
   *
 @@ -96,6 +114,37 @@ void kvm_pmu_vcpu_reset(struct kvm_vcpu *vcpu)
   pmu-irq_pending = false;
  }
  
 +static void kvm_pum_trigger_pmi(struct irq_work *irq_work)
 +{
 + struct kvm_pmu *pmu = container_of(irq_work, struct kvm_pmu, irq_work);
 + struct kvm_vcpu *vcpu = container_of(pmu, struct kvm_vcpu, arch.pmu);
 +
 + kvm_vgic_inject_irq(vcpu-kvm, vcpu-vcpu_id, pmu-irq_num, 1);
 +}
 +
 +/**
 + * When perf event overflows, if vcpu doesn't run, call irq_work_queue to 
 wake
 + * up vcpu. Otherwise call kvm_vgic_inject_irq to inject the interrupt.
 + */
 +static void kvm_pmu_perf_overflow(struct perf_event *perf_event,
 +   struct perf_sample_data *data,
 +   struct pt_regs *regs)
 +{
 + struct kvm_pmc *pmc = perf_event-overflow_handler_context;
 + struct kvm_vcpu *vcpu = pmc-vcpu;
 + struct kvm_pmu *pmu = vcpu-arch.pmu;
 +
 + if (pmc-interrupt == true) {
 + __set_bit(pmc-idx, (unsigned long *)pmu-overflow_status);

why not declare overflow_status as an unsigned long instead?

 + pmu-irq_pending = 1;
 + if (vcpu-mode != IN_GUEST_MODE)
 + irq_work_queue(pmu-irq_work);

why 

Re: [PATCH 18/18] KVM: ARM64: Add KVM_CAP_ARM_PMU and KVM_ARM_PMU_SET_IRQ

2015-07-17 Thread Christoffer Dall
On Mon, Jul 06, 2015 at 10:17:48AM +0800, shannon.z...@linaro.org wrote:
 From: Shannon Zhao shannon.z...@linaro.org
 
 Add KVM_CAP_ARM_PMU for userspace to check whether KVM supports PMU. Add
 KVM_ARM_PMU_SET_IRQ for userspace to set PMU IRQ number.
 
 Signed-off-by: Shannon Zhao shannon.z...@linaro.org
 ---
  arch/arm/kvm/arm.c   | 8 
  include/kvm/arm_pmu.h| 5 +
  include/uapi/linux/kvm.h | 4 
  virt/kvm/arm/pmu.c   | 9 +
  4 files changed, 26 insertions(+)
 
 diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
 index 41eb063..350866e 100644
 --- a/arch/arm/kvm/arm.c
 +++ b/arch/arm/kvm/arm.c
 @@ -182,6 +182,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long 
 ext)
   case KVM_CAP_ARM_PSCI_0_2:
   case KVM_CAP_READONLY_MEM:
   case KVM_CAP_MP_STATE:
 + case KVM_CAP_ARM_PMU:
   r = 1;
   break;
   case KVM_CAP_COALESCED_MMIO:
 @@ -816,6 +817,13 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
   return -E2BIG;
   return kvm_arm_copy_reg_indices(vcpu, user_list-reg);
   }
 + case KVM_ARM_PMU_SET_IRQ: {
 + uint32_t irq;
 +
 + if (copy_from_user(irq, argp, sizeof(irq)))
 + return -EFAULT;
 + return kvm_pmu_set_irq_num(vcpu, irq);
 + }
   default:
   return -EINVAL;
   }
 diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
 index 5bcf27b..1a93f53 100644
 --- a/include/kvm/arm_pmu.h
 +++ b/include/kvm/arm_pmu.h
 @@ -58,6 +58,7 @@ void kvm_pmu_enable_interrupt(struct kvm_vcpu *vcpu, 
 unsigned long val);
  void kvm_pmu_software_increment(struct kvm_vcpu *vcpu, unsigned long val);
  void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, unsigned long 
 data,
   unsigned long select_idx);
 +int kvm_pmu_set_irq_num(struct kvm_vcpu *vcpu, u32 irq);
  void kvm_pmu_init(struct kvm_vcpu *vcpu);
  #else
  void kvm_pmu_sync_hwstate(struct kvm_vcpu *vcpu) {}
 @@ -76,6 +77,10 @@ void kvm_pmu_enable_interrupt(struct kvm_vcpu *vcpu, 
 unsigned long val) {}
  void kvm_pmu_software_increment(struct kvm_vcpu *vcpu, unsigned long val) {}
  void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, unsigned long 
 data,
   unsigned long select_idx) {}
 +int kvm_pmu_set_irq_num(struct kvm_vcpu *vcpu, u32 irq)
 +{
 + return -ENXIO;
 +}
  static inline void kvm_pmu_init(struct kvm_vcpu *vcpu) {}
  #endif
  
 diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
 index 716ad4a..90f5e73 100644
 --- a/include/uapi/linux/kvm.h
 +++ b/include/uapi/linux/kvm.h
 @@ -817,6 +817,7 @@ struct kvm_ppc_smmu_info {
  #define KVM_CAP_DISABLE_QUIRKS 116
  #define KVM_CAP_X86_SMM 117
  #define KVM_CAP_MULTI_ADDRESS_SPACE 118
 +#define KVM_CAP_ARM_PMU 119
  
  #ifdef KVM_CAP_IRQ_ROUTING
  
 @@ -1205,6 +1206,9 @@ struct kvm_s390_ucas_mapping {
  /* Available with KVM_CAP_X86_SMM */
  #define KVM_SMI   _IO(KVMIO,   0xb7)
  
 +/* Available with KVM_CAP_ARM_PMU */
 +#define KVM_ARM_PMU_SET_IRQ_IOW(KVMIO, 0xb8, __u32)
 +

does this really warrant a completely new ioctl?  Perhaps a new kvm
device that you create with a PMU would be better, in that way you could
choose whether you want the PMU for the guest or not.

Alternatively, we have some room to spare in the features array of
KVM_ARM_VCPU_INIT.

Alternatively to the alternative, does the IRQ number appear in any
register somewhere?  If so, we could use the ONE_REG interface to set
the irq number.

In any case, the new ABI should be documented in
Documentation/virtual/kvm/api.txt.


  #define KVM_DEV_ASSIGN_ENABLE_IOMMU  (1  0)
  #define KVM_DEV_ASSIGN_PCI_2_3   (1  1)
  #define KVM_DEV_ASSIGN_MASK_INTX (1  2)
 diff --git a/virt/kvm/arm/pmu.c b/virt/kvm/arm/pmu.c
 index f957b85..57585e1 100644
 --- a/virt/kvm/arm/pmu.c
 +++ b/virt/kvm/arm/pmu.c
 @@ -381,6 +381,15 @@ void kvm_pmu_set_counter_event_type(struct kvm_vcpu 
 *vcpu, unsigned long data,
   pmc-perf_event = event;
  }
  
 +int kvm_pmu_set_irq_num(struct kvm_vcpu *vcpu, u32 irq)
 +{
 + struct kvm_pmu *pmu = vcpu-arch.pmu;
 +
 + kvm_info(kvm_arm_set_pmu_irq: irq: %u\n, irq);

kvm_debug instead?

 + pmu-irq_num = irq;
 + return 0;
 +}
 +
  /**
   * kvm_pmu_init - Initialize global PMU state for per vcpu
   * @vcpu: The vcpu pointer
 -- 
 2.1.0
 

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


Re: [PATCH 02/18] KVM: ARM64: Add initial support for PMU

2015-07-17 Thread Shannon Zhao


On 2015/7/17 2:25, Christoffer Dall wrote:
 On Mon, Jul 06, 2015 at 10:17:32AM +0800, shannon.z...@linaro.org wrote:
 From: Shannon Zhao shannon.z...@linaro.org

 Here we plan to support virtual PMU for guest by full software
 emulation, so define some basic structs and functions preparing for
 futher steps. Define struct kvm_pmc for performance monitor counter and
 struct kvm_pmu for performance monitor unit for each vcpu. According to
 ARMv8 spec, the PMU contains at most 32(ARMV8_MAX_COUNTERS) counters.
 Initialize PMU for each vcpu when kvm initialize vcpus, while reset PMU
 when kvm reset vcpus.
 Since this only supports ARM64 (or PMUv3), add a separate config symbol
 for it.

 Signed-off-by: Shannon Zhao shannon.z...@linaro.org
 ---
  arch/arm/kvm/arm.c|  4 +++
  arch/arm64/include/asm/kvm_host.h |  2 ++
  arch/arm64/include/asm/pmu.h  |  2 ++
  arch/arm64/kvm/Kconfig|  7 +
  arch/arm64/kvm/Makefile   |  1 +
  arch/arm64/kvm/reset.c|  3 +++
  include/kvm/arm_pmu.h | 54 
 ++
  virt/kvm/arm/pmu.c| 55 
 +++
  8 files changed, 128 insertions(+)
  create mode 100644 include/kvm/arm_pmu.h
  create mode 100644 virt/kvm/arm/pmu.c

 diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
 index bc738d2..4e82625 100644
 --- a/arch/arm/kvm/arm.c
 +++ b/arch/arm/kvm/arm.c
 @@ -28,6 +28,7 @@
  #include linux/sched.h
  #include linux/kvm.h
  #include trace/events/kvm.h
 +#include kvm/arm_pmu.h
  
  #define CREATE_TRACE_POINTS
  #include trace.h
 @@ -278,6 +279,9 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
  /* Set up the timer */
  kvm_timer_vcpu_init(vcpu);
  
 +/* Set up the PMU */
 +kvm_pmu_init(vcpu);
 +
  return 0;
  }
  
 diff --git a/arch/arm64/include/asm/kvm_host.h 
 b/arch/arm64/include/asm/kvm_host.h
 index 2709db2..3c88873 100644
 --- a/arch/arm64/include/asm/kvm_host.h
 +++ b/arch/arm64/include/asm/kvm_host.h
 @@ -42,6 +42,7 @@
  
  #include kvm/arm_vgic.h
  #include kvm/arm_arch_timer.h
 +#include kvm/arm_pmu.h
  
  #define KVM_VCPU_MAX_FEATURES 3
  
 @@ -116,6 +117,7 @@ struct kvm_vcpu_arch {
  /* VGIC state */
  struct vgic_cpu vgic_cpu;
  struct arch_timer_cpu timer_cpu;
 +struct kvm_pmu pmu;
  
  /*
   * Anything that is not used directly from assembly code goes
 diff --git a/arch/arm64/include/asm/pmu.h b/arch/arm64/include/asm/pmu.h
 index b9f394a..95681e6 100644
 --- a/arch/arm64/include/asm/pmu.h
 +++ b/arch/arm64/include/asm/pmu.h
 @@ -19,6 +19,8 @@
  #ifndef __ASM_PMU_H
  #define __ASM_PMU_H
  
 +#include linux/perf_event.h
 +
  #define ARMV8_MAX_COUNTERS  32
  #define ARMV8_COUNTER_MASK  (ARMV8_MAX_COUNTERS - 1)
  
 diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
 index bfffe8f..eae3a1b 100644
 --- a/arch/arm64/kvm/Kconfig
 +++ b/arch/arm64/kvm/Kconfig
 @@ -31,6 +31,7 @@ config KVM
  select KVM_VFIO
  select HAVE_KVM_EVENTFD
  select HAVE_KVM_IRQFD
 +select KVM_ARM_PMU
  ---help---
Support hosting virtualized guest machines.
  
 @@ -52,4 +53,10 @@ config KVM_ARM_MAX_VCPUS
large, so only choose a reasonable number that you expect to
actually use.
  
 +config KVM_ARM_PMU
 +bool
 +depends on KVM_ARM_HOST
 +---help---
 +  Adds support for the Performance Monitoring in virtual machines.
 
 Adds support for a virtual Performance Monitoring Unit (PMU) in virtual
 machines.
 
 +
  endif # VIRTUALIZATION
 diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
 index f90f4aa..78db4ee 100644
 --- a/arch/arm64/kvm/Makefile
 +++ b/arch/arm64/kvm/Makefile
 @@ -27,3 +27,4 @@ kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic-v3.o
  kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic-v3-emul.o
  kvm-$(CONFIG_KVM_ARM_HOST) += vgic-v3-switch.o
  kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/arch_timer.o
 +kvm-$(CONFIG_KVM_ARM_PMU) += $(KVM)/arm/pmu.o
 diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
 index 0b43265..ee2c2e9 100644
 --- a/arch/arm64/kvm/reset.c
 +++ b/arch/arm64/kvm/reset.c
 @@ -107,5 +107,8 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
  /* Reset timer */
  kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);
  
 +/* Reset PMU */
 +kvm_pmu_vcpu_reset(vcpu);
 +
  return 0;
  }
 diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
 new file mode 100644
 index 000..27d14ca
 --- /dev/null
 +++ b/include/kvm/arm_pmu.h
 @@ -0,0 +1,54 @@
 +/*
 + * Copyright (C) 2015 Linaro Ltd.
 + * Author: Shannon Zhao shannon.z...@linaro.org
 + *
 + * This program is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License version 2 as
 + * published by the Free Software Foundation.
 + *
 + * This program is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS 

Re: [PATCH 04/18] KVM: ARM64: Add reset and access handlers for PMCR_EL0 register

2015-07-17 Thread Shannon Zhao


On 2015/7/17 3:55, Christoffer Dall wrote:
 On Mon, Jul 06, 2015 at 10:17:34AM +0800, shannon.z...@linaro.org wrote:
 From: Shannon Zhao shannon.z...@linaro.org

 Add reset handler which gets host value of PMCR_EL0 and make writable
 bits architecturally UNKNOWN. Add access handler which emulates
 writing and reading PMCR_EL0 register.

 Signed-off-by: Shannon Zhao shannon.z...@linaro.org
 ---
  arch/arm64/kvm/sys_regs.c | 41 -
  1 file changed, 40 insertions(+), 1 deletion(-)

 diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
 index c370b40..152ee17 100644
 --- a/arch/arm64/kvm/sys_regs.c
 +++ b/arch/arm64/kvm/sys_regs.c
 @@ -33,6 +33,7 @@
  #include asm/kvm_emulate.h
  #include asm/kvm_host.h
  #include asm/kvm_mmu.h
 +#include asm/pmu.h
  
  #include trace/events/kvm.h
  
 @@ -236,6 +237,44 @@ static void reset_mpidr(struct kvm_vcpu *vcpu, const 
 struct sys_reg_desc *r)
  vcpu_sys_reg(vcpu, MPIDR_EL1) = (1ULL  31) | mpidr;
  }
  
 +static void reset_pmcr_el0(struct kvm_vcpu *vcpu, const struct sys_reg_desc 
 *r)
 +{
 +u32 pmcr;
 +
 +asm volatile(mrs %0, pmcr_el0\n : =r (pmcr));
 +vcpu_sys_reg(vcpu, PMCR_EL0) = (pmcr  ~ARMV8_PMCR_MASK)
 +   | (ARMV8_PMCR_MASK  0xdecafbad);
 
 You could add a comment that this resets to UNKNOWN as to not make
 people confused about the pseudo-random hex value.
 
Ok.

 Have we thought about whether we want to tell the guest that it has the
 same PMU as available on the real hardware, or does the virtualization
 layer suggest to us that we should adjust this somehow?
 
I guess here the number of PMU counters is what we can adjust, right?
Are we worried about that the host will run out of counters when guest
and host register lots of events?
The PMU of cortex-a57 has 6 counters. IIUC, if one of the guest vcpu
process registers 6 events and some host process register 6 events too,
these events will be monitored in real hardware PMU counter when the
related process runs on the cpu. And when other processes are scheduled
to run, it will switch the contexts of PMU counters.

 
 +}
 +
 +/* PMCR_EL0 accessor. Only called as long as MDCR_EL2.TPMCR is set. */
 +static bool access_pmcr(struct kvm_vcpu *vcpu,
 +const struct sys_reg_params *p,
 +const struct sys_reg_desc *r)
 +{
 +unsigned long val;
 +
 +if (p-is_write) {
 +/* Only update writeable bits of PMCR */
 +if (!p-is_aarch32)
 +val = vcpu_sys_reg(vcpu, r-reg);
 +else
 +val = vcpu_cp15(vcpu, r-reg);
 
 don't you need to add this function as the handler in the cp15_regs
 array as well?
 
Sorry, I'm not very clear about this. Will look at the codes and
understand the use of cp15_regs.

 +val = ~ARMV8_PMCR_MASK;
 +val |= *vcpu_reg(vcpu, p-Rt)  ARMV8_PMCR_MASK;
 +if (!p-is_aarch32)
 +vcpu_sys_reg(vcpu, r-reg) = val;
 +else
 +vcpu_cp15(vcpu, r-reg) = val;
 +} else {
 +if (!p-is_aarch32)
 +*vcpu_reg(vcpu, p-Rt) = vcpu_sys_reg(vcpu, r-reg);
 +else
 +*vcpu_reg(vcpu, p-Rt) = vcpu_cp15(vcpu, r-reg);
 +}
 +
 +return true;
 +}
 +
  /* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go 
 */
  #define DBG_BCR_BVR_WCR_WVR_EL1(n)  \
  /* DBGBVRn_EL1 */   \
 @@ -427,7 +466,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
  
  /* PMCR_EL0 */
  { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b000),
 -  trap_raz_wi },
 +  access_pmcr, reset_pmcr_el0, PMCR_EL0, },
  /* PMCNTENSET_EL0 */
  { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b001),
trap_raz_wi },
 -- 
 2.1.0

 Thanks,
 -Christoffer
 

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


Re: [PATCH v2] virt: IRQ bypass manager

2015-07-17 Thread Christian Borntraeger
Am 16.07.2015 um 23:26 schrieb Alex Williamson:
 When a physical I/O device is assigned to a virtual machine through
 facilities like VFIO and KVM, the interrupt for the device generally
 bounces through the host system before being injected into the VM.
 However, hardware technologies exist that often allow the host to be
 bypassed for some of these scenarios.  Intel Posted Interrupts allow
 the specified physical edge interrupts to be directly injected into a
 guest when delivered to a physical processor while the vCPU is
 running.  ARM IRQ Forwarding allows forwarded physical interrupts to
 be directly deactivated by the guest.
 
 The IRQ bypass manager here is meant to provide the shim to connect
 interrupt producers, generally the host physical device driver, with
 interrupt consumers, generally the hypervisor, in order to configure
 these bypass mechanism.  To do this, we base the connection on a
 shared, opaque token.  For KVM-VFIO this is expected to be an
 eventfd_ctx since this is the connection we already use to connect an
 eventfd to an irqfd on the in-kernel path.  When a producer and
 consumer with matching tokens is found, callbacks via both registered
 participants allow the bypass facilities to be automatically enabled.
 
 Signed-off-by: Alex Williamson alex.william...@redhat.com
 ---
 
 I'm not sure if we're settled on everything, I think Eric is out of
 the office and we haven't really resolved the opaque data element.
 I think it has problems because it assumes which side gets to provide
 the data and implies that the other side knows that the data is
 compatible.  We also don't need to pass it as a callback argument if
 we put it on the consumer/produce struct and consider it public.
 However, I'm posting this to record the current state of this code
 and to make sure I'm not the bottleneck.



Yi Min,

can you have a look if the IRQ passthrough that the pci virtualization
on s390 has would work with this? As far as I can tell, this looks like
we can implement whatever we want in kvm/s390 and this infrastructure
just connects vfio and kvm without assuming anything about the details
but lets double check.





 
 v2 Makes the rest of the changes suggested by Eric, various comment
 fixes, error paths for the add callbacks, and adds a MAINTAINERS
 entry for virt/lib.  Thanks,
 
 Alex
 
  MAINTAINERS   |7 +
  include/linux/irqbypass.h |   90 
  virt/lib/Kconfig  |2 
  virt/lib/Makefile |1 
  virt/lib/irqbypass.c  |  260 
 +
  5 files changed, 360 insertions(+)
  create mode 100644 include/linux/irqbypass.h
  create mode 100644 virt/lib/Kconfig
  create mode 100644 virt/lib/Makefile
  create mode 100644 virt/lib/irqbypass.c
 
 diff --git a/MAINTAINERS b/MAINTAINERS
 index d8afd29..8e728cb 100644
 --- a/MAINTAINERS
 +++ b/MAINTAINERS
 @@ -10613,6 +10613,13 @@ L:   net...@vger.kernel.org
  S:   Maintained
  F:   drivers/net/ethernet/via/via-velocity.*
 
 +VIRT LIB
 +M:   Alex Williamson alex.william...@redhat.com
 +M:   Paolo Bonzini pbonz...@redhat.com
 +L:   kvm@vger.kernel.org
 +S:   Supported
 +F:   virt/lib/
 +
  VIVID VIRTUAL VIDEO DRIVER
  M:   Hans Verkuil hverk...@xs4all.nl
  L:   linux-me...@vger.kernel.org
 diff --git a/include/linux/irqbypass.h b/include/linux/irqbypass.h
 new file mode 100644
 index 000..fde7b64
 --- /dev/null
 +++ b/include/linux/irqbypass.h
 @@ -0,0 +1,90 @@
 +/*
 + * IRQ offload/bypass manager
 + *
 + * Copyright (C) 2015 Red Hat, Inc.
 + * Copyright (c) 2015 Linaro Ltd.
 + *
 + * This program is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License version 2 as
 + * published by the Free Software Foundation.
 + */
 +#ifndef IRQBYPASS_H
 +#define IRQBYPASS_H
 +
 +#include linux/list.h
 +
 +struct irq_bypass_consumer;
 +
 +/*
 + * Theory of operation
 + *
 + * The IRQ bypass manager is a simple set of lists and callbacks that allows
 + * IRQ producers (ex. physical interrupt sources) to be matched to IRQ
 + * consumers (ex. virtualization hardware that allows IRQ bypass or offload)
 + * via a shared token (ex. eventfd_ctx).  Producers and consumers register
 + * independently.  When a token match is found, the optional @stop callback
 + * will be called for each participant.  The pair will then be connected via
 + * the @add_* callbacks, and finally the optional @start callback will allow
 + * any final coordination.  When either participant is unregistered, the
 + * process is repeated using the @del_* callbacks in place of the @add_*
 + * callbacks.  Match tokens must be unique per producer/consumer, 1:N 
 pairings
 + * are not supported.
 + */
 +
 +/**
 + * struct irq_bypass_producer - IRQ bypass producer definition
 + * @node: IRQ bypass manager private list management
 + * @token: opaque token to match between producer and consumer
 + * @irq: Linux IRQ number for the producer device
 + * 

RE: [PATCH v2 3/7] KVM: irqchip: convey devid to kvm_set_msi

2015-07-17 Thread Pavel Fedin
 -Original Message-
 From: kvm-ow...@vger.kernel.org [mailto:kvm-ow...@vger.kernel.org] On Behalf 
 Of Eric Auger
 Sent: Thursday, July 09, 2015 11:22 AM
 To: eric.au...@st.com; eric.au...@linaro.org; 
 linux-arm-ker...@lists.infradead.org;
 marc.zyng...@arm.com; christoffer.d...@linaro.org; 
 kvm...@lists.cs.columbia.edu;
 kvm@vger.kernel.org
 Cc: patc...@linaro.org; andre.przyw...@arm.com; p.fe...@samsung.com; 
 pbonz...@redhat.com
 Subject: [PATCH v2 3/7] KVM: irqchip: convey devid to kvm_set_msi
 
 on ARM, a devid field is populated in kvm_msi struct in case the
 flag is set to KVM_MSI_VALID_DEVID. Let's populate the corresponding
 kvm_kernel_irq_routing_entry devid field and set the msi type to
 KVM_IRQ_ROUTING_EXTENDED_MSI.
 
 Signed-off-by: Eric Auger eric.au...@linaro.org
 ---
  virt/kvm/irqchip.c | 10 +-
  1 file changed, 9 insertions(+), 1 deletion(-)
 
 diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c
 index 21c1424..e678f8a 100644
 --- a/virt/kvm/irqchip.c
 +++ b/virt/kvm/irqchip.c
 @@ -72,9 +72,17 @@ int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi 
 *msi)
  {
   struct kvm_kernel_irq_routing_entry route;
 
 - if (!irqchip_in_kernel(kvm) || msi-flags != 0)
 + if (!irqchip_in_kernel(kvm))
   return -EINVAL;
 
 + if (msi-flags  KVM_MSI_VALID_DEVID) {
 + route.devid = msi-devid;
 + route.type = KVM_IRQ_ROUTING_EXTENDED_MSI;
 + } else if (!msi-flags)
 + return -EINVAL;

 Did you mean if (msg-flags) here (inverted condition)?

 +
 + /* historically the route.type was not set */
 +
   route.msi.address_lo = msi-address_lo;
   route.msi.address_hi = msi-address_hi;
   route.msi.data = msi-data;
 --
 1.9.1

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

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


Re: [PATCH 03/18] KVM: ARM64: Add offset defines for PMU registers

2015-07-17 Thread Shannon Zhao


On 2015/7/17 2:45, Christoffer Dall wrote:
 On Mon, Jul 06, 2015 at 10:17:33AM +0800, shannon.z...@linaro.org wrote:
 From: Shannon Zhao shannon.z...@linaro.org

 We are about to trap and emulate acccesses to each PMU register
 individually. This adds the context offsets for the AArch64 PMU
 registers and their AArch32 counterparts.

 Signed-off-by: Shannon Zhao shannon.z...@linaro.org
 ---
  arch/arm64/include/asm/kvm_asm.h | 59 
 +++-
  1 file changed, 52 insertions(+), 7 deletions(-)

 diff --git a/arch/arm64/include/asm/kvm_asm.h 
 b/arch/arm64/include/asm/kvm_asm.h
 index 3c5fe68..21b5d3b 100644
 --- a/arch/arm64/include/asm/kvm_asm.h
 +++ b/arch/arm64/include/asm/kvm_asm.h
 @@ -56,14 +56,36 @@
  #define DBGWVR15_EL186
  #define MDCCINT_EL1 87  /* Monitor Debug Comms Channel Interrupt Enable 
 Reg */
  
 +/* Performance Monitors Registers */
 +#define PMCR_EL088  /* Control Register */
 +#define PMOVSSET_EL089  /* Overflow Flag Status Set Register */
 +#define PMOVSCLR_EL090  /* Overflow Flag Status Clear Register 
 */
 +#define PMCCNTR_EL0 91  /* Cycle Counter Register */
 +#define PMSELR_EL0  92  /* Event Counter Selection Register */
 +#define PMCEID0_EL0 93  /* Common Event Identification Register 0 */
 +#define PMCEID1_EL0 94  /* Common Event Identification Register 1 */
 +#define PMEVCNTR0_EL0   95  /* Event Counter Register (0-30) */
 
 why do we need these when we trap-and-emulate and we have the kvm_pmc
 structs? 
This just makes the guest work when accessing these registers.

 Is that because the kvm_pmc structs are only used when we
 actually have an active counter running and registered with perf?
 

Right, the kvm_pmc structs are used to store the status of perf evnets,
like the event type, count number of this perf event.

On the other hand, the kernel perf codes will not directly access to the
PMEVCNTRx_EL0 and PMEVTYPERx_EL0 registers. It will firstly write the
index of select counter to PMSELR_EL0 and access to PMXEVCNTR_EL0 or
PMXEVTYPER_EL0. Then this is architecturally mapped to PMEVCNTRx_EL0 and
PMEVTYPERx_EL0.

 +#define PMEVTYPER0_EL0  96  /* Event Type Register (0-30) */
 +#define PMEVCNTR30_EL0  155
 +#define PMEVTYPER30_EL0 156
 +#define PMXEVCNTR_EL0   157 /* Selected Event Count Register */
 +#define PMXEVTYPER_EL0  158 /* Selected Event Type Register */
 +#define PMCNTENSET_EL0  159 /* Count Enable Set Register */
 +#define PMCNTENCLR_EL0  160 /* Count Enable Clear Register */
 +#define PMINTENSET_EL1  161 /* Interrupt Enable Set Register */
 +#define PMINTENCLR_EL1  162 /* Interrupt Enable Clear Register */
 +#define PMUSERENR_EL0   163 /* User Enable Register */
 +#define PMCCFILTR_EL0   164 /* Cycle Count Filter Register */
 +#define PMSWINC_EL0 165 /* Software Increment Register */
 +
  /* 32bit specific registers. Keep them at the end of the range */
 -#define DACR32_EL2  88  /* Domain Access Control Register */
 -#define IFSR32_EL2  89  /* Instruction Fault Status Register */
 -#define FPEXC32_EL2 90  /* Floating-Point Exception Control 
 Register */
 -#define DBGVCR32_EL291  /* Debug Vector Catch Register */
 -#define TEECR32_EL1 92  /* ThumbEE Configuration Register */
 -#define TEEHBR32_EL193  /* ThumbEE Handler Base Register */
 -#define NR_SYS_REGS 94
 +#define DACR32_EL2  166 /* Domain Access Control Register */
 +#define IFSR32_EL2  167 /* Instruction Fault Status Register */
 +#define FPEXC32_EL2 168 /* Floating-Point Exception Control 
 Register */
 +#define DBGVCR32_EL2169 /* Debug Vector Catch Register */
 +#define TEECR32_EL1 170 /* ThumbEE Configuration Register */
 +#define TEEHBR32_EL1171 /* ThumbEE Handler Base Register */
 +#define NR_SYS_REGS 172
  
  /* 32bit mapping */
  #define c0_MPIDR(MPIDR_EL1 * 2) /* MultiProcessor ID Register */
 @@ -85,6 +107,24 @@
  #define c6_IFAR (c6_DFAR + 1)   /* Instruction Fault Address 
 Register */
  #define c7_PAR  (PAR_EL1 * 2)   /* Physical Address Register */
  #define c7_PAR_high (c7_PAR + 1)/* PAR top 32 bits */
 +
 +/* Performance Monitors*/
 +#define c9_PMCR (PMCR_EL0 * 2)
 +#define c9_PMOVSSET (PMOVSSET_EL0 * 2)
 +#define c9_PMOVSCLR (PMOVSCLR_EL0 * 2)
 +#define c9_PMCCNTR  (PMCCNTR_EL0 * 2)
 +#define c9_PMSELR   (PMSELR_EL0 * 2)
 +#define c9_PMCEID0  (PMCEID0_EL0 * 2)
 +#define c9_PMCEID1  (PMCEID1_EL0 * 2)
 +#define c9_PMXEVCNTR(PMXEVCNTR_EL0 * 2)
 +#define c9_PMXEVTYPER   (PMXEVTYPER_EL0 * 2)
 +#define c9_PMCNTENSET   (PMCNTENSET_EL0 * 2)
 +#define c9_PMCNTENCLR   (PMCNTENCLR_EL0 * 2)
 +#define c9_PMINTENSET   (PMINTENSET_EL1 * 2)
 +#define c9_PMINTENCLR   (PMINTENCLR_EL1 * 2)
 +#define 

[PATCH 00/12] kvmtool: Improve portability

2015-07-17 Thread Andre Przywara
Hi,

this is a collection of patches to bring kvmtool closer to standards
compliance (with standards not necessarily meaning GNU only).
With all those patches applied, you can compile kvmtool with newer
C standards, with clang and against musl-libc.

The first patch was already on the list, it allows compiling with
-std=gnu99 (or gnu11, even). As this will become the new GCC default 
at some point, that sounds useful.

Patch 2-7 fix compilation with clang: some are real bugs, some are
just things that clang is pickier about. Please note that the BIOS
code for x86 still does not compile with clang. I have the gut
feeling that rewriting this is assembly would be cleaner than all
those hacks we do to make this possible in C, but I will look at this
later.

The next four patches fix compilation against musl-libc. No real bugs
here, but again improves code quality. Compiling against musl-libc
gives you really small binaries (174K for ARM, for instance).

The last patch just follows a comment in the code to remove a kludge.

Cheers,
Andre.

Andre Przywara (12):
  avoid casts when initializing structures
  qcow: fix signedness bugs
  kvm-ipc: use proper type for file descriptor
  Makefile: remove unneeded -s switch on compiling BIOS files
  ui: remove pointless double const in keymap declarations
  kvm__set_dir(): avoid variable arguments call
  util/util.c: avoid clang error on vsnprintf
  Fix call to connect()
  use poll.h instead of sys/poll.h
  check for and use C library provided strlcpy and strlcat
  avoid using predefined PAGE_SIZE
  remove KVM_CAP_MAX_VCPUS hack

 Makefile | 15 ++-
 config/feature-tests.mak | 10 ++
 disk/core.c  |  2 +-
 disk/qcow.c  | 14 +++---
 include/kvm/kvm.h|  6 +-
 include/kvm/mutex.h  |  2 +-
 include/kvm/strbuf.h |  2 ++
 include/linux/rbtree.h   |  2 +-
 kvm-ipc.c|  4 ++--
 kvm.c| 29 ++---
 main.c   |  9 -
 ui/gtk3.c|  2 +-
 ui/sdl.c |  2 +-
 util/strbuf.c|  2 ++
 util/util.c  |  1 +
 virtio/9p.c  |  2 +-
 virtio/balloon.c |  2 +-
 virtio/blk.c |  2 +-
 virtio/console.c |  2 +-
 virtio/net.c |  2 +-
 virtio/rng.c |  2 +-
 virtio/scsi.c|  2 +-
 22 files changed, 65 insertions(+), 51 deletions(-)

-- 
2.3.5

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


Re: [PATCH] arm64/kvm: Add generic v8 KVM target

2015-07-17 Thread Christoffer Dall
On Fri, Jul 03, 2015 at 11:10:09AM +0100, Marc Zyngier wrote:
 On 03/07/15 10:34, Peter Maydell wrote:
  On 3 July 2015 at 09:28, Marc Zyngier marc.zyng...@arm.com wrote:
  On 03/07/15 09:12, Peter Maydell wrote:
  I would still like to see the proponents of this patch say
  what their model is for userspace support of cross-host migration,
  if we're abandoning the model the current API envisages.
 
  I thought we had discussed this above, and don't really see this as a
  departure from the current model:
 
  - -cpu host results in GENERIC being used: VM can only be migrated
  to the exact same HW (no cross-host migration). MIDR should probably
  become RO.
  - -cpu host results in A57 (for example): VM can be migrated to a
  variety of A57 platforms, and allow for some fuzzing on the revision (or
  accept any revision).
  - -cpu a57 forces an A57 model to be emulated, always. It is always
  possible to migrate such a VM on any host.
 
  I think only the first point is new, but the last two are what we have
  (or what we should have).
  
  Right, but the implicit idea of this GENERIC patch seems to
  be that new host CPU types don't get their own KVM_ARM_TARGET_*
  constant, and are thus forever unable to do cross-host migration.
  It's not clear to me why we'd want to have new CPUs be second
  class citizens like that.
 
 I certainly don't want to see *any* CPU be a second class citizen. But
 let's face it, we're adding more and more targets that don't implement
 anything new, and just satisfy themselves with the generic implementation.
 
 I see it as an incentive to provide something useful (tables of all the
 registers with default values?) so that cross-host migration becomes a
 reality instead of the figment of our imagination (as it is now). If it
 wasn't already ABI, I'd have removed the existing targets until we have
 something meaningful to put there.

What we're doing now certainly seems silly, because we're adding kernel
patches without bringing anything to the table...

 
 Now, I also have my own doubts about cross-host migration (timers
 anyone?). But I don't see the above as a change in policy. More as a way
 to outline the fact that we currently don't have the right level of
 information/infrastructure to support it at all.
 
The one thing that I've lost track of here (sorry) is whether we're
enforcing the inability to do cross-host migration with the generic
target when this patch is merged or do we leave this up to the graces of
userspace?

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


Re: [PATCH] arm64/kvm: Add generic v8 KVM target

2015-07-17 Thread Christoffer Dall
On Fri, Jul 17, 2015 at 10:56:39AM +0100, Marc Zyngier wrote:
 On 17/07/15 10:33, Christoffer Dall wrote:
  On Fri, Jul 03, 2015 at 11:10:09AM +0100, Marc Zyngier wrote:
  On 03/07/15 10:34, Peter Maydell wrote:
  On 3 July 2015 at 09:28, Marc Zyngier marc.zyng...@arm.com wrote:
  On 03/07/15 09:12, Peter Maydell wrote:
  I would still like to see the proponents of this patch say
  what their model is for userspace support of cross-host migration,
  if we're abandoning the model the current API envisages.
 
  I thought we had discussed this above, and don't really see this as a
  departure from the current model:
 
  - -cpu host results in GENERIC being used: VM can only be migrated
  to the exact same HW (no cross-host migration). MIDR should probably
  become RO.
  - -cpu host results in A57 (for example): VM can be migrated to a
  variety of A57 platforms, and allow for some fuzzing on the revision (or
  accept any revision).
  - -cpu a57 forces an A57 model to be emulated, always. It is always
  possible to migrate such a VM on any host.
 
  I think only the first point is new, but the last two are what we have
  (or what we should have).
 
  Right, but the implicit idea of this GENERIC patch seems to
  be that new host CPU types don't get their own KVM_ARM_TARGET_*
  constant, and are thus forever unable to do cross-host migration.
  It's not clear to me why we'd want to have new CPUs be second
  class citizens like that.
 
  I certainly don't want to see *any* CPU be a second class citizen. But
  let's face it, we're adding more and more targets that don't implement
  anything new, and just satisfy themselves with the generic implementation.
 
  I see it as an incentive to provide something useful (tables of all the
  registers with default values?) so that cross-host migration becomes a
  reality instead of the figment of our imagination (as it is now). If it
  wasn't already ABI, I'd have removed the existing targets until we have
  something meaningful to put there.
  
  What we're doing now certainly seems silly, because we're adding kernel
  patches without bringing anything to the table...
  
 
  Now, I also have my own doubts about cross-host migration (timers
  anyone?). But I don't see the above as a change in policy. More as a way
  to outline the fact that we currently don't have the right level of
  information/infrastructure to support it at all.
 
  The one thing that I've lost track of here (sorry) is whether we're
  enforcing the inability to do cross-host migration with the generic
  target when this patch is merged or do we leave this up to the graces of
  userspace?
 
 The jury is still out on that one.
 
 I was initially not going to enforce anything (after all, this isn't
 that different from the whole CNTVOFF story where we allow userspace to
 shoot itself in the foot), but I'm equally happy to make MIDR_EL1
 read-only if we're creating a generic guest...
 
Looking at the code, midr_el1 is already an invariant register, so isn't
this automagically enforced already?

In that case, I'm fine with merging this patch.

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


Re: [PATCH v4 0/2] arm/arm64: KVM: Optimize arm64 fp/simd, saves 30-50% on exits

2015-07-17 Thread Christoffer Dall
On Thu, Jul 16, 2015 at 02:29:36PM -0700, Mario Smarduch wrote:
 Currently we save/restore fp/simd on each exit. The first patch optimizes 
 arm64
 save/restore, we only do so on Guest access. hackbench and several lmbench
 tests show anywhere from 30% to 50% of exits don't context switch the vfp/simd
 registers.
 
 For second patch 32-bit handler is updated to keep exit handling consistent
 with 64-bit code.
 

For the series:

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


Re: [PATCH 02/18] KVM: ARM64: Add initial support for PMU

2015-07-17 Thread Christoffer Dall
On Fri, Jul 17, 2015 at 04:13:35PM +0800, Shannon Zhao wrote:
 
 
 On 2015/7/17 2:25, Christoffer Dall wrote:
  On Mon, Jul 06, 2015 at 10:17:32AM +0800, shannon.z...@linaro.org wrote:
  From: Shannon Zhao shannon.z...@linaro.org
 
  Here we plan to support virtual PMU for guest by full software
  emulation, so define some basic structs and functions preparing for
  futher steps. Define struct kvm_pmc for performance monitor counter and
  struct kvm_pmu for performance monitor unit for each vcpu. According to
  ARMv8 spec, the PMU contains at most 32(ARMV8_MAX_COUNTERS) counters.
  Initialize PMU for each vcpu when kvm initialize vcpus, while reset PMU
  when kvm reset vcpus.
  Since this only supports ARM64 (or PMUv3), add a separate config symbol
  for it.
 
  Signed-off-by: Shannon Zhao shannon.z...@linaro.org
  ---
   arch/arm/kvm/arm.c|  4 +++
   arch/arm64/include/asm/kvm_host.h |  2 ++
   arch/arm64/include/asm/pmu.h  |  2 ++
   arch/arm64/kvm/Kconfig|  7 +
   arch/arm64/kvm/Makefile   |  1 +
   arch/arm64/kvm/reset.c|  3 +++
   include/kvm/arm_pmu.h | 54 
  ++
   virt/kvm/arm/pmu.c| 55 
  +++
   8 files changed, 128 insertions(+)
   create mode 100644 include/kvm/arm_pmu.h
   create mode 100644 virt/kvm/arm/pmu.c
 
  diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
  index bc738d2..4e82625 100644
  --- a/arch/arm/kvm/arm.c
  +++ b/arch/arm/kvm/arm.c
  @@ -28,6 +28,7 @@
   #include linux/sched.h
   #include linux/kvm.h
   #include trace/events/kvm.h
  +#include kvm/arm_pmu.h
   
   #define CREATE_TRACE_POINTS
   #include trace.h
  @@ -278,6 +279,9 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
 /* Set up the timer */
 kvm_timer_vcpu_init(vcpu);
   
  +  /* Set up the PMU */
  +  kvm_pmu_init(vcpu);
  +
 return 0;
   }
   
  diff --git a/arch/arm64/include/asm/kvm_host.h 
  b/arch/arm64/include/asm/kvm_host.h
  index 2709db2..3c88873 100644
  --- a/arch/arm64/include/asm/kvm_host.h
  +++ b/arch/arm64/include/asm/kvm_host.h
  @@ -42,6 +42,7 @@
   
   #include kvm/arm_vgic.h
   #include kvm/arm_arch_timer.h
  +#include kvm/arm_pmu.h
   
   #define KVM_VCPU_MAX_FEATURES 3
   
  @@ -116,6 +117,7 @@ struct kvm_vcpu_arch {
 /* VGIC state */
 struct vgic_cpu vgic_cpu;
 struct arch_timer_cpu timer_cpu;
  +  struct kvm_pmu pmu;
   
 /*
  * Anything that is not used directly from assembly code goes
  diff --git a/arch/arm64/include/asm/pmu.h b/arch/arm64/include/asm/pmu.h
  index b9f394a..95681e6 100644
  --- a/arch/arm64/include/asm/pmu.h
  +++ b/arch/arm64/include/asm/pmu.h
  @@ -19,6 +19,8 @@
   #ifndef __ASM_PMU_H
   #define __ASM_PMU_H
   
  +#include linux/perf_event.h
  +
   #define ARMV8_MAX_COUNTERS  32
   #define ARMV8_COUNTER_MASK  (ARMV8_MAX_COUNTERS - 1)
   
  diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
  index bfffe8f..eae3a1b 100644
  --- a/arch/arm64/kvm/Kconfig
  +++ b/arch/arm64/kvm/Kconfig
  @@ -31,6 +31,7 @@ config KVM
 select KVM_VFIO
 select HAVE_KVM_EVENTFD
 select HAVE_KVM_IRQFD
  +  select KVM_ARM_PMU
 ---help---
   Support hosting virtualized guest machines.
   
  @@ -52,4 +53,10 @@ config KVM_ARM_MAX_VCPUS
   large, so only choose a reasonable number that you expect to
   actually use.
   
  +config KVM_ARM_PMU
  +  bool
  +  depends on KVM_ARM_HOST
  +  ---help---
  +Adds support for the Performance Monitoring in virtual machines.
  
  Adds support for a virtual Performance Monitoring Unit (PMU) in virtual
  machines.
  
  +
   endif # VIRTUALIZATION
  diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
  index f90f4aa..78db4ee 100644
  --- a/arch/arm64/kvm/Makefile
  +++ b/arch/arm64/kvm/Makefile
  @@ -27,3 +27,4 @@ kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic-v3.o
   kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic-v3-emul.o
   kvm-$(CONFIG_KVM_ARM_HOST) += vgic-v3-switch.o
   kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/arch_timer.o
  +kvm-$(CONFIG_KVM_ARM_PMU) += $(KVM)/arm/pmu.o
  diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
  index 0b43265..ee2c2e9 100644
  --- a/arch/arm64/kvm/reset.c
  +++ b/arch/arm64/kvm/reset.c
  @@ -107,5 +107,8 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
 /* Reset timer */
 kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);
   
  +  /* Reset PMU */
  +  kvm_pmu_vcpu_reset(vcpu);
  +
 return 0;
   }
  diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
  new file mode 100644
  index 000..27d14ca
  --- /dev/null
  +++ b/include/kvm/arm_pmu.h
  @@ -0,0 +1,54 @@
  +/*
  + * Copyright (C) 2015 Linaro Ltd.
  + * Author: Shannon Zhao shannon.z...@linaro.org
  + *
  + * This program is free software; you can redistribute it and/or modify
  + * it under the terms of the GNU General Public License version 2 as
  + * published by the Free Software Foundation.
  + *
  + * This 

Re: [PATCH] arm64/kvm: Add generic v8 KVM target

2015-07-17 Thread Marc Zyngier
On 17/07/15 11:15, Christoffer Dall wrote:
 On Fri, Jul 17, 2015 at 10:56:39AM +0100, Marc Zyngier wrote:
 On 17/07/15 10:33, Christoffer Dall wrote:
 On Fri, Jul 03, 2015 at 11:10:09AM +0100, Marc Zyngier wrote:
 On 03/07/15 10:34, Peter Maydell wrote:
 On 3 July 2015 at 09:28, Marc Zyngier marc.zyng...@arm.com wrote:
 On 03/07/15 09:12, Peter Maydell wrote:
 I would still like to see the proponents of this patch say
 what their model is for userspace support of cross-host migration,
 if we're abandoning the model the current API envisages.

 I thought we had discussed this above, and don't really see this as a
 departure from the current model:

 - -cpu host results in GENERIC being used: VM can only be migrated
 to the exact same HW (no cross-host migration). MIDR should probably
 become RO.
 - -cpu host results in A57 (for example): VM can be migrated to a
 variety of A57 platforms, and allow for some fuzzing on the revision (or
 accept any revision).
 - -cpu a57 forces an A57 model to be emulated, always. It is always
 possible to migrate such a VM on any host.

 I think only the first point is new, but the last two are what we have
 (or what we should have).

 Right, but the implicit idea of this GENERIC patch seems to
 be that new host CPU types don't get their own KVM_ARM_TARGET_*
 constant, and are thus forever unable to do cross-host migration.
 It's not clear to me why we'd want to have new CPUs be second
 class citizens like that.

 I certainly don't want to see *any* CPU be a second class citizen. But
 let's face it, we're adding more and more targets that don't implement
 anything new, and just satisfy themselves with the generic implementation.

 I see it as an incentive to provide something useful (tables of all the
 registers with default values?) so that cross-host migration becomes a
 reality instead of the figment of our imagination (as it is now). If it
 wasn't already ABI, I'd have removed the existing targets until we have
 something meaningful to put there.

 What we're doing now certainly seems silly, because we're adding kernel
 patches without bringing anything to the table...


 Now, I also have my own doubts about cross-host migration (timers
 anyone?). But I don't see the above as a change in policy. More as a way
 to outline the fact that we currently don't have the right level of
 information/infrastructure to support it at all.

 The one thing that I've lost track of here (sorry) is whether we're
 enforcing the inability to do cross-host migration with the generic
 target when this patch is merged or do we leave this up to the graces of
 userspace?

 The jury is still out on that one.

 I was initially not going to enforce anything (after all, this isn't
 that different from the whole CNTVOFF story where we allow userspace to
 shoot itself in the foot), but I'm equally happy to make MIDR_EL1
 read-only if we're creating a generic guest...

 Looking at the code, midr_el1 is already an invariant register, so isn't
 this automagically enforced already?

Ah, you're perfectly right, I has already in that fantasy world where we
can actually migrate VMs across implementations.

 In that case, I'm fine with merging this patch.

Cool. I'll queue that for 4.3.

Thanks,

M.
-- 
Jazz is not dead. It just smells funny...
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] powerpc/rtas: Introduce rtas_get_sensor_fast() for IRQ handlers

2015-07-17 Thread Thomas Huth
The EPOW interrupt handler uses rtas_get_sensor(), which in turn
uses rtas_busy_delay() to wait for RTAS becoming ready in case it
is necessary. But rtas_busy_delay() is annotated with might_sleep()
and thus may not be used by interrupts handlers like the EPOW handler!
This leads to the following BUG when CONFIG_DEBUG_ATOMIC_SLEEP is
enabled:

 BUG: sleeping function called from invalid context at 
arch/powerpc/kernel/rtas.c:496
 in_atomic(): 1, irqs_disabled(): 1, pid: 0, name: swapper/1
 CPU: 1 PID: 0 Comm: swapper/1 Not tainted 4.2.0-rc2-thuth #6
 Call Trace:
 [c0007ffe7b90] [c0807670] dump_stack+0xa0/0xdc (unreliable)
 [c0007ffe7bc0] [c00e1f14] ___might_sleep+0x134/0x180
 [c0007ffe7c20] [c002aec0] rtas_busy_delay+0x30/0xd0
 [c0007ffe7c50] [c002bde4] rtas_get_sensor+0x74/0xe0
 [c0007ffe7ce0] [c0083264] ras_epow_interrupt+0x44/0x450
 [c0007ffe7d90] [c0120260] handle_irq_event_percpu+0xa0/0x300
 [c0007ffe7e70] [c0120524] handle_irq_event+0x64/0xc0
 [c0007ffe7eb0] [c0124dbc] handle_fasteoi_irq+0xec/0x260
 [c0007ffe7ef0] [c011f4f0] generic_handle_irq+0x50/0x80
 [c0007ffe7f20] [c0010f3c] __do_irq+0x8c/0x200
 [c0007ffe7f90] [c00236cc] call_do_irq+0x14/0x24
 [c0007e6f39e0] [c0011144] do_IRQ+0x94/0x110
 [c0007e6f3a30] [c0002594] hardware_interrupt_common+0x114/0x180

Fix this issue by introducing a new rtas_get_sensor_fast() function
that does not use rtas_busy_delay() - and thus can only be used for
sensors that do not cause a BUSY condition (which should be the case
for the sensor that is queried by the EPOW IRQ handler).

Signed-off-by: Thomas Huth th...@redhat.com
---
 arch/powerpc/include/asm/rtas.h  |  1 +
 arch/powerpc/kernel/rtas.c   | 17 +
 arch/powerpc/platforms/pseries/ras.c |  3 ++-
 3 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
index 7a4ede1..b77ef36 100644
--- a/arch/powerpc/include/asm/rtas.h
+++ b/arch/powerpc/include/asm/rtas.h
@@ -343,6 +343,7 @@ extern void rtas_power_off(void);
 extern void rtas_halt(void);
 extern void rtas_os_term(char *str);
 extern int rtas_get_sensor(int sensor, int index, int *state);
+extern int rtas_get_sensor_fast(int sensor, int index, int *state);
 extern int rtas_get_power_level(int powerdomain, int *level);
 extern int rtas_set_power_level(int powerdomain, int level, int *setlevel);
 extern bool rtas_indicator_present(int token, int *maxindex);
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 7a488c1..caffb10 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -584,6 +584,23 @@ int rtas_get_sensor(int sensor, int index, int *state)
 }
 EXPORT_SYMBOL(rtas_get_sensor);
 
+int rtas_get_sensor_fast(int sensor, int index, int *state)
+{
+   int token = rtas_token(get-sensor-state);
+   int rc;
+
+   if (token == RTAS_UNKNOWN_SERVICE)
+   return -ENOENT;
+
+   rc = rtas_call(token, 2, 2, state, sensor, index);
+   WARN_ON(rc == RTAS_BUSY || (rc = RTAS_EXTENDED_DELAY_MIN 
+   rc = RTAS_EXTENDED_DELAY_MAX));
+
+   if (rc  0)
+   return rtas_error_rc(rc);
+   return rc;
+}
+
 bool rtas_indicator_present(int token, int *maxindex)
 {
int proplen, count, i;
diff --git a/arch/powerpc/platforms/pseries/ras.c 
b/arch/powerpc/platforms/pseries/ras.c
index 02e4a17..3b6647e 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -189,7 +189,8 @@ static irqreturn_t ras_epow_interrupt(int irq, void *dev_id)
int state;
int critical;
 
-   status = rtas_get_sensor(EPOW_SENSOR_TOKEN, EPOW_SENSOR_INDEX, state);
+   status = rtas_get_sensor_fast(EPOW_SENSOR_TOKEN, EPOW_SENSOR_INDEX,
+ state);
 
if (state  3)
critical = 1;   /* Time Critical */
-- 
1.8.3.1

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


KVM call for agenda for 2015-07-21

2015-07-17 Thread Juan Quintela

Hi

Please, send any topic that you are interested in covering.


 Call details:

By popular demand, a google calendar public entry with it

  
https://www.google.com/calendar/embed?src=dG9iMXRqcXAzN3Y4ZXZwNzRoMHE4a3BqcXNAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ

(Let me know if you have any problems with the calendar entry.  I just
gave up about getting right at the same time CEST, CET, EDT and DST).

If you need phone number details,  contact me privately

Thanks, Juan.


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


Re: [PATCH] arm64/kvm: Add generic v8 KVM target

2015-07-17 Thread Marc Zyngier
On 17/07/15 10:33, Christoffer Dall wrote:
 On Fri, Jul 03, 2015 at 11:10:09AM +0100, Marc Zyngier wrote:
 On 03/07/15 10:34, Peter Maydell wrote:
 On 3 July 2015 at 09:28, Marc Zyngier marc.zyng...@arm.com wrote:
 On 03/07/15 09:12, Peter Maydell wrote:
 I would still like to see the proponents of this patch say
 what their model is for userspace support of cross-host migration,
 if we're abandoning the model the current API envisages.

 I thought we had discussed this above, and don't really see this as a
 departure from the current model:

 - -cpu host results in GENERIC being used: VM can only be migrated
 to the exact same HW (no cross-host migration). MIDR should probably
 become RO.
 - -cpu host results in A57 (for example): VM can be migrated to a
 variety of A57 platforms, and allow for some fuzzing on the revision (or
 accept any revision).
 - -cpu a57 forces an A57 model to be emulated, always. It is always
 possible to migrate such a VM on any host.

 I think only the first point is new, but the last two are what we have
 (or what we should have).

 Right, but the implicit idea of this GENERIC patch seems to
 be that new host CPU types don't get their own KVM_ARM_TARGET_*
 constant, and are thus forever unable to do cross-host migration.
 It's not clear to me why we'd want to have new CPUs be second
 class citizens like that.

 I certainly don't want to see *any* CPU be a second class citizen. But
 let's face it, we're adding more and more targets that don't implement
 anything new, and just satisfy themselves with the generic implementation.

 I see it as an incentive to provide something useful (tables of all the
 registers with default values?) so that cross-host migration becomes a
 reality instead of the figment of our imagination (as it is now). If it
 wasn't already ABI, I'd have removed the existing targets until we have
 something meaningful to put there.
 
 What we're doing now certainly seems silly, because we're adding kernel
 patches without bringing anything to the table...
 

 Now, I also have my own doubts about cross-host migration (timers
 anyone?). But I don't see the above as a change in policy. More as a way
 to outline the fact that we currently don't have the right level of
 information/infrastructure to support it at all.

 The one thing that I've lost track of here (sorry) is whether we're
 enforcing the inability to do cross-host migration with the generic
 target when this patch is merged or do we leave this up to the graces of
 userspace?

The jury is still out on that one.

I was initially not going to enforce anything (after all, this isn't
that different from the whole CNTVOFF story where we allow userspace to
shoot itself in the foot), but I'm equally happy to make MIDR_EL1
read-only if we're creating a generic guest...

Thanks,

M.
-- 
Jazz is not dead. It just smells funny...
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 3/7] KVM: irqchip: convey devid to kvm_set_msi

2015-07-17 Thread Paolo Bonzini


On 17/07/2015 09:27, Pavel Fedin wrote:
  +  } else if (!msi-flags)
  +  return -EINVAL;
  Did you mean if (msg-flags) here (inverted condition)?

Indeed, and also you need { } around the return for the QEMU coding
standard.

Paolo

  +
  +  /* historically the route.type was not set */
  +
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 03/18] KVM: ARM64: Add offset defines for PMU registers

2015-07-17 Thread Christoffer Dall
On Fri, Jul 17, 2015 at 04:25:06PM +0800, Shannon Zhao wrote:
 
 
 On 2015/7/17 2:45, Christoffer Dall wrote:
  On Mon, Jul 06, 2015 at 10:17:33AM +0800, shannon.z...@linaro.org wrote:
  From: Shannon Zhao shannon.z...@linaro.org
 
  We are about to trap and emulate acccesses to each PMU register
  individually. This adds the context offsets for the AArch64 PMU
  registers and their AArch32 counterparts.
 
  Signed-off-by: Shannon Zhao shannon.z...@linaro.org
  ---
   arch/arm64/include/asm/kvm_asm.h | 59 
  +++-
   1 file changed, 52 insertions(+), 7 deletions(-)
 
  diff --git a/arch/arm64/include/asm/kvm_asm.h 
  b/arch/arm64/include/asm/kvm_asm.h
  index 3c5fe68..21b5d3b 100644
  --- a/arch/arm64/include/asm/kvm_asm.h
  +++ b/arch/arm64/include/asm/kvm_asm.h
  @@ -56,14 +56,36 @@
   #define DBGWVR15_EL1  86
   #define MDCCINT_EL1   87  /* Monitor Debug Comms Channel 
  Interrupt Enable Reg */
   
  +/* Performance Monitors Registers */
  +#define PMCR_EL0  88  /* Control Register */
  +#define PMOVSSET_EL0  89  /* Overflow Flag Status Set Register */
  +#define PMOVSCLR_EL0  90  /* Overflow Flag Status Clear Register 
  */
  +#define PMCCNTR_EL0   91  /* Cycle Counter Register */
  +#define PMSELR_EL092  /* Event Counter Selection Register */
  +#define PMCEID0_EL0   93  /* Common Event Identification Register 
  0 */
  +#define PMCEID1_EL0   94  /* Common Event Identification Register 
  1 */
  +#define PMEVCNTR0_EL0 95  /* Event Counter Register (0-30) */
  
  why do we need these when we trap-and-emulate and we have the kvm_pmc
  structs? 
 This just makes the guest work when accessing these registers.
 
  Is that because the kvm_pmc structs are only used when we
  actually have an active counter running and registered with perf?
  
 
 Right, the kvm_pmc structs are used to store the status of perf evnets,
 like the event type, count number of this perf event.
 
 On the other hand, the kernel perf codes will not directly access to the
 PMEVCNTRx_EL0 and PMEVTYPERx_EL0 registers. It will firstly write the
 index of select counter to PMSELR_EL0 and access to PMXEVCNTR_EL0 or
 PMXEVTYPER_EL0. Then this is architecturally mapped to PMEVCNTRx_EL0 and
 PMEVTYPERx_EL0.
 

I'm just wondering if it makes sense to keep virtual state around for
all these registers, since we don't emulate the counter values, so why
do we need to preserve any virtual cpu state for all of them?

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


RE: [PATCH v2 3/7] KVM: irqchip: convey devid to kvm_set_msi

2015-07-17 Thread Pavel Fedin
 Hello!

   +} else if (!msi-flags)
   +return -EINVAL;
   Did you mean if (msg-flags) here (inverted condition)?
 
 Indeed, and also you need { } around the return for the QEMU coding
 standard.

 It's kernel and not qemu :)

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

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


Re: [PATCH 04/18] KVM: ARM64: Add reset and access handlers for PMCR_EL0 register

2015-07-17 Thread Christoffer Dall
On Fri, Jul 17, 2015 at 04:45:44PM +0800, Shannon Zhao wrote:
 
 
 On 2015/7/17 3:55, Christoffer Dall wrote:
  On Mon, Jul 06, 2015 at 10:17:34AM +0800, shannon.z...@linaro.org wrote:
  From: Shannon Zhao shannon.z...@linaro.org
 
  Add reset handler which gets host value of PMCR_EL0 and make writable
  bits architecturally UNKNOWN. Add access handler which emulates
  writing and reading PMCR_EL0 register.
 
  Signed-off-by: Shannon Zhao shannon.z...@linaro.org
  ---
   arch/arm64/kvm/sys_regs.c | 41 -
   1 file changed, 40 insertions(+), 1 deletion(-)
 
  diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
  index c370b40..152ee17 100644
  --- a/arch/arm64/kvm/sys_regs.c
  +++ b/arch/arm64/kvm/sys_regs.c
  @@ -33,6 +33,7 @@
   #include asm/kvm_emulate.h
   #include asm/kvm_host.h
   #include asm/kvm_mmu.h
  +#include asm/pmu.h
   
   #include trace/events/kvm.h
   
  @@ -236,6 +237,44 @@ static void reset_mpidr(struct kvm_vcpu *vcpu, const 
  struct sys_reg_desc *r)
 vcpu_sys_reg(vcpu, MPIDR_EL1) = (1ULL  31) | mpidr;
   }
   
  +static void reset_pmcr_el0(struct kvm_vcpu *vcpu, const struct 
  sys_reg_desc *r)
  +{
  +  u32 pmcr;
  +
  +  asm volatile(mrs %0, pmcr_el0\n : =r (pmcr));
  +  vcpu_sys_reg(vcpu, PMCR_EL0) = (pmcr  ~ARMV8_PMCR_MASK)
  + | (ARMV8_PMCR_MASK  0xdecafbad);
  
  You could add a comment that this resets to UNKNOWN as to not make
  people confused about the pseudo-random hex value.
  
 Ok.
 
  Have we thought about whether we want to tell the guest that it has the
  same PMU as available on the real hardware, or does the virtualization
  layer suggest to us that we should adjust this somehow?
  
 I guess here the number of PMU counters is what we can adjust, right?
 Are we worried about that the host will run out of counters when guest
 and host register lots of events?

that's what I wonder; if perf itself reserves a counter for example,
then we'll at best be able to measure with N-1 counters for the guest (N
being the number of counters on the physical CPU), so why tell the guest
we have N counters?

Of course, we can never even be guaranteed to have N-1 counters
avaialable either, so maybe the sane choice is just to tell the guest
what kind of hardware we have, and then fiddle the best we can with the
remaining counters?  After all, correct functionality of the guest
doesn't depend on this, it's a best-effort kind of thing...

Thoughts?

 The PMU of cortex-a57 has 6 counters. IIUC, if one of the guest vcpu
 process registers 6 events and some host process register 6 events too,
 these events will be monitored in real hardware PMU counter when the
 related process runs on the cpu. And when other processes are scheduled
 to run, it will switch the contexts of PMU counters.

That depends on the way the counters are used by perf I think.  What if
you have system wide events?  What if the KVM (vcpu) process itself is
being monitored for some events?

 
  
  +}
  +
  +/* PMCR_EL0 accessor. Only called as long as MDCR_EL2.TPMCR is set. */
  +static bool access_pmcr(struct kvm_vcpu *vcpu,
  +  const struct sys_reg_params *p,
  +  const struct sys_reg_desc *r)
  +{
  +  unsigned long val;
  +
  +  if (p-is_write) {
  +  /* Only update writeable bits of PMCR */
  +  if (!p-is_aarch32)
  +  val = vcpu_sys_reg(vcpu, r-reg);
  +  else
  +  val = vcpu_cp15(vcpu, r-reg);
  
  don't you need to add this function as the handler in the cp15_regs
  array as well?
  
 Sorry, I'm not very clear about this. Will look at the codes and
 understand the use of cp15_regs.
 

I think the point is that you cannot use the same value of r-reg to
index into both arrays, so the cp15 index must be passed from the
cp15_regs array first.

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


Re: [PATCH v4 0/2] arm/arm64: KVM: Optimize arm64 fp/simd, saves 30-50% on exits

2015-07-17 Thread Marc Zyngier
On 16/07/15 22:29, Mario Smarduch wrote:
 Currently we save/restore fp/simd on each exit. The first patch optimizes 
 arm64
 save/restore, we only do so on Guest access. hackbench and several lmbench
 tests show anywhere from 30% to 50% of exits don't context switch the vfp/simd
 registers.
 
 For second patch 32-bit handler is updated to keep exit handling consistent
 with 64-bit code.

This looks pretty good, I'll take these patches in for 4.3.

Thanks,

M.
-- 
Jazz is not dead. It just smells funny...
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 2/3] KVM: arm: Detect vGIC presence at runtime

2015-07-17 Thread Marc Zyngier
On 14/07/15 13:06, Pavel Fedin wrote:
 Allows to use KVM on hardware without vGIC. Interrupt controller has to be
 emulated in userspace in this case.
 
 -ENODEV return code from probe function means there's no GIC at all. -ENXIO
 happens when, for example, there is GIC node in the device tree, but it does
 not specify vGIC resources. Normally this means that vGIC hardware is defunct.
 Any other code is still treated as full stop because it might mean some really
 serious problems.

As mentioned in a previous email, supporting systems that don't even
have a GIC at all (hence don't support the management of an ACTIVE
state) is going to keep us in the dark ages. See the active timer series
that mandates it.

So keeping KVM alive when we get an -ENODEV is not acceptable. No GIC,
no fun.

 
 Signed-off-by: Pavel Fedin p.fe...@samsung.com
 ---
  arch/arm/kvm/arm.c | 22 --
  1 file changed, 20 insertions(+), 2 deletions(-)
 
 diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
 index 5668c4e..7e389fd 100644
 --- a/arch/arm/kvm/arm.c
 +++ b/arch/arm/kvm/arm.c
 @@ -61,6 +61,8 @@ static atomic64_t kvm_vmid_gen = ATOMIC64_INIT(1);
  static u8 kvm_next_vmid;
  static DEFINE_SPINLOCK(kvm_vmid_lock);
  
 +static bool vgic_present;
 +

This needs documentation.

  static void kvm_arm_set_running_vcpu(struct kvm_vcpu *vcpu)
  {
   BUG_ON(preemptible());
 @@ -131,7 +133,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
   kvm-arch.vmid_gen = 0;
  
   /* The maximum number of VCPUs is limited by the host's GIC model */
 - kvm-arch.max_vcpus = kvm_vgic_get_max_vcpus();
 + kvm-arch.max_vcpus = vgic_present ?
 + kvm_vgic_get_max_vcpus() : KVM_MAX_VCPUS;
  
   return ret;
  out_free_stage2_pgd:
 @@ -172,6 +175,8 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long 
 ext)
   switch (ext) {
   case KVM_CAP_IRQCHIP:
   case KVM_CAP_IRQFD:
 + r = vgic_present;
 + break;
   case KVM_CAP_IOEVENTFD:
   case KVM_CAP_DEVICE_CTRL:
   case KVM_CAP_USER_MEMORY:
 @@ -850,6 +855,8 @@ static int kvm_vm_ioctl_set_device_addr(struct kvm *kvm,
  
   switch (dev_id) {
   case KVM_ARM_DEVICE_VGIC_V2:
 + if (!vgic_present)
 + return -ENXIO;
   return kvm_vgic_addr(kvm, type, dev_addr-addr, true);
   default:
   return -ENODEV;
 @@ -864,6 +871,8 @@ long kvm_arch_vm_ioctl(struct file *filp,
  
   switch (ioctl) {
   case KVM_CREATE_IRQCHIP: {
 + if (!vgic_present)
 + return -ENXIO;
   return kvm_vgic_create(kvm, KVM_DEV_TYPE_ARM_VGIC_V2);
   }
   case KVM_ARM_SET_DEVICE_ADDR: {
 @@ -1046,8 +1055,17 @@ static int init_hyp_mode(void)
* Init HYP view of VGIC
*/
   err = kvm_vgic_hyp_init();
 - if (err)
 + switch (err) {
 + case 0:
 + vgic_present = true;
 + break;
 + case -ENODEV:
 + case -ENXIO:
 + vgic_present = false;
 + break;
 + default:
   goto out_free_context;
 + }
  
   /*
* Init HYP architected timer support
 


-- 
Jazz is not dead. It just smells funny...
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 1/3] KVM: arm: Fix NULL pointer dereference if KVM is used without in-kernel irqchip

2015-07-17 Thread Marc Zyngier
On 14/07/15 13:06, Pavel Fedin wrote:
 Makes qemu working again with kernel-irqchip=off option

I'd appreciate a better commit log. Which patch broke it, why is that
necessary.

 
 Signed-off-by: Pavel Fedin p.fe...@samsung.com
 ---
  arch/arm/kvm/arm.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
 index d9631ec..5668c4e 100644
 --- a/arch/arm/kvm/arm.c
 +++ b/arch/arm/kvm/arm.c
 @@ -450,7 +450,7 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
* Map the VGIC hardware resources before running a vcpu the first
* time on this VM.
*/
 - if (unlikely(!vgic_ready(kvm))) {
 + if (irqchip_in_kernel(kvm)  unlikely(!vgic_ready(kvm))) {

I think you should factor the irqchip_in_kernel() inside the unlikely
clause. Something like

bool vgic_needs_init = irqchip_in_kernel(kvm)  !vgic_ready(kvm);

if (unlikely(vfic_needs_init)) {
...
}

   ret = kvm_vgic_map_resources(kvm);
   if (ret)
   return ret;
 

Thanks,

M.
-- 
Jazz is not dead. It just smells funny...
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 00/12] kvmtool: Improve portability

2015-07-17 Thread Will Deacon
On Fri, Jul 17, 2015 at 05:02:06PM +0100, Andre Przywara wrote:
 Hi,

Hi Andre,

 this is a collection of patches to bring kvmtool closer to standards
 compliance (with standards not necessarily meaning GNU only).
 With all those patches applied, you can compile kvmtool with newer
 C standards, with clang and against musl-libc.

Most of this looks good to me, thanks! I'll leave it to stew for a few
days on the list, but I'm planning to merge it all apart from the two
*printf clang hacks and the PAGE_SIZE patch which Szabolcs commented on.

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


Re: [PATCH 11/12] avoid using predefined PAGE_SIZE

2015-07-17 Thread Szabolcs Nagy
On 17/07/15 17:02, Andre Przywara wrote:
 The musl-libc comes with a predefined PAGE_SIZE macro, which may be
 wrong on systems which support multiple smallest page sizes.
 Make sure we use our own (runtime evaluated) definition of PAGE_SIZE.


musl only provides PAGE_SIZE on archs where it is
constant, if not, that's a musl bug and should be
fixed there (this is a posix requirement).

the ifdef does not help around this: musl sysconf
will return the same value as you get from the
header (it would be a conformance bug otherwise).

use

#include limits.h
#ifndef PAGE_SIZE
#define PAGE_SIZE sysconf(_SC_PAGE_SIZE)
#endif

 Signed-off-by: Andre Przywara andre.przyw...@arm.com
 ---
  include/kvm/kvm.h | 4 
  1 file changed, 4 insertions(+)

 diff --git a/include/kvm/kvm.h b/include/kvm/kvm.h
 index 9818046..8b12cd6 100644
 --- a/include/kvm/kvm.h
 +++ b/include/kvm/kvm.h
 @@ -19,6 +19,10 @@
  #define HOME_DIR getenv(HOME)
  #define KVM_BINARY_NAME  lkvm

 +/* Let's determine the actual page size at runtime. */
 +#ifdef PAGE_SIZE
 +#undef PAGE_SIZE
 +#endif
  #define PAGE_SIZE (sysconf(_SC_PAGE_SIZE))

  #define DEFINE_KVM_EXT(ext)  \



-- IMPORTANT NOTICE: The contents of this email and any attachments are 
confidential and may also be privileged. If you are not the intended recipient, 
please notify the sender immediately and do not disclose the contents to any 
other person, use it for any purpose, or store or copy the information in any 
medium.  Thank you.

ARM Limited, Registered office 110 Fulbourn Road, Cambridge CB1 9NJ, Registered 
in England  Wales, Company No:  2557590
ARM Holdings plc, Registered office 110 Fulbourn Road, Cambridge CB1 9NJ, 
Registered in England  Wales, Company No:  2548782

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


Re: [PATCH 06/12] kvm__set_dir(): avoid variable arguments call

2015-07-17 Thread Will Deacon
On Fri, Jul 17, 2015 at 05:02:12PM +0100, Andre Przywara wrote:
 The clang compiler by default dislikes non-literal format strings
 in *printf functions, so it complains about kvm__set_dir() in kvm.c.
 Instead of suppressing this warning, lets change the code to avoid
 that unneeded var_args detour and use a literal format string.

Why does clang moan about this? The current code looks perfectly alright
to me.

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


Re: [PATCH 07/12] util/util.c: avoid clang error on vsnprintf

2015-07-17 Thread Will Deacon
On Fri, Jul 17, 2015 at 05:02:13PM +0100, Andre Przywara wrote:
 clang by default doesn't seem to like printf calls with non-literal
 format strings.
 Add the proper pragma to disable this warning in the report function
 to make kvmtool compile with clang. Despite its GCC name, clang also
 accepts this.
 
 Signed-off-by: Andre Przywara andre.przyw...@arm.com
 ---
  util/util.c | 1 +
  1 file changed, 1 insertion(+)
 
 diff --git a/util/util.c b/util/util.c
 index 1877105..825da3f 100644
 --- a/util/util.c
 +++ b/util/util.c
 @@ -10,6 +10,7 @@
  #include sys/stat.h
  #include sys/statfs.h
  
 +#pragma GCC diagnostic ignored -Wformat-nonliteral

Urgh! I think we need to figure out a better way to keep clang happy in
this regard, if we decide that we care about building with it.

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


Re: [PATCH v2 0/3] KVM: arm/arm64: Allow to use KVM without in-kernel irqchip

2015-07-17 Thread Marc Zyngier
On 14/07/15 13:06, Pavel Fedin wrote:
 This patch set brings back functionality which was broken in v4.1. The
 overall goal is to eventually enable using virtual timer too, but for now
 changes affect only a possibility to run KVM itself. The guest currently
 has to use another timer because there's no API to propagate interrupts
 from in-kernel virtual timer to the interrupt controller emulated in
 userspace.
 
 v1=v2:
 - Do not use defensive approach in patch 0001. Use correct conditions in
   callers instead
 - Added ARM64-specific code, without which attempt to run a VM ends in a
   HYP crash because of unset vGIC save/restore function pointers
 
 Christoffer Dall: I decided to leave original approach of 0002 as it is,
 because:
 - It is much simpler to implement than doing changes inside both probe
   functions.
 - These are all use cases for vgic_present flag. Nothing else is going to
   rely on it. IMHO this switch is very short and stylish :) If you don't
   like two error codes, we could change -ENXIO to -ENODEV where appropriate,
   this change would be small enough.
 Actually i tried to discuss some things with you, but you stopped replying,
 therefore i respin in order to revive the thing. On top of this i have

I'm not Christoffer, but I'm going to take that one for the team.

Believe it or not, we're not only patch reviewing machines, and if you
count the number of pending patches, you'll quickly notice that yours
are basically noise in the grand scheme of things.

So please cut us some slack.

 complete implementation of API which allows to emulate GIC in userspace by
 qemu, and now i can run any virtual machine, including generic timer, on
 vGIC-less machine. RasPI-2 is expected to benefit too.

Do you mean feeding interrupts back to userspace? How is that going to
work with the active-timer series that really mandates a full blown GIC?
Your pet platform might cope with it, but I can't see that happening on
the RPi.

Thanks,

M.
-- 
Jazz is not dead. It just smells funny...
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 11/12] avoid using predefined PAGE_SIZE

2015-07-17 Thread Andre Przywara
The musl-libc comes with a predefined PAGE_SIZE macro, which may be
wrong on systems which support multiple smallest page sizes.
Make sure we use our own (runtime evaluated) definition of PAGE_SIZE.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 include/kvm/kvm.h | 4 
 1 file changed, 4 insertions(+)

diff --git a/include/kvm/kvm.h b/include/kvm/kvm.h
index 9818046..8b12cd6 100644
--- a/include/kvm/kvm.h
+++ b/include/kvm/kvm.h
@@ -19,6 +19,10 @@
 #define HOME_DIR   getenv(HOME)
 #define KVM_BINARY_NAMElkvm
 
+/* Let's determine the actual page size at runtime. */
+#ifdef PAGE_SIZE
+#undef PAGE_SIZE
+#endif
 #define PAGE_SIZE (sysconf(_SC_PAGE_SIZE))
 
 #define DEFINE_KVM_EXT(ext)\
-- 
2.3.5

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


[PATCH 03/12] kvm-ipc: use proper type for file descriptor

2015-07-17 Thread Andre Przywara
A socket (as any other file descriptor) is of type int to catch the
negative error cases. Fix the declaration to allow errors to be
detected.
Found and needed by clang.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 kvm-ipc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kvm-ipc.c b/kvm-ipc.c
index b1c43dd..a289d4b 100644
--- a/kvm-ipc.c
+++ b/kvm-ipc.c
@@ -34,7 +34,7 @@ static pthread_t thread;
 static int kvm__create_socket(struct kvm *kvm)
 {
char full_name[PATH_MAX];
-   unsigned int s;
+   int s;
struct sockaddr_un local;
int len, r;
 
-- 
2.3.5

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


[PATCH 01/12] avoid casts when initializing structures

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

This allows us to compile with all the three GNU standards GCC
currently supports: gnu89/90, gnu99 and gnu11.
GCC threatens people with moving to gnu11 as the new default standard,
so lets fix this better sooner than later.
(Compiling without GNU extensions still breaks and I don't bother to
fix that without very good reasons.)

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 disk/qcow.c| 6 +++---
 include/kvm/mutex.h| 2 +-
 include/linux/rbtree.h | 2 +-
 virtio/9p.c| 2 +-
 virtio/balloon.c   | 2 +-
 virtio/blk.c   | 2 +-
 virtio/console.c   | 2 +-
 virtio/net.c   | 2 +-
 virtio/rng.c   | 2 +-
 virtio/scsi.c  | 2 +-
 10 files changed, 12 insertions(+), 12 deletions(-)

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

[PATCH 02/12] qcow: fix signedness bugs

2015-07-17 Thread Andre Przywara
Some functions in qcow.c return u64, but are checked against  0
because they want to check for the -1 error return value.
Do an explicit comparison against the casted -1 to express this
properly.
This was silently compiled out by gcc, but clang complained about it.

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

diff --git a/disk/qcow.c b/disk/qcow.c
index e26c419..64cf927 100644
--- a/disk/qcow.c
+++ b/disk/qcow.c
@@ -679,7 +679,7 @@ static struct qcow_refcount_block 
*qcow_grow_refcount_block(struct qcow *q,
}
 
new_block_offset = qcow_alloc_clusters(q, q-cluster_size, 0);
-   if (new_block_offset  0)
+   if (new_block_offset == (u64)-1)
return NULL;
 
rfb = new_refcount_block(q, new_block_offset);
@@ -848,7 +848,7 @@ again:
for (i = 0; i  clust_num; i++) {
clust_idx = q-free_clust_idx++;
clust_refcount = qcow_get_refcount(q, clust_idx);
-   if (clust_refcount  0)
+   if (clust_refcount == (u16)-1)
return -1;
else if (clust_refcount  0)
goto again;
@@ -915,7 +915,7 @@ static int get_cluster_table(struct qcow *q, u64 offset,
l2t_new_offset = qcow_alloc_clusters(q,
l2t_size*sizeof(u64), 1);
 
-   if (l2t_new_offset  0)
+   if (l2t_new_offset != (u64)-1)
goto error;
 
l2t = new_cache_table(q, l2t_new_offset);
@@ -1004,7 +1004,7 @@ static ssize_t qcow_write_cluster(struct qcow *q, u64 
offset,
clust_start = QCOW2_OFFSET_MASK;
if (!(clust_flags  QCOW2_OFLAG_COPIED)) {
clust_new_start = qcow_alloc_clusters(q, q-cluster_size, 1);
-   if (clust_new_start  0) {
+   if (clust_new_start != (u64)-1) {
pr_warning(Cluster alloc error);
goto error;
}
-- 
2.3.5

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


[PATCH 08/12] Fix call to connect()

2015-07-17 Thread Andre Przywara
According to the manpage and the prototype the second argument to
connect(2) is a const struct sockaddr*, so cast our protocol
specific type back to the super type.
This fixes compilation on musl-libc.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 kvm-ipc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kvm-ipc.c b/kvm-ipc.c
index a289d4b..857b0dc 100644
--- a/kvm-ipc.c
+++ b/kvm-ipc.c
@@ -99,7 +99,7 @@ int kvm__get_sock_by_instance(const char *name)
strlcpy(local.sun_path, sock_file, sizeof(local.sun_path));
len = strlen(local.sun_path) + sizeof(local.sun_family);
 
-   r = connect(s, local, len);
+   r = connect(s, (struct sockaddr *)local, len);
if (r  0  errno == ECONNREFUSED) {
/* Tell the user clean ghost socket file */
pr_err(\%s\ could be a ghost socket file, please remove it,
-- 
2.3.5

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


[PATCH 06/12] kvm__set_dir(): avoid variable arguments call

2015-07-17 Thread Andre Przywara
The clang compiler by default dislikes non-literal format strings
in *printf functions, so it complains about kvm__set_dir() in kvm.c.
Instead of suppressing this warning, lets change the code to avoid
that unneeded var_args detour and use a literal format string.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 include/kvm/kvm.h |  2 +-
 kvm.c | 21 ++---
 main.c|  9 -
 3 files changed, 15 insertions(+), 17 deletions(-)

diff --git a/include/kvm/kvm.h b/include/kvm/kvm.h
index 754e029..9818046 100644
--- a/include/kvm/kvm.h
+++ b/include/kvm/kvm.h
@@ -67,7 +67,7 @@ struct kvm {
int vm_state;
 };
 
-void kvm__set_dir(const char *fmt, ...);
+int kvm__set_dir(const char *basedir, const char *lkvmdir);
 const char *kvm__get_dir(void);
 
 int kvm__init(struct kvm *kvm);
diff --git a/kvm.c b/kvm.c
index 78dd7c0..5222e1e 100644
--- a/kvm.c
+++ b/kvm.c
@@ -63,31 +63,22 @@ extern struct kvm_ext kvm_req_ext[];
 
 static char kvm_dir[PATH_MAX];
 
-static int set_dir(const char *fmt, va_list args)
+int kvm__set_dir(const char *basedir, const char* lkvmdir)
 {
char tmp[PATH_MAX];
 
-   vsnprintf(tmp, sizeof(tmp), fmt, args);
-
-   mkdir(tmp, 0777);
-
+   snprintf(tmp, PATH_MAX, %s/%s, basedir, lkvmdir);
if (!realpath(tmp, kvm_dir))
-   return -errno;
+   return errno;
+
+   if (access(tmp, R_OK | W_OK))
+   return errno;
 
strcat(kvm_dir, /);
 
return 0;
 }
 
-void kvm__set_dir(const char *fmt, ...)
-{
-   va_list args;
-
-   va_start(args, fmt);
-   set_dir(fmt, args);
-   va_end(args);
-}
-
 const char *kvm__get_dir(void)
 {
return kvm_dir;
diff --git a/main.c b/main.c
index 05bc82c..09ba8c1 100644
--- a/main.c
+++ b/main.c
@@ -13,7 +13,14 @@ static int handle_kvm_command(int argc, char **argv)
 
 int main(int argc, char *argv[])
 {
-   kvm__set_dir(%s/%s, HOME_DIR, KVM_PID_FILE_PATH);
+   int ret;
+
+   ret = kvm__set_dir(HOME_DIR, KVM_PID_FILE_PATH);
+   if (ret) {
+   pr_err(could not access lkvm directory \%s/%s\\n,
+  HOME_DIR, KVM_PID_FILE_PATH);
+   return 1;
+   }
 
return handle_kvm_command(argc - 1, argv[1]);
 }
-- 
2.3.5

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


[PATCH 04/12] Makefile: remove unneeded -s switch on compiling BIOS files

2015-07-17 Thread Andre Przywara
Stripping has no effect on object files, so having -s -c on the
command line makes no sense.
In fact clang complains about it and aborts with an error, so lets
just remove the unneeded -s switch here.

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

diff --git a/Makefile b/Makefile
index 151fa9d..46e4a9d 100644
--- a/Makefile
+++ b/Makefile
@@ -421,15 +421,15 @@ x86/bios.o: x86/bios/bios.bin x86/bios/bios-rom.h
 
 x86/bios/bios.bin.elf: x86/bios/entry.S x86/bios/e820.c x86/bios/int10.c 
x86/bios/int15.c x86/bios/rom.ld.S
$(E)   CC   x86/bios/memcpy.o
-   $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s 
x86/bios/memcpy.c -o x86/bios/memcpy.o
+   $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c 
x86/bios/memcpy.c -o x86/bios/memcpy.o
$(E)   CC   x86/bios/e820.o
-   $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s 
x86/bios/e820.c -o x86/bios/e820.o
+   $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c 
x86/bios/e820.c -o x86/bios/e820.o
$(E)   CC   x86/bios/int10.o
-   $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s 
x86/bios/int10.c -o x86/bios/int10.o
+   $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c 
x86/bios/int10.c -o x86/bios/int10.o
$(E)   CC   x86/bios/int15.o
-   $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s 
x86/bios/int15.c -o x86/bios/int15.o
+   $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c 
x86/bios/int15.c -o x86/bios/int15.o
$(E)   CC   x86/bios/entry.o
-   $(Q) $(CC) $(CFLAGS) $(BIOS_CFLAGS) -c -s x86/bios/entry.S -o 
x86/bios/entry.o
+   $(Q) $(CC) $(CFLAGS) $(BIOS_CFLAGS) -c x86/bios/entry.S -o 
x86/bios/entry.o
$(E)   LD   $@
$(Q) $(LD) -T x86/bios/rom.ld.S -o x86/bios/bios.bin.elf 
x86/bios/memcpy.o x86/bios/entry.o x86/bios/e820.o x86/bios/int10.o 
x86/bios/int15.o
 
-- 
2.3.5

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


[PATCH 05/12] ui: remove pointless double const in keymap declarations

2015-07-17 Thread Andre Przywara
clang does not like two const specifiers in one declaration, so
remove one to let clang compile kvmtool.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 ui/gtk3.c | 2 +-
 ui/sdl.c  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/ui/gtk3.c b/ui/gtk3.c
index b2335bc..1e08a8f 100644
--- a/ui/gtk3.c
+++ b/ui/gtk3.c
@@ -34,7 +34,7 @@ struct set2_scancode {
.type = SCANCODE_ESCAPED,   \
 }
 
-static const struct set2_scancode const keymap[256] = {
+static const struct set2_scancode keymap[256] = {
[9] = DEFINE_SC(0x76),  /* esc */
[10]= DEFINE_SC(0x16),  /* 1 */
[11]= DEFINE_SC(0x1e),  /* 2 */
diff --git a/ui/sdl.c b/ui/sdl.c
index a260002..f97a511 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -36,7 +36,7 @@ struct set2_scancode {
.type = SCANCODE_ESCAPED,\
 }
 
-static const struct set2_scancode const keymap[256] = {
+static const struct set2_scancode keymap[256] = {
[9] = DEFINE_SC(0x76),  /* esc */
[10]= DEFINE_SC(0x16),  /* 1 */
[11]= DEFINE_SC(0x1e),  /* 2 */
-- 
2.3.5

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


[PATCH 09/12] use poll.h instead of sys/poll.h

2015-07-17 Thread Andre Przywara
The manpage of poll(2) states that the prototype of poll is defined
in poll.h. Use that header file instead of sys/poll.h to allow
compilation against musl-libc.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 disk/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/disk/core.c b/disk/core.c
index 309e16c..dd2f258 100644
--- a/disk/core.c
+++ b/disk/core.c
@@ -5,7 +5,7 @@
 
 #include linux/err.h
 #include sys/eventfd.h
-#include sys/poll.h
+#include poll.h
 
 #define AIO_MAX 256
 
-- 
2.3.5

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


[PATCH 10/12] check for and use C library provided strlcpy and strlcat

2015-07-17 Thread Andre Przywara
The musl-libc library provides implementations of strlcpy and strlcat,
so introduce a feature check for it and only use the kvmtool
implementation if there is no library support for it.
This avoids clashes with the public definition.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 Makefile |  5 +
 config/feature-tests.mak | 10 ++
 include/kvm/strbuf.h |  2 ++
 util/strbuf.c|  2 ++
 4 files changed, 19 insertions(+)

diff --git a/Makefile b/Makefile
index 46e4a9d..285c482 100644
--- a/Makefile
+++ b/Makefile
@@ -199,6 +199,11 @@ endif
 # On a given system, some libs may link statically, some may not; so, check
 # both and only build those that link!
 
+ifeq ($(call try-build,$(SOURCE_STRLCPY),$(CFLAGS),),y)
+   CFLAGS_DYNOPT   += -DHAVE_STRLCPY
+   CFLAGS_STATOPT  += -DHAVE_STRLCPY
+endif
+
 ifeq ($(call try-build,$(SOURCE_BFD),$(CFLAGS),-lbfd -static),y)
CFLAGS_STATOPT  += -DCONFIG_HAS_BFD
OBJS_STATOPT+= symbol.o
diff --git a/config/feature-tests.mak b/config/feature-tests.mak
index 6bee6c2..03cdb42 100644
--- a/config/feature-tests.mak
+++ b/config/feature-tests.mak
@@ -196,3 +196,13 @@ int main(void)
return 0;
 }
 endef
+
+define SOURCE_STRLCPY
+#include string.h
+
+int main(void)
+{
+   strlcpy(NULL, NULL, 0);
+   return 0;
+}
+endef
diff --git a/include/kvm/strbuf.h b/include/kvm/strbuf.h
index 2beefbc..7657339 100644
--- a/include/kvm/strbuf.h
+++ b/include/kvm/strbuf.h
@@ -6,8 +6,10 @@
 
 int prefixcmp(const char *str, const char *prefix);
 
+#ifndef HAVE_STRLCPY
 extern size_t strlcat(char *dest, const char *src, size_t count);
 extern size_t strlcpy(char *dest, const char *src, size_t size);
+#endif
 
 /* some inline functions */
 
diff --git a/util/strbuf.c b/util/strbuf.c
index 99d6b0c..2c6e8ad 100644
--- a/util/strbuf.c
+++ b/util/strbuf.c
@@ -13,6 +13,7 @@ int prefixcmp(const char *str, const char *prefix)
}
 }
 
+#ifndef HAVE_STRLCPY
 /**
  * strlcat - Append a length-limited, %NUL-terminated string to another
  * @dest: The string to be appended to
@@ -60,3 +61,4 @@ size_t strlcpy(char *dest, const char *src, size_t size)
}
return ret;
 }
+#endif
-- 
2.3.5

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


[PATCH 07/12] util/util.c: avoid clang error on vsnprintf

2015-07-17 Thread Andre Przywara
clang by default doesn't seem to like printf calls with non-literal
format strings.
Add the proper pragma to disable this warning in the report function
to make kvmtool compile with clang. Despite its GCC name, clang also
accepts this.

Signed-off-by: Andre Przywara andre.przyw...@arm.com
---
 util/util.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/util/util.c b/util/util.c
index 1877105..825da3f 100644
--- a/util/util.c
+++ b/util/util.c
@@ -10,6 +10,7 @@
 #include sys/stat.h
 #include sys/statfs.h
 
+#pragma GCC diagnostic ignored -Wformat-nonliteral
 static void report(const char *prefix, const char *err, va_list params)
 {
char msg[1024];
-- 
2.3.5

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


[PATCH 12/12] remove KVM_CAP_MAX_VCPUS hack

2015-07-17 Thread Andre Przywara
As we now have the header file in our repository, we can safely follow
the recommendation in kvm.c and remove the hack adding the
KVM_CAP_MAX_VCPUS macro.

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

diff --git a/kvm.c b/kvm.c
index 5222e1e..53e5c6b 100644
--- a/kvm.c
+++ b/kvm.c
@@ -223,14 +223,6 @@ int kvm__recommended_cpus(struct kvm *kvm)
return ret;
 }
 
-/*
- * The following hack should be removed once 'x86: Raise the hard
- * VCPU count limit' makes it's way into the mainline.
- */
-#ifndef KVM_CAP_MAX_VCPUS
-#define KVM_CAP_MAX_VCPUS 66
-#endif
-
 int kvm__max_cpus(struct kvm *kvm)
 {
int ret;
-- 
2.3.5

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


Re: [PATCH] arm64/kvm: Add generic v8 KVM target

2015-07-17 Thread Chalamarla, Tirumalesh

 On Jul 17, 2015, at 3:19 AM, Marc Zyngier marc.zyng...@arm.com wrote:
 
 On 17/07/15 11:15, Christoffer Dall wrote:
 On Fri, Jul 17, 2015 at 10:56:39AM +0100, Marc Zyngier wrote:
 On 17/07/15 10:33, Christoffer Dall wrote:
 On Fri, Jul 03, 2015 at 11:10:09AM +0100, Marc Zyngier wrote:
 On 03/07/15 10:34, Peter Maydell wrote:
 On 3 July 2015 at 09:28, Marc Zyngier marc.zyng...@arm.com wrote:
 On 03/07/15 09:12, Peter Maydell wrote:
 I would still like to see the proponents of this patch say
 what their model is for userspace support of cross-host migration,
 if we're abandoning the model the current API envisages.
 
 I thought we had discussed this above, and don't really see this as a
 departure from the current model:
 
 - -cpu host results in GENERIC being used: VM can only be migrated
 to the exact same HW (no cross-host migration). MIDR should probably
 become RO.
 - -cpu host results in A57 (for example): VM can be migrated to a
 variety of A57 platforms, and allow for some fuzzing on the revision (or
 accept any revision).
 - -cpu a57 forces an A57 model to be emulated, always. It is always
 possible to migrate such a VM on any host.
 
 I think only the first point is new, but the last two are what we have
 (or what we should have).
 
 Right, but the implicit idea of this GENERIC patch seems to
 be that new host CPU types don't get their own KVM_ARM_TARGET_*
 constant, and are thus forever unable to do cross-host migration.
 It's not clear to me why we'd want to have new CPUs be second
 class citizens like that.
 
 I certainly don't want to see *any* CPU be a second class citizen. But
 let's face it, we're adding more and more targets that don't implement
 anything new, and just satisfy themselves with the generic implementation.
 
 I see it as an incentive to provide something useful (tables of all the
 registers with default values?) so that cross-host migration becomes a
 reality instead of the figment of our imagination (as it is now). If it
 wasn't already ABI, I'd have removed the existing targets until we have
 something meaningful to put there.
 
 What we're doing now certainly seems silly, because we're adding kernel
 patches without bringing anything to the table...
 
 
 Now, I also have my own doubts about cross-host migration (timers
 anyone?). But I don't see the above as a change in policy. More as a way
 to outline the fact that we currently don't have the right level of
 information/infrastructure to support it at all.
 
 The one thing that I've lost track of here (sorry) is whether we're
 enforcing the inability to do cross-host migration with the generic
 target when this patch is merged or do we leave this up to the graces of
 userspace?
 
 The jury is still out on that one.
 
 I was initially not going to enforce anything (after all, this isn't
 that different from the whole CNTVOFF story where we allow userspace to
 shoot itself in the foot), but I'm equally happy to make MIDR_EL1
 read-only if we're creating a generic guest...
 
 Looking at the code, midr_el1 is already an invariant register, so isn't
 this automagically enforced already?
 
 Ah, you're perfectly right, I has already in that fantasy world where we
 can actually migrate VMs across implementations.
 
 In that case, I'm fine with merging this patch.
 
 Cool. I'll queue that for 4.3.
 

this sounds nice. 
 Thanks,
 
   M.
 -- 
 Jazz is not dead. It just smells funny...

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


Re: [PATCH v2 04/10] KVM: arm/arm64: vgic: Allow HW irq to be encoded in LR

2015-07-17 Thread Christoffer Dall
On Wed, Jul 08, 2015 at 06:56:36PM +0100, Marc Zyngier wrote:
 Now that struct vgic_lr supports the LR_HW bit and carries a hwirq
 field, we can encode that information into the list registers.
 
 This patch provides implementations for both GICv2 and GICv3.
 
 Signed-off-by: Marc Zyngier marc.zyng...@arm.com
 ---
  include/linux/irqchip/arm-gic-v3.h |  3 +++
  include/linux/irqchip/arm-gic.h|  3 ++-
  virt/kvm/arm/vgic-v2.c | 16 +++-
  virt/kvm/arm/vgic-v3.c | 21 ++---
  4 files changed, 38 insertions(+), 5 deletions(-)
 
 diff --git a/include/linux/irqchip/arm-gic-v3.h 
 b/include/linux/irqchip/arm-gic-v3.h
 index ffbc034..cf637d6 100644
 --- a/include/linux/irqchip/arm-gic-v3.h
 +++ b/include/linux/irqchip/arm-gic-v3.h
 @@ -268,9 +268,12 @@
  
  #define ICH_LR_EOI   (1UL  41)
  #define ICH_LR_GROUP (1UL  60)
 +#define ICH_LR_HW(1UL  61)
  #define ICH_LR_STATE (3UL  62)
  #define ICH_LR_PENDING_BIT   (1UL  62)
  #define ICH_LR_ACTIVE_BIT(1UL  63)
 +#define ICH_LR_PHYS_ID_SHIFT 32
 +#define ICH_LR_PHYS_ID_MASK  (0x3ffUL  ICH_LR_PHYS_ID_SHIFT)
  
  #define ICH_MISR_EOI (1  0)
  #define ICH_MISR_U   (1  1)
 diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h
 index 9de976b..ca88dad 100644
 --- a/include/linux/irqchip/arm-gic.h
 +++ b/include/linux/irqchip/arm-gic.h
 @@ -71,11 +71,12 @@
  
  #define GICH_LR_VIRTUALID(0x3ff  0)
  #define GICH_LR_PHYSID_CPUID_SHIFT   (10)
 -#define GICH_LR_PHYSID_CPUID (7  GICH_LR_PHYSID_CPUID_SHIFT)
 +#define GICH_LR_PHYSID_CPUID (0x3ff  GICH_LR_PHYSID_CPUID_SHIFT)
  #define GICH_LR_STATE(3  28)
  #define GICH_LR_PENDING_BIT  (1  28)
  #define GICH_LR_ACTIVE_BIT   (1  29)
  #define GICH_LR_EOI  (1  19)
 +#define GICH_LR_HW   (1  31)
  
  #define GICH_VMCR_CTRL_SHIFT 0
  #define GICH_VMCR_CTRL_MASK  (0x21f  GICH_VMCR_CTRL_SHIFT)
 diff --git a/virt/kvm/arm/vgic-v2.c b/virt/kvm/arm/vgic-v2.c
 index f9b9c7c..8d7b04d 100644
 --- a/virt/kvm/arm/vgic-v2.c
 +++ b/virt/kvm/arm/vgic-v2.c
 @@ -48,6 +48,10 @@ static struct vgic_lr vgic_v2_get_lr(const struct kvm_vcpu 
 *vcpu, int lr)
   lr_desc.state |= LR_STATE_ACTIVE;
   if (val  GICH_LR_EOI)
   lr_desc.state |= LR_EOI_INT;
 + if (val  GICH_LR_HW) {
 + lr_desc.state |= LR_HW;
 + lr_desc.hwirq = (val  GICH_LR_PHYSID_CPUID)  
 GICH_LR_PHYSID_CPUID_SHIFT;
 + }
  
   return lr_desc;
  }
 @@ -55,7 +59,9 @@ static struct vgic_lr vgic_v2_get_lr(const struct kvm_vcpu 
 *vcpu, int lr)
  static void vgic_v2_set_lr(struct kvm_vcpu *vcpu, int lr,
  struct vgic_lr lr_desc)
  {
 - u32 lr_val = (lr_desc.source  GICH_LR_PHYSID_CPUID_SHIFT) | 
 lr_desc.irq;
 + u32 lr_val;
 +
 + lr_val = lr_desc.irq;
  
   if (lr_desc.state  LR_STATE_PENDING)
   lr_val |= GICH_LR_PENDING_BIT;
 @@ -64,6 +70,14 @@ static void vgic_v2_set_lr(struct kvm_vcpu *vcpu, int lr,
   if (lr_desc.state  LR_EOI_INT)
   lr_val |= GICH_LR_EOI;
  
 + if (lr_desc.state  LR_HW) {
 + lr_val |= GICH_LR_HW;
 + lr_val |= (u32)lr_desc.hwirq  GICH_LR_PHYSID_CPUID_SHIFT;
 + }
 +
 + if (lr_desc.irq  VGIC_NR_SGIS)
 + lr_val |= (lr_desc.source  GICH_LR_PHYSID_CPUID_SHIFT);
 +
   vcpu-arch.vgic_cpu.vgic_v2.vgic_lr[lr] = lr_val;
  }
  
 diff --git a/virt/kvm/arm/vgic-v3.c b/virt/kvm/arm/vgic-v3.c
 index dff0602..afbf925 100644
 --- a/virt/kvm/arm/vgic-v3.c
 +++ b/virt/kvm/arm/vgic-v3.c
 @@ -67,6 +67,10 @@ static struct vgic_lr vgic_v3_get_lr(const struct kvm_vcpu 
 *vcpu, int lr)
   lr_desc.state |= LR_STATE_ACTIVE;
   if (val  ICH_LR_EOI)
   lr_desc.state |= LR_EOI_INT;
 + if (val  ICH_LR_HW) {
 + lr_desc.state |= LR_HW;
 + lr_desc.hwirq = (val  ICH_LR_PHYS_ID_SHIFT)  GENMASK(9, 0);
 + }
  
   return lr_desc;
  }
 @@ -84,10 +88,17 @@ static void vgic_v3_set_lr(struct kvm_vcpu *vcpu, int lr,
* Eventually we want to make this configurable, so we may revisit
* this in the future.
*/
 - if (vcpu-kvm-arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3)
 + switch (vcpu-kvm-arch.vgic.vgic_model) {
 + case KVM_DEV_TYPE_ARM_VGIC_V3:
   lr_val |= ICH_LR_GROUP;
 - else
 - lr_val |= (u32)lr_desc.source  GICH_LR_PHYSID_CPUID_SHIFT;
 + break;
 + case  KVM_DEV_TYPE_ARM_VGIC_V2:
 + if (lr_desc.irq  VGIC_NR_SGIS)
 + lr_val |= (u32)lr_desc.source  
 GICH_LR_PHYSID_CPUID_SHIFT;

I forget how this works: Why are we mixing GICH_LR_ stuff with ICH_LR_
in the same function?  Aren't we always accessing these registers via
the system registers 

Re: [PATCH v2 10/10] KVM: arm/arm64: vgic: Allow non-shared device HW interrupts

2015-07-17 Thread Christoffer Dall
On Wed, Jul 08, 2015 at 06:56:42PM +0100, Marc Zyngier wrote:
 So far, the only use of the HW interrupt facility is the timer,
 implying that the active state is context-switched for each vcpu,
 as the device is is shared across all vcpus.
 
 This does not work for a device that has been assigned to a VM,
 as the guest is entierely in control of that device (the HW is
 not shared). In that case, it makes sense to bypass the whole
 active state switchint, and only track the deactivation of the

switching

 interrupt.
 
 Signed-off-by: Marc Zyngier marc.zyng...@arm.com
 ---
  include/kvm/arm_vgic.h|  5 ++--
  virt/kvm/arm/arch_timer.c |  2 +-
  virt/kvm/arm/vgic.c   | 62 
 ---
  3 files changed, 52 insertions(+), 17 deletions(-)
 
 diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
 index 9fd4023..31c987a 100644
 --- a/include/kvm/arm_vgic.h
 +++ b/include/kvm/arm_vgic.h
 @@ -163,7 +163,8 @@ struct irq_phys_map {
   u32 virt_irq;
   u32 phys_irq;
   u32 irq;
 - boolactive;
 + boolshared;
 + boolactive; /* Only valid if shared */
  };
  
  struct irq_phys_map_entry {
 @@ -354,7 +355,7 @@ void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
  int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
  int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
  struct irq_phys_map *vgic_map_phys_irq(struct kvm_vcpu *vcpu,
 -int virt_irq, int irq);
 +int virt_irq, int irq, bool shared);
  int vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, struct irq_phys_map *map);
  bool vgic_get_phys_irq_active(struct irq_phys_map *map);
  void vgic_set_phys_irq_active(struct irq_phys_map *map, bool active);
 diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
 index b9fff78..9544d79 100644
 --- a/virt/kvm/arm/arch_timer.c
 +++ b/virt/kvm/arm/arch_timer.c
 @@ -202,7 +202,7 @@ void kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
* Tell the VGIC that the virtual interrupt is tied to a
* physical interrupt. We do that once per VCPU.
*/
 - timer-map = vgic_map_phys_irq(vcpu, irq-irq, host_vtimer_irq);
 + timer-map = vgic_map_phys_irq(vcpu, irq-irq, host_vtimer_irq, true);
   WARN_ON(!timer-map);
  }
  
 diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
 index 39f9479..3585bb0 100644
 --- a/virt/kvm/arm/vgic.c
 +++ b/virt/kvm/arm/vgic.c
 @@ -1123,18 +1123,21 @@ static void vgic_queue_irq_to_lr(struct kvm_vcpu 
 *vcpu, int irq,
   map = vgic_irq_map_search(vcpu, irq);
  
   if (map) {
 - int ret;
 -
 - BUG_ON(!map-active);
   vlr.hwirq = map-phys_irq;
   vlr.state |= LR_HW;
   vlr.state = ~LR_EOI_INT;
  
 - ret = irq_set_irqchip_state(map-irq,
 - IRQCHIP_STATE_ACTIVE,
 - true);
   vgic_irq_set_queued(vcpu, irq);
 - WARN_ON(ret);
 +
 + if (map-shared) {
 + int ret;
 +
 + BUG_ON(!map-active);
 + ret = irq_set_irqchip_state(map-irq,
 + 
 IRQCHIP_STATE_ACTIVE,
 + true);
 + WARN_ON(ret);

do we have any other example of a shared device or is this really simply
because the timer hardware is fscking strangely tied to the gic and is a
total one-off?

In the latter case, would it be cleaner to drop this notion of a shared
device entirely and put all this logic in the arch timer code instead?

 + }
   }
   }
  
 @@ -1366,21 +1369,37 @@ static bool vgic_process_maintenance(struct kvm_vcpu 
 *vcpu)
  static int vgic_sync_hwirq(struct kvm_vcpu *vcpu, struct vgic_lr vlr)
  {
   struct irq_phys_map *map;
 + bool active;
   int ret;
  
   if (!(vlr.state  LR_HW))
   return 0;
  
   map = vgic_irq_map_search(vcpu, vlr.irq);
 - BUG_ON(!map || !map-active);
 + BUG_ON(!map);
 + BUG_ON(map-shared  !map-active);
  
   ret = irq_get_irqchip_state(map-irq,
   IRQCHIP_STATE_ACTIVE,
 - map-active);
 + active);
  
   WARN_ON(ret);
  
 - if (map-active) {
 + /*
 +  * For a non-shared interrupt, we have to catter for two

s/catter/cater/ ?

 +  * possible deactivation conditions

conditions:

 +  *
 +  * - the interrupt is now inactive
 +  * - the interrupt is still active, but is flagged as not
 +  *   queued, 

Re: [PATCH v2 02/10] arm/arm64: KVM: Move vgic handling to a non-preemptible section

2015-07-17 Thread Christoffer Dall
On Wed, Jul 08, 2015 at 06:56:34PM +0100, Marc Zyngier wrote:
 As we're about to introduce some serious GIC-poking to the vgic code,
 it is important to make sure that we're going to poke the part of
 the GIC that belongs to the CPU we're about to run on (otherwise,
 we'd end up with some unexpected interrupts firing)...
 
 Introducing a non-preemptible section in kvm_arch_vcpu_ioctl_run
 prevents the problem from occuring.
 
 Signed-off-by: Marc Zyngier marc.zyng...@arm.com
 Reviewed-by: Alex Bennée alex.ben...@linaro.org

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


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

2015-07-17 Thread Christoffer Dall
On Wed, Jul 08, 2015 at 06:56:39PM +0100, Marc Zyngier wrote:
 To allow a HW interrupt to be injected into a guest, we lookup the
 guest virtual interrupt in the irq_phys_map rbtree, and if we have

s/rbtree/list/

 a match, encode both interrupts in the LR.
 
 We also mark the interrupt as active at the host distributor level.
 
 On guest EOI on the virtual interrupt, the host interrupt will be
 deactivated.
 
 Signed-off-by: Marc Zyngier marc.zyng...@arm.com
 ---
  virt/kvm/arm/vgic.c | 72 
 ++---
  1 file changed, 69 insertions(+), 3 deletions(-)
 
 diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
 index 3424329..f8582d7 100644
 --- a/virt/kvm/arm/vgic.c
 +++ b/virt/kvm/arm/vgic.c
 @@ -1118,6 +1118,26 @@ static void vgic_queue_irq_to_lr(struct kvm_vcpu 
 *vcpu, int irq,
   if (!vgic_irq_is_edge(vcpu, irq))
   vlr.state |= LR_EOI_INT;
  
 + if (vlr.irq = VGIC_NR_SGIS) {
 + struct irq_phys_map *map;
 + map = vgic_irq_map_search(vcpu, irq);
 +
 + if (map) {
 + int ret;
 +
 + BUG_ON(!map-active);
 + vlr.hwirq = map-phys_irq;
 + vlr.state |= LR_HW;
 + vlr.state = ~LR_EOI_INT;
 +
 + ret = irq_set_irqchip_state(map-irq,
 + IRQCHIP_STATE_ACTIVE,
 + true);

So if we have a mapping, and the virtual interrupt is being injected,
then we must set the state to active in the physical world, because
otherwise the guest will just exit before processing the virtual
interrupt, yes?

I think this deserves a comment here.

 + vgic_irq_set_queued(vcpu, irq);

And we set it queued only to avoid sampling it again and setting
PENDING+ACTIVE, because the hardware doesn't support setting that state
when the HW bit is set, yes?

I think a comment here is warranted too.

 + WARN_ON(ret);
 + }
 + }
 +
   vgic_set_lr(vcpu, lr_nr, vlr);
   vgic_sync_lr_elrsr(vcpu, lr_nr, vlr);
  }
 @@ -1342,6 +1362,35 @@ static bool vgic_process_maintenance(struct kvm_vcpu 
 *vcpu)
   return level_pending;
  }
  
 +/* Return 1 if HW interrupt went from active to inactive, and 0 otherwise */

... also clear the active state on the physical distributor so that
shared devices can be used in a different context. (did I get this
right?)

 +static int vgic_sync_hwirq(struct kvm_vcpu *vcpu, struct vgic_lr vlr)
 +{
 + struct irq_phys_map *map;
 + int ret;
 +
 + if (!(vlr.state  LR_HW))
 + return 0;
 +
 + map = vgic_irq_map_search(vcpu, vlr.irq);
 + BUG_ON(!map || !map-active);
 +
 + ret = irq_get_irqchip_state(map-irq,
 + IRQCHIP_STATE_ACTIVE,
 + map-active);
 +
 + WARN_ON(ret);
 +
 + if (map-active) {
 + ret = irq_set_irqchip_state(map-irq,
 + IRQCHIP_STATE_ACTIVE,
 + false);
 + WARN_ON(ret);
 + return 0;
 + }
 +
 + return 1;
 +}
 +
  /* Sync back the VGIC state after a guest run */
  static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
  {
 @@ -1356,14 +1405,31 @@ static void __kvm_vgic_sync_hwstate(struct kvm_vcpu 
 *vcpu)
   elrsr = vgic_get_elrsr(vcpu);
   elrsr_ptr = u64_to_bitmask(elrsr);
  
 - /* Clear mappings for empty LRs */
 - for_each_set_bit(lr, elrsr_ptr, vgic-nr_lr) {
 + /* Deal with HW interrupts, and clear mappings for empty LRs */
 + for (lr = 0; lr  vgic-nr_lr; lr++) {
   struct vgic_lr vlr;
  
 - if (!test_and_clear_bit(lr, vgic_cpu-lr_used))
 + if (!test_bit(lr, vgic_cpu-lr_used))
   continue;
  
   vlr = vgic_get_lr(vcpu, lr);
 + if (vgic_sync_hwirq(vcpu, vlr)) {
 + /*
 +  * So this is a HW interrupt that the guest
 +  * EOI-ed. Clean the LR state and allow the
 +  * interrupt to be queued again.

s/queued/sampled/ ?

 +  */
 + vlr.state = 0;
 + vlr.hwirq = 0;
 + vgic_set_lr(vcpu, lr, vlr);
 + vgic_irq_clear_queued(vcpu, vlr.irq);
 + set_bit(lr, elrsr_ptr);
 + }
 +
 + if (!test_bit(lr, elrsr_ptr))
 + continue;
 +
 + clear_bit(lr, vgic_cpu-lr_used);
  
   BUG_ON(vlr.irq = dist-nr_irqs);
   vgic_cpu-vgic_irq_lr_map[vlr.irq] = LR_EMPTY;
 -- 
 2.1.4
 
Thanks,
-Christoffer
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  

Re: [PATCH v2 05/10] KVM: arm/arm64: vgic: Relax vgic_can_sample_irq for edge IRQs

2015-07-17 Thread Christoffer Dall
On Wed, Jul 08, 2015 at 06:56:37PM +0100, Marc Zyngier wrote:
 We only set the irq_queued flag for level interrupts, meaning
 that !vgic_irq_is_queued(vcpu, irq) is a good enough predicate
 for all interrupts.
 
 This will allow us to inject edge HW interrupts, for which the
 state ACTIVE+PENDING is not allowed.
 
 Signed-off-by: Marc Zyngier marc.zyng...@arm.com
 ---
  virt/kvm/arm/vgic.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
 index bc40137..5bd1695 100644
 --- a/virt/kvm/arm/vgic.c
 +++ b/virt/kvm/arm/vgic.c
 @@ -375,7 +375,7 @@ void vgic_cpu_irq_clear(struct kvm_vcpu *vcpu, int irq)
  
  static bool vgic_can_sample_irq(struct kvm_vcpu *vcpu, int irq)
  {
 - return vgic_irq_is_edge(vcpu, irq) || !vgic_irq_is_queued(vcpu, irq);
 + return !vgic_irq_is_queued(vcpu, irq);
  }
  
  /**
 -- 
 2.1.4
 
Reviewed-by: Christoffer Dall christoffer.d...@linaro.org
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


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

2015-07-17 Thread Christoffer Dall
On Wed, Jul 08, 2015 at 06:56:35PM +0100, Marc Zyngier wrote:
 As we're about to cram more information in the vgic_lr structure
 (HW interrupt number and additional state information), we switch
 to a layout similar to the HW's:
 
 - use bitfields to save space (we don't need more than 10 bits
   to represent the irq numbers)
 - source CPU and HW interrupt can share the same field, as
   a SGI doesn't have a physical line.
 
 Signed-off-by: Marc Zyngier marc.zyng...@arm.com
 Reviewed-by: Alex Bennée alex.ben...@linaro.org
 ---
  include/kvm/arm_vgic.h | 10 +++---
  1 file changed, 7 insertions(+), 3 deletions(-)
 
 diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
 index 133ea00..4f9fa1d 100644
 --- a/include/kvm/arm_vgic.h
 +++ b/include/kvm/arm_vgic.h
 @@ -95,11 +95,15 @@ enum vgic_type {
  #define LR_STATE_ACTIVE  (1  1)
  #define LR_STATE_MASK(3  0)
  #define LR_EOI_INT   (1  2)
 +#define LR_HW(1  3)
  
  struct vgic_lr {
 - u16 irq;
 - u8  source;
 - u8  state;
 + unsigned irq:10;
 + union {
 + unsigned hwirq:10;
 + unsigned source:8;

why 8?  why not 3?

 + };
 + unsigned state:4;
  };
  
  struct vgic_vmcr {
 -- 
 2.1.4
 

otherwise:

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


Re: [PATCH v2 08/10] KVM: arm/arm64: vgic: Add vgic_{get,set}_phys_irq_active

2015-07-17 Thread Christoffer Dall
On Wed, Jul 08, 2015 at 06:56:40PM +0100, Marc Zyngier wrote:
 In order to control the active state of an interrupt, introduce
 a pair of accessors allowing the state to be set/queried.
 
 This only affects the logical state, and the HW state will only be
 applied at world-switch time.
 
 Signed-off-by: Marc Zyngier marc.zyng...@arm.com

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


Re: [PATCH v2 09/10] KVM: arm/arm64: timer: Allow the timer to control the active state

2015-07-17 Thread Christoffer Dall
On Wed, Jul 08, 2015 at 06:56:41PM +0100, Marc Zyngier wrote:
 In order to remove the crude hack where we sneak the masked bit
 into the timer's control register, make use of the phys_irq_map
 API control the active state of the interrupt.
 
 Signed-off-by: Marc Zyngier marc.zyng...@arm.com

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


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

2015-07-17 Thread Christoffer Dall
On Wed, Jul 08, 2015 at 06:56:38PM +0100, Marc Zyngier wrote:
 In order to be able to feed physical interrupts to a guest, we need
 to be able to establish the virtual-physical mapping between the two
 worlds.
 
 The mappings are kept in a set of RCU lists, indexed by virtual interrupts.
 
 Signed-off-by: Marc Zyngier marc.zyng...@arm.com
 ---
  arch/arm/kvm/arm.c |   2 +
  include/kvm/arm_vgic.h |  25 +
  virt/kvm/arm/vgic.c| 144 
 -
  3 files changed, 170 insertions(+), 1 deletion(-)
 
 diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
 index 1583a34..d5ce5cc 100644
 --- a/arch/arm/kvm/arm.c
 +++ b/arch/arm/kvm/arm.c
 @@ -125,6 +125,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
   if (ret)
   goto out_free_stage2_pgd;
  
 + kvm_vgic_init(kvm);
   kvm_timer_init(kvm);
  
   /* Mark the initial VMID generation invalid */
 @@ -249,6 +250,7 @@ out:
  
  void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
  {
 + kvm_vgic_vcpu_postcreate(vcpu);
  }
  
  void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
 diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
 index 4f9fa1d..32e57d2 100644
 --- a/include/kvm/arm_vgic.h
 +++ b/include/kvm/arm_vgic.h
 @@ -159,6 +159,19 @@ struct vgic_io_device {
   struct kvm_io_device dev;
  };
  
 +struct irq_phys_map {
 + u32 virt_irq;
 + u32 phys_irq;
 + u32 irq;
 + boolactive;
 +};
 +
 +struct irq_phys_map_entry {
 + struct list_headentry;
 + struct rcu_head rcu;
 + struct irq_phys_map map;
 +};
 +
  struct vgic_dist {
   spinlock_t  lock;
   boolin_kernel;
 @@ -256,6 +269,10 @@ struct vgic_dist {
   struct vgic_vm_ops  vm_ops;
   struct vgic_io_device   dist_iodev;
   struct vgic_io_device   *redist_iodevs;
 +
 + /* Virtual irq to hwirq mapping */
 + spinlock_t  irq_phys_map_lock;
 + struct list_headirq_phys_map_list;
  };
  
  struct vgic_v2_cpu_if {
 @@ -307,6 +324,9 @@ struct vgic_cpu {
   struct vgic_v2_cpu_if   vgic_v2;
   struct vgic_v3_cpu_if   vgic_v3;
   };
 +
 + /* Protected by the distributor's irq_phys_map_lock */
 + struct list_headirq_phys_map_list;
  };
  
  #define LR_EMPTY 0xff
 @@ -321,8 +341,10 @@ int kvm_vgic_addr(struct kvm *kvm, unsigned long type, 
 u64 *addr, bool write);
  int kvm_vgic_hyp_init(void);
  int kvm_vgic_map_resources(struct kvm *kvm);
  int kvm_vgic_get_max_vcpus(void);
 +void kvm_vgic_init(struct kvm *kvm);
  int kvm_vgic_create(struct kvm *kvm, u32 type);
  void kvm_vgic_destroy(struct kvm *kvm);
 +void kvm_vgic_vcpu_postcreate(struct kvm_vcpu *vcpu);
  void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu);
  void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu);
  void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu);
 @@ -331,6 +353,9 @@ int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, 
 unsigned int irq_num,
  void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
  int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
  int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
 +struct irq_phys_map *vgic_map_phys_irq(struct kvm_vcpu *vcpu,
 +int virt_irq, int irq);
 +int vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, struct irq_phys_map *map);

should these functions not have a kvm_ prefix?

  
  #define irqchip_in_kernel(k) (!!((k)-arch.vgic.in_kernel))
  #define vgic_initialized(k)  (!!((k)-arch.vgic.nr_cpus))
 diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
 index 5bd1695..3424329 100644
 --- a/virt/kvm/arm/vgic.c
 +++ b/virt/kvm/arm/vgic.c
 @@ -24,6 +24,7 @@
  #include linux/of.h
  #include linux/of_address.h
  #include linux/of_irq.h
 +#include linux/rculist.h
  #include linux/uaccess.h
  
  #include asm/kvm_emulate.h
 @@ -82,6 +83,8 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu 
 *vcpu);
  static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu);
  static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr);
  static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr, struct vgic_lr 
 lr_desc);
 +static struct irq_phys_map *vgic_irq_map_search(struct kvm_vcpu *vcpu,
 + int virt_irq);
  
  static const struct vgic_ops *vgic_ops;
  static const struct vgic_params *vgic;
 @@ -1583,6 +1586,131 @@ static irqreturn_t vgic_maintenance_handler(int irq, 
 void *data)
   return IRQ_HANDLED;
  }
  
 +static struct list_head *vgic_get_irq_phys_map(struct kvm_vcpu *vcpu,
 +int virt_irq)
 +{
 + if (virt_irq  VGIC_NR_PRIVATE_IRQS)
 + return vcpu-arch.vgic_cpu.irq_phys_map_list;
 + else
 + return vcpu-kvm-arch.vgic.irq_phys_map_list;
 +}
 +

You know what I'm going to ask you