Re: SIGBUS short mmap object

2017-07-20 Thread Mark Kettenis
> Date: Thu, 20 Jul 2017 18:18:58 +0200
> From: Alexander Bluhm 
> 
> On Thu, Jul 20, 2017 at 02:03:10PM +0200, Mark Kettenis wrote:
> > If you can make the BUS_ADRERR -> BUS_OBJERR change (both here and in
> > the regress test), this is ok kettenis@
> 
> This passes on amd64 and i386.
> 
> ok?

ok kettenis@

The man page will need some further tweaking once other architectures
catch up.

> Index: sys/arch/amd64/amd64/trap.c
> ===
> RCS file: /data/mirror/openbsd/cvs/src/sys/arch/amd64/amd64/trap.c,v
> retrieving revision 1.55
> diff -u -p -r1.55 trap.c
> --- sys/arch/amd64/amd64/trap.c   14 Jul 2017 12:20:32 -  1.55
> +++ sys/arch/amd64/amd64/trap.c   20 Jul 2017 15:59:37 -
> @@ -306,6 +306,7 @@ copyfault:
>   struct vm_map *map;
>   vm_prot_t ftype;
>   extern struct vm_map *kernel_map;
> + int signal, sicode;
>  
>   cr2 = rcr2();
>   KERNEL_LOCK();
> @@ -372,12 +373,14 @@ faultcommon:
>   map, fa, ftype, error);
>   goto we_re_toast;
>   }
> +
> + signal = SIGSEGV;
> + sicode = SEGV_MAPERR;
>   if (error == ENOMEM) {
>   printf("UVM: pid %d (%s), uid %d killed:"
>   " out of swap\n", p->p_p->ps_pid, p->p_p->ps_comm,
>   p->p_ucred ? (int)p->p_ucred->cr_uid : -1);
> - sv.sival_ptr = (void *)fa;
> - trapsignal(p, SIGKILL, T_PAGEFLT, SEGV_MAPERR, sv);
> + signal = SIGKILL;
>   } else {
>  #ifdef TRAP_SIGDEBUG
>   printf("pid %d (%s): %s at rip %llx addr %llx\n",
> @@ -385,10 +388,15 @@ faultcommon:
>   frame->tf_rip, rcr2());
>   frame_dump(frame);
>  #endif
> - sv.sival_ptr = (void *)fa;
> - trapsignal(p, SIGSEGV, T_PAGEFLT,
> - error == EACCES ? SEGV_ACCERR : SEGV_MAPERR, sv);
>   }
> + if (error == EACCES)
> + sicode = SEGV_ACCERR;
> + if (error == EIO) {
> + signal = SIGBUS;
> + sicode = BUS_OBJERR;
> + }
> + sv.sival_ptr = (void *)fa;
> + trapsignal(p, signal, T_PAGEFLT, sicode, sv);
>   KERNEL_UNLOCK();
>   break;
>   }
> Index: sys/arch/i386/i386/trap.c
> ===
> RCS file: /data/mirror/openbsd/cvs/src/sys/arch/i386/i386/trap.c,v
> retrieving revision 1.131
> diff -u -p -r1.131 trap.c
> --- sys/arch/i386/i386/trap.c 14 Jul 2017 12:20:32 -  1.131
> +++ sys/arch/i386/i386/trap.c 20 Jul 2017 16:00:16 -
> @@ -374,6 +374,7 @@ trap(struct trapframe *frame)
>   struct vmspace *vm;
>   struct vm_map *map;
>   int error;
> + int signal, sicode;
>  
>   cr2 = rcr2();
>   KERNEL_LOCK();
> @@ -431,9 +432,17 @@ trap(struct trapframe *frame)
>   map, va, ftype, error);
>   goto we_re_toast;
>   }
> +
> + signal = SIGSEGV;
> + sicode = SEGV_MAPERR;
> + if (error == EACCES)
> + sicode = SEGV_ACCERR;
> + if (error == EIO) {
> + signal = SIGBUS;
> + sicode = BUS_OBJERR;
> + }
>   sv.sival_int = fa;
> - trapsignal(p, SIGSEGV, vftype,
> - error == EACCES ? SEGV_ACCERR : SEGV_MAPERR, sv);
> + trapsignal(p, signal, vftype, sicode, sv);
>   KERNEL_UNLOCK();
>   break;
>   }
> Index: sys/uvm/uvm_fault.c
> ===
> RCS file: /data/mirror/openbsd/cvs/src/sys/uvm/uvm_fault.c,v
> retrieving revision 1.91
> diff -u -p -r1.91 uvm_fault.c
> --- sys/uvm/uvm_fault.c   16 Sep 2016 01:09:53 -  1.91
> +++ sys/uvm/uvm_fault.c   20 Jul 2017 15:56:46 -
> @@ -1032,7 +1032,7 @@ Case2:
>   }
>  
>   if (!UVM_ET_ISNOFAULT(ufi.entry))
> - return (EACCES); /* XXX i/o error */
> + return (EIO);
>  
>   uobjpage = PGO_DONTCARE;
>   promote = TRUE;
> Index: regress/sys/kern/siginfo-fault/siginfo-fault.c
> ===
> RCS file: 
> /data/mirror/openbsd/cvs/src/regress/sys/kern/siginfo-fault/siginfo-fault.c,v
> retrieving revision 1.4
> diff -u -p -r1.4 siginfo-fault.c
> --- regress/sys/kern/siginfo-fault/siginfo-fault.c13 Jul 2017 00:29:14 
> -  1.4
> +++ 

