Skip to content

Commit

Permalink
KVM: MMU: Fix inherited permissions for emulated guest pte updates
Browse files Browse the repository at this point in the history
When we emulate a guest pte write, we fail to apply the correct inherited
permissions from the parent ptes.  Now that we store inherited permissions
in the shadow page, we can use that to update the pte permissions correctly.

Signed-off-by: Avi Kivity <avi@qumranet.com>
  • Loading branch information
avikivity committed Jan 30, 2008
1 parent bedbe4e commit 41074d0
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 5 deletions.
4 changes: 2 additions & 2 deletions drivers/kvm/kvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ struct kvm_pte_chain {
* bits 4:7 - page table level for this shadow (1-4)
* bits 8:9 - page table quadrant for 2-level guests
* bit 16 - "metaphysical" - gfn is not a real page (huge page/real mode)
* bits 17:19 - "access" - the user, writable, and nx bits of a huge page pde
* bits 17:19 - common access permissions for all ptes in this shadow page
*/
union kvm_mmu_page_role {
unsigned word;
Expand All @@ -65,7 +65,7 @@ union kvm_mmu_page_role {
unsigned quadrant : 2;
unsigned pad_for_nice_hex_output : 6;
unsigned metaphysical : 1;
unsigned hugepage_access : 3;
unsigned access : 3;
};
};

Expand Down
4 changes: 2 additions & 2 deletions drivers/kvm/mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,7 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
gva_t gaddr,
unsigned level,
int metaphysical,
unsigned hugepage_access,
unsigned access,
u64 *parent_pte)
{
union kvm_mmu_page_role role;
Expand All @@ -694,7 +694,7 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
role.glevels = vcpu->mmu.root_level;
role.level = level;
role.metaphysical = metaphysical;
role.hugepage_access = hugepage_access;
role.access = access;
if (vcpu->mmu.root_level <= PT32_ROOT_LEVEL) {
quadrant = gaddr >> (PAGE_SHIFT + (PT64_PT_BITS * level));
quadrant &= (1 << ((PT32_PT_BITS - PT64_PT_BITS) * level)) - 1;
Expand Down
4 changes: 3 additions & 1 deletion drivers/kvm/paging_tmpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@ static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page,
int offset_in_pte)
{
pt_element_t gpte;
unsigned pte_access;

gpte = *(const pt_element_t *)pte;
if (~gpte & (PT_PRESENT_MASK | PT_ACCESSED_MASK)) {
Expand All @@ -337,7 +338,8 @@ static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page,
if (bytes < sizeof(pt_element_t))
return;
pgprintk("%s: gpte %llx spte %p\n", __FUNCTION__, (u64)gpte, spte);
FNAME(set_pte)(vcpu, gpte, spte, ACC_ALL, ACC_ALL,
pte_access = page->role.access & FNAME(gpte_access)(vcpu, gpte);
FNAME(set_pte)(vcpu, gpte, spte, page->role.access, pte_access,
0, 0, NULL, NULL, gpte_to_gfn(gpte));
}

Expand Down

0 comments on commit 41074d0

Please sign in to comment.