aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/include/asm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/include/asm')
-rw-r--r--arch/powerpc/include/asm/kvm_book3s.h3
-rw-r--r--arch/powerpc/include/asm/kvm_book3s_64.h140
-rw-r--r--arch/powerpc/include/asm/kvm_book3s_asm.h13
-rw-r--r--arch/powerpc/include/asm/kvm_host.h6
-rw-r--r--arch/powerpc/include/asm/kvm_ppc.h3
5 files changed, 138 insertions, 27 deletions
diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h
index b8d5b8e35244..9a667007bff8 100644
--- a/arch/powerpc/include/asm/kvm_book3s.h
+++ b/arch/powerpc/include/asm/kvm_book3s.h
@@ -216,7 +216,8 @@ extern kvm_pfn_t kvmppc_gpa_to_pfn(struct kvm_vcpu *vcpu, gpa_t gpa,
216 bool writing, bool *writable); 216 bool writing, bool *writable);
217extern void kvmppc_add_revmap_chain(struct kvm *kvm, struct revmap_entry *rev, 217extern void kvmppc_add_revmap_chain(struct kvm *kvm, struct revmap_entry *rev,
218 unsigned long *rmap, long pte_index, int realmode); 218 unsigned long *rmap, long pte_index, int realmode);
219extern void kvmppc_update_rmap_change(unsigned long *rmap, unsigned long psize); 219extern void kvmppc_update_dirty_map(struct kvm_memory_slot *memslot,
220 unsigned long gfn, unsigned long psize);
220extern void kvmppc_invalidate_hpte(struct kvm *kvm, __be64 *hptep, 221extern void kvmppc_invalidate_hpte(struct kvm *kvm, __be64 *hptep,
221 unsigned long pte_index); 222 unsigned long pte_index);
222void kvmppc_clear_ref_hpte(struct kvm *kvm, __be64 *hptep, 223void kvmppc_clear_ref_hpte(struct kvm *kvm, __be64 *hptep,
diff --git a/arch/powerpc/include/asm/kvm_book3s_64.h b/arch/powerpc/include/asm/kvm_book3s_64.h
index d55c7f881ce7..735cfa35298a 100644
--- a/arch/powerpc/include/asm/kvm_book3s_64.h
+++ b/arch/powerpc/include/asm/kvm_book3s_64.h
@@ -20,6 +20,8 @@
20#ifndef __ASM_KVM_BOOK3S_64_H__ 20#ifndef __ASM_KVM_BOOK3S_64_H__
21#define __ASM_KVM_BOOK3S_64_H__ 21#define __ASM_KVM_BOOK3S_64_H__
22 22
23#include <linux/string.h>
24#include <asm/bitops.h>
23#include <asm/book3s/64/mmu-hash.h> 25#include <asm/book3s/64/mmu-hash.h>
24 26
25/* Power architecture requires HPT is at least 256kiB, at most 64TiB */ 27/* Power architecture requires HPT is at least 256kiB, at most 64TiB */
@@ -107,18 +109,96 @@ static inline void __unlock_hpte(__be64 *hpte, unsigned long hpte_v)
107 hpte[0] = cpu_to_be64(hpte_v); 109 hpte[0] = cpu_to_be64(hpte_v);
108} 110}
109 111
112/*
113 * These functions encode knowledge of the POWER7/8/9 hardware
114 * interpretations of the HPTE LP (large page size) field.
115 */
116static inline int kvmppc_hpte_page_shifts(unsigned long h, unsigned long l)
117{
118 unsigned int lphi;
119
120 if (!(h & HPTE_V_LARGE))
121 return 12; /* 4kB */
122 lphi = (l >> 16) & 0xf;
123 switch ((l >> 12) & 0xf) {
124 case 0:
125 return !lphi ? 24 : -1; /* 16MB */
126 break;
127 case 1:
128 return 16; /* 64kB */
129 break;
130 case 3:
131 return !lphi ? 34 : -1; /* 16GB */
132 break;
133 case 7:
134 return (16 << 8) + 12; /* 64kB in 4kB */
135 break;
136 case 8:
137 if (!lphi)
138 return (24 << 8) + 16; /* 16MB in 64kkB */
139 if (lphi == 3)
140 return (24 << 8) + 12; /* 16MB in 4kB */
141 break;
142 }
143 return -1;
144}
145
146static inline int kvmppc_hpte_base_page_shift(unsigned long h, unsigned long l)
147{
148 return kvmppc_hpte_page_shifts(h, l) & 0xff;
149}
150
151static inline int kvmppc_hpte_actual_page_shift(unsigned long h, unsigned long l)
152{
153 int tmp = kvmppc_hpte_page_shifts(h, l);
154
155 if (tmp >= 0x100)
156 tmp >>= 8;
157 return tmp;
158}
159
160static inline unsigned long kvmppc_actual_pgsz(unsigned long v, unsigned long r)
161{
162 return 1ul << kvmppc_hpte_actual_page_shift(v, r);
163}
164
165static inline int kvmppc_pgsize_lp_encoding(int base_shift, int actual_shift)
166{
167 switch (base_shift) {
168 case 12:
169 switch (actual_shift) {
170 case 12:
171 return 0;
172 case 16:
173 return 7;
174 case 24:
175 return 0x38;
176 }
177 break;
178 case 16:
179 switch (actual_shift) {
180 case 16:
181 return 1;
182 case 24:
183 return 8;
184 }
185 break;
186 case 24:
187 return 0;
188 }
189 return -1;
190}
191
110static inline unsigned long compute_tlbie_rb(unsigned long v, unsigned long r, 192static inline unsigned long compute_tlbie_rb(unsigned long v, unsigned long r,
111 unsigned long pte_index) 193 unsigned long pte_index)
112{ 194{
113 int i, b_psize = MMU_PAGE_4K, a_psize = MMU_PAGE_4K; 195 int a_pgshift, b_pgshift;
114 unsigned int penc;
115 unsigned long rb = 0, va_low, sllp; 196 unsigned long rb = 0, va_low, sllp;
116 unsigned int lp = (r >> LP_SHIFT) & ((1 << LP_BITS) - 1);
117 197
118 if (v & HPTE_V_LARGE) { 198 b_pgshift = a_pgshift = kvmppc_hpte_page_shifts(v, r);
119 i = hpte_page_sizes[lp]; 199 if (a_pgshift >= 0x100) {
120 b_psize = i & 0xf; 200 b_pgshift &= 0xff;
121 a_psize = i >> 4; 201 a_pgshift >>= 8;
122 } 202 }
123 203
124 /* 204 /*
@@ -152,37 +232,33 @@ static inline unsigned long compute_tlbie_rb(unsigned long v, unsigned long r,
152 va_low ^= v >> (SID_SHIFT_1T - 16); 232 va_low ^= v >> (SID_SHIFT_1T - 16);
153 va_low &= 0x7ff; 233 va_low &= 0x7ff;
154 234
155 switch (b_psize) { 235 if (b_pgshift == 12) {
156 case MMU_PAGE_4K: 236 if (a_pgshift > 12) {
157 sllp = get_sllp_encoding(a_psize); 237 sllp = (a_pgshift == 16) ? 5 : 4;
158 rb |= sllp << 5; /* AP field */ 238 rb |= sllp << 5; /* AP field */
239 }
159 rb |= (va_low & 0x7ff) << 12; /* remaining 11 bits of AVA */ 240 rb |= (va_low & 0x7ff) << 12; /* remaining 11 bits of AVA */
160 break; 241 } else {
161 default:
162 {
163 int aval_shift; 242 int aval_shift;
164 /* 243 /*
165 * remaining bits of AVA/LP fields 244 * remaining bits of AVA/LP fields
166 * Also contain the rr bits of LP 245 * Also contain the rr bits of LP
167 */ 246 */
168 rb |= (va_low << mmu_psize_defs[b_psize].shift) & 0x7ff000; 247 rb |= (va_low << b_pgshift) & 0x7ff000;
169 /* 248 /*
170 * Now clear not needed LP bits based on actual psize 249 * Now clear not needed LP bits based on actual psize
171 */ 250 */
172 rb &= ~((1ul << mmu_psize_defs[a_psize].shift) - 1); 251 rb &= ~((1ul << a_pgshift) - 1);
173 /* 252 /*
174 * AVAL field 58..77 - base_page_shift bits of va 253 * AVAL field 58..77 - base_page_shift bits of va
175 * we have space for 58..64 bits, Missing bits should 254 * we have space for 58..64 bits, Missing bits should
176 * be zero filled. +1 is to take care of L bit shift 255 * be zero filled. +1 is to take care of L bit shift
177 */ 256 */
178 aval_shift = 64 - (77 - mmu_psize_defs[b_psize].shift) + 1; 257 aval_shift = 64 - (77 - b_pgshift) + 1;
179 rb |= ((va_low << aval_shift) & 0xfe); 258 rb |= ((va_low << aval_shift) & 0xfe);
180 259
181 rb |= 1; /* L field */ 260 rb |= 1; /* L field */
182 penc = mmu_psize_defs[b_psize].penc[a_psize]; 261 rb |= r & 0xff000 & ((1ul << a_pgshift) - 1); /* LP field */
183 rb |= penc << 12; /* LP field */
184 break;
185 }
186 } 262 }
187 rb |= (v >> HPTE_V_SSIZE_SHIFT) << 8; /* B field */ 263 rb |= (v >> HPTE_V_SSIZE_SHIFT) << 8; /* B field */
188 return rb; 264 return rb;
@@ -370,6 +446,28 @@ static inline unsigned long kvmppc_hpt_mask(struct kvm_hpt_info *hpt)
370 return (1UL << (hpt->order - 7)) - 1; 446 return (1UL << (hpt->order - 7)) - 1;
371} 447}
372 448
449/* Set bits in a dirty bitmap, which is in LE format */
450static inline void set_dirty_bits(unsigned long *map, unsigned long i,
451 unsigned long npages)
452{
453
454 if (npages >= 8)
455 memset((char *)map + i / 8, 0xff, npages / 8);
456 else
457 for (; npages; ++i, --npages)
458 __set_bit_le(i, map);
459}
460
461static inline void set_dirty_bits_atomic(unsigned long *map, unsigned long i,
462 unsigned long npages)
463{
464 if (npages >= 8)
465 memset((char *)map + i / 8, 0xff, npages / 8);
466 else
467 for (; npages; ++i, --npages)
468 set_bit_le(i, map);
469}
470
373#endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */ 471#endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */
374 472
375#endif /* __ASM_KVM_BOOK3S_64_H__ */ 473#endif /* __ASM_KVM_BOOK3S_64_H__ */
diff --git a/arch/powerpc/include/asm/kvm_book3s_asm.h b/arch/powerpc/include/asm/kvm_book3s_asm.h
index 7cea76f11c26..ab386af2904f 100644
--- a/arch/powerpc/include/asm/kvm_book3s_asm.h
+++ b/arch/powerpc/include/asm/kvm_book3s_asm.h
@@ -82,6 +82,16 @@ struct kvm_split_mode {
82 u8 do_nap; 82 u8 do_nap;
83 u8 napped[MAX_SMT_THREADS]; 83 u8 napped[MAX_SMT_THREADS];
84 struct kvmppc_vcore *vc[MAX_SUBCORES]; 84 struct kvmppc_vcore *vc[MAX_SUBCORES];
85 /* Bits for changing lpcr on P9 */
86 unsigned long lpcr_req;
87 unsigned long lpidr_req;
88 unsigned long host_lpcr;
89 u32 do_set;
90 u32 do_restore;
91 union {
92 u32 allphases;
93 u8 phase[4];
94 } lpcr_sync;
85}; 95};
86 96
87/* 97/*
@@ -107,7 +117,8 @@ struct kvmppc_host_state {
107 u8 hwthread_req; 117 u8 hwthread_req;
108 u8 hwthread_state; 118 u8 hwthread_state;
109 u8 host_ipi; 119 u8 host_ipi;
110 u8 ptid; 120 u8 ptid; /* thread number within subcore when split */
121 u8 tid; /* thread number within whole core */
111 struct kvm_vcpu *kvm_vcpu; 122 struct kvm_vcpu *kvm_vcpu;
112 struct kvmppc_vcore *kvm_vcore; 123 struct kvmppc_vcore *kvm_vcore;
113 void __iomem *xics_phys; 124 void __iomem *xics_phys;
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index e372ed871c51..3aa5b577cd60 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -235,10 +235,7 @@ struct revmap_entry {
235 */ 235 */
236#define KVMPPC_RMAP_LOCK_BIT 63 236#define KVMPPC_RMAP_LOCK_BIT 63
237#define KVMPPC_RMAP_RC_SHIFT 32 237#define KVMPPC_RMAP_RC_SHIFT 32
238#define KVMPPC_RMAP_CHG_SHIFT 48
239#define KVMPPC_RMAP_REFERENCED (HPTE_R_R << KVMPPC_RMAP_RC_SHIFT) 238#define KVMPPC_RMAP_REFERENCED (HPTE_R_R << KVMPPC_RMAP_RC_SHIFT)
240#define KVMPPC_RMAP_CHANGED (HPTE_R_C << KVMPPC_RMAP_RC_SHIFT)
241#define KVMPPC_RMAP_CHG_ORDER (0x3ful << KVMPPC_RMAP_CHG_SHIFT)
242#define KVMPPC_RMAP_PRESENT 0x100000000ul 239#define KVMPPC_RMAP_PRESENT 0x100000000ul
243#define KVMPPC_RMAP_INDEX 0xfffffffful 240#define KVMPPC_RMAP_INDEX 0xfffffffful
244 241
@@ -276,7 +273,7 @@ struct kvm_arch {
276 int tlbie_lock; 273 int tlbie_lock;
277 unsigned long lpcr; 274 unsigned long lpcr;
278 unsigned long vrma_slb_v; 275 unsigned long vrma_slb_v;
279 int hpte_setup_done; 276 int mmu_ready;
280 atomic_t vcpus_running; 277 atomic_t vcpus_running;
281 u32 online_vcores; 278 u32 online_vcores;
282 atomic_t hpte_mod_interest; 279 atomic_t hpte_mod_interest;
@@ -284,6 +281,7 @@ struct kvm_arch {
284 cpumask_t cpu_in_guest; 281 cpumask_t cpu_in_guest;
285 u8 radix; 282 u8 radix;
286 u8 fwnmi_enabled; 283 u8 fwnmi_enabled;
284 bool threads_indep;
287 pgd_t *pgtable; 285 pgd_t *pgtable;
288 u64 process_table; 286 u64 process_table;
289 struct dentry *debugfs_dir; 287 struct dentry *debugfs_dir;
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index ba5fadd6f3c9..96753f3aac6d 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -168,6 +168,7 @@ extern int kvmppc_allocate_hpt(struct kvm_hpt_info *info, u32 order);
168extern void kvmppc_set_hpt(struct kvm *kvm, struct kvm_hpt_info *info); 168extern void kvmppc_set_hpt(struct kvm *kvm, struct kvm_hpt_info *info);
169extern long kvmppc_alloc_reset_hpt(struct kvm *kvm, int order); 169extern long kvmppc_alloc_reset_hpt(struct kvm *kvm, int order);
170extern void kvmppc_free_hpt(struct kvm_hpt_info *info); 170extern void kvmppc_free_hpt(struct kvm_hpt_info *info);
171extern void kvmppc_rmap_reset(struct kvm *kvm);
171extern long kvmppc_prepare_vrma(struct kvm *kvm, 172extern long kvmppc_prepare_vrma(struct kvm *kvm,
172 struct kvm_userspace_memory_region *mem); 173 struct kvm_userspace_memory_region *mem);
173extern void kvmppc_map_vrma(struct kvm_vcpu *vcpu, 174extern void kvmppc_map_vrma(struct kvm_vcpu *vcpu,
@@ -177,6 +178,8 @@ extern long kvm_spapr_tce_attach_iommu_group(struct kvm *kvm, int tablefd,
177 struct iommu_group *grp); 178 struct iommu_group *grp);
178extern void kvm_spapr_tce_release_iommu_group(struct kvm *kvm, 179extern void kvm_spapr_tce_release_iommu_group(struct kvm *kvm,
179 struct iommu_group *grp); 180 struct iommu_group *grp);
181extern int kvmppc_switch_mmu_to_hpt(struct kvm *kvm);
182extern int kvmppc_switch_mmu_to_radix(struct kvm *kvm);
180 183
181extern long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm, 184extern long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
182 struct kvm_create_spapr_tce_64 *args); 185 struct kvm_create_spapr_tce_64 *args);