All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH for-4.17] x86/pci: allow BARs to be positioned on e820 reserved regions
@ 2022-10-04 15:36 Roger Pau Monne
  2022-10-04 16:11 ` Jan Beulich
  0 siblings, 1 reply; 9+ messages in thread
From: Roger Pau Monne @ 2022-10-04 15:36 UTC (permalink / raw)
  To: xen-devel
  Cc: Roger Pau Monne, Stefano Stabellini, Julien Grall,
	Bertrand Marquis, Volodymyr Babchuk, Andrew Cooper,
	George Dunlap, Jan Beulich, Wei Liu

The EFI memory map contains two memory types (EfiMemoryMappedIO and
EfiMemoryMappedIOPortSpace) used to describe IO memory areas used by
EFI firmware.

The current parsing of the EFI memory map is translating
EfiMemoryMappedIO to E820_RESERVED on x86.  This causes issues on some
boxes as the firmware is relying on using those regions to position
the BARs of devices being used (possibly during runtime) for the
firmware.

Xen will disable memory decoding on any device that has BARs
positioned over any regions on the e820 memory map, hence the firmware
will malfunction after Xen turning off memory decoding for the
device(s) that have BARs mapped in EfiMemoryMappedIO regions.

The system under which this was observed has:

EFI memory map:
[...]
 00000fd000000-00000fe7fffff type=11 attr=800000000000100d
[...]
0000:00:1f.5 disabled: BAR [0xfe010, 0xfe010] overlaps with memory map

The device behind this BAR is:

00:1f.5 Serial bus controller [0c80]: Intel Corporation Lewisburg SPI Controller (rev 09)
	Subsystem: Super Micro Computer Inc Device 091c
	Flags: fast devsel
	Memory at fe010000 (32-bit, non-prefetchable) [size=4K]well

For the record, the symptom observed in that machine was a hard freeze
when attempting to set an EFI variable (XEN_EFI_set_variable).

Fix by allowing BARs of PCI devices to be positioned over reserved
memory regions, but print a warning message about such overlap.

Fixes: 75cc460a1b ('xen/pci: detect when BARs are not suitably positioned')
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
---
 xen/arch/arm/include/asm/pci.h |  2 --
 xen/arch/x86/include/asm/pci.h | 10 ----------
 xen/arch/x86/pci.c             | 27 +++++++++++++++++++++++++++
 xen/include/xen/pci.h          |  1 +
 4 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/xen/arch/arm/include/asm/pci.h b/xen/arch/arm/include/asm/pci.h
index 8cb46f6b71..80a2431804 100644
--- a/xen/arch/arm/include/asm/pci.h
+++ b/xen/arch/arm/include/asm/pci.h
@@ -126,8 +126,6 @@ int pci_host_iterate_bridges_and_count(struct domain *d,
 
 int pci_host_bridge_mappings(struct domain *d);
 
-bool pci_check_bar(const struct pci_dev *pdev, mfn_t start, mfn_t end);
-
 #else   /*!CONFIG_HAS_PCI*/
 
 struct arch_pci_dev { };
diff --git a/xen/arch/x86/include/asm/pci.h b/xen/arch/x86/include/asm/pci.h
index f4a58c8acf..c8e1a9ecdb 100644
--- a/xen/arch/x86/include/asm/pci.h
+++ b/xen/arch/x86/include/asm/pci.h
@@ -57,14 +57,4 @@ static always_inline bool is_pci_passthrough_enabled(void)
 
 void arch_pci_init_pdev(struct pci_dev *pdev);
 
-static inline bool pci_check_bar(const struct pci_dev *pdev,
-                                 mfn_t start, mfn_t end)
-{
-    /*
-     * Check if BAR is not overlapping with any memory region defined
-     * in the memory map.
-     */
-    return is_memory_hole(start, end);
-}
-
 #endif /* __X86_PCI_H__ */
diff --git a/xen/arch/x86/pci.c b/xen/arch/x86/pci.c
index 97b792e578..6920bf2168 100644
--- a/xen/arch/x86/pci.c
+++ b/xen/arch/x86/pci.c
@@ -98,3 +98,30 @@ int pci_conf_write_intercept(unsigned int seg, unsigned int bdf,
 
     return rc;
 }
+
+bool pci_check_bar(const struct pci_dev *pdev, mfn_t start, mfn_t end)
+{
+    unsigned long mfn;
+
+    /*
+     * Check if BAR is not overlapping with any memory region defined
+     * in the memory map.
+     */
+    if ( is_memory_hole(start, end) )
+        return true;
+
+    /*
+     * Also allow BARs placed on reserved regions in order to deal with EFI
+     * firmware using EfiMemoryMappedIO regions to place the BARs of devices
+     * that can be used during runtime.  But print a warning when doing so.
+     */
+    for ( mfn = mfn_x(start); mfn <= mfn_x(end); mfn++ )
+        if ( !page_is_ram_type(mfn, RAM_TYPE_RESERVED) )
+            return false;
+
+    printk(XENLOG_WARNING
+           "%pp: BAR [%#" PRI_mfn ", %#" PRI_mfn "] overlaps reserved region\n",
+           &pdev->sbdf, mfn_x(start), mfn_x(end));
+
+    return true;
+}
diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h
index 5975ca2f30..64995fc68d 100644
--- a/xen/include/xen/pci.h
+++ b/xen/include/xen/pci.h
@@ -211,6 +211,7 @@ unsigned int pci_size_mem_bar(pci_sbdf_t sbdf, unsigned int pos,
 
 void pci_intx(const struct pci_dev *, bool enable);
 bool_t pcie_aer_get_firmware_first(const struct pci_dev *);
+bool pci_check_bar(const struct pci_dev *pdev, mfn_t start, mfn_t end);
 
 struct pirq;
 int msixtbl_pt_register(struct domain *, struct pirq *, uint64_t gtable);
-- 
2.37.3



^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2022-10-06  9:44 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-04 15:36 [PATCH for-4.17] x86/pci: allow BARs to be positioned on e820 reserved regions Roger Pau Monne
2022-10-04 16:11 ` Jan Beulich
2022-10-05  8:37   ` Roger Pau Monné
2022-10-05  8:53     ` Jan Beulich
2022-10-05 14:12       ` Roger Pau Monné
2022-10-05 15:42         ` Jan Beulich
2022-10-06  8:48           ` Roger Pau Monné
2022-10-06  9:02             ` Jan Beulich
2022-10-06  9:43               ` Roger Pau Monné

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.