diff --git a/xen/drivers/char/xhci-dbc.c b/xen/drivers/char/xhci-dbc.c index 4712faaabe..f55f73e382 100644 --- a/xen/drivers/char/xhci-dbc.c +++ b/xen/drivers/char/xhci-dbc.c @@ -20,6 +20,7 @@ */ #include +#include #include #include #include @@ -1051,13 +1052,21 @@ static struct uart_driver dbc_uart_driver = { }; /* Those are accessed via DMA. */ -static struct xhci_trb evt_trb[DBC_TRB_RING_CAP]; -static struct xhci_trb out_trb[DBC_TRB_RING_CAP]; -static struct xhci_trb in_trb[DBC_TRB_RING_CAP]; -static struct xhci_erst_segment erst __aligned(16); -static struct xhci_dbc_ctx ctx __aligned(16); -static uint8_t out_wrk_buf[DBC_WORK_RING_CAP]; -static struct xhci_string_descriptor str_buf[DBC_STRINGS_COUNT]; +struct dbc_dma_bufs { + struct xhci_trb evt_trb[DBC_TRB_RING_CAP]; + struct xhci_trb out_trb[DBC_TRB_RING_CAP]; + struct xhci_trb in_trb[DBC_TRB_RING_CAP]; + uint8_t out_wrk_buf[DBC_WORK_RING_CAP]; + struct xhci_erst_segment erst __aligned(16); + struct xhci_dbc_ctx ctx __aligned(16); + struct xhci_string_descriptor str_buf[DBC_STRINGS_COUNT]; + /* + * Don't place anything else on this page - it will be + * DMA-reachable by the USB controller. + */ +}; +static struct dbc_dma_bufs __section(".bss.page_aligned") __aligned(PAGE_SIZE) + dbc_dma_bufs; static int __init xhci_parse_dbgp(const char *opt_dbgp) { @@ -1104,16 +1113,22 @@ void __init xhci_dbc_uart_init(void) if ( !dbc->enable ) return; - dbc->dbc_ctx = &ctx; - dbc->dbc_erst = &erst; - dbc->dbc_ering.trb = evt_trb; - dbc->dbc_oring.trb = out_trb; - dbc->dbc_iring.trb = in_trb; - dbc->dbc_owork.buf = out_wrk_buf; - dbc->dbc_str = str_buf; + dbc->dbc_ctx = &dbc_dma_bufs.ctx; + dbc->dbc_erst = &dbc_dma_bufs.erst; + dbc->dbc_ering.trb = dbc_dma_bufs.evt_trb; + dbc->dbc_oring.trb = dbc_dma_bufs.out_trb; + dbc->dbc_iring.trb = dbc_dma_bufs.in_trb; + dbc->dbc_owork.buf = dbc_dma_bufs.out_wrk_buf; + dbc->dbc_str = dbc_dma_bufs.str_buf; if ( dbc_open(dbc) ) + { + iommu_add_extra_reserved_device_memory( + PFN_DOWN(virt_to_maddr(&dbc_dma_bufs)), + PFN_UP(sizeof(dbc_dma_bufs)), + uart->dbc.sbdf); serial_register_uart(SERHND_XHCI, &dbc_uart_driver, &dbc_uart); + } } #ifdef DBC_DEBUG