Fix xHCI heap corruption: allocate the Output Device Context full size at Address Device, never swap it (found at O-C)
xhci_cmd_address_device() sized the Output Device Context for Slot + EP0 (64 bytes); xhci_cmd_configure_endpoint() then allocated a bigger copy and repointed DCBAA[slot_id]. The controller keeps the address it was given at Address Device (QEMU caches it), so every bulk Endpoint Context was written past the 64-byte block into the next kmalloc header -- on every USB mass-storage attach, every ISA. After O-C's smoke campaign reshuffled the heap, a kfree at thumbdrive unplug walked into it: #GP in coalesce_neighbors(). Found with temporary instrumentation (load base, code bytes at RIP, event crumbs, a heap-list checker): the corrupt word was an EP Context (Bulk IN, Running, MPS 1024) exactly DCI 3 x 32 bytes into the 64-byte context. Now: XHCI_DEVICE_CTX_BYTES (32 contexts x 32 bytes) allocated once per slot at Address Device, zeroed whole, never reallocated; Configure Endpoint just fills it. Also ends the per-attach leak of the old context. Verified: heap checker clean from boot; campaign -> O-A -> MINT -> unplug -> re-attach passes with 0 exceptions; 3-ISA acceptance passes, parity and dict_hash set unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
ee4c401d1c
commit
df150e8626
@@ -443,6 +443,13 @@ typedef struct {
|
||||
volatile uint32_t reserved[3];
|
||||
} xhci_ep_ctx32_t;
|
||||
|
||||
/* The whole Output Device Context (xHCI 1.2 spec section 6.2.1): the Slot
|
||||
* Context plus 31 Endpoint Contexts, 32-byte each (CSZ=0, the only mode
|
||||
* this driver implements). Allocated at this size once, at Address Device
|
||||
* -- the controller keeps the address it was given there. */
|
||||
#define XHCI_DEVICE_CTX_ENTRIES 32u
|
||||
#define XHCI_DEVICE_CTX_BYTES (XHCI_DEVICE_CTX_ENTRIES * sizeof(xhci_ep_ctx32_t))
|
||||
|
||||
#define XHCI_EP_CTX_TYPE_SHIFT 3
|
||||
#define XHCI_EP_CTX_TYPE_CONTROL_BIDI 4u /* EP0 */
|
||||
#define XHCI_EP_CTX_TYPE_BULK_OUT 2u /* xHCI 1.2 spec table 6-9 */
|
||||
|
||||
@@ -98,7 +98,8 @@ typedef struct {
|
||||
* device_ctx/ep0_ring* before this fix; single-drive-at-a-time scope
|
||||
* removed, each attached device now gets its own. */
|
||||
void *input_ctx; /* Input Control Ctx + Slot Ctx + EP0 Ctx (96 bytes, 32-byte contexts) */
|
||||
void *device_ctx; /* Slot Ctx + EP0 Ctx (64 bytes) -- DCBAA[slot_id] points here */
|
||||
void *device_ctx; /* full Output Device Context (XHCI_DEVICE_CTX_BYTES, all 32
|
||||
* contexts) -- DCBAA[slot_id] points here, never swapped */
|
||||
xhci_trb_t *ep0_ring; /* EP0 Transfer Ring, XHCI_RING_TRB_COUNT TRBs */
|
||||
uint32_t ep0_ring_cycle;
|
||||
uint32_t ep0_ring_enq;
|
||||
|
||||
Reference in New Issue
Block a user