[IA64] vcpu_setcontext: only set cr_irr if VGCF_SET_CR_IRR flag is set.
authorAlex Williamson <alex.williamson@hp.com>
Wed, 28 Nov 2007 19:32:28 +0000 (12:32 -0700)
committerAlex Williamson <alex.williamson@hp.com>
Wed, 28 Nov 2007 19:32:28 +0000 (12:32 -0700)
cr_irr can be modified even when a vcpu is blocked (by itv handler).
Unconditionally setting cr_irr can trouble debugger as it may clear a bit
of cr_irr and thus miss an interrupt.  This can be very annoying if the
interrupt is itv and the vcpu is inside PAL_HALT_LIGHT (the vcpu stays
blocked forever).

Signed-off-by: Tristan Gingold <tgingold@free.fr>
tools/libxc/ia64/xc_ia64_linux_restore.c
xen/arch/ia64/vmx/vmx_vcpu_save.c
xen/include/public/arch-ia64.h

index 271a7297aaa775401a4bc0629cd1e43fb799fe65..528eef67e2fdf0b8230e6f94955727bcbb83383c 100644 (file)
@@ -127,7 +127,7 @@ xc_ia64_recv_vcpu_context(int xc_handle, int io_fd, uint32_t dom,
     fprintf(stderr, "ip=%016lx, b0=%016lx\n", ctxt->regs.ip, ctxt->regs.b[0]);
 
     /* Initialize and set registers.  */
-    ctxt->flags = VGCF_EXTRA_REGS;
+    ctxt->flags = VGCF_EXTRA_REGS | VGCF_SET_CR_IRR;
     if (xc_vcpu_setcontext(xc_handle, dom, vcpu, ctxt) != 0) {
         ERROR("Couldn't set vcpu context");
         return -1;
index f435bddd1fe688f7df4fcd842993ddfb0a42ed88..db55279c64f1c9ff02717a3bcbc8f218158ee096 100644 (file)
@@ -118,8 +118,8 @@ vmx_arch_set_info_guest(struct vcpu *v, vcpu_guest_context_u c)
     unsigned long vnat;
     unsigned long vbnat;
 
-     union vcpu_ar_regs *ar = &c.nat->regs.ar;
-     union vcpu_cr_regs *cr = &c.nat->regs.cr;
+    union vcpu_ar_regs *ar = &c.nat->regs.ar;
+    union vcpu_cr_regs *cr = &c.nat->regs.cr;
     int i;
 
     // banked registers
@@ -177,13 +177,15 @@ vmx_arch_set_info_guest(struct vcpu *v, vcpu_guest_context_u c)
     vpd_low->iim = cr->iim;
     vpd_low->iha = cr->iha;
     vpd_low->lid = cr->lid;
-    vpd_low->ivr = cr->ivr; //XXX vlsapic
     vpd_low->tpr = cr->tpr;
+    vpd_low->ivr = cr->ivr; //XXX vlsapic
     vpd_low->eoi = cr->eoi;
-    vpd_low->irr[0] = cr->irr[0];
-    vpd_low->irr[1] = cr->irr[1];
-    vpd_low->irr[2] = cr->irr[2];
-    vpd_low->irr[3] = cr->irr[3];
+    if (c.nat->flags & VGCF_SET_CR_IRR) {
+        vpd_low->irr[0] = cr->irr[0];
+        vpd_low->irr[1] = cr->irr[1];
+        vpd_low->irr[2] = cr->irr[2];
+        vpd_low->irr[3] = cr->irr[3];
+    }
     vpd_low->itv = cr->itv;
     vpd_low->pmv = cr->pmv;
     vpd_low->cmcv = cr->cmcv;
index 805f793d241a2a5682784e4a9c3445eaca7aa6e7..9fd63b1787d17b540997678e260e469810b23bbb 100644 (file)
@@ -435,6 +435,7 @@ struct vcpu_guest_context_regs {
 
 struct vcpu_guest_context {
 #define VGCF_EXTRA_REGS (1UL << 1)     /* Set extra regs.  */
+#define VGCF_SET_CR_IRR (1UL << 2)     /* Set cr_irr[0:3]. */
     unsigned long flags;       /* VGCF_* flags */
 
     struct vcpu_guest_context_regs regs;