Jan Beulich
2008-Jul-18 09:45 UTC
[Xen-devel] [PATCH] linux/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. Almost as usual, written and tested on 2.6.16.60 and made apply to the 2.6.18 tree without further testing. Signed-off-by: Jan Beulich <jbeulich@novell.com> Index: sle10sp2-2008-06-04/arch/i386/kernel/process-xen.c ==================================================================--- sle10sp2-2008-06-04.orig/arch/i386/kernel/process-xen.c 2008-05-13 11:27:02.000000000 +0200 +++ sle10sp2-2008-06-04/arch/i386/kernel/process-xen.c 2008-06-23 14:55:31.000000000 +0200 @@ -533,8 +533,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. */ @@ -582,9 +588,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++; } @@ -592,12 +604,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(); Index: sle10sp2-2008-06-04/arch/x86_64/kernel/process-xen.c ==================================================================--- sle10sp2-2008-06-04.orig/arch/x86_64/kernel/process-xen.c 2008-05-13 11:27:02.000000000 +0200 +++ sle10sp2-2008-06-04/arch/x86_64/kernel/process-xen.c 2008-06-23 15:28:08.000000000 +0200 @@ -488,8 +488,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; /* @@ -532,9 +538,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++; } @@ -542,12 +554,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-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel