summaryrefslogtreecommitdiff
path: root/5ec50b05-x86-idle-rework-C6-EOI-workaround.patch
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2023-10-12 04:00:49 +0000
committerCoprDistGit <infra@openeuler.org>2023-10-12 04:00:49 +0000
commitc22f60e6e55f1bf300dd76d2222a93911f3b2bb2 (patch)
treeef665e7018377f53612ac2751dcaea35a1c587b6 /5ec50b05-x86-idle-rework-C6-EOI-workaround.patch
parent39a4763249cd6289e5019acfe0c98dbb169f5f2e (diff)
automatic import of xenopeneuler22.03_LTS
Diffstat (limited to '5ec50b05-x86-idle-rework-C6-EOI-workaround.patch')
-rw-r--r--5ec50b05-x86-idle-rework-C6-EOI-workaround.patch100
1 files changed, 100 insertions, 0 deletions
diff --git a/5ec50b05-x86-idle-rework-C6-EOI-workaround.patch b/5ec50b05-x86-idle-rework-C6-EOI-workaround.patch
new file mode 100644
index 0000000..d2e42b0
--- /dev/null
+++ b/5ec50b05-x86-idle-rework-C6-EOI-workaround.patch
@@ -0,0 +1,100 @@
+# Commit 5fef1fd713660406a6187ef352fbf79986abfe43
+# Date 2020-05-20 12:48:37 +0200
+# Author Roger Pau Monné <roger.pau@citrix.com>
+# Committer Jan Beulich <jbeulich@suse.com>
+x86/idle: rework C6 EOI workaround
+
+Change the C6 EOI workaround (errata AAJ72) to use x86_match_cpu. Also
+call the workaround from mwait_idle, previously it was only used by
+the ACPI idle driver. Finally make sure the routine is called for all
+states equal or greater than ACPI_STATE_C3, note that the ACPI driver
+doesn't currently handle them, but the errata condition shouldn't be
+limited by that.
+
+Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
+Reviewed-by: Jan Beulich <jbeulich@suse.com>
+
+--- a/xen/arch/x86/acpi/cpu_idle.c
++++ b/xen/arch/x86/acpi/cpu_idle.c
+@@ -537,26 +537,35 @@ void trace_exit_reason(u32 *irq_traced)
+ }
+ }
+
+-/*
+- * "AAJ72. EOI Transaction May Not be Sent if Software Enters Core C6 During
+- * an Interrupt Service Routine"
+- *
+- * There was an errata with some Core i7 processors that an EOI transaction
+- * may not be sent if software enters core C6 during an interrupt service
+- * routine. So we don't enter deep Cx state if there is an EOI pending.
+- */
+-static bool errata_c6_eoi_workaround(void)
++bool errata_c6_eoi_workaround(void)
+ {
+- static int8_t fix_needed = -1;
++ static int8_t __read_mostly fix_needed = -1;
+
+ if ( unlikely(fix_needed == -1) )
+ {
+- int model = boot_cpu_data.x86_model;
+- fix_needed = (cpu_has_apic && !directed_eoi_enabled &&
+- (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) &&
+- (boot_cpu_data.x86 == 6) &&
+- ((model == 0x1a) || (model == 0x1e) || (model == 0x1f) ||
+- (model == 0x25) || (model == 0x2c) || (model == 0x2f)));
++#define INTEL_FAM6_MODEL(m) { X86_VENDOR_INTEL, 6, m, X86_FEATURE_ALWAYS }
++ /*
++ * Errata AAJ72: EOI Transaction May Not be Sent if Software Enters
++ * Core C6 During an Interrupt Service Routine"
++ *
++ * There was an errata with some Core i7 processors that an EOI
++ * transaction may not be sent if software enters core C6 during an
++ * interrupt service routine. So we don't enter deep Cx state if
++ * there is an EOI pending.
++ */
++ static const struct x86_cpu_id eoi_errata[] = {
++ INTEL_FAM6_MODEL(0x1a),
++ INTEL_FAM6_MODEL(0x1e),
++ INTEL_FAM6_MODEL(0x1f),
++ INTEL_FAM6_MODEL(0x25),
++ INTEL_FAM6_MODEL(0x2c),
++ INTEL_FAM6_MODEL(0x2f),
++ { }
++ };
++#undef INTEL_FAM6_MODEL
++
++ fix_needed = cpu_has_apic && !directed_eoi_enabled &&
++ x86_match_cpu(eoi_errata);
+ }
+
+ return (fix_needed && cpu_has_pending_apic_eoi());
+@@ -664,7 +673,7 @@ static void acpi_processor_idle(void)
+ return;
+ }
+
+- if ( (cx->type == ACPI_STATE_C3) && errata_c6_eoi_workaround() )
++ if ( (cx->type >= ACPI_STATE_C3) && errata_c6_eoi_workaround() )
+ cx = power->safe_state;
+
+
+--- a/xen/arch/x86/cpu/mwait-idle.c
++++ b/xen/arch/x86/cpu/mwait-idle.c
+@@ -769,6 +769,9 @@ static void mwait_idle(void)
+ return;
+ }
+
++ if ((cx->type >= 3) && errata_c6_eoi_workaround())
++ cx = power->safe_state;
++
+ eax = cx->address;
+ cstate = ((eax >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK) + 1;
+
+--- a/xen/include/asm-x86/cpuidle.h
++++ b/xen/include/asm-x86/cpuidle.h
+@@ -26,4 +26,6 @@ void update_idle_stats(struct acpi_proce
+ void update_last_cx_stat(struct acpi_processor_power *,
+ struct acpi_processor_cx *, uint64_t);
+
++bool errata_c6_eoi_workaround(void);
++
+ #endif /* __X86_ASM_CPUIDLE_H__ */