Splits pmap ops up for each arch
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 16 Mar 2015 20:00:39 +0000 (16:00 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Tue, 17 Mar 2015 14:56:00 +0000 (10:56 -0400)
The helpers are the same for now, but this lets x86's ops change to
support EPTs.

kern/arch/riscv/pmap_ops.h [new file with mode: 0644]
kern/arch/x86/pmap_ops.h [new file with mode: 0644]
kern/include/pmap.h

diff --git a/kern/arch/riscv/pmap_ops.h b/kern/arch/riscv/pmap_ops.h
new file mode 100644 (file)
index 0000000..c5eae53
--- /dev/null
@@ -0,0 +1,115 @@
+/* Copyright (c) 2015 Google Inc.
+ * Barret Rhoden <brho@cs.berkeley.edu>
+ * See LICENSE for details.
+ *
+ * Arch-specific operations for page tables and PTEs */
+
+#ifndef ROS_ARCH_PMAPS_OPS_H
+#define ROS_ARCH_PMAPS_OPS_H
+
+static inline bool pte_walk_okay(pte_t pte)
+{
+       return pte ? TRUE : FALSE;
+}
+
+/* PTE states:
+ *  - present: the PTE is involved in a valid page table walk, with the physaddr
+ *  part pointing to a physical page.
+ *
+ *     - mapped: the PTE is involved in some sort of mapping, e.g. a VMR.  We're
+ *     storing something in the PTE, but it is isn't necessarily present and
+ *     pointing to an actual physical page.  All present are mapped, but not vice
+ *     versa.  Mapped could also include paged-out, if we support that later.
+ *
+ *     - unmapped: completely unused. (0 value) */
+static inline bool pte_is_present(pte_t pte)
+{
+       return *(kpte_t*)pte & PTE_P ? TRUE : FALSE;
+}
+
+static inline bool pte_is_unmapped(pte_t pte)
+{
+       return PAGE_UNMAPPED(*(kpte_t*)pte);
+}
+
+static inline bool pte_is_mapped(pte_t pte)
+{
+       return !PAGE_UNMAPPED(*(kpte_t*)pte);
+}
+
+static inline bool pte_is_paged_out(pte_t pte)
+{
+       return PAGE_PAGED_OUT(*(kpte_t*)pte);
+}
+
+static inline bool pte_is_dirty(pte_t pte)
+{
+       return *(kpte_t*)pte & PTE_D ? TRUE : FALSE;
+}
+
+static inline bool pte_is_accessed(pte_t pte)
+{
+       return *(kpte_t*)pte & PTE_A ? TRUE : FALSE;
+}
+
+/* Used in debugging code - want something better involving the walk */
+static inline bool pte_is_jumbo(pte_t pte)
+{
+       return *(kpte_t*)pte & PTE_PS ? TRUE : FALSE;
+}
+
+static inline physaddr_t pte_get_paddr(pte_t pte)
+{
+       return PTE_ADDR(*(kpte_t*)pte);
+}
+
+/* Returns the PTE in an unsigned long, for debugging mostly. */
+static inline unsigned long pte_print(pte_t pte)
+{
+       return *(kpte_t*)pte;
+}
+
+static inline void pte_write(pte_t pte, physaddr_t pa, int perm)
+{
+       *(kpte_t*)pte = PTE(pa2ppn(pa), perm);
+}
+
+static inline void pte_clear_present(pte_t pte)
+{
+       *(kpte_t*)pte &= ~PTE_P;
+}
+
+static inline void pte_clear(pte_t pte)
+{
+       *(kpte_t*)pte = 0;
+}
+
+/* These are used by memcpy_*_user, but are very dangerous (and possibly used
+ * incorrectly there).  These aren't the overall perms for a VA.  For U and W,
+ * we need the intersection of the PTEs along the walk and not just the last
+ * one.  It just so happens that the W is only cleared on the last PTE, so the
+ * check works for that.  But if there was a page under ULIM that wasn't U due
+ * to an intermediate PTE, we'd miss that. */
+static inline bool pte_has_perm_ur(pte_t pte)
+{
+       return *(kpte_t*)pte & PTE_USER_RO ? TRUE : FALSE;
+}
+
+static inline bool pte_has_perm_urw(pte_t pte)
+{
+       return *(kpte_t*)pte & PTE_USER_RW ? TRUE : FALSE;
+}
+
+/* return the arch-independent format for prots - whatever you'd expect to
+ * receive for pte_write.  Careful with the ret, since a valid type is 0. */
+static inline int pte_get_perm(pte_t pte)
+{
+       return *(kpte_t*)pte & PTE_PERM;
+}
+
+static inline void pte_replace_perm(pte_t pte, int perm)
+{
+       *(kpte_t*)pte = (*(kpte_t*)pte & ~PTE_PERM) | perm;
+}
+
+#endif /* ROS_ARCH_PMAPS_OPS_H */
diff --git a/kern/arch/x86/pmap_ops.h b/kern/arch/x86/pmap_ops.h
new file mode 100644 (file)
index 0000000..c5eae53
--- /dev/null
@@ -0,0 +1,115 @@
+/* Copyright (c) 2015 Google Inc.
+ * Barret Rhoden <brho@cs.berkeley.edu>
+ * See LICENSE for details.
+ *
+ * Arch-specific operations for page tables and PTEs */
+
+#ifndef ROS_ARCH_PMAPS_OPS_H
+#define ROS_ARCH_PMAPS_OPS_H
+
+static inline bool pte_walk_okay(pte_t pte)
+{
+       return pte ? TRUE : FALSE;
+}
+
+/* PTE states:
+ *  - present: the PTE is involved in a valid page table walk, with the physaddr
+ *  part pointing to a physical page.
+ *
+ *     - mapped: the PTE is involved in some sort of mapping, e.g. a VMR.  We're
+ *     storing something in the PTE, but it is isn't necessarily present and
+ *     pointing to an actual physical page.  All present are mapped, but not vice
+ *     versa.  Mapped could also include paged-out, if we support that later.
+ *
+ *     - unmapped: completely unused. (0 value) */
+static inline bool pte_is_present(pte_t pte)
+{
+       return *(kpte_t*)pte & PTE_P ? TRUE : FALSE;
+}
+
+static inline bool pte_is_unmapped(pte_t pte)
+{
+       return PAGE_UNMAPPED(*(kpte_t*)pte);
+}
+
+static inline bool pte_is_mapped(pte_t pte)
+{
+       return !PAGE_UNMAPPED(*(kpte_t*)pte);
+}
+
+static inline bool pte_is_paged_out(pte_t pte)
+{
+       return PAGE_PAGED_OUT(*(kpte_t*)pte);
+}
+
+static inline bool pte_is_dirty(pte_t pte)
+{
+       return *(kpte_t*)pte & PTE_D ? TRUE : FALSE;
+}
+
+static inline bool pte_is_accessed(pte_t pte)
+{
+       return *(kpte_t*)pte & PTE_A ? TRUE : FALSE;
+}
+
+/* Used in debugging code - want something better involving the walk */
+static inline bool pte_is_jumbo(pte_t pte)
+{
+       return *(kpte_t*)pte & PTE_PS ? TRUE : FALSE;
+}
+
+static inline physaddr_t pte_get_paddr(pte_t pte)
+{
+       return PTE_ADDR(*(kpte_t*)pte);
+}
+
+/* Returns the PTE in an unsigned long, for debugging mostly. */
+static inline unsigned long pte_print(pte_t pte)
+{
+       return *(kpte_t*)pte;
+}
+
+static inline void pte_write(pte_t pte, physaddr_t pa, int perm)
+{
+       *(kpte_t*)pte = PTE(pa2ppn(pa), perm);
+}
+
+static inline void pte_clear_present(pte_t pte)
+{
+       *(kpte_t*)pte &= ~PTE_P;
+}
+
+static inline void pte_clear(pte_t pte)
+{
+       *(kpte_t*)pte = 0;
+}
+
+/* These are used by memcpy_*_user, but are very dangerous (and possibly used
+ * incorrectly there).  These aren't the overall perms for a VA.  For U and W,
+ * we need the intersection of the PTEs along the walk and not just the last
+ * one.  It just so happens that the W is only cleared on the last PTE, so the
+ * check works for that.  But if there was a page under ULIM that wasn't U due
+ * to an intermediate PTE, we'd miss that. */
+static inline bool pte_has_perm_ur(pte_t pte)
+{
+       return *(kpte_t*)pte & PTE_USER_RO ? TRUE : FALSE;
+}
+
+static inline bool pte_has_perm_urw(pte_t pte)
+{
+       return *(kpte_t*)pte & PTE_USER_RW ? TRUE : FALSE;
+}
+
+/* return the arch-independent format for prots - whatever you'd expect to
+ * receive for pte_write.  Careful with the ret, since a valid type is 0. */
+static inline int pte_get_perm(pte_t pte)
+{
+       return *(kpte_t*)pte & PTE_PERM;
+}
+
+static inline void pte_replace_perm(pte_t pte, int perm)
+{
+       *(kpte_t*)pte = (*(kpte_t*)pte & ~PTE_PERM) | perm;
+}
+
+#endif /* ROS_ARCH_PMAPS_OPS_H */
index cabf615..fe584b6 100644 (file)
@@ -161,109 +161,9 @@ static inline unsigned long nr_pages(size_t nr_bytes)
        return (nr_bytes >> PGSHIFT) + (PGOFF(nr_bytes) ? 1 : 0);
 }
 
