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

[Xen-devel] [PATCH] [RESEND] ioemu: make unused Base Address Register 0 hardwired.



Hi Ian,

This patch modifies to make unused Base Address Register 0 hardwired.
Unused BAR should not be changed by guest software. 

This patch also changed the check value of unused BAR to
(*value > 0 && *value < PT_BAR_ALLF-1). Because Linux writes
PT_BAR_ALLF-1 when it checks the BAR.

When I forced ioemu to hide expansion ROM, ioemu output the following
warning message which is the same with Tim's one.

> pt_pci_write_config: Warning: Guest attempt to set address to unused Base 
> Address Register. [00:03.0][Offset:30h][Length:4]

But when I changed the check value of unused BAR to PT_BAR_ALLF-1,
ioemu didn't output the warning message.

I am taking days off from April 29th to May 6th. So I can't answer any
question by then.

Thanks,
--
Yuji Shimada


Signed-off-by: Yuji Shimada <shimada-yxb@xxxxxxxxxxxxxxx>

diff --git a/hw/pass-through.c b/hw/pass-through.c
index 7bd2feb..601cd8a 100644
--- a/hw/pass-through.c
+++ b/hw/pass-through.c
@@ -416,11 +416,9 @@ static struct pt_reg_info_tbl pt_emu_reg_header0_tbl[] = {
         .offset     = PCI_ROM_ADDRESS,
         .size       = 4,
         .init_val   = 0x00000000,
-        .ro_mask    = 0x000007FE,
-        .emu_mask   = 0xFFFFF800,
         .init       = pt_bar_reg_init,
-        .u.dw.read  = pt_long_reg_read,
-        .u.dw.write = pt_exp_rom_bar_reg_write,
+        .u.dw.read  = pt_bar_reg_read,
+        .u.dw.write = pt_bar_reg_write,
         .u.dw.restore = pt_exp_rom_bar_reg_restore,
     },
     {
@@ -1218,17 +1216,6 @@ static void pt_pci_write_config(PCIDevice *d, uint32_t 
address, uint32_t val,
         goto exit;
     }
 
-    /* check unused BAR register */
-    index = pt_bar_offset_to_index(address);
-    if ((index >= 0) && (val > 0 && val < PT_BAR_ALLF) &&
-        (assigned_device->bases[index].bar_flag == PT_BAR_FLAG_UNUSED))
-    {
-        PT_LOG("Warning: Guest attempt to set address to unused Base Address "
-            "Register. [%02x:%02x.%x][Offset:%02xh][Length:%d]\n",
-            pci_bus_num(d->bus), ((d->devfn >> 3) & 0x1F),
-            (d->devfn & 0x7), address, len);
-    }
-
     /* check power state transition flags */
     if (pm_state != NULL && pm_state->flags & PT_FLAG_TRANSITING)
         /* can't accept untill previous power state transition is completed.
@@ -1776,7 +1763,7 @@ static int pt_bar_reg_parse(
     /* for ExpROM BAR */
     if (index == PCI_ROM_SLOT)
     {
-        bar_flag = PT_BAR_FLAG_MEM;
+        bar_flag = PT_BAR_FLAG_EXP;
         goto out;
     }
 
@@ -1819,11 +1806,13 @@ static void pt_bar_mapping(struct pt_dev *ptdev, int 
io_enable, int mem_enable)
 
         /* need unmapping in case I/O Space or Memory Space disable */
         if (((base->bar_flag == PT_BAR_FLAG_IO) && !io_enable ) ||
-            ((base->bar_flag == PT_BAR_FLAG_MEM) && !mem_enable ))
+            ((base->bar_flag == PT_BAR_FLAG_MEM) && !mem_enable ) ||
+            ((base->bar_flag == PT_BAR_FLAG_EXP) && !mem_enable ))
             r_addr = -1;
 
         /* prevent guest software mapping memory resource to 00000000h */
-        if ((base->bar_flag == PT_BAR_FLAG_MEM) && (r_addr == 0))
+        if (((base->bar_flag == PT_BAR_FLAG_MEM) && (r_addr == 0)) ||
+            ((base->bar_flag == PT_BAR_FLAG_EXP) && (r_addr == 0)))
             r_addr = -1;
 
         /* align resource size (memory type only) */
@@ -2408,7 +2397,6 @@ static uint32_t pt_irqpin_reg_init(struct pt_dev *ptdev,
 static uint32_t pt_bar_reg_init(struct pt_dev *ptdev,
         struct pt_reg_info_tbl *reg, uint32_t real_offset)
 {
-    int reg_field = 0;
     int index;
 
     /* get BAR index */
@@ -2426,10 +2414,8 @@ static uint32_t pt_bar_reg_init(struct pt_dev *ptdev,
 
     /* set BAR flag */
     ptdev->bases[index].bar_flag = pt_bar_reg_parse(ptdev, reg);
-    if (ptdev->bases[index].bar_flag == PT_BAR_FLAG_UNUSED)
-        reg_field = PT_INVALID_REG;
 
-    return reg_field;
+    return 0;
 }
 
 /* initialize Power Management Capabilities register */
@@ -2896,6 +2882,12 @@ static int pt_bar_reg_read(struct pt_dev *ptdev,
     case PT_BAR_FLAG_UPPER:
         bar_emu_mask = PT_BAR_ALLF;
         break;
+    case PT_BAR_FLAG_EXP:
+        bar_emu_mask = PT_BAR_EXP_EMU_MASK;
+        break;
+    case PT_BAR_FLAG_UNUSED:
+        bar_emu_mask = PT_BAR_ALLF;
+        break;
     default:
         break;
     }
@@ -3083,6 +3075,14 @@ static int pt_bar_reg_write(struct pt_dev *ptdev,
         bar_emu_mask = PT_BAR_ALLF;
         bar_ro_mask = 0;    /* all upper 32bit are R/W */
         break;
+    case PT_BAR_FLAG_EXP:
+        bar_emu_mask = PT_BAR_EXP_EMU_MASK;
+        bar_ro_mask = PT_BAR_EXP_RO_MASK | (r_size -1);
+        break;
+    case PT_BAR_FLAG_UNUSED:
+        bar_emu_mask = PT_BAR_ALLF;
+        bar_ro_mask = PT_BAR_ALLF;
+        break;
     default:
         break;
     }
@@ -3119,6 +3119,9 @@ static int pt_bar_reg_write(struct pt_dev *ptdev,
             goto exit;
         }
         break;
+    case PT_BAR_FLAG_EXP:
+        goto exit;
+        break;
     case PT_BAR_FLAG_UPPER:
         if (cfg_entry->data)
         {
@@ -3157,6 +3160,16 @@ static int pt_bar_reg_write(struct pt_dev *ptdev,
          */
         r->addr = -1;
         goto exit;
+    case PT_BAR_FLAG_UNUSED:
+        /* check unused BAR register */
+        if (*value > 0 && *value < PT_BAR_ALLF-1)
+        {
+            PT_LOG("Warning: Guest attempt to set address to unused Base "
+            "Address Register. [%02x:%02x.%x][Offset:%02xh]\n",
+            pci_bus_num(d->bus), ((d->devfn >> 3) & 0x1F),
+            (d->devfn & 0x7), reg->offset);
+        }
+        break;
     default:
         break;
     }
@@ -3181,45 +3194,6 @@ exit:
     return 0;
 }
 
-/* write Exp ROM BAR */
-static int pt_exp_rom_bar_reg_write(struct pt_dev *ptdev,
-        struct pt_reg_tbl *cfg_entry,
-        uint32_t *value, uint32_t dev_value, uint32_t valid_mask)
-{
-    struct pt_reg_info_tbl *reg = cfg_entry->reg;
-    struct pt_region *base = NULL;
-    PCIDevice *d = (PCIDevice *)&ptdev->dev;
-    PCIIORegion *r;
-    uint32_t writable_mask = 0;
-    uint32_t throughable_mask = 0;
-    uint32_t r_size = 0;
-    uint32_t bar_emu_mask = 0;
-    uint32_t bar_ro_mask = 0;
-
-    r = &d->io_regions[PCI_ROM_SLOT];
-    r_size = r->size;
-    base = &ptdev->bases[PCI_ROM_SLOT];
-    /* align memory type resource size */
-    PT_GET_EMUL_SIZE(base->bar_flag, r_size);
-
-    /* set emulate mask and read-only mask */
-    bar_emu_mask = reg->emu_mask;
-    bar_ro_mask = reg->ro_mask | (r_size - 1);
-
-    /* modify emulate register */
-    writable_mask = bar_emu_mask & ~bar_ro_mask & valid_mask;
-    cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask);
-
-    /* update the corresponding virtual region address */
-    r->addr = cfg_entry->data;
-
-    /* create value for writing to I/O device register */
-    throughable_mask = ~bar_emu_mask & valid_mask;
-    *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask);
-
-    return 0;
-}
-
 /* write Power Management Control/Status register */
 static int pt_pmcsr_reg_write(struct pt_dev *ptdev,
         struct pt_reg_tbl *cfg_entry,
diff --git a/hw/pass-through.h b/hw/pass-through.h
index a503e80..c747828 100644
--- a/hw/pass-through.h
+++ b/hw/pass-through.h
@@ -131,10 +131,13 @@
 #define PT_BAR_MEM_EMU_MASK     0xFFFFFFF0      /* BAR emul mask(Memory) */
 #define PT_BAR_IO_RO_MASK       0x00000003      /* BAR ReadOnly mask(I/O) */
 #define PT_BAR_IO_EMU_MASK      0xFFFFFFFC      /* BAR emul mask(I/O) */
+#define PT_BAR_EXP_RO_MASK      0x000007FE      /* BAR ReadOnly mask(Exp ROM) 
*/
+#define PT_BAR_EXP_EMU_MASK     0xFFFFF800      /* BAR emul mask(Exp ROM) */
 enum {
     PT_BAR_FLAG_MEM = 0,                        /* Memory type BAR */
     PT_BAR_FLAG_IO,                             /* I/O type BAR */
     PT_BAR_FLAG_UPPER,                          /* upper 64bit BAR */
+    PT_BAR_FLAG_EXP,                            /* Exp ROM type BAR */
     PT_BAR_FLAG_UNUSED,                         /* unused BAR */
 };
 enum {

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

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