Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[PAE] minor virtual memory i386 code rework



Hi list,

I am currently in the process of adding PAE support within kvm(3). As
such, I am proposing a patch (see attached) to the "review before
commit" process:

- it makes paddr_t a 64 bits entity for i386 userland, whether PAE
support was compiled in, or not (only affects kvm_i386).

- basic rework of PD/PT code, to expose some macros simultaneously for
i386 native and PAE mode.

Depending on the mode they apply to, they are either prefixed with
"I386_" or "PAE_" (suggestions welcomed for better wording). These
macros are required in different parts of pmap, directly or indirectly
(through pl*_i functions). In order to remain "largely" compatible with
the current architecture, I am using ___CONCAT() magic to properly
select the ones that will be used at compilation time.

After the pmap rework from rmind@, I will investigate further on how I
could get more abstraction inside pmap, like providing native and PAE
code simultaneously in kernel, without too much duplication (this will
need paddr_t 64 bits work too, so let's do this gradually).

Opinions on that one? It is required for my kvm(3) prototype change
work, which will be subject of another mail to current-users@ in about 5
min. The libsa change will be committed separately.

-- 
Jean-Yves Migeon
jeanyves.migeon%free.fr@localhost
Index: sys/arch/i386/include/pte.h
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/include/pte.h,v
retrieving revision 1.24
diff -u -p -r1.24 pte.h
--- sys/arch/i386/include/pte.h 6 Jul 2010 20:50:34 -0000       1.24
+++ sys/arch/i386/include/pte.h 6 Sep 2010 17:39:03 -0000
@@ -192,50 +192,96 @@ typedef uint32_t pt_entry_t;              /* PTE */
 #endif
 
 /*
- * now we define various for playing with virtual addresses
+ * now we define various macros for playing with virtual addresses.
+ * As PAE modifies the way virtual addresses are manipulated, certain macros
+ * are prefixed with either 'I386_' (native i386) or 'PAE_' (PAE mode)
+ * depending on the mode to which they apply.
  */
 
-#ifdef PAE
-#define        L1_SHIFT        12
-#define        L2_SHIFT        21
-#define        L3_SHIFT        30
-#define        NBPD_L1         (1ULL << L1_SHIFT) /* # bytes mapped by L1 ent 
(4K) */
-#define        NBPD_L2         (1ULL << L2_SHIFT) /* # bytes mapped by L2 ent 
(2MB) */
-#define        NBPD_L3         (1ULL << L3_SHIFT) /* # bytes mapped by L3 ent 
(1GB) */
-
-#define        L3_MASK         0xc0000000
-#define        L2_REALMASK     0x3fe00000
-#define        L2_MASK         (L2_REALMASK | L3_MASK)
-#define        L1_MASK         0x001ff000
-
-#define        L3_FRAME        (L3_MASK)
-#define        L2_FRAME        (L3_FRAME | L2_MASK)
-#define        L1_FRAME        (L2_FRAME|L1_MASK)
+/* First, the native i386 macros */
 
-#define        PG_FRAME        0x000ffffffffff000ULL /* page frame mask */
-#define        PG_LGFRAME      0x000fffffffe00000ULL /* large (2MB) page frame 
mask */
+#define        I386_L1_SHIFT   12
+#define        I386_L2_SHIFT   22
 
-/* macros to get real L2 and L3 index, from our "extended" L2 index */
-#define l2tol3(idx)    ((idx) >> (L3_SHIFT - L2_SHIFT))
-#define l2tol2(idx)    ((idx) & (L2_REALMASK >>  L2_SHIFT))
+/* # bytes mapped by L1 ent (4K) */
+#define        I386_NBPD_L1    (1UL << I386_L1_SHIFT)
 
-#else /* PAE */
+/* # bytes mapped by L2 ent (4MB) */
+#define        I386_NBPD_L2    (1UL << I386_L2_SHIFT)
+
+#define        I386_L2_MASK    0xffc00000
+#define        I386_L1_MASK    0x003ff000
+
+#define        I386_L2_FRAME   (I386_L2_MASK)
+#define        I386_L1_FRAME   (I386_L2_FRAME | I386_L1_MASK)
+
+#define        I386_PG_FRAME   0xfffff000      /* page frame mask */
+#define        I386_PG_LGFRAME 0xffc00000      /* large (4MB) page frame mask 
*/
 
-#define        L1_SHIFT        12
-#define        L2_SHIFT        22
-#define        NBPD_L1         (1UL << L1_SHIFT) /* # bytes mapped by L1 ent 
(4K) */
-#define        NBPD_L2         (1UL << L2_SHIFT) /* # bytes mapped by L2 ent 
(4MB) */
+/* Second, PAE macros */
 
-#define L2_MASK                0xffc00000
-#define L1_MASK                0x003ff000
+#define        PAE_L1_SHIFT    12
+#define        PAE_L2_SHIFT    21
+#define        PAE_L3_SHIFT    30
 
-#define L2_FRAME       (L2_MASK)
-#define L1_FRAME       (L2_FRAME|L1_MASK)
+/* # bytes mapped by L1 ent (4K) */
+#define        PAE_NBPD_L1     (1ULL << PAE_L1_SHIFT)
 
-#define        PG_FRAME        0xfffff000      /* page frame mask */
-#define        PG_LGFRAME      0xffc00000      /* large (4MB) page frame mask 
*/
+/* # bytes mapped by L2 ent (2MB) */
+#define        PAE_NBPD_L2     (1ULL << PAE_L2_SHIFT)
 
+/* # bytes mapped by L3 ent (1GB) */
+#define        PAE_NBPD_L3     (1ULL << PAE_L3_SHIFT)
+
+#define        PAE_L3_MASK     0xc0000000
+#define        PAE_L2_REALMASK 0x3fe00000
+#define        PAE_L2_MASK     (PAE_L2_REALMASK | PAE_L3_MASK)
+#define        PAE_L1_MASK     0x001ff000
+
+#define        PAE_L3_FRAME    (PAE_L3_MASK)
+#define        PAE_L2_FRAME    (PAE_L3_FRAME | PAE_L2_MASK)
+#define        PAE_L1_FRAME    (PAE_L2_FRAME | PAE_L1_MASK)
+
+#define        PAE_PG_FRAME    0x000ffffffffff000ULL /* page frame mask */
+#define        PAE_PG_LGFRAME  0x000fffffffe00000ULL /* large (2MB) page frame 
mask */
+
+/* macros to get real L2 and L3 index, from our "extended" L2 index */
+#define l2tol3(idx)    ((idx) >> (PAE_L3_SHIFT - PAE_L2_SHIFT))
+#define l2tol2(idx)    ((idx) & (PAE_L2_REALMASK >>  PAE_L2_SHIFT))
+
+/*
+ * Use CONCAT dark magic, so that general purpose in-kernel macros
+ * are correctly chosen depending on i386 mode (native, or PAE) used at build
+ * time.
+ */
+
+#include <sys/cdefs.h>
+
+#ifdef PAE
+#define I386_MODE PAE_
+#else /* PAE */
+#define I386_MODE I386_
 #endif /* PAE */
+
+#define        L1_SHIFT        ___CONCAT(I386_MODE,L1_SHIFT)
+#define        L2_SHIFT        ___CONCAT(I386_MODE,L2_SHIFT)
+#define        L3_SHIFT        ___CONCAT(I386_MODE,L3_SHIFT)
+
+#define        NBPD_L1         ___CONCAT(I386_MODE,NBPD_L1)
+#define        NBPD_L2         ___CONCAT(I386_MODE,NBPD_L2)
+#define        NBPD_L3         ___CONCAT(I386_MODE,NBPD_L3)
+
+#define        L1_MASK         ___CONCAT(I386_MODE,L1_MASK)
+#define        L2_MASK         ___CONCAT(I386_MODE,L2_MASK)
+#define        L3_MASK         ___CONCAT(I386_MODE,L3_MASK)
+
+#define        L1_FRAME        ___CONCAT(I386_MODE,L1_FRAME)
+#define        L2_FRAME        ___CONCAT(I386_MODE,L2_FRAME)
+#define        L3_FRAME        ___CONCAT(I386_MODE,L3_FRAME)
+
+#define        PG_FRAME        ___CONCAT(I386_MODE,PG_FRAME)
+#define        PG_LGFRAME      ___CONCAT(I386_MODE,PG_LGFRAME)
+
 /*
  * here we define the bits of the PDE/PTE, as described above:
  *
@@ -267,7 +313,7 @@ typedef uint32_t pt_entry_t;                /* PTE */
 #define        PG_KW           0x00000002      /* kernel read-write */
 
 #ifdef PAE
-#define        PG_NX           0x8000000000000000 /* No-execute */
+#define        PG_NX           0x8000000000000000ULL /* No-execute */
 #else
 #define        PG_NX           0               /* dummy */
 #endif
Index: sys/arch/i386/include/types.h
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/include/types.h,v
retrieving revision 1.67
diff -u -p -r1.67 types.h
--- sys/arch/i386/include/types.h       11 Dec 2009 05:52:03 -0000      1.67
+++ sys/arch/i386/include/types.h       6 Sep 2010 17:39:03 -0000
@@ -47,27 +47,43 @@ typedef struct label_t {
 } label_t;
 #endif
 
-/* NB: This should probably be if defined(_KERNEL) */
 #if defined(_NETBSD_SOURCE)
+#if defined(_KERNEL)
+
+/*
+ * XXX JYM for now, in kernel paddr_t can be 32 or 64 bits, depending
+ * on PAE. Revisit when paddr_t becomes 64 bits for !PAE systems.
+ */
 #ifdef PAE
 typedef unsigned long long paddr_t;
 typedef unsigned long long psize_t;
 #define        PRIxPADDR       "llx"
 #define        PRIxPSIZE       "llx"
 #define        PRIuPSIZE       "llu"
-#else
+#else /* PAE */
 typedef unsigned long  paddr_t;
 typedef unsigned long  psize_t;
 #define        PRIxPADDR       "lx"
 #define        PRIxPSIZE       "lx"
 #define        PRIuPSIZE       "lu"
 #endif /* PAE */
+
+#else /* _KERNEL */
+/* paddr_t is always 64 bits for userland */
+typedef unsigned long long paddr_t;
+typedef unsigned long long psize_t;
+#define        PRIxPADDR       "llx"
+#define        PRIxPSIZE       "llx"
+#define        PRIuPSIZE       "llu"
+
+#endif /* _KERNEL */
+
 typedef unsigned long  vaddr_t;
 typedef unsigned long  vsize_t;
 #define        PRIxVADDR       "lx"
 #define        PRIxVSIZE       "lx"
 #define        PRIuVSIZE       "lu"
-#endif
+#endif /* _NETBSD_SOURCE */
 
 typedef int            pmc_evid_t;
 typedef __uint64_t     pmc_ctr_t;
Index: sys/lib/libsa/loadfile_elf32.c
===================================================================
RCS file: /cvsroot/src/sys/lib/libsa/loadfile_elf32.c,v
retrieving revision 1.26
diff -u -p -r1.26 loadfile_elf32.c
--- sys/lib/libsa/loadfile_elf32.c      2 Sep 2010 17:10:14 -0000       1.26
+++ sys/lib/libsa/loadfile_elf32.c      6 Sep 2010 17:39:10 -0000
@@ -263,8 +263,9 @@ ELFNAMEEND(loadfile)(int fd, Elf_Ehdr *e
        int i, j;
        ssize_t sz;
        int first;
-       paddr_t minp = ~0, maxp = 0, pos = 0;
-       paddr_t offset = marks[MARK_START], shpp, elfp = 0;
+       Elf_Addr shpp;
+       Elf_Addr minp = ~0, maxp = 0, pos = 0, elfp = 0;
+       u_long offset = marks[MARK_START];
        ssize_t nr;
        struct __packed {
                Elf_Nhdr        nh;


Home | Main Index | Thread Index | Old Index