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

[Xen-changelog] [xen-unstable] xenoprof: Handle 32-bit guest stacks properly in a 64-bit hypervisor



# HG changeset patch
# User George Dunlap <george.dunlap@xxxxxxxxxxxxx>
# Date 1327311389 0
# Node ID 3c0a533d3af06839ef3d90d67b01171498d9e572
# Parent  212cf37d50e13e4f13bb6e239d1c3e1808bcfdfd
xenoprof: Handle 32-bit guest stacks properly in a 64-bit hypervisor

The dump_guest_backtrace() function attempted to walk the stack
based on the assumption that the guest and hypervisor pointer sizes
were the same; thus any 32-bit guest running under 64-bit hypervisor
would have unreliable results.

In 64-bit mode, read the 32-bit stack frame properly.

Signed-off-by: Marcus Granado <marcus.granado@xxxxxxxxxxxxx>
Signed-off-by: George Dunlap <george.dunlap@xxxxxxxxxxxxx>
Committed-by: Keir Fraser <keir@xxxxxxx>
---


diff -r 212cf37d50e1 -r 3c0a533d3af0 xen/arch/x86/oprofile/backtrace.c
--- a/xen/arch/x86/oprofile/backtrace.c Mon Jan 23 09:36:01 2012 +0000
+++ b/xen/arch/x86/oprofile/backtrace.c Mon Jan 23 09:36:29 2012 +0000
@@ -20,6 +20,13 @@
     unsigned long ret;
 } __attribute__((packed));
 
+#ifdef CONFIG_X86_64
+struct frame_head_32bit {
+    uint32_t ebp;
+    unsigned long ret;
+} __attribute__((packed));
+#endif
+
 static struct frame_head *
 dump_hypervisor_backtrace(struct domain *d, struct vcpu *vcpu, 
                          struct frame_head * head, int mode)
@@ -35,19 +42,46 @@
     return head->ebp;
 }
 
+#ifdef CONFIG_X86_64
+static inline int is_32bit_vcpu(struct vcpu *vcpu)
+{
+    if (is_hvm_vcpu(vcpu))
+        return !hvm_long_mode_enabled(vcpu);
+    else
+        return is_pv_32bit_vcpu(vcpu);
+}
+#endif
+
 static struct frame_head *
 dump_guest_backtrace(struct domain *d, struct vcpu *vcpu, 
                     struct frame_head * head, int mode)
 {
     struct frame_head bufhead[2];
     XEN_GUEST_HANDLE(char) guest_head = guest_handle_from_ptr(head, char);
-       
-    /* Also check accessibility of one struct frame_head beyond */
-    if (!guest_handle_okay(guest_head, sizeof(bufhead)))
-        return 0;
-    if (__copy_from_guest_offset((char *)bufhead, guest_head, 0, 
-                                 sizeof(bufhead)))
-        return 0;
+
+#ifdef CONFIG_X86_64
+    if ( is_32bit_vcpu(vcpu) )
+    {
+        struct frame_head_32bit bufhead32[2];
+        /* Also check accessibility of one struct frame_head beyond */
+        if (!guest_handle_okay(guest_head, sizeof(bufhead32)))
+            return 0;
+        if (__copy_from_guest_offset((char *)bufhead32, guest_head, 0, 
+                                     sizeof(bufhead32)))
+            return 0;
+        bufhead[0].ebp=(struct frame_head *)(unsigned long)bufhead32[0].ebp;
+        bufhead[0].ret=bufhead32[0].ret;
+    }
+    else
+#endif
+    {
+        /* Also check accessibility of one struct frame_head beyond */
+        if (!guest_handle_okay(guest_head, sizeof(bufhead)))
+            return 0;
+        if (__copy_from_guest_offset((char *)bufhead, guest_head, 0, 
+                                     sizeof(bufhead)))
+            return 0;
+    }
     
     if (!xenoprof_add_trace(d, vcpu, bufhead[0].ret, mode))
         return 0;

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

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