From b3ccd965a7154fa5b766b524ad0a0f6f1330f8db Mon Sep 17 00:00:00 2001 From: Leo Fang Date: Wed, 18 Mar 2020 17:26:39 +0800 Subject: [PATCH] pcie: Add pcie-root-port deivce 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 --- ...e-root-port-fast-plug-unplug-feature.patch | 122 ++++++++++++++++++ ...-devices-which-do-not-support-Link-W.patch | 49 +++++++ qemu.spec | 8 +- 3 files changed, 178 insertions(+), 1 deletion(-) create mode 100644 pcie-Add-pcie-root-port-fast-plug-unplug-feature.patch create mode 100644 pcie-Compat-with-devices-which-do-not-support-Link-W.patch 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 00000000..bf5b144d --- /dev/null +++ b/pcie-Add-pcie-root-port-fast-plug-unplug-feature.patch @@ -0,0 +1,122 @@ +From 55c4f093b3a527c52cc8ed7138c330512973c9e6 Mon Sep 17 00:00:00 2001 +From: fangying +Date: Wed, 18 Mar 2020 12:49:33 +0800 +Subject: [PATCH 1/2] 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 +--- + hw/core/machine.c | 1 + + hw/pci-bridge/gen_pcie_root_port.c | 3 ++- + hw/pci/pcie.c | 23 +++++++++++++++++++---- + include/hw/pci/pcie_port.h | 3 ++- + 4 files changed, 24 insertions(+), 6 deletions(-) + +diff --git a/hw/core/machine.c b/hw/core/machine.c +index 2baf9ec3..3138f97b 100644 +--- a/hw/core/machine.c ++++ b/hw/core/machine.c +@@ -33,6 +33,7 @@ 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 3179c4ea..2fbb11d0 100644 +--- a/hw/pci-bridge/gen_pcie_root_port.c ++++ b/hw/pci-bridge/gen_pcie_root_port.c +@@ -131,7 +131,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, disable_lnksta_dllla, 0), ++ 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 c0d6ff13..2a8ff86d 100644 +--- a/hw/pci/pcie.c ++++ b/hw/pci/pcie.c +@@ -85,7 +85,7 @@ pcie_cap_v1_fill(PCIDevice *dev, uint8_t port, uint8_t type, uint8_t version) + * To fix this up, let's enable the PCI_EXP_LNKSTA_DLLLA + * only if it is a PCIESlot device. + */ +- if (s == NULL || s->disable_lnksta_dllla == 0) { ++ if (s == NULL || s->fast_plug == 0) { + if (dev->cap_present & QEMU_PCIE_LNKSTA_DLLLA) { + pci_word_test_and_set_mask(exp_cap + PCI_EXP_LNKSTA, + PCI_EXP_LNKSTA_DLLLA); +@@ -136,8 +136,11 @@ static void pcie_cap_fill_slot_lnk(PCIDevice *dev) + */ + pci_long_test_and_set_mask(exp_cap + PCI_EXP_LNKCAP, + PCI_EXP_LNKCAP_DLLLARC); +- pci_word_test_and_set_mask(exp_cap + PCI_EXP_LNKSTA, +- PCI_EXP_LNKSTA_DLLLA); ++ ++ if(s->fast_plug == 0) { ++ pci_word_test_and_set_mask(exp_cap + PCI_EXP_LNKSTA, ++ PCI_EXP_LNKSTA_DLLLA); ++ } + + /* + * Target Link Speed defaults to the highest link speed supported by +@@ -477,6 +480,8 @@ void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev, + Error *local_err = NULL; + PCIDevice *pci_dev = PCI_DEVICE(dev); + PCIBus *bus = pci_get_bus(pci_dev); ++ PCIESlot *s = PCIE_SLOT(PCI_DEVICE(hotplug_dev)); ++ uint8_t *exp_cap = pci_dev->config + pci_dev->exp.exp_cap; + + pcie_cap_slot_plug_common(PCI_DEVICE(hotplug_dev), dev, &local_err); + if (local_err) { +@@ -495,7 +500,17 @@ void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev, + return; + } + +- pcie_cap_slot_push_attention_button(PCI_DEVICE(hotplug_dev)); ++ if ((pci_dev->cap_present & QEMU_PCIE_LNKSTA_DLLLA) && s->fast_plug) { ++ pci_word_test_and_clear_mask(exp_cap+ PCI_EXP_LNKSTA, ++ PCI_EXP_LNKSTA_DLLLA); ++ } ++ ++ if (s->fast_unplug) { ++ pcie_cap_slot_event(PCI_DEVICE(hotplug_dev), ++ PCI_EXP_HP_EV_PDC | PCI_EXP_HP_EV_ABP); ++ } else { ++ pcie_cap_slot_push_attention_button(PCI_DEVICE(hotplug_dev)); ++ } + } + + /* 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 c3969921..b57af4ee 100644 +--- a/include/hw/pci/pcie_port.h ++++ b/include/hw/pci/pcie_port.h +@@ -50,7 +50,8 @@ struct PCIESlot { + uint8_t chassis; + uint16_t slot; + +- uint8_t disable_lnksta_dllla; ++ uint8_t fast_plug; ++ uint8_t fast_unplug; + + PCIExpLinkSpeed speed; + PCIExpLinkWidth width; +-- +2.19.1 + diff --git a/pcie-Compat-with-devices-which-do-not-support-Link-W.patch b/pcie-Compat-with-devices-which-do-not-support-Link-W.patch new file mode 100644 index 00000000..f5c26191 --- /dev/null +++ b/pcie-Compat-with-devices-which-do-not-support-Link-W.patch @@ -0,0 +1,49 @@ +From 5e1ad9f0f3c344b9fe20fc01ea2f1dfb8ac7fd67 Mon Sep 17 00:00:00 2001 +From: fangying +Date: Wed, 18 Mar 2020 12:51:33 +0800 +Subject: [PATCH 2/2] pcie: Compat with devices which do not support Link + Width, such as ioh3420 + +We hack into PCI_EXP_LNKCAP to support device fast plug/unplug +for pcie-root-port. However some devices like ioh3420 does not +suport it, so PCI_EXP_LNKCAP is not set for such devices. + +Signed-off-by: Ying Fang +--- + hw/pci/pcie.c | 13 ++++++------- + 1 file changed, 6 insertions(+), 7 deletions(-) + +diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c +index 2a8ff86d..5044bff4 100644 +--- a/hw/pci/pcie.c ++++ b/hw/pci/pcie.c +@@ -108,13 +108,6 @@ static void pcie_cap_fill_slot_lnk(PCIDevice *dev) + return; + } + +- /* Clear and fill LNKCAP from what was configured above */ +- pci_long_test_and_clear_mask(exp_cap + PCI_EXP_LNKCAP, +- PCI_EXP_LNKCAP_MLW | PCI_EXP_LNKCAP_SLS); +- pci_long_test_and_set_mask(exp_cap + PCI_EXP_LNKCAP, +- QEMU_PCI_EXP_LNKCAP_MLW(s->width) | +- QEMU_PCI_EXP_LNKCAP_MLS(s->speed)); +- + /* + * Link bandwidth notification is required for all root ports and + * downstream ports supporting links wider than x1 or multiple link +@@ -122,6 +115,12 @@ static void pcie_cap_fill_slot_lnk(PCIDevice *dev) + */ + if (s->width > QEMU_PCI_EXP_LNK_X1 || + s->speed > QEMU_PCI_EXP_LNK_2_5GT) { ++ /* Clear and fill LNKCAP from what was configured above */ ++ pci_long_test_and_clear_mask(exp_cap + PCI_EXP_LNKCAP, ++ PCI_EXP_LNKCAP_MLW | PCI_EXP_LNKCAP_SLS); ++ pci_long_test_and_set_mask(exp_cap + PCI_EXP_LNKCAP, ++ QEMU_PCI_EXP_LNKCAP_MLW(s->width) | ++ QEMU_PCI_EXP_LNKCAP_MLS(s->speed)); + pci_long_test_and_set_mask(exp_cap + PCI_EXP_LNKCAP, + PCI_EXP_LNKCAP_LBNC); + } +-- +2.19.1 + diff --git a/qemu.spec b/qemu.spec index 212c99c1..eb3cc898 100644 --- a/qemu.spec +++ b/qemu.spec @@ -59,6 +59,8 @@ Patch0046: qcow2-Limit-total-allocation-range-to-INT_MAX.patch Patch0047: mirror-Do-not-dereference-invalid-pointers.patch Patch0048: COLO-compare-Fix-incorrect-if-logic.patch Patch0049: qcow2-bitmap-Fix-uint64_t-left-shift-overflow.patch +Patch0050: pcie-Add-pcie-root-port-fast-plug-unplug-feature.patch +Patch0051: pcie-Compat-with-devices-which-do-not-support-Link-W.patch BuildRequires: flex BuildRequires: bison @@ -394,7 +396,11 @@ getent passwd qemu >/dev/null || \ %endif %changelog -* Thu Mar 17 2020 Huawei Technologies Co., Ltd. +* Wed Mar 18 2020 Huawei Technologies Co., Ltd. +- pcie: Add pcie-root-port fast plug/unplug feature +- pcie: Compat with devices which do not support Link Width + +* Tue Mar 17 2020 Huawei Technologies Co., Ltd. - Put linuxboot_dma.bin and pvh.bin in x86 package * Mon Mar 16 2020 backport some bug fix patches from upstream -- Gitee