Browse Source

Merge branch 'for_linus' into for_next

Jan Kara 10 years ago
parent
commit
1cd6b7be92
100 changed files with 976 additions and 588 deletions
  1. 1 0
      .mailmap
  2. 12 37
      Documentation/target/tcm_mod_builder.py
  3. 16 6
      MAINTAINERS
  4. 2 1
      Makefile
  5. 1 0
      arch/arm/include/uapi/asm/unistd.h
  6. 1 0
      arch/arm/kernel/calls.S
  7. 8 0
      arch/arm/kernel/perf_regs.c
  8. 2 7
      arch/arm/mm/dump.c
  9. 2 2
      arch/arm/mm/init.c
  10. 2 2
      arch/arm/mm/mmu.c
  11. 1 0
      arch/arm64/include/asm/arch_timer.h
  12. 5 0
      arch/arm64/include/asm/cpu.h
  13. 1 3
      arch/arm64/include/asm/processor.h
  14. 1 1
      arch/arm64/include/asm/unistd.h
  15. 10 0
      arch/arm64/kernel/cpuinfo.c
  16. 1 1
      arch/arm64/kernel/efi.c
  17. 1 0
      arch/arm64/kernel/module.c
  18. 8 0
      arch/arm64/kernel/perf_regs.c
  19. 1 0
      arch/arm64/kernel/setup.c
  20. 1 0
      arch/arm64/kernel/smp_spin_table.c
  21. 1 0
      arch/blackfin/mach-bf533/boards/stamp.c
  22. 1 1
      arch/ia64/include/asm/unistd.h
  23. 1 0
      arch/ia64/include/uapi/asm/unistd.h
  24. 4 5
      arch/ia64/kernel/acpi.c
  25. 1 0
      arch/ia64/kernel/entry.S
  26. 10 0
      arch/powerpc/include/asm/kexec.h
  27. 1 0
      arch/powerpc/include/asm/systbl.h
  28. 1 1
      arch/powerpc/include/asm/unistd.h
  29. 1 0
      arch/powerpc/include/uapi/asm/unistd.h
  30. 1 1
      arch/powerpc/kernel/machine_kexec_64.c
  31. 1 8
      arch/powerpc/kernel/smp.c
  32. 7 1
      arch/powerpc/platforms/pseries/lpar.c
  33. 1 0
      arch/x86/boot/Makefile
  34. 1 1
      arch/x86/crypto/Makefile
  35. 35 11
      arch/x86/crypto/aes_ctrby8_avx-x86_64.S
  36. 4 2
      arch/x86/include/asm/vgtod.h
  37. 4 5
      arch/x86/kernel/acpi/boot.c
  38. 1 0
      arch/x86/kernel/cpu/Makefile
  39. 1 1
      arch/x86/kernel/cpu/mkcapflags.sh
  40. 1 1
      arch/x86/kernel/cpu/perf_event_intel_uncore.h
  41. 17 0
      arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c
  42. 90 0
      arch/x86/kernel/perf_regs.c
  43. 1 1
      arch/x86/lib/insn.c
  44. 17 20
      arch/x86/mm/init.c
  45. 29 16
      arch/x86/vdso/vma.c
  46. 21 1
      arch/x86/xen/enlighten.c
  47. 10 10
      arch/x86/xen/p2m.c
  48. 20 22
      arch/x86/xen/setup.c
  49. 5 13
      arch/x86/xen/time.c
  50. 4 2
      drivers/Makefile
  51. 14 11
      drivers/acpi/acpi_processor.c
  52. 1 1
      drivers/acpi/device_pm.c
  53. 7 4
      drivers/acpi/int340x_thermal.c
  54. 28 28
      drivers/acpi/processor_core.c
  55. 8 5
      drivers/acpi/scan.c
  56. 10 0
      drivers/acpi/video.c
  57. 2 1
      drivers/char/ipmi/ipmi_ssif.c
  58. 67 89
      drivers/gpio/gpio-dln2.c
  59. 2 1
      drivers/gpio/gpio-grgpio.c
  60. 1 1
      drivers/gpu/drm/Makefile
  61. 168 148
      drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
  62. 26 2
      drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
  63. 1 1
      drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c
  64. 1 1
      drivers/gpu/drm/amd/amdkfd/kfd_pasid.c
  65. 18 0
      drivers/gpu/drm/amd/amdkfd/kfd_priv.h
  66. 1 1
      drivers/gpu/drm/amd/amdkfd/kfd_topology.c
  67. 1 1
      drivers/gpu/drm/amd/include/kgd_kfd_interface.h
  68. 0 2
      drivers/gpu/drm/i915/i915_drv.h
  69. 7 1
      drivers/gpu/drm/i915/i915_gem.c
  70. 2 4
      drivers/gpu/drm/i915/i915_irq.c
  71. 1 7
      drivers/gpu/drm/i915/intel_display.c
  72. 0 27
      drivers/gpu/drm/i915/intel_runtime_pm.c
  73. 2 2
      drivers/gpu/drm/nouveau/core/core/event.c
  74. 1 1
      drivers/gpu/drm/nouveau/core/core/notify.c
  75. 33 0
      drivers/gpu/drm/nouveau/core/engine/device/nve0.c
  76. 4 2
      drivers/gpu/drm/nouveau/core/subdev/bios/shadowramin.c
  77. 51 14
      drivers/gpu/drm/nouveau/core/subdev/fb/ramnvaa.c
  78. 0 8
      drivers/gpu/drm/nouveau/core/subdev/mc/nv4c.c
  79. 3 1
      drivers/gpu/drm/nouveau/nouveau_bo.c
  80. 30 5
      drivers/gpu/drm/nouveau/nouveau_gem.c
  81. 4 4
      drivers/gpu/drm/radeon/atombios_crtc.c
  82. 4 0
      drivers/gpu/drm/radeon/atombios_dp.c
  83. 2 0
      drivers/gpu/drm/radeon/cikd.h
  84. 1 1
      drivers/gpu/drm/radeon/dce3_1_afmt.c
  85. 4 6
      drivers/gpu/drm/radeon/kv_dpm.c
  86. 20 3
      drivers/gpu/drm/radeon/radeon_kfd.c
  87. 1 1
      drivers/gpu/drm/radeon/radeon_state.c
  88. 2 1
      drivers/hid/Kconfig
  89. 1 0
      drivers/hid/hid-core.c
  90. 1 0
      drivers/hid/hid-ids.h
  91. 3 0
      drivers/hid/hid-input.c
  92. 4 0
      drivers/hid/hid-kye.c
  93. 15 1
      drivers/hid/hid-logitech-dj.c
  94. 41 0
      drivers/hid/hid-logitech-hidpp.c
  95. 6 2
      drivers/hid/hid-roccat-pyra.c
  96. 0 5
      drivers/hid/i2c-hid/i2c-hid.c
  97. 1 0
      drivers/hid/usbhid/hid-quirks.c
  98. 4 8
      drivers/iommu/intel-iommu.c
  99. 3 3
      drivers/iommu/ipmmu-vmsa.c
  100. 0 1
      drivers/iommu/rockchip-iommu.c

+ 1 - 0
.mailmap

@@ -51,6 +51,7 @@ Greg Kroah-Hartman <gregkh@suse.de>
 Greg Kroah-Hartman <greg@kroah.com>
 Greg Kroah-Hartman <greg@kroah.com>
 Henk Vergonet <Henk.Vergonet@gmail.com>
 Henk Vergonet <Henk.Vergonet@gmail.com>
 Henrik Kretzschmar <henne@nachtwindheim.de>
 Henrik Kretzschmar <henne@nachtwindheim.de>
+Henrik Rydberg <rydberg@bitmath.org>
 Herbert Xu <herbert@gondor.apana.org.au>
 Herbert Xu <herbert@gondor.apana.org.au>
 Jacob Shin <Jacob.Shin@amd.com>
 Jacob Shin <Jacob.Shin@amd.com>
 James Bottomley <jejb@mulgrave.(none)>
 James Bottomley <jejb@mulgrave.(none)>

+ 12 - 37
Documentation/target/tcm_mod_builder.py

@@ -389,9 +389,6 @@ def tcm_mod_build_configfs(proto_ident, fabric_mod_dir_var, fabric_mod_name):
 	buf += "	.release_cmd			= " + fabric_mod_name + "_release_cmd,\n"
 	buf += "	.release_cmd			= " + fabric_mod_name + "_release_cmd,\n"
 	buf += "	.shutdown_session		= " + fabric_mod_name + "_shutdown_session,\n"
 	buf += "	.shutdown_session		= " + fabric_mod_name + "_shutdown_session,\n"
 	buf += "	.close_session			= " + fabric_mod_name + "_close_session,\n"
 	buf += "	.close_session			= " + fabric_mod_name + "_close_session,\n"
-	buf += "	.stop_session			= " + fabric_mod_name + "_stop_session,\n"
-	buf += "	.fall_back_to_erl0		= " + fabric_mod_name + "_reset_nexus,\n"
-	buf += "	.sess_logged_in			= " + fabric_mod_name + "_sess_logged_in,\n"
 	buf += "	.sess_get_index			= " + fabric_mod_name + "_sess_get_index,\n"
 	buf += "	.sess_get_index			= " + fabric_mod_name + "_sess_get_index,\n"
 	buf += "	.sess_get_initiator_sid		= NULL,\n"
 	buf += "	.sess_get_initiator_sid		= NULL,\n"
 	buf += "	.write_pending			= " + fabric_mod_name + "_write_pending,\n"
 	buf += "	.write_pending			= " + fabric_mod_name + "_write_pending,\n"
@@ -402,7 +399,7 @@ def tcm_mod_build_configfs(proto_ident, fabric_mod_dir_var, fabric_mod_name):
 	buf += "	.queue_data_in			= " + fabric_mod_name + "_queue_data_in,\n"
 	buf += "	.queue_data_in			= " + fabric_mod_name + "_queue_data_in,\n"
 	buf += "	.queue_status			= " + fabric_mod_name + "_queue_status,\n"
 	buf += "	.queue_status			= " + fabric_mod_name + "_queue_status,\n"
 	buf += "	.queue_tm_rsp			= " + fabric_mod_name + "_queue_tm_rsp,\n"
 	buf += "	.queue_tm_rsp			= " + fabric_mod_name + "_queue_tm_rsp,\n"
-	buf += "	.is_state_remove		= " + fabric_mod_name + "_is_state_remove,\n"
+	buf += "	.aborted_task			= " + fabric_mod_name + "_aborted_task,\n"
 	buf += "	/*\n"
 	buf += "	/*\n"
 	buf += "	 * Setup function pointers for generic logic in target_core_fabric_configfs.c\n"
 	buf += "	 * Setup function pointers for generic logic in target_core_fabric_configfs.c\n"
 	buf += "	 */\n"
 	buf += "	 */\n"
@@ -428,7 +425,7 @@ def tcm_mod_build_configfs(proto_ident, fabric_mod_dir_var, fabric_mod_name):
 	buf += "	/*\n"
 	buf += "	/*\n"
 	buf += "	 * Register the top level struct config_item_type with TCM core\n"
 	buf += "	 * Register the top level struct config_item_type with TCM core\n"
 	buf += "	 */\n"
 	buf += "	 */\n"
-	buf += "	fabric = target_fabric_configfs_init(THIS_MODULE, \"" + fabric_mod_name[4:] + "\");\n"
+	buf += "	fabric = target_fabric_configfs_init(THIS_MODULE, \"" + fabric_mod_name + "\");\n"
 	buf += "	if (IS_ERR(fabric)) {\n"
 	buf += "	if (IS_ERR(fabric)) {\n"
 	buf += "		printk(KERN_ERR \"target_fabric_configfs_init() failed\\n\");\n"
 	buf += "		printk(KERN_ERR \"target_fabric_configfs_init() failed\\n\");\n"
 	buf += "		return PTR_ERR(fabric);\n"
 	buf += "		return PTR_ERR(fabric);\n"
@@ -595,7 +592,7 @@ def tcm_mod_dump_fabric_ops(proto_ident, fabric_mod_dir_var, fabric_mod_name):
 		if re.search('get_fabric_name', fo):
 		if re.search('get_fabric_name', fo):
 			buf += "char *" + fabric_mod_name + "_get_fabric_name(void)\n"
 			buf += "char *" + fabric_mod_name + "_get_fabric_name(void)\n"
 			buf += "{\n"
 			buf += "{\n"
-			buf += "	return \"" + fabric_mod_name[4:] + "\";\n"
+			buf += "	return \"" + fabric_mod_name + "\";\n"
 			buf += "}\n\n"
 			buf += "}\n\n"
 			bufi += "char *" + fabric_mod_name + "_get_fabric_name(void);\n"
 			bufi += "char *" + fabric_mod_name + "_get_fabric_name(void);\n"
 			continue
 			continue
@@ -820,27 +817,6 @@ def tcm_mod_dump_fabric_ops(proto_ident, fabric_mod_dir_var, fabric_mod_name):
 			buf += "}\n\n"
 			buf += "}\n\n"
 			bufi += "void " + fabric_mod_name + "_close_session(struct se_session *);\n"
 			bufi += "void " + fabric_mod_name + "_close_session(struct se_session *);\n"
 
 
-		if re.search('stop_session\)\(', fo):
-			buf += "void " + fabric_mod_name + "_stop_session(struct se_session *se_sess, int sess_sleep , int conn_sleep)\n"
-			buf += "{\n"
-			buf += "	return;\n"
-			buf += "}\n\n"
-			bufi += "void " + fabric_mod_name + "_stop_session(struct se_session *, int, int);\n"
-
-		if re.search('fall_back_to_erl0\)\(', fo):
-			buf += "void " + fabric_mod_name + "_reset_nexus(struct se_session *se_sess)\n"
-			buf += "{\n"
-			buf += "	return;\n"
-			buf += "}\n\n"
-			bufi += "void " + fabric_mod_name + "_reset_nexus(struct se_session *);\n"
-
-		if re.search('sess_logged_in\)\(', fo):
-			buf += "int " + fabric_mod_name + "_sess_logged_in(struct se_session *se_sess)\n"
-			buf += "{\n"
-			buf += "	return 0;\n"
-			buf += "}\n\n"
-			bufi += "int " + fabric_mod_name + "_sess_logged_in(struct se_session *);\n"
-
 		if re.search('sess_get_index\)\(', fo):
 		if re.search('sess_get_index\)\(', fo):
 			buf += "u32 " + fabric_mod_name + "_sess_get_index(struct se_session *se_sess)\n"
 			buf += "u32 " + fabric_mod_name + "_sess_get_index(struct se_session *se_sess)\n"
 			buf += "{\n"
 			buf += "{\n"
@@ -898,19 +874,18 @@ def tcm_mod_dump_fabric_ops(proto_ident, fabric_mod_dir_var, fabric_mod_name):
 			bufi += "int " + fabric_mod_name + "_queue_status(struct se_cmd *);\n"
 			bufi += "int " + fabric_mod_name + "_queue_status(struct se_cmd *);\n"
 
 
 		if re.search('queue_tm_rsp\)\(', fo):
 		if re.search('queue_tm_rsp\)\(', fo):
-			buf += "int " + fabric_mod_name + "_queue_tm_rsp(struct se_cmd *se_cmd)\n"
+			buf += "void " + fabric_mod_name + "_queue_tm_rsp(struct se_cmd *se_cmd)\n"
 			buf += "{\n"
 			buf += "{\n"
-			buf += "	return 0;\n"
+			buf += "	return;\n"
 			buf += "}\n\n"
 			buf += "}\n\n"
-			bufi += "int " + fabric_mod_name + "_queue_tm_rsp(struct se_cmd *);\n"
+			bufi += "void " + fabric_mod_name + "_queue_tm_rsp(struct se_cmd *);\n"
 
 
-		if re.search('is_state_remove\)\(', fo):
-			buf += "int " + fabric_mod_name + "_is_state_remove(struct se_cmd *se_cmd)\n"
+		if re.search('aborted_task\)\(', fo):
+			buf += "void " + fabric_mod_name + "_aborted_task(struct se_cmd *se_cmd)\n"
 			buf += "{\n"
 			buf += "{\n"
-			buf += "	return 0;\n"
+			buf += "	return;\n"
 			buf += "}\n\n"
 			buf += "}\n\n"
-			bufi += "int " + fabric_mod_name + "_is_state_remove(struct se_cmd *);\n"
-
+			bufi += "void " + fabric_mod_name + "_aborted_task(struct se_cmd *);\n"
 
 
 	ret = p.write(buf)
 	ret = p.write(buf)
 	if ret:
 	if ret:
@@ -1018,11 +993,11 @@ def main(modname, proto_ident):
 	tcm_mod_build_kbuild(fabric_mod_dir, fabric_mod_name)
 	tcm_mod_build_kbuild(fabric_mod_dir, fabric_mod_name)
 	tcm_mod_build_kconfig(fabric_mod_dir, fabric_mod_name)
 	tcm_mod_build_kconfig(fabric_mod_dir, fabric_mod_name)
 
 
-	input = raw_input("Would you like to add " + fabric_mod_name + "to drivers/target/Makefile..? [yes,no]: ")
+	input = raw_input("Would you like to add " + fabric_mod_name + " to drivers/target/Makefile..? [yes,no]: ")
 	if input == "yes" or input == "y":
 	if input == "yes" or input == "y":
 		tcm_mod_add_kbuild(tcm_dir, fabric_mod_name)
 		tcm_mod_add_kbuild(tcm_dir, fabric_mod_name)
 
 
-	input = raw_input("Would you like to add " + fabric_mod_name + "to drivers/target/Kconfig..? [yes,no]: ")
+	input = raw_input("Would you like to add " + fabric_mod_name + " to drivers/target/Kconfig..? [yes,no]: ")
 	if input == "yes" or input == "y":
 	if input == "yes" or input == "y":
 		tcm_mod_add_kconfig(tcm_dir, fabric_mod_name)
 		tcm_mod_add_kconfig(tcm_dir, fabric_mod_name)
 
 

+ 16 - 6
MAINTAINERS

@@ -724,15 +724,15 @@ F:	include/uapi/linux/apm_bios.h
 F:	drivers/char/apm-emulation.c
 F:	drivers/char/apm-emulation.c
 
 
 APPLE BCM5974 MULTITOUCH DRIVER
 APPLE BCM5974 MULTITOUCH DRIVER
-M:	Henrik Rydberg <rydberg@euromail.se>
+M:	Henrik Rydberg <rydberg@bitmath.org>
 L:	linux-input@vger.kernel.org
 L:	linux-input@vger.kernel.org
-S:	Maintained
+S:	Odd fixes
 F:	drivers/input/mouse/bcm5974.c
 F:	drivers/input/mouse/bcm5974.c
 
 
 APPLE SMC DRIVER
 APPLE SMC DRIVER
-M:	Henrik Rydberg <rydberg@euromail.se>
+M:	Henrik Rydberg <rydberg@bitmath.org>
 L:	lm-sensors@lm-sensors.org
 L:	lm-sensors@lm-sensors.org
-S:	Maintained
+S:	Odd fixes
 F:	drivers/hwmon/applesmc.c
 F:	drivers/hwmon/applesmc.c
 
 
 APPLETALK NETWORK LAYER
 APPLETALK NETWORK LAYER
@@ -2259,6 +2259,7 @@ F:	drivers/gpio/gpio-bt8xx.c
 BTRFS FILE SYSTEM
 BTRFS FILE SYSTEM
 M:	Chris Mason <clm@fb.com>
 M:	Chris Mason <clm@fb.com>
 M:	Josef Bacik <jbacik@fb.com>
 M:	Josef Bacik <jbacik@fb.com>
+M:	David Sterba <dsterba@suse.cz>
 L:	linux-btrfs@vger.kernel.org
 L:	linux-btrfs@vger.kernel.org
 W:	http://btrfs.wiki.kernel.org/
 W:	http://btrfs.wiki.kernel.org/
 Q:	http://patchwork.kernel.org/project/linux-btrfs/list/
 Q:	http://patchwork.kernel.org/project/linux-btrfs/list/
@@ -4940,10 +4941,10 @@ F:	include/uapi/linux/input.h
 F:	include/linux/input/
 F:	include/linux/input/
 
 
 INPUT MULTITOUCH (MT) PROTOCOL
 INPUT MULTITOUCH (MT) PROTOCOL
-M:	Henrik Rydberg <rydberg@euromail.se>
+M:	Henrik Rydberg <rydberg@bitmath.org>
 L:	linux-input@vger.kernel.org
 L:	linux-input@vger.kernel.org
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/rydberg/input-mt.git
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/rydberg/input-mt.git
-S:	Maintained
+S:	Odd fixes
 F:	Documentation/input/multi-touch-protocol.txt
 F:	Documentation/input/multi-touch-protocol.txt
 F:	drivers/input/input-mt.c
 F:	drivers/input/input-mt.c
 K:	\b(ABS|SYN)_MT_
 K:	\b(ABS|SYN)_MT_
@@ -5279,6 +5280,15 @@ W:	www.open-iscsi.org
 Q:	http://patchwork.kernel.org/project/linux-rdma/list/
 Q:	http://patchwork.kernel.org/project/linux-rdma/list/
 F:	drivers/infiniband/ulp/iser/
 F:	drivers/infiniband/ulp/iser/
 
 
+ISCSI EXTENSIONS FOR RDMA (ISER) TARGET
+M:	Sagi Grimberg <sagig@mellanox.com>
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git master
+L:	linux-rdma@vger.kernel.org
+L:	target-devel@vger.kernel.org
+S:	Supported
+W:	http://www.linux-iscsi.org
+F:	drivers/infiniband/ulp/isert
+
 ISDN SUBSYSTEM
 ISDN SUBSYSTEM
 M:	Karsten Keil <isdn@linux-pingi.de>
 M:	Karsten Keil <isdn@linux-pingi.de>
 L:	isdn4linux@listserv.isdn4linux.de (subscribers-only)
 L:	isdn4linux@listserv.isdn4linux.de (subscribers-only)

+ 2 - 1
Makefile

@@ -1,7 +1,7 @@
 VERSION = 3
 VERSION = 3
 PATCHLEVEL = 19
 PATCHLEVEL = 19
 SUBLEVEL = 0
 SUBLEVEL = 0
-EXTRAVERSION = -rc2
+EXTRAVERSION = -rc4
 NAME = Diseased Newt
 NAME = Diseased Newt
 
 
 # *DOCUMENTATION*
 # *DOCUMENTATION*
@@ -391,6 +391,7 @@ USERINCLUDE    := \
 # Needed to be compatible with the O= option
 # Needed to be compatible with the O= option
 LINUXINCLUDE    := \
 LINUXINCLUDE    := \
 		-I$(srctree)/arch/$(hdr-arch)/include \
 		-I$(srctree)/arch/$(hdr-arch)/include \
+		-Iarch/$(hdr-arch)/include/generated/uapi \
 		-Iarch/$(hdr-arch)/include/generated \
 		-Iarch/$(hdr-arch)/include/generated \
 		$(if $(KBUILD_SRC), -I$(srctree)/include) \
 		$(if $(KBUILD_SRC), -I$(srctree)/include) \
 		-Iinclude \
 		-Iinclude \

+ 1 - 0
arch/arm/include/uapi/asm/unistd.h

@@ -413,6 +413,7 @@
 #define __NR_getrandom			(__NR_SYSCALL_BASE+384)
 #define __NR_getrandom			(__NR_SYSCALL_BASE+384)
 #define __NR_memfd_create		(__NR_SYSCALL_BASE+385)
 #define __NR_memfd_create		(__NR_SYSCALL_BASE+385)
 #define __NR_bpf			(__NR_SYSCALL_BASE+386)
 #define __NR_bpf			(__NR_SYSCALL_BASE+386)
+#define __NR_execveat			(__NR_SYSCALL_BASE+387)
 
 
 /*
 /*
  * The following SWIs are ARM private.
  * The following SWIs are ARM private.

+ 1 - 0
arch/arm/kernel/calls.S

@@ -396,6 +396,7 @@
 		CALL(sys_getrandom)
 		CALL(sys_getrandom)
 /* 385 */	CALL(sys_memfd_create)
 /* 385 */	CALL(sys_memfd_create)
 		CALL(sys_bpf)
 		CALL(sys_bpf)
+		CALL(sys_execveat)
 #ifndef syscalls_counted
 #ifndef syscalls_counted
 .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
 .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
 #define syscalls_counted
 #define syscalls_counted

+ 8 - 0
arch/arm/kernel/perf_regs.c

@@ -28,3 +28,11 @@ u64 perf_reg_abi(struct task_struct *task)
 {
 {
 	return PERF_SAMPLE_REGS_ABI_32;
 	return PERF_SAMPLE_REGS_ABI_32;
 }
 }
+
+void perf_get_regs_user(struct perf_regs *regs_user,
+			struct pt_regs *regs,
+			struct pt_regs *regs_user_copy)
+{
+	regs_user->regs = task_pt_regs(current);
+	regs_user->abi = perf_reg_abi(current);
+}

+ 2 - 7
arch/arm/mm/dump.c

