For virtual addresses use fixed page frame without AMD SEV reduction.
authorbluhm <bluhm@openbsd.org>
Tue, 3 Sep 2024 17:19:53 +0000 (17:19 +0000)
committerbluhm <bluhm@openbsd.org>
Tue, 3 Sep 2024 17:19:53 +0000 (17:19 +0000)
When running as a SEV guest, page frame mask is calculated from the
CPUID provided "physical address bit reduction".  The amd64 pmap
code uses the variable pg_frame instead of the defined PG_FRAME
0x000ffffffffff000.
There was one instance in pmap code where pg_frame was applied to
virtual address, not physical address.  On some machines the address
bit reduction is rather large with six bits.  So the calculated
pg_frame is 0x00003fffffe00000.  However, on amd64 VM_MAX_ADDRESS
is defined as 0x00007fbfdfeff000.  Masking a such large address
with pg_frame caused havoc.  Therefore, when masking virtual
addresses, still use PG_FRAME.

from hshoexer@

sys/arch/amd64/amd64/pmap.c

index cf8e592..c7d2dca 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pmap.c,v 1.172 2024/08/29 20:13:42 dv Exp $   */
+/*     $OpenBSD: pmap.c,v 1.173 2024/09/03 17:19:53 bluhm Exp $        */
 /*     $NetBSD: pmap.c,v 1.3 2003/05/08 18:13:13 thorpej Exp $ */
 
 /*
@@ -2159,8 +2159,8 @@ pmap_write_protect(struct pmap *pmap, vaddr_t sva, vaddr_t eva, vm_prot_t prot)
        shootself = (scr3 == 0);
 
        /* should be ok, but just in case ... */
-       sva &= pg_frame;
-       eva &= pg_frame;
+       sva &= PG_FRAME;
+       eva &= PG_FRAME;
 
        if (!(prot & PROT_READ))
                set |= pg_xo;