aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/mmu.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kvm/mmu.c')
-rw-r--r--arch/x86/kvm/mmu.c60
1 files changed, 52 insertions, 8 deletions
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 9cd5a717ede..dd76765310c 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -1504,6 +1504,12 @@ static void shadow_walk_init(struct kvm_shadow_walk_iterator *iterator,
1504 iterator->addr = addr; 1504 iterator->addr = addr;
1505 iterator->shadow_addr = vcpu->arch.mmu.root_hpa; 1505 iterator->shadow_addr = vcpu->arch.mmu.root_hpa;
1506 iterator->level = vcpu->arch.mmu.shadow_root_level; 1506 iterator->level = vcpu->arch.mmu.shadow_root_level;
1507
1508 if (iterator->level == PT64_ROOT_LEVEL &&
1509 vcpu->arch.mmu.root_level < PT64_ROOT_LEVEL &&
1510 !vcpu->arch.mmu.direct_map)
1511 --iterator->level;
1512
1507 if (iterator->level == PT32E_ROOT_LEVEL) { 1513 if (iterator->level == PT32E_ROOT_LEVEL) {
1508 iterator->shadow_addr 1514 iterator->shadow_addr
1509 = vcpu->arch.mmu.pae_root[(addr >> 30) & 3]; 1515 = vcpu->arch.mmu.pae_root[(addr >> 30) & 3];
@@ -2314,7 +2320,9 @@ static void mmu_free_roots(struct kvm_vcpu *vcpu)
2314 if (!VALID_PAGE(vcpu->arch.mmu.root_hpa)) 2320 if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
2315 return; 2321 return;
2316 spin_lock(&vcpu->kvm->mmu_lock); 2322 spin_lock(&vcpu->kvm->mmu_lock);
2317 if (vcpu->arch.mmu.shadow_root_level == PT64_ROOT_LEVEL) { 2323 if (vcpu->arch.mmu.shadow_root_level == PT64_ROOT_LEVEL &&
2324 (vcpu->arch.mmu.root_level == PT64_ROOT_LEVEL ||
2325 vcpu->arch.mmu.direct_map)) {
2318 hpa_t root = vcpu->arch.mmu.root_hpa; 2326 hpa_t root = vcpu->arch.mmu.root_hpa;
2319 2327
2320 sp = page_header(root); 2328 sp = page_header(root);
@@ -2394,10 +2402,10 @@ static int mmu_alloc_direct_roots(struct kvm_vcpu *vcpu)
2394 2402
2395static int mmu_alloc_shadow_roots(struct kvm_vcpu *vcpu) 2403static int mmu_alloc_shadow_roots(struct kvm_vcpu *vcpu)
2396{ 2404{
2397 int i;
2398 gfn_t root_gfn;
2399 struct kvm_mmu_page *sp; 2405 struct kvm_mmu_page *sp;
2400 u64 pdptr; 2406 u64 pdptr, pm_mask;
2407 gfn_t root_gfn;
2408 int i;
2401 2409
2402 root_gfn = vcpu->arch.mmu.get_cr3(vcpu) >> PAGE_SHIFT; 2410 root_gfn = vcpu->arch.mmu.get_cr3(vcpu) >> PAGE_SHIFT;
2403 2411
@@ -2426,8 +2434,13 @@ static int mmu_alloc_shadow_roots(struct kvm_vcpu *vcpu)
2426 2434
2427 /* 2435 /*
2428 * We shadow a 32 bit page table. This may be a legacy 2-level 2436 * We shadow a 32 bit page table. This may be a legacy 2-level
2429 * or a PAE 3-level page table. 2437 * or a PAE 3-level page table. In either case we need to be aware that
2438 * the shadow page table may be a PAE or a long mode page table.
2430 */ 2439 */
2440 pm_mask = PT_PRESENT_MASK;
2441 if (vcpu->arch.mmu.shadow_root_level == PT64_ROOT_LEVEL)
2442 pm_mask |= PT_ACCESSED_MASK | PT_WRITABLE_MASK | PT_USER_MASK;
2443
2431 for (i = 0; i < 4; ++i) { 2444 for (i = 0; i < 4; ++i) {
2432 hpa_t root = vcpu->arch.mmu.pae_root[i]; 2445 hpa_t root = vcpu->arch.mmu.pae_root[i];
2433 2446
@@ -2451,9 +2464,35 @@ static int mmu_alloc_shadow_roots(struct kvm_vcpu *vcpu)
2451 ++sp->root_count; 2464 ++sp->root_count;
2452 spin_unlock(&vcpu->kvm->mmu_lock); 2465 spin_unlock(&vcpu->kvm->mmu_lock);
2453 2466
2454 vcpu->arch.mmu.pae_root[i] = root | PT_PRESENT_MASK; 2467 vcpu->arch.mmu.pae_root[i] = root | pm_mask;
2468 vcpu->arch.mmu.root_hpa = __pa(vcpu->arch.mmu.pae_root);
2455 } 2469 }
2456 vcpu->arch.mmu.root_hpa = __pa(vcpu->arch.mmu.pae_root); 2470
2471 /*
2472 * If we shadow a 32 bit page table with a long mode page
2473 * table we enter this path.
2474 */
2475 if (vcpu->arch.mmu.shadow_root_level == PT64_ROOT_LEVEL) {
2476 if (vcpu->arch.mmu.lm_root == NULL) {
2477 /*
2478 * The additional page necessary for this is only
2479 * allocated on demand.
2480 */
2481
2482 u64 *lm_root;
2483
2484 lm_root = (void*)get_zeroed_page(GFP_KERNEL);
2485 if (lm_root == NULL)
2486 return 1;
2487
2488 lm_root[0] = __pa(vcpu->arch.mmu.pae_root) | pm_mask;
2489
2490 vcpu->arch.mmu.lm_root = lm_root;
2491 }
2492
2493 vcpu->arch.mmu.root_hpa = __pa(vcpu->arch.mmu.lm_root);
2494 }
2495
2457 return 0; 2496 return 0;
2458} 2497}
2459 2498
@@ -2470,9 +2509,12 @@ static void mmu_sync_roots(struct kvm_vcpu *vcpu)
2470 int i; 2509 int i;
2471 struct kvm_mmu_page *sp; 2510 struct kvm_mmu_page *sp;
2472 2511
2512 if (vcpu->arch.mmu.direct_map)
2513 return;
2514
2473 if (!VALID_PAGE(vcpu->arch.mmu.root_hpa)) 2515 if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
2474 return; 2516 return;
2475 if (vcpu->arch.mmu.shadow_root_level == PT64_ROOT_LEVEL) { 2517 if (vcpu->arch.mmu.root_level == PT64_ROOT_LEVEL) {
2476 hpa_t root = vcpu->arch.mmu.root_hpa; 2518 hpa_t root = vcpu->arch.mmu.root_hpa;
2477 sp = page_header(root); 2519 sp = page_header(root);
2478 mmu_sync_children(vcpu, sp); 2520 mmu_sync_children(vcpu, sp);
@@ -3253,6 +3295,8 @@ EXPORT_SYMBOL_GPL(kvm_disable_tdp);
3253static void free_mmu_pages(struct kvm_vcpu *vcpu) 3295static void free_mmu_pages(struct kvm_vcpu *vcpu)
3254{ 3296{
3255 free_page((unsigned long)vcpu->arch.mmu.pae_root); 3297 free_page((unsigned long)vcpu->arch.mmu.pae_root);
3298 if (vcpu->arch.mmu.lm_root != NULL)
3299 free_page((unsigned long)vcpu->arch.mmu.lm_root);
3256} 3300}
3257 3301
3258static int alloc_mmu_pages(struct kvm_vcpu *vcpu) 3302static int alloc_mmu_pages(struct kvm_vcpu *vcpu)