io_base and io_size represent physical addresses. So they should use
paddr_t (instead of u64).

However in future, paddr_t may be defined as u32. So when typecasting
values from u64 to paddr_t, one should always check for any possible
truncation. If any truncation is discovered, Xen needs to raise a BUG
for this (as the address is provided either by reading the PCIE registers
or parsing parameters from string, so the error is unrecoverable).

Signed-off-by: Ayan Kumar Halder <ayan.kumar.hal...@amd.com>
---
Changes from -
v1 - NA

v2 - 1. Extracted the patch from "[XEN v2 05/11] xen/arm: Use paddr_t instead 
of u64 for address/size"
into a separate patch of its own.


 xen/drivers/char/ns16550.c | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c
index 092f6b9c4b..2aee5642f9 100644
--- a/xen/drivers/char/ns16550.c
+++ b/xen/drivers/char/ns16550.c
@@ -42,8 +42,8 @@
 
 static struct ns16550 {
     int baud, clock_hz, data_bits, parity, stop_bits, fifo_size, irq;
-    u64 io_base;   /* I/O port or memory-mapped I/O address. */
-    u64 io_size;
+    paddr_t io_base;   /* I/O port or memory-mapped I/O address. */
+    paddr_t io_size;
     int reg_shift; /* Bits to shift register offset by */
     int reg_width; /* Size of access to use, the registers
                     * themselves are still bytes */
@@ -1166,8 +1166,9 @@ static const struct ns16550_config __initconst 
uart_config[] =
 static int __init
 pci_uart_config(struct ns16550 *uart, bool_t skip_amt, unsigned int idx)
 {
-    u64 orig_base = uart->io_base;
+    paddr_t orig_base = uart->io_base;
     unsigned int b, d, f, nextf, i;
+    u64 pci_uart_io_base;
 
     /* NB. Start at bus 1 to avoid AMT: a plug-in card cannot be on bus 0. */
     for ( b = skip_amt ? 1 : 0; b < 0x100; b++ )
@@ -1259,8 +1260,13 @@ pci_uart_config(struct ns16550 *uart, bool_t skip_amt, 
unsigned int idx)
                     else
                         size = len & PCI_BASE_ADDRESS_MEM_MASK;
 
-                    uart->io_base = ((u64)bar_64 << 32) |
-                                    (bar & PCI_BASE_ADDRESS_MEM_MASK);
+                    pci_uart_io_base = ((u64)bar_64 << 32) |
+                                        (bar & PCI_BASE_ADDRESS_MEM_MASK);
+
+                    /* Truncation detected while converting to paddr_t */
+                    BUG_ON((pci_uart_io_base >> (PADDR_SHIFT - 1)) > 1);
+
+                    uart->io_base = pci_uart_io_base;
                 }
                 /* IO based */
                 else if ( !param->mmio && (bar & PCI_BASE_ADDRESS_SPACE_IO) )
@@ -1468,6 +1474,7 @@ static bool __init parse_positional(struct ns16550 *uart, 
char **str)
     int baud;
     const char *conf;
     char *name_val_pos;
+    u64 uart_io_base;
 
     conf = *str;
     name_val_pos = strchr(conf, '=');
@@ -1532,7 +1539,12 @@ static bool __init parse_positional(struct ns16550 
*uart, char **str)
         else
 #endif
         {
-            uart->io_base = simple_strtoull(conf, &conf, 0);
+            uart_io_base = simple_strtoull(conf, &conf, 0);
+
+            /* Truncation detected while converting to paddr_t */
+            BUG_ON((uart_io_base >> (PADDR_SHIFT - 1)) > 1);
+
+            uart->io_base = uart_io_base;
         }
     }
 
-- 
2.17.1


Reply via email to