* 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;
unsigned quadrant : 2;
unsigned pad_for_nice_hex_output : 6;
unsigned metaphysical : 1;
- unsigned hugepage_access : 3;
+ unsigned access : 3;
};
};
gva_t gaddr,
unsigned level,
int metaphysical,
- unsigned hugepage_access,
+ unsigned access,
u64 *parent_pte)
{
union kvm_mmu_page_role role;
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;
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)) {
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));
}