[Xen-ia64-devel] [PATCH 0/5] fix fpswa and related issues.

2008-12-09 Thread Isaku Yamahata

Hi. This patch series addresses the bug reported as
http://bugzilla.xensource.com/bugzilla/show_bug.cgi?id=1392
Please test it.

It includes some clean ups and a reimplementation of fpswa hypercall.
When fp fault/trap occurs, xen vmm tries to get a bundle in question
from guest virtual address space. It sometimes fails because of
I/D tlb cache. In that case inject the fault/trap into a guest
and let a guest to call fpswa hypercall.

thanks  

___
Xen-ia64-devel mailing list
Xen-ia64-devel@lists.xensource.com
http://lists.xensource.com/xen-ia64-devel


[Xen-ia64-devel] [PATCH 1/5] use symbolic constant instead of magic number

2008-12-09 Thread Isaku Yamahata
IA64: use symbolic constant for hypercall.

define symbolic names for hypercall number and use them.

Signed-off-by: Isaku Yamahata <[EMAIL PROTECTED]>

diff --git a/xen/arch/ia64/xen/dom_fw_asm.S b/xen/arch/ia64/xen/dom_fw_asm.S
--- a/xen/arch/ia64/xen/dom_fw_asm.S
+++ b/xen/arch/ia64/xen/dom_fw_asm.S
@@ -1,3 +1,5 @@
+#include 
+
 // moved from xenasm.S to be shared by xen and libxc
 /*
  * Assembly support routines for Xen/ia64
@@ -26,14 +28,14 @@ xen_ia64_pal_call_stub:
 xen_ia64_pal_call_stub:
{
 .mii
-   addl r2=0x1000,r0   //  Hypercall number (Value is patched).
+   addl r2=FW_HYPERCALL_PAL_CALL_ASM,r0//  Hypercall number (Value is 
patched).
mov r9=256
;; 
cmp.gtu p7,p8=r9,r28/* r32 <= 255? */
}
{
 .mbb
-   break 0x1000//  Hypercall vector (Value is patched).
+   break __IA64_XEN_HYPERCALL_DEFAULT  //  Hypercall vector (Value is 
patched).
 (p7)   br.cond.sptk.few rp
 (p8)   br.ret.sptk.few rp
}
diff --git a/xen/arch/ia64/xen/domain.c b/xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c
+++ b/xen/arch/ia64/xen/domain.c
@@ -561,7 +561,7 @@ int arch_domain_create(struct domain *d,
 
// the following will eventually need to be negotiated dynamically
d->arch.shared_info_va = DEFAULT_SHAREDINFO_ADDR;
-   d->arch.breakimm = 0x1000;
+   d->arch.breakimm = __IA64_XEN_HYPERCALL_DEFAULT;
for (i = 0; i < NR_CPUS; i++) {
d->arch.last_vcpu[i].vcpu_id = INVALID_VCPU_ID;
}
diff --git a/xen/include/asm-ia64/dom_fw.h b/xen/include/asm-ia64/dom_fw.h
--- a/xen/include/asm-ia64/dom_fw.h
+++ b/xen/include/asm-ia64/dom_fw.h
@@ -4,6 +4,9 @@
  * Copyright (C) 2004 Hewlett-Packard Co
  * Dan Magenheimer ([EMAIL PROTECTED])
  */
+
+#define __IA64_XEN_HYPERCALL_DEFAULT   0x1000
+#define __IA64_XEN_HYPERCALL_DEFAULT_STR   "0x1000"
 
 /* Portion of guest physical memory space reserved for PAL/SAL/EFI/ACPI
data and code.  */
@@ -65,6 +68,7 @@
 #define FW_HYPERCALL_PAL_CALL_INDEX0x80UL
 #define FW_HYPERCALL_PAL_CALL_PADDR
FW_HYPERCALL_PADDR(FW_HYPERCALL_PAL_CALL_INDEX)
 #define FW_HYPERCALL_PAL_CALL  0x1000UL
+#define FW_HYPERCALL_PAL_CALL_ASM  0x1000
 
 /*
  * SAL consists of a table of descriptors, one of which (type=0)
@@ -164,6 +168,7 @@
 #define FW_HYPERCALL_FPSWA_ENTRY_PADDR 
FW_HYPERCALL_PADDR(FW_HYPERCALL_FPSWA_ENTRY_INDEX)
 #define FW_HYPERCALL_FPSWA_PATCH_PADDR 
FW_HYPERCALL_PADDR(FW_HYPERCALL_FPSWA_PATCH_INDEX)
 #define FW_HYPERCALL_FPSWA 0x500UL
+#define FW_HYPERCALL_FPSWA_STR "0x500"
 
 /* Set the shared_info base virtual address.  */
 #define FW_HYPERCALL_SET_SHARED_INFO_VA0x600UL
@@ -186,7 +191,7 @@
 /* Additionnal OEM SAL.  */
 #define SAL_XEN_SAL_RETURN 0x0200
 
-#ifdef __XEN__
+#if defined(__XEN__) && !defined(__ASSEMBLY__)
 #include 
 extern struct ia64_pal_retval xen_pal_emulator(u64, u64, u64, u64);
 extern struct sal_ret_values sal_emulator (long index, unsigned long in1, 
unsigned long in2, unsigned long in3, unsigned long in4, unsigned long in5, 
unsigned long in6, unsigned long in7);
IA64: use symbolic constant for hypercall.

define symbolic names for hypercall number and use them.

Signed-off-by: Isaku Yamahata <[EMAIL PROTECTED]>

diff --git a/xen/arch/ia64/xen/dom_fw_asm.S b/xen/arch/ia64/xen/dom_fw_asm.S
--- a/xen/arch/ia64/xen/dom_fw_asm.S
+++ b/xen/arch/ia64/xen/dom_fw_asm.S
@@ -1,3 +1,5 @@
+#include 
+
 // moved from xenasm.S to be shared by xen and libxc
 /*
  * Assembly support routines for Xen/ia64
@@ -26,14 +28,14 @@ xen_ia64_pal_call_stub:
 xen_ia64_pal_call_stub:
 	{
 	 .mii
-	addl r2=0x1000,r0	//  Hypercall number (Value is patched).
+	addl r2=FW_HYPERCALL_PAL_CALL_ASM,r0	//  Hypercall number (Value is patched).
 	mov r9=256
 	;; 
 	cmp.gtu p7,p8=r9,r28		/* r32 <= 255? */
 	}
 	{
 	 .mbb
-	break 0x1000		//  Hypercall vector (Value is patched).
+	break __IA64_XEN_HYPERCALL_DEFAULT	//  Hypercall vector (Value is patched).
 (p7)	br.cond.sptk.few rp
 (p8)	br.ret.sptk.few rp
 	}
