mirror of
https://gitee.com/bianbu-linux/linux-6.6
synced 2025-04-24 14:07:52 -04:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
No conflicts. Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
3150a73366
294 changed files with 2604 additions and 1244 deletions
|
@ -25,6 +25,6 @@ Sub graphs of DRBD's state transitions
|
||||||
:alt: disk-states-8.dot
|
:alt: disk-states-8.dot
|
||||||
:align: center
|
:align: center
|
||||||
|
|
||||||
.. kernel-figure:: node-states-8.dot
|
.. kernel-figure:: peer-states-8.dot
|
||||||
:alt: node-states-8.dot
|
:alt: peer-states-8.dot
|
||||||
:align: center
|
:align: center
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
digraph node_states {
|
|
||||||
Secondary -> Primary [ label = "ioctl_set_state()" ]
|
|
||||||
Primary -> Secondary [ label = "ioctl_set_state()" ]
|
|
||||||
}
|
|
||||||
|
|
||||||
digraph peer_states {
|
digraph peer_states {
|
||||||
Secondary -> Primary [ label = "recv state packet" ]
|
Secondary -> Primary [ label = "recv state packet" ]
|
||||||
Primary -> Secondary [ label = "recv state packet" ]
|
Primary -> Secondary [ label = "recv state packet" ]
|
|
@ -53,11 +53,10 @@ The number of bits that the PAC occupies in a pointer is 55 minus the
|
||||||
virtual address size configured by the kernel. For example, with a
|
virtual address size configured by the kernel. For example, with a
|
||||||
virtual address size of 48, the PAC is 7 bits wide.
|
virtual address size of 48, the PAC is 7 bits wide.
|
||||||
|
|
||||||
Recent versions of GCC can compile code with APIAKey-based return
|
When ARM64_PTR_AUTH_KERNEL is selected, the kernel will be compiled
|
||||||
address protection when passed the -msign-return-address option. This
|
with HINT space pointer authentication instructions protecting
|
||||||
uses instructions in the HINT space (unless -march=armv8.3-a or higher
|
function returns. Kernels built with this option will work on hardware
|
||||||
is also passed), and such code can run on systems without the pointer
|
with or without pointer authentication support.
|
||||||
authentication extension.
|
|
||||||
|
|
||||||
In addition to exec(), keys can also be reinitialized to random values
|
In addition to exec(), keys can also be reinitialized to random values
|
||||||
using the PR_PAC_RESET_KEYS prctl. A bitmask of PR_PAC_APIAKEY,
|
using the PR_PAC_RESET_KEYS prctl. A bitmask of PR_PAC_APIAKEY,
|
||||||
|
|
|
@ -249,11 +249,16 @@ except ImportError:
|
||||||
|
|
||||||
html_static_path = ['sphinx-static']
|
html_static_path = ['sphinx-static']
|
||||||
|
|
||||||
html_context = {
|
html_css_files = [
|
||||||
|
'theme_overrides.css',
|
||||||
|
]
|
||||||
|
|
||||||
|
if major <= 1 and minor < 8:
|
||||||
|
html_context = {
|
||||||
'css_files': [
|
'css_files': [
|
||||||
'_static/theme_overrides.css',
|
'_static/theme_overrides.css',
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
# Add any extra paths that contain custom files (such as robots.txt or
|
# Add any extra paths that contain custom files (such as robots.txt or
|
||||||
# .htaccess) here, relative to this directory. These files are copied
|
# .htaccess) here, relative to this directory. These files are copied
|
||||||
|
|
|
@ -73,12 +73,12 @@ CPUFREQ_POSTCHANGE.
|
||||||
The third argument is a struct cpufreq_freqs with the following
|
The third argument is a struct cpufreq_freqs with the following
|
||||||
values:
|
values:
|
||||||
|
|
||||||
===== ===========================
|
====== ======================================
|
||||||
cpu number of the affected CPU
|
policy a pointer to the struct cpufreq_policy
|
||||||
old old frequency
|
old old frequency
|
||||||
new new frequency
|
new new frequency
|
||||||
flags flags of the cpufreq driver
|
flags flags of the cpufreq driver
|
||||||
===== ===========================
|
====== ======================================
|
||||||
|
|
||||||
3. CPUFreq Table Generation with Operating Performance Point (OPP)
|
3. CPUFreq Table Generation with Operating Performance Point (OPP)
|
||||||
==================================================================
|
==================================================================
|
||||||
|
|
|
@ -33,6 +33,7 @@ properties:
|
||||||
- rockchip,rk3328-spi
|
- rockchip,rk3328-spi
|
||||||
- rockchip,rk3368-spi
|
- rockchip,rk3368-spi
|
||||||
- rockchip,rk3399-spi
|
- rockchip,rk3399-spi
|
||||||
|
- rockchip,rk3568-spi
|
||||||
- rockchip,rv1126-spi
|
- rockchip,rv1126-spi
|
||||||
- const: rockchip,rk3066-spi
|
- const: rockchip,rk3066-spi
|
||||||
|
|
||||||
|
|
|
@ -439,11 +439,9 @@ preemption. The following substitution works on both kernels::
|
||||||
spin_lock(&p->lock);
|
spin_lock(&p->lock);
|
||||||
p->count += this_cpu_read(var2);
|
p->count += this_cpu_read(var2);
|
||||||
|
|
||||||
On a non-PREEMPT_RT kernel migrate_disable() maps to preempt_disable()
|
|
||||||
which makes the above code fully equivalent. On a PREEMPT_RT kernel
|
|
||||||
migrate_disable() ensures that the task is pinned on the current CPU which
|
migrate_disable() ensures that the task is pinned on the current CPU which
|
||||||
in turn guarantees that the per-CPU access to var1 and var2 are staying on
|
in turn guarantees that the per-CPU access to var1 and var2 are staying on
|
||||||
the same CPU.
|
the same CPU while the task remains preemptible.
|
||||||
|
|
||||||
The migrate_disable() substitution is not valid for the following
|
The migrate_disable() substitution is not valid for the following
|
||||||
scenario::
|
scenario::
|
||||||
|
@ -456,9 +454,8 @@ scenario::
|
||||||
p = this_cpu_ptr(&var1);
|
p = this_cpu_ptr(&var1);
|
||||||
p->val = func2();
|
p->val = func2();
|
||||||
|
|
||||||
While correct on a non-PREEMPT_RT kernel, this breaks on PREEMPT_RT because
|
This breaks because migrate_disable() does not protect against reentrancy from
|
||||||
here migrate_disable() does not protect against reentrancy from a
|
a preempting task. A correct substitution for this case is::
|
||||||
preempting task. A correct substitution for this case is::
|
|
||||||
|
|
||||||
func()
|
func()
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,6 +35,7 @@ GNU make 3.81 make --version
|
||||||
binutils 2.23 ld -v
|
binutils 2.23 ld -v
|
||||||
flex 2.5.35 flex --version
|
flex 2.5.35 flex --version
|
||||||
bison 2.0 bison --version
|
bison 2.0 bison --version
|
||||||
|
pahole 1.16 pahole --version
|
||||||
util-linux 2.10o fdformat --version
|
util-linux 2.10o fdformat --version
|
||||||
kmod 13 depmod -V
|
kmod 13 depmod -V
|
||||||
e2fsprogs 1.41.4 e2fsck -V
|
e2fsprogs 1.41.4 e2fsck -V
|
||||||
|
@ -108,6 +109,16 @@ Bison
|
||||||
Since Linux 4.16, the build system generates parsers
|
Since Linux 4.16, the build system generates parsers
|
||||||
during build. This requires bison 2.0 or later.
|
during build. This requires bison 2.0 or later.
|
||||||
|
|
||||||
|
pahole:
|
||||||
|
-------
|
||||||
|
|
||||||
|
Since Linux 5.2, if CONFIG_DEBUG_INFO_BTF is selected, the build system
|
||||||
|
generates BTF (BPF Type Format) from DWARF in vmlinux, a bit later from kernel
|
||||||
|
modules as well. This requires pahole v1.16 or later.
|
||||||
|
|
||||||
|
It is found in the 'dwarves' or 'pahole' distro packages or from
|
||||||
|
https://fedorapeople.org/~acme/dwarves/.
|
||||||
|
|
||||||
Perl
|
Perl
|
||||||
----
|
----
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,8 @@ works, see Documentation/process/development-process.rst. Also, read
|
||||||
Documentation/process/submit-checklist.rst
|
Documentation/process/submit-checklist.rst
|
||||||
for a list of items to check before submitting code. If you are submitting
|
for a list of items to check before submitting code. If you are submitting
|
||||||
a driver, also read Documentation/process/submitting-drivers.rst; for device
|
a driver, also read Documentation/process/submitting-drivers.rst; for device
|
||||||
tree binding patches, read Documentation/process/submitting-patches.rst.
|
tree binding patches, read
|
||||||
|
Documentation/devicetree/bindings/submitting-patches.rst.
|
||||||
|
|
||||||
This documentation assumes that you're using ``git`` to prepare your patches.
|
This documentation assumes that you're using ``git`` to prepare your patches.
|
||||||
If you're unfamiliar with ``git``, you would be well-advised to learn how to
|
If you're unfamiliar with ``git``, you would be well-advised to learn how to
|
||||||
|
|
10
MAINTAINERS
10
MAINTAINERS
|
@ -12180,8 +12180,8 @@ F: drivers/net/ethernet/mellanox/mlx5/core/fpga/*
|
||||||
F: include/linux/mlx5/mlx5_ifc_fpga.h
|
F: include/linux/mlx5/mlx5_ifc_fpga.h
|
||||||
|
|
||||||
MELLANOX ETHERNET SWITCH DRIVERS
|
MELLANOX ETHERNET SWITCH DRIVERS
|
||||||
M: Jiri Pirko <jiri@nvidia.com>
|
|
||||||
M: Ido Schimmel <idosch@nvidia.com>
|
M: Ido Schimmel <idosch@nvidia.com>
|
||||||
|
M: Petr Machata <petrm@nvidia.com>
|
||||||
L: netdev@vger.kernel.org
|
L: netdev@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
W: http://www.mellanox.com
|
W: http://www.mellanox.com
|
||||||
|
@ -16517,6 +16517,12 @@ T: git git://linuxtv.org/media_tree.git
|
||||||
F: Documentation/devicetree/bindings/media/allwinner,sun8i-a83t-de2-rotate.yaml
|
F: Documentation/devicetree/bindings/media/allwinner,sun8i-a83t-de2-rotate.yaml
|
||||||
F: drivers/media/platform/sunxi/sun8i-rotate/
|
F: drivers/media/platform/sunxi/sun8i-rotate/
|
||||||
|
|
||||||
|
RPMSG TTY DRIVER
|
||||||
|
M: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com>
|
||||||
|
L: linux-remoteproc@vger.kernel.org
|
||||||
|
S: Maintained
|
||||||
|
F: drivers/tty/rpmsg_tty.c
|
||||||
|
|
||||||
RTL2830 MEDIA DRIVER
|
RTL2830 MEDIA DRIVER
|
||||||
M: Antti Palosaari <crope@iki.fi>
|
M: Antti Palosaari <crope@iki.fi>
|
||||||
L: linux-media@vger.kernel.org
|
L: linux-media@vger.kernel.org
|
||||||
|
@ -16638,7 +16644,6 @@ W: http://www.ibm.com/developerworks/linux/linux390/
|
||||||
F: drivers/iommu/s390-iommu.c
|
F: drivers/iommu/s390-iommu.c
|
||||||
|
|
||||||
S390 IUCV NETWORK LAYER
|
S390 IUCV NETWORK LAYER
|
||||||
M: Julian Wiedmann <jwi@linux.ibm.com>
|
|
||||||
M: Alexandra Winter <wintera@linux.ibm.com>
|
M: Alexandra Winter <wintera@linux.ibm.com>
|
||||||
M: Wenjia Zhang <wenjia@linux.ibm.com>
|
M: Wenjia Zhang <wenjia@linux.ibm.com>
|
||||||
L: linux-s390@vger.kernel.org
|
L: linux-s390@vger.kernel.org
|
||||||
|
@ -16650,7 +16655,6 @@ F: include/net/iucv/
|
||||||
F: net/iucv/
|
F: net/iucv/
|
||||||
|
|
||||||
S390 NETWORK DRIVERS
|
S390 NETWORK DRIVERS
|
||||||
M: Julian Wiedmann <jwi@linux.ibm.com>
|
|
||||||
M: Alexandra Winter <wintera@linux.ibm.com>
|
M: Alexandra Winter <wintera@linux.ibm.com>
|
||||||
M: Wenjia Zhang <wenjia@linux.ibm.com>
|
M: Wenjia Zhang <wenjia@linux.ibm.com>
|
||||||
L: linux-s390@vger.kernel.org
|
L: linux-s390@vger.kernel.org
|
||||||
|
|
4
Makefile
4
Makefile
|
@ -2,7 +2,7 @@
|
||||||
VERSION = 5
|
VERSION = 5
|
||||||
PATCHLEVEL = 16
|
PATCHLEVEL = 16
|
||||||
SUBLEVEL = 0
|
SUBLEVEL = 0
|
||||||
EXTRAVERSION = -rc3
|
EXTRAVERSION = -rc4
|
||||||
NAME = Gobble Gobble
|
NAME = Gobble Gobble
|
||||||
|
|
||||||
# *DOCUMENTATION*
|
# *DOCUMENTATION*
|
||||||
|
@ -789,7 +789,7 @@ stackp-flags-$(CONFIG_STACKPROTECTOR_STRONG) := -fstack-protector-strong
|
||||||
KBUILD_CFLAGS += $(stackp-flags-y)
|
KBUILD_CFLAGS += $(stackp-flags-y)
|
||||||
|
|
||||||
KBUILD_CFLAGS-$(CONFIG_WERROR) += -Werror
|
KBUILD_CFLAGS-$(CONFIG_WERROR) += -Werror
|
||||||
KBUILD_CFLAGS += $(KBUILD_CFLAGS-y) $(CONFIG_CC_IMPLICIT_FALLTHROUGH)
|
KBUILD_CFLAGS += $(KBUILD_CFLAGS-y) $(CONFIG_CC_IMPLICIT_FALLTHROUGH:"%"=%)
|
||||||
|
|
||||||
ifdef CONFIG_CC_IS_CLANG
|
ifdef CONFIG_CC_IS_CLANG
|
||||||
KBUILD_CPPFLAGS += -Qunused-arguments
|
KBUILD_CPPFLAGS += -Qunused-arguments
|
||||||
|
|
|
@ -77,11 +77,17 @@
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
SYM_CODE_START(ftrace_regs_caller)
|
SYM_CODE_START(ftrace_regs_caller)
|
||||||
|
#ifdef BTI_C
|
||||||
|
BTI_C
|
||||||
|
#endif
|
||||||
ftrace_regs_entry 1
|
ftrace_regs_entry 1
|
||||||
b ftrace_common
|
b ftrace_common
|
||||||
SYM_CODE_END(ftrace_regs_caller)
|
SYM_CODE_END(ftrace_regs_caller)
|
||||||
|
|
||||||
SYM_CODE_START(ftrace_caller)
|
SYM_CODE_START(ftrace_caller)
|
||||||
|
#ifdef BTI_C
|
||||||
|
BTI_C
|
||||||
|
#endif
|
||||||
ftrace_regs_entry 0
|
ftrace_regs_entry 0
|
||||||
b ftrace_common
|
b ftrace_common
|
||||||
SYM_CODE_END(ftrace_caller)
|
SYM_CODE_END(ftrace_caller)
|
||||||
|
|
|
@ -147,7 +147,7 @@ int machine_kexec_post_load(struct kimage *kimage)
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
kimage->arch.ttbr1 = __pa(trans_pgd);
|
kimage->arch.ttbr1 = __pa(trans_pgd);
|
||||||
kimage->arch.zero_page = __pa(empty_zero_page);
|
kimage->arch.zero_page = __pa_symbol(empty_zero_page);
|
||||||
|
|
||||||
reloc_size = __relocate_new_kernel_end - __relocate_new_kernel_start;
|
reloc_size = __relocate_new_kernel_end - __relocate_new_kernel_start;
|
||||||
memcpy(reloc_code, __relocate_new_kernel_start, reloc_size);
|
memcpy(reloc_code, __relocate_new_kernel_start, reloc_size);
|
||||||
|
|
|
@ -98,7 +98,7 @@ do { \
|
||||||
#define emit(...) __emit(__VA_ARGS__)
|
#define emit(...) __emit(__VA_ARGS__)
|
||||||
|
|
||||||
/* Workaround for R10000 ll/sc errata */
|
/* Workaround for R10000 ll/sc errata */
|
||||||
#ifdef CONFIG_WAR_R10000
|
#ifdef CONFIG_WAR_R10000_LLSC
|
||||||
#define LLSC_beqz beqzl
|
#define LLSC_beqz beqzl
|
||||||
#else
|
#else
|
||||||
#define LLSC_beqz beqz
|
#define LLSC_beqz beqz
|
||||||
|
|
|
@ -15,7 +15,12 @@
|
||||||
# Mike Shaver, Helge Deller and Martin K. Petersen
|
# Mike Shaver, Helge Deller and Martin K. Petersen
|
||||||
#
|
#
|
||||||
|
|
||||||
|
ifdef CONFIG_PARISC_SELF_EXTRACT
|
||||||
|
boot := arch/parisc/boot
|
||||||
|
KBUILD_IMAGE := $(boot)/bzImage
|
||||||
|
else
|
||||||
KBUILD_IMAGE := vmlinuz
|
KBUILD_IMAGE := vmlinuz
|
||||||
|
endif
|
||||||
|
|
||||||
NM = sh $(srctree)/arch/parisc/nm
|
NM = sh $(srctree)/arch/parisc/nm
|
||||||
CHECKFLAGS += -D__hppa__=1
|
CHECKFLAGS += -D__hppa__=1
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
CONFIG_LOCALVERSION="-64bit"
|
CONFIG_LOCALVERSION="-64bit"
|
||||||
# CONFIG_LOCALVERSION_AUTO is not set
|
# CONFIG_LOCALVERSION_AUTO is not set
|
||||||
|
CONFIG_KERNEL_LZ4=y
|
||||||
CONFIG_SYSVIPC=y
|
CONFIG_SYSVIPC=y
|
||||||
CONFIG_POSIX_MQUEUE=y
|
CONFIG_POSIX_MQUEUE=y
|
||||||
|
CONFIG_AUDIT=y
|
||||||
CONFIG_BSD_PROCESS_ACCT=y
|
CONFIG_BSD_PROCESS_ACCT=y
|
||||||
CONFIG_BSD_PROCESS_ACCT_V3=y
|
CONFIG_BSD_PROCESS_ACCT_V3=y
|
||||||
CONFIG_TASKSTATS=y
|
CONFIG_TASKSTATS=y
|
||||||
|
@ -35,6 +37,7 @@ CONFIG_MODVERSIONS=y
|
||||||
CONFIG_BLK_DEV_INTEGRITY=y
|
CONFIG_BLK_DEV_INTEGRITY=y
|
||||||
CONFIG_BINFMT_MISC=m
|
CONFIG_BINFMT_MISC=m
|
||||||
# CONFIG_COMPACTION is not set
|
# CONFIG_COMPACTION is not set
|
||||||
|
CONFIG_MEMORY_FAILURE=y
|
||||||
CONFIG_NET=y
|
CONFIG_NET=y
|
||||||
CONFIG_PACKET=y
|
CONFIG_PACKET=y
|
||||||
CONFIG_UNIX=y
|
CONFIG_UNIX=y
|
||||||
|
@ -65,12 +68,15 @@ CONFIG_SCSI_ISCSI_ATTRS=y
|
||||||
CONFIG_SCSI_SRP_ATTRS=y
|
CONFIG_SCSI_SRP_ATTRS=y
|
||||||
CONFIG_ISCSI_BOOT_SYSFS=y
|
CONFIG_ISCSI_BOOT_SYSFS=y
|
||||||
CONFIG_SCSI_MPT2SAS=y
|
CONFIG_SCSI_MPT2SAS=y
|
||||||
CONFIG_SCSI_LASI700=m
|
CONFIG_SCSI_LASI700=y
|
||||||
CONFIG_SCSI_SYM53C8XX_2=y
|
CONFIG_SCSI_SYM53C8XX_2=y
|
||||||
CONFIG_SCSI_ZALON=y
|
CONFIG_SCSI_ZALON=y
|
||||||
CONFIG_SCSI_QLA_ISCSI=m
|
CONFIG_SCSI_QLA_ISCSI=m
|
||||||
CONFIG_SCSI_DH=y
|
CONFIG_SCSI_DH=y
|
||||||
CONFIG_ATA=y
|
CONFIG_ATA=y
|
||||||
|
CONFIG_SATA_SIL=y
|
||||||
|
CONFIG_SATA_SIS=y
|
||||||
|
CONFIG_SATA_VIA=y
|
||||||
CONFIG_PATA_NS87415=y
|
CONFIG_PATA_NS87415=y
|
||||||
CONFIG_PATA_SIL680=y
|
CONFIG_PATA_SIL680=y
|
||||||
CONFIG_ATA_GENERIC=y
|
CONFIG_ATA_GENERIC=y
|
||||||
|
@ -79,6 +85,7 @@ CONFIG_MD_LINEAR=m
|
||||||
CONFIG_BLK_DEV_DM=m
|
CONFIG_BLK_DEV_DM=m
|
||||||
CONFIG_DM_RAID=m
|
CONFIG_DM_RAID=m
|
||||||
CONFIG_DM_UEVENT=y
|
CONFIG_DM_UEVENT=y
|
||||||
|
CONFIG_DM_AUDIT=y
|
||||||
CONFIG_FUSION=y
|
CONFIG_FUSION=y
|
||||||
CONFIG_FUSION_SPI=y
|
CONFIG_FUSION_SPI=y
|
||||||
CONFIG_FUSION_SAS=y
|
CONFIG_FUSION_SAS=y
|
||||||
|
@ -196,10 +203,15 @@ CONFIG_FB_MATROX_G=y
|
||||||
CONFIG_FB_MATROX_I2C=y
|
CONFIG_FB_MATROX_I2C=y
|
||||||
CONFIG_FB_MATROX_MAVEN=y
|
CONFIG_FB_MATROX_MAVEN=y
|
||||||
CONFIG_FB_RADEON=y
|
CONFIG_FB_RADEON=y
|
||||||
|
CONFIG_LOGO=y
|
||||||
|
# CONFIG_LOGO_LINUX_CLUT224 is not set
|
||||||
CONFIG_HIDRAW=y
|
CONFIG_HIDRAW=y
|
||||||
CONFIG_HID_PID=y
|
CONFIG_HID_PID=y
|
||||||
CONFIG_USB_HIDDEV=y
|
CONFIG_USB_HIDDEV=y
|
||||||
CONFIG_USB=y
|
CONFIG_USB=y
|
||||||
|
CONFIG_USB_EHCI_HCD=y
|
||||||
|
CONFIG_USB_OHCI_HCD=y
|
||||||
|
CONFIG_USB_OHCI_HCD_PLATFORM=y
|
||||||
CONFIG_UIO=y
|
CONFIG_UIO=y
|
||||||
CONFIG_UIO_PDRV_GENIRQ=m
|
CONFIG_UIO_PDRV_GENIRQ=m
|
||||||
CONFIG_UIO_AEC=m
|
CONFIG_UIO_AEC=m
|
||||||
|
|
|
@ -39,6 +39,7 @@ verify "$3"
|
||||||
if [ -n "${INSTALLKERNEL}" ]; then
|
if [ -n "${INSTALLKERNEL}" ]; then
|
||||||
if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi
|
if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi
|
||||||
if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi
|
if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi
|
||||||
|
if [ -x /usr/sbin/${INSTALLKERNEL} ]; then exec /usr/sbin/${INSTALLKERNEL} "$@"; fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Default install
|
# Default install
|
||||||
|
|
|
@ -249,30 +249,16 @@ void __init time_init(void)
|
||||||
static int __init init_cr16_clocksource(void)
|
static int __init init_cr16_clocksource(void)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* The cr16 interval timers are not syncronized across CPUs on
|
* The cr16 interval timers are not syncronized across CPUs, even if
|
||||||
* different sockets, so mark them unstable and lower rating on
|
* they share the same socket.
|
||||||
* multi-socket SMP systems.
|
|
||||||
*/
|
*/
|
||||||
if (num_online_cpus() > 1 && !running_on_qemu) {
|
if (num_online_cpus() > 1 && !running_on_qemu) {
|
||||||
int cpu;
|
|
||||||
unsigned long cpu0_loc;
|
|
||||||
cpu0_loc = per_cpu(cpu_data, 0).cpu_loc;
|
|
||||||
|
|
||||||
for_each_online_cpu(cpu) {
|
|
||||||
if (cpu == 0)
|
|
||||||
continue;
|
|
||||||
if ((cpu0_loc != 0) &&
|
|
||||||
(cpu0_loc == per_cpu(cpu_data, cpu).cpu_loc))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* mark sched_clock unstable */
|
/* mark sched_clock unstable */
|
||||||
clear_sched_clock_stable();
|
clear_sched_clock_stable();
|
||||||
|
|
||||||
clocksource_cr16.name = "cr16_unstable";
|
clocksource_cr16.name = "cr16_unstable";
|
||||||
clocksource_cr16.flags = CLOCK_SOURCE_UNSTABLE;
|
clocksource_cr16.flags = CLOCK_SOURCE_UNSTABLE;
|
||||||
clocksource_cr16.rating = 0;
|
clocksource_cr16.rating = 0;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* register at clocksource framework */
|
/* register at clocksource framework */
|
||||||
|
|
|
@ -403,7 +403,6 @@ CONFIG_DEVTMPFS=y
|
||||||
CONFIG_CONNECTOR=y
|
CONFIG_CONNECTOR=y
|
||||||
CONFIG_ZRAM=y
|
CONFIG_ZRAM=y
|
||||||
CONFIG_BLK_DEV_LOOP=m
|
CONFIG_BLK_DEV_LOOP=m
|
||||||
CONFIG_BLK_DEV_CRYPTOLOOP=m
|
|
||||||
CONFIG_BLK_DEV_DRBD=m
|
CONFIG_BLK_DEV_DRBD=m
|
||||||
CONFIG_BLK_DEV_NBD=m
|
CONFIG_BLK_DEV_NBD=m
|
||||||
CONFIG_BLK_DEV_RAM=y
|
CONFIG_BLK_DEV_RAM=y
|
||||||
|
@ -476,6 +475,7 @@ CONFIG_MACVLAN=m
|
||||||
CONFIG_MACVTAP=m
|
CONFIG_MACVTAP=m
|
||||||
CONFIG_VXLAN=m
|
CONFIG_VXLAN=m
|
||||||
CONFIG_BAREUDP=m
|
CONFIG_BAREUDP=m
|
||||||
|
CONFIG_AMT=m
|
||||||
CONFIG_TUN=m
|
CONFIG_TUN=m
|
||||||
CONFIG_VETH=m
|
CONFIG_VETH=m
|
||||||
CONFIG_VIRTIO_NET=m
|
CONFIG_VIRTIO_NET=m
|
||||||
|
@ -489,6 +489,7 @@ CONFIG_NLMON=m
|
||||||
# CONFIG_NET_VENDOR_AMD is not set
|
# CONFIG_NET_VENDOR_AMD is not set
|
||||||
# CONFIG_NET_VENDOR_AQUANTIA is not set
|
# CONFIG_NET_VENDOR_AQUANTIA is not set
|
||||||
# CONFIG_NET_VENDOR_ARC is not set
|
# CONFIG_NET_VENDOR_ARC is not set
|
||||||
|
# CONFIG_NET_VENDOR_ASIX is not set
|
||||||
# CONFIG_NET_VENDOR_ATHEROS is not set
|
# CONFIG_NET_VENDOR_ATHEROS is not set
|
||||||
# CONFIG_NET_VENDOR_BROADCOM is not set
|
# CONFIG_NET_VENDOR_BROADCOM is not set
|
||||||
# CONFIG_NET_VENDOR_BROCADE is not set
|
# CONFIG_NET_VENDOR_BROCADE is not set
|
||||||
|
@ -571,6 +572,7 @@ CONFIG_WATCHDOG=y
|
||||||
CONFIG_WATCHDOG_NOWAYOUT=y
|
CONFIG_WATCHDOG_NOWAYOUT=y
|
||||||
CONFIG_SOFT_WATCHDOG=m
|
CONFIG_SOFT_WATCHDOG=m
|
||||||
CONFIG_DIAG288_WATCHDOG=m
|
CONFIG_DIAG288_WATCHDOG=m
|
||||||
|
# CONFIG_DRM_DEBUG_MODESET_LOCK is not set
|
||||||
CONFIG_FB=y
|
CONFIG_FB=y
|
||||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||||
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
|
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
|
||||||
|
@ -775,12 +777,14 @@ CONFIG_CRC4=m
|
||||||
CONFIG_CRC7=m
|
CONFIG_CRC7=m
|
||||||
CONFIG_CRC8=m
|
CONFIG_CRC8=m
|
||||||
CONFIG_RANDOM32_SELFTEST=y
|
CONFIG_RANDOM32_SELFTEST=y
|
||||||
|
CONFIG_XZ_DEC_MICROLZMA=y
|
||||||
CONFIG_DMA_CMA=y
|
CONFIG_DMA_CMA=y
|
||||||
CONFIG_CMA_SIZE_MBYTES=0
|
CONFIG_CMA_SIZE_MBYTES=0
|
||||||
CONFIG_PRINTK_TIME=y
|
CONFIG_PRINTK_TIME=y
|
||||||
CONFIG_DYNAMIC_DEBUG=y
|
CONFIG_DYNAMIC_DEBUG=y
|
||||||
CONFIG_DEBUG_INFO=y
|
CONFIG_DEBUG_INFO=y
|
||||||
CONFIG_DEBUG_INFO_DWARF4=y
|
CONFIG_DEBUG_INFO_DWARF4=y
|
||||||
|
CONFIG_DEBUG_INFO_BTF=y
|
||||||
CONFIG_GDB_SCRIPTS=y
|
CONFIG_GDB_SCRIPTS=y
|
||||||
CONFIG_HEADERS_INSTALL=y
|
CONFIG_HEADERS_INSTALL=y
|
||||||
CONFIG_DEBUG_SECTION_MISMATCH=y
|
CONFIG_DEBUG_SECTION_MISMATCH=y
|
||||||
|
@ -807,6 +811,7 @@ CONFIG_DEBUG_MEMORY_INIT=y
|
||||||
CONFIG_MEMORY_NOTIFIER_ERROR_INJECT=m
|
CONFIG_MEMORY_NOTIFIER_ERROR_INJECT=m
|
||||||
CONFIG_DEBUG_PER_CPU_MAPS=y
|
CONFIG_DEBUG_PER_CPU_MAPS=y
|
||||||
CONFIG_KFENCE=y
|
CONFIG_KFENCE=y
|
||||||
|
CONFIG_KFENCE_STATIC_KEYS=y
|
||||||
CONFIG_DEBUG_SHIRQ=y
|
CONFIG_DEBUG_SHIRQ=y
|
||||||
CONFIG_PANIC_ON_OOPS=y
|
CONFIG_PANIC_ON_OOPS=y
|
||||||
CONFIG_DETECT_HUNG_TASK=y
|
CONFIG_DETECT_HUNG_TASK=y
|
||||||
|
@ -842,6 +847,7 @@ CONFIG_FTRACE_STARTUP_TEST=y
|
||||||
CONFIG_SAMPLES=y
|
CONFIG_SAMPLES=y
|
||||||
CONFIG_SAMPLE_TRACE_PRINTK=m
|
CONFIG_SAMPLE_TRACE_PRINTK=m
|
||||||
CONFIG_SAMPLE_FTRACE_DIRECT=m
|
CONFIG_SAMPLE_FTRACE_DIRECT=m
|
||||||
|
CONFIG_SAMPLE_FTRACE_DIRECT_MULTI=m
|
||||||
CONFIG_DEBUG_ENTRY=y
|
CONFIG_DEBUG_ENTRY=y
|
||||||
CONFIG_CIO_INJECT=y
|
CONFIG_CIO_INJECT=y
|
||||||
CONFIG_KUNIT=m
|
CONFIG_KUNIT=m
|
||||||
|
@ -860,7 +866,7 @@ CONFIG_FAIL_FUNCTION=y
|
||||||
CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y
|
CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y
|
||||||
CONFIG_LKDTM=m
|
CONFIG_LKDTM=m
|
||||||
CONFIG_TEST_MIN_HEAP=y
|
CONFIG_TEST_MIN_HEAP=y
|
||||||
CONFIG_KPROBES_SANITY_TEST=y
|
CONFIG_KPROBES_SANITY_TEST=m
|
||||||
CONFIG_RBTREE_TEST=y
|
CONFIG_RBTREE_TEST=y
|
||||||
CONFIG_INTERVAL_TREE_TEST=m
|
CONFIG_INTERVAL_TREE_TEST=m
|
||||||
CONFIG_PERCPU_TEST=m
|
CONFIG_PERCPU_TEST=m
|
||||||
|
|
|
@ -394,7 +394,6 @@ CONFIG_DEVTMPFS=y
|
||||||
CONFIG_CONNECTOR=y
|
CONFIG_CONNECTOR=y
|
||||||
CONFIG_ZRAM=y
|
CONFIG_ZRAM=y
|
||||||
CONFIG_BLK_DEV_LOOP=m
|
CONFIG_BLK_DEV_LOOP=m
|
||||||
CONFIG_BLK_DEV_CRYPTOLOOP=m
|
|
||||||
CONFIG_BLK_DEV_DRBD=m
|
CONFIG_BLK_DEV_DRBD=m
|
||||||
CONFIG_BLK_DEV_NBD=m
|
CONFIG_BLK_DEV_NBD=m
|
||||||
CONFIG_BLK_DEV_RAM=y
|
CONFIG_BLK_DEV_RAM=y
|
||||||
|
@ -467,6 +466,7 @@ CONFIG_MACVLAN=m
|
||||||
CONFIG_MACVTAP=m
|
CONFIG_MACVTAP=m
|
||||||
CONFIG_VXLAN=m
|
CONFIG_VXLAN=m
|
||||||
CONFIG_BAREUDP=m
|
CONFIG_BAREUDP=m
|
||||||
|
CONFIG_AMT=m
|
||||||
CONFIG_TUN=m
|
CONFIG_TUN=m
|
||||||
CONFIG_VETH=m
|
CONFIG_VETH=m
|
||||||
CONFIG_VIRTIO_NET=m
|
CONFIG_VIRTIO_NET=m
|
||||||
|
@ -480,6 +480,7 @@ CONFIG_NLMON=m
|
||||||
# CONFIG_NET_VENDOR_AMD is not set
|
# CONFIG_NET_VENDOR_AMD is not set
|
||||||
# CONFIG_NET_VENDOR_AQUANTIA is not set
|
# CONFIG_NET_VENDOR_AQUANTIA is not set
|
||||||
# CONFIG_NET_VENDOR_ARC is not set
|
# CONFIG_NET_VENDOR_ARC is not set
|
||||||
|
# CONFIG_NET_VENDOR_ASIX is not set
|
||||||
# CONFIG_NET_VENDOR_ATHEROS is not set
|
# CONFIG_NET_VENDOR_ATHEROS is not set
|
||||||
# CONFIG_NET_VENDOR_BROADCOM is not set
|
# CONFIG_NET_VENDOR_BROADCOM is not set
|
||||||
# CONFIG_NET_VENDOR_BROCADE is not set
|
# CONFIG_NET_VENDOR_BROCADE is not set
|
||||||
|
@ -762,12 +763,14 @@ CONFIG_PRIME_NUMBERS=m
|
||||||
CONFIG_CRC4=m
|
CONFIG_CRC4=m
|
||||||
CONFIG_CRC7=m
|
CONFIG_CRC7=m
|
||||||
CONFIG_CRC8=m
|
CONFIG_CRC8=m
|
||||||
|
CONFIG_XZ_DEC_MICROLZMA=y
|
||||||
CONFIG_DMA_CMA=y
|
CONFIG_DMA_CMA=y
|
||||||
CONFIG_CMA_SIZE_MBYTES=0
|
CONFIG_CMA_SIZE_MBYTES=0
|
||||||
CONFIG_PRINTK_TIME=y
|
CONFIG_PRINTK_TIME=y
|
||||||
CONFIG_DYNAMIC_DEBUG=y
|
CONFIG_DYNAMIC_DEBUG=y
|
||||||
CONFIG_DEBUG_INFO=y
|
CONFIG_DEBUG_INFO=y
|
||||||
CONFIG_DEBUG_INFO_DWARF4=y
|
CONFIG_DEBUG_INFO_DWARF4=y
|
||||||
|
CONFIG_DEBUG_INFO_BTF=y
|
||||||
CONFIG_GDB_SCRIPTS=y
|
CONFIG_GDB_SCRIPTS=y
|
||||||
CONFIG_DEBUG_SECTION_MISMATCH=y
|
CONFIG_DEBUG_SECTION_MISMATCH=y
|
||||||
CONFIG_MAGIC_SYSRQ=y
|
CONFIG_MAGIC_SYSRQ=y
|
||||||
|
@ -792,9 +795,11 @@ CONFIG_HIST_TRIGGERS=y
|
||||||
CONFIG_SAMPLES=y
|
CONFIG_SAMPLES=y
|
||||||
CONFIG_SAMPLE_TRACE_PRINTK=m
|
CONFIG_SAMPLE_TRACE_PRINTK=m
|
||||||
CONFIG_SAMPLE_FTRACE_DIRECT=m
|
CONFIG_SAMPLE_FTRACE_DIRECT=m
|
||||||
|
CONFIG_SAMPLE_FTRACE_DIRECT_MULTI=m
|
||||||
CONFIG_KUNIT=m
|
CONFIG_KUNIT=m
|
||||||
CONFIG_KUNIT_DEBUGFS=y
|
CONFIG_KUNIT_DEBUGFS=y
|
||||||
CONFIG_LKDTM=m
|
CONFIG_LKDTM=m
|
||||||
|
CONFIG_KPROBES_SANITY_TEST=m
|
||||||
CONFIG_PERCPU_TEST=m
|
CONFIG_PERCPU_TEST=m
|
||||||
CONFIG_ATOMIC64_SELFTEST=y
|
CONFIG_ATOMIC64_SELFTEST=y
|
||||||
CONFIG_TEST_BPF=m
|
CONFIG_TEST_BPF=m
|
||||||
|
|
|
@ -65,9 +65,11 @@ CONFIG_ZFCP=y
|
||||||
# CONFIG_NETWORK_FILESYSTEMS is not set
|
# CONFIG_NETWORK_FILESYSTEMS is not set
|
||||||
CONFIG_LSM="yama,loadpin,safesetid,integrity"
|
CONFIG_LSM="yama,loadpin,safesetid,integrity"
|
||||||
# CONFIG_ZLIB_DFLTCC is not set
|
# CONFIG_ZLIB_DFLTCC is not set
|
||||||
|
CONFIG_XZ_DEC_MICROLZMA=y
|
||||||
CONFIG_PRINTK_TIME=y
|
CONFIG_PRINTK_TIME=y
|
||||||
# CONFIG_SYMBOLIC_ERRNAME is not set
|
# CONFIG_SYMBOLIC_ERRNAME is not set
|
||||||
CONFIG_DEBUG_INFO=y
|
CONFIG_DEBUG_INFO=y
|
||||||
|
CONFIG_DEBUG_INFO_BTF=y
|
||||||
CONFIG_DEBUG_FS=y
|
CONFIG_DEBUG_FS=y
|
||||||
CONFIG_DEBUG_KERNEL=y
|
CONFIG_DEBUG_KERNEL=y
|
||||||
CONFIG_PANIC_ON_OOPS=y
|
CONFIG_PANIC_ON_OOPS=y
|
||||||
|
|
|
@ -14,12 +14,13 @@
|
||||||
|
|
||||||
/* I/O Map */
|
/* I/O Map */
|
||||||
#define ZPCI_IOMAP_SHIFT 48
|
#define ZPCI_IOMAP_SHIFT 48
|
||||||
#define ZPCI_IOMAP_ADDR_BASE 0x8000000000000000UL
|
#define ZPCI_IOMAP_ADDR_SHIFT 62
|
||||||
|
#define ZPCI_IOMAP_ADDR_BASE (1UL << ZPCI_IOMAP_ADDR_SHIFT)
|
||||||
#define ZPCI_IOMAP_ADDR_OFF_MASK ((1UL << ZPCI_IOMAP_SHIFT) - 1)
|
#define ZPCI_IOMAP_ADDR_OFF_MASK ((1UL << ZPCI_IOMAP_SHIFT) - 1)
|
||||||
#define ZPCI_IOMAP_MAX_ENTRIES \
|
#define ZPCI_IOMAP_MAX_ENTRIES \
|
||||||
((ULONG_MAX - ZPCI_IOMAP_ADDR_BASE + 1) / (1UL << ZPCI_IOMAP_SHIFT))
|
(1UL << (ZPCI_IOMAP_ADDR_SHIFT - ZPCI_IOMAP_SHIFT))
|
||||||
#define ZPCI_IOMAP_ADDR_IDX_MASK \
|
#define ZPCI_IOMAP_ADDR_IDX_MASK \
|
||||||
(~ZPCI_IOMAP_ADDR_OFF_MASK - ZPCI_IOMAP_ADDR_BASE)
|
((ZPCI_IOMAP_ADDR_BASE - 1) & ~ZPCI_IOMAP_ADDR_OFF_MASK)
|
||||||
|
|
||||||
struct zpci_iomap_entry {
|
struct zpci_iomap_entry {
|
||||||
u32 fh;
|
u32 fh;
|
||||||
|
|
|
@ -173,10 +173,11 @@ static noinline int unwindme_func4(struct unwindme *u)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* trigger specification exception
|
* Trigger operation exception; use insn notation to bypass
|
||||||
|
* llvm's integrated assembler sanity checks.
|
||||||
*/
|
*/
|
||||||
asm volatile(
|
asm volatile(
|
||||||
" mvcl %%r1,%%r1\n"
|
" .insn e,0x0000\n" /* illegal opcode */
|
||||||
"0: nopr %%r7\n"
|
"0: nopr %%r7\n"
|
||||||
EX_TABLE(0b, 0b)
|
EX_TABLE(0b, 0b)
|
||||||
:);
|
:);
|
||||||
|
|
|
@ -1932,6 +1932,7 @@ config EFI
|
||||||
depends on ACPI
|
depends on ACPI
|
||||||
select UCS2_STRING
|
select UCS2_STRING
|
||||||
select EFI_RUNTIME_WRAPPERS
|
select EFI_RUNTIME_WRAPPERS
|
||||||
|
select ARCH_USE_MEMREMAP_PROT
|
||||||
help
|
help
|
||||||
This enables the kernel to use EFI runtime services that are
|
This enables the kernel to use EFI runtime services that are
|
||||||
available (such as the EFI variable services).
|
available (such as the EFI variable services).
|
||||||
|
|
|
@ -574,6 +574,10 @@ SYM_INNER_LABEL(swapgs_restore_regs_and_return_to_usermode, SYM_L_GLOBAL)
|
||||||
ud2
|
ud2
|
||||||
1:
|
1:
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_XEN_PV
|
||||||
|
ALTERNATIVE "", "jmp xenpv_restore_regs_and_return_to_usermode", X86_FEATURE_XENPV
|
||||||
|
#endif
|
||||||
|
|
||||||
POP_REGS pop_rdi=0
|
POP_REGS pop_rdi=0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -890,6 +894,7 @@ SYM_CODE_START_LOCAL(paranoid_entry)
|
||||||
.Lparanoid_entry_checkgs:
|
.Lparanoid_entry_checkgs:
|
||||||
/* EBX = 1 -> kernel GSBASE active, no restore required */
|
/* EBX = 1 -> kernel GSBASE active, no restore required */
|
||||||
movl $1, %ebx
|
movl $1, %ebx
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The kernel-enforced convention is a negative GSBASE indicates
|
* The kernel-enforced convention is a negative GSBASE indicates
|
||||||
* a kernel value. No SWAPGS needed on entry and exit.
|
* a kernel value. No SWAPGS needed on entry and exit.
|
||||||
|
@ -897,21 +902,14 @@ SYM_CODE_START_LOCAL(paranoid_entry)
|
||||||
movl $MSR_GS_BASE, %ecx
|
movl $MSR_GS_BASE, %ecx
|
||||||
rdmsr
|
rdmsr
|
||||||
testl %edx, %edx
|
testl %edx, %edx
|
||||||
jns .Lparanoid_entry_swapgs
|
js .Lparanoid_kernel_gsbase
|
||||||
ret
|
|
||||||
|
|
||||||
.Lparanoid_entry_swapgs:
|
|
||||||
swapgs
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The above SAVE_AND_SWITCH_TO_KERNEL_CR3 macro doesn't do an
|
|
||||||
* unconditional CR3 write, even in the PTI case. So do an lfence
|
|
||||||
* to prevent GS speculation, regardless of whether PTI is enabled.
|
|
||||||
*/
|
|
||||||
FENCE_SWAPGS_KERNEL_ENTRY
|
|
||||||
|
|
||||||
/* EBX = 0 -> SWAPGS required on exit */
|
/* EBX = 0 -> SWAPGS required on exit */
|
||||||
xorl %ebx, %ebx
|
xorl %ebx, %ebx
|
||||||
|
swapgs
|
||||||
|
.Lparanoid_kernel_gsbase:
|
||||||
|
|
||||||
|
FENCE_SWAPGS_KERNEL_ENTRY
|
||||||
ret
|
ret
|
||||||
SYM_CODE_END(paranoid_entry)
|
SYM_CODE_END(paranoid_entry)
|
||||||
|
|
||||||
|
@ -993,11 +991,6 @@ SYM_CODE_START_LOCAL(error_entry)
|
||||||
pushq %r12
|
pushq %r12
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.Lerror_entry_done_lfence:
|
|
||||||
FENCE_SWAPGS_KERNEL_ENTRY
|
|
||||||
.Lerror_entry_done:
|
|
||||||
ret
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There are two places in the kernel that can potentially fault with
|
* There are two places in the kernel that can potentially fault with
|
||||||
* usergs. Handle them here. B stepping K8s sometimes report a
|
* usergs. Handle them here. B stepping K8s sometimes report a
|
||||||
|
@ -1020,8 +1013,14 @@ SYM_CODE_START_LOCAL(error_entry)
|
||||||
* .Lgs_change's error handler with kernel gsbase.
|
* .Lgs_change's error handler with kernel gsbase.
|
||||||
*/
|
*/
|
||||||
SWAPGS
|
SWAPGS
|
||||||
FENCE_SWAPGS_USER_ENTRY
|
|
||||||
jmp .Lerror_entry_done
|
/*
|
||||||
|
* Issue an LFENCE to prevent GS speculation, regardless of whether it is a
|
||||||
|
* kernel or user gsbase.
|
||||||
|
*/
|
||||||
|
.Lerror_entry_done_lfence:
|
||||||
|
FENCE_SWAPGS_KERNEL_ENTRY
|
||||||
|
ret
|
||||||
|
|
||||||
.Lbstep_iret:
|
.Lbstep_iret:
|
||||||
/* Fix truncated RIP */
|
/* Fix truncated RIP */
|
||||||
|
|
|
@ -108,7 +108,7 @@
|
||||||
#define INTEL_FAM6_ALDERLAKE 0x97 /* Golden Cove / Gracemont */
|
#define INTEL_FAM6_ALDERLAKE 0x97 /* Golden Cove / Gracemont */
|
||||||
#define INTEL_FAM6_ALDERLAKE_L 0x9A /* Golden Cove / Gracemont */
|
#define INTEL_FAM6_ALDERLAKE_L 0x9A /* Golden Cove / Gracemont */
|
||||||
|
|
||||||
#define INTEL_FAM6_RAPTOR_LAKE 0xB7
|
#define INTEL_FAM6_RAPTORLAKE 0xB7
|
||||||
|
|
||||||
/* "Small Core" Processors (Atom) */
|
/* "Small Core" Processors (Atom) */
|
||||||
|
|
||||||
|
|
|
@ -1036,6 +1036,7 @@ struct kvm_x86_msr_filter {
|
||||||
#define APICV_INHIBIT_REASON_PIT_REINJ 4
|
#define APICV_INHIBIT_REASON_PIT_REINJ 4
|
||||||
#define APICV_INHIBIT_REASON_X2APIC 5
|
#define APICV_INHIBIT_REASON_X2APIC 5
|
||||||
#define APICV_INHIBIT_REASON_BLOCKIRQ 6
|
#define APICV_INHIBIT_REASON_BLOCKIRQ 6
|
||||||
|
#define APICV_INHIBIT_REASON_ABSENT 7
|
||||||
|
|
||||||
struct kvm_arch {
|
struct kvm_arch {
|
||||||
unsigned long n_used_mmu_pages;
|
unsigned long n_used_mmu_pages;
|
||||||
|
|
|
@ -73,4 +73,15 @@
|
||||||
|
|
||||||
#define GHCB_RESP_CODE(v) ((v) & GHCB_MSR_INFO_MASK)
|
#define GHCB_RESP_CODE(v) ((v) & GHCB_MSR_INFO_MASK)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Error codes related to GHCB input that can be communicated back to the guest
|
||||||
|
* by setting the lower 32-bits of the GHCB SW_EXITINFO1 field to 2.
|
||||||
|
*/
|
||||||
|
#define GHCB_ERR_NOT_REGISTERED 1
|
||||||
|
#define GHCB_ERR_INVALID_USAGE 2
|
||||||
|
#define GHCB_ERR_INVALID_SCRATCH_AREA 3
|
||||||
|
#define GHCB_ERR_MISSING_INPUT 4
|
||||||
|
#define GHCB_ERR_INVALID_INPUT 5
|
||||||
|
#define GHCB_ERR_INVALID_EVENT 6
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -118,7 +118,7 @@ static inline bool save_xstate_epilog(void __user *buf, int ia32_frame,
|
||||||
struct fpstate *fpstate)
|
struct fpstate *fpstate)
|
||||||
{
|
{
|
||||||
struct xregs_state __user *x = buf;
|
struct xregs_state __user *x = buf;
|
||||||
struct _fpx_sw_bytes sw_bytes;
|
struct _fpx_sw_bytes sw_bytes = {};
|
||||||
u32 xfeatures;
|
u32 xfeatures;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
|
|
@ -294,11 +294,6 @@ static enum es_result vc_write_mem(struct es_em_ctxt *ctxt,
|
||||||
char *dst, char *buf, size_t size)
|
char *dst, char *buf, size_t size)
|
||||||
{
|
{
|
||||||
unsigned long error_code = X86_PF_PROT | X86_PF_WRITE;
|
unsigned long error_code = X86_PF_PROT | X86_PF_WRITE;
|
||||||
char __user *target = (char __user *)dst;
|
|
||||||
u64 d8;
|
|
||||||
u32 d4;
|
|
||||||
u16 d2;
|
|
||||||
u8 d1;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function uses __put_user() independent of whether kernel or user
|
* This function uses __put_user() independent of whether kernel or user
|
||||||
|
@ -320,26 +315,42 @@ static enum es_result vc_write_mem(struct es_em_ctxt *ctxt,
|
||||||
* instructions here would cause infinite nesting.
|
* instructions here would cause infinite nesting.
|
||||||
*/
|
*/
|
||||||
switch (size) {
|
switch (size) {
|
||||||
case 1:
|
case 1: {
|
||||||
|
u8 d1;
|
||||||
|
u8 __user *target = (u8 __user *)dst;
|
||||||
|
|
||||||
memcpy(&d1, buf, 1);
|
memcpy(&d1, buf, 1);
|
||||||
if (__put_user(d1, target))
|
if (__put_user(d1, target))
|
||||||
goto fault;
|
goto fault;
|
||||||
break;
|
break;
|
||||||
case 2:
|
}
|
||||||
|
case 2: {
|
||||||
|
u16 d2;
|
||||||
|
u16 __user *target = (u16 __user *)dst;
|
||||||
|
|
||||||
memcpy(&d2, buf, 2);
|
memcpy(&d2, buf, 2);
|
||||||
if (__put_user(d2, target))
|
if (__put_user(d2, target))
|
||||||
goto fault;
|
goto fault;
|
||||||
break;
|
break;
|
||||||
case 4:
|
}
|
||||||
|
case 4: {
|
||||||
|
u32 d4;
|
||||||
|
u32 __user *target = (u32 __user *)dst;
|
||||||
|
|
||||||
memcpy(&d4, buf, 4);
|
memcpy(&d4, buf, 4);
|
||||||
if (__put_user(d4, target))
|
if (__put_user(d4, target))
|
||||||
goto fault;
|
goto fault;
|
||||||
break;
|
break;
|
||||||
case 8:
|
}
|
||||||
|
case 8: {
|
||||||
|
u64 d8;
|
||||||
|
u64 __user *target = (u64 __user *)dst;
|
||||||
|
|
||||||
memcpy(&d8, buf, 8);
|
memcpy(&d8, buf, 8);
|
||||||
if (__put_user(d8, target))
|
if (__put_user(d8, target))
|
||||||
goto fault;
|
goto fault;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
WARN_ONCE(1, "%s: Invalid size: %zu\n", __func__, size);
|
WARN_ONCE(1, "%s: Invalid size: %zu\n", __func__, size);
|
||||||
return ES_UNSUPPORTED;
|
return ES_UNSUPPORTED;
|
||||||
|
@ -362,11 +373,6 @@ static enum es_result vc_read_mem(struct es_em_ctxt *ctxt,
|
||||||
char *src, char *buf, size_t size)
|
char *src, char *buf, size_t size)
|
||||||
{
|
{
|
||||||
unsigned long error_code = X86_PF_PROT;
|
unsigned long error_code = X86_PF_PROT;
|
||||||
char __user *s = (char __user *)src;
|
|
||||||
u64 d8;
|
|
||||||
u32 d4;
|
|
||||||
u16 d2;
|
|
||||||
u8 d1;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function uses __get_user() independent of whether kernel or user
|
* This function uses __get_user() independent of whether kernel or user
|
||||||
|
@ -388,26 +394,41 @@ static enum es_result vc_read_mem(struct es_em_ctxt *ctxt,
|
||||||
* instructions here would cause infinite nesting.
|
* instructions here would cause infinite nesting.
|
||||||
*/
|
*/
|
||||||
switch (size) {
|
switch (size) {
|
||||||
case 1:
|
case 1: {
|
||||||
|
u8 d1;
|
||||||
|
u8 __user *s = (u8 __user *)src;
|
||||||
|
|
||||||
if (__get_user(d1, s))
|
if (__get_user(d1, s))
|
||||||
goto fault;
|
goto fault;
|
||||||
memcpy(buf, &d1, 1);
|
memcpy(buf, &d1, 1);
|
||||||
break;
|
break;
|
||||||
case 2:
|
}
|
||||||
|
case 2: {
|
||||||
|
u16 d2;
|
||||||
|
u16 __user *s = (u16 __user *)src;
|
||||||
|
|
||||||
if (__get_user(d2, s))
|
if (__get_user(d2, s))
|
||||||
goto fault;
|
goto fault;
|
||||||
memcpy(buf, &d2, 2);
|
memcpy(buf, &d2, 2);
|
||||||
break;
|
break;
|
||||||
case 4:
|
}
|
||||||
|
case 4: {
|
||||||
|
u32 d4;
|
||||||
|
u32 __user *s = (u32 __user *)src;
|
||||||
|
|
||||||
if (__get_user(d4, s))
|
if (__get_user(d4, s))
|
||||||
goto fault;
|
goto fault;
|
||||||
memcpy(buf, &d4, 4);
|
memcpy(buf, &d4, 4);
|
||||||
break;
|
break;
|
||||||
case 8:
|
}
|
||||||
|
case 8: {
|
||||||
|
u64 d8;
|
||||||
|
u64 __user *s = (u64 __user *)src;
|
||||||
if (__get_user(d8, s))
|
if (__get_user(d8, s))
|
||||||
goto fault;
|
goto fault;
|
||||||
memcpy(buf, &d8, 8);
|
memcpy(buf, &d8, 8);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
WARN_ONCE(1, "%s: Invalid size: %zu\n", __func__, size);
|
WARN_ONCE(1, "%s: Invalid size: %zu\n", __func__, size);
|
||||||
return ES_UNSUPPORTED;
|
return ES_UNSUPPORTED;
|
||||||
|
|
|
@ -1180,6 +1180,12 @@ void mark_tsc_unstable(char *reason)
|
||||||
|
|
||||||
EXPORT_SYMBOL_GPL(mark_tsc_unstable);
|
EXPORT_SYMBOL_GPL(mark_tsc_unstable);
|
||||||
|
|
||||||
|
static void __init tsc_disable_clocksource_watchdog(void)
|
||||||
|
{
|
||||||
|
clocksource_tsc_early.flags &= ~CLOCK_SOURCE_MUST_VERIFY;
|
||||||
|
clocksource_tsc.flags &= ~CLOCK_SOURCE_MUST_VERIFY;
|
||||||
|
}
|
||||||
|
|
||||||
static void __init check_system_tsc_reliable(void)
|
static void __init check_system_tsc_reliable(void)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_MGEODEGX1) || defined(CONFIG_MGEODE_LX) || defined(CONFIG_X86_GENERIC)
|
#if defined(CONFIG_MGEODEGX1) || defined(CONFIG_MGEODE_LX) || defined(CONFIG_X86_GENERIC)
|
||||||
|
@ -1196,6 +1202,23 @@ static void __init check_system_tsc_reliable(void)
|
||||||
#endif
|
#endif
|
||||||
if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE))
|
if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE))
|
||||||
tsc_clocksource_reliable = 1;
|
tsc_clocksource_reliable = 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disable the clocksource watchdog when the system has:
|
||||||
|
* - TSC running at constant frequency
|
||||||
|
* - TSC which does not stop in C-States
|
||||||
|
* - the TSC_ADJUST register which allows to detect even minimal
|
||||||
|
* modifications
|
||||||
|
* - not more than two sockets. As the number of sockets cannot be
|
||||||
|
* evaluated at the early boot stage where this has to be
|
||||||
|
* invoked, check the number of online memory nodes as a
|
||||||
|
* fallback solution which is an reasonable estimate.
|
||||||
|
*/
|
||||||
|
if (boot_cpu_has(X86_FEATURE_CONSTANT_TSC) &&
|
||||||
|
boot_cpu_has(X86_FEATURE_NONSTOP_TSC) &&
|
||||||
|
boot_cpu_has(X86_FEATURE_TSC_ADJUST) &&
|
||||||
|
nr_online_nodes <= 2)
|
||||||
|
tsc_disable_clocksource_watchdog();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1387,9 +1410,6 @@ static int __init init_tsc_clocksource(void)
|
||||||
if (tsc_unstable)
|
if (tsc_unstable)
|
||||||
goto unreg;
|
goto unreg;
|
||||||
|
|
||||||
if (tsc_clocksource_reliable || no_tsc_watchdog)
|
|
||||||
clocksource_tsc.flags &= ~CLOCK_SOURCE_MUST_VERIFY;
|
|
||||||
|
|
||||||
if (boot_cpu_has(X86_FEATURE_NONSTOP_TSC_S3))
|
if (boot_cpu_has(X86_FEATURE_NONSTOP_TSC_S3))
|
||||||
clocksource_tsc.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP;
|
clocksource_tsc.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP;
|
||||||
|
|
||||||
|
@ -1527,7 +1547,7 @@ void __init tsc_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tsc_clocksource_reliable || no_tsc_watchdog)
|
if (tsc_clocksource_reliable || no_tsc_watchdog)
|
||||||
clocksource_tsc_early.flags &= ~CLOCK_SOURCE_MUST_VERIFY;
|
tsc_disable_clocksource_watchdog();
|
||||||
|
|
||||||
clocksource_register_khz(&clocksource_tsc_early, tsc_khz);
|
clocksource_register_khz(&clocksource_tsc_early, tsc_khz);
|
||||||
detect_art();
|
detect_art();
|
||||||
|
|
|
@ -30,6 +30,7 @@ struct tsc_adjust {
|
||||||
};
|
};
|
||||||
|
|
||||||
static DEFINE_PER_CPU(struct tsc_adjust, tsc_adjust);
|
static DEFINE_PER_CPU(struct tsc_adjust, tsc_adjust);
|
||||||
|
static struct timer_list tsc_sync_check_timer;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TSC's on different sockets may be reset asynchronously.
|
* TSC's on different sockets may be reset asynchronously.
|
||||||
|
@ -77,6 +78,46 @@ void tsc_verify_tsc_adjust(bool resume)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Normally the tsc_sync will be checked every time system enters idle
|
||||||
|
* state, but there is still caveat that a system won't enter idle,
|
||||||
|
* either because it's too busy or configured purposely to not enter
|
||||||
|
* idle.
|
||||||
|
*
|
||||||
|
* So setup a periodic timer (every 10 minutes) to make sure the check
|
||||||
|
* is always on.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SYNC_CHECK_INTERVAL (HZ * 600)
|
||||||
|
|
||||||
|
static void tsc_sync_check_timer_fn(struct timer_list *unused)
|
||||||
|
{
|
||||||
|
int next_cpu;
|
||||||
|
|
||||||
|
tsc_verify_tsc_adjust(false);
|
||||||
|
|
||||||
|
/* Run the check for all onlined CPUs in turn */
|
||||||
|
next_cpu = cpumask_next(raw_smp_processor_id(), cpu_online_mask);
|
||||||
|
if (next_cpu >= nr_cpu_ids)
|
||||||
|
next_cpu = cpumask_first(cpu_online_mask);
|
||||||
|
|
||||||
|
tsc_sync_check_timer.expires += SYNC_CHECK_INTERVAL;
|
||||||
|
add_timer_on(&tsc_sync_check_timer, next_cpu);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init start_sync_check_timer(void)
|
||||||
|
{
|
||||||
|
if (!cpu_feature_enabled(X86_FEATURE_TSC_ADJUST) || tsc_clocksource_reliable)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
timer_setup(&tsc_sync_check_timer, tsc_sync_check_timer_fn, 0);
|
||||||
|
tsc_sync_check_timer.expires = jiffies + SYNC_CHECK_INTERVAL;
|
||||||
|
add_timer(&tsc_sync_check_timer);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
late_initcall(start_sync_check_timer);
|
||||||
|
|
||||||
static void tsc_sanitize_first_cpu(struct tsc_adjust *cur, s64 bootval,
|
static void tsc_sanitize_first_cpu(struct tsc_adjust *cur, s64 bootval,
|
||||||
unsigned int cpu, bool bootcpu)
|
unsigned int cpu, bool bootcpu)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1936,7 +1936,11 @@ static void mmu_audit_disable(void) { }
|
||||||
|
|
||||||
static bool is_obsolete_sp(struct kvm *kvm, struct kvm_mmu_page *sp)
|
static bool is_obsolete_sp(struct kvm *kvm, struct kvm_mmu_page *sp)
|
||||||
{
|
{
|
||||||
return sp->role.invalid ||
|
if (sp->role.invalid)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
/* TDP MMU pages due not use the MMU generation. */
|
||||||
|
return !sp->tdp_mmu_page &&
|
||||||
unlikely(sp->mmu_valid_gen != kvm->arch.mmu_valid_gen);
|
unlikely(sp->mmu_valid_gen != kvm->arch.mmu_valid_gen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3976,6 +3980,20 @@ out_retry:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns true if the page fault is stale and needs to be retried, i.e. if the
|
||||||
|
* root was invalidated by a memslot update or a relevant mmu_notifier fired.
|
||||||
|
*/
|
||||||
|
static bool is_page_fault_stale(struct kvm_vcpu *vcpu,
|
||||||
|
struct kvm_page_fault *fault, int mmu_seq)
|
||||||
|
{
|
||||||
|
if (is_obsolete_sp(vcpu->kvm, to_shadow_page(vcpu->arch.mmu->root_hpa)))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return fault->slot &&
|
||||||
|
mmu_notifier_retry_hva(vcpu->kvm, mmu_seq, fault->hva);
|
||||||
|
}
|
||||||
|
|
||||||
static int direct_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
|
static int direct_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
|
||||||
{
|
{
|
||||||
bool is_tdp_mmu_fault = is_tdp_mmu(vcpu->arch.mmu);
|
bool is_tdp_mmu_fault = is_tdp_mmu(vcpu->arch.mmu);
|
||||||
|
@ -4013,8 +4031,9 @@ static int direct_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault
|
||||||
else
|
else
|
||||||
write_lock(&vcpu->kvm->mmu_lock);
|
write_lock(&vcpu->kvm->mmu_lock);
|
||||||
|
|
||||||
if (fault->slot && mmu_notifier_retry_hva(vcpu->kvm, mmu_seq, fault->hva))
|
if (is_page_fault_stale(vcpu, fault, mmu_seq))
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
||||||
r = make_mmu_pages_available(vcpu);
|
r = make_mmu_pages_available(vcpu);
|
||||||
if (r)
|
if (r)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
|
@ -911,7 +911,8 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault
|
||||||
|
|
||||||
r = RET_PF_RETRY;
|
r = RET_PF_RETRY;
|
||||||
write_lock(&vcpu->kvm->mmu_lock);
|
write_lock(&vcpu->kvm->mmu_lock);
|
||||||
if (fault->slot && mmu_notifier_retry_hva(vcpu->kvm, mmu_seq, fault->hva))
|
|
||||||
|
if (is_page_fault_stale(vcpu, fault, mmu_seq))
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
||||||
kvm_mmu_audit(vcpu, AUDIT_PRE_PAGE_FAULT);
|
kvm_mmu_audit(vcpu, AUDIT_PRE_PAGE_FAULT);
|
||||||
|
|
|
@ -900,6 +900,7 @@ out:
|
||||||
bool svm_check_apicv_inhibit_reasons(ulong bit)
|
bool svm_check_apicv_inhibit_reasons(ulong bit)
|
||||||
{
|
{
|
||||||
ulong supported = BIT(APICV_INHIBIT_REASON_DISABLE) |
|
ulong supported = BIT(APICV_INHIBIT_REASON_DISABLE) |
|
||||||
|
BIT(APICV_INHIBIT_REASON_ABSENT) |
|
||||||
BIT(APICV_INHIBIT_REASON_HYPERV) |
|
BIT(APICV_INHIBIT_REASON_HYPERV) |
|
||||||
BIT(APICV_INHIBIT_REASON_NESTED) |
|
BIT(APICV_INHIBIT_REASON_NESTED) |
|
||||||
BIT(APICV_INHIBIT_REASON_IRQWIN) |
|
BIT(APICV_INHIBIT_REASON_IRQWIN) |
|
||||||
|
|
|
@ -281,7 +281,7 @@ static void amd_pmu_refresh(struct kvm_vcpu *vcpu)
|
||||||
pmu->nr_arch_gp_counters = AMD64_NUM_COUNTERS;
|
pmu->nr_arch_gp_counters = AMD64_NUM_COUNTERS;
|
||||||
|
|
||||||
pmu->counter_bitmask[KVM_PMC_GP] = ((u64)1 << 48) - 1;
|
pmu->counter_bitmask[KVM_PMC_GP] = ((u64)1 << 48) - 1;
|
||||||
pmu->reserved_bits = 0xffffffff00200000ull;
|
pmu->reserved_bits = 0xfffffff000280000ull;
|
||||||
pmu->version = 1;
|
pmu->version = 1;
|
||||||
/* not applicable to AMD; but clean them to prevent any fall out */
|
/* not applicable to AMD; but clean them to prevent any fall out */
|
||||||
pmu->counter_bitmask[KVM_PMC_FIXED] = 0;
|
pmu->counter_bitmask[KVM_PMC_FIXED] = 0;
|
||||||
|
|
|
@ -2260,7 +2260,7 @@ void sev_free_vcpu(struct kvm_vcpu *vcpu)
|
||||||
__free_page(virt_to_page(svm->sev_es.vmsa));
|
__free_page(virt_to_page(svm->sev_es.vmsa));
|
||||||
|
|
||||||
if (svm->sev_es.ghcb_sa_free)
|
if (svm->sev_es.ghcb_sa_free)
|
||||||
kfree(svm->sev_es.ghcb_sa);
|
kvfree(svm->sev_es.ghcb_sa);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dump_ghcb(struct vcpu_svm *svm)
|
static void dump_ghcb(struct vcpu_svm *svm)
|
||||||
|
@ -2352,24 +2352,29 @@ static void sev_es_sync_from_ghcb(struct vcpu_svm *svm)
|
||||||
memset(ghcb->save.valid_bitmap, 0, sizeof(ghcb->save.valid_bitmap));
|
memset(ghcb->save.valid_bitmap, 0, sizeof(ghcb->save.valid_bitmap));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
|
static bool sev_es_validate_vmgexit(struct vcpu_svm *svm)
|
||||||
{
|
{
|
||||||
struct kvm_vcpu *vcpu;
|
struct kvm_vcpu *vcpu;
|
||||||
struct ghcb *ghcb;
|
struct ghcb *ghcb;
|
||||||
u64 exit_code = 0;
|
u64 exit_code;
|
||||||
|
u64 reason;
|
||||||
|
|
||||||
ghcb = svm->sev_es.ghcb;
|
ghcb = svm->sev_es.ghcb;
|
||||||
|
|
||||||
/* Only GHCB Usage code 0 is supported */
|
|
||||||
if (ghcb->ghcb_usage)
|
|
||||||
goto vmgexit_err;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Retrieve the exit code now even though is may not be marked valid
|
* Retrieve the exit code now even though it may not be marked valid
|
||||||
* as it could help with debugging.
|
* as it could help with debugging.
|
||||||
*/
|
*/
|
||||||
exit_code = ghcb_get_sw_exit_code(ghcb);
|
exit_code = ghcb_get_sw_exit_code(ghcb);
|
||||||
|
|
||||||
|
/* Only GHCB Usage code 0 is supported */
|
||||||
|
if (ghcb->ghcb_usage) {
|
||||||
|
reason = GHCB_ERR_INVALID_USAGE;
|
||||||
|
goto vmgexit_err;
|
||||||
|
}
|
||||||
|
|
||||||
|
reason = GHCB_ERR_MISSING_INPUT;
|
||||||
|
|
||||||
if (!ghcb_sw_exit_code_is_valid(ghcb) ||
|
if (!ghcb_sw_exit_code_is_valid(ghcb) ||
|
||||||
!ghcb_sw_exit_info_1_is_valid(ghcb) ||
|
!ghcb_sw_exit_info_1_is_valid(ghcb) ||
|
||||||
!ghcb_sw_exit_info_2_is_valid(ghcb))
|
!ghcb_sw_exit_info_2_is_valid(ghcb))
|
||||||
|
@ -2448,30 +2453,34 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
|
||||||
case SVM_VMGEXIT_UNSUPPORTED_EVENT:
|
case SVM_VMGEXIT_UNSUPPORTED_EVENT:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
reason = GHCB_ERR_INVALID_EVENT;
|
||||||
goto vmgexit_err;
|
goto vmgexit_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return true;
|
||||||
|
|
||||||
vmgexit_err:
|
vmgexit_err:
|
||||||
vcpu = &svm->vcpu;
|
vcpu = &svm->vcpu;
|
||||||
|
|
||||||
if (ghcb->ghcb_usage) {
|
if (reason == GHCB_ERR_INVALID_USAGE) {
|
||||||
vcpu_unimpl(vcpu, "vmgexit: ghcb usage %#x is not valid\n",
|
vcpu_unimpl(vcpu, "vmgexit: ghcb usage %#x is not valid\n",
|
||||||
ghcb->ghcb_usage);
|
ghcb->ghcb_usage);
|
||||||
|
} else if (reason == GHCB_ERR_INVALID_EVENT) {
|
||||||
|
vcpu_unimpl(vcpu, "vmgexit: exit code %#llx is not valid\n",
|
||||||
|
exit_code);
|
||||||
} else {
|
} else {
|
||||||
vcpu_unimpl(vcpu, "vmgexit: exit reason %#llx is not valid\n",
|
vcpu_unimpl(vcpu, "vmgexit: exit code %#llx input is not valid\n",
|
||||||
exit_code);
|
exit_code);
|
||||||
dump_ghcb(svm);
|
dump_ghcb(svm);
|
||||||
}
|
}
|
||||||
|
|
||||||
vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
|
/* Clear the valid entries fields */
|
||||||
vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_UNEXPECTED_EXIT_REASON;
|
memset(ghcb->save.valid_bitmap, 0, sizeof(ghcb->save.valid_bitmap));
|
||||||
vcpu->run->internal.ndata = 2;
|
|
||||||
vcpu->run->internal.data[0] = exit_code;
|
|
||||||
vcpu->run->internal.data[1] = vcpu->arch.last_vmentry_cpu;
|
|
||||||
|
|
||||||
return -EINVAL;
|
ghcb_set_sw_exit_info_1(ghcb, 2);
|
||||||
|
ghcb_set_sw_exit_info_2(ghcb, reason);
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sev_es_unmap_ghcb(struct vcpu_svm *svm)
|
void sev_es_unmap_ghcb(struct vcpu_svm *svm)
|
||||||
|
@ -2493,7 +2502,7 @@ void sev_es_unmap_ghcb(struct vcpu_svm *svm)
|
||||||
svm->sev_es.ghcb_sa_sync = false;
|
svm->sev_es.ghcb_sa_sync = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
kfree(svm->sev_es.ghcb_sa);
|
kvfree(svm->sev_es.ghcb_sa);
|
||||||
svm->sev_es.ghcb_sa = NULL;
|
svm->sev_es.ghcb_sa = NULL;
|
||||||
svm->sev_es.ghcb_sa_free = false;
|
svm->sev_es.ghcb_sa_free = false;
|
||||||
}
|
}
|
||||||
|
@ -2541,14 +2550,14 @@ static bool setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len)
|
||||||
scratch_gpa_beg = ghcb_get_sw_scratch(ghcb);
|
scratch_gpa_beg = ghcb_get_sw_scratch(ghcb);
|
||||||
if (!scratch_gpa_beg) {
|
if (!scratch_gpa_beg) {
|
||||||
pr_err("vmgexit: scratch gpa not provided\n");
|
pr_err("vmgexit: scratch gpa not provided\n");
|
||||||
return false;
|
goto e_scratch;
|
||||||
}
|
}
|
||||||
|
|
||||||
scratch_gpa_end = scratch_gpa_beg + len;
|
scratch_gpa_end = scratch_gpa_beg + len;
|
||||||
if (scratch_gpa_end < scratch_gpa_beg) {
|
if (scratch_gpa_end < scratch_gpa_beg) {
|
||||||
pr_err("vmgexit: scratch length (%#llx) not valid for scratch address (%#llx)\n",
|
pr_err("vmgexit: scratch length (%#llx) not valid for scratch address (%#llx)\n",
|
||||||
len, scratch_gpa_beg);
|
len, scratch_gpa_beg);
|
||||||
return false;
|
goto e_scratch;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((scratch_gpa_beg & PAGE_MASK) == control->ghcb_gpa) {
|
if ((scratch_gpa_beg & PAGE_MASK) == control->ghcb_gpa) {
|
||||||
|
@ -2566,7 +2575,7 @@ static bool setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len)
|
||||||
scratch_gpa_end > ghcb_scratch_end) {
|
scratch_gpa_end > ghcb_scratch_end) {
|
||||||
pr_err("vmgexit: scratch area is outside of GHCB shared buffer area (%#llx - %#llx)\n",
|
pr_err("vmgexit: scratch area is outside of GHCB shared buffer area (%#llx - %#llx)\n",
|
||||||
scratch_gpa_beg, scratch_gpa_end);
|
scratch_gpa_beg, scratch_gpa_end);
|
||||||
return false;
|
goto e_scratch;
|
||||||
}
|
}
|
||||||
|
|
||||||
scratch_va = (void *)svm->sev_es.ghcb;
|
scratch_va = (void *)svm->sev_es.ghcb;
|
||||||
|
@ -2579,18 +2588,18 @@ static bool setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len)
|
||||||
if (len > GHCB_SCRATCH_AREA_LIMIT) {
|
if (len > GHCB_SCRATCH_AREA_LIMIT) {
|
||||||
pr_err("vmgexit: scratch area exceeds KVM limits (%#llx requested, %#llx limit)\n",
|
pr_err("vmgexit: scratch area exceeds KVM limits (%#llx requested, %#llx limit)\n",
|
||||||
len, GHCB_SCRATCH_AREA_LIMIT);
|
len, GHCB_SCRATCH_AREA_LIMIT);
|
||||||
return false;
|
goto e_scratch;
|
||||||
}
|
}
|
||||||
scratch_va = kzalloc(len, GFP_KERNEL_ACCOUNT);
|
scratch_va = kvzalloc(len, GFP_KERNEL_ACCOUNT);
|
||||||
if (!scratch_va)
|
if (!scratch_va)
|
||||||
return false;
|
goto e_scratch;
|
||||||
|
|
||||||
if (kvm_read_guest(svm->vcpu.kvm, scratch_gpa_beg, scratch_va, len)) {
|
if (kvm_read_guest(svm->vcpu.kvm, scratch_gpa_beg, scratch_va, len)) {
|
||||||
/* Unable to copy scratch area from guest */
|
/* Unable to copy scratch area from guest */
|
||||||
pr_err("vmgexit: kvm_read_guest for scratch area failed\n");
|
pr_err("vmgexit: kvm_read_guest for scratch area failed\n");
|
||||||
|
|
||||||
kfree(scratch_va);
|
kvfree(scratch_va);
|
||||||
return false;
|
goto e_scratch;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2607,6 +2616,12 @@ static bool setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len)
|
||||||
svm->sev_es.ghcb_sa_len = len;
|
svm->sev_es.ghcb_sa_len = len;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
e_scratch:
|
||||||
|
ghcb_set_sw_exit_info_1(ghcb, 2);
|
||||||
|
ghcb_set_sw_exit_info_2(ghcb, GHCB_ERR_INVALID_SCRATCH_AREA);
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_ghcb_msr_bits(struct vcpu_svm *svm, u64 value, u64 mask,
|
static void set_ghcb_msr_bits(struct vcpu_svm *svm, u64 value, u64 mask,
|
||||||
|
@ -2657,7 +2672,7 @@ static int sev_handle_vmgexit_msr_protocol(struct vcpu_svm *svm)
|
||||||
|
|
||||||
ret = svm_invoke_exit_handler(vcpu, SVM_EXIT_CPUID);
|
ret = svm_invoke_exit_handler(vcpu, SVM_EXIT_CPUID);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
ret = -EINVAL;
|
/* Error, keep GHCB MSR value as-is */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2693,10 +2708,13 @@ static int sev_handle_vmgexit_msr_protocol(struct vcpu_svm *svm)
|
||||||
GHCB_MSR_TERM_REASON_POS);
|
GHCB_MSR_TERM_REASON_POS);
|
||||||
pr_info("SEV-ES guest requested termination: %#llx:%#llx\n",
|
pr_info("SEV-ES guest requested termination: %#llx:%#llx\n",
|
||||||
reason_set, reason_code);
|
reason_set, reason_code);
|
||||||
fallthrough;
|
|
||||||
|
ret = -EINVAL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
ret = -EINVAL;
|
/* Error, keep GHCB MSR value as-is */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
trace_kvm_vmgexit_msr_protocol_exit(svm->vcpu.vcpu_id,
|
trace_kvm_vmgexit_msr_protocol_exit(svm->vcpu.vcpu_id,
|
||||||
|
@ -2720,14 +2738,18 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
|
||||||
|
|
||||||
if (!ghcb_gpa) {
|
if (!ghcb_gpa) {
|
||||||
vcpu_unimpl(vcpu, "vmgexit: GHCB gpa is not set\n");
|
vcpu_unimpl(vcpu, "vmgexit: GHCB gpa is not set\n");
|
||||||
return -EINVAL;
|
|
||||||
|
/* Without a GHCB, just return right back to the guest */
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kvm_vcpu_map(vcpu, ghcb_gpa >> PAGE_SHIFT, &svm->sev_es.ghcb_map)) {
|
if (kvm_vcpu_map(vcpu, ghcb_gpa >> PAGE_SHIFT, &svm->sev_es.ghcb_map)) {
|
||||||
/* Unable to map GHCB from guest */
|
/* Unable to map GHCB from guest */
|
||||||
vcpu_unimpl(vcpu, "vmgexit: error mapping GHCB [%#llx] from guest\n",
|
vcpu_unimpl(vcpu, "vmgexit: error mapping GHCB [%#llx] from guest\n",
|
||||||
ghcb_gpa);
|
ghcb_gpa);
|
||||||
return -EINVAL;
|
|
||||||
|
/* Without a GHCB, just return right back to the guest */
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
svm->sev_es.ghcb = svm->sev_es.ghcb_map.hva;
|
svm->sev_es.ghcb = svm->sev_es.ghcb_map.hva;
|
||||||
|
@ -2737,15 +2759,14 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
|
||||||
|
|
||||||
exit_code = ghcb_get_sw_exit_code(ghcb);
|
exit_code = ghcb_get_sw_exit_code(ghcb);
|
||||||
|
|
||||||
ret = sev_es_validate_vmgexit(svm);
|
if (!sev_es_validate_vmgexit(svm))
|
||||||
if (ret)
|
return 1;
|
||||||
return ret;
|
|
||||||
|
|
||||||
sev_es_sync_from_ghcb(svm);
|
sev_es_sync_from_ghcb(svm);
|
||||||
ghcb_set_sw_exit_info_1(ghcb, 0);
|
ghcb_set_sw_exit_info_1(ghcb, 0);
|
||||||
ghcb_set_sw_exit_info_2(ghcb, 0);
|
ghcb_set_sw_exit_info_2(ghcb, 0);
|
||||||
|
|
||||||
ret = -EINVAL;
|
ret = 1;
|
||||||
switch (exit_code) {
|
switch (exit_code) {
|
||||||
case SVM_VMGEXIT_MMIO_READ:
|
case SVM_VMGEXIT_MMIO_READ:
|
||||||
if (!setup_vmgexit_scratch(svm, true, control->exit_info_2))
|
if (!setup_vmgexit_scratch(svm, true, control->exit_info_2))
|
||||||
|
@ -2786,20 +2807,17 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
|
||||||
default:
|
default:
|
||||||
pr_err("svm: vmgexit: unsupported AP jump table request - exit_info_1=%#llx\n",
|
pr_err("svm: vmgexit: unsupported AP jump table request - exit_info_1=%#llx\n",
|
||||||
control->exit_info_1);
|
control->exit_info_1);
|
||||||
ghcb_set_sw_exit_info_1(ghcb, 1);
|
ghcb_set_sw_exit_info_1(ghcb, 2);
|
||||||
ghcb_set_sw_exit_info_2(ghcb,
|
ghcb_set_sw_exit_info_2(ghcb, GHCB_ERR_INVALID_INPUT);
|
||||||
X86_TRAP_UD |
|
|
||||||
SVM_EVTINJ_TYPE_EXEPT |
|
|
||||||
SVM_EVTINJ_VALID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 1;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SVM_VMGEXIT_UNSUPPORTED_EVENT:
|
case SVM_VMGEXIT_UNSUPPORTED_EVENT:
|
||||||
vcpu_unimpl(vcpu,
|
vcpu_unimpl(vcpu,
|
||||||
"vmgexit: unsupported event - exit_info_1=%#llx, exit_info_2=%#llx\n",
|
"vmgexit: unsupported event - exit_info_1=%#llx, exit_info_2=%#llx\n",
|
||||||
control->exit_info_1, control->exit_info_2);
|
control->exit_info_1, control->exit_info_2);
|
||||||
|
ret = -EINVAL;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ret = svm_invoke_exit_handler(vcpu, exit_code);
|
ret = svm_invoke_exit_handler(vcpu, exit_code);
|
||||||
|
@ -2821,7 +2839,7 @@ int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (!setup_vmgexit_scratch(svm, in, bytes))
|
if (!setup_vmgexit_scratch(svm, in, bytes))
|
||||||
return -EINVAL;
|
return 1;
|
||||||
|
|
||||||
return kvm_sev_es_string_io(&svm->vcpu, size, port, svm->sev_es.ghcb_sa,
|
return kvm_sev_es_string_io(&svm->vcpu, size, port, svm->sev_es.ghcb_sa,
|
||||||
count, in);
|
count, in);
|
||||||
|
|
|
@ -2591,8 +2591,10 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
|
||||||
|
|
||||||
if ((vmcs12->vm_entry_controls & VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL) &&
|
if ((vmcs12->vm_entry_controls & VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL) &&
|
||||||
WARN_ON_ONCE(kvm_set_msr(vcpu, MSR_CORE_PERF_GLOBAL_CTRL,
|
WARN_ON_ONCE(kvm_set_msr(vcpu, MSR_CORE_PERF_GLOBAL_CTRL,
|
||||||
vmcs12->guest_ia32_perf_global_ctrl)))
|
vmcs12->guest_ia32_perf_global_ctrl))) {
|
||||||
|
*entry_failure_code = ENTRY_FAIL_DEFAULT;
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
kvm_rsp_write(vcpu, vmcs12->guest_rsp);
|
kvm_rsp_write(vcpu, vmcs12->guest_rsp);
|
||||||
kvm_rip_write(vcpu, vmcs12->guest_rip);
|
kvm_rip_write(vcpu, vmcs12->guest_rip);
|
||||||
|
|
|
@ -7525,6 +7525,7 @@ static void hardware_unsetup(void)
|
||||||
static bool vmx_check_apicv_inhibit_reasons(ulong bit)
|
static bool vmx_check_apicv_inhibit_reasons(ulong bit)
|
||||||
{
|
{
|
||||||
ulong supported = BIT(APICV_INHIBIT_REASON_DISABLE) |
|
ulong supported = BIT(APICV_INHIBIT_REASON_DISABLE) |
|
||||||
|
BIT(APICV_INHIBIT_REASON_ABSENT) |
|
||||||
BIT(APICV_INHIBIT_REASON_HYPERV) |
|
BIT(APICV_INHIBIT_REASON_HYPERV) |
|
||||||
BIT(APICV_INHIBIT_REASON_BLOCKIRQ);
|
BIT(APICV_INHIBIT_REASON_BLOCKIRQ);
|
||||||
|
|
||||||
|
|
|
@ -5740,6 +5740,7 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
|
||||||
smp_wmb();
|
smp_wmb();
|
||||||
kvm->arch.irqchip_mode = KVM_IRQCHIP_SPLIT;
|
kvm->arch.irqchip_mode = KVM_IRQCHIP_SPLIT;
|
||||||
kvm->arch.nr_reserved_ioapic_pins = cap->args[0];
|
kvm->arch.nr_reserved_ioapic_pins = cap->args[0];
|
||||||
|
kvm_request_apicv_update(kvm, true, APICV_INHIBIT_REASON_ABSENT);
|
||||||
r = 0;
|
r = 0;
|
||||||
split_irqchip_unlock:
|
split_irqchip_unlock:
|
||||||
mutex_unlock(&kvm->lock);
|
mutex_unlock(&kvm->lock);
|
||||||
|
@ -6120,6 +6121,7 @@ set_identity_unlock:
|
||||||
/* Write kvm->irq_routing before enabling irqchip_in_kernel. */
|
/* Write kvm->irq_routing before enabling irqchip_in_kernel. */
|
||||||
smp_wmb();
|
smp_wmb();
|
||||||
kvm->arch.irqchip_mode = KVM_IRQCHIP_KERNEL;
|
kvm->arch.irqchip_mode = KVM_IRQCHIP_KERNEL;
|
||||||
|
kvm_request_apicv_update(kvm, true, APICV_INHIBIT_REASON_ABSENT);
|
||||||
create_irqchip_unlock:
|
create_irqchip_unlock:
|
||||||
mutex_unlock(&kvm->lock);
|
mutex_unlock(&kvm->lock);
|
||||||
break;
|
break;
|
||||||
|
@ -8818,10 +8820,9 @@ static void kvm_apicv_init(struct kvm *kvm)
|
||||||
{
|
{
|
||||||
init_rwsem(&kvm->arch.apicv_update_lock);
|
init_rwsem(&kvm->arch.apicv_update_lock);
|
||||||
|
|
||||||
if (enable_apicv)
|
set_bit(APICV_INHIBIT_REASON_ABSENT,
|
||||||
clear_bit(APICV_INHIBIT_REASON_DISABLE,
|
|
||||||
&kvm->arch.apicv_inhibit_reasons);
|
&kvm->arch.apicv_inhibit_reasons);
|
||||||
else
|
if (!enable_apicv)
|
||||||
set_bit(APICV_INHIBIT_REASON_DISABLE,
|
set_bit(APICV_INHIBIT_REASON_DISABLE,
|
||||||
&kvm->arch.apicv_inhibit_reasons);
|
&kvm->arch.apicv_inhibit_reasons);
|
||||||
}
|
}
|
||||||
|
|
|
@ -277,7 +277,8 @@ void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
new = early_memremap(data.phys_map, data.size);
|
new = early_memremap_prot(data.phys_map, data.size,
|
||||||
|
pgprot_val(pgprot_encrypted(FIXMAP_PAGE_NORMAL)));
|
||||||
if (!new) {
|
if (!new) {
|
||||||
pr_err("Failed to map new boot services memmap\n");
|
pr_err("Failed to map new boot services memmap\n");
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -72,6 +72,7 @@ static void __init setup_real_mode(void)
|
||||||
#ifdef CONFIG_X86_64
|
#ifdef CONFIG_X86_64
|
||||||
u64 *trampoline_pgd;
|
u64 *trampoline_pgd;
|
||||||
u64 efer;
|
u64 efer;
|
||||||
|
int i;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
base = (unsigned char *)real_mode_header;
|
base = (unsigned char *)real_mode_header;
|
||||||
|
@ -128,8 +129,17 @@ static void __init setup_real_mode(void)
|
||||||
trampoline_header->flags = 0;
|
trampoline_header->flags = 0;
|
||||||
|
|
||||||
trampoline_pgd = (u64 *) __va(real_mode_header->trampoline_pgd);
|
trampoline_pgd = (u64 *) __va(real_mode_header->trampoline_pgd);
|
||||||
|
|
||||||
|
/* Map the real mode stub as virtual == physical */
|
||||||
trampoline_pgd[0] = trampoline_pgd_entry.pgd;
|
trampoline_pgd[0] = trampoline_pgd_entry.pgd;
|
||||||
trampoline_pgd[511] = init_top_pgt[511].pgd;
|
|
||||||
|
/*
|
||||||
|
* Include the entirety of the kernel mapping into the trampoline
|
||||||
|
* PGD. This way, all mappings present in the normal kernel page
|
||||||
|
* tables are usable while running on trampoline_pgd.
|
||||||
|
*/
|
||||||
|
for (i = pgd_index(__PAGE_OFFSET); i < PTRS_PER_PGD; i++)
|
||||||
|
trampoline_pgd[i] = init_top_pgt[i].pgd;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sme_sev_setup_real_mode(trampoline_header);
|
sme_sev_setup_real_mode(trampoline_header);
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/linkage.h>
|
#include <linux/linkage.h>
|
||||||
|
#include <../entry/calling.h>
|
||||||
|
|
||||||
.pushsection .noinstr.text, "ax"
|
.pushsection .noinstr.text, "ax"
|
||||||
/*
|
/*
|
||||||
|
@ -192,6 +193,25 @@ SYM_CODE_START(xen_iret)
|
||||||
jmp hypercall_iret
|
jmp hypercall_iret
|
||||||
SYM_CODE_END(xen_iret)
|
SYM_CODE_END(xen_iret)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XEN pv doesn't use trampoline stack, PER_CPU_VAR(cpu_tss_rw + TSS_sp0) is
|
||||||
|
* also the kernel stack. Reusing swapgs_restore_regs_and_return_to_usermode()
|
||||||
|
* in XEN pv would cause %rsp to move up to the top of the kernel stack and
|
||||||
|
* leave the IRET frame below %rsp, which is dangerous to be corrupted if #NMI
|
||||||
|
* interrupts. And swapgs_restore_regs_and_return_to_usermode() pushing the IRET
|
||||||
|
* frame at the same address is useless.
|
||||||
|
*/
|
||||||
|
SYM_CODE_START(xenpv_restore_regs_and_return_to_usermode)
|
||||||
|
UNWIND_HINT_REGS
|
||||||
|
POP_REGS
|
||||||
|
|
||||||
|
/* stackleak_erase() can work safely on the kernel stack. */
|
||||||
|
STACKLEAK_ERASE_NOCLOBBER
|
||||||
|
|
||||||
|
addq $8, %rsp /* skip regs->orig_ax */
|
||||||
|
jmp xen_iret
|
||||||
|
SYM_CODE_END(xenpv_restore_regs_and_return_to_usermode)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Xen handles syscall callbacks much like ordinary exceptions, which
|
* Xen handles syscall callbacks much like ordinary exceptions, which
|
||||||
* means we have:
|
* means we have:
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <linux/falloc.h>
|
#include <linux/falloc.h>
|
||||||
#include <linux/suspend.h>
|
#include <linux/suspend.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
|
#include <linux/module.h>
|
||||||
#include "blk.h"
|
#include "blk.h"
|
||||||
|
|
||||||
static inline struct inode *bdev_file_inode(struct file *file)
|
static inline struct inode *bdev_file_inode(struct file *file)
|
||||||
|
|
|
@ -827,7 +827,7 @@ static ssize_t ata_scsi_lpm_show(struct device *dev,
|
||||||
if (ap->target_lpm_policy >= ARRAY_SIZE(ata_lpm_policy_names))
|
if (ap->target_lpm_policy >= ARRAY_SIZE(ata_lpm_policy_names))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
return snprintf(buf, PAGE_SIZE, "%s\n",
|
return sysfs_emit(buf, "%s\n",
|
||||||
ata_lpm_policy_names[ap->target_lpm_policy]);
|
ata_lpm_policy_names[ap->target_lpm_policy]);
|
||||||
}
|
}
|
||||||
DEVICE_ATTR(link_power_management_policy, S_IRUGO | S_IWUSR,
|
DEVICE_ATTR(link_power_management_policy, S_IRUGO | S_IWUSR,
|
||||||
|
|
|
@ -55,14 +55,14 @@ static unsigned int pata_falcon_data_xfer(struct ata_queued_cmd *qc,
|
||||||
/* Transfer multiple of 2 bytes */
|
/* Transfer multiple of 2 bytes */
|
||||||
if (rw == READ) {
|
if (rw == READ) {
|
||||||
if (swap)
|
if (swap)
|
||||||
raw_insw_swapw((u16 *)data_addr, (u16 *)buf, words);
|
raw_insw_swapw(data_addr, (u16 *)buf, words);
|
||||||
else
|
else
|
||||||
raw_insw((u16 *)data_addr, (u16 *)buf, words);
|
raw_insw(data_addr, (u16 *)buf, words);
|
||||||
} else {
|
} else {
|
||||||
if (swap)
|
if (swap)
|
||||||
raw_outsw_swapw((u16 *)data_addr, (u16 *)buf, words);
|
raw_outsw_swapw(data_addr, (u16 *)buf, words);
|
||||||
else
|
else
|
||||||
raw_outsw((u16 *)data_addr, (u16 *)buf, words);
|
raw_outsw(data_addr, (u16 *)buf, words);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Transfer trailing byte, if any. */
|
/* Transfer trailing byte, if any. */
|
||||||
|
@ -74,16 +74,16 @@ static unsigned int pata_falcon_data_xfer(struct ata_queued_cmd *qc,
|
||||||
|
|
||||||
if (rw == READ) {
|
if (rw == READ) {
|
||||||
if (swap)
|
if (swap)
|
||||||
raw_insw_swapw((u16 *)data_addr, (u16 *)pad, 1);
|
raw_insw_swapw(data_addr, (u16 *)pad, 1);
|
||||||
else
|
else
|
||||||
raw_insw((u16 *)data_addr, (u16 *)pad, 1);
|
raw_insw(data_addr, (u16 *)pad, 1);
|
||||||
*buf = pad[0];
|
*buf = pad[0];
|
||||||
} else {
|
} else {
|
||||||
pad[0] = *buf;
|
pad[0] = *buf;
|
||||||
if (swap)
|
if (swap)
|
||||||
raw_outsw_swapw((u16 *)data_addr, (u16 *)pad, 1);
|
raw_outsw_swapw(data_addr, (u16 *)pad, 1);
|
||||||
else
|
else
|
||||||
raw_outsw((u16 *)data_addr, (u16 *)pad, 1);
|
raw_outsw(data_addr, (u16 *)pad, 1);
|
||||||
}
|
}
|
||||||
words++;
|
words++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1394,6 +1394,14 @@ static int sata_fsl_init_controller(struct ata_host *host)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sata_fsl_host_stop(struct ata_host *host)
|
||||||
|
{
|
||||||
|
struct sata_fsl_host_priv *host_priv = host->private_data;
|
||||||
|
|
||||||
|
iounmap(host_priv->hcr_base);
|
||||||
|
kfree(host_priv);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* scsi mid-layer and libata interface structures
|
* scsi mid-layer and libata interface structures
|
||||||
*/
|
*/
|
||||||
|
@ -1426,6 +1434,8 @@ static struct ata_port_operations sata_fsl_ops = {
|
||||||
.port_start = sata_fsl_port_start,
|
.port_start = sata_fsl_port_start,
|
||||||
.port_stop = sata_fsl_port_stop,
|
.port_stop = sata_fsl_port_stop,
|
||||||
|
|
||||||
|
.host_stop = sata_fsl_host_stop,
|
||||||
|
|
||||||
.pmp_attach = sata_fsl_pmp_attach,
|
.pmp_attach = sata_fsl_pmp_attach,
|
||||||
.pmp_detach = sata_fsl_pmp_detach,
|
.pmp_detach = sata_fsl_pmp_detach,
|
||||||
};
|
};
|
||||||
|
@ -1480,9 +1490,9 @@ static int sata_fsl_probe(struct platform_device *ofdev)
|
||||||
host_priv->ssr_base = ssr_base;
|
host_priv->ssr_base = ssr_base;
|
||||||
host_priv->csr_base = csr_base;
|
host_priv->csr_base = csr_base;
|
||||||
|
|
||||||
irq = irq_of_parse_and_map(ofdev->dev.of_node, 0);
|
irq = platform_get_irq(ofdev, 0);
|
||||||
if (!irq) {
|
if (irq < 0) {
|
||||||
dev_err(&ofdev->dev, "invalid irq from platform\n");
|
retval = irq;
|
||||||
goto error_exit_with_cleanup;
|
goto error_exit_with_cleanup;
|
||||||
}
|
}
|
||||||
host_priv->irq = irq;
|
host_priv->irq = irq;
|
||||||
|
@ -1557,10 +1567,6 @@ static int sata_fsl_remove(struct platform_device *ofdev)
|
||||||
|
|
||||||
ata_host_detach(host);
|
ata_host_detach(host);
|
||||||
|
|
||||||
irq_dispose_mapping(host_priv->irq);
|
|
||||||
iounmap(host_priv->hcr_base);
|
|
||||||
kfree(host_priv);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2103,7 +2103,7 @@ static int loop_control_remove(int idx)
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (idx < 0) {
|
if (idx < 0) {
|
||||||
pr_warn("deleting an unspecified loop device is not supported.\n");
|
pr_warn_once("deleting an unspecified loop device is not supported.\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -281,7 +281,7 @@ agp_ioc_init(void __iomem *ioc_regs)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int __init
|
||||||
lba_find_capability(int cap)
|
lba_find_capability(int cap)
|
||||||
{
|
{
|
||||||
struct _parisc_agp_info *info = &parisc_agp_info;
|
struct _parisc_agp_info *info = &parisc_agp_info;
|
||||||
|
@ -366,7 +366,7 @@ fail:
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int __init
|
||||||
find_quicksilver(struct device *dev, void *data)
|
find_quicksilver(struct device *dev, void *data)
|
||||||
{
|
{
|
||||||
struct parisc_device **lba = data;
|
struct parisc_device **lba = data;
|
||||||
|
@ -378,7 +378,7 @@ find_quicksilver(struct device *dev, void *data)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int __init
|
||||||
parisc_agp_init(void)
|
parisc_agp_init(void)
|
||||||
{
|
{
|
||||||
extern struct sba_device *sba_list;
|
extern struct sba_device *sba_list;
|
||||||
|
|
|
@ -1004,10 +1004,9 @@ static struct kobj_type ktype_cpufreq = {
|
||||||
.release = cpufreq_sysfs_release,
|
.release = cpufreq_sysfs_release,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void add_cpu_dev_symlink(struct cpufreq_policy *policy, unsigned int cpu)
|
static void add_cpu_dev_symlink(struct cpufreq_policy *policy, unsigned int cpu,
|
||||||
|
struct device *dev)
|
||||||
{
|
{
|
||||||
struct device *dev = get_cpu_device(cpu);
|
|
||||||
|
|
||||||
if (unlikely(!dev))
|
if (unlikely(!dev))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1296,8 +1295,9 @@ static void cpufreq_policy_free(struct cpufreq_policy *policy)
|
||||||
|
|
||||||
if (policy->max_freq_req) {
|
if (policy->max_freq_req) {
|
||||||
/*
|
/*
|
||||||
* CPUFREQ_CREATE_POLICY notification is sent only after
|
* Remove max_freq_req after sending CPUFREQ_REMOVE_POLICY
|
||||||
* successfully adding max_freq_req request.
|
* notification, since CPUFREQ_CREATE_POLICY notification was
|
||||||
|
* sent after adding max_freq_req earlier.
|
||||||
*/
|
*/
|
||||||
blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
|
blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
|
||||||
CPUFREQ_REMOVE_POLICY, policy);
|
CPUFREQ_REMOVE_POLICY, policy);
|
||||||
|
@ -1391,7 +1391,7 @@ static int cpufreq_online(unsigned int cpu)
|
||||||
if (new_policy) {
|
if (new_policy) {
|
||||||
for_each_cpu(j, policy->related_cpus) {
|
for_each_cpu(j, policy->related_cpus) {
|
||||||
per_cpu(cpufreq_cpu_data, j) = policy;
|
per_cpu(cpufreq_cpu_data, j) = policy;
|
||||||
add_cpu_dev_symlink(policy, j);
|
add_cpu_dev_symlink(policy, j, get_cpu_device(j));
|
||||||
}
|
}
|
||||||
|
|
||||||
policy->min_freq_req = kzalloc(2 * sizeof(*policy->min_freq_req),
|
policy->min_freq_req = kzalloc(2 * sizeof(*policy->min_freq_req),
|
||||||
|
@ -1565,7 +1565,7 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
|
||||||
/* Create sysfs link on CPU registration */
|
/* Create sysfs link on CPU registration */
|
||||||
policy = per_cpu(cpufreq_cpu_data, cpu);
|
policy = per_cpu(cpufreq_cpu_data, cpu);
|
||||||
if (policy)
|
if (policy)
|
||||||
add_cpu_dev_symlink(policy, cpu);
|
add_cpu_dev_symlink(policy, cpu, dev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -290,7 +290,7 @@ static void system_heap_dma_buf_release(struct dma_buf *dmabuf)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
table = &buffer->sg_table;
|
table = &buffer->sg_table;
|
||||||
for_each_sg(table->sgl, sg, table->nents, i) {
|
for_each_sgtable_sg(table, sg, i) {
|
||||||
struct page *page = sg_page(sg);
|
struct page *page = sg_page(sg);
|
||||||
|
|
||||||
__free_pages(page, compound_order(page));
|
__free_pages(page, compound_order(page));
|
||||||
|
|
|
@ -1396,7 +1396,7 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
|
||||||
struct sg_table *sg = NULL;
|
struct sg_table *sg = NULL;
|
||||||
uint64_t user_addr = 0;
|
uint64_t user_addr = 0;
|
||||||
struct amdgpu_bo *bo;
|
struct amdgpu_bo *bo;
|
||||||
struct drm_gem_object *gobj;
|
struct drm_gem_object *gobj = NULL;
|
||||||
u32 domain, alloc_domain;
|
u32 domain, alloc_domain;
|
||||||
u64 alloc_flags;
|
u64 alloc_flags;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -1506,13 +1506,15 @@ allocate_init_user_pages_failed:
|
||||||
remove_kgd_mem_from_kfd_bo_list(*mem, avm->process_info);
|
remove_kgd_mem_from_kfd_bo_list(*mem, avm->process_info);
|
||||||
drm_vma_node_revoke(&gobj->vma_node, drm_priv);
|
drm_vma_node_revoke(&gobj->vma_node, drm_priv);
|
||||||
err_node_allow:
|
err_node_allow:
|
||||||
drm_gem_object_put(gobj);
|
|
||||||
/* Don't unreserve system mem limit twice */
|
/* Don't unreserve system mem limit twice */
|
||||||
goto err_reserve_limit;
|
goto err_reserve_limit;
|
||||||
err_bo_create:
|
err_bo_create:
|
||||||
unreserve_mem_limit(adev, size, alloc_domain, !!sg);
|
unreserve_mem_limit(adev, size, alloc_domain, !!sg);
|
||||||
err_reserve_limit:
|
err_reserve_limit:
|
||||||
mutex_destroy(&(*mem)->lock);
|
mutex_destroy(&(*mem)->lock);
|
||||||
|
if (gobj)
|
||||||
|
drm_gem_object_put(gobj);
|
||||||
|
else
|
||||||
kfree(*mem);
|
kfree(*mem);
|
||||||
err:
|
err:
|
||||||
if (sg) {
|
if (sg) {
|
||||||
|
|
|
@ -3833,7 +3833,7 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev)
|
||||||
/* disable all interrupts */
|
/* disable all interrupts */
|
||||||
amdgpu_irq_disable_all(adev);
|
amdgpu_irq_disable_all(adev);
|
||||||
if (adev->mode_info.mode_config_initialized){
|
if (adev->mode_info.mode_config_initialized){
|
||||||
if (!amdgpu_device_has_dc_support(adev))
|
if (!drm_drv_uses_atomic_modeset(adev_to_drm(adev)))
|
||||||
drm_helper_force_disable_all(adev_to_drm(adev));
|
drm_helper_force_disable_all(adev_to_drm(adev));
|
||||||
else
|
else
|
||||||
drm_atomic_helper_shutdown(adev_to_drm(adev));
|
drm_atomic_helper_shutdown(adev_to_drm(adev));
|
||||||
|
@ -4289,6 +4289,8 @@ static int amdgpu_device_reset_sriov(struct amdgpu_device *adev,
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
amdgpu_amdkfd_pre_reset(adev);
|
||||||
|
|
||||||
if (from_hypervisor)
|
if (from_hypervisor)
|
||||||
r = amdgpu_virt_request_full_gpu(adev, true);
|
r = amdgpu_virt_request_full_gpu(adev, true);
|
||||||
else
|
else
|
||||||
|
@ -4316,6 +4318,7 @@ static int amdgpu_device_reset_sriov(struct amdgpu_device *adev,
|
||||||
|
|
||||||
amdgpu_irq_gpu_reset_resume_helper(adev);
|
amdgpu_irq_gpu_reset_resume_helper(adev);
|
||||||
r = amdgpu_ib_ring_tests(adev);
|
r = amdgpu_ib_ring_tests(adev);
|
||||||
|
amdgpu_amdkfd_post_reset(adev);
|
||||||
|
|
||||||
error:
|
error:
|
||||||
if (!r && adev->virt.gim_feature & AMDGIM_FEATURE_GIM_FLR_VRAMLOST) {
|
if (!r && adev->virt.gim_feature & AMDGIM_FEATURE_GIM_FLR_VRAMLOST) {
|
||||||
|
@ -5030,6 +5033,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
||||||
|
|
||||||
cancel_delayed_work_sync(&tmp_adev->delayed_init_work);
|
cancel_delayed_work_sync(&tmp_adev->delayed_init_work);
|
||||||
|
|
||||||
|
if (!amdgpu_sriov_vf(tmp_adev))
|
||||||
amdgpu_amdkfd_pre_reset(tmp_adev);
|
amdgpu_amdkfd_pre_reset(tmp_adev);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -5129,7 +5133,7 @@ skip_hw_reset:
|
||||||
drm_sched_start(&ring->sched, !tmp_adev->asic_reset_res);
|
drm_sched_start(&ring->sched, !tmp_adev->asic_reset_res);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!amdgpu_device_has_dc_support(tmp_adev) && !job_signaled) {
|
if (!drm_drv_uses_atomic_modeset(adev_to_drm(tmp_adev)) && !job_signaled) {
|
||||||
drm_helper_resume_force_mode(adev_to_drm(tmp_adev));
|
drm_helper_resume_force_mode(adev_to_drm(tmp_adev));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5148,8 +5152,8 @@ skip_hw_reset:
|
||||||
|
|
||||||
skip_sched_resume:
|
skip_sched_resume:
|
||||||
list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
|
list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
|
||||||
/* unlock kfd */
|
/* unlock kfd: SRIOV would do it separately */
|
||||||
if (!need_emergency_restart)
|
if (!need_emergency_restart && !amdgpu_sriov_vf(tmp_adev))
|
||||||
amdgpu_amdkfd_post_reset(tmp_adev);
|
amdgpu_amdkfd_post_reset(tmp_adev);
|
||||||
|
|
||||||
/* kfd_post_reset will do nothing if kfd device is not initialized,
|
/* kfd_post_reset will do nothing if kfd device is not initialized,
|
||||||
|
|
|
@ -157,6 +157,8 @@ static int hw_id_map[MAX_HWIP] = {
|
||||||
[HDP_HWIP] = HDP_HWID,
|
[HDP_HWIP] = HDP_HWID,
|
||||||
[SDMA0_HWIP] = SDMA0_HWID,
|
[SDMA0_HWIP] = SDMA0_HWID,
|
||||||
[SDMA1_HWIP] = SDMA1_HWID,
|
[SDMA1_HWIP] = SDMA1_HWID,
|
||||||
|
[SDMA2_HWIP] = SDMA2_HWID,
|
||||||
|
[SDMA3_HWIP] = SDMA3_HWID,
|
||||||
[MMHUB_HWIP] = MMHUB_HWID,
|
[MMHUB_HWIP] = MMHUB_HWID,
|
||||||
[ATHUB_HWIP] = ATHUB_HWID,
|
[ATHUB_HWIP] = ATHUB_HWID,
|
||||||
[NBIO_HWIP] = NBIF_HWID,
|
[NBIO_HWIP] = NBIF_HWID,
|
||||||
|
@ -918,6 +920,7 @@ static int amdgpu_discovery_set_mm_ip_blocks(struct amdgpu_device *adev)
|
||||||
case IP_VERSION(3, 0, 64):
|
case IP_VERSION(3, 0, 64):
|
||||||
case IP_VERSION(3, 1, 1):
|
case IP_VERSION(3, 1, 1):
|
||||||
case IP_VERSION(3, 0, 2):
|
case IP_VERSION(3, 0, 2):
|
||||||
|
case IP_VERSION(3, 0, 192):
|
||||||
amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block);
|
amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block);
|
||||||
if (!amdgpu_sriov_vf(adev))
|
if (!amdgpu_sriov_vf(adev))
|
||||||
amdgpu_device_ip_block_add(adev, &jpeg_v3_0_ip_block);
|
amdgpu_device_ip_block_add(adev, &jpeg_v3_0_ip_block);
|
||||||
|
|
|
@ -135,6 +135,7 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
|
||||||
break;
|
break;
|
||||||
case IP_VERSION(3, 0, 0):
|
case IP_VERSION(3, 0, 0):
|
||||||
case IP_VERSION(3, 0, 64):
|
case IP_VERSION(3, 0, 64):
|
||||||
|
case IP_VERSION(3, 0, 192):
|
||||||
if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 0))
|
if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 0))
|
||||||
fw_name = FIRMWARE_SIENNA_CICHLID;
|
fw_name = FIRMWARE_SIENNA_CICHLID;
|
||||||
else
|
else
|
||||||
|
|
|
@ -504,8 +504,8 @@ static int amdgpu_vkms_sw_fini(void *handle)
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
for (i = 0; i < adev->mode_info.num_crtc; i++)
|
for (i = 0; i < adev->mode_info.num_crtc; i++)
|
||||||
if (adev->mode_info.crtcs[i])
|
if (adev->amdgpu_vkms_output[i].vblank_hrtimer.function)
|
||||||
hrtimer_cancel(&adev->mode_info.crtcs[i]->vblank_timer);
|
hrtimer_cancel(&adev->amdgpu_vkms_output[i].vblank_hrtimer);
|
||||||
|
|
||||||
kfree(adev->mode_info.bios_hardcoded_edid);
|
kfree(adev->mode_info.bios_hardcoded_edid);
|
||||||
kfree(adev->amdgpu_vkms_output);
|
kfree(adev->amdgpu_vkms_output);
|
||||||
|
|
|
@ -4060,9 +4060,10 @@ static int gfx_v9_0_hw_fini(void *handle)
|
||||||
|
|
||||||
gfx_v9_0_cp_enable(adev, false);
|
gfx_v9_0_cp_enable(adev, false);
|
||||||
|
|
||||||
/* Skip suspend with A+A reset */
|
/* Skip stopping RLC with A+A reset or when RLC controls GFX clock */
|
||||||
if (adev->gmc.xgmi.connected_to_cpu && amdgpu_in_reset(adev)) {
|
if ((adev->gmc.xgmi.connected_to_cpu && amdgpu_in_reset(adev)) ||
|
||||||
dev_dbg(adev->dev, "Device in reset. Skipping RLC halt\n");
|
(adev->ip_versions[GC_HWIP][0] >= IP_VERSION(9, 4, 2))) {
|
||||||
|
dev_dbg(adev->dev, "Skipping RLC halt\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -183,6 +183,7 @@ static int nv_query_video_codecs(struct amdgpu_device *adev, bool encode,
|
||||||
switch (adev->ip_versions[UVD_HWIP][0]) {
|
switch (adev->ip_versions[UVD_HWIP][0]) {
|
||||||
case IP_VERSION(3, 0, 0):
|
case IP_VERSION(3, 0, 0):
|
||||||
case IP_VERSION(3, 0, 64):
|
case IP_VERSION(3, 0, 64):
|
||||||
|
case IP_VERSION(3, 0, 192):
|
||||||
if (amdgpu_sriov_vf(adev)) {
|
if (amdgpu_sriov_vf(adev)) {
|
||||||
if (encode)
|
if (encode)
|
||||||
*codecs = &sriov_sc_video_codecs_encode;
|
*codecs = &sriov_sc_video_codecs_encode;
|
||||||
|
|
|
@ -1574,7 +1574,6 @@ retry_flush_work:
|
||||||
static void svm_range_restore_work(struct work_struct *work)
|
static void svm_range_restore_work(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct delayed_work *dwork = to_delayed_work(work);
|
struct delayed_work *dwork = to_delayed_work(work);
|
||||||
struct amdkfd_process_info *process_info;
|
|
||||||
struct svm_range_list *svms;
|
struct svm_range_list *svms;
|
||||||
struct svm_range *prange;
|
struct svm_range *prange;
|
||||||
struct kfd_process *p;
|
struct kfd_process *p;
|
||||||
|
@ -1594,12 +1593,10 @@ static void svm_range_restore_work(struct work_struct *work)
|
||||||
* the lifetime of this thread, kfd_process and mm will be valid.
|
* the lifetime of this thread, kfd_process and mm will be valid.
|
||||||
*/
|
*/
|
||||||
p = container_of(svms, struct kfd_process, svms);
|
p = container_of(svms, struct kfd_process, svms);
|
||||||
process_info = p->kgd_process_info;
|
|
||||||
mm = p->mm;
|
mm = p->mm;
|
||||||
if (!mm)
|
if (!mm)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mutex_lock(&process_info->lock);
|
|
||||||
svm_range_list_lock_and_flush_work(svms, mm);
|
svm_range_list_lock_and_flush_work(svms, mm);
|
||||||
mutex_lock(&svms->lock);
|
mutex_lock(&svms->lock);
|
||||||
|
|
||||||
|
@ -1652,7 +1649,6 @@ static void svm_range_restore_work(struct work_struct *work)
|
||||||
out_reschedule:
|
out_reschedule:
|
||||||
mutex_unlock(&svms->lock);
|
mutex_unlock(&svms->lock);
|
||||||
mmap_write_unlock(mm);
|
mmap_write_unlock(mm);
|
||||||
mutex_unlock(&process_info->lock);
|
|
||||||
|
|
||||||
/* If validation failed, reschedule another attempt */
|
/* If validation failed, reschedule another attempt */
|
||||||
if (evicted_ranges) {
|
if (evicted_ranges) {
|
||||||
|
@ -2614,6 +2610,7 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid,
|
||||||
|
|
||||||
if (atomic_read(&svms->drain_pagefaults)) {
|
if (atomic_read(&svms->drain_pagefaults)) {
|
||||||
pr_debug("draining retry fault, drop fault 0x%llx\n", addr);
|
pr_debug("draining retry fault, drop fault 0x%llx\n", addr);
|
||||||
|
r = 0;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2623,6 +2620,7 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid,
|
||||||
mm = get_task_mm(p->lead_thread);
|
mm = get_task_mm(p->lead_thread);
|
||||||
if (!mm) {
|
if (!mm) {
|
||||||
pr_debug("svms 0x%p failed to get mm\n", svms);
|
pr_debug("svms 0x%p failed to get mm\n", svms);
|
||||||
|
r = 0;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2660,6 +2658,7 @@ retry_write_locked:
|
||||||
|
|
||||||
if (svm_range_skip_recover(prange)) {
|
if (svm_range_skip_recover(prange)) {
|
||||||
amdgpu_gmc_filter_faults_remove(adev, addr, pasid);
|
amdgpu_gmc_filter_faults_remove(adev, addr, pasid);
|
||||||
|
r = 0;
|
||||||
goto out_unlock_range;
|
goto out_unlock_range;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2668,6 +2667,7 @@ retry_write_locked:
|
||||||
if (timestamp < AMDGPU_SVM_RANGE_RETRY_FAULT_PENDING) {
|
if (timestamp < AMDGPU_SVM_RANGE_RETRY_FAULT_PENDING) {
|
||||||
pr_debug("svms 0x%p [0x%lx %lx] already restored\n",
|
pr_debug("svms 0x%p [0x%lx %lx] already restored\n",
|
||||||
svms, prange->start, prange->last);
|
svms, prange->start, prange->last);
|
||||||
|
r = 0;
|
||||||
goto out_unlock_range;
|
goto out_unlock_range;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3177,7 +3177,6 @@ static int
|
||||||
svm_range_set_attr(struct kfd_process *p, uint64_t start, uint64_t size,
|
svm_range_set_attr(struct kfd_process *p, uint64_t start, uint64_t size,
|
||||||
uint32_t nattr, struct kfd_ioctl_svm_attribute *attrs)
|
uint32_t nattr, struct kfd_ioctl_svm_attribute *attrs)
|
||||||
{
|
{
|
||||||
struct amdkfd_process_info *process_info = p->kgd_process_info;
|
|
||||||
struct mm_struct *mm = current->mm;
|
struct mm_struct *mm = current->mm;
|
||||||
struct list_head update_list;
|
struct list_head update_list;
|
||||||
struct list_head insert_list;
|
struct list_head insert_list;
|
||||||
|
@ -3196,8 +3195,6 @@ svm_range_set_attr(struct kfd_process *p, uint64_t start, uint64_t size,
|
||||||
|
|
||||||
svms = &p->svms;
|
svms = &p->svms;
|
||||||
|
|
||||||
mutex_lock(&process_info->lock);
|
|
||||||
|
|
||||||
svm_range_list_lock_and_flush_work(svms, mm);
|
svm_range_list_lock_and_flush_work(svms, mm);
|
||||||
|
|
||||||
r = svm_range_is_valid(p, start, size);
|
r = svm_range_is_valid(p, start, size);
|
||||||
|
@ -3273,8 +3270,6 @@ out_unlock_range:
|
||||||
mutex_unlock(&svms->lock);
|
mutex_unlock(&svms->lock);
|
||||||
mmap_read_unlock(mm);
|
mmap_read_unlock(mm);
|
||||||
out:
|
out:
|
||||||
mutex_unlock(&process_info->lock);
|
|
||||||
|
|
||||||
pr_debug("pasid 0x%x svms 0x%p [0x%llx 0x%llx] done, r=%d\n", p->pasid,
|
pr_debug("pasid 0x%x svms 0x%p [0x%llx 0x%llx] done, r=%d\n", p->pasid,
|
||||||
&p->svms, start, start + size - 1, r);
|
&p->svms, start, start + size - 1, r);
|
||||||
|
|
||||||
|
|
|
@ -314,6 +314,14 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name)
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((aconn->base.connector_type != DRM_MODE_CONNECTOR_DisplayPort) &&
|
||||||
|
(aconn->base.connector_type != DRM_MODE_CONNECTOR_eDP)) {
|
||||||
|
DRM_DEBUG_DRIVER("No DP connector available for CRC source\n");
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
|
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
|
||||||
|
|
|
@ -36,6 +36,8 @@
|
||||||
#include "dm_helpers.h"
|
#include "dm_helpers.h"
|
||||||
|
|
||||||
#include "dc_link_ddc.h"
|
#include "dc_link_ddc.h"
|
||||||
|
#include "ddc_service_types.h"
|
||||||
|
#include "dpcd_defs.h"
|
||||||
|
|
||||||
#include "i2caux_interface.h"
|
#include "i2caux_interface.h"
|
||||||
#include "dmub_cmd.h"
|
#include "dmub_cmd.h"
|
||||||
|
@ -157,6 +159,16 @@ static const struct drm_connector_funcs dm_dp_mst_connector_funcs = {
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||||
|
static bool needs_dsc_aux_workaround(struct dc_link *link)
|
||||||
|
{
|
||||||
|
if (link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_90CC24 &&
|
||||||
|
(link->dpcd_caps.dpcd_rev.raw == DPCD_REV_14 || link->dpcd_caps.dpcd_rev.raw == DPCD_REV_12) &&
|
||||||
|
link->dpcd_caps.sink_count.bits.SINK_COUNT >= 2)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnector)
|
static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnector)
|
||||||
{
|
{
|
||||||
struct dc_sink *dc_sink = aconnector->dc_sink;
|
struct dc_sink *dc_sink = aconnector->dc_sink;
|
||||||
|
@ -166,7 +178,7 @@ static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnecto
|
||||||
u8 *dsc_branch_dec_caps = NULL;
|
u8 *dsc_branch_dec_caps = NULL;
|
||||||
|
|
||||||
aconnector->dsc_aux = drm_dp_mst_dsc_aux_for_port(port);
|
aconnector->dsc_aux = drm_dp_mst_dsc_aux_for_port(port);
|
||||||
#if defined(CONFIG_HP_HOOK_WORKAROUND)
|
|
||||||
/*
|
/*
|
||||||
* drm_dp_mst_dsc_aux_for_port() will return NULL for certain configs
|
* drm_dp_mst_dsc_aux_for_port() will return NULL for certain configs
|
||||||
* because it only check the dsc/fec caps of the "port variable" and not the dock
|
* because it only check the dsc/fec caps of the "port variable" and not the dock
|
||||||
|
@ -176,10 +188,10 @@ static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnecto
|
||||||
* Workaround: explicitly check the use case above and use the mst dock's aux as dsc_aux
|
* Workaround: explicitly check the use case above and use the mst dock's aux as dsc_aux
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
if (!aconnector->dsc_aux && !port->parent->port_parent &&
|
||||||
if (!aconnector->dsc_aux && !port->parent->port_parent)
|
needs_dsc_aux_workaround(aconnector->dc_link))
|
||||||
aconnector->dsc_aux = &aconnector->mst_port->dm_dp_aux.aux;
|
aconnector->dsc_aux = &aconnector->mst_port->dm_dp_aux.aux;
|
||||||
#endif
|
|
||||||
if (!aconnector->dsc_aux)
|
if (!aconnector->dsc_aux)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -758,6 +758,18 @@ static bool detect_dp(struct dc_link *link,
|
||||||
dal_ddc_service_set_transaction_type(link->ddc,
|
dal_ddc_service_set_transaction_type(link->ddc,
|
||||||
sink_caps->transaction_type);
|
sink_caps->transaction_type);
|
||||||
|
|
||||||
|
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||||
|
/* Apply work around for tunneled MST on certain USB4 docks. Always use DSC if dock
|
||||||
|
* reports DSC support.
|
||||||
|
*/
|
||||||
|
if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA &&
|
||||||
|
link->type == dc_connection_mst_branch &&
|
||||||
|
link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_90CC24 &&
|
||||||
|
link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT &&
|
||||||
|
!link->dc->debug.dpia_debug.bits.disable_mst_dsc_work_around)
|
||||||
|
link->wa_flags.dpia_mst_dsc_always_on = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_DRM_AMD_DC_HDCP)
|
#if defined(CONFIG_DRM_AMD_DC_HDCP)
|
||||||
/* In case of fallback to SST when topology discovery below fails
|
/* In case of fallback to SST when topology discovery below fails
|
||||||
* HDCP caps will be querried again later by the upper layer (caller
|
* HDCP caps will be querried again later by the upper layer (caller
|
||||||
|
@ -1203,6 +1215,10 @@ static bool dc_link_detect_helper(struct dc_link *link,
|
||||||
LINK_INFO("link=%d, mst branch is now Disconnected\n",
|
LINK_INFO("link=%d, mst branch is now Disconnected\n",
|
||||||
link->link_index);
|
link->link_index);
|
||||||
|
|
||||||
|
/* Disable work around which keeps DSC on for tunneled MST on certain USB4 docks. */
|
||||||
|
if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
|
||||||
|
link->wa_flags.dpia_mst_dsc_always_on = false;
|
||||||
|
|
||||||
dm_helpers_dp_mst_stop_top_mgr(link->ctx, link);
|
dm_helpers_dp_mst_stop_top_mgr(link->ctx, link);
|
||||||
|
|
||||||
link->mst_stream_alloc_table.stream_count = 0;
|
link->mst_stream_alloc_table.stream_count = 0;
|
||||||
|
|
|
@ -2138,7 +2138,7 @@ static enum link_training_result dp_perform_8b_10b_link_training(
|
||||||
}
|
}
|
||||||
|
|
||||||
for (lane = 0; lane < (uint8_t)lt_settings->link_settings.lane_count; lane++)
|
for (lane = 0; lane < (uint8_t)lt_settings->link_settings.lane_count; lane++)
|
||||||
lt_settings->dpcd_lane_settings[lane].bits.VOLTAGE_SWING_SET = VOLTAGE_SWING_LEVEL0;
|
lt_settings->dpcd_lane_settings[lane].raw = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status == LINK_TRAINING_SUCCESS) {
|
if (status == LINK_TRAINING_SUCCESS) {
|
||||||
|
|
|
@ -1664,6 +1664,10 @@ bool dc_is_stream_unchanged(
|
||||||
if (old_stream->ignore_msa_timing_param != stream->ignore_msa_timing_param)
|
if (old_stream->ignore_msa_timing_param != stream->ignore_msa_timing_param)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Only Have Audio left to check whether it is same or not. This is a corner case for Tiled sinks
|
||||||
|
if (old_stream->audio_info.mode_count != stream->audio_info.mode_count)
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2252,16 +2256,6 @@ enum dc_status dc_validate_global_state(
|
||||||
|
|
||||||
if (!new_ctx)
|
if (!new_ctx)
|
||||||
return DC_ERROR_UNEXPECTED;
|
return DC_ERROR_UNEXPECTED;
|
||||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Update link encoder to stream assignment.
|
|
||||||
* TODO: Split out reason allocation from validation.
|
|
||||||
*/
|
|
||||||
if (dc->res_pool->funcs->link_encs_assign && fast_validate == false)
|
|
||||||
dc->res_pool->funcs->link_encs_assign(
|
|
||||||
dc, new_ctx, new_ctx->streams, new_ctx->stream_count);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (dc->res_pool->funcs->validate_global) {
|
if (dc->res_pool->funcs->validate_global) {
|
||||||
result = dc->res_pool->funcs->validate_global(dc, new_ctx);
|
result = dc->res_pool->funcs->validate_global(dc, new_ctx);
|
||||||
|
@ -2313,6 +2307,16 @@ enum dc_status dc_validate_global_state(
|
||||||
if (!dc->res_pool->funcs->validate_bandwidth(dc, new_ctx, fast_validate))
|
if (!dc->res_pool->funcs->validate_bandwidth(dc, new_ctx, fast_validate))
|
||||||
result = DC_FAIL_BANDWIDTH_VALIDATE;
|
result = DC_FAIL_BANDWIDTH_VALIDATE;
|
||||||
|
|
||||||
|
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||||
|
/*
|
||||||
|
* Only update link encoder to stream assignment after bandwidth validation passed.
|
||||||
|
* TODO: Split out assignment and validation.
|
||||||
|
*/
|
||||||
|
if (result == DC_OK && dc->res_pool->funcs->link_encs_assign && fast_validate == false)
|
||||||
|
dc->res_pool->funcs->link_encs_assign(
|
||||||
|
dc, new_ctx, new_ctx->streams, new_ctx->stream_count);
|
||||||
|
#endif
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -508,7 +508,8 @@ union dpia_debug_options {
|
||||||
uint32_t disable_dpia:1;
|
uint32_t disable_dpia:1;
|
||||||
uint32_t force_non_lttpr:1;
|
uint32_t force_non_lttpr:1;
|
||||||
uint32_t extend_aux_rd_interval:1;
|
uint32_t extend_aux_rd_interval:1;
|
||||||
uint32_t reserved:29;
|
uint32_t disable_mst_dsc_work_around:1;
|
||||||
|
uint32_t reserved:28;
|
||||||
} bits;
|
} bits;
|
||||||
uint32_t raw;
|
uint32_t raw;
|
||||||
};
|
};
|
||||||
|
|
|
@ -191,6 +191,8 @@ struct dc_link {
|
||||||
bool dp_skip_DID2;
|
bool dp_skip_DID2;
|
||||||
bool dp_skip_reset_segment;
|
bool dp_skip_reset_segment;
|
||||||
bool dp_mot_reset_segment;
|
bool dp_mot_reset_segment;
|
||||||
|
/* Some USB4 docks do not handle turning off MST DSC once it has been enabled. */
|
||||||
|
bool dpia_mst_dsc_always_on;
|
||||||
} wa_flags;
|
} wa_flags;
|
||||||
struct link_mst_stream_allocation_table mst_stream_alloc_table;
|
struct link_mst_stream_allocation_table mst_stream_alloc_table;
|
||||||
|
|
||||||
|
|
|
@ -1468,7 +1468,7 @@ static int smu_disable_dpms(struct smu_context *smu)
|
||||||
dev_err(adev->dev, "Failed to disable smu features.\n");
|
dev_err(adev->dev, "Failed to disable smu features.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(10, 0, 0) &&
|
if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(9, 4, 2) &&
|
||||||
adev->gfx.rlc.funcs->stop)
|
adev->gfx.rlc.funcs->stop)
|
||||||
adev->gfx.rlc.funcs->stop(adev);
|
adev->gfx.rlc.funcs->stop(adev);
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <linux/shmem_fs.h>
|
#include <linux/shmem_fs.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/vmalloc.h>
|
#include <linux/vmalloc.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
|
||||||
#ifdef CONFIG_X86
|
#ifdef CONFIG_X86
|
||||||
#include <asm/set_memory.h>
|
#include <asm/set_memory.h>
|
||||||
|
|
|
@ -1640,6 +1640,9 @@ struct intel_dp {
|
||||||
struct intel_dp_pcon_frl frl;
|
struct intel_dp_pcon_frl frl;
|
||||||
|
|
||||||
struct intel_psr psr;
|
struct intel_psr psr;
|
||||||
|
|
||||||
|
/* When we last wrote the OUI for eDP */
|
||||||
|
unsigned long last_oui_write;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum lspcon_vendor {
|
enum lspcon_vendor {
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <linux/notifier.h>
|
#include <linux/notifier.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
#include <linux/timekeeping.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
#include <asm/byteorder.h>
|
#include <asm/byteorder.h>
|
||||||
|
@ -1955,6 +1956,16 @@ intel_edp_init_source_oui(struct intel_dp *intel_dp, bool careful)
|
||||||
|
|
||||||
if (drm_dp_dpcd_write(&intel_dp->aux, DP_SOURCE_OUI, oui, sizeof(oui)) < 0)
|
if (drm_dp_dpcd_write(&intel_dp->aux, DP_SOURCE_OUI, oui, sizeof(oui)) < 0)
|
||||||
drm_err(&i915->drm, "Failed to write source OUI\n");
|
drm_err(&i915->drm, "Failed to write source OUI\n");
|
||||||
|
|
||||||
|
intel_dp->last_oui_write = jiffies;
|
||||||
|
}
|
||||||
|
|
||||||
|
void intel_dp_wait_source_oui(struct intel_dp *intel_dp)
|
||||||
|
{
|
||||||
|
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
|
||||||
|
|
||||||
|
drm_dbg_kms(&i915->drm, "Performing OUI wait\n");
|
||||||
|
wait_remaining_ms_from_jiffies(intel_dp->last_oui_write, 30);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the device supports it, try to set the power state appropriately */
|
/* If the device supports it, try to set the power state appropriately */
|
||||||
|
|
|
@ -119,4 +119,6 @@ void intel_dp_pcon_dsc_configure(struct intel_dp *intel_dp,
|
||||||
const struct intel_crtc_state *crtc_state);
|
const struct intel_crtc_state *crtc_state);
|
||||||
void intel_dp_phy_test(struct intel_encoder *encoder);
|
void intel_dp_phy_test(struct intel_encoder *encoder);
|
||||||
|
|
||||||
|
void intel_dp_wait_source_oui(struct intel_dp *intel_dp);
|
||||||
|
|
||||||
#endif /* __INTEL_DP_H__ */
|
#endif /* __INTEL_DP_H__ */
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
|
|
||||||
#include "intel_backlight.h"
|
#include "intel_backlight.h"
|
||||||
#include "intel_display_types.h"
|
#include "intel_display_types.h"
|
||||||
|
#include "intel_dp.h"
|
||||||
#include "intel_dp_aux_backlight.h"
|
#include "intel_dp_aux_backlight.h"
|
||||||
|
|
||||||
/* TODO:
|
/* TODO:
|
||||||
|
@ -106,6 +107,8 @@ intel_dp_aux_supports_hdr_backlight(struct intel_connector *connector)
|
||||||
int ret;
|
int ret;
|
||||||
u8 tcon_cap[4];
|
u8 tcon_cap[4];
|
||||||
|
|
||||||
|
intel_dp_wait_source_oui(intel_dp);
|
||||||
|
|
||||||
ret = drm_dp_dpcd_read(aux, INTEL_EDP_HDR_TCON_CAP0, tcon_cap, sizeof(tcon_cap));
|
ret = drm_dp_dpcd_read(aux, INTEL_EDP_HDR_TCON_CAP0, tcon_cap, sizeof(tcon_cap));
|
||||||
if (ret != sizeof(tcon_cap))
|
if (ret != sizeof(tcon_cap))
|
||||||
return false;
|
return false;
|
||||||
|
@ -204,6 +207,8 @@ intel_dp_aux_hdr_enable_backlight(const struct intel_crtc_state *crtc_state,
|
||||||
int ret;
|
int ret;
|
||||||
u8 old_ctrl, ctrl;
|
u8 old_ctrl, ctrl;
|
||||||
|
|
||||||
|
intel_dp_wait_source_oui(intel_dp);
|
||||||
|
|
||||||
ret = drm_dp_dpcd_readb(&intel_dp->aux, INTEL_EDP_HDR_GETSET_CTRL_PARAMS, &old_ctrl);
|
ret = drm_dp_dpcd_readb(&intel_dp->aux, INTEL_EDP_HDR_GETSET_CTRL_PARAMS, &old_ctrl);
|
||||||
if (ret != 1) {
|
if (ret != 1) {
|
||||||
drm_err(&i915->drm, "Failed to read current backlight control mode: %d\n", ret);
|
drm_err(&i915->drm, "Failed to read current backlight control mode: %d\n", ret);
|
||||||
|
@ -293,6 +298,13 @@ intel_dp_aux_vesa_enable_backlight(const struct intel_crtc_state *crtc_state,
|
||||||
struct intel_panel *panel = &connector->panel;
|
struct intel_panel *panel = &connector->panel;
|
||||||
struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
|
struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
|
||||||
|
|
||||||
|
if (!panel->backlight.edp.vesa.info.aux_enable) {
|
||||||
|
u32 pwm_level = intel_backlight_invert_pwm_level(connector,
|
||||||
|
panel->backlight.pwm_level_max);
|
||||||
|
|
||||||
|
panel->backlight.pwm_funcs->enable(crtc_state, conn_state, pwm_level);
|
||||||
|
}
|
||||||
|
|
||||||
drm_edp_backlight_enable(&intel_dp->aux, &panel->backlight.edp.vesa.info, level);
|
drm_edp_backlight_enable(&intel_dp->aux, &panel->backlight.edp.vesa.info, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,6 +316,10 @@ static void intel_dp_aux_vesa_disable_backlight(const struct drm_connector_state
|
||||||
struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
|
struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
|
||||||
|
|
||||||
drm_edp_backlight_disable(&intel_dp->aux, &panel->backlight.edp.vesa.info);
|
drm_edp_backlight_disable(&intel_dp->aux, &panel->backlight.edp.vesa.info);
|
||||||
|
|
||||||
|
if (!panel->backlight.edp.vesa.info.aux_enable)
|
||||||
|
panel->backlight.pwm_funcs->disable(old_conn_state,
|
||||||
|
intel_backlight_invert_pwm_level(connector, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int intel_dp_aux_vesa_setup_backlight(struct intel_connector *connector, enum pipe pipe)
|
static int intel_dp_aux_vesa_setup_backlight(struct intel_connector *connector, enum pipe pipe)
|
||||||
|
@ -321,6 +337,15 @@ static int intel_dp_aux_vesa_setup_backlight(struct intel_connector *connector,
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
if (!panel->backlight.edp.vesa.info.aux_enable) {
|
||||||
|
ret = panel->backlight.pwm_funcs->setup(connector, pipe);
|
||||||
|
if (ret < 0) {
|
||||||
|
drm_err(&i915->drm,
|
||||||
|
"Failed to setup PWM backlight controls for eDP backlight: %d\n",
|
||||||
|
ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
panel->backlight.max = panel->backlight.edp.vesa.info.max;
|
panel->backlight.max = panel->backlight.edp.vesa.info.max;
|
||||||
panel->backlight.min = 0;
|
panel->backlight.min = 0;
|
||||||
if (current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD) {
|
if (current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD) {
|
||||||
|
@ -340,12 +365,7 @@ intel_dp_aux_supports_vesa_backlight(struct intel_connector *connector)
|
||||||
struct intel_dp *intel_dp = intel_attached_dp(connector);
|
struct intel_dp *intel_dp = intel_attached_dp(connector);
|
||||||
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
|
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
|
||||||
|
|
||||||
/* TODO: We currently only support AUX only backlight configurations, not backlights which
|
if (drm_edp_backlight_supported(intel_dp->edp_dpcd)) {
|
||||||
* require a mix of PWM and AUX controls to work. In the mean time, these machines typically
|
|
||||||
* work just fine using normal PWM controls anyway.
|
|
||||||
*/
|
|
||||||
if ((intel_dp->edp_dpcd[1] & DP_EDP_BACKLIGHT_AUX_ENABLE_CAP) &&
|
|
||||||
drm_edp_backlight_supported(intel_dp->edp_dpcd)) {
|
|
||||||
drm_dbg_kms(&i915->drm, "AUX Backlight Control Supported!\n");
|
drm_dbg_kms(&i915->drm, "AUX Backlight Control Supported!\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <linux/slab.h> /* fault-inject.h is not standalone! */
|
#include <linux/slab.h> /* fault-inject.h is not standalone! */
|
||||||
|
|
||||||
#include <linux/fault-inject.h>
|
#include <linux/fault-inject.h>
|
||||||
|
#include <linux/sched/mm.h>
|
||||||
|
|
||||||
#include "gem/i915_gem_lmem.h"
|
#include "gem/i915_gem_lmem.h"
|
||||||
#include "i915_trace.h"
|
#include "i915_trace.h"
|
||||||
|
|
|
@ -621,13 +621,6 @@ static void gen12_ctx_workarounds_init(struct intel_engine_cs *engine,
|
||||||
FF_MODE2_GS_TIMER_MASK,
|
FF_MODE2_GS_TIMER_MASK,
|
||||||
FF_MODE2_GS_TIMER_224,
|
FF_MODE2_GS_TIMER_224,
|
||||||
0, false);
|
0, false);
|
||||||
|
|
||||||
/*
|
|
||||||
* Wa_14012131227:dg1
|
|
||||||
* Wa_1508744258:tgl,rkl,dg1,adl-s,adl-p
|
|
||||||
*/
|
|
||||||
wa_masked_en(wal, GEN7_COMMON_SLICE_CHICKEN1,
|
|
||||||
GEN9_RHWO_OPTIMIZATION_DISABLE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dg1_ctx_workarounds_init(struct intel_engine_cs *engine,
|
static void dg1_ctx_workarounds_init(struct intel_engine_cs *engine,
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/sched/clock.h>
|
#include <linux/sched/clock.h>
|
||||||
#include <linux/sched/signal.h>
|
#include <linux/sched/signal.h>
|
||||||
|
#include <linux/sched/mm.h>
|
||||||
|
|
||||||
#include "gem/i915_gem_context.h"
|
#include "gem/i915_gem_context.h"
|
||||||
#include "gt/intel_breadcrumbs.h"
|
#include "gt/intel_breadcrumbs.h"
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <linux/regulator/consumer.h>
|
#include <linux/regulator/consumer.h>
|
||||||
#include <linux/reset.h>
|
#include <linux/reset.h>
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,8 @@ config DRM_MSM
|
||||||
tristate "MSM DRM"
|
tristate "MSM DRM"
|
||||||
depends on DRM
|
depends on DRM
|
||||||
depends on ARCH_QCOM || SOC_IMX5 || COMPILE_TEST
|
depends on ARCH_QCOM || SOC_IMX5 || COMPILE_TEST
|
||||||
|
depends on COMMON_CLK
|
||||||
depends on IOMMU_SUPPORT
|
depends on IOMMU_SUPPORT
|
||||||
depends on (OF && COMMON_CLK) || COMPILE_TEST
|
|
||||||
depends on QCOM_OCMEM || QCOM_OCMEM=n
|
depends on QCOM_OCMEM || QCOM_OCMEM=n
|
||||||
depends on QCOM_LLCC || QCOM_LLCC=n
|
depends on QCOM_LLCC || QCOM_LLCC=n
|
||||||
depends on QCOM_COMMAND_DB || QCOM_COMMAND_DB=n
|
depends on QCOM_COMMAND_DB || QCOM_COMMAND_DB=n
|
||||||
|
|
|
@ -23,8 +23,10 @@ msm-y := \
|
||||||
hdmi/hdmi_i2c.o \
|
hdmi/hdmi_i2c.o \
|
||||||
hdmi/hdmi_phy.o \
|
hdmi/hdmi_phy.o \
|
||||||
hdmi/hdmi_phy_8960.o \
|
hdmi/hdmi_phy_8960.o \
|
||||||
|
hdmi/hdmi_phy_8996.o \
|
||||||
hdmi/hdmi_phy_8x60.o \
|
hdmi/hdmi_phy_8x60.o \
|
||||||
hdmi/hdmi_phy_8x74.o \
|
hdmi/hdmi_phy_8x74.o \
|
||||||
|
hdmi/hdmi_pll_8960.o \
|
||||||
edp/edp.o \
|
edp/edp.o \
|
||||||
edp/edp_aux.o \
|
edp/edp_aux.o \
|
||||||
edp/edp_bridge.o \
|
edp/edp_bridge.o \
|
||||||
|
@ -37,6 +39,7 @@ msm-y := \
|
||||||
disp/mdp4/mdp4_dtv_encoder.o \
|
disp/mdp4/mdp4_dtv_encoder.o \
|
||||||
disp/mdp4/mdp4_lcdc_encoder.o \
|
disp/mdp4/mdp4_lcdc_encoder.o \
|
||||||
disp/mdp4/mdp4_lvds_connector.o \
|
disp/mdp4/mdp4_lvds_connector.o \
|
||||||
|
disp/mdp4/mdp4_lvds_pll.o \
|
||||||
disp/mdp4/mdp4_irq.o \
|
disp/mdp4/mdp4_irq.o \
|
||||||
disp/mdp4/mdp4_kms.o \
|
disp/mdp4/mdp4_kms.o \
|
||||||
disp/mdp4/mdp4_plane.o \
|
disp/mdp4/mdp4_plane.o \
|
||||||
|
@ -116,9 +119,6 @@ msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \
|
||||||
dp/dp_audio.o
|
dp/dp_audio.o
|
||||||
|
|
||||||
msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o
|
msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o
|
||||||
msm-$(CONFIG_COMMON_CLK) += disp/mdp4/mdp4_lvds_pll.o
|
|
||||||
msm-$(CONFIG_COMMON_CLK) += hdmi/hdmi_pll_8960.o
|
|
||||||
msm-$(CONFIG_COMMON_CLK) += hdmi/hdmi_phy_8996.o
|
|
||||||
|
|
||||||
msm-$(CONFIG_DRM_MSM_HDMI_HDCP) += hdmi/hdmi_hdcp.o
|
msm-$(CONFIG_DRM_MSM_HDMI_HDCP) += hdmi/hdmi_hdcp.o
|
||||||
|
|
||||||
|
|
|
@ -1424,17 +1424,24 @@ static void a6xx_llc_activate(struct a6xx_gpu *a6xx_gpu)
|
||||||
{
|
{
|
||||||
struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
|
struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
|
||||||
struct msm_gpu *gpu = &adreno_gpu->base;
|
struct msm_gpu *gpu = &adreno_gpu->base;
|
||||||
u32 gpu_scid, cntl1_regval = 0;
|
u32 cntl1_regval = 0;
|
||||||
|
|
||||||
if (IS_ERR(a6xx_gpu->llc_mmio))
|
if (IS_ERR(a6xx_gpu->llc_mmio))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!llcc_slice_activate(a6xx_gpu->llc_slice)) {
|
if (!llcc_slice_activate(a6xx_gpu->llc_slice)) {
|
||||||
gpu_scid = llcc_get_slice_id(a6xx_gpu->llc_slice);
|
u32 gpu_scid = llcc_get_slice_id(a6xx_gpu->llc_slice);
|
||||||
|
|
||||||
gpu_scid &= 0x1f;
|
gpu_scid &= 0x1f;
|
||||||
cntl1_regval = (gpu_scid << 0) | (gpu_scid << 5) | (gpu_scid << 10) |
|
cntl1_regval = (gpu_scid << 0) | (gpu_scid << 5) | (gpu_scid << 10) |
|
||||||
(gpu_scid << 15) | (gpu_scid << 20);
|
(gpu_scid << 15) | (gpu_scid << 20);
|
||||||
|
|
||||||
|
/* On A660, the SCID programming for UCHE traffic is done in
|
||||||
|
* A6XX_GBIF_SCACHE_CNTL0[14:10]
|
||||||
|
*/
|
||||||
|
if (adreno_is_a660_family(adreno_gpu))
|
||||||
|
gpu_rmw(gpu, REG_A6XX_GBIF_SCACHE_CNTL0, (0x1f << 10) |
|
||||||
|
(1 << 8), (gpu_scid << 10) | (1 << 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1471,13 +1478,6 @@ static void a6xx_llc_activate(struct a6xx_gpu *a6xx_gpu)
|
||||||
}
|
}
|
||||||
|
|
||||||
gpu_rmw(gpu, REG_A6XX_GBIF_SCACHE_CNTL1, GENMASK(24, 0), cntl1_regval);
|
gpu_rmw(gpu, REG_A6XX_GBIF_SCACHE_CNTL1, GENMASK(24, 0), cntl1_regval);
|
||||||
|
|
||||||
/* On A660, the SCID programming for UCHE traffic is done in
|
|
||||||
* A6XX_GBIF_SCACHE_CNTL0[14:10]
|
|
||||||
*/
|
|
||||||
if (adreno_is_a660_family(adreno_gpu))
|
|
||||||
gpu_rmw(gpu, REG_A6XX_GBIF_SCACHE_CNTL0, (0x1f << 10) |
|
|
||||||
(1 << 8), (gpu_scid << 10) | (1 << 8));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void a6xx_llc_slices_destroy(struct a6xx_gpu *a6xx_gpu)
|
static void a6xx_llc_slices_destroy(struct a6xx_gpu *a6xx_gpu)
|
||||||
|
@ -1640,7 +1640,7 @@ static unsigned long a6xx_gpu_busy(struct msm_gpu *gpu)
|
||||||
return (unsigned long)busy_time;
|
return (unsigned long)busy_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
void a6xx_gpu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp)
|
static void a6xx_gpu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp)
|
||||||
{
|
{
|
||||||
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
|
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
|
||||||
struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
|
struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
|
||||||
|
|
|
@ -777,12 +777,12 @@ static void a6xx_get_gmu_registers(struct msm_gpu *gpu,
|
||||||
struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
|
struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
|
||||||
|
|
||||||
a6xx_state->gmu_registers = state_kcalloc(a6xx_state,
|
a6xx_state->gmu_registers = state_kcalloc(a6xx_state,
|
||||||
2, sizeof(*a6xx_state->gmu_registers));
|
3, sizeof(*a6xx_state->gmu_registers));
|
||||||
|
|
||||||
if (!a6xx_state->gmu_registers)
|
if (!a6xx_state->gmu_registers)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
a6xx_state->nr_gmu_registers = 2;
|
a6xx_state->nr_gmu_registers = 3;
|
||||||
|
|
||||||
/* Get the CX GMU registers from AHB */
|
/* Get the CX GMU registers from AHB */
|
||||||
_a6xx_get_gmu_registers(gpu, a6xx_state, &a6xx_gmu_reglist[0],
|
_a6xx_get_gmu_registers(gpu, a6xx_state, &a6xx_gmu_reglist[0],
|
||||||
|
|
|
@ -33,6 +33,7 @@ struct dp_aux_private {
|
||||||
bool read;
|
bool read;
|
||||||
bool no_send_addr;
|
bool no_send_addr;
|
||||||
bool no_send_stop;
|
bool no_send_stop;
|
||||||
|
bool initted;
|
||||||
u32 offset;
|
u32 offset;
|
||||||
u32 segment;
|
u32 segment;
|
||||||
|
|
||||||
|
@ -331,6 +332,10 @@ static ssize_t dp_aux_transfer(struct drm_dp_aux *dp_aux,
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&aux->mutex);
|
mutex_lock(&aux->mutex);
|
||||||
|
if (!aux->initted) {
|
||||||
|
ret = -EIO;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
dp_aux_update_offset_and_segment(aux, msg);
|
dp_aux_update_offset_and_segment(aux, msg);
|
||||||
dp_aux_transfer_helper(aux, msg, true);
|
dp_aux_transfer_helper(aux, msg, true);
|
||||||
|
@ -380,6 +385,8 @@ static ssize_t dp_aux_transfer(struct drm_dp_aux *dp_aux,
|
||||||
}
|
}
|
||||||
|
|
||||||
aux->cmd_busy = false;
|
aux->cmd_busy = false;
|
||||||
|
|
||||||
|
exit:
|
||||||
mutex_unlock(&aux->mutex);
|
mutex_unlock(&aux->mutex);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -431,8 +438,13 @@ void dp_aux_init(struct drm_dp_aux *dp_aux)
|
||||||
|
|
||||||
aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
|
aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
|
||||||
|
|
||||||
|
mutex_lock(&aux->mutex);
|
||||||
|
|
||||||
dp_catalog_aux_enable(aux->catalog, true);
|
dp_catalog_aux_enable(aux->catalog, true);
|
||||||
aux->retry_cnt = 0;
|
aux->retry_cnt = 0;
|
||||||
|
aux->initted = true;
|
||||||
|
|
||||||
|
mutex_unlock(&aux->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dp_aux_deinit(struct drm_dp_aux *dp_aux)
|
void dp_aux_deinit(struct drm_dp_aux *dp_aux)
|
||||||
|
@ -441,7 +453,12 @@ void dp_aux_deinit(struct drm_dp_aux *dp_aux)
|
||||||
|
|
||||||
aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
|
aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
|
||||||
|
|
||||||
|
mutex_lock(&aux->mutex);
|
||||||
|
|
||||||
|
aux->initted = false;
|
||||||
dp_catalog_aux_enable(aux->catalog, false);
|
dp_catalog_aux_enable(aux->catalog, false);
|
||||||
|
|
||||||
|
mutex_unlock(&aux->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
int dp_aux_register(struct drm_dp_aux *dp_aux)
|
int dp_aux_register(struct drm_dp_aux *dp_aux)
|
||||||
|
|
|
@ -1658,6 +1658,8 @@ static int dsi_host_parse_lane_data(struct msm_dsi_host *msm_host,
|
||||||
if (!prop) {
|
if (!prop) {
|
||||||
DRM_DEV_DEBUG(dev,
|
DRM_DEV_DEBUG(dev,
|
||||||
"failed to find data lane mapping, using default\n");
|
"failed to find data lane mapping, using default\n");
|
||||||
|
/* Set the number of date lanes to 4 by default. */
|
||||||
|
msm_host->num_data_lanes = 4;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,6 +77,7 @@ static int msm_gpu_open(struct inode *inode, struct file *file)
|
||||||
goto free_priv;
|
goto free_priv;
|
||||||
|
|
||||||
pm_runtime_get_sync(&gpu->pdev->dev);
|
pm_runtime_get_sync(&gpu->pdev->dev);
|
||||||
|
msm_gpu_hw_init(gpu);
|
||||||
show_priv->state = gpu->funcs->gpu_state_get(gpu);
|
show_priv->state = gpu->funcs->gpu_state_get(gpu);
|
||||||
pm_runtime_put_sync(&gpu->pdev->dev);
|
pm_runtime_put_sync(&gpu->pdev->dev);
|
||||||
|
|
||||||
|
|
|
@ -967,29 +967,18 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void *data,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int msm_ioctl_wait_fence(struct drm_device *dev, void *data,
|
static int wait_fence(struct msm_gpu_submitqueue *queue, uint32_t fence_id,
|
||||||
struct drm_file *file)
|
ktime_t timeout)
|
||||||
{
|
{
|
||||||
struct msm_drm_private *priv = dev->dev_private;
|
|
||||||
struct drm_msm_wait_fence *args = data;
|
|
||||||
ktime_t timeout = to_ktime(args->timeout);
|
|
||||||
struct msm_gpu_submitqueue *queue;
|
|
||||||
struct msm_gpu *gpu = priv->gpu;
|
|
||||||
struct dma_fence *fence;
|
struct dma_fence *fence;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (args->pad) {
|
if (fence_id > queue->last_fence) {
|
||||||
DRM_ERROR("invalid pad: %08x\n", args->pad);
|
DRM_ERROR_RATELIMITED("waiting on invalid fence: %u (of %u)\n",
|
||||||
|
fence_id, queue->last_fence);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gpu)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
queue = msm_submitqueue_get(file->driver_priv, args->queueid);
|
|
||||||
if (!queue)
|
|
||||||
return -ENOENT;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Map submitqueue scoped "seqno" (which is actually an idr key)
|
* Map submitqueue scoped "seqno" (which is actually an idr key)
|
||||||
* back to underlying dma-fence
|
* back to underlying dma-fence
|
||||||
|
@ -1001,7 +990,7 @@ static int msm_ioctl_wait_fence(struct drm_device *dev, void *data,
|
||||||
ret = mutex_lock_interruptible(&queue->lock);
|
ret = mutex_lock_interruptible(&queue->lock);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
fence = idr_find(&queue->fence_idr, args->fence);
|
fence = idr_find(&queue->fence_idr, fence_id);
|
||||||
if (fence)
|
if (fence)
|
||||||
fence = dma_fence_get_rcu(fence);
|
fence = dma_fence_get_rcu(fence);
|
||||||
mutex_unlock(&queue->lock);
|
mutex_unlock(&queue->lock);
|
||||||
|
@ -1017,6 +1006,32 @@ static int msm_ioctl_wait_fence(struct drm_device *dev, void *data,
|
||||||
}
|
}
|
||||||
|
|
||||||
dma_fence_put(fence);
|
dma_fence_put(fence);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int msm_ioctl_wait_fence(struct drm_device *dev, void *data,
|
||||||
|
struct drm_file *file)
|
||||||
|
{
|
||||||
|
struct msm_drm_private *priv = dev->dev_private;
|
||||||
|
struct drm_msm_wait_fence *args = data;
|
||||||
|
struct msm_gpu_submitqueue *queue;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (args->pad) {
|
||||||
|
DRM_ERROR("invalid pad: %08x\n", args->pad);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!priv->gpu)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
queue = msm_submitqueue_get(file->driver_priv, args->queueid);
|
||||||
|
if (!queue)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
ret = wait_fence(queue, args->fence, to_ktime(args->timeout));
|
||||||
|
|
||||||
msm_submitqueue_put(queue);
|
msm_submitqueue_put(queue);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -1056,8 +1056,7 @@ static int msm_gem_object_mmap(struct drm_gem_object *obj, struct vm_area_struct
|
||||||
{
|
{
|
||||||
struct msm_gem_object *msm_obj = to_msm_bo(obj);
|
struct msm_gem_object *msm_obj = to_msm_bo(obj);
|
||||||
|
|
||||||
vma->vm_flags &= ~VM_PFNMAP;
|
vma->vm_flags |= VM_IO | VM_MIXEDMAP | VM_DONTEXPAND | VM_DONTDUMP;
|
||||||
vma->vm_flags |= VM_MIXEDMAP | VM_DONTEXPAND;
|
|
||||||
vma->vm_page_prot = msm_gem_pgprot(msm_obj, vm_get_page_prot(vma->vm_flags));
|
vma->vm_page_prot = msm_gem_pgprot(msm_obj, vm_get_page_prot(vma->vm_flags));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1121,7 +1120,7 @@ static int msm_gem_new_impl(struct drm_device *dev,
|
||||||
break;
|
break;
|
||||||
fallthrough;
|
fallthrough;
|
||||||
default:
|
default:
|
||||||
DRM_DEV_ERROR(dev->dev, "invalid cache flag: %x\n",
|
DRM_DEV_DEBUG(dev->dev, "invalid cache flag: %x\n",
|
||||||
(flags & MSM_BO_CACHE_MASK));
|
(flags & MSM_BO_CACHE_MASK));
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/vmalloc.h>
|
#include <linux/vmalloc.h>
|
||||||
|
#include <linux/sched/mm.h>
|
||||||
|
|
||||||
#include "msm_drv.h"
|
#include "msm_drv.h"
|
||||||
#include "msm_gem.h"
|
#include "msm_gem.h"
|
||||||
|
|
|
@ -772,6 +772,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
|
||||||
args->nr_cmds);
|
args->nr_cmds);
|
||||||
if (IS_ERR(submit)) {
|
if (IS_ERR(submit)) {
|
||||||
ret = PTR_ERR(submit);
|
ret = PTR_ERR(submit);
|
||||||
|
submit = NULL;
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -904,6 +905,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
|
||||||
drm_sched_entity_push_job(&submit->base);
|
drm_sched_entity_push_job(&submit->base);
|
||||||
|
|
||||||
args->fence = submit->fence_id;
|
args->fence = submit->fence_id;
|
||||||
|
queue->last_fence = submit->fence_id;
|
||||||
|
|
||||||
msm_reset_syncobjs(syncobjs_to_reset, args->nr_in_syncobjs);
|
msm_reset_syncobjs(syncobjs_to_reset, args->nr_in_syncobjs);
|
||||||
msm_process_post_deps(post_deps, args->nr_out_syncobjs,
|
msm_process_post_deps(post_deps, args->nr_out_syncobjs,
|
||||||
|
|
|
@ -359,6 +359,8 @@ static inline int msm_gpu_convert_priority(struct msm_gpu *gpu, int prio,
|
||||||
* @ring_nr: the ringbuffer used by this submitqueue, which is determined
|
* @ring_nr: the ringbuffer used by this submitqueue, which is determined
|
||||||
* by the submitqueue's priority
|
* by the submitqueue's priority
|
||||||
* @faults: the number of GPU hangs associated with this submitqueue
|
* @faults: the number of GPU hangs associated with this submitqueue
|
||||||
|
* @last_fence: the sequence number of the last allocated fence (for error
|
||||||
|
* checking)
|
||||||
* @ctx: the per-drm_file context associated with the submitqueue (ie.
|
* @ctx: the per-drm_file context associated with the submitqueue (ie.
|
||||||
* which set of pgtables do submits jobs associated with the
|
* which set of pgtables do submits jobs associated with the
|
||||||
* submitqueue use)
|
* submitqueue use)
|
||||||
|
@ -374,6 +376,7 @@ struct msm_gpu_submitqueue {
|
||||||
u32 flags;
|
u32 flags;
|
||||||
u32 ring_nr;
|
u32 ring_nr;
|
||||||
int faults;
|
int faults;
|
||||||
|
uint32_t last_fence;
|
||||||
struct msm_file_private *ctx;
|
struct msm_file_private *ctx;
|
||||||
struct list_head node;
|
struct list_head node;
|
||||||
struct idr fence_idr;
|
struct idr fence_idr;
|
||||||
|
|
|
@ -20,6 +20,10 @@ static int msm_devfreq_target(struct device *dev, unsigned long *freq,
|
||||||
struct msm_gpu *gpu = dev_to_gpu(dev);
|
struct msm_gpu *gpu = dev_to_gpu(dev);
|
||||||
struct dev_pm_opp *opp;
|
struct dev_pm_opp *opp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note that devfreq_recommended_opp() can modify the freq
|
||||||
|
* to something that actually is in the opp table:
|
||||||
|
*/
|
||||||
opp = devfreq_recommended_opp(dev, freq, flags);
|
opp = devfreq_recommended_opp(dev, freq, flags);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -28,6 +32,7 @@ static int msm_devfreq_target(struct device *dev, unsigned long *freq,
|
||||||
*/
|
*/
|
||||||
if (gpu->devfreq.idle_freq) {
|
if (gpu->devfreq.idle_freq) {
|
||||||
gpu->devfreq.idle_freq = *freq;
|
gpu->devfreq.idle_freq = *freq;
|
||||||
|
dev_pm_opp_put(opp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,9 +208,6 @@ static void msm_devfreq_idle_work(struct kthread_work *work)
|
||||||
struct msm_gpu *gpu = container_of(df, struct msm_gpu, devfreq);
|
struct msm_gpu *gpu = container_of(df, struct msm_gpu, devfreq);
|
||||||
unsigned long idle_freq, target_freq = 0;
|
unsigned long idle_freq, target_freq = 0;
|
||||||
|
|
||||||
if (!df->devfreq)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Hold devfreq lock to synchronize with get_dev_status()/
|
* Hold devfreq lock to synchronize with get_dev_status()/
|
||||||
* target() callbacks
|
* target() callbacks
|
||||||
|
@ -227,6 +229,9 @@ void msm_devfreq_idle(struct msm_gpu *gpu)
|
||||||
{
|
{
|
||||||
struct msm_gpu_devfreq *df = &gpu->devfreq;
|
struct msm_gpu_devfreq *df = &gpu->devfreq;
|
||||||
|
|
||||||
|
if (!df->devfreq)
|
||||||
|
return;
|
||||||
|
|
||||||
msm_hrtimer_queue_work(&df->idle_work, ms_to_ktime(1),
|
msm_hrtimer_queue_work(&df->idle_work, ms_to_ktime(1),
|
||||||
HRTIMER_MODE_ABS);
|
HRTIMER_MODE_REL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/shmem_fs.h>
|
#include <linux/shmem_fs.h>
|
||||||
#include <linux/file.h>
|
#include <linux/file.h>
|
||||||
|
#include <linux/module.h>
|
||||||
#include <drm/drm_cache.h>
|
#include <drm/drm_cache.h>
|
||||||
#include <drm/ttm/ttm_bo_driver.h>
|
#include <drm/ttm/ttm_bo_driver.h>
|
||||||
|
|
||||||
|
|
|
@ -337,10 +337,10 @@ static void vc4_atomic_commit_tail(struct drm_atomic_state *state)
|
||||||
struct drm_device *dev = state->dev;
|
struct drm_device *dev = state->dev;
|
||||||
struct vc4_dev *vc4 = to_vc4_dev(dev);
|
struct vc4_dev *vc4 = to_vc4_dev(dev);
|
||||||
struct vc4_hvs *hvs = vc4->hvs;
|
struct vc4_hvs *hvs = vc4->hvs;
|
||||||
struct drm_crtc_state *old_crtc_state;
|
|
||||||
struct drm_crtc_state *new_crtc_state;
|
struct drm_crtc_state *new_crtc_state;
|
||||||
struct drm_crtc *crtc;
|
struct drm_crtc *crtc;
|
||||||
struct vc4_hvs_state *old_hvs_state;
|
struct vc4_hvs_state *old_hvs_state;
|
||||||
|
unsigned int channel;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
|
for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
|
||||||
|
@ -353,30 +353,32 @@ static void vc4_atomic_commit_tail(struct drm_atomic_state *state)
|
||||||
vc4_hvs_mask_underrun(dev, vc4_crtc_state->assigned_channel);
|
vc4_hvs_mask_underrun(dev, vc4_crtc_state->assigned_channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vc4->hvs->hvs5)
|
|
||||||
clk_set_min_rate(hvs->core_clk, 500000000);
|
|
||||||
|
|
||||||
old_hvs_state = vc4_hvs_get_old_global_state(state);
|
old_hvs_state = vc4_hvs_get_old_global_state(state);
|
||||||
if (!old_hvs_state)
|
if (IS_ERR(old_hvs_state))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for_each_old_crtc_in_state(state, crtc, old_crtc_state, i) {
|
for (channel = 0; channel < HVS_NUM_CHANNELS; channel++) {
|
||||||
struct vc4_crtc_state *vc4_crtc_state =
|
struct drm_crtc_commit *commit;
|
||||||
to_vc4_crtc_state(old_crtc_state);
|
|
||||||
unsigned int channel = vc4_crtc_state->assigned_channel;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (channel == VC4_HVS_CHANNEL_DISABLED)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!old_hvs_state->fifo_state[channel].in_use)
|
if (!old_hvs_state->fifo_state[channel].in_use)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ret = drm_crtc_commit_wait(old_hvs_state->fifo_state[channel].pending_commit);
|
commit = old_hvs_state->fifo_state[channel].pending_commit;
|
||||||
|
if (!commit)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ret = drm_crtc_commit_wait(commit);
|
||||||
if (ret)
|
if (ret)
|
||||||
drm_err(dev, "Timed out waiting for commit\n");
|
drm_err(dev, "Timed out waiting for commit\n");
|
||||||
|
|
||||||
|
drm_crtc_commit_put(commit);
|
||||||
|
old_hvs_state->fifo_state[channel].pending_commit = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vc4->hvs->hvs5)
|
||||||
|
clk_set_min_rate(hvs->core_clk, 500000000);
|
||||||
|
|
||||||
drm_atomic_helper_commit_modeset_disables(dev, state);
|
drm_atomic_helper_commit_modeset_disables(dev, state);
|
||||||
|
|
||||||
vc4_ctm_commit(vc4, state);
|
vc4_ctm_commit(vc4, state);
|
||||||
|
@ -410,8 +412,8 @@ static int vc4_atomic_commit_setup(struct drm_atomic_state *state)
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
hvs_state = vc4_hvs_get_new_global_state(state);
|
hvs_state = vc4_hvs_get_new_global_state(state);
|
||||||
if (!hvs_state)
|
if (WARN_ON(IS_ERR(hvs_state)))
|
||||||
return -EINVAL;
|
return PTR_ERR(hvs_state);
|
||||||
|
|
||||||
for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
|
for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
|
||||||
struct vc4_crtc_state *vc4_crtc_state =
|
struct vc4_crtc_state *vc4_crtc_state =
|
||||||
|
@ -668,12 +670,6 @@ vc4_hvs_channels_duplicate_state(struct drm_private_obj *obj)
|
||||||
|
|
||||||
for (i = 0; i < HVS_NUM_CHANNELS; i++) {
|
for (i = 0; i < HVS_NUM_CHANNELS; i++) {
|
||||||
state->fifo_state[i].in_use = old_state->fifo_state[i].in_use;
|
state->fifo_state[i].in_use = old_state->fifo_state[i].in_use;
|
||||||
|
|
||||||
if (!old_state->fifo_state[i].pending_commit)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
state->fifo_state[i].pending_commit =
|
|
||||||
drm_crtc_commit_get(old_state->fifo_state[i].pending_commit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &state->base;
|
return &state->base;
|
||||||
|
@ -762,8 +758,8 @@ static int vc4_pv_muxing_atomic_check(struct drm_device *dev,
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
hvs_new_state = vc4_hvs_get_global_state(state);
|
hvs_new_state = vc4_hvs_get_global_state(state);
|
||||||
if (!hvs_new_state)
|
if (IS_ERR(hvs_new_state))
|
||||||
return -EINVAL;
|
return PTR_ERR(hvs_new_state);
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(hvs_new_state->fifo_state); i++)
|
for (i = 0; i < ARRAY_SIZE(hvs_new_state->fifo_state); i++)
|
||||||
if (!hvs_new_state->fifo_state[i].in_use)
|
if (!hvs_new_state->fifo_state[i].in_use)
|
||||||
|
|
|
@ -157,36 +157,6 @@ static void virtio_gpu_config_changed(struct virtio_device *vdev)
|
||||||
schedule_work(&vgdev->config_changed_work);
|
schedule_work(&vgdev->config_changed_work);
|
||||||
}
|
}
|
||||||
|
|
||||||
static __poll_t virtio_gpu_poll(struct file *filp,
|
|
||||||
struct poll_table_struct *wait)
|
|
||||||
{
|
|
||||||
struct drm_file *drm_file = filp->private_data;
|
|
||||||
struct virtio_gpu_fpriv *vfpriv = drm_file->driver_priv;
|
|
||||||
struct drm_device *dev = drm_file->minor->dev;
|
|
||||||
struct virtio_gpu_device *vgdev = dev->dev_private;
|
|
||||||
struct drm_pending_event *e = NULL;
|
|
||||||
__poll_t mask = 0;
|
|
||||||
|
|
||||||
if (!vgdev->has_virgl_3d || !vfpriv || !vfpriv->ring_idx_mask)
|
|
||||||
return drm_poll(filp, wait);
|
|
||||||
|
|
||||||
poll_wait(filp, &drm_file->event_wait, wait);
|
|
||||||
|
|
||||||
if (!list_empty(&drm_file->event_list)) {
|
|
||||||
spin_lock_irq(&dev->event_lock);
|
|
||||||
e = list_first_entry(&drm_file->event_list,
|
|
||||||
struct drm_pending_event, link);
|
|
||||||
drm_file->event_space += e->event->length;
|
|
||||||
list_del(&e->link);
|
|
||||||
spin_unlock_irq(&dev->event_lock);
|
|
||||||
|
|
||||||
kfree(e);
|
|
||||||
mask |= EPOLLIN | EPOLLRDNORM;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct virtio_device_id id_table[] = {
|
static struct virtio_device_id id_table[] = {
|
||||||
{ VIRTIO_ID_GPU, VIRTIO_DEV_ANY_ID },
|
{ VIRTIO_ID_GPU, VIRTIO_DEV_ANY_ID },
|
||||||
{ 0 },
|
{ 0 },
|
||||||
|
@ -226,17 +196,7 @@ MODULE_AUTHOR("Dave Airlie <airlied@redhat.com>");
|
||||||
MODULE_AUTHOR("Gerd Hoffmann <kraxel@redhat.com>");
|
MODULE_AUTHOR("Gerd Hoffmann <kraxel@redhat.com>");
|
||||||
MODULE_AUTHOR("Alon Levy");
|
MODULE_AUTHOR("Alon Levy");
|
||||||
|
|
||||||
static const struct file_operations virtio_gpu_driver_fops = {
|
DEFINE_DRM_GEM_FOPS(virtio_gpu_driver_fops);
|
||||||
.owner = THIS_MODULE,
|
|
||||||
.open = drm_open,
|
|
||||||
.release = drm_release,
|
|
||||||
.unlocked_ioctl = drm_ioctl,
|
|
||||||
.compat_ioctl = drm_compat_ioctl,
|
|
||||||
.poll = virtio_gpu_poll,
|
|
||||||
.read = drm_read,
|
|
||||||
.llseek = noop_llseek,
|
|
||||||
.mmap = drm_gem_mmap
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct drm_driver driver = {
|
static const struct drm_driver driver = {
|
||||||
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_RENDER | DRIVER_ATOMIC,
|
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_RENDER | DRIVER_ATOMIC,
|
||||||
|
|
|
@ -138,7 +138,6 @@ struct virtio_gpu_fence_driver {
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define VIRTGPU_EVENT_FENCE_SIGNALED_INTERNAL 0x10000000
|
|
||||||
struct virtio_gpu_fence_event {
|
struct virtio_gpu_fence_event {
|
||||||
struct drm_pending_event base;
|
struct drm_pending_event base;
|
||||||
struct drm_event event;
|
struct drm_event event;
|
||||||
|
|
|
@ -54,7 +54,7 @@ static int virtio_gpu_fence_event_create(struct drm_device *dev,
|
||||||
if (!e)
|
if (!e)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
e->event.type = VIRTGPU_EVENT_FENCE_SIGNALED_INTERNAL;
|
e->event.type = VIRTGPU_EVENT_FENCE_SIGNALED;
|
||||||
e->event.length = sizeof(e->event);
|
e->event.length = sizeof(e->event);
|
||||||
|
|
||||||
ret = drm_event_reserve_init(dev, file, &e->base, &e->event);
|
ret = drm_event_reserve_init(dev, file, &e->base, &e->event);
|
||||||
|
|
|
@ -207,14 +207,14 @@ config HID_CHERRY
|
||||||
|
|
||||||
config HID_CHICONY
|
config HID_CHICONY
|
||||||
tristate "Chicony devices"
|
tristate "Chicony devices"
|
||||||
depends on HID
|
depends on USB_HID
|
||||||
default !EXPERT
|
default !EXPERT
|
||||||
help
|
help
|
||||||
Support for Chicony Tactical pad and special keys on Chicony keyboards.
|
Support for Chicony Tactical pad and special keys on Chicony keyboards.
|
||||||
|
|
||||||
config HID_CORSAIR
|
config HID_CORSAIR
|
||||||
tristate "Corsair devices"
|
tristate "Corsair devices"
|
||||||
depends on HID && USB && LEDS_CLASS
|
depends on USB_HID && LEDS_CLASS
|
||||||
help
|
help
|
||||||
Support for Corsair devices that are not fully compliant with the
|
Support for Corsair devices that are not fully compliant with the
|
||||||
HID standard.
|
HID standard.
|
||||||
|
@ -245,7 +245,7 @@ config HID_MACALLY
|
||||||
|
|
||||||
config HID_PRODIKEYS
|
config HID_PRODIKEYS
|
||||||
tristate "Prodikeys PC-MIDI Keyboard support"
|
tristate "Prodikeys PC-MIDI Keyboard support"
|
||||||
depends on HID && SND
|
depends on USB_HID && SND
|
||||||
select SND_RAWMIDI
|
select SND_RAWMIDI
|
||||||
help
|
help
|
||||||
Support for Prodikeys PC-MIDI Keyboard device support.
|
Support for Prodikeys PC-MIDI Keyboard device support.
|
||||||
|
@ -560,7 +560,7 @@ config HID_LENOVO
|
||||||
|
|
||||||
config HID_LOGITECH
|
config HID_LOGITECH
|
||||||
tristate "Logitech devices"
|
tristate "Logitech devices"
|
||||||
depends on HID
|
depends on USB_HID
|
||||||
depends on LEDS_CLASS
|
depends on LEDS_CLASS
|
||||||
default !EXPERT
|
default !EXPERT
|
||||||
help
|
help
|
||||||
|
@ -951,7 +951,7 @@ config HID_SAITEK
|
||||||
|
|
||||||
config HID_SAMSUNG
|
config HID_SAMSUNG
|
||||||
tristate "Samsung InfraRed remote control or keyboards"
|
tristate "Samsung InfraRed remote control or keyboards"
|
||||||
depends on HID
|
depends on USB_HID
|
||||||
help
|
help
|
||||||
Support for Samsung InfraRed remote control or keyboards.
|
Support for Samsung InfraRed remote control or keyboards.
|
||||||
|
|
||||||
|
|
|
@ -1028,8 +1028,7 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||||
if (drvdata->quirks & QUIRK_IS_MULTITOUCH)
|
if (drvdata->quirks & QUIRK_IS_MULTITOUCH)
|
||||||
drvdata->tp = &asus_i2c_tp;
|
drvdata->tp = &asus_i2c_tp;
|
||||||
|
|
||||||
if ((drvdata->quirks & QUIRK_T100_KEYBOARD) &&
|
if ((drvdata->quirks & QUIRK_T100_KEYBOARD) && hid_is_usb(hdev)) {
|
||||||
hid_is_using_ll_driver(hdev, &usb_hid_driver)) {
|
|
||||||
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
|
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
|
||||||
|
|
||||||
if (intf->altsetting->desc.bInterfaceNumber == T100_TPAD_INTF) {
|
if (intf->altsetting->desc.bInterfaceNumber == T100_TPAD_INTF) {
|
||||||
|
@ -1057,8 +1056,7 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||||
drvdata->tp = &asus_t100chi_tp;
|
drvdata->tp = &asus_t100chi_tp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((drvdata->quirks & QUIRK_MEDION_E1239T) &&
|
if ((drvdata->quirks & QUIRK_MEDION_E1239T) && hid_is_usb(hdev)) {
|
||||||
hid_is_using_ll_driver(hdev, &usb_hid_driver)) {
|
|
||||||
struct usb_host_interface *alt =
|
struct usb_host_interface *alt =
|
||||||
to_usb_interface(hdev->dev.parent)->altsetting;
|
to_usb_interface(hdev->dev.parent)->altsetting;
|
||||||
|
|
||||||
|
|
|
@ -191,7 +191,7 @@ static void bigben_worker(struct work_struct *work)
|
||||||
struct bigben_device, worker);
|
struct bigben_device, worker);
|
||||||
struct hid_field *report_field = bigben->report->field[0];
|
struct hid_field *report_field = bigben->report->field[0];
|
||||||
|
|
||||||
if (bigben->removed)
|
if (bigben->removed || !report_field)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (bigben->work_led) {
|
if (bigben->work_led) {
|
||||||
|
|
|
@ -114,6 +114,9 @@ static int ch_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (!hid_is_usb(hdev))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
hdev->quirks |= HID_QUIRK_INPUT_PER_APP;
|
hdev->quirks |= HID_QUIRK_INPUT_PER_APP;
|
||||||
ret = hid_parse(hdev);
|
ret = hid_parse(hdev);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
|
|
@ -553,7 +553,12 @@ static int corsair_probe(struct hid_device *dev, const struct hid_device_id *id)
|
||||||
int ret;
|
int ret;
|
||||||
unsigned long quirks = id->driver_data;
|
unsigned long quirks = id->driver_data;
|
||||||
struct corsair_drvdata *drvdata;
|
struct corsair_drvdata *drvdata;
|
||||||
struct usb_interface *usbif = to_usb_interface(dev->dev.parent);
|
struct usb_interface *usbif;
|
||||||
|
|
||||||
|
if (!hid_is_usb(dev))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
usbif = to_usb_interface(dev->dev.parent);
|
||||||
|
|
||||||
drvdata = devm_kzalloc(&dev->dev, sizeof(struct corsair_drvdata),
|
drvdata = devm_kzalloc(&dev->dev, sizeof(struct corsair_drvdata),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
|
|
|
@ -50,7 +50,7 @@ struct elan_drvdata {
|
||||||
|
|
||||||
static int is_not_elan_touchpad(struct hid_device *hdev)
|
static int is_not_elan_touchpad(struct hid_device *hdev)
|
||||||
{
|
{
|
||||||
if (hdev->bus == BUS_USB) {
|
if (hid_is_usb(hdev)) {
|
||||||
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
|
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
|
||||||
|
|
||||||
return (intf->altsetting->desc.bInterfaceNumber !=
|
return (intf->altsetting->desc.bInterfaceNumber !=
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue