On 8/6/2026 9:15 AM, Sohil Mehta wrote: > TSS I/O permission bitmap reads are implicit supervisor accesses which > are subject to Linear Address Space Separation (LASS) enforcement.
I am not sure about it. According to SDM vol 3a (253668-089US), Chapter "LINEAR-ADDRESS PRE-PROCESSING", section "MODE-BASED ACCESSES AND LINEAR-ADDRESS-SPACE PARTITIONING", it defines and limits "implicit supervisor-mode accesses" to the following operations: - accesses to the global descriptor table (GDT) or local descriptor table (LDT) to load a segment descriptor - accesses to the interrupt descriptor table (IDT) when delivering an interrupt or exception - accesses to the task-state segment (TSS) as part of a task switch or change of CPL - accesses to a user posted-interrupt descriptor (UPID) during user-interrupt notification processing IIUC, the TSS I/O bitmap read during ordinary instruction execution (under CPL = 3) rather than during a task switch or CPL transition, I don't think they fall under the classification of implicit supervisor-mode accesses. > Though highly unlikely, if a guest configures a TSS base in the > user half, hardware would raise a #GP on access when LASS is enabled. > > Currently, the emulator reads the I/O permission bitmap from the TSS by > calling read_std() directly which is inconsistent with other implicit > accesses in the emulator such as IDT reads, GDT/LDT reads and TSS reads > during task switch. > > An upcoming change will add a check to linear_read_system() to catch > LASS violations. For consistency as well as to keep LASS enforcement > centralized, switch both I/O bitmap reads to linear_read_system(). > > Note, emulator_io_port_access_allowed() doesn't propagate faults, so > even though linear_read_system() will set the exception details they > will be ignored. > > While at it, fix an off-by-one in the I/O bitmap bounds check to account > for the 2-byte read and ensure both bytes are within the TSS limit. The > SDM mandates a trailing 0xFF byte after the bitmap so any out-of-bounds > access would be all 1s (denying access). Make the change primarily to > ensure hardware fidelity. A correctly configured OS will not run into > this issue. > > Signed-off-by: Sohil Mehta <[email protected]> > --- > v4: > - New patch > > There could be a pre-existing issue here. It is unlikely that any OS > demand-pages the I/O bitmap portion of the TSS. But if it does, the #PF > details could get lost and the guest would get a #GP instead of a > restartable #PF. Propagating the #PF to the callers is a larger change > that is beyond the scope of this series. > --- > arch/x86/kvm/emulate.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c > index 8ff28643b2e3..7f04544cfee5 100644 > --- a/arch/x86/kvm/emulate.c > +++ b/arch/x86/kvm/emulate.c > @@ -2573,12 +2573,12 @@ static bool emulator_io_port_access_allowed(struct > x86_emulate_ctxt *ctxt, > #ifdef CONFIG_X86_64 > base |= ((u64)base3) << 32; > #endif > - r = ops->read_std(ctxt, base + 102, &io_bitmap_ptr, 2, NULL, true); > + r = linear_read_system(ctxt, base + 102, &io_bitmap_ptr, 2); > if (r != X86EMUL_CONTINUE) > return false; > - if (io_bitmap_ptr + port/8 > desc_limit_scaled(&tr_seg)) > + if (io_bitmap_ptr + port/8 + 1 > desc_limit_scaled(&tr_seg)) > return false; > - r = ops->read_std(ctxt, base + io_bitmap_ptr + port/8, &perm, 2, NULL, > true); > + r = linear_read_system(ctxt, base + io_bitmap_ptr + port/8, &perm, 2); > if (r != X86EMUL_CONTINUE) > return false; > if ((perm >> bit_idx) & mask)