diff --git a/xen/arch/ia64/xen/domain.c b/xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c
+++ b/xen/arch/ia64/xen/domain.c
@@ -561,7 +561,7 @@ int arch_domain_create(struct domain *d,
 
 	// the following will eventually need to be negotiated dynamically
 	d->arch.shared_info_va = DEFAULT_SHAREDINFO_ADDR;
-	d->arch.breakimm = 0x1000;
+	d->arch.breakimm = __IA64_XEN_HYPERCALL_DEFAULT;
 	for (i = 0; i < NR_CPUS; i++) {
 		d->arch.last_vcpu[i].vcpu_id = INVALID_VCPU_ID;
 	}
diff --git a/xen/include/asm-ia64/dom_fw.h b/xen/include/asm-ia64/dom_fw.h
--- a/xen/include/asm-ia64/dom_fw.h
+++ b/xen/include/asm-ia64/dom_fw.h
@@ -4,6 +4,9 @@
  * Copyright (C) 2004 Hewlett-Packard Co
  *	Dan Magenheimer ([EMAIL PROTECTED])
  */
+
+#define __IA64_XEN_HYPERCALL_DEFAULT		0x1000
+#defi

[Xen-ia64-devel] [PATCH 4/5] fix fp fault/trap handler

2008-12-09 Thread Isaku Yamahata
IA64: fix fp fault/trap handler.

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

When fpswa handler fails to get a bundle in guest,
fp fault/trap should be injected into the guest and let a guest
to handle it.
When the fpswa library return a error, there is no way to
pass the value to the guest. In that case, revert the change
and inject the fp fault/trap.

Signed-off-by: Isaku Yamahata <[EMAIL PROTECTED]>

diff --git a/xen/arch/ia64/vmx/vmx_fault.c b/xen/arch/ia64/vmx/vmx_fault.c
--- a/xen/arch/ia64/vmx/vmx_fault.c
+++ b/xen/arch/ia64/vmx/vmx_fault.c
@@ -122,8 +122,7 @@ void vmx_reflect_interruption(u64 ifa, u
 if (!status) {
 vcpu_increment_iip(vcpu);
 return;
-} else if (IA64_RETRY == status)
-return;
+}
 break;
 
 case 33:   // IA64_FP_TRAP_VECTOR
@@ -133,10 +132,6 @@ void vmx_reflect_interruption(u64 ifa, u
 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
diff --git a/xen/arch/ia64/xen/faults.c b/xen/arch/ia64/xen/faults.c
--- a/xen/arch/ia64/xen/faults.c
+++ b/xen/arch/ia64/xen/faults.c
@@ -314,11 +314,15 @@ unsigned long
 unsigned long
 handle_fpu_swa(int fp_fault, struct pt_regs *regs, unsigned long isr)
 {
-   struct vcpu *v = current;
IA64_BUNDLE bundle;
unsigned long fault_ip;
fpswa_ret_t ret;
unsigned long rc;
+
+   unsigned long ipsr_save;
+   unsigned long fpsr_save;
+   unsigned long pr_save;
+   struct ia64_fpreg fp_save[6];
 
fault_ip = regs->cr_iip;
/*
@@ -344,11 +348,22 @@ handle_fpu_swa(int fp_fault, struct pt_r
return IA64_RETRY;
}
 
+   /* If fpswa returns error, fp falut/trap is reflected and
+  a guest will call fpswa itself. So we have to revert the effect
+  to avoid calling fpswa twice. */
+   ipsr_save = regs->cr_ipsr;
+   fpsr_save = regs->ar_fpsr;
+   pr_save = regs->pr;
+   memcpy(fp_save, ®s->f6, sizeof(fp_save));
+
ret = fp_emulate(fp_fault, &bundle, ®s->cr_ipsr, ®s->ar_fpsr,
 &isr, ®s->pr, ®s->cr_ifs, regs);
 
if (ret.status) {
-   PSCBX(v, fpswa_ret) = ret;
+   regs->cr_ipsr = ipsr_save;
+   regs->ar_fpsr = fpsr_save;
+   regs->pr = pr_save;
+   memcpy(®s->f6, fp_save, sizeof(fp_save));
printk("%s(%s): fp_emulate() returned %ld\n",
   __FUNCTION__, fp_fault ? "fault" : "trap", ret.status);
}
@@ -688,9 +703,6 @@ ia64_handle_reflection(unsigned long ifa
vcpu_increment_iip(v);
return;
}
-   // fetch code fail
-   if (IA64_RETRY == status)
-   return;
printk("ia64_handle_reflection: handling FP fault\n");
vector = IA64_FP_FAULT_VECTOR;
break;
@@ -698,11 +710,6 @@ ia64_handle_reflection(unsigned long ifa
status = handle_fpu_swa(0, regs, isr);
if (!status)
return;
-   // fetch code fail
-   if (IA64_RETRY == status) {
-   vcpu_decrement_iip(v);
-   return;
-   }
printk("ia64_handle_reflection: handling FP trap\n");
vector = IA64_FP_TRAP_VECTOR;
break;
diff --git a/xen/include/asm-ia64/domain.h b/xen/include/asm-ia64/domain.h
--- a/xen/include/asm-ia64/domain.h
+++ b/xen/include/asm-ia64/domain.h
@@ -288,7 +288,6 @@ struct arch_vcpu {
 char irq_new_condition;// vpsr.i/vtpr change, check for pending VHPI
 char hypercall_continuation;
 
-fpswa_ret_t fpswa_ret; /* save return values of FPSWA emulation */
 struct timer hlt_timer;
 struct arch_vmx_struct arch_vmx; /* Virtual Machine Extensions */
 
IA64: fix fp fault/trap handler.

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

When fpswa handler fails to get a bundle in guest,
fp fault/trap should be injected into the guest and let a guest
to handle it.
When the fpswa library return a error, there is no way to
pass the value to the guest. In that case, revert the change
and inject the fp fault/trap.

Signed-off-by: Isaku Yamahata <[EMAIL PROTECTED]>

diff --git a/xen/arch/ia64/vmx/vmx_fault.c b/xen/arch/ia64/vmx/vmx_fault.c
--- a/xen/arch/ia64/vmx/vmx_fault.c
+++ b/xen/arch/ia64/vmx/vmx_fault.c
@@ -122,8 +122,7 @@ void vmx_reflect_interruption(u64 ifa, u
 if (!status) {
 vcpu_increment_iip(vcpu);
 return;
-} else if (IA64_RETRY == status)
-return;
+}
 

[Xen-ia64-devel] [PATCH 2/5] improve handle_fpu_swa()

2008-12-09 Thread Isaku Yamahata
IA64: improve handle_fpu_swa()

It tries to get a bundle in guest.
Make it more robust using vmx_get_domain_bundle() instead of
__get_domain_bundle().

Signed-off-by: Isaku Yamahata <[EMAIL PROTECTED]>

diff --git a/xen/arch/ia64/xen/faults.c b/xen/arch/ia64/xen/faults.c
--- a/xen/arch/ia64/xen/faults.c
+++ b/xen/arch/ia64/xen/faults.c
@@ -318,6 +318,7 @@ handle_fpu_swa(int fp_fault, struct pt_r
IA64_BUNDLE bundle;
unsigned long fault_ip;
fpswa_ret_t ret;
+   unsigned long rc;
 
fault_ip = regs->cr_iip;
/*
@@ -329,15 +330,18 @@ handle_fpu_swa(int fp_fault, struct pt_r
fault_ip -= 16;
 
if (VMX_DOMAIN(current)) {
-   if (IA64_RETRY == __vmx_get_domain_bundle(fault_ip, &bundle))
-   return IA64_RETRY;
-   } else
-   bundle = __get_domain_bundle(fault_ip);
-
-   if (!bundle.i64[0] && !bundle.i64[1]) {
-   printk("%s: floating-point bundle at 0x%lx not mapped\n",
-  __FUNCTION__, fault_ip);
-   return -1;
+   rc = __vmx_get_domain_bundle(fault_ip, &bundle);
+   } else {
+   rc = 0;
+   if (vcpu_get_domain_bundle(current, regs, fault_ip,
+  &bundle) == 0)
+   rc = IA64_RETRY;
+   }
+   if (rc == IA64_RETRY) {
+   gdprintk(XENLOG_DEBUG,
+"%s(%s): floating-point bundle at 0x%lx not mapped\n",
+__FUNCTION__, fp_fault ? "fault" : "trap", fault_ip);
+   return IA64_RETRY;
}
 
ret = fp_emulate(fp_fault, &bundle, ®s->cr_ipsr, ®s->ar_fpsr,
@@ -689,8 +693,10 @@ ia64_handle_reflection(unsigned long ifa
if (!status)
return;
// fetch code fail
-   if (IA64_RETRY == status)
+   if (IA64_RETRY == status) {
+   vcpu_decrement_iip(v);
return;
+   }
printk("ia64_handle_reflection: handling FP trap\n");
vector = IA64_FP_TRAP_VECTOR;
break;
diff --git a/xen/arch/ia64/xen/vcpu.c b/xen/arch/ia64/xen/vcpu.c
--- a/xen/arch/ia64/xen/vcpu.c
+++ b/xen/arch/ia64/xen/vcpu.c
@@ -1355,6 +1355,26 @@ vcpu_get_domain_bundle(VCPU * vcpu, REGS
// copy its value to the variable, tr, before use.
TR_ENTRY tr;
 
+   // fast path:
+   // try to access gip with guest virtual address directly.
+   // This may cause tlb miss. see vcpu_translate(). Be careful!
+   swap_rr0 = (!region && PSCB(vcpu, metaphysical_mode));
+   if (swap_rr0) {
+   set_virtual_rr0();
+   }
+   *bundle = __get_domain_bundle(gip);
+   if (swap_rr0) {
+   set_metaphysical_rr0();
+   }
+   
+   if (!bundle->i64[0] && !bundle->i64[1]) {
+   dprintk(XENLOG_INFO, "%s gip 0x%lx\n", __func__, gip);
+   } else {
+   // Okay, mDTC successed
+   return 1;
+   }
+   // mDTC failed, so try vTLB.
+
trp = vcpu_tr_lookup(vcpu, gip, rid, 0);
if (trp != NULL) {
tr = *trp;
@@ -1374,28 +1394,13 @@ vcpu_get_domain_bundle(VCPU * vcpu, REGS
tr = *trp;
goto found;
}
-#if 0
tr = PSCBX(vcpu, dtlb);
if (vcpu_match_tr_entry(&tr, gip, rid)) {
goto found;
}
-#endif
 
-   // try to access gip with guest virtual address
-   // This may cause tlb miss. see vcpu_translate(). Be careful!
-   swap_rr0 = (!region && PSCB(vcpu, metaphysical_mode));
-   if (swap_rr0) {
-   set_virtual_rr0();
-   }
-   *bundle = __get_domain_bundle(gip);
-   if (swap_rr0) {
-   set_metaphysical_rr0();
-   }
-   if (bundle->i64[0] == 0 && bundle->i64[1] == 0) {
-   dprintk(XENLOG_INFO, "%s gip 0x%lx\n", __func__, gip);
-   return 0;
-   }
-   return 1;
+   // mDTC and vTLB failed. so reflect tlb miss into the guest.
+   return 0;
 
found:
gpip = ((tr.pte.ppn >> (tr.ps - 12)) << tr.ps) |
IA64: improve handle_fpu_swa()

It tries to get a bundle in guest.
Make it more robust using vmx_get_domain_bundle() instead of
__get_domain_bundle().

Signed-off-by: Isaku Yamahata <[EMAIL PROTECTED]>

diff --git a/xen/arch/ia64/xen/faults.c b/xen/arch/ia64/xen/faults.c
--- a/xen/arch/ia64/xen/faults.c
+++ b/xen/arch/ia64/xen/faults.c
@@ -318,6 +318,7 @@ handle_fpu_swa(int fp_fault

[Xen-ia64-devel] [PATCH 5/5] fix efi_emulate_set_virtual_address_map()

2008-12-09 Thread Isaku Yamahata
IA64: fix efi_emulate_set_virtual_address_map()

get_page() before touching guest pages.
Otherwise pages may be freed during those operations.

Signed-off-by: Isaku Yamahata <[EMAIL PROTECTED]>

diff --git a/xen/arch/ia64/xen/fw_emul.c b/xen/arch/ia64/xen/fw_emul.c
--- a/xen/arch/ia64/xen/fw_emul.c
+++ b/xen/arch/ia64/xen/fw_emul.c
@@ -1334,6 +1334,10 @@ efi_emulate_set_virtual_address_map(
efi_desc_size = sizeof(efi_memory_desc_t);
 
for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
+   struct page_info *efi_runtime_page = NULL;
+   struct page_info *fpswa_inf_page = NULL;
+   struct page_info *fw_table_page = NULL;
+   
if (copy_from_user(&entry, p, sizeof(efi_memory_desc_t))) {
printk ("efi_emulate_set_virtual_address_map: 
copy_from_user() fault. addr=0x%p\n", p);
return EFI_UNSUPPORTED;
@@ -1342,6 +1346,27 @@ efi_emulate_set_virtual_address_map(
/* skip over non-PAL_CODE memory descriptors; EFI_RUNTIME is 
included in PAL_CODE. */
 if (md->type != EFI_PAL_CODE)
 continue;
+
+   /* get pages to prevend them from being freed 
+* during touching them.
+* those entres are in [FW_TABLES_BASE_PADDR, ...]
+* see dom_fw.h for its layout.
+*/
+   efi_runtime_page = virt_to_page(efi_runtime);
+   fpswa_inf_page = virt_to_page(fpswa_inf);
+   fw_table_page = virt_to_page(
+   domain_mpa_to_imva(d, FW_TABLES_BASE_PADDR));
+   if (get_page(efi_runtime_page, d) == 0)
+   return EFI_INVALID_PARAMETER;
+   if (get_page(fpswa_inf_page, d) == 0) {
+   put_page(efi_runtime_page);
+   return EFI_INVALID_PARAMETER;
+   }
+   if (get_page(fw_table_page, d) == 0) {
+   put_page(fpswa_inf_page);
+   put_page(efi_runtime_page);
+   return EFI_INVALID_PARAMETER;
+   }
 
 #define EFI_HYPERCALL_PATCH_TO_VIRT(tgt,call) \
do { \
@@ -1365,6 +1390,10 @@ efi_emulate_set_virtual_address_map(
*vfn++ = FW_HYPERCALL_FPSWA_PATCH_INDEX * 16UL + md->virt_addr;
*vfn   = 0;
fpswa_inf->fpswa = (void *) (FW_HYPERCALL_FPSWA_ENTRY_INDEX * 
16UL + md->virt_addr);
+
+   put_page(fw_table_page);
+   put_page(fpswa_inf_page);
+   put_page(efi_runtime_page);
break;
}
 
IA64: fix efi_emulate_set_virtual_address_map()

get_page() before touching guest pages.
Otherwise pages may be freed during those operations.

Signed-off-by: Isaku Yamahata <[EMAIL PROTECTED]>

diff --git a/xen/arch/ia64/xen/fw_emul.c b/xen/arch/ia64/xen/fw_emul.c
--- a/xen/arch/ia64/xen/fw_emul.c
+++ b/xen/arch/ia64/xen/fw_emul.c
@@ -1334,6 +1334,10 @@ efi_emulate_set_virtual_address_map(
 	efi_desc_size = sizeof(efi_memory_desc_t);
 
 	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
+		struct page_info *efi_runtime_page = NULL;
+		struct page_info *fpswa_inf_page = NULL;
+		struct page_info *fw_table_page = NULL;
+		
 		if (copy_from_user(&entry, p, sizeof(efi_memory_desc_t))) {
 			printk ("efi_emulate_set_virtual_address_map: copy_from_user() fault. addr=0x%p\n", p);
 			return EFI_UNSUPPORTED;
@@ -1342,6 +1346,27 @@ efi_emulate_set_virtual_address_map(
 		/* skip over non-PAL_CODE memory descriptors; EFI_RUNTIME is included in PAL_CODE. */
 if (md->type != EFI_PAL_CODE)
 continue;
+
+		/* get pages to prevend them from being freed 
+		 * during touching them.
+		 * those entres are in [FW_TABLES_BASE_PADDR, ...]
+		 * see dom_fw.h for its layout.
+		 */
+		efi_runtime_page = virt_to_page(efi_runtime);
+		fpswa_inf_page = virt_to_page(fpswa_inf);
+		fw_table_page = virt_to_page(
+			domain_mpa_to_imva(d, FW_TABLES_BASE_PADDR));
+		if (get_page(efi_runtime_page, d) == 0)
+			return EFI_INVALID_PARAMETER;
+		if (get_page(fpswa_inf_page, d) == 0) {
+			put_page(efi_runtime_page);
+			return EFI_INVALID_PARAMETER;
+		}
+		if (get_page(fw_table_page, d) == 0) {
+			put_page(fpswa_inf_page);
+			put_page(efi_runtime_page);
+			return EFI_INVALID_PARAMETER;
+		}
 
 #define EFI_HYPERCALL_PATCH_TO_VIRT(tgt,call) \
 	do { \
@@ -1365,6 +1390,10 @@ efi_emulate_set_virtual_address_map(
 		*vfn++ = FW_HYPERCALL_FPSWA_PATCH_INDEX * 16UL + md->virt_addr;
 		*vfn   = 0;
 		fpswa_inf->fpswa = (void *) (FW_HYPERCALL_FPSWA_ENTRY_INDEX * 16UL + md->virt_addr);
+
+		put_page(fw_table_page);
+		put_page(fpswa_inf_page);
+		put_page(efi_runtime_page);
 		break;
 	}
 
___
Xen-ia64-devel mailing list
Xen-ia64-devel@lists.xensource.com
http://lists.xensource.com/xen-ia64-devel

[Xen-ia64-devel] [PATCH 3/5] fix fp emulation

2008-12-09 Thread Isaku Yamahata
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 <[EMAIL PROTECTED]>

diff --git a/xen/arch/ia64/vmx/vmx_fault.c b/xen/arch/ia64/vmx/vmx_fault.c
--- a/xen/arch/ia64/vmx/vmx_fault.c
+++ b/xen/arch/ia64/vmx/vmx_fault.c
@@ -74,7 +74,14 @@ static const u16 vec2off[68] = {0x0,0x40
 0x7f00
 };
 
-
+void vmx_lazy_load_fpu(struct vcpu *vcpu)
+{
+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);
+}
+}
 
 void vmx_reflect_interruption(u64 ifa, u64 isr, u64 iim,
   u64 vec, REGS *regs)
@@ -98,11 +105,7 @@ void vmx_reflect_interruption(u64 ifa, u
 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);
-}
+vmx_lazy_load_fpu(vcpu);
 if (!(VCPU(vcpu, vpsr) & IA64_PSR_DFH)) {
 regs->cr_ipsr &= ~IA64_PSR_DFH;
 return;
diff --git a/xen/arch/ia64/xen/dom_fw_common.c 
b/xen/arch/ia64/xen/dom_fw_common.c
--- a/xen/arch/ia64/xen/dom_fw_common.c
+++ b/xen/arch/ia64/xen/dom_fw_common.c
@@ -142,6 +142,117 @@ build_pal_hypercall_bundles(uint64_t *im
ia64_fc(imva + 3);
 }
 
+/* xen fpswa call stub. 14 bundles */
+extern const unsigned long xen_ia64_fpswa_call_stub[];
+extern const unsigned long xen_ia64_fpswa_call_stub_end[];
+extern const unsigned long xen_ia64_fpswa_call_stub_patch[];
+asm(
+   ".align 32\n"
+   ".proc xen_ia64_fpswa_call_stub;\n"
+   "xen_ia64_fpswa_call_stub:\n"
+   ".prologue\n"
+   "alloc r3 = ar.pfs, 8, 0, 0, 0\n"
+   ".body\n"
+   "mov r14 = in0\n"
+   "ld8 r15 = [in1], 8\n"
+   ";;\n"
+   "ld8 r16 = [in1]\n"
+   "ld8 r17 = [in2]\n"
+   "ld8 r18 = [in3]\n"
+   "ld8 r19 = [in4]\n"
+   "ld8 r20 = [in5]\n"
+   "ld8 r21 = [in6]\n"
+   "ld8 r22 = [in7], 8\n"
+   ";;\n"
+   "ld8 r23 = [in7], 8\n"
+   ";;\n"
+   "ld8 r24 = [in7], 8\n"
+   ";;\n"
+   "cmp.ne p6, p0 = r24, r0\n"
+   "ld8 r25 = [in7], 8\n"
+   ";;\n"
+   "(p6) tpa r24 = r24\n"
+   "cmp.ne p7, p0 = r25, r0\n"
+   "ld8 r26 = [in7], 8\n"
+   ";;\n"
+   "(p7)tpa r25 = r25\n"
+   "cmp.ne p8, p0 = r26, r0\n"
+   "ld8 r27 = [in7], 8\n"
+   ";;\n"
+   "(p8)tpa r26 = r26\n"
+   "cmp.ne p9, p0 = r27, r0\n"
+   ";;\n"
+   "tpa r27 = r27\n"
+   "xen_ia64_fpswa_call_stub_patch:"
+   "{\n"
+   "mov r2 = " FW_HYPERCALL_FPSWA_STR "\n"
+   "break " __IA64_XEN_HYPERCALL_DEFAULT_STR "\n"
+   "nop.i 0\n"
+   "}\n"
+   "st8 [in2] = r17\n"
+   "st8 [in3] = r18\n"
+   "st8 [in4] = r19\n"
+   "st8 [in5] = r20\n"
+   "st8 [in6] = r21\n"
+   "br.ret.sptk.many rp\n"
+   "xen_ia64_fpswa_call_stub_end:"
+   ".endp xen_ia64_fpswa_call_stub\n"
+);
+
+static void
+build_fpswa_hypercall_bundle(uint64_t *imva, uint64_t brkimm, uint64_t hypnum)
+{
+   INST64_A5 slot0;
+   INST64_I19 slot1;
+   INST64_I18 slot2;
+   IA64_BUNDLE bundle;
+
+   /* slot0: mov r2 = hypnum (low 20 bits) */
+   slot0.inst = 0;
+   slot0.qp = 0;
+   slot0.r1 = 2;
+   slot0.r3 = 0;
+   slot0.major = 0x9;
+
+   slot0.s = 0;
+   slot0.imm9d = hypnum >> 7;
+   slot0.imm5c = hypnum >> 16;
+   slot0.imm7b = hypnum;
+
+   /* slot1: break brkimm */
+   slot1.inst = 0;
+   slot1.qp = 0;
+   slot1.x6 = 0;
+   slot1.x3 = 0;
+   slot1.major = 0x0;
+   slot1.i = brkimm >> 20;
+   slot1.imm20 = brkimm;
+
+   /* slot2: nop.i */
+   slot2.inst = 0;
+   slot2.qp = 0;
+   slot2.imm20 = 0;
+   slot2.y = 0;
+   slot2.x6 = 1;
+   slot2.x3 = 0;
+   slot2.i = 0;
+   slot2.major = 0;
+
+   /* MII bundle */
+   bundle.i64[0] = 0;
+   bundle.i64[1] = 0;
+   bundle.template = 0x0; /* MII */
+   bundle.slot0 = slot0.inst;
+   bundle.slot1a = slot1.inst;
+   bundle.slot1b = slot1.inst >> 18;
+   bundle.slot2 = slot2.inst;
+   
+   imva[0] = bundle.i64[0];
+   imva[1] = bundle.i64[1];
+   ia64_fc(imva);
+   ia64_fc(imva + 1);
+}
+
 // builds a hypercall bundle at domain physical address
 static void
 dom_fpswa_hypercall_patch(uint64_t brkimm, unsigned long 

RE: [Xen-ia64-devel] [Test Report] Xen/IPF Unstable CS#18860 Status --- Dom0 Crash

2008-12-09 Thread You, Yongkang
On Monday, December 08, 2008 2:10 PM, "Isaku Yamahata" wrote:

> On Mon, Dec 08, 2008 at 01:52:38PM +0800, Zhang, Jingke wrote:
>> Isaku Yamahata wrote:
>>> On Mon, Dec 08, 2008 at 11:31:15AM +0800, Zhang, Jingke wrote:
 Hi Isaku,
 We re-get the detail information from serial port, please see
 below. Two comments add:
>>> 
>>> Thank you.
>>> 
>>> 
 1. We can be sure the Cset#18832 works well on the same tiger4
 machine. But we did not do regression test between 18832 and this
 18860. 
 2. It is strange that on another Tiger4 box, dom0 will NOT
 crash. Do you have any idea from the serial log? Thanks!
>>> 
>>> I haven't hit this crash. And Kuwamura-san's test seems that
>>> he haven't hit it either. Kuwamura-san, is it correct?
>>> Hmm... it seems to depend on hw configuration?
>>> I'm inclined to suspect masking/unmasking interruption race.
>>> event channel issues? But that's just only my very vague guess.
>>> 
>>> The difference between 18832 and 18860 means the merging
>>> xen-unstable into xen-ia64-unstable. Looking the log, I suspect
>>> linux-2.6.18-xen instead of xen. 
>>> Could you provide the linux c/s which corresponds to 18832 and
>>> 18860? 
>> 
>> 
>> Hi Isaku,
>> Yes, some of our machines do not crash. I am afraid there may be
>> some potential issue. By testing 18832, we use linux#742. While
>> 18860 uses linux#753. Thanks! 
> 
> Thank you. Taking rough look at them those change sets doesn't
> seem culprit.
> I agree with you that this may indicate some potential bugs...

Hi All,

This bug is stably reproduced, if providing "dom0_mem=2048M" in append option. 
And if setting dom0_mem to 1024M or 4096M, the crashing doesn't happen. 

We tried #18869 Xen + #742 Dom0, system is okay. So the problem might be in 
Linux tree between #742~#753

Best Regards,
Yongkang You
___
Xen-ia64-devel mailing list
Xen-ia64-devel@lists.xensource.com
http://lists.xensource.com/xen-ia64-devel


[Xen-ia64-devel] Re: [PATCH 0/5] fix fpswa and related issues.

2008-12-09 Thread Alex Williamson
On Tue, 2008-12-09 at 18:29 +0900, Isaku Yamahata wrote:
> Hi. This patch series addresses the bug reported as
> http://bugzilla.xensource.com/bugzilla/show_bug.cgi?id=1392
> Please test it.
> 
> It includes some clean ups and a reimplementation of fpswa hypercall.
> When fp fault/trap occurs, xen vmm tries to get a bundle in question
> from guest virtual address space. It sometimes fails because of
> I/D tlb cache. In that case inject the fault/trap into a guest
> and let a guest to call fpswa hypercall.

Hi Isaku,

I've been testing this for a few hours today (over 25k iterations) and
it seems to fix the problem for me.  Thanks!

Alex

-- 
Alex Williamson HP Open Source & Linux Org.


___
Xen-ia64-devel mailing list
Xen-ia64-devel@lists.xensource.com
http://lists.xensource.com/xen-ia64-devel


[Xen-ia64-devel] RE: [PATCH 0/5] fix fpswa and related issues.

2008-12-09 Thread Zhang, Xiantao
Alex Williamson wrote:
> On Tue, 2008-12-09 at 18:29 +0900, Isaku Yamahata wrote:
>> Hi. This patch series addresses the bug reported as
>> http://bugzilla.xensource.com/bugzilla/show_bug.cgi?id=1392
>> Please test it.
>> 
>> It includes some clean ups and a reimplementation of fpswa hypercall.
>> When fp fault/trap occurs, xen vmm tries to get a bundle in question
>> from guest virtual address space. It sometimes fails because of
>> I/D tlb cache. In that case inject the fault/trap into a guest
>> and let a guest to call fpswa hypercall.
> 
> Hi Isaku,
> 
> I've been testing this for a few hours today (over 25k iterations) and
> it seems to fix the problem for me.  Thanks!

Hi, Alex
Have you verified vmx domain as well ? 
Xiantao 


___
Xen-ia64-devel mailing list
Xen-ia64-devel@lists.xensource.com
http://lists.xensource.com/xen-ia64-devel


[Xen-ia64-devel] RE: [PATCH 0/5] fix fpswa and related issues.

2008-12-09 Thread Alex Williamson
On Wed, 2008-12-10 at 10:51 +0800, Zhang, Xiantao wrote: 
> > I've been testing this for a few hours today (over 25k iterations)
> and
> > it seems to fix the problem for me.  Thanks!
> 
> Hi, Alex
> Have you verified vmx domain as well ? 

Good point, no I was just testing in dom0.

Alex

-- 
Alex Williamson HP Open Source & Linux Org.


___
Xen-ia64-devel mailing list
Xen-ia64-devel@lists.xensource.com
http://lists.xensource.com/xen-ia64-devel


Re: [Xen-ia64-devel] [Fwd: [Xen-bugs] [Bug 1392] New: Problems with denormalized floating point numbers on XEN-virtualized Linux/IA64]

2008-12-09 Thread Isaku Yamahata
On Sat, Dec 06, 2008 at 11:10:22AM +0800, Zhang, Xiantao wrote:
> > If we fail to get a bundle in a guest when FP trap,
> > we can't reexecute the instruction. We have to inject floating
> > point trap into guest.
> 
> For HVM, injecting  it to guest should be the right way to go.  

Another issue.
When fpswa library in xen VMM returns status > 0, 
what should we do for PV/HVM domain? 
I suppose this case hasn't been tested.
The current implementation just inject FP trap/fault into guest,
and guest calls fpswa itself.

In such a case, fpswa is called twice. I tried to revert the effect
of fpswa library call with the new patch series, but it wasn't enough.
In order to revert the effect, all the fp register must be saved
before the call. It would impose unacceptable performance overhead.

Some considerations:

- let fpswa library be called twice.
  Is it safe to call fpswa library twice? If this answer is yes,
  this option can be taken.
  However I'm not sure. the specification[1] doesn't tell much.
  Looking at the linux trap handler, might it be sufficent
  for fpswa to return error > 0 on the second call?

  [1] "Itanium Processor floating-point software assistance and 
   floating-point exception handling."

- Ignore this issue.
  Are there any applications which depend on SIGFPE process signal?
  If no, we might be able to ignore this case.
  On native Linux, SIGPFE is delivered to the process when fpswa
  returns status > 0.
  If there is no application to use SIGPFE to recover its computation,
  we might be able to ignore this issue (until an unfortunate application
  developers complains).

- save the result of fpswa call in xen VMM and return the value
  when fpswa hypercall is issued assuming the guest kernel is none
  preemptive. This is only for PV domain.
  The first thing which comes into my mind is that the guest kernel might
  be preemptive.
  The previous implementation (before my patch) assumes that
  the PV guest kernel is none preemptive, and it calls fpswa library call
  right after the fp fault/trap.
  So it saves the result of fpswa call in Xen VMM and returned
  the return values.
  The Linux fp fault/trap handler assumes not to be preempted between
  fault/trap occurrence and fpswa library call because it uses
  processor's f2-f5, f12-f127.
  As for HVM domain case, guest firmware uses its own fpswa library,
  the call isn't hooked to Xen VMM. So this isn't an option for HVM
  domain.

- abandon to handle fp trap/fault in Xen VMM.
  Always inject the fp trap/fault into a guest without calling
  fpswa library in Xen VMM. This should work and the implementation
  would become simple. But how about performance?

thanks,
-- 
yamahata

___
Xen-ia64-devel mailing list
Xen-ia64-devel@lists.xensource.com
http://lists.xensource.com/xen-ia64-devel


Re: [Xen-ia64-devel] RE: [PATCH 0/5] fix fpswa and related issues.

2008-12-09 Thread Isaku Yamahata
On Tue, Dec 09, 2008 at 09:23:01PM -0700, Alex Williamson wrote:
> On Wed, 2008-12-10 at 10:51 +0800, Zhang, Xiantao wrote: 
> > > I've been testing this for a few hours today (over 25k iterations)
> > and
> > > it seems to fix the problem for me.  Thanks!
> > 
> > Hi, Alex
> > Have you verified vmx domain as well ? 
> 
> Good point, no I was just testing in dom0.

You may want to test with two PV guest because
of eager safe/lazy restore fp.
I wrote the code to address it, but it hasn't been tested very well.
-- 
yamahata

___
Xen-ia64-devel mailing list
Xen-ia64-devel@lists.xensource.com
http://lists.xensource.com/xen-ia64-devel


Re: [Xen-ia64-devel] [PATCH 0/5] fix fpswa and related issues.

2008-12-09 Thread Isaku Yamahata
On Tue, Dec 09, 2008 at 06:29:41PM +0900, Isaku Yamahata wrote:
> 
> Hi. This patch series addresses the bug reported as
> http://bugzilla.xensource.com/bugzilla/show_bug.cgi?id=1392
> Please test it.
> 
> It includes some clean ups and a reimplementation of fpswa hypercall.
> When fp fault/trap occurs, xen vmm tries to get a bundle in question
> from guest virtual address space. It sometimes fails because of
> I/D tlb cache. In that case inject the fault/trap into a guest
> and let a guest to call fpswa hypercall.
> 
> thanks
> 
> ___
> Xen-ia64-devel mailing list
> Xen-ia64-devel@lists.xensource.com
> http://lists.xensource.com/xen-ia64-devel
> 


I'd like to add one more patch.
It seems to take a while to address the case that fpswa
returns status > 0.
So keep the previous behavior in such cases for now.

IA64: make the fpswa emulation keep the previous behaviour.

When fpswa library return statue > 0, keep the previous behavior.
This case should be addressed somehow later, but it seems somewhat
difficult to resolve, so keep the previous behavor for now.

Signed-off-by: Isaku Yamahata <[EMAIL PROTECTED]>

diff --git a/xen/arch/ia64/xen/faults.c b/xen/arch/ia64/xen/faults.c
--- a/xen/arch/ia64/xen/faults.c
+++ b/xen/arch/ia64/xen/faults.c
@@ -319,11 +319,6 @@ handle_fpu_swa(int fp_fault, struct pt_r
fpswa_ret_t ret;
unsigned long rc;
 
-   unsigned long ipsr_save;
-   unsigned long fpsr_save;
-   unsigned long pr_save;
-   struct ia64_fpreg fp_save[6];
-
fault_ip = regs->cr_iip;
/*
 * When the FP trap occurs, the trapping instruction is completed.
@@ -342,28 +337,18 @@ handle_fpu_swa(int fp_fault, struct pt_r
rc = IA64_RETRY;
}
if (rc == IA64_RETRY) {
+   PSCBX(v, fpswa_ret) = (fpswa_ret_t){IA64_RETRY, 0, 0, 0};
gdprintk(XENLOG_DEBUG,
 "%s(%s): floating-point bundle at 0x%lx not mapped\n",
 __FUNCTION__, fp_fault ? "fault" : "trap", fault_ip);
return IA64_RETRY;
}
 
-   /* If fpswa returns error, fp falut/trap is reflected and
-  a guest will call fpswa itself. So we have to revert the effect
-  to avoid calling fpswa twice. */
-   ipsr_save = regs->cr_ipsr;
-   fpsr_save = regs->ar_fpsr;
-   pr_save = regs->pr;
-   memcpy(fp_save, ®s->f6, sizeof(fp_save));
-
ret = fp_emulate(fp_fault, &bundle, ®s->cr_ipsr, ®s->ar_fpsr,
 &isr, ®s->pr, ®s->cr_ifs, regs);
 
if (ret.status) {
-   regs->cr_ipsr = ipsr_save;
-   regs->ar_fpsr = fpsr_save;
-   regs->pr = pr_save;
-   memcpy(®s->f6, fp_save, sizeof(fp_save));
+   PSCBX(v, fpswa_ret) = ret;
printk("%s(%s): fp_emulate() returned %ld\n",
   __FUNCTION__, fp_fault ? "fault" : "trap", ret.status);
}
diff --git a/xen/arch/ia64/xen/hypercall.c b/xen/arch/ia64/xen/hypercall.c
--- a/xen/arch/ia64/xen/hypercall.c
+++ b/xen/arch/ia64/xen/hypercall.c
@@ -164,6 +164,13 @@ fw_hypercall_fpswa (struct vcpu *v, stru
struct page_info *hp_page = NULL;
struct page_info *hv_page = NULL;
XEN_EFI_RR_DECLARE(rr6, rr7);
+
+   if (unlikely(PSCBX(v, fpswa_ret).status != 0 && 
+PSCBX(v, fpswa_ret).status != IA64_RETRY)) {
+   ret = PSCBX(v, fpswa_ret);
+   PSCBX(v, fpswa_ret) = (fpswa_ret_t){0, 0, 0, 0};
+   return ret;
+   }
 
if (!fpswa_interface)
goto error;
diff --git a/xen/include/asm-ia64/domain.h b/xen/include/asm-ia64/domain.h
--- a/xen/include/asm-ia64/domain.h
+++ b/xen/include/asm-ia64/domain.h
@@ -288,6 +288,7 @@ struct arch_vcpu {
 char irq_new_condition;// vpsr.i/vtpr change, check for pending VHPI
 char hypercall_continuation;
 
+fpswa_ret_t fpswa_ret; /* save return values of FPSWA emulation */
 struct timer hlt_timer;
 struct arch_vmx_struct arch_vmx; /* Virtual Machine Extensions */
 

-- 
yamahata

___
Xen-ia64-devel mailing list
Xen-ia64-devel@lists.xensource.com
http://lists.xensource.com/xen-ia64-devel