Skip to content

Commit 650f256

Browse files
committed
fix: clear private flag after freeing gmem folio
Not clearing the private flag causes it to stick around after freeing, potentially confusing subsequent users of the folio that assign meaning to the private flag. Signed-off-by: Patrick Roy <[email protected]>
1 parent 7f78d60 commit 650f256

File tree

3 files changed

+100
-115
lines changed

3 files changed

+100
-115
lines changed

resources/hiding_ci/linux_patches/10-direct-map-removal/0011-KVM-guest_memfd-Add-flag-to-remove-from-direct-map.patch

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
From b1fc478976c93fd42b14e06d2de57e121be03142 Mon Sep 17 00:00:00 2001
1+
From a06590a8007e35c86caf7344f76e69d4501bc43a Mon Sep 17 00:00:00 2001
22
From: Patrick Roy <[email protected]>
33
Date: Fri, 7 Feb 2025 14:33:01 +0000
4-
Subject: [PATCH 11/26] KVM: guest_memfd: Add flag to remove from direct map
4+
Subject: [PATCH] KVM: guest_memfd: Add flag to remove from direct map
55

66
Add KVM_GMEM_NO_DIRECT_MAP flag for KVM_CREATE_GUEST_MEMFD() ioctl. When
77
set, guest_memfd folios will be removed from the direct map after
@@ -56,9 +56,9 @@ spectre-gadget.
5656
Signed-off-by: Patrick Roy <[email protected]>
5757
---
5858
include/uapi/linux/kvm.h | 3 +++
59-
virt/kvm/guest_memfd.c | 28 +++++++++++++++++++++++++++-
59+
virt/kvm/guest_memfd.c | 38 +++++++++++++++++++++++++++++++++-----
6060
virt/kvm/kvm_main.c | 5 +++++
61-
3 files changed, 35 insertions(+), 1 deletion(-)
61+
3 files changed, 41 insertions(+), 5 deletions(-)
6262

6363
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
6464
index 117937a895da..fb02a93546d8 100644
@@ -82,7 +82,7 @@ index 117937a895da..fb02a93546d8 100644
8282

8383
struct kvm_pre_fault_memory {
8484
diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c
85-
index fbf89e643add..a2b96bc51391 100644
85+
index fbf89e643add..5545a35ce900 100644
8686
--- a/virt/kvm/guest_memfd.c
8787
+++ b/virt/kvm/guest_memfd.c
8888
@@ -4,6 +4,7 @@
@@ -117,18 +117,42 @@ index fbf89e643add..a2b96bc51391 100644
117117
folio_mark_uptodate(folio);
118118
}
119119

120-
@@ -478,6 +494,10 @@ static void kvm_gmem_free_folio(struct folio *folio)
120+
@@ -471,24 +487,30 @@ static int kvm_gmem_error_folio(struct address_space *mapping, struct folio *fol
121+
return MF_DELAYED;
122+
}
123+
124+
-#ifdef CONFIG_HAVE_KVM_ARCH_GMEM_INVALIDATE
125+
static void kvm_gmem_free_folio(struct folio *folio)
126+
{
127+
+#ifdef CONFIG_HAVE_KVM_ARCH_GMEM_INVALIDATE
128+
struct page *page = folio_page(folio, 0);
121129
kvm_pfn_t pfn = page_to_pfn(page);
122130
int order = folio_order(folio);
131+
+#endif
123132

124-
+ if (folio_test_private(folio))
133+
+ if (folio_test_private(folio)) {
125134
+ WARN_ON_ONCE(set_direct_map_valid_noflush(folio_page(folio, 0),
126135
+ folio_nr_pages(folio), true));
136+
+ folio_clear_private(folio);
137+
+ }
127138
+
139+
+#ifdef CONFIG_HAVE_KVM_ARCH_GMEM_INVALIDATE
128140
kvm_arch_gmem_invalidate(pfn, pfn + (1ul << order));
129-
}
141+
-}
130142
#endif
131-
@@ -551,6 +571,9 @@ static int __kvm_gmem_create(struct kvm *kvm, loff_t size, u64 flags)
143+
+}
144+
145+
static const struct address_space_operations kvm_gmem_aops = {
146+
.dirty_folio = noop_dirty_folio,
147+
.migrate_folio = kvm_gmem_migrate_folio,
148+
.error_remove_folio = kvm_gmem_error_folio,
149+
-#ifdef CONFIG_HAVE_KVM_ARCH_GMEM_INVALIDATE
150+
.free_folio = kvm_gmem_free_folio,
151+
-#endif
152+
};
153+
154+
static int kvm_gmem_getattr(struct mnt_idmap *idmap, const struct path *path,
155+
@@ -551,6 +573,9 @@ static int __kvm_gmem_create(struct kvm *kvm, loff_t size, u64 flags)
132156
/* Unmovable mappings are supposed to be marked unevictable as well. */
133157
WARN_ON_ONCE(!mapping_unevictable(inode->i_mapping));
134158

@@ -138,7 +162,7 @@ index fbf89e643add..a2b96bc51391 100644
138162
kvm_get_kvm(kvm);
139163
gmem->kvm = kvm;
140164
xa_init(&gmem->bindings);
141-
@@ -570,7 +593,10 @@ int kvm_gmem_create(struct kvm *kvm, struct kvm_create_guest_memfd *args)
165+
@@ -570,7 +595,10 @@ int kvm_gmem_create(struct kvm *kvm, struct kvm_create_guest_memfd *args)
142166
{
143167
loff_t size = args->size;
144168
u64 flags = args->flags;
@@ -174,5 +198,5 @@ index 3e40acb9f5c0..32ca1c921ab0 100644
174198
return !kvm || kvm_arch_has_private_mem(kvm);
175199
#endif
176200
--
177-
2.47.1
201+
2.49.0
178202

resources/hiding_ci/linux_patches/10-direct-map-removal/0012-fixup-for-direct-map-removal-v4.patch

Lines changed: 0 additions & 51 deletions
This file was deleted.

resources/hiding_ci/linux_patches/11-kvmclock.patch

Lines changed: 65 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,32 @@
1-
From f6c3a183801123395e05959b7a6508bf420eb726 Mon Sep 17 00:00:00 2001
1+
From 48bd0eb952cf1455b124fa06c348b801ef2254ad Mon Sep 17 00:00:00 2001
22
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
44
Subject: [PATCH] de-gpc-ify kvm-clock
55

66
Signed-off-by: Patrick Roy <[email protected]>
77
---
88
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(-)
1111

1212
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
1414
--- a/arch/x86/include/asm/kvm_host.h
1515
+++ 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;
1919
unsigned int hw_tsc_khz;
2020
- struct gfn_to_pfn_cache pv_time;
2121
+ gpa_t system_time;
2222
/* set guest stopped flag in pvclock flags field */
2323
bool pvclock_set_guest_stopped_request;
2424

2525
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
26-
index 2a02f2457c42..5aad662ec0e1 100644
26+
index 4b64ab350bcd..b8fbe9b4331b 100644
2727
--- a/arch/x86/kvm/x86.c
2828
+++ 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,
3030

3131
/* we verify if the enable bit is set... */
3232
if (system_time & 1)
@@ -41,20 +41,19 @@ index 2a02f2457c42..5aad662ec0e1 100644
4141
}
4242

4343
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+
}
4546

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,
4848
- 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)
5152
{
53+
struct kvm_vcpu_arch *vcpu = &v->arch;
5254
- 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;
5555
- unsigned long flags;
56-
57-
memcpy(&hv_clock, ref_hv_clock, sizeof(hv_clock));
56+
+ struct pvclock_vcpu_time_info guest_hv_clock;
5857

5958
- read_lock_irqsave(&gpc->lock, flags);
6059
- while (!kvm_gpc_check(gpc, offset + sizeof(*guest_hv_clock))) {
@@ -67,55 +66,59 @@ index 2a02f2457c42..5aad662ec0e1 100644
6766
- }
6867
-
6968
- 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));
7170

7271
/*
7372
* 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,
7574
* it is consistent.
7675
*/
7776

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+
+
8081
smp_wmb();
8182

8283
/* 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));
8594

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;
8898

8999
smp_wmb();
90100

91-
- guest_hv_clock->version = ++hv_clock.version;
101+
- guest_hv_clock->version = ++vcpu->hv_clock.version;
92102
-
93103
- kvm_gpc_mark_dirty_in_slot(gpc);
94104
- 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));
97107

98-
trace_kvm_pvclock_update(vcpu->vcpu_id, &hv_clock);
108+
trace_kvm_pvclock_update(v->vcpu_id, &vcpu->hv_clock);
99109
}
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)
119122

120123
static void kvmclock_reset(struct kvm_vcpu *vcpu)
121124
{
@@ -124,7 +127,7 @@ index 2a02f2457c42..5aad662ec0e1 100644
124127
vcpu->arch.time = 0;
125128
}
126129

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,
128131
*/
129132
static int kvm_set_guest_paused(struct kvm_vcpu *vcpu)
130133
{
@@ -133,14 +136,23 @@ index 2a02f2457c42..5aad662ec0e1 100644
133136
return -EINVAL;
134137
vcpu->arch.pvclock_set_guest_stopped_request = true;
135138
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)
137149
vcpu->arch.regs_avail = ~0;
138150
vcpu->arch.regs_dirty = ~0;
139151

140152
- kvm_gpc_init(&vcpu->arch.pv_time, vcpu->kvm);
141153
-
142154
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;
144156
else
145157
--
146158
2.49.0

0 commit comments

Comments
 (0)