@@ -220,9 +220,6 @@ static void note_page(struct pg_state *st, unsigned long addr, unsigned level, u
 	static const char units[] = "KMGTPE";
 	static const char units[] = "KMGTPE";
 	u64 prot = val & pg_level[level].mask;
 	u64 prot = val & pg_level[level].mask;
 
 
-	if (addr < USER_PGTABLES_CEILING)
-		return;
-
 	if (!st->level) {
 	if (!st->level) {
 		st->level = level;
 		st->level = level;
 		st->current_prot = prot;
 		st->current_prot = prot;
@@ -308,15 +305,13 @@ static void walk_pgd(struct seq_file *m)
 	pgd_t *pgd = swapper_pg_dir;
 	pgd_t *pgd = swapper_pg_dir;
 	struct pg_state st;
 	struct pg_state st;
 	unsigned long addr;
 	unsigned long addr;
-	unsigned i, pgdoff = USER_PGTABLES_CEILING / PGDIR_SIZE;
+	unsigned i;
 
 
 	memset(&st, 0, sizeof(st));
 	memset(&st, 0, sizeof(st));
 	st.seq = m;
 	st.seq = m;
 	st.marker = address_markers;
 	st.marker = address_markers;
 
 
-	pgd += pgdoff;
-
-	for (i = pgdoff; i < PTRS_PER_PGD; i++, pgd++) {
+	for (i = 0; i < PTRS_PER_PGD; i++, pgd++) {
 		addr = i * PGDIR_SIZE;
 		addr = i * PGDIR_SIZE;
 		if (!pgd_none(*pgd)) {
 		if (!pgd_none(*pgd)) {
 			walk_pud(&st, pgd, addr);
 			walk_pud(&st, pgd, addr);

+ 2 - 2
arch/arm/mm/init.c

@@ -658,8 +658,8 @@ static struct section_perm ro_perms[] = {
 		.start  = (unsigned long)_stext,
 		.start  = (unsigned long)_stext,
 		.end    = (unsigned long)__init_begin,
 		.end    = (unsigned long)__init_begin,
 #ifdef CONFIG_ARM_LPAE
 #ifdef CONFIG_ARM_LPAE
-		.mask   = ~PMD_SECT_RDONLY,
-		.prot   = PMD_SECT_RDONLY,
+		.mask   = ~L_PMD_SECT_RDONLY,
+		.prot   = L_PMD_SECT_RDONLY,
 #else
 #else
 		.mask   = ~(PMD_SECT_APX | PMD_SECT_AP_WRITE),
 		.mask   = ~(PMD_SECT_APX | PMD_SECT_AP_WRITE),
 		.prot   = PMD_SECT_APX | PMD_SECT_AP_WRITE,
 		.prot   = PMD_SECT_APX | PMD_SECT_AP_WRITE,

+ 2 - 2
arch/arm/mm/mmu.c

@@ -1329,8 +1329,8 @@ static void __init kmap_init(void)
 static void __init map_lowmem(void)
 static void __init map_lowmem(void)
 {
 {
 	struct memblock_region *reg;
 	struct memblock_region *reg;
-	unsigned long kernel_x_start = round_down(__pa(_stext), SECTION_SIZE);
-	unsigned long kernel_x_end = round_up(__pa(__init_end), SECTION_SIZE);
+	phys_addr_t kernel_x_start = round_down(__pa(_stext), SECTION_SIZE);
+	phys_addr_t kernel_x_end = round_up(__pa(__init_end), SECTION_SIZE);
 
 
 	/* Map all the lowmem memory banks. */
 	/* Map all the lowmem memory banks. */
 	for_each_memblock(memory, reg) {
 	for_each_memblock(memory, reg) {

+ 1 - 0
arch/arm64/include/asm/arch_timer.h

@@ -21,6 +21,7 @@
 
 
 #include <asm/barrier.h>
 #include <asm/barrier.h>
 
 
+#include <linux/bug.h>
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/types.h>
 
 

+ 5 - 0
arch/arm64/include/asm/cpu.h

@@ -39,6 +39,7 @@ struct cpuinfo_arm64 {
 	u64		reg_id_aa64pfr0;
 	u64		reg_id_aa64pfr0;
 	u64		reg_id_aa64pfr1;
 	u64		reg_id_aa64pfr1;
 
 
+	u32		reg_id_dfr0;
 	u32		reg_id_isar0;
 	u32		reg_id_isar0;
 	u32		reg_id_isar1;
 	u32		reg_id_isar1;
 	u32		reg_id_isar2;
 	u32		reg_id_isar2;
@@ -51,6 +52,10 @@ struct cpuinfo_arm64 {
 	u32		reg_id_mmfr3;
 	u32		reg_id_mmfr3;
 	u32		reg_id_pfr0;
 	u32		reg_id_pfr0;
 	u32		reg_id_pfr1;
 	u32		reg_id_pfr1;
+
+	u32		reg_mvfr0;
+	u32		reg_mvfr1;
+	u32		reg_mvfr2;
 };
 };
 
 
 DECLARE_PER_CPU(struct cpuinfo_arm64, cpu_data);
 DECLARE_PER_CPU(struct cpuinfo_arm64, cpu_data);

+ 1 - 3
arch/arm64/include/asm/processor.h

@@ -31,6 +31,7 @@
 
 
 #include <asm/fpsimd.h>
 #include <asm/fpsimd.h>
 #include <asm/hw_breakpoint.h>
 #include <asm/hw_breakpoint.h>
+#include <asm/pgtable-hwdef.h>
 #include <asm/ptrace.h>
 #include <asm/ptrace.h>
 #include <asm/types.h>
 #include <asm/types.h>
 
 
@@ -123,9 +124,6 @@ struct task_struct;
 /* Free all resources held by a thread. */
 /* Free all resources held by a thread. */
 extern void release_thread(struct task_struct *);
 extern void release_thread(struct task_struct *);
 
 
-/* Prepare to copy thread state - unlazy all lazy status */
-#define prepare_to_copy(tsk)	do { } while (0)
-
 unsigned long get_wchan(struct task_struct *p);
 unsigned long get_wchan(struct task_struct *p);
 
 
 #define cpu_relax()			barrier()
 #define cpu_relax()			barrier()

+ 1 - 1
arch/arm64/include/asm/unistd.h

@@ -44,7 +44,7 @@
 #define __ARM_NR_compat_cacheflush	(__ARM_NR_COMPAT_BASE+2)
 #define __ARM_NR_compat_cacheflush	(__ARM_NR_COMPAT_BASE+2)
 #define __ARM_NR_compat_set_tls		(__ARM_NR_COMPAT_BASE+5)
 #define __ARM_NR_compat_set_tls		(__ARM_NR_COMPAT_BASE+5)
 
 
-#define __NR_compat_syscalls		386
+#define __NR_compat_syscalls		387
 #endif
 #endif
 
 
 #define __ARCH_WANT_SYS_CLONE
 #define __ARCH_WANT_SYS_CLONE

+ 10 - 0
arch/arm64/kernel/cpuinfo.c

@@ -147,6 +147,7 @@ static void cpuinfo_sanity_check(struct cpuinfo_arm64 *cur)
 	 * If we have AArch32, we care about 32-bit features for compat. These
 	 * If we have AArch32, we care about 32-bit features for compat. These
 	 * registers should be RES0 otherwise.
 	 * registers should be RES0 otherwise.
 	 */
 	 */
+	diff |= CHECK(id_dfr0, boot, cur, cpu);
 	diff |= CHECK(id_isar0, boot, cur, cpu);
 	diff |= CHECK(id_isar0, boot, cur, cpu);
 	diff |= CHECK(id_isar1, boot, cur, cpu);
 	diff |= CHECK(id_isar1, boot, cur, cpu);
 	diff |= CHECK(id_isar2, boot, cur, cpu);
 	diff |= CHECK(id_isar2, boot, cur, cpu);
@@ -165,6 +166,10 @@ static void cpuinfo_sanity_check(struct cpuinfo_arm64 *cur)
 	diff |= CHECK(id_pfr0, boot, cur, cpu);
 	diff |= CHECK(id_pfr0, boot, cur, cpu);
 	diff |= CHECK(id_pfr1, boot, cur, cpu);
 	diff |= CHECK(id_pfr1, boot, cur, cpu);
 
 
+	diff |= CHECK(mvfr0, boot, cur, cpu);
+	diff |= CHECK(mvfr1, boot, cur, cpu);
+	diff |= CHECK(mvfr2, boot, cur, cpu);
+
 	/*
 	/*
 	 * Mismatched CPU features are a recipe for disaster. Don't even
 	 * Mismatched CPU features are a recipe for disaster. Don't even
 	 * pretend to support them.
 	 * pretend to support them.
@@ -189,6 +194,7 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
 	info->reg_id_aa64pfr0 = read_cpuid(ID_AA64PFR0_EL1);
 	info->reg_id_aa64pfr0 = read_cpuid(ID_AA64PFR0_EL1);
 	info->reg_id_aa64pfr1 = read_cpuid(ID_AA64PFR1_EL1);
 	info->reg_id_aa64pfr1 = read_cpuid(ID_AA64PFR1_EL1);
 
 
+	info->reg_id_dfr0 = read_cpuid(ID_DFR0_EL1);
 	info->reg_id_isar0 = read_cpuid(ID_ISAR0_EL1);
 	info->reg_id_isar0 = read_cpuid(ID_ISAR0_EL1);
 	info->reg_id_isar1 = read_cpuid(ID_ISAR1_EL1);
 	info->reg_id_isar1 = read_cpuid(ID_ISAR1_EL1);
 	info->reg_id_isar2 = read_cpuid(ID_ISAR2_EL1);
 	info->reg_id_isar2 = read_cpuid(ID_ISAR2_EL1);
@@ -202,6 +208,10 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
 	info->reg_id_pfr0 = read_cpuid(ID_PFR0_EL1);
 	info->reg_id_pfr0 = read_cpuid(ID_PFR0_EL1);
 	info->reg_id_pfr1 = read_cpuid(ID_PFR1_EL1);
 	info->reg_id_pfr1 = read_cpuid(ID_PFR1_EL1);
 
 
+	info->reg_mvfr0 = read_cpuid(MVFR0_EL1);
+	info->reg_mvfr1 = read_cpuid(MVFR1_EL1);
+	info->reg_mvfr2 = read_cpuid(MVFR2_EL1);
+
 	cpuinfo_detect_icache_policy(info);
 	cpuinfo_detect_icache_policy(info);
 
 
 	check_local_cpu_errata();
 	check_local_cpu_errata();

+ 1 - 1
arch/arm64/kernel/efi.c

@@ -326,6 +326,7 @@ void __init efi_idmap_init(void)
 
 
 	/* boot time idmap_pg_dir is incomplete, so fill in missing parts */
 	/* boot time idmap_pg_dir is incomplete, so fill in missing parts */
 	efi_setup_idmap();
 	efi_setup_idmap();
+	early_memunmap(memmap.map, memmap.map_end - memmap.map);
 }
 }
 
 
 static int __init remap_region(efi_memory_desc_t *md, void **new)
 static int __init remap_region(efi_memory_desc_t *md, void **new)
@@ -380,7 +381,6 @@ static int __init arm64_enter_virtual_mode(void)
 	}
 	}
 
 
 	mapsize = memmap.map_end - memmap.map;
 	mapsize = memmap.map_end - memmap.map;
-	early_memunmap(memmap.map, mapsize);
 
 
 	if (efi_runtime_disabled()) {
 	if (efi_runtime_disabled()) {
 		pr_info("EFI runtime services will be disabled.\n");
 		pr_info("EFI runtime services will be disabled.\n");

+ 1 - 0
arch/arm64/kernel/module.c

@@ -25,6 +25,7 @@
 #include <linux/mm.h>
 #include <linux/mm.h>
 #include <linux/moduleloader.h>
 #include <linux/moduleloader.h>
 #include <linux/vmalloc.h>
 #include <linux/vmalloc.h>
+#include <asm/alternative.h>
 #include <asm/insn.h>
 #include <asm/insn.h>
 #include <asm/sections.h>
 #include <asm/sections.h>
 
 

+ 8 - 0
arch/arm64/kernel/perf_regs.c

@@ -50,3 +50,11 @@ u64 perf_reg_abi(struct task_struct *task)
 	else
 	else
 		return PERF_SAMPLE_REGS_ABI_64;
 		return PERF_SAMPLE_REGS_ABI_64;
 }
 }
+
+void perf_get_regs_user(struct perf_regs *regs_user,
+			struct pt_regs *regs,
+			struct pt_regs *regs_user_copy)
+{
+	regs_user->regs = task_pt_regs(current);
+	regs_user->abi = perf_reg_abi(current);
+}

+ 1 - 0
arch/arm64/kernel/setup.c

@@ -402,6 +402,7 @@ void __init setup_arch(char **cmdline_p)
 	request_standard_resources();
 	request_standard_resources();
 
 
 	efi_idmap_init();
 	efi_idmap_init();
+	early_ioremap_reset();
 
 
 	unflatten_device_tree();
 	unflatten_device_tree();
 
 

+ 1 - 0
arch/arm64/kernel/smp_spin_table.c

@@ -25,6 +25,7 @@
 #include <asm/cacheflush.h>
 #include <asm/cacheflush.h>
 #include <asm/cpu_ops.h>
 #include <asm/cpu_ops.h>
 #include <asm/cputype.h>
 #include <asm/cputype.h>
+#include <asm/io.h>
 #include <asm/smp_plat.h>
 #include <asm/smp_plat.h>
 
 
 extern void secondary_holding_pen(void);
 extern void secondary_holding_pen(void);

+ 1 - 0
arch/blackfin/mach-bf533/boards/stamp.c

@@ -7,6 +7,7 @@
  */
  */
 
 
 #include <linux/device.h>
 #include <linux/device.h>
+#include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/partitions.h>

+ 1 - 1
arch/ia64/include/asm/unistd.h

@@ -11,7 +11,7 @@
 
 
 
 
 
 
-#define NR_syscalls			318 /* length of syscall table */
+#define NR_syscalls			319 /* length of syscall table */
 
 
 /*
 /*
  * The following defines stop scripts/checksyscalls.sh from complaining about
  * The following defines stop scripts/checksyscalls.sh from complaining about

+ 1 - 0
arch/ia64/include/uapi/asm/unistd.h

@@ -331,5 +331,6 @@
 #define __NR_getrandom			1339
 #define __NR_getrandom			1339
 #define __NR_memfd_create		1340
 #define __NR_memfd_create		1340
 #define __NR_bpf			1341
 #define __NR_bpf			1341
+#define __NR_execveat			1342
 
 
 #endif /* _UAPI_ASM_IA64_UNISTD_H */
 #endif /* _UAPI_ASM_IA64_UNISTD_H */

+ 4 - 5
arch/ia64/kernel/acpi.c

@@ -893,13 +893,13 @@ static int _acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu)
 }
 }
 
 
 /* wrapper to silence section mismatch warning */
 /* wrapper to silence section mismatch warning */
-int __ref acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu)
+int __ref acpi_map_cpu(acpi_handle handle, int physid, int *pcpu)
 {
 {
 	return _acpi_map_lsapic(handle, physid, pcpu);
 	return _acpi_map_lsapic(handle, physid, pcpu);
 }
 }
-EXPORT_SYMBOL(acpi_map_lsapic);
+EXPORT_SYMBOL(acpi_map_cpu);
 
 
-int acpi_unmap_lsapic(int cpu)
+int acpi_unmap_cpu(int cpu)
 {
 {
 	ia64_cpu_to_sapicid[cpu] = -1;
 	ia64_cpu_to_sapicid[cpu] = -1;
 	set_cpu_present(cpu, false);
 	set_cpu_present(cpu, false);
@@ -910,8 +910,7 @@ int acpi_unmap_lsapic(int cpu)
 
 
 	return (0);
 	return (0);
 }
 }
-
-EXPORT_SYMBOL(acpi_unmap_lsapic);
+EXPORT_SYMBOL(acpi_unmap_cpu);
 #endif				/* CONFIG_ACPI_HOTPLUG_CPU */
 #endif				/* CONFIG_ACPI_HOTPLUG_CPU */
 
 
 #ifdef CONFIG_ACPI_NUMA
 #ifdef CONFIG_ACPI_NUMA

+ 1 - 0
arch/ia64/kernel/entry.S

@@ -1779,6 +1779,7 @@ sys_call_table:
 	data8 sys_getrandom
 	data8 sys_getrandom
 	data8 sys_memfd_create			// 1340
 	data8 sys_memfd_create			// 1340
 	data8 sys_bpf
 	data8 sys_bpf
+	data8 sys_execveat
 
 
 	.org sys_call_table + 8*NR_syscalls	// guard against failures to increase NR_syscalls
 	.org sys_call_table + 8*NR_syscalls	// guard against failures to increase NR_syscalls
 #endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
 #endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */

+ 10 - 0
arch/powerpc/include/asm/kexec.h

@@ -86,6 +86,11 @@ extern int overlaps_crashkernel(unsigned long start, unsigned long size);
 extern void reserve_crashkernel(void);
 extern void reserve_crashkernel(void);
 extern void machine_kexec_mask_interrupts(void);
 extern void machine_kexec_mask_interrupts(void);
 
 
+static inline bool kdump_in_progress(void)
+{
+	return crashing_cpu >= 0;
+}
+
 #else /* !CONFIG_KEXEC */
 #else /* !CONFIG_KEXEC */
 static inline void crash_kexec_secondary(struct pt_regs *regs) { }
 static inline void crash_kexec_secondary(struct pt_regs *regs) { }
 
 
@@ -106,6 +111,11 @@ static inline int crash_shutdown_unregister(crash_shutdown_t handler)
 	return 0;
 	return 0;
 }
 }
 
 
+static inline bool kdump_in_progress(void)
+{
+	return false;
+}
+
 #endif /* CONFIG_KEXEC */
 #endif /* CONFIG_KEXEC */
 #endif /* ! __ASSEMBLY__ */
 #endif /* ! __ASSEMBLY__ */
 #endif /* __KERNEL__ */
 #endif /* __KERNEL__ */

+ 1 - 0
arch/powerpc/include/asm/systbl.h

@@ -366,3 +366,4 @@ SYSCALL_SPU(seccomp)
 SYSCALL_SPU(getrandom)
 SYSCALL_SPU(getrandom)
 SYSCALL_SPU(memfd_create)
 SYSCALL_SPU(memfd_create)
 SYSCALL_SPU(bpf)
 SYSCALL_SPU(bpf)
+COMPAT_SYS(execveat)

+ 1 - 1
arch/powerpc/include/asm/unistd.h

@@ -12,7 +12,7 @@
 #include <uapi/asm/unistd.h>
 #include <uapi/asm/unistd.h>
 
 
 
 
-#define __NR_syscalls		362
+#define __NR_syscalls		363
 
 
 #define __NR__exit __NR_exit
 #define __NR__exit __NR_exit
 #define NR_syscalls	__NR_syscalls
 #define NR_syscalls	__NR_syscalls

+ 1 - 0
arch/powerpc/include/uapi/asm/unistd.h

@@ -384,5 +384,6 @@
 #define __NR_getrandom		359
 #define __NR_getrandom		359
 #define __NR_memfd_create	360
 #define __NR_memfd_create	360
 #define __NR_bpf		361
 #define __NR_bpf		361
+#define __NR_execveat		362
 
 
 #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */
 #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */

+ 1 - 1
arch/powerpc/kernel/machine_kexec_64.c

@@ -330,7 +330,7 @@ void default_machine_kexec(struct kimage *image)
         * using debugger IPI.
         * using debugger IPI.
         */
         */
 
 
-	if (crashing_cpu == -1)
+	if (!kdump_in_progress())
 		kexec_prepare_cpus();
 		kexec_prepare_cpus();
 
 
 	pr_debug("kexec: Starting switchover sequence.\n");
 	pr_debug("kexec: Starting switchover sequence.\n");

+ 1 - 8
arch/powerpc/kernel/smp.c

@@ -700,6 +700,7 @@ void start_secondary(void *unused)
 	smp_store_cpu_info(cpu);
 	smp_store_cpu_info(cpu);
 	set_dec(tb_ticks_per_jiffy);
 	set_dec(tb_ticks_per_jiffy);
 	preempt_disable();
 	preempt_disable();
+	cpu_callin_map[cpu] = 1;
 
 
 	if (smp_ops->setup_cpu)
 	if (smp_ops->setup_cpu)
 		smp_ops->setup_cpu(cpu);
 		smp_ops->setup_cpu(cpu);
@@ -738,14 +739,6 @@ void start_secondary(void *unused)
 	notify_cpu_starting(cpu);
 	notify_cpu_starting(cpu);
 	set_cpu_online(cpu, true);
 	set_cpu_online(cpu, true);
 
 
-	/*
-	 * CPU must be marked active and online before we signal back to the
-	 * master, because the scheduler needs to see the cpu_online and
-	 * cpu_active bits set.
-	 */
-	smp_wmb();
-	cpu_callin_map[cpu] = 1;
-
 	local_irq_enable();
 	local_irq_enable();
 
 
 	cpu_startup_entry(CPUHP_ONLINE);
 	cpu_startup_entry(CPUHP_ONLINE);

+ 7 - 1
arch/powerpc/platforms/pseries/lpar.c

@@ -43,6 +43,7 @@
 #include <asm/trace.h>
 #include <asm/trace.h>
 #include <asm/firmware.h>
 #include <asm/firmware.h>
 #include <asm/plpar_wrappers.h>
 #include <asm/plpar_wrappers.h>
+#include <asm/kexec.h>
 #include <asm/fadump.h>
 #include <asm/fadump.h>
 
 
 #include "pseries.h"
 #include "pseries.h"
@@ -267,8 +268,13 @@ static void pSeries_lpar_hptab_clear(void)
 		 * out to the user, but at least this will stop us from
 		 * out to the user, but at least this will stop us from
 		 * continuing on further and creating an even more
 		 * continuing on further and creating an even more
 		 * difficult to debug situation.
 		 * difficult to debug situation.
+		 *
+		 * There is a known problem when kdump'ing, if cpus are offline
+		 * the above call will fail. Rather than panicking again, keep
+		 * going and hope the kdump kernel is also little endian, which
+		 * it usually is.
 		 */
 		 */
-		if (rc)
+		if (rc && !kdump_in_progress())
 			panic("Could not enable big endian exceptions");
 			panic("Could not enable big endian exceptions");
 	}
 	}
 #endif
 #endif

+ 1 - 0
arch/x86/boot/Makefile

@@ -51,6 +51,7 @@ targets += cpustr.h
 $(obj)/cpustr.h: $(obj)/mkcpustr FORCE
 $(obj)/cpustr.h: $(obj)/mkcpustr FORCE
 	$(call if_changed,cpustr)
 	$(call if_changed,cpustr)
 endif
 endif
+clean-files += cpustr.h
 
 
 # ---------------------------------------------------------------------------
 # ---------------------------------------------------------------------------
 
 

+ 1 - 1
arch/x86/crypto/Makefile

@@ -26,7 +26,6 @@ obj-$(CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL) += ghash-clmulni-intel.o
 
 
 obj-$(CONFIG_CRYPTO_CRC32C_INTEL) += crc32c-intel.o
 obj-$(CONFIG_CRYPTO_CRC32C_INTEL) += crc32c-intel.o
 obj-$(CONFIG_CRYPTO_SHA1_SSSE3) += sha1-ssse3.o
 obj-$(CONFIG_CRYPTO_SHA1_SSSE3) += sha1-ssse3.o
-obj-$(CONFIG_CRYPTO_SHA1_MB) += sha-mb/
 obj-$(CONFIG_CRYPTO_CRC32_PCLMUL) += crc32-pclmul.o
 obj-$(CONFIG_CRYPTO_CRC32_PCLMUL) += crc32-pclmul.o
 obj-$(CONFIG_CRYPTO_SHA256_SSSE3) += sha256-ssse3.o
 obj-$(CONFIG_CRYPTO_SHA256_SSSE3) += sha256-ssse3.o
 obj-$(CONFIG_CRYPTO_SHA512_SSSE3) += sha512-ssse3.o
 obj-$(CONFIG_CRYPTO_SHA512_SSSE3) += sha512-ssse3.o
@@ -46,6 +45,7 @@ endif
 ifeq ($(avx2_supported),yes)
 ifeq ($(avx2_supported),yes)
 	obj-$(CONFIG_CRYPTO_CAMELLIA_AESNI_AVX2_X86_64) += camellia-aesni-avx2.o
 	obj-$(CONFIG_CRYPTO_CAMELLIA_AESNI_AVX2_X86_64) += camellia-aesni-avx2.o
 	obj-$(CONFIG_CRYPTO_SERPENT_AVX2_X86_64) += serpent-avx2.o
 	obj-$(CONFIG_CRYPTO_SERPENT_AVX2_X86_64) += serpent-avx2.o
+	obj-$(CONFIG_CRYPTO_SHA1_MB) += sha-mb/
 endif
 endif
 
 
 aes-i586-y := aes-i586-asm_32.o aes_glue.o
 aes-i586-y := aes-i586-asm_32.o aes_glue.o

+ 35 - 11
arch/x86/crypto/aes_ctrby8_avx-x86_64.S

@@ -208,7 +208,7 @@ ddq_add_8:
 
 
 	.if (klen == KEY_128)
 	.if (klen == KEY_128)
 		.if (load_keys)
 		.if (load_keys)
-			vmovdqa	3*16(p_keys), xkeyA
+			vmovdqa	3*16(p_keys), xkey4
 		.endif
 		.endif
 	.else
 	.else
 		vmovdqa	3*16(p_keys), xkeyA
 		vmovdqa	3*16(p_keys), xkeyA
@@ -224,7 +224,7 @@ ddq_add_8:
 	add	$(16*by), p_in
 	add	$(16*by), p_in
 
 
 	.if (klen == KEY_128)
 	.if (klen == KEY_128)
-		vmovdqa	4*16(p_keys), xkey4
+		vmovdqa	4*16(p_keys), xkeyB
 	.else
 	.else
 		.if (load_keys)
 		.if (load_keys)
 			vmovdqa	4*16(p_keys), xkey4
 			vmovdqa	4*16(p_keys), xkey4
@@ -234,7 +234,12 @@ ddq_add_8:
 	.set i, 0
 	.set i, 0
 	.rept by
 	.rept by
 		club XDATA, i
 		club XDATA, i
-		vaesenc	xkeyA, var_xdata, var_xdata		/* key 3 */
+		/* key 3 */
+		.if (klen == KEY_128)
+			vaesenc	xkey4, var_xdata, var_xdata
+		.else
+			vaesenc	xkeyA, var_xdata, var_xdata
+		.endif
 		.set i, (i +1)
 		.set i, (i +1)
 	.endr
 	.endr
 
 
@@ -243,13 +248,18 @@ ddq_add_8:
 	.set i, 0
 	.set i, 0
 	.rept by
 	.rept by
 		club XDATA, i
 		club XDATA, i
-		vaesenc	xkey4, var_xdata, var_xdata		/* key 4 */
+		/* key 4 */
+		.if (klen == KEY_128)
+			vaesenc	xkeyB, var_xdata, var_xdata
+		.else
+			vaesenc	xkey4, var_xdata, var_xdata
+		.endif
 		.set i, (i +1)
 		.set i, (i +1)
 	.endr
 	.endr
 
 
 	.if (klen == KEY_128)
 	.if (klen == KEY_128)
 		.if (load_keys)
 		.if (load_keys)
-			vmovdqa	6*16(p_keys), xkeyB
+			vmovdqa	6*16(p_keys), xkey8
 		.endif
 		.endif
 	.else
 	.else
 		vmovdqa	6*16(p_keys), xkeyB
 		vmovdqa	6*16(p_keys), xkeyB
@@ -267,12 +277,17 @@ ddq_add_8:
 	.set i, 0
 	.set i, 0
 	.rept by
 	.rept by
 		club XDATA, i
 		club XDATA, i
-		vaesenc	xkeyB, var_xdata, var_xdata		/* key 6 */
+		/* key 6 */
+		.if (klen == KEY_128)
+			vaesenc	xkey8, var_xdata, var_xdata
+		.else
+			vaesenc	xkeyB, var_xdata, var_xdata
+		.endif
 		.set i, (i +1)
 		.set i, (i +1)
 	.endr
 	.endr
 
 
 	.if (klen == KEY_128)
 	.if (klen == KEY_128)
-		vmovdqa	8*16(p_keys), xkey8
+		vmovdqa	8*16(p_keys), xkeyB
 	.else
 	.else
 		.if (load_keys)
 		.if (load_keys)
 			vmovdqa	8*16(p_keys), xkey8
 			vmovdqa	8*16(p_keys), xkey8
