# HG changeset patch
# User Alex Williamson <alex.williamson@xxxxxx>
# Date 1179165121 21600
# Node ID fd72e71de51a53f865e4e82d2bcca1c7664c9b04
# Parent c0de8feef4cda1cfe6bd926f8b9adbc1fbc8589b
[IA64] Fix ptc.ga emulation
cset14829(c42ae7839750) was incomplete.
The region register 0 will be clobbered as follows.
time pcpu0 pcpu1 pcpu2
| vcpu0 vcpu1 idle // assignment of vcpu
V
1.vcpu0 issues ptc.ga
2.vcpu0 sends IPI to vcpu1(pcpu1)
3.vcpu1 migrates from pcpu1 to pcpu2
4.pcpu1 receives IPI of 2 and exec ptc_ga_remote_func()
5.pcpu1 saves and modifies vrr[0]
6.vcpu1(pcpu2) modifies vrr[0]
7.pcpu1 restores vrr[0] // vrr[0] of 6 is lost
Windows will crash due to this issue.
Signed-off-by: Kouya Shimura <kouya@xxxxxxxxxxxxxx>
---
xen/arch/ia64/vmx/vmmu.c | 42 ++++++++++++++++++++++--------------------
1 files changed, 22 insertions(+), 20 deletions(-)
diff -r c0de8feef4cd -r fd72e71de51a xen/arch/ia64/vmx/vmmu.c
--- a/xen/arch/ia64/vmx/vmmu.c Mon May 14 11:13:24 2007 -0600
+++ b/xen/arch/ia64/vmx/vmmu.c Mon May 14 11:52:01 2007 -0600
@@ -563,11 +563,17 @@ struct ptc_ga_args {
static void ptc_ga_remote_func (void *varg)
{
- u64 oldrid, moldrid, mpta, oldpsbits, vadr;
+ u64 oldrid, moldrid, mpta, oldpsbits, vadr, flags;
struct ptc_ga_args *args = (struct ptc_ga_args *)varg;
VCPU *v = args->vcpu;
vadr = args->vadr;
+ /* Try again if VCPU has migrated. */
+ if (v->processor != current->processor)
+ return;
+ vcpu_schedule_lock_irqsave(v, flags);
+ if (v->processor != current->processor)
+ goto bail;
oldrid = VMX(v, vrr[0]);
VMX(v, vrr[0]) = args->rid;
oldpsbits = VMX(v, psbits[0]);
@@ -584,6 +590,9 @@ static void ptc_ga_remote_func (void *va
ia64_set_rr(0x0,moldrid);
ia64_set_pta(mpta);
ia64_dv_serialize_data();
+ args->vcpu = NULL;
+bail:
+ vcpu_schedule_unlock_irqrestore(v, flags);
}
@@ -602,28 +611,21 @@ IA64FAULT vmx_vcpu_ptc_ga(VCPU *vcpu, u6
if (!v->is_initialised)
continue;
+ if (v == vcpu) {
+ vmx_vcpu_ptc_l(v, va, ps);
+ continue;
+ }
+
args.vcpu = v;
-again: /* Try again if VCPU has migrated. */
- proc = v->processor;
- if (proc != vcpu->processor) {
- /* Flush VHPT on remote processors. */
- smp_call_function_single(v->processor,
- &ptc_ga_remote_func, &args, 0, 1);
- if (proc != v->processor)
- goto again;
- } else if (v == vcpu) {
- vmx_vcpu_ptc_l(v, va, ps);
- } else {
- vcpu_schedule_lock_irq(v);
+ do {
proc = v->processor;
- if (proc == vcpu->processor)
+ if (proc != vcpu->processor)
+ /* Flush VHPT on remote processors. */
+ smp_call_function_single(proc, &ptc_ga_remote_func,
+ &args, 0, 1);
+ else
ptc_ga_remote_func(&args);
- else
- proc = INVALID_PROCESSOR;
- vcpu_schedule_unlock_irq(v);
- if (proc == INVALID_PROCESSOR)
- goto again;
- }
+ } while (args.vcpu != NULL);
}
return IA64_NO_FAULT;
}
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|