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>
This commit is contained in:
Родитель
b223649576
Коммит
b5fcc59be7
|
@ -1561,12 +1561,9 @@ static inline struct kvm_lapic *to_lapic(struct kvm_io_device *dev)
|
|||
#define APIC_REGS_MASK(first, count) \
|
||||
(APIC_REG_MASK(first) * ((1ull << (count)) - 1))
|
||||
|
||||
static int kvm_lapic_reg_read(struct kvm_lapic *apic, u32 offset, int len,
|
||||
void *data)
|
||||
u64 kvm_lapic_readable_reg_mask(struct kvm_lapic *apic)
|
||||
{
|
||||
unsigned char alignment = offset & 0xf;
|
||||
u32 result;
|
||||
/* this bitmask has a bit cleared for each reserved register */
|
||||
/* Leave bits '0' for reserved and write-only registers. */
|
||||
u64 valid_reg_mask =
|
||||
APIC_REG_MASK(APIC_ID) |
|
||||
APIC_REG_MASK(APIC_LVR) |
|
||||
|
@ -1592,22 +1589,33 @@ static int kvm_lapic_reg_read(struct kvm_lapic *apic, u32 offset, int len,
|
|||
if (kvm_lapic_lvt_supported(apic, LVT_CMCI))
|
||||
valid_reg_mask |= APIC_REG_MASK(APIC_LVTCMCI);
|
||||
|
||||
/*
|
||||
* ARBPRI, DFR, and ICR2 are not valid in x2APIC mode. WARN if KVM
|
||||
* reads ICR in x2APIC mode as it's an 8-byte register in x2APIC and
|
||||
* needs to be manually handled by the caller.
|
||||
*/
|
||||
/* ARBPRI, DFR, and ICR2 are not valid in x2APIC mode. */
|
||||
if (!apic_x2apic_mode(apic))
|
||||
valid_reg_mask |= APIC_REG_MASK(APIC_ARBPRI) |
|
||||
APIC_REG_MASK(APIC_DFR) |
|
||||
APIC_REG_MASK(APIC_ICR2);
|
||||
else
|
||||
WARN_ON_ONCE(offset == APIC_ICR);
|
||||
|
||||
return valid_reg_mask;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kvm_lapic_readable_reg_mask);
|
||||
|
||||
static int kvm_lapic_reg_read(struct kvm_lapic *apic, u32 offset, int len,
|
||||
void *data)
|
||||
{
|
||||
unsigned char alignment = offset & 0xf;
|
||||
u32 result;
|
||||
|
||||
/*
|
||||
* WARN if KVM reads ICR in x2APIC mode, as it's an 8-byte register in
|
||||
* x2APIC and needs to be manually handled by the caller.
|
||||
*/
|
||||
WARN_ON_ONCE(apic_x2apic_mode(apic) && offset == APIC_ICR);
|
||||
|
||||
if (alignment + len > 4)
|
||||
return 1;
|
||||
|
||||
if (offset > 0x3f0 || !(valid_reg_mask & APIC_REG_MASK(offset)))
|
||||
if (offset > 0x3f0 ||
|
||||
!(kvm_lapic_readable_reg_mask(apic) & APIC_REG_MASK(offset)))
|
||||
return 1;
|
||||
|
||||
result = __apic_read(apic, offset & ~0xf);
|
||||
|
|
|
@ -146,6 +146,8 @@ int kvm_hv_vapic_msr_read(struct kvm_vcpu *vcpu, u32 msr, u64 *data);
|
|||
int kvm_lapic_set_pv_eoi(struct kvm_vcpu *vcpu, u64 data, unsigned long len);
|
||||
void kvm_lapic_exit(void);
|
||||
|
||||
u64 kvm_lapic_readable_reg_mask(struct kvm_lapic *apic);
|
||||
|
||||
#define VEC_POS(v) ((v) & (32 - 1))
|
||||
#define REG_POS(v) (((v) >> 5) << 4)
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче