[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH for-4.21??? 1/3] x86/vLAPIC: add indirection to LVT handling
In preparation to add support for the CMCI LVT, which is discontiguous to the other LVTs, add a level of indirection. Rename the prior vlapic_lvt_mask[] while doing so (as subsequently a 2nd array will want adding, for use by guest_wrmsr_x2apic()). Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> --- The new name (lvt_valid[]) reflects its present contents. When re-based on top of "x86/hvm: vlapic: fix RO bits emulation in LVTx regs", the name wants to change to lvt_writable[] (or the 2nd array be added right away, with lvt_valid[] then used by guest_wrmsr_x2apic()). Alternatively the order of patches may want changing. --- a/xen/arch/x86/hvm/vlapic.c +++ b/xen/arch/x86/hvm/vlapic.c @@ -32,7 +32,16 @@ #include <public/hvm/params.h> #define VLAPIC_VERSION 0x00050014 -#define VLAPIC_LVT_NUM 6 +#define LVT_BIAS(reg) (((reg) - APIC_LVTT) >> 4) + +#define LVTS \ + LVT(LVTT), LVT(LVTTHMR), LVT(LVTPC), LVT(LVT0), LVT(LVT1), LVT(LVTERR), + +static const unsigned int lvt_reg[] = { +#define LVT(which) APIC_ ## which + LVTS +#undef LVT +}; #define LVT_MASK \ (APIC_LVT_MASKED | APIC_SEND_PENDING | APIC_VECTOR_MASK) @@ -41,20 +50,21 @@ (LVT_MASK | APIC_DM_MASK | APIC_INPUT_POLARITY |\ APIC_LVT_REMOTE_IRR | APIC_LVT_LEVEL_TRIGGER) -static const unsigned int vlapic_lvt_mask[VLAPIC_LVT_NUM] = +static const unsigned int lvt_valid[] = { - /* LVTT */ - LVT_MASK | APIC_TIMER_MODE_MASK, - /* LVTTHMR */ - LVT_MASK | APIC_DM_MASK, - /* LVTPC */ - LVT_MASK | APIC_DM_MASK, - /* LVT0-1 */ - LINT_MASK, LINT_MASK, - /* LVTERR */ - LVT_MASK +#define LVTT_VALID (LVT_MASK | APIC_TIMER_MODE_MASK) +#define LVTTHMR_VALID (LVT_MASK | APIC_DM_MASK) +#define LVTPC_VALID (LVT_MASK | APIC_DM_MASK) +#define LVT0_VALID LINT_MASK +#define LVT1_VALID LINT_MASK +#define LVTERR_VALID LVT_MASK +#define LVT(which) [LVT_BIAS(APIC_ ## which)] = which ## _VALID + LVTS +#undef LVT }; +#undef LVTS + #define vlapic_lvtt_period(vlapic) \ ((vlapic_get_reg(vlapic, APIC_LVTT) & APIC_TIMER_MODE_MASK) \ == APIC_TIMER_MODE_PERIODIC) @@ -827,16 +837,16 @@ void vlapic_reg_write(struct vcpu *v, un if ( !(val & APIC_SPIV_APIC_ENABLED) ) { - int i; + unsigned int i, + nr = GET_APIC_MAXLVT(vlapic_get_reg(vlapic, APIC_LVR)) + 1; uint32_t lvt_val; vlapic->hw.disabled |= VLAPIC_SW_DISABLED; - for ( i = 0; i < VLAPIC_LVT_NUM; i++ ) + for ( i = 0; i < nr; i++ ) { - lvt_val = vlapic_get_reg(vlapic, APIC_LVTT + 0x10 * i); - vlapic_set_reg(vlapic, APIC_LVTT + 0x10 * i, - lvt_val | APIC_LVT_MASKED); + lvt_val = vlapic_get_reg(vlapic, lvt_reg[i]); + vlapic_set_reg(vlapic, lvt_reg[i], lvt_val | APIC_LVT_MASKED); } } else @@ -878,7 +888,7 @@ void vlapic_reg_write(struct vcpu *v, un case APIC_LVTERR: /* LVT Error Reg */ if ( vlapic_sw_disabled(vlapic) ) val |= APIC_LVT_MASKED; - val &= array_access_nospec(vlapic_lvt_mask, (reg - APIC_LVTT) >> 4); + val &= array_access_nospec(lvt_valid, LVT_BIAS(reg)); vlapic_set_reg(vlapic, reg, val); if ( reg == APIC_LVT0 ) { @@ -1424,7 +1434,7 @@ bool is_vlapic_lvtpc_enabled(struct vlap /* Reset the VLAPIC back to its init state. */ static void vlapic_do_init(struct vlapic *vlapic) { - int i; + unsigned int i, nr; if ( !has_vlapic(vlapic_vcpu(vlapic)->domain) ) return; @@ -1452,8 +1462,9 @@ static void vlapic_do_init(struct vlapic vlapic_set_reg(vlapic, APIC_DFR, 0xffffffffU); - for ( i = 0; i < VLAPIC_LVT_NUM; i++ ) - vlapic_set_reg(vlapic, APIC_LVTT + 0x10 * i, APIC_LVT_MASKED); + nr = GET_APIC_MAXLVT(vlapic_get_reg(vlapic, APIC_LVR)) + 1; + for ( i = 0; i < nr; i++ ) + vlapic_set_reg(vlapic, lvt_reg[i], APIC_LVT_MASKED); vlapic_set_reg(vlapic, APIC_SPIV, 0xff); vlapic->hw.disabled |= VLAPIC_SW_DISABLED;
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |