~ubuntu-branches/ubuntu/raring/linux-ti-omap4/raring-proposed

« back to all changes in this revision

Viewing changes to ubuntu/i915/i915_gem_execbuffer.c

  • Committer: Package Import Robot
  • Author(s): Paolo Pisati, Paolo Pisati, Ubuntu: 3.5.0-20.31
  • Date: 2012-12-06 14:14:29 UTC
  • Revision ID: package-import@ubuntu.com-20121206141429-3f6mmypbjdmnmm2t
Tags: 3.5.0-216.23
* Release Tracking Bug
  - LP: #1087216

[ Paolo Pisati ]

* rebased on Ubuntu-3.5.0-20.31

[ Ubuntu: 3.5.0-20.31 ]

* Release Tracking Bug
  - LP: #1086759
* SAUCE: i915_hsw: Include #define I915_PARAM_HAS_WAIT_TIMEOUT
  - LP: #1085245
* SAUCE: i915_hsw: Include #define DRM_I915_GEM_CONTEXT_[CREATE,DESTROY]
  - LP: #1085245
* SAUCE: i915_hsw: drm/i915: add register read IOCTL
  - LP: #1085245
* SAUCE: i915_hsw: Include #define i915_execbuffer2_[set,get]_context_id
  - LP: #1085245
* SAUCE: i915_hsw: Include #define I915_GEM_PARAM_HAS_SEMAPHORES
  - LP: #1085245
* SAUCE: i915_hsw: Include #define I915_PARAM_HAS_SECURE_BATCHES
  - LP: #1085245
* SAUCE: i915_hsw: drm/i915: call intel_enable_gtt
  - LP: #1085245
* SAUCE: i915_hsw: drm: add helper to sort panels to the head of the
  connector list
  - LP: #1085245
* SAUCE: i915_hsw: drm: extract dp link bw helpers
  - LP: #1085245
* SAUCE: i915_hsw: drm: extract drm_dp_max_lane_count helper
  - LP: #1085245
* SAUCE: i915_hsw: drm: dp helper: extract drm_dp_channel_eq_ok
  - LP: #1085245
* SAUCE: i915_hsw: drm: extract helpers to compute new training values
  from sink request
  - LP: #1085245
* SAUCE: i915_hsw: drm: dp helper: extract drm_dp_clock_recovery_ok
  - LP: #1085245
* SAUCE: i915_hsw: Include #define I915_PARAM_HAS_PRIME_VMAP_FLUSH
  - LP: #1085245
* SAUCE: i915_hsw: Provide an ubuntu/i915 driver for Haswell graphics
  - LP: #1085245
* SAUCE: i915_hsw: Revert "drm: Make the .mode_fixup() operations mode
  argument a const pointer" for ubuntu/i915 driver
  - LP: #1085245
* SAUCE: i915_hsw: Rename ubuntu/i915 driver i915_hsw
  - LP: #1085245
* SAUCE: i915_hsw: Only support Haswell with ubuntu/i915 driver
  - LP: #1085245
* SAUCE: i915_hsw: Include #define DRM_I915_GEM_WAIT
  - LP: #1085245
* SAUCE: i915_hsw: drm: extract dp link train delay functions from radeon
  - LP: #1085245
* SAUCE: i915_hsw: drm/dp: Update DPCD defines
  - LP: #1085245
* SAUCE: i915_hsw: Update intel_ips.h file location
  - LP: #1085245
* SAUCE: i915_hsw: Provide updated drm_mm.h and drm_mm.c for ubuntu/i915
  - LP: #1085245
* SAUCE: i915_hsw: drm/i915: Replace the array of pages with a
  scatterlist
  - LP: #1085245
* SAUCE: i915_hsw: drm/i915: Replace the array of pages with a
  scatterlist
  - LP: #1085245
* SAUCE: i915_hsw: drm/i915: Stop using AGP layer for GEN6+
  - LP: #1085245
* SAUCE: i915_hsw: Add i915_hsw_gpu_*() calls for ubuntu/i915
  - LP: #1085245
* i915_hsw: [Config] Enable CONFIG_DRM_I915_HSW=m
  - LP: #1085245
* SAUCE: drm/i915: fix hsw_fdi_link_train "retry" code
  - LP: #1085245
* SAUCE: drm/i915: reject modes the LPT FDI receiver can't handle
  - LP: #1085245
* SAUCE: drm/i915: add support for mPHY destination on intel_sbi_{read,
  write}
  - LP: #1085245
* SAUCE: drm/i915: add lpt_init_pch_refclk
  - LP: #1085245
* SAUCE: drm/i915: set the LPT FDI RX polarity reversal bit when needed
  - LP: #1085245
* Revert "SAUCE: SECCOMP: audit: always report seccomp violations"
  - LP: #1079469
* Revert "cgroup: Drop task_lock(parent) on cgroup_fork()"
  - LP: #1084539
* Revert "cgroup: Remove task_lock() from cgroup_post_fork()"
  - LP: #1084539
* Revert "x86/mm: Fix the size calculation of mapping tables"
  - LP: #1084539
* Revert "SUNRPC: Ensure we close the socket on EPIPE errors too..."
  - LP: #1084539
* Revert "ath9k_hw: Updated AR9003 tx gain table for 5GHz"
  - LP: #1084539
* Revert "sched: Add missing call to calc_load_exit_idle()"
  - LP: #1084539
* net: fix secpath kmemleak
  - LP: #1065434
* seccomp: forcing auditing of kill condition
  - LP: #1079469
* e1000e: add device IDs for i218
  - LP: #1081796
* bonding: Bonding driver does not consider the gso_max_size/gso_max_segs
  setting of slave devices.
  - LP: #1078184
* mm/hotplug: correctly add new zone to all other nodes' zone lists
  - LP: #1079860
  - CVE-2012-5517
* xen: enable platform-pci only in a Xen guest
  - LP: #1081054
* udf: fix retun value on error path in udf_load_logicalvol
  - LP: #1084539
* usb: gadget: at91_udc: fix dt support
  - LP: #1084539
* netfilter: nf_nat_sip: fix incorrect handling of EBUSY for RTCP
  expectation
  - LP: #1084539
* netfilter: nf_nat_sip: fix via header translation with multiple
  parameters
  - LP: #1084539
* netfilter: nf_ct_expect: fix possible access to uninitialized timer
  - LP: #1084539
* netfilter: xt_limit: have r->cost != 0 case work
  - LP: #1084539
* netfilter: nf_conntrack: fix racy timer handling with reliable events
  - LP: #1084539
* netfilter: nfnetlink_log: fix NLA_PUT macro removal bug
  - LP: #1084539
* MIPS: ath79: Fix CPU/DDR frequency calculation for SRIF PLLs
  - LP: #1084539
* jbd: Fix assertion failure in commit code due to lacking transaction
  credits
  - LP: #1084539
* nfsd4: fix nfs4 stateid leak
  - LP: #1084539
* NFSD: pass null terminated buf to kstrtouint()
  - LP: #1084539
* mfd: 88pm860x: Move _IO resources out of ioport_ioresource
  - LP: #1084539
* target: support zero allocation length in INQUIRY
  - LP: #1084539
* target: fix truncation of mode data, support zero allocation length
  - LP: #1084539
* target: fix return code in target_core_init_configfs error path
  - LP: #1084539
* powerpc/eeh: Lock module while handling EEH event
  - LP: #1084539
* SUNRPC: Ensure that the TCP socket is closed when in CLOSE_WAIT
  - LP: #1084539
* ext4: remove erroneous ext4_superblock_csum_set() in update_backups()
  - LP: #1084539
* block: remove the duplicated setting for congestion_threshold
  - LP: #1084539
* block: lift the initial queue bypass mode on blk_register_queue()
  instead of blk_init_allocated_queue()
  - LP: #1084539
* block: fix request_queue->flags initialization
  - LP: #1084539
* viafb: don't touch clock state on OLPC XO-1.5
  - LP: #1084539
* qla2xxx: Fix endianness of task management response code
  - LP: #1084539
* iscsi-target: Correctly set 0xffffffff field within ISCSI_OP_REJECT PDU
  - LP: #1084539
* drm/i915: use adjusted_mode instead of mode for checking the 6bpc force
  flag
  - LP: #1084539
* kbuild: Do not package /boot and /lib in make tar-pkg
  - LP: #1084539
* module: taint kernel when lve module is loaded
  - LP: #1084539
* mtd: nand: allow NAND_NO_SUBPAGE_WRITE to be set from driver
  - LP: #1084539
* nfsd4: don't pin clientids to pseudoflavors
  - LP: #1084539
* lockd: use rpc client's cl_nodename for id encoding
  - LP: #1084539
* pnfsblock: fix partial page buffer wirte
  - LP: #1084539
* pnfsblock: fix non-aligned DIO read
  - LP: #1084539
* pnfsblock: fix non-aligned DIO write
  - LP: #1084539
* target/file: Re-enable optional fd_buffered_io=1 operation
  - LP: #1084539
* iscsi-target: Add explicit set of cache_dynamic_acls=1 for TPG
  demo-mode
  - LP: #1084539
* iscsit: remove incorrect unlock in iscsit_build_sendtargets_resp
  - LP: #1084539
* iscsi-target: Bump defaults for nopin_timeout + nopin_response_timeout
  values
  - LP: #1084539
* drivers/dma/dmaengine.c: lower the priority of 'failed to get' dma
  channel message
  - LP: #1084539
* ath9k: use ieee80211_free_txskb
  - LP: #1084539
* ALSA: hda - Fix hang caused by race during suspend.
  - LP: #1084539
* ACPI: EC: Make the GPE storm threshold a module parameter
  - LP: #1084539
* ACPI: EC: Add a quirk for CLEVO M720T/M730T laptop
  - LP: #1084539
* mmc: sdhci-s3c: fix the wrong number of max bus clocks
  - LP: #1084539
* mac80211: use ieee80211_free_txskb to fix possible skb leaks
  - LP: #1084539
* ARM: OMAP: counter: add locking to read_persistent_clock
  - LP: #1084539
* ARM: vfp: fix saving d16-d31 vfp registers on v6+ kernels
  - LP: #1084539
* scsi_debug: Fix off-by-one bug when unmapping region
  - LP: #1084539
