summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/qemu/qemu/07-xen-pt-split-out-calculation-of-throughable-mask-CVE-2015-4106.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-devtools/qemu/qemu/07-xen-pt-split-out-calculation-of-throughable-mask-CVE-2015-4106.patch')
-rw-r--r--meta/recipes-devtools/qemu/qemu/07-xen-pt-split-out-calculation-of-throughable-mask-CVE-2015-4106.patch263
1 files changed, 263 insertions, 0 deletions
diff --git a/meta/recipes-devtools/qemu/qemu/07-xen-pt-split-out-calculation-of-throughable-mask-CVE-2015-4106.patch b/meta/recipes-devtools/qemu/qemu/07-xen-pt-split-out-calculation-of-throughable-mask-CVE-2015-4106.patch
new file mode 100644
index 0000000000..f8308d8619
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/07-xen-pt-split-out-calculation-of-throughable-mask-CVE-2015-4106.patch
@@ -0,0 +1,263 @@
1Upstream-Status: Backport
2
3Signed-off-by: Kai Kang <kai.kang@windriver.com>
4
5From 0e7ef22136955169a0fd03c4e41af95662352733 Mon Sep 17 00:00:00 2001
6From: Jan Beulich <jbeulich@suse.com>
7Date: Tue, 2 Jun 2015 15:07:01 +0000
8Subject: xen/pt: split out calculation of throughable mask in
9 PCI config space handling
10Bug-Debian: http://bugs.debian.org/787547
11
12This is just to avoid having to adjust that calculation later in
13multiple places.
14
15Note that including ->ro_mask in get_throughable_mask()'s calculation
16is only an apparent (i.e. benign) behavioral change: For r/o fields it
17doesn't matter > whether they get passed through - either the same flag
18is also set in emu_mask (then there's no change at all) or the field is
19r/o in hardware (and hence a write won't change it anyway).
20
21This is a preparatory patch for XSA-131.
22
23Signed-off-by: Jan Beulich <jbeulich@suse.com>
24Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
25Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>
26---
27 hw/xen/xen_pt_config_init.c | 51 ++++++++++++++++++---------------------------
28 1 file changed, 20 insertions(+), 31 deletions(-)
29
30Index: qemu-2.2.0/hw/xen/xen_pt_config_init.c
31===================================================================
32--- qemu-2.2.0.orig/hw/xen/xen_pt_config_init.c
33+++ qemu-2.2.0/hw/xen/xen_pt_config_init.c
34@@ -95,6 +95,14 @@ XenPTReg *xen_pt_find_reg(XenPTRegGroup
35 return NULL;
36 }
37
38+static uint32_t get_throughable_mask(const XenPCIPassthroughState *s,
39+ const XenPTRegInfo *reg,
40+ uint32_t valid_mask)
41+{
42+ uint32_t throughable_mask = ~(reg->emu_mask | reg->ro_mask);
43+
44+ return throughable_mask & valid_mask;
45+}
46
47 /****************
48 * general register functions
49@@ -157,14 +165,13 @@ static int xen_pt_byte_reg_write(XenPCIP
50 {
51 XenPTRegInfo *reg = cfg_entry->reg;
52 uint8_t writable_mask = 0;
53- uint8_t throughable_mask = 0;
54+ uint8_t throughable_mask = get_throughable_mask(s, reg, valid_mask);
55
56 /* modify emulate register */
57 writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
58 cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask);
59
60 /* create value for writing to I/O device register */
61- throughable_mask = ~reg->emu_mask & valid_mask;
62 *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask);
63
64 return 0;
65@@ -175,14 +182,13 @@ static int xen_pt_word_reg_write(XenPCIP
66 {
67 XenPTRegInfo *reg = cfg_entry->reg;
68 uint16_t writable_mask = 0;
69- uint16_t throughable_mask = 0;
70+ uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask);
71
72 /* modify emulate register */
73 writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
74 cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask);
75
76 /* create value for writing to I/O device register */
77- throughable_mask = ~reg->emu_mask & valid_mask;
78 *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask);
79
80 return 0;
81@@ -193,14 +199,13 @@ static int xen_pt_long_reg_write(XenPCIP
82 {
83 XenPTRegInfo *reg = cfg_entry->reg;
84 uint32_t writable_mask = 0;
85- uint32_t throughable_mask = 0;
86+ uint32_t throughable_mask = get_throughable_mask(s, reg, valid_mask);
87
88 /* modify emulate register */
89 writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
90 cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask);
91
92 /* create value for writing to I/O device register */
93- throughable_mask = ~reg->emu_mask & valid_mask;
94 *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask);
95
96 return 0;
97@@ -309,7 +314,7 @@ static int xen_pt_cmd_reg_write(XenPCIPa
98 {
99 XenPTRegInfo *reg = cfg_entry->reg;
100 uint16_t writable_mask = 0;
101- uint16_t throughable_mask = 0;
102+ uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask);
103 uint16_t emu_mask = reg->emu_mask;
104
105 if (s->is_virtfn) {
106@@ -321,8 +326,6 @@ static int xen_pt_cmd_reg_write(XenPCIPa
107 cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask);
108
109 /* create value for writing to I/O device register */
110- throughable_mask = ~emu_mask & valid_mask;
111-
112 if (*val & PCI_COMMAND_INTX_DISABLE) {
113 throughable_mask |= PCI_COMMAND_INTX_DISABLE;
114 } else {
115@@ -478,7 +481,6 @@ static int xen_pt_bar_reg_write(XenPCIPa
116 PCIDevice *d = &s->dev;
117 const PCIIORegion *r;
118 uint32_t writable_mask = 0;
119- uint32_t throughable_mask = 0;
120 uint32_t bar_emu_mask = 0;
121 uint32_t bar_ro_mask = 0;
122 uint32_t r_size = 0;
123@@ -535,8 +537,7 @@ static int xen_pt_bar_reg_write(XenPCIPa
124 }
125
126 /* create value for writing to I/O device register */
127- throughable_mask = ~bar_emu_mask & valid_mask;
128- *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask);
129+ *val = XEN_PT_MERGE_VALUE(*val, dev_value, 0);
130
131 return 0;
132 }
133@@ -550,9 +551,8 @@ static int xen_pt_exp_rom_bar_reg_write(
134 XenPTRegion *base = NULL;
135 PCIDevice *d = (PCIDevice *)&s->dev;
136 uint32_t writable_mask = 0;
137- uint32_t throughable_mask = 0;
138+ uint32_t throughable_mask = get_throughable_mask(s, reg, valid_mask);
139 pcibus_t r_size = 0;
140- uint32_t bar_emu_mask = 0;
141 uint32_t bar_ro_mask = 0;
142
143 r_size = d->io_regions[PCI_ROM_SLOT].size;
144@@ -561,7 +561,6 @@ static int xen_pt_exp_rom_bar_reg_write(
145 r_size = xen_pt_get_emul_size(base->bar_flag, r_size);
146
147 /* set emulate mask and read-only mask */
148- bar_emu_mask = reg->emu_mask;
149 bar_ro_mask = (reg->ro_mask | (r_size - 1)) & ~PCI_ROM_ADDRESS_ENABLE;
150
151 /* modify emulate register */
152@@ -569,7 +568,6 @@ static int xen_pt_exp_rom_bar_reg_write(
153 cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask);
154
155 /* create value for writing to I/O device register */
156- throughable_mask = ~bar_emu_mask & valid_mask;
157 *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask);
158
159 return 0;
160@@ -964,14 +962,13 @@ static int xen_pt_pmcsr_reg_write(XenPCI
161 {
162 XenPTRegInfo *reg = cfg_entry->reg;
163 uint16_t writable_mask = 0;
164- uint16_t throughable_mask = 0;
165+ uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask);
166
167 /* modify emulate register */
168 writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
169 cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask);
170
171 /* create value for writing to I/O device register */
172- throughable_mask = ~reg->emu_mask & valid_mask;
173 *val = XEN_PT_MERGE_VALUE(*val, dev_value & ~PCI_PM_CTRL_PME_STATUS,
174 throughable_mask);
175
176@@ -1060,7 +1057,7 @@ static int xen_pt_msgctrl_reg_write(XenP
177 XenPTRegInfo *reg = cfg_entry->reg;
178 XenPTMSI *msi = s->msi;
179 uint16_t writable_mask = 0;
180- uint16_t throughable_mask = 0;
181+ uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask);
182
183 /* Currently no support for multi-vector */
184 if (*val & PCI_MSI_FLAGS_QSIZE) {
185@@ -1073,7 +1070,6 @@ static int xen_pt_msgctrl_reg_write(XenP
186 msi->flags |= cfg_entry->data & ~PCI_MSI_FLAGS_ENABLE;
187
188 /* create value for writing to I/O device register */
189- throughable_mask = ~reg->emu_mask & valid_mask;
190 *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask);
191
192 /* update MSI */
193@@ -1185,7 +1181,6 @@ static int xen_pt_msgaddr32_reg_write(Xe
194 {
195 XenPTRegInfo *reg = cfg_entry->reg;
196 uint32_t writable_mask = 0;
197- uint32_t throughable_mask = 0;
198 uint32_t old_addr = cfg_entry->data;
199
200 /* modify emulate register */
201@@ -1194,8 +1189,7 @@ static int xen_pt_msgaddr32_reg_write(Xe
202 s->msi->addr_lo = cfg_entry->data;
203
204 /* create value for writing to I/O device register */
205- throughable_mask = ~reg->emu_mask & valid_mask;
206- *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask);
207+ *val = XEN_PT_MERGE_VALUE(*val, dev_value, 0);
208
209 /* update MSI */
210 if (cfg_entry->data != old_addr) {
211@@ -1213,7 +1207,6 @@ static int xen_pt_msgaddr64_reg_write(Xe
212 {
213 XenPTRegInfo *reg = cfg_entry->reg;
214 uint32_t writable_mask = 0;
215- uint32_t throughable_mask = 0;
216 uint32_t old_addr = cfg_entry->data;
217
218 /* check whether the type is 64 bit or not */
219@@ -1230,8 +1223,7 @@ static int xen_pt_msgaddr64_reg_write(Xe
220 s->msi->addr_hi = cfg_entry->data;
221
222 /* create value for writing to I/O device register */
223- throughable_mask = ~reg->emu_mask & valid_mask;
224- *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask);
225+ *val = XEN_PT_MERGE_VALUE(*val, dev_value, 0);
226
227 /* update MSI */
228 if (cfg_entry->data != old_addr) {
229@@ -1253,7 +1245,6 @@ static int xen_pt_msgdata_reg_write(XenP
230 XenPTRegInfo *reg = cfg_entry->reg;
231 XenPTMSI *msi = s->msi;
232 uint16_t writable_mask = 0;
233- uint16_t throughable_mask = 0;
234 uint16_t old_data = cfg_entry->data;
235 uint32_t offset = reg->offset;
236
237@@ -1271,8 +1262,7 @@ static int xen_pt_msgdata_reg_write(XenP
238 msi->data = cfg_entry->data;
239
240 /* create value for writing to I/O device register */
241- throughable_mask = ~reg->emu_mask & valid_mask;
242- *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask);
243+ *val = XEN_PT_MERGE_VALUE(*val, dev_value, 0);
244
245 /* update MSI */
246 if (cfg_entry->data != old_data) {
247@@ -1434,7 +1424,7 @@ static int xen_pt_msixctrl_reg_write(Xen
248 {
249 XenPTRegInfo *reg = cfg_entry->reg;
250 uint16_t writable_mask = 0;
251- uint16_t throughable_mask = 0;
252+ uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask);
253 int debug_msix_enabled_old;
254
255 /* modify emulate register */
256@@ -1442,7 +1432,6 @@ static int xen_pt_msixctrl_reg_write(Xen
257 cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask);
258
259 /* create value for writing to I/O device register */
260- throughable_mask = ~reg->emu_mask & valid_mask;
261 *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask);
262
263 /* update MSI-X */