Re: [Qemu-devel] [kvm-unit-tests PATCH v11 1/3] arm: Add PMU test

2016-11-23 Thread Wei Huang


On 11/23/2016 11:15 AM, Andrew Jones wrote:
> On Wed, Nov 23, 2016 at 01:16:08PM +, Andre Przywara wrote:
>> Hi,
>>
>> On 22/11/16 18:29, Wei Huang wrote:
>>> From: Christopher Covington 
>>>
>>> Beginning with a simple sanity check of the control register, add
>>> a unit test for the ARM Performance Monitors Unit (PMU).
>>
>> Mmh, the output of this is a bit confusing. How about to join some
>> information? I changed it to give me:
>> INFO: pmu: PMU implementer/ID code: "A"(0x41)/0x0
>> INFO: pmu: Event counters:  0
>> PASS: pmu: Control register
>>
>> ... by using the newly introduced report_info() to make it look nicer.
> 
> Agreed. That would look nicer and make good use of report_info. Let's
> do that.

I have adjusted v12 using report_info(), with all PMU PMCR fields
printed in the same line. Implementer info was printed with Hex first,
then ASCII representation, to match MIDR table in ARM manual:

INFO: pmu: PMU implementer/ID code/counters: 0x41("A")/0x1/6


> 
>>
>>>
>>> Signed-off-by: Christopher Covington 
>>> Signed-off-by: Wei Huang 
>>> Reviewed-by: Andrew Jones 
>>> ---
>>>  arm/Makefile.common |  3 ++-
>>>  arm/pmu.c   | 74 
>>> +
>>>  arm/unittests.cfg   |  5 
>>>  3 files changed, 81 insertions(+), 1 deletion(-)
>>>  create mode 100644 arm/pmu.c
>>>
>>> diff --git a/arm/Makefile.common b/arm/Makefile.common
>>> index f37b5c2..5da2fdd 100644
>>> --- a/arm/Makefile.common
>>> +++ b/arm/Makefile.common
>>> @@ -12,7 +12,8 @@ endif
>>>  tests-common = \
>>> $(TEST_DIR)/selftest.flat \
>>> $(TEST_DIR)/spinlock-test.flat \
>>> -   $(TEST_DIR)/pci-test.flat
>>> +   $(TEST_DIR)/pci-test.flat \
>>> +   $(TEST_DIR)/pmu.flat
>>>  
>>>  all: test_cases
>>>  
>>> diff --git a/arm/pmu.c b/arm/pmu.c
>>> new file mode 100644
>>> index 000..9d9c53b
>>> --- /dev/null
>>> +++ b/arm/pmu.c
>>> @@ -0,0 +1,74 @@
>>> +/*
>>> + * Test the ARM Performance Monitors Unit (PMU).
>>> + *
>>> + * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
>>> + *
>>> + * This program is free software; you can redistribute it and/or modify it
>>> + * under the terms of the GNU Lesser General Public License version 2.1 and
>>> + * only version 2.1 as published by the Free Software Foundation.
>>> + *
>>> + * This program is distributed in the hope that it will be useful, but 
>>> WITHOUT
>>> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
>>> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
>>> License
>>> + * for more details.
>>> + */
>>> +#include "libcflat.h"
>>> +#include "asm/barrier.h"
>>> +
>>> +#define PMU_PMCR_N_SHIFT   11
>>> +#define PMU_PMCR_N_MASK0x1f
>>> +#define PMU_PMCR_ID_SHIFT  16
>>> +#define PMU_PMCR_ID_MASK   0xff
>>> +#define PMU_PMCR_IMP_SHIFT 24
>>> +#define PMU_PMCR_IMP_MASK  0xff
>>> +
>>> +#if defined(__arm__)
>>
>> I guess you should use the arch specific header files we have in place
>> for that (lib/arm{.64}/asm/processor.h). Also there are sysreg read
>> wrappers (at least for arm64) in there already, can't we base this
>> function on them: DEFINE_GET_SYSREG32(pmcr, el0)?
>> (Requires a small change to get rid of the forced "_el1" suffix)
>>
>> We should wait for the GIC series to be merged, as this contains some
>> changes in this area.
> 
> As this unit test is the only consumer of PMC registers so far, then
> I'd prefer the defines and accessors stay here for now. Once we see
> a use in other unit tests then we can move some of it out.

I left accessors in-place. We can always come back to refactor them later.

> 
>>
>>> +static inline uint32_t pmcr_read(void)
>>> +{
>>> +   uint32_t ret;
>>> +
>>> +   asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (ret));
>>> +   return ret;
>>> +}
>>> +#elif defined(__aarch64__)
>>> +static inline uint32_t pmcr_read(void)
>>> +{
>>> +   uint32_t ret;
>>> +
>>> +   asm volatile("mrs %0, pmcr_el0" : "=r" (ret));
>>> +   return ret;
>>> +}
>>> +#endif
>>> +
>>> +/*
>>> + * As a simple sanity check on the PMCR_EL0, ensure the implementer field 
>>> isn't
>>> + * null. Also print out a couple other interesting fields for diagnostic
>>> + * purposes. For example, as of fall 2016, QEMU TCG mode doesn't implement
>>> + * event counters and therefore reports zero event counters, but hopefully
>>> + * support for at least the instructions event will be added in the future 
>>> and
>>> + * the reported number of event counters will become nonzero.
>>> + */
>>> +static bool check_pmcr(void)
>>> +{
>>> +   uint32_t pmcr;
>>> +
>>> +   pmcr = pmcr_read();
>>> +
>>> +   printf("PMU implementer: %c\n",
>>> +  (pmcr >> PMU_PMCR_IMP_SHIFT) & PMU_PMCR_IMP_MASK);
>>
>> If this register reads as zero, the output is mangled (since it cuts off
>> the string before the newline):
>> =
>> PMU implementer: Identification code: 

[kvm-unit-tests PATCH v12 3/3] arm: pmu: Add CPI checking

2016-11-23 Thread Wei Huang
From: Christopher Covington 

Calculate the numbers of cycles per instruction (CPI) implied by ARM
PMU cycle counter values. The code includes a strict checking facility
intended for the -icount option in TCG mode in the configuration file.

Signed-off-by: Christopher Covington 
Signed-off-by: Wei Huang 
Reviewed-by: Andrew Jones 
---
 arm/pmu.c | 123 +-
 arm/unittests.cfg |  14 +++
 2 files changed, 136 insertions(+), 1 deletion(-)

diff --git a/arm/pmu.c b/arm/pmu.c
index 3ae6545..f05d00d 100644
--- a/arm/pmu.c
+++ b/arm/pmu.c
@@ -104,6 +104,27 @@ static inline uint32_t id_dfr0_read(void)
asm volatile("mrc p15, 0, %0, c0, c1, 2" : "=r" (val));
return val;
 }
+
+/*
+ * Extra instructions inserted by the compiler would be difficult to compensate
+ * for, so hand assemble everything between, and including, the PMCR accesses
+ * to start and stop counting. isb instructions were inserted to make sure
+ * pmccntr read after this function returns the exact instructions executed in
+ * the controlled block. Total instrs = isb + mcr + 2*loop = 2 + 2*loop.
+ */
+static inline void precise_instrs_loop(int loop, uint32_t pmcr)
+{
+   asm volatile(
+   "   mcr p15, 0, %[pmcr], c9, c12, 0\n"
+   "   isb\n"
+   "1: subs%[loop], %[loop], #1\n"
+   "   bgt 1b\n"
+   "   mcr p15, 0, %[z], c9, c12, 0\n"
+   "   isb\n"
+   : [loop] "+r" (loop)
+   : [pmcr] "r" (pmcr), [z] "r" (0)
+   : "cc");
+}
 #elif defined(__aarch64__)
 static inline uint32_t pmcr_read(void)
 {
@@ -150,6 +171,27 @@ static inline uint32_t id_dfr0_read(void)
asm volatile("mrs %0, id_dfr0_el1" : "=r" (id));
return id;
 }
+
+/*
+ * Extra instructions inserted by the compiler would be difficult to compensate
+ * for, so hand assemble everything between, and including, the PMCR accesses
+ * to start and stop counting. isb instructions are inserted to make sure
+ * pmccntr read after this function returns the exact instructions executed
+ * in the controlled block. Total instrs = isb + msr + 2*loop = 2 + 2*loop.
+ */
+static inline void precise_instrs_loop(int loop, uint32_t pmcr)
+{
+   asm volatile(
+   "   msr pmcr_el0, %[pmcr]\n"
+   "   isb\n"
+   "1: subs%[loop], %[loop], #1\n"
+   "   b.gt1b\n"
+   "   msr pmcr_el0, xzr\n"
+   "   isb\n"
+   : [loop] "+r" (loop)
+   : [pmcr] "r" (pmcr)
+   : "cc");
+}
 #endif
 
 /*
@@ -207,6 +249,79 @@ static bool check_cycles_increase(void)
return success;
 }
 
+/*
+ * Execute a known number of guest instructions. Only even instruction counts
+ * greater than or equal to 4 are supported by the in-line assembly code. The
+ * control register (PMCR_EL0) is initialized with the provided value (allowing
+ * for example for the cycle counter or event counters to be reset). At the end
+ * of the exact instruction loop, zero is written to PMCR_EL0 to disable
+ * counting, allowing the cycle counter or event counters to be read at the
+ * leisure of the calling code.
+ */
+static void measure_instrs(int num, uint32_t pmcr)
+{
+   int loop = (num - 2) / 2;
+
+   assert(num >= 4 && ((num - 2) % 2 == 0));
+   precise_instrs_loop(loop, pmcr);
+}
+
+/*
+ * Measure cycle counts for various known instruction counts. Ensure that the
+ * cycle counter progresses (similar to check_cycles_increase() but with more
+ * instructions and using reset and stop controls). If supplied a positive,
+ * nonzero CPI parameter, also strictly check that every measurement matches
+ * it. Strict CPI checking is used to test -icount mode.
+ */
+static bool check_cpi(int cpi)
+{
+   uint32_t pmcr = pmcr_read() | PMU_PMCR_LC | PMU_PMCR_C | PMU_PMCR_E;
+
+   /* init before event access, this test only cares about cycle count */
+   pmcntenset_write(1 << PMU_CYCLE_IDX);
+   pmccfiltr_write(0); /* count cycles in EL0, EL1, but not EL2 */
+
+   if (cpi > 0)
+   printf("Checking for CPI=%d.\n", cpi);
+   printf("instrs : cycles0 cycles1 ...\n");
+
+   for (unsigned int i = 4; i < 300; i += 32) {
+   uint64_t avg, sum = 0;
+
+   printf("%d :", i);
+   for (int j = 0; j < NR_SAMPLES; j++) {
+   uint64_t cycles;
+
+   pmccntr_write(0);
+   measure_instrs(i, pmcr);
+   cycles = pmccntr_read();
+   printf(" %"PRId64"", cycles);
+
+   if (!cycles) {
+   printf("\ncycles not incrementing!\n");
+   return false;
+   } else if (cpi > 0 && cycles != i * cpi) {
+   printf("\nunexpected cycle count received!\n");
+

[kvm-unit-tests PATCH v12 2/3] arm: pmu: Check cycle count increases

2016-11-23 Thread Wei Huang
From: Christopher Covington 

Ensure that reads of the PMCCNTR_EL0 are monotonically increasing,
even for the smallest delta of two subsequent reads.

Signed-off-by: Christopher Covington 
Signed-off-by: Wei Huang 
Reviewed-by: Andrew Jones 
---
 arm/pmu.c | 156 ++
 1 file changed, 156 insertions(+)

diff --git a/arm/pmu.c b/arm/pmu.c
index 98ebea4..3ae6545 100644
--- a/arm/pmu.c
+++ b/arm/pmu.c
@@ -15,6 +15,9 @@
 #include "libcflat.h"
 #include "asm/barrier.h"
 
+#define PMU_PMCR_E (1 << 0)
+#define PMU_PMCR_C (1 << 2)
+#define PMU_PMCR_LC(1 << 6)
 #define PMU_PMCR_N_SHIFT   11
 #define PMU_PMCR_N_MASK0x1f
 #define PMU_PMCR_ID_SHIFT  16
@@ -22,6 +25,14 @@
 #define PMU_PMCR_IMP_SHIFT 24
 #define PMU_PMCR_IMP_MASK  0xff
 
+#define ID_DFR0_PERFMON_SHIFT 24
+#define ID_DFR0_PERFMON_MASK  0xf
+
+#define PMU_CYCLE_IDX 31
+
+#define NR_SAMPLES 10
+
+static unsigned int pmu_version;
 #if defined(__arm__)
 static inline uint32_t pmcr_read(void)
 {
@@ -30,6 +41,69 @@ static inline uint32_t pmcr_read(void)
asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (ret));
return ret;
 }
+
+static inline void pmcr_write(uint32_t value)
+{
+   asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r" (value));
+   isb();
+}
+
+static inline void pmselr_write(uint32_t value)
+{
+   asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (value));
+   isb();
+}
+
+static inline void pmxevtyper_write(uint32_t value)
+{
+   asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (value));
+}
+
+static inline uint64_t pmccntr_read(void)
+{
+   uint32_t lo, hi = 0;
+
+   if (pmu_version == 0x3)
+   asm volatile("mrrc p15, 0, %0, %1, c9" : "=r" (lo), "=r" (hi));
+   else
+   asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (lo));
+
+   return ((uint64_t)hi << 32) | lo;
+}
+
+static inline void pmccntr_write(uint64_t value)
+{
+   uint32_t lo, hi;
+
+   lo = value & 0x;
+   hi = (value >> 32) & 0x;
+
+   if (pmu_version == 0x3)
+   asm volatile("mcrr p15, 0, %0, %1, c9" : : "r" (lo), "r" (hi));
+   else
+   asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (lo));
+}
+
+static inline void pmcntenset_write(uint32_t value)
+{
+   asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (value));
+}
+
+/* PMCCFILTR is an obsolete name for PMXEVTYPER31 in ARMv7 */
+static inline void pmccfiltr_write(uint32_t value)
+{
+   pmselr_write(PMU_CYCLE_IDX);
+   pmxevtyper_write(value);
+   isb();
+}
+
+static inline uint32_t id_dfr0_read(void)
+{
+   uint32_t val;
+
+   asm volatile("mrc p15, 0, %0, c0, c1, 2" : "=r" (val));
+   return val;
+}
 #elif defined(__aarch64__)
 static inline uint32_t pmcr_read(void)
 {
@@ -38,6 +112,44 @@ static inline uint32_t pmcr_read(void)
asm volatile("mrs %0, pmcr_el0" : "=r" (ret));
return ret;
 }
+
+static inline void pmcr_write(uint32_t value)
+{
+   asm volatile("msr pmcr_el0, %0" : : "r" (value));
+   isb();
+}
+
+static inline uint64_t pmccntr_read(void)
+{
+   uint64_t cycles;
+
+   asm volatile("mrs %0, pmccntr_el0" : "=r" (cycles));
+   return cycles;
+}
+
+static inline void pmccntr_write(uint64_t value)
+{
+   asm volatile("msr pmccntr_el0, %0" : : "r" (value));
+}
+
+static inline void pmcntenset_write(uint32_t value)
+{
+   asm volatile("msr pmcntenset_el0, %0" : : "r" (value));
+}
+
+static inline void pmccfiltr_write(uint32_t value)
+{
+   asm volatile("msr pmccfiltr_el0, %0" : : "r" (value));
+   isb();
+}
+
+static inline uint32_t id_dfr0_read(void)
+{
+   uint32_t id;
+
+   asm volatile("mrs %0, id_dfr0_el1" : "=r" (id));
+   return id;
+}
 #endif
 
 /*
@@ -63,11 +175,55 @@ static bool check_pmcr(void)
return ((pmcr >> PMU_PMCR_IMP_SHIFT) & PMU_PMCR_IMP_MASK) != 0;
 }
 
+/*
+ * Ensure that the cycle counter progresses between back-to-back reads.
+ */
+static bool check_cycles_increase(void)
+{
+   bool success = true;
+
+   /* init before event access, this test only cares about cycle count */
+   pmcntenset_write(1 << PMU_CYCLE_IDX);
+   pmccfiltr_write(0); /* count cycles in EL0, EL1, but not EL2 */
+   pmccntr_write(0);
+
+   pmcr_write(pmcr_read() | PMU_PMCR_LC | PMU_PMCR_C | PMU_PMCR_E);
+
+   for (int i = 0; i < NR_SAMPLES; i++) {
+   uint64_t a, b;
+
+   a = pmccntr_read();
+   b = pmccntr_read();
+
+   if (a >= b) {
+   printf("Read %"PRId64" then %"PRId64".\n", a, b);
+   success = false;
+   break;
+   }
+   }
+
+   pmcr_write(pmcr_read() & ~PMU_PMCR_E);
+
+   return success;
+}
+
+void pmu_init(void)
+{
+   uint32_t dfr0;
+
+   /* probe pmu 

[kvm-unit-tests PATCH v12 1/3] arm: Add PMU test

2016-11-23 Thread Wei Huang
From: Christopher Covington 

Beginning with a simple sanity check of the control register, add
a unit test for the ARM Performance Monitors Unit (PMU).

Signed-off-by: Christopher Covington 
Signed-off-by: Wei Huang 
---
 arm/Makefile.common |  3 ++-
 arm/pmu.c   | 73 +
 arm/unittests.cfg   |  5 
 3 files changed, 80 insertions(+), 1 deletion(-)
 create mode 100644 arm/pmu.c

diff --git a/arm/Makefile.common b/arm/Makefile.common
index f37b5c2..5da2fdd 100644
--- a/arm/Makefile.common
+++ b/arm/Makefile.common
@@ -12,7 +12,8 @@ endif
 tests-common = \
$(TEST_DIR)/selftest.flat \
$(TEST_DIR)/spinlock-test.flat \
-   $(TEST_DIR)/pci-test.flat
+   $(TEST_DIR)/pci-test.flat \
+   $(TEST_DIR)/pmu.flat
 
 all: test_cases
 
diff --git a/arm/pmu.c b/arm/pmu.c
new file mode 100644
index 000..98ebea4
--- /dev/null
+++ b/arm/pmu.c
@@ -0,0 +1,73 @@
+/*
+ * Test the ARM Performance Monitors Unit (PMU).
+ *
+ * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License version 2.1 and
+ * only version 2.1 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ */
+#include "libcflat.h"
+#include "asm/barrier.h"
+
+#define PMU_PMCR_N_SHIFT   11
+#define PMU_PMCR_N_MASK0x1f
+#define PMU_PMCR_ID_SHIFT  16
+#define PMU_PMCR_ID_MASK   0xff
+#define PMU_PMCR_IMP_SHIFT 24
+#define PMU_PMCR_IMP_MASK  0xff
+
+#if defined(__arm__)
+static inline uint32_t pmcr_read(void)
+{
+   uint32_t ret;
+
+   asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (ret));
+   return ret;
+}
+#elif defined(__aarch64__)
+static inline uint32_t pmcr_read(void)
+{
+   uint32_t ret;
+
+   asm volatile("mrs %0, pmcr_el0" : "=r" (ret));
+   return ret;
+}
+#endif
+
+/*
+ * As a simple sanity check on the PMCR_EL0, ensure the implementer field isn't
+ * null. Also print out a couple other interesting fields for diagnostic
+ * purposes. For example, as of fall 2016, QEMU TCG mode doesn't implement
+ * event counters and therefore reports zero event counters, but hopefully
+ * support for at least the instructions event will be added in the future and
+ * the reported number of event counters will become nonzero.
+ */
+static bool check_pmcr(void)
+{
+   uint32_t pmcr;
+
+   pmcr = pmcr_read();
+
+   report_info("PMU implementer/ID code/counters: 0x%x(\"%c\")/0x%x/%d",
+   (pmcr >> PMU_PMCR_IMP_SHIFT) & PMU_PMCR_IMP_MASK,
+   ((pmcr >> PMU_PMCR_IMP_SHIFT) & PMU_PMCR_IMP_MASK) ? : ' ',
+   (pmcr >> PMU_PMCR_ID_SHIFT) & PMU_PMCR_ID_MASK,
+   (pmcr >> PMU_PMCR_N_SHIFT) & PMU_PMCR_N_MASK);
+
+   return ((pmcr >> PMU_PMCR_IMP_SHIFT) & PMU_PMCR_IMP_MASK) != 0;
+}
+
+int main(void)
+{
+   report_prefix_push("pmu");
+
+   report("Control register", check_pmcr());
+
+   return report_summary();
+}
diff --git a/arm/unittests.cfg b/arm/unittests.cfg
index ae32a42..816f494 100644
--- a/arm/unittests.cfg
+++ b/arm/unittests.cfg
@@ -58,3 +58,8 @@ groups = selftest
 [pci-test]
 file = pci-test.flat
 groups = pci
+
+# Test PMU support
+[pmu]
+file = pmu.flat
+groups = pmu
-- 
1.8.3.1

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


[kvm-unit-tests PATCH v12 0/3] ARM PMU tests

2016-11-23 Thread Wei Huang
Changes from v11:
* Use report_info() to report PMU HW related info (implementer, id code, ...)
* Print PMU PMCR info in the same line

Note:
1) Current KVM code has bugs in handling PMCCFILTR write. A fix (see
below) is required for this unit testing code to work correctly under
KVM mode.
https://lists.cs.columbia.edu/pipermail/kvmarm/2016-November/022134.html.

Thanks,
-Wei

Christopher Covington (3):
  arm: Add PMU test
  arm: pmu: Check cycle count increases
  arm: pmu: Add CPI checking

 arm/Makefile.common |   3 +-
 arm/pmu.c   | 350 
 arm/unittests.cfg   |  19 +++
 3 files changed, 371 insertions(+), 1 deletion(-)
 create mode 100644 arm/pmu.c

-- 
1.8.3.1

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


Re: [Qemu-devel] [kvm-unit-tests PATCH v11 1/3] arm: Add PMU test

2016-11-23 Thread Andrew Jones
On Wed, Nov 23, 2016 at 01:16:08PM +, Andre Przywara wrote:
> Hi,
> 
> On 22/11/16 18:29, Wei Huang wrote:
> > From: Christopher Covington 
> > 
> > Beginning with a simple sanity check of the control register, add
> > a unit test for the ARM Performance Monitors Unit (PMU).
> 
> Mmh, the output of this is a bit confusing. How about to join some
> information? I changed it to give me:
> INFO: pmu: PMU implementer/ID code: "A"(0x41)/0x0
> INFO: pmu: Event counters:  0
> PASS: pmu: Control register
> 
> ... by using the newly introduced report_info() to make it look nicer.

Agreed. That would look nicer and make good use of report_info. Let's
do that.

> 
> > 
> > Signed-off-by: Christopher Covington 
> > Signed-off-by: Wei Huang 
> > Reviewed-by: Andrew Jones 
> > ---
> >  arm/Makefile.common |  3 ++-
> >  arm/pmu.c   | 74 
> > +
> >  arm/unittests.cfg   |  5 
> >  3 files changed, 81 insertions(+), 1 deletion(-)
> >  create mode 100644 arm/pmu.c
> > 
> > diff --git a/arm/Makefile.common b/arm/Makefile.common
> > index f37b5c2..5da2fdd 100644
> > --- a/arm/Makefile.common
> > +++ b/arm/Makefile.common
> > @@ -12,7 +12,8 @@ endif
> >  tests-common = \
> > $(TEST_DIR)/selftest.flat \
> > $(TEST_DIR)/spinlock-test.flat \
> > -   $(TEST_DIR)/pci-test.flat
> > +   $(TEST_DIR)/pci-test.flat \
> > +   $(TEST_DIR)/pmu.flat
> >  
> >  all: test_cases
> >  
> > diff --git a/arm/pmu.c b/arm/pmu.c
> > new file mode 100644
> > index 000..9d9c53b
> > --- /dev/null
> > +++ b/arm/pmu.c
> > @@ -0,0 +1,74 @@
> > +/*
> > + * Test the ARM Performance Monitors Unit (PMU).
> > + *
> > + * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
> > + *
> > + * This program is free software; you can redistribute it and/or modify it
> > + * under the terms of the GNU Lesser General Public License version 2.1 and
> > + * only version 2.1 as published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope that it will be useful, but 
> > WITHOUT
> > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
> > License
> > + * for more details.
> > + */
> > +#include "libcflat.h"
> > +#include "asm/barrier.h"
> > +
> > +#define PMU_PMCR_N_SHIFT   11
> > +#define PMU_PMCR_N_MASK0x1f
> > +#define PMU_PMCR_ID_SHIFT  16
> > +#define PMU_PMCR_ID_MASK   0xff
> > +#define PMU_PMCR_IMP_SHIFT 24
> > +#define PMU_PMCR_IMP_MASK  0xff
> > +
> > +#if defined(__arm__)
> 
> I guess you should use the arch specific header files we have in place
> for that (lib/arm{.64}/asm/processor.h). Also there are sysreg read
> wrappers (at least for arm64) in there already, can't we base this
> function on them: DEFINE_GET_SYSREG32(pmcr, el0)?
> (Requires a small change to get rid of the forced "_el1" suffix)
> 
> We should wait for the GIC series to be merged, as this contains some
> changes in this area.

