OSDN Git Service

kvm: LAPIC: write down valid APIC registers
authorPaolo Bonzini <pbonzini@redhat.com>
Fri, 5 Jul 2019 12:57:58 +0000 (14:57 +0200)
committerPaolo Bonzini <pbonzini@redhat.com>
Fri, 5 Jul 2019 13:32:59 +0000 (15:32 +0200)
Replace a magic 64-bit mask with a list of valid registers, computing
the same mask in the end.

Suggested-by: Liran Alon <liran.alon@oracle.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/lapic.c

index 2e4470f..e4227ce 100644 (file)
@@ -1312,25 +1312,45 @@ static inline struct kvm_lapic *to_lapic(struct kvm_io_device *dev)
        return container_of(dev, struct kvm_lapic, dev);
 }
 
+#define APIC_REG_MASK(reg)     (1ull << ((reg) >> 4))
+#define APIC_REGS_MASK(first, count) \
+       (APIC_REG_MASK(first) * ((1ull << (count)) - 1))
+
 int kvm_lapic_reg_read(struct kvm_lapic *apic, u32 offset, int len,
                void *data)
 {
        unsigned char alignment = offset & 0xf;
        u32 result;
        /* this bitmask has a bit cleared for each reserved register */
-       u64 rmask = 0x43ff01ffffffe70cULL;
-
-       if ((alignment + len) > 4) {
-               apic_debug("KVM_APIC_READ: alignment error %x %d\n",
-                          offset, len);
-               return 1;
-       }
-
-       /* ARBPRI is also reserved on x2APIC */
-       if (apic_x2apic_mode(apic))
-               rmask &= ~(1 << (APIC_ARBPRI >> 4));
+       u64 valid_reg_mask =
+               APIC_REG_MASK(APIC_ID) |
+               APIC_REG_MASK(APIC_LVR) |
+               APIC_REG_MASK(APIC_TASKPRI) |
+               APIC_REG_MASK(APIC_PROCPRI) |
+               APIC_REG_MASK(APIC_LDR) |
+               APIC_REG_MASK(APIC_DFR) |
+               APIC_REG_MASK(APIC_SPIV) |
+               APIC_REGS_MASK(APIC_ISR, APIC_ISR_NR) |
+               APIC_REGS_MASK(APIC_TMR, APIC_ISR_NR) |
+               APIC_REGS_MASK(APIC_IRR, APIC_ISR_NR) |
+               APIC_REG_MASK(APIC_ESR) |
+               APIC_REG_MASK(APIC_ICR) |
+               APIC_REG_MASK(APIC_ICR2) |
+               APIC_REG_MASK(APIC_LVTT) |
+               APIC_REG_MASK(APIC_LVTTHMR) |
+               APIC_REG_MASK(APIC_LVTPC) |
+               APIC_REG_MASK(APIC_LVT0) |
+               APIC_REG_MASK(APIC_LVT1) |
+               APIC_REG_MASK(APIC_LVTERR) |
+               APIC_REG_MASK(APIC_TMICT) |
+               APIC_REG_MASK(APIC_TMCCT) |
+               APIC_REG_MASK(APIC_TDCR);
+
+       /* ARBPRI is not valid on x2APIC */
+       if (!apic_x2apic_mode(apic))
+               valid_reg_mask |= APIC_REG_MASK(APIC_ARBPRI);
 
-       if (offset > 0x3f0 || !(rmask & (1ULL << (offset >> 4)))) {
+       if (offset > 0x3f0 || !(valid_reg_mask & APIC_REG_MASK(offset))) {
                apic_debug("KVM_APIC_READ: read reserved register %x\n",
                           offset);
                return 1;