diff mbox series

[v2,2/7] xen: introduce generic helper checking for memory map conflicts

Message ID 20240820082012.31316-3-jgross@suse.com (mailing list archive)
State Superseded
Commit ba88829706e2c5b7238638fc2b0713edf596495e
Headers show
Series xen: fix dom0 PV boot on some AMD machines | expand

Commit Message

Juergen Gross Aug. 20, 2024, 8:20 a.m. UTC
When booting as a Xen PV dom0 the memory layout of the dom0 is
modified to match that of the host, as this requires less changes in
the kernel for supporting Xen.

There are some cases, though, which are problematic, as it is the Xen
hypervisor selecting the kernel's load address plus some other data,
which might conflict with the host's memory map.

These conflicts are detected at boot time and result in a boot error.
In order to support handling at least some of these conflicts in
future, introduce a generic helper function which will later gain the
ability to adapt the memory layout when possible.

Add the missing check for the xen_start_info area.

Signed-off-by: Juergen Gross <jgross@suse.com>
Tested-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
---
 arch/x86/xen/mmu_pv.c  |  5 +----
 arch/x86/xen/setup.c   | 34 ++++++++++++++++++++++++++++------
 arch/x86/xen/xen-ops.h |  3 ++-
 3 files changed, 31 insertions(+), 11 deletions(-)

Comments

Jan Beulich Aug. 20, 2024, 8:35 a.m. UTC | #1
On 20.08.2024 10:20, Juergen Gross wrote:
> When booting as a Xen PV dom0 the memory layout of the dom0 is
> modified to match that of the host, as this requires less changes in
> the kernel for supporting Xen.
> 
> There are some cases, though, which are problematic, as it is the Xen
> hypervisor selecting the kernel's load address plus some other data,
> which might conflict with the host's memory map.
> 
> These conflicts are detected at boot time and result in a boot error.
> In order to support handling at least some of these conflicts in
> future, introduce a generic helper function which will later gain the
> ability to adapt the memory layout when possible.
> 
> Add the missing check for the xen_start_info area.
> 
> Signed-off-by: Juergen Gross <jgross@suse.com>
> Tested-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>

Reviewed-by: Jan Beulich <jbeulich@suse.com>

However, since you mention the start_info area it may be worth adding half
a sentence to the description also mentioning why the hypervisor allocated
stack page doesn't need checking. In fact this may want to extend to
initrd and phys-mach map as well, to cover everything Xen sets up on behalf
of the kernel.

Jan
Juergen Gross Aug. 22, 2024, 11:29 a.m. UTC | #2
On 20.08.24 10:35, Jan Beulich wrote:
> On 20.08.2024 10:20, Juergen Gross wrote:
>> When booting as a Xen PV dom0 the memory layout of the dom0 is
>> modified to match that of the host, as this requires less changes in
>> the kernel for supporting Xen.
>>
>> There are some cases, though, which are problematic, as it is the Xen
>> hypervisor selecting the kernel's load address plus some other data,
>> which might conflict with the host's memory map.
>>
>> These conflicts are detected at boot time and result in a boot error.
>> In order to support handling at least some of these conflicts in
>> future, introduce a generic helper function which will later gain the
>> ability to adapt the memory layout when possible.
>>
>> Add the missing check for the xen_start_info area.
>>
>> Signed-off-by: Juergen Gross <jgross@suse.com>
>> Tested-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
> 
> Reviewed-by: Jan Beulich <jbeulich@suse.com>
> 
> However, since you mention the start_info area it may be worth adding half
> a sentence to the description also mentioning why the hypervisor allocated
> stack page doesn't need checking. In fact this may want to extend to
> initrd and phys-mach map as well, to cover everything Xen sets up on behalf
> of the kernel.

Okay.


Juergen
diff mbox series

Patch

diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c
index f1ce39d6d32c..839e6613753d 100644
--- a/arch/x86/xen/mmu_pv.c
+++ b/arch/x86/xen/mmu_pv.c
@@ -2018,10 +2018,7 @@  void __init xen_reserve_special_pages(void)
 
 void __init xen_pt_check_e820(void)
 {
-	if (xen_is_e820_reserved(xen_pt_base, xen_pt_size)) {
-		xen_raw_console_write("Xen hypervisor allocated page table memory conflicts with E820 map\n");
-		BUG();
-	}
+	xen_chk_is_e820_usable(xen_pt_base, xen_pt_size, "page table");
 }
 
 static unsigned char dummy_mapping[PAGE_SIZE] __page_aligned_bss;
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index 4bcc70a71b7d..96765180514b 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -567,7 +567,7 @@  static void __init xen_ignore_unusable(void)
 	}
 }
 
-bool __init xen_is_e820_reserved(phys_addr_t start, phys_addr_t size)
+static bool __init xen_is_e820_reserved(phys_addr_t start, phys_addr_t size)
 {
 	struct e820_entry *entry;
 	unsigned mapcnt;
@@ -624,6 +624,23 @@  phys_addr_t __init xen_find_free_area(phys_addr_t size)
 	return 0;
 }
 
+/*
+ * Check for an area in physical memory to be usable for non-movable purposes.
+ * An area is considered to usable if the used E820 map lists it to be RAM.
+ * In case the area is not usable, crash the system with an error message.
+ */
+void __init xen_chk_is_e820_usable(phys_addr_t start, phys_addr_t size,
+				   const char *component)
+{
+	if (!xen_is_e820_reserved(start, size))
+		return;
+
+	xen_raw_console_write("Xen hypervisor allocated ");
+	xen_raw_console_write(component);
+	xen_raw_console_write(" memory conflicts with E820 map\n");
+	BUG();
+}
+
 /*
  * Like memcpy, but with physical addresses for dest and src.
  */
@@ -824,11 +841,16 @@  char * __init xen_memory_setup(void)
 	 * Failing now is better than running into weird problems later due
 	 * to relocating (and even reusing) pages with kernel text or data.
 	 */
-	if (xen_is_e820_reserved(__pa_symbol(_text),
-				 __pa_symbol(_end) - __pa_symbol(_text))) {
-		xen_raw_console_write("Xen hypervisor allocated kernel memory conflicts with E820 map\n");
-		BUG();
-	}
+	xen_chk_is_e820_usable(__pa_symbol(_text),
+			       __pa_symbol(_end) - __pa_symbol(_text),
+			       "kernel");
+
+	/*
+	 * Check for a conflict of the xen_start_info memory with the target
+	 * E820 map.
+	 */
+	xen_chk_is_e820_usable(__pa(xen_start_info), sizeof(*xen_start_info),
+			       "xen_start_info");
 
 	/*
 	 * Check for a conflict of the hypervisor supplied page tables with
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
index 0cf16fc79e0b..9a27d1d653d3 100644
--- a/arch/x86/xen/xen-ops.h
+++ b/arch/x86/xen/xen-ops.h
@@ -48,7 +48,8 @@  void xen_mm_unpin_all(void);
 void __init xen_relocate_p2m(void);
 #endif
 
-bool __init xen_is_e820_reserved(phys_addr_t start, phys_addr_t size);
+void __init xen_chk_is_e820_usable(phys_addr_t start, phys_addr_t size,
+				   const char *component);
 unsigned long __ref xen_chk_extra_mem(unsigned long pfn);
 void __init xen_inv_extra_mem(void);
 void __init xen_remap_memory(void);