diff options
author | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2004-05-12 16:24:54 +0000 |
---|---|---|
committer | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2004-05-12 16:24:54 +0000 |
commit | 577256743338ab1d65574b77f626f252860f3f88 (patch) | |
tree | bbc4f5549bcb56521bca601fcce122d404118fae /xen | |
parent | c9cbf814f77829b03cf273042c147b4ef754e939 (diff) | |
download | xen-577256743338ab1d65574b77f626f252860f3f88.tar.gz xen-577256743338ab1d65574b77f626f252860f3f88.tar.bz2 xen-577256743338ab1d65574b77f626f252860f3f88.zip |
bitkeeper revision 1.891.1.13 (40a24fd6V2eF76NjMSt5mccf1Jh1qQ)
Lazy page-table switching.
Diffstat (limited to 'xen')
-rw-r--r-- | xen/arch/i386/process.c | 22 | ||||
-rw-r--r-- | xen/common/domain.c | 17 | ||||
-rw-r--r-- | xen/common/memory.c | 13 |
3 files changed, 29 insertions, 23 deletions
diff --git a/xen/arch/i386/process.c b/xen/arch/i386/process.c index 29c4fde8cb..408daa1f14 100644 --- a/xen/arch/i386/process.c +++ b/xen/arch/i386/process.c @@ -270,7 +270,7 @@ void switch_to(struct task_struct *prev_p, struct task_struct *next_p) tss->ss1 = next->guestos_ss; /* Maybe switch the debug registers. */ - if ( next->debugreg[7] ) + if ( unlikely(next->debugreg[7]) ) { loaddebug(next, 0); loaddebug(next, 1); @@ -280,10 +280,17 @@ void switch_to(struct task_struct *prev_p, struct task_struct *next_p) loaddebug(next, 6); loaddebug(next, 7); } + + /* Switch page tables. */ + write_ptbase(&next_p->mm); + tlb_clocktick(); } - if ( ( prev_p->io_bitmap != NULL ) || ( next_p->io_bitmap != NULL ) ) { - if ( next_p->io_bitmap != NULL ) { + if ( unlikely(prev_p->io_bitmap != NULL) || + unlikely(next_p->io_bitmap != NULL) ) + { + if ( next_p->io_bitmap != NULL ) + { /* Copy in the appropriate parts of the IO bitmap. We use the * selector to copy only the interesting parts of the bitmap. */ @@ -314,7 +321,9 @@ void switch_to(struct task_struct *prev_p, struct task_struct *next_p) tss->bitmap = IO_BITMAP_OFFSET; - } else { + } + else + { /* In this case, we're switching FROM a task with IO port access, * to a task that doesn't use the IO bitmap. We set any TSS bits * that might have been cleared, ready for future use. */ @@ -332,11 +341,6 @@ void switch_to(struct task_struct *prev_p, struct task_struct *next_p) tss->bitmap = INVALID_IO_BITMAP_OFFSET; } } - - - /* Switch page tables. */ - write_ptbase(&next_p->mm); - tlb_clocktick(); set_current(next_p); diff --git a/xen/common/domain.c b/xen/common/domain.c index 1b8759e912..f19c05eaf2 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -214,10 +214,6 @@ void __kill_domain(struct task_struct *p) *pp = p->next_hash; write_unlock_irqrestore(&tasklist_lock, flags); - if ( atomic_read(&p->refcnt) >2 ) - DPRINTK("Domain refcnt>1 so kil deferred. Missing put_task? p=%p cur=%p cnt=%d\n",p,current,atomic_read(&p->refcnt)); - - if ( p == current ) { __enter_scheduler(); @@ -412,7 +408,16 @@ void free_all_dom_mem(struct task_struct *p) INIT_LIST_HEAD(&zombies); - if ( p->mm.shadow_mode ) shadow_mode_disable(p); + /* + * If we're executing the idle task then we may still be running over the + * dead domain's page tables. We'd better fix that before freeing them! + */ + if ( is_idle_task(current) ) + write_ptbase(¤t->mm); + + /* Exit shadow mode before deconstructing final guest page table. */ + if ( p->mm.shadow_mode ) + shadow_mode_disable(p); /* STEP 1. Drop the in-use reference to the page-table base. */ put_page_and_type(&frame_table[pagetable_val(p->mm.pagetable) >> @@ -1066,7 +1071,7 @@ int construct_dom0(struct task_struct *p, set_bit(PF_CONSTRUCTED, &p->flags); -#if 0 // XXXXX DO NOT CHECK IN ENABLED !!! (but useful for testing so leave) +#if 0 /* XXXXX DO NOT CHECK IN ENABLED !!! (but useful for testing so leave) */ shadow_mode_enable(&p->mm, SHM_test); #endif diff --git a/xen/common/memory.c b/xen/common/memory.c index 5acfae8482..3f8ee288ee 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -194,7 +194,6 @@ static struct { */ void __init init_frametable(unsigned long nr_pages) { - int i; unsigned long mfn; memset(percpu_info, 0, sizeof(percpu_info)); @@ -209,15 +208,13 @@ void __init init_frametable(unsigned long nr_pages) INIT_LIST_HEAD(&free_list); free_pfns = 0; - /* so that we can map them latter, set the ownership of pages - belonging to the machine_to_phys_mapping to CPU0 idle task */ - - mfn = virt_to_phys((void *)RDWR_MPT_VIRT_START)>>PAGE_SHIFT; -// for(i=0;i<nr_pages;i+=1024,mfn++) - for(i=0;i<1024*1024;i+=1024,mfn++) + /* Pin the ownership of the MP table so that DOM0 can map it later. */ + for ( mfn = virt_to_phys((void *)RDWR_MPT_VIRT_START)>>PAGE_SHIFT; + mfn < virt_to_phys((void *)RDWR_MPT_VIRT_END)>>PAGE_SHIFT; + mfn++ ) { frame_table[mfn].count_and_flags = 1 | PGC_allocated; - frame_table[mfn].type_and_flags = 1 | PGT_gdt_page; // anything non RW + frame_table[mfn].type_and_flags = 1 | PGT_gdt_page; /* non-RW type */ frame_table[mfn].u.domain = &idle0_task; } } |