Skip to content

Commit 749cf76

Browse files
author
Christoffer Dall
committed
KVM: ARM: Initial skeleton to compile KVM support
Targets KVM support for Cortex A-15 processors. Contains all the framework components, make files, header files, some tracing functionality, and basic user space API. Only supported core is Cortex-A15 for now. Most functionality is in arch/arm/kvm/* or arch/arm/include/asm/kvm_*.h. Reviewed-by: Will Deacon <[email protected]> Reviewed-by: Marcelo Tosatti <[email protected]> Signed-off-by: Rusty Russell <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Signed-off-by: Christoffer Dall <[email protected]>
1 parent 9e9a367 commit 749cf76

File tree

21 files changed

+1445
-4
lines changed

21 files changed

+1445
-4
lines changed

Documentation/virtual/kvm/api.txt

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ kvm_run' (see below).
293293
4.11 KVM_GET_REGS
294294

295295
Capability: basic
296-
Architectures: all
296+
Architectures: all except ARM
297297
Type: vcpu ioctl
298298
Parameters: struct kvm_regs (out)
299299
Returns: 0 on success, -1 on error
@@ -314,7 +314,7 @@ struct kvm_regs {
314314
4.12 KVM_SET_REGS
315315

316316
Capability: basic
317-
Architectures: all
317+
Architectures: all except ARM
318318
Type: vcpu ioctl
319319
Parameters: struct kvm_regs (in)
320320
Returns: 0 on success, -1 on error
@@ -600,15 +600,16 @@ struct kvm_fpu {
600600
4.24 KVM_CREATE_IRQCHIP
601601

602602
Capability: KVM_CAP_IRQCHIP
603-
Architectures: x86, ia64
603+
Architectures: x86, ia64, ARM
604604
Type: vm ioctl
605605
Parameters: none
606606
Returns: 0 on success, -1 on error
607607

608608
Creates an interrupt controller model in the kernel. On x86, creates a virtual
609609
ioapic, a virtual PIC (two PICs, nested), and sets up future vcpus to have a
610610
local APIC. IRQ routing for GSIs 0-15 is set to both PIC and IOAPIC; GSI 16-23
611-
only go to the IOAPIC. On ia64, a IOSAPIC is created.
611+
only go to the IOAPIC. On ia64, a IOSAPIC is created. On ARM, a GIC is
612+
created.
612613

613614

614615
4.25 KVM_IRQ_LINE
@@ -1775,6 +1776,14 @@ registers, find a list below:
17751776
PPC | KVM_REG_PPC_VPA_DTL | 128
17761777
PPC | KVM_REG_PPC_EPCR | 32
17771778

1779+
ARM registers are mapped using the lower 32 bits. The upper 16 of that
1780+
is the register group type, or coprocessor number:
1781+
1782+
ARM core registers have the following id bit patterns:
1783+
0x4002 0000 0010 <index into the kvm_regs struct:16>
1784+
1785+
1786+
17781787
4.69 KVM_GET_ONE_REG
17791788

17801789
Capability: KVM_CAP_ONE_REG
@@ -2127,6 +2136,46 @@ written, then `n_invalid' invalid entries, invalidating any previously
21272136
valid entries found.
21282137

21292138

2139+
4.77 KVM_ARM_VCPU_INIT
2140+
2141+
Capability: basic
2142+
Architectures: arm
2143+
Type: vcpu ioctl
2144+
Parameters: struct struct kvm_vcpu_init (in)
2145+
Returns: 0 on success; -1 on error
2146+
Errors:
2147+
 EINVAL:    the target is unknown, or the combination of features is invalid.
2148+
 ENOENT:    a features bit specified is unknown.
2149+
2150+
This tells KVM what type of CPU to present to the guest, and what
2151+
optional features it should have.  This will cause a reset of the cpu
2152+
registers to their initial values.  If this is not called, KVM_RUN will
2153+
return ENOEXEC for that vcpu.
2154+
2155+
Note that because some registers reflect machine topology, all vcpus
2156+
should be created before this ioctl is invoked.
2157+
2158+
2159+
4.78 KVM_GET_REG_LIST
2160+
2161+
Capability: basic
2162+
Architectures: arm
2163+
Type: vcpu ioctl
2164+
Parameters: struct kvm_reg_list (in/out)
2165+
Returns: 0 on success; -1 on error
2166+
Errors:
2167+
 E2BIG:     the reg index list is too big to fit in the array specified by
2168+
            the user (the number required will be written into n).
2169+
2170+
struct kvm_reg_list {
2171+
__u64 n; /* number of registers in reg[] */
2172+
__u64 reg[0];
2173+
};
2174+
2175+
This ioctl returns the guest registers that are supported for the
2176+
KVM_GET_ONE_REG/KVM_SET_ONE_REG calls.
2177+
2178+
21302179
5. The kvm_run structure
21312180
------------------------
21322181

