@@ -34,15 +34,15 @@ static inline struct pi_desc *vcpu_to_pi_desc(struct kvm_vcpu *vcpu)
34
34
return & (to_vmx (vcpu )-> pi_desc );
35
35
}
36
36
37
- static int pi_try_set_control (struct pi_desc * pi_desc , u64 old , u64 new )
37
+ static int pi_try_set_control (struct pi_desc * pi_desc , u64 * pold , u64 new )
38
38
{
39
39
/*
40
40
* PID.ON can be set at any time by a different vCPU or by hardware,
41
41
* e.g. a device. PID.control must be written atomically, and the
42
42
* update must be retried with a fresh snapshot an ON change causes
43
43
* the cmpxchg to fail.
44
44
*/
45
- if (!try_cmpxchg64 (& pi_desc -> control , & old , new ))
45
+ if (!try_cmpxchg64 (& pi_desc -> control , pold , new ))
46
46
return - EBUSY ;
47
47
48
48
return 0 ;
@@ -96,8 +96,9 @@ void vmx_vcpu_pi_load(struct kvm_vcpu *vcpu, int cpu)
96
96
if (!x2apic_mode )
97
97
dest = (dest << 8 ) & 0xFF00 ;
98
98
99
+ old .control = READ_ONCE (pi_desc -> control );
99
100
do {
100
- old .control = new .control = READ_ONCE ( pi_desc -> control ) ;
101
+ new .control = old .control ;
101
102
102
103
/*
103
104
* Clear SN (as above) and refresh the destination APIC ID to
@@ -111,7 +112,7 @@ void vmx_vcpu_pi_load(struct kvm_vcpu *vcpu, int cpu)
111
112
* descriptor was modified on "put" to use the wakeup vector.
112
113
*/
113
114
new .nv = POSTED_INTR_VECTOR ;
114
- } while (pi_try_set_control (pi_desc , old .control , new .control ));
115
+ } while (pi_try_set_control (pi_desc , & old .control , new .control ));
115
116
116
117
local_irq_restore (flags );
117
118
@@ -156,12 +157,12 @@ static void pi_enable_wakeup_handler(struct kvm_vcpu *vcpu)
156
157
157
158
WARN (pi_desc -> sn , "PI descriptor SN field set before blocking" );
158
159
160
+ old .control = READ_ONCE (pi_desc -> control );
159
161
do {
160
- old .control = new .control = READ_ONCE (pi_desc -> control );
161
-
162
162
/* set 'NV' to 'wakeup vector' */
163
+ new .control = old .control ;
163
164
new .nv = POSTED_INTR_WAKEUP_VECTOR ;
164
- } while (pi_try_set_control (pi_desc , old .control , new .control ));
165
+ } while (pi_try_set_control (pi_desc , & old .control , new .control ));
165
166
166
167
/*
167
168
* Send a wakeup IPI to this CPU if an interrupt may have been posted
0 commit comments