.. | .. |
---|
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 |
---|