ia64/xen-unstable

changeset 18873:a86a4ddd8b2b

IA64: fix emulation of fp emulation in pv domain

This patch is a part of fixes to bug reported as
http://bugzilla.xensource.com/bugzilla/show_bug.cgi?id=1392

When vmm fails to get a bundle in a question during fpswa processing,
there is no way, but a guest provides the bundle.
On the other hand the current implementation just returns random value.
This patch make the fpswa hypercall calling convention complicated and
pass necessary informations to the hypervisor.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author Isaku Yamahata <yamahata@valinux.co.jp>
date Fri Dec 12 10:29:15 2008 +0900 (2008-12-12)
parents 3acca92b9597
children 9e0f8f78d37a
files xen/arch/ia64/vmx/vmx_fault.c xen/arch/ia64/xen/dom_fw_common.c xen/arch/ia64/xen/faults.c xen/arch/ia64/xen/hypercall.c xen/include/asm-ia64/bundle.h xen/include/asm-ia64/dom_fw.h xen/include/asm-ia64/domain.h xen/include/asm-ia64/vmx.h
line diff
     1.1 --- a/xen/arch/ia64/vmx/vmx_fault.c	Wed Dec 10 15:39:47 2008 +0900
     1.2 +++ b/xen/arch/ia64/vmx/vmx_fault.c	Fri Dec 12 10:29:15 2008 +0900
     1.3 @@ -74,7 +74,14 @@ static const u16 vec2off[68] = {0x0,0x40
     1.4      0x7f00
     1.5  };
     1.6  
     1.7 -
     1.8 +void vmx_lazy_load_fpu(struct vcpu *vcpu)
     1.9 +{
    1.10 +    if (FP_PSR(vcpu) & IA64_PSR_DFH) {
    1.11 +        FP_PSR(vcpu) = IA64_PSR_MFH;
    1.12 +        if (__ia64_per_cpu_var(fp_owner) != vcpu)
    1.13 +            __ia64_load_fpu(vcpu->arch._thread.fph);
    1.14 +    }
    1.15 +}
    1.16  
    1.17  void vmx_reflect_interruption(u64 ifa, u64 isr, u64 iim,
    1.18                                u64 vec, REGS *regs)
    1.19 @@ -98,11 +105,7 @@ void vmx_reflect_interruption(u64 ifa, u
    1.20      case 25:	// IA64_DISABLED_FPREG_VECTOR
    1.21          if (!(vpsr & IA64_PSR_IC))
    1.22              goto nested_fault;
    1.23 -        if (FP_PSR(vcpu) & IA64_PSR_DFH) {
    1.24 -            FP_PSR(vcpu) = IA64_PSR_MFH;
    1.25 -            if (__ia64_per_cpu_var(fp_owner) != vcpu)
    1.26 -                __ia64_load_fpu(vcpu->arch._thread.fph);
    1.27 -        }
    1.28 +        vmx_lazy_load_fpu(vcpu);
    1.29          if (!(VCPU(vcpu, vpsr) & IA64_PSR_DFH)) {
    1.30              regs->cr_ipsr &= ~IA64_PSR_DFH;
    1.31              return;
     2.1 --- a/xen/arch/ia64/xen/dom_fw_common.c	Wed Dec 10 15:39:47 2008 +0900
     2.2 +++ b/xen/arch/ia64/xen/dom_fw_common.c	Fri Dec 12 10:29:15 2008 +0900
     2.3 @@ -142,6 +142,117 @@ build_pal_hypercall_bundles(uint64_t *im
     2.4  	ia64_fc(imva + 3);
     2.5  }
     2.6  
     2.7 +/* xen fpswa call stub. 14 bundles */
     2.8 +extern const unsigned long xen_ia64_fpswa_call_stub[];
     2.9 +extern const unsigned long xen_ia64_fpswa_call_stub_end[];
    2.10 +extern const unsigned long xen_ia64_fpswa_call_stub_patch[];
    2.11 +asm(
    2.12 +	".align 32\n"
    2.13 +	".proc xen_ia64_fpswa_call_stub;\n"
    2.14 +	"xen_ia64_fpswa_call_stub:\n"
    2.15 +	".prologue\n"
    2.16 +	"alloc r3 = ar.pfs, 8, 0, 0, 0\n"
    2.17 +	".body\n"
    2.18 +	"mov r14 = in0\n"
    2.19 +	"ld8 r15 = [in1], 8\n"
    2.20 +	";;\n"
    2.21 +	"ld8 r16 = [in1]\n"
    2.22 +	"ld8 r17 = [in2]\n"
    2.23 +	"ld8 r18 = [in3]\n"
    2.24 +	"ld8 r19 = [in4]\n"
    2.25 +	"ld8 r20 = [in5]\n"
    2.26 +	"ld8 r21 = [in6]\n"
    2.27 +	"ld8 r22 = [in7], 8\n"
    2.28 +	";;\n"
    2.29 +	"ld8 r23 = [in7], 8\n"
    2.30 +	";;\n"
    2.31 +	"ld8 r24 = [in7], 8\n"
    2.32 +	";;\n"
    2.33 +	"cmp.ne p6, p0 = r24, r0\n"
    2.34 +	"ld8 r25 = [in7], 8\n"
    2.35 +	";;\n"
    2.36 +	"(p6) tpa r24 = r24\n"
    2.37 +	"cmp.ne p7, p0 = r25, r0\n"
    2.38 +	"ld8 r26 = [in7], 8\n"
    2.39 +	";;\n"
    2.40 +	"(p7)tpa r25 = r25\n"
    2.41 +	"cmp.ne p8, p0 = r26, r0\n"
    2.42 +	"ld8 r27 = [in7], 8\n"
    2.43 +	";;\n"
    2.44 +	"(p8)tpa r26 = r26\n"
    2.45 +	"cmp.ne p9, p0 = r27, r0\n"
    2.46 +	";;\n"
    2.47 +	"tpa r27 = r27\n"
    2.48 +	"xen_ia64_fpswa_call_stub_patch:"
    2.49 +	"{\n"
    2.50 +	"mov r2 = " FW_HYPERCALL_FPSWA_STR "\n"
    2.51 +	"break " __IA64_XEN_HYPERCALL_DEFAULT_STR "\n"
    2.52 +	"nop.i 0\n"
    2.53 +	"}\n"
    2.54 +	"st8 [in2] = r17\n"
    2.55 +	"st8 [in3] = r18\n"
    2.56 +	"st8 [in4] = r19\n"
    2.57 +	"st8 [in5] = r20\n"
    2.58 +	"st8 [in6] = r21\n"
    2.59 +	"br.ret.sptk.many rp\n"
    2.60 +	"xen_ia64_fpswa_call_stub_end:"
    2.61 +	".endp xen_ia64_fpswa_call_stub\n"
    2.62 +);
    2.63 +
    2.64 +static void
    2.65 +build_fpswa_hypercall_bundle(uint64_t *imva, uint64_t brkimm, uint64_t hypnum)
    2.66 +{
    2.67 +	INST64_A5 slot0;
    2.68 +	INST64_I19 slot1;
    2.69 +	INST64_I18 slot2;
    2.70 +	IA64_BUNDLE bundle;
    2.71 +
    2.72 +	/* slot0: mov r2 = hypnum (low 20 bits) */
    2.73 +	slot0.inst = 0;
    2.74 +	slot0.qp = 0;
    2.75 +	slot0.r1 = 2;
    2.76 +	slot0.r3 = 0;
    2.77 +	slot0.major = 0x9;
    2.78 +
    2.79 +	slot0.s = 0;
    2.80 +	slot0.imm9d = hypnum >> 7;
    2.81 +	slot0.imm5c = hypnum >> 16;
    2.82 +	slot0.imm7b = hypnum;
    2.83 +
    2.84 +	/* slot1: break brkimm */
    2.85 +	slot1.inst = 0;
    2.86 +	slot1.qp = 0;
    2.87 +	slot1.x6 = 0;
    2.88 +	slot1.x3 = 0;
    2.89 +	slot1.major = 0x0;
    2.90 +	slot1.i = brkimm >> 20;
    2.91 +	slot1.imm20 = brkimm;
    2.92 +
    2.93 +	/* slot2: nop.i */
    2.94 +	slot2.inst = 0;
    2.95 +	slot2.qp = 0;
    2.96 +	slot2.imm20 = 0;
    2.97 +	slot2.y = 0;
    2.98 +	slot2.x6 = 1;
    2.99 +	slot2.x3 = 0;
   2.100 +	slot2.i = 0;
   2.101 +	slot2.major = 0;
   2.102 +
   2.103 +	/* MII bundle */
   2.104 +	bundle.i64[0] = 0;
   2.105 +	bundle.i64[1] = 0;
   2.106 +	bundle.template = 0x0; /* MII */
   2.107 +	bundle.slot0 = slot0.inst;
   2.108 +	bundle.slot1a = slot1.inst;
   2.109 +	bundle.slot1b = slot1.inst >> 18;
   2.110 +	bundle.slot2 = slot2.inst;
   2.111 +	
   2.112 +	imva[0] = bundle.i64[0];
   2.113 +	imva[1] = bundle.i64[1];
   2.114 +	ia64_fc(imva);
   2.115 +	ia64_fc(imva + 1);
   2.116 +}
   2.117 +
   2.118  // builds a hypercall bundle at domain physical address
   2.119  static void
   2.120  dom_fpswa_hypercall_patch(uint64_t brkimm, unsigned long imva)
   2.121 @@ -149,6 +260,10 @@ dom_fpswa_hypercall_patch(uint64_t brkim
   2.122  	unsigned long *entry_imva, *patch_imva;
   2.123  	const unsigned long entry_paddr = FW_HYPERCALL_FPSWA_ENTRY_PADDR;
   2.124  	const unsigned long patch_paddr = FW_HYPERCALL_FPSWA_PATCH_PADDR;
   2.125 +	const size_t stub_size =
   2.126 +		(char*)xen_ia64_fpswa_call_stub_end -
   2.127 +		(char*)xen_ia64_fpswa_call_stub;
   2.128 +	size_t i;
   2.129  
   2.130  	entry_imva = (unsigned long *)(imva + entry_paddr -
   2.131  	                               FW_HYPERCALL_BASE_PADDR);
   2.132 @@ -159,7 +274,17 @@ dom_fpswa_hypercall_patch(uint64_t brkim
   2.133  	*entry_imva++ = patch_paddr;
   2.134  	*entry_imva   = 0;
   2.135  
   2.136 -	build_hypercall_bundle(patch_imva, brkimm, FW_HYPERCALL_FPSWA, 1);
   2.137 +	/* see dom_fw.h */
   2.138 +	BUILD_BUG_ON((char*)xen_ia64_fpswa_call_stub_end -
   2.139 +		     (char*)xen_ia64_fpswa_call_stub > 0xff - 16);
   2.140 +
   2.141 +	/* call stub */
   2.142 +	memcpy(patch_imva, xen_ia64_fpswa_call_stub, stub_size);
   2.143 +	for (i = 0; i < stub_size; i++)
   2.144 +		ia64_fc(imva + i);
   2.145 +	patch_imva +=
   2.146 +		xen_ia64_fpswa_call_stub_patch - xen_ia64_fpswa_call_stub;
   2.147 +	build_fpswa_hypercall_bundle(patch_imva, brkimm, FW_HYPERCALL_FPSWA);
   2.148  }
   2.149  
   2.150  // builds a hypercall bundle at domain physical address
     3.1 --- a/xen/arch/ia64/xen/faults.c	Wed Dec 10 15:39:47 2008 +0900
     3.2 +++ b/xen/arch/ia64/xen/faults.c	Fri Dec 12 10:29:15 2008 +0900
     3.3 @@ -570,6 +570,17 @@ ia64_handle_privop(unsigned long ifa, st
     3.4  }
     3.5  
     3.6  void
     3.7 +ia64_lazy_load_fpu(struct vcpu *v)
     3.8 +{
     3.9 +	if (PSCB(v, hpsr_dfh)) {
    3.10 +		PSCB(v, hpsr_dfh) = 0;
    3.11 +		PSCB(v, hpsr_mfh) = 1;
    3.12 +		if (__ia64_per_cpu_var(fp_owner) != v)
    3.13 +			__ia64_load_fpu(v->arch._thread.fph);
    3.14 +	}
    3.15 +}
    3.16 +
    3.17 +void
    3.18  ia64_handle_reflection(unsigned long ifa, struct pt_regs *regs,
    3.19                         unsigned long isr, unsigned long iim,
    3.20                         unsigned long vector)
    3.21 @@ -617,12 +628,7 @@ ia64_handle_reflection(unsigned long ifa
    3.22  		vector = IA64_GENEX_VECTOR;
    3.23  		break;
    3.24  	case 25:
    3.25 -		if (PSCB(v, hpsr_dfh)) {
    3.26 -			PSCB(v, hpsr_dfh) = 0;
    3.27 -			PSCB(v, hpsr_mfh) = 1;
    3.28 -			if (__ia64_per_cpu_var(fp_owner) != v)
    3.29 -				__ia64_load_fpu(v->arch._thread.fph);
    3.30 -		}
    3.31 +		ia64_lazy_load_fpu(v);
    3.32  		if (!PSCB(v, vpsr_dfh)) {
    3.33  			regs->cr_ipsr &= ~IA64_PSR_DFH;
    3.34  			return;
     4.1 --- a/xen/arch/ia64/xen/hypercall.c	Wed Dec 10 15:39:47 2008 +0900
     4.2 +++ b/xen/arch/ia64/xen/hypercall.c	Fri Dec 12 10:29:15 2008 +0900
     4.3 @@ -118,10 +118,128 @@ fw_hypercall_ipi (struct pt_regs *regs)
     4.4  	return;
     4.5  }
     4.6  
     4.7 +static int
     4.8 +fpswa_get_domain_addr(struct vcpu *v, unsigned long gpaddr, size_t size,
     4.9 +		      void **virt, struct page_info **page, const char *name)
    4.10 +{
    4.11 +	int cross_page_boundary;
    4.12 +
    4.13 +	if (gpaddr == 0) {
    4.14 +		*virt = 0;
    4.15 +		return 0;
    4.16 +	}
    4.17 +
    4.18 +	cross_page_boundary = (((gpaddr & ~PAGE_MASK) + size) > PAGE_SIZE);
    4.19 +	if (unlikely(cross_page_boundary)) {
    4.20 +		/* this case isn't implemented */
    4.21 +		gdprintk(XENLOG_ERR,
    4.22 +			 "%s: fpswa hypercall is called with "
    4.23 +			 "page crossing argument %s 0x%lx\n",
    4.24 +			 __func__, name, gpaddr);
    4.25 +		return -ENOSYS;
    4.26 +	}
    4.27 +
    4.28 +again:
    4.29 +        *virt = domain_mpa_to_imva(v->domain, gpaddr);
    4.30 +        *page = virt_to_page(*virt);
    4.31 +        if (get_page(*page, current->domain) == 0) {
    4.32 +                if (page_get_owner(*page) != current->domain) {
    4.33 +			*page = NULL;
    4.34 +			return -EFAULT;
    4.35 +		}
    4.36 +                goto again;
    4.37 +        }
    4.38 +
    4.39 +	return 0;
    4.40 +}
    4.41 +
    4.42  static fpswa_ret_t
    4.43 -fw_hypercall_fpswa (struct vcpu *v)
    4.44 +fw_hypercall_fpswa (struct vcpu *v, struct pt_regs *regs)
    4.45  {
    4.46 -	return PSCBX(v, fpswa_ret);
    4.47 +	fpswa_ret_t ret = {-1, 0, 0, 0};
    4.48 +	unsigned long bundle[2] = { regs->r15, regs->r16};
    4.49 +	fp_state_t fp_state;
    4.50 +	struct page_info *lp_page = NULL;
    4.51 +	struct page_info *lv_page = NULL;
    4.52 +	struct page_info *hp_page = NULL;
    4.53 +	struct page_info *hv_page = NULL;
    4.54 +	XEN_EFI_RR_DECLARE(rr6, rr7);
    4.55 +
    4.56 +	if (!fpswa_interface)
    4.57 +		goto error;
    4.58 +
    4.59 +	memset(&fp_state, 0, sizeof(fp_state));
    4.60 +	fp_state.bitmask_low64 = regs->r22;
    4.61 +	fp_state.bitmask_high64 = regs->r23;
    4.62 +
    4.63 +	/* bit6..bit11 */
    4.64 +	if ((fp_state.bitmask_low64 & 0xfc0) != 0xfc0) {
    4.65 +		/* other cases isn't supported yet */
    4.66 +		gdprintk(XENLOG_ERR, "%s unsupported bitmask_low64 0x%lx\n",
    4.67 +			 __func__, fp_state.bitmask_low64);
    4.68 +		goto error;
    4.69 +	}
    4.70 +	if (regs->r25 == 0)
    4.71 +		/* fp_state.fp_state_low_volatile must be supplied */
    4.72 +		goto error;
    4.73 +
    4.74 +	/* eager save/lazy restore fpu: f32...f127 */
    4.75 +	if ((~fp_state.bitmask_low64 & ((1UL << 31) - 1)) != 0 ||
    4.76 +	    ~fp_state.bitmask_high64 != 0) {
    4.77 +		if (VMX_DOMAIN(v))
    4.78 +			vmx_lazy_load_fpu(v);
    4.79 +		else
    4.80 +			ia64_lazy_load_fpu(v);
    4.81 +	}
    4.82 +
    4.83 +	if (fpswa_get_domain_addr(v, regs->r24,
    4.84 +				  sizeof(fp_state.fp_state_low_preserved), 
    4.85 +				  (void*)&fp_state.fp_state_low_preserved,
    4.86 +				  &lp_page, "fp_state_low_preserved") < 0)
    4.87 +		goto error;
    4.88 +	if (fpswa_get_domain_addr(v, regs->r25,
    4.89 +				  sizeof(fp_state.fp_state_low_volatile),
    4.90 +				  (void*)&fp_state.fp_state_low_volatile,
    4.91 +				  &lv_page, "fp_state_low_volatile") < 0)
    4.92 +		goto error;
    4.93 +	if (fpswa_get_domain_addr(v, regs->r26,
    4.94 +				  sizeof(fp_state.fp_state_high_preserved),
    4.95 +				  (void*)&fp_state.fp_state_high_preserved,
    4.96 +				  &hp_page, "fp_state_low_preserved") < 0)
    4.97 +		goto error;
    4.98 +	if (fpswa_get_domain_addr(v, regs->r27,
    4.99 +				  sizeof(fp_state.fp_state_high_volatile),
   4.100 +				  (void*)&fp_state.fp_state_high_volatile,
   4.101 +				  &hv_page, "fp_state_high_volatile") < 0)
   4.102 +		goto error;
   4.103 +
   4.104 +	XEN_EFI_RR_ENTER(rr6, rr7);
   4.105 +	ret = (*fpswa_interface->fpswa)(regs->r14,
   4.106 +					bundle,
   4.107 +					&regs->r17,	/* pipsr */
   4.108 +					&regs->r18,	/* pfsr */
   4.109 +					&regs->r19,	/* pisr */
   4.110 +					&regs->r20,	/* ppreds */
   4.111 +					&regs->r21,	/* pifs	*/
   4.112 +					&fp_state);
   4.113 +	XEN_EFI_RR_LEAVE(rr6, rr7);
   4.114 +
   4.115 +error:
   4.116 +	if (lp_page != NULL)
   4.117 +		put_page(lp_page);
   4.118 +	if (lv_page != NULL)
   4.119 +		put_page(lv_page);
   4.120 +	if (hp_page != NULL)
   4.121 +		put_page(hp_page);
   4.122 +	if (hv_page != NULL)
   4.123 +		put_page(hv_page);
   4.124 +	return ret;
   4.125 +}
   4.126 +
   4.127 +static fpswa_ret_t
   4.128 +fw_hypercall_fpswa_error(void)
   4.129 +{
   4.130 +	return (fpswa_ret_t) {-1, 0, 0, 0};
   4.131  }
   4.132  
   4.133  IA64FAULT
   4.134 @@ -226,8 +344,24 @@ ia64_hypercall(struct pt_regs *regs)
   4.135  	case FW_HYPERCALL_SET_SHARED_INFO_VA:
   4.136  	        regs->r8 = domain_set_shared_info_va (regs->r28);
   4.137  		break;
   4.138 -	case FW_HYPERCALL_FPSWA:
   4.139 -		fpswa_ret = fw_hypercall_fpswa (v);
   4.140 +	case FW_HYPERCALL_FPSWA_BASE:
   4.141 +		switch (regs->r2) {
   4.142 +		case FW_HYPERCALL_FPSWA_BROKEN:
   4.143 +			gdprintk(XENLOG_WARNING,
   4.144 +				 "Old fpswa hypercall was called (0x%lx).\n"
   4.145 +				 "Please update your domain builder. ip 0x%lx\n",
   4.146 +				 FW_HYPERCALL_FPSWA_BROKEN, regs->cr_iip);
   4.147 +			fpswa_ret = fw_hypercall_fpswa_error();
   4.148 +			break;
   4.149 +		case FW_HYPERCALL_FPSWA:
   4.150 +			fpswa_ret = fw_hypercall_fpswa(v, regs);
   4.151 +			break;
   4.152 +		default:
   4.153 +			gdprintk(XENLOG_ERR, "unknown fpswa hypercall %lx\n",
   4.154 +				 regs->r2);
   4.155 +			fpswa_ret = fw_hypercall_fpswa_error();
   4.156 +			break;
   4.157 +		}
   4.158  		regs->r8  = fpswa_ret.status;
   4.159  		regs->r9  = fpswa_ret.err0;
   4.160  		regs->r10 = fpswa_ret.err1;
     5.1 --- a/xen/include/asm-ia64/bundle.h	Wed Dec 10 15:39:47 2008 +0900
     5.2 +++ b/xen/include/asm-ia64/bundle.h	Fri Dec 12 10:29:15 2008 +0900
     5.3 @@ -33,6 +33,11 @@ typedef union U_INST64_B9 {
     5.4      struct { unsigned long qp:6, imm20:20, :1, x6:6, :3, i:1, major:4; };
     5.5  } INST64_B9;
     5.6  
     5.7 +typedef union U_INST64_I18 {
     5.8 +    IA64_INST inst;
     5.9 +    struct { unsigned long qp:6, imm20:20, y:1, x6:6, x3:3, i:1, major:4; };
    5.10 +} INST64_I18;
    5.11 +
    5.12  typedef union U_INST64_I19 {
    5.13      IA64_INST inst;
    5.14      struct { unsigned long qp:6, imm20:20, :1, x6:6, x3:3, i:1, major:4; };
    5.15 @@ -191,6 +196,7 @@ typedef union U_INST64 {
    5.16      INST64_B4 B4;	// used in build_hypercall_bundle only
    5.17      INST64_B8 B8;	// rfi, bsw.[01]
    5.18      INST64_B9 B9;	// break.b
    5.19 +    INST64_I18 I18;	// nop.i used in build_fpswa_hypercall_bundle only
    5.20      INST64_I19 I19;	// used in build_hypercall_bundle only
    5.21      INST64_I26 I26;	// mov register to ar (I unit)
    5.22      INST64_I27 I27;	// mov immediate to ar (I unit)
     6.1 --- a/xen/include/asm-ia64/dom_fw.h	Wed Dec 10 15:39:47 2008 +0900
     6.2 +++ b/xen/include/asm-ia64/dom_fw.h	Fri Dec 12 10:29:15 2008 +0900
     6.3 @@ -161,14 +161,21 @@
     6.4  
     6.5  /*
     6.6   * This is a hypercall number for FPSWA.
     6.7 - * FPSWA hypercall uses 2 bundles for a pseudo-entry-point and a hypercall-patch.
     6.8 + * FPSWA hypercall uses one bundle for a pseudo-entry-point
     6.9 + * and 14 bundles for a hypercall-patch.
    6.10 + *
    6.11 + * 0x500 was used before. But that implemetation is broken.
    6.12 + * To keep hypercall abi, 0x500 is obsoleted and allocate 0x501 for 
    6.13 + * fspwa hypercall.
    6.14   */
    6.15  #define FW_HYPERCALL_FPSWA_ENTRY_INDEX			0x90UL
    6.16  #define FW_HYPERCALL_FPSWA_PATCH_INDEX			0x91UL
    6.17  #define FW_HYPERCALL_FPSWA_ENTRY_PADDR			FW_HYPERCALL_PADDR(FW_HYPERCALL_FPSWA_ENTRY_INDEX)
    6.18  #define FW_HYPERCALL_FPSWA_PATCH_PADDR			FW_HYPERCALL_PADDR(FW_HYPERCALL_FPSWA_PATCH_INDEX)
    6.19 -#define FW_HYPERCALL_FPSWA				0x500UL
    6.20 -#define FW_HYPERCALL_FPSWA_STR				"0x500"
    6.21 +#define FW_HYPERCALL_FPSWA_BASE				0x500UL
    6.22 +#define FW_HYPERCALL_FPSWA_BROKEN			0x500UL
    6.23 +#define FW_HYPERCALL_FPSWA				0x501UL
    6.24 +#define FW_HYPERCALL_FPSWA_STR				"0x501"
    6.25  
    6.26  /* Set the shared_info base virtual address.  */
    6.27  #define FW_HYPERCALL_SET_SHARED_INFO_VA			0x600UL
     7.1 --- a/xen/include/asm-ia64/domain.h	Wed Dec 10 15:39:47 2008 +0900
     7.2 +++ b/xen/include/asm-ia64/domain.h	Fri Dec 12 10:29:15 2008 +0900
     7.3 @@ -323,6 +323,9 @@ ia64_fault(unsigned long vector, unsigne
     7.4             unsigned long iim, unsigned long itir, unsigned long arg5,
     7.5             unsigned long arg6, unsigned long arg7, unsigned long stack);
     7.6  
     7.7 +void
     7.8 +ia64_lazy_load_fpu(struct vcpu *vcpu);
     7.9 +
    7.10  #endif /* __ASM_DOMAIN_H__ */
    7.11  
    7.12  /*
     8.1 --- a/xen/include/asm-ia64/vmx.h	Wed Dec 10 15:39:47 2008 +0900
     8.2 +++ b/xen/include/asm-ia64/vmx.h	Fri Dec 12 10:29:15 2008 +0900
     8.3 @@ -45,6 +45,7 @@ extern void vmx_relinquish_vcpu_resource
     8.4  extern void vmx_send_assist_req(struct vcpu *v);
     8.5  extern void deliver_pal_init(struct vcpu *vcpu);
     8.6  extern void vmx_pend_pal_init(struct domain *d);
     8.7 +extern void vmx_lazy_load_fpu(struct vcpu *vcpu);
     8.8  
     8.9  static inline vcpu_iodata_t *get_vio(struct vcpu *v)
    8.10  {