@@ -288,7 +303,7 @@ ddq_add_8:
 
 
 	.if (klen == KEY_128)
 	.if (klen == KEY_128)
 		.if (load_keys)
 		.if (load_keys)
-			vmovdqa	9*16(p_keys), xkeyA
+			vmovdqa	9*16(p_keys), xkey12
 		.endif
 		.endif
 	.else
 	.else
 		vmovdqa	9*16(p_keys), xkeyA
 		vmovdqa	9*16(p_keys), xkeyA
@@ -297,7 +312,12 @@ ddq_add_8:
 	.set i, 0
 	.set i, 0
 	.rept by
 	.rept by
 		club XDATA, i
 		club XDATA, i
-		vaesenc	xkey8, var_xdata, var_xdata		/* key 8 */
+		/* key 8 */
+		.if (klen == KEY_128)
+			vaesenc	xkeyB, var_xdata, var_xdata
+		.else
+			vaesenc	xkey8, var_xdata, var_xdata
+		.endif
 		.set i, (i +1)
 		.set i, (i +1)
 	.endr
 	.endr
 
 
@@ -306,7 +326,12 @@ ddq_add_8:
 	.set i, 0
 	.set i, 0
 	.rept by
 	.rept by
 		club XDATA, i
 		club XDATA, i
-		vaesenc	xkeyA, var_xdata, var_xdata		/* key 9 */
+		/* key 9 */
+		.if (klen == KEY_128)
+			vaesenc	xkey12, var_xdata, var_xdata
+		.else
+			vaesenc	xkeyA, var_xdata, var_xdata
+		.endif
 		.set i, (i +1)
 		.set i, (i +1)
 	.endr
 	.endr
 
 
@@ -412,7 +437,6 @@ ddq_add_8:
 /* main body of aes ctr load */
 /* main body of aes ctr load */
 
 
 .macro do_aes_ctrmain key_len
 .macro do_aes_ctrmain key_len
-
 	cmp	$16, num_bytes
 	cmp	$16, num_bytes
 	jb	.Ldo_return2\key_len
 	jb	.Ldo_return2\key_len
 
 

+ 4 - 2
arch/x86/include/asm/vgtod.h

@@ -80,9 +80,11 @@ static inline unsigned int __getcpu(void)
 
 
 	/*
 	/*
 	 * Load per CPU data from GDT.  LSL is faster than RDTSCP and
 	 * Load per CPU data from GDT.  LSL is faster than RDTSCP and
-	 * works on all CPUs.
+	 * works on all CPUs.  This is volatile so that it orders
+	 * correctly wrt barrier() and to keep gcc from cleverly
+	 * hoisting it out of the calling function.
 	 */
 	 */
-	asm("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG));
+	asm volatile ("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG));
 
 
 	return p;
 	return p;
 }
 }

+ 4 - 5
arch/x86/kernel/acpi/boot.c

@@ -750,13 +750,13 @@ static int _acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu)
 }
 }
 
 
 /* wrapper to silence section mismatch warning */
 /* wrapper to silence section mismatch warning */
-int __ref acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu)
+int __ref acpi_map_cpu(acpi_handle handle, int physid, int *pcpu)
 {
 {
 	return _acpi_map_lsapic(handle, physid, pcpu);
 	return _acpi_map_lsapic(handle, physid, pcpu);
 }
 }
-EXPORT_SYMBOL(acpi_map_lsapic);
+EXPORT_SYMBOL(acpi_map_cpu);
 
 
-int acpi_unmap_lsapic(int cpu)
+int acpi_unmap_cpu(int cpu)
 {
 {
 #ifdef CONFIG_ACPI_NUMA
 #ifdef CONFIG_ACPI_NUMA
 	set_apicid_to_node(per_cpu(x86_cpu_to_apicid, cpu), NUMA_NO_NODE);
 	set_apicid_to_node(per_cpu(x86_cpu_to_apicid, cpu), NUMA_NO_NODE);
@@ -768,8 +768,7 @@ int acpi_unmap_lsapic(int cpu)
 
 
 	return (0);
 	return (0);
 }
 }
-
-EXPORT_SYMBOL(acpi_unmap_lsapic);
+EXPORT_SYMBOL(acpi_unmap_cpu);
 #endif				/* CONFIG_ACPI_HOTPLUG_CPU */
 #endif				/* CONFIG_ACPI_HOTPLUG_CPU */
 
 
 int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base)
 int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base)

+ 1 - 0
arch/x86/kernel/cpu/Makefile

@@ -66,3 +66,4 @@ targets += capflags.c
 $(obj)/capflags.c: $(cpufeature) $(src)/mkcapflags.sh FORCE
 $(obj)/capflags.c: $(cpufeature) $(src)/mkcapflags.sh FORCE
 	$(call if_changed,mkcapflags)
 	$(call if_changed,mkcapflags)
 endif
 endif
+clean-files += capflags.c

+ 1 - 1
arch/x86/kernel/cpu/mkcapflags.sh

@@ -28,7 +28,7 @@ function dump_array()
 		# If the /* comment */ starts with a quote string, grab that.
 		# If the /* comment */ starts with a quote string, grab that.
 		VALUE="$(echo "$i" | sed -n 's@.*/\* *\("[^"]*"\).*\*/@\1@p')"
 		VALUE="$(echo "$i" | sed -n 's@.*/\* *\("[^"]*"\).*\*/@\1@p')"
 		[ -z "$VALUE" ] && VALUE="\"$NAME\""
 		[ -z "$VALUE" ] && VALUE="\"$NAME\""
-		[ "$VALUE" == '""' ] && continue
+		[ "$VALUE" = '""' ] && continue
 
 
 		# Name is uppercase, VALUE is all lowercase
 		# Name is uppercase, VALUE is all lowercase
 		VALUE="$(echo "$VALUE" | tr A-Z a-z)"
 		VALUE="$(echo "$VALUE" | tr A-Z a-z)"

+ 1 - 1
arch/x86/kernel/cpu/perf_event_intel_uncore.h

@@ -17,7 +17,7 @@
 #define UNCORE_PCI_DEV_TYPE(data)	((data >> 8) & 0xff)
 #define UNCORE_PCI_DEV_TYPE(data)	((data >> 8) & 0xff)
 #define UNCORE_PCI_DEV_IDX(data)	(data & 0xff)
 #define UNCORE_PCI_DEV_IDX(data)	(data & 0xff)
 #define UNCORE_EXTRA_PCI_DEV		0xff
 #define UNCORE_EXTRA_PCI_DEV		0xff
-#define UNCORE_EXTRA_PCI_DEV_MAX	2
+#define UNCORE_EXTRA_PCI_DEV_MAX	3
 
 
 /* support up to 8 sockets */
 /* support up to 8 sockets */
 #define UNCORE_SOCKET_MAX		8
 #define UNCORE_SOCKET_MAX		8

+ 17 - 0
arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c

@@ -891,6 +891,7 @@ void snbep_uncore_cpu_init(void)
 enum {
 enum {
 	SNBEP_PCI_QPI_PORT0_FILTER,
 	SNBEP_PCI_QPI_PORT0_FILTER,
 	SNBEP_PCI_QPI_PORT1_FILTER,
 	SNBEP_PCI_QPI_PORT1_FILTER,
+	HSWEP_PCI_PCU_3,
 };
 };
 
 
 static int snbep_qpi_hw_config(struct intel_uncore_box *box, struct perf_event *event)
 static int snbep_qpi_hw_config(struct intel_uncore_box *box, struct perf_event *event)
@@ -2026,6 +2027,17 @@ void hswep_uncore_cpu_init(void)
 {
 {
 	if (hswep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
 	if (hswep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
 		hswep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
 		hswep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
+
+	/* Detect 6-8 core systems with only two SBOXes */
+	if (uncore_extra_pci_dev[0][HSWEP_PCI_PCU_3]) {
+		u32 capid4;
+
+		pci_read_config_dword(uncore_extra_pci_dev[0][HSWEP_PCI_PCU_3],
+				      0x94, &capid4);
+		if (((capid4 >> 6) & 0x3) == 0)
+			hswep_uncore_sbox.num_boxes = 2;
+	}
+
 	uncore_msr_uncores = hswep_msr_uncores;
 	uncore_msr_uncores = hswep_msr_uncores;
 }
 }
 
 
@@ -2287,6 +2299,11 @@ static DEFINE_PCI_DEVICE_TABLE(hswep_uncore_pci_ids) = {
 		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
 		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
 						   SNBEP_PCI_QPI_PORT1_FILTER),
 						   SNBEP_PCI_QPI_PORT1_FILTER),
 	},
 	},
+	{ /* PCU.3 (for Capability registers) */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fc0),
+		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
+						   HSWEP_PCI_PCU_3),
+	},
 	{ /* end: all zeroes */ }
 	{ /* end: all zeroes */ }
 };
 };
 
 

+ 90 - 0
arch/x86/kernel/perf_regs.c

@@ -78,6 +78,14 @@ u64 perf_reg_abi(struct task_struct *task)
 {
 {
 	return PERF_SAMPLE_REGS_ABI_32;
 	return PERF_SAMPLE_REGS_ABI_32;
 }
 }
+
+void perf_get_regs_user(struct perf_regs *regs_user,
+			struct pt_regs *regs,
+			struct pt_regs *regs_user_copy)
+{
+	regs_user->regs = task_pt_regs(current);
+	regs_user->abi = perf_reg_abi(current);
+}
 #else /* CONFIG_X86_64 */
 #else /* CONFIG_X86_64 */
 #define REG_NOSUPPORT ((1ULL << PERF_REG_X86_DS) | \
 #define REG_NOSUPPORT ((1ULL << PERF_REG_X86_DS) | \
 		       (1ULL << PERF_REG_X86_ES) | \
 		       (1ULL << PERF_REG_X86_ES) | \
@@ -102,4 +110,86 @@ u64 perf_reg_abi(struct task_struct *task)
 	else
 	else
 		return PERF_SAMPLE_REGS_ABI_64;
 		return PERF_SAMPLE_REGS_ABI_64;
 }
 }
+
+void perf_get_regs_user(struct perf_regs *regs_user,
+			struct pt_regs *regs,
+			struct pt_regs *regs_user_copy)
+{
+	struct pt_regs *user_regs = task_pt_regs(current);
+
+	/*
+	 * If we're in an NMI that interrupted task_pt_regs setup, then
+	 * we can't sample user regs at all.  This check isn't really
+	 * sufficient, though, as we could be in an NMI inside an interrupt
+	 * that happened during task_pt_regs setup.
+	 */
+	if (regs->sp > (unsigned long)&user_regs->r11 &&
+	    regs->sp <= (unsigned long)(user_regs + 1)) {
+		regs_user->abi = PERF_SAMPLE_REGS_ABI_NONE;
+		regs_user->regs = NULL;
+		return;
+	}
+
+	/*
+	 * RIP, flags, and the argument registers are usually saved.
+	 * orig_ax is probably okay, too.
+	 */
+	regs_user_copy->ip = user_regs->ip;
+	regs_user_copy->cx = user_regs->cx;
+	regs_user_copy->dx = user_regs->dx;
+	regs_user_copy->si = user_regs->si;
+	regs_user_copy->di = user_regs->di;
+	regs_user_copy->r8 = user_regs->r8;
+	regs_user_copy->r9 = user_regs->r9;
+	regs_user_copy->r10 = user_regs->r10;
+	regs_user_copy->r11 = user_regs->r11;
+	regs_user_copy->orig_ax = user_regs->orig_ax;
+	regs_user_copy->flags = user_regs->flags;
+
+	/*
+	 * Don't even try to report the "rest" regs.
+	 */
+	regs_user_copy->bx = -1;
+	regs_user_copy->bp = -1;
+	regs_user_copy->r12 = -1;
+	regs_user_copy->r13 = -1;
+	regs_user_copy->r14 = -1;
+	regs_user_copy->r15 = -1;
+
+	/*
+	 * For this to be at all useful, we need a reasonable guess for
+	 * sp and the ABI.  Be careful: we're in NMI context, and we're
+	 * considering current to be the current task, so we should
+	 * be careful not to look at any other percpu variables that might
+	 * change during context switches.
+	 */
+	if (IS_ENABLED(CONFIG_IA32_EMULATION) &&
+	    task_thread_info(current)->status & TS_COMPAT) {
+		/* Easy case: we're in a compat syscall. */
+		regs_user->abi = PERF_SAMPLE_REGS_ABI_32;
+		regs_user_copy->sp = user_regs->sp;
+		regs_user_copy->cs = user_regs->cs;
+		regs_user_copy->ss = user_regs->ss;
+	} else if (user_regs->orig_ax != -1) {
+		/*
+		 * We're probably in a 64-bit syscall.
+		 * Warning: this code is severely racy.  At least it's better
+		 * than just blindly copying user_regs.
+		 */
+		regs_user->abi = PERF_SAMPLE_REGS_ABI_64;
+		regs_user_copy->sp = this_cpu_read(old_rsp);
+		regs_user_copy->cs = __USER_CS;
+		regs_user_copy->ss = __USER_DS;
+		regs_user_copy->cx = -1;  /* usually contains garbage */
+	} else {
+		/* We're probably in an interrupt or exception. */
+		regs_user->abi = user_64bit_mode(user_regs) ?
+			PERF_SAMPLE_REGS_ABI_64 : PERF_SAMPLE_REGS_ABI_32;
+		regs_user_copy->sp = user_regs->sp;
+		regs_user_copy->cs = user_regs->cs;
+		regs_user_copy->ss = user_regs->ss;
+	}
+
+	regs_user->regs = regs_user_copy;
+}
 #endif /* CONFIG_X86_32 */
 #endif /* CONFIG_X86_32 */

+ 1 - 1
arch/x86/lib/insn.c

@@ -28,7 +28,7 @@
 
 
 /* Verify next sizeof(t) bytes can be on the same instruction */
 /* Verify next sizeof(t) bytes can be on the same instruction */
 #define validate_next(t, insn, n)	\
 #define validate_next(t, insn, n)	\
-	((insn)->next_byte + sizeof(t) + n < (insn)->end_kaddr)
+	((insn)->next_byte + sizeof(t) + n <= (insn)->end_kaddr)
 
 
 #define __get_next(t, insn)	\
 #define __get_next(t, insn)	\
 	({ t r = *(t*)insn->next_byte; insn->next_byte += sizeof(t); r; })
 	({ t r = *(t*)insn->next_byte; insn->next_byte += sizeof(t); r; })

+ 17 - 20
arch/x86/mm/init.c

@@ -438,20 +438,20 @@ static unsigned long __init init_range_memory_mapping(
 static unsigned long __init get_new_step_size(unsigned long step_size)
 static unsigned long __init get_new_step_size(unsigned long step_size)
 {
 {
 	/*
 	/*
-	 * Explain why we shift by 5 and why we don't have to worry about
-	 * 'step_size << 5' overflowing:
-	 *
-	 * initial mapped size is PMD_SIZE (2M).
+	 * Initial mapped size is PMD_SIZE (2M).
 	 * We can not set step_size to be PUD_SIZE (1G) yet.
 	 * We can not set step_size to be PUD_SIZE (1G) yet.
 	 * In worse case, when we cross the 1G boundary, and
 	 * In worse case, when we cross the 1G boundary, and
 	 * PG_LEVEL_2M is not set, we will need 1+1+512 pages (2M + 8k)
 	 * PG_LEVEL_2M is not set, we will need 1+1+512 pages (2M + 8k)
-	 * to map 1G range with PTE. Use 5 as shift for now.
+	 * to map 1G range with PTE. Hence we use one less than the
+	 * difference of page table level shifts.
 	 *
 	 *
-	 * Don't need to worry about overflow, on 32bit, when step_size
-	 * is 0, round_down() returns 0 for start, and that turns it
-	 * into 0x100000000ULL.
+	 * Don't need to worry about overflow in the top-down case, on 32bit,
+	 * when step_size is 0, round_down() returns 0 for start, and that
+	 * turns it into 0x100000000ULL.
+	 * In the bottom-up case, round_up(x, 0) returns 0 though too, which
+	 * needs to be taken into consideration by the code below.
 	 */
 	 */
-	return step_size << 5;
+	return step_size << (PMD_SHIFT - PAGE_SHIFT - 1);
 }
 }
 
 
 /**
 /**
@@ -471,7 +471,6 @@ static void __init memory_map_top_down(unsigned long map_start,
 	unsigned long step_size;
 	unsigned long step_size;
 	unsigned long addr;
 	unsigned long addr;
 	unsigned long mapped_ram_size = 0;
 	unsigned long mapped_ram_size = 0;
-	unsigned long new_mapped_ram_size;
 
 
 	/* xen has big range in reserved near end of ram, skip it at first.*/
 	/* xen has big range in reserved near end of ram, skip it at first.*/
 	addr = memblock_find_in_range(map_start, map_end, PMD_SIZE, PMD_SIZE);
 	addr = memblock_find_in_range(map_start, map_end, PMD_SIZE, PMD_SIZE);
@@ -496,14 +495,12 @@ static void __init memory_map_top_down(unsigned long map_start,
 				start = map_start;
 				start = map_start;
 		} else
 		} else
 			start = map_start;
 			start = map_start;
-		new_mapped_ram_size = init_range_memory_mapping(start,
+		mapped_ram_size += init_range_memory_mapping(start,
 							last_start);
 							last_start);
 		last_start = start;
 		last_start = start;
 		min_pfn_mapped = last_start >> PAGE_SHIFT;
 		min_pfn_mapped = last_start >> PAGE_SHIFT;
-		/* only increase step_size after big range get mapped */
-		if (new_mapped_ram_size > mapped_ram_size)
+		if (mapped_ram_size >= step_size)
 			step_size = get_new_step_size(step_size);
 			step_size = get_new_step_size(step_size);
-		mapped_ram_size += new_mapped_ram_size;
 	}
 	}
 
 
 	if (real_end < map_end)
 	if (real_end < map_end)
@@ -524,7 +521,7 @@ static void __init memory_map_top_down(unsigned long map_start,
 static void __init memory_map_bottom_up(unsigned long map_start,
 static void __init memory_map_bottom_up(unsigned long map_start,
 					unsigned long map_end)
 					unsigned long map_end)
 {
 {
-	unsigned long next, new_mapped_ram_size, start;
+	unsigned long next, start;
 	unsigned long mapped_ram_size = 0;
 	unsigned long mapped_ram_size = 0;
 	/* step_size need to be small so pgt_buf from BRK could cover it */
 	/* step_size need to be small so pgt_buf from BRK could cover it */
 	unsigned long step_size = PMD_SIZE;
 	unsigned long step_size = PMD_SIZE;
@@ -539,19 +536,19 @@ static void __init memory_map_bottom_up(unsigned long map_start,
 	 * for page table.
 	 * for page table.
 	 */
 	 */
 	while (start < map_end) {
 	while (start < map_end) {
-		if (map_end - start > step_size) {
+		if (step_size && map_end - start > step_size) {
 			next = round_up(start + 1, step_size);
 			next = round_up(start + 1, step_size);
 			if (next > map_end)
 			if (next > map_end)
 				next = map_end;
 				next = map_end;
-		} else
+		} else {
 			next = map_end;
 			next = map_end;
+		}
 
 
-		new_mapped_ram_size = init_range_memory_mapping(start, next);
+		mapped_ram_size += init_range_memory_mapping(start, next);
 		start = next;
 		start = next;
 
 
-		if (new_mapped_ram_size > mapped_ram_size)
+		if (mapped_ram_size >= step_size)
 			step_size = get_new_step_size(step_size);
 			step_size = get_new_step_size(step_size);
-		mapped_ram_size += new_mapped_ram_size;
 	}
 	}
 }
 }
 
 

+ 29 - 16
arch/x86/vdso/vma.c

@@ -41,12 +41,17 @@ void __init init_vdso_image(const struct vdso_image *image)
 
 
 struct linux_binprm;
 struct linux_binprm;
 
 
-/* Put the vdso above the (randomized) stack with another randomized offset.
-   This way there is no hole in the middle of address space.
-   To save memory make sure it is still in the same PTE as the stack top.
-   This doesn't give that many random bits.
-
-   Only used for the 64-bit and x32 vdsos. */
+/*
+ * Put the vdso above the (randomized) stack with another randomized
+ * offset.  This way there is no hole in the middle of address space.
+ * To save memory make sure it is still in the same PTE as the stack
+ * top.  This doesn't give that many random bits.
+ *
+ * Note that this algorithm is imperfect: the distribution of the vdso
+ * start address within a PMD is biased toward the end.
+ *
+ * Only used for the 64-bit and x32 vdsos.
+ */
 static unsigned long vdso_addr(unsigned long start, unsigned len)
 static unsigned long vdso_addr(unsigned long start, unsigned len)
 {
 {
 #ifdef CONFIG_X86_32
 #ifdef CONFIG_X86_32
@@ -54,22 +59,30 @@ static unsigned long vdso_addr(unsigned long start, unsigned len)
 #else
 #else
 	unsigned long addr, end;
 	unsigned long addr, end;
 	unsigned offset;
 	unsigned offset;
-	end = (start + PMD_SIZE - 1) & PMD_MASK;
+
+	/*
+	 * Round up the start address.  It can start out unaligned as a result
+	 * of stack start randomization.
+	 */
+	start = PAGE_ALIGN(start);
+
+	/* Round the lowest possible end address up to a PMD boundary. */
+	end = (start + len + PMD_SIZE - 1) & PMD_MASK;
 	if (end >= TASK_SIZE_MAX)
 	if (end >= TASK_SIZE_MAX)
 		end = TASK_SIZE_MAX;
 		end = TASK_SIZE_MAX;
 	end -= len;
 	end -= len;
-	/* This loses some more bits than a modulo, but is cheaper */
-	offset = get_random_int() & (PTRS_PER_PTE - 1);
-	addr = start + (offset << PAGE_SHIFT);
-	if (addr >= end)
-		addr = end;
+
+	if (end > start) {
+		offset = get_random_int() % (((end - start) >> PAGE_SHIFT) + 1);
+		addr = start + (offset << PAGE_SHIFT);
+	} else {
+		addr = start;
+	}
 
 
 	/*
 	/*
-	 * page-align it here so that get_unmapped_area doesn't
-	 * align it wrongfully again to the next page. addr can come in 4K
-	 * unaligned here as a result of stack start randomization.
+	 * Forcibly align the final address in case we have a hardware
+	 * issue that requires alignment for performance reasons.
 	 */
 	 */
-	addr = PAGE_ALIGN(addr);
 	addr = align_vdso_addr(addr);
 	addr = align_vdso_addr(addr);
 
 
 	return addr;
 	return addr;

+ 21 - 1
arch/x86/xen/enlighten.c

@@ -40,6 +40,7 @@
 #include <xen/interface/physdev.h>
 #include <xen/interface/physdev.h>
 #include <xen/interface/vcpu.h>
 #include <xen/interface/vcpu.h>
 #include <xen/interface/memory.h>
 #include <xen/interface/memory.h>
+#include <xen/interface/nmi.h>
 #include <xen/interface/xen-mca.h>
 #include <xen/interface/xen-mca.h>
 #include <xen/features.h>
 #include <xen/features.h>
 #include <xen/page.h>
 #include <xen/page.h>
@@ -66,6 +67,7 @@
 #include <asm/reboot.h>
 #include <asm/reboot.h>
 #include <asm/stackprotector.h>
 #include <asm/stackprotector.h>
 #include <asm/hypervisor.h>
 #include <asm/hypervisor.h>
+#include <asm/mach_traps.h>
 #include <asm/mwait.h>
 #include <asm/mwait.h>
 #include <asm/pci_x86.h>
 #include <asm/pci_x86.h>
 #include <asm/pat.h>
 #include <asm/pat.h>
@@ -1351,6 +1353,21 @@ static const struct machine_ops xen_machine_ops __initconst = {
 	.emergency_restart = xen_emergency_restart,
 	.emergency_restart = xen_emergency_restart,
 };
 };
 
 
+static unsigned char xen_get_nmi_reason(void)
+{
+	unsigned char reason = 0;
+
+	/* Construct a value which looks like it came from port 0x61. */
+	if (test_bit(_XEN_NMIREASON_io_error,
+		     &HYPERVISOR_shared_info->arch.nmi_reason))
+		reason |= NMI_REASON_IOCHK;
+	if (test_bit(_XEN_NMIREASON_pci_serr,
+		     &HYPERVISOR_shared_info->arch.nmi_reason))
+		reason |= NMI_REASON_SERR;
+
+	return reason;
+}
+
 static void __init xen_boot_params_init_edd(void)
 static void __init xen_boot_params_init_edd(void)
 {
 {
 #if IS_ENABLED(CONFIG_EDD)
 #if IS_ENABLED(CONFIG_EDD)
@@ -1535,9 +1552,12 @@ asmlinkage __visible void __init xen_start_kernel(void)
 	pv_info = xen_info;
 	pv_info = xen_info;
 	pv_init_ops = xen_init_ops;
 	pv_init_ops = xen_init_ops;
 	pv_apic_ops = xen_apic_ops;
 	pv_apic_ops = xen_apic_ops;
-	if (!xen_pvh_domain())
+	if (!xen_pvh_domain()) {
 		pv_cpu_ops = xen_cpu_ops;
 		pv_cpu_ops = xen_cpu_ops;
 
 
+		x86_platform.get_nmi_reason = xen_get_nmi_reason;
+	}
+
 	if (xen_feature(XENFEAT_auto_translated_physmap))
 	if (xen_feature(XENFEAT_auto_translated_physmap))
 		x86_init.resources.memory_setup = xen_auto_xlated_memory_setup;
 		x86_init.resources.memory_setup = xen_auto_xlated_memory_setup;
 	else
 	else

+ 10 - 10
arch/x86/xen/p2m.c

@@ -167,10 +167,13 @@ static void * __ref alloc_p2m_page(void)
 	return (void *)__get_free_page(GFP_KERNEL | __GFP_REPEAT);
 	return (void *)__get_free_page(GFP_KERNEL | __GFP_REPEAT);
 }
 }
 
 
-/* Only to be called in case of a race for a page just allocated! */
-static void free_p2m_page(void *p)
+static void __ref free_p2m_page(void *p)
 {
 {
-	BUG_ON(!slab_is_available());
+	if (unlikely(!slab_is_available())) {
+		free_bootmem((unsigned long)p, PAGE_SIZE);
+		return;
+	}
+
 	free_page((unsigned long)p);
 	free_page((unsigned long)p);
 }
 }
 
 
@@ -375,7 +378,7 @@ static void __init xen_rebuild_p2m_list(unsigned long *p2m)
 			p2m_missing_pte : p2m_identity_pte;
 			p2m_missing_pte : p2m_identity_pte;
 		for (i = 0; i < PMDS_PER_MID_PAGE; i++) {
 		for (i = 0; i < PMDS_PER_MID_PAGE; i++) {
 			pmdp = populate_extra_pmd(
 			pmdp = populate_extra_pmd(
-				(unsigned long)(p2m + pfn + i * PTRS_PER_PTE));
+				(unsigned long)(p2m + pfn) + i * PMD_SIZE);
 			set_pmd(pmdp, __pmd(__pa(ptep) | _KERNPG_TABLE));
 			set_pmd(pmdp, __pmd(__pa(ptep) | _KERNPG_TABLE));
 		}
 		}
 	}
 	}
@@ -436,10 +439,9 @@ EXPORT_SYMBOL_GPL(get_phys_to_machine);
  * a new pmd is to replace p2m_missing_pte or p2m_identity_pte by a individual
  * a new pmd is to replace p2m_missing_pte or p2m_identity_pte by a individual
  * pmd. In case of PAE/x86-32 there are multiple pmds to allocate!
  * pmd. In case of PAE/x86-32 there are multiple pmds to allocate!
  */
  */
-static pte_t *alloc_p2m_pmd(unsigned long addr, pte_t *ptep, pte_t *pte_pg)
+static pte_t *alloc_p2m_pmd(unsigned long addr, pte_t *pte_pg)
 {
 {
 	pte_t *ptechk;
 	pte_t *ptechk;
-	pte_t *pteret = ptep;
 	pte_t *pte_newpg[PMDS_PER_MID_PAGE];
 	pte_t *pte_newpg[PMDS_PER_MID_PAGE];
 	pmd_t *pmdp;
 	pmd_t *pmdp;
 	unsigned int level;
 	unsigned int level;
@@ -473,8 +475,6 @@ static pte_t *alloc_p2m_pmd(unsigned long addr, pte_t *ptep, pte_t *pte_pg)
 		if (ptechk == pte_pg) {
 		if (ptechk == pte_pg) {
 			set_pmd(pmdp,
 			set_pmd(pmdp,
 				__pmd(__pa(pte_newpg[i]) | _KERNPG_TABLE));
 				__pmd(__pa(pte_newpg[i]) | _KERNPG_TABLE));
-			if (vaddr == (addr & ~(PMD_SIZE - 1)))
-				pteret = pte_offset_kernel(pmdp, addr);
 			pte_newpg[i] = NULL;
 			pte_newpg[i] = NULL;
 		}
 		}
 
 
@@ -488,7 +488,7 @@ static pte_t *alloc_p2m_pmd(unsigned long addr, pte_t *ptep, pte_t *pte_pg)
 		vaddr += PMD_SIZE;
 		vaddr += PMD_SIZE;
 	}
 	}
 
 
-	return pteret;
+	return lookup_address(addr, &level);
 }
 }
 
 
 /*
 /*
@@ -517,7 +517,7 @@ static bool alloc_p2m(unsigned long pfn)
 
 
 	if (pte_pg == p2m_missing_pte || pte_pg == p2m_identity_pte) {
 	if (pte_pg == p2m_missing_pte || pte_pg == p2m_identity_pte) {
 		/* PMD level is missing, allocate a new one */
 		/* PMD level is missing, allocate a new one */
