From: Greg Kroah-Hartman Date: Tue, 14 Apr 2020 12:37:08 +0000 (+0200) Subject: 5.6-stable patches X-Git-Tag: v4.19.116~70 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=479db7216a160c61ef7701cad4521f69c7582eab;p=thirdparty%2Fkernel%2Fstable-queue.git 5.6-stable patches added patches: ath9k-handle-txpower-changes-even-when-tpc-is-disabled.patch sdhci-tegra-implement-tegra-specific-set_timeout-callback.patch signal-extend-exec_id-to-64bits.patch x86-entry-32-add-missing-asm_clac-to-general_protection-entry.patch x86-tsc_msr-fix-msr_fsb_freq-mask-for-cherry-trail-devices.patch x86-tsc_msr-make-msr-derived-tsc-frequency-more-accurate.patch x86-tsc_msr-use-named-struct-initializers.patch --- diff --git a/queue-5.6/ath9k-handle-txpower-changes-even-when-tpc-is-disabled.patch b/queue-5.6/ath9k-handle-txpower-changes-even-when-tpc-is-disabled.patch new file mode 100644 index 00000000000..ad2ee29057b --- /dev/null +++ b/queue-5.6/ath9k-handle-txpower-changes-even-when-tpc-is-disabled.patch @@ -0,0 +1,57 @@ +From 968ae2caad0782db5dbbabb560d3cdefd2945d38 Mon Sep 17 00:00:00 2001 +From: Remi Pommarel +Date: Sat, 29 Feb 2020 17:13:47 +0100 +Subject: ath9k: Handle txpower changes even when TPC is disabled + +From: Remi Pommarel + +commit 968ae2caad0782db5dbbabb560d3cdefd2945d38 upstream. + +When TPC is disabled IEEE80211_CONF_CHANGE_POWER event can be handled to +reconfigure HW's maximum txpower. + +This fixes 0dBm txpower setting when user attaches to an interface for +the first time with the following scenario: + +ieee80211_do_open() + ath9k_add_interface() + ath9k_set_txpower() /* Set TX power with not yet initialized + sc->hw->conf.power_level */ + + ieee80211_hw_config() /* Iniatilize sc->hw->conf.power_level and + raise IEEE80211_CONF_CHANGE_POWER */ + + ath9k_config() /* IEEE80211_CONF_CHANGE_POWER is ignored */ + +This issue can be reproduced with the following: + + $ modprobe -r ath9k + $ modprobe ath9k + $ wpa_supplicant -i wlan0 -c /tmp/wpa.conf & + $ iw dev /* Here TX power is either 0 or 3 depending on RF chain */ + $ killall wpa_supplicant + $ iw dev /* TX power goes back to calibrated value and subsequent + calls will be fine */ + +Fixes: 283dd11994cde ("ath9k: add per-vif TX power capability") +Cc: stable@vger.kernel.org +Signed-off-by: Remi Pommarel +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/main.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -1457,6 +1457,9 @@ static int ath9k_config(struct ieee80211 + ath_chanctx_set_channel(sc, ctx, &hw->conf.chandef); + } + ++ if (changed & IEEE80211_CONF_CHANGE_POWER) ++ ath9k_set_txpower(sc, NULL); ++ + mutex_unlock(&sc->mutex); + ath9k_ps_restore(sc); + diff --git a/queue-5.6/sdhci-tegra-implement-tegra-specific-set_timeout-callback.patch b/queue-5.6/sdhci-tegra-implement-tegra-specific-set_timeout-callback.patch new file mode 100644 index 00000000000..bdacd8d3ba2 --- /dev/null +++ b/queue-5.6/sdhci-tegra-implement-tegra-specific-set_timeout-callback.patch @@ -0,0 +1,93 @@ +From 5e958e4aacf44e1cc98b0d88d8e66e98f03bbf66 Mon Sep 17 00:00:00 2001 +From: Sowjanya Komatineni +Date: Wed, 11 Mar 2020 08:47:54 -0700 +Subject: sdhci: tegra: Implement Tegra specific set_timeout callback + +From: Sowjanya Komatineni + +commit 5e958e4aacf44e1cc98b0d88d8e66e98f03bbf66 upstream. + +Tegra host supports HW busy detection and timeouts based on the +count programmed in SDHCI_TIMEOUT_CONTROL register and max busy +timeout it supports is 11s in finite busy wait mode. + +Some operations like SLEEP_AWAKE, ERASE and flush cache through +SWITCH commands take longer than 11s and Tegra host supports +infinite HW busy wait mode where HW waits forever till the card +is busy without HW timeout. + +This patch implements Tegra specific set_timeout sdhci_ops to allow +switching between finite and infinite HW busy detection wait modes +based on the device command expected operation time. + +Signed-off-by: Sowjanya Komatineni +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/1583941675-9884-1-git-send-email-skomatineni@nvidia.com +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mmc/host/sdhci-tegra.c | 31 +++++++++++++++++++++++++++++++ + 1 file changed, 31 insertions(+) + +--- a/drivers/mmc/host/sdhci-tegra.c ++++ b/drivers/mmc/host/sdhci-tegra.c +@@ -45,6 +45,7 @@ + #define SDHCI_TEGRA_CAP_OVERRIDES_DQS_TRIM_SHIFT 8 + + #define SDHCI_TEGRA_VENDOR_MISC_CTRL 0x120 ++#define SDHCI_MISC_CTRL_ERASE_TIMEOUT_LIMIT BIT(0) + #define SDHCI_MISC_CTRL_ENABLE_SDR104 0x8 + #define SDHCI_MISC_CTRL_ENABLE_SDR50 0x10 + #define SDHCI_MISC_CTRL_ENABLE_SDHCI_SPEC_300 0x20 +@@ -1227,6 +1228,34 @@ static u32 sdhci_tegra_cqhci_irq(struct + return 0; + } + ++static void tegra_sdhci_set_timeout(struct sdhci_host *host, ++ struct mmc_command *cmd) ++{ ++ u32 val; ++ ++ /* ++ * HW busy detection timeout is based on programmed data timeout ++ * counter and maximum supported timeout is 11s which may not be ++ * enough for long operations like cache flush, sleep awake, erase. ++ * ++ * ERASE_TIMEOUT_LIMIT bit of VENDOR_MISC_CTRL register allows ++ * host controller to wait for busy state until the card is busy ++ * without HW timeout. ++ * ++ * So, use infinite busy wait mode for operations that may take ++ * more than maximum HW busy timeout of 11s otherwise use finite ++ * busy wait mode. ++ */ ++ val = sdhci_readl(host, SDHCI_TEGRA_VENDOR_MISC_CTRL); ++ if (cmd && cmd->busy_timeout >= 11 * HZ) ++ val |= SDHCI_MISC_CTRL_ERASE_TIMEOUT_LIMIT; ++ else ++ val &= ~SDHCI_MISC_CTRL_ERASE_TIMEOUT_LIMIT; ++ sdhci_writel(host, val, SDHCI_TEGRA_VENDOR_MISC_CTRL); ++ ++ __sdhci_set_timeout(host, cmd); ++} ++ + static const struct cqhci_host_ops sdhci_tegra_cqhci_ops = { + .write_l = tegra_cqhci_writel, + .enable = sdhci_tegra_cqe_enable, +@@ -1366,6 +1395,7 @@ static const struct sdhci_ops tegra210_s + .set_uhs_signaling = tegra_sdhci_set_uhs_signaling, + .voltage_switch = tegra_sdhci_voltage_switch, + .get_max_clock = tegra_sdhci_get_max_clock, ++ .set_timeout = tegra_sdhci_set_timeout, + }; + + static const struct sdhci_pltfm_data sdhci_tegra210_pdata = { +@@ -1403,6 +1433,7 @@ static const struct sdhci_ops tegra186_s + .voltage_switch = tegra_sdhci_voltage_switch, + .get_max_clock = tegra_sdhci_get_max_clock, + .irq = sdhci_tegra_cqhci_irq, ++ .set_timeout = tegra_sdhci_set_timeout, + }; + + static const struct sdhci_pltfm_data sdhci_tegra186_pdata = { diff --git a/queue-5.6/series b/queue-5.6/series index 6c974d7c300..c8d19b7a7d8 100644 --- a/queue-5.6/series +++ b/queue-5.6/series @@ -120,3 +120,10 @@ mips-tlbex-fix-lddir-usage-in-setup_pw-for-loongson-3.patch mips-octeon-irq-fix-potential-null-pointer-dereference.patch pm-domains-allow-no-domain-idle-states-dt-property-in-genpd-when-parsing.patch pm-sleep-wakeup-skip-wakeup_source_sysfs_remove-if-device-is-not-there.patch +sdhci-tegra-implement-tegra-specific-set_timeout-callback.patch +ath9k-handle-txpower-changes-even-when-tpc-is-disabled.patch +signal-extend-exec_id-to-64bits.patch +x86-tsc_msr-use-named-struct-initializers.patch +x86-tsc_msr-fix-msr_fsb_freq-mask-for-cherry-trail-devices.patch +x86-tsc_msr-make-msr-derived-tsc-frequency-more-accurate.patch +x86-entry-32-add-missing-asm_clac-to-general_protection-entry.patch diff --git a/queue-5.6/signal-extend-exec_id-to-64bits.patch b/queue-5.6/signal-extend-exec_id-to-64bits.patch new file mode 100644 index 00000000000..c6192ad5002 --- /dev/null +++ b/queue-5.6/signal-extend-exec_id-to-64bits.patch @@ -0,0 +1,82 @@ +From d1e7fd6462ca9fc76650fbe6ca800e35b24267da Mon Sep 17 00:00:00 2001 +From: "Eric W. Biederman" +Date: Mon, 30 Mar 2020 19:01:04 -0500 +Subject: signal: Extend exec_id to 64bits + +From: Eric W. Biederman + +commit d1e7fd6462ca9fc76650fbe6ca800e35b24267da upstream. + +Replace the 32bit exec_id with a 64bit exec_id to make it impossible +to wrap the exec_id counter. With care an attacker can cause exec_id +wrap and send arbitrary signals to a newly exec'd parent. This +bypasses the signal sending checks if the parent changes their +credentials during exec. + +The severity of this problem can been seen that in my limited testing +of a 32bit exec_id it can take as little as 19s to exec 65536 times. +Which means that it can take as little as 14 days to wrap a 32bit +exec_id. Adam Zabrocki has succeeded wrapping the self_exe_id in 7 +days. Even my slower timing is in the uptime of a typical server. +Which means self_exec_id is simply a speed bump today, and if exec +gets noticably faster self_exec_id won't even be a speed bump. + +Extending self_exec_id to 64bits introduces a problem on 32bit +architectures where reading self_exec_id is no longer atomic and can +take two read instructions. Which means that is is possible to hit +a window where the read value of exec_id does not match the written +value. So with very lucky timing after this change this still +remains expoiltable. + +I have updated the update of exec_id on exec to use WRITE_ONCE +and the read of exec_id in do_notify_parent to use READ_ONCE +to make it clear that there is no locking between these two +locations. + +Link: https://lore.kernel.org/kernel-hardening/20200324215049.GA3710@pi3.com.pl +Fixes: 2.3.23pre2 +Cc: stable@vger.kernel.org +Signed-off-by: "Eric W. Biederman" +Signed-off-by: Greg Kroah-Hartman + +--- + fs/exec.c | 2 +- + include/linux/sched.h | 4 ++-- + kernel/signal.c | 2 +- + 3 files changed, 4 insertions(+), 4 deletions(-) + +--- a/fs/exec.c ++++ b/fs/exec.c +@@ -1386,7 +1386,7 @@ void setup_new_exec(struct linux_binprm + + /* An exec changes our domain. We are no longer part of the thread + group */ +- current->self_exec_id++; ++ WRITE_ONCE(current->self_exec_id, current->self_exec_id + 1); + flush_signal_handlers(current, 0); + } + EXPORT_SYMBOL(setup_new_exec); +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -939,8 +939,8 @@ struct task_struct { + struct seccomp seccomp; + + /* Thread group tracking: */ +- u32 parent_exec_id; +- u32 self_exec_id; ++ u64 parent_exec_id; ++ u64 self_exec_id; + + /* Protection against (de-)allocation: mm, files, fs, tty, keyrings, mems_allowed, mempolicy: */ + spinlock_t alloc_lock; +--- a/kernel/signal.c ++++ b/kernel/signal.c +@@ -1931,7 +1931,7 @@ bool do_notify_parent(struct task_struct + * This is only possible if parent == real_parent. + * Check if it has changed security domain. + */ +- if (tsk->parent_exec_id != tsk->parent->self_exec_id) ++ if (tsk->parent_exec_id != READ_ONCE(tsk->parent->self_exec_id)) + sig = SIGCHLD; + } + diff --git a/queue-5.6/x86-entry-32-add-missing-asm_clac-to-general_protection-entry.patch b/queue-5.6/x86-entry-32-add-missing-asm_clac-to-general_protection-entry.patch new file mode 100644 index 00000000000..b69330588da --- /dev/null +++ b/queue-5.6/x86-entry-32-add-missing-asm_clac-to-general_protection-entry.patch @@ -0,0 +1,35 @@ +From 3d51507f29f2153a658df4a0674ec5b592b62085 Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Tue, 25 Feb 2020 22:36:37 +0100 +Subject: x86/entry/32: Add missing ASM_CLAC to general_protection entry + +From: Thomas Gleixner + +commit 3d51507f29f2153a658df4a0674ec5b592b62085 upstream. + +All exception entry points must have ASM_CLAC right at the +beginning. The general_protection entry is missing one. + +Fixes: e59d1b0a2419 ("x86-32, smap: Add STAC/CLAC instructions to 32-bit kernel entry") +Signed-off-by: Thomas Gleixner +Reviewed-by: Frederic Weisbecker +Reviewed-by: Alexandre Chartre +Reviewed-by: Andy Lutomirski +Cc: stable@vger.kernel.org +Link: https://lkml.kernel.org/r/20200225220216.219537887@linutronix.de +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/entry/entry_32.S | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/x86/entry/entry_32.S ++++ b/arch/x86/entry/entry_32.S +@@ -1694,6 +1694,7 @@ SYM_CODE_START(int3) + SYM_CODE_END(int3) + + SYM_CODE_START(general_protection) ++ ASM_CLAC + pushl $do_general_protection + jmp common_exception + SYM_CODE_END(general_protection) diff --git a/queue-5.6/x86-tsc_msr-fix-msr_fsb_freq-mask-for-cherry-trail-devices.patch b/queue-5.6/x86-tsc_msr-fix-msr_fsb_freq-mask-for-cherry-trail-devices.patch new file mode 100644 index 00000000000..0448c4d9ca2 --- /dev/null +++ b/queue-5.6/x86-tsc_msr-fix-msr_fsb_freq-mask-for-cherry-trail-devices.patch @@ -0,0 +1,127 @@ +From c8810e2ffc30c7e1577f9c057c4b85d984bbc35a Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Sun, 23 Feb 2020 15:06:09 +0100 +Subject: x86/tsc_msr: Fix MSR_FSB_FREQ mask for Cherry Trail devices + +From: Hans de Goede + +commit c8810e2ffc30c7e1577f9c057c4b85d984bbc35a upstream. + +According to the "Intel 64 and IA-32 Architectures Software Developer's +Manual Volume 4: Model-Specific Registers" on Cherry Trail (Airmont) +devices the 4 lowest bits of the MSR_FSB_FREQ mask indicate the bus freq +unlike on e.g. Bay Trail where only the lowest 3 bits are used. + +This is also the reason why MAX_NUM_FREQS is defined as 9, since Cherry +Trail SoCs have 9 possible frequencies, so the lo value from the MSR needs +to be masked with 0x0f, not with 0x07 otherwise the 9th frequency will get +interpreted as the 1st. + +Bump MAX_NUM_FREQS to 16 to avoid any possibility of addressing the array +out of bounds and makes the mask part of the cpufreq struct so it can be +set it per model. + +While at it also log an error when the index points to an uninitialized +part of the freqs lookup-table. + +Signed-off-by: Hans de Goede +Signed-off-by: Thomas Gleixner +Cc: stable@vger.kernel.org +Link: https://lkml.kernel.org/r/20200223140610.59612-2-hdegoede@redhat.com +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/tsc_msr.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +--- a/arch/x86/kernel/tsc_msr.c ++++ b/arch/x86/kernel/tsc_msr.c +@@ -15,7 +15,7 @@ + #include + #include + +-#define MAX_NUM_FREQS 9 ++#define MAX_NUM_FREQS 16 /* 4 bits to select the frequency */ + + /* + * If MSR_PERF_STAT[31] is set, the maximum resolved bus ratio can be +@@ -27,6 +27,7 @@ + struct freq_desc { + bool use_msr_plat; + u32 freqs[MAX_NUM_FREQS]; ++ u32 mask; + }; + + /* +@@ -37,37 +38,44 @@ struct freq_desc { + static const struct freq_desc freq_desc_pnw = { + .use_msr_plat = false, + .freqs = { 0, 0, 0, 0, 0, 99840, 0, 83200 }, ++ .mask = 0x07, + }; + + static const struct freq_desc freq_desc_clv = { + .use_msr_plat = false, + .freqs = { 0, 133200, 0, 0, 0, 99840, 0, 83200 }, ++ .mask = 0x07, + }; + + static const struct freq_desc freq_desc_byt = { + .use_msr_plat = true, + .freqs = { 83300, 100000, 133300, 116700, 80000, 0, 0, 0 }, ++ .mask = 0x07, + }; + + static const struct freq_desc freq_desc_cht = { + .use_msr_plat = true, + .freqs = { 83300, 100000, 133300, 116700, 80000, 93300, 90000, + 88900, 87500 }, ++ .mask = 0x0f, + }; + + static const struct freq_desc freq_desc_tng = { + .use_msr_plat = true, + .freqs = { 0, 100000, 133300, 0, 0, 0, 0, 0 }, ++ .mask = 0x07, + }; + + static const struct freq_desc freq_desc_ann = { + .use_msr_plat = true, + .freqs = { 83300, 100000, 133300, 100000, 0, 0, 0, 0 }, ++ .mask = 0x0f, + }; + + static const struct freq_desc freq_desc_lgm = { + .use_msr_plat = true, + .freqs = { 78000, 78000, 78000, 78000, 78000, 78000, 78000, 78000 }, ++ .mask = 0x0f, + }; + + static const struct x86_cpu_id tsc_msr_cpu_ids[] = { +@@ -93,6 +101,7 @@ unsigned long cpu_khz_from_msr(void) + const struct freq_desc *freq_desc; + const struct x86_cpu_id *id; + unsigned long res; ++ int index; + + id = x86_match_cpu(tsc_msr_cpu_ids); + if (!id) +@@ -109,13 +118,17 @@ unsigned long cpu_khz_from_msr(void) + + /* Get FSB FREQ ID */ + rdmsr(MSR_FSB_FREQ, lo, hi); ++ index = lo & freq_desc->mask; + + /* Map CPU reference clock freq ID(0-7) to CPU reference clock freq(KHz) */ +- freq = freq_desc->freqs[lo & 0x7]; ++ freq = freq_desc->freqs[index]; + + /* TSC frequency = maximum resolved freq * maximum resolved bus ratio */ + res = freq * ratio; + ++ if (freq == 0) ++ pr_err("Error MSR_FSB_FREQ index %d is unknown\n", index); ++ + #ifdef CONFIG_X86_LOCAL_APIC + lapic_timer_period = (freq * 1000) / HZ; + #endif diff --git a/queue-5.6/x86-tsc_msr-make-msr-derived-tsc-frequency-more-accurate.patch b/queue-5.6/x86-tsc_msr-make-msr-derived-tsc-frequency-more-accurate.patch new file mode 100644 index 00000000000..69165138997 --- /dev/null +++ b/queue-5.6/x86-tsc_msr-make-msr-derived-tsc-frequency-more-accurate.patch @@ -0,0 +1,228 @@ +From fac01d11722c92a186b27ee26cd429a8066adfb5 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Sun, 23 Feb 2020 15:06:10 +0100 +Subject: x86/tsc_msr: Make MSR derived TSC frequency more accurate +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Hans de Goede + +commit fac01d11722c92a186b27ee26cd429a8066adfb5 upstream. + +The "Intel 64 and IA-32 Architectures Software Developer’s Manual Volume 4: +Model-Specific Registers" has the following table for the values from +freq_desc_byt: + + 000B: 083.3 MHz + 001B: 100.0 MHz + 010B: 133.3 MHz + 011B: 116.7 MHz + 100B: 080.0 MHz + +Notice how for e.g the 83.3 MHz value there are 3 significant digits, which +translates to an accuracy of a 1000 ppm, where as a typical crystal +oscillator is 20 - 100 ppm, so the accuracy of the frequency format used in +the Software Developer’s Manual is not really helpful. + +As far as we know Bay Trail SoCs use a 25 MHz crystal and Cherry Trail +uses a 19.2 MHz crystal, the crystal is the source clock for a root PLL +which outputs 1600 and 100 MHz. It is unclear if the root PLL outputs are +used directly by the CPU clock PLL or if there is another PLL in between. + +This does not matter though, we can model the chain of PLLs as a single PLL +with a quotient equal to the quotients of all PLLs in the chain multiplied. + +So we can create a simplified model of the CPU clock setup using a +reference clock of 100 MHz plus a quotient which gets us as close to the +frequency from the SDM as possible. + +For the 83.3 MHz example from above this would give 100 MHz * 5 / 6 = 83 +and 1/3 MHz, which matches exactly what has been measured on actual +hardware. + +Use a simplified PLL model with a reference clock of 100 MHz for all Bay +and Cherry Trail models. + +This has been tested on the following models: + + CPU freq before: CPU freq after: +Intel N2840 2165.800 MHz 2166.667 MHz +Intel Z3736 1332.800 MHz 1333.333 MHz +Intel Z3775 1466.300 MHz 1466.667 MHz +Intel Z8350 1440.000 MHz 1440.000 MHz +Intel Z8750 1600.000 MHz 1600.000 MHz + +This fixes the time drifting by about 1 second per hour (20 - 30 seconds +per day) on (some) devices which rely on the tsc_msr.c code to determine +the TSC frequency. + +Reported-by: Vipul Kumar +Suggested-by: Thomas Gleixner +Signed-off-by: Hans de Goede +Signed-off-by: Thomas Gleixner +Cc: stable@vger.kernel.org +Link: https://lkml.kernel.org/r/20200223140610.59612-3-hdegoede@redhat.com +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/tsc_msr.c | 97 ++++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 86 insertions(+), 11 deletions(-) + +--- a/arch/x86/kernel/tsc_msr.c ++++ b/arch/x86/kernel/tsc_msr.c +@@ -18,6 +18,28 @@ + #define MAX_NUM_FREQS 16 /* 4 bits to select the frequency */ + + /* ++ * The frequency numbers in the SDM are e.g. 83.3 MHz, which does not contain a ++ * lot of accuracy which leads to clock drift. As far as we know Bay Trail SoCs ++ * use a 25 MHz crystal and Cherry Trail uses a 19.2 MHz crystal, the crystal ++ * is the source clk for a root PLL which outputs 1600 and 100 MHz. It is ++ * unclear if the root PLL outputs are used directly by the CPU clock PLL or ++ * if there is another PLL in between. ++ * This does not matter though, we can model the chain of PLLs as a single PLL ++ * with a quotient equal to the quotients of all PLLs in the chain multiplied. ++ * So we can create a simplified model of the CPU clock setup using a reference ++ * clock of 100 MHz plus a quotient which gets us as close to the frequency ++ * from the SDM as possible. ++ * For the 83.3 MHz example from above this would give us 100 MHz * 5 / 6 = ++ * 83 and 1/3 MHz, which matches exactly what has been measured on actual hw. ++ */ ++#define TSC_REFERENCE_KHZ 100000 ++ ++struct muldiv { ++ u32 multiplier; ++ u32 divider; ++}; ++ ++/* + * If MSR_PERF_STAT[31] is set, the maximum resolved bus ratio can be + * read in MSR_PLATFORM_ID[12:8], otherwise in MSR_PERF_STAT[44:40]. + * Unfortunately some Intel Atom SoCs aren't quite compliant to this, +@@ -26,6 +48,11 @@ + */ + struct freq_desc { + bool use_msr_plat; ++ struct muldiv muldiv[MAX_NUM_FREQS]; ++ /* ++ * Some CPU frequencies in the SDM do not map to known PLL freqs, in ++ * that case the muldiv array is empty and the freqs array is used. ++ */ + u32 freqs[MAX_NUM_FREQS]; + u32 mask; + }; +@@ -47,31 +74,66 @@ static const struct freq_desc freq_desc_ + .mask = 0x07, + }; + ++/* ++ * Bay Trail SDM MSR_FSB_FREQ frequencies simplified PLL model: ++ * 000: 100 * 5 / 6 = 83.3333 MHz ++ * 001: 100 * 1 / 1 = 100.0000 MHz ++ * 010: 100 * 4 / 3 = 133.3333 MHz ++ * 011: 100 * 7 / 6 = 116.6667 MHz ++ * 100: 100 * 4 / 5 = 80.0000 MHz ++ */ + static const struct freq_desc freq_desc_byt = { + .use_msr_plat = true, +- .freqs = { 83300, 100000, 133300, 116700, 80000, 0, 0, 0 }, ++ .muldiv = { { 5, 6 }, { 1, 1 }, { 4, 3 }, { 7, 6 }, ++ { 4, 5 } }, + .mask = 0x07, + }; + ++/* ++ * Cherry Trail SDM MSR_FSB_FREQ frequencies simplified PLL model: ++ * 0000: 100 * 5 / 6 = 83.3333 MHz ++ * 0001: 100 * 1 / 1 = 100.0000 MHz ++ * 0010: 100 * 4 / 3 = 133.3333 MHz ++ * 0011: 100 * 7 / 6 = 116.6667 MHz ++ * 0100: 100 * 4 / 5 = 80.0000 MHz ++ * 0101: 100 * 14 / 15 = 93.3333 MHz ++ * 0110: 100 * 9 / 10 = 90.0000 MHz ++ * 0111: 100 * 8 / 9 = 88.8889 MHz ++ * 1000: 100 * 7 / 8 = 87.5000 MHz ++ */ + static const struct freq_desc freq_desc_cht = { + .use_msr_plat = true, +- .freqs = { 83300, 100000, 133300, 116700, 80000, 93300, 90000, +- 88900, 87500 }, ++ .muldiv = { { 5, 6 }, { 1, 1 }, { 4, 3 }, { 7, 6 }, ++ { 4, 5 }, { 14, 15 }, { 9, 10 }, { 8, 9 }, ++ { 7, 8 } }, + .mask = 0x0f, + }; + ++/* ++ * Merriefield SDM MSR_FSB_FREQ frequencies simplified PLL model: ++ * 0001: 100 * 1 / 1 = 100.0000 MHz ++ * 0010: 100 * 4 / 3 = 133.3333 MHz ++ */ + static const struct freq_desc freq_desc_tng = { + .use_msr_plat = true, +- .freqs = { 0, 100000, 133300, 0, 0, 0, 0, 0 }, ++ .muldiv = { { 0, 0 }, { 1, 1 }, { 4, 3 } }, + .mask = 0x07, + }; + ++/* ++ * Moorefield SDM MSR_FSB_FREQ frequencies simplified PLL model: ++ * 0000: 100 * 5 / 6 = 83.3333 MHz ++ * 0001: 100 * 1 / 1 = 100.0000 MHz ++ * 0010: 100 * 4 / 3 = 133.3333 MHz ++ * 0011: 100 * 1 / 1 = 100.0000 MHz ++ */ + static const struct freq_desc freq_desc_ann = { + .use_msr_plat = true, +- .freqs = { 83300, 100000, 133300, 100000, 0, 0, 0, 0 }, ++ .muldiv = { { 5, 6 }, { 1, 1 }, { 4, 3 }, { 1, 1 } }, + .mask = 0x0f, + }; + ++/* 24 MHz crystal? : 24 * 13 / 4 = 78 MHz */ + static const struct freq_desc freq_desc_lgm = { + .use_msr_plat = true, + .freqs = { 78000, 78000, 78000, 78000, 78000, 78000, 78000, 78000 }, +@@ -97,9 +159,10 @@ static const struct x86_cpu_id tsc_msr_c + */ + unsigned long cpu_khz_from_msr(void) + { +- u32 lo, hi, ratio, freq; ++ u32 lo, hi, ratio, freq, tscref; + const struct freq_desc *freq_desc; + const struct x86_cpu_id *id; ++ const struct muldiv *md; + unsigned long res; + int index; + +@@ -119,12 +182,24 @@ unsigned long cpu_khz_from_msr(void) + /* Get FSB FREQ ID */ + rdmsr(MSR_FSB_FREQ, lo, hi); + index = lo & freq_desc->mask; ++ md = &freq_desc->muldiv[index]; + +- /* Map CPU reference clock freq ID(0-7) to CPU reference clock freq(KHz) */ +- freq = freq_desc->freqs[index]; +- +- /* TSC frequency = maximum resolved freq * maximum resolved bus ratio */ +- res = freq * ratio; ++ /* ++ * Note this also catches cases where the index points to an unpopulated ++ * part of muldiv, in that case the else will set freq and res to 0. ++ */ ++ if (md->divider) { ++ tscref = TSC_REFERENCE_KHZ * md->multiplier; ++ freq = DIV_ROUND_CLOSEST(tscref, md->divider); ++ /* ++ * Multiplying by ratio before the division has better ++ * accuracy than just calculating freq * ratio. ++ */ ++ res = DIV_ROUND_CLOSEST(tscref * ratio, md->divider); ++ } else { ++ freq = freq_desc->freqs[index]; ++ res = freq * ratio; ++ } + + if (freq == 0) + pr_err("Error MSR_FSB_FREQ index %d is unknown\n", index); diff --git a/queue-5.6/x86-tsc_msr-use-named-struct-initializers.patch b/queue-5.6/x86-tsc_msr-use-named-struct-initializers.patch new file mode 100644 index 00000000000..00fbd1004d6 --- /dev/null +++ b/queue-5.6/x86-tsc_msr-use-named-struct-initializers.patch @@ -0,0 +1,94 @@ +From 812c2d7506fde7cdf83cb2532810a65782b51741 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Sun, 23 Feb 2020 15:06:08 +0100 +Subject: x86/tsc_msr: Use named struct initializers + +From: Hans de Goede + +commit 812c2d7506fde7cdf83cb2532810a65782b51741 upstream. + +Use named struct initializers for the freq_desc struct-s initialization +and change the "u8 msr_plat" to a "bool use_msr_plat" to make its meaning +more clear instead of relying on a comment to explain it. + +Signed-off-by: Hans de Goede +Signed-off-by: Thomas Gleixner +Cc: stable@vger.kernel.org +Link: https://lkml.kernel.org/r/20200223140610.59612-1-hdegoede@redhat.com +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/tsc_msr.c | 28 ++++++++++++++++++---------- + 1 file changed, 18 insertions(+), 10 deletions(-) + +--- a/arch/x86/kernel/tsc_msr.c ++++ b/arch/x86/kernel/tsc_msr.c +@@ -22,10 +22,10 @@ + * read in MSR_PLATFORM_ID[12:8], otherwise in MSR_PERF_STAT[44:40]. + * Unfortunately some Intel Atom SoCs aren't quite compliant to this, + * so we need manually differentiate SoC families. This is what the +- * field msr_plat does. ++ * field use_msr_plat does. + */ + struct freq_desc { +- u8 msr_plat; /* 1: use MSR_PLATFORM_INFO, 0: MSR_IA32_PERF_STATUS */ ++ bool use_msr_plat; + u32 freqs[MAX_NUM_FREQS]; + }; + +@@ -35,31 +35,39 @@ struct freq_desc { + * by MSR based on SDM. + */ + static const struct freq_desc freq_desc_pnw = { +- 0, { 0, 0, 0, 0, 0, 99840, 0, 83200 } ++ .use_msr_plat = false, ++ .freqs = { 0, 0, 0, 0, 0, 99840, 0, 83200 }, + }; + + static const struct freq_desc freq_desc_clv = { +- 0, { 0, 133200, 0, 0, 0, 99840, 0, 83200 } ++ .use_msr_plat = false, ++ .freqs = { 0, 133200, 0, 0, 0, 99840, 0, 83200 }, + }; + + static const struct freq_desc freq_desc_byt = { +- 1, { 83300, 100000, 133300, 116700, 80000, 0, 0, 0 } ++ .use_msr_plat = true, ++ .freqs = { 83300, 100000, 133300, 116700, 80000, 0, 0, 0 }, + }; + + static const struct freq_desc freq_desc_cht = { +- 1, { 83300, 100000, 133300, 116700, 80000, 93300, 90000, 88900, 87500 } ++ .use_msr_plat = true, ++ .freqs = { 83300, 100000, 133300, 116700, 80000, 93300, 90000, ++ 88900, 87500 }, + }; + + static const struct freq_desc freq_desc_tng = { +- 1, { 0, 100000, 133300, 0, 0, 0, 0, 0 } ++ .use_msr_plat = true, ++ .freqs = { 0, 100000, 133300, 0, 0, 0, 0, 0 }, + }; + + static const struct freq_desc freq_desc_ann = { +- 1, { 83300, 100000, 133300, 100000, 0, 0, 0, 0 } ++ .use_msr_plat = true, ++ .freqs = { 83300, 100000, 133300, 100000, 0, 0, 0, 0 }, + }; + + static const struct freq_desc freq_desc_lgm = { +- 1, { 78000, 78000, 78000, 78000, 78000, 78000, 78000, 78000 } ++ .use_msr_plat = true, ++ .freqs = { 78000, 78000, 78000, 78000, 78000, 78000, 78000, 78000 }, + }; + + static const struct x86_cpu_id tsc_msr_cpu_ids[] = { +@@ -91,7 +99,7 @@ unsigned long cpu_khz_from_msr(void) + return 0; + + freq_desc = (struct freq_desc *)id->driver_data; +- if (freq_desc->msr_plat) { ++ if (freq_desc->use_msr_plat) { + rdmsr(MSR_PLATFORM_INFO, lo, hi); + ratio = (lo >> 8) & 0xff; + } else {