@@ -228,14 +228,32 @@ static void kvmppc_pmd_free(pmd_t *pmdp)
228
228
kmem_cache_free (kvm_pmd_cache , pmdp );
229
229
}
230
230
231
+ static void kvmppc_unmap_pte (struct kvm * kvm , pte_t * pte ,
232
+ unsigned long gpa , unsigned int shift )
233
+
234
+ {
235
+ unsigned long page_size = 1ul << shift ;
236
+ unsigned long old ;
237
+
238
+ old = kvmppc_radix_update_pte (kvm , pte , ~0UL , 0 , gpa , shift );
239
+ kvmppc_radix_tlbie_page (kvm , gpa , shift );
240
+ if (old & _PAGE_DIRTY ) {
241
+ unsigned long gfn = gpa >> PAGE_SHIFT ;
242
+ struct kvm_memory_slot * memslot ;
243
+
244
+ memslot = gfn_to_memslot (kvm , gfn );
245
+ if (memslot && memslot -> dirty_bitmap )
246
+ kvmppc_update_dirty_map (memslot , gfn , page_size );
247
+ }
248
+ }
249
+
231
250
static int kvmppc_create_pte (struct kvm * kvm , pte_t pte , unsigned long gpa ,
232
251
unsigned int level , unsigned long mmu_seq )
233
252
{
234
253
pgd_t * pgd ;
235
254
pud_t * pud , * new_pud = NULL ;
236
255
pmd_t * pmd , * new_pmd = NULL ;
237
256
pte_t * ptep , * new_ptep = NULL ;
238
- unsigned long old ;
239
257
int ret ;
240
258
241
259
/* Traverse the guest's 2nd-level tree, allocate new levels needed */
@@ -287,17 +305,7 @@ static int kvmppc_create_pte(struct kvm *kvm, pte_t pte, unsigned long gpa,
287
305
goto out_unlock ;
288
306
}
289
307
/* Valid 1GB page here already, remove it */
290
- old = kvmppc_radix_update_pte (kvm , (pte_t * )pud ,
291
- ~0UL , 0 , hgpa , PUD_SHIFT );
292
- kvmppc_radix_tlbie_page (kvm , hgpa , PUD_SHIFT );
293
- if (old & _PAGE_DIRTY ) {
294
- unsigned long gfn = hgpa >> PAGE_SHIFT ;
295
- struct kvm_memory_slot * memslot ;
296
- memslot = gfn_to_memslot (kvm , gfn );
297
- if (memslot && memslot -> dirty_bitmap )
298
- kvmppc_update_dirty_map (memslot ,
299
- gfn , PUD_SIZE );
300
- }
308
+ kvmppc_unmap_pte (kvm , (pte_t * )pud , hgpa , PUD_SHIFT );
301
309
}
302
310
if (level == 2 ) {
303
311
if (!pud_none (* pud )) {
@@ -338,17 +346,7 @@ static int kvmppc_create_pte(struct kvm *kvm, pte_t pte, unsigned long gpa,
338
346
goto out_unlock ;
339
347
}
340
348
/* Valid 2MB page here already, remove it */
341
- old = kvmppc_radix_update_pte (kvm , pmdp_ptep (pmd ),
342
- ~0UL , 0 , lgpa , PMD_SHIFT );
343
- kvmppc_radix_tlbie_page (kvm , lgpa , PMD_SHIFT );
344
- if (old & _PAGE_DIRTY ) {
345
- unsigned long gfn = lgpa >> PAGE_SHIFT ;
346
- struct kvm_memory_slot * memslot ;
347
- memslot = gfn_to_memslot (kvm , gfn );
348
- if (memslot && memslot -> dirty_bitmap )
349
- kvmppc_update_dirty_map (memslot ,
350
- gfn , PMD_SIZE );
351
- }
349
+ kvmppc_unmap_pte (kvm , pmdp_ptep (pmd ), lgpa , PMD_SHIFT );
352
350
}
353
351
if (level == 1 ) {
354
352
if (!pmd_none (* pmd )) {
@@ -373,6 +371,8 @@ static int kvmppc_create_pte(struct kvm *kvm, pte_t pte, unsigned long gpa,
373
371
}
374
372
ptep = pte_offset_kernel (pmd , gpa );
375
373
if (pte_present (* ptep )) {
374
+ unsigned long old ;
375
+
376
376
/* Check if someone else set the same thing */
377
377
if (pte_raw (* ptep ) == pte_raw (pte )) {
378
378
ret = 0 ;
0 commit comments