[IA64] fix INIT injection.
authorIsaku Yamahata <yamahata@valinux.co.jp>
Thu, 18 Sep 2008 08:54:15 +0000 (17:54 +0900)
committerIsaku Yamahata <yamahata@valinux.co.jp>
Thu, 18 Sep 2008 08:54:15 +0000 (17:54 +0900)
xm trigger command sometimes causes an unexpected domain panic.
There are several symptoms:
 * Guest nested fault (INIT handler runs with vpsr.cpl != 0)
 * Interrupt when IC=0
 * Unexpected virtual <--> physical mode transition

Signed-off-by: Kouya Shimura <kouya@jp.fujitsu.com>
Signed-off-by: Kazuhiro Suzuki <kaz@jp.fujitsu.com>
xen/arch/ia64/vmx/vlsapic.c
xen/arch/ia64/vmx/vmx_phy_mode.c
xen/include/asm-ia64/vmx_phy_mode.h

index 124b4e892ba27b2ad73552e6e2ead70eff9bf850..e0a063afbfcab8b248c342a099231e6ad9e6ed12 100644 (file)
@@ -43,6 +43,7 @@
 #include <asm/vmx_platform.h>
 #include <asm/viosapic.h>
 #include <asm/vlsapic.h>
+#include <asm/vmx_phy_mode.h>
 #include <asm/linux/jiffies.h>
 #include <xen/domain.h>
 #include <asm/hvm/support.h>
@@ -614,9 +615,8 @@ struct vcpu *lid_to_vcpu(struct domain *d, uint16_t dest)
  * To inject INIT to guest, we must set the PAL_INIT entry 
  * and set psr to switch to physical mode
  */
-#define PAL_INIT_ENTRY 0x80000000ffffffa0
 #define PSR_SET_BITS (IA64_PSR_DT | IA64_PSR_IT | IA64_PSR_RT | \
-                      IA64_PSR_IC | IA64_PSR_RI)
+                      IA64_PSR_IC | IA64_PSR_RI | IA64_PSR_I | IA64_PSR_CPL)
 
 static void vmx_inject_guest_pal_init(VCPU *vcpu)
 {
index 5d347719604d9e589d9829fb42b065655a495297..096c41bc20e7701f7429146b3c952795da3d516f 100644 (file)
@@ -255,7 +255,12 @@ void
 switch_mm_mode(VCPU *vcpu, IA64_PSR old_psr, IA64_PSR new_psr)
 {
     int act;
-    act = mm_switch_action(old_psr, new_psr);
+    /* Switch to physical mode when injecting PAL_INIT */
+    if (unlikely(MODE_IND(new_psr) == 0 &&
+                 vcpu_regs(vcpu)->cr_iip == PAL_INIT_ENTRY))
+        act = SW_2P_DT;
+    else
+        act = mm_switch_action(old_psr, new_psr);
     perfc_incra(vmx_switch_mm_mode, act);
     switch (act) {
     case SW_2P_DT:
index a032fc795404fde1199aeaf6e5b953ea0b6a8e8b..91ffbc74a5f49b9c44ecdbad1675a9b77873cf94 100644 (file)
@@ -96,4 +96,6 @@ extern void physical_tlb_miss(VCPU *vcpu, u64 vadr, int type);
 #define VMX_MMU_PHY_D      1    /* Half physical: it=1,dt=0  */
 #define VMX_MMU_PHY_DT     3    /* Full physical mode: it=0,dt=0  */
 
+#define PAL_INIT_ENTRY 0x80000000ffffffa0
+
 #endif /* _PHY_MODE_H_ */