When running as a Xen PV dom0 the system needs to map ACPI data of the
host using host physical addresses, while those addresses can conflict
with the guest physical addresses of the loaded linux kernel.
This conflict can be solved by mapping the ACPI data to a different
guest physical address, but mapping the data via acpi_os_ioremap()
must still be possible using the host physical address, as this
address might be generated by AML when referencing some of the ACPI
data.
When configured to support running as a Xen PV dom0, have an
implementation of acpi_os_ioremap() being aware of the possibility to
need above mentioned translation of a host physical address to the
guest physical address.
This modification requires to fix some #include of asm/acpi.h in x86
code to use linux/acpi.h instead.
Signed-off-by: Juergen Gross <jgross@suse.com>
---
V2:
- new patch (Jan Beulich)
---
arch/x86/include/asm/acpi.h | 8 ++++++++
arch/x86/kernel/acpi/boot.c | 10 ++++++++++
arch/x86/kernel/mmconf-fam10h_64.c | 2 +-
arch/x86/kernel/x86_init.c | 2 +-
arch/x86/xen/p2m.c | 30 ++++++++++++++++++++++++++++++
arch/x86/xen/setup.c | 2 +-
6 files changed, 51 insertions(+), 3 deletions(-)
diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h
index 21bc53f5ed0c..42067643e615 100644
--- a/arch/x86/include/asm/acpi.h
+++ b/arch/x86/include/asm/acpi.h
@@ -174,6 +174,14 @@ void acpi_generic_reduced_hw_init(void);
void x86_default_set_root_pointer(u64 addr);
u64 x86_default_get_root_pointer(void);
+#ifdef CONFIG_XEN_PV_DOM0
+/* A Xen PV dom0 needs a special acpi_os_ioremap() handling. */
+extern void __iomem * (*acpi_os_ioremap)(acpi_physical_address phys,
+ acpi_size size);
+void __iomem *x86_acpi_os_ioremap(acpi_physical_address phys, acpi_size size);
+#define acpi_os_ioremap acpi_os_ioremap
+#endif
+
#else /* !CONFIG_ACPI */
#define acpi_lapic 0
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 9f4618dcd704..6dd01d15f277 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -1778,3 +1778,13 @@ u64 x86_default_get_root_pointer(void)
{
return boot_params.acpi_rsdp_addr;
}
+
+#ifdef CONFIG_XEN_PV_DOM0
+void __iomem *x86_acpi_os_ioremap(acpi_physical_address phys, acpi_size size)
+{
+ return ioremap_cache(phys, size);
+}
+
+void __iomem * (*acpi_os_ioremap)(acpi_physical_address phys, acpi_size size) =
+ x86_acpi_os_ioremap;
+#endif
diff --git a/arch/x86/kernel/mmconf-fam10h_64.c b/arch/x86/kernel/mmconf-fam10h_64.c
index c94dec6a1834..8347a29f9db4 100644
--- a/arch/x86/kernel/mmconf-fam10h_64.c
+++ b/arch/x86/kernel/mmconf-fam10h_64.c
@@ -9,12 +9,12 @@
#include <linux/pci.h>
#include <linux/dmi.h>
#include <linux/range.h>
+#include <linux/acpi.h>
#include <asm/pci-direct.h>
#include <linux/sort.h>
#include <asm/io.h>
#include <asm/msr.h>
-#include <asm/acpi.h>
#include <asm/mmconfig.h>
#include <asm/pci_x86.h>
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index 82b128d3f309..47ef8af23101 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -8,8 +8,8 @@
#include <linux/ioport.h>
#include <linux/export.h>
#include <linux/pci.h>
+#include <linux/acpi.h>
-#include <asm/acpi.h>
#include <asm/bios_ebda.h>
#include <asm/paravirt.h>
#include <asm/pci_x86.h>
diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c
index bb55e0fe1a04..61aaf066bf3e 100644
--- a/arch/x86/xen/p2m.c
+++ b/arch/x86/xen/p2m.c
@@ -70,6 +70,7 @@
#include <linux/memblock.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
+#include <linux/acpi.h>
#include <asm/cache.h>
#include <asm/setup.h>
@@ -838,6 +839,31 @@ void __init xen_do_remap_nonram(void)
pr_info("Remapped %u non-RAM page(s)\n", remapped);
}
+/*
+ * Xen variant of acpi_os_ioremap() taking potentially remapped non-RAM
+ * regions into acount.
+ * Any attempt to map an area crossing a remap boundary will produce a
+ * WARN() splat.
+ */
+static void __iomem *xen_acpi_os_ioremap(acpi_physical_address phys,
+ acpi_size size)
+{
+ unsigned int i;
+ struct nonram_remap *remap = xen_nonram_remap;
+
+ for (i = 0; i < nr_nonram_remap; i++) {
+ if (phys + size > remap->maddr &&
+ phys < remap->maddr + remap->size) {
+ WARN_ON(phys < remap->maddr ||
+ phys + size > remap->maddr + remap->size);
+ phys = remap->paddr + phys - remap->maddr;
+ break;
+ }
+ }
+
+ return x86_acpi_os_ioremap(phys, size);
+}
+
/*
* Add a new non-RAM remap entry.
* In case of no free entry found, just crash the system.
@@ -850,6 +876,10 @@ void __init xen_add_remap_nonram(phys_addr_t maddr, phys_addr_t paddr,
BUG();
}
+ /* Switch to the Xen acpi_os_ioremap() variant. */
+ if (nr_nonram_remap == 0)
+ acpi_os_ioremap = xen_acpi_os_ioremap;
+
xen_nonram_remap[nr_nonram_remap].maddr = maddr;
xen_nonram_remap[nr_nonram_remap].paddr = paddr;
xen_nonram_remap[nr_nonram_remap].size = size;
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index d678c0330971..88b2ebd23da3 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -15,12 +15,12 @@
#include <linux/cpuidle.h>
#include <linux/cpufreq.h>
#include <linux/memory_hotplug.h>
+#include <linux/acpi.h>
#include <asm/elf.h>
#include <asm/vdso.h>
#include <asm/e820/api.h>
#include <asm/setup.h>
-#include <asm/acpi.h>
#include <asm/numa.h>
#include <asm/idtentry.h>
#include <asm/xen/hypervisor.h>
--
2.43.0
Hi Juergen, kernel test robot noticed the following build errors: [auto build test ERROR on tip/x86/core] [also build test ERROR on rafael-pm/linux-next rafael-pm/bleeding-edge linus/master v6.11-rc4 next-20240820] [cannot apply to xen-tip/linux-next] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Juergen-Gross/xen-use-correct-end-address-of-kernel-for-conflict-checking/20240820-162344 base: tip/x86/core patch link: https://lore.kernel.org/r/20240820082012.31316-7-jgross%40suse.com patch subject: [PATCH v2 6/7] xen: allow mapping ACPI data using a different physical address config: x86_64-randconfig-004-20240820 (https://download.01.org/0day-ci/archive/20240821/202408210336.uafTZlvc-lkp@intel.com/config) compiler: gcc-12 (Debian 12.2.0-14) 12.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240821/202408210336.uafTZlvc-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202408210336.uafTZlvc-lkp@intel.com/ All errors (new ones prefixed by >>): In file included from arch/x86/kernel/smpboot.c:64: >> arch/x86/include/asm/acpi.h:179:42: error: unknown type name 'acpi_physical_address' 179 | extern void __iomem * (*acpi_os_ioremap)(acpi_physical_address phys, | ^~~~~~~~~~~~~~~~~~~~~ >> arch/x86/include/asm/acpi.h:180:42: error: unknown type name 'acpi_size' 180 | acpi_size size); | ^~~~~~~~~ arch/x86/include/asm/acpi.h:181:35: error: unknown type name 'acpi_physical_address' 181 | void __iomem *x86_acpi_os_ioremap(acpi_physical_address phys, acpi_size size); | ^~~~~~~~~~~~~~~~~~~~~ arch/x86/include/asm/acpi.h:181:63: error: unknown type name 'acpi_size' 181 | void __iomem *x86_acpi_os_ioremap(acpi_physical_address phys, acpi_size size); | ^~~~~~~~~ vim +/acpi_physical_address +179 arch/x86/include/asm/acpi.h 176 177 #ifdef CONFIG_XEN_PV_DOM0 178 /* A Xen PV dom0 needs a special acpi_os_ioremap() handling. */ > 179 extern void __iomem * (*acpi_os_ioremap)(acpi_physical_address phys, > 180 acpi_size size); 181 void __iomem *x86_acpi_os_ioremap(acpi_physical_address phys, acpi_size size); 182 #define acpi_os_ioremap acpi_os_ioremap 183 #endif 184 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
Hi Juergen, kernel test robot noticed the following build errors: [auto build test ERROR on tip/x86/core] [also build test ERROR on rafael-pm/linux-next rafael-pm/bleeding-edge linus/master v6.11-rc4 next-20240820] [cannot apply to xen-tip/linux-next] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Juergen-Gross/xen-use-correct-end-address-of-kernel-for-conflict-checking/20240820-162344 base: tip/x86/core patch link: https://lore.kernel.org/r/20240820082012.31316-7-jgross%40suse.com patch subject: [PATCH v2 6/7] xen: allow mapping ACPI data using a different physical address config: i386-buildonly-randconfig-002-20240820 (https://download.01.org/0day-ci/archive/20240821/202408210000.e7XA8iNs-lkp@intel.com/config) compiler: clang version 18.1.5 (https://github.com/llvm/llvm-project 617a15a9eac96088ae5e9134248d8236e34b91b1) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240821/202408210000.e7XA8iNs-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202408210000.e7XA8iNs-lkp@intel.com/ All errors (new ones prefixed by >>): >> arch/x86/kernel/x86_init.c:123:23: error: use of undeclared identifier 'x86_default_set_root_pointer' 123 | .set_root_pointer = x86_default_set_root_pointer, | ^ >> arch/x86/kernel/x86_init.c:124:23: error: use of undeclared identifier 'x86_default_get_root_pointer' 124 | .get_root_pointer = x86_default_get_root_pointer, | ^ >> arch/x86/kernel/x86_init.c:125:28: error: use of undeclared identifier 'acpi_generic_reduced_hw_init' 125 | .reduced_hw_early_init = acpi_generic_reduced_hw_init, | ^ 3 errors generated. vim +/x86_default_set_root_pointer +123 arch/x86/kernel/x86_init.c f7cf5a5b8c0e59 Thomas Gleixner 2009-08-19 65 f7cf5a5b8c0e59 Thomas Gleixner 2009-08-19 66 .resources = { 5d94e81f69d4b1 Dan Williams 2011-03-08 67 .probe_roms = probe_roms, 8fee697d990c54 Thomas Gleixner 2009-08-19 68 .reserve_resources = reserve_standard_io_resources, 103e206309639b Ingo Molnar 2017-01-28 69 .memory_setup = e820__memory_setup_default, 0f4a1e80989aca Kevin Loughlin 2024-03-13 70 .dmi_setup = dmi_setup, f7cf5a5b8c0e59 Thomas Gleixner 2009-08-19 71 }, f4848472cd9948 Thomas Gleixner 2009-08-20 72 f4848472cd9948 Thomas Gleixner 2009-08-20 73 .mpparse = { de93410310952f Thomas Gleixner 2009-08-20 74 .setup_ioapic_ids = x86_init_noop, e061c7ae0830ff Thomas Gleixner 2024-02-13 75 .find_mptable = mpparse_find_mptable, dcb7600849ce9b Thomas Gleixner 2024-02-13 76 .early_parse_smp_cfg = mpparse_parse_early_smp_config, dcb7600849ce9b Thomas Gleixner 2024-02-13 77 .parse_smp_cfg = mpparse_parse_smp_config, f4848472cd9948 Thomas Gleixner 2009-08-20 78 }, d9112f43021554 Thomas Gleixner 2009-08-20 79 d9112f43021554 Thomas Gleixner 2009-08-20 80 .irqs = { d9112f43021554 Thomas Gleixner 2009-08-20 81 .pre_vector_init = init_ISA_irqs, 66bcaf0bde100a Thomas Gleixner 2009-08-20 82 .intr_init = native_init_IRQ, 979923871f69a4 Thomas Gleixner 2020-01-23 83 .intr_mode_select = apic_intr_mode_select, 6b15ffa07dc325 Thomas Gleixner 2020-08-26 84 .intr_mode_init = apic_intr_mode_init, 6b15ffa07dc325 Thomas Gleixner 2020-08-26 85 .create_pci_msi_domain = native_create_pci_msi_domain, d9112f43021554 Thomas Gleixner 2009-08-20 86 }, 42bbdb43b16d23 Thomas Gleixner 2009-08-20 87 42bbdb43b16d23 Thomas Gleixner 2009-08-20 88 .oem = { 42bbdb43b16d23 Thomas Gleixner 2009-08-20 89 .arch_setup = x86_init_noop, 6f30c1ac3fcf11 Thomas Gleixner 2009-08-20 90 .banner = default_banner, 42bbdb43b16d23 Thomas Gleixner 2009-08-20 91 }, 030cb6c00d242c Thomas Gleixner 2009-08-20 92 030cb6c00d242c Thomas Gleixner 2009-08-20 93 .paging = { 7737b215ad0f94 Attilio Rao 2012-08-21 94 .pagetable_init = native_pagetable_init, 030cb6c00d242c Thomas Gleixner 2009-08-20 95 }, 736decac643e89 Thomas Gleixner 2009-08-19 96 736decac643e89 Thomas Gleixner 2009-08-19 97 .timers = { 736decac643e89 Thomas Gleixner 2009-08-19 98 .setup_percpu_clockev = setup_boot_APIC_clock, 845b3944bbdf9e Thomas Gleixner 2009-08-19 99 .timer_init = hpet_time_init, c311ed6183f4fd Rahul Tanwar 2019-10-10 100 .wallclock_init = x86_wallclock_init, 736decac643e89 Thomas Gleixner 2009-08-19 101 }, d07c1be0693e09 FUJITA Tomonori 2009-11-10 102 d07c1be0693e09 FUJITA Tomonori 2009-11-10 103 .iommu = { d07c1be0693e09 FUJITA Tomonori 2009-11-10 104 .iommu_init = iommu_init_noop, d07c1be0693e09 FUJITA Tomonori 2009-11-10 105 }, b72d0db9dd41da Thomas Gleixner 2009-08-29 106 b72d0db9dd41da Thomas Gleixner 2009-08-29 107 .pci = { b72d0db9dd41da Thomas Gleixner 2009-08-29 108 .init = x86_default_pci_init, ab3b37937e8f4f Thomas Gleixner 2009-08-29 109 .init_irq = x86_default_pci_init_irq, 9325a28ce2fa7c Thomas Gleixner 2009-08-29 110 .fixup_irqs = x86_default_pci_fixup_irqs, b72d0db9dd41da Thomas Gleixner 2009-08-29 111 }, f72e38e8ec8869 Juergen Gross 2017-11-09 112 f72e38e8ec8869 Juergen Gross 2017-11-09 113 .hyper = { f72e38e8ec8869 Juergen Gross 2017-11-09 114 .init_platform = x86_init_noop, f3614646005a1b Juergen Gross 2017-11-09 115 .guest_late_init = x86_init_noop, f72e38e8ec8869 Juergen Gross 2017-11-09 116 .x2apic_available = bool_x86_init_noop, ab0f59c6f13528 David Woodhouse 2020-10-24 117 .msi_ext_dest_id = bool_x86_init_noop, f72e38e8ec8869 Juergen Gross 2017-11-09 118 .init_mem_mapping = x86_init_noop, 6f84f8d1587f20 Pavel Tatashin 2018-04-10 119 .init_after_bootmem = x86_init_noop, f72e38e8ec8869 Juergen Gross 2017-11-09 120 }, 038bac2b02989a Juergen Gross 2018-02-19 121 038bac2b02989a Juergen Gross 2018-02-19 122 .acpi = { 41fa1ee9c6d687 Josh Boyer 2019-08-19 @123 .set_root_pointer = x86_default_set_root_pointer, e7b66d16fe4172 Juergen Gross 2018-10-10 @124 .get_root_pointer = x86_default_get_root_pointer, 81b53e5ff21e09 Andy Shevchenko 2018-02-20 @125 .reduced_hw_early_init = acpi_generic_reduced_hw_init, 038bac2b02989a Juergen Gross 2018-02-19 126 }, 736decac643e89 Thomas Gleixner 2009-08-19 127 }; 736decac643e89 Thomas Gleixner 2009-08-19 128 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
On 20.08.2024 10:20, Juergen Gross wrote: > @@ -838,6 +839,31 @@ void __init xen_do_remap_nonram(void) > pr_info("Remapped %u non-RAM page(s)\n", remapped); > } > > +/* > + * Xen variant of acpi_os_ioremap() taking potentially remapped non-RAM > + * regions into acount. > + * Any attempt to map an area crossing a remap boundary will produce a > + * WARN() splat. > + */ > +static void __iomem *xen_acpi_os_ioremap(acpi_physical_address phys, > + acpi_size size) > +{ > + unsigned int i; > + struct nonram_remap *remap = xen_nonram_remap; const (also in one of the functions in patch 5)? > + for (i = 0; i < nr_nonram_remap; i++) { > + if (phys + size > remap->maddr && > + phys < remap->maddr + remap->size) { > + WARN_ON(phys < remap->maddr || > + phys + size > remap->maddr + remap->size); > + phys = remap->paddr + phys - remap->maddr; > + break; > + } > + } > + > + return x86_acpi_os_ioremap(phys, size); > +} At least this, perhaps also what patch 5 adds, likely wants to be limited to the XEN_DOM0 case? Or else I wonder whether ... > @@ -850,6 +876,10 @@ void __init xen_add_remap_nonram(phys_addr_t maddr, phys_addr_t paddr, > BUG(); > } > > + /* Switch to the Xen acpi_os_ioremap() variant. */ > + if (nr_nonram_remap == 0) > + acpi_os_ioremap = xen_acpi_os_ioremap; ... this would actually build when XEN_DOM0=n. I'm actually surprised there's no Dom0-only code section in this file, where the new code could then simply be inserted. Jan
On 20.08.24 11:56, Jan Beulich wrote: > On 20.08.2024 10:20, Juergen Gross wrote: >> @@ -838,6 +839,31 @@ void __init xen_do_remap_nonram(void) >> pr_info("Remapped %u non-RAM page(s)\n", remapped); >> } >> >> +/* >> + * Xen variant of acpi_os_ioremap() taking potentially remapped non-RAM >> + * regions into acount. >> + * Any attempt to map an area crossing a remap boundary will produce a >> + * WARN() splat. >> + */ >> +static void __iomem *xen_acpi_os_ioremap(acpi_physical_address phys, >> + acpi_size size) >> +{ >> + unsigned int i; >> + struct nonram_remap *remap = xen_nonram_remap; > > const (also in one of the functions in patch 5)? Yes. > >> + for (i = 0; i < nr_nonram_remap; i++) { >> + if (phys + size > remap->maddr && >> + phys < remap->maddr + remap->size) { >> + WARN_ON(phys < remap->maddr || >> + phys + size > remap->maddr + remap->size); >> + phys = remap->paddr + phys - remap->maddr; >> + break; >> + } >> + } >> + >> + return x86_acpi_os_ioremap(phys, size); >> +} > > At least this, perhaps also what patch 5 adds, likely wants to be limited > to the XEN_DOM0 case? Or else I wonder whether ... > >> @@ -850,6 +876,10 @@ void __init xen_add_remap_nonram(phys_addr_t maddr, phys_addr_t paddr, >> BUG(); >> } >> >> + /* Switch to the Xen acpi_os_ioremap() variant. */ >> + if (nr_nonram_remap == 0) >> + acpi_os_ioremap = xen_acpi_os_ioremap; > > ... this would actually build when XEN_DOM0=n. > > I'm actually surprised there's no Dom0-only code section in this file, > where the new code could then simply be inserted. I'd rather make this conditional on CONFIG_ACPI. Depending on how Xen tools will handle a PV-domain with "e820_host=1" this code might be important for domUs, too. Juergen
On 10.09.2024 10:15, Juergen Gross wrote: > On 20.08.24 11:56, Jan Beulich wrote: >> On 20.08.2024 10:20, Juergen Gross wrote: >>> @@ -838,6 +839,31 @@ void __init xen_do_remap_nonram(void) >>> pr_info("Remapped %u non-RAM page(s)\n", remapped); >>> } >>> >>> +/* >>> + * Xen variant of acpi_os_ioremap() taking potentially remapped non-RAM >>> + * regions into acount. >>> + * Any attempt to map an area crossing a remap boundary will produce a >>> + * WARN() splat. >>> + */ >>> +static void __iomem *xen_acpi_os_ioremap(acpi_physical_address phys, >>> + acpi_size size) >>> +{ >>> + unsigned int i; >>> + struct nonram_remap *remap = xen_nonram_remap; >> >> const (also in one of the functions in patch 5)? > > Yes. > >> >>> + for (i = 0; i < nr_nonram_remap; i++) { >>> + if (phys + size > remap->maddr && >>> + phys < remap->maddr + remap->size) { >>> + WARN_ON(phys < remap->maddr || >>> + phys + size > remap->maddr + remap->size); >>> + phys = remap->paddr + phys - remap->maddr; >>> + break; >>> + } >>> + } >>> + >>> + return x86_acpi_os_ioremap(phys, size); >>> +} >> >> At least this, perhaps also what patch 5 adds, likely wants to be limited >> to the XEN_DOM0 case? Or else I wonder whether ... >> >>> @@ -850,6 +876,10 @@ void __init xen_add_remap_nonram(phys_addr_t maddr, phys_addr_t paddr, >>> BUG(); >>> } >>> >>> + /* Switch to the Xen acpi_os_ioremap() variant. */ >>> + if (nr_nonram_remap == 0) >>> + acpi_os_ioremap = xen_acpi_os_ioremap; >> >> ... this would actually build when XEN_DOM0=n. >> >> I'm actually surprised there's no Dom0-only code section in this file, >> where the new code could then simply be inserted. > > I'd rather make this conditional on CONFIG_ACPI. Oh, sure. > Depending on how Xen tools will handle a PV-domain with "e820_host=1" this > code might be important for domUs, too. Right, if that's a possibility for PV (I thought that was a HVM-only thing, yet maybe it really is precisely the other way around), then yes, DomU-s may too need to cope with unexpected overlaps. Jan
© 2016 - 2024 Red Hat, Inc.