Skip to content

Commit

Permalink
[PATCH] ppc64: kill bitfields in ppc64 hash code
Browse files Browse the repository at this point in the history
This patch removes the use of bitfield types from the ppc64 hash table
manipulation code.

Signed-off-by: David Gibson <[email protected]>
Acked-by: Stephen Rothwell <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
dgibson authored and Linus Torvalds committed Jul 13, 2005
1 parent f13487c commit 96e2844
Show file tree
Hide file tree
Showing 11 changed files with 164 additions and 228 deletions.
51 changes: 21 additions & 30 deletions arch/ppc64/kernel/iSeries_htab.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,45 +38,40 @@ static inline void iSeries_hunlock(unsigned long slot)
}

static long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va,
unsigned long prpn, int secondary,
unsigned long hpteflags, int bolted, int large)
unsigned long prpn, unsigned long vflags,
unsigned long rflags)
{
long slot;
HPTE lhpte;
hpte_t lhpte;
int secondary = 0;

/*
* The hypervisor tries both primary and secondary.
* If we are being called to insert in the secondary,
* it means we have already tried both primary and secondary,
* so we return failure immediately.
*/
if (secondary)
if (vflags & HPTE_V_SECONDARY)
return -1;

iSeries_hlock(hpte_group);

slot = HvCallHpt_findValid(&lhpte, va >> PAGE_SHIFT);
BUG_ON(lhpte.dw0.dw0.v);
BUG_ON(lhpte.v & HPTE_V_VALID);

if (slot == -1) { /* No available entry found in either group */
iSeries_hunlock(hpte_group);
return -1;
}

if (slot < 0) { /* MSB set means secondary group */
vflags |= HPTE_V_VALID;
secondary = 1;
slot &= 0x7fffffffffffffff;
}

lhpte.dw1.dword1 = 0;
lhpte.dw1.dw1.rpn = physRpn_to_absRpn(prpn);
lhpte.dw1.flags.flags = hpteflags;

lhpte.dw0.dword0 = 0;
lhpte.dw0.dw0.avpn = va >> 23;
lhpte.dw0.dw0.h = secondary;
lhpte.dw0.dw0.bolted = bolted;
lhpte.dw0.dw0.v = 1;
lhpte.v = (va >> 23) << HPTE_V_AVPN_SHIFT | vflags | HPTE_V_VALID;
lhpte.r = (physRpn_to_absRpn(prpn) << HPTE_R_RPN_SHIFT) | rflags;

/* Now fill in the actual HPTE */
HvCallHpt_addValidate(slot, secondary, &lhpte);
Expand All @@ -88,31 +83,27 @@ static long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va,

static unsigned long iSeries_hpte_getword0(unsigned long slot)
{
unsigned long dword0;
HPTE hpte;
hpte_t hpte;

HvCallHpt_get(&hpte, slot);
dword0 = hpte.dw0.dword0;

return dword0;
return hpte.v;
}

static long iSeries_hpte_remove(unsigned long hpte_group)
{
unsigned long slot_offset;
int i;
HPTE lhpte;
unsigned long hpte_v;

/* Pick a random slot to start at */
slot_offset = mftb() & 0x7;

iSeries_hlock(hpte_group);

for (i = 0; i < HPTES_PER_GROUP; i++) {
lhpte.dw0.dword0 =
iSeries_hpte_getword0(hpte_group + slot_offset);
hpte_v = iSeries_hpte_getword0(hpte_group + slot_offset);

if (!lhpte.dw0.dw0.bolted) {
if (! (hpte_v & HPTE_V_BOLTED)) {
HvCallHpt_invalidateSetSwBitsGet(hpte_group +
slot_offset, 0, 0);
iSeries_hunlock(hpte_group);
Expand All @@ -137,13 +128,13 @@ static long iSeries_hpte_remove(unsigned long hpte_group)
static long iSeries_hpte_updatepp(unsigned long slot, unsigned long newpp,
unsigned long va, int large, int local)
{
HPTE hpte;
hpte_t hpte;
unsigned long avpn = va >> 23;

iSeries_hlock(slot);

HvCallHpt_get(&hpte, slot);
if ((hpte.dw0.dw0.avpn == avpn) && (hpte.dw0.dw0.v)) {
if ((HPTE_V_AVPN_VAL(hpte.v) == avpn) && (hpte.v & HPTE_V_VALID)) {
/*
* Hypervisor expects bits as NPPP, which is
* different from how they are mapped in our PP.
Expand All @@ -167,7 +158,7 @@ static long iSeries_hpte_updatepp(unsigned long slot, unsigned long newpp,
*/
static long iSeries_hpte_find(unsigned long vpn)
{
HPTE hpte;
hpte_t hpte;
long slot;

/*
Expand All @@ -177,7 +168,7 @@ static long iSeries_hpte_find(unsigned long vpn)
* 0x80000000xxxxxxxx : Entry found in secondary group, slot x
*/
slot = HvCallHpt_findValid(&hpte, vpn);
if (hpte.dw0.dw0.v) {
if (hpte.v & HPTE_V_VALID) {
if (slot < 0) {
slot &= 0x7fffffffffffffff;
slot = -slot;
Expand Down Expand Up @@ -212,17 +203,17 @@ static void iSeries_hpte_updateboltedpp(unsigned long newpp, unsigned long ea)
static void iSeries_hpte_invalidate(unsigned long slot, unsigned long va,
int large, int local)
{
HPTE lhpte;
unsigned long hpte_v;
unsigned long avpn = va >> 23;
unsigned long flags;

local_irq_save(flags);

iSeries_hlock(slot);

lhpte.dw0.dword0 = iSeries_hpte_getword0(slot);
hpte_v = iSeries_hpte_getword0(slot);

if ((lhpte.dw0.dw0.avpn == avpn) && lhpte.dw0.dw0.v)
if ((HPTE_V_AVPN_VAL(hpte_v) == avpn) && (hpte_v & HPTE_V_VALID))
HvCallHpt_invalidateSetSwBitsGet(slot, 0, 0);

iSeries_hunlock(slot);
Expand Down
18 changes: 8 additions & 10 deletions arch/ppc64/kernel/iSeries_setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ static void __init build_iSeries_Memory_Map(void)

/* Fill in the hashed page table hash mask */
num_ptegs = hptSizePages *
(PAGE_SIZE / (sizeof(HPTE) * HPTES_PER_GROUP));
(PAGE_SIZE / (sizeof(hpte_t) * HPTES_PER_GROUP));
htab_hash_mask = num_ptegs - 1;

/*
Expand Down Expand Up @@ -618,25 +618,23 @@ static void __init setup_iSeries_cache_sizes(void)
static void iSeries_make_pte(unsigned long va, unsigned long pa,
int mode)
{
HPTE local_hpte, rhpte;
hpte_t local_hpte, rhpte;
unsigned long hash, vpn;
long slot;

vpn = va >> PAGE_SHIFT;
hash = hpt_hash(vpn, 0);

local_hpte.dw1.dword1 = pa | mode;
local_hpte.dw0.dword0 = 0;
local_hpte.dw0.dw0.avpn = va >> 23;
local_hpte.dw0.dw0.bolted = 1; /* bolted */
local_hpte.dw0.dw0.v = 1;
local_hpte.r = pa | mode;
local_hpte.v = ((va >> 23) << HPTE_V_AVPN_SHIFT)
| HPTE_V_BOLTED | HPTE_V_VALID;

slot = HvCallHpt_findValid(&rhpte, vpn);
if (slot < 0) {
/* Must find space in primary group */
panic("hash_page: hpte already exists\n");
}
HvCallHpt_addValidate(slot, 0, (HPTE *)&local_hpte );
HvCallHpt_addValidate(slot, 0, &local_hpte);
}

/*
Expand All @@ -646,7 +644,7 @@ static void __init iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr)
{
unsigned long pa;
unsigned long mode_rw = _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX;
HPTE hpte;
hpte_t hpte;

for (pa = saddr; pa < eaddr ;pa += PAGE_SIZE) {
unsigned long ea = (unsigned long)__va(pa);
Expand All @@ -659,7 +657,7 @@ static void __init iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr)
if (!in_kernel_text(ea))
mode_rw |= HW_NO_EXEC;

if (hpte.dw0.dw0.v) {
if (hpte.v & HPTE_V_VALID) {
/* HPTE exists, so just bolt it */
HvCallHpt_setSwBits(slot, 0x10, 0);
/* And make sure the pp bits are correct */
Expand Down
47 changes: 16 additions & 31 deletions arch/ppc64/kernel/pSeries_lpar.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,31 +277,20 @@ void vpa_init(int cpu)

long pSeries_lpar_hpte_insert(unsigned long hpte_group,
unsigned long va, unsigned long prpn,
int secondary, unsigned long hpteflags,
int bolted, int large)
unsigned long vflags, unsigned long rflags)
{
unsigned long arpn = physRpn_to_absRpn(prpn);
unsigned long lpar_rc;
unsigned long flags;
unsigned long slot;
HPTE lhpte;
unsigned long hpte_v, hpte_r;
unsigned long dummy0, dummy1;

/* Fill in the local HPTE with absolute rpn, avpn and flags */
lhpte.dw1.dword1 = 0;
lhpte.dw1.dw1.rpn = arpn;
lhpte.dw1.flags.flags = hpteflags;
hpte_v = ((va >> 23) << HPTE_V_AVPN_SHIFT) | vflags | HPTE_V_VALID;
if (vflags & HPTE_V_LARGE)
hpte_v &= ~(1UL << HPTE_V_AVPN_SHIFT);

lhpte.dw0.dword0 = 0;
lhpte.dw0.dw0.avpn = va >> 23;
lhpte.dw0.dw0.h = secondary;
lhpte.dw0.dw0.bolted = bolted;
lhpte.dw0.dw0.v = 1;

if (large) {
lhpte.dw0.dw0.l = 1;
lhpte.dw0.dw0.avpn &= ~0x1UL;
}
hpte_r = (arpn << HPTE_R_RPN_SHIFT) | rflags;

/* Now fill in the actual HPTE */
/* Set CEC cookie to 0 */
Expand All @@ -312,11 +301,11 @@ long pSeries_lpar_hpte_insert(unsigned long hpte_group,
flags = 0;

/* XXX why is this here? - Anton */
if (hpteflags & (_PAGE_GUARDED|_PAGE_NO_CACHE))
lhpte.dw1.flags.flags &= ~_PAGE_COHERENT;
if (rflags & (_PAGE_GUARDED|_PAGE_NO_CACHE))
hpte_r &= ~_PAGE_COHERENT;

lpar_rc = plpar_hcall(H_ENTER, flags, hpte_group, lhpte.dw0.dword0,
lhpte.dw1.dword1, &slot, &dummy0, &dummy1);
lpar_rc = plpar_hcall(H_ENTER, flags, hpte_group, hpte_v,
hpte_r, &slot, &dummy0, &dummy1);

if (unlikely(lpar_rc == H_PTEG_Full))
return -1;
Expand All @@ -332,7 +321,7 @@ long pSeries_lpar_hpte_insert(unsigned long hpte_group,
/* Because of iSeries, we have to pass down the secondary
* bucket bit here as well
*/
return (slot & 7) | (secondary << 3);
return (slot & 7) | (!!(vflags & HPTE_V_SECONDARY) << 3);
}

static DEFINE_SPINLOCK(pSeries_lpar_tlbie_lock);
Expand Down Expand Up @@ -427,22 +416,18 @@ static long pSeries_lpar_hpte_find(unsigned long vpn)
unsigned long hash;
unsigned long i, j;
long slot;
union {
unsigned long dword0;
Hpte_dword0 dw0;
} hpte_dw0;
Hpte_dword0 dw0;
unsigned long hpte_v;

hash = hpt_hash(vpn, 0);

for (j = 0; j < 2; j++) {
slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
for (i = 0; i < HPTES_PER_GROUP; i++) {
hpte_dw0.dword0 = pSeries_lpar_hpte_getword0(slot);
dw0 = hpte_dw0.dw0;
hpte_v = pSeries_lpar_hpte_getword0(slot);

if ((dw0.avpn == (vpn >> 11)) && dw0.v &&
(dw0.h == j)) {
if ((HPTE_V_AVPN_VAL(hpte_v) == (vpn >> 11))
&& (hpte_v & HPTE_V_VALID)
&& (!!(hpte_v & HPTE_V_SECONDARY) == j)) {
/* HPTE matches */
if (j)
slot = -slot;
Expand Down
8 changes: 2 additions & 6 deletions arch/ppc64/mm/hash_low.S
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,7 @@ htab_insert_pte:
/* Call ppc_md.hpte_insert */
ld r7,STK_PARM(r4)(r1) /* Retreive new pp bits */
mr r4,r29 /* Retreive va */
li r6,0 /* primary slot */
li r8,0 /* not bolted and not large */
li r9,0
li r6,0 /* no vflags */
_GLOBAL(htab_call_hpte_insert1)
bl . /* Will be patched by htab_finish_init() */
cmpdi 0,r3,0
Expand All @@ -192,9 +190,7 @@ _GLOBAL(htab_call_hpte_insert1)
/* Call ppc_md.hpte_insert */
ld r7,STK_PARM(r4)(r1) /* Retreive new pp bits */
mr r4,r29 /* Retreive va */
li r6,1 /* secondary slot */
li r8,0 /* not bolted and not large */
li r9,0
li r6,HPTE_V_SECONDARY@l /* secondary slot */
_GLOBAL(htab_call_hpte_insert2)
bl . /* Will be patched by htab_finish_init() */
cmpdi 0,r3,0
Expand Down
Loading

0 comments on commit 96e2844

Please sign in to comment.