mirror of
https://github.com/xen-project/xen.git
synced 2026-10-30 03:00:05 +01:00
Enable compatibility mode operation for HYPERVISOR_vcpu_op.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
This commit is contained in:
1 parent
248b44f921
commit
10254dc104
11 files changed
+225
-6
No files matched your search
+20
-5
@@ -40,6 +40,9 @@
|
||||
#include <asm/hvm/hvm.h>
|
||||
#include <asm/hvm/support.h>
|
||||
#include <asm/msr.h>
|
||||
#ifdef CONFIG_COMPAT
|
||||
#include <compat/vcpu.h>
|
||||
#endif
|
||||
|
||||
DEFINE_PER_CPU(struct vcpu *, curr_vcpu);
|
||||
|
||||
@@ -559,16 +562,16 @@ arch_do_vcpu_op(
|
||||
break;
|
||||
|
||||
rc = 0;
|
||||
v->runstate_guest = area.addr.h;
|
||||
runstate_guest(v) = area.addr.h;
|
||||
|
||||
if ( v == current )
|
||||
{
|
||||
__copy_to_guest(v->runstate_guest, &v->runstate, 1);
|
||||
__copy_to_guest(runstate_guest(v), &v->runstate, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
vcpu_runstate_get(v, &runstate);
|
||||
__copy_to_guest(v->runstate_guest, &runstate, 1);
|
||||
__copy_to_guest(runstate_guest(v), &runstate, 1);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -970,8 +973,20 @@ void context_switch(struct vcpu *prev, struct vcpu *next)
|
||||
context_saved(prev);
|
||||
|
||||
/* Update per-VCPU guest runstate shared memory area (if registered). */
|
||||
if ( !guest_handle_is_null(next->runstate_guest) )
|
||||
__copy_to_guest(next->runstate_guest, &next->runstate, 1);
|
||||
if ( !guest_handle_is_null(runstate_guest(next)) )
|
||||
{
|
||||
if ( !IS_COMPAT(next->domain) )
|
||||
__copy_to_guest(runstate_guest(next), &next->runstate, 1);
|
||||
#ifdef CONFIG_COMPAT
|
||||
else
|
||||
{
|
||||
struct compat_vcpu_runstate_info info;
|
||||
|
||||
XLAT_vcpu_runstate_info(&info, &next->runstate);
|
||||
__copy_to_guest(next->runstate_guest.compat, &info, 1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
schedule_tail(next);
|
||||
BUG();
|
||||
|
||||
@@ -4,6 +4,7 @@ obj-y += mm.o
|
||||
obj-y += traps.o
|
||||
|
||||
obj-$(CONFIG_COMPAT) += compat.o
|
||||
obj-$(CONFIG_COMPAT) += domain.o
|
||||
obj-$(CONFIG_COMPAT) += physdev.o
|
||||
|
||||
ifeq ($(CONFIG_COMPAT),y)
|
||||
|
||||
@@ -284,7 +284,6 @@ CFIX14:
|
||||
#define compat_multicall domain_crash_synchronous
|
||||
#define compat_set_timer_op domain_crash_synchronous
|
||||
#define compat_grant_table_op domain_crash_synchronous
|
||||
#define compat_vcpu_op domain_crash_synchronous
|
||||
#define compat_acm_op domain_crash_synchronous
|
||||
#define compat_arch_sched_op domain_crash_synchronous
|
||||
#define compat_xenoprof_op domain_crash_synchronous
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/******************************************************************************
|
||||
* arch/x86/x86_64/domain.c
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xen/config.h>
|
||||
#include <xen/types.h>
|
||||
#include <xen/guest_access.h>
|
||||
#include <asm/hypercall.h>
|
||||
#include <compat/vcpu.h>
|
||||
|
||||
int
|
||||
arch_compat_vcpu_op(
|
||||
int cmd, struct vcpu *v, XEN_GUEST_HANDLE(void) arg)
|
||||
{
|
||||
long rc = 0;
|
||||
|
||||
switch ( cmd )
|
||||
{
|
||||
case VCPUOP_register_runstate_memory_area:
|
||||
{
|
||||
struct compat_vcpu_register_runstate_memory_area area;
|
||||
struct compat_vcpu_runstate_info info;
|
||||
|
||||
rc = -EFAULT;
|
||||
if ( copy_from_guest(&area, arg, 1) )
|
||||
break;
|
||||
|
||||
if ( area.addr.h.c != area.addr.p ||
|
||||
!compat_handle_okay(area.addr.h, 1) )
|
||||
break;
|
||||
|
||||
rc = 0;
|
||||
guest_from_compat_handle(v->runstate_guest.compat, area.addr.h);
|
||||
|
||||
if ( v == current )
|
||||
{
|
||||
XLAT_vcpu_runstate_info(&info, &v->runstate);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct vcpu_runstate_info runstate;
|
||||
|
||||
vcpu_runstate_get(v, &runstate);
|
||||
XLAT_vcpu_runstate_info(&info, &v->runstate);
|
||||
}
|
||||
__copy_to_guest(v->runstate_guest.compat, &info, 1);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
rc = -ENOSYS;
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
* c-set-style: "BSD"
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -1,3 +1,4 @@
|
||||
obj-y += domain.o
|
||||
obj-y += kernel.o
|
||||
obj-y += memory.o
|
||||
obj-y += xlat.o
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
/******************************************************************************
|
||||
* domain.c
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xen/config.h>
|
||||
#include <xen/lib.h>
|
||||
#include <xen/sched.h>
|
||||
#include <xen/domain.h>
|
||||
#include <xen/guest_access.h>
|
||||
#include <xen/hypercall.h>
|
||||
#include <compat/vcpu.h>
|
||||
|
||||
int compat_vcpu_op(int cmd, int vcpuid, XEN_GUEST_HANDLE(void) arg)
|
||||
{
|
||||
struct domain *d = current->domain;
|
||||
struct vcpu *v;
|
||||
long rc = 0;
|
||||
|
||||
if ( (vcpuid < 0) || (vcpuid >= MAX_VIRT_CPUS) )
|
||||
return -EINVAL;
|
||||
|
||||
if ( (v = d->vcpu[vcpuid]) == NULL )
|
||||
return -ENOENT;
|
||||
|
||||
switch ( cmd )
|
||||
{
|
||||
case VCPUOP_initialise:
|
||||
{
|
||||
struct compat_vcpu_guest_context *cmp_ctxt;
|
||||
struct vcpu_guest_context *nat_ctxt;
|
||||
|
||||
if ( (cmp_ctxt = xmalloc(struct compat_vcpu_guest_context)) == NULL )
|
||||
{
|
||||
rc = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( copy_from_guest(cmp_ctxt, arg, 1) )
|
||||
{
|
||||
xfree(cmp_ctxt);
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( (nat_ctxt = xmalloc(struct vcpu_guest_context)) == NULL )
|
||||
{
|
||||
rc = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
|
||||
memset(nat_ctxt, 0, sizeof(*nat_ctxt));
|
||||
XLAT_vcpu_guest_context(nat_ctxt, cmp_ctxt);
|
||||
xfree(cmp_ctxt);
|
||||
|
||||
LOCK_BIGLOCK(d);
|
||||
rc = -EEXIST;
|
||||
if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
|
||||
rc = boot_vcpu(d, vcpuid, nat_ctxt);
|
||||
UNLOCK_BIGLOCK(d);
|
||||
|
||||
xfree(nat_ctxt);
|
||||
break;
|
||||
}
|
||||
|
||||
case VCPUOP_up:
|
||||
case VCPUOP_down:
|
||||
case VCPUOP_is_up:
|
||||
rc = do_vcpu_op(cmd, vcpuid, arg);
|
||||
break;
|
||||
|
||||
case VCPUOP_get_runstate_info:
|
||||
{
|
||||
union {
|
||||
struct vcpu_runstate_info nat;
|
||||
struct compat_vcpu_runstate_info cmp;
|
||||
} runstate;
|
||||
|
||||
vcpu_runstate_get(v, &runstate.nat);
|
||||
xlat_vcpu_runstate_info(&runstate.nat);
|
||||
if ( copy_to_guest(arg, &runstate.cmp, 1) )
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
rc = arch_compat_vcpu_op(cmd, v, arg);
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
* c-set-style: "BSD"
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <xen/lib.h>
|
||||
#include <compat/xen.h>
|
||||
#include <compat/event_channel.h>
|
||||
#include <compat/vcpu.h>
|
||||
|
||||
/* In-place translation functons: */
|
||||
void xlat_start_info(struct start_info *native,
|
||||
@@ -17,6 +18,14 @@ void xlat_start_info(struct start_info *native,
|
||||
XLAT_start_info(compat, native);
|
||||
}
|
||||
|
||||
void xlat_vcpu_runstate_info(struct vcpu_runstate_info *native)
|
||||
{
|
||||
struct compat_vcpu_runstate_info *compat = (void *)native;
|
||||
|
||||
BUILD_BUG_ON(sizeof(*native) < sizeof(*compat));
|
||||
XLAT_vcpu_runstate_info(compat, native);
|
||||
}
|
||||
|
||||
#define xen_dom0_vga_console_info dom0_vga_console_info
|
||||
CHECK_dom0_vga_console_info;
|
||||
#undef dom0_vga_console_info
|
||||
|
||||
@@ -130,6 +130,10 @@ compat_physdev_op(
|
||||
int cmd,
|
||||
XEN_GUEST_HANDLE(void) arg);
|
||||
|
||||
extern int
|
||||
arch_compat_vcpu_op(
|
||||
int cmd, struct vcpu *v, XEN_GUEST_HANDLE(void) arg);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __ASM_X86_HYPERCALL_H__ */
|
||||
@@ -163,6 +163,8 @@ int hypercall_xlat_continuation(unsigned int *id, unsigned int mask, ...);
|
||||
/* In-place translation functons: */
|
||||
struct start_info;
|
||||
void xlat_start_info(struct start_info *, enum XLAT_start_info_console);
|
||||
struct vcpu_runstate_info;
|
||||
void xlat_vcpu_runstate_info(struct vcpu_runstate_info *);
|
||||
|
||||
#define BITS_PER_GUEST_LONG(d) (!IS_COMPAT(d) ? BITS_PER_LONG : COMPAT_BITS_PER_LONG)
|
||||
|
||||
|
||||
@@ -18,6 +18,11 @@
|
||||
#include <xen/xenoprof.h>
|
||||
#include <xen/irq.h>
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
#include <compat/vcpu.h>
|
||||
DEFINE_XEN_GUEST_HANDLE(vcpu_runstate_info_compat_t);
|
||||
#endif
|
||||
|
||||
extern unsigned long volatile jiffies;
|
||||
extern rwlock_t domlist_lock;
|
||||
|
||||
@@ -82,7 +87,16 @@ struct vcpu
|
||||
void *sched_priv; /* scheduler-specific data */
|
||||
|
||||
struct vcpu_runstate_info runstate;
|
||||
#ifndef CONFIG_COMPAT
|
||||
# define runstate_guest(v) ((v)->runstate_guest)
|
||||
XEN_GUEST_HANDLE(vcpu_runstate_info_t) runstate_guest; /* guest address */
|
||||
#else
|
||||
# define runstate_guest(v) ((v)->runstate_guest.native)
|
||||
union {
|
||||
XEN_GUEST_HANDLE(vcpu_runstate_info_t) native;
|
||||
XEN_GUEST_HANDLE(vcpu_runstate_info_compat_t) compat;
|
||||
} runstate_guest; /* guest address */
|
||||
#endif
|
||||
|
||||
unsigned long vcpu_flags;
|
||||
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
! mmuext_op xen.h
|
||||
! start_info xen.h
|
||||
? vcpu_time_info xen.h
|
||||
! cpu_user_regs arch-@arch@.h
|
||||
! trap_info arch-@arch@.h
|
||||
! vcpu_guest_context arch-@arch@.h
|
||||
? evtchn_alloc_unbound event_channel.h
|
||||
? evtchn_bind_interdomain event_channel.h
|
||||
? evtchn_bind_ipi event_channel.h
|
||||
@@ -23,3 +26,4 @@
|
||||
! memory_map memory.h
|
||||
! memory_reservation memory.h
|
||||
! translate_gpfn_list memory.h
|
||||
! vcpu_runstate_info vcpu.h
|
||||