xref: /qemu/hw/acpi/pcihp.c (revision cc03dfa827819c78fdc6c8c5065910d6ac2567f1)
1  /*
2   * QEMU<->ACPI BIOS PCI hotplug interface
3   *
4   * QEMU supports PCI hotplug via ACPI. This module
5   * implements the interface between QEMU and the ACPI BIOS.
6   * Interface specification - see docs/specs/acpi_pci_hotplug.txt
7   *
8   * Copyright (c) 2013, Red Hat Inc, Michael S. Tsirkin (mst@redhat.com)
9   * Copyright (c) 2006 Fabrice Bellard
10   *
11   * This library is free software; you can redistribute it and/or
12   * modify it under the terms of the GNU Lesser General Public
13   * License version 2.1 as published by the Free Software Foundation.
14   *
15   * This library is distributed in the hope that it will be useful,
16   * but WITHOUT ANY WARRANTY; without even the implied warranty of
17   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18   * Lesser General Public License for more details.
19   *
20   * You should have received a copy of the GNU Lesser General Public
21   * License along with this library; if not, see <http://www.gnu.org/licenses/>
22   *
23   * Contributions after 2012-01-13 are licensed under the terms of the
24   * GNU GPL, version 2 or (at your option) any later version.
25   */
26  
27  #include "qemu/osdep.h"
28  #include "hw/acpi/pcihp.h"
29  
30  #include "hw/pci-host/i440fx.h"
31  #include "hw/pci/pci.h"
32  #include "hw/pci/pci_bridge.h"
33  #include "hw/pci/pci_host.h"
34  #include "hw/pci/pcie_port.h"
35  #include "hw/pci-bridge/xio3130_downstream.h"
36  #include "hw/i386/acpi-build.h"
37  #include "hw/acpi/acpi.h"
38  #include "hw/pci/pci_bus.h"
39  #include "migration/vmstate.h"
40  #include "qapi/error.h"
41  #include "qom/qom-qobject.h"
42  #include "trace.h"
43  
44  #define ACPI_PCIHP_SIZE 0x0018
45  #define PCI_UP_BASE 0x0000
46  #define PCI_DOWN_BASE 0x0004
47  #define PCI_EJ_BASE 0x0008
48  #define PCI_RMV_BASE 0x000c
49  #define PCI_SEL_BASE 0x0010
50  #define PCI_AIDX_BASE 0x0014
51  
52  typedef struct AcpiPciHpFind {
53      int bsel;
54      PCIBus *bus;
55  } AcpiPciHpFind;
56  
57  static int acpi_pcihp_get_bsel(PCIBus *bus)
58  {
59      Error *local_err = NULL;
60      uint64_t bsel = object_property_get_uint(OBJECT(bus), ACPI_PCIHP_PROP_BSEL,
61                                               &local_err);
62  
63      if (local_err || bsel >= ACPI_PCIHP_MAX_HOTPLUG_BUS) {
64          if (local_err) {
65              error_free(local_err);
66          }
67          return -1;
68      } else {
69          return bsel;
70      }
71  }
72  
73  typedef struct {
74      unsigned bsel_alloc;
75      bool has_bridge_hotplug;
76  } BSELInfo;
77  
78  /* Assign BSEL property only to buses that support hotplug. */
79  static void *acpi_set_bsel(PCIBus *bus, void *opaque)
80  {
81      BSELInfo *info = opaque;
82      unsigned *bus_bsel;
83      DeviceState *br = bus->qbus.parent;
84      bool is_bridge = IS_PCI_BRIDGE(br);
85  
86      /* hotplugged bridges can't be described in ACPI ignore them */
87      if (qbus_is_hotpluggable(BUS(bus))) {
88          if (!is_bridge || (!br->hotplugged && info->has_bridge_hotplug)) {
89              bus_bsel = g_malloc(sizeof *bus_bsel);
90  
91              *bus_bsel = info->bsel_alloc++;
92              object_property_add_uint32_ptr(OBJECT(bus), ACPI_PCIHP_PROP_BSEL,
93                                             bus_bsel, OBJ_PROP_FLAG_READ);
94          }
95      }
96  
97      return info;
98  }
99  
100  static void acpi_set_pci_info(bool has_bridge_hotplug)
101  {
102      static bool bsel_is_set;
103      Object *host = acpi_get_i386_pci_host();
104      PCIBus *bus;
105      BSELInfo info = { .bsel_alloc = ACPI_PCIHP_BSEL_DEFAULT,
106                        .has_bridge_hotplug = has_bridge_hotplug };
107  
108      if (bsel_is_set) {
109          return;
110      }
111      bsel_is_set = true;
112  
113      if (!host) {
114          return;
115      }
116  
117      bus = PCI_HOST_BRIDGE(host)->bus;
118      if (bus) {
119          /* Scan all PCI buses. Set property to enable acpi based hotplug. */
120          pci_for_each_bus_depth_first(bus, acpi_set_bsel, NULL, &info);
121      }
122  }
123  
124  static void acpi_pcihp_test_hotplug_bus(PCIBus *bus, void *opaque)
125  {
126      AcpiPciHpFind *find = opaque;
127      if (find->bsel == acpi_pcihp_get_bsel(bus)) {
128          find->bus = bus;
129      }
130  }
131  
132  static PCIBus *acpi_pcihp_find_hotplug_bus(AcpiPciHpState *s, int bsel)
133  {
134      AcpiPciHpFind find = { .bsel = bsel, .bus = NULL };
135  
136      if (bsel < 0) {
137          return NULL;
138      }
139  
140      pci_for_each_bus(s->root, acpi_pcihp_test_hotplug_bus, &find);
141  
142      /* Make bsel 0 eject root bus if bsel property is not set,
143       * for compatibility with non acpi setups.
144       * TODO: really needed?
145       */
146      if (!bsel && !find.bus) {
147          find.bus = s->root;
148      }
149  
150      /*
151       * Check if find.bus is actually hotpluggable. If bsel is set to
152       * NULL for example on the root bus in order to make it
153       * non-hotpluggable, find.bus will match the root bus when bsel
154       * is 0. See acpi_pcihp_test_hotplug_bus() above. Since the
155       * bus is not hotpluggable however, we should not select the bus.
156       * Instead, we should set find.bus to NULL in that case. In the check
157       * below, we generalize this case for all buses, not just the root bus.
158       * The callers of this function check for a null return value and
159       * handle them appropriately.
160       */
161      if (find.bus && !qbus_is_hotpluggable(BUS(find.bus))) {
162          find.bus = NULL;
163      }
164      return find.bus;
165  }
166  
167  static bool acpi_pcihp_pc_no_hotplug(AcpiPciHpState *s, PCIDevice *dev)
168  {
169      DeviceClass *dc = DEVICE_GET_CLASS(dev);
170      /*
171       * ACPI doesn't allow hotplug of bridge devices.  Don't allow
172       * hot-unplug of bridge devices unless they were added by hotplug
173       * (and so, not described by acpi).
174       *
175       * Don't allow hot-unplug of SR-IOV Virtual Functions, as they
176       * will be removed implicitly, when Physical Function is unplugged.
177       */
178      return (IS_PCI_BRIDGE(dev) && !dev->qdev.hotplugged) || !dc->hotpluggable ||
179             pci_is_vf(dev);
180  }
181  
182  static void acpi_pcihp_eject_slot(AcpiPciHpState *s, unsigned bsel, unsigned slots)
183  {
184      HotplugHandler *hotplug_ctrl;
185      BusChild *kid, *next;
186      int slot = ctz32(slots);
187      PCIBus *bus = acpi_pcihp_find_hotplug_bus(s, bsel);
188  
189      trace_acpi_pci_eject_slot(bsel, slot);
190  
191      if (!bus || slot > 31) {
192          return;
193      }
194  
195      /* Mark request as complete */
196      s->acpi_pcihp_pci_status[bsel].down &= ~(1U << slot);
197      s->acpi_pcihp_pci_status[bsel].up &= ~(1U << slot);
198  
199      QTAILQ_FOREACH_SAFE(kid, &bus->qbus.children, sibling, next) {
200          DeviceState *qdev = kid->child;
201          PCIDevice *dev = PCI_DEVICE(qdev);
202          if (PCI_SLOT(dev->devfn) == slot) {
203              if (!acpi_pcihp_pc_no_hotplug(s, dev)) {
204                  /*
205                   * partially_hotplugged is used by virtio-net failover:
206                   * failover has asked the guest OS to unplug the device
207                   * but we need to keep some references to the device
208                   * to be able to plug it back in case of failure so
209                   * we don't execute hotplug_handler_unplug().
210                   */
211                  if (dev->partially_hotplugged) {
212                      /*
213                       * pending_deleted_event is set to true when
214                       * virtio-net failover asks to unplug the device,
215                       * and set to false here when the operation is done
216                       * This is used by the migration loop to detect the
217                       * end of the operation and really start the migration.
218                       */
219                      qdev->pending_deleted_event = false;
220                  } else {
221                      hotplug_ctrl = qdev_get_hotplug_handler(qdev);
222                      hotplug_handler_unplug(hotplug_ctrl, qdev, &error_abort);
223                      object_unparent(OBJECT(qdev));
224                  }
225              }
226          }
227      }
228  }
229  
230  static void acpi_pcihp_update_hotplug_bus(AcpiPciHpState *s, int bsel)
231  {
232      BusChild *kid, *next;
233      PCIBus *bus = acpi_pcihp_find_hotplug_bus(s, bsel);
234  
235      /* Execute any pending removes during reset */
236      while (s->acpi_pcihp_pci_status[bsel].down) {
237          acpi_pcihp_eject_slot(s, bsel, s->acpi_pcihp_pci_status[bsel].down);
238      }
239  
240      s->acpi_pcihp_pci_status[bsel].hotplug_enable = ~0;
241  
242      if (!bus) {
243          return;
244      }
245      QTAILQ_FOREACH_SAFE(kid, &bus->qbus.children, sibling, next) {
246          DeviceState *qdev = kid->child;
247          PCIDevice *pdev = PCI_DEVICE(qdev);
248          int slot = PCI_SLOT(pdev->devfn);
249  
250          if (acpi_pcihp_pc_no_hotplug(s, pdev)) {
251              s->acpi_pcihp_pci_status[bsel].hotplug_enable &= ~(1U << slot);
252          }
253      }
254  }
255  
256  static void acpi_pcihp_update(AcpiPciHpState *s)
257  {
258      int i;
259  
260      for (i = 0; i < ACPI_PCIHP_MAX_HOTPLUG_BUS; ++i) {
261          acpi_pcihp_update_hotplug_bus(s, i);
262      }
263  }
264  
265  void acpi_pcihp_reset(AcpiPciHpState *s)
266  {
267      acpi_set_pci_info(s->use_acpi_hotplug_bridge);
268      acpi_pcihp_update(s);
269  }
270  
271  void acpi_pcihp_device_pre_plug_cb(HotplugHandler *hotplug_dev,
272                                     DeviceState *dev, Error **errp)
273  {
274      PCIDevice *pdev = PCI_DEVICE(dev);
275  
276      /* Only hotplugged devices need the hotplug capability. */
277      if (dev->hotplugged &&
278          acpi_pcihp_get_bsel(pci_get_bus(pdev)) < 0) {
279          error_setg(errp, "Unsupported bus. Bus doesn't have property '"
280                     ACPI_PCIHP_PROP_BSEL "' set");
281          return;
282      }
283  }
284  
285  void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
286                                 DeviceState *dev, Error **errp)
287  {
288      PCIDevice *pdev = PCI_DEVICE(dev);
289      int slot = PCI_SLOT(pdev->devfn);
290      PCIDevice *bridge;
291      PCIBus *bus;
292      int bsel;
293  
294      /* Don't send event when device is enabled during qemu machine creation:
295       * it is present on boot, no hotplug event is necessary. We do send an
296       * event when the device is disabled later. */
297      if (!dev->hotplugged) {
298          /*
299           * Overwrite the default hotplug handler with the ACPI PCI one
300           * for cold plugged bridges only.
301           */
302          if (s->use_acpi_hotplug_bridge &&
303              object_dynamic_cast(OBJECT(dev), TYPE_PCI_BRIDGE)) {
304              PCIBus *sec = pci_bridge_get_sec_bus(PCI_BRIDGE(pdev));
305  
306              qbus_set_hotplug_handler(BUS(sec), OBJECT(hotplug_dev));
307              /* We don't have to overwrite any other hotplug handler yet */
308              assert(QLIST_EMPTY(&sec->child));
309          }
310  
311          return;
312      }
313  
314      bus = pci_get_bus(pdev);
315      bridge = pci_bridge_get_device(bus);
316      if (object_dynamic_cast(OBJECT(bridge), TYPE_PCIE_ROOT_PORT) ||
317          object_dynamic_cast(OBJECT(bridge), TYPE_XIO3130_DOWNSTREAM)) {
318          pcie_cap_slot_enable_power(bridge);
319      }
320  
321      bsel = acpi_pcihp_get_bsel(bus);
322      g_assert(bsel >= 0);
323      s->acpi_pcihp_pci_status[bsel].up |= (1U << slot);
324      acpi_send_event(DEVICE(hotplug_dev), ACPI_PCI_HOTPLUG_STATUS);
325  }
326  
327  void acpi_pcihp_device_unplug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
328                                   DeviceState *dev, Error **errp)
329  {
330      PCIDevice *pdev = PCI_DEVICE(dev);
331  
332      trace_acpi_pci_unplug(PCI_SLOT(pdev->devfn),
333                            acpi_pcihp_get_bsel(pci_get_bus(pdev)));
334  
335      qdev_unrealize(dev);
336  }
337  
338  void acpi_pcihp_device_unplug_request_cb(HotplugHandler *hotplug_dev,
339                                           AcpiPciHpState *s, DeviceState *dev,
340                                           Error **errp)
341  {
342      PCIDevice *pdev = PCI_DEVICE(dev);
343      int slot = PCI_SLOT(pdev->devfn);
344      int bsel = acpi_pcihp_get_bsel(pci_get_bus(pdev));
345  
346      trace_acpi_pci_unplug_request(bsel, slot);
347  
348      if (bsel < 0) {
349          error_setg(errp, "Unsupported bus. Bus doesn't have property '"
350                     ACPI_PCIHP_PROP_BSEL "' set");
351          return;
352      }
353  
354      /*
355       * pending_deleted_event is used by virtio-net failover to detect the
356       * end of the unplug operation, the flag is set to false in
357       * acpi_pcihp_eject_slot() when the operation is completed.
358       */
359      pdev->qdev.pending_deleted_event = true;
360      s->acpi_pcihp_pci_status[bsel].down |= (1U << slot);
361      acpi_send_event(DEVICE(hotplug_dev), ACPI_PCI_HOTPLUG_STATUS);
362  }
363  
364  bool acpi_pcihp_is_hotpluggbale_bus(AcpiPciHpState *s, BusState *bus)
365  {
366      Object *o = OBJECT(bus->parent);
367  
368      if (s->use_acpi_hotplug_bridge &&
369          object_dynamic_cast(o, TYPE_PCI_BRIDGE)) {
370          if (object_dynamic_cast(o, TYPE_PCIE_SLOT) && !PCIE_SLOT(o)->hotplug) {
371              return false;
372          }
373          return true;
374      }
375  
376      if (s->use_acpi_root_pci_hotplug) {
377          return true;
378      }
379      return false;
380  }
381  
382  static uint64_t pci_read(void *opaque, hwaddr addr, unsigned int size)
383  {
384      AcpiPciHpState *s = opaque;
385      uint32_t val = 0;
386      int bsel = s->hotplug_select;
387  
388      if (bsel < 0 || bsel >= ACPI_PCIHP_MAX_HOTPLUG_BUS) {
389          return 0;
390      }
391  
392      switch (addr) {
393      case PCI_UP_BASE:
394          val = s->acpi_pcihp_pci_status[bsel].up;
395          if (s->use_acpi_hotplug_bridge) {
396              s->acpi_pcihp_pci_status[bsel].up = 0;
397          }
398          trace_acpi_pci_up_read(val);
399          break;
400      case PCI_DOWN_BASE:
401          val = s->acpi_pcihp_pci_status[bsel].down;
402          trace_acpi_pci_down_read(val);
403          break;
404      case PCI_EJ_BASE:
405          trace_acpi_pci_features_read(val);
406          break;
407      case PCI_RMV_BASE:
408          val = s->acpi_pcihp_pci_status[bsel].hotplug_enable;
409          trace_acpi_pci_rmv_read(val);
410          break;
411      case PCI_SEL_BASE:
412          val = s->hotplug_select;
413          trace_acpi_pci_sel_read(val);
414          break;
415      case PCI_AIDX_BASE:
416          val = s->acpi_index;
417          s->acpi_index = 0;
418          trace_acpi_pci_acpi_index_read(val);
419          break;
420      default:
421          break;
422      }
423  
424      return val;
425  }
426  
427  static void pci_write(void *opaque, hwaddr addr, uint64_t data,
428                        unsigned int size)
429  {
430      int slot;
431      PCIBus *bus;
432      BusChild *kid, *next;
433      AcpiPciHpState *s = opaque;
434  
435      s->acpi_index = 0;
436      switch (addr) {
437      case PCI_AIDX_BASE:
438          /*
439           * fetch acpi-index for specified slot so that follow up read from
440           * PCI_AIDX_BASE can return it to guest
441           */
442          slot = ctz32(data);
443  
444          if (s->hotplug_select >= ACPI_PCIHP_MAX_HOTPLUG_BUS) {
445              break;
446          }
447  
448          bus = acpi_pcihp_find_hotplug_bus(s, s->hotplug_select);
449          if (!bus) {
450              break;
451          }
452          QTAILQ_FOREACH_SAFE(kid, &bus->qbus.children, sibling, next) {
453              Object *o = OBJECT(kid->child);
454              PCIDevice *dev = PCI_DEVICE(o);
455              if (PCI_SLOT(dev->devfn) == slot) {
456                  s->acpi_index = object_property_get_uint(o, "acpi-index", NULL);
457                  break;
458              }
459          }
460          trace_acpi_pci_acpi_index_write(s->hotplug_select, slot, s->acpi_index);
461          break;
462      case PCI_EJ_BASE:
463          if (s->hotplug_select >= ACPI_PCIHP_MAX_HOTPLUG_BUS) {
464              break;
465          }
466          acpi_pcihp_eject_slot(s, s->hotplug_select, data);
467          trace_acpi_pci_ej_write(addr, data);
468          break;
469      case PCI_SEL_BASE:
470          s->hotplug_select = s->use_acpi_hotplug_bridge ? data :
471              ACPI_PCIHP_BSEL_DEFAULT;
472          trace_acpi_pci_sel_write(addr, data);
473      default:
474          break;
475      }
476  }
477  
478  static const MemoryRegionOps acpi_pcihp_io_ops = {
479      .read = pci_read,
480      .write = pci_write,
481      .endianness = DEVICE_LITTLE_ENDIAN,
482      .valid = {
483          .min_access_size = 4,
484          .max_access_size = 4,
485      },
486  };
487  
488  void acpi_pcihp_init(Object *owner, AcpiPciHpState *s, PCIBus *root_bus,
489                       MemoryRegion *address_space_io,
490                       uint16_t io_base)
491  {
492      s->io_len = ACPI_PCIHP_SIZE;
493      s->io_base = io_base;
494  
495      s->root = root_bus;
496  
497      memory_region_init_io(&s->io, owner, &acpi_pcihp_io_ops, s,
498                            "acpi-pci-hotplug", s->io_len);
499      memory_region_add_subregion(address_space_io, s->io_base, &s->io);
500  
501      object_property_add_uint16_ptr(owner, ACPI_PCIHP_IO_BASE_PROP, &s->io_base,
502                                     OBJ_PROP_FLAG_READ);
503      object_property_add_uint16_ptr(owner, ACPI_PCIHP_IO_LEN_PROP, &s->io_len,
504                                     OBJ_PROP_FLAG_READ);
505  }
506  
507  const VMStateDescription vmstate_acpi_pcihp_pci_status = {
508      .name = "acpi_pcihp_pci_status",
509      .version_id = 1,
510      .minimum_version_id = 1,
511      .fields = (VMStateField[]) {
512          VMSTATE_UINT32(up, AcpiPciHpPciStatus),
513          VMSTATE_UINT32(down, AcpiPciHpPciStatus),
514          VMSTATE_END_OF_LIST()
515      }
516  };
517