[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v8 20/20] xenctx: Ensure errno is not zero on error in xc_translate_foreign_address()



This is because xc_translate_foreign_address() returns 0 in both the
error case and when 0 is the mfn.  By making sure that errno is set
callers can now determine if it is an error or not.

Fixup map_page() to set errno to zero (0) to improve error handling.

Also call on perror() in map_page().

Signed-off-by: Don Slutz <dslutz@xxxxxxxxxxx>
---
 tools/libxc/xc_pagetab.c | 48 +++++++++++++++++++++++++++++++++++++++++-------
 tools/xentrace/xenctx.c  | 22 +++++++++++++++++++---
 2 files changed, 60 insertions(+), 10 deletions(-)

diff --git a/tools/libxc/xc_pagetab.c b/tools/libxc/xc_pagetab.c
index 9d3349f..5c8049b 100644
--- a/tools/libxc/xc_pagetab.c
+++ b/tools/libxc/xc_pagetab.c
@@ -35,12 +35,17 @@ unsigned long xc_translate_foreign_address(xc_interface 
*xch, uint32_t dom,
     int size, level, pt_levels = 2;
     void *map;
 
-    if (xc_domain_getinfo(xch, dom, 1, &dominfo) != 1 
-        || dominfo.domid != dom)
+    if ( xc_domain_getinfo(xch, dom, 1, &dominfo) != 1
+         || dominfo.domid != dom )
+    {
+        if ( !errno )
+            errno = EINVAL;
         return 0;
+    }
 
     /* What kind of paging are we dealing with? */
-    if (dominfo.hvm) {
+    if ( dominfo.hvm )
+    {
         struct hvm_hw_cpu hvm_ctx;
         if (xc_domain_hvm_getcontext_partial(xch, dom,
                                              HVM_SAVE_CODE(CPU), vcpu,
@@ -50,14 +55,26 @@ unsigned long xc_translate_foreign_address(xc_interface 
*xch, uint32_t dom,
             vcpu_guest_context_any_t ctx;
 
             if ( errno != EBADSLT )
+            {
+                if ( !errno )
+                    errno = EINVAL;
                 return 0;
+            }
             /*
              * Offline CPU, use xc_vcpu_getcontext() if possible
              */
             if ( xc_vcpu_getcontext(xch, dom, vcpu, &ctx) != 0 )
+            {
+                if ( !errno )
+                    errno = EINVAL;
                 return 0;
+            }
             if ( xc_domain_get_guest_width(xch, dom, &gwidth) != 0 )
+            {
+                if ( !errno )
+                    errno = EINVAL;
                 return 0;
+            }
             if ( gwidth == 8 )
             {
                 if ( !(ctx.x64.ctrlreg[0] & CR0_PG) )
@@ -85,10 +102,18 @@ unsigned long xc_translate_foreign_address(xc_interface 
*xch, uint32_t dom,
     } else {
         unsigned int gwidth;
         vcpu_guest_context_any_t ctx;
-        if (xc_vcpu_getcontext(xch, dom, vcpu, &ctx) != 0)
+        if ( xc_vcpu_getcontext(xch, dom, vcpu, &ctx) != 0 )
+        {
+            if ( !errno )
+                errno = EINVAL;
             return 0;
+        }
         if (xc_domain_get_guest_width(xch, dom, &gwidth) != 0)
+        {
+            if ( !errno )
+                errno = EINVAL;
             return 0;
+        }
         if (gwidth == 8) {
             pt_levels = 4;
             paddr = (uint64_t)xen_cr3_to_pfn_x86_64(ctx.x64.ctrlreg[3])
@@ -117,14 +142,23 @@ unsigned long xc_translate_foreign_address(xc_interface 
*xch, uint32_t dom,
         paddr += ((virt & mask) >> (xc_ffs64(mask) - 1)) * size;
         map = xc_map_foreign_range(xch, dom, PAGE_SIZE, PROT_READ, 
                                    paddr >>PAGE_SHIFT);
-        if (!map) 
+        if ( !map )
+        {
+            if ( !errno )
+                errno = EINVAL;
             return 0;
+        }
         memcpy(&pte, map + (paddr & (PAGE_SIZE - 1)), size);
         munmap(map, PAGE_SIZE);
-        if (!(pte & 1)) 
+        if ( !(pte & 1) )
+        {
+            if ( !errno )
+                errno = EADDRNOTAVAIL;
             return 0;
+        }
         paddr = pte & 0x000ffffffffff000ull;
-        if (level == 2 && (pte & PTE_PSE)) {
+        if ( level == 2 && (pte & PTE_PSE) )
+        {
             mask = ((mask ^ ~-mask) >> 1); /* All bits below first set bit */
             return ((paddr & ~mask) | (virt & mask)) >> PAGE_SHIFT;
         }
diff --git a/tools/xentrace/xenctx.c b/tools/xentrace/xenctx.c
index 6105ffb..f485ade 100644
--- a/tools/xentrace/xenctx.c
+++ b/tools/xentrace/xenctx.c
@@ -713,21 +713,37 @@ static void *map_page(vcpu_guest_context_any_t *ctx, int 
vcpu, guest_word_t virt
     static unsigned long previous_mfn = 0;
     static void *mapped = NULL;
 
-    unsigned long mfn = xc_translate_foreign_address(xenctx.xc_handle, 
xenctx.domid, vcpu, virt);
+    unsigned long mfn;
     unsigned long offset = virt & ~XC_PAGE_MASK;
+    int saved_errno;
 
-    if (mapped && mfn == previous_mfn)
+    errno = 0;
+    mfn = xc_translate_foreign_address(xenctx.xc_handle, xenctx.domid,
+                                       vcpu, virt);
+    saved_errno = errno;
+    if ( mapped && mfn == previous_mfn && !saved_errno )
         goto out;
 
     if (mapped)
         munmap(mapped, XC_PAGE_SIZE);
 
+    if ( saved_errno )
+    {
+        fprintf(stderr, "\nfailed to map page for "FMT_32B_WORD".\n", virt);
+        errno = saved_errno;
+        perror("xenctx");
+        return NULL;
+    }
     previous_mfn = mfn;
 
     mapped = xc_map_foreign_range(xenctx.xc_handle, xenctx.domid, 
XC_PAGE_SIZE, PROT_READ, mfn);
 
-    if (mapped == NULL) {
+    if ( mapped == NULL )
+    {
+        saved_errno = errno;
         fprintf(stderr, "\nfailed to map page for "FMT_32B_WORD".\n", virt);
+        errno = saved_errno;
+        perror("xenctx");
         return NULL;
     }
 
-- 
1.8.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.