WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] PV-on-HVM: Add new ioreq 'invalidate' for

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] PV-on-HVM: Add new ioreq 'invalidate' for zapping ioemu-dm mapccahe
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 05 Apr 2007 14:00:24 -0700
Delivery-date: Thu, 05 Apr 2007 13:59:43 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1175779758 -3600
# Node ID 1a347b19142ac3bc136cb3a3896968740e3bcbf7
# Parent  c29a4adc65c6d6faf185dc1b444663f11e1e0201
PV-on-HVM: Add new ioreq 'invalidate' for zapping ioemu-dm mapccahe
after balloon operations in an HVM guest.

This removes the I/O port hack from the guest OS, and from ioemu.

Also we flush on reservation *increases* as well as decreases. This is
necessary until qemu-dm can demand-fault page mappings into existing
valid buckets.

Signed-off-by: Steven Hand <steven@xxxxxxxxxxxxx>
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c       |    8 -
 tools/ioemu/hw/xen_platform.c                            |    8 -
 tools/ioemu/target-i386-dm/helper2.c                     |    7 +
 unmodified_drivers/linux-2.6/platform-pci/platform-pci.c |   10 --
 xen/arch/x86/hvm/hvm.c                                   |   73 ++++++++-------
 xen/arch/x86/hvm/io.c                                    |   12 ++
 xen/arch/x86/hvm/platform.c                              |   28 +++++
 xen/arch/x86/hvm/svm/svm.c                               |   11 +-
 xen/arch/x86/hvm/vmx/vmx.c                               |   10 +-
 xen/include/asm-x86/hvm/io.h                             |    1 
 xen/include/asm-x86/hvm/support.h                        |    3 
 xen/include/public/hvm/ioreq.h                           |    1 
 12 files changed, 104 insertions(+), 68 deletions(-)

diff -r c29a4adc65c6 -r 1a347b19142a 
linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c
--- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c        Thu Apr 05 
14:02:55 2007 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c        Thu Apr 05 
14:29:18 2007 +0100
@@ -306,14 +306,6 @@ static int decrease_reservation(unsigned
                balloon_append(pfn_to_page(pfn));
        }
 
-#ifndef CONFIG_XEN
-       /* XXX Temporary hack. */
-       {
-               extern void xen_invalidate_foreign_mappings(void);
-               xen_invalidate_foreign_mappings(); 
-       }
-#endif
-
        set_xen_guest_handle(reservation.extent_start, frame_list);
        reservation.nr_extents   = nr_pages;
        ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation);
diff -r c29a4adc65c6 -r 1a347b19142a tools/ioemu/hw/xen_platform.c
--- a/tools/ioemu/hw/xen_platform.c     Thu Apr 05 14:02:55 2007 +0100
+++ b/tools/ioemu/hw/xen_platform.c     Thu Apr 05 14:29:18 2007 +0100
@@ -29,16 +29,10 @@
 
 extern FILE *logfile;
 
-static void platform_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
-    if (val == 0)
-        qemu_invalidate_map_cache();
-}
-
 static void platform_ioport_map(PCIDevice *pci_dev, int region_num,
                                 uint32_t addr, uint32_t size, int type)
 {
-    register_ioport_write(addr, 1, 1, platform_ioport_write, NULL);
+    /* nothing yet */
 }
 
 static uint32_t platform_mmio_read(void *opaque, target_phys_addr_t addr)
diff -r c29a4adc65c6 -r 1a347b19142a tools/ioemu/target-i386-dm/helper2.c
--- a/tools/ioemu/target-i386-dm/helper2.c      Thu Apr 05 14:02:55 2007 +0100
+++ b/tools/ioemu/target-i386-dm/helper2.c      Thu Apr 05 14:29:18 2007 +0100
@@ -506,8 +506,11 @@ void __handle_ioreq(CPUState *env, ioreq
         cpu_ioreq_xchg(env, req);
         break;
     case IOREQ_TYPE_TIMEOFFSET:
-       cpu_ioreq_timeoffset(env, req);
-       break;
+        cpu_ioreq_timeoffset(env, req);
+        break;
+    case IOREQ_TYPE_INVALIDATE:
+        qemu_invalidate_map_cache();
+        break;
     default:
         hw_error("Invalid ioreq type 0x%x\n", req->type);
     }
