diff options
author | iap10@labyrinth.cl.cam.ac.uk <iap10@labyrinth.cl.cam.ac.uk> | 2004-05-13 16:48:30 +0000 |
---|---|---|
committer | iap10@labyrinth.cl.cam.ac.uk <iap10@labyrinth.cl.cam.ac.uk> | 2004-05-13 16:48:30 +0000 |
commit | 5a258f039214b3d6cc25477ba02a48ee3df14732 (patch) | |
tree | c4cc156ecd19c0e5bca7cfee069476113a50f6f6 /xen | |
parent | 11c23eec7386c4c81ba99214006a0676d6b3372f (diff) | |
parent | 49c6b7cad5d16552fcc86a7aac8e2a505abd12a3 (diff) | |
download | xen-5a258f039214b3d6cc25477ba02a48ee3df14732.tar.gz xen-5a258f039214b3d6cc25477ba02a48ee3df14732.tar.bz2 xen-5a258f039214b3d6cc25477ba02a48ee3df14732.zip |
bitkeeper revision 1.905 (40a3a6de5FuSwJGHH_WcDAjtx8enEA)
Merge labyrinth.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
into labyrinth.cl.cam.ac.uk:/auto/groups/xeno/users/iap10/xeno-clone/xeno.bk
Diffstat (limited to 'xen')
-rw-r--r-- | xen/arch/i386/entry.S | 30 | ||||
-rw-r--r-- | xen/common/dom_mem_ops.c | 64 | ||||
-rw-r--r-- | xen/common/domain.c | 5 | ||||
-rw-r--r-- | xen/common/memory.c | 27 | ||||
-rw-r--r-- | xen/include/hypervisor-ifs/hypervisor-if.h | 1 |
5 files changed, 70 insertions, 57 deletions
diff --git a/xen/arch/i386/entry.S b/xen/arch/i386/entry.S index b522f4f754..1d55a51617 100644 --- a/xen/arch/i386/entry.S +++ b/xen/arch/i386/entry.S @@ -183,20 +183,22 @@ do_multicall: multicall_loop: pushl %ecx multicall_fault1: - pushl 20(%ebx) + pushl 20(%ebx) # args[4] multicall_fault2: - pushl 16(%ebx) + pushl 16(%ebx) # args[3] multicall_fault3: - pushl 12(%ebx) + pushl 12(%ebx) # args[2] multicall_fault4: - pushl 8(%ebx) + pushl 8(%ebx) # args[1] multicall_fault5: - pushl 4(%ebx) + pushl 4(%ebx) # args[0] multicall_fault6: - movl (%ebx),%eax + movl (%ebx),%eax # op andl $255,%eax call *SYMBOL_NAME(hypervisor_call_table)(,%eax,4) multicall_return_from_call: +multicall_fault7: + movl %eax,24(%ebx) # args[5] == result addl $20,%esp popl %ecx addl $(ARGS_PER_MULTICALL_ENTRY*4),%ebx @@ -245,10 +247,6 @@ restore_all_guest: movsl movsl movsl - # Third, reenable interrupts. They will definitely be reenabled by IRET - # in any case. They could be disabled here if we are returning from an - # interrupt. We need interrupts enabled if we take a fault. - sti # Finally, restore guest registers -- faults will cause failsafe popl %ebx popl %ecx @@ -539,11 +537,14 @@ error_code: movl %edx,%es movl %edx,%fs movl %edx,%gs - movl EFLAGS(%esp),%edx - testl $0x200,%edx # Is IF asserted in saved EFLAGS? - jz 1f # Don't STI if it isn't. + # We force a STI here. In most cases it is illegal to fault with + # interrupts disabled, so no need to check EFLAGS. There is one + # case when it /is/ valid -- on final return to guest context, we + # CLI so we can atomically check for events to notify guest about and + # return, all in one go. If we fault it is necessary to STI and the + # worst that will happen is that our return code is no longer atomic. + # This will do -- noone will ever notice. :-) sti -1: movl %esp,%edx pushl %esi # push the error code pushl %edx # push the pt_regs pointer GET_CURRENT(%ebx) @@ -745,6 +746,7 @@ ENTRY(hypervisor_call_table) .long SYMBOL_NAME(do_xen_version) .long SYMBOL_NAME(do_console_io) .long SYMBOL_NAME(do_physdev_op) + .long SYMBOL_NAME(do_update_va_mapping_otherdomain) /* 25 */ .rept NR_syscalls-((.-hypervisor_call_table)/4) .long SYMBOL_NAME(do_ni_syscall) .endr diff --git a/xen/common/dom_mem_ops.c b/xen/common/dom_mem_ops.c index 79d0bb1df1..fcc4977bee 100644 --- a/xen/common/dom_mem_ops.c +++ b/xen/common/dom_mem_ops.c @@ -18,24 +18,22 @@ static long alloc_dom_mem(struct task_struct *p, reservation_increase_t op) { - struct pfn_info *page; - unsigned long mpfn; /* machine frame number of current page */ - void *va; /* Xen-usable mapping of current page */ - unsigned long i; + struct pfn_info *page; + unsigned long i; - for ( i = 0; i < op.size; i++ ) + /* Leave some slack pages; e.g., for the network. */ + if ( unlikely(free_pfns < (op.size + (SLACK_DOMAIN_MEM_KILOBYTES >> + (PAGE_SHIFT-10)))) ) { - /* Leave some slack pages; e.g., for the network. */ - if ( unlikely(free_pfns < (SLACK_DOMAIN_MEM_KILOBYTES >> - (PAGE_SHIFT-10))) ) - { - DPRINTK("Not enough slack: %u %u\n", - free_pfns, - SLACK_DOMAIN_MEM_KILOBYTES >> (PAGE_SHIFT-10)); - break; - } + DPRINTK("Not enough slack: %u %u\n", + free_pfns, + SLACK_DOMAIN_MEM_KILOBYTES >> (PAGE_SHIFT-10)); + return 0; + } - /* NB. 'alloc_domain_page' does limit checking on pages per domain. */ + for ( i = 0; i < op.size; i++ ) + { + /* NB. 'alloc_domain_page' does limit-checking on pages per domain. */ if ( unlikely((page = alloc_domain_page(p)) == NULL) ) { DPRINTK("Could not allocate a frame\n"); @@ -43,14 +41,8 @@ static long alloc_dom_mem(struct task_struct *p, reservation_increase_t op) } /* Inform the domain of the new page's machine address. */ - mpfn = (unsigned long)(page - frame_table); - copy_to_user(op.pages, &mpfn, sizeof(mpfn)); - op.pages++; - - /* Zero out the page to prevent information leakage. */ - va = map_domain_mem(mpfn << PAGE_SHIFT); - memset(va, 0, PAGE_SIZE); - unmap_domain_mem(va); + if ( unlikely(put_user(page_to_pfn(page), &op.pages[i]) != 0) ) + break; } return i; @@ -58,22 +50,21 @@ static long alloc_dom_mem(struct task_struct *p, reservation_increase_t op) static long free_dom_mem(struct task_struct *p, reservation_decrease_t op) { - struct pfn_info *page; - unsigned long mpfn; /* machine frame number of current page */ - unsigned long i; - long rc = 0; - int need_flush = 0; + struct pfn_info *page; + unsigned long i, mpfn; + long rc = 0; for ( i = 0; i < op.size; i++ ) { - copy_from_user(&mpfn, op.pages, sizeof(mpfn)); - op.pages++; - if ( mpfn >= max_page ) + if ( unlikely(get_user(mpfn, &op.pages[i]) != 0) ) + break; + + if ( unlikely(mpfn >= max_page) ) { DPRINTK("Domain %llu page number out of range (%08lx>=%08lx)\n", p->domain, mpfn, max_page); rc = -EINVAL; - goto out; + break; } page = &frame_table[mpfn]; @@ -81,7 +72,7 @@ static long free_dom_mem(struct task_struct *p, reservation_decrease_t op) { DPRINTK("Bad page free for domain %llu\n", p->domain); rc = -EINVAL; - goto out; + break; } if ( test_and_clear_bit(_PGC_guest_pinned, &page->count_and_flags) ) @@ -93,13 +84,6 @@ static long free_dom_mem(struct task_struct *p, reservation_decrease_t op) put_page(page); } - out: - if ( need_flush ) - { - __flush_tlb(); - perfc_incr(need_flush_tlb_flush); - } - return rc ? rc : op.size; } diff --git a/xen/common/domain.c b/xen/common/domain.c index d55f65d5ae..88cc659711 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -332,8 +332,7 @@ struct pfn_info *alloc_domain_page(struct task_struct *p) page->type_and_flags = 0; if ( p != NULL ) { - if ( unlikely(in_irq()) ) - BUG(); + ASSERT(!in_irq()); wmb(); /* Domain pointer must be visible before updating refcnt. */ spin_lock(&p->page_list_lock); if ( unlikely(p->tot_pages >= p->max_pages) ) @@ -377,7 +376,7 @@ void free_domain_page(struct pfn_info *page) if ( !(page->count_and_flags & PGC_zombie) ) { page->tlbflush_timestamp = tlbflush_clock; - if (p) + if ( likely(p != NULL) ) { page->u.cpu_mask = 1 << p->processor; spin_lock(&p->page_list_lock); diff --git a/xen/common/memory.c b/xen/common/memory.c index ddb2778bc3..15560b6609 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -1224,6 +1224,33 @@ int do_update_va_mapping(unsigned long page_nr, return err; } +int do_update_va_mapping_otherdomain(unsigned long page_nr, + unsigned long val, + unsigned long flags, + domid_t domid) +{ + unsigned int cpu = smp_processor_id(); + struct task_struct *p; + int rc; + + if ( unlikely(!IS_PRIV(current)) ) + return -EPERM; + + percpu_info[cpu].gps = p = find_domain_by_id(domid); + if ( unlikely(p == NULL) ) + { + MEM_LOG("Unknown domain '%llu'", domid); + return -ESRCH; + } + + rc = do_update_va_mapping(page_nr, val, flags); + + put_task_struct(p); + percpu_info[cpu].gps = NULL; + + return rc; +} + #ifndef NDEBUG /* diff --git a/xen/include/hypervisor-ifs/hypervisor-if.h b/xen/include/hypervisor-ifs/hypervisor-if.h index 5cde5d46e4..efe34e2184 100644 --- a/xen/include/hypervisor-ifs/hypervisor-if.h +++ b/xen/include/hypervisor-ifs/hypervisor-if.h @@ -39,6 +39,7 @@ #define __HYPERVISOR_xen_version 22 #define __HYPERVISOR_console_io 23 #define __HYPERVISOR_physdev_op 24 +#define __HYPERVISOR_update_va_mapping_otherdomain 25 /* * MULTICALLS |