diff options
Diffstat (limited to 'arch/arm/include')
-rw-r--r-- | arch/arm/include/asm/arch_timer.h | 109 | ||||
-rw-r--r-- | arch/arm/include/asm/kvm_arch_timer.h | 85 | ||||
-rw-r--r-- | arch/arm/include/asm/kvm_asm.h | 3 | ||||
-rw-r--r-- | arch/arm/include/asm/kvm_host.h | 23 | ||||
-rw-r--r-- | arch/arm/include/asm/kvm_vgic.h | 221 | ||||
-rw-r--r-- | arch/arm/include/uapi/asm/kvm.h | 16 |
6 files changed, 450 insertions, 7 deletions
diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h index d40229d9a1c9..7ade91d8cc6f 100644 --- a/arch/arm/include/asm/arch_timer.h +++ b/arch/arm/include/asm/arch_timer.h | |||
@@ -1,13 +1,115 @@ | |||
1 | #ifndef __ASMARM_ARCH_TIMER_H | 1 | #ifndef __ASMARM_ARCH_TIMER_H |
2 | #define __ASMARM_ARCH_TIMER_H | 2 | #define __ASMARM_ARCH_TIMER_H |
3 | 3 | ||
4 | #include <asm/barrier.h> | ||
4 | #include <asm/errno.h> | 5 | #include <asm/errno.h> |
5 | #include <linux/clocksource.h> | 6 | #include <linux/clocksource.h> |
7 | #include <linux/init.h> | ||
8 | #include <linux/types.h> | ||
9 | |||
10 | #include <clocksource/arm_arch_timer.h> | ||
6 | 11 | ||
7 | #ifdef CONFIG_ARM_ARCH_TIMER | 12 | #ifdef CONFIG_ARM_ARCH_TIMER |
8 | int arch_timer_of_register(void); | 13 | int arch_timer_of_register(void); |
9 | int arch_timer_sched_clock_init(void); | 14 | int arch_timer_sched_clock_init(void); |
10 | struct timecounter *arch_timer_get_timecounter(void); | 15 | |
16 | /* | ||
17 | * These register accessors are marked inline so the compiler can | ||
18 | * nicely work out which register we want, and chuck away the rest of | ||
19 | * the code. At least it does so with a recent GCC (4.6.3). | ||
20 | */ | ||
21 | static inline void arch_timer_reg_write(const int access, const int reg, u32 val) | ||
22 | { | ||
23 | if (access == ARCH_TIMER_PHYS_ACCESS) { | ||
24 | switch (reg) { | ||
25 | case ARCH_TIMER_REG_CTRL: | ||
26 | asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" (val)); | ||
27 | break; | ||
28 | case ARCH_TIMER_REG_TVAL: | ||
29 | asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" (val)); | ||
30 | break; | ||
31 | } | ||
32 | } | ||
33 | |||
34 | if (access == ARCH_TIMER_VIRT_ACCESS) { | ||
35 | switch (reg) { | ||
36 | case ARCH_TIMER_REG_CTRL: | ||
37 | asm volatile("mcr p15, 0, %0, c14, c3, 1" : : "r" (val)); | ||
38 | break; | ||
39 | case ARCH_TIMER_REG_TVAL: | ||
40 | asm volatile("mcr p15, 0, %0, c14, c3, 0" : : "r" (val)); | ||
41 | break; | ||
42 | } | ||
43 | } | ||
44 | |||
45 | isb(); | ||
46 | } | ||
47 | |||
48 | static inline u32 arch_timer_reg_read(const int access, const int reg) | ||
49 | { | ||
50 | u32 val = 0; | ||
51 | |||
52 | if (access == ARCH_TIMER_PHYS_ACCESS) { | ||
53 | switch (reg) { | ||
54 | case ARCH_TIMER_REG_CTRL: | ||
55 | asm volatile("mrc p15, 0, %0, c14, c2, 1" : "=r" (val)); | ||
56 | break; | ||
57 | case ARCH_TIMER_REG_TVAL: | ||
58 | asm volatile("mrc p15, 0, %0, c14, c2, 0" : "=r" (val)); | ||
59 | break; | ||
60 | } | ||
61 | } | ||
62 | |||
63 | if (access == ARCH_TIMER_VIRT_ACCESS) { | ||
64 | switch (reg) { | ||
65 | case ARCH_TIMER_REG_CTRL: | ||
66 | asm volatile("mrc p15, 0, %0, c14, c3, 1" : "=r" (val)); | ||
67 | break; | ||
68 | case ARCH_TIMER_REG_TVAL: | ||
69 | asm volatile("mrc p15, 0, %0, c14, c3, 0" : "=r" (val)); | ||
70 | break; | ||
71 | } | ||
72 | } | ||
73 | |||
74 | return val; | ||
75 | } | ||
76 | |||
77 | static inline u32 arch_timer_get_cntfrq(void) | ||
78 | { | ||
79 | u32 val; | ||
80 | asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (val)); | ||
81 | return val; | ||
82 | } | ||
83 | |||
84 | static inline u64 arch_counter_get_cntpct(void) | ||
85 | { | ||
86 | u64 cval; | ||
87 | |||
88 | isb(); | ||
89 | asm volatile("mrrc p15, 0, %Q0, %R0, c14" : "=r" (cval)); | ||
90 | return cval; | ||
91 | } | ||
92 | |||
93 | static inline u64 arch_counter_get_cntvct(void) | ||
94 | { | ||
95 | u64 cval; | ||
96 | |||
97 | isb(); | ||
98 | asm volatile("mrrc p15, 1, %Q0, %R0, c14" : "=r" (cval)); | ||
99 | return cval; | ||
100 | } | ||
101 | |||
102 | static inline void __cpuinit arch_counter_set_user_access(void) | ||
103 | { | ||
104 | u32 cntkctl; | ||
105 | |||
106 | asm volatile("mrc p15, 0, %0, c14, c1, 0" : "=r" (cntkctl)); | ||
107 | |||
108 | /* disable user access to everything */ | ||
109 | cntkctl &= ~((3 << 8) | (7 << 0)); | ||
110 | |||
111 | asm volatile("mcr p15, 0, %0, c14, c1, 0" : : "r" (cntkctl)); | ||
112 | } | ||
11 | #else | 113 | #else |
12 | static inline int arch_timer_of_register(void) | 114 | static inline int arch_timer_of_register(void) |
13 | { | 115 | { |
@@ -18,11 +120,6 @@ static inline int arch_timer_sched_clock_init(void) | |||
18 | { | 120 | { |
19 | return -ENXIO; | 121 | return -ENXIO; |
20 | } | 122 | } |
21 | |||
22 | static inline struct timecounter *arch_timer_get_timecounter(void) | ||
23 | { | ||
24 | return NULL; | ||
25 | } | ||
26 | #endif | 123 | #endif |
27 | 124 | ||
28 | #endif | 125 | #endif |
diff --git a/arch/arm/include/asm/kvm_arch_timer.h b/arch/arm/include/asm/kvm_arch_timer.h new file mode 100644 index 000000000000..68cb9e1dfb81 --- /dev/null +++ b/arch/arm/include/asm/kvm_arch_timer.h | |||
@@ -0,0 +1,85 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012 ARM Ltd. | ||
3 | * Author: Marc Zyngier <marc.zyngier@arm.com> | ||
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, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
17 | */ | ||
18 | |||
19 | #ifndef __ASM_ARM_KVM_ARCH_TIMER_H | ||
20 | #define __ASM_ARM_KVM_ARCH_TIMER_H | ||
21 | |||
22 | #include <linux/clocksource.h> | ||
23 | #include <linux/hrtimer.h> | ||
24 | #include <linux/workqueue.h> | ||
25 | |||
26 | struct arch_timer_kvm { | ||
27 | #ifdef CONFIG_KVM_ARM_TIMER | ||
28 | /* Is the timer enabled */ | ||
29 | bool enabled; | ||
30 | |||
31 | /* Virtual offset */ | ||
32 | cycle_t cntvoff; | ||
33 | #endif | ||
34 | }; | ||
35 | |||
36 | struct arch_timer_cpu { | ||
37 | #ifdef CONFIG_KVM_ARM_TIMER | ||
38 | /* Registers: control register, timer value */ | ||
39 | u32 cntv_ctl; /* Saved/restored */ | ||
40 | cycle_t cntv_cval; /* Saved/restored */ | ||
41 | |||
42 | /* | ||
43 | * Anything that is not used directly from assembly code goes | ||
44 | * here. | ||
45 | */ | ||
46 | |||
47 | /* Background timer used when the guest is not running */ | ||
48 | struct hrtimer timer; | ||
49 | |||
50 | /* Work queued with the above timer expires */ | ||
51 | struct work_struct expired; | ||
52 | |||
53 | /* Background timer active */ | ||
54 | bool armed; | ||
55 | |||
56 | /* Timer IRQ */ | ||
57 | const struct kvm_irq_level *irq; | ||
58 | #endif | ||
59 | }; | ||
60 | |||
61 | #ifdef CONFIG_KVM_ARM_TIMER | ||
62 | int kvm_timer_hyp_init(void); | ||
63 | int kvm_timer_init(struct kvm *kvm); | ||
64 | void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu); | ||
65 | void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu); | ||
66 | void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu); | ||
67 | void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu); | ||
68 | #else | ||
69 | static inline int kvm_timer_hyp_init(void) | ||
70 | { | ||
71 | return 0; | ||
72 | }; | ||
73 | |||
74 | static inline int kvm_timer_init(struct kvm *kvm) | ||
75 | { | ||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | static inline void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu) {} | ||
80 | static inline void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu) {} | ||
81 | static inline void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu) {} | ||
82 | static inline void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu) {} | ||
83 | #endif | ||
84 | |||
85 | #endif | ||
diff --git a/arch/arm/include/asm/kvm_asm.h b/arch/arm/include/asm/kvm_asm.h index 5e06e8177784..e4956f4e23e1 100644 --- a/arch/arm/include/asm/kvm_asm.h +++ b/arch/arm/include/asm/kvm_asm.h | |||
@@ -45,7 +45,8 @@ | |||
45 | #define c13_TID_URW 23 /* Thread ID, User R/W */ | 45 | #define c13_TID_URW 23 /* Thread ID, User R/W */ |
46 | #define c13_TID_URO 24 /* Thread ID, User R/O */ | 46 | #define c13_TID_URO 24 /* Thread ID, User R/O */ |
47 | #define c13_TID_PRIV 25 /* Thread ID, Privileged */ | 47 | #define c13_TID_PRIV 25 /* Thread ID, Privileged */ |
48 | #define NR_CP15_REGS 26 /* Number of regs (incl. invalid) */ | 48 | #define c14_CNTKCTL 26 /* Timer Control Register (PL1) */ |
49 | #define NR_CP15_REGS 27 /* Number of regs (incl. invalid) */ | ||
49 | 50 | ||
50 | #define ARM_EXCEPTION_RESET 0 | 51 | #define ARM_EXCEPTION_RESET 0 |
51 | #define ARM_EXCEPTION_UNDEFINED 1 | 52 | #define ARM_EXCEPTION_UNDEFINED 1 |
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h index 98b4d1a72923..dfe98866a992 100644 --- a/arch/arm/include/asm/kvm_host.h +++ b/arch/arm/include/asm/kvm_host.h | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <asm/kvm_asm.h> | 23 | #include <asm/kvm_asm.h> |
24 | #include <asm/kvm_mmio.h> | 24 | #include <asm/kvm_mmio.h> |
25 | #include <asm/fpstate.h> | 25 | #include <asm/fpstate.h> |
26 | #include <asm/kvm_arch_timer.h> | ||
26 | 27 | ||
27 | #define KVM_MAX_VCPUS CONFIG_KVM_ARM_MAX_VCPUS | 28 | #define KVM_MAX_VCPUS CONFIG_KVM_ARM_MAX_VCPUS |
28 | #define KVM_MEMORY_SLOTS 32 | 29 | #define KVM_MEMORY_SLOTS 32 |
@@ -37,6 +38,8 @@ | |||
37 | #define KVM_NR_PAGE_SIZES 1 | 38 | #define KVM_NR_PAGE_SIZES 1 |
38 | #define KVM_PAGES_PER_HPAGE(x) (1UL<<31) | 39 | #define KVM_PAGES_PER_HPAGE(x) (1UL<<31) |
39 | 40 | ||
41 | #include <asm/kvm_vgic.h> | ||
42 | |||
40 | struct kvm_vcpu; | 43 | struct kvm_vcpu; |
41 | u32 *kvm_vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num, u32 mode); | 44 | u32 *kvm_vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num, u32 mode); |
42 | int kvm_target_cpu(void); | 45 | int kvm_target_cpu(void); |
@@ -47,6 +50,9 @@ struct kvm_arch { | |||
47 | /* VTTBR value associated with below pgd and vmid */ | 50 | /* VTTBR value associated with below pgd and vmid */ |
48 | u64 vttbr; | 51 | u64 vttbr; |
49 | 52 | ||
53 | /* Timer */ | ||
54 | struct arch_timer_kvm timer; | ||
55 | |||
50 | /* | 56 | /* |
51 | * Anything that is not used directly from assembly code goes | 57 | * Anything that is not used directly from assembly code goes |
52 | * here. | 58 | * here. |
@@ -58,6 +64,9 @@ struct kvm_arch { | |||
58 | 64 | ||
59 | /* Stage-2 page table */ | 65 | /* Stage-2 page table */ |
60 | pgd_t *pgd; | 66 | pgd_t *pgd; |
67 | |||
68 | /* Interrupt controller */ | ||
69 | struct vgic_dist vgic; | ||
61 | }; | 70 | }; |
62 | 71 | ||
63 | #define KVM_NR_MEM_OBJS 40 | 72 | #define KVM_NR_MEM_OBJS 40 |
@@ -92,6 +101,10 @@ struct kvm_vcpu_arch { | |||
92 | struct vfp_hard_struct vfp_guest; | 101 | struct vfp_hard_struct vfp_guest; |
93 | struct vfp_hard_struct *vfp_host; | 102 | struct vfp_hard_struct *vfp_host; |
94 | 103 | ||
104 | /* VGIC state */ | ||
105 | struct vgic_cpu vgic_cpu; | ||
106 | struct arch_timer_cpu timer_cpu; | ||
107 | |||
95 | /* | 108 | /* |
96 | * Anything that is not used directly from assembly code goes | 109 | * Anything that is not used directly from assembly code goes |
97 | * here. | 110 | * here. |
@@ -158,4 +171,14 @@ static inline int kvm_test_age_hva(struct kvm *kvm, unsigned long hva) | |||
158 | { | 171 | { |
159 | return 0; | 172 | return 0; |
160 | } | 173 | } |
174 | |||
175 | struct kvm_vcpu *kvm_arm_get_running_vcpu(void); | ||
176 | struct kvm_vcpu __percpu **kvm_get_running_vcpus(void); | ||
177 | |||
178 | int kvm_arm_copy_coproc_indices(struct kvm_vcpu *vcpu, u64 __user *uindices); | ||
179 | unsigned long kvm_arm_num_coproc_regs(struct kvm_vcpu *vcpu); | ||
180 | struct kvm_one_reg; | ||
181 | int kvm_arm_coproc_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *); | ||
182 | int kvm_arm_coproc_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *); | ||
183 | |||
161 | #endif /* __ARM_KVM_HOST_H__ */ | 184 | #endif /* __ARM_KVM_HOST_H__ */ |
diff --git a/arch/arm/include/asm/kvm_vgic.h b/arch/arm/include/asm/kvm_vgic.h new file mode 100644 index 000000000000..ab97207d9cd3 --- /dev/null +++ b/arch/arm/include/asm/kvm_vgic.h | |||
@@ -0,0 +1,221 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012 ARM Ltd. | ||
3 | * Author: Marc Zyngier <marc.zyngier@arm.com> | ||
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, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
17 | */ | ||
18 | |||
19 | #ifndef __ASM_ARM_KVM_VGIC_H | ||
20 | #define __ASM_ARM_KVM_VGIC_H | ||
21 | |||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/kvm.h> | ||
24 | #include <linux/kvm_host.h> | ||
25 | #include <linux/irqreturn.h> | ||
26 | #include <linux/spinlock.h> | ||
27 | #include <linux/types.h> | ||
28 | #include <linux/irqchip/arm-gic.h> | ||
29 | |||
30 | #define VGIC_NR_IRQS 128 | ||
31 | #define VGIC_NR_SGIS 16 | ||
32 | #define VGIC_NR_PPIS 16 | ||
33 | #define VGIC_NR_PRIVATE_IRQS (VGIC_NR_SGIS + VGIC_NR_PPIS) | ||
34 | #define VGIC_NR_SHARED_IRQS (VGIC_NR_IRQS - VGIC_NR_PRIVATE_IRQS) | ||
35 | #define VGIC_MAX_CPUS KVM_MAX_VCPUS | ||
36 | #define VGIC_MAX_LRS (1 << 6) | ||
37 | |||
38 | /* Sanity checks... */ | ||
39 | #if (VGIC_MAX_CPUS > 8) | ||
40 | #error Invalid number of CPU interfaces | ||
41 | #endif | ||
42 | |||
43 | #if (VGIC_NR_IRQS & 31) | ||
44 | #error "VGIC_NR_IRQS must be a multiple of 32" | ||
45 | #endif | ||
46 | |||
47 | #if (VGIC_NR_IRQS > 1024) | ||
48 | #error "VGIC_NR_IRQS must be <= 1024" | ||
49 | #endif | ||
50 | |||
51 | /* | ||
52 | * The GIC distributor registers describing interrupts have two parts: | ||
53 | * - 32 per-CPU interrupts (SGI + PPI) | ||
54 | * - a bunch of shared interrupts (SPI) | ||
55 | */ | ||
56 | struct vgic_bitmap { | ||
57 | union { | ||
58 | u32 reg[VGIC_NR_PRIVATE_IRQS / 32]; | ||
59 | DECLARE_BITMAP(reg_ul, VGIC_NR_PRIVATE_IRQS); | ||
60 | } percpu[VGIC_MAX_CPUS]; | ||
61 | union { | ||
62 | u32 reg[VGIC_NR_SHARED_IRQS / 32]; | ||
63 | DECLARE_BITMAP(reg_ul, VGIC_NR_SHARED_IRQS); | ||
64 | } shared; | ||
65 | }; | ||
66 | |||
67 | struct vgic_bytemap { | ||
68 | u32 percpu[VGIC_MAX_CPUS][VGIC_NR_PRIVATE_IRQS / 4]; | ||
69 | u32 shared[VGIC_NR_SHARED_IRQS / 4]; | ||
70 | }; | ||
71 | |||
72 | struct vgic_dist { | ||
73 | #ifdef CONFIG_KVM_ARM_VGIC | ||
74 | spinlock_t lock; | ||
75 | bool ready; | ||
76 | |||
77 | /* Virtual control interface mapping */ | ||
78 | void __iomem *vctrl_base; | ||
79 | |||
80 | /* Distributor and vcpu interface mapping in the guest */ | ||
81 | phys_addr_t vgic_dist_base; | ||
82 | phys_addr_t vgic_cpu_base; | ||
83 | |||
84 | /* Distributor enabled */ | ||
85 | u32 enabled; | ||
86 | |||
87 | /* Interrupt enabled (one bit per IRQ) */ | ||
88 | struct vgic_bitmap irq_enabled; | ||
89 | |||
90 | /* Interrupt 'pin' level */ | ||
91 | struct vgic_bitmap irq_state; | ||
92 | |||
93 | /* Level-triggered interrupt in progress */ | ||
94 | struct vgic_bitmap irq_active; | ||
95 | |||
96 | /* Interrupt priority. Not used yet. */ | ||
97 | struct vgic_bytemap irq_priority; | ||
98 | |||
99 | /* Level/edge triggered */ | ||
100 | struct vgic_bitmap irq_cfg; | ||
101 | |||
102 | /* Source CPU per SGI and target CPU */ | ||
103 | u8 irq_sgi_sources[VGIC_MAX_CPUS][VGIC_NR_SGIS]; | ||
104 | |||
105 | /* Target CPU for each IRQ */ | ||
106 | u8 irq_spi_cpu[VGIC_NR_SHARED_IRQS]; | ||
107 | struct vgic_bitmap irq_spi_target[VGIC_MAX_CPUS]; | ||
108 | |||
109 | /* Bitmap indicating which CPU has something pending */ | ||
110 | unsigned long irq_pending_on_cpu; | ||
111 | #endif | ||
112 | }; | ||
113 | |||
114 | struct vgic_cpu { | ||
115 | #ifdef CONFIG_KVM_ARM_VGIC | ||
116 | /* per IRQ to LR mapping */ | ||
117 | u8 vgic_irq_lr_map[VGIC_NR_IRQS]; | ||
118 | |||
119 | /* Pending interrupts on this VCPU */ | ||
120 | DECLARE_BITMAP( pending_percpu, VGIC_NR_PRIVATE_IRQS); | ||
121 | DECLARE_BITMAP( pending_shared, VGIC_NR_SHARED_IRQS); | ||
122 | |||
123 | /* Bitmap of used/free list registers */ | ||
124 | DECLARE_BITMAP( lr_used, VGIC_MAX_LRS); | ||
125 | |||
126 | /* Number of list registers on this CPU */ | ||
127 | int nr_lr; | ||
128 | |||
129 | /* CPU vif control registers for world switch */ | ||
130 | u32 vgic_hcr; | ||
131 | u32 vgic_vmcr; | ||
132 | u32 vgic_misr; /* Saved only */ | ||
133 | u32 vgic_eisr[2]; /* Saved only */ | ||
134 | u32 vgic_elrsr[2]; /* Saved only */ | ||
135 | u32 vgic_apr; | ||
136 | u32 vgic_lr[VGIC_MAX_LRS]; | ||
137 | #endif | ||
138 | }; | ||
139 | |||
140 | #define LR_EMPTY 0xff | ||
141 | |||
142 | struct kvm; | ||
143 | struct kvm_vcpu; | ||
144 | struct kvm_run; | ||
145 | struct kvm_exit_mmio; | ||
146 | |||
147 | #ifdef CONFIG_KVM_ARM_VGIC | ||
148 | int kvm_vgic_set_addr(struct kvm *kvm, unsigned long type, u64 addr); | ||
149 | int kvm_vgic_hyp_init(void); | ||
150 | int kvm_vgic_init(struct kvm *kvm); | ||
151 | int kvm_vgic_create(struct kvm *kvm); | ||
152 | int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu); | ||
153 | void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu); | ||
154 | void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu); | ||
155 | int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num, | ||
156 | bool level); | ||
157 | int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu); | ||
158 | bool vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run, | ||
159 | struct kvm_exit_mmio *mmio); | ||
160 | |||
161 | #define irqchip_in_kernel(k) (!!((k)->arch.vgic.vctrl_base)) | ||
162 | #define vgic_initialized(k) ((k)->arch.vgic.ready) | ||
163 | |||
164 | #else | ||
165 | static inline int kvm_vgic_hyp_init(void) | ||
166 | { | ||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | static inline int kvm_vgic_set_addr(struct kvm *kvm, unsigned long type, u64 addr) | ||
171 | { | ||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | static inline int kvm_vgic_init(struct kvm *kvm) | ||
176 | { | ||
177 | return 0; | ||
178 | } | ||
179 | |||
180 | static inline int kvm_vgic_create(struct kvm *kvm) | ||
181 | { | ||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | static inline int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu) | ||
186 | { | ||
187 | return 0; | ||
188 | } | ||
189 | |||
190 | static inline void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu) {} | ||
191 | static inline void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu) {} | ||
192 | |||
193 | static inline int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, | ||
194 | unsigned int irq_num, bool level) | ||
195 | { | ||
196 | return 0; | ||
197 | } | ||
198 | |||
199 | static inline int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu) | ||
200 | { | ||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | static inline bool vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run, | ||
205 | struct kvm_exit_mmio *mmio) | ||
206 | { | ||
207 | return false; | ||
208 | } | ||
209 | |||
210 | static inline int irqchip_in_kernel(struct kvm *kvm) | ||
211 | { | ||
212 | return 0; | ||
213 | } | ||
214 | |||
215 | static inline bool vgic_initialized(struct kvm *kvm) | ||
216 | { | ||
217 | return true; | ||
218 | } | ||
219 | #endif | ||
220 | |||
221 | #endif | ||
diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h index 3303ff5adbf3..023bfeb367bf 100644 --- a/arch/arm/include/uapi/asm/kvm.h +++ b/arch/arm/include/uapi/asm/kvm.h | |||
@@ -65,6 +65,22 @@ struct kvm_regs { | |||
65 | #define KVM_ARM_TARGET_CORTEX_A15 0 | 65 | #define KVM_ARM_TARGET_CORTEX_A15 0 |
66 | #define KVM_ARM_NUM_TARGETS 1 | 66 | #define KVM_ARM_NUM_TARGETS 1 |
67 | 67 | ||
68 | /* KVM_ARM_SET_DEVICE_ADDR ioctl id encoding */ | ||
69 | #define KVM_ARM_DEVICE_TYPE_SHIFT 0 | ||
70 | #define KVM_ARM_DEVICE_TYPE_MASK (0xffff << KVM_ARM_DEVICE_TYPE_SHIFT) | ||
71 | #define KVM_ARM_DEVICE_ID_SHIFT 16 | ||
72 | #define KVM_ARM_DEVICE_ID_MASK (0xffff << KVM_ARM_DEVICE_ID_SHIFT) | ||
73 | |||
74 | /* Supported device IDs */ | ||
75 | #define KVM_ARM_DEVICE_VGIC_V2 0 | ||
76 | |||
77 | /* Supported VGIC address types */ | ||
78 | #define KVM_VGIC_V2_ADDR_TYPE_DIST 0 | ||
79 | #define KVM_VGIC_V2_ADDR_TYPE_CPU 1 | ||
80 | |||
81 | #define KVM_VGIC_V2_DIST_SIZE 0x1000 | ||
82 | #define KVM_VGIC_V2_CPU_SIZE 0x2000 | ||
83 | |||
68 | #define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */ | 84 | #define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */ |
69 | 85 | ||
70 | struct kvm_vcpu_init { | 86 | struct kvm_vcpu_init { |