diff -r c29a4adc65c6 -r 1a347b19142a 
unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
--- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c  Thu Apr 05 
14:02:55 2007 +0100
+++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c  Thu Apr 05 
14:29:18 2007 +0100
@@ -208,14 +208,6 @@ static uint64_t get_callback_via(struct 
                ((uint64_t)(pin - 1) & 3));
 }
 
-/* Invalidate foreign mappings (e.g., in qemu-based device model). */
-static uint16_t invlmap_port;
-void xen_invalidate_foreign_mappings(void)
-{
-       outb(0, invlmap_port);
-}
-EXPORT_SYMBOL(xen_invalidate_foreign_mappings);
-
 static int __devinit platform_pci_init(struct pci_dev *pdev,
                                       const struct pci_device_id *ent)
 {
@@ -239,8 +231,6 @@ static int __devinit platform_pci_init(s
                printk(KERN_WARNING DRV_NAME ":no resources found\n");
                return -ENOENT;
        }
-
-       invlmap_port = ioaddr;
 
        if (request_mem_region(mmio_addr, mmio_len, DRV_NAME) == NULL)
        {
diff -r c29a4adc65c6 -r 1a347b19142a xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Thu Apr 05 14:02:55 2007 +0100
+++ b/xen/arch/x86/hvm/hvm.c    Thu Apr 05 14:29:18 2007 +0100
@@ -521,32 +521,19 @@ static hvm_hypercall_t *hvm_hypercall_ta
     HYPERCALL(hvm_op)
 };
 
-int hvm_do_hypercall(struct cpu_user_regs *pregs)
-{
-    if ( unlikely(ring_3(pregs)) )
-    {
-        pregs->eax = -EPERM;
-        return 0;
-    }
-
+static void __hvm_do_hypercall(struct cpu_user_regs *pregs)
+{
     if ( (pregs->eax >= NR_hypercalls) || !hvm_hypercall_table[pregs->eax] )
     {
         if ( pregs->eax != __HYPERVISOR_grant_table_op )
             gdprintk(XENLOG_WARNING, "HVM vcpu %d:%d bad hypercall %d.\n",
                      current->domain->domain_id, current->vcpu_id, pregs->eax);
         pregs->eax = -ENOSYS;
-        return 0;
-    }
-
-    /* Check for preemption: EIP will be modified from this dummy value. */
-    pregs->eip = 0xF0F0F0FF;
+        return;
+    }
 
     pregs->eax = hvm_hypercall_table[pregs->eax](
         pregs->ebx, pregs->ecx, pregs->edx, pregs->esi, pregs->edi);
-
-    /* XXX: put fake IO instr here to inform the emulator to flush mapcache */
-
-    return (pregs->eip != 0xF0F0F0FF); /* preempted? */
 }
 
 #else /* defined(__x86_64__) */
@@ -606,14 +593,8 @@ static hvm_hypercall_t *hvm_hypercall32_
     HYPERCALL(event_channel_op)
 };
 
