l3_pgentry_t *pl3e;
l2_pgentry_t *pl2e;
int i, j, k;
+ unsigned long pte_update_limit;
/* Select relocation address. */
e = end - reloc_size;
xen_phys_start = e;
bootsym(trampoline_xen_phys_start) = e;
+ /*
+ * No PTEs pointing above this address are candidates for relocation.
+ * Due to possibility of partial overlap of the end of source image
+ * and the beginning of region for destination image some PTEs may
+ * point to addresses in range [e, e + XEN_IMG_OFFSET).
+ */
+ pte_update_limit = PFN_DOWN(e + XEN_IMG_OFFSET);
+
/*
* Perform relocation to new physical address.
* Before doing so we must sync static/global data with main memory
/* Not present, 1GB mapping, or already relocated? */
if ( !(l3e_get_flags(*pl3e) & _PAGE_PRESENT) ||
(l3e_get_flags(*pl3e) & _PAGE_PSE) ||
- (l3e_get_pfn(*pl3e) > PFN_DOWN(xen_phys_start)) )
+ (l3e_get_pfn(*pl3e) >= pte_update_limit) )
continue;
*pl3e = l3e_from_intpte(l3e_get_intpte(*pl3e) +
xen_phys_start);
/* Not present, PSE, or already relocated? */
if ( !(l2e_get_flags(*pl2e) & _PAGE_PRESENT) ||
(l2e_get_flags(*pl2e) & _PAGE_PSE) ||
- (l2e_get_pfn(*pl2e) > PFN_DOWN(xen_phys_start)) )
+ (l2e_get_pfn(*pl2e) >= pte_update_limit) )
continue;
*pl2e = l2e_from_intpte(l2e_get_intpte(*pl2e) +
xen_phys_start);
unsigned int flags;
if ( !(l2e_get_flags(*pl2e) & _PAGE_PRESENT) ||
- (l2e_get_pfn(*pl2e) > PFN_DOWN(xen_phys_start)) )
+ (l2e_get_pfn(*pl2e) >= pte_update_limit) )
continue;
if ( !using_2M_mapping() )