-		ptep = alloc_p2m_pmd(addr, ptep, pte_pg);
+		ptep = alloc_p2m_pmd(addr, pte_pg);
 		if (!ptep)
 		if (!ptep)
 			return false;
 			return false;
 	}
 	}

+ 20 - 22
arch/x86/xen/setup.c

@@ -140,7 +140,7 @@ static void __init xen_del_extra_mem(u64 start, u64 size)
 unsigned long __ref xen_chk_extra_mem(unsigned long pfn)
 unsigned long __ref xen_chk_extra_mem(unsigned long pfn)
 {
 {
 	int i;
 	int i;
-	unsigned long addr = PFN_PHYS(pfn);
+	phys_addr_t addr = PFN_PHYS(pfn);
 
 
 	for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) {
 	for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) {
 		if (addr >= xen_extra_mem[i].start &&
 		if (addr >= xen_extra_mem[i].start &&
@@ -160,6 +160,8 @@ void __init xen_inv_extra_mem(void)
 	int i;
 	int i;
 
 
 	for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) {
 	for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) {
+		if (!xen_extra_mem[i].size)
+			continue;
 		pfn_s = PFN_DOWN(xen_extra_mem[i].start);
 		pfn_s = PFN_DOWN(xen_extra_mem[i].start);
 		pfn_e = PFN_UP(xen_extra_mem[i].start + xen_extra_mem[i].size);
 		pfn_e = PFN_UP(xen_extra_mem[i].start + xen_extra_mem[i].size);
 		for (pfn = pfn_s; pfn < pfn_e; pfn++)
 		for (pfn = pfn_s; pfn < pfn_e; pfn++)
@@ -229,15 +231,14 @@ static int __init xen_free_mfn(unsigned long mfn)
  * as a fallback if the remapping fails.
  * as a fallback if the remapping fails.
  */
  */
 static void __init xen_set_identity_and_release_chunk(unsigned long start_pfn,
 static void __init xen_set_identity_and_release_chunk(unsigned long start_pfn,
-	unsigned long end_pfn, unsigned long nr_pages, unsigned long *identity,
-	unsigned long *released)
+	unsigned long end_pfn, unsigned long nr_pages, unsigned long *released)
 {
 {
-	unsigned long len = 0;
 	unsigned long pfn, end;
 	unsigned long pfn, end;
 	int ret;
 	int ret;
 
 
 	WARN_ON(start_pfn > end_pfn);
 	WARN_ON(start_pfn > end_pfn);
 
 
+	/* Release pages first. */
 	end = min(end_pfn, nr_pages);
 	end = min(end_pfn, nr_pages);
 	for (pfn = start_pfn; pfn < end; pfn++) {
 	for (pfn = start_pfn; pfn < end; pfn++) {
 		unsigned long mfn = pfn_to_mfn(pfn);
 		unsigned long mfn = pfn_to_mfn(pfn);
@@ -250,16 +251,14 @@ static void __init xen_set_identity_and_release_chunk(unsigned long start_pfn,
 		WARN(ret != 1, "Failed to release pfn %lx err=%d\n", pfn, ret);
 		WARN(ret != 1, "Failed to release pfn %lx err=%d\n", pfn, ret);
 
 
 		if (ret == 1) {
 		if (ret == 1) {
+			(*released)++;
 			if (!__set_phys_to_machine(pfn, INVALID_P2M_ENTRY))
 			if (!__set_phys_to_machine(pfn, INVALID_P2M_ENTRY))
 				break;
 				break;
-			len++;
 		} else
 		} else
 			break;
 			break;
 	}
 	}
 
 
-	/* Need to release pages first */
-	*released += len;
-	*identity += set_phys_range_identity(start_pfn, end_pfn);
+	set_phys_range_identity(start_pfn, end_pfn);
 }
 }
 
 
 /*
 /*
@@ -287,7 +286,7 @@ static void __init xen_update_mem_tables(unsigned long pfn, unsigned long mfn)
 	}
 	}
 
 
 	/* Update kernel mapping, but not for highmem. */
 	/* Update kernel mapping, but not for highmem. */
-	if ((pfn << PAGE_SHIFT) >= __pa(high_memory))
+	if (pfn >= PFN_UP(__pa(high_memory - 1)))
 		return;
 		return;
 
 
 	if (HYPERVISOR_update_va_mapping((unsigned long)__va(pfn << PAGE_SHIFT),
 	if (HYPERVISOR_update_va_mapping((unsigned long)__va(pfn << PAGE_SHIFT),
@@ -318,7 +317,6 @@ static void __init xen_do_set_identity_and_remap_chunk(
 	unsigned long ident_pfn_iter, remap_pfn_iter;
 	unsigned long ident_pfn_iter, remap_pfn_iter;
 	unsigned long ident_end_pfn = start_pfn + size;
 	unsigned long ident_end_pfn = start_pfn + size;
 	unsigned long left = size;
 	unsigned long left = size;
-	unsigned long ident_cnt = 0;
 	unsigned int i, chunk;
 	unsigned int i, chunk;
 
 
 	WARN_ON(size == 0);
 	WARN_ON(size == 0);
@@ -347,8 +345,7 @@ static void __init xen_do_set_identity_and_remap_chunk(
 		xen_remap_mfn = mfn;
 		xen_remap_mfn = mfn;
 
 
 		/* Set identity map */
 		/* Set identity map */
-		ident_cnt += set_phys_range_identity(ident_pfn_iter,
-			ident_pfn_iter + chunk);
+		set_phys_range_identity(ident_pfn_iter, ident_pfn_iter + chunk);
 
 
 		left -= chunk;
 		left -= chunk;
 	}
 	}
@@ -371,7 +368,7 @@ static void __init xen_do_set_identity_and_remap_chunk(
 static unsigned long __init xen_set_identity_and_remap_chunk(
 static unsigned long __init xen_set_identity_and_remap_chunk(
         const struct e820entry *list, size_t map_size, unsigned long start_pfn,
         const struct e820entry *list, size_t map_size, unsigned long start_pfn,
 	unsigned long end_pfn, unsigned long nr_pages, unsigned long remap_pfn,
 	unsigned long end_pfn, unsigned long nr_pages, unsigned long remap_pfn,
-	unsigned long *identity, unsigned long *released)
+	unsigned long *released, unsigned long *remapped)
 {
 {
 	unsigned long pfn;
 	unsigned long pfn;
 	unsigned long i = 0;
 	unsigned long i = 0;
@@ -386,8 +383,7 @@ static unsigned long __init xen_set_identity_and_remap_chunk(
 		/* Do not remap pages beyond the current allocation */
 		/* Do not remap pages beyond the current allocation */
 		if (cur_pfn >= nr_pages) {
 		if (cur_pfn >= nr_pages) {
 			/* Identity map remaining pages */
 			/* Identity map remaining pages */
-			*identity += set_phys_range_identity(cur_pfn,
-				cur_pfn + size);
+			set_phys_range_identity(cur_pfn, cur_pfn + size);
 			break;
 			break;
 		}
 		}
 		if (cur_pfn + size > nr_pages)
 		if (cur_pfn + size > nr_pages)
@@ -398,7 +394,7 @@ static unsigned long __init xen_set_identity_and_remap_chunk(
 		if (!remap_range_size) {
 		if (!remap_range_size) {
 			pr_warning("Unable to find available pfn range, not remapping identity pages\n");
 			pr_warning("Unable to find available pfn range, not remapping identity pages\n");
 			xen_set_identity_and_release_chunk(cur_pfn,
 			xen_set_identity_and_release_chunk(cur_pfn,
-				cur_pfn + left, nr_pages, identity, released);
+				cur_pfn + left, nr_pages, released);
 			break;
 			break;
 		}
 		}
 		/* Adjust size to fit in current e820 RAM region */
 		/* Adjust size to fit in current e820 RAM region */
@@ -410,7 +406,7 @@ static unsigned long __init xen_set_identity_and_remap_chunk(
 		/* Update variables to reflect new mappings. */
 		/* Update variables to reflect new mappings. */
 		i += size;
 		i += size;
 		remap_pfn += size;
 		remap_pfn += size;
-		*identity += size;
+		*remapped += size;
 	}
 	}
 
 
 	/*
 	/*
@@ -427,13 +423,13 @@ static unsigned long __init xen_set_identity_and_remap_chunk(
 
 
 static void __init xen_set_identity_and_remap(
 static void __init xen_set_identity_and_remap(
 	const struct e820entry *list, size_t map_size, unsigned long nr_pages,
 	const struct e820entry *list, size_t map_size, unsigned long nr_pages,
-	unsigned long *released)
+	unsigned long *released, unsigned long *remapped)
 {
 {
 	phys_addr_t start = 0;
 	phys_addr_t start = 0;
-	unsigned long identity = 0;
 	unsigned long last_pfn = nr_pages;
 	unsigned long last_pfn = nr_pages;
 	const struct e820entry *entry;
 	const struct e820entry *entry;
 	unsigned long num_released = 0;
 	unsigned long num_released = 0;
+	unsigned long num_remapped = 0;
 	int i;
 	int i;
 
 
 	/*
 	/*
@@ -460,14 +456,14 @@ static void __init xen_set_identity_and_remap(
 				last_pfn = xen_set_identity_and_remap_chunk(
 				last_pfn = xen_set_identity_and_remap_chunk(
 						list, map_size, start_pfn,
 						list, map_size, start_pfn,
 						end_pfn, nr_pages, last_pfn,
 						end_pfn, nr_pages, last_pfn,
-						&identity, &num_released);
+						&num_released, &num_remapped);
 			start = end;
 			start = end;
 		}
 		}
 	}
 	}
 
 
 	*released = num_released;
 	*released = num_released;
+	*remapped = num_remapped;
 
 
-	pr_info("Set %ld page(s) to 1-1 mapping\n", identity);
 	pr_info("Released %ld page(s)\n", num_released);
 	pr_info("Released %ld page(s)\n", num_released);
 }
 }
 
 
@@ -586,6 +582,7 @@ char * __init xen_memory_setup(void)
 	struct xen_memory_map memmap;
 	struct xen_memory_map memmap;
 	unsigned long max_pages;
 	unsigned long max_pages;
 	unsigned long extra_pages = 0;
 	unsigned long extra_pages = 0;
+	unsigned long remapped_pages;
 	int i;
 	int i;
 	int op;
 	int op;
 
 
@@ -635,9 +632,10 @@ char * __init xen_memory_setup(void)
 	 * underlying RAM.
 	 * underlying RAM.
 	 */
 	 */
 	xen_set_identity_and_remap(map, memmap.nr_entries, max_pfn,
 	xen_set_identity_and_remap(map, memmap.nr_entries, max_pfn,
-				   &xen_released_pages);
+				   &xen_released_pages, &remapped_pages);
 
 
 	extra_pages += xen_released_pages;
 	extra_pages += xen_released_pages;
+	extra_pages += remapped_pages;
 
 
 	/*
 	/*
 	 * Clamp the amount of extra memory to a EXTRA_MEM_RATIO
 	 * Clamp the amount of extra memory to a EXTRA_MEM_RATIO

+ 5 - 13
arch/x86/xen/time.c

@@ -391,7 +391,7 @@ static const struct clock_event_device *xen_clockevent =
 
 
 struct xen_clock_event_device {
 struct xen_clock_event_device {
 	struct clock_event_device evt;
 	struct clock_event_device evt;
-	char *name;
+	char name[16];
 };
 };
 static DEFINE_PER_CPU(struct xen_clock_event_device, xen_clock_events) = { .evt.irq = -1 };
 static DEFINE_PER_CPU(struct xen_clock_event_device, xen_clock_events) = { .evt.irq = -1 };
 
 
@@ -420,46 +420,38 @@ void xen_teardown_timer(int cpu)
 	if (evt->irq >= 0) {
 	if (evt->irq >= 0) {
 		unbind_from_irqhandler(evt->irq, NULL);
 		unbind_from_irqhandler(evt->irq, NULL);
 		evt->irq = -1;
 		evt->irq = -1;
-		kfree(per_cpu(xen_clock_events, cpu).name);
-		per_cpu(xen_clock_events, cpu).name = NULL;
 	}
 	}
 }
 }
 
 
 void xen_setup_timer(int cpu)
 void xen_setup_timer(int cpu)
 {
 {
-	char *name;
-	struct clock_event_device *evt;
+	struct xen_clock_event_device *xevt = &per_cpu(xen_clock_events, cpu);
+	struct clock_event_device *evt = &xevt->evt;
 	int irq;
 	int irq;
 
 
-	evt = &per_cpu(xen_clock_events, cpu).evt;
 	WARN(evt->irq >= 0, "IRQ%d for CPU%d is already allocated\n", evt->irq, cpu);
 	WARN(evt->irq >= 0, "IRQ%d for CPU%d is already allocated\n", evt->irq, cpu);
 	if (evt->irq >= 0)
 	if (evt->irq >= 0)
 		xen_teardown_timer(cpu);
 		xen_teardown_timer(cpu);
 
 
 	printk(KERN_INFO "installing Xen timer for CPU %d\n", cpu);
 	printk(KERN_INFO "installing Xen timer for CPU %d\n", cpu);
 
 
-	name = kasprintf(GFP_KERNEL, "timer%d", cpu);
-	if (!name)
-		name = "<timer kasprintf failed>";
+	snprintf(xevt->name, sizeof(xevt->name), "timer%d", cpu);
 
 
 	irq = bind_virq_to_irqhandler(VIRQ_TIMER, cpu, xen_timer_interrupt,
 	irq = bind_virq_to_irqhandler(VIRQ_TIMER, cpu, xen_timer_interrupt,
 				      IRQF_PERCPU|IRQF_NOBALANCING|IRQF_TIMER|
 				      IRQF_PERCPU|IRQF_NOBALANCING|IRQF_TIMER|
 				      IRQF_FORCE_RESUME|IRQF_EARLY_RESUME,
 				      IRQF_FORCE_RESUME|IRQF_EARLY_RESUME,
-				      name, NULL);
+				      xevt->name, NULL);
 	(void)xen_set_irq_priority(irq, XEN_IRQ_PRIORITY_MAX);
 	(void)xen_set_irq_priority(irq, XEN_IRQ_PRIORITY_MAX);
 
 
 	memcpy(evt, xen_clockevent, sizeof(*evt));
 	memcpy(evt, xen_clockevent, sizeof(*evt));
 
 
 	evt->cpumask = cpumask_of(cpu);
 	evt->cpumask = cpumask_of(cpu);
 	evt->irq = irq;
 	evt->irq = irq;
-	per_cpu(xen_clock_events, cpu).name = name;
 }
 }
 
 
 
 
 void xen_setup_cpu_clockevents(void)
 void xen_setup_cpu_clockevents(void)
 {
 {
-	BUG_ON(preemptible());
-
 	clockevents_register_device(this_cpu_ptr(&xen_clock_events.evt));
 	clockevents_register_device(this_cpu_ptr(&xen_clock_events.evt));
 }
 }
 
 

+ 4 - 2
drivers/Makefile

@@ -50,7 +50,10 @@ obj-$(CONFIG_RESET_CONTROLLER)	+= reset/
 obj-y				+= tty/
 obj-y				+= tty/
 obj-y				+= char/
 obj-y				+= char/
 
 
-# gpu/ comes after char for AGP vs DRM startup
+# iommu/ comes before gpu as gpu are using iommu controllers
+obj-$(CONFIG_IOMMU_SUPPORT)	+= iommu/
+
+# gpu/ comes after char for AGP vs DRM startup and after iommu
 obj-y				+= gpu/
 obj-y				+= gpu/
 
 
 obj-$(CONFIG_CONNECTOR)		+= connector/
 obj-$(CONFIG_CONNECTOR)		+= connector/
@@ -141,7 +144,6 @@ obj-y				+= clk/
 
 
 obj-$(CONFIG_MAILBOX)		+= mailbox/
 obj-$(CONFIG_MAILBOX)		+= mailbox/
 obj-$(CONFIG_HWSPINLOCK)	+= hwspinlock/
 obj-$(CONFIG_HWSPINLOCK)	+= hwspinlock/
-obj-$(CONFIG_IOMMU_SUPPORT)	+= iommu/
 obj-$(CONFIG_REMOTEPROC)	+= remoteproc/
 obj-$(CONFIG_REMOTEPROC)	+= remoteproc/
 obj-$(CONFIG_RPMSG)		+= rpmsg/
 obj-$(CONFIG_RPMSG)		+= rpmsg/
 
 

+ 14 - 11
drivers/acpi/acpi_processor.c

@@ -170,7 +170,7 @@ static int acpi_processor_hotadd_init(struct acpi_processor *pr)
 	acpi_status status;
 	acpi_status status;
 	int ret;
 	int ret;
 
 
-	if (pr->apic_id == -1)
+	if (pr->phys_id == -1)
 		return -ENODEV;
 		return -ENODEV;
 
 
 	status = acpi_evaluate_integer(pr->handle, "_STA", NULL, &sta);
 	status = acpi_evaluate_integer(pr->handle, "_STA", NULL, &sta);
@@ -180,13 +180,13 @@ static int acpi_processor_hotadd_init(struct acpi_processor *pr)
 	cpu_maps_update_begin();
 	cpu_maps_update_begin();
 	cpu_hotplug_begin();
 	cpu_hotplug_begin();
 
 
-	ret = acpi_map_lsapic(pr->handle, pr->apic_id, &pr->id);
+	ret = acpi_map_cpu(pr->handle, pr->phys_id, &pr->id);
 	if (ret)
 	if (ret)
 		goto out;
 		goto out;
 
 
 	ret = arch_register_cpu(pr->id);
 	ret = arch_register_cpu(pr->id);
 	if (ret) {
 	if (ret) {
-		acpi_unmap_lsapic(pr->id);
+		acpi_unmap_cpu(pr->id);
 		goto out;
 		goto out;
 	}
 	}
 
 
@@ -215,7 +215,7 @@ static int acpi_processor_get_info(struct acpi_device *device)
 	union acpi_object object = { 0 };
 	union acpi_object object = { 0 };
 	struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
 	struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
 	struct acpi_processor *pr = acpi_driver_data(device);
 	struct acpi_processor *pr = acpi_driver_data(device);
-	int apic_id, cpu_index, device_declaration = 0;
+	int phys_id, cpu_index, device_declaration = 0;
 	acpi_status status = AE_OK;
 	acpi_status status = AE_OK;
 	static int cpu0_initialized;
 	static int cpu0_initialized;
 	unsigned long long value;
 	unsigned long long value;
@@ -262,15 +262,18 @@ static int acpi_processor_get_info(struct acpi_device *device)
 		pr->acpi_id = value;
 		pr->acpi_id = value;
 	}
 	}
 
 
-	apic_id = acpi_get_apicid(pr->handle, device_declaration, pr->acpi_id);
-	if (apic_id < 0)
-		acpi_handle_debug(pr->handle, "failed to get CPU APIC ID.\n");
-	pr->apic_id = apic_id;
+	phys_id = acpi_get_phys_id(pr->handle, device_declaration, pr->acpi_id);
+	if (phys_id < 0)
+		acpi_handle_debug(pr->handle, "failed to get CPU physical ID.\n");
+	pr->phys_id = phys_id;
 
 
-	cpu_index = acpi_map_cpuid(pr->apic_id, pr->acpi_id);
+	cpu_index = acpi_map_cpuid(pr->phys_id, pr->acpi_id);
 	if (!cpu0_initialized && !acpi_has_cpu_in_madt()) {
 	if (!cpu0_initialized && !acpi_has_cpu_in_madt()) {
 		cpu0_initialized = 1;
 		cpu0_initialized = 1;
-		/* Handle UP system running SMP kernel, with no LAPIC in MADT */
+		/*
+		 * Handle UP system running SMP kernel, with no CPU
+		 * entry in MADT
+		 */
 		if ((cpu_index == -1) && (num_online_cpus() == 1))
 		if ((cpu_index == -1) && (num_online_cpus() == 1))
 			cpu_index = 0;
 			cpu_index = 0;
 	}
 	}
@@ -458,7 +461,7 @@ static void acpi_processor_remove(struct acpi_device *device)
 
 
 	/* Remove the CPU. */
 	/* Remove the CPU. */
 	arch_unregister_cpu(pr->id);
 	arch_unregister_cpu(pr->id);
-	acpi_unmap_lsapic(pr->id);
+	acpi_unmap_cpu(pr->id);
 
 
 	cpu_hotplug_done();
 	cpu_hotplug_done();
 	cpu_maps_update_done();
 	cpu_maps_update_done();

+ 1 - 1
drivers/acpi/device_pm.c

@@ -257,7 +257,7 @@ int acpi_bus_init_power(struct acpi_device *device)
 
 
 	device->power.state = ACPI_STATE_UNKNOWN;
 	device->power.state = ACPI_STATE_UNKNOWN;
 	if (!acpi_device_is_present(device))
 	if (!acpi_device_is_present(device))
-		return 0;
+		return -ENXIO;
 
 
 	result = acpi_device_get_power(device, &state);
 	result = acpi_device_get_power(device, &state);
 	if (result)
 	if (result)

+ 7 - 4
drivers/acpi/int340x_thermal.c

@@ -14,10 +14,10 @@
 
 
 #include "internal.h"
 #include "internal.h"
 
 
-#define DO_ENUMERATION 0x01
+#define INT3401_DEVICE 0X01
 static const struct acpi_device_id int340x_thermal_device_ids[] = {
 static const struct acpi_device_id int340x_thermal_device_ids[] = {
-	{"INT3400", DO_ENUMERATION },
-	{"INT3401"},
+	{"INT3400"},
+	{"INT3401", INT3401_DEVICE},
 	{"INT3402"},
 	{"INT3402"},
 	{"INT3403"},
 	{"INT3403"},
 	{"INT3404"},
 	{"INT3404"},
@@ -34,7 +34,10 @@ static int int340x_thermal_handler_attach(struct acpi_device *adev,
 					const struct acpi_device_id *id)
 					const struct acpi_device_id *id)
 {
 {
 #if defined(CONFIG_INT340X_THERMAL) || defined(CONFIG_INT340X_THERMAL_MODULE)
 #if defined(CONFIG_INT340X_THERMAL) || defined(CONFIG_INT340X_THERMAL_MODULE)
-	if (id->driver_data == DO_ENUMERATION)
+	acpi_create_platform_device(adev);
+#elif defined(INTEL_SOC_DTS_THERMAL) || defined(INTEL_SOC_DTS_THERMAL_MODULE)
+	/* Intel SoC DTS thermal driver needs INT3401 to set IRQ descriptor */
+	if (id->driver_data == INT3401_DEVICE)
 		acpi_create_platform_device(adev);
 		acpi_create_platform_device(adev);
 #endif
 #endif
 	return 1;
 	return 1;

+ 28 - 28
drivers/acpi/processor_core.c

@@ -69,7 +69,7 @@ static int map_madt_entry(int type, u32 acpi_id)
 	unsigned long madt_end, entry;
 	unsigned long madt_end, entry;
 	static struct acpi_table_madt *madt;
 	static struct acpi_table_madt *madt;
 	static int read_madt;
 	static int read_madt;
-	int apic_id = -1;
+	int phys_id = -1;	/* CPU hardware ID */
 
 
 	if (!read_madt) {
 	if (!read_madt) {
 		if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0,
 		if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0,
@@ -79,7 +79,7 @@ static int map_madt_entry(int type, u32 acpi_id)
 	}
 	}
 
 
 	if (!madt)
 	if (!madt)
-		return apic_id;
+		return phys_id;
 
 
 	entry = (unsigned long)madt;
 	entry = (unsigned long)madt;
 	madt_end = entry + madt->header.length;
 	madt_end = entry + madt->header.length;
@@ -91,18 +91,18 @@ static int map_madt_entry(int type, u32 acpi_id)
 		struct acpi_subtable_header *header =
 		struct acpi_subtable_header *header =
 			(struct acpi_subtable_header *)entry;
 			(struct acpi_subtable_header *)entry;
 		if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) {
 		if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) {
-			if (!map_lapic_id(header, acpi_id, &apic_id))
+			if (!map_lapic_id(header, acpi_id, &phys_id))
 				break;
 				break;
 		} else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) {
 		} else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) {
-			if (!map_x2apic_id(header, type, acpi_id, &apic_id))
+			if (!map_x2apic_id(header, type, acpi_id, &phys_id))
 				break;
 				break;
 		} else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
 		} else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
-			if (!map_lsapic_id(header, type, acpi_id, &apic_id))
+			if (!map_lsapic_id(header, type, acpi_id, &phys_id))
 				break;
 				break;
 		}
 		}
 		entry += header->length;
 		entry += header->length;
 	}
 	}
-	return apic_id;
+	return phys_id;
 }
 }
 
 
 static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id)
 static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id)
@@ -110,7 +110,7 @@ static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id)
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 	union acpi_object *obj;
 	union acpi_object *obj;
 	struct acpi_subtable_header *header;
 	struct acpi_subtable_header *header;
-	int apic_id = -1;
+	int phys_id = -1;
 
 
 	if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer)))
 	if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer)))
 		goto exit;
 		goto exit;
