Commit 92f842ea authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Martin Schwidefsky

[S390] store indication fault optimization

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: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 6931be08
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
extern pgd_t swapper_pg_dir[] __attribute__ ((aligned (4096))); extern pgd_t swapper_pg_dir[] __attribute__ ((aligned (4096)));
extern void paging_init(void); extern void paging_init(void);
extern void vmem_map_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 * The S390 doesn't have any external MMU info: the kernel page
......
...@@ -52,6 +52,19 @@ ...@@ -52,6 +52,19 @@
#define VM_FAULT_BADMAP 0x020000 #define VM_FAULT_BADMAP 0x020000
#define VM_FAULT_BADACCESS 0x040000 #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) static inline int notify_page_fault(struct pt_regs *regs)
{ {
int ret = 0; int ret = 0;
...@@ -294,7 +307,7 @@ static inline int do_exception(struct pt_regs *regs, int access, ...@@ -294,7 +307,7 @@ static inline int do_exception(struct pt_regs *regs, int access,
struct mm_struct *mm; struct mm_struct *mm;
struct vm_area_struct *vma; struct vm_area_struct *vma;
unsigned long address; unsigned long address;
int fault; int fault, write;
if (notify_page_fault(regs)) if (notify_page_fault(regs))
return 0; return 0;
...@@ -348,8 +361,10 @@ static inline int do_exception(struct pt_regs *regs, int access, ...@@ -348,8 +361,10 @@ static inline int do_exception(struct pt_regs *regs, int access,
* make sure we exit gracefully rather than endlessly redo * make sure we exit gracefully rather than endlessly redo
* the fault. * the fault.
*/ */
fault = handle_mm_fault(mm, vma, address, write = (access == VM_WRITE ||
(access == VM_WRITE) ? FAULT_FLAG_WRITE : 0); (trans_exc_code & store_indication) == 0x400) ?
FAULT_FLAG_WRITE : 0;
fault = handle_mm_fault(mm, vma, address, write);
if (unlikely(fault & VM_FAULT_ERROR)) if (unlikely(fault & VM_FAULT_ERROR))
goto out_up; goto out_up;
......
...@@ -124,6 +124,7 @@ void __init paging_init(void) ...@@ -124,6 +124,7 @@ void __init paging_init(void)
#endif #endif
max_zone_pfns[ZONE_NORMAL] = max_low_pfn; max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
free_area_init_nodes(max_zone_pfns); free_area_init_nodes(max_zone_pfns);
fault_init();
} }
void __init mem_init(void) void __init mem_init(void)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment