[PATCH] pcie_root_port: Add disable_hotplug option

Julia Suvorova posted 1 patch 5 years, 8 months ago
Test docker-quick@centos7 passed
Test FreeBSD passed
Test docker-mingw@fedora passed
Test checkpatch passed
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20200218161717.386723-1-jusual@redhat.com
Maintainers: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>, Eduardo Habkost <ehabkost@redhat.com>, "Michael S. Tsirkin" <mst@redhat.com>
hw/core/machine.c                  | 1 +
hw/pci-bridge/pcie_root_port.c     | 3 ++-
hw/pci-bridge/xio3130_downstream.c | 2 +-
hw/pci/pcie.c                      | 8 ++++++--
include/hw/pci/pcie.h              | 2 +-
include/hw/pci/pcie_port.h         | 1 +
6 files changed, 12 insertions(+), 5 deletions(-)
[PATCH] pcie_root_port: Add disable_hotplug option
Posted by Julia Suvorova 5 years, 8 months ago
Make hot-plug/hot-unplug on PCIe Root Ports optional to allow libvirt
to manage it and restrict unplug for the entire machine. This is going
to prevent user-initiated unplug in guests (Windows mostly).
Usage:
    -device pcie-root-port,disable-hotplug=true,...

Discussion related:
    https://lists.gnu.org/archive/html/qemu-devel/2020-02/msg00530.html

Signed-off-by: Julia Suvorova <jusual@redhat.com>
---
 hw/core/machine.c                  | 1 +
 hw/pci-bridge/pcie_root_port.c     | 3 ++-
 hw/pci-bridge/xio3130_downstream.c | 2 +-
 hw/pci/pcie.c                      | 8 ++++++--
 include/hw/pci/pcie.h              | 2 +-
 include/hw/pci/pcie_port.h         | 1 +
 6 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index 84812a1d1c..5ff698ac3c 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -36,6 +36,7 @@ GlobalProperty hw_compat_4_2[] = {
     { "usb-redir", "suppress-remote-wake", "off" },
     { "qxl", "revision", "4" },
     { "qxl-vga", "revision", "4" },
+    { "pcie-root-port-base", "disable-hotplug", "false" },
 };
 const size_t hw_compat_4_2_len = G_N_ELEMENTS(hw_compat_4_2);
 
diff --git a/hw/pci-bridge/pcie_root_port.c b/hw/pci-bridge/pcie_root_port.c
index 0ba4e4dea4..d6a080bee8 100644
--- a/hw/pci-bridge/pcie_root_port.c
+++ b/hw/pci-bridge/pcie_root_port.c
@@ -94,7 +94,7 @@ static void rp_realize(PCIDevice *d, Error **errp)
 
     pcie_cap_arifwd_init(d);
     pcie_cap_deverr_init(d);
-    pcie_cap_slot_init(d, s->slot);
+    pcie_cap_slot_init(d, s);
     pcie_cap_root_init(d);
 
     pcie_chassis_create(s->chassis);
@@ -147,6 +147,7 @@ static Property rp_props[] = {
     DEFINE_PROP_BIT(COMPAT_PROP_PCP, PCIDevice, cap_present,
                     QEMU_PCIE_SLTCAP_PCP_BITNR, true),
     DEFINE_PROP_BOOL("disable-acs", PCIESlot, disable_acs, false),
+    DEFINE_PROP_BOOL("disable-hotplug", PCIESlot, disable_hotplug, false),
     DEFINE_PROP_END_OF_LIST()
 };
 
diff --git a/hw/pci-bridge/xio3130_downstream.c b/hw/pci-bridge/xio3130_downstream.c
index 153a4acad2..04aae72cd6 100644
--- a/hw/pci-bridge/xio3130_downstream.c
+++ b/hw/pci-bridge/xio3130_downstream.c
@@ -94,7 +94,7 @@ static void xio3130_downstream_realize(PCIDevice *d, Error **errp)
     }
     pcie_cap_flr_init(d);
     pcie_cap_deverr_init(d);
-    pcie_cap_slot_init(d, s->slot);
+    pcie_cap_slot_init(d, s);
     pcie_cap_arifwd_init(d);
 
     pcie_chassis_create(s->chassis);
diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 08718188bb..6dd9b89e21 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -495,7 +495,7 @@ void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev,
 
 /* pci express slot for pci express root/downstream port
    PCI express capability slot registers */