arch/arm/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2322,3 +2322,5 @@ source "security/Kconfig"
23222322
source "crypto/Kconfig"
23232323

23242324
source "lib/Kconfig"
2325+
2326+
source "arch/arm/kvm/Kconfig"

arch/arm/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/
252252
core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ)
253253
core-$(CONFIG_VFP) += arch/arm/vfp/
254254
core-$(CONFIG_XEN) += arch/arm/xen/
255+
core-$(CONFIG_KVM_ARM_HOST) += arch/arm/kvm/
255256

256257
# If we have a machine-specific directory, then include it in the build.
257258
core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/

arch/arm/include/asm/kvm_arm.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright (C) 2012 - Virtual Open Systems and Columbia University
3+
* Author: Christoffer Dall <[email protected]>
4+
*
5+
* This program is free software; you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License, version 2, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program; if not, write to the Free Software
16+
* Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17+
*/
18+
19+
#ifndef __ARM_KVM_ARM_H__
20+
#define __ARM_KVM_ARM_H__
21+
22+
#include <linux/types.h>
23+
24+
#endif /* __ARM_KVM_ARM_H__ */

arch/arm/include/asm/kvm_asm.h

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright (C) 2012 - Virtual Open Systems and Columbia University
3+
* Author: Christoffer Dall <[email protected]>
4+
*
5+
* This program is free software; you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License, version 2, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program; if not, write to the Free Software
16+
* Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17+
*/
18+
19+
#ifndef __ARM_KVM_ASM_H__
20+
#define __ARM_KVM_ASM_H__
21+
22+
/* 0 is reserved as an invalid value. */
23+
#define c0_MPIDR 1 /* MultiProcessor ID Register */
24+
#define c0_CSSELR 2 /* Cache Size Selection Register */
25+
#define c1_SCTLR 3 /* System Control Register */
26+
#define c1_ACTLR 4 /* Auxilliary Control Register */
27+
#define c1_CPACR 5 /* Coprocessor Access Control */
28+
#define c2_TTBR0 6 /* Translation Table Base Register 0 */
29+
#define c2_TTBR0_high 7 /* TTBR0 top 32 bits */
30+
#define c2_TTBR1 8 /* Translation Table Base Register 1 */
31+
#define c2_TTBR1_high 9 /* TTBR1 top 32 bits */
32+
#define c2_TTBCR 10 /* Translation Table Base Control R. */
33+
#define c3_DACR 11 /* Domain Access Control Register */
34+
#define c5_DFSR 12 /* Data Fault Status Register */
35+
#define c5_IFSR 13 /* Instruction Fault Status Register */
36+
#define c5_ADFSR 14 /* Auxilary Data Fault Status R */
37+
#define c5_AIFSR 15 /* Auxilary Instrunction Fault Status R */
38+
#define c6_DFAR 16 /* Data Fault Address Register */
39+
#define c6_IFAR 17 /* Instruction Fault Address Register */
40+
#define c9_L2CTLR 18 /* Cortex A15 L2 Control Register */
41+
#define c10_PRRR 19 /* Primary Region Remap Register */
42+
#define c10_NMRR 20 /* Normal Memory Remap Register */
43+
#define c12_VBAR 21 /* Vector Base Address Register */
44+
#define c13_CID 22 /* Context ID Register */
45+
#define c13_TID_URW 23 /* Thread ID, User R/W */
46+
#define c13_TID_URO 24 /* Thread ID, User R/O */
47+
#define c13_TID_PRIV 25 /* Thread ID, Privileged */
48+
#define NR_CP15_REGS 26 /* Number of regs (incl. invalid) */
49+
50+
#define ARM_EXCEPTION_RESET 0
51+
#define ARM_EXCEPTION_UNDEFINED 1
52+
#define ARM_EXCEPTION_SOFTWARE 2
53+
#define ARM_EXCEPTION_PREF_ABORT 3
54+
#define ARM_EXCEPTION_DATA_ABORT 4
55+
#define ARM_EXCEPTION_IRQ 5
56+
#define ARM_EXCEPTION_FIQ 6
57+
58+
#endif /* __ARM_KVM_ASM_H__ */

