Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 201195
b: refs/heads/master
c: 7ffb65f
h: refs/heads/master
i:
  201193: 27cc6d0
  201191: 48afc4c
v: v3
  • Loading branch information
Benjamin Herrenschmidt committed Jul 23, 2010
1 parent 5119b27 commit def5c55
Show file tree
Hide file tree
Showing 35 changed files with 243 additions and 112 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 23dcab8f8e89bb25d7e156ffec4b27542d1f737a
refs/heads/master: 7ffb65f84bd3852e4906c43b9e84dcc4e4d72d14
2 changes: 1 addition & 1 deletion trunk/Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 35
EXTRAVERSION = -rc5
EXTRAVERSION = -rc6
NAME = Sheep on Meth

# *DOCUMENTATION*
Expand Down
17 changes: 14 additions & 3 deletions trunk/arch/arm/mach-omap2/board-rx51-peripherals.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,13 +175,18 @@ static void __init rx51_add_gpio_keys(void)
#endif /* CONFIG_KEYBOARD_GPIO || CONFIG_KEYBOARD_GPIO_MODULE */

static int board_keymap[] = {
/*
* Note that KEY(x, 8, KEY_XXX) entries represent "entrire row
* connected to the ground" matrix state.
*/
KEY(0, 0, KEY_Q),
KEY(0, 1, KEY_O),
KEY(0, 2, KEY_P),
KEY(0, 3, KEY_COMMA),
KEY(0, 4, KEY_BACKSPACE),
KEY(0, 6, KEY_A),
KEY(0, 7, KEY_S),

KEY(1, 0, KEY_W),
KEY(1, 1, KEY_D),
KEY(1, 2, KEY_F),
Expand All @@ -190,13 +195,16 @@ static int board_keymap[] = {
KEY(1, 5, KEY_J),
KEY(1, 6, KEY_K),
KEY(1, 7, KEY_L),

KEY(2, 0, KEY_E),
KEY(2, 1, KEY_DOT),
KEY(2, 2, KEY_UP),
KEY(2, 3, KEY_ENTER),
KEY(2, 5, KEY_Z),
KEY(2, 6, KEY_X),
KEY(2, 7, KEY_C),
KEY(2, 8, KEY_F9),

KEY(3, 0, KEY_R),
KEY(3, 1, KEY_V),
KEY(3, 2, KEY_B),
Expand All @@ -205,20 +213,23 @@ static int board_keymap[] = {
KEY(3, 5, KEY_SPACE),
KEY(3, 6, KEY_SPACE),
KEY(3, 7, KEY_LEFT),

KEY(4, 0, KEY_T),
KEY(4, 1, KEY_DOWN),
KEY(4, 2, KEY_RIGHT),
KEY(4, 4, KEY_LEFTCTRL),
KEY(4, 5, KEY_RIGHTALT),
KEY(4, 6, KEY_LEFTSHIFT),
KEY(4, 8, KEY_10),

KEY(5, 0, KEY_Y),
KEY(5, 8, KEY_11),

KEY(6, 0, KEY_U),

KEY(7, 0, KEY_I),
KEY(7, 1, KEY_F7),
KEY(7, 2, KEY_F8),
KEY(0xff, 2, KEY_F9),
KEY(0xff, 4, KEY_F10),
KEY(0xff, 5, KEY_F11),
};

static struct matrix_keymap_data board_map_data = {
Expand Down
4 changes: 3 additions & 1 deletion trunk/arch/powerpc/include/asm/mmu-hash64.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,9 @@ extern int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
pte_t *ptep, unsigned long trap, int local, int ssize,
unsigned int shift, unsigned int mmu_psize);

extern void hash_failure_debug(unsigned long ea, unsigned long access,
unsigned long vsid, unsigned long trap,
int ssize, int psize, unsigned long pte);
extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
unsigned long pstart, unsigned long prot,
int psize, int ssize);
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/powerpc/kernel/prom.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ static int __init early_init_dt_scan_drconf_memory(unsigned long node)
u64 base, size, memblock_size;
unsigned int is_kexec_kdump = 0, rngs;

ls = of_get_flat_dt_prop(node, "ibm,memblock-size", &l);
ls = of_get_flat_dt_prop(node, "ibm,lmb-size", &l);
if (ls == NULL || l < dt_root_size_cells * sizeof(__be32))
return 0;
memblock_size = dt_mem_next_cell(dt_root_size_cells, &ls);
Expand Down
9 changes: 0 additions & 9 deletions trunk/arch/powerpc/mm/hash_low_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,6 @@ _GLOBAL(__hash_page_4K)
std r8,STK_PARM(r8)(r1)
std r9,STK_PARM(r9)(r1)

/* Add _PAGE_PRESENT to access */
ori r4,r4,_PAGE_PRESENT

/* Save non-volatile registers.
* r31 will hold "old PTE"
* r30 is "new PTE"
Expand Down Expand Up @@ -347,9 +344,6 @@ _GLOBAL(__hash_page_4K)
std r8,STK_PARM(r8)(r1)
std r9,STK_PARM(r9)(r1)

/* Add _PAGE_PRESENT to access */
ori r4,r4,_PAGE_PRESENT

/* Save non-volatile registers.
* r31 will hold "old PTE"
* r30 is "new PTE"
Expand Down Expand Up @@ -687,9 +681,6 @@ _GLOBAL(__hash_page_64K)
std r8,STK_PARM(r8)(r1)
std r9,STK_PARM(r9)(r1)

/* Add _PAGE_PRESENT to access */
ori r4,r4,_PAGE_PRESENT

/* Save non-volatile registers.
* r31 will hold "old PTE"
* r30 is "new PTE"
Expand Down
53 changes: 40 additions & 13 deletions trunk/arch/powerpc/mm/hash_utils_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -871,6 +871,18 @@ static inline int subpage_protection(struct mm_struct *mm, unsigned long ea)
}
#endif

void hash_failure_debug(unsigned long ea, unsigned long access,
unsigned long vsid, unsigned long trap,
int ssize, int psize, unsigned long pte)
{
if (!printk_ratelimit())
return;
pr_info("mm: Hashing failure ! EA=0x%lx access=0x%lx current=%s\n",
ea, access, current->comm);
pr_info(" trap=0x%lx vsid=0x%lx ssize=%d psize=%d pte=0x%lx\n",
trap, vsid, ssize, psize, pte);
}

/* Result code is:
* 0 - handled
* 1 - normal page fault
Expand Down Expand Up @@ -955,6 +967,17 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
return 1;
}

/* Add _PAGE_PRESENT to the required access perm */
access |= _PAGE_PRESENT;

/* Pre-check access permissions (will be re-checked atomically
* in __hash_page_XX but this pre-check is a fast path
*/
if (access & ~pte_val(*ptep)) {
DBG_LOW(" no access !\n");
return 1;
}

#ifdef CONFIG_HUGETLB_PAGE
if (hugeshift)
return __hash_page_huge(ea, access, vsid, ptep, trap, local,
Expand All @@ -967,14 +990,6 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
DBG_LOW(" i-pte: %016lx %016lx\n", pte_val(*ptep),
pte_val(*(ptep + PTRS_PER_PTE)));
#endif
/* Pre-check access permissions (will be re-checked atomically
* in __hash_page_XX but this pre-check is a fast path
*/
if (access & ~pte_val(*ptep)) {
DBG_LOW(" no access !\n");
return 1;
}

/* Do actual hashing */
#ifdef CONFIG_PPC_64K_PAGES
/* If _PAGE_4K_PFN is set, make sure this is a 4k segment */
Expand Down Expand Up @@ -1033,6 +1048,12 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
local, ssize, spp);
}

/* Dump some info in case of hash insertion failure, they should
* never happen so it is really useful to know if/when they do
*/
if (rc == -1)
hash_failure_debug(ea, access, vsid, trap, ssize, psize,
pte_val(*ptep));
#ifndef CONFIG_PPC_64K_PAGES
DBG_LOW(" o-pte: %016lx\n", pte_val(*ptep));
#else
Expand All @@ -1051,8 +1072,7 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,
void *pgdir;
pte_t *ptep;
unsigned long flags;
int local = 0;
int ssize;
int rc, ssize, local = 0;

BUG_ON(REGION_ID(ea) != USER_REGION_ID);

Expand Down Expand Up @@ -1098,11 +1118,18 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,
/* Hash it in */
#ifdef CONFIG_PPC_HAS_HASH_64K
if (mm->context.user_psize == MMU_PAGE_64K)
__hash_page_64K(ea, access, vsid, ptep, trap, local, ssize);
rc = __hash_page_64K(ea, access, vsid, ptep, trap, local, ssize);
else
#endif /* CONFIG_PPC_HAS_HASH_64K */
__hash_page_4K(ea, access, vsid, ptep, trap, local, ssize,
subpage_protection(pgdir, ea));
rc = __hash_page_4K(ea, access, vsid, ptep, trap, local, ssize,
subpage_protection(pgdir, ea));

/* Dump some info in case of hash insertion failure, they should
* never happen so it is really useful to know if/when they do
*/
if (rc == -1)
hash_failure_debug(ea, access, vsid, trap, ssize,
mm->context.user_psize, pte_val(*ptep));

local_irq_restore(flags);
}
Expand Down
40 changes: 22 additions & 18 deletions trunk/arch/powerpc/mm/hugetlbpage-hash64.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,13 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
unsigned long old_pte, new_pte;
unsigned long va, rflags, pa, sz;
long slot;
int err = 1;

BUG_ON(shift != mmu_psize_defs[mmu_psize].shift);

/* Search the Linux page table for a match with va */
va = hpt_va(ea, vsid, ssize);

