--- /dev/null
+From eb0a4a47ae89aaa0674ab3180de6a162f3be2ddf Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@redhat.com>
+Date: Fri, 20 May 2016 22:13:45 +0200
+Subject: af_unix: fix hard linked sockets on overlay
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+commit eb0a4a47ae89aaa0674ab3180de6a162f3be2ddf upstream.
+
+Overlayfs uses separate inodes even in the case of hard links on the
+underlying filesystems. This is a problem for AF_UNIX socket
+implementation which indexes sockets based on the inode. This resulted in
+hard linked sockets not working.
+
+The fix is to use the real, underlying inode.
+
+Test case follows:
+
+-- ovl-sock-test.c --
+#include <unistd.h>
+#include <err.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#define SOCK "test-sock"
+#define SOCK2 "test-sock2"
+
+int main(void)
+{
+ int fd, fd2;
+ struct sockaddr_un addr = {
+ .sun_family = AF_UNIX,
+ .sun_path = SOCK,
+ };
+ struct sockaddr_un addr2 = {
+ .sun_family = AF_UNIX,
+ .sun_path = SOCK2,
+ };
+
+ unlink(SOCK);
+ unlink(SOCK2);
+ if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
+ err(1, "socket");
+ if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
+ err(1, "bind");
+ if (listen(fd, 0) == -1)
+ err(1, "listen");
+ if (link(SOCK, SOCK2) == -1)
+ err(1, "link");
+ if ((fd2 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
+ err(1, "socket");
+ if (connect(fd2, (struct sockaddr *) &addr2, sizeof(addr2)) == -1)
+ err (1, "connect");
+ return 0;
+}
+----
+
+Reported-by: Alexander Morozov <alexandr.morozov@docker.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/unix/af_unix.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -315,7 +315,7 @@ static struct sock *unix_find_socket_byi
+ &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) {
+ struct dentry *dentry = unix_sk(s)->path.dentry;
+
+- if (dentry && d_backing_inode(dentry) == i) {
++ if (dentry && d_real_inode(dentry) == i) {
+ sock_hold(s);
+ goto found;
+ }
+@@ -911,7 +911,7 @@ static struct sock *unix_find_other(stru
+ err = kern_path(sunname->sun_path, LOOKUP_FOLLOW, &path);
+ if (err)
+ goto fail;
+- inode = d_backing_inode(path.dentry);
++ inode = d_real_inode(path.dentry);
+ err = inode_permission(inode, MAY_WRITE);
+ if (err)
+ goto put_fail;
+@@ -1048,7 +1048,7 @@ static int unix_bind(struct socket *sock
+ goto out_up;
+ }
+ addr->hash = UNIX_HASH_SIZE;
+- hash = d_backing_inode(dentry)->i_ino & (UNIX_HASH_SIZE - 1);
++ hash = d_real_inode(dentry)->i_ino & (UNIX_HASH_SIZE - 1);
+ spin_lock(&unix_table_lock);
+ u->path = u_path;
+ list = &unix_socket_table[hash];
--- /dev/null
+From 64c12921e11b3a0c10d088606e328c58e29274d8 Mon Sep 17 00:00:00 2001
+From: Jeff Mahoney <jeffm@suse.com>
+Date: Wed, 8 Jun 2016 00:36:38 -0400
+Subject: btrfs: account for non-CoW'd blocks in btrfs_abort_transaction
+
+From: Jeff Mahoney <jeffm@suse.com>
+
+commit 64c12921e11b3a0c10d088606e328c58e29274d8 upstream.
+
+The test for !trans->blocks_used in btrfs_abort_transaction is
+insufficient to determine whether it's safe to drop the transaction
+handle on the floor. btrfs_cow_block, informed by should_cow_block,
+can return blocks that have already been CoW'd in the current
+transaction. trans->blocks_used is only incremented for new block
+allocations. If an operation overlaps the blocks in the current
+transaction entirely and must abort the transaction, we'll happily
+let it clean up the trans handle even though it may have modified
+the blocks and will commit an incomplete operation.
+
+In the long-term, I'd like to do closer tracking of when the fs
+is actually modified so we can still recover as gracefully as possible,
+but that approach will need some discussion. In the short term,
+since this is the only code using trans->blocks_used, let's just
+switch it to a bool indicating whether any blocks were used and set
+it when should_cow_block returns false.
+
+Signed-off-by: Jeff Mahoney <jeffm@suse.com>
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/ctree.c | 5 ++++-
+ fs/btrfs/extent-tree.c | 2 +-
+ fs/btrfs/super.c | 2 +-
+ fs/btrfs/transaction.h | 2 +-
+ 4 files changed, 7 insertions(+), 4 deletions(-)
+
+--- a/fs/btrfs/ctree.c
++++ b/fs/btrfs/ctree.c
+@@ -1552,6 +1552,7 @@ noinline int btrfs_cow_block(struct btrf
+ trans->transid, root->fs_info->generation);
+
+ if (!should_cow_block(trans, root, buf)) {
++ trans->dirty = true;
+ *cow_ret = buf;
+ return 0;
+ }
+@@ -2773,8 +2774,10 @@ again:
+ * then we don't want to set the path blocking,
+ * so we test it here
+ */
+- if (!should_cow_block(trans, root, b))
++ if (!should_cow_block(trans, root, b)) {
++ trans->dirty = true;
+ goto cow_done;
++ }
+
+ /*
+ * must have write locks on this node and the
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -7929,7 +7929,7 @@ btrfs_init_new_buffer(struct btrfs_trans
+ set_extent_dirty(&trans->transaction->dirty_pages, buf->start,
+ buf->start + buf->len - 1, GFP_NOFS);
+ }
+- trans->blocks_used++;
++ trans->dirty = true;
+ /* this returns a buffer locked for blocking */
+ return buf;
+ }
+--- a/fs/btrfs/super.c
++++ b/fs/btrfs/super.c
+@@ -239,7 +239,7 @@ void __btrfs_abort_transaction(struct bt
+ trans->aborted = errno;
+ /* Nothing used. The other threads that have joined this
+ * transaction may be able to continue. */
+- if (!trans->blocks_used && list_empty(&trans->new_bgs)) {
++ if (!trans->dirty && list_empty(&trans->new_bgs)) {
+ const char *errstr;
+
+ errstr = btrfs_decode_error(errno);
+--- a/fs/btrfs/transaction.h
++++ b/fs/btrfs/transaction.h
+@@ -110,7 +110,6 @@ struct btrfs_trans_handle {
+ u64 chunk_bytes_reserved;
+ unsigned long use_count;
+ unsigned long blocks_reserved;
+- unsigned long blocks_used;
+ unsigned long delayed_ref_updates;
+ struct btrfs_transaction *transaction;
+ struct btrfs_block_rsv *block_rsv;
+@@ -121,6 +120,7 @@ struct btrfs_trans_handle {
+ bool can_flush_pending_bgs;
+ bool reloc_reserved;
+ bool sync;
++ bool dirty;
+ unsigned int type;
+ /*
+ * this root is only needed to validate that the root passed to
--- /dev/null
+From b201e743f42d143f4bcdcb14587caf7cb1d99229 Mon Sep 17 00:00:00 2001
+From: Tomi Valkeinen <tomi.valkeinen@ti.com>
+Date: Tue, 31 May 2016 15:03:15 +0300
+Subject: drm: add missing drm_mode_set_crtcinfo call
+
+From: Tomi Valkeinen <tomi.valkeinen@ti.com>
+
+commit b201e743f42d143f4bcdcb14587caf7cb1d99229 upstream.
+
+When setting mode via MODE_ID property,
+drm_atomic_set_mode_prop_for_crtc() does not call
+drm_mode_set_crtcinfo() which possibly causes:
+
+"[drm:drm_calc_timestamping_constants [drm]] *ERROR* crtc 32: Can't
+calculate constants, dotclock = 0!"
+
+Whether the error is seen depends on the previous data in state->mode,
+as state->mode is not cleared when setting new mode.
+
+This patch adds drm_mode_set_crtcinfo() call to
+drm_mode_convert_umode(), which is called in both legacy and atomic
+paths. This should be fine as there's no reason to call
+drm_mode_convert_umode() without also setting the crtc related fields.
+
+drm_mode_set_crtcinfo() is removed from the legacy drm_mode_setcrtc() as
+that is no longer needed.
+
+Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
+Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/drm_crtc.c | 2 --
+ drivers/gpu/drm/drm_modes.c | 2 ++
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/drm_crtc.c
++++ b/drivers/gpu/drm/drm_crtc.c
+@@ -2800,8 +2800,6 @@ int drm_mode_setcrtc(struct drm_device *
+ goto out;
+ }
+
+- drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
+-
+ /*
+ * Check whether the primary plane supports the fb pixel format.
+ * Drivers not implementing the universal planes API use a
+--- a/drivers/gpu/drm/drm_modes.c
++++ b/drivers/gpu/drm/drm_modes.c
+@@ -1518,6 +1518,8 @@ int drm_mode_convert_umode(struct drm_di
+ if (out->status != MODE_OK)
+ goto out;
+
++ drm_mode_set_crtcinfo(out, CRTC_INTERLACE_HALVE_V);
++
+ ret = 0;
+
+ out:
--- /dev/null
+From 576b4401b1971fe40be4cfd379430a61cd8426b2 Mon Sep 17 00:00:00 2001
+From: Rex Zhu <Rex.Zhu@amd.com>
+Date: Mon, 13 Jun 2016 17:39:19 +0800
+Subject: drm/amd/powerplay: fix bug that function parameter was incorect.
+
+From: Rex Zhu <Rex.Zhu@amd.com>
+
+commit 576b4401b1971fe40be4cfd379430a61cd8426b2 upstream.
+
+Wrong value passed to acpi_pcie_perf_request.
+
+Signed-off-by: Rex Zhu <Rex.Zhu@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Reviewed-by: Ken Wang <Qingqing.Wang@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/powerplay/hwmgr/pp_acpi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_acpi.c
++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_acpi.c
+@@ -54,7 +54,7 @@ int acpi_pcie_perf_request(void *device,
+ ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST,
+ &atcs_input,
+ &atcs_output,
+- 0,
++ 1,
+ sizeof(atcs_input),
+ sizeof(atcs_output));
+ if (result != 0)
--- /dev/null
+From 1dfefee8939b07dd65a35bb78f6a06df85578301 Mon Sep 17 00:00:00 2001
+From: Huang Rui <ray.huang@amd.com>
+Date: Wed, 6 Jul 2016 09:32:24 +0800
+Subject: drm/amd/powerplay: fix incorrect voltage table value for tonga
+
+From: Huang Rui <ray.huang@amd.com>
+
+commit 1dfefee8939b07dd65a35bb78f6a06df85578301 upstream.
+
+Signed-off-by: Huang Rui <ray.huang@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c
++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c
+@@ -1298,7 +1298,7 @@ static int tonga_populate_smc_mvdd_table
+ table->Smio[count] |=
+ data->mvdd_voltage_table.entries[count].smio_low;
+ }
+- table->SmioMask2 = data->vddci_voltage_table.mask_low;
++ table->SmioMask2 = data->mvdd_voltage_table.mask_low;
+
+ CONVERT_FROM_HOST_TO_SMC_UL(table->MvddLevelCount);
+ }
--- /dev/null
+From 1d7b84d12af8312b52316029f1fa0fa4eac3c9e4 Mon Sep 17 00:00:00 2001
+From: Rex Zhu <Rex.Zhu@amd.com>
+Date: Fri, 17 Jun 2016 18:21:01 +0800
+Subject: drm/amd/powerplay: fix logic error.
+
+From: Rex Zhu <Rex.Zhu@amd.com>
+
+commit 1d7b84d12af8312b52316029f1fa0fa4eac3c9e4 upstream.
+
+the error lead powerplay can't get display info in DGPU case.
+store_cc6_data just implement in APU.
+
+Signed-off-by: Rex Zhu <Rex.Zhu@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c
++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c
+@@ -306,10 +306,14 @@ int phm_store_dal_configuration_data(str
+ {
+ PHM_FUNC_CHECK(hwmgr);
+
+- if (hwmgr->hwmgr_func->store_cc6_data == NULL)
++ if (display_config == NULL)
+ return -EINVAL;
+
+ hwmgr->display_config = *display_config;
++
++ if (hwmgr->hwmgr_func->store_cc6_data == NULL)
++ return -EINVAL;
++
+ /* to do pass other display configuration in furture */
+
+ if (hwmgr->hwmgr_func->store_cc6_data)
--- /dev/null
+From 4b2427605e5325eafb5cfc2698f517db68e41075 Mon Sep 17 00:00:00 2001
+From: Rex Zhu <Rex.Zhu@amd.com>
+Date: Tue, 5 Jul 2016 13:11:47 +0800
+Subject: drm/amd/powerplay: incorrectly use of the function return value
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rex Zhu <Rex.Zhu@amd.com>
+
+commit 4b2427605e5325eafb5cfc2698f517db68e41075 upstream.
+
+'0' means true.
+
+Signed-off-by: Rex Zhu <Rex.Zhu@amd.com>
+Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c
++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c
+@@ -299,7 +299,7 @@ static int init_dpm_2_parameters(
+ (((unsigned long)powerplay_table) + le16_to_cpu(powerplay_table->usPPMTableOffset));
+
+ if (0 != powerplay_table->usPPMTableOffset) {
+- if (1 == get_platform_power_management_table(hwmgr, atom_ppm_table)) {
++ if (get_platform_power_management_table(hwmgr, atom_ppm_table) == 0) {
+ phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+ PHM_PlatformCaps_EnablePlatformPowerManagement);
+ }
--- /dev/null
+From 0a4fef559b69ae2e682c98f31d53a225fbda78bd Mon Sep 17 00:00:00 2001
+From: Rex Zhu <Rex.Zhu@amd.com>
+Date: Tue, 14 Jun 2016 18:36:36 +0800
+Subject: drm/amd/powerplay: need to notify system bios pcie device ready
+
+From: Rex Zhu <Rex.Zhu@amd.com>
+
+commit 0a4fef559b69ae2e682c98f31d53a225fbda78bd upstream.
+
+before request performance state.
+
+Signed-off-by: Rex Zhu <Rex.Zhu@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Reviewed-by: Ken Wang <Qingqing.Wang@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/powerplay/hwmgr/pp_acpi.c | 16 +++++++++++++++-
+ drivers/gpu/drm/amd/powerplay/inc/pp_acpi.h | 1 +
+ 2 files changed, 16 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_acpi.c
++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_acpi.c
+@@ -21,6 +21,20 @@ bool acpi_atcs_functions_supported(void
+ return result == 0 ? (output_buf.function_bits & (1 << (index - 1))) != 0 : false;
+ }
+
++bool acpi_atcs_notify_pcie_device_ready(void *device)
++{
++ int32_t temp_buffer = 1;
++
++ return cgs_call_acpi_method(device, CGS_ACPI_METHOD_ATCS,
++ ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION,
++ &temp_buffer,
++ NULL,
++ 0,
++ sizeof(temp_buffer),
++ 0);
++}
++
++
+ int acpi_pcie_perf_request(void *device, uint8_t perf_req, bool advertise)
+ {
+ struct atcs_pref_req_input atcs_input;
+@@ -29,7 +43,7 @@ int acpi_pcie_perf_request(void *device,
+ int result;
+ struct cgs_system_info info = {0};
+
+- if (!acpi_atcs_functions_supported(device, ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST))
++ if( 0 != acpi_atcs_notify_pcie_device_ready(device))
+ return -EINVAL;
+
+ info.size = sizeof(struct cgs_system_info);
+--- a/drivers/gpu/drm/amd/powerplay/inc/pp_acpi.h
++++ b/drivers/gpu/drm/amd/powerplay/inc/pp_acpi.h
+@@ -26,3 +26,4 @@ extern bool acpi_atcs_functions_supporte
+ extern int acpi_pcie_perf_request(void *device,
+ uint8_t perf_req,
+ bool advertise);
++extern bool acpi_atcs_notify_pcie_device_ready(void *device);
--- /dev/null
+From 0b10029d826ed8c18a5f9d2f4abfa415d15cd1d3 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Fri, 17 Jun 2016 10:17:17 -0400
+Subject: drm/amdgpu: fix num_rbs exposed to userspace (v2)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit 0b10029d826ed8c18a5f9d2f4abfa415d15cd1d3 upstream.
+
+This was accidently broken for harvest cards when the
+code was refactored for Polaris support.
+
+v2: multiply by shader engines. Noticed by Nicolai.
+
+Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+@@ -448,7 +448,8 @@ static int amdgpu_info_ioctl(struct drm_
+ dev_info.max_memory_clock = adev->pm.default_mclk * 10;
+ }
+ dev_info.enabled_rb_pipes_mask = adev->gfx.config.backend_enable_mask;
+- dev_info.num_rb_pipes = adev->gfx.config.num_rbs;
++ dev_info.num_rb_pipes = adev->gfx.config.max_backends_per_se *
++ adev->gfx.config.max_shader_engines;
+ dev_info.num_hw_gfx_contexts = adev->gfx.config.max_hw_contexts;
+ dev_info._pad = 0;
+ dev_info.ids_flags = 0;
--- /dev/null
+From 8b18300c13a1e08e152f6b6a430faac84f986231 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Mon, 13 Jun 2016 18:26:24 -0400
+Subject: drm/amdgpu/gfx7: fix broken condition check
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit 8b18300c13a1e08e152f6b6a430faac84f986231 upstream.
+
+Wrong operator.
+
+Reported-by: David Binderman <linuxdev.baldrick@gmail.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
+@@ -5074,7 +5074,7 @@ static int gfx_v7_0_eop_irq(struct amdgp
+ case 2:
+ for (i = 0; i < adev->gfx.num_compute_rings; i++) {
+ ring = &adev->gfx.compute_ring[i];
+- if ((ring->me == me_id) & (ring->pipe == pipe_id))
++ if ((ring->me == me_id) && (ring->pipe == pipe_id))
+ amdgpu_fence_process(ring);
+ }
+ break;
--- /dev/null
+From 29b9c528b8c295911e8b1e515273e89a2b7fa2d8 Mon Sep 17 00:00:00 2001
+From: Nicolas Iooss <nicolas.iooss_linux@m4x.org>
+Date: Sat, 18 Jun 2016 22:55:00 +0200
+Subject: drm/amdgpu: initialize amdgpu_cgs_acpi_eval_object result value
+
+From: Nicolas Iooss <nicolas.iooss_linux@m4x.org>
+
+commit 29b9c528b8c295911e8b1e515273e89a2b7fa2d8 upstream.
+
+amdgpu_cgs_acpi_eval_object() returned the value of variable "result"
+without initializing it first.
+
+This bug has been found by compiling the kernel with clang. The
+compiler complained:
+
+ drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:972:14: error: variable
+ 'result' is used uninitialized whenever 'for' loop exits because its
+ condition is false [-Werror,-Wsometimes-uninitialized]
+ for (i = 0; i < count; i++) {
+ ^~~~~~~~~
+ drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:1011:9: note: uninitialized
+ use occurs here
+ return result;
+ ^~~~~~
+ drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:972:14: note: remove the
+ condition if it is always true
+ for (i = 0; i < count; i++) {
+ ^~~~~~~~~
+ drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:864:12: note: initialize the
+ variable 'result' to silence this warning
+ int result;
+ ^
+ = 0
+
+Fixes: 3f1d35a03b3c ("drm/amdgpu: implement new cgs interface for acpi
+function")
+Signed-off-by: Nicolas Iooss <nicolas.iooss_linux@m4x.org>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
+@@ -880,7 +880,7 @@ static int amdgpu_cgs_acpi_eval_object(v
+ struct cgs_acpi_method_argument *argument = NULL;
+ uint32_t i, count;
+ acpi_status status;
+- int result;
++ int result = 0;
+ uint32_t func_no = 0xFFFFFFFF;
+
+ handle = ACPI_HANDLE(&adev->pdev->dev);
--- /dev/null
+From bc4755a4bd1845ef6e88ac8c62f12e05bb530256 Mon Sep 17 00:00:00 2001
+From: Oded Gabbay <oded.gabbay@gmail.com>
+Date: Thu, 26 May 2016 08:41:48 +0300
+Subject: drm/amdkfd: destroy dbgmgr in notifier release
+
+From: Oded Gabbay <oded.gabbay@gmail.com>
+
+commit bc4755a4bd1845ef6e88ac8c62f12e05bb530256 upstream.
+
+amdkfd need to destroy the debug manager in case amdkfd's notifier
+function is called before the unbind function, because in that case,
+the unbind function will exit without destroying debug manager.
+
+Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/amdkfd/kfd_process.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+@@ -242,13 +242,19 @@ static void kfd_process_notifier_release
+ pqm_uninit(&p->pqm);
+
+ /* Iterate over all process device data structure and check
+- * if we should reset all wavefronts */
+- list_for_each_entry(pdd, &p->per_device_data, per_device_list)
++ * if we should delete debug managers and reset all wavefronts
++ */
++ list_for_each_entry(pdd, &p->per_device_data, per_device_list) {
++ if ((pdd->dev->dbgmgr) &&
++ (pdd->dev->dbgmgr->pasid == p->pasid))
++ kfd_dbgmgr_destroy(pdd->dev->dbgmgr);
++
+ if (pdd->reset_wavefronts) {
+ pr_warn("amdkfd: Resetting all wave fronts\n");
+ dbgdev_wave_reset_wavefronts(pdd->dev, p);
+ pdd->reset_wavefronts = false;
+ }
++ }
+
+ mutex_unlock(&p->mutex);
+
--- /dev/null
+From 121b78e679ee3ffab780115e260b2775d0cc1f73 Mon Sep 17 00:00:00 2001
+From: Oded Gabbay <oded.gabbay@gmail.com>
+Date: Thu, 26 May 2016 08:41:08 +0300
+Subject: drm/amdkfd: unbind only existing processes
+
+From: Oded Gabbay <oded.gabbay@gmail.com>
+
+commit 121b78e679ee3ffab780115e260b2775d0cc1f73 upstream.
+
+When unbinding a process from a device (initiated by amd_iommu_v2), the
+driver needs to make sure that process still exists in the process table.
+There is a possibility that amdkfd's own notifier handler -
+kfd_process_notifier_release() - was called before the unbind function
+and it already removed the process from the process table.
+
+v2:
+Because there can be only one process with the specified pasid, and
+because *p can't be NULL inside the hash_for_each_rcu macro, it is more
+reasonable to just put the whole code inside the if statement that
+compares the pasid value. That way, when we exit hash_for_each_rcu, we
+simply exit the function as well.
+
+Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/amdkfd/kfd_process.c | 60 ++++++++++++++++++-------------
+ 1 file changed, 35 insertions(+), 25 deletions(-)
+
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+@@ -404,42 +404,52 @@ void kfd_unbind_process_from_device(stru
+
+ idx = srcu_read_lock(&kfd_processes_srcu);
+
++ /*
++ * Look for the process that matches the pasid. If there is no such
++ * process, we either released it in amdkfd's own notifier, or there
++ * is a bug. Unfortunately, there is no way to tell...
++ */
+ hash_for_each_rcu(kfd_processes_table, i, p, kfd_processes)
+- if (p->pasid == pasid)
+- break;
++ if (p->pasid == pasid) {
+
+- srcu_read_unlock(&kfd_processes_srcu, idx);
++ srcu_read_unlock(&kfd_processes_srcu, idx);
+
+- BUG_ON(p->pasid != pasid);
++ pr_debug("Unbinding process %d from IOMMU\n", pasid);
+
+- mutex_lock(&p->mutex);
++ mutex_lock(&p->mutex);
+
+- if ((dev->dbgmgr) && (dev->dbgmgr->pasid == p->pasid))
+- kfd_dbgmgr_destroy(dev->dbgmgr);
++ if ((dev->dbgmgr) && (dev->dbgmgr->pasid == p->pasid))
++ kfd_dbgmgr_destroy(dev->dbgmgr);
+
+- pqm_uninit(&p->pqm);
++ pqm_uninit(&p->pqm);
+
+- pdd = kfd_get_process_device_data(dev, p);
++ pdd = kfd_get_process_device_data(dev, p);
+
+- if (!pdd) {
+- mutex_unlock(&p->mutex);
+- return;
+- }
++ if (!pdd) {
++ mutex_unlock(&p->mutex);
++ return;
++ }
+
+- if (pdd->reset_wavefronts) {
+- dbgdev_wave_reset_wavefronts(pdd->dev, p);
+- pdd->reset_wavefronts = false;
+- }
++ if (pdd->reset_wavefronts) {
++ dbgdev_wave_reset_wavefronts(pdd->dev, p);
++ pdd->reset_wavefronts = false;
++ }
+
+- /*
+- * Just mark pdd as unbound, because we still need it to call
+- * amd_iommu_unbind_pasid() in when the process exits.
+- * We don't call amd_iommu_unbind_pasid() here
+- * because the IOMMU called us.
+- */
+- pdd->bound = false;
++ /*
++ * Just mark pdd as unbound, because we still need it
++ * to call amd_iommu_unbind_pasid() in when the
++ * process exits.
++ * We don't call amd_iommu_unbind_pasid() here
++ * because the IOMMU called us.
++ */
++ pdd->bound = false;
++
++ mutex_unlock(&p->mutex);
+
+- mutex_unlock(&p->mutex);
++ return;
++ }
++
++ srcu_read_unlock(&kfd_processes_srcu, idx);
+ }
+
+ struct kfd_process_device *kfd_get_first_process_device_data(struct kfd_process *p)
--- /dev/null
+From 1b7e38b92b0bbd363369f5160f13f4d26140972d Mon Sep 17 00:00:00 2001
+From: Boris Brezillon <boris.brezillon@free-electrons.com>
+Date: Fri, 27 May 2016 16:09:25 +0200
+Subject: drm: atmel-hlcdc: actually disable scaling when no scaling is required
+
+From: Boris Brezillon <boris.brezillon@free-electrons.com>
+
+commit 1b7e38b92b0bbd363369f5160f13f4d26140972d upstream.
+
+The driver is only enabling scaling, but never disabling it, thus, if you
+enable the scaling feature once it stays enabled forever.
+
+Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Reported-by: Alex Vazquez <avazquez.dev@gmail.com>
+Reviewed-by: Nicolas Ferre <nicolas.ferre@atmel.com>
+Fixes: 1a396789f65a ("drm: add Atmel HLCDC Display Controller support")
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
++++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
+@@ -335,6 +335,8 @@ atmel_hlcdc_plane_update_pos_and_size(st
+
+ atmel_hlcdc_layer_update_cfg(&plane->layer, 13, 0xffffffff,
+ factor_reg);
++ } else {
++ atmel_hlcdc_layer_update_cfg(&plane->layer, 13, 0xffffffff, 0);
+ }
+ }
+
--- /dev/null
+From 81e257e964268d050f8e9188becd44d50f241d72 Mon Sep 17 00:00:00 2001
+From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+Date: Thu, 23 Jun 2016 13:45:06 +0200
+Subject: drm/atomic: Make drm_atomic_legacy_backoff reset crtc->acquire_ctx
+
+From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+
+commit 81e257e964268d050f8e9188becd44d50f241d72 upstream.
+
+Atomic updates may acquire more state than initially locked through
+drm_modeset_lock_crtc, running with heavy stress can cause a
+WARN_ON(crtc->acquire_ctx) in drm_modeset_lock_crtc:
+
+[ 601.491296] ------------[ cut here ]------------
+[ 601.491366] WARNING: CPU: 0 PID: 2411 at
+drivers/gpu/drm/drm_modeset_lock.c:191 drm_modeset_lock_crtc+0xeb/0xf0 [drm]
+[ 601.491369] Modules linked in: drm i915 drm_kms_helper
+[ 601.491414] CPU: 0 PID: 2411 Comm: kms_cursor_lega Tainted: G U 4.7.0-rc4-patser+ #4798
+[ 601.491417] Hardware name: Intel Corporation Skylake Client
+[ 601.491420] 0000000000000000 ffff88044d153c98 ffffffff812ead28 0000000000000000
+[ 601.491425] 0000000000000000 ffff88044d153cd8 ffffffff810868e6 000000bf58058030
+[ 601.491431] ffff880088b415e8 ffff880458058030 ffff88008a271548 ffff88008a271568
+[ 601.491436] Call Trace:
+[ 601.491443] [<ffffffff812ead28>] dump_stack+0x4d/0x65
+[ 601.491447] [<ffffffff810868e6>] __warn+0xc6/0xe0
+[ 601.491452] [<ffffffff81086968>] warn_slowpath_null+0x18/0x20
+[ 601.491472] [<ffffffffc00d4ffb>] drm_modeset_lock_crtc+0xeb/0xf0 [drm]
+[ 601.491491] [<ffffffffc00c5526>] drm_mode_cursor_common+0x66/0x180 [drm]
+[ 601.491509] [<ffffffffc00c91cc>] drm_mode_cursor_ioctl+0x3c/0x40 [drm]
+[ 601.491524] [<ffffffffc00bc94d>] drm_ioctl+0x14d/0x530 [drm]
+[ 601.491540] [<ffffffffc00c9190>] ? drm_mode_setcrtc+0x520/0x520 [drm]
+[ 601.491545] [<ffffffff81176aeb>] ? handle_mm_fault+0x106b/0x1430
+[ 601.491550] [<ffffffff81108441>] ? stop_one_cpu+0x61/0x70
+[ 601.491556] [<ffffffff811bb71d>] do_vfs_ioctl+0x8d/0x570
+[ 601.491560] [<ffffffff81290d7e>] ? security_file_ioctl+0x3e/0x60
+[ 601.491565] [<ffffffff811bbc74>] SyS_ioctl+0x74/0x80
+[ 601.491571] [<ffffffff810e321c>] ? posix_get_monotonic_raw+0xc/0x10
+[ 601.491576] [<ffffffff8175b11b>] entry_SYSCALL_64_fastpath+0x13/0x8f
+[ 601.491581] ---[ end trace 56f3d3d85f000d00 ]---
+
+For good measure, test mode_config.acquire_ctx too, although this should
+never happen.
+
+Testcase: kms_cursor_legacy
+Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/drm_atomic.c | 27 ++++++++++++++++++++++++++-
+ 1 file changed, 26 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/drm_atomic.c
++++ b/drivers/gpu/drm/drm_atomic.c
+@@ -1288,14 +1288,39 @@ EXPORT_SYMBOL(drm_atomic_add_affected_pl
+ */
+ void drm_atomic_legacy_backoff(struct drm_atomic_state *state)
+ {
++ struct drm_device *dev = state->dev;
++ unsigned crtc_mask = 0;
++ struct drm_crtc *crtc;
+ int ret;
++ bool global = false;
++
++ drm_for_each_crtc(crtc, dev) {
++ if (crtc->acquire_ctx != state->acquire_ctx)
++ continue;
++
++ crtc_mask |= drm_crtc_mask(crtc);
++ crtc->acquire_ctx = NULL;
++ }
++
++ if (WARN_ON(dev->mode_config.acquire_ctx == state->acquire_ctx)) {
++ global = true;
++
++ dev->mode_config.acquire_ctx = NULL;
++ }
+
+ retry:
+ drm_modeset_backoff(state->acquire_ctx);
+
+- ret = drm_modeset_lock_all_ctx(state->dev, state->acquire_ctx);
++ ret = drm_modeset_lock_all_ctx(dev, state->acquire_ctx);
+ if (ret)
+ goto retry;
++
++ drm_for_each_crtc(crtc, dev)
++ if (drm_crtc_mask(crtc) & crtc_mask)
++ crtc->acquire_ctx = state->acquire_ctx;
++
++ if (global)
++ dev->mode_config.acquire_ctx = state->acquire_ctx;
+ }
+ EXPORT_SYMBOL(drm_atomic_legacy_backoff);
+
--- /dev/null
+From fd2d2bac6e79b0be91ab86a6075a0c46ffda658a Mon Sep 17 00:00:00 2001
+From: Andrey Grodzovsky <Andrey.Grodzovsky@amd.com>
+Date: Wed, 25 May 2016 16:45:43 -0400
+Subject: drm/dp/mst: Always clear proposed vcpi table for port.
+
+From: Andrey Grodzovsky <Andrey.Grodzovsky@amd.com>
+
+commit fd2d2bac6e79b0be91ab86a6075a0c46ffda658a upstream.
+
+Not clearing mst manager's proposed vcpis table for destroyed connectors when the manager is stopped leaves it pointing to unrefernced memory, this causes pagefault when the manager is restarted when plugging back a branch.
+
+Fixes: 91a25e463130 ("drm/dp/mst: deallocate payload on port destruction")
+Signed-off-by: Andrey Grodzovsky <Andrey.Grodzovsky@amd.com>
+Reviewed-by: Lyude <cpaul@redhat.com>
+Cc: Mykola Lysenko <Mykola.Lysenko@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/drm_dp_mst_topology.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+--- a/drivers/gpu/drm/drm_dp_mst_topology.c
++++ b/drivers/gpu/drm/drm_dp_mst_topology.c
+@@ -2908,11 +2908,9 @@ static void drm_dp_destroy_connector_wor
+ drm_dp_port_teardown_pdt(port, port->pdt);
+
+ if (!port->input && port->vcpi.vcpi > 0) {
+- if (mgr->mst_state) {
+- drm_dp_mst_reset_vcpi_slots(mgr, port);
+- drm_dp_update_payload_part1(mgr);
+- drm_dp_mst_put_payload_id(mgr, port->vcpi.vcpi);
+- }
++ drm_dp_mst_reset_vcpi_slots(mgr, port);
++ drm_dp_update_payload_part1(mgr);
++ drm_dp_mst_put_payload_id(mgr, port->vcpi.vcpi);
+ }
+
+ kref_put(&port->kref, drm_dp_free_mst_port);
--- /dev/null
+From 1e3fa0acfec677e915d7de5ac6e1f18cfa4f805b Mon Sep 17 00:00:00 2001
+From: Lyude <cpaul@redhat.com>
+Date: Thu, 9 Jun 2016 11:58:15 -0400
+Subject: drm/i915/fbc: Disable on HSW by default for now
+
+From: Lyude <cpaul@redhat.com>
+
+commit 1e3fa0acfec677e915d7de5ac6e1f18cfa4f805b upstream.
+
+>From https://bugs.freedesktop.org/show_bug.cgi?id=96461 :
+
+This was kind of a difficult bug to track down. If you're using a
+Haswell system running GNOME and you have fbc completely enabled and
+working, playing videos can result in video artifacts. Steps to
+reproduce:
+
+- Run GNOME
+- Ensure FBC is enabled and active
+- Download a movie, I used the ogg version of Big Buck Bunny for this
+- Run `gst-launch-1.0 filesrc location='some_movie.ogg' ! decodebin !
+ glimagesink` in a terminal
+- Watch for about over a minute, you'll see small horizontal lines go
+ down the screen.
+
+For the time being, disable FBC for Haswell by default.
+
+Stefan Richter reported kernel freezes (no video artifacts) when fbc
+is on. (E3-1245 v3 with HD P4600; openbox and some KDE and LXDE
+applications, thread begins at https://lkml.org/lkml/2016/4/26/813).
+We also got reports from Steven Honeyman on openbox+roxterm.
+
+v2 (From Paulo):
+ - Add extra information to the commit message
+ - Add Fixes tag
+ - Rebase
+
+Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96461
+Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96464
+Fixes: a98ee79317b4 ("drm/i915/fbc: enable FBC by default on HSW and BDW")
+Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
+Signed-off-by: Lyude <cpaul@redhat.com>
+Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/1465487895-7401-1-git-send-email-cpaul@redhat.com
+(cherry picked from commit c7f7e2feffb0294302041507dfd5fc15f01afccc)
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/intel_fbc.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/i915/intel_fbc.c
++++ b/drivers/gpu/drm/i915/intel_fbc.c
+@@ -823,8 +823,7 @@ static bool intel_fbc_can_choose(struct
+ {
+ struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+ struct intel_fbc *fbc = &dev_priv->fbc;
+- bool enable_by_default = IS_HASWELL(dev_priv) ||
+- IS_BROADWELL(dev_priv);
++ bool enable_by_default = IS_BROADWELL(dev_priv);
+
+ if (intel_vgpu_active(dev_priv->dev)) {
+ fbc->no_fbc_reason = "VGPU is active";
--- /dev/null
+From 476490a945e1f0f6bd58e303058d2d8ca93a974c Mon Sep 17 00:00:00 2001
+From: Lyude <cpaul@redhat.com>
+Date: Tue, 14 Jun 2016 11:04:09 -0400
+Subject: drm/i915/ilk: Don't disable SSC source if it's in use
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Lyude <cpaul@redhat.com>
+
+commit 476490a945e1f0f6bd58e303058d2d8ca93a974c upstream.
+
+Thanks to Ville Syrjälä for pointing me towards the cause of this issue.
+
+Unfortunately one of the sideaffects of having the refclk for a DPLL set
+to SSC is that as long as it's set to SSC, the GPU will prevent us from
+powering down any of the pipes or transcoders using it. A couple of
+BIOSes enable SSC in both PCH_DREF_CONTROL and in the DPLL
+configurations. This causes issues on the first modeset, since we don't
+expect SSC to be left on and as a result, can't successfully power down
+the pipes or the transcoders using it. Here's an example from this Dell
+OptiPlex 990:
+
+[drm:intel_modeset_init] SSC enabled by BIOS, overriding VBT which says disabled
+[drm:intel_modeset_init] 2 display pipes available.
+[drm:intel_update_cdclk] Current CD clock rate: 400000 kHz
+[drm:intel_update_max_cdclk] Max CD clock rate: 400000 kHz
+[drm:intel_update_max_cdclk] Max dotclock rate: 360000 kHz
+vgaarb: device changed decodes: PCI:0000:00:02.0,olddecodes=io+mem,decodes=io+mem:owns=io+mem
+[drm:intel_crt_reset] crt adpa set to 0xf40000
+[drm:intel_dp_init_connector] Adding DP connector on port C
+[drm:intel_dp_aux_init] registering DPDDC-C bus for card0-DP-1
+[drm:ironlake_init_pch_refclk] has_panel 0 has_lvds 0 has_ck505 0
+[drm:ironlake_init_pch_refclk] Disabling SSC entirely
+… later we try committing the first modeset …
+[drm:intel_dump_pipe_config] [CRTC:26][modeset] config ffff88041b02e800 for pipe A
+[drm:intel_dump_pipe_config] cpu_transcoder: A
+…
+[drm:intel_dump_pipe_config] dpll_hw_state: dpll: 0xc4016001, dpll_md: 0x0, fp0: 0x20e08, fp1: 0x30d07
+[drm:intel_dump_pipe_config] planes on this crtc
+[drm:intel_dump_pipe_config] STANDARD PLANE:23 plane: 0.0 idx: 0 enabled
+[drm:intel_dump_pipe_config] FB:42, fb = 800x600 format = 0x34325258
+[drm:intel_dump_pipe_config] scaler:0 src (0, 0) 800x600 dst (0, 0) 800x600
+[drm:intel_dump_pipe_config] CURSOR PLANE:25 plane: 0.1 idx: 1 disabled, scaler_id = 0
+[drm:intel_dump_pipe_config] STANDARD PLANE:27 plane: 0.1 idx: 2 disabled, scaler_id = 0
+[drm:intel_get_shared_dpll] CRTC:26 allocated PCH DPLL A
+[drm:intel_get_shared_dpll] using PCH DPLL A for pipe A
+[drm:ilk_audio_codec_disable] Disable audio codec on port C, pipe A
+[drm:intel_disable_pipe] disabling pipe A
+------------[ cut here ]------------
+WARNING: CPU: 1 PID: 130 at drivers/gpu/drm/i915/intel_display.c:1146 intel_disable_pipe+0x297/0x2d0 [i915]
+pipe_off wait timed out
+…
+---[ end trace 94fc8aa03ae139e8 ]---
+[drm:intel_dp_link_down]
+[drm:ironlake_crtc_disable [i915]] *ERROR* failed to disable transcoder A
+
+Later modesets succeed since they reset the DPLL's configuration anyway,
+but this is enough to get stuck with a big fat warning in dmesg.
+
+A better solution would be to add refcounts for the SSC source, but for
+now leaving the source clock on should suffice.
+
+Changes since v4:
+ - Fix calculation of final for systems with LVDS panels (fixes BUG() on
+ CI test suite)
+Changes since v3:
+ - Move temp variable into loop
+ - Move checks for using_ssc_source to after we've figured out has_ck505
+ - Add using_ssc_source to debug output
+Changes since v2:
+ - Fix debug output for when we disable the CPU source
+Changes since v1:
+ - Leave the SSC source clock on instead of just shutting it off on all
+ of the DPLL configurations.
+
+Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Signed-off-by: Lyude <cpaul@redhat.com>
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Link: http://patchwork.freedesktop.org/patch/msgid/1465916649-10228-1-git-send-email-cpaul@redhat.com
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/intel_display.c | 48 ++++++++++++++++++++++++-----------
+ 1 file changed, 34 insertions(+), 14 deletions(-)
+
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -8229,12 +8229,14 @@ static void ironlake_init_pch_refclk(str
+ {
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_encoder *encoder;
++ int i;
+ u32 val, final;
+ bool has_lvds = false;
+ bool has_cpu_edp = false;
+ bool has_panel = false;
+ bool has_ck505 = false;
+ bool can_ssc = false;
++ bool using_ssc_source = false;
+
+ /* We need to take the global config into account */
+ for_each_intel_encoder(dev, encoder) {
+@@ -8261,8 +8263,22 @@ static void ironlake_init_pch_refclk(str
+ can_ssc = true;
+ }
+
+- DRM_DEBUG_KMS("has_panel %d has_lvds %d has_ck505 %d\n",
+- has_panel, has_lvds, has_ck505);
++ /* Check if any DPLLs are using the SSC source */
++ for (i = 0; i < dev_priv->num_shared_dpll; i++) {
++ u32 temp = I915_READ(PCH_DPLL(i));
++
++ if (!(temp & DPLL_VCO_ENABLE))
++ continue;
++
++ if ((temp & PLL_REF_INPUT_MASK) ==
++ PLLB_REF_INPUT_SPREADSPECTRUMIN) {
++ using_ssc_source = true;
++ break;
++ }
++ }
++
++ DRM_DEBUG_KMS("has_panel %d has_lvds %d has_ck505 %d using_ssc_source %d\n",
++ has_panel, has_lvds, has_ck505, using_ssc_source);
+
+ /* Ironlake: try to setup display ref clock before DPLL
+ * enabling. This is only under driver's control after
+@@ -8299,9 +8315,9 @@ static void ironlake_init_pch_refclk(str
+ final |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD;
+ } else
+ final |= DREF_CPU_SOURCE_OUTPUT_DISABLE;
+- } else {
+- final |= DREF_SSC_SOURCE_DISABLE;
+- final |= DREF_CPU_SOURCE_OUTPUT_DISABLE;
++ } else if (using_ssc_source) {
++ final |= DREF_SSC_SOURCE_ENABLE;
++ final |= DREF_SSC1_ENABLE;
+ }
+
+ if (final == val)
+@@ -8347,7 +8363,7 @@ static void ironlake_init_pch_refclk(str
+ POSTING_READ(PCH_DREF_CONTROL);
+ udelay(200);
+ } else {
+- DRM_DEBUG_KMS("Disabling SSC entirely\n");
++ DRM_DEBUG_KMS("Disabling CPU source output\n");
+
+ val &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
+
+@@ -8358,16 +8374,20 @@ static void ironlake_init_pch_refclk(str
+ POSTING_READ(PCH_DREF_CONTROL);
+ udelay(200);
+
+- /* Turn off the SSC source */
+- val &= ~DREF_SSC_SOURCE_MASK;
+- val |= DREF_SSC_SOURCE_DISABLE;
++ if (!using_ssc_source) {
++ DRM_DEBUG_KMS("Disabling SSC source\n");
+
+- /* Turn off SSC1 */
+- val &= ~DREF_SSC1_ENABLE;
++ /* Turn off the SSC source */
++ val &= ~DREF_SSC_SOURCE_MASK;
++ val |= DREF_SSC_SOURCE_DISABLE;
+
+- I915_WRITE(PCH_DREF_CONTROL, val);
+- POSTING_READ(PCH_DREF_CONTROL);
+- udelay(200);
++ /* Turn off SSC1 */
++ val &= ~DREF_SSC1_ENABLE;
++
++ I915_WRITE(PCH_DREF_CONTROL, val);
++ POSTING_READ(PCH_DREF_CONTROL);
++ udelay(200);
++ }
+ }
+
+ BUG_ON(val != final);
--- /dev/null
+From 664a84d2c77cbff2945ed7f96d08afbba42b6293 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com>
+Date: Fri, 13 May 2016 20:53:56 +0300
+Subject: drm/i915: Refresh cached DP port register value on resume
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ville Syrjälä <ville.syrjala@linux.intel.com>
+
+commit 664a84d2c77cbff2945ed7f96d08afbba42b6293 upstream.
+
+During hibernation the cached DP port register value will be left with
+whatever value we have there when we create the hibernation image.
+Currently that means the port (and eDP PLL) will be off in the cached
+value. However when we resume there is no guarantee that the value
+in the actual register will match the cached value. If i915 isn't
+loaded in the kernel that loads the hibernation image, the port may
+well be on (eg. left on by the BIOS). The encoder state readout
+does the right thing in this case and updates our encoder state
+to reflect the actual hardware state. However the post-resume modeset
+will then use the stale cached port register value in
+intel_dp_link_down() and potentially confuse the hardware.
+
+This was caught by the following assert
+ WARNING: CPU: 3 PID: 5288 at ../drivers/gpu/drm/i915/intel_dp.c:2184 assert_edp_pll+0x99/0xa0 [i915]
+ eDP PLL state assertion failure (expected on, current off)
+on account of the eDP PLL getting prematurely turned off when
+shutting down the port, since the DP_PLL_ENABLE bit wasn't set
+in the cached register value.
+
+Presumably I introduced this problem in
+commit 6fec76628333 ("drm/i915: Use intel_dp->DP in eDP PLL setup")
+as before that we didn't update the cached value after shuttting the
+port down. That's assuming the port got enabled at least once prior
+to hibernating. If that didn't happen then the cached value would
+still have been totally out of sync with reality (eg. first boot w/o
+eDP on, then hibernate, and then resume with eDP on).
+
+So, let's fix this properly and refresh the cached register value from
+the hardware register during resume.
+
+DDI platforms shouldn't use the cached value during port disable at
+least, so shouldn't have this particular issue. They might still have
+issues if we skip the initial modeset and then try to retrain the link
+or something. But untangling this DP vs. DDI mess is a bigger topic,
+so let's jut punt on DDI for now.
+
+Cc: Jani Nikula <jani.nikula@intel.com>
+Fixes: 6fec76628333 ("drm/i915: Use intel_dp->DP in eDP PLL setup")
+Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/1463162036-27931-1-git-send-email-ville.syrjala@linux.intel.com
+Reviewed-by: Imre Deak <imre.deak@intel.com>
+(cherry picked from commit 64989ca4b27acb026b6496ec21e43bee66f86a5b)
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/intel_dp.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/drivers/gpu/drm/i915/intel_dp.c
++++ b/drivers/gpu/drm/i915/intel_dp.c
+@@ -4942,13 +4942,15 @@ static void intel_edp_panel_vdd_sanitize
+
+ void intel_dp_encoder_reset(struct drm_encoder *encoder)
+ {
+- struct intel_dp *intel_dp;
++ struct drm_i915_private *dev_priv = to_i915(encoder->dev);
++ struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
++
++ if (!HAS_DDI(dev_priv))
++ intel_dp->DP = I915_READ(intel_dp->output_reg);
+
+ if (to_intel_encoder(encoder)->type != INTEL_OUTPUT_EDP)
+ return;
+
+- intel_dp = enc_to_intel_dp(encoder);
+-
+ pps_lock(intel_dp);
+
+ /*
--- /dev/null
+From b19240062722c39fa92c99f04cbfd93034625123 Mon Sep 17 00:00:00 2001
+From: Chris Wilson <chris@chris-wilson.co.uk>
+Date: Mon, 11 Jul 2016 14:46:17 +0100
+Subject: drm/i915: Update ifdeffery for mutex->owner
+
+From: Chris Wilson <chris@chris-wilson.co.uk>
+
+commit b19240062722c39fa92c99f04cbfd93034625123 upstream.
+
+In commit 7608a43d8f2e ("locking/mutexes: Use MUTEX_SPIN_ON_OWNER when
+appropriate") the owner field in the mutex was updated from being
+dependent upon CONFIG_SMP to using optimistic spin. Update our peek
+function to suite.
+
+Fixes:7608a43d8f2e ("locking/mutexes: Use MUTEX_SPIN_ON_OWNER...")
+Reported-by: Hong Liu <hong.liu@intel.com>
+Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
+Link: http://patchwork.freedesktop.org/patch/msgid/1468244777-4888-1-git-send-email-chris@chris-wilson.co.uk
+Reviewed-by: Matthew Auld <matthew.auld@intel.com>
+(cherry picked from commit 4f074a5393431a7d2cc0de7fcfe2f61d24854628)
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/i915_gem_shrinker.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/i915/i915_gem_shrinker.c
++++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c
+@@ -39,7 +39,7 @@ static bool mutex_is_locked_by(struct mu
+ if (!mutex_is_locked(mutex))
+ return false;
+
+-#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_MUTEXES)
++#if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_MUTEX_SPIN_ON_OWNER)
+ return mutex->owner == task;
+ #else
+ /* Since UP may be pre-empted, we cannot assume that we own the lock */
--- /dev/null
+From 6709887c448d1cff51b52d09763c7b834ea5f0be Mon Sep 17 00:00:00 2001
+From: Tomi Valkeinen <tomi.valkeinen@ti.com>
+Date: Tue, 31 May 2016 15:03:17 +0300
+Subject: drm: make drm_atomic_set_mode_prop_for_crtc() more reliable
+
+From: Tomi Valkeinen <tomi.valkeinen@ti.com>
+
+commit 6709887c448d1cff51b52d09763c7b834ea5f0be upstream.
+
+drm_atomic_set_mode_prop_for_crtc() does not clear the state->mode, so
+old data may be left there when a new mode is set, possibly causing odd
+issues.
+
+This patch improves the situation by always clearing the state->mode
+first.
+
+Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
+Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/drm_atomic.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/drm_atomic.c
++++ b/drivers/gpu/drm/drm_atomic.c
+@@ -354,6 +354,8 @@ int drm_atomic_set_mode_prop_for_crtc(st
+ drm_property_unreference_blob(state->mode_blob);
+ state->mode_blob = NULL;
+
++ memset(&state->mode, 0, sizeof(state->mode));
++
+ if (blob) {
+ if (blob->length != sizeof(struct drm_mode_modeinfo) ||
+ drm_mode_convert_umode(&state->mode,
+@@ -366,7 +368,6 @@ int drm_atomic_set_mode_prop_for_crtc(st
+ DRM_DEBUG_ATOMIC("Set [MODE:%s] for CRTC state %p\n",
+ state->mode.name, state);
+ } else {
+- memset(&state->mode, 0, sizeof(state->mode));
+ state->enable = false;
+ DRM_DEBUG_ATOMIC("Set [NOMODE] for CRTC state %p\n",
+ state);
--- /dev/null
+From bc9139d23f6b038e32bcd2dffdee70a8d76b3976 Mon Sep 17 00:00:00 2001
+From: Ben Skeggs <bskeggs@redhat.com>
+Date: Wed, 25 May 2016 10:56:24 +1000
+Subject: drm/nouveau/bios/disp: fix handling of "match any protocol" entries
+
+From: Ben Skeggs <bskeggs@redhat.com>
+
+commit bc9139d23f6b038e32bcd2dffdee70a8d76b3976 upstream.
+
+As it turns out, a value of 0xff means "any protocol" and not "VGA".
+
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/disp.h | 5 +++--
+ drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c | 13 +++++--------
+ drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c | 12 ++++--------
+ drivers/gpu/drm/nouveau/nvkm/subdev/bios/disp.c | 8 +++++---
+ 4 files changed, 17 insertions(+), 21 deletions(-)
+
+--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/disp.h
++++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/disp.h
+@@ -25,7 +25,8 @@ u16 nvbios_outp_match(struct nvkm_bios *
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_outp *);
+
+ struct nvbios_ocfg {
+- u16 match;
++ u8 proto;
++ u8 flags;
+ u16 clkcmp[2];
+ };
+
+@@ -33,7 +34,7 @@ u16 nvbios_ocfg_entry(struct nvkm_bios *
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+ u16 nvbios_ocfg_parse(struct nvkm_bios *, u16 outp, u8 idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *);
+-u16 nvbios_ocfg_match(struct nvkm_bios *, u16 outp, u16 type,
++u16 nvbios_ocfg_match(struct nvkm_bios *, u16 outp, u8 proto, u8 flags,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *);
+ u16 nvbios_oclk_match(struct nvkm_bios *, u16 cmp, u32 khz);
+ #endif
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c
+@@ -76,6 +76,7 @@ exec_lookup(struct nv50_disp *disp, int
+ mask |= 0x0001 << or;
+ mask |= 0x0100 << head;
+
++
+ list_for_each_entry(outp, &disp->base.outp, head) {
+ if ((outp->info.hasht & 0xff) == type &&
+ (outp->info.hashm & mask) == mask) {
+@@ -155,25 +156,21 @@ exec_clkcmp(struct nv50_disp *disp, int
+ if (!outp)
+ return NULL;
+
++ *conf = (ctrl & 0x00000f00) >> 8;
+ switch (outp->info.type) {
+ case DCB_OUTPUT_TMDS:
+- *conf = (ctrl & 0x00000f00) >> 8;
+ if (*conf == 5)
+ *conf |= 0x0100;
+ break;
+ case DCB_OUTPUT_LVDS:
+- *conf = disp->sor.lvdsconf;
+- break;
+- case DCB_OUTPUT_DP:
+- *conf = (ctrl & 0x00000f00) >> 8;
++ *conf |= disp->sor.lvdsconf;
+ break;
+- case DCB_OUTPUT_ANALOG:
+ default:
+- *conf = 0x00ff;
+ break;
+ }
+
+- data = nvbios_ocfg_match(bios, data, *conf, &ver, &hdr, &cnt, &len, &info2);
++ data = nvbios_ocfg_match(bios, data, *conf & 0xff, *conf >> 8,
++ &ver, &hdr, &cnt, &len, &info2);
+ if (data && id < 0xff) {
+ data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk);
+ if (data) {
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c
+@@ -387,22 +387,17 @@ exec_clkcmp(struct nv50_disp *disp, int
+ if (!outp)
+ return NULL;
+
++ *conf = (ctrl & 0x00000f00) >> 8;
+ if (outp->info.location == 0) {
+ switch (outp->info.type) {
+ case DCB_OUTPUT_TMDS:
+- *conf = (ctrl & 0x00000f00) >> 8;
+ if (*conf == 5)
+ *conf |= 0x0100;
+ break;
+ case DCB_OUTPUT_LVDS:
+- *conf = disp->sor.lvdsconf;
++ *conf |= disp->sor.lvdsconf;
+ break;
+- case DCB_OUTPUT_DP:
+- *conf = (ctrl & 0x00000f00) >> 8;
+- break;
+- case DCB_OUTPUT_ANALOG:
+ default:
+- *conf = 0x00ff;
+ break;
+ }
+ } else {
+@@ -410,7 +405,8 @@ exec_clkcmp(struct nv50_disp *disp, int
+ pclk = pclk / 2;
+ }
+
+- data = nvbios_ocfg_match(bios, data, *conf, &ver, &hdr, &cnt, &len, &info2);
++ data = nvbios_ocfg_match(bios, data, *conf & 0xff, *conf >> 8,
++ &ver, &hdr, &cnt, &len, &info2);
+ if (data && id < 0xff) {
+ data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk);
+ if (data) {
+--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/disp.c
++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/disp.c
+@@ -141,7 +141,8 @@ nvbios_ocfg_parse(struct nvkm_bios *bios
+ {
+ u16 data = nvbios_ocfg_entry(bios, outp, idx, ver, hdr, cnt, len);
+ if (data) {
+- info->match = nvbios_rd16(bios, data + 0x00);
++ info->proto = nvbios_rd08(bios, data + 0x00);
++ info->flags = nvbios_rd16(bios, data + 0x01);
+ info->clkcmp[0] = nvbios_rd16(bios, data + 0x02);
+ info->clkcmp[1] = nvbios_rd16(bios, data + 0x04);
+ }
+@@ -149,12 +150,13 @@ nvbios_ocfg_parse(struct nvkm_bios *bios
+ }
+
+ u16
+-nvbios_ocfg_match(struct nvkm_bios *bios, u16 outp, u16 type,
++nvbios_ocfg_match(struct nvkm_bios *bios, u16 outp, u8 proto, u8 flags,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *info)
+ {
+ u16 data, idx = 0;
+ while ((data = nvbios_ocfg_parse(bios, outp, idx++, ver, hdr, cnt, len, info))) {
+- if (info->match == type)
++ if ((info->proto == proto || info->proto == 0xff) &&
++ (info->flags == flags))
+ break;
+ }
+ return data;
--- /dev/null
+From a8953c52b95167b5d21a66f0859751570271d834 Mon Sep 17 00:00:00 2001
+From: Ben Skeggs <bskeggs@redhat.com>
+Date: Fri, 3 Jun 2016 14:37:40 +1000
+Subject: drm/nouveau/disp/sor/gf119: both links use the same training register
+
+From: Ben Skeggs <bskeggs@redhat.com>
+
+commit a8953c52b95167b5d21a66f0859751570271d834 upstream.
+
+It appears that, for whatever reason, both link A and B use the same
+register to control the training pattern. It's a little odd, as the
+GPUs before this (Tesla/Fermi1) have per-link registers, as do newer
+GPUs (Maxwell).
+
+Fixes the third DP output on NVS 510 (GK107).
+
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c
+@@ -40,8 +40,7 @@ static int
+ gf119_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern)
+ {
+ struct nvkm_device *device = outp->base.disp->engine.subdev.device;
+- const u32 loff = gf119_sor_loff(outp);
+- nvkm_mask(device, 0x61c110 + loff, 0x0f0f0f0f, 0x01010101 * pattern);
++ nvkm_mask(device, 0x61c110, 0x0f0f0f0f, 0x01010101 * pattern);
+ return 0;
+ }
+
--- /dev/null
+From 217215041b9285af2193a755b56a8f3ed408bfe2 Mon Sep 17 00:00:00 2001
+From: Ben Skeggs <bskeggs@redhat.com>
+Date: Wed, 6 Jul 2016 06:50:36 +1000
+Subject: drm/nouveau/disp/sor/gf119: select correct sor when poking training pattern
+
+From: Ben Skeggs <bskeggs@redhat.com>
+
+commit 217215041b9285af2193a755b56a8f3ed408bfe2 upstream.
+
+Fixes a regression caused by a stupid thinko from "disp/sor/gf119: both
+links use the same training register".
+
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c
+@@ -40,7 +40,8 @@ static int
+ gf119_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern)
+ {
+ struct nvkm_device *device = outp->base.disp->engine.subdev.device;
+- nvkm_mask(device, 0x61c110, 0x0f0f0f0f, 0x01010101 * pattern);
++ const u32 soff = gf119_sor_soff(outp);
++ nvkm_mask(device, 0x61c110 + soff, 0x0f0f0f0f, 0x01010101 * pattern);
+ return 0;
+ }
+
--- /dev/null
+From 4691409b3e2250ed66aa8dcefa23fe765daf7add Mon Sep 17 00:00:00 2001
+From: Ben Skeggs <bskeggs@redhat.com>
+Date: Fri, 3 Jun 2016 15:05:52 +1000
+Subject: drm/nouveau/disp/sor/gm107: training pattern registers are like gm200
+
+From: Ben Skeggs <bskeggs@redhat.com>
+
+commit 4691409b3e2250ed66aa8dcefa23fe765daf7add upstream.
+
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild | 1
+ drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c | 2
+ drivers/gpu/drm/nouveau/nvkm/engine/disp/outpdp.h | 9 ++-
+ drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c | 2
+ drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c | 53 ++++++++++++++++++++
+ drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c | 15 -----
+ 6 files changed, 64 insertions(+), 18 deletions(-)
+
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild
+@@ -18,6 +18,7 @@ nvkm-y += nvkm/engine/disp/piornv50.o
+ nvkm-y += nvkm/engine/disp/sornv50.o
+ nvkm-y += nvkm/engine/disp/sorg94.o
+ nvkm-y += nvkm/engine/disp/sorgf119.o
++nvkm-y += nvkm/engine/disp/sorgm107.o
+ nvkm-y += nvkm/engine/disp/sorgm200.o
+ nvkm-y += nvkm/engine/disp/dport.o
+
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c
+@@ -36,7 +36,7 @@ gm107_disp = {
+ .outp.internal.crt = nv50_dac_output_new,
+ .outp.internal.tmds = nv50_sor_output_new,
+ .outp.internal.lvds = nv50_sor_output_new,
+- .outp.internal.dp = gf119_sor_dp_new,
++ .outp.internal.dp = gm107_sor_dp_new,
+ .dac.nr = 3,
+ .dac.power = nv50_dac_power,
+ .dac.sense = nv50_dac_sense,
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outpdp.h
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outpdp.h
+@@ -62,7 +62,12 @@ int g94_sor_dp_lnk_pwr(struct nvkm_outpu
+ int gf119_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *,
+ struct nvkm_output **);
+ int gf119_sor_dp_lnk_ctl(struct nvkm_output_dp *, int, int, bool);
++int gf119_sor_dp_drv_ctl(struct nvkm_output_dp *, int, int, int, int);
+
+-int gm200_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *,
+- struct nvkm_output **);
++int gm107_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *,
++ struct nvkm_output **);
++int gm107_sor_dp_pattern(struct nvkm_output_dp *, int);
++
++int gm200_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *,
++ struct nvkm_output **);
+ #endif
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c
+@@ -63,7 +63,7 @@ gf119_sor_dp_lnk_ctl(struct nvkm_output_
+ return 0;
+ }
+
+-static int
++int
+ gf119_sor_dp_drv_ctl(struct nvkm_output_dp *outp,
+ int ln, int vs, int pe, int pc)
+ {
+--- /dev/null
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c
+@@ -0,0 +1,53 @@
++/*
++ * Copyright 2016 Red Hat Inc.
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining a
++ * copy of this software and associated documentation files (the "Software"),
++ * to deal in the Software without restriction, including without limitation
++ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
++ * and/or sell copies of the Software, and to permit persons to whom the
++ * Software is furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included in
++ * all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
++ * OTHER DEALINGS IN THE SOFTWARE.
++ *
++ * Authors: Ben Skeggs <bskeggs@redhat.com>
++ */
++#include "nv50.h"
++#include "outpdp.h"
++
++int
++gm107_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern)
++{
++ struct nvkm_device *device = outp->base.disp->engine.subdev.device;
++ const u32 soff = outp->base.or * 0x800;
++ const u32 data = 0x01010101 * pattern;
++ if (outp->base.info.sorconf.link & 1)
++ nvkm_mask(device, 0x61c110 + soff, 0x0f0f0f0f, data);
++ else
++ nvkm_mask(device, 0x61c12c + soff, 0x0f0f0f0f, data);
++ return 0;
++}
++
++static const struct nvkm_output_dp_func
++gm107_sor_dp_func = {
++ .pattern = gm107_sor_dp_pattern,
++ .lnk_pwr = g94_sor_dp_lnk_pwr,
++ .lnk_ctl = gf119_sor_dp_lnk_ctl,
++ .drv_ctl = gf119_sor_dp_drv_ctl,
++};
++
++int
++gm107_sor_dp_new(struct nvkm_disp *disp, int index,
++ struct dcb_output *dcbE, struct nvkm_output **poutp)
++{
++ return nvkm_output_dp_new_(&gm107_sor_dp_func, disp, index, dcbE, poutp);
++}
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c
+@@ -57,19 +57,6 @@ gm200_sor_dp_lane_map(struct nvkm_device
+ }
+
+ static int
+-gm200_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern)
+-{
+- struct nvkm_device *device = outp->base.disp->engine.subdev.device;
+- const u32 soff = gm200_sor_soff(outp);
+- const u32 data = 0x01010101 * pattern;
+- if (outp->base.info.sorconf.link & 1)
+- nvkm_mask(device, 0x61c110 + soff, 0x0f0f0f0f, data);
+- else
+- nvkm_mask(device, 0x61c12c + soff, 0x0f0f0f0f, data);
+- return 0;
+-}
+-
+-static int
+ gm200_sor_dp_lnk_pwr(struct nvkm_output_dp *outp, int nr)
+ {
+ struct nvkm_device *device = outp->base.disp->engine.subdev.device;
+@@ -129,7 +116,7 @@ gm200_sor_dp_drv_ctl(struct nvkm_output_
+
+ static const struct nvkm_output_dp_func
+ gm200_sor_dp_func = {
+- .pattern = gm200_sor_dp_pattern,
++ .pattern = gm107_sor_dp_pattern,
+ .lnk_pwr = gm200_sor_dp_lnk_pwr,
+ .lnk_ctl = gf119_sor_dp_lnk_ctl,
+ .drv_ctl = gm200_sor_dp_drv_ctl,
--- /dev/null
+From f045f459d925138fe7d6193a8c86406bda7e49da Mon Sep 17 00:00:00 2001
+From: Ben Skeggs <bskeggs@redhat.com>
+Date: Thu, 2 Jun 2016 12:23:31 +1000
+Subject: drm/nouveau/fbcon: fix out-of-bounds memory accesses
+
+From: Ben Skeggs <bskeggs@redhat.com>
+
+commit f045f459d925138fe7d6193a8c86406bda7e49da upstream.
+
+Reported by KASAN.
+
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/nouveau/nouveau_fbcon.c | 1 +
+ drivers/gpu/drm/nouveau/nv04_fbcon.c | 7 ++-----
+ drivers/gpu/drm/nouveau/nv50_fbcon.c | 6 ++----
+ drivers/gpu/drm/nouveau/nvc0_fbcon.c | 6 ++----
+ 4 files changed, 7 insertions(+), 13 deletions(-)
+
+--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
++++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+@@ -557,6 +557,7 @@ nouveau_fbcon_init(struct drm_device *de
+ if (ret)
+ goto fini;
+
++ fbcon->helper.fbdev->pixmap.buf_align = 4;
+ return 0;
+
+ fini:
+--- a/drivers/gpu/drm/nouveau/nv04_fbcon.c
++++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c
+@@ -82,7 +82,6 @@ nv04_fbcon_imageblit(struct fb_info *inf
+ uint32_t fg;
+ uint32_t bg;
+ uint32_t dsize;
+- uint32_t width;
+ uint32_t *data = (uint32_t *)image->data;
+ int ret;
+
+@@ -93,9 +92,6 @@ nv04_fbcon_imageblit(struct fb_info *inf
+ if (ret)
+ return ret;
+
+- width = ALIGN(image->width, 8);
+- dsize = ALIGN(width * image->height, 32) >> 5;
+-
+ if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
+ info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
+ fg = ((uint32_t *) info->pseudo_palette)[image->fg_color];
+@@ -111,10 +107,11 @@ nv04_fbcon_imageblit(struct fb_info *inf
+ ((image->dx + image->width) & 0xffff));
+ OUT_RING(chan, bg);
+ OUT_RING(chan, fg);
+- OUT_RING(chan, (image->height << 16) | width);
++ OUT_RING(chan, (image->height << 16) | image->width);
+ OUT_RING(chan, (image->height << 16) | image->width);
+ OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff));
+
++ dsize = ALIGN(image->width * image->height, 32) >> 5;
+ while (dsize) {
+ int iter_len = dsize > 128 ? 128 : dsize;
+
+--- a/drivers/gpu/drm/nouveau/nv50_fbcon.c
++++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c
+@@ -95,7 +95,7 @@ nv50_fbcon_imageblit(struct fb_info *inf
+ struct nouveau_fbdev *nfbdev = info->par;
+ struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
+ struct nouveau_channel *chan = drm->channel;
+- uint32_t width, dwords, *data = (uint32_t *)image->data;
++ uint32_t dwords, *data = (uint32_t *)image->data;
+ uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel));
+ uint32_t *palette = info->pseudo_palette;
+ int ret;
+@@ -107,9 +107,6 @@ nv50_fbcon_imageblit(struct fb_info *inf
+ if (ret)
+ return ret;
+
+- width = ALIGN(image->width, 32);
+- dwords = (width * image->height) >> 5;
+-
+ BEGIN_NV04(chan, NvSub2D, 0x0814, 2);
+ if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
+ info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
+@@ -128,6 +125,7 @@ nv50_fbcon_imageblit(struct fb_info *inf
+ OUT_RING(chan, 0);
+ OUT_RING(chan, image->dy);
+
++ dwords = ALIGN(image->width * image->height, 32) >> 5;
+ while (dwords) {
+ int push = dwords > 2047 ? 2047 : dwords;
+
+--- a/drivers/gpu/drm/nouveau/nvc0_fbcon.c
++++ b/drivers/gpu/drm/nouveau/nvc0_fbcon.c
+@@ -95,7 +95,7 @@ nvc0_fbcon_imageblit(struct fb_info *inf
+ struct nouveau_fbdev *nfbdev = info->par;
+ struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
+ struct nouveau_channel *chan = drm->channel;
+- uint32_t width, dwords, *data = (uint32_t *)image->data;
++ uint32_t dwords, *data = (uint32_t *)image->data;
+ uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel));
+ uint32_t *palette = info->pseudo_palette;
+ int ret;
+@@ -107,9 +107,6 @@ nvc0_fbcon_imageblit(struct fb_info *inf
+ if (ret)
+ return ret;
+
+- width = ALIGN(image->width, 32);
+- dwords = (width * image->height) >> 5;
+-
+ BEGIN_NVC0(chan, NvSub2D, 0x0814, 2);
+ if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
+ info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
+@@ -128,6 +125,7 @@ nvc0_fbcon_imageblit(struct fb_info *inf
+ OUT_RING (chan, 0);
+ OUT_RING (chan, image->dy);
+
++ dwords = ALIGN(image->width * image->height, 32) >> 5;
+ while (dwords) {
+ int push = dwords > 2047 ? 2047 : dwords;
+
--- /dev/null
+From 52dfcc5ccfbb6697ac3cac7f7ff1e712760e1216 Mon Sep 17 00:00:00 2001
+From: Dmitrii Tcvetkov <demfloro@demfloro.ru>
+Date: Mon, 20 Jun 2016 13:52:14 +0300
+Subject: drm/nouveau: fix for disabled fbdev emulation
+
+From: Dmitrii Tcvetkov <demfloro@demfloro.ru>
+
+commit 52dfcc5ccfbb6697ac3cac7f7ff1e712760e1216 upstream.
+
+Hello,
+
+after this commit:
+
+commit f045f459d925138fe7d6193a8c86406bda7e49da
+Author: Ben Skeggs <bskeggs@redhat.com>
+Date: Thu Jun 2 12:23:31 2016 +1000
+ drm/nouveau/fbcon: fix out-of-bounds memory accesses
+
+kernel started to oops when loading nouveau module when using GTX 780 Ti
+video adapter. This patch fixes the problem.
+
+Bug report: https://bugzilla.kernel.org/show_bug.cgi?id=120591
+
+Signed-off-by: Dmitrii Tcvetkov <demfloro@demfloro.ru>
+Suggested-by: Ilia Mirkin <imirkin@alum.mit.edu>
+Fixes: f045f459d925 ("nouveau_fbcon_init()")
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/nouveau/nouveau_fbcon.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
++++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+@@ -557,7 +557,8 @@ nouveau_fbcon_init(struct drm_device *de
+ if (ret)
+ goto fini;
+
+- fbcon->helper.fbdev->pixmap.buf_align = 4;
++ if (fbcon->helper.fbdev)
++ fbcon->helper.fbdev->pixmap.buf_align = 4;
+ return 0;
+
+ fini:
--- /dev/null
+From 383d0a419f8e63e3d65e706c3c515fa9505ce364 Mon Sep 17 00:00:00 2001
+From: Ben Skeggs <bskeggs@redhat.com>
+Date: Wed, 1 Jun 2016 16:20:10 +1000
+Subject: drm/nouveau/gr/gf100-: update sm error decoding from gk20a nvgpu headers
+
+From: Ben Skeggs <bskeggs@redhat.com>
+
+commit 383d0a419f8e63e3d65e706c3c515fa9505ce364 upstream.
+
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 37 ++++++++++++++++++-------
+ 1 file changed, 28 insertions(+), 9 deletions(-)
+
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
+@@ -942,22 +942,41 @@ gf100_gr_trap_gpc_rop(struct gf100_gr *g
+ }
+
+ static const struct nvkm_enum gf100_mp_warp_error[] = {
+- { 0x00, "NO_ERROR" },
+- { 0x01, "STACK_MISMATCH" },
++ { 0x01, "STACK_ERROR" },
++ { 0x02, "API_STACK_ERROR" },
++ { 0x03, "RET_EMPTY_STACK_ERROR" },
++ { 0x04, "PC_WRAP" },
+ { 0x05, "MISALIGNED_PC" },
+- { 0x08, "MISALIGNED_GPR" },
+- { 0x09, "INVALID_OPCODE" },
+- { 0x0d, "GPR_OUT_OF_BOUNDS" },
+- { 0x0e, "MEM_OUT_OF_BOUNDS" },
+- { 0x0f, "UNALIGNED_MEM_ACCESS" },
++ { 0x06, "PC_OVERFLOW" },
++ { 0x07, "MISALIGNED_IMMC_ADDR" },
++ { 0x08, "MISALIGNED_REG" },
++ { 0x09, "ILLEGAL_INSTR_ENCODING" },
++ { 0x0a, "ILLEGAL_SPH_INSTR_COMBO" },
++ { 0x0b, "ILLEGAL_INSTR_PARAM" },
++ { 0x0c, "INVALID_CONST_ADDR" },
++ { 0x0d, "OOR_REG" },
++ { 0x0e, "OOR_ADDR" },
++ { 0x0f, "MISALIGNED_ADDR" },
+ { 0x10, "INVALID_ADDR_SPACE" },
+- { 0x11, "INVALID_PARAM" },
++ { 0x11, "ILLEGAL_INSTR_PARAM2" },
++ { 0x12, "INVALID_CONST_ADDR_LDC" },
++ { 0x13, "GEOMETRY_SM_ERROR" },
++ { 0x14, "DIVERGENT" },
++ { 0x15, "WARP_EXIT" },
+ {}
+ };
+
+ static const struct nvkm_bitfield gf100_mp_global_error[] = {
++ { 0x00000001, "SM_TO_SM_FAULT" },
++ { 0x00000002, "L1_ERROR" },
+ { 0x00000004, "MULTIPLE_WARP_ERRORS" },
+- { 0x00000008, "OUT_OF_STACK_SPACE" },
++ { 0x00000008, "PHYSICAL_STACK_OVERFLOW" },
++ { 0x00000010, "BPT_INT" },
++ { 0x00000020, "BPT_PAUSE" },
++ { 0x00000040, "SINGLE_STEP_COMPLETE" },
++ { 0x20000000, "ECC_SEC_ERROR" },
++ { 0x40000000, "ECC_DED_ERROR" },
++ { 0x80000000, "TIMEOUT" },
+ {}
+ };
+
--- /dev/null
+From 9057c8d75018f05bbc769d7b4602de3b8b20f8aa Mon Sep 17 00:00:00 2001
+From: Ben Skeggs <bskeggs@redhat.com>
+Date: Fri, 27 May 2016 12:01:27 +1000
+Subject: drm/nouveau/ltc/gm107-: fix typo in the address of NV_PLTCG_LTC0_LTS0_INTR
+
+From: Ben Skeggs <bskeggs@redhat.com>
+
+commit 9057c8d75018f05bbc769d7b4602de3b8b20f8aa upstream.
+
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm107.c | 6 +++---
+ drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm200.c | 2 +-
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm107.c
++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm107.c
+@@ -69,11 +69,11 @@ gm107_ltc_zbc_clear_depth(struct nvkm_lt
+ }
+
+ static void
+-gm107_ltc_lts_isr(struct nvkm_ltc *ltc, int c, int s)
++gm107_ltc_intr_lts(struct nvkm_ltc *ltc, int c, int s)
+ {
+ struct nvkm_subdev *subdev = <c->subdev;
+ struct nvkm_device *device = subdev->device;
+- u32 base = 0x140000 + (c * 0x2000) + (s * 0x200);
++ u32 base = 0x140400 + (c * 0x2000) + (s * 0x200);
+ u32 stat = nvkm_rd32(device, base + 0x00c);
+
+ if (stat) {
+@@ -92,7 +92,7 @@ gm107_ltc_intr(struct nvkm_ltc *ltc)
+ while (mask) {
+ u32 s, c = __ffs(mask);
+ for (s = 0; s < ltc->lts_nr; s++)
+- gm107_ltc_lts_isr(ltc, c, s);
++ gm107_ltc_intr_lts(ltc, c, s);
+ mask &= ~(1 << c);
+ }
+ }
+--- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm200.c
++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm200.c
+@@ -46,7 +46,7 @@ static const struct nvkm_ltc_func
+ gm200_ltc = {
+ .oneinit = gm200_ltc_oneinit,
+ .init = gm200_ltc_init,
+- .intr = gm107_ltc_intr, /*XXX: not validated */
++ .intr = gm107_ltc_intr,
+ .cbc_clear = gm107_ltc_cbc_clear,
+ .cbc_wait = gm107_ltc_cbc_wait,
+ .zbc = 16,
--- /dev/null
+From 05082b8bbd1a0ffc74235449c4b8930a8c240f85 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Mon, 13 Jun 2016 15:37:34 -0400
+Subject: drm/radeon: fix asic initialization for virtualized environments
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit 05082b8bbd1a0ffc74235449c4b8930a8c240f85 upstream.
+
+When executing in a PCI passthrough based virtuzliation environment, the
+hypervisor will usually attempt to send a PCIe bus reset signal to the
+ASIC when the VM reboots. In this scenario, the card is not correctly
+initialized, but we still consider it to be posted. Therefore, in a
+passthrough based environemnt we should always post the card to guarantee
+it is in a good state for driver initialization.
+
+Ported from amdgpu commit:
+amdgpu: fix asic initialization for virtualized environments
+
+Cc: Andres Rodriguez <andres.rodriguez@amd.com>
+Cc: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/radeon_device.c | 21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+--- a/drivers/gpu/drm/radeon/radeon_device.c
++++ b/drivers/gpu/drm/radeon/radeon_device.c
+@@ -630,6 +630,23 @@ void radeon_gtt_location(struct radeon_d
+ /*
+ * GPU helpers function.
+ */
++
++/**
++ * radeon_device_is_virtual - check if we are running is a virtual environment
++ *
++ * Check if the asic has been passed through to a VM (all asics).
++ * Used at driver startup.
++ * Returns true if virtual or false if not.
++ */
++static bool radeon_device_is_virtual(void)
++{
++#ifdef CONFIG_X86
++ return boot_cpu_has(X86_FEATURE_HYPERVISOR);
++#else
++ return false;
++#endif
++}
++
+ /**
+ * radeon_card_posted - check if the hw has already been initialized
+ *
+@@ -643,6 +660,10 @@ bool radeon_card_posted(struct radeon_de
+ {
+ uint32_t reg;
+
++ /* for pass through, always force asic_init */
++ if (radeon_device_is_virtual())
++ return false;
++
+ /* required for EFI mode on macbook2,1 which uses an r5xx asic */
+ if (efi_enabled(EFI_BOOT) &&
+ (rdev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE) &&
--- /dev/null
+From 94477bff390aa4612d2332c8abafaae0a13d6923 Mon Sep 17 00:00:00 2001
+From: Sinclair Yeh <syeh@vmware.com>
+Date: Wed, 29 Jun 2016 12:58:49 -0700
+Subject: drm/ttm: Make ttm_bo_mem_compat available
+
+From: Sinclair Yeh <syeh@vmware.com>
+
+commit 94477bff390aa4612d2332c8abafaae0a13d6923 upstream.
+
+There are cases where it is desired to see if a proposed placement
+is compatible with a buffer object before calling ttm_bo_validate().
+
+Signed-off-by: Sinclair Yeh <syeh@vmware.com>
+Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/ttm/ttm_bo.c | 7 ++++---
+ include/drm/ttm/ttm_bo_api.h | 14 ++++++++++++++
+ 2 files changed, 18 insertions(+), 3 deletions(-)
+
+--- a/drivers/gpu/drm/ttm/ttm_bo.c
++++ b/drivers/gpu/drm/ttm/ttm_bo.c
+@@ -1016,9 +1016,9 @@ out_unlock:
+ return ret;
+ }
+
+-static bool ttm_bo_mem_compat(struct ttm_placement *placement,
+- struct ttm_mem_reg *mem,
+- uint32_t *new_flags)
++bool ttm_bo_mem_compat(struct ttm_placement *placement,
++ struct ttm_mem_reg *mem,
++ uint32_t *new_flags)
+ {
+ int i;
+
+@@ -1050,6 +1050,7 @@ static bool ttm_bo_mem_compat(struct ttm
+
+ return false;
+ }
++EXPORT_SYMBOL(ttm_bo_mem_compat);
+
+ int ttm_bo_validate(struct ttm_buffer_object *bo,
+ struct ttm_placement *placement,
+--- a/include/drm/ttm/ttm_bo_api.h
++++ b/include/drm/ttm/ttm_bo_api.h
+@@ -316,6 +316,20 @@ ttm_bo_reference(struct ttm_buffer_objec
+ */
+ extern int ttm_bo_wait(struct ttm_buffer_object *bo, bool lazy,
+ bool interruptible, bool no_wait);
++
++/**
++ * ttm_bo_mem_compat - Check if proposed placement is compatible with a bo
++ *
++ * @placement: Return immediately if buffer is busy.
++ * @mem: The struct ttm_mem_reg indicating the region where the bo resides
++ * @new_flags: Describes compatible placement found
++ *
++ * Returns true if the placement is compatible
++ */
++extern bool ttm_bo_mem_compat(struct ttm_placement *placement,
++ struct ttm_mem_reg *mem,
++ uint32_t *new_flags);
++
+ /**
+ * ttm_bo_validate
+ *
--- /dev/null
+From 04319d89fbec72dfd60738003c3813b97c1d5f5a Mon Sep 17 00:00:00 2001
+From: Sinclair Yeh <syeh@vmware.com>
+Date: Wed, 29 Jun 2016 12:15:48 -0700
+Subject: drm/vmwgfx: Add an option to change assumed FB bpp
+
+From: Sinclair Yeh <syeh@vmware.com>
+
+commit 04319d89fbec72dfd60738003c3813b97c1d5f5a upstream.
+
+Offer an option for advanced users who want larger modes at 16bpp.
+
+This becomes necessary after the fix: "Work around mode set
+failure in 2D VMs." Without this patch, there would be no way
+for existing advanced users to get to a high res mode, and the
+regression is they will likely get a black screen after a software
+update on their current VM.
+
+Signed-off-by: Sinclair Yeh <syeh@vmware.com>
+Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 5 +++++
+ drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 1 +
+ drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 3 +++
+ 3 files changed, 9 insertions(+)
+
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+@@ -227,6 +227,7 @@ static int vmw_force_iommu;
+ static int vmw_restrict_iommu;
+ static int vmw_force_coherent;
+ static int vmw_restrict_dma_mask;
++static int vmw_assume_16bpp;
+
+ static int vmw_probe(struct pci_dev *, const struct pci_device_id *);
+ static void vmw_master_init(struct vmw_master *);
+@@ -243,6 +244,8 @@ MODULE_PARM_DESC(force_coherent, "Force
+ module_param_named(force_coherent, vmw_force_coherent, int, 0600);
+ MODULE_PARM_DESC(restrict_dma_mask, "Restrict DMA mask to 44 bits with IOMMU");
+ module_param_named(restrict_dma_mask, vmw_restrict_dma_mask, int, 0600);
++MODULE_PARM_DESC(assume_16bpp, "Assume 16-bpp when filtering modes");
++module_param_named(assume_16bpp, vmw_assume_16bpp, int, 0600);
+
+
+ static void vmw_print_capabilities(uint32_t capabilities)
+@@ -653,6 +656,8 @@ static int vmw_driver_load(struct drm_de
+ dev_priv->vram_start = pci_resource_start(dev->pdev, 1);
+ dev_priv->mmio_start = pci_resource_start(dev->pdev, 2);
+
++ dev_priv->assume_16bpp = !!vmw_assume_16bpp;
++
+ dev_priv->enable_fb = enable_fbdev;
+
+ vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2);
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+@@ -386,6 +386,7 @@ struct vmw_private {
+ spinlock_t hw_lock;
+ spinlock_t cap_lock;
+ bool has_dx;
++ bool assume_16bpp;
+
+ /*
+ * VGA registers.
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+@@ -1562,6 +1562,9 @@ int vmw_du_connector_fill_modes(struct d
+ if (dev_priv->active_display_unit == vmw_du_screen_object)
+ assumed_bpp = 4;
+
++ if (dev_priv->assume_16bpp)
++ assumed_bpp = 2;
++
+ if (dev_priv->active_display_unit == vmw_du_screen_target) {
+ max_width = min(max_width, dev_priv->stdu_max_width);
+ max_height = min(max_height, dev_priv->stdu_max_height);
--- /dev/null
+From 4ed7e2242b637bc4af0416e4aa9f945db30fb44a Mon Sep 17 00:00:00 2001
+From: Sinclair Yeh <syeh@vmware.com>
+Date: Wed, 29 Jun 2016 13:20:26 -0700
+Subject: drm/vmwgfx: Check pin count before attempting to move a buffer
+
+From: Sinclair Yeh <syeh@vmware.com>
+
+commit 4ed7e2242b637bc4af0416e4aa9f945db30fb44a upstream.
+
+In certain scenarios, e.g. when fbdev is enabled, we can get into
+a situation where a vmw_framebuffer_pin() is called on a buffer
+that is already pinned.
+
+When this happens, ttm_bo_validate() will unintentially remove the
+TTM_PL_FLAG_NO_EVICT flag, thus unpinning it, and leaving no way
+to actually pin the buffer again.
+
+To prevent this, if a buffer is already pinned, then instead of
+calling ttm_bo_validate(), just make sure the proposed placement is
+compatible with the existing placement.
+
+Signed-off-by: Sinclair Yeh <syeh@vmware.com>
+Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c | 25 ++++++++++++++++++++++---
+ 1 file changed, 22 insertions(+), 3 deletions(-)
+
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c
+@@ -49,6 +49,7 @@ int vmw_dmabuf_pin_in_placement(struct v
+ {
+ struct ttm_buffer_object *bo = &buf->base;
+ int ret;
++ uint32_t new_flags;
+
+ ret = ttm_write_lock(&dev_priv->reservation_sem, interruptible);
+ if (unlikely(ret != 0))
+@@ -60,7 +61,12 @@ int vmw_dmabuf_pin_in_placement(struct v
+ if (unlikely(ret != 0))
+ goto err;
+
+- ret = ttm_bo_validate(bo, placement, interruptible, false);
++ if (buf->pin_count > 0)
++ ret = ttm_bo_mem_compat(placement, &bo->mem,
++ &new_flags) == true ? 0 : -EINVAL;
++ else
++ ret = ttm_bo_validate(bo, placement, interruptible, false);
++
+ if (!ret)
+ vmw_bo_pin_reserved(buf, true);
+
+@@ -91,6 +97,7 @@ int vmw_dmabuf_pin_in_vram_or_gmr(struct
+ {
+ struct ttm_buffer_object *bo = &buf->base;
+ int ret;
++ uint32_t new_flags;
+
+ ret = ttm_write_lock(&dev_priv->reservation_sem, interruptible);
+ if (unlikely(ret != 0))
+@@ -102,6 +109,12 @@ int vmw_dmabuf_pin_in_vram_or_gmr(struct
+ if (unlikely(ret != 0))
+ goto err;
+
++ if (buf->pin_count > 0) {
++ ret = ttm_bo_mem_compat(&vmw_vram_gmr_placement, &bo->mem,
++ &new_flags) == true ? 0 : -EINVAL;
++ goto out_unreserve;
++ }
++
+ ret = ttm_bo_validate(bo, &vmw_vram_gmr_placement, interruptible,
+ false);
+ if (likely(ret == 0) || ret == -ERESTARTSYS)
+@@ -161,6 +174,7 @@ int vmw_dmabuf_pin_in_start_of_vram(stru
+ struct ttm_placement placement;
+ struct ttm_place place;
+ int ret = 0;
++ uint32_t new_flags;
+
+ place = vmw_vram_placement.placement[0];
+ place.lpfn = bo->num_pages;
+@@ -185,10 +199,15 @@ int vmw_dmabuf_pin_in_start_of_vram(stru
+ */
+ if (bo->mem.mem_type == TTM_PL_VRAM &&
+ bo->mem.start < bo->num_pages &&
+- bo->mem.start > 0)
++ bo->mem.start > 0 &&
++ buf->pin_count == 0)
+ (void) ttm_bo_validate(bo, &vmw_sys_placement, false, false);
+
+- ret = ttm_bo_validate(bo, &placement, interruptible, false);
++ if (buf->pin_count > 0)
++ ret = ttm_bo_mem_compat(&placement, &bo->mem,
++ &new_flags) == true ? 0 : -EINVAL;
++ else
++ ret = ttm_bo_validate(bo, &placement, interruptible, false);
+
+ /* For some reason we didn't end up at the start of vram */
+ WARN_ON(ret == 0 && bo->offset != 0);
--- /dev/null
+From d5f1a291e32309324a8c481ed84b5c118d1360ea Mon Sep 17 00:00:00 2001
+From: Sinclair Yeh <syeh@vmware.com>
+Date: Wed, 29 Jun 2016 13:23:18 -0700
+Subject: drm/vmwgfx: Delay pinning fbdev framebuffer until after mode set
+
+From: Sinclair Yeh <syeh@vmware.com>
+
+commit d5f1a291e32309324a8c481ed84b5c118d1360ea upstream.
+
+For the Screen Object display unit, we need to reserve a
+guest-invisible region equal to the size of the framebuffer for
+the host. This region can only be reserved in VRAM, whereas
+the guest-visible framebuffer can be reserved in either VRAM or
+GMR.
+
+As such priority should be given to the guest-invisible
+region otherwise in a limited VRAM situation, we can fail to
+allocate this region.
+
+This patch makes it so that vmw_sou_backing_alloc() is called
+before the framebuffer is pinned.
+
+Signed-off-by: Sinclair Yeh <syeh@vmware.com>
+Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 47 +++++++++++++++++++------------------
+ 1 file changed, 25 insertions(+), 22 deletions(-)
+
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
+@@ -517,28 +517,6 @@ static int vmw_fb_kms_framebuffer(struct
+
+ par->set_fb = &vfb->base;
+
+- if (!par->bo_ptr) {
+- /*
+- * Pin before mapping. Since we don't know in what placement
+- * to pin, call into KMS to do it for us.
+- */
+- ret = vfb->pin(vfb);
+- if (ret) {
+- DRM_ERROR("Could not pin the fbdev framebuffer.\n");
+- return ret;
+- }
+-
+- ret = ttm_bo_kmap(&par->vmw_bo->base, 0,
+- par->vmw_bo->base.num_pages, &par->map);
+- if (ret) {
+- vfb->unpin(vfb);
+- DRM_ERROR("Could not map the fbdev framebuffer.\n");
+- return ret;
+- }
+-
+- par->bo_ptr = ttm_kmap_obj_virtual(&par->map, &par->bo_iowrite);
+- }
+-
+ return 0;
+ }
+
+@@ -601,6 +579,31 @@ static int vmw_fb_set_par(struct fb_info
+ if (ret)
+ goto out_unlock;
+
++ if (!par->bo_ptr) {
++ struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(set.fb);
++
++ /*
++ * Pin before mapping. Since we don't know in what placement
++ * to pin, call into KMS to do it for us.
++ */
++ ret = vfb->pin(vfb);
++ if (ret) {
++ DRM_ERROR("Could not pin the fbdev framebuffer.\n");
++ return ret;
++ }
++
++ ret = ttm_bo_kmap(&par->vmw_bo->base, 0,
++ par->vmw_bo->base.num_pages, &par->map);
++ if (ret) {
++ vfb->unpin(vfb);
++ DRM_ERROR("Could not map the fbdev framebuffer.\n");
++ return ret;
++ }
++
++ par->bo_ptr = ttm_kmap_obj_virtual(&par->map, &par->bo_iowrite);
++ }
++
++
+ vmw_fb_dirty_mark(par, par->fb_x, par->fb_y,
+ par->set_fb->width, par->set_fb->height);
+
--- /dev/null
+From beca4cf55323147ca9c8a98de1871be6e4fe8f34 Mon Sep 17 00:00:00 2001
+From: Thomas Hellstrom <thellstrom@vmware.com>
+Date: Wed, 29 Jun 2016 13:37:35 -0700
+Subject: drm/vmwgfx: Fix corner case screen target management
+
+From: Thomas Hellstrom <thellstrom@vmware.com>
+
+commit beca4cf55323147ca9c8a98de1871be6e4fe8f34 upstream.
+
+When the surface backing a framebuffer doesn't match the framebuffer's
+dimensions, the screen target code would test the framebuffer dimensions
+rather than the surface dimensions when deciding whether to bind the
+surface as a screen target directly. This causes a screen target -
+surface dimension mismatch and a subsequent device error.
+
+Fix this by testing against the surface dimension.
+
+v2: Fix review comments by Sinclair Yeh.
+
+Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
+Reviewed-by: Sinclair Yeh <syeh@vmware.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
+@@ -399,8 +399,10 @@ static int vmw_stdu_bind_fb(struct vmw_p
+
+ WARN_ON_ONCE(!stdu->defined);
+
+- if (!vfb->dmabuf && new_fb->width == mode->hdisplay &&
+- new_fb->height == mode->vdisplay)
++ new_vfbs = (vfb->dmabuf) ? NULL : vmw_framebuffer_to_vfbs(new_fb);
++
++ if (new_vfbs && new_vfbs->surface->base_size.width == mode->hdisplay &&
++ new_vfbs->surface->base_size.height == mode->vdisplay)
+ new_content_type = SAME_AS_DISPLAY;
+ else if (vfb->dmabuf)
+ new_content_type = SEPARATE_DMA;
+@@ -444,7 +446,6 @@ static int vmw_stdu_bind_fb(struct vmw_p
+ content_srf.mip_levels[0] = 1;
+ content_srf.multisample_count = 0;
+ } else {
+- new_vfbs = vmw_framebuffer_to_vfbs(new_fb);
+ content_srf = *new_vfbs->surface;
+ }
+
+@@ -464,7 +465,6 @@ static int vmw_stdu_bind_fb(struct vmw_p
+ return ret;
+ }
+ } else if (new_content_type == SAME_AS_DISPLAY) {
+- new_vfbs = vmw_framebuffer_to_vfbs(new_fb);
+ new_display_srf = vmw_surface_reference(new_vfbs->surface);
+ }
+
--- /dev/null
+From 58541f7a6458e17ab417321b284f0090f530aa91 Mon Sep 17 00:00:00 2001
+From: Sinclair Yeh <syeh@vmware.com>
+Date: Thu, 7 Jul 2016 11:01:30 -0700
+Subject: drm/vmwgfx: Fix error paths when mapping framebuffer
+
+From: Sinclair Yeh <syeh@vmware.com>
+
+commit 58541f7a6458e17ab417321b284f0090f530aa91 upstream.
+
+Rather than returning immediately, make sure to unlock the
+mutexes first.
+
+Signed-off-by: Sinclair Yeh <syeh@vmware.com>
+Reviewed-by: Charmaine Lee <charmainel@vmware.com>
+Reported-by: Emil Velikov <emil.l.velikov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
+@@ -589,7 +589,7 @@ static int vmw_fb_set_par(struct fb_info
+ ret = vfb->pin(vfb);
+ if (ret) {
+ DRM_ERROR("Could not pin the fbdev framebuffer.\n");
+- return ret;
++ goto out_unlock;
+ }
+
+ ret = ttm_bo_kmap(&par->vmw_bo->base, 0,
+@@ -597,7 +597,7 @@ static int vmw_fb_set_par(struct fb_info
+ if (ret) {
+ vfb->unpin(vfb);
+ DRM_ERROR("Could not map the fbdev framebuffer.\n");
+- return ret;
++ goto out_unlock;
+ }
+
+ par->bo_ptr = ttm_kmap_obj_virtual(&par->map, &par->bo_iowrite);
--- /dev/null
+From 7c20d213dd3cd6295bf9162730e7a368af957854 Mon Sep 17 00:00:00 2001
+From: Sinclair Yeh <syeh@vmware.com>
+Date: Wed, 29 Jun 2016 11:29:47 -0700
+Subject: drm/vmwgfx: Work around mode set failure in 2D VMs
+
+From: Sinclair Yeh <syeh@vmware.com>
+
+commit 7c20d213dd3cd6295bf9162730e7a368af957854 upstream.
+
+In a low-memory 2D VM, fbdev can take up a large percentage of
+available memory, making them unavailable for other DRM clients.
+
+Since we do not take fbdev into account when filtering modes,
+we end up claiming to support more modes than we actually do.
+
+As a result, users get a black screen when setting a mode too
+large for current available memory. In a low-memory VM
+configuration, users can get a black screen for a mode as low
+as 1024x768.
+
+The current mode filtering mechanism keys off of
+SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB, i.e. the maximum amount
+of surface memory we have. Since this value is a performance
+suggestion, not a hard limit, and since there should not be much
+of a performance impact for a 2D VM, rather than filtering out
+more modes, we will just allow ourselves to exceed the SVGA's
+performance suggestion.
+
+Also changed assumed bpp to 32 from 16 to make sure we can
+actually support all the modes listed.
+
+Signed-off-by: Sinclair Yeh <syeh@vmware.com>
+Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 7 +++++++
+ drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 9 +--------
+ 2 files changed, 8 insertions(+), 8 deletions(-)
+
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+@@ -704,6 +704,13 @@ static int vmw_driver_load(struct drm_de
+ vmw_read(dev_priv,
+ SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB);
+
++ /*
++ * Workaround for low memory 2D VMs to compensate for the
++ * allocation taken by fbdev
++ */
++ if (!(dev_priv->capabilities & SVGA_CAP_3D))
++ mem_size *= 2;
++
+ dev_priv->max_mob_pages = mem_size * 1024 / PAGE_SIZE;
+ dev_priv->prim_bb_mem =
+ vmw_read(dev_priv,
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+@@ -1553,14 +1553,7 @@ int vmw_du_connector_fill_modes(struct d
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC)
+ };
+ int i;
+- u32 assumed_bpp = 2;
+-
+- /*
+- * If using screen objects, then assume 32-bpp because that's what the
+- * SVGA device is assuming
+- */
+- if (dev_priv->active_display_unit == vmw_du_screen_object)
+- assumed_bpp = 4;
++ u32 assumed_bpp = 4;
+
+ if (dev_priv->assume_16bpp)
+ assumed_bpp = 2;
--- /dev/null
+From afe705be38f1e65b173868486944377186b9f206 Mon Sep 17 00:00:00 2001
+From: Chris Wilson <chris@chris-wilson.co.uk>
+Date: Tue, 31 May 2016 22:25:52 +0100
+Subject: drm: Wrap direct calls to driver->gem_free_object from CMA
+
+From: Chris Wilson <chris@chris-wilson.co.uk>
+
+commit afe705be38f1e65b173868486944377186b9f206 upstream.
+
+Since the introduction of (struct_mutex) lockless GEM bo freeing, there
+are a pair of driver vfuncs for freeing the GEM bo, of which the driver
+may choose to only implement driver->gem_object_free_unlocked (and so
+avoid taking the struct_mutex along the free path). However, the CMA GEM
+helpers were still calling driver->gem_free_object directly, now NULL,
+and promptly dying on the fancy new lockless drivers. Oops.
+
+Robert Foss bisected this to b82caafcf2303 (drm/vc4: Use lockless gem BO
+free callback) on his vc4 device, but that just serves as an enabler for
+9f0ba539d13ae (drm/gem: support BO freeing without dev->struct_mutex).
+
+Reported-by: Robert Foss <robert.foss@collabora.com>
+Fixes: 9f0ba539d13ae (drm/gem: support BO freeing without dev->struct_mutex)
+Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
+Cc: Robert Foss <robert.foss@collabora.com>
+Cc: Daniel Vetter <daniel.vetter@intel.com>
+Cc: Eric Anholt <eric@anholt.net>
+Cc: Alex Deucher <alexdeucher@gmail.com>
+Cc: Lucas Stach <l.stach@pengutronix.de>
+Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Tested-by: Robert Foss <robert.foss@collabora.com>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/drm_fb_cma_helper.c | 2 +-
+ drivers/gpu/drm/drm_gem_cma_helper.c | 12 +++---------
+ 2 files changed, 4 insertions(+), 10 deletions(-)
+
+--- a/drivers/gpu/drm/drm_fb_cma_helper.c
++++ b/drivers/gpu/drm/drm_fb_cma_helper.c
+@@ -301,7 +301,7 @@ static int drm_fbdev_cma_create(struct d
+ err_fb_info_destroy:
+ drm_fb_helper_release_fbi(helper);
+ err_gem_free_object:
+- dev->driver->gem_free_object(&obj->base);
++ drm_gem_object_unreference_unlocked(&obj->base);
+ return ret;
+ }
+
+--- a/drivers/gpu/drm/drm_gem_cma_helper.c
++++ b/drivers/gpu/drm/drm_gem_cma_helper.c
+@@ -121,7 +121,7 @@ struct drm_gem_cma_object *drm_gem_cma_c
+ return cma_obj;
+
+ error:
+- drm->driver->gem_free_object(&cma_obj->base);
++ drm_gem_object_unreference_unlocked(&cma_obj->base);
+ return ERR_PTR(ret);
+ }
+ EXPORT_SYMBOL_GPL(drm_gem_cma_create);
+@@ -162,18 +162,12 @@ drm_gem_cma_create_with_handle(struct dr
+ * and handle has the id what user can see.
+ */
+ ret = drm_gem_handle_create(file_priv, gem_obj, handle);
+- if (ret)
+- goto err_handle_create;
+-
+ /* drop reference from allocate - handle holds it now. */
+ drm_gem_object_unreference_unlocked(gem_obj);
++ if (ret)
++ return ERR_PTR(ret);
+
+ return cma_obj;
+-
+-err_handle_create:
+- drm->driver->gem_free_object(gem_obj);
+-
+- return ERR_PTR(ret);
+ }
+
+ /**
--- /dev/null
+From 8f50b8e57442d28e41bb736c173d8a2490549a82 Mon Sep 17 00:00:00 2001
+From: "Ocquidant, Sebastien" <sebastienocquidant@eaton.com>
+Date: Wed, 15 Jun 2016 13:47:35 +0200
+Subject: memory: omap-gpmc: Fix omap gpmc EXTRADELAY timing
+
+From: Ocquidant, Sebastien <sebastienocquidant@eaton.com>
+
+commit 8f50b8e57442d28e41bb736c173d8a2490549a82 upstream.
+
+In the omap gpmc driver it can be noticed that GPMC_CONFIG4_OEEXTRADELAY
+is overwritten by the WEEXTRADELAY value from the device tree and
+GPMC_CONFIG4_WEEXTRADELAY is not updated by the value from the device
+tree.
+
+As a consequence, the memory accesses cannot be configured properly when
+the extra delay are needed for OE and WE.
+
+Fix the update of GPMC_CONFIG4_WEEXTRADELAY with the value from the
+device tree file and prevents GPMC_CONFIG4_OEXTRADELAY
+being overwritten by the WEXTRADELAY value from the device tree.
+
+Signed-off-by: Ocquidant, Sebastien <sebastienocquidant@eaton.com>
+Signed-off-by: Roger Quadros <rogerq@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/memory/omap-gpmc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/memory/omap-gpmc.c
++++ b/drivers/memory/omap-gpmc.c
+@@ -394,7 +394,7 @@ static void gpmc_cs_bool_timings(int cs,
+ gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4,
+ GPMC_CONFIG4_OEEXTRADELAY, p->oe_extra_delay);
+ gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4,
+- GPMC_CONFIG4_OEEXTRADELAY, p->we_extra_delay);
++ GPMC_CONFIG4_WEEXTRADELAY, p->we_extra_delay);
+ gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG6,
+ GPMC_CONFIG6_CYCLE2CYCLESAMECSEN,
+ p->cycle2cyclesamecsen);
--- /dev/null
+From ef0dab4aae14e25efddf1577736f8450132800c5 Mon Sep 17 00:00:00 2001
+From: David Miller <davem@davemloft.net>
+Date: Sat, 18 Jun 2016 23:52:25 -0700
+Subject: PCI: Fix unaligned accesses in VC code
+
+From: David Miller <davem@davemloft.net>
+
+commit ef0dab4aae14e25efddf1577736f8450132800c5 upstream.
+
+The save/restore buffers for VC state is first composed of a 2-byte control
+register, then a bunch of 4-byte words.
+
+This causes unaligned accesses which trap on platform such as sparc.
+
+This is easy to fix by simply moving the buffer pointer forward by 4 bytes
+instead of 2 after dealing with the control register. The length
+adjustment needs to be changed likewise as well.
+
+Fixes: 5f8fc43217a0 ("PCI: Include pci/pcie/Kconfig directly from pci/Kconfig")
+Reported-by: Meelis Roos <mroos@linux.ee>
+Reported-by: Anatoly Pugachev <matorola@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/vc.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/pci/vc.c
++++ b/drivers/pci/vc.c
+@@ -221,9 +221,9 @@ static int pci_vc_do_save_buffer(struct
+ else
+ pci_write_config_word(dev, pos + PCI_VC_PORT_CTRL,
+ *(u16 *)buf);
+- buf += 2;
++ buf += 4;
+ }
+- len += 2;
++ len += 4;
+
+ /*
+ * If we have any Low Priority VCs and a VC Arbitration Table Offset
--- /dev/null
+From 4f996e234dad488e5d9ba0858bc1bae12eff82c3 Mon Sep 17 00:00:00 2001
+From: Tejun Heo <tj@kernel.org>
+Date: Wed, 25 May 2016 11:48:25 -0400
+Subject: percpu: fix synchronization between chunk->map_extend_work and chunk destruction
+
+From: Tejun Heo <tj@kernel.org>
+
+commit 4f996e234dad488e5d9ba0858bc1bae12eff82c3 upstream.
+
+Atomic allocations can trigger async map extensions which is serviced
+by chunk->map_extend_work. pcpu_balance_work which is responsible for
+destroying idle chunks wasn't synchronizing properly against
+chunk->map_extend_work and may end up freeing the chunk while the work
+item is still in flight.
+
+This patch fixes the bug by rolling async map extension operations
+into pcpu_balance_work.
+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Reported-and-tested-by: Alexei Starovoitov <alexei.starovoitov@gmail.com>
+Reported-by: Vlastimil Babka <vbabka@suse.cz>
+Reported-by: Sasha Levin <sasha.levin@oracle.com>
+Fixes: 9c824b6a172c ("percpu: make sure chunk->map array has available space")
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ mm/percpu.c | 57 ++++++++++++++++++++++++++++++++++++---------------------
+ 1 file changed, 36 insertions(+), 21 deletions(-)
+
+--- a/mm/percpu.c
++++ b/mm/percpu.c
+@@ -112,7 +112,7 @@ struct pcpu_chunk {
+ int map_used; /* # of map entries used before the sentry */
+ int map_alloc; /* # of map entries allocated */
+ int *map; /* allocation map */
+- struct work_struct map_extend_work;/* async ->map[] extension */
++ struct list_head map_extend_list;/* on pcpu_map_extend_chunks */
+
+ void *data; /* chunk data */
+ int first_free; /* no free below this */
+@@ -166,6 +166,9 @@ static DEFINE_MUTEX(pcpu_alloc_mutex); /
+
+ static struct list_head *pcpu_slot __read_mostly; /* chunk list slots */
+
++/* chunks which need their map areas extended, protected by pcpu_lock */
++static LIST_HEAD(pcpu_map_extend_chunks);
++
+ /*
+ * The number of empty populated pages, protected by pcpu_lock. The
+ * reserved chunk doesn't contribute to the count.
+@@ -395,13 +398,19 @@ static int pcpu_need_to_extend(struct pc
+ {
+ int margin, new_alloc;
+
++ lockdep_assert_held(&pcpu_lock);
++
+ if (is_atomic) {
+ margin = 3;
+
+ if (chunk->map_alloc <
+- chunk->map_used + PCPU_ATOMIC_MAP_MARGIN_LOW &&
+- pcpu_async_enabled)
+- schedule_work(&chunk->map_extend_work);
++ chunk->map_used + PCPU_ATOMIC_MAP_MARGIN_LOW) {
++ if (list_empty(&chunk->map_extend_list)) {
++ list_add_tail(&chunk->map_extend_list,
++ &pcpu_map_extend_chunks);
++ pcpu_schedule_balance_work();
++ }
++ }
+ } else {
+ margin = PCPU_ATOMIC_MAP_MARGIN_HIGH;
+ }
+@@ -467,20 +476,6 @@ out_unlock:
+ return 0;
+ }
+
+-static void pcpu_map_extend_workfn(struct work_struct *work)
+-{
+- struct pcpu_chunk *chunk = container_of(work, struct pcpu_chunk,
+- map_extend_work);
+- int new_alloc;
+-
+- spin_lock_irq(&pcpu_lock);
+- new_alloc = pcpu_need_to_extend(chunk, false);
+- spin_unlock_irq(&pcpu_lock);
+-
+- if (new_alloc)
+- pcpu_extend_area_map(chunk, new_alloc);
+-}
+-
+ /**
+ * pcpu_fit_in_area - try to fit the requested allocation in a candidate area
+ * @chunk: chunk the candidate area belongs to
+@@ -740,7 +735,7 @@ static struct pcpu_chunk *pcpu_alloc_chu
+ chunk->map_used = 1;
+
+ INIT_LIST_HEAD(&chunk->list);
+- INIT_WORK(&chunk->map_extend_work, pcpu_map_extend_workfn);
++ INIT_LIST_HEAD(&chunk->map_extend_list);
+ chunk->free_size = pcpu_unit_size;
+ chunk->contig_hint = pcpu_unit_size;
+
+@@ -1129,6 +1124,7 @@ static void pcpu_balance_workfn(struct w
+ if (chunk == list_first_entry(free_head, struct pcpu_chunk, list))
+ continue;
+
++ list_del_init(&chunk->map_extend_list);
+ list_move(&chunk->list, &to_free);
+ }
+
+@@ -1146,6 +1142,25 @@ static void pcpu_balance_workfn(struct w
+ pcpu_destroy_chunk(chunk);
+ }
+
++ /* service chunks which requested async area map extension */
++ do {
++ int new_alloc = 0;
++
++ spin_lock_irq(&pcpu_lock);
++
++ chunk = list_first_entry_or_null(&pcpu_map_extend_chunks,
++ struct pcpu_chunk, map_extend_list);
++ if (chunk) {
++ list_del_init(&chunk->map_extend_list);
++ new_alloc = pcpu_need_to_extend(chunk, false);
++ }
++
++ spin_unlock_irq(&pcpu_lock);
++
++ if (new_alloc)
++ pcpu_extend_area_map(chunk, new_alloc);
++ } while (chunk);
++
+ /*
+ * Ensure there are certain number of free populated pages for
+ * atomic allocs. Fill up from the most packed so that atomic
+@@ -1644,7 +1659,7 @@ int __init pcpu_setup_first_chunk(const
+ */
+ schunk = memblock_virt_alloc(pcpu_chunk_struct_size, 0);
+ INIT_LIST_HEAD(&schunk->list);
+- INIT_WORK(&schunk->map_extend_work, pcpu_map_extend_workfn);
++ INIT_LIST_HEAD(&schunk->map_extend_list);
+ schunk->base_addr = base_addr;
+ schunk->map = smap;
+ schunk->map_alloc = ARRAY_SIZE(smap);
+@@ -1673,7 +1688,7 @@ int __init pcpu_setup_first_chunk(const
+ if (dyn_size) {
+ dchunk = memblock_virt_alloc(pcpu_chunk_struct_size, 0);
+ INIT_LIST_HEAD(&dchunk->list);
+- INIT_WORK(&dchunk->map_extend_work, pcpu_map_extend_workfn);
++ INIT_LIST_HEAD(&dchunk->map_extend_list);
+ dchunk->base_addr = base_addr;
+ dchunk->map = dmap;
+ dchunk->map_alloc = ARRAY_SIZE(dmap);
--- /dev/null
+From 6710e594f71ccaad8101bc64321152af7cd9ea28 Mon Sep 17 00:00:00 2001
+From: Tejun Heo <tj@kernel.org>
+Date: Wed, 25 May 2016 11:48:25 -0400
+Subject: percpu: fix synchronization between synchronous map extension and chunk destruction
+
+From: Tejun Heo <tj@kernel.org>
+
+commit 6710e594f71ccaad8101bc64321152af7cd9ea28 upstream.
+
+For non-atomic allocations, pcpu_alloc() can try to extend the area
+map synchronously after dropping pcpu_lock; however, the extension
+wasn't synchronized against chunk destruction and the chunk might get
+freed while extension is in progress.
+
+This patch fixes the bug by putting most of non-atomic allocations
+under pcpu_alloc_mutex to synchronize against pcpu_balance_work which
+is responsible for async chunk management including destruction.
+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Reported-and-tested-by: Alexei Starovoitov <alexei.starovoitov@gmail.com>
+Reported-by: Vlastimil Babka <vbabka@suse.cz>
+Reported-by: Sasha Levin <sasha.levin@oracle.com>
+Fixes: 1a4d76076cda ("percpu: implement asynchronous chunk population")
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ mm/percpu.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/mm/percpu.c
++++ b/mm/percpu.c
+@@ -162,7 +162,7 @@ static struct pcpu_chunk *pcpu_reserved_
+ static int pcpu_reserved_chunk_limit;
+
+ static DEFINE_SPINLOCK(pcpu_lock); /* all internal data structures */
+-static DEFINE_MUTEX(pcpu_alloc_mutex); /* chunk create/destroy, [de]pop */
++static DEFINE_MUTEX(pcpu_alloc_mutex); /* chunk create/destroy, [de]pop, map ext */
+
+ static struct list_head *pcpu_slot __read_mostly; /* chunk list slots */
+
+@@ -444,6 +444,8 @@ static int pcpu_extend_area_map(struct p
+ size_t old_size = 0, new_size = new_alloc * sizeof(new[0]);
+ unsigned long flags;
+
++ lockdep_assert_held(&pcpu_alloc_mutex);
++
+ new = pcpu_mem_zalloc(new_size);
+ if (!new)
+ return -ENOMEM;
+@@ -890,6 +892,9 @@ static void __percpu *pcpu_alloc(size_t
+ return NULL;
+ }
+
++ if (!is_atomic)
++ mutex_lock(&pcpu_alloc_mutex);
++
+ spin_lock_irqsave(&pcpu_lock, flags);
+
+ /* serve reserved allocations from the reserved chunk if available */
+@@ -962,12 +967,9 @@ restart:
+ if (is_atomic)
+ goto fail;
+
+- mutex_lock(&pcpu_alloc_mutex);
+-
+ if (list_empty(&pcpu_slot[pcpu_nr_slots - 1])) {
+ chunk = pcpu_create_chunk();
+ if (!chunk) {
+- mutex_unlock(&pcpu_alloc_mutex);
+ err = "failed to allocate new chunk";
+ goto fail;
+ }
+@@ -978,7 +980,6 @@ restart:
+ spin_lock_irqsave(&pcpu_lock, flags);
+ }
+
+- mutex_unlock(&pcpu_alloc_mutex);
+ goto restart;
+
+ area_found:
+@@ -988,8 +989,6 @@ area_found:
+ if (!is_atomic) {
+ int page_start, page_end, rs, re;
+
+- mutex_lock(&pcpu_alloc_mutex);
+-
+ page_start = PFN_DOWN(off);
+ page_end = PFN_UP(off + size);
+
+@@ -1000,7 +999,6 @@ area_found:
+
+ spin_lock_irqsave(&pcpu_lock, flags);
+ if (ret) {
+- mutex_unlock(&pcpu_alloc_mutex);
+ pcpu_free_area(chunk, off, &occ_pages);
+ err = "failed to populate";
+ goto fail_unlock;
+@@ -1040,6 +1038,8 @@ fail:
+ /* see the flag handling in pcpu_blance_workfn() */
+ pcpu_atomic_alloc_failed = true;
+ pcpu_schedule_balance_work();
++ } else {
++ mutex_unlock(&pcpu_alloc_mutex);
+ }
+ return NULL;
+ }
arm64-fix-dump_instr-when-pan-and-uao-are-in-use.patch
arm64-mm-remove-page_mapping-check-in-__sync_icache_dcache.patch
arm64-kernel-save-and-restore-uao-and-addr_limit-on-exception-entry.patch
+vfs-add-d_real_inode-helper.patch
+af_unix-fix-hard-linked-sockets-on-overlay.patch
+percpu-fix-synchronization-between-chunk-map_extend_work-and-chunk-destruction.patch
+percpu-fix-synchronization-between-synchronous-map-extension-and-chunk-destruction.patch
+btrfs-account-for-non-cow-d-blocks-in-btrfs_abort_transaction.patch
+drm-radeon-fix-asic-initialization-for-virtualized-environments.patch
+drm-amdgpu-gfx7-fix-broken-condition-check.patch
+drm-amdgpu-fix-num_rbs-exposed-to-userspace-v2.patch
+drm-amdgpu-initialize-amdgpu_cgs_acpi_eval_object-result-value.patch
+ubi-make-recover_peb-power-cut-aware.patch
+drm-amdkfd-unbind-only-existing-processes.patch
+drm-amdkfd-destroy-dbgmgr-in-notifier-release.patch
+drm-dp-mst-always-clear-proposed-vcpi-table-for-port.patch
+virtio_balloon-fix-pfn-format-for-virtio-1.patch
+drm-nouveau-bios-disp-fix-handling-of-match-any-protocol-entries.patch
+drm-nouveau-disp-sor-gf119-both-links-use-the-same-training-register.patch
+drm-nouveau-gr-gf100-update-sm-error-decoding-from-gk20a-nvgpu-headers.patch
+drm-nouveau-ltc-gm107-fix-typo-in-the-address-of-nv_pltcg_ltc0_lts0_intr.patch
+drm-nouveau-fbcon-fix-out-of-bounds-memory-accesses.patch
+drm-nouveau-disp-sor-gm107-training-pattern-registers-are-like-gm200.patch
+drm-nouveau-fix-for-disabled-fbdev-emulation.patch
+drm-nouveau-disp-sor-gf119-select-correct-sor-when-poking-training-pattern.patch
+drm-i915-ilk-don-t-disable-ssc-source-if-it-s-in-use.patch
+drm-i915-fbc-disable-on-hsw-by-default-for-now.patch
+drm-i915-refresh-cached-dp-port-register-value-on-resume.patch
+drm-i915-update-ifdeffery-for-mutex-owner.patch
+drm-add-missing-drm_mode_set_crtcinfo-call.patch
+drm-make-drm_atomic_set_mode_prop_for_crtc-more-reliable.patch
+drm-wrap-direct-calls-to-driver-gem_free_object-from-cma.patch
+drm-amd-powerplay-fix-bug-that-function-parameter-was-incorect.patch
+drm-amd-powerplay-need-to-notify-system-bios-pcie-device-ready.patch
+drm-amd-powerplay-fix-logic-error.patch
+drm-amd-powerplay-incorrectly-use-of-the-function-return-value.patch
+drm-amd-powerplay-fix-incorrect-voltage-table-value-for-tonga.patch
+drm-atmel-hlcdc-actually-disable-scaling-when-no-scaling-is-required.patch
+drm-atomic-make-drm_atomic_legacy_backoff-reset-crtc-acquire_ctx.patch
+drm-ttm-make-ttm_bo_mem_compat-available.patch
+drm-vmwgfx-add-an-option-to-change-assumed-fb-bpp.patch
+drm-vmwgfx-work-around-mode-set-failure-in-2d-vms.patch
+drm-vmwgfx-check-pin-count-before-attempting-to-move-a-buffer.patch
+drm-vmwgfx-delay-pinning-fbdev-framebuffer-until-after-mode-set.patch
+drm-vmwgfx-fix-corner-case-screen-target-management.patch
+drm-vmwgfx-fix-error-paths-when-mapping-framebuffer.patch
+memory-omap-gpmc-fix-omap-gpmc-extradelay-timing.patch
+pci-fix-unaligned-accesses-in-vc-code.patch
--- /dev/null
+From 972228d87445dc46c0a01f5f3de673ac017626f7 Mon Sep 17 00:00:00 2001
+From: Richard Weinberger <richard@nod.at>
+Date: Tue, 21 Jun 2016 00:31:50 +0200
+Subject: ubi: Make recover_peb power cut aware
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Richard Weinberger <richard@nod.at>
+
+commit 972228d87445dc46c0a01f5f3de673ac017626f7 upstream.
+
+recover_peb() was never power cut aware,
+if a power cut happened right after writing the VID header
+upon next attach UBI would blindly use the new partial written
+PEB and all data from the old PEB is lost.
+
+In order to make recover_peb() power cut aware, write the new
+VID with a proper crc and copy_flag set such that the UBI attach
+process will detect whether the new PEB is completely written
+or not.
+We cannot directly use ubi_eba_atomic_leb_change() since we'd
+have to unlock the LEB which is facing a write error.
+
+Reported-by: Jörg Pfähler <pfaehler@isse.de>
+Reviewed-by: Jörg Pfähler <pfaehler@isse.de>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mtd/ubi/eba.c | 22 +++++++++++++++-------
+ 1 file changed, 15 insertions(+), 7 deletions(-)
+
+--- a/drivers/mtd/ubi/eba.c
++++ b/drivers/mtd/ubi/eba.c
+@@ -575,6 +575,7 @@ static int recover_peb(struct ubi_device
+ int err, idx = vol_id2idx(ubi, vol_id), new_pnum, data_size, tries = 0;
+ struct ubi_volume *vol = ubi->volumes[idx];
+ struct ubi_vid_hdr *vid_hdr;
++ uint32_t crc;
+
+ vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS);
+ if (!vid_hdr)
+@@ -599,14 +600,8 @@ retry:
+ goto out_put;
+ }
+
+- vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
+- err = ubi_io_write_vid_hdr(ubi, new_pnum, vid_hdr);
+- if (err) {
+- up_read(&ubi->fm_eba_sem);
+- goto write_error;
+- }
++ ubi_assert(vid_hdr->vol_type == UBI_VID_DYNAMIC);
+
+- data_size = offset + len;
+ mutex_lock(&ubi->buf_mutex);
+ memset(ubi->peb_buf + offset, 0xFF, len);
+
+@@ -621,6 +616,19 @@ retry:
+
+ memcpy(ubi->peb_buf + offset, buf, len);
+
++ data_size = offset + len;
++ crc = crc32(UBI_CRC32_INIT, ubi->peb_buf, data_size);
++ vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
++ vid_hdr->copy_flag = 1;
++ vid_hdr->data_size = cpu_to_be32(data_size);
++ vid_hdr->data_crc = cpu_to_be32(crc);
++ err = ubi_io_write_vid_hdr(ubi, new_pnum, vid_hdr);
++ if (err) {
++ mutex_unlock(&ubi->buf_mutex);
++ up_read(&ubi->fm_eba_sem);
++ goto write_error;
++ }
++
+ err = ubi_io_write_data(ubi, ubi->peb_buf, new_pnum, 0, data_size);
+ if (err) {
+ mutex_unlock(&ubi->buf_mutex);
--- /dev/null
+From a118084432d642eeccb961c7c8cc61525a941fcb Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@redhat.com>
+Date: Fri, 20 May 2016 22:13:45 +0200
+Subject: vfs: add d_real_inode() helper
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+commit a118084432d642eeccb961c7c8cc61525a941fcb upstream.
+
+Needed by the following fix.
+
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/dcache.h | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/include/linux/dcache.h
++++ b/include/linux/dcache.h
+@@ -576,5 +576,17 @@ static inline struct inode *vfs_select_i
+ return inode;
+ }
+
++/**
++ * d_real_inode - Return the real inode
++ * @dentry: The dentry to query
++ *
++ * If dentry is on an union/overlay, then return the underlying, real inode.
++ * Otherwise return d_inode().
++ */
++static inline struct inode *d_real_inode(struct dentry *dentry)
++{
++ return d_backing_inode(d_real(dentry));
++}
++
+
+ #endif /* __LINUX_DCACHE_H */
--- /dev/null
+From 87c9403b0d1de4676b0bd273eea68fcf6de68e68 Mon Sep 17 00:00:00 2001
+From: "Michael S. Tsirkin" <mst@redhat.com>
+Date: Tue, 17 May 2016 13:31:18 +0300
+Subject: virtio_balloon: fix PFN format for virtio-1
+
+From: Michael S. Tsirkin <mst@redhat.com>
+
+commit 87c9403b0d1de4676b0bd273eea68fcf6de68e68 upstream.
+
+Everything should be LE when using virtio-1, but
+the linux balloon driver does not seem to care about that.
+
+Reported-by: Cornelia Huck <cornelia.huck@de.ibm.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Tested-by: Cornelia Huck <cornelia.huck@de.ibm.com>
+Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/virtio/virtio_balloon.c | 20 ++++++++++++--------
+ 1 file changed, 12 insertions(+), 8 deletions(-)
+
+--- a/drivers/virtio/virtio_balloon.c
++++ b/drivers/virtio/virtio_balloon.c
+@@ -75,7 +75,7 @@ struct virtio_balloon {
+
+ /* The array of pfns we tell the Host about. */
+ unsigned int num_pfns;
+- u32 pfns[VIRTIO_BALLOON_ARRAY_PFNS_MAX];
++ __virtio32 pfns[VIRTIO_BALLOON_ARRAY_PFNS_MAX];
+
+ /* Memory statistics */
+ struct virtio_balloon_stat stats[VIRTIO_BALLOON_S_NR];
+@@ -127,14 +127,16 @@ static void tell_host(struct virtio_ball
+
+ }
+
+-static void set_page_pfns(u32 pfns[], struct page *page)
++static void set_page_pfns(struct virtio_balloon *vb,
++ __virtio32 pfns[], struct page *page)
+ {
+ unsigned int i;
+
+ /* Set balloon pfns pointing at this page.
+ * Note that the first pfn points at start of the page. */
+ for (i = 0; i < VIRTIO_BALLOON_PAGES_PER_PAGE; i++)
+- pfns[i] = page_to_balloon_pfn(page) + i;
++ pfns[i] = cpu_to_virtio32(vb->vdev,
++ page_to_balloon_pfn(page) + i);
+ }
+
+ static unsigned fill_balloon(struct virtio_balloon *vb, size_t num)
+@@ -158,7 +160,7 @@ static unsigned fill_balloon(struct virt
+ msleep(200);
+ break;
+ }
+- set_page_pfns(vb->pfns + vb->num_pfns, page);
++ set_page_pfns(vb, vb->pfns + vb->num_pfns, page);
+ vb->num_pages += VIRTIO_BALLOON_PAGES_PER_PAGE;
+ if (!virtio_has_feature(vb->vdev,
+ VIRTIO_BALLOON_F_DEFLATE_ON_OOM))
+@@ -177,10 +179,12 @@ static unsigned fill_balloon(struct virt
+ static void release_pages_balloon(struct virtio_balloon *vb)
+ {
+ unsigned int i;
++ struct page *page;
+
+ /* Find pfns pointing at start of each page, get pages and free them. */
+ for (i = 0; i < vb->num_pfns; i += VIRTIO_BALLOON_PAGES_PER_PAGE) {
+- struct page *page = balloon_pfn_to_page(vb->pfns[i]);
++ page = balloon_pfn_to_page(virtio32_to_cpu(vb->vdev,
++ vb->pfns[i]));
+ if (!virtio_has_feature(vb->vdev,
+ VIRTIO_BALLOON_F_DEFLATE_ON_OOM))
+ adjust_managed_page_count(page, 1);
+@@ -203,7 +207,7 @@ static unsigned leak_balloon(struct virt
+ page = balloon_page_dequeue(vb_dev_info);
+ if (!page)
+ break;
+- set_page_pfns(vb->pfns + vb->num_pfns, page);
++ set_page_pfns(vb, vb->pfns + vb->num_pfns, page);
+ vb->num_pages -= VIRTIO_BALLOON_PAGES_PER_PAGE;
+ }
+
+@@ -471,13 +475,13 @@ static int virtballoon_migratepage(struc
+ __count_vm_event(BALLOON_MIGRATE);
+ spin_unlock_irqrestore(&vb_dev_info->pages_lock, flags);
+ vb->num_pfns = VIRTIO_BALLOON_PAGES_PER_PAGE;
+- set_page_pfns(vb->pfns, newpage);
++ set_page_pfns(vb, vb->pfns, newpage);
+ tell_host(vb, vb->inflate_vq);
+
+ /* balloon's page migration 2nd step -- deflate "page" */
+ balloon_page_delete(page);
+ vb->num_pfns = VIRTIO_BALLOON_PAGES_PER_PAGE;
+- set_page_pfns(vb->pfns, page);
++ set_page_pfns(vb, vb->pfns, page);
+ tell_host(vb, vb->deflate_vq);
+
+ mutex_unlock(&vb->balloon_lock);