-int hvm_do_hypercall(struct cpu_user_regs *pregs)
-{
-    if ( unlikely(ring_3(pregs)) )
-    {
-        pregs->rax = -EPERM;
-        return 0;
-    }
-
+static void __hvm_do_hypercall(struct cpu_user_regs *pregs)
+{
     pregs->rax = (uint32_t)pregs->eax; /* mask in case compat32 caller */
     if ( (pregs->rax >= NR_hypercalls) || !hvm_hypercall64_table[pregs->rax] )
     {
@@ -621,11 +602,8 @@ int hvm_do_hypercall(struct cpu_user_reg
             gdprintk(XENLOG_WARNING, "HVM vcpu %d:%d bad hypercall %ld.\n",
                      current->domain->domain_id, current->vcpu_id, pregs->rax);
         pregs->rax = -ENOSYS;
-        return 0;
-    }
-
-    /* Check for preemption: RIP will be modified from this dummy value. */
-    pregs->rip = 0xF0F0F0FF;
+        return;
+    }
 
     if ( current->arch.paging.mode->guest_levels == 4 )
     {
@@ -643,13 +621,40 @@ int hvm_do_hypercall(struct cpu_user_reg
                                                        (uint32_t)pregs->esi,
                                                        (uint32_t)pregs->edi);
     }
-
-    /* XXX: put fake IO instr here to inform the emulator to flush mapcache */
-
-    return (pregs->rip != 0xF0F0F0FF); /* preempted? */
 }
 
 #endif /* defined(__x86_64__) */
+
+int hvm_do_hypercall(struct cpu_user_regs *pregs)
+{
+    int flush, preempted;
+    unsigned long old_eip;
+
+    if ( unlikely(ring_3(pregs)) )
+    {
+        pregs->eax = -EPERM;
+        return 0;
+    }
+
+    /*
+     * NB. In future flush only on decrease_reservation.
+     * For now we also need to flush when pages are added, as qemu-dm is not
+     * yet capable of faulting pages into an existing valid mapcache bucket.
+     */
+    flush = ((uint32_t)pregs->eax == __HYPERVISOR_memory_op);
+
+    /* Check for preemption: RIP will be modified from this dummy value. */
+    old_eip = pregs->eip;
+    pregs->eip = 0xF0F0F0FF;
+
+    __hvm_do_hypercall(pregs);
+
+    preempted = (pregs->eip != 0xF0F0F0FF);
+    pregs->eip = old_eip;
+
+    return (preempted ? HVM_HCALL_preempted :
+            flush ? HVM_HCALL_invalidate : HVM_HCALL_completed);
+}
 
 void hvm_update_guest_cr3(struct vcpu *v, unsigned long guest_cr3)
 {
diff -r c29a4adc65c6 -r 1a347b19142a xen/arch/x86/hvm/io.c
--- a/xen/arch/x86/hvm/io.c     Thu Apr 05 14:02:55 2007 +0100
+++ b/xen/arch/x86/hvm/io.c     Thu Apr 05 14:29:18 2007 +0100
@@ -845,10 +845,17 @@ void hvm_io_assist(void)
 
     p->state = STATE_IOREQ_NONE;
 
-    if ( p->type == IOREQ_TYPE_PIO )
+    switch ( p->type )
+    {
+    case IOREQ_TYPE_INVALIDATE:
+        goto out;
+    case IOREQ_TYPE_PIO:
         hvm_pio_assist(regs, p, io_opp);
-    else
+        break;
+    default:
         hvm_mmio_assist(regs, p, io_opp);
+        break;
+    }
 
     /* Copy register changes back into current guest state. */
     hvm_load_cpu_guest_regs(v, regs);
@@ -861,6 +868,7 @@ void hvm_io_assist(void)
         mark_dirty(d, gmfn);
     }
 
+ out:
     vcpu_end_shutdown_deferral(v);
 }
 
diff -r c29a4adc65c6 -r 1a347b19142a xen/arch/x86/hvm/platform.c
--- a/xen/arch/x86/hvm/platform.c       Thu Apr 05 14:02:55 2007 +0100
+++ b/xen/arch/x86/hvm/platform.c       Thu Apr 05 14:29:18 2007 +0100
@@ -941,6 +941,34 @@ void send_timeoffset_req(unsigned long t
         printk("Unsuccessful timeoffset update\n");
 }
 
+/* Ask ioemu mapcache to invalidate mappings. */
+void send_invalidate_req(void)
+{
+    struct vcpu *v = current;
+    vcpu_iodata_t *vio;
+    ioreq_t *p;
+
+    vio = get_vio(v->domain, v->vcpu_id);
+    if ( vio == NULL )
+    {
+        printk("bad shared page: %lx\n", (unsigned long) vio);
+        domain_crash_synchronous();
+    }
+
+    p = &vio->vp_ioreq;
+    if ( p->state != STATE_IOREQ_NONE )
+        printk("WARNING: send invalidate req with something "
+               "already pending (%d)?\n", p->state);
+
+    p->type = IOREQ_TYPE_INVALIDATE;
+    p->size = 4;
+    p->dir = IOREQ_WRITE;
+    p->data = ~0UL; /* flush all */
+    p->io_count++;
+
+    hvm_send_assist_req(v);
+}
+
 static void mmio_operands(int type, unsigned long gpa,
                           struct hvm_io_op *mmio_op,
                           unsigned char op_size)
