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-ia64-devel

[Xen-ia64-devel] [PATCH 7/16] domheap: allocate privregs from domain hea

To: xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-ia64-devel] [PATCH 7/16] domheap: allocate privregs from domain heap for VTi domain.
From: Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
Date: Mon, 7 Jan 2008 16:52:34 +0900
Cc: Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
Delivery-date: Sun, 06 Jan 2008 23:54:24 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-ia64-devel-request@lists.xensource.com?subject=help>
List-id: Discussion of the ia64 port of Xen <xen-ia64-devel.lists.xensource.com>
List-post: <mailto:xen-ia64-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ia64-devel>, <mailto:xen-ia64-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ia64-devel>, <mailto:xen-ia64-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-ia64-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mutt/1.4.2.1i
# HG changeset patch
# User yamahata@xxxxxxxxxxxxx
# Date 1198814687 -32400
# Node ID 3fa9bfb63a947099e0202c25437eb785507d6025
# Parent  b02e17ab2adf8b5b7199fd24a7408ce6e5a921f3
allocate privregs from domain heap for VTi domain.
- pin privregs down with both dtr/itr so that privregs can be allocated
  from the domain heap
- introduce vmx_vpd_pin()/vmx_vpd_unpin().
  the vpd area is pinned down when current. But two functions,
  update_vhpi() and alloc_vpd() are exceptions.
  We have to pin down the area before PAL call.
- minor twist context switch not to use unpinned vpd area.
  vmx_load_state() needs the vpd area pinned down.
  call it after vmx_load_all_rr()
- fix vmx_load_all_rr()
  vmx_switch_rr7() sets psr.ic = 0 so that clearing psr.ic before calling
  vmx_switch_rr7() doesn't make sense.
- improve vmx_switch_rr7()
  it sets psr.ic = 0 after switching to physical mode. But it can be
  done at the switching time.
PATCHNAME: vti_privregs_from_domheap

Signed-off-by: Isaku Yamahata <yamahata@xxxxxxxxxxxxx>

diff -r b02e17ab2adf -r 3fa9bfb63a94 xen/arch/ia64/vmx/vlsapic.c
--- a/xen/arch/ia64/vmx/vlsapic.c       Tue Dec 25 17:29:11 2007 +0900
+++ b/xen/arch/ia64/vmx/vlsapic.c       Fri Dec 28 13:04:47 2007 +0900
@@ -36,6 +36,7 @@
 #include <asm/gcc_intrin.h>
 #include <asm/vmx_mm_def.h>
 #include <asm/vmx.h>
+#include <asm/vmx_vpd.h>
 #include <asm/hw_irq.h>
 #include <asm/vmx_pal_vsa.h>
 #include <asm/kregs.h>
@@ -91,9 +92,12 @@ static void update_vhpi(VCPU *vcpu, int 
 
     VCPU(vcpu,vhpi) = vhpi;
     // TODO: Add support for XENO
-    if (VCPU(vcpu,vac).a_int)
+    if (VCPU(vcpu,vac).a_int) {
+        vmx_vpd_pin(vcpu);
         ia64_call_vsa(PAL_VPS_SET_PENDING_INTERRUPT, 
                       (uint64_t)vcpu->arch.privregs, 0, 0, 0, 0, 0, 0);
+        vmx_vpd_unpin(vcpu);
+    }
 }
 
 
diff -r b02e17ab2adf -r 3fa9bfb63a94 xen/arch/ia64/vmx/vmx_entry.S
--- a/xen/arch/ia64/vmx/vmx_entry.S     Tue Dec 25 17:29:11 2007 +0900
+++ b/xen/arch/ia64/vmx/vmx_entry.S     Fri Dec 28 13:04:47 2007 +0900
@@ -616,14 +616,14 @@ END(ia64_leave_hypercall)
 #define PSR_BITS_TO_CLEAR                                           \
        (IA64_PSR_I | IA64_PSR_IT | IA64_PSR_DT | IA64_PSR_DB |     \
         IA64_PSR_RT | IA64_PSR_DD | IA64_PSR_SS | IA64_PSR_RI |    \
-        IA64_PSR_ED | IA64_PSR_DFL | IA64_PSR_DFH)
+        IA64_PSR_ED | IA64_PSR_DFL | IA64_PSR_DFH | IA64_PSR_IC)
 #define PSR_BITS_TO_SET    IA64_PSR_BN
 
-//extern void vmx_switch_rr7(unsigned long rid, void *guest_vhpt, void * 
pal_vaddr );
+//extern void vmx_switch_rr7(unsigned long rid, void *guest_vhpt, void * 
pal_vaddr, void * shared_arch_info );
 GLOBAL_ENTRY(vmx_switch_rr7)
        // not sure this unwind statement is correct...
        .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(1)
-       alloc loc1 = ar.pfs, 3, 7, 0, 0
+       alloc loc1 = ar.pfs, 4, 8, 0, 0
 1:{
        mov r28  = in0                  // copy procedure index
        mov r8   = ip                   // save ip to compute branch
@@ -636,7 +636,12 @@ 1:{
        tpa r3 = r8                     // get physical address of ip
        dep loc5 = 0,in1,60,4           // get physical address of guest_vhpt
        dep loc6 = 0,in2,60,4           // get physical address of pal code
-       ;;
+       dep loc7 = 0,in3,60,4           // get physical address of privregs
+       ;;
+       dep loc6 = 0,loc6,0,IA64_GRANULE_SHIFT
+                                        // mask granule shift
+       dep loc7 = 0,loc7,0,IA64_GRANULE_SHIFT
+                                        // mask granule shift
        mov loc4 = psr                  // save psr
        ;;
        mov loc3 = ar.rsc               // save RSE configuration
@@ -654,11 +659,9 @@ 1:
        dep r16=-1,r0,61,3
        ;;
        mov rr[r16]=in0
+       ;;
        srlz.d
        ;;
-       rsm 0x6000
-       ;;
-       srlz.d
 
        // re-pin mappings for kernel text and data
        mov r18=KERNEL_TR_PAGE_SHIFT<<2
@@ -672,6 +675,7 @@ 1:
        mov r16=IA64_TR_KERNEL
        movl r25 = PAGE_KERNEL
        // r2=KERNEL_TR_PAGE_SHIFT truncated physicall address of ip
+       //   = ia64_tpa(ip) & (KERNEL_TR_PAGE_SIZE - 1)
        dep r2=0,r3,0,KERNEL_TR_PAGE_SHIFT
        ;;
        or r24=r2,r25
@@ -730,7 +734,9 @@ 1:
        // re-pin mappings for guest_vhpt
        // unless overlaps with IA64_TR_XEN_HEAP_REGS or IA64_TR_CURRENT_STACK
        dep r18=0,loc5,0,KERNEL_TR_PAGE_SHIFT
+       // r21 = (current physical addr) & (IA64_GRANULE_SIZE - 1)
        dep r21=0,r21,0,IA64_GRANULE_SHIFT 
+       // r17 = (guest_vhpt physical addr) & (IA64_GRANULE_SIZE - 1)
        dep r17=0,loc5,0,IA64_GRANULE_SHIFT 
        ;;
        cmp.eq p6,p0=r18,r2             // check overlap with xen heap
@@ -764,6 +770,43 @@ 1:
        itr.i itr[r24]=loc6             // wire in new mapping...
        ;;
 
+       // r16, r19, r20 are used by
+       //  ia64_switch_mode_phys()/ia64_switch_mode_virt()
+       // re-pin mappings for privregs
+       // r2   = ia64_tpa(ip) & (KERNEL_TR_PAGE_SIZE - 1)
+       // r21  = (current physical addr) & (IA64_GRANULE_SIZE - 1)
+       // r17  = (guest_vhpt physical addr) & (IA64_GRANULE_SIZE - 1)
+
+       // r24  = (privregs physical addr) & (KERNEL_TR_PAGE_SIZE - 1)
+       // loc6 = (((pal phys addr) & (IA64_GRANULE_SIZE - 1) << 2)) | 
PAGE_KERNEL
+       // loc7 = (privregs physical addr) & (IA64_GRANULE_SIZE - 1)
+       dep r24 = 0,loc7,0,KERNEL_TR_PAGE_SHIFT
+       ;;
+       cmp.ne p6,p0=r24,r2             // check overlap with xen heap
+       ;; 
+(p6)   cmp.ne.unc p7,p0=r21,loc7       // check overlap with current stack
+       ;;
+(p7)   cmp.ne.unc p8,p0=r17,loc7       // check overlap with guest_vhpt
+       ;;
+       // loc7 = (((privregs phys) & (IA64_GRANULE_SIZE - 1)) << 2) | 
PAGE_KERNEL
+       or loc7 = r25,loc7          // construct PA | page properties
+       ;;
+       cmp.ne p9,p0=loc6,loc7
+       mov r22=IA64_TR_VPD
+       mov r24=IA64_TR_MAPPED_REGS
+       mov r23 = IA64_GRANULE_SHIFT <<2
+       ;;
+(p9)   ptr.i   in3,r23 
+(p8)   ptr.d   in3,r23
+       mov cr.itir=r23
+       mov cr.ifa=in3
+       ;;
+(p9)   itr.i itr[r22]=loc7         // wire in new mapping...
+       ;;
+(p8)   itr.d dtr[r24]=loc7         // wire in new mapping...
+       ;;
+.privregs_overlaps:
+
        // done, switch back to virtual and return
        mov r16=loc4                    // r16= original psr
        br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode
diff -r b02e17ab2adf -r 3fa9bfb63a94 xen/arch/ia64/vmx/vmx_init.c
--- a/xen/arch/ia64/vmx/vmx_init.c      Tue Dec 25 17:29:11 2007 +0900
+++ b/xen/arch/ia64/vmx/vmx_init.c      Fri Dec 28 13:04:47 2007 +0900
@@ -51,6 +51,7 @@
 #include <asm/viosapic.h>
 #include <xen/event.h>
 #include <asm/vlsapic.h>
+#include <asm/vhpt.h>
 #include "entry.h"
 
 /* Global flag to identify whether Intel vmx feature is on */
@@ -150,20 +151,21 @@ typedef union {
        };
 } cpuid3_t;
 
-/* Allocate vpd from xenheap */
+/* Allocate vpd from domheap */
 static vpd_t *alloc_vpd(void)
 {
        int i;
        cpuid3_t cpuid3;
+       struct page_info *page;
        vpd_t *vpd;
        mapped_regs_t *mregs;
 
-       vpd = alloc_xenheap_pages(get_order(VPD_SIZE));
-       if (!vpd) {
+       page = alloc_domheap_pages(NULL, get_order(VPD_SIZE), 0);
+       if (page == NULL) {
                printk("VPD allocation failed.\n");
                return NULL;
        }
-       vpd = (vpd_t *)virt_to_xenva(vpd);
+       vpd = page_to_virt(page);
 
        printk(XENLOG_DEBUG "vpd base: 0x%p, vpd size:%ld\n",
               vpd, sizeof(vpd_t));
@@ -191,12 +193,79 @@ static vpd_t *alloc_vpd(void)
        return vpd;
 }
 
-/* Free vpd to xenheap */
+/* Free vpd to domheap */
 static void
 free_vpd(struct vcpu *v)
 {
        if ( v->arch.privregs )
-               free_xenheap_pages(v->arch.privregs, get_order(VPD_SIZE));
+               free_domheap_pages(virt_to_page(v->arch.privregs),
+                                  get_order(VPD_SIZE));
+}
+
+// This is used for PAL_VP_CREATE and PAL_VPS_SET_PENDING_INTERRUPT
+// so that we don't have to pin the vpd down with itr[].
+void
+__vmx_vpd_pin(struct vcpu* v)
+{
+       unsigned long privregs = (unsigned long)v->arch.privregs;
+       u64 psr;
+       
+       // check overlapping with xenheap
+       if ((privregs &
+            ~(KERNEL_TR_PAGE_SIZE - 1)) ==
+           ((unsigned long)__va(ia64_tpa(current_text_addr())) &
+            ~(KERNEL_TR_PAGE_SIZE - 1)))
+               return;
+               
+       privregs &= ~(IA64_GRANULE_SIZE - 1);
+
+       // check overlapping with current stack
+       if (privregs ==
+           ((unsigned long)current & ~(IA64_GRANULE_SIZE - 1)))
+               return;
+
+       if (!VMX_DOMAIN(current)) {
+               // check overlapping with vhpt
+               if (privregs ==
+                   (vcpu_vhpt_maddr(current) & ~(IA64_GRANULE_SHIFT - 1)))
+                       return;
+       } else {
+               // check overlapping with vhpt
+               if (privregs ==
+                   ((unsigned long)current->arch.vhpt.hash &
+                    ~(IA64_GRANULE_SHIFT - 1)))
+                       return;
+
+               // check overlapping with privregs
+               if (privregs ==
+                   ((unsigned long)current->arch.privregs &
+                    ~(IA64_GRANULE_SHIFT - 1)))
+                       return;
+       }
+
+       psr = ia64_clear_ic();
+       ia64_ptr(0x2 /*D*/, privregs, IA64_GRANULE_SIZE);
+       ia64_srlz_d();
+       ia64_itr(0x2 /*D*/, IA64_TR_MAPPED_REGS, privregs,
+                pte_val(pfn_pte(__pa(privregs) >> PAGE_SHIFT, PAGE_KERNEL)),
+                IA64_GRANULE_SHIFT);
+       ia64_set_psr(psr);
+       ia64_srlz_d();
+}
+
+void
+__vmx_vpd_unpin(struct vcpu* v)
+{
+       if (!VMX_DOMAIN(current)) {
+               int rc;
+               rc = !set_one_rr(VRN7 << VRN_SHIFT, VCPU(current, rrs[VRN7]));
+               BUG_ON(rc);
+       } else {
+               IA64FAULT fault;
+               fault = vmx_vcpu_set_rr(current, VRN7 << VRN_SHIFT,
+                                       VMX(current, vrr[VRN7]));
+               BUG_ON(fault != IA64_NO_FAULT);
+       }
 }
 
 /*
@@ -212,7 +281,11 @@ vmx_create_vp(struct vcpu *v)
        /* ia64_ivt is function pointer, so need this tranlation */
        ivt_base = (u64) &vmx_ia64_ivt;
        printk(XENLOG_DEBUG "ivt_base: 0x%lx\n", ivt_base);
+
+       vmx_vpd_pin(v);
        ret = ia64_pal_vp_create((u64 *)vpd, (u64 *)ivt_base, 0);
+       vmx_vpd_unpin(v);
+       
        if (ret != PAL_STATUS_SUCCESS){
                panic_domain(vcpu_regs(v),"ia64_pal_vp_create failed. \n");
        }
@@ -224,6 +297,7 @@ vmx_save_state(struct vcpu *v)
 {
        u64 status;
 
+       BUG_ON(v != current);
        /* FIXME: about setting of pal_proc_vector... time consuming */
        status = ia64_pal_vp_save((u64 *)v->arch.privregs, 0);
        if (status != PAL_STATUS_SUCCESS){
@@ -250,6 +324,7 @@ vmx_load_state(struct vcpu *v)
 {
        u64 status;
 
+       BUG_ON(v != current);
        status = ia64_pal_vp_restore((u64 *)v->arch.privregs, 0);
        if (status != PAL_STATUS_SUCCESS){
                panic_domain(vcpu_regs(v),"Restore vp status failed\n");
@@ -518,6 +593,7 @@ void vmx_do_resume(struct vcpu *v)
        ioreq_t *p;
 
        vmx_load_all_rr(v);
+       vmx_load_state(v);
        migrate_timer(&v->arch.arch_vmx.vtm.vtm_timer, v->processor);
 
        /* stolen from hvm_do_resume() in arch/x86/hvm/hvm.c */
diff -r b02e17ab2adf -r 3fa9bfb63a94 xen/arch/ia64/vmx/vmx_phy_mode.c
--- a/xen/arch/ia64/vmx/vmx_phy_mode.c  Tue Dec 25 17:29:11 2007 +0900
+++ b/xen/arch/ia64/vmx/vmx_phy_mode.c  Fri Dec 28 13:04:47 2007 +0900
@@ -138,7 +138,6 @@ void
 void
 vmx_load_all_rr(VCPU *vcpu)
 {
-       unsigned long psr;
        unsigned long rr0, rr4;
 
        switch (vcpu->arch.arch_vmx.mmu_mode) {
@@ -158,8 +157,6 @@ vmx_load_all_rr(VCPU *vcpu)
                panic_domain(NULL, "bad mmu mode value");
        }
 
-       psr = ia64_clear_ic();
-
        ia64_set_rr((VRN0 << VRN_SHIFT), rr0);
        ia64_dv_serialize_data();
        ia64_set_rr((VRN4 << VRN_SHIFT), rr4);
@@ -175,13 +172,11 @@ vmx_load_all_rr(VCPU *vcpu)
        ia64_set_rr((VRN6 << VRN_SHIFT), vrrtomrr(vcpu, VMX(vcpu, vrr[VRN6])));
        ia64_dv_serialize_data();
        vmx_switch_rr7(vrrtomrr(vcpu,VMX(vcpu, vrr[VRN7])),
-                      (void *)vcpu->arch.vhpt.hash, pal_vaddr);
+                (void *)vcpu->arch.vhpt.hash, pal_vaddr, vcpu->arch.privregs);
        ia64_set_pta(VMX(vcpu, mpta));
        vmx_ia64_set_dcr(vcpu);
 
        ia64_srlz_d();
-       ia64_set_psr(psr);
-       ia64_srlz_i();
 }
 
 void
diff -r b02e17ab2adf -r 3fa9bfb63a94 xen/arch/ia64/vmx/vmx_vcpu.c
--- a/xen/arch/ia64/vmx/vmx_vcpu.c      Tue Dec 25 17:29:11 2007 +0900
+++ b/xen/arch/ia64/vmx/vmx_vcpu.c      Fri Dec 28 13:04:47 2007 +0900
@@ -184,8 +184,8 @@ IA64FAULT vmx_vcpu_set_rr(VCPU *vcpu, u6
     switch((u64)(reg>>VRN_SHIFT)) {
     case VRN7:
         if (likely(vcpu == current))
-            vmx_switch_rr7(vrrtomrr(vcpu,val),
-                           (void *)vcpu->arch.vhpt.hash, pal_vaddr );
+            vmx_switch_rr7(vrrtomrr(vcpu,val), (void *)vcpu->arch.vhpt.hash,
+                           pal_vaddr, vcpu->arch.privregs);
        break;
     case VRN4:
         rrval = vrrtomrr(vcpu,val);
diff -r b02e17ab2adf -r 3fa9bfb63a94 xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c        Tue Dec 25 17:29:11 2007 +0900
+++ b/xen/arch/ia64/xen/domain.c        Fri Dec 28 13:04:47 2007 +0900
@@ -241,8 +241,6 @@ void context_switch(struct vcpu *prev, s
             ia64_setreg(_IA64_REG_CR_DCR, dcr);
         }
     }
-    if (VMX_DOMAIN(next))
-        vmx_load_state(next);
 
     ia64_disable_vhpt_walker();
     lazy_fp_switch(prev, current);
@@ -261,6 +259,7 @@ void context_switch(struct vcpu *prev, s
 
     if (VMX_DOMAIN(current)) {
         vmx_load_all_rr(current);
+        vmx_load_state(current);
         migrate_timer(&current->arch.arch_vmx.vtm.vtm_timer,
                       current->processor);
     } else {
diff -r b02e17ab2adf -r 3fa9bfb63a94 xen/include/asm-ia64/vmx_vcpu.h
--- a/xen/include/asm-ia64/vmx_vcpu.h   Tue Dec 25 17:29:11 2007 +0900
+++ b/xen/include/asm-ia64/vmx_vcpu.h   Fri Dec 28 13:04:47 2007 +0900
@@ -114,7 +114,7 @@ extern void memwrite_v(VCPU * vcpu, thas
                        size_t s);
 extern void memwrite_p(VCPU * vcpu, u64 * src, u64 * dest, size_t s);
 extern void vcpu_load_kernel_regs(VCPU * vcpu);
-extern void vmx_switch_rr7(unsigned long, void *, void *);
+extern void vmx_switch_rr7(unsigned long, void *, void *, void *);
 
 extern void dtlb_fault(VCPU * vcpu, u64 vadr);
 extern void nested_dtlb(VCPU * vcpu);
diff -r b02e17ab2adf -r 3fa9bfb63a94 xen/include/asm-ia64/vmx_vpd.h
--- a/xen/include/asm-ia64/vmx_vpd.h    Tue Dec 25 17:29:11 2007 +0900
+++ b/xen/include/asm-ia64/vmx_vpd.h    Fri Dec 28 13:04:47 2007 +0900
@@ -70,6 +70,24 @@ struct arch_vmx_struct {
 
 #define ARCH_VMX_DOMAIN         0       /* Need it to indicate VTi domain */
 
+/* pin/unpin vpd area for PAL call with DTR[] */
+void __vmx_vpd_pin(struct vcpu* v);
+void __vmx_vpd_unpin(struct vcpu* v); 
+
+static inline void vmx_vpd_pin(struct vcpu* v)
+{
+    if (likely(v == current))
+        return;
+    __vmx_vpd_pin(v);
+}
+
+static inline void vmx_vpd_unpin(struct vcpu* v)
+{
+    if (likely(v == current))
+        return;
+    __vmx_vpd_unpin(v);
+}
+
 #endif //__ASSEMBLY__
 
 // VPD field offset
diff -r b02e17ab2adf -r 3fa9bfb63a94 xen/include/asm-ia64/xenkregs.h
--- a/xen/include/asm-ia64/xenkregs.h   Tue Dec 25 17:29:11 2007 +0900
+++ b/xen/include/asm-ia64/xenkregs.h   Fri Dec 28 13:04:47 2007 +0900
@@ -8,6 +8,8 @@
 #define IA64_TR_SHARED_INFO    4       /* dtr4: page shared with domain */
 #define IA64_TR_MAPPED_REGS    5       /* dtr5: vcpu mapped regs */
 #define        IA64_TR_VHPT            6       /* dtr6: vhpt */
+
+#define IA64_TR_VPD            2       /* itr2: vpd */
 
 #define IA64_DTR_GUEST_KERNEL   7
 #define IA64_ITR_GUEST_KERNEL   2

Attachment: 16701_3fa9bfb63a94_vti_privregs_from_domheap.patch
Description: Text Data

_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ia64-devel
<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-ia64-devel] [PATCH 7/16] domheap: allocate privregs from domain heap for VTi domain., Isaku Yamahata <=