Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP1:GA
xen.950
xsa131-qemut-4.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File xsa131-qemut-4.patch of Package xen.950
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@suse.com> Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Reviewed-by: Anthony PERARD <anthony.perard@citrix.com> Index: xen-4.4.2-testing/tools/qemu-xen-traditional-dir-remote/hw/pass-through.c =================================================================== --- xen-4.4.2-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/pass-through.c +++ xen-4.4.2-testing/tools/qemu-xen-traditional-dir-remote/hw/pass-through.c @@ -3440,6 +3440,15 @@ static int pt_bar_reg_read(struct pt_dev } +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_d { 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_d { 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_d { 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_de { 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_de 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_de 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_de 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(stru 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(stru 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(stru 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_ 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_ 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 p { 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 p /* 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 p /* 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 { 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 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 { 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 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 p { 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 p 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 { 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 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 */
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor