diff options
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/include/asm/kvm_book3s.h | 6 | ||||
-rw-r--r-- | arch/powerpc/kvm/Makefile | 13 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_64_mmu.c | 81 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_64_mmu_host.c | 21 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_64_slb.S | 13 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_pr.c | 3 | ||||
-rw-r--r-- | arch/powerpc/kvm/booke.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kvm/emulate.c | 3 |
8 files changed, 89 insertions, 53 deletions
diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index 349ed85c7d61..08891d07aeb6 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h | |||
@@ -107,8 +107,9 @@ struct kvmppc_vcpu_book3s { | |||
107 | #define CONTEXT_GUEST 1 | 107 | #define CONTEXT_GUEST 1 |
108 | #define CONTEXT_GUEST_END 2 | 108 | #define CONTEXT_GUEST_END 2 |
109 | 109 | ||
110 | #define VSID_REAL 0x1fffffffffc00000ULL | 110 | #define VSID_REAL 0x0fffffffffc00000ULL |
111 | #define VSID_BAT 0x1fffffffffb00000ULL | 111 | #define VSID_BAT 0x0fffffffffb00000ULL |
112 | #define VSID_1T 0x1000000000000000ULL | ||
112 | #define VSID_REAL_DR 0x2000000000000000ULL | 113 | #define VSID_REAL_DR 0x2000000000000000ULL |
113 | #define VSID_REAL_IR 0x4000000000000000ULL | 114 | #define VSID_REAL_IR 0x4000000000000000ULL |
114 | #define VSID_PR 0x8000000000000000ULL | 115 | #define VSID_PR 0x8000000000000000ULL |
@@ -123,6 +124,7 @@ extern void kvmppc_mmu_book3s_32_init(struct kvm_vcpu *vcpu); | |||
123 | extern void kvmppc_mmu_book3s_hv_init(struct kvm_vcpu *vcpu); | 124 | extern void kvmppc_mmu_book3s_hv_init(struct kvm_vcpu *vcpu); |
124 | extern int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte); | 125 | extern int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte); |
125 | extern int kvmppc_mmu_map_segment(struct kvm_vcpu *vcpu, ulong eaddr); | 126 | extern int kvmppc_mmu_map_segment(struct kvm_vcpu *vcpu, ulong eaddr); |
127 | extern void kvmppc_mmu_flush_segment(struct kvm_vcpu *vcpu, ulong eaddr, ulong seg_size); | ||
126 | extern void kvmppc_mmu_flush_segments(struct kvm_vcpu *vcpu); | 128 | extern void kvmppc_mmu_flush_segments(struct kvm_vcpu *vcpu); |
127 | extern int kvmppc_book3s_hv_page_fault(struct kvm_run *run, | 129 | extern int kvmppc_book3s_hv_page_fault(struct kvm_run *run, |
128 | struct kvm_vcpu *vcpu, unsigned long addr, | 130 | struct kvm_vcpu *vcpu, unsigned long addr, |
diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile index 422de3f4d46c..008cd856c5b5 100644 --- a/arch/powerpc/kvm/Makefile +++ b/arch/powerpc/kvm/Makefile | |||
@@ -5,9 +5,10 @@ | |||
5 | subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror | 5 | subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror |
6 | 6 | ||
7 | ccflags-y := -Ivirt/kvm -Iarch/powerpc/kvm | 7 | ccflags-y := -Ivirt/kvm -Iarch/powerpc/kvm |
8 | KVM := ../../../virt/kvm | ||
8 | 9 | ||
9 | common-objs-y = $(addprefix ../../../virt/kvm/, kvm_main.o coalesced_mmio.o \ | 10 | common-objs-y = $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o \ |
10 | eventfd.o) | 11 | $(KVM)/eventfd.o |
11 | 12 | ||
12 | CFLAGS_44x_tlb.o := -I. | 13 | CFLAGS_44x_tlb.o := -I. |
13 | CFLAGS_e500_mmu.o := -I. | 14 | CFLAGS_e500_mmu.o := -I. |
@@ -53,7 +54,7 @@ kvm-e500mc-objs := \ | |||
53 | kvm-objs-$(CONFIG_KVM_E500MC) := $(kvm-e500mc-objs) | 54 | kvm-objs-$(CONFIG_KVM_E500MC) := $(kvm-e500mc-objs) |
54 | 55 | ||
55 | kvm-book3s_64-objs-$(CONFIG_KVM_BOOK3S_64_PR) := \ | 56 | kvm-book3s_64-objs-$(CONFIG_KVM_BOOK3S_64_PR) := \ |
56 | ../../../virt/kvm/coalesced_mmio.o \ | 57 | $(KVM)/coalesced_mmio.o \ |
57 | fpu.o \ | 58 | fpu.o \ |
58 | book3s_paired_singles.o \ | 59 | book3s_paired_singles.o \ |
59 | book3s_pr.o \ | 60 | book3s_pr.o \ |
@@ -86,8 +87,8 @@ kvm-book3s_64-objs-$(CONFIG_KVM_XICS) += \ | |||
86 | book3s_xics.o | 87 | book3s_xics.o |
87 | 88 | ||
88 | kvm-book3s_64-module-objs := \ | 89 | kvm-book3s_64-module-objs := \ |
89 | ../../../virt/kvm/kvm_main.o \ | 90 | $(KVM)/kvm_main.o \ |
90 | ../../../virt/kvm/eventfd.o \ | 91 | $(KVM)/eventfd.o \ |
91 | powerpc.o \ | 92 | powerpc.o \ |
92 | emulate.o \ | 93 | emulate.o \ |
93 | book3s.o \ | 94 | book3s.o \ |
@@ -111,7 +112,7 @@ kvm-book3s_32-objs := \ | |||
111 | kvm-objs-$(CONFIG_KVM_BOOK3S_32) := $(kvm-book3s_32-objs) | 112 | kvm-objs-$(CONFIG_KVM_BOOK3S_32) := $(kvm-book3s_32-objs) |
112 | 113 | ||
113 | kvm-objs-$(CONFIG_KVM_MPIC) += mpic.o | 114 | kvm-objs-$(CONFIG_KVM_MPIC) += mpic.o |
114 | kvm-objs-$(CONFIG_HAVE_KVM_IRQ_ROUTING) += $(addprefix ../../../virt/kvm/, irqchip.o) | 115 | kvm-objs-$(CONFIG_HAVE_KVM_IRQ_ROUTING) += $(KVM)/irqchip.o |
115 | 116 | ||
116 | kvm-objs := $(kvm-objs-m) $(kvm-objs-y) | 117 | kvm-objs := $(kvm-objs-m) $(kvm-objs-y) |
117 | 118 | ||
diff --git a/arch/powerpc/kvm/book3s_64_mmu.c b/arch/powerpc/kvm/book3s_64_mmu.c index b871721c0050..739bfbadb85e 100644 --- a/arch/powerpc/kvm/book3s_64_mmu.c +++ b/arch/powerpc/kvm/book3s_64_mmu.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <asm/tlbflush.h> | 26 | #include <asm/tlbflush.h> |
27 | #include <asm/kvm_ppc.h> | 27 | #include <asm/kvm_ppc.h> |
28 | #include <asm/kvm_book3s.h> | 28 | #include <asm/kvm_book3s.h> |
29 | #include <asm/mmu-hash64.h> | ||
29 | 30 | ||
30 | /* #define DEBUG_MMU */ | 31 | /* #define DEBUG_MMU */ |
31 | 32 | ||
@@ -76,6 +77,24 @@ static struct kvmppc_slb *kvmppc_mmu_book3s_64_find_slbe( | |||
76 | return NULL; | 77 | return NULL; |
77 | } | 78 | } |
78 | 79 | ||
80 | static int kvmppc_slb_sid_shift(struct kvmppc_slb *slbe) | ||
81 | { | ||
82 | return slbe->tb ? SID_SHIFT_1T : SID_SHIFT; | ||
83 | } | ||
84 | |||
85 | static u64 kvmppc_slb_offset_mask(struct kvmppc_slb *slbe) | ||
86 | { | ||
87 | return (1ul << kvmppc_slb_sid_shift(slbe)) - 1; | ||
88 | } | ||
89 | |||
90 | static u64 kvmppc_slb_calc_vpn(struct kvmppc_slb *slb, gva_t eaddr) | ||
91 | { | ||
92 | eaddr &= kvmppc_slb_offset_mask(slb); | ||
93 | |||
94 | return (eaddr >> VPN_SHIFT) | | ||
95 | ((slb->vsid) << (kvmppc_slb_sid_shift(slb) - VPN_SHIFT)); | ||
96 | } | ||
97 | |||
79 | static u64 kvmppc_mmu_book3s_64_ea_to_vp(struct kvm_vcpu *vcpu, gva_t eaddr, | 98 | static u64 kvmppc_mmu_book3s_64_ea_to_vp(struct kvm_vcpu *vcpu, gva_t eaddr, |
80 | bool data) | 99 | bool data) |
81 | { | 100 | { |
@@ -85,11 +104,7 @@ static u64 kvmppc_mmu_book3s_64_ea_to_vp(struct kvm_vcpu *vcpu, gva_t eaddr, | |||
85 | if (!slb) | 104 | if (!slb) |
86 | return 0; | 105 | return 0; |
87 | 106 | ||
88 | if (slb->tb) | 107 | return kvmppc_slb_calc_vpn(slb, eaddr); |
89 | return (((u64)eaddr >> 12) & 0xfffffff) | | ||
90 | (((u64)slb->vsid) << 28); | ||
91 | |||
92 | return (((u64)eaddr >> 12) & 0xffff) | (((u64)slb->vsid) << 16); | ||
93 | } | 108 | } |
94 | 109 | ||
95 | static int kvmppc_mmu_book3s_64_get_pagesize(struct kvmppc_slb *slbe) | 110 | static int kvmppc_mmu_book3s_64_get_pagesize(struct kvmppc_slb *slbe) |
@@ -100,7 +115,8 @@ static int kvmppc_mmu_book3s_64_get_pagesize(struct kvmppc_slb *slbe) | |||
100 | static u32 kvmppc_mmu_book3s_64_get_page(struct kvmppc_slb *slbe, gva_t eaddr) | 115 | static u32 kvmppc_mmu_book3s_64_get_page(struct kvmppc_slb *slbe, gva_t eaddr) |
101 | { | 116 | { |
102 | int p = kvmppc_mmu_book3s_64_get_pagesize(slbe); | 117 | int p = kvmppc_mmu_book3s_64_get_pagesize(slbe); |
103 | return ((eaddr & 0xfffffff) >> p); | 118 | |
119 | return ((eaddr & kvmppc_slb_offset_mask(slbe)) >> p); | ||
104 | } | 120 | } |
105 | 121 | ||
106 | static hva_t kvmppc_mmu_book3s_64_get_pteg( | 122 | static hva_t kvmppc_mmu_book3s_64_get_pteg( |
@@ -109,13 +125,15 @@ static hva_t kvmppc_mmu_book3s_64_get_pteg( | |||
109 | bool second) | 125 | bool second) |
110 | { | 126 | { |
111 | u64 hash, pteg, htabsize; | 127 | u64 hash, pteg, htabsize; |
112 | u32 page; | 128 | u32 ssize; |
113 | hva_t r; | 129 | hva_t r; |
130 | u64 vpn; | ||
114 | 131 | ||
115 | page = kvmppc_mmu_book3s_64_get_page(slbe, eaddr); | ||
116 | htabsize = ((1 << ((vcpu_book3s->sdr1 & 0x1f) + 11)) - 1); | 132 | htabsize = ((1 << ((vcpu_book3s->sdr1 & 0x1f) + 11)) - 1); |
117 | 133 | ||
118 | hash = slbe->vsid ^ page; | 134 | vpn = kvmppc_slb_calc_vpn(slbe, eaddr); |
135 | ssize = slbe->tb ? MMU_SEGSIZE_1T : MMU_SEGSIZE_256M; | ||
136 | hash = hpt_hash(vpn, kvmppc_mmu_book3s_64_get_pagesize(slbe), ssize); | ||
119 | if (second) | 137 | if (second) |
120 | hash = ~hash; | 138 | hash = ~hash; |
121 | hash &= ((1ULL << 39ULL) - 1ULL); | 139 | hash &= ((1ULL << 39ULL) - 1ULL); |
@@ -146,7 +164,7 @@ static u64 kvmppc_mmu_book3s_64_get_avpn(struct kvmppc_slb *slbe, gva_t eaddr) | |||
146 | u64 avpn; | 164 | u64 avpn; |
147 | 165 | ||
148 | avpn = kvmppc_mmu_book3s_64_get_page(slbe, eaddr); | 166 | avpn = kvmppc_mmu_book3s_64_get_page(slbe, eaddr); |
149 | avpn |= slbe->vsid << (28 - p); | 167 | avpn |= slbe->vsid << (kvmppc_slb_sid_shift(slbe) - p); |
150 | 168 | ||
151 | if (p < 24) | 169 | if (p < 24) |
152 | avpn >>= ((80 - p) - 56) - 8; | 170 | avpn >>= ((80 - p) - 56) - 8; |
@@ -167,7 +185,6 @@ static int kvmppc_mmu_book3s_64_xlate(struct kvm_vcpu *vcpu, gva_t eaddr, | |||
167 | int i; | 185 | int i; |
168 | u8 key = 0; | 186 | u8 key = 0; |
169 | bool found = false; | 187 | bool found = false; |
170 | bool perm_err = false; | ||
171 | int second = 0; | 188 | int second = 0; |
172 | ulong mp_ea = vcpu->arch.magic_page_ea; | 189 | ulong mp_ea = vcpu->arch.magic_page_ea; |
173 | 190 | ||
@@ -190,13 +207,15 @@ static int kvmppc_mmu_book3s_64_xlate(struct kvm_vcpu *vcpu, gva_t eaddr, | |||
190 | if (!slbe) | 207 | if (!slbe) |
191 | goto no_seg_found; | 208 | goto no_seg_found; |
192 | 209 | ||
210 | avpn = kvmppc_mmu_book3s_64_get_avpn(slbe, eaddr); | ||
211 | if (slbe->tb) | ||
212 | avpn |= SLB_VSID_B_1T; | ||
213 | |||
193 | do_second: | 214 | do_second: |
194 | ptegp = kvmppc_mmu_book3s_64_get_pteg(vcpu_book3s, slbe, eaddr, second); | 215 | ptegp = kvmppc_mmu_book3s_64_get_pteg(vcpu_book3s, slbe, eaddr, second); |
195 | if (kvm_is_error_hva(ptegp)) | 216 | if (kvm_is_error_hva(ptegp)) |
196 | goto no_page_found; | 217 | goto no_page_found; |
197 | 218 | ||
198 | avpn = kvmppc_mmu_book3s_64_get_avpn(slbe, eaddr); | ||
199 | |||
200 | if(copy_from_user(pteg, (void __user *)ptegp, sizeof(pteg))) { | 219 | if(copy_from_user(pteg, (void __user *)ptegp, sizeof(pteg))) { |
201 | printk(KERN_ERR "KVM can't copy data from 0x%lx!\n", ptegp); | 220 | printk(KERN_ERR "KVM can't copy data from 0x%lx!\n", ptegp); |
202 | goto no_page_found; | 221 | goto no_page_found; |
@@ -219,7 +238,7 @@ do_second: | |||
219 | continue; | 238 | continue; |
220 | 239 | ||
221 | /* AVPN compare */ | 240 | /* AVPN compare */ |
222 | if (HPTE_V_AVPN_VAL(avpn) == HPTE_V_AVPN_VAL(v)) { | 241 | if (HPTE_V_COMPARE(avpn, v)) { |
223 | u8 pp = (r & HPTE_R_PP) | key; | 242 | u8 pp = (r & HPTE_R_PP) | key; |
224 | int eaddr_mask = 0xFFF; | 243 | int eaddr_mask = 0xFFF; |
225 | 244 | ||
@@ -248,11 +267,6 @@ do_second: | |||
248 | break; | 267 | break; |
249 | } | 268 | } |
250 | 269 | ||
251 | if (!gpte->may_read) { | ||
252 | perm_err = true; | ||
253 | continue; | ||
254 | } | ||
255 | |||
256 | dprintk("KVM MMU: Translated 0x%lx [0x%llx] -> 0x%llx " | 270 | dprintk("KVM MMU: Translated 0x%lx [0x%llx] -> 0x%llx " |
257 | "-> 0x%lx\n", | 271 | "-> 0x%lx\n", |
258 | eaddr, avpn, gpte->vpage, gpte->raddr); | 272 | eaddr, avpn, gpte->vpage, gpte->raddr); |
@@ -281,6 +295,8 @@ do_second: | |||
281 | if (pteg[i+1] != oldr) | 295 | if (pteg[i+1] != oldr) |
282 | copy_to_user((void __user *)ptegp, pteg, sizeof(pteg)); | 296 | copy_to_user((void __user *)ptegp, pteg, sizeof(pteg)); |
283 | 297 | ||
298 | if (!gpte->may_read) | ||
299 | return -EPERM; | ||
284 | return 0; | 300 | return 0; |
285 | } else { | 301 | } else { |
286 | dprintk("KVM MMU: No PTE found (ea=0x%lx sdr1=0x%llx " | 302 | dprintk("KVM MMU: No PTE found (ea=0x%lx sdr1=0x%llx " |
@@ -296,13 +312,7 @@ do_second: | |||
296 | } | 312 | } |
297 | } | 313 | } |
298 | 314 | ||
299 | |||
300 | no_page_found: | 315 | no_page_found: |
301 | |||
302 | |||
303 | if (perm_err) | ||
304 | return -EPERM; | ||
305 | |||
306 | return -ENOENT; | 316 | return -ENOENT; |
307 | 317 | ||
308 | no_seg_found: | 318 | no_seg_found: |
@@ -334,7 +344,7 @@ static void kvmppc_mmu_book3s_64_slbmte(struct kvm_vcpu *vcpu, u64 rs, u64 rb) | |||
334 | slbe->large = (rs & SLB_VSID_L) ? 1 : 0; | 344 | slbe->large = (rs & SLB_VSID_L) ? 1 : 0; |
335 | slbe->tb = (rs & SLB_VSID_B_1T) ? 1 : 0; | 345 | slbe->tb = (rs & SLB_VSID_B_1T) ? 1 : 0; |
336 | slbe->esid = slbe->tb ? esid_1t : esid; | 346 | slbe->esid = slbe->tb ? esid_1t : esid; |
337 | slbe->vsid = rs >> 12; | 347 | slbe->vsid = (rs & ~SLB_VSID_B) >> (kvmppc_slb_sid_shift(slbe) - 16); |
338 | slbe->valid = (rb & SLB_ESID_V) ? 1 : 0; | 348 | slbe->valid = (rb & SLB_ESID_V) ? 1 : 0; |
339 | slbe->Ks = (rs & SLB_VSID_KS) ? 1 : 0; | 349 | slbe->Ks = (rs & SLB_VSID_KS) ? 1 : 0; |
340 | slbe->Kp = (rs & SLB_VSID_KP) ? 1 : 0; | 350 | slbe->Kp = (rs & SLB_VSID_KP) ? 1 : 0; |
@@ -375,6 +385,7 @@ static u64 kvmppc_mmu_book3s_64_slbmfev(struct kvm_vcpu *vcpu, u64 slb_nr) | |||
375 | static void kvmppc_mmu_book3s_64_slbie(struct kvm_vcpu *vcpu, u64 ea) | 385 | static void kvmppc_mmu_book3s_64_slbie(struct kvm_vcpu *vcpu, u64 ea) |
376 | { | 386 | { |
377 | struct kvmppc_slb *slbe; | 387 | struct kvmppc_slb *slbe; |
388 | u64 seg_size; | ||
378 | 389 | ||
379 | dprintk("KVM MMU: slbie(0x%llx)\n", ea); | 390 | dprintk("KVM MMU: slbie(0x%llx)\n", ea); |
380 | 391 | ||
@@ -386,8 +397,11 @@ static void kvmppc_mmu_book3s_64_slbie(struct kvm_vcpu *vcpu, u64 ea) | |||
386 | dprintk("KVM MMU: slbie(0x%llx, 0x%llx)\n", ea, slbe->esid); | 397 | dprintk("KVM MMU: slbie(0x%llx, 0x%llx)\n", ea, slbe->esid); |
387 | 398 | ||
388 | slbe->valid = false; | 399 | slbe->valid = false; |
400 | slbe->orige = 0; | ||
401 | slbe->origv = 0; | ||
389 | 402 | ||
390 | kvmppc_mmu_map_segment(vcpu, ea); | 403 | seg_size = 1ull << kvmppc_slb_sid_shift(slbe); |
404 | kvmppc_mmu_flush_segment(vcpu, ea & ~(seg_size - 1), seg_size); | ||
391 | } | 405 | } |
392 | 406 | ||
393 | static void kvmppc_mmu_book3s_64_slbia(struct kvm_vcpu *vcpu) | 407 | static void kvmppc_mmu_book3s_64_slbia(struct kvm_vcpu *vcpu) |
@@ -396,8 +410,11 @@ static void kvmppc_mmu_book3s_64_slbia(struct kvm_vcpu *vcpu) | |||
396 | 410 | ||
397 | dprintk("KVM MMU: slbia()\n"); | 411 | dprintk("KVM MMU: slbia()\n"); |
398 | 412 | ||
399 | for (i = 1; i < vcpu->arch.slb_nr; i++) | 413 | for (i = 1; i < vcpu->arch.slb_nr; i++) { |
400 | vcpu->arch.slb[i].valid = false; | 414 | vcpu->arch.slb[i].valid = false; |
415 | vcpu->arch.slb[i].orige = 0; | ||
416 | vcpu->arch.slb[i].origv = 0; | ||
417 | } | ||
401 | 418 | ||
402 | if (vcpu->arch.shared->msr & MSR_IR) { | 419 | if (vcpu->arch.shared->msr & MSR_IR) { |
403 | kvmppc_mmu_flush_segments(vcpu); | 420 | kvmppc_mmu_flush_segments(vcpu); |
@@ -467,8 +484,14 @@ static int kvmppc_mmu_book3s_64_esid_to_vsid(struct kvm_vcpu *vcpu, ulong esid, | |||
467 | 484 | ||
468 | if (vcpu->arch.shared->msr & (MSR_DR|MSR_IR)) { | 485 | if (vcpu->arch.shared->msr & (MSR_DR|MSR_IR)) { |
469 | slb = kvmppc_mmu_book3s_64_find_slbe(vcpu, ea); | 486 | slb = kvmppc_mmu_book3s_64_find_slbe(vcpu, ea); |
470 | if (slb) | 487 | if (slb) { |
471 | gvsid = slb->vsid; | 488 | gvsid = slb->vsid; |
489 | if (slb->tb) { | ||
490 | gvsid <<= SID_SHIFT_1T - SID_SHIFT; | ||
491 | gvsid |= esid & ((1ul << (SID_SHIFT_1T - SID_SHIFT)) - 1); | ||
492 | gvsid |= VSID_1T; | ||
493 | } | ||
494 | } | ||
472 | } | 495 | } |
473 | 496 | ||
474 | switch (vcpu->arch.shared->msr & (MSR_DR|MSR_IR)) { | 497 | switch (vcpu->arch.shared->msr & (MSR_DR|MSR_IR)) { |
diff --git a/arch/powerpc/kvm/book3s_64_mmu_host.c b/arch/powerpc/kvm/book3s_64_mmu_host.c index 3a9a1aceb14f..b350d9494b26 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_host.c +++ b/arch/powerpc/kvm/book3s_64_mmu_host.c | |||
@@ -301,6 +301,23 @@ out: | |||
301 | return r; | 301 | return r; |
302 | } | 302 | } |
303 | 303 | ||
304 | void kvmppc_mmu_flush_segment(struct kvm_vcpu *vcpu, ulong ea, ulong seg_size) | ||
305 | { | ||
306 | struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu); | ||
307 | ulong seg_mask = -seg_size; | ||
308 | int i; | ||
309 | |||
310 | for (i = 1; i < svcpu->slb_max; i++) { | ||
311 | if ((svcpu->slb[i].esid & SLB_ESID_V) && | ||
312 | (svcpu->slb[i].esid & seg_mask) == ea) { | ||
313 | /* Invalidate this entry */ | ||
314 | svcpu->slb[i].esid = 0; | ||
315 | } | ||
316 | } | ||
317 | |||
318 | svcpu_put(svcpu); | ||
319 | } | ||
320 | |||
304 | void kvmppc_mmu_flush_segments(struct kvm_vcpu *vcpu) | 321 | void kvmppc_mmu_flush_segments(struct kvm_vcpu *vcpu) |
305 | { | 322 | { |
306 | struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu); | 323 | struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu); |
@@ -325,9 +342,9 @@ int kvmppc_mmu_init(struct kvm_vcpu *vcpu) | |||
325 | return -1; | 342 | return -1; |
326 | vcpu3s->context_id[0] = err; | 343 | vcpu3s->context_id[0] = err; |
327 | 344 | ||
328 | vcpu3s->proto_vsid_max = ((vcpu3s->context_id[0] + 1) | 345 | vcpu3s->proto_vsid_max = ((u64)(vcpu3s->context_id[0] + 1) |
329 | << ESID_BITS) - 1; | 346 | << ESID_BITS) - 1; |
330 | vcpu3s->proto_vsid_first = vcpu3s->context_id[0] << ESID_BITS; | 347 | vcpu3s->proto_vsid_first = (u64)vcpu3s->context_id[0] << ESID_BITS; |
331 | vcpu3s->proto_vsid_next = vcpu3s->proto_vsid_first; | 348 | vcpu3s->proto_vsid_next = vcpu3s->proto_vsid_first; |
332 | 349 | ||
333 | kvmppc_mmu_hpte_init(vcpu); | 350 | kvmppc_mmu_hpte_init(vcpu); |
diff --git a/arch/powerpc/kvm/book3s_64_slb.S b/arch/powerpc/kvm/book3s_64_slb.S index 56b983e7b738..4f0caecc0f9d 100644 --- a/arch/powerpc/kvm/book3s_64_slb.S +++ b/arch/powerpc/kvm/book3s_64_slb.S | |||
@@ -66,10 +66,6 @@ slb_exit_skip_ ## num: | |||
66 | 66 | ||
67 | ld r12, PACA_SLBSHADOWPTR(r13) | 67 | ld r12, PACA_SLBSHADOWPTR(r13) |
68 | 68 | ||
69 | /* Save off the first entry so we can slbie it later */ | ||
70 | ld r10, SHADOW_SLB_ESID(0)(r12) | ||
71 | ld r11, SHADOW_SLB_VSID(0)(r12) | ||
72 | |||
73 | /* Remove bolted entries */ | 69 | /* Remove bolted entries */ |
74 | UNBOLT_SLB_ENTRY(0) | 70 | UNBOLT_SLB_ENTRY(0) |
75 | UNBOLT_SLB_ENTRY(1) | 71 | UNBOLT_SLB_ENTRY(1) |
@@ -81,15 +77,10 @@ slb_exit_skip_ ## num: | |||
81 | 77 | ||
82 | /* Flush SLB */ | 78 | /* Flush SLB */ |
83 | 79 | ||
80 | li r10, 0 | ||
81 | slbmte r10, r10 | ||
84 | slbia | 82 | slbia |
85 | 83 | ||
86 | /* r0 = esid & ESID_MASK */ | ||
87 | rldicr r10, r10, 0, 35 | ||
88 | /* r0 |= CLASS_BIT(VSID) */ | ||
89 | rldic r12, r11, 56 - 36, 36 | ||
90 | or r10, r10, r12 | ||
91 | slbie r10 | ||
92 | |||
93 | /* Fill SLB with our shadow */ | 84 | /* Fill SLB with our shadow */ |
94 | 85 | ||
95 | lbz r12, SVCPU_SLB_MAX(r3) | 86 | lbz r12, SVCPU_SLB_MAX(r3) |
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index bdc40b8e77d9..19498a567a81 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c | |||
@@ -1239,8 +1239,7 @@ out: | |||
1239 | #ifdef CONFIG_PPC64 | 1239 | #ifdef CONFIG_PPC64 |
1240 | int kvm_vm_ioctl_get_smmu_info(struct kvm *kvm, struct kvm_ppc_smmu_info *info) | 1240 | int kvm_vm_ioctl_get_smmu_info(struct kvm *kvm, struct kvm_ppc_smmu_info *info) |
1241 | { | 1241 | { |
1242 | /* No flags */ | 1242 | info->flags = KVM_PPC_1T_SEGMENTS; |
1243 | info->flags = 0; | ||
1244 | 1243 | ||
1245 | /* SLB is always 64 entries */ | 1244 | /* SLB is always 64 entries */ |
1246 | info->slb_size = 64; | 1245 | info->slb_size = 64; |
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index 1a1b51189773..dcc94f016007 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c | |||
@@ -796,7 +796,7 @@ static void kvmppc_restart_interrupt(struct kvm_vcpu *vcpu, | |||
796 | kvmppc_fill_pt_regs(®s); | 796 | kvmppc_fill_pt_regs(®s); |
797 | timer_interrupt(®s); | 797 | timer_interrupt(®s); |
798 | break; | 798 | break; |
799 | #if defined(CONFIG_PPC_FSL_BOOK3E) || defined(CONFIG_PPC_BOOK3E_64) | 799 | #if defined(CONFIG_PPC_DOORBELL) |
800 | case BOOKE_INTERRUPT_DOORBELL: | 800 | case BOOKE_INTERRUPT_DOORBELL: |
801 | kvmppc_fill_pt_regs(®s); | 801 | kvmppc_fill_pt_regs(®s); |
802 | doorbell_exception(®s); | 802 | doorbell_exception(®s); |
diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c index 631a2650e4e4..2c52ada30775 100644 --- a/arch/powerpc/kvm/emulate.c +++ b/arch/powerpc/kvm/emulate.c | |||
@@ -169,6 +169,9 @@ static int kvmppc_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs) | |||
169 | vcpu->arch.shared->sprg3 = spr_val; | 169 | vcpu->arch.shared->sprg3 = spr_val; |
170 | break; | 170 | break; |
171 | 171 | ||
172 | /* PIR can legally be written, but we ignore it */ | ||
173 | case SPRN_PIR: break; | ||
174 | |||
172 | default: | 175 | default: |
173 | emulated = kvmppc_core_emulate_mtspr(vcpu, sprn, | 176 | emulated = kvmppc_core_emulate_mtspr(vcpu, sprn, |
174 | spr_val); | 177 | spr_val); |