|
@@ -50,6 +50,7 @@
|
|
|
#define VM_FAULT_BADMAP 0x020000
|
|
|
#define VM_FAULT_BADACCESS 0x040000
|
|
|
#define VM_FAULT_SIGNAL 0x080000
|
|
|
+#define VM_FAULT_PFAULT 0x100000
|
|
|
|
|
|
static unsigned long store_indication __read_mostly;
|
|
|
|
|
@@ -227,6 +228,7 @@ static noinline void do_fault_error(struct pt_regs *regs, int fault)
|
|
|
return;
|
|
|
}
|
|
|
case VM_FAULT_BADCONTEXT:
|
|
|
+ case VM_FAULT_PFAULT:
|
|
|
do_no_context(regs);
|
|
|
break;
|
|
|
case VM_FAULT_SIGNAL:
|
|
@@ -264,6 +266,9 @@ static noinline void do_fault_error(struct pt_regs *regs, int fault)
|
|
|
*/
|
|
|
static inline int do_exception(struct pt_regs *regs, int access)
|
|
|
{
|
|
|
+#ifdef CONFIG_PGSTE
|
|
|
+ struct gmap *gmap;
|
|
|
+#endif
|
|
|
struct task_struct *tsk;
|
|
|
struct mm_struct *mm;
|
|
|
struct vm_area_struct *vma;
|
|
@@ -304,9 +309,10 @@ static inline int do_exception(struct pt_regs *regs, int access)
|
|
|
down_read(&mm->mmap_sem);
|
|
|
|
|
|
#ifdef CONFIG_PGSTE
|
|
|
- if ((current->flags & PF_VCPU) && S390_lowcore.gmap) {
|
|
|
- address = __gmap_fault(address,
|
|
|
- (struct gmap *) S390_lowcore.gmap);
|
|
|
+ gmap = (struct gmap *)
|
|
|
+ ((current->flags & PF_VCPU) ? S390_lowcore.gmap : 0);
|
|
|
+ if (gmap) {
|
|
|
+ address = __gmap_fault(address, gmap);
|
|
|
if (address == -EFAULT) {
|
|
|
fault = VM_FAULT_BADMAP;
|
|
|
goto out_up;
|
|
@@ -315,6 +321,8 @@ static inline int do_exception(struct pt_regs *regs, int access)
|
|
|
fault = VM_FAULT_OOM;
|
|
|
goto out_up;
|
|
|
}
|
|
|
+ if (gmap->pfault_enabled)
|
|
|
+ flags |= FAULT_FLAG_RETRY_NOWAIT;
|
|
|
}
|
|
|
#endif
|
|
|
|
|
@@ -371,9 +379,19 @@ retry:
|
|
|
regs, address);
|
|
|
}
|
|
|
if (fault & VM_FAULT_RETRY) {
|
|
|
+#ifdef CONFIG_PGSTE
|
|
|
+ if (gmap && (flags & FAULT_FLAG_RETRY_NOWAIT)) {
|
|
|
+ /* FAULT_FLAG_RETRY_NOWAIT has been set,
|
|
|
+ * mmap_sem has not been released */
|
|
|
+ current->thread.gmap_pfault = 1;
|
|
|
+ fault = VM_FAULT_PFAULT;
|
|
|
+ goto out_up;
|
|
|
+ }
|
|
|
+#endif
|
|
|
/* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk
|
|
|
* of starvation. */
|
|
|
- flags &= ~FAULT_FLAG_ALLOW_RETRY;
|
|
|
+ flags &= ~(FAULT_FLAG_ALLOW_RETRY |
|
|
|
+ FAULT_FLAG_RETRY_NOWAIT);
|
|
|
flags |= FAULT_FLAG_TRIED;
|
|
|
down_read(&mm->mmap_sem);
|
|
|
goto retry;
|