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] [IA64] Renames vmx_process.c into vmx_fau

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [IA64] Renames vmx_process.c into vmx_fault.c
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 27 Jul 2007 02:56:24 -0700
Delivery-date: Fri, 27 Jul 2007 02:54:27 -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 Alex Williamson <alex.williamson@xxxxxx>
# Date 1183663482 21600
# Node ID 5927f10462cd4ed7c71671aebc075a750ff77604
# Parent  a8aeffcc06aa6b6553d4039f3834fed1f45d1494
[IA64] Renames vmx_process.c into vmx_fault.c

Signed-off-by: Tristan Gingold <tgingold@xxxxxxx>
---
 xen/arch/ia64/vmx/vmx_process.c |  528 ----------------------------------------
 xen/arch/ia64/vmx/Makefile      |    2 
 xen/arch/ia64/vmx/vmx_fault.c   |  528 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 529 insertions(+), 529 deletions(-)

diff -r a8aeffcc06aa -r 5927f10462cd xen/arch/ia64/vmx/Makefile
--- a/xen/arch/ia64/vmx/Makefile        Thu Jul 05 13:17:30 2007 -0600
+++ b/xen/arch/ia64/vmx/Makefile        Thu Jul 05 13:24:42 2007 -0600
@@ -10,7 +10,7 @@ obj-y += vmx_interrupt.o
 obj-y += vmx_interrupt.o
 obj-y += vmx_ivt.o
 obj-y += vmx_phy_mode.o
-obj-y += vmx_process.o
+obj-y += vmx_fault.o
 obj-y += vmx_support.o
 obj-y += vmx_utility.o
 obj-y += vmx_vcpu.o