* storvsc: Account for in-transit packets in the RESET path
  - LP: #1084539
* firewire: cdev: fix user memory corruption (i386 userland on amd64
  kernel)
  - LP: #1084539
* timers: Fix endless looping between cascade() and internal_add_timer()
  - LP: #1084539
* timekeeping: Cast raw_interval to u64 to avoid shift overflow
  - LP: #1084539
* video/udlfb: fix line counting in fb_write
  - LP: #1084539
* tmpfs,ceph,gfs2,isofs,reiserfs,xfs: fix fh_len checking
  - LP: #1084539
* ALSA: hda - Add missing hda_gen_spec to struct via_spec
  - LP: #1084539
* ALSA: hda - Fix memory leaks at error path in patch_cirrus.c
  - LP: #1084539
* autofs4 - fix reset pending flag on mount fail
  - LP: #1084539
* pktgen: fix crash when generating IPv6 packets
  - LP: #1084539
* md/raid10: use correct limit variable
  - LP: #1084539
* mips,kgdb: fix recursive page fault with CONFIG_KPROBES
  - LP: #1084539
* kdb,vt_console: Fix missed data due to pager overruns
  - LP: #1084539
* xen/bootup: allow read_tscp call for Xen PV guests.
  - LP: #1084539
* xen/bootup: allow {read|write}_cr8 pvops call.
  - LP: #1084539
* libceph: eliminate connection state "DEAD"
  - LP: #1084539
* libceph: kill bad_proto ceph connection op
  - LP: #1084539
* libceph: rename socket callbacks
  - LP: #1084539
* libceph: rename kvec_reset and kvec_add functions
  - LP: #1084539
* libceph: embed ceph messenger structure in ceph_client
  - LP: #1084539
* libceph: start separating connection flags from state
  - LP: #1084539
* libceph: start tracking connection socket state
  - LP: #1084539
* libceph: provide osd number when creating osd
  - LP: #1084539
* libceph: set CLOSED state bit in con_init
  - LP: #1084539
* libceph: embed ceph connection structure in mon_client
  - LP: #1084539
* libceph: drop connection refcounting for mon_client
  - LP: #1084539
* libceph: init monitor connection when opening
  - LP: #1084539
* libceph: fully initialize connection in con_init()
  - LP: #1084539
* libceph: tweak ceph_alloc_msg()
  - LP: #1084539
* libceph: have messages point to their connection
  - LP: #1084539
* libceph: have messages take a connection reference
  - LP: #1084539
* libceph: make ceph_con_revoke() a msg operation
  - LP: #1084539
* libceph: make ceph_con_revoke_message() a msg op
  - LP: #1084539
* libceph: fix overflow in __decode_pool_names()
  - LP: #1084539
* libceph: fix overflow in osdmap_decode()
  - LP: #1084539
* libceph: fix overflow in osdmap_apply_incremental()
  - LP: #1084539
* libceph: transition socket state prior to actual connect
  - LP: #1084539
* libceph: fix NULL dereference in reset_connection()
  - LP: #1084539
* libceph: use con get/put methods
  - LP: #1084539
* libceph: drop ceph_con_get/put helpers and nref member
  - LP: #1084539
* libceph: encapsulate out message data setup
  - LP: #1084539
* libceph: encapsulate advancing msg page
  - LP: #1084539
* libceph: don't mark footer complete before it is
  - LP: #1084539
* libceph: move init_bio_*() functions up
  - LP: #1084539
* libceph: move init of bio_iter
  - LP: #1084539
* libceph: don't use bio_iter as a flag
  - LP: #1084539
* libceph: SOCK_CLOSED is a flag, not a state
  - LP: #1084539
* libceph: don't change socket state on sock event
  - LP: #1084539
* libceph: just set SOCK_CLOSED when state changes
  - LP: #1084539
* libceph: don't touch con state in con_close_socket()
  - LP: #1084539
* libceph: clear CONNECTING in ceph_con_close()
  - LP: #1084539
* libceph: clear NEGOTIATING when done
  - LP: #1084539
* libceph: define and use an explicit CONNECTED state
  - LP: #1084539
* libceph: separate banner and connect writes
  - LP: #1084539
* libceph: distinguish two phases of connect sequence
  - LP: #1084539
* libceph: small changes to messenger.c
  - LP: #1084539
* libceph: add some fine ASCII art
  - LP: #1084539
* libceph: set peer name on con_open, not init
  - LP: #1084539
* libceph: initialize mon_client con only once
  - LP: #1084539
* libceph: allow sock transition from CONNECTING to CLOSED
  - LP: #1084539
* libceph: initialize msgpool message types
  - LP: #1084539
* libceph: prevent the race of incoming work during teardown
  - LP: #1084539
* libceph: report socket read/write error message
  - LP: #1084539
* libceph: fix mutex coverage for ceph_con_close
  - LP: #1084539
* libceph: resubmit linger ops when pg mapping changes
  - LP: #1084539
* libceph: (re)initialize bio_iter on start of message receive
  - LP: #1084539
* libceph: protect ceph_con_open() with mutex
  - LP: #1084539
* libceph: reset connection retry on successfully negotiation
  - LP: #1084539
* libceph: fix fault locking; close socket on lossy fault
  - LP: #1084539
* libceph: move msgr clear_standby under con mutex protection
  - LP: #1084539
* libceph: move ceph_con_send() closed check under the con mutex
  - LP: #1084539
* libceph: drop gratuitous socket close calls in con_work
  - LP: #1084539
* libceph: close socket directly from ceph_con_close()
  - LP: #1084539
* libceph: drop unnecessary CLOSED check in socket state change callback
  - LP: #1084539
* libceph: replace connection state bits with states
  - LP: #1084539
* libceph: clean up con flags
  - LP: #1084539
* libceph: clear all flags on con_close
  - LP: #1084539
* libceph: fix handling of immediate socket connect failure
  - LP: #1084539
* libceph: revoke mon_client messages on session restart
  - LP: #1084539
* libceph: verify state after retaking con lock after dispatch
  - LP: #1084539
* libceph: avoid dropping con mutex before fault
  - LP: #1084539
* libceph: change ceph_con_in_msg_alloc convention to be less weird
  - LP: #1084539
* libceph: recheck con state after allocating incoming message
  - LP: #1084539
* libceph: fix crypto key null deref, memory leak
  - LP: #1084539
* libceph: delay debugfs initialization until we learn global_id
  - LP: #1084539
* libceph: avoid truncation due to racing banners
  - LP: #1084539
* libceph: only kunmap kmapped pages
  - LP: #1084539
* rbd: reset BACKOFF if unable to re-queue
  - LP: #1084539
* libceph: avoid NULL kref_put when osd reset races with alloc_msg
  - LP: #1084539
* ceph: fix dentry reference leak in encode_fh()
  - LP: #1084539
* ceph: Fix oops when handling mdsmap that decreases max_mds
  - LP: #1084539
* libceph: check for invalid mapping
  - LP: #1084539
* ceph: avoid 32-bit page index overflow
  - LP: #1084539
* ASoC: wm2200: Use rev A register patches on rev B
  - LP: #1084539
* ASoC: wm2200: Fix non-inverted OUT2 mute control
  - LP: #1084539
* drm/i915: remove useless BUG_ON which caused a regression in 3.5.
  - LP: #1084539
* USB: Enable LPM after a failed probe.
  - LP: #1084539
* usb: Don't enable LPM if the exit latency is zero.
  - LP: #1084539
* usb: Send Set SEL before enabling parent U1/U2 timeout.
  - LP: #1084539
* ASoC: fsi: don't reschedule DMA from an atomic context
  - LP: #1084539
* drm/i915: Set guardband clipping workaround bit in the right register.
  - LP: #1084539
* pcmcia: sharpsl: don't discard sharpsl_pcmcia_ops
  - LP: #1084539
* hwmon: (coretemp) Add support for Atom CE4110/4150/4170
  - LP: #1084539
* ALSA: hda - Fix registration race of VGA switcheroo
  - LP: #1084539
* usb: dwc3: gadget: fix 'endpoint always busy' bug
  - LP: #1084539
* usb: musb: am35xx: drop spurious unplugging a device
  - LP: #1084539
* drm/radeon: Don't destroy I2C Bus Rec in radeon_ext_tmds_enc_destroy().
  - LP: #1084539
* ALSA: hda - Always check array bounds in alc_get_line_out_pfx
  - LP: #1084539
* NLM: nlm_lookup_file() may return NLMv4-specific error codes
  - LP: #1084539
* x86: Exclude E820_RESERVED regions and memory holes above 4 GB from
  direct mapping.
  - LP: #1084539
* SUNRPC: Prevent kernel stack corruption on long values of flush
  - LP: #1084539
* USB: cdc-acm: fix pipe type of write endpoint
  - LP: #1084539
* usb: acm: fix the computation of the number of data bits
  - LP: #1084539
* usb: host: xhci: New system added for Compliance Mode Patch on
  SN65LVPE502CP
  - LP: #1084539
* USB: option: blacklist net interface on ZTE devices
  - LP: #1084539
* USB: option: add more ZTE devices
  - LP: #1084539
* ext4: race-condition protection for
  ext4_convert_unwritten_extents_endio
  - LP: #1084539
* ext4: fix metadata checksum calculation for the superblock
  - LP: #1084539
* nohz: Fix idle ticks in cpu summary line of /proc/stat
  - LP: #1084539
* ring-buffer: Check for uninitialized cpu buffer before resizing
  - LP: #1084539
* Bluetooth: SMP: Fix setting unknown auth_req bits
  - LP: #1084539
* oprofile, x86: Fix wrapping bug in op_x86_get_ctrl()
  - LP: #1084539
* cfg80211/mac80211: avoid state mishmash on deauth
  - LP: #1084539
* mac80211: check if key has TKIP type before updating IV
  - LP: #1084539
* mac80211: use ieee80211_free_txskb in a few more places
  - LP: #1084539
* bcma: fix unregistration of cores
  - LP: #1084539
* net/wireless: ipw2200: Fix panic occurring in
  ipw_handle_promiscuous_tx()
  - LP: #1084539
* iwlwifi: fix 6000 series channel switch command
  - LP: #1084539
* cgroup: notify_on_release may not be triggered in some cases
  - LP: #1084539
* dt: Document: correct tegra20/30 pinctrl slew-rate name
  - LP: #1084539
* pinctrl: tegra: set low power mode bank width to 2
  - LP: #1084539
* pinctrl: tegra: correct bank for pingroup and drv pingroup
  - LP: #1084539
* s390: fix linker script for 31 bit builds
  - LP: #1084539
* pinctrl: remove mutex lock in groups show
  - LP: #1084539
* xen/x86: don't corrupt %eip when returning from a signal handler
  - LP: #1084539
* ALSA: hda - Fix silent headphone output from Toshiba P200
  - LP: #1084539
* ext4: Checksum the block bitmap properly with bigalloc enabled
  - LP: #1084539
* ARM: 7559/1: smp: switch away from the idmap before updating
  init_mm.mm_count
  - LP: #1084539
* usb hub: send clear_tt_buffer_complete events when canceling TT clear
  work
  - LP: #1084539
* staging: comedi: amplc_pc236: fix invalid register access during detach
  - LP: #1084539
* Staging: android: binder: Fix memory leak on thread/process exit
  - LP: #1084539
* Staging: android: binder: Allow using highmem for binder buffers
  - LP: #1084539
* ext4: Avoid underflow in ext4_trim_fs()
  - LP: #1084539
* cpufreq / powernow-k8: Remove usage of smp_processor_id() in
  preemptible code
  - LP: #1084539
* extcon: Unregister compat class at module unload to fix oops
  - LP: #1084539
* extcon: unregister compat link on cleanup
  - LP: #1084539
* pinctrl: fix missing unlock on error in pinctrl_groups_show()
  - LP: #1084539
* arch/tile: avoid generating .eh_frame information in modules
  - LP: #1084539
* drm/radeon: add some new SI PCI ids
  - LP: #1084539
* drm/radeon: add error output if VM CS fails on cayman
  - LP: #1084539
* xhci: endianness xhci_calculate_intel_u2_timeout
  - LP: #1084539
* xhci: fix integer overflow
  - LP: #1084539
* dmaengine: imx-dma: fix missing unlock on error in imxdma_xfer_desc()
  - LP: #1084539
* x86-64: Fix page table accounting
  - LP: #1084539
* dmaengine: sirf: fix a typo in dma_prep_interleaved
  - LP: #1084539
* dmaengine: sirf: fix a typo in moving running dma_desc to active queue
  - LP: #1084539
* amd64_edac:__amd64_set_scrub_rate(): avoid overindexing scrubrates[]
  - LP: #1084539
* SUNRPC: Clear the connect flag when socket state is TCP_CLOSE_WAIT
  - LP: #1084539
* SUNRPC: Prevent races in xs_abort_connection()
  - LP: #1084539
* SUNRPC: Get rid of the xs_error_report socket callback
  - LP: #1084539
* iommu/tegra: smmu: Fix deadly typo
  - LP: #1084539
* ARM: at91/tc: fix typo in the DT document
  - LP: #1084539
* ARM: at91: at91sam9g10: fix SOC type detection
  - LP: #1084539
* ARM: at91/i2c: change id to let i2c-gpio work
  - LP: #1084539
* b43: Fix oops on unload when firmware not found
  - LP: #1084539
* USB: serial: Fix memory leak in sierra_release()
  - LP: #1084539
* x86, mm: Trim memory in memblock to be page aligned
  - LP: #1084539
* x86, mm: Use memblock memory loop instead of e820_RAM
  - LP: #1084539
* usb-storage: add unusual_devs entry for Casio EX-N1 digital camera
  - LP: #1084539
* Drivers: hv: Cleanup error handling in vmbus_open()
  - LP: #1084539
* sysfs: sysfs_pathname/sysfs_add_one: Use strlcat() instead of strcat()
  - LP: #1084539
* vhost: fix mergeable bufs on BE hosts
  - LP: #1084539
* USB: metro-usb: fix io after disconnect
  - LP: #1084539
* USB: whiteheat: fix memory leak in error path
  - LP: #1084539
* USB: quatech2: fix memory leak in error path
  - LP: #1084539
* USB: quatech2: fix io after disconnect
  - LP: #1084539
* USB: opticon: fix DMA from stack
  - LP: #1084539
* USB: opticon: fix memory leak in error path
  - LP: #1084539
* USB: mct_u232: fix broken close
  - LP: #1084539
* USB: sierra: fix memory leak in attach error path
  - LP: #1084539
* USB: sierra: fix memory leak in probe error path
  - LP: #1084539
* USB: mos7840: fix urb leak at release
  - LP: #1084539
* USB: mos7840: fix port-device leak in error path
  - LP: #1084539
* USB: mos7840: remove NULL-urb submission
  - LP: #1084539
* USB: mos7840: remove invalid disconnect handling
  - LP: #1084539
* ehci: fix Lucid nohandoff pci quirk to be more generic with BIOS
  versions
  - LP: #1084539
* ehci: Add yet-another Lucid nohandoff pci quirk
  - LP: #1084539
* xhci: Fix potential NULL ptr deref in command cancellation.
  - LP: #1084539
* freezer: exec should clear PF_NOFREEZE along with PF_KTHREAD
  - LP: #1084539
* mm: fix XFS oops due to dirty pages without buffers on s390
  - LP: #1084539
* genalloc: stop crashing the system when destroying a pool
  - LP: #1084539
* drivers/rtc/rtc-imxdi.c: add missing spin lock initialization
  - LP: #1084539
* gen_init_cpio: avoid stack overflow when expanding
  - LP: #1084539
* fs/compat_ioctl.c: VIDEO_SET_SPU_PALETTE missing error check
  - LP: #1084539
* qmi_wwan/cdc_ether: move Novatel 551 and E362 to qmi_wwan
  - LP: #1084539
* efi: Defer freeing boot services memory until after ACPI init
  - LP: #1084539
* x86: efi: Turn off efi_enabled after setup on mixed fw/kernel
  - LP: #1082059, #1084539
* target: Re-add explict zeroing of INQUIRY bounce buffer memory
  - LP: #1084539
* ARM: 7566/1: vfp: fix save and restore when running on pre-VFPv3 and
  CONFIG_VFPv3 set
  - LP: #1084539
* libceph: drop declaration of ceph_con_get()
  - LP: #1084539
* x86, mm: Find_early_table_space based on ranges that are actually being
  mapped
  - LP: #1084539
* x86, mm: Undo incorrect revert in arch/x86/mm/init.c
  - LP: #1084539
* Linux 3.5.7.1
  - LP: #1084539
* ALSA: hda - Cirrus: Correctly clear line_out_pins when moving to
  speaker
  - LP: #1076840
* Bluetooth: ath3k: Add support for VAIO VPCEH [0489:e027]
  - LP: #898826
* i915_hsw: drm/i915: Reserve ioctl numbers for set/get_caching
  - LP: #1085245
* i915_hsw: drm: Export drm_probe_ddc()
  - LP: #1085245
* i915_hsw: drm: remove the raw_edid field from struct drm_display_info
  - LP: #1085245
* i915_hsw: drm/i915: fix hsw uncached pte
  - LP: #1085245
* i915_hsw: drm/fb-helper: delay hotplug handling when partially bound
  - LP: #1085245
* i915_hsw: drm/fb helper: don't call drm_crtc_helper_set_config
  - LP: #1085245
* i915_hsw: drm/fb-helper: don't clobber output routing in setup_crtcs
  - LP: #1085245
* i915_hsw: drm/fb helper: don't call drm_helper_connector_dpms directly
  - LP: #1085245
* i915_hsw: drm/edid: Fix potential memory leak in edid_load()
  - LP: #1085245

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright © 2008,2010 Intel Corporation
 
3
 *
 
4
 * Permission is hereby granted, free of charge, to any person obtaining a
 
5
 * copy of this software and associated documentation files (the "Software"),
 
6
 * to deal in the Software without restriction, including without limitation
 
7
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 
8
 * and/or sell copies of the Software, and to permit persons to whom the
 
9
 * Software is furnished to do so, subject to the following conditions:
 
10
 *
 
11
 * The above copyright notice and this permission notice (including the next
 
12
 * paragraph) shall be included in all copies or substantial portions of the
 
13
 * Software.
 
14
 *
 
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 
18
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
19
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 
20
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 
21
 * IN THE SOFTWARE.
 
22
 *
 
23
 * Authors:
 
24
 *    Eric Anholt <eric@anholt.net>
 
25
 *    Chris Wilson <chris@chris-wilson.co.uk>
 
26
 *
 
27
 */
 
28
 
 
29
#include "drmP.h"
 
30
#include "drm.h"
 
31
#include "i915_drm.h"
 
32
#include "i915_drv.h"
 
33
#include "i915_trace.h"
 
34
#include "intel_drv.h"
 
35
#include <linux/dma_remapping.h>
 
36
 
 
37
struct eb_objects {
 
38
        int and;
 
39
        struct hlist_head buckets[0];
 
40
};
 
41
 
 
42
static struct eb_objects *
 
43
eb_create(int size)
 
44
{
 
45
        struct eb_objects *eb;
 
46
        int count = PAGE_SIZE / sizeof(struct hlist_head) / 2;
 
47
        BUILD_BUG_ON(!is_power_of_2(PAGE_SIZE / sizeof(struct hlist_head)));
 
48
        while (count > size)
 
49
                count >>= 1;
 
50
        eb = kzalloc(count*sizeof(struct hlist_head) +
 
51
                     sizeof(struct eb_objects),
 
52
                     GFP_KERNEL);
 
53
        if (eb == NULL)
 
54
                return eb;
 
55
 
 
56
        eb->and = count - 1;
 
57
        return eb;
 
58
}
 
59
 
 
60
static void
 
61
eb_reset(struct eb_objects *eb)
 
62
{
 
63
        memset(eb->buckets, 0, (eb->and+1)*sizeof(struct hlist_head));
 
64
}
 
65
 
 
66
static void
 
67
eb_add_object(struct eb_objects *eb, struct drm_i915_gem_object *obj)
 
68
{
 
69
        hlist_add_head(&obj->exec_node,
 
70
                       &eb->buckets[obj->exec_handle & eb->and]);
 
71
}
 
72
 
 
73
static struct drm_i915_gem_object *
 
74
eb_get_object(struct eb_objects *eb, unsigned long handle)
 
75
{
 
76
        struct hlist_head *head;
 
77
        struct hlist_node *node;
 
78
        struct drm_i915_gem_object *obj;
 
79
 
 
80
        head = &eb->buckets[handle & eb->and];
 
81
        hlist_for_each(node, head) {
 
82
                obj = hlist_entry(node, struct drm_i915_gem_object, exec_node);
 
83
                if (obj->exec_handle == handle)
 
84
                        return obj;
 
85
        }
 
86
 
 
87
        return NULL;
 
88
}
 
89
 
 
90
static void
 
91
eb_destroy(struct eb_objects *eb)
 
92
{
 
93
        kfree(eb);
 
94
}
 
95
 
 
96
static inline int use_cpu_reloc(struct drm_i915_gem_object *obj)
 
97
{
 
98
        return (obj->base.write_domain == I915_GEM_DOMAIN_CPU ||
 
99
                !obj->map_and_fenceable ||
 
100
                obj->cache_level != I915_CACHE_NONE);
 
101
}
 
102
 
 
103
static int
 
104
i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
 
105
                                   struct eb_objects *eb,
 
106
                                   struct drm_i915_gem_relocation_entry *reloc)
 
107
{
 
108
        struct drm_device *dev = obj->base.dev;
 
109
        struct drm_gem_object *target_obj;
 
110
        struct drm_i915_gem_object *target_i915_obj;
 
111
        uint32_t target_offset;
 
112
        int ret = -EINVAL;
 
113
 
 
114
        /* we've already hold a reference to all valid objects */
 
115
        target_obj = &eb_get_object(eb, reloc->target_handle)->base;
 
116
        if (unlikely(target_obj == NULL))
 
117
                return -ENOENT;
 
118
 
 
119
        target_i915_obj = to_intel_bo(target_obj);
 
120
        target_offset = target_i915_obj->gtt_offset;
 
121
 
 
122
        /* Sandybridge PPGTT errata: We need a global gtt mapping for MI and
 
123
         * pipe_control writes because the gpu doesn't properly redirect them
 
124
         * through the ppgtt for non_secure batchbuffers. */
 
125
        if (unlikely(IS_GEN6(dev) &&
 
126
            reloc->write_domain == I915_GEM_DOMAIN_INSTRUCTION &&
 
127
            !target_i915_obj->has_global_gtt_mapping)) {
 
128
                i915_gem_gtt_bind_object(target_i915_obj,
 
129
                                         target_i915_obj->cache_level);
 
130
        }
 
131
 
 
132
        /* Validate that the target is in a valid r/w GPU domain */
 
133
        if (unlikely(reloc->write_domain & (reloc->write_domain - 1))) {
 
134
                DRM_DEBUG("reloc with multiple write domains: "
 
135
                          "obj %p target %d offset %d "
 
136
                          "read %08x write %08x",
 
137
                          obj, reloc->target_handle,
 
138
                          (int) reloc->offset,
 
139
                          reloc->read_domains,
 
140
                          reloc->write_domain);
 
141
                return ret;
 
142
        }
 
143
        if (unlikely((reloc->write_domain | reloc->read_domains)
 
144
                     & ~I915_GEM_GPU_DOMAINS)) {
 
145
                DRM_DEBUG("reloc with read/write non-GPU domains: "
 
146
                          "obj %p target %d offset %d "
 
147
                          "read %08x write %08x",
 
148
                          obj, reloc->target_handle,
 
149
                          (int) reloc->offset,
 
150
                          reloc->read_domains,
 
151
                          reloc->write_domain);
 
152
                return ret;
 
153
        }
 
154
        if (unlikely(reloc->write_domain && target_obj->pending_write_domain &&
 
155
                     reloc->write_domain != target_obj->pending_write_domain)) {
 
156
                DRM_DEBUG("Write domain conflict: "
 
157
                          "obj %p target %d offset %d "
 
158
                          "new %08x old %08x\n",
 
159
                          obj, reloc->target_handle,
 
160
                          (int) reloc->offset,
 
161
                          reloc->write_domain,
 
162
                          target_obj->pending_write_domain);
 
163
                return ret;
 
164
        }
 
165
 
 
166
        target_obj->pending_read_domains |= reloc->read_domains;
 
167
        target_obj->pending_write_domain |= reloc->write_domain;
 
168
 
 
169
        /* If the relocation already has the right value in it, no
 
170
         * more work needs to be done.
 
171
         */
 
172
        if (target_offset == reloc->presumed_offset)
 
173
                return 0;
 
174
 
 
175
        /* Check that the relocation address is valid... */
 
176
        if (unlikely(reloc->offset > obj->base.size - 4)) {
 
177
                DRM_DEBUG("Relocation beyond object bounds: "
 
178
                          "obj %p target %d offset %d size %d.\n",
 
179
                          obj, reloc->target_handle,
 
180
                          (int) reloc->offset,
 
181
                          (int) obj->base.size);
 
182
                return ret;
 
183
        }
 
184
        if (unlikely(reloc->offset & 3)) {
 
185
                DRM_DEBUG("Relocation not 4-byte aligned: "
 
186
                          "obj %p target %d offset %d.\n",
 
187
                          obj, reloc->target_handle,
 
188
                          (int) reloc->offset);
 
189
                return ret;
 
190
        }
 
191
 
 
192
        /* We can't wait for rendering with pagefaults disabled */
 
193
        if (obj->active && in_atomic())
 
194
                return -EFAULT;
 
195
 
 
196
        reloc->delta += target_offset;
 
197
        if (use_cpu_reloc(obj)) {
 
198
                uint32_t page_offset = reloc->offset & ~PAGE_MASK;
 
199
                char *vaddr;
 
200
 
 
201
                ret = i915_gem_object_set_to_cpu_domain(obj, 1);
 
202
                if (ret)
 
203
                        return ret;
 
204
 
 
205
                vaddr = kmap_atomic(i915_gem_object_get_page(obj,
 
206
                                                             reloc->offset >> PAGE_SHIFT));
 
207
                *(uint32_t *)(vaddr + page_offset) = reloc->delta;
 
208
                kunmap_atomic(vaddr);
 
209
        } else {
 
210
                struct drm_i915_private *dev_priv = dev->dev_private;
 
211
                uint32_t __iomem *reloc_entry;
 
212
                void __iomem *reloc_page;
 
213
 
 
214
                ret = i915_gem_object_set_to_gtt_domain(obj, true);
 
215
                if (ret)
 
216
                        return ret;
 
217
 
 
218
                ret = i915_gem_object_put_fence(obj);
 
219
                if (ret)
 
220
                        return ret;
 
221
 
 
222
                /* Map the page containing the relocation we're going to perform.  */
 
223
                reloc->offset += obj->gtt_offset;
 
224
                reloc_page = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping,
 
225
                                                      reloc->offset & PAGE_MASK);
 
226
                reloc_entry = (uint32_t __iomem *)
 
227
                        (reloc_page + (reloc->offset & ~PAGE_MASK));
 
228
                iowrite32(reloc->delta, reloc_entry);
 
229
                io_mapping_unmap_atomic(reloc_page);
 
230
        }
 
231
 
 
232
        /* and update the user's relocation entry */
 
233
        reloc->presumed_offset = target_offset;
 
234
 
 
235
        return 0;
 
236
}
 
237
 
 
238
static int
 
239
i915_gem_execbuffer_relocate_object(struct drm_i915_gem_object *obj,
 
240
                                    struct eb_objects *eb)
 
241
{
 
242
#define N_RELOC(x) ((x) / sizeof(struct drm_i915_gem_relocation_entry))
 
243
        struct drm_i915_gem_relocation_entry stack_reloc[N_RELOC(512)];
 
244
        struct drm_i915_gem_relocation_entry __user *user_relocs;
 
245
        struct drm_i915_gem_exec_object2 *entry = obj->exec_entry;
 
246
        int remain, ret;
 
247
 
 
248
        user_relocs = (void __user *)(uintptr_t)entry->relocs_ptr;
 
249
 
 
250
        remain = entry->relocation_count;
 
251
        while (remain) {
 
252
                struct drm_i915_gem_relocation_entry *r = stack_reloc;
 
253
                int count = remain;
 
254
                if (count > ARRAY_SIZE(stack_reloc))
 
255
                        count = ARRAY_SIZE(stack_reloc);
 
256
                remain -= count;
 
257
 
 
258
                if (__copy_from_user_inatomic(r, user_relocs, count*sizeof(r[0])))
 
259
                        return -EFAULT;
 
260
 
 
261
                do {
 
262
                        u64 offset = r->presumed_offset;
 
263
 
 
264
                        ret = i915_gem_execbuffer_relocate_entry(obj, eb, r);
 
265
                        if (ret)
 
266
                                return ret;
 
267
 
 
268
                        if (r->presumed_offset != offset &&
 
269
                            __copy_to_user_inatomic(&user_relocs->presumed_offset,
 
270
                                                    &r->presumed_offset,
 
271
                                                    sizeof(r->presumed_offset))) {
 
272
                                return -EFAULT;
 
273
                        }
 
274
 
 
275
                        user_relocs++;
 
276
                        r++;
 
277
                } while (--count);
 
278
        }
 
279
 
 
280
        return 0;
 
281
#undef N_RELOC
 
282
}
 
283
 
 
284
static int
 
285
i915_gem_execbuffer_relocate_object_slow(struct drm_i915_gem_object *obj,
 
286
                                         struct eb_objects *eb,
 
287
                                         struct drm_i915_gem_relocation_entry *relocs)
 
288
{
 
289
        const struct drm_i915_gem_exec_object2 *entry = obj->exec_entry;
 
290
        int i, ret;
 
291
 
 
292
        for (i = 0; i < entry->relocation_count; i++) {
 
293
                ret = i915_gem_execbuffer_relocate_entry(obj, eb, &relocs[i]);
 
294
                if (ret)
 
295
                        return ret;
 
296
        }
 
297
 
 
298
        return 0;
 
299
}
 
300
 
 
301
static int
 
302
i915_gem_execbuffer_relocate(struct drm_device *dev,
 
303
                             struct eb_objects *eb,
 
304
                             struct list_head *objects)
 
305
{
 
306
        struct drm_i915_gem_object *obj;
 
307
        int ret = 0;
 
308
 
 
309
        /* This is the fast path and we cannot handle a pagefault whilst
 
310
         * holding the struct mutex lest the user pass in the relocations
 
311
         * contained within a mmaped bo. For in such a case we, the page
 
312
         * fault handler would call i915_gem_fault() and we would try to
 
313
         * acquire the struct mutex again. Obviously this is bad and so
 
314
         * lockdep complains vehemently.
 
315
         */
 
316
        pagefault_disable();
 
317
        list_for_each_entry(obj, objects, exec_list) {
 
318
                ret = i915_gem_execbuffer_relocate_object(obj, eb);
 
319
                if (ret)
 
320
                        break;
 
321
        }
 
322
        pagefault_enable();
 
323
 
 
324
        return ret;
 
325
}
 
326
 
 
327
#define  __EXEC_OBJECT_HAS_PIN (1<<31)
 
328
#define  __EXEC_OBJECT_HAS_FENCE (1<<30)
 
329
 
 
330
static int
 
331
need_reloc_mappable(struct drm_i915_gem_object *obj)
 
332
{
 
333
        struct drm_i915_gem_exec_object2 *entry = obj->exec_entry;
 
334
        return entry->relocation_count && !use_cpu_reloc(obj);
 
335
}
 
336
 
 
337
static int
 
338
i915_gem_execbuffer_reserve_object(struct drm_i915_gem_object *obj,
 
339
                                   struct intel_ring_buffer *ring)
 
340
{
 
341
        struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
 
342
        struct drm_i915_gem_exec_object2 *entry = obj->exec_entry;
 
343
        bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4;
 
344
        bool need_fence, need_mappable;
 
345
        int ret;
 
346
 
 
347
        need_fence =
 
348
                has_fenced_gpu_access &&
 
349
                entry->flags & EXEC_OBJECT_NEEDS_FENCE &&
 
350
                obj->tiling_mode != I915_TILING_NONE;
 
351
        need_mappable = need_fence || need_reloc_mappable(obj);
 
352
 
 
353
        ret = i915_gem_object_pin(obj, entry->alignment, need_mappable, false);
 
354
        if (ret)
 
355
                return ret;
 
356
 
 
357
        entry->flags |= __EXEC_OBJECT_HAS_PIN;
 
358
 
 
359
        if (has_fenced_gpu_access) {
 
360
                if (entry->flags & EXEC_OBJECT_NEEDS_FENCE) {
 
361
                        ret = i915_gem_object_get_fence(obj);
 
362
                        if (ret)
 
363
                                return ret;
 
364
 
 
365
                        if (i915_gem_object_pin_fence(obj))
 
366
                                entry->flags |= __EXEC_OBJECT_HAS_FENCE;
 
367
 
 
368
                        obj->pending_fenced_gpu_access = true;
 
369
                }
 
370
        }
 
371
 
 
372
        /* Ensure ppgtt mapping exists if needed */
 
373
        if (dev_priv->mm.aliasing_ppgtt && !obj->has_aliasing_ppgtt_mapping) {
 
374
                i915_ppgtt_bind_object(dev_priv->mm.aliasing_ppgtt,
 
375
                                       obj, obj->cache_level);
 
376
 
 
377
                obj->has_aliasing_ppgtt_mapping = 1;
 
378
        }
 
379
 
 
380
        entry->offset = obj->gtt_offset;
 
381
        return 0;
 
382
}
 
383
 
 
384
static void
 
385
i915_gem_execbuffer_unreserve_object(struct drm_i915_gem_object *obj)
 
386
{
 
387
        struct drm_i915_gem_exec_object2 *entry;
 
388
 
 
389
        if (!obj->gtt_space)
 
390
                return;
 
391
 
 
392
        entry = obj->exec_entry;
 
393
 
 
394
        if (entry->flags & __EXEC_OBJECT_HAS_FENCE)
 
395
                i915_gem_object_unpin_fence(obj);
 
396
 
 
397
        if (entry->flags & __EXEC_OBJECT_HAS_PIN)
 
398
                i915_gem_object_unpin(obj);
 
399
 
 
400
        entry->flags &= ~(__EXEC_OBJECT_HAS_FENCE | __EXEC_OBJECT_HAS_PIN);
 
401
}
 
402
 
 
403
static int
 
404
i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring,
 
405
                            struct drm_file *file,
 
406
                            struct list_head *objects)
 
407
{
 
408
        struct drm_i915_gem_object *obj;
 
409
        struct list_head ordered_objects;
 
410
        bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4;
 
411
        int retry;
 
412
 
 
413
        INIT_LIST_HEAD(&ordered_objects);
 
414
        while (!list_empty(objects)) {
 
415
                struct drm_i915_gem_exec_object2 *entry;
 
416
                bool need_fence, need_mappable;
 
417
 
 
418
                obj = list_first_entry(objects,
 
419
                                       struct drm_i915_gem_object,
 
420
                                       exec_list);
 
421
                entry = obj->exec_entry;
 
422
 
 
423
                need_fence =
 
424
                        has_fenced_gpu_access &&
 
425
                        entry->flags & EXEC_OBJECT_NEEDS_FENCE &&
 
426
                        obj->tiling_mode != I915_TILING_NONE;
 
427
                need_mappable = need_fence || need_reloc_mappable(obj);
 
428
 
 
429
                if (need_mappable)
 
430
                        list_move(&obj->exec_list, &ordered_objects);
 
431
                else
 
432
                        list_move_tail(&obj->exec_list, &ordered_objects);
 
433
 
 
434
                obj->base.pending_read_domains = 0;
 
435
                obj->base.pending_write_domain = 0;
 
436
                obj->pending_fenced_gpu_access = false;
 
437
        }
 
438
        list_splice(&ordered_objects, objects);
 
439
 
 
440
        /* Attempt to pin all of the buffers into the GTT.
 
441
         * This is done in 3 phases:
 
442
         *
 
443
         * 1a. Unbind all objects that do not match the GTT constraints for
 
444
         *     the execbuffer (fenceable, mappable, alignment etc).
 
445
         * 1b. Increment pin count for already bound objects.
 
446
         * 2.  Bind new objects.
 
447
         * 3.  Decrement pin count.
 
448
         *
 
449
         * This avoid unnecessary unbinding of later objects in order to make
 
450
         * room for the earlier objects *unless* we need to defragment.
 
451
         */
 
452
        retry = 0;
 
453
        do {
 
454
                int ret = 0;
 
455
 
 
456
                /* Unbind any ill-fitting objects or pin. */
 
457
                list_for_each_entry(obj, objects, exec_list) {
 
458
                        struct drm_i915_gem_exec_object2 *entry = obj->exec_entry;
 
459
                        bool need_fence, need_mappable;
 
460
 
 
461
                        if (!obj->gtt_space)
 
462
                                continue;
 
463
 
 
464
                        need_fence =
 
465
                                has_fenced_gpu_access &&
 
466
                                entry->flags & EXEC_OBJECT_NEEDS_FENCE &&
 
467
                                obj->tiling_mode != I915_TILING_NONE;
 
468
                        need_mappable = need_fence || need_reloc_mappable(obj);
 
469
 
 
470
                        if ((entry->alignment && obj->gtt_offset & (entry->alignment - 1)) ||
 
471
                            (need_mappable && !obj->map_and_fenceable))
 
472
                                ret = i915_gem_object_unbind(obj);
 
473
                        else
 
474
                                ret = i915_gem_execbuffer_reserve_object(obj, ring);
 
475
                        if (ret)
 
476
                                goto err;
 
477
                }
 
478
 
 
479
                /* Bind fresh objects */
 
480
                list_for_each_entry(obj, objects, exec_list) {
 
481
                        if (obj->gtt_space)
 
482
                                continue;
 
483
 
 
484
                        ret = i915_gem_execbuffer_reserve_object(obj, ring);
 
485
                        if (ret)
 
486
                                goto err;
 
487
                }
 
488
 
 
489
err:            /* Decrement pin count for bound objects */
 
490
                list_for_each_entry(obj, objects, exec_list)
 
491
                        i915_gem_execbuffer_unreserve_object(obj);
 
492
 
 
493
                if (ret != -ENOSPC || retry++)
 
494
                        return ret;
 
495
 
 
496
                ret = i915_gem_evict_everything(ring->dev);
 
497
                if (ret)
 
498
                        return ret;
 
499
        } while (1);
 
500
}
 
501
 
 
502
static int
 
503
i915_gem_execbuffer_relocate_slow(struct drm_device *dev,
 
504
                                  struct drm_file *file,
 
505
                                  struct intel_ring_buffer *ring,
 
506
                                  struct list_head *objects,
 
507
                                  struct eb_objects *eb,
 
508
                                  struct drm_i915_gem_exec_object2 *exec,
 
509
                                  int count)
 
510
{
 
511
        struct drm_i915_gem_relocation_entry *reloc;
 
512
        struct drm_i915_gem_object *obj;
 
513
        int *reloc_offset;
 
514
        int i, total, ret;
 
515
 
 
516
        /* We may process another execbuffer during the unlock... */
 
517
        while (!list_empty(objects)) {
 
518
                obj = list_first_entry(objects,
 
519
                                       struct drm_i915_gem_object,
 
520
                                       exec_list);
 
521
                list_del_init(&obj->exec_list);
 
522
                drm_gem_object_unreference(&obj->base);
 
523
        }
 
524
 
 
525
        mutex_unlock(&dev->struct_mutex);
 
526
 
 
527
        total = 0;
 
528
        for (i = 0; i < count; i++)
 
529
                total += exec[i].relocation_count;
 
530
 
 
531
        reloc_offset = drm_malloc_ab(count, sizeof(*reloc_offset));
 
532
        reloc = drm_malloc_ab(total, sizeof(*reloc));
 
533
        if (reloc == NULL || reloc_offset == NULL) {
 
534
                drm_free_large(reloc);
 
535
                drm_free_large(reloc_offset);
 
536
                mutex_lock(&dev->struct_mutex);
 
537
                return -ENOMEM;
 
538
        }
 
539
 
 
540
        total = 0;
 
541
        for (i = 0; i < count; i++) {
 
542
                struct drm_i915_gem_relocation_entry __user *user_relocs;
 
543
 
 
544
                user_relocs = (void __user *)(uintptr_t)exec[i].relocs_ptr;
 
545
 
 
546
                if (copy_from_user(reloc+total, user_relocs,
 
547
                                   exec[i].relocation_count * sizeof(*reloc))) {
 
548
                        ret = -EFAULT;
 
549
                        mutex_lock(&dev->struct_mutex);
 
550
                        goto err;
 
551
                }
 
552
 
 
553
                reloc_offset[i] = total;
 
554
                total += exec[i].relocation_count;
 
555
        }
 
556
 
 
557
        ret = i915_mutex_lock_interruptible(dev);
 
558
        if (ret) {
 
559
                mutex_lock(&dev->struct_mutex);
 
560
                goto err;
 
561
        }
 
562
 
 
563
        /* reacquire the objects */
 
564
        eb_reset(eb);
 
565
        for (i = 0; i < count; i++) {
 
566
                obj = to_intel_bo(drm_gem_object_lookup(dev, file,
 
567
                                                        exec[i].handle));
 
568
                if (&obj->base == NULL) {
 
569
                        DRM_DEBUG("Invalid object handle %d at index %d\n",
 
570
                                   exec[i].handle, i);
 
571
                        ret = -ENOENT;
 
572
                        goto err;
 
573
                }
 
574
 
 
575
                list_add_tail(&obj->exec_list, objects);
 
576
                obj->exec_handle = exec[i].handle;
 
577
                obj->exec_entry = &exec[i];
 
578
                eb_add_object(eb, obj);
 
579
        }
 
580
 
 
581
        ret = i915_gem_execbuffer_reserve(ring, file, objects);
 
582
        if (ret)
 
583
                goto err;
 
584
 
 
585
        list_for_each_entry(obj, objects, exec_list) {
 
586
                int offset = obj->exec_entry - exec;
 
587
                ret = i915_gem_execbuffer_relocate_object_slow(obj, eb,
 
588
                                                               reloc + reloc_offset[offset]);
 
589
                if (ret)
 
590
                        goto err;
 
591
        }
 
592
 
 
593
        /* Leave the user relocations as are, this is the painfully slow path,
 
594
         * and we want to avoid the complication of dropping the lock whilst
 
595
         * having buffers reserved in the aperture and so causing spurious
 
596
         * ENOSPC for random operations.
 
597
         */
 
598
 
 
599
err:
 
600
        drm_free_large(reloc);
 
601
        drm_free_large(reloc_offset);
 
602
        return ret;
 
603
}
 
604
 
 
605
static int
 
606
i915_gem_execbuffer_wait_for_flips(struct intel_ring_buffer *ring, u32 flips)
 
607
{
 
608
        u32 plane, flip_mask;
 
609
        int ret;
 
610
 
 
611
        /* Check for any pending flips. As we only maintain a flip queue depth
 
612
         * of 1, we can simply insert a WAIT for the next display flip prior
 
613
         * to executing the batch and avoid stalling the CPU.
 
614
         */
 
615
 
 
616
        for (plane = 0; flips >> plane; plane++) {
 
617
                if (((flips >> plane) & 1) == 0)
 
618
                        continue;
 
619
 
 
620
                if (plane)
 
621
                        flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
 
622
                else
 
623
                        flip_mask = MI_WAIT_FOR_PLANE_A_FLIP;
 
624
 
 
625
                ret = intel_ring_begin(ring, 2);
 
626
                if (ret)
 
627
                        return ret;
 
628
 
 
629
                intel_ring_emit(ring, MI_WAIT_FOR_EVENT | flip_mask);
 
630
                intel_ring_emit(ring, MI_NOOP);
 
631
                intel_ring_advance(ring);
 
632
        }
 
633
 
 
634
        return 0;
 
635
}
 
636
 
 
637
static int
 
638
i915_gem_execbuffer_move_to_gpu(struct intel_ring_buffer *ring,
 
639
                                struct list_head *objects)
 
640
{
 
641
        struct drm_i915_gem_object *obj;
 
642
        uint32_t flush_domains = 0;
 
643
        uint32_t flips = 0;
 
644
        int ret;
 
645
 
 
646
        list_for_each_entry(obj, objects, exec_list) {
 
647
                ret = i915_gem_object_sync(obj, ring);
 
648
                if (ret)
 
649
                        return ret;
 
650
 
 
651
                if (obj->base.write_domain & I915_GEM_DOMAIN_CPU)
 
652
                        i915_gem_clflush_object(obj);
 
653
 
 
654
                if (obj->base.pending_write_domain)
 
655
                        flips |= atomic_read(&obj->pending_flip);
 
656
 
 
657
                flush_domains |= obj->base.write_domain;
 
658
        }
 
659
 
 
660
        if (flips) {
 
661
                ret = i915_gem_execbuffer_wait_for_flips(ring, flips);
 
662
                if (ret)
 
663
                        return ret;
 
664
        }
 
665
 
 
666
        if (flush_domains & I915_GEM_DOMAIN_CPU)
 
667
                i915_gem_chipset_flush(ring->dev);
 
668
 
 
669
        if (flush_domains & I915_GEM_DOMAIN_GTT)
 
670
                wmb();
 
671
 
 
672
        /* Unconditionally invalidate gpu caches and ensure that we do flush
 
673
         * any residual writes from the previous batch.
 
674
         */
 
675
        return intel_ring_invalidate_all_caches(ring);
 
676
}
 
677
 
 
678
static bool
 
679
i915_gem_check_execbuffer(struct drm_i915_gem_execbuffer2 *exec)
 
680
{
 
681
        return ((exec->batch_start_offset | exec->batch_len) & 0x7) == 0;
 
682
}
 
683
 
 
684
static int
 
685
validate_exec_list(struct drm_i915_gem_exec_object2 *exec,
 
686
                   int count)
 
687
{
 
688
        int i;
 
689
 
 
690
        for (i = 0; i < count; i++) {
 
691
                char __user *ptr = (char __user *)(uintptr_t)exec[i].relocs_ptr;
 
692
                int length; /* limited by fault_in_pages_readable() */
 
693
 
 
694
                /* First check for malicious input causing overflow */
 
695
                if (exec[i].relocation_count >
 
696
                    INT_MAX / sizeof(struct drm_i915_gem_relocation_entry))
 
697
                        return -EINVAL;
 
698
 
 
699
                length = exec[i].relocation_count *
 
700
                        sizeof(struct drm_i915_gem_relocation_entry);
 
701
                if (!access_ok(VERIFY_READ, ptr, length))
 
702
                        return -EFAULT;
 
703
 
 
704
                /* we may also need to update the presumed offsets */
 
705
                if (!access_ok(VERIFY_WRITE, ptr, length))
 
706
                        return -EFAULT;
 
707
 
 
708
                if (fault_in_multipages_readable(ptr, length))
 
709
                        return -EFAULT;
 
710
        }
 
711
 
 
712
        return 0;
 
713
}
 
714
 
 
715
static void
 
716
i915_gem_execbuffer_move_to_active(struct list_head *objects,
 
717
                                   struct intel_ring_buffer *ring,
 
718
                                   u32 seqno)
 
719
{
 
720
        struct drm_i915_gem_object *obj;
 
721
 
 
722
        list_for_each_entry(obj, objects, exec_list) {
 
723
                u32 old_read = obj->base.read_domains;
 
724
                u32 old_write = obj->base.write_domain;
 
725
 
 
726
                obj->base.read_domains = obj->base.pending_read_domains;
 
727
                obj->base.write_domain = obj->base.pending_write_domain;
 
728
                obj->fenced_gpu_access = obj->pending_fenced_gpu_access;
 
729
 
 
730
                i915_gem_object_move_to_active(obj, ring, seqno);
 
731
                if (obj->base.write_domain) {
 
732
                        obj->dirty = 1;
 
733
                        obj->last_write_seqno = seqno;
 
734
                        if (obj->pin_count) /* check for potential scanout */
 
735
                                intel_mark_fb_busy(obj);
 
736
                }
 
737
 
 
738
                trace_i915_gem_object_change_domain(obj, old_read, old_write);
 
739
        }
 
740
}
 
741
 
 
742
static void
 
743
i915_gem_execbuffer_retire_commands(struct drm_device *dev,
 
744
                                    struct drm_file *file,
 
745
                                    struct intel_ring_buffer *ring)
 
746
{
 
747
        /* Unconditionally force add_request to emit a full flush. */
 
748
        ring->gpu_caches_dirty = true;
 
749
 
 
750
        /* Add a breadcrumb for the completion of the batch buffer */
 
751
        (void)i915_add_request(ring, file, NULL);
 
752
}
 
753
 
 
754
static int
 
755
i915_reset_gen7_sol_offsets(struct drm_device *dev,
 
756
                            struct intel_ring_buffer *ring)
 
757
{
 
758
        drm_i915_private_t *dev_priv = dev->dev_private;
 
759
        int ret, i;
 
760
 
 
761
        if (!IS_GEN7(dev) || ring != &dev_priv->ring[RCS])
 
762
                return 0;
 
763
 
 
764
        ret = intel_ring_begin(ring, 4 * 3);
 
765
        if (ret)
 
766
                return ret;
 
767
 
 
768
        for (i = 0; i < 4; i++) {
 
769
                intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
 
770
                intel_ring_emit(ring, GEN7_SO_WRITE_OFFSET(i));
 
771
                intel_ring_emit(ring, 0);
 
772
        }
 
773
 
 
774
        intel_ring_advance(ring);
 
775
 
 
776
        return 0;
 
777
}
 
778
 
 
779
static int
 
780
i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 
781
                       struct drm_file *file,
 
782
                       struct drm_i915_gem_execbuffer2 *args,
 
783
                       struct drm_i915_gem_exec_object2 *exec)
 