As this unit test is the only consumer of PMC registers so far, then
I'd prefer the defines and accessors stay here for now. Once we see
a use in other unit tests then we can move some of it out.

> 
> > +static inline uint32_t pmcr_read(void)
> > +{
> > +   uint32_t ret;
> > +
> > +   asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (ret));
> > +   return ret;
> > +}
> > +#elif defined(__aarch64__)
> > +static inline uint32_t pmcr_read(void)
> > +{
> > +   uint32_t ret;
> > +
> > +   asm volatile("mrs %0, pmcr_el0" : "=r" (ret));
> > +   return ret;
> > +}
> > +#endif
> > +
> > +/*
> > + * As a simple sanity check on the PMCR_EL0, ensure the implementer field 
> > isn't
> > + * null. Also print out a couple other interesting fields for diagnostic
> > + * purposes. For example, as of fall 2016, QEMU TCG mode doesn't implement
> > + * event counters and therefore reports zero event counters, but hopefully
> > + * support for at least the instructions event will be added in the future 
> > and
> > + * the reported number of event counters will become nonzero.
> > + */
> > +static bool check_pmcr(void)
> > +{
> > +   uint32_t pmcr;
> > +
> > +   pmcr = pmcr_read();
> > +
> > +   printf("PMU implementer: %c\n",
> > +  (pmcr >> PMU_PMCR_IMP_SHIFT) & PMU_PMCR_IMP_MASK);
> 
> If this register reads as zero, the output is mangled (since it cuts off
> the string before the newline):
> =
> PMU implementer: Identification code: 0x0
> =
> 
> I guess you need something like:
> (pmcr >> PMU_PMCR_IMP_SHIFT) & PMU_PMCR_IMP_MASK ?: ' '

Good idea.

> 
> > +   printf("Identification code: 0x%x\n",
> > +  (pmcr >> PMU_PMCR_ID_SHIFT) & PMU_PMCR_ID_MASK);
> 
> As mentioned above this should use report_info() now, also it would be
> nice to merge this with the message above into one line of output.

Agreed.

Thanks,
drew

> 
> Cheers,
> Andre
> 

Re: [Qemu-devel] [kvm-unit-tests PATCH v11 3/3] arm: pmu: Add CPI checking

2016-11-23 Thread Andrew Jones
On Tue, Nov 22, 2016 at 12:29:14PM -0600, Wei Huang wrote:
> From: Christopher Covington 
> 
> Calculate the numbers of cycles per instruction (CPI) implied by ARM
> PMU cycle counter values. The code includes a strict checking facility
> intended for the -icount option in TCG mode in the configuration file.
> 
> Signed-off-by: Christopher Covington 
> Signed-off-by: Wei Huang 
> ---
>  arm/pmu.c | 123 
> +-
>  arm/unittests.cfg |  14 +++
>  2 files changed, 136 insertions(+), 1 deletion(-)


Reviewed-by: Andrew Jones 
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [Qemu-devel] [kvm-unit-tests PATCH v11 0/3] ARM PMU tests

2016-11-23 Thread Andrew Jones
On Tue, Nov 22, 2016 at 12:29:11PM -0600, Wei Huang wrote:
> Changes from v10:
> * Change the name of loop test function to precise_instrs_loop()
> * Minor comment fixes to measure_instrs() and to explain isb() in loop funcs 
> 
> Note:
> 1) Current KVM code has bugs in handling PMCCFILTR write. A fix (see
> below) is required for this unit testing code to work correctly under
> KVM mode.
> https://lists.cs.columbia.edu/pipermail/kvmarm/2016-November/022134.html.
> 
> Thanks,
> -Wei
> 
> Christopher Covington (3):
>   arm: Add PMU test
>   arm: pmu: Check cycle count increases
>   arm: pmu: Add CPI checking
> 
>  arm/Makefile.common |   3 +-
>  arm/pmu.c   | 351 
> 
>  arm/unittests.cfg   |  19 +++
>  3 files changed, 372 insertions(+), 1 deletion(-)
>  create mode 100644 arm/pmu.c
> 
> -- 
> 1.8.3.1
>

I'm pretty happy with this series. Andre has good suggestions though.
If you send a v12 soon, and nobody complains about my v7 gic series,
then I'll group this with the gic series into a single PULL request
for Radim and Paolo.

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


[kvm-unit-tests PATCH v7 08/11] libcflat: add IS_ALIGNED() macro, and page sizes

2016-11-23 Thread Andrew Jones
From: Peter Xu 

These macros will be useful to do page alignment checks.

Reviewed-by: Andre Przywara 
Reviewed-by: Eric Auger 
Signed-off-by: Peter Xu 
[drew: also added SZ_64K and changed to shifts]
Signed-off-by: Andrew Jones 

---
v6: change to shifts [Alex]
---
 lib/libcflat.h | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/lib/libcflat.h b/lib/libcflat.h
index c3fa4f24c499..bdcc561ccafd 100644
--- a/lib/libcflat.h
+++ b/lib/libcflat.h
@@ -33,6 +33,12 @@
 #define __ALIGN_MASK(x, mask)  (((x) + (mask)) & ~(mask))
 #define __ALIGN(x, a)  __ALIGN_MASK(x, (typeof(x))(a) - 1)
 #define ALIGN(x, a)__ALIGN((x), (a))
+#define IS_ALIGNED(x, a)   (((x) & ((typeof(x))(a) - 1)) == 0)
+
+#define SZ_4K  (1 << 12)
+#define SZ_64K (1 << 16)
+#define SZ_2M  (1 << 21)
+#define SZ_1G  (1 << 30)
 
 typedef uint8_tu8;
 typedef int8_t s8;
-- 
2.9.3

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


[kvm-unit-tests PATCH v7 11/11] arm/arm64: gic: don't just use zero

2016-11-23 Thread Andrew Jones
Allow user to select who sends ipis and with which irq,
rather than just always sending irq=0 from cpu0.

Signed-off-by: Andrew Jones 

---
v7: cleanup cmdline parsing and add complain on bad args [Eric]
v6:
 - make sender/irq names more future-proof [drew]
 - sanity check inputs [drew]
 - introduce check_sender/irq and bad_sender/irq to more
   cleanly do checks [drew]
 - default sender and irq to 1, instead of still zero [drew]
v4: improve structure and make sure spurious checking is
done even when the sender isn't cpu0
v2: actually check that the irq received was the irq sent,
and (for gicv2) that the sender is the expected one.
---
 arm/gic.c | 143 --
 1 file changed, 120 insertions(+), 23 deletions(-)

diff --git a/arm/gic.c b/arm/gic.c
index 23c1860a49d9..88c5f49d807d 100644
--- a/arm/gic.c
+++ b/arm/gic.c
@@ -11,6 +11,7 @@
  * This work is licensed under the terms of the GNU LGPL, version 2.
  */
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -27,6 +28,8 @@ struct gic {
 
 static struct gic *gic;
 static int acked[NR_CPUS], spurious[NR_CPUS];
+static int bad_sender[NR_CPUS], bad_irq[NR_CPUS];
+static int cmdl_sender = 1, cmdl_irq = 1;
 static cpumask_t ready;
 
 static void nr_cpu_check(int nr)
@@ -42,10 +45,23 @@ static void wait_on_ready(void)
cpu_relax();
 }
 
+static void stats_reset(void)
+{
+   int i;
+
+   for (i = 0; i < nr_cpus; ++i) {
+   acked[i] = 0;
+   bad_sender[i] = -1;
+   bad_irq[i] = -1;
+   }
+   smp_wmb();
+}
+
 static void check_acked(cpumask_t *mask)
 {
int missing = 0, extra = 0, unexpected = 0;
int nr_pass, cpu, i;
+   bool bad = false;
 
/* Wait up to 5s for all interrupts to be delivered */
for (i = 0; i < 50; ++i) {
@@ -55,9 +71,21 @@ static void check_acked(cpumask_t *mask)
smp_rmb();
nr_pass += cpumask_test_cpu(cpu, mask) ?
acked[cpu] == 1 : acked[cpu] == 0;
+
+   if (bad_sender[cpu] != -1) {
+   printf("cpu%d received IPI from wrong sender 
%d\n",
+   cpu, bad_sender[cpu]);
+   bad = true;
+   }
+
+   if (bad_irq[cpu] != -1) {
+   printf("cpu%d received wrong irq %d\n",
+   cpu, bad_irq[cpu]);
+   bad = true;
+   }
}
if (nr_pass == nr_cpus) {
-   report("Completed in %d ms", true, ++i * 100);
+   report("Completed in %d ms", !bad, ++i * 100);
return;
}
}
@@ -90,6 +118,22 @@ static void check_spurious(void)
}
 }
 
