From: Juergen Gross <jgross@suse.com>
To: linux-kernel@vger.kernel.org, x86@kernel.org
Cc: "Juergen Gross" <jgross@suse.com>,
"Boris Ostrovsky" <boris.ostrovsky@oracle.com>,
"Thomas Gleixner" <tglx@linutronix.de>,
"Ingo Molnar" <mingo@redhat.com>,
"Borislav Petkov" <bp@alien8.de>,
"Dave Hansen" <dave.hansen@linux.intel.com>,
"H. Peter Anvin" <hpa@zytor.com>,
xen-devel@lists.xenproject.org,
"Marek Marczykowski-Górecki" <marmarek@invisiblethingslab.com>
Subject: [PATCH v2 7/7] xen: tolerate ACPI NVS memory overlapping with Xen allocated memory
Date: Tue, 20 Aug 2024 10:20:12 +0200 [thread overview]
Message-ID: <20240820082012.31316-8-jgross@suse.com> (raw)
In-Reply-To: <20240820082012.31316-1-jgross@suse.com>
In order to minimize required special handling for running as Xen PV
dom0, the memory layout is modified to match that of the host. This
requires to have only RAM at the locations where Xen allocated memory
is living. Unfortunately there seem to be some machines, where ACPI
NVS is located at 64 MB, resulting in a conflict with the loaded
kernel or the initial page tables built by Xen.
As ACPI NVS needs to be accessed by the kernel only for saving and
restoring it across suspend operations, it can be relocated in the
dom0's memory map by swapping it with unused RAM (this is possible
via modification of the dom0 P2M map).
While the E820 map can (and should) be modified right away, the P2M
map can be updated only after memory allocation is working, as the P2M
map might need to be extended.
Fixes: 808fdb71936c ("xen: check for kernel memory conflicting with memory layout")
Signed-off-by: Juergen Gross <jgross@suse.com>
Tested-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
---
V2:
- remap helpers split off into other patch
---
arch/x86/xen/setup.c | 92 +++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 91 insertions(+), 1 deletion(-)
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index 88b2ebd23da3..5697f1cdd6a0 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -495,6 +495,8 @@ void __init xen_remap_memory(void)
set_pte_mfn(buf, mfn_save, PAGE_KERNEL);
pr_info("Remapped %ld page(s)\n", remapped);
+
+ xen_do_remap_nonram();
}
static unsigned long __init xen_get_pages_limit(void)
@@ -625,14 +627,102 @@ phys_addr_t __init xen_find_free_area(phys_addr_t size)
return 0;
}
+/*
+ * Swap a non-RAM E820 map entry with RAM above ini_nr_pages.
+ * Note that the E820 map is modified accordingly, but the P2M map isn't yet.
+ * The adaption of the P2M must be deferred until page allocation is possible.
+ */
+static void __init xen_e820_swap_entry_with_ram(struct e820_entry *swap_entry)
+{
+ struct e820_entry *entry;
+ unsigned int mapcnt;
+ phys_addr_t mem_end = PFN_PHYS(ini_nr_pages);
+ phys_addr_t swap_addr, swap_size, entry_end;
+
+ swap_addr = PAGE_ALIGN_DOWN(swap_entry->addr);
+ swap_size = PAGE_ALIGN(swap_entry->addr - swap_addr + swap_entry->size);
+ entry = xen_e820_table.entries;
+
+ for (mapcnt = 0; mapcnt < xen_e820_table.nr_entries; mapcnt++) {
+ entry_end = entry->addr + entry->size;
+ if (entry->type == E820_TYPE_RAM && entry->size >= swap_size &&
+ entry_end - swap_size >= mem_end) {
+ /* Reduce RAM entry by needed space (whole pages). */
+ entry->size -= swap_size;
+
+ /* Add new entry at the end of E820 map. */
+ entry = xen_e820_table.entries +
+ xen_e820_table.nr_entries;
+ xen_e820_table.nr_entries++;
+
+ /* Fill new entry (keep size and page offset). */
+ entry->type = swap_entry->type;
+ entry->addr = entry_end - swap_size +
+ swap_addr - swap_entry->addr;
+ entry->size = swap_entry->size;
+
+ /* Convert old entry to RAM, align to pages. */
+ swap_entry->type = E820_TYPE_RAM;
+ swap_entry->addr = swap_addr;
+ swap_entry->size = swap_size;
+
+ /* Remember PFN<->MFN relation for P2M update. */
+ xen_add_remap_nonram(swap_addr, entry_end - swap_size,
+ swap_size);
+
+ /* Order E820 table and merge entries. */
+ e820__update_table(&xen_e820_table);
+
+ return;
+ }
+
+ entry++;
+ }
+
+ xen_raw_console_write("No suitable area found for required E820 entry remapping action\n");
+ BUG();
+}
+
+/*
+ * Look for non-RAM memory types in a specific guest physical area and move
+ * those away if possible (ACPI NVS only for now).
+ */
+static void __init xen_e820_resolve_conflicts(phys_addr_t start,
+ phys_addr_t size)
+{
+ struct e820_entry *entry;
+ unsigned int mapcnt;
+ phys_addr_t end;
+
+ if (!size)
+ return;
+
+ end = start + size;
+ entry = xen_e820_table.entries;
+
+ for (mapcnt = 0; mapcnt < xen_e820_table.nr_entries; mapcnt++) {
+ if (entry->addr >= end)
+ return;
+
+ if (entry->addr + entry->size > start &&
+ entry->type == E820_TYPE_NVS)
+ xen_e820_swap_entry_with_ram(entry);
+
+ entry++;
+ }
+}
+
/*
* 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.
+ * An area is considered to usable if the used E820 map lists it to be RAM or
+ * some other type which can be moved to higher PFNs while keeping the MFNs.
* 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)
{
+ xen_e820_resolve_conflicts(start, size);
+
if (!xen_is_e820_reserved(start, size))
return;
--
2.43.0
next prev parent reply other threads:[~2024-08-20 8:20 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-20 8:20 [PATCH v2 0/7] xen: fix dom0 PV boot on some AMD machines Juergen Gross
2024-08-20 8:20 ` [PATCH v2 1/7] xen: use correct end address of kernel for conflict checking Juergen Gross
2024-08-20 8:29 ` Jan Beulich
2024-08-20 8:20 ` [PATCH v2 2/7] xen: introduce generic helper checking for memory map conflicts Juergen Gross
2024-08-20 8:35 ` Jan Beulich
2024-08-22 11:29 ` Jürgen Groß
2024-08-20 8:20 ` [PATCH v2 3/7] xen: move checks for e820 conflicts further up Juergen Gross
2024-08-20 8:40 ` Jan Beulich
2024-08-20 8:20 ` [PATCH v2 4/7] xen: move max_pfn in xen_memory_setup() out of function scope Juergen Gross
2024-08-20 8:44 ` Jan Beulich
2024-08-22 11:38 ` Jürgen Groß
2024-08-20 8:20 ` [PATCH v2 5/7] xen: add capability to remap non-RAM pages to different PFNs Juergen Gross
2024-08-20 9:38 ` Jan Beulich
2024-09-10 7:59 ` Jürgen Groß
2024-08-20 8:20 ` [PATCH v2 6/7] xen: allow mapping ACPI data using a different physical address Juergen Gross
2024-08-20 9:56 ` Jan Beulich
2024-09-10 8:15 ` Juergen Gross
2024-09-10 8:54 ` Jan Beulich
2024-08-20 17:37 ` kernel test robot
2024-08-20 19:39 ` kernel test robot
2024-08-20 8:20 ` Juergen Gross [this message]
2024-08-20 10:23 ` [PATCH v2 7/7] xen: tolerate ACPI NVS memory overlapping with Xen allocated memory Jan Beulich
2024-09-10 8:16 ` Jürgen Groß
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240820082012.31316-8-jgross@suse.com \
--to=jgross@suse.com \
--cc=boris.ostrovsky@oracle.com \
--cc=bp@alien8.de \
--cc=dave.hansen@linux.intel.com \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=marmarek@invisiblethingslab.com \
--cc=mingo@redhat.com \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox