3d7e78aa77
We introduce a new global flag 'acpi-root-pci-hotplug' for i440fx with which
we can turn on or off PCI device hotplug on the root bus. This flag can be
used to prevent all PCI devices from getting hotplugged or unplugged from the
root PCI bus.
This feature is targetted mostly towards Windows VMs. It is useful in cases
where some hypervisor admins want to deploy guest VMs in a way so that the
users of the guest OSes are not able to hot-eject certain PCI devices from
the Windows system tray. Laine has explained the use case here in detail:
https://www.redhat.com/archives/libvir-list/2020-February/msg00110.html
Julia has resolved this issue for PCIE buses with the following commit:
530a096318
("pcie_root_port: Add hotplug disabling option")
This commit attempts to introduce similar behavior for PCI root buses used in
i440fx machine types (although in this case, we do not have a per-slot
capability to turn hotplug on or off).
Usage:
-global PIIX4_PM.acpi-root-pci-hotplug=off
By default, this option is enabled which means that hotplug is turned on for
the PCI root bus.
The previously existing flag 'acpi-pci-hotplug-with-bridge-support' for PCI-PCI
bridges remain as is and can be used along with this new flag to control PCI
hotplug on PCI bridges.
This change has been tested using a Windows 2012R2 server guest image and also
with a Windows 2019 server guest image on a Ubuntu 18.04 host using the latest
master qemu from upstream.
Signed-off-by: Ani Sinha <ani@anisinha.ca>
Message-Id: <20200821165403.26589-1-ani@anisinha.ca>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Tested-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
84 lines
3.1 KiB
C
84 lines
3.1 KiB
C
/*
|
|
* QEMU<->ACPI BIOS PCI hotplug interface
|
|
*
|
|
* QEMU supports PCI hotplug via ACPI. This module
|
|
* implements the interface between QEMU and the ACPI BIOS.
|
|
* Interface specification - see docs/specs/acpi_pci_hotplug.txt
|
|
*
|
|
* Copyright (c) 2013, Red Hat Inc, Michael S. Tsirkin (mst@redhat.com)
|
|
* Copyright (c) 2006 Fabrice Bellard
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License version 2 as published by the Free Software Foundation.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, see <http://www.gnu.org/licenses/>
|
|
*
|
|
* Contributions after 2012-01-13 are licensed under the terms of the
|
|
* GNU GPL, version 2 or (at your option) any later version.
|
|
*/
|
|
|
|
#ifndef HW_ACPI_PCIHP_H
|
|
#define HW_ACPI_PCIHP_H
|
|
|
|
#include "hw/acpi/acpi.h"
|
|
#include "hw/hotplug.h"
|
|
|
|
#define ACPI_PCIHP_IO_BASE_PROP "acpi-pcihp-io-base"
|
|
#define ACPI_PCIHP_IO_LEN_PROP "acpi-pcihp-io-len"
|
|
|
|
typedef struct AcpiPciHpPciStatus {
|
|
uint32_t up;
|
|
uint32_t down;
|
|
uint32_t hotplug_enable;
|
|
} AcpiPciHpPciStatus;
|
|
|
|
#define ACPI_PCIHP_PROP_BSEL "acpi-pcihp-bsel"
|
|
#define ACPI_PCIHP_MAX_HOTPLUG_BUS 256
|
|
#define ACPI_PCIHP_BSEL_DEFAULT 0x0
|
|
|
|
typedef struct AcpiPciHpState {
|
|
AcpiPciHpPciStatus acpi_pcihp_pci_status[ACPI_PCIHP_MAX_HOTPLUG_BUS];
|
|
uint32_t hotplug_select;
|
|
PCIBus *root;
|
|
MemoryRegion io;
|
|
bool legacy_piix;
|
|
uint16_t io_base;
|
|
uint16_t io_len;
|
|
} AcpiPciHpState;
|
|
|
|
void acpi_pcihp_init(Object *owner, AcpiPciHpState *, PCIBus *root,
|
|
MemoryRegion *address_space_io, bool bridges_enabled);
|
|
|
|
void acpi_pcihp_device_pre_plug_cb(HotplugHandler *hotplug_dev,
|
|
DeviceState *dev, Error **errp);
|
|
void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
|
|
DeviceState *dev, Error **errp);
|
|
void acpi_pcihp_device_unplug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
|
|
DeviceState *dev, Error **errp);
|
|
void acpi_pcihp_device_unplug_request_cb(HotplugHandler *hotplug_dev,
|
|
AcpiPciHpState *s, DeviceState *dev,
|
|
Error **errp);
|
|
|
|
/* Called on reset */
|
|
void acpi_pcihp_reset(AcpiPciHpState *s, bool acpihp_root_off);
|
|
|
|
extern const VMStateDescription vmstate_acpi_pcihp_pci_status;
|
|
|
|
#define VMSTATE_PCI_HOTPLUG(pcihp, state, test_pcihp) \
|
|
VMSTATE_UINT32_TEST(pcihp.hotplug_select, state, \
|
|
test_pcihp), \
|
|
VMSTATE_STRUCT_ARRAY_TEST(pcihp.acpi_pcihp_pci_status, state, \
|
|
ACPI_PCIHP_MAX_HOTPLUG_BUS, \
|
|
test_pcihp, 1, \
|
|
vmstate_acpi_pcihp_pci_status, \
|
|
AcpiPciHpPciStatus)
|
|
|
|
#endif
|