direct-io.hg

changeset 4339:04226a1b141c

bitkeeper revision 1.1159.275.1 (4244b7056FS2uC4AapFJtHCNgoKPFg)

No direct entry to __enter_scheduler allowed. Must always pass through
softirq handler. Also domain_crash() now returns and defers
descheduling from local CPU: old behaviour is still provided by
domain_crash_synchronous().
Signed-off-by: Keir Fraser <keir@xensource.com>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author cl349@firebug.cl.cam.ac.uk
date Sat Mar 26 01:12:37 2005 +0000 (2005-03-26)
parents dfc37b282730
children d1189200b017 bd8d20bfcf48
files xen/arch/x86/domain.c xen/arch/x86/memory.c xen/arch/x86/shadow.c xen/arch/x86/traps.c xen/arch/x86/x86_32/entry.S xen/common/domain.c xen/common/schedule.c xen/include/xen/sched.h
line diff
     1.1 --- a/xen/arch/x86/domain.c	Fri Mar 25 13:33:46 2005 +0000
     1.2 +++ b/xen/arch/x86/domain.c	Sat Mar 26 01:12:37 2005 +0000
     1.3 @@ -82,7 +82,8 @@ void startup_cpu_idle_loop(void)
     1.4      /* Just some sanity to ensure that the scheduler is set up okay. */
     1.5      ASSERT(current->id == IDLE_DOMAIN_ID);
     1.6      domain_unpause_by_systemcontroller(current);
     1.7 -    __enter_scheduler();
     1.8 +    raise_softirq(SCHEDULE_SOFTIRQ);
     1.9 +    do_softirq();
    1.10  
    1.11      /*
    1.12       * Declares CPU setup done to the boot processor.
     2.1 --- a/xen/arch/x86/memory.c	Fri Mar 25 13:33:46 2005 +0000
     2.2 +++ b/xen/arch/x86/memory.c	Sat Mar 26 01:12:37 2005 +0000
     2.3 @@ -1686,7 +1686,7 @@ void ptwr_flush(const int which)
     2.4          MEM_LOG("ptwr: Could not read pte at %p\n", ptep);
     2.5          /*
     2.6           * Really a bug. We could read this PTE during the initial fault,
     2.7 -         * and pagetables can't have changed meantime. XXX Multi-CPU guests?
     2.8 +         * and pagetables can't have changed meantime.
     2.9           */
    2.10          BUG();
    2.11      }
    2.12 @@ -1713,7 +1713,7 @@ void ptwr_flush(const int which)
    2.13          MEM_LOG("ptwr: Could not update pte at %p\n", ptep);
    2.14          /*
    2.15           * Really a bug. We could write this PTE during the initial fault,
    2.16 -         * and pagetables can't have changed meantime. XXX Multi-CPU guests?
    2.17 +         * and pagetables can't have changed meantime.
    2.18           */
    2.19          BUG();
    2.20      }
    2.21 @@ -1771,6 +1771,7 @@ void ptwr_flush(const int which)
    2.22                  *pl2e = mk_l2_pgentry(l2_pgentry_val(*pl2e) | _PAGE_PRESENT); 
    2.23              }
    2.24              domain_crash();
    2.25 +            return;
    2.26          }
    2.27          
    2.28          if ( unlikely(sl1e != NULL) )
    2.29 @@ -1834,13 +1835,17 @@ int ptwr_do_page_fault(unsigned long add
    2.30      /* Get the L2 index at which this L1 p.t. is always mapped. */
    2.31      l2_idx = page->u.inuse.type_info & PGT_va_mask;
    2.32      if ( unlikely(l2_idx >= PGT_va_unknown) )
    2.33 +    {
    2.34          domain_crash(); /* Urk! This L1 is mapped in multiple L2 slots! */
    2.35 +        return 0;
    2.36 +    }
    2.37      l2_idx >>= PGT_va_shift;
    2.38  
    2.39      if ( l2_idx == (addr >> L2_PAGETABLE_SHIFT) )
    2.40      {
    2.41          MEM_LOG("PTWR failure! Pagetable maps itself at %08lx\n", addr);
    2.42          domain_crash();
    2.43 +        return 0;
    2.44      }
    2.45  
    2.46      /*
    2.47 @@ -1908,6 +1913,7 @@ int ptwr_do_page_fault(unsigned long add
    2.48          unmap_domain_mem(ptwr_info[cpu].ptinfo[which].pl1e);
    2.49          ptwr_info[cpu].ptinfo[which].l1va = 0;
    2.50          domain_crash();
    2.51 +        return 0;
    2.52      }
    2.53      
    2.54      return EXCRET_fault_fixed;
    2.55 @@ -1938,40 +1944,6 @@ static __init int ptwr_init(void)
    2.56  
    2.57  #ifndef NDEBUG
    2.58  
    2.59 -void ptwr_status(void)
    2.60 -{
    2.61 -    unsigned long pte, *ptep, pfn;
    2.62 -    struct pfn_info *page;
    2.63 -    int cpu = smp_processor_id();
    2.64 -
    2.65 -    ptep = (unsigned long *)&linear_pg_table
    2.66 -        [ptwr_info[cpu].ptinfo[PTWR_PT_INACTIVE].l1va>>PAGE_SHIFT];
    2.67 -
    2.68 -    if ( __get_user(pte, ptep) ) {
    2.69 -        MEM_LOG("ptwr: Could not read pte at %p\n", ptep);
    2.70 -        domain_crash();
    2.71 -    }
    2.72 -
    2.73 -    pfn = pte >> PAGE_SHIFT;
    2.74 -    page = &frame_table[pfn];
    2.75 -    printk("need to alloc l1 page %p\n", page);
    2.76 -    /* make pt page writable */
    2.77 -    printk("need to make read-only l1-page at %p is %08lx\n",
    2.78 -           ptep, pte);
    2.79 -
    2.80 -    if ( ptwr_info[cpu].ptinfo[PTWR_PT_ACTIVE].l1va == 0 )
    2.81 -        return;
    2.82 -
    2.83 -    if ( __get_user(pte, (unsigned long *)
    2.84 -                    ptwr_info[cpu].ptinfo[PTWR_PT_ACTIVE].l1va) ) {
    2.85 -        MEM_LOG("ptwr: Could not read pte at %p\n", (unsigned long *)
    2.86 -                ptwr_info[cpu].ptinfo[PTWR_PT_ACTIVE].l1va);
    2.87 -        domain_crash();
    2.88 -    }
    2.89 -    pfn = pte >> PAGE_SHIFT;
    2.90 -    page = &frame_table[pfn];
    2.91 -}
    2.92 -
    2.93  void audit_domain(struct domain *d)
    2.94  {
    2.95      int ttot=0, ctot=0, io_mappings=0, lowmem_mappings=0;
     3.1 --- a/xen/arch/x86/shadow.c	Fri Mar 25 13:33:46 2005 +0000
     3.2 +++ b/xen/arch/x86/shadow.c	Sat Mar 26 01:12:37 2005 +0000
     3.3 @@ -580,15 +580,13 @@ int shadow_fault(unsigned long va, long 
     3.4                               &linear_pg_table[va >> PAGE_SHIFT])) )
     3.5      {
     3.6          SH_VVLOG("shadow_fault - EXIT: read gpte faulted" );
     3.7 -        shadow_unlock(m);
     3.8 -        return 0;
     3.9 +        goto fail;
    3.10      }
    3.11  
    3.12      if ( unlikely(!(gpte & _PAGE_PRESENT)) )
    3.13      {
    3.14          SH_VVLOG("shadow_fault - EXIT: gpte not present (%lx)",gpte );
    3.15 -        shadow_unlock(m);
    3.16 -        return 0;
    3.17 +        goto fail;
    3.18      }
    3.19  
    3.20      /* Write fault? */
    3.21 @@ -598,8 +596,7 @@ int shadow_fault(unsigned long va, long 
    3.22          {
    3.23              /* Write fault on a read-only mapping. */
    3.24              SH_VVLOG("shadow_fault - EXIT: wr fault on RO page (%lx)", gpte);
    3.25 -            shadow_unlock(m);
    3.26 -            return 0;
    3.27 +            goto fail;
    3.28          }
    3.29  
    3.30          l1pte_write_fault(m, &gpte, &spte);
    3.31 @@ -616,7 +613,10 @@ int shadow_fault(unsigned long va, long 
    3.32      /* XXX Watch out for read-only L2 entries! (not used in Linux). */
    3.33      if ( unlikely(__put_user(gpte, (unsigned long *)
    3.34                               &linear_pg_table[va >> PAGE_SHIFT])) )
    3.35 +    {
    3.36          domain_crash();
    3.37 +        goto fail;
    3.38 +    }
    3.39  
    3.40      /*
    3.41       * Update of shadow PTE can fail because the L1 p.t. is not shadowed,
    3.42 @@ -637,6 +637,10 @@ int shadow_fault(unsigned long va, long 
    3.43  
    3.44      check_pagetable(m, current->mm.pagetable, "post-sf");
    3.45      return EXCRET_fault_fixed;
    3.46 +
    3.47 + fail:
    3.48 +    shadow_unlock(m);
    3.49 +    return 0;
    3.50  }
    3.51  
    3.52  
     4.1 --- a/xen/arch/x86/traps.c	Fri Mar 25 13:33:46 2005 +0000
     4.2 +++ b/xen/arch/x86/traps.c	Sat Mar 26 01:12:37 2005 +0000
     4.3 @@ -654,8 +654,6 @@ asmlinkage int do_debug(struct xen_regs 
     4.4      struct domain *d = current;
     4.5      struct trap_bounce *tb = &d->thread.trap_bounce;
     4.6  
     4.7 -    DEBUGGER_trap_entry(TRAP_debug, regs);
     4.8 -
     4.9      __asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
    4.10  
    4.11      /* Mask out spurious debug traps due to lazy DR7 setting */
    4.12 @@ -666,6 +664,8 @@ asmlinkage int do_debug(struct xen_regs 
    4.13          goto out;
    4.14      }
    4.15  
    4.16 +    DEBUGGER_trap_entry(TRAP_debug, regs);
    4.17 +
    4.18      if ( !GUEST_FAULT(regs) )
    4.19      {
    4.20          /* Clear TF just for absolute sanity. */
     5.1 --- a/xen/arch/x86/x86_32/entry.S	Fri Mar 25 13:33:46 2005 +0000
     5.2 +++ b/xen/arch/x86/x86_32/entry.S	Sat Mar 26 01:12:37 2005 +0000
     5.3 @@ -112,7 +112,7 @@ DBLFLT1:GET_CURRENT(%ebx)
     5.4          jmp   test_all_events
     5.5  DBLFIX1:GET_CURRENT(%ebx)
     5.6          testb $TF_failsafe_return,DOMAIN_thread_flags(%ebx)
     5.7 -        jnz   domain_crash             # cannot reenter failsafe code
     5.8 +        jnz   domain_crash_synchronous # cannot reenter failsafe code
     5.9          orb   $TF_failsafe_return,DOMAIN_thread_flags(%ebx)
    5.10          jmp   test_all_events          # will return via failsafe code
    5.11  .previous
    5.12 @@ -330,7 +330,7 @@ DBLFLT2:jmp   process_guest_exception_an
    5.13  	.long FLT23,FIX7 , FLT24,FIX7 , FLT25,FIX7 , FLT26,FIX7 , FLT27,FIX7
    5.14  .previous
    5.15  .section __ex_table,"a"
    5.16 -        .long DBLFLT2,domain_crash
    5.17 +        .long DBLFLT2,domain_crash_synchronous
    5.18  .previous
    5.19  
    5.20          ALIGN
    5.21 @@ -620,9 +620,9 @@ 1:      orl  $X86_EFLAGS_VM,%edx   # For
    5.22          jmp test_all_events
    5.23  
    5.24  .section __ex_table,"a"
    5.25 -        .long VFLT1,domain_crash
    5.26 -        .long VFLT2,domain_crash
    5.27 -        .long VFLT3,domain_crash
    5.28 +        .long VFLT1,domain_crash_synchronous
    5.29 +        .long VFLT2,domain_crash_synchronous
    5.30 +        .long VFLT3,domain_crash_synchronous
    5.31  .previous
    5.32  
    5.33  .data
     6.1 --- a/xen/common/domain.c	Fri Mar 25 13:33:46 2005 +0000
     6.2 +++ b/xen/common/domain.c	Sat Mar 26 01:12:37 2005 +0000
     6.3 @@ -9,6 +9,7 @@
     6.4  #include <xen/lib.h>
     6.5  #include <xen/errno.h>
     6.6  #include <xen/sched.h>
     6.7 +#include <xen/softirq.h>
     6.8  #include <xen/mm.h>
     6.9  #include <xen/event.h>
    6.10  #include <xen/time.h>
    6.11 @@ -146,8 +147,15 @@ void domain_crash(void)
    6.12  
    6.13      send_guest_virq(dom0, VIRQ_DOM_EXC);
    6.14      
    6.15 -    __enter_scheduler();
    6.16 -    BUG();
    6.17 +    raise_softirq(SCHEDULE_SOFTIRQ);
    6.18 +}
    6.19 +
    6.20 +
    6.21 +void domain_crash_synchronous(void)
    6.22 +{
    6.23 +    domain_crash();
    6.24 +    for ( ; ; )
    6.25 +        do_softirq();
    6.26  }
    6.27  
    6.28  void domain_shutdown(u8 reason)
    6.29 @@ -169,18 +177,14 @@ void domain_shutdown(u8 reason)
    6.30          }
    6.31      }
    6.32  
    6.33 -    if ( reason == SHUTDOWN_crash )
    6.34 -    {
    6.35 -        domain_crash();
    6.36 -        BUG();
    6.37 -    }
    6.38 -
    6.39 -    current->shutdown_code = reason;
    6.40 -    set_bit(DF_SHUTDOWN, &current->flags);
    6.41 +    if ( (current->shutdown_code = reason) == SHUTDOWN_crash )
    6.42 +        set_bit(DF_CRASHED, &current->flags);
    6.43 +    else
    6.44 +        set_bit(DF_SHUTDOWN, &current->flags);
    6.45  
    6.46      send_guest_virq(dom0, VIRQ_DOM_EXC);
    6.47  
    6.48 -    __enter_scheduler();
    6.49 +    raise_softirq(SCHEDULE_SOFTIRQ);
    6.50  }
    6.51  
    6.52  unsigned int alloc_new_dom_mem(struct domain *d, unsigned int kbytes)
     7.1 --- a/xen/common/schedule.c	Fri Mar 25 13:33:46 2005 +0000
     7.2 +++ b/xen/common/schedule.c	Sat Mar 26 01:12:37 2005 +0000
     7.3 @@ -79,7 +79,8 @@ static struct scheduler *schedulers[] = 
     7.4      NULL
     7.5  };
     7.6  
     7.7 -/* Operations for the current scheduler. */
     7.8 +static void __enter_scheduler(void);
     7.9 +
    7.10  static struct scheduler ops;
    7.11  
    7.12  #define SCHED_OP(fn, ...)                                 \
    7.13 @@ -310,7 +311,7 @@ long sched_adjdom(struct sched_adjdom_cm
    7.14   * - deschedule the current domain (scheduler independent).
    7.15   * - pick a new domain (scheduler dependent).
    7.16   */
    7.17 -void __enter_scheduler(void)
    7.18 +static void __enter_scheduler(void)
    7.19  {
    7.20      struct domain *prev = current, *next = NULL;
    7.21      int                 cpu = prev->processor;
     8.1 --- a/xen/include/xen/sched.h	Fri Mar 25 13:33:46 2005 +0000
     8.2 +++ b/xen/include/xen/sched.h	Sat Mar 26 01:12:37 2005 +0000
     8.3 @@ -184,8 +184,19 @@ struct domain *find_domain_by_id(domid_t
     8.4  struct domain *find_last_domain(void);
     8.5  extern void domain_destruct(struct domain *d);
     8.6  extern void domain_kill(struct domain *d);
     8.7 +extern void domain_shutdown(u8 reason);
     8.8 +
     8.9 +/*
    8.10 + * Mark current domain as crashed. This function returns: the domain is not
    8.11 + * synchronously descheduled from any processor.
    8.12 + */
    8.13  extern void domain_crash(void);
    8.14 -extern void domain_shutdown(u8 reason);
    8.15 +
    8.16 +/*
    8.17 + * Mark current domain as crashed and synchronously deschedule from the local
    8.18 + * processor. This function never returns.
    8.19 + */
    8.20 +extern void domain_crash_synchronous(void) __attribute__((noreturn));
    8.21  
    8.22  void new_thread(struct domain *d,
    8.23                  unsigned long start_pc,
    8.24 @@ -207,8 +218,6 @@ void init_idle_task(void);
    8.25  void domain_wake(struct domain *d);
    8.26  void domain_sleep(struct domain *d);
    8.27  
    8.28 -void __enter_scheduler(void);
    8.29 -
    8.30  extern void switch_to(struct domain *prev, 
    8.31                        struct domain *next);
    8.32