diff --git a/pcie-Add-pcie-root-port-fast-plug-unplug-feature.patch b/pcie-Add-pcie-root-port-fast-plug-unplug-feature.patch new file mode 100644 index 0000000..7822fb9 --- /dev/null +++ b/pcie-Add-pcie-root-port-fast-plug-unplug-feature.patch @@ -0,0 +1,99 @@ +From 2412c1968777a0fe77cb24dda935e3414e00ebb1 Mon Sep 17 00:00:00 2001 +From: Yan Wang +Date: Tue, 8 Feb 2022 16:10:31 +0800 +Subject: [PATCH 5/6] pcie: Add pcie-root-port fast plug/unplug feature + +If a device is plugged in the pcie-root-port when VM kernel is +booting, the kernel may wrongly disable the device. +This bug was brought in by two patches of the linux kernel: + +https://patchwork.kernel.org/patch/10575355/ +https://patchwork.kernel.org/patch/10766219/ + +VM runtime like kata uses this feature to boot microVM, +so we must fix it up. We hack into the pcie native hotplug +patch so that hotplug/unplug will work under this circumstance. + +Signed-off-by: Ying Fang +Signed-off-by: Yan Wang +--- + hw/core/machine.c | 2 ++ + hw/pci-bridge/gen_pcie_root_port.c | 2 ++ + hw/pci/pcie.c | 13 ++++++++++++- + include/hw/pci/pcie_port.h | 3 +++ + 4 files changed, 19 insertions(+), 1 deletion(-) + +diff --git a/hw/core/machine.c b/hw/core/machine.c +index 53a99ab..126e3e2 100644 +--- a/hw/core/machine.c ++++ b/hw/core/machine.c +@@ -121,6 +121,8 @@ const size_t hw_compat_4_0_len = G_N_ELEMENTS(hw_compat_4_0); + GlobalProperty hw_compat_3_1[] = { + { "pcie-root-port", "x-speed", "2_5" }, + { "pcie-root-port", "x-width", "1" }, ++ { "pcie-root-port", "fast-plug", "0" }, ++ { "pcie-root-port", "fast-unplug", "0" }, + { "memory-backend-file", "x-use-canonical-path-for-ramblock-id", "true" }, + { "memory-backend-memfd", "x-use-canonical-path-for-ramblock-id", "true" }, + { "tpm-crb", "ppi", "false" }, +diff --git a/hw/pci-bridge/gen_pcie_root_port.c b/hw/pci-bridge/gen_pcie_root_port.c +index 20099a8..0bf9df9 100644 +--- a/hw/pci-bridge/gen_pcie_root_port.c ++++ b/hw/pci-bridge/gen_pcie_root_port.c +@@ -140,6 +140,8 @@ static Property gen_rp_props[] = { + speed, PCIE_LINK_SPEED_16), + DEFINE_PROP_PCIE_LINK_WIDTH("x-width", PCIESlot, + width, PCIE_LINK_WIDTH_32), ++ DEFINE_PROP_UINT8("fast-plug", PCIESlot, fast_plug, 0), ++ DEFINE_PROP_UINT8("fast-unplug", PCIESlot, fast_unplug, 0), + DEFINE_PROP_END_OF_LIST() + }; + +diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c +index d7d73a3..d7d1504 100644 +--- a/hw/pci/pcie.c ++++ b/hw/pci/pcie.c +@@ -526,6 +526,7 @@ void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev, + uint8_t *exp_cap = hotplug_pdev->config + hotplug_pdev->exp.exp_cap; + uint32_t sltcap = pci_get_word(exp_cap + PCI_EXP_SLTCAP); + uint16_t sltctl = pci_get_word(exp_cap + PCI_EXP_SLTCTL); ++ PCIESlot *s = PCIE_SLOT(hotplug_pdev); + + /* Check if hot-unplug is disabled on the slot */ + if ((sltcap & PCI_EXP_SLTCAP_HPC) == 0) { +@@ -572,7 +573,17 @@ void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev, + return; + } + +- pcie_cap_slot_push_attention_button(hotplug_pdev); ++ if ((pci_dev->cap_present & QEMU_PCIE_LNKSTA_DLLLA) && s->fast_plug) { ++ pci_word_test_and_clear_mask(pci_dev->config + pci_dev->exp.exp_cap + PCI_EXP_LNKSTA, ++ PCI_EXP_LNKSTA_DLLLA); ++ } ++ ++ if (s->fast_unplug) { ++ pcie_cap_slot_event(hotplug_pdev, ++ PCI_EXP_HP_EV_PDC | PCI_EXP_HP_EV_ABP); ++ } else { ++ pcie_cap_slot_push_attention_button(hotplug_pdev); ++ } + } + + /* pci express slot for pci express root/downstream port +diff --git a/include/hw/pci/pcie_port.h b/include/hw/pci/pcie_port.h +index e25b289..5b80a13 100644 +--- a/include/hw/pci/pcie_port.h ++++ b/include/hw/pci/pcie_port.h +@@ -51,6 +51,9 @@ struct PCIESlot { + uint8_t chassis; + uint16_t slot; + ++ uint8_t fast_plug; ++ uint8_t fast_unplug; ++ + PCIExpLinkSpeed speed; + PCIExpLinkWidth width; + +-- +1.9.1 +