diff mbox series

pcie_root_port: Add disable_hotplug option

Message ID 20200218161717.386723-1-jusual@redhat.com (mailing list archive)
State New, archived
Headers show
Series pcie_root_port: Add disable_hotplug option | expand

Commit Message

Julia Suvorova Feb. 18, 2020, 4:17 p.m. UTC
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(-)

Comments

Igor Mammedov Feb. 18, 2020, 5:15 p.m. UTC | #1
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;
>  };
>
Laine Stump Feb. 18, 2020, 5:18 p.m. UTC | #2
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"?
Ján Tomko Feb. 18, 2020, 5:24 p.m. UTC | #3
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
Julia Suvorova Feb. 18, 2020, 6:40 p.m. UTC | #4
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.
Laine Stump Feb. 19, 2020, 3:02 a.m. UTC | #5
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.
Michael S. Tsirkin Feb. 19, 2020, 3:47 a.m. UTC | #6
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?
Julia Suvorova Feb. 19, 2020, 12:21 p.m. UTC | #7
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.
Daniel P. Berrangé Feb. 21, 2020, 12:03 p.m. UTC | #8
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
Michael S. Tsirkin Feb. 21, 2020, 3:45 p.m. UTC | #9
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.
diff mbox series

Patch

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;
 };