@@ -126,38 +126,38 @@ static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id)
 
 
 	header = (struct acpi_subtable_header *)obj->buffer.pointer;
 	header = (struct acpi_subtable_header *)obj->buffer.pointer;
 	if (header->type == ACPI_MADT_TYPE_LOCAL_APIC)
 	if (header->type == ACPI_MADT_TYPE_LOCAL_APIC)
-		map_lapic_id(header, acpi_id, &apic_id);
+		map_lapic_id(header, acpi_id, &phys_id);
 	else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC)
 	else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC)
-		map_lsapic_id(header, type, acpi_id, &apic_id);
+		map_lsapic_id(header, type, acpi_id, &phys_id);
 	else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC)
 	else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC)
-		map_x2apic_id(header, type, acpi_id, &apic_id);
+		map_x2apic_id(header, type, acpi_id, &phys_id);
 
 
 exit:
 exit:
 	kfree(buffer.pointer);
 	kfree(buffer.pointer);
-	return apic_id;
+	return phys_id;
 }
 }
 
 
-int acpi_get_apicid(acpi_handle handle, int type, u32 acpi_id)
+int acpi_get_phys_id(acpi_handle handle, int type, u32 acpi_id)
 {
 {
-	int apic_id;
+	int phys_id;
 
 
-	apic_id = map_mat_entry(handle, type, acpi_id);
-	if (apic_id == -1)
-		apic_id = map_madt_entry(type, acpi_id);
+	phys_id = map_mat_entry(handle, type, acpi_id);
+	if (phys_id == -1)
+		phys_id = map_madt_entry(type, acpi_id);
 
 
-	return apic_id;
+	return phys_id;
 }
 }
 
 
-int acpi_map_cpuid(int apic_id, u32 acpi_id)
+int acpi_map_cpuid(int phys_id, u32 acpi_id)
 {
 {
 #ifdef CONFIG_SMP
 #ifdef CONFIG_SMP
 	int i;
 	int i;
 #endif
 #endif
 
 
-	if (apic_id == -1) {
+	if (phys_id == -1) {
 		/*
 		/*
 		 * On UP processor, there is no _MAT or MADT table.
 		 * On UP processor, there is no _MAT or MADT table.
-		 * So above apic_id is always set to -1.
+		 * So above phys_id is always set to -1.
 		 *
 		 *
 		 * BIOS may define multiple CPU handles even for UP processor.
 		 * BIOS may define multiple CPU handles even for UP processor.
 		 * For example,
 		 * For example,
@@ -170,7 +170,7 @@ int acpi_map_cpuid(int apic_id, u32 acpi_id)
 		 *     Processor (CPU3, 0x03, 0x00000410, 0x06) {}
 		 *     Processor (CPU3, 0x03, 0x00000410, 0x06) {}
 		 * }
 		 * }
 		 *
 		 *
-		 * Ignores apic_id and always returns 0 for the processor
+		 * Ignores phys_id and always returns 0 for the processor
 		 * handle with acpi id 0 if nr_cpu_ids is 1.
 		 * handle with acpi id 0 if nr_cpu_ids is 1.
 		 * This should be the case if SMP tables are not found.
 		 * This should be the case if SMP tables are not found.
 		 * Return -1 for other CPU's handle.
 		 * Return -1 for other CPU's handle.
@@ -178,28 +178,28 @@ int acpi_map_cpuid(int apic_id, u32 acpi_id)
 		if (nr_cpu_ids <= 1 && acpi_id == 0)
 		if (nr_cpu_ids <= 1 && acpi_id == 0)
 			return acpi_id;
 			return acpi_id;
 		else
 		else
-			return apic_id;
+			return phys_id;
 	}
 	}
 
 
 #ifdef CONFIG_SMP
 #ifdef CONFIG_SMP
 	for_each_possible_cpu(i) {
 	for_each_possible_cpu(i) {
-		if (cpu_physical_id(i) == apic_id)
+		if (cpu_physical_id(i) == phys_id)
 			return i;
 			return i;
 	}
 	}
 #else
 #else
 	/* In UP kernel, only processor 0 is valid */
 	/* In UP kernel, only processor 0 is valid */
-	if (apic_id == 0)
-		return apic_id;
+	if (phys_id == 0)
+		return phys_id;
 #endif
 #endif
 	return -1;
 	return -1;
 }
 }
 
 
 int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id)
 int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id)
 {
 {
-	int apic_id;
+	int phys_id;
 
 
-	apic_id = acpi_get_apicid(handle, type, acpi_id);
+	phys_id = acpi_get_phys_id(handle, type, acpi_id);
 
 
-	return acpi_map_cpuid(apic_id, acpi_id);
+	return acpi_map_cpuid(phys_id, acpi_id);
 }
 }
 EXPORT_SYMBOL_GPL(acpi_get_cpuid);
 EXPORT_SYMBOL_GPL(acpi_get_cpuid);

+ 8 - 5
drivers/acpi/scan.c

@@ -1001,7 +1001,7 @@ static void acpi_free_power_resources_lists(struct acpi_device *device)
 	if (device->wakeup.flags.valid)
 	if (device->wakeup.flags.valid)
 		acpi_power_resources_list_free(&device->wakeup.resources);
 		acpi_power_resources_list_free(&device->wakeup.resources);
 
 
-	if (!device->flags.power_manageable)
+	if (!device->power.flags.power_resources)
 		return;
 		return;
 
 
 	for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++) {
 	for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++) {
@@ -1744,10 +1744,8 @@ static void acpi_bus_get_power_flags(struct acpi_device *device)
 			device->power.flags.power_resources)
 			device->power.flags.power_resources)
 		device->power.states[ACPI_STATE_D3_COLD].flags.os_accessible = 1;
 		device->power.states[ACPI_STATE_D3_COLD].flags.os_accessible = 1;
 
 
-	if (acpi_bus_init_power(device)) {
-		acpi_free_power_resources_lists(device);
+	if (acpi_bus_init_power(device))
 		device->flags.power_manageable = 0;
 		device->flags.power_manageable = 0;
-	}
 }
 }
 
 
 static void acpi_bus_get_flags(struct acpi_device *device)
 static void acpi_bus_get_flags(struct acpi_device *device)
@@ -2371,13 +2369,18 @@ static void acpi_bus_attach(struct acpi_device *device)
 	/* Skip devices that are not present. */
 	/* Skip devices that are not present. */
 	if (!acpi_device_is_present(device)) {
 	if (!acpi_device_is_present(device)) {
 		device->flags.visited = false;
 		device->flags.visited = false;
+		device->flags.power_manageable = 0;
 		return;
 		return;
 	}
 	}
 	if (device->handler)
 	if (device->handler)
 		goto ok;
 		goto ok;
 
 
 	if (!device->flags.initialized) {
 	if (!device->flags.initialized) {
-		acpi_bus_update_power(device, NULL);
+		device->flags.power_manageable =
+			device->power.states[ACPI_STATE_D0].flags.valid;
+		if (acpi_bus_init_power(device))
+			device->flags.power_manageable = 0;
+
 		device->flags.initialized = true;
 		device->flags.initialized = true;
 	}
 	}
 	device->flags.visited = false;
 	device->flags.visited = false;

+ 10 - 0
drivers/acpi/video.c

@@ -522,6 +522,16 @@ static struct dmi_system_id video_dmi_table[] __initdata = {
 		DMI_MATCH(DMI_PRODUCT_NAME, "370R4E/370R4V/370R5E/3570RE/370R5V"),
 		DMI_MATCH(DMI_PRODUCT_NAME, "370R4E/370R4V/370R5E/3570RE/370R5V"),
 		},
 		},
 	},
 	},
+
+	{
+	 /* https://bugzilla.redhat.com/show_bug.cgi?id=1163574 */
+	 .callback = video_disable_native_backlight,
+	 .ident = "Dell XPS15 L521X",
+	 .matches = {
+		DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+		DMI_MATCH(DMI_PRODUCT_NAME, "XPS L521X"),
+		},
+	},
 	{}
 	{}
 };
 };
 
 

+ 2 - 1
drivers/char/ipmi/ipmi_ssif.c

@@ -969,7 +969,8 @@ static void sender(void                *send_info,
 
 
 		do_gettimeofday(&t);
 		do_gettimeofday(&t);
 		pr_info("**Enqueue %02x %02x: %ld.%6.6ld\n",
 		pr_info("**Enqueue %02x %02x: %ld.%6.6ld\n",
-		       msg->data[0], msg->data[1], t.tv_sec, t.tv_usec);
+		       msg->data[0], msg->data[1],
+		       (long) t.tv_sec, (long) t.tv_usec);
 	}
 	}
 }
 }
 
 

+ 67 - 89
drivers/gpio/gpio-dln2.c

@@ -47,13 +47,6 @@
 
 
 #define DLN2_GPIO_MAX_PINS 32
 #define DLN2_GPIO_MAX_PINS 32
 
 
-struct dln2_irq_work {
-	struct work_struct work;
-	struct dln2_gpio *dln2;
-	int pin;
-	int type;
-};
-
 struct dln2_gpio {
 struct dln2_gpio {
 	struct platform_device *pdev;
 	struct platform_device *pdev;
 	struct gpio_chip gpio;
 	struct gpio_chip gpio;
@@ -64,10 +57,12 @@ struct dln2_gpio {
 	 */
 	 */
 	DECLARE_BITMAP(output_enabled, DLN2_GPIO_MAX_PINS);
 	DECLARE_BITMAP(output_enabled, DLN2_GPIO_MAX_PINS);
 
 
-	DECLARE_BITMAP(irqs_masked, DLN2_GPIO_MAX_PINS);
-	DECLARE_BITMAP(irqs_enabled, DLN2_GPIO_MAX_PINS);
-	DECLARE_BITMAP(irqs_pending, DLN2_GPIO_MAX_PINS);
-	struct dln2_irq_work *irq_work;
+	/* active IRQs - not synced to hardware */
+	DECLARE_BITMAP(unmasked_irqs, DLN2_GPIO_MAX_PINS);
+	/* active IRQS - synced to hardware */
+	DECLARE_BITMAP(enabled_irqs, DLN2_GPIO_MAX_PINS);
+	int irq_type[DLN2_GPIO_MAX_PINS];
+	struct mutex irq_lock;
 };
 };
 
 
 struct dln2_gpio_pin {
 struct dln2_gpio_pin {
@@ -141,16 +136,16 @@ static int dln2_gpio_pin_get_out_val(struct dln2_gpio *dln2, unsigned int pin)
 	return !!ret;
 	return !!ret;
 }
 }
 
 
-static void dln2_gpio_pin_set_out_val(struct dln2_gpio *dln2,
-				      unsigned int pin, int value)
+static int dln2_gpio_pin_set_out_val(struct dln2_gpio *dln2,
+				     unsigned int pin, int value)
 {
 {
 	struct dln2_gpio_pin_val req = {
 	struct dln2_gpio_pin_val req = {
 		.pin = cpu_to_le16(pin),
 		.pin = cpu_to_le16(pin),
 		.value = value,
 		.value = value,
 	};
 	};
 
 
-	dln2_transfer_tx(dln2->pdev, DLN2_GPIO_PIN_SET_OUT_VAL, &req,
-			 sizeof(req));
+	return dln2_transfer_tx(dln2->pdev, DLN2_GPIO_PIN_SET_OUT_VAL, &req,
+				sizeof(req));
 }
 }
 
 
 #define DLN2_GPIO_DIRECTION_IN		0
 #define DLN2_GPIO_DIRECTION_IN		0
@@ -267,6 +262,13 @@ static int dln2_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
 static int dln2_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
 static int dln2_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
 				      int value)
 				      int value)
 {
 {
+	struct dln2_gpio *dln2 = container_of(chip, struct dln2_gpio, gpio);
+	int ret;
+
+	ret = dln2_gpio_pin_set_out_val(dln2, offset, value);
+	if (ret < 0)
+		return ret;
+
 	return dln2_gpio_set_direction(chip, offset, DLN2_GPIO_DIRECTION_OUT);
 	return dln2_gpio_set_direction(chip, offset, DLN2_GPIO_DIRECTION_OUT);
 }
 }
 
 
@@ -297,36 +299,13 @@ static int dln2_gpio_set_event_cfg(struct dln2_gpio *dln2, unsigned pin,
 				&req, sizeof(req));
 				&req, sizeof(req));
 }
 }
 
 
-static void dln2_irq_work(struct work_struct *w)
-{
-	struct dln2_irq_work *iw = container_of(w, struct dln2_irq_work, work);
-	struct dln2_gpio *dln2 = iw->dln2;
-	u8 type = iw->type & DLN2_GPIO_EVENT_MASK;
-
-	if (test_bit(iw->pin, dln2->irqs_enabled))
-		dln2_gpio_set_event_cfg(dln2, iw->pin, type, 0);
-	else
-		dln2_gpio_set_event_cfg(dln2, iw->pin, DLN2_GPIO_EVENT_NONE, 0);
-}
-
-static void dln2_irq_enable(struct irq_data *irqd)
-{
-	struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
-	struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio);
-	int pin = irqd_to_hwirq(irqd);
-
-	set_bit(pin, dln2->irqs_enabled);
-	schedule_work(&dln2->irq_work[pin].work);
-}
-
-static void dln2_irq_disable(struct irq_data *irqd)
+static void dln2_irq_unmask(struct irq_data *irqd)
 {
 {
 	struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
 	struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
 	struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio);
 	struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio);
 	int pin = irqd_to_hwirq(irqd);
 	int pin = irqd_to_hwirq(irqd);
 
 
-	clear_bit(pin, dln2->irqs_enabled);
-	schedule_work(&dln2->irq_work[pin].work);
+	set_bit(pin, dln2->unmasked_irqs);
 }
 }
 
 
 static void dln2_irq_mask(struct irq_data *irqd)
 static void dln2_irq_mask(struct irq_data *irqd)
@@ -335,27 +314,7 @@ static void dln2_irq_mask(struct irq_data *irqd)
 	struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio);
 	struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio);
 	int pin = irqd_to_hwirq(irqd);
 	int pin = irqd_to_hwirq(irqd);
 
 
-	set_bit(pin, dln2->irqs_masked);
-}
-
-static void dln2_irq_unmask(struct irq_data *irqd)
-{
-	struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
-	struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio);
-	struct device *dev = dln2->gpio.dev;
-	int pin = irqd_to_hwirq(irqd);
-
-	if (test_and_clear_bit(pin, dln2->irqs_pending)) {
-		int irq;
-
-		irq = irq_find_mapping(dln2->gpio.irqdomain, pin);
-		if (!irq) {
-			dev_err(dev, "pin %d not mapped to IRQ\n", pin);
-			return;
-		}
-
-		generic_handle_irq(irq);
-	}
+	clear_bit(pin, dln2->unmasked_irqs);
 }
 }
 
 
 static int dln2_irq_set_type(struct irq_data *irqd, unsigned type)
 static int dln2_irq_set_type(struct irq_data *irqd, unsigned type)
@@ -366,19 +325,19 @@ static int dln2_irq_set_type(struct irq_data *irqd, unsigned type)
 
 
 	switch (type) {
 	switch (type) {
 	case IRQ_TYPE_LEVEL_HIGH:
 	case IRQ_TYPE_LEVEL_HIGH:
-		dln2->irq_work[pin].type = DLN2_GPIO_EVENT_LVL_HIGH;
+		dln2->irq_type[pin] = DLN2_GPIO_EVENT_LVL_HIGH;
 		break;
 		break;
 	case IRQ_TYPE_LEVEL_LOW:
 	case IRQ_TYPE_LEVEL_LOW:
-		dln2->irq_work[pin].type = DLN2_GPIO_EVENT_LVL_LOW;
+		dln2->irq_type[pin] = DLN2_GPIO_EVENT_LVL_LOW;
 		break;
 		break;
 	case IRQ_TYPE_EDGE_BOTH:
 	case IRQ_TYPE_EDGE_BOTH:
-		dln2->irq_work[pin].type = DLN2_GPIO_EVENT_CHANGE;
+		dln2->irq_type[pin] = DLN2_GPIO_EVENT_CHANGE;
 		break;
 		break;
 	case IRQ_TYPE_EDGE_RISING:
 	case IRQ_TYPE_EDGE_RISING:
-		dln2->irq_work[pin].type = DLN2_GPIO_EVENT_CHANGE_RISING;
+		dln2->irq_type[pin] = DLN2_GPIO_EVENT_CHANGE_RISING;
 		break;
 		break;
 	case IRQ_TYPE_EDGE_FALLING:
 	case IRQ_TYPE_EDGE_FALLING:
-		dln2->irq_work[pin].type = DLN2_GPIO_EVENT_CHANGE_FALLING;
+		dln2->irq_type[pin] = DLN2_GPIO_EVENT_CHANGE_FALLING;
 		break;
 		break;
 	default:
 	default:
 		return -EINVAL;
 		return -EINVAL;
@@ -387,13 +346,50 @@ static int dln2_irq_set_type(struct irq_data *irqd, unsigned type)
 	return 0;
 	return 0;
 }
 }
 
 
