File xsa410-04.patch of Package xen.28177

x86/HAP: adjust monitor table related error handling

hap_make_monitor_table() will return INVALID_MFN if it encounters an
error condition, but hap_update_paging_modes() wasn’t handling this
value, resulting in an inappropriate value being stored in
monitor_table. This would subsequently misguide at least
hap_vcpu_teardown(). Avoid this by bailing early.

Further, when a domain has/was already crashed or (perhaps less
important as there's no such path known to lead here) is already dying,
avoid calling domain_crash() on it again - that's at best confusing.

This is part of XSA-410.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>

--- a/xen/arch/x86/mm/hap/hap.c
+++ b/xen/arch/x86/mm/hap/hap.c
@@ -40,6 +40,7 @@
 #include <asm/domain.h>
 #include <xen/numa.h>
 #include <asm/hvm/nestedhvm.h>
+#include <public/sched.h>
 
 #include "private.h"
 
@@ -426,8 +427,13 @@ static mfn_t hap_make_monitor_table(stru
     return m4mfn;
 
  oom:
-    HAP_ERROR("out of memory building monitor pagetable\n");
-    domain_crash(d);
+    if ( !d->is_dying &&
+         (!d->is_shutting_down || d->shutdown_code != SHUTDOWN_crash) )
+    {
+        HAP_ERROR("d%d: out of memory building monitor pagetable\n",
+                  d->domain_id);
+        domain_crash(d);
+    }
     return _mfn(INVALID_MFN);
 }
 
@@ -727,6 +733,9 @@ static void hap_update_paging_modes(stru
     if ( pagetable_is_null(v->arch.monitor_table) )
     {
         mfn_t mmfn = hap_make_monitor_table(v);
+
+        if ( mfn_x(mmfn) == INVALID_MFN )
+            goto unlock;
         v->arch.monitor_table = pagetable_from_mfn(mmfn);
         make_cr3(v, mfn_x(mmfn));
         hvm_update_host_cr3(v);
@@ -735,6 +744,7 @@ static void hap_update_paging_modes(stru
     /* CR3 is effectively updated by a mode change. Flush ASIDs, etc. */
     hap_update_cr3(v, 0);
 
+ unlock:
     paging_unlock(d);
     put_gfn(d, cr3_gfn);
 }
openSUSE Build Service is sponsored by