ia64/xen-unstable

changeset 2073:4678a5d8fc54

bitkeeper revision 1.1143 (4110b5c38VYeFSdv3JdFEuUgJgQXcg)

Add a HYPERVISOR_vm_assist() hypercall for optionally enabling features
such as writeable pagetables.
author kaf24@scramble.cl.cam.ac.uk
date Wed Aug 04 10:09:07 2004 +0000 (2004-08-04)
parents 14ad99d6f689
children a3e585a0c6ca
files linux-2.6.7-xen-sparse/arch/xen/i386/kernel/setup.c linux-2.6.7-xen-sparse/include/asm-xen/hypervisor.h xen/arch/x86/traps.c xen/arch/x86/x86_32/emulate.c xen/arch/x86/x86_32/entry.S xen/common/kernel.c xen/include/hypervisor-ifs/hypervisor-if.h xen/include/xen/sched.h
line diff
     1.1 --- a/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/setup.c	Wed Aug 04 09:43:44 2004 +0000
     1.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/setup.c	Wed Aug 04 10:09:07 2004 +0000
     1.3 @@ -1096,6 +1096,13 @@ void __init setup_arch(char **cmdline_p)
     1.4  {
     1.5  	unsigned long max_low_pfn;
     1.6  
     1.7 +	HYPERVISOR_vm_assist(VMASST_CMD_enable,
     1.8 +			     VMASST_TYPE_4gb_segments);
     1.9 +#if 0
    1.10 +	HYPERVISOR_vm_assist(VMASST_CMD_enable,
    1.11 +			     VMASST_TYPE_writeable_pagetables);
    1.12 +#endif
    1.13 +
    1.14  	memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
    1.15  	early_cpu_init();
    1.16  
     2.1 --- a/linux-2.6.7-xen-sparse/include/asm-xen/hypervisor.h	Wed Aug 04 09:43:44 2004 +0000
     2.2 +++ b/linux-2.6.7-xen-sparse/include/asm-xen/hypervisor.h	Wed Aug 04 10:09:07 2004 +0000
     2.3 @@ -467,4 +467,15 @@ static inline int HYPERVISOR_update_va_m
     2.4      return ret;
     2.5  }
     2.6  
     2.7 +static inline int HYPERVISOR_vm_assist(unsigned int cmd, unsigned int type)
     2.8 +{
     2.9 +    int ret;
    2.10 +    __asm__ __volatile__ (
    2.11 +        TRAP_INSTR
    2.12 +        : "=a" (ret) : "0" (__HYPERVISOR_vm_assist),
    2.13 +        "b" (cmd), "c" (type) : "memory" );
    2.14 +
    2.15 +    return ret;
    2.16 +}
    2.17 +
    2.18  #endif /* __HYPERVISOR_H__ */
     3.1 --- a/xen/arch/x86/traps.c	Wed Aug 04 09:43:44 2004 +0000
     3.2 +++ b/xen/arch/x86/traps.c	Wed Aug 04 10:09:07 2004 +0000
     3.3 @@ -310,50 +310,54 @@ asmlinkage void do_page_fault(struct pt_
     3.4      struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id();
     3.5      trap_info_t *ti;
     3.6      unsigned long off, addr, fixup;
     3.7 -    struct domain *p = current;
     3.8 +    struct domain *d = current;
     3.9      extern int map_ldt_shadow_page(unsigned int);
    3.10 -    int cpu = smp_processor_id();
    3.11 +    int cpu = d->processor;
    3.12  
    3.13      __asm__ __volatile__ ("movl %%cr2,%0" : "=r" (addr) : );
    3.14  
    3.15      perfc_incrc(page_faults);
    3.16  
    3.17      if ( unlikely(addr >= LDT_VIRT_START) && 
    3.18 -         (addr < (LDT_VIRT_START + (p->mm.ldt_ents*LDT_ENTRY_SIZE))) )
    3.19 +         (addr < (LDT_VIRT_START + (d->mm.ldt_ents*LDT_ENTRY_SIZE))) )
    3.20      {
    3.21          /*
    3.22           * Copy a mapping from the guest's LDT, if it is valid. Otherwise we
    3.23           * send the fault up to the guest OS to be handled.
    3.24           */
    3.25          off  = addr - LDT_VIRT_START;
    3.26 -        addr = p->mm.ldt_base + off;
    3.27 +        addr = d->mm.ldt_base + off;
    3.28          if ( likely(map_ldt_shadow_page(off >> PAGE_SHIFT)) )
    3.29              return; /* successfully copied the mapping */
    3.30      }
    3.31  
    3.32 -    if ((addr >> L2_PAGETABLE_SHIFT) == ptwr_info[cpu].disconnected) {
    3.33 +    if ( (addr >> L2_PAGETABLE_SHIFT) == ptwr_info[cpu].disconnected )
    3.34 +    {
    3.35          ptwr_reconnect_disconnected(addr);
    3.36          return;
    3.37      }
    3.38  
    3.39 -    if (addr < PAGE_OFFSET && error_code & 2 && ptwr_do_page_fault(addr))
    3.40 +    if ( VM_ASSIST(d, VMASST_TYPE_writeable_pagetables) && 
    3.41 +         (addr < PAGE_OFFSET) &&
    3.42 +         ((error_code & 3) == 3) && /* write-protection fault */
    3.43 +         ptwr_do_page_fault(addr) )
    3.44          return;
    3.45  
    3.46 -    if ( unlikely(p->mm.shadow_mode) && 
    3.47 +    if ( unlikely(d->mm.shadow_mode) && 
    3.48           (addr < PAGE_OFFSET) && shadow_fault(addr, error_code) )
    3.49          return; /* Returns TRUE if fault was handled. */
    3.50  
    3.51      if ( unlikely(!(regs->xcs & 3)) )
    3.52          goto xen_fault;
    3.53  
    3.54 -    ti = p->thread.traps + 14;
    3.55 +    ti = d->thread.traps + 14;
    3.56      gtb->flags = GTBF_TRAP_CR2; /* page fault pushes %cr2 */
    3.57      gtb->cr2        = addr;
    3.58      gtb->error_code = error_code;
    3.59      gtb->cs         = ti->cs;
    3.60      gtb->eip        = ti->address;
    3.61      if ( TI_GET_IF(ti) )
    3.62 -        p->shared_info->vcpu_data[0].evtchn_upcall_mask = 1;
    3.63 +        d->shared_info->vcpu_data[0].evtchn_upcall_mask = 1;
    3.64      return; 
    3.65  
    3.66   xen_fault:
    3.67 @@ -361,7 +365,7 @@ asmlinkage void do_page_fault(struct pt_
    3.68      if ( likely((fixup = search_exception_table(regs->eip)) != 0) )
    3.69      {
    3.70          perfc_incrc(copy_user_faults);
    3.71 -        if ( !p->mm.shadow_mode )
    3.72 +        if ( !d->mm.shadow_mode )
    3.73              DPRINTK("Page fault: %08lx -> %08lx\n", regs->eip, fixup);
    3.74          regs->eip = fixup;
    3.75          regs->xds = regs->xes = regs->xfs = regs->xgs = __HYPERVISOR_DS;
    3.76 @@ -405,7 +409,7 @@ asmlinkage void do_page_fault(struct pt_
    3.77  
    3.78  asmlinkage void do_general_protection(struct pt_regs *regs, long error_code)
    3.79  {
    3.80 -    struct domain *p = current;
    3.81 +    struct domain *d = current;
    3.82      struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id();
    3.83      trap_info_t *ti;
    3.84      unsigned long fixup;
    3.85 @@ -457,7 +461,9 @@ asmlinkage void do_general_protection(st
    3.86      }
    3.87  
    3.88  #if defined(__i386__)
    3.89 -    if ( (error_code == 0) && gpf_emulate_4gb(regs) )
    3.90 +    if ( VM_ASSIST(d, VMASST_TYPE_4gb_segments) && 
    3.91 +         (error_code == 0) && 
    3.92 +         gpf_emulate_4gb(regs) )
    3.93          return;
    3.94  #endif
    3.95      
    3.96 @@ -469,7 +475,7 @@ asmlinkage void do_general_protection(st
    3.97      gtb->cs         = ti->cs;
    3.98      gtb->eip        = ti->address;
    3.99      if ( TI_GET_IF(ti) )
   3.100 -        p->shared_info->vcpu_data[0].evtchn_upcall_mask = 1;
   3.101 +        d->shared_info->vcpu_data[0].evtchn_upcall_mask = 1;
   3.102      return;
   3.103  
   3.104   gp_in_kernel:
     4.1 --- a/xen/arch/x86/x86_32/emulate.c	Wed Aug 04 09:43:44 2004 +0000
     4.2 +++ b/xen/arch/x86/x86_32/emulate.c	Wed Aug 04 10:09:07 2004 +0000
     4.3 @@ -499,31 +499,6 @@ int gpf_emulate_4gb(struct pt_regs *regs
     4.4          goto undecodeable;
     4.5      }
     4.6  
     4.7 -#if 0
     4.8 -    {
     4.9 -        char str1[] = { 0x65,0x8b,0x00,0x8b,0x30 };
    4.10 -        char str2[] = { 0x65,0x8b,0x02,0x8b,0x40,0x0c };
    4.11 -        char str3[] = { 0x65,0x8b,0x30,0x85,0xf6 };
    4.12 -        char str4[] = { 0x65,0x8b,0x00,0x5d,0x8b,0x00 };
    4.13 -        char str5[] = { 0x65,0x89,0x30,0x8b,0x45,0x08 };
    4.14 -        char str6[] = { 0x65,0x8b,0x00,0x8b,0x50,0x0c };
    4.15 -        char str7[] = { 0x65,0x89,0x51,0x00,0x83,0xc8,0xff };
    4.16 -        if ( (memcmp(eip,str1,5) == 0) ||
    4.17 -             (memcmp(eip,str2,6) == 0) ) goto out;
    4.18 -        if ( (memcmp(eip,str3,5) == 0) ||
    4.19 -             (memcmp(eip,str4,6) == 0) ) goto out;
    4.20 -        if ( (memcmp(eip,str5,6) == 0) ||
    4.21 -             (memcmp(eip,str6,6) == 0) ) goto out;
    4.22 -        if ( (memcmp(eip,str7,7) == 0) ||
    4.23 -             (memcmp(eip,str7,7) == 0) ) goto out;
    4.24 -    }
    4.25 -    printk(" .byte 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n",
    4.26 -           eip[-8],eip[-7],eip[-6],eip[-5],eip[-4],eip[-3],eip[-2],eip[-1]);
    4.27 -    printk(" .byte 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n",
    4.28 -           eip[0],eip[1],eip[2],eip[3],eip[4],eip[5],eip[6],eip[7]);
    4.29 -    printk(" @ %04x:%08lx\n", regs->xcs, regs->eip);
    4.30 -#endif
    4.31 -
    4.32      /* Success! */
    4.33      perfc_incrc(emulations);
    4.34      regs->eip += pb - eip;
     5.1 --- a/xen/arch/x86/x86_32/entry.S	Wed Aug 04 09:43:44 2004 +0000
     5.2 +++ b/xen/arch/x86/x86_32/entry.S	Wed Aug 04 10:09:07 2004 +0000
     5.3 @@ -719,6 +719,7 @@ ENTRY(hypercall_table)
     5.4          .long SYMBOL_NAME(do_console_io)
     5.5          .long SYMBOL_NAME(do_physdev_op)
     5.6          .long SYMBOL_NAME(do_update_va_mapping_otherdomain) /* 20 */
     5.7 +        .long SYMBOL_NAME(do_vm_assist)
     5.8          .rept NR_hypercalls-((.-hypercall_table)/4)
     5.9          .long SYMBOL_NAME(do_ni_hypercall)
    5.10          .endr
     6.1 --- a/xen/common/kernel.c	Wed Aug 04 09:43:44 2004 +0000
     6.2 +++ b/xen/common/kernel.c	Wed Aug 04 10:09:07 2004 +0000
     6.3 @@ -340,6 +340,24 @@ long do_xen_version(int cmd)
     6.4      return (XEN_VERSION<<16) | (XEN_SUBVERSION);
     6.5  }
     6.6  
     6.7 +long do_vm_assist(unsigned int cmd, unsigned int type)
     6.8 +{
     6.9 +    if ( type > (sizeof(unsigned long) * 8) )
    6.10 +        return -EINVAL;
    6.11 +
    6.12 +    switch ( cmd )
    6.13 +    {
    6.14 +    case VMASST_CMD_enable:
    6.15 +        set_bit(type, &current->vm_assist);
    6.16 +        return 0;
    6.17 +    case VMASST_CMD_disable:
    6.18 +        clear_bit(type, &current->vm_assist);
    6.19 +        return 0;
    6.20 +    }
    6.21 +
    6.22 +    return -ENOSYS;
    6.23 +}
    6.24 +
    6.25  long do_ni_hypercall(void)
    6.26  {
    6.27      /* No-op hypercall. */
     7.1 --- a/xen/include/hypervisor-ifs/hypervisor-if.h	Wed Aug 04 09:43:44 2004 +0000
     7.2 +++ b/xen/include/hypervisor-ifs/hypervisor-if.h	Wed Aug 04 10:09:07 2004 +0000
     7.3 @@ -44,6 +44,7 @@
     7.4  #define __HYPERVISOR_console_io           18
     7.5  #define __HYPERVISOR_physdev_op           19
     7.6  #define __HYPERVISOR_update_va_mapping_otherdomain 20
     7.7 +#define __HYPERVISOR_vm_assist            21
     7.8  
     7.9  /*
    7.10   * MULTICALLS
    7.11 @@ -181,6 +182,14 @@
    7.12  #define MEMOP_increase_reservation 0
    7.13  #define MEMOP_decrease_reservation 1
    7.14  
    7.15 +/*
    7.16 + * Commands to HYPERVISOR_vm_assist().
    7.17 + */
    7.18 +#define VMASST_CMD_enable                0
    7.19 +#define VMASST_CMD_disable               1
    7.20 +#define VMASST_TYPE_4gb_segments         0
    7.21 +#define VMASST_TYPE_writeable_pagetables 1
    7.22 +
    7.23  #ifndef __ASSEMBLY__
    7.24  
    7.25  typedef u32 domid_t;
     8.1 --- a/xen/include/xen/sched.h	Wed Aug 04 09:43:44 2004 +0000
     8.2 +++ b/xen/include/xen/sched.h	Wed Aug 04 10:09:07 2004 +0000
     8.3 @@ -144,6 +144,7 @@ struct domain
     8.4      unsigned long *io_bitmap; /* Pointer to task's IO bitmap or NULL */
     8.5  
     8.6      unsigned long flags;
     8.7 +    unsigned long vm_assist;
     8.8  
     8.9      atomic_t refcnt;
    8.10      atomic_t pausecnt;
    8.11 @@ -289,6 +290,8 @@ static inline void domain_unpause_by_sys
    8.12  #define IS_PRIV(_d) (test_bit(DF_PRIVILEGED, &(_d)->flags))
    8.13  #define IS_CAPABLE_PHYSDEV(_d) (test_bit(DF_PHYSDEV, &(_d)->flags))
    8.14  
    8.15 +#define VM_ASSIST(_d,_t) (test_bit((_t), &(_d)->vm_assist))
    8.16 +
    8.17  #include <xen/slab.h>
    8.18  #include <asm/domain.h>
    8.19