diff --git a/src/pciinit.c b/src/pciinit.c
index f75e552..9be895c 100644
--- a/src/pciinit.c
+++ b/src/pciinit.c
@@ -49,6 +49,12 @@ static void pci_set_io_region_addr(u16 bdf, int region_num, u32 addr)
     dprintf(1, "region %d: 0x%08x\n", region_num, addr);
 }
 
+static inline int pci_bar_overflow(u32 addr, u32 size)
+{
+    return (ALIGN(addr, size) < addr) ||
+        (ALIGN(addr, size) + size < ALIGN(addr, size));
+}
+
 /*
  * return value
  *      0:     32bit BAR
@@ -78,7 +84,8 @@ static int pci_bios_allocate_region(u16 bdf, int region_num)
     if (val != 0) {
         if (val & PCI_BASE_ADDRESS_SPACE_IO) {
             paddr = &pci_bios_io_addr;
-            if (ALIGN(*paddr, size) + size >= 64 * 1024) {
+            if (pci_bar_overflow(*paddr, size) ||
+                ALIGN(*paddr, size) + size >= 64 * 1024) {
                 dprintf(1,
                         "io region of (bdf 0x%x bar %d) can't be mapped.\n",
                         bdf, region_num);
@@ -90,7 +97,8 @@ static int pci_bios_allocate_region(u16 bdf, int region_num)
                  /* If pci_bios_prefmem_addr == 0, keep old behaviour */
                  pci_bios_prefmem_addr != 0) {
             paddr = &pci_bios_prefmem_addr;
-            if (ALIGN(*paddr, size) + size >= BUILD_PCIPREFMEM_END) {
+            if (pci_bar_overflow(*paddr, size) ||
+                ALIGN(*paddr, size) + size >= BUILD_PCIPREFMEM_END) {
                 dprintf(1,
                         "prefmem region of (bdf 0x%x bar %d) can't be mapped. "
                         "decrease BUILD_PCIMEM_SIZE and recompile. size %x\n",
@@ -99,7 +107,8 @@ static int pci_bios_allocate_region(u16 bdf, int region_num)
             }
         } else {
             paddr = &pci_bios_mem_addr;
-            if (ALIGN(*paddr, size) + size >= BUILD_PCIMEM_END) {
+            if (pci_bar_overflow(*paddr, size) ||
+                ALIGN(*paddr, size) + size >= BUILD_PCIMEM_END) {
                 dprintf(1,
                         "mem region of (bdf 0x%x bar %d) can't be mapped. "
                         "increase BUILD_PCIMEM_SIZE and recompile. size %x\n",
@@ -152,6 +161,12 @@ static const struct pci_device_id pci_isa_bridge_tbl[] = {
     PCI_DEVICE_END
 };
 
+static inline int pci_addr_overflow(u32 old, u32 base, u32 addr, u32 end)
+{
+    /* if without overflow, old <= base <= addr <= end */
+    return (old > base) || (base > addr) || (addr > end);
+}
+
 #define PCI_IO_ALIGN            4096
 #define PCI_IO_SHIFT            8
 #define PCI_MEMORY_ALIGN        (1UL << 20)
@@ -184,36 +199,41 @@ static void pci_bios_init_device_bridge(u16 bdf, void *arg)
         pci_bios_init_device_in_bus(secbus);
     }
 
-    pci_bios_io_addr = ALIGN(pci_bios_io_addr, PCI_IO_ALIGN);
-    pci_bios_mem_addr = ALIGN(pci_bios_mem_addr, PCI_MEMORY_ALIGN);
-    pci_bios_prefmem_addr =
-        ALIGN(pci_bios_prefmem_addr, PCI_PREF_MEMORY_ALIGN);
-
-    u32 io_end = pci_bios_io_addr;
-    if (io_end == io_base) {
+    u32 io_end = ALIGN(pci_bios_io_addr, PCI_IO_ALIGN);
+    if (pci_addr_overflow(io_old, io_base, pci_bios_io_addr, io_end) ||
+        io_end == io_base) {
         pci_bios_io_addr = io_old;
         io_base = 0xffff;
         io_end = 1;
+    } else {
+        pci_bios_io_addr = io_end;
     }
     pci_config_writeb(bdf, PCI_IO_BASE, io_base >> PCI_IO_SHIFT);
     pci_config_writew(bdf, PCI_IO_BASE_UPPER16, 0);
     pci_config_writeb(bdf, PCI_IO_LIMIT, (io_end - 1) >> PCI_IO_SHIFT);
     pci_config_writew(bdf, PCI_IO_LIMIT_UPPER16, 0);
 
-    u32 mem_end = pci_bios_mem_addr;
-    if (mem_end == mem_base) {
+    u32 mem_end = ALIGN(pci_bios_mem_addr, PCI_MEMORY_ALIGN);
+    if (pci_addr_overflow(mem_old, mem_base, pci_bios_mem_addr, mem_end) ||
+        mem_end == mem_base) {
         pci_bios_mem_addr = mem_old;
         mem_base = 0xffffffff;
         mem_end = 1;
+    } else {
+        pci_bios_io_addr = mem_end;
     }
     pci_config_writew(bdf, PCI_MEMORY_BASE, mem_base >> PCI_MEMORY_SHIFT);
     pci_config_writew(bdf, PCI_MEMORY_LIMIT, (mem_end -1) >> PCI_MEMORY_SHIFT);
 
-    u32 prefmem_end = pci_bios_prefmem_addr;
-    if (prefmem_end == prefmem_base) {
+    u32 prefmem_end = ALIGN(pci_bios_prefmem_addr, PCI_PREF_MEMORY_ALIGN);
+    if (pci_addr_overflow(prefmem_old, prefmem_base,
+                          pci_bios_prefmem_addr, prefmem_end) ||
+        prefmem_end == prefmem_base) {
         pci_bios_prefmem_addr = prefmem_old;
         prefmem_base = 0xffffffff;
         prefmem_end = 1;
+    } else {
+        pci_bios_prefmem_addr = prefmem_end;
     }
     pci_config_writew(bdf, PCI_PREF_MEMORY_BASE,
                       prefmem_base >> PCI_PREF_MEMORY_SHIFT);
