diff --git a/xen/arch/x86/hvm/hpet.c b/xen/arch/x86/hvm/hpet.c index be371ecc0b..a916758106 100644 --- 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 array_access_nospec(h->hpet.timers, HPET_TN(CFG, addr)).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), + ARRAY_SIZE(h->hpet.timers)), + 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 array_access_nospec(h->hpet.timers, HPET_TN(ROUTE, addr)).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), ARRAY_SIZE(h->hpet.timers)); 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), ARRAY_SIZE(h->hpet.timers)); if ( timer_is_periodic(h, tn) && !(h->hpet.timers[tn].config & HPET_TN_SETVAL) ) { @@ -523,8 +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); - h->hpet.timers[tn].fsb = new_val; + array_access_nospec(h->hpet.timers, HPET_TN(ROUTE, addr)).fsb = new_val; break; default: diff --git a/xen/include/xen/nospec.h b/xen/include/xen/nospec.h index 48793996e8..8acfa60f1b 100644 --- a/xen/include/xen/nospec.h +++ b/xen/include/xen/nospec.h @@ -58,6 +58,12 @@ static inline unsigned long array_index_mask_nospec(unsigned long index, (typeof(_i)) (_i & _mask); \ }) +/* + * array_access_nospec - allow nospec access for static size arrays + */ +#define array_access_nospec(array, index) \ + (array)[array_index_nospec(index, ARRAY_SIZE(array))] + #endif /* XEN_NOSPEC_H */ /*