ia64/xen-unstable

changeset 9680:633e8bbabf76

[IA64] vmx_ia64_handle_break

vmx_ia64_handle_break: do hypercall only when cpl = 0.

Signed-off-by: Tristan Gingold <tristan.gingold@bull.net>
author awilliam@xenbuild.aw
date Thu Apr 13 14:42:43 2006 -0600 (2006-04-13)
parents 6e3841e5ef8f
children 99e1c7f276ea
files xen/arch/ia64/vmx/vmx_process.c
line diff
     1.1 --- a/xen/arch/ia64/vmx/vmx_process.c	Thu Apr 13 14:08:30 2006 -0600
     1.2 +++ b/xen/arch/ia64/vmx/vmx_process.c	Thu Apr 13 14:42:43 2006 -0600
     1.3 @@ -82,12 +82,12 @@ void vmx_reflect_interruption(UINT64 ifa
     1.4  {
     1.5      VCPU *vcpu = current;
     1.6      UINT64 vpsr = vmx_vcpu_get_psr(vcpu);
     1.7 -    if(!(vpsr&IA64_PSR_IC)&&(vector!=5)){
     1.8 -        panic("Guest nested fault!");
     1.9 +    vector=vec2off[vector];
    1.10 +    if(!(vpsr&IA64_PSR_IC)&&(vector!=0x1400)){
    1.11 +        panic_domain(regs, "Guest nested fault vector=%lx!\n", vector);
    1.12      }
    1.13      VCPU(vcpu,isr)=isr;
    1.14      VCPU(vcpu,iipa) = regs->cr_iip;
    1.15 -    vector=vec2off[vector];
    1.16      if (vector == IA64_BREAK_VECTOR || vector == IA64_SPECULATION_VECTOR)
    1.17          VCPU(vcpu,iim) = iim;
    1.18      else {
    1.19 @@ -96,24 +96,92 @@ void vmx_reflect_interruption(UINT64 ifa
    1.20      inject_guest_interruption(vcpu, vector);
    1.21  }
    1.22  
    1.23 +static void
    1.24 +vmx_handle_hypercall (VCPU *v, REGS *regs)
    1.25 +{
    1.26 +    struct ia64_pal_retval y;
    1.27 +    struct sal_ret_values x;
    1.28 +    unsigned long i, sal_param[8];
    1.29 +
    1.30 +    switch (regs->r2) {
    1.31 +        case FW_HYPERCALL_PAL_CALL:
    1.32 +            //printf("*** PAL hypercall: index=%d\n",regs->r28);
    1.33 +            //FIXME: This should call a C routine
    1.34 +            y = pal_emulator_static(VCPU(v, vgr[12]));
    1.35 +            regs->r8 = y.status; regs->r9 = y.v0;
    1.36 +            regs->r10 = y.v1; regs->r11 = y.v2;
    1.37 +#if 0
    1.38 +            if (regs->r8)
    1.39 +                printk("Failed vpal emulation, with index:0x%lx\n",
    1.40 +                       VCPU(v, vgr[12]));
    1.41 +#endif
    1.42 +            break;
    1.43 +        case FW_HYPERCALL_SAL_CALL:
    1.44 +            for (i = 0; i < 8; i++)
    1.45 +                vcpu_get_gr_nat(v, 32+i, &sal_param[i]);
    1.46 +            x = sal_emulator(sal_param[0], sal_param[1],
    1.47 +                             sal_param[2], sal_param[3],
    1.48 +                             sal_param[4], sal_param[5],
    1.49 +                             sal_param[6], sal_param[7]);
    1.50 +            regs->r8 = x.r8; regs->r9 = x.r9;
    1.51 +            regs->r10 = x.r10; regs->r11 = x.r11;
    1.52 +#if 0
    1.53 +            if (regs->r8)
    1.54 +                printk("Failed vsal emulation, with index:0x%lx\n",
    1.55 +                       sal_param[0]);
    1.56 +#endif
    1.57 +            break;
    1.58 +        case FW_HYPERCALL_EFI_RESET_SYSTEM:
    1.59 +            printf("efi.reset_system called ");
    1.60 +            if (current->domain == dom0) {
    1.61 +                printf("(by dom0)\n ");
    1.62 +                (*efi.reset_system)(EFI_RESET_WARM,0,0,NULL);
    1.63 +            }
    1.64 +            printf("(not supported for non-0 domain)\n");
    1.65 +            regs->r8 = EFI_UNSUPPORTED;
    1.66 +            break;
    1.67 +        case FW_HYPERCALL_EFI_GET_TIME:
    1.68 +            {
    1.69 +                unsigned long *tv, *tc;
    1.70 +                vcpu_get_gr_nat(v, 32, (u64 *)&tv);
    1.71 +                vcpu_get_gr_nat(v, 33, (u64 *)&tc);
    1.72 +                printf("efi_get_time(%p,%p) called...",tv,tc);
    1.73 +                tv = __va(translate_domain_mpaddr((unsigned long)tv));
    1.74 +                if (tc) tc = __va(translate_domain_mpaddr((unsigned long)tc));
    1.75 +                regs->r8 = (*efi.get_time)((efi_time_t *)tv,(efi_time_cap_t *)tc);
    1.76 +                printf("and returns %lx\n",regs->r8);
    1.77 +            }
    1.78 +            break;
    1.79 +        case FW_HYPERCALL_EFI_SET_TIME:
    1.80 +        case FW_HYPERCALL_EFI_GET_WAKEUP_TIME:
    1.81 +        case FW_HYPERCALL_EFI_SET_WAKEUP_TIME:
    1.82 +            // FIXME: need fixes in efi.h from 2.6.9
    1.83 +        case FW_HYPERCALL_EFI_SET_VIRTUAL_ADDRESS_MAP:
    1.84 +            // FIXME: WARNING!! IF THIS EVER GETS IMPLEMENTED
    1.85 +            // SOME OF THE OTHER EFI EMULATIONS WILL CHANGE AS
    1.86 +            // POINTER ARGUMENTS WILL BE VIRTUAL!!
    1.87 +        case FW_HYPERCALL_EFI_GET_VARIABLE:
    1.88 +            // FIXME: need fixes in efi.h from 2.6.9
    1.89 +        case FW_HYPERCALL_EFI_GET_NEXT_VARIABLE:
    1.90 +        case FW_HYPERCALL_EFI_SET_VARIABLE:
    1.91 +        case FW_HYPERCALL_EFI_GET_NEXT_HIGH_MONO_COUNT:
    1.92 +            // FIXME: need fixes in efi.h from 2.6.9
    1.93 +            regs->r8 = EFI_UNSUPPORTED;
    1.94 +            break;
    1.95 +    }
    1.96 +#if 0
    1.97 +    if (regs->r8)
    1.98 +        printk("Failed vgfw emulation, with index:0x%lx\n",
    1.99 +               regs->r2);
   1.100 +#endif
   1.101 +}
   1.102 +
   1.103  IA64FAULT
   1.104  vmx_ia64_handle_break (unsigned long ifa, struct pt_regs *regs, unsigned long isr, unsigned long iim)
   1.105  {
   1.106 -	struct domain *d = (struct domain *) current->domain;
   1.107 -	struct vcpu *v = (struct vcpu *) current;
   1.108 -	unsigned long i, sal_param[8];
   1.109 +    struct domain *d = current->domain;
   1.110 +    struct vcpu *v = current;
   1.111  
   1.112 -#if 0
   1.113 -	if (first_time) {
   1.114 -		if (platform_is_hp_ski()) running_on_sim = 1;
   1.115 -		else running_on_sim = 0;
   1.116 -		first_time = 0;
   1.117 -	}
   1.118 -	if (iim == 0x80001 || iim == 0x80002) {	//FIXME: don't hardcode constant
   1.119 -		if (running_on_sim) do_ssc(vcpu_get_gr_nat(current,36), regs);
   1.120 -		else do_ssc(vcpu_get_gr_nat(current,36), regs);
   1.121 -	}
   1.122 -#endif
   1.123  #ifdef CRASH_DEBUG
   1.124  	if ((iim == 0 || iim == CDB_BREAK_NUM) && !user_mode(regs) &&
   1.125          IS_VMM_ADDRESS(regs->cr_iip)) {
   1.126 @@ -122,88 +190,24 @@ vmx_ia64_handle_break (unsigned long ifa
   1.127  		debugger_trap_fatal(0 /* don't care */, regs);
   1.128  	} else
   1.129  #endif
   1.130 -	if (iim == d->arch.breakimm) {
   1.131 -		struct ia64_pal_retval y;
   1.132 -		struct sal_ret_values x;
   1.133 -		switch (regs->r2) {
   1.134 -		    case FW_HYPERCALL_PAL_CALL:
   1.135 -			//printf("*** PAL hypercall: index=%d\n",regs->r28);
   1.136 -			//FIXME: This should call a C routine
   1.137 -			y = pal_emulator_static(VCPU(v, vgr[12]));
   1.138 -			regs->r8 = y.status; regs->r9 = y.v0;
   1.139 -			regs->r10 = y.v1; regs->r11 = y.v2;
   1.140 -#if 0
   1.141 -			if (regs->r8)
   1.142 -				printk("Failed vpal emulation, with index:0x%lx\n",
   1.143 -					VCPU(v, vgr[12]));
   1.144 -#endif
   1.145 -			break;
   1.146 -		    case FW_HYPERCALL_SAL_CALL:
   1.147 -			for (i = 0; i < 8; i++)
   1.148 -				vcpu_get_gr_nat(v, 32+i, &sal_param[i]);
   1.149 -			x = sal_emulator(sal_param[0], sal_param[1],
   1.150 -					 sal_param[2], sal_param[3],
   1.151 -					 sal_param[4], sal_param[5],
   1.152 -					 sal_param[6], sal_param[7]);
   1.153 -			regs->r8 = x.r8; regs->r9 = x.r9;
   1.154 -			regs->r10 = x.r10; regs->r11 = x.r11;
   1.155 -#if 0
   1.156 -			if (regs->r8)
   1.157 -				printk("Failed vsal emulation, with index:0x%lx\n",
   1.158 -					sal_param[0]);
   1.159 -#endif
   1.160 -			break;
   1.161 -		    case FW_HYPERCALL_EFI_RESET_SYSTEM:
   1.162 -			printf("efi.reset_system called ");
   1.163 -			if (current->domain == dom0) {
   1.164 -				printf("(by dom0)\n ");
   1.165 -				(*efi.reset_system)(EFI_RESET_WARM,0,0,NULL);
   1.166 -			}
   1.167 -			printf("(not supported for non-0 domain)\n");
   1.168 -			regs->r8 = EFI_UNSUPPORTED;
   1.169 -			break;
   1.170 -		    case FW_HYPERCALL_EFI_GET_TIME:
   1.171 -			{
   1.172 -			unsigned long *tv, *tc;
   1.173 -			vcpu_get_gr_nat(v, 32, (u64 *)&tv);
   1.174 -			vcpu_get_gr_nat(v, 33, (u64 *)&tc);
   1.175 -			printf("efi_get_time(%p,%p) called...",tv,tc);
   1.176 -			tv = __va(translate_domain_mpaddr((unsigned long)tv));
   1.177 -			if (tc) tc = __va(translate_domain_mpaddr((unsigned long)tc));
   1.178 -			regs->r8 = (*efi.get_time)((efi_time_t *)tv,(efi_time_cap_t *)tc);
   1.179 -			printf("and returns %lx\n",regs->r8);
   1.180 -			}
   1.181 -			break;
   1.182 -		    case FW_HYPERCALL_EFI_SET_TIME:
   1.183 -		    case FW_HYPERCALL_EFI_GET_WAKEUP_TIME:
   1.184 -		    case FW_HYPERCALL_EFI_SET_WAKEUP_TIME:
   1.185 -			// FIXME: need fixes in efi.h from 2.6.9
   1.186 -		    case FW_HYPERCALL_EFI_SET_VIRTUAL_ADDRESS_MAP:
   1.187 -			// FIXME: WARNING!! IF THIS EVER GETS IMPLEMENTED
   1.188 -			// SOME OF THE OTHER EFI EMULATIONS WILL CHANGE AS
   1.189 -			// POINTER ARGUMENTS WILL BE VIRTUAL!!
   1.190 -		    case FW_HYPERCALL_EFI_GET_VARIABLE:
   1.191 -			// FIXME: need fixes in efi.h from 2.6.9
   1.192 -		    case FW_HYPERCALL_EFI_GET_NEXT_VARIABLE:
   1.193 -		    case FW_HYPERCALL_EFI_SET_VARIABLE:
   1.194 -		    case FW_HYPERCALL_EFI_GET_NEXT_HIGH_MONO_COUNT:
   1.195 -			// FIXME: need fixes in efi.h from 2.6.9
   1.196 -			regs->r8 = EFI_UNSUPPORTED;
   1.197 -			break;
   1.198 -		}
   1.199 -#if 0
   1.200 -		if (regs->r8)
   1.201 -			printk("Failed vgfw emulation, with index:0x%lx\n",
   1.202 -				regs->r2);
   1.203 -#endif
   1.204 -		vmx_vcpu_increment_iip(current);
   1.205 -	}else if(iim == DOMN_PAL_REQUEST){
   1.206 -        pal_emul(current);
   1.207 -		vmx_vcpu_increment_iip(current);
   1.208 -    } else {
   1.209 -		if (iim == 0) 
   1.210 -			die_if_kernel("bug check", regs, iim);
   1.211 -		vmx_reflect_interruption(ifa,isr,iim,11,regs);
   1.212 +    {
   1.213 +        if (iim == 0) 
   1.214 +            die_if_kernel("bug check", regs, iim);
   1.215 +
   1.216 +        if (!user_mode(regs)) {
   1.217 +            /* Allow hypercalls only when cpl = 0.  */
   1.218 +            if (iim == d->arch.breakimm) {
   1.219 +                vmx_handle_hypercall (v ,regs);
   1.220 +                vmx_vcpu_increment_iip(current);
   1.221 +                return IA64_NO_FAULT;
   1.222 +            }
   1.223 +            else if(iim == DOMN_PAL_REQUEST){
   1.224 +                pal_emul(current);
   1.225 +                vmx_vcpu_increment_iip(current);
   1.226 +                return IA64_NO_FAULT;
   1.227 +            }
   1.228 +        }
   1.229 +        vmx_reflect_interruption(ifa,isr,iim,11,regs);
   1.230      }
   1.231      return IA64_NO_FAULT;
   1.232  }