+static void check_ipi_sender(u32 irqstat)
+{
+   if (gic_version() == 2) {
+   int src = (irqstat >> 10) & 7;
+
+   if (src != cmdl_sender)
+   bad_sender[smp_processor_id()] = src;
+   }
+}
+
+static void check_irqnr(u32 irqnr)
+{
+   if (irqnr != (u32)cmdl_irq)
+   bad_irq[smp_processor_id()] = irqnr;
+}
+
 static void ipi_handler(struct pt_regs *regs __unused)
 {
u32 irqstat = gic_read_iar();
@@ -97,8 +141,10 @@ static void ipi_handler(struct pt_regs *regs __unused)
 
if (irqnr != GICC_INT_SPURIOUS) {
gic_write_eoir(irqstat);
-   smp_rmb(); /* pairs with wmb in ipi_test functions */
+   smp_rmb(); /* pairs with wmb in stats_reset */
++acked[smp_processor_id()];
+   check_ipi_sender(irqstat);
+   check_irqnr(irqnr);
smp_wmb(); /* pairs with rmb in check_acked */
} else {
++spurious[smp_processor_id()];
@@ -108,22 +154,22 @@ static void ipi_handler(struct pt_regs *regs __unused)
 
 static void gicv2_ipi_send_self(void)
 {
-   writel(2 << 24, gicv2_dist_base() + GICD_SGIR);
+   writel(2 << 24 | cmdl_irq, gicv2_dist_base() + GICD_SGIR);
 }
 
 static void gicv2_ipi_send_broadcast(void)
 {
-   writel(1 << 24, gicv2_dist_base() + GICD_SGIR);
+   writel(1 << 24 | cmdl_irq, gicv2_dist_base() + GICD_SGIR);
 }
 
 static void gicv3_ipi_send_self(void)
 {
-   gic_ipi_send_single(0, smp_processor_id());
+   gic_ipi_send_single(cmdl_irq, smp_processor_id());
 }
 
 static void gicv3_ipi_send_broadcast(void)
 {
-   gicv3_write_sgi1r(1ULL << 40);
+   gicv3_write_sgi1r(1ULL << 40 | cmdl_irq << 24);
isb();
 }
 
@@ -132,10 +178,9 @@ static void ipi_test_self(void)
cpumask_t mask;
 
report_prefix_push("self");
-   memset(acked, 0, sizeof(acked));
-   smp_wmb();
+   stats_reset();
cpumask_clear();
-   cpumask_set_cpu(0, );
+   

[kvm-unit-tests PATCH v7 10/11] arm/arm64: gicv3: add an IPI test

2016-11-23 Thread Andrew Jones
Signed-off-by: Andrew Jones 

---
v7:
 - add common ipi_send_single/mask (replacing ipi_send).
   Note, the arg order irq,cpu got swapped. [Eric]
 - comment rewording [Eric]
 - make enable_defaults a common op [Eric]
 - gic_enable_defaults() will now invoke gic_init if
   necessary [drew]
 - split lib/arm/gic.c into gic-v2/3.c [Eric]
v6: move most gicv2/gicv3 wrappers to common code [Alex]
v5:
 - fix copy+paste error in gicv3_write_eoir [drew]
 - use modern register names [Andre]
v4:
 - heavily comment gicv3_ipi_send_tlist() [Eric]
 - changes needed for gicv2 iar/irqstat fix to other patch
v2:
 - use IRM for gicv3 broadcast
---
 arm/gic.c  | 83 
 arm/unittests.cfg  |  6 +++
 lib/arm/asm/arch_gicv3.h   | 23 
 lib/arm/asm/gic-v2.h   |  2 +
 lib/arm/asm/gic-v3.h   | 12 +-
 lib/arm/asm/gic.h  | 63 +++
 lib/arm/gic-v2.c   | 40 
 lib/arm/gic-v3.c   | 94 ++
 lib/arm/gic.c  |  9 -
 lib/arm64/asm/arch_gicv3.h | 22 +++
 10 files changed, 336 insertions(+), 18 deletions(-)

diff --git a/arm/gic.c b/arm/gic.c
index b42c2b1ca1e1..23c1860a49d9 100644
--- a/arm/gic.c
+++ b/arm/gic.c
@@ -3,6 +3,8 @@
  *
  * GICv2
  *   + test sending/receiving IPIs
+ * GICv3
+ *   + test sending/receiving IPIs
  *
  * Copyright (C) 2016, Red Hat Inc, Andrew Jones 
  *
@@ -16,7 +18,14 @@
 #include 
 #include 
 
-static int gic_version;
+struct gic {
+   struct {
+   void (*send_self)(void);
+   void (*send_broadcast)(void);
+   } ipi;
+};
+
+static struct gic *gic;
 static int acked[NR_CPUS], spurious[NR_CPUS];
 static cpumask_t ready;
 
@@ -83,11 +92,11 @@ static void check_spurious(void)
 
 static void ipi_handler(struct pt_regs *regs __unused)
 {
-   u32 irqstat = readl(gicv2_cpu_base() + GICC_IAR);
-   u32 irqnr = irqstat & GICC_IAR_INT_ID_MASK;
+   u32 irqstat = gic_read_iar();
+   u32 irqnr = gic_iar_irqnr(irqstat);
 
if (irqnr != GICC_INT_SPURIOUS) {
-   writel(irqstat, gicv2_cpu_base() + GICC_EOIR);
+   gic_write_eoir(irqstat);
smp_rmb(); /* pairs with wmb in ipi_test functions */
++acked[smp_processor_id()];
smp_wmb(); /* pairs with rmb in check_acked */
@@ -97,6 +106,27 @@ static void ipi_handler(struct pt_regs *regs __unused)
}
 }
 
+static void gicv2_ipi_send_self(void)
+{
+   writel(2 << 24, gicv2_dist_base() + GICD_SGIR);
+}
+
+static void gicv2_ipi_send_broadcast(void)
+{
+   writel(1 << 24, gicv2_dist_base() + GICD_SGIR);
+}
+
+static void gicv3_ipi_send_self(void)
+{
+   gic_ipi_send_single(0, smp_processor_id());
+}
+
+static void gicv3_ipi_send_broadcast(void)
+{
+   gicv3_write_sgi1r(1ULL << 40);
+   isb();
+}
+
 static void ipi_test_self(void)
 {
cpumask_t mask;
@@ -106,7 +136,7 @@ static void ipi_test_self(void)
smp_wmb();
cpumask_clear();
cpumask_set_cpu(0, );
-   writel(2 << 24, gicv2_dist_base() + GICD_SGIR);
+   gic->ipi.send_self();
check_acked();
report_prefix_pop();
 }
@@ -114,14 +144,15 @@ static void ipi_test_self(void)
 static void ipi_test_smp(void)
 {
cpumask_t mask;
-   unsigned long tlist;
+   int i;
 
report_prefix_push("target-list");
memset(acked, 0, sizeof(acked));
smp_wmb();
-   tlist = cpumask_bits(_present_mask)[0] & 0xaa;
-   cpumask_bits()[0] = tlist;
-   writel((u8)tlist << 16, gicv2_dist_base() + GICD_SGIR);
+   cpumask_copy(, _present_mask);
+   for (i = 0; i < nr_cpus; i += 2)
+   cpumask_clear_cpu(i, );
+   gic_ipi_send_mask(0, );
check_acked();
report_prefix_pop();
 
@@ -130,14 +161,14 @@ static void ipi_test_smp(void)
smp_wmb();
cpumask_copy(, _present_mask);
cpumask_clear_cpu(0, );
-   writel(1 << 24, gicv2_dist_base() + GICD_SGIR);
+   gic->ipi.send_broadcast();
check_acked();
report_prefix_pop();
 }
 
 static void ipi_enable(void)
 {
-   gicv2_enable_defaults();
+   gic_enable_defaults();
 #ifdef __arm__
install_exception_handler(EXCPTN_IRQ, ipi_handler);
 #else
@@ -154,18 +185,40 @@ static void ipi_recv(void)
wfi();
 }
 
+static struct gic gicv2 = {
+   .ipi = {
+   .send_self = gicv2_ipi_send_self,
+   .send_broadcast = gicv2_ipi_send_broadcast,
+   },
+};
+
+static struct gic gicv3 = {
+   .ipi = {
+   .send_self = gicv3_ipi_send_self,
+   .send_broadcast = gicv3_ipi_send_broadcast,
+   },
+};
+
 int main(int argc, char **argv)
 {
char pfx[8];
int cpu;
 
-   gic_version = gic_init();
-   if (!gic_version)
-   report_abort("No gic present!");
+  

[kvm-unit-tests PATCH v7 09/11] arm/arm64: add initial gicv3 support

2016-11-23 Thread Andrew Jones
Reviewed-by: Alex Bennée 
Reviewed-by: Eric Auger 
Signed-off-by: Andrew Jones 

---
v7: split lib/arm/gic.c into gic-v2/3.c [Eric]
v6:
 - added comments [Alex]
 - added stride parameter to gicv3_set_redist_base [Andre]
 - redist-wait s/rwp/uwp/ and comment [Andre]
 - removed unnecessary wait-for-rwps [Andre]
v5: use modern register names [Andre]
v4:
 - only take defines from kernel we need now [Andre]
 - simplify enable by not caring if we reinit the distributor [drew]
v2:
 - configure irqs as NS GRP1
---
 arm/Makefile.common|   2 +-
 lib/arm/asm/arch_gicv3.h   |  47 
 lib/arm/asm/gic-v3.h   | 104 +
 lib/arm/asm/gic.h  |   5 ++-
 lib/arm/gic-v2.c   |  27 
 lib/arm/gic-v3.c   |  61 ++
 lib/arm/gic.c  |  30 +
 lib/arm64/asm/arch_gicv3.h |  44 +++
 lib/arm64/asm/gic-v3.h |   1 +
 lib/arm64/asm/sysreg.h |  44 +++
 10 files changed, 343 insertions(+), 22 deletions(-)
 create mode 100644 lib/arm/asm/arch_gicv3.h
 create mode 100644 lib/arm/asm/gic-v3.h
 create mode 100644 lib/arm/gic-v2.c
 create mode 100644 lib/arm/gic-v3.c
 create mode 100644 lib/arm64/asm/arch_gicv3.h
 create mode 100644 lib/arm64/asm/gic-v3.h
 create mode 100644 lib/arm64/asm/sysreg.h

diff --git a/arm/Makefile.common b/arm/Makefile.common
index 2fe7aeeca6d4..6c0898f28be1 100644
--- a/arm/Makefile.common
+++ b/arm/Makefile.common
@@ -46,7 +46,7 @@ cflatobjs += lib/arm/mmu.o
 cflatobjs += lib/arm/bitops.o
 cflatobjs += lib/arm/psci.o
 cflatobjs += lib/arm/smp.o
-cflatobjs += lib/arm/gic.o
+cflatobjs += lib/arm/gic.o lib/arm/gic-v2.o lib/arm/gic-v3.o
 
 libeabi = lib/arm/libeabi.a
 eabiobjs = lib/arm/eabi_compat.o
diff --git a/lib/arm/asm/arch_gicv3.h b/lib/arm/asm/arch_gicv3.h
new file mode 100644
index ..276577452a14
--- /dev/null
+++ b/lib/arm/asm/arch_gicv3.h
@@ -0,0 +1,47 @@
+/*
+ * All ripped off from arch/arm/include/asm/arch_gicv3.h
+ *
+ * Copyright (C) 2016, Red Hat Inc, Andrew Jones 
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+#ifndef _ASMARM_ARCH_GICV3_H_
+#define _ASMARM_ARCH_GICV3_H_
+
+#ifndef __ASSEMBLY__
+#include 
+#include 
+#include 
+
+#define __stringify xstr
+
+#define __ACCESS_CP15(CRn, Op1, CRm, Op2)  p15, Op1, %0, CRn, CRm, Op2
+
+#define ICC_PMR__ACCESS_CP15(c4, 0, c6, 0)
+#define ICC_IGRPEN1__ACCESS_CP15(c12, 0, c12, 7)
+
+static inline void gicv3_write_pmr(u32 val)
+{
+   asm volatile("mcr " __stringify(ICC_PMR) : : "r" (val));
+}
+
+static inline void gicv3_write_grpen1(u32 val)
+{
+   asm volatile("mcr " __stringify(ICC_IGRPEN1) : : "r" (val));
+   isb();
+}
+
+/*
+ * We may access GICR_TYPER and GITS_TYPER by reading both the TYPER
+ * offset and the following offset (+ 4) and then combining them to
+ * form a 64-bit address.
+ */
+static inline u64 gicv3_read_typer(const volatile void __iomem *addr)
+{
+   u64 val = readl(addr);
+   val |= (u64)readl(addr + 4) << 32;
+   return val;
+}
+
+#endif /* !__ASSEMBLY__ */
+#endif /* _ASMARM_ARCH_GICV3_H_ */
diff --git a/lib/arm/asm/gic-v3.h b/lib/arm/asm/gic-v3.h
new file mode 100644
index ..73ade4681d21
--- /dev/null
+++ b/lib/arm/asm/gic-v3.h
@@ -0,0 +1,104 @@
+/*
+ * All GIC* defines are lifted from include/linux/irqchip/arm-gic-v3.h
+ *
+ * Copyright (C) 2016, Red Hat Inc, Andrew Jones 
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+#ifndef _ASMARM_GIC_V3_H_
+#define _ASMARM_GIC_V3_H_
+
+#ifndef _ASMARM_GIC_H_
+#error Do not directly include . Include 
+#endif
+
+/*
+ * Distributor registers
+ *
+ * We expect to be run in Non-secure mode, thus we define the
+ * group1 enable bits with respect to that view.
+ */
+#define GICD_CTLR_RWP  (1U << 31)
+#define GICD_CTLR_ARE_NS   (1U << 4)
+#define GICD_CTLR_ENABLE_G1A   (1U << 1)
+#define GICD_CTLR_ENABLE_G1(1U << 0)
+
+/* Re-Distributor registers, offsets from RD_base */
+#define GICR_TYPER 0x0008
+
+#define GICR_TYPER_LAST(1U << 4)
+
+/* Re-Distributor registers, offsets from SGI_base */
+#define GICR_IGROUPR0  GICD_IGROUPR
+#define GICR_ISENABLER0GICD_ISENABLER
+#define GICR_IPRIORITYR0   GICD_IPRIORITYR
+
+#include 
+
+#ifndef __ASSEMBLY__
+#include 
+#include 
+#include 
+#include 
+
+struct gicv3_data {
+   void *dist_base;
+   void *redist_base[NR_CPUS];
+   unsigned int irq_nr;
+};
+extern struct gicv3_data gicv3_data;
+
+#define gicv3_dist_base()  (gicv3_data.dist_base)
+#define gicv3_redist_base()
(gicv3_data.redist_base[smp_processor_id()])
+#define 

[kvm-unit-tests PATCH v7 03/11] arm/arm64: smp: support more than 8 cpus

2016-11-23 Thread Andrew Jones
By adding support for launching with gicv3 we can break the 8 vcpu
limit. This patch adds support to smp code and also selects the
vgic model corresponding to the host. The vgic model may also be
manually selected by adding e.g. -machine gic-version=3 to
extra_params.

Reviewed-by: Alex Bennée 
Reviewed-by: Andre Przywara 
Reviewed-by: Eric Auger 
Signed-off-by: Andrew Jones 

---
v5: left cpus a u32 for now. Changing to u64 requires a change to
devicetree. Will do it later. [Andre]
v4: improved commit message
---
 arm/run   | 19 ---
 arm/selftest.c|  5 -
 lib/arm/asm/processor.h   |  9 +++--
 lib/arm/asm/setup.h   |  4 ++--
 lib/arm/setup.c   | 10 ++
 lib/arm64/asm/processor.h |  9 +++--
 6 files changed, 42 insertions(+), 14 deletions(-)

diff --git a/arm/run b/arm/run
index f1b04af614dc..1c40ab02eb57 100755
--- a/arm/run
+++ b/arm/run
@@ -31,13 +31,6 @@ if [ -z "$ACCEL" ]; then
fi
 fi
 
-if [ "$HOST" = "aarch64" ] && [ "$ACCEL" = "kvm" ]; then
-   processor="host"
-   if [ "$ARCH" = "arm" ]; then
-   processor+=",aarch64=off"
-   fi
-fi
-
 qemu="${QEMU:-qemu-system-$ARCH_NAME}"
 qpath=$(which $qemu 2>/dev/null)
 
@@ -53,6 +46,18 @@ fi
 
 M='-machine virt'
 
+if [ "$ACCEL" = "kvm" ]; then
+   if $qemu $M,\? 2>&1 | grep gic-version > /dev/null; then
+   M+=',gic-version=host'
+   fi
+   if [ "$HOST" = "aarch64" ]; then
+   processor="host"
+   if [ "$ARCH" = "arm" ]; then
+   processor+=",aarch64=off"
+   fi
+   fi
+fi
+
 if ! $qemu $M -device '?' 2>&1 | grep virtconsole > /dev/null; then
echo "$qpath doesn't support virtio-console for chr-testdev. Exiting."
exit 2
diff --git a/arm/selftest.c b/arm/selftest.c
index 196164f5313d..2f117f795d2d 100644
--- a/arm/selftest.c
+++ b/arm/selftest.c
@@ -312,9 +312,10 @@ static bool psci_check(void)
 static cpumask_t smp_reported;
 static void cpu_report(void)
 {
+   unsigned long mpidr = get_mpidr();
int cpu = smp_processor_id();
 
-   report("CPU%d online", true, cpu);
+   report("CPU(%3d) mpidr=%lx", mpidr_to_cpu(mpidr) == cpu, cpu, mpidr);
cpumask_set_cpu(cpu, _reported);
halt();
 }
@@ -343,6 +344,7 @@ int main(int argc, char **argv)
 
} else if (strcmp(argv[1], "smp") == 0) {
 
+   unsigned long mpidr = get_mpidr();
int cpu;
 
report("PSCI version", psci_check());
@@ -353,6 +355,7 @@ int main(int argc, char **argv)
smp_boot_secondary(cpu, cpu_report);
}
 
+   report("CPU(%3d) mpidr=%lx", mpidr_to_cpu(mpidr) == 0, 0, 
mpidr);
cpumask_set_cpu(0, _reported);
while (!cpumask_full(_reported))
cpu_relax();
diff --git a/lib/arm/asm/processor.h b/lib/arm/asm/processor.h
index 02f912f99974..ecf5bbe1824a 100644
--- a/lib/arm/asm/processor.h
+++ b/lib/arm/asm/processor.h
@@ -40,8 +40,13 @@ static inline unsigned long get_mpidr(void)
return mpidr;
 }
 
-/* Only support Aff0 for now, up to 4 cpus */
-#define mpidr_to_cpu(mpidr) ((int)((mpidr) & 0xff))
+#define MPIDR_HWID_BITMASK 0xff
+extern int mpidr_to_cpu(unsigned long mpidr);
+
+#define MPIDR_LEVEL_SHIFT(level) \
+   (((1 << level) >> 1) << 3)
+#define MPIDR_AFFINITY_LEVEL(mpidr, level) \
+   ((mpidr >> MPIDR_LEVEL_SHIFT(level)) & 0xff)
 
 extern void start_usr(void (*func)(void *arg), void *arg, unsigned long 
sp_usr);
 extern bool is_user(void);
diff --git a/lib/arm/asm/setup.h b/lib/arm/asm/setup.h
index cb8fdbd38dd5..1de99dd184d1 100644
--- a/lib/arm/asm/setup.h
+++ b/lib/arm/asm/setup.h
@@ -10,8 +10,8 @@
 #include 
 #include 
 
-#define NR_CPUS8
-extern u32 cpus[NR_CPUS];
+#define NR_CPUS255
+extern u32 cpus[NR_CPUS];  /* per-cpu IDs (MPIDRs) */
 extern int nr_cpus;
 
 #define NR_MEM_REGIONS 8
diff --git a/lib/arm/setup.c b/lib/arm/setup.c
index 7e7b39f11dde..241bf9410447 100644
--- a/lib/arm/setup.c
+++ b/lib/arm/setup.c
@@ -30,6 +30,16 @@ int nr_cpus;
 struct mem_region mem_regions[NR_MEM_REGIONS];
 phys_addr_t __phys_offset, __phys_end;
 
+int mpidr_to_cpu(unsigned long mpidr)
+{
+   int i;
+
+   for (i = 0; i < nr_cpus; ++i)
+   if (cpus[i] == (mpidr & MPIDR_HWID_BITMASK))
+   return i;
+   return -1;
+}
+
 static void cpu_set(int fdtnode __unused, u32 regval, void *info __unused)
 {
int cpu = nr_cpus++;
diff --git a/lib/arm64/asm/processor.h b/lib/arm64/asm/processor.h
index 9a208ff729b7..7e448dc81a6a 100644
--- a/lib/arm64/asm/processor.h
+++ b/lib/arm64/asm/processor.h
@@ -78,8 +78,13 @@ static inline type get_##reg(void)   
\
 
 DEFINE_GET_SYSREG64(mpidr)
 
-/* 

[kvm-unit-tests PATCH v7 04/11] arm/arm64: add some delay routines

2016-11-23 Thread Andrew Jones
Allow a thread to wait some specified amount of time. Can
specify in cycles, usecs, and msecs.

Reviewed-by: Alex Bennée 
Reviewed-by: Eric Auger 
Signed-off-by: Andrew Jones 
---
 lib/arm/asm/processor.h   | 19 +++
 lib/arm/processor.c   | 15 +++
 lib/arm64/asm/processor.h | 19 +++
 lib/arm64/processor.c | 15 +++
 4 files changed, 68 insertions(+)

diff --git a/lib/arm/asm/processor.h b/lib/arm/asm/processor.h
index ecf5bbe1824a..bc46d1f980ee 100644
--- a/lib/arm/asm/processor.h
+++ b/lib/arm/asm/processor.h
@@ -5,7 +5,9 @@
  *
  * This work is licensed under the terms of the GNU LGPL, version 2.
  */
+#include 
 #include 
+#include 
 
 enum vector {
EXCPTN_RST,
@@ -51,4 +53,21 @@ extern int mpidr_to_cpu(unsigned long mpidr);
 extern void start_usr(void (*func)(void *arg), void *arg, unsigned long 
sp_usr);
 extern bool is_user(void);
 
+static inline u64 get_cntvct(void)
+{
+   u64 vct;
+   isb();
+   asm volatile("mrrc p15, 1, %Q0, %R0, c14" : "=r" (vct));
+   return vct;
+}
+
+extern void delay(u64 cycles);
+extern void udelay(unsigned long usecs);
+
+static inline void mdelay(unsigned long msecs)
+{
+   while (msecs--)
+   udelay(1000);
+}
+
 #endif /* _ASMARM_PROCESSOR_H_ */
diff --git a/lib/arm/processor.c b/lib/arm/processor.c
index 54fdb87ef019..c2ee360df688 100644
--- a/lib/arm/processor.c
+++ b/lib/arm/processor.c
@@ -9,6 +9,7 @@
 #include 
 #include 
 #include 
+#include 
 
 static const char *processor_modes[] = {
"USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" ,
@@ -141,3 +142,17 @@ bool is_user(void)
 {
return current_thread_info()->flags & TIF_USER_MODE;
 }
+
+void delay(u64 cycles)
+{
+   u64 start = get_cntvct();
+   while ((get_cntvct() - start) < cycles)
+   cpu_relax();
+}
+
+void udelay(unsigned long usec)
+{
+   unsigned int frq;
+   asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (frq));
+   delay((u64)usec * frq / 100);
+}
diff --git a/lib/arm64/asm/processor.h b/lib/arm64/asm/processor.h
index 7e448dc81a6a..94f7ce35b65c 100644
--- a/lib/arm64/asm/processor.h
+++ b/lib/arm64/asm/processor.h
@@ -17,8 +17,10 @@
 #define SCTLR_EL1_M(1 << 0)
 
 #ifndef __ASSEMBLY__
+#include 
 #include 
 #include 
+#include 
 
 enum vector {
EL1T_SYNC,
@@ -89,5 +91,22 @@ extern int mpidr_to_cpu(unsigned long mpidr);
 extern void start_usr(void (*func)(void *arg), void *arg, unsigned long 
sp_usr);
 extern bool is_user(void);
 
+static inline u64 get_cntvct(void)
+{
+   u64 vct;
+   isb();
+   asm volatile("mrs %0, cntvct_el0" : "=r" (vct));
+   return vct;
+}
+
+extern void delay(u64 cycles);
+extern void udelay(unsigned long usecs);
+
+static inline void mdelay(unsigned long msecs)
+{
+   while (msecs--)
+   udelay(1000);
+}
+
 #endif /* !__ASSEMBLY__ */
 #endif /* _ASMARM64_PROCESSOR_H_ */
diff --git a/lib/arm64/processor.c b/lib/arm64/processor.c
index deeab4ec9c8a..50fa835c6f1e 100644
--- a/lib/arm64/processor.c
+++ b/lib/arm64/processor.c
@@ -9,6 +9,7 @@
 #include 
 #include 
 #include 
+#include 
 
 static const char *vector_names[] = {
"el1t_sync",
@@ -253,3 +254,17 @@ bool is_user(void)
 {
return current_thread_info()->flags & TIF_USER_MODE;
 }
+
+void delay(u64 cycles)
+{
+   u64 start = get_cntvct();
+   while ((get_cntvct() - start) < cycles)
+   cpu_relax();
+}
+
+void udelay(unsigned long usec)
+{
+   unsigned int frq;
+   asm volatile("mrs %0, cntfrq_el0" : "=r" (frq));
+   delay((u64)usec * frq / 100);
+}
-- 
2.9.3

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


[kvm-unit-tests PATCH v7 02/11] arm64: fix get_"sysreg32" and make MPIDR 64bit

2016-11-23 Thread Andrew Jones
mrs is always 64bit, so we should always use a 64bit register.
Sometimes we'll only want to return the lower 32, but not for
MPIDR, as that does define fields in the upper 32.

Reviewed-by: Alex Bennée 
Reviewed-by: Eric Auger 
Signed-off-by: Andrew Jones 

---
v5: switch arm32's get_mpidr to 'unsigned long' too, to be
consistent with arm64 [Andre]
---
 lib/arm/asm/processor.h   |  4 ++--
 lib/arm64/asm/processor.h | 15 +--
 2 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/lib/arm/asm/processor.h b/lib/arm/asm/processor.h
index f25e7eee3666..02f912f99974 100644
--- a/lib/arm/asm/processor.h
+++ b/lib/arm/asm/processor.h
@@ -33,9 +33,9 @@ static inline unsigned long current_cpsr(void)
 
 #define current_mode() (current_cpsr() & MODE_MASK)
 
-static inline unsigned int get_mpidr(void)
+static inline unsigned long get_mpidr(void)
 {
-   unsigned int mpidr;
+   unsigned long mpidr;
asm volatile("mrc p15, 0, %0, c0, c0, 5" : "=r" (mpidr));
return mpidr;
 }
diff --git a/lib/arm64/asm/processor.h b/lib/arm64/asm/processor.h
index 84d5c7ce752b..9a208ff729b7 100644
--- a/lib/arm64/asm/processor.h
+++ b/lib/arm64/asm/processor.h
@@ -66,14 +66,17 @@ static inline unsigned long current_level(void)
return el & 0xc;
 }
 
-#define DEFINE_GET_SYSREG32(reg)   \
-static inline unsigned int get_##reg(void) \
+#define DEFINE_GET_SYSREG(reg, type)   \
+static inline type get_##reg(void) \
 {  \
-   unsigned int reg;   \
-   asm volatile("mrs %0, " #reg "_el1" : "=r" (reg));  \
-   return reg; \
+   unsigned long r;\
+   asm volatile("mrs %0, " #reg "_el1" : "=r" (r));\
+   return (type)r; \
 }
-DEFINE_GET_SYSREG32(mpidr)
+#define DEFINE_GET_SYSREG32(reg) DEFINE_GET_SYSREG(reg, unsigned int)
+#define DEFINE_GET_SYSREG64(reg) DEFINE_GET_SYSREG(reg, unsigned long)
+
+DEFINE_GET_SYSREG64(mpidr)
 
 /* Only support Aff0 for now, gicv2 only */
 #define mpidr_to_cpu(mpidr) ((int)((mpidr) & 0xff))
-- 
2.9.3

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


[kvm-unit-tests PATCH v7 00/11] arm/arm64: add gic framework

2016-11-23 Thread Andrew Jones
v7:
 - biggest change is splitting lib/arm/gic.c into lib/arm/gic.c,
   lib/arm/gic-v2.c, lib/arm/gic-v3.c
 - second biggest change, which probably affects Alex, is that
   gic_ipi_send(cpu, irq) changed to gic_ipi_send_single(irq, cpu),
   note the swapping of cpu and irq!
 - other changes thanks to Eric are noted in individual patches
 - also rebased to latest master

v6:
 - rebased to latest master
 - several other changes thanks to Andre and Alex, changes in
   individual patch change logs
 - some code cleanups

v5:
 - fix arm32/gicv3 compile [drew]
 - use modern register names [Andre]
 - one Andre r-b

v4:
 - Eric's r-b's
 - Andre's suggestion to only take defines we need
 - several other changes listed in individual patches

v3:
 - Rebased on latest master
 - Added Alex's r-b's

v2:
 Rebased on latest master + my "populate argv[0]" series (will
 send a REPOST for that shortly. Additionally a few patches got
 fixes/features;
 07/10 got same fix as kernel 7c9b973061 "irqchip/gic-v3: Configure
   all interrupts as non-secure Group-1" in order to continue
   working over TCG, as the gicv3 code for TCG removed a hack
   it had there to make Linux happy.
 08/10 added more output for when things fail (if they fail)
 09/10 switched gicv3 broadcast implementation to using IRM. This
   found a bug in a recent (but not tip) kernel, which I was
   about to fix, but then I saw MarcZ beat me to it.
 10/10 actually check that the input irq is the received irq


Import defines, and steal enough helper functions, from Linux to
enable programming of the gic (v2 and v3). Then use the framework
to add an initial test (an ipi test; self, target-list, broadcast).

It's my hope that this framework will be a suitable base on which
more tests may be easily added, particularly because we have
vgic-new and tcg gicv3 emulation getting close to merge. (v3 UPDATE:
vgic-new and tcg gicv3 are merged now)

To run it, along with other tests, just do

 ./configure [ --arch=[arm|arm64] --cross-prefix=$PREFIX ]
 make
 export QEMU=$PATH_TO_QEMU
 ./run_tests.sh

To run it separately do, e.g.

$QEMU -machine virt,accel=tcg -cpu cortex-a57 \
 -device virtio-serial-device \
 -device virtconsole,chardev=ctd -chardev testdev,id=ctd \
 -display none -serial stdio \
 -kernel arm/gic.flat \
 -smp 123 -machine gic-version=3 -append ipi
  ^^ note, we can go nuts with nr-cpus on TCG :-)

Or, a KVM example using a different "sender" cpu and irq (other than zero)

$QEMU -machine virt,accel=kvm -cpu host \
 -device virtio-serial-device \
 -device virtconsole,chardev=ctd -chardev testdev,id=ctd \
 -display none -serial stdio \
 -kernel arm/gic.flat \
 -smp 48 -machine gic-version=3 -append 'ipi sender=42 irq=1'


Patches:
01-05: fixes and functionality needed by the later gic patches
06-07: enable gicv2 and gicv2 IPI test
08-10: enable gicv3 and gicv3 IPI test
   11: extend the IPI tests to take variable sender and irq

Available here: https://github.com/rhdrjones/kvm-unit-tests/commits/arm/gic-v7


Andrew Jones (10):
  lib: xstr: allow multiple args
  arm64: fix get_"sysreg32" and make MPIDR 64bit
  arm/arm64: smp: support more than 8 cpus
  arm/arm64: add some delay routines
  arm/arm64: irq enable/disable
  arm/arm64: add initial gicv2 support
  arm/arm64: gicv2: add an IPI test
  arm/arm64: add initial gicv3 support
  arm/arm64: gicv3: add an IPI test
  arm/arm64: gic: don't just use zero

Peter Xu (1):
  libcflat: add IS_ALIGNED() macro, and page sizes

 arm/Makefile.common|   9 +-
 arm/gic.c  | 349 +
 arm/run|  19 ++-
 arm/selftest.c |   5 +-
 arm/unittests.cfg  |  14 ++
 lib/arm/asm/arch_gicv3.h   |  70 +
 lib/arm/asm/gic-v2.h   |  38 +
 lib/arm/asm/gic-v3.h   | 114 +++
 lib/arm/asm/gic.h  | 109 ++
 lib/arm/asm/processor.h|  42 +-
 lib/arm/asm/setup.h|   4 +-
 lib/arm/gic-v2.c   |  67 +
 lib/arm/gic-v3.c   | 155 
 lib/arm/gic.c  |  71 +
 lib/arm/processor.c|  15 ++
 lib/arm/setup.c|  10 ++
 lib/arm64/asm/arch_gicv3.h |  66 +
 lib/arm64/asm/gic-v2.h |   1 +
 lib/arm64/asm/gic-v3.h |   1 +
 lib/arm64/asm/gic.h|   1 +
 lib/arm64/asm/processor.h  |  53 +--
 lib/arm64/asm/sysreg.h |  44 ++
 lib/arm64/processor.c  |  15 ++
 lib/libcflat.h |  10 +-
 24 files changed, 1254 insertions(+), 28 deletions(-)
 create mode 100644 arm/gic.c
 create mode 100644 lib/arm/asm/arch_gicv3.h
 create mode 100644 lib/arm/asm/gic-v2.h
 create mode 100644 lib/arm/asm/gic-v3.h
 create mode 100644 lib/arm/asm/gic.h
 create mode 100644 lib/arm/gic-v2.c
 create mode 100644 lib/arm/gic-v3.c
 create mode 100644 lib/arm/gic.c
 create mode 100644 lib/arm64/asm/arch_gicv3.h
 create mode 100644 lib/arm64/asm/gic-v2.h
 create mode 100644 

[kvm-unit-tests PATCH v7 07/11] arm/arm64: gicv2: add an IPI test

2016-11-23 Thread Andrew Jones
Reviewed-by: Eric Auger 
Signed-off-by: Andrew Jones 
---
v6: move the spurious check to its own check_ function [drew]
v5: use modern registers [Andre]
v4: properly mask irqnr in ipi_handler
v2: add more details in the output if a test fails,
report spurious interrupts if we get them
---
 arm/Makefile.common  |   8 +--
 arm/gic.c| 199 +++
 arm/unittests.cfg|   8 +++
 lib/arm/asm/gic-v2.h |   2 +
 lib/arm/asm/gic.h|   4 ++
 5 files changed, 217 insertions(+), 4 deletions(-)
 create mode 100644 arm/gic.c

diff --git a/arm/Makefile.common b/arm/Makefile.common
index 6f56015c43c4..2fe7aeeca6d4 100644
--- a/arm/Makefile.common
+++ b/arm/Makefile.common
@@ -9,10 +9,10 @@ ifeq ($(LOADADDR),)
LOADADDR = 0x4000
 endif
 
-tests-common = \
-   $(TEST_DIR)/selftest.flat \
-   $(TEST_DIR)/spinlock-test.flat \
-   $(TEST_DIR)/pci-test.flat
+tests-common  = $(TEST_DIR)/selftest.flat
+tests-common += $(TEST_DIR)/spinlock-test.flat
+tests-common += $(TEST_DIR)/pci-test.flat
+tests-common += $(TEST_DIR)/gic.flat
 
 all: test_cases
 
diff --git a/arm/gic.c b/arm/gic.c
new file mode 100644
index ..b42c2b1ca1e1
--- /dev/null
+++ b/arm/gic.c
@@ -0,0 +1,199 @@
+/*
+ * GIC tests
+ *
+ * GICv2
+ *   + test sending/receiving IPIs
+ *
+ * Copyright (C) 2016, Red Hat Inc, Andrew Jones 
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static int gic_version;
+static int acked[NR_CPUS], spurious[NR_CPUS];
+static cpumask_t ready;
+
+static void nr_cpu_check(int nr)
+{
+   if (nr_cpus < nr)
+   report_abort("At least %d cpus required", nr);
+}
+
+static void wait_on_ready(void)
+{
+   cpumask_set_cpu(smp_processor_id(), );
+   while (!cpumask_full())
+   cpu_relax();
+}
+
+static void check_acked(cpumask_t *mask)
+{
+   int missing = 0, extra = 0, unexpected = 0;
+   int nr_pass, cpu, i;
+
+   /* Wait up to 5s for all interrupts to be delivered */
+   for (i = 0; i < 50; ++i) {
+   mdelay(100);
+   nr_pass = 0;
+   for_each_present_cpu(cpu) {
+   smp_rmb();
+   nr_pass += cpumask_test_cpu(cpu, mask) ?
+   acked[cpu] == 1 : acked[cpu] == 0;
+   }
+   if (nr_pass == nr_cpus) {
+   report("Completed in %d ms", true, ++i * 100);
+   return;
+   }
+   }
+
+   for_each_present_cpu(cpu) {
+   if (cpumask_test_cpu(cpu, mask)) {
+   if (!acked[cpu])
+   ++missing;
+   else if (acked[cpu] > 1)
+   ++extra;
+   } else {
+   if (acked[cpu])
+   ++unexpected;
+   }
+   }
+
+   report("Timed-out (5s). ACKS: missing=%d extra=%d unexpected=%d",
+  false, missing, extra, unexpected);
+}
+
+static void check_spurious(void)
+{
+   int cpu;
+
+   smp_rmb();
+   for_each_present_cpu(cpu) {
+   if (spurious[cpu])
+   printf("ipi: WARN: cpu%d got %d spurious interrupts\n",
+   spurious[cpu], smp_processor_id());
+   }
+}
+
+static void ipi_handler(struct pt_regs *regs __unused)
+{
+   u32 irqstat = readl(gicv2_cpu_base() + GICC_IAR);
+   u32 irqnr = irqstat & GICC_IAR_INT_ID_MASK;
+
+   if (irqnr != GICC_INT_SPURIOUS) {
+   writel(irqstat, gicv2_cpu_base() + GICC_EOIR);
+   smp_rmb(); /* pairs with wmb in ipi_test functions */
+   ++acked[smp_processor_id()];
+   smp_wmb(); /* pairs with rmb in check_acked */
+   } else {
+   ++spurious[smp_processor_id()];
+   smp_wmb();
+   }
+}
+
+static void ipi_test_self(void)
+{
+   cpumask_t mask;
+
+   report_prefix_push("self");
+   memset(acked, 0, sizeof(acked));
+   smp_wmb();
+   cpumask_clear();
+   cpumask_set_cpu(0, );
+   writel(2 << 24, gicv2_dist_base() + GICD_SGIR);
+   check_acked();
+   report_prefix_pop();
+}
+
+static void ipi_test_smp(void)
+{
+   cpumask_t mask;
+   unsigned long tlist;
+
+   report_prefix_push("target-list");
+   memset(acked, 0, sizeof(acked));
+   smp_wmb();
+   tlist = cpumask_bits(_present_mask)[0] & 0xaa;
+   cpumask_bits()[0] = tlist;
+   writel((u8)tlist << 16, gicv2_dist_base() + GICD_SGIR);
+   check_acked();
+   report_prefix_pop();
+
+   report_prefix_push("broadcast");
+   memset(acked, 0, sizeof(acked));
+   smp_wmb();
+   cpumask_copy(, _present_mask);
+   cpumask_clear_cpu(0, );
+   writel(1 << 

[kvm-unit-tests PATCH v7 01/11] lib: xstr: allow multiple args

2016-11-23 Thread Andrew Jones
Make implementation equivalent to Linux's include/linux/stringify.h

Reviewed-by: Eric Auger 
Signed-off-by: Andrew Jones 
---
 lib/libcflat.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/libcflat.h b/lib/libcflat.h
index c622198677c1..c3fa4f24c499 100644
--- a/lib/libcflat.h
+++ b/lib/libcflat.h
@@ -27,8 +27,8 @@
 
 #define __unused __attribute__((__unused__))
 
-#define xstr(s) xxstr(s)
-#define xxstr(s) #s
+#define xstr(s...) xxstr(s)
+#define xxstr(s...) #s
 
 #define __ALIGN_MASK(x, mask)  (((x) + (mask)) & ~(mask))
 #define __ALIGN(x, a)  __ALIGN_MASK(x, (typeof(x))(a) - 1)
-- 
2.9.3

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


Re: [kvm-unit-tests PATCH v11 1/3] arm: Add PMU test

2016-11-23 Thread Wei Huang


On 11/23/2016 07:16 AM, Andre Przywara wrote:
> Hi,
> 
> On 22/11/16 18:29, Wei Huang wrote:
>> From: Christopher Covington 
>>
>> Beginning with a simple sanity check of the control register, add
>> a unit test for the ARM Performance Monitors Unit (PMU).
> 
> Mmh, the output of this is a bit confusing. How about to join some
> information? I changed it to give me:
> INFO: pmu: PMU implementer/ID code: "A"(0x41)/0x0
> INFO: pmu: Event counters:  0
> PASS: pmu: Control register
> 
> ... by using the newly introduced report_info() to make it look nicer.
> 
>>
>> Signed-off-by: Christopher Covington 
>> Signed-off-by: Wei Huang 
>> Reviewed-by: Andrew Jones 
>> ---
>>  arm/Makefile.common |  3 ++-
>>  arm/pmu.c   | 74 
>> +
>>  arm/unittests.cfg   |  5 
>>  3 files changed, 81 insertions(+), 1 deletion(-)
>>  create mode 100644 arm/pmu.c
>>
>> diff --git a/arm/Makefile.common b/arm/Makefile.common
>> index f37b5c2..5da2fdd 100644
>> --- a/arm/Makefile.common
>> +++ b/arm/Makefile.common
>> @@ -12,7 +12,8 @@ endif
>>  tests-common = \
>>  $(TEST_DIR)/selftest.flat \
>>  $(TEST_DIR)/spinlock-test.flat \
>> -$(TEST_DIR)/pci-test.flat
>> +$(TEST_DIR)/pci-test.flat \
>> +$(TEST_DIR)/pmu.flat
>>  
>>  all: test_cases
>>  
>> diff --git a/arm/pmu.c b/arm/pmu.c
>> new file mode 100644
>> index 000..9d9c53b
>> --- /dev/null
>> +++ b/arm/pmu.c
>> @@ -0,0 +1,74 @@
>> +/*
>> + * Test the ARM Performance Monitors Unit (PMU).
>> + *
>> + * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
>> + *
>> + * This program is free software; you can redistribute it and/or modify it
>> + * under the terms of the GNU Lesser General Public License version 2.1 and
>> + * only version 2.1 as published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that it will be useful, but 
>> WITHOUT
>> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
>> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
>> License
>> + * for more details.
>> + */
>> +#include "libcflat.h"
>> +#include "asm/barrier.h"
>> +
>> +#define PMU_PMCR_N_SHIFT   11
>> +#define PMU_PMCR_N_MASK0x1f
>> +#define PMU_PMCR_ID_SHIFT  16
>> +#define PMU_PMCR_ID_MASK   0xff
>> +#define PMU_PMCR_IMP_SHIFT 24
>> +#define PMU_PMCR_IMP_MASK  0xff
>> +
>> +#if defined(__arm__)
> 
> I guess you should use the arch specific header files we have in place
> for that (lib/arm{.64}/asm/processor.h). Also there are sysreg read
> wrappers (at least for arm64) in there already, can't we base this
> function on them: DEFINE_GET_SYSREG32(pmcr, el0)?
> (Requires a small change to get rid of the forced "_el1" suffix)
> 
> We should wait for the GIC series to be merged, as this contains some
> changes in this area.

We planned to add it after this series is merged. However if GIC series
has a similar support, we can piggy-back on it.

> 
>> +static inline uint32_t pmcr_read(void)
>> +{
>> +uint32_t ret;
>> +
>> +asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (ret));
>> +return ret;
>> +}
>> +#elif defined(__aarch64__)
>> +static inline uint32_t pmcr_read(void)
>> +{
>> +uint32_t ret;
>> +
>> +asm volatile("mrs %0, pmcr_el0" : "=r" (ret));
>> +return ret;
>> +}
>> +#endif
>> +
>> +/*
>> + * As a simple sanity check on the PMCR_EL0, ensure the implementer field 
>> isn't
>> + * null. Also print out a couple other interesting fields for diagnostic
>> + * purposes. For example, as of fall 2016, QEMU TCG mode doesn't implement
>> + * event counters and therefore reports zero event counters, but hopefully
>> + * support for at least the instructions event will be added in the future 
>> and
>> + * the reported number of event counters will become nonzero.
>> + */
>> +static bool check_pmcr(void)
>> +{
>> +uint32_t pmcr;
>> +
>> +pmcr = pmcr_read();
>> +
>> +printf("PMU implementer: %c\n",
>> +   (pmcr >> PMU_PMCR_IMP_SHIFT) & PMU_PMCR_IMP_MASK);
> 
> If this register reads as zero, the output is mangled (since it cuts off
> the string before the newline):
> =
> PMU implementer: Identification code: 0x0
> =
> 
> I guess you need something like:
> (pmcr >> PMU_PMCR_IMP_SHIFT) & PMU_PMCR_IMP_MASK ?: ' '
> 
>> +printf("Identification code: 0x%x\n",
>> +   (pmcr >> PMU_PMCR_ID_SHIFT) & PMU_PMCR_ID_MASK);
> 
> As mentioned above this should use report_info() now, also it would be
> nice to merge this with the message above into one line of output.

I will take them into consideration. Thanks.

> 
> Cheers,
> Andre
> 
>> +printf("Event counters:  %d\n",
>> +   (pmcr >> PMU_PMCR_N_SHIFT) & PMU_PMCR_N_MASK);
>> +
>> +return ((pmcr >> PMU_PMCR_IMP_SHIFT) & PMU_PMCR_IMP_MASK) != 0;
>> +}
>> +
>> +int main(void)
>> +{
>> +

Re: [Qemu-devel] [kvm-unit-tests PATCH 3/4] arm/arm64: GICv2: add GICD_ITARGETSR testing

2016-11-23 Thread Andre Przywara
Hi Eric,

thanks for having such a close look (as always!).

On 23/11/16 13:51, Auger Eric wrote:
> Hi Andre,
> 
> On 23/11/2016 14:24, Auger Eric wrote:
>> Hi,
>>
>> On 18/11/2016 15:20, Andrew Jones wrote:
>>> On Thu, Nov 17, 2016 at 05:57:51PM +, Andre Przywara wrote:
 Some tests for the ITARGETS registers.
 Bits corresponding to non-existent CPUs must be RAZ/WI.
 These registers must be byte-accessible, also check that accesses beyond
 the implemented IRQ limit are actually read-as-zero/write-ignore.

 Signed-off-by: Andre Przywara 
 ---
  arm/gic.c | 54 
 ++
  lib/arm/asm/gic.h |  1 +
  2 files changed, 55 insertions(+)

 diff --git a/arm/gic.c b/arm/gic.c
 index a27da2c..02b1be1 100644
 --- a/arm/gic.c
 +++ b/arm/gic.c
 @@ -397,6 +397,57 @@ static bool test_priorities(int nr_irqs, void *priptr)
return true;
  }
  
 +static bool test_targets(int nr_irqs)
 +{
 +  void *targetsptr = gicv2_dist_base() + GICD_ITARGETSR;
 +  u32 orig_targets;
 +  u32 cpu_mask;
 +  u32 pattern, reg;
 +
 +  orig_targets = readl(targetsptr + 32);
 +  report_prefix_push("ITARGETSR");
 +
 +  cpu_mask = (1 << nr_cpus) - 1;
>>>
>>> Shouldn't this be 1 << (nr_cpus - 1) ?
>> original looks correct to me.
>>>
>>> Is this test always going to be gicv2-only? We should probably comment it,
>>> if so. We don't want to risk this being run when nr_cpus can be larger
>>> than 8.
>>>
 +  cpu_mask |= cpu_mask << 8;

So this instruction is supposed to copy bits[7:0] into bits[15:8] (not
caring about the other bits, which are zero anyway).

 +  cpu_mask |= cpu_mask << 16;

And this one copies bits[15:0] into bits[31:16].

>> Don't we miss the 4th byte mask?

I don't think so, the idea is just to copy the lowest byte into all the
other three bytes of that word and thus to propagate the byte mask for
one IRQ into a word covering four interrupts. Does that make sense?
I take it this deserves a comment then ...

 +
 +  /* Check that bits for non implemented CPUs are RAZ/WI. */
 +  if (nr_cpus < 8) {
 +  writel(0x, targetsptr + 32);
 +  report("bits for %d non-existent CPUs masked",
 + !(readl(targetsptr + 32) & ~cpu_mask), 8 - nr_cpus);
> 
> yep on AMD overdrive with smp=4 I get:
> 
> FAIL: gicv2: mmio: ITARGETSR: bits for 4 non-existent CPUs masked

I guess because you don't have
http://lists.infradead.org/pipermail/linux-arm-kernel/2016-November/468296.html
in your host kernel?
This was one of the two genuine bugs I spotted with this.

Cheers,
Andre.

 +  } else {
 +  report_skip("CPU masking (all CPUs implemented)");
 +  }
 +
 +  report("accesses beyond limit RAZ/WI",
 + test_readonly_32(targetsptr + nr_irqs, true));
 +
 +  pattern = 0x0103020f;
 +  writel(pattern, targetsptr + 32);
 +  reg = readl(targetsptr + 32);
 +  report("register content preserved (%08x => %08x)",
 + reg == (pattern & cpu_mask), pattern & cpu_mask, reg);
 +
 +  /*
 +   * The TARGETS registers are byte accessible, do a byte-wide
 +   * read and write of known content to check for this.
 +   */
 +  reg = readb(targetsptr + 33);
 +  report("byte reads successful (0x%08x => 0x%02x)",
 + reg == (BYTE(pattern, 1) & cpu_mask),
 + pattern & cpu_mask, reg);
 +
 +  pattern = REPLACE_BYTE(pattern, 2, 0x04);
 +  writeb(BYTE(pattern, 2), targetsptr + 34);
 +  reg = readl(targetsptr + 32);
 +  report("byte writes successful (0x%02x => 0x%08x)",
 + reg == (pattern & cpu_mask), BYTE(pattern, 2), reg);
>>>
>>> Last patch also had a byte addressability test. Maybe we should make
>>> a helper function?
>>>
 +
 +  writel(orig_targets, targetsptr + 32);
 +  return true;
>>>
>>> Function can/should be void.
>>>
 +}
 +
  static int gic_test_mmio(int gic_version)
  {
u32 reg;
 @@ -436,6 +487,9 @@ static int gic_test_mmio(int gic_version)
  
test_priorities(nr_irqs, gic_dist_base + GICD_IPRIORITYR);
  
 +  if (gic_version == 2)
 +  test_targets(nr_irqs);
 +
return 0;
  }
  
 diff --git a/lib/arm/asm/gic.h b/lib/arm/asm/gic.h
 index cef748d..6f170cb 100644
 --- a/lib/arm/asm/gic.h
 +++ b/lib/arm/asm/gic.h
 @@ -14,6 +14,7 @@
  #define GICD_IGROUPR  0x0080
  #define GICD_ISENABLER0x0100
  #define GICD_IPRIORITYR   0x0400
 +#define GICD_ITARGETSR0x0800
  #define GICD_SGIR 0x0f00
  #define GICD_ICPIDR2  0x0fe8
  
 -- 
 2.9.0


>>>
>>> Thanks,
>>> drew
>>>

Re: [Qemu-devel] [kvm-unit-tests PATCH 3/4] arm/arm64: GICv2: add GICD_ITARGETSR testing

2016-11-23 Thread Auger Eric
Hi Andre,

On 23/11/2016 14:24, Auger Eric wrote:
> Hi,
> 
> On 18/11/2016 15:20, Andrew Jones wrote:
>> On Thu, Nov 17, 2016 at 05:57:51PM +, Andre Przywara wrote:
>>> Some tests for the ITARGETS registers.
>>> Bits corresponding to non-existent CPUs must be RAZ/WI.
>>> These registers must be byte-accessible, also check that accesses beyond
>>> the implemented IRQ limit are actually read-as-zero/write-ignore.
>>>
>>> Signed-off-by: Andre Przywara 
>>> ---
>>>  arm/gic.c | 54 
>>> ++
>>>  lib/arm/asm/gic.h |  1 +
>>>  2 files changed, 55 insertions(+)
>>>
>>> diff --git a/arm/gic.c b/arm/gic.c
>>> index a27da2c..02b1be1 100644
>>> --- a/arm/gic.c
>>> +++ b/arm/gic.c
>>> @@ -397,6 +397,57 @@ static bool test_priorities(int nr_irqs, void *priptr)
>>> return true;
>>>  }
>>>  
>>> +static bool test_targets(int nr_irqs)
>>> +{
>>> +   void *targetsptr = gicv2_dist_base() + GICD_ITARGETSR;
>>> +   u32 orig_targets;
>>> +   u32 cpu_mask;
>>> +   u32 pattern, reg;
>>> +
>>> +   orig_targets = readl(targetsptr + 32);
>>> +   report_prefix_push("ITARGETSR");
>>> +
>>> +   cpu_mask = (1 << nr_cpus) - 1;
>>
>> Shouldn't this be 1 << (nr_cpus - 1) ?
> original looks correct to me.
>>
>> Is this test always going to be gicv2-only? We should probably comment it,
>> if so. We don't want to risk this being run when nr_cpus can be larger
>> than 8.
>>
>>> +   cpu_mask |= cpu_mask << 8;
>>> +   cpu_mask |= cpu_mask << 16;
> Don't we miss the 4th byte mask?
> 
> Thanks
> 
> Eric
>>> +
>>> +   /* Check that bits for non implemented CPUs are RAZ/WI. */
>>> +   if (nr_cpus < 8) {
>>> +   writel(0x, targetsptr + 32);
>>> +   report("bits for %d non-existent CPUs masked",
>>> +  !(readl(targetsptr + 32) & ~cpu_mask), 8 - nr_cpus);

yep on AMD overdrive with smp=4 I get:

FAIL: gicv2: mmio: ITARGETSR: bits for 4 non-existent CPUs masked

Thanks

Eric

>>> +   } else {
>>> +   report_skip("CPU masking (all CPUs implemented)");
>>> +   }
>>> +
>>> +   report("accesses beyond limit RAZ/WI",
>>> +  test_readonly_32(targetsptr + nr_irqs, true));
>>> +
>>> +   pattern = 0x0103020f;
>>> +   writel(pattern, targetsptr + 32);
>>> +   reg = readl(targetsptr + 32);
>>> +   report("register content preserved (%08x => %08x)",
>>> +  reg == (pattern & cpu_mask), pattern & cpu_mask, reg);
>>> +
>>> +   /*
>>> +* The TARGETS registers are byte accessible, do a byte-wide
>>> +* read and write of known content to check for this.
>>> +*/
>>> +   reg = readb(targetsptr + 33);
>>> +   report("byte reads successful (0x%08x => 0x%02x)",
>>> +  reg == (BYTE(pattern, 1) & cpu_mask),
>>> +  pattern & cpu_mask, reg);
>>> +
>>> +   pattern = REPLACE_BYTE(pattern, 2, 0x04);
>>> +   writeb(BYTE(pattern, 2), targetsptr + 34);
>>> +   reg = readl(targetsptr + 32);
>>> +   report("byte writes successful (0x%02x => 0x%08x)",
>>> +  reg == (pattern & cpu_mask), BYTE(pattern, 2), reg);
>>
>> Last patch also had a byte addressability test. Maybe we should make
>> a helper function?
>>
>>> +
>>> +   writel(orig_targets, targetsptr + 32);
>>> +   return true;
>>
>> Function can/should be void.
>>
>>> +}
>>> +
>>>  static int gic_test_mmio(int gic_version)
>>>  {
>>> u32 reg;
>>> @@ -436,6 +487,9 @@ static int gic_test_mmio(int gic_version)
>>>  
>>> test_priorities(nr_irqs, gic_dist_base + GICD_IPRIORITYR);
>>>  
>>> +   if (gic_version == 2)
>>> +   test_targets(nr_irqs);
>>> +
>>> return 0;
>>>  }
>>>  
>>> diff --git a/lib/arm/asm/gic.h b/lib/arm/asm/gic.h
>>> index cef748d..6f170cb 100644
>>> --- a/lib/arm/asm/gic.h
>>> +++ b/lib/arm/asm/gic.h
>>> @@ -14,6 +14,7 @@
>>>  #define GICD_IGROUPR   0x0080
>>>  #define GICD_ISENABLER 0x0100
>>>  #define GICD_IPRIORITYR0x0400
>>> +#define GICD_ITARGETSR 0x0800
>>>  #define GICD_SGIR  0x0f00
>>>  #define GICD_ICPIDR2   0x0fe8
>>>  
>>> -- 
>>> 2.9.0
>>>
>>>
>>
>> Thanks,
>> drew
>>
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [kvm-unit-tests PATCH v6 11/11] arm/arm64: gic: don't just use zero

2016-11-23 Thread Andrew Jones
On Wed, Nov 23, 2016 at 02:33:31PM +0100, Auger Eric wrote:
> 
> 
> On 23/11/2016 14:01, Andrew Jones wrote:
> > On Wed, Nov 23, 2016 at 12:28:34PM +0100, Auger Eric wrote:
> >> Hi,
> >>
> >> On 14/11/2016 22:08, Andrew Jones wrote:
> >>> Allow user to select who sends ipis and with which irq,
> >>> rather than just always sending irq=0 from cpu0.
> >> From a user point of view is there a way to know the list of available
> >> tests and their arg?
> > 
> > Not at the moment. I could change the arg-less run and/or add
> > a '-h' though that would provide a usage. So far unit tests
> > have never had -h's, but it's not a bad idea.
> 
> OK thanks for the info
> > 
> >>>
> >>> Signed-off-by: Andrew Jones 
> >>>
> >>> ---
> >>> v6:
> >>>  - make sender/irq names more future-proof [drew]
> >>>  - sanity check inputs [drew]
> >>>  - introduce check_sender/irq and bad_sender/irq to more
> >>>cleanly do checks [drew]
> >>>  - default sender and irq to 1, instead of still zero [drew]
> >>> v4: improve structure and make sure spurious checking is
> >>> done even when the sender isn't cpu0
> >>> v2: actually check that the irq received was the irq sent,
> >>> and (for gicv2) that the sender is the expected one.
> >>> ---
> >>>  arm/gic.c | 124 
> >>> +-
> >>>  1 file changed, 99 insertions(+), 25 deletions(-)
> >>>
> >>> diff --git a/arm/gic.c b/arm/gic.c
> >>> index d954a3775c26..638b8b140c96 100644
> >>> --- a/arm/gic.c
> >>> +++ b/arm/gic.c
> >>> @@ -11,6 +11,7 @@
> >>>   * This work is licensed under the terms of the GNU LGPL, version 2.
> >>>   */
> >>>  #include 
> >>> +#include 
> >>>  #include 
> >>>  #include 
> >>>  #include 
> >>> @@ -28,6 +29,8 @@ struct gic {
> >>>  
> >>>  static struct gic *gic;
> >>>  static int acked[NR_CPUS], spurious[NR_CPUS];
> >>> +static int bad_sender[NR_CPUS], bad_irq[NR_CPUS];
> >>> +static int cmdl_sender = 1, cmdl_irq = 1;
> >>>  static cpumask_t ready;
> >>>  
> >>>  static void nr_cpu_check(int nr)
> >>> @@ -43,10 +46,23 @@ static void wait_on_ready(void)
> >>>   cpu_relax();
> >>>  }
> >>>  
> >>> +static void stats_reset(void)
> >>> +{
> >>> + int i;
> >>> +
> >>> + for (i = 0; i < nr_cpus; ++i) {
> >>> + acked[i] = 0;
> >>> + bad_sender[i] = -1;
> >>> + bad_irq[i] = -1;
> >>> + }
> >>> + smp_wmb();
> >>> +}
> >>> +
> >>>  static void check_acked(cpumask_t *mask)
> >>>  {
> >>>   int missing = 0, extra = 0, unexpected = 0;
> >>>   int nr_pass, cpu, i;
> >>> + bool bad = false;
> >>>  
> >>>   /* Wait up to 5s for all interrupts to be delivered */
> >>>   for (i = 0; i < 50; ++i) {
> >>> @@ -56,9 +72,21 @@ static void check_acked(cpumask_t *mask)
> >>>   smp_rmb();
> >>>   nr_pass += cpumask_test_cpu(cpu, mask) ?
> >>>   acked[cpu] == 1 : acked[cpu] == 0;
> >>> +
> >>> + if (bad_sender[cpu] != -1) {
> >>> + printf("cpu%d received IPI from wrong sender 
> >>> %d\n",
> >>> + cpu, bad_sender[cpu]);
> >>> + bad = true;
> >>> + }
> >>> +
> >>> + if (bad_irq[cpu] != -1) {
> >>> + printf("cpu%d received wrong irq %d\n",
> >>> + cpu, bad_irq[cpu]);
> >>> + bad = true;
> >>> + }
> >>>   }
> >>>   if (nr_pass == nr_cpus) {
> >>> - report("Completed in %d ms", true, ++i * 100);
> >>> + report("Completed in %d ms", !bad, ++i * 100);
> >>>   return;
> >>>   }
> >>>   }
> >>> @@ -91,6 +119,22 @@ static void check_spurious(void)
> >>>   }
> >>>  }
> >>>  
> >>> +static void check_ipi_sender(u32 irqstat)
> >>> +{
> >>> + if (gic_version() == 2) {
> >>> + int src = (irqstat >> 10) & 7;
> >>> +
> >>> + if (src != cmdl_sender)
> >>> + bad_sender[smp_processor_id()] = src;
> >>> + }
> >>> +}
> >>> +
> >>> +static void check_irqnr(u32 irqnr)
> >>> +{
> >>> + if (irqnr != (u32)cmdl_irq)
> >>> + bad_irq[smp_processor_id()] = irqnr;
> >>> +}
> >>> +
> >>>  static void ipi_handler(struct pt_regs *regs __unused)
> >>>  {
> >>>   u32 irqstat = gic_read_iar();
> >>> @@ -98,8 +142,10 @@ static void ipi_handler(struct pt_regs *regs __unused)
> >>>  
> >>>   if (irqnr != GICC_INT_SPURIOUS) {
> >>>   gic_write_eoir(irqstat);
> >>> - smp_rmb(); /* pairs with wmb in ipi_test functions */
> >>> + smp_rmb(); /* pairs with wmb in stats_reset */
> >>>   ++acked[smp_processor_id()];
> >>> + check_ipi_sender(irqstat);
> >>> + check_irqnr(irqnr);
> >>>   smp_wmb(); /* pairs with rmb in check_acked */
> >>>   } else {
> >>>   ++spurious[smp_processor_id()];
> >>> @@ -109,19 +155,19 @@ static void ipi_handler(struct pt_regs *regs 
> >>> 

Re: [kvm-unit-tests PATCH v6 11/11] arm/arm64: gic: don't just use zero

2016-11-23 Thread Auger Eric


On 23/11/2016 14:01, Andrew Jones wrote:
> On Wed, Nov 23, 2016 at 12:28:34PM +0100, Auger Eric wrote:
>> Hi,
>>
>> On 14/11/2016 22:08, Andrew Jones wrote:
>>> Allow user to select who sends ipis and with which irq,
>>> rather than just always sending irq=0 from cpu0.
>> From a user point of view is there a way to know the list of available
>> tests and their arg?
> 
> Not at the moment. I could change the arg-less run and/or add
> a '-h' though that would provide a usage. So far unit tests
> have never had -h's, but it's not a bad idea.

OK thanks for the info
> 
>>>
>>> Signed-off-by: Andrew Jones 
>>>
>>> ---
>>> v6:
>>>  - make sender/irq names more future-proof [drew]
>>>  - sanity check inputs [drew]
>>>  - introduce check_sender/irq and bad_sender/irq to more
>>>cleanly do checks [drew]
>>>  - default sender and irq to 1, instead of still zero [drew]
>>> v4: improve structure and make sure spurious checking is
>>> done even when the sender isn't cpu0
>>> v2: actually check that the irq received was the irq sent,
>>> and (for gicv2) that the sender is the expected one.
>>> ---
>>>  arm/gic.c | 124 
>>> +-
>>>  1 file changed, 99 insertions(+), 25 deletions(-)
>>>
>>> diff --git a/arm/gic.c b/arm/gic.c
>>> index d954a3775c26..638b8b140c96 100644
>>> --- a/arm/gic.c
>>> +++ b/arm/gic.c
>>> @@ -11,6 +11,7 @@
>>>   * This work is licensed under the terms of the GNU LGPL, version 2.
>>>   */
>>>  #include 
>>> +#include 
>>>  #include 
>>>  #include 
>>>  #include 
>>> @@ -28,6 +29,8 @@ struct gic {
>>>  
>>>  static struct gic *gic;
>>>  static int acked[NR_CPUS], spurious[NR_CPUS];
>>> +static int bad_sender[NR_CPUS], bad_irq[NR_CPUS];
>>> +static int cmdl_sender = 1, cmdl_irq = 1;
>>>  static cpumask_t ready;
>>>  
>>>  static void nr_cpu_check(int nr)
>>> @@ -43,10 +46,23 @@ static void wait_on_ready(void)
>>> cpu_relax();
>>>  }
>>>  
>>> +static void stats_reset(void)
>>> +{
>>> +   int i;
>>> +
>>> +   for (i = 0; i < nr_cpus; ++i) {
>>> +   acked[i] = 0;
>>> +   bad_sender[i] = -1;
>>> +   bad_irq[i] = -1;
>>> +   }
>>> +   smp_wmb();
>>> +}
>>> +
>>>  static void check_acked(cpumask_t *mask)
>>>  {
>>> int missing = 0, extra = 0, unexpected = 0;
>>> int nr_pass, cpu, i;
>>> +   bool bad = false;
>>>  
>>> /* Wait up to 5s for all interrupts to be delivered */
>>> for (i = 0; i < 50; ++i) {
>>> @@ -56,9 +72,21 @@ static void check_acked(cpumask_t *mask)
>>> smp_rmb();
>>> nr_pass += cpumask_test_cpu(cpu, mask) ?
>>> acked[cpu] == 1 : acked[cpu] == 0;
>>> +
>>> +   if (bad_sender[cpu] != -1) {
>>> +   printf("cpu%d received IPI from wrong sender 
>>> %d\n",
>>> +   cpu, bad_sender[cpu]);
>>> +   bad = true;
>>> +   }
>>> +
>>> +   if (bad_irq[cpu] != -1) {
>>> +   printf("cpu%d received wrong irq %d\n",
>>> +   cpu, bad_irq[cpu]);
>>> +   bad = true;
>>> +   }
>>> }
>>> if (nr_pass == nr_cpus) {
>>> -   report("Completed in %d ms", true, ++i * 100);
>>> +   report("Completed in %d ms", !bad, ++i * 100);
>>> return;
>>> }
>>> }
>>> @@ -91,6 +119,22 @@ static void check_spurious(void)
>>> }
>>>  }
>>>  
>>> +static void check_ipi_sender(u32 irqstat)
>>> +{
>>> +   if (gic_version() == 2) {
>>> +   int src = (irqstat >> 10) & 7;
>>> +
>>> +   if (src != cmdl_sender)
>>> +   bad_sender[smp_processor_id()] = src;
>>> +   }
>>> +}
>>> +
>>> +static void check_irqnr(u32 irqnr)
>>> +{
>>> +   if (irqnr != (u32)cmdl_irq)
>>> +   bad_irq[smp_processor_id()] = irqnr;
>>> +}
>>> +
>>>  static void ipi_handler(struct pt_regs *regs __unused)
>>>  {
>>> u32 irqstat = gic_read_iar();
>>> @@ -98,8 +142,10 @@ static void ipi_handler(struct pt_regs *regs __unused)
>>>  
>>> if (irqnr != GICC_INT_SPURIOUS) {
>>> gic_write_eoir(irqstat);
>>> -   smp_rmb(); /* pairs with wmb in ipi_test functions */
>>> +   smp_rmb(); /* pairs with wmb in stats_reset */
>>> ++acked[smp_processor_id()];
>>> +   check_ipi_sender(irqstat);
>>> +   check_irqnr(irqnr);
>>> smp_wmb(); /* pairs with rmb in check_acked */
>>> } else {
>>> ++spurious[smp_processor_id()];
>>> @@ -109,19 +155,19 @@ static void ipi_handler(struct pt_regs *regs __unused)
>>>  
>>>  static void gicv2_ipi_send_self(void)
>>>  {
>>> -   writel(2 << 24, gicv2_dist_base() + GICD_SGIR);
>>> +   writel(2 << 24 | cmdl_irq, gicv2_dist_base() + GICD_SGIR);
>>>  }
>>>  
>>> -static void gicv2_ipi_send_tlist(cpumask_t 

Re: [Qemu-devel] [kvm-unit-tests PATCH 3/4] arm/arm64: GICv2: add GICD_ITARGETSR testing

2016-11-23 Thread Auger Eric
Hi,

On 18/11/2016 15:20, Andrew Jones wrote:
> On Thu, Nov 17, 2016 at 05:57:51PM +, Andre Przywara wrote:
>> Some tests for the ITARGETS registers.
>> Bits corresponding to non-existent CPUs must be RAZ/WI.
>> These registers must be byte-accessible, also check that accesses beyond
>> the implemented IRQ limit are actually read-as-zero/write-ignore.
>>
>> Signed-off-by: Andre Przywara 
>> ---
>>  arm/gic.c | 54 
>> ++
>>  lib/arm/asm/gic.h |  1 +
>>  2 files changed, 55 insertions(+)
>>
>> diff --git a/arm/gic.c b/arm/gic.c
>> index a27da2c..02b1be1 100644
>> --- a/arm/gic.c
>> +++ b/arm/gic.c
>> @@ -397,6 +397,57 @@ static bool test_priorities(int nr_irqs, void *priptr)
>>  return true;
>>  }
>>  
>> +static bool test_targets(int nr_irqs)
>> +{
>> +void *targetsptr = gicv2_dist_base() + GICD_ITARGETSR;
>> +u32 orig_targets;
>> +u32 cpu_mask;
>> +u32 pattern, reg;
>> +
>> +orig_targets = readl(targetsptr + 32);
>> +report_prefix_push("ITARGETSR");
>> +
>> +cpu_mask = (1 << nr_cpus) - 1;
> 
> Shouldn't this be 1 << (nr_cpus - 1) ?
original looks correct to me.
> 
> Is this test always going to be gicv2-only? We should probably comment it,
> if so. We don't want to risk this being run when nr_cpus can be larger
> than 8.
> 
>> +cpu_mask |= cpu_mask << 8;
>> +cpu_mask |= cpu_mask << 16;
Don't we miss the 4th byte mask?

Thanks

Eric
>> +
>> +/* Check that bits for non implemented CPUs are RAZ/WI. */
>> +if (nr_cpus < 8) {
>> +writel(0x, targetsptr + 32);
>> +report("bits for %d non-existent CPUs masked",
>> +   !(readl(targetsptr + 32) & ~cpu_mask), 8 - nr_cpus);
>> +} else {
>> +report_skip("CPU masking (all CPUs implemented)");
>> +}
>> +
>> +report("accesses beyond limit RAZ/WI",
>> +   test_readonly_32(targetsptr + nr_irqs, true));
>> +
>> +pattern = 0x0103020f;
>> +writel(pattern, targetsptr + 32);
>> +reg = readl(targetsptr + 32);
>> +report("register content preserved (%08x => %08x)",
>> +   reg == (pattern & cpu_mask), pattern & cpu_mask, reg);
>> +
>> +/*
>> + * The TARGETS registers are byte accessible, do a byte-wide
>> + * read and write of known content to check for this.
>> + */
>> +reg = readb(targetsptr + 33);
>> +report("byte reads successful (0x%08x => 0x%02x)",
>> +   reg == (BYTE(pattern, 1) & cpu_mask),
>> +   pattern & cpu_mask, reg);
>> +
>> +pattern = REPLACE_BYTE(pattern, 2, 0x04);
>> +writeb(BYTE(pattern, 2), targetsptr + 34);
>> +reg = readl(targetsptr + 32);
>> +report("byte writes successful (0x%02x => 0x%08x)",
>> +   reg == (pattern & cpu_mask), BYTE(pattern, 2), reg);
> 
> Last patch also had a byte addressability test. Maybe we should make
> a helper function?
> 
>> +
>> +writel(orig_targets, targetsptr + 32);
>> +return true;
> 
> Function can/should be void.
> 
>> +}
>> +
>>  static int gic_test_mmio(int gic_version)
>>  {
>>  u32 reg;
>> @@ -436,6 +487,9 @@ static int gic_test_mmio(int gic_version)
>>  
>>  test_priorities(nr_irqs, gic_dist_base + GICD_IPRIORITYR);
>>  
>> +if (gic_version == 2)
>> +test_targets(nr_irqs);
>> +
>>  return 0;
>>  }
>>  
>> diff --git a/lib/arm/asm/gic.h b/lib/arm/asm/gic.h
>> index cef748d..6f170cb 100644
>> --- a/lib/arm/asm/gic.h
>> +++ b/lib/arm/asm/gic.h
>> @@ -14,6 +14,7 @@
>>  #define GICD_IGROUPR0x0080
>>  #define GICD_ISENABLER  0x0100
>>  #define GICD_IPRIORITYR 0x0400
>> +#define GICD_ITARGETSR  0x0800
>>  #define GICD_SGIR   0x0f00
>>  #define GICD_ICPIDR20x0fe8
>>  
>> -- 
>> 2.9.0
>>
>>
> 
> Thanks,
> drew
> 
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [kvm-unit-tests PATCH v11 1/3] arm: Add PMU test

2016-11-23 Thread Andre Przywara
Hi,

On 22/11/16 18:29, Wei Huang wrote:
> From: Christopher Covington 
> 
> Beginning with a simple sanity check of the control register, add
> a unit test for the ARM Performance Monitors Unit (PMU).

Mmh, the output of this is a bit confusing. How about to join some
information? I changed it to give me:
INFO: pmu: PMU implementer/ID code: "A"(0x41)/0x0
INFO: pmu: Event counters:  0
PASS: pmu: Control register

... by using the newly introduced report_info() to make it look nicer.

> 
> Signed-off-by: Christopher Covington 
> Signed-off-by: Wei Huang 
> Reviewed-by: Andrew Jones 
> ---
>  arm/Makefile.common |  3 ++-
>  arm/pmu.c   | 74 
> +
>  arm/unittests.cfg   |  5 
>  3 files changed, 81 insertions(+), 1 deletion(-)
>  create mode 100644 arm/pmu.c
> 
> diff --git a/arm/Makefile.common b/arm/Makefile.common
> index f37b5c2..5da2fdd 100644
> --- a/arm/Makefile.common
> +++ b/arm/Makefile.common
> @@ -12,7 +12,8 @@ endif
>  tests-common = \
>   $(TEST_DIR)/selftest.flat \
>   $(TEST_DIR)/spinlock-test.flat \
> - $(TEST_DIR)/pci-test.flat
> + $(TEST_DIR)/pci-test.flat \
> + $(TEST_DIR)/pmu.flat
>  
>  all: test_cases
>  
> diff --git a/arm/pmu.c b/arm/pmu.c
> new file mode 100644
> index 000..9d9c53b
> --- /dev/null
> +++ b/arm/pmu.c
> @@ -0,0 +1,74 @@
> +/*
> + * Test the ARM Performance Monitors Unit (PMU).
> + *
> + * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 2.1 and
> + * only version 2.1 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful, but 
> WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
> License
> + * for more details.
> + */
> +#include "libcflat.h"
> +#include "asm/barrier.h"
> +
> +#define PMU_PMCR_N_SHIFT   11
> +#define PMU_PMCR_N_MASK0x1f
> +#define PMU_PMCR_ID_SHIFT  16
> +#define PMU_PMCR_ID_MASK   0xff
> +#define PMU_PMCR_IMP_SHIFT 24
> +#define PMU_PMCR_IMP_MASK  0xff
> +
> +#if defined(__arm__)

I guess you should use the arch specific header files we have in place
for that (lib/arm{.64}/asm/processor.h). Also there are sysreg read
wrappers (at least for arm64) in there already, can't we base this
function on them: DEFINE_GET_SYSREG32(pmcr, el0)?
(Requires a small change to get rid of the forced "_el1" suffix)

We should wait for the GIC series to be merged, as this contains some
changes in this area.

> +static inline uint32_t pmcr_read(void)
> +{
> + uint32_t ret;
> +
> + asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (ret));
> + return ret;
> +}
> +#elif defined(__aarch64__)
> +static inline uint32_t pmcr_read(void)
> +{
> + uint32_t ret;
> +
> + asm volatile("mrs %0, pmcr_el0" : "=r" (ret));
> + return ret;
> +}
> +#endif
> +
> +/*
> + * As a simple sanity check on the PMCR_EL0, ensure the implementer field 
> isn't
> + * null. Also print out a couple other interesting fields for diagnostic
> + * purposes. For example, as of fall 2016, QEMU TCG mode doesn't implement
> + * event counters and therefore reports zero event counters, but hopefully
> + * support for at least the instructions event will be added in the future 
> and
> + * the reported number of event counters will become nonzero.
> + */
> +static bool check_pmcr(void)
> +{
> + uint32_t pmcr;
> +
> + pmcr = pmcr_read();
> +
> + printf("PMU implementer: %c\n",
> +(pmcr >> PMU_PMCR_IMP_SHIFT) & PMU_PMCR_IMP_MASK);

If this register reads as zero, the output is mangled (since it cuts off
the string before the newline):
=
PMU implementer: Identification code: 0x0
=

I guess you need something like:
(pmcr >> PMU_PMCR_IMP_SHIFT) & PMU_PMCR_IMP_MASK ?: ' '

> + printf("Identification code: 0x%x\n",
> +(pmcr >> PMU_PMCR_ID_SHIFT) & PMU_PMCR_ID_MASK);

As mentioned above this should use report_info() now, also it would be
nice to merge this with the message above into one line of output.

Cheers,
Andre

> + printf("Event counters:  %d\n",
> +(pmcr >> PMU_PMCR_N_SHIFT) & PMU_PMCR_N_MASK);
> +
> + return ((pmcr >> PMU_PMCR_IMP_SHIFT) & PMU_PMCR_IMP_MASK) != 0;
> +}
> +
> +int main(void)
> +{
> + report_prefix_push("pmu");
> +
> + report("Control register", check_pmcr());
> +
> + return report_summary();
> +}
> diff --git a/arm/unittests.cfg b/arm/unittests.cfg
> index ae32a42..816f494 100644
> --- a/arm/unittests.cfg
> +++ b/arm/unittests.cfg
> @@ -58,3 +58,8 @@ groups = selftest
>  [pci-test]
>  file = pci-test.flat
>  groups = pci
> +
> +# Test PMU support
> +[pmu]
> +file = 

Re: [Qemu-devel] [kvm-unit-tests PATCH 2/4] arm/arm64: GICv2: add GICD_IPRIORITYR testing

2016-11-23 Thread Auger Eric
Hi Andre,
On 18/11/2016 15:02, Andrew Jones wrote:
> On Thu, Nov 17, 2016 at 05:57:50PM +, Andre Przywara wrote:
>> Some tests for the IPRIORITY registers. The significant number of bits
>> is IMPLEMENTATION DEFINED, but should be the same for every IRQ.
>> Also these registers must be byte-accessible.
>> Check that accesses beyond the implemented IRQ limit are actually
>> read-as-zero/write-ignore.
>>
>> Signed-off-by: Andre Przywara 
>> ---
>>  arm/gic.c | 72 
>> +++
>>  1 file changed, 72 insertions(+)
>>
>> diff --git a/arm/gic.c b/arm/gic.c
>> index ba2585b..a27da2c 100644
>> --- a/arm/gic.c
>> +++ b/arm/gic.c
>> @@ -327,6 +327,76 @@ static bool test_typer_v2(uint32_t reg)
>>  return true;
>>  }
>>  
>> +#define BYTE(reg32, byte) (((reg32) >> ((byte) * 8)) & 0xff)
>> +#define REPLACE_BYTE(reg32, byte, new) (((reg32) & ~(0xff << ((byte) * 8))) 
>> |\
>> +((new) << ((byte) * 8)))
>> +
>> +static bool test_priorities(int nr_irqs, void *priptr)
>> +{
>> +u32 orig_prio, reg, pri_bits;
>> +u32 pri_mask, pattern;
>> +
>> +orig_prio = readl(priptr + 32);
>> +report_prefix_push("IPRIORITYR");
>> +
>> +/*
>> + * Determine implemented number of priority bits by writing all 1's
>> + * and checking the number of cleared bits in the value read back.
>> + */
>> +writel(0x, priptr + 32);
>> +pri_mask = readl(priptr + 32);
>> +
>> +reg = ~pri_mask;
>> +report("consistent priority masking (0x%08x)",
>> +   (((reg >> 16) == (reg & 0x)) &&
>> +((reg & 0xff) == ((reg >> 8) & 0xff))), pri_mask);
>> +
>> +reg = reg & 0xff;
>> +for (pri_bits = 8; reg & 1; reg >>= 1, pri_bits--)
>> +;
>> +report("implements at least 4 priority bits (%d)",
>> +   pri_bits >= 4, pri_bits);
>> +
>> +pattern = 0;
>> +writel(pattern, priptr + 32);
>> +report("clearing priorities", readl(priptr + 32) == pattern);
>> +
>> +pattern = 0x;
>> +writel(pattern, priptr + 32);
>> +report("filling priorities",
>> +   readl(priptr + 32) == (pattern & pri_mask));
what's the point to re-do that check?
>> +
>> +report("accesses beyond limit RAZ/WI",
>> +   test_readonly_32(priptr + nr_irqs, true));
>> +
>> +writel(pattern, priptr + nr_irqs - 4);
>> +report("accessing last SPIs",
>> +   readl(priptr + nr_irqs - 4) == (pattern & pri_mask));
>> +
>> +pattern = 0xff7fbf3f;
>> +writel(pattern, priptr + 32);
>> +report("priorities are preserved",
>> +   readl(priptr + 32) == (pattern & pri_mask));
>> +
>> +/*
>> + * The PRIORITY registers are byte accessible, do a byte-wide
>> + * read and write of known content to check for this.
>> + */
>> +reg = readb(priptr + 33);
>> +report("byte reads successful (0x%08x => 0x%02x)",
>> +   reg == (BYTE(pattern, 1) & pri_mask), pattern & pri_mask, reg);
>> +
>> +pattern = REPLACE_BYTE(pattern, 2, 0x1f);
>> +writeb(BYTE(pattern, 2), priptr + 34);
>> +reg = readl(priptr + 32);
>> +report("byte writes successful (0x%02x => 0x%08x)",
>> +   reg == (pattern & pri_mask), BYTE(pattern, 2) & pri_mask, reg);
>> +
>> +report_prefix_pop();
>> +writel(orig_prio, priptr + 32);
>> +return true;
> 
> Might be nice to have FIRST_SPI and maybe LAST_SPI macros to avoid all
> the +32's
> 
> This function always returns true, so it can be a void.
> 
>> +}
>> +
>>  static int gic_test_mmio(int gic_version)
>>  {
>>  u32 reg;
>> @@ -364,6 +434,8 @@ static int gic_test_mmio(int gic_version)
>> test_readonly_32(idreg, false),
>> reg);
>>  
>> +test_priorities(nr_irqs, gic_dist_base + GICD_IPRIORITYR);
> 
> Feel free to add state like nr_irqs and dist_base to the gic struct
> defined in arm/gic.c. That struct should provide the abstraction
> needed to handle both gicv2 and gicv3 and contain anything that the
> test functions need to refer to frequently. Using it should help
> reduce the amount of parameters passed around.
> 
>> +
>>  return 0;
>>  }
>>  
>> -- 
>> 2.9.0
> 
> Otherwise looks good to me
same: Reviewed-by: Eric Auger 

Thanks

Eric

> 
> Reviewed-by: Andrew Jones 
>>
>>
> 
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [Qemu-devel] [kvm-unit-tests PATCH v6 00/11] arm/arm64: add gic framework

2016-11-23 Thread Andrew Jones
On Wed, Nov 23, 2016 at 12:33:53PM +0100, Auger Eric wrote:
> Hi,
> On 23/11/2016 11:09, Alex Bennée wrote:
> > 
> > Andrew Jones  writes:
> > 
> >> Andre, Alex, Eric, anybody,
> >>
> >> Any more comments on this? If not, I'll send a pull request
> >> to Radim and Paolo to finally get this merged.
> > 
> > Looks good to me. I successfully re-based my TCG tests on top and they
> > work fine ;-)
> no blocking point for me either. That's already a huge work and when
> adding new tests we may end up rationalizing things in separate v2/v3
> lib files and ops.
> 
> Tested on Cavium ThunderX
> 
> Reviewed-by: Eric Auger 
> Tested-by: Eric Auger 

Thanks Eric!

I like your suggestions for "gicv3: add an IPI test", so I'll
spin a v7.

drew

> 
> Thanks
> 
> Eric
> 
> 
> > 
> > Tested-by: Alex Bennée 
> > 
> >>
> >> Thanks,
> >> drew
> >>
> >>
> >> On Mon, Nov 14, 2016 at 10:08:28PM +0100, Andrew Jones wrote:
> >>> v6:
> >>>  - rebased to latest master
> >>>  - several other changes thanks to Andre and Alex, changes in
> >>>individual patch change logs
> >>>  - some code cleanups
> >>>
> >>> v5:
> >>>  - fix arm32/gicv3 compile [drew]
> >>>  - use modern register names [Andre]
> >>>  - one Andre r-b
> >>>
> >>> v4:
> >>>  - Eric's r-b's
> >>>  - Andre's suggestion to only take defines we need
> >>>  - several other changes listed in individual patches
> >>>
> >>> v3:
> >>>  - Rebased on latest master
> >>>  - Added Alex's r-b's
> >>>
> >>> v2:
> >>>  Rebased on latest master + my "populate argv[0]" series (will
> >>>  send a REPOST for that shortly. Additionally a few patches got
> >>>  fixes/features;
> >>>  07/10 got same fix as kernel 7c9b973061 "irqchip/gic-v3: Configure
> >>>all interrupts as non-secure Group-1" in order to continue
> >>>working over TCG, as the gicv3 code for TCG removed a hack
> >>>it had there to make Linux happy.
> >>>  08/10 added more output for when things fail (if they fail)
> >>>  09/10 switched gicv3 broadcast implementation to using IRM. This
> >>>found a bug in a recent (but not tip) kernel, which I was
> >>>about to fix, but then I saw MarcZ beat me to it.
> >>>  10/10 actually check that the input irq is the received irq
> >>>
> >>>
> >>> Import defines, and steal enough helper functions, from Linux to
> >>> enable programming of the gic (v2 and v3). Then use the framework
> >>> to add an initial test (an ipi test; self, target-list, broadcast).
> >>>
> >>> It's my hope that this framework will be a suitable base on which
> >>> more tests may be easily added, particularly because we have
> >>> vgic-new and tcg gicv3 emulation getting close to merge. (v3 UPDATE:
> >>> vgic-new and tcg gicv3 are merged now)
> >>>
> >>> To run it, along with other tests, just do
> >>>
> >>>  ./configure [ --arch=[arm|arm64] --cross-prefix=$PREFIX ]
> >>>  make
> >>>  export QEMU=$PATH_TO_QEMU
> >>>  ./run_tests.sh
> >>>
> >>> To run it separately do, e.g.
> >>>
> >>> $QEMU -machine virt,accel=tcg -cpu cortex-a57 \
> >>>  -device virtio-serial-device \
> >>>  -device virtconsole,chardev=ctd -chardev testdev,id=ctd \
> >>>  -display none -serial stdio \
> >>>  -kernel arm/gic.flat \
> >>>  -smp 123 -machine gic-version=3 -append ipi
> >>>   ^^ note, we can go nuts with nr-cpus on TCG :-)
> >>>
> >>> Or, a KVM example using a different "sender" cpu and irq (other than zero)
> >>>
> >>> $QEMU -machine virt,accel=kvm -cpu host \
> >>>  -device virtio-serial-device \
> >>>  -device virtconsole,chardev=ctd -chardev testdev,id=ctd \
> >>>  -display none -serial stdio \
> >>>  -kernel arm/gic.flat \
> >>>  -smp 48 -machine gic-version=3 -append 'ipi sender=42 irq=1'
> >>>
> >>>
> >>> Patches:
> >>> 01-05: fixes and functionality needed by the later gic patches
> >>> 06-07: enable gicv2 and gicv2 IPI test
> >>> 08-10: enable gicv3 and gicv3 IPI test
> >>>11: extend the IPI tests to take variable sender and irq
> >>>
> >>> Available here: 
> >>> https://github.com/rhdrjones/kvm-unit-tests/commits/arm/gic-v6
> >>>
> >>>
> >>> Andrew Jones (10):
> >>>   lib: xstr: allow multiple args
> >>>   arm64: fix get_"sysreg32" and make MPIDR 64bit
> >>>   arm/arm64: smp: support more than 8 cpus
> >>>   arm/arm64: add some delay routines
> >>>   arm/arm64: irq enable/disable
> >>>   arm/arm64: add initial gicv2 support
> >>>   arm/arm64: gicv2: add an IPI test
> >>>   arm/arm64: add initial gicv3 support
> >>>   arm/arm64: gicv3: add an IPI test
> >>>   arm/arm64: gic: don't just use zero
> >>>
> >>> Peter Xu (1):
> >>>   libcflat: add IS_ALIGNED() macro, and page sizes
> >>>
> >>>  arm/Makefile.common|   9 +-
> >>>  arm/gic.c  | 340 
> >>> +
> >>>  arm/run|  19 ++-
> >>>  arm/selftest.c |   5 +-
> >>>  arm/unittests.cfg  |  14 ++
> >>>  lib/arm/asm/arch_gicv3.h   |  70 

[PATCH v9 02/11] arm/arm64: vgic: Add distributor and redistributor access

2016-11-23 Thread vijay . kilari
From: Vijaya Kumar K 

VGICv3 Distributor and Redistributor registers are accessed using
KVM_DEV_ARM_VGIC_GRP_DIST_REGS and KVM_DEV_ARM_VGIC_GRP_REDIST_REGS
with KVM_SET_DEVICE_ATTR and KVM_GET_DEVICE_ATTR ioctls.
These registers are accessed as 32-bit and cpu mpidr
value passed along with register offset is used to identify the
cpu for redistributor registers access.

The version of VGIC v3 specification is define here
Documentation/virtual/kvm/devices/arm-vgic-v3.txt

Also update arch/arm/include/uapi/asm/kvm.h to compile for
AArch32 mode.

Signed-off-by: Vijaya Kumar K 
---
 arch/arm/include/uapi/asm/kvm.h |   4 +
 arch/arm64/include/uapi/asm/kvm.h   |   4 +
 virt/kvm/arm/vgic/vgic-kvm-device.c | 144 ++--
 virt/kvm/arm/vgic/vgic-mmio-v2.c|  16 +---
 virt/kvm/arm/vgic/vgic-mmio-v3.c|  72 ++
 virt/kvm/arm/vgic/vgic-mmio.c   |  22 ++
 virt/kvm/arm/vgic/vgic-mmio.h   |   4 +
 virt/kvm/arm/vgic/vgic.h|  49 +++-
 8 files changed, 292 insertions(+), 23 deletions(-)

diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
index af05f8e..0ae6035 100644
--- a/arch/arm/include/uapi/asm/kvm.h
+++ b/arch/arm/include/uapi/asm/kvm.h
@@ -181,10 +181,14 @@ struct kvm_arch_memory_slot {
 #define KVM_DEV_ARM_VGIC_GRP_CPU_REGS  2
 #define   KVM_DEV_ARM_VGIC_CPUID_SHIFT 32
 #define   KVM_DEV_ARM_VGIC_CPUID_MASK  (0xffULL << 
KVM_DEV_ARM_VGIC_CPUID_SHIFT)
+#define   KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT 32
+#define   KVM_DEV_ARM_VGIC_V3_MPIDR_MASK \
+   (0xULL << KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT)
 #define   KVM_DEV_ARM_VGIC_OFFSET_SHIFT0
 #define   KVM_DEV_ARM_VGIC_OFFSET_MASK (0xULL << 
KVM_DEV_ARM_VGIC_OFFSET_SHIFT)
 #define KVM_DEV_ARM_VGIC_GRP_NR_IRQS   3
 #define KVM_DEV_ARM_VGIC_GRP_CTRL   4