-void pcie_cap_slot_init(PCIDevice *dev, uint16_t slot)
+void pcie_cap_slot_init(PCIDevice *dev, PCIESlot *s)
 {
     uint32_t pos = dev->exp.exp_cap;
 
@@ -505,13 +505,17 @@ void pcie_cap_slot_init(PCIDevice *dev, uint16_t slot)
     pci_long_test_and_clear_mask(dev->config + pos + PCI_EXP_SLTCAP,
                                  ~PCI_EXP_SLTCAP_PSN);
     pci_long_test_and_set_mask(dev->config + pos + PCI_EXP_SLTCAP,
-                               (slot << PCI_EXP_SLTCAP_PSN_SHIFT) |
+                               (s->slot << PCI_EXP_SLTCAP_PSN_SHIFT) |
                                PCI_EXP_SLTCAP_EIP |
                                PCI_EXP_SLTCAP_HPS |
                                PCI_EXP_SLTCAP_HPC |
                                PCI_EXP_SLTCAP_PIP |
                                PCI_EXP_SLTCAP_AIP |
                                PCI_EXP_SLTCAP_ABP);
+    if (s->disable_hotplug) {
+        pci_long_test_and_clear_mask(dev->config + pos + PCI_EXP_SLTCAP,
+                                     PCI_EXP_SLTCAP_HPC);
+    }
 
     if (dev->cap_present & QEMU_PCIE_SLTCAP_PCP) {
         pci_long_test_and_set_mask(dev->config + pos + PCI_EXP_SLTCAP,
diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h
index 7064875835..14c58ebdb6 100644
--- a/include/hw/pci/pcie.h
+++ b/include/hw/pci/pcie.h
@@ -104,7 +104,7 @@ void pcie_cap_deverr_reset(PCIDevice *dev);
 void pcie_cap_lnkctl_init(PCIDevice *dev);
 void pcie_cap_lnkctl_reset(PCIDevice *dev);
 
-void pcie_cap_slot_init(PCIDevice *dev, uint16_t slot);
+void pcie_cap_slot_init(PCIDevice *dev, PCIESlot *s);
 void pcie_cap_slot_reset(PCIDevice *dev);
 void pcie_cap_slot_get(PCIDevice *dev, uint16_t *slt_ctl, uint16_t *slt_sta);
 void pcie_cap_slot_write_config(PCIDevice *dev,
diff --git a/include/hw/pci/pcie_port.h b/include/hw/pci/pcie_port.h
index 4b3d254b08..796fc8f3ab 100644
--- a/include/hw/pci/pcie_port.h
+++ b/include/hw/pci/pcie_port.h
@@ -55,6 +55,7 @@ struct PCIESlot {
 
     /* Disable ACS (really for a pcie_root_port) */
     bool        disable_acs;
+    bool        disable_hotplug;
     QLIST_ENTRY(PCIESlot) next;
 };
 
-- 
2.24.1


Re: [PATCH] pcie_root_port: Add disable_hotplug option
Posted by Ján Tomko 5 years, 8 months ago
On Tue, Feb 18, 2020 at 05:17:17PM +0100, Julia Suvorova wrote:
>Make hot-plug/hot-unplug on PCIe Root Ports optional to allow libvirt
>to manage it and restrict unplug for the entire machine. This is going
>to prevent user-initiated unplug in guests (Windows mostly).
>Usage:
>    -device pcie-root-port,disable-hotplug=true,...
>
>Discussion related:
>    https://lists.gnu.org/archive/html/qemu-devel/2020-02/msg00530.html
>
>Signed-off-by: Julia Suvorova <jusual@redhat.com>
>---
> hw/core/machine.c                  | 1 +
> hw/pci-bridge/pcie_root_port.c     | 3 ++-
> hw/pci-bridge/xio3130_downstream.c | 2 +-
> hw/pci/pcie.c                      | 8 ++++++--
> include/hw/pci/pcie.h              | 2 +-
> include/hw/pci/pcie_port.h         | 1 +
> 6 files changed, 12 insertions(+), 5 deletions(-)
>
>diff --git a/hw/core/machine.c b/hw/core/machine.c
>index 84812a1d1c..5ff698ac3c 100644
>--- a/hw/core/machine.c
>+++ b/hw/core/machine.c
>@@ -36,6 +36,7 @@ GlobalProperty hw_compat_4_2[] = {
>     { "usb-redir", "suppress-remote-wake", "off" },
>     { "qxl", "revision", "4" },
>     { "qxl-vga", "revision", "4" },
>+    { "pcie-root-port-base", "disable-hotplug", "false" },
> };
> const size_t hw_compat_4_2_len = G_N_ELEMENTS(hw_compat_4_2);
>
>diff --git a/hw/pci-bridge/pcie_root_port.c b/hw/pci-bridge/pcie_root_port.c
>index 0ba4e4dea4..d6a080bee8 100644
>--- a/hw/pci-bridge/pcie_root_port.c
>+++ b/hw/pci-bridge/pcie_root_port.c
>@@ -94,7 +94,7 @@ static void rp_realize(PCIDevice *d, Error **errp)
>
>     pcie_cap_arifwd_init(d);
>     pcie_cap_deverr_init(d);
>-    pcie_cap_slot_init(d, s->slot);
>+    pcie_cap_slot_init(d, s);
>     pcie_cap_root_init(d);
>
>     pcie_chassis_create(s->chassis);
>@@ -147,6 +147,7 @@ static Property rp_props[] = {
>     DEFINE_PROP_BIT(COMPAT_PROP_PCP, PCIDevice, cap_present,
>                     QEMU_PCIE_SLTCAP_PCP_BITNR, true),
>     DEFINE_PROP_BOOL("disable-acs", PCIESlot, disable_acs, false),
>+    DEFINE_PROP_BOOL("disable-hotplug", PCIESlot, disable_hotplug, false),
>     DEFINE_PROP_END_OF_LIST()
> };
>
>diff --git a/hw/pci-bridge/xio3130_downstream.c b/hw/pci-bridge/xio3130_downstream.c
>index 153a4acad2..04aae72cd6 100644
>--- a/hw/pci-bridge/xio3130_downstream.c
>+++ b/hw/pci-bridge/xio3130_downstream.c
>@@ -94,7 +94,7 @@ static void xio3130_downstream_realize(PCIDevice *d, Error **errp)
>     }
>     pcie_cap_flr_init(d);
>     pcie_cap_deverr_init(d);
>-    pcie_cap_slot_init(d, s->slot);
>+    pcie_cap_slot_init(d, s);
>     pcie_cap_arifwd_init(d);
>

The corresponding entry in xio3130_downstream_props[] is missing.

>     pcie_chassis_create(s->chassis);

Jano
Re: [PATCH] pcie_root_port: Add disable_hotplug option
Posted by Laine Stump 5 years, 8 months ago
On 2/18/20 11:17 AM, Julia Suvorova wrote:
> Make hot-plug/hot-unplug on PCIe Root Ports optional to allow libvirt
> to manage it and restrict unplug for the entire machine. This is going
> to prevent user-initiated unplug in guests (Windows mostly).
> Usage:
>      -device pcie-root-port,disable-hotplug=true,...

Double negatives (e.g. "disable-hotplug=false") tend to confuse simple 
minds like mine. Would it be any more difficult to make the name of the 
option positive instead (e.g. "enable-hotplug") with the default set to 
"true"?


Re: [PATCH] pcie_root_port: Add disable_hotplug option
Posted by Daniel P. Berrangé 5 years, 8 months ago
On Tue, Feb 18, 2020 at 12:18:04PM -0500, Laine Stump wrote:
> On 2/18/20 11:17 AM, Julia Suvorova wrote:
> > Make hot-plug/hot-unplug on PCIe Root Ports optional to allow libvirt
> > to manage it and restrict unplug for the entire machine. This is going
> > to prevent user-initiated unplug in guests (Windows mostly).
> > Usage:
> >      -device pcie-root-port,disable-hotplug=true,...
> 
> Double negatives (e.g. "disable-hotplug=false") tend to confuse simple minds
> like mine. Would it be any more difficult to make the name of the option
> positive instead (e.g. "enable-hotplug") with the default set to "true"?

Or simply  "hotpluggable=on|off"


Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|


Re: [PATCH] pcie_root_port: Add disable_hotplug option
Posted by Julia Suvorova 5 years, 8 months ago
On Tue, Feb 18, 2020 at 6:18 PM Laine Stump <laine@redhat.com> wrote:
>
> On 2/18/20 11:17 AM, Julia Suvorova wrote:
> > Make hot-plug/hot-unplug on PCIe Root Ports optional to allow libvirt
> > to manage it and restrict unplug for the entire machine. This is going
> > to prevent user-initiated unplug in guests (Windows mostly).
> > Usage:
> >      -device pcie-root-port,disable-hotplug=true,...
>
> Double negatives (e.g. "disable-hotplug=false") tend to confuse simple
> minds like mine. Would it be any more difficult to make the name of the
> option positive instead (e.g. "enable-hotplug") with the default set to
> "true"?

disable-hotplug=false will not be used, because it's default. And it
follows previous naming (''disable-acs').

Best regards, Julia Suvorova.


Re: [PATCH] pcie_root_port: Add disable_hotplug option
Posted by Laine Stump 5 years, 8 months ago
On 2/18/20 1:40 PM, Julia Suvorova wrote:
> On Tue, Feb 18, 2020 at 6:18 PM Laine Stump <laine@redhat.com> wrote:
>>
>> On 2/18/20 11:17 AM, Julia Suvorova wrote:
>>> Make hot-plug/hot-unplug on PCIe Root Ports optional to allow libvirt
>>> to manage it and restrict unplug for the entire machine. This is going
>>> to prevent user-initiated unplug in guests (Windows mostly).
>>> Usage:
>>>       -device pcie-root-port,disable-hotplug=true,...
>>
>> Double negatives (e.g. "disable-hotplug=false") tend to confuse simple
>> minds like mine. Would it be any more difficult to make the name of the
>> option positive instead (e.g. "enable-hotplug") with the default set to
>> "true"?
> 
> disable-hotplug=false will not be used, because it's default. And it
> follows previous naming (''disable-acs').

Yeah, I don't like the name of that one either (or of "disable-modern" 
or "disable-legacy") but I don't follow qemu-devel closely so I didn't 
see them when their patches went by. But now is my chance to complain :-)

I can live with it either way, but still think it's much better to not 
have "negative" option names. Feel free to ignore, and I'll just be 
happy that I didn't accept it silently.

Also, is there a rhyme/reason for some options having true/false, and 
some being off/on? disable-acs seems to be true/false, but 
disable-modern is on/off. Doesn't make any difference to me in the end, 
but just thought I'd bring it up in case there might be a reason to use 
on/off instead of true/false for this one.


Re: [PATCH] pcie_root_port: Add disable_hotplug option
Posted by Michael S. Tsirkin 5 years, 8 months ago
On Tue, Feb 18, 2020 at 10:02:19PM -0500, Laine Stump wrote:
> Also, is there a rhyme/reason for some options having true/false, and some
> being off/on? disable-acs seems to be true/false, but disable-modern is
> on/off. Doesn't make any difference to me in the end, but just thought I'd
> bring it up in case there might be a reason to use on/off instead of
> true/false for this one.

Some places accept on/off, some true/false, some on/off/true/false
others on/off/yes/no and others on/off/true/false/yes/no.

In this case both user visitor machinery. Which I *think*
means on/off is the safe choice and true/false can be
broken in some places.

We really should clean up this mess ... Julia, what do you think?
Let's make them all support all options?


-- 
MST


Re: [PATCH] pcie_root_port: Add disable_hotplug option
Posted by Julia Suvorova 5 years, 8 months ago
On Wed, Feb 19, 2020 at 4:47 AM Michael S. Tsirkin <mst@redhat.com> wrote:
>
> On Tue, Feb 18, 2020 at 10:02:19PM -0500, Laine Stump wrote:
> > Also, is there a rhyme/reason for some options having true/false, and some
> > being off/on? disable-acs seems to be true/false, but disable-modern is
> > on/off. Doesn't make any difference to me in the end, but just thought I'd
> > bring it up in case there might be a reason to use on/off instead of
> > true/false for this one.
>
> Some places accept on/off, some true/false, some on/off/true/false
> others on/off/yes/no and others on/off/true/false/yes/no.
>
> In this case both user visitor machinery. Which I *think*
> means on/off is the safe choice and true/false can be
> broken in some places.
>
> We really should clean up this mess ... Julia, what do you think?
> Let's make them all support all options?

Options already support all of on/off/true/false/yes/no as long as
they are defined as boolean (look at parse_type_bool()). That is, you
can use disable-modern with yes/no/true/false too.
The only problem is with types OnOffSplit and OnOffAuto (as in disable-legacy).

Best regards, Julia Suvorova.


Re: [PATCH] pcie_root_port: Add disable_hotplug option
Posted by Michael S. Tsirkin 5 years, 8 months ago
On Wed, Feb 19, 2020 at 01:21:10PM +0100, Julia Suvorova wrote:
> On Wed, Feb 19, 2020 at 4:47 AM Michael S. Tsirkin <mst@redhat.com> wrote:
> >
> > On Tue, Feb 18, 2020 at 10:02:19PM -0500, Laine Stump wrote:
> > > Also, is there a rhyme/reason for some options having true/false, and some
> > > being off/on? disable-acs seems to be true/false, but disable-modern is
> > > on/off. Doesn't make any difference to me in the end, but just thought I'd
> > > bring it up in case there might be a reason to use on/off instead of
> > > true/false for this one.
> >
> > Some places accept on/off, some true/false, some on/off/true/false
> > others on/off/yes/no and others on/off/true/false/yes/no.
> >
> > In this case both user visitor machinery. Which I *think*
> > means on/off is the safe choice and true/false can be
> > broken in some places.
> >
> > We really should clean up this mess ... Julia, what do you think?
> > Let's make them all support all options?
> 
> Options already support all of on/off/true/false/yes/no as long as
> they are defined as boolean (look at parse_type_bool()). That is, you
> can use disable-modern with yes/no/true/false too.
> The only problem is with types OnOffSplit and OnOffAuto (as in disable-legacy).

Right. Not only that though - parse_option_bool can only handle
on/off. target/sparc/cpu.c can handle on/off and true/false.
JSON bool is only true/false.
As you said OnOffSplit and OnOffAuto are on/off.

And from documentation POV, it's all over the place.



-- 
MST


Re: [PATCH] pcie_root_port: Add disable_hotplug option
Posted by Igor Mammedov 5 years, 8 months ago
On Tue, 18 Feb 2020 17:17:17 +0100
Julia Suvorova <jusual@redhat.com> wrote:

> Make hot-plug/hot-unplug on PCIe Root Ports optional to allow libvirt
> to manage it and restrict unplug for the entire machine. This is going
> to prevent user-initiated unplug in guests (Windows mostly).
> Usage:
>     -device pcie-root-port,disable-hotplug=true,...
> 
> Discussion related:
>     https://lists.gnu.org/archive/html/qemu-devel/2020-02/msg00530.html
> 
> Signed-off-by: Julia Suvorova <jusual@redhat.com>
> ---
>  hw/core/machine.c                  | 1 +
>  hw/pci-bridge/pcie_root_port.c     | 3 ++-
>  hw/pci-bridge/xio3130_downstream.c | 2 +-
>  hw/pci/pcie.c                      | 8 ++++++--
>  include/hw/pci/pcie.h              | 2 +-
>  include/hw/pci/pcie_port.h         | 1 +
>  6 files changed, 12 insertions(+), 5 deletions(-)
> 
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index 84812a1d1c..5ff698ac3c 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -36,6 +36,7 @@ GlobalProperty hw_compat_4_2[] = {
>      { "usb-redir", "suppress-remote-wake", "off" },
>      { "qxl", "revision", "4" },
>      { "qxl-vga", "revision", "4" },
> +    { "pcie-root-port-base", "disable-hotplug", "false" },
this looks unnecessary as the property is 'off' by default

>  };
>  const size_t hw_compat_4_2_len = G_N_ELEMENTS(hw_compat_4_2);
>  
> diff --git a/hw/pci-bridge/pcie_root_port.c b/hw/pci-bridge/pcie_root_port.c
> index 0ba4e4dea4..d6a080bee8 100644
> --- a/hw/pci-bridge/pcie_root_port.c
> +++ b/hw/pci-bridge/pcie_root_port.c
> @@ -94,7 +94,7 @@ static void rp_realize(PCIDevice *d, Error **errp)
>  
>      pcie_cap_arifwd_init(d);
>      pcie_cap_deverr_init(d);
> -    pcie_cap_slot_init(d, s->slot);
> +    pcie_cap_slot_init(d, s);
>      pcie_cap_root_init(d);
>  
>      pcie_chassis_create(s->chassis);
> @@ -147,6 +147,7 @@ static Property rp_props[] = {
>      DEFINE_PROP_BIT(COMPAT_PROP_PCP, PCIDevice, cap_present,
>                      QEMU_PCIE_SLTCAP_PCP_BITNR, true),
>      DEFINE_PROP_BOOL("disable-acs", PCIESlot, disable_acs, false),
> +    DEFINE_PROP_BOOL("disable-hotplug", PCIESlot, disable_hotplug, false),
>      DEFINE_PROP_END_OF_LIST()
>  };
>  
> diff --git a/hw/pci-bridge/xio3130_downstream.c b/hw/pci-bridge/xio3130_downstream.c
> index 153a4acad2..04aae72cd6 100644
> --- a/hw/pci-bridge/xio3130_downstream.c
> +++ b/hw/pci-bridge/xio3130_downstream.c
> @@ -94,7 +94,7 @@ static void xio3130_downstream_realize(PCIDevice *d, Error **errp)
>      }
>      pcie_cap_flr_init(d);
>      pcie_cap_deverr_init(d);
> -    pcie_cap_slot_init(d, s->slot);
> +    pcie_cap_slot_init(d, s);
>      pcie_cap_arifwd_init(d);
>  
>      pcie_chassis_create(s->chassis);
> diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
> index 08718188bb..6dd9b89e21 100644
> --- a/hw/pci/pcie.c
> +++ b/hw/pci/pcie.c
> @@ -495,7 +495,7 @@ void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev,
>  
>  /* pci express slot for pci express root/downstream port
>     PCI express capability slot registers */
> -void pcie_cap_slot_init(PCIDevice *dev, uint16_t slot)
> +void pcie_cap_slot_init(PCIDevice *dev, PCIESlot *s)
>  {
>      uint32_t pos = dev->exp.exp_cap;
>  
> @@ -505,13 +505,17 @@ void pcie_cap_slot_init(PCIDevice *dev, uint16_t slot)
>      pci_long_test_and_clear_mask(dev->config + pos + PCI_EXP_SLTCAP,
>                                   ~PCI_EXP_SLTCAP_PSN);
>      pci_long_test_and_set_mask(dev->config + pos + PCI_EXP_SLTCAP,
> -                               (slot << PCI_EXP_SLTCAP_PSN_SHIFT) |
> +                               (s->slot << PCI_EXP_SLTCAP_PSN_SHIFT) |
>                                 PCI_EXP_SLTCAP_EIP |
>                                 PCI_EXP_SLTCAP_HPS |
>                                 PCI_EXP_SLTCAP_HPC |

why not to set it to begin with instead of clearing it later as afterthought?

Also only _HPC but _HPS is left, wouldn't it confuse guests?

>                                 PCI_EXP_SLTCAP_PIP |
>                                 PCI_EXP_SLTCAP_AIP |
>                                 PCI_EXP_SLTCAP_ABP);
> +    if (s->disable_hotplug) {
> +        pci_long_test_and_clear_mask(dev->config + pos + PCI_EXP_SLTCAP,
> +                                     PCI_EXP_SLTCAP_HPC);

> +    }
>  
>      if (dev->cap_present & QEMU_PCIE_SLTCAP_PCP) {
>          pci_long_test_and_set_mask(dev->config + pos + PCI_EXP_SLTCAP,
> diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h
> index 7064875835..14c58ebdb6 100644
> --- a/include/hw/pci/pcie.h
> +++ b/include/hw/pci/pcie.h
> @@ -104,7 +104,7 @@ void pcie_cap_deverr_reset(PCIDevice *dev);
>  void pcie_cap_lnkctl_init(PCIDevice *dev);
>  void pcie_cap_lnkctl_reset(PCIDevice *dev);
>  
> -void pcie_cap_slot_init(PCIDevice *dev, uint16_t slot);
> +void pcie_cap_slot_init(PCIDevice *dev, PCIESlot *s);
>  void pcie_cap_slot_reset(PCIDevice *dev);
>  void pcie_cap_slot_get(PCIDevice *dev, uint16_t *slt_ctl, uint16_t *slt_sta);
>  void pcie_cap_slot_write_config(PCIDevice *dev,
> diff --git a/include/hw/pci/pcie_port.h b/include/hw/pci/pcie_port.h
> index 4b3d254b08..796fc8f3ab 100644
> --- a/include/hw/pci/pcie_port.h
> +++ b/include/hw/pci/pcie_port.h
> @@ -55,6 +55,7 @@ struct PCIESlot {
>  
>      /* Disable ACS (really for a pcie_root_port) */
>      bool        disable_acs;
> +    bool        disable_hotplug;
>      QLIST_ENTRY(PCIESlot) next;
>  };
>