Exemplo n.º 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;
}
Exemplo n.º 2
0
static long ps3_hpte_updatepp(unsigned long slot, unsigned long newpp,
	unsigned long va, int psize, int ssize, int local)
{
	int result;
	u64 hpte_v, want_v, hpte_rs;
	u64 hpte_v_array[4];
	unsigned long flags;
	long ret;

	want_v = hpte_encode_v(va, psize, ssize);

	spin_lock_irqsave(&ps3_htab_lock, flags);

	result = lv1_read_htab_entries(PS3_LPAR_VAS_ID_CURRENT, slot & ~0x3UL,
				       &hpte_v_array[0], &hpte_v_array[1],
				       &hpte_v_array[2], &hpte_v_array[3],
				       &hpte_rs);

	if (result) {
		pr_info("%s: res=%d read va=%lx slot=%lx psize=%d\n",
			__func__, result, va, slot, psize);
		BUG();
	}

	hpte_v = hpte_v_array[slot % 4];

	/*
	 * As lv1_read_htab_entries() does not give us the RPN, we can
	 * not synthesize the new hpte_r value here, and therefore can
	 * not update the hpte with lv1_insert_htab_entry(), so we
<<<<<<< HEAD
	 * instead invalidate it and ask the caller to update it via
=======
	 * insted invalidate it and ask the caller to update it via
>>>>>>> 296c66da8a02d52243f45b80521febece5ed498a
	 * ps3_hpte_insert() by returning a -1 value.
	 */
	if (!HPTE_V_COMPARE(hpte_v, want_v) || !(hpte_v & HPTE_V_VALID)) {
		/* not found */
		ret = -1;
	} else {
		/* entry found, just invalidate it */
		result = lv1_write_htab_entry(PS3_LPAR_VAS_ID_CURRENT,
					      slot, 0, 0);
		ret = -1;
	}

	spin_unlock_irqrestore(&ps3_htab_lock, flags);
	return ret;
}
Exemplo n.º 3
0
static long pSeries_lpar_hpte_find(unsigned long vpn, int psize, int ssize)
{
	unsigned long hash;
	unsigned long i;
	long slot;
	unsigned long want_v, hpte_v;

	hash = hpt_hash(vpn, mmu_psize_defs[psize].shift, ssize);
	want_v = hpte_encode_avpn(vpn, psize, ssize);

	/* Bolted entries are always in the primary group */
	slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
	for (i = 0; i < HPTES_PER_GROUP; i++) {
		hpte_v = pSeries_lpar_hpte_getword0(slot);

		if (HPTE_V_COMPARE(hpte_v, want_v) && (hpte_v & HPTE_V_VALID))
			/* HPTE matches */
			return slot;
		++slot;
	}

	return -1;
} 
Exemplo n.º 4
0
static long __pSeries_lpar_hpte_find(unsigned long want_v, unsigned long hpte_group)
{
	long lpar_rc;
	unsigned long i, j;
	struct {
		unsigned long pteh;
		unsigned long ptel;
	} ptes[4];

	for (i = 0; i < HPTES_PER_GROUP; i += 4, hpte_group += 4) {

		lpar_rc = plpar_pte_read_4(0, hpte_group, (void *)ptes);
		if (lpar_rc != H_SUCCESS)
			continue;

		for (j = 0; j < 4; j++) {
			if (HPTE_V_COMPARE(ptes[j].pteh, want_v) &&
			    (ptes[j].pteh & HPTE_V_VALID))
				return i + j;
		}
	}

	return -1;
}
Exemplo n.º 5
0
Arquivo: htab.c Projeto: cilynx/dd-wrt
/*
 * The HyperVisor expects the "flags" argument in this form:
 *	bits  0..59 : reserved
 *	bit      60 : N
 *	bits 61..63 : PP2,PP1,PP0
 */
static long iSeries_hpte_updatepp(unsigned long slot, unsigned long newpp,
				  unsigned long va, int psize, int local)
{
	struct hash_pte hpte;
	unsigned long want_v;

	iSeries_hlock(slot);

	HvCallHpt_get(&hpte, slot);
	want_v = hpte_encode_v(va, MMU_PAGE_4K);

	if (HPTE_V_COMPARE(hpte.v, want_v) && (hpte.v & HPTE_V_VALID)) {
		/*
		 * Hypervisor expects bits as NPPP, which is
		 * different from how they are mapped in our PP.
		 */
		HvCallHpt_setPp(slot, (newpp & 0x3) | ((newpp & 0x4) << 1));
		iSeries_hunlock(slot);
		return 0;
	}
	iSeries_hunlock(slot);

	return -1;
}