Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F106096725
D18874.id53003.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D18874.id53003.diff
View Options
Index: sys/riscv/include/pcb.h
===================================================================
--- sys/riscv/include/pcb.h
+++ sys/riscv/include/pcb.h
@@ -55,7 +55,6 @@
#define PCB_FP_STARTED 0x1
#define PCB_FP_USERMASK 0x1
uint64_t pcb_sepc; /* Supervisor exception pc */
- vm_offset_t pcb_l1addr; /* L1 page tables base address */
vm_offset_t pcb_onfault; /* Copyinout fault handler */
};
Index: sys/riscv/include/pcpu.h
===================================================================
--- sys/riscv/include/pcpu.h
+++ sys/riscv/include/pcpu.h
@@ -45,6 +45,7 @@
#define ALT_STACK_SIZE 128
#define PCPU_MD_FIELDS \
+ struct pmap *pc_curpmap; /* Currently active pmap */ \
uint32_t pc_pending_ipis; /* IPIs pending to this CPU */ \
char __pad[61]
Index: sys/riscv/include/pmap.h
===================================================================
--- sys/riscv/include/pmap.h
+++ sys/riscv/include/pmap.h
@@ -41,6 +41,7 @@
#ifndef LOCORE
#include <sys/queue.h>
+#include <sys/_cpuset.h>
#include <sys/_lock.h>
#include <sys/_mutex.h>
@@ -80,6 +81,7 @@
struct mtx pm_mtx;
struct pmap_statistics pm_stats; /* pmap statictics */
pd_entry_t *pm_l1;
+ cpuset_t pm_active; /* active on cpus */
TAILQ_HEAD(,pv_chunk) pm_pvchunk; /* list of mappings in pmap */
LIST_ENTRY(pmap) pm_list; /* List of all pmaps */
struct vm_radix pm_root;
@@ -137,6 +139,10 @@
#define L1_MAPPABLE_P(va, pa, size) \
((((va) | (pa)) & L1_OFFSET) == 0 && (size) >= L1_SIZE)
+struct thread;
+
+void pmap_activate_boot(pmap_t);
+void pmap_activate_sw(struct thread *);
void pmap_bootstrap(vm_offset_t, vm_paddr_t, vm_size_t);
void pmap_kenter_device(vm_offset_t, vm_size_t, vm_paddr_t);
vm_paddr_t pmap_kextract(vm_offset_t va);
Index: sys/riscv/riscv/genassym.c
===================================================================
--- sys/riscv/riscv/genassym.c
+++ sys/riscv/riscv/genassym.c
@@ -63,7 +63,6 @@
ASSYM(TDF_NEEDRESCHED, TDF_NEEDRESCHED);
ASSYM(PCB_ONFAULT, offsetof(struct pcb, pcb_onfault));
-ASSYM(PCB_L1ADDR, offsetof(struct pcb, pcb_l1addr));
ASSYM(PCB_SIZE, sizeof(struct pcb));
ASSYM(PCB_RA, offsetof(struct pcb, pcb_ra));
ASSYM(PCB_SP, offsetof(struct pcb, pcb_sp));
Index: sys/riscv/riscv/machdep.c
===================================================================
--- sys/riscv/riscv/machdep.c
+++ sys/riscv/riscv/machdep.c
@@ -871,10 +871,6 @@
init_proc0(rvbp->kern_stack);
- /* set page table base register for thread0 */
- thread0.td_pcb->pcb_l1addr = \
- (rvbp->kern_l1pt - KERNBASE + rvbp->kern_phys);
-
msgbufinit(msgbufp, msgbufsize);
mutex_init();
init_param2(physmem);
Index: sys/riscv/riscv/mp_machdep.c
===================================================================
--- sys/riscv/riscv/mp_machdep.c
+++ sys/riscv/riscv/mp_machdep.c
@@ -58,6 +58,7 @@
#include <vm/pmap.h>
#include <vm/vm_extern.h>
#include <vm/vm_kern.h>
+#include <vm/vm_map.h>
#include <machine/intr.h>
#include <machine/smp.h>
@@ -255,6 +256,9 @@
/* Enable external (PLIC) interrupts */
csr_set(sie, SIE_SEIE);
+ /* Activate process 0's pmap. */
+ pmap_activate_boot(vmspace_pmap(proc0.p_vmspace));
+
mtx_lock_spin(&ap_boot_mtx);
atomic_add_rel_32(&smp_cpus, 1);
Index: sys/riscv/riscv/pmap.c
===================================================================
--- sys/riscv/riscv/pmap.c
+++ sys/riscv/riscv/pmap.c
@@ -118,9 +118,10 @@
*/
#include <sys/param.h>
+#include <sys/systm.h>
#include <sys/bitstring.h>
#include <sys/bus.h>
-#include <sys/systm.h>
+#include <sys/cpuset.h>
#include <sys/kernel.h>
#include <sys/ktr.h>
#include <sys/lock.h>
@@ -566,6 +567,8 @@
rw_init(&pvh_global_lock, "pmap pv global");
+ CPU_FILL(&kernel_pmap->pm_active);
+
/* Assume the address we were loaded to is a valid physical address. */
min_pa = max_pa = kernstart;
@@ -723,9 +726,6 @@
* In general, the calling thread uses a plain fence to order the
* writes to the page tables before invoking an SBI callback to invoke
* sfence_vma() on remote CPUs.
- *
- * Since the riscv pmap does not yet have a pm_active field, IPIs are
- * sent to all CPUs in the system.
*/
static void
pmap_invalidate_page(pmap_t pmap, vm_offset_t va)
@@ -733,10 +733,11 @@
cpuset_t mask;
sched_pin();
- mask = all_cpus;
+ mask = pmap->pm_active;
CPU_CLR(PCPU_GET(cpuid), &mask);
fence();
- sbi_remote_sfence_vma(mask.__bits, va, 1);
+ if (!CPU_EMPTY(&mask) && smp_started)
+ sbi_remote_sfence_vma(mask.__bits, va, 1);
sfence_vma_page(va);
sched_unpin();
}
@@ -747,10 +748,11 @@
cpuset_t mask;
sched_pin();
- mask = all_cpus;
+ mask = pmap->pm_active;
CPU_CLR(PCPU_GET(cpuid), &mask);
fence();
- sbi_remote_sfence_vma(mask.__bits, sva, eva - sva + 1);
+ if (!CPU_EMPTY(&mask) && smp_started)
+ sbi_remote_sfence_vma(mask.__bits, sva, eva - sva + 1);
/*
* Might consider a loop of sfence_vma_page() for a small
@@ -766,16 +768,17 @@
cpuset_t mask;
sched_pin();
- mask = all_cpus;
+ mask = pmap->pm_active;
CPU_CLR(PCPU_GET(cpuid), &mask);
- fence();
/*
* XXX: The SBI doc doesn't detail how to specify x0 as the
* address to perform a global fence. BBL currently treats
* all sfence_vma requests as global however.
*/
- sbi_remote_sfence_vma(mask.__bits, 0, 0);
+ fence();
+ if (!CPU_EMPTY(&mask) && smp_started)
+ sbi_remote_sfence_vma(mask.__bits, 0, 0);
sfence_vma();
sched_unpin();
}
@@ -1199,6 +1202,8 @@
PMAP_LOCK_INIT(pmap);
bzero(&pmap->pm_stats, sizeof(pmap->pm_stats));
pmap->pm_l1 = kernel_pmap->pm_l1;
+ CPU_ZERO(&pmap->pm_active);
+ pmap_activate_boot(pmap);
}
int
@@ -1222,6 +1227,8 @@
bzero(&pmap->pm_stats, sizeof(pmap->pm_stats));
+ CPU_ZERO(&pmap->pm_active);
+
/* Install kernel pagetables */
memcpy(pmap->pm_l1, kernel_pmap->pm_l1, PAGE_SIZE);
@@ -1411,6 +1418,8 @@
KASSERT(pmap->pm_stats.resident_count == 0,
("pmap_release: pmap resident count %ld != 0",
pmap->pm_stats.resident_count));
+ KASSERT(CPU_EMPTY(&pmap->pm_active),
+ ("releasing active pmap %p", pmap));
mtx_lock(&allpmaps_lock);
LIST_REMOVE(pmap, pm_list);
@@ -4263,25 +4272,59 @@
}
void
-pmap_activate(struct thread *td)
+pmap_activate_sw(struct thread *td)
{
- pmap_t pmap;
- uint64_t reg;
+ pmap_t oldpmap, pmap;
+ u_int cpu;
- critical_enter();
+ oldpmap = PCPU_GET(curpmap);
pmap = vmspace_pmap(td->td_proc->p_vmspace);
- td->td_pcb->pcb_l1addr = vtophys(pmap->pm_l1);
- reg = SATP_MODE_SV39;
- reg |= (td->td_pcb->pcb_l1addr >> PAGE_SHIFT);
- load_satp(reg);
+ load_satp(SATP_MODE_SV39 | (vtophys(pmap->pm_l1) >> PAGE_SHIFT));
+
+ if (pmap == oldpmap) {
+ critical_exit();
+ return;
+ }
+
+ cpu = PCPU_GET(cpuid);
+#ifdef SMP
+ CPU_SET_ATOMIC(cpu, &pmap->pm_active);
+ CPU_CLR_ATOMIC(cpu, &oldpmap->pm_active);
+#else
+ CPU_SET(cpu, &pmap->pm_active);
+ CPU_CLR(cpu, &oldpmap->pm_active);
+#endif
+ PCPU_SET(curpmap, pmap);
pmap_invalidate_all(pmap);
+}
+
+void
+pmap_activate(struct thread *td)
+{
+
+ critical_enter();
+ pmap_activate_sw(td);
critical_exit();
}
void
-pmap_sync_icache(pmap_t pm, vm_offset_t va, vm_size_t sz)
+pmap_activate_boot(pmap_t pmap)
+{
+ u_int cpu;
+
+ cpu = PCPU_GET(cpuid);
+#ifdef SMP
+ CPU_SET_ATOMIC(cpu, &pmap->pm_active);
+#else
+ CPU_SET(cpu, &pmap->pm_active);
+#endif
+ PCPU_SET(curpmap, pmap);
+}
+
+void
+pmap_sync_icache(pmap_t pmap, vm_offset_t va, vm_size_t sz)
{
cpuset_t mask;
@@ -4297,7 +4340,8 @@
mask = all_cpus;
CPU_CLR(PCPU_GET(cpuid), &mask);
fence();
- sbi_remote_fence_i(mask.__bits);
+ if (!CPU_EMPTY(&mask) && smp_started)
+ sbi_remote_fence_i(mask.__bits);
sched_unpin();
}
Index: sys/riscv/riscv/swtch.S
===================================================================
--- sys/riscv/riscv/swtch.S
+++ sys/riscv/riscv/swtch.S
@@ -207,28 +207,21 @@
END(fpe_state_clear)
/*
- * void cpu_throw(struct thread *old, struct thread *new)
+ * void cpu_throw(struct thread *old __unused, struct thread *new)
*/
ENTRY(cpu_throw)
+ /* Activate the new thread's pmap. */
+ mv s0, a1
+ mv a0, a1
+ call _C_LABEL(pmap_activate_sw)
+ mv a0, s0
+
/* Store the new curthread */
- sd a1, PC_CURTHREAD(gp)
+ sd a0, PC_CURTHREAD(gp)
/* And the new pcb */
- ld x13, TD_PCB(a1)
+ ld x13, TD_PCB(a0)
sd x13, PC_CURPCB(gp)
- sfence.vma
-
- /* Switch to the new pmap */
- ld t0, PCB_L1ADDR(x13)
- srli t0, t0, PAGE_SHIFT
- li t1, SATP_MODE_SV39
- or t0, t0, t1
- csrw satp, t0
-
- /* TODO: Invalidate the TLB */
-
- sfence.vma
-
/* Load registers */
ld ra, (PCB_RA)(x13)
ld sp, (PCB_SP)(x13)
@@ -250,7 +243,7 @@
#ifdef FPE
/* Is FPE enabled for new thread? */
- ld t0, TD_FRAME(a1)
+ ld t0, TD_FRAME(a0)
ld t1, (TF_SSTATUS)(t0)
li t2, SSTATUS_FS_MASK
and t3, t1, t2
@@ -324,38 +317,27 @@
1:
#endif
- /*
- * Restore the saved context.
- */
- ld x13, TD_PCB(a1)
-
- /*
- * TODO: We may need to flush the cache here if switching
- * to a user process.
- */
-
- sfence.vma
-
- /* Switch to the new pmap */
- ld t0, PCB_L1ADDR(x13)
- srli t0, t0, PAGE_SHIFT
- li t1, SATP_MODE_SV39
- or t0, t0, t1
- csrw satp, t0
-
- /* TODO: Invalidate the TLB */
-
- sfence.vma
+ /* Activate the new thread's pmap */
+ mv s0, a0
+ mv s1, a1
+ mv s2, a2
+ mv a0, a1
+ call _C_LABEL(pmap_activate_sw)
+ mv a1, s1
/* Release the old thread */
- sd a2, TD_LOCK(a0)
+ sd s2, TD_LOCK(s0)
#if defined(SCHED_ULE) && defined(SMP)
/* Spin if TD_LOCK points to a blocked_lock */
- la a2, _C_LABEL(blocked_lock)
+ la s2, _C_LABEL(blocked_lock)
1:
ld t0, TD_LOCK(a1)
- beq t0, a2, 1b
+ beq t0, s2, 1b
#endif
+ /*
+ * Restore the saved context.
+ */
+ ld x13, TD_PCB(a1)
/* Restore the registers */
ld tp, (PCB_TP)(x13)
Index: sys/riscv/riscv/vm_machdep.c
===================================================================
--- sys/riscv/riscv/vm_machdep.c
+++ sys/riscv/riscv/vm_machdep.c
@@ -92,9 +92,6 @@
td2->td_pcb = pcb2;
bcopy(td1->td_pcb, pcb2, sizeof(*pcb2));
- td2->td_pcb->pcb_l1addr =
- vtophys(vmspace_pmap(td2->td_proc->p_vmspace)->pm_l1);
-
tf = (struct trapframe *)STACKALIGN((struct trapframe *)pcb2 - 1);
bcopy(td1->td_frame, tf, sizeof(*tf));
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Dec 26, 8:35 AM (11 h, 31 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15602899
Default Alt Text
D18874.id53003.diff (9 KB)
Attached To
Mode
D18874: Implement per-CPU pmap activation tracking.
Attached
Detach File
Event Timeline
Log In to Comment