+#define KVM_DEV_ARM_VGIC_GRP_REDIST_REGS 5
 #define   KVM_DEV_ARM_VGIC_CTRL_INIT0
 
 /* KVM_IRQ_LINE irq field index values */
diff --git a/arch/arm64/include/uapi/asm/kvm.h 
b/arch/arm64/include/uapi/asm/kvm.h
index 3051f86..56dc08d 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -201,10 +201,14 @@ struct kvm_arch_memory_slot {
 #define KVM_DEV_ARM_VGIC_GRP_CPU_REGS  2
 #define   KVM_DEV_ARM_VGIC_CPUID_SHIFT 32
 #define   KVM_DEV_ARM_VGIC_CPUID_MASK  (0xffULL << 
KVM_DEV_ARM_VGIC_CPUID_SHIFT)
+#define   KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT 32
+#define   KVM_DEV_ARM_VGIC_V3_MPIDR_MASK \
+   (0xULL << KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT)
 #define   KVM_DEV_ARM_VGIC_OFFSET_SHIFT0
 #define   KVM_DEV_ARM_VGIC_OFFSET_MASK (0xULL << 
KVM_DEV_ARM_VGIC_OFFSET_SHIFT)
 #define KVM_DEV_ARM_VGIC_GRP_NR_IRQS   3
 #define KVM_DEV_ARM_VGIC_GRP_CTRL  4
