History

Merge tag 'kvm-arm-for-3.13-1' of git://git.linaro.org/people/cdall/linux-kvm-arm into next

Updates for KVM/ARM including cpu=host and Cortex-A7 support

Gleb Natapov committed 13 years ago

Commit d5701422 parents f2e1066 a7265fb16 files · +270 −134Browse files

Unified · Split

16 files
  1. Documentation/virtual/kvm/api.txt +27 −4
  2. arch/arm/include/asm/kvm_arm.h +2 −2
  3. arch/arm/include/asm/kvm_asm.h +1 −1
  4. arch/arm/include/asm/kvm_host.h +1 −0
  5. arch/arm/include/uapi/asm/kvm.h +2 −1
  6. arch/arm/kvm/Makefile +1 −1
  7. arch/arm/kvm/arm.c +13 −0
  8. arch/arm/kvm/coproc.c +114 −0
  9. arch/arm/kvm/coproc_a15.c +1 −116
  10. arch/arm/kvm/coproc_a7.c +54 −0
  11. arch/arm/kvm/emulate.c +1 −1
  12. arch/arm/kvm/guest.c +23 −1
  13. arch/arm/kvm/reset.c +8 −7
  14. arch/arm64/include/asm/kvm_host.h +1 −0
  15. arch/arm64/kvm/guest.c +20 −0
  16. include/uapi/linux/kvm.h +1 −0
Documentation/virtual/kvm/api.txt+27−4
@@ -2304,7 +2304,31 @@ Possible features: · 2303 unmodified lines
23042304 Depends on KVM_CAP_ARM_EL1_32BIT (arm64 only).
23052305
23062306
2307−4.83 KVM_GET_REG_LIST
2307+4.83 KVM_ARM_PREFERRED_TARGET
2308+
2309+Capability: basic
2310+Architectures: arm, arm64
2311+Type: vm ioctl
2312+Parameters: struct struct kvm_vcpu_init (out)
2313+Returns: 0 on success; -1 on error
2314+Errors:
2315+ ENODEV: no preferred target available for the host
2316+
2317+This queries KVM for preferred CPU target type which can be emulated
2318+by KVM on underlying host.
2319+
2320+The ioctl returns struct kvm_vcpu_init instance containing information
2321+about preferred CPU target type and recommended features for it. The
2322+kvm_vcpu_init->features bitmap returned will have feature bits set if
2323+the preferred target recommends setting these features, but this is
2324+not mandatory.
2325+
2326+The information returned by this ioctl can be used to prepare an instance
2327+of struct kvm_vcpu_init for KVM_ARM_VCPU_INIT ioctl which will result in
2328+in VCPU matching underlying host.
2329+
2330+
2331+4.84 KVM_GET_REG_LIST
23082332
23092333 Capability: basic
23102334 Architectures: arm, arm64
@@ -2323,8 +2347,7 @@ struct kvm_reg_list { · 12 unmodified lines
23232347 This ioctl returns the guest registers that are supported for the
23242348 KVM_GET_ONE_REG/KVM_SET_ONE_REG calls.
23252349
2326−
2327−4.84 KVM_ARM_SET_DEVICE_ADDR
2350+4.85 KVM_ARM_SET_DEVICE_ADDR
23282351
23292352 Capability: KVM_CAP_ARM_SET_DEVICE_ADDR
23302353 Architectures: arm, arm64
@@ -2362,7 +2385,7 @@ must be called after calling KVM_CREATE_IRQCHIP, but before calling · 31 unmodified lines
23622385 KVM_RUN on any of the VCPUs. Calling this ioctl twice for any of the
23632386 base addresses will return -EEXIST.
23642387
2365−4.85 KVM_PPC_RTAS_DEFINE_TOKEN
2388+4.86 KVM_PPC_RTAS_DEFINE_TOKEN
23662389
23672390 Capability: KVM_CAP_PPC_RTAS
23682391 Architectures: ppc
arch/arm/include/asm/kvm_arm.h+2−2
@@ -95,12 +95,12 @@ · 94 unmodified lines
9595 #define TTBCR_IRGN1 (3 << 24)
9696 #define TTBCR_EPD1 (1 << 23)
9797 #define TTBCR_A1 (1 << 22)
98−#define TTBCR_T1SZ (3 << 16)
98+#define TTBCR_T1SZ (7 << 16)
9999 #define TTBCR_SH0 (3 << 12)
100100 #define TTBCR_ORGN0 (3 << 10)
101101 #define TTBCR_IRGN0 (3 << 8)
102102 #define TTBCR_EPD0 (1 << 7)
103−#define TTBCR_T0SZ 3
103+#define TTBCR_T0SZ (7 << 0)
104104 #define HTCR_MASK (TTBCR_T0SZ | TTBCR_IRGN0 | TTBCR_ORGN0 | TTBCR_SH0)
105105
106106 /* Hyp System Trap Register */
arch/arm/include/asm/kvm_asm.h+1−1
@@ -39,7 +39,7 @@ · 38 unmodified lines
3939 #define c6_IFAR 17 /* Instruction Fault Address Register */
4040 #define c7_PAR 18 /* Physical Address Register */
4141 #define c7_PAR_high 19 /* PAR top 32 bits */
42−#define c9_L2CTLR 20 /* Cortex A15 L2 Control Register */
42+#define c9_L2CTLR 20 /* Cortex A15/A7 L2 Control Register */
4343 #define c10_PRRR 21 /* Primary Region Remap Register */
4444 #define c10_NMRR 22 /* Normal Memory Remap Register */
4545 #define c12_VBAR 23 /* Vector Base Address Register */
arch/arm/include/asm/kvm_host.h+1−0
@@ -149,6 +149,7 @@ struct kvm_vcpu_stat { · 148 unmodified lines
149149 struct kvm_vcpu_init;
150150 int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
151151 const struct kvm_vcpu_init *init);
152+int kvm_vcpu_preferred_target(struct kvm_vcpu_init *init);
152153 unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu);
153154 int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices);
154155 struct kvm_one_reg;
arch/arm/include/uapi/asm/kvm.h+2−1
@@ -63,7 +63,8 @@ struct kvm_regs { · 62 unmodified lines
6363
6464 /* Supported Processor Types */
6565 #define KVM_ARM_TARGET_CORTEX_A15 0
66−#define KVM_ARM_NUM_TARGETS 1
66+#define KVM_ARM_TARGET_CORTEX_A7 1
67+#define KVM_ARM_NUM_TARGETS 2
6768
6869 /* KVM_ARM_SET_DEVICE_ADDR ioctl id encoding */
6970 #define KVM_ARM_DEVICE_TYPE_SHIFT 0
arch/arm/kvm/Makefile+1−1
@@ -19,6 +19,6 @@ kvm-arm-y = $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o · 18 unmodified lines
1919
2020 obj-y += kvm-arm.o init.o interrupts.o
2121 obj-y += arm.o handle_exit.o guest.o mmu.o emulate.o reset.o
22−obj-y += coproc.o coproc_a15.o mmio.o psci.o perf.o
22+obj-y += coproc.o coproc_a15.o coproc_a7.o mmio.o psci.o perf.o
2323 obj-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic.o
2424 obj-$(CONFIG_KVM_ARM_TIMER) += $(KVM)/arm/arch_timer.o
arch/arm/kvm/arm.c+13−0
@@ -797,6 +797,19 @@ long kvm_arch_vm_ioctl(struct file *filp, · 796 unmodified lines
797797 return -EFAULT;
798798 return kvm_vm_ioctl_set_device_addr(kvm, &dev_addr);
799799 }
800+ case KVM_ARM_PREFERRED_TARGET: {
801+ int err;
802+ struct kvm_vcpu_init init;
803+
804+ err = kvm_vcpu_preferred_target(&init);
805+ if (err)
806+ return err;
807+
808+ if (copy_to_user(argp, &init, sizeof(init)))
809+ return -EFAULT;
810+
811+ return 0;
812+ }
800813 default:
801814 return -EINVAL;
802815 }
arch/arm/kvm/coproc.c+114−0
@@ -71,6 +71,92 @@ int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run) · 70 unmodified lines
7171 return 1;
7272 }
7373
74+static void reset_mpidr(struct kvm_vcpu *vcpu, const struct coproc_reg *r)
75+{
76+ /*
77+ * Compute guest MPIDR. No need to mess around with different clusters
78+ * but we read the 'U' bit from the underlying hardware directly.
79+ */
80+ vcpu->arch.cp15[c0_MPIDR] = (read_cpuid_mpidr() & MPIDR_SMP_BITMASK)
81+ | vcpu->vcpu_id;
82+}
83+
84+/* TRM entries A7:4.3.31 A15:4.3.28 - RO WI */
85+static bool access_actlr(struct kvm_vcpu *vcpu,
86+ const struct coproc_params *p,
87+ const struct coproc_reg *r)
88+{
89+ if (p->is_write)
90+ return ignore_write(vcpu, p);
91+
92+ *vcpu_reg(vcpu, p->Rt1) = vcpu->arch.cp15[c1_ACTLR];
93+ return true;
94+}
95+
96+/* TRM entries A7:4.3.56, A15:4.3.60 - R/O. */
97+static bool access_cbar(struct kvm_vcpu *vcpu,
98+ const struct coproc_params *p,
99+ const struct coproc_reg *r)
100+{
101+ if (p->is_write)
102+ return write_to_read_only(vcpu, p);
103+ return read_zero(vcpu, p);
104+}
105+
106+/* TRM entries A7:4.3.49, A15:4.3.48 - R/O WI */
107+static bool access_l2ctlr(struct kvm_vcpu *vcpu,
108+ const struct coproc_params *p,
109+ const struct coproc_reg *r)
110+{
111+ if (p->is_write)
112+ return ignore_write(vcpu, p);
113+
114+ *vcpu_reg(vcpu, p->Rt1) = vcpu->arch.cp15[c9_L2CTLR];
115+ return true;
116+}
117+
118+static void reset_l2ctlr(struct kvm_vcpu *vcpu, const struct coproc_reg *r)
119+{
120+ u32 l2ctlr, ncores;
121+
122+ asm volatile("mrc p15, 1, %0, c9, c0, 2\n" : "=r" (l2ctlr));
123+ l2ctlr &= ~(3 << 24);
124+ ncores = atomic_read(&vcpu->kvm->online_vcpus) - 1;
125+ l2ctlr |= (ncores & 3) << 24;
126+
127+ vcpu->arch.cp15[c9_L2CTLR] = l2ctlr;
128+}
129+
130+static void reset_actlr(struct kvm_vcpu *vcpu, const struct coproc_reg *r)
131+{
132+ u32 actlr;
133+
134+ /* ACTLR contains SMP bit: make sure you create all cpus first! */
135+ asm volatile("mrc p15, 0, %0, c1, c0, 1\n" : "=r" (actlr));
136+ /* Make the SMP bit consistent with the guest configuration */
137+ if (atomic_read(&vcpu->kvm->online_vcpus) > 1)
138+ actlr |= 1U << 6;
139+ else
140+ actlr &= ~(1U << 6);
141+
142+ vcpu->arch.cp15[c1_ACTLR] = actlr;
143+}
144+
145+/*
146+ * TRM entries: A7:4.3.50, A15:4.3.49
147+ * R/O WI (even if NSACR.NS_L2ERR, a write of 1 is ignored).
148+ */
149+static bool access_l2ectlr(struct kvm_vcpu *vcpu,
150+ const struct coproc_params *p,
151+ const struct coproc_reg *r)
152+{
153+ if (p->is_write)
154+ return ignore_write(vcpu, p);
155+
156+ *vcpu_reg(vcpu, p->Rt1) = 0;
157+ return true;
158+}
159+
74160 /* See note at ARM ARM B1.14.4 */
75161 static bool access_dcsw(struct kvm_vcpu *vcpu,
76162 const struct coproc_params *p,
@@ -153,10 +239,22 @@ static bool pm_fake(struct kvm_vcpu *vcpu, · 76 unmodified lines
153239 * registers preceding 32-bit ones.
154240 */
155241 static const struct coproc_reg cp15_regs[] = {
242+ /* MPIDR: we use VMPIDR for guest access. */
243+ { CRn( 0), CRm( 0), Op1( 0), Op2( 5), is32,
244+ NULL, reset_mpidr, c0_MPIDR },
245+
156246 /* CSSELR: swapped by interrupt.S. */
157247 { CRn( 0), CRm( 0), Op1( 2), Op2( 0), is32,
158248 NULL, reset_unknown, c0_CSSELR },
159249
250+ /* ACTLR: trapped by HCR.TAC bit. */
251+ { CRn( 1), CRm( 0), Op1( 0), Op2( 1), is32,
252+ access_actlr, reset_actlr, c1_ACTLR },
253+
254+ /* CPACR: swapped by interrupt.S. */
255+ { CRn( 1), CRm( 0), Op1( 0), Op2( 2), is32,
256+ NULL, reset_val, c1_CPACR, 0x00000000 },
257+
160258 /* TTBR0/TTBR1: swapped by interrupt.S. */
161259 { CRm64( 2), Op1( 0), is64, NULL, reset_unknown64, c2_TTBR0 },
162260 { CRm64( 2), Op1( 1), is64, NULL, reset_unknown64, c2_TTBR1 },
@@ -194,6 +292,13 @@ static const struct coproc_reg cp15_regs[] = { · 31 unmodified lines
194292 { CRn( 7), CRm( 6), Op1( 0), Op2( 2), is32, access_dcsw},
195293 { CRn( 7), CRm(10), Op1( 0), Op2( 2), is32, access_dcsw},
196294 { CRn( 7), CRm(14), Op1( 0), Op2( 2), is32, access_dcsw},
295+ /*
296+ * L2CTLR access (guest wants to know #CPUs).
297+ */
298+ { CRn( 9), CRm( 0), Op1( 1), Op2( 2), is32,
299+ access_l2ctlr, reset_l2ctlr, c9_L2CTLR },
300+ { CRn( 9), CRm( 0), Op1( 1), Op2( 3), is32, access_l2ectlr},
301+
197302 /*
198303 * Dummy performance monitor implementation.
199304 */
@@ -234,6 +339,9 @@ static const struct coproc_reg cp15_regs[] = { · 34 unmodified lines
234339 /* CNTKCTL: swapped by interrupt.S. */
235340 { CRn(14), CRm( 1), Op1( 0), Op2( 0), is32,
236341 NULL, reset_val, c14_CNTKCTL, 0x00000000 },
342+
343+ /* The Configuration Base Address Register. */
344+ { CRn(15), CRm( 0), Op1( 4), Op2( 0), is32, access_cbar},
237345 };
238346
239347 /* Target specific emulation tables */
@@ -241,6 +349,12 @@ static struct kvm_coproc_target_table *target_tables[KVM_ARM_NUM_TARGETS]; · 1 unmodified line
241349
242350 void kvm_register_target_coproc_table(struct kvm_coproc_target_table *table)
243351 {
352+ unsigned int i;
353+
354+ for (i = 1; i < table->num; i++)
355+ BUG_ON(cmp_reg(&table->table[i-1],
356+ &table->table[i]) >= 0);
357+
244358 target_tables[table->target] = table;
245359 }
246360
arch/arm/kvm/coproc_a15.c+1−116
@@ -17,101 +17,12 @@ · 16 unmodified lines
1717 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1818 */
1919 #include <linux/kvm_host.h>
20−#include <asm/cputype.h>
21−#include <asm/kvm_arm.h>
22−#include <asm/kvm_host.h>
23−#include <asm/kvm_emulate.h>
2420 #include <asm/kvm_coproc.h>
21+#include <asm/kvm_emulate.h>
2522 #include <linux/init.h>
2623
27−static void reset_mpidr(struct kvm_vcpu *vcpu, const struct coproc_reg *r)
28−{
29− /*
30− * Compute guest MPIDR:
31− * (Even if we present only one VCPU to the guest on an SMP
32− * host we don't set the U bit in the MPIDR, or vice versa, as
33− * revealing the underlying hardware properties is likely to
34− * be the best choice).
35− */
36− vcpu->arch.cp15[c0_MPIDR] = (read_cpuid_mpidr() & ~MPIDR_LEVEL_MASK)
37− | (vcpu->vcpu_id & MPIDR_LEVEL_MASK);
38−}
39−
4024 #include "coproc.h"
4125
42−/* A15 TRM 4.3.28: RO WI */
43−static bool access_actlr(struct kvm_vcpu *vcpu,
44− const struct coproc_params *p,
45− const struct coproc_reg *r)
46−{
47− if (p->is_write)
48− return ignore_write(vcpu, p);
49−
50− *vcpu_reg(vcpu, p->Rt1) = vcpu->arch.cp15[c1_ACTLR];
51− return true;
52−}
53−
54−/* A15 TRM 4.3.60: R/O. */
55−static bool access_cbar(struct kvm_vcpu *vcpu,
56− const struct coproc_params *p,
57− const struct coproc_reg *r)
58−{
59− if (p->is_write)
60− return write_to_read_only(vcpu, p);
61− return read_zero(vcpu, p);
62−}
63−
64−/* A15 TRM 4.3.48: R/O WI. */
65−static bool access_l2ctlr(struct kvm_vcpu *vcpu,
66− const struct coproc_params *p,
67− const struct coproc_reg *r)
68−{
69− if (p->is_write)
70− return ignore_write(vcpu, p);
71−
72− *vcpu_reg(vcpu, p->Rt1) = vcpu->arch.cp15[c9_L2CTLR];
73− return true;
74−}
75−
76−static void reset_l2ctlr(struct kvm_vcpu *vcpu, const struct coproc_reg *r)
77−{
78− u32 l2ctlr, ncores;
79−
80− asm volatile("mrc p15, 1, %0, c9, c0, 2\n" : "=r" (l2ctlr));
81− l2ctlr &= ~(3 << 24);
82− ncores = atomic_read(&vcpu->kvm->online_vcpus) - 1;
83− l2ctlr |= (ncores & 3) << 24;
84−
85− vcpu->arch.cp15[c9_L2CTLR] = l2ctlr;
86−}
87−
88−static void reset_actlr(struct kvm_vcpu *vcpu, const struct coproc_reg *r)
89−{
90− u32 actlr;
91−
92− /* ACTLR contains SMP bit: make sure you create all cpus first! */
93− asm volatile("mrc p15, 0, %0, c1, c0, 1\n" : "=r" (actlr));
94− /* Make the SMP bit consistent with the guest configuration */
95− if (atomic_read(&vcpu->kvm->online_vcpus) > 1)
96− actlr |= 1U << 6;
97− else
98− actlr &= ~(1U << 6);
99−
100− vcpu->arch.cp15[c1_ACTLR] = actlr;
101−}
102−
103−/* A15 TRM 4.3.49: R/O WI (even if NSACR.NS_L2ERR, a write of 1 is ignored). */
104−static bool access_l2ectlr(struct kvm_vcpu *vcpu,
105− const struct coproc_params *p,
106− const struct coproc_reg *r)
107−{
108− if (p->is_write)
109− return ignore_write(vcpu, p);
110−
111− *vcpu_reg(vcpu, p->Rt1) = 0;
112− return true;
113−}
114−
11526 /*
11627 * A15-specific CP15 registers.
11728 * CRn denotes the primary register number, but is copied to the CRm in the
@@ -121,29 +32,9 @@ static bool access_l2ectlr(struct kvm_vcpu *vcpu, · 3 unmodified lines
12132 * registers preceding 32-bit ones.
12233 */
12334 static const struct coproc_reg a15_regs[] = {
124− /* MPIDR: we use VMPIDR for guest access. */
125− { CRn( 0), CRm( 0), Op1( 0), Op2( 5), is32,
126− NULL, reset_mpidr, c0_MPIDR },
127−
12835 /* SCTLR: swapped by interrupt.S. */
12936 { CRn( 1), CRm( 0), Op1( 0), Op2( 0), is32,
13037 NULL, reset_val, c1_SCTLR, 0x00C50078 },
131− /* ACTLR: trapped by HCR.TAC bit. */
132− { CRn( 1), CRm( 0), Op1( 0), Op2( 1), is32,
133− access_actlr, reset_actlr, c1_ACTLR },
134− /* CPACR: swapped by interrupt.S. */
135− { CRn( 1), CRm( 0), Op1( 0), Op2( 2), is32,
136− NULL, reset_val, c1_CPACR, 0x00000000 },
137−
138− /*
139− * L2CTLR access (guest wants to know #CPUs).
140− */
141− { CRn( 9), CRm( 0), Op1( 1), Op2( 2), is32,
142− access_l2ctlr, reset_l2ctlr, c9_L2CTLR },
143− { CRn( 9), CRm( 0), Op1( 1), Op2( 3), is32, access_l2ectlr},
144−
145− /* The Configuration Base Address Register. */
146− { CRn(15), CRm( 0), Op1( 4), Op2( 0), is32, access_cbar},
14738 };
14839
14940 static struct kvm_coproc_target_table a15_target_table = {
@@ -154,12 +45,6 @@ static struct kvm_coproc_target_table a15_target_table = { · 4 unmodified lines
15445
15546 static int __init coproc_a15_init(void)
15647 {
157− unsigned int i;
158−
159− for (i = 1; i < ARRAY_SIZE(a15_regs); i++)
160− BUG_ON(cmp_reg(&a15_regs[i-1],
161− &a15_regs[i]) >= 0);
162−
16348 kvm_register_target_coproc_table(&a15_target_table);
16449 return 0;
16550 }
arch/arm/kvm/coproc_a7.c+54−0
@@ -0,0 +1,54 @@
1+/*
2+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
3+ * Copyright (C) 2013 - ARM Ltd
4+ *
5+ * Authors: Rusty Russell <rusty@rustcorp.au>
6+ * Christoffer Dall <c.dall@virtualopensystems.com>
7+ * Jonathan Austin <jonathan.austin@arm.com>
8+ *
9+ * This program is free software; you can redistribute it and/or modify
10+ * it under the terms of the GNU General Public License, version 2, as
11+ * published by the Free Software Foundation.
12+ *
13+ * This program is distributed in the hope that it will be useful,
14+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+ * GNU General Public License for more details.
17+ *
18+ * You should have received a copy of the GNU General Public License
19+ * along with this program; if not, write to the Free Software
20+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21+ */
22+#include <linux/kvm_host.h>
23+#include <asm/kvm_coproc.h>
24+#include <asm/kvm_emulate.h>
25+#include <linux/init.h>
26+
27+#include "coproc.h"
28+
29+/*
30+ * Cortex-A7 specific CP15 registers.
31+ * CRn denotes the primary register number, but is copied to the CRm in the
32+ * user space API for 64-bit register access in line with the terminology used
33+ * in the ARM ARM.
34+ * Important: Must be sorted ascending by CRn, CRM, Op1, Op2 and with 64-bit
35+ * registers preceding 32-bit ones.
36+ */
37+static const struct coproc_reg a7_regs[] = {
38+ /* SCTLR: swapped by interrupt.S. */
39+ { CRn( 1), CRm( 0), Op1( 0), Op2( 0), is32,
40+ NULL, reset_val, c1_SCTLR, 0x00C50878 },
41+};
42+
43+static struct kvm_coproc_target_table a7_target_table = {
44+ .target = KVM_ARM_TARGET_CORTEX_A7,
45+ .table = a7_regs,
46+ .num = ARRAY_SIZE(a7_regs),
47+};
48+
49+static int __init coproc_a7_init(void)
50+{
51+ kvm_register_target_coproc_table(&a7_target_table);
52+ return 0;
53+}
54+late_initcall(coproc_a7_init);
arch/arm/kvm/emulate.c+1−1
@@ -354,7 +354,7 @@ static void inject_abt(struct kvm_vcpu *vcpu, bool is_pabt, unsigned long addr) · 353 unmodified lines
354354 *vcpu_pc(vcpu) = exc_vector_base(vcpu) + vect_offset;
355355
356356 if (is_pabt) {
357− /* Set DFAR and DFSR */
357+ /* Set IFAR and IFSR */
358358 vcpu->arch.cp15[c6_IFAR] = addr;
359359 is_lpae = (vcpu->arch.cp15[c2_TTBCR] >> 31);
360360 /* Always give debug fault for now - should give guest a clue */
arch/arm/kvm/guest.c+23−1
@@ -190,6 +190,8 @@ int __attribute_const__ kvm_target_cpu(void) · 189 unmodified lines
190190 return -EINVAL;
191191
192192 switch (part_number) {
193+ case ARM_CPU_PART_CORTEX_A7:
194+ return KVM_ARM_TARGET_CORTEX_A7;
193195 case ARM_CPU_PART_CORTEX_A15:
194196 return KVM_ARM_TARGET_CORTEX_A15;
195197 default:
@@ -202,7 +204,7 @@ int kvm_vcpu_set_target(struct kvm_vcpu *vcpu, · 6 unmodified lines
202204 {
203205 unsigned int i;
204206
205− /* We can only do a cortex A15 for now. */
207+ /* We can only cope with guest==host and only on A15/A7 (for now). */
206208 if (init->target != kvm_target_cpu())
207209 return -EINVAL;
208210
@@ -222,6 +224,26 @@ int kvm_vcpu_set_target(struct kvm_vcpu *vcpu, · 13 unmodified lines
222224 return kvm_reset_vcpu(vcpu);
223225 }
224226
227+int kvm_vcpu_preferred_target(struct kvm_vcpu_init *init)
228+{
229+ int target = kvm_target_cpu();
230+
231+ if (target < 0)
232+ return -ENODEV;
233+
234+ memset(init, 0, sizeof(*init));
235+
236+ /*
237+ * For now, we don't return any features.
238+ * In future, we might use features to return target
239+ * specific features available for the preferred
240+ * target type.
241+ */
242+ init->target = (__u32)target;
243+
244+ return 0;
245+}
246+
225247 int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
226248 {
227249 return -EINVAL;
arch/arm/kvm/reset.c+8−7
@@ -30,16 +30,16 @@ · 29 unmodified lines
3030 #include <kvm/arm_arch_timer.h>
3131
3232 /******************************************************************************
33− * Cortex-A15 Reset Values
33+ * Cortex-A15 and Cortex-A7 Reset Values
3434 */
3535
36−static const int a15_max_cpu_idx = 3;
36+static const int cortexa_max_cpu_idx = 3;
3737
38−static struct kvm_regs a15_regs_reset = {
38+static struct kvm_regs cortexa_regs_reset = {
3939 .usr_regs.ARM_cpsr = SVC_MODE | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT,
4040 };
4141
42−static const struct kvm_irq_level a15_vtimer_irq = {
42+static const struct kvm_irq_level cortexa_vtimer_irq = {
4343 { .irq = 27 },
4444 .level = 1,
4545 };
@@ -62,12 +62,13 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu) · 16 unmodified lines
6262 const struct kvm_irq_level *cpu_vtimer_irq;
6363
6464 switch (vcpu->arch.target) {
65+ case KVM_ARM_TARGET_CORTEX_A7:
6566 case KVM_ARM_TARGET_CORTEX_A15:
66− if (vcpu->vcpu_id > a15_max_cpu_idx)
67+ if (vcpu->vcpu_id > cortexa_max_cpu_idx)
6768 return -EINVAL;
68− cpu_reset = &a15_regs_reset;
69+ cpu_reset = &cortexa_regs_reset;
6970 vcpu->arch.midr = read_cpuid_id();
70− cpu_vtimer_irq = &a15_vtimer_irq;
71+ cpu_vtimer_irq = &cortexa_vtimer_irq;
7172 break;
7273 default:
7374 return -ENODEV;
arch/arm64/include/asm/kvm_host.h+1−0
@@ -146,6 +146,7 @@ struct kvm_vcpu_stat { · 145 unmodified lines
146146 struct kvm_vcpu_init;
147147 int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
148148 const struct kvm_vcpu_init *init);
149+int kvm_vcpu_preferred_target(struct kvm_vcpu_init *init);
149150 unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu);
150151 int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices);
151152 struct kvm_one_reg;
arch/arm64/kvm/guest.c+20−0
@@ -248,6 +248,26 @@ int kvm_vcpu_set_target(struct kvm_vcpu *vcpu, · 247 unmodified lines
248248 return kvm_reset_vcpu(vcpu);
249249 }
250250
251+int kvm_vcpu_preferred_target(struct kvm_vcpu_init *init)
252+{
253+ int target = kvm_target_cpu();
254+
255+ if (target < 0)
256+ return -ENODEV;
257+
258+ memset(init, 0, sizeof(*init));
259+
260+ /*
261+ * For now, we don't return any features.
262+ * In future, we might use features to return target
263+ * specific features available for the preferred
264+ * target type.
265+ */
266+ init->target = (__u32)target;
267+
268+ return 0;
269+}
270+
251271 int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
252272 {
253273 return -EINVAL;
include/uapi/linux/kvm.h+1−0
@@ -1012,6 +1012,7 @@ struct kvm_s390_ucas_mapping { · 1011 unmodified lines
10121012 /* VM is being stopped by host */
10131013 #define KVM_KVMCLOCK_CTRL _IO(KVMIO, 0xad)
10141014 #define KVM_ARM_VCPU_INIT _IOW(KVMIO, 0xae, struct kvm_vcpu_init)
1015+#define KVM_ARM_PREFERRED_TARGET _IOR(KVMIO, 0xaf, struct kvm_vcpu_init)
10151016 #define KVM_GET_REG_LIST _IOWR(KVMIO, 0xb0, struct kvm_reg_list)
10161017
10171018 #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0)