From 3bd85bcd904b57fa1898a99ff36dbad65706e84b Mon Sep 17 00:00:00 2001 From: Norbert Manthey Subject: [PATCH SpectreV1+L1TF 11/13] x86/hvm/hpet: block speculative out-of-bound accesses When interacting with hpet, read and write operations can be executed during instruction emulation, where the guest controls the data that is used. As it is hard to predict the number of instructions that are executed speculatively, we prevent out-of-bound accesses by using the array_index_nospec function for guest specified addresses that should be used for hpet operations. This is part of the SpectreV1+L1TF mitigation patch series. Signed-off-by: Norbert Manthey --- xen/arch/x86/hvm/hpet.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/xen/arch/x86/hvm/hpet.c b/xen/arch/x86/hvm/hpet.c --- a/xen/arch/x86/hvm/hpet.c +++ b/xen/arch/x86/hvm/hpet.c @@ -25,6 +25,7 @@ #include #include #include +#include #define domain_vhpet(x) (&(x)->arch.hvm.pl_time->vhpet) #define vcpu_vhpet(x) (domain_vhpet((x)->domain)) @@ -124,15 +125,18 @@ static inline uint64_t hpet_read64(HPETState *h, unsigned long addr, case HPET_Tn_CFG(0): case HPET_Tn_CFG(1): case HPET_Tn_CFG(2): - return h->hpet.timers[HPET_TN(CFG, addr)].config; + return h->hpet.timers[array_index_nospec(HPET_TN(CFG, addr), + HPET_TIMER_NUM)].config; case HPET_Tn_CMP(0): case HPET_Tn_CMP(1): case HPET_Tn_CMP(2): - return hpet_get_comparator(h, HPET_TN(CMP, addr), guest_time); + return hpet_get_comparator(h, array_index_nospec(HPET_TN(CMP, addr), + HPET_TIMER_NUM), guest_time); case HPET_Tn_ROUTE(0): case HPET_Tn_ROUTE(1): case HPET_Tn_ROUTE(2): - return h->hpet.timers[HPET_TN(ROUTE, addr)].fsb; + return h->hpet.timers[array_index_nospec(HPET_TN(ROUTE, addr), + HPET_TIMER_NUM)].fsb; } return 0; @@ -438,7 +442,7 @@ static int hpet_write( case HPET_Tn_CFG(0): case HPET_Tn_CFG(1): case HPET_Tn_CFG(2): - tn = HPET_TN(CFG, addr); + tn = array_index_nospec(HPET_TN(CFG, addr), HPET_TIMER_NUM); h->hpet.timers[tn].config = hpet_fixup_reg(new_val, old_val, @@ -480,7 +484,7 @@ static int hpet_write( case HPET_Tn_CMP(0): case HPET_Tn_CMP(1): case HPET_Tn_CMP(2): - tn = HPET_TN(CMP, addr); + tn = array_index_nospec(HPET_TN(CMP, addr), HPET_TIMER_NUM); if ( timer_is_periodic(h, tn) && !(h->hpet.timers[tn].config & HPET_TN_SETVAL) ) { @@ -523,7 +527,7 @@ static int hpet_write( case HPET_Tn_ROUTE(0): case HPET_Tn_ROUTE(1): case HPET_Tn_ROUTE(2): - tn = HPET_TN(ROUTE, addr); + tn = array_index_nospec(HPET_TN(ROUTE, addr), HPET_TIMER_NUM); h->hpet.timers[tn].fsb = new_val; break; -- 2.7.4