+static void dln2_irq_bus_lock(struct irq_data *irqd)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
+	struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio);
+
+	mutex_lock(&dln2->irq_lock);
+}
+
+static void dln2_irq_bus_unlock(struct irq_data *irqd)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
+	struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio);
+	int pin = irqd_to_hwirq(irqd);
+	int enabled, unmasked;
+	unsigned type;
+	int ret;
+
+	enabled = test_bit(pin, dln2->enabled_irqs);
+	unmasked = test_bit(pin, dln2->unmasked_irqs);
+
+	if (enabled != unmasked) {
+		if (unmasked) {
+			type = dln2->irq_type[pin] & DLN2_GPIO_EVENT_MASK;
+			set_bit(pin, dln2->enabled_irqs);
+		} else {
+			type = DLN2_GPIO_EVENT_NONE;
+			clear_bit(pin, dln2->enabled_irqs);
+		}
+
+		ret = dln2_gpio_set_event_cfg(dln2, pin, type, 0);
+		if (ret)
+			dev_err(dln2->gpio.dev, "failed to set event\n");
+	}
+
+	mutex_unlock(&dln2->irq_lock);
+}
+
 static struct irq_chip dln2_gpio_irqchip = {
 static struct irq_chip dln2_gpio_irqchip = {
 	.name = "dln2-irq",
 	.name = "dln2-irq",
-	.irq_enable = dln2_irq_enable,
-	.irq_disable = dln2_irq_disable,
 	.irq_mask = dln2_irq_mask,
 	.irq_mask = dln2_irq_mask,
 	.irq_unmask = dln2_irq_unmask,
 	.irq_unmask = dln2_irq_unmask,
 	.irq_set_type = dln2_irq_set_type,
 	.irq_set_type = dln2_irq_set_type,
+	.irq_bus_lock = dln2_irq_bus_lock,
+	.irq_bus_sync_unlock = dln2_irq_bus_unlock,
 };
 };
 
 
 static void dln2_gpio_event(struct platform_device *pdev, u16 echo,
 static void dln2_gpio_event(struct platform_device *pdev, u16 echo,
@@ -425,14 +421,7 @@ static void dln2_gpio_event(struct platform_device *pdev, u16 echo,
 		return;
 		return;
 	}
 	}
 
 
-	if (!test_bit(pin, dln2->irqs_enabled))
-		return;
-	if (test_bit(pin, dln2->irqs_masked)) {
-		set_bit(pin, dln2->irqs_pending);
-		return;
-	}
-
-	switch (dln2->irq_work[pin].type) {
+	switch (dln2->irq_type[pin]) {
 	case DLN2_GPIO_EVENT_CHANGE_RISING:
 	case DLN2_GPIO_EVENT_CHANGE_RISING:
 		if (event->value)
 		if (event->value)
 			generic_handle_irq(irq);
 			generic_handle_irq(irq);
@@ -451,7 +440,7 @@ static int dln2_gpio_probe(struct platform_device *pdev)
 	struct dln2_gpio *dln2;
 	struct dln2_gpio *dln2;
 	struct device *dev = &pdev->dev;
 	struct device *dev = &pdev->dev;
 	int pins;
 	int pins;
-	int i, ret;
+	int ret;
 
 
 	pins = dln2_gpio_get_pin_count(pdev);
 	pins = dln2_gpio_get_pin_count(pdev);
 	if (pins < 0) {
 	if (pins < 0) {
@@ -467,15 +456,7 @@ static int dln2_gpio_probe(struct platform_device *pdev)
 	if (!dln2)
 	if (!dln2)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	dln2->irq_work = devm_kcalloc(&pdev->dev, pins,
-				      sizeof(struct dln2_irq_work), GFP_KERNEL);
-	if (!dln2->irq_work)
-		return -ENOMEM;
-	for (i = 0; i < pins; i++) {
-		INIT_WORK(&dln2->irq_work[i].work, dln2_irq_work);
-		dln2->irq_work[i].pin = i;
-		dln2->irq_work[i].dln2 = dln2;
-	}
+	mutex_init(&dln2->irq_lock);
 
 
 	dln2->pdev = pdev;
 	dln2->pdev = pdev;
 
 
@@ -529,11 +510,8 @@ out:
 static int dln2_gpio_remove(struct platform_device *pdev)
 static int dln2_gpio_remove(struct platform_device *pdev)
 {
 {
 	struct dln2_gpio *dln2 = platform_get_drvdata(pdev);
 	struct dln2_gpio *dln2 = platform_get_drvdata(pdev);
-	int i;
 
 
 	dln2_unregister_event_cb(pdev, DLN2_GPIO_CONDITION_MET_EV);
 	dln2_unregister_event_cb(pdev, DLN2_GPIO_CONDITION_MET_EV);
-	for (i = 0; i < dln2->gpio.ngpio; i++)
-		flush_work(&dln2->irq_work[i].work);
 	gpiochip_remove(&dln2->gpio);
 	gpiochip_remove(&dln2->gpio);
 
 
 	return 0;
 	return 0;

+ 2 - 1
drivers/gpio/gpio-grgpio.c

@@ -441,7 +441,8 @@ static int grgpio_probe(struct platform_device *ofdev)
 	err = gpiochip_add(gc);
 	err = gpiochip_add(gc);
 	if (err) {
 	if (err) {
 		dev_err(&ofdev->dev, "Could not add gpiochip\n");
 		dev_err(&ofdev->dev, "Could not add gpiochip\n");
-		irq_domain_remove(priv->domain);
+		if (priv->domain)
+			irq_domain_remove(priv->domain);
 		return err;
 		return err;
 	}
 	}
 
 

+ 1 - 1
drivers/gpu/drm/Makefile

@@ -37,6 +37,7 @@ obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o
 obj-$(CONFIG_DRM_TTM)	+= ttm/
 obj-$(CONFIG_DRM_TTM)	+= ttm/
 obj-$(CONFIG_DRM_TDFX)	+= tdfx/
 obj-$(CONFIG_DRM_TDFX)	+= tdfx/
 obj-$(CONFIG_DRM_R128)	+= r128/
 obj-$(CONFIG_DRM_R128)	+= r128/
+obj-$(CONFIG_HSA_AMD) += amd/amdkfd/
 obj-$(CONFIG_DRM_RADEON)+= radeon/
 obj-$(CONFIG_DRM_RADEON)+= radeon/
 obj-$(CONFIG_DRM_MGA)	+= mga/
 obj-$(CONFIG_DRM_MGA)	+= mga/
 obj-$(CONFIG_DRM_I810)	+= i810/
 obj-$(CONFIG_DRM_I810)	+= i810/
@@ -67,4 +68,3 @@ obj-$(CONFIG_DRM_IMX) += imx/
 obj-y			+= i2c/
 obj-y			+= i2c/
 obj-y			+= panel/
 obj-y			+= panel/
 obj-y			+= bridge/
 obj-y			+= bridge/
-obj-$(CONFIG_HSA_AMD) += amd/amdkfd/

+ 168 - 148
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c

@@ -31,7 +31,6 @@
 #include <uapi/linux/kfd_ioctl.h>
 #include <uapi/linux/kfd_ioctl.h>
 #include <linux/time.h>
 #include <linux/time.h>
 #include <linux/mm.h>
 #include <linux/mm.h>
-#include <linux/uaccess.h>
 #include <uapi/asm-generic/mman-common.h>
 #include <uapi/asm-generic/mman-common.h>
 #include <asm/processor.h>
 #include <asm/processor.h>
 #include "kfd_priv.h"
 #include "kfd_priv.h"
@@ -127,17 +126,14 @@ static int kfd_open(struct inode *inode, struct file *filep)
 	return 0;
 	return 0;
 }
 }
 
 
-static long kfd_ioctl_get_version(struct file *filep, struct kfd_process *p,
-					void __user *arg)
+static int kfd_ioctl_get_version(struct file *filep, struct kfd_process *p,
+					void *data)
 {
 {
-	struct kfd_ioctl_get_version_args args;
+	struct kfd_ioctl_get_version_args *args = data;
 	int err = 0;
 	int err = 0;
 
 
-	args.major_version = KFD_IOCTL_MAJOR_VERSION;
-	args.minor_version = KFD_IOCTL_MINOR_VERSION;
-
-	if (copy_to_user(arg, &args, sizeof(args)))
-		err = -EFAULT;
+	args->major_version = KFD_IOCTL_MAJOR_VERSION;
+	args->minor_version = KFD_IOCTL_MINOR_VERSION;
 
 
 	return err;
 	return err;
 }
 }
@@ -221,10 +217,10 @@ static int set_queue_properties_from_user(struct queue_properties *q_properties,
 	return 0;
 	return 0;
 }
 }
 
 
-static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
-					void __user *arg)
+static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
+					void *data)
 {
 {
-	struct kfd_ioctl_create_queue_args args;
+	struct kfd_ioctl_create_queue_args *args = data;
 	struct kfd_dev *dev;
 	struct kfd_dev *dev;
 	int err = 0;
 	int err = 0;
 	unsigned int queue_id;
 	unsigned int queue_id;
@@ -233,16 +229,13 @@ static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
 
 
 	memset(&q_properties, 0, sizeof(struct queue_properties));
 	memset(&q_properties, 0, sizeof(struct queue_properties));
 
 
-	if (copy_from_user(&args, arg, sizeof(args)))
-		return -EFAULT;
-
 	pr_debug("kfd: creating queue ioctl\n");
 	pr_debug("kfd: creating queue ioctl\n");
 
 
-	err = set_queue_properties_from_user(&q_properties, &args);
+	err = set_queue_properties_from_user(&q_properties, args);
 	if (err)
 	if (err)
 		return err;
 		return err;
 
 
-	dev = kfd_device_by_id(args.gpu_id);
+	dev = kfd_device_by_id(args->gpu_id);
 	if (dev == NULL)
 	if (dev == NULL)
 		return -EINVAL;
 		return -EINVAL;
 
 
@@ -250,7 +243,7 @@ static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
 
 
 	pdd = kfd_bind_process_to_device(dev, p);
 	pdd = kfd_bind_process_to_device(dev, p);
 	if (IS_ERR(pdd)) {
 	if (IS_ERR(pdd)) {
-		err = PTR_ERR(pdd);
+		err = -ESRCH;
 		goto err_bind_process;
 		goto err_bind_process;
 	}
 	}
 
 
@@ -263,33 +256,26 @@ static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
 	if (err != 0)
 	if (err != 0)
 		goto err_create_queue;
 		goto err_create_queue;
 
 
-	args.queue_id = queue_id;
+	args->queue_id = queue_id;
 
 
 	/* Return gpu_id as doorbell offset for mmap usage */
 	/* Return gpu_id as doorbell offset for mmap usage */
-	args.doorbell_offset = args.gpu_id << PAGE_SHIFT;
-
-	if (copy_to_user(arg, &args, sizeof(args))) {
-		err = -EFAULT;
-		goto err_copy_args_out;
-	}
+	args->doorbell_offset = args->gpu_id << PAGE_SHIFT;
 
 
 	mutex_unlock(&p->mutex);
 	mutex_unlock(&p->mutex);
 
 
-	pr_debug("kfd: queue id %d was created successfully\n", args.queue_id);
+	pr_debug("kfd: queue id %d was created successfully\n", args->queue_id);
 
 
 	pr_debug("ring buffer address == 0x%016llX\n",
 	pr_debug("ring buffer address == 0x%016llX\n",
-			args.ring_base_address);
+			args->ring_base_address);
 
 
 	pr_debug("read ptr address    == 0x%016llX\n",
 	pr_debug("read ptr address    == 0x%016llX\n",
-			args.read_pointer_address);
+			args->read_pointer_address);
 
 
 	pr_debug("write ptr address   == 0x%016llX\n",
 	pr_debug("write ptr address   == 0x%016llX\n",
-			args.write_pointer_address);
+			args->write_pointer_address);
 
 
 	return 0;
 	return 0;
 
 
-err_copy_args_out:
-	pqm_destroy_queue(&p->pqm, queue_id);
 err_create_queue:
 err_create_queue:
 err_bind_process:
 err_bind_process:
 	mutex_unlock(&p->mutex);
 	mutex_unlock(&p->mutex);
@@ -297,99 +283,90 @@ err_bind_process:
 }
 }
 
 
 static int kfd_ioctl_destroy_queue(struct file *filp, struct kfd_process *p,
 static int kfd_ioctl_destroy_queue(struct file *filp, struct kfd_process *p,
-					void __user *arg)
+					void *data)
 {
 {
 	int retval;
 	int retval;
-	struct kfd_ioctl_destroy_queue_args args;
-
-	if (copy_from_user(&args, arg, sizeof(args)))
-		return -EFAULT;
+	struct kfd_ioctl_destroy_queue_args *args = data;
 
 
 	pr_debug("kfd: destroying queue id %d for PASID %d\n",
 	pr_debug("kfd: destroying queue id %d for PASID %d\n",
-				args.queue_id,
+				args->queue_id,
 				p->pasid);
 				p->pasid);
 
 
 	mutex_lock(&p->mutex);
 	mutex_lock(&p->mutex);
 
 
-	retval = pqm_destroy_queue(&p->pqm, args.queue_id);
+	retval = pqm_destroy_queue(&p->pqm, args->queue_id);
 
 
 	mutex_unlock(&p->mutex);
 	mutex_unlock(&p->mutex);
 	return retval;
 	return retval;
 }
 }
 
 
 static int kfd_ioctl_update_queue(struct file *filp, struct kfd_process *p,
 static int kfd_ioctl_update_queue(struct file *filp, struct kfd_process *p,
-					void __user *arg)
+					void *data)
 {
 {
 	int retval;
 	int retval;
-	struct kfd_ioctl_update_queue_args args;
+	struct kfd_ioctl_update_queue_args *args = data;
 	struct queue_properties properties;
 	struct queue_properties properties;
 
 
-	if (copy_from_user(&args, arg, sizeof(args)))
-		return -EFAULT;
-
-	if (args.queue_percentage > KFD_MAX_QUEUE_PERCENTAGE) {
+	if (args->queue_percentage > KFD_MAX_QUEUE_PERCENTAGE) {
 		pr_err("kfd: queue percentage must be between 0 to KFD_MAX_QUEUE_PERCENTAGE\n");
 		pr_err("kfd: queue percentage must be between 0 to KFD_MAX_QUEUE_PERCENTAGE\n");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	if (args.queue_priority > KFD_MAX_QUEUE_PRIORITY) {
+	if (args->queue_priority > KFD_MAX_QUEUE_PRIORITY) {
 		pr_err("kfd: queue priority must be between 0 to KFD_MAX_QUEUE_PRIORITY\n");
 		pr_err("kfd: queue priority must be between 0 to KFD_MAX_QUEUE_PRIORITY\n");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	if ((args.ring_base_address) &&
+	if ((args->ring_base_address) &&
 		(!access_ok(VERIFY_WRITE,
 		(!access_ok(VERIFY_WRITE,
-			(const void __user *) args.ring_base_address,
+			(const void __user *) args->ring_base_address,
 			sizeof(uint64_t)))) {
 			sizeof(uint64_t)))) {
 		pr_err("kfd: can't access ring base address\n");
 		pr_err("kfd: can't access ring base address\n");
 		return -EFAULT;
 		return -EFAULT;
 	}
 	}
 
 
-	if (!is_power_of_2(args.ring_size) && (args.ring_size != 0)) {
+	if (!is_power_of_2(args->ring_size) && (args->ring_size != 0)) {
 		pr_err("kfd: ring size must be a power of 2 or 0\n");
 		pr_err("kfd: ring size must be a power of 2 or 0\n");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	properties.queue_address = args.ring_base_address;
-	properties.queue_size = args.ring_size;
-	properties.queue_percent = args.queue_percentage;
-	properties.priority = args.queue_priority;
+	properties.queue_address = args->ring_base_address;
+	properties.queue_size = args->ring_size;
+	properties.queue_percent = args->queue_percentage;
+	properties.priority = args->queue_priority;
 
 
 	pr_debug("kfd: updating queue id %d for PASID %d\n",
 	pr_debug("kfd: updating queue id %d for PASID %d\n",
-			args.queue_id, p->pasid);
+			args->queue_id, p->pasid);
 
 
 	mutex_lock(&p->mutex);
 	mutex_lock(&p->mutex);
 
 
-	retval = pqm_update_queue(&p->pqm, args.queue_id, &properties);
+	retval = pqm_update_queue(&p->pqm, args->queue_id, &properties);
 
 
 	mutex_unlock(&p->mutex);
 	mutex_unlock(&p->mutex);
 
 
 	return retval;
 	return retval;
 }
 }
 
 
-static long kfd_ioctl_set_memory_policy(struct file *filep,
-				struct kfd_process *p, void __user *arg)
+static int kfd_ioctl_set_memory_policy(struct file *filep,
+					struct kfd_process *p, void *data)
 {
 {
-	struct kfd_ioctl_set_memory_policy_args args;
+	struct kfd_ioctl_set_memory_policy_args *args = data;
 	struct kfd_dev *dev;
 	struct kfd_dev *dev;
 	int err = 0;
 	int err = 0;
 	struct kfd_process_device *pdd;
 	struct kfd_process_device *pdd;
 	enum cache_policy default_policy, alternate_policy;
 	enum cache_policy default_policy, alternate_policy;
 
 
-	if (copy_from_user(&args, arg, sizeof(args)))
-		return -EFAULT;
-
-	if (args.default_policy != KFD_IOC_CACHE_POLICY_COHERENT
-	    && args.default_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) {
+	if (args->default_policy != KFD_IOC_CACHE_POLICY_COHERENT
+	    && args->default_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) {
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	if (args.alternate_policy != KFD_IOC_CACHE_POLICY_COHERENT
-	    && args.alternate_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) {
+	if (args->alternate_policy != KFD_IOC_CACHE_POLICY_COHERENT
+	    && args->alternate_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) {
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	dev = kfd_device_by_id(args.gpu_id);
+	dev = kfd_device_by_id(args->gpu_id);
 	if (dev == NULL)
 	if (dev == NULL)
 		return -EINVAL;
 		return -EINVAL;
 
 
@@ -397,23 +374,23 @@ static long kfd_ioctl_set_memory_policy(struct file *filep,
 
 
 	pdd = kfd_bind_process_to_device(dev, p);
 	pdd = kfd_bind_process_to_device(dev, p);
 	if (IS_ERR(pdd)) {
 	if (IS_ERR(pdd)) {
-		err = PTR_ERR(pdd);
+		err = -ESRCH;
 		goto out;
 		goto out;
 	}
 	}
 
 
-	default_policy = (args.default_policy == KFD_IOC_CACHE_POLICY_COHERENT)
+	default_policy = (args->default_policy == KFD_IOC_CACHE_POLICY_COHERENT)
 			 ? cache_policy_coherent : cache_policy_noncoherent;
 			 ? cache_policy_coherent : cache_policy_noncoherent;
 
 
 	alternate_policy =
 	alternate_policy =
-		(args.alternate_policy == KFD_IOC_CACHE_POLICY_COHERENT)
+		(args->alternate_policy == KFD_IOC_CACHE_POLICY_COHERENT)
 		   ? cache_policy_coherent : cache_policy_noncoherent;
 		   ? cache_policy_coherent : cache_policy_noncoherent;
 
 
 	if (!dev->dqm->set_cache_memory_policy(dev->dqm,
 	if (!dev->dqm->set_cache_memory_policy(dev->dqm,
 				&pdd->qpd,
 				&pdd->qpd,
 				default_policy,
 				default_policy,
 				alternate_policy,
 				alternate_policy,
-				(void __user *)args.alternate_aperture_base,
-				args.alternate_aperture_size))
+				(void __user *)args->alternate_aperture_base,
+				args->alternate_aperture_size))
 		err = -EINVAL;
 		err = -EINVAL;
 
 
 out:
 out:
@@ -422,53 +399,44 @@ out:
 	return err;
 	return err;
 }
 }
 
 
-static long kfd_ioctl_get_clock_counters(struct file *filep,
-				struct kfd_process *p, void __user *arg)
+static int kfd_ioctl_get_clock_counters(struct file *filep,
+				struct kfd_process *p, void *data)
 {
 {
-	struct kfd_ioctl_get_clock_counters_args args;
+	struct kfd_ioctl_get_clock_counters_args *args = data;
 	struct kfd_dev *dev;
 	struct kfd_dev *dev;
 	struct timespec time;
 	struct timespec time;
 
 
-	if (copy_from_user(&args, arg, sizeof(args)))
-		return -EFAULT;
-
-	dev = kfd_device_by_id(args.gpu_id);
+	dev = kfd_device_by_id(args->gpu_id);
 	if (dev == NULL)
 	if (dev == NULL)
 		return -EINVAL;
 		return -EINVAL;
 
 
 	/* Reading GPU clock counter from KGD */
 	/* Reading GPU clock counter from KGD */
-	args.gpu_clock_counter = kfd2kgd->get_gpu_clock_counter(dev->kgd);
+	args->gpu_clock_counter = kfd2kgd->get_gpu_clock_counter(dev->kgd);
 
 
 	/* No access to rdtsc. Using raw monotonic time */
 	/* No access to rdtsc. Using raw monotonic time */
 	getrawmonotonic(&time);
 	getrawmonotonic(&time);
-	args.cpu_clock_counter = (uint64_t)timespec_to_ns(&time);
+	args->cpu_clock_counter = (uint64_t)timespec_to_ns(&time);
 
 
 	get_monotonic_boottime(&time);
 	get_monotonic_boottime(&time);
-	args.system_clock_counter = (uint64_t)timespec_to_ns(&time);
+	args->system_clock_counter = (uint64_t)timespec_to_ns(&time);
 
 
 	/* Since the counter is in nano-seconds we use 1GHz frequency */
 	/* Since the counter is in nano-seconds we use 1GHz frequency */
-	args.system_clock_freq = 1000000000;
-
-	if (copy_to_user(arg, &args, sizeof(args)))
-		return -EFAULT;
+	args->system_clock_freq = 1000000000;
 
 
 	return 0;
 	return 0;
 }
 }
 
 
 
 
 static int kfd_ioctl_get_process_apertures(struct file *filp,
 static int kfd_ioctl_get_process_apertures(struct file *filp,
-				struct kfd_process *p, void __user *arg)
+				struct kfd_process *p, void *data)
 {
 {
-	struct kfd_ioctl_get_process_apertures_args args;
+	struct kfd_ioctl_get_process_apertures_args *args = data;
 	struct kfd_process_device_apertures *pAperture;
 	struct kfd_process_device_apertures *pAperture;
 	struct kfd_process_device *pdd;
 	struct kfd_process_device *pdd;
 
 
 	dev_dbg(kfd_device, "get apertures for PASID %d", p->pasid);
 	dev_dbg(kfd_device, "get apertures for PASID %d", p->pasid);
 
 
-	if (copy_from_user(&args, arg, sizeof(args)))
-		return -EFAULT;
-
-	args.num_of_nodes = 0;
+	args->num_of_nodes = 0;
 
 
 	mutex_lock(&p->mutex);
 	mutex_lock(&p->mutex);
 
 
@@ -477,7 +445,8 @@ static int kfd_ioctl_get_process_apertures(struct file *filp,
 		/* Run over all pdd of the process */
 		/* Run over all pdd of the process */
 		pdd = kfd_get_first_process_device_data(p);
 		pdd = kfd_get_first_process_device_data(p);
 		do {
 		do {
-			pAperture = &args.process_apertures[args.num_of_nodes];
+			pAperture =
+				&args->process_apertures[args->num_of_nodes];
 			pAperture->gpu_id = pdd->dev->id;
 			pAperture->gpu_id = pdd->dev->id;
 			pAperture->lds_base = pdd->lds_base;
 			pAperture->lds_base = pdd->lds_base;
 			pAperture->lds_limit = pdd->lds_limit;
 			pAperture->lds_limit = pdd->lds_limit;
@@ -487,7 +456,7 @@ static int kfd_ioctl_get_process_apertures(struct file *filp,
 			pAperture->scratch_limit = pdd->scratch_limit;
 			pAperture->scratch_limit = pdd->scratch_limit;
 
 
 			dev_dbg(kfd_device,
 			dev_dbg(kfd_device,
-				"node id %u\n", args.num_of_nodes);
+				"node id %u\n", args->num_of_nodes);
 			dev_dbg(kfd_device,
 			dev_dbg(kfd_device,
 				"gpu id %u\n", pdd->dev->id);
 				"gpu id %u\n", pdd->dev->id);
 			dev_dbg(kfd_device,
 			dev_dbg(kfd_device,
@@ -503,80 +472,131 @@ static int kfd_ioctl_get_process_apertures(struct file *filp,
 			dev_dbg(kfd_device,
 			dev_dbg(kfd_device,
 				"scratch_limit %llX\n", pdd->scratch_limit);
 				"scratch_limit %llX\n", pdd->scratch_limit);
 
 
-			args.num_of_nodes++;
+			args->num_of_nodes++;
 		} while ((pdd = kfd_get_next_process_device_data(p, pdd)) != NULL &&
 		} while ((pdd = kfd_get_next_process_device_data(p, pdd)) != NULL &&
-				(args.num_of_nodes < NUM_OF_SUPPORTED_GPUS));
+				(args->num_of_nodes < NUM_OF_SUPPORTED_GPUS));
 	}
 	}
 
 
 	mutex_unlock(&p->mutex);
 	mutex_unlock(&p->mutex);
 
 
-	if (copy_to_user(arg, &args, sizeof(args)))
-		return -EFAULT;
-
 	return 0;
 	return 0;
 }
 }
 
 
+#define AMDKFD_IOCTL_DEF(ioctl, _func, _flags) \
+	[_IOC_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0, .name = #ioctl}
+
+/** Ioctl table */
+static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = {
+	AMDKFD_IOCTL_DEF(AMDKFD_IOC_GET_VERSION,
+			kfd_ioctl_get_version, 0),
+
+	AMDKFD_IOCTL_DEF(AMDKFD_IOC_CREATE_QUEUE,
+			kfd_ioctl_create_queue, 0),
+
+	AMDKFD_IOCTL_DEF(AMDKFD_IOC_DESTROY_QUEUE,
+			kfd_ioctl_destroy_queue, 0),
+
+	AMDKFD_IOCTL_DEF(AMDKFD_IOC_SET_MEMORY_POLICY,
+			kfd_ioctl_set_memory_policy, 0),
+
+	AMDKFD_IOCTL_DEF(AMDKFD_IOC_GET_CLOCK_COUNTERS,
+			kfd_ioctl_get_clock_counters, 0),
+
+	AMDKFD_IOCTL_DEF(AMDKFD_IOC_GET_PROCESS_APERTURES,
+			kfd_ioctl_get_process_apertures, 0),
+
+	AMDKFD_IOCTL_DEF(AMDKFD_IOC_UPDATE_QUEUE,
+			kfd_ioctl_update_queue, 0),
+};
+
+#define AMDKFD_CORE_IOCTL_COUNT	ARRAY_SIZE(amdkfd_ioctls)
+
 static long kfd_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
 static long kfd_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
 {
 {
 	struct kfd_process *process;
 	struct kfd_process *process;
-	long err = -EINVAL;
+	amdkfd_ioctl_t *func;
+	const struct amdkfd_ioctl_desc *ioctl = NULL;
+	unsigned int nr = _IOC_NR(cmd);
+	char stack_kdata[128];
+	char *kdata = NULL;
+	unsigned int usize, asize;
+	int retcode = -EINVAL;
 
 
-	dev_dbg(kfd_device,
-		"ioctl cmd 0x%x (#%d), arg 0x%lx\n",
-		cmd, _IOC_NR(cmd), arg);
+	if (nr >= AMDKFD_CORE_IOCTL_COUNT)
+		goto err_i1;
+
+	if ((nr >= AMDKFD_COMMAND_START) && (nr < AMDKFD_COMMAND_END)) {
+		u32 amdkfd_size;
+
+		ioctl = &amdkfd_ioctls[nr];
+
+		amdkfd_size = _IOC_SIZE(ioctl->cmd);
+		usize = asize = _IOC_SIZE(cmd);
+		if (amdkfd_size > asize)
+			asize = amdkfd_size;
+
+		cmd = ioctl->cmd;
+	} else
+		goto err_i1;
+
+	dev_dbg(kfd_device, "ioctl cmd 0x%x (#%d), arg 0x%lx\n", cmd, nr, arg);
 
 
 	process = kfd_get_process(current);
 	process = kfd_get_process(current);
-	if (IS_ERR(process))
-		return PTR_ERR(process);
+	if (IS_ERR(process)) {
+		dev_dbg(kfd_device, "no process\n");
+		goto err_i1;
+	}
 
 
-	switch (cmd) {
-	case KFD_IOC_GET_VERSION:
-		err = kfd_ioctl_get_version(filep, process, (void __user *)arg);
-		break;
-	case KFD_IOC_CREATE_QUEUE:
-		err = kfd_ioctl_create_queue(filep, process,
-						(void __user *)arg);
-		break;
-
-	case KFD_IOC_DESTROY_QUEUE:
-		err = kfd_ioctl_destroy_queue(filep, process,
-						(void __user *)arg);
-		break;
-
-	case KFD_IOC_SET_MEMORY_POLICY:
-		err = kfd_ioctl_set_memory_policy(filep, process,
-						(void __user *)arg);
-		break;
-
-	case KFD_IOC_GET_CLOCK_COUNTERS:
-		err = kfd_ioctl_get_clock_counters(filep, process,
-						(void __user *)arg);
-		break;
-
-	case KFD_IOC_GET_PROCESS_APERTURES:
-		err = kfd_ioctl_get_process_apertures(filep, process,
-						(void __user *)arg);
-		break;
-
-	case KFD_IOC_UPDATE_QUEUE:
-		err = kfd_ioctl_update_queue(filep, process,
-						(void __user *)arg);
-		break;
-
-	default:
-		dev_err(kfd_device,
-			"unknown ioctl cmd 0x%x, arg 0x%lx)\n",
-			cmd, arg);
-		err = -EINVAL;
-		break;
+	/* Do not trust userspace, use our own definition */
+	func = ioctl->func;
+
+	if (unlikely(!func)) {
+		dev_dbg(kfd_device, "no function\n");
+		retcode = -EINVAL;
+		goto err_i1;
 	}
 	}
 
 
-	if (err < 0)
-		dev_err(kfd_device,
-			"ioctl error %ld for ioctl cmd 0x%x (#%d)\n",
-			err, cmd, _IOC_NR(cmd));
+	if (cmd & (IOC_IN | IOC_OUT)) {
+		if (asize <= sizeof(stack_kdata)) {
+			kdata = stack_kdata;
+		} else {
+			kdata = kmalloc(asize, GFP_KERNEL);
+			if (!kdata) {
+				retcode = -ENOMEM;
+				goto err_i1;
+			}
+		}
+		if (asize > usize)
+			memset(kdata + usize, 0, asize - usize);
+	}
 
 
-	return err;
+	if (cmd & IOC_IN) {
+		if (copy_from_user(kdata, (void __user *)arg, usize) != 0) {
+			retcode = -EFAULT;
+			goto err_i1;
+		}
+	} else if (cmd & IOC_OUT) {
+		memset(kdata, 0, usize);
+	}
+
+	retcode = func(filep, process, kdata);
+
+	if (cmd & IOC_OUT)
+		if (copy_to_user((void __user *)arg, kdata, usize) != 0)
+			retcode = -EFAULT;
+
+err_i1:
+	if (!ioctl)
+		dev_dbg(kfd_device, "invalid ioctl: pid=%d, cmd=0x%02x, nr=0x%02x\n",
+			  task_pid_nr(current), cmd, nr);
+
+	if (kdata != stack_kdata)
+		kfree(kdata);
+
+	if (retcode)
+		dev_dbg(kfd_device, "ret = %d\n", retcode);
+
+	return retcode;
 }
 }
 
 
 static int kfd_mmap(struct file *filp, struct vm_area_struct *vma)
 static int kfd_mmap(struct file *filp, struct vm_area_struct *vma)

+ 26 - 2
drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c

@@ -161,6 +161,9 @@ static void deallocate_vmid(struct device_queue_manager *dqm,
 {
 {
 	int bit = qpd->vmid - KFD_VMID_START_OFFSET;
 	int bit = qpd->vmid - KFD_VMID_START_OFFSET;
 
 
+	/* Release the vmid mapping */
+	set_pasid_vmid_mapping(dqm, 0, qpd->vmid);
+
 	set_bit(bit, (unsigned long *)&dqm->vmid_bitmap);
 	set_bit(bit, (unsigned long *)&dqm->vmid_bitmap);
 	qpd->vmid = 0;
 	qpd->vmid = 0;
 	q->properties.vmid = 0;
 	q->properties.vmid = 0;
@@ -272,6 +275,18 @@ static int create_compute_queue_nocpsch(struct device_queue_manager *dqm,
 		return retval;
 		return retval;
 	}
 	}
 
 
+	pr_debug("kfd: loading mqd to hqd on pipe (%d) queue (%d)\n",
+			q->pipe,
+			q->queue);
+
+	retval = mqd->load_mqd(mqd, q->mqd, q->pipe,
+			q->queue, q->properties.write_ptr);
+	if (retval != 0) {
+		deallocate_hqd(dqm, q);
+		mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj);
+		return retval;
+	}
+
 	return 0;
 	return 0;
 }
 }
 
 
@@ -320,6 +335,7 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q)
 {
 {
 	int retval;
 	int retval;
 	struct mqd_manager *mqd;
 	struct mqd_manager *mqd;
+	bool prev_active = false;
 
 
 	BUG_ON(!dqm || !q || !q->mqd);
 	BUG_ON(!dqm || !q || !q->mqd);
 
 
@@ -330,10 +346,18 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q)
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
 
 
-	retval = mqd->update_mqd(mqd, q->mqd, &q->properties);
 	if (q->properties.is_active == true)
 	if (q->properties.is_active == true)
+		prev_active = true;
+
+	/*
+	 *
+	 * check active state vs. the previous state
+	 * and modify counter accordingly
+	 */
+	retval = mqd->update_mqd(mqd, q->mqd, &q->properties);
+	if ((q->properties.is_active == true) && (prev_active == false))
 		dqm->queue_count++;
 		dqm->queue_count++;
-	else
+	else if ((q->properties.is_active == false) && (prev_active == true))
 		dqm->queue_count--;
 		dqm->queue_count--;
 
 
 	if (sched_policy != KFD_SCHED_POLICY_NO_HWS)
 	if (sched_policy != KFD_SCHED_POLICY_NO_HWS)

+ 1 - 1
drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c

@@ -184,7 +184,7 @@ static bool is_occupied(struct mqd_manager *mm, void *mqd,
 			uint32_t queue_id)
 			uint32_t queue_id)
 {
 {
 
 
-	return kfd2kgd->hqd_is_occupies(mm->dev->kgd, queue_address,
+	return kfd2kgd->hqd_is_occupied(mm->dev->kgd, queue_address,
 					pipe_id, queue_id);
 					pipe_id, queue_id);
 
 
 }
 }

+ 1 - 1
drivers/gpu/drm/amd/amdkfd/kfd_pasid.c

@@ -32,7 +32,7 @@ int kfd_pasid_init(void)
 {
 {
 	pasid_limit = max_num_of_processes;
 	pasid_limit = max_num_of_processes;
 
 
-	pasid_bitmap = kzalloc(BITS_TO_LONGS(pasid_limit), GFP_KERNEL);
+	pasid_bitmap = kcalloc(BITS_TO_LONGS(pasid_limit), sizeof(long), GFP_KERNEL);
 	if (!pasid_bitmap)
 	if (!pasid_bitmap)
 		return -ENOMEM;
 		return -ENOMEM;
 
 

+ 18 - 0
drivers/gpu/drm/amd/amdkfd/kfd_priv.h

@@ -463,6 +463,24 @@ struct kfd_process {
 	bool is_32bit_user_mode;
 	bool is_32bit_user_mode;
 };
 };
 
 
+/**
+ * Ioctl function type.
+ *
+ * \param filep pointer to file structure.
+ * \param p amdkfd process pointer.
+ * \param data pointer to arg that was copied from user.
+ */
+typedef int amdkfd_ioctl_t(struct file *filep, struct kfd_process *p,
+				void *data);
+
+struct amdkfd_ioctl_desc {
+	unsigned int cmd;
+	int flags;
+	amdkfd_ioctl_t *func;
+	unsigned int cmd_drv;
+	const char *name;
+};
+
 void kfd_process_create_wq(void);
 void kfd_process_create_wq(void);
 void kfd_process_destroy_wq(void);
 void kfd_process_destroy_wq(void);
 struct kfd_process *kfd_create_process(const struct task_struct *);
 struct kfd_process *kfd_create_process(const struct task_struct *);

+ 1 - 1
drivers/gpu/drm/amd/amdkfd/kfd_topology.c

@@ -921,7 +921,7 @@ static int kfd_build_sysfs_node_tree(void)
 	uint32_t i = 0;
 	uint32_t i = 0;
 
 
 	list_for_each_entry(dev, &topology_device_list, list) {
 	list_for_each_entry(dev, &topology_device_list, list) {
-		ret = kfd_build_sysfs_node_entry(dev, 0);
+		ret = kfd_build_sysfs_node_entry(dev, i);
 		if (ret < 0)
 		if (ret < 0)
 			return ret;
 			return ret;
 		i++;
 		i++;

+ 1 - 1
drivers/gpu/drm/amd/include/kgd_kfd_interface.h

@@ -183,7 +183,7 @@ struct kfd2kgd_calls {
 	int (*hqd_load)(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
 	int (*hqd_load)(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
 			uint32_t queue_id, uint32_t __user *wptr);
 			uint32_t queue_id, uint32_t __user *wptr);
 
 
-	bool (*hqd_is_occupies)(struct kgd_dev *kgd, uint64_t queue_address,
+	bool (*hqd_is_occupied)(struct kgd_dev *kgd, uint64_t queue_address,
 				uint32_t pipe_id, uint32_t queue_id);
 				uint32_t pipe_id, uint32_t queue_id);
 
 
 	int (*hqd_destroy)(struct kgd_dev *kgd, uint32_t reset_type,
 	int (*hqd_destroy)(struct kgd_dev *kgd, uint32_t reset_type,

+ 0 - 2
drivers/gpu/drm/i915/i915_drv.h

@@ -1756,8 +1756,6 @@ struct drm_i915_private {
 	 */
 	 */
 	struct workqueue_struct *dp_wq;
 	struct workqueue_struct *dp_wq;
 
 
-	uint32_t bios_vgacntr;
-
 	/* Abstract the submission mechanism (legacy ringbuffer or execlists) away */
 	/* Abstract the submission mechanism (legacy ringbuffer or execlists) away */
 	struct {
 	struct {
 		int (*do_execbuf)(struct drm_device *dev, struct drm_file *file,
 		int (*do_execbuf)(struct drm_device *dev, struct drm_file *file,

+ 7 - 1
drivers/gpu/drm/i915/i915_gem.c

@@ -1048,6 +1048,7 @@ int
 i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
 i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
 		      struct drm_file *file)
 		      struct drm_file *file)
 {
 {
+	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_i915_gem_pwrite *args = data;
 	struct drm_i915_gem_pwrite *args = data;
 	struct drm_i915_gem_object *obj;
 	struct drm_i915_gem_object *obj;
 	int ret;
 	int ret;
@@ -1067,9 +1068,11 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
 			return -EFAULT;
 			return -EFAULT;
 	}
 	}
 
 
+	intel_runtime_pm_get(dev_priv);
+
 	ret = i915_mutex_lock_interruptible(dev);
 	ret = i915_mutex_lock_interruptible(dev);
 	if (ret)
 	if (ret)
-		return ret;
+		goto put_rpm;
 
 
 	obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
 	obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
 	if (&obj->base == NULL) {
 	if (&obj->base == NULL) {
@@ -1121,6 +1124,9 @@ out:
 	drm_gem_object_unreference(&obj->base);
 	drm_gem_object_unreference(&obj->base);
 unlock:
 unlock:
 	mutex_unlock(&dev->struct_mutex);
 	mutex_unlock(&dev->struct_mutex);
+put_rpm:
+	intel_runtime_pm_put(dev_priv);
+
 	return ret;
 	return ret;
 }
 }
 
 

+ 2 - 4
drivers/gpu/drm/i915/i915_irq.c

@@ -3725,8 +3725,6 @@ static bool i8xx_handle_vblank(struct drm_device *dev,
 	if ((iir & flip_pending) == 0)
 	if ((iir & flip_pending) == 0)
 		goto check_page_flip;
 		goto check_page_flip;
 
 
-	intel_prepare_page_flip(dev, plane);
-
 	/* We detect FlipDone by looking for the change in PendingFlip from '1'
 	/* We detect FlipDone by looking for the change in PendingFlip from '1'
 	 * to '0' on the following vblank, i.e. IIR has the Pendingflip
 	 * to '0' on the following vblank, i.e. IIR has the Pendingflip
 	 * asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence
 	 * asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence
@@ -3736,6 +3734,7 @@ static bool i8xx_handle_vblank(struct drm_device *dev,
 	if (I915_READ16(ISR) & flip_pending)
 	if (I915_READ16(ISR) & flip_pending)
 		goto check_page_flip;
 		goto check_page_flip;
 
 
+	intel_prepare_page_flip(dev, plane);
 	intel_finish_page_flip(dev, pipe);
 	intel_finish_page_flip(dev, pipe);
 	return true;
 	return true;
 
 
@@ -3907,8 +3906,6 @@ static bool i915_handle_vblank(struct drm_device *dev,
 	if ((iir & flip_pending) == 0)
 	if ((iir & flip_pending) == 0)
 		goto check_page_flip;
 		goto check_page_flip;
 
 
-	intel_prepare_page_flip(dev, plane);
-
 	/* We detect FlipDone by looking for the change in PendingFlip from '1'
 	/* We detect FlipDone by looking for the change in PendingFlip from '1'
 	 * to '0' on the following vblank, i.e. IIR has the Pendingflip
 	 * to '0' on the following vblank, i.e. IIR has the Pendingflip
 	 * asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence
 	 * asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence
@@ -3918,6 +3915,7 @@ static bool i915_handle_vblank(struct drm_device *dev,
 	if (I915_READ(ISR) & flip_pending)
 	if (I915_READ(ISR) & flip_pending)
 		goto check_page_flip;
 		goto check_page_flip;
 
 
+	intel_prepare_page_flip(dev, plane);
 	intel_finish_page_flip(dev, pipe);
 	intel_finish_page_flip(dev, pipe);
 	return true;
 	return true;
 
 

+ 1 - 7
drivers/gpu/drm/i915/intel_display.c

@@ -13057,11 +13057,7 @@ static void i915_disable_vga(struct drm_device *dev)
 	vga_put(dev->pdev, VGA_RSRC_LEGACY_IO);
 	vga_put(dev->pdev, VGA_RSRC_LEGACY_IO);
 	udelay(300);
 	udelay(300);
 
 
-	/*
-	 * Fujitsu-Siemens Lifebook S6010 (830) has problems resuming
-	 * from S3 without preserving (some of?) the other bits.
-	 */
-	I915_WRITE(vga_reg, dev_priv->bios_vgacntr | VGA_DISP_DISABLE);
+	I915_WRITE(vga_reg, VGA_DISP_DISABLE);
 	POSTING_READ(vga_reg);
 	POSTING_READ(vga_reg);
 }
 }
 
 
@@ -13146,8 +13142,6 @@ void intel_modeset_init(struct drm_device *dev)
 
 
 	intel_shared_dpll_init(dev);
 	intel_shared_dpll_init(dev);
 
 
-	/* save the BIOS value before clobbering it */
-	dev_priv->bios_vgacntr = I915_READ(i915_vgacntrl_reg(dev));
 	/* Just disable it once at startup */
 	/* Just disable it once at startup */
 	i915_disable_vga(dev);
 	i915_disable_vga(dev);
 	intel_setup_outputs(dev);
 	intel_setup_outputs(dev);

+ 0 - 27
drivers/gpu/drm/i915/intel_runtime_pm.c

@@ -615,29 +615,6 @@ static void chv_pipe_power_well_disable(struct drm_i915_private *dev_priv,
 		vlv_power_sequencer_reset(dev_priv);
 		vlv_power_sequencer_reset(dev_priv);
 }
 }
 
 
-static void check_power_well_state(struct drm_i915_private *dev_priv,
-				   struct i915_power_well *power_well)
-{
-	bool enabled = power_well->ops->is_enabled(dev_priv, power_well);
-
-	if (power_well->always_on || !i915.disable_power_well) {
-		if (!enabled)
-			goto mismatch;
-
-		return;
-	}
-
-	if (enabled != (power_well->count > 0))
-		goto mismatch;
-
-	return;
-
-mismatch:
-	WARN(1, "state mismatch for '%s' (always_on %d hw state %d use-count %d disable_power_well %d\n",
-		  power_well->name, power_well->always_on, enabled,
-		  power_well->count, i915.disable_power_well);
-}
-
 /**
 /**
  * intel_display_power_get - grab a power domain reference
  * intel_display_power_get - grab a power domain reference
  * @dev_priv: i915 device instance
  * @dev_priv: i915 device instance
@@ -669,8 +646,6 @@ void intel_display_power_get(struct drm_i915_private *dev_priv,
 			power_well->ops->enable(dev_priv, power_well);
 			power_well->ops->enable(dev_priv, power_well);
 			power_well->hw_enabled = true;
 			power_well->hw_enabled = true;
 		}
 		}
-
-		check_power_well_state(dev_priv, power_well);
 	}
 	}
 
 
 	power_domains->domain_use_count[domain]++;
 	power_domains->domain_use_count[domain]++;
@@ -709,8 +684,6 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
 			power_well->hw_enabled = false;
 			power_well->hw_enabled = false;
 			power_well->ops->disable(dev_priv, power_well);
 			power_well->ops->disable(dev_priv, power_well);
 		}
 		}
-
-		check_power_well_state(dev_priv, power_well);
 	}
 	}
 
 
 	mutex_unlock(&power_domains->lock);
 	mutex_unlock(&power_domains->lock);

+ 2 - 2
drivers/gpu/drm/nouveau/core/core/event.c

@@ -26,7 +26,7 @@
 void
 void
 nvkm_event_put(struct nvkm_event *event, u32 types, int index)
 nvkm_event_put(struct nvkm_event *event, u32 types, int index)
 {
 {
-	BUG_ON(!spin_is_locked(&event->refs_lock));
+	assert_spin_locked(&event->refs_lock);
 	while (types) {
 	while (types) {
 		int type = __ffs(types); types &= ~(1 << type);
 		int type = __ffs(types); types &= ~(1 << type);
 		if (--event->refs[index * event->types_nr + type] == 0) {
 		if (--event->refs[index * event->types_nr + type] == 0) {
@@ -39,7 +39,7 @@ nvkm_event_put(struct nvkm_event *event, u32 types, int index)
 void
 void
 nvkm_event_get(struct nvkm_event *event, u32 types, int index)
 nvkm_event_get(struct nvkm_event *event, u32 types, int index)
 {
 {
-	BUG_ON(!spin_is_locked(&event->refs_lock));
+	assert_spin_locked(&event->refs_lock);
 	while (types) {
 	while (types) {
 		int type = __ffs(types); types &= ~(1 << type);
 		int type = __ffs(types); types &= ~(1 << type);
 		if (++event->refs[index * event->types_nr + type] == 1) {
 		if (++event->refs[index * event->types_nr + type] == 1) {

+ 1 - 1
drivers/gpu/drm/nouveau/core/core/notify.c

@@ -98,7 +98,7 @@ nvkm_notify_send(struct nvkm_notify *notify, void *data, u32 size)
 	struct nvkm_event *event = notify->event;
 	struct nvkm_event *event = notify->event;
 	unsigned long flags;
 	unsigned long flags;
 
 
-	BUG_ON(!spin_is_locked(&event->list_lock));
+	assert_spin_locked(&event->list_lock);
 	BUG_ON(size != notify->size);
 	BUG_ON(size != notify->size);
 
 
 	spin_lock_irqsave(&event->refs_lock, flags);
 	spin_lock_irqsave(&event->refs_lock, flags);

+ 33 - 0
drivers/gpu/drm/nouveau/core/engine/device/nve0.c

@@ -249,6 +249,39 @@ nve0_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nvc0_ppp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nvc0_ppp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] = &nvf0_perfmon_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] = &nvf0_perfmon_oclass;
 		break;
 		break;
+	case 0x106:
+		device->cname = "GK208B";
+		device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
+		device->oclass[NVDEV_SUBDEV_GPIO   ] =  nve0_gpio_oclass;
+		device->oclass[NVDEV_SUBDEV_I2C    ] =  nve0_i2c_oclass;
+		device->oclass[NVDEV_SUBDEV_FUSE   ] = &gf100_fuse_oclass;
+		device->oclass[NVDEV_SUBDEV_CLOCK  ] = &nve0_clock_oclass;
+		device->oclass[NVDEV_SUBDEV_THERM  ] = &nvd0_therm_oclass;
+		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
+		device->oclass[NVDEV_SUBDEV_DEVINIT] =  nvc0_devinit_oclass;
+		device->oclass[NVDEV_SUBDEV_MC     ] =  gk20a_mc_oclass;
+		device->oclass[NVDEV_SUBDEV_BUS    ] =  nvc0_bus_oclass;
+		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+		device->oclass[NVDEV_SUBDEV_FB     ] =  nve0_fb_oclass;
+		device->oclass[NVDEV_SUBDEV_LTC    ] =  gk104_ltc_oclass;
+		device->oclass[NVDEV_SUBDEV_IBUS   ] = &nve0_ibus_oclass;
+		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
+		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
+		device->oclass[NVDEV_SUBDEV_BAR    ] = &nvc0_bar_oclass;
+		device->oclass[NVDEV_SUBDEV_PWR    ] =  nv108_pwr_oclass;
+		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
+		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nvd0_dmaeng_oclass;
+		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv108_fifo_oclass;
+		device->oclass[NVDEV_ENGINE_SW     ] =  nvc0_software_oclass;
+		device->oclass[NVDEV_ENGINE_GR     ] =  nv108_graph_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nvf0_disp_oclass;
+		device->oclass[NVDEV_ENGINE_COPY0  ] = &nve0_copy0_oclass;
+		device->oclass[NVDEV_ENGINE_COPY1  ] = &nve0_copy1_oclass;
+		device->oclass[NVDEV_ENGINE_COPY2  ] = &nve0_copy2_oclass;
+		device->oclass[NVDEV_ENGINE_BSP    ] = &nve0_bsp_oclass;
+		device->oclass[NVDEV_ENGINE_VP     ] = &nve0_vp_oclass;
+		device->oclass[NVDEV_ENGINE_PPP    ] = &nvc0_ppp_oclass;
+		break;
 	case 0x108:
 	case 0x108:
 		device->cname = "GK208";
 		device->cname = "GK208";
 		device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
 		device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;

+ 4 - 2
drivers/gpu/drm/nouveau/core/subdev/bios/shadowramin.c

@@ -44,8 +44,10 @@ static void
 pramin_fini(void *data)
 pramin_fini(void *data)
 {
 {
 	struct priv *priv = data;
 	struct priv *priv = data;
-	nv_wr32(priv->bios, 0x001700, priv->bar0);
-	kfree(priv);
+	if (priv) {
+		nv_wr32(priv->bios, 0x001700, priv->bar0);
+		kfree(priv);
+	}
 }
 }
 
 
 static void *
 static void *

+ 51 - 14
drivers/gpu/drm/nouveau/core/subdev/fb/ramnvaa.c

@@ -24,34 +24,71 @@
 
 
 #include "nv50.h"
 #include "nv50.h"
 
 
+struct nvaa_ram_priv {
+	struct nouveau_ram base;
+	u64 poller_base;
+};
+
 static int
 static int
 nvaa_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 nvaa_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 	      struct nouveau_oclass *oclass, void *data, u32 datasize,
 	      struct nouveau_oclass *oclass, void *data, u32 datasize,
 	      struct nouveau_object **pobject)
 	      struct nouveau_object **pobject)
 {
 {
-	const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */
-	const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */
+	u32 rsvd_head = ( 256 * 1024); /* vga memory */
+	u32 rsvd_tail = (1024 * 1024); /* vbios etc */
 	struct nouveau_fb *pfb = nouveau_fb(parent);
 	struct nouveau_fb *pfb = nouveau_fb(parent);
-	struct nouveau_ram *ram;
+	struct nvaa_ram_priv *priv;
 	int ret;
 	int ret;
 
 
-	ret = nouveau_ram_create(parent, engine, oclass, &ram);
-	*pobject = nv_object(ram);
+	ret = nouveau_ram_create(parent, engine, oclass, &priv);
+	*pobject = nv_object(priv);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 
 
-	ram->size = nv_rd32(pfb, 0x10020c);
-	ram->size = (ram->size & 0xffffff00) | ((ram->size & 0x000000ff) << 32);
+	priv->base.type   = NV_MEM_TYPE_STOLEN;
+	priv->base.stolen = (u64)nv_rd32(pfb, 0x100e10) << 12;
+	priv->base.size   = (u64)nv_rd32(pfb, 0x100e14) << 12;
 
 
-	ret = nouveau_mm_init(&pfb->vram, rsvd_head, (ram->size >> 12) -
-			      (rsvd_head + rsvd_tail), 1);
+	rsvd_tail += 0x1000;
+	priv->poller_base = priv->base.size - rsvd_tail;
+
+	ret = nouveau_mm_init(&pfb->vram, rsvd_head >> 12,
+			      (priv->base.size  - (rsvd_head + rsvd_tail)) >> 12,
+			      1);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 
 
-	ram->type   = NV_MEM_TYPE_STOLEN;
-	ram->stolen = (u64)nv_rd32(pfb, 0x100e10) << 12;
-	ram->get = nv50_ram_get;
-	ram->put = nv50_ram_put;
+	priv->base.get = nv50_ram_get;
+	priv->base.put = nv50_ram_put;
+	return 0;
+}
+
+static int
+nvaa_ram_init(struct nouveau_object *object)
+{
+	struct nouveau_fb *pfb = nouveau_fb(object);
+	struct nvaa_ram_priv *priv = (void *)object;
+	int ret;
+	u64 dniso, hostnb, flush;
+
+	ret = nouveau_ram_init(&priv->base);
+	if (ret)
+		return ret;
+
+	dniso  = ((priv->base.size - (priv->poller_base + 0x00)) >> 5) - 1;
+	hostnb = ((priv->base.size - (priv->poller_base + 0x20)) >> 5) - 1;
+	flush  = ((priv->base.size - (priv->poller_base + 0x40)) >> 5) - 1;
+
+	/* Enable NISO poller for various clients and set their associated
+	 * read address, only for MCP77/78 and MCP79/7A. (fd#25701)
+	 */
+	nv_wr32(pfb, 0x100c18, dniso);
+	nv_mask(pfb, 0x100c14, 0x00000000, 0x00000001);
+	nv_wr32(pfb, 0x100c1c, hostnb);
+	nv_mask(pfb, 0x100c14, 0x00000000, 0x00000002);
+	nv_wr32(pfb, 0x100c24, flush);
+	nv_mask(pfb, 0x100c14, 0x00000000, 0x00010000);
+
 	return 0;
 	return 0;
 }
 }
 
 
@@ -60,7 +97,7 @@ nvaa_ram_oclass = {
 	.ofuncs = &(struct nouveau_ofuncs) {
 	.ofuncs = &(struct nouveau_ofuncs) {
 		.ctor = nvaa_ram_ctor,
 		.ctor = nvaa_ram_ctor,
 		.dtor = _nouveau_ram_dtor,
 		.dtor = _nouveau_ram_dtor,
-		.init = _nouveau_ram_init,
+		.init = nvaa_ram_init,
 		.fini = _nouveau_ram_fini,
 		.fini = _nouveau_ram_fini,
 	},
 	},
 };
 };

+ 0 - 8
drivers/gpu/drm/nouveau/core/subdev/mc/nv4c.c

@@ -24,13 +24,6 @@
 
 
 #include "nv04.h"
 #include "nv04.h"
 
 
-static void
-nv4c_mc_msi_rearm(struct nouveau_mc *pmc)
-{
-	struct nv04_mc_priv *priv = (void *)pmc;
-	nv_wr08(priv, 0x088050, 0xff);
-}
-
 struct nouveau_oclass *
 struct nouveau_oclass *
 nv4c_mc_oclass = &(struct nouveau_mc_oclass) {
 nv4c_mc_oclass = &(struct nouveau_mc_oclass) {
 	.base.handle = NV_SUBDEV(MC, 0x4c),
 	.base.handle = NV_SUBDEV(MC, 0x4c),
@@ -41,5 +34,4 @@ nv4c_mc_oclass = &(struct nouveau_mc_oclass) {
 		.fini = _nouveau_mc_fini,
 		.fini = _nouveau_mc_fini,
 	},
 	},
 	.intr = nv04_mc_intr,
 	.intr = nv04_mc_intr,
-	.msi_rearm = nv4c_mc_msi_rearm,
 }.base;
 }.base;

+ 3 - 1
drivers/gpu/drm/nouveau/nouveau_bo.c

@@ -1572,8 +1572,10 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm)
 	 * so use the DMA API for them.
 	 * so use the DMA API for them.
 	 */
 	 */
 	if (!nv_device_is_cpu_coherent(device) &&
 	if (!nv_device_is_cpu_coherent(device) &&
-	    ttm->caching_state == tt_uncached)
+	    ttm->caching_state == tt_uncached) {
 		ttm_dma_unpopulate(ttm_dma, dev->dev);
 		ttm_dma_unpopulate(ttm_dma, dev->dev);
+		return;
+	}
 
 
 #if __OS_HAS_AGP
 #if __OS_HAS_AGP
 	if (drm->agp.stat == ENABLED) {
 	if (drm->agp.stat == ENABLED) {

+ 30 - 5
drivers/gpu/drm/nouveau/nouveau_gem.c

@@ -36,7 +36,14 @@ void
 nouveau_gem_object_del(struct drm_gem_object *gem)
 nouveau_gem_object_del(struct drm_gem_object *gem)
 {
 {
 	struct nouveau_bo *nvbo = nouveau_gem_object(gem);
 	struct nouveau_bo *nvbo = nouveau_gem_object(gem);
+	struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
 	struct ttm_buffer_object *bo = &nvbo->bo;
 	struct ttm_buffer_object *bo = &nvbo->bo;
+	struct device *dev = drm->dev->dev;
+	int ret;
+
+	ret = pm_runtime_get_sync(dev);
+	if (WARN_ON(ret < 0 && ret != -EACCES))
+		return;
 
 
 	if (gem->import_attach)
 	if (gem->import_attach)
 		drm_prime_gem_destroy(gem, nvbo->bo.sg);
 		drm_prime_gem_destroy(gem, nvbo->bo.sg);
@@ -46,6 +53,9 @@ nouveau_gem_object_del(struct drm_gem_object *gem)
 	/* reset filp so nouveau_bo_del_ttm() can test for it */
 	/* reset filp so nouveau_bo_del_ttm() can test for it */
 	gem->filp = NULL;
 	gem->filp = NULL;
 	ttm_bo_unref(&bo);
 	ttm_bo_unref(&bo);
+
+	pm_runtime_mark_last_busy(dev);
+	pm_runtime_put_autosuspend(dev);
 }
 }
 
 
 int
 int
@@ -53,7 +63,9 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv)
 {
 {
 	struct nouveau_cli *cli = nouveau_cli(file_priv);
 	struct nouveau_cli *cli = nouveau_cli(file_priv);
 	struct nouveau_bo *nvbo = nouveau_gem_object(gem);
 	struct nouveau_bo *nvbo = nouveau_gem_object(gem);
+	struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
 	struct nouveau_vma *vma;
 	struct nouveau_vma *vma;
+	struct device *dev = drm->dev->dev;
 	int ret;
 	int ret;
 
 
 	if (!cli->vm)
 	if (!cli->vm)
@@ -71,11 +83,16 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv)
 			goto out;
 			goto out;
 		}
 		}
 
 
+		ret = pm_runtime_get_sync(dev);
+		if (ret < 0 && ret != -EACCES)
+			goto out;
+
 		ret = nouveau_bo_vma_add(nvbo, cli->vm, vma);
 		ret = nouveau_bo_vma_add(nvbo, cli->vm, vma);
-		if (ret) {
+		if (ret)
 			kfree(vma);
 			kfree(vma);
-			goto out;
-		}
+
+		pm_runtime_mark_last_busy(dev);
+		pm_runtime_put_autosuspend(dev);
 	} else {
 	} else {
 		vma->refcount++;
 		vma->refcount++;
 	}
 	}
@@ -129,6 +146,8 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv)
 {
 {
 	struct nouveau_cli *cli = nouveau_cli(file_priv);
 	struct nouveau_cli *cli = nouveau_cli(file_priv);
 	struct nouveau_bo *nvbo = nouveau_gem_object(gem);
 	struct nouveau_bo *nvbo = nouveau_gem_object(gem);
+	struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
+	struct device *dev = drm->dev->dev;
 	struct nouveau_vma *vma;
 	struct nouveau_vma *vma;
 	int ret;
 	int ret;
 
 
@@ -141,8 +160,14 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv)
 
 
 	vma = nouveau_bo_vma_find(nvbo, cli->vm);
 	vma = nouveau_bo_vma_find(nvbo, cli->vm);
 	if (vma) {
 	if (vma) {
-		if (--vma->refcount == 0)
-			nouveau_gem_object_unmap(nvbo, vma);
+		if (--vma->refcount == 0) {
+			ret = pm_runtime_get_sync(dev);
+			if (!WARN_ON(ret < 0 && ret != -EACCES)) {
+				nouveau_gem_object_unmap(nvbo, vma);
+				pm_runtime_mark_last_busy(dev);
+				pm_runtime_put_autosuspend(dev);
+			}
+		}
 	}
 	}
 	ttm_bo_unreserve(&nvbo->bo);
 	ttm_bo_unreserve(&nvbo->bo);
 }
 }

+ 4 - 4
drivers/gpu/drm/radeon/atombios_crtc.c

@@ -1851,10 +1851,9 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
 				return pll;
 				return pll;
 		}
 		}
 		/* otherwise, pick one of the plls */
 		/* otherwise, pick one of the plls */
-		if ((rdev->family == CHIP_KAVERI) ||
-		    (rdev->family == CHIP_KABINI) ||
+		if ((rdev->family == CHIP_KABINI) ||
 		    (rdev->family == CHIP_MULLINS)) {
 		    (rdev->family == CHIP_MULLINS)) {
-			/* KB/KV/ML has PPLL1 and PPLL2 */
+			/* KB/ML has PPLL1 and PPLL2 */
 			pll_in_use = radeon_get_pll_use_mask(crtc);
 			pll_in_use = radeon_get_pll_use_mask(crtc);
 			if (!(pll_in_use & (1 << ATOM_PPLL2)))
 			if (!(pll_in_use & (1 << ATOM_PPLL2)))
 				return ATOM_PPLL2;
 				return ATOM_PPLL2;
@@ -1863,7 +1862,7 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
 			DRM_ERROR("unable to allocate a PPLL\n");
 			DRM_ERROR("unable to allocate a PPLL\n");
 			return ATOM_PPLL_INVALID;
 			return ATOM_PPLL_INVALID;
 		} else {
 		} else {
-			/* CI has PPLL0, PPLL1, and PPLL2 */
+			/* CI/KV has PPLL0, PPLL1, and PPLL2 */
 			pll_in_use = radeon_get_pll_use_mask(crtc);
 			pll_in_use = radeon_get_pll_use_mask(crtc);
 			if (!(pll_in_use & (1 << ATOM_PPLL2)))
 			if (!(pll_in_use & (1 << ATOM_PPLL2)))
 				return ATOM_PPLL2;
 				return ATOM_PPLL2;
@@ -2155,6 +2154,7 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)
 	case ATOM_PPLL0:
 	case ATOM_PPLL0:
 		/* disable the ppll */
 		/* disable the ppll */
 		if ((rdev->family == CHIP_ARUBA) ||
 		if ((rdev->family == CHIP_ARUBA) ||
+		    (rdev->family == CHIP_KAVERI) ||
 		    (rdev->family == CHIP_BONAIRE) ||
 		    (rdev->family == CHIP_BONAIRE) ||
 		    (rdev->family == CHIP_HAWAII))
 		    (rdev->family == CHIP_HAWAII))
 			atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
 			atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,

+ 4 - 0
drivers/gpu/drm/radeon/atombios_dp.c

@@ -492,6 +492,10 @@ int radeon_dp_mode_valid_helper(struct drm_connector *connector,
 	struct radeon_connector_atom_dig *dig_connector;
 	struct radeon_connector_atom_dig *dig_connector;
 	int dp_clock;
 	int dp_clock;
 
 
+	if ((mode->clock > 340000) &&
+	    (!radeon_connector_is_dp12_capable(connector)))
+		return MODE_CLOCK_HIGH;
+
 	if (!radeon_connector->con_priv)
 	if (!radeon_connector->con_priv)
 		return MODE_CLOCK_HIGH;
 		return MODE_CLOCK_HIGH;
 	dig_connector = radeon_connector->con_priv;
 	dig_connector = radeon_connector->con_priv;

+ 2 - 0
drivers/gpu/drm/radeon/cikd.h

@@ -2156,4 +2156,6 @@
 #define ATC_VM_APERTURE1_HIGH_ADDR				0x330Cu
 #define ATC_VM_APERTURE1_HIGH_ADDR				0x330Cu
 #define ATC_VM_APERTURE1_LOW_ADDR				0x3304u
 #define ATC_VM_APERTURE1_LOW_ADDR				0x3304u
 
 
+#define IH_VMID_0_LUT						0x3D40u
+
 #endif
 #endif

+ 1 - 1
drivers/gpu/drm/radeon/dce3_1_afmt.c

@@ -103,7 +103,7 @@ static void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder)
 	}
 	}
 
 
 	sad_count = drm_edid_to_sad(radeon_connector->edid, &sads);
 	sad_count = drm_edid_to_sad(radeon_connector->edid, &sads);
-	if (sad_count < 0) {
+	if (sad_count <= 0) {
 		DRM_ERROR("Couldn't read SADs: %d\n", sad_count);
 		DRM_ERROR("Couldn't read SADs: %d\n", sad_count);
 		return;
 		return;
 	}
 	}

+ 4 - 6
drivers/gpu/drm/radeon/kv_dpm.c

@@ -2745,13 +2745,11 @@ int kv_dpm_init(struct radeon_device *rdev)
 	pi->enable_auto_thermal_throttling = true;
 	pi->enable_auto_thermal_throttling = true;
 	pi->disable_nb_ps3_in_battery = false;
 	pi->disable_nb_ps3_in_battery = false;
 	if (radeon_bapm == -1) {
 	if (radeon_bapm == -1) {
-		/* There are stability issues reported on with
-		 * bapm enabled on an asrock system.
-		 */
-		if (rdev->pdev->subsystem_vendor == 0x1849)
-			pi->bapm_enable = false;
-		else
+		/* only enable bapm on KB, ML by default */
+		if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS)
 			pi->bapm_enable = true;
 			pi->bapm_enable = true;
+		else
+			pi->bapm_enable = false;
 	} else if (radeon_bapm == 0) {
 	} else if (radeon_bapm == 0) {
 		pi->bapm_enable = false;
 		pi->bapm_enable = false;
 	} else {
 	} else {

+ 20 - 3
drivers/gpu/drm/radeon/radeon_kfd.c

@@ -72,7 +72,7 @@ static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id,
 static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
 static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
 			uint32_t queue_id, uint32_t __user *wptr);
 			uint32_t queue_id, uint32_t __user *wptr);
 
 
-static bool kgd_hqd_is_occupies(struct kgd_dev *kgd, uint64_t queue_address,
+static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,
 				uint32_t pipe_id, uint32_t queue_id);
 				uint32_t pipe_id, uint32_t queue_id);
 
 
 static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type,
 static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type,
@@ -92,7 +92,7 @@ static const struct kfd2kgd_calls kfd2kgd = {
 	.init_memory = kgd_init_memory,
 	.init_memory = kgd_init_memory,
 	.init_pipeline = kgd_init_pipeline,
 	.init_pipeline = kgd_init_pipeline,
 	.hqd_load = kgd_hqd_load,
 	.hqd_load = kgd_hqd_load,
-	.hqd_is_occupies = kgd_hqd_is_occupies,
+	.hqd_is_occupied = kgd_hqd_is_occupied,
 	.hqd_destroy = kgd_hqd_destroy,
 	.hqd_destroy = kgd_hqd_destroy,
 	.get_fw_version = get_fw_version
 	.get_fw_version = get_fw_version
 };
 };
@@ -101,6 +101,7 @@ static const struct kgd2kfd_calls *kgd2kfd;
 
 
 bool radeon_kfd_init(void)
 bool radeon_kfd_init(void)
 {
 {
+#if defined(CONFIG_HSA_AMD_MODULE)
 	bool (*kgd2kfd_init_p)(unsigned, const struct kfd2kgd_calls*,
 	bool (*kgd2kfd_init_p)(unsigned, const struct kfd2kgd_calls*,
 				const struct kgd2kfd_calls**);
 				const struct kgd2kfd_calls**);
 
 
@@ -117,6 +118,17 @@ bool radeon_kfd_init(void)
 	}
 	}
 
 
 	return true;
 	return true;
+#elif defined(CONFIG_HSA_AMD)
+	if (!kgd2kfd_init(KFD_INTERFACE_VERSION, &kfd2kgd, &kgd2kfd)) {
+		kgd2kfd = NULL;
+
+		return false;
+	}
+
+	return true;
+#else
+	return false;
+#endif
 }
 }
 
 
 void radeon_kfd_fini(void)
 void radeon_kfd_fini(void)
@@ -378,6 +390,10 @@ static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, unsigned int pasid,
 		cpu_relax();
 		cpu_relax();
 	write_register(kgd, ATC_VMID_PASID_MAPPING_UPDATE_STATUS, 1U << vmid);
 	write_register(kgd, ATC_VMID_PASID_MAPPING_UPDATE_STATUS, 1U << vmid);
 
 
+	/* Mapping vmid to pasid also for IH block */
+	write_register(kgd, IH_VMID_0_LUT + vmid * sizeof(uint32_t),
+			pasid_mapping);
+
 	return 0;
 	return 0;
 }
 }
 
 
@@ -517,7 +533,7 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
 	return 0;
 	return 0;
 }
 }
 
 
-static bool kgd_hqd_is_occupies(struct kgd_dev *kgd, uint64_t queue_address,
+static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,
 				uint32_t pipe_id, uint32_t queue_id)
 				uint32_t pipe_id, uint32_t queue_id)
 {
 {
 	uint32_t act;
 	uint32_t act;
@@ -556,6 +572,7 @@ static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type,
 		if (timeout == 0) {
 		if (timeout == 0) {
 			pr_err("kfd: cp queue preemption time out (%dms)\n",
 			pr_err("kfd: cp queue preemption time out (%dms)\n",
 				temp);
 				temp);
+			release_queue(kgd);
 			return -ETIME;
 			return -ETIME;
 		}
 		}
 		msleep(20);
 		msleep(20);

+ 1 - 1
drivers/gpu/drm/radeon/radeon_state.c

@@ -1703,7 +1703,7 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev,
 	u32 format;
 	u32 format;
 	u32 *buffer;
 	u32 *buffer;
 	const u8 __user *data;
 	const u8 __user *data;
-	int size, dwords, tex_width, blit_width, spitch;
+	unsigned int size, dwords, tex_width, blit_width, spitch;
 	u32 height;
 	u32 height;
 	int i;
 	int i;
 	u32 texpitch, microtile;
 	u32 texpitch, microtile;

+ 2 - 1
drivers/hid/Kconfig

@@ -27,7 +27,8 @@ if HID
 
 
 config HID_BATTERY_STRENGTH
 config HID_BATTERY_STRENGTH
 	bool "Battery level reporting for HID devices"
 	bool "Battery level reporting for HID devices"
-	depends on HID && POWER_SUPPLY && HID = POWER_SUPPLY
+	depends on HID
+	select POWER_SUPPLY
 	default n
 	default n
 	---help---
 	---help---
 	This option adds support of reporting battery strength (for HID devices
 	This option adds support of reporting battery strength (for HID devices

+ 1 - 0
drivers/hid/hid-core.c

@@ -1805,6 +1805,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_I405X) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_I405X) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) },