Re: SIGBUS short mmap object

2017-07-20 Thread Alexander Bluhm
On Thu, Jul 20, 2017 at 02:03:10PM +0200, Mark Kettenis wrote:
> If you can make the BUS_ADRERR -> BUS_OBJERR change (both here and in
> the regress test), this is ok kettenis@

This passes on amd64 and i386.

ok?

bluhm

Index: sys/arch/amd64/amd64/trap.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/arch/amd64/amd64/trap.c,v
retrieving revision 1.55
diff -u -p -r1.55 trap.c
--- sys/arch/amd64/amd64/trap.c 14 Jul 2017 12:20:32 -  1.55
+++ sys/arch/amd64/amd64/trap.c 20 Jul 2017 15:59:37 -
@@ -306,6 +306,7 @@ copyfault:
struct vm_map *map;
vm_prot_t ftype;
extern struct vm_map *kernel_map;
+   int signal, sicode;
 
cr2 = rcr2();
KERNEL_LOCK();
@@ -372,12 +373,14 @@ faultcommon:
map, fa, ftype, error);
goto we_re_toast;
}
+
+   signal = SIGSEGV;
+   sicode = SEGV_MAPERR;
if (error == ENOMEM) {
printf("UVM: pid %d (%s), uid %d killed:"
" out of swap\n", p->p_p->ps_pid, p->p_p->ps_comm,
p->p_ucred ? (int)p->p_ucred->cr_uid : -1);
-   sv.sival_ptr = (void *)fa;
-   trapsignal(p, SIGKILL, T_PAGEFLT, SEGV_MAPERR, sv);
+   signal = SIGKILL;
} else {
 #ifdef TRAP_SIGDEBUG
printf("pid %d (%s): %s at rip %llx addr %llx\n",
@@ -385,10 +388,15 @@ faultcommon:
frame->tf_rip, rcr2());
frame_dump(frame);
 #endif
-   sv.sival_ptr = (void *)fa;
-   trapsignal(p, SIGSEGV, T_PAGEFLT,
-   error == EACCES ? SEGV_ACCERR : SEGV_MAPERR, sv);
}
+   if (error == EACCES)
+   sicode = SEGV_ACCERR;
+   if (error == EIO) {
+   signal = SIGBUS;
+   sicode = BUS_OBJERR;
+   }
+   sv.sival_ptr = (void *)fa;
+   trapsignal(p, signal, T_PAGEFLT, sicode, sv);
KERNEL_UNLOCK();
break;
}
Index: sys/arch/i386/i386/trap.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/arch/i386/i386/trap.c,v
retrieving revision 1.131
diff -u -p -r1.131 trap.c
--- sys/arch/i386/i386/trap.c   14 Jul 2017 12:20:32 -  1.131
+++ sys/arch/i386/i386/trap.c   20 Jul 2017 16:00:16 -
@@ -374,6 +374,7 @@ trap(struct trapframe *frame)
struct vmspace *vm;
struct vm_map *map;
int error;
+   int signal, sicode;
 
cr2 = rcr2();
KERNEL_LOCK();
@@ -431,9 +432,17 @@ trap(struct trapframe *frame)
map, va, ftype, error);
goto we_re_toast;
}
+
+   signal = SIGSEGV;
+   sicode = SEGV_MAPERR;
+   if (error == EACCES)
+   sicode = SEGV_ACCERR;
+   if (error == EIO) {
+   signal = SIGBUS;
+   sicode = BUS_OBJERR;
+   }
sv.sival_int = fa;
-   trapsignal(p, SIGSEGV, vftype,
-   error == EACCES ? SEGV_ACCERR : SEGV_MAPERR, sv);
+   trapsignal(p, signal, vftype, sicode, sv);
KERNEL_UNLOCK();
break;
}
Index: sys/uvm/uvm_fault.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/uvm/uvm_fault.c,v
retrieving revision 1.91
diff -u -p -r1.91 uvm_fault.c
--- sys/uvm/uvm_fault.c 16 Sep 2016 01:09:53 -  1.91
+++ sys/uvm/uvm_fault.c 20 Jul 2017 15:56:46 -
@@ -1032,7 +1032,7 @@ Case2:
}
 
if (!UVM_ET_ISNOFAULT(ufi.entry))
-   return (EACCES); /* XXX i/o error */
+   return (EIO);
 
uobjpage = PGO_DONTCARE;
promote = TRUE;
Index: regress/sys/kern/siginfo-fault/siginfo-fault.c
===
RCS file: 
/data/mirror/openbsd/cvs/src/regress/sys/kern/siginfo-fault/siginfo-fault.c,v
retrieving revision 1.4
diff -u -p -r1.4 siginfo-fault.c
--- regress/sys/kern/siginfo-fault/siginfo-fault.c  13 Jul 2017 00:29:14 
-  1.4
+++ regress/sys/kern/siginfo-fault/siginfo-fault.c  20 Jul 2017 16:02:42 
-
@@ -156,7 +156,7 @@ main()
p[3] = 1;
FAIL();
}
-   fail += checksig("mmap file", SIGBUS, BUS_ADRERR, p + 3);
+   fail += checksig("mmap file", SIGBUS, BUS_OBJERR, p + 3);
 
return 

Re: SIGBUS short mmap object

2017-07-20 Thread Mark Kettenis
> Date: Mon, 17 Jul 2017 23:36:17 +0200
> From: Alexander Bluhm 
> 
> Hi,
> 
> The tests regress/sys/kern/siginfo-fault accesses an mmap(2)ed file
> behind its end.  Then it expects an SIGBUS, but gets an SIGSEGV.

As you found it, this was a bit controversial.  Theo and I discussed
this and did some software archeology.  I didn't entirely convince
him, but he gave in and won't object to something like this going in.
We both agree that the SIGBUS/SIGSEGV dichotomy is a mess and I think
that given that mess it makes sense to move the posts a bit and get to
a situation where the BUS_XXX and SEGV_XXX codes make a bit more
sense.

> Related commit message is:
> Additionally, SIGBUS/BUS_ADRERR should be generated instead of SIGSEGV
> for access to file mapped pages that exceed the end of the file.
> (Thanks to kettenis@ for suggesting this test.)
> 
> I think this description refers to
> http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html
> Reference to whole pages within the mapping, but beyond the current
> length of the object, shall result in a SIGBUS signal.

It does.  However, instead of SIGBUS/BUS_ADRERR it should
SIGBUS/BUS_OBJERR.

> The attached diff fixes that for amd64 and i386 and the test passes.
> 
> ok?

If you can make the BUS_ADRERR -> BUS_OBJERR change (both here and in
the regress test), this is ok kettenis@

I'll make an effort to make sure the regress test passes on other
architectures as well once this is in.


