[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH 4/6] acpi_piix4: Track PCI hotplug status and al
From: |
Michael S. Tsirkin |
Subject: |
Re: [Qemu-devel] [PATCH 4/6] acpi_piix4: Track PCI hotplug status and allow non-ACPI remove path |
Date: |
Sun, 11 Mar 2012 23:57:19 +0200 |
User-agent: |
Mutt/1.5.21 (2010-09-15) |
On Tue, Mar 06, 2012 at 05:14:51PM -0700, Alex Williamson wrote:
> When a guest probes a device, clear the "up" bit in the hotplug
> register. This allows us to enable a non-ACPI remove path for
> devices added, but never accessed by the guest. This is useful
> when a guest does not have ACPI PCI hotplug support to avoid losing
> devices to a guest. We also now individually track bits for "up"
> and "down" rather than clearing both on each PCI hotplug action.
>
> Signed-off-by: Alex Williamson <address@hidden>
There are two features here:
1. Fixing up/down handling
2. non ACPI removal
I think 1 is done correctly here. But 2.
seems something completely unrelated to acpi.
How about tracking access in pci core?
> ---
>
> hw/acpi_piix4.c | 58
> ++++++++++++++++++++++++++++++++++++++++++++-----------
> 1 files changed, 46 insertions(+), 12 deletions(-)
>
> diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
> index 4d88e23..7e766e5 100644
> --- a/hw/acpi_piix4.c
> +++ b/hw/acpi_piix4.c
> @@ -27,6 +27,7 @@
> #include "sysemu.h"
> #include "range.h"
> #include "ioport.h"
> +#include "pci_host.h"
>
> //#define DEBUG
>
> @@ -75,6 +76,7 @@ typedef struct PIIX4PMState {
> qemu_irq smi_irq;
> int kvm_enabled;
> Notifier machine_ready;
> + Notifier device_probe;
>
> /* for pci hotplug */
> ACPIGPE gpe;
> @@ -336,6 +338,16 @@ static void piix4_pm_machine_ready(Notifier *n, void
> *opaque)
>
> }
>
> +static void piix4_pm_device_probe(Notifier *n, void *opaque)
> +{
> + PIIX4PMState *s = container_of(n, PIIX4PMState, device_probe);
> + PCIDevice *pdev = opaque;
> +
> + if (pci_find_domain(pdev->bus) == 0 && pci_bus_num(pdev->bus) == 0) {
> + s->pci0_status.up &= ~(1U << PCI_SLOT(pdev->devfn));
> + }
Seems ugly. How about we register notifiers per bus?
> +}
> +
> static PIIX4PMState *global_piix4_pm_state; /* cpu hotadd */
>
> static int piix4_pm_initfn(PCIDevice *dev)
> @@ -383,6 +395,8 @@ static int piix4_pm_initfn(PCIDevice *dev)
> qemu_add_machine_init_done_notifier(&s->machine_ready);
> qemu_register_reset(piix4_reset, s);
> piix4_acpi_system_hot_add_init(dev->bus, s);
> + s->device_probe.notify = piix4_pm_device_probe;
> + pci_host_add_dev_probe_notifier(&s->device_probe);
>
> return 0;
> }
> @@ -502,6 +516,7 @@ static void pciej_write(void *opaque, uint32_t addr,
> uint32_t val)
> PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
> if (PCI_SLOT(dev->devfn) == slot && !pc->no_hotplug) {
> qdev_free(qdev);
> + s->pci0_status.down &= ~(1U << slot);
> }
> }
>
> @@ -594,16 +609,41 @@ void qemu_system_cpu_hot_add(int cpu, int state)
> }
> #endif
>
> -static void enable_device(PIIX4PMState *s, int slot)
> +static int enable_device(PIIX4PMState *s, int slot)
> {
> + uint32_t mask = 1U << slot;
> +
> + if ((s->pci0_status.up | s->pci0_status.down) & mask) {
> + return -1;
> + }
> +
> s->gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS;
> - s->pci0_status.up |= (1 << slot);
> + s->pci0_status.up |= mask;
> +
> + pm_update_sci(s);
> + return 0;
> }
>
> -static void disable_device(PIIX4PMState *s, int slot)
> +static int disable_device(PIIX4PMState *s, int slot)
> {
> + uint32_t mask = 1U << slot;
> +
> + if (s->pci0_status.up & mask) {
> + s->pci0_status.up &= ~mask;
> + pciej_write(s, PCI_EJ_BASE, mask);
> +
> + /* Clear GPE PCI hotplug status if nothing left pending */
> + if (!(s->pci0_status.up | s->pci0_status.down)) {
> + s->gpe.sts[0] &= ~PIIX4_PCI_HOTPLUG_STATUS;
> + }
> + return 0;
> + }
> +
> s->gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS;
> - s->pci0_status.down |= (1 << slot);
> + s->pci0_status.down |= mask;
> +
> + pm_update_sci(s);
> + return 0;
> }
>
> static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
> @@ -620,15 +660,9 @@ static int piix4_device_hotplug(DeviceState *qdev,
> PCIDevice *dev,
> return 0;
> }
>
> - s->pci0_status.up = 0;
> - s->pci0_status.down = 0;
> if (state == PCI_HOTPLUG_ENABLED) {
> - enable_device(s, slot);
> + return enable_device(s, slot);
> } else {
> - disable_device(s, slot);
> + return disable_device(s, slot);
> }
> -
> - pm_update_sci(s);
> -
> - return 0;
> }
- [Qemu-devel] [PATCH 0/6] PCI hotplug improvements, Alex Williamson, 2012/03/06
- [Qemu-devel] [PATCH 2/6] acpi_piix4: Only allow writes to PCI hotplug eject register, Alex Williamson, 2012/03/06
- [Qemu-devel] [PATCH 1/6] acpi_piix4: Disallow write to up/down PCI hotplug registers, Alex Williamson, 2012/03/06
- [Qemu-devel] [PATCH 3/6] pci: Add notifier for device probing, Alex Williamson, 2012/03/06
- [Qemu-devel] [PATCH 4/6] acpi_piix4: Track PCI hotplug status and allow non-ACPI remove path, Alex Williamson, 2012/03/06
- Re: [Qemu-devel] [PATCH 4/6] acpi_piix4: Track PCI hotplug status and allow non-ACPI remove path,
Michael S. Tsirkin <=
- [Qemu-devel] [PATCH 5/6] acpi_piix4: Use pci_get/set_byte, Alex Williamson, 2012/03/06
- [Qemu-devel] [PATCH 6/6] api_piix4: Remove PCI_RMV_BASE write code, Alex Williamson, 2012/03/06
- Re: [Qemu-devel] [PATCH 0/6] PCI hotplug improvements, Gleb Natapov, 2012/03/07
- Re: [Qemu-devel] [PATCH 0/6] PCI hotplug improvements, Alex Williamson, 2012/03/07
- Re: [Qemu-devel] [PATCH 0/6] PCI hotplug improvements, Gleb Natapov, 2012/03/07
- Re: [Qemu-devel] [PATCH 0/6] PCI hotplug improvements, Alex Williamson, 2012/03/07
- Re: [Qemu-devel] [PATCH 0/6] PCI hotplug improvements, Gleb Natapov, 2012/03/07
- Re: [Qemu-devel] [PATCH 0/6] PCI hotplug improvements, Alex Williamson, 2012/03/07
- Re: [Qemu-devel] [PATCH 0/6] PCI hotplug improvements, Gleb Natapov, 2012/03/07
- Re: [Qemu-devel] [PATCH 0/6] PCI hotplug improvements, Alex Williamson, 2012/03/07