+ 1 - 0
drivers/hid/hid-ids.h

@@ -526,6 +526,7 @@
 #define USB_DEVICE_ID_KYE_GPEN_560	0x5003
 #define USB_DEVICE_ID_KYE_GPEN_560	0x5003
 #define USB_DEVICE_ID_KYE_EASYPEN_I405X	0x5010
 #define USB_DEVICE_ID_KYE_EASYPEN_I405X	0x5010
 #define USB_DEVICE_ID_KYE_MOUSEPEN_I608X	0x5011
 #define USB_DEVICE_ID_KYE_MOUSEPEN_I608X	0x5011
+#define USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2	0x501a
 #define USB_DEVICE_ID_KYE_EASYPEN_M610X	0x5013
 #define USB_DEVICE_ID_KYE_EASYPEN_M610X	0x5013
 
 
 #define USB_VENDOR_ID_LABTEC		0x1020
 #define USB_VENDOR_ID_LABTEC		0x1020

+ 3 - 0
drivers/hid/hid-input.c

@@ -311,6 +311,9 @@ static const struct hid_device_id hid_battery_quirks[] = {
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
 			       USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI),
 			       USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI),
 	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
 	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
+	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
+			       USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO),
+	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
 		USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI),
 		USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI),
 	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
 	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },

+ 4 - 0
drivers/hid/hid-kye.c

@@ -323,6 +323,7 @@ static __u8 *kye_report_fixup(struct hid_device *hdev, __u8 *rdesc,
 		}
 		}
 		break;
 		break;
 	case USB_DEVICE_ID_KYE_MOUSEPEN_I608X:
 	case USB_DEVICE_ID_KYE_MOUSEPEN_I608X:
+	case USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2:
 		if (*rsize == MOUSEPEN_I608X_RDESC_ORIG_SIZE) {
 		if (*rsize == MOUSEPEN_I608X_RDESC_ORIG_SIZE) {
 			rdesc = mousepen_i608x_rdesc_fixed;
 			rdesc = mousepen_i608x_rdesc_fixed;
 			*rsize = sizeof(mousepen_i608x_rdesc_fixed);
 			*rsize = sizeof(mousepen_i608x_rdesc_fixed);
@@ -415,6 +416,7 @@ static int kye_probe(struct hid_device *hdev, const struct hid_device_id *id)
 	switch (id->product) {
 	switch (id->product) {
 	case USB_DEVICE_ID_KYE_EASYPEN_I405X:
 	case USB_DEVICE_ID_KYE_EASYPEN_I405X:
 	case USB_DEVICE_ID_KYE_MOUSEPEN_I608X:
 	case USB_DEVICE_ID_KYE_MOUSEPEN_I608X:
+	case USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2:
 	case USB_DEVICE_ID_KYE_EASYPEN_M610X:
 	case USB_DEVICE_ID_KYE_EASYPEN_M610X:
 		ret = kye_tablet_enable(hdev);
 		ret = kye_tablet_enable(hdev);
 		if (ret) {
 		if (ret) {
@@ -445,6 +447,8 @@ static const struct hid_device_id kye_devices[] = {
 				USB_DEVICE_ID_KYE_EASYPEN_I405X) },
 				USB_DEVICE_ID_KYE_EASYPEN_I405X) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE,
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE,
 				USB_DEVICE_ID_KYE_MOUSEPEN_I608X) },
 				USB_DEVICE_ID_KYE_MOUSEPEN_I608X) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE,
+				USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE,
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE,
 				USB_DEVICE_ID_KYE_EASYPEN_M610X) },
 				USB_DEVICE_ID_KYE_EASYPEN_M610X) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE,
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE,

+ 15 - 1
drivers/hid/hid-logitech-dj.c

@@ -962,10 +962,24 @@ static int logi_dj_raw_event(struct hid_device *hdev,
 
 
 	switch (data[0]) {
 	switch (data[0]) {
 	case REPORT_ID_DJ_SHORT:
 	case REPORT_ID_DJ_SHORT:
+		if (size != DJREPORT_SHORT_LENGTH) {
+			dev_err(&hdev->dev, "DJ report of bad size (%d)", size);
+			return false;
+		}
 		return logi_dj_dj_event(hdev, report, data, size);
 		return logi_dj_dj_event(hdev, report, data, size);
 	case REPORT_ID_HIDPP_SHORT:
 	case REPORT_ID_HIDPP_SHORT:
-		/* intentional fallthrough */
+		if (size != HIDPP_REPORT_SHORT_LENGTH) {
+			dev_err(&hdev->dev,
+				"Short HID++ report of bad size (%d)", size);
+			return false;
+		}
+		return logi_dj_hidpp_event(hdev, report, data, size);
 	case REPORT_ID_HIDPP_LONG:
 	case REPORT_ID_HIDPP_LONG:
+		if (size != HIDPP_REPORT_LONG_LENGTH) {
+			dev_err(&hdev->dev,
+				"Long HID++ report of bad size (%d)", size);
+			return false;
+		}
 		return logi_dj_hidpp_event(hdev, report, data, size);
 		return logi_dj_hidpp_event(hdev, report, data, size);
 	}
 	}
 
 

+ 41 - 0
drivers/hid/hid-logitech-hidpp.c

@@ -282,6 +282,33 @@ static inline bool hidpp_report_is_connect_event(struct hidpp_report *report)
 		(report->rap.sub_id == 0x41);
 		(report->rap.sub_id == 0x41);
 }
 }
 
 
+/**
+ * hidpp_prefix_name() prefixes the current given name with "Logitech ".
+ */
+static void hidpp_prefix_name(char **name, int name_length)
+{
+#define PREFIX_LENGTH 9 /* "Logitech " */
+
+	int new_length;
+	char *new_name;
+
+	if (name_length > PREFIX_LENGTH &&
+	    strncmp(*name, "Logitech ", PREFIX_LENGTH) == 0)
+		/* The prefix has is already in the name */
+		return;
+
+	new_length = PREFIX_LENGTH + name_length;
+	new_name = kzalloc(new_length, GFP_KERNEL);
+	if (!new_name)
+		return;
+
+	snprintf(new_name, new_length, "Logitech %s", *name);
+
+	kfree(*name);
+
+	*name = new_name;
+}
+
 /* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
 /* HIDP++ 1.0 commands                                                        */
 /* HIDP++ 1.0 commands                                                        */
 /* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
@@ -321,6 +348,10 @@ static char *hidpp_get_unifying_name(struct hidpp_device *hidpp_dev)
 		return NULL;
 		return NULL;
 
 
 	memcpy(name, &response.rap.params[2], len);
 	memcpy(name, &response.rap.params[2], len);
+
+	/* include the terminating '\0' */
+	hidpp_prefix_name(&name, len + 1);
+
 	return name;
 	return name;
 }
 }
 
 
@@ -498,6 +529,9 @@ static char *hidpp_get_device_name(struct hidpp_device *hidpp)
 		index += ret;
 		index += ret;
 	}
 	}
 
 
+	/* include the terminating '\0' */
+	hidpp_prefix_name(&name, __name_length + 1);
+
 	return name;
 	return name;
 }
 }
 
 
@@ -794,18 +828,25 @@ static int wtp_raw_event(struct hid_device *hdev, u8 *data, int size)
 
 
 	switch (data[0]) {
 	switch (data[0]) {
 	case 0x02:
 	case 0x02:
+		if (size < 2) {
+			hid_err(hdev, "Received HID report of bad size (%d)",
+				size);
+			return 1;
+		}
 		if (hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS) {
 		if (hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS) {
 			input_event(wd->input, EV_KEY, BTN_LEFT,
 			input_event(wd->input, EV_KEY, BTN_LEFT,
 					!!(data[1] & 0x01));
 					!!(data[1] & 0x01));
 			input_event(wd->input, EV_KEY, BTN_RIGHT,
 			input_event(wd->input, EV_KEY, BTN_RIGHT,
 					!!(data[1] & 0x02));
 					!!(data[1] & 0x02));
 			input_sync(wd->input);
 			input_sync(wd->input);
+			return 0;
 		} else {
 		} else {
 			if (size < 21)
 			if (size < 21)
 				return 1;
 				return 1;
 			return wtp_mouse_raw_xy_event(hidpp, &data[7]);
 			return wtp_mouse_raw_xy_event(hidpp, &data[7]);
 		}
 		}
 	case REPORT_ID_HIDPP_LONG:
 	case REPORT_ID_HIDPP_LONG:
+		/* size is already checked in hidpp_raw_event. */
 		if ((report->fap.feature_index != wd->mt_feature_index) ||
 		if ((report->fap.feature_index != wd->mt_feature_index) ||
 		    (report->fap.funcindex_clientid != EVENT_TOUCHPAD_RAW_XY))
 		    (report->fap.funcindex_clientid != EVENT_TOUCHPAD_RAW_XY))
 			return 1;
 			return 1;

+ 6 - 2
drivers/hid/hid-roccat-pyra.c

@@ -35,6 +35,8 @@ static struct class *pyra_class;
 static void profile_activated(struct pyra_device *pyra,
 static void profile_activated(struct pyra_device *pyra,
 		unsigned int new_profile)
 		unsigned int new_profile)
 {
 {
+	if (new_profile >= ARRAY_SIZE(pyra->profile_settings))
+		return;
 	pyra->actual_profile = new_profile;
 	pyra->actual_profile = new_profile;
 	pyra->actual_cpi = pyra->profile_settings[pyra->actual_profile].y_cpi;
 	pyra->actual_cpi = pyra->profile_settings[pyra->actual_profile].y_cpi;
 }
 }
@@ -257,9 +259,11 @@ static ssize_t pyra_sysfs_write_settings(struct file *fp,
 	if (off != 0 || count != PYRA_SIZE_SETTINGS)
 	if (off != 0 || count != PYRA_SIZE_SETTINGS)
 		return -EINVAL;
 		return -EINVAL;
 
 
-	mutex_lock(&pyra->pyra_lock);
-
 	settings = (struct pyra_settings const *)buf;
 	settings = (struct pyra_settings const *)buf;
+	if (settings->startup_profile >= ARRAY_SIZE(pyra->profile_settings))
+		return -EINVAL;
+
+	mutex_lock(&pyra->pyra_lock);
 
 
 	retval = pyra_set_settings(usb_dev, settings);
 	retval = pyra_set_settings(usb_dev, settings);
 	if (retval) {
 	if (retval) {

+ 0 - 5
drivers/hid/i2c-hid/i2c-hid.c

@@ -706,12 +706,7 @@ static int i2c_hid_start(struct hid_device *hid)
 
 
 static void i2c_hid_stop(struct hid_device *hid)
 static void i2c_hid_stop(struct hid_device *hid)
 {
 {
-	struct i2c_client *client = hid->driver_data;
-	struct i2c_hid *ihid = i2c_get_clientdata(client);
-
 	hid->claimed = 0;
 	hid->claimed = 0;
-
-	i2c_hid_free_buffers(ihid);
 }
 }
 
 
 static int i2c_hid_open(struct hid_device *hid)
 static int i2c_hid_open(struct hid_device *hid)

+ 1 - 0
drivers/hid/usbhid/hid-quirks.c

@@ -124,6 +124,7 @@ static const struct hid_blacklist {
 	{ USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS, HID_QUIRK_MULTI_INPUT },
 	{ USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS, HID_QUIRK_MULTI_INPUT },
 	{ USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD, HID_QUIRK_NO_INIT_REPORTS },
 	{ USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD, HID_QUIRK_NO_INIT_REPORTS },
 	{ USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X, HID_QUIRK_MULTI_INPUT },
 	{ USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X, HID_QUIRK_MULTI_INPUT },
+	{ USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2, HID_QUIRK_MULTI_INPUT },
 	{ USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X, HID_QUIRK_MULTI_INPUT },
 	{ USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X, HID_QUIRK_MULTI_INPUT },
 	{ USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_DUOSENSE, HID_QUIRK_NO_INIT_REPORTS },
 	{ USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_DUOSENSE, HID_QUIRK_NO_INIT_REPORTS },
 	{ USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD, HID_QUIRK_NO_INIT_REPORTS },
 	{ USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD, HID_QUIRK_NO_INIT_REPORTS },

+ 4 - 8
drivers/iommu/intel-iommu.c

@@ -4029,14 +4029,6 @@ static int device_notifier(struct notifier_block *nb,
 	if (action != BUS_NOTIFY_REMOVED_DEVICE)
 	if (action != BUS_NOTIFY_REMOVED_DEVICE)
 		return 0;
 		return 0;
 
 
-	/*
-	 * If the device is still attached to a device driver we can't
-	 * tear down the domain yet as DMA mappings may still be in use.
-	 * Wait for the BUS_NOTIFY_UNBOUND_DRIVER event to do that.
-	 */
-	if (action == BUS_NOTIFY_DEL_DEVICE && dev->driver != NULL)
-		return 0;
-
 	domain = find_domain(dev);
 	domain = find_domain(dev);
 	if (!domain)
 	if (!domain)
 		return 0;
 		return 0;
@@ -4428,6 +4420,10 @@ static int intel_iommu_attach_device(struct iommu_domain *domain,
 				domain_remove_one_dev_info(old_domain, dev);
 				domain_remove_one_dev_info(old_domain, dev);
 			else
 			else
 				domain_remove_dev_info(old_domain);
 				domain_remove_dev_info(old_domain);
+
+			if (!domain_type_is_vm_or_si(old_domain) &&
+			     list_empty(&old_domain->devices))
+				domain_exit(old_domain);
 		}
 		}
 	}
 	}
 
 

+ 3 - 3
drivers/iommu/ipmmu-vmsa.c

@@ -558,7 +558,7 @@ static pmd_t *ipmmu_alloc_pmd(struct ipmmu_vmsa_device *mmu, pgd_t *pgd,
 
 
 static u64 ipmmu_page_prot(unsigned int prot, u64 type)
 static u64 ipmmu_page_prot(unsigned int prot, u64 type)
 {
 {
-	u64 pgprot = ARM_VMSA_PTE_XN | ARM_VMSA_PTE_nG | ARM_VMSA_PTE_AF
+	u64 pgprot = ARM_VMSA_PTE_nG | ARM_VMSA_PTE_AF
 		   | ARM_VMSA_PTE_SH_IS | ARM_VMSA_PTE_AP_UNPRIV
 		   | ARM_VMSA_PTE_SH_IS | ARM_VMSA_PTE_AP_UNPRIV
 		   | ARM_VMSA_PTE_NS | type;
 		   | ARM_VMSA_PTE_NS | type;
 
 
@@ -568,8 +568,8 @@ static u64 ipmmu_page_prot(unsigned int prot, u64 type)
 	if (prot & IOMMU_CACHE)
 	if (prot & IOMMU_CACHE)
 		pgprot |= IMMAIR_ATTR_IDX_WBRWA << ARM_VMSA_PTE_ATTRINDX_SHIFT;
 		pgprot |= IMMAIR_ATTR_IDX_WBRWA << ARM_VMSA_PTE_ATTRINDX_SHIFT;
 
 
-	if (prot & IOMMU_EXEC)
-		pgprot &= ~ARM_VMSA_PTE_XN;
+	if (prot & IOMMU_NOEXEC)
+		pgprot |= ARM_VMSA_PTE_XN;
 	else if (!(prot & (IOMMU_READ | IOMMU_WRITE)))
 	else if (!(prot & (IOMMU_READ | IOMMU_WRITE)))
 		/* If no access create a faulting entry to avoid TLB fills. */
 		/* If no access create a faulting entry to avoid TLB fills. */
 		pgprot &= ~ARM_VMSA_PTE_PAGE;
 		pgprot &= ~ARM_VMSA_PTE_PAGE;

+ 0 - 1
drivers/iommu/rockchip-iommu.c

@@ -1009,7 +1009,6 @@ static struct platform_driver rk_iommu_driver = {
 	.remove = rk_iommu_remove,
 	.remove = rk_iommu_remove,
 	.driver = {
 	.driver = {
 		   .name = "rk_iommu",
 		   .name = "rk_iommu",
-		   .owner = THIS_MODULE,
 		   .of_match_table = of_match_ptr(rk_iommu_dt_ids),
 		   .of_match_table = of_match_ptr(rk_iommu_dt_ids),
 	},
 	},
 };
 };

Some files were not shown because too many files changed in this diff