Pmap ops: perm->settings

This clarifies some aspects of pte_get_perms and pte_write.  In reality,
write takes all sorts of non-permission based flags.  What we really
wanted (I think) was the pte settings: the non-paddr lower 12 bits, in
an arch-indep format (based on the #defines).

Still, pte_replace_perm() is very useful as is.  pte_get_perm paired
with pte_write and wasn't really related to pte_replace_perm (in usage).
diff --git a/kern/arch/riscv/pmap_ops.h b/kern/arch/riscv/pmap_ops.h
index c5eae53..d6012a4 100644
--- a/kern/arch/riscv/pmap_ops.h
+++ b/kern/arch/riscv/pmap_ops.h
@@ -69,9 +69,9 @@
 	return *(kpte_t*)pte;
 }
 
-static inline void pte_write(pte_t pte, physaddr_t pa, int perm)
+static inline void pte_write(pte_t pte, physaddr_t pa, int settings)
 {
-	*(kpte_t*)pte = PTE(pa2ppn(pa), perm);
+	*(kpte_t*)pte = PTE(pa2ppn(pa), settings);
 }
 
 static inline void pte_clear_present(pte_t pte)
@@ -100,9 +100,13 @@
 	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)
+/* Settings includes protection (maskable via PTE_PROT) and other bits, such as
+ * jumbo, dirty, accessed, etc.  Whatever this returns can get fed back to
+ * replace_settings or pte_write.
+ *
+ * Arch-indep settings include: PTE_PERM (U, W, P, etc), PTE_D, PTE_A, PTE_PS.
+ * Other OSs (x86) may include others. */
+static inline int pte_get_settings(pte_t pte)
 {
 	return *(kpte_t*)pte & PTE_PERM;
 }
diff --git a/kern/arch/x86/kpt.h b/kern/arch/x86/kpt.h
index 3415418..c42e393 100644
--- a/kern/arch/x86/kpt.h
+++ b/kern/arch/x86/kpt.h
@@ -55,10 +55,11 @@
 	return *kpte;
 }
 
-static inline void kpte_write(kpte_t *kpte, physaddr_t pa, int perm)
+static inline void kpte_write(kpte_t *kpte, physaddr_t pa, int settings)
 {
 	assert(!PGOFF(pa));
-	*kpte = pa | perm;
+	/* The arch-bits like PTE_D, PTE_PS, etc are all in the native KPT format */
+	*kpte = pa | settings;
 }
 
 static inline void kpte_clear_present(kpte_t *kpte)
@@ -81,9 +82,9 @@
 	return (*kpte & PTE_USER_RW) == PTE_USER_RW;
 }
 
-static inline int kpte_get_perm(kpte_t *kpte)
+static inline int kpte_get_settings(kpte_t *kpte)
 {
-	return *kpte & PTE_PERM;
+	return *kpte & 0xfff;
 }
 
 static inline void kpte_replace_perm(kpte_t *kpte, int perm)
diff --git a/kern/arch/x86/pmap64.c b/kern/arch/x86/pmap64.c
index 857479a..f8ccc76 100644
--- a/kern/arch/x86/pmap64.c
+++ b/kern/arch/x86/pmap64.c
@@ -681,7 +681,8 @@
 			reason = "paddr";
 			goto fail;
 		}
-		if (kpte_get_perm(kpte) != epte_get_perm(epte)) {
+		if ((kpte_get_settings(kpte) & PTE_PERM) !=
+		    (epte_get_settings(epte) & PTE_PERM)) {
 			reason = "permissions";
 			goto fail;
 		}
diff --git a/kern/arch/x86/pmap_ops.h b/kern/arch/x86/pmap_ops.h
index 19a0fec..e5e08e1 100644
--- a/kern/arch/x86/pmap_ops.h
+++ b/kern/arch/x86/pmap_ops.h
@@ -90,10 +90,10 @@
 	return kpte_print(pte);
 }
 
-static inline void pte_write(pte_t pte, physaddr_t pa, int perm)
+static inline void pte_write(pte_t pte, physaddr_t pa, int settings)
 {
-	kpte_write(pte, pa, perm);
-	epte_write(kpte_to_epte(pte), pa, perm);
+	kpte_write(pte, pa, settings);
+	epte_write(kpte_to_epte(pte), pa, settings);
 }
 
 static inline void pte_clear_present(pte_t pte)
@@ -124,11 +124,15 @@
 	return kpte_has_perm_urw(pte);
 }
 
-/* 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)
+/* Settings includes protection (maskable via PTE_PROT) and other bits, such as
+ * jumbo, dirty, accessed, etc.  Whatever this returns can get fed back to
+ * pte_write.
+ *
+ * Arch-indep settings include: PTE_PERM (U, W, P, etc), PTE_D, PTE_A, PTE_PS.
+ * Other OSs (x86) may include others. */
+static inline int pte_get_settings(pte_t pte)
 {
-	return kpte_get_perm(pte);
+	return kpte_get_settings(pte);
 }
 
 static inline void pte_replace_perm(pte_t pte, int perm)
diff --git a/kern/arch/x86/vmm/ept.h b/kern/arch/x86/vmm/ept.h
index b2d3da9..4cb39ed 100644
--- a/kern/arch/x86/vmm/ept.h
+++ b/kern/arch/x86/vmm/ept.h
@@ -134,24 +134,26 @@
 	return (*epte & (EPTE_R | EPTE_W | EPTE_X)) == (EPTE_R | EPTE_W | EPTE_X);
 }
 
-/* We want to know User and Writable, in the 'PTE' sense.  All present epte
- * entries are User PTEs. */
-static inline int epte_get_perm(epte_t *epte)
+static inline int epte_get_settings(epte_t *epte)
 {
 	int settings = 0;
 	if (*epte & EPTE_P) {
+		/* We want to know User and Writable, in the 'PTE' sense.  All present
+		 * epte entries are User PTEs. */
 		settings |= PTE_P | PTE_U;
 		settings |= *epte & EPTE_W ? PTE_W : 0;
 	}
-	//settings |= *epte & EPTE_PS ? PTE_PS : 0; /* TODO */
+	settings |= *epte & EPTE_PS ? PTE_PS : 0;
+	settings |= *epte & EPTE_A ? PTE_A : 0;
+	settings |= *epte & EPTE_D ? PTE_D : 0;
 	return settings;
 }
 
 /* Again, we're replacing the old perms with U and/or W.  Any non-U are ignored,
- * as with epte_write.  R (and X) are implied. */
-static inline void epte_replace_perm(epte_t *epte, int settings)
+ * as with epte_write.  */
+static inline void epte_replace_perm(epte_t *epte, int perm)
 {
-	*epte = (*epte & ~EPTE_P) | __pte_to_epte_perm(settings & PTE_PERM);
+	*epte = (*epte & ~EPTE_P) | __pte_to_epte_perm(perm & PTE_PERM);
 }
 
 /* These ops might be the same for AMD as Intel; in which case we can move the
diff --git a/kern/src/mm.c b/kern/src/mm.c
index bf93513..9270970 100644
--- a/kern/src/mm.c
+++ b/kern/src/mm.c
@@ -292,7 +292,7 @@
 			/* TODO: check for jumbos */
 			if (upage_alloc(new_p, &pp, 0))
 				return -ENOMEM;
-			if (page_insert(new_p->env_pgdir, pp, va, pte_get_perm(pte))) {
+			if (page_insert(new_p->env_pgdir, pp, va, pte_get_settings(pte))) {
 				page_decref(pp);
 				return -ENOMEM;
 			}