# HG changeset patch
# User Emmanuel Ackaouy <ack@xxxxxxxxxxxxx>
# Date 1168018471 0
# Node ID e4088ae584b81959999318c35bd718c21bed69f2
# Parent 244e46e7d021b1942ace91440c0fdab72a6ce5e4
Enable compatibility mode operation for HYPERVISOR_mmu_update and
HYPERVISOR_mmuext_op.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>
---
xen/arch/x86/mm.c | 16 ++--
xen/arch/x86/x86_64/compat/entry.S | 4 -
xen/arch/x86/x86_64/compat/mm.c | 148 +++++++++++++++++++++++++++++++++++++
xen/common/compat/xlat.c | 4 +
xen/include/asm-x86/hypercall.h | 7 +
xen/include/xlat.lst | 2
6 files changed, 170 insertions(+), 11 deletions(-)
diff -r 244e46e7d021 -r e4088ae584b8 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Fri Jan 05 17:34:31 2007 +0000
+++ b/xen/arch/x86/mm.c Fri Jan 05 17:34:31 2007 +0000
@@ -106,6 +106,7 @@
#include <asm/ldt.h>
#include <asm/x86_emulate.h>
#include <asm/e820.h>
+#include <asm/hypercall.h>
#include <public/memory.h>
#define MEM_LOG(_f, _a...) gdprintk(XENLOG_WARNING , _f "\n" , ## _a)
@@ -118,13 +119,6 @@
#if !defined(NDEBUG) || defined(CONFIG_X86_PAE)
#define PTE_UPDATE_WITH_CMPXCHG
#endif
-
-/*
- * Both do_mmuext_op() and do_mmu_update():
- * We steal the m.s.b. of the @count parameter to indicate whether this
- * invocation of do_mmu_update() is resuming a previously preempted call.
- */
-#define MMU_UPDATE_PREEMPTED (~(~0U>>1))
/* Used to defer flushing of memory structures. */
struct percpu_mm_info {
@@ -2033,6 +2027,8 @@ int do_mmuext_op(
goto pin_page;
case MMUEXT_PIN_L4_TABLE:
+ if ( IS_COMPAT(FOREIGNDOM) )
+ break;
type = PGT_l4_page_table;
pin_page:
@@ -2096,7 +2092,11 @@ int do_mmuext_op(
#ifdef __x86_64__
case MMUEXT_NEW_USER_BASEPTR:
- okay = 1;
+ if ( IS_COMPAT(FOREIGNDOM) )
+ {
+ okay = 0;
+ break;
+ }
if (likely(mfn != 0))
{
if ( shadow_mode_refcounts(d) )
diff -r 244e46e7d021 -r e4088ae584b8 xen/arch/x86/x86_64/compat/entry.S
--- a/xen/arch/x86/x86_64/compat/entry.S Fri Jan 05 17:34:31 2007 +0000
+++ b/xen/arch/x86/x86_64/compat/entry.S Fri Jan 05 17:34:31 2007 +0000
@@ -279,7 +279,6 @@ CFIX14:
.section .rodata, "a", @progbits
#define compat_set_trap_table domain_crash_synchronous
-#define compat_mmu_update domain_crash_synchronous
#define compat_set_gdt domain_crash_synchronous
#define compat_platform_op domain_crash_synchronous
#define compat_multicall domain_crash_synchronous
@@ -288,7 +287,6 @@ CFIX14:
#define compat_physdev_op_compat domain_crash_synchronous
#define compat_grant_table_op domain_crash_synchronous
#define compat_vcpu_op domain_crash_synchronous
-#define compat_mmuext_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
@@ -299,7 +297,7 @@ CFIX14:
ENTRY(compat_hypercall_table)
.quad compat_set_trap_table /* 0 */
- .quad compat_mmu_update
+ .quad do_mmu_update
.quad compat_set_gdt
.quad do_stack_switch
.quad compat_set_callbacks
diff -r 244e46e7d021 -r e4088ae584b8 xen/arch/x86/x86_64/compat/mm.c
--- a/xen/arch/x86/x86_64/compat/mm.c Fri Jan 05 17:34:31 2007 +0000
+++ b/xen/arch/x86/x86_64/compat/mm.c Fri Jan 05 17:34:31 2007 +0000
@@ -1,6 +1,8 @@
#ifdef CONFIG_COMPAT
+#include <xen/event.h>
#include <compat/memory.h>
+#include <compat/xen.h>
int compat_update_descriptor(u32 pa_lo, u32 pa_hi, u32 desc_lo, u32 desc_hi)
{
@@ -135,6 +137,152 @@ int compat_update_va_mapping_otherdomain
{
return do_update_va_mapping_otherdomain(va, lo | ((u64)hi << 32), flags,
domid);
}
+
+DEFINE_XEN_GUEST_HANDLE(mmuext_op_compat_t);
+
+int compat_mmuext_op(XEN_GUEST_HANDLE(mmuext_op_compat_t) cmp_uops,
+ unsigned int count,
+ XEN_GUEST_HANDLE(uint) pdone,
+ unsigned int foreigndom)
+{
+ unsigned int i, preempt_mask;
+ int rc = 0;
+ XEN_GUEST_HANDLE(mmuext_op_t) nat_ops;
+
+ preempt_mask = count & MMU_UPDATE_PREEMPTED;
+ count ^= preempt_mask;
+
+ if ( unlikely(!guest_handle_okay(cmp_uops, count)) )
+ return -EFAULT;
+
+ set_xen_guest_handle(nat_ops, (void
*)COMPAT_ARG_XLAT_VIRT_START(current->vcpu_id));
+
+ for ( ; count; count -= i )
+ {
+ mmuext_op_t *nat_op = nat_ops.p;
+ unsigned int limit;
+ int err;
+
+ if ( hypercall_preempt_check() )
+ {
+ rc = hypercall_create_continuation(
+ __HYPERVISOR_mmuext_op, "hihi",
+ cmp_uops, count | MMU_UPDATE_PREEMPTED, pdone, foreigndom);
+ break;
+ }
+
+ limit = COMPAT_ARG_XLAT_SIZE / sizeof(*nat_op);
+
+ for ( i = 0; i < min(limit, count); ++i )
+ {
+ mmuext_op_compat_t cmp_op;
+ enum XLAT_mmuext_op_arg1 arg1;
+ enum XLAT_mmuext_op_arg2 arg2;
+
+ if ( unlikely(__copy_from_guest(&cmp_op, cmp_uops, 1) != 0) )
+ {
+ rc = -EFAULT;
+ break;
+ }
+
+ switch ( cmp_op.cmd )
+ {
+ case MMUEXT_PIN_L1_TABLE:
+ case MMUEXT_PIN_L2_TABLE:
+ case MMUEXT_PIN_L3_TABLE:
+ case MMUEXT_PIN_L4_TABLE:
+ case MMUEXT_UNPIN_TABLE:
+ case MMUEXT_NEW_BASEPTR:
+ arg1 = XLAT_mmuext_op_arg1_mfn;
+ break;
+ default:
+ arg1 = XLAT_mmuext_op_arg1_linear_addr;
+ break;
+ case MMUEXT_NEW_USER_BASEPTR:
+ rc = -EINVAL;
+ case MMUEXT_TLB_FLUSH_LOCAL:
+ case MMUEXT_TLB_FLUSH_MULTI:
+ case MMUEXT_TLB_FLUSH_ALL:
+ case MMUEXT_FLUSH_CACHE:
+ arg1 = -1;
+ break;
+ }
+
+ if ( rc )
+ break;
+
+ switch ( cmp_op.cmd )
+ {
+ case MMUEXT_SET_LDT:
+ arg2 = XLAT_mmuext_op_arg2_nr_ents;
+ break;
+ case MMUEXT_TLB_FLUSH_MULTI:
+ case MMUEXT_INVLPG_MULTI:
+ arg2 = XLAT_mmuext_op_arg2_vcpumask;
+ break;
+ default:
+ arg2 = -1;
+ break;
+ }
+
+#define XLAT_mmuext_op_HNDL_arg2_vcpumask(_d_, _s_) \
+ do \
+ { \
+ unsigned int vcpumask; \
+ if ( i < --limit ) \
+ { \
+ (_d_)->arg2.vcpumask.p = (void *)(nat_ops.p + limit); \
+ if ( copy_from_compat(&vcpumask, (_s_)->arg2.vcpumask, 1)
== 0 ) \
+ *(unsigned long *)(_d_)->arg2.vcpumask.p = vcpumask; \
+ else \
+ rc = -EFAULT; \
+ } \
+ } while(0)
+ XLAT_mmuext_op(nat_op, &cmp_op);
+#undef XLAT_mmuext_op_HNDL_arg2_vcpumask
+
+ if ( rc || i >= limit )
+ break;
+
+ guest_handle_add_offset(cmp_uops, 1);
+ ++nat_op;
+ }
+
+ err = do_mmuext_op(nat_ops, i | preempt_mask, pdone, foreigndom);
+
+ if ( err )
+ {
+ BUILD_BUG_ON(__HYPERVISOR_mmuext_op <= 0);
+ if ( err == __HYPERVISOR_mmuext_op )
+ {
+ struct cpu_user_regs *regs = guest_cpu_user_regs();
+ unsigned int left = regs->ecx & ~MMU_UPDATE_PREEMPTED;
+
+ BUG_ON(!(regs->ecx & MMU_UPDATE_PREEMPTED));
+ BUG_ON(left > count);
+ guest_handle_add_offset(nat_ops, count - left);
+ BUG_ON(left + i < count);
+ guest_handle_add_offset(cmp_uops, (signed int)(count - left -
i));
+ left = 1;
+ BUG_ON(!hypercall_xlat_continuation(&left, 0x01, nat_ops,
cmp_uops));
+ BUG_ON(left != regs->ecx);
+ regs->ecx += count - i;
+ }
+ else
+ BUG_ON(rc > 0);
+ rc = err;
+ }
+
+ if ( rc )
+ break;
+
+ /* Force do_mmuext_op() to not start counting from zero again. */
+ preempt_mask = MMU_UPDATE_PREEMPTED;
+ }
+
+ return rc;
+}
+
#endif /* CONFIG_COMPAT */
/*
diff -r 244e46e7d021 -r e4088ae584b8 xen/common/compat/xlat.c
--- a/xen/common/compat/xlat.c Fri Jan 05 17:34:31 2007 +0000
+++ b/xen/common/compat/xlat.c Fri Jan 05 17:34:31 2007 +0000
@@ -21,6 +21,10 @@ CHECK_dom0_vga_console_info;
CHECK_dom0_vga_console_info;
#undef dom0_vga_console_info
+#define xen_mmu_update mmu_update
+CHECK_mmu_update;
+#undef xen_mmu_update
+
#define xen_vcpu_time_info vcpu_time_info
CHECK_vcpu_time_info;
#undef xen_vcpu_time_info
diff -r 244e46e7d021 -r e4088ae584b8 xen/include/asm-x86/hypercall.h
--- a/xen/include/asm-x86/hypercall.h Fri Jan 05 17:34:31 2007 +0000
+++ b/xen/include/asm-x86/hypercall.h Fri Jan 05 17:34:31 2007 +0000
@@ -7,6 +7,13 @@
#include <public/physdev.h>
#include <xen/types.h>
+
+/*
+ * Both do_mmuext_op() and do_mmu_update():
+ * We steal the m.s.b. of the @count parameter to indicate whether this
+ * invocation of do_mmu_update() is resuming a previously preempted call.
+ */
+#define MMU_UPDATE_PREEMPTED (~(~0U>>1))
extern long
do_event_channel_op_compat(
diff -r 244e46e7d021 -r e4088ae584b8 xen/include/xlat.lst
--- a/xen/include/xlat.lst Fri Jan 05 17:34:31 2007 +0000
+++ b/xen/include/xlat.lst Fri Jan 05 17:34:31 2007 +0000
@@ -2,6 +2,8 @@
# ! - needs translation
# ? - needs checking
? dom0_vga_console_info xen.h
+? mmu_update xen.h
+! mmuext_op xen.h
! start_info xen.h
? vcpu_time_info xen.h
! add_to_physmap memory.h
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|