ia64/xen-unstable

changeset 9610:67de34c062b5

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@xensource.com>
author Ian.Campbell@xensource.com
date Thu Apr 06 12:03:53 2006 +0100 (2006-04-06)
parents d2705953c6d2
children 8b39930c70d5
files linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h xen/arch/x86/x86_32/entry.S xen/arch/x86/x86_32/traps.c xen/arch/x86/x86_64/entry.S xen/arch/x86/x86_64/traps.c xen/include/public/arch-x86_32.h xen/include/public/arch-x86_64.h xen/include/public/callback.h xen/include/public/xen.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h	Thu Apr 06 11:34:14 2006 +0100
     1.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h	Thu Apr 06 12:03:53 2006 +0100
     1.3 @@ -329,6 +329,14 @@ HYPERVISOR_nmi_op(
     1.4  	return _hypercall2(int, nmi_op, op, arg);
     1.5  }
     1.6  
     1.7 +static inline int
     1.8 +HYPERVISOR_callback_op(
     1.9 +	int cmd,
    1.10 +	void *arg)
    1.11 +{
    1.12 +	return _hypercall2(int, callback_op, cmd, arg);
    1.13 +}
    1.14 +
    1.15  #endif /* __HYPERCALL_H__ */
    1.16  
    1.17  /*
     2.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h	Thu Apr 06 11:34:14 2006 +0100
     2.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h	Thu Apr 06 12:03:53 2006 +0100
     2.3 @@ -6,6 +6,8 @@
     2.4   *	use of all of the static functions.
     2.5   **/
     2.6  
     2.7 +#include <xen/interface/callback.h>
     2.8 +
     2.9  static char * __init machine_specific_memory_setup(void)
    2.10  {
    2.11  	unsigned long max_pfn = xen_start_info->nr_pages;
    2.12 @@ -23,6 +25,14 @@ extern void nmi(void);
    2.13  static void __init machine_specific_arch_setup(void)
    2.14  {
    2.15  	struct xen_platform_parameters pp;
    2.16 +	callback_register_t event = {
    2.17 +		.type = CALLBACKTYPE_event,
    2.18 +		.address = { __KERNEL_CS, (unsigned long)hypervisor_callback },
    2.19 +	};
    2.20 +	callback_register_t failsafe = {
    2.21 +		.type = CALLBACKTYPE_failsafe,
    2.22 +		.address = { __KERNEL_CS, (unsigned long)failsafe_callback },
    2.23 +	};
    2.24  	struct xennmi_callback cb;
    2.25  
    2.26  	if (xen_feature(XENFEAT_auto_translated_physmap) &&
    2.27 @@ -32,9 +42,8 @@ static void __init machine_specific_arch
    2.28  		memset(empty_zero_page, 0, sizeof(empty_zero_page));
    2.29  	}
    2.30  
    2.31 -	HYPERVISOR_set_callbacks(
    2.32 -	    __KERNEL_CS, (unsigned long)hypervisor_callback,
    2.33 -	    __KERNEL_CS, (unsigned long)failsafe_callback);
    2.34 +	HYPERVISOR_callback_op(CALLBACKOP_register, &event);
    2.35 +	HYPERVISOR_callback_op(CALLBACKOP_register, &failsafe);
    2.36  
    2.37  	cb.handler_address = (unsigned long)&nmi;
    2.38  	HYPERVISOR_nmi_op(XENNMI_register_callback, &cb);
     3.1 --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h	Thu Apr 06 11:34:14 2006 +0100
     3.2 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h	Thu Apr 06 12:03:53 2006 +0100
     3.3 @@ -330,6 +330,13 @@ HYPERVISOR_nmi_op(
     3.4  	return _hypercall2(int, nmi_op, op, arg);
     3.5  }
     3.6  
     3.7 +static inline int
     3.8 +HYPERVISOR_callback_op(
     3.9 +	int cmd, void *arg)
    3.10 +{
    3.11 +	return _hypercall2(int, callback_op, cmd, arg);
    3.12 +}
    3.13 +
    3.14  #endif /* __HYPERCALL_H__ */
    3.15  
    3.16  /*
     4.1 --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h	Thu Apr 06 11:34:14 2006 +0100
     4.2 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h	Thu Apr 06 12:03:53 2006 +0100
     4.3 @@ -6,20 +6,33 @@
     4.4   *	use of all of the static functions.
     4.5   **/
     4.6  
     4.7 +#include <xen/interface/callback.h>
     4.8 +
     4.9  extern void hypervisor_callback(void);
    4.10  extern void failsafe_callback(void);
    4.11  extern void nmi(void);
    4.12  
    4.13  static void __init machine_specific_arch_setup(void)
    4.14  {
    4.15 +	callback_register_t event = {
    4.16 +		.type = CALLBACKTYPE_event,
    4.17 +		.address = (unsigned long) hypervisor_callback,
    4.18 +	};
    4.19 +	callback_register_t failsafe = {
    4.20 +		.type = CALLBACKTYPE_failsafe,
    4.21 +		.address = (unsigned long)failsafe_callback,
    4.22 +	};
    4.23 +	callback_register_t syscall = {
    4.24 +		.type = CALLBACKTYPE_syscall,
    4.25 +		.address = (unsigned long)system_call,
    4.26 +	};
    4.27  #ifdef CONFIG_X86_LOCAL_APIC
    4.28  	struct xennmi_callback cb;
    4.29  #endif
    4.30  
    4.31 -	HYPERVISOR_set_callbacks(
    4.32 -                (unsigned long) hypervisor_callback,
    4.33 -                (unsigned long) failsafe_callback,
    4.34 -                (unsigned long) system_call);
    4.35 +	HYPERVISOR_callback_op(CALLBACKOP_register, &event);
    4.36 +	HYPERVISOR_callback_op(CALLBACKOP_register, &failsafe);
    4.37 +	HYPERVISOR_callback_op(CALLBACKOP_register, &syscall);
    4.38  
    4.39  #ifdef CONFIG_X86_LOCAL_APIC
    4.40  	cb.handler_address = (unsigned long)&nmi;
     5.1 --- a/xen/arch/x86/x86_32/entry.S	Thu Apr 06 11:34:14 2006 +0100
     5.2 +++ b/xen/arch/x86/x86_32/entry.S	Thu Apr 06 12:03:53 2006 +0100
     5.3 @@ -648,6 +648,7 @@ ENTRY(hypercall_table)
     5.4          .long do_acm_op
     5.5          .long do_nmi_op
     5.6          .long do_arch_sched_op
     5.7 +        .long do_callback_op        /* 30 */
     5.8          .rept NR_hypercalls-((.-hypercall_table)/4)
     5.9          .long do_ni_hypercall
    5.10          .endr
    5.11 @@ -683,6 +684,7 @@ ENTRY(hypercall_args_table)
    5.12          .byte 1 /* do_acm_op            */
    5.13          .byte 2 /* do_nmi_op            */
    5.14          .byte 2 /* do_arch_sched_op     */
    5.15 +        .byte 2 /* do_callback_op       */  /* 30 */
    5.16          .rept NR_hypercalls-(.-hypercall_args_table)
    5.17          .byte 0 /* do_ni_hypercall      */
    5.18          .endr
     6.1 --- a/xen/arch/x86/x86_32/traps.c	Thu Apr 06 11:34:14 2006 +0100
     6.2 +++ b/xen/arch/x86/x86_32/traps.c	Thu Apr 06 12:03:53 2006 +0100
     6.3 @@ -14,6 +14,8 @@
     6.4  #include <asm/hvm/hvm.h>
     6.5  #include <asm/hvm/support.h>
     6.6  
     6.7 +#include <public/callback.h>
     6.8 +
     6.9  /* All CPUs have their own IDT to allow int80 direct trap. */
    6.10  idt_entry_t *idt_tables[NR_CPUS] = { 0 };
    6.11  
    6.12 @@ -315,20 +317,102 @@ void init_int80_direct_trap(struct vcpu 
    6.13          set_int80_direct_trap(v);
    6.14  }
    6.15  
    6.16 +static long register_guest_callback(struct callback_register *reg)
    6.17 +{
    6.18 +    long ret = 0;
    6.19 +    struct vcpu *v = current;
    6.20 +
    6.21 +    if ( reg->address.cs )
    6.22 +        fixup_guest_code_selector(reg->address.cs);
    6.23 +
    6.24 +    switch ( reg->type )
    6.25 +    {
    6.26 +    case CALLBACKTYPE_event:
    6.27 +        v->arch.guest_context.event_callback_cs     = reg->address.cs;
    6.28 +        v->arch.guest_context.event_callback_eip    = reg->address.eip;
    6.29 +        break;
    6.30 +
    6.31 +    case CALLBACKTYPE_failsafe:
    6.32 +        v->arch.guest_context.failsafe_callback_cs  = reg->address.cs;
    6.33 +        v->arch.guest_context.failsafe_callback_eip = reg->address.eip;
    6.34 +        break;
    6.35 +
    6.36 +    default:
    6.37 +        ret = -EINVAL;
    6.38 +        break;
    6.39 +    }
    6.40 +
    6.41 +    return ret;
    6.42 +}
    6.43 +
    6.44 +static long unregister_guest_callback(struct callback_unregister *unreg)
    6.45 +{
    6.46 +    long ret;
    6.47 +
    6.48 +    switch ( unreg->type )
    6.49 +    {
    6.50 +    default:
    6.51 +        ret = -EINVAL;
    6.52 +        break;
    6.53 +    }
    6.54 +    return ret;
    6.55 +}
    6.56 +
    6.57 +
    6.58 +long do_callback_op(int cmd, GUEST_HANDLE(void) arg)
    6.59 +{
    6.60 +    long ret;
    6.61 +
    6.62 +    switch ( cmd )
    6.63 +    {
    6.64 +    case CALLBACKOP_register:
    6.65 +    {
    6.66 +        struct callback_register reg;
    6.67 +
    6.68 +        ret = -EFAULT;
    6.69 +        if ( copy_from_guest( &reg, arg, 1 ) )
    6.70 +            break;
    6.71 +
    6.72 +        ret = register_guest_callback(&reg);
    6.73 +    }
    6.74 +    break;
    6.75 +
    6.76 +    case CALLBACKOP_unregister:
    6.77 +    {
    6.78 +        struct callback_unregister unreg;
    6.79 +
    6.80 +        ret = -EFAULT;
    6.81 +        if ( copy_from_guest( &unreg, arg, 1 ) )
    6.82 +            break;
    6.83 +
    6.84 +        ret = unregister_guest_callback(&unreg);
    6.85 +    }
    6.86 +    break;
    6.87 +
    6.88 +    default:
    6.89 +        ret = -EINVAL;
    6.90 +        break;
    6.91 +    }
    6.92 +
    6.93 +    return ret;
    6.94 +}
    6.95 +
    6.96  long do_set_callbacks(unsigned long event_selector,
    6.97                        unsigned long event_address,
    6.98                        unsigned long failsafe_selector,
    6.99                        unsigned long failsafe_address)
   6.100  {
   6.101 -    struct vcpu *d = current;
   6.102 -
   6.103 -    fixup_guest_code_selector(event_selector);
   6.104 -    fixup_guest_code_selector(failsafe_selector);
   6.105 +    struct callback_register event = {
   6.106 +        .type = CALLBACKTYPE_event,
   6.107 +        .address = { event_selector, event_address },
   6.108 +    };
   6.109 +    struct callback_register failsafe = {
   6.110 +        .type = CALLBACKTYPE_failsafe,
   6.111 +        .address = { failsafe_selector, failsafe_address },
   6.112 +    };
   6.113  
   6.114 -    d->arch.guest_context.event_callback_cs     = event_selector;
   6.115 -    d->arch.guest_context.event_callback_eip    = event_address;
   6.116 -    d->arch.guest_context.failsafe_callback_cs  = failsafe_selector;
   6.117 -    d->arch.guest_context.failsafe_callback_eip = failsafe_address;
   6.118 +    register_guest_callback(&event);
   6.119 +    register_guest_callback(&failsafe);
   6.120  
   6.121      return 0;
   6.122  }
     7.1 --- a/xen/arch/x86/x86_64/entry.S	Thu Apr 06 11:34:14 2006 +0100
     7.2 +++ b/xen/arch/x86/x86_64/entry.S	Thu Apr 06 12:03:53 2006 +0100
     7.3 @@ -557,6 +557,7 @@ ENTRY(hypercall_table)
     7.4          .quad do_acm_op
     7.5          .quad do_nmi_op
     7.6          .quad do_arch_sched_op
     7.7 +        .quad do_callback_op        /* 30 */
     7.8          .rept NR_hypercalls-((.-hypercall_table)/8)
     7.9          .quad do_ni_hypercall
    7.10          .endr
    7.11 @@ -592,6 +593,7 @@ ENTRY(hypercall_args_table)
    7.12          .byte 1 /* do_acm_op            */
    7.13          .byte 2 /* do_nmi_op            */
    7.14          .byte 2 /* do_arch_sched_op     */
    7.15 +        .byte 2 /* do_callback_op       */  /* 30 */
    7.16          .rept NR_hypercalls-(.-hypercall_args_table)
    7.17          .byte 0 /* do_ni_hypercall      */
    7.18          .endr
     8.1 --- a/xen/arch/x86/x86_64/traps.c	Thu Apr 06 11:34:14 2006 +0100
     8.2 +++ b/xen/arch/x86/x86_64/traps.c	Thu Apr 06 12:03:53 2006 +0100
     8.3 @@ -17,6 +17,8 @@
     8.4  #include <asm/hvm/hvm.h>
     8.5  #include <asm/hvm/support.h>
     8.6  
     8.7 +#include <public/callback.h>
     8.8 +
     8.9  void show_registers(struct cpu_user_regs *regs)
    8.10  {
    8.11      struct cpu_user_regs fault_regs = *regs;
    8.12 @@ -312,15 +314,105 @@ void __init percpu_traps_init(void)
    8.13      wrmsr(MSR_SYSCALL_MASK, EF_VM|EF_RF|EF_NT|EF_DF|EF_IE|EF_TF, 0U);
    8.14  }
    8.15  
    8.16 +static long register_guest_callback(struct callback_register *reg)
    8.17 +{
    8.18 +    long ret = 0;
    8.19 +    struct vcpu *v = current;
    8.20 +
    8.21 +    switch ( reg->type )
    8.22 +    {
    8.23 +    case CALLBACKTYPE_event:
    8.24 +        v->arch.guest_context.event_callback_eip    = reg->address;
    8.25 +        break;
    8.26 +
    8.27 +    case CALLBACKTYPE_failsafe:
    8.28 +        v->arch.guest_context.failsafe_callback_eip = reg->address;
    8.29 +        break;
    8.30 +
    8.31 +    case CALLBACKTYPE_syscall:
    8.32 +        v->arch.guest_context.syscall_callback_eip  = reg->address;
    8.33 +        break;
    8.34 +
    8.35 +    default:
    8.36 +        ret = -EINVAL;
    8.37 +        break;
    8.38 +    }
    8.39 +
    8.40 +    return ret;
    8.41 +}
    8.42 +
    8.43 +static long unregister_guest_callback(struct callback_unregister *unreg)
    8.44 +{
    8.45 +    long ret;
    8.46 +
    8.47 +    switch ( unreg->type )
    8.48 +    {
    8.49 +    default:
    8.50 +        ret = -EINVAL;
    8.51 +        break;
    8.52 +    }
    8.53 +    return ret;
    8.54 +}
    8.55 +
    8.56 +
    8.57 +long do_callback_op(int cmd, GUEST_HANDLE(void) arg)
    8.58 +{
    8.59 +    long ret;
    8.60 +
    8.61 +    switch ( cmd )
    8.62 +    {
    8.63 +    case CALLBACKOP_register:
    8.64 +    {
    8.65 +        struct callback_register reg;
    8.66 +
    8.67 +        ret = -EFAULT;
    8.68 +        if ( copy_from_guest( &reg, arg, 1 ) )
    8.69 +            break;
    8.70 +
    8.71 +        ret = register_guest_callback(&reg);
    8.72 +    }
    8.73 +    break;
    8.74 +
    8.75 +    case CALLBACKOP_unregister:
    8.76 +    {
    8.77 +        struct callback_unregister unreg;
    8.78 +
    8.79 +        ret = -EFAULT;
    8.80 +        if ( copy_from_guest( &unreg, arg, 1 ) )
    8.81 +            break;
    8.82 +
    8.83 +        ret = unregister_guest_callback(&unreg);
    8.84 +    }
    8.85 +    break;
    8.86 +
    8.87 +    default:
    8.88 +        ret = -EINVAL;
    8.89 +        break;
    8.90 +    }
    8.91 +
    8.92 +    return ret;
    8.93 +}
    8.94 +
    8.95  long do_set_callbacks(unsigned long event_address,
    8.96                        unsigned long failsafe_address,
    8.97                        unsigned long syscall_address)
    8.98  {
    8.99 -    struct vcpu *d = current;
   8.100 +    callback_register_t event = {
   8.101 +        .type = CALLBACKTYPE_event,
   8.102 +        .address = event_address,
   8.103 +    };
   8.104 +    callback_register_t failsafe = {
   8.105 +        .type = CALLBACKTYPE_failsafe,
   8.106 +        .address = failsafe_address,
   8.107 +    };
   8.108 +    callback_register_t syscall = {
   8.109 +        .type = CALLBACKTYPE_syscall,
   8.110 +        .address = syscall_address,
   8.111 +    };
   8.112  
   8.113 -    d->arch.guest_context.event_callback_eip    = event_address;
   8.114 -    d->arch.guest_context.failsafe_callback_eip = failsafe_address;
   8.115 -    d->arch.guest_context.syscall_callback_eip  = syscall_address;
   8.116 +    register_guest_callback(&event);
   8.117 +    register_guest_callback(&failsafe);
   8.118 +    register_guest_callback(&syscall);
   8.119  
   8.120      return 0;
   8.121  }
     9.1 --- a/xen/include/public/arch-x86_32.h	Thu Apr 06 11:34:14 2006 +0100
     9.2 +++ b/xen/include/public/arch-x86_32.h	Thu Apr 06 12:03:53 2006 +0100
     9.3 @@ -168,6 +168,11 @@ typedef struct {
     9.4      unsigned long pad[5]; /* sizeof(vcpu_info_t) == 64 */
     9.5  } arch_vcpu_info_t;
     9.6  
     9.7 +typedef struct {
     9.8 +    unsigned long cs;
     9.9 +    unsigned long eip;
    9.10 +} xen_callback_t;
    9.11 +
    9.12  #endif /* !__ASSEMBLY__ */
    9.13  
    9.14  /*
    10.1 --- a/xen/include/public/arch-x86_64.h	Thu Apr 06 11:34:14 2006 +0100
    10.2 +++ b/xen/include/public/arch-x86_64.h	Thu Apr 06 12:03:53 2006 +0100
    10.3 @@ -244,6 +244,8 @@ typedef struct {
    10.4      unsigned long pad; /* sizeof(vcpu_info_t) == 64 */
    10.5  } arch_vcpu_info_t;
    10.6  
    10.7 +typedef unsigned long xen_callback_t;
    10.8 +
    10.9  #endif /* !__ASSEMBLY__ */
   10.10  
   10.11  /*
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/xen/include/public/callback.h	Thu Apr 06 12:03:53 2006 +0100
    11.3 @@ -0,0 +1,57 @@
    11.4 +/******************************************************************************
    11.5 + * callback.h
    11.6 + *
    11.7 + * Register guest OS callbacks with Xen.
    11.8 + *
    11.9 + * Copyright (c) 2006, Ian Campbell
   11.10 + */
   11.11 +
   11.12 +#ifndef __XEN_PUBLIC_CALLBACK_H__
   11.13 +#define __XEN_PUBLIC_CALLBACK_H__
   11.14 +
   11.15 +#include "xen.h"
   11.16 +
   11.17 +/*
   11.18 + * Prototype for this hypercall is:
   11.19 + *   long callback_op(int cmd, void *extra_args)
   11.20 + * @cmd        == CALLBACKOP_??? (callback operation).
   11.21 + * @extra_args == Operation-specific extra arguments (NULL if none).
   11.22 + */
   11.23 +
   11.24 +#define CALLBACKTYPE_event                 0
   11.25 +#define CALLBACKTYPE_failsafe              1
   11.26 +#define CALLBACKTYPE_syscall               2 /* x86_64 only */
   11.27 +
   11.28 +/*
   11.29 + * Register a callback.
   11.30 + */
   11.31 +#define CALLBACKOP_register                0
   11.32 +typedef struct callback_register {
   11.33 +     int type;
   11.34 +     xen_callback_t address;
   11.35 +} callback_register_t;
   11.36 +DEFINE_GUEST_HANDLE(callback_register_t);
   11.37 +
   11.38 +/*
   11.39 + * Unregister a callback.
   11.40 + *
   11.41 + * Not all callbacks can be unregistered. -EINVAL will be returned if
   11.42 + * you attempt to unregister such a callback.
   11.43 + */
   11.44 +#define CALLBACKOP_unregister              1
   11.45 +typedef struct callback_unregister {
   11.46 +     int type;
   11.47 +} callback_unregister_t;
   11.48 +DEFINE_GUEST_HANDLE(callback_unregister_t);
   11.49 +
   11.50 +#endif /* __XEN_PUBLIC_CALLBACK_H__ */
   11.51 +
   11.52 +/*
   11.53 + * Local variables:
   11.54 + * mode: C
   11.55 + * c-set-style: "BSD"
   11.56 + * c-basic-offset: 4
   11.57 + * tab-width: 4
   11.58 + * indent-tabs-mode: nil
   11.59 + * End:
   11.60 + */
    12.1 --- a/xen/include/public/xen.h	Thu Apr 06 11:34:14 2006 +0100
    12.2 +++ b/xen/include/public/xen.h	Thu Apr 06 12:03:53 2006 +0100
    12.3 @@ -60,6 +60,7 @@
    12.4  #define __HYPERVISOR_acm_op               27
    12.5  #define __HYPERVISOR_nmi_op               28
    12.6  #define __HYPERVISOR_sched_op             29
    12.7 +#define __HYPERVISOR_callback_op          30
    12.8  
    12.9  /* 
   12.10   * VIRTUAL INTERRUPTS