> Index: arch/amd64/amd64/trap.c
> ===
> RCS file: /data/mirror/openbsd/cvs/src/sys/arch/amd64/amd64/trap.c,v
> retrieving revision 1.55
> diff -u -p -r1.55 trap.c
> --- arch/amd64/amd64/trap.c   14 Jul 2017 12:20:32 -  1.55
> +++ arch/amd64/amd64/trap.c   14 Jul 2017 22:54:28 -
> @@ -306,6 +306,7 @@ copyfault:
>   struct vm_map *map;
>   vm_prot_t ftype;
>   extern struct vm_map *kernel_map;
> + int signal, sicode;
>  
>   cr2 = rcr2();
>   KERNEL_LOCK();
> @@ -372,12 +373,14 @@ faultcommon:
>   map, fa, ftype, error);
>   goto we_re_toast;
>   }
> +
> + signal = SIGSEGV;
> + sicode = SEGV_MAPERR;
>   if (error == ENOMEM) {
>   printf("UVM: pid %d (%s), uid %d killed:"
>   " out of swap\n", p->p_p->ps_pid, p->p_p->ps_comm,
>   p->p_ucred ? (int)p->p_ucred->cr_uid : -1);
> - sv.sival_ptr = (void *)fa;
> - trapsignal(p, SIGKILL, T_PAGEFLT, SEGV_MAPERR, sv);
> + signal = SIGKILL;
>   } else {
>  #ifdef TRAP_SIGDEBUG
>   printf("pid %d (%s): %s at rip %llx addr %llx\n",
> @@ -385,10 +388,15 @@ faultcommon:
>   frame->tf_rip, rcr2());
>   frame_dump(frame);
>  #endif
> - sv.sival_ptr = (void *)fa;
> - trapsignal(p, SIGSEGV, T_PAGEFLT,
> - error == EACCES ? SEGV_ACCERR : SEGV_MAPERR, sv);
>   }
> + if (error == EACCES)
> + sicode = SEGV_ACCERR;
> + if (error == EIO) {
> + signal = SIGBUS;
> + sicode = BUS_ADRERR;
> + }
> + sv.sival_ptr = (void *)fa;
> + trapsignal(p, signal, T_PAGEFLT, sicode, sv);
>   KERNEL_UNLOCK();
>   break;
>   }
> Index: arch/i386/i386/trap.c
> ===
> RCS file: /data/mirror/openbsd/cvs/src/sys/arch/i386/i386/trap.c,v
> retrieving revision 1.131
> diff -u -p -r1.131 trap.c
> --- arch/i386/i386/trap.c 14 Jul 2017 12:20:32 -  1.131
> +++ arch/i386/i386/trap.c 14 Jul 2017 22:55:16 -
> @@ -374,6 +374,7 @@ trap(struct trapframe *frame)
>   struct vmspace *vm;
>   struct vm_map *map;
>   int error;
> + int signal, sicode;
>  
>   cr2 = rcr2();
>   KERNEL_LOCK();
> @@ -431,9 +432,17 @@ trap(struct trapframe *frame)
>   map, va, ftype, error);
>   goto we_re_toast;
>   }
> +
> + signal = SIGSEGV;
> + sicode = SEGV_MAPERR;
> + if (error == EACCES)
> + sicode = SEGV_ACCERR;
> + if (error == EIO) {
> + signal = SIGBUS;
> + sicode = BUS_ADRERR;
> + }
>   sv.sival_int = fa;
> - trapsignal(p, SIGSEGV, vftype,
> - error == EACCES ? SEGV_ACCERR : SEGV_MAPERR, sv);
> + trapsignal(p, signal, vftype, sicode, sv);
>   KERNEL_UNLOCK();
>   break;
>   }
> Index: 

Re: SIGBUS short mmap object

2017-07-18 Thread Mark Kettenis
> From: Theo de Raadt 
> Date: Mon, 17 Jul 2017 16:06:05 -0600 (MDT)
> 
> Sorry I disagree.  SIGSEGV is the right answer.  It was not mapped.
> That is segmentation.

Actually it is mapped in the sense that uvm has created mapping
entries for it.  The mapping just isn't backed (because the backing
store was never there, or the file has been truncated in the
meantime).

> A SIGBUS should be delivered when the mode of access is not permitted
> on a valid mapping.

Most of our architectures (but not all) actually return SIGSEGV in
that case.

> I know some other operating systems have gotten extremly sloppy and
> inconsistant in this regard.  And I despise what they did.  It suspect
> they got so used to unaligned-access architectures they then forgot
> the reason why SIGBUS was something else, and wanted to reuse it to
> mean something else before siginfo became popular.  And I think this
> bug came about due to i386 X.

OpenBSD is sloppy as well.  The usual issue of importing from
diffferent vintage NetBSD and FreeBSD is almost certainly at work here.

The SIGBUS for mmap behaviour seems to be lifted straight from the
SunOS 4.1.3 documentation:

  
https://www.freebsd.org/cgi/man.cgi?query=mmap=0=2=SunOS+4.1.3=default=html

