]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
.37 patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Fri, 25 Mar 2011 16:21:35 +0000 (09:21 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 25 Mar 2011 16:21:35 +0000 (09:21 -0700)
queue-2.6.37/drm-check-for-modesetting-on-modeset-ioctls.patch [new file with mode: 0644]
queue-2.6.37/drm-fix-use-after-free-in-drm_gem_vm_close.patch [new file with mode: 0644]
queue-2.6.37/drm-i915-prevent-racy-removal-of-request-from-client-list.patch [new file with mode: 0644]
queue-2.6.37/drm-radeon-kms-fix-hardcoded-edid-handling.patch [new file with mode: 0644]
queue-2.6.37/drm-radeon-kms-prefer-legacy-pll-algo-for-tv-out.patch [new file with mode: 0644]
queue-2.6.37/perf-fix-tear-down-of-inherited-group-events.patch [new file with mode: 0644]
queue-2.6.37/series

diff --git a/queue-2.6.37/drm-check-for-modesetting-on-modeset-ioctls.patch b/queue-2.6.37/drm-check-for-modesetting-on-modeset-ioctls.patch
new file mode 100644 (file)
index 0000000..9ea7d0a
--- /dev/null
@@ -0,0 +1,191 @@
+From fb3b06c8a1fd1a80298f13b738ab38ef8c73baff Mon Sep 17 00:00:00 2001
+From: Dave Airlie <airlied@redhat.com>
+Date: Tue, 8 Feb 2011 13:55:21 +1000
+Subject: drm: check for modesetting on modeset ioctls
+
+From: Dave Airlie <airlied@redhat.com>
+
+commit fb3b06c8a1fd1a80298f13b738ab38ef8c73baff upstream.
+
+Noticed this while working on some other things, helps if we check for modeset
+enabled on modesetting ioctls.
+
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/gpu/drm/drm_crtc.c |   51 +++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 51 insertions(+)
+
+--- a/drivers/gpu/drm/drm_crtc.c
++++ b/drivers/gpu/drm/drm_crtc.c
+@@ -1073,6 +1073,9 @@ int drm_mode_getresources(struct drm_dev
+       uint32_t __user *encoder_id;
+       struct drm_mode_group *mode_group;
++      if (!drm_core_check_feature(dev, DRIVER_MODESET))
++              return -EINVAL;
++
+       mutex_lock(&dev->mode_config.mutex);
+       /*
+@@ -1244,6 +1247,9 @@ int drm_mode_getcrtc(struct drm_device *
+       struct drm_mode_object *obj;
+       int ret = 0;
++      if (!drm_core_check_feature(dev, DRIVER_MODESET))
++              return -EINVAL;
++
+       mutex_lock(&dev->mode_config.mutex);
+       obj = drm_mode_object_find(dev, crtc_resp->crtc_id,
+@@ -1312,6 +1318,9 @@ int drm_mode_getconnector(struct drm_dev
+       uint64_t __user *prop_values;
+       uint32_t __user *encoder_ptr;
++      if (!drm_core_check_feature(dev, DRIVER_MODESET))
++              return -EINVAL;
++
+       memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo));
+       DRM_DEBUG_KMS("[CONNECTOR:%d:?]\n", out_resp->connector_id);
+@@ -1431,6 +1440,9 @@ int drm_mode_getencoder(struct drm_devic
+       struct drm_encoder *encoder;
+       int ret = 0;
++      if (!drm_core_check_feature(dev, DRIVER_MODESET))
++              return -EINVAL;
++
+       mutex_lock(&dev->mode_config.mutex);
+       obj = drm_mode_object_find(dev, enc_resp->encoder_id,
+                                  DRM_MODE_OBJECT_ENCODER);
+@@ -1486,6 +1498,9 @@ int drm_mode_setcrtc(struct drm_device *
+       int ret = 0;
+       int i;
++      if (!drm_core_check_feature(dev, DRIVER_MODESET))
++              return -EINVAL;
++
+       mutex_lock(&dev->mode_config.mutex);
+       obj = drm_mode_object_find(dev, crtc_req->crtc_id,
+                                  DRM_MODE_OBJECT_CRTC);
+@@ -1603,6 +1618,9 @@ int drm_mode_cursor_ioctl(struct drm_dev
+       struct drm_crtc *crtc;
+       int ret = 0;
++      if (!drm_core_check_feature(dev, DRIVER_MODESET))
++              return -EINVAL;
++
+       if (!req->flags) {
+               DRM_ERROR("no operation set\n");
+               return -EINVAL;
+@@ -1667,6 +1685,9 @@ int drm_mode_addfb(struct drm_device *de
+       struct drm_framebuffer *fb;
+       int ret = 0;
++      if (!drm_core_check_feature(dev, DRIVER_MODESET))
++              return -EINVAL;
++
+       if ((config->min_width > r->width) || (r->width > config->max_width)) {
+               DRM_ERROR("mode new framebuffer width not within limits\n");
+               return -EINVAL;
+@@ -1724,6 +1745,9 @@ int drm_mode_rmfb(struct drm_device *dev
+       int ret = 0;
+       int found = 0;
++      if (!drm_core_check_feature(dev, DRIVER_MODESET))
++              return -EINVAL;
++
+       mutex_lock(&dev->mode_config.mutex);
+       obj = drm_mode_object_find(dev, *id, DRM_MODE_OBJECT_FB);
+       /* TODO check that we realy get a framebuffer back. */
+@@ -1780,6 +1804,9 @@ int drm_mode_getfb(struct drm_device *de
+       struct drm_framebuffer *fb;
+       int ret = 0;
++      if (!drm_core_check_feature(dev, DRIVER_MODESET))
++              return -EINVAL;
++
+       mutex_lock(&dev->mode_config.mutex);
+       obj = drm_mode_object_find(dev, r->fb_id, DRM_MODE_OBJECT_FB);
+       if (!obj) {
+@@ -1813,6 +1840,9 @@ int drm_mode_dirtyfb_ioctl(struct drm_de
+       int num_clips;
+       int ret = 0;
++      if (!drm_core_check_feature(dev, DRIVER_MODESET))
++              return -EINVAL;
++
+       mutex_lock(&dev->mode_config.mutex);
+       obj = drm_mode_object_find(dev, r->fb_id, DRM_MODE_OBJECT_FB);
+       if (!obj) {
+@@ -1996,6 +2026,9 @@ int drm_mode_attachmode_ioctl(struct drm
+       struct drm_mode_modeinfo *umode = &mode_cmd->mode;
+       int ret = 0;
++      if (!drm_core_check_feature(dev, DRIVER_MODESET))
++              return -EINVAL;
++
+       mutex_lock(&dev->mode_config.mutex);
+       obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR);
+@@ -2042,6 +2075,9 @@ int drm_mode_detachmode_ioctl(struct drm
+       struct drm_mode_modeinfo *umode = &mode_cmd->mode;
+       int ret = 0;
++      if (!drm_core_check_feature(dev, DRIVER_MODESET))
++              return -EINVAL;
++
+       mutex_lock(&dev->mode_config.mutex);
+       obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR);
+@@ -2211,6 +2247,9 @@ int drm_mode_getproperty_ioctl(struct dr
+       uint64_t __user *values_ptr;
+       uint32_t __user *blob_length_ptr;
++      if (!drm_core_check_feature(dev, DRIVER_MODESET))
++              return -EINVAL;
++
+       mutex_lock(&dev->mode_config.mutex);
+       obj = drm_mode_object_find(dev, out_resp->prop_id, DRM_MODE_OBJECT_PROPERTY);
+       if (!obj) {
+@@ -2333,6 +2372,9 @@ int drm_mode_getblob_ioctl(struct drm_de
+       int ret = 0;
+       void *blob_ptr;
++      if (!drm_core_check_feature(dev, DRIVER_MODESET))
++              return -EINVAL;
++
+       mutex_lock(&dev->mode_config.mutex);
+       obj = drm_mode_object_find(dev, out_resp->blob_id, DRM_MODE_OBJECT_BLOB);
+       if (!obj) {
+@@ -2393,6 +2435,9 @@ int drm_mode_connector_property_set_ioct
+       int ret = -EINVAL;
+       int i;
++      if (!drm_core_check_feature(dev, DRIVER_MODESET))
++              return -EINVAL;
++
+       mutex_lock(&dev->mode_config.mutex);
+       obj = drm_mode_object_find(dev, out_resp->connector_id, DRM_MODE_OBJECT_CONNECTOR);
+@@ -2509,6 +2554,9 @@ int drm_mode_gamma_set_ioctl(struct drm_
+       int size;
+       int ret = 0;
++      if (!drm_core_check_feature(dev, DRIVER_MODESET))
++              return -EINVAL;
++
+       mutex_lock(&dev->mode_config.mutex);
+       obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC);
+       if (!obj) {
+@@ -2560,6 +2608,9 @@ int drm_mode_gamma_get_ioctl(struct drm_
+       int size;
+       int ret = 0;
++      if (!drm_core_check_feature(dev, DRIVER_MODESET))
++              return -EINVAL;
++
+       mutex_lock(&dev->mode_config.mutex);
+       obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC);
+       if (!obj) {
diff --git a/queue-2.6.37/drm-fix-use-after-free-in-drm_gem_vm_close.patch b/queue-2.6.37/drm-fix-use-after-free-in-drm_gem_vm_close.patch
new file mode 100644 (file)
index 0000000..9f79e21
--- /dev/null
@@ -0,0 +1,78 @@
+From b74ad5ae14def5e81ad0be3dddb96e485b861b1b Mon Sep 17 00:00:00 2001
+From: Chris Wilson <chris@chris-wilson.co.uk>
+Date: Thu, 17 Mar 2011 22:33:33 +0000
+Subject: drm: Fix use-after-free in drm_gem_vm_close()
+
+From: Chris Wilson <chris@chris-wilson.co.uk>
+
+commit b74ad5ae14def5e81ad0be3dddb96e485b861b1b upstream.
+
+As we may release the last reference, we need to store the device in a
+local variable in order to unlock afterwards.
+
+[   60.140768] BUG: unable to handle kernel paging request at 6b6b6b9f
+[   60.140973] IP: [<c1536d11>] __mutex_unlock_slowpath+0x5a/0x111
+[   60.141014] *pdpt = 0000000024a54001 *pde = 0000000000000000
+[   60.141014] Oops: 0002 [#1] PREEMPT SMP
+[   60.141014] last sysfs file: /sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/PNP0C0A:00/power_supply/BAT0/voltage_now
+[   60.141014] Modules linked in: uvcvideo ath9k pegasus ath9k_common ath9k_hw hid_egalax ath3k joydev asus_laptop sparse_keymap battery input_polldev
+[   60.141014]
+[   60.141014] Pid: 771, comm: meego-ux-daemon Not tainted 2.6.37.2-7.1 #1 EXOPC EXOPG06411/EXOPG06411
+[   60.141014] EIP: 0060:[<c1536d11>] EFLAGS: 00010046 CPU: 0
+[   60.141014] EIP is at __mutex_unlock_slowpath+0x5a/0x111
+[   60.141014] EAX: 00000100 EBX: 6b6b6b9b ECX: e9b4a1b0 EDX: e4a4e580
+[   60.141014] ESI: db162558 EDI: 00000246 EBP: e480be50 ESP: e480be44
+[   60.141014]  DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068
+[   60.141014] Process meego-ux-daemon (pid: 771, ti=e480a000 task=e9b4a1b0 task.ti=e480a000)
+[   60.141014] Stack:
+[   60.141014]  e4a4e580 db162558 f5a2f838 e480be58 c1536dd0 e480be68 c125ab1b db162558
+[   60.141014]  db1624e0 e480be78 c10ba071 db162558 f760241c e480be94 c10bb0bc 000155fe
+[   60.141014]  f760241c f5a2f838 f5a2f8c8 00000000 e480bea4 c1037c24 00000000 f5a2f838
+[   60.141014] Call Trace:
+[   60.141014]  [<c1536dd0>] ? mutex_unlock+0x8/0xa
+[   60.141014]  [<c125ab1b>] ? drm_gem_vm_close+0x39/0x3d
+[   60.141014]  [<c10ba071>] ? remove_vma+0x2d/0x58
+[   60.141014]  [<c10bb0bc>] ? exit_mmap+0x126/0x13f
+[   60.141014]  [<c1037c24>] ? mmput+0x37/0x9a
+[   60.141014]  [<c10d450d>] ? exec_mmap+0x178/0x19c
+[   60.141014]  [<c1537f85>] ? _raw_spin_unlock+0x1d/0x36
+[   60.141014]  [<c10d4eb0>] ? flush_old_exec+0x42/0x75
+[   60.141014]  [<c1104442>] ? load_elf_binary+0x32a/0x922
+[   60.141014]  [<c10d3f76>] ? search_binary_handler+0x200/0x2ea
+[   60.141014]  [<c10d3ecf>] ? search_binary_handler+0x159/0x2ea
+[   60.141014]  [<c1104118>] ? load_elf_binary+0x0/0x922
+[   60.141014]  [<c10d56b2>] ? do_execve+0x1ff/0x2e6
+[   60.141014]  [<c100970e>] ? sys_execve+0x2d/0x55
+[   60.141014]  [<c1002a5a>] ? ptregs_execve+0x12/0x18
+[   60.141014]  [<c10029dc>] ? sysenter_do_call+0x12/0x3c
+[   60.141014]  [<c1530000>] ? init_centaur+0x9c/0x1ba
+[   60.141014] Code: c1 00 75 0f ba 38 01 00 00 b8 8c 3a 6c c1 e8 cc 2e b0 ff 9c 58 8d 74 26 00 89 c7 fa 90 8d 74 26 00 e8 d2 b4 b2 ff b8 00 01 00 00 <f0> 66 0f c1 43 04 38 e0 74 07 f3 90 8a 43 04 eb f5 83 3d 64 ef
+[   60.141014] EIP: [<c1536d11>] __mutex_unlock_slowpath+0x5a/0x111 SS:ESP 0068:e480be44
+[   60.141014] CR2: 000000006b6b6b9f
+
+Reported-by: Rusty Lynch <rusty.lynch@intel.com>
+Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/gpu/drm/drm_gem.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/drm_gem.c
++++ b/drivers/gpu/drm/drm_gem.c
+@@ -498,11 +498,12 @@ EXPORT_SYMBOL(drm_gem_vm_open);
+ void drm_gem_vm_close(struct vm_area_struct *vma)
+ {
+       struct drm_gem_object *obj = vma->vm_private_data;
++      struct drm_device *dev = obj->dev;
+-      mutex_lock(&obj->dev->struct_mutex);
++      mutex_lock(&dev->struct_mutex);
+       drm_vm_close_locked(vma);
+       drm_gem_object_unreference(obj);
+-      mutex_unlock(&obj->dev->struct_mutex);
++      mutex_unlock(&dev->struct_mutex);
+ }
+ EXPORT_SYMBOL(drm_gem_vm_close);
diff --git a/queue-2.6.37/drm-i915-prevent-racy-removal-of-request-from-client-list.patch b/queue-2.6.37/drm-i915-prevent-racy-removal-of-request-from-client-list.patch
new file mode 100644 (file)
index 0000000..f6a4e64
--- /dev/null
@@ -0,0 +1,80 @@
+From 09bfa51773c1e90f13000dc2fc0c4b84047009bc Mon Sep 17 00:00:00 2001
+From: Herton Ronaldo Krzesinski <herton.krzesinski@canonical.com>
+Date: Thu, 17 Mar 2011 13:45:12 +0000
+Subject: drm/i915: Prevent racy removal of request from client list
+
+From: Herton Ronaldo Krzesinski <herton.krzesinski@canonical.com>
+
+commit 09bfa51773c1e90f13000dc2fc0c4b84047009bc upstream.
+
+When i915_gem_retire_requests_ring calls i915_gem_request_remove_from_client,
+the client_list for that request may already be removed in i915_gem_release.
+So we may call twice list_del(&request->client_list), resulting in an
+oops like this report:
+
+[126167.230394] BUG: unable to handle kernel paging request at 00100104
+[126167.230699] IP: [<f8c2ce44>] i915_gem_retire_requests_ring+0xd4/0x240 [i915]
+[126167.231042] *pdpt = 00000000314c1001 *pde = 0000000000000000
+[126167.231314] Oops: 0002 [#1] SMP
+[126167.231471] last sysfs file: /sys/devices/LNXSYSTM:00/device:00/PNP0C0A:00/power_supply/BAT1/current_now
+[126167.231901] Modules linked in: snd_seq_dummy nls_utf8 isofs btrfs zlib_deflate libcrc32c ufs qnx4 hfsplus hfs minix ntfs vfat msdos fat jfs xfs exportfs reiserfs cryptd aes_i586 aes_generic binfmt_misc vboxnetadp vboxnetflt vboxdrv parport_pc ppdev snd_hda_codec_hdmi snd_hda_codec_conexant snd_hda_intel snd_hda_codec snd_hwdep arc4 snd_pcm snd_seq_midi snd_rawmidi snd_seq_midi_event snd_seq uvcvideo videodev snd_timer snd_seq_device joydev iwlagn iwlcore mac80211 snd cfg80211 soundcore i915 drm_kms_helper snd_page_alloc psmouse drm serio_raw i2c_algo_bit video lp parport usbhid hid sky2 sdhci_pci ahci sdhci libahci
+[126167.232018]
+[126167.232018] Pid: 1101, comm: Xorg Not tainted 2.6.38-6-generic-pae #34-Ubuntu Gateway                          MC7833U /
+[126167.232018] EIP: 0060:[<f8c2ce44>] EFLAGS: 00213246 CPU: 0
+[126167.232018] EIP is at i915_gem_retire_requests_ring+0xd4/0x240 [i915]
+[126167.232018] EAX: 00200200 EBX: f1ac25b0 ECX: 00000040 EDX: 00100100
+[126167.232018] ESI: f1a2801c EDI: e87fc060 EBP: ef4d7dd8 ESP: ef4d7db0
+[126167.232018]  DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
+[126167.232018] Process Xorg (pid: 1101, ti=ef4d6000 task=f1ba6500 task.ti=ef4d6000)
+[126167.232018] Stack:
+[126167.232018]  f1a28000 f1a2809c f1a28094 0058bd97 f1aa2400 f1a2801c 0058bd7b 0058bd85
+[126167.232018]  f1a2801c f1a28000 ef4d7e38 f8c2e995 ef4d7e30 ef4d7e60 c14d1ebc f6b3a040
+[126167.232018]  f1522cc0 000000db 00000000 f1ba6500 ffffffa1 00000000 00000001 f1a29214
+[126167.232018] Call Trace:
+
+Unfortunately the call trace reported was cut, but looking at debug
+symbols the crash is at __list_del, when probably list_del is called
+twice on the same request->client_list, as the dereferenced value is
+LIST_POISON1 + 4, and by looking more at the debug symbols before
+list_del call it should have being called by
+i915_gem_request_remove_from_client
+
+And as I can see in the code, it seems we indeed have the possibility
+to remove a request->client_list twice, which would cause the above,
+because we do list_del(&request->client_list) on both
+i915_gem_request_remove_from_client and i915_gem_release
+
+As Chris Wilson pointed out, it's indeed the case:
+"(...) I had thought that the actual insertion/deletion was serialised
+under the struct mutex and the intention of the spinlock was to protect
+the unlocked list traversal during throttling. However, I missed that
+i915_gem_release() is also called without struct mutex and so we do need
+the double check for i915_gem_request_remove_from_client()."
+
+This change does the required check to avoid the duplicate remove of
+request->client_list.
+
+Bugzilla: http://bugs.launchpad.net/bugs/733780
+Signed-off-by: Herton Ronaldo Krzesinski <herton.krzesinski@canonical.com>
+Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/gpu/drm/i915/i915_gem.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/i915/i915_gem.c
++++ b/drivers/gpu/drm/i915/i915_gem.c
+@@ -1748,8 +1748,10 @@ i915_gem_request_remove_from_client(stru
+               return;
+       spin_lock(&file_priv->mm.lock);
+-      list_del(&request->client_list);
+-      request->file_priv = NULL;
++      if (request->file_priv) {
++              list_del(&request->client_list);
++              request->file_priv = NULL;
++      }
+       spin_unlock(&file_priv->mm.lock);
+ }
diff --git a/queue-2.6.37/drm-radeon-kms-fix-hardcoded-edid-handling.patch b/queue-2.6.37/drm-radeon-kms-fix-hardcoded-edid-handling.patch
new file mode 100644 (file)
index 0000000..e2debe7
--- /dev/null
@@ -0,0 +1,168 @@
+From fafcf94e2b5732d1e13b440291c53115d2b172e9 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexdeucher@gmail.com>
+Date: Wed, 23 Mar 2011 08:10:10 +0000
+Subject: drm/radeon/kms: fix hardcoded EDID handling
+
+From: Alex Deucher <alexdeucher@gmail.com>
+
+commit fafcf94e2b5732d1e13b440291c53115d2b172e9 upstream.
+
+On some servers there is a hardcoded EDID provided
+in the vbios so that the driver will always see a
+display connected even if something like a KVM
+prevents traditional means like DDC or load
+detection from working properly.  Also most
+server boards with DVI are not actually DVI, but
+DVO connected to a virtual KVM service processor.
+If we fail to detect a monitor via DDC or load
+detection and a hardcoded EDID is available, use
+it.
+
+Additionally, when using the hardcoded EDID, use
+a copy of it rather than the actual one stored
+in the driver as the detect() and get_modes()
+functions may free it if DDC is successful.
+
+This fixes the virtual KVM on several internal
+servers.
+
+Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/gpu/drm/radeon/radeon_combios.c    |   21 +++++++++++++++-----
+ drivers/gpu/drm/radeon/radeon_connectors.c |   30 +++++++++++++++++++++++++++--
+ drivers/gpu/drm/radeon/radeon_mode.h       |    1 
+ 3 files changed, 45 insertions(+), 7 deletions(-)
+
+--- a/drivers/gpu/drm/radeon/radeon_combios.c
++++ b/drivers/gpu/drm/radeon/radeon_combios.c
+@@ -448,7 +448,7 @@ static uint16_t combios_get_table_offset
+ bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev)
+ {
+-      int edid_info;
++      int edid_info, size;
+       struct edid *edid;
+       unsigned char *raw;
+       edid_info = combios_get_table_offset(rdev->ddev, COMBIOS_HARDCODED_EDID_TABLE);
+@@ -456,11 +456,12 @@ bool radeon_combios_check_hardcoded_edid
+               return false;
+       raw = rdev->bios + edid_info;
+-      edid = kmalloc(EDID_LENGTH * (raw[0x7e] + 1), GFP_KERNEL);
++      size = EDID_LENGTH * (raw[0x7e] + 1);
++      edid = kmalloc(size, GFP_KERNEL);
+       if (edid == NULL)
+               return false;
+-      memcpy((unsigned char *)edid, raw, EDID_LENGTH * (raw[0x7e] + 1));
++      memcpy((unsigned char *)edid, raw, size);
+       if (!drm_edid_is_valid(edid)) {
+               kfree(edid);
+@@ -468,14 +469,24 @@ bool radeon_combios_check_hardcoded_edid
+       }
+       rdev->mode_info.bios_hardcoded_edid = edid;
++      rdev->mode_info.bios_hardcoded_edid_size = size;
+       return true;
+ }
+ struct edid *
+ radeon_combios_get_hardcoded_edid(struct radeon_device *rdev)
+ {
+-      if (rdev->mode_info.bios_hardcoded_edid)
+-              return rdev->mode_info.bios_hardcoded_edid;
++      struct edid *edid;
++
++      if (rdev->mode_info.bios_hardcoded_edid) {
++              edid = kmalloc(rdev->mode_info.bios_hardcoded_edid_size, GFP_KERNEL);
++              if (edid) {
++                      memcpy((unsigned char *)edid,
++                             (unsigned char *)rdev->mode_info.bios_hardcoded_edid,
++                             rdev->mode_info.bios_hardcoded_edid_size);
++                      return edid;
++              }
++      }
+       return NULL;
+ }
+--- a/drivers/gpu/drm/radeon/radeon_connectors.c
++++ b/drivers/gpu/drm/radeon/radeon_connectors.c
+@@ -626,6 +626,8 @@ static int radeon_vga_mode_valid(struct
+ static enum drm_connector_status
+ radeon_vga_detect(struct drm_connector *connector, bool force)
+ {
++      struct drm_device *dev = connector->dev;
++      struct radeon_device *rdev = dev->dev_private;
+       struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+       struct drm_encoder *encoder;
+       struct drm_encoder_helper_funcs *encoder_funcs;
+@@ -676,6 +678,17 @@ radeon_vga_detect(struct drm_connector *
+       if (ret == connector_status_connected)
+               ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, true);
++
++      /* RN50 and some RV100 asics in servers often have a hardcoded EDID in the
++       * vbios to deal with KVMs. If we have one and are not able to detect a monitor
++       * by other means, assume the CRT is connected and use that EDID.
++       */
++      if ((!rdev->is_atom_bios) &&
++          (ret == connector_status_disconnected) &&
++          rdev->mode_info.bios_hardcoded_edid_size) {
++              ret = connector_status_connected;
++      }
++
+       radeon_connector_update_scratch_regs(connector, ret);
+       return ret;
+ }
+@@ -787,6 +800,8 @@ static int radeon_dvi_get_modes(struct d
+ static enum drm_connector_status
+ radeon_dvi_detect(struct drm_connector *connector, bool force)
+ {
++      struct drm_device *dev = connector->dev;
++      struct radeon_device *rdev = dev->dev_private;
+       struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+       struct drm_encoder *encoder = NULL;
+       struct drm_encoder_helper_funcs *encoder_funcs;
+@@ -826,8 +841,6 @@ radeon_dvi_detect(struct drm_connector *
+                        * you don't really know what's connected to which port as both are digital.
+                        */
+                       if (radeon_connector->shared_ddc && (ret == connector_status_connected)) {
+-                              struct drm_device *dev = connector->dev;
+-                              struct radeon_device *rdev = dev->dev_private;
+                               struct drm_connector *list_connector;
+                               struct radeon_connector *list_radeon_connector;
+                               list_for_each_entry(list_connector, &dev->mode_config.connector_list, head) {
+@@ -892,6 +905,19 @@ radeon_dvi_detect(struct drm_connector *
+               ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, true);
+       }
++      /* RN50 and some RV100 asics in servers often have a hardcoded EDID in the
++       * vbios to deal with KVMs. If we have one and are not able to detect a monitor
++       * by other means, assume the DFP is connected and use that EDID.  In most
++       * cases the DVI port is actually a virtual KVM port connected to the service
++       * processor.
++       */
++      if ((!rdev->is_atom_bios) &&
++          (ret == connector_status_disconnected) &&
++          rdev->mode_info.bios_hardcoded_edid_size) {
++              radeon_connector->use_digital = true;
++              ret = connector_status_connected;
++      }
++
+ out:
+       /* updated in get modes as well since we need to know if it's analog or digital */
+       radeon_connector_update_scratch_regs(connector, ret);
+--- a/drivers/gpu/drm/radeon/radeon_mode.h
++++ b/drivers/gpu/drm/radeon/radeon_mode.h
+@@ -239,6 +239,7 @@ struct radeon_mode_info {
+       struct drm_property *underscan_vborder_property;
+       /* hardcoded DFP edid from BIOS */
+       struct edid *bios_hardcoded_edid;
++      int bios_hardcoded_edid_size;
+       /* pointer to fbdev info structure */
+       struct radeon_fbdev *rfbdev;
diff --git a/queue-2.6.37/drm-radeon-kms-prefer-legacy-pll-algo-for-tv-out.patch b/queue-2.6.37/drm-radeon-kms-prefer-legacy-pll-algo-for-tv-out.patch
new file mode 100644 (file)
index 0000000..99b4320
--- /dev/null
@@ -0,0 +1,38 @@
+From 64146f8b2af1ba77fe3c21d9d6d7213b9bb72b40 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexdeucher@gmail.com>
+Date: Tue, 22 Mar 2011 01:46:12 -0400
+Subject: drm/radeon/kms: prefer legacy pll algo for tv-out
+
+From: Alex Deucher <alexdeucher@gmail.com>
+
+commit 64146f8b2af1ba77fe3c21d9d6d7213b9bb72b40 upstream.
+
+ntsc seems to work fine with either algo, some
+pal TVs seem pickier.
+
+Fixes:
+https://bugzilla.kernel.org/show_bug.cgi?id=30832
+
+Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/gpu/drm/radeon/atombios_crtc.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/radeon/atombios_crtc.c
++++ b/drivers/gpu/drm/radeon/atombios_crtc.c
+@@ -921,7 +921,11 @@ static void atombios_crtc_set_pll(struct
+       /* adjust pixel clock as needed */
+       adjusted_clock = atombios_adjust_pll(crtc, mode, pll, ss_enabled, &ss);
+-      if (ASIC_IS_AVIVO(rdev))
++      if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
++              /* TV seems to prefer the legacy algo on some boards */
++              radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
++                                        &ref_div, &post_div);
++      else if (ASIC_IS_AVIVO(rdev))
+               radeon_compute_pll_avivo(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
+                                        &ref_div, &post_div);
+       else
diff --git a/queue-2.6.37/perf-fix-tear-down-of-inherited-group-events.patch b/queue-2.6.37/perf-fix-tear-down-of-inherited-group-events.patch
new file mode 100644 (file)
index 0000000..5192b15
--- /dev/null
@@ -0,0 +1,51 @@
+From 38b435b16c36b0d863efcf3f07b34a6fac9873fd Mon Sep 17 00:00:00 2001
+From: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Date: Tue, 15 Mar 2011 14:37:10 +0100
+Subject: perf: Fix tear-down of inherited group events
+
+From: Peter Zijlstra <a.p.zijlstra@chello.nl>
+
+commit 38b435b16c36b0d863efcf3f07b34a6fac9873fd upstream.
+
+When destroying inherited events, we need to destroy groups too,
+otherwise the event iteration in perf_event_exit_task_context() will
+miss group siblings and we leak events with all the consequences.
+
+Reported-and-tested-by: Vince Weaver <vweaver1@eecs.utk.edu>
+Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
+LKML-Reference: <1300196470.2203.61.camel@twins>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ kernel/perf_event.c |   13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+--- a/kernel/perf_event.c
++++ b/kernel/perf_event.c
+@@ -5863,17 +5863,20 @@ __perf_event_exit_task(struct perf_event
+                        struct perf_event_context *child_ctx,
+                        struct task_struct *child)
+ {
+-      struct perf_event *parent_event;
++      if (child_event->parent) {
++              raw_spin_lock_irq(&child_ctx->lock);
++              perf_group_detach(child_event);
++              raw_spin_unlock_irq(&child_ctx->lock);
++      }
+       perf_event_remove_from_context(child_event);
+-      parent_event = child_event->parent;
+       /*
+-       * It can happen that parent exits first, and has events
++       * It can happen that the parent exits first, and has events
+        * that are still around due to the child reference. These
+-       * events need to be zapped - but otherwise linger.
++       * events need to be zapped.
+        */
+-      if (parent_event) {
++      if (child_event->parent) {
+               sync_child_event(child_event, child);
+               free_event(child_event);
+       }
index 6f5a0a7784c35db9a8154d9a79a3eb547e017883..07c5ffe684bf79da7dba7e7fd67782924f7401c9 100644 (file)
@@ -42,3 +42,9 @@ usb-cdc-acm-fix-potential-null-pointer-dereference-on-disconnect.patch
 fs-assign-sb-s_bdi-to-default_backing_dev_info-if-the-bdi-is-going-away.patch
 input-xen-kbdfront-advertise-either-absolute-or-relative-coordinates.patch
 x86-cleanup-highmap-after-brk-is-concluded.patch
+drm-check-for-modesetting-on-modeset-ioctls.patch
+drm-i915-prevent-racy-removal-of-request-from-client-list.patch
+drm-fix-use-after-free-in-drm_gem_vm_close.patch
+drm-radeon-kms-prefer-legacy-pll-algo-for-tv-out.patch
+drm-radeon-kms-fix-hardcoded-edid-handling.patch
+perf-fix-tear-down-of-inherited-group-events.patch