arch/arm/include/asm/kvm_coproc.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright (C) 2012 Rusty Russell IBM Corporation
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License, version 2, as
6+
* published by the Free Software Foundation.
7+
*
8+
* This program is distributed in the hope that it will be useful,
9+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
* GNU General Public License for more details.
12+
*
13+
* You should have received a copy of the GNU General Public License
14+
* along with this program; if not, write to the Free Software
15+
* Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16+
*/
17+
18+
#ifndef __ARM_KVM_COPROC_H__
19+
#define __ARM_KVM_COPROC_H__
20+
#include <linux/kvm_host.h>
21+
22+
void kvm_reset_coprocs(struct kvm_vcpu *vcpu);
23+
24+
#endif /* __ARM_KVM_COPROC_H__ */

arch/arm/include/asm/kvm_emulate.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright (C) 2012 - Virtual Open Systems and Columbia University
3+
* Author: Christoffer Dall <[email protected]>
4+
*
5+
* This program is free software; you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License, version 2, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program; if not, write to the Free Software
16+
* Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17+
*/
18+
19+
#ifndef __ARM_KVM_EMULATE_H__
20+
#define __ARM_KVM_EMULATE_H__
21+
22+
#include <linux/kvm_host.h>
23+
#include <asm/kvm_asm.h>
24+
25+
u32 *vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num);
26+
u32 *vcpu_spsr(struct kvm_vcpu *vcpu);
27+
28+
static inline u32 *vcpu_pc(struct kvm_vcpu *vcpu)
29+
{
30+
return (u32 *)&vcpu->arch.regs.usr_regs.ARM_pc;
31+
}
32+
33+
static inline u32 *vcpu_cpsr(struct kvm_vcpu *vcpu)
34+
{
35+
return (u32 *)&vcpu->arch.regs.usr_regs.ARM_cpsr;
36+
}
37+
38+
static inline bool mode_has_spsr(struct kvm_vcpu *vcpu)
39+
{
40+
unsigned long cpsr_mode = vcpu->arch.regs.usr_regs.ARM_cpsr & MODE_MASK;
41+
return (cpsr_mode > USR_MODE && cpsr_mode < SYSTEM_MODE);
42+
}
43+
44+
static inline bool vcpu_mode_priv(struct kvm_vcpu *vcpu)
45+
{
46+
unsigned long cpsr_mode = vcpu->arch.regs.usr_regs.ARM_cpsr & MODE_MASK;
47+
return cpsr_mode > USR_MODE;;
48+
}
49+
50+
#endif /* __ARM_KVM_EMULATE_H__ */