+#define KVM_DEV_ARM_VGIC_GRP_REDIST_REGS 5
 #define   KVM_DEV_ARM_VGIC_CTRL_INIT   0
 
 /* Device Control API on vcpu fd */
diff --git a/virt/kvm/arm/vgic/vgic-kvm-device.c 
b/virt/kvm/arm/vgic/vgic-kvm-device.c
index fbe87a6..bc7de95 100644
--- a/virt/kvm/arm/vgic/vgic-kvm-device.c
+++ b/virt/kvm/arm/vgic/vgic-kvm-device.c
@@ -235,7 +235,7 @@ struct vgic_reg_attr {
gpa_t addr;
 };
 
-static int parse_vgic_v2_attr(struct kvm_device *dev,
+static int vgic_v2_parse_attr(struct kvm_device *dev,
  struct kvm_device_attr *attr,
  struct vgic_reg_attr *reg_attr)
 {
@@ -292,14 +292,14 @@ static bool lock_all_vcpus(struct kvm *kvm)
 }
 
 /**
- * vgic_attr_regs_access_v2 - allows user space to access VGIC v2 state
+ * vgic_v2_attr_regs_access - allows user space to access VGIC v2 state
  *
  * @dev:  kvm device handle
  * @attr: kvm device attribute
  * @reg:  address the value is read or written
  * @is_write: true if userspace is writing a register
  */
-static int vgic_attr_regs_access_v2(struct kvm_device *dev,
+static int vgic_v2_attr_regs_access(struct kvm_device *dev,
struct kvm_device_attr *attr,
u32 *reg, bool is_write)
 {
@@ -308,7 +308,7 @@ static int vgic_attr_regs_access_v2(struct kvm_device *dev,
struct kvm_vcpu *vcpu;
int ret;
 
-   ret = parse_vgic_v2_attr(dev, attr, _attr);
+   ret = vgic_v2_parse_attr(dev, attr, _attr);
if (ret)
return ret;
 
@@ -362,7 +362,7 @@ static int vgic_v2_set_attr(struct kvm_device *dev,
if (get_user(reg, uaddr))
return -EFAULT;
 
-   return vgic_attr_regs_access_v2(dev, attr, , true);
+   return vgic_v2_attr_regs_access(dev, attr, , true);
}
}
 
@@ -384,7 +384,7 @@ static int vgic_v2_get_attr(struct kvm_device *dev,
u32 __user *uaddr = (u32 __user *)(long)attr->addr;
u32 reg = 0;
 
-   ret = vgic_attr_regs_access_v2(dev, attr, , false);
+   ret = 

[PATCH v9 08/11] arm/arm64: Documentation: Update arm-vgic-v3.txt

2016-11-23 Thread vijay . kilari
From: Vijaya Kumar K 

Update error code returned for Invalid CPU interface register
value.

Signed-off-by: Vijaya Kumar K 
---
 Documentation/virtual/kvm/devices/arm-vgic-v3.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/virtual/kvm/devices/arm-vgic-v3.txt 
b/Documentation/virtual/kvm/devices/arm-vgic-v3.txt
index 9348b3c..bff2898 100644
--- a/Documentation/virtual/kvm/devices/arm-vgic-v3.txt
+++ b/Documentation/virtual/kvm/devices/arm-vgic-v3.txt
@@ -145,7 +145,7 @@ Groups:
   Errors:
 -ENXIO: Getting or setting this register is not yet supported
 -EBUSY: VCPU is running
--EINVAL: Invalid mpidr supplied
+-EINVAL: Invalid mpidr or register value supplied
 
 
   KVM_DEV_ARM_VGIC_GRP_NR_IRQS
-- 
1.9.1

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


[PATCH v9 07/11] arm/arm64: vgic: Implement KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO ioctl

2016-11-23 Thread vijay . kilari
From: Vijaya Kumar K 

Userspace requires to store and restore of line_level for
level triggered interrupts using ioctl KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO.

Signed-off-by: Vijaya Kumar K 
---
 arch/arm/include/uapi/asm/kvm.h |  7 ++
 arch/arm64/include/uapi/asm/kvm.h   |  6 +
 virt/kvm/arm/vgic/vgic-kvm-device.c | 49 -
 virt/kvm/arm/vgic/vgic-mmio-v3.c| 11 +
 virt/kvm/arm/vgic/vgic-mmio.c   | 38 
 virt/kvm/arm/vgic/vgic-mmio.h   |  5 
 virt/kvm/arm/vgic/vgic.h|  2 ++
 7 files changed, 117 insertions(+), 1 deletion(-)

diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
index 98658d9d..f347779 100644
--- a/arch/arm/include/uapi/asm/kvm.h
+++ b/arch/arm/include/uapi/asm/kvm.h
@@ -191,6 +191,13 @@ struct kvm_arch_memory_slot {
 #define KVM_DEV_ARM_VGIC_GRP_CTRL   4
 #define KVM_DEV_ARM_VGIC_GRP_REDIST_REGS 5
 #define KVM_DEV_ARM_VGIC_CPU_SYSREGS6
+#define KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO 7
+#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT 10
+#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK \
+   (0x3fULL << KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT)
+#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INTID_MASK 0x3ff
+#define VGIC_LEVEL_INFO_LINE_LEVEL 0
+
 #define   KVM_DEV_ARM_VGIC_CTRL_INIT0
 
 /* KVM_IRQ_LINE irq field index values */
diff --git a/arch/arm64/include/uapi/asm/kvm.h 
b/arch/arm64/include/uapi/asm/kvm.h
index 91c7137..4100f8c 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -211,6 +211,12 @@ struct kvm_arch_memory_slot {
 #define KVM_DEV_ARM_VGIC_GRP_CTRL  4
 #define KVM_DEV_ARM_VGIC_GRP_REDIST_REGS 5
 #define KVM_DEV_ARM_VGIC_CPU_SYSREGS6
+#define KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO 7
+#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT 10
+#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK \
+   (0x3fULL << KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT)
+#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INTID_MASK 0x3ff
+#define VGIC_LEVEL_INFO_LINE_LEVEL 0
 
 #define   KVM_DEV_ARM_VGIC_CTRL_INIT   0
 
diff --git a/virt/kvm/arm/vgic/vgic-kvm-device.c 
b/virt/kvm/arm/vgic/vgic-kvm-device.c
index b6266fe..52ed00b 100644
--- a/virt/kvm/arm/vgic/vgic-kvm-device.c
+++ b/virt/kvm/arm/vgic/vgic-kvm-device.c
@@ -510,6 +510,25 @@ static int vgic_v3_attr_regs_access(struct kvm_device *dev,
  regid, reg);
break;
}
+   case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO: {
+   unsigned int info, intid;
+
+   info = (attr->attr & KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK) >>
+   KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT;
+   if (info == VGIC_LEVEL_INFO_LINE_LEVEL) {
+   if (is_write)
+   tmp32 = *reg;
+   intid = attr->attr &
+   KVM_DEV_ARM_VGIC_LINE_LEVEL_INTID_MASK;
+   ret = vgic_v3_line_level_info_uaccess(vcpu, is_write,
+ intid, );
+   if (!is_write)
+   *reg = tmp32;
+   } else {
+   ret = -EINVAL;
+   }
+   break;
+   }
default:
ret = -EINVAL;
break;
@@ -552,6 +571,17 @@ static int vgic_v3_set_attr(struct kvm_device *dev,
 
return vgic_v3_attr_regs_access(dev, attr, , true);
}
+   case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO: {
+   u32 __user *uaddr = (u32 __user *)(long)attr->addr;
+   u64 reg;
+   u32 tmp32;
+
+   if (get_user(tmp32, uaddr))
+   return -EFAULT;
+
+   reg = tmp32;
+   return vgic_v3_attr_regs_access(dev, attr, , true);
+   }
}
return -ENXIO;
 }
@@ -587,8 +617,18 @@ static int vgic_v3_get_attr(struct kvm_device *dev,
return ret;
return put_user(reg, uaddr);
}
-   }
+   case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO: {
+   u32 __user *uaddr = (u32 __user *)(long)attr->addr;
+   u64 reg;
+   u32 tmp32;
 
+   ret = vgic_v3_attr_regs_access(dev, attr, , false);
+   if (ret)
+   return ret;
+   tmp32 = reg;
+   return put_user(tmp32, uaddr);
+   }
+   }
return -ENXIO;
 }
 
