Exemple #1
0
static long beat_lpar_hpte_find(unsigned long va, int psize)
{
    unsigned long hash;
    unsigned long i, j;
    long slot;
    unsigned long want_v, hpte_v;

    hash = hpt_hash(va, mmu_psize_defs[psize].shift, MMU_SEGSIZE_256M);
    want_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M);

    for (j = 0; j < 2; j++) {
        slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
        for (i = 0; i < HPTES_PER_GROUP; i++) {
            hpte_v = beat_lpar_hpte_getword0(slot);

            if (HPTE_V_COMPARE(hpte_v, want_v)
                    && (hpte_v & HPTE_V_VALID)
                    && (!!(hpte_v & HPTE_V_SECONDARY) == j)) {
                /* HPTE matches */
                if (j)
                    slot = -slot;
                return slot;
            }
            ++slot;
        }
        hash = ~hash;
    }

    return -1;
}
Exemple #2
0
static void beat_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
                                      int psize, int ssize, int local)
{
    unsigned long want_v;
    unsigned long lpar_rc;
    u64 dummy1, dummy2;
    unsigned long flags;

    DBG_LOW("    inval : slot=%lx, va=%016lx, psize: %d, local: %d\n",
            slot, va, psize, local);
    want_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M);

    atomic_spin_lock_irqsave(&beat_htab_lock, flags);
    dummy1 = beat_lpar_hpte_getword0(slot);

    if ((dummy1 & ~0x7FUL) != (want_v & ~0x7FUL)) {
        DBG_LOW("not found !\n");
        atomic_spin_unlock_irqrestore(&beat_htab_lock, flags);
        return;
    }

    lpar_rc = beat_write_htab_entry(0, slot, 0, 0, HPTE_V_VALID, 0,
                                    &dummy1, &dummy2);
    atomic_spin_unlock_irqrestore(&beat_htab_lock, flags);

    BUG_ON(lpar_rc != 0);
}
Exemple #3
0
/*
 * NOTE: for updatepp ops we are fortunate that the linux "newpp" bits and
 * the low 3 bits of flags happen to line up.  So no transform is needed.
 * We can probably optimize here and assume the high bits of newpp are
 * already zero.  For now I am paranoid.
 */
static long beat_lpar_hpte_updatepp(unsigned long slot,
				    unsigned long newpp,
				    unsigned long vpn,
				    int psize, int apsize,
				    int ssize, unsigned long flags)
{
	unsigned long lpar_rc;
	u64 dummy0, dummy1;
	unsigned long want_v;

	want_v = hpte_encode_avpn(vpn, psize, MMU_SEGSIZE_256M);

	DBG_LOW("    update: "
		"avpnv=%016lx, slot=%016lx, psize: %d, newpp %016lx ... ",
		want_v & HPTE_V_AVPN, slot, psize, newpp);

	raw_spin_lock(&beat_htab_lock);
	dummy0 = beat_lpar_hpte_getword0(slot);
	if ((dummy0 & ~0x7FUL) != (want_v & ~0x7FUL)) {
		DBG_LOW("not found !\n");
		raw_spin_unlock(&beat_htab_lock);
		return -1;
	}

	lpar_rc = beat_write_htab_entry(0, slot, 0, newpp, 0, 7, &dummy0,
					&dummy1);
	raw_spin_unlock(&beat_htab_lock);
	if (lpar_rc != 0 || dummy0 == 0) {
		DBG_LOW("not found !\n");
		return -1;
	}

	DBG_LOW("ok %lx %lx\n", dummy0, dummy1);

	BUG_ON(lpar_rc != 0);

	return 0;
}