diff options
author | Jan Beulich <JBeulich@suse.com> | 2017-09-25 04:01:01 -0400 |
---|---|---|
committer | Boris Ostrovsky <boris.ostrovsky@oracle.com> | 2017-09-28 08:26:25 -0400 |
commit | 8c28ef3f1c1c57b6f468343d5959e5125b30334d (patch) | |
tree | d0ed3d8dbfbd919dabab198cf9187c77e23177b5 | |
parent | 51a9a8284e43642fc3e85810fd54f4c245d23a14 (diff) |
xen-pciback: relax BAR sizing write value check
Just like done in d2bd05d88d ("xen-pciback: return proper values during
BAR sizing") for the ROM BAR, ordinary ones also shouldn't compare the
written value directly against ~0, but consider the r/o bits at the
bottom (if any).
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
-rw-r--r-- | drivers/xen/xen-pciback/conf_space_header.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/drivers/xen/xen-pciback/conf_space_header.c b/drivers/xen/xen-pciback/conf_space_header.c index 5fbfd9cfb6d6..5b3d57fc82d3 100644 --- a/drivers/xen/xen-pciback/conf_space_header.c +++ b/drivers/xen/xen-pciback/conf_space_header.c | |||
@@ -169,6 +169,9 @@ static int rom_write(struct pci_dev *dev, int offset, u32 value, void *data) | |||
169 | static int bar_write(struct pci_dev *dev, int offset, u32 value, void *data) | 169 | static int bar_write(struct pci_dev *dev, int offset, u32 value, void *data) |
170 | { | 170 | { |
171 | struct pci_bar_info *bar = data; | 171 | struct pci_bar_info *bar = data; |
172 | unsigned int pos = (offset - PCI_BASE_ADDRESS_0) / 4; | ||
173 | const struct resource *res = dev->resource; | ||
174 | u32 mask; | ||
172 | 175 | ||
173 | if (unlikely(!bar)) { | 176 | if (unlikely(!bar)) { |
174 | pr_warn(DRV_NAME ": driver data not found for %s\n", | 177 | pr_warn(DRV_NAME ": driver data not found for %s\n", |
@@ -179,7 +182,13 @@ static int bar_write(struct pci_dev *dev, int offset, u32 value, void *data) | |||
179 | /* A write to obtain the length must happen as a 32-bit write. | 182 | /* A write to obtain the length must happen as a 32-bit write. |
180 | * This does not (yet) support writing individual bytes | 183 | * This does not (yet) support writing individual bytes |
181 | */ | 184 | */ |
182 | if (value == ~0) | 185 | if (res[pos].flags & IORESOURCE_IO) |
186 | mask = ~PCI_BASE_ADDRESS_IO_MASK; | ||
187 | else if (pos && (res[pos - 1].flags & IORESOURCE_MEM_64)) | ||
188 | mask = 0; | ||
189 | else | ||
190 | mask = ~PCI_BASE_ADDRESS_MEM_MASK; | ||
191 | if ((value | mask) == ~0U) | ||
183 | bar->which = 1; | 192 | bar->which = 1; |
184 | else { | 193 | else { |
185 | u32 tmpval; | 194 | u32 tmpval; |