Skip to content

Commit

Permalink
[PATCH] KVM: MMU: Ignore pcd, pwt, and pat bits on ptes
Browse files Browse the repository at this point in the history
The pcd, pwt, and pat bits on page table entries affect the cpu cache.  Since
the cache is a host resource, the guest should not be able to control it.
Moreover, the meaning of these bits changes depending on whether pat is
enabled or not.

So, force these bits to zero on shadow page table entries at all times.

Signed-off-by: Avi Kivity <avi@qumranet.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
  • Loading branch information
Avi Kivity authored and Linus Torvalds committed Dec 13, 2006
1 parent 0770b19 commit 8c7bb72
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 28 deletions.
17 changes: 2 additions & 15 deletions drivers/kvm/mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,22 +61,9 @@


#define PT32_PTE_COPY_MASK \
(PT_PRESENT_MASK | PT_PWT_MASK | PT_PCD_MASK | \
PT_ACCESSED_MASK | PT_DIRTY_MASK | PT_PAT_MASK | \
PT_GLOBAL_MASK )

#define PT32_NON_PTE_COPY_MASK \
(PT_PRESENT_MASK | PT_PWT_MASK | PT_PCD_MASK | \
PT_ACCESSED_MASK | PT_DIRTY_MASK)


#define PT64_PTE_COPY_MASK \
(PT64_NX_MASK | PT32_PTE_COPY_MASK)

#define PT64_NON_PTE_COPY_MASK \
(PT64_NX_MASK | PT32_NON_PTE_COPY_MASK)

(PT_PRESENT_MASK | PT_ACCESSED_MASK | PT_DIRTY_MASK | PT_GLOBAL_MASK)

#define PT64_PTE_COPY_MASK (PT64_NX_MASK | PT32_PTE_COPY_MASK)

#define PT_FIRST_AVAIL_BITS_SHIFT 9
#define PT64_SECOND_AVAIL_BITS_SHIFT 52
Expand Down
20 changes: 7 additions & 13 deletions drivers/kvm/paging_tmpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
#define SHADOW_PT_INDEX(addr, level) PT64_INDEX(addr, level)
#define PT_LEVEL_MASK(level) PT64_LEVEL_MASK(level)
#define PT_PTE_COPY_MASK PT64_PTE_COPY_MASK
#define PT_NON_PTE_COPY_MASK PT64_NON_PTE_COPY_MASK
#elif PTTYPE == 32
#define pt_element_t u32
#define guest_walker guest_walker32
Expand All @@ -43,7 +42,6 @@
#define SHADOW_PT_INDEX(addr, level) PT64_INDEX(addr, level)
#define PT_LEVEL_MASK(level) PT32_LEVEL_MASK(level)
#define PT_PTE_COPY_MASK PT32_PTE_COPY_MASK
#define PT_NON_PTE_COPY_MASK PT32_NON_PTE_COPY_MASK
#else
#error Invalid PTTYPE value
#endif
Expand Down Expand Up @@ -105,9 +103,7 @@ static void FNAME(set_pde)(struct kvm_vcpu *vcpu, u64 guest_pde,
if (PTTYPE == 32 && is_cpuid_PSE36())
gaddr |= (guest_pde & PT32_DIR_PSE36_MASK) <<
(32 - PT32_DIR_PSE36_SHIFT);
*shadow_pte = (guest_pde & (PT_NON_PTE_COPY_MASK | PT_GLOBAL_MASK)) |
((guest_pde & PT_DIR_PAT_MASK) >>
(PT_DIR_PAT_SHIFT - PT_PAT_SHIFT));
*shadow_pte = guest_pde & PT_PTE_COPY_MASK;
set_pte_common(vcpu, shadow_pte, gaddr,
guest_pde & PT_DIRTY_MASK, access_bits);
}
Expand Down Expand Up @@ -162,6 +158,7 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
u32 index = SHADOW_PT_INDEX(addr, level);
u64 *shadow_ent = ((u64 *)__va(shadow_addr)) + index;
pt_element_t *guest_ent;
u64 shadow_pte;

if (is_present_pte(*shadow_ent) || is_io_pte(*shadow_ent)) {
if (level == PT_PAGE_TABLE_LEVEL)
Expand Down Expand Up @@ -204,14 +201,11 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
shadow_addr = kvm_mmu_alloc_page(vcpu, shadow_ent);
if (!VALID_PAGE(shadow_addr))
return ERR_PTR(-ENOMEM);
if (!kvm_arch_ops->is_long_mode(vcpu) && level == 3)
*shadow_ent = shadow_addr |
(*guest_ent & (PT_PRESENT_MASK | PT_PWT_MASK | PT_PCD_MASK));
else {
*shadow_ent = shadow_addr |
(*guest_ent & PT_NON_PTE_COPY_MASK);
*shadow_ent |= (PT_WRITABLE_MASK | PT_USER_MASK);
}
shadow_pte = shadow_addr | PT_PRESENT_MASK;
if (vcpu->mmu.root_level > 3 || level != 3)
shadow_pte |= PT_ACCESSED_MASK
| PT_WRITABLE_MASK | PT_USER_MASK;
*shadow_ent = shadow_pte;
prev_shadow_ent = shadow_ent;
}
}
Expand Down

0 comments on commit 8c7bb72

Please sign in to comment.