Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6598c8b2 authored by Avi Kivity's avatar Avi Kivity
Browse files

KVM: MMU: Pass the guest pde to set_pte_common



We will need the accessed bit (in addition to the dirty bit) and
also write access (for setting the dirty bit) in a future patch.

Signed-off-by: default avatarAvi Kivity <avi@qumranet.com>
parent e60d75ea
Loading
Loading
Loading
Loading
+15 −14
Original line number Original line Diff line number Diff line
@@ -195,11 +195,12 @@ static void FNAME(mark_pagetable_dirty)(struct kvm *kvm,
static void FNAME(set_pte_common)(struct kvm_vcpu *vcpu,
static void FNAME(set_pte_common)(struct kvm_vcpu *vcpu,
				  u64 *shadow_pte,
				  u64 *shadow_pte,
				  gpa_t gaddr,
				  gpa_t gaddr,
				  int dirty,
				  pt_element_t *gpte,
				  u64 access_bits,
				  u64 access_bits,
				  gfn_t gfn)
				  gfn_t gfn)
{
{
	hpa_t paddr;
	hpa_t paddr;
	int dirty = *gpte & PT_DIRTY_MASK;


	*shadow_pte |= access_bits << PT_SHADOW_BITS_OFFSET;
	*shadow_pte |= access_bits << PT_SHADOW_BITS_OFFSET;
	if (!dirty)
	if (!dirty)
@@ -240,14 +241,14 @@ static void FNAME(set_pte_common)(struct kvm_vcpu *vcpu,
	rmap_add(vcpu, shadow_pte);
	rmap_add(vcpu, shadow_pte);
}
}


static void FNAME(set_pte)(struct kvm_vcpu *vcpu, u64 guest_pte,
static void FNAME(set_pte)(struct kvm_vcpu *vcpu, pt_element_t *gpte,
			   u64 *shadow_pte, u64 access_bits, gfn_t gfn)
			   u64 *shadow_pte, u64 access_bits, gfn_t gfn)
{
{
	ASSERT(*shadow_pte == 0);
	ASSERT(*shadow_pte == 0);
	access_bits &= guest_pte;
	access_bits &= *gpte;
	*shadow_pte = (guest_pte & PT_PTE_COPY_MASK);
	*shadow_pte = (*gpte & PT_PTE_COPY_MASK);
	FNAME(set_pte_common)(vcpu, shadow_pte, guest_pte & PT_BASE_ADDR_MASK,
	FNAME(set_pte_common)(vcpu, shadow_pte, *gpte & PT_BASE_ADDR_MASK,
			      guest_pte & PT_DIRTY_MASK, access_bits, gfn);
			      gpte, access_bits, gfn);
}
}


static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page,
static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page,
@@ -261,24 +262,24 @@ static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page,
	if (~gpte & (PT_PRESENT_MASK | PT_ACCESSED_MASK))
	if (~gpte & (PT_PRESENT_MASK | PT_ACCESSED_MASK))
		return;
		return;
	pgprintk("%s: gpte %llx spte %p\n", __FUNCTION__, (u64)gpte, spte);
	pgprintk("%s: gpte %llx spte %p\n", __FUNCTION__, (u64)gpte, spte);
	FNAME(set_pte)(vcpu, gpte, spte, PT_USER_MASK | PT_WRITABLE_MASK,
	FNAME(set_pte)(vcpu, &gpte, spte, PT_USER_MASK | PT_WRITABLE_MASK,
		       (gpte & PT_BASE_ADDR_MASK) >> PAGE_SHIFT);
		       (gpte & PT_BASE_ADDR_MASK) >> PAGE_SHIFT);
}
}


static void FNAME(set_pde)(struct kvm_vcpu *vcpu, u64 guest_pde,
static void FNAME(set_pde)(struct kvm_vcpu *vcpu, pt_element_t *gpde,
			   u64 *shadow_pte, u64 access_bits, gfn_t gfn)
			   u64 *shadow_pte, u64 access_bits, gfn_t gfn)
{
{
	gpa_t gaddr;
	gpa_t gaddr;


	ASSERT(*shadow_pte == 0);
	ASSERT(*shadow_pte == 0);
	access_bits &= guest_pde;
	access_bits &= *gpde;
	gaddr = (gpa_t)gfn << PAGE_SHIFT;
	gaddr = (gpa_t)gfn << PAGE_SHIFT;
	if (PTTYPE == 32 && is_cpuid_PSE36())
	if (PTTYPE == 32 && is_cpuid_PSE36())
		gaddr |= (guest_pde & PT32_DIR_PSE36_MASK) <<
		gaddr |= (*gpde & PT32_DIR_PSE36_MASK) <<
			(32 - PT32_DIR_PSE36_SHIFT);
			(32 - PT32_DIR_PSE36_SHIFT);
	*shadow_pte = guest_pde & PT_PTE_COPY_MASK;
	*shadow_pte = *gpde & PT_PTE_COPY_MASK;
	FNAME(set_pte_common)(vcpu, shadow_pte, gaddr,
	FNAME(set_pte_common)(vcpu, shadow_pte, gaddr,
			      guest_pde & PT_DIRTY_MASK, access_bits, gfn);
			      gpde, access_bits, gfn);
}
}


/*
/*
@@ -349,11 +350,11 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
	if (walker->level == PT_DIRECTORY_LEVEL) {
	if (walker->level == PT_DIRECTORY_LEVEL) {
		if (prev_shadow_ent)
		if (prev_shadow_ent)
			*prev_shadow_ent |= PT_SHADOW_PS_MARK;
			*prev_shadow_ent |= PT_SHADOW_PS_MARK;
		FNAME(set_pde)(vcpu, *guest_ent, shadow_ent,
		FNAME(set_pde)(vcpu, guest_ent, shadow_ent,
			       walker->inherited_ar, walker->gfn);
			       walker->inherited_ar, walker->gfn);
	} else {
	} else {
		ASSERT(walker->level == PT_PAGE_TABLE_LEVEL);
		ASSERT(walker->level == PT_PAGE_TABLE_LEVEL);
		FNAME(set_pte)(vcpu, *guest_ent, shadow_ent,
		FNAME(set_pte)(vcpu, guest_ent, shadow_ent,
			       walker->inherited_ar,
			       walker->inherited_ar,
			       walker->gfn);
			       walker->gfn);
	}
	}