# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1216376786 -3600
# Node ID 2c80783731a23f4718089761a0f4e4a8e635c035
# Parent f23e94e1c3352acc449d14cc119feec1506d341f
xen/x86: fix compatibility handling
A recent need for our kernel was to be able to run on 3.0.2-based Xen,
and this pointed out that while the fallback code in hypercall.h deals
with most of the cases, the multicalls used in the context switch code
didn't have appropriate fallback mechanisms. Short of breaking up the
multicall or checking individual operation status, the easier method
to fix this seemed to be to simply use the old hypercalls when
CONFIG_XEN_COMPAT_030002_AND_LATER is defined.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>
---
arch/i386/kernel/process-xen.c | 21 +++++++++++++++++++++
arch/x86_64/kernel/process-xen.c | 21 +++++++++++++++++++++
2 files changed, 42 insertions(+)
diff -r f23e94e1c335 -r 2c80783731a2 arch/i386/kernel/process-xen.c
--- a/arch/i386/kernel/process-xen.c Fri Jul 18 11:25:56 2008 +0100
+++ b/arch/i386/kernel/process-xen.c Fri Jul 18 11:26:26 2008 +0100
@@ -552,8 +552,14 @@ struct task_struct fastcall * __switch_t
#ifndef CONFIG_X86_NO_TSS
struct tss_struct *tss = &per_cpu(init_tss, cpu);
#endif
+#if CONFIG_XEN_COMPAT > 0x030002
struct physdev_set_iopl iopl_op;
struct physdev_set_iobitmap iobmp_op;
+#else
+ struct physdev_op _pdo[2], *pdo = _pdo;
+#define iopl_op pdo->u.set_iopl
+#define iobmp_op pdo->u.set_iobitmap
+#endif
multicall_entry_t _mcl[8], *mcl = _mcl;
/* XEN NOTE: FS/GS saved in switch_mm(), not here. */
@@ -601,9 +607,15 @@ struct task_struct fastcall * __switch_t
if (unlikely(prev->iopl != next->iopl)) {
iopl_op.iopl = (next->iopl == 0) ? 1 : (next->iopl >> 12) & 3;
+#if CONFIG_XEN_COMPAT > 0x030002
mcl->op = __HYPERVISOR_physdev_op;
mcl->args[0] = PHYSDEVOP_set_iopl;
mcl->args[1] = (unsigned long)&iopl_op;
+#else
+ mcl->op = __HYPERVISOR_physdev_op_compat;
+ pdo->cmd = PHYSDEVOP_set_iopl;
+ mcl->args[0] = (unsigned long)pdo++;
+#endif
mcl++;
}
@@ -611,12 +623,21 @@ struct task_struct fastcall * __switch_t
set_xen_guest_handle(iobmp_op.bitmap,
(char *)next->io_bitmap_ptr);
iobmp_op.nr_ports = next->io_bitmap_ptr ? IO_BITMAP_BITS : 0;
+#if CONFIG_XEN_COMPAT > 0x030002
mcl->op = __HYPERVISOR_physdev_op;
mcl->args[0] = PHYSDEVOP_set_iobitmap;
mcl->args[1] = (unsigned long)&iobmp_op;
+#else
+ mcl->op = __HYPERVISOR_physdev_op_compat;
+ pdo->cmd = PHYSDEVOP_set_iobitmap;
+ mcl->args[0] = (unsigned long)pdo++;
+#endif
mcl++;
}
+#if CONFIG_XEN_COMPAT <= 0x030002
+ BUG_ON(pdo > _pdo + ARRAY_SIZE(_pdo));
+#endif
BUG_ON(mcl > _mcl + ARRAY_SIZE(_mcl));
if (unlikely(HYPERVISOR_multicall_check(_mcl, mcl - _mcl, NULL)))
BUG();
diff -r f23e94e1c335 -r 2c80783731a2 arch/x86_64/kernel/process-xen.c
--- a/arch/x86_64/kernel/process-xen.c Fri Jul 18 11:25:56 2008 +0100
+++ b/arch/x86_64/kernel/process-xen.c Fri Jul 18 11:26:26 2008 +0100
@@ -491,8 +491,14 @@ __switch_to(struct task_struct *prev_p,
#ifndef CONFIG_X86_NO_TSS
struct tss_struct *tss = &per_cpu(init_tss, cpu);
#endif
+#if CONFIG_XEN_COMPAT > 0x030002
struct physdev_set_iopl iopl_op;
struct physdev_set_iobitmap iobmp_op;
+#else
+ struct physdev_op _pdo[2], *pdo = _pdo;
+#define iopl_op pdo->u.set_iopl
+#define iobmp_op pdo->u.set_iobitmap
+#endif
multicall_entry_t _mcl[8], *mcl = _mcl;
/*
@@ -535,9 +541,15 @@ __switch_to(struct task_struct *prev_p,
if (unlikely(prev->iopl != next->iopl)) {
iopl_op.iopl = (next->iopl == 0) ? 1 : next->iopl;
+#if CONFIG_XEN_COMPAT > 0x030002
mcl->op = __HYPERVISOR_physdev_op;
mcl->args[0] = PHYSDEVOP_set_iopl;
mcl->args[1] = (unsigned long)&iopl_op;
+#else
+ mcl->op = __HYPERVISOR_physdev_op_compat;
+ pdo->cmd = PHYSDEVOP_set_iopl;
+ mcl->args[0] = (unsigned long)pdo++;
+#endif
mcl++;
}
@@ -545,12 +557,21 @@ __switch_to(struct task_struct *prev_p,
set_xen_guest_handle(iobmp_op.bitmap,
(char *)next->io_bitmap_ptr);
iobmp_op.nr_ports = next->io_bitmap_ptr ? IO_BITMAP_BITS : 0;
+#if CONFIG_XEN_COMPAT > 0x030002
mcl->op = __HYPERVISOR_physdev_op;
mcl->args[0] = PHYSDEVOP_set_iobitmap;
mcl->args[1] = (unsigned long)&iobmp_op;
+#else
+ mcl->op = __HYPERVISOR_physdev_op_compat;
+ pdo->cmd = PHYSDEVOP_set_iobitmap;
+ mcl->args[0] = (unsigned long)pdo++;
+#endif
mcl++;
}
+#if CONFIG_XEN_COMPAT <= 0x030002
+ BUG_ON(pdo > _pdo + ARRAY_SIZE(_pdo));
+#endif
BUG_ON(mcl > _mcl + ARRAY_SIZE(_mcl));
if (unlikely(HYPERVISOR_multicall_check(_mcl, mcl - _mcl, NULL)))
BUG();
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|