Skip to content

Commit

Permalink
[S390] store indication fault optimization
Browse files Browse the repository at this point in the history
Use the store indication bit in the translation exception code on
page faults to avoid the protection faults that immediatly follow
the page fault if the access has been a write.

Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
  • Loading branch information
Martin Schwidefsky authored and Martin Schwidefsky committed Oct 25, 2010
1 parent 6931be0 commit 92f842e
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 3 deletions.
1 change: 1 addition & 0 deletions arch/s390/include/asm/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
extern pgd_t swapper_pg_dir[] __attribute__ ((aligned (4096)));
extern void paging_init(void);
extern void vmem_map_init(void);
extern void fault_init(void);

/*
* The S390 doesn't have any external MMU info: the kernel page
Expand Down
21 changes: 18 additions & 3 deletions arch/s390/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,19 @@
#define VM_FAULT_BADMAP 0x020000
#define VM_FAULT_BADACCESS 0x040000

static unsigned long store_indication;

void fault_init(void)
{
unsigned long long facility_list[2];

if (stfle(facility_list, 2) < 2)
return;
if ((facility_list[0] & (1ULL << 61)) &&
(facility_list[1] & (1ULL << 52)))
store_indication = 0xc00;
}

static inline int notify_page_fault(struct pt_regs *regs)
{
int ret = 0;
Expand Down Expand Up @@ -294,7 +307,7 @@ static inline int do_exception(struct pt_regs *regs, int access,
struct mm_struct *mm;
struct vm_area_struct *vma;
unsigned long address;
int fault;
int fault, write;

if (notify_page_fault(regs))
return 0;
Expand Down Expand Up @@ -348,8 +361,10 @@ static inline int do_exception(struct pt_regs *regs, int access,
* make sure we exit gracefully rather than endlessly redo
* the fault.
*/
fault = handle_mm_fault(mm, vma, address,
(access == VM_WRITE) ? FAULT_FLAG_WRITE : 0);
write = (access == VM_WRITE ||
(trans_exc_code & store_indication) == 0x400) ?
FAULT_FLAG_WRITE : 0;
fault = handle_mm_fault(mm, vma, address, write);
if (unlikely(fault & VM_FAULT_ERROR))
goto out_up;

Expand Down
1 change: 1 addition & 0 deletions arch/s390/mm/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ void __init paging_init(void)
#endif
max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
free_area_init_nodes(max_zone_pfns);
fault_init();
}

void __init mem_init(void)
Expand Down

0 comments on commit 92f842e

Please sign in to comment.