Fix domain pickled_id computation for xen-3.4+
Subsystems (2)
PATCH v3 6/9 Fix domain pickled_id computation for xen-3.4+
Originally, Xen stored the 32-bit address of the domain structure in struct page_info. On x86-64, the physical address was stored, but since all heap objects were allocated in the 1:1 mapping which started at 0xffff830000000000, the end result was the same as if we simply chopped off the high bits (actual implementation in makedumpfile).
Then, during the development of Xen-3.4, this logic was changed several times for x86-64:
changeset 39517e863cc8 widened the _domain field to 64 bits and stored the
virtual address of struct domain instead of physical address
changeset beba88f6f90d removed the pickle/unpickle macros changeset 0858f961c77a changed _domain back from unsigned long to u32,
*and* stores the MFN of struct domain instead
All the above changes went into Xen-3.4, and the relation between a domain address and the contents of the _domain field hasn't changed since then. That means, when the MADDR space was compressed in Xen-4.0, the type of the _domain field was changed to _pdx_t, which was specifically invented to preserve its calculation from the struct domain address.
To sum it up:
1. For all Xen versions before Xen-3.4, the _domain field contains the address of struct domain (with high bits chopped for x86-64).
2. For all Xen versions starting with Xen-3.4, the _domain field can be computed from struct domain address as:
(addr - DIRECTMAP_VIRT_START) >> PAGE_SHIFT
--- arch/x86_64.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-)
arch/x86_64.c +20 -6
@@ -405,12 +405,26 @@ int get_xen_info_x86_64(void) {int i; -/* -* pickled_id == domain addr for x86_64 -*/ -for (i =0 ; i < info->num_domain; i++) { - info->domain_list[i].pickled_id = - info->domain_list[i].domain_addr; +if (info->xen_crash_info.com && + (info->xen_crash_info.com->xen_major_version >=4 || + (info->xen_crash_info.com->xen_major_version ==3 && + info->xen_crash_info.com->xen_minor_version >=4 ))) { +/* +* cf. changeset 0858f961c77a +*/ +for (i =0 ; i < info->num_domain; i++) { + info->domain_list[i].pickled_id = + (info->domain_list[i].domain_addr - +DIRECTMAP_VIRT_START ) >>PAGESHIFT (); + } + }else { +/* +* pickled_id == domain addr for x86_64 +*/ +for (i =0 ; i < info->num_domain; i++) { + info->domain_list[i].pickled_id = + info->domain_list[i].domain_addr; + } }return TRUE;
_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec