QEMU update with VENOM (CVE-2015-3456) patch
[packages/centos6/qemu.git] / 0624-xhci-kill-xhci_mem_-read-write-dispatcher-functions.patch
1 From d2efc9f3dc62810ef6075f8759c9856016447c14 Mon Sep 17 00:00:00 2001
2 From: Gerd Hoffmann <kraxel@redhat.com>
3 Date: Tue, 4 Sep 2012 14:42:20 +0200
4 Subject: [PATCH] xhci: kill xhci_mem_{read,write} dispatcher functions
5
6 ... and register subregions instead, so we offload the dispatching
7 to the the memory subsystem which is designed to handle it.
8
9 Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
10 ---
11  hw/usb/hcd-xhci.c | 140 +++++++++++++++++++++++++++++-------------------------
12  1 file changed, 75 insertions(+), 65 deletions(-)
13
14 diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
15 index 4992705..4ba9464 100644
16 --- a/hw/usb/hcd-xhci.c
17 +++ b/hw/usb/hcd-xhci.c
18 @@ -404,6 +404,10 @@ struct XHCIState {
19      USBBus bus;
20      qemu_irq irq;
21      MemoryRegion mem;
22 +    MemoryRegion mem_cap;
23 +    MemoryRegion mem_oper;
24 +    MemoryRegion mem_runtime;
25 +    MemoryRegion mem_doorbell;
26      const char *name;
27      unsigned int devaddr;
28  
29 @@ -2343,8 +2347,9 @@ static void xhci_reset(DeviceState *dev)
30      xhci_mfwrap_update(xhci);
31  }
32  
33 -static uint32_t xhci_cap_read(XHCIState *xhci, uint32_t reg)
34 +static uint64_t xhci_cap_read(void *ptr, target_phys_addr_t reg, unsigned size)
35  {
36 +    XHCIState *xhci = ptr;
37      uint32_t ret;
38  
39      switch (reg) {
40 @@ -2401,7 +2406,7 @@ static uint32_t xhci_cap_read(XHCIState *xhci, uint32_t reg)
41          ret = 0x00000000; /* reserved */
42          break;
43      default:
44 -        fprintf(stderr, "xhci_cap_read: reg %d unimplemented\n", reg);
45 +        fprintf(stderr, "xhci_cap_read: reg %d unimplemented\n", (int)reg);
46          ret = 0;
47      }
48  
49 @@ -2482,8 +2487,9 @@ static void xhci_port_write(XHCIState *xhci, uint32_t reg, uint32_t val)
50      }
51  }
52  
53 -static uint32_t xhci_oper_read(XHCIState *xhci, uint32_t reg)
54 +static uint64_t xhci_oper_read(void *ptr, target_phys_addr_t reg, unsigned size)
55  {
56 +    XHCIState *xhci = ptr;
57      uint32_t ret;
58  
59      if (reg >= 0x400) {
60 @@ -2519,7 +2525,7 @@ static uint32_t xhci_oper_read(XHCIState *xhci, uint32_t reg)
61          ret = xhci->config;
62          break;
63      default:
64 -        fprintf(stderr, "xhci_oper_read: reg 0x%x unimplemented\n", reg);
65 +        fprintf(stderr, "xhci_oper_read: reg 0x%x unimplemented\n", (int)reg);
66          ret = 0;
67      }
68  
69 @@ -2527,8 +2533,11 @@ static uint32_t xhci_oper_read(XHCIState *xhci, uint32_t reg)
70      return ret;
71  }
72  
73 -static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val)
74 +static void xhci_oper_write(void *ptr, target_phys_addr_t reg,
75 +                            uint64_t val, unsigned size)
76  {
77 +    XHCIState *xhci = ptr;
78 +
79      if (reg >= 0x400) {
80          xhci_port_write(xhci, reg - 0x400, val);
81          return;
82 @@ -2586,12 +2595,14 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val)
83          xhci->config = val & 0xff;
84          break;
85      default:
86 -        fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", reg);
87 +        fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", (int)reg);
88      }
89  }
90  
91 -static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg)
92 +static uint64_t xhci_runtime_read(void *ptr, target_phys_addr_t reg,
93 +                                  unsigned size)
94  {
95 +    XHCIState *xhci = ptr;
96      uint32_t ret = 0;
97  
98      if (reg < 0x20) {
99 @@ -2600,7 +2611,8 @@ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg)
100              ret = xhci_mfindex_get(xhci) & 0x3fff;
101              break;
102          default:
103 -            fprintf(stderr, "xhci_runtime_read: reg 0x%x unimplemented\n", reg);
104 +            fprintf(stderr, "xhci_runtime_read: reg 0x%x unimplemented\n",
105 +                    (int)reg);
106              break;
107          }
108      } else {
109 @@ -2635,14 +2647,16 @@ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg)
110      return ret;
111  }
112  
113 -static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val)
114 +static void xhci_runtime_write(void *ptr, target_phys_addr_t reg,
115 +                               uint64_t val, unsigned size)
116  {
117 +    XHCIState *xhci = ptr;
118      int v = (reg - 0x20) / 0x20;
119      XHCIInterrupter *intr = &xhci->intr[v];
120      trace_usb_xhci_runtime_write(reg, val);
121  
122      if (reg < 0x20) {
123 -        fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", reg);
124 +        fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", (int)reg);
125          return;
126      }
127  
128 @@ -2684,19 +2698,24 @@ static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val)
129          xhci_events_update(xhci, v);
130          break;
131      default:
132 -        fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", reg);
133 +        fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n",
134 +                (int)reg);
135      }
136  }
137  
138 -static uint32_t xhci_doorbell_read(XHCIState *xhci, uint32_t reg)
139 +static uint64_t xhci_doorbell_read(void *ptr, target_phys_addr_t reg,
140 +                                   unsigned size)
141  {
142      /* doorbells always read as 0 */
143      trace_usb_xhci_doorbell_read(reg, 0);
144      return 0;
145  }
146  
147 -static void xhci_doorbell_write(XHCIState *xhci, uint32_t reg, uint32_t val)
148 +static void xhci_doorbell_write(void *ptr, target_phys_addr_t reg,
149 +                                uint64_t val, unsigned size)
150  {
151 +    XHCIState *xhci = ptr;
152 +
153      trace_usb_xhci_doorbell_write(reg, val);
154  
155      if (!xhci_running(xhci)) {
156 @@ -2710,69 +2729,47 @@ static void xhci_doorbell_write(XHCIState *xhci, uint32_t reg, uint32_t val)
157          if (val == 0) {
158              xhci_process_commands(xhci);
159          } else {
160 -            fprintf(stderr, "xhci: bad doorbell 0 write: 0x%x\n", val);
161 +            fprintf(stderr, "xhci: bad doorbell 0 write: 0x%x\n",
162 +                    (uint32_t)val);
163          }
164      } else {
165          if (reg > MAXSLOTS) {
166 -            fprintf(stderr, "xhci: bad doorbell %d\n", reg);
167 +            fprintf(stderr, "xhci: bad doorbell %d\n", (int)reg);
168          } else if (val > 31) {
169 -            fprintf(stderr, "xhci: bad doorbell %d write: 0x%x\n", reg, val);
170 +            fprintf(stderr, "xhci: bad doorbell %d write: 0x%x\n",
171 +                    (int)reg, (uint32_t)val);
172          } else {
173              xhci_kick_ep(xhci, reg, val);
174          }
175      }
176  }
177  
178 -static uint64_t xhci_mem_read(void *ptr, target_phys_addr_t addr,
179 -                              unsigned size)
180 -{
181 -    XHCIState *xhci = ptr;
182 -
183 -    /* Only aligned reads are allowed on xHCI */
184 -    if (addr & 3) {
185 -        fprintf(stderr, "xhci_mem_read: Mis-aligned read\n");
186 -        return 0;
187 -    }
188 -
189 -    if (addr < LEN_CAP) {
190 -        return xhci_cap_read(xhci, addr);
191 -    } else if (addr >= OFF_OPER && addr < (OFF_OPER + LEN_OPER)) {
192 -        return xhci_oper_read(xhci, addr - OFF_OPER);
193 -    } else if (addr >= OFF_RUNTIME && addr < (OFF_RUNTIME + LEN_RUNTIME)) {
194 -        return xhci_runtime_read(xhci, addr - OFF_RUNTIME);
195 -    } else if (addr >= OFF_DOORBELL && addr < (OFF_DOORBELL + LEN_DOORBELL)) {
196 -        return xhci_doorbell_read(xhci, addr - OFF_DOORBELL);
197 -    } else {
198 -        fprintf(stderr, "xhci_mem_read: Bad offset %x\n", (int)addr);
199 -        return 0;
200 -    }
201 -}
202 -
203 -static void xhci_mem_write(void *ptr, target_phys_addr_t addr,
204 -                           uint64_t val, unsigned size)
205 -{
206 -    XHCIState *xhci = ptr;
207 +static const MemoryRegionOps xhci_cap_ops = {
208 +    .read = xhci_cap_read,
209 +    .valid.min_access_size = 4,
210 +    .valid.max_access_size = 4,
211 +    .endianness = DEVICE_LITTLE_ENDIAN,
212 +};
213  
214 -    /* Only aligned writes are allowed on xHCI */
215 -    if (addr & 3) {
216 -        fprintf(stderr, "xhci_mem_write: Mis-aligned write\n");
217 -        return;
218 -    }
219 +static const MemoryRegionOps xhci_oper_ops = {
220 +    .read = xhci_oper_read,
221 +    .write = xhci_oper_write,
222 +    .valid.min_access_size = 4,
223 +    .valid.max_access_size = 4,
224 +    .endianness = DEVICE_LITTLE_ENDIAN,
225 +};
226  
227 -    if (addr >= OFF_OPER && addr < (OFF_OPER + LEN_OPER)) {
228 -        xhci_oper_write(xhci, addr - OFF_OPER, val);
229 -    } else if (addr >= OFF_RUNTIME && addr < (OFF_RUNTIME + LEN_RUNTIME)) {
230 -        xhci_runtime_write(xhci, addr - OFF_RUNTIME, val);
231 -    } else if (addr >= OFF_DOORBELL && addr < (OFF_DOORBELL + LEN_DOORBELL)) {
232 -        xhci_doorbell_write(xhci, addr - OFF_DOORBELL, val);
233 -    } else {
234 -        fprintf(stderr, "xhci_mem_write: Bad offset %x\n", (int)addr);
235 -    }
236 -}
237 +static const MemoryRegionOps xhci_runtime_ops = {
238 +    .read = xhci_runtime_read,
239 +    .write = xhci_runtime_write,
240 +    .valid.min_access_size = 4,
241 +    .valid.max_access_size = 4,
242 +    .endianness = DEVICE_LITTLE_ENDIAN,
243 +};
244  
245 -static const MemoryRegionOps xhci_mem_ops = {
246 -    .read = xhci_mem_read,
247 -    .write = xhci_mem_write,
248 +static const MemoryRegionOps xhci_doorbell_ops = {
249 +    .read = xhci_doorbell_read,
250 +    .write = xhci_doorbell_write,
251      .valid.min_access_size = 1,
252      .valid.max_access_size = 4,
253      .impl.min_access_size = 4,
254 @@ -2940,8 +2937,21 @@ static int usb_xhci_initfn(struct PCIDevice *dev)
255  
256      xhci->irq = xhci->pci_dev.irq[0];
257  
258 -    memory_region_init_io(&xhci->mem, &xhci_mem_ops, xhci,
259 -                          "xhci", LEN_REGS);
260 +    memory_region_init(&xhci->mem, "xhci", LEN_REGS);
261 +    memory_region_init_io(&xhci->mem_cap, &xhci_cap_ops, xhci,
262 +                          "capabilities", LEN_CAP);
263 +    memory_region_init_io(&xhci->mem_oper, &xhci_oper_ops, xhci,
264 +                          "operational", 0x400 + 0x10 * xhci->numports);
265 +    memory_region_init_io(&xhci->mem_runtime, &xhci_runtime_ops, xhci,
266 +                          "runtime", LEN_RUNTIME);
267 +    memory_region_init_io(&xhci->mem_doorbell, &xhci_doorbell_ops, xhci,
268 +                          "doorbell", LEN_DOORBELL);
269 +
270 +    memory_region_add_subregion(&xhci->mem, 0,            &xhci->mem_cap);
271 +    memory_region_add_subregion(&xhci->mem, OFF_OPER,     &xhci->mem_oper);
272 +    memory_region_add_subregion(&xhci->mem, OFF_RUNTIME,  &xhci->mem_runtime);
273 +    memory_region_add_subregion(&xhci->mem, OFF_DOORBELL, &xhci->mem_doorbell);
274 +
275      pci_register_bar(&xhci->pci_dev, 0,
276                       PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64,
277                       &xhci->mem);
278 -- 
279 1.7.12.1
280