The patch below does not apply to the 4.4-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable(a)vger.kernel.org>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
>From 7c7cfdcf7f1777c7376fc9a239980de04b6b5ea1 Mon Sep 17 00:00:00 2001
From: Adrian Hunter <adrian.hunter(a)intel.com>
Date: Wed, 14 Aug 2019 15:59:50 +0300
Subject: [PATCH] scsi: ufs: Fix NULL pointer dereference in
ufshcd_config_vreg_hpm()
Fix the following BUG:
[ 187.065689] BUG: kernel NULL pointer dereference, address: 000000000000001c
[ 187.065790] RIP: 0010:ufshcd_vreg_set_hpm+0x3c/0x110 [ufshcd_core]
[ 187.065938] Call Trace:
[ 187.065959] ufshcd_resume+0x72/0x290 [ufshcd_core]
[ 187.065980] ufshcd_system_resume+0x54/0x140 [ufshcd_core]
[ 187.065993] ? pci_pm_restore+0xb0/0xb0
[ 187.066005] ufshcd_pci_resume+0x15/0x20 [ufshcd_pci]
[ 187.066017] pci_pm_thaw+0x4c/0x90
[ 187.066030] dpm_run_callback+0x5b/0x150
[ 187.066043] device_resume+0x11b/0x220
Voltage regulators are optional, so functions must check they exist
before dereferencing.
Note this issue is hidden if CONFIG_REGULATORS is not set, because the
offending code is optimised away.
Notes for stable:
The issue first appears in commit 57d104c153d3 ("ufs: add UFS power
management support") but is inadvertently fixed in commit 60f0187031c0
("scsi: ufs: disable vccq if it's not needed by UFS device") which in
turn was reverted by commit 730679817d83 ("Revert "scsi: ufs: disable vccq
if it's not needed by UFS device""). So fix applies v3.18 to v4.5 and
v5.1+
Fixes: 57d104c153d3 ("ufs: add UFS power management support")
Fixes: 730679817d83 ("Revert "scsi: ufs: disable vccq if it's not needed by UFS device"")
Cc: stable(a)vger.kernel.org
Signed-off-by: Adrian Hunter <adrian.hunter(a)intel.com>
Signed-off-by: Martin K. Petersen <martin.petersen(a)oracle.com>
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index e274053109d0..029da74bb2f5 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -7062,6 +7062,9 @@ static inline int ufshcd_config_vreg_lpm(struct ufs_hba *hba,
static inline int ufshcd_config_vreg_hpm(struct ufs_hba *hba,
struct ufs_vreg *vreg)
{
+ if (!vreg)
+ return 0;
+
return ufshcd_config_vreg_load(hba->dev, vreg, vreg->max_uA);
}
when creating a vGPU workload, the guest context head pointer should
be updated correctly by comparing with the exsiting workload in the
guest worklod queue including the current running context.
in some situation, there is a running context A and then received 2 new
vGPU workload context B and A. in the new workload context A, it's head
pointer should be updated with the running context A's tail.
Fixes: 09975b861aa0 ("drm/i915/execlists: Disable preemption under GVT")
Fixes: 22b7a426bbe1 ("drm/i915/execlists: Preempt-to-busy")
v2: walk through guest workload list in backward way.
Cc: stable(a)vger.kernel.org
Signed-off-by: Xiaolin Zhang <xiaolin.zhang(a)intel.com>
---
drivers/gpu/drm/i915/gvt/scheduler.c | 28 +++++++++++++++-------------
1 file changed, 15 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c
index 8940fa8..166b998 100644
--- a/drivers/gpu/drm/i915/gvt/scheduler.c
+++ b/drivers/gpu/drm/i915/gvt/scheduler.c
@@ -1438,9 +1438,6 @@ static int prepare_mm(struct intel_vgpu_workload *workload)
#define same_context(a, b) (((a)->context_id == (b)->context_id) && \
((a)->lrca == (b)->lrca))
-#define get_last_workload(q) \
- (list_empty(q) ? NULL : container_of(q->prev, \
- struct intel_vgpu_workload, list))
/**
* intel_vgpu_create_workload - create a vGPU workload
* @vgpu: a vGPU
@@ -1460,7 +1457,7 @@ intel_vgpu_create_workload(struct intel_vgpu *vgpu, int ring_id,
{
struct intel_vgpu_submission *s = &vgpu->submission;
struct list_head *q = workload_q_head(vgpu, ring_id);
- struct intel_vgpu_workload *last_workload = get_last_workload(q);
+ struct intel_vgpu_workload *last_workload = NULL;
struct intel_vgpu_workload *workload = NULL;
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
u64 ring_context_gpa;
@@ -1486,15 +1483,20 @@ intel_vgpu_create_workload(struct intel_vgpu *vgpu, int ring_id,
head &= RB_HEAD_OFF_MASK;
tail &= RB_TAIL_OFF_MASK;
- if (last_workload && same_context(&last_workload->ctx_desc, desc)) {
- gvt_dbg_el("ring id %d cur workload == last\n", ring_id);
- gvt_dbg_el("ctx head %x real head %lx\n", head,
- last_workload->rb_tail);
- /*
- * cannot use guest context head pointer here,
- * as it might not be updated at this time
- */
- head = last_workload->rb_tail;
+ list_for_each_entry_reverse(last_workload, q, list) {
+
+ if (same_context(&last_workload->ctx_desc, desc)) {
+ gvt_dbg_el("ring id %d cur workload == last\n",
+ ring_id);
+ gvt_dbg_el("ctx head %x real head %lx\n", head,
+ last_workload->rb_tail);
+ /*
+ * cannot use guest context head pointer here,
+ * as it might not be updated at this time
+ */
+ head = last_workload->rb_tail;
+ break;
+ }
}
gvt_dbg_el("ring id %d begin a new workload\n", ring_id);
--
2.7.4
This is the start of the stable review cycle for the 4.14.141 release.
There are 62 patches in this series, all will be posted as a response
to this one. If anyone has any issues with these being applied, please
let me know.
Responses should be made by Thu 29 Aug 2019 07:25:02 AM UTC.
Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.14.141-r…
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.14.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Linux 4.14.141-rc1
Alastair D'Silva <alastair(a)d-silva.org>
powerpc: Allow flush_(inval_)dcache_range to work across ranges >4GB
Dan Carpenter <dan.carpenter(a)oracle.com>
dm zoned: fix potential NULL dereference in dmz_do_reclaim()
Darrick J. Wong <darrick.wong(a)oracle.com>
xfs: fix missing ILOCK unlock when xfs_setattr_nonsize fails due to EDQUOT
Henry Burns <henryburns(a)google.com>
mm/zsmalloc.c: fix race condition in zs_destroy_pool
Henry Burns <henryburns(a)google.com>
mm/zsmalloc.c: migration can leave pages in ZS_EMPTY indefinitely
Vlastimil Babka <vbabka(a)suse.cz>
mm, page_owner: handle THP splits correctly
Michael Kelley <mikelley(a)microsoft.com>
genirq: Properly pair kobject_del() with kobject_add()
Dmitry Fomichev <dmitry.fomichev(a)wdc.com>
dm zoned: properly handle backing device failure
Dmitry Fomichev <dmitry.fomichev(a)wdc.com>
dm zoned: improve error handling in i/o map code
Dmitry Fomichev <dmitry.fomichev(a)wdc.com>
dm zoned: improve error handling in reclaim
Mikulas Patocka <mpatocka(a)redhat.com>
dm table: fix invalid memory accesses with too high sector number
ZhangXiaoxu <zhangxiaoxu5(a)huawei.com>
dm space map metadata: fix missing store of apply_bops() return value
ZhangXiaoxu <zhangxiaoxu5(a)huawei.com>
dm btree: fix order of block initialization in btree_split_beneath
Dmitry Fomichev <dmitry.fomichev(a)wdc.com>
dm kcopyd: always complete failed jobs
John Hubbard <jhubbard(a)nvidia.com>
x86/boot: Fix boot regression caused by bootparam sanitizing
John Hubbard <jhubbard(a)nvidia.com>
x86/boot: Save fields explicitly, zero out everything else
Tom Lendacky <thomas.lendacky(a)amd.com>
x86/CPU/AMD: Clear RDRAND CPUID bit on AMD family 15h/16h
Thomas Gleixner <tglx(a)linutronix.de>
x86/apic: Handle missing global clockevent gracefully
Sean Christopherson <sean.j.christopherson(a)intel.com>
x86/retpoline: Don't clobber RFLAGS during CALL_NOSPEC on i386
Oleg Nesterov <oleg(a)redhat.com>
userfaultfd_release: always remove uffd flags and clear vm_userfaultfd_ctx
Bartosz Golaszewski <bgolaszewski(a)baylibre.com>
gpiolib: never report open-drain/source lines as 'input' to user-space
Lyude Paul <lyude(a)redhat.com>
drm/nouveau: Don't retry infinitely when receiving no data on i2c over AUX
Ilya Dryomov <idryomov(a)gmail.com>
libceph: fix PG split vs OSD (re)connect race
Jeff Layton <jlayton(a)kernel.org>
ceph: don't try fill file_lock on unsuccessful GETFILELOCK reply
Mikulas Patocka <mpatocka(a)redhat.com>
Revert "dm bufio: fix deadlock with loop device"
Jason Gerecke <jason.gerecke(a)wacom.com>
HID: wacom: Correct distance scale for 2nd-gen Intuos devices
Aaron Armstrong Skomra <skomra(a)gmail.com>
HID: wacom: correct misreported EKR ring values
Naresh Kamboju <naresh.kamboju () linaro ! org>
selftests: kvm: Adding config fragments
Jin Yao <yao.jin(a)linux.intel.com>
perf pmu-events: Fix missing "cpu_clk_unhalted.core" event
He Zhe <zhe.he(a)windriver.com>
perf cpumap: Fix writing to illegal memory in handling cpumap mask
He Zhe <zhe.he(a)windriver.com>
perf ftrace: Fix failure to set cpumask when only one cpu is present
Colin Ian King <colin.king(a)canonical.com>
drm/vmwgfx: fix memory leak when too many retries have occurred
Valdis Kletnieks <valdis.kletnieks(a)vt.edu>
x86/lib/cpu: Address missing prototypes warning
Jens Axboe <axboe(a)kernel.dk>
libata: add SG safety checks in SFF pio transfers
Jens Axboe <axboe(a)kernel.dk>
libata: have ata_scsi_rw_xlat() fail invalid passthrough requests
Jiangfeng Xiao <xiaojiangfeng(a)huawei.com>
net: hisilicon: Fix dma_map_single failed on arm64
Jiangfeng Xiao <xiaojiangfeng(a)huawei.com>
net: hisilicon: fix hip04-xmit never return TX_BUSY
Jiangfeng Xiao <xiaojiangfeng(a)huawei.com>
net: hisilicon: make hip04_tx_reclaim non-reentrant
Christophe JAILLET <christophe.jaillet(a)wanadoo.fr>
net: cxgb3_main: Fix a resource leak in a error path in 'init_one()'
Sebastien Tisserant <stisserant(a)wallix.com>
SMB3: Kernel oops mounting a encryptData share with CONFIG_DEBUG_VIRTUAL
Nicolas Saenz Julienne <nsaenzjulienne(a)suse.de>
HID: input: fix a4tech horizontal wheel custom usage
Trond Myklebust <trond.myklebust(a)hammerspace.com>
NFSv4: Fix a potential sleep while atomic in nfs4_do_reclaim()
Wang Xiayang <xywang.sjtu(a)sjtu.edu.cn>
net/ethernet/qlogic/qed: force the string buffer NULL-terminated
Wang Xiayang <xywang.sjtu(a)sjtu.edu.cn>
can: peak_usb: force the string buffer NULL-terminated
Wang Xiayang <xywang.sjtu(a)sjtu.edu.cn>
can: sja1000: force the string buffer NULL-terminated
Jiri Olsa <jolsa(a)kernel.org>
perf bench numa: Fix cpu0 binding
Juliana Rodrigueiro <juliana.rodrigueiro(a)intra2net.com>
isdn: hfcsusb: Fix mISDN driver crash caused by transfer buffer on the stack
Jozsef Kadlecsik <kadlec(a)netfilter.org>
netfilter: ipset: Fix rename concurrency with listing
Jia-Ju Bai <baijiaju1990(a)gmail.com>
isdn: mISDN: hfcsusb: Fix possible null-pointer dereferences in start_isoc_chain()
Michal Kalderon <michal.kalderon(a)marvell.com>
qed: RDMA - Fix the hw_ver returned in device attributes
Bob Ham <bob.ham(a)puri.sm>
net: usb: qmi_wwan: Add the BroadMobi BM818 card
Peter Ujfalusi <peter.ujfalusi(a)ti.com>
ASoC: ti: davinci-mcasp: Correct slot_width posed constraint
Navid Emamdoost <navid.emamdoost(a)gmail.com>
st_nci_hci_connectivity_event_received: null check the allocation
Navid Emamdoost <navid.emamdoost(a)gmail.com>
st21nfca_connectivity_event_received: null check the allocation
Ricard Wanderlof <ricard.wanderlof(a)axis.com>
ASoC: Fail card instantiation if DAI format setup fails
Rasmus Villemoes <rasmus.villemoes(a)prevas.dk>
can: dev: call netif_carrier_off() in register_candev()
Thomas Falcon <tlfalcon(a)linux.ibm.com>
bonding: Force slave speed check after link state recovery for 802.3ad
Charles Keepax <ckeepax(a)opensource.cirrus.com>
ASoC: dapm: Fix handling of custom_stop_condition on DAPM graph walks
Wenwen Wang <wenwen(a)cs.uga.edu>
netfilter: ebtables: fix a memory leak bug in compat
Vladimir Kondratiev <vladimir.kondratiev(a)linux.intel.com>
mips: fix cacheinfo
Thomas Bogendoerfer <tbogendoerfer(a)suse.de>
MIPS: kernel: only use i8253 clocksource with periodic clockevent
Ilya Trukhanov <lahvuun(a)gmail.com>
HID: Add 044f:b320 ThrustMaster, Inc. 2 in 1 DT
-------------
Diffstat:
Documentation/admin-guide/kernel-parameters.txt | 7 ++
Makefile | 4 +-
arch/mips/kernel/cacheinfo.c | 2 +
arch/mips/kernel/i8253.c | 3 +-
arch/powerpc/kernel/misc_64.S | 4 +-
arch/x86/include/asm/bootparam_utils.h | 61 +++++++++++----
arch/x86/include/asm/msr-index.h | 1 +
arch/x86/include/asm/nospec-branch.h | 2 +-
arch/x86/kernel/apic/apic.c | 68 +++++++++++++----
arch/x86/kernel/cpu/amd.c | 66 +++++++++++++++++
arch/x86/lib/cpu.c | 1 +
arch/x86/power/cpu.c | 86 ++++++++++++++++++----
drivers/ata/libata-scsi.c | 21 ++++++
drivers/ata/libata-sff.c | 6 ++
drivers/gpio/gpiolib.c | 6 +-
drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c | 24 ++++--
drivers/gpu/drm/vmwgfx/vmwgfx_msg.c | 4 +-
drivers/hid/hid-a4tech.c | 30 +++++++-
drivers/hid/hid-tmff.c | 12 +++
drivers/hid/wacom_wac.c | 4 +-
drivers/isdn/hardware/mISDN/hfcsusb.c | 13 +++-
drivers/md/dm-bufio.c | 4 +-
drivers/md/dm-kcopyd.c | 5 +-
drivers/md/dm-table.c | 5 +-
drivers/md/dm-zoned-metadata.c | 59 +++++++++++----
drivers/md/dm-zoned-reclaim.c | 44 ++++++++---
drivers/md/dm-zoned-target.c | 67 +++++++++++++++--
drivers/md/dm-zoned.h | 10 +++
drivers/md/persistent-data/dm-btree.c | 31 ++++----
drivers/md/persistent-data/dm-space-map-metadata.c | 2 +-
drivers/net/bonding/bond_main.c | 9 +++
drivers/net/can/dev.c | 2 +
drivers/net/can/sja1000/peak_pcmcia.c | 2 +-
drivers/net/can/usb/peak_usb/pcan_usb_core.c | 2 +-
drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c | 5 +-
drivers/net/ethernet/hisilicon/hip04_eth.c | 28 ++++---
drivers/net/ethernet/qlogic/qed/qed_int.c | 2 +-
drivers/net/ethernet/qlogic/qed/qed_rdma.c | 2 +-
drivers/net/usb/qmi_wwan.c | 1 +
drivers/nfc/st-nci/se.c | 2 +
drivers/nfc/st21nfca/se.c | 2 +
fs/ceph/locks.c | 3 +-
fs/cifs/smb2ops.c | 10 ++-
fs/nfs/nfs4_fs.h | 3 +-
fs/nfs/nfs4client.c | 5 +-
fs/nfs/nfs4state.c | 27 +++++--
fs/userfaultfd.c | 25 ++++---
fs/xfs/xfs_iops.c | 1 +
kernel/irq/irqdesc.c | 15 +++-
mm/huge_memory.c | 4 +
mm/zsmalloc.c | 78 ++++++++++++++++++--
net/bridge/netfilter/ebtables.c | 4 +-
net/ceph/osd_client.c | 9 +--
net/netfilter/ipset/ip_set_core.c | 2 +-
sound/soc/davinci/davinci-mcasp.c | 43 ++++++++---
sound/soc/soc-core.c | 7 +-
sound/soc/soc-dapm.c | 8 +-
tools/perf/bench/numa.c | 6 +-
tools/perf/builtin-ftrace.c | 2 +-
tools/perf/pmu-events/jevents.c | 1 +
tools/perf/util/cpumap.c | 5 +-
tools/testing/selftests/kvm/config | 3 +
62 files changed, 786 insertions(+), 184 deletions(-)
The patch below does not apply to the 4.9-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable(a)vger.kernel.org>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
>From c49a0a80137c7ca7d6ced4c812c9e07a949f6f24 Mon Sep 17 00:00:00 2001
From: Tom Lendacky <thomas.lendacky(a)amd.com>
Date: Mon, 19 Aug 2019 15:52:35 +0000
Subject: [PATCH] x86/CPU/AMD: Clear RDRAND CPUID bit on AMD family 15h/16h
There have been reports of RDRAND issues after resuming from suspend on
some AMD family 15h and family 16h systems. This issue stems from a BIOS
not performing the proper steps during resume to ensure RDRAND continues
to function properly.
RDRAND support is indicated by CPUID Fn00000001_ECX[30]. This bit can be
reset by clearing MSR C001_1004[62]. Any software that checks for RDRAND
support using CPUID, including the kernel, will believe that RDRAND is
not supported.
Update the CPU initialization to clear the RDRAND CPUID bit for any family
15h and 16h processor that supports RDRAND. If it is known that the family
15h or family 16h system does not have an RDRAND resume issue or that the
system will not be placed in suspend, the "rdrand=force" kernel parameter
can be used to stop the clearing of the RDRAND CPUID bit.
Additionally, update the suspend and resume path to save and restore the
MSR C001_1004 value to ensure that the RDRAND CPUID setting remains in
place after resuming from suspend.
Note, that clearing the RDRAND CPUID bit does not prevent a processor
that normally supports the RDRAND instruction from executing it. So any
code that determined the support based on family and model won't #UD.
Signed-off-by: Tom Lendacky <thomas.lendacky(a)amd.com>
Signed-off-by: Borislav Petkov <bp(a)suse.de>
Cc: Andrew Cooper <andrew.cooper3(a)citrix.com>
Cc: Andrew Morton <akpm(a)linux-foundation.org>
Cc: Chen Yu <yu.c.chen(a)intel.com>
Cc: "H. Peter Anvin" <hpa(a)zytor.com>
Cc: Ingo Molnar <mingo(a)redhat.com>
Cc: Jonathan Corbet <corbet(a)lwn.net>
Cc: Josh Poimboeuf <jpoimboe(a)redhat.com>
Cc: Juergen Gross <jgross(a)suse.com>
Cc: Kees Cook <keescook(a)chromium.org>
Cc: "linux-doc(a)vger.kernel.org" <linux-doc(a)vger.kernel.org>
Cc: "linux-pm(a)vger.kernel.org" <linux-pm(a)vger.kernel.org>
Cc: Nathan Chancellor <natechancellor(a)gmail.com>
Cc: Paolo Bonzini <pbonzini(a)redhat.com>
Cc: Pavel Machek <pavel(a)ucw.cz>
Cc: "Rafael J. Wysocki" <rjw(a)rjwysocki.net>
Cc: <stable(a)vger.kernel.org>
Cc: Thomas Gleixner <tglx(a)linutronix.de>
Cc: "x86(a)kernel.org" <x86(a)kernel.org>
Link: https://lkml.kernel.org/r/7543af91666f491547bd86cebb1e17c66824ab9f.15662299…
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 47d981a86e2f..4c1971960afa 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -4090,6 +4090,13 @@
Run specified binary instead of /init from the ramdisk,
used for early userspace startup. See initrd.
+ rdrand= [X86]
+ force - Override the decision by the kernel to hide the
+ advertisement of RDRAND support (this affects
+ certain AMD processors because of buggy BIOS
+ support, specifically around the suspend/resume
+ path).
+
rdt= [HW,X86,RDT]
Turn on/off individual RDT features. List is:
cmt, mbmtotal, mbmlocal, l3cat, l3cdp, l2cat, l2cdp,
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 6b4fc2788078..271d837d69a8 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -381,6 +381,7 @@
#define MSR_AMD64_PATCH_LEVEL 0x0000008b
#define MSR_AMD64_TSC_RATIO 0xc0000104
#define MSR_AMD64_NB_CFG 0xc001001f
+#define MSR_AMD64_CPUID_FN_1 0xc0011004
#define MSR_AMD64_PATCH_LOADER 0xc0010020
#define MSR_AMD64_OSVW_ID_LENGTH 0xc0010140
#define MSR_AMD64_OSVW_STATUS 0xc0010141
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index 8d4e50428b68..68c363c341bf 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -804,6 +804,64 @@ static void init_amd_ln(struct cpuinfo_x86 *c)
msr_set_bit(MSR_AMD64_DE_CFG, 31);
}
+static bool rdrand_force;
+
+static int __init rdrand_cmdline(char *str)
+{
+ if (!str)
+ return -EINVAL;
+
+ if (!strcmp(str, "force"))
+ rdrand_force = true;
+ else
+ return -EINVAL;
+
+ return 0;
+}
+early_param("rdrand", rdrand_cmdline);
+
+static void clear_rdrand_cpuid_bit(struct cpuinfo_x86 *c)
+{
+ /*
+ * Saving of the MSR used to hide the RDRAND support during
+ * suspend/resume is done by arch/x86/power/cpu.c, which is
+ * dependent on CONFIG_PM_SLEEP.
+ */
+ if (!IS_ENABLED(CONFIG_PM_SLEEP))
+ return;
+
+ /*
+ * The nordrand option can clear X86_FEATURE_RDRAND, so check for
+ * RDRAND support using the CPUID function directly.
+ */
+ if (!(cpuid_ecx(1) & BIT(30)) || rdrand_force)
+ return;
+
+ msr_clear_bit(MSR_AMD64_CPUID_FN_1, 62);
+
+ /*
+ * Verify that the CPUID change has occurred in case the kernel is
+ * running virtualized and the hypervisor doesn't support the MSR.
+ */
+ if (cpuid_ecx(1) & BIT(30)) {
+ pr_info_once("BIOS may not properly restore RDRAND after suspend, but hypervisor does not support hiding RDRAND via CPUID.\n");
+ return;
+ }
+
+ clear_cpu_cap(c, X86_FEATURE_RDRAND);
+ pr_info_once("BIOS may not properly restore RDRAND after suspend, hiding RDRAND via CPUID. Use rdrand=force to reenable.\n");
+}
+
+static void init_amd_jg(struct cpuinfo_x86 *c)
+{
+ /*
+ * Some BIOS implementations do not restore proper RDRAND support
+ * across suspend and resume. Check on whether to hide the RDRAND
+ * instruction support via CPUID.
+ */
+ clear_rdrand_cpuid_bit(c);
+}
+
static void init_amd_bd(struct cpuinfo_x86 *c)
{
u64 value;
@@ -818,6 +876,13 @@ static void init_amd_bd(struct cpuinfo_x86 *c)
wrmsrl_safe(MSR_F15H_IC_CFG, value);
}
}
+
+ /*
+ * Some BIOS implementations do not restore proper RDRAND support
+ * across suspend and resume. Check on whether to hide the RDRAND
+ * instruction support via CPUID.
+ */
+ clear_rdrand_cpuid_bit(c);
}
static void init_amd_zn(struct cpuinfo_x86 *c)
@@ -860,6 +925,7 @@ static void init_amd(struct cpuinfo_x86 *c)
case 0x10: init_amd_gh(c); break;
case 0x12: init_amd_ln(c); break;
case 0x15: init_amd_bd(c); break;
+ case 0x16: init_amd_jg(c); break;
case 0x17: init_amd_zn(c); break;
}
diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
index 24b079e94bc2..c9ef6a7a4a1a 100644
--- a/arch/x86/power/cpu.c
+++ b/arch/x86/power/cpu.c
@@ -12,6 +12,7 @@
#include <linux/smp.h>
#include <linux/perf_event.h>
#include <linux/tboot.h>
+#include <linux/dmi.h>
#include <asm/pgtable.h>
#include <asm/proto.h>
@@ -23,7 +24,7 @@
#include <asm/debugreg.h>
#include <asm/cpu.h>
#include <asm/mmu_context.h>
-#include <linux/dmi.h>
+#include <asm/cpu_device_id.h>
#ifdef CONFIG_X86_32
__visible unsigned long saved_context_ebx;
@@ -397,15 +398,14 @@ static int __init bsp_pm_check_init(void)
core_initcall(bsp_pm_check_init);
-static int msr_init_context(const u32 *msr_id, const int total_num)
+static int msr_build_context(const u32 *msr_id, const int num)
{
- int i = 0;
+ struct saved_msrs *saved_msrs = &saved_context.saved_msrs;
struct saved_msr *msr_array;
+ int total_num;
+ int i, j;
- if (saved_context.saved_msrs.array || saved_context.saved_msrs.num > 0) {
- pr_err("x86/pm: MSR quirk already applied, please check your DMI match table.\n");
- return -EINVAL;
- }
+ total_num = saved_msrs->num + num;
msr_array = kmalloc_array(total_num, sizeof(struct saved_msr), GFP_KERNEL);
if (!msr_array) {
@@ -413,19 +413,30 @@ static int msr_init_context(const u32 *msr_id, const int total_num)
return -ENOMEM;
}
- for (i = 0; i < total_num; i++) {
- msr_array[i].info.msr_no = msr_id[i];
+ if (saved_msrs->array) {
+ /*
+ * Multiple callbacks can invoke this function, so copy any
+ * MSR save requests from previous invocations.
+ */
+ memcpy(msr_array, saved_msrs->array,
+ sizeof(struct saved_msr) * saved_msrs->num);
+
+ kfree(saved_msrs->array);
+ }
+
+ for (i = saved_msrs->num, j = 0; i < total_num; i++, j++) {
+ msr_array[i].info.msr_no = msr_id[j];
msr_array[i].valid = false;
msr_array[i].info.reg.q = 0;
}
- saved_context.saved_msrs.num = total_num;
- saved_context.saved_msrs.array = msr_array;
+ saved_msrs->num = total_num;
+ saved_msrs->array = msr_array;
return 0;
}
/*
- * The following section is a quirk framework for problematic BIOSen:
+ * The following sections are a quirk framework for problematic BIOSen:
* Sometimes MSRs are modified by the BIOSen after suspended to
* RAM, this might cause unexpected behavior after wakeup.
* Thus we save/restore these specified MSRs across suspend/resume
@@ -440,7 +451,7 @@ static int msr_initialize_bdw(const struct dmi_system_id *d)
u32 bdw_msr_id[] = { MSR_IA32_THERM_CONTROL };
pr_info("x86/pm: %s detected, MSR saving is needed during suspending.\n", d->ident);
- return msr_init_context(bdw_msr_id, ARRAY_SIZE(bdw_msr_id));
+ return msr_build_context(bdw_msr_id, ARRAY_SIZE(bdw_msr_id));
}
static const struct dmi_system_id msr_save_dmi_table[] = {
@@ -455,9 +466,58 @@ static const struct dmi_system_id msr_save_dmi_table[] = {
{}
};
+static int msr_save_cpuid_features(const struct x86_cpu_id *c)
+{
+ u32 cpuid_msr_id[] = {
+ MSR_AMD64_CPUID_FN_1,
+ };
+
+ pr_info("x86/pm: family %#hx cpu detected, MSR saving is needed during suspending.\n",
+ c->family);
+
+ return msr_build_context(cpuid_msr_id, ARRAY_SIZE(cpuid_msr_id));
+}
+
+static const struct x86_cpu_id msr_save_cpu_table[] = {
+ {
+ .vendor = X86_VENDOR_AMD,
+ .family = 0x15,
+ .model = X86_MODEL_ANY,
+ .feature = X86_FEATURE_ANY,
+ .driver_data = (kernel_ulong_t)msr_save_cpuid_features,
+ },
+ {
+ .vendor = X86_VENDOR_AMD,
+ .family = 0x16,
+ .model = X86_MODEL_ANY,
+ .feature = X86_FEATURE_ANY,
+ .driver_data = (kernel_ulong_t)msr_save_cpuid_features,
+ },
+ {}
+};
+
+typedef int (*pm_cpu_match_t)(const struct x86_cpu_id *);
+static int pm_cpu_check(const struct x86_cpu_id *c)
+{
+ const struct x86_cpu_id *m;
+ int ret = 0;
+
+ m = x86_match_cpu(msr_save_cpu_table);
+ if (m) {
+ pm_cpu_match_t fn;
+
+ fn = (pm_cpu_match_t)m->driver_data;
+ ret = fn(m);
+ }
+
+ return ret;
+}
+
static int pm_check_save_msr(void)
{
dmi_check_system(msr_save_dmi_table);
+ pm_cpu_check(msr_save_cpu_table);
+
return 0;
}