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

[PATCH 2/2] drivers/char: Use sub-page ro API to make just xhci dbc cap RO



... not the whole page, which may contain other registers too. In fact
on Tiger Lake and newer (at least), this page do contain other registers
that Linux tries to use. And with share=yes, a domU would use them too.
Without this patch, PV dom0 would fail to initialize the controller,
while HVM would be killed on EPT violation.

Signed-off-by: Marek Marczykowski-Górecki <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
---
 xen/drivers/char/xhci-dbc.c | 38 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 36 insertions(+), 2 deletions(-)

diff --git a/xen/drivers/char/xhci-dbc.c b/xen/drivers/char/xhci-dbc.c
index 60b781f87202..df2524b0ca18 100644
--- a/xen/drivers/char/xhci-dbc.c
+++ b/xen/drivers/char/xhci-dbc.c
@@ -1226,9 +1226,43 @@ static void __init cf_check dbc_uart_init_postirq(struct 
serial_port *port)
                          uart->dbc.xhc_dbc_offset),
                 PFN_UP((uart->dbc.bar_val & PCI_BASE_ADDRESS_MEM_MASK) +
                        uart->dbc.xhc_dbc_offset +
-                sizeof(*uart->dbc.dbc_reg)) - 1) )
-        printk(XENLOG_INFO
+                sizeof(*uart->dbc.dbc_reg)) - 1) ) {
+        printk(XENLOG_WARNING
                "Error while adding MMIO range of device to mmio_ro_ranges\n");
+    }
+    else
+    {
+        unsigned long dbc_regs_start = (uart->dbc.bar_val &
+                PCI_BASE_ADDRESS_MEM_MASK) + uart->dbc.xhc_dbc_offset;
+        unsigned long dbc_regs_end = dbc_regs_start + 
sizeof(*uart->dbc.dbc_reg);
+
+        /* This being smaller than a page simplifies conditions below */
+        BUILD_BUG_ON(sizeof(*uart->dbc.dbc_reg) >= PAGE_SIZE - 1);
+        if ( dbc_regs_start & (PAGE_SIZE - 1) ||
+                PFN_DOWN(dbc_regs_start) == PFN_DOWN(dbc_regs_end) )
+        {
+            if ( subpage_mmio_ro_add(
+                        _mfn(PFN_DOWN(dbc_regs_start)),
+                        dbc_regs_start & (PAGE_SIZE - 1),
+                        PFN_DOWN(dbc_regs_start) == PFN_DOWN(dbc_regs_end)
+                        ? dbc_regs_end & (PAGE_SIZE - 1)
+                        : PAGE_SIZE - 1,
+                        FIX_XHCI_END) )
+                printk(XENLOG_WARNING
+                        "Error while adding MMIO range of device to 
subpage_mmio_ro\n");
+        }
+        if ( dbc_regs_end & (PAGE_SIZE - 1) &&
+                PFN_DOWN(dbc_regs_start) != PFN_DOWN(dbc_regs_end) )
+        {
+            if ( subpage_mmio_ro_add(
+                        _mfn(PFN_DOWN(dbc_regs_end)),
+                        0,
+                        dbc_regs_end & (PAGE_SIZE - 1),
+                        FIX_XHCI_END + PFN_DOWN(sizeof(*uart->dbc.dbc_reg))) )
+                printk(XENLOG_WARNING
+                        "Error while adding MMIO range of device to 
subpage_mmio_ro\n");
+        }
+    }
 #endif
 }
 
-- 
git-series 0.9.1



 


Rackspace

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