-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlinux-kernel-test.patch
263 lines (254 loc) · 8.81 KB
/
linux-kernel-test.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
diff -ruN a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
--- a/Documentation/admin-guide/kernel-parameters.txt 2023-04-23 12:02:52.000000000 -0700
+++ b/Documentation/admin-guide/kernel-parameters.txt 2023-04-24 09:06:17.451378498 -0700
@@ -4190,6 +4190,15 @@
nomsi [MSI] If the PCI_MSI kernel config parameter is
enabled, this kernel boot option can be used to
disable the use of MSI interrupts system-wide.
+ pcie_acs_override =
+ [PCIE] Override missing PCIe ACS support for:
+ downstream
+ All downstream ports - full ACS capabilities
+ multfunction
+ All multifunction devices - multifunction ACS subset
+ id:nnnn:nnnn
+ Specfic device - full ACS capabilities
+ Specified as vid:did (vendor/device ID) in hex
noioapicquirk [APIC] Disable all boot interrupt quirks.
Safety option to keep boot IRQs enabled. This
should never be necessary.
diff -ruN a/drivers/pci/quirks.c b/drivers/pci/quirks.c
--- a/drivers/pci/quirks.c 2023-04-23 12:02:52.000000000 -0700
+++ b/drivers/pci/quirks.c 2023-04-24 09:27:41.976143291 -0700
@@ -4603,6 +4603,107 @@
return false;
}
+static bool acs_on_downstream;
+static bool acs_on_multifunction;
+
+#define NUM_ACS_IDS 16
+struct acs_on_id {
+ unsigned short vendor;
+ unsigned short device;
+};
+static struct acs_on_id acs_on_ids[NUM_ACS_IDS];
+static u8 max_acs_id;
+
+static __init int pcie_acs_override_setup(char *p)
+{
+ if (!p)
+ return -EINVAL;
+
+ while (*p) {
+ if (!strncmp(p, "downstream", 10))
+ acs_on_downstream = true;
+ if (!strncmp(p, "multifunction", 13))
+ acs_on_multifunction = true;
+ if (!strncmp(p, "id:", 3)) {
+ char opt[5];
+ int ret;
+ long val;
+
+ if (max_acs_id >= NUM_ACS_IDS - 1) {
+ pr_warn("Out of PCIe ACS override slots (%d)\n",
+ NUM_ACS_IDS);
+ goto next;
+ }
+
+ p += 3;
+ snprintf(opt, 5, "%s", p);
+ ret = kstrtol(opt, 16, &val);
+ if (ret) {
+ pr_warn("PCIe ACS ID parse error %d\n", ret);
+ goto next;
+ }
+ acs_on_ids[max_acs_id].vendor = val;
+
+ p += strcspn(p, ":");
+ if (*p != ':') {
+ pr_warn("PCIe ACS invalid ID\n");
+ goto next;
+ }
+
+ p++;
+ snprintf(opt, 5, "%s", p);
+ ret = kstrtol(opt, 16, &val);
+ if (ret) {
+ pr_warn("PCIe ACS ID parse error %d\n", ret);
+ goto next;
+ }
+ acs_on_ids[max_acs_id].device = val;
+ max_acs_id++;
+ }
+next:
+ p += strcspn(p, ",");
+ if (*p == ',')
+ p++;
+ }
+
+ if (acs_on_downstream || acs_on_multifunction || max_acs_id)
+ pr_warn("Warning: PCIe ACS overrides enabled; This may allow non-IOMMU protected peer-to-peer DMA\n");
+
+ return 0;
+}
+early_param("pcie_acs_override", pcie_acs_override_setup);
+
+static int pcie_acs_overrides(struct pci_dev *dev, u16 acs_flags)
+{
+ int i;
+
+ /* Never override ACS for legacy devices or devices with ACS caps */
+ if (!pci_is_pcie(dev) ||
+ pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS))
+ return -ENOTTY;
+
+ for (i = 0; i < max_acs_id; i++)
+ if (acs_on_ids[i].vendor == dev->vendor &&
+ acs_on_ids[i].device == dev->device)
+ return 1;
+
+ switch (pci_pcie_type(dev)) {
+ case PCI_EXP_TYPE_DOWNSTREAM:
+ case PCI_EXP_TYPE_ROOT_PORT:
+ if (acs_on_downstream)
+ return 1;
+ break;
+ case PCI_EXP_TYPE_ENDPOINT:
+ case PCI_EXP_TYPE_UPSTREAM:
+ case PCI_EXP_TYPE_LEG_END:
+ case PCI_EXP_TYPE_RC_END:
+ if (acs_on_multifunction && dev->multifunction)
+ return 1;
+ }
+
+ return -ENOTTY;
+}
+
/*
* Many Intel PCH Root Ports do provide ACS-like features to disable peer
* transactions and validate bus numbers in requests, but do not provide an
@@ -5002,6 +5103,7 @@
{ PCI_VENDOR_ID_ZHAOXIN, PCI_ANY_ID, pci_quirk_zhaoxin_pcie_ports_acs },
/* Wangxun nics */
{ PCI_VENDOR_ID_WANGXUN, PCI_ANY_ID, pci_quirk_wangxun_nic_acs },
+ { PCI_ANY_ID, PCI_ANY_ID, pcie_acs_overrides },
{ 0 }
};
diff --unified --recursive --text --new-file ../../linux-6.7/arch/x86/include/asm/kvm_host.h linux-6.7/arch/x86/include/asm/kvm_host.h
--- ../../linux-6.7/arch/x86/include/asm/kvm_host.h 2024-01-07 21:18:38.000000000 +0100
+++ linux-6.7/arch/x86/include/asm/kvm_host.h 2024-03-28 16:08:35.105335736 +0100
@@ -680,6 +680,8 @@
u64 vm_id;
u32 vp_id;
} nested;
+ /* HACK (CPPC) */
+ u32 cppc_hack_counter;
};
struct kvm_hypervisor_cpuid {
diff --unified --recursive --text --new-file ../../linux-6.7/arch/x86/kvm/cpuid.c linux-6.7/arch/x86/kvm/cpuid.c
--- ../../linux-6.7/arch/x86/kvm/cpuid.c 2024-01-07 21:18:38.000000000 +0100
+++ linux-6.7/arch/x86/kvm/cpuid.c 2024-03-28 16:08:35.108669099 +0100
@@ -1535,6 +1535,7 @@
if (kvm_hv_invtsc_suppressed(vcpu))
*edx &= ~SF(CONSTANT_TSC);
}
+ kvm_hv_override_cpuid(vcpu, function, eax, ebx, ecx, edx);
} else {
*eax = *ebx = *ecx = *edx = 0;
/*
diff --unified --recursive --text --new-file ../../linux-6.7/arch/x86/kvm/hyperv.h linux-6.7/arch/x86/kvm/hyperv.h
--- ../../linux-6.7/arch/x86/kvm/hyperv.h 2024-01-07 21:18:38.000000000 +0100
+++ linux-6.7/arch/x86/kvm/hyperv.h 2024-03-28 16:08:35.108669099 +0100
@@ -163,6 +163,47 @@
return !(to_kvm_hv(vcpu->kvm)->hv_invtsc_control & HV_EXPOSE_INVARIANT_TSC);
}
+/*
+ * HACK (CPPC) - disable HV_CPU_MANAGEMENT until hypercalls are enabled
+ * to work around a page mapping error in winload.
+ */
+static inline void kvm_hv_override_cpuid(struct kvm_vcpu *vcpu, int function,
+ u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
+{
+ struct kvm *kvm = vcpu->kvm;
+ struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
+ struct kvm_hv *hv = to_kvm_hv(kvm);
+ if (unlikely(!hv || !hv_vcpu))
+ return;
+ if (vcpu->vcpu_idx != 0)
+ return;
+ if (hv->hv_hypercall & HV_X64_MSR_HYPERCALL_ENABLE) {
+ //Use a 'warmup' counter to fix another issue:
+ // Prevent requirement for nested Hyper-V;
+ // if Hyper-V is not enabled but HV_CPU_MANAGEMENT is,
+ // Windows refuses to boot.
+ // The check is usually 2 HYPERV_CPUID_FEATURES
+ // calls after enabling hypercalls (winload).
+ if (hv_vcpu->cppc_hack_counter >= 4)
+ return;
+ if (function == HYPERV_CPUID_FEATURES)
+ ++hv_vcpu->cppc_hack_counter;
+ }
+ else {
+ hv_vcpu->cppc_hack_counter = 0;
+ }
+ if (function == HYPERV_CPUID_FEATURES) {
+ if (*ebx & HV_CPU_MANAGEMENT) {
+ *ebx &= ~(HV_CPU_MANAGEMENT | HV_ISOLATION);
+ }
+ }
+ //if (function == HYPERV_CPUID_ENLIGHTMENT_INFO) {
+ // if (hv_vcpu->cpuid_cache.features_ebx & HV_CPU_MANAGEMENT) {
+ // *eax &= ~(HV_X64_HYPERV_NESTED);
+ // }
+ //}
+}
+
void kvm_hv_process_stimers(struct kvm_vcpu *vcpu);
void kvm_hv_setup_tsc_page(struct kvm *kvm,
diff --unified --recursive --text --new-file ../../linux-6.7/arch/x86/kvm/svm/svm.c linux-6.7/arch/x86/kvm/svm/svm.c
--- ../../linux-6.7/arch/x86/kvm/svm/svm.c 2024-01-07 21:18:38.000000000 +0100
+++ linux-6.7/arch/x86/kvm/svm/svm.c 2024-03-28 16:09:14.499024370 +0100
@@ -104,6 +104,10 @@
{ .index = MSR_IA32_LASTINTFROMIP, .always = false },
{ .index = MSR_IA32_LASTINTTOIP, .always = false },
{ .index = MSR_IA32_XSS, .always = false },
+ { .index = MSR_IA32_MPERF, .always = true },
+ { .index = MSR_IA32_APERF, .always = true },
+ { .index = 0xC00000E7, .always = true }, //MPERF_RO AMD
+ { .index = 0xC00000E8, .always = true }, //APERF_RO AMD
{ .index = MSR_EFER, .always = false },
{ .index = MSR_IA32_CR_PAT, .always = false },
{ .index = MSR_AMD64_SEV_ES_GHCB, .always = true },
diff --unified --recursive --text --new-file ../../linux-6.7/arch/x86/kvm/svm/svm.h linux-6.7/arch/x86/kvm/svm/svm.h
--- ../../linux-6.7/arch/x86/kvm/svm/svm.h 2024-01-07 21:18:38.000000000 +0100
+++ linux-6.7/arch/x86/kvm/svm/svm.h 2024-03-28 16:08:49.745467660 +0100
@@ -30,7 +30,7 @@
#define IOPM_SIZE PAGE_SIZE * 3
#define MSRPM_SIZE PAGE_SIZE * 2
-#define MAX_DIRECT_ACCESS_MSRS 47
+#define MAX_DIRECT_ACCESS_MSRS 51
#define MSRPM_OFFSETS 32
extern u32 msrpm_offsets[MSRPM_OFFSETS] __read_mostly;
extern bool npt_enabled;
diff -x '*.orig' -x '*.rej' -x .config --unified --recursive --text --new-file ../../linux-6.7/arch/x86/kvm/vmx/vmx.c linux-6.7/arch/x86/kvm/vmx/vmx.c
--- linux-6.6_unpatched/arch/x86/kvm/vmx/vmx.c 2024-04-01 18:58:59.141664982 +0200
+++ linux-6.6/arch/x86/kvm/vmx/vmx.c 2024-04-01 19:00:48.689376837 +0200
@@ -179,6 +179,8 @@
MSR_CORE_C3_RESIDENCY,
MSR_CORE_C6_RESIDENCY,
MSR_CORE_C7_RESIDENCY,
+ MSR_IA32_MPERF,
+ MSR_IA32_APERF,
};
/*
diff -x '*.orig' -x '*.rej' -x .config --unified --recursive --text --new-file ../../linux-6.7/arch/x86/kvm/vmx/vmx.h linux-6.7/arch/x86/kvm/vmx/vmx.h
--- linux-6.6_unpatched/arch/x86/kvm/vmx/vmx.h 2024-04-01 18:58:59.141664982 +0200
+++ linux-6.6/arch/x86/kvm/vmx/vmx.h 2024-04-01 19:00:48.689376837 +0200
@@ -357,7 +357,7 @@
struct lbr_desc lbr_desc;
/* Save desired MSR intercept (read: pass-through) state */
-#define MAX_POSSIBLE_PASSTHROUGH_MSRS 16
+#define MAX_POSSIBLE_PASSTHROUGH_MSRS 18
struct {
DECLARE_BITMAP(read, MAX_POSSIBLE_PASSTHROUGH_MSRS);
DECLARE_BITMAP(write, MAX_POSSIBLE_PASSTHROUGH_MSRS);