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

[xen stable-4.20] x86/mm: special-case IOMMU (un)mapping failure path in _get_page_type()



commit e8f54bbbbd7fac9e47dc88e3efcfc772f4e49d53
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Thu Oct 29 13:35:56 2026 +0100
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Thu Oct 29 13:35:56 2026 +0100

    x86/mm: special-case IOMMU (un)mapping failure path in _get_page_type()
    
    The error path put in place to address XSA-291 was broken by the re-work
    done for XSA-299: With PTF_partial_set not passed in (since PGT_partial is
    clear for a page undergoing a type change) and the page not having
    PGT_validated set just yet, _put_page_type() would fail its consistency
    check for non-dying domains. Introduce yet another flag to indicate use of
    the function from _get_page_type()'s recovery path.
    
    Fixes: c40b33d72630 ("x86/mm: Don't drop a type ref unless you held a ref 
to begin with")
    Reported-by: Yehyeong Lee <yhlee@xxxxxxxxxxxxxxxxxx>
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Reviewed-by: Roger Pau Monné <roger@xxxxxxxxxxxxxx>
    master commit: f78ced6adbaef158b62a5d7a368f95368b36cc62
    master date: 2026-10-29 09:13:01 +0100
---
 xen/arch/x86/mm.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index ea64b5a55f..ff6498385f 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -1092,6 +1092,7 @@ get_page_from_l1e(
  * more information.
  */
 #define PTF_partial_set           (1 << 0)
+#define PTF_recovery              (1 << 1)
 #define PTF_preemptible           (1 << 2)
 #define PTF_defer                 (1 << 3)
 #define PTF_retain_ref_on_restart (1 << 4)
@@ -2849,15 +2850,21 @@ static int _put_page_type(struct page_info *page, 
unsigned int flags,
          * *not* fully validated, continuing would almost certainly
          * open up a security hole.  An exception to this is during
          * domain destruction, where PGT_validated can be dropped
-         * without dropping a type ref.
+         * without dropping a type ref.  Another exception is on error
+         * paths from _get_page_type(), where the type ref was already
+         * put in place, but PGT_validated isn't set yet (page
+         * validation still pending).
          *
-         * If the latter, do nothing unless type PGT_partial is set.
-         * If it is set, the type count must be 1.
+         * In the domain destruction case, do nothing unless PGT_partial
+         * is set.  If it is set, the type count must be 1.
+         *
+         * In the _get_page_type() error path case operate normally,
+         * again also including the type count sanity check.
          */
-        if ( !(flags & PTF_partial_set) )
+        if ( !(flags & (PTF_partial_set | PTF_recovery)) )
             BUG_ON((x & PGT_partial) ||
                    !((x & PGT_validated) || page_get_owner(page)->is_dying));
-        else if ( !(x & PGT_partial) )
+        else if ( (flags & PTF_partial_set) && !(x & PGT_partial) )
             return 0;
         else
             BUG_ON((x & PGT_count_mask) != 1);
@@ -3134,7 +3141,7 @@ static int _get_page_type(struct page_info *page, 
unsigned long type,
 
             if ( unlikely(rc) )
             {
-                _put_page_type(page, 0, NULL);
+                _put_page_type(page, PTF_recovery, NULL);
                 goto out;
             }
         }
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.20



 


Rackspace

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