Skip to contentSkip to conversation

nestedhvm: do not translate INVALID_GFN

PATCH In review Christoph Egger 2 participants 6 messages Jul 31, 2012 – Aug 2, 2012

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 nestedhvm: do not translate INVALID_GFN

Do not translate INVALID_GFN as l2 guest gfn into l1 guest gfn. Pass correct pfec for translation into l1 guest gfn. Found with Hyper-V.

Signature · 6 lines
---to satisfy European Law for business letters:
Advanced Micro Devices GmbH
Einsteinring 24, 85689 Dornach b. Muenchen
Geschaeftsfuehrer: Alberto Bozzo
Sitz: Dornach, Gemeinde Aschheim, Landkreis Muenchen
Registergericht Muenchen, HRB Nr. 43632
xen/arch/x86/mm/p2m.c +7 -0
diff -r 8330198c3240 xen/arch/x86/mm/p2m.c
@@ -1582,12 +1582,19 @@ unsigned long paging_gva_to_gfn(struct v
         struct p2m_domain *p2m;
         const struct paging_mode *mode;
         uint64_t ncr3 = nhvm_vcpu_hostcr3(v);
+        uint32_t pfec1 = *pfec;
 
         /* translate l2 guest va into l2 guest gfn */
         p2m = p2m_get_nestedp2m(v, ncr3);
         mode = paging_get_nestedmode(v);
         gfn = mode->gva_to_gfn(v, p2m, va, pfec);
 
+        /* if l1 guest maps its mmio pages into the
+         * l2 guest then we see this case here. */
+        if (gfn == INVALID_GFN)
+            return INVALID_GFN;
+        *pfec = pfec1;
+
         /* translate l2 guest gfn into l1 guest gfn */
         return hostmode->p2m_ga_to_gfn(v, hostp2m, ncr3,
                                        gfn << PAGE_SHIFT, pfec, NULL);

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

#1 lore raw

Hi,

Quoted 1 line · Christoph Egger

Do not translate INVALID_GFN as l2 guest gfn into l1 guest gfn.

Why not? l2 gfns don't have any special meaning that we can dictate from inside Xen.

Quoted 1 line

Pass correct pfec for translation into l1 guest gfn.

This seems like a good idea, but probably should happen for all entries, not just INVALID_GFN ones -- we shouldn't be returning a PFEC to the guest that comes from translations outside his control.

How about this:

xen/arch/x86/mm/p2m.c +2 -1
diff -r fdd4b7b36959 xen/arch/x86/mm/p2m.c
@@ -1581,6 +1581,7 @@ unsigned long paging_gva_to_gfn(struct v
         unsigned long gfn;
         struct p2m_domain *p2m;
         const struct paging_mode *mode;
+        uint32_t pfec_21 = *pfec;
         uint64_t ncr3 = nhvm_vcpu_hostcr3(v);
 
         /* translate l2 guest va into l2 guest gfn */
@@ -1590,7 +1591,7 @@ unsigned long paging_gva_to_gfn(struct v
 
         /* translate l2 guest gfn into l1 guest gfn */
         return hostmode->p2m_ga_to_gfn(v, hostp2m, ncr3,
-                                       gfn << PAGE_SHIFT, pfec, NULL);
+                                       gfn << PAGE_SHIFT, &pfec_21, NULL);
     }
 
     return hostmode->gva_to_gfn(v, hostp2m, va, pfec);

Cheers,

Tim.

Quoted 12 lines

Found with Hyper-V.

Signature · 6 lines
---to satisfy European Law for business letters:
Advanced Micro Devices GmbH
Einsteinring 24, 85689 Dornach b. Muenchen
Geschaeftsfuehrer: Alberto Bozzo
Sitz: Dornach, Gemeinde Aschheim, Landkreis Muenchen
Registergericht Muenchen, HRB Nr. 43632

Content-Description: xen_p2m.diff

Quoted 28 lines

diff -r 8330198c3240 xen/arch/x86/mm/p2m.c

xen/arch/x86/mm/p2m.c +7 -0
@@ -1582,12 +1582,19 @@ unsigned long paging_gva_to_gfn(struct v
         struct p2m_domain *p2m;
         const struct paging_mode *mode;
         uint64_t ncr3 = nhvm_vcpu_hostcr3(v);
+        uint32_t pfec1 = *pfec;
 
         /* translate l2 guest va into l2 guest gfn */
         p2m = p2m_get_nestedp2m(v, ncr3);
         mode = paging_get_nestedmode(v);
         gfn = mode->gva_to_gfn(v, p2m, va, pfec);
 
+        /* if l1 guest maps its mmio pages into the
+         * l2 guest then we see this case here. */
+        if (gfn == INVALID_GFN)
+            return INVALID_GFN;
+        *pfec = pfec1;
+
         /* translate l2 guest gfn into l1 guest gfn */
         return hostmode->p2m_ga_to_gfn(v, hostp2m, ncr3,
                                        gfn << PAGE_SHIFT, pfec, NULL);

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

#2 lore raw
Quoted 28 lines · Tim Deegan

Hi,

Quoted 1 line · Christoph Egger

Do not translate INVALID_GFN as l2 guest gfn into l1 guest gfn.

Why not? l2 gfns don't have any special meaning that we can dictate from inside Xen.

Quoted 1 line

Pass correct pfec for translation into l1 guest gfn.

This seems like a good idea, but probably should happen for all entries, not just INVALID_GFN ones -- we shouldn't be returning a PFEC to the guest that comes from translations outside his control.

How about this:

diff -r fdd4b7b36959 xen/arch/x86/mm/p2m.c

xen/arch/x86/mm/p2m.c +1 -0
@@ -1581,6 +1581,7 @@ unsigned long paging_gva_to_gfn(struct v
         unsigned long gfn;
         struct p2m_domain *p2m;
         const struct paging_mode *mode;
+        uint32_t pfec_21 = *pfec;
         uint64_t ncr3 = nhvm_vcpu_hostcr3(v);
 
         /* translate l2 guest va into l2 guest gfn */

xen/arch/x86/mm/p2m.c unsigned long paging_gva_to_gfn(struct v · line 1594

Quoted 5 lines
xen/arch/x86/mm/p2m.c +1 -1
@@ -1590,7 +1591,7 @@ unsigned long paging_gva_to_gfn(struct v
 
         /* translate l2 guest gfn into l1 guest gfn */
         return hostmode->p2m_ga_to_gfn(v, hostp2m, ncr3,
-                                       gfn << PAGE_SHIFT, pfec, NULL);
+                                       gfn << PAGE_SHIFT, &pfec_21, NULL);

The caller will see the return value of pfec and not from pfec_21. If this is what the caller expects then this is fine with me.

Christoph

Quoted 52 lines
xen/arch/x86/mm/p2m.c +0 -0
     }
 
     return hostmode->gva_to_gfn(v, hostp2m, va, pfec);

Cheers,

Tim.

Quoted 12 lines

Found with Hyper-V.

Signature · 6 lines
---to satisfy European Law for business letters:
Advanced Micro Devices GmbH
Einsteinring 24, 85689 Dornach b. Muenchen
Geschaeftsfuehrer: Alberto Bozzo
Sitz: Dornach, Gemeinde Aschheim, Landkreis Muenchen
Registergericht Muenchen, HRB Nr. 43632

Content-Description: xen_p2m.diff

Quoted 28 lines

diff -r 8330198c3240 xen/arch/x86/mm/p2m.c

xen/arch/x86/mm/p2m.c +7 -0
@@ -1582,12 +1582,19 @@ unsigned long paging_gva_to_gfn(struct v
         struct p2m_domain *p2m;
         const struct paging_mode *mode;
         uint64_t ncr3 = nhvm_vcpu_hostcr3(v);
+        uint32_t pfec1 = *pfec;
 
         /* translate l2 guest va into l2 guest gfn */
         p2m = p2m_get_nestedp2m(v, ncr3);
         mode = paging_get_nestedmode(v);
         gfn = mode->gva_to_gfn(v, p2m, va, pfec);
 
+        /* if l1 guest maps its mmio pages into the
+         * l2 guest then we see this case here. */
+        if (gfn == INVALID_GFN)
+            return INVALID_GFN;
+        *pfec = pfec1;
+
         /* translate l2 guest gfn into l1 guest gfn */
         return hostmode->p2m_ga_to_gfn(v, hostp2m, ncr3,
                                        gfn << PAGE_SHIFT, pfec, NULL);

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

Signature · 6 lines
---to satisfy European Law for business letters:
Advanced Micro Devices GmbH
Einsteinring 24, 85689 Dornach b. Muenchen
Geschaeftsfuehrer: Alberto Bozzo
Sitz: Dornach, Gemeinde Aschheim, Landkreis Muenchen
Registergericht Muenchen, HRB Nr. 43632
#3 lore raw
Quoted 31 lines · Christoph Egger
Quoted 29 lines · Tim Deegan

Hi,

Quoted 1 line · Christoph Egger

Do not translate INVALID_GFN as l2 guest gfn into l1 guest gfn.

Why not? l2 gfns don't have any special meaning that we can dictate from inside Xen.

Quoted 1 line

Pass correct pfec for translation into l1 guest gfn.

This seems like a good idea, but probably should happen for all entries, not just INVALID_GFN ones -- we shouldn't be returning a PFEC to the guest that comes from translations outside his control.

How about this:

diff -r fdd4b7b36959 xen/arch/x86/mm/p2m.c

xen/arch/x86/mm/p2m.c +1 -0
@@ -1581,6 +1581,7 @@ unsigned long paging_gva_to_gfn(struct v
         unsigned long gfn;
         struct p2m_domain *p2m;
         const struct paging_mode *mode;
+        uint32_t pfec_21 = *pfec;
         uint64_t ncr3 = nhvm_vcpu_hostcr3(v);
 
         /* translate l2 guest va into l2 guest gfn */
@@ -1590,7 +1591,7 @@ unsigned long paging_gva_to_gfn(struct v
 
Quoted 8 lines

xen/arch/x86/mm/p2m.c unsigned long paging_gva_to_gfn(struct v · line 1594

Quoted 4 lines
xen/arch/x86/mm/p2m.c +1 -1
         /* translate l2 guest gfn into l1 guest gfn */
         return hostmode->p2m_ga_to_gfn(v, hostp2m, ncr3,
-                                       gfn << PAGE_SHIFT, pfec, NULL);
+                                       gfn << PAGE_SHIFT, &pfec_21, NULL);

The caller will see the return value of pfec and not from pfec_21. If this is what the caller expects then this is fine with me.

Yes, I think that is what the caller expects -- the error code is made up from the pagetable walk rather than from the p2m table.

Can I take that as an ack?

And more importantly, does it fix the Hyper-V problem you encountered?

Cheers,

Tim

#4 lore raw
Quoted 41 lines · Tim Deegan
Quoted 31 lines · Christoph Egger
Quoted 29 lines · Tim Deegan

Hi,

Quoted 1 line · Christoph Egger

Do not translate INVALID_GFN as l2 guest gfn into l1 guest gfn.

Why not? l2 gfns don't have any special meaning that we can dictate from inside Xen.

Quoted 1 line

Pass correct pfec for translation into l1 guest gfn.

This seems like a good idea, but probably should happen for all entries, not just INVALID_GFN ones -- we shouldn't be returning a PFEC to the guest that comes from translations outside his control.

How about this:

diff -r fdd4b7b36959 xen/arch/x86/mm/p2m.c

xen/arch/x86/mm/p2m.c +1 -0
@@ -1581,6 +1581,7 @@ unsigned long paging_gva_to_gfn(struct v
         unsigned long gfn;
         struct p2m_domain *p2m;
         const struct paging_mode *mode;
+        uint32_t pfec_21 = *pfec;
         uint64_t ncr3 = nhvm_vcpu_hostcr3(v);
 
         /* translate l2 guest va into l2 guest gfn */
@@ -1590,7 +1591,7 @@ unsigned long paging_gva_to_gfn(struct v
 
Quoted 8 lines

xen/arch/x86/mm/p2m.c unsigned long paging_gva_to_gfn(struct v · line 1594

Quoted 4 lines
xen/arch/x86/mm/p2m.c +1 -1
         /* translate l2 guest gfn into l1 guest gfn */
         return hostmode->p2m_ga_to_gfn(v, hostp2m, ncr3,
-                                       gfn << PAGE_SHIFT, pfec, NULL);
+                                       gfn << PAGE_SHIFT, &pfec_21, NULL);

The caller will see the return value of pfec and not from pfec_21. If this is what the caller expects then this is fine with me.

Quoted 4 lines

Yes, I think that is what the caller expects -- the error code is made up from the pagetable walk rather than from the p2m table.

Can I take that as an ack?

Yes.

Quoted 1 line

And more importantly, does it fix the Hyper-V problem you encountered?

The one you mean is covered with the other patch. But I found this with Hyper-V when doing MMIO accesses.

Christoph

Signature · 6 lines
---to satisfy European Law for business letters:
Advanced Micro Devices GmbH
Einsteinring 24, 85689 Dornach b. Muenchen
Geschaeftsfuehrer: Alberto Bozzo
Sitz: Dornach, Gemeinde Aschheim, Landkreis Muenchen
Registergericht Muenchen, HRB Nr. 43632
#5 lore raw
Quoted 6 lines · Christoph Egger
Quoted 4 lines

Yes, I think that is what the caller expects -- the error code is made up from the pagetable walk rather than from the p2m table.

Can I take that as an ack?

Yes.

Thanks; I've applied it.

Tim.