Skip to content

Commit b5fcc59

Browse files
committed
KVM: x86: Split out logic to generate "readable" APIC regs mask to helper
Move the generation of the readable APIC regs bitmask to a standalone helper so that VMX can use the mask for its MSR interception bitmaps. No functional change intended. Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com> Link: https://lore.kernel.org/r/20230107011025.565472-5-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent b223649 commit b5fcc59

2 files changed

Lines changed: 23 additions & 13 deletions

File tree

arch/x86/kvm/lapic.c

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1561,12 +1561,9 @@ static inline struct kvm_lapic *to_lapic(struct kvm_io_device *dev)
15611561
#define APIC_REGS_MASK(first, count) \
15621562
(APIC_REG_MASK(first) * ((1ull << (count)) - 1))
15631563

1564-
static int kvm_lapic_reg_read(struct kvm_lapic *apic, u32 offset, int len,
1565-
void *data)
1564+
u64 kvm_lapic_readable_reg_mask(struct kvm_lapic *apic)
15661565
{
1567-
unsigned char alignment = offset & 0xf;
1568-
u32 result;
1569-
/* this bitmask has a bit cleared for each reserved register */
1566+
/* Leave bits '0' for reserved and write-only registers. */
15701567
u64 valid_reg_mask =
15711568
APIC_REG_MASK(APIC_ID) |
15721569
APIC_REG_MASK(APIC_LVR) |
@@ -1592,22 +1589,33 @@ static int kvm_lapic_reg_read(struct kvm_lapic *apic, u32 offset, int len,
15921589
if (kvm_lapic_lvt_supported(apic, LVT_CMCI))
15931590
valid_reg_mask |= APIC_REG_MASK(APIC_LVTCMCI);
15941591

1595-
/*
1596-
* ARBPRI, DFR, and ICR2 are not valid in x2APIC mode. WARN if KVM
1597-
* reads ICR in x2APIC mode as it's an 8-byte register in x2APIC and
1598-
* needs to be manually handled by the caller.
1599-
*/
1592+
/* ARBPRI, DFR, and ICR2 are not valid in x2APIC mode. */
16001593
if (!apic_x2apic_mode(apic))
16011594
valid_reg_mask |= APIC_REG_MASK(APIC_ARBPRI) |
16021595
APIC_REG_MASK(APIC_DFR) |
16031596
APIC_REG_MASK(APIC_ICR2);
1604-
else
1605-
WARN_ON_ONCE(offset == APIC_ICR);
1597+
1598+
return valid_reg_mask;
1599+
}
1600+
EXPORT_SYMBOL_GPL(kvm_lapic_readable_reg_mask);
1601+
1602+
static int kvm_lapic_reg_read(struct kvm_lapic *apic, u32 offset, int len,
1603+
void *data)
1604+
{
1605+
unsigned char alignment = offset & 0xf;
1606+
u32 result;
1607+
1608+
/*
1609+
* WARN if KVM reads ICR in x2APIC mode, as it's an 8-byte register in
1610+
* x2APIC and needs to be manually handled by the caller.
1611+
*/
1612+
WARN_ON_ONCE(apic_x2apic_mode(apic) && offset == APIC_ICR);
16061613

16071614
if (alignment + len > 4)
16081615
return 1;
16091616

1610-
if (offset > 0x3f0 || !(valid_reg_mask & APIC_REG_MASK(offset)))
1617+
if (offset > 0x3f0 ||
1618+
!(kvm_lapic_readable_reg_mask(apic) & APIC_REG_MASK(offset)))
16111619
return 1;
16121620

16131621
result = __apic_read(apic, offset & ~0xf);

arch/x86/kvm/lapic.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ int kvm_hv_vapic_msr_read(struct kvm_vcpu *vcpu, u32 msr, u64 *data);
146146
int kvm_lapic_set_pv_eoi(struct kvm_vcpu *vcpu, u64 data, unsigned long len);
147147
void kvm_lapic_exit(void);
148148

149+
u64 kvm_lapic_readable_reg_mask(struct kvm_lapic *apic);
150+
149151
#define VEC_POS(v) ((v) & (32 - 1))
150152
#define REG_POS(v) (((v) >> 5) << 4)
151153

0 commit comments

Comments
 (0)