KVM: MMU: Replace role.glevels with role.cr4_pae
authorAvi Kivity <avi@redhat.com>
Wed, 14 Apr 2010 16:20:03 +0000 (19:20 +0300)
committerAvi Kivity <avi@redhat.com>
Mon, 17 May 2010 09:17:47 +0000 (12:17 +0300)
There is no real distinction between glevels=3 and glevels=4; both have
exactly the same format and the code is treated exactly the same way.  Drop
role.glevels and replace is with role.cr4_pae (which is meaningful).  This
simplifies the code a bit.

As a side effect, it allows sharing shadow page tables between pae and
longmode guest page tables at the same guest page.

Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
arch/x86/include/asm/kvm_host.h
arch/x86/kvm/mmu.c
arch/x86/kvm/mmutrace.h

index 3602728d54de78a3595f5383ea6ebaa88343f885..707d272ae4a143c9a10b609ee73af81992b49e09 100644 (file)
@@ -171,8 +171,8 @@ struct kvm_pte_chain {
 union kvm_mmu_page_role {
        unsigned word;
        struct {
-               unsigned glevels:4;
                unsigned level:4;
+               unsigned cr4_pae:1;
                unsigned quadrant:2;
                unsigned pad_for_nice_hex_output:6;
                unsigned direct:1;
index ec8900b6692a96dd6ddde3cbfa0e3faa80d930f2..51aa580d0aa5bbb8ff24b42d6c0733bd0884543d 100644 (file)
@@ -1206,7 +1206,7 @@ static int kvm_mmu_zap_page(struct kvm *kvm, struct kvm_mmu_page *sp);
 
 static int kvm_sync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
 {
-       if (sp->role.glevels != vcpu->arch.mmu.root_level) {
+       if (sp->role.cr4_pae != !!is_pae(vcpu)) {
                kvm_mmu_zap_page(vcpu->kvm, sp);
                return 1;
        }
@@ -1329,7 +1329,7 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
        role.level = level;
        role.direct = direct;
        if (role.direct)
-               role.glevels = 0;
+               role.cr4_pae = 0;
        role.access = access;
        if (vcpu->arch.mmu.root_level <= PT32_ROOT_LEVEL) {
                quadrant = gaddr >> (PAGE_SHIFT + (PT64_PT_BITS * level));
@@ -2443,7 +2443,7 @@ static int init_kvm_softmmu(struct kvm_vcpu *vcpu)
        else
                r = paging32_init_context(vcpu);
 
-       vcpu->arch.mmu.base_role.glevels = vcpu->arch.mmu.root_level;
+       vcpu->arch.mmu.base_role.cr4_pae = !!is_pae(vcpu);
 
        return r;
 }
@@ -2532,7 +2532,7 @@ static void mmu_pte_write_new_pte(struct kvm_vcpu *vcpu,
         }
 
        ++vcpu->kvm->stat.mmu_pte_updated;
-       if (sp->role.glevels == PT32_ROOT_LEVEL)
+       if (!sp->role.cr4_pae)
                paging32_update_pte(vcpu, sp, spte, new);
        else
                paging64_update_pte(vcpu, sp, spte, new);
@@ -2681,7 +2681,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
        hlist_for_each_entry_safe(sp, node, n, bucket, hash_link) {
                if (sp->gfn != gfn || sp->role.direct || sp->role.invalid)
                        continue;
-               pte_size = sp->role.glevels == PT32_ROOT_LEVEL ? 4 : 8;
+               pte_size = sp->role.cr4_pae ? 8 : 4;
                misaligned = (offset ^ (offset + bytes - 1)) & ~(pte_size - 1);
                misaligned |= bytes < 4;
                if (misaligned || flooded) {
@@ -2705,7 +2705,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
                page_offset = offset;
                level = sp->role.level;
                npte = 1;
-               if (sp->role.glevels == PT32_ROOT_LEVEL) {
+               if (!sp->role.cr4_pae) {
                        page_offset <<= 1;      /* 32->64 */
                        /*
                         * A 32-bit pde maps 4MB while the shadow pdes map
index 1fe956ab76171e1e27fb86f1089d81dca7a0af66..3851f1f3030cd8be25a23d38218185605022c9a2 100644 (file)
                                                                        \
        role.word = __entry->role;                                      \
                                                                        \
-       trace_seq_printf(p, "sp gfn %llx %u/%u q%u%s %s%s %spge"        \
+       trace_seq_printf(p, "sp gfn %llx %u%s q%u%s %s%s %spge"         \
                         " %snxe root %u %s%c",                         \
-                        __entry->gfn, role.level, role.glevels,        \
+                        __entry->gfn, role.level,                      \
+                        role.cr4_pae ? " pae" : "",                    \
                         role.quadrant,                                 \
                         role.direct ? " direct" : "",                  \
                         access_str[role.access],                       \