784
{
 
785
        drm_i915_private_t *dev_priv = dev->dev_private;
 
786
        struct list_head objects;
 
787
        struct eb_objects *eb;
 
788
        struct drm_i915_gem_object *batch_obj;
 
789
        struct drm_clip_rect *cliprects = NULL;
 
790
        struct intel_ring_buffer *ring;
 
791
        u32 ctx_id = i915_execbuffer2_get_context_id(*args);
 
792
        u32 exec_start, exec_len;
 
793
        u32 seqno;
 
794
        u32 mask;
 
795
        u32 flags;
 
796
        int ret, mode, i;
 
797
 
 
798
        if (!i915_gem_check_execbuffer(args)) {
 
799
                DRM_DEBUG("execbuf with invalid offset/length\n");
 
800
                return -EINVAL;
 
801
        }
 
802
 
 
803
        ret = validate_exec_list(exec, args->buffer_count);
 
804
        if (ret)
 
805
                return ret;
 
806
 
 
807
        flags = 0;
 
808
        if (args->flags & I915_EXEC_SECURE) {
 
809
                if (!file->is_master || !capable(CAP_SYS_ADMIN))
 
810
                    return -EPERM;
 
811
 
 
812
                flags |= I915_DISPATCH_SECURE;
 
813
        }
 
814
 
 
815
        switch (args->flags & I915_EXEC_RING_MASK) {
 
816
        case I915_EXEC_DEFAULT:
 
817
        case I915_EXEC_RENDER:
 
818
                ring = &dev_priv->ring[RCS];
 
819
                break;
 
820
        case I915_EXEC_BSD:
 
821
                ring = &dev_priv->ring[VCS];
 
822
                if (ctx_id != 0) {
 
823
                        DRM_DEBUG("Ring %s doesn't support contexts\n",
 
824
                                  ring->name);
 
825
                        return -EPERM;
 
826
                }
 
827
                break;
 
828
        case I915_EXEC_BLT:
 
829
                ring = &dev_priv->ring[BCS];
 
830
                if (ctx_id != 0) {
 
831
                        DRM_DEBUG("Ring %s doesn't support contexts\n",
 
832
                                  ring->name);
 
833
                        return -EPERM;
 
834
                }
 
835
                break;
 
836
        default:
 
837
                DRM_DEBUG("execbuf with unknown ring: %d\n",
 
838
                          (int)(args->flags & I915_EXEC_RING_MASK));
 
839
                return -EINVAL;
 
840
        }
 
841
        if (!intel_ring_initialized(ring)) {
 
842
                DRM_DEBUG("execbuf with invalid ring: %d\n",
 
843
                          (int)(args->flags & I915_EXEC_RING_MASK));
 
844
                return -EINVAL;
 
845
        }
 
846
 
 
847
        mode = args->flags & I915_EXEC_CONSTANTS_MASK;
 
848
        mask = I915_EXEC_CONSTANTS_MASK;
 
849
        switch (mode) {
 
850
        case I915_EXEC_CONSTANTS_REL_GENERAL:
 
851
        case I915_EXEC_CONSTANTS_ABSOLUTE:
 
852
        case I915_EXEC_CONSTANTS_REL_SURFACE:
 
853
                if (ring == &dev_priv->ring[RCS] &&
 
854
                    mode != dev_priv->relative_constants_mode) {
 
855
                        if (INTEL_INFO(dev)->gen < 4)
 
856
                                return -EINVAL;
 
857
 
 
858
                        if (INTEL_INFO(dev)->gen > 5 &&
 
859
                            mode == I915_EXEC_CONSTANTS_REL_SURFACE)
 
860
                                return -EINVAL;
 
861
 
 
862
                        /* The HW changed the meaning on this bit on gen6 */
 
863
                        if (INTEL_INFO(dev)->gen >= 6)
 
864
                                mask &= ~I915_EXEC_CONSTANTS_REL_SURFACE;
 
865
                }
 
866
                break;
 
867
        default:
 
868
                DRM_DEBUG("execbuf with unknown constants: %d\n", mode);
 
869
                return -EINVAL;
 
870
        }
 
871
 
 
872
        if (args->buffer_count < 1) {
 
873
                DRM_DEBUG("execbuf with %d buffers\n", args->buffer_count);
 
874
                return -EINVAL;
 
875
        }
 
876
 
 
877
        if (args->num_cliprects != 0) {
 
878
                if (ring != &dev_priv->ring[RCS]) {
 
879
                        DRM_DEBUG("clip rectangles are only valid with the render ring\n");
 
880
                        return -EINVAL;
 
881
                }
 
882
 
 
883
                if (INTEL_INFO(dev)->gen >= 5) {
 
884
                        DRM_DEBUG("clip rectangles are only valid on pre-gen5\n");
 
885
                        return -EINVAL;
 
886
                }
 
887
 
 
888
                if (args->num_cliprects > UINT_MAX / sizeof(*cliprects)) {
 
889
                        DRM_DEBUG("execbuf with %u cliprects\n",
 
890
                                  args->num_cliprects);
 
891
                        return -EINVAL;
 
892
                }
 
893
 
 
894
                cliprects = kmalloc(args->num_cliprects * sizeof(*cliprects),
 
895
                                    GFP_KERNEL);
 
896
                if (cliprects == NULL) {
 
897
                        ret = -ENOMEM;
 
898
                        goto pre_mutex_err;
 
899
                }
 
900
 
 
901
                if (copy_from_user(cliprects,
 
902
                                     (struct drm_clip_rect __user *)(uintptr_t)
 
903
                                     args->cliprects_ptr,
 
904
                                     sizeof(*cliprects)*args->num_cliprects)) {
 
905
                        ret = -EFAULT;
 
906
                        goto pre_mutex_err;
 
907
                }
 
908
        }
 
909
 
 
910
        ret = i915_mutex_lock_interruptible(dev);
 
911
        if (ret)
 
912
                goto pre_mutex_err;
 
913
 
 
914
        if (dev_priv->mm.suspended) {
 
915
                mutex_unlock(&dev->struct_mutex);
 
916
                ret = -EBUSY;
 
917
                goto pre_mutex_err;
 
918
        }
 
919
 
 
920
        eb = eb_create(args->buffer_count);
 
921
        if (eb == NULL) {
 
922
                mutex_unlock(&dev->struct_mutex);
 
923
                ret = -ENOMEM;
 
924
                goto pre_mutex_err;
 
925
        }
 
926
 
 
927
        /* Look up object handles */
 
928
        INIT_LIST_HEAD(&objects);
 
929
        for (i = 0; i < args->buffer_count; i++) {
 
930
                struct drm_i915_gem_object *obj;
 
931
 
 
932
                obj = to_intel_bo(drm_gem_object_lookup(dev, file,
 
933
                                                        exec[i].handle));
 
934
                if (&obj->base == NULL) {
 
935
                        DRM_DEBUG("Invalid object handle %d at index %d\n",
 
936
                                   exec[i].handle, i);
 
937
                        /* prevent error path from reading uninitialized data */
 
938
                        ret = -ENOENT;
 
939
                        goto err;
 
940
                }
 
941
 
 
942
                if (!list_empty(&obj->exec_list)) {
 
943
                        DRM_DEBUG("Object %p [handle %d, index %d] appears more than once in object list\n",
 
944
                                   obj, exec[i].handle, i);
 
945
                        ret = -EINVAL;
 
946
                        goto err;
 
947
                }
 
948
 
 
949
                list_add_tail(&obj->exec_list, &objects);
 
950
                obj->exec_handle = exec[i].handle;
 
951
                obj->exec_entry = &exec[i];
 
952
                eb_add_object(eb, obj);
 
953
        }
 
954
 
 
955
        /* take note of the batch buffer before we might reorder the lists */
 
956
        batch_obj = list_entry(objects.prev,
 
957
                               struct drm_i915_gem_object,
 
958
                               exec_list);
 
959
 
 
960
        /* Move the objects en-masse into the GTT, evicting if necessary. */
 
961
        ret = i915_gem_execbuffer_reserve(ring, file, &objects);
 
962
        if (ret)
 
963
                goto err;
 
964
 
 
965
        /* The objects are in their final locations, apply the relocations. */
 
966
        ret = i915_gem_execbuffer_relocate(dev, eb, &objects);
 
967
        if (ret) {
 
968
                if (ret == -EFAULT) {
 
969
                        ret = i915_gem_execbuffer_relocate_slow(dev, file, ring,
 
970
                                                                &objects, eb,
 
971
                                                                exec,
 
972
                                                                args->buffer_count);
 
973
                        BUG_ON(!mutex_is_locked(&dev->struct_mutex));
 
974
                }
 
975
                if (ret)
 
976
                        goto err;
 
977
        }
 
978
 
 
979
        /* Set the pending read domains for the batch buffer to COMMAND */
 
980
        if (batch_obj->base.pending_write_domain) {
 
981
                DRM_DEBUG("Attempting to use self-modifying batch buffer\n");
 
982
                ret = -EINVAL;
 
983
                goto err;
 
984
        }
 
985
        batch_obj->base.pending_read_domains |= I915_GEM_DOMAIN_COMMAND;
 
986
 
 
987
        /* snb/ivb/vlv conflate the "batch in ppgtt" bit with the "non-secure
 
988
         * batch" bit. Hence we need to pin secure batches into the global gtt.
 
989
         * hsw should have this fixed, but let's be paranoid and do it
 
990
         * unconditionally for now. */
 
991
        if (flags & I915_DISPATCH_SECURE && !batch_obj->has_global_gtt_mapping)
 
992
                i915_gem_gtt_bind_object(batch_obj, batch_obj->cache_level);
 
993
 
 
994
        ret = i915_gem_execbuffer_move_to_gpu(ring, &objects);
 
995
        if (ret)
 
996
                goto err;
 
997
 
 
998
        seqno = i915_gem_next_request_seqno(ring);
 
999
        for (i = 0; i < ARRAY_SIZE(ring->sync_seqno); i++) {
 
1000
                if (seqno < ring->sync_seqno[i]) {
 
1001
                        /* The GPU can not handle its semaphore value wrapping,
 
1002
                         * so every billion or so execbuffers, we need to stall
 
1003
                         * the GPU in order to reset the counters.
 
1004
                         */
 
1005
                        ret = i915_gpu_idle(dev);
 
1006
                        if (ret)
 
1007
                                goto err;
 
1008
                        i915_gem_retire_requests(dev);
 
1009
 
 
1010
                        BUG_ON(ring->sync_seqno[i]);
 
1011
                }
 
1012
        }
 
1013
 
 
1014
        ret = i915_switch_context(ring, file, ctx_id);
 
1015
        if (ret)
 
1016
                goto err;
 
1017
 
 
1018
        if (ring == &dev_priv->ring[RCS] &&
 
1019
            mode != dev_priv->relative_constants_mode) {
 
1020
                ret = intel_ring_begin(ring, 4);
 
1021
                if (ret)
 
1022
                                goto err;
 
1023
 
 
1024
                intel_ring_emit(ring, MI_NOOP);
 
1025
                intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
 
1026
                intel_ring_emit(ring, INSTPM);
 
1027
                intel_ring_emit(ring, mask << 16 | mode);
 
1028
                intel_ring_advance(ring);
 
1029
 
 
1030
                dev_priv->relative_constants_mode = mode;
 
1031
        }
 
1032
 
 
1033
        if (args->flags & I915_EXEC_GEN7_SOL_RESET) {
 
1034
                ret = i915_reset_gen7_sol_offsets(dev, ring);
 
1035
                if (ret)
 
1036
                        goto err;
 
1037
        }
 
1038
 
 
1039
        trace_i915_gem_ring_dispatch(ring, seqno, flags);
 
1040
 
 
1041
        exec_start = batch_obj->gtt_offset + args->batch_start_offset;
 
1042
        exec_len = args->batch_len;
 
1043
        if (cliprects) {
 
1044
                for (i = 0; i < args->num_cliprects; i++) {
 
1045
                        ret = i915_emit_box(dev, &cliprects[i],
 
1046
                                            args->DR1, args->DR4);
 
1047
                        if (ret)
 
1048
                                goto err;
 
1049
 
 
1050
                        ret = ring->dispatch_execbuffer(ring,
 
1051
                                                        exec_start, exec_len,
 
1052
                                                        flags);
 
1053
                        if (ret)
 
1054
                                goto err;
 
1055
                }
 
1056
        } else {
 
1057
                ret = ring->dispatch_execbuffer(ring,
 
1058
                                                exec_start, exec_len,
 
1059
                                                flags);
 
1060
                if (ret)
 
1061
                        goto err;
 
1062
        }
 
1063
 
 
1064
        i915_gem_execbuffer_move_to_active(&objects, ring, seqno);
 
1065
        i915_gem_execbuffer_retire_commands(dev, file, ring);
 
1066
 
 
1067
err:
 
1068
        eb_destroy(eb);
 
1069
        while (!list_empty(&objects)) {
 
1070
                struct drm_i915_gem_object *obj;
 
1071
 
 
1072
                obj = list_first_entry(&objects,
 
1073
                                       struct drm_i915_gem_object,
 
1074
                                       exec_list);
 
1075
                list_del_init(&obj->exec_list);
 
1076
                drm_gem_object_unreference(&obj->base);
 
1077
        }
 
1078
 
 
1079
        mutex_unlock(&dev->struct_mutex);
 
1080
 
 
1081
pre_mutex_err:
 
1082
        kfree(cliprects);
 
1083
        return ret;
 
1084
}
 
1085
 
 
1086
/*
 
1087
 * Legacy execbuffer just creates an exec2 list from the original exec object
 
1088
 * list array and passes it to the real function.
 
1089
 */
 
1090
int
 
1091
i915_gem_execbuffer(struct drm_device *dev, void *data,
 
1092
                    struct drm_file *file)
 
1093
{
 
1094
        struct drm_i915_gem_execbuffer *args = data;
 
1095
        struct drm_i915_gem_execbuffer2 exec2;
 
1096
        struct drm_i915_gem_exec_object *exec_list = NULL;
 
1097
        struct drm_i915_gem_exec_object2 *exec2_list = NULL;
 
1098
        int ret, i;
 
1099
 
 
1100
        if (args->buffer_count < 1) {
 
1101
                DRM_DEBUG("execbuf with %d buffers\n", args->buffer_count);
 
1102
                return -EINVAL;
 
1103
        }
 
1104
 
 
1105
        /* Copy in the exec list from userland */
 
1106
        exec_list = drm_malloc_ab(sizeof(*exec_list), args->buffer_count);
 
1107
        exec2_list = drm_malloc_ab(sizeof(*exec2_list), args->buffer_count);
 
1108
        if (exec_list == NULL || exec2_list == NULL) {
 
1109
                DRM_DEBUG("Failed to allocate exec list for %d buffers\n",
 
1110
                          args->buffer_count);
 
1111
                drm_free_large(exec_list);
 
1112
                drm_free_large(exec2_list);
 
1113
                return -ENOMEM;
 
1114
        }
 
1115
        ret = copy_from_user(exec_list,
 
1116
                             (void __user *)(uintptr_t)args->buffers_ptr,
 
1117
                             sizeof(*exec_list) * args->buffer_count);
 
1118
        if (ret != 0) {
 
1119
                DRM_DEBUG("copy %d exec entries failed %d\n",
 
1120
                          args->buffer_count, ret);
 
1121
                drm_free_large(exec_list);
 
1122
                drm_free_large(exec2_list);
 
1123
                return -EFAULT;
 
1124
        }
 
1125
 
 
1126
        for (i = 0; i < args->buffer_count; i++) {
 
1127
                exec2_list[i].handle = exec_list[i].handle;
 
1128
                exec2_list[i].relocation_count = exec_list[i].relocation_count;
 
1129
                exec2_list[i].relocs_ptr = exec_list[i].relocs_ptr;
 
1130
                exec2_list[i].alignment = exec_list[i].alignment;
 
1131
                exec2_list[i].offset = exec_list[i].offset;
 
1132
                if (INTEL_INFO(dev)->gen < 4)
 
1133
                        exec2_list[i].flags = EXEC_OBJECT_NEEDS_FENCE;
 
1134
                else
 
1135
                        exec2_list[i].flags = 0;
 
1136
        }
 
1137
 
 
1138
        exec2.buffers_ptr = args->buffers_ptr;
 
1139
        exec2.buffer_count = args->buffer_count;
 
1140
        exec2.batch_start_offset = args->batch_start_offset;
 
1141
        exec2.batch_len = args->batch_len;
 
1142
        exec2.DR1 = args->DR1;
 
1143
        exec2.DR4 = args->DR4;
 
1144
        exec2.num_cliprects = args->num_cliprects;
 
1145
        exec2.cliprects_ptr = args->cliprects_ptr;
 
1146
        exec2.flags = I915_EXEC_RENDER;
 
1147
        i915_execbuffer2_set_context_id(exec2, 0);
 
1148
 
 
1149
        ret = i915_gem_do_execbuffer(dev, data, file, &exec2, exec2_list);
 
1150
        if (!ret) {
 
1151
                /* Copy the new buffer offsets back to the user's exec list. */
 
1152
                for (i = 0; i < args->buffer_count; i++)
 
1153
                        exec_list[i].offset = exec2_list[i].offset;
 
1154
                /* ... and back out to userspace */
 
1155
                ret = copy_to_user((void __user *)(uintptr_t)args->buffers_ptr,
 
1156
                                   exec_list,
 
1157
                                   sizeof(*exec_list) * args->buffer_count);
 
1158
                if (ret) {
 
1159
                        ret = -EFAULT;
 
1160
                        DRM_DEBUG("failed to copy %d exec entries "
 
1161
                                  "back to user (%d)\n",
 
1162
                                  args->buffer_count, ret);
 
1163
                }
 
1164
        }
 
1165
 
 
1166
        drm_free_large(exec_list);
 
1167
        drm_free_large(exec2_list);
 
1168
        return ret;
 
1169
}
 
1170
 
 
1171
int
 
1172
i915_gem_execbuffer2(struct drm_device *dev, void *data,
 
1173
                     struct drm_file *file)
 
1174
{
 
1175
        struct drm_i915_gem_execbuffer2 *args = data;
 
1176
        struct drm_i915_gem_exec_object2 *exec2_list = NULL;
 
1177
        int ret;
 
1178
 
 
1179
        if (args->buffer_count < 1 ||
 
1180
            args->buffer_count > UINT_MAX / sizeof(*exec2_list)) {
 
1181
                DRM_DEBUG("execbuf2 with %d buffers\n", args->buffer_count);
 
1182
                return -EINVAL;
 
1183
        }
 
1184
 
 
1185
        exec2_list = kmalloc(sizeof(*exec2_list)*args->buffer_count,
 
1186
                             GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
 
1187
        if (exec2_list == NULL)
 
1188
                exec2_list = drm_malloc_ab(sizeof(*exec2_list),
 
1189
                                           args->buffer_count);
 
1190
        if (exec2_list == NULL) {
 
1191
                DRM_DEBUG("Failed to allocate exec list for %d buffers\n",
 
1192
                          args->buffer_count);
 
1193
                return -ENOMEM;
 
1194
        }
 
1195
        ret = copy_from_user(exec2_list,
 
1196
                             (struct drm_i915_relocation_entry __user *)
 
1197
                             (uintptr_t) args->buffers_ptr,
 
1198
                             sizeof(*exec2_list) * args->buffer_count);
 
1199
        if (ret != 0) {
 
1200
                DRM_DEBUG("copy %d exec entries failed %d\n",
 
1201
                          args->buffer_count, ret);
 
1202
                drm_free_large(exec2_list);
 
1203
                return -EFAULT;
 
1204
        }
 
1205
 
 
1206
        ret = i915_gem_do_execbuffer(dev, data, file, args, exec2_list);
 
1207
        if (!ret) {
 
1208
                /* Copy the new buffer offsets back to the user's exec list. */
 
1209
                ret = copy_to_user((void __user *)(uintptr_t)args->buffers_ptr,
 
1210
                                   exec2_list,
 
1211
                                   sizeof(*exec2_list) * args->buffer_count);
 
1212
                if (ret) {
 
1213
                        ret = -EFAULT;
 
1214
                        DRM_DEBUG("failed to copy %d exec entries "
 
1215
                                  "back to user (%d)\n",
 
1216
                                  args->buffer_count, ret);
 
1217
                }
 
1218
        }
 
1219
 
 
1220
        drm_free_large(exec2_list);
 
1221
        return ret;
 
1222
}