-static inline bool pte_walk_okay(pte_t pte)
-{
-       return pte ? TRUE : FALSE;
-}
-
-/* PTE states:
- *  - present: the PTE is involved in a valid page table walk, with the physaddr
- *  part pointing to a physical page.
- *
- *     - mapped: the PTE is involved in some sort of mapping, e.g. a VMR.  We're
- *     storing something in the PTE, but it is isn't necessarily present and
- *     pointing to an actual physical page.  All present are mapped, but not vice
- *     versa.  Mapped could also include paged-out, if we support that later.
- *
- *     - unmapped: completely unused. (0 value) */
-static inline bool pte_is_present(pte_t pte)
-{
-       return *(kpte_t*)pte & PTE_P ? TRUE : FALSE;
-}
-
-static inline bool pte_is_unmapped(pte_t pte)
-{
-       return PAGE_UNMAPPED(*(kpte_t*)pte);
-}
-
-static inline bool pte_is_mapped(pte_t pte)
-{
-       return !PAGE_UNMAPPED(*(kpte_t*)pte);
-}
-
-static inline bool pte_is_paged_out(pte_t pte)
-{
-       return PAGE_PAGED_OUT(*(kpte_t*)pte);
-}
-
-static inline bool pte_is_dirty(pte_t pte)
-{
-       return *(kpte_t*)pte & PTE_D ? TRUE : FALSE;
-}
-
-static inline bool pte_is_accessed(pte_t pte)
-{
-       return *(kpte_t*)pte & PTE_A ? TRUE : FALSE;
-}
-
-/* Used in debugging code - want something better involving the walk */
-static inline bool pte_is_jumbo(pte_t pte)
-{
-       return *(kpte_t*)pte & PTE_PS ? TRUE : FALSE;
-}
-
-static inline physaddr_t pte_get_paddr(pte_t pte)
-{
-       return PTE_ADDR(*(kpte_t*)pte);
-}
-
-/* Returns the PTE in an unsigned long, for debugging mostly. */
-static inline unsigned long pte_print(pte_t pte)
-{
-       return *(kpte_t*)pte;
-}
-
-static inline void pte_write(pte_t pte, physaddr_t pa, int perm)
-{
-       *(kpte_t*)pte = PTE(pa2ppn(pa), perm);
-}
-
-static inline void pte_clear_present(pte_t pte)
-{
-       *(kpte_t*)pte &= ~PTE_P;
-}
-
-static inline void pte_clear(pte_t pte)
-{
-       *(kpte_t*)pte = 0;
-}
-
-/* These are used by memcpy_*_user, but are very dangerous (and possibly used
- * incorrectly there).  These aren't the overall perms for a VA.  For U and W,
- * we need the intersection of the PTEs along the walk and not just the last
- * one.  It just so happens that the W is only cleared on the last PTE, so the
- * check works for that.  But if there was a page under ULIM that wasn't U due
- * to an intermediate PTE, we'd miss that. */
-static inline bool pte_has_perm_ur(pte_t pte)
-{
-       return *(kpte_t*)pte & PTE_USER_RO ? TRUE : FALSE;
-}
-
-static inline bool pte_has_perm_urw(pte_t pte)
-{
-       return *(kpte_t*)pte & PTE_USER_RW ? TRUE : FALSE;
-}
-
-/* return the arch-independent format for prots - whatever you'd expect to
- * receive for pte_write.  Careful with the ret, since a valid type is 0. */
-static inline int pte_get_perm(pte_t pte)
-{
-       return *(kpte_t*)pte & PTE_PERM;
-}
-
-static inline void pte_replace_perm(pte_t pte, int perm)
-{
-       *(kpte_t*)pte = (*(kpte_t*)pte & ~PTE_PERM) | perm;
-}
+/* Including here, since these ops often rely on pmap.h helpers, which rely on
+ * the generic arch/pmap.h.  It's likely that many of these ops will be inlined
+ * for speed in pmap_ops. */
+#include <arch/pmap_ops.h>
 
 #endif /* !ROS_KERN_PMAP_H */