From: Stefano Stabellini <sstabellini@kernel.org>
To: roger.pau@citrix.com, andrew.cooper3@citrix.com, jbeulich@suse.com
Cc: sstabellini@kernel.org, xen-devel@lists.xenproject.org,
Xenia.Ragiadakou@amd.com,
Stefano Stabellini <stefano.stabellini@amd.com>
Subject: [PATCH 2/2] xen/x86/pvh: copy ACPI tables to Dom0 instead of mapping
Date: Fri, 12 May 2023 18:17:20 -0700 [thread overview]
Message-ID: <20230513011720.3978354-2-sstabellini@kernel.org> (raw)
In-Reply-To: <alpine.DEB.2.22.394.2305121801460.3748626@ubuntu-linux-20-04-desktop>
From: Stefano Stabellini <stefano.stabellini@amd.com>
Mapping the ACPI tables to Dom0 PVH 1:1 leads to memory corruptions of
the tables in the guest. Instead, copy the tables to Dom0.
This is a workaround.
Signed-off-by: Stefano Stabellini <stefano.stabellini@amd.com>
---
As mentioned in the cover letter, this is a RFC workaround as I don't
know the cause of the underlying problem. I do know that this patch
solves what would be otherwise a hang at boot when Dom0 PVH attempts to
parse ACPI tables.
---
xen/arch/x86/hvm/dom0_build.c | 107 +++++++++-------------------------
1 file changed, 27 insertions(+), 80 deletions(-)
diff --git a/xen/arch/x86/hvm/dom0_build.c b/xen/arch/x86/hvm/dom0_build.c
index 5fde769863..a6037fc6ed 100644
--- a/xen/arch/x86/hvm/dom0_build.c
+++ b/xen/arch/x86/hvm/dom0_build.c
@@ -73,32 +73,6 @@ static void __init print_order_stats(const struct domain *d)
printk("order %2u allocations: %u\n", i, order_stats[i]);
}
-static int __init modify_identity_mmio(struct domain *d, unsigned long pfn,
- unsigned long nr_pages, const bool map)
-{
- int rc;
-
- for ( ; ; )
- {
- rc = map ? map_mmio_regions(d, _gfn(pfn), nr_pages, _mfn(pfn))
- : unmap_mmio_regions(d, _gfn(pfn), nr_pages, _mfn(pfn));
- if ( rc == 0 )
- break;
- if ( rc < 0 )
- {
- printk(XENLOG_WARNING
- "Failed to identity %smap [%#lx,%#lx) for d%d: %d\n",
- map ? "" : "un", pfn, pfn + nr_pages, d->domain_id, rc);
- break;
- }
- nr_pages -= rc;
- pfn += rc;
- process_pending_softirqs();
- }
-
- return rc;
-}
-
/* Populate a HVM memory range using the biggest possible order. */
static int __init pvh_populate_memory_range(struct domain *d,
unsigned long start,
@@ -967,6 +941,8 @@ static int __init pvh_setup_acpi_xsdt(struct domain *d, paddr_t madt_addr,
unsigned long size = sizeof(*xsdt);
unsigned int i, j, num_tables = 0;
int rc;
+ struct acpi_table_fadt fadt;
+ unsigned long fadt_addr = 0, dsdt_addr = 0, facs_addr = 0, fadt_size = 0;
struct acpi_table_header header = {
.signature = "XSDT",
.length = sizeof(struct acpi_table_header),
@@ -1013,10 +989,33 @@ static int __init pvh_setup_acpi_xsdt(struct domain *d, paddr_t madt_addr,
/* Copy the addresses of the rest of the allowed tables. */
for( i = 0, j = 1; i < acpi_gbl_root_table_list.count; i++ )
{
+ void *table;
+
+ pvh_steal_ram(d, tables[i].length, 0, GB(4), addr);
+ table = acpi_os_map_memory(tables[i].address, tables[i].length);
+ hvm_copy_to_guest_phys(*addr, table, tables[i].length, d->vcpu[0]);
+ pvh_add_mem_range(d, *addr, *addr + tables[i].length, E820_ACPI);
+
+ if ( !strncmp(tables[i].signature.ascii, ACPI_SIG_FADT, ACPI_NAME_SIZE) )
+ {
+ memcpy(&fadt, table, tables[i].length);
+ fadt_addr = *addr;
+ fadt_size = tables[i].length;
+ }
+ else if ( !strncmp(tables[i].signature.ascii, ACPI_SIG_DSDT, ACPI_NAME_SIZE) )
+ dsdt_addr = *addr;
+ else if ( !strncmp(tables[i].signature.ascii, ACPI_SIG_FACS, ACPI_NAME_SIZE) )
+ facs_addr = *addr;
+
if ( pvh_acpi_xsdt_table_allowed(tables[i].signature.ascii,
- tables[i].address, tables[i].length) )
- xsdt->table_offset_entry[j++] = tables[i].address;
+ tables[i].address, tables[i].length) )
+ xsdt->table_offset_entry[j++] = *addr;
+
+ acpi_os_unmap_memory(table, tables[i].length);
}
+ fadt.dsdt = dsdt_addr;
+ fadt.facs = facs_addr;
+ hvm_copy_to_guest_phys(fadt_addr, &fadt, fadt_size, d->vcpu[0]);
xsdt->header.revision = 1;
xsdt->header.length = size;
@@ -1055,9 +1054,7 @@ static int __init pvh_setup_acpi_xsdt(struct domain *d, paddr_t madt_addr,
static int __init pvh_setup_acpi(struct domain *d, paddr_t start_info)
{
- unsigned long pfn, nr_pages;
paddr_t madt_paddr, xsdt_paddr, rsdp_paddr;
- unsigned int i;
int rc;
struct acpi_table_rsdp *native_rsdp, rsdp = {
.signature = ACPI_SIG_RSDP,
@@ -1065,56 +1062,6 @@ static int __init pvh_setup_acpi(struct domain *d, paddr_t start_info)
.length = sizeof(rsdp),
};
-
- /* Scan top-level tables and add their regions to the guest memory map. */
- for( i = 0; i < acpi_gbl_root_table_list.count; i++ )
- {
- const char *sig = acpi_gbl_root_table_list.tables[i].signature.ascii;
- unsigned long addr = acpi_gbl_root_table_list.tables[i].address;
- unsigned long size = acpi_gbl_root_table_list.tables[i].length;
-
- /*
- * Make sure the original MADT is also mapped, so that Dom0 can
- * properly access the data returned by _MAT methods in case it's
- * re-using MADT memory.
- */
- if ( strncmp(sig, ACPI_SIG_MADT, ACPI_NAME_SIZE)
- ? pvh_acpi_table_allowed(sig, addr, size)
- : !acpi_memory_banned(addr, size) )
- pvh_add_mem_range(d, addr, addr + size, E820_ACPI);
- }
-
- /* Identity map ACPI e820 regions. */
- for ( i = 0; i < d->arch.nr_e820; i++ )
- {
- if ( d->arch.e820[i].type != E820_ACPI &&
- d->arch.e820[i].type != E820_NVS )
- continue;
-
- pfn = PFN_DOWN(d->arch.e820[i].addr);
- nr_pages = PFN_UP((d->arch.e820[i].addr & ~PAGE_MASK) +
- d->arch.e820[i].size);
-
- /* Memory below 1MB has been dealt with by pvh_populate_p2m(). */
- if ( pfn < PFN_DOWN(MB(1)) )
- {
- if ( pfn + nr_pages <= PFN_DOWN(MB(1)) )
- continue;
-
- /* This shouldn't happen, but is easy to deal with. */
- nr_pages -= PFN_DOWN(MB(1)) - pfn;
- pfn = PFN_DOWN(MB(1));
- }
-
- rc = modify_identity_mmio(d, pfn, nr_pages, true);
- if ( rc )
- {
- printk("Failed to map ACPI region [%#lx, %#lx) into Dom0 memory map\n",
- pfn, pfn + nr_pages);
- return rc;
- }
- }
-
rc = pvh_setup_acpi_madt(d, &madt_paddr);
if ( rc )
return rc;
--
2.25.1
next prev parent reply other threads:[~2023-05-13 1:17 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-05-13 1:16 [PATCH 0/2] PVH Dom0 on QEMU Stefano Stabellini
2023-05-13 1:17 ` [PATCH 1/2] xen/x86/pvh: use preset XSDT header for XSDT generation Stefano Stabellini
2023-05-15 8:48 ` Roger Pau Monné
2023-05-15 14:14 ` Jan Beulich
2023-05-16 0:16 ` Stefano Stabellini
2023-05-16 6:13 ` Jan Beulich
2023-05-16 8:10 ` Roger Pau Monné
2023-05-16 8:13 ` Roger Pau Monné
2023-05-16 8:24 ` Roger Pau Monné
2023-05-16 9:13 ` Jan Beulich
2023-05-16 9:23 ` Roger Pau Monné
2023-05-16 22:11 ` Stefano Stabellini
2023-05-17 8:42 ` Roger Pau Monné
2023-05-13 1:17 ` Stefano Stabellini [this message]
2023-05-15 9:44 ` [PATCH 2/2] xen/x86/pvh: copy ACPI tables to Dom0 instead of mapping Roger Pau Monné
2023-05-16 0:11 ` Stefano Stabellini
2023-05-16 0:38 ` Stefano Stabellini
2023-05-16 6:27 ` Jan Beulich
2023-05-16 9:21 ` Roger Pau Monné
2023-05-16 23:34 ` Stefano Stabellini
2023-05-17 8:40 ` Roger Pau Monné
2023-05-17 21:00 ` Stefano Stabellini
2023-05-18 8:34 ` Roger Pau Monné
2023-05-15 14:17 ` Jan Beulich
2023-05-16 0:12 ` Stefano Stabellini
2023-05-18 7:24 ` Xenia Ragiadakou
2023-05-18 9:31 ` Roger Pau Monné
2023-05-18 11:36 ` Xenia Ragiadakou
2023-05-18 11:44 ` Roger Pau Monné
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=20230513011720.3978354-2-sstabellini@kernel.org \
--to=sstabellini@kernel.org \
--cc=Xenia.Ragiadakou@amd.com \
--cc=andrew.cooper3@citrix.com \
--cc=jbeulich@suse.com \
--cc=roger.pau@citrix.com \
--cc=stefano.stabellini@amd.com \
--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 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.