# HG changeset patch # User cl349@arcadians.cl.cam.ac.uk # Date 1101303524 0 # Node ID f1c44a4d49986e2229f3e6982670940616b69cfc # Parent 42bdac6c89852e5d5527f641ba0111d64e37ebb1# Parent 2754a2ed61c39ed6bdd7bd6fa2c0b88227a48c2f bitkeeper revision 1.1159.1.446 (41a48ee42Omqs3zoJHTZPhLlPx5LUw) Merge arcadians.cl.cam.ac.uk:/auto/groups/xeno/BK/xen-unstable.bk into arcadians.cl.cam.ac.uk:/auto/groups/xeno/users/cl349/BK/xen.bk-smp diff -r 42bdac6c8985 -r f1c44a4d4998 xen/arch/x86/domain.c --- a/xen/arch/x86/domain.c Wed Nov 24 12:07:16 2004 +0000 +++ b/xen/arch/x86/domain.c Wed Nov 24 13:38:44 2004 +0000 @@ -429,6 +429,22 @@ long do_iopl(domid_t domain, unsigned in return 0; } +void hypercall_create_continuation(unsigned int op, unsigned int nr_args, ...) +{ + execution_context_t *ec = get_execution_context(); + unsigned long *preg = &ec->ebx; + unsigned int i; + va_list args; + + ec->eax = op; + ec->eip -= 2; /* re-execute 'int 0x82' */ + + va_start(args, nr_args); + for ( i = 0; i < nr_args; i++ ) + *preg++ = va_arg(args, unsigned long); + va_end(args); +} + #endif diff -r 42bdac6c8985 -r f1c44a4d4998 xen/arch/x86/i8259.c --- a/xen/arch/x86/i8259.c Wed Nov 24 12:07:16 2004 +0000 +++ b/xen/arch/x86/i8259.c Wed Nov 24 13:38:44 2004 +0000 @@ -7,6 +7,7 @@ #include #include +#include #include #include #include diff -r 42bdac6c8985 -r f1c44a4d4998 xen/arch/x86/memory.c --- a/xen/arch/x86/memory.c Wed Nov 24 12:07:16 2004 +0000 +++ b/xen/arch/x86/memory.c Wed Nov 24 13:38:44 2004 +0000 @@ -1307,6 +1307,9 @@ int do_mmu_update(mmu_update_t *ureqs, i for ( i = 0; i < count; i++ ) { + hypercall_may_preempt( + __HYPERVISOR_mmu_update, 3, ureqs, count-i, success_count); + if ( unlikely(__copy_from_user(&req, ureqs, sizeof(req)) != 0) ) { MEM_LOG("Bad __copy_from_user"); @@ -1462,7 +1465,7 @@ int do_mmu_update(mmu_update_t *ureqs, i } if ( unlikely(success_count != NULL) ) - put_user(count, success_count); + put_user(i, success_count); UNLOCK_BIGLOCK(d); return rc; diff -r 42bdac6c8985 -r f1c44a4d4998 xen/arch/x86/traps.c --- a/xen/arch/x86/traps.c Wed Nov 24 12:07:16 2004 +0000 +++ b/xen/arch/x86/traps.c Wed Nov 24 13:38:44 2004 +0000 @@ -814,6 +814,8 @@ long do_set_trap_table(trap_info_t *trap for ( ; ; ) { + hypercall_may_preempt(__HYPERVISOR_set_trap_table, 1, traps); + if ( copy_from_user(&cur, traps, sizeof(cur)) ) return -EFAULT; if ( cur.address == 0 ) break; diff -r 42bdac6c8985 -r f1c44a4d4998 xen/arch/x86/x86_32/entry.S --- a/xen/arch/x86/x86_32/entry.S Wed Nov 24 12:07:16 2004 +0000 +++ b/xen/arch/x86/x86_32/entry.S Wed Nov 24 13:38:44 2004 +0000 @@ -95,6 +95,11 @@ do_multicall: jnc bad_multicall_address multicall_loop: pushl %ecx + movl 4(%esp),%ecx # %ecx = struct domain + movl DOMAIN_processor(%ecx),%eax + shl $6,%eax # sizeof(irq_cpustat) == 64 + testl $~0,SYMBOL_NAME(irq_stat)(%eax,1) + jnz multicall_preempt multicall_fault1: pushl 20(%ebx) # args[4] multicall_fault2: @@ -120,6 +125,17 @@ multicall_fault7: xorl %eax,%eax jmp ret_from_hypercall +multicall_preempt: + # NB. remaining nr_calls is already at top of stack + pushl %ebx # call_list + pushl $2 # nr_args == 2 + pushl $__HYPERVISOR_multicall # op == __HYPERVISOR_multicall + call hypercall_create_continuation + addl $16,%esp + popl %ebx + movl $__HYPERVISOR_multicall,%eax + jmp ret_from_hypercall + bad_multicall_address: popl %ebx movl $-EFAULT,%eax diff -r 42bdac6c8985 -r f1c44a4d4998 xen/common/dom_mem_ops.c --- a/xen/common/dom_mem_ops.c Wed Nov 24 12:07:16 2004 +0000 +++ b/xen/common/dom_mem_ops.c Wed Nov 24 13:38:44 2004 +0000 @@ -35,6 +35,12 @@ static long alloc_dom_mem(struct domain for ( i = 0; i < nr_extents; i++ ) { + hypercall_may_preempt( + __HYPERVISOR_dom_mem_op, 5, + MEMOP_increase_reservation, + &extent_list[i], nr_extents-i, extent_order, + (d == current) ? DOMID_SELF : d->id); + if ( unlikely((page = alloc_domheap_pages(d, extent_order)) == NULL) ) { DPRINTK("Could not allocate a frame\n"); @@ -63,6 +69,12 @@ static long free_dom_mem(struct domain * for ( i = 0; i < nr_extents; i++ ) { + hypercall_may_preempt( + __HYPERVISOR_dom_mem_op, 5, + MEMOP_decrease_reservation, + &extent_list[i], nr_extents-i, extent_order, + (d == current) ? DOMID_SELF : d->id); + if ( unlikely(__get_user(mpfn, &extent_list[i]) != 0) ) return i; diff -r 42bdac6c8985 -r f1c44a4d4998 xen/common/grant_table.c --- a/xen/common/grant_table.c Wed Nov 24 12:07:16 2004 +0000 +++ b/xen/common/grant_table.c Wed Nov 24 13:38:44 2004 +0000 @@ -437,6 +437,9 @@ do_grant_table_op( { long rc; + /* XXX stubbed out XXX */ + return -ENOSYS; + if ( count > 512 ) return -EINVAL; diff -r 42bdac6c8985 -r f1c44a4d4998 xen/include/asm-x86/x86_32/regs.h --- a/xen/include/asm-x86/x86_32/regs.h Wed Nov 24 12:07:16 2004 +0000 +++ b/xen/include/asm-x86/x86_32/regs.h Wed Nov 24 13:38:44 2004 +0000 @@ -1,8 +1,6 @@ #ifndef _I386_REGS_H #define _I386_REGS_H -#include - struct xen_regs { /* All saved activations contain the following fields. */ diff -r 42bdac6c8985 -r f1c44a4d4998 xen/include/xen/irq_cpustat.h --- a/xen/include/xen/irq_cpustat.h Wed Nov 24 12:07:16 2004 +0000 +++ b/xen/include/xen/irq_cpustat.h Wed Nov 24 13:38:44 2004 +0000 @@ -10,6 +10,7 @@ */ #include +#include /* * Simple wrappers reducing source bloat. Define all irq_stat fields @@ -17,7 +18,7 @@ * definitions instead of differing sets for each arch. */ -extern irq_cpustat_t irq_stat[]; /* defined in asm/hardirq.h */ +extern irq_cpustat_t irq_stat[]; #ifdef CONFIG_SMP #define __IRQ_STAT(cpu, member) (irq_stat[cpu].member) diff -r 42bdac6c8985 -r f1c44a4d4998 xen/include/xen/keyhandler.h --- a/xen/include/xen/keyhandler.h Wed Nov 24 12:07:16 2004 +0000 +++ b/xen/include/xen/keyhandler.h Wed Nov 24 13:38:44 2004 +0000 @@ -10,7 +10,7 @@ #ifndef __XEN_KEYHANDLER_H__ #define __XEN_KEYHANDLER_H__ -#include +struct xen_regs; /* * Register a callback function for key @key. The callback occurs in diff -r 42bdac6c8985 -r f1c44a4d4998 xen/include/xen/sched.h --- a/xen/include/xen/sched.h Wed Nov 24 12:07:16 2004 +0000 +++ b/xen/include/xen/sched.h Wed Nov 24 13:38:44 2004 +0000 @@ -21,6 +21,7 @@ #include #include #include +#include extern unsigned long volatile jiffies; extern rwlock_t domlist_lock; @@ -255,6 +256,14 @@ void continue_cpu_idle_loop(void); void continue_nonidle_task(void); +void hypercall_create_continuation(unsigned int op, unsigned int nr_args, ...); +#define hypercall_may_preempt(_op, _nr_args, _args...) \ + do { \ + if ( unlikely(softirq_pending(smp_processor_id())) ) { \ + hypercall_create_continuation(_op , _nr_args , ##_args); \ + return _op; \ + } } while ( 0 ) + /* This domain_hash and domain_list are protected by the domlist_lock. */ #define DOMAIN_HASH_SIZE 256 #define DOMAIN_HASH(_id) ((int)(_id)&(DOMAIN_HASH_SIZE-1))