--- /dev/null
+From bd75c59a999eba2f7f27b84829209b8bba5a73c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Oct 2019 21:58:14 +1000
+Subject: powerpc/powernv: Fix CPU idle to be called with IRQs disabled
+
+From: Nicholas Piggin <npiggin@gmail.com>
+
+[ Upstream commit 7d6475051fb3d9339c5c760ed9883bc0a9048b21 ]
+
+Commit e78a7614f3876 ("idle: Prevent late-arriving interrupts from
+disrupting offline") changes arch_cpu_idle_dead to be called with
+interrupts disabled, which triggers the WARN in pnv_smp_cpu_kill_self.
+
+Fix this by fixing up irq_happened after hard disabling, rather than
+requiring there are no pending interrupts, similarly to what was done
+done until commit 2525db04d1cc5 ("powerpc/powernv: Simplify lazy IRQ
+handling in CPU offline").
+
+Fixes: e78a7614f3876 ("idle: Prevent late-arriving interrupts from disrupting offline")
+Reported-by: Paul Mackerras <paulus@samba.org>
+Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
+[mpe: Add unexpected_mask rather than checking for known bad values,
+ change the WARN_ON() to a WARN_ON_ONCE()]
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20191022115814.22456-1-npiggin@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/powernv/smp.c | 53 +++++++++++++++++++---------
+ 1 file changed, 37 insertions(+), 16 deletions(-)
+
+diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c
+index 94cd96b9b7bbc..001dfac8354a8 100644
+--- a/arch/powerpc/platforms/powernv/smp.c
++++ b/arch/powerpc/platforms/powernv/smp.c
+@@ -146,20 +146,25 @@ static int pnv_smp_cpu_disable(void)
+ return 0;
+ }
+
++static void pnv_flush_interrupts(void)
++{
++ if (cpu_has_feature(CPU_FTR_ARCH_300)) {
++ if (xive_enabled())
++ xive_flush_interrupt();
++ else
++ icp_opal_flush_interrupt();
++ } else {
++ icp_native_flush_interrupt();
++ }
++}
++
+ static void pnv_smp_cpu_kill_self(void)
+ {
++ unsigned long srr1, unexpected_mask, wmask;
+ unsigned int cpu;
+- unsigned long srr1, wmask;
+ u64 lpcr_val;
+
+ /* Standard hot unplug procedure */
+- /*
+- * This hard disables local interurpts, ensuring we have no lazy
+- * irqs pending.
+- */
+- WARN_ON(irqs_disabled());
+- hard_irq_disable();
+- WARN_ON(lazy_irq_pending());
+
+ idle_task_exit();
+ current->active_mm = NULL; /* for sanity */
+@@ -172,6 +177,27 @@ static void pnv_smp_cpu_kill_self(void)
+ if (cpu_has_feature(CPU_FTR_ARCH_207S))
+ wmask = SRR1_WAKEMASK_P8;
+
++ /*
++ * This turns the irq soft-disabled state we're called with, into a
++ * hard-disabled state with pending irq_happened interrupts cleared.
++ *
++ * PACA_IRQ_DEC - Decrementer should be ignored.
++ * PACA_IRQ_HMI - Can be ignored, processing is done in real mode.
++ * PACA_IRQ_DBELL, EE, PMI - Unexpected.
++ */
++ hard_irq_disable();
++ if (generic_check_cpu_restart(cpu))
++ goto out;
++
++ unexpected_mask = ~(PACA_IRQ_DEC | PACA_IRQ_HMI | PACA_IRQ_HARD_DIS);
++ if (local_paca->irq_happened & unexpected_mask) {
++ if (local_paca->irq_happened & PACA_IRQ_EE)
++ pnv_flush_interrupts();
++ DBG("CPU%d Unexpected exit while offline irq_happened=%lx!\n",
++ cpu, local_paca->irq_happened);
++ }
++ local_paca->irq_happened = PACA_IRQ_HARD_DIS;
++
+ /*
+ * We don't want to take decrementer interrupts while we are
+ * offline, so clear LPCR:PECE1. We keep PECE2 (and
+@@ -197,6 +223,7 @@ static void pnv_smp_cpu_kill_self(void)
+
+ srr1 = pnv_cpu_offline(cpu);
+
++ WARN_ON_ONCE(!irqs_disabled());
+ WARN_ON(lazy_irq_pending());
+
+ /*
+@@ -212,13 +239,7 @@ static void pnv_smp_cpu_kill_self(void)
+ */
+ if (((srr1 & wmask) == SRR1_WAKEEE) ||
+ ((srr1 & wmask) == SRR1_WAKEHVI)) {
+- if (cpu_has_feature(CPU_FTR_ARCH_300)) {
+- if (xive_enabled())
+- xive_flush_interrupt();
+- else
+- icp_opal_flush_interrupt();
+- } else
+- icp_native_flush_interrupt();
++ pnv_flush_interrupts();
+ } else if ((srr1 & wmask) == SRR1_WAKEHDBELL) {
+ unsigned long msg = PPC_DBELL_TYPE(PPC_DBELL_SERVER);
+ asm volatile(PPC_MSGCLR(%0) : : "r" (msg));
+@@ -266,7 +287,7 @@ static void pnv_smp_cpu_kill_self(void)
+ */
+ lpcr_val = mfspr(SPRN_LPCR) | (u64)LPCR_PECE1;
+ pnv_program_cpu_hotplug_lpcr(cpu, lpcr_val);
+-
++out:
+ DBG("CPU%d coming online...\n", cpu);
+ }
+
+--
+2.20.1
+
--- /dev/null
+From bfd1a098bf342334986af1892de942e713375ca0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Oct 2019 09:10:56 +0100
+Subject: Revert "ALSA: hda: Flush interrupts on disabling"
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit 1a7f60b9df614bb36d14dc0c0bc898a31b2b506f ]
+
+This reverts commit caa8422d01e983782548648e125fd617cadcec3f.
+
+It turned out that this commit caused a regression at shutdown /
+reboot, as the synchronize_irq() calls seems blocking the whole
+shutdown. Also another part of the change about shuffling the call
+order looks suspicious; the azx_stop_chip() call disables the CORB /
+RIRB while the others may still need the CORB/RIRB update.
+
+Since the original commit itself was a cargo-fix, let's revert the
+whole patch.
+
+Fixes: caa8422d01e9 ("ALSA: hda: Flush interrupts on disabling")
+BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=205333
+BugLinK: https://bugs.freedesktop.org/show_bug.cgi?id=111174
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Cc: Chris Wilson <chris@chris-wilson.co.uk>
+Link: https://lore.kernel.org/r/20191028081056.22010-1-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/hda/hdac_controller.c | 2 --
+ sound/pci/hda/hda_intel.c | 2 +-
+ 2 files changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/sound/hda/hdac_controller.c b/sound/hda/hdac_controller.c
+index 196bbc85699e5..3b0110545070a 100644
+--- a/sound/hda/hdac_controller.c
++++ b/sound/hda/hdac_controller.c
+@@ -447,8 +447,6 @@ static void azx_int_disable(struct hdac_bus *bus)
+ list_for_each_entry(azx_dev, &bus->stream_list, list)
+ snd_hdac_stream_updateb(azx_dev, SD_CTL, SD_INT_MASK, 0);
+
+- synchronize_irq(bus->irq);
+-
+ /* disable SIE for all streams */
+ snd_hdac_chip_writeb(bus, INTCTL, 0);
+
+diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
+index 783f9a9c40ecd..b0de3e3b33e5c 100644
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -1349,9 +1349,9 @@ static int azx_free(struct azx *chip)
+ }
+
+ if (bus->chip_init) {
+- azx_stop_chip(chip);
+ azx_clear_irq_pending(chip);
+ azx_stop_all_streams(chip);
++ azx_stop_chip(chip);
+ }
+
+ if (bus->irq >= 0)
+--
+2.20.1
+
--- /dev/null
+From c44cad6384ce51d4a3dd2ee68b7b8f2d26302e4c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Nov 2019 21:09:19 -0500
+Subject: Revert "nvme: allow 64-bit results in passthru commands"
+
+This reverts commit 76d609da9ed1cc0dc780e2b539d7b827ce28f182.
+
+The patch adds new functionality and shouldn't have been backported.
+
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/core.c | 108 +++++---------------------------
+ include/uapi/linux/nvme_ioctl.h | 23 -------
+ 2 files changed, 16 insertions(+), 115 deletions(-)
+
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index 36a5ed1eacbea..3304e2c8a448a 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -852,7 +852,7 @@ out:
+ static int nvme_submit_user_cmd(struct request_queue *q,
+ struct nvme_command *cmd, void __user *ubuffer,
+ unsigned bufflen, void __user *meta_buffer, unsigned meta_len,
+- u32 meta_seed, u64 *result, unsigned timeout)
++ u32 meta_seed, u32 *result, unsigned timeout)
+ {
+ bool write = nvme_is_write(cmd);
+ struct nvme_ns *ns = q->queuedata;
+@@ -893,7 +893,7 @@ static int nvme_submit_user_cmd(struct request_queue *q,
+ else
+ ret = nvme_req(req)->status;
+ if (result)
+- *result = le64_to_cpu(nvme_req(req)->result.u64);
++ *result = le32_to_cpu(nvme_req(req)->result.u32);
+ if (meta && !ret && !write) {
+ if (copy_to_user(meta_buffer, meta, meta_len))
+ ret = -EFAULT;
+@@ -1339,54 +1339,6 @@ static int nvme_user_cmd(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
+ struct nvme_command c;
+ unsigned timeout = 0;
+ u32 effects;
+- u64 result;
+- int status;
+-
+- if (!capable(CAP_SYS_ADMIN))
+- return -EACCES;
+- if (copy_from_user(&cmd, ucmd, sizeof(cmd)))
+- return -EFAULT;
+- if (cmd.flags)
+- return -EINVAL;
+-
+- memset(&c, 0, sizeof(c));
+- c.common.opcode = cmd.opcode;
+- c.common.flags = cmd.flags;
+- c.common.nsid = cpu_to_le32(cmd.nsid);
+- c.common.cdw2[0] = cpu_to_le32(cmd.cdw2);
+- c.common.cdw2[1] = cpu_to_le32(cmd.cdw3);
+- c.common.cdw10 = cpu_to_le32(cmd.cdw10);
+- c.common.cdw11 = cpu_to_le32(cmd.cdw11);
+- c.common.cdw12 = cpu_to_le32(cmd.cdw12);
+- c.common.cdw13 = cpu_to_le32(cmd.cdw13);
+- c.common.cdw14 = cpu_to_le32(cmd.cdw14);
+- c.common.cdw15 = cpu_to_le32(cmd.cdw15);
+-
+- if (cmd.timeout_ms)
+- timeout = msecs_to_jiffies(cmd.timeout_ms);
+-
+- effects = nvme_passthru_start(ctrl, ns, cmd.opcode);
+- status = nvme_submit_user_cmd(ns ? ns->queue : ctrl->admin_q, &c,
+- (void __user *)(uintptr_t)cmd.addr, cmd.data_len,
+- (void __user *)(uintptr_t)cmd.metadata,
+- cmd.metadata_len, 0, &result, timeout);
+- nvme_passthru_end(ctrl, effects);
+-
+- if (status >= 0) {
+- if (put_user(result, &ucmd->result))
+- return -EFAULT;
+- }
+-
+- return status;
+-}
+-
+-static int nvme_user_cmd64(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
+- struct nvme_passthru_cmd64 __user *ucmd)
+-{
+- struct nvme_passthru_cmd64 cmd;
+- struct nvme_command c;
+- unsigned timeout = 0;
+- u32 effects;
+ int status;
+
+ if (!capable(CAP_SYS_ADMIN))
+@@ -1457,41 +1409,6 @@ static void nvme_put_ns_from_disk(struct nvme_ns_head *head, int idx)
+ srcu_read_unlock(&head->srcu, idx);
+ }
+
+-static bool is_ctrl_ioctl(unsigned int cmd)
+-{
+- if (cmd == NVME_IOCTL_ADMIN_CMD || cmd == NVME_IOCTL_ADMIN64_CMD)
+- return true;
+- if (is_sed_ioctl(cmd))
+- return true;
+- return false;
+-}
+-
+-static int nvme_handle_ctrl_ioctl(struct nvme_ns *ns, unsigned int cmd,
+- void __user *argp,
+- struct nvme_ns_head *head,
+- int srcu_idx)
+-{
+- struct nvme_ctrl *ctrl = ns->ctrl;
+- int ret;
+-
+- nvme_get_ctrl(ns->ctrl);
+- nvme_put_ns_from_disk(head, srcu_idx);
+-
+- switch (cmd) {
+- case NVME_IOCTL_ADMIN_CMD:
+- ret = nvme_user_cmd(ctrl, NULL, argp);
+- break;
+- case NVME_IOCTL_ADMIN64_CMD:
+- ret = nvme_user_cmd64(ctrl, NULL, argp);
+- break;
+- default:
+- ret = sed_ioctl(ctrl->opal_dev, cmd, argp);
+- break;
+- }
+- nvme_put_ctrl(ctrl);
+- return ret;
+-}
+-
+ static int nvme_ioctl(struct block_device *bdev, fmode_t mode,
+ unsigned int cmd, unsigned long arg)
+ {
+@@ -1509,8 +1426,20 @@ static int nvme_ioctl(struct block_device *bdev, fmode_t mode,
+ * seperately and drop the ns SRCU reference early. This avoids a
+ * deadlock when deleting namespaces using the passthrough interface.
+ */
+- if (is_ctrl_ioctl(cmd))
+- return nvme_handle_ctrl_ioctl(ns, cmd, argp, head, srcu_idx);
++ if (cmd == NVME_IOCTL_ADMIN_CMD || is_sed_ioctl(cmd)) {
++ struct nvme_ctrl *ctrl = ns->ctrl;
++
++ nvme_get_ctrl(ns->ctrl);
++ nvme_put_ns_from_disk(head, srcu_idx);
++
++ if (cmd == NVME_IOCTL_ADMIN_CMD)
++ ret = nvme_user_cmd(ctrl, NULL, argp);
++ else
++ ret = sed_ioctl(ctrl->opal_dev, cmd, argp);
++
++ nvme_put_ctrl(ctrl);
++ return ret;
++ }
+
+ switch (cmd) {
+ case NVME_IOCTL_ID:
+@@ -1523,9 +1452,6 @@ static int nvme_ioctl(struct block_device *bdev, fmode_t mode,
+ case NVME_IOCTL_SUBMIT_IO:
+ ret = nvme_submit_io(ns, argp);
+ break;
+- case NVME_IOCTL_IO64_CMD:
+- ret = nvme_user_cmd64(ns->ctrl, ns, argp);
+- break;
+ default:
+ if (ns->ndev)
+ ret = nvme_nvm_ioctl(ns, cmd, arg);
+@@ -2900,8 +2826,6 @@ static long nvme_dev_ioctl(struct file *file, unsigned int cmd,
+ switch (cmd) {
+ case NVME_IOCTL_ADMIN_CMD:
+ return nvme_user_cmd(ctrl, NULL, argp);
+- case NVME_IOCTL_ADMIN64_CMD:
+- return nvme_user_cmd64(ctrl, NULL, argp);
+ case NVME_IOCTL_IO_CMD:
+ return nvme_dev_user_cmd(ctrl, argp);
+ case NVME_IOCTL_RESET:
+diff --git a/include/uapi/linux/nvme_ioctl.h b/include/uapi/linux/nvme_ioctl.h
+index e168dc59e9a0d..1c215ea1798e6 100644
+--- a/include/uapi/linux/nvme_ioctl.h
++++ b/include/uapi/linux/nvme_ioctl.h
+@@ -45,27 +45,6 @@ struct nvme_passthru_cmd {
+ __u32 result;
+ };
+
+-struct nvme_passthru_cmd64 {
+- __u8 opcode;
+- __u8 flags;
+- __u16 rsvd1;
+- __u32 nsid;
+- __u32 cdw2;
+- __u32 cdw3;
+- __u64 metadata;
+- __u64 addr;
+- __u32 metadata_len;
+- __u32 data_len;
+- __u32 cdw10;
+- __u32 cdw11;
+- __u32 cdw12;
+- __u32 cdw13;
+- __u32 cdw14;
+- __u32 cdw15;
+- __u32 timeout_ms;
+- __u64 result;
+-};
+-
+ #define nvme_admin_cmd nvme_passthru_cmd
+
+ #define NVME_IOCTL_ID _IO('N', 0x40)
+@@ -75,7 +54,5 @@ struct nvme_passthru_cmd64 {
+ #define NVME_IOCTL_RESET _IO('N', 0x44)
+ #define NVME_IOCTL_SUBSYS_RESET _IO('N', 0x45)
+ #define NVME_IOCTL_RESCAN _IO('N', 0x46)
+-#define NVME_IOCTL_ADMIN64_CMD _IOWR('N', 0x47, struct nvme_passthru_cmd64)
+-#define NVME_IOCTL_IO64_CMD _IOWR('N', 0x48, struct nvme_passthru_cmd64)
+
+ #endif /* _UAPI_LINUX_NVME_IOCTL_H */
+--
+2.20.1
+