@@ -609,6 +649,13 @@ static int vgic_v3_has_attr(struct kvm_device *dev,
return vgic_v3_has_attr_regs(dev, attr);
case KVM_DEV_ARM_VGIC_GRP_NR_IRQS:
return 0;
+   case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO: {
+   if (((attr->attr & KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK) >>
+ 

[PATCH v9 11/11] arm: vgic: Save and restore GICv3 CPU interface regs for AArch32

2016-11-23 Thread vijay . kilari
From: Vijaya Kumar K 

Use coproc_reg infrastructure to save and restore CPU
interface register of GICv3 for AArch32 host.

Signed-off-by: Vijaya Kumar K 
---
 arch/arm/kvm/Makefile  |   2 +
 virt/kvm/arm/vgic/vgic-coproc-reg-v3.c | 155 +
 2 files changed, 157 insertions(+)

diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile
index d571243..451e666 100644
--- a/arch/arm/kvm/Makefile
+++ b/arch/arm/kvm/Makefile
@@ -32,6 +32,8 @@ obj-y += $(KVM)/arm/vgic/vgic-mmio.o
 obj-y += $(KVM)/arm/vgic/vgic-mmio-v2.o
 obj-y += $(KVM)/arm/vgic/vgic-mmio-v3.o
 obj-y += $(KVM)/arm/vgic/vgic-kvm-device.o
+obj-y += $(KVM)/arm/vgic/vgic-sys-reg-common.o
+obj-y += $(KVM)/arm/vgic/vgic-coproc-reg-v3.o
 obj-y += $(KVM)/arm/vgic/vgic-its.o
 obj-y += $(KVM)/irqchip.o
 obj-y += $(KVM)/arm/arch_timer.o
diff --git a/virt/kvm/arm/vgic/vgic-coproc-reg-v3.c 
b/virt/kvm/arm/vgic/vgic-coproc-reg-v3.c
new file mode 100644
index 000..25d00e5
--- /dev/null
+++ b/virt/kvm/arm/vgic/vgic-coproc-reg-v3.c
@@ -0,0 +1,155 @@
+/*
+ * VGIC system registers handling functions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "vgic.h"
+#include "coproc.h"
+
+#define ACCESS_COPROC_REG(REG) \
+static bool access_gic_##REG##_coproc_reg(struct kvm_vcpu *vcpu,   \
+  struct coproc_params *p, \
+  const struct coproc_reg *r)  \
+{  \
+   return  access_gic_##REG##_reg(vcpu, p->is_write, >Rt1); \
+}
+
+ACCESS_COPROC_REG(ctlr)
+ACCESS_COPROC_REG(pmr)
+ACCESS_COPROC_REG(bpr0)
+ACCESS_COPROC_REG(bpr1)
+ACCESS_COPROC_REG(sre)
+ACCESS_COPROC_REG(grpen0)
+ACCESS_COPROC_REG(grpen1)
+
+#define ACCESS_COPROC_APNR_REG(REG)\
+static bool access_gic_##REG##_coproc_reg(struct kvm_vcpu *vcpu,   \
+  struct coproc_params *p, \
+  const struct coproc_reg *r)  \
+{  \
+   u8 idx = p->Op2 & 3;\
+   \
+   return access_gic_##REG##_reg(vcpu, p->is_write, idx, >Rt1); \
+}
+
+ACCESS_COPROC_APNR_REG(ap0r)
+ACCESS_COPROC_APNR_REG(ap1r)
+
+static const struct coproc_reg gic_v3_icc_coproc_reg_descs[] = {
+   /* ICC_PMR_EL1 */
+   { CRn(0), CRm(6), Op1(0), Op2(0), is32, access_gic_pmr_coproc_reg },
+   /* ICC_BPR0_EL1 */
+   { CRn(12), CRm(8), Op1(0), Op2(3), is32, access_gic_bpr0_coproc_reg },
+   /* ICC_AP0R0_EL1 */
+   { CRn(12), CRm(8), Op1(0), Op2(4), is32, access_gic_ap0r_coproc_reg },
+   /* ICC_AP0R1_EL1 */
+   { CRn(12), CRm(8), Op1(0), Op2(5), is32, access_gic_ap0r_coproc_reg },
+   /* ICC_AP0R2_EL1 */
+   { CRn(12), CRm(8), Op1(0), Op2(6), is32, access_gic_ap0r_coproc_reg },
+   /* ICC_AP0R3_EL1 */
+   { CRn(12), CRm(8), Op1(0), Op2(7), is32, access_gic_ap0r_coproc_reg },
+   /* ICC_AP1R0_EL1 */
+   { CRn(12), CRm(9), Op1(0), Op2(0), is32, access_gic_ap1r_coproc_reg },
+   /* ICC_AP1R1_EL1 */
+   { CRn(12), CRm(9), Op1(0), Op2(1), is32, access_gic_ap1r_coproc_reg },
+   /* ICC_AP1R2_EL1 */
+   { CRn(12), CRm(9), Op1(0), Op2(2), is32, access_gic_ap1r_coproc_reg },
+   /* ICC_AP1R3_EL1 */
+   { CRn(12), CRm(9), Op1(0), Op2(3), is32, access_gic_ap1r_coproc_reg },
+   /* ICC_BPR1_EL1 */
+   { CRn(12), CRm(12), Op1(0), Op2(3), is32, access_gic_bpr1_coproc_reg },
+   /* ICC_CTLR_EL1 */
+   { CRn(12), CRm(12), Op1(0), Op2(4), is32, access_gic_ctlr_coproc_reg },
+   /* ICC_SRE_EL1 */
+   { CRn(12), CRm(12), Op1(0), Op2(5), is32, access_gic_sre_coproc_reg },
+   /* ICC_IGRPEN0_EL1 */
+   { CRn(12), CRm(12), Op1(0), Op2(6), is32,
+ access_gic_grpen0_coproc_reg },
+   /* ICC_GRPEN1_EL1 */
+   { CRn(12), CRm(12), Op1(0), Op2(7), is32,
+ access_gic_grpen1_coproc_reg },
+};
+
+
+#define KVM_DEV_ARM_VGIC_COPROC_MASK 0x3fff
+
+/* As per Documentation/virtual/kvm/devices/arm-vgic-v3.txt,
+ * CPUREGs id is passed in AArch64 system register encoding format.
+ * Format to COPROC register format for AArch32 mode before using.
+ */
+static u64 vgic_to_cpreg(u64 id)
+{
+   u64 cpreg 

[PATCH v9 06/11] arm/arm64: vgic: Implement VGICv3 CPU interface access

2016-11-23 Thread vijay . kilari
From: Vijaya Kumar K 

VGICv3 CPU interface registers are accessed using
KVM_DEV_ARM_VGIC_CPU_SYSREGS ioctl. These registers are accessed
as 64-bit. The cpu MPIDR value is passed along with register id.
is used to identify the cpu for registers access.

The VM that supports SEIs expect it on destination machine to handle
guest aborts and hence checked for ICC_CTLR_EL1.SEIS compatibility.
Similarly, VM that supports Affinity Level 3 that is required for AArch64
mode, is required to be supported on destination machine. Hence checked
for ICC_CTLR_EL1.A3V compatibility.

The CPU system register handling is spitted into two files
vgic-sys-reg-common.c and vgic-sys-reg-v3.c.
The vgic-sys-reg-common.c handles read and write of VGIC CPU registers
for both AArch64 and AArch32 mode. The vgic-sys-reg-v3.c handles AArch64
mode and is compiled only for AArch64 mode.

Updated arch/arm/include/uapi/asm/kvm.h with new definitions
required to compile for AArch32.

The version of VGIC v3 specification is define here
Documentation/virtual/kvm/devices/arm-vgic-v3.txt

Signed-off-by: Pavel Fedin 
Signed-off-by: Vijaya Kumar K 
---
 arch/arm/include/uapi/asm/kvm.h |   2 +
 arch/arm64/include/uapi/asm/kvm.h   |   3 +
 arch/arm64/kvm/Makefile |   2 +
 include/kvm/arm_vgic.h  |   9 ++
 virt/kvm/arm/vgic/vgic-kvm-device.c |  28 
 virt/kvm/arm/vgic/vgic-mmio-v3.c|  18 +++
 virt/kvm/arm/vgic/vgic-sys-reg-common.c | 258 
 virt/kvm/arm/vgic/vgic-sys-reg-v3.c | 142 ++
 virt/kvm/arm/vgic/vgic-v3.c |   8 +
 virt/kvm/arm/vgic/vgic.h|  22 +++
 10 files changed, 492 insertions(+)

diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
index 0ae6035..98658d9d 100644
--- a/arch/arm/include/uapi/asm/kvm.h
+++ b/arch/arm/include/uapi/asm/kvm.h
@@ -186,9 +186,11 @@ struct kvm_arch_memory_slot {
(0xULL << KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT)
 #define   KVM_DEV_ARM_VGIC_OFFSET_SHIFT0
 #define   KVM_DEV_ARM_VGIC_OFFSET_MASK (0xULL << 
KVM_DEV_ARM_VGIC_OFFSET_SHIFT)
+#define   KVM_DEV_ARM_VGIC_SYSREG_INSTR_MASK (0x)
 #define KVM_DEV_ARM_VGIC_GRP_NR_IRQS   3
 #define KVM_DEV_ARM_VGIC_GRP_CTRL   4
 #define KVM_DEV_ARM_VGIC_GRP_REDIST_REGS 5
+#define KVM_DEV_ARM_VGIC_CPU_SYSREGS6
 #define   KVM_DEV_ARM_VGIC_CTRL_INIT0
 
 /* KVM_IRQ_LINE irq field index values */
diff --git a/arch/arm64/include/uapi/asm/kvm.h 
b/arch/arm64/include/uapi/asm/kvm.h
index 56dc08d..91c7137 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -206,9 +206,12 @@ struct kvm_arch_memory_slot {
(0xULL << KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT)
 #define   KVM_DEV_ARM_VGIC_OFFSET_SHIFT0
 #define   KVM_DEV_ARM_VGIC_OFFSET_MASK (0xULL << 
KVM_DEV_ARM_VGIC_OFFSET_SHIFT)
+#define   KVM_DEV_ARM_VGIC_SYSREG_INSTR_MASK (0x)
 #define KVM_DEV_ARM_VGIC_GRP_NR_IRQS   3
 #define KVM_DEV_ARM_VGIC_GRP_CTRL  4
 #define KVM_DEV_ARM_VGIC_GRP_REDIST_REGS 5
+#define KVM_DEV_ARM_VGIC_CPU_SYSREGS6
+
 #define   KVM_DEV_ARM_VGIC_CTRL_INIT   0
 
 /* Device Control API on vcpu fd */
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index d50a82a..5c8580e 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -32,5 +32,7 @@ kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-mmio-v3.o
 kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-kvm-device.o
 kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-its.o
 kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/irqchip.o
+kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-sys-reg-common.o
+kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-sys-reg-v3.o
 kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/arch_timer.o
 kvm-$(CONFIG_KVM_ARM_PMU) += $(KVM)/arm/pmu.o
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 002f092..730a18a 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -71,6 +71,9 @@ struct vgic_global {
 
/* GIC system register CPU interface */
struct static_key_false gicv3_cpuif;
+
+   /* Cache ICH_VTR_EL2 reg value */
+   u32 ich_vtr_el2;
 };
 
 extern struct vgic_global kvm_vgic_global_state;
@@ -269,6 +272,12 @@ struct vgic_cpu {
u64 pendbaser;
 
bool lpis_enabled;
+
+   /* Cache guest priority bits */
+   u32 num_pri_bits;
+
+   /* Cache guest interrupt ID bits */
+   u32 num_id_bits;
 };
 
 extern struct static_key_false vgic_v2_cpuif_trap;
diff --git a/virt/kvm/arm/vgic/vgic-kvm-device.c 
b/virt/kvm/arm/vgic/vgic-kvm-device.c
index bc7de95..b6266fe 100644
--- a/virt/kvm/arm/vgic/vgic-kvm-device.c
+++ b/virt/kvm/arm/vgic/vgic-kvm-device.c
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include "vgic.h"
 
@@ -501,6 +502,14 @@ static 

[PATCH v9 10/11] arm: coproc: Introduce find_coproc_reg_by_id()

2016-11-23 Thread vijay . kilari
From: Vijaya Kumar K 

To access CPU interface access in AArch32 mode, we need to
perform coproc_reg table lookup. For this introduce
find_coproc_reg_by_id() and export.

Also use this function internally in coproc.c wherever
required.

Signed-off-by: Vijaya Kumar K 
---
 arch/arm/kvm/coproc.c | 22 +++---
 arch/arm/kvm/coproc.h |  4 
 2 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c
index 5753926..7d05700 100644
--- a/arch/arm/kvm/coproc.c
+++ b/arch/arm/kvm/coproc.c
@@ -616,6 +616,17 @@ static bool index_to_params(u64 id, struct coproc_params 
*params)
}
 }
 
+const struct coproc_reg *
+find_coproc_reg_by_id(u64 id, struct coproc_params *params,
+ const struct coproc_reg table[],
+ unsigned int num)
+{
+   if (!index_to_params(id, params))
+   return NULL;
+
+   return find_reg(params, table, num);
+}
+
 /* Decode an index value, and find the cp15 coproc_reg entry. */
 static const struct coproc_reg *index_to_coproc_reg(struct kvm_vcpu *vcpu,
u64 id)
@@ -742,10 +753,8 @@ static int get_invariant_cp15(u64 id, void __user *uaddr)
const struct coproc_reg *r;
int ret;
 
-   if (!index_to_params(id, ))
-   return -ENOENT;
-
-   r = find_reg(, invariant_cp15, ARRAY_SIZE(invariant_cp15));
+   r = find_coproc_reg_by_id(id, , invariant_cp15,
+ ARRAY_SIZE(invariant_cp15));
if (!r)
return -ENOENT;
 
@@ -767,9 +776,8 @@ static int set_invariant_cp15(u64 id, void __user *uaddr)
int err;
u64 val;
 
-   if (!index_to_params(id, ))
-   return -ENOENT;
-   r = find_reg(, invariant_cp15, ARRAY_SIZE(invariant_cp15));
+   r = find_coproc_reg_by_id(id, , invariant_cp15,
+ ARRAY_SIZE(invariant_cp15));
if (!r)
return -ENOENT;
 
diff --git a/arch/arm/kvm/coproc.h b/arch/arm/kvm/coproc.h
index bbeff2a..2accd9d 100644
--- a/arch/arm/kvm/coproc.h
+++ b/arch/arm/kvm/coproc.h
@@ -157,4 +157,8 @@ bool access_vm_reg(struct kvm_vcpu *vcpu,
   struct coproc_params *p,
   const struct coproc_reg *r);
 
+const struct coproc_reg *
+find_coproc_reg_by_id(u64 id, struct coproc_params *params,
+ const struct coproc_reg table[],
+ unsigned int num);
 #endif /* __ARM_KVM_COPROC_LOCAL_H__ */
-- 
1.9.1

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


[PATCH v9 09/11] arm: coproc: Drop const from coproc reg access function

2016-11-23 Thread vijay . kilari
From: Vijaya Kumar K 

In order to read or write to coproc regiter, the
access function is should allow the coproc_param to be non
constant.

Signed-off-by: Vijaya Kumar K 
---
 arch/arm/kvm/coproc.c | 20 ++--
 arch/arm/kvm/coproc.h |  4 ++--
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c
index 3e5e419..5753926 100644
--- a/arch/arm/kvm/coproc.c
+++ b/arch/arm/kvm/coproc.c
@@ -113,7 +113,7 @@ static void reset_mpidr(struct kvm_vcpu *vcpu, const struct 
coproc_reg *r)
 
 /* TRM entries A7:4.3.31 A15:4.3.28 - RO WI */
 static bool access_actlr(struct kvm_vcpu *vcpu,
-const struct coproc_params *p,
+struct coproc_params *p,
 const struct coproc_reg *r)
 {
if (p->is_write)
@@ -125,7 +125,7 @@ static bool access_actlr(struct kvm_vcpu *vcpu,
 
 /* TRM entries A7:4.3.56, A15:4.3.60 - R/O. */
 static bool access_cbar(struct kvm_vcpu *vcpu,
-   const struct coproc_params *p,
+   struct coproc_params *p,
const struct coproc_reg *r)
 {
if (p->is_write)
@@ -135,7 +135,7 @@ static bool access_cbar(struct kvm_vcpu *vcpu,
 
 /* TRM entries A7:4.3.49, A15:4.3.48 - R/O WI */
 static bool access_l2ctlr(struct kvm_vcpu *vcpu,
- const struct coproc_params *p,
+ struct coproc_params *p,
  const struct coproc_reg *r)
 {
if (p->is_write)
@@ -181,7 +181,7 @@ static void reset_actlr(struct kvm_vcpu *vcpu, const struct 
coproc_reg *r)
  * R/O WI (even if NSACR.NS_L2ERR, a write of 1 is ignored).
  */
 static bool access_l2ectlr(struct kvm_vcpu *vcpu,
-  const struct coproc_params *p,
+  struct coproc_params *p,
   const struct coproc_reg *r)
 {
if (p->is_write)
@@ -195,7 +195,7 @@ static bool access_l2ectlr(struct kvm_vcpu *vcpu,
  * See note at ARMv7 ARM B1.14.4 (TL;DR: S/W ops are not easily virtualized).
  */
 static bool access_dcsw(struct kvm_vcpu *vcpu,
-   const struct coproc_params *p,
+   struct coproc_params *p,
const struct coproc_reg *r)
 {
if (!p->is_write)
@@ -213,7 +213,7 @@ static bool access_dcsw(struct kvm_vcpu *vcpu,
  * Used by the cpu-specific code.
  */
 bool access_vm_reg(struct kvm_vcpu *vcpu,
-  const struct coproc_params *p,
+  struct coproc_params *p,
   const struct coproc_reg *r)
 {
bool was_enabled = vcpu_has_cache_enabled(vcpu);
@@ -229,7 +229,7 @@ bool access_vm_reg(struct kvm_vcpu *vcpu,
 }
 
 static bool access_gic_sgi(struct kvm_vcpu *vcpu,
-  const struct coproc_params *p,
+  struct coproc_params *p,
   const struct coproc_reg *r)
 {
u64 reg;
@@ -246,7 +246,7 @@ static bool access_gic_sgi(struct kvm_vcpu *vcpu,
 }
 
 static bool access_gic_sre(struct kvm_vcpu *vcpu,
-  const struct coproc_params *p,
+  struct coproc_params *p,
   const struct coproc_reg *r)
 {
if (p->is_write)
@@ -267,7 +267,7 @@ static bool access_gic_sre(struct kvm_vcpu *vcpu,
  * all PM registers, which doesn't crash the guest kernel at least.
  */
 static bool pm_fake(struct kvm_vcpu *vcpu,
-   const struct coproc_params *p,
+   struct coproc_params *p,
const struct coproc_reg *r)
 {
if (p->is_write)
@@ -480,7 +480,7 @@ static const struct coproc_reg *find_reg(const struct 
coproc_params *params,
 }
 
 static int emulate_cp15(struct kvm_vcpu *vcpu,
-   const struct coproc_params *params)
+   struct coproc_params *params)
 {
size_t num;
const struct coproc_reg *table, *r;
diff --git a/arch/arm/kvm/coproc.h b/arch/arm/kvm/coproc.h
index eef1759..bbeff2a 100644
--- a/arch/arm/kvm/coproc.h
+++ b/arch/arm/kvm/coproc.h
@@ -41,7 +41,7 @@ struct coproc_reg {
 
/* Trapped access from guest, if non-NULL. */
bool (*access)(struct kvm_vcpu *,
-  const struct coproc_params *,
+  struct coproc_params *,
   const struct coproc_reg *);
 
/* Initialization for vcpu. */
@@ -154,7 +154,7 @@ static inline int cmp_reg(const struct coproc_reg *i1,
 #define is32   .is_64bit = false
 
 bool access_vm_reg(struct kvm_vcpu *vcpu,
-  const struct coproc_params *p,
+  struct coproc_params *p,
   const struct coproc_reg *r);
 
 #endif /* __ARM_KVM_COPROC_LOCAL_H__ */
-- 
1.9.1

___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu

[PATCH v9 03/11] arm/arm64: vgic: Introduce find_reg_by_id()

2016-11-23 Thread vijay . kilari
From: Vijaya Kumar K 

In order to implement vGICv3 CPU interface access, we will need to perform
table lookup of system registers. We would need both index_to_params() and
find_reg() exported for that purpose, but instead we export a single
function which combines them both.

Signed-off-by: Pavel Fedin 
Signed-off-by: Vijaya Kumar K 
Reviewed-by: Andre Przywara 
Acked-by: Christoffer Dall 
---
 arch/arm64/kvm/sys_regs.c | 22 +++---
 arch/arm64/kvm/sys_regs.h |  4 
 2 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index f302fdb..1330d4c 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1789,6 +1789,17 @@ static bool index_to_params(u64 id, struct 
sys_reg_params *params)
}
 }
 
+const struct sys_reg_desc *find_reg_by_id(u64 id,
+ struct sys_reg_params *params,
+ const struct sys_reg_desc table[],
+ unsigned int num)
+{
+   if (!index_to_params(id, params))
+   return NULL;
+
+   return find_reg(params, table, num);
+}
+
 /* Decode an index value, and find the sys_reg_desc entry. */
 static const struct sys_reg_desc *index_to_sys_reg_desc(struct kvm_vcpu *vcpu,
u64 id)
@@ -1912,10 +1923,8 @@ static int get_invariant_sys_reg(u64 id, void __user 
*uaddr)
struct sys_reg_params params;
const struct sys_reg_desc *r;
 
-   if (!index_to_params(id, ))
-   return -ENOENT;
-
-   r = find_reg(, invariant_sys_regs, 
ARRAY_SIZE(invariant_sys_regs));
+   r = find_reg_by_id(id, , invariant_sys_regs,
+  ARRAY_SIZE(invariant_sys_regs));
if (!r)
return -ENOENT;
 
@@ -1929,9 +1938,8 @@ static int set_invariant_sys_reg(u64 id, void __user 
*uaddr)
int err;
u64 val = 0; /* Make sure high bits are 0 for 32-bit regs */
 
-   if (!index_to_params(id, ))
-   return -ENOENT;
-   r = find_reg(, invariant_sys_regs, 
ARRAY_SIZE(invariant_sys_regs));
+   r = find_reg_by_id(id, , invariant_sys_regs,
+  ARRAY_SIZE(invariant_sys_regs));
if (!r)
return -ENOENT;
 
diff --git a/arch/arm64/kvm/sys_regs.h b/arch/arm64/kvm/sys_regs.h
index dbbb01c..9c6ffd0 100644
--- a/arch/arm64/kvm/sys_regs.h
+++ b/arch/arm64/kvm/sys_regs.h
@@ -136,6 +136,10 @@ static inline int cmp_sys_reg(const struct sys_reg_desc 
*i1,
return i1->Op2 - i2->Op2;
 }
 
+const struct sys_reg_desc *find_reg_by_id(u64 id,
+ struct sys_reg_params *params,
+ const struct sys_reg_desc table[],
+ unsigned int num);
 
 #define Op0(_x).Op0 = _x
 #define Op1(_x).Op1 = _x
-- 
1.9.1

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


[PATCH v9 0/11] arm/arm64: vgic: Implement API for vGICv3 live migration

2016-11-23 Thread vijay . kilari
From: Vijaya Kumar K 

This patchset adds API for saving and restoring
of VGICv3 registers to support live migration with new vgic feature.
This API definition is as per version of VGICv3 specification
Documentation/virtual/kvm/devices/arm-vgic-v3.txt

The patch 3 & 4 are picked from the Pavel's previous implementation.
http://www.spinics.net/lists/kvm/msg122040.html

NOTE: Only compilation tested for AArch32. No hardware to test.

v8 => v9:
 - Rebased to kvmarm/next branch
 - Introduce support for save and restore of CPU interface
   registers for AArch32 mode (9,10 and 11 patches).
   Only compilation tested.
 - Fixed vmcr.ctlr format
 - Updated error code for invalid CPU REG value in Documentation
 - Updated commit messages and added comments required
 - Queued IRQ when irq_line is set.
 - Compatibility check on ICC_CTLR_EL1.SEIS and A3V

v7 => v8:
 - Rebased to 4.9-rc3
 - Fixed wrong parameter to VGIC_TO_MPIDR
v6 => v7:
 - Rename all patches heading from vgic-new to vgic
 - Moved caching of priority and ID bits from vgic global struct
   to vgic_cpu struct.

v5 => v6:
 - Collated all register definitions to single patch (4)
 - Introduce macro to convert userspace MPIDR format to MPIDR reg format
 - Check on ICC_CTLR_EL1.CBPR value is made while accessing ICC_BPR1_EL1
 - Cached ich_vtr_el2 and guests priority and ID bits
 - Check on number of priority and ID bits when ICC_CTRL_EL1 write is made
 - Check is made on SRE bit for ICC_SRE_EL1 write

v4 => v5:
 - ICC_CTLR_EL1 access is updated to reflect HW values
 - Updated ICC reg access mask and shift macros
 - Introduced patch 4 for VMCR changes
 - Other minor fixes.
v3 => v4:
 - Rebased to latest code base
 - Moved vgic_uaccess() from vgic-mmio-v2.c to vgic-mmio.c
 - Dropped macro REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED_UACCESS
 - Dropped LE conversion for userspace access
 - Introduced vgic_uaccess_write_pending() for ISPENDR write
 - Change macro KVM_DEV_ARM_VGIC_V3_CPUID_MASK to KVM_DEV_ARM_VGIC_V3_MIDR_MASK
 - Refactored some code as common code.
 - Changed handing of ICC_* registers
 - Allowed ICC_SRE_EL1 read by userspace
 - Fixed KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_* macros

v2 => v3:
 - Implemented separate API for ISPENDR and ICPENDR to
   read soft_pending instead of pending for level triggerred interrupts
 - Implemented ioctl KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO to access line level
 - Rebased on top of Christoffer's patch set
   http://www.spinics.net/lists/kvm/msg136840.html

 NOTE: GICD_STATUSR and GICR_STATUSR are implemented as RAZ/WI.

v1 => v2:
 - The init sequence change patch is no more required.
   Fixed in patch 2 by using static vgic_io_dev regions structure instead
   of using dynamic allocation pointer.
 - Updated commit message of patch 4.
 - Dropped usage of union to manage 32-bit and 64-bit access in patch 1.
   Used local variable for 32-bit access.
 - Updated macro __ARM64_SYS_REG and ARM64_SYS_REG in
   arch/arm64/include/uapi/asm/kvm.h as per qemu requirements.

Vijaya Kumar K (11):
  arm/arm64: vgic: Implement support for userspace access
  arm/arm64: vgic: Add distributor and redistributor access
  arm/arm64: vgic: Introduce find_reg_by_id()
  irqchip/gic-v3: Add missing system register definitions
  arm/arm64: vgic: Introduce VENG0 and VENG1 fields to vmcr struct
  arm/arm64: vgic: Implement VGICv3 CPU interface access
  arm/arm64: vgic: Implement KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO ioctl
  arm/arm64: Documentation: Update arm-vgic-v3.txt
  arm: coproc: Drop const from coproc reg access function
  arm: coproc: Introduce find_coproc_reg_by_id()
  arm: vgic: Save and restore GICv3 CPU interface regs for AArch32

 Documentation/virtual/kvm/devices/arm-vgic-v3.txt |   2 +-
 arch/arm/include/uapi/asm/kvm.h   |  13 ++
 arch/arm/kvm/Makefile |   2 +
 arch/arm/kvm/coproc.c |  42 ++--
 arch/arm/kvm/coproc.h |   8 +-
 arch/arm64/include/uapi/asm/kvm.h |  13 ++
 arch/arm64/kvm/Makefile   |   2 +
 arch/arm64/kvm/sys_regs.c |  22 +-
 arch/arm64/kvm/sys_regs.h |   4 +
 include/kvm/arm_vgic.h|   9 +
 include/linux/irqchip/arm-gic-v3.h|  45 +++-
 virt/kvm/arm/vgic/vgic-coproc-reg-v3.c| 155 +
 virt/kvm/arm/vgic/vgic-kvm-device.c   | 219 +-
 virt/kvm/arm/vgic/vgic-mmio-v2.c  |  57 +
 virt/kvm/arm/vgic/vgic-mmio-v3.c  | 203 +++--
 virt/kvm/arm/vgic/vgic-mmio.c | 154 -
 virt/kvm/arm/vgic/vgic-mmio.h |  28 +++
 virt/kvm/arm/vgic/vgic-sys-reg-common.c   | 258 ++
 virt/kvm/arm/vgic/vgic-sys-reg-v3.c   | 142 
 virt/kvm/arm/vgic/vgic-v3.c   |  30 ++-
 virt/kvm/arm/vgic/vgic.h  

Re: [kvm-unit-tests PATCH v6 11/11] arm/arm64: gic: don't just use zero

2016-11-23 Thread Andrew Jones
On Wed, Nov 23, 2016 at 12:28:34PM +0100, Auger Eric wrote:
> Hi,
> 
> On 14/11/2016 22:08, Andrew Jones wrote:
> > Allow user to select who sends ipis and with which irq,
> > rather than just always sending irq=0 from cpu0.
> From a user point of view is there a way to know the list of available
> tests and their arg?

Not at the moment. I could change the arg-less run and/or add
a '-h' though that would provide a usage. So far unit tests
have never had -h's, but it's not a bad idea.

> > 
> > Signed-off-by: Andrew Jones 
> > 
> > ---
> > v6:
> >  - make sender/irq names more future-proof [drew]
> >  - sanity check inputs [drew]
> >  - introduce check_sender/irq and bad_sender/irq to more
> >cleanly do checks [drew]
> >  - default sender and irq to 1, instead of still zero [drew]
> > v4: improve structure and make sure spurious checking is
> > done even when the sender isn't cpu0
> > v2: actually check that the irq received was the irq sent,
> > and (for gicv2) that the sender is the expected one.
> > ---
> >  arm/gic.c | 124 
> > +-
> >  1 file changed, 99 insertions(+), 25 deletions(-)
> > 
> > diff --git a/arm/gic.c b/arm/gic.c
> > index d954a3775c26..638b8b140c96 100644
> > --- a/arm/gic.c
> > +++ b/arm/gic.c
> > @@ -11,6 +11,7 @@
> >   * This work is licensed under the terms of the GNU LGPL, version 2.
> >   */
> >  #include 
> > +#include 
> >  #include 
> >  #include 
> >  #include 
> > @@ -28,6 +29,8 @@ struct gic {
> >  
> >  static struct gic *gic;
> >  static int acked[NR_CPUS], spurious[NR_CPUS];
> > +static int bad_sender[NR_CPUS], bad_irq[NR_CPUS];
> > +static int cmdl_sender = 1, cmdl_irq = 1;
> >  static cpumask_t ready;
> >  
> >  static void nr_cpu_check(int nr)
> > @@ -43,10 +46,23 @@ static void wait_on_ready(void)
> > cpu_relax();
> >  }
> >  
> > +static void stats_reset(void)
> > +{
> > +   int i;
> > +
> > +   for (i = 0; i < nr_cpus; ++i) {
> > +   acked[i] = 0;
> > +   bad_sender[i] = -1;
> > +   bad_irq[i] = -1;
> > +   }
> > +   smp_wmb();
> > +}
> > +
> >  static void check_acked(cpumask_t *mask)
> >  {
> > int missing = 0, extra = 0, unexpected = 0;
> > int nr_pass, cpu, i;
> > +   bool bad = false;
> >  
> > /* Wait up to 5s for all interrupts to be delivered */
> > for (i = 0; i < 50; ++i) {
> > @@ -56,9 +72,21 @@ static void check_acked(cpumask_t *mask)
> > smp_rmb();
> > nr_pass += cpumask_test_cpu(cpu, mask) ?
> > acked[cpu] == 1 : acked[cpu] == 0;
> > +
> > +   if (bad_sender[cpu] != -1) {
> > +   printf("cpu%d received IPI from wrong sender 
> > %d\n",
> > +   cpu, bad_sender[cpu]);
> > +   bad = true;
> > +   }
> > +
> > +   if (bad_irq[cpu] != -1) {
> > +   printf("cpu%d received wrong irq %d\n",
> > +   cpu, bad_irq[cpu]);
> > +   bad = true;
> > +   }
> > }
> > if (nr_pass == nr_cpus) {
> > -   report("Completed in %d ms", true, ++i * 100);
> > +   report("Completed in %d ms", !bad, ++i * 100);
> > return;
> > }
> > }
> > @@ -91,6 +119,22 @@ static void check_spurious(void)
> > }
> >  }
> >  
> > +static void check_ipi_sender(u32 irqstat)
> > +{
> > +   if (gic_version() == 2) {
> > +   int src = (irqstat >> 10) & 7;
> > +
> > +   if (src != cmdl_sender)
> > +   bad_sender[smp_processor_id()] = src;
> > +   }
> > +}
> > +
> > +static void check_irqnr(u32 irqnr)
> > +{
> > +   if (irqnr != (u32)cmdl_irq)
> > +   bad_irq[smp_processor_id()] = irqnr;
> > +}
> > +
> >  static void ipi_handler(struct pt_regs *regs __unused)
> >  {
> > u32 irqstat = gic_read_iar();
> > @@ -98,8 +142,10 @@ static void ipi_handler(struct pt_regs *regs __unused)
> >  
> > if (irqnr != GICC_INT_SPURIOUS) {
> > gic_write_eoir(irqstat);
> > -   smp_rmb(); /* pairs with wmb in ipi_test functions */
> > +   smp_rmb(); /* pairs with wmb in stats_reset */
> > ++acked[smp_processor_id()];
> > +   check_ipi_sender(irqstat);
> > +   check_irqnr(irqnr);
> > smp_wmb(); /* pairs with rmb in check_acked */
> > } else {
> > ++spurious[smp_processor_id()];
> > @@ -109,19 +155,19 @@ static void ipi_handler(struct pt_regs *regs __unused)
> >  
> >  static void gicv2_ipi_send_self(void)
> >  {
> > -   writel(2 << 24, gicv2_dist_base() + GICD_SGIR);
> > +   writel(2 << 24 | cmdl_irq, gicv2_dist_base() + GICD_SGIR);
> >  }
> >  
> > -static void gicv2_ipi_send_tlist(cpumask_t *mask, int irq __unused)
> > +static void gicv2_ipi_send_tlist(cpumask_t *mask, int 

Re: [kvm-unit-tests PATCH v6 11/11] arm/arm64: gic: don't just use zero

2016-11-23 Thread Auger Eric
Hi,

On 14/11/2016 22:08, Andrew Jones wrote:
> Allow user to select who sends ipis and with which irq,
> rather than just always sending irq=0 from cpu0.
>From a user point of view is there a way to know the list of available
tests and their arg?
> 
> Signed-off-by: Andrew Jones 
> 
> ---
> v6:
>  - make sender/irq names more future-proof [drew]
>  - sanity check inputs [drew]
>  - introduce check_sender/irq and bad_sender/irq to more
>cleanly do checks [drew]
>  - default sender and irq to 1, instead of still zero [drew]
> v4: improve structure and make sure spurious checking is
> done even when the sender isn't cpu0
> v2: actually check that the irq received was the irq sent,
> and (for gicv2) that the sender is the expected one.
> ---
>  arm/gic.c | 124 
> +-
>  1 file changed, 99 insertions(+), 25 deletions(-)
> 
> diff --git a/arm/gic.c b/arm/gic.c
> index d954a3775c26..638b8b140c96 100644
> --- a/arm/gic.c
> +++ b/arm/gic.c
> @@ -11,6 +11,7 @@
>   * This work is licensed under the terms of the GNU LGPL, version 2.
>   */
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -28,6 +29,8 @@ struct gic {
>  
>  static struct gic *gic;
>  static int acked[NR_CPUS], spurious[NR_CPUS];
> +static int bad_sender[NR_CPUS], bad_irq[NR_CPUS];
> +static int cmdl_sender = 1, cmdl_irq = 1;
>  static cpumask_t ready;
>  
>  static void nr_cpu_check(int nr)
> @@ -43,10 +46,23 @@ static void wait_on_ready(void)
>   cpu_relax();
>  }
>  
> +static void stats_reset(void)
> +{
> + int i;
> +
> + for (i = 0; i < nr_cpus; ++i) {
> + acked[i] = 0;
> + bad_sender[i] = -1;
> + bad_irq[i] = -1;
> + }
> + smp_wmb();
> +}
> +
>  static void check_acked(cpumask_t *mask)
>  {
>   int missing = 0, extra = 0, unexpected = 0;
>   int nr_pass, cpu, i;
> + bool bad = false;
>  
>   /* Wait up to 5s for all interrupts to be delivered */
>   for (i = 0; i < 50; ++i) {
> @@ -56,9 +72,21 @@ static void check_acked(cpumask_t *mask)
>   smp_rmb();
>   nr_pass += cpumask_test_cpu(cpu, mask) ?
>   acked[cpu] == 1 : acked[cpu] == 0;
> +
> + if (bad_sender[cpu] != -1) {
> + printf("cpu%d received IPI from wrong sender 
> %d\n",
> + cpu, bad_sender[cpu]);
> + bad = true;
> + }
> +
> + if (bad_irq[cpu] != -1) {
> + printf("cpu%d received wrong irq %d\n",
> + cpu, bad_irq[cpu]);
> + bad = true;
> + }
>   }
>   if (nr_pass == nr_cpus) {
> - report("Completed in %d ms", true, ++i * 100);
> + report("Completed in %d ms", !bad, ++i * 100);
>   return;
>   }
>   }
> @@ -91,6 +119,22 @@ static void check_spurious(void)
>   }
>  }
>  
> +static void check_ipi_sender(u32 irqstat)
> +{
> + if (gic_version() == 2) {
> + int src = (irqstat >> 10) & 7;
> +
> + if (src != cmdl_sender)
> + bad_sender[smp_processor_id()] = src;
> + }
> +}
> +
> +static void check_irqnr(u32 irqnr)
> +{
> + if (irqnr != (u32)cmdl_irq)
> + bad_irq[smp_processor_id()] = irqnr;
> +}
> +
>  static void ipi_handler(struct pt_regs *regs __unused)
>  {
>   u32 irqstat = gic_read_iar();
> @@ -98,8 +142,10 @@ static void ipi_handler(struct pt_regs *regs __unused)
>  
>   if (irqnr != GICC_INT_SPURIOUS) {
>   gic_write_eoir(irqstat);
> - smp_rmb(); /* pairs with wmb in ipi_test functions */
> + smp_rmb(); /* pairs with wmb in stats_reset */
>   ++acked[smp_processor_id()];
> + check_ipi_sender(irqstat);
> + check_irqnr(irqnr);
>   smp_wmb(); /* pairs with rmb in check_acked */
>   } else {
>   ++spurious[smp_processor_id()];
> @@ -109,19 +155,19 @@ static void ipi_handler(struct pt_regs *regs __unused)
>  
>  static void gicv2_ipi_send_self(void)
>  {
> - writel(2 << 24, gicv2_dist_base() + GICD_SGIR);
> + writel(2 << 24 | cmdl_irq, gicv2_dist_base() + GICD_SGIR);
>  }
>  
> -static void gicv2_ipi_send_tlist(cpumask_t *mask, int irq __unused)
> +static void gicv2_ipi_send_tlist(cpumask_t *mask, int irq)
>  {
>   u8 tlist = (u8)cpumask_bits(mask)[0];
>  
> - writel(tlist << 16, gicv2_dist_base() + GICD_SGIR);
> + writel(tlist << 16 | irq, gicv2_dist_base() + GICD_SGIR);
>  }
>  
>  static void gicv2_ipi_send_broadcast(void)
>  {
> - writel(1 << 24, gicv2_dist_base() + GICD_SGIR);
> + writel(1 << 24 | cmdl_irq, gicv2_dist_base() + GICD_SGIR);
>  }
>  
>  static void 

Re: [kvm-unit-tests PATCH v6 09/11] arm/arm64: add initial gicv3 support

2016-11-23 Thread Auger Eric
Hi Drew,

On 14/11/2016 22:08, Andrew Jones wrote:
> Reviewed-by: Alex Bennée 
> Signed-off-by: Andrew Jones 
> 
> ---
> v6:
>  - added comments [Alex]
>  - added stride parameter to gicv3_set_redist_base [Andre]
>  - redist-wait s/rwp/uwp/ and comment [Andre]
>  - removed unnecessary wait-for-rwps [Andre]
> v5: use modern register names [Andre]
> v4:
>  - only take defines from kernel we need now [Andre]
>  - simplify enable by not caring if we reinit the distributor [drew]
> v2:
>  - configure irqs as NS GRP1
> ---
>  lib/arm/asm/arch_gicv3.h   |  47 
>  lib/arm/asm/gic-v3.h   | 104 
> +
>  lib/arm/asm/gic.h  |   5 ++-
>  lib/arm/gic.c  |  64 
>  lib/arm64/asm/arch_gicv3.h |  44 +++
>  lib/arm64/asm/gic-v3.h |   1 +
>  lib/arm64/asm/sysreg.h |  44 +++
>  7 files changed, 308 insertions(+), 1 deletion(-)
>  create mode 100644 lib/arm/asm/arch_gicv3.h
>  create mode 100644 lib/arm/asm/gic-v3.h
>  create mode 100644 lib/arm64/asm/arch_gicv3.h
>  create mode 100644 lib/arm64/asm/gic-v3.h
>  create mode 100644 lib/arm64/asm/sysreg.h
> 
> diff --git a/lib/arm/asm/arch_gicv3.h b/lib/arm/asm/arch_gicv3.h
> new file mode 100644
> index ..276577452a14
> --- /dev/null
> +++ b/lib/arm/asm/arch_gicv3.h
> @@ -0,0 +1,47 @@
> +/*
> + * All ripped off from arch/arm/include/asm/arch_gicv3.h
> + *
> + * Copyright (C) 2016, Red Hat Inc, Andrew Jones 
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2.
> + */
> +#ifndef _ASMARM_ARCH_GICV3_H_
> +#define _ASMARM_ARCH_GICV3_H_
> +
> +#ifndef __ASSEMBLY__
> +#include 
> +#include 
> +#include 
> +
> +#define __stringify xstr
> +
> +#define __ACCESS_CP15(CRn, Op1, CRm, Op2)p15, Op1, %0, CRn, CRm, Op2
> +
> +#define ICC_PMR  __ACCESS_CP15(c4, 0, c6, 0)
> +#define ICC_IGRPEN1  __ACCESS_CP15(c12, 0, c12, 7)
> +
> +static inline void gicv3_write_pmr(u32 val)
> +{
> + asm volatile("mcr " __stringify(ICC_PMR) : : "r" (val));
> +}
> +
> +static inline void gicv3_write_grpen1(u32 val)
> +{
> + asm volatile("mcr " __stringify(ICC_IGRPEN1) : : "r" (val));
> + isb();
> +}
> +
> +/*
> + * We may access GICR_TYPER and GITS_TYPER by reading both the TYPER
> + * offset and the following offset (+ 4) and then combining them to
> + * form a 64-bit address.
> + */
> +static inline u64 gicv3_read_typer(const volatile void __iomem *addr)
> +{
> + u64 val = readl(addr);
> + val |= (u64)readl(addr + 4) << 32;
> + return val;
> +}
> +
> +#endif /* !__ASSEMBLY__ */
> +#endif /* _ASMARM_ARCH_GICV3_H_ */
> diff --git a/lib/arm/asm/gic-v3.h b/lib/arm/asm/gic-v3.h
> new file mode 100644
> index ..73ade4681d21
> --- /dev/null
> +++ b/lib/arm/asm/gic-v3.h
> @@ -0,0 +1,104 @@
> +/*
> + * All GIC* defines are lifted from include/linux/irqchip/arm-gic-v3.h
> + *
> + * Copyright (C) 2016, Red Hat Inc, Andrew Jones 
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2.
> + */
> +#ifndef _ASMARM_GIC_V3_H_
> +#define _ASMARM_GIC_V3_H_
> +
> +#ifndef _ASMARM_GIC_H_
> +#error Do not directly include . Include 
> +#endif
> +
> +/*
> + * Distributor registers
> + *
> + * We expect to be run in Non-secure mode, thus we define the
> + * group1 enable bits with respect to that view.
> + */
> +#define GICD_CTLR_RWP(1U << 31)
> +#define GICD_CTLR_ARE_NS (1U << 4)
> +#define GICD_CTLR_ENABLE_G1A (1U << 1)
> +#define GICD_CTLR_ENABLE_G1  (1U << 0)
> +
> +/* Re-Distributor registers, offsets from RD_base */
> +#define GICR_TYPER   0x0008
> +
> +#define GICR_TYPER_LAST  (1U << 4)
> +
> +/* Re-Distributor registers, offsets from SGI_base */
> +#define GICR_IGROUPR0GICD_IGROUPR
> +#define GICR_ISENABLER0  GICD_ISENABLER
> +#define GICR_IPRIORITYR0 GICD_IPRIORITYR
> +
> +#include 
> +
> +#ifndef __ASSEMBLY__
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +struct gicv3_data {
> + void *dist_base;
> + void *redist_base[NR_CPUS];
> + unsigned int irq_nr;
> +};
> +extern struct gicv3_data gicv3_data;
> +
> +#define gicv3_dist_base()(gicv3_data.dist_base)
> +#define gicv3_redist_base()  
> (gicv3_data.redist_base[smp_processor_id()])
> +#define gicv3_sgi_base() 
> (gicv3_data.redist_base[smp_processor_id()] + SZ_64K)
> +
> +extern int gicv3_init(void);
> +extern void gicv3_enable_defaults(void);
> +extern void gicv3_set_redist_base(size_t stride);
> +
> +static inline void gicv3_do_wait_for_rwp(void *base)
> +{
> + int count = 10; /* 1s */
> +
> + while (readl(base + GICD_CTLR) & GICD_CTLR_RWP) {
> + if (!--count) {
> +

Re: [kvm-unit-tests PATCH v6 08/11] libcflat: add IS_ALIGNED() macro, and page sizes

2016-11-23 Thread Auger Eric
Hi,
On 14/11/2016 22:08, Andrew Jones wrote:
> From: Peter Xu 
> 
> These macros will be useful to do page alignment checks.
> 
> Reviewed-by: Andre Przywara 
> Signed-off-by: Peter Xu 
> [drew: also added SZ_64K and changed to shifts]
> Signed-off-by: Andrew Jones 
> 
> ---
> v6: change to shifts [Alex]
> ---
>  lib/libcflat.h | 6 ++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/lib/libcflat.h b/lib/libcflat.h
> index 82005f5d014f..244e40a724be 100644
> --- a/lib/libcflat.h
> +++ b/lib/libcflat.h
> @@ -33,6 +33,12 @@
>  #define __ALIGN_MASK(x, mask)(((x) + (mask)) & ~(mask))
>  #define __ALIGN(x, a)__ALIGN_MASK(x, (typeof(x))(a) - 1)
>  #define ALIGN(x, a)  __ALIGN((x), (a))
> +#define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a) - 1)) == 0)
> +
> +#define SZ_4K(1 << 12)
> +#define SZ_64K   (1 << 16)
> +#define SZ_2M(1 << 21)
> +#define SZ_1G(1 << 30)
>  
>  typedef uint8_t  u8;
>  typedef int8_t   s8;
> 
Reviewed-by: Eric Auger 

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


Re: [kvm-unit-tests PATCH v6 06/11] arm/arm64: add initial gicv2 support

2016-11-23 Thread Auger Eric
Hi,

On 14/11/2016 22:08, Andrew Jones wrote:
> Add some gicv2 support. This just adds init and enable
> functions, allowing unit tests to start messing with it.
> 
> Reviewed-by: Andre Przywara 
> Signed-off-by: Andrew Jones 
> 
> ---
> v6: added comments (register offset headers) [Alex]
> v5: share/use only the modern register names [Andre]
> v4:
>  - only take defines from kernel we need now [Andre]
>  - moved defines to asm/gic.h so they'll be shared with v3 [drew]
>  - simplify enable by not caring if we reinit the distributor [drew]
>  - init all GICD_INT_DEF_PRI_X4 registers [Eric]
> ---
>  arm/Makefile.common|  1 +
>  lib/arm/asm/gic-v2.h   | 34 ++
>  lib/arm/asm/gic.h  | 39 ++
>  lib/arm/gic.c  | 76 
> ++
>  lib/arm64/asm/gic-v2.h |  1 +
>  lib/arm64/asm/gic.h|  1 +
>  6 files changed, 152 insertions(+)
>  create mode 100644 lib/arm/asm/gic-v2.h
>  create mode 100644 lib/arm/asm/gic.h
>  create mode 100644 lib/arm/gic.c
>  create mode 100644 lib/arm64/asm/gic-v2.h
>  create mode 100644 lib/arm64/asm/gic.h
> 
> diff --git a/arm/Makefile.common b/arm/Makefile.common
> index f37b5c2a3de4..6f56015c43c4 100644
> --- a/arm/Makefile.common
> +++ b/arm/Makefile.common
> @@ -46,6 +46,7 @@ cflatobjs += lib/arm/mmu.o
>  cflatobjs += lib/arm/bitops.o
>  cflatobjs += lib/arm/psci.o
>  cflatobjs += lib/arm/smp.o
> +cflatobjs += lib/arm/gic.o
>  
>  libeabi = lib/arm/libeabi.a
>  eabiobjs = lib/arm/eabi_compat.o
> diff --git a/lib/arm/asm/gic-v2.h b/lib/arm/asm/gic-v2.h
> new file mode 100644
> index ..c2d5fecd4886
> --- /dev/null
> +++ b/lib/arm/asm/gic-v2.h
> @@ -0,0 +1,34 @@
> +/*
> + * All GIC* defines are lifted from include/linux/irqchip/arm-gic.h
> + *
> + * Copyright (C) 2016, Red Hat Inc, Andrew Jones 
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2.
> + */
> +#ifndef _ASMARM_GIC_V2_H_
> +#define _ASMARM_GIC_V2_H_
> +
> +#ifndef _ASMARM_GIC_H_
> +#error Do not directly include . Include 
> +#endif
> +
> +#define GICD_ENABLE  0x1
> +#define GICC_ENABLE  0x1
> +
> +#ifndef __ASSEMBLY__
> +
> +struct gicv2_data {
> + void *dist_base;
> + void *cpu_base;
> + unsigned int irq_nr;
> +};
> +extern struct gicv2_data gicv2_data;
> +
> +#define gicv2_dist_base()(gicv2_data.dist_base)
> +#define gicv2_cpu_base() (gicv2_data.cpu_base)
> +
> +extern int gicv2_init(void);
> +extern void gicv2_enable_defaults(void);
> +
> +#endif /* !__ASSEMBLY__ */
> +#endif /* _ASMARM_GIC_V2_H_ */
> diff --git a/lib/arm/asm/gic.h b/lib/arm/asm/gic.h
> new file mode 100644
> index ..e3580bd1d42d
> --- /dev/null
> +++ b/lib/arm/asm/gic.h
> @@ -0,0 +1,39 @@
> +/*
> + * Copyright (C) 2016, Red Hat Inc, Andrew Jones 
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2.
> + */
> +#ifndef _ASMARM_GIC_H_
> +#define _ASMARM_GIC_H_
> +
> +#include 
> +
> +/* Distributor registers */
> +#define GICD_CTLR0x
> +#define GICD_TYPER   0x0004
> +#define GICD_ISENABLER   0x0100
> +#define GICD_IPRIORITYR  0x0400
> +
> +#define GICD_TYPER_IRQS(typer)   typer) & 0x1f) + 1) * 32)
> +#define GICD_INT_EN_SET_SGI  0x
> +#define GICD_INT_DEF_PRI_X4  0xa0a0a0a0
> +
> +/* CPU interface registers */
> +#define GICC_CTLR0x
> +#define GICC_PMR 0x0004
> +
> +#define GICC_INT_PRI_THRESHOLD   0xf0
> +
> +#ifndef __ASSEMBLY__
> +
> +/*
> + * gic_init will try to find all known gics, and then
> + * initialize the gic data for the one found.
> + * returns
> + *  0   : no gic was found
> + *  > 0 : the gic version of the gic found
> + */
> +extern int gic_init(void);
> +
> +#endif /* !__ASSEMBLY__ */
> +#endif /* _ASMARM_GIC_H_ */
> diff --git a/lib/arm/gic.c b/lib/arm/gic.c
> new file mode 100644
> index ..d655105e058b
> --- /dev/null
> +++ b/lib/arm/gic.c
> @@ -0,0 +1,76 @@
> +/*
> + * Copyright (C) 2016, Red Hat Inc, Andrew Jones 
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2.
> + */
> +#include 
> +#include 
> +#include 
> +
> +struct gicv2_data gicv2_data;
> +
> +/*
> + * Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt
> + */
> +static bool
> +gic_get_dt_bases(const char *compatible, void **base1, void **base2)
> +{
> + struct dt_pbus_reg reg;
> + struct dt_device gic;
> + struct dt_bus bus;
> + int node, ret;
> +
> + dt_bus_init_defaults();
> + dt_device_init(, , NULL);
> +
> + node = dt_device_find_compatible(, compatible);
> + assert(node >= 0 || node == -FDT_ERR_NOTFOUND);
> +
> + if (node == -FDT_ERR_NOTFOUND)
> + return 

Re: [Qemu-devel] [kvm-unit-tests PATCH v6 00/11] arm/arm64: add gic framework

2016-11-23 Thread Alex Bennée

Andrew Jones  writes:

> Andre, Alex, Eric, anybody,
>
> Any more comments on this? If not, I'll send a pull request
> to Radim and Paolo to finally get this merged.

Looks good to me. I successfully re-based my TCG tests on top and they
work fine ;-)

Tested-by: Alex Bennée 

>
> Thanks,
> drew
>
>
> On Mon, Nov 14, 2016 at 10:08:28PM +0100, Andrew Jones wrote:
>> v6:
>>  - rebased to latest master
>>  - several other changes thanks to Andre and Alex, changes in
>>individual patch change logs
>>  - some code cleanups
>>
>> v5:
>>  - fix arm32/gicv3 compile [drew]
>>  - use modern register names [Andre]
>>  - one Andre r-b
>>
>> v4:
>>  - Eric's r-b's
>>  - Andre's suggestion to only take defines we need
>>  - several other changes listed in individual patches
>>
>> v3:
>>  - Rebased on latest master
>>  - Added Alex's r-b's
>>
>> v2:
>>  Rebased on latest master + my "populate argv[0]" series (will
>>  send a REPOST for that shortly. Additionally a few patches got
>>  fixes/features;
>>  07/10 got same fix as kernel 7c9b973061 "irqchip/gic-v3: Configure
>>all interrupts as non-secure Group-1" in order to continue
>>working over TCG, as the gicv3 code for TCG removed a hack
>>it had there to make Linux happy.
>>  08/10 added more output for when things fail (if they fail)
>>  09/10 switched gicv3 broadcast implementation to using IRM. This
>>found a bug in a recent (but not tip) kernel, which I was
>>about to fix, but then I saw MarcZ beat me to it.
>>  10/10 actually check that the input irq is the received irq
>>
>>
>> Import defines, and steal enough helper functions, from Linux to
>> enable programming of the gic (v2 and v3). Then use the framework
>> to add an initial test (an ipi test; self, target-list, broadcast).
>>
>> It's my hope that this framework will be a suitable base on which
>> more tests may be easily added, particularly because we have
>> vgic-new and tcg gicv3 emulation getting close to merge. (v3 UPDATE:
>> vgic-new and tcg gicv3 are merged now)
>>
>> To run it, along with other tests, just do
>>
>>  ./configure [ --arch=[arm|arm64] --cross-prefix=$PREFIX ]
>>  make
>>  export QEMU=$PATH_TO_QEMU
>>  ./run_tests.sh
>>
>> To run it separately do, e.g.
>>
>> $QEMU -machine virt,accel=tcg -cpu cortex-a57 \
>>  -device virtio-serial-device \
>>  -device virtconsole,chardev=ctd -chardev testdev,id=ctd \
>>  -display none -serial stdio \
>>  -kernel arm/gic.flat \
>>  -smp 123 -machine gic-version=3 -append ipi
>>   ^^ note, we can go nuts with nr-cpus on TCG :-)
>>
>> Or, a KVM example using a different "sender" cpu and irq (other than zero)
>>
>> $QEMU -machine virt,accel=kvm -cpu host \
>>  -device virtio-serial-device \
>>  -device virtconsole,chardev=ctd -chardev testdev,id=ctd \
>>  -display none -serial stdio \
>>  -kernel arm/gic.flat \
>>  -smp 48 -machine gic-version=3 -append 'ipi sender=42 irq=1'
>>
>>
>> Patches:
>> 01-05: fixes and functionality needed by the later gic patches
>> 06-07: enable gicv2 and gicv2 IPI test
>> 08-10: enable gicv3 and gicv3 IPI test
>>11: extend the IPI tests to take variable sender and irq
>>
>> Available here: 
>> https://github.com/rhdrjones/kvm-unit-tests/commits/arm/gic-v6
>>
>>
>> Andrew Jones (10):
>>   lib: xstr: allow multiple args
>>   arm64: fix get_"sysreg32" and make MPIDR 64bit
>>   arm/arm64: smp: support more than 8 cpus
>>   arm/arm64: add some delay routines
>>   arm/arm64: irq enable/disable
>>   arm/arm64: add initial gicv2 support
>>   arm/arm64: gicv2: add an IPI test
>>   arm/arm64: add initial gicv3 support
>>   arm/arm64: gicv3: add an IPI test
>>   arm/arm64: gic: don't just use zero
>>
>> Peter Xu (1):
>>   libcflat: add IS_ALIGNED() macro, and page sizes
>>
>>  arm/Makefile.common|   9 +-
>>  arm/gic.c  | 340 
>> +
>>  arm/run|  19 ++-
>>  arm/selftest.c |   5 +-
>>  arm/unittests.cfg  |  14 ++
>>  lib/arm/asm/arch_gicv3.h   |  70 ++
>>  lib/arm/asm/gic-v2.h   |  36 +
>>  lib/arm/asm/gic-v3.h   | 112 +++
>>  lib/arm/asm/gic.h  | 106 ++
>>  lib/arm/asm/processor.h|  42 +-
>>  lib/arm/asm/setup.h|   4 +-
>>  lib/arm/gic.c  | 267 +++
>>  lib/arm/processor.c|  15 ++
>>  lib/arm/setup.c|  10 ++
>>  lib/arm64/asm/arch_gicv3.h |  66 +
>>  lib/arm64/asm/gic-v2.h |   1 +
>>  lib/arm64/asm/gic-v3.h |   1 +
>>  lib/arm64/asm/gic.h|   1 +
>>  lib/arm64/asm/processor.h  |  53 +--
>>  lib/arm64/asm/sysreg.h |  44 ++
>>  lib/arm64/processor.c  |  15 ++
>>  lib/libcflat.h |  10 +-
>>  22 files changed, 1212 insertions(+), 28 deletions(-)
>>  create mode 100644 arm/gic.c
>>  create mode 100644 lib/arm/asm/arch_gicv3.h
>>  create mode 100644 

Re: [Qemu-devel] [kvm-unit-tests PATCH v6 00/11] arm/arm64: add gic framework

2016-11-23 Thread Andre Przywara
Hi,

On 22/11/16 18:45, Andrew Jones wrote:
> 
> Andre, Alex, Eric, anybody,
> 
> Any more comments on this? If not, I'll send a pull request
> to Radim and Paolo to finally get this merged.

I didn't manage to look in detail at the IPI test, but I am OK with the
rest of the GIC framework.
So I'd say: go ahead.

Cheers,
Andre.

> On Mon, Nov 14, 2016 at 10:08:28PM +0100, Andrew Jones wrote:
>> v6:
>>  - rebased to latest master
>>  - several other changes thanks to Andre and Alex, changes in
>>individual patch change logs
>>  - some code cleanups
>>
>> v5:
>>  - fix arm32/gicv3 compile [drew]
>>  - use modern register names [Andre]
>>  - one Andre r-b
>>
>> v4:
>>  - Eric's r-b's
>>  - Andre's suggestion to only take defines we need
>>  - several other changes listed in individual patches
>>
>> v3:
>>  - Rebased on latest master
>>  - Added Alex's r-b's
>>
>> v2:
>>  Rebased on latest master + my "populate argv[0]" series (will
>>  send a REPOST for that shortly. Additionally a few patches got
>>  fixes/features;
>>  07/10 got same fix as kernel 7c9b973061 "irqchip/gic-v3: Configure
>>all interrupts as non-secure Group-1" in order to continue
>>working over TCG, as the gicv3 code for TCG removed a hack
>>it had there to make Linux happy.
>>  08/10 added more output for when things fail (if they fail)
>>  09/10 switched gicv3 broadcast implementation to using IRM. This
>>found a bug in a recent (but not tip) kernel, which I was
>>about to fix, but then I saw MarcZ beat me to it.
>>  10/10 actually check that the input irq is the received irq
>>
>>
>> Import defines, and steal enough helper functions, from Linux to
>> enable programming of the gic (v2 and v3). Then use the framework
>> to add an initial test (an ipi test; self, target-list, broadcast).
>>
>> It's my hope that this framework will be a suitable base on which
>> more tests may be easily added, particularly because we have
>> vgic-new and tcg gicv3 emulation getting close to merge. (v3 UPDATE:
>> vgic-new and tcg gicv3 are merged now)
>>
>> To run it, along with other tests, just do
>>
>>  ./configure [ --arch=[arm|arm64] --cross-prefix=$PREFIX ]
>>  make
>>  export QEMU=$PATH_TO_QEMU
>>  ./run_tests.sh
>>
>> To run it separately do, e.g.
>>
>> $QEMU -machine virt,accel=tcg -cpu cortex-a57 \
>>  -device virtio-serial-device \
>>  -device virtconsole,chardev=ctd -chardev testdev,id=ctd \
>>  -display none -serial stdio \
>>  -kernel arm/gic.flat \
>>  -smp 123 -machine gic-version=3 -append ipi
>>   ^^ note, we can go nuts with nr-cpus on TCG :-)
>>
>> Or, a KVM example using a different "sender" cpu and irq (other than zero)
>>
>> $QEMU -machine virt,accel=kvm -cpu host \
>>  -device virtio-serial-device \
>>  -device virtconsole,chardev=ctd -chardev testdev,id=ctd \
>>  -display none -serial stdio \
>>  -kernel arm/gic.flat \
>>  -smp 48 -machine gic-version=3 -append 'ipi sender=42 irq=1'
>>
>>
>> Patches:
>> 01-05: fixes and functionality needed by the later gic patches
>> 06-07: enable gicv2 and gicv2 IPI test
>> 08-10: enable gicv3 and gicv3 IPI test
>>11: extend the IPI tests to take variable sender and irq
>>
>> Available here: 
>> https://github.com/rhdrjones/kvm-unit-tests/commits/arm/gic-v6
>>
>>
>> Andrew Jones (10):
>>   lib: xstr: allow multiple args
>>   arm64: fix get_"sysreg32" and make MPIDR 64bit
>>   arm/arm64: smp: support more than 8 cpus
>>   arm/arm64: add some delay routines
>>   arm/arm64: irq enable/disable
>>   arm/arm64: add initial gicv2 support
>>   arm/arm64: gicv2: add an IPI test
>>   arm/arm64: add initial gicv3 support
>>   arm/arm64: gicv3: add an IPI test
>>   arm/arm64: gic: don't just use zero
>>
>> Peter Xu (1):
>>   libcflat: add IS_ALIGNED() macro, and page sizes
>>
>>  arm/Makefile.common|   9 +-
>>  arm/gic.c  | 340 
>> +
>>  arm/run|  19 ++-
>>  arm/selftest.c |   5 +-
>>  arm/unittests.cfg  |  14 ++
>>  lib/arm/asm/arch_gicv3.h   |  70 ++
>>  lib/arm/asm/gic-v2.h   |  36 +
>>  lib/arm/asm/gic-v3.h   | 112 +++
>>  lib/arm/asm/gic.h  | 106 ++
>>  lib/arm/asm/processor.h|  42 +-
>>  lib/arm/asm/setup.h|   4 +-
>>  lib/arm/gic.c  | 267 +++
>>  lib/arm/processor.c|  15 ++
>>  lib/arm/setup.c|  10 ++
>>  lib/arm64/asm/arch_gicv3.h |  66 +
>>  lib/arm64/asm/gic-v2.h |   1 +
>>  lib/arm64/asm/gic-v3.h |   1 +
>>  lib/arm64/asm/gic.h|   1 +
>>  lib/arm64/asm/processor.h  |  53 +--
>>  lib/arm64/asm/sysreg.h |  44 ++
>>  lib/arm64/processor.c  |  15 ++
>>  lib/libcflat.h |  10 +-
>>  22 files changed, 1212 insertions(+), 28 deletions(-)
>>  create mode 100644 arm/gic.c
>>  create mode 100644 lib/arm/asm/arch_gicv3.h
>>  create mode 100644 lib/arm/asm/gic-v2.h
>>  create