arch/arm/include/asm/kvm_host.h

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
* Copyright (C) 2012 - Virtual Open Systems and Columbia University
3+
* Author: Christoffer Dall <[email protected]>
4+
*
5+
* This program is free software; you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License, version 2, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program; if not, write to the Free Software
16+
* Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17+
*/
18+
19+
#ifndef __ARM_KVM_HOST_H__
20+
#define __ARM_KVM_HOST_H__
21+
22+
#include <asm/kvm.h>
23+
#include <asm/kvm_asm.h>
24+
25+
#define KVM_MAX_VCPUS CONFIG_KVM_ARM_MAX_VCPUS
26+
#define KVM_MEMORY_SLOTS 32
27+
#define KVM_PRIVATE_MEM_SLOTS 4
28+
#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
29+
30+
#define KVM_VCPU_MAX_FEATURES 0
31+
32+
/* We don't currently support large pages. */
33+
#define KVM_HPAGE_GFN_SHIFT(x) 0
34+
#define KVM_NR_PAGE_SIZES 1
35+
#define KVM_PAGES_PER_HPAGE(x) (1UL<<31)
36+
37+
struct kvm_vcpu;
38+
u32 *kvm_vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num, u32 mode);
39+
int kvm_target_cpu(void);
40+
int kvm_reset_vcpu(struct kvm_vcpu *vcpu);
41+
void kvm_reset_coprocs(struct kvm_vcpu *vcpu);
42+
43+
struct kvm_arch {
44+
/* VTTBR value associated with below pgd and vmid */
45+
u64 vttbr;
46+
47+
/*
48+
* Anything that is not used directly from assembly code goes
49+
* here.
50+
*/
51+
52+
/* The VMID generation used for the virt. memory system */
53+
u64 vmid_gen;
54+
u32 vmid;
55+
56+
/* Stage-2 page table */
57+
pgd_t *pgd;
58+
};
59+
60+
#define KVM_NR_MEM_OBJS 40
61+
62+
/*
63+
* We don't want allocation failures within the mmu code, so we preallocate
64+
* enough memory for a single page fault in a cache.
65+
*/
66+
struct kvm_mmu_memory_cache {
67+
int nobjs;
68+
void *objects[KVM_NR_MEM_OBJS];
69+
};
70+
71+
struct kvm_vcpu_arch {
72+
struct kvm_regs regs;
73+
74+
int target; /* Processor target */
75+
DECLARE_BITMAP(features, KVM_VCPU_MAX_FEATURES);
76+
77+
/* System control coprocessor (cp15) */
78+
u32 cp15[NR_CP15_REGS];
79+
80+
/* The CPU type we expose to the VM */
81+
u32 midr;
82+
83+
/* Exception Information */
84+
u32 hsr; /* Hyp Syndrome Register */
85+
u32 hxfar; /* Hyp Data/Inst Fault Address Register */
86+
u32 hpfar; /* Hyp IPA Fault Address Register */
87+
88+
/* Interrupt related fields */
89+
u32 irq_lines; /* IRQ and FIQ levels */
90+
91+
/* Hyp exception information */
92+
u32 hyp_pc; /* PC when exception was taken from Hyp mode */
93+
94+
/* Cache some mmu pages needed inside spinlock regions */
95+
struct kvm_mmu_memory_cache mmu_page_cache;
96+
};
97+
98+
struct kvm_vm_stat {
99+
u32 remote_tlb_flush;
100+
};
101+
102+
struct kvm_vcpu_stat {
103+
u32 halt_wakeup;
104+
};
105+
106+
struct kvm_vcpu_init;
107+
int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
108+
const struct kvm_vcpu_init *init);
109+
unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu);
110+
int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices);
111+
struct kvm_one_reg;
112+
int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
113+
int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
114+
#endif /* __ARM_KVM_HOST_H__ */

0 commit comments

Comments
 (0)