From: Igor Mammedov <imammedo@redhat.com>
To: "Michael S. Tsirkin" <mst@redhat.com>
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH 2/3] pcie: check that slt ctrl changed before deleting
Date: Mon, 1 Jul 2019 15:07:24 +0200 [thread overview]
Message-ID: <20190701150724.1fb1099c@redhat.com> (raw)
In-Reply-To: <20190621064615.20099-3-mst@redhat.com>
On Fri, 21 Jun 2019 02:46:48 -0400
"Michael S. Tsirkin" <mst@redhat.com> wrote:
> During boot, linux would sometimes overwrites control of a powered off
> slot before powering it on. Unfortunately QEMU interprets that as a
> power off request and ejects the device.
>
> For example:
>
> /x86_64-softmmu/qemu-system-x86_64 -enable-kvm -S -machine q35 \
> -device pcie-root-port,id=pcie_root_port_0,slot=2,chassis=2,addr=0x2,bus=pcie.0 \
> -monitor stdio disk.qcow2
> (qemu)device_add virtio-balloon-pci,id=balloon,bus=pcie_root_port_0
> (qemu)cont
>
> Balloon is deleted during guest boot.
>
> To fix, save control beforehand and check that power
> or led state actually change before ejecting.
>
> Note: this is more a hack than a solution, ideally we'd
> find a better way to detect ejects, or move away
> from ejects completely and instead monitor whether
> it's safe to delete device due to e.g. its power state.
>
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Tested-by: Igor Mammedov <imammedo@redhat.com>
> ---
> include/hw/pci/pcie.h | 3 ++-
> hw/pci-bridge/pcie_root_port.c | 5 ++++-
> hw/pci-bridge/xio3130_downstream.c | 5 ++++-
> hw/pci/pcie.c | 14 ++++++++++++--
> 4 files changed, 22 insertions(+), 5 deletions(-)
>
> diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h
> index e30334d74d..8d90c0e193 100644
> --- a/include/hw/pci/pcie.h
> +++ b/include/hw/pci/pcie.h
> @@ -107,7 +107,8 @@ void pcie_cap_lnkctl_reset(PCIDevice *dev);
>
> void pcie_cap_slot_init(PCIDevice *dev, uint16_t slot);
> void pcie_cap_slot_reset(PCIDevice *dev);
> -void pcie_cap_slot_write_config(PCIDevice *dev,
> +void pcie_cap_slot_get(PCIDevice *dev, uint16_t *slot_ctl, uint16_t *slt_sta);
> +void pcie_cap_slot_write_config(PCIDevice *dev, uint16_t slot_ctl, uint16_t slt_sta,
> uint32_t addr, uint32_t val, int len);
> int pcie_cap_slot_post_load(void *opaque, int version_id);
> void pcie_cap_slot_push_attention_button(PCIDevice *dev);
> diff --git a/hw/pci-bridge/pcie_root_port.c b/hw/pci-bridge/pcie_root_port.c
> index 92f253c924..09019ca05d 100644
> --- a/hw/pci-bridge/pcie_root_port.c
> +++ b/hw/pci-bridge/pcie_root_port.c
> @@ -31,10 +31,13 @@ static void rp_write_config(PCIDevice *d, uint32_t address,
> {
> uint32_t root_cmd =
> pci_get_long(d->config + d->exp.aer_cap + PCI_ERR_ROOT_COMMAND);
> + uint16_t slt_ctl, slt_sta;
> +
> + pcie_cap_slot_get(d, &slt_ctl, &slt_sta);
>
> pci_bridge_write_config(d, address, val, len);
> rp_aer_vector_update(d);
> - pcie_cap_slot_write_config(d, address, val, len);
> + pcie_cap_slot_write_config(d, slt_ctl, slt_sta, address, val, len);
> pcie_aer_write_config(d, address, val, len);
> pcie_aer_root_write_config(d, address, val, len, root_cmd);
> }
> diff --git a/hw/pci-bridge/xio3130_downstream.c b/hw/pci-bridge/xio3130_downstream.c
> index 264e37d6a6..899b0fd6c9 100644
> --- a/hw/pci-bridge/xio3130_downstream.c
> +++ b/hw/pci-bridge/xio3130_downstream.c
> @@ -41,9 +41,12 @@
> static void xio3130_downstream_write_config(PCIDevice *d, uint32_t address,
> uint32_t val, int len)
> {
> + uint16_t slt_ctl, slt_sta;
> +
> + pcie_cap_slot_get(d, &slt_sta, &slt_ctl);
> pci_bridge_write_config(d, address, val, len);
> pcie_cap_flr_write_config(d, address, val, len);
> - pcie_cap_slot_write_config(d, address, val, len);
> + pcie_cap_slot_write_config(d, slt_ctl, slt_sta, address, val, len);
> pcie_aer_write_config(d, address, val, len);
> }
>
> diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
> index b22527000d..f8490a00de 100644
> --- a/hw/pci/pcie.c
> +++ b/hw/pci/pcie.c
> @@ -594,7 +594,15 @@ void pcie_cap_slot_reset(PCIDevice *dev)
> hotplug_event_update_event_status(dev);
> }
>
> -void pcie_cap_slot_write_config(PCIDevice *dev,
> +void pcie_cap_slot_get(PCIDevice *dev, uint16_t *slt_ctl, uint16_t *slt_sta)
> +{
> + uint32_t pos = dev->exp.exp_cap;
> + uint8_t *exp_cap = dev->config + pos;
> + *slt_ctl = pci_get_word(exp_cap + PCI_EXP_SLTCTL);
> + *slt_sta = pci_get_word(exp_cap + PCI_EXP_SLTSTA);
> +}
> +
> +void pcie_cap_slot_write_config(PCIDevice *dev, uint16_t slt_ctl, uint16_t slt_sta,
> uint32_t addr, uint32_t val, int len)
> {
> uint32_t pos = dev->exp.exp_cap;
> @@ -623,7 +631,9 @@ void pcie_cap_slot_write_config(PCIDevice *dev,
> * controller is off, it is safe to detach the devices.
> */
> if ((sltsta & PCI_EXP_SLTSTA_PDS) && (val & PCI_EXP_SLTCTL_PCC) &&
> - ((val & PCI_EXP_SLTCTL_PIC_OFF) == PCI_EXP_SLTCTL_PIC_OFF)) {
> + (val & PCI_EXP_SLTCTL_PIC_OFF) == PCI_EXP_SLTCTL_PIC_OFF &&
> + (!(slt_ctl & PCI_EXP_SLTCTL_PCC) ||
> + (slt_ctl & PCI_EXP_SLTCTL_PIC_OFF) != PCI_EXP_SLTCTL_PIC_OFF)) {
> PCIBus *sec_bus = pci_bridge_get_sec_bus(PCI_BRIDGE(dev));
> pci_for_each_device(sec_bus, pci_bus_num(sec_bus),
> pcie_unplug_device, NULL);
next prev parent reply other threads:[~2019-07-01 13:19 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-06-21 6:46 [Qemu-devel] [PATCH 0/3] pcie: hotplug fixes Michael S. Tsirkin
2019-06-21 6:46 ` [Qemu-devel] [PATCH 1/3] pcie: don't skip multi-mask events Michael S. Tsirkin
2019-06-25 11:14 ` Igor Mammedov
2019-07-01 7:01 ` Marcel Apfelbaum
2019-07-01 9:56 ` Philippe Mathieu-Daudé
2019-06-21 6:46 ` [Qemu-devel] [PATCH 2/3] pcie: check that slt ctrl changed before deleting Michael S. Tsirkin
2019-06-25 12:45 ` Igor Mammedov
2019-07-01 9:23 ` Michael S. Tsirkin
2019-07-01 7:03 ` Marcel Apfelbaum
2019-07-01 13:07 ` Igor Mammedov [this message]
2019-06-21 6:46 ` [Qemu-devel] [PATCH 3/3] pcie: work around for racy guest init Michael S. Tsirkin
2019-06-25 13:07 ` Igor Mammedov
2019-07-01 9:20 ` Michael S. Tsirkin
2019-07-01 12:04 ` Igor Mammedov
2019-07-01 12:08 ` Michael S. Tsirkin
2019-07-01 7:04 ` Marcel Apfelbaum
[not found] ` <20190701105708.5d28f497@redhat.com>
2019-07-01 9:12 ` Marcel Apfelbaum
2019-07-01 9:13 ` Marcel Apfelbaum
2019-07-01 13:01 ` Igor Mammedov
2019-07-01 9:34 ` [Qemu-devel] [PATCH 4/3] pcie: minor cleanups for slot control/status Michael S. Tsirkin
2019-07-01 9:56 ` Philippe Mathieu-Daudé
2019-07-01 13:07 ` Igor Mammedov
2019-07-01 13:51 ` Christophe de Dinechin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190701150724.1fb1099c@redhat.com \
--to=imammedo@redhat.com \
--cc=mst@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.