aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/mm/fault.c
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2010-10-25 10:10:13 -0400
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2010-10-25 10:10:15 -0400
commit92f842eac7ee321c8a0749aba2513541b4ac226f (patch)
tree06a9c2302729ecd6d2941f8629da1646c11c714c /arch/s390/mm/fault.c
parent6931be0803ddae2791f3c646c8e1e0f82ca26013 (diff)
[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: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/mm/fault.c')
-rw-r--r--arch/s390/mm/fault.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 2505b2ea0ef..b49d12073f1 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -52,6 +52,19 @@
52#define VM_FAULT_BADMAP 0x020000 52#define VM_FAULT_BADMAP 0x020000
53#define VM_FAULT_BADACCESS 0x040000 53#define VM_FAULT_BADACCESS 0x040000
54 54
55static unsigned long store_indication;
56
57void fault_init(void)
58{
59 unsigned long long facility_list[2];
60
61 if (stfle(facility_list, 2) < 2)
62 return;
63 if ((facility_list[0] & (1ULL << 61)) &&
64 (facility_list[1] & (1ULL << 52)))
65 store_indication = 0xc00;
66}
67
55static inline int notify_page_fault(struct pt_regs *regs) 68static inline int notify_page_fault(struct pt_regs *regs)
56{ 69{
57 int ret = 0; 70 int ret = 0;
@@ -294,7 +307,7 @@ static inline int do_exception(struct pt_regs *regs, int access,
294 struct mm_struct *mm; 307 struct mm_struct *mm;
295 struct vm_area_struct *vma; 308 struct vm_area_struct *vma;
296 unsigned long address; 309 unsigned long address;
297 int fault; 310 int fault, write;
298 311
299 if (notify_page_fault(regs)) 312 if (notify_page_fault(regs))
300 return 0; 313 return 0;
@@ -348,8 +361,10 @@ static inline int do_exception(struct pt_regs *regs, int access,
348 * make sure we exit gracefully rather than endlessly redo 361 * make sure we exit gracefully rather than endlessly redo
349 * the fault. 362 * the fault.
350 */ 363 */
351 fault = handle_mm_fault(mm, vma, address, 364 write = (access == VM_WRITE ||
352 (access == VM_WRITE) ? FAULT_FLAG_WRITE : 0); 365 (trans_exc_code & store_indication) == 0x400) ?
366 FAULT_FLAG_WRITE : 0;
367 fault = handle_mm_fault(mm, vma, address, write);
353 if (unlikely(fault & VM_FAULT_ERROR)) 368 if (unlikely(fault & VM_FAULT_ERROR))
354 goto out_up; 369 goto out_up;
355 370