[Cbe-oss-dev] 64K Page Support for Kexec

luke lukebr at linux.vnet.ibm.com
Mon Mar 26 00:00:12 EST 2007


There are some XXX comments pertaining to large page support in
slot2va() that I am not clear about.  

I wrote the following routine to determine the large page size encoding.

static inline int hpte_decode_lpsize(unsigned long pa)
{
        int i;

        for (i = MMU_PAGE_COUNT - 1; i > 0; i--) {
                unsigned int penc = mmu_psize_defs[i].penc;
                if ((penc & pa) == penc)
                        break;
        }
        return i;
}

It is invoked as follows:

static void native_hpte_clear(void)
{
        unsigned long slot, slots, flags;
        hpte_t *hptep = htab_address;
        unsigned long hpte_v;
        unsigned long pteg_count;

        pteg_count = htab_hash_mask + 1;

        local_irq_save(flags);

        /* we take the tlbie lock and hold it.  Some hardware will
         * deadlock if we try to tlbie from two processors at once.
         */
        spin_lock(&native_tlbie_lock);

        slots = pteg_count * HPTES_PER_GROUP;

        for (slot = 0; slot < slots; slot++, hptep++) {
                /*
                 * we could lock the pte here, but we are the only cpu
                 * running,  right?  and for crash dump, we probably
                 * don't want to wait for a maybe bad cpu.
                 */
                hpte_v = hptep->v;

                /*
                 * Call __tlbie() here rather than tlbie() since we
                 * already hold the native_tlbie_lock.
                 */
                if (hpte_v & HPTE_V_VALID) {
                        if (!(hpte_v & HPTE_V_LARGE))
                                psize = MMU_PAGE_4K;
                        else
                                psize = hpte_decode_lpsize(hptep->r);
                        hptep->v = 0;
                        __tlbie(slot2va(hpte_v, slot), psize);
                }
        }

        asm volatile("eieio; tlbsync; ptesync":::"memory");
        spin_unlock(&native_tlbie_lock);
        local_irq_restore(flags);
}

I am confused about the following comment.

/*
 * XXX This need fixing based on page size. It's only used by
 * native_hpte_clear() for now which needs fixing too so they
 * make a good pair...
 */
static unsigned long slot2va(unsigned long hpte_v, unsigned long slot)
{
        unsigned long avpn = HPTE_V_AVPN_VAL(hpte_v);
        unsigned long va;

        va = avpn << 23;

        if (! (hpte_v & HPTE_V_LARGE)) {
                unsigned long vpi, pteg;

                pteg = slot / HPTES_PER_GROUP;
                if (hpte_v & HPTE_V_SECONDARY)
                        pteg = ~pteg;

                vpi = ((va >> 28) ^ pteg) & htab_hash_mask;

                va |= vpi << PAGE_SHIFT;
        }

        return va;
}

The routine above looks OK to me.  What am I missing?

Thx, Luke




More information about the cbe-oss-dev mailing list