summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Morris <[email protected]>2019-07-16 17:02:21 -0400
committerRobert Morris <[email protected]>2019-07-16 17:02:21 -0400
commitebc39372096280a4a5957d3e3836c859e5d78a79 (patch)
tree8df08ba410ac0f829b120f76e896bfe3658ddb96
parent6bbc2b2245c5b006824eb42ef33d5b296158a693 (diff)
downloadxv6-labs-ebc39372096280a4a5957d3e3836c859e5d78a79.tar.gz
xv6-labs-ebc39372096280a4a5957d3e3836c859e5d78a79.tar.bz2
xv6-labs-ebc39372096280a4a5957d3e3836c859e5d78a79.zip
conservatively call sfence.vma before every satp load.
-rw-r--r--kernel/proc.c2
-rw-r--r--kernel/riscv.h11
-rw-r--r--kernel/trampoline.S4
-rw-r--r--kernel/vm.c1
4 files changed, 16 insertions, 2 deletions
diff --git a/kernel/proc.c b/kernel/proc.c
index 0655783..6ba3fec 100644
--- a/kernel/proc.c
+++ b/kernel/proc.c
@@ -544,7 +544,7 @@ sleep(void *chan, struct spinlock *lk)
}
//PAGEBREAK!
-// Wake up p, used by exit().
+// Wake up p if it is sleeping in wait(); used by exit().
// Caller must hold p->lock.
static void
wakeup1(struct proc *p)
diff --git a/kernel/riscv.h b/kernel/riscv.h
index e5c0f64..e35f3bc 100644
--- a/kernel/riscv.h
+++ b/kernel/riscv.h
@@ -312,6 +312,17 @@ r_ra()
return x;
}
+// tell the machine to finish any previous writes to
+// PTEs, so that a subsequent use of a virtual
+// address or load of the SATP will see those writes.
+// perhaps this also flushes the TLB.
+static inline void
+sfence_vma()
+{
+ // the zero, zero means flush all TLB entries.
+ asm volatile("sfence.vma zero, zero");
+}
+
#define PGSIZE 4096 // bytes per page
#define PGSHIFT 12 // bits of offset within a page
diff --git a/kernel/trampoline.S b/kernel/trampoline.S
index b992ea6..471a29c 100644
--- a/kernel/trampoline.S
+++ b/kernel/trampoline.S
@@ -17,7 +17,8 @@ trampout:
# a0: p->tf in user page table
# a1: new value for satp, for user page table
- # switch to user page table
+ # switch to user page table.
+ sfence.vma zero, zero
csrw satp, a1
# put the saved user a0 in sscratch, so we
@@ -128,6 +129,7 @@ trampin:
# restore kernel page table from p->tf->kernel_satp
ld t1, 0(a0)
+ sfence.vma zero, zero
csrw satp, t1
# a0 is no longer valid, since the kernel page
diff --git a/kernel/vm.c b/kernel/vm.c
index bdb53c2..412ec8c 100644
--- a/kernel/vm.c
+++ b/kernel/vm.c
@@ -61,6 +61,7 @@ kvminit()
void
kvminithart()
{
+ sfence_vma();
w_satp(MAKE_SATP(kernel_pagetable));
}