On 08/12/2020 17:57, Manuel Bouyer wrote:
> Hello,
> for the first time I tried to boot a xen kernel from devel with
> a NetBSD PV dom0. The kernel boots, but when the first userland prcess
> is launched, it seems to enter a loop involving search_pre_exception_table()
> (I see an endless stream from the dprintk() at arch/x86/extable.c:202)
>
> With xen 4.13 I see it, but exactly once:
> (XEN) extable.c:202: Pre-exception: ffff82d08038c304 -> ffff82d08038c8c8
>
> with devel:
> (XEN) extable.c:202: Pre-exception: ffff82d040393309 -> ffff82d0403938c8      
>   
> (XEN) extable.c:202: Pre-exception: ffff82d040393309 -> ffff82d0403938c8      
>   
> (XEN) extable.c:202: Pre-exception: ffff82d040393309 -> ffff82d0403938c8      
>   
> (XEN) extable.c:202: Pre-exception: ffff82d040393309 -> ffff82d0403938c8      
>   
> (XEN) extable.c:202: Pre-exception: ffff82d040393309 -> ffff82d0403938c8      
>   
> [...]
>
> the dom0 kernel is the same.
>
> At first glance it looks like a fault in the guest is not handled at it 
> should,
> and the userland process keeps faulting on the same address.
>
> Any idea what to look at ?

That is a reoccurring fault on IRET back to guest context, and is
probably caused by some unwise-in-hindsight cleanup which doesn't
escalate the failure to the failsafe callback.

This ought to give something useful to debug with:

~Andrew

diff --git a/xen/arch/x86/extable.c b/xen/arch/x86/extable.c
index 70972f1085..62a7bcbe38 100644
--- a/xen/arch/x86/extable.c
+++ b/xen/arch/x86/extable.c
@@ -191,6 +191,10 @@ static int __init stub_selftest(void)
 __initcall(stub_selftest);
 #endif
 
+#include <xen/sched.h>
+#include <xen/softirq.h>
+const char *vec_name(unsigned int vec);
+
 unsigned long
 search_pre_exception_table(struct cpu_user_regs *regs)
 {
@@ -199,7 +203,13 @@ search_pre_exception_table(struct cpu_user_regs *regs)
         __start___pre_ex_table, __stop___pre_ex_table-1, addr);
     if ( fixup )
     {
-        dprintk(XENLOG_INFO, "Pre-exception: %p -> %p\n", _p(addr),
_p(fixup));
+        printk(XENLOG_ERR "IRET fault: %s[%04x]\n",
+               vec_name(regs->entry_vector), regs->error_code);
+
+        domain_crash(current->domain);
+        for ( ;; )
+            do_softirq();
+
         perfc_incr(exception_fixed);
     }
     return fixup;
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index 0459cee9fb..1059f3ce66 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -687,7 +687,7 @@ const char *trapstr(unsigned int trapnr)
     return trapnr < ARRAY_SIZE(strings) ? strings[trapnr] : "???";
 }
 
-static const char *vec_name(unsigned int vec)
+const char *vec_name(unsigned int vec)
 {
     static const char names[][4] = {
 #define P(x) [X86_EXC_ ## x] = "#" #x


Reply via email to