[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |