aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/include/asm/kvm_book3s.h11
-rw-r--r--arch/powerpc/kvm/book3s.c4
-rw-r--r--arch/powerpc/kvm/book3s_32_mmu.c79
3 files changed, 46 insertions, 48 deletions
diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h
index f04f516c97da..08846520220c 100644
--- a/arch/powerpc/include/asm/kvm_book3s.h
+++ b/arch/powerpc/include/asm/kvm_book3s.h
@@ -38,15 +38,6 @@ struct kvmppc_slb {
38 bool class : 1; 38 bool class : 1;
39}; 39};
40 40
41struct kvmppc_sr {
42 u32 raw;
43 u32 vsid;
44 bool Ks : 1;
45 bool Kp : 1;
46 bool nx : 1;
47 bool valid : 1;
48};
49
50struct kvmppc_bat { 41struct kvmppc_bat {
51 u64 raw; 42 u64 raw;
52 u32 bepi; 43 u32 bepi;
@@ -79,7 +70,7 @@ struct kvmppc_vcpu_book3s {
79 u64 vsid; 70 u64 vsid;
80 } slb_shadow[64]; 71 } slb_shadow[64];
81 u8 slb_shadow_max; 72 u8 slb_shadow_max;
82 struct kvmppc_sr sr[16]; 73 u32 sr[16];
83 struct kvmppc_bat ibat[8]; 74 struct kvmppc_bat ibat[8];
84 struct kvmppc_bat dbat[8]; 75 struct kvmppc_bat dbat[8];
85 u64 hid[6]; 76 u64 hid[6];
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index 2fb528f417ff..34472afbb3ec 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -1162,8 +1162,8 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
1162 } 1162 }
1163 } else { 1163 } else {
1164 for (i = 0; i < 16; i++) { 1164 for (i = 0; i < 16; i++) {
1165 sregs->u.s.ppc32.sr[i] = vcpu3s->sr[i].raw; 1165 sregs->u.s.ppc32.sr[i] = vcpu3s->sr[i];
1166 sregs->u.s.ppc32.sr[i] = vcpu3s->sr[i].raw; 1166 sregs->u.s.ppc32.sr[i] = vcpu3s->sr[i];
1167 } 1167 }
1168 for (i = 0; i < 8; i++) { 1168 for (i = 0; i < 8; i++) {
1169 sregs->u.s.ppc32.ibat[i] = vcpu3s->ibat[i].raw; 1169 sregs->u.s.ppc32.ibat[i] = vcpu3s->ibat[i].raw;
diff --git a/arch/powerpc/kvm/book3s_32_mmu.c b/arch/powerpc/kvm/book3s_32_mmu.c
index 5bf4bf8c9e65..d4ff76fd1ff9 100644
--- a/arch/powerpc/kvm/book3s_32_mmu.c
+++ b/arch/powerpc/kvm/book3s_32_mmu.c
@@ -58,14 +58,39 @@ static inline bool check_debug_ip(struct kvm_vcpu *vcpu)
58#endif 58#endif
59} 59}
60 60
61static inline u32 sr_vsid(u32 sr_raw)
62{
63 return sr_raw & 0x0fffffff;
64}
65
66static inline bool sr_valid(u32 sr_raw)
67{
68 return (sr_raw & 0x80000000) ? false : true;
69}
70
71static inline bool sr_ks(u32 sr_raw)
72{
73 return (sr_raw & 0x40000000) ? true: false;
74}
75
76static inline bool sr_kp(u32 sr_raw)
77{
78 return (sr_raw & 0x20000000) ? true: false;
79}
80
81static inline bool sr_nx(u32 sr_raw)
82{
83 return (sr_raw & 0x10000000) ? true: false;
84}
85
61static int kvmppc_mmu_book3s_32_xlate_bat(struct kvm_vcpu *vcpu, gva_t eaddr, 86static int kvmppc_mmu_book3s_32_xlate_bat(struct kvm_vcpu *vcpu, gva_t eaddr,
62 struct kvmppc_pte *pte, bool data); 87 struct kvmppc_pte *pte, bool data);
63static int kvmppc_mmu_book3s_32_esid_to_vsid(struct kvm_vcpu *vcpu, ulong esid, 88static int kvmppc_mmu_book3s_32_esid_to_vsid(struct kvm_vcpu *vcpu, ulong esid,
64 u64 *vsid); 89 u64 *vsid);
65 90
66static struct kvmppc_sr *find_sr(struct kvmppc_vcpu_book3s *vcpu_book3s, gva_t eaddr) 91static u32 find_sr(struct kvmppc_vcpu_book3s *vcpu_book3s, gva_t eaddr)
67{ 92{
68 return &vcpu_book3s->sr[(eaddr >> 28) & 0xf]; 93 return vcpu_book3s->sr[(eaddr >> 28) & 0xf];
69} 94}
70 95
71static u64 kvmppc_mmu_book3s_32_ea_to_vp(struct kvm_vcpu *vcpu, gva_t eaddr, 96static u64 kvmppc_mmu_book3s_32_ea_to_vp(struct kvm_vcpu *vcpu, gva_t eaddr,
@@ -87,7 +112,7 @@ static void kvmppc_mmu_book3s_32_reset_msr(struct kvm_vcpu *vcpu)
87} 112}
88 113
89static hva_t kvmppc_mmu_book3s_32_get_pteg(struct kvmppc_vcpu_book3s *vcpu_book3s, 114static hva_t kvmppc_mmu_book3s_32_get_pteg(struct kvmppc_vcpu_book3s *vcpu_book3s,
90 struct kvmppc_sr *sre, gva_t eaddr, 115 u32 sre, gva_t eaddr,
91 bool primary) 116 bool primary)
92{ 117{
93 u32 page, hash, pteg, htabmask; 118 u32 page, hash, pteg, htabmask;
@@ -96,7 +121,7 @@ static hva_t kvmppc_mmu_book3s_32_get_pteg(struct kvmppc_vcpu_book3s *vcpu_book3
96 page = (eaddr & 0x0FFFFFFF) >> 12; 121 page = (eaddr & 0x0FFFFFFF) >> 12;
97 htabmask = ((vcpu_book3s->sdr1 & 0x1FF) << 16) | 0xFFC0; 122 htabmask = ((vcpu_book3s->sdr1 & 0x1FF) << 16) | 0xFFC0;
98 123
99 hash = ((sre->vsid ^ page) << 6); 124 hash = ((sr_vsid(sre) ^ page) << 6);
100 if (!primary) 125 if (!primary)
101 hash = ~hash; 126 hash = ~hash;
102 hash &= htabmask; 127 hash &= htabmask;
@@ -105,7 +130,7 @@ static hva_t kvmppc_mmu_book3s_32_get_pteg(struct kvmppc_vcpu_book3s *vcpu_book3
105 130
106 dprintk("MMU: pc=0x%lx eaddr=0x%lx sdr1=0x%llx pteg=0x%x vsid=0x%x\n", 131 dprintk("MMU: pc=0x%lx eaddr=0x%lx sdr1=0x%llx pteg=0x%x vsid=0x%x\n",
107 kvmppc_get_pc(&vcpu_book3s->vcpu), eaddr, vcpu_book3s->sdr1, pteg, 132 kvmppc_get_pc(&vcpu_book3s->vcpu), eaddr, vcpu_book3s->sdr1, pteg,
108 sre->vsid); 133 sr_vsid(sre));
109 134
110 r = gfn_to_hva(vcpu_book3s->vcpu.kvm, pteg >> PAGE_SHIFT); 135 r = gfn_to_hva(vcpu_book3s->vcpu.kvm, pteg >> PAGE_SHIFT);
111 if (kvm_is_error_hva(r)) 136 if (kvm_is_error_hva(r))
@@ -113,10 +138,9 @@ static hva_t kvmppc_mmu_book3s_32_get_pteg(struct kvmppc_vcpu_book3s *vcpu_book3
113 return r | (pteg & ~PAGE_MASK); 138 return r | (pteg & ~PAGE_MASK);
114} 139}
115 140
116static u32 kvmppc_mmu_book3s_32_get_ptem(struct kvmppc_sr *sre, gva_t eaddr, 141static u32 kvmppc_mmu_book3s_32_get_ptem(u32 sre, gva_t eaddr, bool primary)
117 bool primary)
118{ 142{
119 return ((eaddr & 0x0fffffff) >> 22) | (sre->vsid << 7) | 143 return ((eaddr & 0x0fffffff) >> 22) | (sr_vsid(sre) << 7) |
120 (primary ? 0 : 0x40) | 0x80000000; 144 (primary ? 0 : 0x40) | 0x80000000;
121} 145}
122 146
@@ -180,7 +204,7 @@ static int kvmppc_mmu_book3s_32_xlate_pte(struct kvm_vcpu *vcpu, gva_t eaddr,
180 bool primary) 204 bool primary)
181{ 205{
182 struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu); 206 struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
183 struct kvmppc_sr *sre; 207 u32 sre;
184 hva_t ptegp; 208 hva_t ptegp;
185 u32 pteg[16]; 209 u32 pteg[16];
186 u32 ptem = 0; 210 u32 ptem = 0;
@@ -190,7 +214,7 @@ static int kvmppc_mmu_book3s_32_xlate_pte(struct kvm_vcpu *vcpu, gva_t eaddr,
190 sre = find_sr(vcpu_book3s, eaddr); 214 sre = find_sr(vcpu_book3s, eaddr);
191 215
192 dprintk_pte("SR 0x%lx: vsid=0x%x, raw=0x%x\n", eaddr >> 28, 216 dprintk_pte("SR 0x%lx: vsid=0x%x, raw=0x%x\n", eaddr >> 28,
193 sre->vsid, sre->raw); 217 sr_vsid(sre), sre);
194 218
195 pte->vpage = kvmppc_mmu_book3s_32_ea_to_vp(vcpu, eaddr, data); 219 pte->vpage = kvmppc_mmu_book3s_32_ea_to_vp(vcpu, eaddr, data);
196 220
@@ -214,8 +238,8 @@ static int kvmppc_mmu_book3s_32_xlate_pte(struct kvm_vcpu *vcpu, gva_t eaddr,
214 pte->raddr = (pteg[i+1] & ~(0xFFFULL)) | (eaddr & 0xFFF); 238 pte->raddr = (pteg[i+1] & ~(0xFFFULL)) | (eaddr & 0xFFF);
215 pp = pteg[i+1] & 3; 239 pp = pteg[i+1] & 3;
216 240
217 if ((sre->Kp && (vcpu->arch.shared->msr & MSR_PR)) || 241 if ((sr_kp(sre) && (vcpu->arch.shared->msr & MSR_PR)) ||
218 (sre->Ks && !(vcpu->arch.shared->msr & MSR_PR))) 242 (sr_ks(sre) && !(vcpu->arch.shared->msr & MSR_PR)))
219 pp |= 4; 243 pp |= 4;
220 244
221 pte->may_write = false; 245 pte->may_write = false;
@@ -311,30 +335,13 @@ static int kvmppc_mmu_book3s_32_xlate(struct kvm_vcpu *vcpu, gva_t eaddr,
311 335
312static u32 kvmppc_mmu_book3s_32_mfsrin(struct kvm_vcpu *vcpu, u32 srnum) 336static u32 kvmppc_mmu_book3s_32_mfsrin(struct kvm_vcpu *vcpu, u32 srnum)
313{ 337{
314 return to_book3s(vcpu)->sr[srnum].raw; 338 return to_book3s(vcpu)->sr[srnum];
315} 339}
316 340
317static void kvmppc_mmu_book3s_32_mtsrin(struct kvm_vcpu *vcpu, u32 srnum, 341static void kvmppc_mmu_book3s_32_mtsrin(struct kvm_vcpu *vcpu, u32 srnum,
318 ulong value) 342 ulong value)
319{ 343{
320 struct kvmppc_sr *sre; 344 to_book3s(vcpu)->sr[srnum] = value;
321
322 sre = &to_book3s(vcpu)->sr[srnum];
323
324 /* Flush any left-over shadows from the previous SR */
325
326 /* XXX Not necessary? */
327 /* kvmppc_mmu_pte_flush(vcpu, ((u64)sre->vsid) << 28, 0xf0000000ULL); */
328
329 /* And then put in the new SR */
330 sre->raw = value;
331 sre->vsid = (value & 0x0fffffff);
332 sre->valid = (value & 0x80000000) ? false : true;
333 sre->Ks = (value & 0x40000000) ? true : false;
334 sre->Kp = (value & 0x20000000) ? true : false;
335 sre->nx = (value & 0x10000000) ? true : false;
336
337 /* Map the new segment */
338 kvmppc_mmu_map_segment(vcpu, srnum << SID_SHIFT); 345 kvmppc_mmu_map_segment(vcpu, srnum << SID_SHIFT);
339} 346}
340 347
@@ -347,13 +354,13 @@ static int kvmppc_mmu_book3s_32_esid_to_vsid(struct kvm_vcpu *vcpu, ulong esid,
347 u64 *vsid) 354 u64 *vsid)
348{ 355{
349 ulong ea = esid << SID_SHIFT; 356 ulong ea = esid << SID_SHIFT;
350 struct kvmppc_sr *sr; 357 u32 sr;
351 u64 gvsid = esid; 358 u64 gvsid = esid;
352 359
353 if (vcpu->arch.shared->msr & (MSR_DR|MSR_IR)) { 360 if (vcpu->arch.shared->msr & (MSR_DR|MSR_IR)) {
354 sr = find_sr(to_book3s(vcpu), ea); 361 sr = find_sr(to_book3s(vcpu), ea);
355 if (sr->valid) 362 if (sr_valid(sr))
356 gvsid = sr->vsid; 363 gvsid = sr_vsid(sr);
357 } 364 }
358 365
359 /* In case we only have one of MSR_IR or MSR_DR set, let's put 366 /* In case we only have one of MSR_IR or MSR_DR set, let's put
@@ -370,8 +377,8 @@ static int kvmppc_mmu_book3s_32_esid_to_vsid(struct kvm_vcpu *vcpu, ulong esid,
370 *vsid = VSID_REAL_DR | gvsid; 377 *vsid = VSID_REAL_DR | gvsid;
371 break; 378 break;
372 case MSR_DR|MSR_IR: 379 case MSR_DR|MSR_IR:
373 if (sr->valid) 380 if (sr_valid(sr))
374 *vsid = sr->vsid; 381 *vsid = sr_vsid(sr);
375 else 382 else
376 *vsid = VSID_BAT | gvsid; 383 *vsid = VSID_BAT | gvsid;
377 break; 384 break;