static long pSeries_lpar_hpte_remove(unsigned long hpte_group) { unsigned long slot_offset; unsigned long lpar_rc; int i; unsigned long dummy1, dummy2; /* pick a random slot to start at */ slot_offset = mftb() & 0x7; for (i = 0; i < HPTES_PER_GROUP; i++) { /* don't remove a bolted entry */ lpar_rc = plpar_pte_remove(H_ANDCOND, hpte_group + slot_offset, (0x1UL << 4), &dummy1, &dummy2); if (lpar_rc == H_SUCCESS) return i; /* * The test for adjunct partition is performed before the * ANDCOND test. H_RESOURCE may be returned, so we need to * check for that as well. */ BUG_ON(lpar_rc != H_NOT_FOUND && lpar_rc != H_RESOURCE); slot_offset++; slot_offset &= 0x7; } return -1; }
static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long vpn, int psize, int apsize, int ssize, int local) { unsigned long want_v; unsigned long lpar_rc; unsigned long dummy1, dummy2; pr_devel(" inval : slot=%lx, vpn=%016lx, psize: %d, local: %d\n", slot, vpn, psize, local); want_v = hpte_encode_avpn(vpn, psize, ssize); lpar_rc = plpar_pte_remove(H_AVPN, slot, want_v, &dummy1, &dummy2); if (lpar_rc == H_NOT_FOUND) return; BUG_ON(lpar_rc != H_SUCCESS); }
static void gnttab_pre_unmap_grant_ref( struct gnttab_unmap_grant_ref *unmap, int count) { long slot; int i; ulong ea; unsigned long dummy1, dummy2; ulong flags; /* paranoia */ local_irq_save(flags); for (i = 0 ; i < count; i++) { struct page *page; ea = (ulong)__va(unmap[i].host_addr); page = virt_to_page(ea); if (!gnt_unmap(page)) { DBG("%s[0x%x]: skip: 0x%lx, mapcount 0x%x\n", __func__, i, ea, gnt_mapcount(page)); continue; } slot = find_map_slot(ea); if (slot < 0) { printk(KERN_EMERG "%s: PTE not found: 0x%lx\n", __func__, ea); continue; } DBG("%s[0x%x]: 0x%lx: mapcount: 0x%x\n", __func__, i, ea, gnt_mapcount(page)); plpar_pte_remove(0, slot, 0, &dummy1, &dummy2); } local_irq_restore(flags); }