diff -r a8aeffcc06aa -r 5927f10462cd xen/arch/ia64/vmx/vmx_fault.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/ia64/vmx/vmx_fault.c     Thu Jul 05 13:24:42 2007 -0600
@@ -0,0 +1,528 @@
+/* -*-  Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */
+/*
+ * vmx_process.c: handling VMX architecture-related VM exits
+ * Copyright (c) 2005, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ *  Xiaoyan Feng (Fleming Feng)  <fleming.feng@xxxxxxxxx>
+ *  Xuefei Xu (Anthony Xu) (Anthony.xu@xxxxxxxxx)
+ */
+
+#include <xen/config.h>
+#include <xen/lib.h>
+#include <xen/errno.h>
+#include <xen/sched.h>
+#include <xen/smp.h>
+#include <asm/ptrace.h>
+#include <xen/delay.h>
+
+#include <linux/efi.h>  /* FOR EFI_UNIMPLEMENTED */
+#include <asm/sal.h>    /* FOR struct ia64_sal_retval */
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/desc.h>
+#include <asm/vlsapic.h>
+#include <xen/irq.h>
+#include <xen/event.h>
+#include <asm/regionreg.h>
+#include <asm/privop.h>
+#include <asm/ia64_int.h>
+#include <asm/debugger.h>
+//#include <asm/hpsim_ssc.h>
+#include <asm/dom_fw.h>
+#include <asm/vmx_vcpu.h>
+#include <asm/kregs.h>
+#include <asm/vmx.h>
+#include <asm/vmmu.h>
+#include <asm/vmx_mm_def.h>
+#include <asm/vmx_phy_mode.h>
+#include <xen/mm.h>
+#include <asm/vmx_pal.h>
+/* reset all PSR field to 0, except up,mfl,mfh,pk,dt,rt,mc,it */
+#define INITIAL_PSR_VALUE_AT_INTERRUPTION 0x0000001808028034
+
+
+extern void die_if_kernel(char *str, struct pt_regs *regs, long err);
+extern void rnat_consumption (VCPU *vcpu);
+extern void alt_itlb (VCPU *vcpu, u64 vadr);
+extern void itlb_fault (VCPU *vcpu, u64 vadr);
+extern void ivhpt_fault (VCPU *vcpu, u64 vadr);
+extern unsigned long handle_fpu_swa (int fp_fault, struct pt_regs *regs, 
unsigned long isr);
+
+#define DOMN_PAL_REQUEST    0x110000
+#define DOMN_SAL_REQUEST    0x110001
+
+static u64 vec2off[68] = {0x0,0x400,0x800,0xc00,0x1000,0x1400,0x1800,
+    0x1c00,0x2000,0x2400,0x2800,0x2c00,0x3000,0x3400,0x3800,0x3c00,0x4000,
+    0x4400,0x4800,0x4c00,0x5000,0x5100,0x5200,0x5300,0x5400,0x5500,0x5600,
+    0x5700,0x5800,0x5900,0x5a00,0x5b00,0x5c00,0x5d00,0x5e00,0x5f00,0x6000,
+    0x6100,0x6200,0x6300,0x6400,0x6500,0x6600,0x6700,0x6800,0x6900,0x6a00,
+    0x6b00,0x6c00,0x6d00,0x6e00,0x6f00,0x7000,0x7100,0x7200,0x7300,0x7400,
+    0x7500,0x7600,0x7700,0x7800,0x7900,0x7a00,0x7b00,0x7c00,0x7d00,0x7e00,
+    0x7f00
+};
+
+
+
+void vmx_reflect_interruption(u64 ifa, u64 isr, u64 iim,
+                              u64 vec, REGS *regs)
+{
+    u64 status, vector;
+    VCPU *vcpu = current;
+    u64 vpsr = VCPU(vcpu, vpsr);
+    
+    vector = vec2off[vec];
+
+    switch (vec) {
+    case 5:  // IA64_DATA_NESTED_TLB_VECTOR
+        break;
+    case 22:   // IA64_INST_ACCESS_RIGHTS_VECTOR
+        if (!(vpsr & IA64_PSR_IC))
+            goto nested_fault;
+        if (vhpt_access_rights_fixup(vcpu, ifa, 0))
+            return;
+        break;
+
+    case 25:   // IA64_DISABLED_FPREG_VECTOR
+        if (!(vpsr & IA64_PSR_IC))
+            goto nested_fault;
+        if (FP_PSR(vcpu) & IA64_PSR_DFH) {
+            FP_PSR(vcpu) = IA64_PSR_MFH;
+            if (__ia64_per_cpu_var(fp_owner) != vcpu)
+                __ia64_load_fpu(vcpu->arch._thread.fph);
+        }
+        if (!(VCPU(vcpu, vpsr) & IA64_PSR_DFH)) {
+            regs->cr_ipsr &= ~IA64_PSR_DFH;
+            return;
+        }
+
+        break;       
+
+    case 32:   // IA64_FP_FAULT_VECTOR
+        if (!(vpsr & IA64_PSR_IC))
+            goto nested_fault;
+        // handle fpswa emulation
+        // fp fault
+        status = handle_fpu_swa(1, regs, isr);
+        if (!status) {
+            vcpu_increment_iip(vcpu);
+            return;
+        } else if (IA64_RETRY == status)
+            return;
+        break;
+
+    case 33:   // IA64_FP_TRAP_VECTOR
+        if (!(vpsr & IA64_PSR_IC))
+            goto nested_fault;
+        //fp trap
+        status = handle_fpu_swa(0, regs, isr);
+        if (!status)
+            return;
+        else if (IA64_RETRY == status) {
+            vcpu_decrement_iip(vcpu);
+            return;
+        }
+        break;
+
+    case 29: // IA64_DEBUG_VECTOR
+    case 35: // IA64_TAKEN_BRANCH_TRAP_VECTOR
+    case 36: // IA64_SINGLE_STEP_TRAP_VECTOR
+        if (vmx_guest_kernel_mode(regs)
+            && current->domain->debugger_attached) {
+            domain_pause_for_debugger();
+            return;
+        }
+        if (!(vpsr & IA64_PSR_IC))
+            goto nested_fault;
+        break;
+
+    default:
+        if (!(vpsr & IA64_PSR_IC))
+            goto nested_fault;
+        break;
+    } 
+    VCPU(vcpu,isr)=isr;
+    VCPU(vcpu,iipa) = regs->cr_iip;
+    if (vector == IA64_BREAK_VECTOR || vector == IA64_SPECULATION_VECTOR)
+        VCPU(vcpu,iim) = iim;
+    else {
+        set_ifa_itir_iha(vcpu,ifa,1,1,1);
+    }
+    inject_guest_interruption(vcpu, vector);
+    return;
+
+ nested_fault:
+    panic_domain(regs, "Guest nested fault vector=%lx!\n", vector);
+}
+
+
+IA64FAULT
+vmx_ia64_handle_break (unsigned long ifa, struct pt_regs *regs, unsigned long 
isr, unsigned long iim)
+{
+    struct domain *d = current->domain;
+    struct vcpu *v = current;
+
+    perfc_incr(vmx_ia64_handle_break);
+#ifdef CRASH_DEBUG
+    if ((iim == 0 || iim == CDB_BREAK_NUM) && !guest_mode(regs) &&
+        IS_VMM_ADDRESS(regs->cr_iip)) {
+        if (iim == 0)
+            show_registers(regs);
+        debugger_trap_fatal(0 /* don't care */, regs);
+    } else
+#endif
+    {
+        if (iim == 0) 
+            vmx_die_if_kernel("Break 0 in Hypervisor.", regs, iim);
+
+        if (ia64_psr(regs)->cpl == 0) {
+            /* Allow hypercalls only when cpl = 0.  */
+            if (iim == d->arch.breakimm) {
+                ia64_hypercall(regs);
+                vcpu_increment_iip(v);
+                return IA64_NO_FAULT;
+            }
+            else if(iim == DOMN_PAL_REQUEST){
+                pal_emul(v);
+                vcpu_increment_iip(v);
+                return IA64_NO_FAULT;
+            }else if(iim == DOMN_SAL_REQUEST){
+                sal_emul(v);
+                vcpu_increment_iip(v);
+                return IA64_NO_FAULT;
+            }
+        }
+        vmx_reflect_interruption(ifa,isr,iim,11,regs);
+    }
+    return IA64_NO_FAULT;
+}
+
+
+void save_banked_regs_to_vpd(VCPU *v, REGS *regs)
+{
+    unsigned long i=0UL, * src,* dst, *sunat, *dunat;
+    IA64_PSR vpsr;
+    src=&regs->r16;
+    sunat=&regs->eml_unat;
+    vpsr.val = VCPU(v, vpsr);
+    if(vpsr.bn){
+        dst = &VCPU(v, vgr[0]);
+        dunat =&VCPU(v, vnat);
+        __asm__ __volatile__ (";;extr.u %0 = %1,%4,16;; \
+                            dep %2 = %0, %2, 0, 16;; \
+                            st8 [%3] = %2;;"
+       
::"r"(i),"r"(*sunat),"r"(*dunat),"r"(dunat),"i"(IA64_PT_REGS_R16_SLOT):"memory");
+
+    }else{
+        dst = &VCPU(v, vbgr[0]);
+//        dunat =&VCPU(v, vbnat);
+//        __asm__ __volatile__ (";;extr.u %0 = %1,%4,16;;
+//                            dep %2 = %0, %2, 16, 16;;
+//                            st8 [%3] = %2;;"
+//       
::"r"(i),"r"(*sunat),"r"(*dunat),"r"(dunat),"i"(IA64_PT_REGS_R16_SLOT):"memory");
+
+    }
+    for(i=0; i<16; i++)
+        *dst++ = *src++;
+}
+
+
+// ONLY gets called from ia64_leave_kernel
+// ONLY call with interrupts disabled?? (else might miss one?)
+// NEVER successful if already reflecting a trap/fault because psr.i==0
+void leave_hypervisor_tail(void)
+{
+    struct domain *d = current->domain;
+    struct vcpu *v = current;
+
+    // FIXME: Will this work properly if doing an RFI???
+    if (!is_idle_domain(d) ) { // always comes from guest
+//        struct pt_regs *user_regs = vcpu_regs(current);
+        local_irq_enable();
+        do_softirq();
+        local_irq_disable();
+
+        if (v->vcpu_id == 0) {
+            unsigned long callback_irq =
+                d->arch.hvm_domain.params[HVM_PARAM_CALLBACK_IRQ];
+
+            if ( v->arch.arch_vmx.pal_init_pending ) {
+                /*inject INIT interruption to guest pal*/
+                v->arch.arch_vmx.pal_init_pending = 0;
+                deliver_pal_init(v);
+                return;
+            }
+
+            /*
+             * val[63:56] == 1: val[55:0] is a delivery PCI INTx line:
+             *                  Domain = val[47:32], Bus  = val[31:16],
+             *                  DevFn  = val[15: 8], IntX = val[ 1: 0]
+             * val[63:56] == 0: val[55:0] is a delivery as GSI
+             */
+            if (callback_irq != 0 && local_events_need_delivery()) {
+                /* change level for para-device callback irq */
+                /* use level irq to send discrete event */
+                if ((uint8_t)(callback_irq >> 56) == 1) {
+                    /* case of using PCI INTx line as callback irq */
+                    int pdev = (callback_irq >> 11) & 0x1f;
+                    int pintx = callback_irq & 3;
+                    viosapic_set_pci_irq(d, pdev, pintx, 1);
+                    viosapic_set_pci_irq(d, pdev, pintx, 0);
+                } else {
+                    /* case of using GSI as callback irq */
+                    viosapic_set_irq(d, callback_irq, 1);
+                    viosapic_set_irq(d, callback_irq, 0);
+                }
+            }
+        }
+
+        rmb();
+        if (xchg(&v->arch.irq_new_pending, 0)) {
+            v->arch.irq_new_condition = 0;
+            vmx_check_pending_irq(v);
+            return;
+        }
+
+        if (v->arch.irq_new_condition) {
+            v->arch.irq_new_condition = 0;
+            vhpi_detection(v);
+        }
+    }
+}
+
+extern ia64_rr vmx_vcpu_rr(VCPU *vcpu, u64 vadr);
+
+static int vmx_handle_lds(REGS* regs)
+{
+    regs->cr_ipsr |=IA64_PSR_ED;
+    return IA64_FAULT;
+}
+
+/* We came here because the H/W VHPT walker failed to find an entry */
+IA64FAULT
+vmx_hpw_miss(u64 vadr , u64 vec, REGS* regs)
+{
+    IA64_PSR vpsr;
+    int type;
+    u64 vhpt_adr, gppa, pteval, rr, itir;
+    ISR misr;
+    PTA vpta;
+    thash_data_t *data;
+    VCPU *v = current;
+
+    vpsr.val = VCPU(v, vpsr);
+    misr.val = VMX(v,cr_isr);
+    
+    if (vec == 1)
+        type = ISIDE_TLB;
+    else if (vec == 2)
+        type = DSIDE_TLB;
+    else
+        panic_domain(regs, "wrong vec:%lx\n", vec);
+
+    if(is_physical_mode(v)&&(!(vadr<<1>>62))){
+        if(vec==2){
+            if (misr.sp) /* Refer to SDM Vol2 Table 4-11,4-12 */
+                return vmx_handle_lds(regs);
+            if (v->domain != dom0
+                && __gpfn_is_io(v->domain, (vadr << 1) >> (PAGE_SHIFT + 1))) {
+                emulate_io_inst(v,((vadr<<1)>>1),4);   //  UC
+                return IA64_FAULT;
+            }
+        }
+        physical_tlb_miss(v, vadr, type);
+        return IA64_FAULT;
+    }
+    
+try_again:
+    if((data=vtlb_lookup(v, vadr,type))!=0){
+        if (v->domain != dom0 && type == DSIDE_TLB) {
+            if (misr.sp) { /* Refer to SDM Vol2 Table 4-10,4-12 */
+                if ((data->ma == VA_MATTR_UC) || (data->ma == VA_MATTR_UCE))
+                    return vmx_handle_lds(regs);
+            }
+            gppa = (vadr & ((1UL << data->ps) - 1)) +
+                   (data->ppn >> (data->ps - 12) << data->ps);
+            if (__gpfn_is_io(v->domain, gppa >> PAGE_SHIFT)) {
+                if (misr.sp)
+                    panic_domain(NULL, "ld.s on I/O page not with UC attr."
+                                 " pte=0x%lx\n", data->page_flags);
+                if (data->pl >= ((regs->cr_ipsr >> IA64_PSR_CPL0_BIT) & 3))
+                    emulate_io_inst(v, gppa, data->ma);
+                else {
+                    vcpu_set_isr(v, misr.val);
+                    data_access_rights(v, vadr);
+                }
+                return IA64_FAULT;
+            }
+        }
+        thash_vhpt_insert(v, data->page_flags, data->itir, vadr, type);
+
+    }else if(type == DSIDE_TLB){
+    
+        if (misr.sp)
+            return vmx_handle_lds(regs);
+
+        vcpu_get_rr(v, vadr, &rr);
+        itir = rr & (RR_RID_MASK | RR_PS_MASK);
+
+        if(!vhpt_enabled(v, vadr, misr.rs?RSE_REF:DATA_REF)){
+            if (GOS_WINDOWS(v)) {
+                /* windows use region 4 and 5 for identity mapping */
+                if (REGION_NUMBER(vadr) == 4 && !(regs->cr_ipsr & IA64_PSR_CPL)
+                    && (REGION_OFFSET(vadr)<= _PAGE_PPN_MASK)) {
+
+                    pteval = PAGEALIGN(REGION_OFFSET(vadr), itir_ps(itir)) |
+                             (_PAGE_P | _PAGE_A | _PAGE_D |
+                               _PAGE_MA_WB | _PAGE_AR_RW);
+
+                    if (thash_purge_and_insert(v, pteval, itir, vadr, type))
+                        goto try_again;
+
+                    return IA64_NO_FAULT;
+                }
+
+                if (REGION_NUMBER(vadr) == 5 && !(regs->cr_ipsr & IA64_PSR_CPL)
+                    && (REGION_OFFSET(vadr)<= _PAGE_PPN_MASK)) {
+
+                    pteval = PAGEALIGN(REGION_OFFSET(vadr),itir_ps(itir)) |
+                             (_PAGE_P | _PAGE_A | _PAGE_D |
+                              _PAGE_MA_UC | _PAGE_AR_RW);
+
+                    if (thash_purge_and_insert(v, pteval, itir, vadr, type))
+                        goto try_again;
+
+                    return IA64_NO_FAULT;
+                }
+            }
+
+            if(vpsr.ic){
+                vcpu_set_isr(v, misr.val);
+                alt_dtlb(v, vadr);
+                return IA64_FAULT;
+            } else{
+                nested_dtlb(v);
+                return IA64_FAULT;
+            }
+        }
+
+        vpta.val = vmx_vcpu_get_pta(v);
+        if (vpta.vf) {
+            /* Long format is not yet supported.  */
+            if (vpsr.ic) {
+                vcpu_set_isr(v, misr.val);
+                dtlb_fault(v, vadr);
+                return IA64_FAULT;
+            } else {
+                nested_dtlb(v);
+                return IA64_FAULT;
+            }
+        }
+
+        /* avoid recursively walking (short format) VHPT */
+        if (!GOS_WINDOWS(v) &&
+            (((vadr ^ vpta.val) << 3) >> (vpta.size + 3)) == 0) {
+
+            if (vpsr.ic) {
+                vcpu_set_isr(v, misr.val);
+                dtlb_fault(v, vadr);
+                return IA64_FAULT;
+            } else {
+                nested_dtlb(v);
+                return IA64_FAULT;
+            }
+        }
+            
+        vhpt_adr = vmx_vcpu_thash(v, vadr);
+        if (!guest_vhpt_lookup(vhpt_adr, &pteval)) {
+            /* VHPT successfully read.  */
+            if (!(pteval & _PAGE_P)) {
+                if (vpsr.ic) {
+                    vcpu_set_isr(v, misr.val);
+                    dtlb_fault(v, vadr);
+                    return IA64_FAULT;
+                } else {
+                    nested_dtlb(v);
+                    return IA64_FAULT;
+                }
+            } else if ((pteval & _PAGE_MA_MASK) != _PAGE_MA_ST) {
+                thash_purge_and_insert(v, pteval, itir, vadr, DSIDE_TLB);
+                return IA64_NO_FAULT;
+            } else if (vpsr.ic) {
+                vcpu_set_isr(v, misr.val);
+                dtlb_fault(v, vadr);
+                return IA64_FAULT;
+            }else{
+                nested_dtlb(v);
+                return IA64_FAULT;
+            }
+        } else {
+            /* Can't read VHPT.  */
+            if (vpsr.ic) {
+                vcpu_set_isr(v, misr.val);
+                dvhpt_fault(v, vadr);
+                return IA64_FAULT;
+            } else {
+                nested_dtlb(v);
+                return IA64_FAULT;
+            }
+        }
+    }else if(type == ISIDE_TLB){
+    
+        if (!vpsr.ic)
+            misr.ni = 1;
+        if (!vhpt_enabled(v, vadr, INST_REF)) {
+            vcpu_set_isr(v, misr.val);
+            alt_itlb(v, vadr);
+            return IA64_FAULT;
+        }
+
+        vpta.val = vmx_vcpu_get_pta(v);
+        if (vpta.vf) {
+            /* Long format is not yet supported.  */
+            vcpu_set_isr(v, misr.val);
+            itlb_fault(v, vadr);
+            return IA64_FAULT;
+        }
+
+
+        vhpt_adr = vmx_vcpu_thash(v, vadr);
+        if (!guest_vhpt_lookup(vhpt_adr, &pteval)) {
+            /* VHPT successfully read.  */
+            if (pteval & _PAGE_P) {
+                if ((pteval & _PAGE_MA_MASK) == _PAGE_MA_ST) {
+                    vcpu_set_isr(v, misr.val);
+                    itlb_fault(v, vadr);
+                    return IA64_FAULT;
+                }
+                vcpu_get_rr(v, vadr, &rr);
+                itir = rr & (RR_RID_MASK | RR_PS_MASK);
+                thash_purge_and_insert(v, pteval, itir, vadr, ISIDE_TLB);
+                return IA64_NO_FAULT;
+            } else {
+                vcpu_set_isr(v, misr.val);
+                inst_page_not_present(v, vadr);
+                return IA64_FAULT;
+            }
+        } else {
+            vcpu_set_isr(v, misr.val);
+            ivhpt_fault(v, vadr);
+            return IA64_FAULT;
+        }
+    }
+    return IA64_NO_FAULT;
+}
diff -r a8aeffcc06aa -r 5927f10462cd xen/arch/ia64/vmx/vmx_process.c
--- a/xen/arch/ia64/vmx/vmx_process.c   Thu Jul 05 13:17:30 2007 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,528 +0,0 @@
-/* -*-  Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */
-/*
- * vmx_process.c: handling VMX architecture-related VM exits
- * Copyright (c) 2005, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- *  Xiaoyan Feng (Fleming Feng)  <fleming.feng@xxxxxxxxx>
- *  Xuefei Xu (Anthony Xu) (Anthony.xu@xxxxxxxxx)
- */
-
-#include <xen/config.h>
-#include <xen/lib.h>
-#include <xen/errno.h>
-#include <xen/sched.h>
-#include <xen/smp.h>
-#include <asm/ptrace.h>
-#include <xen/delay.h>
-
-#include <linux/efi.h>  /* FOR EFI_UNIMPLEMENTED */
-#include <asm/sal.h>    /* FOR struct ia64_sal_retval */
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/processor.h>
-#include <asm/desc.h>
-#include <asm/vlsapic.h>
-#include <xen/irq.h>
-#include <xen/event.h>
-#include <asm/regionreg.h>
-#include <asm/privop.h>
-#include <asm/ia64_int.h>
-#include <asm/debugger.h>
-//#include <asm/hpsim_ssc.h>
-#include <asm/dom_fw.h>
-#include <asm/vmx_vcpu.h>
-#include <asm/kregs.h>
-#include <asm/vmx.h>
-#include <asm/vmmu.h>
-#include <asm/vmx_mm_def.h>
-#include <asm/vmx_phy_mode.h>
-#include <xen/mm.h>
-#include <asm/vmx_pal.h>
-/* reset all PSR field to 0, except up,mfl,mfh,pk,dt,rt,mc,it */
-#define INITIAL_PSR_VALUE_AT_INTERRUPTION 0x0000001808028034
-
-
-extern void die_if_kernel(char *str, struct pt_regs *regs, long err);
-extern void rnat_consumption (VCPU *vcpu);
-extern void alt_itlb (VCPU *vcpu, u64 vadr);
-extern void itlb_fault (VCPU *vcpu, u64 vadr);
-extern void ivhpt_fault (VCPU *vcpu, u64 vadr);
-extern unsigned long handle_fpu_swa (int fp_fault, struct pt_regs *regs, 
unsigned long isr);
-
-#define DOMN_PAL_REQUEST    0x110000
-#define DOMN_SAL_REQUEST    0x110001
-
-static u64 vec2off[68] = {0x0,0x400,0x800,0xc00,0x1000,0x1400,0x1800,
-    0x1c00,0x2000,0x2400,0x2800,0x2c00,0x3000,0x3400,0x3800,0x3c00,0x4000,
-    0x4400,0x4800,0x4c00,0x5000,0x5100,0x5200,0x5300,0x5400,0x5500,0x5600,
-    0x5700,0x5800,0x5900,0x5a00,0x5b00,0x5c00,0x5d00,0x5e00,0x5f00,0x6000,
-    0x6100,0x6200,0x6300,0x6400,0x6500,0x6600,0x6700,0x6800,0x6900,0x6a00,
-    0x6b00,0x6c00,0x6d00,0x6e00,0x6f00,0x7000,0x7100,0x7200,0x7300,0x7400,
-    0x7500,0x7600,0x7700,0x7800,0x7900,0x7a00,0x7b00,0x7c00,0x7d00,0x7e00,
-    0x7f00
-};
-
-
-
-void vmx_reflect_interruption(u64 ifa, u64 isr, u64 iim,
-                              u64 vec, REGS *regs)
-{
-    u64 status, vector;
-    VCPU *vcpu = current;
-    u64 vpsr = VCPU(vcpu, vpsr);
-    
-    vector = vec2off[vec];
-
-    switch (vec) {
-    case 5:  // IA64_DATA_NESTED_TLB_VECTOR
-        break;
-    case 22:   // IA64_INST_ACCESS_RIGHTS_VECTOR
-        if (!(vpsr & IA64_PSR_IC))
-            goto nested_fault;
-        if (vhpt_access_rights_fixup(vcpu, ifa, 0))
-            return;
-        break;
-
-    case 25:   // IA64_DISABLED_FPREG_VECTOR
-        if (!(vpsr & IA64_PSR_IC))
-            goto nested_fault;
-        if (FP_PSR(vcpu) & IA64_PSR_DFH) {
-            FP_PSR(vcpu) = IA64_PSR_MFH;
-            if (__ia64_per_cpu_var(fp_owner) != vcpu)
-                __ia64_load_fpu(vcpu->arch._thread.fph);
-        }
-        if (!(VCPU(vcpu, vpsr) & IA64_PSR_DFH)) {
-            regs->cr_ipsr &= ~IA64_PSR_DFH;
-            return;
-        }
-
-        break;       
-
-    case 32:   // IA64_FP_FAULT_VECTOR
-        if (!(vpsr & IA64_PSR_IC))
-            goto nested_fault;
-        // handle fpswa emulation
-        // fp fault
-        status = handle_fpu_swa(1, regs, isr);
-        if (!status) {
-            vcpu_increment_iip(vcpu);
-            return;
-        } else if (IA64_RETRY == status)
-            return;
-        break;
-
-    case 33:   // IA64_FP_TRAP_VECTOR
-        if (!(vpsr & IA64_PSR_IC))
-            goto nested_fault;
-        //fp trap
-        status = handle_fpu_swa(0, regs, isr);
-        if (!status)
-            return;
-        else if (IA64_RETRY == status) {
-            vcpu_decrement_iip(vcpu);
-            return;
-        }
-        break;
-
-    case 29: // IA64_DEBUG_VECTOR
-    case 35: // IA64_TAKEN_BRANCH_TRAP_VECTOR
-    case 36: // IA64_SINGLE_STEP_TRAP_VECTOR
-        if (vmx_guest_kernel_mode(regs)
-            && current->domain->debugger_attached) {
-            domain_pause_for_debugger();
-            return;
-        }
-        if (!(vpsr & IA64_PSR_IC))
-            goto nested_fault;
-        break;
-
-    default:
-        if (!(vpsr & IA64_PSR_IC))
-            goto nested_fault;
-        break;
-    } 
-    VCPU(vcpu,isr)=isr;
-    VCPU(vcpu,iipa) = regs->cr_iip;
-    if (vector == IA64_BREAK_VECTOR || vector == IA64_SPECULATION_VECTOR)
-        VCPU(vcpu,iim) = iim;
-    else {
-        set_ifa_itir_iha(vcpu,ifa,1,1,1);
-    }
-    inject_guest_interruption(vcpu, vector);
-    return;
-
- nested_fault:
-    panic_domain(regs, "Guest nested fault vector=%lx!\n", vector);
-}
-
-
-IA64FAULT
-vmx_ia64_handle_break (unsigned long ifa, struct pt_regs *regs, unsigned long 
isr, unsigned long iim)
-{
-    struct domain *d = current->domain;
-    struct vcpu *v = current;
-
-    perfc_incr(vmx_ia64_handle_break);
-#ifdef CRASH_DEBUG
-    if ((iim == 0 || iim == CDB_BREAK_NUM) && !guest_mode(regs) &&
-        IS_VMM_ADDRESS(regs->cr_iip)) {
-        if (iim == 0)
-            show_registers(regs);
-        debugger_trap_fatal(0 /* don't care */, regs);
-    } else
-#endif
-    {
-        if (iim == 0) 
-            vmx_die_if_kernel("Break 0 in Hypervisor.", regs, iim);
-
-        if (ia64_psr(regs)->cpl == 0) {
-            /* Allow hypercalls only when cpl = 0.  */
-            if (iim == d->arch.breakimm) {
-                ia64_hypercall(regs);
-                vcpu_increment_iip(v);
-                return IA64_NO_FAULT;
-            }
-            else if(iim == DOMN_PAL_REQUEST){
-                pal_emul(v);
-                vcpu_increment_iip(v);
-                return IA64_NO_FAULT;
-            }else if(iim == DOMN_SAL_REQUEST){
-                sal_emul(v);
-                vcpu_increment_iip(v);
-                return IA64_NO_FAULT;
-            }
-        }
-        vmx_reflect_interruption(ifa,isr,iim,11,regs);
-    }
-    return IA64_NO_FAULT;
-}
-
-
-void save_banked_regs_to_vpd(VCPU *v, REGS *regs)
-{
-    unsigned long i=0UL, * src,* dst, *sunat, *dunat;
-    IA64_PSR vpsr;
-    src=&regs->r16;
-    sunat=&regs->eml_unat;
-    vpsr.val = VCPU(v, vpsr);
-    if(vpsr.bn){
-        dst = &VCPU(v, vgr[0]);
-        dunat =&VCPU(v, vnat);
-        __asm__ __volatile__ (";;extr.u %0 = %1,%4,16;; \
-                            dep %2 = %0, %2, 0, 16;; \
-                            st8 [%3] = %2;;"
-       
::"r"(i),"r"(*sunat),"r"(*dunat),"r"(dunat),"i"(IA64_PT_REGS_R16_SLOT):"memory");
-
-    }else{
-        dst = &VCPU(v, vbgr[0]);
-//        dunat =&VCPU(v, vbnat);
-//        __asm__ __volatile__ (";;extr.u %0 = %1,%4,16;;
-//                            dep %2 = %0, %2, 16, 16;;
-//                            st8 [%3] = %2;;"
-//       
::"r"(i),"r"(*sunat),"r"(*dunat),"r"(dunat),"i"(IA64_PT_REGS_R16_SLOT):"memory");
-
-    }
-    for(i=0; i<16; i++)
-        *dst++ = *src++;
-}
-
-
-// ONLY gets called from ia64_leave_kernel
-// ONLY call with interrupts disabled?? (else might miss one?)
-// NEVER successful if already reflecting a trap/fault because psr.i==0
-void leave_hypervisor_tail(void)
-{
-    struct domain *d = current->domain;
-    struct vcpu *v = current;
-
-    // FIXME: Will this work properly if doing an RFI???
-    if (!is_idle_domain(d) ) { // always comes from guest
-//        struct pt_regs *user_regs = vcpu_regs(current);
-        local_irq_enable();
-        do_softirq();
-        local_irq_disable();
-
-        if (v->vcpu_id == 0) {
-            unsigned long callback_irq =
-                d->arch.hvm_domain.params[HVM_PARAM_CALLBACK_IRQ];
-
-            if ( v->arch.arch_vmx.pal_init_pending ) {
-                /*inject INIT interruption to guest pal*/
-                v->arch.arch_vmx.pal_init_pending = 0;
-                deliver_pal_init(v);
-                return;
-            }
-
-            /*
-             * val[63:56] == 1: val[55:0] is a delivery PCI INTx line:
-             *                  Domain = val[47:32], Bus  = val[31:16],
-             *                  DevFn  = val[15: 8], IntX = val[ 1: 0]
-             * val[63:56] == 0: val[55:0] is a delivery as GSI
-             */
-            if (callback_irq != 0 && local_events_need_delivery()) {
-                /* change level for para-device callback irq */
-                /* use level irq to send discrete event */
-                if ((uint8_t)(callback_irq >> 56) == 1) {
-                    /* case of using PCI INTx line as callback irq */
-                    int pdev = (callback_irq >> 11) & 0x1f;
-                    int pintx = callback_irq & 3;
-                    viosapic_set_pci_irq(d, pdev, pintx, 1);
-                    viosapic_set_pci_irq(d, pdev, pintx, 0);
-                } else {
-                    /* case of using GSI as callback irq */
-                    viosapic_set_irq(d, callback_irq, 1);
-                    viosapic_set_irq(d, callback_irq, 0);
-                }
-            }
-        }
-
-        rmb();
-        if (xchg(&v->arch.irq_new_pending, 0)) {
-            v->arch.irq_new_condition = 0;
-            vmx_check_pending_irq(v);
-            return;
-        }
-
-        if (v->arch.irq_new_condition) {
-            v->arch.irq_new_condition = 0;
-            vhpi_detection(v);
-        }
-    }
-}
-
-extern ia64_rr vmx_vcpu_rr(VCPU *vcpu, u64 vadr);
-
-static int vmx_handle_lds(REGS* regs)
-{
-    regs->cr_ipsr |=IA64_PSR_ED;
-    return IA64_FAULT;
-}
-
-/* We came here because the H/W VHPT walker failed to find an entry */
-IA64FAULT
-vmx_hpw_miss(u64 vadr , u64 vec, REGS* regs)
-{
-    IA64_PSR vpsr;
-    int type;
-    u64 vhpt_adr, gppa, pteval, rr, itir;
-    ISR misr;
-    PTA vpta;
-    thash_data_t *data;
-    VCPU *v = current;
-
-    vpsr.val = VCPU(v, vpsr);
-    misr.val = VMX(v,cr_isr);
-    
-    if (vec == 1)
-        type = ISIDE_TLB;
-    else if (vec == 2)
-        type = DSIDE_TLB;
-    else
-        panic_domain(regs, "wrong vec:%lx\n", vec);
-
-    if(is_physical_mode(v)&&(!(vadr<<1>>62))){
-        if(vec==2){
-            if (misr.sp) /* Refer to SDM Vol2 Table 4-11,4-12 */
-                return vmx_handle_lds(regs);
-            if (v->domain != dom0
-                && __gpfn_is_io(v->domain, (vadr << 1) >> (PAGE_SHIFT + 1))) {
-                emulate_io_inst(v,((vadr<<1)>>1),4);   //  UC
-                return IA64_FAULT;
-            }
-        }
-        physical_tlb_miss(v, vadr, type);
-        return IA64_FAULT;
-    }
-    
-try_again:
-    if((data=vtlb_lookup(v, vadr,type))!=0){
-        if (v->domain != dom0 && type == DSIDE_TLB) {
-            if (misr.sp) { /* Refer to SDM Vol2 Table 4-10,4-12 */
-                if ((data->ma == VA_MATTR_UC) || (data->ma == VA_MATTR_UCE))
-                    return vmx_handle_lds(regs);
-            }
-            gppa = (vadr & ((1UL << data->ps) - 1)) +
-                   (data->ppn >> (data->ps - 12) << data->ps);
-            if (__gpfn_is_io(v->domain, gppa >> PAGE_SHIFT)) {
-                if (misr.sp)
-                    panic_domain(NULL, "ld.s on I/O page not with UC attr."
-                                 " pte=0x%lx\n", data->page_flags);
-                if (data->pl >= ((regs->cr_ipsr >> IA64_PSR_CPL0_BIT) & 3))
-                    emulate_io_inst(v, gppa, data->ma);
-                else {
-                    vcpu_set_isr(v, misr.val);
-                    data_access_rights(v, vadr);
-                }
-                return IA64_FAULT;
-            }
-        }
-        thash_vhpt_insert(v, data->page_flags, data->itir, vadr, type);
-
-    }else if(type == DSIDE_TLB){
-    
-        if (misr.sp)
-            return vmx_handle_lds(regs);
-
-        vcpu_get_rr(v, vadr, &rr);
-        itir = rr & (RR_RID_MASK | RR_PS_MASK);
-
-        if(!vhpt_enabled(v, vadr, misr.rs?RSE_REF:DATA_REF)){
-            if (GOS_WINDOWS(v)) {
-                /* windows use region 4 and 5 for identity mapping */
-                if (REGION_NUMBER(vadr) == 4 && !(regs->cr_ipsr & IA64_PSR_CPL)
-                    && (REGION_OFFSET(vadr)<= _PAGE_PPN_MASK)) {
-
-                    pteval = PAGEALIGN(REGION_OFFSET(vadr), itir_ps(itir)) |
-                             (_PAGE_P | _PAGE_A | _PAGE_D |
-                               _PAGE_MA_WB | _PAGE_AR_RW);
-
-                    if (thash_purge_and_insert(v, pteval, itir, vadr, type))
-                        goto try_again;
-
-                    return IA64_NO_FAULT;
-                }
-
-                if (REGION_NUMBER(vadr) == 5 && !(regs->cr_ipsr & IA64_PSR_CPL)
-                    && (REGION_OFFSET(vadr)<= _PAGE_PPN_MASK)) {
-
-                    pteval = PAGEALIGN(REGION_OFFSET(vadr),itir_ps(itir)) |
-                             (_PAGE_P | _PAGE_A | _PAGE_D |
-                              _PAGE_MA_UC | _PAGE_AR_RW);
-
-                    if (thash_purge_and_insert(v, pteval, itir, vadr, type))
-                        goto try_again;
-
-                    return IA64_NO_FAULT;
-                }
-            }
-
-            if(vpsr.ic){
-                vcpu_set_isr(v, misr.val);
-                alt_dtlb(v, vadr);
-                return IA64_FAULT;
-            } else{
-                nested_dtlb(v);
-                return IA64_FAULT;
-            }
-        }
-
-        vpta.val = vmx_vcpu_get_pta(v);
-        if (vpta.vf) {
-            /* Long format is not yet supported.  */
-            if (vpsr.ic) {
-                vcpu_set_isr(v, misr.val);
-                dtlb_fault(v, vadr);
-                return IA64_FAULT;
-            } else {
-                nested_dtlb(v);
-                return IA64_FAULT;
-            }
-        }
-
-        /* avoid recursively walking (short format) VHPT */
-        if (!GOS_WINDOWS(v) &&
-            (((vadr ^ vpta.val) << 3) >> (vpta.size + 3)) == 0) {
-
-            if (vpsr.ic) {
-                vcpu_set_isr(v, misr.val);
-                dtlb_fault(v, vadr);
-                return IA64_FAULT;
-            } else {
-                nested_dtlb(v);
-                return IA64_FAULT;
-            }
-        }
-            
-        vhpt_adr = vmx_vcpu_thash(v, vadr);
-        if (!guest_vhpt_lookup(vhpt_adr, &pteval)) {
-            /* VHPT successfully read.  */
-            if (!(pteval & _PAGE_P)) {
-                if (vpsr.ic) {
-                    vcpu_set_isr(v, misr.val);
-                    dtlb_fault(v, vadr);
-                    return IA64_FAULT;
-                } else {
-                    nested_dtlb(v);
-                    return IA64_FAULT;
-                }
-            } else if ((pteval & _PAGE_MA_MASK) != _PAGE_MA_ST) {
-                thash_purge_and_insert(v, pteval, itir, vadr, DSIDE_TLB);
-                return IA64_NO_FAULT;
-            } else if (vpsr.ic) {
-                vcpu_set_isr(v, misr.val);
-                dtlb_fault(v, vadr);
-                return IA64_FAULT;
-            }else{
-                nested_dtlb(v);
-                return IA64_FAULT;
-            }
-        } else {
-            /* Can't read VHPT.  */
-            if (vpsr.ic) {
-                vcpu_set_isr(v, misr.val);
-                dvhpt_fault(v, vadr);
-                return IA64_FAULT;
-            } else {
-                nested_dtlb(v);
-                return IA64_FAULT;
-            }
-        }
-    }else if(type == ISIDE_TLB){
-    
-        if (!vpsr.ic)
-            misr.ni = 1;
-        if (!vhpt_enabled(v, vadr, INST_REF)) {
-            vcpu_set_isr(v, misr.val);
-            alt_itlb(v, vadr);
-            return IA64_FAULT;
-        }
-
-        vpta.val = vmx_vcpu_get_pta(v);
-        if (vpta.vf) {
-            /* Long format is not yet supported.  */
-            vcpu_set_isr(v, misr.val);
-            itlb_fault(v, vadr);
-            return IA64_FAULT;
-        }
-
-
-        vhpt_adr = vmx_vcpu_thash(v, vadr);
-        if (!guest_vhpt_lookup(vhpt_adr, &pteval)) {
-            /* VHPT successfully read.  */
-            if (pteval & _PAGE_P) {
-                if ((pteval & _PAGE_MA_MASK) == _PAGE_MA_ST) {
-                    vcpu_set_isr(v, misr.val);
-                    itlb_fault(v, vadr);
-                    return IA64_FAULT;
-                }
-                vcpu_get_rr(v, vadr, &rr);
-                itir = rr & (RR_RID_MASK | RR_PS_MASK);
-                thash_purge_and_insert(v, pteval, itir, vadr, ISIDE_TLB);
-                return IA64_NO_FAULT;
-            } else {
-                vcpu_set_isr(v, misr.val);
-                inst_page_not_present(v, vadr);
-                return IA64_FAULT;
-            }
-        } else {
-            vcpu_set_isr(v, misr.val);
-            ivhpt_fault(v, vadr);
-            return IA64_FAULT;
-        }
-    }
-    return IA64_NO_FAULT;
-}

_______________________________________________
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] [IA64] Renames vmx_process.c into vmx_fault.c, Xen patchbot-unstable <=