[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [qemu-xen-4.4-testing] xen/pt: split out calculation of throughable mask in PCI config space handling
commit dd37ad776c7ea026b7b9f34b240f5714aee6819d Author: Jan Beulich <jbeulich@xxxxxxxx> AuthorDate: Wed Jun 10 14:12:16 2015 +0100 Commit: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx> CommitDate: Wed Jun 10 14:12:16 2015 +0100 xen/pt: split out calculation of throughable mask in PCI config space handling This is just to avoid having to adjust that calculation later in multiple places. Note that including ->ro_mask in get_throughable_mask()'s calculation is only an apparent (i.e. benign) behavioral change: For r/o fields it doesn't matter > whether they get passed through - either the same flag is also set in emu_mask (then there's no change at all) or the field is r/o in hardware (and hence a write won't change it anyway). This is a preparatory patch for XSA-131. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> Acked-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> Reviewed-by: Anthony PERARD <anthony.perard@xxxxxxxxxx> --- hw/pass-through.c | 59 +++++++++++++++++++++------------------------------- 1 files changed, 24 insertions(+), 35 deletions(-) diff --git a/hw/pass-through.c b/hw/pass-through.c index 7d4ef0e..9ec9211 100644 --- a/hw/pass-through.c +++ b/hw/pass-through.c @@ -3440,6 +3440,15 @@ static int pt_bar_reg_read(struct pt_dev *ptdev, } +static uint32_t get_throughable_mask(const struct pt_dev *ptdev, + const struct pt_reg_info_tbl *reg, + uint32_t valid_mask) +{ + uint32_t throughable_mask = ~(reg->emu_mask | reg->ro_mask); + + return throughable_mask & valid_mask; +} + /* write byte size emulate register */ static int pt_byte_reg_write(struct pt_dev *ptdev, struct pt_reg_tbl *cfg_entry, @@ -3447,14 +3456,13 @@ static int pt_byte_reg_write(struct pt_dev *ptdev, { struct pt_reg_info_tbl *reg = cfg_entry->reg; uint8_t writable_mask = 0; - uint8_t throughable_mask = 0; + uint8_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask); /* modify emulate register */ writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); /* create value for writing to I/O device register */ - throughable_mask = ~reg->emu_mask & valid_mask; *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); return 0; @@ -3467,14 +3475,13 @@ static int pt_word_reg_write(struct pt_dev *ptdev, { struct pt_reg_info_tbl *reg = cfg_entry->reg; uint16_t writable_mask = 0; - uint16_t throughable_mask = 0; + uint16_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask); /* modify emulate register */ writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); /* create value for writing to I/O device register */ - throughable_mask = ~reg->emu_mask & valid_mask; *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); return 0; @@ -3487,14 +3494,13 @@ static int pt_long_reg_write(struct pt_dev *ptdev, { struct pt_reg_info_tbl *reg = cfg_entry->reg; uint32_t writable_mask = 0; - uint32_t throughable_mask = 0; + uint32_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask); /* modify emulate register */ writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); /* create value for writing to I/O device register */ - throughable_mask = ~reg->emu_mask & valid_mask; *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); return 0; @@ -3507,7 +3513,7 @@ static int pt_cmd_reg_write(struct pt_dev *ptdev, { struct pt_reg_info_tbl *reg = cfg_entry->reg; uint16_t writable_mask = 0; - uint16_t throughable_mask = 0; + uint16_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask); uint16_t wr_value = *value; /* modify emulate register */ @@ -3515,8 +3521,6 @@ static int pt_cmd_reg_write(struct pt_dev *ptdev, cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); /* create value for writing to I/O device register */ - throughable_mask = ~reg->emu_mask & valid_mask; - if (*value & PCI_COMMAND_DISABLE_INTx) { if (ptdev->msi_trans_en) @@ -3562,7 +3566,6 @@ static int pt_bar_reg_write(struct pt_dev *ptdev, PCIDevice *d = (PCIDevice *)&ptdev->dev; PCIIORegion *r; uint32_t writable_mask = 0; - uint32_t throughable_mask = 0; uint32_t bar_emu_mask = 0; uint32_t bar_ro_mask = 0; uint32_t new_addr, last_addr; @@ -3689,8 +3692,7 @@ static int pt_bar_reg_write(struct pt_dev *ptdev, exit: /* 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); + *value = PT_MERGE_VALUE(*value, dev_value, 0); /* After BAR reg update, we need to remap BAR*/ reg_grp_entry = pt_find_reg_grp(ptdev, PCI_COMMAND); @@ -3717,9 +3719,8 @@ static int pt_exp_rom_bar_reg_write(struct pt_dev *ptdev, PCIDevice *d = (PCIDevice *)&ptdev->dev; PCIIORegion *r; uint32_t writable_mask = 0; - uint32_t throughable_mask = 0; + uint32_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask); uint32_t r_size = 0; - uint32_t bar_emu_mask = 0; uint32_t bar_ro_mask = 0; r = &d->io_regions[PCI_ROM_SLOT]; @@ -3729,7 +3730,6 @@ static int pt_exp_rom_bar_reg_write(struct pt_dev *ptdev, 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)) & ~PCI_ROM_ADDRESS_ENABLE; /* modify emulate register */ @@ -3749,7 +3749,6 @@ static int pt_exp_rom_bar_reg_write(struct pt_dev *ptdev, 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); /* After BAR reg update, we need to remap BAR*/ @@ -3774,7 +3773,7 @@ static int pt_pmcsr_reg_write(struct pt_dev *ptdev, struct pt_reg_info_tbl *reg = cfg_entry->reg; PCIDevice *d = &ptdev->dev; uint16_t writable_mask = 0; - uint16_t throughable_mask = 0; + uint16_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask); struct pt_pm_info *pm_state = ptdev->pm_state; uint16_t read_val = 0; @@ -3783,7 +3782,6 @@ static int pt_pmcsr_reg_write(struct pt_dev *ptdev, cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); /* create value for writing to I/O device register */ - throughable_mask = ~reg->emu_mask & valid_mask; *value = PT_MERGE_VALUE(*value, dev_value & ~PCI_PM_CTRL_PME_STATUS, throughable_mask); @@ -3892,7 +3890,7 @@ static int pt_msgctrl_reg_write(struct pt_dev *ptdev, { struct pt_reg_info_tbl *reg = cfg_entry->reg; uint16_t writable_mask = 0; - uint16_t throughable_mask = 0; + uint16_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask); uint16_t old_ctrl = cfg_entry->data; PCIDevice *pd = (PCIDevice *)ptdev; uint16_t val; @@ -3904,8 +3902,10 @@ static int pt_msgctrl_reg_write(struct pt_dev *ptdev, /* modify emulate register */ writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; /* also emulate MSI_ENABLE bit for MSI-INTx translation */ - if (ptdev->msi_trans_en) + if (ptdev->msi_trans_en) { writable_mask |= PCI_MSI_FLAGS_ENABLE & valid_mask; + throughable_mask &= ~PCI_MSI_FLAGS_ENABLE; + } cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); /* update the msi_info too */ ptdev->msi->flags |= cfg_entry->data & @@ -3913,10 +3913,6 @@ static int pt_msgctrl_reg_write(struct pt_dev *ptdev, /* create value for writing to I/O device register */ val = *value; - throughable_mask = ~reg->emu_mask & valid_mask; - /* don't pass through MSI_ENABLE bit for MSI-INTx translation */ - if (ptdev->msi_trans_en) - throughable_mask &= ~PCI_MSI_FLAGS_ENABLE; *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); /* update MSI */ @@ -3970,7 +3966,6 @@ static int pt_msgaddr32_reg_write(struct pt_dev *ptdev, { struct pt_reg_info_tbl *reg = cfg_entry->reg; uint32_t writable_mask = 0; - uint32_t throughable_mask = 0; uint32_t old_addr = cfg_entry->data; /* modify emulate register */ @@ -3980,8 +3975,7 @@ static int pt_msgaddr32_reg_write(struct pt_dev *ptdev, ptdev->msi->addr_lo = cfg_entry->data; /* create value for writing to I/O device register */ - throughable_mask = ~reg->emu_mask & valid_mask; - *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); + *value = PT_MERGE_VALUE(*value, dev_value, 0); /* update MSI */ if (cfg_entry->data != old_addr) @@ -4000,7 +3994,6 @@ static int pt_msgaddr64_reg_write(struct pt_dev *ptdev, { struct pt_reg_info_tbl *reg = cfg_entry->reg; uint32_t writable_mask = 0; - uint32_t throughable_mask = 0; uint32_t old_addr = cfg_entry->data; /* check whether the type is 64 bit or not */ @@ -4018,8 +4011,7 @@ static int pt_msgaddr64_reg_write(struct pt_dev *ptdev, ptdev->msi->addr_hi = cfg_entry->data; /* create value for writing to I/O device register */ - throughable_mask = ~reg->emu_mask & valid_mask; - *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); + *value = PT_MERGE_VALUE(*value, dev_value, 0); /* update MSI */ if (cfg_entry->data != old_addr) @@ -4039,7 +4031,6 @@ static int pt_msgdata_reg_write(struct pt_dev *ptdev, { struct pt_reg_info_tbl *reg = cfg_entry->reg; uint16_t writable_mask = 0; - uint16_t throughable_mask = 0; uint16_t old_data = cfg_entry->data; uint32_t flags = ptdev->msi->flags; uint32_t offset = reg->offset; @@ -4060,8 +4051,7 @@ static int pt_msgdata_reg_write(struct pt_dev *ptdev, ptdev->msi->data = cfg_entry->data; /* create value for writing to I/O device register */ - throughable_mask = ~reg->emu_mask & valid_mask; - *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); + *value = PT_MERGE_VALUE(*value, dev_value, 0); /* update MSI */ if (cfg_entry->data != old_data) @@ -4080,7 +4070,7 @@ static int pt_msixctrl_reg_write(struct pt_dev *ptdev, { struct pt_reg_info_tbl *reg = cfg_entry->reg; uint16_t writable_mask = 0; - uint16_t throughable_mask = 0; + uint16_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask); uint16_t old_ctrl = cfg_entry->data; /* modify emulate register */ @@ -4088,7 +4078,6 @@ static int pt_msixctrl_reg_write(struct pt_dev *ptdev, cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); /* create value for writing to I/O device register */ - throughable_mask = ~reg->emu_mask & valid_mask; *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); /* update MSI-X */ -- generated by git-patchbot for /home/xen/git/qemu-xen-4.4-testing.git _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |