| .. | .. |
|---|
| 10 | 10 | #define KVM_APIC_SIPI 1 |
|---|
| 11 | 11 | #define KVM_APIC_LVT_NUM 6 |
|---|
| 12 | 12 | |
|---|
| 13 | | -#define KVM_APIC_SHORT_MASK 0xc0000 |
|---|
| 14 | | -#define KVM_APIC_DEST_MASK 0x800 |
|---|
| 13 | +#define APIC_SHORT_MASK 0xc0000 |
|---|
| 14 | +#define APIC_DEST_NOSHORT 0x0 |
|---|
| 15 | +#define APIC_DEST_MASK 0x800 |
|---|
| 15 | 16 | |
|---|
| 16 | 17 | #define APIC_BUS_CYCLE_NS 1 |
|---|
| 17 | 18 | #define APIC_BUS_FREQUENCY (1000000000ULL / APIC_BUS_CYCLE_NS) |
|---|
| 19 | + |
|---|
| 20 | +#define APIC_BROADCAST 0xFF |
|---|
| 21 | +#define X2APIC_BROADCAST 0xFFFFFFFFul |
|---|
| 18 | 22 | |
|---|
| 19 | 23 | enum lapic_mode { |
|---|
| 20 | 24 | LAPIC_MODE_DISABLED = 0, |
|---|
| .. | .. |
|---|
| 31 | 35 | u32 timer_mode_mask; |
|---|
| 32 | 36 | u64 tscdeadline; |
|---|
| 33 | 37 | u64 expired_tscdeadline; |
|---|
| 38 | + u32 timer_advance_ns; |
|---|
| 39 | + s64 advance_expire_delta; |
|---|
| 34 | 40 | atomic_t pending; /* accumulated triggered timers */ |
|---|
| 35 | 41 | bool hv_timer_in_use; |
|---|
| 36 | 42 | }; |
|---|
| .. | .. |
|---|
| 62 | 68 | |
|---|
| 63 | 69 | struct dest_map; |
|---|
| 64 | 70 | |
|---|
| 65 | | -int kvm_create_lapic(struct kvm_vcpu *vcpu); |
|---|
| 71 | +int kvm_create_lapic(struct kvm_vcpu *vcpu, int timer_advance_ns); |
|---|
| 66 | 72 | void kvm_free_lapic(struct kvm_vcpu *vcpu); |
|---|
| 67 | 73 | |
|---|
| 68 | 74 | int kvm_apic_has_interrupt(struct kvm_vcpu *vcpu); |
|---|
| .. | .. |
|---|
| 75 | 81 | void kvm_lapic_set_eoi(struct kvm_vcpu *vcpu); |
|---|
| 76 | 82 | void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value); |
|---|
| 77 | 83 | u64 kvm_lapic_get_base(struct kvm_vcpu *vcpu); |
|---|
| 84 | +void kvm_recalculate_apic_map(struct kvm *kvm); |
|---|
| 78 | 85 | void kvm_apic_set_version(struct kvm_vcpu *vcpu); |
|---|
| 79 | 86 | int kvm_lapic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val); |
|---|
| 80 | 87 | int kvm_lapic_reg_read(struct kvm_lapic *apic, u32 offset, int len, |
|---|
| 81 | 88 | void *data); |
|---|
| 82 | 89 | bool kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, |
|---|
| 83 | | - int short_hand, unsigned int dest, int dest_mode); |
|---|
| 84 | | - |
|---|
| 90 | + int shorthand, unsigned int dest, int dest_mode); |
|---|
| 91 | +int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2); |
|---|
| 92 | +void kvm_apic_clear_irr(struct kvm_vcpu *vcpu, int vec); |
|---|
| 85 | 93 | bool __kvm_apic_update_irr(u32 *pir, void *regs, int *max_irr); |
|---|
| 86 | 94 | bool kvm_apic_update_irr(struct kvm_vcpu *vcpu, u32 *pir, int *max_irr); |
|---|
| 87 | 95 | void kvm_apic_update_ppr(struct kvm_vcpu *vcpu); |
|---|
| 88 | 96 | int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq, |
|---|
| 89 | 97 | struct dest_map *dest_map); |
|---|
| 90 | 98 | int kvm_apic_local_deliver(struct kvm_lapic *apic, int lvt_type); |
|---|
| 99 | +void kvm_apic_update_apicv(struct kvm_vcpu *vcpu); |
|---|
| 91 | 100 | |
|---|
| 92 | 101 | bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, struct kvm_lapic *src, |
|---|
| 93 | 102 | struct kvm_lapic_irq *irq, int *r, struct dest_map *dest_map); |
|---|
| 103 | +void kvm_apic_send_ipi(struct kvm_lapic *apic, u32 icr_low, u32 icr_high); |
|---|
| 94 | 104 | |
|---|
| 95 | 105 | u64 kvm_get_apic_base(struct kvm_vcpu *vcpu); |
|---|
| 96 | 106 | int kvm_set_apic_base(struct kvm_vcpu *vcpu, struct msr_data *msr_info); |
|---|
| .. | .. |
|---|
| 127 | 137 | #define VEC_POS(v) ((v) & (32 - 1)) |
|---|
| 128 | 138 | #define REG_POS(v) (((v) >> 5) << 4) |
|---|
| 129 | 139 | |
|---|
| 140 | +static inline void kvm_lapic_clear_vector(int vec, void *bitmap) |
|---|
| 141 | +{ |
|---|
| 142 | + clear_bit(VEC_POS(vec), (bitmap) + REG_POS(vec)); |
|---|
| 143 | +} |
|---|
| 144 | + |
|---|
| 130 | 145 | static inline void kvm_lapic_set_vector(int vec, void *bitmap) |
|---|
| 131 | 146 | { |
|---|
| 132 | 147 | set_bit(VEC_POS(vec), (bitmap) + REG_POS(vec)); |
|---|
| .. | .. |
|---|
| 147 | 162 | return *((u32 *) (apic->regs + reg_off)); |
|---|
| 148 | 163 | } |
|---|
| 149 | 164 | |
|---|
| 165 | +static inline void __kvm_lapic_set_reg(char *regs, int reg_off, u32 val) |
|---|
| 166 | +{ |
|---|
| 167 | + *((u32 *) (regs + reg_off)) = val; |
|---|
| 168 | +} |
|---|
| 169 | + |
|---|
| 150 | 170 | static inline void kvm_lapic_set_reg(struct kvm_lapic *apic, int reg_off, u32 val) |
|---|
| 151 | 171 | { |
|---|
| 152 | | - *((u32 *) (apic->regs + reg_off)) = val; |
|---|
| 172 | + __kvm_lapic_set_reg(apic->regs, reg_off, val); |
|---|
| 153 | 173 | } |
|---|
| 154 | 174 | |
|---|
| 155 | 175 | extern struct static_key kvm_no_apic_vcpu; |
|---|
| .. | .. |
|---|
| 217 | 237 | |
|---|
| 218 | 238 | bool kvm_apic_pending_eoi(struct kvm_vcpu *vcpu, int vector); |
|---|
| 219 | 239 | |
|---|
| 220 | | -void wait_lapic_expire(struct kvm_vcpu *vcpu); |
|---|
| 240 | +void kvm_wait_lapic_expire(struct kvm_vcpu *vcpu); |
|---|
| 241 | + |
|---|
| 242 | +void kvm_bitmap_or_dest_vcpus(struct kvm *kvm, struct kvm_lapic_irq *irq, |
|---|
| 243 | + unsigned long *vcpu_bitmap); |
|---|
| 221 | 244 | |
|---|
| 222 | 245 | bool kvm_intr_is_single_vcpu_fast(struct kvm *kvm, struct kvm_lapic_irq *irq, |
|---|
| 223 | 246 | struct kvm_vcpu **dest_vcpu); |
|---|
| .. | .. |
|---|
| 228 | 251 | void kvm_lapic_expired_hv_timer(struct kvm_vcpu *vcpu); |
|---|
| 229 | 252 | bool kvm_lapic_hv_timer_in_use(struct kvm_vcpu *vcpu); |
|---|
| 230 | 253 | void kvm_lapic_restart_hv_timer(struct kvm_vcpu *vcpu); |
|---|
| 254 | +bool kvm_can_use_hv_timer(struct kvm_vcpu *vcpu); |
|---|
| 231 | 255 | |
|---|
| 232 | 256 | static inline enum lapic_mode kvm_apic_mode(u64 apic_base) |
|---|
| 233 | 257 | { |
|---|
| 234 | 258 | return apic_base & (MSR_IA32_APICBASE_ENABLE | X2APIC_ENABLE); |
|---|
| 235 | 259 | } |
|---|
| 236 | 260 | |
|---|
| 261 | +static inline u8 kvm_xapic_id(struct kvm_lapic *apic) |
|---|
| 262 | +{ |
|---|
| 263 | + return kvm_lapic_get_reg(apic, APIC_ID) >> 24; |
|---|
| 264 | +} |
|---|
| 265 | + |
|---|
| 237 | 266 | #endif |
|---|