]> code.ossystems Code Review - openembedded-core.git/blob
28b75922d723731cb47ede4ecd29f8805d20f3fc
[openembedded-core.git] /
1 Upstream-Status: Backport
2
3 Signed-off-by: Kai Kang <kai.kang@windriver.com>
4
5 From 0e7ef22136955169a0fd03c4e41af95662352733 Mon Sep 17 00:00:00 2001
6 From: Jan Beulich <jbeulich@suse.com>
7 Date: Tue, 2 Jun 2015 15:07:01 +0000
8 Subject: xen/pt: split out calculation of throughable mask in
9  PCI config space handling
10 Bug-Debian: http://bugs.debian.org/787547
11
12 This is just to avoid having to adjust that calculation later in
13 multiple places.
14
15 Note that including ->ro_mask in get_throughable_mask()'s calculation
16 is only an apparent (i.e. benign) behavioral change: For r/o fields it
17 doesn't matter > whether they get passed through - either the same flag
18 is also set in emu_mask (then there's no change at all) or the field is
19 r/o in hardware (and hence a write won't change it anyway).
20
21 This is a preparatory patch for XSA-131.
22
23 Signed-off-by: Jan Beulich <jbeulich@suse.com>
24 Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
25 Reviewed-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
30 diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c
31 index 027ac32..3833b9e 100644
32 --- a/hw/xen/xen_pt_config_init.c
33 +++ b/hw/xen/xen_pt_config_init.c
34 @@ -95,6 +95,14 @@ XenPTReg *xen_pt_find_reg(XenPTRegGroup *reg_grp, uint32_t address)
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(XenPCIPassthroughState *s, XenPTReg *cfg_entry,
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(XenPCIPassthroughState *s, XenPTReg *cfg_entry,
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(XenPCIPassthroughState *s, XenPTReg *cfg_entry,
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 @@ -292,15 +297,13 @@ static int xen_pt_cmd_reg_write(XenPCIPassthroughState *s, XenPTReg *cfg_entry,
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  
104      /* modify emulate register */
105      writable_mask = ~reg->ro_mask & valid_mask;
106      cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask);
107  
108      /* create value for writing to I/O device register */
109 -    throughable_mask = ~reg->emu_mask & valid_mask;
110 -
111      if (*val & PCI_COMMAND_INTX_DISABLE) {
112          throughable_mask |= PCI_COMMAND_INTX_DISABLE;
113      } else {
114 @@ -454,7 +457,6 @@ static int xen_pt_bar_reg_write(XenPCIPassthroughState *s, XenPTReg *cfg_entry,
115      PCIDevice *d = &s->dev;
116      const PCIIORegion *r;
117      uint32_t writable_mask = 0;
118 -    uint32_t throughable_mask = 0;
119      uint32_t bar_emu_mask = 0;
120      uint32_t bar_ro_mask = 0;
121      uint32_t r_size = 0;
122 @@ -511,8 +513,7 @@ static int xen_pt_bar_reg_write(XenPCIPassthroughState *s, XenPTReg *cfg_entry,
123      }
124  
125      /* create value for writing to I/O device register */
126 -    throughable_mask = ~bar_emu_mask & valid_mask;
127 -    *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask);
128 +    *val = XEN_PT_MERGE_VALUE(*val, dev_value, 0);
129  
130      return 0;
131  }
132 @@ -526,9 +527,8 @@ static int xen_pt_exp_rom_bar_reg_write(XenPCIPassthroughState *s,
133      XenPTRegion *base = NULL;
134      PCIDevice *d = (PCIDevice *)&s->dev;
135      uint32_t writable_mask = 0;
136 -    uint32_t throughable_mask = 0;
137 +    uint32_t throughable_mask = get_throughable_mask(s, reg, valid_mask);
138      pcibus_t r_size = 0;
139 -    uint32_t bar_emu_mask = 0;
140      uint32_t bar_ro_mask = 0;
141  
142      r_size = d->io_regions[PCI_ROM_SLOT].size;
143 @@ -537,7 +537,6 @@ static int xen_pt_exp_rom_bar_reg_write(XenPCIPassthroughState *s,
144      r_size = xen_pt_get_emul_size(base->bar_flag, r_size);
145  
146      /* set emulate mask and read-only mask */
147 -    bar_emu_mask = reg->emu_mask;
148      bar_ro_mask = (reg->ro_mask | (r_size - 1)) & ~PCI_ROM_ADDRESS_ENABLE;
149  
150      /* modify emulate register */
151 @@ -545,7 +544,6 @@ static int xen_pt_exp_rom_bar_reg_write(XenPCIPassthroughState *s,
152      cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask);
153  
154      /* create value for writing to I/O device register */
155 -    throughable_mask = ~bar_emu_mask & valid_mask;
156      *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask);
157  
158      return 0;
159 @@ -940,14 +938,13 @@ static int xen_pt_pmcsr_reg_write(XenPCIPassthroughState *s,
160  {
161      XenPTRegInfo *reg = cfg_entry->reg;
162      uint16_t writable_mask = 0;
163 -    uint16_t throughable_mask = 0;
164 +    uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask);
165  
166      /* modify emulate register */
167      writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
168      cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask);
169  
170      /* create value for writing to I/O device register */
171 -    throughable_mask = ~reg->emu_mask & valid_mask;
172      *val = XEN_PT_MERGE_VALUE(*val, dev_value & ~PCI_PM_CTRL_PME_STATUS,
173                                throughable_mask);
174  
175 @@ -1036,7 +1033,7 @@ static int xen_pt_msgctrl_reg_write(XenPCIPassthroughState *s,
176      XenPTRegInfo *reg = cfg_entry->reg;
177      XenPTMSI *msi = s->msi;
178      uint16_t writable_mask = 0;
179 -    uint16_t throughable_mask = 0;
180 +    uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask);
181  
182      /* Currently no support for multi-vector */
183      if (*val & PCI_MSI_FLAGS_QSIZE) {
184 @@ -1049,7 +1046,6 @@ static int xen_pt_msgctrl_reg_write(XenPCIPassthroughState *s,
185      msi->flags |= cfg_entry->data & ~PCI_MSI_FLAGS_ENABLE;
186  
187      /* create value for writing to I/O device register */
188 -    throughable_mask = ~reg->emu_mask & valid_mask;
189      *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask);
190  
191      /* update MSI */
192 @@ -1161,7 +1157,6 @@ static int xen_pt_msgaddr32_reg_write(XenPCIPassthroughState *s,
193  {
194      XenPTRegInfo *reg = cfg_entry->reg;
195      uint32_t writable_mask = 0;
196 -    uint32_t throughable_mask = 0;
197      uint32_t old_addr = cfg_entry->data;
198  
199      /* modify emulate register */
200 @@ -1170,8 +1165,7 @@ static int xen_pt_msgaddr32_reg_write(XenPCIPassthroughState *s,
201      s->msi->addr_lo = cfg_entry->data;
202  
203      /* create value for writing to I/O device register */
204 -    throughable_mask = ~reg->emu_mask & valid_mask;
205 -    *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask);
206 +    *val = XEN_PT_MERGE_VALUE(*val, dev_value, 0);
207  
208      /* update MSI */
209      if (cfg_entry->data != old_addr) {
210 @@ -1189,7 +1183,6 @@ static int xen_pt_msgaddr64_reg_write(XenPCIPassthroughState *s,
211  {
212      XenPTRegInfo *reg = cfg_entry->reg;
213      uint32_t writable_mask = 0;
214 -    uint32_t throughable_mask = 0;
215      uint32_t old_addr = cfg_entry->data;
216  
217      /* check whether the type is 64 bit or not */
218 @@ -1206,8 +1199,7 @@ static int xen_pt_msgaddr64_reg_write(XenPCIPassthroughState *s,
219      s->msi->addr_hi = cfg_entry->data;
220  
221      /* create value for writing to I/O device register */
222 -    throughable_mask = ~reg->emu_mask & valid_mask;
223 -    *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask);
224 +    *val = XEN_PT_MERGE_VALUE(*val, dev_value, 0);
225  
226      /* update MSI */
227      if (cfg_entry->data != old_addr) {
228 @@ -1229,7 +1221,6 @@ static int xen_pt_msgdata_reg_write(XenPCIPassthroughState *s,
229      XenPTRegInfo *reg = cfg_entry->reg;
230      XenPTMSI *msi = s->msi;
231      uint16_t writable_mask = 0;
232 -    uint16_t throughable_mask = 0;
233      uint16_t old_data = cfg_entry->data;
234      uint32_t offset = reg->offset;
235  
236 @@ -1247,8 +1238,7 @@ static int xen_pt_msgdata_reg_write(XenPCIPassthroughState *s,
237      msi->data = cfg_entry->data;
238  
239      /* create value for writing to I/O device register */
240 -    throughable_mask = ~reg->emu_mask & valid_mask;
241 -    *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask);
242 +    *val = XEN_PT_MERGE_VALUE(*val, dev_value, 0);
243  
244      /* update MSI */
245      if (cfg_entry->data != old_data) {
246 @@ -1410,7 +1400,7 @@ static int xen_pt_msixctrl_reg_write(XenPCIPassthroughState *s,
247  {
248      XenPTRegInfo *reg = cfg_entry->reg;
249      uint16_t writable_mask = 0;
250 -    uint16_t throughable_mask = 0;
251 +    uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask);
252      int debug_msix_enabled_old;
253  
254      /* modify emulate register */
255 @@ -1418,7 +1408,6 @@ static int xen_pt_msixctrl_reg_write(XenPCIPassthroughState *s,
256      cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask);
257  
258      /* create value for writing to I/O device register */
259 -    throughable_mask = ~reg->emu_mask & valid_mask;
260      *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask);
261  
262      /* update MSI-X */
263 -- 
264 2.1.4
265