diff -r c29a4adc65c6 -r 1a347b19142a xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Thu Apr 05 14:02:55 2007 +0100
+++ b/xen/arch/x86/hvm/svm/svm.c        Thu Apr 05 14:29:18 2007 +0100
@@ -2166,7 +2166,7 @@ asmlinkage void svm_vmexit_handler(struc
     unsigned long eip;
     struct vcpu *v = current;
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-    int inst_len;
+    int inst_len, rc;
 
     exit_reason = vmcb->exitcode;
     save_svm_cpu_user_regs(v, regs);
@@ -2275,8 +2275,13 @@ asmlinkage void svm_vmexit_handler(struc
         inst_len = __get_instruction_length(v, INSTR_VMCALL, NULL);
         ASSERT(inst_len > 0);
         HVMTRACE_1D(VMMCALL, v, regs->eax);
-        if ( !hvm_do_hypercall(regs) )
-            __update_guest_eip(vmcb, inst_len); /* not preempted */
+        rc = hvm_do_hypercall(regs);
+        if ( rc != HVM_HCALL_preempted )
+        {
+            __update_guest_eip(vmcb, inst_len);
+            if ( rc == HVM_HCALL_invalidate )
+                send_invalidate_req();
+        }
         break;
 
     case VMEXIT_CR0_READ:
diff -r c29a4adc65c6 -r 1a347b19142a xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Thu Apr 05 14:02:55 2007 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Thu Apr 05 14:29:18 2007 +0100
@@ -2626,10 +2626,16 @@ asmlinkage void vmx_vmexit_handler(struc
     }
     case EXIT_REASON_VMCALL:
     {
+        int rc;
         HVMTRACE_1D(VMMCALL, v, regs->eax);
         inst_len = __get_instruction_length(); /* Safe: VMCALL */
-        if ( !hvm_do_hypercall(regs) )
-            __update_guest_eip(inst_len); /* not preempted */
+        rc = hvm_do_hypercall(regs);
+        if ( rc != HVM_HCALL_preempted )
+        {
+            __update_guest_eip(inst_len);
+            if ( rc == HVM_HCALL_invalidate )
+                send_invalidate_req();
+        }
         break;
     }
     case EXIT_REASON_CR_ACCESS:
diff -r c29a4adc65c6 -r 1a347b19142a xen/include/asm-x86/hvm/io.h
--- a/xen/include/asm-x86/hvm/io.h      Thu Apr 05 14:02:55 2007 +0100
+++ b/xen/include/asm-x86/hvm/io.h      Thu Apr 05 14:29:18 2007 +0100
@@ -147,6 +147,7 @@ extern void send_pio_req(unsigned long p
 extern void send_pio_req(unsigned long port, unsigned long count, int size,
                          paddr_t value, int dir, int df, int value_is_ptr);
 void send_timeoffset_req(unsigned long timeoff);
+void send_invalidate_req(void);
 extern void handle_mmio(unsigned long gpa);
 extern void hvm_interrupt_post(struct vcpu *v, int vector, int type);
 extern void hvm_io_assist(void);
diff -r c29a4adc65c6 -r 1a347b19142a xen/include/asm-x86/hvm/support.h
--- a/xen/include/asm-x86/hvm/support.h Thu Apr 05 14:02:55 2007 +0100
+++ b/xen/include/asm-x86/hvm/support.h Thu Apr 05 14:29:18 2007 +0100
@@ -228,6 +228,9 @@ void hvm_print_line(struct vcpu *v, cons
 void hvm_print_line(struct vcpu *v, const char c);
 void hlt_timer_fn(void *data);
 
+#define HVM_HCALL_completed  0 /* hypercall completed - no further action */
+#define HVM_HCALL_preempted  1 /* hypercall preempted - re-execute VMCALL */
+#define HVM_HCALL_invalidate 2 /* invalidate ioemu-dm memory cache        */
 int hvm_do_hypercall(struct cpu_user_regs *pregs);
 
 void hvm_hlt(unsigned long rflags);
diff -r c29a4adc65c6 -r 1a347b19142a xen/include/public/hvm/ioreq.h
--- a/xen/include/public/hvm/ioreq.h    Thu Apr 05 14:02:55 2007 +0100
+++ b/xen/include/public/hvm/ioreq.h    Thu Apr 05 14:29:18 2007 +0100
@@ -40,6 +40,7 @@
 #define IOREQ_TYPE_XCHG         5
 #define IOREQ_TYPE_ADD          6
 #define IOREQ_TYPE_TIMEOFFSET   7
+#define IOREQ_TYPE_INVALIDATE   8 /* mapcache */
 
 /*
  * VMExit dispatcher should cooperate with instruction decoder to

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] PV-on-HVM: Add new ioreq 'invalidate' for zapping ioemu-dm mapccahe, Xen patchbot-unstable <=