Ejemplo n.º 1
0
/*
 * Build the parallel p2m_top_mfn and p2m_mid_mfn structures
 *
 * This is called both at boot time, and after resuming from suspend:
 * - At boot time we're called rather early, and must use alloc_bootmem*()
 *   to allocate memory.
 *
 * - After resume we're called from within stop_machine, but the mfn
 *   tree should already be completely allocated.
 */
void __ref xen_build_mfn_list_list(void)
{
    unsigned long pfn, mfn;
    pte_t *ptep;
    unsigned int level, topidx, mididx;
    unsigned long *mid_mfn_p;

    if (xen_feature(XENFEAT_auto_translated_physmap))
        return;

    /* Pre-initialize p2m_top_mfn to be completely missing */
    if (p2m_top_mfn == NULL) {
        p2m_mid_missing_mfn = alloc_p2m_page();
        p2m_mid_mfn_init(p2m_mid_missing_mfn, p2m_missing);

        p2m_top_mfn_p = alloc_p2m_page();
        p2m_top_mfn_p_init(p2m_top_mfn_p);

        p2m_top_mfn = alloc_p2m_page();
        p2m_top_mfn_init(p2m_top_mfn);
    } else {
        /* Reinitialise, mfn's all change after migration */
        p2m_mid_mfn_init(p2m_mid_missing_mfn, p2m_missing);
    }

    for (pfn = 0; pfn < xen_max_p2m_pfn && pfn < MAX_P2M_PFN;
            pfn += P2M_PER_PAGE) {
        topidx = p2m_top_index(pfn);
        mididx = p2m_mid_index(pfn);

        mid_mfn_p = p2m_top_mfn_p[topidx];
        ptep = lookup_address((unsigned long)(xen_p2m_addr + pfn),
                              &level);
        BUG_ON(!ptep || level != PG_LEVEL_4K);
        mfn = pte_mfn(*ptep);
        ptep = (pte_t *)((unsigned long)ptep & ~(PAGE_SIZE - 1));

        /* Don't bother allocating any mfn mid levels if
         * they're just missing, just update the stored mfn,
         * since all could have changed over a migrate.
         */
        if (ptep == p2m_missing_pte || ptep == p2m_identity_pte) {
            BUG_ON(mididx);
            BUG_ON(mid_mfn_p != p2m_mid_missing_mfn);
            p2m_top_mfn[topidx] = virt_to_mfn(p2m_mid_missing_mfn);
            pfn += (P2M_MID_PER_PAGE - 1) * P2M_PER_PAGE;
            continue;
        }

        if (mid_mfn_p == p2m_mid_missing_mfn) {
            mid_mfn_p = alloc_p2m_page();
            p2m_mid_mfn_init(mid_mfn_p, p2m_missing);

            p2m_top_mfn_p[topidx] = mid_mfn_p;
        }

        p2m_top_mfn[topidx] = virt_to_mfn(mid_mfn_p);
        mid_mfn_p[mididx] = mfn;
    }
}
Ejemplo n.º 2
0
/*
 * Build the parallel p2m_top_mfn and p2m_mid_mfn structures
 *
 * This is called both at boot time, and after resuming from suspend:
 * - At boot time we're called very early, and must use extend_brk()
 *   to allocate memory.
 *
 * - After resume we're called from within stop_machine, but the mfn
 *   tree should alreay be completely allocated.
 */
void __ref xen_build_mfn_list_list(void)
{
	unsigned long pfn;

	/* Pre-initialize p2m_top_mfn to be completely missing */
	if (p2m_top_mfn == NULL) {
		p2m_mid_missing_mfn = extend_brk(PAGE_SIZE, PAGE_SIZE);
		p2m_mid_mfn_init(p2m_mid_missing_mfn);

		p2m_top_mfn_p = extend_brk(PAGE_SIZE, PAGE_SIZE);
		p2m_top_mfn_p_init(p2m_top_mfn_p);

		p2m_top_mfn = extend_brk(PAGE_SIZE, PAGE_SIZE);
		p2m_top_mfn_init(p2m_top_mfn);
	} else {
		/* Reinitialise, mfn's all change after migration */
		p2m_mid_mfn_init(p2m_mid_missing_mfn);
	}

	for (pfn = 0; pfn < xen_max_p2m_pfn; pfn += P2M_PER_PAGE) {
		unsigned topidx = p2m_top_index(pfn);
		unsigned mididx = p2m_mid_index(pfn);
		unsigned long **mid;
		unsigned long *mid_mfn_p;

		mid = p2m_top[topidx];
		mid_mfn_p = p2m_top_mfn_p[topidx];

		/* Don't bother allocating any mfn mid levels if
		 * they're just missing, just update the stored mfn,
		 * since all could have changed over a migrate.
		 */
		if (mid == p2m_mid_missing) {
			BUG_ON(mididx);
			BUG_ON(mid_mfn_p != p2m_mid_missing_mfn);
			p2m_top_mfn[topidx] = virt_to_mfn(p2m_mid_missing_mfn);
			pfn += (P2M_MID_PER_PAGE - 1) * P2M_PER_PAGE;
			continue;
		}

		if (mid_mfn_p == p2m_mid_missing_mfn) {
			/*
			 * XXX boot-time only!  We should never find
			 * missing parts of the mfn tree after
			 * runtime.  extend_brk() will BUG if we call
			 * it too late.
			 */
			mid_mfn_p = extend_brk(PAGE_SIZE, PAGE_SIZE);
			p2m_mid_mfn_init(mid_mfn_p);

			p2m_top_mfn_p[topidx] = mid_mfn_p;
		}

		p2m_top_mfn[topidx] = virt_to_mfn(mid_mfn_p);
		mid_mfn_p[mididx] = virt_to_mfn(mid[mididx]);
	}
}
Ejemplo n.º 3
0
void __ref xen_build_mfn_list_list(void)
{
	unsigned long pfn;

	
	if (p2m_top_mfn == NULL) {
		p2m_mid_missing_mfn = extend_brk(PAGE_SIZE, PAGE_SIZE);
		p2m_mid_mfn_init(p2m_mid_missing_mfn);

		p2m_top_mfn_p = extend_brk(PAGE_SIZE, PAGE_SIZE);
		p2m_top_mfn_p_init(p2m_top_mfn_p);

		p2m_top_mfn = extend_brk(PAGE_SIZE, PAGE_SIZE);
		p2m_top_mfn_init(p2m_top_mfn);
	} else {
		
		p2m_mid_mfn_init(p2m_mid_missing_mfn);
	}

	for (pfn = 0; pfn < xen_max_p2m_pfn; pfn += P2M_PER_PAGE) {
		unsigned topidx = p2m_top_index(pfn);
		unsigned mididx = p2m_mid_index(pfn);
		unsigned long **mid;
		unsigned long *mid_mfn_p;

		mid = p2m_top[topidx];
		mid_mfn_p = p2m_top_mfn_p[topidx];

		if (mid == p2m_mid_missing) {
			BUG_ON(mididx);
			BUG_ON(mid_mfn_p != p2m_mid_missing_mfn);
			p2m_top_mfn[topidx] = virt_to_mfn(p2m_mid_missing_mfn);
			pfn += (P2M_MID_PER_PAGE - 1) * P2M_PER_PAGE;
			continue;
		}

		if (mid_mfn_p == p2m_mid_missing_mfn) {
			mid_mfn_p = extend_brk(PAGE_SIZE, PAGE_SIZE);
			p2m_mid_mfn_init(mid_mfn_p);

			p2m_top_mfn_p[topidx] = mid_mfn_p;
		}

		p2m_top_mfn[topidx] = virt_to_mfn(mid_mfn_p);
		mid_mfn_p[mididx] = virt_to_mfn(mid[mididx]);
	}
}