Do on i386 as we do on amd64. This is done on variable cpu_pae, which
authorderaadt <deraadt@openbsd.org>
Wed, 18 Jan 2023 05:06:44 +0000 (05:06 +0000)
committerderaadt <deraadt@openbsd.org>
Wed, 18 Jan 2023 05:06:44 +0000 (05:06 +0000)
indicates the "PAE" pmap is being used, which only happens if the cpu
has both PAE and NX.
On i386 machines without the NX feature enabled, we can't distinguish
between page faults as a result of instruction fetches or normal data
access.  Handle this in the same way as we do on landisk: if handling
the fault with access type PROT_READ fails, retry with PROT_EXEC.
Fortunately we know whether NX is enabled or nor so only do this when
it isn't.
ok kettenis, jsg

sys/arch/i386/i386/trap.c

index 6139457..bdbc90a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: trap.c,v 1.157 2023/01/16 05:32:05 deraadt Exp $      */
+/*     $OpenBSD: trap.c,v 1.158 2023/01/18 05:06:44 deraadt Exp $      */
 /*     $NetBSD: trap.c,v 1.95 1996/05/05 06:50:02 mycroft Exp $        */
 
 /*-
@@ -126,7 +126,14 @@ upageflttrap(struct trapframe *frame, uint32_t cr2)
        union sigval sv;
        int signal, sicode, error;
 
+       /*
+        * cpu_pae is true if system has PAE + NX.
+        * If NX is not enabled, we cant distinguish between PROT_READ
+        * and PROT_EXEC access, so try both.
+        */
        error = uvm_fault(&p->p_vmspace->vm_map, va, 0, access_type);
+       if (cpu_pae == 0 && error == EACCES && access_type == PROT_READ)
+               error = uvm_fault(&p->p_vmspace->vm_map, va, 0, PROT_EXEC);
 
        if (error == 0) {
                uvm_grow(p, va);