[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen stable-4.4] xen/arm: Correctly save/restore CNTKCTL_EL1



commit 9a9e59e4080122a45de347a74f0b366731b95a09
Author:     Julien Grall <julien.grall@xxxxxxxxxx>
AuthorDate: Thu May 1 11:55:14 2014 +0100
Commit:     Ian Campbell <ian.campbell@xxxxxxxxxx>
CommitDate: Thu May 1 13:57:21 2014 +0100

    xen/arm: Correctly save/restore CNTKCTL_EL1
    
    CNTKCTL_EL1 is used by the guest to control access to the timer from
    userspace.  It therefore needs to be save/restored by Xen as part of
    the VCPU state.
    
    By default Linux on ARM64 exposes the timer to userspace.  Furthermore on
    ARM64, Linux provides helpers in a VDSO (gettimeofday/__do_get_tspec)
    that use the timer counter.  Conversely, during CPU bring up, Xen will
    set CNTKCTL_EL1 to 0 (i.e disallow timer access to the userspace).  As
    a result, currently, if dom0 has 1 VCPU which is migrated to another
    PCPU, init might crash.
    
    Alternatively, a guest (malicious or not) might decide to disable
    access to the timer from userspace.  If the register is not
    save/restored, when a DOM0 VCPU runs again, a similar crash would
    result.
    
    Also, drop CNTKCTL_EL1 initialization in init_timer_interrupt.  Xen
    should let the guest deal with this register.
    
    This is XSA-91 / CVE-2014-3125.
    
    Reported-by: Chen Baozi <baozich@xxxxxxxxx>
    Signed-off-by: Julien Grall <julien.grall@xxxxxxxxxx>
    Signed-off-by: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
    Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
---
 xen/arch/arm/domain.c        |    2 ++
 xen/arch/arm/time.c          |    1 -
 xen/include/asm-arm/domain.h |    3 +++
 3 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 8f20fdf..ba07846 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -72,6 +72,7 @@ static void ctxt_switch_from(struct vcpu *p)
     p->arch.tpidr_el1 = READ_SYSREG(TPIDR_EL1);
 
     /* Arch timer */
+    p->arch.cntkctl = READ_SYSREG32(CNTKCTL_EL1);
     virt_timer_save(p);
 
     if ( is_pv32_domain(p->domain) && cpu_has_thumbee )
@@ -224,6 +225,7 @@ static void ctxt_switch_to(struct vcpu *n)
 
     /* This is could trigger an hardware interrupt from the virtual
      * timer. The interrupt needs to be injected into the guest. */
+    WRITE_SYSREG32(n->arch.cntkctl, CNTKCTL_EL1);
     virt_timer_restore(n);
 }
 
diff --git a/xen/arch/arm/time.c b/xen/arch/arm/time.c
index 81e3e28..5374bf7 100644
--- a/xen/arch/arm/time.c
+++ b/xen/arch/arm/time.c
@@ -234,7 +234,6 @@ void __cpuinit init_timer_interrupt(void)
 {
     /* Sensible defaults */
     WRITE_SYSREG64(0, CNTVOFF_EL2);     /* No VM-specific offset */
-    WRITE_SYSREG32(0, CNTKCTL_EL1);     /* No user-mode access */
 #if USE_HYP_TIMER
     /* Do not let the VMs program the physical timer, only read the physical 
counter */
     WRITE_SYSREG32(CNTHCTL_PA, CNTHCTL_EL2);
diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
index bc20a15..49f64b8 100644
--- a/xen/include/asm-arm/domain.h
+++ b/xen/include/asm-arm/domain.h
@@ -283,6 +283,9 @@ struct arch_vcpu
         spinlock_t lock;
     } vgic;
 
+    /* Timer registers  */
+    uint32_t cntkctl;
+
     struct vtimer phys_timer;
     struct vtimer virt_timer;
 }  __cacheline_aligned;
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.4

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.