aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/include/asm/kvm_book3s_64.h8
-rw-r--r--arch/powerpc/include/asm/kvm_host.h10
-rw-r--r--arch/powerpc/kvm/book3s_64_mmu_hv.c44
-rw-r--r--arch/powerpc/kvm/book3s_hv_rm_mmu.c87
4 files changed, 103 insertions, 46 deletions
diff --git a/arch/powerpc/include/asm/kvm_book3s_64.h b/arch/powerpc/include/asm/kvm_book3s_64.h
index 2054e4726ba2..fa3dc79af702 100644
--- a/arch/powerpc/include/asm/kvm_book3s_64.h
+++ b/arch/powerpc/include/asm/kvm_book3s_64.h
@@ -35,6 +35,14 @@ static inline void svcpu_put(struct kvmppc_book3s_shadow_vcpu *svcpu)
35 35
36#define SPAPR_TCE_SHIFT 12 36#define SPAPR_TCE_SHIFT 12
37 37
38#ifdef CONFIG_KVM_BOOK3S_64_HV
39/* For now use fixed-size 16MB page table */
40#define HPT_ORDER 24
41#define HPT_NPTEG (1ul << (HPT_ORDER - 7)) /* 128B per pteg */
42#define HPT_NPTE (HPT_NPTEG << 3) /* 8 PTEs per PTEG */
43#define HPT_HASH_MASK (HPT_NPTEG - 1)
44#endif
45
38static inline unsigned long compute_tlbie_rb(unsigned long v, unsigned long r, 46static inline unsigned long compute_tlbie_rb(unsigned long v, unsigned long r,
39 unsigned long pte_index) 47 unsigned long pte_index)
40{ 48{
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 66c75cddaec6..629df2ed22f7 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -166,9 +166,19 @@ struct kvmppc_rma_info {
166 atomic_t use_count; 166 atomic_t use_count;
167}; 167};
168 168
169/*
170 * The reverse mapping array has one entry for each HPTE,
171 * which stores the guest's view of the second word of the HPTE
172 * (including the guest physical address of the mapping).
173 */
174struct revmap_entry {
175 unsigned long guest_rpte;
176};
177
169struct kvm_arch { 178struct kvm_arch {
170#ifdef CONFIG_KVM_BOOK3S_64_HV 179#ifdef CONFIG_KVM_BOOK3S_64_HV
171 unsigned long hpt_virt; 180 unsigned long hpt_virt;
181 struct revmap_entry *revmap;
172 unsigned long ram_npages; 182 unsigned long ram_npages;
173 unsigned long ram_psize; 183 unsigned long ram_psize;
174 unsigned long ram_porder; 184 unsigned long ram_porder;
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c
index bc3a2ea94217..80ece8de4070 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
@@ -23,6 +23,7 @@
23#include <linux/gfp.h> 23#include <linux/gfp.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/hugetlb.h> 25#include <linux/hugetlb.h>
26#include <linux/vmalloc.h>
26 27
27#include <asm/tlbflush.h> 28#include <asm/tlbflush.h>
28#include <asm/kvm_ppc.h> 29#include <asm/kvm_ppc.h>
@@ -33,11 +34,6 @@
33#include <asm/ppc-opcode.h> 34#include <asm/ppc-opcode.h>
34#include <asm/cputable.h> 35#include <asm/cputable.h>
35 36
36/* For now use fixed-size 16MB page table */
37#define HPT_ORDER 24
38#define HPT_NPTEG (1ul << (HPT_ORDER - 7)) /* 128B per pteg */
39#define HPT_HASH_MASK (HPT_NPTEG - 1)
40
41/* Pages in the VRMA are 16MB pages */ 37/* Pages in the VRMA are 16MB pages */
42#define VRMA_PAGE_ORDER 24 38#define VRMA_PAGE_ORDER 24
43#define VRMA_VSID 0x1ffffffUL /* 1TB VSID reserved for VRMA */ 39#define VRMA_VSID 0x1ffffffUL /* 1TB VSID reserved for VRMA */
@@ -51,7 +47,9 @@ long kvmppc_alloc_hpt(struct kvm *kvm)
51{ 47{
52 unsigned long hpt; 48 unsigned long hpt;
53 unsigned long lpid; 49 unsigned long lpid;
50 struct revmap_entry *rev;
54 51
52 /* Allocate guest's hashed page table */
55 hpt = __get_free_pages(GFP_KERNEL|__GFP_ZERO|__GFP_REPEAT|__GFP_NOWARN, 53 hpt = __get_free_pages(GFP_KERNEL|__GFP_ZERO|__GFP_REPEAT|__GFP_NOWARN,
56 HPT_ORDER - PAGE_SHIFT); 54 HPT_ORDER - PAGE_SHIFT);
57 if (!hpt) { 55 if (!hpt) {
@@ -60,12 +58,20 @@ long kvmppc_alloc_hpt(struct kvm *kvm)
60 } 58 }
61 kvm->arch.hpt_virt = hpt; 59 kvm->arch.hpt_virt = hpt;
62 60
61 /* Allocate reverse map array */
62 rev = vmalloc(sizeof(struct revmap_entry) * HPT_NPTE);
63 if (!rev) {
64 pr_err("kvmppc_alloc_hpt: Couldn't alloc reverse map array\n");
65 goto out_freehpt;
66 }
67 kvm->arch.revmap = rev;
68
69 /* Allocate the guest's logical partition ID */
63 do { 70 do {
64 lpid = find_first_zero_bit(lpid_inuse, NR_LPIDS); 71 lpid = find_first_zero_bit(lpid_inuse, NR_LPIDS);
65 if (lpid >= NR_LPIDS) { 72 if (lpid >= NR_LPIDS) {
66 pr_err("kvm_alloc_hpt: No LPIDs free\n"); 73 pr_err("kvm_alloc_hpt: No LPIDs free\n");
67 free_pages(hpt, HPT_ORDER - PAGE_SHIFT); 74 goto out_freeboth;
68 return -ENOMEM;
69 } 75 }
70 } while (test_and_set_bit(lpid, lpid_inuse)); 76 } while (test_and_set_bit(lpid, lpid_inuse));
71 77
@@ -74,11 +80,18 @@ long kvmppc_alloc_hpt(struct kvm *kvm)
74 80
75 pr_info("KVM guest htab at %lx, LPID %lx\n", hpt, lpid); 81 pr_info("KVM guest htab at %lx, LPID %lx\n", hpt, lpid);
76 return 0; 82 return 0;
83
84 out_freeboth:
85 vfree(rev);
86 out_freehpt:
87 free_pages(hpt, HPT_ORDER - PAGE_SHIFT);
88 return -ENOMEM;
77} 89}
78 90
79void kvmppc_free_hpt(struct kvm *kvm) 91void kvmppc_free_hpt(struct kvm *kvm)
80{ 92{
81 clear_bit(kvm->arch.lpid, lpid_inuse); 93 clear_bit(kvm->arch.lpid, lpid_inuse);
94 vfree(kvm->arch.revmap);
82 free_pages(kvm->arch.hpt_virt, HPT_ORDER - PAGE_SHIFT); 95 free_pages(kvm->arch.hpt_virt, HPT_ORDER - PAGE_SHIFT);
83} 96}
84 97
@@ -89,14 +102,16 @@ void kvmppc_map_vrma(struct kvm *kvm, struct kvm_userspace_memory_region *mem)
89 unsigned long pfn; 102 unsigned long pfn;
90 unsigned long *hpte; 103 unsigned long *hpte;
91 unsigned long hash; 104 unsigned long hash;
105 unsigned long porder = kvm->arch.ram_porder;
106 struct revmap_entry *rev;
92 struct kvmppc_pginfo *pginfo = kvm->arch.ram_pginfo; 107 struct kvmppc_pginfo *pginfo = kvm->arch.ram_pginfo;
93 108
94 if (!pginfo) 109 if (!pginfo)
95 return; 110 return;
96 111
97 /* VRMA can't be > 1TB */ 112 /* VRMA can't be > 1TB */
98 if (npages > 1ul << (40 - kvm->arch.ram_porder)) 113 if (npages > 1ul << (40 - porder))
99 npages = 1ul << (40 - kvm->arch.ram_porder); 114 npages = 1ul << (40 - porder);
100 /* Can't use more than 1 HPTE per HPTEG */ 115 /* Can't use more than 1 HPTE per HPTEG */
101 if (npages > HPT_NPTEG) 116 if (npages > HPT_NPTEG)
102 npages = HPT_NPTEG; 117 npages = HPT_NPTEG;
@@ -113,15 +128,20 @@ void kvmppc_map_vrma(struct kvm *kvm, struct kvm_userspace_memory_region *mem)
113 * at most one HPTE per HPTEG, we just assume entry 7 128 * at most one HPTE per HPTEG, we just assume entry 7
114 * is available and use it. 129 * is available and use it.
115 */ 130 */
116 hpte = (unsigned long *) (kvm->arch.hpt_virt + (hash << 7)); 131 hash = (hash << 3) + 7;
117 hpte += 7 * 2; 132 hpte = (unsigned long *) (kvm->arch.hpt_virt + (hash << 4));
118 /* HPTE low word - RPN, protection, etc. */ 133 /* HPTE low word - RPN, protection, etc. */
119 hpte[1] = (pfn << PAGE_SHIFT) | HPTE_R_R | HPTE_R_C | 134 hpte[1] = (pfn << PAGE_SHIFT) | HPTE_R_R | HPTE_R_C |
120 HPTE_R_M | PP_RWXX; 135 HPTE_R_M | PP_RWXX;
121 wmb(); 136 smp_wmb();
122 hpte[0] = HPTE_V_1TB_SEG | (VRMA_VSID << (40 - 16)) | 137 hpte[0] = HPTE_V_1TB_SEG | (VRMA_VSID << (40 - 16)) |
123 (i << (VRMA_PAGE_ORDER - 16)) | HPTE_V_BOLTED | 138 (i << (VRMA_PAGE_ORDER - 16)) | HPTE_V_BOLTED |
124 HPTE_V_LARGE | HPTE_V_VALID; 139 HPTE_V_LARGE | HPTE_V_VALID;
140
141 /* Reverse map info */
142 rev = &kvm->arch.revmap[hash];
143 rev->guest_rpte = (i << porder) | HPTE_R_R | HPTE_R_C |
144 HPTE_R_M | PP_RWXX;
125 } 145 }
126} 146}
127 147
diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
index bacb0cfa3602..614849360a0a 100644
--- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c
+++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
@@ -20,10 +20,19 @@
20#include <asm/synch.h> 20#include <asm/synch.h>
21#include <asm/ppc-opcode.h> 21#include <asm/ppc-opcode.h>
22 22
23/* For now use fixed-size 16MB page table */ 23/* Translate address of a vmalloc'd thing to a linear map address */
24#define HPT_ORDER 24 24static void *real_vmalloc_addr(void *x)
25#define HPT_NPTEG (1ul << (HPT_ORDER - 7)) /* 128B per pteg */ 25{
26#define HPT_HASH_MASK (HPT_NPTEG - 1) 26 unsigned long addr = (unsigned long) x;
27 pte_t *p;
28
29 p = find_linux_pte(swapper_pg_dir, addr);
30 if (!p || !pte_present(*p))
31 return NULL;
32 /* assume we don't have huge pages in vmalloc space... */
33 addr = (pte_pfn(*p) << PAGE_SHIFT) | (addr & ~PAGE_MASK);
34 return __va(addr);
35}
27 36
28#define HPTE_V_HVLOCK 0x40UL 37#define HPTE_V_HVLOCK 0x40UL
29 38
@@ -52,6 +61,8 @@ long kvmppc_h_enter(struct kvm_vcpu *vcpu, unsigned long flags,
52 struct kvm *kvm = vcpu->kvm; 61 struct kvm *kvm = vcpu->kvm;
53 unsigned long i, lpn, pa; 62 unsigned long i, lpn, pa;
54 unsigned long *hpte; 63 unsigned long *hpte;
64 struct revmap_entry *rev;
65 unsigned long g_ptel = ptel;
55 66
56 /* only handle 4k, 64k and 16M pages for now */ 67 /* only handle 4k, 64k and 16M pages for now */
57 porder = 12; 68 porder = 12;
@@ -82,7 +93,7 @@ long kvmppc_h_enter(struct kvm_vcpu *vcpu, unsigned long flags,
82 pteh &= ~0x60UL; 93 pteh &= ~0x60UL;
83 ptel &= ~(HPTE_R_PP0 - kvm->arch.ram_psize); 94 ptel &= ~(HPTE_R_PP0 - kvm->arch.ram_psize);
84 ptel |= pa; 95 ptel |= pa;
85 if (pte_index >= (HPT_NPTEG << 3)) 96 if (pte_index >= HPT_NPTE)
86 return H_PARAMETER; 97 return H_PARAMETER;
87 if (likely((flags & H_EXACT) == 0)) { 98 if (likely((flags & H_EXACT) == 0)) {
88 pte_index &= ~7UL; 99 pte_index &= ~7UL;
@@ -95,18 +106,22 @@ long kvmppc_h_enter(struct kvm_vcpu *vcpu, unsigned long flags,
95 break; 106 break;
96 hpte += 2; 107 hpte += 2;
97 } 108 }
109 pte_index += i;
98 } else { 110 } else {
99 i = 0;
100 hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4)); 111 hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4));
101 if (!lock_hpte(hpte, HPTE_V_HVLOCK | HPTE_V_VALID)) 112 if (!lock_hpte(hpte, HPTE_V_HVLOCK | HPTE_V_VALID))
102 return H_PTEG_FULL; 113 return H_PTEG_FULL;
103 } 114 }
115
116 /* Save away the guest's idea of the second HPTE dword */
117 rev = real_vmalloc_addr(&kvm->arch.revmap[pte_index]);
118 if (rev)
119 rev->guest_rpte = g_ptel;
104 hpte[1] = ptel; 120 hpte[1] = ptel;
105 eieio(); 121 eieio();
106 hpte[0] = pteh; 122 hpte[0] = pteh;
107 asm volatile("ptesync" : : : "memory"); 123 asm volatile("ptesync" : : : "memory");
108 atomic_inc(&kvm->arch.ram_pginfo[lpn].refcnt); 124 vcpu->arch.gpr[4] = pte_index;
109 vcpu->arch.gpr[4] = pte_index + i;
110 return H_SUCCESS; 125 return H_SUCCESS;
111} 126}
112 127
@@ -138,7 +153,7 @@ long kvmppc_h_remove(struct kvm_vcpu *vcpu, unsigned long flags,
138 unsigned long *hpte; 153 unsigned long *hpte;
139 unsigned long v, r, rb; 154 unsigned long v, r, rb;
140 155
141 if (pte_index >= (HPT_NPTEG << 3)) 156 if (pte_index >= HPT_NPTE)
142 return H_PARAMETER; 157 return H_PARAMETER;
143 hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4)); 158 hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4));
144 while (!lock_hpte(hpte, HPTE_V_HVLOCK)) 159 while (!lock_hpte(hpte, HPTE_V_HVLOCK))
@@ -193,7 +208,7 @@ long kvmppc_h_bulk_remove(struct kvm_vcpu *vcpu)
193 if (req == 3) 208 if (req == 3)
194 break; 209 break;
195 if (req != 1 || flags == 3 || 210 if (req != 1 || flags == 3 ||
196 pte_index >= (HPT_NPTEG << 3)) { 211 pte_index >= HPT_NPTE) {
197 /* parameter error */ 212 /* parameter error */
198 args[i * 2] = ((0xa0 | flags) << 56) + pte_index; 213 args[i * 2] = ((0xa0 | flags) << 56) + pte_index;
199 ret = H_PARAMETER; 214 ret = H_PARAMETER;
@@ -256,9 +271,10 @@ long kvmppc_h_protect(struct kvm_vcpu *vcpu, unsigned long flags,
256{ 271{
257 struct kvm *kvm = vcpu->kvm; 272 struct kvm *kvm = vcpu->kvm;
258 unsigned long *hpte; 273 unsigned long *hpte;
259 unsigned long v, r, rb; 274 struct revmap_entry *rev;
275 unsigned long v, r, rb, mask, bits;
260 276
261 if (pte_index >= (HPT_NPTEG << 3)) 277 if (pte_index >= HPT_NPTE)
262 return H_PARAMETER; 278 return H_PARAMETER;
263 hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4)); 279 hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4));
264 while (!lock_hpte(hpte, HPTE_V_HVLOCK)) 280 while (!lock_hpte(hpte, HPTE_V_HVLOCK))
@@ -271,11 +287,21 @@ long kvmppc_h_protect(struct kvm_vcpu *vcpu, unsigned long flags,
271 if (atomic_read(&kvm->online_vcpus) == 1) 287 if (atomic_read(&kvm->online_vcpus) == 1)
272 flags |= H_LOCAL; 288 flags |= H_LOCAL;
273 v = hpte[0]; 289 v = hpte[0];
274 r = hpte[1] & ~(HPTE_R_PP0 | HPTE_R_PP | HPTE_R_N | 290 bits = (flags << 55) & HPTE_R_PP0;
275 HPTE_R_KEY_HI | HPTE_R_KEY_LO); 291 bits |= (flags << 48) & HPTE_R_KEY_HI;
276 r |= (flags << 55) & HPTE_R_PP0; 292 bits |= flags & (HPTE_R_PP | HPTE_R_N | HPTE_R_KEY_LO);
277 r |= (flags << 48) & HPTE_R_KEY_HI; 293
278 r |= flags & (HPTE_R_PP | HPTE_R_N | HPTE_R_KEY_LO); 294 /* Update guest view of 2nd HPTE dword */
295 mask = HPTE_R_PP0 | HPTE_R_PP | HPTE_R_N |
296 HPTE_R_KEY_HI | HPTE_R_KEY_LO;
297 rev = real_vmalloc_addr(&kvm->arch.revmap[pte_index]);
298 if (rev) {
299 r = (rev->guest_rpte & ~mask) | bits;
300 rev->guest_rpte = r;
301 }
302 r = (hpte[1] & ~mask) | bits;
303
304 /* Update HPTE */
279 rb = compute_tlbie_rb(v, r, pte_index); 305 rb = compute_tlbie_rb(v, r, pte_index);
280 hpte[0] = v & ~HPTE_V_VALID; 306 hpte[0] = v & ~HPTE_V_VALID;
281 if (!(flags & H_LOCAL)) { 307 if (!(flags & H_LOCAL)) {
@@ -298,38 +324,31 @@ long kvmppc_h_protect(struct kvm_vcpu *vcpu, unsigned long flags,
298 return H_SUCCESS; 324 return H_SUCCESS;
299} 325}
300 326
301static unsigned long reverse_xlate(struct kvm *kvm, unsigned long realaddr)
302{
303 long int i;
304 unsigned long offset, rpn;
305
306 offset = realaddr & (kvm->arch.ram_psize - 1);
307 rpn = (realaddr - offset) >> PAGE_SHIFT;
308 for (i = 0; i < kvm->arch.ram_npages; ++i)
309 if (rpn == kvm->arch.ram_pginfo[i].pfn)
310 return (i << PAGE_SHIFT) + offset;
311 return HPTE_R_RPN; /* all 1s in the RPN field */
312}
313
314long kvmppc_h_read(struct kvm_vcpu *vcpu, unsigned long flags, 327long kvmppc_h_read(struct kvm_vcpu *vcpu, unsigned long flags,
315 unsigned long pte_index) 328 unsigned long pte_index)
316{ 329{
317 struct kvm *kvm = vcpu->kvm; 330 struct kvm *kvm = vcpu->kvm;
318 unsigned long *hpte, r; 331 unsigned long *hpte, r;
319 int i, n = 1; 332 int i, n = 1;
333 struct revmap_entry *rev = NULL;
320 334
321 if (pte_index >= (HPT_NPTEG << 3)) 335 if (pte_index >= HPT_NPTE)
322 return H_PARAMETER; 336 return H_PARAMETER;
323 if (flags & H_READ_4) { 337 if (flags & H_READ_4) {
324 pte_index &= ~3; 338 pte_index &= ~3;
325 n = 4; 339 n = 4;
326 } 340 }
341 if (flags & H_R_XLATE)
342 rev = real_vmalloc_addr(&kvm->arch.revmap[pte_index]);
327 for (i = 0; i < n; ++i, ++pte_index) { 343 for (i = 0; i < n; ++i, ++pte_index) {
328 hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4)); 344 hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4));
329 r = hpte[1]; 345 r = hpte[1];
330 if ((flags & H_R_XLATE) && (hpte[0] & HPTE_V_VALID)) 346 if (hpte[0] & HPTE_V_VALID) {
331 r = reverse_xlate(kvm, r & HPTE_R_RPN) | 347 if (rev)
332 (r & ~HPTE_R_RPN); 348 r = rev[i].guest_rpte;
349 else
350 r = hpte[1] | HPTE_R_RPN;
351 }
333 vcpu->arch.gpr[4 + i * 2] = hpte[0]; 352 vcpu->arch.gpr[4 + i * 2] = hpte[0];
334 vcpu->arch.gpr[5 + i * 2] = r; 353 vcpu->arch.gpr[5 + i * 2] = r;
335 } 354 }