[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Add new hypercall "set_callback" taking a callback identifier and the
# HG changeset patch # User Ian.Campbell@xxxxxxxxxxxxx # Node ID 67de34c062b5897d1e82995b171be081f976558e # Parent d2705953c6d268779a4612b0115dc52b34f4f68c Add new hypercall "set_callback" taking a callback identifier and the callback address. This new hypercall incorporates the functionality of the existing set_callbacks hypercall in a more flexible manner. set_callbacks is retained for compatibility. Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxxxxx> diff -r d2705953c6d2 -r 67de34c062b5 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h Thu Apr 6 10:34:14 2006 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h Thu Apr 6 11:03:53 2006 @@ -327,6 +327,14 @@ unsigned long op, void *arg) { return _hypercall2(int, nmi_op, op, arg); +} + +static inline int +HYPERVISOR_callback_op( + int cmd, + void *arg) +{ + return _hypercall2(int, callback_op, cmd, arg); } #endif /* __HYPERCALL_H__ */ diff -r d2705953c6d2 -r 67de34c062b5 linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h Thu Apr 6 10:34:14 2006 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h Thu Apr 6 11:03:53 2006 @@ -5,6 +5,8 @@ * This is included late in kernel/setup.c so that it can make * use of all of the static functions. **/ + +#include <xen/interface/callback.h> static char * __init machine_specific_memory_setup(void) { @@ -23,6 +25,14 @@ static void __init machine_specific_arch_setup(void) { struct xen_platform_parameters pp; + callback_register_t event = { + .type = CALLBACKTYPE_event, + .address = { __KERNEL_CS, (unsigned long)hypervisor_callback }, + }; + callback_register_t failsafe = { + .type = CALLBACKTYPE_failsafe, + .address = { __KERNEL_CS, (unsigned long)failsafe_callback }, + }; struct xennmi_callback cb; if (xen_feature(XENFEAT_auto_translated_physmap) && @@ -32,9 +42,8 @@ memset(empty_zero_page, 0, sizeof(empty_zero_page)); } - HYPERVISOR_set_callbacks( - __KERNEL_CS, (unsigned long)hypervisor_callback, - __KERNEL_CS, (unsigned long)failsafe_callback); + HYPERVISOR_callback_op(CALLBACKOP_register, &event); + HYPERVISOR_callback_op(CALLBACKOP_register, &failsafe); cb.handler_address = (unsigned long)&nmi; HYPERVISOR_nmi_op(XENNMI_register_callback, &cb); diff -r d2705953c6d2 -r 67de34c062b5 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h Thu Apr 6 10:34:14 2006 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h Thu Apr 6 11:03:53 2006 @@ -328,6 +328,13 @@ unsigned long op, void *arg) { return _hypercall2(int, nmi_op, op, arg); +} + +static inline int +HYPERVISOR_callback_op( + int cmd, void *arg) +{ + return _hypercall2(int, callback_op, cmd, arg); } #endif /* __HYPERCALL_H__ */ diff -r d2705953c6d2 -r 67de34c062b5 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h Thu Apr 6 10:34:14 2006 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h Thu Apr 6 11:03:53 2006 @@ -6,20 +6,33 @@ * use of all of the static functions. **/ +#include <xen/interface/callback.h> + extern void hypervisor_callback(void); extern void failsafe_callback(void); extern void nmi(void); static void __init machine_specific_arch_setup(void) { + callback_register_t event = { + .type = CALLBACKTYPE_event, + .address = (unsigned long) hypervisor_callback, + }; + callback_register_t failsafe = { + .type = CALLBACKTYPE_failsafe, + .address = (unsigned long)failsafe_callback, + }; + callback_register_t syscall = { + .type = CALLBACKTYPE_syscall, + .address = (unsigned long)system_call, + }; #ifdef CONFIG_X86_LOCAL_APIC struct xennmi_callback cb; #endif - HYPERVISOR_set_callbacks( - (unsigned long) hypervisor_callback, - (unsigned long) failsafe_callback, - (unsigned long) system_call); + HYPERVISOR_callback_op(CALLBACKOP_register, &event); + HYPERVISOR_callback_op(CALLBACKOP_register, &failsafe); + HYPERVISOR_callback_op(CALLBACKOP_register, &syscall); #ifdef CONFIG_X86_LOCAL_APIC cb.handler_address = (unsigned long)&nmi; diff -r d2705953c6d2 -r 67de34c062b5 xen/arch/x86/x86_32/entry.S --- a/xen/arch/x86/x86_32/entry.S Thu Apr 6 10:34:14 2006 +++ b/xen/arch/x86/x86_32/entry.S Thu Apr 6 11:03:53 2006 @@ -648,6 +648,7 @@ .long do_acm_op .long do_nmi_op .long do_arch_sched_op + .long do_callback_op /* 30 */ .rept NR_hypercalls-((.-hypercall_table)/4) .long do_ni_hypercall .endr @@ -683,6 +684,7 @@ .byte 1 /* do_acm_op */ .byte 2 /* do_nmi_op */ .byte 2 /* do_arch_sched_op */ + .byte 2 /* do_callback_op */ /* 30 */ .rept NR_hypercalls-(.-hypercall_args_table) .byte 0 /* do_ni_hypercall */ .endr diff -r d2705953c6d2 -r 67de34c062b5 xen/arch/x86/x86_32/traps.c --- a/xen/arch/x86/x86_32/traps.c Thu Apr 6 10:34:14 2006 +++ b/xen/arch/x86/x86_32/traps.c Thu Apr 6 11:03:53 2006 @@ -13,6 +13,8 @@ #include <asm/flushtlb.h> #include <asm/hvm/hvm.h> #include <asm/hvm/support.h> + +#include <public/callback.h> /* All CPUs have their own IDT to allow int80 direct trap. */ idt_entry_t *idt_tables[NR_CPUS] = { 0 }; @@ -315,20 +317,102 @@ set_int80_direct_trap(v); } +static long register_guest_callback(struct callback_register *reg) +{ + long ret = 0; + struct vcpu *v = current; + + if ( reg->address.cs ) + fixup_guest_code_selector(reg->address.cs); + + switch ( reg->type ) + { + case CALLBACKTYPE_event: + v->arch.guest_context.event_callback_cs = reg->address.cs; + v->arch.guest_context.event_callback_eip = reg->address.eip; + break; + + case CALLBACKTYPE_failsafe: + v->arch.guest_context.failsafe_callback_cs = reg->address.cs; + v->arch.guest_context.failsafe_callback_eip = reg->address.eip; + break; + + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static long unregister_guest_callback(struct callback_unregister *unreg) +{ + long ret; + + switch ( unreg->type ) + { + default: + ret = -EINVAL; + break; + } + return ret; +} + + +long do_callback_op(int cmd, GUEST_HANDLE(void) arg) +{ + long ret; + + switch ( cmd ) + { + case CALLBACKOP_register: + { + struct callback_register reg; + + ret = -EFAULT; + if ( copy_from_guest( ®, arg, 1 ) ) + break; + + ret = register_guest_callback(®); + } + break; + + case CALLBACKOP_unregister: + { + struct callback_unregister unreg; + + ret = -EFAULT; + if ( copy_from_guest( &unreg, arg, 1 ) ) + break; + + ret = unregister_guest_callback(&unreg); + } + break; + + default: + ret = -EINVAL; + break; + } + + return ret; +} + long do_set_callbacks(unsigned long event_selector, unsigned long event_address, unsigned long failsafe_selector, unsigned long failsafe_address) { - struct vcpu *d = current; - - fixup_guest_code_selector(event_selector); - fixup_guest_code_selector(failsafe_selector); - - d->arch.guest_context.event_callback_cs = event_selector; - d->arch.guest_context.event_callback_eip = event_address; - d->arch.guest_context.failsafe_callback_cs = failsafe_selector; - d->arch.guest_context.failsafe_callback_eip = failsafe_address; + struct callback_register event = { + .type = CALLBACKTYPE_event, + .address = { event_selector, event_address }, + }; + struct callback_register failsafe = { + .type = CALLBACKTYPE_failsafe, + .address = { failsafe_selector, failsafe_address }, + }; + + register_guest_callback(&event); + register_guest_callback(&failsafe); return 0; } diff -r d2705953c6d2 -r 67de34c062b5 xen/arch/x86/x86_64/entry.S --- a/xen/arch/x86/x86_64/entry.S Thu Apr 6 10:34:14 2006 +++ b/xen/arch/x86/x86_64/entry.S Thu Apr 6 11:03:53 2006 @@ -557,6 +557,7 @@ .quad do_acm_op .quad do_nmi_op .quad do_arch_sched_op + .quad do_callback_op /* 30 */ .rept NR_hypercalls-((.-hypercall_table)/8) .quad do_ni_hypercall .endr @@ -592,6 +593,7 @@ .byte 1 /* do_acm_op */ .byte 2 /* do_nmi_op */ .byte 2 /* do_arch_sched_op */ + .byte 2 /* do_callback_op */ /* 30 */ .rept NR_hypercalls-(.-hypercall_args_table) .byte 0 /* do_ni_hypercall */ .endr diff -r d2705953c6d2 -r 67de34c062b5 xen/arch/x86/x86_64/traps.c --- a/xen/arch/x86/x86_64/traps.c Thu Apr 6 10:34:14 2006 +++ b/xen/arch/x86/x86_64/traps.c Thu Apr 6 11:03:53 2006 @@ -16,6 +16,8 @@ #include <asm/shadow.h> #include <asm/hvm/hvm.h> #include <asm/hvm/support.h> + +#include <public/callback.h> void show_registers(struct cpu_user_regs *regs) { @@ -312,15 +314,105 @@ wrmsr(MSR_SYSCALL_MASK, EF_VM|EF_RF|EF_NT|EF_DF|EF_IE|EF_TF, 0U); } +static long register_guest_callback(struct callback_register *reg) +{ + long ret = 0; + struct vcpu *v = current; + + switch ( reg->type ) + { + case CALLBACKTYPE_event: + v->arch.guest_context.event_callback_eip = reg->address; + break; + + case CALLBACKTYPE_failsafe: + v->arch.guest_context.failsafe_callback_eip = reg->address; + break; + + case CALLBACKTYPE_syscall: + v->arch.guest_context.syscall_callback_eip = reg->address; + break; + + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static long unregister_guest_callback(struct callback_unregister *unreg) +{ + long ret; + + switch ( unreg->type ) + { + default: + ret = -EINVAL; + break; + } + return ret; +} + + +long do_callback_op(int cmd, GUEST_HANDLE(void) arg) +{ + long ret; + + switch ( cmd ) + { + case CALLBACKOP_register: + { + struct callback_register reg; + + ret = -EFAULT; + if ( copy_from_guest( ®, arg, 1 ) ) + break; + + ret = register_guest_callback(®); + } + break; + + case CALLBACKOP_unregister: + { + struct callback_unregister unreg; + + ret = -EFAULT; + if ( copy_from_guest( &unreg, arg, 1 ) ) + break; + + ret = unregister_guest_callback(&unreg); + } + break; + + default: + ret = -EINVAL; + break; + } + + return ret; +} + long do_set_callbacks(unsigned long event_address, unsigned long failsafe_address, unsigned long syscall_address) { - struct vcpu *d = current; - - d->arch.guest_context.event_callback_eip = event_address; - d->arch.guest_context.failsafe_callback_eip = failsafe_address; - d->arch.guest_context.syscall_callback_eip = syscall_address; + callback_register_t event = { + .type = CALLBACKTYPE_event, + .address = event_address, + }; + callback_register_t failsafe = { + .type = CALLBACKTYPE_failsafe, + .address = failsafe_address, + }; + callback_register_t syscall = { + .type = CALLBACKTYPE_syscall, + .address = syscall_address, + }; + + register_guest_callback(&event); + register_guest_callback(&failsafe); + register_guest_callback(&syscall); return 0; } diff -r d2705953c6d2 -r 67de34c062b5 xen/include/public/arch-x86_32.h --- a/xen/include/public/arch-x86_32.h Thu Apr 6 10:34:14 2006 +++ b/xen/include/public/arch-x86_32.h Thu Apr 6 11:03:53 2006 @@ -168,6 +168,11 @@ unsigned long pad[5]; /* sizeof(vcpu_info_t) == 64 */ } arch_vcpu_info_t; +typedef struct { + unsigned long cs; + unsigned long eip; +} xen_callback_t; + #endif /* !__ASSEMBLY__ */ /* diff -r d2705953c6d2 -r 67de34c062b5 xen/include/public/arch-x86_64.h --- a/xen/include/public/arch-x86_64.h Thu Apr 6 10:34:14 2006 +++ b/xen/include/public/arch-x86_64.h Thu Apr 6 11:03:53 2006 @@ -244,6 +244,8 @@ unsigned long pad; /* sizeof(vcpu_info_t) == 64 */ } arch_vcpu_info_t; +typedef unsigned long xen_callback_t; + #endif /* !__ASSEMBLY__ */ /* diff -r d2705953c6d2 -r 67de34c062b5 xen/include/public/xen.h --- a/xen/include/public/xen.h Thu Apr 6 10:34:14 2006 +++ b/xen/include/public/xen.h Thu Apr 6 11:03:53 2006 @@ -60,6 +60,7 @@ #define __HYPERVISOR_acm_op 27 #define __HYPERVISOR_nmi_op 28 #define __HYPERVISOR_sched_op 29 +#define __HYPERVISOR_callback_op 30 /* * VIRTUAL INTERRUPTS diff -r d2705953c6d2 -r 67de34c062b5 xen/include/public/callback.h --- /dev/null Thu Apr 6 10:34:14 2006 +++ b/xen/include/public/callback.h Thu Apr 6 11:03:53 2006 @@ -0,0 +1,57 @@ +/****************************************************************************** + * callback.h + * + * Register guest OS callbacks with Xen. + * + * Copyright (c) 2006, Ian Campbell + */ + +#ifndef __XEN_PUBLIC_CALLBACK_H__ +#define __XEN_PUBLIC_CALLBACK_H__ + +#include "xen.h" + +/* + * Prototype for this hypercall is: + * long callback_op(int cmd, void *extra_args) + * @cmd == CALLBACKOP_??? (callback operation). + * @extra_args == Operation-specific extra arguments (NULL if none). + */ + +#define CALLBACKTYPE_event 0 +#define CALLBACKTYPE_failsafe 1 +#define CALLBACKTYPE_syscall 2 /* x86_64 only */ + +/* + * Register a callback. + */ +#define CALLBACKOP_register 0 +typedef struct callback_register { + int type; + xen_callback_t address; +} callback_register_t; +DEFINE_GUEST_HANDLE(callback_register_t); + +/* + * Unregister a callback. + * + * Not all callbacks can be unregistered. -EINVAL will be returned if + * you attempt to unregister such a callback. + */ +#define CALLBACKOP_unregister 1 +typedef struct callback_unregister { + int type; +} callback_unregister_t; +DEFINE_GUEST_HANDLE(callback_unregister_t); + +#endif /* __XEN_PUBLIC_CALLBACK_H__ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |