diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-07 14:35:30 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-07 14:35:30 -0400 |
commit | 66bb0aa077978dbb76e6283531eb3cc7a878de38 (patch) | |
tree | 62a28a96cb43df2d8f7c6eb14d4676a1e2ce3887 /arch | |
parent | e306e3be1cbe5b11d0f8a53a557c205cf27e4979 (diff) | |
parent | c77dcacb397519b6ade8f08201a4a90a7f4f751e (diff) |
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull second round of KVM changes from Paolo Bonzini:
"Here are the PPC and ARM changes for KVM, which I separated because
they had small conflicts (respectively within KVM documentation, and
with 3.16-rc changes). Since they were all within the subsystem, I
took care of them.
Stephen Rothwell reported some snags in PPC builds, but they are all
fixed now; the latest linux-next report was clean.
New features for ARM include:
- KVM VGIC v2 emulation on GICv3 hardware
- Big-Endian support for arm/arm64 (guest and host)
- Debug Architecture support for arm64 (arm32 is on Christoffer's todo list)
And for PPC:
- Book3S: Good number of LE host fixes, enable HV on LE
- Book3S HV: Add in-guest debug support
This release drops support for KVM on the PPC440. As a result, the
PPC merge removes more lines than it adds. :)
I also included an x86 change, since Davidlohr tied it to an
independent bug report and the reporter quickly provided a Tested-by;
there was no reason to wait for -rc2"
* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: (122 commits)
KVM: Move more code under CONFIG_HAVE_KVM_IRQFD
KVM: nVMX: fix "acknowledge interrupt on exit" when APICv is in use
KVM: nVMX: Fix nested vmexit ack intr before load vmcs01
KVM: PPC: Enable IRQFD support for the XICS interrupt controller
KVM: Give IRQFD its own separate enabling Kconfig option
KVM: Move irq notifier implementation into eventfd.c
KVM: Move all accesses to kvm::irq_routing into irqchip.c
KVM: irqchip: Provide and use accessors for irq routing table
KVM: Don't keep reference to irq routing table in irqfd struct
KVM: PPC: drop duplicate tracepoint
arm64: KVM: fix 64bit CP15 VM access for 32bit guests
KVM: arm64: GICv3: mandate page-aligned GICV region
arm64: KVM: GICv3: move system register access to msr_s/mrs_s
KVM: PPC: PR: Handle FSCR feature deselects
KVM: PPC: HV: Remove generic instruction emulation
KVM: PPC: BOOKEHV: rename e500hv_spr to bookehv_spr
KVM: PPC: Remove DCR handling
KVM: PPC: Expose helper functions for data/inst faults
KVM: PPC: Separate loadstore emulation from priv emulation
KVM: PPC: Handle magic page in kvmppc_ld/st
...
Diffstat (limited to 'arch')
98 files changed, 3818 insertions, 2415 deletions
diff --git a/arch/arm/include/asm/kvm_asm.h b/arch/arm/include/asm/kvm_asm.h index 53b3c4a50d5c..3a67bec72d0c 100644 --- a/arch/arm/include/asm/kvm_asm.h +++ b/arch/arm/include/asm/kvm_asm.h | |||
@@ -61,6 +61,24 @@ | |||
61 | #define ARM_EXCEPTION_FIQ 6 | 61 | #define ARM_EXCEPTION_FIQ 6 |
62 | #define ARM_EXCEPTION_HVC 7 | 62 | #define ARM_EXCEPTION_HVC 7 |
63 | 63 | ||
64 | /* | ||
65 | * The rr_lo_hi macro swaps a pair of registers depending on | ||
66 | * current endianness. It is used in conjunction with ldrd and strd | ||
67 | * instructions that load/store a 64-bit value from/to memory to/from | ||
68 | * a pair of registers which are used with the mrrc and mcrr instructions. | ||
69 | * If used with the ldrd/strd instructions, the a1 parameter is the first | ||
70 | * source/destination register and the a2 parameter is the second | ||
71 | * source/destination register. Note that the ldrd/strd instructions | ||
72 | * already swap the bytes within the words correctly according to the | ||
73 | * endianness setting, but the order of the registers need to be effectively | ||
74 | * swapped when used with the mrrc/mcrr instructions. | ||
75 | */ | ||
76 | #ifdef CONFIG_CPU_ENDIAN_BE8 | ||
77 | #define rr_lo_hi(a1, a2) a2, a1 | ||
78 | #else | ||
79 | #define rr_lo_hi(a1, a2) a1, a2 | ||
80 | #endif | ||
81 | |||
64 | #ifndef __ASSEMBLY__ | 82 | #ifndef __ASSEMBLY__ |
65 | struct kvm; | 83 | struct kvm; |
66 | struct kvm_vcpu; | 84 | struct kvm_vcpu; |
diff --git a/arch/arm/include/asm/kvm_emulate.h b/arch/arm/include/asm/kvm_emulate.h index 0fa90c962ac8..69b746955fca 100644 --- a/arch/arm/include/asm/kvm_emulate.h +++ b/arch/arm/include/asm/kvm_emulate.h | |||
@@ -185,9 +185,16 @@ static inline unsigned long vcpu_data_guest_to_host(struct kvm_vcpu *vcpu, | |||
185 | default: | 185 | default: |
186 | return be32_to_cpu(data); | 186 | return be32_to_cpu(data); |
187 | } | 187 | } |
188 | } else { | ||
189 | switch (len) { | ||
190 | case 1: | ||
191 | return data & 0xff; | ||
192 | case 2: | ||
193 | return le16_to_cpu(data & 0xffff); | ||
194 | default: | ||
195 | return le32_to_cpu(data); | ||
196 | } | ||
188 | } | 197 | } |
189 | |||
190 | return data; /* Leave LE untouched */ | ||
191 | } | 198 | } |
192 | 199 | ||
193 | static inline unsigned long vcpu_data_host_to_guest(struct kvm_vcpu *vcpu, | 200 | static inline unsigned long vcpu_data_host_to_guest(struct kvm_vcpu *vcpu, |
@@ -203,9 +210,16 @@ static inline unsigned long vcpu_data_host_to_guest(struct kvm_vcpu *vcpu, | |||
203 | default: | 210 | default: |
204 | return cpu_to_be32(data); | 211 | return cpu_to_be32(data); |
205 | } | 212 | } |
213 | } else { | ||
214 | switch (len) { | ||
215 | case 1: | ||
216 | return data & 0xff; | ||
217 | case 2: | ||
218 | return cpu_to_le16(data & 0xffff); | ||
219 | default: | ||
220 | return cpu_to_le32(data); | ||
221 | } | ||
206 | } | 222 | } |
207 | |||
208 | return data; /* Leave LE untouched */ | ||
209 | } | 223 | } |
210 | 224 | ||
211 | #endif /* __ARM_KVM_EMULATE_H__ */ | 225 | #endif /* __ARM_KVM_EMULATE_H__ */ |
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h index 193ceaf01bfd..6dfb404f6c46 100644 --- a/arch/arm/include/asm/kvm_host.h +++ b/arch/arm/include/asm/kvm_host.h | |||
@@ -225,10 +225,12 @@ static inline int kvm_arch_dev_ioctl_check_extension(long ext) | |||
225 | return 0; | 225 | return 0; |
226 | } | 226 | } |
227 | 227 | ||
228 | static inline void vgic_arch_setup(const struct vgic_params *vgic) | ||
229 | { | ||
230 | BUG_ON(vgic->type != VGIC_V2); | ||
231 | } | ||
232 | |||
228 | int kvm_perf_init(void); | 233 | int kvm_perf_init(void); |
229 | int kvm_perf_teardown(void); | 234 | int kvm_perf_teardown(void); |
230 | 235 | ||
231 | u64 kvm_arm_timer_get_reg(struct kvm_vcpu *, u64 regid); | ||
232 | int kvm_arm_timer_set_reg(struct kvm_vcpu *, u64 regid, u64 value); | ||
233 | |||
234 | #endif /* __ARM_KVM_HOST_H__ */ | 236 | #endif /* __ARM_KVM_HOST_H__ */ |
diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h index 5c7aa3c1519f..5cc0b0f5f72f 100644 --- a/arch/arm/include/asm/kvm_mmu.h +++ b/arch/arm/include/asm/kvm_mmu.h | |||
@@ -127,6 +127,18 @@ static inline void kvm_set_s2pmd_writable(pmd_t *pmd) | |||
127 | (__boundary - 1 < (end) - 1)? __boundary: (end); \ | 127 | (__boundary - 1 < (end) - 1)? __boundary: (end); \ |
128 | }) | 128 | }) |
129 | 129 | ||
130 | static inline bool kvm_page_empty(void *ptr) | ||
131 | { | ||
132 | struct page *ptr_page = virt_to_page(ptr); | ||
133 | return page_count(ptr_page) == 1; | ||
134 | } | ||
135 | |||
136 | |||
137 | #define kvm_pte_table_empty(ptep) kvm_page_empty(ptep) | ||
138 | #define kvm_pmd_table_empty(pmdp) kvm_page_empty(pmdp) | ||
139 | #define kvm_pud_table_empty(pudp) (0) | ||
140 | |||
141 | |||
130 | struct kvm; | 142 | struct kvm; |
131 | 143 | ||
132 | #define kvm_flush_dcache_to_poc(a,l) __cpuc_flush_dcache_area((a), (l)) | 144 | #define kvm_flush_dcache_to_poc(a,l) __cpuc_flush_dcache_area((a), (l)) |
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c index 85598b5d1efd..713e807621d2 100644 --- a/arch/arm/kernel/asm-offsets.c +++ b/arch/arm/kernel/asm-offsets.c | |||
@@ -182,13 +182,13 @@ int main(void) | |||
182 | DEFINE(VCPU_HYP_PC, offsetof(struct kvm_vcpu, arch.fault.hyp_pc)); | 182 | DEFINE(VCPU_HYP_PC, offsetof(struct kvm_vcpu, arch.fault.hyp_pc)); |
183 | #ifdef CONFIG_KVM_ARM_VGIC | 183 | #ifdef CONFIG_KVM_ARM_VGIC |
184 | DEFINE(VCPU_VGIC_CPU, offsetof(struct kvm_vcpu, arch.vgic_cpu)); | 184 | DEFINE(VCPU_VGIC_CPU, offsetof(struct kvm_vcpu, arch.vgic_cpu)); |
185 | DEFINE(VGIC_CPU_HCR, offsetof(struct vgic_cpu, vgic_hcr)); | 185 | DEFINE(VGIC_V2_CPU_HCR, offsetof(struct vgic_cpu, vgic_v2.vgic_hcr)); |
186 | DEFINE(VGIC_CPU_VMCR, offsetof(struct vgic_cpu, vgic_vmcr)); | 186 | DEFINE(VGIC_V2_CPU_VMCR, offsetof(struct vgic_cpu, vgic_v2.vgic_vmcr)); |
187 | DEFINE(VGIC_CPU_MISR, offsetof(struct vgic_cpu, vgic_misr)); | 187 | DEFINE(VGIC_V2_CPU_MISR, offsetof(struct vgic_cpu, vgic_v2.vgic_misr)); |
188 | DEFINE(VGIC_CPU_EISR, offsetof(struct vgic_cpu, vgic_eisr)); | 188 | DEFINE(VGIC_V2_CPU_EISR, offsetof(struct vgic_cpu, vgic_v2.vgic_eisr)); |
189 | DEFINE(VGIC_CPU_ELRSR, offsetof(struct vgic_cpu, vgic_elrsr)); | 189 | DEFINE(VGIC_V2_CPU_ELRSR, offsetof(struct vgic_cpu, vgic_v2.vgic_elrsr)); |
190 | DEFINE(VGIC_CPU_APR, offsetof(struct vgic_cpu, vgic_apr)); | 190 | DEFINE(VGIC_V2_CPU_APR, offsetof(struct vgic_cpu, vgic_v2.vgic_apr)); |
191 | DEFINE(VGIC_CPU_LR, offsetof(struct vgic_cpu, vgic_lr)); | 191 | DEFINE(VGIC_V2_CPU_LR, offsetof(struct vgic_cpu, vgic_v2.vgic_lr)); |
192 | DEFINE(VGIC_CPU_NR_LR, offsetof(struct vgic_cpu, nr_lr)); | 192 | DEFINE(VGIC_CPU_NR_LR, offsetof(struct vgic_cpu, nr_lr)); |
193 | #ifdef CONFIG_KVM_ARM_TIMER | 193 | #ifdef CONFIG_KVM_ARM_TIMER |
194 | DEFINE(VCPU_TIMER_CNTV_CTL, offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_ctl)); | 194 | DEFINE(VCPU_TIMER_CNTV_CTL, offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_ctl)); |
diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S index 56ce6290c831..2a55373f49bf 100644 --- a/arch/arm/kernel/hyp-stub.S +++ b/arch/arm/kernel/hyp-stub.S | |||
@@ -134,9 +134,7 @@ ENTRY(__hyp_stub_install_secondary) | |||
134 | mcr p15, 4, r7, c1, c1, 3 @ HSTR | 134 | mcr p15, 4, r7, c1, c1, 3 @ HSTR |
135 | 135 | ||
136 | THUMB( orr r7, #(1 << 30) ) @ HSCTLR.TE | 136 | THUMB( orr r7, #(1 << 30) ) @ HSCTLR.TE |
137 | #ifdef CONFIG_CPU_BIG_ENDIAN | 137 | ARM_BE8(orr r7, r7, #(1 << 25)) @ HSCTLR.EE |
138 | orr r7, #(1 << 9) @ HSCTLR.EE | ||
139 | #endif | ||
140 | mcr p15, 4, r7, c1, c0, 0 @ HSCTLR | 138 | mcr p15, 4, r7, c1, c0, 0 @ HSCTLR |
141 | 139 | ||
142 | mrc p15, 4, r7, c1, c1, 1 @ HDCR | 140 | mrc p15, 4, r7, c1, c1, 1 @ HDCR |
diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig index 4be5bb150bdd..466bd299b1a8 100644 --- a/arch/arm/kvm/Kconfig +++ b/arch/arm/kvm/Kconfig | |||
@@ -23,7 +23,7 @@ config KVM | |||
23 | select HAVE_KVM_CPU_RELAX_INTERCEPT | 23 | select HAVE_KVM_CPU_RELAX_INTERCEPT |
24 | select KVM_MMIO | 24 | select KVM_MMIO |
25 | select KVM_ARM_HOST | 25 | select KVM_ARM_HOST |
26 | depends on ARM_VIRT_EXT && ARM_LPAE && !CPU_BIG_ENDIAN | 26 | depends on ARM_VIRT_EXT && ARM_LPAE |
27 | ---help--- | 27 | ---help--- |
28 | Support hosting virtualized guest machines. You will also | 28 | Support hosting virtualized guest machines. You will also |
29 | need to select one or more of the processor modules below. | 29 | need to select one or more of the processor modules below. |
diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile index 789bca9e64a7..f7057ed045b6 100644 --- a/arch/arm/kvm/Makefile +++ b/arch/arm/kvm/Makefile | |||
@@ -21,4 +21,5 @@ obj-y += kvm-arm.o init.o interrupts.o | |||
21 | obj-y += arm.o handle_exit.o guest.o mmu.o emulate.o reset.o | 21 | obj-y += arm.o handle_exit.o guest.o mmu.o emulate.o reset.o |
22 | obj-y += coproc.o coproc_a15.o coproc_a7.o mmio.o psci.o perf.o | 22 | obj-y += coproc.o coproc_a15.o coproc_a7.o mmio.o psci.o perf.o |
23 | obj-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic.o | 23 | obj-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic.o |
24 | obj-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic-v2.o | ||
24 | obj-$(CONFIG_KVM_ARM_TIMER) += $(KVM)/arm/arch_timer.o | 25 | obj-$(CONFIG_KVM_ARM_TIMER) += $(KVM)/arm/arch_timer.o |
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 3c82b37c0f9e..a99e0cdf8ba2 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c | |||
@@ -155,16 +155,6 @@ int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf) | |||
155 | return VM_FAULT_SIGBUS; | 155 | return VM_FAULT_SIGBUS; |
156 | } | 156 | } |
157 | 157 | ||
158 | void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *free, | ||
159 | struct kvm_memory_slot *dont) | ||
160 | { | ||
161 | } | ||
162 | |||
163 | int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot, | ||
164 | unsigned long npages) | ||
165 | { | ||
166 | return 0; | ||
167 | } | ||
168 | 158 | ||
169 | /** | 159 | /** |
170 | * kvm_arch_destroy_vm - destroy the VM data structure | 160 | * kvm_arch_destroy_vm - destroy the VM data structure |
@@ -184,7 +174,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm) | |||
184 | } | 174 | } |
185 | } | 175 | } |
186 | 176 | ||
187 | int kvm_dev_ioctl_check_extension(long ext) | 177 | int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) |
188 | { | 178 | { |
189 | int r; | 179 | int r; |
190 | switch (ext) { | 180 | switch (ext) { |
@@ -225,33 +215,6 @@ long kvm_arch_dev_ioctl(struct file *filp, | |||
225 | return -EINVAL; | 215 | return -EINVAL; |
226 | } | 216 | } |
227 | 217 | ||
228 | void kvm_arch_memslots_updated(struct kvm *kvm) | ||
229 | { | ||
230 | } | ||
231 | |||
232 | int kvm_arch_prepare_memory_region(struct kvm *kvm, | ||
233 | struct kvm_memory_slot *memslot, | ||
234 | struct kvm_userspace_memory_region *mem, | ||
235 | enum kvm_mr_change change) | ||
236 | { | ||
237 | return 0; | ||
238 | } | ||
239 | |||
240 | void kvm_arch_commit_memory_region(struct kvm *kvm, | ||
241 | struct kvm_userspace_memory_region *mem, | ||
242 | const struct kvm_memory_slot *old, | ||
243 | enum kvm_mr_change change) | ||
244 | { | ||
245 | } | ||
246 | |||
247 | void kvm_arch_flush_shadow_all(struct kvm *kvm) | ||
248 | { | ||
249 | } | ||
250 | |||
251 | void kvm_arch_flush_shadow_memslot(struct kvm *kvm, | ||
252 | struct kvm_memory_slot *slot) | ||
253 | { | ||
254 | } | ||
255 | 218 | ||
256 | struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id) | 219 | struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id) |
257 | { | 220 | { |
diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c index c58a35116f63..37a0fe1bb9bb 100644 --- a/arch/arm/kvm/coproc.c +++ b/arch/arm/kvm/coproc.c | |||
@@ -44,6 +44,31 @@ static u32 cache_levels; | |||
44 | /* CSSELR values; used to index KVM_REG_ARM_DEMUX_ID_CCSIDR */ | 44 | /* CSSELR values; used to index KVM_REG_ARM_DEMUX_ID_CCSIDR */ |
45 | #define CSSELR_MAX 12 | 45 | #define CSSELR_MAX 12 |
46 | 46 | ||
47 | /* | ||
48 | * kvm_vcpu_arch.cp15 holds cp15 registers as an array of u32, but some | ||
49 | * of cp15 registers can be viewed either as couple of two u32 registers | ||
50 | * or one u64 register. Current u64 register encoding is that least | ||
51 | * significant u32 word is followed by most significant u32 word. | ||
52 | */ | ||
53 | static inline void vcpu_cp15_reg64_set(struct kvm_vcpu *vcpu, | ||
54 | const struct coproc_reg *r, | ||
55 | u64 val) | ||
56 | { | ||
57 | vcpu->arch.cp15[r->reg] = val & 0xffffffff; | ||
58 | vcpu->arch.cp15[r->reg + 1] = val >> 32; | ||
59 | } | ||
60 | |||
61 | static inline u64 vcpu_cp15_reg64_get(struct kvm_vcpu *vcpu, | ||
62 | const struct coproc_reg *r) | ||
63 | { | ||
64 | u64 val; | ||
65 | |||
66 | val = vcpu->arch.cp15[r->reg + 1]; | ||
67 | val = val << 32; | ||
68 | val = val | vcpu->arch.cp15[r->reg]; | ||
69 | return val; | ||
70 | } | ||
71 | |||
47 | int kvm_handle_cp10_id(struct kvm_vcpu *vcpu, struct kvm_run *run) | 72 | int kvm_handle_cp10_id(struct kvm_vcpu *vcpu, struct kvm_run *run) |
48 | { | 73 | { |
49 | kvm_inject_undefined(vcpu); | 74 | kvm_inject_undefined(vcpu); |
@@ -682,17 +707,23 @@ static struct coproc_reg invariant_cp15[] = { | |||
682 | { CRn( 0), CRm( 0), Op1( 1), Op2( 7), is32, NULL, get_AIDR }, | 707 | { CRn( 0), CRm( 0), Op1( 1), Op2( 7), is32, NULL, get_AIDR }, |
683 | }; | 708 | }; |
684 | 709 | ||
710 | /* | ||
711 | * Reads a register value from a userspace address to a kernel | ||
712 | * variable. Make sure that register size matches sizeof(*__val). | ||
713 | */ | ||
685 | static int reg_from_user(void *val, const void __user *uaddr, u64 id) | 714 | static int reg_from_user(void *val, const void __user *uaddr, u64 id) |
686 | { | 715 | { |
687 | /* This Just Works because we are little endian. */ | ||
688 | if (copy_from_user(val, uaddr, KVM_REG_SIZE(id)) != 0) | 716 | if (copy_from_user(val, uaddr, KVM_REG_SIZE(id)) != 0) |
689 | return -EFAULT; | 717 | return -EFAULT; |
690 | return 0; | 718 | return 0; |
691 | } | 719 | } |
692 | 720 | ||
721 | /* | ||
722 | * Writes a register value to a userspace address from a kernel variable. | ||
723 | * Make sure that register size matches sizeof(*__val). | ||
724 | */ | ||
693 | static int reg_to_user(void __user *uaddr, const void *val, u64 id) | 725 | static int reg_to_user(void __user *uaddr, const void *val, u64 id) |
694 | { | 726 | { |
695 | /* This Just Works because we are little endian. */ | ||
696 | if (copy_to_user(uaddr, val, KVM_REG_SIZE(id)) != 0) | 727 | if (copy_to_user(uaddr, val, KVM_REG_SIZE(id)) != 0) |
697 | return -EFAULT; | 728 | return -EFAULT; |
698 | return 0; | 729 | return 0; |
@@ -702,6 +733,7 @@ static int get_invariant_cp15(u64 id, void __user *uaddr) | |||
702 | { | 733 | { |
703 | struct coproc_params params; | 734 | struct coproc_params params; |
704 | const struct coproc_reg *r; | 735 | const struct coproc_reg *r; |
736 | int ret; | ||
705 | 737 | ||
706 | if (!index_to_params(id, ¶ms)) | 738 | if (!index_to_params(id, ¶ms)) |
707 | return -ENOENT; | 739 | return -ENOENT; |
@@ -710,7 +742,15 @@ static int get_invariant_cp15(u64 id, void __user *uaddr) | |||
710 | if (!r) | 742 | if (!r) |
711 | return -ENOENT; | 743 | return -ENOENT; |
712 | 744 | ||
713 | return reg_to_user(uaddr, &r->val, id); | 745 | ret = -ENOENT; |
746 | if (KVM_REG_SIZE(id) == 4) { | ||
747 | u32 val = r->val; | ||
748 | |||
749 | ret = reg_to_user(uaddr, &val, id); | ||
750 | } else if (KVM_REG_SIZE(id) == 8) { | ||
751 | ret = reg_to_user(uaddr, &r->val, id); | ||
752 | } | ||
753 | return ret; | ||
714 | } | 754 | } |
715 | 755 | ||
716 | static int set_invariant_cp15(u64 id, void __user *uaddr) | 756 | static int set_invariant_cp15(u64 id, void __user *uaddr) |
@@ -718,7 +758,7 @@ static int set_invariant_cp15(u64 id, void __user *uaddr) | |||
718 | struct coproc_params params; | 758 | struct coproc_params params; |
719 | const struct coproc_reg *r; | 759 | const struct coproc_reg *r; |
720 | int err; | 760 | int err; |
721 | u64 val = 0; /* Make sure high bits are 0 for 32-bit regs */ | 761 | u64 val; |
722 | 762 | ||
723 | if (!index_to_params(id, ¶ms)) | 763 | if (!index_to_params(id, ¶ms)) |
724 | return -ENOENT; | 764 | return -ENOENT; |
@@ -726,7 +766,16 @@ static int set_invariant_cp15(u64 id, void __user *uaddr) | |||
726 | if (!r) | 766 | if (!r) |
727 | return -ENOENT; | 767 | return -ENOENT; |
728 | 768 | ||
729 | err = reg_from_user(&val, uaddr, id); | 769 | err = -ENOENT; |
770 | if (KVM_REG_SIZE(id) == 4) { | ||
771 | u32 val32; | ||
772 | |||
773 | err = reg_from_user(&val32, uaddr, id); | ||
774 | if (!err) | ||
775 | val = val32; | ||
776 | } else if (KVM_REG_SIZE(id) == 8) { | ||
777 | err = reg_from_user(&val, uaddr, id); | ||
778 | } | ||
730 | if (err) | 779 | if (err) |
731 | return err; | 780 | return err; |
732 | 781 | ||
@@ -1004,6 +1053,7 @@ int kvm_arm_coproc_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) | |||
1004 | { | 1053 | { |
1005 | const struct coproc_reg *r; | 1054 | const struct coproc_reg *r; |
1006 | void __user *uaddr = (void __user *)(long)reg->addr; | 1055 | void __user *uaddr = (void __user *)(long)reg->addr; |
1056 | int ret; | ||
1007 | 1057 | ||
1008 | if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_DEMUX) | 1058 | if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_DEMUX) |
1009 | return demux_c15_get(reg->id, uaddr); | 1059 | return demux_c15_get(reg->id, uaddr); |
@@ -1015,14 +1065,24 @@ int kvm_arm_coproc_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) | |||
1015 | if (!r) | 1065 | if (!r) |
1016 | return get_invariant_cp15(reg->id, uaddr); | 1066 | return get_invariant_cp15(reg->id, uaddr); |
1017 | 1067 | ||
1018 | /* Note: copies two regs if size is 64 bit. */ | 1068 | ret = -ENOENT; |
1019 | return reg_to_user(uaddr, &vcpu->arch.cp15[r->reg], reg->id); | 1069 | if (KVM_REG_SIZE(reg->id) == 8) { |
1070 | u64 val; | ||
1071 | |||
1072 | val = vcpu_cp15_reg64_get(vcpu, r); | ||
1073 | ret = reg_to_user(uaddr, &val, reg->id); | ||
1074 | } else if (KVM_REG_SIZE(reg->id) == 4) { | ||
1075 | ret = reg_to_user(uaddr, &vcpu->arch.cp15[r->reg], reg->id); | ||
1076 | } | ||
1077 | |||
1078 | return ret; | ||
1020 | } | 1079 | } |
1021 | 1080 | ||
1022 | int kvm_arm_coproc_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) | 1081 | int kvm_arm_coproc_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) |
1023 | { | 1082 | { |
1024 | const struct coproc_reg *r; | 1083 | const struct coproc_reg *r; |
1025 | void __user *uaddr = (void __user *)(long)reg->addr; | 1084 | void __user *uaddr = (void __user *)(long)reg->addr; |
1085 | int ret; | ||
1026 | 1086 | ||
1027 | if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_DEMUX) | 1087 | if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_DEMUX) |
1028 | return demux_c15_set(reg->id, uaddr); | 1088 | return demux_c15_set(reg->id, uaddr); |
@@ -1034,8 +1094,18 @@ int kvm_arm_coproc_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) | |||
1034 | if (!r) | 1094 | if (!r) |
1035 | return set_invariant_cp15(reg->id, uaddr); | 1095 | return set_invariant_cp15(reg->id, uaddr); |
1036 | 1096 | ||
1037 | /* Note: copies two regs if size is 64 bit */ | 1097 | ret = -ENOENT; |
1038 | return reg_from_user(&vcpu->arch.cp15[r->reg], uaddr, reg->id); | 1098 | if (KVM_REG_SIZE(reg->id) == 8) { |
1099 | u64 val; | ||
1100 | |||
1101 | ret = reg_from_user(&val, uaddr, reg->id); | ||
1102 | if (!ret) | ||
1103 | vcpu_cp15_reg64_set(vcpu, r, val); | ||
1104 | } else if (KVM_REG_SIZE(reg->id) == 4) { | ||
1105 | ret = reg_from_user(&vcpu->arch.cp15[r->reg], uaddr, reg->id); | ||
1106 | } | ||
1107 | |||
1108 | return ret; | ||
1039 | } | 1109 | } |
1040 | 1110 | ||
1041 | static unsigned int num_demux_regs(void) | 1111 | static unsigned int num_demux_regs(void) |
diff --git a/arch/arm/kvm/guest.c b/arch/arm/kvm/guest.c index 70bf49b8b244..813e49258690 100644 --- a/arch/arm/kvm/guest.c +++ b/arch/arm/kvm/guest.c | |||
@@ -124,16 +124,6 @@ static bool is_timer_reg(u64 index) | |||
124 | return false; | 124 | return false; |
125 | } | 125 | } |
126 | 126 | ||
127 | int kvm_arm_timer_set_reg(struct kvm_vcpu *vcpu, u64 regid, u64 value) | ||
128 | { | ||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | u64 kvm_arm_timer_get_reg(struct kvm_vcpu *vcpu, u64 regid) | ||
133 | { | ||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | #else | 127 | #else |
138 | 128 | ||
139 | #define NUM_TIMER_REGS 3 | 129 | #define NUM_TIMER_REGS 3 |
diff --git a/arch/arm/kvm/init.S b/arch/arm/kvm/init.S index b2d229f09c07..991415d978b6 100644 --- a/arch/arm/kvm/init.S +++ b/arch/arm/kvm/init.S | |||
@@ -72,7 +72,7 @@ __do_hyp_init: | |||
72 | bne phase2 @ Yes, second stage init | 72 | bne phase2 @ Yes, second stage init |
73 | 73 | ||
74 | @ Set the HTTBR to point to the hypervisor PGD pointer passed | 74 | @ Set the HTTBR to point to the hypervisor PGD pointer passed |
75 | mcrr p15, 4, r2, r3, c2 | 75 | mcrr p15, 4, rr_lo_hi(r2, r3), c2 |
76 | 76 | ||
77 | @ Set the HTCR and VTCR to the same shareability and cacheability | 77 | @ Set the HTCR and VTCR to the same shareability and cacheability |
78 | @ settings as the non-secure TTBCR and with T0SZ == 0. | 78 | @ settings as the non-secure TTBCR and with T0SZ == 0. |
@@ -138,7 +138,7 @@ phase2: | |||
138 | ret r0 | 138 | ret r0 |
139 | 139 | ||
140 | target: @ We're now in the trampoline code, switch page tables | 140 | target: @ We're now in the trampoline code, switch page tables |
141 | mcrr p15, 4, r2, r3, c2 | 141 | mcrr p15, 4, rr_lo_hi(r2, r3), c2 |
142 | isb | 142 | isb |
143 | 143 | ||
144 | @ Invalidate the old TLBs | 144 | @ Invalidate the old TLBs |
diff --git a/arch/arm/kvm/interrupts.S b/arch/arm/kvm/interrupts.S index 0d68d4073068..01dcb0e752d9 100644 --- a/arch/arm/kvm/interrupts.S +++ b/arch/arm/kvm/interrupts.S | |||
@@ -52,7 +52,7 @@ ENTRY(__kvm_tlb_flush_vmid_ipa) | |||
52 | dsb ishst | 52 | dsb ishst |
53 | add r0, r0, #KVM_VTTBR | 53 | add r0, r0, #KVM_VTTBR |
54 | ldrd r2, r3, [r0] | 54 | ldrd r2, r3, [r0] |
55 | mcrr p15, 6, r2, r3, c2 @ Write VTTBR | 55 | mcrr p15, 6, rr_lo_hi(r2, r3), c2 @ Write VTTBR |
56 | isb | 56 | isb |
57 | mcr p15, 0, r0, c8, c3, 0 @ TLBIALLIS (rt ignored) | 57 | mcr p15, 0, r0, c8, c3, 0 @ TLBIALLIS (rt ignored) |
58 | dsb ish | 58 | dsb ish |
@@ -135,7 +135,7 @@ ENTRY(__kvm_vcpu_run) | |||
135 | ldr r1, [vcpu, #VCPU_KVM] | 135 | ldr r1, [vcpu, #VCPU_KVM] |
136 | add r1, r1, #KVM_VTTBR | 136 | add r1, r1, #KVM_VTTBR |
137 | ldrd r2, r3, [r1] | 137 | ldrd r2, r3, [r1] |
138 | mcrr p15, 6, r2, r3, c2 @ Write VTTBR | 138 | mcrr p15, 6, rr_lo_hi(r2, r3), c2 @ Write VTTBR |
139 | 139 | ||
140 | @ We're all done, just restore the GPRs and go to the guest | 140 | @ We're all done, just restore the GPRs and go to the guest |
141 | restore_guest_regs | 141 | restore_guest_regs |
@@ -199,8 +199,13 @@ after_vfp_restore: | |||
199 | 199 | ||
200 | restore_host_regs | 200 | restore_host_regs |
201 | clrex @ Clear exclusive monitor | 201 | clrex @ Clear exclusive monitor |
202 | #ifndef CONFIG_CPU_ENDIAN_BE8 | ||
202 | mov r0, r1 @ Return the return code | 203 | mov r0, r1 @ Return the return code |
203 | mov r1, #0 @ Clear upper bits in return value | 204 | mov r1, #0 @ Clear upper bits in return value |
205 | #else | ||
206 | @ r1 already has return code | ||
207 | mov r0, #0 @ Clear upper bits in return value | ||
208 | #endif /* CONFIG_CPU_ENDIAN_BE8 */ | ||
204 | bx lr @ return to IOCTL | 209 | bx lr @ return to IOCTL |
205 | 210 | ||
206 | /******************************************************************** | 211 | /******************************************************************** |
diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S index 76af93025574..98c8c5b9a87f 100644 --- a/arch/arm/kvm/interrupts_head.S +++ b/arch/arm/kvm/interrupts_head.S | |||
@@ -1,4 +1,5 @@ | |||
1 | #include <linux/irqchip/arm-gic.h> | 1 | #include <linux/irqchip/arm-gic.h> |
2 | #include <asm/assembler.h> | ||
2 | 3 | ||
3 | #define VCPU_USR_REG(_reg_nr) (VCPU_USR_REGS + (_reg_nr * 4)) | 4 | #define VCPU_USR_REG(_reg_nr) (VCPU_USR_REGS + (_reg_nr * 4)) |
4 | #define VCPU_USR_SP (VCPU_USR_REG(13)) | 5 | #define VCPU_USR_SP (VCPU_USR_REG(13)) |
@@ -420,15 +421,23 @@ vcpu .req r0 @ vcpu pointer always in r0 | |||
420 | ldr r8, [r2, #GICH_ELRSR0] | 421 | ldr r8, [r2, #GICH_ELRSR0] |
421 | ldr r9, [r2, #GICH_ELRSR1] | 422 | ldr r9, [r2, #GICH_ELRSR1] |
422 | ldr r10, [r2, #GICH_APR] | 423 | ldr r10, [r2, #GICH_APR] |
423 | 424 | ARM_BE8(rev r3, r3 ) | |
424 | str r3, [r11, #VGIC_CPU_HCR] | 425 | ARM_BE8(rev r4, r4 ) |
425 | str r4, [r11, #VGIC_CPU_VMCR] | 426 | ARM_BE8(rev r5, r5 ) |
426 | str r5, [r11, #VGIC_CPU_MISR] | 427 | ARM_BE8(rev r6, r6 ) |
427 | str r6, [r11, #VGIC_CPU_EISR] | 428 | ARM_BE8(rev r7, r7 ) |
428 | str r7, [r11, #(VGIC_CPU_EISR + 4)] | 429 | ARM_BE8(rev r8, r8 ) |
429 | str r8, [r11, #VGIC_CPU_ELRSR] | 430 | ARM_BE8(rev r9, r9 ) |
430 | str r9, [r11, #(VGIC_CPU_ELRSR + 4)] | 431 | ARM_BE8(rev r10, r10 ) |
431 | str r10, [r11, #VGIC_CPU_APR] | 432 | |
433 | str r3, [r11, #VGIC_V2_CPU_HCR] | ||
434 | str r4, [r11, #VGIC_V2_CPU_VMCR] | ||
435 | str r5, [r11, #VGIC_V2_CPU_MISR] | ||
436 | str r6, [r11, #VGIC_V2_CPU_EISR] | ||
437 | str r7, [r11, #(VGIC_V2_CPU_EISR + 4)] | ||
438 | str r8, [r11, #VGIC_V2_CPU_ELRSR] | ||
439 | str r9, [r11, #(VGIC_V2_CPU_ELRSR + 4)] | ||
440 | str r10, [r11, #VGIC_V2_CPU_APR] | ||
432 | 441 | ||
433 | /* Clear GICH_HCR */ | 442 | /* Clear GICH_HCR */ |
434 | mov r5, #0 | 443 | mov r5, #0 |
@@ -436,9 +445,10 @@ vcpu .req r0 @ vcpu pointer always in r0 | |||
436 | 445 | ||
437 | /* Save list registers */ | 446 | /* Save list registers */ |
438 | add r2, r2, #GICH_LR0 | 447 | add r2, r2, #GICH_LR0 |
439 | add r3, r11, #VGIC_CPU_LR | 448 | add r3, r11, #VGIC_V2_CPU_LR |
440 | ldr r4, [r11, #VGIC_CPU_NR_LR] | 449 | ldr r4, [r11, #VGIC_CPU_NR_LR] |
441 | 1: ldr r6, [r2], #4 | 450 | 1: ldr r6, [r2], #4 |
451 | ARM_BE8(rev r6, r6 ) | ||
442 | str r6, [r3], #4 | 452 | str r6, [r3], #4 |
443 | subs r4, r4, #1 | 453 | subs r4, r4, #1 |
444 | bne 1b | 454 | bne 1b |
@@ -463,9 +473,12 @@ vcpu .req r0 @ vcpu pointer always in r0 | |||
463 | add r11, vcpu, #VCPU_VGIC_CPU | 473 | add r11, vcpu, #VCPU_VGIC_CPU |
464 | 474 | ||
465 | /* We only restore a minimal set of registers */ | 475 | /* We only restore a minimal set of registers */ |
466 | ldr r3, [r11, #VGIC_CPU_HCR] | 476 | ldr r3, [r11, #VGIC_V2_CPU_HCR] |
467 | ldr r4, [r11, #VGIC_CPU_VMCR] | 477 | ldr r4, [r11, #VGIC_V2_CPU_VMCR] |
468 | ldr r8, [r11, #VGIC_CPU_APR] | 478 | ldr r8, [r11, #VGIC_V2_CPU_APR] |
479 | ARM_BE8(rev r3, r3 ) | ||
480 | ARM_BE8(rev r4, r4 ) | ||
481 | ARM_BE8(rev r8, r8 ) | ||
469 | 482 | ||
470 | str r3, [r2, #GICH_HCR] | 483 | str r3, [r2, #GICH_HCR] |
471 | str r4, [r2, #GICH_VMCR] | 484 | str r4, [r2, #GICH_VMCR] |
@@ -473,9 +486,10 @@ vcpu .req r0 @ vcpu pointer always in r0 | |||
473 | 486 | ||
474 | /* Restore list registers */ | 487 | /* Restore list registers */ |
475 | add r2, r2, #GICH_LR0 | 488 | add r2, r2, #GICH_LR0 |
476 | add r3, r11, #VGIC_CPU_LR | 489 | add r3, r11, #VGIC_V2_CPU_LR |
477 | ldr r4, [r11, #VGIC_CPU_NR_LR] | 490 | ldr r4, [r11, #VGIC_CPU_NR_LR] |
478 | 1: ldr r6, [r3], #4 | 491 | 1: ldr r6, [r3], #4 |
492 | ARM_BE8(rev r6, r6 ) | ||
479 | str r6, [r2], #4 | 493 | str r6, [r2], #4 |
480 | subs r4, r4, #1 | 494 | subs r4, r4, #1 |
481 | bne 1b | 495 | bne 1b |
@@ -506,7 +520,7 @@ vcpu .req r0 @ vcpu pointer always in r0 | |||
506 | mcr p15, 0, r2, c14, c3, 1 @ CNTV_CTL | 520 | mcr p15, 0, r2, c14, c3, 1 @ CNTV_CTL |
507 | isb | 521 | isb |
508 | 522 | ||
509 | mrrc p15, 3, r2, r3, c14 @ CNTV_CVAL | 523 | mrrc p15, 3, rr_lo_hi(r2, r3), c14 @ CNTV_CVAL |
510 | ldr r4, =VCPU_TIMER_CNTV_CVAL | 524 | ldr r4, =VCPU_TIMER_CNTV_CVAL |
511 | add r5, vcpu, r4 | 525 | add r5, vcpu, r4 |
512 | strd r2, r3, [r5] | 526 | strd r2, r3, [r5] |
@@ -546,12 +560,12 @@ vcpu .req r0 @ vcpu pointer always in r0 | |||
546 | 560 | ||
547 | ldr r2, [r4, #KVM_TIMER_CNTVOFF] | 561 | ldr r2, [r4, #KVM_TIMER_CNTVOFF] |
548 | ldr r3, [r4, #(KVM_TIMER_CNTVOFF + 4)] | 562 | ldr r3, [r4, #(KVM_TIMER_CNTVOFF + 4)] |
549 | mcrr p15, 4, r2, r3, c14 @ CNTVOFF | 563 | mcrr p15, 4, rr_lo_hi(r2, r3), c14 @ CNTVOFF |
550 | 564 | ||
551 | ldr r4, =VCPU_TIMER_CNTV_CVAL | 565 | ldr r4, =VCPU_TIMER_CNTV_CVAL |
552 | add r5, vcpu, r4 | 566 | add r5, vcpu, r4 |
553 | ldrd r2, r3, [r5] | 567 | ldrd r2, r3, [r5] |
554 | mcrr p15, 3, r2, r3, c14 @ CNTV_CVAL | 568 | mcrr p15, 3, rr_lo_hi(r2, r3), c14 @ CNTV_CVAL |
555 | isb | 569 | isb |
556 | 570 | ||
557 | ldr r2, [vcpu, #VCPU_TIMER_CNTV_CTL] | 571 | ldr r2, [vcpu, #VCPU_TIMER_CNTV_CTL] |
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index 16f804938b8f..16e7994bf347 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c | |||
@@ -90,104 +90,115 @@ static void *mmu_memory_cache_alloc(struct kvm_mmu_memory_cache *mc) | |||
90 | return p; | 90 | return p; |
91 | } | 91 | } |
92 | 92 | ||
93 | static bool page_empty(void *ptr) | 93 | static void clear_pgd_entry(struct kvm *kvm, pgd_t *pgd, phys_addr_t addr) |
94 | { | 94 | { |
95 | struct page *ptr_page = virt_to_page(ptr); | 95 | pud_t *pud_table __maybe_unused = pud_offset(pgd, 0); |
96 | return page_count(ptr_page) == 1; | 96 | pgd_clear(pgd); |
97 | kvm_tlb_flush_vmid_ipa(kvm, addr); | ||
98 | pud_free(NULL, pud_table); | ||
99 | put_page(virt_to_page(pgd)); | ||
97 | } | 100 | } |
98 | 101 | ||
99 | static void clear_pud_entry(struct kvm *kvm, pud_t *pud, phys_addr_t addr) | 102 | static void clear_pud_entry(struct kvm *kvm, pud_t *pud, phys_addr_t addr) |
100 | { | 103 | { |
101 | if (pud_huge(*pud)) { | 104 | pmd_t *pmd_table = pmd_offset(pud, 0); |
102 | pud_clear(pud); | 105 | VM_BUG_ON(pud_huge(*pud)); |
103 | kvm_tlb_flush_vmid_ipa(kvm, addr); | 106 | pud_clear(pud); |
104 | } else { | 107 | kvm_tlb_flush_vmid_ipa(kvm, addr); |
105 | pmd_t *pmd_table = pmd_offset(pud, 0); | 108 | pmd_free(NULL, pmd_table); |
106 | pud_clear(pud); | ||
107 | kvm_tlb_flush_vmid_ipa(kvm, addr); | ||
108 | pmd_free(NULL, pmd_table); | ||
109 | } | ||
110 | put_page(virt_to_page(pud)); | 109 | put_page(virt_to_page(pud)); |
111 | } | 110 | } |
112 | 111 | ||
113 | static void clear_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr) | 112 | static void clear_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr) |
114 | { | 113 | { |
115 | if (kvm_pmd_huge(*pmd)) { | 114 | pte_t *pte_table = pte_offset_kernel(pmd, 0); |
116 | pmd_clear(pmd); | 115 | VM_BUG_ON(kvm_pmd_huge(*pmd)); |
117 | kvm_tlb_flush_vmid_ipa(kvm, addr); | 116 | pmd_clear(pmd); |
118 | } else { | 117 | kvm_tlb_flush_vmid_ipa(kvm, addr); |
119 | pte_t *pte_table = pte_offset_kernel(pmd, 0); | 118 | pte_free_kernel(NULL, pte_table); |
120 | pmd_clear(pmd); | ||
121 | kvm_tlb_flush_vmid_ipa(kvm, addr); | ||
122 | pte_free_kernel(NULL, pte_table); | ||
123 | } | ||
124 | put_page(virt_to_page(pmd)); | 119 | put_page(virt_to_page(pmd)); |
125 | } | 120 | } |
126 | 121 | ||
127 | static void clear_pte_entry(struct kvm *kvm, pte_t *pte, phys_addr_t addr) | 122 | static void unmap_ptes(struct kvm *kvm, pmd_t *pmd, |
123 | phys_addr_t addr, phys_addr_t end) | ||
128 | { | 124 | { |
129 | if (pte_present(*pte)) { | 125 | phys_addr_t start_addr = addr; |
130 | kvm_set_pte(pte, __pte(0)); | 126 | pte_t *pte, *start_pte; |
131 | put_page(virt_to_page(pte)); | 127 | |
132 | kvm_tlb_flush_vmid_ipa(kvm, addr); | 128 | start_pte = pte = pte_offset_kernel(pmd, addr); |
133 | } | 129 | do { |
130 | if (!pte_none(*pte)) { | ||
131 | kvm_set_pte(pte, __pte(0)); | ||
132 | put_page(virt_to_page(pte)); | ||
133 | kvm_tlb_flush_vmid_ipa(kvm, addr); | ||
134 | } | ||
135 | } while (pte++, addr += PAGE_SIZE, addr != end); | ||
136 | |||
137 | if (kvm_pte_table_empty(start_pte)) | ||
138 | clear_pmd_entry(kvm, pmd, start_addr); | ||
134 | } | 139 | } |
135 | 140 | ||
136 | static void unmap_range(struct kvm *kvm, pgd_t *pgdp, | 141 | static void unmap_pmds(struct kvm *kvm, pud_t *pud, |
137 | unsigned long long start, u64 size) | 142 | phys_addr_t addr, phys_addr_t end) |
138 | { | 143 | { |
139 | pgd_t *pgd; | 144 | phys_addr_t next, start_addr = addr; |
140 | pud_t *pud; | 145 | pmd_t *pmd, *start_pmd; |
141 | pmd_t *pmd; | ||
142 | pte_t *pte; | ||
143 | unsigned long long addr = start, end = start + size; | ||
144 | u64 next; | ||
145 | |||
146 | while (addr < end) { | ||
147 | pgd = pgdp + pgd_index(addr); | ||
148 | pud = pud_offset(pgd, addr); | ||
149 | pte = NULL; | ||
150 | if (pud_none(*pud)) { | ||
151 | addr = kvm_pud_addr_end(addr, end); | ||
152 | continue; | ||
153 | } | ||
154 | 146 | ||
155 | if (pud_huge(*pud)) { | 147 | start_pmd = pmd = pmd_offset(pud, addr); |
156 | /* | 148 | do { |
157 | * If we are dealing with a huge pud, just clear it and | 149 | next = kvm_pmd_addr_end(addr, end); |
158 | * move on. | 150 | if (!pmd_none(*pmd)) { |
159 | */ | 151 | if (kvm_pmd_huge(*pmd)) { |
160 | clear_pud_entry(kvm, pud, addr); | 152 | pmd_clear(pmd); |
161 | addr = kvm_pud_addr_end(addr, end); | 153 | kvm_tlb_flush_vmid_ipa(kvm, addr); |
162 | continue; | 154 | put_page(virt_to_page(pmd)); |
155 | } else { | ||
156 | unmap_ptes(kvm, pmd, addr, next); | ||
157 | } | ||
163 | } | 158 | } |
159 | } while (pmd++, addr = next, addr != end); | ||
164 | 160 | ||
165 | pmd = pmd_offset(pud, addr); | 161 | if (kvm_pmd_table_empty(start_pmd)) |
166 | if (pmd_none(*pmd)) { | 162 | clear_pud_entry(kvm, pud, start_addr); |
167 | addr = kvm_pmd_addr_end(addr, end); | 163 | } |
168 | continue; | ||
169 | } | ||
170 | 164 | ||
171 | if (!kvm_pmd_huge(*pmd)) { | 165 | static void unmap_puds(struct kvm *kvm, pgd_t *pgd, |
172 | pte = pte_offset_kernel(pmd, addr); | 166 | phys_addr_t addr, phys_addr_t end) |
173 | clear_pte_entry(kvm, pte, addr); | 167 | { |
174 | next = addr + PAGE_SIZE; | 168 | phys_addr_t next, start_addr = addr; |
175 | } | 169 | pud_t *pud, *start_pud; |
176 | 170 | ||
177 | /* | 171 | start_pud = pud = pud_offset(pgd, addr); |
178 | * If the pmd entry is to be cleared, walk back up the ladder | 172 | do { |
179 | */ | 173 | next = kvm_pud_addr_end(addr, end); |
180 | if (kvm_pmd_huge(*pmd) || (pte && page_empty(pte))) { | 174 | if (!pud_none(*pud)) { |
181 | clear_pmd_entry(kvm, pmd, addr); | 175 | if (pud_huge(*pud)) { |
182 | next = kvm_pmd_addr_end(addr, end); | 176 | pud_clear(pud); |
183 | if (page_empty(pmd) && !page_empty(pud)) { | 177 | kvm_tlb_flush_vmid_ipa(kvm, addr); |
184 | clear_pud_entry(kvm, pud, addr); | 178 | put_page(virt_to_page(pud)); |
185 | next = kvm_pud_addr_end(addr, end); | 179 | } else { |
180 | unmap_pmds(kvm, pud, addr, next); | ||
186 | } | 181 | } |
187 | } | 182 | } |
183 | } while (pud++, addr = next, addr != end); | ||
188 | 184 | ||
189 | addr = next; | 185 | if (kvm_pud_table_empty(start_pud)) |
190 | } | 186 | clear_pgd_entry(kvm, pgd, start_addr); |
187 | } | ||
188 | |||
189 | |||
190 | static void unmap_range(struct kvm *kvm, pgd_t *pgdp, | ||
191 | phys_addr_t start, u64 size) | ||
192 | { | ||
193 | pgd_t *pgd; | ||
194 | phys_addr_t addr = start, end = start + size; | ||
195 | phys_addr_t next; | ||
196 | |||
197 | pgd = pgdp + pgd_index(addr); | ||
198 | do { | ||
199 | next = kvm_pgd_addr_end(addr, end); | ||
200 | unmap_puds(kvm, pgd, addr, next); | ||
201 | } while (pgd++, addr = next, addr != end); | ||
191 | } | 202 | } |
192 | 203 | ||
193 | static void stage2_flush_ptes(struct kvm *kvm, pmd_t *pmd, | 204 | static void stage2_flush_ptes(struct kvm *kvm, pmd_t *pmd, |
@@ -748,6 +759,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, | |||
748 | struct kvm_mmu_memory_cache *memcache = &vcpu->arch.mmu_page_cache; | 759 | struct kvm_mmu_memory_cache *memcache = &vcpu->arch.mmu_page_cache; |
749 | struct vm_area_struct *vma; | 760 | struct vm_area_struct *vma; |
750 | pfn_t pfn; | 761 | pfn_t pfn; |
762 | pgprot_t mem_type = PAGE_S2; | ||
751 | 763 | ||
752 | write_fault = kvm_is_write_fault(kvm_vcpu_get_hsr(vcpu)); | 764 | write_fault = kvm_is_write_fault(kvm_vcpu_get_hsr(vcpu)); |
753 | if (fault_status == FSC_PERM && !write_fault) { | 765 | if (fault_status == FSC_PERM && !write_fault) { |
@@ -798,6 +810,9 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, | |||
798 | if (is_error_pfn(pfn)) | 810 | if (is_error_pfn(pfn)) |
799 | return -EFAULT; | 811 | return -EFAULT; |
800 | 812 | ||
813 | if (kvm_is_mmio_pfn(pfn)) | ||
814 | mem_type = PAGE_S2_DEVICE; | ||
815 | |||
801 | spin_lock(&kvm->mmu_lock); | 816 | spin_lock(&kvm->mmu_lock); |
802 | if (mmu_notifier_retry(kvm, mmu_seq)) | 817 | if (mmu_notifier_retry(kvm, mmu_seq)) |
803 | goto out_unlock; | 818 | goto out_unlock; |
@@ -805,7 +820,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, | |||
805 | hugetlb = transparent_hugepage_adjust(&pfn, &fault_ipa); | 820 | hugetlb = transparent_hugepage_adjust(&pfn, &fault_ipa); |
806 | 821 | ||
807 | if (hugetlb) { | 822 | if (hugetlb) { |
808 | pmd_t new_pmd = pfn_pmd(pfn, PAGE_S2); | 823 | pmd_t new_pmd = pfn_pmd(pfn, mem_type); |
809 | new_pmd = pmd_mkhuge(new_pmd); | 824 | new_pmd = pmd_mkhuge(new_pmd); |
810 | if (writable) { | 825 | if (writable) { |
811 | kvm_set_s2pmd_writable(&new_pmd); | 826 | kvm_set_s2pmd_writable(&new_pmd); |
@@ -814,13 +829,14 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, | |||
814 | coherent_cache_guest_page(vcpu, hva & PMD_MASK, PMD_SIZE); | 829 | coherent_cache_guest_page(vcpu, hva & PMD_MASK, PMD_SIZE); |
815 | ret = stage2_set_pmd_huge(kvm, memcache, fault_ipa, &new_pmd); | 830 | ret = stage2_set_pmd_huge(kvm, memcache, fault_ipa, &new_pmd); |
816 | } else { | 831 | } else { |
817 | pte_t new_pte = pfn_pte(pfn, PAGE_S2); | 832 | pte_t new_pte = pfn_pte(pfn, mem_type); |
818 | if (writable) { | 833 | if (writable) { |
819 | kvm_set_s2pte_writable(&new_pte); | 834 | kvm_set_s2pte_writable(&new_pte); |
820 | kvm_set_pfn_dirty(pfn); | 835 | kvm_set_pfn_dirty(pfn); |
821 | } | 836 | } |
822 | coherent_cache_guest_page(vcpu, hva, PAGE_SIZE); | 837 | coherent_cache_guest_page(vcpu, hva, PAGE_SIZE); |
823 | ret = stage2_set_pte(kvm, memcache, fault_ipa, &new_pte, false); | 838 | ret = stage2_set_pte(kvm, memcache, fault_ipa, &new_pte, |
839 | mem_type == PAGE_S2_DEVICE); | ||
824 | } | 840 | } |
825 | 841 | ||
826 | 842 | ||
@@ -1100,3 +1116,49 @@ out: | |||
1100 | free_hyp_pgds(); | 1116 | free_hyp_pgds(); |
1101 | return err; | 1117 | return err; |
1102 | } | 1118 | } |
1119 | |||
1120 | void kvm_arch_commit_memory_region(struct kvm *kvm, | ||
1121 | struct kvm_userspace_memory_region *mem, | ||
1122 | const struct kvm_memory_slot *old, | ||
1123 | enum kvm_mr_change change) | ||
1124 | { | ||
1125 | gpa_t gpa = old->base_gfn << PAGE_SHIFT; | ||
1126 | phys_addr_t size = old->npages << PAGE_SHIFT; | ||
1127 | if (change == KVM_MR_DELETE || change == KVM_MR_MOVE) { | ||
1128 | spin_lock(&kvm->mmu_lock); | ||
1129 | unmap_stage2_range(kvm, gpa, size); | ||
1130 | spin_unlock(&kvm->mmu_lock); | ||
1131 | } | ||
1132 | } | ||
1133 | |||
1134 | int kvm_arch_prepare_memory_region(struct kvm *kvm, | ||
1135 | struct kvm_memory_slot *memslot, | ||
1136 | struct kvm_userspace_memory_region *mem, | ||
1137 | enum kvm_mr_change change) | ||
1138 | { | ||
1139 | return 0; | ||
1140 | } | ||
1141 | |||
1142 | void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *free, | ||
1143 | struct kvm_memory_slot *dont) | ||
1144 | { | ||
1145 | } | ||
1146 | |||
1147 | int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot, | ||
1148 | unsigned long npages) | ||
1149 | { | ||
1150 | return 0; | ||
1151 | } | ||
1152 | |||
1153 | void kvm_arch_memslots_updated(struct kvm *kvm) | ||
1154 | { | ||
1155 | } | ||
1156 | |||
1157 | void kvm_arch_flush_shadow_all(struct kvm *kvm) | ||
1158 | { | ||
1159 | } | ||
1160 | |||
1161 | void kvm_arch_flush_shadow_memslot(struct kvm *kvm, | ||
1162 | struct kvm_memory_slot *slot) | ||
1163 | { | ||
1164 | } | ||
diff --git a/arch/arm64/include/asm/debug-monitors.h b/arch/arm64/include/asm/debug-monitors.h index 6e9b5b36921c..7fb343779498 100644 --- a/arch/arm64/include/asm/debug-monitors.h +++ b/arch/arm64/include/asm/debug-monitors.h | |||
@@ -18,6 +18,15 @@ | |||
18 | 18 | ||
19 | #ifdef __KERNEL__ | 19 | #ifdef __KERNEL__ |
20 | 20 | ||
21 | /* Low-level stepping controls. */ | ||
22 | #define DBG_MDSCR_SS (1 << 0) | ||
23 | #define DBG_SPSR_SS (1 << 21) | ||
24 | |||
25 | /* MDSCR_EL1 enabling bits */ | ||
26 | #define DBG_MDSCR_KDE (1 << 13) | ||
27 | #define DBG_MDSCR_MDE (1 << 15) | ||
28 | #define DBG_MDSCR_MASK ~(DBG_MDSCR_KDE | DBG_MDSCR_MDE) | ||
29 | |||
21 | #define DBG_ESR_EVT(x) (((x) >> 27) & 0x7) | 30 | #define DBG_ESR_EVT(x) (((x) >> 27) & 0x7) |
22 | 31 | ||
23 | /* AArch64 */ | 32 | /* AArch64 */ |
@@ -73,11 +82,6 @@ | |||
73 | 82 | ||
74 | #define CACHE_FLUSH_IS_SAFE 1 | 83 | #define CACHE_FLUSH_IS_SAFE 1 |
75 | 84 | ||
76 | enum debug_el { | ||
77 | DBG_ACTIVE_EL0 = 0, | ||
78 | DBG_ACTIVE_EL1, | ||
79 | }; | ||
80 | |||
81 | /* AArch32 */ | 85 | /* AArch32 */ |
82 | #define DBG_ESR_EVT_BKPT 0x4 | 86 | #define DBG_ESR_EVT_BKPT 0x4 |
83 | #define DBG_ESR_EVT_VECC 0x5 | 87 | #define DBG_ESR_EVT_VECC 0x5 |
@@ -115,6 +119,11 @@ void unregister_break_hook(struct break_hook *hook); | |||
115 | 119 | ||
116 | u8 debug_monitors_arch(void); | 120 | u8 debug_monitors_arch(void); |
117 | 121 | ||
122 | enum debug_el { | ||
123 | DBG_ACTIVE_EL0 = 0, | ||
124 | DBG_ACTIVE_EL1, | ||
125 | }; | ||
126 | |||
118 | void enable_debug_monitors(enum debug_el el); | 127 | void enable_debug_monitors(enum debug_el el); |
119 | void disable_debug_monitors(enum debug_el el); | 128 | void disable_debug_monitors(enum debug_el el); |
120 | 129 | ||
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h index 3d6903006a8a..cc83520459ed 100644 --- a/arch/arm64/include/asm/kvm_arm.h +++ b/arch/arm64/include/asm/kvm_arm.h | |||
@@ -76,9 +76,10 @@ | |||
76 | */ | 76 | */ |
77 | #define HCR_GUEST_FLAGS (HCR_TSC | HCR_TSW | HCR_TWE | HCR_TWI | HCR_VM | \ | 77 | #define HCR_GUEST_FLAGS (HCR_TSC | HCR_TSW | HCR_TWE | HCR_TWI | HCR_VM | \ |
78 | HCR_TVM | HCR_BSU_IS | HCR_FB | HCR_TAC | \ | 78 | HCR_TVM | HCR_BSU_IS | HCR_FB | HCR_TAC | \ |
79 | HCR_AMO | HCR_IMO | HCR_FMO | \ | 79 | HCR_AMO | HCR_SWIO | HCR_TIDCP | HCR_RW) |
80 | HCR_SWIO | HCR_TIDCP | HCR_RW) | ||
81 | #define HCR_VIRT_EXCP_MASK (HCR_VA | HCR_VI | HCR_VF) | 80 | #define HCR_VIRT_EXCP_MASK (HCR_VA | HCR_VI | HCR_VF) |
81 | #define HCR_INT_OVERRIDE (HCR_FMO | HCR_IMO) | ||
82 | |||
82 | 83 | ||
83 | /* Hyp System Control Register (SCTLR_EL2) bits */ | 84 | /* Hyp System Control Register (SCTLR_EL2) bits */ |
84 | #define SCTLR_EL2_EE (1 << 25) | 85 | #define SCTLR_EL2_EE (1 << 25) |
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h index 9fcd54b1e16d..483842180f8f 100644 --- a/arch/arm64/include/asm/kvm_asm.h +++ b/arch/arm64/include/asm/kvm_asm.h | |||
@@ -18,6 +18,8 @@ | |||
18 | #ifndef __ARM_KVM_ASM_H__ | 18 | #ifndef __ARM_KVM_ASM_H__ |
19 | #define __ARM_KVM_ASM_H__ | 19 | #define __ARM_KVM_ASM_H__ |
20 | 20 | ||
21 | #include <asm/virt.h> | ||
22 | |||
21 | /* | 23 | /* |
22 | * 0 is reserved as an invalid value. | 24 | * 0 is reserved as an invalid value. |
23 | * Order *must* be kept in sync with the hyp switch code. | 25 | * Order *must* be kept in sync with the hyp switch code. |
@@ -43,14 +45,25 @@ | |||
43 | #define AMAIR_EL1 19 /* Aux Memory Attribute Indirection Register */ | 45 | #define AMAIR_EL1 19 /* Aux Memory Attribute Indirection Register */ |
44 | #define CNTKCTL_EL1 20 /* Timer Control Register (EL1) */ | 46 | #define CNTKCTL_EL1 20 /* Timer Control Register (EL1) */ |
45 | #define PAR_EL1 21 /* Physical Address Register */ | 47 | #define PAR_EL1 21 /* Physical Address Register */ |
48 | #define MDSCR_EL1 22 /* Monitor Debug System Control Register */ | ||
49 | #define DBGBCR0_EL1 23 /* Debug Breakpoint Control Registers (0-15) */ | ||
50 | #define DBGBCR15_EL1 38 | ||
51 | #define DBGBVR0_EL1 39 /* Debug Breakpoint Value Registers (0-15) */ | ||
52 | #define DBGBVR15_EL1 54 | ||
53 | #define DBGWCR0_EL1 55 /* Debug Watchpoint Control Registers (0-15) */ | ||
54 | #define DBGWCR15_EL1 70 | ||
55 | #define DBGWVR0_EL1 71 /* Debug Watchpoint Value Registers (0-15) */ | ||
56 | #define DBGWVR15_EL1 86 | ||
57 | #define MDCCINT_EL1 87 /* Monitor Debug Comms Channel Interrupt Enable Reg */ | ||
58 | |||
46 | /* 32bit specific registers. Keep them at the end of the range */ | 59 | /* 32bit specific registers. Keep them at the end of the range */ |
47 | #define DACR32_EL2 22 /* Domain Access Control Register */ | 60 | #define DACR32_EL2 88 /* Domain Access Control Register */ |
48 | #define IFSR32_EL2 23 /* Instruction Fault Status Register */ | 61 | #define IFSR32_EL2 89 /* Instruction Fault Status Register */ |
49 | #define FPEXC32_EL2 24 /* Floating-Point Exception Control Register */ | 62 | #define FPEXC32_EL2 90 /* Floating-Point Exception Control Register */ |
50 | #define DBGVCR32_EL2 25 /* Debug Vector Catch Register */ | 63 | #define DBGVCR32_EL2 91 /* Debug Vector Catch Register */ |
51 | #define TEECR32_EL1 26 /* ThumbEE Configuration Register */ | 64 | #define TEECR32_EL1 92 /* ThumbEE Configuration Register */ |
52 | #define TEEHBR32_EL1 27 /* ThumbEE Handler Base Register */ | 65 | #define TEEHBR32_EL1 93 /* ThumbEE Handler Base Register */ |
53 | #define NR_SYS_REGS 28 | 66 | #define NR_SYS_REGS 94 |
54 | 67 | ||
55 | /* 32bit mapping */ | 68 | /* 32bit mapping */ |
56 | #define c0_MPIDR (MPIDR_EL1 * 2) /* MultiProcessor ID Register */ | 69 | #define c0_MPIDR (MPIDR_EL1 * 2) /* MultiProcessor ID Register */ |
@@ -82,11 +95,23 @@ | |||
82 | #define c10_AMAIR0 (AMAIR_EL1 * 2) /* Aux Memory Attr Indirection Reg */ | 95 | #define c10_AMAIR0 (AMAIR_EL1 * 2) /* Aux Memory Attr Indirection Reg */ |
83 | #define c10_AMAIR1 (c10_AMAIR0 + 1)/* Aux Memory Attr Indirection Reg */ | 96 | #define c10_AMAIR1 (c10_AMAIR0 + 1)/* Aux Memory Attr Indirection Reg */ |
84 | #define c14_CNTKCTL (CNTKCTL_EL1 * 2) /* Timer Control Register (PL1) */ | 97 | #define c14_CNTKCTL (CNTKCTL_EL1 * 2) /* Timer Control Register (PL1) */ |
85 | #define NR_CP15_REGS (NR_SYS_REGS * 2) | 98 | |
99 | #define cp14_DBGDSCRext (MDSCR_EL1 * 2) | ||
100 | #define cp14_DBGBCR0 (DBGBCR0_EL1 * 2) | ||
101 | #define cp14_DBGBVR0 (DBGBVR0_EL1 * 2) | ||
102 | #define cp14_DBGBXVR0 (cp14_DBGBVR0 + 1) | ||
103 | #define cp14_DBGWCR0 (DBGWCR0_EL1 * 2) | ||
104 | #define cp14_DBGWVR0 (DBGWVR0_EL1 * 2) | ||
105 | #define cp14_DBGDCCINT (MDCCINT_EL1 * 2) | ||
106 | |||
107 | #define NR_COPRO_REGS (NR_SYS_REGS * 2) | ||
86 | 108 | ||
87 | #define ARM_EXCEPTION_IRQ 0 | 109 | #define ARM_EXCEPTION_IRQ 0 |
88 | #define ARM_EXCEPTION_TRAP 1 | 110 | #define ARM_EXCEPTION_TRAP 1 |
89 | 111 | ||
112 | #define KVM_ARM64_DEBUG_DIRTY_SHIFT 0 | ||
113 | #define KVM_ARM64_DEBUG_DIRTY (1 << KVM_ARM64_DEBUG_DIRTY_SHIFT) | ||
114 | |||
90 | #ifndef __ASSEMBLY__ | 115 | #ifndef __ASSEMBLY__ |
91 | struct kvm; | 116 | struct kvm; |
92 | struct kvm_vcpu; | 117 | struct kvm_vcpu; |
@@ -96,13 +121,21 @@ extern char __kvm_hyp_init_end[]; | |||
96 | 121 | ||
97 | extern char __kvm_hyp_vector[]; | 122 | extern char __kvm_hyp_vector[]; |
98 | 123 | ||
99 | extern char __kvm_hyp_code_start[]; | 124 | #define __kvm_hyp_code_start __hyp_text_start |
100 | extern char __kvm_hyp_code_end[]; | 125 | #define __kvm_hyp_code_end __hyp_text_end |
101 | 126 | ||
102 | extern void __kvm_flush_vm_context(void); | 127 | extern void __kvm_flush_vm_context(void); |
103 | extern void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa); | 128 | extern void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa); |
104 | 129 | ||
105 | extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu); | 130 | extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu); |
131 | |||
132 | extern u64 __vgic_v3_get_ich_vtr_el2(void); | ||
133 | |||
134 | extern char __save_vgic_v2_state[]; | ||
135 | extern char __restore_vgic_v2_state[]; | ||
136 | extern char __save_vgic_v3_state[]; | ||
137 | extern char __restore_vgic_v3_state[]; | ||
138 | |||
106 | #endif | 139 | #endif |
107 | 140 | ||
108 | #endif /* __ARM_KVM_ASM_H__ */ | 141 | #endif /* __ARM_KVM_ASM_H__ */ |
diff --git a/arch/arm64/include/asm/kvm_coproc.h b/arch/arm64/include/asm/kvm_coproc.h index 9a59301cd014..0b52377a6c11 100644 --- a/arch/arm64/include/asm/kvm_coproc.h +++ b/arch/arm64/include/asm/kvm_coproc.h | |||
@@ -39,7 +39,8 @@ void kvm_register_target_sys_reg_table(unsigned int target, | |||
39 | struct kvm_sys_reg_target_table *table); | 39 | struct kvm_sys_reg_target_table *table); |
40 | 40 | ||
41 | int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run); | 41 | int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run); |
42 | int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run); | 42 | int kvm_handle_cp14_32(struct kvm_vcpu *vcpu, struct kvm_run *run); |
43 | int kvm_handle_cp14_64(struct kvm_vcpu *vcpu, struct kvm_run *run); | ||
43 | int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run); | 44 | int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run); |
44 | int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run); | 45 | int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run); |
45 | int kvm_handle_sys_reg(struct kvm_vcpu *vcpu, struct kvm_run *run); | 46 | int kvm_handle_sys_reg(struct kvm_vcpu *vcpu, struct kvm_run *run); |
diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h index dd8ecfc3f995..fdc3e21abd8d 100644 --- a/arch/arm64/include/asm/kvm_emulate.h +++ b/arch/arm64/include/asm/kvm_emulate.h | |||
@@ -213,6 +213,17 @@ static inline unsigned long vcpu_data_guest_to_host(struct kvm_vcpu *vcpu, | |||
213 | default: | 213 | default: |
214 | return be64_to_cpu(data); | 214 | return be64_to_cpu(data); |
215 | } | 215 | } |
216 | } else { | ||
217 | switch (len) { | ||
218 | case 1: | ||
219 | return data & 0xff; | ||
220 | case 2: | ||
221 | return le16_to_cpu(data & 0xffff); | ||
222 | case 4: | ||
223 | return le32_to_cpu(data & 0xffffffff); | ||
224 | default: | ||
225 | return le64_to_cpu(data); | ||
226 | } | ||
216 | } | 227 | } |
217 | 228 | ||
218 | return data; /* Leave LE untouched */ | 229 | return data; /* Leave LE untouched */ |
@@ -233,6 +244,17 @@ static inline unsigned long vcpu_data_host_to_guest(struct kvm_vcpu *vcpu, | |||
233 | default: | 244 | default: |
234 | return cpu_to_be64(data); | 245 | return cpu_to_be64(data); |
235 | } | 246 | } |
247 | } else { | ||
248 | switch (len) { | ||
249 | case 1: | ||
250 | return data & 0xff; | ||
251 | case 2: | ||
252 | return cpu_to_le16(data & 0xffff); | ||
253 | case 4: | ||
254 | return cpu_to_le32(data & 0xffffffff); | ||
255 | default: | ||
256 | return cpu_to_le64(data); | ||
257 | } | ||
236 | } | 258 | } |
237 | 259 | ||
238 | return data; /* Leave LE untouched */ | 260 | return data; /* Leave LE untouched */ |
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 92242ce06309..e10c45a578e3 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h | |||
@@ -86,7 +86,7 @@ struct kvm_cpu_context { | |||
86 | struct kvm_regs gp_regs; | 86 | struct kvm_regs gp_regs; |
87 | union { | 87 | union { |
88 | u64 sys_regs[NR_SYS_REGS]; | 88 | u64 sys_regs[NR_SYS_REGS]; |
89 | u32 cp15[NR_CP15_REGS]; | 89 | u32 copro[NR_COPRO_REGS]; |
90 | }; | 90 | }; |
91 | }; | 91 | }; |
92 | 92 | ||
@@ -101,6 +101,9 @@ struct kvm_vcpu_arch { | |||
101 | /* Exception Information */ | 101 | /* Exception Information */ |
102 | struct kvm_vcpu_fault_info fault; | 102 | struct kvm_vcpu_fault_info fault; |
103 | 103 | ||
104 | /* Debug state */ | ||
105 | u64 debug_flags; | ||
106 | |||
104 | /* Pointer to host CPU context */ | 107 | /* Pointer to host CPU context */ |
105 | kvm_cpu_context_t *host_cpu_context; | 108 | kvm_cpu_context_t *host_cpu_context; |
106 | 109 | ||
@@ -138,7 +141,20 @@ struct kvm_vcpu_arch { | |||
138 | 141 | ||
139 | #define vcpu_gp_regs(v) (&(v)->arch.ctxt.gp_regs) | 142 | #define vcpu_gp_regs(v) (&(v)->arch.ctxt.gp_regs) |
140 | #define vcpu_sys_reg(v,r) ((v)->arch.ctxt.sys_regs[(r)]) | 143 | #define vcpu_sys_reg(v,r) ((v)->arch.ctxt.sys_regs[(r)]) |
141 | #define vcpu_cp15(v,r) ((v)->arch.ctxt.cp15[(r)]) | 144 | /* |
145 | * CP14 and CP15 live in the same array, as they are backed by the | ||
146 | * same system registers. | ||
147 | */ | ||
148 | #define vcpu_cp14(v,r) ((v)->arch.ctxt.copro[(r)]) | ||
149 | #define vcpu_cp15(v,r) ((v)->arch.ctxt.copro[(r)]) | ||
150 | |||
151 | #ifdef CONFIG_CPU_BIG_ENDIAN | ||
152 | #define vcpu_cp15_64_high(v,r) vcpu_cp15((v),(r)) | ||
153 | #define vcpu_cp15_64_low(v,r) vcpu_cp15((v),(r) + 1) | ||
154 | #else | ||
155 | #define vcpu_cp15_64_high(v,r) vcpu_cp15((v),(r) + 1) | ||
156 | #define vcpu_cp15_64_low(v,r) vcpu_cp15((v),(r)) | ||
157 | #endif | ||
142 | 158 | ||
143 | struct kvm_vm_stat { | 159 | struct kvm_vm_stat { |
144 | u32 remote_tlb_flush; | 160 | u32 remote_tlb_flush; |
@@ -200,4 +216,32 @@ static inline void __cpu_init_hyp_mode(phys_addr_t boot_pgd_ptr, | |||
200 | hyp_stack_ptr, vector_ptr); | 216 | hyp_stack_ptr, vector_ptr); |
201 | } | 217 | } |
202 | 218 | ||
219 | struct vgic_sr_vectors { | ||
220 | void *save_vgic; | ||
221 | void *restore_vgic; | ||
222 | }; | ||
223 | |||
224 | static inline void vgic_arch_setup(const struct vgic_params *vgic) | ||
225 | { | ||
226 | extern struct vgic_sr_vectors __vgic_sr_vectors; | ||
227 | |||
228 | switch(vgic->type) | ||
229 | { | ||
230 | case VGIC_V2: | ||
231 | __vgic_sr_vectors.save_vgic = __save_vgic_v2_state; | ||
232 | __vgic_sr_vectors.restore_vgic = __restore_vgic_v2_state; | ||
233 | break; | ||
234 | |||
235 | #ifdef CONFIG_ARM_GIC_V3 | ||
236 | case VGIC_V3: | ||
237 | __vgic_sr_vectors.save_vgic = __save_vgic_v3_state; | ||
238 | __vgic_sr_vectors.restore_vgic = __restore_vgic_v3_state; | ||
239 | break; | ||
240 | #endif | ||
241 | |||
242 | default: | ||
243 | BUG(); | ||
244 | } | ||
245 | } | ||
246 | |||
203 | #endif /* __ARM64_KVM_HOST_H__ */ | 247 | #endif /* __ARM64_KVM_HOST_H__ */ |
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h index 7d29847a893b..8e138c7c53ac 100644 --- a/arch/arm64/include/asm/kvm_mmu.h +++ b/arch/arm64/include/asm/kvm_mmu.h | |||
@@ -125,6 +125,21 @@ static inline void kvm_set_s2pmd_writable(pmd_t *pmd) | |||
125 | #define kvm_pud_addr_end(addr, end) pud_addr_end(addr, end) | 125 | #define kvm_pud_addr_end(addr, end) pud_addr_end(addr, end) |
126 | #define kvm_pmd_addr_end(addr, end) pmd_addr_end(addr, end) | 126 | #define kvm_pmd_addr_end(addr, end) pmd_addr_end(addr, end) |
127 | 127 | ||
128 | static inline bool kvm_page_empty(void *ptr) | ||
129 | { | ||
130 | struct page *ptr_page = virt_to_page(ptr); | ||
131 | return page_count(ptr_page) == 1; | ||
132 | } | ||
133 | |||
134 | #define kvm_pte_table_empty(ptep) kvm_page_empty(ptep) | ||
135 | #ifndef CONFIG_ARM64_64K_PAGES | ||
136 | #define kvm_pmd_table_empty(pmdp) kvm_page_empty(pmdp) | ||
137 | #else | ||
138 | #define kvm_pmd_table_empty(pmdp) (0) | ||
139 | #endif | ||
140 | #define kvm_pud_table_empty(pudp) (0) | ||
141 | |||
142 | |||
128 | struct kvm; | 143 | struct kvm; |
129 | 144 | ||
130 | #define kvm_flush_dcache_to_poc(a,l) __flush_dcache_area((a), (l)) | 145 | #define kvm_flush_dcache_to_poc(a,l) __flush_dcache_area((a), (l)) |
diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h index 215ad4649dd7..7a5df5252dd7 100644 --- a/arch/arm64/include/asm/virt.h +++ b/arch/arm64/include/asm/virt.h | |||
@@ -50,6 +50,10 @@ static inline bool is_hyp_mode_mismatched(void) | |||
50 | return __boot_cpu_mode[0] != __boot_cpu_mode[1]; | 50 | return __boot_cpu_mode[0] != __boot_cpu_mode[1]; |
51 | } | 51 | } |
52 | 52 | ||
53 | /* The section containing the hypervisor text */ | ||
54 | extern char __hyp_text_start[]; | ||
55 | extern char __hyp_text_end[]; | ||
56 | |||
53 | #endif /* __ASSEMBLY__ */ | 57 | #endif /* __ASSEMBLY__ */ |
54 | 58 | ||
55 | #endif /* ! __ASM__VIRT_H */ | 59 | #endif /* ! __ASM__VIRT_H */ |
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c index 646f888387cd..9a9fce090d58 100644 --- a/arch/arm64/kernel/asm-offsets.c +++ b/arch/arm64/kernel/asm-offsets.c | |||
@@ -120,6 +120,7 @@ int main(void) | |||
120 | DEFINE(VCPU_ESR_EL2, offsetof(struct kvm_vcpu, arch.fault.esr_el2)); | 120 | DEFINE(VCPU_ESR_EL2, offsetof(struct kvm_vcpu, arch.fault.esr_el2)); |
121 | DEFINE(VCPU_FAR_EL2, offsetof(struct kvm_vcpu, arch.fault.far_el2)); | 121 | DEFINE(VCPU_FAR_EL2, offsetof(struct kvm_vcpu, arch.fault.far_el2)); |
122 | DEFINE(VCPU_HPFAR_EL2, offsetof(struct kvm_vcpu, arch.fault.hpfar_el2)); | 122 | DEFINE(VCPU_HPFAR_EL2, offsetof(struct kvm_vcpu, arch.fault.hpfar_el2)); |
123 | DEFINE(VCPU_DEBUG_FLAGS, offsetof(struct kvm_vcpu, arch.debug_flags)); | ||
123 | DEFINE(VCPU_HCR_EL2, offsetof(struct kvm_vcpu, arch.hcr_el2)); | 124 | DEFINE(VCPU_HCR_EL2, offsetof(struct kvm_vcpu, arch.hcr_el2)); |
124 | DEFINE(VCPU_IRQ_LINES, offsetof(struct kvm_vcpu, arch.irq_lines)); | 125 | DEFINE(VCPU_IRQ_LINES, offsetof(struct kvm_vcpu, arch.irq_lines)); |
125 | DEFINE(VCPU_HOST_CONTEXT, offsetof(struct kvm_vcpu, arch.host_cpu_context)); | 126 | DEFINE(VCPU_HOST_CONTEXT, offsetof(struct kvm_vcpu, arch.host_cpu_context)); |
@@ -129,13 +130,24 @@ int main(void) | |||
129 | DEFINE(KVM_TIMER_ENABLED, offsetof(struct kvm, arch.timer.enabled)); | 130 | DEFINE(KVM_TIMER_ENABLED, offsetof(struct kvm, arch.timer.enabled)); |
130 | DEFINE(VCPU_KVM, offsetof(struct kvm_vcpu, kvm)); | 131 | DEFINE(VCPU_KVM, offsetof(struct kvm_vcpu, kvm)); |
131 | DEFINE(VCPU_VGIC_CPU, offsetof(struct kvm_vcpu, arch.vgic_cpu)); | 132 | DEFINE(VCPU_VGIC_CPU, offsetof(struct kvm_vcpu, arch.vgic_cpu)); |
132 | DEFINE(VGIC_CPU_HCR, offsetof(struct vgic_cpu, vgic_hcr)); | 133 | DEFINE(VGIC_SAVE_FN, offsetof(struct vgic_sr_vectors, save_vgic)); |
133 | DEFINE(VGIC_CPU_VMCR, offsetof(struct vgic_cpu, vgic_vmcr)); | 134 | DEFINE(VGIC_RESTORE_FN, offsetof(struct vgic_sr_vectors, restore_vgic)); |
134 | DEFINE(VGIC_CPU_MISR, offsetof(struct vgic_cpu, vgic_misr)); | 135 | DEFINE(VGIC_SR_VECTOR_SZ, sizeof(struct vgic_sr_vectors)); |
135 | DEFINE(VGIC_CPU_EISR, offsetof(struct vgic_cpu, vgic_eisr)); | 136 | DEFINE(VGIC_V2_CPU_HCR, offsetof(struct vgic_cpu, vgic_v2.vgic_hcr)); |
136 | DEFINE(VGIC_CPU_ELRSR, offsetof(struct vgic_cpu, vgic_elrsr)); | 137 | DEFINE(VGIC_V2_CPU_VMCR, offsetof(struct vgic_cpu, vgic_v2.vgic_vmcr)); |
137 | DEFINE(VGIC_CPU_APR, offsetof(struct vgic_cpu, vgic_apr)); | 138 | DEFINE(VGIC_V2_CPU_MISR, offsetof(struct vgic_cpu, vgic_v2.vgic_misr)); |
138 | DEFINE(VGIC_CPU_LR, offsetof(struct vgic_cpu, vgic_lr)); | 139 | DEFINE(VGIC_V2_CPU_EISR, offsetof(struct vgic_cpu, vgic_v2.vgic_eisr)); |
140 | DEFINE(VGIC_V2_CPU_ELRSR, offsetof(struct vgic_cpu, vgic_v2.vgic_elrsr)); | ||
141 | DEFINE(VGIC_V2_CPU_APR, offsetof(struct vgic_cpu, vgic_v2.vgic_apr)); | ||
142 | DEFINE(VGIC_V2_CPU_LR, offsetof(struct vgic_cpu, vgic_v2.vgic_lr)); | ||
143 | DEFINE(VGIC_V3_CPU_HCR, offsetof(struct vgic_cpu, vgic_v3.vgic_hcr)); | ||
144 | DEFINE(VGIC_V3_CPU_VMCR, offsetof(struct vgic_cpu, vgic_v3.vgic_vmcr)); | ||
145 | DEFINE(VGIC_V3_CPU_MISR, offsetof(struct vgic_cpu, vgic_v3.vgic_misr)); | ||
146 | DEFINE(VGIC_V3_CPU_EISR, offsetof(struct vgic_cpu, vgic_v3.vgic_eisr)); | ||
147 | DEFINE(VGIC_V3_CPU_ELRSR, offsetof(struct vgic_cpu, vgic_v3.vgic_elrsr)); | ||
148 | DEFINE(VGIC_V3_CPU_AP0R, offsetof(struct vgic_cpu, vgic_v3.vgic_ap0r)); | ||
149 | DEFINE(VGIC_V3_CPU_AP1R, offsetof(struct vgic_cpu, vgic_v3.vgic_ap1r)); | ||
150 | DEFINE(VGIC_V3_CPU_LR, offsetof(struct vgic_cpu, vgic_v3.vgic_lr)); | ||
139 | DEFINE(VGIC_CPU_NR_LR, offsetof(struct vgic_cpu, nr_lr)); | 151 | DEFINE(VGIC_CPU_NR_LR, offsetof(struct vgic_cpu, nr_lr)); |
140 | DEFINE(KVM_VTTBR, offsetof(struct kvm, arch.vttbr)); | 152 | DEFINE(KVM_VTTBR, offsetof(struct kvm, arch.vttbr)); |
141 | DEFINE(KVM_VGIC_VCTRL, offsetof(struct kvm, arch.vgic.vctrl_base)); | 153 | DEFINE(KVM_VGIC_VCTRL, offsetof(struct kvm, arch.vgic.vctrl_base)); |
diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c index fe5b94078d82..b056369fd47d 100644 --- a/arch/arm64/kernel/debug-monitors.c +++ b/arch/arm64/kernel/debug-monitors.c | |||
@@ -30,15 +30,6 @@ | |||
30 | #include <asm/cputype.h> | 30 | #include <asm/cputype.h> |
31 | #include <asm/system_misc.h> | 31 | #include <asm/system_misc.h> |
32 | 32 | ||
33 | /* Low-level stepping controls. */ | ||
34 | #define DBG_MDSCR_SS (1 << 0) | ||
35 | #define DBG_SPSR_SS (1 << 21) | ||
36 | |||
37 | /* MDSCR_EL1 enabling bits */ | ||
38 | #define DBG_MDSCR_KDE (1 << 13) | ||
39 | #define DBG_MDSCR_MDE (1 << 15) | ||
40 | #define DBG_MDSCR_MASK ~(DBG_MDSCR_KDE | DBG_MDSCR_MDE) | ||
41 | |||
42 | /* Determine debug architecture. */ | 33 | /* Determine debug architecture. */ |
43 | u8 debug_monitors_arch(void) | 34 | u8 debug_monitors_arch(void) |
44 | { | 35 | { |
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile index 72a9fd583ad3..32a096174b94 100644 --- a/arch/arm64/kvm/Makefile +++ b/arch/arm64/kvm/Makefile | |||
@@ -20,4 +20,8 @@ kvm-$(CONFIG_KVM_ARM_HOST) += hyp.o hyp-init.o handle_exit.o | |||
20 | kvm-$(CONFIG_KVM_ARM_HOST) += guest.o reset.o sys_regs.o sys_regs_generic_v8.o | 20 | kvm-$(CONFIG_KVM_ARM_HOST) += guest.o reset.o sys_regs.o sys_regs_generic_v8.o |
21 | 21 | ||
22 | kvm-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic.o | 22 | kvm-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic.o |
23 | kvm-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic-v2.o | ||
24 | kvm-$(CONFIG_KVM_ARM_VGIC) += vgic-v2-switch.o | ||
25 | kvm-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic-v3.o | ||
26 | kvm-$(CONFIG_KVM_ARM_VGIC) += vgic-v3-switch.o | ||
23 | kvm-$(CONFIG_KVM_ARM_TIMER) += $(KVM)/arm/arch_timer.o | 27 | kvm-$(CONFIG_KVM_ARM_TIMER) += $(KVM)/arm/arch_timer.o |
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c index 60b5c31f3c10..8d1ec2887a26 100644 --- a/arch/arm64/kvm/guest.c +++ b/arch/arm64/kvm/guest.c | |||
@@ -136,13 +136,67 @@ static unsigned long num_core_regs(void) | |||
136 | } | 136 | } |
137 | 137 | ||
138 | /** | 138 | /** |
139 | * ARM64 versions of the TIMER registers, always available on arm64 | ||
140 | */ | ||
141 | |||
142 | #define NUM_TIMER_REGS 3 | ||
143 | |||
144 | static bool is_timer_reg(u64 index) | ||
145 | { | ||
146 | switch (index) { | ||
147 | case KVM_REG_ARM_TIMER_CTL: | ||
148 | case KVM_REG_ARM_TIMER_CNT: | ||
149 | case KVM_REG_ARM_TIMER_CVAL: | ||
150 | return true; | ||
151 | } | ||
152 | return false; | ||
153 | } | ||
154 | |||
155 | static int copy_timer_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) | ||
156 | { | ||
157 | if (put_user(KVM_REG_ARM_TIMER_CTL, uindices)) | ||
158 | return -EFAULT; | ||
159 | uindices++; | ||
160 | if (put_user(KVM_REG_ARM_TIMER_CNT, uindices)) | ||
161 | return -EFAULT; | ||
162 | uindices++; | ||
163 | if (put_user(KVM_REG_ARM_TIMER_CVAL, uindices)) | ||
164 | return -EFAULT; | ||
165 | |||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | static int set_timer_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) | ||
170 | { | ||
171 | void __user *uaddr = (void __user *)(long)reg->addr; | ||
172 | u64 val; | ||
173 | int ret; | ||
174 | |||
175 | ret = copy_from_user(&val, uaddr, KVM_REG_SIZE(reg->id)); | ||
176 | if (ret != 0) | ||
177 | return ret; | ||
178 | |||
179 | return kvm_arm_timer_set_reg(vcpu, reg->id, val); | ||
180 | } | ||
181 | |||
182 | static int get_timer_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) | ||
183 | { | ||
184 | void __user *uaddr = (void __user *)(long)reg->addr; | ||
185 | u64 val; | ||
186 | |||
187 | val = kvm_arm_timer_get_reg(vcpu, reg->id); | ||
188 | return copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id)); | ||
189 | } | ||
190 | |||
191 | /** | ||
139 | * kvm_arm_num_regs - how many registers do we present via KVM_GET_ONE_REG | 192 | * kvm_arm_num_regs - how many registers do we present via KVM_GET_ONE_REG |
140 | * | 193 | * |
141 | * This is for all registers. | 194 | * This is for all registers. |
142 | */ | 195 | */ |
143 | unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu) | 196 | unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu) |
144 | { | 197 | { |
145 | return num_core_regs() + kvm_arm_num_sys_reg_descs(vcpu); | 198 | return num_core_regs() + kvm_arm_num_sys_reg_descs(vcpu) |
199 | + NUM_TIMER_REGS; | ||
146 | } | 200 | } |
147 | 201 | ||
148 | /** | 202 | /** |
@@ -154,6 +208,7 @@ int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) | |||
154 | { | 208 | { |
155 | unsigned int i; | 209 | unsigned int i; |
156 | const u64 core_reg = KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE; | 210 | const u64 core_reg = KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE; |
211 | int ret; | ||
157 | 212 | ||
158 | for (i = 0; i < sizeof(struct kvm_regs) / sizeof(__u32); i++) { | 213 | for (i = 0; i < sizeof(struct kvm_regs) / sizeof(__u32); i++) { |
159 | if (put_user(core_reg | i, uindices)) | 214 | if (put_user(core_reg | i, uindices)) |
@@ -161,6 +216,11 @@ int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) | |||
161 | uindices++; | 216 | uindices++; |
162 | } | 217 | } |
163 | 218 | ||
219 | ret = copy_timer_indices(vcpu, uindices); | ||
220 | if (ret) | ||
221 | return ret; | ||
222 | uindices += NUM_TIMER_REGS; | ||
223 | |||
164 | return kvm_arm_copy_sys_reg_indices(vcpu, uindices); | 224 | return kvm_arm_copy_sys_reg_indices(vcpu, uindices); |
165 | } | 225 | } |
166 | 226 | ||
@@ -174,6 +234,9 @@ int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) | |||
174 | if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE) | 234 | if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE) |
175 | return get_core_reg(vcpu, reg); | 235 | return get_core_reg(vcpu, reg); |
176 | 236 | ||
237 | if (is_timer_reg(reg->id)) | ||
238 | return get_timer_reg(vcpu, reg); | ||
239 | |||
177 | return kvm_arm_sys_reg_get_reg(vcpu, reg); | 240 | return kvm_arm_sys_reg_get_reg(vcpu, reg); |
178 | } | 241 | } |
179 | 242 | ||
@@ -187,6 +250,9 @@ int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) | |||
187 | if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE) | 250 | if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE) |
188 | return set_core_reg(vcpu, reg); | 251 | return set_core_reg(vcpu, reg); |
189 | 252 | ||
253 | if (is_timer_reg(reg->id)) | ||
254 | return set_timer_reg(vcpu, reg); | ||
255 | |||
190 | return kvm_arm_sys_reg_set_reg(vcpu, reg); | 256 | return kvm_arm_sys_reg_set_reg(vcpu, reg); |
191 | } | 257 | } |
192 | 258 | ||
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c index 182415e1a952..e28be510380c 100644 --- a/arch/arm64/kvm/handle_exit.c +++ b/arch/arm64/kvm/handle_exit.c | |||
@@ -73,9 +73,9 @@ static exit_handle_fn arm_exit_handlers[] = { | |||
73 | [ESR_EL2_EC_WFI] = kvm_handle_wfx, | 73 | [ESR_EL2_EC_WFI] = kvm_handle_wfx, |
74 | [ESR_EL2_EC_CP15_32] = kvm_handle_cp15_32, | 74 | [ESR_EL2_EC_CP15_32] = kvm_handle_cp15_32, |
75 | [ESR_EL2_EC_CP15_64] = kvm_handle_cp15_64, | 75 | [ESR_EL2_EC_CP15_64] = kvm_handle_cp15_64, |
76 | [ESR_EL2_EC_CP14_MR] = kvm_handle_cp14_access, | 76 | [ESR_EL2_EC_CP14_MR] = kvm_handle_cp14_32, |
77 | [ESR_EL2_EC_CP14_LS] = kvm_handle_cp14_load_store, | 77 | [ESR_EL2_EC_CP14_LS] = kvm_handle_cp14_load_store, |
78 | [ESR_EL2_EC_CP14_64] = kvm_handle_cp14_access, | 78 | [ESR_EL2_EC_CP14_64] = kvm_handle_cp14_64, |
79 | [ESR_EL2_EC_HVC32] = handle_hvc, | 79 | [ESR_EL2_EC_HVC32] = handle_hvc, |
80 | [ESR_EL2_EC_SMC32] = handle_smc, | 80 | [ESR_EL2_EC_SMC32] = handle_smc, |
81 | [ESR_EL2_EC_HVC64] = handle_hvc, | 81 | [ESR_EL2_EC_HVC64] = handle_hvc, |
diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S index b0d1512acf08..b72aa9f9215c 100644 --- a/arch/arm64/kvm/hyp.S +++ b/arch/arm64/kvm/hyp.S | |||
@@ -16,11 +16,11 @@ | |||
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/linkage.h> | 18 | #include <linux/linkage.h> |
19 | #include <linux/irqchip/arm-gic.h> | ||
20 | 19 | ||
21 | #include <asm/assembler.h> | 20 | #include <asm/assembler.h> |
22 | #include <asm/memory.h> | 21 | #include <asm/memory.h> |
23 | #include <asm/asm-offsets.h> | 22 | #include <asm/asm-offsets.h> |
23 | #include <asm/debug-monitors.h> | ||
24 | #include <asm/fpsimdmacros.h> | 24 | #include <asm/fpsimdmacros.h> |
25 | #include <asm/kvm.h> | 25 | #include <asm/kvm.h> |
26 | #include <asm/kvm_asm.h> | 26 | #include <asm/kvm_asm.h> |
@@ -36,9 +36,6 @@ | |||
36 | .pushsection .hyp.text, "ax" | 36 | .pushsection .hyp.text, "ax" |
37 | .align PAGE_SHIFT | 37 | .align PAGE_SHIFT |
38 | 38 | ||
39 | __kvm_hyp_code_start: | ||
40 | .globl __kvm_hyp_code_start | ||
41 | |||
42 | .macro save_common_regs | 39 | .macro save_common_regs |
43 | // x2: base address for cpu context | 40 | // x2: base address for cpu context |
44 | // x3: tmp register | 41 | // x3: tmp register |
@@ -215,6 +212,7 @@ __kvm_hyp_code_start: | |||
215 | mrs x22, amair_el1 | 212 | mrs x22, amair_el1 |
216 | mrs x23, cntkctl_el1 | 213 | mrs x23, cntkctl_el1 |
217 | mrs x24, par_el1 | 214 | mrs x24, par_el1 |
215 | mrs x25, mdscr_el1 | ||
218 | 216 | ||
219 | stp x4, x5, [x3] | 217 | stp x4, x5, [x3] |
220 | stp x6, x7, [x3, #16] | 218 | stp x6, x7, [x3, #16] |
@@ -226,7 +224,202 @@ __kvm_hyp_code_start: | |||
226 | stp x18, x19, [x3, #112] | 224 | stp x18, x19, [x3, #112] |
227 | stp x20, x21, [x3, #128] | 225 | stp x20, x21, [x3, #128] |
228 | stp x22, x23, [x3, #144] | 226 | stp x22, x23, [x3, #144] |
229 | str x24, [x3, #160] | 227 | stp x24, x25, [x3, #160] |
228 | .endm | ||
229 | |||
230 | .macro save_debug | ||
231 | // x2: base address for cpu context | ||
232 | // x3: tmp register | ||
233 | |||
234 | mrs x26, id_aa64dfr0_el1 | ||
235 | ubfx x24, x26, #12, #4 // Extract BRPs | ||
236 | ubfx x25, x26, #20, #4 // Extract WRPs | ||
237 | mov w26, #15 | ||
238 | sub w24, w26, w24 // How many BPs to skip | ||
239 | sub w25, w26, w25 // How many WPs to skip | ||
240 | |||
241 | add x3, x2, #CPU_SYSREG_OFFSET(DBGBCR0_EL1) | ||
242 | |||
243 | adr x26, 1f | ||
244 | add x26, x26, x24, lsl #2 | ||
245 | br x26 | ||
246 | 1: | ||
247 | mrs x20, dbgbcr15_el1 | ||
248 | mrs x19, dbgbcr14_el1 | ||
249 | mrs x18, dbgbcr13_el1 | ||
250 | mrs x17, dbgbcr12_el1 | ||
251 | mrs x16, dbgbcr11_el1 | ||
252 | mrs x15, dbgbcr10_el1 | ||
253 | mrs x14, dbgbcr9_el1 | ||
254 | mrs x13, dbgbcr8_el1 | ||
255 | mrs x12, dbgbcr7_el1 | ||
256 | mrs x11, dbgbcr6_el1 | ||
257 | mrs x10, dbgbcr5_el1 | ||
258 | mrs x9, dbgbcr4_el1 | ||
259 | mrs x8, dbgbcr3_el1 | ||
260 | mrs x7, dbgbcr2_el1 | ||
261 | mrs x6, dbgbcr1_el1 | ||
262 | mrs x5, dbgbcr0_el1 | ||
263 | |||
264 | adr x26, 1f | ||
265 | add x26, x26, x24, lsl #2 | ||
266 | br x26 | ||
267 | |||
268 | 1: | ||
269 | str x20, [x3, #(15 * 8)] | ||
270 | str x19, [x3, #(14 * 8)] | ||
271 | str x18, [x3, #(13 * 8)] | ||
272 | str x17, [x3, #(12 * 8)] | ||
273 | str x16, [x3, #(11 * 8)] | ||
274 | str x15, [x3, #(10 * 8)] | ||
275 | str x14, [x3, #(9 * 8)] | ||
276 | str x13, [x3, #(8 * 8)] | ||
277 | str x12, [x3, #(7 * 8)] | ||
278 | str x11, [x3, #(6 * 8)] | ||
279 | str x10, [x3, #(5 * 8)] | ||
280 | str x9, [x3, #(4 * 8)] | ||
281 | str x8, [x3, #(3 * 8)] | ||
282 | str x7, [x3, #(2 * 8)] | ||
283 | str x6, [x3, #(1 * 8)] | ||
284 | str x5, [x3, #(0 * 8)] | ||
285 | |||
286 | add x3, x2, #CPU_SYSREG_OFFSET(DBGBVR0_EL1) | ||
287 | |||
288 | adr x26, 1f | ||
289 | add x26, x26, x24, lsl #2 | ||
290 | br x26 | ||
291 | 1: | ||
292 | mrs x20, dbgbvr15_el1 | ||
293 | mrs x19, dbgbvr14_el1 | ||
294 | mrs x18, dbgbvr13_el1 | ||
295 | mrs x17, dbgbvr12_el1 | ||
296 | mrs x16, dbgbvr11_el1 | ||
297 | mrs x15, dbgbvr10_el1 | ||
298 | mrs x14, dbgbvr9_el1 | ||
299 | mrs x13, dbgbvr8_el1 | ||
300 | mrs x12, dbgbvr7_el1 | ||
301 | mrs x11, dbgbvr6_el1 | ||
302 | mrs x10, dbgbvr5_el1 | ||
303 | mrs x9, dbgbvr4_el1 | ||
304 | mrs x8, dbgbvr3_el1 | ||
305 | mrs x7, dbgbvr2_el1 | ||
306 | mrs x6, dbgbvr1_el1 | ||
307 | mrs x5, dbgbvr0_el1 | ||
308 | |||
309 | adr x26, 1f | ||
310 | add x26, x26, x24, lsl #2 | ||
311 | br x26 | ||
312 | |||
313 | 1: | ||
314 | str x20, [x3, #(15 * 8)] | ||
315 | str x19, [x3, #(14 * 8)] | ||
316 | str x18, [x3, #(13 * 8)] | ||
317 | str x17, [x3, #(12 * 8)] | ||
318 | str x16, [x3, #(11 * 8)] | ||
319 | str x15, [x3, #(10 * 8)] | ||
320 | str x14, [x3, #(9 * 8)] | ||
321 | str x13, [x3, #(8 * 8)] | ||
322 | str x12, [x3, #(7 * 8)] | ||
323 | str x11, [x3, #(6 * 8)] | ||
324 | str x10, [x3, #(5 * 8)] | ||
325 | str x9, [x3, #(4 * 8)] | ||
326 | str x8, [x3, #(3 * 8)] | ||
327 | str x7, [x3, #(2 * 8)] | ||
328 | str x6, [x3, #(1 * 8)] | ||
329 | str x5, [x3, #(0 * 8)] | ||
330 | |||
331 | add x3, x2, #CPU_SYSREG_OFFSET(DBGWCR0_EL1) | ||
332 | |||
333 | adr x26, 1f | ||
334 | add x26, x26, x25, lsl #2 | ||
335 | br x26 | ||
336 | 1: | ||
337 | mrs x20, dbgwcr15_el1 | ||
338 | mrs x19, dbgwcr14_el1 | ||
339 | mrs x18, dbgwcr13_el1 | ||
340 | mrs x17, dbgwcr12_el1 | ||
341 | mrs x16, dbgwcr11_el1 | ||
342 | mrs x15, dbgwcr10_el1 | ||
343 | mrs x14, dbgwcr9_el1 | ||
344 | mrs x13, dbgwcr8_el1 | ||
345 | mrs x12, dbgwcr7_el1 | ||
346 | mrs x11, dbgwcr6_el1 | ||
347 | mrs x10, dbgwcr5_el1 | ||
348 | mrs x9, dbgwcr4_el1 | ||
349 | mrs x8, dbgwcr3_el1 | ||
350 | mrs x7, dbgwcr2_el1 | ||
351 | mrs x6, dbgwcr1_el1 | ||
352 | mrs x5, dbgwcr0_el1 | ||
353 | |||
354 | adr x26, 1f | ||
355 | add x26, x26, x25, lsl #2 | ||
356 | br x26 | ||
357 | |||
358 | 1: | ||
359 | str x20, [x3, #(15 * 8)] | ||
360 | str x19, [x3, #(14 * 8)] | ||
361 | str x18, [x3, #(13 * 8)] | ||
362 | str x17, [x3, #(12 * 8)] | ||
363 | str x16, [x3, #(11 * 8)] | ||
364 | str x15, [x3, #(10 * 8)] | ||
365 | str x14, [x3, #(9 * 8)] | ||
366 | str x13, [x3, #(8 * 8)] | ||
367 | str x12, [x3, #(7 * 8)] | ||
368 | str x11, [x3, #(6 * 8)] | ||
369 | str x10, [x3, #(5 * 8)] | ||
370 | str x9, [x3, #(4 * 8)] | ||
371 | str x8, [x3, #(3 * 8)] | ||
372 | str x7, [x3, #(2 * 8)] | ||
373 | str x6, [x3, #(1 * 8)] | ||
374 | str x5, [x3, #(0 * 8)] | ||
375 | |||
376 | add x3, x2, #CPU_SYSREG_OFFSET(DBGWVR0_EL1) | ||
377 | |||
378 | adr x26, 1f | ||
379 | add x26, x26, x25, lsl #2 | ||
380 | br x26 | ||
381 | 1: | ||
382 | mrs x20, dbgwvr15_el1 | ||
383 | mrs x19, dbgwvr14_el1 | ||
384 | mrs x18, dbgwvr13_el1 | ||
385 | mrs x17, dbgwvr12_el1 | ||
386 | mrs x16, dbgwvr11_el1 | ||
387 | mrs x15, dbgwvr10_el1 | ||
388 | mrs x14, dbgwvr9_el1 | ||
389 | mrs x13, dbgwvr8_el1 | ||
390 | mrs x12, dbgwvr7_el1 | ||
391 | mrs x11, dbgwvr6_el1 | ||
392 | mrs x10, dbgwvr5_el1 | ||
393 | mrs x9, dbgwvr4_el1 | ||
394 | mrs x8, dbgwvr3_el1 | ||
395 | mrs x7, dbgwvr2_el1 | ||
396 | mrs x6, dbgwvr1_el1 | ||
397 | mrs x5, dbgwvr0_el1 | ||
398 | |||
399 | adr x26, 1f | ||
400 | add x26, x26, x25, lsl #2 | ||
401 | br x26 | ||
402 | |||
403 | 1: | ||
404 | str x20, [x3, #(15 * 8)] | ||
405 | str x19, [x3, #(14 * 8)] | ||
406 | str x18, [x3, #(13 * 8)] | ||
407 | str x17, [x3, #(12 * 8)] | ||
408 | str x16, [x3, #(11 * 8)] | ||
409 | str x15, [x3, #(10 * 8)] | ||
410 | str x14, [x3, #(9 * 8)] | ||
411 | str x13, [x3, #(8 * 8)] | ||
412 | str x12, [x3, #(7 * 8)] | ||
413 | str x11, [x3, #(6 * 8)] | ||
414 | str x10, [x3, #(5 * 8)] | ||
415 | str x9, [x3, #(4 * 8)] | ||
416 | str x8, [x3, #(3 * 8)] | ||
417 | str x7, [x3, #(2 * 8)] | ||
418 | str x6, [x3, #(1 * 8)] | ||
419 | str x5, [x3, #(0 * 8)] | ||
420 | |||
421 | mrs x21, mdccint_el1 | ||
422 | str x21, [x2, #CPU_SYSREG_OFFSET(MDCCINT_EL1)] | ||
230 | .endm | 423 | .endm |
231 | 424 | ||
232 | .macro restore_sysregs | 425 | .macro restore_sysregs |
@@ -245,7 +438,7 @@ __kvm_hyp_code_start: | |||
245 | ldp x18, x19, [x3, #112] | 438 | ldp x18, x19, [x3, #112] |
246 | ldp x20, x21, [x3, #128] | 439 | ldp x20, x21, [x3, #128] |
247 | ldp x22, x23, [x3, #144] | 440 | ldp x22, x23, [x3, #144] |
248 | ldr x24, [x3, #160] | 441 | ldp x24, x25, [x3, #160] |
249 | 442 | ||
250 | msr vmpidr_el2, x4 | 443 | msr vmpidr_el2, x4 |
251 | msr csselr_el1, x5 | 444 | msr csselr_el1, x5 |
@@ -268,6 +461,198 @@ __kvm_hyp_code_start: | |||
268 | msr amair_el1, x22 | 461 | msr amair_el1, x22 |
269 | msr cntkctl_el1, x23 | 462 | msr cntkctl_el1, x23 |
270 | msr par_el1, x24 | 463 | msr par_el1, x24 |
464 | msr mdscr_el1, x25 | ||
465 | .endm | ||
466 | |||
467 | .macro restore_debug | ||
468 | // x2: base address for cpu context | ||
469 | // x3: tmp register | ||
470 | |||
471 | mrs x26, id_aa64dfr0_el1 | ||
472 | ubfx x24, x26, #12, #4 // Extract BRPs | ||
473 | ubfx x25, x26, #20, #4 // Extract WRPs | ||
474 | mov w26, #15 | ||
475 | sub w24, w26, w24 // How many BPs to skip | ||
476 | sub w25, w26, w25 // How many WPs to skip | ||
477 | |||
478 | add x3, x2, #CPU_SYSREG_OFFSET(DBGBCR0_EL1) | ||
479 | |||
480 | adr x26, 1f | ||
481 | add x26, x26, x24, lsl #2 | ||
482 | br x26 | ||
483 | 1: | ||
484 | ldr x20, [x3, #(15 * 8)] | ||
485 | ldr x19, [x3, #(14 * 8)] | ||
486 | ldr x18, [x3, #(13 * 8)] | ||
487 | ldr x17, [x3, #(12 * 8)] | ||
488 | ldr x16, [x3, #(11 * 8)] | ||
489 | ldr x15, [x3, #(10 * 8)] | ||
490 | ldr x14, [x3, #(9 * 8)] | ||
491 | ldr x13, [x3, #(8 * 8)] | ||
492 | ldr x12, [x3, #(7 * 8)] | ||
493 | ldr x11, [x3, #(6 * 8)] | ||
494 | ldr x10, [x3, #(5 * 8)] | ||
495 | ldr x9, [x3, #(4 * 8)] | ||
496 | ldr x8, [x3, #(3 * 8)] | ||
497 | ldr x7, [x3, #(2 * 8)] | ||
498 | ldr x6, [x3, #(1 * 8)] | ||
499 | ldr x5, [x3, #(0 * 8)] | ||
500 | |||
501 | adr x26, 1f | ||
502 | add x26, x26, x24, lsl #2 | ||
503 | br x26 | ||
504 | 1: | ||
505 | msr dbgbcr15_el1, x20 | ||
506 | msr dbgbcr14_el1, x19 | ||
507 | msr dbgbcr13_el1, x18 | ||
508 | msr dbgbcr12_el1, x17 | ||
509 | msr dbgbcr11_el1, x16 | ||
510 | msr dbgbcr10_el1, x15 | ||
511 | msr dbgbcr9_el1, x14 | ||
512 | msr dbgbcr8_el1, x13 | ||
513 | msr dbgbcr7_el1, x12 | ||
514 | msr dbgbcr6_el1, x11 | ||
515 | msr dbgbcr5_el1, x10 | ||
516 | msr dbgbcr4_el1, x9 | ||
517 | msr dbgbcr3_el1, x8 | ||
518 | msr dbgbcr2_el1, x7 | ||
519 | msr dbgbcr1_el1, x6 | ||
520 | msr dbgbcr0_el1, x5 | ||
521 | |||
522 | add x3, x2, #CPU_SYSREG_OFFSET(DBGBVR0_EL1) | ||
523 | |||
524 | adr x26, 1f | ||
525 | add x26, x26, x24, lsl #2 | ||
526 | br x26 | ||
527 | 1: | ||
528 | ldr x20, [x3, #(15 * 8)] | ||
529 | ldr x19, [x3, #(14 * 8)] | ||
530 | ldr x18, [x3, #(13 * 8)] | ||
531 | ldr x17, [x3, #(12 * 8)] | ||
532 | ldr x16, [x3, #(11 * 8)] | ||
533 | ldr x15, [x3, #(10 * 8)] | ||
534 | ldr x14, [x3, #(9 * 8)] | ||
535 | ldr x13, [x3, #(8 * 8)] | ||
536 | ldr x12, [x3, #(7 * 8)] | ||
537 | ldr x11, [x3, #(6 * 8)] | ||
538 | ldr x10, [x3, #(5 * 8)] | ||
539 | ldr x9, [x3, #(4 * 8)] | ||
540 | ldr x8, [x3, #(3 * 8)] | ||
541 | ldr x7, [x3, #(2 * 8)] | ||
542 | ldr x6, [x3, #(1 * 8)] | ||
543 | ldr x5, [x3, #(0 * 8)] | ||
544 | |||
545 | adr x26, 1f | ||
546 | add x26, x26, x24, lsl #2 | ||
547 | br x26 | ||
548 | 1: | ||
549 | msr dbgbvr15_el1, x20 | ||
550 | msr dbgbvr14_el1, x19 | ||
551 | msr dbgbvr13_el1, x18 | ||
552 | msr dbgbvr12_el1, x17 | ||
553 | msr dbgbvr11_el1, x16 | ||
554 | msr dbgbvr10_el1, x15 | ||
555 | msr dbgbvr9_el1, x14 | ||
556 | msr dbgbvr8_el1, x13 | ||
557 | msr dbgbvr7_el1, x12 | ||
558 | msr dbgbvr6_el1, x11 | ||
559 | msr dbgbvr5_el1, x10 | ||
560 | msr dbgbvr4_el1, x9 | ||
561 | msr dbgbvr3_el1, x8 | ||
562 | msr dbgbvr2_el1, x7 | ||
563 | msr dbgbvr1_el1, x6 | ||
564 | msr dbgbvr0_el1, x5 | ||
565 | |||
566 | add x3, x2, #CPU_SYSREG_OFFSET(DBGWCR0_EL1) | ||
567 | |||
568 | adr x26, 1f | ||
569 | add x26, x26, x25, lsl #2 | ||
570 | br x26 | ||
571 | 1: | ||
572 | ldr x20, [x3, #(15 * 8)] | ||
573 | ldr x19, [x3, #(14 * 8)] | ||
574 | ldr x18, [x3, #(13 * 8)] | ||
575 | ldr x17, [x3, #(12 * 8)] | ||
576 | ldr x16, [x3, #(11 * 8)] | ||
577 | ldr x15, [x3, #(10 * 8)] | ||
578 | ldr x14, [x3, #(9 * 8)] | ||
579 | ldr x13, [x3, #(8 * 8)] | ||
580 | ldr x12, [x3, #(7 * 8)] | ||
581 | ldr x11, [x3, #(6 * 8)] | ||
582 | ldr x10, [x3, #(5 * 8)] | ||
583 | ldr x9, [x3, #(4 * 8)] | ||
584 | ldr x8, [x3, #(3 * 8)] | ||
585 | ldr x7, [x3, #(2 * 8)] | ||
586 | ldr x6, [x3, #(1 * 8)] | ||
587 | ldr x5, [x3, #(0 * 8)] | ||
588 | |||
589 | adr x26, 1f | ||
590 | add x26, x26, x25, lsl #2 | ||
591 | br x26 | ||
592 | 1: | ||
593 | msr dbgwcr15_el1, x20 | ||
594 | msr dbgwcr14_el1, x19 | ||
595 | msr dbgwcr13_el1, x18 | ||
596 | msr dbgwcr12_el1, x17 | ||
597 | msr dbgwcr11_el1, x16 | ||
598 | msr dbgwcr10_el1, x15 | ||
599 | msr dbgwcr9_el1, x14 | ||
600 | msr dbgwcr8_el1, x13 | ||
601 | msr dbgwcr7_el1, x12 | ||
602 | msr dbgwcr6_el1, x11 | ||
603 | msr dbgwcr5_el1, x10 | ||
604 | msr dbgwcr4_el1, x9 | ||
605 | msr dbgwcr3_el1, x8 | ||
606 | msr dbgwcr2_el1, x7 | ||
607 | msr dbgwcr1_el1, x6 | ||
608 | msr dbgwcr0_el1, x5 | ||
609 | |||
610 | add x3, x2, #CPU_SYSREG_OFFSET(DBGWVR0_EL1) | ||
611 | |||
612 | adr x26, 1f | ||
613 | add x26, x26, x25, lsl #2 | ||
614 | br x26 | ||
615 | 1: | ||
616 | ldr x20, [x3, #(15 * 8)] | ||
617 | ldr x19, [x3, #(14 * 8)] | ||
618 | ldr x18, [x3, #(13 * 8)] | ||
619 | ldr x17, [x3, #(12 * 8)] | ||
620 | ldr x16, [x3, #(11 * 8)] | ||
621 | ldr x15, [x3, #(10 * 8)] | ||
622 | ldr x14, [x3, #(9 * 8)] | ||
623 | ldr x13, [x3, #(8 * 8)] | ||
624 | ldr x12, [x3, #(7 * 8)] | ||
625 | ldr x11, [x3, #(6 * 8)] | ||
626 | ldr x10, [x3, #(5 * 8)] | ||
627 | ldr x9, [x3, #(4 * 8)] | ||
628 | ldr x8, [x3, #(3 * 8)] | ||
629 | ldr x7, [x3, #(2 * 8)] | ||
630 | ldr x6, [x3, #(1 * 8)] | ||
631 | ldr x5, [x3, #(0 * 8)] | ||
632 | |||
633 | adr x26, 1f | ||
634 | add x26, x26, x25, lsl #2 | ||
635 | br x26 | ||
636 | 1: | ||
637 | msr dbgwvr15_el1, x20 | ||
638 | msr dbgwvr14_el1, x19 | ||
639 | msr dbgwvr13_el1, x18 | ||
640 | msr dbgwvr12_el1, x17 | ||
641 | msr dbgwvr11_el1, x16 | ||
642 | msr dbgwvr10_el1, x15 | ||
643 | msr dbgwvr9_el1, x14 | ||
644 | msr dbgwvr8_el1, x13 | ||
645 | msr dbgwvr7_el1, x12 | ||
646 | msr dbgwvr6_el1, x11 | ||
647 | msr dbgwvr5_el1, x10 | ||
648 | msr dbgwvr4_el1, x9 | ||
649 | msr dbgwvr3_el1, x8 | ||
650 | msr dbgwvr2_el1, x7 | ||
651 | msr dbgwvr1_el1, x6 | ||
652 | msr dbgwvr0_el1, x5 | ||
653 | |||
654 | ldr x21, [x2, #CPU_SYSREG_OFFSET(MDCCINT_EL1)] | ||
655 | msr mdccint_el1, x21 | ||
271 | .endm | 656 | .endm |
272 | 657 | ||
273 | .macro skip_32bit_state tmp, target | 658 | .macro skip_32bit_state tmp, target |
@@ -282,6 +667,35 @@ __kvm_hyp_code_start: | |||
282 | tbz \tmp, #12, \target | 667 | tbz \tmp, #12, \target |
283 | .endm | 668 | .endm |
284 | 669 | ||
670 | .macro skip_debug_state tmp, target | ||
671 | ldr \tmp, [x0, #VCPU_DEBUG_FLAGS] | ||
672 | tbz \tmp, #KVM_ARM64_DEBUG_DIRTY_SHIFT, \target | ||
673 | .endm | ||
674 | |||
675 | .macro compute_debug_state target | ||
676 | // Compute debug state: If any of KDE, MDE or KVM_ARM64_DEBUG_DIRTY | ||
677 | // is set, we do a full save/restore cycle and disable trapping. | ||
678 | add x25, x0, #VCPU_CONTEXT | ||
679 | |||
680 | // Check the state of MDSCR_EL1 | ||
681 | ldr x25, [x25, #CPU_SYSREG_OFFSET(MDSCR_EL1)] | ||
682 | and x26, x25, #DBG_MDSCR_KDE | ||
683 | and x25, x25, #DBG_MDSCR_MDE | ||
684 | adds xzr, x25, x26 | ||
685 | b.eq 9998f // Nothing to see there | ||
686 | |||
687 | // If any interesting bits was set, we must set the flag | ||
688 | mov x26, #KVM_ARM64_DEBUG_DIRTY | ||
689 | str x26, [x0, #VCPU_DEBUG_FLAGS] | ||
690 | b 9999f // Don't skip restore | ||
691 | |||
692 | 9998: | ||
693 | // Otherwise load the flags from memory in case we recently | ||
694 | // trapped | ||
695 | skip_debug_state x25, \target | ||
696 | 9999: | ||
697 | .endm | ||
698 | |||
285 | .macro save_guest_32bit_state | 699 | .macro save_guest_32bit_state |
286 | skip_32bit_state x3, 1f | 700 | skip_32bit_state x3, 1f |
287 | 701 | ||
@@ -297,10 +711,13 @@ __kvm_hyp_code_start: | |||
297 | mrs x4, dacr32_el2 | 711 | mrs x4, dacr32_el2 |
298 | mrs x5, ifsr32_el2 | 712 | mrs x5, ifsr32_el2 |
299 | mrs x6, fpexc32_el2 | 713 | mrs x6, fpexc32_el2 |
300 | mrs x7, dbgvcr32_el2 | ||
301 | stp x4, x5, [x3] | 714 | stp x4, x5, [x3] |
302 | stp x6, x7, [x3, #16] | 715 | str x6, [x3, #16] |
303 | 716 | ||
717 | skip_debug_state x8, 2f | ||
718 | mrs x7, dbgvcr32_el2 | ||
719 | str x7, [x3, #24] | ||
720 | 2: | ||
304 | skip_tee_state x8, 1f | 721 | skip_tee_state x8, 1f |
305 | 722 | ||
306 | add x3, x2, #CPU_SYSREG_OFFSET(TEECR32_EL1) | 723 | add x3, x2, #CPU_SYSREG_OFFSET(TEECR32_EL1) |
@@ -323,12 +740,15 @@ __kvm_hyp_code_start: | |||
323 | 740 | ||
324 | add x3, x2, #CPU_SYSREG_OFFSET(DACR32_EL2) | 741 | add x3, x2, #CPU_SYSREG_OFFSET(DACR32_EL2) |
325 | ldp x4, x5, [x3] | 742 | ldp x4, x5, [x3] |
326 | ldp x6, x7, [x3, #16] | 743 | ldr x6, [x3, #16] |
327 | msr dacr32_el2, x4 | 744 | msr dacr32_el2, x4 |
328 | msr ifsr32_el2, x5 | 745 | msr ifsr32_el2, x5 |
329 | msr fpexc32_el2, x6 | 746 | msr fpexc32_el2, x6 |
330 | msr dbgvcr32_el2, x7 | ||
331 | 747 | ||
748 | skip_debug_state x8, 2f | ||
749 | ldr x7, [x3, #24] | ||
750 | msr dbgvcr32_el2, x7 | ||
751 | 2: | ||
332 | skip_tee_state x8, 1f | 752 | skip_tee_state x8, 1f |
333 | 753 | ||
334 | add x3, x2, #CPU_SYSREG_OFFSET(TEECR32_EL1) | 754 | add x3, x2, #CPU_SYSREG_OFFSET(TEECR32_EL1) |
@@ -339,11 +759,8 @@ __kvm_hyp_code_start: | |||
339 | .endm | 759 | .endm |
340 | 760 | ||
341 | .macro activate_traps | 761 | .macro activate_traps |
342 | ldr x2, [x0, #VCPU_IRQ_LINES] | 762 | ldr x2, [x0, #VCPU_HCR_EL2] |
343 | ldr x1, [x0, #VCPU_HCR_EL2] | 763 | msr hcr_el2, x2 |
344 | orr x2, x2, x1 | ||
345 | msr hcr_el2, x2 | ||
346 | |||
347 | ldr x2, =(CPTR_EL2_TTA) | 764 | ldr x2, =(CPTR_EL2_TTA) |
348 | msr cptr_el2, x2 | 765 | msr cptr_el2, x2 |
349 | 766 | ||
@@ -353,6 +770,14 @@ __kvm_hyp_code_start: | |||
353 | mrs x2, mdcr_el2 | 770 | mrs x2, mdcr_el2 |
354 | and x2, x2, #MDCR_EL2_HPMN_MASK | 771 | and x2, x2, #MDCR_EL2_HPMN_MASK |
355 | orr x2, x2, #(MDCR_EL2_TPM | MDCR_EL2_TPMCR) | 772 | orr x2, x2, #(MDCR_EL2_TPM | MDCR_EL2_TPMCR) |
773 | orr x2, x2, #(MDCR_EL2_TDRA | MDCR_EL2_TDOSA) | ||
774 | |||
775 | // Check for KVM_ARM64_DEBUG_DIRTY, and set debug to trap | ||
776 | // if not dirty. | ||
777 | ldr x3, [x0, #VCPU_DEBUG_FLAGS] | ||
778 | tbnz x3, #KVM_ARM64_DEBUG_DIRTY_SHIFT, 1f | ||
779 | orr x2, x2, #MDCR_EL2_TDA | ||
780 | 1: | ||
356 | msr mdcr_el2, x2 | 781 | msr mdcr_el2, x2 |
357 | .endm | 782 | .endm |
358 | 783 | ||
@@ -379,100 +804,33 @@ __kvm_hyp_code_start: | |||
379 | .endm | 804 | .endm |
380 | 805 | ||
381 | /* | 806 | /* |
382 | * Save the VGIC CPU state into memory | 807 | * Call into the vgic backend for state saving |
383 | * x0: Register pointing to VCPU struct | ||
384 | * Do not corrupt x1!!! | ||
385 | */ | 808 | */ |
386 | .macro save_vgic_state | 809 | .macro save_vgic_state |
387 | /* Get VGIC VCTRL base into x2 */ | 810 | adr x24, __vgic_sr_vectors |
388 | ldr x2, [x0, #VCPU_KVM] | 811 | ldr x24, [x24, VGIC_SAVE_FN] |
389 | kern_hyp_va x2 | 812 | kern_hyp_va x24 |
390 | ldr x2, [x2, #KVM_VGIC_VCTRL] | 813 | blr x24 |
391 | kern_hyp_va x2 | 814 | mrs x24, hcr_el2 |
392 | cbz x2, 2f // disabled | 815 | mov x25, #HCR_INT_OVERRIDE |
393 | 816 | neg x25, x25 | |
394 | /* Compute the address of struct vgic_cpu */ | 817 | and x24, x24, x25 |
395 | add x3, x0, #VCPU_VGIC_CPU | 818 | msr hcr_el2, x24 |
396 | |||
397 | /* Save all interesting registers */ | ||
398 | ldr w4, [x2, #GICH_HCR] | ||
399 | ldr w5, [x2, #GICH_VMCR] | ||
400 | ldr w6, [x2, #GICH_MISR] | ||
401 | ldr w7, [x2, #GICH_EISR0] | ||
402 | ldr w8, [x2, #GICH_EISR1] | ||
403 | ldr w9, [x2, #GICH_ELRSR0] | ||
404 | ldr w10, [x2, #GICH_ELRSR1] | ||
405 | ldr w11, [x2, #GICH_APR] | ||
406 | CPU_BE( rev w4, w4 ) | ||
407 | CPU_BE( rev w5, w5 ) | ||
408 | CPU_BE( rev w6, w6 ) | ||
409 | CPU_BE( rev w7, w7 ) | ||
410 | CPU_BE( rev w8, w8 ) | ||
411 | CPU_BE( rev w9, w9 ) | ||
412 | CPU_BE( rev w10, w10 ) | ||
413 | CPU_BE( rev w11, w11 ) | ||
414 | |||
415 | str w4, [x3, #VGIC_CPU_HCR] | ||
416 | str w5, [x3, #VGIC_CPU_VMCR] | ||
417 | str w6, [x3, #VGIC_CPU_MISR] | ||
418 | str w7, [x3, #VGIC_CPU_EISR] | ||
419 | str w8, [x3, #(VGIC_CPU_EISR + 4)] | ||
420 | str w9, [x3, #VGIC_CPU_ELRSR] | ||
421 | str w10, [x3, #(VGIC_CPU_ELRSR + 4)] | ||
422 | str w11, [x3, #VGIC_CPU_APR] | ||
423 | |||
424 | /* Clear GICH_HCR */ | ||
425 | str wzr, [x2, #GICH_HCR] | ||
426 | |||
427 | /* Save list registers */ | ||
428 | add x2, x2, #GICH_LR0 | ||
429 | ldr w4, [x3, #VGIC_CPU_NR_LR] | ||
430 | add x3, x3, #VGIC_CPU_LR | ||
431 | 1: ldr w5, [x2], #4 | ||
432 | CPU_BE( rev w5, w5 ) | ||
433 | str w5, [x3], #4 | ||
434 | sub w4, w4, #1 | ||
435 | cbnz w4, 1b | ||
436 | 2: | ||
437 | .endm | 819 | .endm |
438 | 820 | ||
439 | /* | 821 | /* |
440 | * Restore the VGIC CPU state from memory | 822 | * Call into the vgic backend for state restoring |
441 | * x0: Register pointing to VCPU struct | ||
442 | */ | 823 | */ |
443 | .macro restore_vgic_state | 824 | .macro restore_vgic_state |
444 | /* Get VGIC VCTRL base into x2 */ | 825 | mrs x24, hcr_el2 |
445 | ldr x2, [x0, #VCPU_KVM] | 826 | ldr x25, [x0, #VCPU_IRQ_LINES] |
446 | kern_hyp_va x2 | 827 | orr x24, x24, #HCR_INT_OVERRIDE |
447 | ldr x2, [x2, #KVM_VGIC_VCTRL] | 828 | orr x24, x24, x25 |
448 | kern_hyp_va x2 | 829 | msr hcr_el2, x24 |
449 | cbz x2, 2f // disabled | 830 | adr x24, __vgic_sr_vectors |
450 | 831 | ldr x24, [x24, #VGIC_RESTORE_FN] | |
451 | /* Compute the address of struct vgic_cpu */ | 832 | kern_hyp_va x24 |
452 | add x3, x0, #VCPU_VGIC_CPU | 833 | blr x24 |
453 | |||
454 | /* We only restore a minimal set of registers */ | ||
455 | ldr w4, [x3, #VGIC_CPU_HCR] | ||
456 | ldr w5, [x3, #VGIC_CPU_VMCR] | ||
457 | ldr w6, [x3, #VGIC_CPU_APR] | ||
458 | CPU_BE( rev w4, w4 ) | ||
459 | CPU_BE( rev w5, w5 ) | ||
460 | CPU_BE( rev w6, w6 ) | ||
461 | |||
462 | str w4, [x2, #GICH_HCR] | ||
463 | str w5, [x2, #GICH_VMCR] | ||
464 | str w6, [x2, #GICH_APR] | ||
465 | |||
466 | /* Restore list registers */ | ||
467 | add x2, x2, #GICH_LR0 | ||
468 | ldr w4, [x3, #VGIC_CPU_NR_LR] | ||
469 | add x3, x3, #VGIC_CPU_LR | ||
470 | 1: ldr w5, [x3], #4 | ||
471 | CPU_BE( rev w5, w5 ) | ||
472 | str w5, [x2], #4 | ||
473 | sub w4, w4, #1 | ||
474 | cbnz w4, 1b | ||
475 | 2: | ||
476 | .endm | 834 | .endm |
477 | 835 | ||
478 | .macro save_timer_state | 836 | .macro save_timer_state |
@@ -537,6 +895,14 @@ __restore_sysregs: | |||
537 | restore_sysregs | 895 | restore_sysregs |
538 | ret | 896 | ret |
539 | 897 | ||
898 | __save_debug: | ||
899 | save_debug | ||
900 | ret | ||
901 | |||
902 | __restore_debug: | ||
903 | restore_debug | ||
904 | ret | ||
905 | |||
540 | __save_fpsimd: | 906 | __save_fpsimd: |
541 | save_fpsimd | 907 | save_fpsimd |
542 | ret | 908 | ret |
@@ -568,6 +934,9 @@ ENTRY(__kvm_vcpu_run) | |||
568 | bl __save_fpsimd | 934 | bl __save_fpsimd |
569 | bl __save_sysregs | 935 | bl __save_sysregs |
570 | 936 | ||
937 | compute_debug_state 1f | ||
938 | bl __save_debug | ||
939 | 1: | ||
571 | activate_traps | 940 | activate_traps |
572 | activate_vm | 941 | activate_vm |
573 | 942 | ||
@@ -579,6 +948,10 @@ ENTRY(__kvm_vcpu_run) | |||
579 | 948 | ||
580 | bl __restore_sysregs | 949 | bl __restore_sysregs |
581 | bl __restore_fpsimd | 950 | bl __restore_fpsimd |
951 | |||
952 | skip_debug_state x3, 1f | ||
953 | bl __restore_debug | ||
954 | 1: | ||
582 | restore_guest_32bit_state | 955 | restore_guest_32bit_state |
583 | restore_guest_regs | 956 | restore_guest_regs |
584 | 957 | ||
@@ -595,6 +968,10 @@ __kvm_vcpu_return: | |||
595 | save_guest_regs | 968 | save_guest_regs |
596 | bl __save_fpsimd | 969 | bl __save_fpsimd |
597 | bl __save_sysregs | 970 | bl __save_sysregs |
971 | |||
972 | skip_debug_state x3, 1f | ||
973 | bl __save_debug | ||
974 | 1: | ||
598 | save_guest_32bit_state | 975 | save_guest_32bit_state |
599 | 976 | ||
600 | save_timer_state | 977 | save_timer_state |
@@ -609,6 +986,14 @@ __kvm_vcpu_return: | |||
609 | 986 | ||
610 | bl __restore_sysregs | 987 | bl __restore_sysregs |
611 | bl __restore_fpsimd | 988 | bl __restore_fpsimd |
989 | |||
990 | skip_debug_state x3, 1f | ||
991 | // Clear the dirty flag for the next run, as all the state has | ||
992 | // already been saved. Note that we nuke the whole 64bit word. | ||
993 | // If we ever add more flags, we'll have to be more careful... | ||
994 | str xzr, [x0, #VCPU_DEBUG_FLAGS] | ||
995 | bl __restore_debug | ||
996 | 1: | ||
612 | restore_host_regs | 997 | restore_host_regs |
613 | 998 | ||
614 | mov x0, x1 | 999 | mov x0, x1 |
@@ -653,6 +1038,12 @@ ENTRY(__kvm_flush_vm_context) | |||
653 | ret | 1038 | ret |
654 | ENDPROC(__kvm_flush_vm_context) | 1039 | ENDPROC(__kvm_flush_vm_context) |
655 | 1040 | ||
1041 | // struct vgic_sr_vectors __vgi_sr_vectors; | ||
1042 | .align 3 | ||
1043 | ENTRY(__vgic_sr_vectors) | ||
1044 | .skip VGIC_SR_VECTOR_SZ | ||
1045 | ENDPROC(__vgic_sr_vectors) | ||
1046 | |||
656 | __kvm_hyp_panic: | 1047 | __kvm_hyp_panic: |
657 | // Guess the context by looking at VTTBR: | 1048 | // Guess the context by looking at VTTBR: |
658 | // If zero, then we're already a host. | 1049 | // If zero, then we're already a host. |
@@ -830,7 +1221,7 @@ el1_trap: | |||
830 | mrs x2, far_el2 | 1221 | mrs x2, far_el2 |
831 | 1222 | ||
832 | 2: mrs x0, tpidr_el2 | 1223 | 2: mrs x0, tpidr_el2 |
833 | str x1, [x0, #VCPU_ESR_EL2] | 1224 | str w1, [x0, #VCPU_ESR_EL2] |
834 | str x2, [x0, #VCPU_FAR_EL2] | 1225 | str x2, [x0, #VCPU_FAR_EL2] |
835 | str x3, [x0, #VCPU_HPFAR_EL2] | 1226 | str x3, [x0, #VCPU_HPFAR_EL2] |
836 | 1227 | ||
@@ -880,7 +1271,4 @@ ENTRY(__kvm_hyp_vector) | |||
880 | ventry el1_error_invalid // Error 32-bit EL1 | 1271 | ventry el1_error_invalid // Error 32-bit EL1 |
881 | ENDPROC(__kvm_hyp_vector) | 1272 | ENDPROC(__kvm_hyp_vector) |
882 | 1273 | ||
883 | __kvm_hyp_code_end: | ||
884 | .globl __kvm_hyp_code_end | ||
885 | |||
886 | .popsection | 1274 | .popsection |
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index c59a1bdab5eb..5805e7c4a4dd 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <asm/kvm_mmu.h> | 30 | #include <asm/kvm_mmu.h> |
31 | #include <asm/cacheflush.h> | 31 | #include <asm/cacheflush.h> |
32 | #include <asm/cputype.h> | 32 | #include <asm/cputype.h> |
33 | #include <asm/debug-monitors.h> | ||
33 | #include <trace/events/kvm.h> | 34 | #include <trace/events/kvm.h> |
34 | 35 | ||
35 | #include "sys_regs.h" | 36 | #include "sys_regs.h" |
@@ -137,10 +138,11 @@ static bool access_vm_reg(struct kvm_vcpu *vcpu, | |||
137 | if (!p->is_aarch32) { | 138 | if (!p->is_aarch32) { |
138 | vcpu_sys_reg(vcpu, r->reg) = val; | 139 | vcpu_sys_reg(vcpu, r->reg) = val; |
139 | } else { | 140 | } else { |
140 | vcpu_cp15(vcpu, r->reg) = val & 0xffffffffUL; | ||
141 | if (!p->is_32bit) | 141 | if (!p->is_32bit) |
142 | vcpu_cp15(vcpu, r->reg + 1) = val >> 32; | 142 | vcpu_cp15_64_high(vcpu, r->reg) = val >> 32; |
143 | vcpu_cp15_64_low(vcpu, r->reg) = val & 0xffffffffUL; | ||
143 | } | 144 | } |
145 | |||
144 | return true; | 146 | return true; |
145 | } | 147 | } |
146 | 148 | ||
@@ -163,18 +165,9 @@ static bool access_sctlr(struct kvm_vcpu *vcpu, | |||
163 | return true; | 165 | return true; |
164 | } | 166 | } |
165 | 167 | ||
166 | /* | 168 | static bool trap_raz_wi(struct kvm_vcpu *vcpu, |
167 | * We could trap ID_DFR0 and tell the guest we don't support performance | 169 | const struct sys_reg_params *p, |
168 | * monitoring. Unfortunately the patch to make the kernel check ID_DFR0 was | 170 | const struct sys_reg_desc *r) |
169 | * NAKed, so it will read the PMCR anyway. | ||
170 | * | ||
171 | * Therefore we tell the guest we have 0 counters. Unfortunately, we | ||
172 | * must always support PMCCNTR (the cycle counter): we just RAZ/WI for | ||
173 | * all PM registers, which doesn't crash the guest kernel at least. | ||
174 | */ | ||
175 | static bool pm_fake(struct kvm_vcpu *vcpu, | ||
176 | const struct sys_reg_params *p, | ||
177 | const struct sys_reg_desc *r) | ||
178 | { | 171 | { |
179 | if (p->is_write) | 172 | if (p->is_write) |
180 | return ignore_write(vcpu, p); | 173 | return ignore_write(vcpu, p); |
@@ -182,6 +175,73 @@ static bool pm_fake(struct kvm_vcpu *vcpu, | |||
182 | return read_zero(vcpu, p); | 175 | return read_zero(vcpu, p); |
183 | } | 176 | } |
184 | 177 | ||
178 | static bool trap_oslsr_el1(struct kvm_vcpu *vcpu, | ||
179 | const struct sys_reg_params *p, | ||
180 | const struct sys_reg_desc *r) | ||
181 | { | ||
182 | if (p->is_write) { | ||
183 | return ignore_write(vcpu, p); | ||
184 | } else { | ||
185 | *vcpu_reg(vcpu, p->Rt) = (1 << 3); | ||
186 | return true; | ||
187 | } | ||
188 | } | ||
189 | |||
190 | static bool trap_dbgauthstatus_el1(struct kvm_vcpu *vcpu, | ||
191 | const struct sys_reg_params *p, | ||
192 | const struct sys_reg_desc *r) | ||
193 | { | ||
194 | if (p->is_write) { | ||
195 | return ignore_write(vcpu, p); | ||
196 | } else { | ||
197 | u32 val; | ||
198 | asm volatile("mrs %0, dbgauthstatus_el1" : "=r" (val)); | ||
199 | *vcpu_reg(vcpu, p->Rt) = val; | ||
200 | return true; | ||
201 | } | ||
202 | } | ||
203 | |||
204 | /* | ||
205 | * We want to avoid world-switching all the DBG registers all the | ||
206 | * time: | ||
207 | * | ||
208 | * - If we've touched any debug register, it is likely that we're | ||
209 | * going to touch more of them. It then makes sense to disable the | ||
210 | * traps and start doing the save/restore dance | ||
211 | * - If debug is active (DBG_MDSCR_KDE or DBG_MDSCR_MDE set), it is | ||
212 | * then mandatory to save/restore the registers, as the guest | ||
213 | * depends on them. | ||
214 | * | ||
215 | * For this, we use a DIRTY bit, indicating the guest has modified the | ||
216 | * debug registers, used as follow: | ||
217 | * | ||
218 | * On guest entry: | ||
219 | * - If the dirty bit is set (because we're coming back from trapping), | ||
220 | * disable the traps, save host registers, restore guest registers. | ||
221 | * - If debug is actively in use (DBG_MDSCR_KDE or DBG_MDSCR_MDE set), | ||
222 | * set the dirty bit, disable the traps, save host registers, | ||
223 | * restore guest registers. | ||
224 | * - Otherwise, enable the traps | ||
225 | * | ||
226 | * On guest exit: | ||
227 | * - If the dirty bit is set, save guest registers, restore host | ||
228 | * registers and clear the dirty bit. This ensure that the host can | ||
229 | * now use the debug registers. | ||
230 | */ | ||
231 | static bool trap_debug_regs(struct kvm_vcpu *vcpu, | ||
232 | const struct sys_reg_params *p, | ||
233 | const struct sys_reg_desc *r) | ||
234 | { | ||
235 | if (p->is_write) { | ||
236 | vcpu_sys_reg(vcpu, r->reg) = *vcpu_reg(vcpu, p->Rt); | ||
237 | vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY; | ||
238 | } else { | ||
239 | *vcpu_reg(vcpu, p->Rt) = vcpu_sys_reg(vcpu, r->reg); | ||
240 | } | ||
241 | |||
242 | return true; | ||
243 | } | ||
244 | |||
185 | static void reset_amair_el1(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) | 245 | static void reset_amair_el1(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) |
186 | { | 246 | { |
187 | u64 amair; | 247 | u64 amair; |
@@ -198,9 +258,39 @@ static void reset_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) | |||
198 | vcpu_sys_reg(vcpu, MPIDR_EL1) = (1UL << 31) | (vcpu->vcpu_id & 0xff); | 258 | vcpu_sys_reg(vcpu, MPIDR_EL1) = (1UL << 31) | (vcpu->vcpu_id & 0xff); |
199 | } | 259 | } |
200 | 260 | ||
261 | /* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */ | ||
262 | #define DBG_BCR_BVR_WCR_WVR_EL1(n) \ | ||
263 | /* DBGBVRn_EL1 */ \ | ||
264 | { Op0(0b10), Op1(0b000), CRn(0b0000), CRm((n)), Op2(0b100), \ | ||
265 | trap_debug_regs, reset_val, (DBGBVR0_EL1 + (n)), 0 }, \ | ||
266 | /* DBGBCRn_EL1 */ \ | ||
267 | { Op0(0b10), Op1(0b000), CRn(0b0000), CRm((n)), Op2(0b101), \ | ||
268 | trap_debug_regs, reset_val, (DBGBCR0_EL1 + (n)), 0 }, \ | ||
269 | /* DBGWVRn_EL1 */ \ | ||
270 | { Op0(0b10), Op1(0b000), CRn(0b0000), CRm((n)), Op2(0b110), \ | ||
271 | trap_debug_regs, reset_val, (DBGWVR0_EL1 + (n)), 0 }, \ | ||
272 | /* DBGWCRn_EL1 */ \ | ||
273 | { Op0(0b10), Op1(0b000), CRn(0b0000), CRm((n)), Op2(0b111), \ | ||
274 | trap_debug_regs, reset_val, (DBGWCR0_EL1 + (n)), 0 } | ||
275 | |||
201 | /* | 276 | /* |
202 | * Architected system registers. | 277 | * Architected system registers. |
203 | * Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2 | 278 | * Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2 |
279 | * | ||
280 | * We could trap ID_DFR0 and tell the guest we don't support performance | ||
281 | * monitoring. Unfortunately the patch to make the kernel check ID_DFR0 was | ||
282 | * NAKed, so it will read the PMCR anyway. | ||
283 | * | ||
284 | * Therefore we tell the guest we have 0 counters. Unfortunately, we | ||
285 | * must always support PMCCNTR (the cycle counter): we just RAZ/WI for | ||
286 | * all PM registers, which doesn't crash the guest kernel at least. | ||
287 | * | ||
288 | * Debug handling: We do trap most, if not all debug related system | ||
289 | * registers. The implementation is good enough to ensure that a guest | ||
290 | * can use these with minimal performance degradation. The drawback is | ||
291 | * that we don't implement any of the external debug, none of the | ||
292 | * OSlock protocol. This should be revisited if we ever encounter a | ||
293 | * more demanding guest... | ||
204 | */ | 294 | */ |
205 | static const struct sys_reg_desc sys_reg_descs[] = { | 295 | static const struct sys_reg_desc sys_reg_descs[] = { |
206 | /* DC ISW */ | 296 | /* DC ISW */ |
@@ -213,12 +303,71 @@ static const struct sys_reg_desc sys_reg_descs[] = { | |||
213 | { Op0(0b01), Op1(0b000), CRn(0b0111), CRm(0b1110), Op2(0b010), | 303 | { Op0(0b01), Op1(0b000), CRn(0b0111), CRm(0b1110), Op2(0b010), |
214 | access_dcsw }, | 304 | access_dcsw }, |
215 | 305 | ||
306 | DBG_BCR_BVR_WCR_WVR_EL1(0), | ||
307 | DBG_BCR_BVR_WCR_WVR_EL1(1), | ||
308 | /* MDCCINT_EL1 */ | ||
309 | { Op0(0b10), Op1(0b000), CRn(0b0000), CRm(0b0010), Op2(0b000), | ||
310 | trap_debug_regs, reset_val, MDCCINT_EL1, 0 }, | ||
311 | /* MDSCR_EL1 */ | ||
312 | { Op0(0b10), Op1(0b000), CRn(0b0000), CRm(0b0010), Op2(0b010), | ||
313 | trap_debug_regs, reset_val, MDSCR_EL1, 0 }, | ||
314 | DBG_BCR_BVR_WCR_WVR_EL1(2), | ||
315 | DBG_BCR_BVR_WCR_WVR_EL1(3), | ||
316 | DBG_BCR_BVR_WCR_WVR_EL1(4), | ||
317 | DBG_BCR_BVR_WCR_WVR_EL1(5), | ||
318 | DBG_BCR_BVR_WCR_WVR_EL1(6), | ||
319 | DBG_BCR_BVR_WCR_WVR_EL1(7), | ||
320 | DBG_BCR_BVR_WCR_WVR_EL1(8), | ||
321 | DBG_BCR_BVR_WCR_WVR_EL1(9), | ||
322 | DBG_BCR_BVR_WCR_WVR_EL1(10), | ||
323 | DBG_BCR_BVR_WCR_WVR_EL1(11), | ||
324 | DBG_BCR_BVR_WCR_WVR_EL1(12), | ||
325 | DBG_BCR_BVR_WCR_WVR_EL1(13), | ||
326 | DBG_BCR_BVR_WCR_WVR_EL1(14), | ||
327 | DBG_BCR_BVR_WCR_WVR_EL1(15), | ||
328 | |||
329 | /* MDRAR_EL1 */ | ||
330 | { Op0(0b10), Op1(0b000), CRn(0b0001), CRm(0b0000), Op2(0b000), | ||
331 | trap_raz_wi }, | ||
332 | /* OSLAR_EL1 */ | ||
333 | { Op0(0b10), Op1(0b000), CRn(0b0001), CRm(0b0000), Op2(0b100), | ||
334 | trap_raz_wi }, | ||
335 | /* OSLSR_EL1 */ | ||
336 | { Op0(0b10), Op1(0b000), CRn(0b0001), CRm(0b0001), Op2(0b100), | ||
337 | trap_oslsr_el1 }, | ||
338 | /* OSDLR_EL1 */ | ||
339 | { Op0(0b10), Op1(0b000), CRn(0b0001), CRm(0b0011), Op2(0b100), | ||
340 | trap_raz_wi }, | ||
341 | /* DBGPRCR_EL1 */ | ||
342 | { Op0(0b10), Op1(0b000), CRn(0b0001), CRm(0b0100), Op2(0b100), | ||
343 | trap_raz_wi }, | ||
344 | /* DBGCLAIMSET_EL1 */ | ||
345 | { Op0(0b10), Op1(0b000), CRn(0b0111), CRm(0b1000), Op2(0b110), | ||
346 | trap_raz_wi }, | ||
347 | /* DBGCLAIMCLR_EL1 */ | ||
348 | { Op0(0b10), Op1(0b000), CRn(0b0111), CRm(0b1001), Op2(0b110), | ||
349 | trap_raz_wi }, | ||
350 | /* DBGAUTHSTATUS_EL1 */ | ||
351 | { Op0(0b10), Op1(0b000), CRn(0b0111), CRm(0b1110), Op2(0b110), | ||
352 | trap_dbgauthstatus_el1 }, | ||
353 | |||
216 | /* TEECR32_EL1 */ | 354 | /* TEECR32_EL1 */ |
217 | { Op0(0b10), Op1(0b010), CRn(0b0000), CRm(0b0000), Op2(0b000), | 355 | { Op0(0b10), Op1(0b010), CRn(0b0000), CRm(0b0000), Op2(0b000), |
218 | NULL, reset_val, TEECR32_EL1, 0 }, | 356 | NULL, reset_val, TEECR32_EL1, 0 }, |
219 | /* TEEHBR32_EL1 */ | 357 | /* TEEHBR32_EL1 */ |
220 | { Op0(0b10), Op1(0b010), CRn(0b0001), CRm(0b0000), Op2(0b000), | 358 | { Op0(0b10), Op1(0b010), CRn(0b0001), CRm(0b0000), Op2(0b000), |
221 | NULL, reset_val, TEEHBR32_EL1, 0 }, | 359 | NULL, reset_val, TEEHBR32_EL1, 0 }, |
360 | |||
361 | /* MDCCSR_EL1 */ | ||
362 | { Op0(0b10), Op1(0b011), CRn(0b0000), CRm(0b0001), Op2(0b000), | ||
363 | trap_raz_wi }, | ||
364 | /* DBGDTR_EL0 */ | ||
365 | { Op0(0b10), Op1(0b011), CRn(0b0000), CRm(0b0100), Op2(0b000), | ||
366 | trap_raz_wi }, | ||
367 | /* DBGDTR[TR]X_EL0 */ | ||
368 | { Op0(0b10), Op1(0b011), CRn(0b0000), CRm(0b0101), Op2(0b000), | ||
369 | trap_raz_wi }, | ||
370 | |||
222 | /* DBGVCR32_EL2 */ | 371 | /* DBGVCR32_EL2 */ |
223 | { Op0(0b10), Op1(0b100), CRn(0b0000), CRm(0b0111), Op2(0b000), | 372 | { Op0(0b10), Op1(0b100), CRn(0b0000), CRm(0b0111), Op2(0b000), |
224 | NULL, reset_val, DBGVCR32_EL2, 0 }, | 373 | NULL, reset_val, DBGVCR32_EL2, 0 }, |
@@ -260,10 +409,10 @@ static const struct sys_reg_desc sys_reg_descs[] = { | |||
260 | 409 | ||
261 | /* PMINTENSET_EL1 */ | 410 | /* PMINTENSET_EL1 */ |
262 | { Op0(0b11), Op1(0b000), CRn(0b1001), CRm(0b1110), Op2(0b001), | 411 | { Op0(0b11), Op1(0b000), CRn(0b1001), CRm(0b1110), Op2(0b001), |
263 | pm_fake }, | 412 | trap_raz_wi }, |
264 | /* PMINTENCLR_EL1 */ | 413 | /* PMINTENCLR_EL1 */ |
265 | { Op0(0b11), Op1(0b000), CRn(0b1001), CRm(0b1110), Op2(0b010), | 414 | { Op0(0b11), Op1(0b000), CRn(0b1001), CRm(0b1110), Op2(0b010), |
266 | pm_fake }, | 415 | trap_raz_wi }, |
267 | 416 | ||
268 | /* MAIR_EL1 */ | 417 | /* MAIR_EL1 */ |
269 | { Op0(0b11), Op1(0b000), CRn(0b1010), CRm(0b0010), Op2(0b000), | 418 | { Op0(0b11), Op1(0b000), CRn(0b1010), CRm(0b0010), Op2(0b000), |
@@ -292,43 +441,43 @@ static const struct sys_reg_desc sys_reg_descs[] = { | |||
292 | 441 | ||
293 | /* PMCR_EL0 */ | 442 | /* PMCR_EL0 */ |
294 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b000), | 443 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b000), |
295 | pm_fake }, | 444 | trap_raz_wi }, |
296 | /* PMCNTENSET_EL0 */ | 445 | /* PMCNTENSET_EL0 */ |
297 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b001), | 446 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b001), |
298 | pm_fake }, | 447 | trap_raz_wi }, |
299 | /* PMCNTENCLR_EL0 */ | 448 | /* PMCNTENCLR_EL0 */ |
300 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b010), | 449 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b010), |
301 | pm_fake }, | 450 | trap_raz_wi }, |
302 | /* PMOVSCLR_EL0 */ | 451 | /* PMOVSCLR_EL0 */ |
303 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b011), | 452 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b011), |
304 | pm_fake }, | 453 | trap_raz_wi }, |
305 | /* PMSWINC_EL0 */ | 454 | /* PMSWINC_EL0 */ |
306 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b100), | 455 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b100), |
307 | pm_fake }, | 456 | trap_raz_wi }, |
308 | /* PMSELR_EL0 */ | 457 | /* PMSELR_EL0 */ |
309 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b101), | 458 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b101), |
310 | pm_fake }, | 459 | trap_raz_wi }, |
311 | /* PMCEID0_EL0 */ | 460 | /* PMCEID0_EL0 */ |
312 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b110), | 461 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b110), |
313 | pm_fake }, | 462 | trap_raz_wi }, |
314 | /* PMCEID1_EL0 */ | 463 | /* PMCEID1_EL0 */ |
315 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b111), | 464 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b111), |
316 | pm_fake }, | 465 | trap_raz_wi }, |
317 | /* PMCCNTR_EL0 */ | 466 | /* PMCCNTR_EL0 */ |
318 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1101), Op2(0b000), | 467 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1101), Op2(0b000), |
319 | pm_fake }, | 468 | trap_raz_wi }, |
320 | /* PMXEVTYPER_EL0 */ | 469 | /* PMXEVTYPER_EL0 */ |
321 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1101), Op2(0b001), | 470 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1101), Op2(0b001), |
322 | pm_fake }, | 471 | trap_raz_wi }, |
323 | /* PMXEVCNTR_EL0 */ | 472 | /* PMXEVCNTR_EL0 */ |
324 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1101), Op2(0b010), | 473 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1101), Op2(0b010), |
325 | pm_fake }, | 474 | trap_raz_wi }, |
326 | /* PMUSERENR_EL0 */ | 475 | /* PMUSERENR_EL0 */ |
327 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1110), Op2(0b000), | 476 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1110), Op2(0b000), |
328 | pm_fake }, | 477 | trap_raz_wi }, |
329 | /* PMOVSSET_EL0 */ | 478 | /* PMOVSSET_EL0 */ |
330 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1110), Op2(0b011), | 479 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1110), Op2(0b011), |
331 | pm_fake }, | 480 | trap_raz_wi }, |
332 | 481 | ||
333 | /* TPIDR_EL0 */ | 482 | /* TPIDR_EL0 */ |
334 | { Op0(0b11), Op1(0b011), CRn(0b1101), CRm(0b0000), Op2(0b010), | 483 | { Op0(0b11), Op1(0b011), CRn(0b1101), CRm(0b0000), Op2(0b010), |
@@ -348,13 +497,161 @@ static const struct sys_reg_desc sys_reg_descs[] = { | |||
348 | NULL, reset_val, FPEXC32_EL2, 0x70 }, | 497 | NULL, reset_val, FPEXC32_EL2, 0x70 }, |
349 | }; | 498 | }; |
350 | 499 | ||
500 | static bool trap_dbgidr(struct kvm_vcpu *vcpu, | ||
501 | const struct sys_reg_params *p, | ||
502 | const struct sys_reg_desc *r) | ||
503 | { | ||
504 | if (p->is_write) { | ||
505 | return ignore_write(vcpu, p); | ||
506 | } else { | ||
507 | u64 dfr = read_cpuid(ID_AA64DFR0_EL1); | ||
508 | u64 pfr = read_cpuid(ID_AA64PFR0_EL1); | ||
509 | u32 el3 = !!((pfr >> 12) & 0xf); | ||
510 | |||
511 | *vcpu_reg(vcpu, p->Rt) = ((((dfr >> 20) & 0xf) << 28) | | ||
512 | (((dfr >> 12) & 0xf) << 24) | | ||
513 | (((dfr >> 28) & 0xf) << 20) | | ||
514 | (6 << 16) | (el3 << 14) | (el3 << 12)); | ||
515 | return true; | ||
516 | } | ||
517 | } | ||
518 | |||
519 | static bool trap_debug32(struct kvm_vcpu *vcpu, | ||
520 | const struct sys_reg_params *p, | ||
521 | const struct sys_reg_desc *r) | ||
522 | { | ||
523 | if (p->is_write) { | ||
524 | vcpu_cp14(vcpu, r->reg) = *vcpu_reg(vcpu, p->Rt); | ||
525 | vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY; | ||
526 | } else { | ||
527 | *vcpu_reg(vcpu, p->Rt) = vcpu_cp14(vcpu, r->reg); | ||
528 | } | ||
529 | |||
530 | return true; | ||
531 | } | ||
532 | |||
533 | #define DBG_BCR_BVR_WCR_WVR(n) \ | ||
534 | /* DBGBVRn */ \ | ||
535 | { Op1( 0), CRn( 0), CRm((n)), Op2( 4), trap_debug32, \ | ||
536 | NULL, (cp14_DBGBVR0 + (n) * 2) }, \ | ||
537 | /* DBGBCRn */ \ | ||
538 | { Op1( 0), CRn( 0), CRm((n)), Op2( 5), trap_debug32, \ | ||
539 | NULL, (cp14_DBGBCR0 + (n) * 2) }, \ | ||
540 | /* DBGWVRn */ \ | ||
541 | { Op1( 0), CRn( 0), CRm((n)), Op2( 6), trap_debug32, \ | ||
542 | NULL, (cp14_DBGWVR0 + (n) * 2) }, \ | ||
543 | /* DBGWCRn */ \ | ||
544 | { Op1( 0), CRn( 0), CRm((n)), Op2( 7), trap_debug32, \ | ||
545 | NULL, (cp14_DBGWCR0 + (n) * 2) } | ||
546 | |||
547 | #define DBGBXVR(n) \ | ||
548 | { Op1( 0), CRn( 1), CRm((n)), Op2( 1), trap_debug32, \ | ||
549 | NULL, cp14_DBGBXVR0 + n * 2 } | ||
550 | |||
551 | /* | ||
552 | * Trapped cp14 registers. We generally ignore most of the external | ||
553 | * debug, on the principle that they don't really make sense to a | ||
554 | * guest. Revisit this one day, whould this principle change. | ||
555 | */ | ||
556 | static const struct sys_reg_desc cp14_regs[] = { | ||
557 | /* DBGIDR */ | ||
558 | { Op1( 0), CRn( 0), CRm( 0), Op2( 0), trap_dbgidr }, | ||
559 | /* DBGDTRRXext */ | ||
560 | { Op1( 0), CRn( 0), CRm( 0), Op2( 2), trap_raz_wi }, | ||
561 | |||
562 | DBG_BCR_BVR_WCR_WVR(0), | ||
563 | /* DBGDSCRint */ | ||
564 | { Op1( 0), CRn( 0), CRm( 1), Op2( 0), trap_raz_wi }, | ||
565 | DBG_BCR_BVR_WCR_WVR(1), | ||
566 | /* DBGDCCINT */ | ||
567 | { Op1( 0), CRn( 0), CRm( 2), Op2( 0), trap_debug32 }, | ||
568 | /* DBGDSCRext */ | ||
569 | { Op1( 0), CRn( 0), CRm( 2), Op2( 2), trap_debug32 }, | ||
570 | DBG_BCR_BVR_WCR_WVR(2), | ||
571 | /* DBGDTR[RT]Xint */ | ||
572 | { Op1( 0), CRn( 0), CRm( 3), Op2( 0), trap_raz_wi }, | ||
573 | /* DBGDTR[RT]Xext */ | ||
574 | { Op1( 0), CRn( 0), CRm( 3), Op2( 2), trap_raz_wi }, | ||
575 | DBG_BCR_BVR_WCR_WVR(3), | ||
576 | DBG_BCR_BVR_WCR_WVR(4), | ||
577 | DBG_BCR_BVR_WCR_WVR(5), | ||
578 | /* DBGWFAR */ | ||
579 | { Op1( 0), CRn( 0), CRm( 6), Op2( 0), trap_raz_wi }, | ||
580 | /* DBGOSECCR */ | ||
581 | { Op1( 0), CRn( 0), CRm( 6), Op2( 2), trap_raz_wi }, | ||
582 | DBG_BCR_BVR_WCR_WVR(6), | ||
583 | /* DBGVCR */ | ||
584 | { Op1( 0), CRn( 0), CRm( 7), Op2( 0), trap_debug32 }, | ||
585 | DBG_BCR_BVR_WCR_WVR(7), | ||
586 | DBG_BCR_BVR_WCR_WVR(8), | ||
587 | DBG_BCR_BVR_WCR_WVR(9), | ||
588 | DBG_BCR_BVR_WCR_WVR(10), | ||
589 | DBG_BCR_BVR_WCR_WVR(11), | ||
590 | DBG_BCR_BVR_WCR_WVR(12), | ||
591 | DBG_BCR_BVR_WCR_WVR(13), | ||
592 | DBG_BCR_BVR_WCR_WVR(14), | ||
593 | DBG_BCR_BVR_WCR_WVR(15), | ||
594 | |||
595 | /* DBGDRAR (32bit) */ | ||
596 | { Op1( 0), CRn( 1), CRm( 0), Op2( 0), trap_raz_wi }, | ||
597 | |||
598 | DBGBXVR(0), | ||
599 | /* DBGOSLAR */ | ||
600 | { Op1( 0), CRn( 1), CRm( 0), Op2( 4), trap_raz_wi }, | ||
601 | DBGBXVR(1), | ||
602 | /* DBGOSLSR */ | ||
603 | { Op1( 0), CRn( 1), CRm( 1), Op2( 4), trap_oslsr_el1 }, | ||
604 | DBGBXVR(2), | ||
605 | DBGBXVR(3), | ||
606 | /* DBGOSDLR */ | ||
607 | { Op1( 0), CRn( 1), CRm( 3), Op2( 4), trap_raz_wi }, | ||
608 | DBGBXVR(4), | ||
609 | /* DBGPRCR */ | ||
610 | { Op1( 0), CRn( 1), CRm( 4), Op2( 4), trap_raz_wi }, | ||
611 | DBGBXVR(5), | ||
612 | DBGBXVR(6), | ||
613 | DBGBXVR(7), | ||
614 | DBGBXVR(8), | ||
615 | DBGBXVR(9), | ||
616 | DBGBXVR(10), | ||
617 | DBGBXVR(11), | ||
618 | DBGBXVR(12), | ||
619 | DBGBXVR(13), | ||
620 | DBGBXVR(14), | ||
621 | DBGBXVR(15), | ||
622 | |||
623 | /* DBGDSAR (32bit) */ | ||
624 | { Op1( 0), CRn( 2), CRm( 0), Op2( 0), trap_raz_wi }, | ||
625 | |||
626 | /* DBGDEVID2 */ | ||
627 | { Op1( 0), CRn( 7), CRm( 0), Op2( 7), trap_raz_wi }, | ||
628 | /* DBGDEVID1 */ | ||
629 | { Op1( 0), CRn( 7), CRm( 1), Op2( 7), trap_raz_wi }, | ||
630 | /* DBGDEVID */ | ||
631 | { Op1( 0), CRn( 7), CRm( 2), Op2( 7), trap_raz_wi }, | ||
632 | /* DBGCLAIMSET */ | ||
633 | { Op1( 0), CRn( 7), CRm( 8), Op2( 6), trap_raz_wi }, | ||
634 | /* DBGCLAIMCLR */ | ||
635 | { Op1( 0), CRn( 7), CRm( 9), Op2( 6), trap_raz_wi }, | ||
636 | /* DBGAUTHSTATUS */ | ||
637 | { Op1( 0), CRn( 7), CRm(14), Op2( 6), trap_dbgauthstatus_el1 }, | ||
638 | }; | ||
639 | |||
640 | /* Trapped cp14 64bit registers */ | ||
641 | static const struct sys_reg_desc cp14_64_regs[] = { | ||
642 | /* DBGDRAR (64bit) */ | ||
643 | { Op1( 0), CRm( 1), .access = trap_raz_wi }, | ||
644 | |||
645 | /* DBGDSAR (64bit) */ | ||
646 | { Op1( 0), CRm( 2), .access = trap_raz_wi }, | ||
647 | }; | ||
648 | |||
351 | /* | 649 | /* |
352 | * Trapped cp15 registers. TTBR0/TTBR1 get a double encoding, | 650 | * Trapped cp15 registers. TTBR0/TTBR1 get a double encoding, |
353 | * depending on the way they are accessed (as a 32bit or a 64bit | 651 | * depending on the way they are accessed (as a 32bit or a 64bit |
354 | * register). | 652 | * register). |
355 | */ | 653 | */ |
356 | static const struct sys_reg_desc cp15_regs[] = { | 654 | static const struct sys_reg_desc cp15_regs[] = { |
357 | { Op1( 0), CRn( 0), CRm( 2), Op2( 0), access_vm_reg, NULL, c2_TTBR0 }, | ||
358 | { Op1( 0), CRn( 1), CRm( 0), Op2( 0), access_sctlr, NULL, c1_SCTLR }, | 655 | { Op1( 0), CRn( 1), CRm( 0), Op2( 0), access_sctlr, NULL, c1_SCTLR }, |
359 | { Op1( 0), CRn( 2), CRm( 0), Op2( 0), access_vm_reg, NULL, c2_TTBR0 }, | 656 | { Op1( 0), CRn( 2), CRm( 0), Op2( 0), access_vm_reg, NULL, c2_TTBR0 }, |
360 | { Op1( 0), CRn( 2), CRm( 0), Op2( 1), access_vm_reg, NULL, c2_TTBR1 }, | 657 | { Op1( 0), CRn( 2), CRm( 0), Op2( 1), access_vm_reg, NULL, c2_TTBR1 }, |
@@ -374,26 +671,30 @@ static const struct sys_reg_desc cp15_regs[] = { | |||
374 | { Op1( 0), CRn( 7), CRm(10), Op2( 2), access_dcsw }, | 671 | { Op1( 0), CRn( 7), CRm(10), Op2( 2), access_dcsw }, |
375 | { Op1( 0), CRn( 7), CRm(14), Op2( 2), access_dcsw }, | 672 | { Op1( 0), CRn( 7), CRm(14), Op2( 2), access_dcsw }, |
376 | 673 | ||
377 | { Op1( 0), CRn( 9), CRm(12), Op2( 0), pm_fake }, | 674 | /* PMU */ |
378 | { Op1( 0), CRn( 9), CRm(12), Op2( 1), pm_fake }, | 675 | { Op1( 0), CRn( 9), CRm(12), Op2( 0), trap_raz_wi }, |
379 | { Op1( 0), CRn( 9), CRm(12), Op2( 2), pm_fake }, | 676 | { Op1( 0), CRn( 9), CRm(12), Op2( 1), trap_raz_wi }, |
380 | { Op1( 0), CRn( 9), CRm(12), Op2( 3), pm_fake }, | 677 | { Op1( 0), CRn( 9), CRm(12), Op2( 2), trap_raz_wi }, |
381 | { Op1( 0), CRn( 9), CRm(12), Op2( 5), pm_fake }, | 678 | { Op1( 0), CRn( 9), CRm(12), Op2( 3), trap_raz_wi }, |
382 | { Op1( 0), CRn( 9), CRm(12), Op2( 6), pm_fake }, | 679 | { Op1( 0), CRn( 9), CRm(12), Op2( 5), trap_raz_wi }, |
383 | { Op1( 0), CRn( 9), CRm(12), Op2( 7), pm_fake }, | 680 | { Op1( 0), CRn( 9), CRm(12), Op2( 6), trap_raz_wi }, |
384 | { Op1( 0), CRn( 9), CRm(13), Op2( 0), pm_fake }, | 681 | { Op1( 0), CRn( 9), CRm(12), Op2( 7), trap_raz_wi }, |
385 | { Op1( 0), CRn( 9), CRm(13), Op2( 1), pm_fake }, | 682 | { Op1( 0), CRn( 9), CRm(13), Op2( 0), trap_raz_wi }, |
386 | { Op1( 0), CRn( 9), CRm(13), Op2( 2), pm_fake }, | 683 | { Op1( 0), CRn( 9), CRm(13), Op2( 1), trap_raz_wi }, |
387 | { Op1( 0), CRn( 9), CRm(14), Op2( 0), pm_fake }, | 684 | { Op1( 0), CRn( 9), CRm(13), Op2( 2), trap_raz_wi }, |
388 | { Op1( 0), CRn( 9), CRm(14), Op2( 1), pm_fake }, | 685 | { Op1( 0), CRn( 9), CRm(14), Op2( 0), trap_raz_wi }, |
389 | { Op1( 0), CRn( 9), CRm(14), Op2( 2), pm_fake }, | 686 | { Op1( 0), CRn( 9), CRm(14), Op2( 1), trap_raz_wi }, |
687 | { Op1( 0), CRn( 9), CRm(14), Op2( 2), trap_raz_wi }, | ||
390 | 688 | ||
391 | { Op1( 0), CRn(10), CRm( 2), Op2( 0), access_vm_reg, NULL, c10_PRRR }, | 689 | { Op1( 0), CRn(10), CRm( 2), Op2( 0), access_vm_reg, NULL, c10_PRRR }, |
392 | { Op1( 0), CRn(10), CRm( 2), Op2( 1), access_vm_reg, NULL, c10_NMRR }, | 690 | { Op1( 0), CRn(10), CRm( 2), Op2( 1), access_vm_reg, NULL, c10_NMRR }, |
393 | { Op1( 0), CRn(10), CRm( 3), Op2( 0), access_vm_reg, NULL, c10_AMAIR0 }, | 691 | { Op1( 0), CRn(10), CRm( 3), Op2( 0), access_vm_reg, NULL, c10_AMAIR0 }, |
394 | { Op1( 0), CRn(10), CRm( 3), Op2( 1), access_vm_reg, NULL, c10_AMAIR1 }, | 692 | { Op1( 0), CRn(10), CRm( 3), Op2( 1), access_vm_reg, NULL, c10_AMAIR1 }, |
395 | { Op1( 0), CRn(13), CRm( 0), Op2( 1), access_vm_reg, NULL, c13_CID }, | 693 | { Op1( 0), CRn(13), CRm( 0), Op2( 1), access_vm_reg, NULL, c13_CID }, |
694 | }; | ||
396 | 695 | ||
696 | static const struct sys_reg_desc cp15_64_regs[] = { | ||
697 | { Op1( 0), CRn( 0), CRm( 2), Op2( 0), access_vm_reg, NULL, c2_TTBR0 }, | ||
397 | { Op1( 1), CRn( 0), CRm( 2), Op2( 0), access_vm_reg, NULL, c2_TTBR1 }, | 698 | { Op1( 1), CRn( 0), CRm( 2), Op2( 0), access_vm_reg, NULL, c2_TTBR1 }, |
398 | }; | 699 | }; |
399 | 700 | ||
@@ -454,26 +755,29 @@ int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
454 | return 1; | 755 | return 1; |
455 | } | 756 | } |
456 | 757 | ||
457 | int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run) | 758 | /* |
458 | { | 759 | * emulate_cp -- tries to match a sys_reg access in a handling table, and |
459 | kvm_inject_undefined(vcpu); | 760 | * call the corresponding trap handler. |
460 | return 1; | 761 | * |
461 | } | 762 | * @params: pointer to the descriptor of the access |
462 | 763 | * @table: array of trap descriptors | |
463 | static void emulate_cp15(struct kvm_vcpu *vcpu, | 764 | * @num: size of the trap descriptor array |
464 | const struct sys_reg_params *params) | 765 | * |
766 | * Return 0 if the access has been handled, and -1 if not. | ||
767 | */ | ||
768 | static int emulate_cp(struct kvm_vcpu *vcpu, | ||
769 | const struct sys_reg_params *params, | ||
770 | const struct sys_reg_desc *table, | ||
771 | size_t num) | ||
465 | { | 772 | { |
466 | size_t num; | 773 | const struct sys_reg_desc *r; |
467 | const struct sys_reg_desc *table, *r; | ||
468 | 774 | ||
469 | table = get_target_table(vcpu->arch.target, false, &num); | 775 | if (!table) |
776 | return -1; /* Not handled */ | ||
470 | 777 | ||
471 | /* Search target-specific then generic table. */ | ||
472 | r = find_reg(params, table, num); | 778 | r = find_reg(params, table, num); |
473 | if (!r) | ||
474 | r = find_reg(params, cp15_regs, ARRAY_SIZE(cp15_regs)); | ||
475 | 779 | ||
476 | if (likely(r)) { | 780 | if (r) { |
477 | /* | 781 | /* |
478 | * Not having an accessor means that we have | 782 | * Not having an accessor means that we have |
479 | * configured a trap that we don't know how to | 783 | * configured a trap that we don't know how to |
@@ -485,22 +789,51 @@ static void emulate_cp15(struct kvm_vcpu *vcpu, | |||
485 | if (likely(r->access(vcpu, params, r))) { | 789 | if (likely(r->access(vcpu, params, r))) { |
486 | /* Skip instruction, since it was emulated */ | 790 | /* Skip instruction, since it was emulated */ |
487 | kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu)); | 791 | kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu)); |
488 | return; | ||
489 | } | 792 | } |
490 | /* If access function fails, it should complain. */ | 793 | |
794 | /* Handled */ | ||
795 | return 0; | ||
491 | } | 796 | } |
492 | 797 | ||
493 | kvm_err("Unsupported guest CP15 access at: %08lx\n", *vcpu_pc(vcpu)); | 798 | /* Not handled */ |
799 | return -1; | ||
800 | } | ||
801 | |||
802 | static void unhandled_cp_access(struct kvm_vcpu *vcpu, | ||
803 | struct sys_reg_params *params) | ||
804 | { | ||
805 | u8 hsr_ec = kvm_vcpu_trap_get_class(vcpu); | ||
806 | int cp; | ||
807 | |||
808 | switch(hsr_ec) { | ||
809 | case ESR_EL2_EC_CP15_32: | ||
810 | case ESR_EL2_EC_CP15_64: | ||
811 | cp = 15; | ||
812 | break; | ||
813 | case ESR_EL2_EC_CP14_MR: | ||
814 | case ESR_EL2_EC_CP14_64: | ||
815 | cp = 14; | ||
816 | break; | ||
817 | default: | ||
818 | WARN_ON((cp = -1)); | ||
819 | } | ||
820 | |||
821 | kvm_err("Unsupported guest CP%d access at: %08lx\n", | ||
822 | cp, *vcpu_pc(vcpu)); | ||
494 | print_sys_reg_instr(params); | 823 | print_sys_reg_instr(params); |
495 | kvm_inject_undefined(vcpu); | 824 | kvm_inject_undefined(vcpu); |
496 | } | 825 | } |
497 | 826 | ||
498 | /** | 827 | /** |
499 | * kvm_handle_cp15_64 -- handles a mrrc/mcrr trap on a guest CP15 access | 828 | * kvm_handle_cp_64 -- handles a mrrc/mcrr trap on a guest CP15 access |
500 | * @vcpu: The VCPU pointer | 829 | * @vcpu: The VCPU pointer |
501 | * @run: The kvm_run struct | 830 | * @run: The kvm_run struct |
502 | */ | 831 | */ |
503 | int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run) | 832 | static int kvm_handle_cp_64(struct kvm_vcpu *vcpu, |
833 | const struct sys_reg_desc *global, | ||
834 | size_t nr_global, | ||
835 | const struct sys_reg_desc *target_specific, | ||
836 | size_t nr_specific) | ||
504 | { | 837 | { |
505 | struct sys_reg_params params; | 838 | struct sys_reg_params params; |
506 | u32 hsr = kvm_vcpu_get_hsr(vcpu); | 839 | u32 hsr = kvm_vcpu_get_hsr(vcpu); |
@@ -529,8 +862,14 @@ int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
529 | *vcpu_reg(vcpu, params.Rt) = val; | 862 | *vcpu_reg(vcpu, params.Rt) = val; |
530 | } | 863 | } |
531 | 864 | ||
532 | emulate_cp15(vcpu, ¶ms); | 865 | if (!emulate_cp(vcpu, ¶ms, target_specific, nr_specific)) |
866 | goto out; | ||
867 | if (!emulate_cp(vcpu, ¶ms, global, nr_global)) | ||
868 | goto out; | ||
533 | 869 | ||
870 | unhandled_cp_access(vcpu, ¶ms); | ||
871 | |||
872 | out: | ||
534 | /* Do the opposite hack for the read side */ | 873 | /* Do the opposite hack for the read side */ |
535 | if (!params.is_write) { | 874 | if (!params.is_write) { |
536 | u64 val = *vcpu_reg(vcpu, params.Rt); | 875 | u64 val = *vcpu_reg(vcpu, params.Rt); |
@@ -546,7 +885,11 @@ int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
546 | * @vcpu: The VCPU pointer | 885 | * @vcpu: The VCPU pointer |
547 | * @run: The kvm_run struct | 886 | * @run: The kvm_run struct |
548 | */ | 887 | */ |
549 | int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run) | 888 | static int kvm_handle_cp_32(struct kvm_vcpu *vcpu, |
889 | const struct sys_reg_desc *global, | ||
890 | size_t nr_global, | ||
891 | const struct sys_reg_desc *target_specific, | ||
892 | size_t nr_specific) | ||
550 | { | 893 | { |
551 | struct sys_reg_params params; | 894 | struct sys_reg_params params; |
552 | u32 hsr = kvm_vcpu_get_hsr(vcpu); | 895 | u32 hsr = kvm_vcpu_get_hsr(vcpu); |
@@ -561,10 +904,51 @@ int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
561 | params.Op1 = (hsr >> 14) & 0x7; | 904 | params.Op1 = (hsr >> 14) & 0x7; |
562 | params.Op2 = (hsr >> 17) & 0x7; | 905 | params.Op2 = (hsr >> 17) & 0x7; |
563 | 906 | ||
564 | emulate_cp15(vcpu, ¶ms); | 907 | if (!emulate_cp(vcpu, ¶ms, target_specific, nr_specific)) |
908 | return 1; | ||
909 | if (!emulate_cp(vcpu, ¶ms, global, nr_global)) | ||
910 | return 1; | ||
911 | |||
912 | unhandled_cp_access(vcpu, ¶ms); | ||
565 | return 1; | 913 | return 1; |
566 | } | 914 | } |
567 | 915 | ||
916 | int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run) | ||
917 | { | ||
918 | const struct sys_reg_desc *target_specific; | ||
919 | size_t num; | ||
920 | |||
921 | target_specific = get_target_table(vcpu->arch.target, false, &num); | ||
922 | return kvm_handle_cp_64(vcpu, | ||
923 | cp15_64_regs, ARRAY_SIZE(cp15_64_regs), | ||
924 | target_specific, num); | ||
925 | } | ||
926 | |||
927 | int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run) | ||
928 | { | ||
929 | const struct sys_reg_desc *target_specific; | ||
930 | size_t num; | ||
931 | |||
932 | target_specific = get_target_table(vcpu->arch.target, false, &num); | ||
933 | return kvm_handle_cp_32(vcpu, | ||
934 | cp15_regs, ARRAY_SIZE(cp15_regs), | ||
935 | target_specific, num); | ||
936 | } | ||
937 | |||
938 | int kvm_handle_cp14_64(struct kvm_vcpu *vcpu, struct kvm_run *run) | ||
939 | { | ||
940 | return kvm_handle_cp_64(vcpu, | ||
941 | cp14_64_regs, ARRAY_SIZE(cp14_64_regs), | ||
942 | NULL, 0); | ||
943 | } | ||
944 | |||
945 | int kvm_handle_cp14_32(struct kvm_vcpu *vcpu, struct kvm_run *run) | ||
946 | { | ||
947 | return kvm_handle_cp_32(vcpu, | ||
948 | cp14_regs, ARRAY_SIZE(cp14_regs), | ||
949 | NULL, 0); | ||
950 | } | ||
951 | |||
568 | static int emulate_sys_reg(struct kvm_vcpu *vcpu, | 952 | static int emulate_sys_reg(struct kvm_vcpu *vcpu, |
569 | const struct sys_reg_params *params) | 953 | const struct sys_reg_params *params) |
570 | { | 954 | { |
@@ -776,17 +1160,15 @@ static struct sys_reg_desc invariant_sys_regs[] = { | |||
776 | NULL, get_ctr_el0 }, | 1160 | NULL, get_ctr_el0 }, |
777 | }; | 1161 | }; |
778 | 1162 | ||
779 | static int reg_from_user(void *val, const void __user *uaddr, u64 id) | 1163 | static int reg_from_user(u64 *val, const void __user *uaddr, u64 id) |
780 | { | 1164 | { |
781 | /* This Just Works because we are little endian. */ | ||
782 | if (copy_from_user(val, uaddr, KVM_REG_SIZE(id)) != 0) | 1165 | if (copy_from_user(val, uaddr, KVM_REG_SIZE(id)) != 0) |
783 | return -EFAULT; | 1166 | return -EFAULT; |
784 | return 0; | 1167 | return 0; |
785 | } | 1168 | } |
786 | 1169 | ||
787 | static int reg_to_user(void __user *uaddr, const void *val, u64 id) | 1170 | static int reg_to_user(void __user *uaddr, const u64 *val, u64 id) |
788 | { | 1171 | { |
789 | /* This Just Works because we are little endian. */ | ||
790 | if (copy_to_user(uaddr, val, KVM_REG_SIZE(id)) != 0) | 1172 | if (copy_to_user(uaddr, val, KVM_REG_SIZE(id)) != 0) |
791 | return -EFAULT; | 1173 | return -EFAULT; |
792 | return 0; | 1174 | return 0; |
@@ -962,7 +1344,7 @@ static unsigned int num_demux_regs(void) | |||
962 | 1344 | ||
963 | static int write_demux_regids(u64 __user *uindices) | 1345 | static int write_demux_regids(u64 __user *uindices) |
964 | { | 1346 | { |
965 | u64 val = KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_DEMUX; | 1347 | u64 val = KVM_REG_ARM64 | KVM_REG_SIZE_U32 | KVM_REG_ARM_DEMUX; |
966 | unsigned int i; | 1348 | unsigned int i; |
967 | 1349 | ||
968 | val |= KVM_REG_ARM_DEMUX_ID_CCSIDR; | 1350 | val |= KVM_REG_ARM_DEMUX_ID_CCSIDR; |
@@ -1069,14 +1451,32 @@ int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) | |||
1069 | return write_demux_regids(uindices); | 1451 | return write_demux_regids(uindices); |
1070 | } | 1452 | } |
1071 | 1453 | ||
1454 | static int check_sysreg_table(const struct sys_reg_desc *table, unsigned int n) | ||
1455 | { | ||
1456 | unsigned int i; | ||
1457 | |||
1458 | for (i = 1; i < n; i++) { | ||
1459 | if (cmp_sys_reg(&table[i-1], &table[i]) >= 0) { | ||
1460 | kvm_err("sys_reg table %p out of order (%d)\n", table, i - 1); | ||
1461 | return 1; | ||
1462 | } | ||
1463 | } | ||
1464 | |||
1465 | return 0; | ||
1466 | } | ||
1467 | |||
1072 | void kvm_sys_reg_table_init(void) | 1468 | void kvm_sys_reg_table_init(void) |
1073 | { | 1469 | { |
1074 | unsigned int i; | 1470 | unsigned int i; |
1075 | struct sys_reg_desc clidr; | 1471 | struct sys_reg_desc clidr; |
1076 | 1472 | ||
1077 | /* Make sure tables are unique and in order. */ | 1473 | /* Make sure tables are unique and in order. */ |
1078 | for (i = 1; i < ARRAY_SIZE(sys_reg_descs); i++) | 1474 | BUG_ON(check_sysreg_table(sys_reg_descs, ARRAY_SIZE(sys_reg_descs))); |
1079 | BUG_ON(cmp_sys_reg(&sys_reg_descs[i-1], &sys_reg_descs[i]) >= 0); | 1475 | BUG_ON(check_sysreg_table(cp14_regs, ARRAY_SIZE(cp14_regs))); |
1476 | BUG_ON(check_sysreg_table(cp14_64_regs, ARRAY_SIZE(cp14_64_regs))); | ||
1477 | BUG_ON(check_sysreg_table(cp15_regs, ARRAY_SIZE(cp15_regs))); | ||
1478 | BUG_ON(check_sysreg_table(cp15_64_regs, ARRAY_SIZE(cp15_64_regs))); | ||
1479 | BUG_ON(check_sysreg_table(invariant_sys_regs, ARRAY_SIZE(invariant_sys_regs))); | ||
1080 | 1480 | ||
1081 | /* We abuse the reset function to overwrite the table itself. */ | 1481 | /* We abuse the reset function to overwrite the table itself. */ |
1082 | for (i = 0; i < ARRAY_SIZE(invariant_sys_regs); i++) | 1482 | for (i = 0; i < ARRAY_SIZE(invariant_sys_regs); i++) |
diff --git a/arch/arm64/kvm/vgic-v2-switch.S b/arch/arm64/kvm/vgic-v2-switch.S new file mode 100644 index 000000000000..ae211772f991 --- /dev/null +++ b/arch/arm64/kvm/vgic-v2-switch.S | |||
@@ -0,0 +1,133 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012,2013 - 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, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | |||
18 | #include <linux/linkage.h> | ||
19 | #include <linux/irqchip/arm-gic.h> | ||
20 | |||
21 | #include <asm/assembler.h> | ||
22 | #include <asm/memory.h> | ||
23 | #include <asm/asm-offsets.h> | ||
24 | #include <asm/kvm.h> | ||
25 | #include <asm/kvm_asm.h> | ||
26 | #include <asm/kvm_arm.h> | ||
27 | #include <asm/kvm_mmu.h> | ||
28 | |||
29 | .text | ||
30 | .pushsection .hyp.text, "ax" | ||
31 | |||
32 | /* | ||
33 | * Save the VGIC CPU state into memory | ||
34 | * x0: Register pointing to VCPU struct | ||
35 | * Do not corrupt x1!!! | ||
36 | */ | ||
37 | ENTRY(__save_vgic_v2_state) | ||
38 | __save_vgic_v2_state: | ||
39 | /* Get VGIC VCTRL base into x2 */ | ||
40 | ldr x2, [x0, #VCPU_KVM] | ||
41 | kern_hyp_va x2 | ||
42 | ldr x2, [x2, #KVM_VGIC_VCTRL] | ||
43 | kern_hyp_va x2 | ||
44 | cbz x2, 2f // disabled | ||
45 | |||
46 | /* Compute the address of struct vgic_cpu */ | ||
47 | add x3, x0, #VCPU_VGIC_CPU | ||
48 | |||
49 | /* Save all interesting registers */ | ||
50 | ldr w4, [x2, #GICH_HCR] | ||
51 | ldr w5, [x2, #GICH_VMCR] | ||
52 | ldr w6, [x2, #GICH_MISR] | ||
53 | ldr w7, [x2, #GICH_EISR0] | ||
54 | ldr w8, [x2, #GICH_EISR1] | ||
55 | ldr w9, [x2, #GICH_ELRSR0] | ||
56 | ldr w10, [x2, #GICH_ELRSR1] | ||
57 | ldr w11, [x2, #GICH_APR] | ||
58 | CPU_BE( rev w4, w4 ) | ||
59 | CPU_BE( rev w5, w5 ) | ||
60 | CPU_BE( rev w6, w6 ) | ||
61 | CPU_BE( rev w7, w7 ) | ||
62 | CPU_BE( rev w8, w8 ) | ||
63 | CPU_BE( rev w9, w9 ) | ||
64 | CPU_BE( rev w10, w10 ) | ||
65 | CPU_BE( rev w11, w11 ) | ||
66 | |||
67 | str w4, [x3, #VGIC_V2_CPU_HCR] | ||
68 | str w5, [x3, #VGIC_V2_CPU_VMCR] | ||
69 | str w6, [x3, #VGIC_V2_CPU_MISR] | ||
70 | str w7, [x3, #VGIC_V2_CPU_EISR] | ||
71 | str w8, [x3, #(VGIC_V2_CPU_EISR + 4)] | ||
72 | str w9, [x3, #VGIC_V2_CPU_ELRSR] | ||
73 | str w10, [x3, #(VGIC_V2_CPU_ELRSR + 4)] | ||
74 | str w11, [x3, #VGIC_V2_CPU_APR] | ||
75 | |||
76 | /* Clear GICH_HCR */ | ||
77 | str wzr, [x2, #GICH_HCR] | ||
78 | |||
79 | /* Save list registers */ | ||
80 | add x2, x2, #GICH_LR0 | ||
81 | ldr w4, [x3, #VGIC_CPU_NR_LR] | ||
82 | add x3, x3, #VGIC_V2_CPU_LR | ||
83 | 1: ldr w5, [x2], #4 | ||
84 | CPU_BE( rev w5, w5 ) | ||
85 | str w5, [x3], #4 | ||
86 | sub w4, w4, #1 | ||
87 | cbnz w4, 1b | ||
88 | 2: | ||
89 | ret | ||
90 | ENDPROC(__save_vgic_v2_state) | ||
91 | |||
92 | /* | ||
93 | * Restore the VGIC CPU state from memory | ||
94 | * x0: Register pointing to VCPU struct | ||
95 | */ | ||
96 | ENTRY(__restore_vgic_v2_state) | ||
97 | __restore_vgic_v2_state: | ||
98 | /* Get VGIC VCTRL base into x2 */ | ||
99 | ldr x2, [x0, #VCPU_KVM] | ||
100 | kern_hyp_va x2 | ||
101 | ldr x2, [x2, #KVM_VGIC_VCTRL] | ||
102 | kern_hyp_va x2 | ||
103 | cbz x2, 2f // disabled | ||
104 | |||
105 | /* Compute the address of struct vgic_cpu */ | ||
106 | add x3, x0, #VCPU_VGIC_CPU | ||
107 | |||
108 | /* We only restore a minimal set of registers */ | ||
109 | ldr w4, [x3, #VGIC_V2_CPU_HCR] | ||
110 | ldr w5, [x3, #VGIC_V2_CPU_VMCR] | ||
111 | ldr w6, [x3, #VGIC_V2_CPU_APR] | ||
112 | CPU_BE( rev w4, w4 ) | ||
113 | CPU_BE( rev w5, w5 ) | ||
114 | CPU_BE( rev w6, w6 ) | ||
115 | |||
116 | str w4, [x2, #GICH_HCR] | ||
117 | str w5, [x2, #GICH_VMCR] | ||
118 | str w6, [x2, #GICH_APR] | ||
119 | |||
120 | /* Restore list registers */ | ||
121 | add x2, x2, #GICH_LR0 | ||
122 | ldr w4, [x3, #VGIC_CPU_NR_LR] | ||
123 | add x3, x3, #VGIC_V2_CPU_LR | ||
124 | 1: ldr w5, [x3], #4 | ||
125 | CPU_BE( rev w5, w5 ) | ||
126 | str w5, [x2], #4 | ||
127 | sub w4, w4, #1 | ||
128 | cbnz w4, 1b | ||
129 | 2: | ||
130 | ret | ||
131 | ENDPROC(__restore_vgic_v2_state) | ||
132 | |||
133 | .popsection | ||
diff --git a/arch/arm64/kvm/vgic-v3-switch.S b/arch/arm64/kvm/vgic-v3-switch.S new file mode 100644 index 000000000000..d16046999e06 --- /dev/null +++ b/arch/arm64/kvm/vgic-v3-switch.S | |||
@@ -0,0 +1,267 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012,2013 - 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, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | |||
18 | #include <linux/linkage.h> | ||
19 | #include <linux/irqchip/arm-gic-v3.h> | ||
20 | |||
21 | #include <asm/assembler.h> | ||
22 | #include <asm/memory.h> | ||
23 | #include <asm/asm-offsets.h> | ||
24 | #include <asm/kvm.h> | ||
25 | #include <asm/kvm_asm.h> | ||
26 | #include <asm/kvm_arm.h> | ||
27 | |||
28 | .text | ||
29 | .pushsection .hyp.text, "ax" | ||
30 | |||
31 | /* | ||
32 | * We store LRs in reverse order to let the CPU deal with streaming | ||
33 | * access. Use this macro to make it look saner... | ||
34 | */ | ||
35 | #define LR_OFFSET(n) (VGIC_V3_CPU_LR + (15 - n) * 8) | ||
36 | |||
37 | /* | ||
38 | * Save the VGIC CPU state into memory | ||
39 | * x0: Register pointing to VCPU struct | ||
40 | * Do not corrupt x1!!! | ||
41 | */ | ||
42 | .macro save_vgic_v3_state | ||
43 | // Compute the address of struct vgic_cpu | ||
44 | add x3, x0, #VCPU_VGIC_CPU | ||
45 | |||
46 | // Make sure stores to the GIC via the memory mapped interface | ||
47 | // are now visible to the system register interface | ||
48 | dsb st | ||
49 | |||
50 | // Save all interesting registers | ||
51 | mrs_s x4, ICH_HCR_EL2 | ||
52 | mrs_s x5, ICH_VMCR_EL2 | ||
53 | mrs_s x6, ICH_MISR_EL2 | ||
54 | mrs_s x7, ICH_EISR_EL2 | ||
55 | mrs_s x8, ICH_ELSR_EL2 | ||
56 | |||
57 | str w4, [x3, #VGIC_V3_CPU_HCR] | ||
58 | str w5, [x3, #VGIC_V3_CPU_VMCR] | ||
59 | str w6, [x3, #VGIC_V3_CPU_MISR] | ||
60 | str w7, [x3, #VGIC_V3_CPU_EISR] | ||
61 | str w8, [x3, #VGIC_V3_CPU_ELRSR] | ||
62 | |||
63 | msr_s ICH_HCR_EL2, xzr | ||
64 | |||
65 | mrs_s x21, ICH_VTR_EL2 | ||
66 | mvn w22, w21 | ||
67 | ubfiz w23, w22, 2, 4 // w23 = (15 - ListRegs) * 4 | ||
68 | |||
69 | adr x24, 1f | ||
70 | add x24, x24, x23 | ||
71 | br x24 | ||
72 | |||
73 | 1: | ||
74 | mrs_s x20, ICH_LR15_EL2 | ||
75 | mrs_s x19, ICH_LR14_EL2 | ||
76 | mrs_s x18, ICH_LR13_EL2 | ||
77 | mrs_s x17, ICH_LR12_EL2 | ||
78 | mrs_s x16, ICH_LR11_EL2 | ||
79 | mrs_s x15, ICH_LR10_EL2 | ||
80 | mrs_s x14, ICH_LR9_EL2 | ||
81 | mrs_s x13, ICH_LR8_EL2 | ||
82 | mrs_s x12, ICH_LR7_EL2 | ||
83 | mrs_s x11, ICH_LR6_EL2 | ||
84 | mrs_s x10, ICH_LR5_EL2 | ||
85 | mrs_s x9, ICH_LR4_EL2 | ||
86 | mrs_s x8, ICH_LR3_EL2 | ||
87 | mrs_s x7, ICH_LR2_EL2 | ||
88 | mrs_s x6, ICH_LR1_EL2 | ||
89 | mrs_s x5, ICH_LR0_EL2 | ||
90 | |||
91 | adr x24, 1f | ||
92 | add x24, x24, x23 | ||
93 | br x24 | ||
94 | |||
95 | 1: | ||
96 | str x20, [x3, #LR_OFFSET(15)] | ||
97 | str x19, [x3, #LR_OFFSET(14)] | ||
98 | str x18, [x3, #LR_OFFSET(13)] | ||
99 | str x17, [x3, #LR_OFFSET(12)] | ||
100 | str x16, [x3, #LR_OFFSET(11)] | ||
101 | str x15, [x3, #LR_OFFSET(10)] | ||
102 | str x14, [x3, #LR_OFFSET(9)] | ||
103 | str x13, [x3, #LR_OFFSET(8)] | ||
104 | str x12, [x3, #LR_OFFSET(7)] | ||
105 | str x11, [x3, #LR_OFFSET(6)] | ||
106 | str x10, [x3, #LR_OFFSET(5)] | ||
107 | str x9, [x3, #LR_OFFSET(4)] | ||
108 | str x8, [x3, #LR_OFFSET(3)] | ||
109 | str x7, [x3, #LR_OFFSET(2)] | ||
110 | str x6, [x3, #LR_OFFSET(1)] | ||
111 | str x5, [x3, #LR_OFFSET(0)] | ||
112 | |||
113 | tbnz w21, #29, 6f // 6 bits | ||
114 | tbz w21, #30, 5f // 5 bits | ||
115 | // 7 bits | ||
116 | mrs_s x20, ICH_AP0R3_EL2 | ||
117 | str w20, [x3, #(VGIC_V3_CPU_AP0R + 3*4)] | ||
118 | mrs_s x19, ICH_AP0R2_EL2 | ||
119 | str w19, [x3, #(VGIC_V3_CPU_AP0R + 2*4)] | ||
120 | 6: mrs_s x18, ICH_AP0R1_EL2 | ||
121 | str w18, [x3, #(VGIC_V3_CPU_AP0R + 1*4)] | ||
122 | 5: mrs_s x17, ICH_AP0R0_EL2 | ||
123 | str w17, [x3, #VGIC_V3_CPU_AP0R] | ||
124 | |||
125 | tbnz w21, #29, 6f // 6 bits | ||
126 | tbz w21, #30, 5f // 5 bits | ||
127 | // 7 bits | ||
128 | mrs_s x20, ICH_AP1R3_EL2 | ||
129 | str w20, [x3, #(VGIC_V3_CPU_AP1R + 3*4)] | ||
130 | mrs_s x19, ICH_AP1R2_EL2 | ||
131 | str w19, [x3, #(VGIC_V3_CPU_AP1R + 2*4)] | ||
132 | 6: mrs_s x18, ICH_AP1R1_EL2 | ||
133 | str w18, [x3, #(VGIC_V3_CPU_AP1R + 1*4)] | ||
134 | 5: mrs_s x17, ICH_AP1R0_EL2 | ||
135 | str w17, [x3, #VGIC_V3_CPU_AP1R] | ||
136 | |||
137 | // Restore SRE_EL1 access and re-enable SRE at EL1. | ||
138 | mrs_s x5, ICC_SRE_EL2 | ||
139 | orr x5, x5, #ICC_SRE_EL2_ENABLE | ||
140 | msr_s ICC_SRE_EL2, x5 | ||
141 | isb | ||
142 | mov x5, #1 | ||
143 | msr_s ICC_SRE_EL1, x5 | ||
144 | .endm | ||
145 | |||
146 | /* | ||
147 | * Restore the VGIC CPU state from memory | ||
148 | * x0: Register pointing to VCPU struct | ||
149 | */ | ||
150 | .macro restore_vgic_v3_state | ||
151 | // Disable SRE_EL1 access. Necessary, otherwise | ||
152 | // ICH_VMCR_EL2.VFIQEn becomes one, and FIQ happens... | ||
153 | msr_s ICC_SRE_EL1, xzr | ||
154 | isb | ||
155 | |||
156 | // Compute the address of struct vgic_cpu | ||
157 | add x3, x0, #VCPU_VGIC_CPU | ||
158 | |||
159 | // Restore all interesting registers | ||
160 | ldr w4, [x3, #VGIC_V3_CPU_HCR] | ||
161 | ldr w5, [x3, #VGIC_V3_CPU_VMCR] | ||
162 | |||
163 | msr_s ICH_HCR_EL2, x4 | ||
164 | msr_s ICH_VMCR_EL2, x5 | ||
165 | |||
166 | mrs_s x21, ICH_VTR_EL2 | ||
167 | |||
168 | tbnz w21, #29, 6f // 6 bits | ||
169 | tbz w21, #30, 5f // 5 bits | ||
170 | // 7 bits | ||
171 | ldr w20, [x3, #(VGIC_V3_CPU_AP1R + 3*4)] | ||
172 | msr_s ICH_AP1R3_EL2, x20 | ||
173 | ldr w19, [x3, #(VGIC_V3_CPU_AP1R + 2*4)] | ||
174 | msr_s ICH_AP1R2_EL2, x19 | ||
175 | 6: ldr w18, [x3, #(VGIC_V3_CPU_AP1R + 1*4)] | ||
176 | msr_s ICH_AP1R1_EL2, x18 | ||
177 | 5: ldr w17, [x3, #VGIC_V3_CPU_AP1R] | ||
178 | msr_s ICH_AP1R0_EL2, x17 | ||
179 | |||
180 | tbnz w21, #29, 6f // 6 bits | ||
181 | tbz w21, #30, 5f // 5 bits | ||
182 | // 7 bits | ||
183 | ldr w20, [x3, #(VGIC_V3_CPU_AP0R + 3*4)] | ||
184 | msr_s ICH_AP0R3_EL2, x20 | ||
185 | ldr w19, [x3, #(VGIC_V3_CPU_AP0R + 2*4)] | ||
186 | msr_s ICH_AP0R2_EL2, x19 | ||
187 | 6: ldr w18, [x3, #(VGIC_V3_CPU_AP0R + 1*4)] | ||
188 | msr_s ICH_AP0R1_EL2, x18 | ||
189 | 5: ldr w17, [x3, #VGIC_V3_CPU_AP0R] | ||
190 | msr_s ICH_AP0R0_EL2, x17 | ||
191 | |||
192 | and w22, w21, #0xf | ||
193 | mvn w22, w21 | ||
194 | ubfiz w23, w22, 2, 4 // w23 = (15 - ListRegs) * 4 | ||
195 | |||
196 | adr x24, 1f | ||
197 | add x24, x24, x23 | ||
198 | br x24 | ||
199 | |||
200 | 1: | ||
201 | ldr x20, [x3, #LR_OFFSET(15)] | ||
202 | ldr x19, [x3, #LR_OFFSET(14)] | ||
203 | ldr x18, [x3, #LR_OFFSET(13)] | ||
204 | ldr x17, [x3, #LR_OFFSET(12)] | ||
205 | ldr x16, [x3, #LR_OFFSET(11)] | ||
206 | ldr x15, [x3, #LR_OFFSET(10)] | ||
207 | ldr x14, [x3, #LR_OFFSET(9)] | ||
208 | ldr x13, [x3, #LR_OFFSET(8)] | ||
209 | ldr x12, [x3, #LR_OFFSET(7)] | ||
210 | ldr x11, [x3, #LR_OFFSET(6)] | ||
211 | ldr x10, [x3, #LR_OFFSET(5)] | ||
212 | ldr x9, [x3, #LR_OFFSET(4)] | ||
213 | ldr x8, [x3, #LR_OFFSET(3)] | ||
214 | ldr x7, [x3, #LR_OFFSET(2)] | ||
215 | ldr x6, [x3, #LR_OFFSET(1)] | ||
216 | ldr x5, [x3, #LR_OFFSET(0)] | ||
217 | |||
218 | adr x24, 1f | ||
219 | add x24, x24, x23 | ||
220 | br x24 | ||
221 | |||
222 | 1: | ||
223 | msr_s ICH_LR15_EL2, x20 | ||
224 | msr_s ICH_LR14_EL2, x19 | ||
225 | msr_s ICH_LR13_EL2, x18 | ||
226 | msr_s ICH_LR12_EL2, x17 | ||
227 | msr_s ICH_LR11_EL2, x16 | ||
228 | msr_s ICH_LR10_EL2, x15 | ||
229 | msr_s ICH_LR9_EL2, x14 | ||
230 | msr_s ICH_LR8_EL2, x13 | ||
231 | msr_s ICH_LR7_EL2, x12 | ||
232 | msr_s ICH_LR6_EL2, x11 | ||
233 | msr_s ICH_LR5_EL2, x10 | ||
234 | msr_s ICH_LR4_EL2, x9 | ||
235 | msr_s ICH_LR3_EL2, x8 | ||
236 | msr_s ICH_LR2_EL2, x7 | ||
237 | msr_s ICH_LR1_EL2, x6 | ||
238 | msr_s ICH_LR0_EL2, x5 | ||
239 | |||
240 | // Ensure that the above will have reached the | ||
241 | // (re)distributors. This ensure the guest will read | ||
242 | // the correct values from the memory-mapped interface. | ||
243 | isb | ||
244 | dsb sy | ||
245 | |||
246 | // Prevent the guest from touching the GIC system registers | ||
247 | mrs_s x5, ICC_SRE_EL2 | ||
248 | and x5, x5, #~ICC_SRE_EL2_ENABLE | ||
249 | msr_s ICC_SRE_EL2, x5 | ||
250 | .endm | ||
251 | |||
252 | ENTRY(__save_vgic_v3_state) | ||
253 | save_vgic_v3_state | ||
254 | ret | ||
255 | ENDPROC(__save_vgic_v3_state) | ||
256 | |||
257 | ENTRY(__restore_vgic_v3_state) | ||
258 | restore_vgic_v3_state | ||
259 | ret | ||
260 | ENDPROC(__restore_vgic_v3_state) | ||
261 | |||
262 | ENTRY(__vgic_v3_get_ich_vtr_el2) | ||
263 | mrs_s x0, ICH_VTR_EL2 | ||
264 | ret | ||
265 | ENDPROC(__vgic_v3_get_ich_vtr_el2) | ||
266 | |||
267 | .popsection | ||
diff --git a/arch/ia64/kvm/Kconfig b/arch/ia64/kvm/Kconfig index 990b86420cc6..3d50ea955c4c 100644 --- a/arch/ia64/kvm/Kconfig +++ b/arch/ia64/kvm/Kconfig | |||
@@ -25,6 +25,7 @@ config KVM | |||
25 | select PREEMPT_NOTIFIERS | 25 | select PREEMPT_NOTIFIERS |
26 | select ANON_INODES | 26 | select ANON_INODES |
27 | select HAVE_KVM_IRQCHIP | 27 | select HAVE_KVM_IRQCHIP |
28 | select HAVE_KVM_IRQFD | ||
28 | select HAVE_KVM_IRQ_ROUTING | 29 | select HAVE_KVM_IRQ_ROUTING |
29 | select KVM_APIC_ARCHITECTURE | 30 | select KVM_APIC_ARCHITECTURE |
30 | select KVM_MMIO | 31 | select KVM_MMIO |
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index 6a4309bb821a..0729ba6acddf 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c | |||
@@ -190,7 +190,7 @@ void kvm_arch_check_processor_compat(void *rtn) | |||
190 | *(int *)rtn = 0; | 190 | *(int *)rtn = 0; |
191 | } | 191 | } |
192 | 192 | ||
193 | int kvm_dev_ioctl_check_extension(long ext) | 193 | int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) |
194 | { | 194 | { |
195 | 195 | ||
196 | int r; | 196 | int r; |
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c index 4fda672cb58e..cd7114147ae7 100644 --- a/arch/mips/kvm/mips.c +++ b/arch/mips/kvm/mips.c | |||
@@ -886,7 +886,7 @@ int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf) | |||
886 | return VM_FAULT_SIGBUS; | 886 | return VM_FAULT_SIGBUS; |
887 | } | 887 | } |
888 | 888 | ||
889 | int kvm_dev_ioctl_check_extension(long ext) | 889 | int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) |
890 | { | 890 | { |
891 | int r; | 891 | int r; |
892 | 892 | ||
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug index 35d16bd2760b..ec2e40f2cc11 100644 --- a/arch/powerpc/Kconfig.debug +++ b/arch/powerpc/Kconfig.debug | |||
@@ -202,9 +202,7 @@ config PPC_EARLY_DEBUG_BEAT | |||
202 | 202 | ||
203 | config PPC_EARLY_DEBUG_44x | 203 | config PPC_EARLY_DEBUG_44x |
204 | bool "Early serial debugging for IBM/AMCC 44x CPUs" | 204 | bool "Early serial debugging for IBM/AMCC 44x CPUs" |
205 | # PPC_EARLY_DEBUG on 440 leaves AS=1 mappings above the TLB high water | 205 | depends on 44x |
206 | # mark, which doesn't work with current 440 KVM. | ||
207 | depends on 44x && !KVM | ||
208 | help | 206 | help |
209 | Select this to enable early debugging for IBM 44x chips via the | 207 | Select this to enable early debugging for IBM 44x chips via the |
210 | inbuilt serial port. If you enable this, ensure you set | 208 | inbuilt serial port. If you enable this, ensure you set |
diff --git a/arch/powerpc/configs/ppc44x_defconfig b/arch/powerpc/configs/ppc44x_defconfig index ccf66b9060a6..924e10df1844 100644 --- a/arch/powerpc/configs/ppc44x_defconfig +++ b/arch/powerpc/configs/ppc44x_defconfig | |||
@@ -127,4 +127,3 @@ CONFIG_CRYPTO_PCBC=y | |||
127 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 127 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
128 | # CONFIG_CRYPTO_HW is not set | 128 | # CONFIG_CRYPTO_HW is not set |
129 | CONFIG_VIRTUALIZATION=y | 129 | CONFIG_VIRTUALIZATION=y |
130 | CONFIG_KVM_440=y | ||
diff --git a/arch/powerpc/include/asm/asm-compat.h b/arch/powerpc/include/asm/asm-compat.h index 4b237aa35660..21be8ae8f809 100644 --- a/arch/powerpc/include/asm/asm-compat.h +++ b/arch/powerpc/include/asm/asm-compat.h | |||
@@ -34,10 +34,14 @@ | |||
34 | #define PPC_MIN_STKFRM 112 | 34 | #define PPC_MIN_STKFRM 112 |
35 | 35 | ||
36 | #ifdef __BIG_ENDIAN__ | 36 | #ifdef __BIG_ENDIAN__ |
37 | #define LWZX_BE stringify_in_c(lwzx) | ||
37 | #define LDX_BE stringify_in_c(ldx) | 38 | #define LDX_BE stringify_in_c(ldx) |
39 | #define STWX_BE stringify_in_c(stwx) | ||
38 | #define STDX_BE stringify_in_c(stdx) | 40 | #define STDX_BE stringify_in_c(stdx) |
39 | #else | 41 | #else |
42 | #define LWZX_BE stringify_in_c(lwbrx) | ||
40 | #define LDX_BE stringify_in_c(ldbrx) | 43 | #define LDX_BE stringify_in_c(ldbrx) |
44 | #define STWX_BE stringify_in_c(stwbrx) | ||
41 | #define STDX_BE stringify_in_c(stdbrx) | 45 | #define STDX_BE stringify_in_c(stdbrx) |
42 | #endif | 46 | #endif |
43 | 47 | ||
diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h index ed0afc1e44a4..34a05a1a990b 100644 --- a/arch/powerpc/include/asm/cache.h +++ b/arch/powerpc/include/asm/cache.h | |||
@@ -3,6 +3,7 @@ | |||
3 | 3 | ||
4 | #ifdef __KERNEL__ | 4 | #ifdef __KERNEL__ |
5 | 5 | ||
6 | #include <asm/reg.h> | ||
6 | 7 | ||
7 | /* bytes per L1 cache line */ | 8 | /* bytes per L1 cache line */ |
8 | #if defined(CONFIG_8xx) || defined(CONFIG_403GCX) | 9 | #if defined(CONFIG_8xx) || defined(CONFIG_403GCX) |
@@ -39,6 +40,12 @@ struct ppc64_caches { | |||
39 | }; | 40 | }; |
40 | 41 | ||
41 | extern struct ppc64_caches ppc64_caches; | 42 | extern struct ppc64_caches ppc64_caches; |
43 | |||
44 | static inline void logmpp(u64 x) | ||
45 | { | ||
46 | asm volatile(PPC_LOGMPP(R1) : : "r" (x)); | ||
47 | } | ||
48 | |||
42 | #endif /* __powerpc64__ && ! __ASSEMBLY__ */ | 49 | #endif /* __powerpc64__ && ! __ASSEMBLY__ */ |
43 | 50 | ||
44 | #if defined(__ASSEMBLY__) | 51 | #if defined(__ASSEMBLY__) |
diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h index 5dbbb29f5c3e..85bc8c0d257b 100644 --- a/arch/powerpc/include/asm/hvcall.h +++ b/arch/powerpc/include/asm/hvcall.h | |||
@@ -279,6 +279,12 @@ | |||
279 | #define H_GET_24X7_DATA 0xF07C | 279 | #define H_GET_24X7_DATA 0xF07C |
280 | #define H_GET_PERF_COUNTER_INFO 0xF080 | 280 | #define H_GET_PERF_COUNTER_INFO 0xF080 |
281 | 281 | ||
282 | /* Values for 2nd argument to H_SET_MODE */ | ||
283 | #define H_SET_MODE_RESOURCE_SET_CIABR 1 | ||
284 | #define H_SET_MODE_RESOURCE_SET_DAWR 2 | ||
285 | #define H_SET_MODE_RESOURCE_ADDR_TRANS_MODE 3 | ||
286 | #define H_SET_MODE_RESOURCE_LE 4 | ||
287 | |||
282 | #ifndef __ASSEMBLY__ | 288 | #ifndef __ASSEMBLY__ |
283 | 289 | ||
284 | /** | 290 | /** |
diff --git a/arch/powerpc/include/asm/kvm_44x.h b/arch/powerpc/include/asm/kvm_44x.h deleted file mode 100644 index a0e57618ff33..000000000000 --- a/arch/powerpc/include/asm/kvm_44x.h +++ /dev/null | |||
@@ -1,67 +0,0 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify | ||
3 | * it under the terms of the GNU General Public License, version 2, as | ||
4 | * published by the Free Software Foundation. | ||
5 | * | ||
6 | * This program is distributed in the hope that it will be useful, | ||
7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
9 | * GNU General Public License for more details. | ||
10 | * | ||
11 | * You should have received a copy of the GNU General Public License | ||
12 | * along with this program; if not, write to the Free Software | ||
13 | * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
14 | * | ||
15 | * Copyright IBM Corp. 2008 | ||
16 | * | ||
17 | * Authors: Hollis Blanchard <hollisb@us.ibm.com> | ||
18 | */ | ||
19 | |||
20 | #ifndef __ASM_44X_H__ | ||
21 | #define __ASM_44X_H__ | ||
22 | |||
23 | #include <linux/kvm_host.h> | ||
24 | |||
25 | #define PPC44x_TLB_SIZE 64 | ||
26 | |||
27 | /* If the guest is expecting it, this can be as large as we like; we'd just | ||
28 | * need to find some way of advertising it. */ | ||
29 | #define KVM44x_GUEST_TLB_SIZE 64 | ||
30 | |||
31 | struct kvmppc_44x_tlbe { | ||
32 | u32 tid; /* Only the low 8 bits are used. */ | ||
33 | u32 word0; | ||
34 | u32 word1; | ||
35 | u32 word2; | ||
36 | }; | ||
37 | |||
38 | struct kvmppc_44x_shadow_ref { | ||
39 | struct page *page; | ||
40 | u16 gtlb_index; | ||
41 | u8 writeable; | ||
42 | u8 tid; | ||
43 | }; | ||
44 | |||
45 | struct kvmppc_vcpu_44x { | ||
46 | /* Unmodified copy of the guest's TLB. */ | ||
47 | struct kvmppc_44x_tlbe guest_tlb[KVM44x_GUEST_TLB_SIZE]; | ||
48 | |||
49 | /* References to guest pages in the hardware TLB. */ | ||
50 | struct kvmppc_44x_shadow_ref shadow_refs[PPC44x_TLB_SIZE]; | ||
51 | |||
52 | /* State of the shadow TLB at guest context switch time. */ | ||
53 | struct kvmppc_44x_tlbe shadow_tlb[PPC44x_TLB_SIZE]; | ||
54 | u8 shadow_tlb_mod[PPC44x_TLB_SIZE]; | ||
55 | |||
56 | struct kvm_vcpu vcpu; | ||
57 | }; | ||
58 | |||
59 | static inline struct kvmppc_vcpu_44x *to_44x(struct kvm_vcpu *vcpu) | ||
60 | { | ||
61 | return container_of(vcpu, struct kvmppc_vcpu_44x, vcpu); | ||
62 | } | ||
63 | |||
64 | void kvmppc_44x_tlb_put(struct kvm_vcpu *vcpu); | ||
65 | void kvmppc_44x_tlb_load(struct kvm_vcpu *vcpu); | ||
66 | |||
67 | #endif /* __ASM_44X_H__ */ | ||
diff --git a/arch/powerpc/include/asm/kvm_asm.h b/arch/powerpc/include/asm/kvm_asm.h index ecf7e133a4f2..465dfcb82c92 100644 --- a/arch/powerpc/include/asm/kvm_asm.h +++ b/arch/powerpc/include/asm/kvm_asm.h | |||
@@ -33,7 +33,6 @@ | |||
33 | /* IVPR must be 64KiB-aligned. */ | 33 | /* IVPR must be 64KiB-aligned. */ |
34 | #define VCPU_SIZE_ORDER 4 | 34 | #define VCPU_SIZE_ORDER 4 |
35 | #define VCPU_SIZE_LOG (VCPU_SIZE_ORDER + 12) | 35 | #define VCPU_SIZE_LOG (VCPU_SIZE_ORDER + 12) |
36 | #define VCPU_TLB_PGSZ PPC44x_TLB_64K | ||
37 | #define VCPU_SIZE_BYTES (1<<VCPU_SIZE_LOG) | 36 | #define VCPU_SIZE_BYTES (1<<VCPU_SIZE_LOG) |
38 | 37 | ||
39 | #define BOOKE_INTERRUPT_CRITICAL 0 | 38 | #define BOOKE_INTERRUPT_CRITICAL 0 |
@@ -132,6 +131,7 @@ | |||
132 | #define BOOK3S_HFLAG_NATIVE_PS 0x8 | 131 | #define BOOK3S_HFLAG_NATIVE_PS 0x8 |
133 | #define BOOK3S_HFLAG_MULTI_PGSIZE 0x10 | 132 | #define BOOK3S_HFLAG_MULTI_PGSIZE 0x10 |
134 | #define BOOK3S_HFLAG_NEW_TLBIE 0x20 | 133 | #define BOOK3S_HFLAG_NEW_TLBIE 0x20 |
134 | #define BOOK3S_HFLAG_SPLIT_HACK 0x40 | ||
135 | 135 | ||
136 | #define RESUME_FLAG_NV (1<<0) /* Reload guest nonvolatile state? */ | 136 | #define RESUME_FLAG_NV (1<<0) /* Reload guest nonvolatile state? */ |
137 | #define RESUME_FLAG_HOST (1<<1) /* Resume host? */ | 137 | #define RESUME_FLAG_HOST (1<<1) /* Resume host? */ |
diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index f52f65694527..6acf0c2a0f99 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h | |||
@@ -83,8 +83,6 @@ struct kvmppc_vcpu_book3s { | |||
83 | u64 sdr1; | 83 | u64 sdr1; |
84 | u64 hior; | 84 | u64 hior; |
85 | u64 msr_mask; | 85 | u64 msr_mask; |
86 | u64 purr_offset; | ||
87 | u64 spurr_offset; | ||
88 | #ifdef CONFIG_PPC_BOOK3S_32 | 86 | #ifdef CONFIG_PPC_BOOK3S_32 |
89 | u32 vsid_pool[VSID_POOL_SIZE]; | 87 | u32 vsid_pool[VSID_POOL_SIZE]; |
90 | u32 vsid_next; | 88 | u32 vsid_next; |
@@ -148,9 +146,10 @@ extern void kvmppc_mmu_invalidate_pte(struct kvm_vcpu *vcpu, struct hpte_cache * | |||
148 | extern int kvmppc_mmu_hpte_sysinit(void); | 146 | extern int kvmppc_mmu_hpte_sysinit(void); |
149 | extern void kvmppc_mmu_hpte_sysexit(void); | 147 | extern void kvmppc_mmu_hpte_sysexit(void); |
150 | extern int kvmppc_mmu_hv_init(void); | 148 | extern int kvmppc_mmu_hv_init(void); |
149 | extern int kvmppc_book3s_hcall_implemented(struct kvm *kvm, unsigned long hc); | ||
151 | 150 | ||
151 | /* XXX remove this export when load_last_inst() is generic */ | ||
152 | extern int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, bool data); | 152 | extern int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, bool data); |
153 | extern int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, bool data); | ||
154 | extern void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec); | 153 | extern void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec); |
155 | extern void kvmppc_book3s_dequeue_irqprio(struct kvm_vcpu *vcpu, | 154 | extern void kvmppc_book3s_dequeue_irqprio(struct kvm_vcpu *vcpu, |
156 | unsigned int vec); | 155 | unsigned int vec); |
@@ -159,13 +158,13 @@ extern void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat, | |||
159 | bool upper, u32 val); | 158 | bool upper, u32 val); |
160 | extern void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr); | 159 | extern void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr); |
161 | extern int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu); | 160 | extern int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu); |
162 | extern pfn_t kvmppc_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn, bool writing, | 161 | extern pfn_t kvmppc_gpa_to_pfn(struct kvm_vcpu *vcpu, gpa_t gpa, bool writing, |
163 | bool *writable); | 162 | bool *writable); |
164 | extern void kvmppc_add_revmap_chain(struct kvm *kvm, struct revmap_entry *rev, | 163 | extern void kvmppc_add_revmap_chain(struct kvm *kvm, struct revmap_entry *rev, |
165 | unsigned long *rmap, long pte_index, int realmode); | 164 | unsigned long *rmap, long pte_index, int realmode); |
166 | extern void kvmppc_invalidate_hpte(struct kvm *kvm, unsigned long *hptep, | 165 | extern void kvmppc_invalidate_hpte(struct kvm *kvm, __be64 *hptep, |
167 | unsigned long pte_index); | 166 | unsigned long pte_index); |
168 | void kvmppc_clear_ref_hpte(struct kvm *kvm, unsigned long *hptep, | 167 | void kvmppc_clear_ref_hpte(struct kvm *kvm, __be64 *hptep, |
169 | unsigned long pte_index); | 168 | unsigned long pte_index); |
170 | extern void *kvmppc_pin_guest_page(struct kvm *kvm, unsigned long addr, | 169 | extern void *kvmppc_pin_guest_page(struct kvm *kvm, unsigned long addr, |
171 | unsigned long *nb_ret); | 170 | unsigned long *nb_ret); |
@@ -183,12 +182,16 @@ extern long kvmppc_hv_get_dirty_log(struct kvm *kvm, | |||
183 | struct kvm_memory_slot *memslot, unsigned long *map); | 182 | struct kvm_memory_slot *memslot, unsigned long *map); |
184 | extern void kvmppc_update_lpcr(struct kvm *kvm, unsigned long lpcr, | 183 | extern void kvmppc_update_lpcr(struct kvm *kvm, unsigned long lpcr, |
185 | unsigned long mask); | 184 | unsigned long mask); |
185 | extern void kvmppc_set_fscr(struct kvm_vcpu *vcpu, u64 fscr); | ||
186 | 186 | ||
187 | extern void kvmppc_entry_trampoline(void); | 187 | extern void kvmppc_entry_trampoline(void); |
188 | extern void kvmppc_hv_entry_trampoline(void); | 188 | extern void kvmppc_hv_entry_trampoline(void); |
189 | extern u32 kvmppc_alignment_dsisr(struct kvm_vcpu *vcpu, unsigned int inst); | 189 | extern u32 kvmppc_alignment_dsisr(struct kvm_vcpu *vcpu, unsigned int inst); |
190 | extern ulong kvmppc_alignment_dar(struct kvm_vcpu *vcpu, unsigned int inst); | 190 | extern ulong kvmppc_alignment_dar(struct kvm_vcpu *vcpu, unsigned int inst); |
191 | extern int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd); | 191 | extern int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd); |
192 | extern void kvmppc_pr_init_default_hcalls(struct kvm *kvm); | ||
193 | extern int kvmppc_hcall_impl_pr(unsigned long cmd); | ||
194 | extern int kvmppc_hcall_impl_hv_realmode(unsigned long cmd); | ||
192 | extern void kvmppc_copy_to_svcpu(struct kvmppc_book3s_shadow_vcpu *svcpu, | 195 | extern void kvmppc_copy_to_svcpu(struct kvmppc_book3s_shadow_vcpu *svcpu, |
193 | struct kvm_vcpu *vcpu); | 196 | struct kvm_vcpu *vcpu); |
194 | extern void kvmppc_copy_from_svcpu(struct kvm_vcpu *vcpu, | 197 | extern void kvmppc_copy_from_svcpu(struct kvm_vcpu *vcpu, |
@@ -274,32 +277,6 @@ static inline bool kvmppc_need_byteswap(struct kvm_vcpu *vcpu) | |||
274 | return (kvmppc_get_msr(vcpu) & MSR_LE) != (MSR_KERNEL & MSR_LE); | 277 | return (kvmppc_get_msr(vcpu) & MSR_LE) != (MSR_KERNEL & MSR_LE); |
275 | } | 278 | } |
276 | 279 | ||
277 | static inline u32 kvmppc_get_last_inst_internal(struct kvm_vcpu *vcpu, ulong pc) | ||
278 | { | ||
279 | /* Load the instruction manually if it failed to do so in the | ||
280 | * exit path */ | ||
281 | if (vcpu->arch.last_inst == KVM_INST_FETCH_FAILED) | ||
282 | kvmppc_ld(vcpu, &pc, sizeof(u32), &vcpu->arch.last_inst, false); | ||
283 | |||
284 | return kvmppc_need_byteswap(vcpu) ? swab32(vcpu->arch.last_inst) : | ||
285 | vcpu->arch.last_inst; | ||
286 | } | ||
287 | |||
288 | static inline u32 kvmppc_get_last_inst(struct kvm_vcpu *vcpu) | ||
289 | { | ||
290 | return kvmppc_get_last_inst_internal(vcpu, kvmppc_get_pc(vcpu)); | ||
291 | } | ||
292 | |||
293 | /* | ||
294 | * Like kvmppc_get_last_inst(), but for fetching a sc instruction. | ||
295 | * Because the sc instruction sets SRR0 to point to the following | ||
296 | * instruction, we have to fetch from pc - 4. | ||
297 | */ | ||
298 | static inline u32 kvmppc_get_last_sc(struct kvm_vcpu *vcpu) | ||
299 | { | ||
300 | return kvmppc_get_last_inst_internal(vcpu, kvmppc_get_pc(vcpu) - 4); | ||
301 | } | ||
302 | |||
303 | static inline ulong kvmppc_get_fault_dar(struct kvm_vcpu *vcpu) | 280 | static inline ulong kvmppc_get_fault_dar(struct kvm_vcpu *vcpu) |
304 | { | 281 | { |
305 | return vcpu->arch.fault_dar; | 282 | return vcpu->arch.fault_dar; |
@@ -310,6 +287,13 @@ static inline bool is_kvmppc_resume_guest(int r) | |||
310 | return (r == RESUME_GUEST || r == RESUME_GUEST_NV); | 287 | return (r == RESUME_GUEST || r == RESUME_GUEST_NV); |
311 | } | 288 | } |
312 | 289 | ||
290 | static inline bool is_kvmppc_hv_enabled(struct kvm *kvm); | ||
291 | static inline bool kvmppc_supports_magic_page(struct kvm_vcpu *vcpu) | ||
292 | { | ||
293 | /* Only PR KVM supports the magic page */ | ||
294 | return !is_kvmppc_hv_enabled(vcpu->kvm); | ||
295 | } | ||
296 | |||
313 | /* Magic register values loaded into r3 and r4 before the 'sc' assembly | 297 | /* Magic register values loaded into r3 and r4 before the 'sc' assembly |
314 | * instruction for the OSI hypercalls */ | 298 | * instruction for the OSI hypercalls */ |
315 | #define OSI_SC_MAGIC_R3 0x113724FA | 299 | #define OSI_SC_MAGIC_R3 0x113724FA |
@@ -322,4 +306,7 @@ static inline bool is_kvmppc_resume_guest(int r) | |||
322 | /* LPIDs we support with this build -- runtime limit may be lower */ | 306 | /* LPIDs we support with this build -- runtime limit may be lower */ |
323 | #define KVMPPC_NR_LPIDS (LPID_RSVD + 1) | 307 | #define KVMPPC_NR_LPIDS (LPID_RSVD + 1) |
324 | 308 | ||
309 | #define SPLIT_HACK_MASK 0xff000000 | ||
310 | #define SPLIT_HACK_OFFS 0xfb000000 | ||
311 | |||
325 | #endif /* __ASM_KVM_BOOK3S_H__ */ | 312 | #endif /* __ASM_KVM_BOOK3S_H__ */ |
diff --git a/arch/powerpc/include/asm/kvm_book3s_64.h b/arch/powerpc/include/asm/kvm_book3s_64.h index d645428a65a4..0aa817933e6a 100644 --- a/arch/powerpc/include/asm/kvm_book3s_64.h +++ b/arch/powerpc/include/asm/kvm_book3s_64.h | |||
@@ -59,20 +59,29 @@ extern unsigned long kvm_rma_pages; | |||
59 | /* These bits are reserved in the guest view of the HPTE */ | 59 | /* These bits are reserved in the guest view of the HPTE */ |
60 | #define HPTE_GR_RESERVED HPTE_GR_MODIFIED | 60 | #define HPTE_GR_RESERVED HPTE_GR_MODIFIED |
61 | 61 | ||
62 | static inline long try_lock_hpte(unsigned long *hpte, unsigned long bits) | 62 | static inline long try_lock_hpte(__be64 *hpte, unsigned long bits) |
63 | { | 63 | { |
64 | unsigned long tmp, old; | 64 | unsigned long tmp, old; |
65 | __be64 be_lockbit, be_bits; | ||
66 | |||
67 | /* | ||
68 | * We load/store in native endian, but the HTAB is in big endian. If | ||
69 | * we byte swap all data we apply on the PTE we're implicitly correct | ||
70 | * again. | ||
71 | */ | ||
72 | be_lockbit = cpu_to_be64(HPTE_V_HVLOCK); | ||
73 | be_bits = cpu_to_be64(bits); | ||
65 | 74 | ||
66 | asm volatile(" ldarx %0,0,%2\n" | 75 | asm volatile(" ldarx %0,0,%2\n" |
67 | " and. %1,%0,%3\n" | 76 | " and. %1,%0,%3\n" |
68 | " bne 2f\n" | 77 | " bne 2f\n" |
69 | " ori %0,%0,%4\n" | 78 | " or %0,%0,%4\n" |
70 | " stdcx. %0,0,%2\n" | 79 | " stdcx. %0,0,%2\n" |
71 | " beq+ 2f\n" | 80 | " beq+ 2f\n" |
72 | " mr %1,%3\n" | 81 | " mr %1,%3\n" |
73 | "2: isync" | 82 | "2: isync" |
74 | : "=&r" (tmp), "=&r" (old) | 83 | : "=&r" (tmp), "=&r" (old) |
75 | : "r" (hpte), "r" (bits), "i" (HPTE_V_HVLOCK) | 84 | : "r" (hpte), "r" (be_bits), "r" (be_lockbit) |
76 | : "cc", "memory"); | 85 | : "cc", "memory"); |
77 | return old == 0; | 86 | return old == 0; |
78 | } | 87 | } |
@@ -110,16 +119,12 @@ static inline int __hpte_actual_psize(unsigned int lp, int psize) | |||
110 | static inline unsigned long compute_tlbie_rb(unsigned long v, unsigned long r, | 119 | static inline unsigned long compute_tlbie_rb(unsigned long v, unsigned long r, |
111 | unsigned long pte_index) | 120 | unsigned long pte_index) |
112 | { | 121 | { |
113 | int b_psize, a_psize; | 122 | int b_psize = MMU_PAGE_4K, a_psize = MMU_PAGE_4K; |
114 | unsigned int penc; | 123 | unsigned int penc; |
115 | unsigned long rb = 0, va_low, sllp; | 124 | unsigned long rb = 0, va_low, sllp; |
116 | unsigned int lp = (r >> LP_SHIFT) & ((1 << LP_BITS) - 1); | 125 | unsigned int lp = (r >> LP_SHIFT) & ((1 << LP_BITS) - 1); |
117 | 126 | ||
118 | if (!(v & HPTE_V_LARGE)) { | 127 | if (v & HPTE_V_LARGE) { |
119 | /* both base and actual psize is 4k */ | ||
120 | b_psize = MMU_PAGE_4K; | ||
121 | a_psize = MMU_PAGE_4K; | ||
122 | } else { | ||
123 | for (b_psize = 0; b_psize < MMU_PAGE_COUNT; b_psize++) { | 128 | for (b_psize = 0; b_psize < MMU_PAGE_COUNT; b_psize++) { |
124 | 129 | ||
125 | /* valid entries have a shift value */ | 130 | /* valid entries have a shift value */ |
@@ -142,6 +147,8 @@ static inline unsigned long compute_tlbie_rb(unsigned long v, unsigned long r, | |||
142 | */ | 147 | */ |
143 | /* This covers 14..54 bits of va*/ | 148 | /* This covers 14..54 bits of va*/ |
144 | rb = (v & ~0x7fUL) << 16; /* AVA field */ | 149 | rb = (v & ~0x7fUL) << 16; /* AVA field */ |
150 | |||
151 | rb |= v >> (62 - 8); /* B field */ | ||
145 | /* | 152 | /* |
146 | * AVA in v had cleared lower 23 bits. We need to derive | 153 | * AVA in v had cleared lower 23 bits. We need to derive |
147 | * that from pteg index | 154 | * that from pteg index |
@@ -172,10 +179,10 @@ static inline unsigned long compute_tlbie_rb(unsigned long v, unsigned long r, | |||
172 | { | 179 | { |
173 | int aval_shift; | 180 | int aval_shift; |
174 | /* | 181 | /* |
175 | * remaining 7bits of AVA/LP fields | 182 | * remaining bits of AVA/LP fields |
176 | * Also contain the rr bits of LP | 183 | * Also contain the rr bits of LP |
177 | */ | 184 | */ |
178 | rb |= (va_low & 0x7f) << 16; | 185 | rb |= (va_low << mmu_psize_defs[b_psize].shift) & 0x7ff000; |
179 | /* | 186 | /* |
180 | * Now clear not needed LP bits based on actual psize | 187 | * Now clear not needed LP bits based on actual psize |
181 | */ | 188 | */ |
diff --git a/arch/powerpc/include/asm/kvm_booke.h b/arch/powerpc/include/asm/kvm_booke.h index c7aed6105ff9..f7aa5cc395c4 100644 --- a/arch/powerpc/include/asm/kvm_booke.h +++ b/arch/powerpc/include/asm/kvm_booke.h | |||
@@ -69,11 +69,6 @@ static inline bool kvmppc_need_byteswap(struct kvm_vcpu *vcpu) | |||
69 | return false; | 69 | return false; |
70 | } | 70 | } |
71 | 71 | ||
72 | static inline u32 kvmppc_get_last_inst(struct kvm_vcpu *vcpu) | ||
73 | { | ||
74 | return vcpu->arch.last_inst; | ||
75 | } | ||
76 | |||
77 | static inline void kvmppc_set_ctr(struct kvm_vcpu *vcpu, ulong val) | 72 | static inline void kvmppc_set_ctr(struct kvm_vcpu *vcpu, ulong val) |
78 | { | 73 | { |
79 | vcpu->arch.ctr = val; | 74 | vcpu->arch.ctr = val; |
@@ -108,4 +103,14 @@ static inline ulong kvmppc_get_fault_dar(struct kvm_vcpu *vcpu) | |||
108 | { | 103 | { |
109 | return vcpu->arch.fault_dear; | 104 | return vcpu->arch.fault_dear; |
110 | } | 105 | } |
106 | |||
107 | static inline bool kvmppc_supports_magic_page(struct kvm_vcpu *vcpu) | ||
108 | { | ||
109 | /* Magic page is only supported on e500v2 */ | ||
110 | #ifdef CONFIG_KVM_E500V2 | ||
111 | return true; | ||
112 | #else | ||
113 | return false; | ||
114 | #endif | ||
115 | } | ||
111 | #endif /* __ASM_KVM_BOOKE_H__ */ | 116 | #endif /* __ASM_KVM_BOOKE_H__ */ |
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index bb66d8b8efdf..98d9dd50d063 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <asm/processor.h> | 34 | #include <asm/processor.h> |
35 | #include <asm/page.h> | 35 | #include <asm/page.h> |
36 | #include <asm/cacheflush.h> | 36 | #include <asm/cacheflush.h> |
37 | #include <asm/hvcall.h> | ||
37 | 38 | ||
38 | #define KVM_MAX_VCPUS NR_CPUS | 39 | #define KVM_MAX_VCPUS NR_CPUS |
39 | #define KVM_MAX_VCORES NR_CPUS | 40 | #define KVM_MAX_VCORES NR_CPUS |
@@ -48,7 +49,6 @@ | |||
48 | #define KVM_NR_IRQCHIPS 1 | 49 | #define KVM_NR_IRQCHIPS 1 |
49 | #define KVM_IRQCHIP_NUM_PINS 256 | 50 | #define KVM_IRQCHIP_NUM_PINS 256 |
50 | 51 | ||
51 | #if !defined(CONFIG_KVM_440) | ||
52 | #include <linux/mmu_notifier.h> | 52 | #include <linux/mmu_notifier.h> |
53 | 53 | ||
54 | #define KVM_ARCH_WANT_MMU_NOTIFIER | 54 | #define KVM_ARCH_WANT_MMU_NOTIFIER |
@@ -61,8 +61,6 @@ extern int kvm_age_hva(struct kvm *kvm, unsigned long hva); | |||
61 | extern int kvm_test_age_hva(struct kvm *kvm, unsigned long hva); | 61 | extern int kvm_test_age_hva(struct kvm *kvm, unsigned long hva); |
62 | extern void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); | 62 | extern void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); |
63 | 63 | ||
64 | #endif | ||
65 | |||
66 | #define HPTEG_CACHE_NUM (1 << 15) | 64 | #define HPTEG_CACHE_NUM (1 << 15) |
67 | #define HPTEG_HASH_BITS_PTE 13 | 65 | #define HPTEG_HASH_BITS_PTE 13 |
68 | #define HPTEG_HASH_BITS_PTE_LONG 12 | 66 | #define HPTEG_HASH_BITS_PTE_LONG 12 |
@@ -96,7 +94,6 @@ struct kvm_vm_stat { | |||
96 | struct kvm_vcpu_stat { | 94 | struct kvm_vcpu_stat { |
97 | u32 sum_exits; | 95 | u32 sum_exits; |
98 | u32 mmio_exits; | 96 | u32 mmio_exits; |
99 | u32 dcr_exits; | ||
100 | u32 signal_exits; | 97 | u32 signal_exits; |
101 | u32 light_exits; | 98 | u32 light_exits; |
102 | /* Account for special types of light exits: */ | 99 | /* Account for special types of light exits: */ |
@@ -113,22 +110,21 @@ struct kvm_vcpu_stat { | |||
113 | u32 halt_wakeup; | 110 | u32 halt_wakeup; |
114 | u32 dbell_exits; | 111 | u32 dbell_exits; |
115 | u32 gdbell_exits; | 112 | u32 gdbell_exits; |
113 | u32 ld; | ||
114 | u32 st; | ||
116 | #ifdef CONFIG_PPC_BOOK3S | 115 | #ifdef CONFIG_PPC_BOOK3S |
117 | u32 pf_storage; | 116 | u32 pf_storage; |
118 | u32 pf_instruc; | 117 | u32 pf_instruc; |
119 | u32 sp_storage; | 118 | u32 sp_storage; |
120 | u32 sp_instruc; | 119 | u32 sp_instruc; |
121 | u32 queue_intr; | 120 | u32 queue_intr; |
122 | u32 ld; | ||
123 | u32 ld_slow; | 121 | u32 ld_slow; |
124 | u32 st; | ||
125 | u32 st_slow; | 122 | u32 st_slow; |
126 | #endif | 123 | #endif |
127 | }; | 124 | }; |
128 | 125 | ||
129 | enum kvm_exit_types { | 126 | enum kvm_exit_types { |
130 | MMIO_EXITS, | 127 | MMIO_EXITS, |
131 | DCR_EXITS, | ||
132 | SIGNAL_EXITS, | 128 | SIGNAL_EXITS, |
133 | ITLB_REAL_MISS_EXITS, | 129 | ITLB_REAL_MISS_EXITS, |
134 | ITLB_VIRT_MISS_EXITS, | 130 | ITLB_VIRT_MISS_EXITS, |
@@ -254,7 +250,6 @@ struct kvm_arch { | |||
254 | atomic_t hpte_mod_interest; | 250 | atomic_t hpte_mod_interest; |
255 | spinlock_t slot_phys_lock; | 251 | spinlock_t slot_phys_lock; |
256 | cpumask_t need_tlb_flush; | 252 | cpumask_t need_tlb_flush; |
257 | struct kvmppc_vcore *vcores[KVM_MAX_VCORES]; | ||
258 | int hpt_cma_alloc; | 253 | int hpt_cma_alloc; |
259 | #endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */ | 254 | #endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */ |
260 | #ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE | 255 | #ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE |
@@ -263,6 +258,7 @@ struct kvm_arch { | |||
263 | #ifdef CONFIG_PPC_BOOK3S_64 | 258 | #ifdef CONFIG_PPC_BOOK3S_64 |
264 | struct list_head spapr_tce_tables; | 259 | struct list_head spapr_tce_tables; |
265 | struct list_head rtas_tokens; | 260 | struct list_head rtas_tokens; |
261 | DECLARE_BITMAP(enabled_hcalls, MAX_HCALL_OPCODE/4 + 1); | ||
266 | #endif | 262 | #endif |
267 | #ifdef CONFIG_KVM_MPIC | 263 | #ifdef CONFIG_KVM_MPIC |
268 | struct openpic *mpic; | 264 | struct openpic *mpic; |
@@ -271,6 +267,10 @@ struct kvm_arch { | |||
271 | struct kvmppc_xics *xics; | 267 | struct kvmppc_xics *xics; |
272 | #endif | 268 | #endif |
273 | struct kvmppc_ops *kvm_ops; | 269 | struct kvmppc_ops *kvm_ops; |
270 | #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE | ||
271 | /* This array can grow quite large, keep it at the end */ | ||
272 | struct kvmppc_vcore *vcores[KVM_MAX_VCORES]; | ||
273 | #endif | ||
274 | }; | 274 | }; |
275 | 275 | ||
276 | /* | 276 | /* |
@@ -305,6 +305,8 @@ struct kvmppc_vcore { | |||
305 | u32 arch_compat; | 305 | u32 arch_compat; |
306 | ulong pcr; | 306 | ulong pcr; |
307 | ulong dpdes; /* doorbell state (POWER8) */ | 307 | ulong dpdes; /* doorbell state (POWER8) */ |
308 | void *mpp_buffer; /* Micro Partition Prefetch buffer */ | ||
309 | bool mpp_buffer_is_valid; | ||
308 | }; | 310 | }; |
309 | 311 | ||
310 | #define VCORE_ENTRY_COUNT(vc) ((vc)->entry_exit_count & 0xff) | 312 | #define VCORE_ENTRY_COUNT(vc) ((vc)->entry_exit_count & 0xff) |
@@ -503,8 +505,10 @@ struct kvm_vcpu_arch { | |||
503 | #ifdef CONFIG_BOOKE | 505 | #ifdef CONFIG_BOOKE |
504 | u32 decar; | 506 | u32 decar; |
505 | #endif | 507 | #endif |
506 | u32 tbl; | 508 | /* Time base value when we entered the guest */ |
507 | u32 tbu; | 509 | u64 entry_tb; |
510 | u64 entry_vtb; | ||
511 | u64 entry_ic; | ||
508 | u32 tcr; | 512 | u32 tcr; |
509 | ulong tsr; /* we need to perform set/clr_bits() which requires ulong */ | 513 | ulong tsr; /* we need to perform set/clr_bits() which requires ulong */ |
510 | u32 ivor[64]; | 514 | u32 ivor[64]; |
@@ -580,6 +584,8 @@ struct kvm_vcpu_arch { | |||
580 | u32 mmucfg; | 584 | u32 mmucfg; |
581 | u32 eptcfg; | 585 | u32 eptcfg; |
582 | u32 epr; | 586 | u32 epr; |
587 | u64 sprg9; | ||
588 | u32 pwrmgtcr0; | ||
583 | u32 crit_save; | 589 | u32 crit_save; |
584 | /* guest debug registers*/ | 590 | /* guest debug registers*/ |
585 | struct debug_reg dbg_reg; | 591 | struct debug_reg dbg_reg; |
@@ -593,8 +599,6 @@ struct kvm_vcpu_arch { | |||
593 | u8 io_gpr; /* GPR used as IO source/target */ | 599 | u8 io_gpr; /* GPR used as IO source/target */ |
594 | u8 mmio_is_bigendian; | 600 | u8 mmio_is_bigendian; |
595 | u8 mmio_sign_extend; | 601 | u8 mmio_sign_extend; |
596 | u8 dcr_needed; | ||
597 | u8 dcr_is_write; | ||
598 | u8 osi_needed; | 602 | u8 osi_needed; |
599 | u8 osi_enabled; | 603 | u8 osi_enabled; |
600 | u8 papr_enabled; | 604 | u8 papr_enabled; |
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index 9c89cdd067a6..fb86a2299d8a 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h | |||
@@ -41,12 +41,26 @@ | |||
41 | enum emulation_result { | 41 | enum emulation_result { |
42 | EMULATE_DONE, /* no further processing */ | 42 | EMULATE_DONE, /* no further processing */ |
43 | EMULATE_DO_MMIO, /* kvm_run filled with MMIO request */ | 43 | EMULATE_DO_MMIO, /* kvm_run filled with MMIO request */ |
44 | EMULATE_DO_DCR, /* kvm_run filled with DCR request */ | ||
45 | EMULATE_FAIL, /* can't emulate this instruction */ | 44 | EMULATE_FAIL, /* can't emulate this instruction */ |
46 | EMULATE_AGAIN, /* something went wrong. go again */ | 45 | EMULATE_AGAIN, /* something went wrong. go again */ |
47 | EMULATE_EXIT_USER, /* emulation requires exit to user-space */ | 46 | EMULATE_EXIT_USER, /* emulation requires exit to user-space */ |
48 | }; | 47 | }; |
49 | 48 | ||
49 | enum instruction_type { | ||
50 | INST_GENERIC, | ||
51 | INST_SC, /* system call */ | ||
52 | }; | ||
53 | |||
54 | enum xlate_instdata { | ||
55 | XLATE_INST, /* translate instruction address */ | ||
56 | XLATE_DATA /* translate data address */ | ||
57 | }; | ||
58 | |||
59 | enum xlate_readwrite { | ||
60 | XLATE_READ, /* check for read permissions */ | ||
61 | XLATE_WRITE /* check for write permissions */ | ||
62 | }; | ||
63 | |||
50 | extern int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu); | 64 | extern int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu); |
51 | extern int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu); | 65 | extern int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu); |
52 | extern void kvmppc_handler_highmem(void); | 66 | extern void kvmppc_handler_highmem(void); |
@@ -62,8 +76,16 @@ extern int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
62 | u64 val, unsigned int bytes, | 76 | u64 val, unsigned int bytes, |
63 | int is_default_endian); | 77 | int is_default_endian); |
64 | 78 | ||
79 | extern int kvmppc_load_last_inst(struct kvm_vcpu *vcpu, | ||
80 | enum instruction_type type, u32 *inst); | ||
81 | |||
82 | extern int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, | ||
83 | bool data); | ||
84 | extern int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, | ||
85 | bool data); | ||
65 | extern int kvmppc_emulate_instruction(struct kvm_run *run, | 86 | extern int kvmppc_emulate_instruction(struct kvm_run *run, |
66 | struct kvm_vcpu *vcpu); | 87 | struct kvm_vcpu *vcpu); |
88 | extern int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu); | ||
67 | extern int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu); | 89 | extern int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu); |
68 | extern void kvmppc_emulate_dec(struct kvm_vcpu *vcpu); | 90 | extern void kvmppc_emulate_dec(struct kvm_vcpu *vcpu); |
69 | extern u32 kvmppc_get_dec(struct kvm_vcpu *vcpu, u64 tb); | 91 | extern u32 kvmppc_get_dec(struct kvm_vcpu *vcpu, u64 tb); |
@@ -86,6 +108,9 @@ extern gpa_t kvmppc_mmu_xlate(struct kvm_vcpu *vcpu, unsigned int gtlb_index, | |||
86 | gva_t eaddr); | 108 | gva_t eaddr); |
87 | extern void kvmppc_mmu_dtlb_miss(struct kvm_vcpu *vcpu); | 109 | extern void kvmppc_mmu_dtlb_miss(struct kvm_vcpu *vcpu); |
88 | extern void kvmppc_mmu_itlb_miss(struct kvm_vcpu *vcpu); | 110 | extern void kvmppc_mmu_itlb_miss(struct kvm_vcpu *vcpu); |
111 | extern int kvmppc_xlate(struct kvm_vcpu *vcpu, ulong eaddr, | ||
112 | enum xlate_instdata xlid, enum xlate_readwrite xlrw, | ||
113 | struct kvmppc_pte *pte); | ||
89 | 114 | ||
90 | extern struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, | 115 | extern struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, |
91 | unsigned int id); | 116 | unsigned int id); |
@@ -106,6 +131,14 @@ extern void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu); | |||
106 | extern void kvmppc_core_queue_external(struct kvm_vcpu *vcpu, | 131 | extern void kvmppc_core_queue_external(struct kvm_vcpu *vcpu, |
107 | struct kvm_interrupt *irq); | 132 | struct kvm_interrupt *irq); |
108 | extern void kvmppc_core_dequeue_external(struct kvm_vcpu *vcpu); | 133 | extern void kvmppc_core_dequeue_external(struct kvm_vcpu *vcpu); |
134 | extern void kvmppc_core_queue_dtlb_miss(struct kvm_vcpu *vcpu, ulong dear_flags, | ||
135 | ulong esr_flags); | ||
136 | extern void kvmppc_core_queue_data_storage(struct kvm_vcpu *vcpu, | ||
137 | ulong dear_flags, | ||
138 | ulong esr_flags); | ||
139 | extern void kvmppc_core_queue_itlb_miss(struct kvm_vcpu *vcpu); | ||
140 | extern void kvmppc_core_queue_inst_storage(struct kvm_vcpu *vcpu, | ||
141 | ulong esr_flags); | ||
109 | extern void kvmppc_core_flush_tlb(struct kvm_vcpu *vcpu); | 142 | extern void kvmppc_core_flush_tlb(struct kvm_vcpu *vcpu); |
110 | extern int kvmppc_core_check_requests(struct kvm_vcpu *vcpu); | 143 | extern int kvmppc_core_check_requests(struct kvm_vcpu *vcpu); |
111 | 144 | ||
@@ -228,12 +261,35 @@ struct kvmppc_ops { | |||
228 | void (*fast_vcpu_kick)(struct kvm_vcpu *vcpu); | 261 | void (*fast_vcpu_kick)(struct kvm_vcpu *vcpu); |
229 | long (*arch_vm_ioctl)(struct file *filp, unsigned int ioctl, | 262 | long (*arch_vm_ioctl)(struct file *filp, unsigned int ioctl, |
230 | unsigned long arg); | 263 | unsigned long arg); |
231 | 264 | int (*hcall_implemented)(unsigned long hcall); | |
232 | }; | 265 | }; |
233 | 266 | ||
234 | extern struct kvmppc_ops *kvmppc_hv_ops; | 267 | extern struct kvmppc_ops *kvmppc_hv_ops; |
235 | extern struct kvmppc_ops *kvmppc_pr_ops; | 268 | extern struct kvmppc_ops *kvmppc_pr_ops; |
236 | 269 | ||
270 | static inline int kvmppc_get_last_inst(struct kvm_vcpu *vcpu, | ||
271 | enum instruction_type type, u32 *inst) | ||
272 | { | ||
273 | int ret = EMULATE_DONE; | ||
274 | u32 fetched_inst; | ||
275 | |||
276 | /* Load the instruction manually if it failed to do so in the | ||
277 | * exit path */ | ||
278 | if (vcpu->arch.last_inst == KVM_INST_FETCH_FAILED) | ||
279 | ret = kvmppc_load_last_inst(vcpu, type, &vcpu->arch.last_inst); | ||
280 | |||
281 | /* Write fetch_failed unswapped if the fetch failed */ | ||
282 | if (ret == EMULATE_DONE) | ||
283 | fetched_inst = kvmppc_need_byteswap(vcpu) ? | ||
284 | swab32(vcpu->arch.last_inst) : | ||
285 | vcpu->arch.last_inst; | ||
286 | else | ||
287 | fetched_inst = vcpu->arch.last_inst; | ||
288 | |||
289 | *inst = fetched_inst; | ||
290 | return ret; | ||
291 | } | ||
292 | |||
237 | static inline bool is_kvmppc_hv_enabled(struct kvm *kvm) | 293 | static inline bool is_kvmppc_hv_enabled(struct kvm *kvm) |
238 | { | 294 | { |
239 | return kvm->arch.kvm_ops == kvmppc_hv_ops; | 295 | return kvm->arch.kvm_ops == kvmppc_hv_ops; |
@@ -392,6 +448,17 @@ static inline int kvmppc_xics_hcall(struct kvm_vcpu *vcpu, u32 cmd) | |||
392 | { return 0; } | 448 | { return 0; } |
393 | #endif | 449 | #endif |
394 | 450 | ||
451 | static inline unsigned long kvmppc_get_epr(struct kvm_vcpu *vcpu) | ||
452 | { | ||
453 | #ifdef CONFIG_KVM_BOOKE_HV | ||
454 | return mfspr(SPRN_GEPR); | ||
455 | #elif defined(CONFIG_BOOKE) | ||
456 | return vcpu->arch.epr; | ||
457 | #else | ||
458 | return 0; | ||
459 | #endif | ||
460 | } | ||
461 | |||
395 | static inline void kvmppc_set_epr(struct kvm_vcpu *vcpu, u32 epr) | 462 | static inline void kvmppc_set_epr(struct kvm_vcpu *vcpu, u32 epr) |
396 | { | 463 | { |
397 | #ifdef CONFIG_KVM_BOOKE_HV | 464 | #ifdef CONFIG_KVM_BOOKE_HV |
@@ -472,8 +539,20 @@ static inline bool kvmppc_shared_big_endian(struct kvm_vcpu *vcpu) | |||
472 | #endif | 539 | #endif |
473 | } | 540 | } |
474 | 541 | ||
542 | #define SPRNG_WRAPPER_GET(reg, bookehv_spr) \ | ||
543 | static inline ulong kvmppc_get_##reg(struct kvm_vcpu *vcpu) \ | ||
544 | { \ | ||
545 | return mfspr(bookehv_spr); \ | ||
546 | } \ | ||
547 | |||
548 | #define SPRNG_WRAPPER_SET(reg, bookehv_spr) \ | ||
549 | static inline void kvmppc_set_##reg(struct kvm_vcpu *vcpu, ulong val) \ | ||
550 | { \ | ||
551 | mtspr(bookehv_spr, val); \ | ||
552 | } \ | ||
553 | |||
475 | #define SHARED_WRAPPER_GET(reg, size) \ | 554 | #define SHARED_WRAPPER_GET(reg, size) \ |
476 | static inline u##size kvmppc_get_##reg(struct kvm_vcpu *vcpu) \ | 555 | static inline u##size kvmppc_get_##reg(struct kvm_vcpu *vcpu) \ |
477 | { \ | 556 | { \ |
478 | if (kvmppc_shared_big_endian(vcpu)) \ | 557 | if (kvmppc_shared_big_endian(vcpu)) \ |
479 | return be##size##_to_cpu(vcpu->arch.shared->reg); \ | 558 | return be##size##_to_cpu(vcpu->arch.shared->reg); \ |
@@ -494,14 +573,31 @@ static inline void kvmppc_set_##reg(struct kvm_vcpu *vcpu, u##size val) \ | |||
494 | SHARED_WRAPPER_GET(reg, size) \ | 573 | SHARED_WRAPPER_GET(reg, size) \ |
495 | SHARED_WRAPPER_SET(reg, size) \ | 574 | SHARED_WRAPPER_SET(reg, size) \ |
496 | 575 | ||
576 | #define SPRNG_WRAPPER(reg, bookehv_spr) \ | ||
577 | SPRNG_WRAPPER_GET(reg, bookehv_spr) \ | ||
578 | SPRNG_WRAPPER_SET(reg, bookehv_spr) \ | ||
579 | |||
580 | #ifdef CONFIG_KVM_BOOKE_HV | ||
581 | |||
582 | #define SHARED_SPRNG_WRAPPER(reg, size, bookehv_spr) \ | ||
583 | SPRNG_WRAPPER(reg, bookehv_spr) \ | ||
584 | |||
585 | #else | ||
586 | |||
587 | #define SHARED_SPRNG_WRAPPER(reg, size, bookehv_spr) \ | ||
588 | SHARED_WRAPPER(reg, size) \ | ||
589 | |||
590 | #endif | ||
591 | |||
497 | SHARED_WRAPPER(critical, 64) | 592 | SHARED_WRAPPER(critical, 64) |
498 | SHARED_WRAPPER(sprg0, 64) | 593 | SHARED_SPRNG_WRAPPER(sprg0, 64, SPRN_GSPRG0) |
499 | SHARED_WRAPPER(sprg1, 64) | 594 | SHARED_SPRNG_WRAPPER(sprg1, 64, SPRN_GSPRG1) |
500 | SHARED_WRAPPER(sprg2, 64) | 595 | SHARED_SPRNG_WRAPPER(sprg2, 64, SPRN_GSPRG2) |
501 | SHARED_WRAPPER(sprg3, 64) | 596 | SHARED_SPRNG_WRAPPER(sprg3, 64, SPRN_GSPRG3) |
502 | SHARED_WRAPPER(srr0, 64) | 597 | SHARED_SPRNG_WRAPPER(srr0, 64, SPRN_GSRR0) |
503 | SHARED_WRAPPER(srr1, 64) | 598 | SHARED_SPRNG_WRAPPER(srr1, 64, SPRN_GSRR1) |
504 | SHARED_WRAPPER(dar, 64) | 599 | SHARED_SPRNG_WRAPPER(dar, 64, SPRN_GDEAR) |
600 | SHARED_SPRNG_WRAPPER(esr, 64, SPRN_GESR) | ||
505 | SHARED_WRAPPER_GET(msr, 64) | 601 | SHARED_WRAPPER_GET(msr, 64) |
506 | static inline void kvmppc_set_msr_fast(struct kvm_vcpu *vcpu, u64 val) | 602 | static inline void kvmppc_set_msr_fast(struct kvm_vcpu *vcpu, u64 val) |
507 | { | 603 | { |
diff --git a/arch/powerpc/include/asm/mmu-book3e.h b/arch/powerpc/include/asm/mmu-book3e.h index d0918e09557f..cd4f04a74802 100644 --- a/arch/powerpc/include/asm/mmu-book3e.h +++ b/arch/powerpc/include/asm/mmu-book3e.h | |||
@@ -40,7 +40,11 @@ | |||
40 | 40 | ||
41 | /* MAS registers bit definitions */ | 41 | /* MAS registers bit definitions */ |
42 | 42 | ||
43 | #define MAS0_TLBSEL(x) (((x) << 28) & 0x30000000) | 43 | #define MAS0_TLBSEL_MASK 0x30000000 |
44 | #define MAS0_TLBSEL_SHIFT 28 | ||
45 | #define MAS0_TLBSEL(x) (((x) << MAS0_TLBSEL_SHIFT) & MAS0_TLBSEL_MASK) | ||
46 | #define MAS0_GET_TLBSEL(mas0) (((mas0) & MAS0_TLBSEL_MASK) >> \ | ||
47 | MAS0_TLBSEL_SHIFT) | ||
44 | #define MAS0_ESEL_MASK 0x0FFF0000 | 48 | #define MAS0_ESEL_MASK 0x0FFF0000 |
45 | #define MAS0_ESEL_SHIFT 16 | 49 | #define MAS0_ESEL_SHIFT 16 |
46 | #define MAS0_ESEL(x) (((x) << MAS0_ESEL_SHIFT) & MAS0_ESEL_MASK) | 50 | #define MAS0_ESEL(x) (((x) << MAS0_ESEL_SHIFT) & MAS0_ESEL_MASK) |
@@ -58,6 +62,7 @@ | |||
58 | #define MAS1_TSIZE_MASK 0x00000f80 | 62 | #define MAS1_TSIZE_MASK 0x00000f80 |
59 | #define MAS1_TSIZE_SHIFT 7 | 63 | #define MAS1_TSIZE_SHIFT 7 |
60 | #define MAS1_TSIZE(x) (((x) << MAS1_TSIZE_SHIFT) & MAS1_TSIZE_MASK) | 64 | #define MAS1_TSIZE(x) (((x) << MAS1_TSIZE_SHIFT) & MAS1_TSIZE_MASK) |
65 | #define MAS1_GET_TSIZE(mas1) (((mas1) & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT) | ||
61 | 66 | ||
62 | #define MAS2_EPN (~0xFFFUL) | 67 | #define MAS2_EPN (~0xFFFUL) |
63 | #define MAS2_X0 0x00000040 | 68 | #define MAS2_X0 0x00000040 |
@@ -86,6 +91,7 @@ | |||
86 | #define MAS3_SPSIZE 0x0000003e | 91 | #define MAS3_SPSIZE 0x0000003e |
87 | #define MAS3_SPSIZE_SHIFT 1 | 92 | #define MAS3_SPSIZE_SHIFT 1 |
88 | 93 | ||
94 | #define MAS4_TLBSEL_MASK MAS0_TLBSEL_MASK | ||
89 | #define MAS4_TLBSELD(x) MAS0_TLBSEL(x) | 95 | #define MAS4_TLBSELD(x) MAS0_TLBSEL(x) |
90 | #define MAS4_INDD 0x00008000 /* Default IND */ | 96 | #define MAS4_INDD 0x00008000 /* Default IND */ |
91 | #define MAS4_TSIZED(x) MAS1_TSIZE(x) | 97 | #define MAS4_TSIZED(x) MAS1_TSIZE(x) |
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h index e316dad6ba76..6f8536208049 100644 --- a/arch/powerpc/include/asm/ppc-opcode.h +++ b/arch/powerpc/include/asm/ppc-opcode.h | |||
@@ -139,6 +139,7 @@ | |||
139 | #define PPC_INST_ISEL 0x7c00001e | 139 | #define PPC_INST_ISEL 0x7c00001e |
140 | #define PPC_INST_ISEL_MASK 0xfc00003e | 140 | #define PPC_INST_ISEL_MASK 0xfc00003e |
141 | #define PPC_INST_LDARX 0x7c0000a8 | 141 | #define PPC_INST_LDARX 0x7c0000a8 |
142 | #define PPC_INST_LOGMPP 0x7c0007e4 | ||
142 | #define PPC_INST_LSWI 0x7c0004aa | 143 | #define PPC_INST_LSWI 0x7c0004aa |
143 | #define PPC_INST_LSWX 0x7c00042a | 144 | #define PPC_INST_LSWX 0x7c00042a |
144 | #define PPC_INST_LWARX 0x7c000028 | 145 | #define PPC_INST_LWARX 0x7c000028 |
@@ -277,6 +278,20 @@ | |||
277 | #define __PPC_EH(eh) 0 | 278 | #define __PPC_EH(eh) 0 |
278 | #endif | 279 | #endif |
279 | 280 | ||
281 | /* POWER8 Micro Partition Prefetch (MPP) parameters */ | ||
282 | /* Address mask is common for LOGMPP instruction and MPPR SPR */ | ||
283 | #define PPC_MPPE_ADDRESS_MASK 0xffffffffc000 | ||
284 | |||
285 | /* Bits 60 and 61 of MPP SPR should be set to one of the following */ | ||
286 | /* Aborting the fetch is indeed setting 00 in the table size bits */ | ||
287 | #define PPC_MPPR_FETCH_ABORT (0x0ULL << 60) | ||
288 | #define PPC_MPPR_FETCH_WHOLE_TABLE (0x2ULL << 60) | ||
289 | |||
290 | /* Bits 54 and 55 of register for LOGMPP instruction should be set to: */ | ||
291 | #define PPC_LOGMPP_LOG_L2 (0x02ULL << 54) | ||
292 | #define PPC_LOGMPP_LOG_L2L3 (0x01ULL << 54) | ||
293 | #define PPC_LOGMPP_LOG_ABORT (0x03ULL << 54) | ||
294 | |||
280 | /* Deal with instructions that older assemblers aren't aware of */ | 295 | /* Deal with instructions that older assemblers aren't aware of */ |
281 | #define PPC_DCBAL(a, b) stringify_in_c(.long PPC_INST_DCBAL | \ | 296 | #define PPC_DCBAL(a, b) stringify_in_c(.long PPC_INST_DCBAL | \ |
282 | __PPC_RA(a) | __PPC_RB(b)) | 297 | __PPC_RA(a) | __PPC_RB(b)) |
@@ -285,6 +300,8 @@ | |||
285 | #define PPC_LDARX(t, a, b, eh) stringify_in_c(.long PPC_INST_LDARX | \ | 300 | #define PPC_LDARX(t, a, b, eh) stringify_in_c(.long PPC_INST_LDARX | \ |
286 | ___PPC_RT(t) | ___PPC_RA(a) | \ | 301 | ___PPC_RT(t) | ___PPC_RA(a) | \ |
287 | ___PPC_RB(b) | __PPC_EH(eh)) | 302 | ___PPC_RB(b) | __PPC_EH(eh)) |
303 | #define PPC_LOGMPP(b) stringify_in_c(.long PPC_INST_LOGMPP | \ | ||
304 | __PPC_RB(b)) | ||
288 | #define PPC_LWARX(t, a, b, eh) stringify_in_c(.long PPC_INST_LWARX | \ | 305 | #define PPC_LWARX(t, a, b, eh) stringify_in_c(.long PPC_INST_LWARX | \ |
289 | ___PPC_RT(t) | ___PPC_RA(a) | \ | 306 | ___PPC_RT(t) | ___PPC_RA(a) | \ |
290 | ___PPC_RB(b) | __PPC_EH(eh)) | 307 | ___PPC_RB(b) | __PPC_EH(eh)) |
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index f7b97b895708..1c987bf794ef 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h | |||
@@ -225,6 +225,7 @@ | |||
225 | #define CTRL_TE 0x00c00000 /* thread enable */ | 225 | #define CTRL_TE 0x00c00000 /* thread enable */ |
226 | #define CTRL_RUNLATCH 0x1 | 226 | #define CTRL_RUNLATCH 0x1 |
227 | #define SPRN_DAWR 0xB4 | 227 | #define SPRN_DAWR 0xB4 |
228 | #define SPRN_MPPR 0xB8 /* Micro Partition Prefetch Register */ | ||
228 | #define SPRN_RPR 0xBA /* Relative Priority Register */ | 229 | #define SPRN_RPR 0xBA /* Relative Priority Register */ |
229 | #define SPRN_CIABR 0xBB | 230 | #define SPRN_CIABR 0xBB |
230 | #define CIABR_PRIV 0x3 | 231 | #define CIABR_PRIV 0x3 |
@@ -944,9 +945,6 @@ | |||
944 | * readable variant for reads, which can avoid a fault | 945 | * readable variant for reads, which can avoid a fault |
945 | * with KVM type virtualization. | 946 | * with KVM type virtualization. |
946 | * | 947 | * |
947 | * (*) Under KVM, the host SPRG1 is used to point to | ||
948 | * the current VCPU data structure | ||
949 | * | ||
950 | * 32-bit 8xx: | 948 | * 32-bit 8xx: |
951 | * - SPRG0 scratch for exception vectors | 949 | * - SPRG0 scratch for exception vectors |
952 | * - SPRG1 scratch for exception vectors | 950 | * - SPRG1 scratch for exception vectors |
@@ -1203,6 +1201,15 @@ | |||
1203 | : "r" ((unsigned long)(v)) \ | 1201 | : "r" ((unsigned long)(v)) \ |
1204 | : "memory") | 1202 | : "memory") |
1205 | 1203 | ||
1204 | static inline unsigned long mfvtb (void) | ||
1205 | { | ||
1206 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
1207 | if (cpu_has_feature(CPU_FTR_ARCH_207S)) | ||
1208 | return mfspr(SPRN_VTB); | ||
1209 | #endif | ||
1210 | return 0; | ||
1211 | } | ||
1212 | |||
1206 | #ifdef __powerpc64__ | 1213 | #ifdef __powerpc64__ |
1207 | #if defined(CONFIG_PPC_CELL) || defined(CONFIG_PPC_FSL_BOOK3E) | 1214 | #if defined(CONFIG_PPC_CELL) || defined(CONFIG_PPC_FSL_BOOK3E) |
1208 | #define mftb() ({unsigned long rval; \ | 1215 | #define mftb() ({unsigned long rval; \ |
diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h index 1d428e6007ca..03cbada59d3a 100644 --- a/arch/powerpc/include/asm/time.h +++ b/arch/powerpc/include/asm/time.h | |||
@@ -102,6 +102,15 @@ static inline u64 get_rtc(void) | |||
102 | return (u64)hi * 1000000000 + lo; | 102 | return (u64)hi * 1000000000 + lo; |
103 | } | 103 | } |
104 | 104 | ||
105 | static inline u64 get_vtb(void) | ||
106 | { | ||
107 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
108 | if (cpu_has_feature(CPU_FTR_ARCH_207S)) | ||
109 | return mfvtb(); | ||
110 | #endif | ||
111 | return 0; | ||
112 | } | ||
113 | |||
105 | #ifdef CONFIG_PPC64 | 114 | #ifdef CONFIG_PPC64 |
106 | static inline u64 get_tb(void) | 115 | static inline u64 get_tb(void) |
107 | { | 116 | { |
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h index 2bc4a9409a93..e0e49dbb145d 100644 --- a/arch/powerpc/include/uapi/asm/kvm.h +++ b/arch/powerpc/include/uapi/asm/kvm.h | |||
@@ -548,6 +548,7 @@ struct kvm_get_htab_header { | |||
548 | 548 | ||
549 | #define KVM_REG_PPC_VRSAVE (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xb4) | 549 | #define KVM_REG_PPC_VRSAVE (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xb4) |
550 | #define KVM_REG_PPC_LPCR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xb5) | 550 | #define KVM_REG_PPC_LPCR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xb5) |
551 | #define KVM_REG_PPC_LPCR_64 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb5) | ||
551 | #define KVM_REG_PPC_PPR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb6) | 552 | #define KVM_REG_PPC_PPR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb6) |
552 | 553 | ||
553 | /* Architecture compatibility level */ | 554 | /* Architecture compatibility level */ |
@@ -555,6 +556,7 @@ struct kvm_get_htab_header { | |||
555 | 556 | ||
556 | #define KVM_REG_PPC_DABRX (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xb8) | 557 | #define KVM_REG_PPC_DABRX (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xb8) |
557 | #define KVM_REG_PPC_WORT (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb9) | 558 | #define KVM_REG_PPC_WORT (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb9) |
559 | #define KVM_REG_PPC_SPRG9 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xba) | ||
558 | 560 | ||
559 | /* Transactional Memory checkpointed state: | 561 | /* Transactional Memory checkpointed state: |
560 | * This is all GPRs, all VSX regs and a subset of SPRs | 562 | * This is all GPRs, all VSX regs and a subset of SPRs |
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index e35054054c32..9d7dede2847c 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -491,6 +491,7 @@ int main(void) | |||
491 | DEFINE(KVM_HOST_SDR1, offsetof(struct kvm, arch.host_sdr1)); | 491 | DEFINE(KVM_HOST_SDR1, offsetof(struct kvm, arch.host_sdr1)); |
492 | DEFINE(KVM_TLBIE_LOCK, offsetof(struct kvm, arch.tlbie_lock)); | 492 | DEFINE(KVM_TLBIE_LOCK, offsetof(struct kvm, arch.tlbie_lock)); |
493 | DEFINE(KVM_NEED_FLUSH, offsetof(struct kvm, arch.need_tlb_flush.bits)); | 493 | DEFINE(KVM_NEED_FLUSH, offsetof(struct kvm, arch.need_tlb_flush.bits)); |
494 | DEFINE(KVM_ENABLED_HCALLS, offsetof(struct kvm, arch.enabled_hcalls)); | ||
494 | DEFINE(KVM_LPCR, offsetof(struct kvm, arch.lpcr)); | 495 | DEFINE(KVM_LPCR, offsetof(struct kvm, arch.lpcr)); |
495 | DEFINE(KVM_RMOR, offsetof(struct kvm, arch.rmor)); | 496 | DEFINE(KVM_RMOR, offsetof(struct kvm, arch.rmor)); |
496 | DEFINE(KVM_VRMA_SLB_V, offsetof(struct kvm, arch.vrma_slb_v)); | 497 | DEFINE(KVM_VRMA_SLB_V, offsetof(struct kvm, arch.vrma_slb_v)); |
@@ -665,6 +666,7 @@ int main(void) | |||
665 | DEFINE(VCPU_LR, offsetof(struct kvm_vcpu, arch.lr)); | 666 | DEFINE(VCPU_LR, offsetof(struct kvm_vcpu, arch.lr)); |
666 | DEFINE(VCPU_CTR, offsetof(struct kvm_vcpu, arch.ctr)); | 667 | DEFINE(VCPU_CTR, offsetof(struct kvm_vcpu, arch.ctr)); |
667 | DEFINE(VCPU_PC, offsetof(struct kvm_vcpu, arch.pc)); | 668 | DEFINE(VCPU_PC, offsetof(struct kvm_vcpu, arch.pc)); |
669 | DEFINE(VCPU_SPRG9, offsetof(struct kvm_vcpu, arch.sprg9)); | ||
668 | DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst)); | 670 | DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst)); |
669 | DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear)); | 671 | DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear)); |
670 | DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr)); | 672 | DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr)); |
diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c deleted file mode 100644 index 9cb4b0a36031..000000000000 --- a/arch/powerpc/kvm/44x.c +++ /dev/null | |||
@@ -1,237 +0,0 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify | ||
3 | * it under the terms of the GNU General Public License, version 2, as | ||
4 | * published by the Free Software Foundation. | ||
5 | * | ||
6 | * This program is distributed in the hope that it will be useful, | ||
7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
9 | * GNU General Public License for more details. | ||
10 | * | ||
11 | * You should have received a copy of the GNU General Public License | ||
12 | * along with this program; if not, write to the Free Software | ||
13 | * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
14 | * | ||
15 | * Copyright IBM Corp. 2008 | ||
16 | * | ||
17 | * Authors: Hollis Blanchard <hollisb@us.ibm.com> | ||
18 | */ | ||
19 | |||
20 | #include <linux/kvm_host.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/err.h> | ||
23 | #include <linux/export.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/miscdevice.h> | ||
26 | |||
27 | #include <asm/reg.h> | ||
28 | #include <asm/cputable.h> | ||
29 | #include <asm/tlbflush.h> | ||
30 | #include <asm/kvm_44x.h> | ||
31 | #include <asm/kvm_ppc.h> | ||
32 | |||
33 | #include "44x_tlb.h" | ||
34 | #include "booke.h" | ||
35 | |||
36 | static void kvmppc_core_vcpu_load_44x(struct kvm_vcpu *vcpu, int cpu) | ||
37 | { | ||
38 | kvmppc_booke_vcpu_load(vcpu, cpu); | ||
39 | kvmppc_44x_tlb_load(vcpu); | ||
40 | } | ||
41 | |||
42 | static void kvmppc_core_vcpu_put_44x(struct kvm_vcpu *vcpu) | ||
43 | { | ||
44 | kvmppc_44x_tlb_put(vcpu); | ||
45 | kvmppc_booke_vcpu_put(vcpu); | ||
46 | } | ||
47 | |||
48 | int kvmppc_core_check_processor_compat(void) | ||
49 | { | ||
50 | int r; | ||
51 | |||
52 | if (strncmp(cur_cpu_spec->platform, "ppc440", 6) == 0) | ||
53 | r = 0; | ||
54 | else | ||
55 | r = -ENOTSUPP; | ||
56 | |||
57 | return r; | ||
58 | } | ||
59 | |||
60 | int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu) | ||
61 | { | ||
62 | struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); | ||
63 | struct kvmppc_44x_tlbe *tlbe = &vcpu_44x->guest_tlb[0]; | ||
64 | int i; | ||
65 | |||
66 | tlbe->tid = 0; | ||
67 | tlbe->word0 = PPC44x_TLB_16M | PPC44x_TLB_VALID; | ||
68 | tlbe->word1 = 0; | ||
69 | tlbe->word2 = PPC44x_TLB_SX | PPC44x_TLB_SW | PPC44x_TLB_SR; | ||
70 | |||
71 | tlbe++; | ||
72 | tlbe->tid = 0; | ||
73 | tlbe->word0 = 0xef600000 | PPC44x_TLB_4K | PPC44x_TLB_VALID; | ||
74 | tlbe->word1 = 0xef600000; | ||
75 | tlbe->word2 = PPC44x_TLB_SX | PPC44x_TLB_SW | PPC44x_TLB_SR | ||
76 | | PPC44x_TLB_I | PPC44x_TLB_G; | ||
77 | |||
78 | /* Since the guest can directly access the timebase, it must know the | ||
79 | * real timebase frequency. Accordingly, it must see the state of | ||
80 | * CCR1[TCS]. */ | ||
81 | /* XXX CCR1 doesn't exist on all 440 SoCs. */ | ||
82 | vcpu->arch.ccr1 = mfspr(SPRN_CCR1); | ||
83 | |||
84 | for (i = 0; i < ARRAY_SIZE(vcpu_44x->shadow_refs); i++) | ||
85 | vcpu_44x->shadow_refs[i].gtlb_index = -1; | ||
86 | |||
87 | vcpu->arch.cpu_type = KVM_CPU_440; | ||
88 | vcpu->arch.pvr = mfspr(SPRN_PVR); | ||
89 | |||
90 | return 0; | ||
91 | } | ||
92 | |||
93 | /* 'linear_address' is actually an encoding of AS|PID|EADDR . */ | ||
94 | int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu, | ||
95 | struct kvm_translation *tr) | ||
96 | { | ||
97 | int index; | ||
98 | gva_t eaddr; | ||
99 | u8 pid; | ||
100 | u8 as; | ||
101 | |||
102 | eaddr = tr->linear_address; | ||
103 | pid = (tr->linear_address >> 32) & 0xff; | ||
104 | as = (tr->linear_address >> 40) & 0x1; | ||
105 | |||
106 | index = kvmppc_44x_tlb_index(vcpu, eaddr, pid, as); | ||
107 | if (index == -1) { | ||
108 | tr->valid = 0; | ||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | tr->physical_address = kvmppc_mmu_xlate(vcpu, index, eaddr); | ||
113 | /* XXX what does "writeable" and "usermode" even mean? */ | ||
114 | tr->valid = 1; | ||
115 | |||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | static int kvmppc_core_get_sregs_44x(struct kvm_vcpu *vcpu, | ||
120 | struct kvm_sregs *sregs) | ||
121 | { | ||
122 | return kvmppc_get_sregs_ivor(vcpu, sregs); | ||
123 | } | ||
124 | |||
125 | static int kvmppc_core_set_sregs_44x(struct kvm_vcpu *vcpu, | ||
126 | struct kvm_sregs *sregs) | ||
127 | { | ||
128 | return kvmppc_set_sregs_ivor(vcpu, sregs); | ||
129 | } | ||
130 | |||
131 | static int kvmppc_get_one_reg_44x(struct kvm_vcpu *vcpu, u64 id, | ||
132 | union kvmppc_one_reg *val) | ||
133 | { | ||
134 | return -EINVAL; | ||
135 | } | ||
136 | |||
137 | static int kvmppc_set_one_reg_44x(struct kvm_vcpu *vcpu, u64 id, | ||
138 | union kvmppc_one_reg *val) | ||
139 | { | ||
140 | return -EINVAL; | ||
141 | } | ||
142 | |||
143 | static struct kvm_vcpu *kvmppc_core_vcpu_create_44x(struct kvm *kvm, | ||
144 | unsigned int id) | ||
145 | { | ||
146 | struct kvmppc_vcpu_44x *vcpu_44x; | ||
147 | struct kvm_vcpu *vcpu; | ||
148 | int err; | ||
149 | |||
150 | vcpu_44x = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL); | ||
151 | if (!vcpu_44x) { | ||
152 | err = -ENOMEM; | ||
153 | goto out; | ||
154 | } | ||
155 | |||
156 | vcpu = &vcpu_44x->vcpu; | ||
157 | err = kvm_vcpu_init(vcpu, kvm, id); | ||
158 | if (err) | ||
159 | goto free_vcpu; | ||
160 | |||
161 | vcpu->arch.shared = (void*)__get_free_page(GFP_KERNEL|__GFP_ZERO); | ||
162 | if (!vcpu->arch.shared) | ||
163 | goto uninit_vcpu; | ||
164 | |||
165 | return vcpu; | ||
166 | |||
167 | uninit_vcpu: | ||
168 | kvm_vcpu_uninit(vcpu); | ||
169 | free_vcpu: | ||
170 | kmem_cache_free(kvm_vcpu_cache, vcpu_44x); | ||
171 | out: | ||
172 | return ERR_PTR(err); | ||
173 | } | ||
174 | |||
175 | static void kvmppc_core_vcpu_free_44x(struct kvm_vcpu *vcpu) | ||
176 | { | ||
177 | struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); | ||
178 | |||
179 | free_page((unsigned long)vcpu->arch.shared); | ||
180 | kvm_vcpu_uninit(vcpu); | ||
181 | kmem_cache_free(kvm_vcpu_cache, vcpu_44x); | ||
182 | } | ||
183 | |||
184 | static int kvmppc_core_init_vm_44x(struct kvm *kvm) | ||
185 | { | ||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | static void kvmppc_core_destroy_vm_44x(struct kvm *kvm) | ||
190 | { | ||
191 | } | ||
192 | |||
193 | static struct kvmppc_ops kvm_ops_44x = { | ||
194 | .get_sregs = kvmppc_core_get_sregs_44x, | ||
195 | .set_sregs = kvmppc_core_set_sregs_44x, | ||
196 | .get_one_reg = kvmppc_get_one_reg_44x, | ||
197 | .set_one_reg = kvmppc_set_one_reg_44x, | ||
198 | .vcpu_load = kvmppc_core_vcpu_load_44x, | ||
199 | .vcpu_put = kvmppc_core_vcpu_put_44x, | ||
200 | .vcpu_create = kvmppc_core_vcpu_create_44x, | ||
201 | .vcpu_free = kvmppc_core_vcpu_free_44x, | ||
202 | .mmu_destroy = kvmppc_mmu_destroy_44x, | ||
203 | .init_vm = kvmppc_core_init_vm_44x, | ||
204 | .destroy_vm = kvmppc_core_destroy_vm_44x, | ||
205 | .emulate_op = kvmppc_core_emulate_op_44x, | ||
206 | .emulate_mtspr = kvmppc_core_emulate_mtspr_44x, | ||
207 | .emulate_mfspr = kvmppc_core_emulate_mfspr_44x, | ||
208 | }; | ||
209 | |||
210 | static int __init kvmppc_44x_init(void) | ||
211 | { | ||
212 | int r; | ||
213 | |||
214 | r = kvmppc_booke_init(); | ||
215 | if (r) | ||
216 | goto err_out; | ||
217 | |||
218 | r = kvm_init(NULL, sizeof(struct kvmppc_vcpu_44x), 0, THIS_MODULE); | ||
219 | if (r) | ||
220 | goto err_out; | ||
221 | kvm_ops_44x.owner = THIS_MODULE; | ||
222 | kvmppc_pr_ops = &kvm_ops_44x; | ||
223 | |||
224 | err_out: | ||
225 | return r; | ||
226 | } | ||
227 | |||
228 | static void __exit kvmppc_44x_exit(void) | ||
229 | { | ||
230 | kvmppc_pr_ops = NULL; | ||
231 | kvmppc_booke_exit(); | ||
232 | } | ||
233 | |||
234 | module_init(kvmppc_44x_init); | ||
235 | module_exit(kvmppc_44x_exit); | ||
236 | MODULE_ALIAS_MISCDEV(KVM_MINOR); | ||
237 | MODULE_ALIAS("devname:kvm"); | ||
diff --git a/arch/powerpc/kvm/44x_emulate.c b/arch/powerpc/kvm/44x_emulate.c deleted file mode 100644 index 92c9ab4bcfec..000000000000 --- a/arch/powerpc/kvm/44x_emulate.c +++ /dev/null | |||
@@ -1,194 +0,0 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify | ||
3 | * it under the terms of the GNU General Public License, version 2, as | ||
4 | * published by the Free Software Foundation. | ||
5 | * | ||
6 | * This program is distributed in the hope that it will be useful, | ||
7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
9 | * GNU General Public License for more details. | ||
10 | * | ||
11 | * You should have received a copy of the GNU General Public License | ||
12 | * along with this program; if not, write to the Free Software | ||
13 | * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
14 | * | ||
15 | * Copyright IBM Corp. 2008 | ||
16 | * | ||
17 | * Authors: Hollis Blanchard <hollisb@us.ibm.com> | ||
18 | */ | ||
19 | |||
20 | #include <asm/kvm_ppc.h> | ||
21 | #include <asm/dcr.h> | ||
22 | #include <asm/dcr-regs.h> | ||
23 | #include <asm/disassemble.h> | ||
24 | #include <asm/kvm_44x.h> | ||
25 | #include "timing.h" | ||
26 | |||
27 | #include "booke.h" | ||
28 | #include "44x_tlb.h" | ||
29 | |||
30 | #define XOP_MFDCRX 259 | ||
31 | #define XOP_MFDCR 323 | ||
32 | #define XOP_MTDCRX 387 | ||
33 | #define XOP_MTDCR 451 | ||
34 | #define XOP_TLBSX 914 | ||
35 | #define XOP_ICCCI 966 | ||
36 | #define XOP_TLBWE 978 | ||
37 | |||
38 | static int emulate_mtdcr(struct kvm_vcpu *vcpu, int rs, int dcrn) | ||
39 | { | ||
40 | /* emulate some access in kernel */ | ||
41 | switch (dcrn) { | ||
42 | case DCRN_CPR0_CONFIG_ADDR: | ||
43 | vcpu->arch.cpr0_cfgaddr = kvmppc_get_gpr(vcpu, rs); | ||
44 | return EMULATE_DONE; | ||
45 | default: | ||
46 | vcpu->run->dcr.dcrn = dcrn; | ||
47 | vcpu->run->dcr.data = kvmppc_get_gpr(vcpu, rs); | ||
48 | vcpu->run->dcr.is_write = 1; | ||
49 | vcpu->arch.dcr_is_write = 1; | ||
50 | vcpu->arch.dcr_needed = 1; | ||
51 | kvmppc_account_exit(vcpu, DCR_EXITS); | ||
52 | return EMULATE_DO_DCR; | ||
53 | } | ||
54 | } | ||
55 | |||
56 | static int emulate_mfdcr(struct kvm_vcpu *vcpu, int rt, int dcrn) | ||
57 | { | ||
58 | /* The guest may access CPR0 registers to determine the timebase | ||
59 | * frequency, and it must know the real host frequency because it | ||
60 | * can directly access the timebase registers. | ||
61 | * | ||
62 | * It would be possible to emulate those accesses in userspace, | ||
63 | * but userspace can really only figure out the end frequency. | ||
64 | * We could decompose that into the factors that compute it, but | ||
65 | * that's tricky math, and it's easier to just report the real | ||
66 | * CPR0 values. | ||
67 | */ | ||
68 | switch (dcrn) { | ||
69 | case DCRN_CPR0_CONFIG_ADDR: | ||
70 | kvmppc_set_gpr(vcpu, rt, vcpu->arch.cpr0_cfgaddr); | ||
71 | break; | ||
72 | case DCRN_CPR0_CONFIG_DATA: | ||
73 | local_irq_disable(); | ||
74 | mtdcr(DCRN_CPR0_CONFIG_ADDR, | ||
75 | vcpu->arch.cpr0_cfgaddr); | ||
76 | kvmppc_set_gpr(vcpu, rt, | ||
77 | mfdcr(DCRN_CPR0_CONFIG_DATA)); | ||
78 | local_irq_enable(); | ||
79 | break; | ||
80 | default: | ||
81 | vcpu->run->dcr.dcrn = dcrn; | ||
82 | vcpu->run->dcr.data = 0; | ||
83 | vcpu->run->dcr.is_write = 0; | ||
84 | vcpu->arch.dcr_is_write = 0; | ||
85 | vcpu->arch.io_gpr = rt; | ||
86 | vcpu->arch.dcr_needed = 1; | ||
87 | kvmppc_account_exit(vcpu, DCR_EXITS); | ||
88 | return EMULATE_DO_DCR; | ||
89 | } | ||
90 | |||
91 | return EMULATE_DONE; | ||
92 | } | ||
93 | |||
94 | int kvmppc_core_emulate_op_44x(struct kvm_run *run, struct kvm_vcpu *vcpu, | ||
95 | unsigned int inst, int *advance) | ||
96 | { | ||
97 | int emulated = EMULATE_DONE; | ||
98 | int dcrn = get_dcrn(inst); | ||
99 | int ra = get_ra(inst); | ||
100 | int rb = get_rb(inst); | ||
101 | int rc = get_rc(inst); | ||
102 | int rs = get_rs(inst); | ||
103 | int rt = get_rt(inst); | ||
104 | int ws = get_ws(inst); | ||
105 | |||
106 | switch (get_op(inst)) { | ||
107 | case 31: | ||
108 | switch (get_xop(inst)) { | ||
109 | |||
110 | case XOP_MFDCR: | ||
111 | emulated = emulate_mfdcr(vcpu, rt, dcrn); | ||
112 | break; | ||
113 | |||
114 | case XOP_MFDCRX: | ||
115 | emulated = emulate_mfdcr(vcpu, rt, | ||
116 | kvmppc_get_gpr(vcpu, ra)); | ||
117 | break; | ||
118 | |||
119 | case XOP_MTDCR: | ||
120 | emulated = emulate_mtdcr(vcpu, rs, dcrn); | ||
121 | break; | ||
122 | |||
123 | case XOP_MTDCRX: | ||
124 | emulated = emulate_mtdcr(vcpu, rs, | ||
125 | kvmppc_get_gpr(vcpu, ra)); | ||
126 | break; | ||
127 | |||
128 | case XOP_TLBWE: | ||
129 | emulated = kvmppc_44x_emul_tlbwe(vcpu, ra, rs, ws); | ||
130 | break; | ||
131 | |||
132 | case XOP_TLBSX: | ||
133 | emulated = kvmppc_44x_emul_tlbsx(vcpu, rt, ra, rb, rc); | ||
134 | break; | ||
135 | |||
136 | case XOP_ICCCI: | ||
137 | break; | ||
138 | |||
139 | default: | ||
140 | emulated = EMULATE_FAIL; | ||
141 | } | ||
142 | |||
143 | break; | ||
144 | |||
145 | default: | ||
146 | emulated = EMULATE_FAIL; | ||
147 | } | ||
148 | |||
149 | if (emulated == EMULATE_FAIL) | ||
150 | emulated = kvmppc_booke_emulate_op(run, vcpu, inst, advance); | ||
151 | |||
152 | return emulated; | ||
153 | } | ||
154 | |||
155 | int kvmppc_core_emulate_mtspr_44x(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) | ||
156 | { | ||
157 | int emulated = EMULATE_DONE; | ||
158 | |||
159 | switch (sprn) { | ||
160 | case SPRN_PID: | ||
161 | kvmppc_set_pid(vcpu, spr_val); break; | ||
162 | case SPRN_MMUCR: | ||
163 | vcpu->arch.mmucr = spr_val; break; | ||
164 | case SPRN_CCR0: | ||
165 | vcpu->arch.ccr0 = spr_val; break; | ||
166 | case SPRN_CCR1: | ||
167 | vcpu->arch.ccr1 = spr_val; break; | ||
168 | default: | ||
169 | emulated = kvmppc_booke_emulate_mtspr(vcpu, sprn, spr_val); | ||
170 | } | ||
171 | |||
172 | return emulated; | ||
173 | } | ||
174 | |||
175 | int kvmppc_core_emulate_mfspr_44x(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val) | ||
176 | { | ||
177 | int emulated = EMULATE_DONE; | ||
178 | |||
179 | switch (sprn) { | ||
180 | case SPRN_PID: | ||
181 | *spr_val = vcpu->arch.pid; break; | ||
182 | case SPRN_MMUCR: | ||
183 | *spr_val = vcpu->arch.mmucr; break; | ||
184 | case SPRN_CCR0: | ||
185 | *spr_val = vcpu->arch.ccr0; break; | ||
186 | case SPRN_CCR1: | ||
187 | *spr_val = vcpu->arch.ccr1; break; | ||
188 | default: | ||
189 | emulated = kvmppc_booke_emulate_mfspr(vcpu, sprn, spr_val); | ||
190 | } | ||
191 | |||
192 | return emulated; | ||
193 | } | ||
194 | |||
diff --git a/arch/powerpc/kvm/44x_tlb.c b/arch/powerpc/kvm/44x_tlb.c deleted file mode 100644 index 0deef1082e02..000000000000 --- a/arch/powerpc/kvm/44x_tlb.c +++ /dev/null | |||
@@ -1,528 +0,0 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify | ||
3 | * it under the terms of the GNU General Public License, version 2, as | ||
4 | * published by the Free Software Foundation. | ||
5 | * | ||
6 | * This program is distributed in the hope that it will be useful, | ||
7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
9 | * GNU General Public License for more details. | ||
10 | * | ||
11 | * You should have received a copy of the GNU General Public License | ||
12 | * along with this program; if not, write to the Free Software | ||
13 | * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
14 | * | ||
15 | * Copyright IBM Corp. 2007 | ||
16 | * | ||
17 | * Authors: Hollis Blanchard <hollisb@us.ibm.com> | ||
18 | */ | ||
19 | |||
20 | #include <linux/types.h> | ||
21 | #include <linux/string.h> | ||
22 | #include <linux/kvm.h> | ||
23 | #include <linux/kvm_host.h> | ||
24 | #include <linux/highmem.h> | ||
25 | |||
26 | #include <asm/tlbflush.h> | ||
27 | #include <asm/mmu-44x.h> | ||
28 | #include <asm/kvm_ppc.h> | ||
29 | #include <asm/kvm_44x.h> | ||
30 | #include "timing.h" | ||
31 | |||
32 | #include "44x_tlb.h" | ||
33 | #include "trace.h" | ||
34 | |||
35 | #ifndef PPC44x_TLBE_SIZE | ||
36 | #define PPC44x_TLBE_SIZE PPC44x_TLB_4K | ||
37 | #endif | ||
38 | |||
39 | #define PAGE_SIZE_4K (1<<12) | ||
40 | #define PAGE_MASK_4K (~(PAGE_SIZE_4K - 1)) | ||
41 | |||
42 | #define PPC44x_TLB_UATTR_MASK \ | ||
43 | (PPC44x_TLB_U0|PPC44x_TLB_U1|PPC44x_TLB_U2|PPC44x_TLB_U3) | ||
44 | #define PPC44x_TLB_USER_PERM_MASK (PPC44x_TLB_UX|PPC44x_TLB_UR|PPC44x_TLB_UW) | ||
45 | #define PPC44x_TLB_SUPER_PERM_MASK (PPC44x_TLB_SX|PPC44x_TLB_SR|PPC44x_TLB_SW) | ||
46 | |||
47 | #ifdef DEBUG | ||
48 | void kvmppc_dump_tlbs(struct kvm_vcpu *vcpu) | ||
49 | { | ||
50 | struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); | ||
51 | struct kvmppc_44x_tlbe *tlbe; | ||
52 | int i; | ||
53 | |||
54 | printk("vcpu %d TLB dump:\n", vcpu->vcpu_id); | ||
55 | printk("| %2s | %3s | %8s | %8s | %8s |\n", | ||
56 | "nr", "tid", "word0", "word1", "word2"); | ||
57 | |||
58 | for (i = 0; i < ARRAY_SIZE(vcpu_44x->guest_tlb); i++) { | ||
59 | tlbe = &vcpu_44x->guest_tlb[i]; | ||
60 | if (tlbe->word0 & PPC44x_TLB_VALID) | ||
61 | printk(" G%2d | %02X | %08X | %08X | %08X |\n", | ||
62 | i, tlbe->tid, tlbe->word0, tlbe->word1, | ||
63 | tlbe->word2); | ||
64 | } | ||
65 | } | ||
66 | #endif | ||
67 | |||
68 | static inline void kvmppc_44x_tlbie(unsigned int index) | ||
69 | { | ||
70 | /* 0 <= index < 64, so the V bit is clear and we can use the index as | ||
71 | * word0. */ | ||
72 | asm volatile( | ||
73 | "tlbwe %[index], %[index], 0\n" | ||
74 | : | ||
75 | : [index] "r"(index) | ||
76 | ); | ||
77 | } | ||
78 | |||
79 | static inline void kvmppc_44x_tlbre(unsigned int index, | ||
80 | struct kvmppc_44x_tlbe *tlbe) | ||
81 | { | ||
82 | asm volatile( | ||
83 | "tlbre %[word0], %[index], 0\n" | ||
84 | "mfspr %[tid], %[sprn_mmucr]\n" | ||
85 | "andi. %[tid], %[tid], 0xff\n" | ||
86 | "tlbre %[word1], %[index], 1\n" | ||
87 | "tlbre %[word2], %[index], 2\n" | ||
88 | : [word0] "=r"(tlbe->word0), | ||
89 | [word1] "=r"(tlbe->word1), | ||
90 | [word2] "=r"(tlbe->word2), | ||
91 | [tid] "=r"(tlbe->tid) | ||
92 | : [index] "r"(index), | ||
93 | [sprn_mmucr] "i"(SPRN_MMUCR) | ||
94 | : "cc" | ||
95 | ); | ||
96 | } | ||
97 | |||
98 | static inline void kvmppc_44x_tlbwe(unsigned int index, | ||
99 | struct kvmppc_44x_tlbe *stlbe) | ||
100 | { | ||
101 | unsigned long tmp; | ||
102 | |||
103 | asm volatile( | ||
104 | "mfspr %[tmp], %[sprn_mmucr]\n" | ||
105 | "rlwimi %[tmp], %[tid], 0, 0xff\n" | ||
106 | "mtspr %[sprn_mmucr], %[tmp]\n" | ||
107 | "tlbwe %[word0], %[index], 0\n" | ||
108 | "tlbwe %[word1], %[index], 1\n" | ||
109 | "tlbwe %[word2], %[index], 2\n" | ||
110 | : [tmp] "=&r"(tmp) | ||
111 | : [word0] "r"(stlbe->word0), | ||
112 | [word1] "r"(stlbe->word1), | ||
113 | [word2] "r"(stlbe->word2), | ||
114 | [tid] "r"(stlbe->tid), | ||
115 | [index] "r"(index), | ||
116 | [sprn_mmucr] "i"(SPRN_MMUCR) | ||
117 | ); | ||
118 | } | ||
119 | |||
120 | static u32 kvmppc_44x_tlb_shadow_attrib(u32 attrib, int usermode) | ||
121 | { | ||
122 | /* We only care about the guest's permission and user bits. */ | ||
123 | attrib &= PPC44x_TLB_PERM_MASK|PPC44x_TLB_UATTR_MASK; | ||
124 | |||
125 | if (!usermode) { | ||
126 | /* Guest is in supervisor mode, so we need to translate guest | ||
127 | * supervisor permissions into user permissions. */ | ||
128 | attrib &= ~PPC44x_TLB_USER_PERM_MASK; | ||
129 | attrib |= (attrib & PPC44x_TLB_SUPER_PERM_MASK) << 3; | ||
130 | } | ||
131 | |||
132 | /* Make sure host can always access this memory. */ | ||
133 | attrib |= PPC44x_TLB_SX|PPC44x_TLB_SR|PPC44x_TLB_SW; | ||
134 | |||
135 | /* WIMGE = 0b00100 */ | ||
136 | attrib |= PPC44x_TLB_M; | ||
137 | |||
138 | return attrib; | ||
139 | } | ||
140 | |||
141 | /* Load shadow TLB back into hardware. */ | ||
142 | void kvmppc_44x_tlb_load(struct kvm_vcpu *vcpu) | ||
143 | { | ||
144 | struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); | ||
145 | int i; | ||
146 | |||
147 | for (i = 0; i <= tlb_44x_hwater; i++) { | ||
148 | struct kvmppc_44x_tlbe *stlbe = &vcpu_44x->shadow_tlb[i]; | ||
149 | |||
150 | if (get_tlb_v(stlbe) && get_tlb_ts(stlbe)) | ||
151 | kvmppc_44x_tlbwe(i, stlbe); | ||
152 | } | ||
153 | } | ||
154 | |||
155 | static void kvmppc_44x_tlbe_set_modified(struct kvmppc_vcpu_44x *vcpu_44x, | ||
156 | unsigned int i) | ||
157 | { | ||
158 | vcpu_44x->shadow_tlb_mod[i] = 1; | ||
159 | } | ||
160 | |||
161 | /* Save hardware TLB to the vcpu, and invalidate all guest mappings. */ | ||
162 | void kvmppc_44x_tlb_put(struct kvm_vcpu *vcpu) | ||
163 | { | ||
164 | struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); | ||
165 | int i; | ||
166 | |||
167 | for (i = 0; i <= tlb_44x_hwater; i++) { | ||
168 | struct kvmppc_44x_tlbe *stlbe = &vcpu_44x->shadow_tlb[i]; | ||
169 | |||
170 | if (vcpu_44x->shadow_tlb_mod[i]) | ||
171 | kvmppc_44x_tlbre(i, stlbe); | ||
172 | |||
173 | if (get_tlb_v(stlbe) && get_tlb_ts(stlbe)) | ||
174 | kvmppc_44x_tlbie(i); | ||
175 | } | ||
176 | } | ||
177 | |||
178 | |||
179 | /* Search the guest TLB for a matching entry. */ | ||
180 | int kvmppc_44x_tlb_index(struct kvm_vcpu *vcpu, gva_t eaddr, unsigned int pid, | ||
181 | unsigned int as) | ||
182 | { | ||
183 | struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); | ||
184 | int i; | ||
185 | |||
186 | /* XXX Replace loop with fancy data structures. */ | ||
187 | for (i = 0; i < ARRAY_SIZE(vcpu_44x->guest_tlb); i++) { | ||
188 | struct kvmppc_44x_tlbe *tlbe = &vcpu_44x->guest_tlb[i]; | ||
189 | unsigned int tid; | ||
190 | |||
191 | if (eaddr < get_tlb_eaddr(tlbe)) | ||
192 | continue; | ||
193 | |||
194 | if (eaddr > get_tlb_end(tlbe)) | ||
195 | continue; | ||
196 | |||
197 | tid = get_tlb_tid(tlbe); | ||
198 | if (tid && (tid != pid)) | ||
199 | continue; | ||
200 | |||
201 | if (!get_tlb_v(tlbe)) | ||
202 | continue; | ||
203 | |||
204 | if (get_tlb_ts(tlbe) != as) | ||
205 | continue; | ||
206 | |||
207 | return i; | ||
208 | } | ||
209 | |||
210 | return -1; | ||
211 | } | ||
212 | |||
213 | gpa_t kvmppc_mmu_xlate(struct kvm_vcpu *vcpu, unsigned int gtlb_index, | ||
214 | gva_t eaddr) | ||
215 | { | ||
216 | struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); | ||
217 | struct kvmppc_44x_tlbe *gtlbe = &vcpu_44x->guest_tlb[gtlb_index]; | ||
218 | unsigned int pgmask = get_tlb_bytes(gtlbe) - 1; | ||
219 | |||
220 | return get_tlb_raddr(gtlbe) | (eaddr & pgmask); | ||
221 | } | ||
222 | |||
223 | int kvmppc_mmu_itlb_index(struct kvm_vcpu *vcpu, gva_t eaddr) | ||
224 | { | ||
225 | unsigned int as = !!(vcpu->arch.shared->msr & MSR_IS); | ||
226 | |||
227 | return kvmppc_44x_tlb_index(vcpu, eaddr, vcpu->arch.pid, as); | ||
228 | } | ||
229 | |||
230 | int kvmppc_mmu_dtlb_index(struct kvm_vcpu *vcpu, gva_t eaddr) | ||
231 | { | ||
232 | unsigned int as = !!(vcpu->arch.shared->msr & MSR_DS); | ||
233 | |||
234 | return kvmppc_44x_tlb_index(vcpu, eaddr, vcpu->arch.pid, as); | ||
235 | } | ||
236 | |||
237 | void kvmppc_mmu_itlb_miss(struct kvm_vcpu *vcpu) | ||
238 | { | ||
239 | } | ||
240 | |||
241 | void kvmppc_mmu_dtlb_miss(struct kvm_vcpu *vcpu) | ||
242 | { | ||
243 | } | ||
244 | |||
245 | static void kvmppc_44x_shadow_release(struct kvmppc_vcpu_44x *vcpu_44x, | ||
246 | unsigned int stlb_index) | ||
247 | { | ||
248 | struct kvmppc_44x_shadow_ref *ref = &vcpu_44x->shadow_refs[stlb_index]; | ||
249 | |||
250 | if (!ref->page) | ||
251 | return; | ||
252 | |||
253 | /* Discard from the TLB. */ | ||
254 | /* Note: we could actually invalidate a host mapping, if the host overwrote | ||
255 | * this TLB entry since we inserted a guest mapping. */ | ||
256 | kvmppc_44x_tlbie(stlb_index); | ||
257 | |||
258 | /* Now release the page. */ | ||
259 | if (ref->writeable) | ||
260 | kvm_release_page_dirty(ref->page); | ||
261 | else | ||
262 | kvm_release_page_clean(ref->page); | ||
263 | |||
264 | ref->page = NULL; | ||
265 | |||
266 | /* XXX set tlb_44x_index to stlb_index? */ | ||
267 | |||
268 | trace_kvm_stlb_inval(stlb_index); | ||
269 | } | ||
270 | |||
271 | void kvmppc_mmu_destroy_44x(struct kvm_vcpu *vcpu) | ||
272 | { | ||
273 | struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); | ||
274 | int i; | ||
275 | |||
276 | for (i = 0; i <= tlb_44x_hwater; i++) | ||
277 | kvmppc_44x_shadow_release(vcpu_44x, i); | ||
278 | } | ||
279 | |||
280 | /** | ||
281 | * kvmppc_mmu_map -- create a host mapping for guest memory | ||
282 | * | ||
283 | * If the guest wanted a larger page than the host supports, only the first | ||
284 | * host page is mapped here and the rest are demand faulted. | ||
285 | * | ||
286 | * If the guest wanted a smaller page than the host page size, we map only the | ||
287 | * guest-size page (i.e. not a full host page mapping). | ||
288 | * | ||
289 | * Caller must ensure that the specified guest TLB entry is safe to insert into | ||
290 | * the shadow TLB. | ||
291 | */ | ||
292 | void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gpa_t gpaddr, | ||
293 | unsigned int gtlb_index) | ||
294 | { | ||
295 | struct kvmppc_44x_tlbe stlbe; | ||
296 | struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); | ||
297 | struct kvmppc_44x_tlbe *gtlbe = &vcpu_44x->guest_tlb[gtlb_index]; | ||
298 | struct kvmppc_44x_shadow_ref *ref; | ||
299 | struct page *new_page; | ||
300 | hpa_t hpaddr; | ||
301 | gfn_t gfn; | ||
302 | u32 asid = gtlbe->tid; | ||
303 | u32 flags = gtlbe->word2; | ||
304 | u32 max_bytes = get_tlb_bytes(gtlbe); | ||
305 | unsigned int victim; | ||
306 | |||
307 | /* Select TLB entry to clobber. Indirectly guard against races with the TLB | ||
308 | * miss handler by disabling interrupts. */ | ||
309 | local_irq_disable(); | ||
310 | victim = ++tlb_44x_index; | ||
311 | if (victim > tlb_44x_hwater) | ||
312 | victim = 0; | ||
313 | tlb_44x_index = victim; | ||
314 | local_irq_enable(); | ||
315 | |||
316 | /* Get reference to new page. */ | ||
317 | gfn = gpaddr >> PAGE_SHIFT; | ||
318 | new_page = gfn_to_page(vcpu->kvm, gfn); | ||
319 | if (is_error_page(new_page)) { | ||
320 | printk(KERN_ERR "Couldn't get guest page for gfn %llx!\n", | ||
321 | (unsigned long long)gfn); | ||
322 | return; | ||
323 | } | ||
324 | hpaddr = page_to_phys(new_page); | ||
325 | |||
326 | /* Invalidate any previous shadow mappings. */ | ||
327 | kvmppc_44x_shadow_release(vcpu_44x, victim); | ||
328 | |||
329 | /* XXX Make sure (va, size) doesn't overlap any other | ||
330 | * entries. 440x6 user manual says the result would be | ||
331 | * "undefined." */ | ||
332 | |||
333 | /* XXX what about AS? */ | ||
334 | |||
335 | /* Force TS=1 for all guest mappings. */ | ||
336 | stlbe.word0 = PPC44x_TLB_VALID | PPC44x_TLB_TS; | ||
337 | |||
338 | if (max_bytes >= PAGE_SIZE) { | ||
339 | /* Guest mapping is larger than or equal to host page size. We can use | ||
340 | * a "native" host mapping. */ | ||
341 | stlbe.word0 |= (gvaddr & PAGE_MASK) | PPC44x_TLBE_SIZE; | ||
342 | } else { | ||
343 | /* Guest mapping is smaller than host page size. We must restrict the | ||
344 | * size of the mapping to be at most the smaller of the two, but for | ||
345 | * simplicity we fall back to a 4K mapping (this is probably what the | ||
346 | * guest is using anyways). */ | ||
347 | stlbe.word0 |= (gvaddr & PAGE_MASK_4K) | PPC44x_TLB_4K; | ||
348 | |||
349 | /* 'hpaddr' is a host page, which is larger than the mapping we're | ||
350 | * inserting here. To compensate, we must add the in-page offset to the | ||
351 | * sub-page. */ | ||
352 | hpaddr |= gpaddr & (PAGE_MASK ^ PAGE_MASK_4K); | ||
353 | } | ||
354 | |||
355 | stlbe.word1 = (hpaddr & 0xfffffc00) | ((hpaddr >> 32) & 0xf); | ||
356 | stlbe.word2 = kvmppc_44x_tlb_shadow_attrib(flags, | ||
357 | vcpu->arch.shared->msr & MSR_PR); | ||
358 | stlbe.tid = !(asid & 0xff); | ||
359 | |||
360 | /* Keep track of the reference so we can properly release it later. */ | ||
361 | ref = &vcpu_44x->shadow_refs[victim]; | ||
362 | ref->page = new_page; | ||
363 | ref->gtlb_index = gtlb_index; | ||
364 | ref->writeable = !!(stlbe.word2 & PPC44x_TLB_UW); | ||
365 | ref->tid = stlbe.tid; | ||
366 | |||
367 | /* Insert shadow mapping into hardware TLB. */ | ||
368 | kvmppc_44x_tlbe_set_modified(vcpu_44x, victim); | ||
369 | kvmppc_44x_tlbwe(victim, &stlbe); | ||
370 | trace_kvm_stlb_write(victim, stlbe.tid, stlbe.word0, stlbe.word1, | ||
371 | stlbe.word2); | ||
372 | } | ||
373 | |||
374 | /* For a particular guest TLB entry, invalidate the corresponding host TLB | ||
375 | * mappings and release the host pages. */ | ||
376 | static void kvmppc_44x_invalidate(struct kvm_vcpu *vcpu, | ||
377 | unsigned int gtlb_index) | ||
378 | { | ||
379 | struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); | ||
380 | int i; | ||
381 | |||
382 | for (i = 0; i < ARRAY_SIZE(vcpu_44x->shadow_refs); i++) { | ||
383 | struct kvmppc_44x_shadow_ref *ref = &vcpu_44x->shadow_refs[i]; | ||
384 | if (ref->gtlb_index == gtlb_index) | ||
385 | kvmppc_44x_shadow_release(vcpu_44x, i); | ||
386 | } | ||
387 | } | ||
388 | |||
389 | void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr) | ||
390 | { | ||
391 | int usermode = vcpu->arch.shared->msr & MSR_PR; | ||
392 | |||
393 | vcpu->arch.shadow_pid = !usermode; | ||
394 | } | ||
395 | |||
396 | void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 new_pid) | ||
397 | { | ||
398 | struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); | ||
399 | int i; | ||
400 | |||
401 | if (unlikely(vcpu->arch.pid == new_pid)) | ||
402 | return; | ||
403 | |||
404 | vcpu->arch.pid = new_pid; | ||
405 | |||
406 | /* Guest userspace runs with TID=0 mappings and PID=0, to make sure it | ||
407 | * can't access guest kernel mappings (TID=1). When we switch to a new | ||
408 | * guest PID, which will also use host PID=0, we must discard the old guest | ||
409 | * userspace mappings. */ | ||
410 | for (i = 0; i < ARRAY_SIZE(vcpu_44x->shadow_refs); i++) { | ||
411 | struct kvmppc_44x_shadow_ref *ref = &vcpu_44x->shadow_refs[i]; | ||
412 | |||
413 | if (ref->tid == 0) | ||
414 | kvmppc_44x_shadow_release(vcpu_44x, i); | ||
415 | } | ||
416 | } | ||
417 | |||
418 | static int tlbe_is_host_safe(const struct kvm_vcpu *vcpu, | ||
419 | const struct kvmppc_44x_tlbe *tlbe) | ||
420 | { | ||
421 | gpa_t gpa; | ||
422 | |||
423 | if (!get_tlb_v(tlbe)) | ||
424 | return 0; | ||
425 | |||
426 | /* Does it match current guest AS? */ | ||
427 | /* XXX what about IS != DS? */ | ||
428 | if (get_tlb_ts(tlbe) != !!(vcpu->arch.shared->msr & MSR_IS)) | ||
429 | return 0; | ||
430 | |||
431 | gpa = get_tlb_raddr(tlbe); | ||
432 | if (!gfn_to_memslot(vcpu->kvm, gpa >> PAGE_SHIFT)) | ||
433 | /* Mapping is not for RAM. */ | ||
434 | return 0; | ||
435 | |||
436 | return 1; | ||
437 | } | ||
438 | |||
439 | int kvmppc_44x_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws) | ||
440 | { | ||
441 | struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); | ||
442 | struct kvmppc_44x_tlbe *tlbe; | ||
443 | unsigned int gtlb_index; | ||
444 | int idx; | ||
445 | |||
446 | gtlb_index = kvmppc_get_gpr(vcpu, ra); | ||
447 | if (gtlb_index >= KVM44x_GUEST_TLB_SIZE) { | ||
448 | printk("%s: index %d\n", __func__, gtlb_index); | ||
449 | kvmppc_dump_vcpu(vcpu); | ||
450 | return EMULATE_FAIL; | ||
451 | } | ||
452 | |||
453 | tlbe = &vcpu_44x->guest_tlb[gtlb_index]; | ||
454 | |||
455 | /* Invalidate shadow mappings for the about-to-be-clobbered TLB entry. */ | ||
456 | if (tlbe->word0 & PPC44x_TLB_VALID) | ||
457 | kvmppc_44x_invalidate(vcpu, gtlb_index); | ||
458 | |||
459 | switch (ws) { | ||
460 | case PPC44x_TLB_PAGEID: | ||
461 | tlbe->tid = get_mmucr_stid(vcpu); | ||
462 | tlbe->word0 = kvmppc_get_gpr(vcpu, rs); | ||
463 | break; | ||
464 | |||
465 | case PPC44x_TLB_XLAT: | ||
466 | tlbe->word1 = kvmppc_get_gpr(vcpu, rs); | ||
467 | break; | ||
468 | |||
469 | case PPC44x_TLB_ATTRIB: | ||
470 | tlbe->word2 = kvmppc_get_gpr(vcpu, rs); | ||
471 | break; | ||
472 | |||
473 | default: | ||
474 | return EMULATE_FAIL; | ||
475 | } | ||
476 | |||
477 | idx = srcu_read_lock(&vcpu->kvm->srcu); | ||
478 | |||
479 | if (tlbe_is_host_safe(vcpu, tlbe)) { | ||
480 | gva_t eaddr; | ||
481 | gpa_t gpaddr; | ||
482 | u32 bytes; | ||
483 | |||
484 | eaddr = get_tlb_eaddr(tlbe); | ||
485 | gpaddr = get_tlb_raddr(tlbe); | ||
486 | |||
487 | /* Use the advertised page size to mask effective and real addrs. */ | ||
488 | bytes = get_tlb_bytes(tlbe); | ||
489 | eaddr &= ~(bytes - 1); | ||
490 | gpaddr &= ~(bytes - 1); | ||
491 | |||
492 | kvmppc_mmu_map(vcpu, eaddr, gpaddr, gtlb_index); | ||
493 | } | ||
494 | |||
495 | srcu_read_unlock(&vcpu->kvm->srcu, idx); | ||
496 | |||
497 | trace_kvm_gtlb_write(gtlb_index, tlbe->tid, tlbe->word0, tlbe->word1, | ||
498 | tlbe->word2); | ||
499 | |||
500 | kvmppc_set_exit_type(vcpu, EMULATED_TLBWE_EXITS); | ||
501 | return EMULATE_DONE; | ||
502 | } | ||
503 | |||
504 | int kvmppc_44x_emul_tlbsx(struct kvm_vcpu *vcpu, u8 rt, u8 ra, u8 rb, u8 rc) | ||
505 | { | ||
506 | u32 ea; | ||
507 | int gtlb_index; | ||
508 | unsigned int as = get_mmucr_sts(vcpu); | ||
509 | unsigned int pid = get_mmucr_stid(vcpu); | ||
510 | |||
511 | ea = kvmppc_get_gpr(vcpu, rb); | ||
512 | if (ra) | ||
513 | ea += kvmppc_get_gpr(vcpu, ra); | ||
514 | |||
515 | gtlb_index = kvmppc_44x_tlb_index(vcpu, ea, pid, as); | ||
516 | if (rc) { | ||
517 | u32 cr = kvmppc_get_cr(vcpu); | ||
518 | |||
519 | if (gtlb_index < 0) | ||
520 | kvmppc_set_cr(vcpu, cr & ~0x20000000); | ||
521 | else | ||
522 | kvmppc_set_cr(vcpu, cr | 0x20000000); | ||
523 | } | ||
524 | kvmppc_set_gpr(vcpu, rt, gtlb_index); | ||
525 | |||
526 | kvmppc_set_exit_type(vcpu, EMULATED_TLBSX_EXITS); | ||
527 | return EMULATE_DONE; | ||
528 | } | ||
diff --git a/arch/powerpc/kvm/44x_tlb.h b/arch/powerpc/kvm/44x_tlb.h deleted file mode 100644 index a9ff80e51526..000000000000 --- a/arch/powerpc/kvm/44x_tlb.h +++ /dev/null | |||
@@ -1,86 +0,0 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify | ||
3 | * it under the terms of the GNU General Public License, version 2, as | ||
4 | * published by the Free Software Foundation. | ||
5 | * | ||
6 | * This program is distributed in the hope that it will be useful, | ||
7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
9 | * GNU General Public License for more details. | ||
10 | * | ||
11 | * You should have received a copy of the GNU General Public License | ||
12 | * along with this program; if not, write to the Free Software | ||
13 | * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
14 | * | ||
15 | * Copyright IBM Corp. 2007 | ||
16 | * | ||
17 | * Authors: Hollis Blanchard <hollisb@us.ibm.com> | ||
18 | */ | ||
19 | |||
20 | #ifndef __KVM_POWERPC_TLB_H__ | ||
21 | #define __KVM_POWERPC_TLB_H__ | ||
22 | |||
23 | #include <linux/kvm_host.h> | ||
24 | #include <asm/mmu-44x.h> | ||
25 | |||
26 | extern int kvmppc_44x_tlb_index(struct kvm_vcpu *vcpu, gva_t eaddr, | ||
27 | unsigned int pid, unsigned int as); | ||
28 | |||
29 | extern int kvmppc_44x_emul_tlbsx(struct kvm_vcpu *vcpu, u8 rt, u8 ra, u8 rb, | ||
30 | u8 rc); | ||
31 | extern int kvmppc_44x_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws); | ||
32 | |||
33 | /* TLB helper functions */ | ||
34 | static inline unsigned int get_tlb_size(const struct kvmppc_44x_tlbe *tlbe) | ||
35 | { | ||
36 | return (tlbe->word0 >> 4) & 0xf; | ||
37 | } | ||
38 | |||
39 | static inline gva_t get_tlb_eaddr(const struct kvmppc_44x_tlbe *tlbe) | ||
40 | { | ||
41 | return tlbe->word0 & 0xfffffc00; | ||
42 | } | ||
43 | |||
44 | static inline gva_t get_tlb_bytes(const struct kvmppc_44x_tlbe *tlbe) | ||
45 | { | ||
46 | unsigned int pgsize = get_tlb_size(tlbe); | ||
47 | return 1 << 10 << (pgsize << 1); | ||
48 | } | ||
49 | |||
50 | static inline gva_t get_tlb_end(const struct kvmppc_44x_tlbe *tlbe) | ||
51 | { | ||
52 | return get_tlb_eaddr(tlbe) + get_tlb_bytes(tlbe) - 1; | ||
53 | } | ||
54 | |||
55 | static inline u64 get_tlb_raddr(const struct kvmppc_44x_tlbe *tlbe) | ||
56 | { | ||
57 | u64 word1 = tlbe->word1; | ||
58 | return ((word1 & 0xf) << 32) | (word1 & 0xfffffc00); | ||
59 | } | ||
60 | |||
61 | static inline unsigned int get_tlb_tid(const struct kvmppc_44x_tlbe *tlbe) | ||
62 | { | ||
63 | return tlbe->tid & 0xff; | ||
64 | } | ||
65 | |||
66 | static inline unsigned int get_tlb_ts(const struct kvmppc_44x_tlbe *tlbe) | ||
67 | { | ||
68 | return (tlbe->word0 >> 8) & 0x1; | ||
69 | } | ||
70 | |||
71 | static inline unsigned int get_tlb_v(const struct kvmppc_44x_tlbe *tlbe) | ||
72 | { | ||
73 | return (tlbe->word0 >> 9) & 0x1; | ||
74 | } | ||
75 | |||
76 | static inline unsigned int get_mmucr_stid(const struct kvm_vcpu *vcpu) | ||
77 | { | ||
78 | return vcpu->arch.mmucr & 0xff; | ||
79 | } | ||
80 | |||
81 | static inline unsigned int get_mmucr_sts(const struct kvm_vcpu *vcpu) | ||
82 | { | ||
83 | return (vcpu->arch.mmucr >> 16) & 0x1; | ||
84 | } | ||
85 | |||
86 | #endif /* __KVM_POWERPC_TLB_H__ */ | ||
diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig index d6a53b95de94..602eb51d20bc 100644 --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig | |||
@@ -75,7 +75,6 @@ config KVM_BOOK3S_64 | |||
75 | config KVM_BOOK3S_64_HV | 75 | config KVM_BOOK3S_64_HV |
76 | tristate "KVM support for POWER7 and PPC970 using hypervisor mode in host" | 76 | tristate "KVM support for POWER7 and PPC970 using hypervisor mode in host" |
77 | depends on KVM_BOOK3S_64 | 77 | depends on KVM_BOOK3S_64 |
78 | depends on !CPU_LITTLE_ENDIAN | ||
79 | select KVM_BOOK3S_HV_POSSIBLE | 78 | select KVM_BOOK3S_HV_POSSIBLE |
80 | select MMU_NOTIFIER | 79 | select MMU_NOTIFIER |
81 | select CMA | 80 | select CMA |
@@ -113,23 +112,9 @@ config KVM_BOOK3S_64_PR | |||
113 | config KVM_BOOKE_HV | 112 | config KVM_BOOKE_HV |
114 | bool | 113 | bool |
115 | 114 | ||
116 | config KVM_440 | ||
117 | bool "KVM support for PowerPC 440 processors" | ||
118 | depends on 44x | ||
119 | select KVM | ||
120 | select KVM_MMIO | ||
121 | ---help--- | ||
122 | Support running unmodified 440 guest kernels in virtual machines on | ||
123 | 440 host processors. | ||
124 | |||
125 | This module provides access to the hardware capabilities through | ||
126 | a character device node named /dev/kvm. | ||
127 | |||
128 | If unsure, say N. | ||
129 | |||
130 | config KVM_EXIT_TIMING | 115 | config KVM_EXIT_TIMING |
131 | bool "Detailed exit timing" | 116 | bool "Detailed exit timing" |
132 | depends on KVM_440 || KVM_E500V2 || KVM_E500MC | 117 | depends on KVM_E500V2 || KVM_E500MC |
133 | ---help--- | 118 | ---help--- |
134 | Calculate elapsed time for every exit/enter cycle. A per-vcpu | 119 | Calculate elapsed time for every exit/enter cycle. A per-vcpu |
135 | report is available in debugfs kvm/vm#_vcpu#_timing. | 120 | report is available in debugfs kvm/vm#_vcpu#_timing. |
@@ -173,6 +158,7 @@ config KVM_MPIC | |||
173 | bool "KVM in-kernel MPIC emulation" | 158 | bool "KVM in-kernel MPIC emulation" |
174 | depends on KVM && E500 | 159 | depends on KVM && E500 |
175 | select HAVE_KVM_IRQCHIP | 160 | select HAVE_KVM_IRQCHIP |
161 | select HAVE_KVM_IRQFD | ||
176 | select HAVE_KVM_IRQ_ROUTING | 162 | select HAVE_KVM_IRQ_ROUTING |
177 | select HAVE_KVM_MSI | 163 | select HAVE_KVM_MSI |
178 | help | 164 | help |
@@ -184,6 +170,8 @@ config KVM_MPIC | |||
184 | config KVM_XICS | 170 | config KVM_XICS |
185 | bool "KVM in-kernel XICS emulation" | 171 | bool "KVM in-kernel XICS emulation" |
186 | depends on KVM_BOOK3S_64 && !KVM_MPIC | 172 | depends on KVM_BOOK3S_64 && !KVM_MPIC |
173 | select HAVE_KVM_IRQCHIP | ||
174 | select HAVE_KVM_IRQFD | ||
187 | ---help--- | 175 | ---help--- |
188 | Include support for the XICS (eXternal Interrupt Controller | 176 | Include support for the XICS (eXternal Interrupt Controller |
189 | Specification) interrupt controller architecture used on | 177 | Specification) interrupt controller architecture used on |
diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile index 72905c30082e..0570eef83fba 100644 --- a/arch/powerpc/kvm/Makefile +++ b/arch/powerpc/kvm/Makefile | |||
@@ -10,27 +10,17 @@ KVM := ../../../virt/kvm | |||
10 | common-objs-y = $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o \ | 10 | common-objs-y = $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o \ |
11 | $(KVM)/eventfd.o | 11 | $(KVM)/eventfd.o |
12 | 12 | ||
13 | CFLAGS_44x_tlb.o := -I. | ||
14 | CFLAGS_e500_mmu.o := -I. | 13 | CFLAGS_e500_mmu.o := -I. |
15 | CFLAGS_e500_mmu_host.o := -I. | 14 | CFLAGS_e500_mmu_host.o := -I. |
16 | CFLAGS_emulate.o := -I. | 15 | CFLAGS_emulate.o := -I. |
16 | CFLAGS_emulate_loadstore.o := -I. | ||
17 | 17 | ||
18 | common-objs-y += powerpc.o emulate.o | 18 | common-objs-y += powerpc.o emulate.o emulate_loadstore.o |
19 | obj-$(CONFIG_KVM_EXIT_TIMING) += timing.o | 19 | obj-$(CONFIG_KVM_EXIT_TIMING) += timing.o |
20 | obj-$(CONFIG_KVM_BOOK3S_HANDLER) += book3s_exports.o | 20 | obj-$(CONFIG_KVM_BOOK3S_HANDLER) += book3s_exports.o |
21 | 21 | ||
22 | AFLAGS_booke_interrupts.o := -I$(obj) | 22 | AFLAGS_booke_interrupts.o := -I$(obj) |
23 | 23 | ||
24 | kvm-440-objs := \ | ||
25 | $(common-objs-y) \ | ||
26 | booke.o \ | ||
27 | booke_emulate.o \ | ||
28 | booke_interrupts.o \ | ||
29 | 44x.o \ | ||
30 | 44x_tlb.o \ | ||
31 | 44x_emulate.o | ||
32 | kvm-objs-$(CONFIG_KVM_440) := $(kvm-440-objs) | ||
33 | |||
34 | kvm-e500-objs := \ | 24 | kvm-e500-objs := \ |
35 | $(common-objs-y) \ | 25 | $(common-objs-y) \ |
36 | booke.o \ | 26 | booke.o \ |
@@ -58,6 +48,7 @@ kvm-book3s_64-builtin-objs-$(CONFIG_KVM_BOOK3S_64_HANDLER) := \ | |||
58 | 48 | ||
59 | kvm-pr-y := \ | 49 | kvm-pr-y := \ |
60 | fpu.o \ | 50 | fpu.o \ |
51 | emulate.o \ | ||
61 | book3s_paired_singles.o \ | 52 | book3s_paired_singles.o \ |
62 | book3s_pr.o \ | 53 | book3s_pr.o \ |
63 | book3s_pr_papr.o \ | 54 | book3s_pr_papr.o \ |
@@ -100,7 +91,7 @@ kvm-book3s_64-module-objs += \ | |||
100 | $(KVM)/kvm_main.o \ | 91 | $(KVM)/kvm_main.o \ |
101 | $(KVM)/eventfd.o \ | 92 | $(KVM)/eventfd.o \ |
102 | powerpc.o \ | 93 | powerpc.o \ |
103 | emulate.o \ | 94 | emulate_loadstore.o \ |
104 | book3s.o \ | 95 | book3s.o \ |
105 | book3s_64_vio.o \ | 96 | book3s_64_vio.o \ |
106 | book3s_rtas.o \ | 97 | book3s_rtas.o \ |
@@ -126,7 +117,6 @@ kvm-objs-$(CONFIG_HAVE_KVM_IRQ_ROUTING) += $(KVM)/irqchip.o | |||
126 | 117 | ||
127 | kvm-objs := $(kvm-objs-m) $(kvm-objs-y) | 118 | kvm-objs := $(kvm-objs-m) $(kvm-objs-y) |
128 | 119 | ||
129 | obj-$(CONFIG_KVM_440) += kvm.o | ||
130 | obj-$(CONFIG_KVM_E500V2) += kvm.o | 120 | obj-$(CONFIG_KVM_E500V2) += kvm.o |
131 | obj-$(CONFIG_KVM_E500MC) += kvm.o | 121 | obj-$(CONFIG_KVM_E500MC) += kvm.o |
132 | obj-$(CONFIG_KVM_BOOK3S_64) += kvm.o | 122 | obj-$(CONFIG_KVM_BOOK3S_64) += kvm.o |
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index c254c27f240e..dd03f6b299ba 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c | |||
@@ -72,6 +72,17 @@ void kvmppc_core_load_guest_debugstate(struct kvm_vcpu *vcpu) | |||
72 | { | 72 | { |
73 | } | 73 | } |
74 | 74 | ||
75 | void kvmppc_unfixup_split_real(struct kvm_vcpu *vcpu) | ||
76 | { | ||
77 | if (vcpu->arch.hflags & BOOK3S_HFLAG_SPLIT_HACK) { | ||
78 | ulong pc = kvmppc_get_pc(vcpu); | ||
79 | if ((pc & SPLIT_HACK_MASK) == SPLIT_HACK_OFFS) | ||
80 | kvmppc_set_pc(vcpu, pc & ~SPLIT_HACK_MASK); | ||
81 | vcpu->arch.hflags &= ~BOOK3S_HFLAG_SPLIT_HACK; | ||
82 | } | ||
83 | } | ||
84 | EXPORT_SYMBOL_GPL(kvmppc_unfixup_split_real); | ||
85 | |||
75 | static inline unsigned long kvmppc_interrupt_offset(struct kvm_vcpu *vcpu) | 86 | static inline unsigned long kvmppc_interrupt_offset(struct kvm_vcpu *vcpu) |
76 | { | 87 | { |
77 | if (!is_kvmppc_hv_enabled(vcpu->kvm)) | 88 | if (!is_kvmppc_hv_enabled(vcpu->kvm)) |
@@ -118,6 +129,7 @@ static inline bool kvmppc_critical_section(struct kvm_vcpu *vcpu) | |||
118 | 129 | ||
119 | void kvmppc_inject_interrupt(struct kvm_vcpu *vcpu, int vec, u64 flags) | 130 | void kvmppc_inject_interrupt(struct kvm_vcpu *vcpu, int vec, u64 flags) |
120 | { | 131 | { |
132 | kvmppc_unfixup_split_real(vcpu); | ||
121 | kvmppc_set_srr0(vcpu, kvmppc_get_pc(vcpu)); | 133 | kvmppc_set_srr0(vcpu, kvmppc_get_pc(vcpu)); |
122 | kvmppc_set_srr1(vcpu, kvmppc_get_msr(vcpu) | flags); | 134 | kvmppc_set_srr1(vcpu, kvmppc_get_msr(vcpu) | flags); |
123 | kvmppc_set_pc(vcpu, kvmppc_interrupt_offset(vcpu) + vec); | 135 | kvmppc_set_pc(vcpu, kvmppc_interrupt_offset(vcpu) + vec); |
@@ -218,6 +230,23 @@ void kvmppc_core_dequeue_external(struct kvm_vcpu *vcpu) | |||
218 | kvmppc_book3s_dequeue_irqprio(vcpu, BOOK3S_INTERRUPT_EXTERNAL_LEVEL); | 230 | kvmppc_book3s_dequeue_irqprio(vcpu, BOOK3S_INTERRUPT_EXTERNAL_LEVEL); |
219 | } | 231 | } |
220 | 232 | ||
233 | void kvmppc_core_queue_data_storage(struct kvm_vcpu *vcpu, ulong dar, | ||
234 | ulong flags) | ||
235 | { | ||
236 | kvmppc_set_dar(vcpu, dar); | ||
237 | kvmppc_set_dsisr(vcpu, flags); | ||
238 | kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_DATA_STORAGE); | ||
239 | } | ||
240 | |||
241 | void kvmppc_core_queue_inst_storage(struct kvm_vcpu *vcpu, ulong flags) | ||
242 | { | ||
243 | u64 msr = kvmppc_get_msr(vcpu); | ||
244 | msr &= ~(SRR1_ISI_NOPT | SRR1_ISI_N_OR_G | SRR1_ISI_PROT); | ||
245 | msr |= flags & (SRR1_ISI_NOPT | SRR1_ISI_N_OR_G | SRR1_ISI_PROT); | ||
246 | kvmppc_set_msr_fast(vcpu, msr); | ||
247 | kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_INST_STORAGE); | ||
248 | } | ||
249 | |||
221 | int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority) | 250 | int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority) |
222 | { | 251 | { |
223 | int deliver = 1; | 252 | int deliver = 1; |
@@ -342,18 +371,18 @@ int kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu) | |||
342 | } | 371 | } |
343 | EXPORT_SYMBOL_GPL(kvmppc_core_prepare_to_enter); | 372 | EXPORT_SYMBOL_GPL(kvmppc_core_prepare_to_enter); |
344 | 373 | ||
345 | pfn_t kvmppc_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn, bool writing, | 374 | pfn_t kvmppc_gpa_to_pfn(struct kvm_vcpu *vcpu, gpa_t gpa, bool writing, |
346 | bool *writable) | 375 | bool *writable) |
347 | { | 376 | { |
348 | ulong mp_pa = vcpu->arch.magic_page_pa; | 377 | ulong mp_pa = vcpu->arch.magic_page_pa & KVM_PAM; |
378 | gfn_t gfn = gpa >> PAGE_SHIFT; | ||
349 | 379 | ||
350 | if (!(kvmppc_get_msr(vcpu) & MSR_SF)) | 380 | if (!(kvmppc_get_msr(vcpu) & MSR_SF)) |
351 | mp_pa = (uint32_t)mp_pa; | 381 | mp_pa = (uint32_t)mp_pa; |
352 | 382 | ||
353 | /* Magic page override */ | 383 | /* Magic page override */ |
354 | if (unlikely(mp_pa) && | 384 | gpa &= ~0xFFFULL; |
355 | unlikely(((gfn << PAGE_SHIFT) & KVM_PAM) == | 385 | if (unlikely(mp_pa) && unlikely((gpa & KVM_PAM) == mp_pa)) { |
356 | ((mp_pa & PAGE_MASK) & KVM_PAM))) { | ||
357 | ulong shared_page = ((ulong)vcpu->arch.shared) & PAGE_MASK; | 386 | ulong shared_page = ((ulong)vcpu->arch.shared) & PAGE_MASK; |
358 | pfn_t pfn; | 387 | pfn_t pfn; |
359 | 388 | ||
@@ -366,11 +395,13 @@ pfn_t kvmppc_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn, bool writing, | |||
366 | 395 | ||
367 | return gfn_to_pfn_prot(vcpu->kvm, gfn, writing, writable); | 396 | return gfn_to_pfn_prot(vcpu->kvm, gfn, writing, writable); |
368 | } | 397 | } |
369 | EXPORT_SYMBOL_GPL(kvmppc_gfn_to_pfn); | 398 | EXPORT_SYMBOL_GPL(kvmppc_gpa_to_pfn); |
370 | 399 | ||
371 | static int kvmppc_xlate(struct kvm_vcpu *vcpu, ulong eaddr, bool data, | 400 | int kvmppc_xlate(struct kvm_vcpu *vcpu, ulong eaddr, enum xlate_instdata xlid, |
372 | bool iswrite, struct kvmppc_pte *pte) | 401 | enum xlate_readwrite xlrw, struct kvmppc_pte *pte) |
373 | { | 402 | { |
403 | bool data = (xlid == XLATE_DATA); | ||
404 | bool iswrite = (xlrw == XLATE_WRITE); | ||
374 | int relocated = (kvmppc_get_msr(vcpu) & (data ? MSR_DR : MSR_IR)); | 405 | int relocated = (kvmppc_get_msr(vcpu) & (data ? MSR_DR : MSR_IR)); |
375 | int r; | 406 | int r; |
376 | 407 | ||
@@ -384,88 +415,34 @@ static int kvmppc_xlate(struct kvm_vcpu *vcpu, ulong eaddr, bool data, | |||
384 | pte->may_write = true; | 415 | pte->may_write = true; |
385 | pte->may_execute = true; | 416 | pte->may_execute = true; |
386 | r = 0; | 417 | r = 0; |
418 | |||
419 | if ((kvmppc_get_msr(vcpu) & (MSR_IR | MSR_DR)) == MSR_DR && | ||
420 | !data) { | ||
421 | if ((vcpu->arch.hflags & BOOK3S_HFLAG_SPLIT_HACK) && | ||
422 | ((eaddr & SPLIT_HACK_MASK) == SPLIT_HACK_OFFS)) | ||
423 | pte->raddr &= ~SPLIT_HACK_MASK; | ||
424 | } | ||
387 | } | 425 | } |
388 | 426 | ||
389 | return r; | 427 | return r; |
390 | } | 428 | } |
391 | 429 | ||
392 | static hva_t kvmppc_bad_hva(void) | 430 | int kvmppc_load_last_inst(struct kvm_vcpu *vcpu, enum instruction_type type, |
393 | { | 431 | u32 *inst) |
394 | return PAGE_OFFSET; | ||
395 | } | ||
396 | |||
397 | static hva_t kvmppc_pte_to_hva(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte, | ||
398 | bool read) | ||
399 | { | ||
400 | hva_t hpage; | ||
401 | |||
402 | if (read && !pte->may_read) | ||
403 | goto err; | ||
404 | |||
405 | if (!read && !pte->may_write) | ||
406 | goto err; | ||
407 | |||
408 | hpage = gfn_to_hva(vcpu->kvm, pte->raddr >> PAGE_SHIFT); | ||
409 | if (kvm_is_error_hva(hpage)) | ||
410 | goto err; | ||
411 | |||
412 | return hpage | (pte->raddr & ~PAGE_MASK); | ||
413 | err: | ||
414 | return kvmppc_bad_hva(); | ||
415 | } | ||
416 | |||
417 | int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, | ||
418 | bool data) | ||
419 | { | ||
420 | struct kvmppc_pte pte; | ||
421 | |||
422 | vcpu->stat.st++; | ||
423 | |||
424 | if (kvmppc_xlate(vcpu, *eaddr, data, true, &pte)) | ||
425 | return -ENOENT; | ||
426 | |||
427 | *eaddr = pte.raddr; | ||
428 | |||
429 | if (!pte.may_write) | ||
430 | return -EPERM; | ||
431 | |||
432 | if (kvm_write_guest(vcpu->kvm, pte.raddr, ptr, size)) | ||
433 | return EMULATE_DO_MMIO; | ||
434 | |||
435 | return EMULATE_DONE; | ||
436 | } | ||
437 | EXPORT_SYMBOL_GPL(kvmppc_st); | ||
438 | |||
439 | int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, | ||
440 | bool data) | ||
441 | { | 432 | { |
442 | struct kvmppc_pte pte; | 433 | ulong pc = kvmppc_get_pc(vcpu); |
443 | hva_t hva = *eaddr; | 434 | int r; |
444 | |||
445 | vcpu->stat.ld++; | ||
446 | |||
447 | if (kvmppc_xlate(vcpu, *eaddr, data, false, &pte)) | ||
448 | goto nopte; | ||
449 | |||
450 | *eaddr = pte.raddr; | ||
451 | |||
452 | hva = kvmppc_pte_to_hva(vcpu, &pte, true); | ||
453 | if (kvm_is_error_hva(hva)) | ||
454 | goto mmio; | ||
455 | |||
456 | if (copy_from_user(ptr, (void __user *)hva, size)) { | ||
457 | printk(KERN_INFO "kvmppc_ld at 0x%lx failed\n", hva); | ||
458 | goto mmio; | ||
459 | } | ||
460 | 435 | ||
461 | return EMULATE_DONE; | 436 | if (type == INST_SC) |
437 | pc -= 4; | ||
462 | 438 | ||
463 | nopte: | 439 | r = kvmppc_ld(vcpu, &pc, sizeof(u32), inst, false); |
464 | return -ENOENT; | 440 | if (r == EMULATE_DONE) |
465 | mmio: | 441 | return r; |
466 | return EMULATE_DO_MMIO; | 442 | else |
443 | return EMULATE_AGAIN; | ||
467 | } | 444 | } |
468 | EXPORT_SYMBOL_GPL(kvmppc_ld); | 445 | EXPORT_SYMBOL_GPL(kvmppc_load_last_inst); |
469 | 446 | ||
470 | int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) | 447 | int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) |
471 | { | 448 | { |
@@ -646,6 +623,12 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) | |||
646 | case KVM_REG_PPC_BESCR: | 623 | case KVM_REG_PPC_BESCR: |
647 | val = get_reg_val(reg->id, vcpu->arch.bescr); | 624 | val = get_reg_val(reg->id, vcpu->arch.bescr); |
648 | break; | 625 | break; |
626 | case KVM_REG_PPC_VTB: | ||
627 | val = get_reg_val(reg->id, vcpu->arch.vtb); | ||
628 | break; | ||
629 | case KVM_REG_PPC_IC: | ||
630 | val = get_reg_val(reg->id, vcpu->arch.ic); | ||
631 | break; | ||
649 | default: | 632 | default: |
650 | r = -EINVAL; | 633 | r = -EINVAL; |
651 | break; | 634 | break; |
@@ -750,6 +733,12 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) | |||
750 | case KVM_REG_PPC_BESCR: | 733 | case KVM_REG_PPC_BESCR: |
751 | vcpu->arch.bescr = set_reg_val(reg->id, val); | 734 | vcpu->arch.bescr = set_reg_val(reg->id, val); |
752 | break; | 735 | break; |
736 | case KVM_REG_PPC_VTB: | ||
737 | vcpu->arch.vtb = set_reg_val(reg->id, val); | ||
738 | break; | ||
739 | case KVM_REG_PPC_IC: | ||
740 | vcpu->arch.ic = set_reg_val(reg->id, val); | ||
741 | break; | ||
753 | default: | 742 | default: |
754 | r = -EINVAL; | 743 | r = -EINVAL; |
755 | break; | 744 | break; |
@@ -913,6 +902,11 @@ int kvmppc_core_check_processor_compat(void) | |||
913 | return 0; | 902 | return 0; |
914 | } | 903 | } |
915 | 904 | ||
905 | int kvmppc_book3s_hcall_implemented(struct kvm *kvm, unsigned long hcall) | ||
906 | { | ||
907 | return kvm->arch.kvm_ops->hcall_implemented(hcall); | ||
908 | } | ||
909 | |||
916 | static int kvmppc_book3s_init(void) | 910 | static int kvmppc_book3s_init(void) |
917 | { | 911 | { |
918 | int r; | 912 | int r; |
diff --git a/arch/powerpc/kvm/book3s_32_mmu.c b/arch/powerpc/kvm/book3s_32_mmu.c index 93503bbdae43..cd0b0730e29e 100644 --- a/arch/powerpc/kvm/book3s_32_mmu.c +++ b/arch/powerpc/kvm/book3s_32_mmu.c | |||
@@ -335,7 +335,7 @@ static int kvmppc_mmu_book3s_32_xlate(struct kvm_vcpu *vcpu, gva_t eaddr, | |||
335 | if (r < 0) | 335 | if (r < 0) |
336 | r = kvmppc_mmu_book3s_32_xlate_pte(vcpu, eaddr, pte, | 336 | r = kvmppc_mmu_book3s_32_xlate_pte(vcpu, eaddr, pte, |
337 | data, iswrite, true); | 337 | data, iswrite, true); |
338 | if (r < 0) | 338 | if (r == -ENOENT) |
339 | r = kvmppc_mmu_book3s_32_xlate_pte(vcpu, eaddr, pte, | 339 | r = kvmppc_mmu_book3s_32_xlate_pte(vcpu, eaddr, pte, |
340 | data, iswrite, false); | 340 | data, iswrite, false); |
341 | 341 | ||
diff --git a/arch/powerpc/kvm/book3s_32_mmu_host.c b/arch/powerpc/kvm/book3s_32_mmu_host.c index 678e75370495..2035d16a9262 100644 --- a/arch/powerpc/kvm/book3s_32_mmu_host.c +++ b/arch/powerpc/kvm/book3s_32_mmu_host.c | |||
@@ -156,11 +156,10 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte, | |||
156 | bool writable; | 156 | bool writable; |
157 | 157 | ||
158 | /* Get host physical address for gpa */ | 158 | /* Get host physical address for gpa */ |
159 | hpaddr = kvmppc_gfn_to_pfn(vcpu, orig_pte->raddr >> PAGE_SHIFT, | 159 | hpaddr = kvmppc_gpa_to_pfn(vcpu, orig_pte->raddr, iswrite, &writable); |
160 | iswrite, &writable); | ||
161 | if (is_error_noslot_pfn(hpaddr)) { | 160 | if (is_error_noslot_pfn(hpaddr)) { |
162 | printk(KERN_INFO "Couldn't get guest page for gfn %lx!\n", | 161 | printk(KERN_INFO "Couldn't get guest page for gpa %lx!\n", |
163 | orig_pte->eaddr); | 162 | orig_pte->raddr); |
164 | r = -EINVAL; | 163 | r = -EINVAL; |
165 | goto out; | 164 | goto out; |
166 | } | 165 | } |
diff --git a/arch/powerpc/kvm/book3s_64_mmu_host.c b/arch/powerpc/kvm/book3s_64_mmu_host.c index 0ac98392f363..b982d925c710 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_host.c +++ b/arch/powerpc/kvm/book3s_64_mmu_host.c | |||
@@ -104,9 +104,10 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte, | |||
104 | smp_rmb(); | 104 | smp_rmb(); |
105 | 105 | ||
106 | /* Get host physical address for gpa */ | 106 | /* Get host physical address for gpa */ |
107 | pfn = kvmppc_gfn_to_pfn(vcpu, gfn, iswrite, &writable); | 107 | pfn = kvmppc_gpa_to_pfn(vcpu, orig_pte->raddr, iswrite, &writable); |
108 | if (is_error_noslot_pfn(pfn)) { | 108 | if (is_error_noslot_pfn(pfn)) { |
109 | printk(KERN_INFO "Couldn't get guest page for gfn %lx!\n", gfn); | 109 | printk(KERN_INFO "Couldn't get guest page for gpa %lx!\n", |
110 | orig_pte->raddr); | ||
110 | r = -EINVAL; | 111 | r = -EINVAL; |
111 | goto out; | 112 | goto out; |
112 | } | 113 | } |
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c index a01744fc3483..72c20bb16d26 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c | |||
@@ -448,7 +448,7 @@ static int kvmppc_mmu_book3s_64_hv_xlate(struct kvm_vcpu *vcpu, gva_t eaddr, | |||
448 | unsigned long slb_v; | 448 | unsigned long slb_v; |
449 | unsigned long pp, key; | 449 | unsigned long pp, key; |
450 | unsigned long v, gr; | 450 | unsigned long v, gr; |
451 | unsigned long *hptep; | 451 | __be64 *hptep; |
452 | int index; | 452 | int index; |
453 | int virtmode = vcpu->arch.shregs.msr & (data ? MSR_DR : MSR_IR); | 453 | int virtmode = vcpu->arch.shregs.msr & (data ? MSR_DR : MSR_IR); |
454 | 454 | ||
@@ -471,13 +471,13 @@ static int kvmppc_mmu_book3s_64_hv_xlate(struct kvm_vcpu *vcpu, gva_t eaddr, | |||
471 | preempt_enable(); | 471 | preempt_enable(); |
472 | return -ENOENT; | 472 | return -ENOENT; |
473 | } | 473 | } |
474 | hptep = (unsigned long *)(kvm->arch.hpt_virt + (index << 4)); | 474 | hptep = (__be64 *)(kvm->arch.hpt_virt + (index << 4)); |
475 | v = hptep[0] & ~HPTE_V_HVLOCK; | 475 | v = be64_to_cpu(hptep[0]) & ~HPTE_V_HVLOCK; |
476 | gr = kvm->arch.revmap[index].guest_rpte; | 476 | gr = kvm->arch.revmap[index].guest_rpte; |
477 | 477 | ||
478 | /* Unlock the HPTE */ | 478 | /* Unlock the HPTE */ |
479 | asm volatile("lwsync" : : : "memory"); | 479 | asm volatile("lwsync" : : : "memory"); |
480 | hptep[0] = v; | 480 | hptep[0] = cpu_to_be64(v); |
481 | preempt_enable(); | 481 | preempt_enable(); |
482 | 482 | ||
483 | gpte->eaddr = eaddr; | 483 | gpte->eaddr = eaddr; |
@@ -528,21 +528,14 @@ static int instruction_is_store(unsigned int instr) | |||
528 | static int kvmppc_hv_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu, | 528 | static int kvmppc_hv_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu, |
529 | unsigned long gpa, gva_t ea, int is_store) | 529 | unsigned long gpa, gva_t ea, int is_store) |
530 | { | 530 | { |
531 | int ret; | ||
532 | u32 last_inst; | 531 | u32 last_inst; |
533 | unsigned long srr0 = kvmppc_get_pc(vcpu); | ||
534 | 532 | ||
535 | /* We try to load the last instruction. We don't let | 533 | /* |
536 | * emulate_instruction do it as it doesn't check what | ||
537 | * kvmppc_ld returns. | ||
538 | * If we fail, we just return to the guest and try executing it again. | 534 | * If we fail, we just return to the guest and try executing it again. |
539 | */ | 535 | */ |
540 | if (vcpu->arch.last_inst == KVM_INST_FETCH_FAILED) { | 536 | if (kvmppc_get_last_inst(vcpu, INST_GENERIC, &last_inst) != |
541 | ret = kvmppc_ld(vcpu, &srr0, sizeof(u32), &last_inst, false); | 537 | EMULATE_DONE) |
542 | if (ret != EMULATE_DONE || last_inst == KVM_INST_FETCH_FAILED) | 538 | return RESUME_GUEST; |
543 | return RESUME_GUEST; | ||
544 | vcpu->arch.last_inst = last_inst; | ||
545 | } | ||
546 | 539 | ||
547 | /* | 540 | /* |
548 | * WARNING: We do not know for sure whether the instruction we just | 541 | * WARNING: We do not know for sure whether the instruction we just |
@@ -556,7 +549,7 @@ static int kvmppc_hv_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
556 | * we just return and retry the instruction. | 549 | * we just return and retry the instruction. |
557 | */ | 550 | */ |
558 | 551 | ||
559 | if (instruction_is_store(kvmppc_get_last_inst(vcpu)) != !!is_store) | 552 | if (instruction_is_store(last_inst) != !!is_store) |
560 | return RESUME_GUEST; | 553 | return RESUME_GUEST; |
561 | 554 | ||
562 | /* | 555 | /* |
@@ -581,7 +574,8 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
581 | unsigned long ea, unsigned long dsisr) | 574 | unsigned long ea, unsigned long dsisr) |
582 | { | 575 | { |
583 | struct kvm *kvm = vcpu->kvm; | 576 | struct kvm *kvm = vcpu->kvm; |
584 | unsigned long *hptep, hpte[3], r; | 577 | unsigned long hpte[3], r; |
578 | __be64 *hptep; | ||
585 | unsigned long mmu_seq, psize, pte_size; | 579 | unsigned long mmu_seq, psize, pte_size; |
586 | unsigned long gpa_base, gfn_base; | 580 | unsigned long gpa_base, gfn_base; |
587 | unsigned long gpa, gfn, hva, pfn; | 581 | unsigned long gpa, gfn, hva, pfn; |
@@ -604,16 +598,16 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
604 | if (ea != vcpu->arch.pgfault_addr) | 598 | if (ea != vcpu->arch.pgfault_addr) |
605 | return RESUME_GUEST; | 599 | return RESUME_GUEST; |
606 | index = vcpu->arch.pgfault_index; | 600 | index = vcpu->arch.pgfault_index; |
607 | hptep = (unsigned long *)(kvm->arch.hpt_virt + (index << 4)); | 601 | hptep = (__be64 *)(kvm->arch.hpt_virt + (index << 4)); |
608 | rev = &kvm->arch.revmap[index]; | 602 | rev = &kvm->arch.revmap[index]; |
609 | preempt_disable(); | 603 | preempt_disable(); |
610 | while (!try_lock_hpte(hptep, HPTE_V_HVLOCK)) | 604 | while (!try_lock_hpte(hptep, HPTE_V_HVLOCK)) |
611 | cpu_relax(); | 605 | cpu_relax(); |
612 | hpte[0] = hptep[0] & ~HPTE_V_HVLOCK; | 606 | hpte[0] = be64_to_cpu(hptep[0]) & ~HPTE_V_HVLOCK; |
613 | hpte[1] = hptep[1]; | 607 | hpte[1] = be64_to_cpu(hptep[1]); |
614 | hpte[2] = r = rev->guest_rpte; | 608 | hpte[2] = r = rev->guest_rpte; |
615 | asm volatile("lwsync" : : : "memory"); | 609 | asm volatile("lwsync" : : : "memory"); |
616 | hptep[0] = hpte[0]; | 610 | hptep[0] = cpu_to_be64(hpte[0]); |
617 | preempt_enable(); | 611 | preempt_enable(); |
618 | 612 | ||
619 | if (hpte[0] != vcpu->arch.pgfault_hpte[0] || | 613 | if (hpte[0] != vcpu->arch.pgfault_hpte[0] || |
@@ -729,8 +723,9 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
729 | preempt_disable(); | 723 | preempt_disable(); |
730 | while (!try_lock_hpte(hptep, HPTE_V_HVLOCK)) | 724 | while (!try_lock_hpte(hptep, HPTE_V_HVLOCK)) |
731 | cpu_relax(); | 725 | cpu_relax(); |
732 | if ((hptep[0] & ~HPTE_V_HVLOCK) != hpte[0] || hptep[1] != hpte[1] || | 726 | if ((be64_to_cpu(hptep[0]) & ~HPTE_V_HVLOCK) != hpte[0] || |
733 | rev->guest_rpte != hpte[2]) | 727 | be64_to_cpu(hptep[1]) != hpte[1] || |
728 | rev->guest_rpte != hpte[2]) | ||
734 | /* HPTE has been changed under us; let the guest retry */ | 729 | /* HPTE has been changed under us; let the guest retry */ |
735 | goto out_unlock; | 730 | goto out_unlock; |
736 | hpte[0] = (hpte[0] & ~HPTE_V_ABSENT) | HPTE_V_VALID; | 731 | hpte[0] = (hpte[0] & ~HPTE_V_ABSENT) | HPTE_V_VALID; |
@@ -750,20 +745,20 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
750 | rcbits = *rmap >> KVMPPC_RMAP_RC_SHIFT; | 745 | rcbits = *rmap >> KVMPPC_RMAP_RC_SHIFT; |
751 | r &= rcbits | ~(HPTE_R_R | HPTE_R_C); | 746 | r &= rcbits | ~(HPTE_R_R | HPTE_R_C); |
752 | 747 | ||
753 | if (hptep[0] & HPTE_V_VALID) { | 748 | if (be64_to_cpu(hptep[0]) & HPTE_V_VALID) { |
754 | /* HPTE was previously valid, so we need to invalidate it */ | 749 | /* HPTE was previously valid, so we need to invalidate it */ |
755 | unlock_rmap(rmap); | 750 | unlock_rmap(rmap); |
756 | hptep[0] |= HPTE_V_ABSENT; | 751 | hptep[0] |= cpu_to_be64(HPTE_V_ABSENT); |
757 | kvmppc_invalidate_hpte(kvm, hptep, index); | 752 | kvmppc_invalidate_hpte(kvm, hptep, index); |
758 | /* don't lose previous R and C bits */ | 753 | /* don't lose previous R and C bits */ |
759 | r |= hptep[1] & (HPTE_R_R | HPTE_R_C); | 754 | r |= be64_to_cpu(hptep[1]) & (HPTE_R_R | HPTE_R_C); |
760 | } else { | 755 | } else { |
761 | kvmppc_add_revmap_chain(kvm, rev, rmap, index, 0); | 756 | kvmppc_add_revmap_chain(kvm, rev, rmap, index, 0); |
762 | } | 757 | } |
763 | 758 | ||
764 | hptep[1] = r; | 759 | hptep[1] = cpu_to_be64(r); |
765 | eieio(); | 760 | eieio(); |
766 | hptep[0] = hpte[0]; | 761 | hptep[0] = cpu_to_be64(hpte[0]); |
767 | asm volatile("ptesync" : : : "memory"); | 762 | asm volatile("ptesync" : : : "memory"); |
768 | preempt_enable(); | 763 | preempt_enable(); |
769 | if (page && hpte_is_writable(r)) | 764 | if (page && hpte_is_writable(r)) |
@@ -782,7 +777,7 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
782 | return ret; | 777 | return ret; |
783 | 778 | ||
784 | out_unlock: | 779 | out_unlock: |
785 | hptep[0] &= ~HPTE_V_HVLOCK; | 780 | hptep[0] &= ~cpu_to_be64(HPTE_V_HVLOCK); |
786 | preempt_enable(); | 781 | preempt_enable(); |
787 | goto out_put; | 782 | goto out_put; |
788 | } | 783 | } |
@@ -858,7 +853,7 @@ static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp, | |||
858 | { | 853 | { |
859 | struct revmap_entry *rev = kvm->arch.revmap; | 854 | struct revmap_entry *rev = kvm->arch.revmap; |
860 | unsigned long h, i, j; | 855 | unsigned long h, i, j; |
861 | unsigned long *hptep; | 856 | __be64 *hptep; |
862 | unsigned long ptel, psize, rcbits; | 857 | unsigned long ptel, psize, rcbits; |
863 | 858 | ||
864 | for (;;) { | 859 | for (;;) { |
@@ -874,11 +869,11 @@ static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp, | |||
874 | * rmap chain lock. | 869 | * rmap chain lock. |
875 | */ | 870 | */ |
876 | i = *rmapp & KVMPPC_RMAP_INDEX; | 871 | i = *rmapp & KVMPPC_RMAP_INDEX; |
877 | hptep = (unsigned long *) (kvm->arch.hpt_virt + (i << 4)); | 872 | hptep = (__be64 *) (kvm->arch.hpt_virt + (i << 4)); |
878 | if (!try_lock_hpte(hptep, HPTE_V_HVLOCK)) { | 873 | if (!try_lock_hpte(hptep, HPTE_V_HVLOCK)) { |
879 | /* unlock rmap before spinning on the HPTE lock */ | 874 | /* unlock rmap before spinning on the HPTE lock */ |
880 | unlock_rmap(rmapp); | 875 | unlock_rmap(rmapp); |
881 | while (hptep[0] & HPTE_V_HVLOCK) | 876 | while (be64_to_cpu(hptep[0]) & HPTE_V_HVLOCK) |
882 | cpu_relax(); | 877 | cpu_relax(); |
883 | continue; | 878 | continue; |
884 | } | 879 | } |
@@ -897,14 +892,14 @@ static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp, | |||
897 | 892 | ||
898 | /* Now check and modify the HPTE */ | 893 | /* Now check and modify the HPTE */ |
899 | ptel = rev[i].guest_rpte; | 894 | ptel = rev[i].guest_rpte; |
900 | psize = hpte_page_size(hptep[0], ptel); | 895 | psize = hpte_page_size(be64_to_cpu(hptep[0]), ptel); |
901 | if ((hptep[0] & HPTE_V_VALID) && | 896 | if ((be64_to_cpu(hptep[0]) & HPTE_V_VALID) && |
902 | hpte_rpn(ptel, psize) == gfn) { | 897 | hpte_rpn(ptel, psize) == gfn) { |
903 | if (kvm->arch.using_mmu_notifiers) | 898 | if (kvm->arch.using_mmu_notifiers) |
904 | hptep[0] |= HPTE_V_ABSENT; | 899 | hptep[0] |= cpu_to_be64(HPTE_V_ABSENT); |
905 | kvmppc_invalidate_hpte(kvm, hptep, i); | 900 | kvmppc_invalidate_hpte(kvm, hptep, i); |
906 | /* Harvest R and C */ | 901 | /* Harvest R and C */ |
907 | rcbits = hptep[1] & (HPTE_R_R | HPTE_R_C); | 902 | rcbits = be64_to_cpu(hptep[1]) & (HPTE_R_R | HPTE_R_C); |
908 | *rmapp |= rcbits << KVMPPC_RMAP_RC_SHIFT; | 903 | *rmapp |= rcbits << KVMPPC_RMAP_RC_SHIFT; |
909 | if (rcbits & ~rev[i].guest_rpte) { | 904 | if (rcbits & ~rev[i].guest_rpte) { |
910 | rev[i].guest_rpte = ptel | rcbits; | 905 | rev[i].guest_rpte = ptel | rcbits; |
@@ -912,7 +907,7 @@ static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp, | |||
912 | } | 907 | } |
913 | } | 908 | } |
914 | unlock_rmap(rmapp); | 909 | unlock_rmap(rmapp); |
915 | hptep[0] &= ~HPTE_V_HVLOCK; | 910 | hptep[0] &= ~cpu_to_be64(HPTE_V_HVLOCK); |
916 | } | 911 | } |
917 | return 0; | 912 | return 0; |
918 | } | 913 | } |
@@ -959,7 +954,7 @@ static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp, | |||
959 | { | 954 | { |
960 | struct revmap_entry *rev = kvm->arch.revmap; | 955 | struct revmap_entry *rev = kvm->arch.revmap; |
961 | unsigned long head, i, j; | 956 | unsigned long head, i, j; |
962 | unsigned long *hptep; | 957 | __be64 *hptep; |
963 | int ret = 0; | 958 | int ret = 0; |
964 | 959 | ||
965 | retry: | 960 | retry: |
@@ -975,23 +970,24 @@ static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp, | |||
975 | 970 | ||
976 | i = head = *rmapp & KVMPPC_RMAP_INDEX; | 971 | i = head = *rmapp & KVMPPC_RMAP_INDEX; |
977 | do { | 972 | do { |
978 | hptep = (unsigned long *) (kvm->arch.hpt_virt + (i << 4)); | 973 | hptep = (__be64 *) (kvm->arch.hpt_virt + (i << 4)); |
979 | j = rev[i].forw; | 974 | j = rev[i].forw; |
980 | 975 | ||
981 | /* If this HPTE isn't referenced, ignore it */ | 976 | /* If this HPTE isn't referenced, ignore it */ |
982 | if (!(hptep[1] & HPTE_R_R)) | 977 | if (!(be64_to_cpu(hptep[1]) & HPTE_R_R)) |
983 | continue; | 978 | continue; |
984 | 979 | ||
985 | if (!try_lock_hpte(hptep, HPTE_V_HVLOCK)) { | 980 | if (!try_lock_hpte(hptep, HPTE_V_HVLOCK)) { |
986 | /* unlock rmap before spinning on the HPTE lock */ | 981 | /* unlock rmap before spinning on the HPTE lock */ |
987 | unlock_rmap(rmapp); | 982 | unlock_rmap(rmapp); |
988 | while (hptep[0] & HPTE_V_HVLOCK) | 983 | while (be64_to_cpu(hptep[0]) & HPTE_V_HVLOCK) |
989 | cpu_relax(); | 984 | cpu_relax(); |
990 | goto retry; | 985 | goto retry; |
991 | } | 986 | } |
992 | 987 | ||
993 | /* Now check and modify the HPTE */ | 988 | /* Now check and modify the HPTE */ |
994 | if ((hptep[0] & HPTE_V_VALID) && (hptep[1] & HPTE_R_R)) { | 989 | if ((be64_to_cpu(hptep[0]) & HPTE_V_VALID) && |
990 | (be64_to_cpu(hptep[1]) & HPTE_R_R)) { | ||
995 | kvmppc_clear_ref_hpte(kvm, hptep, i); | 991 | kvmppc_clear_ref_hpte(kvm, hptep, i); |
996 | if (!(rev[i].guest_rpte & HPTE_R_R)) { | 992 | if (!(rev[i].guest_rpte & HPTE_R_R)) { |
997 | rev[i].guest_rpte |= HPTE_R_R; | 993 | rev[i].guest_rpte |= HPTE_R_R; |
@@ -999,7 +995,7 @@ static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp, | |||
999 | } | 995 | } |
1000 | ret = 1; | 996 | ret = 1; |
1001 | } | 997 | } |
1002 | hptep[0] &= ~HPTE_V_HVLOCK; | 998 | hptep[0] &= ~cpu_to_be64(HPTE_V_HVLOCK); |
1003 | } while ((i = j) != head); | 999 | } while ((i = j) != head); |
1004 | 1000 | ||
1005 | unlock_rmap(rmapp); | 1001 | unlock_rmap(rmapp); |
@@ -1033,7 +1029,7 @@ static int kvm_test_age_rmapp(struct kvm *kvm, unsigned long *rmapp, | |||
1033 | do { | 1029 | do { |
1034 | hp = (unsigned long *)(kvm->arch.hpt_virt + (i << 4)); | 1030 | hp = (unsigned long *)(kvm->arch.hpt_virt + (i << 4)); |
1035 | j = rev[i].forw; | 1031 | j = rev[i].forw; |
1036 | if (hp[1] & HPTE_R_R) | 1032 | if (be64_to_cpu(hp[1]) & HPTE_R_R) |
1037 | goto out; | 1033 | goto out; |
1038 | } while ((i = j) != head); | 1034 | } while ((i = j) != head); |
1039 | } | 1035 | } |
@@ -1073,7 +1069,7 @@ static int kvm_test_clear_dirty_npages(struct kvm *kvm, unsigned long *rmapp) | |||
1073 | unsigned long head, i, j; | 1069 | unsigned long head, i, j; |
1074 | unsigned long n; | 1070 | unsigned long n; |
1075 | unsigned long v, r; | 1071 | unsigned long v, r; |
1076 | unsigned long *hptep; | 1072 | __be64 *hptep; |
1077 | int npages_dirty = 0; | 1073 | int npages_dirty = 0; |
1078 | 1074 | ||
1079 | retry: | 1075 | retry: |
@@ -1089,7 +1085,8 @@ static int kvm_test_clear_dirty_npages(struct kvm *kvm, unsigned long *rmapp) | |||
1089 | 1085 | ||
1090 | i = head = *rmapp & KVMPPC_RMAP_INDEX; | 1086 | i = head = *rmapp & KVMPPC_RMAP_INDEX; |
1091 | do { | 1087 | do { |
1092 | hptep = (unsigned long *) (kvm->arch.hpt_virt + (i << 4)); | 1088 | unsigned long hptep1; |
1089 | hptep = (__be64 *) (kvm->arch.hpt_virt + (i << 4)); | ||
1093 | j = rev[i].forw; | 1090 | j = rev[i].forw; |
1094 | 1091 | ||
1095 | /* | 1092 | /* |
@@ -1106,29 +1103,30 @@ static int kvm_test_clear_dirty_npages(struct kvm *kvm, unsigned long *rmapp) | |||
1106 | * Otherwise we need to do the tlbie even if C==0 in | 1103 | * Otherwise we need to do the tlbie even if C==0 in |
1107 | * order to pick up any delayed writeback of C. | 1104 | * order to pick up any delayed writeback of C. |
1108 | */ | 1105 | */ |
1109 | if (!(hptep[1] & HPTE_R_C) && | 1106 | hptep1 = be64_to_cpu(hptep[1]); |
1110 | (!hpte_is_writable(hptep[1]) || vcpus_running(kvm))) | 1107 | if (!(hptep1 & HPTE_R_C) && |
1108 | (!hpte_is_writable(hptep1) || vcpus_running(kvm))) | ||
1111 | continue; | 1109 | continue; |
1112 | 1110 | ||
1113 | if (!try_lock_hpte(hptep, HPTE_V_HVLOCK)) { | 1111 | if (!try_lock_hpte(hptep, HPTE_V_HVLOCK)) { |
1114 | /* unlock rmap before spinning on the HPTE lock */ | 1112 | /* unlock rmap before spinning on the HPTE lock */ |
1115 | unlock_rmap(rmapp); | 1113 | unlock_rmap(rmapp); |
1116 | while (hptep[0] & HPTE_V_HVLOCK) | 1114 | while (hptep[0] & cpu_to_be64(HPTE_V_HVLOCK)) |
1117 | cpu_relax(); | 1115 | cpu_relax(); |
1118 | goto retry; | 1116 | goto retry; |
1119 | } | 1117 | } |
1120 | 1118 | ||
1121 | /* Now check and modify the HPTE */ | 1119 | /* Now check and modify the HPTE */ |
1122 | if (!(hptep[0] & HPTE_V_VALID)) | 1120 | if (!(hptep[0] & cpu_to_be64(HPTE_V_VALID))) |
1123 | continue; | 1121 | continue; |
1124 | 1122 | ||
1125 | /* need to make it temporarily absent so C is stable */ | 1123 | /* need to make it temporarily absent so C is stable */ |
1126 | hptep[0] |= HPTE_V_ABSENT; | 1124 | hptep[0] |= cpu_to_be64(HPTE_V_ABSENT); |
1127 | kvmppc_invalidate_hpte(kvm, hptep, i); | 1125 | kvmppc_invalidate_hpte(kvm, hptep, i); |
1128 | v = hptep[0]; | 1126 | v = be64_to_cpu(hptep[0]); |
1129 | r = hptep[1]; | 1127 | r = be64_to_cpu(hptep[1]); |
1130 | if (r & HPTE_R_C) { | 1128 | if (r & HPTE_R_C) { |
1131 | hptep[1] = r & ~HPTE_R_C; | 1129 | hptep[1] = cpu_to_be64(r & ~HPTE_R_C); |
1132 | if (!(rev[i].guest_rpte & HPTE_R_C)) { | 1130 | if (!(rev[i].guest_rpte & HPTE_R_C)) { |
1133 | rev[i].guest_rpte |= HPTE_R_C; | 1131 | rev[i].guest_rpte |= HPTE_R_C; |
1134 | note_hpte_modification(kvm, &rev[i]); | 1132 | note_hpte_modification(kvm, &rev[i]); |
@@ -1141,7 +1139,7 @@ static int kvm_test_clear_dirty_npages(struct kvm *kvm, unsigned long *rmapp) | |||
1141 | } | 1139 | } |
1142 | v &= ~(HPTE_V_ABSENT | HPTE_V_HVLOCK); | 1140 | v &= ~(HPTE_V_ABSENT | HPTE_V_HVLOCK); |
1143 | v |= HPTE_V_VALID; | 1141 | v |= HPTE_V_VALID; |
1144 | hptep[0] = v; | 1142 | hptep[0] = cpu_to_be64(v); |
1145 | } while ((i = j) != head); | 1143 | } while ((i = j) != head); |
1146 | 1144 | ||
1147 | unlock_rmap(rmapp); | 1145 | unlock_rmap(rmapp); |
@@ -1305,7 +1303,7 @@ struct kvm_htab_ctx { | |||
1305 | * Returns 1 if this HPT entry has been modified or has pending | 1303 | * Returns 1 if this HPT entry has been modified or has pending |
1306 | * R/C bit changes. | 1304 | * R/C bit changes. |
1307 | */ | 1305 | */ |
1308 | static int hpte_dirty(struct revmap_entry *revp, unsigned long *hptp) | 1306 | static int hpte_dirty(struct revmap_entry *revp, __be64 *hptp) |
1309 | { | 1307 | { |
1310 | unsigned long rcbits_unset; | 1308 | unsigned long rcbits_unset; |
1311 | 1309 | ||
@@ -1314,13 +1312,14 @@ static int hpte_dirty(struct revmap_entry *revp, unsigned long *hptp) | |||
1314 | 1312 | ||
1315 | /* Also need to consider changes in reference and changed bits */ | 1313 | /* Also need to consider changes in reference and changed bits */ |
1316 | rcbits_unset = ~revp->guest_rpte & (HPTE_R_R | HPTE_R_C); | 1314 | rcbits_unset = ~revp->guest_rpte & (HPTE_R_R | HPTE_R_C); |
1317 | if ((hptp[0] & HPTE_V_VALID) && (hptp[1] & rcbits_unset)) | 1315 | if ((be64_to_cpu(hptp[0]) & HPTE_V_VALID) && |
1316 | (be64_to_cpu(hptp[1]) & rcbits_unset)) | ||
1318 | return 1; | 1317 | return 1; |
1319 | 1318 | ||
1320 | return 0; | 1319 | return 0; |
1321 | } | 1320 | } |
1322 | 1321 | ||
1323 | static long record_hpte(unsigned long flags, unsigned long *hptp, | 1322 | static long record_hpte(unsigned long flags, __be64 *hptp, |
1324 | unsigned long *hpte, struct revmap_entry *revp, | 1323 | unsigned long *hpte, struct revmap_entry *revp, |
1325 | int want_valid, int first_pass) | 1324 | int want_valid, int first_pass) |
1326 | { | 1325 | { |
@@ -1335,10 +1334,10 @@ static long record_hpte(unsigned long flags, unsigned long *hptp, | |||
1335 | return 0; | 1334 | return 0; |
1336 | 1335 | ||
1337 | valid = 0; | 1336 | valid = 0; |
1338 | if (hptp[0] & (HPTE_V_VALID | HPTE_V_ABSENT)) { | 1337 | if (be64_to_cpu(hptp[0]) & (HPTE_V_VALID | HPTE_V_ABSENT)) { |
1339 | valid = 1; | 1338 | valid = 1; |
1340 | if ((flags & KVM_GET_HTAB_BOLTED_ONLY) && | 1339 | if ((flags & KVM_GET_HTAB_BOLTED_ONLY) && |
1341 | !(hptp[0] & HPTE_V_BOLTED)) | 1340 | !(be64_to_cpu(hptp[0]) & HPTE_V_BOLTED)) |
1342 | valid = 0; | 1341 | valid = 0; |
1343 | } | 1342 | } |
1344 | if (valid != want_valid) | 1343 | if (valid != want_valid) |
@@ -1350,7 +1349,7 @@ static long record_hpte(unsigned long flags, unsigned long *hptp, | |||
1350 | preempt_disable(); | 1349 | preempt_disable(); |
1351 | while (!try_lock_hpte(hptp, HPTE_V_HVLOCK)) | 1350 | while (!try_lock_hpte(hptp, HPTE_V_HVLOCK)) |
1352 | cpu_relax(); | 1351 | cpu_relax(); |
1353 | v = hptp[0]; | 1352 | v = be64_to_cpu(hptp[0]); |
1354 | 1353 | ||
1355 | /* re-evaluate valid and dirty from synchronized HPTE value */ | 1354 | /* re-evaluate valid and dirty from synchronized HPTE value */ |
1356 | valid = !!(v & HPTE_V_VALID); | 1355 | valid = !!(v & HPTE_V_VALID); |
@@ -1358,9 +1357,9 @@ static long record_hpte(unsigned long flags, unsigned long *hptp, | |||
1358 | 1357 | ||
1359 | /* Harvest R and C into guest view if necessary */ | 1358 | /* Harvest R and C into guest view if necessary */ |
1360 | rcbits_unset = ~revp->guest_rpte & (HPTE_R_R | HPTE_R_C); | 1359 | rcbits_unset = ~revp->guest_rpte & (HPTE_R_R | HPTE_R_C); |
1361 | if (valid && (rcbits_unset & hptp[1])) { | 1360 | if (valid && (rcbits_unset & be64_to_cpu(hptp[1]))) { |
1362 | revp->guest_rpte |= (hptp[1] & (HPTE_R_R | HPTE_R_C)) | | 1361 | revp->guest_rpte |= (be64_to_cpu(hptp[1]) & |
1363 | HPTE_GR_MODIFIED; | 1362 | (HPTE_R_R | HPTE_R_C)) | HPTE_GR_MODIFIED; |
1364 | dirty = 1; | 1363 | dirty = 1; |
1365 | } | 1364 | } |
1366 | 1365 | ||
@@ -1379,13 +1378,13 @@ static long record_hpte(unsigned long flags, unsigned long *hptp, | |||
1379 | revp->guest_rpte = r; | 1378 | revp->guest_rpte = r; |
1380 | } | 1379 | } |
1381 | asm volatile(PPC_RELEASE_BARRIER "" : : : "memory"); | 1380 | asm volatile(PPC_RELEASE_BARRIER "" : : : "memory"); |
1382 | hptp[0] &= ~HPTE_V_HVLOCK; | 1381 | hptp[0] &= ~cpu_to_be64(HPTE_V_HVLOCK); |
1383 | preempt_enable(); | 1382 | preempt_enable(); |
1384 | if (!(valid == want_valid && (first_pass || dirty))) | 1383 | if (!(valid == want_valid && (first_pass || dirty))) |
1385 | ok = 0; | 1384 | ok = 0; |
1386 | } | 1385 | } |
1387 | hpte[0] = v; | 1386 | hpte[0] = cpu_to_be64(v); |
1388 | hpte[1] = r; | 1387 | hpte[1] = cpu_to_be64(r); |
1389 | return ok; | 1388 | return ok; |
1390 | } | 1389 | } |
1391 | 1390 | ||
@@ -1395,7 +1394,7 @@ static ssize_t kvm_htab_read(struct file *file, char __user *buf, | |||
1395 | struct kvm_htab_ctx *ctx = file->private_data; | 1394 | struct kvm_htab_ctx *ctx = file->private_data; |
1396 | struct kvm *kvm = ctx->kvm; | 1395 | struct kvm *kvm = ctx->kvm; |
1397 | struct kvm_get_htab_header hdr; | 1396 | struct kvm_get_htab_header hdr; |
1398 | unsigned long *hptp; | 1397 | __be64 *hptp; |
1399 | struct revmap_entry *revp; | 1398 | struct revmap_entry *revp; |
1400 | unsigned long i, nb, nw; | 1399 | unsigned long i, nb, nw; |
1401 | unsigned long __user *lbuf; | 1400 | unsigned long __user *lbuf; |
@@ -1411,7 +1410,7 @@ static ssize_t kvm_htab_read(struct file *file, char __user *buf, | |||
1411 | flags = ctx->flags; | 1410 | flags = ctx->flags; |
1412 | 1411 | ||
1413 | i = ctx->index; | 1412 | i = ctx->index; |
1414 | hptp = (unsigned long *)(kvm->arch.hpt_virt + (i * HPTE_SIZE)); | 1413 | hptp = (__be64 *)(kvm->arch.hpt_virt + (i * HPTE_SIZE)); |
1415 | revp = kvm->arch.revmap + i; | 1414 | revp = kvm->arch.revmap + i; |
1416 | lbuf = (unsigned long __user *)buf; | 1415 | lbuf = (unsigned long __user *)buf; |
1417 | 1416 | ||
@@ -1495,7 +1494,7 @@ static ssize_t kvm_htab_write(struct file *file, const char __user *buf, | |||
1495 | unsigned long i, j; | 1494 | unsigned long i, j; |
1496 | unsigned long v, r; | 1495 | unsigned long v, r; |
1497 | unsigned long __user *lbuf; | 1496 | unsigned long __user *lbuf; |
1498 | unsigned long *hptp; | 1497 | __be64 *hptp; |
1499 | unsigned long tmp[2]; | 1498 | unsigned long tmp[2]; |
1500 | ssize_t nb; | 1499 | ssize_t nb; |
1501 | long int err, ret; | 1500 | long int err, ret; |
@@ -1537,7 +1536,7 @@ static ssize_t kvm_htab_write(struct file *file, const char __user *buf, | |||
1537 | i + hdr.n_valid + hdr.n_invalid > kvm->arch.hpt_npte) | 1536 | i + hdr.n_valid + hdr.n_invalid > kvm->arch.hpt_npte) |
1538 | break; | 1537 | break; |
1539 | 1538 | ||
1540 | hptp = (unsigned long *)(kvm->arch.hpt_virt + (i * HPTE_SIZE)); | 1539 | hptp = (__be64 *)(kvm->arch.hpt_virt + (i * HPTE_SIZE)); |
1541 | lbuf = (unsigned long __user *)buf; | 1540 | lbuf = (unsigned long __user *)buf; |
1542 | for (j = 0; j < hdr.n_valid; ++j) { | 1541 | for (j = 0; j < hdr.n_valid; ++j) { |
1543 | err = -EFAULT; | 1542 | err = -EFAULT; |
@@ -1549,7 +1548,7 @@ static ssize_t kvm_htab_write(struct file *file, const char __user *buf, | |||
1549 | lbuf += 2; | 1548 | lbuf += 2; |
1550 | nb += HPTE_SIZE; | 1549 | nb += HPTE_SIZE; |
1551 | 1550 | ||
1552 | if (hptp[0] & (HPTE_V_VALID | HPTE_V_ABSENT)) | 1551 | if (be64_to_cpu(hptp[0]) & (HPTE_V_VALID | HPTE_V_ABSENT)) |
1553 | kvmppc_do_h_remove(kvm, 0, i, 0, tmp); | 1552 | kvmppc_do_h_remove(kvm, 0, i, 0, tmp); |
1554 | err = -EIO; | 1553 | err = -EIO; |
1555 | ret = kvmppc_virtmode_do_h_enter(kvm, H_EXACT, i, v, r, | 1554 | ret = kvmppc_virtmode_do_h_enter(kvm, H_EXACT, i, v, r, |
@@ -1575,7 +1574,7 @@ static ssize_t kvm_htab_write(struct file *file, const char __user *buf, | |||
1575 | } | 1574 | } |
1576 | 1575 | ||
1577 | for (j = 0; j < hdr.n_invalid; ++j) { | 1576 | for (j = 0; j < hdr.n_invalid; ++j) { |
1578 | if (hptp[0] & (HPTE_V_VALID | HPTE_V_ABSENT)) | 1577 | if (be64_to_cpu(hptp[0]) & (HPTE_V_VALID | HPTE_V_ABSENT)) |
1579 | kvmppc_do_h_remove(kvm, 0, i, 0, tmp); | 1578 | kvmppc_do_h_remove(kvm, 0, i, 0, tmp); |
1580 | ++i; | 1579 | ++i; |
1581 | hptp += 2; | 1580 | hptp += 2; |
diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c index 3f295269af37..5a2bc4b0dfe5 100644 --- a/arch/powerpc/kvm/book3s_emulate.c +++ b/arch/powerpc/kvm/book3s_emulate.c | |||
@@ -439,12 +439,6 @@ int kvmppc_core_emulate_mtspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) | |||
439 | (mfmsr() & MSR_HV)) | 439 | (mfmsr() & MSR_HV)) |
440 | vcpu->arch.hflags |= BOOK3S_HFLAG_DCBZ32; | 440 | vcpu->arch.hflags |= BOOK3S_HFLAG_DCBZ32; |
441 | break; | 441 | break; |
442 | case SPRN_PURR: | ||
443 | to_book3s(vcpu)->purr_offset = spr_val - get_tb(); | ||
444 | break; | ||
445 | case SPRN_SPURR: | ||
446 | to_book3s(vcpu)->spurr_offset = spr_val - get_tb(); | ||
447 | break; | ||
448 | case SPRN_GQR0: | 442 | case SPRN_GQR0: |
449 | case SPRN_GQR1: | 443 | case SPRN_GQR1: |
450 | case SPRN_GQR2: | 444 | case SPRN_GQR2: |
@@ -455,10 +449,10 @@ int kvmppc_core_emulate_mtspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) | |||
455 | case SPRN_GQR7: | 449 | case SPRN_GQR7: |
456 | to_book3s(vcpu)->gqr[sprn - SPRN_GQR0] = spr_val; | 450 | to_book3s(vcpu)->gqr[sprn - SPRN_GQR0] = spr_val; |
457 | break; | 451 | break; |
452 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
458 | case SPRN_FSCR: | 453 | case SPRN_FSCR: |
459 | vcpu->arch.fscr = spr_val; | 454 | kvmppc_set_fscr(vcpu, spr_val); |
460 | break; | 455 | break; |
461 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
462 | case SPRN_BESCR: | 456 | case SPRN_BESCR: |
463 | vcpu->arch.bescr = spr_val; | 457 | vcpu->arch.bescr = spr_val; |
464 | break; | 458 | break; |
@@ -572,10 +566,22 @@ int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val | |||
572 | *spr_val = 0; | 566 | *spr_val = 0; |
573 | break; | 567 | break; |
574 | case SPRN_PURR: | 568 | case SPRN_PURR: |
575 | *spr_val = get_tb() + to_book3s(vcpu)->purr_offset; | 569 | /* |
570 | * On exit we would have updated purr | ||
571 | */ | ||
572 | *spr_val = vcpu->arch.purr; | ||
576 | break; | 573 | break; |
577 | case SPRN_SPURR: | 574 | case SPRN_SPURR: |
578 | *spr_val = get_tb() + to_book3s(vcpu)->purr_offset; | 575 | /* |
576 | * On exit we would have updated spurr | ||
577 | */ | ||
578 | *spr_val = vcpu->arch.spurr; | ||
579 | break; | ||
580 | case SPRN_VTB: | ||
581 | *spr_val = vcpu->arch.vtb; | ||
582 | break; | ||
583 | case SPRN_IC: | ||
584 | *spr_val = vcpu->arch.ic; | ||
579 | break; | 585 | break; |
580 | case SPRN_GQR0: | 586 | case SPRN_GQR0: |
581 | case SPRN_GQR1: | 587 | case SPRN_GQR1: |
@@ -587,10 +593,10 @@ int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val | |||
587 | case SPRN_GQR7: | 593 | case SPRN_GQR7: |
588 | *spr_val = to_book3s(vcpu)->gqr[sprn - SPRN_GQR0]; | 594 | *spr_val = to_book3s(vcpu)->gqr[sprn - SPRN_GQR0]; |
589 | break; | 595 | break; |
596 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
590 | case SPRN_FSCR: | 597 | case SPRN_FSCR: |
591 | *spr_val = vcpu->arch.fscr; | 598 | *spr_val = vcpu->arch.fscr; |
592 | break; | 599 | break; |
593 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
594 | case SPRN_BESCR: | 600 | case SPRN_BESCR: |
595 | *spr_val = vcpu->arch.bescr; | 601 | *spr_val = vcpu->arch.bescr; |
596 | break; | 602 | break; |
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 7a12edbb61e7..27cced9c7249 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c | |||
@@ -35,6 +35,7 @@ | |||
35 | 35 | ||
36 | #include <asm/reg.h> | 36 | #include <asm/reg.h> |
37 | #include <asm/cputable.h> | 37 | #include <asm/cputable.h> |
38 | #include <asm/cache.h> | ||
38 | #include <asm/cacheflush.h> | 39 | #include <asm/cacheflush.h> |
39 | #include <asm/tlbflush.h> | 40 | #include <asm/tlbflush.h> |
40 | #include <asm/uaccess.h> | 41 | #include <asm/uaccess.h> |
@@ -67,6 +68,15 @@ | |||
67 | /* Used as a "null" value for timebase values */ | 68 | /* Used as a "null" value for timebase values */ |
68 | #define TB_NIL (~(u64)0) | 69 | #define TB_NIL (~(u64)0) |
69 | 70 | ||
71 | static DECLARE_BITMAP(default_enabled_hcalls, MAX_HCALL_OPCODE/4 + 1); | ||
72 | |||
73 | #if defined(CONFIG_PPC_64K_PAGES) | ||
74 | #define MPP_BUFFER_ORDER 0 | ||
75 | #elif defined(CONFIG_PPC_4K_PAGES) | ||
76 | #define MPP_BUFFER_ORDER 3 | ||
77 | #endif | ||
78 | |||
79 | |||
70 | static void kvmppc_end_cede(struct kvm_vcpu *vcpu); | 80 | static void kvmppc_end_cede(struct kvm_vcpu *vcpu); |
71 | static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu); | 81 | static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu); |
72 | 82 | ||
@@ -270,7 +280,7 @@ struct kvm_vcpu *kvmppc_find_vcpu(struct kvm *kvm, int id) | |||
270 | static void init_vpa(struct kvm_vcpu *vcpu, struct lppaca *vpa) | 280 | static void init_vpa(struct kvm_vcpu *vcpu, struct lppaca *vpa) |
271 | { | 281 | { |
272 | vpa->__old_status |= LPPACA_OLD_SHARED_PROC; | 282 | vpa->__old_status |= LPPACA_OLD_SHARED_PROC; |
273 | vpa->yield_count = 1; | 283 | vpa->yield_count = cpu_to_be32(1); |
274 | } | 284 | } |
275 | 285 | ||
276 | static int set_vpa(struct kvm_vcpu *vcpu, struct kvmppc_vpa *v, | 286 | static int set_vpa(struct kvm_vcpu *vcpu, struct kvmppc_vpa *v, |
@@ -293,8 +303,8 @@ static int set_vpa(struct kvm_vcpu *vcpu, struct kvmppc_vpa *v, | |||
293 | struct reg_vpa { | 303 | struct reg_vpa { |
294 | u32 dummy; | 304 | u32 dummy; |
295 | union { | 305 | union { |
296 | u16 hword; | 306 | __be16 hword; |
297 | u32 word; | 307 | __be32 word; |
298 | } length; | 308 | } length; |
299 | }; | 309 | }; |
300 | 310 | ||
@@ -333,9 +343,9 @@ static unsigned long do_h_register_vpa(struct kvm_vcpu *vcpu, | |||
333 | if (va == NULL) | 343 | if (va == NULL) |
334 | return H_PARAMETER; | 344 | return H_PARAMETER; |
335 | if (subfunc == H_VPA_REG_VPA) | 345 | if (subfunc == H_VPA_REG_VPA) |
336 | len = ((struct reg_vpa *)va)->length.hword; | 346 | len = be16_to_cpu(((struct reg_vpa *)va)->length.hword); |
337 | else | 347 | else |
338 | len = ((struct reg_vpa *)va)->length.word; | 348 | len = be32_to_cpu(((struct reg_vpa *)va)->length.word); |
339 | kvmppc_unpin_guest_page(kvm, va, vpa, false); | 349 | kvmppc_unpin_guest_page(kvm, va, vpa, false); |
340 | 350 | ||
341 | /* Check length */ | 351 | /* Check length */ |
@@ -540,21 +550,63 @@ static void kvmppc_create_dtl_entry(struct kvm_vcpu *vcpu, | |||
540 | return; | 550 | return; |
541 | memset(dt, 0, sizeof(struct dtl_entry)); | 551 | memset(dt, 0, sizeof(struct dtl_entry)); |
542 | dt->dispatch_reason = 7; | 552 | dt->dispatch_reason = 7; |
543 | dt->processor_id = vc->pcpu + vcpu->arch.ptid; | 553 | dt->processor_id = cpu_to_be16(vc->pcpu + vcpu->arch.ptid); |
544 | dt->timebase = now + vc->tb_offset; | 554 | dt->timebase = cpu_to_be64(now + vc->tb_offset); |
545 | dt->enqueue_to_dispatch_time = stolen; | 555 | dt->enqueue_to_dispatch_time = cpu_to_be32(stolen); |
546 | dt->srr0 = kvmppc_get_pc(vcpu); | 556 | dt->srr0 = cpu_to_be64(kvmppc_get_pc(vcpu)); |
547 | dt->srr1 = vcpu->arch.shregs.msr; | 557 | dt->srr1 = cpu_to_be64(vcpu->arch.shregs.msr); |
548 | ++dt; | 558 | ++dt; |
549 | if (dt == vcpu->arch.dtl.pinned_end) | 559 | if (dt == vcpu->arch.dtl.pinned_end) |
550 | dt = vcpu->arch.dtl.pinned_addr; | 560 | dt = vcpu->arch.dtl.pinned_addr; |
551 | vcpu->arch.dtl_ptr = dt; | 561 | vcpu->arch.dtl_ptr = dt; |
552 | /* order writing *dt vs. writing vpa->dtl_idx */ | 562 | /* order writing *dt vs. writing vpa->dtl_idx */ |
553 | smp_wmb(); | 563 | smp_wmb(); |
554 | vpa->dtl_idx = ++vcpu->arch.dtl_index; | 564 | vpa->dtl_idx = cpu_to_be64(++vcpu->arch.dtl_index); |
555 | vcpu->arch.dtl.dirty = true; | 565 | vcpu->arch.dtl.dirty = true; |
556 | } | 566 | } |
557 | 567 | ||
568 | static bool kvmppc_power8_compatible(struct kvm_vcpu *vcpu) | ||
569 | { | ||
570 | if (vcpu->arch.vcore->arch_compat >= PVR_ARCH_207) | ||
571 | return true; | ||
572 | if ((!vcpu->arch.vcore->arch_compat) && | ||
573 | cpu_has_feature(CPU_FTR_ARCH_207S)) | ||
574 | return true; | ||
575 | return false; | ||
576 | } | ||
577 | |||
578 | static int kvmppc_h_set_mode(struct kvm_vcpu *vcpu, unsigned long mflags, | ||
579 | unsigned long resource, unsigned long value1, | ||
580 | unsigned long value2) | ||
581 | { | ||
582 | switch (resource) { | ||
583 | case H_SET_MODE_RESOURCE_SET_CIABR: | ||
584 | if (!kvmppc_power8_compatible(vcpu)) | ||
585 | return H_P2; | ||
586 | if (value2) | ||
587 | return H_P4; | ||
588 | if (mflags) | ||
589 | return H_UNSUPPORTED_FLAG_START; | ||
590 | /* Guests can't breakpoint the hypervisor */ | ||
591 | if ((value1 & CIABR_PRIV) == CIABR_PRIV_HYPER) | ||
592 | return H_P3; | ||
593 | vcpu->arch.ciabr = value1; | ||
594 | return H_SUCCESS; | ||
595 | case H_SET_MODE_RESOURCE_SET_DAWR: | ||
596 | if (!kvmppc_power8_compatible(vcpu)) | ||
597 | return H_P2; | ||
598 | if (mflags) | ||
599 | return H_UNSUPPORTED_FLAG_START; | ||
600 | if (value2 & DABRX_HYP) | ||
601 | return H_P4; | ||
602 | vcpu->arch.dawr = value1; | ||
603 | vcpu->arch.dawrx = value2; | ||
604 | return H_SUCCESS; | ||
605 | default: | ||
606 | return H_TOO_HARD; | ||
607 | } | ||
608 | } | ||
609 | |||
558 | int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu) | 610 | int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu) |
559 | { | 611 | { |
560 | unsigned long req = kvmppc_get_gpr(vcpu, 3); | 612 | unsigned long req = kvmppc_get_gpr(vcpu, 3); |
@@ -562,6 +614,10 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu) | |||
562 | struct kvm_vcpu *tvcpu; | 614 | struct kvm_vcpu *tvcpu; |
563 | int idx, rc; | 615 | int idx, rc; |
564 | 616 | ||
617 | if (req <= MAX_HCALL_OPCODE && | ||
618 | !test_bit(req/4, vcpu->kvm->arch.enabled_hcalls)) | ||
619 | return RESUME_HOST; | ||
620 | |||
565 | switch (req) { | 621 | switch (req) { |
566 | case H_ENTER: | 622 | case H_ENTER: |
567 | idx = srcu_read_lock(&vcpu->kvm->srcu); | 623 | idx = srcu_read_lock(&vcpu->kvm->srcu); |
@@ -620,7 +676,14 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu) | |||
620 | 676 | ||
621 | /* Send the error out to userspace via KVM_RUN */ | 677 | /* Send the error out to userspace via KVM_RUN */ |
622 | return rc; | 678 | return rc; |
623 | 679 | case H_SET_MODE: | |
680 | ret = kvmppc_h_set_mode(vcpu, kvmppc_get_gpr(vcpu, 4), | ||
681 | kvmppc_get_gpr(vcpu, 5), | ||
682 | kvmppc_get_gpr(vcpu, 6), | ||
683 | kvmppc_get_gpr(vcpu, 7)); | ||
684 | if (ret == H_TOO_HARD) | ||
685 | return RESUME_HOST; | ||
686 | break; | ||
624 | case H_XIRR: | 687 | case H_XIRR: |
625 | case H_CPPR: | 688 | case H_CPPR: |
626 | case H_EOI: | 689 | case H_EOI: |
@@ -639,6 +702,29 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu) | |||
639 | return RESUME_GUEST; | 702 | return RESUME_GUEST; |
640 | } | 703 | } |
641 | 704 | ||
705 | static int kvmppc_hcall_impl_hv(unsigned long cmd) | ||
706 | { | ||
707 | switch (cmd) { | ||
708 | case H_CEDE: | ||
709 | case H_PROD: | ||
710 | case H_CONFER: | ||
711 | case H_REGISTER_VPA: | ||
712 | case H_SET_MODE: | ||
713 | #ifdef CONFIG_KVM_XICS | ||
714 | case H_XIRR: | ||
715 | case H_CPPR: | ||
716 | case H_EOI: | ||
717 | case H_IPI: | ||
718 | case H_IPOLL: | ||
719 | case H_XIRR_X: | ||
720 | #endif | ||
721 | return 1; | ||
722 | } | ||
723 | |||
724 | /* See if it's in the real-mode table */ | ||
725 | return kvmppc_hcall_impl_hv_realmode(cmd); | ||
726 | } | ||
727 | |||
642 | static int kvmppc_handle_exit_hv(struct kvm_run *run, struct kvm_vcpu *vcpu, | 728 | static int kvmppc_handle_exit_hv(struct kvm_run *run, struct kvm_vcpu *vcpu, |
643 | struct task_struct *tsk) | 729 | struct task_struct *tsk) |
644 | { | 730 | { |
@@ -785,7 +871,8 @@ static int kvm_arch_vcpu_ioctl_set_sregs_hv(struct kvm_vcpu *vcpu, | |||
785 | return 0; | 871 | return 0; |
786 | } | 872 | } |
787 | 873 | ||
788 | static void kvmppc_set_lpcr(struct kvm_vcpu *vcpu, u64 new_lpcr) | 874 | static void kvmppc_set_lpcr(struct kvm_vcpu *vcpu, u64 new_lpcr, |
875 | bool preserve_top32) | ||
789 | { | 876 | { |
790 | struct kvmppc_vcore *vc = vcpu->arch.vcore; | 877 | struct kvmppc_vcore *vc = vcpu->arch.vcore; |
791 | u64 mask; | 878 | u64 mask; |
@@ -820,6 +907,10 @@ static void kvmppc_set_lpcr(struct kvm_vcpu *vcpu, u64 new_lpcr) | |||
820 | mask = LPCR_DPFD | LPCR_ILE | LPCR_TC; | 907 | mask = LPCR_DPFD | LPCR_ILE | LPCR_TC; |
821 | if (cpu_has_feature(CPU_FTR_ARCH_207S)) | 908 | if (cpu_has_feature(CPU_FTR_ARCH_207S)) |
822 | mask |= LPCR_AIL; | 909 | mask |= LPCR_AIL; |
910 | |||
911 | /* Broken 32-bit version of LPCR must not clear top bits */ | ||
912 | if (preserve_top32) | ||
913 | mask &= 0xFFFFFFFF; | ||
823 | vc->lpcr = (vc->lpcr & ~mask) | (new_lpcr & mask); | 914 | vc->lpcr = (vc->lpcr & ~mask) | (new_lpcr & mask); |
824 | spin_unlock(&vc->lock); | 915 | spin_unlock(&vc->lock); |
825 | } | 916 | } |
@@ -894,12 +985,6 @@ static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id, | |||
894 | case KVM_REG_PPC_CIABR: | 985 | case KVM_REG_PPC_CIABR: |
895 | *val = get_reg_val(id, vcpu->arch.ciabr); | 986 | *val = get_reg_val(id, vcpu->arch.ciabr); |
896 | break; | 987 | break; |
897 | case KVM_REG_PPC_IC: | ||
898 | *val = get_reg_val(id, vcpu->arch.ic); | ||
899 | break; | ||
900 | case KVM_REG_PPC_VTB: | ||
901 | *val = get_reg_val(id, vcpu->arch.vtb); | ||
902 | break; | ||
903 | case KVM_REG_PPC_CSIGR: | 988 | case KVM_REG_PPC_CSIGR: |
904 | *val = get_reg_val(id, vcpu->arch.csigr); | 989 | *val = get_reg_val(id, vcpu->arch.csigr); |
905 | break; | 990 | break; |
@@ -939,6 +1024,7 @@ static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id, | |||
939 | *val = get_reg_val(id, vcpu->arch.vcore->tb_offset); | 1024 | *val = get_reg_val(id, vcpu->arch.vcore->tb_offset); |
940 | break; | 1025 | break; |
941 | case KVM_REG_PPC_LPCR: | 1026 | case KVM_REG_PPC_LPCR: |
1027 | case KVM_REG_PPC_LPCR_64: | ||
942 | *val = get_reg_val(id, vcpu->arch.vcore->lpcr); | 1028 | *val = get_reg_val(id, vcpu->arch.vcore->lpcr); |
943 | break; | 1029 | break; |
944 | case KVM_REG_PPC_PPR: | 1030 | case KVM_REG_PPC_PPR: |
@@ -1094,12 +1180,6 @@ static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcpu, u64 id, | |||
1094 | if ((vcpu->arch.ciabr & CIABR_PRIV) == CIABR_PRIV_HYPER) | 1180 | if ((vcpu->arch.ciabr & CIABR_PRIV) == CIABR_PRIV_HYPER) |
1095 | vcpu->arch.ciabr &= ~CIABR_PRIV; /* disable */ | 1181 | vcpu->arch.ciabr &= ~CIABR_PRIV; /* disable */ |
1096 | break; | 1182 | break; |
1097 | case KVM_REG_PPC_IC: | ||
1098 | vcpu->arch.ic = set_reg_val(id, *val); | ||
1099 | break; | ||
1100 | case KVM_REG_PPC_VTB: | ||
1101 | vcpu->arch.vtb = set_reg_val(id, *val); | ||
1102 | break; | ||
1103 | case KVM_REG_PPC_CSIGR: | 1183 | case KVM_REG_PPC_CSIGR: |
1104 | vcpu->arch.csigr = set_reg_val(id, *val); | 1184 | vcpu->arch.csigr = set_reg_val(id, *val); |
1105 | break; | 1185 | break; |
@@ -1150,7 +1230,10 @@ static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcpu, u64 id, | |||
1150 | ALIGN(set_reg_val(id, *val), 1UL << 24); | 1230 | ALIGN(set_reg_val(id, *val), 1UL << 24); |
1151 | break; | 1231 | break; |
1152 | case KVM_REG_PPC_LPCR: | 1232 | case KVM_REG_PPC_LPCR: |
1153 | kvmppc_set_lpcr(vcpu, set_reg_val(id, *val)); | 1233 | kvmppc_set_lpcr(vcpu, set_reg_val(id, *val), true); |
1234 | break; | ||
1235 | case KVM_REG_PPC_LPCR_64: | ||
1236 | kvmppc_set_lpcr(vcpu, set_reg_val(id, *val), false); | ||
1154 | break; | 1237 | break; |
1155 | case KVM_REG_PPC_PPR: | 1238 | case KVM_REG_PPC_PPR: |
1156 | vcpu->arch.ppr = set_reg_val(id, *val); | 1239 | vcpu->arch.ppr = set_reg_val(id, *val); |
@@ -1228,6 +1311,33 @@ static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcpu, u64 id, | |||
1228 | return r; | 1311 | return r; |
1229 | } | 1312 | } |
1230 | 1313 | ||
1314 | static struct kvmppc_vcore *kvmppc_vcore_create(struct kvm *kvm, int core) | ||
1315 | { | ||
1316 | struct kvmppc_vcore *vcore; | ||
1317 | |||
1318 | vcore = kzalloc(sizeof(struct kvmppc_vcore), GFP_KERNEL); | ||
1319 | |||
1320 | if (vcore == NULL) | ||
1321 | return NULL; | ||
1322 | |||
1323 | INIT_LIST_HEAD(&vcore->runnable_threads); | ||
1324 | spin_lock_init(&vcore->lock); | ||
1325 | init_waitqueue_head(&vcore->wq); | ||
1326 | vcore->preempt_tb = TB_NIL; | ||
1327 | vcore->lpcr = kvm->arch.lpcr; | ||
1328 | vcore->first_vcpuid = core * threads_per_subcore; | ||
1329 | vcore->kvm = kvm; | ||
1330 | |||
1331 | vcore->mpp_buffer_is_valid = false; | ||
1332 | |||
1333 | if (cpu_has_feature(CPU_FTR_ARCH_207S)) | ||
1334 | vcore->mpp_buffer = (void *)__get_free_pages( | ||
1335 | GFP_KERNEL|__GFP_ZERO, | ||
1336 | MPP_BUFFER_ORDER); | ||
1337 | |||
1338 | return vcore; | ||
1339 | } | ||
1340 | |||
1231 | static struct kvm_vcpu *kvmppc_core_vcpu_create_hv(struct kvm *kvm, | 1341 | static struct kvm_vcpu *kvmppc_core_vcpu_create_hv(struct kvm *kvm, |
1232 | unsigned int id) | 1342 | unsigned int id) |
1233 | { | 1343 | { |
@@ -1279,16 +1389,7 @@ static struct kvm_vcpu *kvmppc_core_vcpu_create_hv(struct kvm *kvm, | |||
1279 | mutex_lock(&kvm->lock); | 1389 | mutex_lock(&kvm->lock); |
1280 | vcore = kvm->arch.vcores[core]; | 1390 | vcore = kvm->arch.vcores[core]; |
1281 | if (!vcore) { | 1391 | if (!vcore) { |
1282 | vcore = kzalloc(sizeof(struct kvmppc_vcore), GFP_KERNEL); | 1392 | vcore = kvmppc_vcore_create(kvm, core); |
1283 | if (vcore) { | ||
1284 | INIT_LIST_HEAD(&vcore->runnable_threads); | ||
1285 | spin_lock_init(&vcore->lock); | ||
1286 | init_waitqueue_head(&vcore->wq); | ||
1287 | vcore->preempt_tb = TB_NIL; | ||
1288 | vcore->lpcr = kvm->arch.lpcr; | ||
1289 | vcore->first_vcpuid = core * threads_per_subcore; | ||
1290 | vcore->kvm = kvm; | ||
1291 | } | ||
1292 | kvm->arch.vcores[core] = vcore; | 1393 | kvm->arch.vcores[core] = vcore; |
1293 | kvm->arch.online_vcores++; | 1394 | kvm->arch.online_vcores++; |
1294 | } | 1395 | } |
@@ -1500,6 +1601,33 @@ static int on_primary_thread(void) | |||
1500 | return 1; | 1601 | return 1; |
1501 | } | 1602 | } |
1502 | 1603 | ||
1604 | static void kvmppc_start_saving_l2_cache(struct kvmppc_vcore *vc) | ||
1605 | { | ||
1606 | phys_addr_t phy_addr, mpp_addr; | ||
1607 | |||
1608 | phy_addr = (phys_addr_t)virt_to_phys(vc->mpp_buffer); | ||
1609 | mpp_addr = phy_addr & PPC_MPPE_ADDRESS_MASK; | ||
1610 | |||
1611 | mtspr(SPRN_MPPR, mpp_addr | PPC_MPPR_FETCH_ABORT); | ||
1612 | logmpp(mpp_addr | PPC_LOGMPP_LOG_L2); | ||
1613 | |||
1614 | vc->mpp_buffer_is_valid = true; | ||
1615 | } | ||
1616 | |||
1617 | static void kvmppc_start_restoring_l2_cache(const struct kvmppc_vcore *vc) | ||
1618 | { | ||
1619 | phys_addr_t phy_addr, mpp_addr; | ||
1620 | |||
1621 | phy_addr = virt_to_phys(vc->mpp_buffer); | ||
1622 | mpp_addr = phy_addr & PPC_MPPE_ADDRESS_MASK; | ||
1623 | |||
1624 | /* We must abort any in-progress save operations to ensure | ||
1625 | * the table is valid so that prefetch engine knows when to | ||
1626 | * stop prefetching. */ | ||
1627 | logmpp(mpp_addr | PPC_LOGMPP_LOG_ABORT); | ||
1628 | mtspr(SPRN_MPPR, mpp_addr | PPC_MPPR_FETCH_WHOLE_TABLE); | ||
1629 | } | ||
1630 | |||
1503 | /* | 1631 | /* |
1504 | * Run a set of guest threads on a physical core. | 1632 | * Run a set of guest threads on a physical core. |
1505 | * Called with vc->lock held. | 1633 | * Called with vc->lock held. |
@@ -1577,9 +1705,16 @@ static void kvmppc_run_core(struct kvmppc_vcore *vc) | |||
1577 | 1705 | ||
1578 | srcu_idx = srcu_read_lock(&vc->kvm->srcu); | 1706 | srcu_idx = srcu_read_lock(&vc->kvm->srcu); |
1579 | 1707 | ||
1708 | if (vc->mpp_buffer_is_valid) | ||
1709 | kvmppc_start_restoring_l2_cache(vc); | ||
1710 | |||
1580 | __kvmppc_vcore_entry(); | 1711 | __kvmppc_vcore_entry(); |
1581 | 1712 | ||
1582 | spin_lock(&vc->lock); | 1713 | spin_lock(&vc->lock); |
1714 | |||
1715 | if (vc->mpp_buffer) | ||
1716 | kvmppc_start_saving_l2_cache(vc); | ||
1717 | |||
1583 | /* disable sending of IPIs on virtual external irqs */ | 1718 | /* disable sending of IPIs on virtual external irqs */ |
1584 | list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) | 1719 | list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) |
1585 | vcpu->cpu = -1; | 1720 | vcpu->cpu = -1; |
@@ -1929,12 +2064,6 @@ static void kvmppc_add_seg_page_size(struct kvm_ppc_one_seg_page_size **sps, | |||
1929 | (*sps)->page_shift = def->shift; | 2064 | (*sps)->page_shift = def->shift; |
1930 | (*sps)->slb_enc = def->sllp; | 2065 | (*sps)->slb_enc = def->sllp; |
1931 | (*sps)->enc[0].page_shift = def->shift; | 2066 | (*sps)->enc[0].page_shift = def->shift; |
1932 | /* | ||
1933 | * Only return base page encoding. We don't want to return | ||
1934 | * all the supporting pte_enc, because our H_ENTER doesn't | ||
1935 | * support MPSS yet. Once they do, we can start passing all | ||
1936 | * support pte_enc here | ||
1937 | */ | ||
1938 | (*sps)->enc[0].pte_enc = def->penc[linux_psize]; | 2067 | (*sps)->enc[0].pte_enc = def->penc[linux_psize]; |
1939 | /* | 2068 | /* |
1940 | * Add 16MB MPSS support if host supports it | 2069 | * Add 16MB MPSS support if host supports it |
@@ -2281,6 +2410,10 @@ static int kvmppc_core_init_vm_hv(struct kvm *kvm) | |||
2281 | */ | 2410 | */ |
2282 | cpumask_setall(&kvm->arch.need_tlb_flush); | 2411 | cpumask_setall(&kvm->arch.need_tlb_flush); |
2283 | 2412 | ||
2413 | /* Start out with the default set of hcalls enabled */ | ||
2414 | memcpy(kvm->arch.enabled_hcalls, default_enabled_hcalls, | ||
2415 | sizeof(kvm->arch.enabled_hcalls)); | ||
2416 | |||
2284 | kvm->arch.rma = NULL; | 2417 | kvm->arch.rma = NULL; |
2285 | 2418 | ||
2286 | kvm->arch.host_sdr1 = mfspr(SPRN_SDR1); | 2419 | kvm->arch.host_sdr1 = mfspr(SPRN_SDR1); |
@@ -2323,8 +2456,14 @@ static void kvmppc_free_vcores(struct kvm *kvm) | |||
2323 | { | 2456 | { |
2324 | long int i; | 2457 | long int i; |
2325 | 2458 | ||
2326 | for (i = 0; i < KVM_MAX_VCORES; ++i) | 2459 | for (i = 0; i < KVM_MAX_VCORES; ++i) { |
2460 | if (kvm->arch.vcores[i] && kvm->arch.vcores[i]->mpp_buffer) { | ||
2461 | struct kvmppc_vcore *vc = kvm->arch.vcores[i]; | ||
2462 | free_pages((unsigned long)vc->mpp_buffer, | ||
2463 | MPP_BUFFER_ORDER); | ||
2464 | } | ||
2327 | kfree(kvm->arch.vcores[i]); | 2465 | kfree(kvm->arch.vcores[i]); |
2466 | } | ||
2328 | kvm->arch.online_vcores = 0; | 2467 | kvm->arch.online_vcores = 0; |
2329 | } | 2468 | } |
2330 | 2469 | ||
@@ -2419,6 +2558,49 @@ static long kvm_arch_vm_ioctl_hv(struct file *filp, | |||
2419 | return r; | 2558 | return r; |
2420 | } | 2559 | } |
2421 | 2560 | ||
2561 | /* | ||
2562 | * List of hcall numbers to enable by default. | ||
2563 | * For compatibility with old userspace, we enable by default | ||
2564 | * all hcalls that were implemented before the hcall-enabling | ||
2565 | * facility was added. Note this list should not include H_RTAS. | ||
2566 | */ | ||
2567 | static unsigned int default_hcall_list[] = { | ||
2568 | H_REMOVE, | ||
2569 | H_ENTER, | ||
2570 | H_READ, | ||
2571 | H_PROTECT, | ||
2572 | H_BULK_REMOVE, | ||
2573 | H_GET_TCE, | ||
2574 | H_PUT_TCE, | ||
2575 | H_SET_DABR, | ||
2576 | H_SET_XDABR, | ||
2577 | H_CEDE, | ||
2578 | H_PROD, | ||
2579 | H_CONFER, | ||
2580 | H_REGISTER_VPA, | ||
2581 | #ifdef CONFIG_KVM_XICS | ||
2582 | H_EOI, | ||
2583 | H_CPPR, | ||
2584 | H_IPI, | ||
2585 | H_IPOLL, | ||
2586 | H_XIRR, | ||
2587 | H_XIRR_X, | ||
2588 | #endif | ||
2589 | 0 | ||
2590 | }; | ||
2591 | |||
2592 | static void init_default_hcalls(void) | ||
2593 | { | ||
2594 | int i; | ||
2595 | unsigned int hcall; | ||
2596 | |||
2597 | for (i = 0; default_hcall_list[i]; ++i) { | ||
2598 | hcall = default_hcall_list[i]; | ||
2599 | WARN_ON(!kvmppc_hcall_impl_hv(hcall)); | ||
2600 | __set_bit(hcall / 4, default_enabled_hcalls); | ||
2601 | } | ||
2602 | } | ||
2603 | |||
2422 | static struct kvmppc_ops kvm_ops_hv = { | 2604 | static struct kvmppc_ops kvm_ops_hv = { |
2423 | .get_sregs = kvm_arch_vcpu_ioctl_get_sregs_hv, | 2605 | .get_sregs = kvm_arch_vcpu_ioctl_get_sregs_hv, |
2424 | .set_sregs = kvm_arch_vcpu_ioctl_set_sregs_hv, | 2606 | .set_sregs = kvm_arch_vcpu_ioctl_set_sregs_hv, |
@@ -2451,6 +2633,7 @@ static struct kvmppc_ops kvm_ops_hv = { | |||
2451 | .emulate_mfspr = kvmppc_core_emulate_mfspr_hv, | 2633 | .emulate_mfspr = kvmppc_core_emulate_mfspr_hv, |
2452 | .fast_vcpu_kick = kvmppc_fast_vcpu_kick_hv, | 2634 | .fast_vcpu_kick = kvmppc_fast_vcpu_kick_hv, |
2453 | .arch_vm_ioctl = kvm_arch_vm_ioctl_hv, | 2635 | .arch_vm_ioctl = kvm_arch_vm_ioctl_hv, |
2636 | .hcall_implemented = kvmppc_hcall_impl_hv, | ||
2454 | }; | 2637 | }; |
2455 | 2638 | ||
2456 | static int kvmppc_book3s_init_hv(void) | 2639 | static int kvmppc_book3s_init_hv(void) |
@@ -2466,6 +2649,8 @@ static int kvmppc_book3s_init_hv(void) | |||
2466 | kvm_ops_hv.owner = THIS_MODULE; | 2649 | kvm_ops_hv.owner = THIS_MODULE; |
2467 | kvmppc_hv_ops = &kvm_ops_hv; | 2650 | kvmppc_hv_ops = &kvm_ops_hv; |
2468 | 2651 | ||
2652 | init_default_hcalls(); | ||
2653 | |||
2469 | r = kvmppc_mmu_hv_init(); | 2654 | r = kvmppc_mmu_hv_init(); |
2470 | return r; | 2655 | return r; |
2471 | } | 2656 | } |
diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c index 6cf498a9bc98..329d7fdd0a6a 100644 --- a/arch/powerpc/kvm/book3s_hv_builtin.c +++ b/arch/powerpc/kvm/book3s_hv_builtin.c | |||
@@ -219,3 +219,16 @@ bool kvm_hv_mode_active(void) | |||
219 | { | 219 | { |
220 | return atomic_read(&hv_vm_count) != 0; | 220 | return atomic_read(&hv_vm_count) != 0; |
221 | } | 221 | } |
222 | |||
223 | extern int hcall_real_table[], hcall_real_table_end[]; | ||
224 | |||
225 | int kvmppc_hcall_impl_hv_realmode(unsigned long cmd) | ||
226 | { | ||
227 | cmd /= 4; | ||
228 | if (cmd < hcall_real_table_end - hcall_real_table && | ||
229 | hcall_real_table[cmd]) | ||
230 | return 1; | ||
231 | |||
232 | return 0; | ||
233 | } | ||
234 | EXPORT_SYMBOL_GPL(kvmppc_hcall_impl_hv_realmode); | ||
diff --git a/arch/powerpc/kvm/book3s_hv_ras.c b/arch/powerpc/kvm/book3s_hv_ras.c index 3a5c568b1e89..d562c8e2bc30 100644 --- a/arch/powerpc/kvm/book3s_hv_ras.c +++ b/arch/powerpc/kvm/book3s_hv_ras.c | |||
@@ -45,14 +45,14 @@ static void reload_slb(struct kvm_vcpu *vcpu) | |||
45 | return; | 45 | return; |
46 | 46 | ||
47 | /* Sanity check */ | 47 | /* Sanity check */ |
48 | n = min_t(u32, slb->persistent, SLB_MIN_SIZE); | 48 | n = min_t(u32, be32_to_cpu(slb->persistent), SLB_MIN_SIZE); |
49 | if ((void *) &slb->save_area[n] > vcpu->arch.slb_shadow.pinned_end) | 49 | if ((void *) &slb->save_area[n] > vcpu->arch.slb_shadow.pinned_end) |
50 | return; | 50 | return; |
51 | 51 | ||
52 | /* Load up the SLB from that */ | 52 | /* Load up the SLB from that */ |
53 | for (i = 0; i < n; ++i) { | 53 | for (i = 0; i < n; ++i) { |
54 | unsigned long rb = slb->save_area[i].esid; | 54 | unsigned long rb = be64_to_cpu(slb->save_area[i].esid); |
55 | unsigned long rs = slb->save_area[i].vsid; | 55 | unsigned long rs = be64_to_cpu(slb->save_area[i].vsid); |
56 | 56 | ||
57 | rb = (rb & ~0xFFFul) | i; /* insert entry number */ | 57 | rb = (rb & ~0xFFFul) | i; /* insert entry number */ |
58 | asm volatile("slbmte %0,%1" : : "r" (rs), "r" (rb)); | 58 | asm volatile("slbmte %0,%1" : : "r" (rs), "r" (rb)); |
diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c index 5a24d3c2b6b8..084ad54c73cd 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c +++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c | |||
@@ -154,10 +154,10 @@ static pte_t lookup_linux_pte_and_update(pgd_t *pgdir, unsigned long hva, | |||
154 | return kvmppc_read_update_linux_pte(ptep, writing, hugepage_shift); | 154 | return kvmppc_read_update_linux_pte(ptep, writing, hugepage_shift); |
155 | } | 155 | } |
156 | 156 | ||
157 | static inline void unlock_hpte(unsigned long *hpte, unsigned long hpte_v) | 157 | static inline void unlock_hpte(__be64 *hpte, unsigned long hpte_v) |
158 | { | 158 | { |
159 | asm volatile(PPC_RELEASE_BARRIER "" : : : "memory"); | 159 | asm volatile(PPC_RELEASE_BARRIER "" : : : "memory"); |
160 | hpte[0] = hpte_v; | 160 | hpte[0] = cpu_to_be64(hpte_v); |
161 | } | 161 | } |
162 | 162 | ||
163 | long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags, | 163 | long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags, |
@@ -166,7 +166,7 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags, | |||
166 | { | 166 | { |
167 | unsigned long i, pa, gpa, gfn, psize; | 167 | unsigned long i, pa, gpa, gfn, psize; |
168 | unsigned long slot_fn, hva; | 168 | unsigned long slot_fn, hva; |
169 | unsigned long *hpte; | 169 | __be64 *hpte; |
170 | struct revmap_entry *rev; | 170 | struct revmap_entry *rev; |
171 | unsigned long g_ptel; | 171 | unsigned long g_ptel; |
172 | struct kvm_memory_slot *memslot; | 172 | struct kvm_memory_slot *memslot; |
@@ -275,9 +275,9 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags, | |||
275 | return H_PARAMETER; | 275 | return H_PARAMETER; |
276 | if (likely((flags & H_EXACT) == 0)) { | 276 | if (likely((flags & H_EXACT) == 0)) { |
277 | pte_index &= ~7UL; | 277 | pte_index &= ~7UL; |
278 | hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4)); | 278 | hpte = (__be64 *)(kvm->arch.hpt_virt + (pte_index << 4)); |
279 | for (i = 0; i < 8; ++i) { | 279 | for (i = 0; i < 8; ++i) { |
280 | if ((*hpte & HPTE_V_VALID) == 0 && | 280 | if ((be64_to_cpu(*hpte) & HPTE_V_VALID) == 0 && |
281 | try_lock_hpte(hpte, HPTE_V_HVLOCK | HPTE_V_VALID | | 281 | try_lock_hpte(hpte, HPTE_V_HVLOCK | HPTE_V_VALID | |
282 | HPTE_V_ABSENT)) | 282 | HPTE_V_ABSENT)) |
283 | break; | 283 | break; |
@@ -292,11 +292,13 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags, | |||
292 | */ | 292 | */ |
293 | hpte -= 16; | 293 | hpte -= 16; |
294 | for (i = 0; i < 8; ++i) { | 294 | for (i = 0; i < 8; ++i) { |
295 | u64 pte; | ||
295 | while (!try_lock_hpte(hpte, HPTE_V_HVLOCK)) | 296 | while (!try_lock_hpte(hpte, HPTE_V_HVLOCK)) |
296 | cpu_relax(); | 297 | cpu_relax(); |
297 | if (!(*hpte & (HPTE_V_VALID | HPTE_V_ABSENT))) | 298 | pte = be64_to_cpu(*hpte); |
299 | if (!(pte & (HPTE_V_VALID | HPTE_V_ABSENT))) | ||
298 | break; | 300 | break; |
299 | *hpte &= ~HPTE_V_HVLOCK; | 301 | *hpte &= ~cpu_to_be64(HPTE_V_HVLOCK); |
300 | hpte += 2; | 302 | hpte += 2; |
301 | } | 303 | } |
302 | if (i == 8) | 304 | if (i == 8) |
@@ -304,14 +306,17 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags, | |||
304 | } | 306 | } |
305 | pte_index += i; | 307 | pte_index += i; |
306 | } else { | 308 | } else { |
307 | hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4)); | 309 | hpte = (__be64 *)(kvm->arch.hpt_virt + (pte_index << 4)); |
308 | if (!try_lock_hpte(hpte, HPTE_V_HVLOCK | HPTE_V_VALID | | 310 | if (!try_lock_hpte(hpte, HPTE_V_HVLOCK | HPTE_V_VALID | |
309 | HPTE_V_ABSENT)) { | 311 | HPTE_V_ABSENT)) { |
310 | /* Lock the slot and check again */ | 312 | /* Lock the slot and check again */ |
313 | u64 pte; | ||
314 | |||
311 | while (!try_lock_hpte(hpte, HPTE_V_HVLOCK)) | 315 | while (!try_lock_hpte(hpte, HPTE_V_HVLOCK)) |
312 | cpu_relax(); | 316 | cpu_relax(); |
313 | if (*hpte & (HPTE_V_VALID | HPTE_V_ABSENT)) { | 317 | pte = be64_to_cpu(*hpte); |
314 | *hpte &= ~HPTE_V_HVLOCK; | 318 | if (pte & (HPTE_V_VALID | HPTE_V_ABSENT)) { |
319 | *hpte &= ~cpu_to_be64(HPTE_V_HVLOCK); | ||
315 | return H_PTEG_FULL; | 320 | return H_PTEG_FULL; |
316 | } | 321 | } |
317 | } | 322 | } |
@@ -347,11 +352,11 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags, | |||
347 | } | 352 | } |
348 | } | 353 | } |
349 | 354 | ||
350 | hpte[1] = ptel; | 355 | hpte[1] = cpu_to_be64(ptel); |
351 | 356 | ||
352 | /* Write the first HPTE dword, unlocking the HPTE and making it valid */ | 357 | /* Write the first HPTE dword, unlocking the HPTE and making it valid */ |
353 | eieio(); | 358 | eieio(); |
354 | hpte[0] = pteh; | 359 | hpte[0] = cpu_to_be64(pteh); |
355 | asm volatile("ptesync" : : : "memory"); | 360 | asm volatile("ptesync" : : : "memory"); |
356 | 361 | ||
357 | *pte_idx_ret = pte_index; | 362 | *pte_idx_ret = pte_index; |
@@ -468,30 +473,35 @@ long kvmppc_do_h_remove(struct kvm *kvm, unsigned long flags, | |||
468 | unsigned long pte_index, unsigned long avpn, | 473 | unsigned long pte_index, unsigned long avpn, |
469 | unsigned long *hpret) | 474 | unsigned long *hpret) |
470 | { | 475 | { |
471 | unsigned long *hpte; | 476 | __be64 *hpte; |
472 | unsigned long v, r, rb; | 477 | unsigned long v, r, rb; |
473 | struct revmap_entry *rev; | 478 | struct revmap_entry *rev; |
479 | u64 pte; | ||
474 | 480 | ||
475 | if (pte_index >= kvm->arch.hpt_npte) | 481 | if (pte_index >= kvm->arch.hpt_npte) |
476 | return H_PARAMETER; | 482 | return H_PARAMETER; |
477 | hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4)); | 483 | hpte = (__be64 *)(kvm->arch.hpt_virt + (pte_index << 4)); |
478 | while (!try_lock_hpte(hpte, HPTE_V_HVLOCK)) | 484 | while (!try_lock_hpte(hpte, HPTE_V_HVLOCK)) |
479 | cpu_relax(); | 485 | cpu_relax(); |
480 | if ((hpte[0] & (HPTE_V_ABSENT | HPTE_V_VALID)) == 0 || | 486 | pte = be64_to_cpu(hpte[0]); |
481 | ((flags & H_AVPN) && (hpte[0] & ~0x7fUL) != avpn) || | 487 | if ((pte & (HPTE_V_ABSENT | HPTE_V_VALID)) == 0 || |
482 | ((flags & H_ANDCOND) && (hpte[0] & avpn) != 0)) { | 488 | ((flags & H_AVPN) && (pte & ~0x7fUL) != avpn) || |
483 | hpte[0] &= ~HPTE_V_HVLOCK; | 489 | ((flags & H_ANDCOND) && (pte & avpn) != 0)) { |
490 | hpte[0] &= ~cpu_to_be64(HPTE_V_HVLOCK); | ||
484 | return H_NOT_FOUND; | 491 | return H_NOT_FOUND; |
485 | } | 492 | } |
486 | 493 | ||
487 | rev = real_vmalloc_addr(&kvm->arch.revmap[pte_index]); | 494 | rev = real_vmalloc_addr(&kvm->arch.revmap[pte_index]); |
488 | v = hpte[0] & ~HPTE_V_HVLOCK; | 495 | v = pte & ~HPTE_V_HVLOCK; |
489 | if (v & HPTE_V_VALID) { | 496 | if (v & HPTE_V_VALID) { |
490 | hpte[0] &= ~HPTE_V_VALID; | 497 | u64 pte1; |
491 | rb = compute_tlbie_rb(v, hpte[1], pte_index); | 498 | |
499 | pte1 = be64_to_cpu(hpte[1]); | ||
500 | hpte[0] &= ~cpu_to_be64(HPTE_V_VALID); | ||
501 | rb = compute_tlbie_rb(v, pte1, pte_index); | ||
492 | do_tlbies(kvm, &rb, 1, global_invalidates(kvm, flags), true); | 502 | do_tlbies(kvm, &rb, 1, global_invalidates(kvm, flags), true); |
493 | /* Read PTE low word after tlbie to get final R/C values */ | 503 | /* Read PTE low word after tlbie to get final R/C values */ |
494 | remove_revmap_chain(kvm, pte_index, rev, v, hpte[1]); | 504 | remove_revmap_chain(kvm, pte_index, rev, v, pte1); |
495 | } | 505 | } |
496 | r = rev->guest_rpte & ~HPTE_GR_RESERVED; | 506 | r = rev->guest_rpte & ~HPTE_GR_RESERVED; |
497 | note_hpte_modification(kvm, rev); | 507 | note_hpte_modification(kvm, rev); |
@@ -514,12 +524,14 @@ long kvmppc_h_bulk_remove(struct kvm_vcpu *vcpu) | |||
514 | { | 524 | { |
515 | struct kvm *kvm = vcpu->kvm; | 525 | struct kvm *kvm = vcpu->kvm; |
516 | unsigned long *args = &vcpu->arch.gpr[4]; | 526 | unsigned long *args = &vcpu->arch.gpr[4]; |
517 | unsigned long *hp, *hptes[4], tlbrb[4]; | 527 | __be64 *hp, *hptes[4]; |
528 | unsigned long tlbrb[4]; | ||
518 | long int i, j, k, n, found, indexes[4]; | 529 | long int i, j, k, n, found, indexes[4]; |
519 | unsigned long flags, req, pte_index, rcbits; | 530 | unsigned long flags, req, pte_index, rcbits; |
520 | int global; | 531 | int global; |
521 | long int ret = H_SUCCESS; | 532 | long int ret = H_SUCCESS; |
522 | struct revmap_entry *rev, *revs[4]; | 533 | struct revmap_entry *rev, *revs[4]; |
534 | u64 hp0; | ||
523 | 535 | ||
524 | global = global_invalidates(kvm, 0); | 536 | global = global_invalidates(kvm, 0); |
525 | for (i = 0; i < 4 && ret == H_SUCCESS; ) { | 537 | for (i = 0; i < 4 && ret == H_SUCCESS; ) { |
@@ -542,8 +554,7 @@ long kvmppc_h_bulk_remove(struct kvm_vcpu *vcpu) | |||
542 | ret = H_PARAMETER; | 554 | ret = H_PARAMETER; |
543 | break; | 555 | break; |
544 | } | 556 | } |
545 | hp = (unsigned long *) | 557 | hp = (__be64 *) (kvm->arch.hpt_virt + (pte_index << 4)); |
546 | (kvm->arch.hpt_virt + (pte_index << 4)); | ||
547 | /* to avoid deadlock, don't spin except for first */ | 558 | /* to avoid deadlock, don't spin except for first */ |
548 | if (!try_lock_hpte(hp, HPTE_V_HVLOCK)) { | 559 | if (!try_lock_hpte(hp, HPTE_V_HVLOCK)) { |
549 | if (n) | 560 | if (n) |
@@ -552,23 +563,24 @@ long kvmppc_h_bulk_remove(struct kvm_vcpu *vcpu) | |||
552 | cpu_relax(); | 563 | cpu_relax(); |
553 | } | 564 | } |
554 | found = 0; | 565 | found = 0; |
555 | if (hp[0] & (HPTE_V_ABSENT | HPTE_V_VALID)) { | 566 | hp0 = be64_to_cpu(hp[0]); |
567 | if (hp0 & (HPTE_V_ABSENT | HPTE_V_VALID)) { | ||
556 | switch (flags & 3) { | 568 | switch (flags & 3) { |
557 | case 0: /* absolute */ | 569 | case 0: /* absolute */ |
558 | found = 1; | 570 | found = 1; |
559 | break; | 571 | break; |
560 | case 1: /* andcond */ | 572 | case 1: /* andcond */ |
561 | if (!(hp[0] & args[j + 1])) | 573 | if (!(hp0 & args[j + 1])) |
562 | found = 1; | 574 | found = 1; |
563 | break; | 575 | break; |
564 | case 2: /* AVPN */ | 576 | case 2: /* AVPN */ |
565 | if ((hp[0] & ~0x7fUL) == args[j + 1]) | 577 | if ((hp0 & ~0x7fUL) == args[j + 1]) |
566 | found = 1; | 578 | found = 1; |
567 | break; | 579 | break; |
568 | } | 580 | } |
569 | } | 581 | } |
570 | if (!found) { | 582 | if (!found) { |
571 | hp[0] &= ~HPTE_V_HVLOCK; | 583 | hp[0] &= ~cpu_to_be64(HPTE_V_HVLOCK); |
572 | args[j] = ((0x90 | flags) << 56) + pte_index; | 584 | args[j] = ((0x90 | flags) << 56) + pte_index; |
573 | continue; | 585 | continue; |
574 | } | 586 | } |
@@ -577,7 +589,7 @@ long kvmppc_h_bulk_remove(struct kvm_vcpu *vcpu) | |||
577 | rev = real_vmalloc_addr(&kvm->arch.revmap[pte_index]); | 589 | rev = real_vmalloc_addr(&kvm->arch.revmap[pte_index]); |
578 | note_hpte_modification(kvm, rev); | 590 | note_hpte_modification(kvm, rev); |
579 | 591 | ||
580 | if (!(hp[0] & HPTE_V_VALID)) { | 592 | if (!(hp0 & HPTE_V_VALID)) { |
581 | /* insert R and C bits from PTE */ | 593 | /* insert R and C bits from PTE */ |
582 | rcbits = rev->guest_rpte & (HPTE_R_R|HPTE_R_C); | 594 | rcbits = rev->guest_rpte & (HPTE_R_R|HPTE_R_C); |
583 | args[j] |= rcbits << (56 - 5); | 595 | args[j] |= rcbits << (56 - 5); |
@@ -585,8 +597,10 @@ long kvmppc_h_bulk_remove(struct kvm_vcpu *vcpu) | |||
585 | continue; | 597 | continue; |
586 | } | 598 | } |
587 | 599 | ||
588 | hp[0] &= ~HPTE_V_VALID; /* leave it locked */ | 600 | /* leave it locked */ |
589 | tlbrb[n] = compute_tlbie_rb(hp[0], hp[1], pte_index); | 601 | hp[0] &= ~cpu_to_be64(HPTE_V_VALID); |
602 | tlbrb[n] = compute_tlbie_rb(be64_to_cpu(hp[0]), | ||
603 | be64_to_cpu(hp[1]), pte_index); | ||
590 | indexes[n] = j; | 604 | indexes[n] = j; |
591 | hptes[n] = hp; | 605 | hptes[n] = hp; |
592 | revs[n] = rev; | 606 | revs[n] = rev; |
@@ -605,7 +619,8 @@ long kvmppc_h_bulk_remove(struct kvm_vcpu *vcpu) | |||
605 | pte_index = args[j] & ((1ul << 56) - 1); | 619 | pte_index = args[j] & ((1ul << 56) - 1); |
606 | hp = hptes[k]; | 620 | hp = hptes[k]; |
607 | rev = revs[k]; | 621 | rev = revs[k]; |
608 | remove_revmap_chain(kvm, pte_index, rev, hp[0], hp[1]); | 622 | remove_revmap_chain(kvm, pte_index, rev, |
623 | be64_to_cpu(hp[0]), be64_to_cpu(hp[1])); | ||
609 | rcbits = rev->guest_rpte & (HPTE_R_R|HPTE_R_C); | 624 | rcbits = rev->guest_rpte & (HPTE_R_R|HPTE_R_C); |
610 | args[j] |= rcbits << (56 - 5); | 625 | args[j] |= rcbits << (56 - 5); |
611 | hp[0] = 0; | 626 | hp[0] = 0; |
@@ -620,23 +635,25 @@ long kvmppc_h_protect(struct kvm_vcpu *vcpu, unsigned long flags, | |||
620 | unsigned long va) | 635 | unsigned long va) |
621 | { | 636 | { |
622 | struct kvm *kvm = vcpu->kvm; | 637 | struct kvm *kvm = vcpu->kvm; |
623 | unsigned long *hpte; | 638 | __be64 *hpte; |
624 | struct revmap_entry *rev; | 639 | struct revmap_entry *rev; |
625 | unsigned long v, r, rb, mask, bits; | 640 | unsigned long v, r, rb, mask, bits; |
641 | u64 pte; | ||
626 | 642 | ||
627 | if (pte_index >= kvm->arch.hpt_npte) | 643 | if (pte_index >= kvm->arch.hpt_npte) |
628 | return H_PARAMETER; | 644 | return H_PARAMETER; |
629 | 645 | ||
630 | hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4)); | 646 | hpte = (__be64 *)(kvm->arch.hpt_virt + (pte_index << 4)); |
631 | while (!try_lock_hpte(hpte, HPTE_V_HVLOCK)) | 647 | while (!try_lock_hpte(hpte, HPTE_V_HVLOCK)) |
632 | cpu_relax(); | 648 | cpu_relax(); |
633 | if ((hpte[0] & (HPTE_V_ABSENT | HPTE_V_VALID)) == 0 || | 649 | pte = be64_to_cpu(hpte[0]); |
634 | ((flags & H_AVPN) && (hpte[0] & ~0x7fUL) != avpn)) { | 650 | if ((pte & (HPTE_V_ABSENT | HPTE_V_VALID)) == 0 || |
635 | hpte[0] &= ~HPTE_V_HVLOCK; | 651 | ((flags & H_AVPN) && (pte & ~0x7fUL) != avpn)) { |
652 | hpte[0] &= ~cpu_to_be64(HPTE_V_HVLOCK); | ||
636 | return H_NOT_FOUND; | 653 | return H_NOT_FOUND; |
637 | } | 654 | } |
638 | 655 | ||
639 | v = hpte[0]; | 656 | v = pte; |
640 | bits = (flags << 55) & HPTE_R_PP0; | 657 | bits = (flags << 55) & HPTE_R_PP0; |
641 | bits |= (flags << 48) & HPTE_R_KEY_HI; | 658 | bits |= (flags << 48) & HPTE_R_KEY_HI; |
642 | bits |= flags & (HPTE_R_PP | HPTE_R_N | HPTE_R_KEY_LO); | 659 | bits |= flags & (HPTE_R_PP | HPTE_R_N | HPTE_R_KEY_LO); |
@@ -650,12 +667,12 @@ long kvmppc_h_protect(struct kvm_vcpu *vcpu, unsigned long flags, | |||
650 | rev->guest_rpte = r; | 667 | rev->guest_rpte = r; |
651 | note_hpte_modification(kvm, rev); | 668 | note_hpte_modification(kvm, rev); |
652 | } | 669 | } |
653 | r = (hpte[1] & ~mask) | bits; | 670 | r = (be64_to_cpu(hpte[1]) & ~mask) | bits; |
654 | 671 | ||
655 | /* Update HPTE */ | 672 | /* Update HPTE */ |
656 | if (v & HPTE_V_VALID) { | 673 | if (v & HPTE_V_VALID) { |
657 | rb = compute_tlbie_rb(v, r, pte_index); | 674 | rb = compute_tlbie_rb(v, r, pte_index); |
658 | hpte[0] = v & ~HPTE_V_VALID; | 675 | hpte[0] = cpu_to_be64(v & ~HPTE_V_VALID); |
659 | do_tlbies(kvm, &rb, 1, global_invalidates(kvm, flags), true); | 676 | do_tlbies(kvm, &rb, 1, global_invalidates(kvm, flags), true); |
660 | /* | 677 | /* |
661 | * If the host has this page as readonly but the guest | 678 | * If the host has this page as readonly but the guest |
@@ -681,9 +698,9 @@ long kvmppc_h_protect(struct kvm_vcpu *vcpu, unsigned long flags, | |||
681 | } | 698 | } |
682 | } | 699 | } |
683 | } | 700 | } |
684 | hpte[1] = r; | 701 | hpte[1] = cpu_to_be64(r); |
685 | eieio(); | 702 | eieio(); |
686 | hpte[0] = v & ~HPTE_V_HVLOCK; | 703 | hpte[0] = cpu_to_be64(v & ~HPTE_V_HVLOCK); |
687 | asm volatile("ptesync" : : : "memory"); | 704 | asm volatile("ptesync" : : : "memory"); |
688 | return H_SUCCESS; | 705 | return H_SUCCESS; |
689 | } | 706 | } |
@@ -692,7 +709,8 @@ long kvmppc_h_read(struct kvm_vcpu *vcpu, unsigned long flags, | |||
692 | unsigned long pte_index) | 709 | unsigned long pte_index) |
693 | { | 710 | { |
694 | struct kvm *kvm = vcpu->kvm; | 711 | struct kvm *kvm = vcpu->kvm; |
695 | unsigned long *hpte, v, r; | 712 | __be64 *hpte; |
713 | unsigned long v, r; | ||
696 | int i, n = 1; | 714 | int i, n = 1; |
697 | struct revmap_entry *rev = NULL; | 715 | struct revmap_entry *rev = NULL; |
698 | 716 | ||
@@ -704,9 +722,9 @@ long kvmppc_h_read(struct kvm_vcpu *vcpu, unsigned long flags, | |||
704 | } | 722 | } |
705 | rev = real_vmalloc_addr(&kvm->arch.revmap[pte_index]); | 723 | rev = real_vmalloc_addr(&kvm->arch.revmap[pte_index]); |
706 | for (i = 0; i < n; ++i, ++pte_index) { | 724 | for (i = 0; i < n; ++i, ++pte_index) { |
707 | hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4)); | 725 | hpte = (__be64 *)(kvm->arch.hpt_virt + (pte_index << 4)); |
708 | v = hpte[0] & ~HPTE_V_HVLOCK; | 726 | v = be64_to_cpu(hpte[0]) & ~HPTE_V_HVLOCK; |
709 | r = hpte[1]; | 727 | r = be64_to_cpu(hpte[1]); |
710 | if (v & HPTE_V_ABSENT) { | 728 | if (v & HPTE_V_ABSENT) { |
711 | v &= ~HPTE_V_ABSENT; | 729 | v &= ~HPTE_V_ABSENT; |
712 | v |= HPTE_V_VALID; | 730 | v |= HPTE_V_VALID; |
@@ -721,25 +739,27 @@ long kvmppc_h_read(struct kvm_vcpu *vcpu, unsigned long flags, | |||
721 | return H_SUCCESS; | 739 | return H_SUCCESS; |
722 | } | 740 | } |
723 | 741 | ||
724 | void kvmppc_invalidate_hpte(struct kvm *kvm, unsigned long *hptep, | 742 | void kvmppc_invalidate_hpte(struct kvm *kvm, __be64 *hptep, |
725 | unsigned long pte_index) | 743 | unsigned long pte_index) |
726 | { | 744 | { |
727 | unsigned long rb; | 745 | unsigned long rb; |
728 | 746 | ||
729 | hptep[0] &= ~HPTE_V_VALID; | 747 | hptep[0] &= ~cpu_to_be64(HPTE_V_VALID); |
730 | rb = compute_tlbie_rb(hptep[0], hptep[1], pte_index); | 748 | rb = compute_tlbie_rb(be64_to_cpu(hptep[0]), be64_to_cpu(hptep[1]), |
749 | pte_index); | ||
731 | do_tlbies(kvm, &rb, 1, 1, true); | 750 | do_tlbies(kvm, &rb, 1, 1, true); |
732 | } | 751 | } |
733 | EXPORT_SYMBOL_GPL(kvmppc_invalidate_hpte); | 752 | EXPORT_SYMBOL_GPL(kvmppc_invalidate_hpte); |
734 | 753 | ||
735 | void kvmppc_clear_ref_hpte(struct kvm *kvm, unsigned long *hptep, | 754 | void kvmppc_clear_ref_hpte(struct kvm *kvm, __be64 *hptep, |
736 | unsigned long pte_index) | 755 | unsigned long pte_index) |
737 | { | 756 | { |
738 | unsigned long rb; | 757 | unsigned long rb; |
739 | unsigned char rbyte; | 758 | unsigned char rbyte; |
740 | 759 | ||
741 | rb = compute_tlbie_rb(hptep[0], hptep[1], pte_index); | 760 | rb = compute_tlbie_rb(be64_to_cpu(hptep[0]), be64_to_cpu(hptep[1]), |
742 | rbyte = (hptep[1] & ~HPTE_R_R) >> 8; | 761 | pte_index); |
762 | rbyte = (be64_to_cpu(hptep[1]) & ~HPTE_R_R) >> 8; | ||
743 | /* modify only the second-last byte, which contains the ref bit */ | 763 | /* modify only the second-last byte, which contains the ref bit */ |
744 | *((char *)hptep + 14) = rbyte; | 764 | *((char *)hptep + 14) = rbyte; |
745 | do_tlbies(kvm, &rb, 1, 1, false); | 765 | do_tlbies(kvm, &rb, 1, 1, false); |
@@ -765,7 +785,7 @@ long kvmppc_hv_find_lock_hpte(struct kvm *kvm, gva_t eaddr, unsigned long slb_v, | |||
765 | unsigned long somask; | 785 | unsigned long somask; |
766 | unsigned long vsid, hash; | 786 | unsigned long vsid, hash; |
767 | unsigned long avpn; | 787 | unsigned long avpn; |
768 | unsigned long *hpte; | 788 | __be64 *hpte; |
769 | unsigned long mask, val; | 789 | unsigned long mask, val; |
770 | unsigned long v, r; | 790 | unsigned long v, r; |
771 | 791 | ||
@@ -797,11 +817,11 @@ long kvmppc_hv_find_lock_hpte(struct kvm *kvm, gva_t eaddr, unsigned long slb_v, | |||
797 | val |= avpn; | 817 | val |= avpn; |
798 | 818 | ||
799 | for (;;) { | 819 | for (;;) { |
800 | hpte = (unsigned long *)(kvm->arch.hpt_virt + (hash << 7)); | 820 | hpte = (__be64 *)(kvm->arch.hpt_virt + (hash << 7)); |
801 | 821 | ||
802 | for (i = 0; i < 16; i += 2) { | 822 | for (i = 0; i < 16; i += 2) { |
803 | /* Read the PTE racily */ | 823 | /* Read the PTE racily */ |
804 | v = hpte[i] & ~HPTE_V_HVLOCK; | 824 | v = be64_to_cpu(hpte[i]) & ~HPTE_V_HVLOCK; |
805 | 825 | ||
806 | /* Check valid/absent, hash, segment size and AVPN */ | 826 | /* Check valid/absent, hash, segment size and AVPN */ |
807 | if (!(v & valid) || (v & mask) != val) | 827 | if (!(v & valid) || (v & mask) != val) |
@@ -810,8 +830,8 @@ long kvmppc_hv_find_lock_hpte(struct kvm *kvm, gva_t eaddr, unsigned long slb_v, | |||
810 | /* Lock the PTE and read it under the lock */ | 830 | /* Lock the PTE and read it under the lock */ |
811 | while (!try_lock_hpte(&hpte[i], HPTE_V_HVLOCK)) | 831 | while (!try_lock_hpte(&hpte[i], HPTE_V_HVLOCK)) |
812 | cpu_relax(); | 832 | cpu_relax(); |
813 | v = hpte[i] & ~HPTE_V_HVLOCK; | 833 | v = be64_to_cpu(hpte[i]) & ~HPTE_V_HVLOCK; |
814 | r = hpte[i+1]; | 834 | r = be64_to_cpu(hpte[i+1]); |
815 | 835 | ||
816 | /* | 836 | /* |
817 | * Check the HPTE again, including base page size | 837 | * Check the HPTE again, including base page size |
@@ -822,7 +842,7 @@ long kvmppc_hv_find_lock_hpte(struct kvm *kvm, gva_t eaddr, unsigned long slb_v, | |||
822 | return (hash << 3) + (i >> 1); | 842 | return (hash << 3) + (i >> 1); |
823 | 843 | ||
824 | /* Unlock and move on */ | 844 | /* Unlock and move on */ |
825 | hpte[i] = v; | 845 | hpte[i] = cpu_to_be64(v); |
826 | } | 846 | } |
827 | 847 | ||
828 | if (val & HPTE_V_SECONDARY) | 848 | if (val & HPTE_V_SECONDARY) |
@@ -851,7 +871,7 @@ long kvmppc_hpte_hv_fault(struct kvm_vcpu *vcpu, unsigned long addr, | |||
851 | struct kvm *kvm = vcpu->kvm; | 871 | struct kvm *kvm = vcpu->kvm; |
852 | long int index; | 872 | long int index; |
853 | unsigned long v, r, gr; | 873 | unsigned long v, r, gr; |
854 | unsigned long *hpte; | 874 | __be64 *hpte; |
855 | unsigned long valid; | 875 | unsigned long valid; |
856 | struct revmap_entry *rev; | 876 | struct revmap_entry *rev; |
857 | unsigned long pp, key; | 877 | unsigned long pp, key; |
@@ -867,9 +887,9 @@ long kvmppc_hpte_hv_fault(struct kvm_vcpu *vcpu, unsigned long addr, | |||
867 | return status; /* there really was no HPTE */ | 887 | return status; /* there really was no HPTE */ |
868 | return 0; /* for prot fault, HPTE disappeared */ | 888 | return 0; /* for prot fault, HPTE disappeared */ |
869 | } | 889 | } |
870 | hpte = (unsigned long *)(kvm->arch.hpt_virt + (index << 4)); | 890 | hpte = (__be64 *)(kvm->arch.hpt_virt + (index << 4)); |
871 | v = hpte[0] & ~HPTE_V_HVLOCK; | 891 | v = be64_to_cpu(hpte[0]) & ~HPTE_V_HVLOCK; |
872 | r = hpte[1]; | 892 | r = be64_to_cpu(hpte[1]); |
873 | rev = real_vmalloc_addr(&kvm->arch.revmap[index]); | 893 | rev = real_vmalloc_addr(&kvm->arch.revmap[index]); |
874 | gr = rev->guest_rpte; | 894 | gr = rev->guest_rpte; |
875 | 895 | ||
diff --git a/arch/powerpc/kvm/book3s_hv_rm_xics.c b/arch/powerpc/kvm/book3s_hv_rm_xics.c index b4b0082f761c..3ee38e6e884f 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_xics.c +++ b/arch/powerpc/kvm/book3s_hv_rm_xics.c | |||
@@ -401,6 +401,11 @@ int kvmppc_rm_h_eoi(struct kvm_vcpu *vcpu, unsigned long xirr) | |||
401 | icp->rm_action |= XICS_RM_REJECT; | 401 | icp->rm_action |= XICS_RM_REJECT; |
402 | icp->rm_reject = irq; | 402 | icp->rm_reject = irq; |
403 | } | 403 | } |
404 | |||
405 | if (!hlist_empty(&vcpu->kvm->irq_ack_notifier_list)) { | ||
406 | icp->rm_action |= XICS_RM_NOTIFY_EOI; | ||
407 | icp->rm_eoied_irq = irq; | ||
408 | } | ||
404 | bail: | 409 | bail: |
405 | return check_too_hard(xics, icp); | 410 | return check_too_hard(xics, icp); |
406 | } | 411 | } |
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index 7faf8fd05738..f0c4db7704c3 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S | |||
@@ -32,10 +32,6 @@ | |||
32 | 32 | ||
33 | #define VCPU_GPRS_TM(reg) (((reg) * ULONG_SIZE) + VCPU_GPR_TM) | 33 | #define VCPU_GPRS_TM(reg) (((reg) * ULONG_SIZE) + VCPU_GPR_TM) |
34 | 34 | ||
35 | #ifdef __LITTLE_ENDIAN__ | ||
36 | #error Need to fix lppaca and SLB shadow accesses in little endian mode | ||
37 | #endif | ||
38 | |||
39 | /* Values in HSTATE_NAPPING(r13) */ | 35 | /* Values in HSTATE_NAPPING(r13) */ |
40 | #define NAPPING_CEDE 1 | 36 | #define NAPPING_CEDE 1 |
41 | #define NAPPING_NOVCPU 2 | 37 | #define NAPPING_NOVCPU 2 |
@@ -601,9 +597,10 @@ kvmppc_got_guest: | |||
601 | ld r3, VCPU_VPA(r4) | 597 | ld r3, VCPU_VPA(r4) |
602 | cmpdi r3, 0 | 598 | cmpdi r3, 0 |
603 | beq 25f | 599 | beq 25f |
604 | lwz r5, LPPACA_YIELDCOUNT(r3) | 600 | li r6, LPPACA_YIELDCOUNT |
601 | LWZX_BE r5, r3, r6 | ||
605 | addi r5, r5, 1 | 602 | addi r5, r5, 1 |
606 | stw r5, LPPACA_YIELDCOUNT(r3) | 603 | STWX_BE r5, r3, r6 |
607 | li r6, 1 | 604 | li r6, 1 |
608 | stb r6, VCPU_VPA_DIRTY(r4) | 605 | stb r6, VCPU_VPA_DIRTY(r4) |
609 | 25: | 606 | 25: |
@@ -677,9 +674,9 @@ END_FTR_SECTION_IFCLR(CPU_FTR_TM) | |||
677 | 674 | ||
678 | mr r31, r4 | 675 | mr r31, r4 |
679 | addi r3, r31, VCPU_FPRS_TM | 676 | addi r3, r31, VCPU_FPRS_TM |
680 | bl .load_fp_state | 677 | bl load_fp_state |
681 | addi r3, r31, VCPU_VRS_TM | 678 | addi r3, r31, VCPU_VRS_TM |
682 | bl .load_vr_state | 679 | bl load_vr_state |
683 | mr r4, r31 | 680 | mr r4, r31 |
684 | lwz r7, VCPU_VRSAVE_TM(r4) | 681 | lwz r7, VCPU_VRSAVE_TM(r4) |
685 | mtspr SPRN_VRSAVE, r7 | 682 | mtspr SPRN_VRSAVE, r7 |
@@ -1423,9 +1420,9 @@ END_FTR_SECTION_IFCLR(CPU_FTR_TM) | |||
1423 | 1420 | ||
1424 | /* Save FP/VSX. */ | 1421 | /* Save FP/VSX. */ |
1425 | addi r3, r9, VCPU_FPRS_TM | 1422 | addi r3, r9, VCPU_FPRS_TM |
1426 | bl .store_fp_state | 1423 | bl store_fp_state |
1427 | addi r3, r9, VCPU_VRS_TM | 1424 | addi r3, r9, VCPU_VRS_TM |
1428 | bl .store_vr_state | 1425 | bl store_vr_state |
1429 | mfspr r6, SPRN_VRSAVE | 1426 | mfspr r6, SPRN_VRSAVE |
1430 | stw r6, VCPU_VRSAVE_TM(r9) | 1427 | stw r6, VCPU_VRSAVE_TM(r9) |
1431 | 1: | 1428 | 1: |
@@ -1448,9 +1445,10 @@ END_FTR_SECTION_IFCLR(CPU_FTR_TM) | |||
1448 | ld r8, VCPU_VPA(r9) /* do they have a VPA? */ | 1445 | ld r8, VCPU_VPA(r9) /* do they have a VPA? */ |
1449 | cmpdi r8, 0 | 1446 | cmpdi r8, 0 |
1450 | beq 25f | 1447 | beq 25f |
1451 | lwz r3, LPPACA_YIELDCOUNT(r8) | 1448 | li r4, LPPACA_YIELDCOUNT |
1449 | LWZX_BE r3, r8, r4 | ||
1452 | addi r3, r3, 1 | 1450 | addi r3, r3, 1 |
1453 | stw r3, LPPACA_YIELDCOUNT(r8) | 1451 | STWX_BE r3, r8, r4 |
1454 | li r3, 1 | 1452 | li r3, 1 |
1455 | stb r3, VCPU_VPA_DIRTY(r9) | 1453 | stb r3, VCPU_VPA_DIRTY(r9) |
1456 | 25: | 1454 | 25: |
@@ -1763,8 +1761,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) | |||
1763 | 33: ld r8,PACA_SLBSHADOWPTR(r13) | 1761 | 33: ld r8,PACA_SLBSHADOWPTR(r13) |
1764 | 1762 | ||
1765 | .rept SLB_NUM_BOLTED | 1763 | .rept SLB_NUM_BOLTED |
1766 | ld r5,SLBSHADOW_SAVEAREA(r8) | 1764 | li r3, SLBSHADOW_SAVEAREA |
1767 | ld r6,SLBSHADOW_SAVEAREA+8(r8) | 1765 | LDX_BE r5, r8, r3 |
1766 | addi r3, r3, 8 | ||
1767 | LDX_BE r6, r8, r3 | ||
1768 | andis. r7,r5,SLB_ESID_V@h | 1768 | andis. r7,r5,SLB_ESID_V@h |
1769 | beq 1f | 1769 | beq 1f |
1770 | slbmte r6,r5 | 1770 | slbmte r6,r5 |
@@ -1915,12 +1915,23 @@ hcall_try_real_mode: | |||
1915 | clrrdi r3,r3,2 | 1915 | clrrdi r3,r3,2 |
1916 | cmpldi r3,hcall_real_table_end - hcall_real_table | 1916 | cmpldi r3,hcall_real_table_end - hcall_real_table |
1917 | bge guest_exit_cont | 1917 | bge guest_exit_cont |
1918 | /* See if this hcall is enabled for in-kernel handling */ | ||
1919 | ld r4, VCPU_KVM(r9) | ||
1920 | srdi r0, r3, 8 /* r0 = (r3 / 4) >> 6 */ | ||
1921 | sldi r0, r0, 3 /* index into kvm->arch.enabled_hcalls[] */ | ||
1922 | add r4, r4, r0 | ||
1923 | ld r0, KVM_ENABLED_HCALLS(r4) | ||
1924 | rlwinm r4, r3, 32-2, 0x3f /* r4 = (r3 / 4) & 0x3f */ | ||
1925 | srd r0, r0, r4 | ||
1926 | andi. r0, r0, 1 | ||
1927 | beq guest_exit_cont | ||
1928 | /* Get pointer to handler, if any, and call it */ | ||
1918 | LOAD_REG_ADDR(r4, hcall_real_table) | 1929 | LOAD_REG_ADDR(r4, hcall_real_table) |
1919 | lwax r3,r3,r4 | 1930 | lwax r3,r3,r4 |
1920 | cmpwi r3,0 | 1931 | cmpwi r3,0 |
1921 | beq guest_exit_cont | 1932 | beq guest_exit_cont |
1922 | add r3,r3,r4 | 1933 | add r12,r3,r4 |
1923 | mtctr r3 | 1934 | mtctr r12 |
1924 | mr r3,r9 /* get vcpu pointer */ | 1935 | mr r3,r9 /* get vcpu pointer */ |
1925 | ld r4,VCPU_GPR(R4)(r9) | 1936 | ld r4,VCPU_GPR(R4)(r9) |
1926 | bctrl | 1937 | bctrl |
@@ -2037,6 +2048,7 @@ hcall_real_table: | |||
2037 | .long 0 /* 0x12c */ | 2048 | .long 0 /* 0x12c */ |
2038 | .long 0 /* 0x130 */ | 2049 | .long 0 /* 0x130 */ |
2039 | .long DOTSYM(kvmppc_h_set_xdabr) - hcall_real_table | 2050 | .long DOTSYM(kvmppc_h_set_xdabr) - hcall_real_table |
2051 | .globl hcall_real_table_end | ||
2040 | hcall_real_table_end: | 2052 | hcall_real_table_end: |
2041 | 2053 | ||
2042 | ignore_hdec: | 2054 | ignore_hdec: |
@@ -2344,7 +2356,18 @@ kvmppc_read_intr: | |||
2344 | cmpdi r6, 0 | 2356 | cmpdi r6, 0 |
2345 | beq- 1f | 2357 | beq- 1f |
2346 | lwzcix r0, r6, r7 | 2358 | lwzcix r0, r6, r7 |
2347 | rlwinm. r3, r0, 0, 0xffffff | 2359 | /* |
2360 | * Save XIRR for later. Since we get in in reverse endian on LE | ||
2361 | * systems, save it byte reversed and fetch it back in host endian. | ||
2362 | */ | ||
2363 | li r3, HSTATE_SAVED_XIRR | ||
2364 | STWX_BE r0, r3, r13 | ||
2365 | #ifdef __LITTLE_ENDIAN__ | ||
2366 | lwz r3, HSTATE_SAVED_XIRR(r13) | ||
2367 | #else | ||
2368 | mr r3, r0 | ||
2369 | #endif | ||
2370 | rlwinm. r3, r3, 0, 0xffffff | ||
2348 | sync | 2371 | sync |
2349 | beq 1f /* if nothing pending in the ICP */ | 2372 | beq 1f /* if nothing pending in the ICP */ |
2350 | 2373 | ||
@@ -2376,10 +2399,9 @@ kvmppc_read_intr: | |||
2376 | li r3, -1 | 2399 | li r3, -1 |
2377 | 1: blr | 2400 | 1: blr |
2378 | 2401 | ||
2379 | 42: /* It's not an IPI and it's for the host, stash it in the PACA | 2402 | 42: /* It's not an IPI and it's for the host. We saved a copy of XIRR in |
2380 | * before exit, it will be picked up by the host ICP driver | 2403 | * the PACA earlier, it will be picked up by the host ICP driver |
2381 | */ | 2404 | */ |
2382 | stw r0, HSTATE_SAVED_XIRR(r13) | ||
2383 | li r3, 1 | 2405 | li r3, 1 |
2384 | b 1b | 2406 | b 1b |
2385 | 2407 | ||
@@ -2414,11 +2436,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX) | |||
2414 | mtmsrd r8 | 2436 | mtmsrd r8 |
2415 | isync | 2437 | isync |
2416 | addi r3,r3,VCPU_FPRS | 2438 | addi r3,r3,VCPU_FPRS |
2417 | bl .store_fp_state | 2439 | bl store_fp_state |
2418 | #ifdef CONFIG_ALTIVEC | 2440 | #ifdef CONFIG_ALTIVEC |
2419 | BEGIN_FTR_SECTION | 2441 | BEGIN_FTR_SECTION |
2420 | addi r3,r31,VCPU_VRS | 2442 | addi r3,r31,VCPU_VRS |
2421 | bl .store_vr_state | 2443 | bl store_vr_state |
2422 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | 2444 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) |
2423 | #endif | 2445 | #endif |
2424 | mfspr r6,SPRN_VRSAVE | 2446 | mfspr r6,SPRN_VRSAVE |
@@ -2450,11 +2472,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX) | |||
2450 | mtmsrd r8 | 2472 | mtmsrd r8 |
2451 | isync | 2473 | isync |
2452 | addi r3,r4,VCPU_FPRS | 2474 | addi r3,r4,VCPU_FPRS |
2453 | bl .load_fp_state | 2475 | bl load_fp_state |
2454 | #ifdef CONFIG_ALTIVEC | 2476 | #ifdef CONFIG_ALTIVEC |
2455 | BEGIN_FTR_SECTION | 2477 | BEGIN_FTR_SECTION |
2456 | addi r3,r31,VCPU_VRS | 2478 | addi r3,r31,VCPU_VRS |
2457 | bl .load_vr_state | 2479 | bl load_vr_state |
2458 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | 2480 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) |
2459 | #endif | 2481 | #endif |
2460 | lwz r7,VCPU_VRSAVE(r31) | 2482 | lwz r7,VCPU_VRSAVE(r31) |
diff --git a/arch/powerpc/kvm/book3s_paired_singles.c b/arch/powerpc/kvm/book3s_paired_singles.c index 6c8011fd57e6..bfb8035314e3 100644 --- a/arch/powerpc/kvm/book3s_paired_singles.c +++ b/arch/powerpc/kvm/book3s_paired_singles.c | |||
@@ -639,26 +639,36 @@ static int kvmppc_ps_one_in(struct kvm_vcpu *vcpu, bool rc, | |||
639 | 639 | ||
640 | int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu) | 640 | int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu) |
641 | { | 641 | { |
642 | u32 inst = kvmppc_get_last_inst(vcpu); | 642 | u32 inst; |
643 | enum emulation_result emulated = EMULATE_DONE; | 643 | enum emulation_result emulated = EMULATE_DONE; |
644 | int ax_rd, ax_ra, ax_rb, ax_rc; | ||
645 | short full_d; | ||
646 | u64 *fpr_d, *fpr_a, *fpr_b, *fpr_c; | ||
644 | 647 | ||
645 | int ax_rd = inst_get_field(inst, 6, 10); | 648 | bool rcomp; |
646 | int ax_ra = inst_get_field(inst, 11, 15); | 649 | u32 cr; |
647 | int ax_rb = inst_get_field(inst, 16, 20); | ||
648 | int ax_rc = inst_get_field(inst, 21, 25); | ||
649 | short full_d = inst_get_field(inst, 16, 31); | ||
650 | |||
651 | u64 *fpr_d = &VCPU_FPR(vcpu, ax_rd); | ||
652 | u64 *fpr_a = &VCPU_FPR(vcpu, ax_ra); | ||
653 | u64 *fpr_b = &VCPU_FPR(vcpu, ax_rb); | ||
654 | u64 *fpr_c = &VCPU_FPR(vcpu, ax_rc); | ||
655 | |||
656 | bool rcomp = (inst & 1) ? true : false; | ||
657 | u32 cr = kvmppc_get_cr(vcpu); | ||
658 | #ifdef DEBUG | 650 | #ifdef DEBUG |
659 | int i; | 651 | int i; |
660 | #endif | 652 | #endif |
661 | 653 | ||
654 | emulated = kvmppc_get_last_inst(vcpu, INST_GENERIC, &inst); | ||
655 | if (emulated != EMULATE_DONE) | ||
656 | return emulated; | ||
657 | |||
658 | ax_rd = inst_get_field(inst, 6, 10); | ||
659 | ax_ra = inst_get_field(inst, 11, 15); | ||
660 | ax_rb = inst_get_field(inst, 16, 20); | ||
661 | ax_rc = inst_get_field(inst, 21, 25); | ||
662 | full_d = inst_get_field(inst, 16, 31); | ||
663 | |||
664 | fpr_d = &VCPU_FPR(vcpu, ax_rd); | ||
665 | fpr_a = &VCPU_FPR(vcpu, ax_ra); | ||
666 | fpr_b = &VCPU_FPR(vcpu, ax_rb); | ||
667 | fpr_c = &VCPU_FPR(vcpu, ax_rc); | ||
668 | |||
669 | rcomp = (inst & 1) ? true : false; | ||
670 | cr = kvmppc_get_cr(vcpu); | ||
671 | |||
662 | if (!kvmppc_inst_is_paired_single(vcpu, inst)) | 672 | if (!kvmppc_inst_is_paired_single(vcpu, inst)) |
663 | return EMULATE_FAIL; | 673 | return EMULATE_FAIL; |
664 | 674 | ||
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index 8eef1e519077..faffb27badd9 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c | |||
@@ -62,6 +62,35 @@ static void kvmppc_giveup_fac(struct kvm_vcpu *vcpu, ulong fac); | |||
62 | #define HW_PAGE_SIZE PAGE_SIZE | 62 | #define HW_PAGE_SIZE PAGE_SIZE |
63 | #endif | 63 | #endif |
64 | 64 | ||
65 | static bool kvmppc_is_split_real(struct kvm_vcpu *vcpu) | ||
66 | { | ||
67 | ulong msr = kvmppc_get_msr(vcpu); | ||
68 | return (msr & (MSR_IR|MSR_DR)) == MSR_DR; | ||
69 | } | ||
70 | |||
71 | static void kvmppc_fixup_split_real(struct kvm_vcpu *vcpu) | ||
72 | { | ||
73 | ulong msr = kvmppc_get_msr(vcpu); | ||
74 | ulong pc = kvmppc_get_pc(vcpu); | ||
75 | |||
76 | /* We are in DR only split real mode */ | ||
77 | if ((msr & (MSR_IR|MSR_DR)) != MSR_DR) | ||
78 | return; | ||
79 | |||
80 | /* We have not fixed up the guest already */ | ||
81 | if (vcpu->arch.hflags & BOOK3S_HFLAG_SPLIT_HACK) | ||
82 | return; | ||
83 | |||
84 | /* The code is in fixupable address space */ | ||
85 | if (pc & SPLIT_HACK_MASK) | ||
86 | return; | ||
87 | |||
88 | vcpu->arch.hflags |= BOOK3S_HFLAG_SPLIT_HACK; | ||
89 | kvmppc_set_pc(vcpu, pc | SPLIT_HACK_OFFS); | ||
90 | } | ||
91 | |||
92 | void kvmppc_unfixup_split_real(struct kvm_vcpu *vcpu); | ||
93 | |||
65 | static void kvmppc_core_vcpu_load_pr(struct kvm_vcpu *vcpu, int cpu) | 94 | static void kvmppc_core_vcpu_load_pr(struct kvm_vcpu *vcpu, int cpu) |
66 | { | 95 | { |
67 | #ifdef CONFIG_PPC_BOOK3S_64 | 96 | #ifdef CONFIG_PPC_BOOK3S_64 |
@@ -71,10 +100,19 @@ static void kvmppc_core_vcpu_load_pr(struct kvm_vcpu *vcpu, int cpu) | |||
71 | svcpu->in_use = 0; | 100 | svcpu->in_use = 0; |
72 | svcpu_put(svcpu); | 101 | svcpu_put(svcpu); |
73 | #endif | 102 | #endif |
103 | |||
104 | /* Disable AIL if supported */ | ||
105 | if (cpu_has_feature(CPU_FTR_HVMODE) && | ||
106 | cpu_has_feature(CPU_FTR_ARCH_207S)) | ||
107 | mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~LPCR_AIL); | ||
108 | |||
74 | vcpu->cpu = smp_processor_id(); | 109 | vcpu->cpu = smp_processor_id(); |
75 | #ifdef CONFIG_PPC_BOOK3S_32 | 110 | #ifdef CONFIG_PPC_BOOK3S_32 |
76 | current->thread.kvm_shadow_vcpu = vcpu->arch.shadow_vcpu; | 111 | current->thread.kvm_shadow_vcpu = vcpu->arch.shadow_vcpu; |
77 | #endif | 112 | #endif |
113 | |||
114 | if (kvmppc_is_split_real(vcpu)) | ||
115 | kvmppc_fixup_split_real(vcpu); | ||
78 | } | 116 | } |
79 | 117 | ||
80 | static void kvmppc_core_vcpu_put_pr(struct kvm_vcpu *vcpu) | 118 | static void kvmppc_core_vcpu_put_pr(struct kvm_vcpu *vcpu) |
@@ -89,8 +127,17 @@ static void kvmppc_core_vcpu_put_pr(struct kvm_vcpu *vcpu) | |||
89 | svcpu_put(svcpu); | 127 | svcpu_put(svcpu); |
90 | #endif | 128 | #endif |
91 | 129 | ||
130 | if (kvmppc_is_split_real(vcpu)) | ||
131 | kvmppc_unfixup_split_real(vcpu); | ||
132 | |||
92 | kvmppc_giveup_ext(vcpu, MSR_FP | MSR_VEC | MSR_VSX); | 133 | kvmppc_giveup_ext(vcpu, MSR_FP | MSR_VEC | MSR_VSX); |
93 | kvmppc_giveup_fac(vcpu, FSCR_TAR_LG); | 134 | kvmppc_giveup_fac(vcpu, FSCR_TAR_LG); |
135 | |||
136 | /* Enable AIL if supported */ | ||
137 | if (cpu_has_feature(CPU_FTR_HVMODE) && | ||
138 | cpu_has_feature(CPU_FTR_ARCH_207S)) | ||
139 | mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) | LPCR_AIL_3); | ||
140 | |||
94 | vcpu->cpu = -1; | 141 | vcpu->cpu = -1; |
95 | } | 142 | } |
96 | 143 | ||
@@ -120,6 +167,14 @@ void kvmppc_copy_to_svcpu(struct kvmppc_book3s_shadow_vcpu *svcpu, | |||
120 | #ifdef CONFIG_PPC_BOOK3S_64 | 167 | #ifdef CONFIG_PPC_BOOK3S_64 |
121 | svcpu->shadow_fscr = vcpu->arch.shadow_fscr; | 168 | svcpu->shadow_fscr = vcpu->arch.shadow_fscr; |
122 | #endif | 169 | #endif |
170 | /* | ||
171 | * Now also save the current time base value. We use this | ||
172 | * to find the guest purr and spurr value. | ||
173 | */ | ||
174 | vcpu->arch.entry_tb = get_tb(); | ||
175 | vcpu->arch.entry_vtb = get_vtb(); | ||
176 | if (cpu_has_feature(CPU_FTR_ARCH_207S)) | ||
177 | vcpu->arch.entry_ic = mfspr(SPRN_IC); | ||
123 | svcpu->in_use = true; | 178 | svcpu->in_use = true; |
124 | } | 179 | } |
125 | 180 | ||
@@ -166,6 +221,14 @@ void kvmppc_copy_from_svcpu(struct kvm_vcpu *vcpu, | |||
166 | #ifdef CONFIG_PPC_BOOK3S_64 | 221 | #ifdef CONFIG_PPC_BOOK3S_64 |
167 | vcpu->arch.shadow_fscr = svcpu->shadow_fscr; | 222 | vcpu->arch.shadow_fscr = svcpu->shadow_fscr; |
168 | #endif | 223 | #endif |
224 | /* | ||
225 | * Update purr and spurr using time base on exit. | ||
226 | */ | ||
227 | vcpu->arch.purr += get_tb() - vcpu->arch.entry_tb; | ||
228 | vcpu->arch.spurr += get_tb() - vcpu->arch.entry_tb; | ||
229 | vcpu->arch.vtb += get_vtb() - vcpu->arch.entry_vtb; | ||
230 | if (cpu_has_feature(CPU_FTR_ARCH_207S)) | ||
231 | vcpu->arch.ic += mfspr(SPRN_IC) - vcpu->arch.entry_ic; | ||
169 | svcpu->in_use = false; | 232 | svcpu->in_use = false; |
170 | 233 | ||
171 | out: | 234 | out: |
@@ -294,6 +357,11 @@ static void kvmppc_set_msr_pr(struct kvm_vcpu *vcpu, u64 msr) | |||
294 | } | 357 | } |
295 | } | 358 | } |
296 | 359 | ||
360 | if (kvmppc_is_split_real(vcpu)) | ||
361 | kvmppc_fixup_split_real(vcpu); | ||
362 | else | ||
363 | kvmppc_unfixup_split_real(vcpu); | ||
364 | |||
297 | if ((kvmppc_get_msr(vcpu) & (MSR_PR|MSR_IR|MSR_DR)) != | 365 | if ((kvmppc_get_msr(vcpu) & (MSR_PR|MSR_IR|MSR_DR)) != |
298 | (old_msr & (MSR_PR|MSR_IR|MSR_DR))) { | 366 | (old_msr & (MSR_PR|MSR_IR|MSR_DR))) { |
299 | kvmppc_mmu_flush_segments(vcpu); | 367 | kvmppc_mmu_flush_segments(vcpu); |
@@ -443,19 +511,19 @@ static void kvmppc_patch_dcbz(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte) | |||
443 | put_page(hpage); | 511 | put_page(hpage); |
444 | } | 512 | } |
445 | 513 | ||
446 | static int kvmppc_visible_gfn(struct kvm_vcpu *vcpu, gfn_t gfn) | 514 | static int kvmppc_visible_gpa(struct kvm_vcpu *vcpu, gpa_t gpa) |
447 | { | 515 | { |
448 | ulong mp_pa = vcpu->arch.magic_page_pa; | 516 | ulong mp_pa = vcpu->arch.magic_page_pa; |
449 | 517 | ||
450 | if (!(kvmppc_get_msr(vcpu) & MSR_SF)) | 518 | if (!(kvmppc_get_msr(vcpu) & MSR_SF)) |
451 | mp_pa = (uint32_t)mp_pa; | 519 | mp_pa = (uint32_t)mp_pa; |
452 | 520 | ||
453 | if (unlikely(mp_pa) && | 521 | gpa &= ~0xFFFULL; |
454 | unlikely((mp_pa & KVM_PAM) >> PAGE_SHIFT == gfn)) { | 522 | if (unlikely(mp_pa) && unlikely((mp_pa & KVM_PAM) == (gpa & KVM_PAM))) { |
455 | return 1; | 523 | return 1; |
456 | } | 524 | } |
457 | 525 | ||
458 | return kvm_is_visible_gfn(vcpu->kvm, gfn); | 526 | return kvm_is_visible_gfn(vcpu->kvm, gpa >> PAGE_SHIFT); |
459 | } | 527 | } |
460 | 528 | ||
461 | int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu, | 529 | int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu, |
@@ -494,6 +562,11 @@ int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
494 | pte.vpage |= ((u64)VSID_REAL << (SID_SHIFT - 12)); | 562 | pte.vpage |= ((u64)VSID_REAL << (SID_SHIFT - 12)); |
495 | break; | 563 | break; |
496 | case MSR_DR: | 564 | case MSR_DR: |
565 | if (!data && | ||
566 | (vcpu->arch.hflags & BOOK3S_HFLAG_SPLIT_HACK) && | ||
567 | ((pte.raddr & SPLIT_HACK_MASK) == SPLIT_HACK_OFFS)) | ||
568 | pte.raddr &= ~SPLIT_HACK_MASK; | ||
569 | /* fall through */ | ||
497 | case MSR_IR: | 570 | case MSR_IR: |
498 | vcpu->arch.mmu.esid_to_vsid(vcpu, eaddr >> SID_SHIFT, &vsid); | 571 | vcpu->arch.mmu.esid_to_vsid(vcpu, eaddr >> SID_SHIFT, &vsid); |
499 | 572 | ||
@@ -541,7 +614,7 @@ int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
541 | kvmppc_set_dar(vcpu, kvmppc_get_fault_dar(vcpu)); | 614 | kvmppc_set_dar(vcpu, kvmppc_get_fault_dar(vcpu)); |
542 | kvmppc_book3s_queue_irqprio(vcpu, vec + 0x80); | 615 | kvmppc_book3s_queue_irqprio(vcpu, vec + 0x80); |
543 | } else if (!is_mmio && | 616 | } else if (!is_mmio && |
544 | kvmppc_visible_gfn(vcpu, pte.raddr >> PAGE_SHIFT)) { | 617 | kvmppc_visible_gpa(vcpu, pte.raddr)) { |
545 | if (data && !(vcpu->arch.fault_dsisr & DSISR_NOHPTE)) { | 618 | if (data && !(vcpu->arch.fault_dsisr & DSISR_NOHPTE)) { |
546 | /* | 619 | /* |
547 | * There is already a host HPTE there, presumably | 620 | * There is already a host HPTE there, presumably |
@@ -637,42 +710,6 @@ static void kvmppc_giveup_fac(struct kvm_vcpu *vcpu, ulong fac) | |||
637 | #endif | 710 | #endif |
638 | } | 711 | } |
639 | 712 | ||
640 | static int kvmppc_read_inst(struct kvm_vcpu *vcpu) | ||
641 | { | ||
642 | ulong srr0 = kvmppc_get_pc(vcpu); | ||
643 | u32 last_inst = kvmppc_get_last_inst(vcpu); | ||
644 | int ret; | ||
645 | |||
646 | ret = kvmppc_ld(vcpu, &srr0, sizeof(u32), &last_inst, false); | ||
647 | if (ret == -ENOENT) { | ||
648 | ulong msr = kvmppc_get_msr(vcpu); | ||
649 | |||
650 | msr = kvmppc_set_field(msr, 33, 33, 1); | ||
651 | msr = kvmppc_set_field(msr, 34, 36, 0); | ||
652 | msr = kvmppc_set_field(msr, 42, 47, 0); | ||
653 | kvmppc_set_msr_fast(vcpu, msr); | ||
654 | kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_INST_STORAGE); | ||
655 | return EMULATE_AGAIN; | ||
656 | } | ||
657 | |||
658 | return EMULATE_DONE; | ||
659 | } | ||
660 | |||
661 | static int kvmppc_check_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr) | ||
662 | { | ||
663 | |||
664 | /* Need to do paired single emulation? */ | ||
665 | if (!(vcpu->arch.hflags & BOOK3S_HFLAG_PAIRED_SINGLE)) | ||
666 | return EMULATE_DONE; | ||
667 | |||
668 | /* Read out the instruction */ | ||
669 | if (kvmppc_read_inst(vcpu) == EMULATE_DONE) | ||
670 | /* Need to emulate */ | ||
671 | return EMULATE_FAIL; | ||
672 | |||
673 | return EMULATE_AGAIN; | ||
674 | } | ||
675 | |||
676 | /* Handle external providers (FPU, Altivec, VSX) */ | 713 | /* Handle external providers (FPU, Altivec, VSX) */ |
677 | static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr, | 714 | static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr, |
678 | ulong msr) | 715 | ulong msr) |
@@ -834,6 +871,15 @@ static int kvmppc_handle_fac(struct kvm_vcpu *vcpu, ulong fac) | |||
834 | 871 | ||
835 | return RESUME_GUEST; | 872 | return RESUME_GUEST; |
836 | } | 873 | } |
874 | |||
875 | void kvmppc_set_fscr(struct kvm_vcpu *vcpu, u64 fscr) | ||
876 | { | ||
877 | if ((vcpu->arch.fscr & FSCR_TAR) && !(fscr & FSCR_TAR)) { | ||
878 | /* TAR got dropped, drop it in shadow too */ | ||
879 | kvmppc_giveup_fac(vcpu, FSCR_TAR_LG); | ||
880 | } | ||
881 | vcpu->arch.fscr = fscr; | ||
882 | } | ||
837 | #endif | 883 | #endif |
838 | 884 | ||
839 | int kvmppc_handle_exit_pr(struct kvm_run *run, struct kvm_vcpu *vcpu, | 885 | int kvmppc_handle_exit_pr(struct kvm_run *run, struct kvm_vcpu *vcpu, |
@@ -858,6 +904,9 @@ int kvmppc_handle_exit_pr(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
858 | ulong shadow_srr1 = vcpu->arch.shadow_srr1; | 904 | ulong shadow_srr1 = vcpu->arch.shadow_srr1; |
859 | vcpu->stat.pf_instruc++; | 905 | vcpu->stat.pf_instruc++; |
860 | 906 | ||
907 | if (kvmppc_is_split_real(vcpu)) | ||
908 | kvmppc_fixup_split_real(vcpu); | ||
909 | |||
861 | #ifdef CONFIG_PPC_BOOK3S_32 | 910 | #ifdef CONFIG_PPC_BOOK3S_32 |
862 | /* We set segments as unused segments when invalidating them. So | 911 | /* We set segments as unused segments when invalidating them. So |
863 | * treat the respective fault as segment fault. */ | 912 | * treat the respective fault as segment fault. */ |
@@ -960,6 +1009,7 @@ int kvmppc_handle_exit_pr(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
960 | case BOOK3S_INTERRUPT_DECREMENTER: | 1009 | case BOOK3S_INTERRUPT_DECREMENTER: |
961 | case BOOK3S_INTERRUPT_HV_DECREMENTER: | 1010 | case BOOK3S_INTERRUPT_HV_DECREMENTER: |
962 | case BOOK3S_INTERRUPT_DOORBELL: | 1011 | case BOOK3S_INTERRUPT_DOORBELL: |
1012 | case BOOK3S_INTERRUPT_H_DOORBELL: | ||
963 | vcpu->stat.dec_exits++; | 1013 | vcpu->stat.dec_exits++; |
964 | r = RESUME_GUEST; | 1014 | r = RESUME_GUEST; |
965 | break; | 1015 | break; |
@@ -977,15 +1027,24 @@ int kvmppc_handle_exit_pr(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
977 | { | 1027 | { |
978 | enum emulation_result er; | 1028 | enum emulation_result er; |
979 | ulong flags; | 1029 | ulong flags; |
1030 | u32 last_inst; | ||
1031 | int emul; | ||
980 | 1032 | ||
981 | program_interrupt: | 1033 | program_interrupt: |
982 | flags = vcpu->arch.shadow_srr1 & 0x1f0000ull; | 1034 | flags = vcpu->arch.shadow_srr1 & 0x1f0000ull; |
983 | 1035 | ||
1036 | emul = kvmppc_get_last_inst(vcpu, INST_GENERIC, &last_inst); | ||
1037 | if (emul != EMULATE_DONE) { | ||
1038 | r = RESUME_GUEST; | ||
1039 | break; | ||
1040 | } | ||
1041 | |||
984 | if (kvmppc_get_msr(vcpu) & MSR_PR) { | 1042 | if (kvmppc_get_msr(vcpu) & MSR_PR) { |
985 | #ifdef EXIT_DEBUG | 1043 | #ifdef EXIT_DEBUG |
986 | printk(KERN_INFO "Userspace triggered 0x700 exception at 0x%lx (0x%x)\n", kvmppc_get_pc(vcpu), kvmppc_get_last_inst(vcpu)); | 1044 | pr_info("Userspace triggered 0x700 exception at\n 0x%lx (0x%x)\n", |
1045 | kvmppc_get_pc(vcpu), last_inst); | ||
987 | #endif | 1046 | #endif |
988 | if ((kvmppc_get_last_inst(vcpu) & 0xff0007ff) != | 1047 | if ((last_inst & 0xff0007ff) != |
989 | (INS_DCBZ & 0xfffffff7)) { | 1048 | (INS_DCBZ & 0xfffffff7)) { |
990 | kvmppc_core_queue_program(vcpu, flags); | 1049 | kvmppc_core_queue_program(vcpu, flags); |
991 | r = RESUME_GUEST; | 1050 | r = RESUME_GUEST; |
@@ -1004,7 +1063,7 @@ program_interrupt: | |||
1004 | break; | 1063 | break; |
1005 | case EMULATE_FAIL: | 1064 | case EMULATE_FAIL: |
1006 | printk(KERN_CRIT "%s: emulation at %lx failed (%08x)\n", | 1065 | printk(KERN_CRIT "%s: emulation at %lx failed (%08x)\n", |
1007 | __func__, kvmppc_get_pc(vcpu), kvmppc_get_last_inst(vcpu)); | 1066 | __func__, kvmppc_get_pc(vcpu), last_inst); |
1008 | kvmppc_core_queue_program(vcpu, flags); | 1067 | kvmppc_core_queue_program(vcpu, flags); |
1009 | r = RESUME_GUEST; | 1068 | r = RESUME_GUEST; |
1010 | break; | 1069 | break; |
@@ -1021,8 +1080,23 @@ program_interrupt: | |||
1021 | break; | 1080 | break; |
1022 | } | 1081 | } |
1023 | case BOOK3S_INTERRUPT_SYSCALL: | 1082 | case BOOK3S_INTERRUPT_SYSCALL: |
1083 | { | ||
1084 | u32 last_sc; | ||
1085 | int emul; | ||
1086 | |||
1087 | /* Get last sc for papr */ | ||
1088 | if (vcpu->arch.papr_enabled) { | ||
1089 | /* The sc instuction points SRR0 to the next inst */ | ||
1090 | emul = kvmppc_get_last_inst(vcpu, INST_SC, &last_sc); | ||
1091 | if (emul != EMULATE_DONE) { | ||
1092 | kvmppc_set_pc(vcpu, kvmppc_get_pc(vcpu) - 4); | ||
1093 | r = RESUME_GUEST; | ||
1094 | break; | ||
1095 | } | ||
1096 | } | ||
1097 | |||
1024 | if (vcpu->arch.papr_enabled && | 1098 | if (vcpu->arch.papr_enabled && |
1025 | (kvmppc_get_last_sc(vcpu) == 0x44000022) && | 1099 | (last_sc == 0x44000022) && |
1026 | !(kvmppc_get_msr(vcpu) & MSR_PR)) { | 1100 | !(kvmppc_get_msr(vcpu) & MSR_PR)) { |
1027 | /* SC 1 papr hypercalls */ | 1101 | /* SC 1 papr hypercalls */ |
1028 | ulong cmd = kvmppc_get_gpr(vcpu, 3); | 1102 | ulong cmd = kvmppc_get_gpr(vcpu, 3); |
@@ -1067,36 +1141,51 @@ program_interrupt: | |||
1067 | r = RESUME_GUEST; | 1141 | r = RESUME_GUEST; |
1068 | } | 1142 | } |
1069 | break; | 1143 | break; |
1144 | } | ||
1070 | case BOOK3S_INTERRUPT_FP_UNAVAIL: | 1145 | case BOOK3S_INTERRUPT_FP_UNAVAIL: |
1071 | case BOOK3S_INTERRUPT_ALTIVEC: | 1146 | case BOOK3S_INTERRUPT_ALTIVEC: |
1072 | case BOOK3S_INTERRUPT_VSX: | 1147 | case BOOK3S_INTERRUPT_VSX: |
1073 | { | 1148 | { |
1074 | int ext_msr = 0; | 1149 | int ext_msr = 0; |
1150 | int emul; | ||
1151 | u32 last_inst; | ||
1152 | |||
1153 | if (vcpu->arch.hflags & BOOK3S_HFLAG_PAIRED_SINGLE) { | ||
1154 | /* Do paired single instruction emulation */ | ||
1155 | emul = kvmppc_get_last_inst(vcpu, INST_GENERIC, | ||
1156 | &last_inst); | ||
1157 | if (emul == EMULATE_DONE) | ||
1158 | goto program_interrupt; | ||
1159 | else | ||
1160 | r = RESUME_GUEST; | ||
1075 | 1161 | ||
1076 | switch (exit_nr) { | 1162 | break; |
1077 | case BOOK3S_INTERRUPT_FP_UNAVAIL: ext_msr = MSR_FP; break; | ||
1078 | case BOOK3S_INTERRUPT_ALTIVEC: ext_msr = MSR_VEC; break; | ||
1079 | case BOOK3S_INTERRUPT_VSX: ext_msr = MSR_VSX; break; | ||
1080 | } | 1163 | } |
1081 | 1164 | ||
1082 | switch (kvmppc_check_ext(vcpu, exit_nr)) { | 1165 | /* Enable external provider */ |
1083 | case EMULATE_DONE: | 1166 | switch (exit_nr) { |
1084 | /* everything ok - let's enable the ext */ | 1167 | case BOOK3S_INTERRUPT_FP_UNAVAIL: |
1085 | r = kvmppc_handle_ext(vcpu, exit_nr, ext_msr); | 1168 | ext_msr = MSR_FP; |
1086 | break; | 1169 | break; |
1087 | case EMULATE_FAIL: | 1170 | |
1088 | /* we need to emulate this instruction */ | 1171 | case BOOK3S_INTERRUPT_ALTIVEC: |
1089 | goto program_interrupt; | 1172 | ext_msr = MSR_VEC; |
1090 | break; | 1173 | break; |
1091 | default: | 1174 | |
1092 | /* nothing to worry about - go again */ | 1175 | case BOOK3S_INTERRUPT_VSX: |
1176 | ext_msr = MSR_VSX; | ||
1093 | break; | 1177 | break; |
1094 | } | 1178 | } |
1179 | |||
1180 | r = kvmppc_handle_ext(vcpu, exit_nr, ext_msr); | ||
1095 | break; | 1181 | break; |
1096 | } | 1182 | } |
1097 | case BOOK3S_INTERRUPT_ALIGNMENT: | 1183 | case BOOK3S_INTERRUPT_ALIGNMENT: |
1098 | if (kvmppc_read_inst(vcpu) == EMULATE_DONE) { | 1184 | { |
1099 | u32 last_inst = kvmppc_get_last_inst(vcpu); | 1185 | u32 last_inst; |
1186 | int emul = kvmppc_get_last_inst(vcpu, INST_GENERIC, &last_inst); | ||
1187 | |||
1188 | if (emul == EMULATE_DONE) { | ||
1100 | u32 dsisr; | 1189 | u32 dsisr; |
1101 | u64 dar; | 1190 | u64 dar; |
1102 | 1191 | ||
@@ -1110,6 +1199,7 @@ program_interrupt: | |||
1110 | } | 1199 | } |
1111 | r = RESUME_GUEST; | 1200 | r = RESUME_GUEST; |
1112 | break; | 1201 | break; |
1202 | } | ||
1113 | #ifdef CONFIG_PPC_BOOK3S_64 | 1203 | #ifdef CONFIG_PPC_BOOK3S_64 |
1114 | case BOOK3S_INTERRUPT_FAC_UNAVAIL: | 1204 | case BOOK3S_INTERRUPT_FAC_UNAVAIL: |
1115 | kvmppc_handle_fac(vcpu, vcpu->arch.shadow_fscr >> 56); | 1205 | kvmppc_handle_fac(vcpu, vcpu->arch.shadow_fscr >> 56); |
@@ -1233,6 +1323,7 @@ static int kvmppc_get_one_reg_pr(struct kvm_vcpu *vcpu, u64 id, | |||
1233 | *val = get_reg_val(id, to_book3s(vcpu)->hior); | 1323 | *val = get_reg_val(id, to_book3s(vcpu)->hior); |
1234 | break; | 1324 | break; |
1235 | case KVM_REG_PPC_LPCR: | 1325 | case KVM_REG_PPC_LPCR: |
1326 | case KVM_REG_PPC_LPCR_64: | ||
1236 | /* | 1327 | /* |
1237 | * We are only interested in the LPCR_ILE bit | 1328 | * We are only interested in the LPCR_ILE bit |
1238 | */ | 1329 | */ |
@@ -1268,6 +1359,7 @@ static int kvmppc_set_one_reg_pr(struct kvm_vcpu *vcpu, u64 id, | |||
1268 | to_book3s(vcpu)->hior_explicit = true; | 1359 | to_book3s(vcpu)->hior_explicit = true; |
1269 | break; | 1360 | break; |
1270 | case KVM_REG_PPC_LPCR: | 1361 | case KVM_REG_PPC_LPCR: |
1362 | case KVM_REG_PPC_LPCR_64: | ||
1271 | kvmppc_set_lpcr_pr(vcpu, set_reg_val(id, *val)); | 1363 | kvmppc_set_lpcr_pr(vcpu, set_reg_val(id, *val)); |
1272 | break; | 1364 | break; |
1273 | default: | 1365 | default: |
@@ -1310,8 +1402,7 @@ static struct kvm_vcpu *kvmppc_core_vcpu_create_pr(struct kvm *kvm, | |||
1310 | p = __get_free_page(GFP_KERNEL|__GFP_ZERO); | 1402 | p = __get_free_page(GFP_KERNEL|__GFP_ZERO); |
1311 | if (!p) | 1403 | if (!p) |
1312 | goto uninit_vcpu; | 1404 | goto uninit_vcpu; |
1313 | /* the real shared page fills the last 4k of our page */ | 1405 | vcpu->arch.shared = (void *)p; |
1314 | vcpu->arch.shared = (void *)(p + PAGE_SIZE - 4096); | ||
1315 | #ifdef CONFIG_PPC_BOOK3S_64 | 1406 | #ifdef CONFIG_PPC_BOOK3S_64 |
1316 | /* Always start the shared struct in native endian mode */ | 1407 | /* Always start the shared struct in native endian mode */ |
1317 | #ifdef __BIG_ENDIAN__ | 1408 | #ifdef __BIG_ENDIAN__ |
@@ -1568,6 +1659,11 @@ static int kvmppc_core_init_vm_pr(struct kvm *kvm) | |||
1568 | { | 1659 | { |
1569 | mutex_init(&kvm->arch.hpt_mutex); | 1660 | mutex_init(&kvm->arch.hpt_mutex); |
1570 | 1661 | ||
1662 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
1663 | /* Start out with the default set of hcalls enabled */ | ||
1664 | kvmppc_pr_init_default_hcalls(kvm); | ||
1665 | #endif | ||
1666 | |||
1571 | if (firmware_has_feature(FW_FEATURE_SET_MODE)) { | 1667 | if (firmware_has_feature(FW_FEATURE_SET_MODE)) { |
1572 | spin_lock(&kvm_global_user_count_lock); | 1668 | spin_lock(&kvm_global_user_count_lock); |
1573 | if (++kvm_global_user_count == 1) | 1669 | if (++kvm_global_user_count == 1) |
@@ -1636,6 +1732,9 @@ static struct kvmppc_ops kvm_ops_pr = { | |||
1636 | .emulate_mfspr = kvmppc_core_emulate_mfspr_pr, | 1732 | .emulate_mfspr = kvmppc_core_emulate_mfspr_pr, |
1637 | .fast_vcpu_kick = kvm_vcpu_kick, | 1733 | .fast_vcpu_kick = kvm_vcpu_kick, |
1638 | .arch_vm_ioctl = kvm_arch_vm_ioctl_pr, | 1734 | .arch_vm_ioctl = kvm_arch_vm_ioctl_pr, |
1735 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
1736 | .hcall_implemented = kvmppc_hcall_impl_pr, | ||
1737 | #endif | ||
1639 | }; | 1738 | }; |
1640 | 1739 | ||
1641 | 1740 | ||
diff --git a/arch/powerpc/kvm/book3s_pr_papr.c b/arch/powerpc/kvm/book3s_pr_papr.c index 52a63bfe3f07..ce3c893d509b 100644 --- a/arch/powerpc/kvm/book3s_pr_papr.c +++ b/arch/powerpc/kvm/book3s_pr_papr.c | |||
@@ -40,8 +40,9 @@ static int kvmppc_h_pr_enter(struct kvm_vcpu *vcpu) | |||
40 | { | 40 | { |
41 | long flags = kvmppc_get_gpr(vcpu, 4); | 41 | long flags = kvmppc_get_gpr(vcpu, 4); |
42 | long pte_index = kvmppc_get_gpr(vcpu, 5); | 42 | long pte_index = kvmppc_get_gpr(vcpu, 5); |
43 | unsigned long pteg[2 * 8]; | 43 | __be64 pteg[2 * 8]; |
44 | unsigned long pteg_addr, i, *hpte; | 44 | __be64 *hpte; |
45 | unsigned long pteg_addr, i; | ||
45 | long int ret; | 46 | long int ret; |
46 | 47 | ||
47 | i = pte_index & 7; | 48 | i = pte_index & 7; |
@@ -93,8 +94,8 @@ static int kvmppc_h_pr_remove(struct kvm_vcpu *vcpu) | |||
93 | pteg = get_pteg_addr(vcpu, pte_index); | 94 | pteg = get_pteg_addr(vcpu, pte_index); |
94 | mutex_lock(&vcpu->kvm->arch.hpt_mutex); | 95 | mutex_lock(&vcpu->kvm->arch.hpt_mutex); |
95 | copy_from_user(pte, (void __user *)pteg, sizeof(pte)); | 96 | copy_from_user(pte, (void __user *)pteg, sizeof(pte)); |
96 | pte[0] = be64_to_cpu(pte[0]); | 97 | pte[0] = be64_to_cpu((__force __be64)pte[0]); |
97 | pte[1] = be64_to_cpu(pte[1]); | 98 | pte[1] = be64_to_cpu((__force __be64)pte[1]); |
98 | 99 | ||
99 | ret = H_NOT_FOUND; | 100 | ret = H_NOT_FOUND; |
100 | if ((pte[0] & HPTE_V_VALID) == 0 || | 101 | if ((pte[0] & HPTE_V_VALID) == 0 || |
@@ -171,8 +172,8 @@ static int kvmppc_h_pr_bulk_remove(struct kvm_vcpu *vcpu) | |||
171 | 172 | ||
172 | pteg = get_pteg_addr(vcpu, tsh & H_BULK_REMOVE_PTEX); | 173 | pteg = get_pteg_addr(vcpu, tsh & H_BULK_REMOVE_PTEX); |
173 | copy_from_user(pte, (void __user *)pteg, sizeof(pte)); | 174 | copy_from_user(pte, (void __user *)pteg, sizeof(pte)); |
174 | pte[0] = be64_to_cpu(pte[0]); | 175 | pte[0] = be64_to_cpu((__force __be64)pte[0]); |
175 | pte[1] = be64_to_cpu(pte[1]); | 176 | pte[1] = be64_to_cpu((__force __be64)pte[1]); |
176 | 177 | ||
177 | /* tsl = AVPN */ | 178 | /* tsl = AVPN */ |
178 | flags = (tsh & H_BULK_REMOVE_FLAGS) >> 26; | 179 | flags = (tsh & H_BULK_REMOVE_FLAGS) >> 26; |
@@ -211,8 +212,8 @@ static int kvmppc_h_pr_protect(struct kvm_vcpu *vcpu) | |||
211 | pteg = get_pteg_addr(vcpu, pte_index); | 212 | pteg = get_pteg_addr(vcpu, pte_index); |
212 | mutex_lock(&vcpu->kvm->arch.hpt_mutex); | 213 | mutex_lock(&vcpu->kvm->arch.hpt_mutex); |
213 | copy_from_user(pte, (void __user *)pteg, sizeof(pte)); | 214 | copy_from_user(pte, (void __user *)pteg, sizeof(pte)); |
214 | pte[0] = be64_to_cpu(pte[0]); | 215 | pte[0] = be64_to_cpu((__force __be64)pte[0]); |
215 | pte[1] = be64_to_cpu(pte[1]); | 216 | pte[1] = be64_to_cpu((__force __be64)pte[1]); |
216 | 217 | ||
217 | ret = H_NOT_FOUND; | 218 | ret = H_NOT_FOUND; |
218 | if ((pte[0] & HPTE_V_VALID) == 0 || | 219 | if ((pte[0] & HPTE_V_VALID) == 0 || |
@@ -231,8 +232,8 @@ static int kvmppc_h_pr_protect(struct kvm_vcpu *vcpu) | |||
231 | 232 | ||
232 | rb = compute_tlbie_rb(v, r, pte_index); | 233 | rb = compute_tlbie_rb(v, r, pte_index); |
233 | vcpu->arch.mmu.tlbie(vcpu, rb, rb & 1 ? true : false); | 234 | vcpu->arch.mmu.tlbie(vcpu, rb, rb & 1 ? true : false); |
234 | pte[0] = cpu_to_be64(pte[0]); | 235 | pte[0] = (__force u64)cpu_to_be64(pte[0]); |
235 | pte[1] = cpu_to_be64(pte[1]); | 236 | pte[1] = (__force u64)cpu_to_be64(pte[1]); |
236 | copy_to_user((void __user *)pteg, pte, sizeof(pte)); | 237 | copy_to_user((void __user *)pteg, pte, sizeof(pte)); |
237 | ret = H_SUCCESS; | 238 | ret = H_SUCCESS; |
238 | 239 | ||
@@ -266,6 +267,12 @@ static int kvmppc_h_pr_xics_hcall(struct kvm_vcpu *vcpu, u32 cmd) | |||
266 | 267 | ||
267 | int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd) | 268 | int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd) |
268 | { | 269 | { |
270 | int rc, idx; | ||
271 | |||
272 | if (cmd <= MAX_HCALL_OPCODE && | ||
273 | !test_bit(cmd/4, vcpu->kvm->arch.enabled_hcalls)) | ||
274 | return EMULATE_FAIL; | ||
275 | |||
269 | switch (cmd) { | 276 | switch (cmd) { |
270 | case H_ENTER: | 277 | case H_ENTER: |
271 | return kvmppc_h_pr_enter(vcpu); | 278 | return kvmppc_h_pr_enter(vcpu); |
@@ -294,8 +301,11 @@ int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd) | |||
294 | break; | 301 | break; |
295 | case H_RTAS: | 302 | case H_RTAS: |
296 | if (list_empty(&vcpu->kvm->arch.rtas_tokens)) | 303 | if (list_empty(&vcpu->kvm->arch.rtas_tokens)) |
297 | return RESUME_HOST; | 304 | break; |
298 | if (kvmppc_rtas_hcall(vcpu)) | 305 | idx = srcu_read_lock(&vcpu->kvm->srcu); |
306 | rc = kvmppc_rtas_hcall(vcpu); | ||
307 | srcu_read_unlock(&vcpu->kvm->srcu, idx); | ||
308 | if (rc) | ||
299 | break; | 309 | break; |
300 | kvmppc_set_gpr(vcpu, 3, 0); | 310 | kvmppc_set_gpr(vcpu, 3, 0); |
301 | return EMULATE_DONE; | 311 | return EMULATE_DONE; |
@@ -303,3 +313,61 @@ int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd) | |||
303 | 313 | ||
304 | return EMULATE_FAIL; | 314 | return EMULATE_FAIL; |
305 | } | 315 | } |
316 | |||
317 | int kvmppc_hcall_impl_pr(unsigned long cmd) | ||
318 | { | ||
319 | switch (cmd) { | ||
320 | case H_ENTER: | ||
321 | case H_REMOVE: | ||
322 | case H_PROTECT: | ||
323 | case H_BULK_REMOVE: | ||
324 | case H_PUT_TCE: | ||
325 | case H_CEDE: | ||
326 | #ifdef CONFIG_KVM_XICS | ||
327 | case H_XIRR: | ||
328 | case H_CPPR: | ||
329 | case H_EOI: | ||
330 | case H_IPI: | ||
331 | case H_IPOLL: | ||
332 | case H_XIRR_X: | ||
333 | #endif | ||
334 | return 1; | ||
335 | } | ||
336 | return 0; | ||
337 | } | ||
338 | |||
339 | /* | ||
340 | * List of hcall numbers to enable by default. | ||
341 | * For compatibility with old userspace, we enable by default | ||
342 | * all hcalls that were implemented before the hcall-enabling | ||
343 | * facility was added. Note this list should not include H_RTAS. | ||
344 | */ | ||
345 | static unsigned int default_hcall_list[] = { | ||
346 | H_ENTER, | ||
347 | H_REMOVE, | ||
348 | H_PROTECT, | ||
349 | H_BULK_REMOVE, | ||
350 | H_PUT_TCE, | ||
351 | H_CEDE, | ||
352 | #ifdef CONFIG_KVM_XICS | ||
353 | H_XIRR, | ||
354 | H_CPPR, | ||
355 | H_EOI, | ||
356 | H_IPI, | ||
357 | H_IPOLL, | ||
358 | H_XIRR_X, | ||
359 | #endif | ||
360 | 0 | ||
361 | }; | ||
362 | |||
363 | void kvmppc_pr_init_default_hcalls(struct kvm *kvm) | ||
364 | { | ||
365 | int i; | ||
366 | unsigned int hcall; | ||
367 | |||
368 | for (i = 0; default_hcall_list[i]; ++i) { | ||
369 | hcall = default_hcall_list[i]; | ||
370 | WARN_ON(!kvmppc_hcall_impl_pr(hcall)); | ||
371 | __set_bit(hcall / 4, kvm->arch.enabled_hcalls); | ||
372 | } | ||
373 | } | ||
diff --git a/arch/powerpc/kvm/book3s_xics.c b/arch/powerpc/kvm/book3s_xics.c index d1acd32a64c0..eaeb78047fb8 100644 --- a/arch/powerpc/kvm/book3s_xics.c +++ b/arch/powerpc/kvm/book3s_xics.c | |||
@@ -64,8 +64,12 @@ | |||
64 | static void icp_deliver_irq(struct kvmppc_xics *xics, struct kvmppc_icp *icp, | 64 | static void icp_deliver_irq(struct kvmppc_xics *xics, struct kvmppc_icp *icp, |
65 | u32 new_irq); | 65 | u32 new_irq); |
66 | 66 | ||
67 | static int ics_deliver_irq(struct kvmppc_xics *xics, u32 irq, u32 level, | 67 | /* |
68 | bool report_status) | 68 | * Return value ideally indicates how the interrupt was handled, but no |
69 | * callers look at it (given that we don't implement KVM_IRQ_LINE_STATUS), | ||
70 | * so just return 0. | ||
71 | */ | ||
72 | static int ics_deliver_irq(struct kvmppc_xics *xics, u32 irq, u32 level) | ||
69 | { | 73 | { |
70 | struct ics_irq_state *state; | 74 | struct ics_irq_state *state; |
71 | struct kvmppc_ics *ics; | 75 | struct kvmppc_ics *ics; |
@@ -82,17 +86,14 @@ static int ics_deliver_irq(struct kvmppc_xics *xics, u32 irq, u32 level, | |||
82 | if (!state->exists) | 86 | if (!state->exists) |
83 | return -EINVAL; | 87 | return -EINVAL; |
84 | 88 | ||
85 | if (report_status) | ||
86 | return state->asserted; | ||
87 | |||
88 | /* | 89 | /* |
89 | * We set state->asserted locklessly. This should be fine as | 90 | * We set state->asserted locklessly. This should be fine as |
90 | * we are the only setter, thus concurrent access is undefined | 91 | * we are the only setter, thus concurrent access is undefined |
91 | * to begin with. | 92 | * to begin with. |
92 | */ | 93 | */ |
93 | if (level == KVM_INTERRUPT_SET_LEVEL) | 94 | if (level == 1 || level == KVM_INTERRUPT_SET_LEVEL) |
94 | state->asserted = 1; | 95 | state->asserted = 1; |
95 | else if (level == KVM_INTERRUPT_UNSET) { | 96 | else if (level == 0 || level == KVM_INTERRUPT_UNSET) { |
96 | state->asserted = 0; | 97 | state->asserted = 0; |
97 | return 0; | 98 | return 0; |
98 | } | 99 | } |
@@ -100,7 +101,7 @@ static int ics_deliver_irq(struct kvmppc_xics *xics, u32 irq, u32 level, | |||
100 | /* Attempt delivery */ | 101 | /* Attempt delivery */ |
101 | icp_deliver_irq(xics, NULL, irq); | 102 | icp_deliver_irq(xics, NULL, irq); |
102 | 103 | ||
103 | return state->asserted; | 104 | return 0; |
104 | } | 105 | } |
105 | 106 | ||
106 | static void ics_check_resend(struct kvmppc_xics *xics, struct kvmppc_ics *ics, | 107 | static void ics_check_resend(struct kvmppc_xics *xics, struct kvmppc_ics *ics, |
@@ -772,6 +773,8 @@ static noinline int kvmppc_h_eoi(struct kvm_vcpu *vcpu, unsigned long xirr) | |||
772 | if (state->asserted) | 773 | if (state->asserted) |
773 | icp_deliver_irq(xics, icp, irq); | 774 | icp_deliver_irq(xics, icp, irq); |
774 | 775 | ||
776 | kvm_notify_acked_irq(vcpu->kvm, 0, irq); | ||
777 | |||
775 | return H_SUCCESS; | 778 | return H_SUCCESS; |
776 | } | 779 | } |
777 | 780 | ||
@@ -789,6 +792,8 @@ static noinline int kvmppc_xics_rm_complete(struct kvm_vcpu *vcpu, u32 hcall) | |||
789 | icp_check_resend(xics, icp); | 792 | icp_check_resend(xics, icp); |
790 | if (icp->rm_action & XICS_RM_REJECT) | 793 | if (icp->rm_action & XICS_RM_REJECT) |
791 | icp_deliver_irq(xics, icp, icp->rm_reject); | 794 | icp_deliver_irq(xics, icp, icp->rm_reject); |
795 | if (icp->rm_action & XICS_RM_NOTIFY_EOI) | ||
796 | kvm_notify_acked_irq(vcpu->kvm, 0, icp->rm_eoied_irq); | ||
792 | 797 | ||
793 | icp->rm_action = 0; | 798 | icp->rm_action = 0; |
794 | 799 | ||
@@ -1170,7 +1175,16 @@ int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level, | |||
1170 | { | 1175 | { |
1171 | struct kvmppc_xics *xics = kvm->arch.xics; | 1176 | struct kvmppc_xics *xics = kvm->arch.xics; |
1172 | 1177 | ||
1173 | return ics_deliver_irq(xics, irq, level, line_status); | 1178 | return ics_deliver_irq(xics, irq, level); |
1179 | } | ||
1180 | |||
1181 | int kvm_set_msi(struct kvm_kernel_irq_routing_entry *irq_entry, struct kvm *kvm, | ||
1182 | int irq_source_id, int level, bool line_status) | ||
1183 | { | ||
1184 | if (!level) | ||
1185 | return -1; | ||
1186 | return kvm_set_irq(kvm, irq_source_id, irq_entry->gsi, | ||
1187 | level, line_status); | ||
1174 | } | 1188 | } |
1175 | 1189 | ||
1176 | static int xics_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr) | 1190 | static int xics_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr) |
@@ -1301,3 +1315,26 @@ void kvmppc_xics_free_icp(struct kvm_vcpu *vcpu) | |||
1301 | vcpu->arch.icp = NULL; | 1315 | vcpu->arch.icp = NULL; |
1302 | vcpu->arch.irq_type = KVMPPC_IRQ_DEFAULT; | 1316 | vcpu->arch.irq_type = KVMPPC_IRQ_DEFAULT; |
1303 | } | 1317 | } |
1318 | |||
1319 | static int xics_set_irq(struct kvm_kernel_irq_routing_entry *e, | ||
1320 | struct kvm *kvm, int irq_source_id, int level, | ||
1321 | bool line_status) | ||
1322 | { | ||
1323 | return kvm_set_irq(kvm, irq_source_id, e->gsi, level, line_status); | ||
1324 | } | ||
1325 | |||
1326 | int kvm_irq_map_gsi(struct kvm *kvm, | ||
1327 | struct kvm_kernel_irq_routing_entry *entries, int gsi) | ||
1328 | { | ||
1329 | entries->gsi = gsi; | ||
1330 | entries->type = KVM_IRQ_ROUTING_IRQCHIP; | ||
1331 | entries->set = xics_set_irq; | ||
1332 | entries->irqchip.irqchip = 0; | ||
1333 | entries->irqchip.pin = gsi; | ||
1334 | return 1; | ||
1335 | } | ||
1336 | |||
1337 | int kvm_irq_map_chip_pin(struct kvm *kvm, unsigned irqchip, unsigned pin) | ||
1338 | { | ||
1339 | return pin; | ||
1340 | } | ||
diff --git a/arch/powerpc/kvm/book3s_xics.h b/arch/powerpc/kvm/book3s_xics.h index dd9326c5c19b..e8aaa7a3f209 100644 --- a/arch/powerpc/kvm/book3s_xics.h +++ b/arch/powerpc/kvm/book3s_xics.h | |||
@@ -71,9 +71,11 @@ struct kvmppc_icp { | |||
71 | #define XICS_RM_KICK_VCPU 0x1 | 71 | #define XICS_RM_KICK_VCPU 0x1 |
72 | #define XICS_RM_CHECK_RESEND 0x2 | 72 | #define XICS_RM_CHECK_RESEND 0x2 |
73 | #define XICS_RM_REJECT 0x4 | 73 | #define XICS_RM_REJECT 0x4 |
74 | #define XICS_RM_NOTIFY_EOI 0x8 | ||
74 | u32 rm_action; | 75 | u32 rm_action; |
75 | struct kvm_vcpu *rm_kick_target; | 76 | struct kvm_vcpu *rm_kick_target; |
76 | u32 rm_reject; | 77 | u32 rm_reject; |
78 | u32 rm_eoied_irq; | ||
77 | 79 | ||
78 | /* Debug stuff for real mode */ | 80 | /* Debug stuff for real mode */ |
79 | union kvmppc_icp_state rm_dbgstate; | 81 | union kvmppc_icp_state rm_dbgstate; |
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index ab62109fdfa3..b4c89fa6f109 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c | |||
@@ -51,7 +51,6 @@ unsigned long kvmppc_booke_handlers; | |||
51 | 51 | ||
52 | struct kvm_stats_debugfs_item debugfs_entries[] = { | 52 | struct kvm_stats_debugfs_item debugfs_entries[] = { |
53 | { "mmio", VCPU_STAT(mmio_exits) }, | 53 | { "mmio", VCPU_STAT(mmio_exits) }, |
54 | { "dcr", VCPU_STAT(dcr_exits) }, | ||
55 | { "sig", VCPU_STAT(signal_exits) }, | 54 | { "sig", VCPU_STAT(signal_exits) }, |
56 | { "itlb_r", VCPU_STAT(itlb_real_miss_exits) }, | 55 | { "itlb_r", VCPU_STAT(itlb_real_miss_exits) }, |
57 | { "itlb_v", VCPU_STAT(itlb_virt_miss_exits) }, | 56 | { "itlb_v", VCPU_STAT(itlb_virt_miss_exits) }, |
@@ -185,24 +184,28 @@ static void kvmppc_booke_queue_irqprio(struct kvm_vcpu *vcpu, | |||
185 | set_bit(priority, &vcpu->arch.pending_exceptions); | 184 | set_bit(priority, &vcpu->arch.pending_exceptions); |
186 | } | 185 | } |
187 | 186 | ||
188 | static void kvmppc_core_queue_dtlb_miss(struct kvm_vcpu *vcpu, | 187 | void kvmppc_core_queue_dtlb_miss(struct kvm_vcpu *vcpu, |
189 | ulong dear_flags, ulong esr_flags) | 188 | ulong dear_flags, ulong esr_flags) |
190 | { | 189 | { |
191 | vcpu->arch.queued_dear = dear_flags; | 190 | vcpu->arch.queued_dear = dear_flags; |
192 | vcpu->arch.queued_esr = esr_flags; | 191 | vcpu->arch.queued_esr = esr_flags; |
193 | kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DTLB_MISS); | 192 | kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DTLB_MISS); |
194 | } | 193 | } |
195 | 194 | ||
196 | static void kvmppc_core_queue_data_storage(struct kvm_vcpu *vcpu, | 195 | void kvmppc_core_queue_data_storage(struct kvm_vcpu *vcpu, |
197 | ulong dear_flags, ulong esr_flags) | 196 | ulong dear_flags, ulong esr_flags) |
198 | { | 197 | { |
199 | vcpu->arch.queued_dear = dear_flags; | 198 | vcpu->arch.queued_dear = dear_flags; |
200 | vcpu->arch.queued_esr = esr_flags; | 199 | vcpu->arch.queued_esr = esr_flags; |
201 | kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DATA_STORAGE); | 200 | kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DATA_STORAGE); |
202 | } | 201 | } |
203 | 202 | ||
204 | static void kvmppc_core_queue_inst_storage(struct kvm_vcpu *vcpu, | 203 | void kvmppc_core_queue_itlb_miss(struct kvm_vcpu *vcpu) |
205 | ulong esr_flags) | 204 | { |
205 | kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_ITLB_MISS); | ||
206 | } | ||
207 | |||
208 | void kvmppc_core_queue_inst_storage(struct kvm_vcpu *vcpu, ulong esr_flags) | ||
206 | { | 209 | { |
207 | vcpu->arch.queued_esr = esr_flags; | 210 | vcpu->arch.queued_esr = esr_flags; |
208 | kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_INST_STORAGE); | 211 | kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_INST_STORAGE); |
@@ -266,13 +269,8 @@ static void kvmppc_core_dequeue_watchdog(struct kvm_vcpu *vcpu) | |||
266 | 269 | ||
267 | static void set_guest_srr(struct kvm_vcpu *vcpu, unsigned long srr0, u32 srr1) | 270 | static void set_guest_srr(struct kvm_vcpu *vcpu, unsigned long srr0, u32 srr1) |
268 | { | 271 | { |
269 | #ifdef CONFIG_KVM_BOOKE_HV | 272 | kvmppc_set_srr0(vcpu, srr0); |
270 | mtspr(SPRN_GSRR0, srr0); | 273 | kvmppc_set_srr1(vcpu, srr1); |
271 | mtspr(SPRN_GSRR1, srr1); | ||
272 | #else | ||
273 | vcpu->arch.shared->srr0 = srr0; | ||
274 | vcpu->arch.shared->srr1 = srr1; | ||
275 | #endif | ||
276 | } | 274 | } |
277 | 275 | ||
278 | static void set_guest_csrr(struct kvm_vcpu *vcpu, unsigned long srr0, u32 srr1) | 276 | static void set_guest_csrr(struct kvm_vcpu *vcpu, unsigned long srr0, u32 srr1) |
@@ -297,51 +295,6 @@ static void set_guest_mcsrr(struct kvm_vcpu *vcpu, unsigned long srr0, u32 srr1) | |||
297 | vcpu->arch.mcsrr1 = srr1; | 295 | vcpu->arch.mcsrr1 = srr1; |
298 | } | 296 | } |
299 | 297 | ||
300 | static unsigned long get_guest_dear(struct kvm_vcpu *vcpu) | ||
301 | { | ||
302 | #ifdef CONFIG_KVM_BOOKE_HV | ||
303 | return mfspr(SPRN_GDEAR); | ||
304 | #else | ||
305 | return vcpu->arch.shared->dar; | ||
306 | #endif | ||
307 | } | ||
308 | |||
309 | static void set_guest_dear(struct kvm_vcpu *vcpu, unsigned long dear) | ||
310 | { | ||
311 | #ifdef CONFIG_KVM_BOOKE_HV | ||
312 | mtspr(SPRN_GDEAR, dear); | ||
313 | #else | ||
314 | vcpu->arch.shared->dar = dear; | ||
315 | #endif | ||
316 | } | ||
317 | |||
318 | static unsigned long get_guest_esr(struct kvm_vcpu *vcpu) | ||
319 | { | ||
320 | #ifdef CONFIG_KVM_BOOKE_HV | ||
321 | return mfspr(SPRN_GESR); | ||
322 | #else | ||
323 | return vcpu->arch.shared->esr; | ||
324 | #endif | ||
325 | } | ||
326 | |||
327 | static void set_guest_esr(struct kvm_vcpu *vcpu, u32 esr) | ||
328 | { | ||
329 | #ifdef CONFIG_KVM_BOOKE_HV | ||
330 | mtspr(SPRN_GESR, esr); | ||
331 | #else | ||
332 | vcpu->arch.shared->esr = esr; | ||
333 | #endif | ||
334 | } | ||
335 | |||
336 | static unsigned long get_guest_epr(struct kvm_vcpu *vcpu) | ||
337 | { | ||
338 | #ifdef CONFIG_KVM_BOOKE_HV | ||
339 | return mfspr(SPRN_GEPR); | ||
340 | #else | ||
341 | return vcpu->arch.epr; | ||
342 | #endif | ||
343 | } | ||
344 | |||
345 | /* Deliver the interrupt of the corresponding priority, if possible. */ | 298 | /* Deliver the interrupt of the corresponding priority, if possible. */ |
346 | static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu, | 299 | static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu, |
347 | unsigned int priority) | 300 | unsigned int priority) |
@@ -450,9 +403,9 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu, | |||
450 | 403 | ||
451 | vcpu->arch.pc = vcpu->arch.ivpr | vcpu->arch.ivor[priority]; | 404 | vcpu->arch.pc = vcpu->arch.ivpr | vcpu->arch.ivor[priority]; |
452 | if (update_esr == true) | 405 | if (update_esr == true) |
453 | set_guest_esr(vcpu, vcpu->arch.queued_esr); | 406 | kvmppc_set_esr(vcpu, vcpu->arch.queued_esr); |
454 | if (update_dear == true) | 407 | if (update_dear == true) |
455 | set_guest_dear(vcpu, vcpu->arch.queued_dear); | 408 | kvmppc_set_dar(vcpu, vcpu->arch.queued_dear); |
456 | if (update_epr == true) { | 409 | if (update_epr == true) { |
457 | if (vcpu->arch.epr_flags & KVMPPC_EPR_USER) | 410 | if (vcpu->arch.epr_flags & KVMPPC_EPR_USER) |
458 | kvm_make_request(KVM_REQ_EPR_EXIT, vcpu); | 411 | kvm_make_request(KVM_REQ_EPR_EXIT, vcpu); |
@@ -752,9 +705,8 @@ static int emulation_exit(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
752 | * they were actually modified by emulation. */ | 705 | * they were actually modified by emulation. */ |
753 | return RESUME_GUEST_NV; | 706 | return RESUME_GUEST_NV; |
754 | 707 | ||
755 | case EMULATE_DO_DCR: | 708 | case EMULATE_AGAIN: |
756 | run->exit_reason = KVM_EXIT_DCR; | 709 | return RESUME_GUEST; |
757 | return RESUME_HOST; | ||
758 | 710 | ||
759 | case EMULATE_FAIL: | 711 | case EMULATE_FAIL: |
760 | printk(KERN_CRIT "%s: emulation at %lx failed (%08x)\n", | 712 | printk(KERN_CRIT "%s: emulation at %lx failed (%08x)\n", |
@@ -866,6 +818,28 @@ static void kvmppc_restart_interrupt(struct kvm_vcpu *vcpu, | |||
866 | } | 818 | } |
867 | } | 819 | } |
868 | 820 | ||
821 | static int kvmppc_resume_inst_load(struct kvm_run *run, struct kvm_vcpu *vcpu, | ||
822 | enum emulation_result emulated, u32 last_inst) | ||
823 | { | ||
824 | switch (emulated) { | ||
825 | case EMULATE_AGAIN: | ||
826 | return RESUME_GUEST; | ||
827 | |||
828 | case EMULATE_FAIL: | ||
829 | pr_debug("%s: load instruction from guest address %lx failed\n", | ||
830 | __func__, vcpu->arch.pc); | ||
831 | /* For debugging, encode the failing instruction and | ||
832 | * report it to userspace. */ | ||
833 | run->hw.hardware_exit_reason = ~0ULL << 32; | ||
834 | run->hw.hardware_exit_reason |= last_inst; | ||
835 | kvmppc_core_queue_program(vcpu, ESR_PIL); | ||
836 | return RESUME_HOST; | ||
837 | |||
838 | default: | ||
839 | BUG(); | ||
840 | } | ||
841 | } | ||
842 | |||
869 | /** | 843 | /** |
870 | * kvmppc_handle_exit | 844 | * kvmppc_handle_exit |
871 | * | 845 | * |
@@ -877,6 +851,8 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
877 | int r = RESUME_HOST; | 851 | int r = RESUME_HOST; |
878 | int s; | 852 | int s; |
879 | int idx; | 853 | int idx; |
854 | u32 last_inst = KVM_INST_FETCH_FAILED; | ||
855 | enum emulation_result emulated = EMULATE_DONE; | ||
880 | 856 | ||
881 | /* update before a new last_exit_type is rewritten */ | 857 | /* update before a new last_exit_type is rewritten */ |
882 | kvmppc_update_timing_stats(vcpu); | 858 | kvmppc_update_timing_stats(vcpu); |
@@ -884,6 +860,20 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
884 | /* restart interrupts if they were meant for the host */ | 860 | /* restart interrupts if they were meant for the host */ |
885 | kvmppc_restart_interrupt(vcpu, exit_nr); | 861 | kvmppc_restart_interrupt(vcpu, exit_nr); |
886 | 862 | ||
863 | /* | ||
864 | * get last instruction before beeing preempted | ||
865 | * TODO: for e6500 check also BOOKE_INTERRUPT_LRAT_ERROR & ESR_DATA | ||
866 | */ | ||
867 | switch (exit_nr) { | ||
868 | case BOOKE_INTERRUPT_DATA_STORAGE: | ||
869 | case BOOKE_INTERRUPT_DTLB_MISS: | ||
870 | case BOOKE_INTERRUPT_HV_PRIV: | ||
871 | emulated = kvmppc_get_last_inst(vcpu, false, &last_inst); | ||
872 | break; | ||
873 | default: | ||
874 | break; | ||
875 | } | ||
876 | |||
887 | local_irq_enable(); | 877 | local_irq_enable(); |
888 | 878 | ||
889 | trace_kvm_exit(exit_nr, vcpu); | 879 | trace_kvm_exit(exit_nr, vcpu); |
@@ -892,6 +882,11 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
892 | run->exit_reason = KVM_EXIT_UNKNOWN; | 882 | run->exit_reason = KVM_EXIT_UNKNOWN; |
893 | run->ready_for_interrupt_injection = 1; | 883 | run->ready_for_interrupt_injection = 1; |
894 | 884 | ||
885 | if (emulated != EMULATE_DONE) { | ||
886 | r = kvmppc_resume_inst_load(run, vcpu, emulated, last_inst); | ||
887 | goto out; | ||
888 | } | ||
889 | |||
895 | switch (exit_nr) { | 890 | switch (exit_nr) { |
896 | case BOOKE_INTERRUPT_MACHINE_CHECK: | 891 | case BOOKE_INTERRUPT_MACHINE_CHECK: |
897 | printk("MACHINE CHECK: %lx\n", mfspr(SPRN_MCSR)); | 892 | printk("MACHINE CHECK: %lx\n", mfspr(SPRN_MCSR)); |
@@ -1181,6 +1176,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
1181 | BUG(); | 1176 | BUG(); |
1182 | } | 1177 | } |
1183 | 1178 | ||
1179 | out: | ||
1184 | /* | 1180 | /* |
1185 | * To avoid clobbering exit_reason, only check for signals if we | 1181 | * To avoid clobbering exit_reason, only check for signals if we |
1186 | * aren't already exiting to userspace for some other reason. | 1182 | * aren't already exiting to userspace for some other reason. |
@@ -1265,17 +1261,17 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | |||
1265 | regs->lr = vcpu->arch.lr; | 1261 | regs->lr = vcpu->arch.lr; |
1266 | regs->xer = kvmppc_get_xer(vcpu); | 1262 | regs->xer = kvmppc_get_xer(vcpu); |
1267 | regs->msr = vcpu->arch.shared->msr; | 1263 | regs->msr = vcpu->arch.shared->msr; |
1268 | regs->srr0 = vcpu->arch.shared->srr0; | 1264 | regs->srr0 = kvmppc_get_srr0(vcpu); |
1269 | regs->srr1 = vcpu->arch.shared->srr1; | 1265 | regs->srr1 = kvmppc_get_srr1(vcpu); |
1270 | regs->pid = vcpu->arch.pid; | 1266 | regs->pid = vcpu->arch.pid; |
1271 | regs->sprg0 = vcpu->arch.shared->sprg0; | 1267 | regs->sprg0 = kvmppc_get_sprg0(vcpu); |
1272 | regs->sprg1 = vcpu->arch.shared->sprg1; | 1268 | regs->sprg1 = kvmppc_get_sprg1(vcpu); |
1273 | regs->sprg2 = vcpu->arch.shared->sprg2; | 1269 | regs->sprg2 = kvmppc_get_sprg2(vcpu); |
1274 | regs->sprg3 = vcpu->arch.shared->sprg3; | 1270 | regs->sprg3 = kvmppc_get_sprg3(vcpu); |
1275 | regs->sprg4 = vcpu->arch.shared->sprg4; | 1271 | regs->sprg4 = kvmppc_get_sprg4(vcpu); |
1276 | regs->sprg5 = vcpu->arch.shared->sprg5; | 1272 | regs->sprg5 = kvmppc_get_sprg5(vcpu); |
1277 | regs->sprg6 = vcpu->arch.shared->sprg6; | 1273 | regs->sprg6 = kvmppc_get_sprg6(vcpu); |
1278 | regs->sprg7 = vcpu->arch.shared->sprg7; | 1274 | regs->sprg7 = kvmppc_get_sprg7(vcpu); |
1279 | 1275 | ||
1280 | for (i = 0; i < ARRAY_SIZE(regs->gpr); i++) | 1276 | for (i = 0; i < ARRAY_SIZE(regs->gpr); i++) |
1281 | regs->gpr[i] = kvmppc_get_gpr(vcpu, i); | 1277 | regs->gpr[i] = kvmppc_get_gpr(vcpu, i); |
@@ -1293,17 +1289,17 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | |||
1293 | vcpu->arch.lr = regs->lr; | 1289 | vcpu->arch.lr = regs->lr; |
1294 | kvmppc_set_xer(vcpu, regs->xer); | 1290 | kvmppc_set_xer(vcpu, regs->xer); |
1295 | kvmppc_set_msr(vcpu, regs->msr); | 1291 | kvmppc_set_msr(vcpu, regs->msr); |
1296 | vcpu->arch.shared->srr0 = regs->srr0; | 1292 | kvmppc_set_srr0(vcpu, regs->srr0); |
1297 | vcpu->arch.shared->srr1 = regs->srr1; | 1293 | kvmppc_set_srr1(vcpu, regs->srr1); |
1298 | kvmppc_set_pid(vcpu, regs->pid); | 1294 | kvmppc_set_pid(vcpu, regs->pid); |
1299 | vcpu->arch.shared->sprg0 = regs->sprg0; | 1295 | kvmppc_set_sprg0(vcpu, regs->sprg0); |
1300 | vcpu->arch.shared->sprg1 = regs->sprg1; | 1296 | kvmppc_set_sprg1(vcpu, regs->sprg1); |
1301 | vcpu->arch.shared->sprg2 = regs->sprg2; | 1297 | kvmppc_set_sprg2(vcpu, regs->sprg2); |
1302 | vcpu->arch.shared->sprg3 = regs->sprg3; | 1298 | kvmppc_set_sprg3(vcpu, regs->sprg3); |
1303 | vcpu->arch.shared->sprg4 = regs->sprg4; | 1299 | kvmppc_set_sprg4(vcpu, regs->sprg4); |
1304 | vcpu->arch.shared->sprg5 = regs->sprg5; | 1300 | kvmppc_set_sprg5(vcpu, regs->sprg5); |
1305 | vcpu->arch.shared->sprg6 = regs->sprg6; | 1301 | kvmppc_set_sprg6(vcpu, regs->sprg6); |
1306 | vcpu->arch.shared->sprg7 = regs->sprg7; | 1302 | kvmppc_set_sprg7(vcpu, regs->sprg7); |
1307 | 1303 | ||
1308 | for (i = 0; i < ARRAY_SIZE(regs->gpr); i++) | 1304 | for (i = 0; i < ARRAY_SIZE(regs->gpr); i++) |
1309 | kvmppc_set_gpr(vcpu, i, regs->gpr[i]); | 1305 | kvmppc_set_gpr(vcpu, i, regs->gpr[i]); |
@@ -1321,8 +1317,8 @@ static void get_sregs_base(struct kvm_vcpu *vcpu, | |||
1321 | sregs->u.e.csrr0 = vcpu->arch.csrr0; | 1317 | sregs->u.e.csrr0 = vcpu->arch.csrr0; |
1322 | sregs->u.e.csrr1 = vcpu->arch.csrr1; | 1318 | sregs->u.e.csrr1 = vcpu->arch.csrr1; |
1323 | sregs->u.e.mcsr = vcpu->arch.mcsr; | 1319 | sregs->u.e.mcsr = vcpu->arch.mcsr; |
1324 | sregs->u.e.esr = get_guest_esr(vcpu); | 1320 | sregs->u.e.esr = kvmppc_get_esr(vcpu); |
1325 | sregs->u.e.dear = get_guest_dear(vcpu); | 1321 | sregs->u.e.dear = kvmppc_get_dar(vcpu); |
1326 | sregs->u.e.tsr = vcpu->arch.tsr; | 1322 | sregs->u.e.tsr = vcpu->arch.tsr; |
1327 | sregs->u.e.tcr = vcpu->arch.tcr; | 1323 | sregs->u.e.tcr = vcpu->arch.tcr; |
1328 | sregs->u.e.dec = kvmppc_get_dec(vcpu, tb); | 1324 | sregs->u.e.dec = kvmppc_get_dec(vcpu, tb); |
@@ -1339,8 +1335,8 @@ static int set_sregs_base(struct kvm_vcpu *vcpu, | |||
1339 | vcpu->arch.csrr0 = sregs->u.e.csrr0; | 1335 | vcpu->arch.csrr0 = sregs->u.e.csrr0; |
1340 | vcpu->arch.csrr1 = sregs->u.e.csrr1; | 1336 | vcpu->arch.csrr1 = sregs->u.e.csrr1; |
1341 | vcpu->arch.mcsr = sregs->u.e.mcsr; | 1337 | vcpu->arch.mcsr = sregs->u.e.mcsr; |
1342 | set_guest_esr(vcpu, sregs->u.e.esr); | 1338 | kvmppc_set_esr(vcpu, sregs->u.e.esr); |
1343 | set_guest_dear(vcpu, sregs->u.e.dear); | 1339 | kvmppc_set_dar(vcpu, sregs->u.e.dear); |
1344 | vcpu->arch.vrsave = sregs->u.e.vrsave; | 1340 | vcpu->arch.vrsave = sregs->u.e.vrsave; |
1345 | kvmppc_set_tcr(vcpu, sregs->u.e.tcr); | 1341 | kvmppc_set_tcr(vcpu, sregs->u.e.tcr); |
1346 | 1342 | ||
@@ -1493,7 +1489,7 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) | |||
1493 | val = get_reg_val(reg->id, vcpu->arch.dbg_reg.dac2); | 1489 | val = get_reg_val(reg->id, vcpu->arch.dbg_reg.dac2); |
1494 | break; | 1490 | break; |
1495 | case KVM_REG_PPC_EPR: { | 1491 | case KVM_REG_PPC_EPR: { |
1496 | u32 epr = get_guest_epr(vcpu); | 1492 | u32 epr = kvmppc_get_epr(vcpu); |
1497 | val = get_reg_val(reg->id, epr); | 1493 | val = get_reg_val(reg->id, epr); |
1498 | break; | 1494 | break; |
1499 | } | 1495 | } |
@@ -1788,6 +1784,57 @@ void kvm_guest_protect_msr(struct kvm_vcpu *vcpu, ulong prot_bitmap, bool set) | |||
1788 | #endif | 1784 | #endif |
1789 | } | 1785 | } |
1790 | 1786 | ||
1787 | int kvmppc_xlate(struct kvm_vcpu *vcpu, ulong eaddr, enum xlate_instdata xlid, | ||
1788 | enum xlate_readwrite xlrw, struct kvmppc_pte *pte) | ||
1789 | { | ||
1790 | int gtlb_index; | ||
1791 | gpa_t gpaddr; | ||
1792 | |||
1793 | #ifdef CONFIG_KVM_E500V2 | ||
1794 | if (!(vcpu->arch.shared->msr & MSR_PR) && | ||
1795 | (eaddr & PAGE_MASK) == vcpu->arch.magic_page_ea) { | ||
1796 | pte->eaddr = eaddr; | ||
1797 | pte->raddr = (vcpu->arch.magic_page_pa & PAGE_MASK) | | ||
1798 | (eaddr & ~PAGE_MASK); | ||
1799 | pte->vpage = eaddr >> PAGE_SHIFT; | ||
1800 | pte->may_read = true; | ||
1801 | pte->may_write = true; | ||
1802 | pte->may_execute = true; | ||
1803 | |||
1804 | return 0; | ||
1805 | } | ||
1806 | #endif | ||
1807 | |||
1808 | /* Check the guest TLB. */ | ||
1809 | switch (xlid) { | ||
1810 | case XLATE_INST: | ||
1811 | gtlb_index = kvmppc_mmu_itlb_index(vcpu, eaddr); | ||
1812 | break; | ||
1813 | case XLATE_DATA: | ||
1814 | gtlb_index = kvmppc_mmu_dtlb_index(vcpu, eaddr); | ||
1815 | break; | ||
1816 | default: | ||
1817 | BUG(); | ||
1818 | } | ||
1819 | |||
1820 | /* Do we have a TLB entry at all? */ | ||
1821 | if (gtlb_index < 0) | ||
1822 | return -ENOENT; | ||
1823 | |||
1824 | gpaddr = kvmppc_mmu_xlate(vcpu, gtlb_index, eaddr); | ||
1825 | |||
1826 | pte->eaddr = eaddr; | ||
1827 | pte->raddr = (gpaddr & PAGE_MASK) | (eaddr & ~PAGE_MASK); | ||
1828 | pte->vpage = eaddr >> PAGE_SHIFT; | ||
1829 | |||
1830 | /* XXX read permissions from the guest TLB */ | ||
1831 | pte->may_read = true; | ||
1832 | pte->may_write = true; | ||
1833 | pte->may_execute = true; | ||
1834 | |||
1835 | return 0; | ||
1836 | } | ||
1837 | |||
1791 | int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, | 1838 | int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, |
1792 | struct kvm_guest_debug *dbg) | 1839 | struct kvm_guest_debug *dbg) |
1793 | { | 1840 | { |
diff --git a/arch/powerpc/kvm/booke.h b/arch/powerpc/kvm/booke.h index b632cd35919b..f753543c56fa 100644 --- a/arch/powerpc/kvm/booke.h +++ b/arch/powerpc/kvm/booke.h | |||
@@ -99,13 +99,6 @@ enum int_class { | |||
99 | 99 | ||
100 | void kvmppc_set_pending_interrupt(struct kvm_vcpu *vcpu, enum int_class type); | 100 | void kvmppc_set_pending_interrupt(struct kvm_vcpu *vcpu, enum int_class type); |
101 | 101 | ||
102 | extern void kvmppc_mmu_destroy_44x(struct kvm_vcpu *vcpu); | ||
103 | extern int kvmppc_core_emulate_op_44x(struct kvm_run *run, struct kvm_vcpu *vcpu, | ||
104 | unsigned int inst, int *advance); | ||
105 | extern int kvmppc_core_emulate_mtspr_44x(struct kvm_vcpu *vcpu, int sprn, | ||
106 | ulong spr_val); | ||
107 | extern int kvmppc_core_emulate_mfspr_44x(struct kvm_vcpu *vcpu, int sprn, | ||
108 | ulong *spr_val); | ||
109 | extern void kvmppc_mmu_destroy_e500(struct kvm_vcpu *vcpu); | 102 | extern void kvmppc_mmu_destroy_e500(struct kvm_vcpu *vcpu); |
110 | extern int kvmppc_core_emulate_op_e500(struct kvm_run *run, | 103 | extern int kvmppc_core_emulate_op_e500(struct kvm_run *run, |
111 | struct kvm_vcpu *vcpu, | 104 | struct kvm_vcpu *vcpu, |
diff --git a/arch/powerpc/kvm/booke_emulate.c b/arch/powerpc/kvm/booke_emulate.c index 27a4b2877c10..28c158881d23 100644 --- a/arch/powerpc/kvm/booke_emulate.c +++ b/arch/powerpc/kvm/booke_emulate.c | |||
@@ -165,16 +165,16 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) | |||
165 | * guest (PR-mode only). | 165 | * guest (PR-mode only). |
166 | */ | 166 | */ |
167 | case SPRN_SPRG4: | 167 | case SPRN_SPRG4: |
168 | vcpu->arch.shared->sprg4 = spr_val; | 168 | kvmppc_set_sprg4(vcpu, spr_val); |
169 | break; | 169 | break; |
170 | case SPRN_SPRG5: | 170 | case SPRN_SPRG5: |
171 | vcpu->arch.shared->sprg5 = spr_val; | 171 | kvmppc_set_sprg5(vcpu, spr_val); |
172 | break; | 172 | break; |
173 | case SPRN_SPRG6: | 173 | case SPRN_SPRG6: |
174 | vcpu->arch.shared->sprg6 = spr_val; | 174 | kvmppc_set_sprg6(vcpu, spr_val); |
175 | break; | 175 | break; |
176 | case SPRN_SPRG7: | 176 | case SPRN_SPRG7: |
177 | vcpu->arch.shared->sprg7 = spr_val; | 177 | kvmppc_set_sprg7(vcpu, spr_val); |
178 | break; | 178 | break; |
179 | 179 | ||
180 | case SPRN_IVPR: | 180 | case SPRN_IVPR: |
diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S index 2c6deb5ef2fe..84c308a9a371 100644 --- a/arch/powerpc/kvm/booke_interrupts.S +++ b/arch/powerpc/kvm/booke_interrupts.S | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <asm/ppc_asm.h> | 21 | #include <asm/ppc_asm.h> |
22 | #include <asm/kvm_asm.h> | 22 | #include <asm/kvm_asm.h> |
23 | #include <asm/reg.h> | 23 | #include <asm/reg.h> |
24 | #include <asm/mmu-44x.h> | ||
25 | #include <asm/page.h> | 24 | #include <asm/page.h> |
26 | #include <asm/asm-offsets.h> | 25 | #include <asm/asm-offsets.h> |
27 | 26 | ||
@@ -424,10 +423,6 @@ lightweight_exit: | |||
424 | mtspr SPRN_PID1, r3 | 423 | mtspr SPRN_PID1, r3 |
425 | #endif | 424 | #endif |
426 | 425 | ||
427 | #ifdef CONFIG_44x | ||
428 | iccci 0, 0 /* XXX hack */ | ||
429 | #endif | ||
430 | |||
431 | /* Load some guest volatiles. */ | 426 | /* Load some guest volatiles. */ |
432 | lwz r0, VCPU_GPR(R0)(r4) | 427 | lwz r0, VCPU_GPR(R0)(r4) |
433 | lwz r2, VCPU_GPR(R2)(r4) | 428 | lwz r2, VCPU_GPR(R2)(r4) |
diff --git a/arch/powerpc/kvm/bookehv_interrupts.S b/arch/powerpc/kvm/bookehv_interrupts.S index a1712b818a5f..e9fa56a911fd 100644 --- a/arch/powerpc/kvm/bookehv_interrupts.S +++ b/arch/powerpc/kvm/bookehv_interrupts.S | |||
@@ -24,12 +24,10 @@ | |||
24 | #include <asm/ppc_asm.h> | 24 | #include <asm/ppc_asm.h> |
25 | #include <asm/kvm_asm.h> | 25 | #include <asm/kvm_asm.h> |
26 | #include <asm/reg.h> | 26 | #include <asm/reg.h> |
27 | #include <asm/mmu-44x.h> | ||
28 | #include <asm/page.h> | 27 | #include <asm/page.h> |
29 | #include <asm/asm-compat.h> | 28 | #include <asm/asm-compat.h> |
30 | #include <asm/asm-offsets.h> | 29 | #include <asm/asm-offsets.h> |
31 | #include <asm/bitsperlong.h> | 30 | #include <asm/bitsperlong.h> |
32 | #include <asm/thread_info.h> | ||
33 | 31 | ||
34 | #ifdef CONFIG_64BIT | 32 | #ifdef CONFIG_64BIT |
35 | #include <asm/exception-64e.h> | 33 | #include <asm/exception-64e.h> |
@@ -122,38 +120,14 @@ | |||
122 | 1: | 120 | 1: |
123 | 121 | ||
124 | .if \flags & NEED_EMU | 122 | .if \flags & NEED_EMU |
125 | /* | ||
126 | * This assumes you have external PID support. | ||
127 | * To support a bookehv CPU without external PID, you'll | ||
128 | * need to look up the TLB entry and create a temporary mapping. | ||
129 | * | ||
130 | * FIXME: we don't currently handle if the lwepx faults. PR-mode | ||
131 | * booke doesn't handle it either. Since Linux doesn't use | ||
132 | * broadcast tlbivax anymore, the only way this should happen is | ||
133 | * if the guest maps its memory execute-but-not-read, or if we | ||
134 | * somehow take a TLB miss in the middle of this entry code and | ||
135 | * evict the relevant entry. On e500mc, all kernel lowmem is | ||
136 | * bolted into TLB1 large page mappings, and we don't use | ||
137 | * broadcast invalidates, so we should not take a TLB miss here. | ||
138 | * | ||
139 | * Later we'll need to deal with faults here. Disallowing guest | ||
140 | * mappings that are execute-but-not-read could be an option on | ||
141 | * e500mc, but not on chips with an LRAT if it is used. | ||
142 | */ | ||
143 | |||
144 | mfspr r3, SPRN_EPLC /* will already have correct ELPID and EGS */ | ||
145 | PPC_STL r15, VCPU_GPR(R15)(r4) | 123 | PPC_STL r15, VCPU_GPR(R15)(r4) |
146 | PPC_STL r16, VCPU_GPR(R16)(r4) | 124 | PPC_STL r16, VCPU_GPR(R16)(r4) |
147 | PPC_STL r17, VCPU_GPR(R17)(r4) | 125 | PPC_STL r17, VCPU_GPR(R17)(r4) |
148 | PPC_STL r18, VCPU_GPR(R18)(r4) | 126 | PPC_STL r18, VCPU_GPR(R18)(r4) |
149 | PPC_STL r19, VCPU_GPR(R19)(r4) | 127 | PPC_STL r19, VCPU_GPR(R19)(r4) |
150 | mr r8, r3 | ||
151 | PPC_STL r20, VCPU_GPR(R20)(r4) | 128 | PPC_STL r20, VCPU_GPR(R20)(r4) |
152 | rlwimi r8, r6, EPC_EAS_SHIFT - MSR_IR_LG, EPC_EAS | ||
153 | PPC_STL r21, VCPU_GPR(R21)(r4) | 129 | PPC_STL r21, VCPU_GPR(R21)(r4) |
154 | rlwimi r8, r6, EPC_EPR_SHIFT - MSR_PR_LG, EPC_EPR | ||
155 | PPC_STL r22, VCPU_GPR(R22)(r4) | 130 | PPC_STL r22, VCPU_GPR(R22)(r4) |
156 | rlwimi r8, r10, EPC_EPID_SHIFT, EPC_EPID | ||
157 | PPC_STL r23, VCPU_GPR(R23)(r4) | 131 | PPC_STL r23, VCPU_GPR(R23)(r4) |
158 | PPC_STL r24, VCPU_GPR(R24)(r4) | 132 | PPC_STL r24, VCPU_GPR(R24)(r4) |
159 | PPC_STL r25, VCPU_GPR(R25)(r4) | 133 | PPC_STL r25, VCPU_GPR(R25)(r4) |
@@ -163,33 +137,15 @@ | |||
163 | PPC_STL r29, VCPU_GPR(R29)(r4) | 137 | PPC_STL r29, VCPU_GPR(R29)(r4) |
164 | PPC_STL r30, VCPU_GPR(R30)(r4) | 138 | PPC_STL r30, VCPU_GPR(R30)(r4) |
165 | PPC_STL r31, VCPU_GPR(R31)(r4) | 139 | PPC_STL r31, VCPU_GPR(R31)(r4) |
166 | mtspr SPRN_EPLC, r8 | ||
167 | |||
168 | /* disable preemption, so we are sure we hit the fixup handler */ | ||
169 | CURRENT_THREAD_INFO(r8, r1) | ||
170 | li r7, 1 | ||
171 | stw r7, TI_PREEMPT(r8) | ||
172 | |||
173 | isync | ||
174 | 140 | ||
175 | /* | 141 | /* |
176 | * In case the read goes wrong, we catch it and write an invalid value | 142 | * We don't use external PID support. lwepx faults would need to be |
177 | * in LAST_INST instead. | 143 | * handled by KVM and this implies aditional code in DO_KVM (for |
144 | * DTB_MISS, DSI and LRAT) to check ESR[EPID] and EPLC[EGS] which | ||
145 | * is too intrusive for the host. Get last instuction in | ||
146 | * kvmppc_get_last_inst(). | ||
178 | */ | 147 | */ |
179 | 1: lwepx r9, 0, r5 | 148 | li r9, KVM_INST_FETCH_FAILED |
180 | 2: | ||
181 | .section .fixup, "ax" | ||
182 | 3: li r9, KVM_INST_FETCH_FAILED | ||
183 | b 2b | ||
184 | .previous | ||
185 | .section __ex_table,"a" | ||
186 | PPC_LONG_ALIGN | ||
187 | PPC_LONG 1b,3b | ||
188 | .previous | ||
189 | |||
190 | mtspr SPRN_EPLC, r3 | ||
191 | li r7, 0 | ||
192 | stw r7, TI_PREEMPT(r8) | ||
193 | stw r9, VCPU_LAST_INST(r4) | 149 | stw r9, VCPU_LAST_INST(r4) |
194 | .endif | 150 | .endif |
195 | 151 | ||
@@ -441,6 +397,7 @@ _GLOBAL(kvmppc_resume_host) | |||
441 | #ifdef CONFIG_64BIT | 397 | #ifdef CONFIG_64BIT |
442 | PPC_LL r3, PACA_SPRG_VDSO(r13) | 398 | PPC_LL r3, PACA_SPRG_VDSO(r13) |
443 | #endif | 399 | #endif |
400 | mfspr r5, SPRN_SPRG9 | ||
444 | PPC_STD(r6, VCPU_SHARED_SPRG4, r11) | 401 | PPC_STD(r6, VCPU_SHARED_SPRG4, r11) |
445 | mfspr r8, SPRN_SPRG6 | 402 | mfspr r8, SPRN_SPRG6 |
446 | PPC_STD(r7, VCPU_SHARED_SPRG5, r11) | 403 | PPC_STD(r7, VCPU_SHARED_SPRG5, r11) |
@@ -448,6 +405,7 @@ _GLOBAL(kvmppc_resume_host) | |||
448 | #ifdef CONFIG_64BIT | 405 | #ifdef CONFIG_64BIT |
449 | mtspr SPRN_SPRG_VDSO_WRITE, r3 | 406 | mtspr SPRN_SPRG_VDSO_WRITE, r3 |
450 | #endif | 407 | #endif |
408 | PPC_STD(r5, VCPU_SPRG9, r4) | ||
451 | PPC_STD(r8, VCPU_SHARED_SPRG6, r11) | 409 | PPC_STD(r8, VCPU_SHARED_SPRG6, r11) |
452 | mfxer r3 | 410 | mfxer r3 |
453 | PPC_STD(r9, VCPU_SHARED_SPRG7, r11) | 411 | PPC_STD(r9, VCPU_SHARED_SPRG7, r11) |
@@ -682,7 +640,9 @@ lightweight_exit: | |||
682 | mtspr SPRN_SPRG5W, r6 | 640 | mtspr SPRN_SPRG5W, r6 |
683 | PPC_LD(r8, VCPU_SHARED_SPRG7, r11) | 641 | PPC_LD(r8, VCPU_SHARED_SPRG7, r11) |
684 | mtspr SPRN_SPRG6W, r7 | 642 | mtspr SPRN_SPRG6W, r7 |
643 | PPC_LD(r5, VCPU_SPRG9, r4) | ||
685 | mtspr SPRN_SPRG7W, r8 | 644 | mtspr SPRN_SPRG7W, r8 |
645 | mtspr SPRN_SPRG9, r5 | ||
686 | 646 | ||
687 | /* Load some guest volatiles. */ | 647 | /* Load some guest volatiles. */ |
688 | PPC_LL r3, VCPU_LR(r4) | 648 | PPC_LL r3, VCPU_LR(r4) |
diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c index 002d51764143..c99c40e9182a 100644 --- a/arch/powerpc/kvm/e500_emulate.c +++ b/arch/powerpc/kvm/e500_emulate.c | |||
@@ -250,6 +250,14 @@ int kvmppc_core_emulate_mtspr_e500(struct kvm_vcpu *vcpu, int sprn, ulong spr_va | |||
250 | spr_val); | 250 | spr_val); |
251 | break; | 251 | break; |
252 | 252 | ||
253 | case SPRN_PWRMGTCR0: | ||
254 | /* | ||
255 | * Guest relies on host power management configurations | ||
256 | * Treat the request as a general store | ||
257 | */ | ||
258 | vcpu->arch.pwrmgtcr0 = spr_val; | ||
259 | break; | ||
260 | |||
253 | /* extra exceptions */ | 261 | /* extra exceptions */ |
254 | case SPRN_IVOR32: | 262 | case SPRN_IVOR32: |
255 | vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL] = spr_val; | 263 | vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL] = spr_val; |
@@ -368,6 +376,10 @@ int kvmppc_core_emulate_mfspr_e500(struct kvm_vcpu *vcpu, int sprn, ulong *spr_v | |||
368 | *spr_val = vcpu->arch.eptcfg; | 376 | *spr_val = vcpu->arch.eptcfg; |
369 | break; | 377 | break; |
370 | 378 | ||
379 | case SPRN_PWRMGTCR0: | ||
380 | *spr_val = vcpu->arch.pwrmgtcr0; | ||
381 | break; | ||
382 | |||
371 | /* extra exceptions */ | 383 | /* extra exceptions */ |
372 | case SPRN_IVOR32: | 384 | case SPRN_IVOR32: |
373 | *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL]; | 385 | *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL]; |
diff --git a/arch/powerpc/kvm/e500_mmu_host.c b/arch/powerpc/kvm/e500_mmu_host.c index 86903d3f5a03..08f14bb57897 100644 --- a/arch/powerpc/kvm/e500_mmu_host.c +++ b/arch/powerpc/kvm/e500_mmu_host.c | |||
@@ -107,11 +107,15 @@ static u32 get_host_mas0(unsigned long eaddr) | |||
107 | { | 107 | { |
108 | unsigned long flags; | 108 | unsigned long flags; |
109 | u32 mas0; | 109 | u32 mas0; |
110 | u32 mas4; | ||
110 | 111 | ||
111 | local_irq_save(flags); | 112 | local_irq_save(flags); |
112 | mtspr(SPRN_MAS6, 0); | 113 | mtspr(SPRN_MAS6, 0); |
114 | mas4 = mfspr(SPRN_MAS4); | ||
115 | mtspr(SPRN_MAS4, mas4 & ~MAS4_TLBSEL_MASK); | ||
113 | asm volatile("tlbsx 0, %0" : : "b" (eaddr & ~CONFIG_PAGE_OFFSET)); | 116 | asm volatile("tlbsx 0, %0" : : "b" (eaddr & ~CONFIG_PAGE_OFFSET)); |
114 | mas0 = mfspr(SPRN_MAS0); | 117 | mas0 = mfspr(SPRN_MAS0); |
118 | mtspr(SPRN_MAS4, mas4); | ||
115 | local_irq_restore(flags); | 119 | local_irq_restore(flags); |
116 | 120 | ||
117 | return mas0; | 121 | return mas0; |
@@ -607,6 +611,104 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 eaddr, gpa_t gpaddr, | |||
607 | } | 611 | } |
608 | } | 612 | } |
609 | 613 | ||
614 | #ifdef CONFIG_KVM_BOOKE_HV | ||
615 | int kvmppc_load_last_inst(struct kvm_vcpu *vcpu, enum instruction_type type, | ||
616 | u32 *instr) | ||
617 | { | ||
618 | gva_t geaddr; | ||
619 | hpa_t addr; | ||
620 | hfn_t pfn; | ||
621 | hva_t eaddr; | ||
622 | u32 mas1, mas2, mas3; | ||
623 | u64 mas7_mas3; | ||
624 | struct page *page; | ||
625 | unsigned int addr_space, psize_shift; | ||
626 | bool pr; | ||
627 | unsigned long flags; | ||
628 | |||
629 | /* Search TLB for guest pc to get the real address */ | ||
630 | geaddr = kvmppc_get_pc(vcpu); | ||
631 | |||
632 | addr_space = (vcpu->arch.shared->msr & MSR_IS) >> MSR_IR_LG; | ||
633 | |||
634 | local_irq_save(flags); | ||
635 | mtspr(SPRN_MAS6, (vcpu->arch.pid << MAS6_SPID_SHIFT) | addr_space); | ||
636 | mtspr(SPRN_MAS5, MAS5_SGS | vcpu->kvm->arch.lpid); | ||
637 | asm volatile("tlbsx 0, %[geaddr]\n" : : | ||
638 | [geaddr] "r" (geaddr)); | ||
639 | mtspr(SPRN_MAS5, 0); | ||
640 | mtspr(SPRN_MAS8, 0); | ||
641 | mas1 = mfspr(SPRN_MAS1); | ||
642 | mas2 = mfspr(SPRN_MAS2); | ||
643 | mas3 = mfspr(SPRN_MAS3); | ||
644 | #ifdef CONFIG_64BIT | ||
645 | mas7_mas3 = mfspr(SPRN_MAS7_MAS3); | ||
646 | #else | ||
647 | mas7_mas3 = ((u64)mfspr(SPRN_MAS7) << 32) | mas3; | ||
648 | #endif | ||
649 | local_irq_restore(flags); | ||
650 | |||
651 | /* | ||
652 | * If the TLB entry for guest pc was evicted, return to the guest. | ||
653 | * There are high chances to find a valid TLB entry next time. | ||
654 | */ | ||
655 | if (!(mas1 & MAS1_VALID)) | ||
656 | return EMULATE_AGAIN; | ||
657 | |||
658 | /* | ||
659 | * Another thread may rewrite the TLB entry in parallel, don't | ||
660 | * execute from the address if the execute permission is not set | ||
661 | */ | ||
662 | pr = vcpu->arch.shared->msr & MSR_PR; | ||
663 | if (unlikely((pr && !(mas3 & MAS3_UX)) || | ||
664 | (!pr && !(mas3 & MAS3_SX)))) { | ||
665 | pr_err_ratelimited( | ||
666 | "%s: Instuction emulation from guest addres %08lx without execute permission\n", | ||
667 | __func__, geaddr); | ||
668 | return EMULATE_AGAIN; | ||
669 | } | ||
670 | |||
671 | /* | ||
672 | * The real address will be mapped by a cacheable, memory coherent, | ||
673 | * write-back page. Check for mismatches when LRAT is used. | ||
674 | */ | ||
675 | if (has_feature(vcpu, VCPU_FTR_MMU_V2) && | ||
676 | unlikely((mas2 & MAS2_I) || (mas2 & MAS2_W) || !(mas2 & MAS2_M))) { | ||
677 | pr_err_ratelimited( | ||
678 | "%s: Instuction emulation from guest addres %08lx mismatches storage attributes\n", | ||
679 | __func__, geaddr); | ||
680 | return EMULATE_AGAIN; | ||
681 | } | ||
682 | |||
683 | /* Get pfn */ | ||
684 | psize_shift = MAS1_GET_TSIZE(mas1) + 10; | ||
685 | addr = (mas7_mas3 & (~0ULL << psize_shift)) | | ||
686 | (geaddr & ((1ULL << psize_shift) - 1ULL)); | ||
687 | pfn = addr >> PAGE_SHIFT; | ||
688 | |||
689 | /* Guard against emulation from devices area */ | ||
690 | if (unlikely(!page_is_ram(pfn))) { | ||
691 | pr_err_ratelimited("%s: Instruction emulation from non-RAM host addres %08llx is not supported\n", | ||
692 | __func__, addr); | ||
693 | return EMULATE_AGAIN; | ||
694 | } | ||
695 | |||
696 | /* Map a page and get guest's instruction */ | ||
697 | page = pfn_to_page(pfn); | ||
698 | eaddr = (unsigned long)kmap_atomic(page); | ||
699 | *instr = *(u32 *)(eaddr | (unsigned long)(addr & ~PAGE_MASK)); | ||
700 | kunmap_atomic((u32 *)eaddr); | ||
701 | |||
702 | return EMULATE_DONE; | ||
703 | } | ||
704 | #else | ||
705 | int kvmppc_load_last_inst(struct kvm_vcpu *vcpu, enum instruction_type type, | ||
706 | u32 *instr) | ||
707 | { | ||
708 | return EMULATE_AGAIN; | ||
709 | } | ||
710 | #endif | ||
711 | |||
610 | /************* MMU Notifiers *************/ | 712 | /************* MMU Notifiers *************/ |
611 | 713 | ||
612 | int kvm_unmap_hva(struct kvm *kvm, unsigned long hva) | 714 | int kvm_unmap_hva(struct kvm *kvm, unsigned long hva) |
diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c index 17e456279224..164bad2a19bf 100644 --- a/arch/powerpc/kvm/e500mc.c +++ b/arch/powerpc/kvm/e500mc.c | |||
@@ -110,7 +110,7 @@ void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr) | |||
110 | { | 110 | { |
111 | } | 111 | } |
112 | 112 | ||
113 | static DEFINE_PER_CPU(struct kvm_vcpu *, last_vcpu_on_cpu); | 113 | static DEFINE_PER_CPU(struct kvm_vcpu *[KVMPPC_NR_LPIDS], last_vcpu_of_lpid); |
114 | 114 | ||
115 | static void kvmppc_core_vcpu_load_e500mc(struct kvm_vcpu *vcpu, int cpu) | 115 | static void kvmppc_core_vcpu_load_e500mc(struct kvm_vcpu *vcpu, int cpu) |
116 | { | 116 | { |
@@ -141,9 +141,9 @@ static void kvmppc_core_vcpu_load_e500mc(struct kvm_vcpu *vcpu, int cpu) | |||
141 | mtspr(SPRN_GESR, vcpu->arch.shared->esr); | 141 | mtspr(SPRN_GESR, vcpu->arch.shared->esr); |
142 | 142 | ||
143 | if (vcpu->arch.oldpir != mfspr(SPRN_PIR) || | 143 | if (vcpu->arch.oldpir != mfspr(SPRN_PIR) || |
144 | __get_cpu_var(last_vcpu_on_cpu) != vcpu) { | 144 | __get_cpu_var(last_vcpu_of_lpid)[vcpu->kvm->arch.lpid] != vcpu) { |
145 | kvmppc_e500_tlbil_all(vcpu_e500); | 145 | kvmppc_e500_tlbil_all(vcpu_e500); |
146 | __get_cpu_var(last_vcpu_on_cpu) = vcpu; | 146 | __get_cpu_var(last_vcpu_of_lpid)[vcpu->kvm->arch.lpid] = vcpu; |
147 | } | 147 | } |
148 | 148 | ||
149 | kvmppc_load_guest_fp(vcpu); | 149 | kvmppc_load_guest_fp(vcpu); |
@@ -267,14 +267,32 @@ static int kvmppc_core_set_sregs_e500mc(struct kvm_vcpu *vcpu, | |||
267 | static int kvmppc_get_one_reg_e500mc(struct kvm_vcpu *vcpu, u64 id, | 267 | static int kvmppc_get_one_reg_e500mc(struct kvm_vcpu *vcpu, u64 id, |
268 | union kvmppc_one_reg *val) | 268 | union kvmppc_one_reg *val) |
269 | { | 269 | { |
270 | int r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val); | 270 | int r = 0; |
271 | |||
272 | switch (id) { | ||
273 | case KVM_REG_PPC_SPRG9: | ||
274 | *val = get_reg_val(id, vcpu->arch.sprg9); | ||
275 | break; | ||
276 | default: | ||
277 | r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val); | ||
278 | } | ||
279 | |||
271 | return r; | 280 | return r; |
272 | } | 281 | } |
273 | 282 | ||
274 | static int kvmppc_set_one_reg_e500mc(struct kvm_vcpu *vcpu, u64 id, | 283 | static int kvmppc_set_one_reg_e500mc(struct kvm_vcpu *vcpu, u64 id, |
275 | union kvmppc_one_reg *val) | 284 | union kvmppc_one_reg *val) |
276 | { | 285 | { |
277 | int r = kvmppc_set_one_reg_e500_tlb(vcpu, id, val); | 286 | int r = 0; |
287 | |||
288 | switch (id) { | ||
289 | case KVM_REG_PPC_SPRG9: | ||
290 | vcpu->arch.sprg9 = set_reg_val(id, *val); | ||
291 | break; | ||
292 | default: | ||
293 | r = kvmppc_set_one_reg_e500_tlb(vcpu, id, val); | ||
294 | } | ||
295 | |||
278 | return r; | 296 | return r; |
279 | } | 297 | } |
280 | 298 | ||
diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c index da86d9ba3476..e96b50d0bdab 100644 --- a/arch/powerpc/kvm/emulate.c +++ b/arch/powerpc/kvm/emulate.c | |||
@@ -207,36 +207,28 @@ static int kvmppc_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt) | |||
207 | return emulated; | 207 | return emulated; |
208 | } | 208 | } |
209 | 209 | ||
210 | /* XXX to do: | ||
211 | * lhax | ||
212 | * lhaux | ||
213 | * lswx | ||
214 | * lswi | ||
215 | * stswx | ||
216 | * stswi | ||
217 | * lha | ||
218 | * lhau | ||
219 | * lmw | ||
220 | * stmw | ||
221 | * | ||
222 | */ | ||
223 | /* XXX Should probably auto-generate instruction decoding for a particular core | 210 | /* XXX Should probably auto-generate instruction decoding for a particular core |
224 | * from opcode tables in the future. */ | 211 | * from opcode tables in the future. */ |
225 | int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) | 212 | int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) |
226 | { | 213 | { |
227 | u32 inst = kvmppc_get_last_inst(vcpu); | 214 | u32 inst; |
228 | int ra = get_ra(inst); | 215 | int rs, rt, sprn; |
229 | int rs = get_rs(inst); | 216 | enum emulation_result emulated; |
230 | int rt = get_rt(inst); | ||
231 | int sprn = get_sprn(inst); | ||
232 | enum emulation_result emulated = EMULATE_DONE; | ||
233 | int advance = 1; | 217 | int advance = 1; |
234 | 218 | ||
235 | /* this default type might be overwritten by subcategories */ | 219 | /* this default type might be overwritten by subcategories */ |
236 | kvmppc_set_exit_type(vcpu, EMULATED_INST_EXITS); | 220 | kvmppc_set_exit_type(vcpu, EMULATED_INST_EXITS); |
237 | 221 | ||
222 | emulated = kvmppc_get_last_inst(vcpu, false, &inst); | ||
223 | if (emulated != EMULATE_DONE) | ||
224 | return emulated; | ||
225 | |||
238 | pr_debug("Emulating opcode %d / %d\n", get_op(inst), get_xop(inst)); | 226 | pr_debug("Emulating opcode %d / %d\n", get_op(inst), get_xop(inst)); |
239 | 227 | ||
228 | rs = get_rs(inst); | ||
229 | rt = get_rt(inst); | ||
230 | sprn = get_sprn(inst); | ||
231 | |||
240 | switch (get_op(inst)) { | 232 | switch (get_op(inst)) { |
241 | case OP_TRAP: | 233 | case OP_TRAP: |
242 | #ifdef CONFIG_PPC_BOOK3S | 234 | #ifdef CONFIG_PPC_BOOK3S |
@@ -264,200 +256,24 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
264 | #endif | 256 | #endif |
265 | advance = 0; | 257 | advance = 0; |
266 | break; | 258 | break; |
267 | case OP_31_XOP_LWZX: | ||
268 | emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1); | ||
269 | break; | ||
270 | |||
271 | case OP_31_XOP_LBZX: | ||
272 | emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1); | ||
273 | break; | ||
274 | |||
275 | case OP_31_XOP_LBZUX: | ||
276 | emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1); | ||
277 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
278 | break; | ||
279 | |||
280 | case OP_31_XOP_STWX: | ||
281 | emulated = kvmppc_handle_store(run, vcpu, | ||
282 | kvmppc_get_gpr(vcpu, rs), | ||
283 | 4, 1); | ||
284 | break; | ||
285 | |||
286 | case OP_31_XOP_STBX: | ||
287 | emulated = kvmppc_handle_store(run, vcpu, | ||
288 | kvmppc_get_gpr(vcpu, rs), | ||
289 | 1, 1); | ||
290 | break; | ||
291 | |||
292 | case OP_31_XOP_STBUX: | ||
293 | emulated = kvmppc_handle_store(run, vcpu, | ||
294 | kvmppc_get_gpr(vcpu, rs), | ||
295 | 1, 1); | ||
296 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
297 | break; | ||
298 | |||
299 | case OP_31_XOP_LHAX: | ||
300 | emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1); | ||
301 | break; | ||
302 | |||
303 | case OP_31_XOP_LHZX: | ||
304 | emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1); | ||
305 | break; | ||
306 | |||
307 | case OP_31_XOP_LHZUX: | ||
308 | emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1); | ||
309 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
310 | break; | ||
311 | 259 | ||
312 | case OP_31_XOP_MFSPR: | 260 | case OP_31_XOP_MFSPR: |
313 | emulated = kvmppc_emulate_mfspr(vcpu, sprn, rt); | 261 | emulated = kvmppc_emulate_mfspr(vcpu, sprn, rt); |
314 | break; | 262 | break; |
315 | 263 | ||
316 | case OP_31_XOP_STHX: | ||
317 | emulated = kvmppc_handle_store(run, vcpu, | ||
318 | kvmppc_get_gpr(vcpu, rs), | ||
319 | 2, 1); | ||
320 | break; | ||
321 | |||
322 | case OP_31_XOP_STHUX: | ||
323 | emulated = kvmppc_handle_store(run, vcpu, | ||
324 | kvmppc_get_gpr(vcpu, rs), | ||
325 | 2, 1); | ||
326 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
327 | break; | ||
328 | |||
329 | case OP_31_XOP_MTSPR: | 264 | case OP_31_XOP_MTSPR: |
330 | emulated = kvmppc_emulate_mtspr(vcpu, sprn, rs); | 265 | emulated = kvmppc_emulate_mtspr(vcpu, sprn, rs); |
331 | break; | 266 | break; |
332 | 267 | ||
333 | case OP_31_XOP_DCBST: | ||
334 | case OP_31_XOP_DCBF: | ||
335 | case OP_31_XOP_DCBI: | ||
336 | /* Do nothing. The guest is performing dcbi because | ||
337 | * hardware DMA is not snooped by the dcache, but | ||
338 | * emulated DMA either goes through the dcache as | ||
339 | * normal writes, or the host kernel has handled dcache | ||
340 | * coherence. */ | ||
341 | break; | ||
342 | |||
343 | case OP_31_XOP_LWBRX: | ||
344 | emulated = kvmppc_handle_load(run, vcpu, rt, 4, 0); | ||
345 | break; | ||
346 | |||
347 | case OP_31_XOP_TLBSYNC: | 268 | case OP_31_XOP_TLBSYNC: |
348 | break; | 269 | break; |
349 | 270 | ||
350 | case OP_31_XOP_STWBRX: | ||
351 | emulated = kvmppc_handle_store(run, vcpu, | ||
352 | kvmppc_get_gpr(vcpu, rs), | ||
353 | 4, 0); | ||
354 | break; | ||
355 | |||
356 | case OP_31_XOP_LHBRX: | ||
357 | emulated = kvmppc_handle_load(run, vcpu, rt, 2, 0); | ||
358 | break; | ||
359 | |||
360 | case OP_31_XOP_STHBRX: | ||
361 | emulated = kvmppc_handle_store(run, vcpu, | ||
362 | kvmppc_get_gpr(vcpu, rs), | ||
363 | 2, 0); | ||
364 | break; | ||
365 | |||
366 | default: | 271 | default: |
367 | /* Attempt core-specific emulation below. */ | 272 | /* Attempt core-specific emulation below. */ |
368 | emulated = EMULATE_FAIL; | 273 | emulated = EMULATE_FAIL; |
369 | } | 274 | } |
370 | break; | 275 | break; |
371 | 276 | ||
372 | case OP_LWZ: | ||
373 | emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1); | ||
374 | break; | ||
375 | |||
376 | /* TBD: Add support for other 64 bit load variants like ldu, ldux, ldx etc. */ | ||
377 | case OP_LD: | ||
378 | rt = get_rt(inst); | ||
379 | emulated = kvmppc_handle_load(run, vcpu, rt, 8, 1); | ||
380 | break; | ||
381 | |||
382 | case OP_LWZU: | ||
383 | emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1); | ||
384 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
385 | break; | ||
386 | |||
387 | case OP_LBZ: | ||
388 | emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1); | ||
389 | break; | ||
390 | |||
391 | case OP_LBZU: | ||
392 | emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1); | ||
393 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
394 | break; | ||
395 | |||
396 | case OP_STW: | ||
397 | emulated = kvmppc_handle_store(run, vcpu, | ||
398 | kvmppc_get_gpr(vcpu, rs), | ||
399 | 4, 1); | ||
400 | break; | ||
401 | |||
402 | /* TBD: Add support for other 64 bit store variants like stdu, stdux, stdx etc. */ | ||
403 | case OP_STD: | ||
404 | rs = get_rs(inst); | ||
405 | emulated = kvmppc_handle_store(run, vcpu, | ||
406 | kvmppc_get_gpr(vcpu, rs), | ||
407 | 8, 1); | ||
408 | break; | ||
409 | |||
410 | case OP_STWU: | ||
411 | emulated = kvmppc_handle_store(run, vcpu, | ||
412 | kvmppc_get_gpr(vcpu, rs), | ||
413 | 4, 1); | ||
414 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
415 | break; | ||
416 | |||
417 | case OP_STB: | ||
418 | emulated = kvmppc_handle_store(run, vcpu, | ||
419 | kvmppc_get_gpr(vcpu, rs), | ||
420 | 1, 1); | ||
421 | break; | ||
422 | |||
423 | case OP_STBU: | ||
424 | emulated = kvmppc_handle_store(run, vcpu, | ||
425 | kvmppc_get_gpr(vcpu, rs), | ||
426 | 1, 1); | ||
427 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
428 | break; | ||
429 | |||
430 | case OP_LHZ: | ||
431 | emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1); | ||
432 | break; | ||
433 | |||
434 | case OP_LHZU: | ||
435 | emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1); | ||
436 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
437 | break; | ||
438 | |||
439 | case OP_LHA: | ||
440 | emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1); | ||
441 | break; | ||
442 | |||
443 | case OP_LHAU: | ||
444 | emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1); | ||
445 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
446 | break; | ||
447 | |||
448 | case OP_STH: | ||
449 | emulated = kvmppc_handle_store(run, vcpu, | ||
450 | kvmppc_get_gpr(vcpu, rs), | ||
451 | 2, 1); | ||
452 | break; | ||
453 | |||
454 | case OP_STHU: | ||
455 | emulated = kvmppc_handle_store(run, vcpu, | ||
456 | kvmppc_get_gpr(vcpu, rs), | ||
457 | 2, 1); | ||
458 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
459 | break; | ||
460 | |||
461 | default: | 277 | default: |
462 | emulated = EMULATE_FAIL; | 278 | emulated = EMULATE_FAIL; |
463 | } | 279 | } |
diff --git a/arch/powerpc/kvm/emulate_loadstore.c b/arch/powerpc/kvm/emulate_loadstore.c new file mode 100644 index 000000000000..0de4ffa175a9 --- /dev/null +++ b/arch/powerpc/kvm/emulate_loadstore.c | |||
@@ -0,0 +1,272 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify | ||
3 | * it under the terms of the GNU General Public License, version 2, as | ||
4 | * published by the Free Software Foundation. | ||
5 | * | ||
6 | * This program is distributed in the hope that it will be useful, | ||
7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
9 | * GNU General Public License for more details. | ||
10 | * | ||
11 | * You should have received a copy of the GNU General Public License | ||
12 | * along with this program; if not, write to the Free Software | ||
13 | * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
14 | * | ||
15 | * Copyright IBM Corp. 2007 | ||
16 | * Copyright 2011 Freescale Semiconductor, Inc. | ||
17 | * | ||
18 | * Authors: Hollis Blanchard <hollisb@us.ibm.com> | ||
19 | */ | ||
20 | |||
21 | #include <linux/jiffies.h> | ||
22 | #include <linux/hrtimer.h> | ||
23 | #include <linux/types.h> | ||
24 | #include <linux/string.h> | ||
25 | #include <linux/kvm_host.h> | ||
26 | #include <linux/clockchips.h> | ||
27 | |||
28 | #include <asm/reg.h> | ||
29 | #include <asm/time.h> | ||
30 | #include <asm/byteorder.h> | ||
31 | #include <asm/kvm_ppc.h> | ||
32 | #include <asm/disassemble.h> | ||
33 | #include <asm/ppc-opcode.h> | ||
34 | #include "timing.h" | ||
35 | #include "trace.h" | ||
36 | |||
37 | /* XXX to do: | ||
38 | * lhax | ||
39 | * lhaux | ||
40 | * lswx | ||
41 | * lswi | ||
42 | * stswx | ||
43 | * stswi | ||
44 | * lha | ||
45 | * lhau | ||
46 | * lmw | ||
47 | * stmw | ||
48 | * | ||
49 | */ | ||
50 | int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu) | ||
51 | { | ||
52 | struct kvm_run *run = vcpu->run; | ||
53 | u32 inst; | ||
54 | int ra, rs, rt; | ||
55 | enum emulation_result emulated; | ||
56 | int advance = 1; | ||
57 | |||
58 | /* this default type might be overwritten by subcategories */ | ||
59 | kvmppc_set_exit_type(vcpu, EMULATED_INST_EXITS); | ||
60 | |||
61 | emulated = kvmppc_get_last_inst(vcpu, false, &inst); | ||
62 | if (emulated != EMULATE_DONE) | ||
63 | return emulated; | ||
64 | |||
65 | ra = get_ra(inst); | ||
66 | rs = get_rs(inst); | ||
67 | rt = get_rt(inst); | ||
68 | |||
69 | switch (get_op(inst)) { | ||
70 | case 31: | ||
71 | switch (get_xop(inst)) { | ||
72 | case OP_31_XOP_LWZX: | ||
73 | emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1); | ||
74 | break; | ||
75 | |||
76 | case OP_31_XOP_LBZX: | ||
77 | emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1); | ||
78 | break; | ||
79 | |||
80 | case OP_31_XOP_LBZUX: | ||
81 | emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1); | ||
82 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
83 | break; | ||
84 | |||
85 | case OP_31_XOP_STWX: | ||
86 | emulated = kvmppc_handle_store(run, vcpu, | ||
87 | kvmppc_get_gpr(vcpu, rs), | ||
88 | 4, 1); | ||
89 | break; | ||
90 | |||
91 | case OP_31_XOP_STBX: | ||
92 | emulated = kvmppc_handle_store(run, vcpu, | ||
93 | kvmppc_get_gpr(vcpu, rs), | ||
94 | 1, 1); | ||
95 | break; | ||
96 | |||
97 | case OP_31_XOP_STBUX: | ||
98 | emulated = kvmppc_handle_store(run, vcpu, | ||
99 | kvmppc_get_gpr(vcpu, rs), | ||
100 | 1, 1); | ||
101 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
102 | break; | ||
103 | |||
104 | case OP_31_XOP_LHAX: | ||
105 | emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1); | ||
106 | break; | ||
107 | |||
108 | case OP_31_XOP_LHZX: | ||
109 | emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1); | ||
110 | break; | ||
111 | |||
112 | case OP_31_XOP_LHZUX: | ||
113 | emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1); | ||
114 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
115 | break; | ||
116 | |||
117 | case OP_31_XOP_STHX: | ||
118 | emulated = kvmppc_handle_store(run, vcpu, | ||
119 | kvmppc_get_gpr(vcpu, rs), | ||
120 | 2, 1); | ||
121 | break; | ||
122 | |||
123 | case OP_31_XOP_STHUX: | ||
124 | emulated = kvmppc_handle_store(run, vcpu, | ||
125 | kvmppc_get_gpr(vcpu, rs), | ||
126 | 2, 1); | ||
127 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
128 | break; | ||
129 | |||
130 | case OP_31_XOP_DCBST: | ||
131 | case OP_31_XOP_DCBF: | ||
132 | case OP_31_XOP_DCBI: | ||
133 | /* Do nothing. The guest is performing dcbi because | ||
134 | * hardware DMA is not snooped by the dcache, but | ||
135 | * emulated DMA either goes through the dcache as | ||
136 | * normal writes, or the host kernel has handled dcache | ||
137 | * coherence. */ | ||
138 | break; | ||
139 | |||
140 | case OP_31_XOP_LWBRX: | ||
141 | emulated = kvmppc_handle_load(run, vcpu, rt, 4, 0); | ||
142 | break; | ||
143 | |||
144 | case OP_31_XOP_STWBRX: | ||
145 | emulated = kvmppc_handle_store(run, vcpu, | ||
146 | kvmppc_get_gpr(vcpu, rs), | ||
147 | 4, 0); | ||
148 | break; | ||
149 | |||
150 | case OP_31_XOP_LHBRX: | ||
151 | emulated = kvmppc_handle_load(run, vcpu, rt, 2, 0); | ||
152 | break; | ||
153 | |||
154 | case OP_31_XOP_STHBRX: | ||
155 | emulated = kvmppc_handle_store(run, vcpu, | ||
156 | kvmppc_get_gpr(vcpu, rs), | ||
157 | 2, 0); | ||
158 | break; | ||
159 | |||
160 | default: | ||
161 | emulated = EMULATE_FAIL; | ||
162 | break; | ||
163 | } | ||
164 | break; | ||
165 | |||
166 | case OP_LWZ: | ||
167 | emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1); | ||
168 | break; | ||
169 | |||
170 | /* TBD: Add support for other 64 bit load variants like ldu, ldux, ldx etc. */ | ||
171 | case OP_LD: | ||
172 | rt = get_rt(inst); | ||
173 | emulated = kvmppc_handle_load(run, vcpu, rt, 8, 1); | ||
174 | break; | ||
175 | |||
176 | case OP_LWZU: | ||
177 | emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1); | ||
178 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
179 | break; | ||
180 | |||
181 | case OP_LBZ: | ||
182 | emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1); | ||
183 | break; | ||
184 | |||
185 | case OP_LBZU: | ||
186 | emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1); | ||
187 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
188 | break; | ||
189 | |||
190 | case OP_STW: | ||
191 | emulated = kvmppc_handle_store(run, vcpu, | ||
192 | kvmppc_get_gpr(vcpu, rs), | ||
193 | 4, 1); | ||
194 | break; | ||
195 | |||
196 | /* TBD: Add support for other 64 bit store variants like stdu, stdux, stdx etc. */ | ||
197 | case OP_STD: | ||
198 | rs = get_rs(inst); | ||
199 | emulated = kvmppc_handle_store(run, vcpu, | ||
200 | kvmppc_get_gpr(vcpu, rs), | ||
201 | 8, 1); | ||
202 | break; | ||
203 | |||
204 | case OP_STWU: | ||
205 | emulated = kvmppc_handle_store(run, vcpu, | ||
206 | kvmppc_get_gpr(vcpu, rs), | ||
207 | 4, 1); | ||
208 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
209 | break; | ||
210 | |||
211 | case OP_STB: | ||
212 | emulated = kvmppc_handle_store(run, vcpu, | ||
213 | kvmppc_get_gpr(vcpu, rs), | ||
214 | 1, 1); | ||
215 | break; | ||
216 | |||
217 | case OP_STBU: | ||
218 | emulated = kvmppc_handle_store(run, vcpu, | ||
219 | kvmppc_get_gpr(vcpu, rs), | ||
220 | 1, 1); | ||
221 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
222 | break; | ||
223 | |||
224 | case OP_LHZ: | ||
225 | emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1); | ||
226 | break; | ||
227 | |||
228 | case OP_LHZU: | ||
229 | emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1); | ||
230 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
231 | break; | ||
232 | |||
233 | case OP_LHA: | ||
234 | emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1); | ||
235 | break; | ||
236 | |||
237 | case OP_LHAU: | ||
238 | emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1); | ||
239 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
240 | break; | ||
241 | |||
242 | case OP_STH: | ||
243 | emulated = kvmppc_handle_store(run, vcpu, | ||
244 | kvmppc_get_gpr(vcpu, rs), | ||
245 | 2, 1); | ||
246 | break; | ||
247 | |||
248 | case OP_STHU: | ||
249 | emulated = kvmppc_handle_store(run, vcpu, | ||
250 | kvmppc_get_gpr(vcpu, rs), | ||
251 | 2, 1); | ||
252 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
253 | break; | ||
254 | |||
255 | default: | ||
256 | emulated = EMULATE_FAIL; | ||
257 | break; | ||
258 | } | ||
259 | |||
260 | if (emulated == EMULATE_FAIL) { | ||
261 | advance = 0; | ||
262 | kvmppc_core_queue_program(vcpu, 0); | ||
263 | } | ||
264 | |||
265 | trace_kvm_ppc_instr(inst, kvmppc_get_pc(vcpu), emulated); | ||
266 | |||
267 | /* Advance past emulated instruction. */ | ||
268 | if (advance) | ||
269 | kvmppc_set_pc(vcpu, kvmppc_get_pc(vcpu) + 4); | ||
270 | |||
271 | return emulated; | ||
272 | } | ||
diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c index b68d0dc9479a..39b3a8f816f2 100644 --- a/arch/powerpc/kvm/mpic.c +++ b/arch/powerpc/kvm/mpic.c | |||
@@ -1826,8 +1826,7 @@ int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, | |||
1826 | return 0; | 1826 | return 0; |
1827 | } | 1827 | } |
1828 | 1828 | ||
1829 | int kvm_set_routing_entry(struct kvm_irq_routing_table *rt, | 1829 | int kvm_set_routing_entry(struct kvm_kernel_irq_routing_entry *e, |
1830 | struct kvm_kernel_irq_routing_entry *e, | ||
1831 | const struct kvm_irq_routing_entry *ue) | 1830 | const struct kvm_irq_routing_entry *ue) |
1832 | { | 1831 | { |
1833 | int r = -EINVAL; | 1832 | int r = -EINVAL; |
@@ -1839,7 +1838,6 @@ int kvm_set_routing_entry(struct kvm_irq_routing_table *rt, | |||
1839 | e->irqchip.pin = ue->u.irqchip.pin; | 1838 | e->irqchip.pin = ue->u.irqchip.pin; |
1840 | if (e->irqchip.pin >= KVM_IRQCHIP_NUM_PINS) | 1839 | if (e->irqchip.pin >= KVM_IRQCHIP_NUM_PINS) |
1841 | goto out; | 1840 | goto out; |
1842 | rt->chip[ue->u.irqchip.irqchip][e->irqchip.pin] = ue->gsi; | ||
1843 | break; | 1841 | break; |
1844 | case KVM_IRQ_ROUTING_MSI: | 1842 | case KVM_IRQ_ROUTING_MSI: |
1845 | e->set = kvm_set_msi; | 1843 | e->set = kvm_set_msi; |
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 61c738ab1283..4c79284b58be 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c | |||
@@ -190,6 +190,25 @@ int kvmppc_kvm_pv(struct kvm_vcpu *vcpu) | |||
190 | vcpu->arch.magic_page_pa = param1 & ~0xfffULL; | 190 | vcpu->arch.magic_page_pa = param1 & ~0xfffULL; |
191 | vcpu->arch.magic_page_ea = param2 & ~0xfffULL; | 191 | vcpu->arch.magic_page_ea = param2 & ~0xfffULL; |
192 | 192 | ||
193 | #ifdef CONFIG_PPC_64K_PAGES | ||
194 | /* | ||
195 | * Make sure our 4k magic page is in the same window of a 64k | ||
196 | * page within the guest and within the host's page. | ||
197 | */ | ||
198 | if ((vcpu->arch.magic_page_pa & 0xf000) != | ||
199 | ((ulong)vcpu->arch.shared & 0xf000)) { | ||
200 | void *old_shared = vcpu->arch.shared; | ||
201 | ulong shared = (ulong)vcpu->arch.shared; | ||
202 | void *new_shared; | ||
203 | |||
204 | shared &= PAGE_MASK; | ||
205 | shared |= vcpu->arch.magic_page_pa & 0xf000; | ||
206 | new_shared = (void*)shared; | ||
207 | memcpy(new_shared, old_shared, 0x1000); | ||
208 | vcpu->arch.shared = new_shared; | ||
209 | } | ||
210 | #endif | ||
211 | |||
193 | r2 = KVM_MAGIC_FEAT_SR | KVM_MAGIC_FEAT_MAS0_TO_SPRG7; | 212 | r2 = KVM_MAGIC_FEAT_SR | KVM_MAGIC_FEAT_MAS0_TO_SPRG7; |
194 | 213 | ||
195 | r = EV_SUCCESS; | 214 | r = EV_SUCCESS; |
@@ -198,7 +217,6 @@ int kvmppc_kvm_pv(struct kvm_vcpu *vcpu) | |||
198 | case KVM_HCALL_TOKEN(KVM_HC_FEATURES): | 217 | case KVM_HCALL_TOKEN(KVM_HC_FEATURES): |
199 | r = EV_SUCCESS; | 218 | r = EV_SUCCESS; |
200 | #if defined(CONFIG_PPC_BOOK3S) || defined(CONFIG_KVM_E500V2) | 219 | #if defined(CONFIG_PPC_BOOK3S) || defined(CONFIG_KVM_E500V2) |
201 | /* XXX Missing magic page on 44x */ | ||
202 | r2 |= (1 << KVM_FEATURE_MAGIC_PAGE); | 220 | r2 |= (1 << KVM_FEATURE_MAGIC_PAGE); |
203 | #endif | 221 | #endif |
204 | 222 | ||
@@ -254,13 +272,16 @@ int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
254 | enum emulation_result er; | 272 | enum emulation_result er; |
255 | int r; | 273 | int r; |
256 | 274 | ||
257 | er = kvmppc_emulate_instruction(run, vcpu); | 275 | er = kvmppc_emulate_loadstore(vcpu); |
258 | switch (er) { | 276 | switch (er) { |
259 | case EMULATE_DONE: | 277 | case EMULATE_DONE: |
260 | /* Future optimization: only reload non-volatiles if they were | 278 | /* Future optimization: only reload non-volatiles if they were |
261 | * actually modified. */ | 279 | * actually modified. */ |
262 | r = RESUME_GUEST_NV; | 280 | r = RESUME_GUEST_NV; |
263 | break; | 281 | break; |
282 | case EMULATE_AGAIN: | ||
283 | r = RESUME_GUEST; | ||
284 | break; | ||
264 | case EMULATE_DO_MMIO: | 285 | case EMULATE_DO_MMIO: |
265 | run->exit_reason = KVM_EXIT_MMIO; | 286 | run->exit_reason = KVM_EXIT_MMIO; |
266 | /* We must reload nonvolatiles because "update" load/store | 287 | /* We must reload nonvolatiles because "update" load/store |
@@ -270,11 +291,15 @@ int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
270 | r = RESUME_HOST_NV; | 291 | r = RESUME_HOST_NV; |
271 | break; | 292 | break; |
272 | case EMULATE_FAIL: | 293 | case EMULATE_FAIL: |
294 | { | ||
295 | u32 last_inst; | ||
296 | |||
297 | kvmppc_get_last_inst(vcpu, false, &last_inst); | ||
273 | /* XXX Deliver Program interrupt to guest. */ | 298 | /* XXX Deliver Program interrupt to guest. */ |
274 | printk(KERN_EMERG "%s: emulation failed (%08x)\n", __func__, | 299 | pr_emerg("%s: emulation failed (%08x)\n", __func__, last_inst); |
275 | kvmppc_get_last_inst(vcpu)); | ||
276 | r = RESUME_HOST; | 300 | r = RESUME_HOST; |
277 | break; | 301 | break; |
302 | } | ||
278 | default: | 303 | default: |
279 | WARN_ON(1); | 304 | WARN_ON(1); |
280 | r = RESUME_GUEST; | 305 | r = RESUME_GUEST; |
@@ -284,6 +309,81 @@ int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
284 | } | 309 | } |
285 | EXPORT_SYMBOL_GPL(kvmppc_emulate_mmio); | 310 | EXPORT_SYMBOL_GPL(kvmppc_emulate_mmio); |
286 | 311 | ||
312 | int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, | ||
313 | bool data) | ||
314 | { | ||
315 | ulong mp_pa = vcpu->arch.magic_page_pa & KVM_PAM & PAGE_MASK; | ||
316 | struct kvmppc_pte pte; | ||
317 | int r; | ||
318 | |||
319 | vcpu->stat.st++; | ||
320 | |||
321 | r = kvmppc_xlate(vcpu, *eaddr, data ? XLATE_DATA : XLATE_INST, | ||
322 | XLATE_WRITE, &pte); | ||
323 | if (r < 0) | ||
324 | return r; | ||
325 | |||
326 | *eaddr = pte.raddr; | ||
327 | |||
328 | if (!pte.may_write) | ||
329 | return -EPERM; | ||
330 | |||
331 | /* Magic page override */ | ||
332 | if (kvmppc_supports_magic_page(vcpu) && mp_pa && | ||
333 | ((pte.raddr & KVM_PAM & PAGE_MASK) == mp_pa) && | ||
334 | !(kvmppc_get_msr(vcpu) & MSR_PR)) { | ||
335 | void *magic = vcpu->arch.shared; | ||
336 | magic += pte.eaddr & 0xfff; | ||
337 | memcpy(magic, ptr, size); | ||
338 | return EMULATE_DONE; | ||
339 | } | ||
340 | |||
341 | if (kvm_write_guest(vcpu->kvm, pte.raddr, ptr, size)) | ||
342 | return EMULATE_DO_MMIO; | ||
343 | |||
344 | return EMULATE_DONE; | ||
345 | } | ||
346 | EXPORT_SYMBOL_GPL(kvmppc_st); | ||
347 | |||
348 | int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, | ||
349 | bool data) | ||
350 | { | ||
351 | ulong mp_pa = vcpu->arch.magic_page_pa & KVM_PAM & PAGE_MASK; | ||
352 | struct kvmppc_pte pte; | ||
353 | int rc; | ||
354 | |||
355 | vcpu->stat.ld++; | ||
356 | |||
357 | rc = kvmppc_xlate(vcpu, *eaddr, data ? XLATE_DATA : XLATE_INST, | ||
358 | XLATE_READ, &pte); | ||
359 | if (rc) | ||
360 | return rc; | ||
361 | |||
362 | *eaddr = pte.raddr; | ||
363 | |||
364 | if (!pte.may_read) | ||
365 | return -EPERM; | ||
366 | |||
367 | if (!data && !pte.may_execute) | ||
368 | return -ENOEXEC; | ||
369 | |||
370 | /* Magic page override */ | ||
371 | if (kvmppc_supports_magic_page(vcpu) && mp_pa && | ||
372 | ((pte.raddr & KVM_PAM & PAGE_MASK) == mp_pa) && | ||
373 | !(kvmppc_get_msr(vcpu) & MSR_PR)) { | ||
374 | void *magic = vcpu->arch.shared; | ||
375 | magic += pte.eaddr & 0xfff; | ||
376 | memcpy(ptr, magic, size); | ||
377 | return EMULATE_DONE; | ||
378 | } | ||
379 | |||
380 | if (kvm_read_guest(vcpu->kvm, pte.raddr, ptr, size)) | ||
381 | return EMULATE_DO_MMIO; | ||
382 | |||
383 | return EMULATE_DONE; | ||
384 | } | ||
385 | EXPORT_SYMBOL_GPL(kvmppc_ld); | ||
386 | |||
287 | int kvm_arch_hardware_enable(void *garbage) | 387 | int kvm_arch_hardware_enable(void *garbage) |
288 | { | 388 | { |
289 | return 0; | 389 | return 0; |
@@ -366,14 +466,20 @@ void kvm_arch_sync_events(struct kvm *kvm) | |||
366 | { | 466 | { |
367 | } | 467 | } |
368 | 468 | ||
369 | int kvm_dev_ioctl_check_extension(long ext) | 469 | int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) |
370 | { | 470 | { |
371 | int r; | 471 | int r; |
372 | /* FIXME!! | 472 | /* Assume we're using HV mode when the HV module is loaded */ |
373 | * Should some of this be vm ioctl ? is it possible now ? | ||
374 | */ | ||
375 | int hv_enabled = kvmppc_hv_ops ? 1 : 0; | 473 | int hv_enabled = kvmppc_hv_ops ? 1 : 0; |
376 | 474 | ||
475 | if (kvm) { | ||
476 | /* | ||
477 | * Hooray - we know which VM type we're running on. Depend on | ||
478 | * that rather than the guess above. | ||
479 | */ | ||
480 | hv_enabled = is_kvmppc_hv_enabled(kvm); | ||
481 | } | ||
482 | |||
377 | switch (ext) { | 483 | switch (ext) { |
378 | #ifdef CONFIG_BOOKE | 484 | #ifdef CONFIG_BOOKE |
379 | case KVM_CAP_PPC_BOOKE_SREGS: | 485 | case KVM_CAP_PPC_BOOKE_SREGS: |
@@ -387,6 +493,7 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
387 | case KVM_CAP_PPC_UNSET_IRQ: | 493 | case KVM_CAP_PPC_UNSET_IRQ: |
388 | case KVM_CAP_PPC_IRQ_LEVEL: | 494 | case KVM_CAP_PPC_IRQ_LEVEL: |
389 | case KVM_CAP_ENABLE_CAP: | 495 | case KVM_CAP_ENABLE_CAP: |
496 | case KVM_CAP_ENABLE_CAP_VM: | ||
390 | case KVM_CAP_ONE_REG: | 497 | case KVM_CAP_ONE_REG: |
391 | case KVM_CAP_IOEVENTFD: | 498 | case KVM_CAP_IOEVENTFD: |
392 | case KVM_CAP_DEVICE_CTRL: | 499 | case KVM_CAP_DEVICE_CTRL: |
@@ -417,6 +524,7 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
417 | case KVM_CAP_PPC_ALLOC_HTAB: | 524 | case KVM_CAP_PPC_ALLOC_HTAB: |
418 | case KVM_CAP_PPC_RTAS: | 525 | case KVM_CAP_PPC_RTAS: |
419 | case KVM_CAP_PPC_FIXUP_HCALL: | 526 | case KVM_CAP_PPC_FIXUP_HCALL: |
527 | case KVM_CAP_PPC_ENABLE_HCALL: | ||
420 | #ifdef CONFIG_KVM_XICS | 528 | #ifdef CONFIG_KVM_XICS |
421 | case KVM_CAP_IRQ_XICS: | 529 | case KVM_CAP_IRQ_XICS: |
422 | #endif | 530 | #endif |
@@ -635,12 +743,6 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) | |||
635 | #endif | 743 | #endif |
636 | } | 744 | } |
637 | 745 | ||
638 | static void kvmppc_complete_dcr_load(struct kvm_vcpu *vcpu, | ||
639 | struct kvm_run *run) | ||
640 | { | ||
641 | kvmppc_set_gpr(vcpu, vcpu->arch.io_gpr, run->dcr.data); | ||
642 | } | ||
643 | |||
644 | static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu, | 746 | static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu, |
645 | struct kvm_run *run) | 747 | struct kvm_run *run) |
646 | { | 748 | { |
@@ -837,10 +939,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
837 | if (!vcpu->mmio_is_write) | 939 | if (!vcpu->mmio_is_write) |
838 | kvmppc_complete_mmio_load(vcpu, run); | 940 | kvmppc_complete_mmio_load(vcpu, run); |
839 | vcpu->mmio_needed = 0; | 941 | vcpu->mmio_needed = 0; |
840 | } else if (vcpu->arch.dcr_needed) { | ||
841 | if (!vcpu->arch.dcr_is_write) | ||
842 | kvmppc_complete_dcr_load(vcpu, run); | ||
843 | vcpu->arch.dcr_needed = 0; | ||
844 | } else if (vcpu->arch.osi_needed) { | 942 | } else if (vcpu->arch.osi_needed) { |
845 | u64 *gprs = run->osi.gprs; | 943 | u64 *gprs = run->osi.gprs; |
846 | int i; | 944 | int i; |
@@ -1099,6 +1197,42 @@ int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_event, | |||
1099 | return 0; | 1197 | return 0; |
1100 | } | 1198 | } |
1101 | 1199 | ||
1200 | |||
1201 | static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, | ||
1202 | struct kvm_enable_cap *cap) | ||
1203 | { | ||
1204 | int r; | ||
1205 | |||
1206 | if (cap->flags) | ||
1207 | return -EINVAL; | ||
1208 | |||
1209 | switch (cap->cap) { | ||
1210 | #ifdef CONFIG_KVM_BOOK3S_64_HANDLER | ||
1211 | case KVM_CAP_PPC_ENABLE_HCALL: { | ||
1212 | unsigned long hcall = cap->args[0]; | ||
1213 | |||
1214 | r = -EINVAL; | ||
1215 | if (hcall > MAX_HCALL_OPCODE || (hcall & 3) || | ||
1216 | cap->args[1] > 1) | ||
1217 | break; | ||
1218 | if (!kvmppc_book3s_hcall_implemented(kvm, hcall)) | ||
1219 | break; | ||
1220 | if (cap->args[1]) | ||
1221 | set_bit(hcall / 4, kvm->arch.enabled_hcalls); | ||
1222 | else | ||
1223 | clear_bit(hcall / 4, kvm->arch.enabled_hcalls); | ||
1224 | r = 0; | ||
1225 | break; | ||
1226 | } | ||
1227 | #endif | ||
1228 | default: | ||
1229 | r = -EINVAL; | ||
1230 | break; | ||
1231 | } | ||
1232 | |||
1233 | return r; | ||
1234 | } | ||
1235 | |||
1102 | long kvm_arch_vm_ioctl(struct file *filp, | 1236 | long kvm_arch_vm_ioctl(struct file *filp, |
1103 | unsigned int ioctl, unsigned long arg) | 1237 | unsigned int ioctl, unsigned long arg) |
1104 | { | 1238 | { |
@@ -1118,6 +1252,15 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
1118 | 1252 | ||
1119 | break; | 1253 | break; |
1120 | } | 1254 | } |
1255 | case KVM_ENABLE_CAP: | ||
1256 | { | ||
1257 | struct kvm_enable_cap cap; | ||
1258 | r = -EFAULT; | ||
1259 | if (copy_from_user(&cap, argp, sizeof(cap))) | ||
1260 | goto out; | ||
1261 | r = kvm_vm_ioctl_enable_cap(kvm, &cap); | ||
1262 | break; | ||
1263 | } | ||
1121 | #ifdef CONFIG_PPC_BOOK3S_64 | 1264 | #ifdef CONFIG_PPC_BOOK3S_64 |
1122 | case KVM_CREATE_SPAPR_TCE: { | 1265 | case KVM_CREATE_SPAPR_TCE: { |
1123 | struct kvm_create_spapr_tce create_tce; | 1266 | struct kvm_create_spapr_tce create_tce; |
@@ -1204,3 +1347,5 @@ void kvm_arch_exit(void) | |||
1204 | { | 1347 | { |
1205 | 1348 | ||
1206 | } | 1349 | } |
1350 | |||
1351 | EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_ppc_instr); | ||
diff --git a/arch/powerpc/kvm/timing.c b/arch/powerpc/kvm/timing.c index 07b6110a4bb7..e44d2b2ea97e 100644 --- a/arch/powerpc/kvm/timing.c +++ b/arch/powerpc/kvm/timing.c | |||
@@ -110,7 +110,6 @@ void kvmppc_update_timing_stats(struct kvm_vcpu *vcpu) | |||
110 | 110 | ||
111 | static const char *kvm_exit_names[__NUMBER_OF_KVM_EXIT_TYPES] = { | 111 | static const char *kvm_exit_names[__NUMBER_OF_KVM_EXIT_TYPES] = { |
112 | [MMIO_EXITS] = "MMIO", | 112 | [MMIO_EXITS] = "MMIO", |
113 | [DCR_EXITS] = "DCR", | ||
114 | [SIGNAL_EXITS] = "SIGNAL", | 113 | [SIGNAL_EXITS] = "SIGNAL", |
115 | [ITLB_REAL_MISS_EXITS] = "ITLBREAL", | 114 | [ITLB_REAL_MISS_EXITS] = "ITLBREAL", |
116 | [ITLB_VIRT_MISS_EXITS] = "ITLBVIRT", | 115 | [ITLB_VIRT_MISS_EXITS] = "ITLBVIRT", |
diff --git a/arch/powerpc/kvm/timing.h b/arch/powerpc/kvm/timing.h index bf191e72b2d8..3123690c82dc 100644 --- a/arch/powerpc/kvm/timing.h +++ b/arch/powerpc/kvm/timing.h | |||
@@ -63,9 +63,6 @@ static inline void kvmppc_account_exit_stat(struct kvm_vcpu *vcpu, int type) | |||
63 | case EMULATED_INST_EXITS: | 63 | case EMULATED_INST_EXITS: |
64 | vcpu->stat.emulated_inst_exits++; | 64 | vcpu->stat.emulated_inst_exits++; |
65 | break; | 65 | break; |
66 | case DCR_EXITS: | ||
67 | vcpu->stat.dcr_exits++; | ||
68 | break; | ||
69 | case DSI_EXITS: | 66 | case DSI_EXITS: |
70 | vcpu->stat.dsi_exits++; | 67 | vcpu->stat.dsi_exits++; |
71 | break; | 68 | break; |
diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig index 10d529ac9821..646db9c467d1 100644 --- a/arch/s390/kvm/Kconfig +++ b/arch/s390/kvm/Kconfig | |||
@@ -26,6 +26,7 @@ config KVM | |||
26 | select KVM_ASYNC_PF | 26 | select KVM_ASYNC_PF |
27 | select KVM_ASYNC_PF_SYNC | 27 | select KVM_ASYNC_PF_SYNC |
28 | select HAVE_KVM_IRQCHIP | 28 | select HAVE_KVM_IRQCHIP |
29 | select HAVE_KVM_IRQFD | ||
29 | select HAVE_KVM_IRQ_ROUTING | 30 | select HAVE_KVM_IRQ_ROUTING |
30 | ---help--- | 31 | ---help--- |
31 | Support hosting paravirtualized guest machines using the SIE | 32 | Support hosting paravirtualized guest machines using the SIE |
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 92528a0bdda6..f4c819bfc193 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c | |||
@@ -1556,8 +1556,7 @@ static int set_adapter_int(struct kvm_kernel_irq_routing_entry *e, | |||
1556 | return ret; | 1556 | return ret; |
1557 | } | 1557 | } |
1558 | 1558 | ||
1559 | int kvm_set_routing_entry(struct kvm_irq_routing_table *rt, | 1559 | int kvm_set_routing_entry(struct kvm_kernel_irq_routing_entry *e, |
1560 | struct kvm_kernel_irq_routing_entry *e, | ||
1561 | const struct kvm_irq_routing_entry *ue) | 1560 | const struct kvm_irq_routing_entry *ue) |
1562 | { | 1561 | { |
1563 | int ret; | 1562 | int ret; |
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 339b34a02fb8..ce81eb2ab76a 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
@@ -146,7 +146,7 @@ long kvm_arch_dev_ioctl(struct file *filp, | |||
146 | return -EINVAL; | 146 | return -EINVAL; |
147 | } | 147 | } |
148 | 148 | ||
149 | int kvm_dev_ioctl_check_extension(long ext) | 149 | int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) |
150 | { | 150 | { |
151 | int r; | 151 | int r; |
152 | 152 | ||
diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig index 287e4c85fff9..f9d16ff56c6b 100644 --- a/arch/x86/kvm/Kconfig +++ b/arch/x86/kvm/Kconfig | |||
@@ -27,6 +27,7 @@ config KVM | |||
27 | select MMU_NOTIFIER | 27 | select MMU_NOTIFIER |
28 | select ANON_INODES | 28 | select ANON_INODES |
29 | select HAVE_KVM_IRQCHIP | 29 | select HAVE_KVM_IRQCHIP |
30 | select HAVE_KVM_IRQFD | ||
30 | select HAVE_KVM_IRQ_ROUTING | 31 | select HAVE_KVM_IRQ_ROUTING |
31 | select HAVE_KVM_EVENTFD | 32 | select HAVE_KVM_EVENTFD |
32 | select KVM_APIC_ARCHITECTURE | 33 | select KVM_APIC_ARCHITECTURE |
diff --git a/arch/x86/kvm/irq.c b/arch/x86/kvm/irq.c index bd0da433e6d7..a1ec6a50a05a 100644 --- a/arch/x86/kvm/irq.c +++ b/arch/x86/kvm/irq.c | |||
@@ -108,7 +108,7 @@ int kvm_cpu_get_interrupt(struct kvm_vcpu *v) | |||
108 | 108 | ||
109 | vector = kvm_cpu_get_extint(v); | 109 | vector = kvm_cpu_get_extint(v); |
110 | 110 | ||
111 | if (kvm_apic_vid_enabled(v->kvm) || vector != -1) | 111 | if (vector != -1) |
112 | return vector; /* PIC */ | 112 | return vector; /* PIC */ |
113 | 113 | ||
114 | return kvm_get_apic_interrupt(v); /* APIC */ | 114 | return kvm_get_apic_interrupt(v); /* APIC */ |
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 3855103f71fd..08e8a899e005 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c | |||
@@ -352,25 +352,46 @@ static inline int apic_find_highest_irr(struct kvm_lapic *apic) | |||
352 | 352 | ||
353 | static inline void apic_clear_irr(int vec, struct kvm_lapic *apic) | 353 | static inline void apic_clear_irr(int vec, struct kvm_lapic *apic) |
354 | { | 354 | { |
355 | apic->irr_pending = false; | 355 | struct kvm_vcpu *vcpu; |
356 | |||
357 | vcpu = apic->vcpu; | ||
358 | |||
356 | apic_clear_vector(vec, apic->regs + APIC_IRR); | 359 | apic_clear_vector(vec, apic->regs + APIC_IRR); |
357 | if (apic_search_irr(apic) != -1) | 360 | if (unlikely(kvm_apic_vid_enabled(vcpu->kvm))) |
358 | apic->irr_pending = true; | 361 | /* try to update RVI */ |
362 | kvm_make_request(KVM_REQ_EVENT, vcpu); | ||
363 | else { | ||
364 | vec = apic_search_irr(apic); | ||
365 | apic->irr_pending = (vec != -1); | ||
366 | } | ||
359 | } | 367 | } |
360 | 368 | ||
361 | static inline void apic_set_isr(int vec, struct kvm_lapic *apic) | 369 | static inline void apic_set_isr(int vec, struct kvm_lapic *apic) |
362 | { | 370 | { |
363 | /* Note that we never get here with APIC virtualization enabled. */ | 371 | struct kvm_vcpu *vcpu; |
372 | |||
373 | if (__apic_test_and_set_vector(vec, apic->regs + APIC_ISR)) | ||
374 | return; | ||
375 | |||
376 | vcpu = apic->vcpu; | ||
364 | 377 | ||
365 | if (!__apic_test_and_set_vector(vec, apic->regs + APIC_ISR)) | ||
366 | ++apic->isr_count; | ||
367 | BUG_ON(apic->isr_count > MAX_APIC_VECTOR); | ||
368 | /* | 378 | /* |
369 | * ISR (in service register) bit is set when injecting an interrupt. | 379 | * With APIC virtualization enabled, all caching is disabled |
370 | * The highest vector is injected. Thus the latest bit set matches | 380 | * because the processor can modify ISR under the hood. Instead |
371 | * the highest bit in ISR. | 381 | * just set SVI. |
372 | */ | 382 | */ |
373 | apic->highest_isr_cache = vec; | 383 | if (unlikely(kvm_apic_vid_enabled(vcpu->kvm))) |
384 | kvm_x86_ops->hwapic_isr_update(vcpu->kvm, vec); | ||
385 | else { | ||
386 | ++apic->isr_count; | ||
387 | BUG_ON(apic->isr_count > MAX_APIC_VECTOR); | ||
388 | /* | ||
389 | * ISR (in service register) bit is set when injecting an interrupt. | ||
390 | * The highest vector is injected. Thus the latest bit set matches | ||
391 | * the highest bit in ISR. | ||
392 | */ | ||
393 | apic->highest_isr_cache = vec; | ||
394 | } | ||
374 | } | 395 | } |
375 | 396 | ||
376 | static inline int apic_find_highest_isr(struct kvm_lapic *apic) | 397 | static inline int apic_find_highest_isr(struct kvm_lapic *apic) |
@@ -1627,11 +1648,16 @@ int kvm_get_apic_interrupt(struct kvm_vcpu *vcpu) | |||
1627 | int vector = kvm_apic_has_interrupt(vcpu); | 1648 | int vector = kvm_apic_has_interrupt(vcpu); |
1628 | struct kvm_lapic *apic = vcpu->arch.apic; | 1649 | struct kvm_lapic *apic = vcpu->arch.apic; |
1629 | 1650 | ||
1630 | /* Note that we never get here with APIC virtualization enabled. */ | ||
1631 | |||
1632 | if (vector == -1) | 1651 | if (vector == -1) |
1633 | return -1; | 1652 | return -1; |
1634 | 1653 | ||
1654 | /* | ||
1655 | * We get here even with APIC virtualization enabled, if doing | ||
1656 | * nested virtualization and L1 runs with the "acknowledge interrupt | ||
1657 | * on exit" mode. Then we cannot inject the interrupt via RVI, | ||
1658 | * because the process would deliver it through the IDT. | ||
1659 | */ | ||
1660 | |||
1635 | apic_set_isr(vector, apic); | 1661 | apic_set_isr(vector, apic); |
1636 | apic_update_ppr(apic); | 1662 | apic_update_ppr(apic); |
1637 | apic_clear_irr(vector, apic); | 1663 | apic_clear_irr(vector, apic); |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index e618f34bde2d..bfe11cf124a1 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -8754,6 +8754,8 @@ static void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason, | |||
8754 | prepare_vmcs12(vcpu, vmcs12, exit_reason, exit_intr_info, | 8754 | prepare_vmcs12(vcpu, vmcs12, exit_reason, exit_intr_info, |
8755 | exit_qualification); | 8755 | exit_qualification); |
8756 | 8756 | ||
8757 | vmx_load_vmcs01(vcpu); | ||
8758 | |||
8757 | if ((exit_reason == EXIT_REASON_EXTERNAL_INTERRUPT) | 8759 | if ((exit_reason == EXIT_REASON_EXTERNAL_INTERRUPT) |
8758 | && nested_exit_intr_ack_set(vcpu)) { | 8760 | && nested_exit_intr_ack_set(vcpu)) { |
8759 | int irq = kvm_cpu_get_interrupt(vcpu); | 8761 | int irq = kvm_cpu_get_interrupt(vcpu); |
@@ -8769,8 +8771,6 @@ static void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason, | |||
8769 | vmcs12->vm_exit_intr_error_code, | 8771 | vmcs12->vm_exit_intr_error_code, |
8770 | KVM_ISA_VMX); | 8772 | KVM_ISA_VMX); |
8771 | 8773 | ||
8772 | vmx_load_vmcs01(vcpu); | ||
8773 | |||
8774 | vm_entry_controls_init(vmx, vmcs_read32(VM_ENTRY_CONTROLS)); | 8774 | vm_entry_controls_init(vmx, vmcs_read32(VM_ENTRY_CONTROLS)); |
8775 | vm_exit_controls_init(vmx, vmcs_read32(VM_EXIT_CONTROLS)); | 8775 | vm_exit_controls_init(vmx, vmcs_read32(VM_EXIT_CONTROLS)); |
8776 | vmx_segment_cache_clear(vmx); | 8776 | vmx_segment_cache_clear(vmx); |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index ca3d760dd581..8f1e22d3b286 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -2636,7 +2636,7 @@ out: | |||
2636 | return r; | 2636 | return r; |
2637 | } | 2637 | } |
2638 | 2638 | ||
2639 | int kvm_dev_ioctl_check_extension(long ext) | 2639 | int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) |
2640 | { | 2640 | { |
2641 | int r; | 2641 | int r; |
2642 | 2642 | ||