vm: clear map cache after kernel requests
. fixes a dirty tlb situation (i.e. random crashes) on some hardware, seemingly new intel architectures (e.g. my desktop i7 machine)
This commit is contained in:
parent
0bb4bb9d51
commit
7cd4002083
3 changed files with 26 additions and 4 deletions
|
@ -31,7 +31,7 @@ PUBLIC int i386_paging_enabled = 0;
|
|||
|
||||
PRIVATE int psok = 0;
|
||||
|
||||
#define FREE_PDES_PER_CPU 3
|
||||
#define FREE_PDES_PER_CPU 2
|
||||
#define MAX_FREEPDES (FREE_PDES_PER_CPU * CONFIG_MAX_CPUS)
|
||||
PRIVATE int nfreepdes = 0, freepdes[MAX_FREEPDES];
|
||||
|
||||
|
@ -145,7 +145,7 @@ PRIVATE int lin_lin_copy(const struct proc *srcproc, vir_bytes srclinaddr,
|
|||
proc_nr_t procslot;
|
||||
|
||||
assert(vm_running);
|
||||
assert(nfreepdes >= 3);
|
||||
assert(nfreepdes >= 2);
|
||||
|
||||
assert(get_cpulocal_var(ptproc));
|
||||
assert(get_cpulocal_var(proc_ptr));
|
||||
|
@ -645,7 +645,7 @@ int vm_phys_memset(phys_bytes ph, const u8_t c, phys_bytes bytes)
|
|||
return OK;
|
||||
}
|
||||
|
||||
assert(nfreepdes >= 3);
|
||||
assert(nfreepdes >= 2);
|
||||
|
||||
assert(get_cpulocal_var(ptproc)->p_seg.p_cr3_v);
|
||||
|
||||
|
|
|
@ -36,6 +36,10 @@
|
|||
|
||||
#include "memory.h"
|
||||
|
||||
/* Free PDE slots we tell kernel about */
|
||||
#define FREE_PDES 2
|
||||
PRIVATE int first_free_pde = -1;
|
||||
|
||||
/* PDE used to map in kernel, kernel physical address. */
|
||||
PRIVATE int id_map_high_pde = -1, pagedir_pde = -1;
|
||||
PRIVATE u32_t global_bit = 0, pagedir_pde_val;
|
||||
|
@ -638,6 +642,18 @@ PUBLIC int pt_ptmap(struct vmproc *src_vmp, struct vmproc *dst_vmp)
|
|||
return OK;
|
||||
}
|
||||
|
||||
PUBLIC int pt_clearmapcache(void)
|
||||
{
|
||||
int f;
|
||||
/* Make sure kernel will invalidate tlb when using current
|
||||
* pagetable (i.e. vm's) to make new mappings before new cr3
|
||||
* is loaded.
|
||||
*/
|
||||
for(f = first_free_pde; f < first_free_pde+FREE_PDES; f++) {
|
||||
vmprocess->vm_pt.pt_dir[f] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* pt_writemap *
|
||||
*===========================================================================*/
|
||||
|
@ -876,6 +892,7 @@ PUBLIC void pt_init(phys_bytes usedlimit)
|
|||
vir_bytes sparepages_mem;
|
||||
phys_bytes sparepages_ph;
|
||||
vir_bytes ptr;
|
||||
int f = 0;
|
||||
|
||||
/* Shorthand. */
|
||||
newpt = &vmprocess->vm_pt;
|
||||
|
@ -1030,10 +1047,12 @@ PUBLIC void pt_init(phys_bytes usedlimit)
|
|||
I386_VM_PRESENT | I386_VM_USER | I386_VM_WRITE;
|
||||
|
||||
/* Tell kernel about free pde's. */
|
||||
while(free_pde*I386_BIG_PAGE_SIZE < VM_PROCSTART) {
|
||||
first_free_pde = free_pde;
|
||||
while(free_pde*I386_BIG_PAGE_SIZE < VM_PROCSTART && f < FREE_PDES) {
|
||||
if((r=sys_vmctl(SELF, VMCTL_I386_FREEPDE, free_pde++)) != OK) {
|
||||
panic("VMCTL_I386_FREEPDE failed: %d", r);
|
||||
}
|
||||
f++;
|
||||
}
|
||||
|
||||
/* first pde in use by process. */
|
||||
|
|
|
@ -112,6 +112,7 @@ PUBLIC int main(void)
|
|||
"message!\n", msg.m_source);
|
||||
}
|
||||
do_pagefaults(&msg);
|
||||
pt_clearmapcache();
|
||||
/*
|
||||
* do not reply to this call, the caller is unblocked by
|
||||
* a sys_vmctl() call in do_pagefaults if success. VM panics
|
||||
|
@ -419,6 +420,8 @@ PRIVATE void sef_cb_signal_handler(int signo)
|
|||
if(missing_spares > 0) {
|
||||
pt_cycle(); /* pagetable code wants to be called */
|
||||
}
|
||||
|
||||
pt_clearmapcache();
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
|
|
Loading…
Reference in a new issue