/*
* Check the user's access rights to the page. If access should be
* prevented then send the problem up to do_page_fault.
*/
if (unlikely(access & ~pte_val(*ptep)))
goto out;
/*
* At this point, we have a pte (old_pte) which can be used to build
/* At this point, we have a pte (old_pte) which can be used to build
* or update an HPTE. There are 2 cases:
*
* 1. There is a valid (present) pte with no associated HPTE (this is
Expand All @@ -49,9 +41,17 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,

do {
old_pte = pte_val(*ptep);
if (old_pte & _PAGE_BUSY)
goto out;
/* If PTE busy, retry the access */
if (unlikely(old_pte & _PAGE_BUSY))
return 0;
/* If PTE permissions don't match, take page fault */
if (unlikely(access & ~old_pte))
return 1;
/* Try to lock the PTE, add ACCESSED and DIRTY if it was
* a write access */
new_pte = old_pte | _PAGE_BUSY | _PAGE_ACCESSED;
if (access & _PAGE_RW)
new_pte |= _PAGE_DIRTY;
} while(old_pte != __cmpxchg_u64((unsigned long *)ptep,
old_pte, new_pte));

Expand Down Expand Up @@ -121,8 +121,16 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
}
}

if (unlikely(slot == -2))
panic("hash_huge_page: pte_insert failed\n");
/*
* Hypervisor failure. Restore old pte and return -1
* similar to __hash_page_*
*/
if (unlikely(slot == -2)) {
*ptep = __pte(old_pte);
hash_failure_debug(ea, access, vsid, trap, ssize,
mmu_psize, old_pte);
return -1;
}

new_pte |= (slot << 12) & (_PAGE_F_SECOND | _PAGE_F_GIX);
}
Expand All @@ -131,9 +139,5 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
* No need to use ldarx/stdcx here
*/
*ptep = __pte(new_pte & ~_PAGE_BUSY);

err = 0;

out:
return err;
return 0;
}
24 changes: 12 additions & 12 deletions trunk/arch/powerpc/mm/numa.c
Original file line number Diff line number Diff line change
Expand Up @@ -398,15 +398,15 @@ static int of_get_drconf_memory(struct device_node *memory, const u32 **dm)
}

/*
* Retreive and validate the ibm,memblock-size property for drconf memory
* Retreive and validate the ibm,lmb-size property for drconf memory
* from the device tree.
*/
static u64 of_get_memblock_size(struct device_node *memory)
static u64 of_get_lmb_size(struct device_node *memory)
{
const u32 *prop;
u32 len;

prop = of_get_property(memory, "ibm,memblock-size", &len);
prop = of_get_property(memory, "ibm,lmb-size", &len);
if (!prop || len < sizeof(unsigned int))
return 0;

Expand Down Expand Up @@ -562,7 +562,7 @@ static unsigned long __init numa_enforce_memory_limit(unsigned long start,
static inline int __init read_usm_ranges(const u32 **usm)
{
/*
* For each memblock in ibm,dynamic-memory a corresponding
* For each lmb in ibm,dynamic-memory a corresponding
* entry in linux,drconf-usable-memory property contains
* a counter followed by that many (base, size) duple.
* read the counter from linux,drconf-usable-memory
Expand All @@ -578,16 +578,16 @@ static void __init parse_drconf_memory(struct device_node *memory)
{
const u32 *dm, *usm;
unsigned int n, rc, ranges, is_kexec_kdump = 0;
unsigned long memblock_size, base, size, sz;
unsigned long lmb_size, base, size, sz;
int nid;
struct assoc_arrays aa;

n = of_get_drconf_memory(memory, &dm);
if (!n)
return;

memblock_size = of_get_memblock_size(memory);
if (!memblock_size)
lmb_size = of_get_lmb_size(memory);
if (!lmb_size)
return;

rc = of_get_assoc_arrays(memory, &aa);
Expand All @@ -611,7 +611,7 @@ static void __init parse_drconf_memory(struct device_node *memory)
continue;

base = drmem.base_addr;
size = memblock_size;
size = lmb_size;
ranges = 1;

if (is_kexec_kdump) {
Expand Down Expand Up @@ -1072,16 +1072,16 @@ static int hot_add_drconf_scn_to_nid(struct device_node *memory,
{
const u32 *dm;
unsigned int drconf_cell_cnt, rc;
unsigned long memblock_size;
unsigned long lmb_size;
struct assoc_arrays aa;
int nid = -1;

drconf_cell_cnt = of_get_drconf_memory(memory, &dm);
if (!drconf_cell_cnt)
return -1;

memblock_size = of_get_memblock_size(memory);
if (!memblock_size)
lmb_size = of_get_lmb_size(memory);
if (!lmb_size)
return -1;

rc = of_get_assoc_arrays(memory, &aa);
Expand All @@ -1100,7 +1100,7 @@ static int hot_add_drconf_scn_to_nid(struct device_node *memory,
continue;

if ((scn_addr < drmem.base_addr)
|| (scn_addr >= (drmem.base_addr + memblock_size)))
|| (scn_addr >= (drmem.base_addr + lmb_size)))
continue;

nid = of_drconf_to_nid_single(&drmem, &aa);
Expand Down
Loading

0 comments on commit def5c55

Please sign in to comment.