|
@@ -75,13 +75,30 @@ static bool synic_has_vector_auto_eoi(struct kvm_vcpu_hv_synic *synic,
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void synic_update_vector(struct kvm_vcpu_hv_synic *synic,
|
|
|
|
+ int vector)
|
|
|
|
+{
|
|
|
|
+ if (vector < HV_SYNIC_FIRST_VALID_VECTOR)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ if (synic_has_vector_connected(synic, vector))
|
|
|
|
+ __set_bit(vector, synic->vec_bitmap);
|
|
|
|
+ else
|
|
|
|
+ __clear_bit(vector, synic->vec_bitmap);
|
|
|
|
+
|
|
|
|
+ if (synic_has_vector_auto_eoi(synic, vector))
|
|
|
|
+ __set_bit(vector, synic->auto_eoi_bitmap);
|
|
|
|
+ else
|
|
|
|
+ __clear_bit(vector, synic->auto_eoi_bitmap);
|
|
|
|
+}
|
|
|
|
+
|
|
static int synic_set_sint(struct kvm_vcpu_hv_synic *synic, int sint,
|
|
static int synic_set_sint(struct kvm_vcpu_hv_synic *synic, int sint,
|
|
u64 data, bool host)
|
|
u64 data, bool host)
|
|
{
|
|
{
|
|
- int vector;
|
|
|
|
|
|
+ int vector, old_vector;
|
|
|
|
|
|
vector = data & HV_SYNIC_SINT_VECTOR_MASK;
|
|
vector = data & HV_SYNIC_SINT_VECTOR_MASK;
|
|
- if (vector < 16 && !host)
|
|
|
|
|
|
+ if (vector < HV_SYNIC_FIRST_VALID_VECTOR && !host)
|
|
return 1;
|
|
return 1;
|
|
/*
|
|
/*
|
|
* Guest may configure multiple SINTs to use the same vector, so
|
|
* Guest may configure multiple SINTs to use the same vector, so
|
|
@@ -89,18 +106,13 @@ static int synic_set_sint(struct kvm_vcpu_hv_synic *synic, int sint,
|
|
* bitmap of vectors with auto-eoi behavior. The bitmaps are
|
|
* bitmap of vectors with auto-eoi behavior. The bitmaps are
|
|
* updated here, and atomically queried on fast paths.
|
|
* updated here, and atomically queried on fast paths.
|
|
*/
|
|
*/
|
|
|
|
+ old_vector = synic_read_sint(synic, sint) & HV_SYNIC_SINT_VECTOR_MASK;
|
|
|
|
|
|
atomic64_set(&synic->sint[sint], data);
|
|
atomic64_set(&synic->sint[sint], data);
|
|
|
|
|
|
- if (synic_has_vector_connected(synic, vector))
|
|
|
|
- __set_bit(vector, synic->vec_bitmap);
|
|
|
|
- else
|
|
|
|
- __clear_bit(vector, synic->vec_bitmap);
|
|
|
|
|
|
+ synic_update_vector(synic, old_vector);
|
|
|
|
|
|
- if (synic_has_vector_auto_eoi(synic, vector))
|
|
|
|
- __set_bit(vector, synic->auto_eoi_bitmap);
|
|
|
|
- else
|
|
|
|
- __clear_bit(vector, synic->auto_eoi_bitmap);
|
|
|
|
|
|
+ synic_update_vector(synic, vector);
|
|
|
|
|
|
/* Load SynIC vectors into EOI exit bitmap */
|
|
/* Load SynIC vectors into EOI exit bitmap */
|
|
kvm_make_request(KVM_REQ_SCAN_IOAPIC, synic_to_vcpu(synic));
|
|
kvm_make_request(KVM_REQ_SCAN_IOAPIC, synic_to_vcpu(synic));
|