Avi Kivity wrote:
> On a pte update, npte will always be 1.  On a pde update, we won't do
> anything in mmu_pte_write_new_pte because it doesn't handle
> pdes.  If we
> extend it to handle pdes, then we need either to modify the
> new gpde or
> to have the update take the quadrant into account.

Agree, so we either just skip npte=2 branch or polish it.
How about following changes?  

diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c
index c85c664..37a7dc5 100644
--- a/drivers/kvm/mmu.c
+++ b/drivers/kvm/mmu.c
@@ -1156,7 +1156,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu,
gpa_t gpa,
        struct hlist_node *node, *n;
        struct hlist_head *bucket;
        unsigned index;
-       u64 *spte;
+       u64 *spte, gpte[2];
        unsigned offset = offset_in_page(gpa);
        unsigned pte_size;
        unsigned page_offset;
@@ -1164,7 +1164,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu,
gpa_t gpa,
        unsigned quadrant;
        int level;
        int flooded = 0;
-       int npte;
+       int npte, i;
 
        pgprintk("%s: gpa %llx bytes %d\n", __FUNCTION__, gpa, bytes);
        if (gfn == vcpu->last_pt_write_gfn) {
@@ -1202,6 +1202,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu,
gpa_t gpa,
                page_offset = offset;
                level = page->role.level;
                npte = 1;
+               gpte[0] = *(long*)new;
                if (page->role.glevels == PT32_ROOT_LEVEL) {
                        page_offset <<= 1;      /* 32->64 */
                        /*
@@ -1209,10 +1210,16 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu,
gpa_t gpa,
                         * only 2MB.  So we need to double the offset
again
                         * and zap two pdes instead of one.
                         */
-                       if (level == PT32_ROOT_LEVEL) {
+                       if ((level == PT_DIRECTORY_LEVEL) &&
+                               (vcpu->cr4 & CR4_PSE_MASK) &&
+                               (gpte[0] & PT_PAGE_SIZE_MASK)) {
                                page_offset &= ~7; /* kill rounding
error */
                                page_offset <<= 1;
                                npte = 2;
+                               gpte[1] = gpte[0];
+                               gpte[1] += 1 << 21;
                        }
                        quadrant = page_offset >> PAGE_SHIFT;
                        page_offset &= ~PAGE_MASK;
@@ -1220,9 +1227,9 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu,
gpa_t gpa,
                                continue;
                }
                spte = &page->spt[page_offset / sizeof(*spte)];
-               while (npte--) {
+               for (i=0; i < npte; i++) {
                        mmu_pte_write_zap_pte(vcpu, page, spte);
-                       mmu_pte_write_new_pte(vcpu, page, spte, new,
bytes);
+                       mmu_pte_write_new_pte(vcpu, page, spte,
&gpte[i], bytes);
                        ++spte;
                }
        }

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
kvm-devel mailing list
kvm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-devel

Reply via email to