aboutsummaryrefslogtreecommitdiffstats
path: root/xen
diff options
context:
space:
mode:
authoriap10@labyrinth.cl.cam.ac.uk <iap10@labyrinth.cl.cam.ac.uk>2004-05-13 16:48:30 +0000
committeriap10@labyrinth.cl.cam.ac.uk <iap10@labyrinth.cl.cam.ac.uk>2004-05-13 16:48:30 +0000
commit5a258f039214b3d6cc25477ba02a48ee3df14732 (patch)
treec4cc156ecd19c0e5bca7cfee069476113a50f6f6 /xen
parent11c23eec7386c4c81ba99214006a0676d6b3372f (diff)
parent49c6b7cad5d16552fcc86a7aac8e2a505abd12a3 (diff)
downloadxen-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.S30
-rw-r--r--xen/common/dom_mem_ops.c64
-rw-r--r--xen/common/domain.c5
-rw-r--r--xen/common/memory.c27
-rw-r--r--xen/include/hypervisor-ifs/hypervisor-if.h1
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