Interestingly enough SunOS 5 "allows" both SIGBUS and SIGSEGV:

  
https://www.freebsd.org/cgi/man.cgi?query=mmap=0=2=SunOS+5.10=default=html

Pretty sure things started to diverge in an early stage.  In the old
days, SIGBUS and SIGSEGV simply mapped 1:1 to the VAX MMU traps.  When
different hardware came along with different MMU traps, the trap to
signal mapping simply wasn't always obvious.  Then of course the
introduction of different vm systems caused further divergence.  Your
right that siginfo prompted folks to make further changes.  Was that a
SVR4 thing?

> And if you quote POSIX, I think they are WRONG.  It is irresponsible
> of people to redefine the meanings of objects such that you cannot
> tell what action to take to repair the problem.

Dividing the possible fault scenarios in two classes is always going
to lead to ambiguities.  I suppose that is one of the reasons folks
came up with siginfo.  The competing BSD "solution" of using a sigcode
that encoded the actual hardware trap is pretty much unusable for
writing portable software.

Here's what POSIX has to say about this:

  When an object is mapped, various application accesses to the mapped
  region may result in signals. In this context, SIGBUS is used to
  indicate an error using the mapped object, and SIGSEGV is used to
  indicate a protection violation or misuse of an address:

  * A mapping may be restricted to disallow some types of access.

  * Write attempts to memory that was mapped without write access, or
any access to memory mapped PROT_NONE, shall result in a SIGSEGV
signal.

  * References to unmapped addresses shall result in a SIGSEGV signal.

  * Reference to whole pages within the mapping, but beyond the
current length of the object, shall result in a SIGBUS signal.

  * The size of the object is unaffected by access beyond the end of
the object (even if a SIGBUS is not generated).

I think this is a sensible way of distinguishing between SIGBUS and
SIGSEGV.  It just doesn't match historical practice in BSD land.  And
I can't blame them for following SVR4 here as in BSD land everything
was (and still is) pretty much undocumented.

That said, on many systems (including Linux) the siginfo
implementation is incomplete and sometimes even incorrect.  You cannot
rely on it for writing portable code.  But it is useful for debugging.
The same holds for the mmap SIGBUS behaviour.  The Solaris folks
probably got it right when documenting that either SIGBUS or SIGSEGV
could happen.

Still I think that having more consistency between architectures on
OpenBSD is a good thing.  POSIX provides such a model, even if it
deviates in places from historical behaviour.  I'm not really worried
about those deviations as we don't implement the historical behaviour
consistently anyway.  If you believe that siginfo is a useful thing,
the POSIX interpretation of SIGBUS and SIGSEGV is the only one that
really makes sense.

In other words, I think we should go with bluhm@'s original diff.

> Finally, the diff here only touches 2 architectures.  Which others
> change semantics in some odd way when that uvm diff goes in?

Once we agree on the regression test for this, we can fix the other
archiitectures.



Re: SIGBUS short mmap object

2017-07-18 Thread Alexander Bluhm
On Mon, Jul 17, 2017 at 04:06:05PM -0600, Theo de Raadt wrote:
> Finally, the diff here only touches 2 architectures.

Yes, I know.  But why work on the others if the change is not
accepted anyway.

> Where is this coming from?  Is it just to satisfy a regress test?

My concern is only the regress test.  I am totally fine to adapt
the test instead of the kernel.  But I don't know why the test was
written that way.  In general I think commiting tests for bugs or
features someone else should fix later is a bad idea.

This adapts the test to the current behavior.  The SEGV_ACCERR looks
wrong.  Should I try to set SEGV_MAPERR in the kernel?

bluhm

Index: regress/sys/kern/siginfo-fault/siginfo-fault.c
===
RCS file: 
/data/mirror/openbsd/cvs/src/regress/sys/kern/siginfo-fault/siginfo-fault.c,v
retrieving revision 1.4
diff -u -p -r1.4 siginfo-fault.c
--- regress/sys/kern/siginfo-fault/siginfo-fault.c  13 Jul 2017 00:29:14 
-  1.4
+++ regress/sys/kern/siginfo-fault/siginfo-fault.c  18 Jul 2017 09:23:57 
-
@@ -156,7 +156,7 @@ main()
p[3] = 1;
FAIL();
}
-   fail += checksig("mmap file", SIGBUS, BUS_ADRERR, p + 3);
+   fail += checksig("mmap file", SIGSEGV, SEGV_ACCERR, p + 3);
 
return (fail);
 }



Re: SIGBUS short mmap object

2017-07-17 Thread Theo de Raadt
The tests regress/sys/kern/siginfo-fault accesses an mmap(2)ed file
behind its end.  Then it expects an SIGBUS, but gets an SIGSEGV.

Sorry I disagree.  SIGSEGV is the right answer.  It was not mapped.
That is segmentation.

A SIGBUS should be delivered when the mode of access is not permitted
on a valid mapping.

I know some other operating systems have gotten extremly sloppy and
inconsistant in this regard.  And I despise what they did.  It suspect
they got so used to unaligned-access architectures they then forgot
the reason why SIGBUS was something else, and wanted to reuse it to
mean something else before siginfo became popular.  And I think this
bug came about due to i386 X.

And if you quote POSIX, I think they are WRONG.  It is irresponsible
of people to redefine the meanings of objects such that you cannot
tell what action to take to repair the problem.

Finally, the diff here only touches 2 architectures.  Which others
change semantics in some odd way when that uvm diff goes in?

Where is this coming from?  Is it just to satisfy a regress test?

Related commit message is:
Additionally, SIGBUS/BUS_ADRERR should be generated instead of 
SIGSEGV
for access to file mapped pages that exceed the end of the file.
(Thanks to kettenis@ for suggesting this test.)

I think this description refers to
http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html
Reference to whole pages within the mapping, but beyond the current
length of the object, shall result in a SIGBUS signal.

The attached diff fixes that for amd64 and i386 and the test passes.

ok?

bluhm

Index: arch/amd64/amd64/trap.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/arch/amd64/amd64/trap.c,v
retrieving revision 1.55
diff -u -p -r1.55 trap.c
--- arch/amd64/amd64/trap.c 14 Jul 2017 12:20:32 -  1.55
+++ arch/amd64/amd64/trap.c 14 Jul 2017 22:54:28 -
@@ -306,6 +306,7 @@ copyfault:
struct vm_map *map;
vm_prot_t ftype;
extern struct vm_map *kernel_map;
+   int signal, sicode;
 
cr2 = rcr2();
KERNEL_LOCK();
@@ -372,12 +373,14 @@ faultcommon:
map, fa, ftype, error);
goto we_re_toast;
}
+
+   signal = SIGSEGV;
+   sicode = SEGV_MAPERR;
if (error == ENOMEM) {
printf("UVM: pid %d (%s), uid %d killed:"
" out of swap\n", p->p_p->ps_pid, 
p->p_p->ps_comm,
p->p_ucred ? (int)p->p_ucred->cr_uid : -1);
-   sv.sival_ptr = (void *)fa;
-   trapsignal(p, SIGKILL, T_PAGEFLT, SEGV_MAPERR, 
sv);
+   signal = SIGKILL;
} else {
 #ifdef TRAP_SIGDEBUG
printf("pid %d (%s): %s at rip %llx addr 
%llx\n",
@@ -385,10 +388,15 @@ faultcommon:
frame->tf_rip, rcr2());
frame_dump(frame);
 #endif
-   sv.sival_ptr = (void *)fa;
-   trapsignal(p, SIGSEGV, T_PAGEFLT,
-   error == EACCES ? SEGV_ACCERR : 
SEGV_MAPERR, sv);
}
+   if (error == EACCES)
+   sicode = SEGV_ACCERR;
+   if (error == EIO) {
+   signal = SIGBUS;
+   sicode = BUS_ADRERR;
+   }
+   sv.sival_ptr = (void *)fa;
+   trapsignal(p, signal, T_PAGEFLT, sicode, sv);
KERNEL_UNLOCK();
break;
}
Index: arch/i386/i386/trap.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/arch/i386/i386/trap.c,v
retrieving revision 1.131
diff -u -p -r1.131 trap.c
--- arch/i386/i386/trap.c   14 Jul 2017 12:20:32 -  1.131
+++ arch/i386/i386/trap.c   14 Jul 2017 22:55:16 -
@@ -374,6 +374,7 @@ trap(struct trapframe *frame)
struct vmspace *vm;
struct vm_map *map;
int error;
+   int signal, sicode;
 
cr2 = rcr2();
KERNEL_LOCK();
@@ -431,9 +432,17 @@ trap(struct trapframe