--- /dev/null
+From 968ae2caad0782db5dbbabb560d3cdefd2945d38 Mon Sep 17 00:00:00 2001
+From: Remi Pommarel <repk@triplefau.lt>
+Date: Sat, 29 Feb 2020 17:13:47 +0100
+Subject: ath9k: Handle txpower changes even when TPC is disabled
+
+From: Remi Pommarel <repk@triplefau.lt>
+
+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 <repk@triplefau.lt>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
+
--- /dev/null
+From e98eac6ff1b45e4e73f2e6031b37c256ccb5d36b Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Fri, 27 Mar 2020 12:06:44 +0100
+Subject: cpu/hotplug: Ignore pm_wakeup_pending() for disable_nonboot_cpus()
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+commit e98eac6ff1b45e4e73f2e6031b37c256ccb5d36b upstream.
+
+A recent change to freeze_secondary_cpus() which added an early abort if a
+wakeup is pending missed the fact that the function is also invoked for
+shutdown, reboot and kexec via disable_nonboot_cpus().
+
+In case of disable_nonboot_cpus() the wakeup event needs to be ignored as
+the purpose is to terminate the currently running kernel.
+
+Add a 'suspend' argument which is only set when the freeze is in context of
+a suspend operation. If not set then an eventually pending wakeup event is
+ignored.
+
+Fixes: a66d955e910a ("cpu/hotplug: Abort disabling secondary CPUs if wakeup is pending")
+Reported-by: Boqun Feng <boqun.feng@gmail.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: Pavankumar Kondeti <pkondeti@codeaurora.org>
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/r/874kuaxdiz.fsf@nanos.tec.linutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/cpu.h | 12 +++++++++---
+ kernel/cpu.c | 4 ++--
+ 2 files changed, 11 insertions(+), 5 deletions(-)
+
+--- a/include/linux/cpu.h
++++ b/include/linux/cpu.h
+@@ -138,12 +138,18 @@ static inline void get_online_cpus(void)
+ static inline void put_online_cpus(void) { cpus_read_unlock(); }
+
+ #ifdef CONFIG_PM_SLEEP_SMP
+-extern int freeze_secondary_cpus(int primary);
++int __freeze_secondary_cpus(int primary, bool suspend);
++static inline int freeze_secondary_cpus(int primary)
++{
++ return __freeze_secondary_cpus(primary, true);
++}
++
+ static inline int disable_nonboot_cpus(void)
+ {
+- return freeze_secondary_cpus(0);
++ return __freeze_secondary_cpus(0, false);
+ }
+-extern void enable_nonboot_cpus(void);
++
++void enable_nonboot_cpus(void);
+
+ static inline int suspend_disable_secondary_cpus(void)
+ {
+--- a/kernel/cpu.c
++++ b/kernel/cpu.c
+@@ -1212,7 +1212,7 @@ EXPORT_SYMBOL_GPL(cpu_up);
+ #ifdef CONFIG_PM_SLEEP_SMP
+ static cpumask_var_t frozen_cpus;
+
+-int freeze_secondary_cpus(int primary)
++int __freeze_secondary_cpus(int primary, bool suspend)
+ {
+ int cpu, error = 0;
+
+@@ -1237,7 +1237,7 @@ int freeze_secondary_cpus(int primary)
+ if (cpu == primary)
+ continue;
+
+- if (pm_wakeup_pending()) {
++ if (suspend && pm_wakeup_pending()) {
+ pr_info("Wakeup pending. Abort CPU freeze\n");
+ error = -EBUSY;
+ break;
--- /dev/null
+From a740a423c36932695b01a3e920f697bc55b05fec Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Fri, 6 Mar 2020 14:03:42 +0100
+Subject: genirq/debugfs: Add missing sanity checks to interrupt injection
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+commit a740a423c36932695b01a3e920f697bc55b05fec upstream.
+
+Interrupts cannot be injected when the interrupt is not activated and when
+a replay is already in progress.
+
+Fixes: 536e2e34bd00 ("genirq/debugfs: Triggering of interrupts from userspace")
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Acked-by: Marc Zyngier <maz@kernel.org>
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/r/20200306130623.500019114@linutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/irq/debugfs.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/kernel/irq/debugfs.c
++++ b/kernel/irq/debugfs.c
+@@ -206,8 +206,15 @@ static ssize_t irq_debug_write(struct fi
+ chip_bus_lock(desc);
+ raw_spin_lock_irqsave(&desc->lock, flags);
+
+- if (irq_settings_is_level(desc) || desc->istate & IRQS_NMI) {
+- /* Can't do level nor NMIs, sorry */
++ /*
++ * Don't allow injection when the interrupt is:
++ * - Level or NMI type
++ * - not activated
++ * - replaying already
++ */
++ if (irq_settings_is_level(desc) ||
++ !irqd_is_activated(&desc->irq_data) ||
++ (desc->istate & (IRQS_NMI | IRQS_REPLAY))) {
+ err = -EINVAL;
+ } else {
+ desc->istate |= IRQS_PENDING;
--- /dev/null
+From c336e992cb1cb1db9ee608dfb30342ae781057ab Mon Sep 17 00:00:00 2001
+From: Jens Axboe <axboe@kernel.dk>
+Date: Fri, 3 Apr 2020 13:54:26 -0600
+Subject: io_uring: remove bogus RLIMIT_NOFILE check in file registration
+
+From: Jens Axboe <axboe@kernel.dk>
+
+commit c336e992cb1cb1db9ee608dfb30342ae781057ab upstream.
+
+We already checked this limit when the file was opened, and we keep it
+open in the file table. Hence when we added unit_inflight to the count
+we want to register, we're doubly accounting these files. This results
+in -EMFILE for file registration, if we're at half the limit.
+
+Cc: stable@vger.kernel.org # v5.1+
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/io_uring.c | 7 -------
+ 1 file changed, 7 deletions(-)
+
+--- a/fs/io_uring.c
++++ b/fs/io_uring.c
+@@ -3092,13 +3092,6 @@ static int __io_sqe_files_scm(struct io_
+ struct sk_buff *skb;
+ int i;
+
+- if (!capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN)) {
+- unsigned long inflight = ctx->user->unix_inflight + nr;
+-
+- if (inflight > task_rlimit(current, RLIMIT_NOFILE))
+- return -EMFILE;
+- }
+-
+ fpl = kzalloc(sizeof(*fpl), GFP_KERNEL);
+ if (!fpl)
+ return -ENOMEM;
--- /dev/null
+From 6a214a28132f19ace3d835a6d8f6422ec80ad200 Mon Sep 17 00:00:00 2001
+From: Sungbo Eo <mans0n@gorani.run>
+Date: Sat, 21 Mar 2020 22:38:42 +0900
+Subject: irqchip/versatile-fpga: Apply clear-mask earlier
+
+From: Sungbo Eo <mans0n@gorani.run>
+
+commit 6a214a28132f19ace3d835a6d8f6422ec80ad200 upstream.
+
+Clear its own IRQs before the parent IRQ get enabled, so that the
+remaining IRQs do not accidentally interrupt the parent IRQ controller.
+
+This patch also fixes a reboot bug on OX820 SoC, where the remaining
+rps-timer IRQ raises a GIC interrupt that is left pending. After that,
+the rps-timer IRQ is cleared during driver initialization, and there's
+no IRQ left in rps-irq when local_irq_enable() is called, which evokes
+an error message "unexpected IRQ trap".
+
+Fixes: bdd272cbb97a ("irqchip: versatile FPGA: support cascaded interrupts from DT")
+Signed-off-by: Sungbo Eo <mans0n@gorani.run>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20200321133842.2408823-1-mans0n@gorani.run
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/irqchip/irq-versatile-fpga.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/irqchip/irq-versatile-fpga.c
++++ b/drivers/irqchip/irq-versatile-fpga.c
+@@ -212,6 +212,9 @@ int __init fpga_irq_of_init(struct devic
+ if (of_property_read_u32(node, "valid-mask", &valid_mask))
+ valid_mask = 0;
+
++ writel(clear_mask, base + IRQ_ENABLE_CLEAR);
++ writel(clear_mask, base + FIQ_ENABLE_CLEAR);
++
+ /* Some chips are cascaded from a parent IRQ */
+ parent_irq = irq_of_parse_and_map(node, 0);
+ if (!parent_irq) {
+@@ -221,9 +224,6 @@ int __init fpga_irq_of_init(struct devic
+
+ fpga_irq_init(base, node->name, 0, parent_irq, valid_mask, node);
+
+- writel(clear_mask, base + IRQ_ENABLE_CLEAR);
+- writel(clear_mask, base + FIQ_ENABLE_CLEAR);
+-
+ /*
+ * On Versatile AB/PB, some secondary interrupts have a direct
+ * pass-thru to the primary controller for IRQs 20 and 22-31 which need
--- /dev/null
+From 792a402c2840054533ef56279c212ef6da87d811 Mon Sep 17 00:00:00 2001
+From: "Gustavo A. R. Silva" <gustavo@embeddedor.com>
+Date: Tue, 22 Jan 2019 14:18:42 -0600
+Subject: MIPS: OCTEON: irq: Fix potential NULL pointer dereference
+
+From: Gustavo A. R. Silva <gustavo@embeddedor.com>
+
+commit 792a402c2840054533ef56279c212ef6da87d811 upstream.
+
+There is a potential NULL pointer dereference in case kzalloc()
+fails and returns NULL.
+
+Fix this by adding a NULL check on *cd*
+
+This bug was detected with the help of Coccinelle.
+
+Fixes: 64b139f97c01 ("MIPS: OCTEON: irq: add CIB and other fixes")
+Cc: stable@vger.kernel.org
+Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/cavium-octeon/octeon-irq.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/arch/mips/cavium-octeon/octeon-irq.c
++++ b/arch/mips/cavium-octeon/octeon-irq.c
+@@ -2199,6 +2199,9 @@ static int octeon_irq_cib_map(struct irq
+ }
+
+ cd = kzalloc(sizeof(*cd), GFP_KERNEL);
++ if (!cd)
++ return -ENOMEM;
++
+ cd->host_data = host_data;
+ cd->bit = hw;
+
--- /dev/null
+From d191aaffe3687d1e73e644c185f5f0550ec242b5 Mon Sep 17 00:00:00 2001
+From: Huacai Chen <chenhc@lemote.com>
+Date: Wed, 25 Mar 2020 11:44:54 +0800
+Subject: MIPS/tlbex: Fix LDDIR usage in setup_pw() for Loongson-3
+
+From: Huacai Chen <chenhc@lemote.com>
+
+commit d191aaffe3687d1e73e644c185f5f0550ec242b5 upstream.
+
+LDDIR/LDPTE is Loongson-3's acceleration for Page Table Walking. If BD
+(Base Directory, the 4th page directory) is not enabled, then GDOffset
+is biased by BadVAddr[63:62]. So, if GDOffset (aka. BadVAddr[47:36] for
+Loongson-3) is big enough, "0b11(BadVAddr[63:62])|BadVAddr[47:36]|...."
+can far beyond pg_swapper_dir. This means the pg_swapper_dir may NOT be
+accessed by LDDIR correctly, so fix it by set PWDirExt in CP0_PWCtl.
+
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Pei Huang <huangpei@loongson.cn>
+Signed-off-by: Huacai Chen <chenhc@lemote.com>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/mm/tlbex.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/arch/mips/mm/tlbex.c
++++ b/arch/mips/mm/tlbex.c
+@@ -1480,6 +1480,7 @@ static void build_r4000_tlb_refill_handl
+
+ static void setup_pw(void)
+ {
++ unsigned int pwctl;
+ unsigned long pgd_i, pgd_w;
+ #ifndef __PAGETABLE_PMD_FOLDED
+ unsigned long pmd_i, pmd_w;
+@@ -1506,6 +1507,7 @@ static void setup_pw(void)
+
+ pte_i = ilog2(_PAGE_GLOBAL);
+ pte_w = 0;
++ pwctl = 1 << 30; /* Set PWDirExt */
+
+ #ifndef __PAGETABLE_PMD_FOLDED
+ write_c0_pwfield(pgd_i << 24 | pmd_i << 12 | pt_i << 6 | pte_i);
+@@ -1516,8 +1518,9 @@ static void setup_pw(void)
+ #endif
+
+ #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
+- write_c0_pwctl(1 << 6 | psn);
++ pwctl |= (1 << 6 | psn);
+ #endif
++ write_c0_pwctl(pwctl);
+ write_c0_kpgd((long)swapper_pg_dir);
+ kscratch_used_mask |= (1 << 7); /* KScratch6 is used for KPGD */
+ }
--- /dev/null
+From 56cb26891ea4180121265dc6b596015772c4a4b8 Mon Sep 17 00:00:00 2001
+From: Ulf Hansson <ulf.hansson@linaro.org>
+Date: Tue, 10 Mar 2020 11:40:23 +0100
+Subject: PM / Domains: Allow no domain-idle-states DT property in genpd when parsing
+
+From: Ulf Hansson <ulf.hansson@linaro.org>
+
+commit 56cb26891ea4180121265dc6b596015772c4a4b8 upstream.
+
+Commit 2c361684803e ("PM / Domains: Don't treat zero found compatible idle
+states as an error"), moved of_genpd_parse_idle_states() towards allowing
+none compatible idle state to be found for the device node, rather than
+returning an error code.
+
+However, it didn't consider that the "domain-idle-states" DT property may
+be missing as it's optional, which makes of_count_phandle_with_args() to
+return -ENOENT. Let's fix this to make the behaviour consistent.
+
+Fixes: 2c361684803e ("PM / Domains: Don't treat zero found compatible idle states as an error")
+Reported-by: Benjamin Gaignard <benjamin.gaignard@st.com>
+Cc: 4.20+ <stable@vger.kernel.org> # 4.20+
+Reviewed-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/base/power/domain.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/base/power/domain.c
++++ b/drivers/base/power/domain.c
+@@ -2615,7 +2615,7 @@ static int genpd_iterate_idle_states(str
+
+ ret = of_count_phandle_with_args(dn, "domain-idle-states", NULL);
+ if (ret <= 0)
+- return ret;
++ return ret == -ENOENT ? 0 : ret;
+
+ /* Loop over the phandles until all the requested entry is found */
+ of_for_each_phandle(&it, ret, dn, "domain-idle-states", NULL, 0) {
--- /dev/null
+From 87de6594dc45dbf6819f3e0ef92f9331c5a9444c Mon Sep 17 00:00:00 2001
+From: Neeraj Upadhyay <neeraju@codeaurora.org>
+Date: Mon, 23 Mar 2020 10:38:51 +0530
+Subject: PM: sleep: wakeup: Skip wakeup_source_sysfs_remove() if device is not there
+
+From: Neeraj Upadhyay <neeraju@codeaurora.org>
+
+commit 87de6594dc45dbf6819f3e0ef92f9331c5a9444c upstream.
+
+Skip wakeup_source_sysfs_remove() to fix a NULL pinter dereference via
+ws->dev, if the wakeup source is unregistered before registering the
+wakeup class from device_add().
+
+Fixes: 2ca3d1ecb8c4 ("PM / wakeup: Register wakeup class kobj after device is added")
+Signed-off-by: Neeraj Upadhyay <neeraju@codeaurora.org>
+Cc: 5.4+ <stable@vger.kernel.org> # 5.4+
+[ rjw: Subject & changelog, white space ]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/base/power/wakeup.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/base/power/wakeup.c
++++ b/drivers/base/power/wakeup.c
+@@ -241,7 +241,9 @@ void wakeup_source_unregister(struct wak
+ {
+ if (ws) {
+ wakeup_source_remove(ws);
+- wakeup_source_sysfs_remove(ws);
++ if (ws->dev)
++ wakeup_source_sysfs_remove(ws);
++
+ wakeup_source_destroy(ws);
+ }
+ }
--- /dev/null
+From 6c871b7314dde9ab64f20de8f5aa3d01be4518e8 Mon Sep 17 00:00:00 2001
+From: Vasily Averin <vvs@virtuozzo.com>
+Date: Tue, 25 Feb 2020 11:11:20 +0300
+Subject: pstore: pstore_ftrace_seq_next should increase position index
+
+From: Vasily Averin <vvs@virtuozzo.com>
+
+commit 6c871b7314dde9ab64f20de8f5aa3d01be4518e8 upstream.
+
+In Aug 2018 NeilBrown noticed
+commit 1f4aace60b0e ("fs/seq_file.c: simplify seq_file iteration code and interface")
+"Some ->next functions do not increment *pos when they return NULL...
+Note that such ->next functions are buggy and should be fixed.
+A simple demonstration is
+
+ dd if=/proc/swaps bs=1000 skip=1
+
+Choose any block size larger than the size of /proc/swaps. This will
+always show the whole last line of /proc/swaps"
+
+/proc/swaps output was fixed recently, however there are lot of other
+affected files, and one of them is related to pstore subsystem.
+
+If .next function does not change position index, following .show function
+will repeat output related to current position index.
+
+There are at least 2 related problems:
+- read after lseek beyond end of file, described above by NeilBrown
+ "dd if=<AFFECTED_FILE> bs=1000 skip=1" will generate whole last list
+- read after lseek on in middle of last line will output expected rest of
+ last line but then repeat whole last line once again.
+
+If .show() function generates multy-line output (like
+pstore_ftrace_seq_show() does ?) following bash script cycles endlessly
+
+ $ q=;while read -r r;do echo "$((++q)) $r";done < AFFECTED_FILE
+
+Unfortunately I'm not familiar enough to pstore subsystem and was unable
+to find affected pstore-related file on my test node.
+
+If .next function does not change position index, following .show function
+will repeat output related to current position index.
+
+Cc: stable@vger.kernel.org
+Fixes: 1f4aace60b0e ("fs/seq_file.c: simplify seq_file iteration code ...")
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=206283
+Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
+Link: https://lore.kernel.org/r/4e49830d-4c88-0171-ee24-1ee540028dad@virtuozzo.com
+[kees: with robustness tweak from Joel Fernandes <joelaf@google.com>]
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/pstore/inode.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/fs/pstore/inode.c
++++ b/fs/pstore/inode.c
+@@ -87,11 +87,11 @@ static void *pstore_ftrace_seq_next(stru
+ struct pstore_private *ps = s->private;
+ struct pstore_ftrace_seq_data *data = v;
+
++ (*pos)++;
+ data->off += REC_SIZE;
+ if (data->off + REC_SIZE > ps->total_size)
+ return NULL;
+
+- (*pos)++;
+ return data;
+ }
+
+@@ -101,6 +101,9 @@ static int pstore_ftrace_seq_show(struct
+ struct pstore_ftrace_seq_data *data = v;
+ struct pstore_ftrace_record *rec;
+
++ if (!data)
++ return 0;
++
+ rec = (struct pstore_ftrace_record *)(ps->record->buf + data->off);
+
+ seq_printf(s, "CPU:%d ts:%llu %08lx %08lx %ps <- %pS\n",
--- /dev/null
+From 5e958e4aacf44e1cc98b0d88d8e66e98f03bbf66 Mon Sep 17 00:00:00 2001
+From: Sowjanya Komatineni <skomatineni@nvidia.com>
+Date: Wed, 11 Mar 2020 08:47:54 -0700
+Subject: sdhci: tegra: Implement Tegra specific set_timeout callback
+
+From: Sowjanya Komatineni <skomatineni@nvidia.com>
+
+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 <skomatineni@nvidia.com>
+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 <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 = {
tpm-tpm1_bios_measurements_next-should-increase-position-index.patch
tpm-tpm2_bios_measurements_next-should-increase-position-index.patch
keys-reaching-the-keys-quotas-correctly.patch
+cpu-hotplug-ignore-pm_wakeup_pending-for-disable_nonboot_cpus.patch
+genirq-debugfs-add-missing-sanity-checks-to-interrupt-injection.patch
+irqchip-versatile-fpga-apply-clear-mask-earlier.patch
+io_uring-remove-bogus-rlimit_nofile-check-in-file-registration.patch
+pstore-pstore_ftrace_seq_next-should-increase-position-index.patch
+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
--- /dev/null
+From d1e7fd6462ca9fc76650fbe6ca800e35b24267da Mon Sep 17 00:00:00 2001
+From: "Eric W. Biederman" <ebiederm@xmission.com>
+Date: Mon, 30 Mar 2020 19:01:04 -0500
+Subject: signal: Extend exec_id to 64bits
+
+From: Eric W. Biederman <ebiederm@xmission.com>
+
+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" <ebiederm@xmission.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -1383,7 +1383,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
+@@ -934,8 +934,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;
+ }
+
--- /dev/null
+From 3d51507f29f2153a658df4a0674ec5b592b62085 Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Tue, 25 Feb 2020 22:36:37 +0100
+Subject: x86/entry/32: Add missing ASM_CLAC to general_protection entry
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+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 <tglx@linutronix.de>
+Reviewed-by: Frederic Weisbecker <frederic@kernel.org>
+Reviewed-by: Alexandre Chartre <alexandre.chartre@oracle.com>
+Reviewed-by: Andy Lutomirski <luto@kernel.org>
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/r/20200225220216.219537887@linutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -1647,6 +1647,7 @@ ENTRY(int3)
+ END(int3)
+
+ ENTRY(general_protection)
++ ASM_CLAC
+ pushl $do_general_protection
+ jmp common_exception
+ END(general_protection)
--- /dev/null
+From c8810e2ffc30c7e1577f9c057c4b85d984bbc35a Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+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 <hdegoede@redhat.com>
+
+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 <hdegoede@redhat.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/r/20200223140610.59612-2-hdegoede@redhat.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 <asm/param.h>
+ #include <asm/tsc.h>
+
+-#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
--- /dev/null
+From fac01d11722c92a186b27ee26cd429a8066adfb5 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+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 <hdegoede@redhat.com>
+
+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 <vipulk0511@gmail.com>
+Suggested-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/r/20200223140610.59612-3-hdegoede@redhat.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
--- /dev/null
+From 812c2d7506fde7cdf83cb2532810a65782b51741 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Sun, 23 Feb 2020 15:06:08 +0100
+Subject: x86/tsc_msr: Use named struct initializers
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+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 <hdegoede@redhat.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/r/20200223140610.59612-1-hdegoede@redhat.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 {