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

[xen master] nestedsvm: Fix multi-byte IO port intercept check



commit 221f87ad399d99d1dc580a8e3eff7b65f2695aec
Author:     Ross Lagerwall <ross.lagerwall@xxxxxxxxxx>
AuthorDate: Fri Sep 11 14:23:15 2026 +0100
Commit:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Fri Sep 11 18:24:25 2026 +0100

    nestedsvm: Fix multi-byte IO port intercept check
    
    For multi-byte IO port accesses, the APM says that SVM should intercept
    if any of the corresponding permission bits are set. However, the code
    has this backwards and only intercepts if all the permission bits are
    set. Fix this and at the same time, make things safer by handling
    mapping failures as intercepted. Also rename the 'enabled' variable to
    make it clearer what it does.
    
    This affects Hyper-V which for the root partition intercepts 0xcf8 and
    0xcfc-0xcff. L2 issues 4 byte CFG index writes to 0xcf8 which are 
incorrectly
    permitted and update the L1 CFG index. The subsequent L2 CFG data read at 
0xcfc
    is intercepted by L1, then resubmitted as a CFG index write followed by CFG
    data read to L0. Since L1 doesn't see the CFG index write by L2, it uses the
    wrong index and gets garbage back, ultimately leading to a failure to boot
    since it cannot access its NVMe disk.
    
    Signed-off-by: Ross Lagerwall <ross.lagerwall@xxxxxxxxxx>
    Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
 xen/arch/x86/hvm/svm/nestedsvm.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/xen/arch/x86/hvm/svm/nestedsvm.c b/xen/arch/x86/hvm/svm/nestedsvm.c
index eec61238b5..a8b15d6eae 100644
--- a/xen/arch/x86/hvm/svm/nestedsvm.c
+++ b/xen/arch/x86/hvm/svm/nestedsvm.c
@@ -830,7 +830,7 @@ nsvm_vmcb_guest_intercepts_ioio(paddr_t iopm_pa, uint64_t 
exitinfo1)
     ioio_info_t ioinfo;
     uint16_t port;
     unsigned int size;
-    bool enabled;
+    bool intercepted;
 
     ioinfo.bytes = exitinfo1;
     port = ioinfo.fields.port;
@@ -851,8 +851,8 @@ nsvm_vmcb_guest_intercepts_ioio(paddr_t iopm_pa, uint64_t 
exitinfo1)
 
     for ( io_bitmap = hvm_map_guest_frame_ro(gfn, 0); ; )
     {
-        enabled = io_bitmap && test_bit(port, io_bitmap);
-        if ( !enabled || !--size )
+        intercepted = !io_bitmap || test_bit(port, io_bitmap);
+        if ( intercepted || !--size )
             break;
         if ( unlikely(++port == 8 * PAGE_SIZE) )
         {
@@ -863,7 +863,7 @@ nsvm_vmcb_guest_intercepts_ioio(paddr_t iopm_pa, uint64_t 
exitinfo1)
     }
     hvm_unmap_guest_frame(io_bitmap, 0);
 
-    if ( !enabled )
+    if ( !intercepted )
         return NESTEDHVM_VMEXIT_HOST;
 
     return NESTEDHVM_VMEXIT_INJECT;
--
generated by git-patchbot for /home/xen/git/xen.git#master



 


Rackspace

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