1
- From f6c3a183801123395e05959b7a6508bf420eb726 Mon Sep 17 00:00:00 2001
1
+ From 48bd0eb952cf1455b124fa06c348b801ef2254ad Mon Sep 17 00:00:00 2001
2
2
From: Patrick Roy <
[email protected] >
3
- Date: Tue, 3 Jun 2025 13:57:15 +0100
3
+ Date: Tue, 3 Jun 2025 15:32:13 +0100
4
4
Subject: [PATCH] de-gpc-ify kvm-clock
5
5
6
6
Signed-off-by: Patrick Roy <
[email protected] >
7
7
---
8
8
arch/x86/include/asm/kvm_host.h | 2 +-
9
- arch/x86/kvm/x86.c | 47 ++++++++++- ----------------------
10
- 2 files changed, 15 insertions(+), 34 deletions(-)
9
+ arch/x86/kvm/x86.c | 53 +++++++++++ ----------------------
10
+ 2 files changed, 19 insertions(+), 36 deletions(-)
11
11
12
12
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
13
- index ce9ad4cd93c5..6b2e9c2ee599 100644
13
+ index b874e54a5ee4..7cdef9002af8 100644
14
14
--- a/arch/x86/include/asm/kvm_host.h
15
15
+++ b/arch/x86/include/asm/kvm_host.h
16
- @@ -915 ,7 +915 ,7 @@ struct kvm_vcpu_arch {
17
- s8 pvclock_tsc_shift ;
18
- u32 pvclock_tsc_mul ;
16
+ @@ -911 ,7 +911 ,7 @@ struct kvm_vcpu_arch {
17
+ gpa_t time ;
18
+ struct pvclock_vcpu_time_info hv_clock ;
19
19
unsigned int hw_tsc_khz;
20
20
- struct gfn_to_pfn_cache pv_time;
21
21
+ gpa_t system_time;
22
22
/* set guest stopped flag in pvclock flags field */
23
23
bool pvclock_set_guest_stopped_request;
24
24
25
25
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
26
- index 2a02f2457c42..5aad662ec0e1 100644
26
+ index 4b64ab350bcd..b8fbe9b4331b 100644
27
27
--- a/arch/x86/kvm/x86.c
28
28
+++ b/arch/x86/kvm/x86.c
29
- @@ -2333 ,12 +2333 ,9 @@ static void kvm_write_system_time(struct kvm_vcpu *vcpu, gpa_t system_time,
29
+ @@ -2326 ,12 +2326 ,9 @@ static void kvm_write_system_time(struct kvm_vcpu *vcpu, gpa_t system_time,
30
30
31
31
/* we verify if the enable bit is set... */
32
32
if (system_time & 1)
@@ -41,20 +41,19 @@ index 2a02f2457c42..5aad662ec0e1 100644
41
41
}
42
42
43
43
static uint32_t div_frac(uint32_t dividend, uint32_t divisor)
44
- @@ -3132,26 +3129,14 @@ u64 get_kvmclock_ns(struct kvm *kvm)
44
+ @@ -3117,25 +3114,13 @@ u64 get_kvmclock_ns(struct kvm *kvm)
45
+ }
45
46
46
- static void kvm_setup_guest_pvclock(struct pvclock_vcpu_time_info *ref_hv_clock,
47
- struct kvm_vcpu *vcpu,
47
+ static void kvm_setup_guest_pvclock(struct kvm_vcpu *v,
48
48
- struct gfn_to_pfn_cache *gpc,
49
- - unsigned int offset)
50
- + gpa_t gpa)
49
+ - unsigned int offset,
50
+ + gpa_t gpa,
51
+ bool force_tsc_unstable)
51
52
{
53
+ struct kvm_vcpu_arch *vcpu = &v->arch;
52
54
- struct pvclock_vcpu_time_info *guest_hv_clock;
53
- + struct pvclock_vcpu_time_info guest_hv_clock;
54
- struct pvclock_vcpu_time_info hv_clock;
55
55
- unsigned long flags;
56
-
57
- memcpy(&hv_clock, ref_hv_clock, sizeof(hv_clock));
56
+ + struct pvclock_vcpu_time_info guest_hv_clock;
58
57
59
58
- read_lock_irqsave(&gpc->lock, flags);
60
59
- while (!kvm_gpc_check(gpc, offset + sizeof(*guest_hv_clock))) {
@@ -67,55 +66,59 @@ index 2a02f2457c42..5aad662ec0e1 100644
67
66
- }
68
67
-
69
68
- guest_hv_clock = (void *)(gpc->khva + offset);
70
- + kvm_read_guest(vcpu ->kvm, gpa, &guest_hv_clock, sizeof(struct pvclock_vcpu_time_info));
69
+ + kvm_read_guest(v ->kvm, gpa, &guest_hv_clock, sizeof(struct pvclock_vcpu_time_info));
71
70
72
71
/*
73
72
* This VCPU is paused, but it's legal for a guest to read another
74
- @@ -3160,20 +3145,18 @@ static void kvm_setup_guest_pvclock(struct pvclock_vcpu_time_info *ref_hv_clock ,
73
+ @@ -3144,28 +3129,28 @@ static void kvm_setup_guest_pvclock(struct kvm_vcpu *v ,
75
74
* it is consistent.
76
75
*/
77
76
78
- - guest_hv_clock->version = hv_clock.version = (guest_hv_clock->version + 1) | 1;
79
- + guest_hv_clock.version = hv_clock.version = (guest_hv_clock.version + 1) | 1;
77
+ - guest_hv_clock->version = vcpu->hv_clock.version = (guest_hv_clock->version + 1) | 1;
78
+ + guest_hv_clock.version = vcpu->hv_clock.version = (guest_hv_clock.version + 1) | 1;
79
+ + kvm_write_guest(v->kvm, gpa, &guest_hv_clock, sizeof(struct pvclock_vcpu_time_info));
80
+ +
80
81
smp_wmb();
81
82
82
83
/* retain PVCLOCK_GUEST_STOPPED if set in guest copy */
83
- - hv_clock.flags |= (guest_hv_clock->flags & PVCLOCK_GUEST_STOPPED);
84
- + hv_clock.flags |= (guest_hv_clock.flags & PVCLOCK_GUEST_STOPPED);
84
+ - vcpu->hv_clock.flags |= (guest_hv_clock->flags & PVCLOCK_GUEST_STOPPED);
85
+ + vcpu->hv_clock.flags |= (guest_hv_clock.flags & PVCLOCK_GUEST_STOPPED);
86
+
87
+ if (vcpu->pvclock_set_guest_stopped_request) {
88
+ vcpu->hv_clock.flags |= PVCLOCK_GUEST_STOPPED;
89
+ vcpu->pvclock_set_guest_stopped_request = false;
90
+ }
91
+
92
+ - memcpy(guest_hv_clock, &vcpu->hv_clock, sizeof(*guest_hv_clock));
93
+ + kvm_write_guest(v->kvm, gpa, &vcpu->hv_clock, sizeof(struct pvclock_vcpu_time_info));
85
94
86
- - memcpy(guest_hv_clock, &hv_clock, sizeof(*guest_hv_clock));
87
- + kvm_write_guest(vcpu->kvm, gpa, &hv_clock, sizeof(struct pvclock_vcpu_time_info));
95
+ if (force_tsc_unstable)
96
+ - guest_hv_clock->flags &= ~PVCLOCK_TSC_STABLE_BIT;
97
+ + guest_hv_clock.flags &= ~PVCLOCK_TSC_STABLE_BIT;
88
98
89
99
smp_wmb();
90
100
91
- - guest_hv_clock->version = ++hv_clock.version;
101
+ - guest_hv_clock->version = ++vcpu-> hv_clock.version;
92
102
-
93
103
- kvm_gpc_mark_dirty_in_slot(gpc);
94
104
- read_unlock_irqrestore(&gpc->lock, flags);
95
- + ++hv_clock.version;
96
- + kvm_write_guest(vcpu ->kvm, gpa + offsetof(struct pvclock_vcpu_time_info, version), & hv_clock.version , sizeof(hv_clock.version ));
105
+ + ++vcpu-> hv_clock.version;
106
+ + kvm_write_guest(v ->kvm, gpa, &vcpu-> hv_clock, sizeof(struct pvclock_vcpu_time_info ));
97
107
98
- trace_kvm_pvclock_update(vcpu ->vcpu_id, &hv_clock);
108
+ trace_kvm_pvclock_update(v ->vcpu_id, &vcpu-> hv_clock);
99
109
}
100
- @@ -3264,7 +3247,7 @@ int kvm_guest_time_update(struct kvm_vcpu *v)
101
- if (use_master_clock)
102
- hv_clock.flags |= PVCLOCK_TSC_STABLE_BIT;
103
-
104
- - if (vcpu->pv_time.active) {
105
- + if (vcpu->system_time != INVALID_GPA) {
106
- /*
107
- * GUEST_STOPPED is only supported by kvmclock, and KVM's
108
- * historic behavior is to only process the request if kvmclock
109
- @@ -3274,7 +3257,7 @@ int kvm_guest_time_update(struct kvm_vcpu *v)
110
- hv_clock.flags |= PVCLOCK_GUEST_STOPPED;
111
- vcpu->pvclock_set_guest_stopped_request = false;
112
- }
113
- - kvm_setup_guest_pvclock(&hv_clock, v, &vcpu->pv_time, 0);
114
- + kvm_setup_guest_pvclock(&hv_clock, v, vcpu->system_time);
115
-
116
- hv_clock.flags &= ~PVCLOCK_GUEST_STOPPED;
117
- }
118
- @@ -3590,7 +3573,7 @@ static int kvm_pv_enable_async_pf_int(struct kvm_vcpu *vcpu, u64 data)
110
+ @@ -3267,8 +3252,8 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
111
+
112
+ vcpu->hv_clock.flags = pvclock_flags;
113
+
114
+ - if (vcpu->pv_time.active)
115
+ - kvm_setup_guest_pvclock(v, &vcpu->pv_time, 0, false);
116
+ + if (vcpu->system_time != INVALID_GPA)
117
+ + kvm_setup_guest_pvclock(v, vcpu->system_time, false);
118
+ #ifdef CONFIG_KVM_XEN
119
+ if (vcpu->xen.vcpu_info_cache.active)
120
+ kvm_setup_guest_pvclock(v, &vcpu->xen.vcpu_info_cache,
121
+ @@ -3570,7 +3555,7 @@ static int kvm_pv_enable_async_pf_int(struct kvm_vcpu *vcpu, u64 data)
119
122
120
123
static void kvmclock_reset(struct kvm_vcpu *vcpu)
121
124
{
@@ -124,7 +127,7 @@ index 2a02f2457c42..5aad662ec0e1 100644
124
127
vcpu->arch.time = 0;
125
128
}
126
129
127
- @@ -5688 ,7 +5671 ,7 @@ static int kvm_vcpu_ioctl_x86_set_xcrs(struct kvm_vcpu *vcpu,
130
+ @@ -5656 ,7 +5641 ,7 @@ static int kvm_vcpu_ioctl_x86_set_xcrs(struct kvm_vcpu *vcpu,
128
131
*/
129
132
static int kvm_set_guest_paused(struct kvm_vcpu *vcpu)
130
133
{
@@ -133,14 +136,23 @@ index 2a02f2457c42..5aad662ec0e1 100644
133
136
return -EINVAL;
134
137
vcpu->arch.pvclock_set_guest_stopped_request = true;
135
138
kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu);
136
- @@ -12278,8 +12261,6 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
139
+ @@ -6909,7 +6894,7 @@ static int kvm_arch_suspend_notifier(struct kvm *kvm)
140
+
141
+ mutex_lock(&kvm->lock);
142
+ kvm_for_each_vcpu(i, vcpu, kvm) {
143
+ - if (!vcpu->arch.pv_time.active)
144
+ + if (vcpu->arch.system_time == INVALID_GPA)
145
+ continue;
146
+
147
+ ret = kvm_set_guest_paused(vcpu);
148
+ @@ -12251,8 +12236,6 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
137
149
vcpu->arch.regs_avail = ~0;
138
150
vcpu->arch.regs_dirty = ~0;
139
151
140
152
- kvm_gpc_init(&vcpu->arch.pv_time, vcpu->kvm);
141
153
-
142
154
if (!irqchip_in_kernel(vcpu->kvm) || kvm_vcpu_is_reset_bsp(vcpu))
143
- kvm_set_mp_state( vcpu, KVM_MP_STATE_RUNNABLE) ;
155
+ vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
144
156
else
145
157
- -
146
158
2.49.0
0 commit comments