x86: restore reserving of IO-APIC pages in XENMEM_machine_memory_map output Commit d1222afda4 ("x86: allow Dom0 read-only access to IO-APICs") had an unintended side effect: By no longer adding IO-APIC pages to Dom0's iomem_caps these also no longer get reported as reserved in the machine memory map presented to it (which got added there intentionally by commit b8a456caed ["x86: improve reporting through XENMEM_machine_memory_map"] because many BIOSes fail to add these). Signed-off-by: Jan Beulich --- Treating everything in mmio_ro_ranges this way doesn't appear to be a suitable option: Certain PCI device ranges (most notably MSI-X control pages) get tracked there as well, and hence this rangeset isn't really stable across the lifetime of a system and thus shouldn't be used for purposes like the one here. --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -122,6 +122,7 @@ #include #include #include +#include #include /* Mapping of the fixmap space needed early. */ @@ -4481,10 +4482,9 @@ struct memory_map_context struct xen_memory_map map; }; -static int handle_iomem_range(unsigned long s, unsigned long e, void *p) +static int _handle_iomem_range(unsigned long s, unsigned long e, + struct memory_map_context *ctxt) { - struct memory_map_context *ctxt = p; - if ( s > ctxt->s ) { e820entry_t ent; @@ -4507,6 +4507,31 @@ static int handle_iomem_range(unsigned l return 0; } +static int handle_iomem_range(unsigned long s, unsigned long e, void *p) +{ + int err = 0; + + do { + unsigned long low = -1UL; + unsigned int i; + + for ( i = 0; i < nr_ioapics; ++i ) + { + unsigned long mfn = paddr_to_pfn(mp_ioapics[i].mpc_apicaddr); + + if ( mfn >= s && mfn <= e && mfn < low ) + low = mfn; + } + if ( !(low + 1) ) + break; + if ( s < low ) + err = _handle_iomem_range(s, low - 1, p); + s = low + 1; + } while ( !err ); + + return err || s > e ? err : _handle_iomem_range(s, e, p); +} + int xenmem_add_to_physmap_one( struct domain *d, unsigned int space, @@ -4734,7 +4759,7 @@ long arch_memory_op(unsigned long cmd, X { unsigned long s = PFN_DOWN(e820.map[i].addr); - if ( s ) + if ( s > ctxt.s ) { rc = rangeset_report_ranges(current->domain->iomem_caps, ctxt.s, s - 1,