minix/kernel/arch/i386/arch_do_vmctl.c
Tomas Hruby 13a0d5fa5e SMP - Cpu local variables
- most global variables carry information which is specific to the
  local CPU and each CPU must have its own copy

- cpu local variable must be declared in cpulocal.h between
  DECLARE_CPULOCAL_START and DECLARE_CPULOCAL_END markers using
  DECLARE_CPULOCAL macro

- to access the cpu local data the provided macros must be used

	get_cpu_var(cpu, name)
	get_cpu_var_ptr(cpu, name)

	get_cpulocal_var(name)
	get_cpulocal_var_ptr(name)

- using this macros makes future changes in the implementation
  possible

- switching to ELF will make the declaration of cpu local data much
  simpler, e.g.

  CPULOCAL int blah;

  anywhere in the kernel source code
2010-09-15 14:09:46 +00:00

70 lines
1.6 KiB
C

/* The kernel call implemented in this file:
* m_type: SYS_VMCTL
*
* The parameters for this kernel call are:
* SVMCTL_WHO which process
* SVMCTL_PARAM set this setting (VMCTL_*)
* SVMCTL_VALUE to this value
*/
#include "kernel/system.h"
#include <minix/type.h>
#include "arch_proto.h"
/*===========================================================================*
* arch_do_vmctl *
*===========================================================================*/
PUBLIC int arch_do_vmctl(m_ptr, p)
register message *m_ptr; /* pointer to request message */
struct proc *p;
{
switch(m_ptr->SVMCTL_PARAM) {
case VMCTL_I386_GETCR3:
/* Get process CR3. */
m_ptr->SVMCTL_VALUE = p->p_seg.p_cr3;
return OK;
case VMCTL_SETADDRSPACE:
/* Set process CR3. */
if(m_ptr->SVMCTL_PTROOT) {
p->p_seg.p_cr3 = m_ptr->SVMCTL_PTROOT;
p->p_seg.p_cr3_v = (u32_t *) m_ptr->SVMCTL_PTROOT_V;
p->p_misc_flags |= MF_FULLVM;
if(p == get_cpulocal_var(ptproc)) {
write_cr3(p->p_seg.p_cr3);
}
} else {
p->p_seg.p_cr3 = 0;
p->p_seg.p_cr3_v = NULL;
p->p_misc_flags &= ~MF_FULLVM;
}
RTS_UNSET(p, RTS_VMINHIBIT);
return OK;
case VMCTL_INCSP:
/* Increase process SP. */
p->p_reg.sp += m_ptr->SVMCTL_VALUE;
return OK;
case VMCTL_I386_KERNELLIMIT:
{
int r;
/* VM wants kernel to increase its segment. */
r = prot_set_kern_seg_limit(m_ptr->SVMCTL_VALUE);
return r;
}
case VMCTL_I386_FREEPDE:
{
i386_freepde(m_ptr->SVMCTL_VALUE);
return OK;
}
case VMCTL_FLUSHTLB:
{
reload_cr3();
return OK;
}
}
printf("arch_do_vmctl: strange param %d\n", m_ptr->SVMCTL_PARAM);
return EINVAL;
}